aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorroot <root@artemis.panaceas.org>2015-12-25 04:40:36 +0000
committerroot <root@artemis.panaceas.org>2015-12-25 04:40:36 +0000
commit849369d6c66d3054688672f97d31fceb8e8230fb (patch)
tree6135abc790ca67dedbe07c39806591e70eda81ce /arch/mips
downloadlinux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.tar.gz
linux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.tar.bz2
linux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.zip
initial_commit
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Kbuild19
-rw-r--r--arch/mips/Kbuild.platforms34
-rw-r--r--arch/mips/Kconfig2508
-rw-r--r--arch/mips/Kconfig.debug131
-rw-r--r--arch/mips/Makefile330
-rw-r--r--arch/mips/alchemy/Kconfig160
-rw-r--r--arch/mips/alchemy/Platform114
-rw-r--r--arch/mips/alchemy/common/Makefile20
-rw-r--r--arch/mips/alchemy/common/clocks.c105
-rw-r--r--arch/mips/alchemy/common/dbdma.c1065
-rw-r--r--arch/mips/alchemy/common/dma.c268
-rw-r--r--arch/mips/alchemy/common/gpiolib-au1000.c126
-rw-r--r--arch/mips/alchemy/common/irq.c646
-rw-r--r--arch/mips/alchemy/common/pci.c104
-rw-r--r--arch/mips/alchemy/common/platform.c556
-rw-r--r--arch/mips/alchemy/common/power.c172
-rw-r--r--arch/mips/alchemy/common/prom.c129
-rw-r--r--arch/mips/alchemy/common/setup.c91
-rw-r--r--arch/mips/alchemy/common/sleeper.S197
-rw-r--r--arch/mips/alchemy/common/time.c192
-rw-r--r--arch/mips/alchemy/devboards/Makefile18
-rw-r--r--arch/mips/alchemy/devboards/bcsr.c149
-rw-r--r--arch/mips/alchemy/devboards/db1200/Makefile1
-rw-r--r--arch/mips/alchemy/devboards/db1200/platform.c567
-rw-r--r--arch/mips/alchemy/devboards/db1200/setup.c88
-rw-r--r--arch/mips/alchemy/devboards/db1x00/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/db1x00/board_setup.c255
-rw-r--r--arch/mips/alchemy/devboards/db1x00/platform.c118
-rw-r--r--arch/mips/alchemy/devboards/pb1000/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/pb1000/board_setup.c209
-rw-r--r--arch/mips/alchemy/devboards/pb1100/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/pb1100/board_setup.c127
-rw-r--r--arch/mips/alchemy/devboards/pb1100/platform.c50
-rw-r--r--arch/mips/alchemy/devboards/pb1200/Makefile5
-rw-r--r--arch/mips/alchemy/devboards/pb1200/board_setup.c174
-rw-r--r--arch/mips/alchemy/devboards/pb1200/platform.c203
-rw-r--r--arch/mips/alchemy/devboards/pb1500/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/pb1500/board_setup.c148
-rw-r--r--arch/mips/alchemy/devboards/pb1500/platform.c49
-rw-r--r--arch/mips/alchemy/devboards/pb1550/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/pb1550/board_setup.c86
-rw-r--r--arch/mips/alchemy/devboards/pb1550/platform.c69
-rw-r--r--arch/mips/alchemy/devboards/platform.c222
-rw-r--r--arch/mips/alchemy/devboards/platform.h21
-rw-r--r--arch/mips/alchemy/devboards/pm.c262
-rw-r--r--arch/mips/alchemy/devboards/prom.c66
-rw-r--r--arch/mips/alchemy/gpr/Makefile8
-rw-r--r--arch/mips/alchemy/gpr/board_setup.c87
-rw-r--r--arch/mips/alchemy/gpr/init.c63
-rw-r--r--arch/mips/alchemy/gpr/platform.c183
-rw-r--r--arch/mips/alchemy/mtx-1/Makefile9
-rw-r--r--arch/mips/alchemy/mtx-1/board_setup.c134
-rw-r--r--arch/mips/alchemy/mtx-1/init.c66
-rw-r--r--arch/mips/alchemy/mtx-1/platform.c168
-rw-r--r--arch/mips/alchemy/xxs1500/Makefile8
-rw-r--r--arch/mips/alchemy/xxs1500/board_setup.c101
-rw-r--r--arch/mips/alchemy/xxs1500/init.c63
-rw-r--r--arch/mips/alchemy/xxs1500/platform.c63
-rw-r--r--arch/mips/ar7/Makefile10
-rw-r--r--arch/mips/ar7/Platform6
-rw-r--r--arch/mips/ar7/clock.c475
-rw-r--r--arch/mips/ar7/gpio.c348
-rw-r--r--arch/mips/ar7/irq.c177
-rw-r--r--arch/mips/ar7/memory.c71
-rw-r--r--arch/mips/ar7/platform.c694
-rw-r--r--arch/mips/ar7/prom.c270
-rw-r--r--arch/mips/ar7/setup.c106
-rw-r--r--arch/mips/ar7/time.c43
-rw-r--r--arch/mips/ath79/Kconfig55
-rw-r--r--arch/mips/ath79/Makefile28
-rw-r--r--arch/mips/ath79/Platform7
-rw-r--r--arch/mips/ath79/clock.c183
-rw-r--r--arch/mips/ath79/common.c97
-rw-r--r--arch/mips/ath79/common.h31
-rw-r--r--arch/mips/ath79/dev-ar913x-wmac.c60
-rw-r--r--arch/mips/ath79/dev-ar913x-wmac.h17
-rw-r--r--arch/mips/ath79/dev-common.c77
-rw-r--r--arch/mips/ath79/dev-common.h18
-rw-r--r--arch/mips/ath79/dev-gpio-buttons.c58
-rw-r--r--arch/mips/ath79/dev-gpio-buttons.h23
-rw-r--r--arch/mips/ath79/dev-leds-gpio.c56
-rw-r--r--arch/mips/ath79/dev-leds-gpio.h21
-rw-r--r--arch/mips/ath79/dev-spi.c38
-rw-r--r--arch/mips/ath79/dev-spi.h22
-rw-r--r--arch/mips/ath79/early_printk.c36
-rw-r--r--arch/mips/ath79/gpio.c197
-rw-r--r--arch/mips/ath79/irq.c183
-rw-r--r--arch/mips/ath79/mach-ap81.c98
-rw-r--r--arch/mips/ath79/mach-pb44.c118
-rw-r--r--arch/mips/ath79/machtypes.h23
-rw-r--r--arch/mips/ath79/prom.c57
-rw-r--r--arch/mips/ath79/setup.c206
-rw-r--r--arch/mips/bcm47xx/Makefile6
-rw-r--r--arch/mips/bcm47xx/Platform7
-rw-r--r--arch/mips/bcm47xx/gpio.c61
-rw-r--r--arch/mips/bcm47xx/irq.c55
-rw-r--r--arch/mips/bcm47xx/nvram.c95
-rw-r--r--arch/mips/bcm47xx/prom.c171
-rw-r--r--arch/mips/bcm47xx/serial.c52
-rw-r--r--arch/mips/bcm47xx/setup.c283
-rw-r--r--arch/mips/bcm47xx/time.c48
-rw-r--r--arch/mips/bcm47xx/wgt634u.c166
-rw-r--r--arch/mips/bcm63xx/Kconfig25
-rw-r--r--arch/mips/bcm63xx/Makefile5
-rw-r--r--arch/mips/bcm63xx/Platform7
-rw-r--r--arch/mips/bcm63xx/boards/Kconfig11
-rw-r--r--arch/mips/bcm63xx/boards/Makefile3
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c913
-rw-r--r--arch/mips/bcm63xx/clk.c226
-rw-r--r--arch/mips/bcm63xx/cpu.c353
-rw-r--r--arch/mips/bcm63xx/cs.c144
-rw-r--r--arch/mips/bcm63xx/dev-dsp.c56
-rw-r--r--arch/mips/bcm63xx/dev-enet.c162
-rw-r--r--arch/mips/bcm63xx/dev-pcmcia.c144
-rw-r--r--arch/mips/bcm63xx/dev-uart.c75
-rw-r--r--arch/mips/bcm63xx/dev-wdt.c37
-rw-r--r--arch/mips/bcm63xx/early_printk.c30
-rw-r--r--arch/mips/bcm63xx/gpio.c134
-rw-r--r--arch/mips/bcm63xx/irq.c241
-rw-r--r--arch/mips/bcm63xx/prom.c52
-rw-r--r--arch/mips/bcm63xx/setup.c127
-rw-r--r--arch/mips/bcm63xx/timer.c205
-rw-r--r--arch/mips/boot/.gitignore6
-rw-r--r--arch/mips/boot/Makefile42
-rw-r--r--arch/mips/boot/compressed/Makefile108
-rw-r--r--arch/mips/boot/compressed/calc_vmlinuz_load_addr.c57
-rw-r--r--arch/mips/boot/compressed/dbg.c37
-rw-r--r--arch/mips/boot/compressed/decompress.c110
-rw-r--r--arch/mips/boot/compressed/dummy.c4
-rw-r--r--arch/mips/boot/compressed/head.S56
-rw-r--r--arch/mips/boot/compressed/ld.script50
-rw-r--r--arch/mips/boot/compressed/uart-16550.c43
-rw-r--r--arch/mips/boot/compressed/uart-alchemy.c7
-rw-r--r--arch/mips/boot/ecoff.h62
-rw-r--r--arch/mips/boot/elf2ecoff.c616
-rw-r--r--arch/mips/cavium-octeon/Kconfig105
-rw-r--r--arch/mips/cavium-octeon/Makefile17
-rw-r--r--arch/mips/cavium-octeon/Platform11
-rw-r--r--arch/mips/cavium-octeon/cpu.c48
-rw-r--r--arch/mips/cavium-octeon/csrc-octeon.c164
-rw-r--r--arch/mips/cavium-octeon/dma-octeon.c349
-rw-r--r--arch/mips/cavium-octeon/executive/Makefile14
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-bootmem.c690
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-errata.c73
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c144
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-l2c.c900
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-sysinfo.c117
-rw-r--r--arch/mips/cavium-octeon/executive/octeon-model.c358
-rw-r--r--arch/mips/cavium-octeon/flash_setup.c75
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c1044
-rw-r--r--arch/mips/cavium-octeon/octeon-memcpy.S521
-rw-r--r--arch/mips/cavium-octeon/octeon-platform.c445
-rw-r--r--arch/mips/cavium-octeon/octeon_boot.h72
-rw-r--r--arch/mips/cavium-octeon/serial.c137
-rw-r--r--arch/mips/cavium-octeon/setup.c785
-rw-r--r--arch/mips/cavium-octeon/smp.c424
-rw-r--r--arch/mips/cobalt/Makefile9
-rw-r--r--arch/mips/cobalt/Platform6
-rw-r--r--arch/mips/cobalt/buttons.c54
-rw-r--r--arch/mips/cobalt/console.c20
-rw-r--r--arch/mips/cobalt/irq.c61
-rw-r--r--arch/mips/cobalt/lcd.c55
-rw-r--r--arch/mips/cobalt/led.c62
-rw-r--r--arch/mips/cobalt/mtd.c61
-rw-r--r--arch/mips/cobalt/pci.c48
-rw-r--r--arch/mips/cobalt/reset.c51
-rw-r--r--arch/mips/cobalt/rtc.c64
-rw-r--r--arch/mips/cobalt/serial.c86
-rw-r--r--arch/mips/cobalt/setup.c120
-rw-r--r--arch/mips/cobalt/time.c54
-rw-r--r--arch/mips/configs/ar7_defconfig152
-rw-r--r--arch/mips/configs/bcm47xx_defconfig624
-rw-r--r--arch/mips/configs/bcm63xx_defconfig90
-rw-r--r--arch/mips/configs/bigsur_defconfig292
-rw-r--r--arch/mips/configs/capcella_defconfig101
-rw-r--r--arch/mips/configs/cavium-octeon_defconfig93
-rw-r--r--arch/mips/configs/cobalt_defconfig90
-rw-r--r--arch/mips/configs/db1000_defconfig118
-rw-r--r--arch/mips/configs/db1100_defconfig122
-rw-r--r--arch/mips/configs/db1200_defconfig170
-rw-r--r--arch/mips/configs/db1500_defconfig128
-rw-r--r--arch/mips/configs/db1550_defconfig157
-rw-r--r--arch/mips/configs/decstation_defconfig120
-rw-r--r--arch/mips/configs/e55_defconfig43
-rw-r--r--arch/mips/configs/fuloong2e_defconfig284
-rw-r--r--arch/mips/configs/gpr_defconfig349
-rw-r--r--arch/mips/configs/ip22_defconfig399
-rw-r--r--arch/mips/configs/ip27_defconfig387
-rw-r--r--arch/mips/configs/ip28_defconfig80
-rw-r--r--arch/mips/configs/ip32_defconfig216
-rw-r--r--arch/mips/configs/jazz_defconfig389
-rw-r--r--arch/mips/configs/jmr3927_defconfig63
-rw-r--r--arch/mips/configs/lasat_defconfig69
-rw-r--r--arch/mips/configs/lemote2f_defconfig461
-rw-r--r--arch/mips/configs/malta_defconfig493
-rw-r--r--arch/mips/configs/markeins_defconfig212
-rw-r--r--arch/mips/configs/mipssim_defconfig64
-rw-r--r--arch/mips/configs/mpc30x_defconfig62
-rw-r--r--arch/mips/configs/msp71xx_defconfig88
-rw-r--r--arch/mips/configs/mtx1_defconfig817
-rw-r--r--arch/mips/configs/nlm_xlr_defconfig574
-rw-r--r--arch/mips/configs/pb1100_defconfig124
-rw-r--r--arch/mips/configs/pb1200_defconfig170
-rw-r--r--arch/mips/configs/pb1500_defconfig141
-rw-r--r--arch/mips/configs/pb1550_defconfig145
-rw-r--r--arch/mips/configs/pnx8335-stb225_defconfig98
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig98
-rw-r--r--arch/mips/configs/pnx8550-stb810_defconfig92
-rw-r--r--arch/mips/configs/powertv_defconfig136
-rw-r--r--arch/mips/configs/rb532_defconfig191
-rw-r--r--arch/mips/configs/rbtx49xx_defconfig113
-rw-r--r--arch/mips/configs/rm200_defconfig480
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig125
-rw-r--r--arch/mips/configs/tb0219_defconfig97
-rw-r--r--arch/mips/configs/tb0226_defconfig95
-rw-r--r--arch/mips/configs/tb0287_defconfig111
-rw-r--r--arch/mips/configs/workpad_defconfig73
-rw-r--r--arch/mips/configs/wrppmc_defconfig97
-rw-r--r--arch/mips/configs/yosemite_defconfig94
-rw-r--r--arch/mips/dec/Makefile10
-rw-r--r--arch/mips/dec/Platform8
-rw-r--r--arch/mips/dec/ecc-berr.c278
-rw-r--r--arch/mips/dec/int-handler.S291
-rw-r--r--arch/mips/dec/ioasic-irq.c77
-rw-r--r--arch/mips/dec/kn01-berr.c201
-rw-r--r--arch/mips/dec/kn02-irq.c79
-rw-r--r--arch/mips/dec/kn02xa-berr.c139
-rw-r--r--arch/mips/dec/prom/Makefile9
-rw-r--r--arch/mips/dec/prom/call_o32.S89
-rw-r--r--arch/mips/dec/prom/cmdline.c39
-rw-r--r--arch/mips/dec/prom/console.c45
-rw-r--r--arch/mips/dec/prom/dectypes.h14
-rw-r--r--arch/mips/dec/prom/identify.c186
-rw-r--r--arch/mips/dec/prom/init.c135
-rw-r--r--arch/mips/dec/prom/locore.S29
-rw-r--r--arch/mips/dec/prom/memory.c118
-rw-r--r--arch/mips/dec/promcon.c54
-rw-r--r--arch/mips/dec/reset.c40
-rw-r--r--arch/mips/dec/setup.c768
-rw-r--r--arch/mips/dec/tc.c95
-rw-r--r--arch/mips/dec/time.c154
-rw-r--r--arch/mips/dec/wbflush.c94
-rw-r--r--arch/mips/emma/Makefile6
-rw-r--r--arch/mips/emma/Platform4
-rw-r--r--arch/mips/emma/common/Makefile10
-rw-r--r--arch/mips/emma/common/prom.c69
-rw-r--r--arch/mips/emma/markeins/Makefile10
-rw-r--r--arch/mips/emma/markeins/irq.c308
-rw-r--r--arch/mips/emma/markeins/led.c57
-rw-r--r--arch/mips/emma/markeins/platform.c212
-rw-r--r--arch/mips/emma/markeins/setup.c131
-rw-r--r--arch/mips/fw/arc/Makefile12
-rw-r--r--arch/mips/fw/arc/arc_con.c50
-rw-r--r--arch/mips/fw/arc/cmdline.c103
-rw-r--r--arch/mips/fw/arc/env.c27
-rw-r--r--arch/mips/fw/arc/file.c75
-rw-r--r--arch/mips/fw/arc/identify.c115
-rw-r--r--arch/mips/fw/arc/init.c59
-rw-r--r--arch/mips/fw/arc/memory.c160
-rw-r--r--arch/mips/fw/arc/misc.c89
-rw-r--r--arch/mips/fw/arc/promlib.c43
-rw-r--r--arch/mips/fw/arc/salone.c24
-rw-r--r--arch/mips/fw/arc/time.c25
-rw-r--r--arch/mips/fw/arc/tree.c127
-rw-r--r--arch/mips/fw/cfe/Makefile5
-rw-r--r--arch/mips/fw/cfe/cfe_api.c432
-rw-r--r--arch/mips/fw/cfe/cfe_api_int.h148
-rw-r--r--arch/mips/fw/lib/Makefile5
-rw-r--r--arch/mips/fw/lib/call_o32.S95
-rw-r--r--arch/mips/fw/sni/Makefile5
-rw-r--r--arch/mips/fw/sni/sniprom.c151
-rw-r--r--arch/mips/include/asm/Kbuild3
-rw-r--r--arch/mips/include/asm/abi.h27
-rw-r--r--arch/mips/include/asm/addrspace.h154
-rw-r--r--arch/mips/include/asm/amon.h7
-rw-r--r--arch/mips/include/asm/arch_hweight.h38
-rw-r--r--arch/mips/include/asm/asm-offsets.h1
-rw-r--r--arch/mips/include/asm/asm.h409
-rw-r--r--arch/mips/include/asm/asmmacro-32.h158
-rw-r--r--arch/mips/include/asm/asmmacro-64.h139
-rw-r--r--arch/mips/include/asm/asmmacro.h92
-rw-r--r--arch/mips/include/asm/atomic.h786
-rw-r--r--arch/mips/include/asm/auxvec.h4
-rw-r--r--arch/mips/include/asm/barrier.h181
-rw-r--r--arch/mips/include/asm/bcache.h60
-rw-r--r--arch/mips/include/asm/bitops.h684
-rw-r--r--arch/mips/include/asm/bitsperlong.h8
-rw-r--r--arch/mips/include/asm/bootinfo.h140
-rw-r--r--arch/mips/include/asm/branch.h38
-rw-r--r--arch/mips/include/asm/break.h37
-rw-r--r--arch/mips/include/asm/bug.h43
-rw-r--r--arch/mips/include/asm/bugs.h54
-rw-r--r--arch/mips/include/asm/byteorder.h19
-rw-r--r--arch/mips/include/asm/cache.h22
-rw-r--r--arch/mips/include/asm/cachectl.h26
-rw-r--r--arch/mips/include/asm/cacheflush.h117
-rw-r--r--arch/mips/include/asm/cacheops.h87
-rw-r--r--arch/mips/include/asm/cevt-r4k.h49
-rw-r--r--arch/mips/include/asm/checksum.h260
-rw-r--r--arch/mips/include/asm/clock.h64
-rw-r--r--arch/mips/include/asm/cmp.h18
-rw-r--r--arch/mips/include/asm/cmpxchg.h121
-rw-r--r--arch/mips/include/asm/compat-signal.h119
-rw-r--r--arch/mips/include/asm/compat.h228
-rw-r--r--arch/mips/include/asm/compiler.h19
-rw-r--r--arch/mips/include/asm/cop2.h35
-rw-r--r--arch/mips/include/asm/cpu-features.h255
-rw-r--r--arch/mips/include/asm/cpu-info.h94
-rw-r--r--arch/mips/include/asm/cpu.h325
-rw-r--r--arch/mips/include/asm/cputime.h6
-rw-r--r--arch/mips/include/asm/current.h1
-rw-r--r--arch/mips/include/asm/debug.h48
-rw-r--r--arch/mips/include/asm/dec/ecc.h55
-rw-r--r--arch/mips/include/asm/dec/interrupts.h126
-rw-r--r--arch/mips/include/asm/dec/ioasic.h38
-rw-r--r--arch/mips/include/asm/dec/ioasic_addrs.h152
-rw-r--r--arch/mips/include/asm/dec/ioasic_ints.h74
-rw-r--r--arch/mips/include/asm/dec/kn01.h89
-rw-r--r--arch/mips/include/asm/dec/kn02.h91
-rw-r--r--arch/mips/include/asm/dec/kn02ba.h67
-rw-r--r--arch/mips/include/asm/dec/kn02ca.h79
-rw-r--r--arch/mips/include/asm/dec/kn02xa.h84
-rw-r--r--arch/mips/include/asm/dec/kn03.h74
-rw-r--r--arch/mips/include/asm/dec/kn05.h76
-rw-r--r--arch/mips/include/asm/dec/kn230.h26
-rw-r--r--arch/mips/include/asm/dec/machtype.h27
-rw-r--r--arch/mips/include/asm/dec/prom.h174
-rw-r--r--arch/mips/include/asm/dec/system.h19
-rw-r--r--arch/mips/include/asm/delay.h32
-rw-r--r--arch/mips/include/asm/device.h19
-rw-r--r--arch/mips/include/asm/div64.h68
-rw-r--r--arch/mips/include/asm/dma-mapping.h90
-rw-r--r--arch/mips/include/asm/dma.h318
-rw-r--r--arch/mips/include/asm/ds1287.h27
-rw-r--r--arch/mips/include/asm/dsp.h85
-rw-r--r--arch/mips/include/asm/edac.h34
-rw-r--r--arch/mips/include/asm/elf.h384
-rw-r--r--arch/mips/include/asm/emergency-restart.h6
-rw-r--r--arch/mips/include/asm/emma/emma2rh.h261
-rw-r--r--arch/mips/include/asm/emma/markeins.h41
-rw-r--r--arch/mips/include/asm/errno.h135
-rw-r--r--arch/mips/include/asm/fb.h19
-rw-r--r--arch/mips/include/asm/fcntl.h77
-rw-r--r--arch/mips/include/asm/fixmap.h125
-rw-r--r--arch/mips/include/asm/floppy.h56
-rw-r--r--arch/mips/include/asm/fpregdef.h99
-rw-r--r--arch/mips/include/asm/fpu.h145
-rw-r--r--arch/mips/include/asm/fpu_emulator.h68
-rw-r--r--arch/mips/include/asm/ftrace.h90
-rw-r--r--arch/mips/include/asm/futex.h206
-rw-r--r--arch/mips/include/asm/fw/arc/hinv.h175
-rw-r--r--arch/mips/include/asm/fw/arc/types.h86
-rw-r--r--arch/mips/include/asm/fw/cfe/cfe_api.h122
-rw-r--r--arch/mips/include/asm/fw/cfe/cfe_error.h80
-rw-r--r--arch/mips/include/asm/gcmpregs.h125
-rw-r--r--arch/mips/include/asm/gic.h342
-rw-r--r--arch/mips/include/asm/gpio.h6
-rw-r--r--arch/mips/include/asm/gt64120.h580
-rw-r--r--arch/mips/include/asm/hardirq.h18
-rw-r--r--arch/mips/include/asm/hazards.h273
-rw-r--r--arch/mips/include/asm/highmem.h63
-rw-r--r--arch/mips/include/asm/hugetlb.h115
-rw-r--r--arch/mips/include/asm/hw_irq.h20
-rw-r--r--arch/mips/include/asm/i8253.h24
-rw-r--r--arch/mips/include/asm/i8259.h86
-rw-r--r--arch/mips/include/asm/ide.h13
-rw-r--r--arch/mips/include/asm/inst.h421
-rw-r--r--arch/mips/include/asm/io.h629
-rw-r--r--arch/mips/include/asm/ioctl.h27
-rw-r--r--arch/mips/include/asm/ioctls.h110
-rw-r--r--arch/mips/include/asm/ip32/crime.h158
-rw-r--r--arch/mips/include/asm/ip32/ip32_ints.h114
-rw-r--r--arch/mips/include/asm/ip32/mace.h365
-rw-r--r--arch/mips/include/asm/ipcbuf.h28
-rw-r--r--arch/mips/include/asm/irq.h148
-rw-r--r--arch/mips/include/asm/irq_cpu.h20
-rw-r--r--arch/mips/include/asm/irq_gt641xx.h60
-rw-r--r--arch/mips/include/asm/irq_regs.h21
-rw-r--r--arch/mips/include/asm/irqflags.h288
-rw-r--r--arch/mips/include/asm/isadep.h34
-rw-r--r--arch/mips/include/asm/jazz.h310
-rw-r--r--arch/mips/include/asm/jazzdma.h95
-rw-r--r--arch/mips/include/asm/jump_label.h50
-rw-r--r--arch/mips/include/asm/kdebug.h16
-rw-r--r--arch/mips/include/asm/kexec.h30
-rw-r--r--arch/mips/include/asm/kgdb.h45
-rw-r--r--arch/mips/include/asm/kmap_types.h12
-rw-r--r--arch/mips/include/asm/kprobes.h92
-rw-r--r--arch/mips/include/asm/kspd.h36
-rw-r--r--arch/mips/include/asm/lasat/ds1603.h18
-rw-r--r--arch/mips/include/asm/lasat/eeprom.h17
-rw-r--r--arch/mips/include/asm/lasat/head.h22
-rw-r--r--arch/mips/include/asm/lasat/lasat.h259
-rw-r--r--arch/mips/include/asm/lasat/lasatint.h14
-rw-r--r--arch/mips/include/asm/lasat/picvue.h15
-rw-r--r--arch/mips/include/asm/lasat/serial.h13
-rw-r--r--arch/mips/include/asm/linkage.h10
-rw-r--r--arch/mips/include/asm/local.h196
-rw-r--r--arch/mips/include/asm/local64.h1
-rw-r--r--arch/mips/include/asm/m48t37.h35
-rw-r--r--arch/mips/include/asm/mach-ar7/ar7.h206
-rw-r--r--arch/mips/include/asm/mach-ar7/gpio.h41
-rw-r--r--arch/mips/include/asm/mach-ar7/irq.h16
-rw-r--r--arch/mips/include/asm/mach-ar7/prom.h25
-rw-r--r--arch/mips/include/asm/mach-ar7/spaces.h22
-rw-r--r--arch/mips/include/asm/mach-ar7/war.h25
-rw-r--r--arch/mips/include/asm/mach-ath79/ar71xx_regs.h233
-rw-r--r--arch/mips/include/asm/mach-ath79/ath79.h96
-rw-r--r--arch/mips/include/asm/mach-ath79/ath79_spi_platform.h23
-rw-r--r--arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h56
-rw-r--r--arch/mips/include/asm/mach-ath79/gpio.h26
-rw-r--r--arch/mips/include/asm/mach-ath79/irq.h36
-rw-r--r--arch/mips/include/asm/mach-ath79/kernel-entry-init.h32
-rw-r--r--arch/mips/include/asm/mach-ath79/war.h25
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1000.h1538
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1000_dma.h454
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1100_mmc.h208
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1550_spi.h15
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx.h43
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h361
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_eth.h18
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_ide.h177
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_psc.h505
-rw-r--r--arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h49
-rw-r--r--arch/mips/include/asm/mach-au1x00/gpio-au1000.h689
-rw-r--r--arch/mips/include/asm/mach-au1x00/gpio.h10
-rw-r--r--arch/mips/include/asm/mach-au1x00/ioremap.h42
-rw-r--r--arch/mips/include/asm/mach-au1x00/prom.h12
-rw-r--r--arch/mips/include/asm/mach-au1x00/war.h25
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/bcm47xx.h25
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/gpio.h65
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/nvram.h54
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/war.h25
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h12
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h11
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h553
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h10
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h13
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h45
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h6
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h13
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h6
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h26
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h93
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h15
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h772
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h11
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h97
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h62
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h51
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/gpio.h15
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/war.h25
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h90
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h72
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/irq.h101
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h136
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/war.h26
-rw-r--r--arch/mips/include/asm/mach-cobalt/cobalt.h22
-rw-r--r--arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h56
-rw-r--r--arch/mips/include/asm/mach-cobalt/irq.h57
-rw-r--r--arch/mips/include/asm/mach-cobalt/mach-gt64120.h27
-rw-r--r--arch/mips/include/asm/mach-cobalt/war.h25
-rw-r--r--arch/mips/include/asm/mach-db1x00/bcsr.h238
-rw-r--r--arch/mips/include/asm/mach-db1x00/db1200.h86
-rw-r--r--arch/mips/include/asm/mach-db1x00/db1x00.h79
-rw-r--r--arch/mips/include/asm/mach-dec/mc146818rtc.h43
-rw-r--r--arch/mips/include/asm/mach-dec/war.h25
-rw-r--r--arch/mips/include/asm/mach-emma2rh/irq.h15
-rw-r--r--arch/mips/include/asm/mach-emma2rh/war.h25
-rw-r--r--arch/mips/include/asm/mach-generic/cpu-feature-overrides.h13
-rw-r--r--arch/mips/include/asm/mach-generic/dma-coherence.h71
-rw-r--r--arch/mips/include/asm/mach-generic/floppy.h139
-rw-r--r--arch/mips/include/asm/mach-generic/gpio.h21
-rw-r--r--arch/mips/include/asm/mach-generic/ide.h138
-rw-r--r--arch/mips/include/asm/mach-generic/ioremap.h34
-rw-r--r--arch/mips/include/asm/mach-generic/irq.h45
-rw-r--r--arch/mips/include/asm/mach-generic/kernel-entry-init.h25
-rw-r--r--arch/mips/include/asm/mach-generic/kmalloc.h13
-rw-r--r--arch/mips/include/asm/mach-generic/mangle-port.h52
-rw-r--r--arch/mips/include/asm/mach-generic/mc146818rtc.h36
-rw-r--r--arch/mips/include/asm/mach-generic/spaces.h85
-rw-r--r--arch/mips/include/asm/mach-generic/topology.h1
-rw-r--r--arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h44
-rw-r--r--arch/mips/include/asm/mach-ip22/spaces.h27
-rw-r--r--arch/mips/include/asm/mach-ip22/war.h29
-rw-r--r--arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h54
-rw-r--r--arch/mips/include/asm/mach-ip27/dma-coherence.h77
-rw-r--r--arch/mips/include/asm/mach-ip27/irq.h22
-rw-r--r--arch/mips/include/asm/mach-ip27/kernel-entry-init.h59
-rw-r--r--arch/mips/include/asm/mach-ip27/kmalloc.h8
-rw-r--r--arch/mips/include/asm/mach-ip27/mangle-port.h25
-rw-r--r--arch/mips/include/asm/mach-ip27/mmzone.h36
-rw-r--r--arch/mips/include/asm/mach-ip27/spaces.h30
-rw-r--r--arch/mips/include/asm/mach-ip27/topology.h58
-rw-r--r--arch/mips/include/asm/mach-ip27/war.h25
-rw-r--r--arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h50
-rw-r--r--arch/mips/include/asm/mach-ip28/spaces.h22
-rw-r--r--arch/mips/include/asm/mach-ip28/war.h25
-rw-r--r--arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h50
-rw-r--r--arch/mips/include/asm/mach-ip32/dma-coherence.h99
-rw-r--r--arch/mips/include/asm/mach-ip32/kmalloc.h11
-rw-r--r--arch/mips/include/asm/mach-ip32/mangle-port.h26
-rw-r--r--arch/mips/include/asm/mach-ip32/mc146818rtc.h36
-rw-r--r--arch/mips/include/asm/mach-ip32/war.h25
-rw-r--r--arch/mips/include/asm/mach-jazz/dma-coherence.h67
-rw-r--r--arch/mips/include/asm/mach-jazz/floppy.h135
-rw-r--r--arch/mips/include/asm/mach-jazz/mc146818rtc.h38
-rw-r--r--arch/mips/include/asm/mach-jazz/war.h25
-rw-r--r--arch/mips/include/asm/mach-jz4740/base.h26
-rw-r--r--arch/mips/include/asm/mach-jz4740/clock.h28
-rw-r--r--arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h51
-rw-r--r--arch/mips/include/asm/mach-jz4740/dma.h90
-rw-r--r--arch/mips/include/asm/mach-jz4740/gpio.h398
-rw-r--r--arch/mips/include/asm/mach-jz4740/irq.h57
-rw-r--r--arch/mips/include/asm/mach-jz4740/jz4740_fb.h67
-rw-r--r--arch/mips/include/asm/mach-jz4740/jz4740_mmc.h15
-rw-r--r--arch/mips/include/asm/mach-jz4740/jz4740_nand.h34
-rw-r--r--arch/mips/include/asm/mach-jz4740/platform.h37
-rw-r--r--arch/mips/include/asm/mach-jz4740/timer.h22
-rw-r--r--arch/mips/include/asm/mach-jz4740/war.h25
-rw-r--r--arch/mips/include/asm/mach-lantiq/lantiq.h63
-rw-r--r--arch/mips/include/asm/mach-lantiq/lantiq_platform.h53
-rw-r--r--arch/mips/include/asm/mach-lantiq/war.h24
-rw-r--r--arch/mips/include/asm/mach-lantiq/xway/irq.h18
-rw-r--r--arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h66
-rw-r--r--arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h141
-rw-r--r--arch/mips/include/asm/mach-lantiq/xway/xway_dma.h60
-rw-r--r--arch/mips/include/asm/mach-lasat/irq.h13
-rw-r--r--arch/mips/include/asm/mach-lasat/mach-gt64120.h27
-rw-r--r--arch/mips/include/asm/mach-lasat/war.h25
-rw-r--r--arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h60
-rw-r--r--arch/mips/include/asm/mach-loongson/cs5536/cs5536.h305
-rw-r--r--arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h35
-rw-r--r--arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h153
-rw-r--r--arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h31
-rw-r--r--arch/mips/include/asm/mach-loongson/dma-coherence.h72
-rw-r--r--arch/mips/include/asm/mach-loongson/gpio.h35
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson.h331
-rw-r--r--arch/mips/include/asm/mach-loongson/machine.h27
-rw-r--r--arch/mips/include/asm/mach-loongson/mc146818rtc.h36
-rw-r--r--arch/mips/include/asm/mach-loongson/mem.h41
-rw-r--r--arch/mips/include/asm/mach-loongson/pci.h50
-rw-r--r--arch/mips/include/asm/mach-loongson/war.h25
-rw-r--r--arch/mips/include/asm/mach-malta/cpu-feature-overrides.h68
-rw-r--r--arch/mips/include/asm/mach-malta/irq.h9
-rw-r--r--arch/mips/include/asm/mach-malta/kernel-entry-init.h52
-rw-r--r--arch/mips/include/asm/mach-malta/mach-gt64120.h19
-rw-r--r--arch/mips/include/asm/mach-malta/mc146818rtc.h48
-rw-r--r--arch/mips/include/asm/mach-malta/war.h25
-rw-r--r--arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h65
-rw-r--r--arch/mips/include/asm/mach-mipssim/war.h25
-rw-r--r--arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h47
-rw-r--r--arch/mips/include/asm/mach-netlogic/irq.h14
-rw-r--r--arch/mips/include/asm/mach-netlogic/war.h26
-rw-r--r--arch/mips/include/asm/mach-pb1x00/mc146818rtc.h34
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1000.h87
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1200.h141
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1550.h73
-rw-r--r--arch/mips/include/asm/mach-pnx833x/gpio.h172
-rw-r--r--arch/mips/include/asm/mach-pnx833x/irq-mapping.h125
-rw-r--r--arch/mips/include/asm/mach-pnx833x/irq.h53
-rw-r--r--arch/mips/include/asm/mach-pnx833x/pnx833x.h202
-rw-r--r--arch/mips/include/asm/mach-pnx833x/war.h25
-rw-r--r--arch/mips/include/asm/mach-pnx8550/cm.h43
-rw-r--r--arch/mips/include/asm/mach-pnx8550/glb.h86
-rw-r--r--arch/mips/include/asm/mach-pnx8550/int.h140
-rw-r--r--arch/mips/include/asm/mach-pnx8550/kernel-entry-init.h262
-rw-r--r--arch/mips/include/asm/mach-pnx8550/nand.h121
-rw-r--r--arch/mips/include/asm/mach-pnx8550/pci.h185
-rw-r--r--arch/mips/include/asm/mach-pnx8550/uart.h30
-rw-r--r--arch/mips/include/asm/mach-pnx8550/usb.h32
-rw-r--r--arch/mips/include/asm/mach-pnx8550/war.h25
-rw-r--r--arch/mips/include/asm/mach-powertv/asic.h120
-rw-r--r--arch/mips/include/asm/mach-powertv/asic_reg_map.h90
-rw-r--r--arch/mips/include/asm/mach-powertv/asic_regs.h125
-rw-r--r--arch/mips/include/asm/mach-powertv/dma-coherence.h119
-rw-r--r--arch/mips/include/asm/mach-powertv/interrupts.h253
-rw-r--r--arch/mips/include/asm/mach-powertv/ioremap.h167
-rw-r--r--arch/mips/include/asm/mach-powertv/irq.h25
-rw-r--r--arch/mips/include/asm/mach-powertv/powertv-clock.h29
-rw-r--r--arch/mips/include/asm/mach-powertv/war.h28
-rw-r--r--arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h76
-rw-r--r--arch/mips/include/asm/mach-rc32434/ddr.h141
-rw-r--r--arch/mips/include/asm/mach-rc32434/dma.h103
-rw-r--r--arch/mips/include/asm/mach-rc32434/dma_v.h52
-rw-r--r--arch/mips/include/asm/mach-rc32434/eth.h220
-rw-r--r--arch/mips/include/asm/mach-rc32434/gpio.h90
-rw-r--r--arch/mips/include/asm/mach-rc32434/integ.h59
-rw-r--r--arch/mips/include/asm/mach-rc32434/irq.h36
-rw-r--r--arch/mips/include/asm/mach-rc32434/pci.h481
-rw-r--r--arch/mips/include/asm/mach-rc32434/prom.h40
-rw-r--r--arch/mips/include/asm/mach-rc32434/rb.h89
-rw-r--r--arch/mips/include/asm/mach-rc32434/rc32434.h19
-rw-r--r--arch/mips/include/asm/mach-rc32434/timer.h65
-rw-r--r--arch/mips/include/asm/mach-rc32434/war.h25
-rw-r--r--arch/mips/include/asm/mach-rm/cpu-feature-overrides.h43
-rw-r--r--arch/mips/include/asm/mach-rm/mc146818rtc.h21
-rw-r--r--arch/mips/include/asm/mach-rm/war.h29
-rw-r--r--arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h47
-rw-r--r--arch/mips/include/asm/mach-sibyte/war.h41
-rw-r--r--arch/mips/include/asm/mach-tx39xx/ioremap.h38
-rw-r--r--arch/mips/include/asm/mach-tx39xx/mangle-port.h23
-rw-r--r--arch/mips/include/asm/mach-tx39xx/war.h25
-rw-r--r--arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h23
-rw-r--r--arch/mips/include/asm/mach-tx49xx/ioremap.h43
-rw-r--r--arch/mips/include/asm/mach-tx49xx/kmalloc.h6
-rw-r--r--arch/mips/include/asm/mach-tx49xx/mangle-port.h26
-rw-r--r--arch/mips/include/asm/mach-tx49xx/war.h25
-rw-r--r--arch/mips/include/asm/mach-vr41xx/irq.h8
-rw-r--r--arch/mips/include/asm/mach-vr41xx/war.h25
-rw-r--r--arch/mips/include/asm/mach-wrppmc/mach-gt64120.h83
-rw-r--r--arch/mips/include/asm/mach-wrppmc/war.h25
-rw-r--r--arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h47
-rw-r--r--arch/mips/include/asm/mach-yosemite/war.h25
-rw-r--r--arch/mips/include/asm/mc146818-time.h119
-rw-r--r--arch/mips/include/asm/mc146818rtc.h16
-rw-r--r--arch/mips/include/asm/mips-boards/bonito64.h431
-rw-r--r--arch/mips/include/asm/mips-boards/generic.h100
-rw-r--r--arch/mips/include/asm/mips-boards/launch.h35
-rw-r--r--arch/mips/include/asm/mips-boards/malta.h102
-rw-r--r--arch/mips/include/asm/mips-boards/maltaint.h107
-rw-r--r--arch/mips/include/asm/mips-boards/msc01_pci.h258
-rw-r--r--arch/mips/include/asm/mips-boards/piix4.h80
-rw-r--r--arch/mips/include/asm/mips-boards/prom.h47
-rw-r--r--arch/mips/include/asm/mips-boards/sim.h40
-rw-r--r--arch/mips/include/asm/mips-boards/simint.h31
-rw-r--r--arch/mips/include/asm/mips_machine.h54
-rw-r--r--arch/mips/include/asm/mips_mt.h26
-rw-r--r--arch/mips/include/asm/mipsmtregs.h395
-rw-r--r--arch/mips/include/asm/mipsprom.h76
-rw-r--r--arch/mips/include/asm/mipsregs.h1665
-rw-r--r--arch/mips/include/asm/mman.h86
-rw-r--r--arch/mips/include/asm/mmu.h9
-rw-r--r--arch/mips/include/asm/mmu_context.h322
-rw-r--r--arch/mips/include/asm/mmzone.h17
-rw-r--r--arch/mips/include/asm/module.h142
-rw-r--r--arch/mips/include/asm/msc01_ic.h147
-rw-r--r--arch/mips/include/asm/msgbuf.h47
-rw-r--r--arch/mips/include/asm/mutex.h9
-rw-r--r--arch/mips/include/asm/netlogic/interrupt.h45
-rw-r--r--arch/mips/include/asm/netlogic/mips-extns.h76
-rw-r--r--arch/mips/include/asm/netlogic/psb-bootinfo.h109
-rw-r--r--arch/mips/include/asm/netlogic/xlr/gpio.h73
-rw-r--r--arch/mips/include/asm/netlogic/xlr/iomap.h131
-rw-r--r--arch/mips/include/asm/netlogic/xlr/pic.h231
-rw-r--r--arch/mips/include/asm/netlogic/xlr/xlr.h75
-rw-r--r--arch/mips/include/asm/nile4.h309
-rw-r--r--arch/mips/include/asm/octeon/cvmx-agl-defs.h1446
-rw-r--r--arch/mips/include/asm/octeon/cvmx-asm.h139
-rw-r--r--arch/mips/include/asm/octeon/cvmx-bootinfo.h275
-rw-r--r--arch/mips/include/asm/octeon/cvmx-bootmem.h373
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ciu-defs.h2297
-rw-r--r--arch/mips/include/asm/octeon/cvmx-gpio-defs.h245
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-errata.h33
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-jtag.h43
-rw-r--r--arch/mips/include/asm/octeon/cvmx-iob-defs.h612
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ipd-defs.h959
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2c-defs.h1569
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2c.h360
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2d-defs.h357
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2t-defs.h140
-rw-r--r--arch/mips/include/asm/octeon/cvmx-led-defs.h227
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mio-defs.h2371
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mixx-defs.h334
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npei-defs.h2479
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npi-defs.h1615
-rw-r--r--arch/mips/include/asm/octeon/cvmx-packet.h61
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pci-defs.h1552
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pcieep-defs.h1365
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pciercx-defs.h1506
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pescx-defs.h394
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pexp-defs.h225
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pow-defs.h761
-rw-r--r--arch/mips/include/asm/octeon/cvmx-rnm-defs.h129
-rw-r--r--arch/mips/include/asm/octeon/cvmx-smix-defs.h174
-rw-r--r--arch/mips/include/asm/octeon/cvmx-spinlock.h232
-rw-r--r--arch/mips/include/asm/octeon/cvmx-sysinfo.h152
-rw-r--r--arch/mips/include/asm/octeon/cvmx-uctlx-defs.h261
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h517
-rw-r--r--arch/mips/include/asm/octeon/octeon-feature.h142
-rw-r--r--arch/mips/include/asm/octeon/octeon-model.h341
-rw-r--r--arch/mips/include/asm/octeon/octeon.h262
-rw-r--r--arch/mips/include/asm/octeon/pci-octeon.h68
-rw-r--r--arch/mips/include/asm/paccess.h112
-rw-r--r--arch/mips/include/asm/page.h213
-rw-r--r--arch/mips/include/asm/param.h16
-rw-r--r--arch/mips/include/asm/parport.h1
-rw-r--r--arch/mips/include/asm/pci.h152
-rw-r--r--arch/mips/include/asm/pci/bridge.h854
-rw-r--r--arch/mips/include/asm/percpu.h6
-rw-r--r--arch/mips/include/asm/perf_event.h15
-rw-r--r--arch/mips/include/asm/pgalloc.h132
-rw-r--r--arch/mips/include/asm/pgtable-32.h231
-rw-r--r--arch/mips/include/asm/pgtable-64.h290
-rw-r--r--arch/mips/include/asm/pgtable-bits.h228
-rw-r--r--arch/mips/include/asm/pgtable.h423
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h21
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/gpio.h46
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_cic_int.h151
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h343
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_int.h43
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_pci.h205
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h171
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h236
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h664
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_slp_int.h141
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h144
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/war.h30
-rw-r--r--arch/mips/include/asm/pmon.h46
-rw-r--r--arch/mips/include/asm/poll.h9
-rw-r--r--arch/mips/include/asm/posix_types.h144
-rw-r--r--arch/mips/include/asm/prefetch.h87
-rw-r--r--arch/mips/include/asm/processor.h361
-rw-r--r--arch/mips/include/asm/prom.h28
-rw-r--r--arch/mips/include/asm/ptrace.h157
-rw-r--r--arch/mips/include/asm/r4k-timer.h30
-rw-r--r--arch/mips/include/asm/r4kcache.h444
-rw-r--r--arch/mips/include/asm/reboot.h15
-rw-r--r--arch/mips/include/asm/reg.h128
-rw-r--r--arch/mips/include/asm/regdef.h100
-rw-r--r--arch/mips/include/asm/resource.h35
-rw-r--r--arch/mips/include/asm/rm9k-ocd.h56
-rw-r--r--arch/mips/include/asm/rtlx.h65
-rw-r--r--arch/mips/include/asm/scatterlist.h6
-rw-r--r--arch/mips/include/asm/seccomp.h32
-rw-r--r--arch/mips/include/asm/sections.h6
-rw-r--r--arch/mips/include/asm/segment.h6
-rw-r--r--arch/mips/include/asm/sembuf.h22
-rw-r--r--arch/mips/include/asm/serial.h1
-rw-r--r--arch/mips/include/asm/setup.h10
-rw-r--r--arch/mips/include/asm/sgi/gio.h86
-rw-r--r--arch/mips/include/asm/sgi/hpc3.h317
-rw-r--r--arch/mips/include/asm/sgi/ioc.h200
-rw-r--r--arch/mips/include/asm/sgi/ip22.h78
-rw-r--r--arch/mips/include/asm/sgi/mc.h231
-rw-r--r--arch/mips/include/asm/sgi/pi1.h71
-rw-r--r--arch/mips/include/asm/sgi/seeq.h21
-rw-r--r--arch/mips/include/asm/sgi/sgi.h47
-rw-r--r--arch/mips/include/asm/sgi/wd.h20
-rw-r--r--arch/mips/include/asm/sgialib.h78
-rw-r--r--arch/mips/include/asm/sgiarcs.h548
-rw-r--r--arch/mips/include/asm/sgidefs.h44
-rw-r--r--arch/mips/include/asm/shmbuf.h38
-rw-r--r--arch/mips/include/asm/shmparam.h13
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_int.h312
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_l2c.h176
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_mc.h984
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_regs.h902
-rw-r--r--arch/mips/include/asm/sibyte/bcm1480_scd.h406
-rw-r--r--arch/mips/include/asm/sibyte/bigsur.h48
-rw-r--r--arch/mips/include/asm/sibyte/board.h68
-rw-r--r--arch/mips/include/asm/sibyte/carmel.h58
-rw-r--r--arch/mips/include/asm/sibyte/sb1250.h68
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_defs.h259
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_dma.h594
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_genbus.h474
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_int.h248
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_l2c.h131
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_ldt.h422
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_mac.h656
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_mc.h550
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_regs.h893
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_scd.h654
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_smbus.h204
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_syncser.h146
-rw-r--r--arch/mips/include/asm/sibyte/sb1250_uart.h362
-rw-r--r--arch/mips/include/asm/sibyte/sentosa.h40
-rw-r--r--arch/mips/include/asm/sibyte/swarm.h64
-rw-r--r--arch/mips/include/asm/sigcontext.h101
-rw-r--r--arch/mips/include/asm/siginfo.h131
-rw-r--r--arch/mips/include/asm/signal.h139
-rw-r--r--arch/mips/include/asm/sim.h82
-rw-r--r--arch/mips/include/asm/smp-ops.h63
-rw-r--r--arch/mips/include/asm/smp.h94
-rw-r--r--arch/mips/include/asm/smtc.h71
-rw-r--r--arch/mips/include/asm/smtc_ipi.h129
-rw-r--r--arch/mips/include/asm/smtc_proc.h23
-rw-r--r--arch/mips/include/asm/smvp.h19
-rw-r--r--arch/mips/include/asm/sn/addrs.h431
-rw-r--r--arch/mips/include/asm/sn/agent.h45
-rw-r--r--arch/mips/include/asm/sn/arch.h64
-rw-r--r--arch/mips/include/asm/sn/fru.h44
-rw-r--r--arch/mips/include/asm/sn/gda.h107
-rw-r--r--arch/mips/include/asm/sn/hub.h16
-rw-r--r--arch/mips/include/asm/sn/intr.h129
-rw-r--r--arch/mips/include/asm/sn/io.h59
-rw-r--r--arch/mips/include/asm/sn/ioc3.h663
-rw-r--r--arch/mips/include/asm/sn/klconfig.h898
-rw-r--r--arch/mips/include/asm/sn/kldir.h217
-rw-r--r--arch/mips/include/asm/sn/klkernvars.h28
-rw-r--r--arch/mips/include/asm/sn/launch.h106
-rw-r--r--arch/mips/include/asm/sn/mapped_kernel.h54
-rw-r--r--arch/mips/include/asm/sn/nmi.h125
-rw-r--r--arch/mips/include/asm/sn/sn0/addrs.h288
-rw-r--r--arch/mips/include/asm/sn/sn0/arch.h72
-rw-r--r--arch/mips/include/asm/sn/sn0/hub.h40
-rw-r--r--arch/mips/include/asm/sn/sn0/hubio.h972
-rw-r--r--arch/mips/include/asm/sn/sn0/hubmd.h789
-rw-r--r--arch/mips/include/asm/sn/sn0/hubni.h255
-rw-r--r--arch/mips/include/asm/sn/sn0/hubpi.h409
-rw-r--r--arch/mips/include/asm/sn/sn0/ip27.h85
-rw-r--r--arch/mips/include/asm/sn/sn_private.h19
-rw-r--r--arch/mips/include/asm/sn/types.h26
-rw-r--r--arch/mips/include/asm/sni.h244
-rw-r--r--arch/mips/include/asm/socket.h124
-rw-r--r--arch/mips/include/asm/sockios.h26
-rw-r--r--arch/mips/include/asm/sparsemem.h13
-rw-r--r--arch/mips/include/asm/spinlock.h458
-rw-r--r--arch/mips/include/asm/spinlock_types.h37
-rw-r--r--arch/mips/include/asm/spram.h10
-rw-r--r--arch/mips/include/asm/stackframe.h614
-rw-r--r--arch/mips/include/asm/stacktrace.h48
-rw-r--r--arch/mips/include/asm/stat.h132
-rw-r--r--arch/mips/include/asm/statfs.h100
-rw-r--r--arch/mips/include/asm/string.h143
-rw-r--r--arch/mips/include/asm/suspend.h7
-rw-r--r--arch/mips/include/asm/swab.h59
-rw-r--r--arch/mips/include/asm/sysmips.h25
-rw-r--r--arch/mips/include/asm/system.h235
-rw-r--r--arch/mips/include/asm/termbits.h227
-rw-r--r--arch/mips/include/asm/termios.h176
-rw-r--r--arch/mips/include/asm/thread_info.h163
-rw-r--r--arch/mips/include/asm/time.h93
-rw-r--r--arch/mips/include/asm/timex.h43
-rw-r--r--arch/mips/include/asm/titan_dep.h231
-rw-r--r--arch/mips/include/asm/tlb.h23
-rw-r--r--arch/mips/include/asm/tlbdebug.h16
-rw-r--r--arch/mips/include/asm/tlbflush.h47
-rw-r--r--arch/mips/include/asm/topology.h17
-rw-r--r--arch/mips/include/asm/traps.h28
-rw-r--r--arch/mips/include/asm/txx9/boards.h13
-rw-r--r--arch/mips/include/asm/txx9/dmac.h51
-rw-r--r--arch/mips/include/asm/txx9/generic.h99
-rw-r--r--arch/mips/include/asm/txx9/jmr3927.h180
-rw-r--r--arch/mips/include/asm/txx9/ndfmc.h30
-rw-r--r--arch/mips/include/asm/txx9/pci.h39
-rw-r--r--arch/mips/include/asm/txx9/rbtx4927.h92
-rw-r--r--arch/mips/include/asm/txx9/rbtx4938.h145
-rw-r--r--arch/mips/include/asm/txx9/rbtx4939.h142
-rw-r--r--arch/mips/include/asm/txx9/smsc_fdc37m81x.h68
-rw-r--r--arch/mips/include/asm/txx9/spi.h34
-rw-r--r--arch/mips/include/asm/txx9/tx3927.h341
-rw-r--r--arch/mips/include/asm/txx9/tx4927.h273
-rw-r--r--arch/mips/include/asm/txx9/tx4927pcic.h203
-rw-r--r--arch/mips/include/asm/txx9/tx4938.h312
-rw-r--r--arch/mips/include/asm/txx9/tx4939.h554
-rw-r--r--arch/mips/include/asm/txx9irq.h34
-rw-r--r--arch/mips/include/asm/txx9pio.h29
-rw-r--r--arch/mips/include/asm/txx9tmr.h67
-rw-r--r--arch/mips/include/asm/types.h49
-rw-r--r--arch/mips/include/asm/uaccess.h1146
-rw-r--r--arch/mips/include/asm/uasm.h247
-rw-r--r--arch/mips/include/asm/ucontext.h1
-rw-r--r--arch/mips/include/asm/unaligned.h28
-rw-r--r--arch/mips/include/asm/unistd.h1082
-rw-r--r--arch/mips/include/asm/user.h58
-rw-r--r--arch/mips/include/asm/vdso.h29
-rw-r--r--arch/mips/include/asm/vga.h47
-rw-r--r--arch/mips/include/asm/vpe.h37
-rw-r--r--arch/mips/include/asm/vr41xx/capcella.h43
-rw-r--r--arch/mips/include/asm/vr41xx/giu.h62
-rw-r--r--arch/mips/include/asm/vr41xx/irq.h101
-rw-r--r--arch/mips/include/asm/vr41xx/mpc30x.h37
-rw-r--r--arch/mips/include/asm/vr41xx/pci.h90
-rw-r--r--arch/mips/include/asm/vr41xx/siu.h58
-rw-r--r--arch/mips/include/asm/vr41xx/tb0219.h42
-rw-r--r--arch/mips/include/asm/vr41xx/tb0226.h43
-rw-r--r--arch/mips/include/asm/vr41xx/tb0287.h43
-rw-r--r--arch/mips/include/asm/vr41xx/vr41xx.h152
-rw-r--r--arch/mips/include/asm/war.h244
-rw-r--r--arch/mips/include/asm/watch.h32
-rw-r--r--arch/mips/include/asm/wbflush.h34
-rw-r--r--arch/mips/include/asm/xor.h1
-rw-r--r--arch/mips/include/asm/xtalk/xtalk.h52
-rw-r--r--arch/mips/include/asm/xtalk/xwidget.h167
-rw-r--r--arch/mips/jazz/Kconfig33
-rw-r--r--arch/mips/jazz/Makefile5
-rw-r--r--arch/mips/jazz/Platform6
-rw-r--r--arch/mips/jazz/irq.c161
-rw-r--r--arch/mips/jazz/jazzdma.c558
-rw-r--r--arch/mips/jazz/reset.c56
-rw-r--r--arch/mips/jazz/setup.c198
-rw-r--r--arch/mips/jz4740/Kconfig12
-rw-r--r--arch/mips/jz4740/Makefile20
-rw-r--r--arch/mips/jz4740/Platform3
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c495
-rw-r--r--arch/mips/jz4740/clock-debugfs.c109
-rw-r--r--arch/mips/jz4740/clock.c924
-rw-r--r--arch/mips/jz4740/clock.h76
-rw-r--r--arch/mips/jz4740/dma.c287
-rw-r--r--arch/mips/jz4740/gpio.c585
-rw-r--r--arch/mips/jz4740/irq.c175
-rw-r--r--arch/mips/jz4740/irq.h21
-rw-r--r--arch/mips/jz4740/platform.c307
-rw-r--r--arch/mips/jz4740/pm.c56
-rw-r--r--arch/mips/jz4740/prom.c68
-rw-r--r--arch/mips/jz4740/pwm.c177
-rw-r--r--arch/mips/jz4740/reset.c79
-rw-r--r--arch/mips/jz4740/reset.h6
-rw-r--r--arch/mips/jz4740/serial.c33
-rw-r--r--arch/mips/jz4740/serial.h20
-rw-r--r--arch/mips/jz4740/setup.c61
-rw-r--r--arch/mips/jz4740/time.c143
-rw-r--r--arch/mips/jz4740/timer.c50
-rw-r--r--arch/mips/jz4740/timer.h136
-rw-r--r--arch/mips/kernel/.gitignore1
-rw-r--r--arch/mips/kernel/8250-platform.c47
-rw-r--r--arch/mips/kernel/Makefile113
-rw-r--r--arch/mips/kernel/asm-offsets.c341
-rw-r--r--arch/mips/kernel/binfmt_elfn32.c122
-rw-r--r--arch/mips/kernel/binfmt_elfo32.c161
-rw-r--r--arch/mips/kernel/branch.c253
-rw-r--r--arch/mips/kernel/cevt-bcm1480.c154
-rw-r--r--arch/mips/kernel/cevt-ds1287.c130
-rw-r--r--arch/mips/kernel/cevt-gt641xx.c141
-rw-r--r--arch/mips/kernel/cevt-r4k.c216
-rw-r--r--arch/mips/kernel/cevt-sb1250.c153
-rw-r--r--arch/mips/kernel/cevt-smtc.c324
-rw-r--r--arch/mips/kernel/cevt-txx9.c193
-rw-r--r--arch/mips/kernel/cpu-bugs64.c319
-rw-r--r--arch/mips/kernel/cpu-probe.c1164
-rw-r--r--arch/mips/kernel/cpufreq/Kconfig41
-rw-r--r--arch/mips/kernel/cpufreq/Makefile5
-rw-r--r--arch/mips/kernel/cpufreq/loongson2_clock.c170
-rw-r--r--arch/mips/kernel/cpufreq/loongson2_cpufreq.c227
-rw-r--r--arch/mips/kernel/csrc-bcm1480.c53
-rw-r--r--arch/mips/kernel/csrc-ioasic.c63
-rw-r--r--arch/mips/kernel/csrc-powertv.c151
-rw-r--r--arch/mips/kernel/csrc-r4k.c36
-rw-r--r--arch/mips/kernel/csrc-sb1250.c69
-rw-r--r--arch/mips/kernel/early_printk.c44
-rw-r--r--arch/mips/kernel/entry.S192
-rw-r--r--arch/mips/kernel/ftrace.c327
-rw-r--r--arch/mips/kernel/genex.S548
-rw-r--r--arch/mips/kernel/gpio_txx9.c89
-rw-r--r--arch/mips/kernel/head.S232
-rw-r--r--arch/mips/kernel/i8253.c135
-rw-r--r--arch/mips/kernel/i8259.c334
-rw-r--r--arch/mips/kernel/init_task.c35
-rw-r--r--arch/mips/kernel/irq-gic.c258
-rw-r--r--arch/mips/kernel/irq-gt641xx.c131
-rw-r--r--arch/mips/kernel/irq-msc01.c165
-rw-r--r--arch/mips/kernel/irq-rm7000.c50
-rw-r--r--arch/mips/kernel/irq-rm9000.c107
-rw-r--r--arch/mips/kernel/irq.c166
-rw-r--r--arch/mips/kernel/irq_cpu.c118
-rw-r--r--arch/mips/kernel/irq_txx9.c191
-rw-r--r--arch/mips/kernel/jump_label.c54
-rw-r--r--arch/mips/kernel/kgdb.c384
-rw-r--r--arch/mips/kernel/kprobes.c557
-rw-r--r--arch/mips/kernel/kspd.c423
-rw-r--r--arch/mips/kernel/linux32.c351
-rw-r--r--arch/mips/kernel/machine_kexec.c85
-rw-r--r--arch/mips/kernel/mcount.S202
-rw-r--r--arch/mips/kernel/mips-mt-fpaff.c214
-rw-r--r--arch/mips/kernel/mips-mt.c332
-rw-r--r--arch/mips/kernel/mips_ksyms.c58
-rw-r--r--arch/mips/kernel/mips_machine.c86
-rw-r--r--arch/mips/kernel/module.c408
-rw-r--r--arch/mips/kernel/octeon_switch.S502
-rw-r--r--arch/mips/kernel/perf_event.c588
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c1054
-rw-r--r--arch/mips/kernel/proc.c112
-rw-r--r--arch/mips/kernel/process.c487
-rw-r--r--arch/mips/kernel/prom.c111
-rw-r--r--arch/mips/kernel/ptrace.c599
-rw-r--r--arch/mips/kernel/ptrace32.c337
-rw-r--r--arch/mips/kernel/r2300_fpu.S126
-rw-r--r--arch/mips/kernel/r2300_switch.S170
-rw-r--r--arch/mips/kernel/r4k_fpu.S188
-rw-r--r--arch/mips/kernel/r4k_switch.S252
-rw-r--r--arch/mips/kernel/r6000_fpu.S87
-rw-r--r--arch/mips/kernel/relocate_kernel.S82
-rw-r--r--arch/mips/kernel/reset.c44
-rw-r--r--arch/mips/kernel/rtlx.c565
-rw-r--r--arch/mips/kernel/scall32-o32.S607
-rw-r--r--arch/mips/kernel/scall64-64.S432
-rw-r--r--arch/mips/kernel/scall64-n32.S432
-rw-r--r--arch/mips/kernel/scall64-o32.S550
-rw-r--r--arch/mips/kernel/setup.c591
-rw-r--r--arch/mips/kernel/signal-common.h41
-rw-r--r--arch/mips/kernel/signal.c708
-rw-r--r--arch/mips/kernel/signal32.c827
-rw-r--r--arch/mips/kernel/signal_n32.c230
-rw-r--r--arch/mips/kernel/smp-cmp.c210
-rw-r--r--arch/mips/kernel/smp-mt.c287
-rw-r--r--arch/mips/kernel/smp-up.c84
-rw-r--r--arch/mips/kernel/smp.c435
-rw-r--r--arch/mips/kernel/smtc-asm.S130
-rw-r--r--arch/mips/kernel/smtc-proc.c92
-rw-r--r--arch/mips/kernel/smtc.c1468
-rw-r--r--arch/mips/kernel/spinlock_test.c141
-rw-r--r--arch/mips/kernel/spram.c220
-rw-r--r--arch/mips/kernel/stacktrace.c87
-rw-r--r--arch/mips/kernel/sync-r4k.c160
-rw-r--r--arch/mips/kernel/syscall.c345
-rw-r--r--arch/mips/kernel/time.c126
-rw-r--r--arch/mips/kernel/topology.c32
-rw-r--r--arch/mips/kernel/traps.c1795
-rw-r--r--arch/mips/kernel/unaligned.c576
-rw-r--r--arch/mips/kernel/vdso.c110
-rw-r--r--arch/mips/kernel/vmlinux.lds.S165
-rw-r--r--arch/mips/kernel/vpe.c1622
-rw-r--r--arch/mips/kernel/watch.c188
-rw-r--r--arch/mips/lantiq/Kconfig23
-rw-r--r--arch/mips/lantiq/Makefile11
-rw-r--r--arch/mips/lantiq/Platform8
-rw-r--r--arch/mips/lantiq/clk.c140
-rw-r--r--arch/mips/lantiq/clk.h18
-rw-r--r--arch/mips/lantiq/devices.c122
-rw-r--r--arch/mips/lantiq/devices.h23
-rw-r--r--arch/mips/lantiq/early_printk.c33
-rw-r--r--arch/mips/lantiq/irq.c326
-rw-r--r--arch/mips/lantiq/machtypes.h20
-rw-r--r--arch/mips/lantiq/prom.c71
-rw-r--r--arch/mips/lantiq/prom.h25
-rw-r--r--arch/mips/lantiq/setup.c66
-rw-r--r--arch/mips/lantiq/xway/Kconfig23
-rw-r--r--arch/mips/lantiq/xway/Makefile7
-rw-r--r--arch/mips/lantiq/xway/clk-ase.c48
-rw-r--r--arch/mips/lantiq/xway/clk-xway.c223
-rw-r--r--arch/mips/lantiq/xway/devices.c121
-rw-r--r--arch/mips/lantiq/xway/devices.h20
-rw-r--r--arch/mips/lantiq/xway/dma.c253
-rw-r--r--arch/mips/lantiq/xway/ebu.c53
-rw-r--r--arch/mips/lantiq/xway/gpio.c195
-rw-r--r--arch/mips/lantiq/xway/gpio_ebu.c126
-rw-r--r--arch/mips/lantiq/xway/gpio_stp.c157
-rw-r--r--arch/mips/lantiq/xway/mach-easy50601.c57
-rw-r--r--arch/mips/lantiq/xway/mach-easy50712.c74
-rw-r--r--arch/mips/lantiq/xway/pmu.c70
-rw-r--r--arch/mips/lantiq/xway/prom-ase.c39
-rw-r--r--arch/mips/lantiq/xway/prom-xway.c54
-rw-r--r--arch/mips/lantiq/xway/reset.c91
-rw-r--r--arch/mips/lantiq/xway/setup-ase.c19
-rw-r--r--arch/mips/lantiq/xway/setup-xway.c20
-rw-r--r--arch/mips/lasat/Kconfig15
-rw-r--r--arch/mips/lasat/Makefile14
-rw-r--r--arch/mips/lasat/Platform7
-rw-r--r--arch/mips/lasat/at93c.c149
-rw-r--r--arch/mips/lasat/at93c.h18
-rw-r--r--arch/mips/lasat/ds1603.c184
-rw-r--r--arch/mips/lasat/ds1603.h31
-rw-r--r--arch/mips/lasat/image/Makefile54
-rw-r--r--arch/mips/lasat/image/head.S31
-rw-r--r--arch/mips/lasat/image/romscript.normal23
-rw-r--r--arch/mips/lasat/interrupt.c134
-rw-r--r--arch/mips/lasat/lasat_board.c280
-rw-r--r--arch/mips/lasat/lasat_models.h67
-rw-r--r--arch/mips/lasat/picvue.c242
-rw-r--r--arch/mips/lasat/picvue.h44
-rw-r--r--arch/mips/lasat/picvue_proc.c216
-rw-r--r--arch/mips/lasat/prom.c124
-rw-r--r--arch/mips/lasat/prom.h7
-rw-r--r--arch/mips/lasat/reset.c61
-rw-r--r--arch/mips/lasat/serial.c93
-rw-r--r--arch/mips/lasat/setup.c153
-rw-r--r--arch/mips/lasat/sysctl.c288
-rw-r--r--arch/mips/lib/Makefile34
-rw-r--r--arch/mips/lib/ashldi3.c29
-rw-r--r--arch/mips/lib/ashrdi3.c31
-rw-r--r--arch/mips/lib/cmpdi2.c27
-rw-r--r--arch/mips/lib/csum_partial.S760
-rw-r--r--arch/mips/lib/delay.c56
-rw-r--r--arch/mips/lib/dump_tlb.c111
-rw-r--r--arch/mips/lib/iomap-pci.c74
-rw-r--r--arch/mips/lib/iomap.c226
-rw-r--r--arch/mips/lib/libgcc.h25
-rw-r--r--arch/mips/lib/lshrdi3.c29
-rw-r--r--arch/mips/lib/memcpy-inatomic.S451
-rw-r--r--arch/mips/lib/memcpy.S566
-rw-r--r--arch/mips/lib/memset.S180
-rw-r--r--arch/mips/lib/r3k_dump_tlb.c63
-rw-r--r--arch/mips/lib/strlen_user.S39
-rw-r--r--arch/mips/lib/strncpy_user.S59
-rw-r--r--arch/mips/lib/strnlen_user.S46
-rw-r--r--arch/mips/lib/ucmpdi2.c21
-rw-r--r--arch/mips/lib/uncached.c81
-rw-r--r--arch/mips/loongson/Kconfig92
-rw-r--r--arch/mips/loongson/Makefile17
-rw-r--r--arch/mips/loongson/Platform32
-rw-r--r--arch/mips/loongson/common/Makefile27
-rw-r--r--arch/mips/loongson/common/bonito-irq.c53
-rw-r--r--arch/mips/loongson/common/cmdline.c48
-rw-r--r--arch/mips/loongson/common/cs5536/Makefile11
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_acc.c140
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_ehci.c160
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_ide.c192
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_isa.c316
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_mfgpt.c214
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_ohci.c149
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_pci.c87
-rw-r--r--arch/mips/loongson/common/early_printk.c41
-rw-r--r--arch/mips/loongson/common/env.c79
-rw-r--r--arch/mips/loongson/common/gpio.c139
-rw-r--r--arch/mips/loongson/common/init.c39
-rw-r--r--arch/mips/loongson/common/irq.c67
-rw-r--r--arch/mips/loongson/common/machtype.c66
-rw-r--r--arch/mips/loongson/common/mem.c119
-rw-r--r--arch/mips/loongson/common/pci.c91
-rw-r--r--arch/mips/loongson/common/platform.c30
-rw-r--r--arch/mips/loongson/common/pm.c161
-rw-r--r--arch/mips/loongson/common/reset.c70
-rw-r--r--arch/mips/loongson/common/rtc.c43
-rw-r--r--arch/mips/loongson/common/serial.c76
-rw-r--r--arch/mips/loongson/common/setup.c55
-rw-r--r--arch/mips/loongson/common/time.c31
-rw-r--r--arch/mips/loongson/common/uart_base.c45
-rw-r--r--arch/mips/loongson/fuloong-2e/Makefile5
-rw-r--r--arch/mips/loongson/fuloong-2e/irq.c68
-rw-r--r--arch/mips/loongson/fuloong-2e/reset.c23
-rw-r--r--arch/mips/loongson/lemote-2f/Makefile11
-rw-r--r--arch/mips/loongson/lemote-2f/ec_kb3310b.c130
-rw-r--r--arch/mips/loongson/lemote-2f/ec_kb3310b.h188
-rw-r--r--arch/mips/loongson/lemote-2f/irq.c128
-rw-r--r--arch/mips/loongson/lemote-2f/machtype.c45
-rw-r--r--arch/mips/loongson/lemote-2f/pm.c149
-rw-r--r--arch/mips/loongson/lemote-2f/reset.c159
-rw-r--r--arch/mips/math-emu/Makefile12
-rw-r--r--arch/mips/math-emu/cp1emu.c1413
-rw-r--r--arch/mips/math-emu/dp_add.c182
-rw-r--r--arch/mips/math-emu/dp_cmp.c66
-rw-r--r--arch/mips/math-emu/dp_div.c156
-rw-r--r--arch/mips/math-emu/dp_fint.c79
-rw-r--r--arch/mips/math-emu/dp_flong.c77
-rw-r--r--arch/mips/math-emu/dp_frexp.c52
-rw-r--r--arch/mips/math-emu/dp_fsp.c73
-rw-r--r--arch/mips/math-emu/dp_logb.c53
-rw-r--r--arch/mips/math-emu/dp_modf.c79
-rw-r--r--arch/mips/math-emu/dp_mul.c176
-rw-r--r--arch/mips/math-emu/dp_scalb.c57
-rw-r--r--arch/mips/math-emu/dp_simple.c85
-rw-r--r--arch/mips/math-emu/dp_sqrt.c164
-rw-r--r--arch/mips/math-emu/dp_sub.c190
-rw-r--r--arch/mips/math-emu/dp_tint.c122
-rw-r--r--arch/mips/math-emu/dp_tlong.c125
-rw-r--r--arch/mips/math-emu/dsemul.c167
-rw-r--r--arch/mips/math-emu/ieee754.c127
-rw-r--r--arch/mips/math-emu/ieee754.h470
-rw-r--r--arch/mips/math-emu/ieee754d.c136
-rw-r--r--arch/mips/math-emu/ieee754dp.c243
-rw-r--r--arch/mips/math-emu/ieee754dp.h82
-rw-r--r--arch/mips/math-emu/ieee754int.h164
-rw-r--r--arch/mips/math-emu/ieee754m.c55
-rw-r--r--arch/mips/math-emu/ieee754sp.c243
-rw-r--r--arch/mips/math-emu/ieee754sp.h88
-rw-r--r--arch/mips/math-emu/ieee754xcpt.c47
-rw-r--r--arch/mips/math-emu/kernel_linkage.c115
-rw-r--r--arch/mips/math-emu/sp_add.c176
-rw-r--r--arch/mips/math-emu/sp_cmp.c66
-rw-r--r--arch/mips/math-emu/sp_div.c156
-rw-r--r--arch/mips/math-emu/sp_fdp.c76
-rw-r--r--arch/mips/math-emu/sp_fint.c79
-rw-r--r--arch/mips/math-emu/sp_flong.c78
-rw-r--r--arch/mips/math-emu/sp_frexp.c52
-rw-r--r--arch/mips/math-emu/sp_logb.c53
-rw-r--r--arch/mips/math-emu/sp_modf.c79
-rw-r--r--arch/mips/math-emu/sp_mul.c170
-rw-r--r--arch/mips/math-emu/sp_scalb.c57
-rw-r--r--arch/mips/math-emu/sp_simple.c85
-rw-r--r--arch/mips/math-emu/sp_sqrt.c116
-rw-r--r--arch/mips/math-emu/sp_sub.c183
-rw-r--r--arch/mips/math-emu/sp_tint.c126
-rw-r--r--arch/mips/math-emu/sp_tlong.c121
-rw-r--r--arch/mips/mipssim/Makefile23
-rw-r--r--arch/mips/mipssim/Platform6
-rw-r--r--arch/mips/mipssim/sim_console.c40
-rw-r--r--arch/mips/mipssim/sim_int.c87
-rw-r--r--arch/mips/mipssim/sim_mem.c115
-rw-r--r--arch/mips/mipssim/sim_platform.c35
-rw-r--r--arch/mips/mipssim/sim_setup.c99
-rw-r--r--arch/mips/mipssim/sim_smtc.c117
-rw-r--r--arch/mips/mipssim/sim_time.c116
-rw-r--r--arch/mips/mm/Makefile38
-rw-r--r--arch/mips/mm/c-octeon.c322
-rw-r--r--arch/mips/mm/c-r3k.c341
-rw-r--r--arch/mips/mm/c-r4k.c1427
-rw-r--r--arch/mips/mm/c-tx39.c434
-rw-r--r--arch/mips/mm/cache.c222
-rw-r--r--arch/mips/mm/cerr-sb1.c586
-rw-r--r--arch/mips/mm/cex-gen.S42
-rw-r--r--arch/mips/mm/cex-oct.S70
-rw-r--r--arch/mips/mm/cex-sb1.S175
-rw-r--r--arch/mips/mm/dma-default.c329
-rw-r--r--arch/mips/mm/extable.c25
-rw-r--r--arch/mips/mm/fault.c294
-rw-r--r--arch/mips/mm/highmem.c137
-rw-r--r--arch/mips/mm/hugetlbpage.c98
-rw-r--r--arch/mips/mm/init.c482
-rw-r--r--arch/mips/mm/ioremap.c192
-rw-r--r--arch/mips/mm/mmap.c122
-rw-r--r--arch/mips/mm/page.c691
-rw-r--r--arch/mips/mm/pgtable-32.c70
-rw-r--r--arch/mips/mm/pgtable-64.c80
-rw-r--r--arch/mips/mm/sc-ip22.c177
-rw-r--r--arch/mips/mm/sc-mips.c146
-rw-r--r--arch/mips/mm/sc-r5k.c108
-rw-r--r--arch/mips/mm/sc-rm7k.c270
-rw-r--r--arch/mips/mm/tlb-r3k.c284
-rw-r--r--arch/mips/mm/tlb-r4k.c471
-rw-r--r--arch/mips/mm/tlb-r8k.c249
-rw-r--r--arch/mips/mm/tlbex-fault.S28
-rw-r--r--arch/mips/mm/tlbex.c2063
-rw-r--r--arch/mips/mm/uasm.c699
-rw-r--r--arch/mips/mti-malta/Makefile17
-rw-r--r--arch/mips/mti-malta/Platform7
-rw-r--r--arch/mips/mti-malta/malta-amon.c81
-rw-r--r--arch/mips/mti-malta/malta-cmdline.c59
-rw-r--r--arch/mips/mti-malta/malta-console.c47
-rw-r--r--arch/mips/mti-malta/malta-display.c64
-rw-r--r--arch/mips/mti-malta/malta-init.c373
-rw-r--r--arch/mips/mti-malta/malta-int.c746
-rw-r--r--arch/mips/mti-malta/malta-memory.c178
-rw-r--r--arch/mips/mti-malta/malta-pci.c266
-rw-r--r--arch/mips/mti-malta/malta-platform.c149
-rw-r--r--arch/mips/mti-malta/malta-reset.c58
-rw-r--r--arch/mips/mti-malta/malta-setup.c224
-rw-r--r--arch/mips/mti-malta/malta-smtc.c162
-rw-r--r--arch/mips/mti-malta/malta-time.c164
-rw-r--r--arch/mips/netlogic/Kconfig5
-rw-r--r--arch/mips/netlogic/xlr/Makefile5
-rw-r--r--arch/mips/netlogic/xlr/irq.c300
-rw-r--r--arch/mips/netlogic/xlr/platform.c98
-rw-r--r--arch/mips/netlogic/xlr/setup.c188
-rw-r--r--arch/mips/netlogic/xlr/smp.c225
-rw-r--r--arch/mips/netlogic/xlr/smpboot.S94
-rw-r--r--arch/mips/netlogic/xlr/time.c51
-rw-r--r--arch/mips/netlogic/xlr/xlr_console.c46
-rw-r--r--arch/mips/nxp/pnx8550/common/pci.c134
-rw-r--r--arch/mips/nxp/pnx8550/common/setup.c145
-rw-r--r--arch/mips/oprofile/Makefile18
-rw-r--r--arch/mips/oprofile/common.c129
-rw-r--r--arch/mips/oprofile/op_impl.h39
-rw-r--r--arch/mips/oprofile/op_model_loongson2.c161
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c397
-rw-r--r--arch/mips/oprofile/op_model_rm9000.c138
-rw-r--r--arch/mips/pci/Makefile63
-rw-r--r--arch/mips/pci/fixup-au1000.c43
-rw-r--r--arch/mips/pci/fixup-bcm63xx.c21
-rw-r--r--arch/mips/pci/fixup-capcella.c50
-rw-r--r--arch/mips/pci/fixup-cobalt.c254
-rw-r--r--arch/mips/pci/fixup-emma2rh.c97
-rw-r--r--arch/mips/pci/fixup-fuloong2e.c225
-rw-r--r--arch/mips/pci/fixup-ip32.c51
-rw-r--r--arch/mips/pci/fixup-jmr3927.c79
-rw-r--r--arch/mips/pci/fixup-lemote2f.c160
-rw-r--r--arch/mips/pci/fixup-malta.c103
-rw-r--r--arch/mips/pci/fixup-mpc30x.c49
-rw-r--r--arch/mips/pci/fixup-pmcmsp.c216
-rw-r--r--arch/mips/pci/fixup-pnx8550.c57
-rw-r--r--arch/mips/pci/fixup-rbtx4927.c73
-rw-r--r--arch/mips/pci/fixup-rbtx4938.c53
-rw-r--r--arch/mips/pci/fixup-rc32434.c70
-rw-r--r--arch/mips/pci/fixup-sb1250.c43
-rw-r--r--arch/mips/pci/fixup-sni.c170
-rw-r--r--arch/mips/pci/fixup-tb0219.c51
-rw-r--r--arch/mips/pci/fixup-tb0226.c86
-rw-r--r--arch/mips/pci/fixup-tb0287.c65
-rw-r--r--arch/mips/pci/fixup-wrppmc.c37
-rw-r--r--arch/mips/pci/fixup-yosemite.c41
-rw-r--r--arch/mips/pci/msi-octeon.c431
-rw-r--r--arch/mips/pci/ops-au1000.c308
-rw-r--r--arch/mips/pci/ops-bcm63xx.c467
-rw-r--r--arch/mips/pci/ops-bonito64.c161
-rw-r--r--arch/mips/pci/ops-bridge.c322
-rw-r--r--arch/mips/pci/ops-emma2rh.c182
-rw-r--r--arch/mips/pci/ops-gt64xxx_pci0.c152
-rw-r--r--arch/mips/pci/ops-lantiq.c116
-rw-r--r--arch/mips/pci/ops-loongson2.c216
-rw-r--r--arch/mips/pci/ops-mace.c102
-rw-r--r--arch/mips/pci/ops-msc.c148
-rw-r--r--arch/mips/pci/ops-nile4.c147
-rw-r--r--arch/mips/pci/ops-pmcmsp.c998
-rw-r--r--arch/mips/pci/ops-pnx8550.c282
-rw-r--r--arch/mips/pci/ops-rc32434.c207
-rw-r--r--arch/mips/pci/ops-sni.c164
-rw-r--r--arch/mips/pci/ops-titan-ht.c124
-rw-r--r--arch/mips/pci/ops-titan.c111
-rw-r--r--arch/mips/pci/ops-tx3927.c231
-rw-r--r--arch/mips/pci/ops-tx4927.c527
-rw-r--r--arch/mips/pci/ops-vr41xx.c126
-rw-r--r--arch/mips/pci/pci-bcm1480.c265
-rw-r--r--arch/mips/pci/pci-bcm1480ht.c216
-rw-r--r--arch/mips/pci/pci-bcm47xx.c59
-rw-r--r--arch/mips/pci/pci-bcm63xx.c224
-rw-r--r--arch/mips/pci/pci-bcm63xx.h27
-rw-r--r--arch/mips/pci/pci-emma2rh.c85
-rw-r--r--arch/mips/pci/pci-ip27.c228
-rw-r--r--arch/mips/pci/pci-ip32.c148
-rw-r--r--arch/mips/pci/pci-lantiq.c297
-rw-r--r--arch/mips/pci/pci-lantiq.h18
-rw-r--r--arch/mips/pci/pci-lasat.c88
-rw-r--r--arch/mips/pci/pci-octeon.c721
-rw-r--r--arch/mips/pci/pci-rc32434.c232
-rw-r--r--arch/mips/pci/pci-sb1250.c290
-rw-r--r--arch/mips/pci/pci-tx4927.c91
-rw-r--r--arch/mips/pci/pci-tx4938.c142
-rw-r--r--arch/mips/pci/pci-tx4939.c107
-rw-r--r--arch/mips/pci/pci-vr41xx.c320
-rw-r--r--arch/mips/pci/pci-vr41xx.h154
-rw-r--r--arch/mips/pci/pci-xlr.c214
-rw-r--r--arch/mips/pci/pci-yosemite.c67
-rw-r--r--arch/mips/pci/pci.c364
-rw-r--r--arch/mips/pci/pcie-octeon.c1402
-rw-r--r--arch/mips/pmc-sierra/Kconfig52
-rw-r--r--arch/mips/pmc-sierra/Platform14
-rw-r--r--arch/mips/pmc-sierra/msp71xx/Makefile14
-rw-r--r--arch/mips/pmc-sierra/msp71xx/gpio.c216
-rw-r--r--arch/mips/pmc-sierra/msp71xx/gpio_extended.c146
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_elb.c46
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_eth.c187
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c165
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq.c162
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c217
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_per.c135
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c107
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_pci.c50
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_prom.c503
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_serial.c93
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_setup.c246
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_smp.c77
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_smtc.c105
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_time.c101
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_usb.c263
-rw-r--r--arch/mips/pmc-sierra/yosemite/Makefile9
-rw-r--r--arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c169
-rw-r--r--arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h67
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht-irq.c51
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht.c415
-rw-r--r--arch/mips/pmc-sierra/yosemite/irq.c153
-rw-r--r--arch/mips/pmc-sierra/yosemite/prom.c143
-rw-r--r--arch/mips/pmc-sierra/yosemite/py-console.c117
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c223
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.h32
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c185
-rw-r--r--arch/mips/pnx833x/Makefile3
-rw-r--r--arch/mips/pnx833x/Platform5
-rw-r--r--arch/mips/pnx833x/common/Makefile1
-rw-r--r--arch/mips/pnx833x/common/interrupts.c315
-rw-r--r--arch/mips/pnx833x/common/platform.c320
-rw-r--r--arch/mips/pnx833x/common/prom.c64
-rw-r--r--arch/mips/pnx833x/common/reset.c44
-rw-r--r--arch/mips/pnx833x/common/setup.c64
-rw-r--r--arch/mips/pnx833x/stb22x/Makefile1
-rw-r--r--arch/mips/pnx833x/stb22x/board.c133
-rw-r--r--arch/mips/pnx8550/Makefile3
-rw-r--r--arch/mips/pnx8550/Platform7
-rw-r--r--arch/mips/pnx8550/common/Makefile26
-rw-r--r--arch/mips/pnx8550/common/int.c236
-rw-r--r--arch/mips/pnx8550/common/pci.c134
-rw-r--r--arch/mips/pnx8550/common/platform.c133
-rw-r--r--arch/mips/pnx8550/common/proc.c110
-rw-r--r--arch/mips/pnx8550/common/prom.c128
-rw-r--r--arch/mips/pnx8550/common/reset.c40
-rw-r--r--arch/mips/pnx8550/common/setup.c144
-rw-r--r--arch/mips/pnx8550/common/time.c151
-rw-r--r--arch/mips/pnx8550/jbs/Makefile4
-rw-r--r--arch/mips/pnx8550/jbs/board_setup.c56
-rw-r--r--arch/mips/pnx8550/jbs/init.c53
-rw-r--r--arch/mips/pnx8550/jbs/irqmap.c35
-rw-r--r--arch/mips/pnx8550/stb810/Makefile4
-rw-r--r--arch/mips/pnx8550/stb810/board_setup.c41
-rw-r--r--arch/mips/pnx8550/stb810/irqmap.c22
-rw-r--r--arch/mips/pnx8550/stb810/prom_init.c46
-rw-r--r--arch/mips/power/Makefile1
-rw-r--r--arch/mips/power/cpu.c43
-rw-r--r--arch/mips/power/hibernate.S62
-rw-r--r--arch/mips/powertv/Kconfig21
-rw-r--r--arch/mips/powertv/Makefile31
-rw-r--r--arch/mips/powertv/Platform7
-rw-r--r--arch/mips/powertv/asic/Kconfig28
-rw-r--r--arch/mips/powertv/asic/Makefile23
-rw-r--r--arch/mips/powertv/asic/asic-calliope.c101
-rw-r--r--arch/mips/powertv/asic/asic-cronus.c101
-rw-r--r--arch/mips/powertv/asic/asic-gaia.c96
-rw-r--r--arch/mips/powertv/asic/asic-zeus.c101
-rw-r--r--arch/mips/powertv/asic/asic_devices.c571
-rw-r--r--arch/mips/powertv/asic/asic_int.c124
-rw-r--r--arch/mips/powertv/asic/irq_asic.c116
-rw-r--r--arch/mips/powertv/asic/prealloc-calliope.c385
-rw-r--r--arch/mips/powertv/asic/prealloc-cronus.c340
-rw-r--r--arch/mips/powertv/asic/prealloc-cronuslite.c174
-rw-r--r--arch/mips/powertv/asic/prealloc-gaia.c589
-rw-r--r--arch/mips/powertv/asic/prealloc-zeus.c304
-rw-r--r--arch/mips/powertv/asic/prealloc.h70
-rw-r--r--arch/mips/powertv/init.c131
-rw-r--r--arch/mips/powertv/init.h26
-rw-r--r--arch/mips/powertv/ioremap.c136
-rw-r--r--arch/mips/powertv/memory.c354
-rw-r--r--arch/mips/powertv/pci/Makefile21
-rw-r--r--arch/mips/powertv/pci/fixup-powertv.c36
-rw-r--r--arch/mips/powertv/pci/powertv-pci.h31
-rw-r--r--arch/mips/powertv/powertv-clock.h26
-rw-r--r--arch/mips/powertv/powertv-usb.c403
-rw-r--r--arch/mips/powertv/powertv_setup.c320
-rw-r--r--arch/mips/powertv/reset.c47
-rw-r--r--arch/mips/powertv/reset.h26
-rw-r--r--arch/mips/powertv/time.c36
-rw-r--r--arch/mips/rb532/Makefile5
-rw-r--r--arch/mips/rb532/Platform7
-rw-r--r--arch/mips/rb532/devices.c348
-rw-r--r--arch/mips/rb532/gpio.c200
-rw-r--r--arch/mips/rb532/irq.c236
-rw-r--r--arch/mips/rb532/prom.c146
-rw-r--r--arch/mips/rb532/serial.c54
-rw-r--r--arch/mips/rb532/setup.c79
-rw-r--r--arch/mips/rb532/time.c66
-rw-r--r--arch/mips/sgi-ip22/Makefile11
-rw-r--r--arch/mips/sgi-ip22/Platform34
-rw-r--r--arch/mips/sgi-ip22/ip22-berr.c116
-rw-r--r--arch/mips/sgi-ip22/ip22-eisa.c147
-rw-r--r--arch/mips/sgi-ip22/ip22-hpc.c63
-rw-r--r--arch/mips/sgi-ip22/ip22-int.c333
-rw-r--r--arch/mips/sgi-ip22/ip22-mc.c237
-rw-r--r--arch/mips/sgi-ip22/ip22-nvram.c121
-rw-r--r--arch/mips/sgi-ip22/ip22-platform.c209
-rw-r--r--arch/mips/sgi-ip22/ip22-reset.c207
-rw-r--r--arch/mips/sgi-ip22/ip22-setup.c99
-rw-r--r--arch/mips/sgi-ip22/ip22-time.c131
-rw-r--r--arch/mips/sgi-ip22/ip28-berr.c502
-rw-r--r--arch/mips/sgi-ip27/Kconfig53
-rw-r--r--arch/mips/sgi-ip27/Makefile10
-rw-r--r--arch/mips/sgi-ip27/Platform19
-rw-r--r--arch/mips/sgi-ip27/TODO19
-rw-r--r--arch/mips/sgi-ip27/ip27-berr.c93
-rw-r--r--arch/mips/sgi-ip27/ip27-console.c40
-rw-r--r--arch/mips/sgi-ip27/ip27-hubio.c185
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c221
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c423
-rw-r--r--arch/mips/sgi-ip27/ip27-klconfig.c135
-rw-r--r--arch/mips/sgi-ip27/ip27-klnuma.c132
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c509
-rw-r--r--arch/mips/sgi-ip27/ip27-nmi.c244
-rw-r--r--arch/mips/sgi-ip27/ip27-reset.c81
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c243
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c234
-rw-r--r--arch/mips/sgi-ip27/ip27-xtalk.c136
-rw-r--r--arch/mips/sgi-ip32/Makefile7
-rw-r--r--arch/mips/sgi-ip32/Platform11
-rw-r--r--arch/mips/sgi-ip32/crime.c103
-rw-r--r--arch/mips/sgi-ip32/ip32-berr.c36
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c507
-rw-r--r--arch/mips/sgi-ip32/ip32-memory.c48
-rw-r--r--arch/mips/sgi-ip32/ip32-platform.c111
-rw-r--r--arch/mips/sgi-ip32/ip32-reset.c205
-rw-r--r--arch/mips/sgi-ip32/ip32-setup.c102
-rw-r--r--arch/mips/sibyte/Kconfig171
-rw-r--r--arch/mips/sibyte/Makefile27
-rw-r--r--arch/mips/sibyte/Platform43
-rw-r--r--arch/mips/sibyte/bcm1480/Makefile3
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c373
-rw-r--r--arch/mips/sibyte/bcm1480/setup.c139
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c198
-rw-r--r--arch/mips/sibyte/bcm1480/time.c27
-rw-r--r--arch/mips/sibyte/common/Makefile3
-rw-r--r--arch/mips/sibyte/common/cfe.c344
-rw-r--r--arch/mips/sibyte/common/cfe_console.c80
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c607
-rw-r--r--arch/mips/sibyte/sb1250/Makefile4
-rw-r--r--arch/mips/sibyte/sb1250/bus_watcher.c258
-rw-r--r--arch/mips/sibyte/sb1250/irq.c330
-rw-r--r--arch/mips/sibyte/sb1250/setup.c247
-rw-r--r--arch/mips/sibyte/sb1250/smp.c186
-rw-r--r--arch/mips/sibyte/sb1250/time.c27
-rw-r--r--arch/mips/sibyte/swarm/Makefile4
-rw-r--r--arch/mips/sibyte/swarm/platform.c139
-rw-r--r--arch/mips/sibyte/swarm/rtc_m41t81.c233
-rw-r--r--arch/mips/sibyte/swarm/rtc_xicor1241.c210
-rw-r--r--arch/mips/sibyte/swarm/setup.c184
-rw-r--r--arch/mips/sibyte/swarm/swarm-i2c.c35
-rw-r--r--arch/mips/sni/Makefile6
-rw-r--r--arch/mips/sni/Platform11
-rw-r--r--arch/mips/sni/a20r.c239
-rw-r--r--arch/mips/sni/eisa.c50
-rw-r--r--arch/mips/sni/irq.c82
-rw-r--r--arch/mips/sni/pcimt.c330
-rw-r--r--arch/mips/sni/pcit.c289
-rw-r--r--arch/mips/sni/reset.c46
-rw-r--r--arch/mips/sni/rm200.c489
-rw-r--r--arch/mips/sni/setup.c261
-rw-r--r--arch/mips/sni/time.c190
-rw-r--r--arch/mips/txx9/Kconfig126
-rw-r--r--arch/mips/txx9/Makefile17
-rw-r--r--arch/mips/txx9/Platform10
-rw-r--r--arch/mips/txx9/generic/7segled.c115
-rw-r--r--arch/mips/txx9/generic/Makefile13
-rw-r--r--arch/mips/txx9/generic/irq_tx3927.c25
-rw-r--r--arch/mips/txx9/generic/irq_tx4927.c49
-rw-r--r--arch/mips/txx9/generic/irq_tx4938.c37
-rw-r--r--arch/mips/txx9/generic/irq_tx4939.c216
-rw-r--r--arch/mips/txx9/generic/mem_tx4927.c75
-rw-r--r--arch/mips/txx9/generic/pci.c435
-rw-r--r--arch/mips/txx9/generic/setup.c982
-rw-r--r--arch/mips/txx9/generic/setup_tx3927.c137
-rw-r--r--arch/mips/txx9/generic/setup_tx4927.c340
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c488
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c583
-rw-r--r--arch/mips/txx9/generic/smsc_fdc37m81x.c172
-rw-r--r--arch/mips/txx9/generic/spi_eeprom.c104
-rw-r--r--arch/mips/txx9/jmr3927/Makefile5
-rw-r--r--arch/mips/txx9/jmr3927/irq.c128
-rw-r--r--arch/mips/txx9/jmr3927/prom.c52
-rw-r--r--arch/mips/txx9/jmr3927/setup.c217
-rw-r--r--arch/mips/txx9/rbtx4927/Makefile1
-rw-r--r--arch/mips/txx9/rbtx4927/irq.c198
-rw-r--r--arch/mips/txx9/rbtx4927/prom.c41
-rw-r--r--arch/mips/txx9/rbtx4927/setup.c368
-rw-r--r--arch/mips/txx9/rbtx4938/Makefile1
-rw-r--r--arch/mips/txx9/rbtx4938/irq.c157
-rw-r--r--arch/mips/txx9/rbtx4938/prom.c23
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c370
-rw-r--r--arch/mips/txx9/rbtx4939/Makefile1
-rw-r--r--arch/mips/txx9/rbtx4939/irq.c95
-rw-r--r--arch/mips/txx9/rbtx4939/prom.c17
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c555
-rw-r--r--arch/mips/vr41xx/Kconfig103
-rw-r--r--arch/mips/vr41xx/Platform32
-rw-r--r--arch/mips/vr41xx/casio-e55/Makefile5
-rw-r--r--arch/mips/vr41xx/casio-e55/setup.c40
-rw-r--r--arch/mips/vr41xx/common/Makefile5
-rw-r--r--arch/mips/vr41xx/common/bcu.c222
-rw-r--r--arch/mips/vr41xx/common/cmu.c257
-rw-r--r--arch/mips/vr41xx/common/giu.c122
-rw-r--r--arch/mips/vr41xx/common/icu.c729
-rw-r--r--arch/mips/vr41xx/common/init.c77
-rw-r--r--arch/mips/vr41xx/common/irq.c124
-rw-r--r--arch/mips/vr41xx/common/pmu.c135
-rw-r--r--arch/mips/vr41xx/common/rtc.c117
-rw-r--r--arch/mips/vr41xx/common/siu.c155
-rw-r--r--arch/mips/vr41xx/common/type.c24
-rw-r--r--arch/mips/vr41xx/ibm-workpad/Makefile5
-rw-r--r--arch/mips/vr41xx/ibm-workpad/setup.c40
-rw-r--r--arch/mips/wrppmc/Makefile12
-rw-r--r--arch/mips/wrppmc/Platform7
-rw-r--r--arch/mips/wrppmc/irq.c56
-rw-r--r--arch/mips/wrppmc/pci.c54
-rw-r--r--arch/mips/wrppmc/reset.c40
-rw-r--r--arch/mips/wrppmc/serial.c80
-rw-r--r--arch/mips/wrppmc/setup.c128
-rw-r--r--arch/mips/wrppmc/time.c39
1540 files changed, 252826 insertions, 0 deletions
diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild
new file mode 100644
index 00000000..7dd65cfa
--- /dev/null
+++ b/arch/mips/Kbuild
@@ -0,0 +1,19 @@
+# Fail on warnings - also for files referenced in subdirs
+# -Werror can be disabled for specific files using:
+# CFLAGS_<file.o> := -Wno-error
+subdir-ccflags-y := -Werror
+
+# platform specific definitions
+include arch/mips/Kbuild.platforms
+obj-y := $(platform-y)
+
+# make clean traverses $(obj-) without having included .config, so
+# everything ends up here
+obj- := $(platform-)
+
+# mips object files
+# The object files are linked as core-y files would be linked
+
+obj-y += kernel/
+obj-y += mm/
+obj-y += math-emu/
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
new file mode 100644
index 00000000..aef6c917
--- /dev/null
+++ b/arch/mips/Kbuild.platforms
@@ -0,0 +1,34 @@
+# All platforms listed in alphabetic order
+
+platforms += alchemy
+platforms += ar7
+platforms += ath79
+platforms += bcm47xx
+platforms += bcm63xx
+platforms += cavium-octeon
+platforms += cobalt
+platforms += dec
+platforms += emma
+platforms += jazz
+platforms += jz4740
+platforms += lantiq
+platforms += lasat
+platforms += loongson
+platforms += mipssim
+platforms += mti-malta
+platforms += pmc-sierra
+platforms += pnx833x
+platforms += pnx8550
+platforms += powertv
+platforms += rb532
+platforms += sgi-ip22
+platforms += sgi-ip27
+platforms += sgi-ip32
+platforms += sibyte
+platforms += sni
+platforms += txx9
+platforms += vr41xx
+platforms += wrppmc
+
+# include the platform specific files
+include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
new file mode 100644
index 00000000..653da62d
--- /dev/null
+++ b/arch/mips/Kconfig
@@ -0,0 +1,2508 @@
+config MIPS
+ bool
+ default y
+ select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_IDE
+ select HAVE_OPROFILE
+ select HAVE_IRQ_WORK
+ select HAVE_PERF_EVENTS
+ select PERF_USE_VMALLOC
+ select HAVE_ARCH_KGDB
+ select HAVE_FUNCTION_TRACER
+ select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+ select HAVE_DYNAMIC_FTRACE
+ select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_C_RECORDMCOUNT
+ select HAVE_FUNCTION_GRAPH_TRACER
+ select HAVE_KPROBES
+ select HAVE_KRETPROBES
+ select RTC_LIB if !MACH_LOONGSON
+ select GENERIC_ATOMIC64 if !64BIT
+ select HAVE_DMA_ATTRS
+ select HAVE_DMA_API_DEBUG
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_PROBE
+ select GENERIC_IRQ_SHOW
+ select HAVE_ARCH_JUMP_LABEL
+
+menu "Machine selection"
+
+config ZONE_DMA
+ bool
+
+choice
+ prompt "System type"
+ default SGI_IP22
+
+config MIPS_ALCHEMY
+ bool "Alchemy processor based machines"
+ select 64BIT_PHYS_ADDR
+ select CEVT_R4K_LIB
+ select CSRC_R4K_LIB
+ select IRQ_CPU
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_APM_EMULATION
+ select GENERIC_GPIO
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select SYS_SUPPORTS_ZBOOT
+
+config AR7
+ bool "Texas Instruments AR7"
+ select BOOT_ELF32
+ select DMA_NONCOHERENT
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select NO_EXCEPT_FILL
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_ZBOOT_UART16550
+ select ARCH_REQUIRE_GPIOLIB
+ select GCD
+ select VLYNQ
+ help
+ Support for the Texas Instruments AR7 System-on-a-Chip
+ family: TNETD7100, 7200 and 7300.
+
+config ATH79
+ bool "Atheros AR71XX/AR724X/AR913X based boards"
+ select ARCH_REQUIRE_GPIOLIB
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select MIPS_MACHINE
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ help
+ Support for the Atheros AR71XX/AR724X/AR913X SoCs.
+
+config BCM47XX
+ bool "Broadcom BCM47XX based boards"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SSB
+ select SSB_DRIVER_MIPS
+ select SSB_DRIVER_EXTIF
+ select SSB_EMBEDDED
+ select SSB_B43_PCI_BRIDGE if PCI
+ select SSB_PCICORE_HOSTMODE if PCI
+ select GENERIC_GPIO
+ select SYS_HAS_EARLY_PRINTK
+ select CFE
+ help
+ Support for BCM47XX based boards
+
+config BCM63XX
+ bool "Broadcom BCM63XX based boards"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+ select SWAP_IO_SPACE
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for BCM63XX based boards
+
+config MIPS_COBALT
+ bool "Cobalt Server"
+ select CEVT_R4K
+ select CSRC_R4K
+ select CEVT_GT641XX
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select I8253
+ select I8259
+ select IRQ_CPU
+ select IRQ_GT641XX
+ select PCI_GT64XXX_PCI0
+ select PCI
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MACH_DECSTATION
+ bool "DECstations"
+ select BOOT_ELF32
+ select CEVT_DS1287
+ select CEVT_R4K
+ select CSRC_IOASIC
+ select CSRC_R4K
+ select CPU_DADDI_WORKAROUNDS if 64BIT
+ select CPU_R4000_WORKAROUNDS if 64BIT
+ select CPU_R4400_WORKAROUNDS if 64BIT
+ select DMA_NONCOHERENT
+ select NO_IOPORT
+ select IRQ_CPU
+ select SYS_HAS_CPU_R3000
+ select SYS_HAS_CPU_R4X00
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_128HZ
+ select SYS_SUPPORTS_256HZ
+ select SYS_SUPPORTS_1024HZ
+ help
+ This enables support for DEC's MIPS based workstations. For details
+ see the Linux/MIPS FAQ on <http://www.linux-mips.org/> and the
+ DECstation porting pages on <http://decstation.unix-ag.org/>.
+
+ If you have one of the following DECstation Models you definitely
+ want to choose R4xx0 for the CPU Type:
+
+ DECstation 5000/50
+ DECstation 5000/150
+ DECstation 5000/260
+ DECsystem 5900/260
+
+ otherwise choose R3000.
+
+config MACH_JAZZ
+ bool "Jazz family of machines"
+ select ARC
+ select ARC32
+ select ARCH_MAY_HAVE_PC_FDC
+ select CEVT_R4K
+ select CSRC_R4K
+ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
+ select GENERIC_ISA_DMA
+ select IRQ_CPU
+ select I8253
+ select I8259
+ select ISA
+ select SYS_HAS_CPU_R4X00
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_100HZ
+ help
+ This a family of machines based on the MIPS R4030 chipset which was
+ used by several vendors to build RISC/os and Windows NT workstations.
+ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
+ Olivetti M700-10 workstations.
+
+config MACH_JZ4740
+ bool "Ingenic JZ4740 based machines"
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select SYS_HAS_EARLY_PRINTK
+ select HAVE_PWM
+ select HAVE_CLK
+
+config LANTIQ
+ bool "Lantiq based platforms"
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select CEVT_R4K
+ select CSRC_R4K
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_MULTITHREADING
+ select SYS_HAS_EARLY_PRINTK
+ select ARCH_REQUIRE_GPIOLIB
+ select SWAP_IO_SPACE
+ select BOOT_RAW
+ select HAVE_CLK
+ select MIPS_MACHINE
+
+config LASAT
+ bool "LASAT Networks platforms"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select SYS_HAS_EARLY_PRINTK
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select PCI_GT64XXX_PCI0
+ select MIPS_NILE4
+ select R5000_CPU_SCACHE
+ select SYS_HAS_CPU_R5000
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config MACH_LOONGSON
+ bool "Loongson family of machines"
+ select SYS_SUPPORTS_ZBOOT
+ help
+ This enables the support of Loongson family of machines.
+
+ Loongson is a family of general-purpose MIPS-compatible CPUs.
+ developed at Institute of Computing Technology (ICT),
+ Chinese Academy of Sciences (CAS) in the People's Republic
+ of China. The chief architect is Professor Weiwu Hu.
+
+config MIPS_MALTA
+ bool "MIPS Malta board"
+ select ARCH_MAY_HAVE_PC_FDC
+ select BOOT_ELF32
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA
+ select IRQ_CPU
+ select IRQ_GIC
+ select HW_HAS_PCI
+ select I8253
+ select I8259
+ select MIPS_BOARDS_GEN
+ select MIPS_BONITO64
+ select MIPS_CPU_SCACHE
+ select PCI_GT64XXX_PCI0
+ select MIPS_MSC
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_CPU_RM7000
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_MIPS_CMP
+ select SYS_SUPPORTS_MULTITHREADING
+ select SYS_SUPPORTS_SMARTMIPS
+ select SYS_SUPPORTS_ZBOOT
+ help
+ This enables support for the MIPS Technologies Malta evaluation
+ board.
+
+config MIPS_SIM
+ bool 'MIPS simulator (MIPSsim)'
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select SYS_HAS_EARLY_PRINTK
+ select IRQ_CPU
+ select BOOT_RAW
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_MULTITHREADING
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This option enables support for MIPS Technologies MIPSsim software
+ emulator.
+
+config NEC_MARKEINS
+ bool "NEC EMMA2RH Mark-eins board"
+ select SOC_EMMA2RH
+ select HW_HAS_PCI
+ help
+ This enables support for the NEC Electronics Mark-eins boards.
+
+config MACH_VR41XX
+ bool "NEC VR4100 series based machines"
+ select CEVT_R4K
+ select CSRC_R4K
+ select SYS_HAS_CPU_VR41XX
+ select ARCH_REQUIRE_GPIOLIB
+
+config NXP_STB220
+ bool "NXP STB220 board"
+ select SOC_PNX833X
+ help
+ Support for NXP Semiconductors STB220 Development Board.
+
+config NXP_STB225
+ bool "NXP 225 board"
+ select SOC_PNX833X
+ select SOC_PNX8335
+ help
+ Support for NXP Semiconductors STB225 Development Board.
+
+config PNX8550_JBS
+ bool "NXP PNX8550 based JBS board"
+ select PNX8550
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config PNX8550_STB810
+ bool "NXP PNX8550 based STB810 board"
+ select PNX8550
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config PMC_MSP
+ bool "PMC-Sierra MSP chipsets"
+ depends on EXPERIMENTAL
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select SWAP_IO_SPACE
+ select NO_EXCEPT_FILL
+ select BOOT_RAW
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select IRQ_CPU
+ select SERIAL_8250
+ select SERIAL_8250_CONSOLE
+ help
+ This adds support for the PMC-Sierra family of Multi-Service
+ Processor System-On-A-Chips. These parts include a number
+ of integrated peripherals, interfaces and DSPs in addition to
+ a variety of MIPS cores.
+
+config PMC_YOSEMITE
+ bool "PMC-Sierra Yosemite eval board"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_COHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select IRQ_CPU_RM7K
+ select IRQ_CPU_RM9K
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_RM9000
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_SMP
+ help
+ Yosemite is an evaluation board for the RM9000x2 processor
+ manufactured by PMC-Sierra.
+
+config POWERTV
+ bool "Cisco PowerTV"
+ select BOOT_ELF32
+ select CEVT_R4K
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
+ select CSRC_POWERTV
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select USB_OHCI_LITTLE_ENDIAN
+ help
+ This enables support for the Cisco PowerTV Platform.
+
+config SGI_IP22
+ bool "SGI IP22 (Indy/Indigo2)"
+ select ARC
+ select ARC32
+ select BOOT_ELF32
+ select CEVT_R4K
+ select CSRC_R4K
+ select DEFAULT_SGI_PARTITION
+ select DMA_NONCOHERENT
+ select HW_HAS_EISA
+ select I8253
+ select I8259
+ select IP22_CPU_SCACHE
+ select IRQ_CPU
+ select GENERIC_ISA_DMA_SUPPORT_BROKEN
+ select SGI_HAS_I8042
+ select SGI_HAS_INDYDOG
+ select SGI_HAS_HAL2
+ select SGI_HAS_SEEQ
+ select SGI_HAS_WD93
+ select SGI_HAS_ZILOG
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R4X00
+ select SYS_HAS_CPU_R5000
+ #
+ # Disable EARLY_PRINTK for now since it leads to overwritten prom
+ # memory during early boot on some machines.
+ #
+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+ # for a more details discussion
+ #
+ # select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ help
+ This are the SGI Indy, Challenge S and Indigo2, as well as certain
+ OEM variants like the Tandem CMN B006S. To compile a Linux kernel
+ that runs on these, say Y here.
+
+config SGI_IP27
+ bool "SGI IP27 (Origin200/2000)"
+ select ARC
+ select ARC64
+ select BOOT_ELF64
+ select DEFAULT_SGI_PARTITION
+ select DMA_COHERENT
+ select SYS_HAS_EARLY_PRINTK
+ select HW_HAS_PCI
+ select NR_CPUS_DEFAULT_64
+ select SYS_HAS_CPU_R10000
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_NUMA
+ select SYS_SUPPORTS_SMP
+ help
+ This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
+ workstations. To compile a Linux kernel that runs on these, say Y
+ here.
+
+config SGI_IP28
+ bool "SGI IP28 (Indigo2 R10k) (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ select ARC
+ select ARC64
+ select BOOT_ELF64
+ select CEVT_R4K
+ select CSRC_R4K
+ select DEFAULT_SGI_PARTITION
+ select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA_SUPPORT_BROKEN
+ select IRQ_CPU
+ select HW_HAS_EISA
+ select I8253
+ select I8259
+ select SGI_HAS_I8042
+ select SGI_HAS_INDYDOG
+ select SGI_HAS_HAL2
+ select SGI_HAS_SEEQ
+ select SGI_HAS_WD93
+ select SGI_HAS_ZILOG
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R10000
+ #
+ # Disable EARLY_PRINTK for now since it leads to overwritten prom
+ # memory during early boot on some machines.
+ #
+ # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+ # for a more details discussion
+ #
+ # select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ help
+ This is the SGI Indigo2 with R10000 processor. To compile a Linux
+ kernel that runs on these, say Y here.
+
+config SGI_IP32
+ bool "SGI IP32 (O2)"
+ select ARC
+ select ARC32
+ select BOOT_ELF32
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select R5000_CPU_SCACHE
+ select RM7000_CPU_SCACHE
+ select SYS_HAS_CPU_R5000
+ select SYS_HAS_CPU_R10000 if BROKEN
+ select SYS_HAS_CPU_RM7000
+ select SYS_HAS_CPU_NEVADA
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ help
+ If you want this kernel to run on SGI O2 workstation, say Y here.
+
+config SIBYTE_CRHINE
+ bool "Sibyte BCM91120C-CRhine"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_BCM1120
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_CARMEL
+ bool "Sibyte BCM91120x-Carmel"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_BCM1120
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_CRHONE
+ bool "Sibyte BCM91125C-CRhone"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_BCM1125
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_RHONE
+ bool "Sibyte BCM91125E-Rhone"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select SIBYTE_BCM1125H
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_SWARM
+ bool "Sibyte BCM91250A-SWARM"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select HAVE_PATA_PLATFORM
+ select NR_CPUS_DEFAULT_2
+ select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select ZONE_DMA32 if 64BIT
+
+config SIBYTE_LITTLESUR
+ bool "Sibyte BCM91250C2-LittleSur"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select HAVE_PATA_PLATFORM
+ select NR_CPUS_DEFAULT_2
+ select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_SENTOSA
+ bool "Sibyte BCM91250E-Sentosa"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select NR_CPUS_DEFAULT_2
+ select SIBYTE_SB1250
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config SIBYTE_BIGSUR
+ bool "Sibyte BCM91480B-BigSur"
+ select BOOT_ELF32
+ select DMA_COHERENT
+ select NR_CPUS_DEFAULT_4
+ select SIBYTE_BCM1x80
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_SB1
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select ZONE_DMA32 if 64BIT
+
+config SNI_RM
+ bool "SNI RM200/300/400"
+ select ARC if CPU_LITTLE_ENDIAN
+ select ARC32 if CPU_LITTLE_ENDIAN
+ select SNIPROM if CPU_BIG_ENDIAN
+ select ARCH_MAY_HAVE_PC_FDC
+ select BOOT_ELF32
+ select CEVT_R4K
+ select CSRC_R4K
+ select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
+ select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA
+ select HW_HAS_EISA
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select I8253
+ select I8259
+ select ISA
+ select SWAP_IO_SPACE if CPU_BIG_ENDIAN
+ select SYS_HAS_CPU_R4X00
+ select SYS_HAS_CPU_R5000
+ select SYS_HAS_CPU_R10000
+ select R5000_CPU_SCACHE
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ The SNI RM200/300/400 are MIPS-based machines manufactured by
+ Siemens Nixdorf Informationssysteme (SNI), parent company of Pyramid
+ Technology and now in turn merged with Fujitsu. Say Y here to
+ support this machine type.
+
+config MACH_TX39XX
+ bool "Toshiba TX39 series based machines"
+
+config MACH_TX49XX
+ bool "Toshiba TX49 series based machines"
+
+config MIKROTIK_RB532
+ bool "Mikrotik RB532 boards"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SWAP_IO_SPACE
+ select BOOT_RAW
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support the Mikrotik(tm) RouterBoard 532 series,
+ based on the IDT RC32434 SoC.
+
+config WR_PPMC
+ bool "Wind River PPMC board"
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select BOOT_ELF32
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select PCI_GT64XXX_PCI0
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_CPU_MIPS64_R1
+ select SYS_HAS_CPU_NEVADA
+ select SYS_HAS_CPU_RM7000
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This enables support for the Wind River MIPS32 4KC PPMC evaluation
+ board, which is based on GT64120 bridge chip.
+
+config CAVIUM_OCTEON_SIMULATOR
+ bool "Cavium Networks Octeon Simulator"
+ select CEVT_R4K
+ select 64BIT_PHYS_ADDR
+ select DMA_COHERENT
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select SYS_HAS_CPU_CAVIUM_OCTEON
+ help
+ The Octeon simulator is software performance model of the Cavium
+ Octeon Processor. It supports simulating Octeon processors on x86
+ hardware.
+
+config CAVIUM_OCTEON_REFERENCE_BOARD
+ bool "Cavium Networks Octeon reference board"
+ select CEVT_R4K
+ select 64BIT_PHYS_ADDR
+ select DMA_COHERENT
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_HAS_CPU_CAVIUM_OCTEON
+ select SWAP_IO_SPACE
+ select HW_HAS_PCI
+ select ARCH_SUPPORTS_MSI
+ select ZONE_DMA32
+ select USB_ARCH_HAS_OHCI
+ select USB_ARCH_HAS_EHCI
+ help
+ This option supports all of the Octeon reference boards from Cavium
+ Networks. It builds a kernel that dynamically determines the Octeon
+ CPU type and supports all known board reference implementations.
+ Some of the supported boards are:
+ EBT3000
+ EBH3000
+ EBH3100
+ Thunder
+ Kodama
+ Hikari
+ Say Y here for most Octeon reference boards.
+
+config NLM_XLR_BOARD
+ bool "Netlogic XLR/XLS based systems"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select NLM_COMMON
+ select NLM_XLR
+ select SYS_HAS_CPU_XLR
+ select SYS_SUPPORTS_SMP
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select 64BIT_PHYS_ADDR
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select DMA_COHERENT
+ select NR_CPUS_DEFAULT_32
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select ZONE_DMA if 64BIT
+ select SYNC_R4K
+ select SYS_HAS_EARLY_PRINTK
+ help
+ Support for systems based on Netlogic XLR and XLS processors.
+ Say Y here if you have a XLR or XLS based board.
+
+endchoice
+
+source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ath79/Kconfig"
+source "arch/mips/bcm63xx/Kconfig"
+source "arch/mips/jazz/Kconfig"
+source "arch/mips/jz4740/Kconfig"
+source "arch/mips/lantiq/Kconfig"
+source "arch/mips/lasat/Kconfig"
+source "arch/mips/pmc-sierra/Kconfig"
+source "arch/mips/powertv/Kconfig"
+source "arch/mips/sgi-ip27/Kconfig"
+source "arch/mips/sibyte/Kconfig"
+source "arch/mips/txx9/Kconfig"
+source "arch/mips/vr41xx/Kconfig"
+source "arch/mips/cavium-octeon/Kconfig"
+source "arch/mips/loongson/Kconfig"
+source "arch/mips/netlogic/Kconfig"
+
+endmenu
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+
+config ARCH_HAS_ILOG2_U32
+ bool
+ default n
+
+config ARCH_HAS_ILOG2_U64
+ bool
+ default n
+
+config ARCH_SUPPORTS_OPROFILE
+ bool
+ default y if !MIPS_MT_SMTC
+
+config GENERIC_HWEIGHT
+ bool
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config GENERIC_CLOCKEVENTS
+ bool
+ default y
+
+config GENERIC_CMOS_UPDATE
+ bool
+ default y
+
+config SCHED_OMIT_FRAME_POINTER
+ bool
+ default y
+
+#
+# Select some configuration options automatically based on user selections.
+#
+config ARC
+ bool
+
+config ARCH_MAY_HAVE_PC_FDC
+ bool
+
+config BOOT_RAW
+ bool
+
+config CEVT_BCM1480
+ bool
+
+config CEVT_DS1287
+ bool
+
+config CEVT_GT641XX
+ bool
+
+config CEVT_R4K_LIB
+ bool
+
+config CEVT_R4K
+ select CEVT_R4K_LIB
+ bool
+
+config CEVT_SB1250
+ bool
+
+config CEVT_TXX9
+ bool
+
+config CSRC_BCM1480
+ bool
+
+config CSRC_IOASIC
+ bool
+
+config CSRC_POWERTV
+ bool
+
+config CSRC_R4K_LIB
+ bool
+
+config CSRC_R4K
+ select CSRC_R4K_LIB
+ bool
+
+config CSRC_SB1250
+ bool
+
+config GPIO_TXX9
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ bool
+
+config CFE
+ bool
+
+config ARCH_DMA_ADDR_T_64BIT
+ def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT
+
+config DMA_COHERENT
+ bool
+
+config DMA_NONCOHERENT
+ bool
+ select NEED_DMA_MAP_STATE
+
+config NEED_DMA_MAP_STATE
+ bool
+
+config SYS_HAS_EARLY_PRINTK
+ bool
+
+config HOTPLUG_CPU
+ bool "Support for hot-pluggable CPUs"
+ depends on SMP && HOTPLUG && SYS_SUPPORTS_HOTPLUG_CPU
+ help
+ Say Y here to allow turning CPUs off and on. CPUs can be
+ controlled through /sys/devices/system/cpu.
+ (Note: power management support will enable this option
+ automatically on SMP systems. )
+ Say N if you want to disable CPU hotplug.
+
+config SYS_SUPPORTS_HOTPLUG_CPU
+ bool
+
+config I8259
+ bool
+
+config MIPS_BONITO64
+ bool
+
+config MIPS_MSC
+ bool
+
+config MIPS_NILE4
+ bool
+
+config MIPS_DISABLE_OBSOLETE_IDE
+ bool
+
+config SYNC_R4K
+ bool
+
+config MIPS_MACHINE
+ def_bool n
+
+config NO_IOPORT
+ def_bool n
+
+config GENERIC_ISA_DMA
+ bool
+ select ZONE_DMA if GENERIC_ISA_DMA_SUPPORT_BROKEN=n
+ select ISA_DMA_API
+
+config GENERIC_ISA_DMA_SUPPORT_BROKEN
+ bool
+ select GENERIC_ISA_DMA
+
+config ISA_DMA_API
+ bool
+
+config GENERIC_GPIO
+ bool
+
+#
+# Endianess selection. Sufficiently obscure so many users don't know what to
+# answer,so we try hard to limit the available choices. Also the use of a
+# choice statement should be more obvious to the user.
+#
+choice
+ prompt "Endianess selection"
+ help
+ Some MIPS machines can be configured for either little or big endian
+ byte order. These modes require different kernels and a different
+ Linux distribution. In general there is one preferred byteorder for a
+ particular system but some systems are just as commonly used in the
+ one or the other endianness.
+
+config CPU_BIG_ENDIAN
+ bool "Big endian"
+ depends on SYS_SUPPORTS_BIG_ENDIAN
+
+config CPU_LITTLE_ENDIAN
+ bool "Little endian"
+ depends on SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+
+endchoice
+
+config EXPORT_UASM
+ bool
+
+config SYS_SUPPORTS_APM_EMULATION
+ bool
+
+config SYS_SUPPORTS_BIG_ENDIAN
+ bool
+
+config SYS_SUPPORTS_LITTLE_ENDIAN
+ bool
+
+config SYS_SUPPORTS_HUGETLBFS
+ bool
+ depends on CPU_SUPPORTS_HUGEPAGES && 64BIT
+ default y
+
+config IRQ_CPU
+ bool
+
+config IRQ_CPU_RM7K
+ bool
+
+config IRQ_CPU_RM9K
+ bool
+
+config IRQ_MSP_SLP
+ bool
+
+config IRQ_MSP_CIC
+ bool
+
+config IRQ_TXX9
+ bool
+
+config IRQ_GT641XX
+ bool
+
+config IRQ_GIC
+ bool
+
+config MIPS_BOARDS_GEN
+ bool
+
+config PCI_GT64XXX_PCI0
+ bool
+
+config NO_EXCEPT_FILL
+ bool
+
+config MIPS_RM9122
+ bool
+ select SERIAL_RM9000
+
+config SOC_EMMA2RH
+ bool
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_HAS_CPU_R5500
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+
+config SOC_PNX833X
+ bool
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select DMA_NONCOHERENT
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select GENERIC_GPIO
+ select CPU_MIPSR2_IRQ_VI
+
+config SOC_PNX8335
+ bool
+ select SOC_PNX833X
+
+config PNX8550
+ bool
+ select SOC_PNX8550
+
+config SOC_PNX8550
+ bool
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select GENERIC_GPIO
+
+config SWAP_IO_SPACE
+ bool
+
+config SERIAL_RM9000
+ bool
+
+config SGI_HAS_INDYDOG
+ bool
+
+config SGI_HAS_HAL2
+ bool
+
+config SGI_HAS_SEEQ
+ bool
+
+config SGI_HAS_WD93
+ bool
+
+config SGI_HAS_ZILOG
+ bool
+
+config SGI_HAS_I8042
+ bool
+
+config DEFAULT_SGI_PARTITION
+ bool
+
+config ARC32
+ bool
+
+config SNIPROM
+ bool
+
+config BOOT_ELF32
+ bool
+
+config MIPS_L1_CACHE_SHIFT
+ int
+ default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL
+ default "6" if MIPS_CPU_SCACHE
+ default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
+ default "5"
+
+config HAVE_STD_PC_SERIAL_PORT
+ bool
+
+config ARC_CONSOLE
+ bool "ARC console support"
+ depends on SGI_IP22 || SGI_IP28 || (SNI_RM && CPU_LITTLE_ENDIAN)
+
+config ARC_MEMORY
+ bool
+ depends on MACH_JAZZ || SNI_RM || SGI_IP32
+ default y
+
+config ARC_PROMLIB
+ bool
+ depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP28 || SGI_IP32
+ default y
+
+config ARC64
+ bool
+
+config BOOT_ELF64
+ bool
+
+menu "CPU selection"
+
+choice
+ prompt "CPU type"
+ default CPU_R4X00
+
+config CPU_LOONGSON2E
+ bool "Loongson 2E"
+ depends on SYS_HAS_CPU_LOONGSON2E
+ select CPU_LOONGSON2
+ help
+ The Loongson 2E processor implements the MIPS III instruction set
+ with many extensions.
+
+ It has an internal FPGA northbridge, which is compatible to
+ bonito64.
+
+config CPU_LOONGSON2F
+ bool "Loongson 2F"
+ depends on SYS_HAS_CPU_LOONGSON2F
+ select CPU_LOONGSON2
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ The Loongson 2F processor implements the MIPS III instruction set
+ with many extensions.
+
+ Loongson2F have built-in DDR2 and PCIX controller. The PCIX controller
+ have a similar programming interface with FPGA northbridge used in
+ Loongson2E.
+
+config CPU_MIPS32_R1
+ bool "MIPS32 Release 1"
+ depends on SYS_HAS_CPU_MIPS32_R1
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ help
+ Choose this option to build a kernel for release 1 or later of the
+ MIPS32 architecture. Most modern embedded systems with a 32-bit
+ MIPS processor are based on a MIPS32 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
+ Release 2 of the MIPS32 architecture is available since several
+ years so chances are you even have a MIPS32 Release 2 processor
+ in which case you should choose CPU_MIPS32_R2 instead for better
+ performance.
+
+config CPU_MIPS32_R2
+ bool "MIPS32 Release 2"
+ depends on SYS_HAS_CPU_MIPS32_R2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS32 architecture. Most modern embedded systems with a 32-bit
+ MIPS processor are based on a MIPS32 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
+
+config CPU_MIPS64_R1
+ bool "MIPS64 Release 1"
+ depends on SYS_HAS_CPU_MIPS64_R1
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ Choose this option to build a kernel for release 1 or later of the
+ MIPS64 architecture. Many modern embedded systems with a 64-bit
+ MIPS processor are based on a MIPS64 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
+ Release 2 of the MIPS64 architecture is available since several
+ years so chances are you even have a MIPS64 Release 2 processor
+ in which case you should choose CPU_MIPS64_R2 instead for better
+ performance.
+
+config CPU_MIPS64_R2
+ bool "MIPS64 Release 2"
+ depends on SYS_HAS_CPU_MIPS64_R2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ Choose this option to build a kernel for release 2 or later of the
+ MIPS64 architecture. Many modern embedded systems with a 64-bit
+ MIPS processor are based on a MIPS64 processor. If you know the
+ specific type of processor in your system, choose those that one
+ otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
+
+config CPU_R3000
+ bool "R3000"
+ depends on SYS_HAS_CPU_R3000
+ select CPU_HAS_WB
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ help
+ Please make sure to pick the right CPU type. Linux/MIPS is not
+ designed to be generic, i.e. Kernels compiled for R3000 CPUs will
+ *not* work on R4000 machines and vice versa. However, since most
+ of the supported machines have an R4000 (or similar) CPU, R4x00
+ might be a safe bet. If the resulting kernel does not work,
+ try to recompile with R3000.
+
+config CPU_TX39XX
+ bool "R39XX"
+ depends on SYS_HAS_CPU_TX39XX
+ select CPU_SUPPORTS_32BIT_KERNEL
+
+config CPU_VR41XX
+ bool "R41xx"
+ depends on SYS_HAS_CPU_VR41XX
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ The options selects support for the NEC VR4100 series of processors.
+ Only choose this option if you have one of these processors as a
+ kernel built with this option will not run on any other type of
+ processor or vice versa.
+
+config CPU_R4300
+ bool "R4300"
+ depends on SYS_HAS_CPU_R4300
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ MIPS Technologies R4300-series processors.
+
+config CPU_R4X00
+ bool "R4x00"
+ depends on SYS_HAS_CPU_R4X00
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ MIPS Technologies R4000-series processors other than 4300, including
+ the R4000, R4400, R4600, and 4700.
+
+config CPU_TX49XX
+ bool "R49XX"
+ depends on SYS_HAS_CPU_TX49XX
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+
+config CPU_R5000
+ bool "R5000"
+ depends on SYS_HAS_CPU_R5000
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ MIPS Technologies R5000-series processors other than the Nevada.
+
+config CPU_R5432
+ bool "R5432"
+ depends on SYS_HAS_CPU_R5432
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+
+config CPU_R5500
+ bool "R5500"
+ depends on SYS_HAS_CPU_R5500
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
+ instruction set.
+
+config CPU_R6000
+ bool "R6000"
+ depends on EXPERIMENTAL
+ depends on SYS_HAS_CPU_R6000
+ select CPU_SUPPORTS_32BIT_KERNEL
+ help
+ MIPS Technologies R6000 and R6000A series processors. Note these
+ processors are extremely rare and the support for them is incomplete.
+
+config CPU_NEVADA
+ bool "RM52xx"
+ depends on SYS_HAS_CPU_NEVADA
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ QED / PMC-Sierra RM52xx-series ("Nevada") processors.
+
+config CPU_R8000
+ bool "R8000"
+ depends on EXPERIMENTAL
+ depends on SYS_HAS_CPU_R8000
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_64BIT_KERNEL
+ help
+ MIPS Technologies R8000 processors. Note these processors are
+ uncommon and the support for them is incomplete.
+
+config CPU_R10000
+ bool "R10000"
+ depends on SYS_HAS_CPU_R10000
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ help
+ MIPS Technologies R10000-series processors.
+
+config CPU_RM7000
+ bool "RM7000"
+ depends on SYS_HAS_CPU_RM7000
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+
+config CPU_RM9000
+ bool "RM9000"
+ depends on SYS_HAS_CPU_RM9000
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select WEAK_ORDERING
+
+config CPU_SB1
+ bool "SB1"
+ depends on SYS_HAS_CPU_SB1
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select WEAK_ORDERING
+
+config CPU_CAVIUM_OCTEON
+ bool "Cavium Octeon processor"
+ depends on SYS_HAS_CPU_CAVIUM_OCTEON
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_SMP
+ select NR_CPUS_DEFAULT_16
+ select WEAK_ORDERING
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ The Cavium Octeon processor is a highly integrated chip containing
+ many ethernet hardware widgets for networking tasks. The processor
+ can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
+ Full details can be found at http://www.caviumnetworks.com.
+
+config CPU_BMIPS3300
+ bool "BMIPS3300"
+ depends on SYS_HAS_CPU_BMIPS3300
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select WEAK_ORDERING
+ help
+ Broadcom BMIPS3300 processors.
+
+config CPU_BMIPS4350
+ bool "BMIPS4350"
+ depends on SYS_HAS_CPU_BMIPS4350
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select WEAK_ORDERING
+ help
+ Broadcom BMIPS4350 ("VIPER") processors.
+
+config CPU_BMIPS4380
+ bool "BMIPS4380"
+ depends on SYS_HAS_CPU_BMIPS4380
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select WEAK_ORDERING
+ help
+ Broadcom BMIPS4380 processors.
+
+config CPU_BMIPS5000
+ bool "BMIPS5000"
+ depends on SYS_HAS_CPU_BMIPS5000
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+ select WEAK_ORDERING
+ help
+ Broadcom BMIPS5000 processors.
+
+config CPU_XLR
+ bool "Netlogic XLR SoC"
+ depends on SYS_HAS_CPU_XLR
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select WEAK_ORDERING
+ select WEAK_REORDERING_BEYOND_LLSC
+ select CPU_SUPPORTS_HUGEPAGES
+ help
+ Netlogic Microsystems XLR/XLS processors.
+endchoice
+
+if CPU_LOONGSON2F
+config CPU_NOP_WORKAROUNDS
+ bool
+
+config CPU_JUMP_WORKAROUNDS
+ bool
+
+config CPU_LOONGSON2F_WORKAROUNDS
+ bool "Loongson 2F Workarounds"
+ default y
+ select CPU_NOP_WORKAROUNDS
+ select CPU_JUMP_WORKAROUNDS
+ help
+ Loongson 2F01 / 2F02 processors have the NOP & JUMP issues which
+ require workarounds. Without workarounds the system may hang
+ unexpectedly. For more information please refer to the gas
+ -mfix-loongson2f-nop and -mfix-loongson2f-jump options.
+
+ Loongson 2F03 and later have fixed these issues and no workarounds
+ are needed. The workarounds have no significant side effect on them
+ but may decrease the performance of the system so this option should
+ be disabled unless the kernel is intended to be run on 2F01 or 2F02
+ systems.
+
+ If unsure, please say Y.
+endif # CPU_LOONGSON2F
+
+config SYS_SUPPORTS_ZBOOT
+ bool
+ select HAVE_KERNEL_GZIP
+ select HAVE_KERNEL_BZIP2
+ select HAVE_KERNEL_LZMA
+ select HAVE_KERNEL_LZO
+
+config SYS_SUPPORTS_ZBOOT_UART16550
+ bool
+ select SYS_SUPPORTS_ZBOOT
+
+config CPU_LOONGSON2
+ bool
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+
+config SYS_HAS_CPU_LOONGSON2E
+ bool
+
+config SYS_HAS_CPU_LOONGSON2F
+ bool
+ select CPU_SUPPORTS_CPUFREQ
+ select CPU_SUPPORTS_ADDRWINCFG if 64BIT
+ select CPU_SUPPORTS_UNCACHED_ACCELERATED
+
+config SYS_HAS_CPU_MIPS32_R1
+ bool
+
+config SYS_HAS_CPU_MIPS32_R2
+ bool
+
+config SYS_HAS_CPU_MIPS64_R1
+ bool
+
+config SYS_HAS_CPU_MIPS64_R2
+ bool
+
+config SYS_HAS_CPU_R3000
+ bool
+
+config SYS_HAS_CPU_TX39XX
+ bool
+
+config SYS_HAS_CPU_VR41XX
+ bool
+
+config SYS_HAS_CPU_R4300
+ bool
+
+config SYS_HAS_CPU_R4X00
+ bool
+
+config SYS_HAS_CPU_TX49XX
+ bool
+
+config SYS_HAS_CPU_R5000
+ bool
+
+config SYS_HAS_CPU_R5432
+ bool
+
+config SYS_HAS_CPU_R5500
+ bool
+
+config SYS_HAS_CPU_R6000
+ bool
+
+config SYS_HAS_CPU_NEVADA
+ bool
+
+config SYS_HAS_CPU_R8000
+ bool
+
+config SYS_HAS_CPU_R10000
+ bool
+
+config SYS_HAS_CPU_RM7000
+ bool
+
+config SYS_HAS_CPU_RM9000
+ bool
+
+config SYS_HAS_CPU_SB1
+ bool
+
+config SYS_HAS_CPU_CAVIUM_OCTEON
+ bool
+
+config SYS_HAS_CPU_BMIPS3300
+ bool
+
+config SYS_HAS_CPU_BMIPS4350
+ bool
+
+config SYS_HAS_CPU_BMIPS4380
+ bool
+
+config SYS_HAS_CPU_BMIPS5000
+ bool
+
+config SYS_HAS_CPU_XLR
+ bool
+
+#
+# CPU may reorder R->R, R->W, W->R, W->W
+# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
+#
+config WEAK_ORDERING
+ bool
+
+#
+# CPU may reorder reads and writes beyond LL/SC
+# CPU may reorder R->LL, R->LL, W->LL, W->LL, R->SC, R->SC, W->SC, W->SC
+#
+config WEAK_REORDERING_BEYOND_LLSC
+ bool
+endmenu
+
+#
+# These two indicate any level of the MIPS32 and MIPS64 architecture
+#
+config CPU_MIPS32
+ bool
+ default y if CPU_MIPS32_R1 || CPU_MIPS32_R2
+
+config CPU_MIPS64
+ bool
+ default y if CPU_MIPS64_R1 || CPU_MIPS64_R2
+
+#
+# These two indicate the revision of the architecture, either Release 1 or Release 2
+#
+config CPU_MIPSR1
+ bool
+ default y if CPU_MIPS32_R1 || CPU_MIPS64_R1
+
+config CPU_MIPSR2
+ bool
+ default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON
+
+config SYS_SUPPORTS_32BIT_KERNEL
+ bool
+config SYS_SUPPORTS_64BIT_KERNEL
+ bool
+config CPU_SUPPORTS_32BIT_KERNEL
+ bool
+config CPU_SUPPORTS_64BIT_KERNEL
+ bool
+config CPU_SUPPORTS_CPUFREQ
+ bool
+config CPU_SUPPORTS_ADDRWINCFG
+ bool
+config CPU_SUPPORTS_HUGEPAGES
+ bool
+config CPU_SUPPORTS_UNCACHED_ACCELERATED
+ bool
+config MIPS_PGD_C0_CONTEXT
+ bool
+ default y if 64BIT && CPU_MIPSR2
+
+#
+# Set to y for ptrace access to watch registers.
+#
+config HARDWARE_WATCHPOINTS
+ bool
+ default y if CPU_MIPSR1 || CPU_MIPSR2
+
+menu "Kernel type"
+
+choice
+
+ prompt "Kernel code model"
+ help
+ You should only select this option if you have a workload that
+ actually benefits from 64-bit processing or if your machine has
+ large memory. You will only be presented a single option in this
+ menu if your system does not support both 32-bit and 64-bit kernels.
+
+config 32BIT
+ bool "32-bit kernel"
+ depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
+ select TRAD_SIGNALS
+ help
+ Select this option if you want to build a 32-bit kernel.
+config 64BIT
+ bool "64-bit kernel"
+ depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
+ select HAVE_SYSCALL_WRAPPERS
+ help
+ Select this option if you want to build a 64-bit kernel.
+
+endchoice
+
+choice
+ prompt "Kernel page size"
+ default PAGE_SIZE_4KB
+
+config PAGE_SIZE_4KB
+ bool "4kB"
+ depends on !CPU_LOONGSON2
+ help
+ This option select the standard 4kB Linux page size. On some
+ R3000-family processors this is the only available page size. Using
+ 4kB page size will minimize memory consumption and is therefore
+ recommended for low memory systems.
+
+config PAGE_SIZE_8KB
+ bool "8kB"
+ depends on (EXPERIMENTAL && CPU_R8000) || CPU_CAVIUM_OCTEON
+ help
+ Using 8kB page size will result in higher performance kernel at
+ the price of higher memory consumption. This option is available
+ only on R8000 and cnMIPS processors. Note that you will need a
+ suitable Linux distribution to support this.
+
+config PAGE_SIZE_16KB
+ bool "16kB"
+ depends on !CPU_R3000 && !CPU_TX39XX
+ help
+ Using 16kB page size will result in higher performance kernel at
+ the price of higher memory consumption. This option is available on
+ all non-R3000 family processors. Note that you will need a suitable
+ Linux distribution to support this.
+
+config PAGE_SIZE_32KB
+ bool "32kB"
+ depends on CPU_CAVIUM_OCTEON
+ help
+ Using 32kB page size will result in higher performance kernel at
+ the price of higher memory consumption. This option is available
+ only on cnMIPS cores. Note that you will need a suitable Linux
+ distribution to support this.
+
+config PAGE_SIZE_64KB
+ bool "64kB"
+ depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX
+ help
+ Using 64kB page size will result in higher performance kernel at
+ the price of higher memory consumption. This option is available on
+ all non-R3000 family processor. Not that at the time of this
+ writing this option is still high experimental.
+
+endchoice
+
+config FORCE_MAX_ZONEORDER
+ int "Maximum zone order"
+ range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
+ default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
+ range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
+ default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
+ range 11 64
+ default "11"
+ help
+ The kernel memory allocator divides physically contiguous memory
+ blocks into "zones", where each zone is a power of two number of
+ pages. This option selects the largest power of two that the kernel
+ keeps in the memory allocator. If you need to allocate very large
+ blocks of physically contiguous memory, then you may need to
+ increase this value.
+
+ This config option is actually maximum order plus one. For example,
+ a value of 11 means that the largest free memory block is 2^10 pages.
+
+ The page size is not necessarily 4KB. Keep this in mind
+ when choosing a value for this option.
+
+config BOARD_SCACHE
+ bool
+
+config IP22_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+
+#
+# Support for a MIPS32 / MIPS64 style S-caches
+#
+config MIPS_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+
+config R5000_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+
+config RM7000_CPU_SCACHE
+ bool
+ select BOARD_SCACHE
+
+config SIBYTE_DMA_PAGEOPS
+ bool "Use DMA to clear/copy pages"
+ depends on CPU_SB1
+ help
+ Instead of using the CPU to zero and copy pages, use a Data Mover
+ channel. These DMA channels are otherwise unused by the standard
+ SiByte Linux port. Seems to give a small performance benefit.
+
+config CPU_HAS_PREFETCH
+ bool
+
+choice
+ prompt "MIPS MT options"
+
+config MIPS_MT_DISABLED
+ bool "Disable multithreading support."
+ help
+ Use this option if your workload can't take advantage of
+ MIPS hardware multithreading support. On systems that don't have
+ the option of an MT-enabled processor this option will be the only
+ option in this menu.
+
+config MIPS_MT_SMP
+ bool "Use 1 TC on each available VPE for SMP"
+ depends on SYS_SUPPORTS_MULTITHREADING
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
+ select MIPS_MT
+ select NR_CPUS_DEFAULT_2
+ select SMP
+ select SYS_SUPPORTS_SCHED_SMT if SMP
+ select SYS_SUPPORTS_SMP
+ select SMP_UP
+ help
+ This is a kernel model which is known a VSMP but lately has been
+ marketesed into SMVP.
+ Virtual SMP uses the processor's VPEs to implement virtual
+ processors. In currently available configuration of the 34K processor
+ this allows for a dual processor. Both processors will share the same
+ primary caches; each will obtain the half of the TLB for it's own
+ exclusive use. For a layman this model can be described as similar to
+ what Intel calls Hyperthreading.
+
+ For further information see http://www.linux-mips.org/wiki/34K#VSMP
+
+config MIPS_MT_SMTC
+ bool "SMTC: Use all TCs on all VPEs for SMP"
+ depends on CPU_MIPS32_R2
+ #depends on CPU_MIPS64_R2 # once there is hardware ...
+ depends on SYS_SUPPORTS_MULTITHREADING
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
+ select MIPS_MT
+ select NR_CPUS_DEFAULT_8
+ select SMP
+ select SYS_SUPPORTS_SMP
+ select SMP_UP
+ help
+ This is a kernel model which is known a SMTC or lately has been
+ marketesed into SMVP.
+ is presenting the available TC's of the core as processors to Linux.
+ On currently available 34K processors this means a Linux system will
+ see up to 5 processors. The implementation of the SMTC kernel differs
+ significantly from VSMP and cannot efficiently coexist in the same
+ kernel binary so the choice between VSMP and SMTC is a compile time
+ decision.
+
+ For further information see http://www.linux-mips.org/wiki/34K#SMTC
+
+endchoice
+
+config MIPS_MT
+ bool
+
+config SCHED_SMT
+ bool "SMT (multithreading) scheduler support"
+ depends on SYS_SUPPORTS_SCHED_SMT
+ default n
+ help
+ SMT scheduler support improves the CPU scheduler's decision making
+ when dealing with MIPS MT enabled cores at a cost of slightly
+ increased overhead in some places. If unsure say N here.
+
+config SYS_SUPPORTS_SCHED_SMT
+ bool
+
+
+config SYS_SUPPORTS_MULTITHREADING
+ bool
+
+config MIPS_MT_FPAFF
+ bool "Dynamic FPU affinity for FP-intensive threads"
+ default y
+ depends on MIPS_MT_SMP || MIPS_MT_SMTC
+
+config MIPS_VPE_LOADER
+ bool "VPE loader support."
+ depends on SYS_SUPPORTS_MULTITHREADING
+ select CPU_MIPSR2_IRQ_VI
+ select CPU_MIPSR2_IRQ_EI
+ select MIPS_MT
+ help
+ Includes a loader for loading an elf relocatable object
+ onto another VPE and running it.
+
+config MIPS_MT_SMTC_IM_BACKSTOP
+ bool "Use per-TC register bits as backstop for inhibited IM bits"
+ depends on MIPS_MT_SMTC
+ default n
+ help
+ To support multiple TC microthreads acting as "CPUs" within
+ a VPE, VPE-wide interrupt mask bits must be specially manipulated
+ during interrupt handling. To support legacy drivers and interrupt
+ controller management code, SMTC has a "backstop" to track and
+ if necessary restore the interrupt mask. This has some performance
+ impact on interrupt service overhead.
+
+config MIPS_MT_SMTC_IRQAFF
+ bool "Support IRQ affinity API"
+ depends on MIPS_MT_SMTC
+ default n
+ help
+ Enables SMP IRQ affinity API (/proc/irq/*/smp_affinity, etc.)
+ for SMTC Linux kernel. Requires platform support, of which
+ an example can be found in the MIPS kernel i8259 and Malta
+ platform code. Adds some overhead to interrupt dispatch, and
+ should be used only if you know what you are doing.
+
+config MIPS_VPE_LOADER_TOM
+ bool "Load VPE program into memory hidden from linux"
+ depends on MIPS_VPE_LOADER
+ default y
+ help
+ The loader can use memory that is present but has been hidden from
+ Linux using the kernel command line option "mem=xxMB". It's up to
+ you to ensure the amount you put in the option and the space your
+ program requires is less or equal to the amount physically present.
+
+# this should possibly be in drivers/char, but it is rather cpu related. Hmmm
+config MIPS_VPE_APSP_API
+ bool "Enable support for AP/SP API (RTLX)"
+ depends on MIPS_VPE_LOADER
+ help
+
+config MIPS_APSP_KSPD
+ bool "Enable KSPD"
+ depends on MIPS_VPE_APSP_API
+ default y
+ help
+ KSPD is a kernel daemon that accepts syscall requests from the SP
+ side, actions them and returns the results. It also handles the
+ "exit" syscall notifying other kernel modules the SP program is
+ exiting. You probably want to say yes here.
+
+config MIPS_CMP
+ bool "MIPS CMP framework support"
+ depends on SYS_SUPPORTS_MIPS_CMP
+ select SYNC_R4K
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_SCHED_SMT if SMP
+ select WEAK_ORDERING
+ default n
+ help
+ This is a placeholder option for the GCMP work. It will need to
+ be handled differently...
+
+config SB1_PASS_1_WORKAROUNDS
+ bool
+ depends on CPU_SB1_PASS_1
+ default y
+
+config SB1_PASS_2_WORKAROUNDS
+ bool
+ depends on CPU_SB1 && (CPU_SB1_PASS_2_2 || CPU_SB1_PASS_2)
+ default y
+
+config SB1_PASS_2_1_WORKAROUNDS
+ bool
+ depends on CPU_SB1 && CPU_SB1_PASS_2
+ default y
+
+config 64BIT_PHYS_ADDR
+ bool
+
+config ARCH_PHYS_ADDR_T_64BIT
+ def_bool 64BIT_PHYS_ADDR
+
+config CPU_HAS_SMARTMIPS
+ depends on SYS_SUPPORTS_SMARTMIPS
+ bool "Support for the SmartMIPS ASE"
+ help
+ SmartMIPS is a extension of the MIPS32 architecture aimed at
+ increased security at both hardware and software level for
+ smartcards. Enabling this option will allow proper use of the
+ SmartMIPS instructions by Linux applications. However a kernel with
+ this option will not work on a MIPS core without SmartMIPS core. If
+ you don't know you probably don't have SmartMIPS and should say N
+ here.
+
+config CPU_HAS_WB
+ bool
+
+#
+# Vectored interrupt mode is an R2 feature
+#
+config CPU_MIPSR2_IRQ_VI
+ bool
+
+#
+# Extended interrupt mode is an R2 feature
+#
+config CPU_MIPSR2_IRQ_EI
+ bool
+
+config CPU_HAS_SYNC
+ bool
+ depends on !CPU_R3000
+ default y
+
+config GENERIC_CLOCKEVENTS_BROADCAST
+ bool
+
+#
+# CPU non-features
+#
+config CPU_DADDI_WORKAROUNDS
+ bool
+
+config CPU_R4000_WORKAROUNDS
+ bool
+ select CPU_R4400_WORKAROUNDS
+
+config CPU_R4400_WORKAROUNDS
+ bool
+
+#
+# - Highmem only makes sense for the 32-bit kernel.
+# - The current highmem code will only work properly on physically indexed
+# caches such as R3000, SB1, R7000 or those that look like they're virtually
+# indexed such as R4000/R4400 SC and MC versions or R10000. So for the
+# moment we protect the user and offer the highmem option only on machines
+# where it's known to be safe. This will not offer highmem on a few systems
+# such as MIPS32 and MIPS64 CPUs which may have virtual and physically
+# indexed CPUs but we're playing safe.
+# - We use SYS_SUPPORTS_HIGHMEM to offer highmem only for systems where we
+# know they might have memory configurations that could make use of highmem
+# support.
+#
+config HIGHMEM
+ bool "High Memory Support"
+ depends on 32BIT && CPU_SUPPORTS_HIGHMEM && SYS_SUPPORTS_HIGHMEM
+
+config CPU_SUPPORTS_HIGHMEM
+ bool
+
+config SYS_SUPPORTS_HIGHMEM
+ bool
+
+config SYS_SUPPORTS_SMARTMIPS
+ bool
+
+config ARCH_FLATMEM_ENABLE
+ def_bool y
+ depends on !NUMA && !CPU_LOONGSON2
+
+config ARCH_DISCONTIGMEM_ENABLE
+ bool
+ default y if SGI_IP27
+ help
+ Say Y to support efficient handling of discontiguous physical memory,
+ for architectures which are either NUMA (Non-Uniform Memory Access)
+ or have huge holes in the physical address space for other reasons.
+ See <file:Documentation/vm/numa> for more.
+
+config ARCH_POPULATES_NODE_MAP
+ def_bool y
+
+config ARCH_SPARSEMEM_ENABLE
+ bool
+ select SPARSEMEM_STATIC
+
+config NUMA
+ bool "NUMA Support"
+ depends on SYS_SUPPORTS_NUMA
+ help
+ Say Y to compile the kernel to support NUMA (Non-Uniform Memory
+ Access). This option improves performance on systems with more
+ than two nodes; on two node systems it is generally better to
+ leave it disabled; on single node systems disable this option
+ disabled.
+
+config SYS_SUPPORTS_NUMA
+ bool
+
+config NODES_SHIFT
+ int
+ default "6"
+ depends on NEED_MULTIPLE_NODES
+
+config HW_PERF_EVENTS
+ bool "Enable hardware performance counter support for perf events"
+ depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32
+ default y
+ help
+ Enable hardware performance counter support for perf events. If
+ disabled, perf events will use software events only.
+
+source "mm/Kconfig"
+
+config SMP
+ bool "Multi-Processing support"
+ depends on SYS_SUPPORTS_SMP
+ select IRQ_PER_CPU
+ select USE_GENERIC_SMP_HELPERS
+ help
+ This enables support for systems with more than one CPU. If you have
+ a system with only one CPU, like most personal computers, say N. If
+ you have a system with more than one CPU, say Y.
+
+ If you say N here, the kernel will run on single and multiprocessor
+ machines, but will use only one CPU of a multiprocessor machine. If
+ you say Y here, the kernel will run on many, but not all,
+ singleprocessor machines. On a singleprocessor machine, the kernel
+ will run faster if you say N here.
+
+ People using multiprocessor machines who say Y here should also say
+ Y to "Enhanced Real Time Clock Support", below.
+
+ See also the SMP-HOWTO available at
+ <http://www.tldp.org/docs.html#howto>.
+
+ If you don't know what to do here, say N.
+
+config SMP_UP
+ bool
+
+config SYS_SUPPORTS_MIPS_CMP
+ bool
+
+config SYS_SUPPORTS_SMP
+ bool
+
+config NR_CPUS_DEFAULT_1
+ bool
+
+config NR_CPUS_DEFAULT_2
+ bool
+
+config NR_CPUS_DEFAULT_4
+ bool
+
+config NR_CPUS_DEFAULT_8
+ bool
+
+config NR_CPUS_DEFAULT_16
+ bool
+
+config NR_CPUS_DEFAULT_32
+ bool
+
+config NR_CPUS_DEFAULT_64
+ bool
+
+config NR_CPUS
+ int "Maximum number of CPUs (2-64)"
+ range 1 64 if NR_CPUS_DEFAULT_1
+ depends on SMP
+ default "1" if NR_CPUS_DEFAULT_1
+ default "2" if NR_CPUS_DEFAULT_2
+ default "4" if NR_CPUS_DEFAULT_4
+ default "8" if NR_CPUS_DEFAULT_8
+ default "16" if NR_CPUS_DEFAULT_16
+ default "32" if NR_CPUS_DEFAULT_32
+ default "64" if NR_CPUS_DEFAULT_64
+ help
+ This allows you to specify the maximum number of CPUs which this
+ kernel will support. The maximum supported value is 32 for 32-bit
+ kernel and 64 for 64-bit kernels; the minimum value which makes
+ sense is 1 for Qemu (useful only for kernel debugging purposes)
+ and 2 for all others.
+
+ This is purely to save memory - each supported CPU adds
+ approximately eight kilobytes to the kernel image. For best
+ performance should round up your number of processors to the next
+ power of two.
+
+source "kernel/time/Kconfig"
+
+#
+# Timer Interrupt Frequency Configuration
+#
+
+choice
+ prompt "Timer frequency"
+ default HZ_250
+ help
+ Allows the configuration of the timer frequency.
+
+ config HZ_48
+ bool "48 HZ" if SYS_SUPPORTS_48HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_100
+ bool "100 HZ" if SYS_SUPPORTS_100HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_128
+ bool "128 HZ" if SYS_SUPPORTS_128HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_250
+ bool "250 HZ" if SYS_SUPPORTS_250HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_256
+ bool "256 HZ" if SYS_SUPPORTS_256HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_1000
+ bool "1000 HZ" if SYS_SUPPORTS_1000HZ || SYS_SUPPORTS_ARBIT_HZ
+
+ config HZ_1024
+ bool "1024 HZ" if SYS_SUPPORTS_1024HZ || SYS_SUPPORTS_ARBIT_HZ
+
+endchoice
+
+config SYS_SUPPORTS_48HZ
+ bool
+
+config SYS_SUPPORTS_100HZ
+ bool
+
+config SYS_SUPPORTS_128HZ
+ bool
+
+config SYS_SUPPORTS_250HZ
+ bool
+
+config SYS_SUPPORTS_256HZ
+ bool
+
+config SYS_SUPPORTS_1000HZ
+ bool
+
+config SYS_SUPPORTS_1024HZ
+ bool
+
+config SYS_SUPPORTS_ARBIT_HZ
+ bool
+ default y if !SYS_SUPPORTS_48HZ && !SYS_SUPPORTS_100HZ && \
+ !SYS_SUPPORTS_128HZ && !SYS_SUPPORTS_250HZ && \
+ !SYS_SUPPORTS_256HZ && !SYS_SUPPORTS_1000HZ && \
+ !SYS_SUPPORTS_1024HZ
+
+config HZ
+ int
+ default 48 if HZ_48
+ default 100 if HZ_100
+ default 128 if HZ_128
+ default 250 if HZ_250
+ default 256 if HZ_256
+ default 1000 if HZ_1000
+ default 1024 if HZ_1024
+
+source "kernel/Kconfig.preempt"
+
+config MIPS_INSANE_LARGE
+ bool "Support for large 64-bit configurations"
+ depends on CPU_R10000 && 64BIT
+ help
+ MIPS R10000 does support a 44 bit / 16TB address space as opposed to
+ previous 64-bit processors which only supported 40 bit / 1TB. If you
+ need processes of more than 1TB virtual address space, say Y here.
+ This will result in additional memory usage, so it is not
+ recommended for normal users.
+
+config KEXEC
+ bool "Kexec system call (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+ but it is independent of the system firmware. And like a reboot
+ you can start any kernel with it, not just Linux.
+
+ The name comes from the similarity to the exec system call.
+
+ It is an ongoing process to be certain the hardware in a machine
+ is properly shutdown, so do not be surprised if this code does not
+ initially work for you. It may help to enable device hotplugging
+ support. As of this writing the exact hardware interface is
+ strongly in flux, so no good recommendation can be made.
+
+config SECCOMP
+ bool "Enable seccomp to safely compute untrusted bytecode"
+ depends on PROC_FS
+ default y
+ help
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via /proc/<pid>/seccomp, it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+ If unsure, say Y. Only embedded should say N here.
+
+config USE_OF
+ bool "Flattened Device Tree support"
+ select OF
+ select OF_EARLY_FLATTREE
+ help
+ Include support for flattened device tree machine descriptions.
+
+endmenu
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
+config STACKTRACE_SUPPORT
+ bool
+ default y
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
+
+config HW_HAS_EISA
+ bool
+config HW_HAS_PCI
+ bool
+
+config PCI
+ bool "Support for PCI controller"
+ depends on HW_HAS_PCI
+ select PCI_DOMAINS
+ help
+ Find out whether you have a PCI motherboard. PCI is the name of a
+ bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. Other bus systems are ISA, EISA, or VESA. If you have PCI,
+ say Y, otherwise N.
+
+config PCI_DOMAINS
+ bool
+
+source "drivers/pci/Kconfig"
+
+#
+# ISA support is now enabled via select. Too many systems still have the one
+# or other ISA chip on the board that users don't know about so don't expect
+# users to choose the right thing ...
+#
+config ISA
+ bool
+
+config EISA
+ bool "EISA support"
+ depends on HW_HAS_EISA
+ select ISA
+ select GENERIC_ISA_DMA
+ ---help---
+ The Extended Industry Standard Architecture (EISA) bus was
+ developed as an open alternative to the IBM MicroChannel bus.
+
+ The EISA bus provided some of the features of the IBM MicroChannel
+ bus while maintaining backward compatibility with cards made for
+ the older ISA bus. The EISA bus saw limited use between 1988 and
+ 1995 when it was made obsolete by the PCI bus.
+
+ Say Y here if you are building a kernel for an EISA-based machine.
+
+ Otherwise, say N.
+
+source "drivers/eisa/Kconfig"
+
+config TC
+ bool "TURBOchannel support"
+ depends on MACH_DECSTATION
+ help
+ TURBOchannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS
+ processors. TURBOchannel programming specifications are available
+ at:
+ <ftp://ftp.hp.com/pub/alphaserver/archive/triadd/>
+ and:
+ <http://www.computer-refuge.org/classiccmp/ftp.digital.com/pub/DEC/TriAdd/>
+ Linux driver support status is documented at:
+ <http://www.linux-mips.org/wiki/DECstation>
+
+#config ACCESSBUS
+# bool "Access.Bus support"
+# depends on TC
+
+config MMU
+ bool
+ default y
+
+config I8253
+ bool
+ select CLKSRC_I8253
+ select MIPS_EXTERNAL_TIMER
+
+config ZONE_DMA32
+ bool
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+config RAPIDIO
+ bool "RapidIO support"
+ depends on PCI
+ default n
+ help
+ If you say Y here, the kernel will include drivers and
+ infrastructure code to support RapidIO interconnect devices.
+
+source "drivers/rapidio/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+config TRAD_SIGNALS
+ bool
+
+config MIPS32_COMPAT
+ bool "Kernel support for Linux/MIPS 32-bit binary compatibility"
+ depends on 64BIT
+ help
+ Select this option if you want Linux/MIPS 32-bit binary
+ compatibility. Since all software available for Linux/MIPS is
+ currently 32-bit you should say Y here.
+
+config COMPAT
+ bool
+ depends on MIPS32_COMPAT
+ default y
+
+config SYSVIPC_COMPAT
+ bool
+ depends on COMPAT && SYSVIPC
+ default y
+
+config MIPS32_O32
+ bool "Kernel support for o32 binaries"
+ depends on MIPS32_COMPAT
+ help
+ Select this option if you want to run o32 binaries. These are pure
+ 32-bit binaries as used by the 32-bit Linux/MIPS port. Most of
+ existing binaries are in this format.
+
+ If unsure, say Y.
+
+config MIPS32_N32
+ bool "Kernel support for n32 binaries"
+ depends on MIPS32_COMPAT
+ help
+ Select this option if you want to run n32 binaries. These are
+ 64-bit binaries using 32-bit quantities for addressing and certain
+ data that would normally be 64-bit. They are used in special
+ cases.
+
+ If unsure, say N.
+
+config BINFMT_ELF32
+ bool
+ default y if MIPS32_O32 || MIPS32_N32
+
+endmenu
+
+menu "Power management options"
+
+config ARCH_HIBERNATION_POSSIBLE
+ def_bool y
+ depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP
+
+config ARCH_SUSPEND_POSSIBLE
+ def_bool y
+ depends on SYS_SUPPORTS_HOTPLUG_CPU || !SMP
+
+source "kernel/power/Kconfig"
+
+endmenu
+
+source "arch/mips/kernel/cpufreq/Kconfig"
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/mips/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+menuconfig VIRTUALIZATION
+ bool "Virtualization"
+ default n
+ ---help---
+ Say Y here to get to see options for using your Linux host to run other
+ operating systems inside virtual machines (guests).
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
+
+if VIRTUALIZATION
+
+source drivers/virtio/Kconfig
+
+endif # VIRTUALIZATION
+
+source "lib/Kconfig"
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
new file mode 100644
index 00000000..83ed00a5
--- /dev/null
+++ b/arch/mips/Kconfig.debug
@@ -0,0 +1,131 @@
+menu "Kernel hacking"
+
+config TRACE_IRQFLAGS_SUPPORT
+ bool
+ default y
+
+source "lib/Kconfig.debug"
+
+config EARLY_PRINTK
+ bool "Early printk" if EXPERT
+ depends on SYS_HAS_EARLY_PRINTK
+ default y
+ help
+ This option enables special console drivers which allow the kernel
+ to print messages very early in the bootup process.
+
+ This is useful for kernel debugging when your machine crashes very
+ early before the console code is initialized. For normal operation,
+ it is not recommended because it looks ugly on some machines and
+ doesn't cooperate with an X server. You should normally say N here,
+ unless you want to debug such a crash.
+
+config CMDLINE_BOOL
+ bool "Built-in kernel command line"
+ default n
+ help
+ For most systems, it is firmware or second stage bootloader that
+ by default specifies the kernel command line options. However,
+ it might be necessary or advantageous to either override the
+ default kernel command line or add a few extra options to it.
+ For such cases, this option allows you to hardcode your own
+ command line options directly into the kernel. For that, you
+ should choose 'Y' here, and fill in the extra boot arguments
+ in CONFIG_CMDLINE.
+
+ The built-in options will be concatenated to the default command
+ line if CMDLINE_OVERRIDE is set to 'N'. Otherwise, the default
+ command line will be ignored and replaced by the built-in string.
+
+ Most MIPS systems will normally expect 'N' here and rely upon
+ the command line from the firmware or the second-stage bootloader.
+
+config CMDLINE
+ string "Default kernel command string"
+ depends on CMDLINE_BOOL
+ default ""
+ help
+ On some platforms, there is currently no way for the boot loader to
+ pass arguments to the kernel. For these platforms, and for the cases
+ when you want to add some extra options to the command line or ignore
+ the default command line, you can supply some command-line options at
+ build time by entering them here. In other cases you can specify
+ kernel args so that you don't have to set them up in board prom
+ initialization routines.
+
+ For more information, see the CMDLINE_BOOL and CMDLINE_OVERRIDE
+ options.
+
+config CMDLINE_OVERRIDE
+ bool "Built-in command line overrides firware arguments"
+ default n
+ depends on CMDLINE_BOOL
+ help
+ By setting this option to 'Y' you will have your kernel ignore
+ command line arguments from firmware or second stage bootloader.
+ Instead, the built-in command line will be used exclusively.
+
+ Normally, you will choose 'N' here.
+
+config DEBUG_STACKOVERFLOW
+ bool "Check for stack overflows"
+ depends on DEBUG_KERNEL
+ help
+ This option will cause messages to be printed if free stack space
+ drops below a certain limit(2GB on MIPS). The debugging option
+ provides another way to check stack overflow happened on kernel mode
+ stack usually caused by nested interruption.
+
+config SMTC_IDLE_HOOK_DEBUG
+ bool "Enable additional debug checks before going into CPU idle loop"
+ depends on DEBUG_KERNEL && MIPS_MT_SMTC
+ help
+ This option enables Enable additional debug checks before going into
+ CPU idle loop. For details on these checks, see
+ arch/mips/kernel/smtc.c. This debugging option result in significant
+ overhead so should be disabled in production kernels.
+
+config SB1XXX_CORELIS
+ bool "Corelis Debugger"
+ depends on SIBYTE_SB1xxx_SOC
+ select DEBUG_INFO
+ help
+ Select compile flags that produce code that can be processed by the
+ Corelis mksym utility and UDB Emulator.
+
+config RUNTIME_DEBUG
+ bool "Enable run-time debugging"
+ depends on DEBUG_KERNEL
+ help
+ If you say Y here, some debugging macros will do run-time checking.
+ If you say N here, those macros will mostly turn to no-ops. See
+ arch/mips/include/asm/debug.h for debugging macros.
+ If unsure, say N.
+
+config DEBUG_ZBOOT
+ bool "Enable compressed kernel support debugging"
+ depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT
+ default n
+ help
+ If you want to add compressed kernel support to a new board, and the
+ board supports uart16550 compatible serial port, please select
+ SYS_SUPPORTS_ZBOOT_UART16550 for your board and enable this option to
+ debug it.
+
+ If your board doesn't support uart16550 compatible serial port, you
+ can try to select SYS_SUPPORTS_ZBOOT and use the other methods to
+ debug it. for example, add a new serial port support just as
+ arch/mips/boot/compressed/uart-16550.c does.
+
+ After the compressed kernel support works, please disable this option
+ to reduce the kernel image size and speed up the booting procedure a
+ little.
+
+config SPINLOCK_TEST
+ bool "Enable spinlock timing tests in debugfs"
+ depends on DEBUG_FS
+ default n
+ help
+ Add several files to the debugfs to test spinlock speed.
+
+endmenu
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
new file mode 100644
index 00000000..884819cd
--- /dev/null
+++ b/arch/mips/Makefile
@@ -0,0 +1,330 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994, 95, 96, 2003 by Ralf Baechle
+# DECStation modifications by Paul M. Antoine, 1996
+# Copyright (C) 2002, 2003, 2004 Maciej W. Rozycki
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" cleaning up for this architecture.
+#
+
+KBUILD_DEFCONFIG := ip22_defconfig
+
+#
+# Select the object file format to substitute into the linker script.
+#
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+32bit-tool-archpref = mipsel
+64bit-tool-archpref = mips64el
+32bit-bfd = elf32-tradlittlemips
+64bit-bfd = elf64-tradlittlemips
+32bit-emul = elf32ltsmip
+64bit-emul = elf64ltsmip
+else
+32bit-tool-archpref = mips
+64bit-tool-archpref = mips64
+32bit-bfd = elf32-tradbigmips
+64bit-bfd = elf64-tradbigmips
+32bit-emul = elf32btsmip
+64bit-emul = elf64btsmip
+endif
+
+ifdef CONFIG_32BIT
+tool-archpref = $(32bit-tool-archpref)
+UTS_MACHINE := mips
+endif
+ifdef CONFIG_64BIT
+tool-archpref = $(64bit-tool-archpref)
+UTS_MACHINE := mips64
+endif
+
+ifneq ($(SUBARCH),$(ARCH))
+ ifeq ($(CROSS_COMPILE),)
+ CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux- $(tool-archpref)-linux-gnu- $(tool-archpref)-unknown-linux-gnu-)
+ endif
+endif
+
+ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ ifndef KBUILD_MCOUNT_RA_ADDRESS
+ ifeq ($(call cc-option-yn,-mmcount-ra-address), y)
+ cflags-y += -mmcount-ra-address -DKBUILD_MCOUNT_RA_ADDRESS
+ endif
+ endif
+endif
+cflags-y += $(call cc-option, -mno-check-zero-division)
+
+ifdef CONFIG_32BIT
+ld-emul = $(32bit-emul)
+vmlinux-32 = vmlinux
+vmlinux-64 = vmlinux.64
+
+cflags-y += -mabi=32
+endif
+
+ifdef CONFIG_64BIT
+ld-emul = $(64bit-emul)
+vmlinux-32 = vmlinux.32
+vmlinux-64 = vmlinux
+
+cflags-y += -mabi=64
+endif
+
+all-$(CONFIG_BOOT_ELF32) := $(vmlinux-32)
+all-$(CONFIG_BOOT_ELF64) := $(vmlinux-64)
+all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlinuz
+
+#
+# GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel
+# code since it only slows down the whole thing. At some point we might make
+# use of global pointer optimizations but their use of $28 conflicts with
+# the current pointer optimization.
+#
+# The DECStation requires an ECOFF kernel for remote booting, other MIPS
+# machines may also. Since BFD is incredibly buggy with respect to
+# crossformat linking we rely on the elf2ecoff tool for format conversion.
+#
+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
+cflags-y += -msoft-float
+LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
+KBUILD_AFLAGS_MODULE += -mlong-calls
+KBUILD_CFLAGS_MODULE += -mlong-calls
+
+cflags-y += -ffreestanding
+
+#
+# We explicitly add the endianness specifier if needed, this allows
+# to compile kernels with a toolchain for the other endianness. We
+# carefully avoid to add it redundantly because gcc 3.3/3.4 complains
+# when fed the toolchain default!
+#
+# Certain gcc versions up to gcc 4.1.1 (probably 4.2-subversion as of
+# 2006-10-10 don't properly change the predefined symbols if -EB / -EL
+# are used, so we kludge that here. A bug has been filed at
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29413.
+#
+undef-all += -UMIPSEB -U_MIPSEB -U__MIPSEB -U__MIPSEB__
+undef-all += -UMIPSEL -U_MIPSEL -U__MIPSEL -U__MIPSEL__
+predef-be += -DMIPSEB -D_MIPSEB -D__MIPSEB -D__MIPSEB__
+predef-le += -DMIPSEL -D_MIPSEL -D__MIPSEL -D__MIPSEL__
+cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' && echo -EB $(undef-all) $(predef-be))
+cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le))
+
+cflags-$(CONFIG_CPU_HAS_SMARTMIPS) += $(call cc-option,-msmartmips)
+
+cflags-$(CONFIG_SB1XXX_CORELIS) += $(call cc-option,-mno-sched-prolog) \
+ -fno-omit-frame-pointer
+
+#
+# CPU-dependent compiler/assembler options for optimization.
+#
+cflags-$(CONFIG_CPU_R3000) += -march=r3000
+cflags-$(CONFIG_CPU_TX39XX) += -march=r3900
+cflags-$(CONFIG_CPU_R6000) += -march=r6000 -Wa,--trap
+cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
+cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
+cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
+cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
+cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
+ -Wa,-mips32 -Wa,--trap
+cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
+ -Wa,-mips32r2 -Wa,--trap
+cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips64 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \
+ -Wa,-mips64 -Wa,--trap
+cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \
+ -Wa,-mips64r2 -Wa,--trap
+cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap
+cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \
+ -Wa,--trap
+cflags-$(CONFIG_CPU_R5500) += $(call cc-option,-march=r5500,-march=r5000) \
+ -Wa,--trap
+cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \
+ -Wa,--trap
+cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \
+ -Wa,--trap
+cflags-$(CONFIG_CPU_RM9000) += $(call cc-option,-march=rm9000,-march=r5000) \
+ -Wa,--trap
+cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \
+ -Wa,--trap
+cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap
+cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \
+ -Wa,--trap
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
+ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
+endif
+cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
+
+cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
+cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
+cflags-$(CONFIG_CPU_DADDI_WORKAROUNDS) += $(call cc-option,-mno-daddi,)
+
+ifdef CONFIG_CPU_SB1
+ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+KBUILD_AFLAGS_MODULE += -msb1-pass1-workarounds
+KBUILD_CFLAGS_MODULE += -msb1-pass1-workarounds
+endif
+endif
+
+#
+# Firmware support
+#
+libs-$(CONFIG_ARC) += arch/mips/fw/arc/
+libs-$(CONFIG_CFE) += arch/mips/fw/cfe/
+libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/
+libs-y += arch/mips/fw/lib/
+
+#
+# Kernel compression
+#
+ifdef SYS_SUPPORTS_ZBOOT
+COMPRESSION_FNAME = vmlinuz
+else
+COMPRESSION_FNAME = vmlinux
+endif
+
+#
+# Board-dependent options and extra files
+#
+include $(srctree)/arch/mips/Kbuild.platforms
+
+#
+# NETLOGIC SOC Common (common)
+#
+cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic
+cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic
+
+#
+# NETLOGIC XLR/XLS SoC, Simulator and boards
+#
+core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/
+load-$(CONFIG_NLM_XLR_BOARD) += 0xffffffff84000000
+
+cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
+drivers-$(CONFIG_PCI) += arch/mips/pci/
+
+#
+# Automatically detect the build format. By default we choose
+# the elf format according to the load address.
+# We can always force a build with a 64-bits symbol format by
+# passing 'KBUILD_SYM32=no' option to the make's command line.
+#
+ifdef CONFIG_64BIT
+ ifndef KBUILD_SYM32
+ ifeq ($(shell expr $(load-y) \< 0xffffffff80000000), 0)
+ KBUILD_SYM32 = y
+ endif
+ endif
+
+ ifeq ($(KBUILD_SYM32)$(call cc-option-yn,-msym32), yy)
+ cflags-y += -msym32 -DKBUILD_64BIT_SYM32
+ else
+ ifeq ($(CONFIG_CPU_DADDI_WORKAROUNDS), y)
+ $(error CONFIG_CPU_DADDI_WORKAROUNDS unsupported without -msym32)
+ endif
+ endif
+endif
+
+KBUILD_AFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_CPPFLAGS += -D"VMLINUX_LOAD_ADDRESS=$(load-y)"
+KBUILD_CPPFLAGS += -D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)"
+
+LDFLAGS += -m $(ld-emul)
+
+ifdef CONFIG_MIPS
+CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \
+ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
+ sed -e 's/^\#define /-D/' -e "s/ /='/" -e "s/$$/'/")
+ifdef CONFIG_64BIT
+CHECKFLAGS += -m64
+endif
+endif
+
+OBJCOPYFLAGS += --remove-section=.reginfo
+
+head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
+
+libs-y += arch/mips/lib/
+
+# See arch/mips/Kbuild for content of core part of the kernel
+core-y += arch/mips/
+
+drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/
+
+# suspend and hibernation support
+drivers-$(CONFIG_PM) += arch/mips/power/
+
+ifdef CONFIG_LASAT
+rom.bin rom.sw: vmlinux
+ $(Q)$(MAKE) $(build)=arch/mips/lasat/image $@
+endif
+
+#
+# Some machines like the Indy need 32-bit ELF binaries for booting purposes.
+# Other need ECOFF, so we build a 32-bit ELF binary for them which we then
+# convert to ECOFF using elf2ecoff.
+#
+vmlinux.32: vmlinux
+ $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+
+
+#obj-$(CONFIG_KPROBES) += kprobes.o
+
+#
+# The 64-bit ELF tools are pretty broken so at this time we generate 64-bit
+# ELF files from 32-bit files by conversion.
+#
+vmlinux.64: vmlinux
+ $(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
+
+all: $(all-y)
+
+# boot
+vmlinux.bin vmlinux.ecoff vmlinux.srec: $(vmlinux-32) FORCE
+ $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) arch/mips/boot/$@
+
+# boot/compressed
+vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec: $(vmlinux-32) FORCE
+ $(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
+ VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $@
+
+
+CLEAN_FILES += vmlinux.32 vmlinux.64
+
+archprepare:
+ifdef CONFIG_MIPS32_N32
+ @echo ' Checking missing-syscalls for N32'
+ $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=n32"
+endif
+ifdef CONFIG_MIPS32_O32
+ @echo ' Checking missing-syscalls for O32'
+ $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=32"
+endif
+
+install:
+ $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
+ $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE)
+ $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
+ $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
+
+archclean:
+ $(Q)$(MAKE) $(clean)=arch/mips/boot
+ $(Q)$(MAKE) $(clean)=arch/mips/boot/compressed
+ $(Q)$(MAKE) $(clean)=arch/mips/lasat
+
+define archhelp
+ echo ' install - install kernel into $(INSTALL_PATH)'
+ echo ' vmlinux.ecoff - ECOFF boot image'
+ echo ' vmlinux.bin - Raw binary boot image'
+ echo ' vmlinux.srec - SREC boot image'
+ echo ' vmlinuz - Compressed boot(zboot) image'
+ echo ' vmlinuz.ecoff - ECOFF zboot image'
+ echo ' vmlinuz.bin - Raw binary zboot image'
+ echo ' vmlinuz.srec - SREC zboot image'
+ echo
+ echo ' These will be default as appropriate for a configured platform.'
+endef
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
new file mode 100644
index 00000000..2ccfd4a1
--- /dev/null
+++ b/arch/mips/alchemy/Kconfig
@@ -0,0 +1,160 @@
+# au1000-style gpio and interrupt controllers
+config ALCHEMY_GPIOINT_AU1000
+ bool
+
+# select this in your board config if you don't want to use the gpio
+# namespace as documented in the manuals. In this case however you need
+# to create the necessary gpio_* functions in your board code/headers!
+# see arch/mips/include/asm/mach-au1x00/gpio.h for more information.
+config ALCHEMY_GPIO_INDIRECT
+ def_bool n
+
+choice
+ prompt "Machine type"
+ depends on MIPS_ALCHEMY
+ default MIPS_DB1000
+
+config MIPS_MTX1
+ bool "4G Systems MTX-1 board"
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_BOSPORUS
+ bool "Alchemy Bosporus board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_DB1000
+ bool "Alchemy DB1000 board"
+ select SOC_AU1000
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_DB1100
+ bool "Alchemy DB1100 board"
+ select SOC_AU1100
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_DB1200
+ bool "Alchemy DB1200 board"
+ select SOC_AU1200
+ select DMA_COHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_DB1500
+ bool "Alchemy DB1500 board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_DB1550
+ bool "Alchemy DB1550 board"
+ select SOC_AU1550
+ select HW_HAS_PCI
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_MIRAGE
+ bool "Alchemy Mirage board"
+ select DMA_NONCOHERENT
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_PB1000
+ bool "Alchemy PB1000 board"
+ select SOC_AU1000
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_PB1100
+ bool "Alchemy PB1100 board"
+ select SOC_AU1100
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_PB1200
+ bool "Alchemy PB1200 board"
+ select SOC_AU1200
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_PB1500
+ bool "Alchemy PB1500 board"
+ select SOC_AU1500
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_PB1550
+ bool "Alchemy PB1550 board"
+ select SOC_AU1550
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_XXS1500
+ bool "MyCable XXS1500 board"
+ select DMA_NONCOHERENT
+ select SOC_AU1500
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+config MIPS_GPR
+ bool "Trapeze ITS GPR board"
+ select SOC_AU1550
+ select HW_HAS_PCI
+ select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+
+endchoice
+
+config SOC_AU1000
+ bool
+ select ALCHEMY_GPIOINT_AU1000
+
+config SOC_AU1100
+ bool
+ select ALCHEMY_GPIOINT_AU1000
+
+config SOC_AU1500
+ bool
+ select ALCHEMY_GPIOINT_AU1000
+
+config SOC_AU1550
+ bool
+ select ALCHEMY_GPIOINT_AU1000
+
+config SOC_AU1200
+ bool
+ select ALCHEMY_GPIOINT_AU1000
diff --git a/arch/mips/alchemy/Platform b/arch/mips/alchemy/Platform
new file mode 100644
index 00000000..96e9e41f
--- /dev/null
+++ b/arch/mips/alchemy/Platform
@@ -0,0 +1,114 @@
+#
+# Core Alchemy code
+#
+platform-$(CONFIG_MIPS_ALCHEMY) += alchemy/common/
+
+
+#
+# AMD Alchemy Pb1000 eval board
+#
+platform-$(CONFIG_MIPS_PB1000) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1000) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1000) += 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1100 eval board
+#
+platform-$(CONFIG_MIPS_PB1100) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1100) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1100) += 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1500 eval board
+#
+platform-$(CONFIG_MIPS_PB1500) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1500) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1500) += 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1550 eval board
+#
+platform-$(CONFIG_MIPS_PB1550) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1550) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000
+
+#
+# AMD Alchemy Pb1200 eval board
+#
+platform-$(CONFIG_MIPS_PB1200) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_PB1200) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
+load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000
+
+#
+# AMD Alchemy Db1000 eval board
+#
+platform-$(CONFIG_MIPS_DB1000) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000
+
+#
+# AMD Alchemy Db1100 eval board
+#
+platform-$(CONFIG_MIPS_DB1100) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1100) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1100) += 0xffffffff80100000
+
+#
+# AMD Alchemy Db1500 eval board
+#
+platform-$(CONFIG_MIPS_DB1500) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1500) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1500) += 0xffffffff80100000
+
+#
+# AMD Alchemy Db1550 eval board
+#
+platform-$(CONFIG_MIPS_DB1550) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
+
+#
+# AMD Alchemy Db1200 eval board
+#
+platform-$(CONFIG_MIPS_DB1200) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1200) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
+
+#
+# AMD Alchemy Bosporus eval board
+#
+platform-$(CONFIG_MIPS_BOSPORUS) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_BOSPORUS) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_BOSPORUS) += 0xffffffff80100000
+
+#
+# AMD Alchemy Mirage eval board
+#
+platform-$(CONFIG_MIPS_MIRAGE) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_MIRAGE) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_MIRAGE) += 0xffffffff80100000
+
+#
+# 4G-Systems eval board
+#
+platform-$(CONFIG_MIPS_MTX1) += alchemy/mtx-1/
+load-$(CONFIG_MIPS_MTX1) += 0xffffffff80100000
+
+#
+# MyCable eval board
+#
+platform-$(CONFIG_MIPS_XXS1500) += alchemy/xxs1500/
+load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
+
+#
+# Trapeze ITS GRP board
+#
+platform-$(CONFIG_MIPS_GPR) += alchemy/gpr/
+load-$(CONFIG_MIPS_GPR) += 0xffffffff80100000
+
+# boards can specify their own <gpio.h> in one of their include dirs.
+# If they do, placing this line here at the end will make sure the
+# compiler picks the board one. If they don't, it will make sure
+# the alchemy generic gpio header is picked up.
+
+cflags-$(CONFIG_MIPS_ALCHEMY) += -I$(srctree)/arch/mips/include/asm/mach-au1x00
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
new file mode 100644
index 00000000..27811fe3
--- /dev/null
+++ b/arch/mips/alchemy/common/Makefile
@@ -0,0 +1,20 @@
+#
+# Copyright 2000, 2008 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for the Alchemy Au1xx0 CPUs, generic files.
+#
+
+obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
+ sleeper.o dma.o dbdma.o
+
+obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o
+
+# optional gpiolib support
+ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
+ ifeq ($(CONFIG_GPIOLIB),y)
+ obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o
+ endif
+endif
+
+obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c
new file mode 100644
index 00000000..f38298a8
--- /dev/null
+++ b/arch/mips/alchemy/common/clocks.c
@@ -0,0 +1,105 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Simple Au1xx0 clocks routines.
+ *
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/time.h>
+#include <asm/mach-au1x00/au1000.h>
+
+/*
+ * I haven't found anyone that doesn't use a 12 MHz source clock,
+ * but just in case.....
+ */
+#define AU1000_SRC_CLK 12000000
+
+static unsigned int au1x00_clock; /* Hz */
+static unsigned long uart_baud_base;
+
+/*
+ * Set the au1000_clock
+ */
+void set_au1x00_speed(unsigned int new_freq)
+{
+ au1x00_clock = new_freq;
+}
+
+unsigned int get_au1x00_speed(void)
+{
+ return au1x00_clock;
+}
+EXPORT_SYMBOL(get_au1x00_speed);
+
+/*
+ * The UART baud base is not known at compile time ... if
+ * we want to be able to use the same code on different
+ * speed CPUs.
+ */
+unsigned long get_au1x00_uart_baud_base(void)
+{
+ return uart_baud_base;
+}
+
+void set_au1x00_uart_baud_base(unsigned long new_baud_base)
+{
+ uart_baud_base = new_baud_base;
+}
+
+/*
+ * We read the real processor speed from the PLL. This is important
+ * because it is more accurate than computing it from the 32 KHz
+ * counter, if it exists. If we don't have an accurate processor
+ * speed, all of the peripherals that derive their clocks based on
+ * this advertised speed will introduce error and sometimes not work
+ * properly. This function is further convoluted to still allow configurations
+ * to do that in case they have really, really old silicon with a
+ * write-only PLL register. -- Dan
+ */
+unsigned long au1xxx_calc_clock(void)
+{
+ unsigned long cpu_speed;
+
+ /*
+ * On early Au1000, sys_cpupll was write-only. Since these
+ * silicon versions of Au1000 are not sold by AMD, we don't bend
+ * over backwards trying to determine the frequency.
+ */
+ if (au1xxx_cpu_has_pll_wo())
+ cpu_speed = 396000000;
+ else
+ cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
+
+ /* On Alchemy CPU:counter ratio is 1:1 */
+ mips_hpt_frequency = cpu_speed;
+ /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
+ set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
+ & 0x03) + 2) * 16));
+
+ set_au1x00_speed(cpu_speed);
+
+ return cpu_speed;
+}
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
new file mode 100644
index 00000000..3a5abb54
--- /dev/null
+++ b/arch/mips/alchemy/common/dbdma.c
@@ -0,0 +1,1065 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * The Descriptor Based DMA channel manager that first appeared
+ * on the Au1550. I started with dma.c, but I think all that is
+ * left is this initial comment :-)
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ * dan@embeddededge.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/syscore_ops.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+
+/*
+ * The Descriptor Based DMA supports up to 16 channels.
+ *
+ * There are 32 devices defined. We keep an internal structure
+ * of devices using these channels, along with additional
+ * information.
+ *
+ * We allocate the descriptors and allow access to them through various
+ * functions. The drivers allocate the data buffers and assign them
+ * to the descriptors.
+ */
+static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock);
+
+/* I couldn't find a macro that did this... */
+#define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1))
+
+static dbdma_global_t *dbdma_gptr =
+ (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
+static int dbdma_initialized;
+
+static dbdev_tab_t dbdev_tab[] = {
+#ifdef CONFIG_SOC_AU1550
+ /* UARTS */
+ { DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
+ { DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
+ { DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 },
+ { DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 },
+
+ /* EXT DMA */
+ { DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 },
+
+ /* USB DEV */
+ { DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 },
+ { DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 },
+ { DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 },
+ { DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 },
+ { DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 },
+ { DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 },
+
+ /* PSC 0 */
+ { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
+ { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
+
+ /* PSC 1 */
+ { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
+ { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
+
+ /* PSC 2 */
+ { DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 },
+ { DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 },
+
+ /* PSC 3 */
+ { DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 },
+ { DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 },
+
+ { DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */
+ { DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */
+
+ /* MAC 0 */
+ { DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+
+ /* MAC 1 */
+ { DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+
+#endif /* CONFIG_SOC_AU1550 */
+
+#ifdef CONFIG_SOC_AU1200
+ { DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
+ { DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
+ { DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 },
+ { DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 },
+
+ { DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
+
+ { DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+ { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
+ { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
+ { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 },
+ { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
+
+ { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
+ { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
+
+ { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 },
+ { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 },
+ { DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+ { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 },
+ { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 },
+ { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+ { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
+ { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
+ { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
+ { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+ { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+
+#endif /* CONFIG_SOC_AU1200 */
+
+ { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+ /* Provide 16 user definable device types */
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+ { ~0, 0, 0, 0, 0, 0, 0 },
+};
+
+#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab)
+
+
+static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
+
+static dbdev_tab_t *find_dbdev_id(u32 id)
+{
+ int i;
+ dbdev_tab_t *p;
+ for (i = 0; i < DBDEV_TAB_SIZE; ++i) {
+ p = &dbdev_tab[i];
+ if (p->dev_id == id)
+ return p;
+ }
+ return NULL;
+}
+
+void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp)
+{
+ return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+}
+EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt);
+
+u32 au1xxx_ddma_add_device(dbdev_tab_t *dev)
+{
+ u32 ret = 0;
+ dbdev_tab_t *p;
+ static u16 new_id = 0x1000;
+
+ p = find_dbdev_id(~0);
+ if (NULL != p) {
+ memcpy(p, dev, sizeof(dbdev_tab_t));
+ p->dev_id = DSCR_DEV2CUSTOM_ID(new_id, dev->dev_id);
+ ret = p->dev_id;
+ new_id++;
+#if 0
+ printk(KERN_DEBUG "add_device: id:%x flags:%x padd:%x\n",
+ p->dev_id, p->dev_flags, p->dev_physaddr);
+#endif
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(au1xxx_ddma_add_device);
+
+void au1xxx_ddma_del_device(u32 devid)
+{
+ dbdev_tab_t *p = find_dbdev_id(devid);
+
+ if (p != NULL) {
+ memset(p, 0, sizeof(dbdev_tab_t));
+ p->dev_id = ~0;
+ }
+}
+EXPORT_SYMBOL(au1xxx_ddma_del_device);
+
+/* Allocate a channel and return a non-zero descriptor if successful. */
+u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ void (*callback)(int, void *), void *callparam)
+{
+ unsigned long flags;
+ u32 used, chan;
+ u32 dcp;
+ int i;
+ dbdev_tab_t *stp, *dtp;
+ chan_tab_t *ctp;
+ au1x_dma_chan_t *cp;
+
+ /*
+ * We do the intialization on the first channel allocation.
+ * We have to wait because of the interrupt handler initialization
+ * which can't be done successfully during board set up.
+ */
+ if (!dbdma_initialized)
+ return 0;
+
+ stp = find_dbdev_id(srcid);
+ if (stp == NULL)
+ return 0;
+ dtp = find_dbdev_id(destid);
+ if (dtp == NULL)
+ return 0;
+
+ used = 0;
+
+ /* Check to see if we can get both channels. */
+ spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+ if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
+ (stp->dev_flags & DEV_FLAGS_ANYUSE)) {
+ /* Got source */
+ stp->dev_flags |= DEV_FLAGS_INUSE;
+ if (!(dtp->dev_flags & DEV_FLAGS_INUSE) ||
+ (dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
+ /* Got destination */
+ dtp->dev_flags |= DEV_FLAGS_INUSE;
+ } else {
+ /* Can't get dest. Release src. */
+ stp->dev_flags &= ~DEV_FLAGS_INUSE;
+ used++;
+ }
+ } else
+ used++;
+ spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+
+ if (used)
+ return 0;
+
+ /* Let's see if we can allocate a channel for it. */
+ ctp = NULL;
+ chan = 0;
+ spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+ for (i = 0; i < NUM_DBDMA_CHANS; i++)
+ if (chan_tab_ptr[i] == NULL) {
+ /*
+ * If kmalloc fails, it is caught below same
+ * as a channel not available.
+ */
+ ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC);
+ chan_tab_ptr[i] = ctp;
+ break;
+ }
+ spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+
+ if (ctp != NULL) {
+ memset(ctp, 0, sizeof(chan_tab_t));
+ ctp->chan_index = chan = i;
+ dcp = KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
+ dcp += (0x0100 * chan);
+ ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
+ cp = (au1x_dma_chan_t *)dcp;
+ ctp->chan_src = stp;
+ ctp->chan_dest = dtp;
+ ctp->chan_callback = callback;
+ ctp->chan_callparam = callparam;
+
+ /* Initialize channel configuration. */
+ i = 0;
+ if (stp->dev_intlevel)
+ i |= DDMA_CFG_SED;
+ if (stp->dev_intpolarity)
+ i |= DDMA_CFG_SP;
+ if (dtp->dev_intlevel)
+ i |= DDMA_CFG_DED;
+ if (dtp->dev_intpolarity)
+ i |= DDMA_CFG_DP;
+ if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
+ (dtp->dev_flags & DEV_FLAGS_SYNC))
+ i |= DDMA_CFG_SYNC;
+ cp->ddma_cfg = i;
+ au_sync();
+
+ /*
+ * Return a non-zero value that can be used to find the channel
+ * information in subsequent operations.
+ */
+ return (u32)(&chan_tab_ptr[chan]);
+ }
+
+ /* Release devices */
+ stp->dev_flags &= ~DEV_FLAGS_INUSE;
+ dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+
+ return 0;
+}
+EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
+
+/*
+ * Set the device width if source or destination is a FIFO.
+ * Should be 8, 16, or 32 bits.
+ */
+u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
+{
+ u32 rv;
+ chan_tab_t *ctp;
+ dbdev_tab_t *stp, *dtp;
+
+ ctp = *((chan_tab_t **)chanid);
+ stp = ctp->chan_src;
+ dtp = ctp->chan_dest;
+ rv = 0;
+
+ if (stp->dev_flags & DEV_FLAGS_IN) { /* Source in fifo */
+ rv = stp->dev_devwidth;
+ stp->dev_devwidth = bits;
+ }
+ if (dtp->dev_flags & DEV_FLAGS_OUT) { /* Destination out fifo */
+ rv = dtp->dev_devwidth;
+ dtp->dev_devwidth = bits;
+ }
+
+ return rv;
+}
+EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
+
+/* Allocate a descriptor ring, initializing as much as possible. */
+u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+{
+ int i;
+ u32 desc_base, srcid, destid;
+ u32 cmd0, cmd1, src1, dest1;
+ u32 src0, dest0;
+ chan_tab_t *ctp;
+ dbdev_tab_t *stp, *dtp;
+ au1x_ddma_desc_t *dp;
+
+ /*
+ * I guess we could check this to be within the
+ * range of the table......
+ */
+ ctp = *((chan_tab_t **)chanid);
+ stp = ctp->chan_src;
+ dtp = ctp->chan_dest;
+
+ /*
+ * The descriptors must be 32-byte aligned. There is a
+ * possibility the allocation will give us such an address,
+ * and if we try that first we are likely to not waste larger
+ * slabs of memory.
+ */
+ desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
+ GFP_KERNEL|GFP_DMA);
+ if (desc_base == 0)
+ return 0;
+
+ if (desc_base & 0x1f) {
+ /*
+ * Lost....do it again, allocate extra, and round
+ * the address base.
+ */
+ kfree((const void *)desc_base);
+ i = entries * sizeof(au1x_ddma_desc_t);
+ i += (sizeof(au1x_ddma_desc_t) - 1);
+ desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA);
+ if (desc_base == 0)
+ return 0;
+
+ ctp->cdb_membase = desc_base;
+ desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
+ } else
+ ctp->cdb_membase = desc_base;
+
+ dp = (au1x_ddma_desc_t *)desc_base;
+
+ /* Keep track of the base descriptor. */
+ ctp->chan_desc_base = dp;
+
+ /* Initialize the rings with as much information as we know. */
+ srcid = stp->dev_id;
+ destid = dtp->dev_id;
+
+ cmd0 = cmd1 = src1 = dest1 = 0;
+ src0 = dest0 = 0;
+
+ cmd0 |= DSCR_CMD0_SID(srcid);
+ cmd0 |= DSCR_CMD0_DID(destid);
+ cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
+ cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE);
+
+ /* Is it mem to mem transfer? */
+ if (((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) ||
+ (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) &&
+ ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) ||
+ (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS)))
+ cmd0 |= DSCR_CMD0_MEM;
+
+ switch (stp->dev_devwidth) {
+ case 8:
+ cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_BYTE);
+ break;
+ case 16:
+ cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_HALFWORD);
+ break;
+ case 32:
+ default:
+ cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_WORD);
+ break;
+ }
+
+ switch (dtp->dev_devwidth) {
+ case 8:
+ cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_BYTE);
+ break;
+ case 16:
+ cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_HALFWORD);
+ break;
+ case 32:
+ default:
+ cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_WORD);
+ break;
+ }
+
+ /*
+ * If the device is marked as an in/out FIFO, ensure it is
+ * set non-coherent.
+ */
+ if (stp->dev_flags & DEV_FLAGS_IN)
+ cmd0 |= DSCR_CMD0_SN; /* Source in FIFO */
+ if (dtp->dev_flags & DEV_FLAGS_OUT)
+ cmd0 |= DSCR_CMD0_DN; /* Destination out FIFO */
+
+ /*
+ * Set up source1. For now, assume no stride and increment.
+ * A channel attribute update can change this later.
+ */
+ switch (stp->dev_tsize) {
+ case 1:
+ src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE1);
+ break;
+ case 2:
+ src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE2);
+ break;
+ case 4:
+ src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE4);
+ break;
+ case 8:
+ default:
+ src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE8);
+ break;
+ }
+
+ /* If source input is FIFO, set static address. */
+ if (stp->dev_flags & DEV_FLAGS_IN) {
+ if (stp->dev_flags & DEV_FLAGS_BURSTABLE)
+ src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
+ else
+ src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
+ }
+
+ if (stp->dev_physaddr)
+ src0 = stp->dev_physaddr;
+
+ /*
+ * Set up dest1. For now, assume no stride and increment.
+ * A channel attribute update can change this later.
+ */
+ switch (dtp->dev_tsize) {
+ case 1:
+ dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE1);
+ break;
+ case 2:
+ dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE2);
+ break;
+ case 4:
+ dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE4);
+ break;
+ case 8:
+ default:
+ dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE8);
+ break;
+ }
+
+ /* If destination output is FIFO, set static address. */
+ if (dtp->dev_flags & DEV_FLAGS_OUT) {
+ if (dtp->dev_flags & DEV_FLAGS_BURSTABLE)
+ dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
+ else
+ dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
+ }
+
+ if (dtp->dev_physaddr)
+ dest0 = dtp->dev_physaddr;
+
+#if 0
+ printk(KERN_DEBUG "did:%x sid:%x cmd0:%x cmd1:%x source0:%x "
+ "source1:%x dest0:%x dest1:%x\n",
+ dtp->dev_id, stp->dev_id, cmd0, cmd1, src0,
+ src1, dest0, dest1);
+#endif
+ for (i = 0; i < entries; i++) {
+ dp->dscr_cmd0 = cmd0;
+ dp->dscr_cmd1 = cmd1;
+ dp->dscr_source0 = src0;
+ dp->dscr_source1 = src1;
+ dp->dscr_dest0 = dest0;
+ dp->dscr_dest1 = dest1;
+ dp->dscr_stat = 0;
+ dp->sw_context = 0;
+ dp->sw_status = 0;
+ dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1));
+ dp++;
+ }
+
+ /* Make last descrptor point to the first. */
+ dp--;
+ dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(ctp->chan_desc_base));
+ ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
+
+ return (u32)ctp->chan_desc_base;
+}
+EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
+
+/*
+ * Put a source buffer into the DMA ring.
+ * This updates the source pointer and byte count. Normally used
+ * for memory to fifo transfers.
+ */
+u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
+{
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+ /*
+ * I guess we could check this to be within the
+ * range of the table......
+ */
+ ctp = *(chan_tab_t **)chanid;
+
+ /*
+ * We should have multiple callers for a particular channel,
+ * an interrupt doesn't affect this pointer nor the descriptor,
+ * so no locking should be needed.
+ */
+ dp = ctp->put_ptr;
+
+ /*
+ * If the descriptor is valid, we are way ahead of the DMA
+ * engine, so just return an error condition.
+ */
+ if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ return 0;
+
+ /* Load up buffer address and byte count. */
+ dp->dscr_source0 = buf & ~0UL;
+ dp->dscr_cmd1 = nbytes;
+ /* Check flags */
+ if (flags & DDMA_FLAGS_IE)
+ dp->dscr_cmd0 |= DSCR_CMD0_IE;
+ if (flags & DDMA_FLAGS_NOIE)
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+
+ /*
+ * There is an errata on the Au1200/Au1550 parts that could result
+ * in "stale" data being DMA'ed. It has to do with the snoop logic on
+ * the cache eviction buffer. DMA_NONCOHERENT is on by default for
+ * these parts. If it is fixed in the future, these dma_cache_inv will
+ * just be nothing more than empty macros. See io.h.
+ */
+ dma_cache_wback_inv((unsigned long)buf, nbytes);
+ dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
+ au_sync();
+ dma_cache_wback_inv((unsigned long)dp, sizeof(*dp));
+ ctp->chan_ptr->ddma_dbell = 0;
+
+ /* Get next descriptor pointer. */
+ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+ /* Return something non-zero. */
+ return nbytes;
+}
+EXPORT_SYMBOL(au1xxx_dbdma_put_source);
+
+/* Put a destination buffer into the DMA ring.
+ * This updates the destination pointer and byte count. Normally used
+ * to place an empty buffer into the ring for fifo to memory transfers.
+ */
+u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags)
+{
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+ /* I guess we could check this to be within the
+ * range of the table......
+ */
+ ctp = *((chan_tab_t **)chanid);
+
+ /* We should have multiple callers for a particular channel,
+ * an interrupt doesn't affect this pointer nor the descriptor,
+ * so no locking should be needed.
+ */
+ dp = ctp->put_ptr;
+
+ /* If the descriptor is valid, we are way ahead of the DMA
+ * engine, so just return an error condition.
+ */
+ if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ return 0;
+
+ /* Load up buffer address and byte count */
+
+ /* Check flags */
+ if (flags & DDMA_FLAGS_IE)
+ dp->dscr_cmd0 |= DSCR_CMD0_IE;
+ if (flags & DDMA_FLAGS_NOIE)
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+
+ dp->dscr_dest0 = buf & ~0UL;
+ dp->dscr_cmd1 = nbytes;
+#if 0
+ printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
+ dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
+ dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
+#endif
+ /*
+ * There is an errata on the Au1200/Au1550 parts that could result in
+ * "stale" data being DMA'ed. It has to do with the snoop logic on the
+ * cache eviction buffer. DMA_NONCOHERENT is on by default for these
+ * parts. If it is fixed in the future, these dma_cache_inv will just
+ * be nothing more than empty macros. See io.h.
+ */
+ dma_cache_inv((unsigned long)buf, nbytes);
+ dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
+ au_sync();
+ dma_cache_wback_inv((unsigned long)dp, sizeof(*dp));
+ ctp->chan_ptr->ddma_dbell = 0;
+
+ /* Get next descriptor pointer. */
+ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+ /* Return something non-zero. */
+ return nbytes;
+}
+EXPORT_SYMBOL(au1xxx_dbdma_put_dest);
+
+/*
+ * Get a destination buffer into the DMA ring.
+ * Normally used to get a full buffer from the ring during fifo
+ * to memory transfers. This does not set the valid bit, you will
+ * have to put another destination buffer to keep the DMA going.
+ */
+u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
+{
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+ u32 rv;
+
+ /*
+ * I guess we could check this to be within the
+ * range of the table......
+ */
+ ctp = *((chan_tab_t **)chanid);
+
+ /*
+ * We should have multiple callers for a particular channel,
+ * an interrupt doesn't affect this pointer nor the descriptor,
+ * so no locking should be needed.
+ */
+ dp = ctp->get_ptr;
+
+ /*
+ * If the descriptor is valid, we are way ahead of the DMA
+ * engine, so just return an error condition.
+ */
+ if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ return 0;
+
+ /* Return buffer address and byte count. */
+ *buf = (void *)(phys_to_virt(dp->dscr_dest0));
+ *nbytes = dp->dscr_cmd1;
+ rv = dp->dscr_stat;
+
+ /* Get next descriptor pointer. */
+ ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+ /* Return something non-zero. */
+ return rv;
+}
+EXPORT_SYMBOL_GPL(au1xxx_dbdma_get_dest);
+
+void au1xxx_dbdma_stop(u32 chanid)
+{
+ chan_tab_t *ctp;
+ au1x_dma_chan_t *cp;
+ int halt_timeout = 0;
+
+ ctp = *((chan_tab_t **)chanid);
+
+ cp = ctp->chan_ptr;
+ cp->ddma_cfg &= ~DDMA_CFG_EN; /* Disable channel */
+ au_sync();
+ while (!(cp->ddma_stat & DDMA_STAT_H)) {
+ udelay(1);
+ halt_timeout++;
+ if (halt_timeout > 100) {
+ printk(KERN_WARNING "warning: DMA channel won't halt\n");
+ break;
+ }
+ }
+ /* clear current desc valid and doorbell */
+ cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
+ au_sync();
+}
+EXPORT_SYMBOL(au1xxx_dbdma_stop);
+
+/*
+ * Start using the current descriptor pointer. If the DBDMA encounters
+ * a non-valid descriptor, it will stop. In this case, we can just
+ * continue by adding a buffer to the list and starting again.
+ */
+void au1xxx_dbdma_start(u32 chanid)
+{
+ chan_tab_t *ctp;
+ au1x_dma_chan_t *cp;
+
+ ctp = *((chan_tab_t **)chanid);
+ cp = ctp->chan_ptr;
+ cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
+ cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */
+ au_sync();
+ cp->ddma_dbell = 0;
+ au_sync();
+}
+EXPORT_SYMBOL(au1xxx_dbdma_start);
+
+void au1xxx_dbdma_reset(u32 chanid)
+{
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+
+ au1xxx_dbdma_stop(chanid);
+
+ ctp = *((chan_tab_t **)chanid);
+ ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
+
+ /* Run through the descriptors and reset the valid indicator. */
+ dp = ctp->chan_desc_base;
+
+ do {
+ dp->dscr_cmd0 &= ~DSCR_CMD0_V;
+ /*
+ * Reset our software status -- this is used to determine
+ * if a descriptor is in use by upper level software. Since
+ * posting can reset 'V' bit.
+ */
+ dp->sw_status = 0;
+ dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ } while (dp != ctp->chan_desc_base);
+}
+EXPORT_SYMBOL(au1xxx_dbdma_reset);
+
+u32 au1xxx_get_dma_residue(u32 chanid)
+{
+ chan_tab_t *ctp;
+ au1x_dma_chan_t *cp;
+ u32 rv;
+
+ ctp = *((chan_tab_t **)chanid);
+ cp = ctp->chan_ptr;
+
+ /* This is only valid if the channel is stopped. */
+ rv = cp->ddma_bytecnt;
+ au_sync();
+
+ return rv;
+}
+EXPORT_SYMBOL_GPL(au1xxx_get_dma_residue);
+
+void au1xxx_dbdma_chan_free(u32 chanid)
+{
+ chan_tab_t *ctp;
+ dbdev_tab_t *stp, *dtp;
+
+ ctp = *((chan_tab_t **)chanid);
+ stp = ctp->chan_src;
+ dtp = ctp->chan_dest;
+
+ au1xxx_dbdma_stop(chanid);
+
+ kfree((void *)ctp->cdb_membase);
+
+ stp->dev_flags &= ~DEV_FLAGS_INUSE;
+ dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+ chan_tab_ptr[ctp->chan_index] = NULL;
+
+ kfree(ctp);
+}
+EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
+
+static irqreturn_t dbdma_interrupt(int irq, void *dev_id)
+{
+ u32 intstat;
+ u32 chan_index;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+ au1x_dma_chan_t *cp;
+
+ intstat = dbdma_gptr->ddma_intstat;
+ au_sync();
+ chan_index = __ffs(intstat);
+
+ ctp = chan_tab_ptr[chan_index];
+ cp = ctp->chan_ptr;
+ dp = ctp->cur_ptr;
+
+ /* Reset interrupt. */
+ cp->ddma_irq = 0;
+ au_sync();
+
+ if (ctp->chan_callback)
+ ctp->chan_callback(irq, ctp->chan_callparam);
+
+ ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ return IRQ_RETVAL(1);
+}
+
+void au1xxx_dbdma_dump(u32 chanid)
+{
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+ dbdev_tab_t *stp, *dtp;
+ au1x_dma_chan_t *cp;
+ u32 i = 0;
+
+ ctp = *((chan_tab_t **)chanid);
+ stp = ctp->chan_src;
+ dtp = ctp->chan_dest;
+ cp = ctp->chan_ptr;
+
+ printk(KERN_DEBUG "Chan %x, stp %x (dev %d) dtp %x (dev %d)\n",
+ (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp,
+ dtp - dbdev_tab);
+ printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n",
+ (u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
+ (u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
+
+ printk(KERN_DEBUG "dbdma chan %x\n", (u32)cp);
+ printk(KERN_DEBUG "cfg %08x, desptr %08x, statptr %08x\n",
+ cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
+ printk(KERN_DEBUG "dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
+ cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat,
+ cp->ddma_bytecnt);
+
+ /* Run through the descriptors */
+ dp = ctp->chan_desc_base;
+
+ do {
+ printk(KERN_DEBUG "Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
+ i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+ printk(KERN_DEBUG "src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
+ dp->dscr_source0, dp->dscr_source1,
+ dp->dscr_dest0, dp->dscr_dest1);
+ printk(KERN_DEBUG "stat %08x, nxtptr %08x\n",
+ dp->dscr_stat, dp->dscr_nxtptr);
+ dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+ } while (dp != ctp->chan_desc_base);
+}
+
+/* Put a descriptor into the DMA ring.
+ * This updates the source/destination pointers and byte count.
+ */
+u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
+{
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
+ u32 nbytes = 0;
+
+ /*
+ * I guess we could check this to be within the
+ * range of the table......
+ */
+ ctp = *((chan_tab_t **)chanid);
+
+ /*
+ * We should have multiple callers for a particular channel,
+ * an interrupt doesn't affect this pointer nor the descriptor,
+ * so no locking should be needed.
+ */
+ dp = ctp->put_ptr;
+
+ /*
+ * If the descriptor is valid, we are way ahead of the DMA
+ * engine, so just return an error condition.
+ */
+ if (dp->dscr_cmd0 & DSCR_CMD0_V)
+ return 0;
+
+ /* Load up buffer addresses and byte count. */
+ dp->dscr_dest0 = dscr->dscr_dest0;
+ dp->dscr_source0 = dscr->dscr_source0;
+ dp->dscr_dest1 = dscr->dscr_dest1;
+ dp->dscr_source1 = dscr->dscr_source1;
+ dp->dscr_cmd1 = dscr->dscr_cmd1;
+ nbytes = dscr->dscr_cmd1;
+ /* Allow the caller to specifiy if an interrupt is generated */
+ dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
+ dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
+ ctp->chan_ptr->ddma_dbell = 0;
+
+ /* Get next descriptor pointer. */
+ ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+ /* Return something non-zero. */
+ return nbytes;
+}
+
+
+static unsigned long alchemy_dbdma_pm_data[NUM_DBDMA_CHANS + 1][6];
+
+static int alchemy_dbdma_suspend(void)
+{
+ int i;
+ void __iomem *addr;
+
+ addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
+ alchemy_dbdma_pm_data[0][0] = __raw_readl(addr + 0x00);
+ alchemy_dbdma_pm_data[0][1] = __raw_readl(addr + 0x04);
+ alchemy_dbdma_pm_data[0][2] = __raw_readl(addr + 0x08);
+ alchemy_dbdma_pm_data[0][3] = __raw_readl(addr + 0x0c);
+
+ /* save channel configurations */
+ addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
+ for (i = 1; i <= NUM_DBDMA_CHANS; i++) {
+ alchemy_dbdma_pm_data[i][0] = __raw_readl(addr + 0x00);
+ alchemy_dbdma_pm_data[i][1] = __raw_readl(addr + 0x04);
+ alchemy_dbdma_pm_data[i][2] = __raw_readl(addr + 0x08);
+ alchemy_dbdma_pm_data[i][3] = __raw_readl(addr + 0x0c);
+ alchemy_dbdma_pm_data[i][4] = __raw_readl(addr + 0x10);
+ alchemy_dbdma_pm_data[i][5] = __raw_readl(addr + 0x14);
+
+ /* halt channel */
+ __raw_writel(alchemy_dbdma_pm_data[i][0] & ~1, addr + 0x00);
+ wmb();
+ while (!(__raw_readl(addr + 0x14) & 1))
+ wmb();
+
+ addr += 0x100; /* next channel base */
+ }
+ /* disable channel interrupts */
+ addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
+ __raw_writel(0, addr + 0x0c);
+ wmb();
+
+ return 0;
+}
+
+static void alchemy_dbdma_resume(void)
+{
+ int i;
+ void __iomem *addr;
+
+ addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
+ __raw_writel(alchemy_dbdma_pm_data[0][0], addr + 0x00);
+ __raw_writel(alchemy_dbdma_pm_data[0][1], addr + 0x04);
+ __raw_writel(alchemy_dbdma_pm_data[0][2], addr + 0x08);
+ __raw_writel(alchemy_dbdma_pm_data[0][3], addr + 0x0c);
+
+ /* restore channel configurations */
+ addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
+ for (i = 1; i <= NUM_DBDMA_CHANS; i++) {
+ __raw_writel(alchemy_dbdma_pm_data[i][0], addr + 0x00);
+ __raw_writel(alchemy_dbdma_pm_data[i][1], addr + 0x04);
+ __raw_writel(alchemy_dbdma_pm_data[i][2], addr + 0x08);
+ __raw_writel(alchemy_dbdma_pm_data[i][3], addr + 0x0c);
+ __raw_writel(alchemy_dbdma_pm_data[i][4], addr + 0x10);
+ __raw_writel(alchemy_dbdma_pm_data[i][5], addr + 0x14);
+ wmb();
+ addr += 0x100; /* next channel base */
+ }
+}
+
+static struct syscore_ops alchemy_dbdma_syscore_ops = {
+ .suspend = alchemy_dbdma_suspend,
+ .resume = alchemy_dbdma_resume,
+};
+
+static int __init au1xxx_dbdma_init(void)
+{
+ int irq_nr, ret;
+
+ dbdma_gptr->ddma_config = 0;
+ dbdma_gptr->ddma_throttle = 0;
+ dbdma_gptr->ddma_inten = 0xffff;
+ au_sync();
+
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1550:
+ irq_nr = AU1550_DDMA_INT;
+ break;
+ case ALCHEMY_CPU_AU1200:
+ irq_nr = AU1200_DDMA_INT;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ ret = request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
+ "Au1xxx dbdma", (void *)dbdma_gptr);
+ if (ret)
+ printk(KERN_ERR "Cannot grab DBDMA interrupt!\n");
+ else {
+ dbdma_initialized = 1;
+ printk(KERN_INFO "Alchemy DBDMA initialized\n");
+ register_syscore_ops(&alchemy_dbdma_syscore_ops);
+ }
+
+ return ret;
+}
+subsys_initcall(au1xxx_dbdma_init);
+
+#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c
new file mode 100644
index 00000000..347980e7
--- /dev/null
+++ b/arch/mips/alchemy/common/dma.c
@@ -0,0 +1,268 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * A DMA channel allocator for Au1x00. API is modeled loosely off of
+ * linux/kernel/dma.c.
+ *
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1000_dma.h>
+
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
+ defined(CONFIG_SOC_AU1100)
+/*
+ * A note on resource allocation:
+ *
+ * All drivers needing DMA channels, should allocate and release them
+ * through the public routines `request_dma()' and `free_dma()'.
+ *
+ * In order to avoid problems, all processes should allocate resources in
+ * the same sequence and release them in the reverse order.
+ *
+ * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ.
+ * When releasing them, first release the IRQ, then release the DMA. The
+ * main reason for this order is that, if you are requesting the DMA buffer
+ * done interrupt, you won't know the irq number until the DMA channel is
+ * returned from request_dma.
+ */
+
+/* DMA Channel register block spacing */
+#define DMA_CHANNEL_LEN 0x00000100
+
+DEFINE_SPINLOCK(au1000_dma_spin_lock);
+
+struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
+ {.dev_id = -1,},
+ {.dev_id = -1,},
+ {.dev_id = -1,},
+ {.dev_id = -1,},
+ {.dev_id = -1,},
+ {.dev_id = -1,},
+ {.dev_id = -1,},
+ {.dev_id = -1,}
+};
+EXPORT_SYMBOL(au1000_dma_table);
+
+/* Device FIFO addresses and default DMA modes */
+static const struct dma_dev {
+ unsigned int fifo_addr;
+ unsigned int dma_mode;
+} dma_dev_table[DMA_NUM_DEV] = {
+ { AU1000_UART0_PHYS_ADDR + 0x04, DMA_DW8 }, /* UART0_TX */
+ { AU1000_UART0_PHYS_ADDR + 0x00, DMA_DW8 | DMA_DR }, /* UART0_RX */
+ { 0, 0 }, /* DMA_REQ0 */
+ { 0, 0 }, /* DMA_REQ1 */
+ { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 }, /* AC97 TX c */
+ { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */
+ { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */
+ { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */
+ { AU1000_USBD_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */
+ { AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */
+ { AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */
+ { AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */
+ { AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */
+ { AU1000_USBD_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */
+ /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */
+ { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */
+ { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */
+};
+
+int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
+ int length, int *eof, void *data)
+{
+ int i, len = 0;
+ struct dma_chan *chan;
+
+ for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
+ chan = get_dma_chan(i);
+ if (chan != NULL)
+ len += sprintf(buf + len, "%2d: %s\n",
+ i, chan->dev_str);
+ }
+
+ if (fpos >= len) {
+ *start = buf;
+ *eof = 1;
+ return 0;
+ }
+ *start = buf + fpos;
+ len -= fpos;
+ if (len > length)
+ return length;
+ *eof = 1;
+ return len;
+}
+
+/* Device FIFO addresses and default DMA modes - 2nd bank */
+static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
+ { AU1100_SD0_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 }, /* coherent */
+ { AU1100_SD0_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR }, /* coherent */
+ { AU1100_SD1_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 }, /* coherent */
+ { AU1100_SD1_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR } /* coherent */
+};
+
+void dump_au1000_dma_channel(unsigned int dmanr)
+{
+ struct dma_chan *chan;
+
+ if (dmanr >= NUM_AU1000_DMA_CHANNELS)
+ return;
+ chan = &au1000_dma_table[dmanr];
+
+ printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr);
+ printk(KERN_INFO " mode = 0x%08x\n",
+ au_readl(chan->io + DMA_MODE_SET));
+ printk(KERN_INFO " addr = 0x%08x\n",
+ au_readl(chan->io + DMA_PERIPHERAL_ADDR));
+ printk(KERN_INFO " start0 = 0x%08x\n",
+ au_readl(chan->io + DMA_BUFFER0_START));
+ printk(KERN_INFO " start1 = 0x%08x\n",
+ au_readl(chan->io + DMA_BUFFER1_START));
+ printk(KERN_INFO " count0 = 0x%08x\n",
+ au_readl(chan->io + DMA_BUFFER0_COUNT));
+ printk(KERN_INFO " count1 = 0x%08x\n",
+ au_readl(chan->io + DMA_BUFFER1_COUNT));
+}
+
+/*
+ * Finds a free channel, and binds the requested device to it.
+ * Returns the allocated channel number, or negative on error.
+ * Requests the DMA done IRQ if irqhandler != NULL.
+ */
+int request_au1000_dma(int dev_id, const char *dev_str,
+ irq_handler_t irqhandler,
+ unsigned long irqflags,
+ void *irq_dev_id)
+{
+ struct dma_chan *chan;
+ const struct dma_dev *dev;
+ int i, ret;
+
+#if defined(CONFIG_SOC_AU1100)
+ if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
+ return -EINVAL;
+#else
+ if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
+ return -EINVAL;
+#endif
+
+ for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
+ if (au1000_dma_table[i].dev_id < 0)
+ break;
+
+ if (i == NUM_AU1000_DMA_CHANNELS)
+ return -ENODEV;
+
+ chan = &au1000_dma_table[i];
+
+ if (dev_id >= DMA_NUM_DEV) {
+ dev_id -= DMA_NUM_DEV;
+ dev = &dma_dev_table_bank2[dev_id];
+ } else
+ dev = &dma_dev_table[dev_id];
+
+ if (irqhandler) {
+ chan->irq_dev = irq_dev_id;
+ ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
+ chan->irq_dev);
+ if (ret) {
+ chan->irq_dev = NULL;
+ return ret;
+ }
+ } else {
+ chan->irq_dev = NULL;
+ }
+
+ /* fill it in */
+ chan->io = KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + i * DMA_CHANNEL_LEN;
+ chan->dev_id = dev_id;
+ chan->dev_str = dev_str;
+ chan->fifo_addr = dev->fifo_addr;
+ chan->mode = dev->dma_mode;
+
+ /* initialize the channel before returning */
+ init_dma(i);
+
+ return i;
+}
+EXPORT_SYMBOL(request_au1000_dma);
+
+void free_au1000_dma(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan) {
+ printk(KERN_ERR "Error trying to free DMA%d\n", dmanr);
+ return;
+ }
+
+ disable_dma(dmanr);
+ if (chan->irq_dev)
+ free_irq(chan->irq, chan->irq_dev);
+
+ chan->irq_dev = NULL;
+ chan->dev_id = -1;
+}
+EXPORT_SYMBOL(free_au1000_dma);
+
+static int __init au1000_dma_init(void)
+{
+ int base, i;
+
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1000:
+ base = AU1000_DMA_INT_BASE;
+ break;
+ case ALCHEMY_CPU_AU1500:
+ base = AU1500_DMA_INT_BASE;
+ break;
+ case ALCHEMY_CPU_AU1100:
+ base = AU1100_DMA_INT_BASE;
+ break;
+ default:
+ goto out;
+ }
+
+ for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
+ au1000_dma_table[i].irq = base + i;
+
+ printk(KERN_INFO "Alchemy DMA initialized\n");
+
+out:
+ return 0;
+}
+arch_initcall(au1000_dma_init);
+
+#endif /* AU1000 AU1500 AU1100 */
diff --git a/arch/mips/alchemy/common/gpiolib-au1000.c b/arch/mips/alchemy/common/gpiolib-au1000.c
new file mode 100644
index 00000000..c8e1a94d
--- /dev/null
+++ b/arch/mips/alchemy/common/gpiolib-au1000.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
+ * GPIOLIB support for Au1000, Au1500, Au1100, Au1550 and Au12x0.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Notes :
+ * au1000 SoC have only one GPIO block : GPIO1
+ * Au1100, Au15x0, Au12x0 have a second one : GPIO2
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/gpio.h>
+
+static int gpio2_get(struct gpio_chip *chip, unsigned offset)
+{
+ return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
+}
+
+static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value);
+}
+
+static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE);
+}
+
+static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE,
+ value);
+}
+
+static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE);
+}
+
+
+static int gpio1_get(struct gpio_chip *chip, unsigned offset)
+{
+ return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
+}
+
+static void gpio1_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value);
+}
+
+static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE);
+}
+
+static int gpio1_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE,
+ value);
+}
+
+static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE);
+}
+
+struct gpio_chip alchemy_gpio_chip[] = {
+ [0] = {
+ .label = "alchemy-gpio1",
+ .direction_input = gpio1_direction_input,
+ .direction_output = gpio1_direction_output,
+ .get = gpio1_get,
+ .set = gpio1_set,
+ .to_irq = gpio1_to_irq,
+ .base = ALCHEMY_GPIO1_BASE,
+ .ngpio = ALCHEMY_GPIO1_NUM,
+ },
+ [1] = {
+ .label = "alchemy-gpio2",
+ .direction_input = gpio2_direction_input,
+ .direction_output = gpio2_direction_output,
+ .get = gpio2_get,
+ .set = gpio2_set,
+ .to_irq = gpio2_to_irq,
+ .base = ALCHEMY_GPIO2_BASE,
+ .ngpio = ALCHEMY_GPIO2_NUM,
+ },
+};
+
+static int __init alchemy_gpiolib_init(void)
+{
+ gpiochip_add(&alchemy_gpio_chip[0]);
+ if (alchemy_get_cputype() != ALCHEMY_CPU_AU1000)
+ gpiochip_add(&alchemy_gpio_chip[1]);
+
+ return 0;
+}
+arch_initcall(alchemy_gpiolib_init);
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
new file mode 100644
index 00000000..8b60ba06
--- /dev/null
+++ b/arch/mips/alchemy/common/irq.c
@@ -0,0 +1,646 @@
+/*
+ * Copyright 2001, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mach-au1x00/au1000.h>
+#ifdef CONFIG_MIPS_PB1000
+#include <asm/mach-pb1x00/pb1000.h>
+#endif
+
+/* Interrupt Controller register offsets */
+#define IC_CFG0RD 0x40
+#define IC_CFG0SET 0x40
+#define IC_CFG0CLR 0x44
+#define IC_CFG1RD 0x48
+#define IC_CFG1SET 0x48
+#define IC_CFG1CLR 0x4C
+#define IC_CFG2RD 0x50
+#define IC_CFG2SET 0x50
+#define IC_CFG2CLR 0x54
+#define IC_REQ0INT 0x54
+#define IC_SRCRD 0x58
+#define IC_SRCSET 0x58
+#define IC_SRCCLR 0x5C
+#define IC_REQ1INT 0x5C
+#define IC_ASSIGNRD 0x60
+#define IC_ASSIGNSET 0x60
+#define IC_ASSIGNCLR 0x64
+#define IC_WAKERD 0x68
+#define IC_WAKESET 0x68
+#define IC_WAKECLR 0x6C
+#define IC_MASKRD 0x70
+#define IC_MASKSET 0x70
+#define IC_MASKCLR 0x74
+#define IC_RISINGRD 0x78
+#define IC_RISINGCLR 0x78
+#define IC_FALLINGRD 0x7C
+#define IC_FALLINGCLR 0x7C
+#define IC_TESTBIT 0x80
+
+static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
+
+/* NOTE on interrupt priorities: The original writers of this code said:
+ *
+ * Because of the tight timing of SETUP token to reply transactions,
+ * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT)
+ * needs the highest priority.
+ */
+
+/* per-processor fixed function irqs */
+struct au1xxx_irqmap {
+ int im_irq;
+ int im_type;
+ int im_request; /* set 1 to get higher priority */
+};
+
+struct au1xxx_irqmap au1000_irqmap[] __initdata = {
+ { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
+ { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { -1, },
+};
+
+struct au1xxx_irqmap au1500_irqmap[] __initdata = {
+ { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
+ { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { -1, },
+};
+
+struct au1xxx_irqmap au1100_irqmap[] __initdata = {
+ { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
+ { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { -1, },
+};
+
+struct au1xxx_irqmap au1550_irqmap[] __initdata = {
+ { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
+ { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { -1, },
+};
+
+struct au1xxx_irqmap au1200_irqmap[] __initdata = {
+ { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { -1, },
+};
+
+
+static void au1x_ic0_unmask(struct irq_data *d)
+{
+ unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
+
+ __raw_writel(1 << bit, base + IC_MASKSET);
+ __raw_writel(1 << bit, base + IC_WAKESET);
+ wmb();
+}
+
+static void au1x_ic1_unmask(struct irq_data *d)
+{
+ unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
+
+ __raw_writel(1 << bit, base + IC_MASKSET);
+ __raw_writel(1 << bit, base + IC_WAKESET);
+
+/* very hacky. does the pb1000 cpld auto-disable this int?
+ * nowhere in the current kernel sources is it disabled. --mlau
+ */
+#if defined(CONFIG_MIPS_PB1000)
+ if (d->irq == AU1000_GPIO15_INT)
+ __raw_writel(0x4000, (void __iomem *)PB1000_MDR); /* enable int */
+#endif
+ wmb();
+}
+
+static void au1x_ic0_mask(struct irq_data *d)
+{
+ unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
+
+ __raw_writel(1 << bit, base + IC_MASKCLR);
+ __raw_writel(1 << bit, base + IC_WAKECLR);
+ wmb();
+}
+
+static void au1x_ic1_mask(struct irq_data *d)
+{
+ unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
+
+ __raw_writel(1 << bit, base + IC_MASKCLR);
+ __raw_writel(1 << bit, base + IC_WAKECLR);
+ wmb();
+}
+
+static void au1x_ic0_ack(struct irq_data *d)
+{
+ unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
+
+ /*
+ * This may assume that we don't get interrupts from
+ * both edges at once, or if we do, that we don't care.
+ */
+ __raw_writel(1 << bit, base + IC_FALLINGCLR);
+ __raw_writel(1 << bit, base + IC_RISINGCLR);
+ wmb();
+}
+
+static void au1x_ic1_ack(struct irq_data *d)
+{
+ unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
+
+ /*
+ * This may assume that we don't get interrupts from
+ * both edges at once, or if we do, that we don't care.
+ */
+ __raw_writel(1 << bit, base + IC_FALLINGCLR);
+ __raw_writel(1 << bit, base + IC_RISINGCLR);
+ wmb();
+}
+
+static void au1x_ic0_maskack(struct irq_data *d)
+{
+ unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
+
+ __raw_writel(1 << bit, base + IC_WAKECLR);
+ __raw_writel(1 << bit, base + IC_MASKCLR);
+ __raw_writel(1 << bit, base + IC_RISINGCLR);
+ __raw_writel(1 << bit, base + IC_FALLINGCLR);
+ wmb();
+}
+
+static void au1x_ic1_maskack(struct irq_data *d)
+{
+ unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
+
+ __raw_writel(1 << bit, base + IC_WAKECLR);
+ __raw_writel(1 << bit, base + IC_MASKCLR);
+ __raw_writel(1 << bit, base + IC_RISINGCLR);
+ __raw_writel(1 << bit, base + IC_FALLINGCLR);
+ wmb();
+}
+
+static int au1x_ic1_setwake(struct irq_data *d, unsigned int on)
+{
+ int bit = d->irq - AU1000_INTC1_INT_BASE;
+ unsigned long wakemsk, flags;
+
+ /* only GPIO 0-7 can act as wakeup source. Fortunately these
+ * are wired up identically on all supported variants.
+ */
+ if ((bit < 0) || (bit > 7))
+ return -EINVAL;
+
+ local_irq_save(flags);
+ wakemsk = __raw_readl((void __iomem *)SYS_WAKEMSK);
+ if (on)
+ wakemsk |= 1 << bit;
+ else
+ wakemsk &= ~(1 << bit);
+ __raw_writel(wakemsk, (void __iomem *)SYS_WAKEMSK);
+ wmb();
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+/*
+ * irq_chips for both ICs; this way the mask handlers can be
+ * as short as possible.
+ */
+static struct irq_chip au1x_ic0_chip = {
+ .name = "Alchemy-IC0",
+ .irq_ack = au1x_ic0_ack,
+ .irq_mask = au1x_ic0_mask,
+ .irq_mask_ack = au1x_ic0_maskack,
+ .irq_unmask = au1x_ic0_unmask,
+ .irq_set_type = au1x_ic_settype,
+};
+
+static struct irq_chip au1x_ic1_chip = {
+ .name = "Alchemy-IC1",
+ .irq_ack = au1x_ic1_ack,
+ .irq_mask = au1x_ic1_mask,
+ .irq_mask_ack = au1x_ic1_maskack,
+ .irq_unmask = au1x_ic1_unmask,
+ .irq_set_type = au1x_ic_settype,
+ .irq_set_wake = au1x_ic1_setwake,
+};
+
+static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
+{
+ struct irq_chip *chip;
+ unsigned int bit, irq = d->irq;
+ irq_flow_handler_t handler = NULL;
+ unsigned char *name = NULL;
+ void __iomem *base;
+ int ret;
+
+ if (irq >= AU1000_INTC1_INT_BASE) {
+ bit = irq - AU1000_INTC1_INT_BASE;
+ chip = &au1x_ic1_chip;
+ base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
+ } else {
+ bit = irq - AU1000_INTC0_INT_BASE;
+ chip = &au1x_ic0_chip;
+ base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
+ }
+
+ if (bit > 31)
+ return -EINVAL;
+
+ ret = 0;
+
+ switch (flow_type) { /* cfgregs 2:1:0 */
+ case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */
+ __raw_writel(1 << bit, base + IC_CFG2CLR);
+ __raw_writel(1 << bit, base + IC_CFG1CLR);
+ __raw_writel(1 << bit, base + IC_CFG0SET);
+ handler = handle_edge_irq;
+ name = "riseedge";
+ break;
+ case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */
+ __raw_writel(1 << bit, base + IC_CFG2CLR);
+ __raw_writel(1 << bit, base + IC_CFG1SET);
+ __raw_writel(1 << bit, base + IC_CFG0CLR);
+ handler = handle_edge_irq;
+ name = "falledge";
+ break;
+ case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */
+ __raw_writel(1 << bit, base + IC_CFG2CLR);
+ __raw_writel(1 << bit, base + IC_CFG1SET);
+ __raw_writel(1 << bit, base + IC_CFG0SET);
+ handler = handle_edge_irq;
+ name = "bothedge";
+ break;
+ case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */
+ __raw_writel(1 << bit, base + IC_CFG2SET);
+ __raw_writel(1 << bit, base + IC_CFG1CLR);
+ __raw_writel(1 << bit, base + IC_CFG0SET);
+ handler = handle_level_irq;
+ name = "hilevel";
+ break;
+ case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */
+ __raw_writel(1 << bit, base + IC_CFG2SET);
+ __raw_writel(1 << bit, base + IC_CFG1SET);
+ __raw_writel(1 << bit, base + IC_CFG0CLR);
+ handler = handle_level_irq;
+ name = "lowlevel";
+ break;
+ case IRQ_TYPE_NONE: /* 0:0:0 */
+ __raw_writel(1 << bit, base + IC_CFG2CLR);
+ __raw_writel(1 << bit, base + IC_CFG1CLR);
+ __raw_writel(1 << bit, base + IC_CFG0CLR);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ __irq_set_chip_handler_name_locked(d->irq, chip, handler, name);
+
+ wmb();
+
+ return ret;
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause();
+ unsigned long s, off;
+
+ if (pending & CAUSEF_IP7) {
+ off = MIPS_CPU_IRQ_BASE + 7;
+ goto handle;
+ } else if (pending & CAUSEF_IP2) {
+ s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT;
+ off = AU1000_INTC0_INT_BASE;
+ } else if (pending & CAUSEF_IP3) {
+ s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT;
+ off = AU1000_INTC0_INT_BASE;
+ } else if (pending & CAUSEF_IP4) {
+ s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT;
+ off = AU1000_INTC1_INT_BASE;
+ } else if (pending & CAUSEF_IP5) {
+ s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT;
+ off = AU1000_INTC1_INT_BASE;
+ } else
+ goto spurious;
+
+ s = __raw_readl((void __iomem *)s);
+ if (unlikely(!s)) {
+spurious:
+ spurious_interrupt();
+ return;
+ }
+ off += __ffs(s);
+handle:
+ do_IRQ(off);
+}
+
+
+static inline void ic_init(void __iomem *base)
+{
+ /* initialize interrupt controller to a safe state */
+ __raw_writel(0xffffffff, base + IC_CFG0CLR);
+ __raw_writel(0xffffffff, base + IC_CFG1CLR);
+ __raw_writel(0xffffffff, base + IC_CFG2CLR);
+ __raw_writel(0xffffffff, base + IC_MASKCLR);
+ __raw_writel(0xffffffff, base + IC_ASSIGNCLR);
+ __raw_writel(0xffffffff, base + IC_WAKECLR);
+ __raw_writel(0xffffffff, base + IC_SRCSET);
+ __raw_writel(0xffffffff, base + IC_FALLINGCLR);
+ __raw_writel(0xffffffff, base + IC_RISINGCLR);
+ __raw_writel(0x00000000, base + IC_TESTBIT);
+ wmb();
+}
+
+static void __init au1000_init_irq(struct au1xxx_irqmap *map)
+{
+ unsigned int bit, irq_nr;
+ void __iomem *base;
+
+ ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR));
+ ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR));
+ mips_cpu_irq_init();
+
+ /* register all 64 possible IC0+IC1 irq sources as type "none".
+ * Use set_irq_type() to set edge/level behaviour at runtime.
+ */
+ for (irq_nr = AU1000_INTC0_INT_BASE;
+ (irq_nr < AU1000_INTC0_INT_BASE + 32); irq_nr++)
+ au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
+
+ for (irq_nr = AU1000_INTC1_INT_BASE;
+ (irq_nr < AU1000_INTC1_INT_BASE + 32); irq_nr++)
+ au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
+
+ /*
+ * Initialize IC0, which is fixed per processor.
+ */
+ while (map->im_irq != -1) {
+ irq_nr = map->im_irq;
+
+ if (irq_nr >= AU1000_INTC1_INT_BASE) {
+ bit = irq_nr - AU1000_INTC1_INT_BASE;
+ base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
+ } else {
+ bit = irq_nr - AU1000_INTC0_INT_BASE;
+ base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
+ }
+ if (map->im_request)
+ __raw_writel(1 << bit, base + IC_ASSIGNSET);
+
+ au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type);
+ ++map;
+ }
+
+ set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
+}
+
+void __init arch_init_irq(void)
+{
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1000:
+ au1000_init_irq(au1000_irqmap);
+ break;
+ case ALCHEMY_CPU_AU1500:
+ au1000_init_irq(au1500_irqmap);
+ break;
+ case ALCHEMY_CPU_AU1100:
+ au1000_init_irq(au1100_irqmap);
+ break;
+ case ALCHEMY_CPU_AU1550:
+ au1000_init_irq(au1550_irqmap);
+ break;
+ case ALCHEMY_CPU_AU1200:
+ au1000_init_irq(au1200_irqmap);
+ break;
+ }
+}
+
+
+static unsigned long alchemy_ic_pmdata[7 * 2];
+
+static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
+{
+ d[0] = __raw_readl(base + IC_CFG0RD);
+ d[1] = __raw_readl(base + IC_CFG1RD);
+ d[2] = __raw_readl(base + IC_CFG2RD);
+ d[3] = __raw_readl(base + IC_SRCRD);
+ d[4] = __raw_readl(base + IC_ASSIGNRD);
+ d[5] = __raw_readl(base + IC_WAKERD);
+ d[6] = __raw_readl(base + IC_MASKRD);
+ ic_init(base); /* shut it up too while at it */
+}
+
+static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
+{
+ ic_init(base);
+
+ __raw_writel(d[0], base + IC_CFG0SET);
+ __raw_writel(d[1], base + IC_CFG1SET);
+ __raw_writel(d[2], base + IC_CFG2SET);
+ __raw_writel(d[3], base + IC_SRCSET);
+ __raw_writel(d[4], base + IC_ASSIGNSET);
+ __raw_writel(d[5], base + IC_WAKESET);
+ wmb();
+
+ __raw_writel(d[6], base + IC_MASKSET);
+ wmb();
+}
+
+static int alchemy_ic_suspend(void)
+{
+ alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
+ alchemy_ic_pmdata);
+ alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
+ &alchemy_ic_pmdata[7]);
+ return 0;
+}
+
+static void alchemy_ic_resume(void)
+{
+ alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
+ &alchemy_ic_pmdata[7]);
+ alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
+ alchemy_ic_pmdata);
+}
+
+static struct syscore_ops alchemy_ic_syscore_ops = {
+ .suspend = alchemy_ic_suspend,
+ .resume = alchemy_ic_resume,
+};
+
+static int __init alchemy_ic_pm_init(void)
+{
+ register_syscore_ops(&alchemy_ic_syscore_ops);
+ return 0;
+}
+device_initcall(alchemy_ic_pm_init);
diff --git a/arch/mips/alchemy/common/pci.c b/arch/mips/alchemy/common/pci.c
new file mode 100644
index 00000000..7866cf50
--- /dev/null
+++ b/arch/mips/alchemy/common/pci.c
@@ -0,0 +1,104 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Alchemy/AMD Au1x00 PCI support.
+ *
+ * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Support for all devices (greater than 16) added by David Gathright.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+/* TBD */
+static struct resource pci_io_resource = {
+ .start = PCI_IO_START,
+ .end = PCI_IO_END,
+ .name = "PCI IO space",
+ .flags = IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+ .start = PCI_MEM_START,
+ .end = PCI_MEM_END,
+ .name = "PCI memory space",
+ .flags = IORESOURCE_MEM
+};
+
+extern struct pci_ops au1x_pci_ops;
+
+static struct pci_controller au1x_controller = {
+ .pci_ops = &au1x_pci_ops,
+ .io_resource = &pci_io_resource,
+ .mem_resource = &pci_mem_resource,
+};
+
+#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+static unsigned long virt_io_addr;
+#endif
+
+static int __init au1x_pci_setup(void)
+{
+ extern void au1x_pci_cfg_init(void);
+
+#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+ virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START,
+ Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1);
+
+ if (!virt_io_addr) {
+ printk(KERN_ERR "Unable to ioremap pci space\n");
+ return 1;
+ }
+ au1x_controller.io_map_base = virt_io_addr;
+
+#ifdef CONFIG_DMA_NONCOHERENT
+ {
+ /*
+ * Set the NC bit in controller for Au1500 pre-AC silicon
+ */
+ u32 prid = read_c0_prid();
+
+ if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
+ au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
+ Au1500_PCI_CFG);
+ printk(KERN_INFO "Non-coherent PCI accesses enabled\n");
+ }
+ }
+#endif
+
+ set_io_port_base(virt_io_addr);
+#endif
+
+ au1x_pci_cfg_init();
+
+ register_pci_controller(&au1x_controller);
+ return 0;
+}
+
+arch_initcall(au1x_pci_setup);
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
new file mode 100644
index 00000000..3b2c18b1
--- /dev/null
+++ b/arch/mips/alchemy/common/platform.c
@@ -0,0 +1,556 @@
+/*
+ * Platform device support for Au1x00 SoCs.
+ *
+ * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
+ *
+ * (C) Copyright Embedded Alley Solutions, Inc 2005
+ * Author: Pantelis Antoniou <pantelis@embeddedalley.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/slab.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
+#include <prom.h>
+
+static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
+ unsigned int old_state)
+{
+#ifdef CONFIG_SERIAL_8250
+ switch (state) {
+ case 0:
+ alchemy_uart_enable(CPHYSADDR(port->membase));
+ serial8250_do_pm(port, state, old_state);
+ break;
+ case 3: /* power off */
+ serial8250_do_pm(port, state, old_state);
+ alchemy_uart_disable(CPHYSADDR(port->membase));
+ break;
+ default:
+ serial8250_do_pm(port, state, old_state);
+ break;
+ }
+#endif
+}
+
+#define PORT(_base, _irq) \
+ { \
+ .mapbase = _base, \
+ .irq = _irq, \
+ .regshift = 2, \
+ .iotype = UPIO_AU, \
+ .flags = UPF_SKIP_TEST | UPF_IOREMAP | \
+ UPF_FIXED_TYPE, \
+ .type = PORT_16550A, \
+ .pm = alchemy_8250_pm, \
+ }
+
+static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
+ [ALCHEMY_CPU_AU1000] = {
+ PORT(AU1000_UART0_PHYS_ADDR, AU1000_UART0_INT),
+ PORT(AU1000_UART1_PHYS_ADDR, AU1000_UART1_INT),
+ PORT(AU1000_UART2_PHYS_ADDR, AU1000_UART2_INT),
+ PORT(AU1000_UART3_PHYS_ADDR, AU1000_UART3_INT),
+ },
+ [ALCHEMY_CPU_AU1500] = {
+ PORT(AU1000_UART0_PHYS_ADDR, AU1500_UART0_INT),
+ PORT(AU1000_UART3_PHYS_ADDR, AU1500_UART3_INT),
+ },
+ [ALCHEMY_CPU_AU1100] = {
+ PORT(AU1000_UART0_PHYS_ADDR, AU1100_UART0_INT),
+ PORT(AU1000_UART1_PHYS_ADDR, AU1100_UART1_INT),
+ PORT(AU1000_UART3_PHYS_ADDR, AU1100_UART3_INT),
+ },
+ [ALCHEMY_CPU_AU1550] = {
+ PORT(AU1000_UART0_PHYS_ADDR, AU1550_UART0_INT),
+ PORT(AU1000_UART1_PHYS_ADDR, AU1550_UART1_INT),
+ PORT(AU1000_UART3_PHYS_ADDR, AU1550_UART3_INT),
+ },
+ [ALCHEMY_CPU_AU1200] = {
+ PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT),
+ PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT),
+ },
+};
+
+static struct platform_device au1xx0_uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_AU1X00,
+};
+
+static void __init alchemy_setup_uarts(int ctype)
+{
+ unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
+ int s = sizeof(struct plat_serial8250_port);
+ int c = alchemy_get_uarts(ctype);
+ struct plat_serial8250_port *ports;
+
+ ports = kzalloc(s * (c + 1), GFP_KERNEL);
+ if (!ports) {
+ printk(KERN_INFO "Alchemy: no memory for UART data\n");
+ return;
+ }
+ memcpy(ports, au1x00_uart_data[ctype], s * c);
+ au1xx0_uart_device.dev.platform_data = ports;
+
+ /* Fill up uartclk. */
+ for (s = 0; s < c; s++)
+ ports[s].uartclk = uartclk;
+ if (platform_device_register(&au1xx0_uart_device))
+ printk(KERN_INFO "Alchemy: failed to register UARTs\n");
+}
+
+/* OHCI (USB full speed host controller) */
+static struct resource au1xxx_usb_ohci_resources[] = {
+ [0] = {
+ .start = USB_OHCI_BASE,
+ .end = USB_OHCI_BASE + USB_OHCI_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = FOR_PLATFORM_C_USB_HOST_INT,
+ .end = FOR_PLATFORM_C_USB_HOST_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device au1xxx_usb_ohci_device = {
+ .name = "au1xxx-ohci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources),
+ .resource = au1xxx_usb_ohci_resources,
+};
+
+/*** AU1100 LCD controller ***/
+
+#ifdef CONFIG_FB_AU1100
+static struct resource au1100_lcd_resources[] = {
+ [0] = {
+ .start = LCD_PHYS_ADDR,
+ .end = LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1100_LCD_INT,
+ .end = AU1100_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device au1100_lcd_device = {
+ .name = "au1100-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1100_lcd_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(au1100_lcd_resources),
+ .resource = au1100_lcd_resources,
+};
+#endif
+
+#ifdef CONFIG_SOC_AU1200
+/* EHCI (USB high speed host controller) */
+static struct resource au1xxx_usb_ehci_resources[] = {
+ [0] = {
+ .start = USB_EHCI_BASE,
+ .end = USB_EHCI_BASE + USB_EHCI_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_USB_INT,
+ .end = AU1200_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device au1xxx_usb_ehci_device = {
+ .name = "au1xxx-ehci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources),
+ .resource = au1xxx_usb_ehci_resources,
+};
+
+/* Au1200 UDC (USB gadget controller) */
+static struct resource au1xxx_usb_gdt_resources[] = {
+ [0] = {
+ .start = USB_UDC_BASE,
+ .end = USB_UDC_BASE + USB_UDC_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_USB_INT,
+ .end = AU1200_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 udc_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device au1xxx_usb_gdt_device = {
+ .name = "au1xxx-udc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources),
+ .resource = au1xxx_usb_gdt_resources,
+};
+
+/* Au1200 UOC (USB OTG controller) */
+static struct resource au1xxx_usb_otg_resources[] = {
+ [0] = {
+ .start = USB_UOC_BASE,
+ .end = USB_UOC_BASE + USB_UOC_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_USB_INT,
+ .end = AU1200_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 uoc_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device au1xxx_usb_otg_device = {
+ .name = "au1xxx-uoc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &uoc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources),
+ .resource = au1xxx_usb_otg_resources,
+};
+
+static struct resource au1200_lcd_resources[] = {
+ [0] = {
+ .start = LCD_PHYS_ADDR,
+ .end = LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_LCD_INT,
+ .end = AU1200_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device au1200_lcd_device = {
+ .name = "au1200-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1200_lcd_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(au1200_lcd_resources),
+ .resource = au1200_lcd_resources,
+};
+
+static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
+
+extern struct au1xmmc_platform_data au1xmmc_platdata[2];
+
+static struct resource au1200_mmc0_resources[] = {
+ [0] = {
+ .start = AU1100_SD0_PHYS_ADDR,
+ .end = AU1100_SD0_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_SD_INT,
+ .end = AU1200_SD_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DSCR_CMD0_SDMS_TX0,
+ .end = DSCR_CMD0_SDMS_TX0,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DSCR_CMD0_SDMS_RX0,
+ .end = DSCR_CMD0_SDMS_RX0,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+static struct platform_device au1200_mmc0_device = {
+ .name = "au1xxx-mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1xxx_mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &au1xmmc_platdata[0],
+ },
+ .num_resources = ARRAY_SIZE(au1200_mmc0_resources),
+ .resource = au1200_mmc0_resources,
+};
+
+#ifndef CONFIG_MIPS_DB1200
+static struct resource au1200_mmc1_resources[] = {
+ [0] = {
+ .start = AU1100_SD1_PHYS_ADDR,
+ .end = AU1100_SD1_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_SD_INT,
+ .end = AU1200_SD_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DSCR_CMD0_SDMS_TX1,
+ .end = DSCR_CMD0_SDMS_TX1,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DSCR_CMD0_SDMS_RX1,
+ .end = DSCR_CMD0_SDMS_RX1,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+static struct platform_device au1200_mmc1_device = {
+ .name = "au1xxx-mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &au1xxx_mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &au1xmmc_platdata[1],
+ },
+ .num_resources = ARRAY_SIZE(au1200_mmc1_resources),
+ .resource = au1200_mmc1_resources,
+};
+#endif /* #ifndef CONFIG_MIPS_DB1200 */
+#endif /* #ifdef CONFIG_SOC_AU1200 */
+
+/* All Alchemy demoboards with I2C have this #define in their headers */
+#ifdef SMBUS_PSC_BASE
+static struct resource pbdb_smbus_resources[] = {
+ {
+ .start = CPHYSADDR(SMBUS_PSC_BASE),
+ .end = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff),
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device pbdb_smbus_device = {
+ .name = "au1xpsc_smbus",
+ .id = 0, /* bus number */
+ .num_resources = ARRAY_SIZE(pbdb_smbus_resources),
+ .resource = pbdb_smbus_resources,
+};
+#endif
+
+/* Macro to help defining the Ethernet MAC resources */
+#define MAC_RES_COUNT 3 /* MAC regs base, MAC enable reg, MAC INT */
+#define MAC_RES(_base, _enable, _irq) \
+ { \
+ .start = _base, \
+ .end = _base + 0xffff, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = _enable, \
+ .end = _enable + 0x3, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = _irq, \
+ .end = _irq, \
+ .flags = IORESOURCE_IRQ \
+ }
+
+static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
+ [ALCHEMY_CPU_AU1000] = {
+ MAC_RES(AU1000_MAC0_PHYS_ADDR,
+ AU1000_MACEN_PHYS_ADDR,
+ AU1000_MAC0_DMA_INT)
+ },
+ [ALCHEMY_CPU_AU1500] = {
+ MAC_RES(AU1500_MAC0_PHYS_ADDR,
+ AU1500_MACEN_PHYS_ADDR,
+ AU1500_MAC0_DMA_INT)
+ },
+ [ALCHEMY_CPU_AU1100] = {
+ MAC_RES(AU1000_MAC0_PHYS_ADDR,
+ AU1000_MACEN_PHYS_ADDR,
+ AU1100_MAC0_DMA_INT)
+ },
+ [ALCHEMY_CPU_AU1550] = {
+ MAC_RES(AU1000_MAC0_PHYS_ADDR,
+ AU1000_MACEN_PHYS_ADDR,
+ AU1550_MAC0_DMA_INT)
+ },
+};
+
+static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
+ .phy1_search_mac0 = 1,
+};
+
+static struct platform_device au1xxx_eth0_device = {
+ .name = "au1000-eth",
+ .id = 0,
+ .num_resources = MAC_RES_COUNT,
+ .dev.platform_data = &au1xxx_eth0_platform_data,
+};
+
+static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
+ [ALCHEMY_CPU_AU1000] = {
+ MAC_RES(AU1000_MAC1_PHYS_ADDR,
+ AU1000_MACEN_PHYS_ADDR + 4,
+ AU1000_MAC1_DMA_INT)
+ },
+ [ALCHEMY_CPU_AU1500] = {
+ MAC_RES(AU1500_MAC1_PHYS_ADDR,
+ AU1500_MACEN_PHYS_ADDR + 4,
+ AU1500_MAC1_DMA_INT)
+ },
+ [ALCHEMY_CPU_AU1550] = {
+ MAC_RES(AU1000_MAC1_PHYS_ADDR,
+ AU1000_MACEN_PHYS_ADDR + 4,
+ AU1550_MAC1_DMA_INT)
+ },
+};
+
+static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
+ .phy1_search_mac0 = 1,
+};
+
+static struct platform_device au1xxx_eth1_device = {
+ .name = "au1000-eth",
+ .id = 1,
+ .num_resources = MAC_RES_COUNT,
+ .dev.platform_data = &au1xxx_eth1_platform_data,
+};
+
+void __init au1xxx_override_eth_cfg(unsigned int port,
+ struct au1000_eth_platform_data *eth_data)
+{
+ if (!eth_data || port > 1)
+ return;
+
+ if (port == 0)
+ memcpy(&au1xxx_eth0_platform_data, eth_data,
+ sizeof(struct au1000_eth_platform_data));
+ else
+ memcpy(&au1xxx_eth1_platform_data, eth_data,
+ sizeof(struct au1000_eth_platform_data));
+}
+
+static void __init alchemy_setup_macs(int ctype)
+{
+ int ret, i;
+ unsigned char ethaddr[6];
+ struct resource *macres;
+
+ /* Handle 1st MAC */
+ if (alchemy_get_macs(ctype) < 1)
+ return;
+
+ macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
+ if (!macres) {
+ printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
+ return;
+ }
+ memcpy(macres, au1xxx_eth0_resources[ctype],
+ sizeof(struct resource) * MAC_RES_COUNT);
+ au1xxx_eth0_device.resource = macres;
+
+ i = prom_get_ethernet_addr(ethaddr);
+ if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
+ memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
+
+ ret = platform_device_register(&au1xxx_eth0_device);
+ if (!ret)
+ printk(KERN_INFO "Alchemy: failed to register MAC0\n");
+
+
+ /* Handle 2nd MAC */
+ if (alchemy_get_macs(ctype) < 2)
+ return;
+
+ macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
+ if (!macres) {
+ printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
+ return;
+ }
+ memcpy(macres, au1xxx_eth1_resources[ctype],
+ sizeof(struct resource) * MAC_RES_COUNT);
+ au1xxx_eth1_device.resource = macres;
+
+ ethaddr[5] += 1; /* next addr for 2nd MAC */
+ if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
+ memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
+
+ /* Register second MAC if enabled in pinfunc */
+ if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) {
+ ret = platform_device_register(&au1xxx_eth1_device);
+ if (ret)
+ printk(KERN_INFO "Alchemy: failed to register MAC1\n");
+ }
+}
+
+static struct platform_device *au1xxx_platform_devices[] __initdata = {
+ &au1xxx_usb_ohci_device,
+#ifdef CONFIG_FB_AU1100
+ &au1100_lcd_device,
+#endif
+#ifdef CONFIG_SOC_AU1200
+ &au1xxx_usb_ehci_device,
+ &au1xxx_usb_gdt_device,
+ &au1xxx_usb_otg_device,
+ &au1200_lcd_device,
+ &au1200_mmc0_device,
+#ifndef CONFIG_MIPS_DB1200
+ &au1200_mmc1_device,
+#endif
+#endif
+#ifdef SMBUS_PSC_BASE
+ &pbdb_smbus_device,
+#endif
+};
+
+static int __init au1xxx_platform_init(void)
+{
+ int err, ctype = alchemy_get_cputype();
+
+ alchemy_setup_uarts(ctype);
+ alchemy_setup_macs(ctype);
+
+ err = platform_add_devices(au1xxx_platform_devices,
+ ARRAY_SIZE(au1xxx_platform_devices));
+ return err;
+}
+
+arch_initcall(au1xxx_platform_init);
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
new file mode 100644
index 00000000..647e518c
--- /dev/null
+++ b/arch/mips/alchemy/common/power.c
@@ -0,0 +1,172 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Au1xx0 Power Management routines.
+ *
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Some of the routines are right out of init/main.c, whose
+ * copyrights apply here.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/sysctl.h>
+#include <linux/jiffies.h>
+
+#include <asm/uaccess.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#ifdef CONFIG_PM
+
+/*
+ * We need to save/restore a bunch of core registers that are
+ * either volatile or reset to some state across a processor sleep.
+ * If reading a register doesn't provide a proper result for a
+ * later restore, we have to provide a function for loading that
+ * register and save a copy.
+ *
+ * We only have to save/restore registers that aren't otherwise
+ * done as part of a driver pm_* function.
+ */
+static unsigned int sleep_usb[2];
+static unsigned int sleep_sys_clocks[5];
+static unsigned int sleep_sys_pinfunc;
+static unsigned int sleep_static_memctlr[4][3];
+
+
+static void save_core_regs(void)
+{
+#ifndef CONFIG_SOC_AU1200
+ /* Shutdown USB host/device. */
+ sleep_usb[0] = au_readl(USB_HOST_CONFIG);
+
+ /* There appears to be some undocumented reset register.... */
+ au_writel(0, 0xb0100004);
+ au_sync();
+ au_writel(0, USB_HOST_CONFIG);
+ au_sync();
+
+ sleep_usb[1] = au_readl(USBD_ENABLE);
+ au_writel(0, USBD_ENABLE);
+ au_sync();
+
+#else /* AU1200 */
+
+ /* enable access to OTG mmio so we can save OTG CAP/MUX.
+ * FIXME: write an OTG driver and move this stuff there!
+ */
+ au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
+ au_sync();
+ sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */
+ sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */
+#endif
+
+ /* Clocks and PLLs. */
+ sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0);
+ sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1);
+ sleep_sys_clocks[2] = au_readl(SYS_CLKSRC);
+ sleep_sys_clocks[3] = au_readl(SYS_CPUPLL);
+ sleep_sys_clocks[4] = au_readl(SYS_AUXPLL);
+
+ /* pin mux config */
+ sleep_sys_pinfunc = au_readl(SYS_PINFUNC);
+
+ /* Save the static memory controller configuration. */
+ sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
+ sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
+ sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
+ sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1);
+ sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1);
+ sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1);
+ sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2);
+ sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2);
+ sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2);
+ sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
+ sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
+ sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
+}
+
+static void restore_core_regs(void)
+{
+ /* restore clock configuration. Writing CPUPLL last will
+ * stall a bit and stabilize other clocks (unless this is
+ * one of those Au1000 with a write-only PLL, where we dont
+ * have a valid value)
+ */
+ au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0);
+ au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1);
+ au_writel(sleep_sys_clocks[2], SYS_CLKSRC);
+ au_writel(sleep_sys_clocks[4], SYS_AUXPLL);
+ if (!au1xxx_cpu_has_pll_wo())
+ au_writel(sleep_sys_clocks[3], SYS_CPUPLL);
+ au_sync();
+
+ au_writel(sleep_sys_pinfunc, SYS_PINFUNC);
+ au_sync();
+
+#ifndef CONFIG_SOC_AU1200
+ au_writel(sleep_usb[0], USB_HOST_CONFIG);
+ au_writel(sleep_usb[1], USBD_ENABLE);
+ au_sync();
+#else
+ /* enable access to OTG memory */
+ au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
+ au_sync();
+
+ /* restore OTG caps and port mux. */
+ au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */
+ au_sync();
+ au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */
+ au_sync();
+#endif
+
+ /* Restore the static memory controller configuration. */
+ au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
+ au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
+ au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
+ au_writel(sleep_static_memctlr[1][0], MEM_STCFG1);
+ au_writel(sleep_static_memctlr[1][1], MEM_STTIME1);
+ au_writel(sleep_static_memctlr[1][2], MEM_STADDR1);
+ au_writel(sleep_static_memctlr[2][0], MEM_STCFG2);
+ au_writel(sleep_static_memctlr[2][1], MEM_STTIME2);
+ au_writel(sleep_static_memctlr[2][2], MEM_STADDR2);
+ au_writel(sleep_static_memctlr[3][0], MEM_STCFG3);
+ au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
+ au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
+}
+
+void au_sleep(void)
+{
+ int cpuid = alchemy_get_cputype();
+ if (cpuid != ALCHEMY_CPU_UNKNOWN) {
+ save_core_regs();
+ if (cpuid <= ALCHEMY_CPU_AU1500)
+ alchemy_sleep_au1000();
+ else if (cpuid <= ALCHEMY_CPU_AU1200)
+ alchemy_sleep_au1550();
+ restore_core_regs();
+ }
+}
+
+#endif /* CONFIG_PM */
diff --git a/arch/mips/alchemy/common/prom.c b/arch/mips/alchemy/common/prom.c
new file mode 100644
index 00000000..53402105
--- /dev/null
+++ b/arch/mips/alchemy/common/prom.c
@@ -0,0 +1,129 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PROM library initialisation code, supports YAMON and U-Boot.
+ *
+ * Copyright 2000-2001, 2006, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+int prom_argc;
+char **prom_argv;
+char **prom_envp;
+
+void __init prom_init_cmdline(void)
+{
+ int i;
+
+ for (i = 1; i < prom_argc; i++) {
+ strlcat(arcs_cmdline, prom_argv[i], COMMAND_LINE_SIZE);
+ if (i < (prom_argc - 1))
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+ }
+}
+
+char *prom_getenv(char *envname)
+{
+ /*
+ * Return a pointer to the given environment variable.
+ * YAMON uses "name", "value" pairs, while U-Boot uses "name=value".
+ */
+
+ char **env = prom_envp;
+ int i = strlen(envname);
+ int yamon = (*env && strchr(*env, '=') == NULL);
+
+ while (*env) {
+ if (yamon) {
+ if (strcmp(envname, *env++) == 0)
+ return *env;
+ } else if (strncmp(envname, *env, i) == 0 && (*env)[i] == '=')
+ return *env + i + 1;
+ env++;
+ }
+
+ return NULL;
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+
+ return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if ((*str == '.') || (*str == ':'))
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= str2hexnum(*str++);
+ ea[i] = num;
+ }
+}
+
+int __init prom_get_ethernet_addr(char *ethernet_addr)
+{
+ char *ethaddr_str;
+
+ /* Check the environment variables first */
+ ethaddr_str = prom_getenv("ethaddr");
+ if (!ethaddr_str) {
+ /* Check command line */
+ ethaddr_str = strstr(arcs_cmdline, "ethaddr=");
+ if (!ethaddr_str)
+ return -1;
+
+ ethaddr_str += strlen("ethaddr=");
+ }
+
+ str2eaddr(ethernet_addr, ethaddr_str);
+
+ return 0;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c
new file mode 100644
index 00000000..1b887c86
--- /dev/null
+++ b/arch/mips/alchemy/common/setup.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2000, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com
+ *
+ * Updates to 2.6, Pete Popov, Embedded Alley Solutions, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+
+#include <asm/mipsregs.h>
+#include <asm/time.h>
+
+#include <au1000.h>
+
+extern void __init board_setup(void);
+extern void set_cpuspec(void);
+
+void __init plat_mem_setup(void)
+{
+ unsigned long est_freq;
+
+ /* determine core clock */
+ est_freq = au1xxx_calc_clock();
+ est_freq += 5000; /* round */
+ est_freq -= est_freq % 10000;
+ printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(),
+ est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
+
+ /* this is faster than wasting cycles trying to approximate it */
+ preset_lpj = (est_freq >> 1) / HZ;
+
+ if (au1xxx_cpu_needs_config_od())
+ /* Various early Au1xx0 errata corrected by this */
+ set_c0_config(1 << 19); /* Set Config[OD] */
+ else
+ /* Clear to obtain best system bus performance */
+ clear_c0_config(1 << 19); /* Clear Config[OD] */
+
+ board_setup(); /* board specific setup */
+
+ /* IO/MEM resources. */
+ set_io_port_base(0);
+ ioport_resource.start = IOPORT_RESOURCE_START;
+ ioport_resource.end = IOPORT_RESOURCE_END;
+ iomem_resource.start = IOMEM_RESOURCE_START;
+ iomem_resource.end = IOMEM_RESOURCE_END;
+}
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI)
+/* This routine should be valid for all Au1x based boards */
+phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ u32 start = (u32)Au1500_PCI_MEM_START;
+ u32 end = (u32)Au1500_PCI_MEM_END;
+
+ /* Don't fixup 36-bit addresses */
+ if ((phys_addr >> 32) != 0)
+ return phys_addr;
+
+ /* Check for PCI memory window */
+ if (phys_addr >= start && (phys_addr + size - 1) <= end)
+ return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START);
+
+ /* default nop */
+ return phys_addr;
+}
+EXPORT_SYMBOL(__fixup_bigphys_addr);
+#endif
diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S
new file mode 100644
index 00000000..77f3c743
--- /dev/null
+++ b/arch/mips/alchemy/common/sleeper.S
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2002 Embedded Edge, LLC
+ * Author: dan@embeddededge.com
+ *
+ * Sleep helper for Au1xxx sleep mode.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+ .extern __flush_cache_all
+
+ .text
+ .set noreorder
+ .set noat
+ .align 5
+
+
+/* preparatory stuff */
+.macro SETUP_SLEEP
+ subu sp, PT_SIZE
+ sw $1, PT_R1(sp)
+ sw $2, PT_R2(sp)
+ sw $3, PT_R3(sp)
+ sw $4, PT_R4(sp)
+ sw $5, PT_R5(sp)
+ sw $6, PT_R6(sp)
+ sw $7, PT_R7(sp)
+ sw $16, PT_R16(sp)
+ sw $17, PT_R17(sp)
+ sw $18, PT_R18(sp)
+ sw $19, PT_R19(sp)
+ sw $20, PT_R20(sp)
+ sw $21, PT_R21(sp)
+ sw $22, PT_R22(sp)
+ sw $23, PT_R23(sp)
+ sw $26, PT_R26(sp)
+ sw $27, PT_R27(sp)
+ sw $28, PT_R28(sp)
+ sw $30, PT_R30(sp)
+ sw $31, PT_R31(sp)
+ mfc0 k0, CP0_STATUS
+ sw k0, 0x20(sp)
+ mfc0 k0, CP0_CONTEXT
+ sw k0, 0x1c(sp)
+ mfc0 k0, CP0_PAGEMASK
+ sw k0, 0x18(sp)
+ mfc0 k0, CP0_CONFIG
+ sw k0, 0x14(sp)
+
+ /* flush caches to make sure context is in memory */
+ la t1, __flush_cache_all
+ lw t0, 0(t1)
+ jalr t0
+ nop
+
+ /* Now set up the scratch registers so the boot rom will
+ * return to this point upon wakeup.
+ * sys_scratch0 : SP
+ * sys_scratch1 : RA
+ */
+ lui t3, 0xb190 /* sys_xxx */
+ sw sp, 0x0018(t3)
+ la k0, alchemy_sleep_wakeup /* resume path */
+ sw k0, 0x001c(t3)
+.endm
+
+.macro DO_SLEEP
+ /* put power supply and processor to sleep */
+ sw zero, 0x0078(t3) /* sys_slppwr */
+ sync
+ sw zero, 0x007c(t3) /* sys_sleep */
+ sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+.endm
+
+/* sleep code for Au1000/Au1100/Au1500 memory controller type */
+LEAF(alchemy_sleep_au1000)
+
+ SETUP_SLEEP
+
+ /* cache following instructions, as memory gets put to sleep */
+ la t0, 1f
+ .set mips3
+ cache 0x14, 0(t0)
+ cache 0x14, 32(t0)
+ cache 0x14, 64(t0)
+ cache 0x14, 96(t0)
+ .set mips0
+
+1: lui a0, 0xb400 /* mem_xxx */
+ sw zero, 0x001c(a0) /* Precharge */
+ sync
+ sw zero, 0x0020(a0) /* Auto Refresh */
+ sync
+ sw zero, 0x0030(a0) /* Sleep */
+ sync
+
+ DO_SLEEP
+
+END(alchemy_sleep_au1000)
+
+/* sleep code for Au1550/Au1200 memory controller type */
+LEAF(alchemy_sleep_au1550)
+
+ SETUP_SLEEP
+
+ /* cache following instructions, as memory gets put to sleep */
+ la t0, 1f
+ .set mips3
+ cache 0x14, 0(t0)
+ cache 0x14, 32(t0)
+ cache 0x14, 64(t0)
+ cache 0x14, 96(t0)
+ .set mips0
+
+1: lui a0, 0xb400 /* mem_xxx */
+ sw zero, 0x08c0(a0) /* Precharge */
+ sync
+ sw zero, 0x08d0(a0) /* Self Refresh */
+ sync
+
+ /* wait for sdram to enter self-refresh mode */
+ lui t0, 0x0100
+2: lw t1, 0x0850(a0) /* mem_sdstat */
+ and t2, t1, t0
+ beq t2, zero, 2b
+ nop
+
+ /* disable SDRAM clocks */
+ lui t0, 0xcfff
+ ori t0, t0, 0xffff
+ lw t1, 0x0840(a0) /* mem_sdconfiga */
+ and t1, t0, t1 /* clear CE[1:0] */
+ sw t1, 0x0840(a0) /* mem_sdconfiga */
+ sync
+
+ DO_SLEEP
+
+END(alchemy_sleep_au1550)
+
+
+ /* This is where we return upon wakeup.
+ * Reload all of the registers and return.
+ */
+LEAF(alchemy_sleep_wakeup)
+ lw k0, 0x20(sp)
+ mtc0 k0, CP0_STATUS
+ lw k0, 0x1c(sp)
+ mtc0 k0, CP0_CONTEXT
+ lw k0, 0x18(sp)
+ mtc0 k0, CP0_PAGEMASK
+ lw k0, 0x14(sp)
+ mtc0 k0, CP0_CONFIG
+
+ /* We need to catch the early Alchemy SOCs with
+ * the write-only Config[OD] bit and set it back to one...
+ */
+ jal au1x00_fixup_config_od
+ nop
+ lw $1, PT_R1(sp)
+ lw $2, PT_R2(sp)
+ lw $3, PT_R3(sp)
+ lw $4, PT_R4(sp)
+ lw $5, PT_R5(sp)
+ lw $6, PT_R6(sp)
+ lw $7, PT_R7(sp)
+ lw $16, PT_R16(sp)
+ lw $17, PT_R17(sp)
+ lw $18, PT_R18(sp)
+ lw $19, PT_R19(sp)
+ lw $20, PT_R20(sp)
+ lw $21, PT_R21(sp)
+ lw $22, PT_R22(sp)
+ lw $23, PT_R23(sp)
+ lw $26, PT_R26(sp)
+ lw $27, PT_R27(sp)
+ lw $28, PT_R28(sp)
+ lw $30, PT_R30(sp)
+ lw $31, PT_R31(sp)
+ jr ra
+ addiu sp, PT_SIZE
+END(alchemy_sleep_wakeup)
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c
new file mode 100644
index 00000000..d5da6adb
--- /dev/null
+++ b/arch/mips/alchemy/common/time.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2008-2009 Manuel Lauss <manuel.lauss@gmail.com>
+ *
+ * Previous incarnations were:
+ * Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com>
+ * Copied and modified Carsten Langgaard's time.c
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Clocksource/event using the 32.768kHz-clocked Counter1 ('RTC' in the
+ * databooks). Firmware/Board init code must enable the counters in the
+ * counter control register, otherwise the CP0 counter clocksource/event
+ * will be installed instead (and use of 'wait' instruction is prohibited).
+ */
+
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/processor.h>
+#include <asm/time.h>
+#include <asm/mach-au1x00/au1000.h>
+
+/* 32kHz clock enabled and detected */
+#define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
+
+static cycle_t au1x_counter1_read(struct clocksource *cs)
+{
+ return au_readl(SYS_RTCREAD);
+}
+
+static struct clocksource au1x_counter1_clocksource = {
+ .name = "alchemy-counter1",
+ .read = au1x_counter1_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .rating = 100,
+};
+
+static int au1x_rtcmatch2_set_next_event(unsigned long delta,
+ struct clock_event_device *cd)
+{
+ delta += au_readl(SYS_RTCREAD);
+ /* wait for register access */
+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M21)
+ ;
+ au_writel(delta, SYS_RTCMATCH2);
+ au_sync();
+
+ return 0;
+}
+
+static void au1x_rtcmatch2_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *cd)
+{
+}
+
+static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = dev_id;
+ cd->event_handler(cd);
+ return IRQ_HANDLED;
+}
+
+static struct clock_event_device au1x_rtcmatch2_clockdev = {
+ .name = "rtcmatch2",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 100,
+ .set_next_event = au1x_rtcmatch2_set_next_event,
+ .set_mode = au1x_rtcmatch2_set_mode,
+ .cpumask = cpu_all_mask,
+};
+
+static struct irqaction au1x_rtcmatch2_irqaction = {
+ .handler = au1x_rtcmatch2_irq,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "timer",
+ .dev_id = &au1x_rtcmatch2_clockdev,
+};
+
+static int __init alchemy_time_init(unsigned int m2int)
+{
+ struct clock_event_device *cd = &au1x_rtcmatch2_clockdev;
+ unsigned long t;
+
+ au1x_rtcmatch2_clockdev.irq = m2int;
+
+ /* Check if firmware (YAMON, ...) has enabled 32kHz and clock
+ * has been detected. If so install the rtcmatch2 clocksource,
+ * otherwise don't bother. Note that both bits being set is by
+ * no means a definite guarantee that the counters actually work
+ * (the 32S bit seems to be stuck set to 1 once a single clock-
+ * edge is detected, hence the timeouts).
+ */
+ if (CNTR_OK != (au_readl(SYS_COUNTER_CNTRL) & CNTR_OK))
+ goto cntr_err;
+
+ /*
+ * setup counter 1 (RTC) to tick at full speed
+ */
+ t = 0xffffff;
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && --t)
+ asm volatile ("nop");
+ if (!t)
+ goto cntr_err;
+
+ au_writel(0, SYS_RTCTRIM); /* 32.768 kHz */
+ au_sync();
+
+ t = 0xffffff;
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t)
+ asm volatile ("nop");
+ if (!t)
+ goto cntr_err;
+ au_writel(0, SYS_RTCWRITE);
+ au_sync();
+
+ t = 0xffffff;
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t)
+ asm volatile ("nop");
+ if (!t)
+ goto cntr_err;
+
+ /* register counter1 clocksource and event device */
+ clocksource_register_hz(&au1x_counter1_clocksource, 32768);
+
+ cd->shift = 32;
+ cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift);
+ cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */
+ clockevents_register_device(cd);
+ setup_irq(m2int, &au1x_rtcmatch2_irqaction);
+
+ printk(KERN_INFO "Alchemy clocksource installed\n");
+
+ return 0;
+
+cntr_err:
+ return -1;
+}
+
+static void __init alchemy_setup_c0timer(void)
+{
+ /*
+ * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this
+ * function is called. Because the Alchemy counters are unusable
+ * the C0 timekeeping code is installed and use of the 'wait'
+ * instruction must be prohibited, which is done most easily by
+ * assigning NULL to cpu_wait.
+ */
+ cpu_wait = NULL;
+ r4k_clockevent_init();
+ init_r4k_clocksource();
+}
+
+static int alchemy_m2inttab[] __initdata = {
+ AU1000_RTC_MATCH2_INT,
+ AU1500_RTC_MATCH2_INT,
+ AU1100_RTC_MATCH2_INT,
+ AU1550_RTC_MATCH2_INT,
+ AU1200_RTC_MATCH2_INT,
+};
+
+void __init plat_time_init(void)
+{
+ int t;
+
+ t = alchemy_get_cputype();
+ if (t == ALCHEMY_CPU_UNKNOWN)
+ alchemy_setup_c0timer();
+ else if (alchemy_time_init(alchemy_m2inttab[t]))
+ alchemy_setup_c0timer();
+}
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
new file mode 100644
index 00000000..826449c8
--- /dev/null
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -0,0 +1,18 @@
+#
+# Alchemy Develboards
+#
+
+obj-y += prom.o bcsr.o platform.o
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_MIPS_PB1000) += pb1000/
+obj-$(CONFIG_MIPS_PB1100) += pb1100/
+obj-$(CONFIG_MIPS_PB1200) += pb1200/
+obj-$(CONFIG_MIPS_PB1500) += pb1500/
+obj-$(CONFIG_MIPS_PB1550) += pb1550/
+obj-$(CONFIG_MIPS_DB1000) += db1x00/
+obj-$(CONFIG_MIPS_DB1100) += db1x00/
+obj-$(CONFIG_MIPS_DB1200) += db1200/
+obj-$(CONFIG_MIPS_DB1500) += db1x00/
+obj-$(CONFIG_MIPS_DB1550) += db1x00/
+obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/
+obj-$(CONFIG_MIPS_MIRAGE) += db1x00/
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
new file mode 100644
index 00000000..596ad00e
--- /dev/null
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -0,0 +1,149 @@
+/*
+ * bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction.
+ *
+ * All Alchemy development boards (except, of course, the weird PB1000)
+ * have a few registers in a CPLD with standardised layout; they mostly
+ * only differ in base address.
+ * All registers are 16bits wide with 32bit spacing.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+static struct bcsr_reg {
+ void __iomem *raddr;
+ spinlock_t lock;
+} bcsr_regs[BCSR_CNT];
+
+static void __iomem *bcsr_virt; /* KSEG1 addr of BCSR base */
+static int bcsr_csc_base; /* linux-irq of first cascaded irq */
+
+void __init bcsr_init(unsigned long bcsr1_phys, unsigned long bcsr2_phys)
+{
+ int i;
+
+ bcsr1_phys = KSEG1ADDR(CPHYSADDR(bcsr1_phys));
+ bcsr2_phys = KSEG1ADDR(CPHYSADDR(bcsr2_phys));
+
+ bcsr_virt = (void __iomem *)bcsr1_phys;
+
+ for (i = 0; i < BCSR_CNT; i++) {
+ if (i >= BCSR_HEXLEDS)
+ bcsr_regs[i].raddr = (void __iomem *)bcsr2_phys +
+ (0x04 * (i - BCSR_HEXLEDS));
+ else
+ bcsr_regs[i].raddr = (void __iomem *)bcsr1_phys +
+ (0x04 * i);
+
+ spin_lock_init(&bcsr_regs[i].lock);
+ }
+}
+
+unsigned short bcsr_read(enum bcsr_id reg)
+{
+ unsigned short r;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
+ r = __raw_readw(bcsr_regs[reg].raddr);
+ spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
+ return r;
+}
+EXPORT_SYMBOL_GPL(bcsr_read);
+
+void bcsr_write(enum bcsr_id reg, unsigned short val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
+ __raw_writew(val, bcsr_regs[reg].raddr);
+ wmb();
+ spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
+}
+EXPORT_SYMBOL_GPL(bcsr_write);
+
+void bcsr_mod(enum bcsr_id reg, unsigned short clr, unsigned short set)
+{
+ unsigned short r;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bcsr_regs[reg].lock, flags);
+ r = __raw_readw(bcsr_regs[reg].raddr);
+ r &= ~clr;
+ r |= set;
+ __raw_writew(r, bcsr_regs[reg].raddr);
+ wmb();
+ spin_unlock_irqrestore(&bcsr_regs[reg].lock, flags);
+}
+EXPORT_SYMBOL_GPL(bcsr_mod);
+
+/*
+ * DB1200/PB1200 CPLD IRQ muxer
+ */
+static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
+{
+ unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
+
+ for ( ; bisr; bisr &= bisr - 1)
+ generic_handle_irq(bcsr_csc_base + __ffs(bisr));
+}
+
+/* NOTE: both the enable and mask bits must be cleared, otherwise the
+ * CPLD generates tons of spurious interrupts (at least on my DB1200).
+ * -- mlau
+ */
+static void bcsr_irq_mask(struct irq_data *d)
+{
+ unsigned short v = 1 << (d->irq - bcsr_csc_base);
+ __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
+ __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
+ wmb();
+}
+
+static void bcsr_irq_maskack(struct irq_data *d)
+{
+ unsigned short v = 1 << (d->irq - bcsr_csc_base);
+ __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
+ __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
+ __raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */
+ wmb();
+}
+
+static void bcsr_irq_unmask(struct irq_data *d)
+{
+ unsigned short v = 1 << (d->irq - bcsr_csc_base);
+ __raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
+ __raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
+ wmb();
+}
+
+static struct irq_chip bcsr_irq_type = {
+ .name = "CPLD",
+ .irq_mask = bcsr_irq_mask,
+ .irq_mask_ack = bcsr_irq_maskack,
+ .irq_unmask = bcsr_irq_unmask,
+};
+
+void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq)
+{
+ unsigned int irq;
+
+ /* mask & disable & ack all */
+ __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTCLR);
+ __raw_writew(0xffff, bcsr_virt + BCSR_REG_MASKCLR);
+ __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSTAT);
+ wmb();
+
+ bcsr_csc_base = csc_start;
+
+ for (irq = csc_start; irq <= csc_end; irq++)
+ irq_set_chip_and_handler_name(irq, &bcsr_irq_type,
+ handle_level_irq, "level");
+
+ irq_set_chained_handler(hook_irq, bcsr_csc_handler);
+}
diff --git a/arch/mips/alchemy/devboards/db1200/Makefile b/arch/mips/alchemy/devboards/db1200/Makefile
new file mode 100644
index 00000000..17840a5e
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1200/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c
new file mode 100644
index 00000000..fbb55935
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1200/platform.c
@@ -0,0 +1,567 @@
+/*
+ * DBAu1200 board platform device registration
+ *
+ * Copyright (C) 2008-2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1550_spi.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/mach-db1x00/db1200.h>
+
+#include "../platform.h"
+
+static struct mtd_partition db1200_spiflash_parts[] = {
+ {
+ .name = "DB1200 SPI flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data db1200_spiflash_data = {
+ .name = "s25fl001",
+ .parts = db1200_spiflash_parts,
+ .nr_parts = ARRAY_SIZE(db1200_spiflash_parts),
+ .type = "m25p10",
+};
+
+static struct spi_board_info db1200_spi_devs[] __initdata = {
+ {
+ /* TI TMP121AIDBVR temp sensor */
+ .modalias = "tmp121",
+ .max_speed_hz = 2000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = 0,
+ },
+ {
+ /* Spansion S25FL001D0FMA SPI flash */
+ .modalias = "m25p80",
+ .max_speed_hz = 50000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = 0,
+ .platform_data = &db1200_spiflash_data,
+ },
+};
+
+static struct i2c_board_info db1200_i2c_devs[] __initdata = {
+ {
+ /* AT24C04-10 I2C eeprom */
+ I2C_BOARD_INFO("24c04", 0x52),
+ },
+ {
+ /* Philips NE1619 temp/voltage sensor (adm1025 drv) */
+ I2C_BOARD_INFO("ne1619", 0x2d),
+ },
+ {
+ /* I2S audio codec WM8731 */
+ I2C_BOARD_INFO("wm8731", 0x1b),
+ },
+};
+
+/**********************************************************************/
+
+static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
+
+ ioaddr &= 0xffffff00;
+
+ if (ctrl & NAND_CLE) {
+ ioaddr += MEM_STNAND_CMD;
+ } else if (ctrl & NAND_ALE) {
+ ioaddr += MEM_STNAND_ADDR;
+ } else {
+ /* assume we want to r/w real data by default */
+ ioaddr += MEM_STNAND_DATA;
+ }
+ this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
+ if (cmd != NAND_CMD_NONE) {
+ __raw_writeb(cmd, this->IO_ADDR_W);
+ wmb();
+ }
+}
+
+static int au1200_nand_device_ready(struct mtd_info *mtd)
+{
+ return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
+}
+
+static const char *db1200_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition db1200_nand_parts[] = {
+ {
+ .name = "NAND FS 0",
+ .offset = 0,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "NAND FS 1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+struct platform_nand_data db1200_nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(db1200_nand_parts),
+ .partitions = db1200_nand_parts,
+ .chip_delay = 20,
+ .part_probe_types = db1200_part_probes,
+ },
+ .ctrl = {
+ .dev_ready = au1200_nand_device_ready,
+ .cmd_ctrl = au1200_nand_cmd_ctrl,
+ },
+};
+
+static struct resource db1200_nand_res[] = {
+ [0] = {
+ .start = DB1200_NAND_PHYS_ADDR,
+ .end = DB1200_NAND_PHYS_ADDR + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device db1200_nand_dev = {
+ .name = "gen_nand",
+ .num_resources = ARRAY_SIZE(db1200_nand_res),
+ .resource = db1200_nand_res,
+ .id = -1,
+ .dev = {
+ .platform_data = &db1200_nand_platdata,
+ }
+};
+
+/**********************************************************************/
+
+static struct smc91x_platdata db1200_eth_data = {
+ .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource db1200_eth_res[] = {
+ [0] = {
+ .start = DB1200_ETH_PHYS_ADDR,
+ .end = DB1200_ETH_PHYS_ADDR + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DB1200_ETH_INT,
+ .end = DB1200_ETH_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device db1200_eth_dev = {
+ .dev = {
+ .platform_data = &db1200_eth_data,
+ },
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(db1200_eth_res),
+ .resource = db1200_eth_res,
+};
+
+/**********************************************************************/
+
+static struct resource db1200_ide_res[] = {
+ [0] = {
+ .start = DB1200_IDE_PHYS_ADDR,
+ .end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DB1200_IDE_INT,
+ .end = DB1200_IDE_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 ide_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device db1200_ide_dev = {
+ .name = "au1200-ide",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ide_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(db1200_ide_res),
+ .resource = db1200_ide_res,
+};
+
+/**********************************************************************/
+
+static struct platform_device db1200_rtc_dev = {
+ .name = "rtc-au1xxx",
+ .id = -1,
+};
+
+/**********************************************************************/
+
+/* SD carddetects: they're supposed to be edge-triggered, but ack
+ * doesn't seem to work (CPLD Rev 2). Instead, the screaming one
+ * is disabled and its counterpart enabled. The 500ms timeout is
+ * because the carddetect isn't debounced in hardware.
+ */
+static irqreturn_t db1200_mmc_cd(int irq, void *ptr)
+{
+ void(*mmc_cd)(struct mmc_host *, unsigned long);
+
+ if (irq == DB1200_SD0_INSERT_INT) {
+ disable_irq_nosync(DB1200_SD0_INSERT_INT);
+ enable_irq(DB1200_SD0_EJECT_INT);
+ } else {
+ disable_irq_nosync(DB1200_SD0_EJECT_INT);
+ enable_irq(DB1200_SD0_INSERT_INT);
+ }
+
+ /* link against CONFIG_MMC=m */
+ mmc_cd = symbol_get(mmc_detect_change);
+ if (mmc_cd) {
+ mmc_cd(ptr, msecs_to_jiffies(500));
+ symbol_put(mmc_detect_change);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int db1200_mmc_cd_setup(void *mmc_host, int en)
+{
+ int ret;
+
+ if (en) {
+ ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
+ IRQF_DISABLED, "sd_insert", mmc_host);
+ if (ret)
+ goto out;
+
+ ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
+ IRQF_DISABLED, "sd_eject", mmc_host);
+ if (ret) {
+ free_irq(DB1200_SD0_INSERT_INT, mmc_host);
+ goto out;
+ }
+
+ if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT)
+ enable_irq(DB1200_SD0_EJECT_INT);
+ else
+ enable_irq(DB1200_SD0_INSERT_INT);
+
+ } else {
+ free_irq(DB1200_SD0_INSERT_INT, mmc_host);
+ free_irq(DB1200_SD0_EJECT_INT, mmc_host);
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+static void db1200_mmc_set_power(void *mmc_host, int state)
+{
+ if (state) {
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
+ msleep(400); /* stabilization time */
+ } else
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
+}
+
+static int db1200_mmc_card_readonly(void *mmc_host)
+{
+ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
+}
+
+static int db1200_mmc_card_inserted(void *mmc_host)
+{
+ return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
+}
+
+static void db1200_mmcled_set(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ if (brightness != LED_OFF)
+ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
+ else
+ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
+}
+
+static struct led_classdev db1200_mmc_led = {
+ .brightness_set = db1200_mmcled_set,
+};
+
+/* needed by arch/mips/alchemy/common/platform.c */
+struct au1xmmc_platform_data au1xmmc_platdata[] = {
+ [0] = {
+ .cd_setup = db1200_mmc_cd_setup,
+ .set_power = db1200_mmc_set_power,
+ .card_inserted = db1200_mmc_card_inserted,
+ .card_readonly = db1200_mmc_card_readonly,
+ .led = &db1200_mmc_led,
+ },
+};
+
+/**********************************************************************/
+
+static struct resource au1200_psc0_res[] = {
+ [0] = {
+ .start = PSC0_PHYS_ADDR,
+ .end = PSC0_PHYS_ADDR + 0x000fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_PSC0_INT,
+ .end = AU1200_PSC0_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DSCR_CMD0_PSC0_TX,
+ .end = DSCR_CMD0_PSC0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DSCR_CMD0_PSC0_RX,
+ .end = DSCR_CMD0_PSC0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1200_i2c_dev = {
+ .name = "au1xpsc_smbus",
+ .id = 0, /* bus number */
+ .num_resources = ARRAY_SIZE(au1200_psc0_res),
+ .resource = au1200_psc0_res,
+};
+
+static void db1200_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol)
+{
+ if (cs)
+ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_SPISEL);
+ else
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_SPISEL, 0);
+}
+
+static struct au1550_spi_info db1200_spi_platdata = {
+ .mainclk_hz = 50000000, /* PSC0 clock */
+ .num_chipselect = 2,
+ .activate_cs = db1200_spi_cs_en,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device db1200_spi_dev = {
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &db1200_spi_platdata,
+ },
+ .name = "au1550-spi",
+ .id = 0, /* bus number */
+ .num_resources = ARRAY_SIZE(au1200_psc0_res),
+ .resource = au1200_psc0_res,
+};
+
+static struct resource au1200_psc1_res[] = {
+ [0] = {
+ .start = PSC1_PHYS_ADDR,
+ .end = PSC1_PHYS_ADDR + 0x000fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_PSC1_INT,
+ .end = AU1200_PSC1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DSCR_CMD0_PSC1_TX,
+ .end = DSCR_CMD0_PSC1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DSCR_CMD0_PSC1_RX,
+ .end = DSCR_CMD0_PSC1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1200_audio_dev = {
+ /* name assigned later based on switch setting */
+ .id = 1, /* PSC ID */
+ .num_resources = ARRAY_SIZE(au1200_psc1_res),
+ .resource = au1200_psc1_res,
+};
+
+static struct platform_device db1200_stac_dev = {
+ .name = "ac97-codec",
+ .id = 1, /* on PSC1 */
+};
+
+static struct platform_device *db1200_devs[] __initdata = {
+ NULL, /* PSC0, selected by S6.8 */
+ &db1200_ide_dev,
+ &db1200_eth_dev,
+ &db1200_rtc_dev,
+ &db1200_nand_dev,
+ &db1200_audio_dev,
+ &db1200_stac_dev,
+};
+
+static int __init db1200_dev_init(void)
+{
+ unsigned long pfc;
+ unsigned short sw;
+ int swapped;
+
+ i2c_register_board_info(0, db1200_i2c_devs,
+ ARRAY_SIZE(db1200_i2c_devs));
+ spi_register_board_info(db1200_spi_devs,
+ ARRAY_SIZE(db1200_i2c_devs));
+
+ /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI)
+ * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
+ */
+
+ /* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however
+ * this pin is claimed by PSC0 (unused though, but pinmux doesn't
+ * allow to free it without crippling the SPI interface).
+ * As a result, in SPI mode, OTG simply won't work (PSC0 uses
+ * it as an input pin which is pulled high on the boards).
+ */
+ pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A;
+
+ /* switch off OTG VBUS supply */
+ gpio_request(215, "otg-vbus");
+ gpio_direction_output(215, 1);
+
+ printk(KERN_INFO "DB1200 device configuration:\n");
+
+ sw = bcsr_read(BCSR_SWITCHES);
+ if (sw & BCSR_SWITCHES_DIP_8) {
+ db1200_devs[0] = &db1200_i2c_dev;
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
+
+ pfc |= (2 << 17); /* GPIO2 block owns GPIO215 */
+
+ printk(KERN_INFO " S6.8 OFF: PSC0 mode I2C\n");
+ printk(KERN_INFO " OTG port VBUS supply available!\n");
+ } else {
+ db1200_devs[0] = &db1200_spi_dev;
+ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC0MUX);
+
+ pfc |= (1 << 17); /* PSC0 owns GPIO215 */
+
+ printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n");
+ printk(KERN_INFO " OTG port VBUS supply disabled\n");
+ }
+ __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
+ wmb();
+
+ /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S!
+ * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S
+ */
+ sw &= BCSR_SWITCHES_DIP_8 | BCSR_SWITCHES_DIP_7;
+ if (sw == BCSR_SWITCHES_DIP_8) {
+ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX);
+ db1200_audio_dev.name = "au1xpsc_i2s";
+ printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n");
+ } else {
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0);
+ db1200_audio_dev.name = "au1xpsc_ac97";
+ printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n");
+ }
+
+ /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
+ __raw_writel(PSC_SEL_CLK_SERCLK,
+ (void __iomem *)KSEG1ADDR(PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+ PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR,
+ PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_IO_PHYS_ADDR,
+ PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ DB1200_PC0_INT,
+ DB1200_PC0_INSERT_INT,
+ /*DB1200_PC0_STSCHG_INT*/0,
+ DB1200_PC0_EJECT_INT,
+ 0);
+
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
+ PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR + 0x004000000,
+ PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
+ PCMCIA_IO_PHYS_ADDR + 0x004000000,
+ PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
+ DB1200_PC1_INT,
+ DB1200_PC1_INSERT_INT,
+ /*DB1200_PC1_STSCHG_INT*/0,
+ DB1200_PC1_EJECT_INT,
+ 1);
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
+ db1x_register_norflash(64 << 20, 2, swapped);
+
+ return platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
+}
+device_initcall(db1200_dev_init);
+
+/* au1200fb calls these: STERBT EINEN TRAGISCHEN TOD!!! */
+int board_au1200fb_panel(void)
+{
+ return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
+}
+
+int board_au1200fb_panel_init(void)
+{
+ /* Apply power */
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+ BCSR_BOARD_LCDBL);
+ return 0;
+}
+
+int board_au1200fb_panel_shutdown(void)
+{
+ /* Remove power */
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+ BCSR_BOARD_LCDBL, 0);
+ return 0;
+}
diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c
new file mode 100644
index 00000000..1dac4f27
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1200/setup.c
@@ -0,0 +1,88 @@
+/*
+ * Alchemy/AMD/RMI DB1200 board setup.
+ *
+ * Licensed under the terms outlined in the file COPYING in the root of
+ * this source archive.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/mach-db1x00/db1200.h>
+
+const char *get_system_type(void)
+{
+ return "Alchemy Db1200";
+}
+
+void __init board_setup(void)
+{
+ unsigned long freq0, clksrc, div, pfc;
+ unsigned short whoami;
+
+ /* Set Config[OD] (disable overlapping bus transaction):
+ * This gets rid of a _lot_ of spurious interrupts (especially
+ * wrt. IDE); but incurs ~10% performance hit in some
+ * cpu-bound applications.
+ */
+ set_c0_config(1 << 19);
+
+ bcsr_init(DB1200_BCSR_PHYS_ADDR,
+ DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
+
+ whoami = bcsr_read(BCSR_WHOAMI);
+ printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d"
+ " Board-ID %d Daughtercard ID %d\n",
+ (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
+
+ /* SMBus/SPI on PSC0, Audio on PSC1 */
+ pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
+ pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
+ pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
+ pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
+ __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
+ wmb();
+
+ /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
+ * CPU clock; all other clock generators off/unused.
+ */
+ div = (get_au1x00_speed() + 25000000) / 50000000;
+ if (div & 1)
+ div++;
+ div = ((div >> 1) - 1) & 0xff;
+
+ freq0 = div << SYS_FC_FRDIV0_BIT;
+ __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
+ wmb();
+ freq0 |= SYS_FC_FE0; /* enable F0 */
+ __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
+ wmb();
+
+ /* psc0_intclk comes 1:1 from F0 */
+ clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
+ __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
+ wmb();
+}
+
+static int __init db1200_arch_init(void)
+{
+ /* GPIO7 is low-level triggered CPLD cascade */
+ irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
+ bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
+
+ /* insert/eject pairs: one of both is always screaming. To avoid
+ * issues they must not be automatically enabled when initially
+ * requested.
+ */
+ irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN);
+ return 0;
+}
+arch_initcall(db1200_arch_init);
diff --git a/arch/mips/alchemy/devboards/db1x00/Makefile b/arch/mips/alchemy/devboards/db1x00/Makefile
new file mode 100644
index 00000000..613c0c0c
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1x00/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright 2000, 2008 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
+#
+
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c
new file mode 100644
index 00000000..5c956fe8
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c
@@ -0,0 +1,255 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Alchemy Db1x00 board setup.
+ *
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+#include <asm/mach-db1x00/db1x00.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/reboot.h>
+
+#include <prom.h>
+
+#ifdef CONFIG_MIPS_DB1500
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT371 */
+ [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
+};
+
+#endif
+
+
+#ifdef CONFIG_MIPS_DB1550
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, AU1550_PCI_INTC, 0xff, 0xff, 0xff }, /* IDSEL 11 - on-board HPT371 */
+ [12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
+ [13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
+};
+#endif
+
+
+#ifdef CONFIG_MIPS_BOSPORUS
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */
+ [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - SN1741 */
+ [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
+};
+
+/*
+ * Micrel/Kendin 5 port switch attached to MAC0,
+ * MAC0 is associated with PHY address 5 (== WAN port)
+ * MAC1 is not associated with any PHY, since it's connected directly
+ * to the switch.
+ * no interrupts are used
+ */
+static struct au1000_eth_platform_data eth0_pdata = {
+ .phy_static_config = 1,
+ .phy_addr = 5,
+};
+
+static void bosporus_power_off(void)
+{
+ while (1)
+ asm volatile (".set mips3 ; wait ; .set mips0");
+}
+
+const char *get_system_type(void)
+{
+ return "Alchemy Bosporus Gateway Reference";
+}
+#endif
+
+
+#ifdef CONFIG_MIPS_MIRAGE
+char irq_tab_alchemy[][5] __initdata = {
+ [11] = { -1, AU1500_PCI_INTD, 0xff, 0xff, 0xff }, /* IDSEL 11 - SMI VGX */
+ [12] = { -1, 0xff, 0xff, AU1500_PCI_INTC, 0xff }, /* IDSEL 12 - PNX1300 */
+ [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 13 - miniPCI */
+};
+
+static void mirage_power_off(void)
+{
+ alchemy_gpio_direction_output(210, 1);
+}
+
+const char *get_system_type(void)
+{
+ return "Alchemy Mirage";
+}
+#endif
+
+
+#if defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
+static void mips_softreset(void)
+{
+ asm volatile ("jr\t%0" : : "r"(0xbfc00000));
+}
+
+#else
+
+const char *get_system_type(void)
+{
+ return "Alchemy Db1x00";
+}
+#endif
+
+
+void __init board_setup(void)
+{
+ unsigned long bcsr1, bcsr2;
+
+ bcsr1 = DB1000_BCSR_PHYS_ADDR;
+ bcsr2 = DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS;
+
+#ifdef CONFIG_MIPS_DB1000
+ printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1500
+ printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1100
+ printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
+#endif
+#ifdef CONFIG_MIPS_BOSPORUS
+ au1xxx_override_eth_cfg(0, &eth0_pdata);
+
+ printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
+#endif
+#ifdef CONFIG_MIPS_MIRAGE
+ printk(KERN_INFO "AMD Alchemy Mirage Board\n");
+#endif
+#ifdef CONFIG_MIPS_DB1550
+ printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
+
+ bcsr1 = DB1550_BCSR_PHYS_ADDR;
+ bcsr2 = DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS;
+#endif
+
+ /* initialize board register space */
+ bcsr_init(bcsr1, bcsr2);
+
+ /* Not valid for Au1550 */
+#if defined(CONFIG_IRDA) && \
+ (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
+ {
+ u32 pin_func;
+
+ /* Set IRFIRSEL instead of GPIO15 */
+ pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
+ au_writel(pin_func, SYS_PINFUNC);
+ /* Power off until the driver is in use */
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
+ BCSR_RESETS_IRDA_MODE_OFF);
+ }
+#endif
+ bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
+
+ /* Enable GPIO[31:0] inputs */
+ alchemy_gpio1_input_enable();
+
+#ifdef CONFIG_MIPS_MIRAGE
+ {
+ u32 pin_func;
+
+ /* GPIO[20] is output */
+ alchemy_gpio_direction_output(20, 0);
+
+ /* Set GPIO[210:208] instead of SSI_0 */
+ pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;
+
+ /* Set GPIO[215:211] for LEDs */
+ pin_func |= 5 << 2;
+
+ /* Set GPIO[214:213] for more LEDs */
+ pin_func |= 5 << 12;
+
+ /* Set GPIO[207:200] instead of PCMCIA/LCD */
+ pin_func |= SYS_PF_LCD | SYS_PF_PC;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ /*
+ * Enable speaker amplifier. This should
+ * be part of the audio driver.
+ */
+ alchemy_gpio_direction_output(209, 1);
+
+ pm_power_off = mirage_power_off;
+ _machine_halt = mirage_power_off;
+ _machine_restart = (void(*)(char *))mips_softreset;
+ }
+#endif
+
+#ifdef CONFIG_MIPS_BOSPORUS
+ pm_power_off = bosporus_power_off;
+ _machine_halt = bosporus_power_off;
+ _machine_restart = (void(*)(char *))mips_softreset;
+#endif
+ au_sync();
+}
+
+static int __init db1x00_init_irq(void)
+{
+#if defined(CONFIG_MIPS_MIRAGE)
+ irq_set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */
+#elif defined(CONFIG_MIPS_DB1550)
+ irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */
+ irq_set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+ irq_set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+ irq_set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+#elif defined(CONFIG_MIPS_DB1500)
+ irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+ irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+ irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+ irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+#elif defined(CONFIG_MIPS_DB1100)
+ irq_set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+ irq_set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+ irq_set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+ irq_set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+#elif defined(CONFIG_MIPS_DB1000)
+ irq_set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+ irq_set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+ irq_set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+ irq_set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+#endif
+ return 0;
+}
+arch_initcall(db1x00_init_irq);
diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c
new file mode 100644
index 00000000..978d5ab3
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1x00/platform.c
@@ -0,0 +1,118 @@
+/*
+ * DBAu1xxx board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include "../platform.h"
+
+/* DB1xxx PCMCIA interrupt sources:
+ * CD0/1 GPIO0/3
+ * STSCHG0/1 GPIO1/4
+ * CARD0/1 GPIO2/5
+ * Db1550: 0/1, 21/22, 3/5
+ */
+
+#define DB1XXX_HAS_PCMCIA
+#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
+
+#if defined(CONFIG_MIPS_DB1000)
+#define DB1XXX_PCMCIA_CD0 AU1000_GPIO0_INT
+#define DB1XXX_PCMCIA_STSCHG0 AU1000_GPIO1_INT
+#define DB1XXX_PCMCIA_CARD0 AU1000_GPIO2_INT
+#define DB1XXX_PCMCIA_CD1 AU1000_GPIO3_INT
+#define DB1XXX_PCMCIA_STSCHG1 AU1000_GPIO4_INT
+#define DB1XXX_PCMCIA_CARD1 AU1000_GPIO5_INT
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#elif defined(CONFIG_MIPS_DB1100)
+#define DB1XXX_PCMCIA_CD0 AU1100_GPIO0_INT
+#define DB1XXX_PCMCIA_STSCHG0 AU1100_GPIO1_INT
+#define DB1XXX_PCMCIA_CARD0 AU1100_GPIO2_INT
+#define DB1XXX_PCMCIA_CD1 AU1100_GPIO3_INT
+#define DB1XXX_PCMCIA_STSCHG1 AU1100_GPIO4_INT
+#define DB1XXX_PCMCIA_CARD1 AU1100_GPIO5_INT
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#elif defined(CONFIG_MIPS_DB1500)
+#define DB1XXX_PCMCIA_CD0 AU1500_GPIO0_INT
+#define DB1XXX_PCMCIA_STSCHG0 AU1500_GPIO1_INT
+#define DB1XXX_PCMCIA_CARD0 AU1500_GPIO2_INT
+#define DB1XXX_PCMCIA_CD1 AU1500_GPIO3_INT
+#define DB1XXX_PCMCIA_STSCHG1 AU1500_GPIO4_INT
+#define DB1XXX_PCMCIA_CARD1 AU1500_GPIO5_INT
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#elif defined(CONFIG_MIPS_DB1550)
+#define DB1XXX_PCMCIA_CD0 AU1550_GPIO0_INT
+#define DB1XXX_PCMCIA_STSCHG0 AU1550_GPIO21_INT
+#define DB1XXX_PCMCIA_CARD0 AU1550_GPIO3_INT
+#define DB1XXX_PCMCIA_CD1 AU1550_GPIO1_INT
+#define DB1XXX_PCMCIA_STSCHG1 AU1550_GPIO22_INT
+#define DB1XXX_PCMCIA_CARD1 AU1550_GPIO5_INT
+#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#else
+/* other board: no PCMCIA */
+#undef DB1XXX_HAS_PCMCIA
+#undef F_SWAPPED
+#define F_SWAPPED 0
+#if defined(CONFIG_MIPS_BOSPORUS)
+#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
+#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+#elif defined(CONFIG_MIPS_MIRAGE)
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+#endif
+
+static int __init db1xxx_dev_init(void)
+{
+#ifdef DB1XXX_HAS_PCMCIA
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+ PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR,
+ PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_IO_PHYS_ADDR,
+ PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ DB1XXX_PCMCIA_CARD0,
+ DB1XXX_PCMCIA_CD0,
+ /*DB1XXX_PCMCIA_STSCHG0*/0,
+ 0,
+ 0);
+
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
+ PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR + 0x004000000,
+ PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
+ PCMCIA_IO_PHYS_ADDR + 0x004000000,
+ PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
+ DB1XXX_PCMCIA_CARD1,
+ DB1XXX_PCMCIA_CD1,
+ /*DB1XXX_PCMCIA_STSCHG1*/0,
+ 0,
+ 1);
+#endif
+ db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
+ return 0;
+}
+device_initcall(db1xxx_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1000/Makefile b/arch/mips/alchemy/devboards/pb1000/Makefile
new file mode 100644
index 00000000..97c6615b
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1000/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright 2000, 2008 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for the Alchemy Semiconductor Pb1000 board.
+#
+
+obj-y := board_setup.o
diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c
new file mode 100644
index 00000000..e64fdcbf
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1000.h>
+#include <asm/reboot.h>
+#include <prom.h>
+
+#include "../platform.h"
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1000";
+}
+
+static void board_reset(char *c)
+{
+ asm volatile ("jr %0" : : "r" (0xbfc00000));
+}
+
+static void board_power_off(void)
+{
+ while (1)
+ asm volatile (
+ " .set mips32 \n"
+ " wait \n"
+ " .set mips0 \n");
+}
+
+void __init board_setup(void)
+{
+ u32 pin_func, static_cfg0;
+ u32 sys_freqctrl, sys_clksrc;
+ u32 prid = read_c0_prid();
+
+ sys_freqctrl = 0;
+ sys_clksrc = 0;
+
+ /* Set AUX clock to 12 MHz * 8 = 96 MHz */
+ au_writel(8, SYS_AUXPLL);
+ alchemy_gpio1_input_enable();
+ udelay(100);
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* Zero and disable FREQ2 */
+ sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ sys_freqctrl &= ~0xFFF00000;
+ au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+ /* Zero and disable USBH/USBD clocks */
+ sys_clksrc = au_readl(SYS_CLKSRC);
+ sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+ SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
+ au_writel(sys_clksrc, SYS_CLKSRC);
+
+ sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ sys_freqctrl &= ~0xFFF00000;
+
+ sys_clksrc = au_readl(SYS_CLKSRC);
+ sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+ SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
+
+ switch (prid & 0x000000FF) {
+ case 0x00: /* DA */
+ case 0x01: /* HA */
+ case 0x02: /* HB */
+ /* CPU core freq to 48 MHz to slow it way down... */
+ au_writel(4, SYS_CPUPLL);
+
+ /*
+ * Setup 48 MHz FREQ2 from CPUPLL for USB Host
+ * FRDIV2 = 3 -> div by 8 of 384 MHz -> 48 MHz
+ */
+ sys_freqctrl |= (3 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2;
+ au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+ /* CPU core freq to 384 MHz */
+ au_writel(0x20, SYS_CPUPLL);
+
+ printk(KERN_INFO "Au1000: 48 MHz OHCI workaround enabled\n");
+ break;
+
+ default: /* HC and newer */
+ /* FREQ2 = aux / 2 = 48 MHz */
+ sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
+ SYS_FC_FE2 | SYS_FC_FS2;
+ au_writel(sys_freqctrl, SYS_FREQCTRL0);
+ break;
+ }
+
+ /*
+ * Route 48 MHz FREQ2 into USB Host and/or Device
+ */
+ sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
+ au_writel(sys_clksrc, SYS_CLKSRC);
+
+ /* Configure pins GPIO[14:9] as GPIO */
+ pin_func = au_readl(SYS_PINFUNC) & ~(SYS_PF_UR3 | SYS_PF_USB);
+
+ /* 2nd USB port is USB host */
+ pin_func |= SYS_PF_USB;
+
+ au_writel(pin_func, SYS_PINFUNC);
+
+ alchemy_gpio_direction_input(11);
+ alchemy_gpio_direction_input(13);
+ alchemy_gpio_direction_output(4, 0);
+ alchemy_gpio_direction_output(5, 0);
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+
+ /* Make GPIO 15 an input (for interrupt line) */
+ pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_IRF;
+ /* We don't need I2S, so make it available for GPIO[31:29] */
+ pin_func |= SYS_PF_I2S;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ alchemy_gpio_direction_input(15);
+
+ static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00;
+ au_writel(static_cfg0, MEM_STCFG0);
+
+ /* configure RCE2* for LCD */
+ au_writel(0x00000004, MEM_STCFG2);
+
+ /* MEM_STTIME2 */
+ au_writel(0x09000000, MEM_STTIME2);
+
+ /* Set 32-bit base address decoding for RCE2* */
+ au_writel(0x10003ff0, MEM_STADDR2);
+
+ /*
+ * PCI CPLD setup
+ * Expand CE0 to cover PCI
+ */
+ au_writel(0x11803e40, MEM_STADDR1);
+
+ /* Burst visibility on */
+ au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
+
+ au_writel(0x83, MEM_STCFG1); /* ewait enabled, flash timing */
+ au_writel(0x33030a10, MEM_STTIME1); /* slower timing for FPGA */
+
+ /* Setup the static bus controller */
+ au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */
+ au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+ au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+
+ /*
+ * Enable Au1000 BCLK switching - note: sed1356 must not use
+ * its BCLK (Au1000 LCLK) for any timings
+ */
+ switch (prid & 0x000000FF) {
+ case 0x00: /* DA */
+ case 0x01: /* HA */
+ case 0x02: /* HB */
+ break;
+ default: /* HC and newer */
+ /*
+ * Enable sys bus clock divider when IDLE state or no bus
+ * activity.
+ */
+ au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+ break;
+ }
+
+ pm_power_off = board_power_off;
+ _machine_halt = board_power_off;
+ _machine_restart = board_reset;
+}
+
+static int __init pb1000_init_irq(void)
+{
+ irq_set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW);
+ return 0;
+}
+arch_initcall(pb1000_init_irq);
+
+static int __init pb1000_device_init(void)
+{
+ return db1x_register_norflash(8 * 1024 * 1024, 4, 0);
+}
+device_initcall(pb1000_device_init);
diff --git a/arch/mips/alchemy/devboards/pb1100/Makefile b/arch/mips/alchemy/devboards/pb1100/Makefile
new file mode 100644
index 00000000..7e3756c8
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1100/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright 2000, 2001, 2008 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for the Alchemy Semiconductor Pb1100 board.
+#
+
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c
new file mode 100644
index 00000000..d108fd57
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2002, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include <prom.h>
+
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1100";
+}
+
+void __init board_setup(void)
+{
+ volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
+
+ bcsr_init(DB1000_BCSR_PHYS_ADDR,
+ DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
+
+ /* Set AUX clock to 12 MHz * 8 = 96 MHz */
+ au_writel(8, SYS_AUXPLL);
+ alchemy_gpio1_input_enable();
+ udelay(100);
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ {
+ u32 pin_func, sys_freqctrl, sys_clksrc;
+
+ /* Configure pins GPIO[14:9] as GPIO */
+ pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
+
+ /* Zero and disable FREQ2 */
+ sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ sys_freqctrl &= ~0xFFF00000;
+ au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+ /* Zero and disable USBH/USBD/IrDA clock */
+ sys_clksrc = au_readl(SYS_CLKSRC);
+ sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
+ au_writel(sys_clksrc, SYS_CLKSRC);
+
+ sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ sys_freqctrl &= ~0xFFF00000;
+
+ sys_clksrc = au_readl(SYS_CLKSRC);
+ sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
+
+ /* FREQ2 = aux / 2 = 48 MHz */
+ sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
+ SYS_FC_FE2 | SYS_FC_FS2;
+ au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+ /*
+ * Route 48 MHz FREQ2 into USBH/USBD/IrDA
+ */
+ sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MIR_BIT;
+ au_writel(sys_clksrc, SYS_CLKSRC);
+
+ /* Setup the static bus controller */
+ au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */
+ au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
+ au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
+
+ /*
+ * Get USB Functionality pin state (device vs host drive pins).
+ */
+ pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
+ /* 2nd USB port is USB host. */
+ pin_func |= SYS_PF_USB;
+ au_writel(pin_func, SYS_PINFUNC);
+ }
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+
+ /* Enable sys bus clock divider when IDLE state or no bus activity. */
+ au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+
+ /* Enable the RTC if not already enabled. */
+ if (!(readb(base + 0x28) & 0x20)) {
+ writeb(readb(base + 0x28) | 0x20, base + 0x28);
+ au_sync();
+ }
+ /* Put the clock in BCD mode. */
+ if (readb(base + 0x2C) & 0x4) { /* reg B */
+ writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
+ au_sync();
+ }
+}
+
+static int __init pb1100_init_irq(void)
+{
+ irq_set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */
+ irq_set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
+ irq_set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
+ irq_set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
+
+ return 0;
+}
+arch_initcall(pb1100_init_irq);
diff --git a/arch/mips/alchemy/devboards/pb1100/platform.c b/arch/mips/alchemy/devboards/pb1100/platform.c
new file mode 100644
index 00000000..2c8dc297
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1100/platform.c
@@ -0,0 +1,50 @@
+/*
+ * Pb1100 board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "../platform.h"
+
+static int __init pb1100_dev_init(void)
+{
+ int swapped;
+
+ /* PCMCIA. single socket, identical to Pb1500 */
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+ PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR,
+ PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_IO_PHYS_ADDR,
+ PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ AU1100_GPIO11_INT, /* card */
+ AU1100_GPIO9_INT, /* insert */
+ /*AU1100_GPIO10_INT*/0, /* stschg */
+ 0, /* eject */
+ 0); /* id */
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
+ db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
+
+ return 0;
+}
+device_initcall(pb1100_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1200/Makefile b/arch/mips/alchemy/devboards/pb1200/Makefile
new file mode 100644
index 00000000..18c1bd53
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1200/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
+#
+
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c
new file mode 100644
index 00000000..6d06b07c
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1200/board_setup.c
@@ -0,0 +1,174 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Alchemy Pb1200/Db1200 board setup.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#ifdef CONFIG_MIPS_PB1200
+#include <asm/mach-pb1x00/pb1200.h>
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#include <asm/mach-db1x00/db1200.h>
+#define PB1200_INT_BEGIN DB1200_INT_BEGIN
+#define PB1200_INT_END DB1200_INT_END
+#endif
+
+#include <prom.h>
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1200";
+}
+
+void __init board_setup(void)
+{
+ printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
+ bcsr_init(PB1200_BCSR_PHYS_ADDR,
+ PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
+
+#if 0
+ {
+ u32 pin_func;
+
+ /*
+ * Enable PSC1 SYNC for AC97. Normaly done in audio driver,
+ * but it is board specific code, so put it here.
+ */
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+ pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
+ au_sync();
+ }
+#endif
+
+#if defined(CONFIG_I2C_AU1550)
+ {
+ u32 freq0, clksrc;
+ u32 pin_func;
+
+ /* Select SMBus in CPLD */
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
+
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+ pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
+ /* Set GPIOs correctly */
+ pin_func |= 2 << 17;
+ au_writel(pin_func, SYS_PINFUNC);
+ au_sync();
+
+ /* The I2C driver depends on 50 MHz clock */
+ freq0 = au_readl(SYS_FREQCTRL0);
+ au_sync();
+ freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
+ freq0 |= 3 << SYS_FC_FRDIV1_BIT;
+ /* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
+ au_writel(freq0, SYS_FREQCTRL0);
+ au_sync();
+ freq0 |= SYS_FC_FE1;
+ au_writel(freq0, SYS_FREQCTRL0);
+ au_sync();
+
+ clksrc = au_readl(SYS_CLKSRC);
+ au_sync();
+ clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
+ /* Bit 22 is EXTCLK0 for PSC0 */
+ clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
+ au_writel(clksrc, SYS_CLKSRC);
+ au_sync();
+ }
+#endif
+
+ /*
+ * The Pb1200 development board uses external MUX for PSC0 to
+ * support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
+ */
+#ifdef CONFIG_I2C_AU1550
+ bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
+#endif
+ au_sync();
+}
+
+static int __init pb1200_init_irq(void)
+{
+ /* We have a problem with CPLD rev 3. */
+ if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
+ printk(KERN_ERR "updated to latest revision. This software will\n");
+ printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ panic("Game over. Your score is 0.");
+ }
+
+ irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
+ bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT);
+
+ return 0;
+}
+arch_initcall(pb1200_init_irq);
+
+
+int board_au1200fb_panel(void)
+{
+ return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
+}
+
+int board_au1200fb_panel_init(void)
+{
+ /* Apply power */
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+ BCSR_BOARD_LCDBL);
+ /* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
+ return 0;
+}
+
+int board_au1200fb_panel_shutdown(void)
+{
+ /* Remove power */
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+ BCSR_BOARD_LCDBL, 0);
+ /* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
+ return 0;
+}
diff --git a/arch/mips/alchemy/devboards/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c
new file mode 100644
index 00000000..3ef2dcee
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1200/platform.c
@@ -0,0 +1,203 @@
+/*
+ * Pb1200/DBAu1200 board platform device registration
+ *
+ * Copyright (C) 2008 MontaVista Software Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "../platform.h"
+
+static int mmc_activity;
+
+static void pb1200mmc0_set_power(void *mmc_host, int state)
+{
+ if (state)
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
+ else
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
+
+ msleep(1);
+}
+
+static int pb1200mmc0_card_readonly(void *mmc_host)
+{
+ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
+}
+
+static int pb1200mmc0_card_inserted(void *mmc_host)
+{
+ return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
+}
+
+static void pb1200_mmcled_set(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ if (brightness != LED_OFF) {
+ if (++mmc_activity == 1)
+ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
+ } else {
+ if (--mmc_activity == 0)
+ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
+ }
+}
+
+static struct led_classdev pb1200mmc_led = {
+ .brightness_set = pb1200_mmcled_set,
+};
+
+static void pb1200mmc1_set_power(void *mmc_host, int state)
+{
+ if (state)
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
+ else
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
+
+ msleep(1);
+}
+
+static int pb1200mmc1_card_readonly(void *mmc_host)
+{
+ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
+}
+
+static int pb1200mmc1_card_inserted(void *mmc_host)
+{
+ return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
+}
+
+const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
+ [0] = {
+ .set_power = pb1200mmc0_set_power,
+ .card_inserted = pb1200mmc0_card_inserted,
+ .card_readonly = pb1200mmc0_card_readonly,
+ .cd_setup = NULL, /* use poll-timer in driver */
+ .led = &pb1200mmc_led,
+ },
+ [1] = {
+ .set_power = pb1200mmc1_set_power,
+ .card_inserted = pb1200mmc1_card_inserted,
+ .card_readonly = pb1200mmc1_card_readonly,
+ .cd_setup = NULL, /* use poll-timer in driver */
+ .led = &pb1200mmc_led,
+ },
+};
+
+static struct resource ide_resources[] = {
+ [0] = {
+ .start = IDE_PHYS_ADDR,
+ .end = IDE_PHYS_ADDR + IDE_PHYS_LEN - 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = IDE_INT,
+ .end = IDE_INT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static u64 ide_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device ide_device = {
+ .name = "au1200-ide",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ide_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(ide_resources),
+ .resource = ide_resources
+};
+
+static struct smc91x_platdata smc_data = {
+ .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91c111_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = SMC91C111_PHYS_ADDR,
+ .end = SMC91C111_PHYS_ADDR + 0xf,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = SMC91C111_INT,
+ .end = SMC91C111_INT,
+ .flags = IORESOURCE_IRQ
+ },
+};
+
+static struct platform_device smc91c111_device = {
+ .dev = {
+ .platform_data = &smc_data,
+ },
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91c111_resources),
+ .resource = smc91c111_resources
+};
+
+static struct platform_device *board_platform_devices[] __initdata = {
+ &ide_device,
+ &smc91c111_device
+};
+
+static int __init board_register_devices(void)
+{
+ int swapped;
+
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+ PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR,
+ PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_IO_PHYS_ADDR,
+ PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ PB1200_PC0_INT,
+ PB1200_PC0_INSERT_INT,
+ /*PB1200_PC0_STSCHG_INT*/0,
+ PB1200_PC0_EJECT_INT,
+ 0);
+
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
+ PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR + 0x008000000,
+ PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
+ PCMCIA_IO_PHYS_ADDR + 0x008000000,
+ PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
+ PB1200_PC1_INT,
+ PB1200_PC1_INSERT_INT,
+ /*PB1200_PC1_STSCHG_INT*/0,
+ PB1200_PC1_EJECT_INT,
+ 1);
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
+ db1x_register_norflash(128 * 1024 * 1024, 2, swapped);
+
+ return platform_add_devices(board_platform_devices,
+ ARRAY_SIZE(board_platform_devices));
+}
+device_initcall(board_register_devices);
diff --git a/arch/mips/alchemy/devboards/pb1500/Makefile b/arch/mips/alchemy/devboards/pb1500/Makefile
new file mode 100644
index 00000000..e83b151b
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1500/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright 2000, 2001, 2008 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for the Alchemy Semiconductor Pb1500 board.
+#
+
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c
new file mode 100644
index 00000000..3b4fa320
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include <prom.h>
+
+
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT370 */
+ [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
+};
+
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1500";
+}
+
+void __init board_setup(void)
+{
+ u32 pin_func;
+ u32 sys_freqctrl, sys_clksrc;
+
+ bcsr_init(DB1000_BCSR_PHYS_ADDR,
+ DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
+
+ sys_clksrc = sys_freqctrl = pin_func = 0;
+ /* Set AUX clock to 12 MHz * 8 = 96 MHz */
+ au_writel(8, SYS_AUXPLL);
+ alchemy_gpio1_input_enable();
+ udelay(100);
+
+ /* GPIO201 is input for PCMCIA card detect */
+ /* GPIO203 is input for PCMCIA interrupt request */
+ alchemy_gpio_direction_input(201);
+ alchemy_gpio_direction_input(203);
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+
+ /* Zero and disable FREQ2 */
+ sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ sys_freqctrl &= ~0xFFF00000;
+ au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+ /* zero and disable USBH/USBD clocks */
+ sys_clksrc = au_readl(SYS_CLKSRC);
+ sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+ SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
+ au_writel(sys_clksrc, SYS_CLKSRC);
+
+ sys_freqctrl = au_readl(SYS_FREQCTRL0);
+ sys_freqctrl &= ~0xFFF00000;
+
+ sys_clksrc = au_readl(SYS_CLKSRC);
+ sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
+ SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
+
+ /* FREQ2 = aux/2 = 48 MHz */
+ sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2 | SYS_FC_FS2;
+ au_writel(sys_freqctrl, SYS_FREQCTRL0);
+
+ /*
+ * Route 48MHz FREQ2 into USB Host and/or Device
+ */
+ sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
+ au_writel(sys_clksrc, SYS_CLKSRC);
+
+ pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
+ /* 2nd USB port is USB host */
+ pin_func |= SYS_PF_USB;
+ au_writel(pin_func, SYS_PINFUNC);
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+
+#ifdef CONFIG_PCI
+ /* Setup PCI bus controller */
+ au_writel(0, Au1500_PCI_CMEM);
+ au_writel(0x00003fff, Au1500_CFG_BASE);
+#if defined(__MIPSEB__)
+ au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+#else
+ au_writel(0xf, Au1500_PCI_CFG);
+#endif
+ au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
+ au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
+ au_writel(0x02a00356, Au1500_PCI_STATCMD);
+ au_writel(0x00003c04, Au1500_PCI_HDRTYPE);
+ au_writel(0x00000008, Au1500_PCI_MBAR);
+ au_sync();
+#endif
+
+ /* Enable sys bus clock divider when IDLE state or no bus activity. */
+ au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
+
+ /* Enable the RTC if not already enabled */
+ if (!(au_readl(0xac000028) & 0x20)) {
+ printk(KERN_INFO "enabling clock ...\n");
+ au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
+ }
+ /* Put the clock in BCD mode */
+ if (au_readl(0xac00002c) & 0x4) { /* reg B */
+ au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
+ au_sync();
+ }
+}
+
+static int __init pb1500_init_irq(void)
+{
+ irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
+ irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+
+ return 0;
+}
+arch_initcall(pb1500_init_irq);
diff --git a/arch/mips/alchemy/devboards/pb1500/platform.c b/arch/mips/alchemy/devboards/pb1500/platform.c
new file mode 100644
index 00000000..d443bc7a
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1500/platform.c
@@ -0,0 +1,49 @@
+/*
+ * Pb1500 board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "../platform.h"
+
+static int __init pb1500_dev_init(void)
+{
+ int swapped;
+
+ /* PCMCIA. single socket, identical to Pb1500 */
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+ PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR,
+ PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_IO_PHYS_ADDR,
+ PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ AU1500_GPIO11_INT, /* card */
+ AU1500_GPIO9_INT, /* insert */
+ /*AU1500_GPIO10_INT*/0, /* stschg */
+ 0, /* eject */
+ 0); /* id */
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
+ db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
+
+ return 0;
+}
+device_initcall(pb1500_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1550/Makefile b/arch/mips/alchemy/devboards/pb1550/Makefile
new file mode 100644
index 00000000..9661b6ec
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1550/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright 2000, 2008 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for the Alchemy Semiconductor Pb1550 board.
+#
+
+obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c
new file mode 100644
index 00000000..b7902138
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c
@@ -0,0 +1,86 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Alchemy Pb1550 board setup.
+ *
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1550.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/mach-au1x00/gpio.h>
+
+#include <prom.h>
+
+
+char irq_tab_alchemy[][5] __initdata = {
+ [12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
+ [13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
+};
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1550";
+}
+
+void __init board_setup(void)
+{
+ u32 pin_func;
+
+ bcsr_init(PB1550_BCSR_PHYS_ADDR,
+ PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
+
+ alchemy_gpio2_enable();
+
+ /*
+ * Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
+ * but it is board specific code, so put it here.
+ */
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+ pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
+
+ printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
+}
+
+static int __init pb1550_init_irq(void)
+{
+ irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
+
+ /* enable both PCMCIA card irqs in the shared line */
+ alchemy_gpio2_enable_int(201);
+ alchemy_gpio2_enable_int(202);
+
+ return 0;
+}
+arch_initcall(pb1550_init_irq);
diff --git a/arch/mips/alchemy/devboards/pb1550/platform.c b/arch/mips/alchemy/devboards/pb1550/platform.c
new file mode 100644
index 00000000..d7150d0f
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pb1550/platform.c
@@ -0,0 +1,69 @@
+/*
+ * Pb1550 board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-pb1x00/pb1550.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+#include "../platform.h"
+
+static int __init pb1550_dev_init(void)
+{
+ int swapped;
+
+ /* Pb1550, like all others, also has statuschange irqs; however they're
+ * wired up on one of the Au1550's shared GPIO201_205 line, which also
+ * services the PCMCIA card interrupts. So we ignore statuschange and
+ * use the GPIO201_205 exclusively for card interrupts, since a) pcmcia
+ * drivers are used to shared irqs and b) statuschange isn't really use-
+ * ful anyway.
+ */
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR,
+ PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR,
+ PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ PCMCIA_IO_PHYS_ADDR,
+ PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ AU1550_GPIO201_205_INT,
+ AU1550_GPIO0_INT,
+ 0,
+ 0,
+ 0);
+
+ db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
+ PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
+ PCMCIA_MEM_PHYS_ADDR + 0x008000000,
+ PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
+ PCMCIA_IO_PHYS_ADDR + 0x008000000,
+ PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
+ AU1550_GPIO201_205_INT,
+ AU1550_GPIO1_INT,
+ 0,
+ 0,
+ 1);
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
+ db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
+
+ return 0;
+}
+device_initcall(pb1550_dev_init);
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c
new file mode 100644
index 00000000..49a4b324
--- /dev/null
+++ b/arch/mips/alchemy/devboards/platform.c
@@ -0,0 +1,222 @@
+/*
+ * devoard misc stuff.
+ */
+
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+static void db1x_power_off(void)
+{
+ bcsr_write(BCSR_RESETS, 0);
+ bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET);
+}
+
+static void db1x_reset(char *c)
+{
+ bcsr_write(BCSR_RESETS, 0);
+ bcsr_write(BCSR_SYSTEM, 0);
+}
+
+static int __init db1x_poweroff_setup(void)
+{
+ if (!pm_power_off)
+ pm_power_off = db1x_power_off;
+ if (!_machine_halt)
+ _machine_halt = db1x_power_off;
+ if (!_machine_restart)
+ _machine_restart = db1x_reset;
+
+ return 0;
+}
+late_initcall(db1x_poweroff_setup);
+
+/* register a pcmcia socket */
+int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
+ phys_addr_t pcmcia_attr_end,
+ phys_addr_t pcmcia_mem_start,
+ phys_addr_t pcmcia_mem_end,
+ phys_addr_t pcmcia_io_start,
+ phys_addr_t pcmcia_io_end,
+ int card_irq,
+ int cd_irq,
+ int stschg_irq,
+ int eject_irq,
+ int id)
+{
+ int cnt, i, ret;
+ struct resource *sr;
+ struct platform_device *pd;
+
+ cnt = 5;
+ if (eject_irq)
+ cnt++;
+ if (stschg_irq)
+ cnt++;
+
+ sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
+ if (!sr)
+ return -ENOMEM;
+
+ pd = platform_device_alloc("db1xxx_pcmcia", id);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ sr[0].name = "pcmcia-attr";
+ sr[0].flags = IORESOURCE_MEM;
+ sr[0].start = pcmcia_attr_start;
+ sr[0].end = pcmcia_attr_end;
+
+ sr[1].name = "pcmcia-mem";
+ sr[1].flags = IORESOURCE_MEM;
+ sr[1].start = pcmcia_mem_start;
+ sr[1].end = pcmcia_mem_end;
+
+ sr[2].name = "pcmcia-io";
+ sr[2].flags = IORESOURCE_MEM;
+ sr[2].start = pcmcia_io_start;
+ sr[2].end = pcmcia_io_end;
+
+ sr[3].name = "insert";
+ sr[3].flags = IORESOURCE_IRQ;
+ sr[3].start = sr[3].end = cd_irq;
+
+ sr[4].name = "card";
+ sr[4].flags = IORESOURCE_IRQ;
+ sr[4].start = sr[4].end = card_irq;
+
+ i = 5;
+ if (stschg_irq) {
+ sr[i].name = "stschg";
+ sr[i].flags = IORESOURCE_IRQ;
+ sr[i].start = sr[i].end = stschg_irq;
+ i++;
+ }
+ if (eject_irq) {
+ sr[i].name = "eject";
+ sr[i].flags = IORESOURCE_IRQ;
+ sr[i].start = sr[i].end = eject_irq;
+ }
+
+ pd->resource = sr;
+ pd->num_resources = cnt;
+
+ ret = platform_device_add(pd);
+ if (!ret)
+ return 0;
+
+ platform_device_put(pd);
+out:
+ kfree(sr);
+ return ret;
+}
+
+#define YAMON_SIZE 0x00100000
+#define YAMON_ENV_SIZE 0x00040000
+
+int __init db1x_register_norflash(unsigned long size, int width,
+ int swapped)
+{
+ struct physmap_flash_data *pfd;
+ struct platform_device *pd;
+ struct mtd_partition *parts;
+ struct resource *res;
+ int ret, i;
+
+ if (size < (8 * 1024 * 1024))
+ return -EINVAL;
+
+ ret = -ENOMEM;
+ parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL);
+ if (!parts)
+ goto out;
+
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ if (!res)
+ goto out1;
+
+ pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
+ if (!pfd)
+ goto out2;
+
+ pd = platform_device_alloc("physmap-flash", 0);
+ if (!pd)
+ goto out3;
+
+ /* NOR flash ends at 0x20000000, regardless of size */
+ res->start = 0x20000000 - size;
+ res->end = 0x20000000 - 1;
+ res->flags = IORESOURCE_MEM;
+
+ /* partition setup. Most Develboards have a switch which allows
+ * to swap the physical locations of the 2 NOR flash banks.
+ */
+ i = 0;
+ if (!swapped) {
+ /* first NOR chip */
+ parts[i].offset = 0;
+ parts[i].name = "User FS";
+ parts[i].size = size / 2;
+ i++;
+ }
+
+ parts[i].offset = MTDPART_OFS_APPEND;
+ parts[i].name = "User FS 2";
+ parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
+ i++;
+
+ parts[i].offset = MTDPART_OFS_APPEND;
+ parts[i].name = "YAMON";
+ parts[i].size = YAMON_SIZE;
+ parts[i].mask_flags = MTD_WRITEABLE;
+ i++;
+
+ parts[i].offset = MTDPART_OFS_APPEND;
+ parts[i].name = "raw kernel";
+ parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
+ i++;
+
+ parts[i].offset = MTDPART_OFS_APPEND;
+ parts[i].name = "YAMON Env";
+ parts[i].size = YAMON_ENV_SIZE;
+ parts[i].mask_flags = MTD_WRITEABLE;
+ i++;
+
+ if (swapped) {
+ parts[i].offset = MTDPART_OFS_APPEND;
+ parts[i].name = "User FS";
+ parts[i].size = size / 2;
+ i++;
+ }
+
+ pfd->width = width;
+ pfd->parts = parts;
+ pfd->nr_parts = 5;
+
+ pd->dev.platform_data = pfd;
+ pd->resource = res;
+ pd->num_resources = 1;
+
+ ret = platform_device_add(pd);
+ if (!ret)
+ return ret;
+
+ platform_device_put(pd);
+out3:
+ kfree(pfd);
+out2:
+ kfree(res);
+out1:
+ kfree(parts);
+out:
+ return ret;
+}
diff --git a/arch/mips/alchemy/devboards/platform.h b/arch/mips/alchemy/devboards/platform.h
new file mode 100644
index 00000000..5ac055d2
--- /dev/null
+++ b/arch/mips/alchemy/devboards/platform.h
@@ -0,0 +1,21 @@
+#ifndef _DEVBOARD_PLATFORM_H_
+#define _DEVBOARD_PLATFORM_H_
+
+#include <linux/init.h>
+
+int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
+ phys_addr_t pcmcia_attr_len,
+ phys_addr_t pcmcia_mem_start,
+ phys_addr_t pcmcia_mem_end,
+ phys_addr_t pcmcia_io_start,
+ phys_addr_t pcmcia_io_end,
+ int card_irq,
+ int cd_irq,
+ int stschg_irq,
+ int eject_irq,
+ int id);
+
+int __init db1x_register_norflash(unsigned long size, int width,
+ int swapped);
+
+#endif
diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c
new file mode 100644
index 00000000..acaf91b5
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pm.c
@@ -0,0 +1,262 @@
+/*
+ * Alchemy Development Board example suspend userspace interface.
+ *
+ * (c) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
+ */
+
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/suspend.h>
+#include <linux/sysfs.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/gpio.h>
+#include <asm/mach-db1x00/bcsr.h>
+
+/*
+ * Generic suspend userspace interface for Alchemy development boards.
+ * This code exports a few sysfs nodes under /sys/power/db1x/ which
+ * can be used by userspace to en/disable all au1x-provided wakeup
+ * sources and configure the timeout after which the the TOYMATCH2 irq
+ * is to trigger a wakeup.
+ */
+
+
+static unsigned long db1x_pm_sleep_secs;
+static unsigned long db1x_pm_wakemsk;
+static unsigned long db1x_pm_last_wakesrc;
+
+static int db1x_pm_enter(suspend_state_t state)
+{
+ unsigned short bcsrs[16];
+ int i, j, hasint;
+
+ /* save CPLD regs */
+ hasint = bcsr_read(BCSR_WHOAMI);
+ hasint = BCSR_WHOAMI_BOARD(hasint) >= BCSR_WHOAMI_DB1200;
+ j = (hasint) ? BCSR_MASKSET : BCSR_SYSTEM;
+
+ for (i = BCSR_STATUS; i <= j; i++)
+ bcsrs[i] = bcsr_read(i);
+
+ /* shut off hexleds */
+ bcsr_write(BCSR_HEXCLEAR, 3);
+
+ /* enable GPIO based wakeup */
+ alchemy_gpio1_input_enable();
+
+ /* clear and setup wake cause and source */
+ au_writel(0, SYS_WAKEMSK);
+ au_sync();
+ au_writel(0, SYS_WAKESRC);
+ au_sync();
+
+ au_writel(db1x_pm_wakemsk, SYS_WAKEMSK);
+ au_sync();
+
+ /* setup 1Hz-timer-based wakeup: wait for reg access */
+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
+ asm volatile ("nop");
+
+ au_writel(au_readl(SYS_TOYREAD) + db1x_pm_sleep_secs, SYS_TOYMATCH2);
+ au_sync();
+
+ /* wait for value to really hit the register */
+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
+ asm volatile ("nop");
+
+ /* ...and now the sandman can come! */
+ au_sleep();
+
+
+ /* restore CPLD regs */
+ for (i = BCSR_STATUS; i <= BCSR_SYSTEM; i++)
+ bcsr_write(i, bcsrs[i]);
+
+ /* restore CPLD int registers */
+ if (hasint) {
+ bcsr_write(BCSR_INTCLR, 0xffff);
+ bcsr_write(BCSR_MASKCLR, 0xffff);
+ bcsr_write(BCSR_INTSTAT, 0xffff);
+ bcsr_write(BCSR_INTSET, bcsrs[BCSR_INTSET]);
+ bcsr_write(BCSR_MASKSET, bcsrs[BCSR_MASKSET]);
+ }
+
+ /* light up hexleds */
+ bcsr_write(BCSR_HEXCLEAR, 0);
+
+ return 0;
+}
+
+static int db1x_pm_begin(suspend_state_t state)
+{
+ if (!db1x_pm_wakemsk) {
+ printk(KERN_ERR "db1x: no wakeup source activated!\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void db1x_pm_end(void)
+{
+ /* read and store wakeup source, the clear the register. To
+ * be able to clear it, WAKEMSK must be cleared first.
+ */
+ db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC);
+
+ au_writel(0, SYS_WAKEMSK);
+ au_writel(0, SYS_WAKESRC);
+ au_sync();
+
+}
+
+static const struct platform_suspend_ops db1x_pm_ops = {
+ .valid = suspend_valid_only_mem,
+ .begin = db1x_pm_begin,
+ .enter = db1x_pm_enter,
+ .end = db1x_pm_end,
+};
+
+#define ATTRCMP(x) (0 == strcmp(attr->attr.name, #x))
+
+static ssize_t db1x_pmattr_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ int idx;
+
+ if (ATTRCMP(timer_timeout))
+ return sprintf(buf, "%lu\n", db1x_pm_sleep_secs);
+
+ else if (ATTRCMP(timer))
+ return sprintf(buf, "%u\n",
+ !!(db1x_pm_wakemsk & SYS_WAKEMSK_M2));
+
+ else if (ATTRCMP(wakesrc))
+ return sprintf(buf, "%lu\n", db1x_pm_last_wakesrc);
+
+ else if (ATTRCMP(gpio0) || ATTRCMP(gpio1) || ATTRCMP(gpio2) ||
+ ATTRCMP(gpio3) || ATTRCMP(gpio4) || ATTRCMP(gpio5) ||
+ ATTRCMP(gpio6) || ATTRCMP(gpio7)) {
+ idx = (attr->attr.name)[4] - '0';
+ return sprintf(buf, "%d\n",
+ !!(db1x_pm_wakemsk & SYS_WAKEMSK_GPIO(idx)));
+
+ } else if (ATTRCMP(wakemsk)) {
+ return sprintf(buf, "%08lx\n", db1x_pm_wakemsk);
+ }
+
+ return -ENOENT;
+}
+
+static ssize_t db1x_pmattr_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *instr,
+ size_t bytes)
+{
+ unsigned long l;
+ int tmp;
+
+ if (ATTRCMP(timer_timeout)) {
+ tmp = strict_strtoul(instr, 0, &l);
+ if (tmp)
+ return tmp;
+
+ db1x_pm_sleep_secs = l;
+
+ } else if (ATTRCMP(timer)) {
+ if (instr[0] != '0')
+ db1x_pm_wakemsk |= SYS_WAKEMSK_M2;
+ else
+ db1x_pm_wakemsk &= ~SYS_WAKEMSK_M2;
+
+ } else if (ATTRCMP(gpio0) || ATTRCMP(gpio1) || ATTRCMP(gpio2) ||
+ ATTRCMP(gpio3) || ATTRCMP(gpio4) || ATTRCMP(gpio5) ||
+ ATTRCMP(gpio6) || ATTRCMP(gpio7)) {
+ tmp = (attr->attr.name)[4] - '0';
+ if (instr[0] != '0') {
+ db1x_pm_wakemsk |= SYS_WAKEMSK_GPIO(tmp);
+ } else {
+ db1x_pm_wakemsk &= ~SYS_WAKEMSK_GPIO(tmp);
+ }
+
+ } else if (ATTRCMP(wakemsk)) {
+ tmp = strict_strtoul(instr, 0, &l);
+ if (tmp)
+ return tmp;
+
+ db1x_pm_wakemsk = l & 0x0000003f;
+
+ } else
+ bytes = -ENOENT;
+
+ return bytes;
+}
+
+#define ATTR(x) \
+ static struct kobj_attribute x##_attribute = \
+ __ATTR(x, 0664, db1x_pmattr_show, \
+ db1x_pmattr_store);
+
+ATTR(gpio0) /* GPIO-based wakeup enable */
+ATTR(gpio1)
+ATTR(gpio2)
+ATTR(gpio3)
+ATTR(gpio4)
+ATTR(gpio5)
+ATTR(gpio6)
+ATTR(gpio7)
+ATTR(timer) /* TOYMATCH2-based wakeup enable */
+ATTR(timer_timeout) /* timer-based wakeup timeout value, in seconds */
+ATTR(wakesrc) /* contents of SYS_WAKESRC after last wakeup */
+ATTR(wakemsk) /* direct access to SYS_WAKEMSK */
+
+#define ATTR_LIST(x) & x ## _attribute.attr
+static struct attribute *db1x_pmattrs[] = {
+ ATTR_LIST(gpio0),
+ ATTR_LIST(gpio1),
+ ATTR_LIST(gpio2),
+ ATTR_LIST(gpio3),
+ ATTR_LIST(gpio4),
+ ATTR_LIST(gpio5),
+ ATTR_LIST(gpio6),
+ ATTR_LIST(gpio7),
+ ATTR_LIST(timer),
+ ATTR_LIST(timer_timeout),
+ ATTR_LIST(wakesrc),
+ ATTR_LIST(wakemsk),
+ NULL, /* terminator */
+};
+
+static struct attribute_group db1x_pmattr_group = {
+ .name = "db1x",
+ .attrs = db1x_pmattrs,
+};
+
+/*
+ * Initialize suspend interface
+ */
+static int __init pm_init(void)
+{
+ /* init TOY to tick at 1Hz if not already done. No need to wait
+ * for confirmation since there's plenty of time from here to
+ * the next suspend cycle.
+ */
+ if (au_readl(SYS_TOYTRIM) != 32767) {
+ au_writel(32767, SYS_TOYTRIM);
+ au_sync();
+ }
+
+ db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC);
+
+ au_writel(0, SYS_WAKESRC);
+ au_sync();
+ au_writel(0, SYS_WAKEMSK);
+ au_sync();
+
+ suspend_set_ops(&db1x_pm_ops);
+
+ return sysfs_create_group(power_kobj, &db1x_pmattr_group);
+}
+
+late_initcall(pm_init);
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c
new file mode 100644
index 00000000..e5306b56
--- /dev/null
+++ b/arch/mips/alchemy/devboards/prom.c
@@ -0,0 +1,66 @@
+/*
+ * Common code used by all Alchemy develboards.
+ *
+ * Extracted from files which had this to say:
+ *
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <prom.h>
+
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_DB1000) || \
+ defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || \
+ defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_DB1500) || \
+ defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
+#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000
+
+#else /* Au1550/Au1200-based develboards */
+#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x08000000
+#endif
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = (int)fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
+ memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
+
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
diff --git a/arch/mips/alchemy/gpr/Makefile b/arch/mips/alchemy/gpr/Makefile
new file mode 100644
index 00000000..cb73fe25
--- /dev/null
+++ b/arch/mips/alchemy/gpr/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright 2003 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for Trapeze ITS GPR board.
+#
+
+obj-y += board_setup.o init.o platform.o
diff --git a/arch/mips/alchemy/gpr/board_setup.c b/arch/mips/alchemy/gpr/board_setup.c
new file mode 100644
index 00000000..5f8f0691
--- /dev/null
+++ b/arch/mips/alchemy/gpr/board_setup.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010 Wolfgang Grandegger <wg@denx.de>
+ *
+ * Copyright 2000-2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <prom.h>
+
+char irq_tab_alchemy[][5] __initdata = {
+ [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff },
+};
+
+static void gpr_reset(char *c)
+{
+ /* switch System-LED to orange (red# and green# on) */
+ alchemy_gpio_direction_output(4, 0);
+ alchemy_gpio_direction_output(5, 0);
+
+ /* trigger watchdog to reset board in 200ms */
+ printk(KERN_EMERG "Triggering watchdog soft reset...\n");
+ raw_local_irq_disable();
+ alchemy_gpio_direction_output(1, 0);
+ udelay(1);
+ alchemy_gpio_set_value(1, 1);
+ while (1)
+ cpu_wait();
+}
+
+static void gpr_power_off(void)
+{
+ while (1)
+ cpu_wait();
+}
+
+void __init board_setup(void)
+{
+ printk(KERN_INFO "Trapeze ITS GPR board\n");
+
+ pm_power_off = gpr_power_off;
+ _machine_halt = gpr_power_off;
+ _machine_restart = gpr_reset;
+
+ /* Enable UART1/3 */
+ alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
+ alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
+
+ /* Take away Reset of UMTS-card */
+ alchemy_gpio_direction_output(215, 1);
+
+#ifdef CONFIG_PCI
+#if defined(__MIPSEB__)
+ au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+#else
+ au_writel(0xf, Au1500_PCI_CFG);
+#endif
+#endif
+}
diff --git a/arch/mips/alchemy/gpr/init.c b/arch/mips/alchemy/gpr/init.c
new file mode 100644
index 00000000..229aafae
--- /dev/null
+++ b/arch/mips/alchemy/gpr/init.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010 Wolfgang Grandegger <wg@denx.de>
+ *
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <prom.h>
+
+const char *get_system_type(void)
+{
+ return "GPR";
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str)
+ memsize = 0x04000000;
+ else
+ strict_strtoul(memsize_str, 0, &memsize);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
diff --git a/arch/mips/alchemy/gpr/platform.c b/arch/mips/alchemy/gpr/platform.c
new file mode 100644
index 00000000..14b46629
--- /dev/null
+++ b/arch/mips/alchemy/gpr/platform.c
@@ -0,0 +1,183 @@
+/*
+ * GPR board platform device registration
+ *
+ * Copyright (C) 2010 Wolfgang Grandegger <wg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+/*
+ * Watchdog
+ */
+static struct resource gpr_wdt_resource[] = {
+ [0] = {
+ .start = 1,
+ .end = 1,
+ .name = "gpr-adm6320-wdt",
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device gpr_wdt_device = {
+ .name = "adm6320-wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(gpr_wdt_resource),
+ .resource = gpr_wdt_resource,
+};
+
+/*
+ * FLASH
+ *
+ * 0x00000000-0x00200000 : "kernel"
+ * 0x00200000-0x00a00000 : "rootfs"
+ * 0x01d00000-0x01f00000 : "config"
+ * 0x01c00000-0x01d00000 : "yamon"
+ * 0x01d00000-0x01d40000 : "yamon env vars"
+ * 0x00000000-0x00a00000 : "kernel+rootfs"
+ */
+static struct mtd_partition gpr_mtd_partitions[] = {
+ {
+ .name = "kernel",
+ .size = 0x00200000,
+ .offset = 0,
+ },
+ {
+ .name = "rootfs",
+ .size = 0x00800000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "config",
+ .size = 0x00200000,
+ .offset = 0x01d00000,
+ },
+ {
+ .name = "yamon",
+ .size = 0x00100000,
+ .offset = 0x01c00000,
+ },
+ {
+ .name = "yamon env vars",
+ .size = 0x00040000,
+ .offset = MTDPART_OFS_APPEND,
+ },
+ {
+ .name = "kernel+rootfs",
+ .size = 0x00a00000,
+ .offset = 0,
+ },
+};
+
+static struct physmap_flash_data gpr_flash_data = {
+ .width = 4,
+ .nr_parts = ARRAY_SIZE(gpr_mtd_partitions),
+ .parts = gpr_mtd_partitions,
+};
+
+static struct resource gpr_mtd_resource = {
+ .start = 0x1e000000,
+ .end = 0x1fffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device gpr_mtd_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &gpr_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &gpr_mtd_resource,
+};
+
+/*
+ * LEDs
+ */
+static struct gpio_led gpr_gpio_leds[] = {
+ { /* green */
+ .name = "gpr:green",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ { /* red */
+ .name = "gpr:red",
+ .gpio = 5,
+ .active_low = 1,
+ }
+};
+
+static struct gpio_led_platform_data gpr_led_data = {
+ .num_leds = ARRAY_SIZE(gpr_gpio_leds),
+ .leds = gpr_gpio_leds,
+};
+
+static struct platform_device gpr_led_devices = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpr_led_data,
+ }
+};
+
+/*
+ * I2C
+ */
+static struct i2c_gpio_platform_data gpr_i2c_data = {
+ .sda_pin = 209,
+ .sda_is_open_drain = 1,
+ .scl_pin = 210,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+ .timeout = HZ,
+ };
+
+static struct platform_device gpr_i2c_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &gpr_i2c_data,
+};
+
+static struct i2c_board_info gpr_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("lm83", 0x18),
+ .type = "lm83"
+ }
+};
+
+static struct platform_device *gpr_devices[] __initdata = {
+ &gpr_wdt_device,
+ &gpr_mtd_device,
+ &gpr_i2c_device,
+ &gpr_led_devices,
+};
+
+static int __init gpr_dev_init(void)
+{
+ i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info));
+
+ return platform_add_devices(gpr_devices, ARRAY_SIZE(gpr_devices));
+}
+device_initcall(gpr_dev_init);
diff --git a/arch/mips/alchemy/mtx-1/Makefile b/arch/mips/alchemy/mtx-1/Makefile
new file mode 100644
index 00000000..81b540ce
--- /dev/null
+++ b/arch/mips/alchemy/mtx-1/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright 2003 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+# Bruno Randolf <bruno.randolf@4g-systems.biz>
+#
+# Makefile for 4G Systems MTX-1 board.
+#
+
+obj-y += init.o board_setup.o platform.o
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c
new file mode 100644
index 00000000..3ae984cf
--- /dev/null
+++ b/arch/mips/alchemy/mtx-1/board_setup.c
@@ -0,0 +1,134 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * 4G Systems MTX-1 board setup.
+ *
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ * Bruno Randolf <bruno.randolf@4g-systems.biz>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <prom.h>
+
+char irq_tab_alchemy[][5] __initdata = {
+ [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
+ [1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
+ [2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
+ [3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
+ [4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
+ [5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
+ [6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
+ [7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
+};
+
+extern int (*board_pci_idsel)(unsigned int devsel, int assert);
+int mtx1_pci_idsel(unsigned int devsel, int assert);
+
+static void mtx1_reset(char *c)
+{
+ /* Jump to the reset vector */
+ __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+static void mtx1_power_off(void)
+{
+ while (1)
+ asm volatile (
+ " .set mips32 \n"
+ " wait \n"
+ " .set mips0 \n");
+}
+
+void __init board_setup(void)
+{
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* Enable USB power switch */
+ alchemy_gpio_direction_output(204, 0);
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+
+#ifdef CONFIG_PCI
+#if defined(__MIPSEB__)
+ au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+#else
+ au_writel(0xf, Au1500_PCI_CFG);
+#endif
+ board_pci_idsel = mtx1_pci_idsel;
+#endif
+
+ /* Initialize sys_pinfunc */
+ au_writel(SYS_PF_NI2, SYS_PINFUNC);
+
+ /* Initialize GPIO */
+ au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR);
+ alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */
+ alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */
+ alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */
+ alchemy_gpio_direction_output(5, 0); /* Disable eth PHY TX_ER */
+
+ /* Enable LED and set it to green */
+ alchemy_gpio_direction_output(211, 1); /* green on */
+ alchemy_gpio_direction_output(212, 0); /* red off */
+
+ pm_power_off = mtx1_power_off;
+ _machine_halt = mtx1_power_off;
+ _machine_restart = mtx1_reset;
+
+ printk(KERN_INFO "4G Systems MTX-1 Board\n");
+}
+
+int
+mtx1_pci_idsel(unsigned int devsel, int assert)
+{
+ /* This function is only necessary to support a proprietary Cardbus
+ * adapter on the mtx-1 "singleboard" variant. It triggers a custom
+ * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.
+ */
+ if (assert && devsel != 0)
+ /* Suppress signal to Cardbus */
+ alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */
+ else
+ alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */
+
+ udelay(1);
+ return 1;
+}
+
+static int __init mtx1_init_irq(void)
+{
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+
+ return 0;
+}
+arch_initcall(mtx1_init_irq);
diff --git a/arch/mips/alchemy/mtx-1/init.c b/arch/mips/alchemy/mtx-1/init.c
new file mode 100644
index 00000000..2e81cc7f
--- /dev/null
+++ b/arch/mips/alchemy/mtx-1/init.c
@@ -0,0 +1,66 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * 4G Systems MTX-1 board setup
+ *
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ * Bruno Randolf <bruno.randolf@4g-systems.biz>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <prom.h>
+
+const char *get_system_type(void)
+{
+ return "MTX-1";
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str)
+ memsize = 0x04000000;
+ else
+ strict_strtoul(memsize_str, 0, &memsize);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
diff --git a/arch/mips/alchemy/mtx-1/platform.c b/arch/mips/alchemy/mtx-1/platform.c
new file mode 100644
index 00000000..55628e39
--- /dev/null
+++ b/arch/mips/alchemy/mtx-1/platform.c
@@ -0,0 +1,168 @@
+/*
+ * MTX-1 platform devices registration
+ *
+ * Copyright (C) 2007-2009, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <mtd/mtd-abi.h>
+
+#include <asm/mach-au1x00/au1xxx_eth.h>
+
+static struct gpio_keys_button mtx1_gpio_button[] = {
+ {
+ .gpio = 207,
+ .code = BTN_0,
+ .desc = "System button",
+ }
+};
+
+static struct gpio_keys_platform_data mtx1_buttons_data = {
+ .buttons = mtx1_gpio_button,
+ .nbuttons = ARRAY_SIZE(mtx1_gpio_button),
+};
+
+static struct platform_device mtx1_button = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &mtx1_buttons_data,
+ }
+};
+
+static struct resource mtx1_wdt_res[] = {
+ [0] = {
+ .start = 215,
+ .end = 215,
+ .name = "mtx1-wdt-gpio",
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device mtx1_wdt = {
+ .name = "mtx1-wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mtx1_wdt_res),
+ .resource = mtx1_wdt_res,
+};
+
+static struct gpio_led default_leds[] = {
+ {
+ .name = "mtx1:green",
+ .gpio = 211,
+ }, {
+ .name = "mtx1:red",
+ .gpio = 212,
+ },
+};
+
+static struct gpio_led_platform_data mtx1_led_data = {
+ .num_leds = ARRAY_SIZE(default_leds),
+ .leds = default_leds,
+};
+
+static struct platform_device mtx1_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mtx1_led_data,
+ }
+};
+
+static struct mtd_partition mtx1_mtd_partitions[] = {
+ {
+ .name = "filesystem",
+ .size = 0x01C00000,
+ .offset = 0,
+ },
+ {
+ .name = "yamon",
+ .size = 0x00100000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .size = 0x002c0000,
+ .offset = MTDPART_OFS_APPEND,
+ },
+ {
+ .name = "yamon env",
+ .size = 0x00040000,
+ .offset = MTDPART_OFS_APPEND,
+ },
+};
+
+static struct physmap_flash_data mtx1_flash_data = {
+ .width = 4,
+ .nr_parts = 4,
+ .parts = mtx1_mtd_partitions,
+};
+
+static struct resource mtx1_mtd_resource = {
+ .start = 0x1e000000,
+ .end = 0x1fffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mtx1_mtd = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &mtx1_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mtx1_mtd_resource,
+};
+
+static struct __initdata platform_device * mtx1_devs[] = {
+ &mtx1_gpio_leds,
+ &mtx1_wdt,
+ &mtx1_button,
+ &mtx1_mtd,
+};
+
+static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = {
+ .phy_search_highest_addr = 1,
+ .phy1_search_mac0 = 1,
+};
+
+static int __init mtx1_register_devices(void)
+{
+ int rc;
+
+ au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata);
+
+ rc = gpio_request(mtx1_gpio_button[0].gpio,
+ mtx1_gpio_button[0].desc);
+ if (rc < 0) {
+ printk(KERN_INFO "mtx1: failed to request %d\n",
+ mtx1_gpio_button[0].gpio);
+ goto out;
+ }
+ gpio_direction_input(mtx1_gpio_button[0].gpio);
+out:
+ return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
+}
+
+arch_initcall(mtx1_register_devices);
diff --git a/arch/mips/alchemy/xxs1500/Makefile b/arch/mips/alchemy/xxs1500/Makefile
new file mode 100644
index 00000000..91defcf4
--- /dev/null
+++ b/arch/mips/alchemy/xxs1500/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright 2003 MontaVista Software Inc.
+# Author: MontaVista Software, Inc. <source@mvista.com>
+#
+# Makefile for MyCable XXS1500 board.
+#
+
+obj-y += init.o board_setup.o platform.o
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c
new file mode 100644
index 00000000..81e57fad
--- /dev/null
+++ b/arch/mips/alchemy/xxs1500/board_setup.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <prom.h>
+
+static void xxs1500_reset(char *c)
+{
+ /* Jump to the reset vector */
+ __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+static void xxs1500_power_off(void)
+{
+ while (1)
+ asm volatile (
+ " .set mips32 \n"
+ " wait \n"
+ " .set mips0 \n");
+}
+
+void __init board_setup(void)
+{
+ u32 pin_func;
+
+ pm_power_off = xxs1500_power_off;
+ _machine_halt = xxs1500_power_off;
+ _machine_restart = xxs1500_reset;
+
+ alchemy_gpio1_input_enable();
+ alchemy_gpio2_enable();
+
+ /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
+ pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
+ pin_func |= SYS_PF_UR3;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ /* Enable UART */
+ alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
+ /* Enable DTR (MCR bit 0) = USB power up */
+ __raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18));
+ wmb();
+
+#ifdef CONFIG_PCI
+#if defined(__MIPSEB__)
+ au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
+#else
+ au_writel(0xf, Au1500_PCI_CFG);
+#endif
+#endif
+}
+
+static int __init xxs1500_init_irq(void)
+{
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW);
+
+ irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */
+ irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW);
+
+ return 0;
+}
+arch_initcall(xxs1500_init_irq);
diff --git a/arch/mips/alchemy/xxs1500/init.c b/arch/mips/alchemy/xxs1500/init.c
new file mode 100644
index 00000000..0ee02cfa
--- /dev/null
+++ b/arch/mips/alchemy/xxs1500/init.c
@@ -0,0 +1,63 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * XXS1500 board setup
+ *
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#include <prom.h>
+
+const char *get_system_type(void)
+{
+ return "XXS1500";
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
+ memsize = 0x04000000;
+
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
diff --git a/arch/mips/alchemy/xxs1500/platform.c b/arch/mips/alchemy/xxs1500/platform.c
new file mode 100644
index 00000000..e87c45cd
--- /dev/null
+++ b/arch/mips/alchemy/xxs1500/platform.c
@@ -0,0 +1,63 @@
+/*
+ * XXS1500 board platform device registration
+ *
+ * Copyright (C) 2009 Manuel Lauss
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+static struct resource xxs1500_pcmcia_res[] = {
+ {
+ .name = "pcmcia-io",
+ .flags = IORESOURCE_MEM,
+ .start = PCMCIA_IO_PHYS_ADDR,
+ .end = PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1,
+ },
+ {
+ .name = "pcmcia-attr",
+ .flags = IORESOURCE_MEM,
+ .start = PCMCIA_ATTR_PHYS_ADDR,
+ .end = PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ },
+ {
+ .name = "pcmcia-mem",
+ .flags = IORESOURCE_MEM,
+ .start = PCMCIA_MEM_PHYS_ADDR,
+ .end = PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ },
+};
+
+static struct platform_device xxs1500_pcmcia_dev = {
+ .name = "xxs1500_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(xxs1500_pcmcia_res),
+ .resource = xxs1500_pcmcia_res,
+};
+
+static struct platform_device *xxs1500_devs[] __initdata = {
+ &xxs1500_pcmcia_dev,
+};
+
+static int __init xxs1500_dev_init(void)
+{
+ return platform_add_devices(xxs1500_devs,
+ ARRAY_SIZE(xxs1500_devs));
+}
+device_initcall(xxs1500_dev_init);
diff --git a/arch/mips/ar7/Makefile b/arch/mips/ar7/Makefile
new file mode 100644
index 00000000..7435e44b
--- /dev/null
+++ b/arch/mips/ar7/Makefile
@@ -0,0 +1,10 @@
+
+obj-y := \
+ prom.o \
+ setup.o \
+ memory.o \
+ irq.o \
+ time.o \
+ platform.o \
+ gpio.o \
+ clock.o
diff --git a/arch/mips/ar7/Platform b/arch/mips/ar7/Platform
new file mode 100644
index 00000000..0bf85c41
--- /dev/null
+++ b/arch/mips/ar7/Platform
@@ -0,0 +1,6 @@
+#
+# Texas Instruments AR7
+#
+platform-$(CONFIG_AR7) += ar7/
+cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7
+load-$(CONFIG_AR7) += 0xffffffff94100000
diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c
new file mode 100644
index 00000000..2ca4ada1
--- /dev/null
+++ b/arch/mips/ar7/clock.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
+ * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/gcd.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/addrspace.h>
+#include <asm/mach-ar7/ar7.h>
+
+#define BOOT_PLL_SOURCE_MASK 0x3
+#define CPU_PLL_SOURCE_SHIFT 16
+#define BUS_PLL_SOURCE_SHIFT 14
+#define USB_PLL_SOURCE_SHIFT 18
+#define DSP_PLL_SOURCE_SHIFT 22
+#define BOOT_PLL_SOURCE_AFE 0
+#define BOOT_PLL_SOURCE_BUS 0
+#define BOOT_PLL_SOURCE_REF 1
+#define BOOT_PLL_SOURCE_XTAL 2
+#define BOOT_PLL_SOURCE_CPU 3
+#define BOOT_PLL_BYPASS 0x00000020
+#define BOOT_PLL_ASYNC_MODE 0x02000000
+#define BOOT_PLL_2TO1_MODE 0x00008000
+
+#define TNETD7200_CLOCK_ID_CPU 0
+#define TNETD7200_CLOCK_ID_DSP 1
+#define TNETD7200_CLOCK_ID_USB 2
+
+#define TNETD7200_DEF_CPU_CLK 211000000
+#define TNETD7200_DEF_DSP_CLK 125000000
+#define TNETD7200_DEF_USB_CLK 48000000
+
+struct tnetd7300_clock {
+ u32 ctrl;
+#define PREDIV_MASK 0x001f0000
+#define PREDIV_SHIFT 16
+#define POSTDIV_MASK 0x0000001f
+ u32 unused1[3];
+ u32 pll;
+#define MUL_MASK 0x0000f000
+#define MUL_SHIFT 12
+#define PLL_MODE_MASK 0x00000001
+#define PLL_NDIV 0x00000800
+#define PLL_DIV 0x00000002
+#define PLL_STATUS 0x00000001
+ u32 unused2[3];
+};
+
+struct tnetd7300_clocks {
+ struct tnetd7300_clock bus;
+ struct tnetd7300_clock cpu;
+ struct tnetd7300_clock usb;
+ struct tnetd7300_clock dsp;
+};
+
+struct tnetd7200_clock {
+ u32 ctrl;
+ u32 unused1[3];
+#define DIVISOR_ENABLE_MASK 0x00008000
+ u32 mul;
+ u32 prediv;
+ u32 postdiv;
+ u32 postdiv2;
+ u32 unused2[6];
+ u32 cmd;
+ u32 status;
+ u32 cmden;
+ u32 padding[15];
+};
+
+struct tnetd7200_clocks {
+ struct tnetd7200_clock cpu;
+ struct tnetd7200_clock dsp;
+ struct tnetd7200_clock usb;
+};
+
+static struct clk bus_clk = {
+ .rate = 125000000,
+};
+
+static struct clk cpu_clk = {
+ .rate = 150000000,
+};
+
+static struct clk dsp_clk;
+static struct clk vbus_clk;
+
+static void approximate(int base, int target, int *prediv,
+ int *postdiv, int *mul)
+{
+ int i, j, k, freq, res = target;
+ for (i = 1; i <= 16; i++)
+ for (j = 1; j <= 32; j++)
+ for (k = 1; k <= 32; k++) {
+ freq = abs(base / j * i / k - target);
+ if (freq < res) {
+ res = freq;
+ *mul = i;
+ *prediv = j;
+ *postdiv = k;
+ }
+ }
+}
+
+static void calculate(int base, int target, int *prediv, int *postdiv,
+ int *mul)
+{
+ int tmp_gcd, tmp_base, tmp_freq;
+
+ for (*prediv = 1; *prediv <= 32; (*prediv)++) {
+ tmp_base = base / *prediv;
+ tmp_gcd = gcd(target, tmp_base);
+ *mul = target / tmp_gcd;
+ *postdiv = tmp_base / tmp_gcd;
+ if ((*mul < 1) || (*mul >= 16))
+ continue;
+ if ((*postdiv > 0) & (*postdiv <= 32))
+ break;
+ }
+
+ if (base / *prediv * *mul / *postdiv != target) {
+ approximate(base, target, prediv, postdiv, mul);
+ tmp_freq = base / *prediv * *mul / *postdiv;
+ printk(KERN_WARNING
+ "Adjusted requested frequency %d to %d\n",
+ target, tmp_freq);
+ }
+
+ printk(KERN_DEBUG "Clocks: prediv: %d, postdiv: %d, mul: %d\n",
+ *prediv, *postdiv, *mul);
+}
+
+static int tnetd7300_dsp_clock(void)
+{
+ u32 didr1, didr2;
+ u8 rev = ar7_chip_rev();
+ didr1 = readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x18));
+ didr2 = readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x1c));
+ if (didr2 & (1 << 23))
+ return 0;
+ if ((rev >= 0x23) && (rev != 0x57))
+ return 250000000;
+ if ((((didr2 & 0x1fff) << 10) | ((didr1 & 0xffc00000) >> 22))
+ > 4208000)
+ return 250000000;
+ return 0;
+}
+
+static int tnetd7300_get_clock(u32 shift, struct tnetd7300_clock *clock,
+ u32 *bootcr, u32 bus_clock)
+{
+ int product;
+ int base_clock = AR7_REF_CLOCK;
+ u32 ctrl = readl(&clock->ctrl);
+ u32 pll = readl(&clock->pll);
+ int prediv = ((ctrl & PREDIV_MASK) >> PREDIV_SHIFT) + 1;
+ int postdiv = (ctrl & POSTDIV_MASK) + 1;
+ int divisor = prediv * postdiv;
+ int mul = ((pll & MUL_MASK) >> MUL_SHIFT) + 1;
+
+ switch ((*bootcr & (BOOT_PLL_SOURCE_MASK << shift)) >> shift) {
+ case BOOT_PLL_SOURCE_BUS:
+ base_clock = bus_clock;
+ break;
+ case BOOT_PLL_SOURCE_REF:
+ base_clock = AR7_REF_CLOCK;
+ break;
+ case BOOT_PLL_SOURCE_XTAL:
+ base_clock = AR7_XTAL_CLOCK;
+ break;
+ case BOOT_PLL_SOURCE_CPU:
+ base_clock = cpu_clk.rate;
+ break;
+ }
+
+ if (*bootcr & BOOT_PLL_BYPASS)
+ return base_clock / divisor;
+
+ if ((pll & PLL_MODE_MASK) == 0)
+ return (base_clock >> (mul / 16 + 1)) / divisor;
+
+ if ((pll & (PLL_NDIV | PLL_DIV)) == (PLL_NDIV | PLL_DIV)) {
+ product = (mul & 1) ?
+ (base_clock * mul) >> 1 :
+ (base_clock * (mul - 1)) >> 2;
+ return product / divisor;
+ }
+
+ if (mul == 16)
+ return base_clock / divisor;
+
+ return base_clock * mul / divisor;
+}
+
+static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock,
+ u32 *bootcr, u32 frequency)
+{
+ int prediv, postdiv, mul;
+ int base_clock = bus_clk.rate;
+
+ switch ((*bootcr & (BOOT_PLL_SOURCE_MASK << shift)) >> shift) {
+ case BOOT_PLL_SOURCE_BUS:
+ base_clock = bus_clk.rate;
+ break;
+ case BOOT_PLL_SOURCE_REF:
+ base_clock = AR7_REF_CLOCK;
+ break;
+ case BOOT_PLL_SOURCE_XTAL:
+ base_clock = AR7_XTAL_CLOCK;
+ break;
+ case BOOT_PLL_SOURCE_CPU:
+ base_clock = cpu_clk.rate;
+ break;
+ }
+
+ calculate(base_clock, frequency, &prediv, &postdiv, &mul);
+
+ writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl);
+ mdelay(1);
+ writel(4, &clock->pll);
+ while (readl(&clock->pll) & PLL_STATUS)
+ ;
+ writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll);
+ mdelay(75);
+}
+
+static void __init tnetd7300_init_clocks(void)
+{
+ u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
+ struct tnetd7300_clocks *clocks =
+ ioremap_nocache(UR8_REGS_CLOCKS,
+ sizeof(struct tnetd7300_clocks));
+
+ bus_clk.rate = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT,
+ &clocks->bus, bootcr, AR7_AFE_CLOCK);
+
+ if (*bootcr & BOOT_PLL_ASYNC_MODE)
+ cpu_clk.rate = tnetd7300_get_clock(CPU_PLL_SOURCE_SHIFT,
+ &clocks->cpu, bootcr, AR7_AFE_CLOCK);
+ else
+ cpu_clk.rate = bus_clk.rate;
+
+ if (dsp_clk.rate == 250000000)
+ tnetd7300_set_clock(DSP_PLL_SOURCE_SHIFT, &clocks->dsp,
+ bootcr, dsp_clk.rate);
+
+ iounmap(clocks);
+ iounmap(bootcr);
+}
+
+static void tnetd7200_set_clock(int base, struct tnetd7200_clock *clock,
+ int prediv, int postdiv, int postdiv2, int mul, u32 frequency)
+{
+ printk(KERN_INFO
+ "Clocks: base = %d, frequency = %u, prediv = %d, "
+ "postdiv = %d, postdiv2 = %d, mul = %d\n",
+ base, frequency, prediv, postdiv, postdiv2, mul);
+
+ writel(0, &clock->ctrl);
+ writel(DIVISOR_ENABLE_MASK | ((prediv - 1) & 0x1F), &clock->prediv);
+ writel((mul - 1) & 0xF, &clock->mul);
+
+ while (readl(&clock->status) & 0x1)
+ ; /* nop */
+
+ writel(DIVISOR_ENABLE_MASK | ((postdiv - 1) & 0x1F), &clock->postdiv);
+
+ writel(readl(&clock->cmden) | 1, &clock->cmden);
+ writel(readl(&clock->cmd) | 1, &clock->cmd);
+
+ while (readl(&clock->status) & 0x1)
+ ; /* nop */
+
+ writel(DIVISOR_ENABLE_MASK | ((postdiv2 - 1) & 0x1F), &clock->postdiv2);
+
+ writel(readl(&clock->cmden) | 1, &clock->cmden);
+ writel(readl(&clock->cmd) | 1, &clock->cmd);
+
+ while (readl(&clock->status) & 0x1)
+ ; /* nop */
+
+ writel(readl(&clock->ctrl) | 1, &clock->ctrl);
+}
+
+static int tnetd7200_get_clock_base(int clock_id, u32 *bootcr)
+{
+ if (*bootcr & BOOT_PLL_ASYNC_MODE)
+ /* Async */
+ switch (clock_id) {
+ case TNETD7200_CLOCK_ID_DSP:
+ return AR7_REF_CLOCK;
+ default:
+ return AR7_AFE_CLOCK;
+ }
+ else
+ /* Sync */
+ if (*bootcr & BOOT_PLL_2TO1_MODE)
+ /* 2:1 */
+ switch (clock_id) {
+ case TNETD7200_CLOCK_ID_DSP:
+ return AR7_REF_CLOCK;
+ default:
+ return AR7_AFE_CLOCK;
+ }
+ else
+ /* 1:1 */
+ return AR7_REF_CLOCK;
+}
+
+
+static void __init tnetd7200_init_clocks(void)
+{
+ u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4);
+ struct tnetd7200_clocks *clocks =
+ ioremap_nocache(AR7_REGS_CLOCKS,
+ sizeof(struct tnetd7200_clocks));
+ int cpu_base, cpu_mul, cpu_prediv, cpu_postdiv;
+ int dsp_base, dsp_mul, dsp_prediv, dsp_postdiv;
+ int usb_base, usb_mul, usb_prediv, usb_postdiv;
+
+ cpu_base = tnetd7200_get_clock_base(TNETD7200_CLOCK_ID_CPU, bootcr);
+ dsp_base = tnetd7200_get_clock_base(TNETD7200_CLOCK_ID_DSP, bootcr);
+
+ if (*bootcr & BOOT_PLL_ASYNC_MODE) {
+ printk(KERN_INFO "Clocks: Async mode\n");
+
+ printk(KERN_INFO "Clocks: Setting DSP clock\n");
+ calculate(dsp_base, TNETD7200_DEF_DSP_CLK,
+ &dsp_prediv, &dsp_postdiv, &dsp_mul);
+ bus_clk.rate =
+ ((dsp_base / dsp_prediv) * dsp_mul) / dsp_postdiv;
+ tnetd7200_set_clock(dsp_base, &clocks->dsp,
+ dsp_prediv, dsp_postdiv * 2, dsp_postdiv, dsp_mul * 2,
+ bus_clk.rate);
+
+ printk(KERN_INFO "Clocks: Setting CPU clock\n");
+ calculate(cpu_base, TNETD7200_DEF_CPU_CLK, &cpu_prediv,
+ &cpu_postdiv, &cpu_mul);
+ cpu_clk.rate =
+ ((cpu_base / cpu_prediv) * cpu_mul) / cpu_postdiv;
+ tnetd7200_set_clock(cpu_base, &clocks->cpu,
+ cpu_prediv, cpu_postdiv, -1, cpu_mul,
+ cpu_clk.rate);
+
+ } else
+ if (*bootcr & BOOT_PLL_2TO1_MODE) {
+ printk(KERN_INFO "Clocks: Sync 2:1 mode\n");
+
+ printk(KERN_INFO "Clocks: Setting CPU clock\n");
+ calculate(cpu_base, TNETD7200_DEF_CPU_CLK, &cpu_prediv,
+ &cpu_postdiv, &cpu_mul);
+ cpu_clk.rate = ((cpu_base / cpu_prediv) * cpu_mul)
+ / cpu_postdiv;
+ tnetd7200_set_clock(cpu_base, &clocks->cpu,
+ cpu_prediv, cpu_postdiv, -1, cpu_mul,
+ cpu_clk.rate);
+
+ printk(KERN_INFO "Clocks: Setting DSP clock\n");
+ calculate(dsp_base, TNETD7200_DEF_DSP_CLK, &dsp_prediv,
+ &dsp_postdiv, &dsp_mul);
+ bus_clk.rate = cpu_clk.rate / 2;
+ tnetd7200_set_clock(dsp_base, &clocks->dsp,
+ dsp_prediv, dsp_postdiv * 2, dsp_postdiv,
+ dsp_mul * 2, bus_clk.rate);
+ } else {
+ printk(KERN_INFO "Clocks: Sync 1:1 mode\n");
+
+ printk(KERN_INFO "Clocks: Setting DSP clock\n");
+ calculate(dsp_base, TNETD7200_DEF_DSP_CLK, &dsp_prediv,
+ &dsp_postdiv, &dsp_mul);
+ bus_clk.rate = ((dsp_base / dsp_prediv) * dsp_mul)
+ / dsp_postdiv;
+ tnetd7200_set_clock(dsp_base, &clocks->dsp,
+ dsp_prediv, dsp_postdiv * 2, dsp_postdiv,
+ dsp_mul * 2, bus_clk.rate);
+
+ cpu_clk.rate = bus_clk.rate;
+ }
+
+ printk(KERN_INFO "Clocks: Setting USB clock\n");
+ usb_base = bus_clk.rate;
+ calculate(usb_base, TNETD7200_DEF_USB_CLK, &usb_prediv,
+ &usb_postdiv, &usb_mul);
+ tnetd7200_set_clock(usb_base, &clocks->usb,
+ usb_prediv, usb_postdiv, -1, usb_mul,
+ TNETD7200_DEF_USB_CLK);
+
+ dsp_clk.rate = cpu_clk.rate;
+
+ iounmap(clocks);
+ iounmap(bootcr);
+}
+
+/*
+ * Linux clock API
+ */
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ if (!strcmp(id, "bus"))
+ return &bus_clk;
+ /* cpmac and vbus share the same rate */
+ if (!strcmp(id, "cpmac"))
+ return &vbus_clk;
+ if (!strcmp(id, "cpu"))
+ return &cpu_clk;
+ if (!strcmp(id, "dsp"));
+ return &dsp_clk;
+ if (!strcmp(id, "vbus"))
+ return &vbus_clk;
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+void __init ar7_init_clocks(void)
+{
+ switch (ar7_chip_id()) {
+ case AR7_CHIP_7100:
+ case AR7_CHIP_7200:
+ tnetd7200_init_clocks();
+ break;
+ case AR7_CHIP_7300:
+ dsp_clk.rate = tnetd7300_dsp_clock();
+ tnetd7300_init_clocks();
+ break;
+ default:
+ break;
+ }
+ /* adjust vbus clock rate */
+ vbus_clk.rate = bus_clk.rate / 2;
+}
diff --git a/arch/mips/ar7/gpio.c b/arch/mips/ar7/gpio.c
new file mode 100644
index 00000000..bb571bcd
--- /dev/null
+++ b/arch/mips/ar7/gpio.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
+ * Copyright (C) 2009-2010 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ar7/gpio.h>
+
+struct ar7_gpio_chip {
+ void __iomem *regs;
+ struct gpio_chip chip;
+};
+
+static int ar7_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_in = gpch->regs + AR7_GPIO_INPUT;
+
+ return readl(gpio_in) & (1 << gpio);
+}
+
+static int titan_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_in0 = gpch->regs + TITAN_GPIO_INPUT_0;
+ void __iomem *gpio_in1 = gpch->regs + TITAN_GPIO_INPUT_1;
+
+ return readl(gpio >> 5 ? gpio_in1 : gpio_in0) & (1 << (gpio & 0x1f));
+}
+
+static void ar7_gpio_set_value(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_out = gpch->regs + AR7_GPIO_OUTPUT;
+ unsigned tmp;
+
+ tmp = readl(gpio_out) & ~(1 << gpio);
+ if (value)
+ tmp |= 1 << gpio;
+ writel(tmp, gpio_out);
+}
+
+static void titan_gpio_set_value(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_out0 = gpch->regs + TITAN_GPIO_OUTPUT_0;
+ void __iomem *gpio_out1 = gpch->regs + TITAN_GPIO_OUTPUT_1;
+ unsigned tmp;
+
+ tmp = readl(gpio >> 5 ? gpio_out1 : gpio_out0) & ~(1 << (gpio & 0x1f));
+ if (value)
+ tmp |= 1 << (gpio & 0x1f);
+ writel(tmp, gpio >> 5 ? gpio_out1 : gpio_out0);
+}
+
+static int ar7_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
+
+ writel(readl(gpio_dir) | (1 << gpio), gpio_dir);
+
+ return 0;
+}
+
+static int titan_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
+ void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
+
+ if (gpio >= TITAN_GPIO_MAX)
+ return -EINVAL;
+
+ writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) | (1 << (gpio & 0x1f)),
+ gpio >> 5 ? gpio_dir1 : gpio_dir0);
+ return 0;
+}
+
+static int ar7_gpio_direction_output(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_dir = gpch->regs + AR7_GPIO_DIR;
+
+ ar7_gpio_set_value(chip, gpio, value);
+ writel(readl(gpio_dir) & ~(1 << gpio), gpio_dir);
+
+ return 0;
+}
+
+static int titan_gpio_direction_output(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ struct ar7_gpio_chip *gpch =
+ container_of(chip, struct ar7_gpio_chip, chip);
+ void __iomem *gpio_dir0 = gpch->regs + TITAN_GPIO_DIR_0;
+ void __iomem *gpio_dir1 = gpch->regs + TITAN_GPIO_DIR_1;
+
+ if (gpio >= TITAN_GPIO_MAX)
+ return -EINVAL;
+
+ titan_gpio_set_value(chip, gpio, value);
+ writel(readl(gpio >> 5 ? gpio_dir1 : gpio_dir0) & ~(1 <<
+ (gpio & 0x1f)), gpio >> 5 ? gpio_dir1 : gpio_dir0);
+
+ return 0;
+}
+
+static struct ar7_gpio_chip ar7_gpio_chip = {
+ .chip = {
+ .label = "ar7-gpio",
+ .direction_input = ar7_gpio_direction_input,
+ .direction_output = ar7_gpio_direction_output,
+ .set = ar7_gpio_set_value,
+ .get = ar7_gpio_get_value,
+ .base = 0,
+ .ngpio = AR7_GPIO_MAX,
+ }
+};
+
+static struct ar7_gpio_chip titan_gpio_chip = {
+ .chip = {
+ .label = "titan-gpio",
+ .direction_input = titan_gpio_direction_input,
+ .direction_output = titan_gpio_direction_output,
+ .set = titan_gpio_set_value,
+ .get = titan_gpio_get_value,
+ .base = 0,
+ .ngpio = TITAN_GPIO_MAX,
+ }
+};
+
+static inline int ar7_gpio_enable_ar7(unsigned gpio)
+{
+ void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
+
+ writel(readl(gpio_en) | (1 << gpio), gpio_en);
+
+ return 0;
+}
+
+static inline int ar7_gpio_enable_titan(unsigned gpio)
+{
+ void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
+ void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
+
+ writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) | (1 << (gpio & 0x1f)),
+ gpio >> 5 ? gpio_en1 : gpio_en0);
+
+ return 0;
+}
+
+int ar7_gpio_enable(unsigned gpio)
+{
+ return ar7_is_titan() ? ar7_gpio_enable_titan(gpio) :
+ ar7_gpio_enable_ar7(gpio);
+}
+EXPORT_SYMBOL(ar7_gpio_enable);
+
+static inline int ar7_gpio_disable_ar7(unsigned gpio)
+{
+ void __iomem *gpio_en = ar7_gpio_chip.regs + AR7_GPIO_ENABLE;
+
+ writel(readl(gpio_en) & ~(1 << gpio), gpio_en);
+
+ return 0;
+}
+
+static inline int ar7_gpio_disable_titan(unsigned gpio)
+{
+ void __iomem *gpio_en0 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_0;
+ void __iomem *gpio_en1 = titan_gpio_chip.regs + TITAN_GPIO_ENBL_1;
+
+ writel(readl(gpio >> 5 ? gpio_en1 : gpio_en0) & ~(1 << (gpio & 0x1f)),
+ gpio >> 5 ? gpio_en1 : gpio_en0);
+
+ return 0;
+}
+
+int ar7_gpio_disable(unsigned gpio)
+{
+ return ar7_is_titan() ? ar7_gpio_disable_titan(gpio) :
+ ar7_gpio_disable_ar7(gpio);
+}
+EXPORT_SYMBOL(ar7_gpio_disable);
+
+struct titan_gpio_cfg {
+ u32 reg;
+ u32 shift;
+ u32 func;
+};
+
+static struct titan_gpio_cfg titan_gpio_table[] = {
+ /* reg, start bit, mux value */
+ {4, 24, 1},
+ {4, 26, 1},
+ {4, 28, 1},
+ {4, 30, 1},
+ {5, 6, 1},
+ {5, 8, 1},
+ {5, 10, 1},
+ {5, 12, 1},
+ {7, 14, 3},
+ {7, 16, 3},
+ {7, 18, 3},
+ {7, 20, 3},
+ {7, 22, 3},
+ {7, 26, 3},
+ {7, 28, 3},
+ {7, 30, 3},
+ {8, 0, 3},
+ {8, 2, 3},
+ {8, 4, 3},
+ {8, 10, 3},
+ {8, 14, 3},
+ {8, 16, 3},
+ {8, 18, 3},
+ {8, 20, 3},
+ {9, 8, 3},
+ {9, 10, 3},
+ {9, 12, 3},
+ {9, 14, 3},
+ {9, 18, 3},
+ {9, 20, 3},
+ {9, 24, 3},
+ {9, 26, 3},
+ {9, 28, 3},
+ {9, 30, 3},
+ {10, 0, 3},
+ {10, 2, 3},
+ {10, 8, 3},
+ {10, 10, 3},
+ {10, 12, 3},
+ {10, 14, 3},
+ {13, 12, 3},
+ {13, 14, 3},
+ {13, 16, 3},
+ {13, 18, 3},
+ {13, 24, 3},
+ {13, 26, 3},
+ {13, 28, 3},
+ {13, 30, 3},
+ {14, 2, 3},
+ {14, 6, 3},
+ {14, 8, 3},
+ {14, 12, 3}
+};
+
+static int titan_gpio_pinsel(unsigned gpio)
+{
+ struct titan_gpio_cfg gpio_cfg;
+ u32 mux_status, pin_sel_reg, tmp;
+ void __iomem *pin_sel = (void __iomem *)KSEG1ADDR(AR7_REGS_PINSEL);
+
+ if (gpio >= ARRAY_SIZE(titan_gpio_table))
+ return -EINVAL;
+
+ gpio_cfg = titan_gpio_table[gpio];
+ pin_sel_reg = gpio_cfg.reg - 1;
+
+ mux_status = (readl(pin_sel + pin_sel_reg) >> gpio_cfg.shift) & 0x3;
+
+ /* Check the mux status */
+ if (!((mux_status == 0) || (mux_status == gpio_cfg.func)))
+ return 0;
+
+ /* Set the pin sel value */
+ tmp = readl(pin_sel + pin_sel_reg);
+ tmp |= ((gpio_cfg.func & 0x3) << gpio_cfg.shift);
+ writel(tmp, pin_sel + pin_sel_reg);
+
+ return 0;
+}
+
+/* Perform minimal Titan GPIO configuration */
+static void titan_gpio_init(void)
+{
+ unsigned i;
+
+ for (i = 44; i < 48; i++) {
+ titan_gpio_pinsel(i);
+ ar7_gpio_enable_titan(i);
+ titan_gpio_direction_input(&titan_gpio_chip.chip, i);
+ }
+}
+
+int __init ar7_gpio_init(void)
+{
+ int ret;
+ struct ar7_gpio_chip *gpch;
+ unsigned size;
+
+ if (!ar7_is_titan()) {
+ gpch = &ar7_gpio_chip;
+ size = 0x10;
+ } else {
+ gpch = &titan_gpio_chip;
+ size = 0x1f;
+ }
+
+ gpch->regs = ioremap_nocache(AR7_REGS_GPIO, size);
+ if (!gpch->regs) {
+ printk(KERN_ERR "%s: failed to ioremap regs\n",
+ gpch->chip.label);
+ return -ENOMEM;
+ }
+
+ ret = gpiochip_add(&gpch->chip);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to add gpiochip\n",
+ gpch->chip.label);
+ return ret;
+ }
+ printk(KERN_INFO "%s: registered %d GPIOs\n",
+ gpch->chip.label, gpch->chip.ngpio);
+
+ if (ar7_is_titan())
+ titan_gpio_init();
+
+ return ret;
+}
diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c
new file mode 100644
index 00000000..03db3daa
--- /dev/null
+++ b/arch/mips/ar7/irq.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2006,2007 Eugene Konev <ejka@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mach-ar7/ar7.h>
+
+#define EXCEPT_OFFSET 0x80
+#define PACE_OFFSET 0xA0
+#define CHNLS_OFFSET 0x200
+
+#define REG_OFFSET(irq, reg) ((irq) / 32 * 0x4 + reg * 0x10)
+#define SEC_REG_OFFSET(reg) (EXCEPT_OFFSET + reg * 0x8)
+#define SEC_SR_OFFSET (SEC_REG_OFFSET(0)) /* 0x80 */
+#define CR_OFFSET(irq) (REG_OFFSET(irq, 1)) /* 0x10 */
+#define SEC_CR_OFFSET (SEC_REG_OFFSET(1)) /* 0x88 */
+#define ESR_OFFSET(irq) (REG_OFFSET(irq, 2)) /* 0x20 */
+#define SEC_ESR_OFFSET (SEC_REG_OFFSET(2)) /* 0x90 */
+#define ECR_OFFSET(irq) (REG_OFFSET(irq, 3)) /* 0x30 */
+#define SEC_ECR_OFFSET (SEC_REG_OFFSET(3)) /* 0x98 */
+#define PIR_OFFSET (0x40)
+#define MSR_OFFSET (0x44)
+#define PM_OFFSET(irq) (REG_OFFSET(irq, 5)) /* 0x50 */
+#define TM_OFFSET(irq) (REG_OFFSET(irq, 6)) /* 0x60 */
+
+#define REG(addr) ((u32 *)(KSEG1ADDR(AR7_REGS_IRQ) + addr))
+
+#define CHNL_OFFSET(chnl) (CHNLS_OFFSET + (chnl * 4))
+
+static int ar7_irq_base;
+
+static void ar7_unmask_irq(struct irq_data *d)
+{
+ writel(1 << ((d->irq - ar7_irq_base) % 32),
+ REG(ESR_OFFSET(d->irq - ar7_irq_base)));
+}
+
+static void ar7_mask_irq(struct irq_data *d)
+{
+ writel(1 << ((d->irq - ar7_irq_base) % 32),
+ REG(ECR_OFFSET(d->irq - ar7_irq_base)));
+}
+
+static void ar7_ack_irq(struct irq_data *d)
+{
+ writel(1 << ((d->irq - ar7_irq_base) % 32),
+ REG(CR_OFFSET(d->irq - ar7_irq_base)));
+}
+
+static void ar7_unmask_sec_irq(struct irq_data *d)
+{
+ writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ESR_OFFSET));
+}
+
+static void ar7_mask_sec_irq(struct irq_data *d)
+{
+ writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_ECR_OFFSET));
+}
+
+static void ar7_ack_sec_irq(struct irq_data *d)
+{
+ writel(1 << (d->irq - ar7_irq_base - 40), REG(SEC_CR_OFFSET));
+}
+
+static struct irq_chip ar7_irq_type = {
+ .name = "AR7",
+ .irq_unmask = ar7_unmask_irq,
+ .irq_mask = ar7_mask_irq,
+ .irq_ack = ar7_ack_irq
+};
+
+static struct irq_chip ar7_sec_irq_type = {
+ .name = "AR7",
+ .irq_unmask = ar7_unmask_sec_irq,
+ .irq_mask = ar7_mask_sec_irq,
+ .irq_ack = ar7_ack_sec_irq,
+};
+
+static struct irqaction ar7_cascade_action = {
+ .handler = no_action,
+ .name = "AR7 cascade interrupt"
+};
+
+static void __init ar7_irq_init(int base)
+{
+ int i;
+ /*
+ * Disable interrupts and clear pending
+ */
+ writel(0xffffffff, REG(ECR_OFFSET(0)));
+ writel(0xff, REG(ECR_OFFSET(32)));
+ writel(0xffffffff, REG(SEC_ECR_OFFSET));
+ writel(0xffffffff, REG(CR_OFFSET(0)));
+ writel(0xff, REG(CR_OFFSET(32)));
+ writel(0xffffffff, REG(SEC_CR_OFFSET));
+
+ ar7_irq_base = base;
+
+ for (i = 0; i < 40; i++) {
+ writel(i, REG(CHNL_OFFSET(i)));
+ /* Primary IRQ's */
+ irq_set_chip_and_handler(base + i, &ar7_irq_type,
+ handle_level_irq);
+ /* Secondary IRQ's */
+ if (i < 32)
+ irq_set_chip_and_handler(base + i + 40,
+ &ar7_sec_irq_type,
+ handle_level_irq);
+ }
+
+ setup_irq(2, &ar7_cascade_action);
+ setup_irq(ar7_irq_base, &ar7_cascade_action);
+ set_c0_status(IE_IRQ0);
+}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+ ar7_irq_init(8);
+}
+
+static void ar7_cascade(void)
+{
+ u32 status;
+ int i, irq;
+
+ /* Primary IRQ's */
+ irq = readl(REG(PIR_OFFSET)) & 0x3f;
+ if (irq) {
+ do_IRQ(ar7_irq_base + irq);
+ return;
+ }
+
+ /* Secondary IRQ's are cascaded through primary '0' */
+ writel(1, REG(CR_OFFSET(irq)));
+ status = readl(REG(SEC_SR_OFFSET));
+ for (i = 0; i < 32; i++) {
+ if (status & 1) {
+ do_IRQ(ar7_irq_base + i + 40);
+ return;
+ }
+ status >>= 1;
+ }
+
+ spurious_interrupt();
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+ if (pending & STATUSF_IP7) /* cpu timer */
+ do_IRQ(7);
+ else if (pending & STATUSF_IP2) /* int0 hardware line */
+ ar7_cascade();
+ else
+ spurious_interrupt();
+}
diff --git a/arch/mips/ar7/memory.c b/arch/mips/ar7/memory.c
new file mode 100644
index 00000000..28abfeef
--- /dev/null
+++ b/arch/mips/ar7/memory.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2007 Eugene Konev <ejka@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/pfn.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+#include <linux/swap.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <asm/mach-ar7/ar7.h>
+#include <asm/mips-boards/prom.h>
+
+static int __init memsize(void)
+{
+ u32 size = (64 << 20);
+ u32 *addr = (u32 *)KSEG1ADDR(AR7_SDRAM_BASE + size - 4);
+ u32 *kernel_end = (u32 *)KSEG1ADDR(CPHYSADDR((u32)&_end));
+ u32 *tmpaddr = addr;
+
+ while (tmpaddr > kernel_end) {
+ *tmpaddr = (u32)tmpaddr;
+ size >>= 1;
+ tmpaddr -= size >> 2;
+ }
+
+ do {
+ tmpaddr += size >> 2;
+ if (*tmpaddr != (u32)tmpaddr)
+ break;
+ size <<= 1;
+ } while (size < (64 << 20));
+
+ writel((u32)tmpaddr, &addr);
+
+ return size;
+}
+
+void __init prom_meminit(void)
+{
+ unsigned long pages;
+
+ pages = memsize() >> PAGE_SHIFT;
+ add_memory_region(PHYS_OFFSET, pages << PAGE_SHIFT, BOOT_MEM_RAM);
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* Nothing to free */
+}
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
new file mode 100644
index 00000000..7d2fab39
--- /dev/null
+++ b/arch/mips/ar7/platform.c
@@ -0,0 +1,694 @@
+/*
+ * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2006,2007 Eugene Konev <ejka@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/vlynq.h>
+#include <linux/leds.h>
+#include <linux/string.h>
+#include <linux/etherdevice.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+
+#include <asm/addrspace.h>
+#include <asm/mach-ar7/ar7.h>
+#include <asm/mach-ar7/gpio.h>
+#include <asm/mach-ar7/prom.h>
+
+/*****************************************************************************
+ * VLYNQ Bus
+ ****************************************************************************/
+struct plat_vlynq_data {
+ struct plat_vlynq_ops ops;
+ int gpio_bit;
+ int reset_bit;
+};
+
+static int vlynq_on(struct vlynq_device *dev)
+{
+ int ret;
+ struct plat_vlynq_data *pdata = dev->dev.platform_data;
+
+ ret = gpio_request(pdata->gpio_bit, "vlynq");
+ if (ret)
+ goto out;
+
+ ar7_device_reset(pdata->reset_bit);
+
+ ret = ar7_gpio_disable(pdata->gpio_bit);
+ if (ret)
+ goto out_enabled;
+
+ ret = ar7_gpio_enable(pdata->gpio_bit);
+ if (ret)
+ goto out_enabled;
+
+ ret = gpio_direction_output(pdata->gpio_bit, 0);
+ if (ret)
+ goto out_gpio_enabled;
+
+ msleep(50);
+
+ gpio_set_value(pdata->gpio_bit, 1);
+
+ msleep(50);
+
+ return 0;
+
+out_gpio_enabled:
+ ar7_gpio_disable(pdata->gpio_bit);
+out_enabled:
+ ar7_device_disable(pdata->reset_bit);
+ gpio_free(pdata->gpio_bit);
+out:
+ return ret;
+}
+
+static void vlynq_off(struct vlynq_device *dev)
+{
+ struct plat_vlynq_data *pdata = dev->dev.platform_data;
+
+ ar7_gpio_disable(pdata->gpio_bit);
+ gpio_free(pdata->gpio_bit);
+ ar7_device_disable(pdata->reset_bit);
+}
+
+static struct resource vlynq_low_res[] = {
+ {
+ .name = "regs",
+ .flags = IORESOURCE_MEM,
+ .start = AR7_REGS_VLYNQ0,
+ .end = AR7_REGS_VLYNQ0 + 0xff,
+ },
+ {
+ .name = "irq",
+ .flags = IORESOURCE_IRQ,
+ .start = 29,
+ .end = 29,
+ },
+ {
+ .name = "mem",
+ .flags = IORESOURCE_MEM,
+ .start = 0x04000000,
+ .end = 0x04ffffff,
+ },
+ {
+ .name = "devirq",
+ .flags = IORESOURCE_IRQ,
+ .start = 80,
+ .end = 111,
+ },
+};
+
+static struct resource vlynq_high_res[] = {
+ {
+ .name = "regs",
+ .flags = IORESOURCE_MEM,
+ .start = AR7_REGS_VLYNQ1,
+ .end = AR7_REGS_VLYNQ1 + 0xff,
+ },
+ {
+ .name = "irq",
+ .flags = IORESOURCE_IRQ,
+ .start = 33,
+ .end = 33,
+ },
+ {
+ .name = "mem",
+ .flags = IORESOURCE_MEM,
+ .start = 0x0c000000,
+ .end = 0x0cffffff,
+ },
+ {
+ .name = "devirq",
+ .flags = IORESOURCE_IRQ,
+ .start = 112,
+ .end = 143,
+ },
+};
+
+static struct plat_vlynq_data vlynq_low_data = {
+ .ops = {
+ .on = vlynq_on,
+ .off = vlynq_off,
+ },
+ .reset_bit = 20,
+ .gpio_bit = 18,
+};
+
+static struct plat_vlynq_data vlynq_high_data = {
+ .ops = {
+ .on = vlynq_on,
+ .off = vlynq_off,
+ },
+ .reset_bit = 16,
+ .gpio_bit = 19,
+};
+
+static struct platform_device vlynq_low = {
+ .id = 0,
+ .name = "vlynq",
+ .dev = {
+ .platform_data = &vlynq_low_data,
+ },
+ .resource = vlynq_low_res,
+ .num_resources = ARRAY_SIZE(vlynq_low_res),
+};
+
+static struct platform_device vlynq_high = {
+ .id = 1,
+ .name = "vlynq",
+ .dev = {
+ .platform_data = &vlynq_high_data,
+ },
+ .resource = vlynq_high_res,
+ .num_resources = ARRAY_SIZE(vlynq_high_res),
+};
+
+/*****************************************************************************
+ * Flash
+ ****************************************************************************/
+static struct resource physmap_flash_resource = {
+ .name = "mem",
+ .flags = IORESOURCE_MEM,
+ .start = 0x10000000,
+ .end = 0x107fffff,
+};
+
+static struct physmap_flash_data physmap_flash_data = {
+ .width = 2,
+};
+
+static struct platform_device physmap_flash = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &physmap_flash_data,
+ },
+ .resource = &physmap_flash_resource,
+ .num_resources = 1,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct resource cpmac_low_res[] = {
+ {
+ .name = "regs",
+ .flags = IORESOURCE_MEM,
+ .start = AR7_REGS_MAC0,
+ .end = AR7_REGS_MAC0 + 0x7ff,
+ },
+ {
+ .name = "irq",
+ .flags = IORESOURCE_IRQ,
+ .start = 27,
+ .end = 27,
+ },
+};
+
+static struct resource cpmac_high_res[] = {
+ {
+ .name = "regs",
+ .flags = IORESOURCE_MEM,
+ .start = AR7_REGS_MAC1,
+ .end = AR7_REGS_MAC1 + 0x7ff,
+ },
+ {
+ .name = "irq",
+ .flags = IORESOURCE_IRQ,
+ .start = 41,
+ .end = 41,
+ },
+};
+
+static struct fixed_phy_status fixed_phy_status __initdata = {
+ .link = 1,
+ .speed = 100,
+ .duplex = 1,
+};
+
+static struct plat_cpmac_data cpmac_low_data = {
+ .reset_bit = 17,
+ .power_bit = 20,
+ .phy_mask = 0x80000000,
+};
+
+static struct plat_cpmac_data cpmac_high_data = {
+ .reset_bit = 21,
+ .power_bit = 22,
+ .phy_mask = 0x7fffffff,
+};
+
+static u64 cpmac_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device cpmac_low = {
+ .id = 0,
+ .name = "cpmac",
+ .dev = {
+ .dma_mask = &cpmac_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &cpmac_low_data,
+ },
+ .resource = cpmac_low_res,
+ .num_resources = ARRAY_SIZE(cpmac_low_res),
+};
+
+static struct platform_device cpmac_high = {
+ .id = 1,
+ .name = "cpmac",
+ .dev = {
+ .dma_mask = &cpmac_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &cpmac_high_data,
+ },
+ .resource = cpmac_high_res,
+ .num_resources = ARRAY_SIZE(cpmac_high_res),
+};
+
+static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
+{
+ char name[5], *mac;
+
+ sprintf(name, "mac%c", 'a' + instance);
+ mac = prom_getenv(name);
+ if (!mac && instance) {
+ sprintf(name, "mac%c", 'a');
+ mac = prom_getenv(name);
+ }
+
+ if (mac) {
+ if (sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+ &dev_addr[0], &dev_addr[1],
+ &dev_addr[2], &dev_addr[3],
+ &dev_addr[4], &dev_addr[5]) != 6) {
+ pr_warning("cannot parse mac address, "
+ "using random address\n");
+ random_ether_addr(dev_addr);
+ }
+ } else
+ random_ether_addr(dev_addr);
+}
+
+/*****************************************************************************
+ * USB
+ ****************************************************************************/
+static struct resource usb_res[] = {
+ {
+ .name = "regs",
+ .flags = IORESOURCE_MEM,
+ .start = AR7_REGS_USB,
+ .end = AR7_REGS_USB + 0xff,
+ },
+ {
+ .name = "irq",
+ .flags = IORESOURCE_IRQ,
+ .start = 32,
+ .end = 32,
+ },
+ {
+ .name = "mem",
+ .flags = IORESOURCE_MEM,
+ .start = 0x03400000,
+ .end = 0x03401fff,
+ },
+};
+
+static struct platform_device ar7_udc = {
+ .name = "ar7_udc",
+ .resource = usb_res,
+ .num_resources = ARRAY_SIZE(usb_res),
+};
+
+/*****************************************************************************
+ * LEDs
+ ****************************************************************************/
+static struct gpio_led default_leds[] = {
+ {
+ .name = "status",
+ .gpio = 8,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led titan_leds[] = {
+ { .name = "status", .gpio = 8, .active_low = 1, },
+ { .name = "wifi", .gpio = 13, .active_low = 1, },
+};
+
+static struct gpio_led dsl502t_leds[] = {
+ {
+ .name = "status",
+ .gpio = 9,
+ .active_low = 1,
+ },
+ {
+ .name = "ethernet",
+ .gpio = 7,
+ .active_low = 1,
+ },
+ {
+ .name = "usb",
+ .gpio = 12,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led dg834g_leds[] = {
+ {
+ .name = "ppp",
+ .gpio = 6,
+ .active_low = 1,
+ },
+ {
+ .name = "status",
+ .gpio = 7,
+ .active_low = 1,
+ },
+ {
+ .name = "adsl",
+ .gpio = 8,
+ .active_low = 1,
+ },
+ {
+ .name = "wifi",
+ .gpio = 12,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 14,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+};
+
+static struct gpio_led fb_sl_leds[] = {
+ {
+ .name = "1",
+ .gpio = 7,
+ },
+ {
+ .name = "2",
+ .gpio = 13,
+ .active_low = 1,
+ },
+ {
+ .name = "3",
+ .gpio = 10,
+ .active_low = 1,
+ },
+ {
+ .name = "4",
+ .gpio = 12,
+ .active_low = 1,
+ },
+ {
+ .name = "5",
+ .gpio = 9,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led fb_fon_leds[] = {
+ {
+ .name = "1",
+ .gpio = 8,
+ },
+ {
+ .name = "2",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ {
+ .name = "3",
+ .gpio = 5,
+ },
+ {
+ .name = "4",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "5",
+ .gpio = 11,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data ar7_led_data;
+
+static struct platform_device ar7_gpio_leds = {
+ .name = "leds-gpio",
+ .dev = {
+ .platform_data = &ar7_led_data,
+ }
+};
+
+static void __init detect_leds(void)
+{
+ char *prid, *usb_prod;
+
+ /* Default LEDs */
+ ar7_led_data.num_leds = ARRAY_SIZE(default_leds);
+ ar7_led_data.leds = default_leds;
+
+ /* FIXME: the whole thing is unreliable */
+ prid = prom_getenv("ProductID");
+ usb_prod = prom_getenv("usb_prod");
+
+ /* If we can't get the product id from PROM, use the default LEDs */
+ if (!prid)
+ return;
+
+ if (strstr(prid, "Fritz_Box_FON")) {
+ ar7_led_data.num_leds = ARRAY_SIZE(fb_fon_leds);
+ ar7_led_data.leds = fb_fon_leds;
+ } else if (strstr(prid, "Fritz_Box_")) {
+ ar7_led_data.num_leds = ARRAY_SIZE(fb_sl_leds);
+ ar7_led_data.leds = fb_sl_leds;
+ } else if ((!strcmp(prid, "AR7RD") || !strcmp(prid, "AR7DB"))
+ && usb_prod != NULL && strstr(usb_prod, "DSL-502T")) {
+ ar7_led_data.num_leds = ARRAY_SIZE(dsl502t_leds);
+ ar7_led_data.leds = dsl502t_leds;
+ } else if (strstr(prid, "DG834")) {
+ ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
+ ar7_led_data.leds = dg834g_leds;
+ } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
+ ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
+ ar7_led_data.leds = titan_leds;
+ }
+}
+
+/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static struct resource ar7_wdt_res = {
+ .name = "regs",
+ .flags = IORESOURCE_MEM,
+ .start = -1, /* Filled at runtime */
+ .end = -1, /* Filled at runtime */
+};
+
+static struct platform_device ar7_wdt = {
+ .name = "ar7_wdt",
+ .resource = &ar7_wdt_res,
+ .num_resources = 1,
+};
+
+/*****************************************************************************
+ * Init
+ ****************************************************************************/
+static int __init ar7_register_uarts(void)
+{
+#ifdef CONFIG_SERIAL_8250
+ static struct uart_port uart_port __initdata;
+ struct clk *bus_clk;
+ int res;
+
+ memset(&uart_port, 0, sizeof(struct uart_port));
+
+ bus_clk = clk_get(NULL, "bus");
+ if (IS_ERR(bus_clk))
+ panic("unable to get bus clk\n");
+
+ uart_port.type = PORT_AR7;
+ uart_port.uartclk = clk_get_rate(bus_clk) / 2;
+ uart_port.iotype = UPIO_MEM32;
+ uart_port.regshift = 2;
+
+ uart_port.line = 0;
+ uart_port.irq = AR7_IRQ_UART0;
+ uart_port.mapbase = AR7_REGS_UART0;
+ uart_port.membase = ioremap(uart_port.mapbase, 256);
+
+ res = early_serial_setup(&uart_port);
+ if (res)
+ return res;
+
+ /* Only TNETD73xx have a second serial port */
+ if (ar7_has_second_uart()) {
+ uart_port.line = 1;
+ uart_port.irq = AR7_IRQ_UART1;
+ uart_port.mapbase = UR8_REGS_UART1;
+ uart_port.membase = ioremap(uart_port.mapbase, 256);
+
+ res = early_serial_setup(&uart_port);
+ if (res)
+ return res;
+ }
+#endif
+
+ return 0;
+}
+
+static void __init titan_fixup_devices(void)
+{
+ /* Set vlynq0 data */
+ vlynq_low_data.reset_bit = 15;
+ vlynq_low_data.gpio_bit = 14;
+
+ /* Set vlynq1 data */
+ vlynq_high_data.reset_bit = 16;
+ vlynq_high_data.gpio_bit = 7;
+
+ /* Set vlynq0 resources */
+ vlynq_low_res[0].start = TITAN_REGS_VLYNQ0;
+ vlynq_low_res[0].end = TITAN_REGS_VLYNQ0 + 0xff;
+ vlynq_low_res[1].start = 33;
+ vlynq_low_res[1].end = 33;
+ vlynq_low_res[2].start = 0x0c000000;
+ vlynq_low_res[2].end = 0x0fffffff;
+ vlynq_low_res[3].start = 80;
+ vlynq_low_res[3].end = 111;
+
+ /* Set vlynq1 resources */
+ vlynq_high_res[0].start = TITAN_REGS_VLYNQ1;
+ vlynq_high_res[0].end = TITAN_REGS_VLYNQ1 + 0xff;
+ vlynq_high_res[1].start = 34;
+ vlynq_high_res[1].end = 34;
+ vlynq_high_res[2].start = 0x40000000;
+ vlynq_high_res[2].end = 0x43ffffff;
+ vlynq_high_res[3].start = 112;
+ vlynq_high_res[3].end = 143;
+
+ /* Set cpmac0 data */
+ cpmac_low_data.phy_mask = 0x40000000;
+
+ /* Set cpmac1 data */
+ cpmac_high_data.phy_mask = 0x80000000;
+
+ /* Set cpmac0 resources */
+ cpmac_low_res[0].start = TITAN_REGS_MAC0;
+ cpmac_low_res[0].end = TITAN_REGS_MAC0 + 0x7ff;
+
+ /* Set cpmac1 resources */
+ cpmac_high_res[0].start = TITAN_REGS_MAC1;
+ cpmac_high_res[0].end = TITAN_REGS_MAC1 + 0x7ff;
+}
+
+static int __init ar7_register_devices(void)
+{
+ void __iomem *bootcr;
+ u32 val;
+ int res;
+
+ res = ar7_register_uarts();
+ if (res)
+ pr_err("unable to setup uart(s): %d\n", res);
+
+ res = platform_device_register(&physmap_flash);
+ if (res)
+ pr_warning("unable to register physmap-flash: %d\n", res);
+
+ if (ar7_is_titan())
+ titan_fixup_devices();
+
+ ar7_device_disable(vlynq_low_data.reset_bit);
+ res = platform_device_register(&vlynq_low);
+ if (res)
+ pr_warning("unable to register vlynq-low: %d\n", res);
+
+ if (ar7_has_high_vlynq()) {
+ ar7_device_disable(vlynq_high_data.reset_bit);
+ res = platform_device_register(&vlynq_high);
+ if (res)
+ pr_warning("unable to register vlynq-high: %d\n", res);
+ }
+
+ if (ar7_has_high_cpmac()) {
+ res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
+ if (!res) {
+ cpmac_get_mac(1, cpmac_high_data.dev_addr);
+
+ res = platform_device_register(&cpmac_high);
+ if (res)
+ pr_warning("unable to register cpmac-high: %d\n", res);
+ } else
+ pr_warning("unable to add cpmac-high phy: %d\n", res);
+ } else
+ cpmac_low_data.phy_mask = 0xffffffff;
+
+ res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
+ if (!res) {
+ cpmac_get_mac(0, cpmac_low_data.dev_addr);
+ res = platform_device_register(&cpmac_low);
+ if (res)
+ pr_warning("unable to register cpmac-low: %d\n", res);
+ } else
+ pr_warning("unable to add cpmac-low phy: %d\n", res);
+
+ detect_leds();
+ res = platform_device_register(&ar7_gpio_leds);
+ if (res)
+ pr_warning("unable to register leds: %d\n", res);
+
+ res = platform_device_register(&ar7_udc);
+ if (res)
+ pr_warning("unable to register usb slave: %d\n", res);
+
+ /* Register watchdog only if enabled in hardware */
+ bootcr = ioremap_nocache(AR7_REGS_DCL, 4);
+ val = readl(bootcr);
+ iounmap(bootcr);
+ if (val & AR7_WDT_HW_ENA) {
+ if (ar7_has_high_vlynq())
+ ar7_wdt_res.start = UR8_REGS_WDT;
+ else
+ ar7_wdt_res.start = AR7_REGS_WDT;
+
+ ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
+ res = platform_device_register(&ar7_wdt);
+ if (res)
+ pr_warning("unable to register watchdog: %d\n", res);
+ }
+
+ return 0;
+}
+device_initcall(ar7_register_devices);
diff --git a/arch/mips/ar7/prom.c b/arch/mips/ar7/prom.c
new file mode 100644
index 00000000..23818d29
--- /dev/null
+++ b/arch/mips/ar7/prom.c
@@ -0,0 +1,270 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Putting things on the screen/serial line using YAMONs facilities.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/serial_reg.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <asm/bootinfo.h>
+
+#include <asm/mach-ar7/ar7.h>
+#include <asm/mach-ar7/prom.h>
+
+#define MAX_ENTRY 80
+
+struct env_var {
+ char *name;
+ char *value;
+};
+
+static struct env_var adam2_env[MAX_ENTRY];
+
+char *prom_getenv(const char *name)
+{
+ int i;
+
+ for (i = 0; (i < MAX_ENTRY) && adam2_env[i].name; i++)
+ if (!strcmp(name, adam2_env[i].name))
+ return adam2_env[i].value;
+
+ return NULL;
+}
+EXPORT_SYMBOL(prom_getenv);
+
+static void __init ar7_init_cmdline(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE);
+ if (i < (argc - 1))
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+ }
+}
+
+struct psbl_rec {
+ u32 psbl_size;
+ u32 env_base;
+ u32 env_size;
+ u32 ffs_base;
+ u32 ffs_size;
+};
+
+static __initdata char psp_env_version[] = "TIENV0.8";
+
+struct psp_env_chunk {
+ u8 num;
+ u8 ctrl;
+ u16 csum;
+ u8 len;
+ char data[11];
+} __attribute__ ((packed));
+
+struct psp_var_map_entry {
+ u8 num;
+ char *value;
+};
+
+static struct psp_var_map_entry psp_var_map[] = {
+ { 1, "cpufrequency" },
+ { 2, "memsize" },
+ { 3, "flashsize" },
+ { 4, "modetty0" },
+ { 5, "modetty1" },
+ { 8, "maca" },
+ { 9, "macb" },
+ { 28, "sysfrequency" },
+ { 38, "mipsfrequency" },
+};
+
+/*
+
+Well-known variable (num is looked up in table above for matching variable name)
+Example: cpufrequency=211968000
++----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
+| 01 |CTRL|CHECKSUM | 01 | _2 | _1 | _1 | _9 | _6 | _8 | _0 | _0 | _0 | \0 | FF
++----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
+
+Name=Value pair in a single chunk
+Example: NAME=VALUE
++----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
+| 00 |CTRL|CHECKSUM | 01 | _N | _A | _M | _E | _0 | _V | _A | _L | _U | _E | \0
++----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
+
+Name=Value pair in 2 chunks (len is the number of chunks)
+Example: bootloaderVersion=1.3.7.15
++----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
+| 00 |CTRL|CHECKSUM | 02 | _b | _o | _o | _t | _l | _o | _a | _d | _e | _r | _V
++----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
+| _e | _r | _s | _i | _o | _n | \0 | _1 | _. | _3 | _. | _7 | _. | _1 | _5 | \0
++----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+---
+
+Data is padded with 0xFF
+
+*/
+
+#define PSP_ENV_SIZE 4096
+
+static char psp_env_data[PSP_ENV_SIZE] = { 0, };
+
+static char * __init lookup_psp_var_map(u8 num)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(psp_var_map); i++)
+ if (psp_var_map[i].num == num)
+ return psp_var_map[i].value;
+
+ return NULL;
+}
+
+static void __init add_adam2_var(char *name, char *value)
+{
+ int i;
+
+ for (i = 0; i < MAX_ENTRY; i++) {
+ if (!adam2_env[i].name) {
+ adam2_env[i].name = name;
+ adam2_env[i].value = value;
+ return;
+ } else if (!strcmp(adam2_env[i].name, name)) {
+ adam2_env[i].value = value;
+ return;
+ }
+ }
+}
+
+static int __init parse_psp_env(void *psp_env_base)
+{
+ int i, n;
+ char *name, *value;
+ struct psp_env_chunk *chunks = (struct psp_env_chunk *)psp_env_data;
+
+ memcpy_fromio(chunks, psp_env_base, PSP_ENV_SIZE);
+
+ i = 1;
+ n = PSP_ENV_SIZE / sizeof(struct psp_env_chunk);
+ while (i < n) {
+ if ((chunks[i].num == 0xff) || ((i + chunks[i].len) > n))
+ break;
+ value = chunks[i].data;
+ if (chunks[i].num) {
+ name = lookup_psp_var_map(chunks[i].num);
+ } else {
+ name = value;
+ value += strlen(name) + 1;
+ }
+ if (name)
+ add_adam2_var(name, value);
+ i += chunks[i].len;
+ }
+ return 0;
+}
+
+static void __init ar7_init_env(struct env_var *env)
+{
+ int i;
+ struct psbl_rec *psbl = (struct psbl_rec *)(KSEG1ADDR(0x14000300));
+ void *psp_env = (void *)KSEG1ADDR(psbl->env_base);
+
+ if (strcmp(psp_env, psp_env_version) == 0) {
+ parse_psp_env(psp_env);
+ } else {
+ for (i = 0; i < MAX_ENTRY; i++, env++)
+ if (env->name)
+ add_adam2_var(env->name, env->value);
+ }
+}
+
+static void __init console_config(void)
+{
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ char console_string[40];
+ int baud = 0;
+ char parity = '\0', bits = '\0', flow = '\0';
+ char *s, *p;
+
+ if (strstr(arcs_cmdline, "console="))
+ return;
+
+ s = prom_getenv("modetty0");
+ if (s) {
+ baud = simple_strtoul(s, &p, 10);
+ s = p;
+ if (*s == ',')
+ s++;
+ if (*s)
+ parity = *s++;
+ if (*s == ',')
+ s++;
+ if (*s)
+ bits = *s++;
+ if (*s == ',')
+ s++;
+ if (*s == 'h')
+ flow = 'r';
+ }
+
+ if (baud == 0)
+ baud = 38400;
+ if (parity != 'n' && parity != 'o' && parity != 'e')
+ parity = 'n';
+ if (bits != '7' && bits != '8')
+ bits = '8';
+
+ if (flow == 'r')
+ sprintf(console_string, " console=ttyS0,%d%c%c%c", baud,
+ parity, bits, flow);
+ else
+ sprintf(console_string, " console=ttyS0,%d%c%c", baud, parity,
+ bits);
+ strlcat(arcs_cmdline, console_string, COMMAND_LINE_SIZE);
+#endif
+}
+
+void __init prom_init(void)
+{
+ ar7_init_cmdline(fw_arg0, (char **)fw_arg1);
+ ar7_init_env((struct env_var *)fw_arg2);
+ console_config();
+
+ ar7_gpio_init();
+}
+
+#define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4)))
+static inline unsigned int serial_in(int offset)
+{
+ return readl((void *)PORT(offset));
+}
+
+static inline void serial_out(int offset, int value)
+{
+ writel(value, (void *)PORT(offset));
+}
+
+int prom_putchar(char c)
+{
+ while ((serial_in(UART_LSR) & UART_LSR_TEMT) == 0)
+ ;
+ serial_out(UART_TX, c);
+ return 1;
+}
diff --git a/arch/mips/ar7/setup.c b/arch/mips/ar7/setup.c
new file mode 100644
index 00000000..f20b53e5
--- /dev/null
+++ b/arch/mips/ar7/setup.c
@@ -0,0 +1,106 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+#include <linux/time.h>
+
+#include <asm/reboot.h>
+#include <asm/mach-ar7/ar7.h>
+#include <asm/mach-ar7/prom.h>
+#include <asm/mach-ar7/gpio.h>
+
+static void ar7_machine_restart(char *command)
+{
+ u32 *softres_reg = ioremap(AR7_REGS_RESET + AR7_RESET_SOFTWARE, 1);
+
+ writel(1, softres_reg);
+}
+
+static void ar7_machine_halt(void)
+{
+ while (1)
+ ;
+}
+
+static void ar7_machine_power_off(void)
+{
+ u32 *power_reg = (u32 *)ioremap(AR7_REGS_POWER, 1);
+ u32 power_state = readl(power_reg) | (3 << 30);
+
+ writel(power_state, power_reg);
+ ar7_machine_halt();
+}
+
+const char *get_system_type(void)
+{
+ u16 chip_id = ar7_chip_id();
+ u16 titan_variant_id = titan_chip_id();
+
+ switch (chip_id) {
+ case AR7_CHIP_7100:
+ return "TI AR7 (TNETD7100)";
+ case AR7_CHIP_7200:
+ return "TI AR7 (TNETD7200)";
+ case AR7_CHIP_7300:
+ return "TI AR7 (TNETD7300)";
+ case AR7_CHIP_TITAN:
+ switch (titan_variant_id) {
+ case TITAN_CHIP_1050:
+ return "TI AR7 (TNETV1050)";
+ case TITAN_CHIP_1055:
+ return "TI AR7 (TNETV1055)";
+ case TITAN_CHIP_1056:
+ return "TI AR7 (TNETV1056)";
+ case TITAN_CHIP_1060:
+ return "TI AR7 (TNETV1060)";
+ }
+ default:
+ return "TI AR7 (unknown)";
+ }
+}
+
+static int __init ar7_init_console(void)
+{
+ return 0;
+}
+console_initcall(ar7_init_console);
+
+/*
+ * Initializes basic routines and structures pointers, memory size (as
+ * given by the bios and saves the command line.
+ */
+void __init plat_mem_setup(void)
+{
+ unsigned long io_base;
+
+ _machine_restart = ar7_machine_restart;
+ _machine_halt = ar7_machine_halt;
+ pm_power_off = ar7_machine_power_off;
+ panic_timeout = 3;
+
+ io_base = (unsigned long)ioremap(AR7_REGS_BASE, 0x10000);
+ if (!io_base)
+ panic("Can't remap IO base!\n");
+ set_io_port_base(io_base);
+
+ prom_meminit();
+
+ printk(KERN_INFO "%s, ID: 0x%04x, Revision: 0x%02x\n",
+ get_system_type(), ar7_chip_id(), ar7_chip_rev());
+}
diff --git a/arch/mips/ar7/time.c b/arch/mips/ar7/time.c
new file mode 100644
index 00000000..22c93213
--- /dev/null
+++ b/arch/mips/ar7/time.c
@@ -0,0 +1,43 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+#include <asm/mach-ar7/ar7.h>
+
+void __init plat_time_init(void)
+{
+ struct clk *cpu_clk;
+
+ /* Initialize ar7 clocks so the CPU clock frequency is correct */
+ ar7_init_clocks();
+
+ cpu_clk = clk_get(NULL, "cpu");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_ERR "unable to get cpu clock\n");
+ return;
+ }
+
+ mips_hpt_frequency = clk_get_rate(cpu_clk) / 2;
+}
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
new file mode 100644
index 00000000..47707410
--- /dev/null
+++ b/arch/mips/ath79/Kconfig
@@ -0,0 +1,55 @@
+if ATH79
+
+menu "Atheros AR71XX/AR724X/AR913X machine selection"
+
+config ATH79_MACH_AP81
+ bool "Atheros AP81 reference board"
+ select SOC_AR913X
+ select ATH79_DEV_AR913X_WMAC
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
+ help
+ Say 'Y' here if you want your kernel to support the
+ Atheros AP81 reference board.
+
+config ATH79_MACH_PB44
+ bool "Atheros PB44 reference board"
+ select SOC_AR71XX
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
+ help
+ Say 'Y' here if you want your kernel to support the
+ Atheros PB44 reference board.
+
+endmenu
+
+config SOC_AR71XX
+ select USB_ARCH_HAS_EHCI
+ select USB_ARCH_HAS_OHCI
+ def_bool n
+
+config SOC_AR724X
+ select USB_ARCH_HAS_EHCI
+ select USB_ARCH_HAS_OHCI
+ def_bool n
+
+config SOC_AR913X
+ select USB_ARCH_HAS_EHCI
+ def_bool n
+
+config ATH79_DEV_AR913X_WMAC
+ depends on SOC_AR913X
+ def_bool n
+
+config ATH79_DEV_GPIO_BUTTONS
+ def_bool n
+
+config ATH79_DEV_LEDS_GPIO
+ def_bool n
+
+config ATH79_DEV_SPI
+ def_bool n
+
+endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
new file mode 100644
index 00000000..c33d4653
--- /dev/null
+++ b/arch/mips/ath79/Makefile
@@ -0,0 +1,28 @@
+#
+# Makefile for the Atheros AR71XX/AR724X/AR913X specific parts of the kernel
+#
+# Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+# Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+
+obj-y := prom.o setup.o irq.o common.o clock.o gpio.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+#
+# Devices
+#
+obj-y += dev-common.o
+obj-$(CONFIG_ATH79_DEV_AR913X_WMAC) += dev-ar913x-wmac.o
+obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
+obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
+obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o
+
+#
+# Machines
+#
+obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
+obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
diff --git a/arch/mips/ath79/Platform b/arch/mips/ath79/Platform
new file mode 100644
index 00000000..2bd66364
--- /dev/null
+++ b/arch/mips/ath79/Platform
@@ -0,0 +1,7 @@
+#
+# Atheros AR71xx/AR724x/AR913x
+#
+
+platform-$(CONFIG_ATH79) += ath79/
+cflags-$(CONFIG_ATH79) += -I$(srctree)/arch/mips/include/asm/mach-ath79
+load-$(CONFIG_ATH79) = 0xffffffff80060000
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
new file mode 100644
index 00000000..680bde99
--- /dev/null
+++ b/arch/mips/ath79/clock.c
@@ -0,0 +1,183 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common routines
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+#define AR71XX_BASE_FREQ 40000000
+#define AR724X_BASE_FREQ 5000000
+#define AR913X_BASE_FREQ 5000000
+
+struct clk {
+ unsigned long rate;
+};
+
+static struct clk ath79_ref_clk;
+static struct clk ath79_cpu_clk;
+static struct clk ath79_ddr_clk;
+static struct clk ath79_ahb_clk;
+static struct clk ath79_wdt_clk;
+static struct clk ath79_uart_clk;
+
+static void __init ar71xx_clocks_init(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ ath79_ref_clk.rate = AR71XX_BASE_FREQ;
+
+ pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
+ freq = div * ath79_ref_clk.rate;
+
+ div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
+ ath79_cpu_clk.rate = freq / div;
+
+ div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
+ ath79_ddr_clk.rate = freq / div;
+
+ div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+ ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+ ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+static void __init ar724x_clocks_init(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ ath79_ref_clk.rate = AR724X_BASE_FREQ;
+ pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
+ freq = div * ath79_ref_clk.rate;
+
+ div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
+ freq *= div;
+
+ ath79_cpu_clk.rate = freq;
+
+ div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
+ ath79_ddr_clk.rate = freq / div;
+
+ div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+ ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+ ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+static void __init ar913x_clocks_init(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ ath79_ref_clk.rate = AR913X_BASE_FREQ;
+ pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
+ freq = div * ath79_ref_clk.rate;
+
+ ath79_cpu_clk.rate = freq;
+
+ div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
+ ath79_ddr_clk.rate = freq / div;
+
+ div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_clk.rate = ath79_cpu_clk.rate / div;
+
+ ath79_wdt_clk.rate = ath79_ahb_clk.rate;
+ ath79_uart_clk.rate = ath79_ahb_clk.rate;
+}
+
+void __init ath79_clocks_init(void)
+{
+ if (soc_is_ar71xx())
+ ar71xx_clocks_init();
+ else if (soc_is_ar724x())
+ ar724x_clocks_init();
+ else if (soc_is_ar913x())
+ ar913x_clocks_init();
+ else
+ BUG();
+
+ pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, "
+ "Ref:%lu.%03luMHz",
+ ath79_cpu_clk.rate / 1000000,
+ (ath79_cpu_clk.rate / 1000) % 1000,
+ ath79_ddr_clk.rate / 1000000,
+ (ath79_ddr_clk.rate / 1000) % 1000,
+ ath79_ahb_clk.rate / 1000000,
+ (ath79_ahb_clk.rate / 1000) % 1000,
+ ath79_ref_clk.rate / 1000000,
+ (ath79_ref_clk.rate / 1000) % 1000);
+}
+
+/*
+ * Linux clock API
+ */
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ if (!strcmp(id, "ref"))
+ return &ath79_ref_clk;
+
+ if (!strcmp(id, "cpu"))
+ return &ath79_cpu_clk;
+
+ if (!strcmp(id, "ddr"))
+ return &ath79_ddr_clk;
+
+ if (!strcmp(id, "ahb"))
+ return &ath79_ahb_clk;
+
+ if (!strcmp(id, "wdt"))
+ return &ath79_wdt_clk;
+
+ if (!strcmp(id, "uart"))
+ return &ath79_uart_clk;
+
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
new file mode 100644
index 00000000..58f60e72
--- /dev/null
+++ b/arch/mips/ath79/common.c
@@ -0,0 +1,97 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common routines
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static DEFINE_SPINLOCK(ath79_device_reset_lock);
+
+u32 ath79_cpu_freq;
+EXPORT_SYMBOL_GPL(ath79_cpu_freq);
+
+u32 ath79_ahb_freq;
+EXPORT_SYMBOL_GPL(ath79_ahb_freq);
+
+u32 ath79_ddr_freq;
+EXPORT_SYMBOL_GPL(ath79_ddr_freq);
+
+enum ath79_soc_type ath79_soc;
+
+void __iomem *ath79_pll_base;
+void __iomem *ath79_reset_base;
+EXPORT_SYMBOL_GPL(ath79_reset_base);
+void __iomem *ath79_ddr_base;
+
+void ath79_ddr_wb_flush(u32 reg)
+{
+ void __iomem *flush_reg = ath79_ddr_base + reg;
+
+ /* Flush the DDR write buffer. */
+ __raw_writel(0x1, flush_reg);
+ while (__raw_readl(flush_reg) & 0x1)
+ ;
+
+ /* It must be run twice. */
+ __raw_writel(0x1, flush_reg);
+ while (__raw_readl(flush_reg) & 0x1)
+ ;
+}
+EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush);
+
+void ath79_device_reset_set(u32 mask)
+{
+ unsigned long flags;
+ u32 reg;
+ u32 t;
+
+ if (soc_is_ar71xx())
+ reg = AR71XX_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar724x())
+ reg = AR724X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar913x())
+ reg = AR913X_RESET_REG_RESET_MODULE;
+ else
+ BUG();
+
+ spin_lock_irqsave(&ath79_device_reset_lock, flags);
+ t = ath79_reset_rr(reg);
+ ath79_reset_wr(reg, t | mask);
+ spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_set);
+
+void ath79_device_reset_clear(u32 mask)
+{
+ unsigned long flags;
+ u32 reg;
+ u32 t;
+
+ if (soc_is_ar71xx())
+ reg = AR71XX_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar724x())
+ reg = AR724X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar913x())
+ reg = AR913X_RESET_REG_RESET_MODULE;
+ else
+ BUG();
+
+ spin_lock_irqsave(&ath79_device_reset_lock, flags);
+ t = ath79_reset_rr(reg);
+ ath79_reset_wr(reg, t & ~mask);
+ spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_clear);
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
new file mode 100644
index 00000000..561906c2
--- /dev/null
+++ b/arch/mips/ath79/common.h
@@ -0,0 +1,31 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ATH79_COMMON_H
+#define __ATH79_COMMON_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024)
+#define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024)
+
+void ath79_clocks_init(void);
+void ath79_ddr_wb_flush(unsigned int reg);
+
+void ath79_gpio_function_enable(u32 mask);
+void ath79_gpio_function_disable(u32 mask);
+void ath79_gpio_function_setup(u32 set, u32 clear);
+void ath79_gpio_init(void);
+
+#endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/dev-ar913x-wmac.c b/arch/mips/ath79/dev-ar913x-wmac.c
new file mode 100644
index 00000000..48f425a5
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.c
@@ -0,0 +1,60 @@
+/*
+ * Atheros AR913X SoC built-in WMAC device support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-ar913x-wmac.h"
+
+static struct ath9k_platform_data ar913x_wmac_data;
+
+static struct resource ar913x_wmac_resources[] = {
+ {
+ .start = AR913X_WMAC_BASE,
+ .end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = ATH79_CPU_IRQ_IP2,
+ .end = ATH79_CPU_IRQ_IP2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ar913x_wmac_device = {
+ .name = "ath9k",
+ .id = -1,
+ .resource = ar913x_wmac_resources,
+ .num_resources = ARRAY_SIZE(ar913x_wmac_resources),
+ .dev = {
+ .platform_data = &ar913x_wmac_data,
+ },
+};
+
+void __init ath79_register_ar913x_wmac(u8 *cal_data)
+{
+ if (cal_data)
+ memcpy(ar913x_wmac_data.eeprom_data, cal_data,
+ sizeof(ar913x_wmac_data.eeprom_data));
+
+ /* reset the WMAC */
+ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ platform_device_register(&ar913x_wmac_device);
+}
diff --git a/arch/mips/ath79/dev-ar913x-wmac.h b/arch/mips/ath79/dev-ar913x-wmac.h
new file mode 100644
index 00000000..579d562b
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.h
@@ -0,0 +1,17 @@
+/*
+ * Atheros AR913X SoC built-in WMAC device support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_AR913X_WMAC_H
+#define _ATH79_DEV_AR913X_WMAC_H
+
+void ath79_register_ar913x_wmac(u8 *cal_data);
+
+#endif /* _ATH79_DEV_AR913X_WMAC_H */
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
new file mode 100644
index 00000000..3b82e325
--- /dev/null
+++ b/arch/mips/ath79/dev-common.c
@@ -0,0 +1,77 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common devices
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+
+static struct resource ath79_uart_resources[] = {
+ {
+ .start = AR71XX_UART_BASE,
+ .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+static struct plat_serial8250_port ath79_uart_data[] = {
+ {
+ .mapbase = AR71XX_UART_BASE,
+ .irq = ATH79_MISC_IRQ_UART,
+ .flags = AR71XX_UART_FLAGS,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ }, {
+ /* terminating entry */
+ }
+};
+
+static struct platform_device ath79_uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .resource = ath79_uart_resources,
+ .num_resources = ARRAY_SIZE(ath79_uart_resources),
+ .dev = {
+ .platform_data = ath79_uart_data
+ },
+};
+
+void __init ath79_register_uart(void)
+{
+ struct clk *clk;
+
+ clk = clk_get(NULL, "uart");
+ if (IS_ERR(clk))
+ panic("unable to get UART clock, err=%ld", PTR_ERR(clk));
+
+ ath79_uart_data[0].uartclk = clk_get_rate(clk);
+ platform_device_register(&ath79_uart_device);
+}
+
+static struct platform_device ath79_wdt_device = {
+ .name = "ath79-wdt",
+ .id = -1,
+};
+
+void __init ath79_register_wdt(void)
+{
+ platform_device_register(&ath79_wdt_device);
+}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
new file mode 100644
index 00000000..0f514e1a
--- /dev/null
+++ b/arch/mips/ath79/dev-common.h
@@ -0,0 +1,18 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common devices
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_COMMON_H
+#define _ATH79_DEV_COMMON_H
+
+void ath79_register_uart(void);
+void ath79_register_wdt(void);
+
+#endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c
new file mode 100644
index 00000000..4b0168a1
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.c
@@ -0,0 +1,58 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "linux/init.h"
+#include "linux/slab.h"
+#include <linux/platform_device.h>
+
+#include "dev-gpio-buttons.h"
+
+void __init ath79_register_gpio_keys_polled(int id,
+ unsigned poll_interval,
+ unsigned nbuttons,
+ struct gpio_keys_button *buttons)
+{
+ struct platform_device *pdev;
+ struct gpio_keys_platform_data pdata;
+ struct gpio_keys_button *p;
+ int err;
+
+ p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return;
+
+ memcpy(p, buttons, nbuttons * sizeof(*p));
+
+ pdev = platform_device_alloc("gpio-keys-polled", id);
+ if (!pdev)
+ goto err_free_buttons;
+
+ memset(&pdata, 0, sizeof(pdata));
+ pdata.poll_interval = poll_interval;
+ pdata.nbuttons = nbuttons;
+ pdata.buttons = p;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put_pdev;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put_pdev;
+
+ return;
+
+err_put_pdev:
+ platform_device_put(pdev);
+
+err_free_buttons:
+ kfree(p);
+}
diff --git a/arch/mips/ath79/dev-gpio-buttons.h b/arch/mips/ath79/dev-gpio-buttons.h
new file mode 100644
index 00000000..481847ac
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.h
@@ -0,0 +1,23 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_GPIO_BUTTONS_H
+#define _ATH79_DEV_GPIO_BUTTONS_H
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+void ath79_register_gpio_keys_polled(int id,
+ unsigned poll_interval,
+ unsigned nbuttons,
+ struct gpio_keys_button *buttons);
+
+#endif /* _ATH79_DEV_GPIO_BUTTONS_H */
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c
new file mode 100644
index 00000000..cdade68d
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.c
@@ -0,0 +1,56 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "dev-leds-gpio.h"
+
+void __init ath79_register_leds_gpio(int id,
+ unsigned num_leds,
+ struct gpio_led *leds)
+{
+ struct platform_device *pdev;
+ struct gpio_led_platform_data pdata;
+ struct gpio_led *p;
+ int err;
+
+ p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return;
+
+ memcpy(p, leds, num_leds * sizeof(*p));
+
+ pdev = platform_device_alloc("leds-gpio", id);
+ if (!pdev)
+ goto err_free_leds;
+
+ memset(&pdata, 0, sizeof(pdata));
+ pdata.num_leds = num_leds;
+ pdata.leds = p;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put_pdev;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put_pdev;
+
+ return;
+
+err_put_pdev:
+ platform_device_put(pdev);
+
+err_free_leds:
+ kfree(p);
+}
diff --git a/arch/mips/ath79/dev-leds-gpio.h b/arch/mips/ath79/dev-leds-gpio.h
new file mode 100644
index 00000000..6e5d8851
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.h
@@ -0,0 +1,21 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_LEDS_GPIO_H
+#define _ATH79_DEV_LEDS_GPIO_H
+
+#include <linux/leds.h>
+
+void ath79_register_leds_gpio(int id,
+ unsigned num_leds,
+ struct gpio_led *leds);
+
+#endif /* _ATH79_DEV_LEDS_GPIO_H */
diff --git a/arch/mips/ath79/dev-spi.c b/arch/mips/ath79/dev-spi.c
new file mode 100644
index 00000000..aa30163e
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.c
@@ -0,0 +1,38 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-spi.h"
+
+static struct resource ath79_spi_resources[] = {
+ {
+ .start = AR71XX_SPI_BASE,
+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ath79_spi_device = {
+ .name = "ath79-spi",
+ .id = -1,
+ .resource = ath79_spi_resources,
+ .num_resources = ARRAY_SIZE(ath79_spi_resources),
+};
+
+void __init ath79_register_spi(struct ath79_spi_platform_data *pdata,
+ struct spi_board_info const *info,
+ unsigned n)
+{
+ spi_register_board_info(info, n);
+ ath79_spi_device.dev.platform_data = pdata;
+ platform_device_register(&ath79_spi_device);
+}
diff --git a/arch/mips/ath79/dev-spi.h b/arch/mips/ath79/dev-spi.h
new file mode 100644
index 00000000..d732565c
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.h
@@ -0,0 +1,22 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_SPI_H
+#define _ATH79_DEV_SPI_H
+
+#include <linux/spi/spi.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+void ath79_register_spi(struct ath79_spi_platform_data *pdata,
+ struct spi_board_info const *info,
+ unsigned n);
+
+#endif /* _ATH79_DEV_SPI_H */
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
new file mode 100644
index 00000000..7499b0e9
--- /dev/null
+++ b/arch/mips/ath79/early_printk.c
@@ -0,0 +1,36 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SoC early printk support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+#include <asm/addrspace.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+static inline void prom_wait_thre(void __iomem *base)
+{
+ u32 lsr;
+
+ do {
+ lsr = __raw_readl(base + UART_LSR * 4);
+ if (lsr & UART_LSR_THRE)
+ break;
+ } while (1);
+}
+
+void prom_putchar(unsigned char ch)
+{
+ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
+
+ prom_wait_thre(base);
+ __raw_writel(ch, base + UART_TX * 4);
+ prom_wait_thre(base);
+}
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
new file mode 100644
index 00000000..a0c426b8
--- /dev/null
+++ b/arch/mips/ath79/gpio.c
@@ -0,0 +1,197 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO API support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79.h>
+#include "common.h"
+
+static void __iomem *ath79_gpio_base;
+static unsigned long ath79_gpio_count;
+static DEFINE_SPINLOCK(ath79_gpio_lock);
+
+static void __ath79_gpio_set_value(unsigned gpio, int value)
+{
+ void __iomem *base = ath79_gpio_base;
+
+ if (value)
+ __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
+ else
+ __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
+}
+
+static int __ath79_gpio_get_value(unsigned gpio)
+{
+ return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
+}
+
+static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+ return __ath79_gpio_get_value(offset);
+}
+
+static void ath79_gpio_set_value(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ __ath79_gpio_set_value(offset, value);
+}
+
+static int ath79_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
+ base + AR71XX_GPIO_REG_OE);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+ return 0;
+}
+
+static int ath79_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ if (value)
+ __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
+ else
+ __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
+ base + AR71XX_GPIO_REG_OE);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+ return 0;
+}
+
+static struct gpio_chip ath79_gpio_chip = {
+ .label = "ath79",
+ .get = ath79_gpio_get_value,
+ .set = ath79_gpio_set_value,
+ .direction_input = ath79_gpio_direction_input,
+ .direction_output = ath79_gpio_direction_output,
+ .base = 0,
+};
+
+void ath79_gpio_function_enable(u32 mask)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_disable(u32 mask)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_setup(u32 set, u32 clear)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void __init ath79_gpio_init(void)
+{
+ int err;
+
+ if (soc_is_ar71xx())
+ ath79_gpio_count = AR71XX_GPIO_COUNT;
+ else if (soc_is_ar724x())
+ ath79_gpio_count = AR724X_GPIO_COUNT;
+ else if (soc_is_ar913x())
+ ath79_gpio_count = AR913X_GPIO_COUNT;
+ else
+ BUG();
+
+ ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
+ ath79_gpio_chip.ngpio = ath79_gpio_count;
+
+ err = gpiochip_add(&ath79_gpio_chip);
+ if (err)
+ panic("cannot add AR71xx GPIO chip, error=%d", err);
+}
+
+int gpio_get_value(unsigned gpio)
+{
+ if (gpio < ath79_gpio_count)
+ return __ath79_gpio_get_value(gpio);
+
+ return __gpio_get_value(gpio);
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int value)
+{
+ if (gpio < ath79_gpio_count)
+ __ath79_gpio_set_value(gpio, value);
+ else
+ __gpio_set_value(gpio, value);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_to_irq(unsigned gpio)
+{
+ /* FIXME */
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned irq)
+{
+ /* FIXME */
+ return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
new file mode 100644
index 00000000..ac610d5f
--- /dev/null
+++ b/arch/mips/ath79/irq.c
@@ -0,0 +1,183 @@
+/*
+ * Atheros AR71xx/AR724x/AR913x specific interrupt handling
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static unsigned int ath79_ip2_flush_reg;
+static unsigned int ath79_ip3_flush_reg;
+
+static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 pending;
+
+ pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ if (pending & MISC_INT_UART)
+ generic_handle_irq(ATH79_MISC_IRQ_UART);
+
+ else if (pending & MISC_INT_DMA)
+ generic_handle_irq(ATH79_MISC_IRQ_DMA);
+
+ else if (pending & MISC_INT_PERFC)
+ generic_handle_irq(ATH79_MISC_IRQ_PERFC);
+
+ else if (pending & MISC_INT_TIMER)
+ generic_handle_irq(ATH79_MISC_IRQ_TIMER);
+
+ else if (pending & MISC_INT_OHCI)
+ generic_handle_irq(ATH79_MISC_IRQ_OHCI);
+
+ else if (pending & MISC_INT_ERROR)
+ generic_handle_irq(ATH79_MISC_IRQ_ERROR);
+
+ else if (pending & MISC_INT_GPIO)
+ generic_handle_irq(ATH79_MISC_IRQ_GPIO);
+
+ else if (pending & MISC_INT_WDOG)
+ generic_handle_irq(ATH79_MISC_IRQ_WDOG);
+
+ else
+ spurious_interrupt();
+}
+
+static void ar71xx_misc_irq_unmask(struct irq_data *d)
+{
+ unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar71xx_misc_irq_mask(struct irq_data *d)
+{
+ unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar724x_misc_irq_ack(struct irq_data *d)
+{
+ unsigned int irq = d->irq - ATH79_MISC_IRQ_BASE;
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+}
+
+static struct irq_chip ath79_misc_irq_chip = {
+ .name = "MISC",
+ .irq_unmask = ar71xx_misc_irq_unmask,
+ .irq_mask = ar71xx_misc_irq_mask,
+};
+
+static void __init ath79_misc_irq_init(void)
+{
+ void __iomem *base = ath79_reset_base;
+ int i;
+
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+ if (soc_is_ar71xx() || soc_is_ar913x())
+ ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
+ else if (soc_is_ar724x())
+ ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
+ else
+ BUG();
+
+ for (i = ATH79_MISC_IRQ_BASE;
+ i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
+ irq_set_chip_and_handler(i, &ath79_misc_irq_chip,
+ handle_level_irq);
+ }
+
+ irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long pending;
+
+ pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP7)
+ do_IRQ(ATH79_CPU_IRQ_TIMER);
+
+ else if (pending & STATUSF_IP2) {
+ ath79_ddr_wb_flush(ath79_ip2_flush_reg);
+ do_IRQ(ATH79_CPU_IRQ_IP2);
+ }
+
+ else if (pending & STATUSF_IP4)
+ do_IRQ(ATH79_CPU_IRQ_GE0);
+
+ else if (pending & STATUSF_IP5)
+ do_IRQ(ATH79_CPU_IRQ_GE1);
+
+ else if (pending & STATUSF_IP3) {
+ ath79_ddr_wb_flush(ath79_ip3_flush_reg);
+ do_IRQ(ATH79_CPU_IRQ_USB);
+ }
+
+ else if (pending & STATUSF_IP6)
+ do_IRQ(ATH79_CPU_IRQ_MISC);
+
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ if (soc_is_ar71xx()) {
+ ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
+ ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB;
+ } else if (soc_is_ar724x()) {
+ ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
+ ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB;
+ } else if (soc_is_ar913x()) {
+ ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
+ ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
+ } else
+ BUG();
+
+ cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
+ mips_cpu_irq_init();
+ ath79_misc_irq_init();
+}
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
new file mode 100644
index 00000000..eee4c121
--- /dev/null
+++ b/arch/mips/ath79/mach-ap81.c
@@ -0,0 +1,98 @@
+/*
+ * Atheros AP81 board support
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "machtypes.h"
+#include "dev-ar913x-wmac.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+
+#define AP81_GPIO_LED_STATUS 1
+#define AP81_GPIO_LED_AOSS 3
+#define AP81_GPIO_LED_WLAN 6
+#define AP81_GPIO_LED_POWER 14
+
+#define AP81_GPIO_BTN_SW4 12
+#define AP81_GPIO_BTN_SW1 21
+
+#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */
+#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL)
+
+#define AP81_CAL_DATA_ADDR 0x1fff1000
+
+static struct gpio_led ap81_leds_gpio[] __initdata = {
+ {
+ .name = "ap81:green:status",
+ .gpio = AP81_GPIO_LED_STATUS,
+ .active_low = 1,
+ }, {
+ .name = "ap81:amber:aoss",
+ .gpio = AP81_GPIO_LED_AOSS,
+ .active_low = 1,
+ }, {
+ .name = "ap81:green:wlan",
+ .gpio = AP81_GPIO_LED_WLAN,
+ .active_low = 1,
+ }, {
+ .name = "ap81:green:power",
+ .gpio = AP81_GPIO_LED_POWER,
+ .active_low = 1,
+ }
+};
+
+static struct gpio_keys_button ap81_gpio_keys[] __initdata = {
+ {
+ .desc = "sw1",
+ .type = EV_KEY,
+ .code = BTN_0,
+ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP81_GPIO_BTN_SW1,
+ .active_low = 1,
+ } , {
+ .desc = "sw4",
+ .type = EV_KEY,
+ .code = BTN_1,
+ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP81_GPIO_BTN_SW4,
+ .active_low = 1,
+ }
+};
+
+static struct spi_board_info ap81_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "m25p64",
+ }
+};
+
+static struct ath79_spi_platform_data ap81_spi_data = {
+ .bus_num = 0,
+ .num_chipselect = 1,
+};
+
+static void __init ap81_setup(void)
+{
+ u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
+ ap81_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ap81_gpio_keys),
+ ap81_gpio_keys);
+ ath79_register_spi(&ap81_spi_data, ap81_spi_info,
+ ARRAY_SIZE(ap81_spi_info));
+ ath79_register_ar913x_wmac(cal_data);
+}
+
+MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
+ ap81_setup);
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
new file mode 100644
index 00000000..ec7b7a13
--- /dev/null
+++ b/arch/mips/ath79/mach-pb44.c
@@ -0,0 +1,118 @@
+/*
+ * Atheros PB44 reference board support
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pcf857x.h>
+
+#include "machtypes.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+
+#define PB44_GPIO_I2C_SCL 0
+#define PB44_GPIO_I2C_SDA 1
+
+#define PB44_GPIO_EXP_BASE 16
+#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6)
+#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8)
+#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9)
+#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + 10)
+
+#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */
+#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL)
+
+static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
+ .sda_pin = PB44_GPIO_I2C_SDA,
+ .scl_pin = PB44_GPIO_I2C_SCL,
+};
+
+static struct platform_device pb44_i2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &pb44_i2c_gpio_data,
+ }
+};
+
+static struct pcf857x_platform_data pb44_pcf857x_data = {
+ .gpio_base = PB44_GPIO_EXP_BASE,
+};
+
+static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf8575", 0x20),
+ .platform_data = &pb44_pcf857x_data,
+ },
+};
+
+static struct gpio_led pb44_leds_gpio[] __initdata = {
+ {
+ .name = "pb44:amber:jump1",
+ .gpio = PB44_GPIO_LED_JUMP1,
+ .active_low = 1,
+ }, {
+ .name = "pb44:green:jump2",
+ .gpio = PB44_GPIO_LED_JUMP2,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
+ {
+ .desc = "soft_reset",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = PB44_GPIO_SW_RESET,
+ .active_low = 1,
+ } , {
+ .desc = "jumpstart",
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = PB44_GPIO_SW_JUMP,
+ .active_low = 1,
+ }
+};
+
+static struct spi_board_info pb44_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "m25p64",
+ },
+};
+
+static struct ath79_spi_platform_data pb44_spi_data = {
+ .bus_num = 0,
+ .num_chipselect = 1,
+};
+
+static void __init pb44_init(void)
+{
+ i2c_register_board_info(0, pb44_i2c_board_info,
+ ARRAY_SIZE(pb44_i2c_board_info));
+ platform_device_register(&pb44_i2c_gpio_device);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
+ pb44_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(pb44_gpio_keys),
+ pb44_gpio_keys);
+ ath79_register_spi(&pb44_spi_data, pb44_spi_info,
+ ARRAY_SIZE(pb44_spi_info));
+}
+
+MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
+ pb44_init);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
new file mode 100644
index 00000000..3940fe47
--- /dev/null
+++ b/arch/mips/ath79/machtypes.h
@@ -0,0 +1,23 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X machine type definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_MACHTYPE_H
+#define _ATH79_MACHTYPE_H
+
+#include <asm/mips_machine.h>
+
+enum ath79_mach_type {
+ ATH79_MACH_GENERIC = 0,
+ ATH79_MACH_AP81, /* Atheros AP81 reference board */
+ ATH79_MACH_PB44, /* Atheros PB44 reference board */
+};
+
+#endif /* _ATH79_MACHTYPE_H */
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c
new file mode 100644
index 00000000..e9cbd7c2
--- /dev/null
+++ b/arch/mips/ath79/prom.c
@@ -0,0 +1,57 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific prom routines
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include "common.h"
+
+static inline int is_valid_ram_addr(void *addr)
+{
+ if (((u32) addr > KSEG0) &&
+ ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX)))
+ return 1;
+
+ if (((u32) addr > KSEG1) &&
+ ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX)))
+ return 1;
+
+ return 0;
+}
+
+static __init void ath79_prom_init_cmdline(int argc, char **argv)
+{
+ int i;
+
+ if (!is_valid_ram_addr(argv))
+ return;
+
+ for (i = 0; i < argc; i++)
+ if (is_valid_ram_addr(argv[i])) {
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+ strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
+ }
+}
+
+void __init prom_init(void)
+{
+ ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* We do not have to prom memory to free */
+}
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
new file mode 100644
index 00000000..159b42f1
--- /dev/null
+++ b/arch/mips/ath79/setup.c
@@ -0,0 +1,206 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific setup
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h> /* for mips_hpt_frequency */
+#include <asm/reboot.h> /* for _machine_{restart,halt} */
+#include <asm/mips_machine.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+#include "machtypes.h"
+
+#define ATH79_SYS_TYPE_LEN 64
+
+#define AR71XX_BASE_FREQ 40000000
+#define AR724X_BASE_FREQ 5000000
+#define AR913X_BASE_FREQ 5000000
+
+static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
+
+static void ath79_restart(char *command)
+{
+ ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
+ for (;;)
+ if (cpu_wait)
+ cpu_wait();
+}
+
+static void ath79_halt(void)
+{
+ while (1)
+ cpu_wait();
+}
+
+static void __init ath79_detect_mem_size(void)
+{
+ unsigned long size;
+
+ for (size = ATH79_MEM_SIZE_MIN; size < ATH79_MEM_SIZE_MAX;
+ size <<= 1) {
+ if (!memcmp(ath79_detect_mem_size,
+ ath79_detect_mem_size + size, 1024))
+ break;
+ }
+
+ add_memory_region(0, size, BOOT_MEM_RAM);
+}
+
+static void __init ath79_detect_sys_type(void)
+{
+ char *chip = "????";
+ u32 id;
+ u32 major;
+ u32 minor;
+ u32 rev = 0;
+
+ id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
+ major = id & REV_ID_MAJOR_MASK;
+
+ switch (major) {
+ case REV_ID_MAJOR_AR71XX:
+ minor = id & AR71XX_REV_ID_MINOR_MASK;
+ rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
+ rev &= AR71XX_REV_ID_REVISION_MASK;
+ switch (minor) {
+ case AR71XX_REV_ID_MINOR_AR7130:
+ ath79_soc = ATH79_SOC_AR7130;
+ chip = "7130";
+ break;
+
+ case AR71XX_REV_ID_MINOR_AR7141:
+ ath79_soc = ATH79_SOC_AR7141;
+ chip = "7141";
+ break;
+
+ case AR71XX_REV_ID_MINOR_AR7161:
+ ath79_soc = ATH79_SOC_AR7161;
+ chip = "7161";
+ break;
+ }
+ break;
+
+ case REV_ID_MAJOR_AR7240:
+ ath79_soc = ATH79_SOC_AR7240;
+ chip = "7240";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR7241:
+ ath79_soc = ATH79_SOC_AR7241;
+ chip = "7241";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR7242:
+ ath79_soc = ATH79_SOC_AR7242;
+ chip = "7242";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR913X:
+ minor = id & AR913X_REV_ID_MINOR_MASK;
+ rev = id >> AR913X_REV_ID_REVISION_SHIFT;
+ rev &= AR913X_REV_ID_REVISION_MASK;
+ switch (minor) {
+ case AR913X_REV_ID_MINOR_AR9130:
+ ath79_soc = ATH79_SOC_AR9130;
+ chip = "9130";
+ break;
+
+ case AR913X_REV_ID_MINOR_AR9132:
+ ath79_soc = ATH79_SOC_AR9132;
+ chip = "9132";
+ break;
+ }
+ break;
+
+ default:
+ panic("ath79: unknown SoC, id:0x%08x\n", id);
+ }
+
+ sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
+ pr_info("SoC: %s\n", ath79_sys_type);
+}
+
+const char *get_system_type(void)
+{
+ return ath79_sys_type;
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ return CP0_LEGACY_COMPARE_IRQ;
+}
+
+void __init plat_mem_setup(void)
+{
+ set_io_port_base(KSEG1);
+
+ ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
+ AR71XX_RESET_SIZE);
+ ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
+ AR71XX_PLL_SIZE);
+ ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
+ AR71XX_DDR_CTRL_SIZE);
+
+ ath79_detect_sys_type();
+ ath79_detect_mem_size();
+ ath79_clocks_init();
+
+ _machine_restart = ath79_restart;
+ _machine_halt = ath79_halt;
+ pm_power_off = ath79_halt;
+}
+
+void __init plat_time_init(void)
+{
+ struct clk *clk;
+
+ clk = clk_get(NULL, "cpu");
+ if (IS_ERR(clk))
+ panic("unable to get CPU clock, err=%ld", PTR_ERR(clk));
+
+ mips_hpt_frequency = clk_get_rate(clk) / 2;
+}
+
+static int __init ath79_setup(void)
+{
+ ath79_gpio_init();
+ ath79_register_uart();
+ ath79_register_wdt();
+
+ mips_machine_setup();
+
+ return 0;
+}
+
+arch_initcall(ath79_setup);
+
+static void __init ath79_generic_init(void)
+{
+ /* Nothing to do */
+}
+
+MIPS_MACHINE(ATH79_MACH_GENERIC,
+ "Generic",
+ "Generic AR71XX/AR724X/AR913X based board",
+ ath79_generic_init);
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile
new file mode 100644
index 00000000..7465e8a7
--- /dev/null
+++ b/arch/mips/bcm47xx/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the BCM47XX specific kernel interface routines
+# under Linux.
+#
+
+obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
diff --git a/arch/mips/bcm47xx/Platform b/arch/mips/bcm47xx/Platform
new file mode 100644
index 00000000..874b7ca4
--- /dev/null
+++ b/arch/mips/bcm47xx/Platform
@@ -0,0 +1,7 @@
+#
+# Broadcom BCM47XX boards
+#
+platform-$(CONFIG_BCM47XX) += bcm47xx/
+cflags-$(CONFIG_BCM47XX) += \
+ -I$(srctree)/arch/mips/include/asm/mach-bcm47xx
+load-$(CONFIG_BCM47XX) := 0xffffffff80001000
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
new file mode 100644
index 00000000..e4a5ee9c
--- /dev/null
+++ b/arch/mips/bcm47xx/gpio.c
@@ -0,0 +1,61 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
+ */
+
+#include <linux/ssb/ssb.h>
+#include <linux/ssb/ssb_driver_chipcommon.h>
+#include <linux/ssb/ssb_driver_extif.h>
+#include <asm/mach-bcm47xx/bcm47xx.h>
+#include <asm/mach-bcm47xx/gpio.h>
+
+#if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES)
+static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES);
+#else
+static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
+#endif
+
+int gpio_request(unsigned gpio, const char *tag)
+{
+ if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
+ ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+ return -EINVAL;
+
+ if (ssb_extif_available(&ssb_bcm47xx.extif) &&
+ ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+ return -EINVAL;
+
+ if (test_and_set_bit(gpio, gpio_in_use))
+ return -EBUSY;
+
+ return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned gpio)
+{
+ if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
+ ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+ return;
+
+ if (ssb_extif_available(&ssb_bcm47xx.extif) &&
+ ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+ return;
+
+ clear_bit(gpio, gpio_in_use);
+}
+EXPORT_SYMBOL(gpio_free);
+
+int gpio_to_irq(unsigned gpio)
+{
+ if (ssb_chipco_available(&ssb_bcm47xx.chipco))
+ return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2;
+ else if (ssb_extif_available(&ssb_bcm47xx.extif))
+ return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2;
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(gpio_to_irq);
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c
new file mode 100644
index 00000000..325757ac
--- /dev/null
+++ b/arch/mips/bcm47xx/irq.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq_cpu.h>
+
+void plat_irq_dispatch(void)
+{
+ u32 cause;
+
+ cause = read_c0_cause() & read_c0_status() & CAUSEF_IP;
+
+ clear_c0_status(cause);
+
+ if (cause & CAUSEF_IP7)
+ do_IRQ(7);
+ if (cause & CAUSEF_IP2)
+ do_IRQ(2);
+ if (cause & CAUSEF_IP3)
+ do_IRQ(3);
+ if (cause & CAUSEF_IP4)
+ do_IRQ(4);
+ if (cause & CAUSEF_IP5)
+ do_IRQ(5);
+ if (cause & CAUSEF_IP6)
+ do_IRQ(6);
+}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+}
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
new file mode 100644
index 00000000..54db815b
--- /dev/null
+++ b/arch/mips/bcm47xx/nvram.c
@@ -0,0 +1,95 @@
+/*
+ * BCM947xx nvram variable access
+ *
+ * Copyright (C) 2005 Broadcom Corporation
+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/ssb/ssb.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <asm/addrspace.h>
+#include <asm/mach-bcm47xx/nvram.h>
+#include <asm/mach-bcm47xx/bcm47xx.h>
+
+static char nvram_buf[NVRAM_SPACE];
+
+/* Probe for NVRAM header */
+static void early_nvram_init(void)
+{
+ struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+ struct nvram_header *header;
+ int i;
+ u32 base, lim, off;
+ u32 *src, *dst;
+
+ base = mcore->flash_window;
+ lim = mcore->flash_window_size;
+
+ off = FLASH_MIN;
+ while (off <= lim) {
+ /* Windowed flash access */
+ header = (struct nvram_header *)
+ KSEG1ADDR(base + off - NVRAM_SPACE);
+ if (header->magic == NVRAM_HEADER)
+ goto found;
+ off <<= 1;
+ }
+
+ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
+ header = (struct nvram_header *) KSEG1ADDR(base + 4096);
+ if (header->magic == NVRAM_HEADER)
+ goto found;
+
+ header = (struct nvram_header *) KSEG1ADDR(base + 1024);
+ if (header->magic == NVRAM_HEADER)
+ goto found;
+
+ return;
+
+found:
+ src = (u32 *) header;
+ dst = (u32 *) nvram_buf;
+ for (i = 0; i < sizeof(struct nvram_header); i += 4)
+ *dst++ = *src++;
+ for (; i < header->len && i < NVRAM_SPACE; i += 4)
+ *dst++ = le32_to_cpu(*src++);
+}
+
+int nvram_getenv(char *name, char *val, size_t val_len)
+{
+ char *var, *value, *end, *eq;
+
+ if (!name)
+ return NVRAM_ERR_INV_PARAM;
+
+ if (!nvram_buf[0])
+ early_nvram_init();
+
+ /* Look for name=value and return value */
+ var = &nvram_buf[sizeof(struct nvram_header)];
+ end = nvram_buf + sizeof(nvram_buf) - 2;
+ end[0] = end[1] = '\0';
+ for (; *var; var = value + strlen(value) + 1) {
+ eq = strchr(var, '=');
+ if (!eq)
+ break;
+ value = eq + 1;
+ if ((eq - var) == strlen(name) &&
+ strncmp(var, name, (eq - var)) == 0) {
+ snprintf(val, val_len, "%s", value);
+ return 0;
+ }
+ }
+ return NVRAM_ERR_ENVNOTFOUND;
+}
+EXPORT_SYMBOL(nvram_getenv);
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
new file mode 100644
index 00000000..f6e9063c
--- /dev/null
+++ b/arch/mips/bcm47xx/prom.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
+ * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <asm/bootinfo.h>
+#include <asm/fw/cfe/cfe_api.h>
+#include <asm/fw/cfe/cfe_error.h>
+
+static int cfe_cons_handle;
+
+const char *get_system_type(void)
+{
+ return "Broadcom BCM47XX";
+}
+
+void prom_putchar(char c)
+{
+ while (cfe_write(cfe_cons_handle, &c, 1) == 0)
+ ;
+}
+
+static __init void prom_init_cfe(void)
+{
+ uint32_t cfe_ept;
+ uint32_t cfe_handle;
+ uint32_t cfe_eptseal;
+ int argc = fw_arg0;
+ char **envp = (char **) fw_arg2;
+ int *prom_vec = (int *) fw_arg3;
+
+ /*
+ * Check if a loader was used; if NOT, the 4 arguments are
+ * what CFE gives us (handle, 0, EPT and EPTSEAL)
+ */
+ if (argc < 0) {
+ cfe_handle = (uint32_t)argc;
+ cfe_ept = (uint32_t)envp;
+ cfe_eptseal = (uint32_t)prom_vec;
+ } else {
+ if ((int)prom_vec < 0) {
+ /*
+ * Old loader; all it gives us is the handle,
+ * so use the "known" entrypoint and assume
+ * the seal.
+ */
+ cfe_handle = (uint32_t)prom_vec;
+ cfe_ept = 0xBFC00500;
+ cfe_eptseal = CFE_EPTSEAL;
+ } else {
+ /*
+ * Newer loaders bundle the handle/ept/eptseal
+ * Note: prom_vec is in the loader's useg
+ * which is still alive in the TLB.
+ */
+ cfe_handle = prom_vec[0];
+ cfe_ept = prom_vec[2];
+ cfe_eptseal = prom_vec[3];
+ }
+ }
+
+ if (cfe_eptseal != CFE_EPTSEAL) {
+ /* too early for panic to do any good */
+ printk(KERN_ERR "CFE's entrypoint seal doesn't match.");
+ while (1) ;
+ }
+
+ cfe_init(cfe_handle, cfe_ept);
+}
+
+static __init void prom_init_console(void)
+{
+ /* Initialize CFE console */
+ cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
+}
+
+static __init void prom_init_cmdline(void)
+{
+ static char buf[COMMAND_LINE_SIZE] __initdata;
+
+ /* Get the kernel command line from CFE */
+ if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) {
+ buf[COMMAND_LINE_SIZE - 1] = 0;
+ strcpy(arcs_cmdline, buf);
+ }
+
+ /* Force a console handover by adding a console= argument if needed,
+ * as CFE is not available anymore later in the boot process. */
+ if ((strstr(arcs_cmdline, "console=")) == NULL) {
+ /* Try to read the default serial port used by CFE */
+ if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0)
+ || (strncmp("uart", buf, 4)))
+ /* Default to uart0 */
+ strcpy(buf, "uart0");
+
+ /* Compute the new command line */
+ snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200",
+ arcs_cmdline, buf[4]);
+ }
+}
+
+static __init void prom_init_mem(void)
+{
+ unsigned long mem;
+ unsigned long max;
+
+ /* Figure out memory size by finding aliases.
+ *
+ * We should theoretically use the mapping from CFE using cfe_enummem().
+ * However as the BCM47XX is mostly used on low-memory systems, we
+ * want to reuse the memory used by CFE (around 4MB). That means cfe_*
+ * functions stop to work at some point during the boot, we should only
+ * call them at the beginning of the boot.
+ *
+ * BCM47XX uses 128MB for addressing the ram, if the system contains
+ * less that that amount of ram it remaps the ram more often into the
+ * available space.
+ * Accessing memory after 128MB will cause an exception.
+ * max contains the biggest possible address supported by the platform.
+ * If the method wants to try something above we assume 128MB ram.
+ */
+ max = ((unsigned long)(prom_init) | ((128 << 20) - 1));
+ for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
+ if (((unsigned long)(prom_init) + mem) > max) {
+ mem = (128 << 20);
+ printk(KERN_DEBUG "assume 128MB RAM\n");
+ break;
+ }
+ if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
+ *(unsigned long *)(prom_init))
+ break;
+ }
+
+ add_memory_region(0, mem, BOOT_MEM_RAM);
+}
+
+void __init prom_init(void)
+{
+ prom_init_cfe();
+ prom_init_console();
+ prom_init_cmdline();
+ prom_init_mem();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c
new file mode 100644
index 00000000..59c11afd
--- /dev/null
+++ b/arch/mips/bcm47xx/serial.c
@@ -0,0 +1,52 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/ssb/ssb.h>
+#include <bcm47xx.h>
+
+static struct plat_serial8250_port uart8250_data[5];
+
+static struct platform_device uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = uart8250_data,
+ },
+};
+
+static int __init uart8250_init(void)
+{
+ int i;
+ struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore);
+
+ memset(&uart8250_data, 0, sizeof(uart8250_data));
+
+ for (i = 0; i < mcore->nr_serial_ports; i++) {
+ struct plat_serial8250_port *p = &(uart8250_data[i]);
+ struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]);
+
+ p->mapbase = (unsigned int) ssb_port->regs;
+ p->membase = (void *) ssb_port->regs;
+ p->irq = ssb_port->irq + 2;
+ p->uartclk = ssb_port->baud_base;
+ p->regshift = ssb_port->reg_shift;
+ p->iotype = UPIO_MEM;
+ p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+ }
+ return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for the BCM47XX platforms");
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
new file mode 100644
index 00000000..73b529b5
--- /dev/null
+++ b/arch/mips/bcm47xx/setup.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>
+ * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
+ * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/ssb/ssb.h>
+#include <linux/ssb/ssb_embedded.h>
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <bcm47xx.h>
+#include <asm/mach-bcm47xx/nvram.h>
+
+struct ssb_bus ssb_bcm47xx;
+EXPORT_SYMBOL(ssb_bcm47xx);
+
+static void bcm47xx_machine_restart(char *command)
+{
+ printk(KERN_ALERT "Please stand by while rebooting the system...\n");
+ local_irq_disable();
+ /* Set the watchdog timer to reset immediately */
+ ssb_watchdog_timer_set(&ssb_bcm47xx, 1);
+ while (1)
+ cpu_relax();
+}
+
+static void bcm47xx_machine_halt(void)
+{
+ /* Disable interrupts and watchdog and spin forever */
+ local_irq_disable();
+ ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
+ while (1)
+ cpu_relax();
+}
+
+#define READ_FROM_NVRAM(_outvar, name, buf) \
+ if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\
+ sprom->_outvar = simple_strtoul(buf, NULL, 0);
+
+#define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \
+ if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \
+ nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\
+ sprom->_outvar = simple_strtoul(buf, NULL, 0);
+
+static inline int nvram_getprefix(const char *prefix, char *name,
+ char *buf, int len)
+{
+ if (prefix) {
+ char key[100];
+
+ snprintf(key, sizeof(key), "%s%s", prefix, name);
+ return nvram_getenv(key, buf, len);
+ }
+
+ return nvram_getenv(name, buf, len);
+}
+
+static u32 nvram_getu32(const char *name, char *buf, int len)
+{
+ int rv;
+ char key[100];
+ u16 var0, var1;
+
+ snprintf(key, sizeof(key), "%s0", name);
+ rv = nvram_getenv(key, buf, len);
+ /* return 0 here so this looks like unset */
+ if (rv < 0)
+ return 0;
+ var0 = simple_strtoul(buf, NULL, 0);
+
+ snprintf(key, sizeof(key), "%s1", name);
+ rv = nvram_getenv(key, buf, len);
+ if (rv < 0)
+ return 0;
+ var1 = simple_strtoul(buf, NULL, 0);
+ return var1 << 16 | var0;
+}
+
+static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
+{
+ char buf[100];
+ u32 boardflags;
+
+ memset(sprom, 0, sizeof(struct ssb_sprom));
+
+ sprom->revision = 1; /* Fallback: Old hardware does not define this. */
+ READ_FROM_NVRAM(revision, "sromrev", buf);
+ if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 ||
+ nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0)
+ nvram_parse_macaddr(buf, sprom->il0mac);
+ if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0)
+ nvram_parse_macaddr(buf, sprom->et0mac);
+ if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0)
+ nvram_parse_macaddr(buf, sprom->et1mac);
+ READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
+ READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
+ READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
+ READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
+ READ_FROM_NVRAM(board_rev, "boardrev", buf);
+ READ_FROM_NVRAM(country_code, "ccode", buf);
+ READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
+ READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
+ READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
+ READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
+ READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
+ READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
+ READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
+ READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
+ READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
+ READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
+ READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
+ READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
+ READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
+ READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
+ READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf);
+ READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf);
+ READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf);
+ READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf);
+ READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf);
+ READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf);
+ READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf);
+ READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf);
+ READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf);
+ READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf);
+ READ_FROM_NVRAM(tri2g, "tri2g", buf);
+ READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
+ READ_FROM_NVRAM(tri5g, "tri5g", buf);
+ READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
+ READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf);
+ READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf);
+ READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf);
+ READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf);
+ READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf);
+ READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf);
+ READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf);
+ READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf);
+ READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf);
+ READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf);
+ READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf);
+ READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf);
+ READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf);
+ READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf);
+ READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf);
+ READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf);
+ READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
+ READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
+ READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
+ READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
+ READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
+ READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
+ READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
+ READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
+ READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
+ READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
+ READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
+
+ sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf));
+ sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf));
+ sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf));
+ sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf));
+
+ READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf);
+ READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf);
+ READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf);
+ READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf);
+ memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24,
+ sizeof(sprom->antenna_gain.ghz5));
+
+ if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) {
+ boardflags = simple_strtoul(buf, NULL, 0);
+ if (boardflags) {
+ sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
+ sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
+ }
+ }
+ if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) {
+ boardflags = simple_strtoul(buf, NULL, 0);
+ if (boardflags) {
+ sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
+ sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
+ }
+ }
+}
+
+int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
+{
+ char prefix[10];
+
+ if (bus->bustype == SSB_BUSTYPE_PCI) {
+ snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
+ bus->host_pci->bus->number + 1,
+ PCI_SLOT(bus->host_pci->devfn));
+ bcm47xx_fill_sprom(out, prefix);
+ return 0;
+ } else {
+ printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n");
+ return -EINVAL;
+ }
+}
+
+static int bcm47xx_get_invariants(struct ssb_bus *bus,
+ struct ssb_init_invariants *iv)
+{
+ char buf[20];
+
+ /* Fill boardinfo structure */
+ memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
+
+ if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
+ iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0);
+ else
+ iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
+ if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
+ iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
+ if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
+ iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
+
+ bcm47xx_fill_sprom(&iv->sprom, NULL);
+
+ if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
+ iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
+
+ return 0;
+}
+
+void __init plat_mem_setup(void)
+{
+ int err;
+ char buf[100];
+ struct ssb_mipscore *mcore;
+
+ err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom);
+ if (err)
+ printk(KERN_WARNING "bcm47xx: someone else already registered"
+ " a ssb SPROM callback handler (err %d)\n", err);
+
+ err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
+ bcm47xx_get_invariants);
+ if (err)
+ panic("Failed to initialize SSB bus (err %d)\n", err);
+
+ mcore = &ssb_bcm47xx.mipscore;
+ if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
+ if (strstr(buf, "console=ttyS1")) {
+ struct ssb_serial_port port;
+
+ printk(KERN_DEBUG "Swapping serial ports!\n");
+ /* swap serial ports */
+ memcpy(&port, &mcore->serial_ports[0], sizeof(port));
+ memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
+ sizeof(port));
+ memcpy(&mcore->serial_ports[1], &port, sizeof(port));
+ }
+ }
+
+ _machine_restart = bcm47xx_machine_restart;
+ _machine_halt = bcm47xx_machine_halt;
+ pm_power_off = bcm47xx_machine_halt;
+}
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
new file mode 100644
index 00000000..0c6f47b3
--- /dev/null
+++ b/arch/mips/bcm47xx/time.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/init.h>
+#include <linux/ssb/ssb.h>
+#include <asm/time.h>
+#include <bcm47xx.h>
+
+void __init plat_time_init(void)
+{
+ unsigned long hz;
+
+ /*
+ * Use deterministic values for initial counter interrupt
+ * so that calibrate delay avoids encountering a counter wrap.
+ */
+ write_c0_count(0);
+ write_c0_compare(0xffff);
+
+ hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2;
+ if (!hz)
+ hz = 100000000;
+
+ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
+ mips_hpt_frequency = hz;
+}
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c
new file mode 100644
index 00000000..74d06965
--- /dev/null
+++ b/arch/mips/bcm47xx/wgt634u.c
@@ -0,0 +1,166 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/leds.h>
+#include <linux/mtd/physmap.h>
+#include <linux/ssb/ssb.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.h>
+#include <linux/gpio.h>
+#include <asm/mach-bcm47xx/bcm47xx.h>
+
+/* GPIO definitions for the WGT634U */
+#define WGT634U_GPIO_LED 3
+#define WGT634U_GPIO_RESET 2
+#define WGT634U_GPIO_TP1 7
+#define WGT634U_GPIO_TP2 6
+#define WGT634U_GPIO_TP3 5
+#define WGT634U_GPIO_TP4 4
+#define WGT634U_GPIO_TP5 1
+
+static struct gpio_led wgt634u_leds[] = {
+ {
+ .name = "power",
+ .gpio = WGT634U_GPIO_LED,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+};
+
+static struct gpio_led_platform_data wgt634u_led_data = {
+ .num_leds = ARRAY_SIZE(wgt634u_leds),
+ .leds = wgt634u_leds,
+};
+
+static struct platform_device wgt634u_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wgt634u_led_data,
+ }
+};
+
+
+/* 8MiB flash. The struct mtd_partition matches original Netgear WGT634U
+ firmware. */
+static struct mtd_partition wgt634u_partitions[] = {
+ {
+ .name = "cfe",
+ .offset = 0,
+ .size = 0x60000, /* 384k */
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "config",
+ .offset = 0x60000,
+ .size = 0x20000 /* 128k */
+ },
+ {
+ .name = "linux",
+ .offset = 0x80000,
+ .size = 0x140000 /* 1280k */
+ },
+ {
+ .name = "jffs",
+ .offset = 0x1c0000,
+ .size = 0x620000 /* 6272k */
+ },
+ {
+ .name = "nvram",
+ .offset = 0x7e0000,
+ .size = 0x20000 /* 128k */
+ },
+};
+
+static struct physmap_flash_data wgt634u_flash_data = {
+ .parts = wgt634u_partitions,
+ .nr_parts = ARRAY_SIZE(wgt634u_partitions)
+};
+
+static struct resource wgt634u_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device wgt634u_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = { .platform_data = &wgt634u_flash_data, },
+ .resource = &wgt634u_flash_resource,
+ .num_resources = 1,
+};
+
+/* Platform devices */
+static struct platform_device *wgt634u_devices[] __initdata = {
+ &wgt634u_flash,
+ &wgt634u_gpio_leds,
+};
+
+static irqreturn_t gpio_interrupt(int irq, void *ignored)
+{
+ int state;
+
+ /* Interrupts are shared, check if the current one is
+ a GPIO interrupt. */
+ if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,
+ SSB_CHIPCO_IRQ_GPIO))
+ return IRQ_NONE;
+
+ state = gpio_get_value(WGT634U_GPIO_RESET);
+
+ /* Interrupt are level triggered, revert the interrupt polarity
+ to clear the interrupt. */
+ gpio_polarity(WGT634U_GPIO_RESET, state);
+
+ if (!state) {
+ printk(KERN_INFO "Reset button pressed");
+ ctrl_alt_del();
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __init wgt634u_init(void)
+{
+ /* There is no easy way to detect that we are running on a WGT634U
+ * machine. Use the MAC address as an heuristic. Netgear Inc. has
+ * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
+ */
+
+ u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
+
+ if (et0mac[0] == 0x00 &&
+ ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
+ (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
+ struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+
+ printk(KERN_INFO "WGT634U machine detected.\n");
+
+ if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
+ gpio_interrupt, IRQF_SHARED,
+ "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
+ gpio_direction_input(WGT634U_GPIO_RESET);
+ gpio_intmask(WGT634U_GPIO_RESET, 1);
+ ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
+ SSB_CHIPCO_IRQ_GPIO,
+ SSB_CHIPCO_IRQ_GPIO);
+ }
+
+ wgt634u_flash_data.width = mcore->flash_buswidth;
+ wgt634u_flash_resource.start = mcore->flash_window;
+ wgt634u_flash_resource.end = mcore->flash_window
+ + mcore->flash_window_size
+ - 1;
+ return platform_add_devices(wgt634u_devices,
+ ARRAY_SIZE(wgt634u_devices));
+ } else
+ return -ENODEV;
+}
+
+module_init(wgt634u_init);
diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig
new file mode 100644
index 00000000..fb177d6d
--- /dev/null
+++ b/arch/mips/bcm63xx/Kconfig
@@ -0,0 +1,25 @@
+menu "CPU support"
+ depends on BCM63XX
+
+config BCM63XX_CPU_6338
+ bool "support 6338 CPU"
+ select HW_HAS_PCI
+ select USB_ARCH_HAS_OHCI
+ select USB_OHCI_BIG_ENDIAN_DESC
+ select USB_OHCI_BIG_ENDIAN_MMIO
+
+config BCM63XX_CPU_6345
+ bool "support 6345 CPU"
+ select USB_OHCI_BIG_ENDIAN_DESC
+ select USB_OHCI_BIG_ENDIAN_MMIO
+
+config BCM63XX_CPU_6348
+ bool "support 6348 CPU"
+ select HW_HAS_PCI
+
+config BCM63XX_CPU_6358
+ bool "support 6358 CPU"
+ select HW_HAS_PCI
+endmenu
+
+source "arch/mips/bcm63xx/boards/Kconfig"
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
new file mode 100644
index 00000000..6dfdc699
--- /dev/null
+++ b/arch/mips/bcm63xx/Makefile
@@ -0,0 +1,5 @@
+obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
+ dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+obj-y += boards/
diff --git a/arch/mips/bcm63xx/Platform b/arch/mips/bcm63xx/Platform
new file mode 100644
index 00000000..5f86b2ff
--- /dev/null
+++ b/arch/mips/bcm63xx/Platform
@@ -0,0 +1,7 @@
+#
+# Broadcom BCM63XX boards
+#
+platform-$(CONFIG_BCM63XX) += bcm63xx/
+cflags-$(CONFIG_BCM63XX) += \
+ -I$(srctree)/arch/mips/include/asm/mach-bcm63xx/
+load-$(CONFIG_BCM63XX) := 0xffffffff80010000
diff --git a/arch/mips/bcm63xx/boards/Kconfig b/arch/mips/bcm63xx/boards/Kconfig
new file mode 100644
index 00000000..c6aed33d
--- /dev/null
+++ b/arch/mips/bcm63xx/boards/Kconfig
@@ -0,0 +1,11 @@
+choice
+ prompt "Board support"
+ depends on BCM63XX
+ default BOARD_BCM963XX
+
+config BOARD_BCM963XX
+ bool "Generic Broadcom 963xx boards"
+ select SSB
+ help
+
+endchoice
diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile
new file mode 100644
index 00000000..9f64fb41
--- /dev/null
+++ b/arch/mips/bcm63xx/boards/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o
+
+ccflags-y := -Werror
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
new file mode 100644
index 00000000..40b223b6
--- /dev/null
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -0,0 +1,913 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/ssb/ssb.h>
+#include <asm/addrspace.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_uart.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_dev_pci.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_dsp.h>
+#include <bcm63xx_dev_pcmcia.h>
+#include <board_bcm963xx.h>
+
+#define PFX "board_bcm963xx: "
+
+static struct bcm963xx_nvram nvram;
+static unsigned int mac_addr_used;
+static struct board_info board;
+
+/*
+ * known 6338 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6338
+static struct board_info __initdata board_96338gw = {
+ .name = "96338GW",
+ .expected_cpu_id = 0x6338,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .enet0 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ {
+ .name = "ses",
+ .gpio = 5,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 1,
+ .active_low = 1,
+ }
+ },
+};
+
+static struct board_info __initdata board_96338w = {
+ .name = "96338W",
+ .expected_cpu_id = 0x6338,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .enet0 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ {
+ .name = "ses",
+ .gpio = 5,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ },
+};
+#endif
+
+/*
+ * known 6345 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6345
+static struct board_info __initdata board_96345gw2 = {
+ .name = "96345GW2",
+ .expected_cpu_id = 0x6345,
+
+ .has_uart0 = 1,
+};
+#endif
+
+/*
+ * known 6348 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6348
+static struct board_info __initdata board_96348r = {
+ .name = "96348R",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .leds = {
+ {
+ .name = "adsl-fail",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+
+ },
+ {
+ .name = "stop",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ },
+};
+
+static struct board_info __initdata board_96348gw_10 = {
+ .name = "96348GW-10",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .has_dsp = 1,
+ .dsp = {
+ .gpio_rst = 6,
+ .gpio_int = 34,
+ .cs = 2,
+ .ext_irq = 2,
+ },
+
+ .leds = {
+ {
+ .name = "adsl-fail",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ },
+};
+
+static struct board_info __initdata board_96348gw_11 = {
+ .name = "96348GW-11",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl-fail",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ },
+};
+
+static struct board_info __initdata board_96348gw = {
+ .name = "96348GW",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+
+ .has_dsp = 1,
+ .dsp = {
+ .gpio_rst = 6,
+ .gpio_int = 34,
+ .ext_irq = 2,
+ .cs = 2,
+ },
+
+ .leds = {
+ {
+ .name = "adsl-fail",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ },
+};
+
+static struct board_info __initdata board_FAST2404 = {
+ .name = "F@ST2404",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+};
+
+static struct board_info __initdata board_rta1025w_16 = {
+ .name = "RTA1025W_16",
+ .expected_cpu_id = 0x6348,
+
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+};
+
+
+static struct board_info __initdata board_DV201AMR = {
+ .name = "DV201AMR",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_pci = 1,
+ .has_ohci0 = 1,
+
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+};
+
+static struct board_info __initdata board_96348gw_a = {
+ .name = "96348GW-A",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+};
+#endif
+
+/*
+ * known 6358 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6358
+static struct board_info __initdata board_96358vw = {
+ .name = "96358VW",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl-fail",
+ .gpio = 15,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp",
+ .gpio = 22,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 23,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 4,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 5,
+ },
+ },
+};
+
+static struct board_info __initdata board_96358vw2 = {
+ .name = "96358VW2",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = 22,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 23,
+ },
+ {
+ .name = "power",
+ .gpio = 5,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ },
+};
+
+static struct board_info __initdata board_AGPFS0 = {
+ .name = "AGPF-S0",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_ehci0 = 1,
+};
+
+static struct board_info __initdata board_DWVS0 = {
+ .name = "DWV-S0",
+ .expected_cpu_id = 0x6358,
+
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+};
+#endif
+
+/*
+ * all boards
+ */
+static const struct board_info __initdata *bcm963xx_boards[] = {
+#ifdef CONFIG_BCM63XX_CPU_6338
+ &board_96338gw,
+ &board_96338w,
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6345
+ &board_96345gw2,
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+ &board_96348r,
+ &board_96348gw,
+ &board_96348gw_10,
+ &board_96348gw_11,
+ &board_FAST2404,
+ &board_DV201AMR,
+ &board_96348gw_a,
+ &board_rta1025w_16,
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6358
+ &board_96358vw,
+ &board_96358vw2,
+ &board_AGPFS0,
+ &board_DWVS0,
+#endif
+};
+
+/*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+ .revision = 0x02,
+ .board_rev = 0x17,
+ .country_code = 0x0,
+ .ant_available_bg = 0x3,
+ .pa0b0 = 0x15ae,
+ .pa0b1 = 0xfa85,
+ .pa0b2 = 0xfe8d,
+ .pa1b0 = 0xffff,
+ .pa1b1 = 0xffff,
+ .pa1b2 = 0xffff,
+ .gpio0 = 0xff,
+ .gpio1 = 0xff,
+ .gpio2 = 0xff,
+ .gpio3 = 0xff,
+ .maxpwr_bg = 0x004c,
+ .itssi_bg = 0x00,
+ .boardflags_lo = 0x2848,
+ .boardflags_hi = 0x0000,
+};
+
+int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
+{
+ if (bus->bustype == SSB_BUSTYPE_PCI) {
+ memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
+ return 0;
+ } else {
+ printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
+ return -EINVAL;
+ }
+}
+#endif
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+ return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+ u8 *p;
+ int count;
+
+ if (mac_addr_used >= nvram.mac_addr_count) {
+ printk(KERN_ERR PFX "not enough mac address\n");
+ return -ENODEV;
+ }
+
+ memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+ p = mac + ETH_ALEN - 1;
+ count = mac_addr_used;
+
+ while (count--) {
+ do {
+ (*p)++;
+ if (*p != 0)
+ break;
+ p--;
+ } while (p != mac);
+ }
+
+ if (p == mac) {
+ printk(KERN_ERR PFX "unable to fetch mac address\n");
+ return -ENODEV;
+ }
+
+ mac_addr_used++;
+ return 0;
+}
+
+/*
+ * early init callback, read nvram data from flash and checksum it
+ */
+void __init board_prom_init(void)
+{
+ unsigned int check_len, i;
+ u8 *boot_addr, *cfe, *p;
+ char cfe_version[32];
+ u32 val;
+
+ /* read base address of boot chip select (0)
+ * 6345 does not have MPI but boots from standard
+ * MIPS Flash address */
+ if (BCMCPU_IS_6345())
+ val = 0x1fc00000;
+ else {
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+ }
+ boot_addr = (u8 *)KSEG1ADDR(val);
+
+ /* dump cfe version */
+ cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
+ if (!memcmp(cfe, "cfe-v", 5))
+ snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
+ cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
+ else
+ strcpy(cfe_version, "unknown");
+ printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
+
+ /* extract nvram data */
+ memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
+
+ /* check checksum before using data */
+ if (nvram.version <= 4)
+ check_len = offsetof(struct bcm963xx_nvram, checksum_old);
+ else
+ check_len = sizeof(nvram);
+ val = 0;
+ p = (u8 *)&nvram;
+ while (check_len--)
+ val += *p;
+ if (val) {
+ printk(KERN_ERR PFX "invalid nvram checksum\n");
+ return;
+ }
+
+ /* find board by name */
+ for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
+ if (strncmp(nvram.name, bcm963xx_boards[i]->name,
+ sizeof(nvram.name)))
+ continue;
+ /* copy, board desc array is marked initdata */
+ memcpy(&board, bcm963xx_boards[i], sizeof(board));
+ break;
+ }
+
+ /* bail out if board is not found, will complain later */
+ if (!board.name[0]) {
+ char name[17];
+ memcpy(name, nvram.name, 16);
+ name[16] = 0;
+ printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
+ name);
+ return;
+ }
+
+ /* setup pin multiplexing depending on board enabled device,
+ * this has to be done this early since PCI init is done
+ * inside arch_initcall */
+ val = 0;
+
+#ifdef CONFIG_PCI
+ if (board.has_pci) {
+ bcm63xx_pci_enabled = 1;
+ if (BCMCPU_IS_6348())
+ val |= GPIO_MODE_6348_G2_PCI;
+ }
+#endif
+
+ if (board.has_pccard) {
+ if (BCMCPU_IS_6348())
+ val |= GPIO_MODE_6348_G1_MII_PCCARD;
+ }
+
+ if (board.has_enet0 && !board.enet0.use_internal_phy) {
+ if (BCMCPU_IS_6348())
+ val |= GPIO_MODE_6348_G3_EXT_MII |
+ GPIO_MODE_6348_G0_EXT_MII;
+ }
+
+ if (board.has_enet1 && !board.enet1.use_internal_phy) {
+ if (BCMCPU_IS_6348())
+ val |= GPIO_MODE_6348_G3_EXT_MII |
+ GPIO_MODE_6348_G0_EXT_MII;
+ }
+
+ bcm_gpio_writel(val, GPIO_MODE_REG);
+
+ /* Generate MAC address for WLAN and
+ * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+ if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+ memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+ memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+ if (ssb_arch_register_fallback_sprom(
+ &bcm63xx_get_fallback_sprom) < 0)
+ printk(KERN_ERR PFX "failed to register fallback SPROM\n");
+ }
+#endif
+}
+
+/*
+ * second stage init callback, good time to panic if we couldn't
+ * identify on which board we're running since early printk is working
+ */
+void __init board_setup(void)
+{
+ if (!board.name[0])
+ panic("unable to detect bcm963xx board");
+ printk(KERN_INFO PFX "board name: %s\n", board.name);
+
+ /* make sure we're running on expected cpu */
+ if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
+ panic("unexpected CPU for bcm963xx board");
+}
+
+static struct mtd_partition mtd_partitions[] = {
+ {
+ .name = "cfe",
+ .offset = 0x0,
+ .size = 0x40000,
+ }
+};
+
+static struct physmap_flash_data flash_data = {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(mtd_partitions),
+ .parts = mtd_partitions,
+};
+
+static struct resource mtd_resources[] = {
+ {
+ .start = 0, /* filled at runtime */
+ .end = 0, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device mtd_dev = {
+ .name = "physmap-flash",
+ .resource = mtd_resources,
+ .num_resources = ARRAY_SIZE(mtd_resources),
+ .dev = {
+ .platform_data = &flash_data,
+ },
+};
+
+static struct gpio_led_platform_data bcm63xx_led_data;
+
+static struct platform_device bcm63xx_gpio_leds = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev.platform_data = &bcm63xx_led_data,
+};
+
+/*
+ * third stage init callback, register all board devices.
+ */
+int __init board_register_devices(void)
+{
+ u32 val;
+
+ if (board.has_uart0)
+ bcm63xx_uart_register(0);
+
+ if (board.has_uart1)
+ bcm63xx_uart_register(1);
+
+ if (board.has_pccard)
+ bcm63xx_pcmcia_register();
+
+ if (board.has_enet0 &&
+ !board_get_mac_address(board.enet0.mac_addr))
+ bcm63xx_enet_register(0, &board.enet0);
+
+ if (board.has_enet1 &&
+ !board_get_mac_address(board.enet1.mac_addr))
+ bcm63xx_enet_register(1, &board.enet1);
+
+ if (board.has_dsp)
+ bcm63xx_dsp_register(&board.dsp);
+
+ /* read base address of boot chip select (0) */
+ if (BCMCPU_IS_6345())
+ val = 0x1fc00000;
+ else {
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+ }
+ mtd_resources[0].start = val;
+ mtd_resources[0].end = 0x1FFFFFFF;
+
+ platform_device_register(&mtd_dev);
+
+ bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
+ bcm63xx_led_data.leds = board.leds;
+
+ platform_device_register(&bcm63xx_gpio_leds);
+
+ return 0;
+}
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
new file mode 100644
index 00000000..2c68ee9c
--- /dev/null
+++ b/arch/mips/bcm63xx/clk.c
@@ -0,0 +1,226 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_clk.h>
+
+static DEFINE_MUTEX(clocks_mutex);
+
+
+static void clk_enable_unlocked(struct clk *clk)
+{
+ if (clk->set && (clk->usage++) == 0)
+ clk->set(clk, 1);
+}
+
+static void clk_disable_unlocked(struct clk *clk)
+{
+ if (clk->set && (--clk->usage) == 0)
+ clk->set(clk, 0);
+}
+
+static void bcm_hwclock_set(u32 mask, int enable)
+{
+ u32 reg;
+
+ reg = bcm_perf_readl(PERF_CKCTL_REG);
+ if (enable)
+ reg |= mask;
+ else
+ reg &= ~mask;
+ bcm_perf_writel(reg, PERF_CKCTL_REG);
+}
+
+/*
+ * Ethernet MAC "misc" clock: dma clocks and main clock on 6348
+ */
+static void enet_misc_set(struct clk *clk, int enable)
+{
+ u32 mask;
+
+ if (BCMCPU_IS_6338())
+ mask = CKCTL_6338_ENET_EN;
+ else if (BCMCPU_IS_6345())
+ mask = CKCTL_6345_ENET_EN;
+ else if (BCMCPU_IS_6348())
+ mask = CKCTL_6348_ENET_EN;
+ else
+ /* BCMCPU_IS_6358 */
+ mask = CKCTL_6358_EMUSB_EN;
+ bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_enet_misc = {
+ .set = enet_misc_set,
+};
+
+/*
+ * Ethernet MAC clocks: only revelant on 6358, silently enable misc
+ * clocks
+ */
+static void enetx_set(struct clk *clk, int enable)
+{
+ if (enable)
+ clk_enable_unlocked(&clk_enet_misc);
+ else
+ clk_disable_unlocked(&clk_enet_misc);
+
+ if (BCMCPU_IS_6358()) {
+ u32 mask;
+
+ if (clk->id == 0)
+ mask = CKCTL_6358_ENET0_EN;
+ else
+ mask = CKCTL_6358_ENET1_EN;
+ bcm_hwclock_set(mask, enable);
+ }
+}
+
+static struct clk clk_enet0 = {
+ .id = 0,
+ .set = enetx_set,
+};
+
+static struct clk clk_enet1 = {
+ .id = 1,
+ .set = enetx_set,
+};
+
+/*
+ * Ethernet PHY clock
+ */
+static void ephy_set(struct clk *clk, int enable)
+{
+ if (!BCMCPU_IS_6358())
+ return;
+ bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
+}
+
+
+static struct clk clk_ephy = {
+ .set = ephy_set,
+};
+
+/*
+ * PCM clock
+ */
+static void pcm_set(struct clk *clk, int enable)
+{
+ if (!BCMCPU_IS_6358())
+ return;
+ bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
+}
+
+static struct clk clk_pcm = {
+ .set = pcm_set,
+};
+
+/*
+ * USB host clock
+ */
+static void usbh_set(struct clk *clk, int enable)
+{
+ if (!BCMCPU_IS_6348())
+ return;
+ bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
+}
+
+static struct clk clk_usbh = {
+ .set = usbh_set,
+};
+
+/*
+ * SPI clock
+ */
+static void spi_set(struct clk *clk, int enable)
+{
+ u32 mask;
+
+ if (BCMCPU_IS_6338())
+ mask = CKCTL_6338_SPI_EN;
+ else if (BCMCPU_IS_6348())
+ mask = CKCTL_6348_SPI_EN;
+ else
+ /* BCMCPU_IS_6358 */
+ mask = CKCTL_6358_SPI_EN;
+ bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_spi = {
+ .set = spi_set,
+};
+
+/*
+ * Internal peripheral clock
+ */
+static struct clk clk_periph = {
+ .rate = (50 * 1000 * 1000),
+};
+
+
+/*
+ * Linux clock API implementation
+ */
+int clk_enable(struct clk *clk)
+{
+ mutex_lock(&clocks_mutex);
+ clk_enable_unlocked(clk);
+ mutex_unlock(&clocks_mutex);
+ return 0;
+}
+
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ mutex_lock(&clocks_mutex);
+ clk_disable_unlocked(clk);
+ mutex_unlock(&clocks_mutex);
+}
+
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ if (!strcmp(id, "enet0"))
+ return &clk_enet0;
+ if (!strcmp(id, "enet1"))
+ return &clk_enet1;
+ if (!strcmp(id, "ephy"))
+ return &clk_ephy;
+ if (!strcmp(id, "usbh"))
+ return &clk_usbh;
+ if (!strcmp(id, "spi"))
+ return &clk_spi;
+ if (!strcmp(id, "periph"))
+ return &clk_periph;
+ if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
+ return &clk_pcm;
+ return ERR_PTR(-ENOENT);
+}
+
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+
+EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
new file mode 100644
index 00000000..7c7e4d44
--- /dev/null
+++ b/arch/mips/bcm63xx/cpu.c
@@ -0,0 +1,353 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <asm/cpu.h>
+#include <asm/cpu-info.h>
+#include <asm/mipsregs.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_irq.h>
+
+const unsigned long *bcm63xx_regs_base;
+EXPORT_SYMBOL(bcm63xx_regs_base);
+
+const int *bcm63xx_irqs;
+EXPORT_SYMBOL(bcm63xx_irqs);
+
+static u16 bcm63xx_cpu_id;
+static u16 bcm63xx_cpu_rev;
+static unsigned int bcm63xx_cpu_freq;
+static unsigned int bcm63xx_memory_size;
+
+/*
+ * 6338 register sets and irqs
+ */
+static const unsigned long bcm96338_regs_base[] = {
+ [RSET_DSL_LMEM] = BCM_6338_DSL_LMEM_BASE,
+ [RSET_PERF] = BCM_6338_PERF_BASE,
+ [RSET_TIMER] = BCM_6338_TIMER_BASE,
+ [RSET_WDT] = BCM_6338_WDT_BASE,
+ [RSET_UART0] = BCM_6338_UART0_BASE,
+ [RSET_UART1] = BCM_6338_UART1_BASE,
+ [RSET_GPIO] = BCM_6338_GPIO_BASE,
+ [RSET_SPI] = BCM_6338_SPI_BASE,
+ [RSET_OHCI0] = BCM_6338_OHCI0_BASE,
+ [RSET_OHCI_PRIV] = BCM_6338_OHCI_PRIV_BASE,
+ [RSET_USBH_PRIV] = BCM_6338_USBH_PRIV_BASE,
+ [RSET_UDC0] = BCM_6338_UDC0_BASE,
+ [RSET_MPI] = BCM_6338_MPI_BASE,
+ [RSET_PCMCIA] = BCM_6338_PCMCIA_BASE,
+ [RSET_SDRAM] = BCM_6338_SDRAM_BASE,
+ [RSET_DSL] = BCM_6338_DSL_BASE,
+ [RSET_ENET0] = BCM_6338_ENET0_BASE,
+ [RSET_ENET1] = BCM_6338_ENET1_BASE,
+ [RSET_ENETDMA] = BCM_6338_ENETDMA_BASE,
+ [RSET_MEMC] = BCM_6338_MEMC_BASE,
+ [RSET_DDR] = BCM_6338_DDR_BASE,
+};
+
+static const int bcm96338_irqs[] = {
+ [IRQ_TIMER] = BCM_6338_TIMER_IRQ,
+ [IRQ_UART0] = BCM_6338_UART0_IRQ,
+ [IRQ_DSL] = BCM_6338_DSL_IRQ,
+ [IRQ_ENET0] = BCM_6338_ENET0_IRQ,
+ [IRQ_ENET_PHY] = BCM_6338_ENET_PHY_IRQ,
+ [IRQ_ENET0_RXDMA] = BCM_6338_ENET0_RXDMA_IRQ,
+ [IRQ_ENET0_TXDMA] = BCM_6338_ENET0_TXDMA_IRQ,
+};
+
+/*
+ * 6345 register sets and irqs
+ */
+static const unsigned long bcm96345_regs_base[] = {
+ [RSET_DSL_LMEM] = BCM_6345_DSL_LMEM_BASE,
+ [RSET_PERF] = BCM_6345_PERF_BASE,
+ [RSET_TIMER] = BCM_6345_TIMER_BASE,
+ [RSET_WDT] = BCM_6345_WDT_BASE,
+ [RSET_UART0] = BCM_6345_UART0_BASE,
+ [RSET_UART1] = BCM_6345_UART1_BASE,
+ [RSET_GPIO] = BCM_6345_GPIO_BASE,
+ [RSET_SPI] = BCM_6345_SPI_BASE,
+ [RSET_UDC0] = BCM_6345_UDC0_BASE,
+ [RSET_OHCI0] = BCM_6345_OHCI0_BASE,
+ [RSET_OHCI_PRIV] = BCM_6345_OHCI_PRIV_BASE,
+ [RSET_USBH_PRIV] = BCM_6345_USBH_PRIV_BASE,
+ [RSET_MPI] = BCM_6345_MPI_BASE,
+ [RSET_PCMCIA] = BCM_6345_PCMCIA_BASE,
+ [RSET_DSL] = BCM_6345_DSL_BASE,
+ [RSET_ENET0] = BCM_6345_ENET0_BASE,
+ [RSET_ENET1] = BCM_6345_ENET1_BASE,
+ [RSET_ENETDMA] = BCM_6345_ENETDMA_BASE,
+ [RSET_EHCI0] = BCM_6345_EHCI0_BASE,
+ [RSET_SDRAM] = BCM_6345_SDRAM_BASE,
+ [RSET_MEMC] = BCM_6345_MEMC_BASE,
+ [RSET_DDR] = BCM_6345_DDR_BASE,
+};
+
+static const int bcm96345_irqs[] = {
+ [IRQ_TIMER] = BCM_6345_TIMER_IRQ,
+ [IRQ_UART0] = BCM_6345_UART0_IRQ,
+ [IRQ_DSL] = BCM_6345_DSL_IRQ,
+ [IRQ_ENET0] = BCM_6345_ENET0_IRQ,
+ [IRQ_ENET_PHY] = BCM_6345_ENET_PHY_IRQ,
+ [IRQ_ENET0_RXDMA] = BCM_6345_ENET0_RXDMA_IRQ,
+ [IRQ_ENET0_TXDMA] = BCM_6345_ENET0_TXDMA_IRQ,
+};
+
+/*
+ * 6348 register sets and irqs
+ */
+static const unsigned long bcm96348_regs_base[] = {
+ [RSET_DSL_LMEM] = BCM_6348_DSL_LMEM_BASE,
+ [RSET_PERF] = BCM_6348_PERF_BASE,
+ [RSET_TIMER] = BCM_6348_TIMER_BASE,
+ [RSET_WDT] = BCM_6348_WDT_BASE,
+ [RSET_UART0] = BCM_6348_UART0_BASE,
+ [RSET_UART1] = BCM_6348_UART1_BASE,
+ [RSET_GPIO] = BCM_6348_GPIO_BASE,
+ [RSET_SPI] = BCM_6348_SPI_BASE,
+ [RSET_OHCI0] = BCM_6348_OHCI0_BASE,
+ [RSET_OHCI_PRIV] = BCM_6348_OHCI_PRIV_BASE,
+ [RSET_USBH_PRIV] = BCM_6348_USBH_PRIV_BASE,
+ [RSET_MPI] = BCM_6348_MPI_BASE,
+ [RSET_PCMCIA] = BCM_6348_PCMCIA_BASE,
+ [RSET_SDRAM] = BCM_6348_SDRAM_BASE,
+ [RSET_DSL] = BCM_6348_DSL_BASE,
+ [RSET_ENET0] = BCM_6348_ENET0_BASE,
+ [RSET_ENET1] = BCM_6348_ENET1_BASE,
+ [RSET_ENETDMA] = BCM_6348_ENETDMA_BASE,
+ [RSET_MEMC] = BCM_6348_MEMC_BASE,
+ [RSET_DDR] = BCM_6348_DDR_BASE,
+};
+
+static const int bcm96348_irqs[] = {
+ [IRQ_TIMER] = BCM_6348_TIMER_IRQ,
+ [IRQ_UART0] = BCM_6348_UART0_IRQ,
+ [IRQ_DSL] = BCM_6348_DSL_IRQ,
+ [IRQ_ENET0] = BCM_6348_ENET0_IRQ,
+ [IRQ_ENET1] = BCM_6348_ENET1_IRQ,
+ [IRQ_ENET_PHY] = BCM_6348_ENET_PHY_IRQ,
+ [IRQ_OHCI0] = BCM_6348_OHCI0_IRQ,
+ [IRQ_PCMCIA] = BCM_6348_PCMCIA_IRQ,
+ [IRQ_ENET0_RXDMA] = BCM_6348_ENET0_RXDMA_IRQ,
+ [IRQ_ENET0_TXDMA] = BCM_6348_ENET0_TXDMA_IRQ,
+ [IRQ_ENET1_RXDMA] = BCM_6348_ENET1_RXDMA_IRQ,
+ [IRQ_ENET1_TXDMA] = BCM_6348_ENET1_TXDMA_IRQ,
+ [IRQ_PCI] = BCM_6348_PCI_IRQ,
+};
+
+/*
+ * 6358 register sets and irqs
+ */
+static const unsigned long bcm96358_regs_base[] = {
+ [RSET_DSL_LMEM] = BCM_6358_DSL_LMEM_BASE,
+ [RSET_PERF] = BCM_6358_PERF_BASE,
+ [RSET_TIMER] = BCM_6358_TIMER_BASE,
+ [RSET_WDT] = BCM_6358_WDT_BASE,
+ [RSET_UART0] = BCM_6358_UART0_BASE,
+ [RSET_UART1] = BCM_6358_UART1_BASE,
+ [RSET_GPIO] = BCM_6358_GPIO_BASE,
+ [RSET_SPI] = BCM_6358_SPI_BASE,
+ [RSET_OHCI0] = BCM_6358_OHCI0_BASE,
+ [RSET_EHCI0] = BCM_6358_EHCI0_BASE,
+ [RSET_OHCI_PRIV] = BCM_6358_OHCI_PRIV_BASE,
+ [RSET_USBH_PRIV] = BCM_6358_USBH_PRIV_BASE,
+ [RSET_MPI] = BCM_6358_MPI_BASE,
+ [RSET_PCMCIA] = BCM_6358_PCMCIA_BASE,
+ [RSET_SDRAM] = BCM_6358_SDRAM_BASE,
+ [RSET_DSL] = BCM_6358_DSL_BASE,
+ [RSET_ENET0] = BCM_6358_ENET0_BASE,
+ [RSET_ENET1] = BCM_6358_ENET1_BASE,
+ [RSET_ENETDMA] = BCM_6358_ENETDMA_BASE,
+ [RSET_MEMC] = BCM_6358_MEMC_BASE,
+ [RSET_DDR] = BCM_6358_DDR_BASE,
+};
+
+static const int bcm96358_irqs[] = {
+ [IRQ_TIMER] = BCM_6358_TIMER_IRQ,
+ [IRQ_UART0] = BCM_6358_UART0_IRQ,
+ [IRQ_UART1] = BCM_6358_UART1_IRQ,
+ [IRQ_DSL] = BCM_6358_DSL_IRQ,
+ [IRQ_ENET0] = BCM_6358_ENET0_IRQ,
+ [IRQ_ENET1] = BCM_6358_ENET1_IRQ,
+ [IRQ_ENET_PHY] = BCM_6358_ENET_PHY_IRQ,
+ [IRQ_OHCI0] = BCM_6358_OHCI0_IRQ,
+ [IRQ_EHCI0] = BCM_6358_EHCI0_IRQ,
+ [IRQ_PCMCIA] = BCM_6358_PCMCIA_IRQ,
+ [IRQ_ENET0_RXDMA] = BCM_6358_ENET0_RXDMA_IRQ,
+ [IRQ_ENET0_TXDMA] = BCM_6358_ENET0_TXDMA_IRQ,
+ [IRQ_ENET1_RXDMA] = BCM_6358_ENET1_RXDMA_IRQ,
+ [IRQ_ENET1_TXDMA] = BCM_6358_ENET1_TXDMA_IRQ,
+ [IRQ_PCI] = BCM_6358_PCI_IRQ,
+};
+
+u16 __bcm63xx_get_cpu_id(void)
+{
+ return bcm63xx_cpu_id;
+}
+
+EXPORT_SYMBOL(__bcm63xx_get_cpu_id);
+
+u16 bcm63xx_get_cpu_rev(void)
+{
+ return bcm63xx_cpu_rev;
+}
+
+EXPORT_SYMBOL(bcm63xx_get_cpu_rev);
+
+unsigned int bcm63xx_get_cpu_freq(void)
+{
+ return bcm63xx_cpu_freq;
+}
+
+unsigned int bcm63xx_get_memory_size(void)
+{
+ return bcm63xx_memory_size;
+}
+
+static unsigned int detect_cpu_clock(void)
+{
+ unsigned int tmp, n1 = 0, n2 = 0, m1 = 0;
+
+ /* BCM6338 has a fixed 240 Mhz frequency */
+ if (BCMCPU_IS_6338())
+ return 240000000;
+
+ /* BCM6345 has a fixed 140Mhz frequency */
+ if (BCMCPU_IS_6345())
+ return 140000000;
+
+ /*
+ * frequency depends on PLL configuration:
+ */
+ if (BCMCPU_IS_6348()) {
+ /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
+ tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
+ n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
+ n2 = (tmp & MIPSPLLCTL_N2_MASK) >> MIPSPLLCTL_N2_SHIFT;
+ m1 = (tmp & MIPSPLLCTL_M1CPU_MASK) >> MIPSPLLCTL_M1CPU_SHIFT;
+ n1 += 1;
+ n2 += 2;
+ m1 += 1;
+ }
+
+ if (BCMCPU_IS_6358()) {
+ /* 16MHz * N1 * N2 / M1_CPU */
+ tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
+ n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
+ n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
+ m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
+ }
+
+ return (16 * 1000000 * n1 * n2) / m1;
+}
+
+/*
+ * attempt to detect the amount of memory installed
+ */
+static unsigned int detect_memory_size(void)
+{
+ unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
+ u32 val;
+
+ if (BCMCPU_IS_6345())
+ return (8 * 1024 * 1024);
+
+ if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
+ val = bcm_sdram_readl(SDRAM_CFG_REG);
+ rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT;
+ cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT;
+ is_32bits = (val & SDRAM_CFG_32B_MASK) ? 1 : 0;
+ banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
+ }
+
+ if (BCMCPU_IS_6358()) {
+ val = bcm_memc_readl(MEMC_CFG_REG);
+ rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
+ cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
+ is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
+ banks = 2;
+ }
+
+ /* 0 => 11 address bits ... 2 => 13 address bits */
+ rows += 11;
+
+ /* 0 => 8 address bits ... 2 => 10 address bits */
+ cols += 8;
+
+ return 1 << (cols + rows + (is_32bits + 1) + banks);
+}
+
+void __init bcm63xx_cpu_init(void)
+{
+ unsigned int tmp, expected_cpu_id;
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int cpu = smp_processor_id();
+
+ /* soc registers location depends on cpu type */
+ expected_cpu_id = 0;
+
+ switch (c->cputype) {
+ case CPU_BMIPS3300:
+ if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) {
+ expected_cpu_id = BCM6348_CPU_ID;
+ bcm63xx_regs_base = bcm96348_regs_base;
+ bcm63xx_irqs = bcm96348_irqs;
+ } else {
+ __cpu_name[cpu] = "Broadcom BCM6338";
+ expected_cpu_id = BCM6338_CPU_ID;
+ bcm63xx_regs_base = bcm96338_regs_base;
+ bcm63xx_irqs = bcm96338_irqs;
+ }
+ break;
+ case CPU_BMIPS32:
+ expected_cpu_id = BCM6345_CPU_ID;
+ bcm63xx_regs_base = bcm96345_regs_base;
+ bcm63xx_irqs = bcm96345_irqs;
+ break;
+ case CPU_BMIPS4350:
+ expected_cpu_id = BCM6358_CPU_ID;
+ bcm63xx_regs_base = bcm96358_regs_base;
+ bcm63xx_irqs = bcm96358_irqs;
+ break;
+ }
+
+ /*
+ * really early to panic, but delaying panic would not help since we
+ * will never get any working console
+ */
+ if (!expected_cpu_id)
+ panic("unsupported Broadcom CPU");
+
+ /*
+ * bcm63xx_regs_base is set, we can access soc registers
+ */
+
+ /* double check CPU type */
+ tmp = bcm_perf_readl(PERF_REV_REG);
+ bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
+ bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
+
+ if (bcm63xx_cpu_id != expected_cpu_id)
+ panic("bcm63xx CPU id mismatch");
+
+ bcm63xx_cpu_freq = detect_cpu_clock();
+ bcm63xx_memory_size = detect_memory_size();
+
+ printk(KERN_INFO "Detected Broadcom 0x%04x CPU revision %02x\n",
+ bcm63xx_cpu_id, bcm63xx_cpu_rev);
+ printk(KERN_INFO "CPU frequency is %u MHz\n",
+ bcm63xx_cpu_freq / 1000000);
+ printk(KERN_INFO "%uMB of RAM installed\n",
+ bcm63xx_memory_size >> 20);
+}
diff --git a/arch/mips/bcm63xx/cs.c b/arch/mips/bcm63xx/cs.c
new file mode 100644
index 00000000..50d8190b
--- /dev/null
+++ b/arch/mips/bcm63xx/cs.c
@@ -0,0 +1,144 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/log2.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_cs.h>
+
+static DEFINE_SPINLOCK(bcm63xx_cs_lock);
+
+/*
+ * check if given chip select exists
+ */
+static int is_valid_cs(unsigned int cs)
+{
+ if (cs > 6)
+ return 0;
+ return 1;
+}
+
+/*
+ * Configure chipselect base address and size (bytes).
+ * Size must be a power of two between 8k and 256M.
+ */
+int bcm63xx_set_cs_base(unsigned int cs, u32 base, unsigned int size)
+{
+ unsigned long flags;
+ u32 val;
+
+ if (!is_valid_cs(cs))
+ return -EINVAL;
+
+ /* sanity check on size */
+ if (size != roundup_pow_of_two(size))
+ return -EINVAL;
+
+ if (size < 8 * 1024 || size > 256 * 1024 * 1024)
+ return -EINVAL;
+
+ val = (base & MPI_CSBASE_BASE_MASK);
+ /* 8k => 0 - 256M => 15 */
+ val |= (ilog2(size) - ilog2(8 * 1024)) << MPI_CSBASE_SIZE_SHIFT;
+
+ spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+ bcm_mpi_writel(val, MPI_CSBASE_REG(cs));
+ spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_base);
+
+/*
+ * configure chipselect timing (ns)
+ */
+int bcm63xx_set_cs_timing(unsigned int cs, unsigned int wait,
+ unsigned int setup, unsigned int hold)
+{
+ unsigned long flags;
+ u32 val;
+
+ if (!is_valid_cs(cs))
+ return -EINVAL;
+
+ spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+ val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+ val &= ~(MPI_CSCTL_WAIT_MASK);
+ val &= ~(MPI_CSCTL_SETUP_MASK);
+ val &= ~(MPI_CSCTL_HOLD_MASK);
+ val |= wait << MPI_CSCTL_WAIT_SHIFT;
+ val |= setup << MPI_CSCTL_SETUP_SHIFT;
+ val |= hold << MPI_CSCTL_HOLD_SHIFT;
+ bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+ spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_timing);
+
+/*
+ * configure other chipselect parameter (data bus size, ...)
+ */
+int bcm63xx_set_cs_param(unsigned int cs, u32 params)
+{
+ unsigned long flags;
+ u32 val;
+
+ if (!is_valid_cs(cs))
+ return -EINVAL;
+
+ /* none of this fields apply to pcmcia */
+ if (cs == MPI_CS_PCMCIA_COMMON ||
+ cs == MPI_CS_PCMCIA_ATTR ||
+ cs == MPI_CS_PCMCIA_IO)
+ return -EINVAL;
+
+ spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+ val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+ val &= ~(MPI_CSCTL_DATA16_MASK);
+ val &= ~(MPI_CSCTL_SYNCMODE_MASK);
+ val &= ~(MPI_CSCTL_TSIZE_MASK);
+ val &= ~(MPI_CSCTL_ENDIANSWAP_MASK);
+ val |= params;
+ bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+ spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_param);
+
+/*
+ * set cs status (enable/disable)
+ */
+int bcm63xx_set_cs_status(unsigned int cs, int enable)
+{
+ unsigned long flags;
+ u32 val;
+
+ if (!is_valid_cs(cs))
+ return -EINVAL;
+
+ spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+ val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+ if (enable)
+ val |= MPI_CSCTL_ENABLE_MASK;
+ else
+ val &= ~MPI_CSCTL_ENABLE_MASK;
+ bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+ spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_status);
diff --git a/arch/mips/bcm63xx/dev-dsp.c b/arch/mips/bcm63xx/dev-dsp.c
new file mode 100644
index 00000000..da46d1d3
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-dsp.c
@@ -0,0 +1,56 @@
+/*
+ * Broadcom BCM63xx VoIP DSP registration
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_dsp.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static struct resource voip_dsp_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bcm63xx_voip_dsp_device = {
+ .name = "bcm63xx-voip-dsp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(voip_dsp_resources),
+ .resource = voip_dsp_resources,
+};
+
+int __init bcm63xx_dsp_register(const struct bcm63xx_dsp_platform_data *pd)
+{
+ struct bcm63xx_dsp_platform_data *dpd;
+ u32 val;
+
+ /* Get the memory window */
+ val = bcm_mpi_readl(MPI_CSBASE_REG(pd->cs - 1));
+ val &= MPI_CSBASE_BASE_MASK;
+ voip_dsp_resources[0].start = val;
+ voip_dsp_resources[0].end = val + 0xFFFFFFF;
+ voip_dsp_resources[1].start = pd->ext_irq;
+
+ /* copy given platform data */
+ dpd = bcm63xx_voip_dsp_device.dev.platform_data;
+ memcpy(dpd, pd, sizeof (*pd));
+
+ return platform_device_register(&bcm63xx_voip_dsp_device);
+}
diff --git a/arch/mips/bcm63xx/dev-enet.c b/arch/mips/bcm63xx/dev-enet.c
new file mode 100644
index 00000000..39c23366
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-enet.c
@@ -0,0 +1,162 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static struct resource shared_res[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bcm63xx_enet_shared_device = {
+ .name = "bcm63xx_enet_shared",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(shared_res),
+ .resource = shared_res,
+};
+
+static int shared_device_registered;
+
+static struct resource enet0_res[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct bcm63xx_enet_platform_data enet0_pd;
+
+static struct platform_device bcm63xx_enet0_device = {
+ .name = "bcm63xx_enet",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(enet0_res),
+ .resource = enet0_res,
+ .dev = {
+ .platform_data = &enet0_pd,
+ },
+};
+
+static struct resource enet1_res[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct bcm63xx_enet_platform_data enet1_pd;
+
+static struct platform_device bcm63xx_enet1_device = {
+ .name = "bcm63xx_enet",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(enet1_res),
+ .resource = enet1_res,
+ .dev = {
+ .platform_data = &enet1_pd,
+ },
+};
+
+int __init bcm63xx_enet_register(int unit,
+ const struct bcm63xx_enet_platform_data *pd)
+{
+ struct platform_device *pdev;
+ struct bcm63xx_enet_platform_data *dpd;
+ int ret;
+
+ if (unit > 1)
+ return -ENODEV;
+
+ if (unit == 1 && BCMCPU_IS_6338())
+ return -ENODEV;
+
+ if (!shared_device_registered) {
+ shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
+ shared_res[0].end = shared_res[0].start;
+ if (BCMCPU_IS_6338())
+ shared_res[0].end += (RSET_ENETDMA_SIZE / 2) - 1;
+ else
+ shared_res[0].end += (RSET_ENETDMA_SIZE) - 1;
+
+ ret = platform_device_register(&bcm63xx_enet_shared_device);
+ if (ret)
+ return ret;
+ shared_device_registered = 1;
+ }
+
+ if (unit == 0) {
+ enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0);
+ enet0_res[0].end = enet0_res[0].start;
+ enet0_res[0].end += RSET_ENET_SIZE - 1;
+ enet0_res[1].start = bcm63xx_get_irq_number(IRQ_ENET0);
+ enet0_res[2].start = bcm63xx_get_irq_number(IRQ_ENET0_RXDMA);
+ enet0_res[3].start = bcm63xx_get_irq_number(IRQ_ENET0_TXDMA);
+ pdev = &bcm63xx_enet0_device;
+ } else {
+ enet1_res[0].start = bcm63xx_regset_address(RSET_ENET1);
+ enet1_res[0].end = enet1_res[0].start;
+ enet1_res[0].end += RSET_ENET_SIZE - 1;
+ enet1_res[1].start = bcm63xx_get_irq_number(IRQ_ENET1);
+ enet1_res[2].start = bcm63xx_get_irq_number(IRQ_ENET1_RXDMA);
+ enet1_res[3].start = bcm63xx_get_irq_number(IRQ_ENET1_TXDMA);
+ pdev = &bcm63xx_enet1_device;
+ }
+
+ /* copy given platform data */
+ dpd = pdev->dev.platform_data;
+ memcpy(dpd, pd, sizeof(*pd));
+
+ /* adjust them in case internal phy is used */
+ if (dpd->use_internal_phy) {
+
+ /* internal phy only exists for enet0 */
+ if (unit == 1)
+ return -ENODEV;
+
+ dpd->phy_id = 1;
+ dpd->has_phy_interrupt = 1;
+ dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
+ }
+
+ ret = platform_device_register(pdev);
+ if (ret)
+ return ret;
+ return 0;
+}
diff --git a/arch/mips/bcm63xx/dev-pcmcia.c b/arch/mips/bcm63xx/dev-pcmcia.c
new file mode 100644
index 00000000..de4d917f
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-pcmcia.c
@@ -0,0 +1,144 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/bootinfo.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cs.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_pcmcia.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static struct resource pcmcia_resources[] = {
+ /* pcmcia registers */
+ {
+ /* start & end filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+
+ /* pcmcia memory zone resources */
+ {
+ .start = BCM_PCMCIA_COMMON_BASE_PA,
+ .end = BCM_PCMCIA_COMMON_END_PA,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = BCM_PCMCIA_ATTR_BASE_PA,
+ .end = BCM_PCMCIA_ATTR_END_PA,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = BCM_PCMCIA_IO_BASE_PA,
+ .end = BCM_PCMCIA_IO_END_PA,
+ .flags = IORESOURCE_MEM,
+ },
+
+ /* PCMCIA irq */
+ {
+ /* start filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+
+ /* declare PCMCIA IO resource also */
+ {
+ .start = BCM_PCMCIA_IO_BASE_PA,
+ .end = BCM_PCMCIA_IO_END_PA,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct bcm63xx_pcmcia_platform_data pd;
+
+static struct platform_device bcm63xx_pcmcia_device = {
+ .name = "bcm63xx_pcmcia",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(pcmcia_resources),
+ .resource = pcmcia_resources,
+ .dev = {
+ .platform_data = &pd,
+ },
+};
+
+static int __init config_pcmcia_cs(unsigned int cs,
+ u32 base, unsigned int size)
+{
+ int ret;
+
+ ret = bcm63xx_set_cs_status(cs, 0);
+ if (!ret)
+ ret = bcm63xx_set_cs_base(cs, base, size);
+ if (!ret)
+ ret = bcm63xx_set_cs_status(cs, 1);
+ return ret;
+}
+
+static const __initdata struct {
+ unsigned int cs;
+ unsigned int base;
+ unsigned int size;
+} pcmcia_cs[3] = {
+ {
+ .cs = MPI_CS_PCMCIA_COMMON,
+ .base = BCM_PCMCIA_COMMON_BASE_PA,
+ .size = BCM_PCMCIA_COMMON_SIZE
+ },
+ {
+ .cs = MPI_CS_PCMCIA_ATTR,
+ .base = BCM_PCMCIA_ATTR_BASE_PA,
+ .size = BCM_PCMCIA_ATTR_SIZE
+ },
+ {
+ .cs = MPI_CS_PCMCIA_IO,
+ .base = BCM_PCMCIA_IO_BASE_PA,
+ .size = BCM_PCMCIA_IO_SIZE
+ },
+};
+
+int __init bcm63xx_pcmcia_register(void)
+{
+ int ret, i;
+
+ if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
+ return 0;
+
+ /* use correct pcmcia ready gpio depending on processor */
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6348_CPU_ID:
+ pd.ready_gpio = 22;
+ break;
+
+ case BCM6358_CPU_ID:
+ pd.ready_gpio = 18;
+ break;
+
+ default:
+ return -ENODEV;
+ }
+
+ pcmcia_resources[0].start = bcm63xx_regset_address(RSET_PCMCIA);
+ pcmcia_resources[0].end = pcmcia_resources[0].start +
+ RSET_PCMCIA_SIZE - 1;
+ pcmcia_resources[4].start = bcm63xx_get_irq_number(IRQ_PCMCIA);
+
+ /* configure pcmcia chip selects */
+ for (i = 0; i < 3; i++) {
+ ret = config_pcmcia_cs(pcmcia_cs[i].cs,
+ pcmcia_cs[i].base,
+ pcmcia_cs[i].size);
+ if (ret)
+ goto out_err;
+ }
+
+ return platform_device_register(&bcm63xx_pcmcia_device);
+
+out_err:
+ printk(KERN_ERR "unable to set pcmcia chip select\n");
+ return ret;
+}
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c
new file mode 100644
index 00000000..c2963da0
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-uart.c
@@ -0,0 +1,75 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+
+static struct resource uart0_resources[] = {
+ {
+ /* start & end filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* start filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource uart1_resources[] = {
+ {
+ /* start & end filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* start filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bcm63xx_uart_devices[] = {
+ {
+ .name = "bcm63xx_uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+ .resource = uart0_resources,
+ },
+
+ {
+ .name = "bcm63xx_uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+ .resource = uart1_resources,
+ }
+};
+
+int __init bcm63xx_uart_register(unsigned int id)
+{
+ if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
+ return -ENODEV;
+
+ if (id == 1 && !BCMCPU_IS_6358())
+ return -ENODEV;
+
+ if (id == 0) {
+ uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
+ uart0_resources[0].end = uart0_resources[0].start +
+ RSET_UART_SIZE - 1;
+ uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
+ }
+
+ if (id == 1) {
+ uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
+ uart1_resources[0].end = uart1_resources[0].start +
+ RSET_UART_SIZE - 1;
+ uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
+ }
+
+ return platform_device_register(&bcm63xx_uart_devices[id]);
+}
diff --git a/arch/mips/bcm63xx/dev-wdt.c b/arch/mips/bcm63xx/dev-wdt.c
new file mode 100644
index 00000000..3e6c716a
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-wdt.c
@@ -0,0 +1,37 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+
+static struct resource wdt_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bcm63xx_wdt_device = {
+ .name = "bcm63xx-wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+int __init bcm63xx_wdt_register(void)
+{
+ wdt_resources[0].start = bcm63xx_regset_address(RSET_WDT);
+ wdt_resources[0].end = wdt_resources[0].start;
+ wdt_resources[0].end += RSET_WDT_SIZE - 1;
+
+ return platform_device_register(&bcm63xx_wdt_device);
+}
+arch_initcall(bcm63xx_wdt_register);
diff --git a/arch/mips/bcm63xx/early_printk.c b/arch/mips/bcm63xx/early_printk.c
new file mode 100644
index 00000000..bf353c93
--- /dev/null
+++ b/arch/mips/bcm63xx/early_printk.c
@@ -0,0 +1,30 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static void __init wait_xfered(void)
+{
+ unsigned int val;
+
+ /* wait for any previous char to be transmitted */
+ do {
+ val = bcm_uart0_readl(UART_IR_REG);
+ if (val & UART_IR_STAT(UART_IR_TXEMPTY))
+ break;
+ } while (1);
+}
+
+void __init prom_putchar(char c)
+{
+ wait_xfered();
+ bcm_uart0_writel(c, UART_FIFO_REG);
+ wait_xfered();
+}
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c
new file mode 100644
index 00000000..f560fe7d
--- /dev/null
+++ b/arch/mips/bcm63xx/gpio.c
@@ -0,0 +1,134 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_gpio.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static DEFINE_SPINLOCK(bcm63xx_gpio_lock);
+static u32 gpio_out_low, gpio_out_high;
+
+static void bcm63xx_gpio_set(struct gpio_chip *chip,
+ unsigned gpio, int val)
+{
+ u32 reg;
+ u32 mask;
+ u32 *v;
+ unsigned long flags;
+
+ if (gpio >= chip->ngpio)
+ BUG();
+
+ if (gpio < 32) {
+ reg = GPIO_DATA_LO_REG;
+ mask = 1 << gpio;
+ v = &gpio_out_low;
+ } else {
+ reg = GPIO_DATA_HI_REG;
+ mask = 1 << (gpio - 32);
+ v = &gpio_out_high;
+ }
+
+ spin_lock_irqsave(&bcm63xx_gpio_lock, flags);
+ if (val)
+ *v |= mask;
+ else
+ *v &= ~mask;
+ bcm_gpio_writel(*v, reg);
+ spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags);
+}
+
+static int bcm63xx_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+ u32 reg;
+ u32 mask;
+
+ if (gpio >= chip->ngpio)
+ BUG();
+
+ if (gpio < 32) {
+ reg = GPIO_DATA_LO_REG;
+ mask = 1 << gpio;
+ } else {
+ reg = GPIO_DATA_HI_REG;
+ mask = 1 << (gpio - 32);
+ }
+
+ return !!(bcm_gpio_readl(reg) & mask);
+}
+
+static int bcm63xx_gpio_set_direction(struct gpio_chip *chip,
+ unsigned gpio, int dir)
+{
+ u32 reg;
+ u32 mask;
+ u32 tmp;
+ unsigned long flags;
+
+ if (gpio >= chip->ngpio)
+ BUG();
+
+ if (gpio < 32) {
+ reg = GPIO_CTL_LO_REG;
+ mask = 1 << gpio;
+ } else {
+ reg = GPIO_CTL_HI_REG;
+ mask = 1 << (gpio - 32);
+ }
+
+ spin_lock_irqsave(&bcm63xx_gpio_lock, flags);
+ tmp = bcm_gpio_readl(reg);
+ if (dir == BCM63XX_GPIO_DIR_IN)
+ tmp &= ~mask;
+ else
+ tmp |= mask;
+ bcm_gpio_writel(tmp, reg);
+ spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags);
+
+ return 0;
+}
+
+static int bcm63xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ return bcm63xx_gpio_set_direction(chip, gpio, BCM63XX_GPIO_DIR_IN);
+}
+
+static int bcm63xx_gpio_direction_output(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ bcm63xx_gpio_set(chip, gpio, value);
+ return bcm63xx_gpio_set_direction(chip, gpio, BCM63XX_GPIO_DIR_OUT);
+}
+
+
+static struct gpio_chip bcm63xx_gpio_chip = {
+ .label = "bcm63xx-gpio",
+ .direction_input = bcm63xx_gpio_direction_input,
+ .direction_output = bcm63xx_gpio_direction_output,
+ .get = bcm63xx_gpio_get,
+ .set = bcm63xx_gpio_set,
+ .base = 0,
+};
+
+int __init bcm63xx_gpio_init(void)
+{
+ gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
+ gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
+ bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
+ pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
+
+ return gpiochip_add(&bcm63xx_gpio_chip);
+}
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
new file mode 100644
index 00000000..cea6021c
--- /dev/null
+++ b/arch/mips/bcm63xx/irq.c
@@ -0,0 +1,241 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Nicolas Schichan <nschichan@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_irq.h>
+
+/*
+ * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
+ * prioritize any interrupt relatively to another. the static counter
+ * will resume the loop where it ended the last time we left this
+ * function.
+ */
+static void bcm63xx_irq_dispatch_internal(void)
+{
+ u32 pending;
+ static int i;
+
+ pending = bcm_perf_readl(PERF_IRQMASK_REG) &
+ bcm_perf_readl(PERF_IRQSTAT_REG);
+
+ if (!pending)
+ return ;
+
+ while (1) {
+ int to_call = i;
+
+ i = (i + 1) & 0x1f;
+ if (pending & (1 << to_call)) {
+ do_IRQ(to_call + IRQ_INTERNAL_BASE);
+ break;
+ }
+ }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ u32 cause;
+
+ do {
+ cause = read_c0_cause() & read_c0_status() & ST0_IM;
+
+ if (!cause)
+ break;
+
+ if (cause & CAUSEF_IP7)
+ do_IRQ(7);
+ if (cause & CAUSEF_IP2)
+ bcm63xx_irq_dispatch_internal();
+ if (cause & CAUSEF_IP3)
+ do_IRQ(IRQ_EXT_0);
+ if (cause & CAUSEF_IP4)
+ do_IRQ(IRQ_EXT_1);
+ if (cause & CAUSEF_IP5)
+ do_IRQ(IRQ_EXT_2);
+ if (cause & CAUSEF_IP6)
+ do_IRQ(IRQ_EXT_3);
+ } while (1);
+}
+
+/*
+ * internal IRQs operations: only mask/unmask on PERF irq mask
+ * register.
+ */
+static inline void bcm63xx_internal_irq_mask(struct irq_data *d)
+{
+ unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
+ u32 mask;
+
+ mask = bcm_perf_readl(PERF_IRQMASK_REG);
+ mask &= ~(1 << irq);
+ bcm_perf_writel(mask, PERF_IRQMASK_REG);
+}
+
+static void bcm63xx_internal_irq_unmask(struct irq_data *d)
+{
+ unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
+ u32 mask;
+
+ mask = bcm_perf_readl(PERF_IRQMASK_REG);
+ mask |= (1 << irq);
+ bcm_perf_writel(mask, PERF_IRQMASK_REG);
+}
+
+/*
+ * external IRQs operations: mask/unmask and clear on PERF external
+ * irq control register.
+ */
+static void bcm63xx_external_irq_mask(struct irq_data *d)
+{
+ unsigned int irq = d->irq - IRQ_EXT_BASE;
+ u32 reg;
+
+ reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+ reg &= ~EXTIRQ_CFG_MASK(irq);
+ bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static void bcm63xx_external_irq_unmask(struct irq_data *d)
+{
+ unsigned int irq = d->irq - IRQ_EXT_BASE;
+ u32 reg;
+
+ reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+ reg |= EXTIRQ_CFG_MASK(irq);
+ bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static void bcm63xx_external_irq_clear(struct irq_data *d)
+{
+ unsigned int irq = d->irq - IRQ_EXT_BASE;
+ u32 reg;
+
+ reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+ reg |= EXTIRQ_CFG_CLEAR(irq);
+ bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static unsigned int bcm63xx_external_irq_startup(struct irq_data *d)
+{
+ set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
+ irq_enable_hazard();
+ bcm63xx_external_irq_unmask(d);
+ return 0;
+}
+
+static void bcm63xx_external_irq_shutdown(struct irq_data *d)
+{
+ bcm63xx_external_irq_mask(d);
+ clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
+ irq_disable_hazard();
+}
+
+static int bcm63xx_external_irq_set_type(struct irq_data *d,
+ unsigned int flow_type)
+{
+ unsigned int irq = d->irq - IRQ_EXT_BASE;
+ u32 reg;
+
+ flow_type &= IRQ_TYPE_SENSE_MASK;
+
+ if (flow_type == IRQ_TYPE_NONE)
+ flow_type = IRQ_TYPE_LEVEL_LOW;
+
+ reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+ reg |= EXTIRQ_CFG_BOTHEDGE(irq);
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+ reg |= EXTIRQ_CFG_SENSE(irq);
+ reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+ reg &= ~EXTIRQ_CFG_SENSE(irq);
+ reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ reg |= EXTIRQ_CFG_LEVELSENSE(irq);
+ reg |= EXTIRQ_CFG_SENSE(irq);
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ reg |= EXTIRQ_CFG_LEVELSENSE(irq);
+ reg &= ~EXTIRQ_CFG_SENSE(irq);
+ break;
+
+ default:
+ printk(KERN_ERR "bogus flow type combination given !\n");
+ return -EINVAL;
+ }
+ bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+
+ irqd_set_trigger_type(d, flow_type);
+ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ else
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+
+ return IRQ_SET_MASK_OK_NOCOPY;
+}
+
+static struct irq_chip bcm63xx_internal_irq_chip = {
+ .name = "bcm63xx_ipic",
+ .irq_mask = bcm63xx_internal_irq_mask,
+ .irq_unmask = bcm63xx_internal_irq_unmask,
+};
+
+static struct irq_chip bcm63xx_external_irq_chip = {
+ .name = "bcm63xx_epic",
+ .irq_startup = bcm63xx_external_irq_startup,
+ .irq_shutdown = bcm63xx_external_irq_shutdown,
+
+ .irq_ack = bcm63xx_external_irq_clear,
+
+ .irq_mask = bcm63xx_external_irq_mask,
+ .irq_unmask = bcm63xx_external_irq_unmask,
+
+ .irq_set_type = bcm63xx_external_irq_set_type,
+};
+
+static struct irqaction cpu_ip2_cascade_action = {
+ .handler = no_action,
+ .name = "cascade_ip2",
+};
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ mips_cpu_irq_init();
+ for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
+ irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip,
+ handle_level_irq);
+
+ for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
+ irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip,
+ handle_edge_irq);
+
+ setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);
+}
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
new file mode 100644
index 00000000..be252efa
--- /dev/null
+++ b/arch/mips/bcm63xx/prom.c
@@ -0,0 +1,52 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <asm/bootinfo.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_gpio.h>
+
+void __init prom_init(void)
+{
+ u32 reg, mask;
+
+ bcm63xx_cpu_init();
+
+ /* stop any running watchdog */
+ bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG);
+ bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
+
+ /* disable all hardware blocks clock for now */
+ if (BCMCPU_IS_6338())
+ mask = CKCTL_6338_ALL_SAFE_EN;
+ else if (BCMCPU_IS_6345())
+ mask = CKCTL_6345_ALL_SAFE_EN;
+ else if (BCMCPU_IS_6348())
+ mask = CKCTL_6348_ALL_SAFE_EN;
+ else
+ /* BCMCPU_IS_6358() */
+ mask = CKCTL_6358_ALL_SAFE_EN;
+
+ reg = bcm_perf_readl(PERF_CKCTL_REG);
+ reg &= ~mask;
+ bcm_perf_writel(reg, PERF_CKCTL_REG);
+
+ /* register gpiochip */
+ bcm63xx_gpio_init();
+
+ /* do low level board init */
+ board_prom_init();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
new file mode 100644
index 00000000..d0056598
--- /dev/null
+++ b/arch/mips/bcm63xx/setup.c
@@ -0,0 +1,127 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/reboot.h>
+#include <asm/cacheflush.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+void bcm63xx_machine_halt(void)
+{
+ printk(KERN_INFO "System halted\n");
+ while (1)
+ ;
+}
+
+static void bcm6348_a1_reboot(void)
+{
+ u32 reg;
+
+ /* soft reset all blocks */
+ printk(KERN_INFO "soft-reseting all blocks ...\n");
+ reg = bcm_perf_readl(PERF_SOFTRESET_REG);
+ reg &= ~SOFTRESET_6348_ALL;
+ bcm_perf_writel(reg, PERF_SOFTRESET_REG);
+ mdelay(10);
+
+ reg = bcm_perf_readl(PERF_SOFTRESET_REG);
+ reg |= SOFTRESET_6348_ALL;
+ bcm_perf_writel(reg, PERF_SOFTRESET_REG);
+ mdelay(10);
+
+ /* Jump to the power on address. */
+ printk(KERN_INFO "jumping to reset vector.\n");
+ /* set high vectors (base at 0xbfc00000 */
+ set_c0_status(ST0_BEV | ST0_ERL);
+ /* run uncached in kseg0 */
+ change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+ __flush_cache_all();
+ /* remove all wired TLB entries */
+ write_c0_wired(0);
+ __asm__ __volatile__(
+ "jr\t%0"
+ :
+ : "r" (0xbfc00000));
+ while (1)
+ ;
+}
+
+void bcm63xx_machine_reboot(void)
+{
+ u32 reg;
+
+ /* mask and clear all external irq */
+ reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+ reg &= ~EXTIRQ_CFG_MASK_ALL;
+ reg |= EXTIRQ_CFG_CLEAR_ALL;
+ bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+
+ if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
+ bcm6348_a1_reboot();
+
+ printk(KERN_INFO "triggering watchdog soft-reset...\n");
+ reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
+ reg |= SYS_PLL_SOFT_RESET;
+ bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
+ while (1)
+ ;
+}
+
+static void __bcm63xx_machine_reboot(char *p)
+{
+ bcm63xx_machine_reboot();
+}
+
+/*
+ * return system type in /proc/cpuinfo
+ */
+const char *get_system_type(void)
+{
+ static char buf[128];
+ snprintf(buf, sizeof(buf), "bcm63xx/%s (0x%04x/0x%04X)",
+ board_get_name(),
+ bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev());
+ return buf;
+}
+
+void __init plat_time_init(void)
+{
+ mips_hpt_frequency = bcm63xx_get_cpu_freq() / 2;
+}
+
+void __init plat_mem_setup(void)
+{
+ add_memory_region(0, bcm63xx_get_memory_size(), BOOT_MEM_RAM);
+
+ _machine_halt = bcm63xx_machine_halt;
+ _machine_restart = __bcm63xx_machine_reboot;
+ pm_power_off = bcm63xx_machine_halt;
+
+ set_io_port_base(0);
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+
+ board_setup();
+}
+
+int __init bcm63xx_register_devices(void)
+{
+ return board_register_devices();
+}
+
+arch_initcall(bcm63xx_register_devices);
diff --git a/arch/mips/bcm63xx/timer.c b/arch/mips/bcm63xx/timer.c
new file mode 100644
index 00000000..5f113598
--- /dev/null
+++ b/arch/mips/bcm63xx/timer.c
@@ -0,0 +1,205 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_timer.h>
+#include <bcm63xx_regs.h>
+
+static DEFINE_RAW_SPINLOCK(timer_reg_lock);
+static DEFINE_RAW_SPINLOCK(timer_data_lock);
+static struct clk *periph_clk;
+
+static struct timer_data {
+ void (*cb)(void *);
+ void *data;
+} timer_data[BCM63XX_TIMER_COUNT];
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ u32 stat;
+ int i;
+
+ raw_spin_lock(&timer_reg_lock);
+ stat = bcm_timer_readl(TIMER_IRQSTAT_REG);
+ bcm_timer_writel(stat, TIMER_IRQSTAT_REG);
+ raw_spin_unlock(&timer_reg_lock);
+
+ for (i = 0; i < BCM63XX_TIMER_COUNT; i++) {
+ if (!(stat & TIMER_IRQSTAT_TIMER_CAUSE(i)))
+ continue;
+
+ raw_spin_lock(&timer_data_lock);
+ if (!timer_data[i].cb) {
+ raw_spin_unlock(&timer_data_lock);
+ continue;
+ }
+
+ timer_data[i].cb(timer_data[i].data);
+ raw_spin_unlock(&timer_data_lock);
+ }
+
+ return IRQ_HANDLED;
+}
+
+int bcm63xx_timer_enable(int id)
+{
+ u32 reg;
+ unsigned long flags;
+
+ if (id >= BCM63XX_TIMER_COUNT)
+ return -EINVAL;
+
+ raw_spin_lock_irqsave(&timer_reg_lock, flags);
+
+ reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+ reg |= TIMER_CTL_ENABLE_MASK;
+ bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+ reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+ reg |= TIMER_IRQSTAT_TIMER_IR_EN(id);
+ bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+ raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_enable);
+
+int bcm63xx_timer_disable(int id)
+{
+ u32 reg;
+ unsigned long flags;
+
+ if (id >= BCM63XX_TIMER_COUNT)
+ return -EINVAL;
+
+ raw_spin_lock_irqsave(&timer_reg_lock, flags);
+
+ reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+ reg &= ~TIMER_CTL_ENABLE_MASK;
+ bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+ reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+ reg &= ~TIMER_IRQSTAT_TIMER_IR_EN(id);
+ bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+ raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_disable);
+
+int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data)
+{
+ unsigned long flags;
+ int ret;
+
+ if (id >= BCM63XX_TIMER_COUNT || !callback)
+ return -EINVAL;
+
+ ret = 0;
+ raw_spin_lock_irqsave(&timer_data_lock, flags);
+ if (timer_data[id].cb) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ timer_data[id].cb = callback;
+ timer_data[id].data = data;
+
+out:
+ raw_spin_unlock_irqrestore(&timer_data_lock, flags);
+ return ret;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_register);
+
+void bcm63xx_timer_unregister(int id)
+{
+ unsigned long flags;
+
+ if (id >= BCM63XX_TIMER_COUNT)
+ return;
+
+ raw_spin_lock_irqsave(&timer_data_lock, flags);
+ timer_data[id].cb = NULL;
+ raw_spin_unlock_irqrestore(&timer_data_lock, flags);
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_unregister);
+
+unsigned int bcm63xx_timer_countdown(unsigned int countdown_us)
+{
+ return (clk_get_rate(periph_clk) / (1000 * 1000)) * countdown_us;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_countdown);
+
+int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us)
+{
+ u32 reg, countdown;
+ unsigned long flags;
+
+ if (id >= BCM63XX_TIMER_COUNT)
+ return -EINVAL;
+
+ countdown = bcm63xx_timer_countdown(countdown_us);
+ if (countdown & ~TIMER_CTL_COUNTDOWN_MASK)
+ return -EINVAL;
+
+ raw_spin_lock_irqsave(&timer_reg_lock, flags);
+ reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+
+ if (monotonic)
+ reg &= ~TIMER_CTL_MONOTONIC_MASK;
+ else
+ reg |= TIMER_CTL_MONOTONIC_MASK;
+
+ reg &= ~TIMER_CTL_COUNTDOWN_MASK;
+ reg |= countdown;
+ bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+ raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_set);
+
+int bcm63xx_timer_init(void)
+{
+ int ret, irq;
+ u32 reg;
+
+ reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+ reg &= ~TIMER_IRQSTAT_TIMER0_IR_EN;
+ reg &= ~TIMER_IRQSTAT_TIMER1_IR_EN;
+ reg &= ~TIMER_IRQSTAT_TIMER2_IR_EN;
+ bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+ periph_clk = clk_get(NULL, "periph");
+ if (IS_ERR(periph_clk))
+ return -ENODEV;
+
+ irq = bcm63xx_get_irq_number(IRQ_TIMER);
+ ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL);
+ if (ret) {
+ printk(KERN_ERR "bcm63xx_timer: failed to register irq\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+arch_initcall(bcm63xx_timer_init);
diff --git a/arch/mips/boot/.gitignore b/arch/mips/boot/.gitignore
new file mode 100644
index 00000000..f210b09e
--- /dev/null
+++ b/arch/mips/boot/.gitignore
@@ -0,0 +1,6 @@
+mkboot
+elf2ecoff
+vmlinux.*
+zImage
+zImage.tmp
+calc_vmlinuz_load_addr
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
new file mode 100644
index 00000000..85bcb5ad
--- /dev/null
+++ b/arch/mips/boot/Makefile
@@ -0,0 +1,42 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995, 1998, 2001, 2002 by Ralf Baechle
+# Copyright (C) 2004 Maciej W. Rozycki
+#
+
+#
+# Some DECstations need all possible sections of an ECOFF executable
+#
+ifdef CONFIG_MACH_DECSTATION
+ e2eflag := -a
+endif
+
+#
+# Drop some uninteresting sections in the kernel.
+# This is only relevant for ELF kernels but doesn't hurt a.out
+#
+drop-sections := .reginfo .mdebug .comment .note .pdr .options .MIPS.options
+strip-flags := $(addprefix --remove-section=,$(drop-sections))
+
+hostprogs-y := elf2ecoff
+
+targets := vmlinux.ecoff
+quiet_cmd_ecoff = ECOFF $@
+ cmd_ecoff = $(obj)/elf2ecoff $(VMLINUX) $@ $(e2eflag)
+$(obj)/vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) FORCE
+ $(call if_changed,ecoff)
+
+targets += vmlinux.bin
+quiet_cmd_bin = OBJCOPY $@
+ cmd_bin = $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $@
+$(obj)/vmlinux.bin: $(VMLINUX) FORCE
+ $(call if_changed,bin)
+
+targets += vmlinux.srec
+quiet_cmd_srec = OBJCOPY $@
+ cmd_srec = $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $@
+$(obj)/vmlinux.srec: $(VMLINUX) FORCE
+ $(call if_changed,srec)
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
new file mode 100644
index 00000000..5042d51b
--- /dev/null
+++ b/arch/mips/boot/compressed/Makefile
@@ -0,0 +1,108 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.
+#
+# Adapted for MIPS Pete Popov, Dan Malek
+#
+# Copyright (C) 1994 by Linus Torvalds
+# Adapted for PowerPC by Gary Thomas
+# modified by Cort (cort@cs.nmt.edu)
+#
+# Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University
+# Author: Wu Zhangjin <wuzhangjin@gmail.com>
+#
+
+# set the default size of the mallocing area for decompressing
+BOOT_HEAP_SIZE := 0x400000
+
+# Disable Function Tracer
+KBUILD_CFLAGS := $(shell echo $(KBUILD_CFLAGS) | sed -e "s/-pg//")
+
+KBUILD_CFLAGS := $(LINUXINCLUDE) $(KBUILD_CFLAGS) -D__KERNEL__ \
+ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull"
+
+KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
+ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
+ -DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ )
+
+targets := head.o decompress.o dbg.o uart-16550.o uart-alchemy.o
+
+# decompressor objects (linked with vmlinuz)
+vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
+
+ifdef CONFIG_DEBUG_ZBOOT
+vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o
+endif
+
+targets += vmlinux.bin
+OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
+$(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE
+ $(call if_changed,objcopy)
+
+tool_$(CONFIG_KERNEL_GZIP) = gzip
+tool_$(CONFIG_KERNEL_BZIP2) = bzip2
+tool_$(CONFIG_KERNEL_LZMA) = lzma
+tool_$(CONFIG_KERNEL_LZO) = lzo
+
+targets += vmlinux.bin.z
+$(obj)/vmlinux.bin.z: $(obj)/vmlinux.bin FORCE
+ $(call if_changed,$(tool_y))
+
+targets += piggy.o
+OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.bin.z \
+ --set-section-flags=.image=contents,alloc,load,readonly,data
+$(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
+ $(call if_changed,objcopy)
+
+# Calculate the load address of the compressed kernel image
+hostprogs-y := calc_vmlinuz_load_addr
+
+VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
+ $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
+
+vmlinuzobjs-y += $(obj)/piggy.o
+
+quiet_cmd_zld = LD $@
+ cmd_zld = $(LD) $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T $< $(vmlinuzobjs-y) -o $@
+quiet_cmd_strip = STRIP $@
+ cmd_strip = $(STRIP) -s $@
+vmlinuz: $(src)/ld.script $(vmlinuzobjs-y) $(obj)/calc_vmlinuz_load_addr
+ $(call cmd,zld)
+ $(call cmd,strip)
+
+#
+# Some DECstations need all possible sections of an ECOFF executable
+#
+ifdef CONFIG_MACH_DECSTATION
+ e2eflag := -a
+endif
+
+# elf2ecoff can only handle 32bit image
+hostprogs-y += ../elf2ecoff
+
+ifdef CONFIG_32BIT
+ VMLINUZ = vmlinuz
+else
+ VMLINUZ = vmlinuz.32
+endif
+
+quiet_cmd_32 = OBJCOPY $@
+ cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+vmlinuz.32: vmlinuz
+ $(call cmd,32)
+
+quiet_cmd_ecoff = ECOFF $@
+ cmd_ecoff = $< $(VMLINUZ) $@ $(e2eflag)
+vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ)
+ $(call cmd,ecoff)
+
+OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary
+vmlinuz.bin: vmlinuz
+ $(call cmd,objcopy)
+
+OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec
+vmlinuz.srec: vmlinuz
+ $(call cmd,objcopy)
+
+clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec}
diff --git a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
new file mode 100644
index 00000000..9a624367
--- /dev/null
+++ b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 "Wu Zhangjin" <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+ unsigned long long vmlinux_size, vmlinux_load_addr, vmlinuz_load_addr;
+ struct stat sb;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <pathname> <vmlinux_load_addr>\n",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (stat(argv[1], &sb) == -1) {
+ perror("stat");
+ return EXIT_FAILURE;
+ }
+
+ /* Convert hex characters to dec number */
+ errno = 0;
+ if (sscanf(argv[2], "%llx", &vmlinux_load_addr) != 1) {
+ if (errno != 0)
+ perror("sscanf");
+ else
+ fprintf(stderr, "No matching characters\n");
+
+ return EXIT_FAILURE;
+ }
+
+ vmlinux_size = (uint64_t)sb.st_size;
+ vmlinuz_load_addr = vmlinux_load_addr + vmlinux_size;
+
+ /*
+ * Align with 16 bytes: "greater than that used for any standard data
+ * types by a MIPS compiler." -- See MIPS Run Linux (Second Edition).
+ */
+
+ vmlinuz_load_addr += (16 - vmlinux_size % 16);
+
+ printf("0x%llx\n", vmlinuz_load_addr);
+
+ return EXIT_SUCCESS;
+}
diff --git a/arch/mips/boot/compressed/dbg.c b/arch/mips/boot/compressed/dbg.c
new file mode 100644
index 00000000..134a6162
--- /dev/null
+++ b/arch/mips/boot/compressed/dbg.c
@@ -0,0 +1,37 @@
+/*
+ * MIPS-specific debug support for pre-boot environment
+ *
+ * NOTE: putc() is board specific, if your board have a 16550 compatible uart,
+ * please select SYS_SUPPORTS_ZBOOT_UART16550 for your machine. othewise, you
+ * need to implement your own putc().
+ */
+#include <linux/compiler.h>
+#include <linux/init.h>
+#include <linux/types.h>
+
+void __weak putc(char c)
+{
+}
+
+void puts(const char *s)
+{
+ char c;
+ while ((c = *s++) != '\0') {
+ putc(c);
+ if (c == '\n')
+ putc('\r');
+ }
+}
+
+void puthex(unsigned long long val)
+{
+
+ unsigned char buf[10];
+ int i;
+ for (i = 7; i >= 0; i--) {
+ buf[i] = "0123456789ABCDEF"[val & 0x0F];
+ val >>= 4;
+ }
+ buf[8] = '\0';
+ puts(buf);
+}
diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c
new file mode 100644
index 00000000..5cad0fae
--- /dev/null
+++ b/arch/mips/boot/compressed/decompress.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <asm/addrspace.h>
+
+/*
+ * These two variables specify the free mem region
+ * that can be used for temporary malloc area
+ */
+unsigned long free_mem_ptr;
+unsigned long free_mem_end_ptr;
+
+/* The linker tells us where the image is. */
+extern unsigned char __image_begin, __image_end;
+
+/* debug interfaces */
+extern void puts(const char *s);
+extern void puthex(unsigned long long val);
+
+void error(char *x)
+{
+ puts("\n\n");
+ puts(x);
+ puts("\n\n -- System halted");
+
+ while (1)
+ ; /* Halt */
+}
+
+/* activate the code for pre-boot environment */
+#define STATIC static
+
+#ifdef CONFIG_KERNEL_GZIP
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ int i;
+ const char *s = src;
+ char *d = dest;
+
+ for (i = 0; i < n; i++)
+ d[i] = s[i];
+ return dest;
+}
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+void *memset(void *s, int c, size_t n)
+{
+ int i;
+ char *ss = s;
+
+ for (i = 0; i < n; i++)
+ ss[i] = c;
+ return s;
+}
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
+void decompress_kernel(unsigned long boot_heap_start)
+{
+ unsigned long zimage_start, zimage_size;
+
+ zimage_start = (unsigned long)(&__image_begin);
+ zimage_size = (unsigned long)(&__image_end) -
+ (unsigned long)(&__image_begin);
+
+ puts("zimage at: ");
+ puthex(zimage_start);
+ puts(" ");
+ puthex(zimage_size + zimage_start);
+ puts("\n");
+
+ /* This area are prepared for mallocing when decompressing */
+ free_mem_ptr = boot_heap_start;
+ free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE;
+
+ /* Display standard Linux/MIPS boot prompt */
+ puts("Uncompressing Linux at load address ");
+ puthex(VMLINUX_LOAD_ADDRESS_ULL);
+ puts("\n");
+
+ /* Decompress the kernel with according algorithm */
+ decompress((char *)zimage_start, zimage_size, 0, 0,
+ (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error);
+
+ /* FIXME: should we flush cache here? */
+ puts("Now, booting the kernel...\n");
+}
diff --git a/arch/mips/boot/compressed/dummy.c b/arch/mips/boot/compressed/dummy.c
new file mode 100644
index 00000000..31dbf45b
--- /dev/null
+++ b/arch/mips/boot/compressed/dummy.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/arch/mips/boot/compressed/head.S b/arch/mips/boot/compressed/head.S
new file mode 100644
index 00000000..4e65a842
--- /dev/null
+++ b/arch/mips/boot/compressed/head.S
@@ -0,0 +1,56 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1995 - 1999 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
+ * Further modifications by David S. Miller and Harald Koerfgen
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+ .set noreorder
+ .cprestore
+ LEAF(start)
+start:
+ /* Save boot rom start args */
+ move s0, a0
+ move s1, a1
+ move s2, a2
+ move s3, a3
+
+ /* Clear BSS */
+ PTR_LA a0, _edata
+ PTR_LA a2, _end
+1: sw zero, 0(a0)
+ bne a2, a0, 1b
+ addiu a0, a0, 4
+
+ PTR_LA a0, (.heap) /* heap address */
+ PTR_LA sp, (.stack + 8192) /* stack address */
+
+ PTR_LA ra, 2f
+ PTR_LA k0, decompress_kernel
+ jr k0
+ nop
+2:
+ move a0, s0
+ move a1, s1
+ move a2, s2
+ move a3, s3
+ PTR_LI k0, KERNEL_ENTRY
+ jr k0
+ nop
+3:
+ b 3b
+ nop
+ END(start)
+
+ .comm .heap,BOOT_HEAP_SIZE,4
+ .comm .stack,4096*2,4
diff --git a/arch/mips/boot/compressed/ld.script b/arch/mips/boot/compressed/ld.script
new file mode 100644
index 00000000..8e6b07ca
--- /dev/null
+++ b/arch/mips/boot/compressed/ld.script
@@ -0,0 +1,50 @@
+/*
+ * ld.script for compressed kernel support of MIPS
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin <wuzhanjing@gmail.com>
+ * Copyright (C) 2010 "Wu Zhangjin" <wuzhanjing@gmail.com>
+ */
+
+OUTPUT_ARCH(mips)
+ENTRY(start)
+SECTIONS
+{
+ /* Text and read-only data */
+ /* . = VMLINUZ_LOAD_ADDRESS; */
+ .text : {
+ *(.text)
+ *(.rodata)
+ }
+ /* End of text section */
+
+ /* Writable data */
+ .data : {
+ *(.data)
+ /* Put the compressed image here */
+ __image_begin = .;
+ *(.image)
+ __image_end = .;
+ CONSTRUCTORS
+ }
+ . = ALIGN(16);
+ _edata = .;
+ /* End of data section */
+
+ /* BSS */
+ .bss : {
+ *(.bss)
+ }
+ . = ALIGN(16);
+ _end = .;
+
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.MIPS.options)
+ *(.options)
+ *(.pdr)
+ *(.reginfo)
+ *(.comment)
+ *(.note)
+ }
+}
diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c
new file mode 100644
index 00000000..c9caaf4f
--- /dev/null
+++ b/arch/mips/boot/compressed/uart-16550.c
@@ -0,0 +1,43 @@
+/*
+ * 16550 compatible uart based serial debug support for zboot
+ */
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+
+#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA)
+#define UART_BASE 0x1fd003f8
+#define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset))
+#endif
+
+#ifdef CONFIG_AR7
+#include <ar7.h>
+#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset))
+#endif
+
+#ifndef PORT
+#error please define the serial port address for your own machine
+#endif
+
+static inline unsigned int serial_in(int offset)
+{
+ return *((char *)PORT(offset));
+}
+
+static inline void serial_out(int offset, int value)
+{
+ *((char *)PORT(offset)) = value;
+}
+
+void putc(char c)
+{
+ int timeout = 1024;
+
+ while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0))
+ ;
+
+ serial_out(UART_TX, c);
+}
diff --git a/arch/mips/boot/compressed/uart-alchemy.c b/arch/mips/boot/compressed/uart-alchemy.c
new file mode 100644
index 00000000..eb063e6d
--- /dev/null
+++ b/arch/mips/boot/compressed/uart-alchemy.c
@@ -0,0 +1,7 @@
+#include <asm/mach-au1x00/au1000.h>
+
+void putc(char c)
+{
+ /* all current (Jan. 2010) in-kernel boards */
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
diff --git a/arch/mips/boot/ecoff.h b/arch/mips/boot/ecoff.h
new file mode 100644
index 00000000..8c3eed28
--- /dev/null
+++ b/arch/mips/boot/ecoff.h
@@ -0,0 +1,62 @@
+/*
+ * Some ECOFF definitions.
+ */
+typedef struct filehdr {
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ long f_timdat; /* time & date stamp */
+ long f_symptr; /* file pointer to symbolic header */
+ long f_nsyms; /* sizeof(symbolic hdr) */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+} FILHDR;
+#define FILHSZ sizeof(FILHDR)
+
+#define OMAGIC 0407
+#define MIPSEBMAGIC 0x160
+#define MIPSELMAGIC 0x162
+
+typedef struct scnhdr {
+ char s_name[8]; /* section name */
+ long s_paddr; /* physical address, aliased s_nlib */
+ long s_vaddr; /* virtual address */
+ long s_size; /* section size */
+ long s_scnptr; /* file ptr to raw data for section */
+ long s_relptr; /* file ptr to relocation */
+ long s_lnnoptr; /* file ptr to gp histogram */
+ unsigned short s_nreloc; /* number of relocation entries */
+ unsigned short s_nlnno; /* number of gp histogram entries */
+ long s_flags; /* flags */
+} SCNHDR;
+#define SCNHSZ sizeof(SCNHDR)
+#define SCNROUND ((long)16)
+
+typedef struct aouthdr {
+ short magic; /* see above */
+ short vstamp; /* version stamp */
+ long tsize; /* text size in bytes, padded to DW bdry*/
+ long dsize; /* initialized data " " */
+ long bsize; /* uninitialized data " " */
+ long entry; /* entry pt. */
+ long text_start; /* base of text used for this file */
+ long data_start; /* base of data used for this file */
+ long bss_start; /* base of bss used for this file */
+ long gprmask; /* general purpose register mask */
+ long cprmask[4]; /* co-processor register masks */
+ long gp_value; /* the gp value used for this object */
+} AOUTHDR;
+#define AOUTHSZ sizeof(AOUTHDR)
+
+#define OMAGIC 0407
+#define NMAGIC 0410
+#define ZMAGIC 0413
+#define SMAGIC 0411
+#define LIBMAGIC 0443
+
+#define N_TXTOFF(f, a) \
+ ((a).magic == ZMAGIC || (a).magic == LIBMAGIC ? 0 : \
+ ((a).vstamp < 23 ? \
+ ((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + 7) & 0xfffffff8) : \
+ ((FILHSZ + AOUTHSZ + (f).f_nscns * SCNHSZ + SCNROUND-1) & ~(SCNROUND-1)) ) )
+#define N_DATOFF(f, a) \
+ N_TXTOFF(f, a) + (a).tsize;
diff --git a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c
new file mode 100644
index 00000000..e19d9062
--- /dev/null
+++ b/arch/mips/boot/elf2ecoff.c
@@ -0,0 +1,616 @@
+/*
+ * Copyright (c) 1995
+ * Ted Lemon (hereinafter referred to as the author)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* elf2ecoff.c
+
+ This program converts an elf executable to an ECOFF executable.
+ No symbol table is retained. This is useful primarily in building
+ net-bootable kernels for machines (e.g., DECstation and Alpha) which
+ only support the ECOFF object file format. */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <elf.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+
+#include "ecoff.h"
+
+/*
+ * Some extra ELF definitions
+ */
+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
+
+/* -------------------------------------------------------------------- */
+
+struct sect {
+ unsigned long vaddr;
+ unsigned long len;
+};
+
+int *symTypeTable;
+int must_convert_endian;
+int format_bigendian;
+
+static void copy(int out, int in, off_t offset, off_t size)
+{
+ char ibuf[4096];
+ int remaining, cur, count;
+
+ /* Go to the start of the ELF symbol table... */
+ if (lseek(in, offset, SEEK_SET) < 0) {
+ perror("copy: lseek");
+ exit(1);
+ }
+
+ remaining = size;
+ while (remaining) {
+ cur = remaining;
+ if (cur > sizeof ibuf)
+ cur = sizeof ibuf;
+ remaining -= cur;
+ if ((count = read(in, ibuf, cur)) != cur) {
+ fprintf(stderr, "copy: read: %s\n",
+ count ? strerror(errno) :
+ "premature end of file");
+ exit(1);
+ }
+ if ((count = write(out, ibuf, cur)) != cur) {
+ perror("copy: write");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Combine two segments, which must be contiguous. If pad is true, it's
+ * okay for there to be padding between.
+ */
+static void combine(struct sect *base, struct sect *new, int pad)
+{
+ if (!base->len)
+ *base = *new;
+ else if (new->len) {
+ if (base->vaddr + base->len != new->vaddr) {
+ if (pad)
+ base->len = new->vaddr - base->vaddr;
+ else {
+ fprintf(stderr,
+ "Non-contiguous data can't be converted.\n");
+ exit(1);
+ }
+ }
+ base->len += new->len;
+ }
+}
+
+static int phcmp(const void *v1, const void *v2)
+{
+ const Elf32_Phdr *h1 = v1;
+ const Elf32_Phdr *h2 = v2;
+
+ if (h1->p_vaddr > h2->p_vaddr)
+ return 1;
+ else if (h1->p_vaddr < h2->p_vaddr)
+ return -1;
+ else
+ return 0;
+}
+
+static char *saveRead(int file, off_t offset, off_t len, char *name)
+{
+ char *tmp;
+ int count;
+ off_t off;
+ if ((off = lseek(file, offset, SEEK_SET)) < 0) {
+ fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
+ exit(1);
+ }
+ if (!(tmp = (char *) malloc(len))) {
+ fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name,
+ len);
+ exit(1);
+ }
+ count = read(file, tmp, len);
+ if (count != len) {
+ fprintf(stderr, "%s: read: %s.\n",
+ name,
+ count ? strerror(errno) : "End of file reached");
+ exit(1);
+ }
+ return tmp;
+}
+
+#define swab16(x) \
+ ((unsigned short)( \
+ (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
+ (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
+
+#define swab32(x) \
+ ((unsigned int)( \
+ (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
+ (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
+ (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
+ (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
+
+static void convert_elf_hdr(Elf32_Ehdr * e)
+{
+ e->e_type = swab16(e->e_type);
+ e->e_machine = swab16(e->e_machine);
+ e->e_version = swab32(e->e_version);
+ e->e_entry = swab32(e->e_entry);
+ e->e_phoff = swab32(e->e_phoff);
+ e->e_shoff = swab32(e->e_shoff);
+ e->e_flags = swab32(e->e_flags);
+ e->e_ehsize = swab16(e->e_ehsize);
+ e->e_phentsize = swab16(e->e_phentsize);
+ e->e_phnum = swab16(e->e_phnum);
+ e->e_shentsize = swab16(e->e_shentsize);
+ e->e_shnum = swab16(e->e_shnum);
+ e->e_shstrndx = swab16(e->e_shstrndx);
+}
+
+static void convert_elf_phdrs(Elf32_Phdr * p, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++, p++) {
+ p->p_type = swab32(p->p_type);
+ p->p_offset = swab32(p->p_offset);
+ p->p_vaddr = swab32(p->p_vaddr);
+ p->p_paddr = swab32(p->p_paddr);
+ p->p_filesz = swab32(p->p_filesz);
+ p->p_memsz = swab32(p->p_memsz);
+ p->p_flags = swab32(p->p_flags);
+ p->p_align = swab32(p->p_align);
+ }
+
+}
+
+static void convert_elf_shdrs(Elf32_Shdr * s, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++, s++) {
+ s->sh_name = swab32(s->sh_name);
+ s->sh_type = swab32(s->sh_type);
+ s->sh_flags = swab32(s->sh_flags);
+ s->sh_addr = swab32(s->sh_addr);
+ s->sh_offset = swab32(s->sh_offset);
+ s->sh_size = swab32(s->sh_size);
+ s->sh_link = swab32(s->sh_link);
+ s->sh_info = swab32(s->sh_info);
+ s->sh_addralign = swab32(s->sh_addralign);
+ s->sh_entsize = swab32(s->sh_entsize);
+ }
+}
+
+static void convert_ecoff_filehdr(struct filehdr *f)
+{
+ f->f_magic = swab16(f->f_magic);
+ f->f_nscns = swab16(f->f_nscns);
+ f->f_timdat = swab32(f->f_timdat);
+ f->f_symptr = swab32(f->f_symptr);
+ f->f_nsyms = swab32(f->f_nsyms);
+ f->f_opthdr = swab16(f->f_opthdr);
+ f->f_flags = swab16(f->f_flags);
+}
+
+static void convert_ecoff_aouthdr(struct aouthdr *a)
+{
+ a->magic = swab16(a->magic);
+ a->vstamp = swab16(a->vstamp);
+ a->tsize = swab32(a->tsize);
+ a->dsize = swab32(a->dsize);
+ a->bsize = swab32(a->bsize);
+ a->entry = swab32(a->entry);
+ a->text_start = swab32(a->text_start);
+ a->data_start = swab32(a->data_start);
+ a->bss_start = swab32(a->bss_start);
+ a->gprmask = swab32(a->gprmask);
+ a->cprmask[0] = swab32(a->cprmask[0]);
+ a->cprmask[1] = swab32(a->cprmask[1]);
+ a->cprmask[2] = swab32(a->cprmask[2]);
+ a->cprmask[3] = swab32(a->cprmask[3]);
+ a->gp_value = swab32(a->gp_value);
+}
+
+static void convert_ecoff_esecs(struct scnhdr *s, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++, s++) {
+ s->s_paddr = swab32(s->s_paddr);
+ s->s_vaddr = swab32(s->s_vaddr);
+ s->s_size = swab32(s->s_size);
+ s->s_scnptr = swab32(s->s_scnptr);
+ s->s_relptr = swab32(s->s_relptr);
+ s->s_lnnoptr = swab32(s->s_lnnoptr);
+ s->s_nreloc = swab16(s->s_nreloc);
+ s->s_nlnno = swab16(s->s_nlnno);
+ s->s_flags = swab32(s->s_flags);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ Elf32_Ehdr ex;
+ Elf32_Phdr *ph;
+ Elf32_Shdr *sh;
+ char *shstrtab;
+ int i, pad;
+ struct sect text, data, bss;
+ struct filehdr efh;
+ struct aouthdr eah;
+ struct scnhdr esecs[6];
+ int infile, outfile;
+ unsigned long cur_vma = ULONG_MAX;
+ int addflag = 0;
+ int nosecs;
+
+ text.len = data.len = bss.len = 0;
+ text.vaddr = data.vaddr = bss.vaddr = 0;
+
+ /* Check args... */
+ if (argc < 3 || argc > 4) {
+ usage:
+ fprintf(stderr,
+ "usage: elf2ecoff <elf executable> <ecoff executable> [-a]\n");
+ exit(1);
+ }
+ if (argc == 4) {
+ if (strcmp(argv[3], "-a"))
+ goto usage;
+ addflag = 1;
+ }
+
+ /* Try the input file... */
+ if ((infile = open(argv[1], O_RDONLY)) < 0) {
+ fprintf(stderr, "Can't open %s for read: %s\n",
+ argv[1], strerror(errno));
+ exit(1);
+ }
+
+ /* Read the header, which is at the beginning of the file... */
+ i = read(infile, &ex, sizeof ex);
+ if (i != sizeof ex) {
+ fprintf(stderr, "ex: %s: %s.\n",
+ argv[1],
+ i ? strerror(errno) : "End of file reached");
+ exit(1);
+ }
+
+ if (ex.e_ident[EI_DATA] == ELFDATA2MSB)
+ format_bigendian = 1;
+
+ if (ntohs(0xaa55) == 0xaa55) {
+ if (!format_bigendian)
+ must_convert_endian = 1;
+ } else {
+ if (format_bigendian)
+ must_convert_endian = 1;
+ }
+ if (must_convert_endian)
+ convert_elf_hdr(&ex);
+
+ /* Read the program headers... */
+ ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
+ ex.e_phnum * sizeof(Elf32_Phdr),
+ "ph");
+ if (must_convert_endian)
+ convert_elf_phdrs(ph, ex.e_phnum);
+ /* Read the section headers... */
+ sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
+ ex.e_shnum * sizeof(Elf32_Shdr),
+ "sh");
+ if (must_convert_endian)
+ convert_elf_shdrs(sh, ex.e_shnum);
+ /* Read in the section string table. */
+ shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
+ sh[ex.e_shstrndx].sh_size, "shstrtab");
+
+ /* Figure out if we can cram the program header into an ECOFF
+ header... Basically, we can't handle anything but loadable
+ segments, but we can ignore some kinds of segments. We can't
+ handle holes in the address space. Segments may be out of order,
+ so we sort them first. */
+
+ qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp);
+
+ for (i = 0; i < ex.e_phnum; i++) {
+ /* Section types we can ignore... */
+ if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE ||
+ ph[i].p_type == PT_PHDR
+ || ph[i].p_type == PT_MIPS_REGINFO)
+ continue;
+ /* Section types we can't handle... */
+ else if (ph[i].p_type != PT_LOAD) {
+ fprintf(stderr,
+ "Program header %d type %d can't be converted.\n",
+ ex.e_phnum, ph[i].p_type);
+ exit(1);
+ }
+ /* Writable (data) segment? */
+ if (ph[i].p_flags & PF_W) {
+ struct sect ndata, nbss;
+
+ ndata.vaddr = ph[i].p_vaddr;
+ ndata.len = ph[i].p_filesz;
+ nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
+ nbss.len = ph[i].p_memsz - ph[i].p_filesz;
+
+ combine(&data, &ndata, 0);
+ combine(&bss, &nbss, 1);
+ } else {
+ struct sect ntxt;
+
+ ntxt.vaddr = ph[i].p_vaddr;
+ ntxt.len = ph[i].p_filesz;
+
+ combine(&text, &ntxt, 0);
+ }
+ /* Remember the lowest segment start address. */
+ if (ph[i].p_vaddr < cur_vma)
+ cur_vma = ph[i].p_vaddr;
+ }
+
+ /* Sections must be in order to be converted... */
+ if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
+ text.vaddr + text.len > data.vaddr
+ || data.vaddr + data.len > bss.vaddr) {
+ fprintf(stderr,
+ "Sections ordering prevents a.out conversion.\n");
+ exit(1);
+ }
+
+ /* If there's a data section but no text section, then the loader
+ combined everything into one section. That needs to be the
+ text section, so just make the data section zero length following
+ text. */
+ if (data.len && !text.len) {
+ text = data;
+ data.vaddr = text.vaddr + text.len;
+ data.len = 0;
+ }
+
+ /* If there is a gap between text and data, we'll fill it when we copy
+ the data, so update the length of the text segment as represented in
+ a.out to reflect that, since a.out doesn't allow gaps in the program
+ address space. */
+ if (text.vaddr + text.len < data.vaddr)
+ text.len = data.vaddr - text.vaddr;
+
+ /* We now have enough information to cons up an a.out header... */
+ eah.magic = OMAGIC;
+ eah.vstamp = 200;
+ eah.tsize = text.len;
+ eah.dsize = data.len;
+ eah.bsize = bss.len;
+ eah.entry = ex.e_entry;
+ eah.text_start = text.vaddr;
+ eah.data_start = data.vaddr;
+ eah.bss_start = bss.vaddr;
+ eah.gprmask = 0xf3fffffe;
+ memset(&eah.cprmask, '\0', sizeof eah.cprmask);
+ eah.gp_value = 0; /* unused. */
+
+ if (format_bigendian)
+ efh.f_magic = MIPSEBMAGIC;
+ else
+ efh.f_magic = MIPSELMAGIC;
+ if (addflag)
+ nosecs = 6;
+ else
+ nosecs = 3;
+ efh.f_nscns = nosecs;
+ efh.f_timdat = 0; /* bogus */
+ efh.f_symptr = 0;
+ efh.f_nsyms = 0;
+ efh.f_opthdr = sizeof eah;
+ efh.f_flags = 0x100f; /* Stripped, not sharable. */
+
+ memset(esecs, 0, sizeof esecs);
+ strcpy(esecs[0].s_name, ".text");
+ strcpy(esecs[1].s_name, ".data");
+ strcpy(esecs[2].s_name, ".bss");
+ if (addflag) {
+ strcpy(esecs[3].s_name, ".rdata");
+ strcpy(esecs[4].s_name, ".sdata");
+ strcpy(esecs[5].s_name, ".sbss");
+ }
+ esecs[0].s_paddr = esecs[0].s_vaddr = eah.text_start;
+ esecs[1].s_paddr = esecs[1].s_vaddr = eah.data_start;
+ esecs[2].s_paddr = esecs[2].s_vaddr = eah.bss_start;
+ if (addflag) {
+ esecs[3].s_paddr = esecs[3].s_vaddr = 0;
+ esecs[4].s_paddr = esecs[4].s_vaddr = 0;
+ esecs[5].s_paddr = esecs[5].s_vaddr = 0;
+ }
+ esecs[0].s_size = eah.tsize;
+ esecs[1].s_size = eah.dsize;
+ esecs[2].s_size = eah.bsize;
+ if (addflag) {
+ esecs[3].s_size = 0;
+ esecs[4].s_size = 0;
+ esecs[5].s_size = 0;
+ }
+ esecs[0].s_scnptr = N_TXTOFF(efh, eah);
+ esecs[1].s_scnptr = N_DATOFF(efh, eah);
+#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10
+#define ECOFF_ROUND(s, a) (((s)+(a)-1)&~((a)-1))
+ esecs[2].s_scnptr = esecs[1].s_scnptr +
+ ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eah));
+ if (addflag) {
+ esecs[3].s_scnptr = 0;
+ esecs[4].s_scnptr = 0;
+ esecs[5].s_scnptr = 0;
+ }
+ esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0;
+ esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0;
+ esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0;
+ esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0;
+ if (addflag) {
+ esecs[3].s_relptr = esecs[4].s_relptr
+ = esecs[5].s_relptr = 0;
+ esecs[3].s_lnnoptr = esecs[4].s_lnnoptr
+ = esecs[5].s_lnnoptr = 0;
+ esecs[3].s_nreloc = esecs[4].s_nreloc = esecs[5].s_nreloc =
+ 0;
+ esecs[3].s_nlnno = esecs[4].s_nlnno = esecs[5].s_nlnno = 0;
+ }
+ esecs[0].s_flags = 0x20;
+ esecs[1].s_flags = 0x40;
+ esecs[2].s_flags = 0x82;
+ if (addflag) {
+ esecs[3].s_flags = 0x100;
+ esecs[4].s_flags = 0x200;
+ esecs[5].s_flags = 0x400;
+ }
+
+ /* Make the output file... */
+ if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
+ fprintf(stderr, "Unable to create %s: %s\n", argv[2],
+ strerror(errno));
+ exit(1);
+ }
+
+ if (must_convert_endian)
+ convert_ecoff_filehdr(&efh);
+ /* Write the headers... */
+ i = write(outfile, &efh, sizeof efh);
+ if (i != sizeof efh) {
+ perror("efh: write");
+ exit(1);
+
+ for (i = 0; i < nosecs; i++) {
+ printf
+ ("Section %d: %s phys %lx size %lx file offset %lx\n",
+ i, esecs[i].s_name, esecs[i].s_paddr,
+ esecs[i].s_size, esecs[i].s_scnptr);
+ }
+ }
+ fprintf(stderr, "wrote %d byte file header.\n", i);
+
+ if (must_convert_endian)
+ convert_ecoff_aouthdr(&eah);
+ i = write(outfile, &eah, sizeof eah);
+ if (i != sizeof eah) {
+ perror("eah: write");
+ exit(1);
+ }
+ fprintf(stderr, "wrote %d byte a.out header.\n", i);
+
+ if (must_convert_endian)
+ convert_ecoff_esecs(&esecs[0], nosecs);
+ i = write(outfile, &esecs, nosecs * sizeof(struct scnhdr));
+ if (i != nosecs * sizeof(struct scnhdr)) {
+ perror("esecs: write");
+ exit(1);
+ }
+ fprintf(stderr, "wrote %d bytes of section headers.\n", i);
+
+ pad = (sizeof(efh) + sizeof(eah) + nosecs * sizeof(struct scnhdr)) & 15;
+ if (pad) {
+ pad = 16 - pad;
+ i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad);
+ if (i < 0) {
+ perror("ipad: write");
+ exit(1);
+ }
+ fprintf(stderr, "wrote %d byte pad.\n", i);
+ }
+
+ /*
+ * Copy the loadable sections. Zero-fill any gaps less than 64k;
+ * complain about any zero-filling, and die if we're asked to zero-fill
+ * more than 64k.
+ */
+ for (i = 0; i < ex.e_phnum; i++) {
+ /* Unprocessable sections were handled above, so just verify that
+ the section can be loaded before copying. */
+ if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) {
+ if (cur_vma != ph[i].p_vaddr) {
+ unsigned long gap =
+ ph[i].p_vaddr - cur_vma;
+ char obuf[1024];
+ if (gap > 65536) {
+ fprintf(stderr,
+ "Intersegment gap (%ld bytes) too large.\n",
+ gap);
+ exit(1);
+ }
+ fprintf(stderr,
+ "Warning: %ld byte intersegment gap.\n",
+ gap);
+ memset(obuf, 0, sizeof obuf);
+ while (gap) {
+ int count =
+ write(outfile, obuf,
+ (gap >
+ sizeof obuf ? sizeof
+ obuf : gap));
+ if (count < 0) {
+ fprintf(stderr,
+ "Error writing gap: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ gap -= count;
+ }
+ }
+ fprintf(stderr, "writing %d bytes...\n",
+ ph[i].p_filesz);
+ copy(outfile, infile, ph[i].p_offset,
+ ph[i].p_filesz);
+ cur_vma = ph[i].p_vaddr + ph[i].p_filesz;
+ }
+ }
+
+ /*
+ * Write a page of padding for boot PROMS that read entire pages.
+ * Without this, they may attempt to read past the end of the
+ * data section, incur an error, and refuse to boot.
+ */
+ {
+ char obuf[4096];
+ memset(obuf, 0, sizeof obuf);
+ if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) {
+ fprintf(stderr, "Error writing PROM padding: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+ }
+
+ /* Looks like we won... */
+ exit(0);
+}
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
new file mode 100644
index 00000000..cad555eb
--- /dev/null
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -0,0 +1,105 @@
+if CPU_CAVIUM_OCTEON
+
+config CAVIUM_CN63XXP1
+ bool "Enable CN63XXP1 errata worarounds"
+ default "n"
+ help
+ The CN63XXP1 chip requires build time workarounds to
+ function reliably, select this option to enable them. These
+ workarounds will cause a slight decrease in performance on
+ non-CN63XXP1 hardware, so it is recommended to select "n"
+ unless it is known the workarounds are needed.
+
+config CAVIUM_OCTEON_2ND_KERNEL
+ bool "Build the kernel to be used as a 2nd kernel on the same chip"
+ default "n"
+ help
+ This option configures this kernel to be linked at a different
+ address and use the 2nd uart for output. This allows a kernel built
+ with this option to be run at the same time as one built without this
+ option.
+
+config CAVIUM_OCTEON_HW_FIX_UNALIGNED
+ bool "Enable hardware fixups of unaligned loads and stores"
+ default "y"
+ help
+ Configure the Octeon hardware to automatically fix unaligned loads
+ and stores. Normally unaligned accesses are fixed using a kernel
+ exception handler. This option enables the hardware automatic fixups,
+ which requires only an extra 3 cycles. Disable this option if you
+ are running code that relies on address exceptions on unaligned
+ accesses.
+
+config CAVIUM_OCTEON_CVMSEG_SIZE
+ int "Number of L1 cache lines reserved for CVMSEG memory"
+ range 0 54
+ default 1
+ help
+ CVMSEG LM is a segment that accesses portions of the dcache as a
+ local memory; the larger CVMSEG is, the smaller the cache is.
+ This selects the size of CVMSEG LM, which is in cache blocks. The
+ legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
+ between zero and 6192 bytes).
+
+config CAVIUM_OCTEON_LOCK_L2
+ bool "Lock often used kernel code in the L2"
+ default "y"
+ help
+ Enable locking parts of the kernel into the L2 cache.
+
+config CAVIUM_OCTEON_LOCK_L2_TLB
+ bool "Lock the TLB handler in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the low level TLB fast path into L2.
+
+config CAVIUM_OCTEON_LOCK_L2_EXCEPTION
+ bool "Lock the exception handler in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the low level exception handler into L2.
+
+config CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT
+ bool "Lock the interrupt handler in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the low level interrupt handler into L2.
+
+config CAVIUM_OCTEON_LOCK_L2_INTERRUPT
+ bool "Lock the 2nd level interrupt handler in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the 2nd level interrupt handler in L2.
+
+config CAVIUM_OCTEON_LOCK_L2_MEMCPY
+ bool "Lock memcpy() in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the kernel's implementation of memcpy() into L2.
+
+config ARCH_SPARSEMEM_ENABLE
+ def_bool y
+ select SPARSEMEM_STATIC
+
+config CAVIUM_OCTEON_HELPER
+ def_bool y
+ depends on OCTEON_ETHERNET || PCI
+
+config IOMMU_HELPER
+ bool
+
+config NEED_SG_DMA_LENGTH
+ bool
+
+config SWIOTLB
+ def_bool y
+ select IOMMU_HELPER
+ select NEED_SG_DMA_LENGTH
+
+
+endif # CPU_CAVIUM_OCTEON
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
new file mode 100644
index 00000000..19eb0434
--- /dev/null
+++ b/arch/mips/cavium-octeon/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for the Cavium Octeon specific kernel interface routines
+# under Linux.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2005-2009 Cavium Networks
+#
+
+obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
+obj-y += dma-octeon.o flash_setup.o
+obj-y += octeon-memcpy.o
+obj-y += executive/
+
+obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/mips/cavium-octeon/Platform b/arch/mips/cavium-octeon/Platform
new file mode 100644
index 00000000..1e43ccf1
--- /dev/null
+++ b/arch/mips/cavium-octeon/Platform
@@ -0,0 +1,11 @@
+#
+# Cavium Octeon
+#
+platform-$(CONFIG_CPU_CAVIUM_OCTEON) += cavium-octeon/
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += \
+ -I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
+ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff84100000
+else
+load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
+endif
diff --git a/arch/mips/cavium-octeon/cpu.c b/arch/mips/cavium-octeon/cpu.c
new file mode 100644
index 00000000..a5b42790
--- /dev/null
+++ b/arch/mips/cavium-octeon/cpu.c
@@ -0,0 +1,48 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Wind River Systems,
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/init.h>
+#include <linux/irqflags.h>
+#include <linux/notifier.h>
+#include <linux/prefetch.h>
+#include <linux/sched.h>
+
+#include <asm/cop2.h>
+#include <asm/current.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/octeon/octeon.h>
+
+static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action,
+ void *data)
+{
+ unsigned long flags;
+ unsigned int status;
+
+ switch (action) {
+ case CU2_EXCEPTION:
+ prefetch(&current->thread.cp2);
+ local_irq_save(flags);
+ KSTK_STATUS(current) |= ST0_CU2;
+ status = read_c0_status();
+ write_c0_status(status | ST0_CU2);
+ octeon_cop2_restore(&(current->thread.cp2));
+ write_c0_status(status & ~ST0_CU2);
+ local_irq_restore(flags);
+
+ return NOTIFY_BAD; /* Don't call default notifier */
+ }
+
+ return NOTIFY_OK; /* Let default notifier send signals */
+}
+
+static int __init cnmips_cu2_setup(void)
+{
+ return cu2_notifier(cnmips_cu2_call, 0);
+}
+early_initcall(cnmips_cu2_setup);
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
new file mode 100644
index 00000000..29d56afb
--- /dev/null
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -0,0 +1,164 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 by Ralf Baechle
+ * Copyright (C) 2009, 2010 Cavium Networks, Inc.
+ */
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/cpu-info.h>
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-ipd-defs.h>
+#include <asm/octeon/cvmx-mio-defs.h>
+
+/*
+ * Set the current core's cvmcount counter to the value of the
+ * IPD_CLK_COUNT. We do this on all cores as they are brought
+ * on-line. This allows for a read from a local cpu register to
+ * access a synchronized counter.
+ *
+ * On CPU_CAVIUM_OCTEON2 the IPD_CLK_COUNT is scaled by rdiv/sdiv.
+ */
+void octeon_init_cvmcount(void)
+{
+ unsigned long flags;
+ unsigned loops = 2;
+ u64 f = 0;
+ u64 rdiv = 0;
+ u64 sdiv = 0;
+ if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
+ union cvmx_mio_rst_boot rst_boot;
+ rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+ rdiv = rst_boot.s.c_mul; /* CPU clock */
+ sdiv = rst_boot.s.pnr_mul; /* I/O clock */
+ f = (0x8000000000000000ull / sdiv) * 2;
+ }
+
+
+ /* Clobber loops so GCC will not unroll the following while loop. */
+ asm("" : "+r" (loops));
+
+ local_irq_save(flags);
+ /*
+ * Loop several times so we are executing from the cache,
+ * which should give more deterministic timing.
+ */
+ while (loops--) {
+ u64 ipd_clk_count = cvmx_read_csr(CVMX_IPD_CLK_COUNT);
+ if (rdiv != 0) {
+ ipd_clk_count *= rdiv;
+ if (f != 0) {
+ asm("dmultu\t%[cnt],%[f]\n\t"
+ "mfhi\t%[cnt]"
+ : [cnt] "+r" (ipd_clk_count),
+ [f] "=r" (f)
+ : : "hi", "lo");
+ }
+ }
+ write_c0_cvmcount(ipd_clk_count);
+ }
+ local_irq_restore(flags);
+}
+
+static cycle_t octeon_cvmcount_read(struct clocksource *cs)
+{
+ return read_c0_cvmcount();
+}
+
+static struct clocksource clocksource_mips = {
+ .name = "OCTEON_CVMCOUNT",
+ .read = octeon_cvmcount_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+unsigned long long notrace sched_clock(void)
+{
+ /* 64-bit arithmatic can overflow, so use 128-bit. */
+ u64 t1, t2, t3;
+ unsigned long long rv;
+ u64 mult = clocksource_mips.mult;
+ u64 shift = clocksource_mips.shift;
+ u64 cnt = read_c0_cvmcount();
+
+ asm (
+ "dmultu\t%[cnt],%[mult]\n\t"
+ "nor\t%[t1],$0,%[shift]\n\t"
+ "mfhi\t%[t2]\n\t"
+ "mflo\t%[t3]\n\t"
+ "dsll\t%[t2],%[t2],1\n\t"
+ "dsrlv\t%[rv],%[t3],%[shift]\n\t"
+ "dsllv\t%[t1],%[t2],%[t1]\n\t"
+ "or\t%[rv],%[t1],%[rv]\n\t"
+ : [rv] "=&r" (rv), [t1] "=&r" (t1), [t2] "=&r" (t2), [t3] "=&r" (t3)
+ : [cnt] "r" (cnt), [mult] "r" (mult), [shift] "r" (shift)
+ : "hi", "lo");
+ return rv;
+}
+
+void __init plat_time_init(void)
+{
+ clocksource_mips.rating = 300;
+ clocksource_register_hz(&clocksource_mips, octeon_get_clock_rate());
+}
+
+static u64 octeon_udelay_factor;
+static u64 octeon_ndelay_factor;
+
+void __init octeon_setup_delays(void)
+{
+ octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
+ /*
+ * For __ndelay we divide by 2^16, so the factor is multiplied
+ * by the same amount.
+ */
+ octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
+
+ preset_lpj = octeon_get_clock_rate() / HZ;
+}
+
+void __udelay(unsigned long us)
+{
+ u64 cur, end, inc;
+
+ cur = read_c0_cvmcount();
+
+ inc = us * octeon_udelay_factor;
+ end = cur + inc;
+
+ while (end > cur)
+ cur = read_c0_cvmcount();
+}
+EXPORT_SYMBOL(__udelay);
+
+void __ndelay(unsigned long ns)
+{
+ u64 cur, end, inc;
+
+ cur = read_c0_cvmcount();
+
+ inc = ((ns * octeon_ndelay_factor) >> 16);
+ end = cur + inc;
+
+ while (end > cur)
+ cur = read_c0_cvmcount();
+}
+EXPORT_SYMBOL(__ndelay);
+
+void __delay(unsigned long loops)
+{
+ u64 cur, end;
+
+ cur = read_c0_cvmcount();
+ end = cur + loops;
+
+ while (end > cur)
+ cur = read_c0_cvmcount();
+}
+EXPORT_SYMBOL(__delay);
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
new file mode 100644
index 00000000..1abb66ca
--- /dev/null
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -0,0 +1,349 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001 Ralf Baechle <ralf@gnu.org>
+ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ * IP32 changes by Ilya.
+ * Copyright (C) 2010 Cavium Networks, Inc.
+ */
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/bootmem.h>
+#include <linux/swiotlb.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+
+#include <asm/octeon/octeon.h>
+
+#ifdef CONFIG_PCI
+#include <asm/octeon/pci-octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
+
+static dma_addr_t octeon_hole_phys_to_dma(phys_addr_t paddr)
+{
+ if (paddr >= CVMX_PCIE_BAR1_PHYS_BASE && paddr < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE))
+ return paddr - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE;
+ else
+ return paddr;
+}
+
+static phys_addr_t octeon_hole_dma_to_phys(dma_addr_t daddr)
+{
+ if (daddr >= CVMX_PCIE_BAR1_RC_BASE)
+ return daddr + CVMX_PCIE_BAR1_PHYS_BASE - CVMX_PCIE_BAR1_RC_BASE;
+ else
+ return daddr;
+}
+
+static dma_addr_t octeon_gen1_phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+ paddr -= 0x400000000ull;
+ return octeon_hole_phys_to_dma(paddr);
+}
+
+static phys_addr_t octeon_gen1_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ daddr = octeon_hole_dma_to_phys(daddr);
+
+ if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+ daddr += 0x400000000ull;
+
+ return daddr;
+}
+
+static dma_addr_t octeon_big_phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+ paddr -= 0x400000000ull;
+
+ /* Anything in the BAR1 hole or above goes via BAR2 */
+ if (paddr >= 0xf0000000ull)
+ paddr = OCTEON_BAR2_PCI_ADDRESS + paddr;
+
+ return paddr;
+}
+
+static phys_addr_t octeon_big_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ if (daddr >= OCTEON_BAR2_PCI_ADDRESS)
+ daddr -= OCTEON_BAR2_PCI_ADDRESS;
+
+ if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+ daddr += 0x400000000ull;
+ return daddr;
+}
+
+static dma_addr_t octeon_small_phys_to_dma(struct device *dev,
+ phys_addr_t paddr)
+{
+ if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
+ paddr -= 0x400000000ull;
+
+ /* Anything not in the BAR1 range goes via BAR2 */
+ if (paddr >= octeon_bar1_pci_phys && paddr < octeon_bar1_pci_phys + 0x8000000ull)
+ paddr = paddr - octeon_bar1_pci_phys;
+ else
+ paddr = OCTEON_BAR2_PCI_ADDRESS + paddr;
+
+ return paddr;
+}
+
+static phys_addr_t octeon_small_dma_to_phys(struct device *dev,
+ dma_addr_t daddr)
+{
+ if (daddr >= OCTEON_BAR2_PCI_ADDRESS)
+ daddr -= OCTEON_BAR2_PCI_ADDRESS;
+ else
+ daddr += octeon_bar1_pci_phys;
+
+ if (daddr >= 0x10000000ull && daddr < 0x20000000ull)
+ daddr += 0x400000000ull;
+ return daddr;
+}
+
+#endif /* CONFIG_PCI */
+
+static dma_addr_t octeon_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size,
+ direction, attrs);
+ mb();
+
+ return daddr;
+}
+
+static int octeon_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+ int r = swiotlb_map_sg_attrs(dev, sg, nents, direction, attrs);
+ mb();
+ return r;
+}
+
+static void octeon_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+{
+ swiotlb_sync_single_for_device(dev, dma_handle, size, direction);
+ mb();
+}
+
+static void octeon_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nelems, enum dma_data_direction direction)
+{
+ swiotlb_sync_sg_for_device(dev, sg, nelems, direction);
+ mb();
+}
+
+static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ void *ret;
+
+ if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
+ return ret;
+
+ /* ignore region specifiers */
+ gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+
+#ifdef CONFIG_ZONE_DMA
+ if (dev == NULL)
+ gfp |= __GFP_DMA;
+ else if (dev->coherent_dma_mask <= DMA_BIT_MASK(24))
+ gfp |= __GFP_DMA;
+ else
+#endif
+#ifdef CONFIG_ZONE_DMA32
+ if (dev->coherent_dma_mask <= DMA_BIT_MASK(32))
+ gfp |= __GFP_DMA32;
+ else
+#endif
+ ;
+
+ /* Don't invoke OOM killer */
+ gfp |= __GFP_NORETRY;
+
+ ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+
+ mb();
+
+ return ret;
+}
+
+static void octeon_dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ int order = get_order(size);
+
+ if (dma_release_from_coherent(dev, order, vaddr))
+ return;
+
+ swiotlb_free_coherent(dev, size, vaddr, dma_handle);
+}
+
+static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ return paddr;
+}
+
+static phys_addr_t octeon_unity_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ return daddr;
+}
+
+struct octeon_dma_map_ops {
+ struct dma_map_ops dma_map_ops;
+ dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr);
+ phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr);
+};
+
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
+ struct octeon_dma_map_ops,
+ dma_map_ops);
+
+ return ops->phys_to_dma(dev, paddr);
+}
+EXPORT_SYMBOL(phys_to_dma);
+
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev),
+ struct octeon_dma_map_ops,
+ dma_map_ops);
+
+ return ops->dma_to_phys(dev, daddr);
+}
+EXPORT_SYMBOL(dma_to_phys);
+
+static struct octeon_dma_map_ops octeon_linear_dma_map_ops = {
+ .dma_map_ops = {
+ .alloc_coherent = octeon_dma_alloc_coherent,
+ .free_coherent = octeon_dma_free_coherent,
+ .map_page = octeon_dma_map_page,
+ .unmap_page = swiotlb_unmap_page,
+ .map_sg = octeon_dma_map_sg,
+ .unmap_sg = swiotlb_unmap_sg_attrs,
+ .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+ .sync_single_for_device = octeon_dma_sync_single_for_device,
+ .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = octeon_dma_sync_sg_for_device,
+ .mapping_error = swiotlb_dma_mapping_error,
+ .dma_supported = swiotlb_dma_supported
+ },
+ .phys_to_dma = octeon_unity_phys_to_dma,
+ .dma_to_phys = octeon_unity_dma_to_phys
+};
+
+char *octeon_swiotlb;
+
+void __init plat_swiotlb_setup(void)
+{
+ int i;
+ phys_t max_addr;
+ phys_t addr_size;
+ size_t swiotlbsize;
+ unsigned long swiotlb_nslabs;
+
+ max_addr = 0;
+ addr_size = 0;
+
+ for (i = 0 ; i < boot_mem_map.nr_map; i++) {
+ struct boot_mem_map_entry *e = &boot_mem_map.map[i];
+ if (e->type != BOOT_MEM_RAM)
+ continue;
+
+ /* These addresses map low for PCI. */
+ if (e->addr > 0x410000000ull)
+ continue;
+
+ addr_size += e->size;
+
+ if (max_addr < e->addr + e->size)
+ max_addr = e->addr + e->size;
+
+ }
+
+ swiotlbsize = PAGE_SIZE;
+
+#ifdef CONFIG_PCI
+ /*
+ * For OCTEON_DMA_BAR_TYPE_SMALL, size the iotlb at 1/4 memory
+ * size to a maximum of 64MB
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+ || OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
+ swiotlbsize = addr_size / 4;
+ if (swiotlbsize > 64 * (1<<20))
+ swiotlbsize = 64 * (1<<20);
+ } else if (max_addr > 0xf0000000ul) {
+ /*
+ * Otherwise only allocate a big iotlb if there is
+ * memory past the BAR1 hole.
+ */
+ swiotlbsize = 64 * (1<<20);
+ }
+#endif
+ swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
+ swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
+ swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
+
+ octeon_swiotlb = alloc_bootmem_low_pages(swiotlbsize);
+
+ swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1);
+
+ mips_dma_map_ops = &octeon_linear_dma_map_ops.dma_map_ops;
+}
+
+#ifdef CONFIG_PCI
+static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = {
+ .dma_map_ops = {
+ .alloc_coherent = octeon_dma_alloc_coherent,
+ .free_coherent = octeon_dma_free_coherent,
+ .map_page = octeon_dma_map_page,
+ .unmap_page = swiotlb_unmap_page,
+ .map_sg = octeon_dma_map_sg,
+ .unmap_sg = swiotlb_unmap_sg_attrs,
+ .sync_single_for_cpu = swiotlb_sync_single_for_cpu,
+ .sync_single_for_device = octeon_dma_sync_single_for_device,
+ .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = octeon_dma_sync_sg_for_device,
+ .mapping_error = swiotlb_dma_mapping_error,
+ .dma_supported = swiotlb_dma_supported
+ },
+};
+
+struct dma_map_ops *octeon_pci_dma_map_ops;
+
+void __init octeon_pci_dma_init(void)
+{
+ switch (octeon_dma_bar_type) {
+ case OCTEON_DMA_BAR_TYPE_PCIE:
+ _octeon_pci_dma_map_ops.phys_to_dma = octeon_gen1_phys_to_dma;
+ _octeon_pci_dma_map_ops.dma_to_phys = octeon_gen1_dma_to_phys;
+ break;
+ case OCTEON_DMA_BAR_TYPE_BIG:
+ _octeon_pci_dma_map_ops.phys_to_dma = octeon_big_phys_to_dma;
+ _octeon_pci_dma_map_ops.dma_to_phys = octeon_big_dma_to_phys;
+ break;
+ case OCTEON_DMA_BAR_TYPE_SMALL:
+ _octeon_pci_dma_map_ops.phys_to_dma = octeon_small_phys_to_dma;
+ _octeon_pci_dma_map_ops.dma_to_phys = octeon_small_dma_to_phys;
+ break;
+ default:
+ BUG();
+ }
+ octeon_pci_dma_map_ops = &_octeon_pci_dma_map_ops.dma_map_ops;
+}
+#endif /* CONFIG_PCI */
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile
new file mode 100644
index 00000000..7f41c5be
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the Cavium Octeon specific kernel interface routines
+# under Linux.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2005-2008 Cavium Networks
+#
+
+obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o
+
+obj-$(CONFIG_CAVIUM_OCTEON_HELPER) += cvmx-helper-errata.o cvmx-helper-jtag.o
diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
new file mode 100644
index 00000000..fdf5f19b
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
@@ -0,0 +1,690 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Simple allocate only memory allocator. Used to allocate memory at
+ * application start time.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/octeon/cvmx.h>
+#include <asm/octeon/cvmx-spinlock.h>
+#include <asm/octeon/cvmx-bootmem.h>
+
+/*#define DEBUG */
+
+
+static struct cvmx_bootmem_desc *cvmx_bootmem_desc;
+
+/* See header file for descriptions of functions */
+
+/*
+ * Wrapper functions are provided for reading/writing the size and
+ * next block values as these may not be directly addressible (in 32
+ * bit applications, for instance.) Offsets of data elements in
+ * bootmem list, must match cvmx_bootmem_block_header_t.
+ */
+#define NEXT_OFFSET 0
+#define SIZE_OFFSET 8
+
+static void cvmx_bootmem_phy_set_size(uint64_t addr, uint64_t size)
+{
+ cvmx_write64_uint64((addr + SIZE_OFFSET) | (1ull << 63), size);
+}
+
+static void cvmx_bootmem_phy_set_next(uint64_t addr, uint64_t next)
+{
+ cvmx_write64_uint64((addr + NEXT_OFFSET) | (1ull << 63), next);
+}
+
+static uint64_t cvmx_bootmem_phy_get_size(uint64_t addr)
+{
+ return cvmx_read64_uint64((addr + SIZE_OFFSET) | (1ull << 63));
+}
+
+static uint64_t cvmx_bootmem_phy_get_next(uint64_t addr)
+{
+ return cvmx_read64_uint64((addr + NEXT_OFFSET) | (1ull << 63));
+}
+
+void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment,
+ uint64_t min_addr, uint64_t max_addr)
+{
+ int64_t address;
+ address =
+ cvmx_bootmem_phy_alloc(size, min_addr, max_addr, alignment, 0);
+
+ if (address > 0)
+ return cvmx_phys_to_ptr(address);
+ else
+ return NULL;
+}
+
+void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address,
+ uint64_t alignment)
+{
+ return cvmx_bootmem_alloc_range(size, alignment, address,
+ address + size);
+}
+
+void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment)
+{
+ return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
+}
+
+void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
+ uint64_t max_addr, uint64_t align,
+ char *name)
+{
+ int64_t addr;
+
+ addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr,
+ align, name, 0);
+ if (addr >= 0)
+ return cvmx_phys_to_ptr(addr);
+ else
+ return NULL;
+}
+
+void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
+ char *name)
+{
+ return cvmx_bootmem_alloc_named_range(size, address, address + size,
+ 0, name);
+}
+
+void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name)
+{
+ return cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name);
+}
+EXPORT_SYMBOL(cvmx_bootmem_alloc_named);
+
+int cvmx_bootmem_free_named(char *name)
+{
+ return cvmx_bootmem_phy_named_block_free(name, 0);
+}
+
+struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name)
+{
+ return cvmx_bootmem_phy_named_block_find(name, 0);
+}
+EXPORT_SYMBOL(cvmx_bootmem_find_named_block);
+
+void cvmx_bootmem_lock(void)
+{
+ cvmx_spinlock_lock((cvmx_spinlock_t *) &(cvmx_bootmem_desc->lock));
+}
+
+void cvmx_bootmem_unlock(void)
+{
+ cvmx_spinlock_unlock((cvmx_spinlock_t *) &(cvmx_bootmem_desc->lock));
+}
+
+int cvmx_bootmem_init(void *mem_desc_ptr)
+{
+ /* Here we set the global pointer to the bootmem descriptor
+ * block. This pointer will be used directly, so we will set
+ * it up to be directly usable by the application. It is set
+ * up as follows for the various runtime/ABI combinations:
+ *
+ * Linux 64 bit: Set XKPHYS bit
+ * Linux 32 bit: use mmap to create mapping, use virtual address
+ * CVMX 64 bit: use physical address directly
+ * CVMX 32 bit: use physical address directly
+ *
+ * Note that the CVMX environment assumes the use of 1-1 TLB
+ * mappings so that the physical addresses can be used
+ * directly
+ */
+ if (!cvmx_bootmem_desc) {
+#if defined(CVMX_ABI_64)
+ /* Set XKPHYS bit */
+ cvmx_bootmem_desc = cvmx_phys_to_ptr(CAST64(mem_desc_ptr));
+#else
+ cvmx_bootmem_desc = (struct cvmx_bootmem_desc *) mem_desc_ptr;
+#endif
+ }
+
+ return 0;
+}
+
+/*
+ * The cvmx_bootmem_phy* functions below return 64 bit physical
+ * addresses, and expose more features that the cvmx_bootmem_functions
+ * above. These are required for full memory space access in 32 bit
+ * applications, as well as for using some advance features. Most
+ * applications should not need to use these.
+ */
+
+int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min,
+ uint64_t address_max, uint64_t alignment,
+ uint32_t flags)
+{
+
+ uint64_t head_addr;
+ uint64_t ent_addr;
+ /* points to previous list entry, NULL current entry is head of list */
+ uint64_t prev_addr = 0;
+ uint64_t new_ent_addr = 0;
+ uint64_t desired_min_addr;
+
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_alloc: req_size: 0x%llx, "
+ "min_addr: 0x%llx, max_addr: 0x%llx, align: 0x%llx\n",
+ (unsigned long long)req_size,
+ (unsigned long long)address_min,
+ (unsigned long long)address_max,
+ (unsigned long long)alignment);
+#endif
+
+ if (cvmx_bootmem_desc->major_version > 3) {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
+ "version: %d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ goto error_out;
+ }
+
+ /*
+ * Do a variety of checks to validate the arguments. The
+ * allocator code will later assume that these checks have
+ * been made. We validate that the requested constraints are
+ * not self-contradictory before we look through the list of
+ * available memory.
+ */
+
+ /* 0 is not a valid req_size for this allocator */
+ if (!req_size)
+ goto error_out;
+
+ /* Round req_size up to mult of minimum alignment bytes */
+ req_size = (req_size + (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1)) &
+ ~(CVMX_BOOTMEM_ALIGNMENT_SIZE - 1);
+
+ /*
+ * Convert !0 address_min and 0 address_max to special case of
+ * range that specifies an exact memory block to allocate. Do
+ * this before other checks and adjustments so that this
+ * tranformation will be validated.
+ */
+ if (address_min && !address_max)
+ address_max = address_min + req_size;
+ else if (!address_min && !address_max)
+ address_max = ~0ull; /* If no limits given, use max limits */
+
+
+ /*
+ * Enforce minimum alignment (this also keeps the minimum free block
+ * req_size the same as the alignment req_size.
+ */
+ if (alignment < CVMX_BOOTMEM_ALIGNMENT_SIZE)
+ alignment = CVMX_BOOTMEM_ALIGNMENT_SIZE;
+
+ /*
+ * Adjust address minimum based on requested alignment (round
+ * up to meet alignment). Do this here so we can reject
+ * impossible requests up front. (NOP for address_min == 0)
+ */
+ if (alignment)
+ address_min = ALIGN(address_min, alignment);
+
+ /*
+ * Reject inconsistent args. We have adjusted these, so this
+ * may fail due to our internal changes even if this check
+ * would pass for the values the user supplied.
+ */
+ if (req_size > address_max - address_min)
+ goto error_out;
+
+ /* Walk through the list entries - first fit found is returned */
+
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_lock();
+ head_addr = cvmx_bootmem_desc->head_addr;
+ ent_addr = head_addr;
+ for (; ent_addr;
+ prev_addr = ent_addr,
+ ent_addr = cvmx_bootmem_phy_get_next(ent_addr)) {
+ uint64_t usable_base, usable_max;
+ uint64_t ent_size = cvmx_bootmem_phy_get_size(ent_addr);
+
+ if (cvmx_bootmem_phy_get_next(ent_addr)
+ && ent_addr > cvmx_bootmem_phy_get_next(ent_addr)) {
+ cvmx_dprintf("Internal bootmem_alloc() error: ent: "
+ "0x%llx, next: 0x%llx\n",
+ (unsigned long long)ent_addr,
+ (unsigned long long)
+ cvmx_bootmem_phy_get_next(ent_addr));
+ goto error_out;
+ }
+
+ /*
+ * Determine if this is an entry that can satisify the
+ * request Check to make sure entry is large enough to
+ * satisfy request.
+ */
+ usable_base =
+ ALIGN(max(address_min, ent_addr), alignment);
+ usable_max = min(address_max, ent_addr + ent_size);
+ /*
+ * We should be able to allocate block at address
+ * usable_base.
+ */
+
+ desired_min_addr = usable_base;
+ /*
+ * Determine if request can be satisfied from the
+ * current entry.
+ */
+ if (!((ent_addr + ent_size) > usable_base
+ && ent_addr < address_max
+ && req_size <= usable_max - usable_base))
+ continue;
+ /*
+ * We have found an entry that has room to satisfy the
+ * request, so allocate it from this entry. If end
+ * CVMX_BOOTMEM_FLAG_END_ALLOC set, then allocate from
+ * the end of this block rather than the beginning.
+ */
+ if (flags & CVMX_BOOTMEM_FLAG_END_ALLOC) {
+ desired_min_addr = usable_max - req_size;
+ /*
+ * Align desired address down to required
+ * alignment.
+ */
+ desired_min_addr &= ~(alignment - 1);
+ }
+
+ /* Match at start of entry */
+ if (desired_min_addr == ent_addr) {
+ if (req_size < ent_size) {
+ /*
+ * big enough to create a new block
+ * from top portion of block.
+ */
+ new_ent_addr = ent_addr + req_size;
+ cvmx_bootmem_phy_set_next(new_ent_addr,
+ cvmx_bootmem_phy_get_next(ent_addr));
+ cvmx_bootmem_phy_set_size(new_ent_addr,
+ ent_size -
+ req_size);
+
+ /*
+ * Adjust next pointer as following
+ * code uses this.
+ */
+ cvmx_bootmem_phy_set_next(ent_addr,
+ new_ent_addr);
+ }
+
+ /*
+ * adjust prev ptr or head to remove this
+ * entry from list.
+ */
+ if (prev_addr)
+ cvmx_bootmem_phy_set_next(prev_addr,
+ cvmx_bootmem_phy_get_next(ent_addr));
+ else
+ /*
+ * head of list being returned, so
+ * update head ptr.
+ */
+ cvmx_bootmem_desc->head_addr =
+ cvmx_bootmem_phy_get_next(ent_addr);
+
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+ return desired_min_addr;
+ }
+ /*
+ * block returned doesn't start at beginning of entry,
+ * so we know that we will be splitting a block off
+ * the front of this one. Create a new block from the
+ * beginning, add to list, and go to top of loop
+ * again.
+ *
+ * create new block from high portion of
+ * block, so that top block starts at desired
+ * addr.
+ */
+ new_ent_addr = desired_min_addr;
+ cvmx_bootmem_phy_set_next(new_ent_addr,
+ cvmx_bootmem_phy_get_next
+ (ent_addr));
+ cvmx_bootmem_phy_set_size(new_ent_addr,
+ cvmx_bootmem_phy_get_size
+ (ent_addr) -
+ (desired_min_addr -
+ ent_addr));
+ cvmx_bootmem_phy_set_size(ent_addr,
+ desired_min_addr - ent_addr);
+ cvmx_bootmem_phy_set_next(ent_addr, new_ent_addr);
+ /* Loop again to handle actual alloc from new block */
+ }
+error_out:
+ /* We didn't find anything, so return error */
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+ return -1;
+}
+
+int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags)
+{
+ uint64_t cur_addr;
+ uint64_t prev_addr = 0; /* zero is invalid */
+ int retval = 0;
+
+#ifdef DEBUG
+ cvmx_dprintf("__cvmx_bootmem_phy_free addr: 0x%llx, size: 0x%llx\n",
+ (unsigned long long)phy_addr, (unsigned long long)size);
+#endif
+ if (cvmx_bootmem_desc->major_version > 3) {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
+ "version: %d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ return 0;
+ }
+
+ /* 0 is not a valid size for this allocator */
+ if (!size)
+ return 0;
+
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_lock();
+ cur_addr = cvmx_bootmem_desc->head_addr;
+ if (cur_addr == 0 || phy_addr < cur_addr) {
+ /* add at front of list - special case with changing head ptr */
+ if (cur_addr && phy_addr + size > cur_addr)
+ goto bootmem_free_done; /* error, overlapping section */
+ else if (phy_addr + size == cur_addr) {
+ /* Add to front of existing first block */
+ cvmx_bootmem_phy_set_next(phy_addr,
+ cvmx_bootmem_phy_get_next
+ (cur_addr));
+ cvmx_bootmem_phy_set_size(phy_addr,
+ cvmx_bootmem_phy_get_size
+ (cur_addr) + size);
+ cvmx_bootmem_desc->head_addr = phy_addr;
+
+ } else {
+ /* New block before first block. OK if cur_addr is 0 */
+ cvmx_bootmem_phy_set_next(phy_addr, cur_addr);
+ cvmx_bootmem_phy_set_size(phy_addr, size);
+ cvmx_bootmem_desc->head_addr = phy_addr;
+ }
+ retval = 1;
+ goto bootmem_free_done;
+ }
+
+ /* Find place in list to add block */
+ while (cur_addr && phy_addr > cur_addr) {
+ prev_addr = cur_addr;
+ cur_addr = cvmx_bootmem_phy_get_next(cur_addr);
+ }
+
+ if (!cur_addr) {
+ /*
+ * We have reached the end of the list, add on to end,
+ * checking to see if we need to combine with last
+ * block
+ */
+ if (prev_addr + cvmx_bootmem_phy_get_size(prev_addr) ==
+ phy_addr) {
+ cvmx_bootmem_phy_set_size(prev_addr,
+ cvmx_bootmem_phy_get_size
+ (prev_addr) + size);
+ } else {
+ cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
+ cvmx_bootmem_phy_set_size(phy_addr, size);
+ cvmx_bootmem_phy_set_next(phy_addr, 0);
+ }
+ retval = 1;
+ goto bootmem_free_done;
+ } else {
+ /*
+ * insert between prev and cur nodes, checking for
+ * merge with either/both.
+ */
+ if (prev_addr + cvmx_bootmem_phy_get_size(prev_addr) ==
+ phy_addr) {
+ /* Merge with previous */
+ cvmx_bootmem_phy_set_size(prev_addr,
+ cvmx_bootmem_phy_get_size
+ (prev_addr) + size);
+ if (phy_addr + size == cur_addr) {
+ /* Also merge with current */
+ cvmx_bootmem_phy_set_size(prev_addr,
+ cvmx_bootmem_phy_get_size(cur_addr) +
+ cvmx_bootmem_phy_get_size(prev_addr));
+ cvmx_bootmem_phy_set_next(prev_addr,
+ cvmx_bootmem_phy_get_next(cur_addr));
+ }
+ retval = 1;
+ goto bootmem_free_done;
+ } else if (phy_addr + size == cur_addr) {
+ /* Merge with current */
+ cvmx_bootmem_phy_set_size(phy_addr,
+ cvmx_bootmem_phy_get_size
+ (cur_addr) + size);
+ cvmx_bootmem_phy_set_next(phy_addr,
+ cvmx_bootmem_phy_get_next
+ (cur_addr));
+ cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
+ retval = 1;
+ goto bootmem_free_done;
+ }
+
+ /* It is a standalone block, add in between prev and cur */
+ cvmx_bootmem_phy_set_size(phy_addr, size);
+ cvmx_bootmem_phy_set_next(phy_addr, cur_addr);
+ cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
+
+ }
+ retval = 1;
+
+bootmem_free_done:
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+ return retval;
+
+}
+
+struct cvmx_bootmem_named_block_desc *
+ cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags)
+{
+ unsigned int i;
+ struct cvmx_bootmem_named_block_desc *named_block_array_ptr;
+
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_named_block_find: %s\n", name);
+#endif
+ /*
+ * Lock the structure to make sure that it is not being
+ * changed while we are examining it.
+ */
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_lock();
+
+ /* Use XKPHYS for 64 bit linux */
+ named_block_array_ptr = (struct cvmx_bootmem_named_block_desc *)
+ cvmx_phys_to_ptr(cvmx_bootmem_desc->named_block_array_addr);
+
+#ifdef DEBUG
+ cvmx_dprintf
+ ("cvmx_bootmem_phy_named_block_find: named_block_array_ptr: %p\n",
+ named_block_array_ptr);
+#endif
+ if (cvmx_bootmem_desc->major_version == 3) {
+ for (i = 0;
+ i < cvmx_bootmem_desc->named_block_num_blocks; i++) {
+ if ((name && named_block_array_ptr[i].size
+ && !strncmp(name, named_block_array_ptr[i].name,
+ cvmx_bootmem_desc->named_block_name_len
+ - 1))
+ || (!name && !named_block_array_ptr[i].size)) {
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+
+ return &(named_block_array_ptr[i]);
+ }
+ }
+ } else {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
+ "version: %d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ }
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+
+ return NULL;
+}
+
+int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags)
+{
+ struct cvmx_bootmem_named_block_desc *named_block_ptr;
+
+ if (cvmx_bootmem_desc->major_version != 3) {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: "
+ "%d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ return 0;
+ }
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_named_block_free: %s\n", name);
+#endif
+
+ /*
+ * Take lock here, as name lookup/block free/name free need to
+ * be atomic.
+ */
+ cvmx_bootmem_lock();
+
+ named_block_ptr =
+ cvmx_bootmem_phy_named_block_find(name,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+ if (named_block_ptr) {
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_named_block_free: "
+ "%s, base: 0x%llx, size: 0x%llx\n",
+ name,
+ (unsigned long long)named_block_ptr->base_addr,
+ (unsigned long long)named_block_ptr->size);
+#endif
+ __cvmx_bootmem_phy_free(named_block_ptr->base_addr,
+ named_block_ptr->size,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+ named_block_ptr->size = 0;
+ /* Set size to zero to indicate block not used. */
+ }
+
+ cvmx_bootmem_unlock();
+ return named_block_ptr != NULL; /* 0 on failure, 1 on success */
+}
+
+int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
+ uint64_t max_addr,
+ uint64_t alignment,
+ char *name,
+ uint32_t flags)
+{
+ int64_t addr_allocated;
+ struct cvmx_bootmem_named_block_desc *named_block_desc_ptr;
+
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_named_block_alloc: size: 0x%llx, min: "
+ "0x%llx, max: 0x%llx, align: 0x%llx, name: %s\n",
+ (unsigned long long)size,
+ (unsigned long long)min_addr,
+ (unsigned long long)max_addr,
+ (unsigned long long)alignment,
+ name);
+#endif
+ if (cvmx_bootmem_desc->major_version != 3) {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: "
+ "%d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ return -1;
+ }
+
+ /*
+ * Take lock here, as name lookup/block alloc/name add need to
+ * be atomic.
+ */
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_spinlock_lock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
+
+ /* Get pointer to first available named block descriptor */
+ named_block_desc_ptr =
+ cvmx_bootmem_phy_named_block_find(NULL,
+ flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
+
+ /*
+ * Check to see if name already in use, return error if name
+ * not available or no more room for blocks.
+ */
+ if (cvmx_bootmem_phy_named_block_find(name,
+ flags | CVMX_BOOTMEM_FLAG_NO_LOCKING) || !named_block_desc_ptr) {
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
+ return -1;
+ }
+
+
+ /*
+ * Round size up to mult of minimum alignment bytes We need
+ * the actual size allocated to allow for blocks to be
+ * coallesced when they are freed. The alloc routine does the
+ * same rounding up on all allocations.
+ */
+ size = ALIGN(size, CVMX_BOOTMEM_ALIGNMENT_SIZE);
+
+ addr_allocated = cvmx_bootmem_phy_alloc(size, min_addr, max_addr,
+ alignment,
+ flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
+ if (addr_allocated >= 0) {
+ named_block_desc_ptr->base_addr = addr_allocated;
+ named_block_desc_ptr->size = size;
+ strncpy(named_block_desc_ptr->name, name,
+ cvmx_bootmem_desc->named_block_name_len);
+ named_block_desc_ptr->name[cvmx_bootmem_desc->named_block_name_len - 1] = 0;
+ }
+
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
+ return addr_allocated;
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c
new file mode 100644
index 00000000..868659e6
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c
@@ -0,0 +1,73 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Fixes and workaround for Octeon chip errata. This file
+ * contains functions called by cvmx-helper to workaround known
+ * chip errata. For the most part, code doesn't need to call
+ * these functions directly.
+ *
+ */
+#include <linux/module.h>
+
+#include <asm/octeon/octeon.h>
+
+#include <asm/octeon/cvmx-helper-jtag.h>
+
+/**
+ * Due to errata G-720, the 2nd order CDR circuit on CN52XX pass
+ * 1 doesn't work properly. The following code disables 2nd order
+ * CDR for the specified QLM.
+ *
+ * @qlm: QLM to disable 2nd order CDR for.
+ */
+void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm)
+{
+ int lane;
+ cvmx_helper_qlm_jtag_init();
+ /* We need to load all four lanes of the QLM, a total of 1072 bits */
+ for (lane = 0; lane < 4; lane++) {
+ /*
+ * Each lane has 268 bits. We need to set
+ * cfg_cdr_incx<67:64> = 3 and cfg_cdr_secord<77> =
+ * 1. All other bits are zero. Bits go in LSB first,
+ * so start off with the zeros for bits <63:0>.
+ */
+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 63 - 0 + 1);
+ /* cfg_cdr_incx<67:64>=3 */
+ cvmx_helper_qlm_jtag_shift(qlm, 67 - 64 + 1, 3);
+ /* Zeros for bits <76:68> */
+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 76 - 68 + 1);
+ /* cfg_cdr_secord<77>=1 */
+ cvmx_helper_qlm_jtag_shift(qlm, 77 - 77 + 1, 1);
+ /* Zeros for bits <267:78> */
+ cvmx_helper_qlm_jtag_shift_zeros(qlm, 267 - 78 + 1);
+ }
+ cvmx_helper_qlm_jtag_update(qlm);
+}
+EXPORT_SYMBOL(__cvmx_helper_errata_qlm_disable_2nd_order_cdr);
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c b/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c
new file mode 100644
index 00000000..c1c54890
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c
@@ -0,0 +1,144 @@
+
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Helper utilities for qlm_jtag.
+ *
+ */
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-helper-jtag.h>
+
+
+/**
+ * Initialize the internal QLM JTAG logic to allow programming
+ * of the JTAG chain by the cvmx_helper_qlm_jtag_*() functions.
+ * These functions should only be used at the direction of Cavium
+ * Networks. Programming incorrect values into the JTAG chain
+ * can cause chip damage.
+ */
+void cvmx_helper_qlm_jtag_init(void)
+{
+ union cvmx_ciu_qlm_jtgc jtgc;
+ uint32_t clock_div = 0;
+ uint32_t divisor = cvmx_sysinfo_get()->cpu_clock_hz / (25 * 1000000);
+ divisor = (divisor - 1) >> 2;
+ /* Convert the divisor into a power of 2 shift */
+ while (divisor) {
+ clock_div++;
+ divisor = divisor >> 1;
+ }
+
+ /*
+ * Clock divider for QLM JTAG operations. eclk is divided by
+ * 2^(CLK_DIV + 2)
+ */
+ jtgc.u64 = 0;
+ jtgc.s.clk_div = clock_div;
+ jtgc.s.mux_sel = 0;
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+ jtgc.s.bypass = 0x3;
+ else
+ jtgc.s.bypass = 0xf;
+ cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64);
+ cvmx_read_csr(CVMX_CIU_QLM_JTGC);
+}
+
+/**
+ * Write up to 32bits into the QLM jtag chain. Bits are shifted
+ * into the MSB and out the LSB, so you should shift in the low
+ * order bits followed by the high order bits. The JTAG chain is
+ * 4 * 268 bits long, or 1072.
+ *
+ * @qlm: QLM to shift value into
+ * @bits: Number of bits to shift in (1-32).
+ * @data: Data to shift in. Bit 0 enters the chain first, followed by
+ * bit 1, etc.
+ *
+ * Returns The low order bits of the JTAG chain that shifted out of the
+ * circle.
+ */
+uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data)
+{
+ union cvmx_ciu_qlm_jtgd jtgd;
+ jtgd.u64 = 0;
+ jtgd.s.shift = 1;
+ jtgd.s.shft_cnt = bits - 1;
+ jtgd.s.shft_reg = data;
+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
+ jtgd.s.select = 1 << qlm;
+ cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64);
+ do {
+ jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD);
+ } while (jtgd.s.shift);
+ return jtgd.s.shft_reg >> (32 - bits);
+}
+
+/**
+ * Shift long sequences of zeros into the QLM JTAG chain. It is
+ * common to need to shift more than 32 bits of zeros into the
+ * chain. This function is a convience wrapper around
+ * cvmx_helper_qlm_jtag_shift() to shift more than 32 bits of
+ * zeros at a time.
+ *
+ * @qlm: QLM to shift zeros into
+ * @bits:
+ */
+void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits)
+{
+ while (bits > 0) {
+ int n = bits;
+ if (n > 32)
+ n = 32;
+ cvmx_helper_qlm_jtag_shift(qlm, n, 0);
+ bits -= n;
+ }
+}
+
+/**
+ * Program the QLM JTAG chain into all lanes of the QLM. You must
+ * have already shifted in 268*4, or 1072 bits into the JTAG
+ * chain. Updating invalid values can possibly cause chip damage.
+ *
+ * @qlm: QLM to program
+ */
+void cvmx_helper_qlm_jtag_update(int qlm)
+{
+ union cvmx_ciu_qlm_jtgd jtgd;
+
+ /* Update the new data */
+ jtgd.u64 = 0;
+ jtgd.s.update = 1;
+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
+ jtgd.s.select = 1 << qlm;
+ cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64);
+ do {
+ jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD);
+ } while (jtgd.s.update);
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
new file mode 100644
index 00000000..d38246e3
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
@@ -0,0 +1,900 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Implementation of the Level 2 Cache (L2C) control,
+ * measurement, and debugging facilities.
+ */
+
+#include <asm/octeon/cvmx.h>
+#include <asm/octeon/cvmx-l2c.h>
+#include <asm/octeon/cvmx-spinlock.h>
+
+/*
+ * This spinlock is used internally to ensure that only one core is
+ * performing certain L2 operations at a time.
+ *
+ * NOTE: This only protects calls from within a single application -
+ * if multiple applications or operating systems are running, then it
+ * is up to the user program to coordinate between them.
+ */
+cvmx_spinlock_t cvmx_l2c_spinlock;
+
+int cvmx_l2c_get_core_way_partition(uint32_t core)
+{
+ uint32_t field;
+
+ /* Validate the core number */
+ if (core >= cvmx_octeon_num_cores())
+ return -1;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return cvmx_read_csr(CVMX_L2C_WPAR_PPX(core)) & 0xffff;
+
+ /*
+ * Use the lower two bits of the coreNumber to determine the
+ * bit offset of the UMSK[] field in the L2C_SPAR register.
+ */
+ field = (core & 0x3) * 8;
+
+ /*
+ * Return the UMSK[] field from the appropriate L2C_SPAR
+ * register based on the coreNumber.
+ */
+
+ switch (core & 0xC) {
+ case 0x0:
+ return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >> field;
+ case 0x4:
+ return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >> field;
+ case 0x8:
+ return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >> field;
+ case 0xC:
+ return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >> field;
+ }
+ return 0;
+}
+
+int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask)
+{
+ uint32_t field;
+ uint32_t valid_mask;
+
+ valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1;
+
+ mask &= valid_mask;
+
+ /* A UMSK setting which blocks all L2C Ways is an error on some chips */
+ if (mask == valid_mask && !OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return -1;
+
+ /* Validate the core number */
+ if (core >= cvmx_octeon_num_cores())
+ return -1;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ cvmx_write_csr(CVMX_L2C_WPAR_PPX(core), mask);
+ return 0;
+ }
+
+ /*
+ * Use the lower two bits of core to determine the bit offset of the
+ * UMSK[] field in the L2C_SPAR register.
+ */
+ field = (core & 0x3) * 8;
+
+ /*
+ * Assign the new mask setting to the UMSK[] field in the appropriate
+ * L2C_SPAR register based on the core_num.
+ *
+ */
+ switch (core & 0xC) {
+ case 0x0:
+ cvmx_write_csr(CVMX_L2C_SPAR0,
+ (cvmx_read_csr(CVMX_L2C_SPAR0) & ~(0xFF << field)) |
+ mask << field);
+ break;
+ case 0x4:
+ cvmx_write_csr(CVMX_L2C_SPAR1,
+ (cvmx_read_csr(CVMX_L2C_SPAR1) & ~(0xFF << field)) |
+ mask << field);
+ break;
+ case 0x8:
+ cvmx_write_csr(CVMX_L2C_SPAR2,
+ (cvmx_read_csr(CVMX_L2C_SPAR2) & ~(0xFF << field)) |
+ mask << field);
+ break;
+ case 0xC:
+ cvmx_write_csr(CVMX_L2C_SPAR3,
+ (cvmx_read_csr(CVMX_L2C_SPAR3) & ~(0xFF << field)) |
+ mask << field);
+ break;
+ }
+ return 0;
+}
+
+int cvmx_l2c_set_hw_way_partition(uint32_t mask)
+{
+ uint32_t valid_mask;
+
+ valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1;
+ mask &= valid_mask;
+
+ /* A UMSK setting which blocks all L2C Ways is an error on some chips */
+ if (mask == valid_mask && !OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return -1;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ cvmx_write_csr(CVMX_L2C_WPAR_IOBX(0), mask);
+ else
+ cvmx_write_csr(CVMX_L2C_SPAR4,
+ (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
+ return 0;
+}
+
+int cvmx_l2c_get_hw_way_partition(void)
+{
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return cvmx_read_csr(CVMX_L2C_WPAR_IOBX(0)) & 0xffff;
+ else
+ return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
+}
+
+void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event,
+ uint32_t clear_on_read)
+{
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+ union cvmx_l2c_pfctl pfctl;
+
+ pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
+
+ switch (counter) {
+ case 0:
+ pfctl.s.cnt0sel = event;
+ pfctl.s.cnt0ena = 1;
+ pfctl.s.cnt0rdclr = clear_on_read;
+ break;
+ case 1:
+ pfctl.s.cnt1sel = event;
+ pfctl.s.cnt1ena = 1;
+ pfctl.s.cnt1rdclr = clear_on_read;
+ break;
+ case 2:
+ pfctl.s.cnt2sel = event;
+ pfctl.s.cnt2ena = 1;
+ pfctl.s.cnt2rdclr = clear_on_read;
+ break;
+ case 3:
+ default:
+ pfctl.s.cnt3sel = event;
+ pfctl.s.cnt3ena = 1;
+ pfctl.s.cnt3rdclr = clear_on_read;
+ break;
+ }
+
+ cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
+ } else {
+ union cvmx_l2c_tadx_prf l2c_tadx_prf;
+ int tad;
+
+ cvmx_dprintf("L2C performance counter events are different for this chip, mapping 'event' to cvmx_l2c_tad_event_t\n");
+ if (clear_on_read)
+ cvmx_dprintf("L2C counters don't support clear on read for this chip\n");
+
+ l2c_tadx_prf.u64 = cvmx_read_csr(CVMX_L2C_TADX_PRF(0));
+
+ switch (counter) {
+ case 0:
+ l2c_tadx_prf.s.cnt0sel = event;
+ break;
+ case 1:
+ l2c_tadx_prf.s.cnt1sel = event;
+ break;
+ case 2:
+ l2c_tadx_prf.s.cnt2sel = event;
+ break;
+ default:
+ case 3:
+ l2c_tadx_prf.s.cnt3sel = event;
+ break;
+ }
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ cvmx_write_csr(CVMX_L2C_TADX_PRF(tad),
+ l2c_tadx_prf.u64);
+ }
+}
+
+uint64_t cvmx_l2c_read_perf(uint32_t counter)
+{
+ switch (counter) {
+ case 0:
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ return cvmx_read_csr(CVMX_L2C_PFC0);
+ else {
+ uint64_t counter = 0;
+ int tad;
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ counter += cvmx_read_csr(CVMX_L2C_TADX_PFC0(tad));
+ return counter;
+ }
+ case 1:
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ return cvmx_read_csr(CVMX_L2C_PFC1);
+ else {
+ uint64_t counter = 0;
+ int tad;
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ counter += cvmx_read_csr(CVMX_L2C_TADX_PFC1(tad));
+ return counter;
+ }
+ case 2:
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ return cvmx_read_csr(CVMX_L2C_PFC2);
+ else {
+ uint64_t counter = 0;
+ int tad;
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ counter += cvmx_read_csr(CVMX_L2C_TADX_PFC2(tad));
+ return counter;
+ }
+ case 3:
+ default:
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX) || OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ return cvmx_read_csr(CVMX_L2C_PFC3);
+ else {
+ uint64_t counter = 0;
+ int tad;
+ for (tad = 0; tad < CVMX_L2C_TADS; tad++)
+ counter += cvmx_read_csr(CVMX_L2C_TADX_PFC3(tad));
+ return counter;
+ }
+ }
+}
+
+/**
+ * @INTERNAL
+ * Helper function use to fault in cache lines for L2 cache locking
+ *
+ * @addr: Address of base of memory region to read into L2 cache
+ * @len: Length (in bytes) of region to fault in
+ */
+static void fault_in(uint64_t addr, int len)
+{
+ volatile char *ptr;
+ volatile char dummy;
+ /*
+ * Adjust addr and length so we get all cache lines even for
+ * small ranges spanning two cache lines.
+ */
+ len += addr & CVMX_CACHE_LINE_MASK;
+ addr &= ~CVMX_CACHE_LINE_MASK;
+ ptr = (volatile char *)cvmx_phys_to_ptr(addr);
+ /*
+ * Invalidate L1 cache to make sure all loads result in data
+ * being in L2.
+ */
+ CVMX_DCACHE_INVALIDATE;
+ while (len > 0) {
+ dummy += *ptr;
+ len -= CVMX_CACHE_LINE_SIZE;
+ ptr += CVMX_CACHE_LINE_SIZE;
+ }
+}
+
+int cvmx_l2c_lock_line(uint64_t addr)
+{
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ int shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT;
+ uint64_t assoc = cvmx_l2c_get_num_assoc();
+ uint64_t tag = addr >> shift;
+ uint64_t index = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, cvmx_l2c_address_to_index(addr) << CVMX_L2C_IDX_ADDR_SHIFT);
+ uint64_t way;
+ union cvmx_l2c_tadx_tag l2c_tadx_tag;
+
+ CVMX_CACHE_LCKL2(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, addr), 0);
+
+ /* Make sure we were able to lock the line */
+ for (way = 0; way < assoc; way++) {
+ CVMX_CACHE_LTGL2I(index | (way << shift), 0);
+ /* make sure CVMX_L2C_TADX_TAG is updated */
+ CVMX_SYNC;
+ l2c_tadx_tag.u64 = cvmx_read_csr(CVMX_L2C_TADX_TAG(0));
+ if (l2c_tadx_tag.s.valid && l2c_tadx_tag.s.tag == tag)
+ break;
+ }
+
+ /* Check if a valid line is found */
+ if (way >= assoc) {
+ /* cvmx_dprintf("ERROR: cvmx_l2c_lock_line: line not found for locking at 0x%llx address\n", (unsigned long long)addr); */
+ return -1;
+ }
+
+ /* Check if lock bit is not set */
+ if (!l2c_tadx_tag.s.lock) {
+ /* cvmx_dprintf("ERROR: cvmx_l2c_lock_line: Not able to lock at 0x%llx address\n", (unsigned long long)addr); */
+ return -1;
+ }
+ return way;
+ } else {
+ int retval = 0;
+ union cvmx_l2c_dbg l2cdbg;
+ union cvmx_l2c_lckbase lckbase;
+ union cvmx_l2c_lckoff lckoff;
+ union cvmx_l2t_err l2t_err;
+
+ cvmx_spinlock_lock(&cvmx_l2c_spinlock);
+
+ l2cdbg.u64 = 0;
+ lckbase.u64 = 0;
+ lckoff.u64 = 0;
+
+ /* Clear l2t error bits if set */
+ l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+ l2t_err.s.lckerr = 1;
+ l2t_err.s.lckerr2 = 1;
+ cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
+
+ addr &= ~CVMX_CACHE_LINE_MASK;
+
+ /* Set this core as debug core */
+ l2cdbg.s.ppnum = cvmx_get_core_num();
+ CVMX_SYNC;
+ cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ lckoff.s.lck_offset = 0; /* Only lock 1 line at a time */
+ cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
+ cvmx_read_csr(CVMX_L2C_LCKOFF);
+
+ if (((union cvmx_l2c_cfg)(cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
+ int alias_shift = CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
+ uint64_t addr_tmp = addr ^ (addr & ((1 << alias_shift) - 1)) >> CVMX_L2_SET_BITS;
+ lckbase.s.lck_base = addr_tmp >> 7;
+ } else {
+ lckbase.s.lck_base = addr >> 7;
+ }
+
+ lckbase.s.lck_ena = 1;
+ cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+ /* Make sure it gets there */
+ cvmx_read_csr(CVMX_L2C_LCKBASE);
+
+ fault_in(addr, CVMX_CACHE_LINE_SIZE);
+
+ lckbase.s.lck_ena = 0;
+ cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+ /* Make sure it gets there */
+ cvmx_read_csr(CVMX_L2C_LCKBASE);
+
+ /* Stop being debug core */
+ cvmx_write_csr(CVMX_L2C_DBG, 0);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+ if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
+ retval = 1; /* We were unable to lock the line */
+
+ cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+ return retval;
+ }
+}
+
+int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
+{
+ int retval = 0;
+
+ /* Round start/end to cache line boundaries */
+ len += start & CVMX_CACHE_LINE_MASK;
+ start &= ~CVMX_CACHE_LINE_MASK;
+ len = (len + CVMX_CACHE_LINE_MASK) & ~CVMX_CACHE_LINE_MASK;
+
+ while (len) {
+ retval += cvmx_l2c_lock_line(start);
+ start += CVMX_CACHE_LINE_SIZE;
+ len -= CVMX_CACHE_LINE_SIZE;
+ }
+ return retval;
+}
+
+void cvmx_l2c_flush(void)
+{
+ uint64_t assoc, set;
+ uint64_t n_assoc, n_set;
+
+ n_set = cvmx_l2c_get_num_sets();
+ n_assoc = cvmx_l2c_get_num_assoc();
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ uint64_t address;
+ /* These may look like constants, but they aren't... */
+ int assoc_shift = CVMX_L2C_TAG_ADDR_ALIAS_SHIFT;
+ int set_shift = CVMX_L2C_IDX_ADDR_SHIFT;
+ for (set = 0; set < n_set; set++) {
+ for (assoc = 0; assoc < n_assoc; assoc++) {
+ address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ (assoc << assoc_shift) | (set << set_shift));
+ CVMX_CACHE_WBIL2I(address, 0);
+ }
+ }
+ } else {
+ for (set = 0; set < n_set; set++)
+ for (assoc = 0; assoc < n_assoc; assoc++)
+ cvmx_l2c_flush_line(assoc, set);
+ }
+}
+
+
+int cvmx_l2c_unlock_line(uint64_t address)
+{
+
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ int assoc;
+ union cvmx_l2c_tag tag;
+ uint32_t tag_addr;
+ uint32_t index = cvmx_l2c_address_to_index(address);
+
+ tag_addr = ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) & ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+
+ /*
+ * For 63XX, we can flush a line by using the physical
+ * address directly, so finding the cache line used by
+ * the address is only required to provide the proper
+ * return value for the function.
+ */
+ for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+ tag = cvmx_l2c_get_tag(assoc, index);
+
+ if (tag.s.V && (tag.s.addr == tag_addr)) {
+ CVMX_CACHE_WBIL2(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, address), 0);
+ return tag.s.L;
+ }
+ }
+ } else {
+ int assoc;
+ union cvmx_l2c_tag tag;
+ uint32_t tag_addr;
+
+ uint32_t index = cvmx_l2c_address_to_index(address);
+
+ /* Compute portion of address that is stored in tag */
+ tag_addr = ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) & ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+ for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+ tag = cvmx_l2c_get_tag(assoc, index);
+
+ if (tag.s.V && (tag.s.addr == tag_addr)) {
+ cvmx_l2c_flush_line(assoc, index);
+ return tag.s.L;
+ }
+ }
+ }
+ return 0;
+}
+
+int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len)
+{
+ int num_unlocked = 0;
+ /* Round start/end to cache line boundaries */
+ len += start & CVMX_CACHE_LINE_MASK;
+ start &= ~CVMX_CACHE_LINE_MASK;
+ len = (len + CVMX_CACHE_LINE_MASK) & ~CVMX_CACHE_LINE_MASK;
+ while (len > 0) {
+ num_unlocked += cvmx_l2c_unlock_line(start);
+ start += CVMX_CACHE_LINE_SIZE;
+ len -= CVMX_CACHE_LINE_SIZE;
+ }
+
+ return num_unlocked;
+}
+
+/*
+ * Internal l2c tag types. These are converted to a generic structure
+ * that can be used on all chips.
+ */
+union __cvmx_l2c_tag {
+ uint64_t u64;
+ struct cvmx_l2c_tag_cn50xx {
+ uint64_t reserved:40;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:20; /* Phys mem addr (33..14) */
+ } cn50xx;
+ struct cvmx_l2c_tag_cn30xx {
+ uint64_t reserved:41;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:19; /* Phys mem addr (33..15) */
+ } cn30xx;
+ struct cvmx_l2c_tag_cn31xx {
+ uint64_t reserved:42;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:18; /* Phys mem addr (33..16) */
+ } cn31xx;
+ struct cvmx_l2c_tag_cn38xx {
+ uint64_t reserved:43;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:17; /* Phys mem addr (33..17) */
+ } cn38xx;
+ struct cvmx_l2c_tag_cn58xx {
+ uint64_t reserved:44;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:16; /* Phys mem addr (33..18) */
+ } cn58xx;
+ struct cvmx_l2c_tag_cn58xx cn56xx; /* 2048 sets */
+ struct cvmx_l2c_tag_cn31xx cn52xx; /* 512 sets */
+};
+
+
+/**
+ * @INTERNAL
+ * Function to read a L2C tag. This code make the current core
+ * the 'debug core' for the L2. This code must only be executed by
+ * 1 core at a time.
+ *
+ * @assoc: Association (way) of the tag to dump
+ * @index: Index of the cacheline
+ *
+ * Returns The Octeon model specific tag structure. This is
+ * translated by a wrapper function to a generic form that is
+ * easier for applications to use.
+ */
+static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
+{
+
+ uint64_t debug_tag_addr = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, (index << 7) + 96);
+ uint64_t core = cvmx_get_core_num();
+ union __cvmx_l2c_tag tag_val;
+ uint64_t dbg_addr = CVMX_L2C_DBG;
+ unsigned long flags;
+
+ union cvmx_l2c_dbg debug_val;
+ debug_val.u64 = 0;
+ /*
+ * For low core count parts, the core number is always small
+ * enough to stay in the correct field and not set any
+ * reserved bits.
+ */
+ debug_val.s.ppnum = core;
+ debug_val.s.l2t = 1;
+ debug_val.s.set = assoc;
+
+ local_irq_save(flags);
+ /*
+ * Make sure core is quiet (no prefetches, etc.) before
+ * entering debug mode.
+ */
+ CVMX_SYNC;
+ /* Flush L1 to make sure debug load misses L1 */
+ CVMX_DCACHE_INVALIDATE;
+
+ /*
+ * The following must be done in assembly as when in debug
+ * mode all data loads from L2 return special debug data, not
+ * normal memory contents. Also, interrupts must be disabled,
+ * since if an interrupt occurs while in debug mode the ISR
+ * will get debug data from all its memory * reads instead of
+ * the contents of memory.
+ */
+
+ asm volatile (
+ ".set push\n\t"
+ ".set mips64\n\t"
+ ".set noreorder\n\t"
+ "sd %[dbg_val], 0(%[dbg_addr])\n\t" /* Enter debug mode, wait for store */
+ "ld $0, 0(%[dbg_addr])\n\t"
+ "ld %[tag_val], 0(%[tag_addr])\n\t" /* Read L2C tag data */
+ "sd $0, 0(%[dbg_addr])\n\t" /* Exit debug mode, wait for store */
+ "ld $0, 0(%[dbg_addr])\n\t"
+ "cache 9, 0($0)\n\t" /* Invalidate dcache to discard debug data */
+ ".set pop"
+ : [tag_val] "=r" (tag_val)
+ : [dbg_addr] "r" (dbg_addr), [dbg_val] "r" (debug_val), [tag_addr] "r" (debug_tag_addr)
+ : "memory");
+
+ local_irq_restore(flags);
+
+ return tag_val;
+}
+
+
+union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index)
+{
+ union cvmx_l2c_tag tag;
+ tag.u64 = 0;
+
+ if ((int)association >= cvmx_l2c_get_num_assoc()) {
+ cvmx_dprintf("ERROR: cvmx_l2c_get_tag association out of range\n");
+ return tag;
+ }
+ if ((int)index >= cvmx_l2c_get_num_sets()) {
+ cvmx_dprintf("ERROR: cvmx_l2c_get_tag index out of range (arg: %d, max: %d)\n",
+ (int)index, cvmx_l2c_get_num_sets());
+ return tag;
+ }
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ union cvmx_l2c_tadx_tag l2c_tadx_tag;
+ uint64_t address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ (association << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) |
+ (index << CVMX_L2C_IDX_ADDR_SHIFT));
+ /*
+ * Use L2 cache Index load tag cache instruction, as
+ * hardware loads the virtual tag for the L2 cache
+ * block with the contents of L2C_TAD0_TAG
+ * register.
+ */
+ CVMX_CACHE_LTGL2I(address, 0);
+ CVMX_SYNC; /* make sure CVMX_L2C_TADX_TAG is updated */
+ l2c_tadx_tag.u64 = cvmx_read_csr(CVMX_L2C_TADX_TAG(0));
+
+ tag.s.V = l2c_tadx_tag.s.valid;
+ tag.s.D = l2c_tadx_tag.s.dirty;
+ tag.s.L = l2c_tadx_tag.s.lock;
+ tag.s.U = l2c_tadx_tag.s.use;
+ tag.s.addr = l2c_tadx_tag.s.tag;
+ } else {
+ union __cvmx_l2c_tag tmp_tag;
+ /* __read_l2_tag is intended for internal use only */
+ tmp_tag = __read_l2_tag(association, index);
+
+ /*
+ * Convert all tag structure types to generic version,
+ * as it can represent all models.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+ tag.s.V = tmp_tag.cn58xx.V;
+ tag.s.D = tmp_tag.cn58xx.D;
+ tag.s.L = tmp_tag.cn58xx.L;
+ tag.s.U = tmp_tag.cn58xx.U;
+ tag.s.addr = tmp_tag.cn58xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+ tag.s.V = tmp_tag.cn38xx.V;
+ tag.s.D = tmp_tag.cn38xx.D;
+ tag.s.L = tmp_tag.cn38xx.L;
+ tag.s.U = tmp_tag.cn38xx.U;
+ tag.s.addr = tmp_tag.cn38xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+ tag.s.V = tmp_tag.cn31xx.V;
+ tag.s.D = tmp_tag.cn31xx.D;
+ tag.s.L = tmp_tag.cn31xx.L;
+ tag.s.U = tmp_tag.cn31xx.U;
+ tag.s.addr = tmp_tag.cn31xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
+ tag.s.V = tmp_tag.cn30xx.V;
+ tag.s.D = tmp_tag.cn30xx.D;
+ tag.s.L = tmp_tag.cn30xx.L;
+ tag.s.U = tmp_tag.cn30xx.U;
+ tag.s.addr = tmp_tag.cn30xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+ tag.s.V = tmp_tag.cn50xx.V;
+ tag.s.D = tmp_tag.cn50xx.D;
+ tag.s.L = tmp_tag.cn50xx.L;
+ tag.s.U = tmp_tag.cn50xx.U;
+ tag.s.addr = tmp_tag.cn50xx.addr;
+ } else {
+ cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+ }
+ }
+ return tag;
+}
+
+uint32_t cvmx_l2c_address_to_index(uint64_t addr)
+{
+ uint64_t idx = addr >> CVMX_L2C_IDX_ADDR_SHIFT;
+ int indxalias = 0;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ union cvmx_l2c_ctl l2c_ctl;
+ l2c_ctl.u64 = cvmx_read_csr(CVMX_L2C_CTL);
+ indxalias = !l2c_ctl.s.disidxalias;
+ } else {
+ union cvmx_l2c_cfg l2c_cfg;
+ l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+ indxalias = l2c_cfg.s.idxalias;
+ }
+
+ if (indxalias) {
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ uint32_t a_14_12 = (idx / (CVMX_L2C_MEMBANK_SELECT_SIZE/(1<<CVMX_L2C_IDX_ADDR_SHIFT))) & 0x7;
+ idx ^= idx / cvmx_l2c_get_num_sets();
+ idx ^= a_14_12;
+ } else {
+ idx ^= ((addr & CVMX_L2C_ALIAS_MASK) >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
+ }
+ }
+ idx &= CVMX_L2C_IDX_MASK;
+ return idx;
+}
+
+int cvmx_l2c_get_cache_size_bytes(void)
+{
+ return cvmx_l2c_get_num_sets() * cvmx_l2c_get_num_assoc() *
+ CVMX_CACHE_LINE_SIZE;
+}
+
+/**
+ * Return log base 2 of the number of sets in the L2 cache
+ * Returns
+ */
+int cvmx_l2c_get_set_bits(void)
+{
+ int l2_set_bits;
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
+ l2_set_bits = 11; /* 2048 sets */
+ else if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
+ l2_set_bits = 10; /* 1024 sets */
+ else if (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
+ l2_set_bits = 9; /* 512 sets */
+ else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
+ l2_set_bits = 8; /* 256 sets */
+ else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
+ l2_set_bits = 7; /* 128 sets */
+ else {
+ cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+ l2_set_bits = 11; /* 2048 sets */
+ }
+ return l2_set_bits;
+}
+
+/* Return the number of sets in the L2 Cache */
+int cvmx_l2c_get_num_sets(void)
+{
+ return 1 << cvmx_l2c_get_set_bits();
+}
+
+/* Return the number of associations in the L2 Cache */
+int cvmx_l2c_get_num_assoc(void)
+{
+ int l2_assoc;
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN52XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN58XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN50XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN38XX))
+ l2_assoc = 8;
+ else if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ l2_assoc = 16;
+ else if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN30XX))
+ l2_assoc = 4;
+ else {
+ cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+ l2_assoc = 8;
+ }
+
+ /* Check to see if part of the cache is disabled */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ union cvmx_mio_fus_dat3 mio_fus_dat3;
+
+ mio_fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
+ /*
+ * cvmx_mio_fus_dat3.s.l2c_crip fuses map as follows
+ * <2> will be not used for 63xx
+ * <1> disables 1/2 ways
+ * <0> disables 1/4 ways
+ * They are cumulative, so for 63xx:
+ * <1> <0>
+ * 0 0 16-way 2MB cache
+ * 0 1 12-way 1.5MB cache
+ * 1 0 8-way 1MB cache
+ * 1 1 4-way 512KB cache
+ */
+
+ if (mio_fus_dat3.s.l2c_crip == 3)
+ l2_assoc = 4;
+ else if (mio_fus_dat3.s.l2c_crip == 2)
+ l2_assoc = 8;
+ else if (mio_fus_dat3.s.l2c_crip == 1)
+ l2_assoc = 12;
+ } else {
+ union cvmx_l2d_fus3 val;
+ val.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
+ /*
+ * Using shifts here, as bit position names are
+ * different for each model but they all mean the
+ * same.
+ */
+ if ((val.u64 >> 35) & 0x1)
+ l2_assoc = l2_assoc >> 2;
+ else if ((val.u64 >> 34) & 0x1)
+ l2_assoc = l2_assoc >> 1;
+ }
+ return l2_assoc;
+}
+
+/**
+ * Flush a line from the L2 cache
+ * This should only be called from one core at a time, as this routine
+ * sets the core to the 'debug' core in order to flush the line.
+ *
+ * @assoc: Association (or way) to flush
+ * @index: Index to flush
+ */
+void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index)
+{
+ /* Check the range of the index. */
+ if (index > (uint32_t)cvmx_l2c_get_num_sets()) {
+ cvmx_dprintf("ERROR: cvmx_l2c_flush_line index out of range.\n");
+ return;
+ }
+
+ /* Check the range of association. */
+ if (assoc > (uint32_t)cvmx_l2c_get_num_assoc()) {
+ cvmx_dprintf("ERROR: cvmx_l2c_flush_line association out of range.\n");
+ return;
+ }
+
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ uint64_t address;
+ /* Create the address based on index and association.
+ * Bits<20:17> select the way of the cache block involved in
+ * the operation
+ * Bits<16:7> of the effect address select the index
+ */
+ address = CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ (assoc << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) |
+ (index << CVMX_L2C_IDX_ADDR_SHIFT));
+ CVMX_CACHE_WBIL2I(address, 0);
+ } else {
+ union cvmx_l2c_dbg l2cdbg;
+
+ l2cdbg.u64 = 0;
+ if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
+ l2cdbg.s.ppnum = cvmx_get_core_num();
+ l2cdbg.s.finv = 1;
+
+ l2cdbg.s.set = assoc;
+ cvmx_spinlock_lock(&cvmx_l2c_spinlock);
+ /*
+ * Enter debug mode, and make sure all other writes
+ * complete before we enter debug mode
+ */
+ CVMX_SYNC;
+ cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ index * CVMX_CACHE_LINE_SIZE),
+ 0);
+ /* Exit debug mode */
+ CVMX_SYNC;
+ cvmx_write_csr(CVMX_L2C_DBG, 0);
+ cvmx_read_csr(CVMX_L2C_DBG);
+ cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+ }
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c
new file mode 100644
index 00000000..8b18a20c
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c
@@ -0,0 +1,117 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * This module provides system/board/application information obtained
+ * by the bootloader.
+ */
+#include <linux/module.h>
+
+#include <asm/octeon/cvmx.h>
+#include <asm/octeon/cvmx-spinlock.h>
+#include <asm/octeon/cvmx-sysinfo.h>
+
+/**
+ * This structure defines the private state maintained by sysinfo module.
+ *
+ */
+static struct {
+ struct cvmx_sysinfo sysinfo; /* system information */
+ cvmx_spinlock_t lock; /* mutex spinlock */
+
+} state = {
+ .lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER
+};
+
+
+/*
+ * Global variables that define the min/max of the memory region set
+ * up for 32 bit userspace access.
+ */
+uint64_t linux_mem32_min;
+uint64_t linux_mem32_max;
+uint64_t linux_mem32_wired;
+uint64_t linux_mem32_offset;
+
+/**
+ * This function returns the application information as obtained
+ * by the bootloader. This provides the core mask of the cores
+ * running the same application image, as well as the physical
+ * memory regions available to the core.
+ *
+ * Returns Pointer to the boot information structure
+ *
+ */
+struct cvmx_sysinfo *cvmx_sysinfo_get(void)
+{
+ return &(state.sysinfo);
+}
+EXPORT_SYMBOL(cvmx_sysinfo_get);
+
+/**
+ * This function is used in non-simple executive environments (such as
+ * Linux kernel, u-boot, etc.) to configure the minimal fields that
+ * are required to use simple executive files directly.
+ *
+ * Locking (if required) must be handled outside of this
+ * function
+ *
+ * @phy_mem_desc_ptr:
+ * Pointer to global physical memory descriptor
+ * (bootmem descriptor) @board_type: Octeon board
+ * type enumeration
+ *
+ * @board_rev_major:
+ * Board major revision
+ * @board_rev_minor:
+ * Board minor revision
+ * @cpu_clock_hz:
+ * CPU clock freqency in hertz
+ *
+ * Returns 0: Failure
+ * 1: success
+ */
+int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr,
+ uint16_t board_type,
+ uint8_t board_rev_major,
+ uint8_t board_rev_minor,
+ uint32_t cpu_clock_hz)
+{
+
+ /* The sysinfo structure was already initialized */
+ if (state.sysinfo.board_type)
+ return 0;
+
+ memset(&(state.sysinfo), 0x0, sizeof(state.sysinfo));
+ state.sysinfo.phy_mem_desc_ptr = phy_mem_desc_ptr;
+ state.sysinfo.board_type = board_type;
+ state.sysinfo.board_rev_major = board_rev_major;
+ state.sysinfo.board_rev_minor = board_rev_minor;
+ state.sysinfo.cpu_clock_hz = cpu_clock_hz;
+
+ return 1;
+}
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c
new file mode 100644
index 00000000..c8d35684
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/octeon-model.c
@@ -0,0 +1,358 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * File defining functions for working with different Octeon
+ * models.
+ */
+#include <asm/octeon/octeon.h>
+
+/**
+ * Given the chip processor ID from COP0, this function returns a
+ * string representing the chip model number. The string is of the
+ * form CNXXXXpX.X-FREQ-SUFFIX.
+ * - XXXX = The chip model number
+ * - X.X = Chip pass number
+ * - FREQ = Current frequency in Mhz
+ * - SUFFIX = NSP, EXP, SCP, SSP, or CP
+ *
+ * @chip_id: Chip ID
+ *
+ * Returns Model string
+ */
+const char *octeon_model_get_string(uint32_t chip_id)
+{
+ static char buffer[32];
+ return octeon_model_get_string_buffer(chip_id, buffer);
+}
+
+/*
+ * Version of octeon_model_get_string() that takes buffer as argument,
+ * as running early in u-boot static/global variables don't work when
+ * running from flash.
+ */
+const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
+{
+ const char *family;
+ const char *core_model;
+ char pass[4];
+ int clock_mhz;
+ const char *suffix;
+ union cvmx_l2d_fus3 fus3;
+ int num_cores;
+ union cvmx_mio_fus_dat2 fus_dat2;
+ union cvmx_mio_fus_dat3 fus_dat3;
+ char fuse_model[10];
+ uint32_t fuse_data = 0;
+
+ fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
+ fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
+ fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
+
+ num_cores = cvmx_octeon_num_cores();
+
+ /* Make sure the non existent devices look disabled */
+ switch ((chip_id >> 8) & 0xff) {
+ case 6: /* CN50XX */
+ case 2: /* CN30XX */
+ fus_dat3.s.nodfa_dte = 1;
+ fus_dat3.s.nozip = 1;
+ break;
+ case 4: /* CN57XX or CN56XX */
+ fus_dat3.s.nodfa_dte = 1;
+ break;
+ default:
+ break;
+ }
+
+ /* Make a guess at the suffix */
+ /* NSP = everything */
+ /* EXP = No crypto */
+ /* SCP = No DFA, No zip */
+ /* CP = No DFA, No crypto, No zip */
+ if (fus_dat3.s.nodfa_dte) {
+ if (fus_dat2.s.nocrypto)
+ suffix = "CP";
+ else
+ suffix = "SCP";
+ } else if (fus_dat2.s.nocrypto)
+ suffix = "EXP";
+ else
+ suffix = "NSP";
+
+ /*
+ * Assume pass number is encoded using <5:3><2:0>. Exceptions
+ * will be fixed later.
+ */
+ sprintf(pass, "%u.%u", ((chip_id >> 3) & 7) + 1, chip_id & 7);
+
+ /*
+ * Use the number of cores to determine the last 2 digits of
+ * the model number. There are some exceptions that are fixed
+ * later.
+ */
+ switch (num_cores) {
+ case 16:
+ core_model = "60";
+ break;
+ case 15:
+ core_model = "58";
+ break;
+ case 14:
+ core_model = "55";
+ break;
+ case 13:
+ core_model = "52";
+ break;
+ case 12:
+ core_model = "50";
+ break;
+ case 11:
+ core_model = "48";
+ break;
+ case 10:
+ core_model = "45";
+ break;
+ case 9:
+ core_model = "42";
+ break;
+ case 8:
+ core_model = "40";
+ break;
+ case 7:
+ core_model = "38";
+ break;
+ case 6:
+ core_model = "34";
+ break;
+ case 5:
+ core_model = "32";
+ break;
+ case 4:
+ core_model = "30";
+ break;
+ case 3:
+ core_model = "25";
+ break;
+ case 2:
+ core_model = "20";
+ break;
+ case 1:
+ core_model = "10";
+ break;
+ default:
+ core_model = "XX";
+ break;
+ }
+
+ /* Now figure out the family, the first two digits */
+ switch ((chip_id >> 8) & 0xff) {
+ case 0: /* CN38XX, CN37XX or CN36XX */
+ if (fus3.cn38xx.crip_512k) {
+ /*
+ * For some unknown reason, the 16 core one is
+ * called 37 instead of 36.
+ */
+ if (num_cores >= 16)
+ family = "37";
+ else
+ family = "36";
+ } else
+ family = "38";
+ /*
+ * This series of chips didn't follow the standard
+ * pass numbering.
+ */
+ switch (chip_id & 0xf) {
+ case 0:
+ strcpy(pass, "1.X");
+ break;
+ case 1:
+ strcpy(pass, "2.X");
+ break;
+ case 3:
+ strcpy(pass, "3.X");
+ break;
+ default:
+ strcpy(pass, "X.X");
+ break;
+ }
+ break;
+ case 1: /* CN31XX or CN3020 */
+ if ((chip_id & 0x10) || fus3.cn31xx.crip_128k)
+ family = "30";
+ else
+ family = "31";
+ /*
+ * This series of chips didn't follow the standard
+ * pass numbering.
+ */
+ switch (chip_id & 0xf) {
+ case 0:
+ strcpy(pass, "1.0");
+ break;
+ case 2:
+ strcpy(pass, "1.1");
+ break;
+ default:
+ strcpy(pass, "X.X");
+ break;
+ }
+ break;
+ case 2: /* CN3010 or CN3005 */
+ family = "30";
+ /* A chip with half cache is an 05 */
+ if (fus3.cn30xx.crip_64k)
+ core_model = "05";
+ /*
+ * This series of chips didn't follow the standard
+ * pass numbering.
+ */
+ switch (chip_id & 0xf) {
+ case 0:
+ strcpy(pass, "1.0");
+ break;
+ case 2:
+ strcpy(pass, "1.1");
+ break;
+ default:
+ strcpy(pass, "X.X");
+ break;
+ }
+ break;
+ case 3: /* CN58XX */
+ family = "58";
+ /* Special case. 4 core, no crypto */
+ if ((num_cores == 4) && fus_dat2.cn38xx.nocrypto)
+ core_model = "29";
+
+ /* Pass 1 uses different encodings for pass numbers */
+ if ((chip_id & 0xFF) < 0x8) {
+ switch (chip_id & 0x3) {
+ case 0:
+ strcpy(pass, "1.0");
+ break;
+ case 1:
+ strcpy(pass, "1.1");
+ break;
+ case 3:
+ strcpy(pass, "1.2");
+ break;
+ default:
+ strcpy(pass, "1.X");
+ break;
+ }
+ }
+ break;
+ case 4: /* CN57XX, CN56XX, CN55XX, CN54XX */
+ if (fus_dat2.cn56xx.raid_en) {
+ if (fus3.cn56xx.crip_1024k)
+ family = "55";
+ else
+ family = "57";
+ if (fus_dat2.cn56xx.nocrypto)
+ suffix = "SP";
+ else
+ suffix = "SSP";
+ } else {
+ if (fus_dat2.cn56xx.nocrypto)
+ suffix = "CP";
+ else {
+ suffix = "NSP";
+ if (fus_dat3.s.nozip)
+ suffix = "SCP";
+ }
+ if (fus3.cn56xx.crip_1024k)
+ family = "54";
+ else
+ family = "56";
+ }
+ break;
+ case 6: /* CN50XX */
+ family = "50";
+ break;
+ case 7: /* CN52XX */
+ if (fus3.cn52xx.crip_256k)
+ family = "51";
+ else
+ family = "52";
+ break;
+ default:
+ family = "XX";
+ core_model = "XX";
+ strcpy(pass, "X.X");
+ suffix = "XXX";
+ break;
+ }
+
+ clock_mhz = octeon_get_clock_rate() / 1000000;
+
+ if (family[0] != '3') {
+ /* Check for model in fuses, overrides normal decode */
+ /* This is _not_ valid for Octeon CN3XXX models */
+ fuse_data |= cvmx_fuse_read_byte(51);
+ fuse_data = fuse_data << 8;
+ fuse_data |= cvmx_fuse_read_byte(50);
+ fuse_data = fuse_data << 8;
+ fuse_data |= cvmx_fuse_read_byte(49);
+ fuse_data = fuse_data << 8;
+ fuse_data |= cvmx_fuse_read_byte(48);
+ if (fuse_data & 0x7ffff) {
+ int model = fuse_data & 0x3fff;
+ int suffix = (fuse_data >> 14) & 0x1f;
+ if (suffix && model) {
+ /*
+ * Have both number and suffix in
+ * fuses, so both
+ */
+ sprintf(fuse_model, "%d%c",
+ model, 'A' + suffix - 1);
+ core_model = "";
+ family = fuse_model;
+ } else if (suffix && !model) {
+ /*
+ * Only have suffix, so add suffix to
+ * 'normal' model number.
+ */
+ sprintf(fuse_model, "%s%c", core_model,
+ 'A' + suffix - 1);
+ core_model = fuse_model;
+ } else {
+ /*
+ * Don't have suffix, so just use
+ * model from fuses.
+ */
+ sprintf(fuse_model, "%d", model);
+ core_model = "";
+ family = fuse_model;
+ }
+ }
+ }
+ sprintf(buffer, "CN%s%sp%s-%d-%s",
+ family, core_model, pass, clock_mhz, suffix);
+ return buffer;
+}
diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c
new file mode 100644
index 00000000..0ee02f5e
--- /dev/null
+++ b/arch/mips/cavium-octeon/flash_setup.c
@@ -0,0 +1,75 @@
+/*
+ * Octeon Bootbus flash setup
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007, 2008 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/octeon/octeon.h>
+
+static struct map_info flash_map;
+static struct mtd_info *mymtd;
+static int nr_parts;
+static struct mtd_partition *parts;
+static const char *part_probe_types[] = {
+ "cmdlinepart",
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+ "RedBoot",
+#endif
+ NULL
+};
+
+/**
+ * Module/ driver initialization.
+ *
+ * Returns Zero on success
+ */
+static int __init flash_init(void)
+{
+ /*
+ * Read the bootbus region 0 setup to determine the base
+ * address of the flash.
+ */
+ union cvmx_mio_boot_reg_cfgx region_cfg;
+ region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0));
+ if (region_cfg.s.en) {
+ /*
+ * The bootloader always takes the flash and sets its
+ * address so the entire flash fits below
+ * 0x1fc00000. This way the flash aliases to
+ * 0x1fc00000 for booting. Software can access the
+ * full flash at the true address, while core boot can
+ * access 4MB.
+ */
+ /* Use this name so old part lines work */
+ flash_map.name = "phys_mapped_flash";
+ flash_map.phys = region_cfg.s.base << 16;
+ flash_map.size = 0x1fc00000 - flash_map.phys;
+ flash_map.bankwidth = 1;
+ flash_map.virt = ioremap(flash_map.phys, flash_map.size);
+ pr_notice("Bootbus flash: Setting flash for %luMB flash at "
+ "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
+ simple_map_init(&flash_map);
+ mymtd = do_map_probe("cfi_probe", &flash_map);
+ if (mymtd) {
+ mymtd->owner = THIS_MODULE;
+
+ nr_parts = parse_mtd_partitions(mymtd,
+ part_probe_types,
+ &parts, 0);
+ mtd_device_register(mymtd, parts, nr_parts);
+ } else {
+ pr_err("Failed to register MTD device for flash\n");
+ }
+ }
+ return 0;
+}
+
+late_initcall(flash_init);
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
new file mode 100644
index 00000000..ffd4ae66
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -0,0 +1,1044 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks
+ */
+
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/percpu.h>
+#include <linux/irq.h>
+#include <linux/smp.h>
+
+#include <asm/octeon/octeon.h>
+
+static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
+static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
+
+static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror);
+static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror);
+
+static __read_mostly u8 octeon_irq_ciu_to_irq[8][64];
+
+union octeon_ciu_chip_data {
+ void *p;
+ unsigned long l;
+ struct {
+ unsigned int line:6;
+ unsigned int bit:6;
+ } s;
+};
+
+struct octeon_core_chip_data {
+ struct mutex core_irq_mutex;
+ bool current_en;
+ bool desired_en;
+ u8 bit;
+};
+
+#define MIPS_CORE_IRQ_LINES 8
+
+static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
+
+static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit,
+ struct irq_chip *chip,
+ irq_flow_handler_t handler)
+{
+ union octeon_ciu_chip_data cd;
+
+ irq_set_chip_and_handler(irq, chip, handler);
+
+ cd.l = 0;
+ cd.s.line = line;
+ cd.s.bit = bit;
+
+ irq_set_chip_data(irq, cd.p);
+ octeon_irq_ciu_to_irq[line][bit] = irq;
+}
+
+static int octeon_coreid_for_cpu(int cpu)
+{
+#ifdef CONFIG_SMP
+ return cpu_logical_map(cpu);
+#else
+ return cvmx_get_core_num();
+#endif
+}
+
+static int octeon_cpu_for_coreid(int coreid)
+{
+#ifdef CONFIG_SMP
+ return cpu_number_map(coreid);
+#else
+ return smp_processor_id();
+#endif
+}
+
+static void octeon_irq_core_ack(struct irq_data *data)
+{
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ unsigned int bit = cd->bit;
+
+ /*
+ * We don't need to disable IRQs to make these atomic since
+ * they are already disabled earlier in the low level
+ * interrupt code.
+ */
+ clear_c0_status(0x100 << bit);
+ /* The two user interrupts must be cleared manually. */
+ if (bit < 2)
+ clear_c0_cause(0x100 << bit);
+}
+
+static void octeon_irq_core_eoi(struct irq_data *data)
+{
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+
+ /*
+ * We don't need to disable IRQs to make these atomic since
+ * they are already disabled earlier in the low level
+ * interrupt code.
+ */
+ set_c0_status(0x100 << cd->bit);
+}
+
+static void octeon_irq_core_set_enable_local(void *arg)
+{
+ struct irq_data *data = arg;
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ unsigned int mask = 0x100 << cd->bit;
+
+ /*
+ * Interrupts are already disabled, so these are atomic.
+ */
+ if (cd->desired_en)
+ set_c0_status(mask);
+ else
+ clear_c0_status(mask);
+
+}
+
+static void octeon_irq_core_disable(struct irq_data *data)
+{
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ cd->desired_en = false;
+}
+
+static void octeon_irq_core_enable(struct irq_data *data)
+{
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ cd->desired_en = true;
+}
+
+static void octeon_irq_core_bus_lock(struct irq_data *data)
+{
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&cd->core_irq_mutex);
+}
+
+static void octeon_irq_core_bus_sync_unlock(struct irq_data *data)
+{
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+
+ if (cd->desired_en != cd->current_en) {
+ on_each_cpu(octeon_irq_core_set_enable_local, data, 1);
+
+ cd->current_en = cd->desired_en;
+ }
+
+ mutex_unlock(&cd->core_irq_mutex);
+}
+
+static struct irq_chip octeon_irq_chip_core = {
+ .name = "Core",
+ .irq_enable = octeon_irq_core_enable,
+ .irq_disable = octeon_irq_core_disable,
+ .irq_ack = octeon_irq_core_ack,
+ .irq_eoi = octeon_irq_core_eoi,
+ .irq_bus_lock = octeon_irq_core_bus_lock,
+ .irq_bus_sync_unlock = octeon_irq_core_bus_sync_unlock,
+
+ .irq_cpu_online = octeon_irq_core_eoi,
+ .irq_cpu_offline = octeon_irq_core_ack,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
+
+static void __init octeon_irq_init_core(void)
+{
+ int i;
+ int irq;
+ struct octeon_core_chip_data *cd;
+
+ for (i = 0; i < MIPS_CORE_IRQ_LINES; i++) {
+ cd = &octeon_irq_core_chip_data[i];
+ cd->current_en = false;
+ cd->desired_en = false;
+ cd->bit = i;
+ mutex_init(&cd->core_irq_mutex);
+
+ irq = OCTEON_IRQ_SW0 + i;
+ switch (irq) {
+ case OCTEON_IRQ_TIMER:
+ case OCTEON_IRQ_SW0:
+ case OCTEON_IRQ_SW1:
+ case OCTEON_IRQ_5:
+ case OCTEON_IRQ_PERF:
+ irq_set_chip_data(irq, cd);
+ irq_set_chip_and_handler(irq, &octeon_irq_chip_core,
+ handle_percpu_irq);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static int next_cpu_for_irq(struct irq_data *data)
+{
+
+#ifdef CONFIG_SMP
+ int cpu;
+ int weight = cpumask_weight(data->affinity);
+
+ if (weight > 1) {
+ cpu = smp_processor_id();
+ for (;;) {
+ cpu = cpumask_next(cpu, data->affinity);
+ if (cpu >= nr_cpu_ids) {
+ cpu = -1;
+ continue;
+ } else if (cpumask_test_cpu(cpu, cpu_online_mask)) {
+ break;
+ }
+ }
+ } else if (weight == 1) {
+ cpu = cpumask_first(data->affinity);
+ } else {
+ cpu = smp_processor_id();
+ }
+ return cpu;
+#else
+ return smp_processor_id();
+#endif
+}
+
+static void octeon_irq_ciu_enable(struct irq_data *data)
+{
+ int cpu = next_cpu_for_irq(data);
+ int coreid = octeon_coreid_for_cpu(cpu);
+ unsigned long *pen;
+ unsigned long flags;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
+}
+
+static void octeon_irq_ciu_enable_local(struct irq_data *data)
+{
+ unsigned long *pen;
+ unsigned long flags;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
+}
+
+static void octeon_irq_ciu_disable_local(struct irq_data *data)
+{
+ unsigned long *pen;
+ unsigned long flags;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
+}
+
+static void octeon_irq_ciu_disable_all(struct irq_data *data)
+{
+ unsigned long flags;
+ unsigned long *pen;
+ int cpu;
+ union octeon_ciu_chip_data cd;
+
+ wmb(); /* Make sure flag changes arrive before register updates. */
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
+}
+
+static void octeon_irq_ciu_enable_all(struct irq_data *data)
+{
+ unsigned long flags;
+ unsigned long *pen;
+ int cpu;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
+}
+
+/*
+ * Enable the irq on the next core in the affinity set for chips that
+ * have the EN*_W1{S,C} registers.
+ */
+static void octeon_irq_ciu_enable_v2(struct irq_data *data)
+{
+ u64 mask;
+ int cpu = next_cpu_for_irq(data);
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ /*
+ * Called under the desc lock, so these should never get out
+ * of sync.
+ */
+ if (cd.s.line == 0) {
+ int index = octeon_coreid_for_cpu(cpu) * 2;
+ set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ } else {
+ int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ }
+}
+
+/*
+ * Enable the irq on the current CPU for chips that
+ * have the EN*_W1{S,C} registers.
+ */
+static void octeon_irq_ciu_enable_local_v2(struct irq_data *data)
+{
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ int index = cvmx_get_core_num() * 2;
+ set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ } else {
+ int index = cvmx_get_core_num() * 2 + 1;
+ set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ }
+}
+
+static void octeon_irq_ciu_disable_local_v2(struct irq_data *data)
+{
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ int index = cvmx_get_core_num() * 2;
+ clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ } else {
+ int index = cvmx_get_core_num() * 2 + 1;
+ clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ }
+}
+
+/*
+ * Write to the W1C bit in CVMX_CIU_INTX_SUM0 to clear the irq.
+ */
+static void octeon_irq_ciu_ack(struct irq_data *data)
+{
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = data->chip_data;
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ int index = cvmx_get_core_num() * 2;
+ cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
+ } else {
+ cvmx_write_csr(CVMX_CIU_INT_SUM1, mask);
+ }
+}
+
+/*
+ * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu_disable_all_v2(struct irq_data *data)
+{
+ int cpu;
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ wmb(); /* Make sure flag changes arrive before register updates. */
+
+ cd.p = data->chip_data;
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ for_each_online_cpu(cpu) {
+ int index = octeon_coreid_for_cpu(cpu) * 2;
+ clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ }
+ } else {
+ for_each_online_cpu(cpu) {
+ int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ }
+ }
+}
+
+/*
+ * Enable the irq on the all cores for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
+{
+ int cpu;
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = data->chip_data;
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ for_each_online_cpu(cpu) {
+ int index = octeon_coreid_for_cpu(cpu) * 2;
+ set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ }
+ } else {
+ for_each_online_cpu(cpu) {
+ int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ }
+ }
+}
+
+#ifdef CONFIG_SMP
+
+static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
+{
+ int cpu = smp_processor_id();
+ cpumask_t new_affinity;
+
+ if (!cpumask_test_cpu(cpu, data->affinity))
+ return;
+
+ if (cpumask_weight(data->affinity) > 1) {
+ /*
+ * It has multi CPU affinity, just remove this CPU
+ * from the affinity set.
+ */
+ cpumask_copy(&new_affinity, data->affinity);
+ cpumask_clear_cpu(cpu, &new_affinity);
+ } else {
+ /* Otherwise, put it on lowest numbered online CPU. */
+ cpumask_clear(&new_affinity);
+ cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
+ }
+ __irq_set_affinity_locked(data, &new_affinity);
+}
+
+static int octeon_irq_ciu_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force)
+{
+ int cpu;
+ bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
+ unsigned long flags;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = data->chip_data;
+
+ /*
+ * For non-v2 CIU, we will allow only single CPU affinity.
+ * This removes the need to do locking in the .ack/.eoi
+ * functions.
+ */
+ if (cpumask_weight(dest) != 1)
+ return -EINVAL;
+
+ if (!enable_one)
+ return 0;
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ set_bit(cd.s.bit, pen);
+ } else {
+ clear_bit(cd.s.bit, pen);
+ }
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ set_bit(cd.s.bit, pen);
+ } else {
+ clear_bit(cd.s.bit, pen);
+ }
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
+ return 0;
+}
+
+/*
+ * Set affinity for the irq for chips that have the EN*_W1{S,C}
+ * registers.
+ */
+static int octeon_irq_ciu_set_affinity_v2(struct irq_data *data,
+ const struct cpumask *dest,
+ bool force)
+{
+ int cpu;
+ bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ if (!enable_one)
+ return 0;
+
+ cd.p = data->chip_data;
+ mask = 1ull << cd.s.bit;
+
+ if (cd.s.line == 0) {
+ for_each_online_cpu(cpu) {
+ unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ int index = octeon_coreid_for_cpu(cpu) * 2;
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ } else {
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ }
+ }
+ } else {
+ for_each_online_cpu(cpu) {
+ unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ } else {
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ }
+ }
+ }
+ return 0;
+}
+#endif
+
+/*
+ * The v1 CIU code already masks things, so supply a dummy version to
+ * the core chip code.
+ */
+static void octeon_irq_dummy_mask(struct irq_data *data)
+{
+}
+
+/*
+ * Newer octeon chips have support for lockless CIU operation.
+ */
+static struct irq_chip octeon_irq_chip_ciu_v2 = {
+ .name = "CIU",
+ .irq_enable = octeon_irq_ciu_enable_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_v2,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu_edge_v2 = {
+ .name = "CIU-E",
+ .irq_enable = octeon_irq_ciu_enable_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_ack = octeon_irq_ciu_ack,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_v2,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu = {
+ .name = "CIU",
+ .irq_enable = octeon_irq_ciu_enable,
+ .irq_disable = octeon_irq_ciu_disable_all,
+ .irq_mask = octeon_irq_dummy_mask,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu_edge = {
+ .name = "CIU-E",
+ .irq_enable = octeon_irq_ciu_enable,
+ .irq_disable = octeon_irq_ciu_disable_all,
+ .irq_mask = octeon_irq_dummy_mask,
+ .irq_ack = octeon_irq_ciu_ack,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+/* The mbox versions don't do any affinity or round-robin. */
+static struct irq_chip octeon_irq_chip_ciu_mbox_v2 = {
+ .name = "CIU-M",
+ .irq_enable = octeon_irq_ciu_enable_all_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_ack = octeon_irq_ciu_disable_local_v2,
+ .irq_eoi = octeon_irq_ciu_enable_local_v2,
+
+ .irq_cpu_online = octeon_irq_ciu_enable_local_v2,
+ .irq_cpu_offline = octeon_irq_ciu_disable_local_v2,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
+
+static struct irq_chip octeon_irq_chip_ciu_mbox = {
+ .name = "CIU-M",
+ .irq_enable = octeon_irq_ciu_enable_all,
+ .irq_disable = octeon_irq_ciu_disable_all,
+
+ .irq_cpu_online = octeon_irq_ciu_enable_local,
+ .irq_cpu_offline = octeon_irq_ciu_disable_local,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
+
+/*
+ * Watchdog interrupts are special. They are associated with a single
+ * core, so we hardwire the affinity to that core.
+ */
+static void octeon_irq_ciu_wd_enable(struct irq_data *data)
+{
+ unsigned long flags;
+ unsigned long *pen;
+ int coreid = data->irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
+ int cpu = octeon_cpu_for_coreid(coreid);
+
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ set_bit(coreid, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+}
+
+/*
+ * Watchdog interrupts are special. They are associated with a single
+ * core, so we hardwire the affinity to that core.
+ */
+static void octeon_irq_ciu1_wd_enable_v2(struct irq_data *data)
+{
+ int coreid = data->irq - OCTEON_IRQ_WDOG0;
+ int cpu = octeon_cpu_for_coreid(coreid);
+
+ set_bit(coreid, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(coreid * 2 + 1), 1ull << coreid);
+}
+
+
+static struct irq_chip octeon_irq_chip_ciu_wd_v2 = {
+ .name = "CIU-W",
+ .irq_enable = octeon_irq_ciu1_wd_enable_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_local_v2,
+};
+
+static struct irq_chip octeon_irq_chip_ciu_wd = {
+ .name = "CIU-W",
+ .irq_enable = octeon_irq_ciu_wd_enable,
+ .irq_disable = octeon_irq_ciu_disable_all,
+ .irq_mask = octeon_irq_dummy_mask,
+};
+
+static void octeon_irq_ip2_v1(void)
+{
+ const unsigned long core_id = cvmx_get_core_num();
+ u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
+
+ ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
+ clear_c0_status(STATUSF_IP2);
+ if (likely(ciu_sum)) {
+ int bit = fls64(ciu_sum) - 1;
+ int irq = octeon_irq_ciu_to_irq[0][bit];
+ if (likely(irq))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+ } else {
+ spurious_interrupt();
+ }
+ set_c0_status(STATUSF_IP2);
+}
+
+static void octeon_irq_ip2_v2(void)
+{
+ const unsigned long core_id = cvmx_get_core_num();
+ u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
+
+ ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
+ if (likely(ciu_sum)) {
+ int bit = fls64(ciu_sum) - 1;
+ int irq = octeon_irq_ciu_to_irq[0][bit];
+ if (likely(irq))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+ } else {
+ spurious_interrupt();
+ }
+}
+static void octeon_irq_ip3_v1(void)
+{
+ u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
+
+ ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
+ clear_c0_status(STATUSF_IP3);
+ if (likely(ciu_sum)) {
+ int bit = fls64(ciu_sum) - 1;
+ int irq = octeon_irq_ciu_to_irq[1][bit];
+ if (likely(irq))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+ } else {
+ spurious_interrupt();
+ }
+ set_c0_status(STATUSF_IP3);
+}
+
+static void octeon_irq_ip3_v2(void)
+{
+ u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
+
+ ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
+ if (likely(ciu_sum)) {
+ int bit = fls64(ciu_sum) - 1;
+ int irq = octeon_irq_ciu_to_irq[1][bit];
+ if (likely(irq))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+ } else {
+ spurious_interrupt();
+ }
+}
+
+static void octeon_irq_ip4_mask(void)
+{
+ clear_c0_status(STATUSF_IP4);
+ spurious_interrupt();
+}
+
+static void (*octeon_irq_ip2)(void);
+static void (*octeon_irq_ip3)(void);
+static void (*octeon_irq_ip4)(void);
+
+void __cpuinitdata (*octeon_irq_setup_secondary)(void);
+
+static void __cpuinit octeon_irq_percpu_enable(void)
+{
+ irq_cpu_online();
+}
+
+static void __cpuinit octeon_irq_init_ciu_percpu(void)
+{
+ int coreid = cvmx_get_core_num();
+ /*
+ * Disable All CIU Interrupts. The ones we need will be
+ * enabled later. Read the SUM register so we know the write
+ * completed.
+ */
+ cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
+ cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
+}
+
+static void __cpuinit octeon_irq_setup_secondary_ciu(void)
+{
+
+ __get_cpu_var(octeon_irq_ciu0_en_mirror) = 0;
+ __get_cpu_var(octeon_irq_ciu1_en_mirror) = 0;
+
+ octeon_irq_init_ciu_percpu();
+ octeon_irq_percpu_enable();
+
+ /* Enable the CIU lines */
+ set_c0_status(STATUSF_IP3 | STATUSF_IP2);
+ clear_c0_status(STATUSF_IP4);
+}
+
+static void __init octeon_irq_init_ciu(void)
+{
+ unsigned int i;
+ struct irq_chip *chip;
+ struct irq_chip *chip_edge;
+ struct irq_chip *chip_mbox;
+ struct irq_chip *chip_wd;
+
+ octeon_irq_init_ciu_percpu();
+ octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ octeon_irq_ip2 = octeon_irq_ip2_v2;
+ octeon_irq_ip3 = octeon_irq_ip3_v2;
+ chip = &octeon_irq_chip_ciu_v2;
+ chip_edge = &octeon_irq_chip_ciu_edge_v2;
+ chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
+ chip_wd = &octeon_irq_chip_ciu_wd_v2;
+ } else {
+ octeon_irq_ip2 = octeon_irq_ip2_v1;
+ octeon_irq_ip3 = octeon_irq_ip3_v1;
+ chip = &octeon_irq_chip_ciu;
+ chip_edge = &octeon_irq_chip_ciu_edge;
+ chip_mbox = &octeon_irq_chip_ciu_mbox;
+ chip_wd = &octeon_irq_chip_ciu_wd;
+ }
+ octeon_irq_ip4 = octeon_irq_ip4_mask;
+
+ /* Mips internal */
+ octeon_irq_init_core();
+
+ /* CIU_0 */
+ for (i = 0; i < 16; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
+ for (i = 0; i < 16; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq);
+
+ for (i = 0; i < 4; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
+ for (i = 0; i < 4; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq);
+
+ for (i = 0; i < 2; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq);
+
+ for (i = 0; i < 4; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
+
+ /* CIU_1 */
+ for (i = 0; i < 16; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq);
+
+ /* Enable the CIU lines */
+ set_c0_status(STATUSF_IP3 | STATUSF_IP2);
+ clear_c0_status(STATUSF_IP4);
+}
+
+void __init arch_init_irq(void)
+{
+#ifdef CONFIG_SMP
+ /* Set the default affinity to the boot cpu. */
+ cpumask_clear(irq_default_affinity);
+ cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
+#endif
+ octeon_irq_init_ciu();
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long cop0_cause;
+ unsigned long cop0_status;
+
+ while (1) {
+ cop0_cause = read_c0_cause();
+ cop0_status = read_c0_status();
+ cop0_cause &= cop0_status;
+ cop0_cause &= ST0_IM;
+
+ if (unlikely(cop0_cause & STATUSF_IP2))
+ octeon_irq_ip2();
+ else if (unlikely(cop0_cause & STATUSF_IP3))
+ octeon_irq_ip3();
+ else if (unlikely(cop0_cause & STATUSF_IP4))
+ octeon_irq_ip4();
+ else if (likely(cop0_cause))
+ do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE);
+ else
+ break;
+ }
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+void fixup_irqs(void)
+{
+ irq_cpu_offline();
+}
+
+#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S
new file mode 100644
index 00000000..88e0cddc
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon-memcpy.S
@@ -0,0 +1,521 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Unified implementation of memcpy, memmove and the __copy_user backend.
+ *
+ * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Broadcom, Inc.
+ * memcpy/copy_user author: Mark Vandevoorde
+ *
+ * Mnemonic names for arguments to memcpy/__copy_user
+ */
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define dst a0
+#define src a1
+#define len a2
+
+/*
+ * Spec
+ *
+ * memcpy copies len bytes from src to dst and sets v0 to dst.
+ * It assumes that
+ * - src and dst don't overlap
+ * - src is readable
+ * - dst is writable
+ * memcpy uses the standard calling convention
+ *
+ * __copy_user copies up to len bytes from src to dst and sets a2 (len) to
+ * the number of uncopied bytes due to an exception caused by a read or write.
+ * __copy_user assumes that src and dst don't overlap, and that the call is
+ * implementing one of the following:
+ * copy_to_user
+ * - src is readable (no exceptions when reading src)
+ * copy_from_user
+ * - dst is writable (no exceptions when writing dst)
+ * __copy_user uses a non-standard calling convention; see
+ * arch/mips/include/asm/uaccess.h
+ *
+ * When an exception happens on a load, the handler must
+ # ensure that all of the destination buffer is overwritten to prevent
+ * leaking information to user mode programs.
+ */
+
+/*
+ * Implementation
+ */
+
+/*
+ * The exception handler for loads requires that:
+ * 1- AT contain the address of the byte just past the end of the source
+ * of the copy,
+ * 2- src_entry <= src < AT, and
+ * 3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores adjust len (if necessary) and return.
+ * These handlers do not need to overwrite any data.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.
+ */
+
+#define EXC(inst_reg,addr,handler) \
+9: inst_reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+/*
+ * Only on the 64-bit kernel we can made use of 64-bit registers.
+ */
+#ifdef CONFIG_64BIT
+#define USE_DOUBLE
+#endif
+
+#ifdef USE_DOUBLE
+
+#define LOAD ld
+#define LOADL ldl
+#define LOADR ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE sd
+#define ADD daddu
+#define SUB dsubu
+#define SRL dsrl
+#define SRA dsra
+#define SLL dsll
+#define SLLV dsllv
+#define SRLV dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+/*
+ * As we are sharing code base with the mips32 tree (which use the o32 ABI
+ * register definitions). We need to redefine the register definitions from
+ * the n64 ABI register naming to the o32 ABI register naming.
+ */
+#undef t0
+#undef t1
+#undef t2
+#undef t3
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+
+#else
+
+#define LOAD lw
+#define LOADL lwl
+#define LOADR lwr
+#define STOREL swl
+#define STORER swr
+#define STORE sw
+#define ADD addu
+#define SUB subu
+#define SRL srl
+#define SLL sll
+#define SRA sra
+#define SLLV sllv
+#define SRLV srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST LOADL
+#define STFIRST STORER
+#define STREST STOREL
+#define SHIFT_DISCARD SLLV
+#else
+#define LDFIRST LOADL
+#define LDREST LOADR
+#define STFIRST STOREL
+#define STREST STORER
+#define SHIFT_DISCARD SRLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit) (FIRST(unit)+NBYTES-1)
+#define UNIT(unit) FIRST(unit)
+
+#define ADDRMASK (NBYTES-1)
+
+ .text
+ .set noreorder
+ .set noat
+
+/*
+ * A combined memcpy/__copy_user
+ * __copy_user sets len to 0 for success; else to an upper bound of
+ * the number of uncopied bytes.
+ * memcpy sets v0 to dst.
+ */
+ .align 5
+LEAF(memcpy) /* a0=dst a1=src a2=len */
+ move v0, dst /* return value */
+__memcpy:
+FEXPORT(__copy_user)
+ /*
+ * Note: dst & src may be unaligned, len may be 0
+ * Temps
+ */
+ #
+ # Octeon doesn't care if the destination is unaligned. The hardware
+ # can fix it faster than we can special case the assembly.
+ #
+ pref 0, 0(src)
+ sltu t0, len, NBYTES # Check if < 1 word
+ bnez t0, copy_bytes_checklen
+ and t0, src, ADDRMASK # Check if src unaligned
+ bnez t0, src_unaligned
+ sltu t0, len, 4*NBYTES # Check if < 4 words
+ bnez t0, less_than_4units
+ sltu t0, len, 8*NBYTES # Check if < 8 words
+ bnez t0, less_than_8units
+ sltu t0, len, 16*NBYTES # Check if < 16 words
+ bnez t0, cleanup_both_aligned
+ sltu t0, len, 128+1 # Check if len < 129
+ bnez t0, 1f # Skip prefetch if len is too short
+ sltu t0, len, 256+1 # Check if len < 257
+ bnez t0, 1f # Skip prefetch if len is too short
+ pref 0, 128(src) # We must not prefetch invalid addresses
+ #
+ # This is where we loop if there is more than 128 bytes left
+2: pref 0, 256(src) # We must not prefetch invalid addresses
+ #
+ # This is where we loop if we can't prefetch anymore
+1:
+EXC( LOAD t0, UNIT(0)(src), l_exc)
+EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+ SUB len, len, 16*NBYTES
+EXC( STORE t0, UNIT(0)(dst), s_exc_p16u)
+EXC( STORE t1, UNIT(1)(dst), s_exc_p15u)
+EXC( STORE t2, UNIT(2)(dst), s_exc_p14u)
+EXC( STORE t3, UNIT(3)(dst), s_exc_p13u)
+EXC( LOAD t0, UNIT(4)(src), l_exc_copy)
+EXC( LOAD t1, UNIT(5)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(6)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(7)(src), l_exc_copy)
+EXC( STORE t0, UNIT(4)(dst), s_exc_p12u)
+EXC( STORE t1, UNIT(5)(dst), s_exc_p11u)
+EXC( STORE t2, UNIT(6)(dst), s_exc_p10u)
+ ADD src, src, 16*NBYTES
+EXC( STORE t3, UNIT(7)(dst), s_exc_p9u)
+ ADD dst, dst, 16*NBYTES
+EXC( LOAD t0, UNIT(-8)(src), l_exc_copy)
+EXC( LOAD t1, UNIT(-7)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(-6)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(-5)(src), l_exc_copy)
+EXC( STORE t0, UNIT(-8)(dst), s_exc_p8u)
+EXC( STORE t1, UNIT(-7)(dst), s_exc_p7u)
+EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u)
+EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u)
+EXC( LOAD t0, UNIT(-4)(src), l_exc_copy)
+EXC( LOAD t1, UNIT(-3)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(-2)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(-1)(src), l_exc_copy)
+EXC( STORE t0, UNIT(-4)(dst), s_exc_p4u)
+EXC( STORE t1, UNIT(-3)(dst), s_exc_p3u)
+EXC( STORE t2, UNIT(-2)(dst), s_exc_p2u)
+EXC( STORE t3, UNIT(-1)(dst), s_exc_p1u)
+ sltu t0, len, 256+1 # See if we can prefetch more
+ beqz t0, 2b
+ sltu t0, len, 128 # See if we can loop more time
+ beqz t0, 1b
+ nop
+ #
+ # Jump here if there are less than 16*NBYTES left.
+ #
+cleanup_both_aligned:
+ beqz len, done
+ sltu t0, len, 8*NBYTES
+ bnez t0, less_than_8units
+ nop
+EXC( LOAD t0, UNIT(0)(src), l_exc)
+EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+ SUB len, len, 8*NBYTES
+EXC( STORE t0, UNIT(0)(dst), s_exc_p8u)
+EXC( STORE t1, UNIT(1)(dst), s_exc_p7u)
+EXC( STORE t2, UNIT(2)(dst), s_exc_p6u)
+EXC( STORE t3, UNIT(3)(dst), s_exc_p5u)
+EXC( LOAD t0, UNIT(4)(src), l_exc_copy)
+EXC( LOAD t1, UNIT(5)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(6)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(7)(src), l_exc_copy)
+EXC( STORE t0, UNIT(4)(dst), s_exc_p4u)
+EXC( STORE t1, UNIT(5)(dst), s_exc_p3u)
+EXC( STORE t2, UNIT(6)(dst), s_exc_p2u)
+EXC( STORE t3, UNIT(7)(dst), s_exc_p1u)
+ ADD src, src, 8*NBYTES
+ beqz len, done
+ ADD dst, dst, 8*NBYTES
+ #
+ # Jump here if there are less than 8*NBYTES left.
+ #
+less_than_8units:
+ sltu t0, len, 4*NBYTES
+ bnez t0, less_than_4units
+ nop
+EXC( LOAD t0, UNIT(0)(src), l_exc)
+EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+ SUB len, len, 4*NBYTES
+EXC( STORE t0, UNIT(0)(dst), s_exc_p4u)
+EXC( STORE t1, UNIT(1)(dst), s_exc_p3u)
+EXC( STORE t2, UNIT(2)(dst), s_exc_p2u)
+EXC( STORE t3, UNIT(3)(dst), s_exc_p1u)
+ ADD src, src, 4*NBYTES
+ beqz len, done
+ ADD dst, dst, 4*NBYTES
+ #
+ # Jump here if there are less than 4*NBYTES left. This means
+ # we may need to copy up to 3 NBYTES words.
+ #
+less_than_4units:
+ sltu t0, len, 1*NBYTES
+ bnez t0, copy_bytes_checklen
+ nop
+ #
+ # 1) Copy NBYTES, then check length again
+ #
+EXC( LOAD t0, 0(src), l_exc)
+ SUB len, len, NBYTES
+ sltu t1, len, 8
+EXC( STORE t0, 0(dst), s_exc_p1u)
+ ADD src, src, NBYTES
+ bnez t1, copy_bytes_checklen
+ ADD dst, dst, NBYTES
+ #
+ # 2) Copy NBYTES, then check length again
+ #
+EXC( LOAD t0, 0(src), l_exc)
+ SUB len, len, NBYTES
+ sltu t1, len, 8
+EXC( STORE t0, 0(dst), s_exc_p1u)
+ ADD src, src, NBYTES
+ bnez t1, copy_bytes_checklen
+ ADD dst, dst, NBYTES
+ #
+ # 3) Copy NBYTES, then check length again
+ #
+EXC( LOAD t0, 0(src), l_exc)
+ SUB len, len, NBYTES
+ ADD src, src, NBYTES
+ ADD dst, dst, NBYTES
+ b copy_bytes_checklen
+EXC( STORE t0, -8(dst), s_exc_p1u)
+
+src_unaligned:
+#define rem t8
+ SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
+ beqz t0, cleanup_src_unaligned
+ and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC( LDFIRST t0, FIRST(0)(src), l_exc)
+EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy)
+ SUB len, len, 4*NBYTES
+EXC( LDREST t0, REST(0)(src), l_exc_copy)
+EXC( LDREST t1, REST(1)(src), l_exc_copy)
+EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy)
+EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy)
+EXC( LDREST t2, REST(2)(src), l_exc_copy)
+EXC( LDREST t3, REST(3)(src), l_exc_copy)
+ ADD src, src, 4*NBYTES
+EXC( STORE t0, UNIT(0)(dst), s_exc_p4u)
+EXC( STORE t1, UNIT(1)(dst), s_exc_p3u)
+EXC( STORE t2, UNIT(2)(dst), s_exc_p2u)
+EXC( STORE t3, UNIT(3)(dst), s_exc_p1u)
+ bne len, rem, 1b
+ ADD dst, dst, 4*NBYTES
+
+cleanup_src_unaligned:
+ beqz len, done
+ and rem, len, NBYTES-1 # rem = len % NBYTES
+ beq rem, len, copy_bytes
+ nop
+1:
+EXC( LDFIRST t0, FIRST(0)(src), l_exc)
+EXC( LDREST t0, REST(0)(src), l_exc_copy)
+ SUB len, len, NBYTES
+EXC( STORE t0, 0(dst), s_exc_p1u)
+ ADD src, src, NBYTES
+ bne len, rem, 1b
+ ADD dst, dst, NBYTES
+
+copy_bytes_checklen:
+ beqz len, done
+ nop
+copy_bytes:
+ /* 0 < len < NBYTES */
+#define COPY_BYTE(N) \
+EXC( lb t0, N(src), l_exc); \
+ SUB len, len, 1; \
+ beqz len, done; \
+EXC( sb t0, N(dst), s_exc_p1)
+
+ COPY_BYTE(0)
+ COPY_BYTE(1)
+#ifdef USE_DOUBLE
+ COPY_BYTE(2)
+ COPY_BYTE(3)
+ COPY_BYTE(4)
+ COPY_BYTE(5)
+#endif
+EXC( lb t0, NBYTES-2(src), l_exc)
+ SUB len, len, 1
+ jr ra
+EXC( sb t0, NBYTES-2(dst), s_exc_p1)
+done:
+ jr ra
+ nop
+ END(memcpy)
+
+l_exc_copy:
+ /*
+ * Copy bytes from src until faulting load address (or until a
+ * lb faults)
+ *
+ * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+ * may be more than a byte beyond the last address.
+ * Hence, the lb below may get an exception.
+ *
+ * Assumes src < THREAD_BUADDR($28)
+ */
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0)
+1:
+EXC( lb t1, 0(src), l_exc)
+ ADD src, src, 1
+ sb t1, 0(dst) # can't fault -- we're copy_from_user
+ bne src, t0, 1b
+ ADD dst, dst, 1
+l_exc:
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
+ nop
+ SUB len, AT, t0 # len number of uncopied bytes
+ /*
+ * Here's where we rely on src and dst being incremented in tandem,
+ * See (3) above.
+ * dst += (fault addr - src) to put dst at first byte to clear
+ */
+ ADD dst, t0 # compute start address in a1
+ SUB dst, src
+ /*
+ * Clear len bytes starting at dst. Can't call __bzero because it
+ * might modify len. An inefficient loop for these rare times...
+ */
+ beqz len, done
+ SUB src, len, 1
+1: sb zero, 0(dst)
+ ADD dst, dst, 1
+ bnez src, 1b
+ SUB src, src, 1
+ jr ra
+ nop
+
+
+#define SEXC(n) \
+s_exc_p ## n ## u: \
+ jr ra; \
+ ADD len, len, n*NBYTES
+
+SEXC(16)
+SEXC(15)
+SEXC(14)
+SEXC(13)
+SEXC(12)
+SEXC(11)
+SEXC(10)
+SEXC(9)
+SEXC(8)
+SEXC(7)
+SEXC(6)
+SEXC(5)
+SEXC(4)
+SEXC(3)
+SEXC(2)
+SEXC(1)
+
+s_exc_p1:
+ jr ra
+ ADD len, len, 1
+s_exc:
+ jr ra
+ nop
+
+ .align 5
+LEAF(memmove)
+ ADD t0, a0, a2
+ ADD t1, a1, a2
+ sltu t0, a1, t0 # dst + len <= src -> memcpy
+ sltu t1, a0, t1 # dst >= src + len -> memcpy
+ and t0, t1
+ beqz t0, __memcpy
+ move v0, a0 /* return value */
+ beqz a2, r_out
+ END(memmove)
+
+ /* fall through to __rmemcpy */
+LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
+ sltu t0, a1, a0
+ beqz t0, r_end_bytes_up # src >= dst
+ nop
+ ADD a0, a2 # dst = dst + len
+ ADD a1, a2 # src = src + len
+
+r_end_bytes:
+ lb t0, -1(a1)
+ SUB a2, a2, 0x1
+ sb t0, -1(a0)
+ SUB a1, a1, 0x1
+ bnez a2, r_end_bytes
+ SUB a0, a0, 0x1
+
+r_out:
+ jr ra
+ move a2, zero
+
+r_end_bytes_up:
+ lb t0, (a1)
+ SUB a2, a2, 0x1
+ sb t0, (a0)
+ ADD a1, a1, 0x1
+ bnez a2, r_end_bytes_up
+ ADD a0, a0, 0x1
+
+ jr ra
+ move a2, zero
+ END(__rmemcpy)
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
new file mode 100644
index 00000000..cd61d728
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -0,0 +1,445 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004-2010 Cavium Networks
+ * Copyright (C) 2008 Wind River Systems
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/usb.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-rnm-defs.h>
+
+static struct octeon_cf_data octeon_cf_data;
+
+static int __init octeon_cf_device_init(void)
+{
+ union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
+ unsigned long base_ptr, region_base, region_size;
+ struct platform_device *pd;
+ struct resource cf_resources[3];
+ unsigned int num_resources;
+ int i;
+ int ret = 0;
+
+ /* Setup octeon-cf platform device if present. */
+ base_ptr = 0;
+ if (octeon_bootinfo->major_version == 1
+ && octeon_bootinfo->minor_version >= 1) {
+ if (octeon_bootinfo->compact_flash_common_base_addr)
+ base_ptr =
+ octeon_bootinfo->compact_flash_common_base_addr;
+ } else {
+ base_ptr = 0x1d000800;
+ }
+
+ if (!base_ptr)
+ return ret;
+
+ /* Find CS0 region. */
+ for (i = 0; i < 8; i++) {
+ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i));
+ region_base = mio_boot_reg_cfg.s.base << 16;
+ region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+ if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
+ && base_ptr < region_base + region_size)
+ break;
+ }
+ if (i >= 7) {
+ /* i and i + 1 are CS0 and CS1, both must be less than 8. */
+ goto out;
+ }
+ octeon_cf_data.base_region = i;
+ octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width;
+ octeon_cf_data.base_region_bias = base_ptr - region_base;
+ memset(cf_resources, 0, sizeof(cf_resources));
+ num_resources = 0;
+ cf_resources[num_resources].flags = IORESOURCE_MEM;
+ cf_resources[num_resources].start = region_base;
+ cf_resources[num_resources].end = region_base + region_size - 1;
+ num_resources++;
+
+
+ if (!(base_ptr & 0xfffful)) {
+ /*
+ * Boot loader signals availability of DMA (true_ide
+ * mode) by setting low order bits of base_ptr to
+ * zero.
+ */
+
+ /* Assume that CS1 immediately follows. */
+ mio_boot_reg_cfg.u64 =
+ cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1));
+ region_base = mio_boot_reg_cfg.s.base << 16;
+ region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+ if (!mio_boot_reg_cfg.s.en)
+ goto out;
+
+ cf_resources[num_resources].flags = IORESOURCE_MEM;
+ cf_resources[num_resources].start = region_base;
+ cf_resources[num_resources].end = region_base + region_size - 1;
+ num_resources++;
+
+ octeon_cf_data.dma_engine = 0;
+ cf_resources[num_resources].flags = IORESOURCE_IRQ;
+ cf_resources[num_resources].start = OCTEON_IRQ_BOOTDMA;
+ cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA;
+ num_resources++;
+ } else {
+ octeon_cf_data.dma_engine = -1;
+ }
+
+ pd = platform_device_alloc("pata_octeon_cf", -1);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ pd->dev.platform_data = &octeon_cf_data;
+
+ ret = platform_device_add_resources(pd, cf_resources, num_resources);
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+
+ return ret;
+fail:
+ platform_device_put(pd);
+out:
+ return ret;
+}
+device_initcall(octeon_cf_device_init);
+
+/* Octeon Random Number Generator. */
+static int __init octeon_rng_device_init(void)
+{
+ struct platform_device *pd;
+ int ret = 0;
+
+ struct resource rng_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .start = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS),
+ .end = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS) + 0xf
+ }, {
+ .flags = IORESOURCE_MEM,
+ .start = cvmx_build_io_address(8, 0),
+ .end = cvmx_build_io_address(8, 0) + 0x7
+ }
+ };
+
+ pd = platform_device_alloc("octeon_rng", -1);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = platform_device_add_resources(pd, rng_resources,
+ ARRAY_SIZE(rng_resources));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+
+ return ret;
+fail:
+ platform_device_put(pd);
+
+out:
+ return ret;
+}
+device_initcall(octeon_rng_device_init);
+
+static struct i2c_board_info __initdata octeon_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68),
+ },
+};
+
+static int __init octeon_i2c_devices_init(void)
+{
+ return i2c_register_board_info(0, octeon_i2c_devices,
+ ARRAY_SIZE(octeon_i2c_devices));
+}
+arch_initcall(octeon_i2c_devices_init);
+
+#define OCTEON_I2C_IO_BASE 0x1180000001000ull
+#define OCTEON_I2C_IO_UNIT_OFFSET 0x200
+
+static struct octeon_i2c_data octeon_i2c_data[2];
+
+static int __init octeon_i2c_device_init(void)
+{
+ struct platform_device *pd;
+ int ret = 0;
+ int port, num_ports;
+
+ struct resource i2c_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
+ num_ports = 2;
+ else
+ num_ports = 1;
+
+ for (port = 0; port < num_ports; port++) {
+ octeon_i2c_data[port].sys_freq = octeon_get_io_clock_rate();
+ /*FIXME: should be examined. At the moment is set for 100Khz */
+ octeon_i2c_data[port].i2c_freq = 100000;
+
+ pd = platform_device_alloc("i2c-octeon", port);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ pd->dev.platform_data = octeon_i2c_data + port;
+
+ i2c_resources[0].start =
+ OCTEON_I2C_IO_BASE + (port * OCTEON_I2C_IO_UNIT_OFFSET);
+ i2c_resources[0].end = i2c_resources[0].start + 0x1f;
+ switch (port) {
+ case 0:
+ i2c_resources[1].start = OCTEON_IRQ_TWSI;
+ i2c_resources[1].end = OCTEON_IRQ_TWSI;
+ break;
+ case 1:
+ i2c_resources[1].start = OCTEON_IRQ_TWSI2;
+ i2c_resources[1].end = OCTEON_IRQ_TWSI2;
+ break;
+ default:
+ BUG();
+ }
+
+ ret = platform_device_add_resources(pd,
+ i2c_resources,
+ ARRAY_SIZE(i2c_resources));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+ }
+ return ret;
+fail:
+ platform_device_put(pd);
+out:
+ return ret;
+}
+device_initcall(octeon_i2c_device_init);
+
+/* Octeon SMI/MDIO interface. */
+static int __init octeon_mdiobus_device_init(void)
+{
+ struct platform_device *pd;
+ int ret = 0;
+
+ if (octeon_is_simulation())
+ return 0; /* No mdio in the simulator. */
+
+ /* The bus number is the platform_device id. */
+ pd = platform_device_alloc("mdio-octeon", 0);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+
+ return ret;
+fail:
+ platform_device_put(pd);
+
+out:
+ return ret;
+
+}
+device_initcall(octeon_mdiobus_device_init);
+
+/* Octeon mgmt port Ethernet interface. */
+static int __init octeon_mgmt_device_init(void)
+{
+ struct platform_device *pd;
+ int ret = 0;
+ int port, num_ports;
+
+ struct resource mgmt_port_resource = {
+ .flags = IORESOURCE_IRQ,
+ .start = -1,
+ .end = -1
+ };
+
+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX))
+ return 0;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX))
+ num_ports = 1;
+ else
+ num_ports = 2;
+
+ for (port = 0; port < num_ports; port++) {
+ pd = platform_device_alloc("octeon_mgmt", port);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ /* No DMA restrictions */
+ pd->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+ pd->dev.dma_mask = &pd->dev.coherent_dma_mask;
+
+ switch (port) {
+ case 0:
+ mgmt_port_resource.start = OCTEON_IRQ_MII0;
+ break;
+ case 1:
+ mgmt_port_resource.start = OCTEON_IRQ_MII1;
+ break;
+ default:
+ BUG();
+ }
+ mgmt_port_resource.end = mgmt_port_resource.start;
+
+ ret = platform_device_add_resources(pd, &mgmt_port_resource, 1);
+
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+ }
+ return ret;
+fail:
+ platform_device_put(pd);
+
+out:
+ return ret;
+
+}
+device_initcall(octeon_mgmt_device_init);
+
+#ifdef CONFIG_USB
+
+static int __init octeon_ehci_device_init(void)
+{
+ struct platform_device *pd;
+ int ret = 0;
+
+ struct resource usb_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ /* Only Octeon2 has ehci/ohci */
+ if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return 0;
+
+ if (octeon_is_simulation() || usb_disabled())
+ return 0; /* No USB in the simulator. */
+
+ pd = platform_device_alloc("octeon-ehci", 0);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ usb_resources[0].start = 0x00016F0000000000ULL;
+ usb_resources[0].end = usb_resources[0].start + 0x100;
+
+ usb_resources[1].start = OCTEON_IRQ_USB0;
+ usb_resources[1].end = OCTEON_IRQ_USB0;
+
+ ret = platform_device_add_resources(pd, usb_resources,
+ ARRAY_SIZE(usb_resources));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+
+ return ret;
+fail:
+ platform_device_put(pd);
+out:
+ return ret;
+}
+device_initcall(octeon_ehci_device_init);
+
+static int __init octeon_ohci_device_init(void)
+{
+ struct platform_device *pd;
+ int ret = 0;
+
+ struct resource usb_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ /* Only Octeon2 has ehci/ohci */
+ if (!OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return 0;
+
+ if (octeon_is_simulation() || usb_disabled())
+ return 0; /* No USB in the simulator. */
+
+ pd = platform_device_alloc("octeon-ohci", 0);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ usb_resources[0].start = 0x00016F0000000400ULL;
+ usb_resources[0].end = usb_resources[0].start + 0x100;
+
+ usb_resources[1].start = OCTEON_IRQ_USB0;
+ usb_resources[1].end = OCTEON_IRQ_USB0;
+
+ ret = platform_device_add_resources(pd, usb_resources,
+ ARRAY_SIZE(usb_resources));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+
+ return ret;
+fail:
+ platform_device_put(pd);
+out:
+ return ret;
+}
+device_initcall(octeon_ohci_device_init);
+
+#endif /* CONFIG_USB */
+
+MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Platform driver for Octeon SOC");
diff --git a/arch/mips/cavium-octeon/octeon_boot.h b/arch/mips/cavium-octeon/octeon_boot.h
new file mode 100644
index 00000000..428864b2
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon_boot.h
@@ -0,0 +1,72 @@
+/*
+ * (C) Copyright 2004, 2005 Cavium Networks
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __OCTEON_BOOT_H__
+#define __OCTEON_BOOT_H__
+
+#include <linux/types.h>
+
+struct boot_init_vector {
+ /* First stage address - in ram instead of flash */
+ uint64_t code_addr;
+ /* Setup code for application, NOT application entry point */
+ uint32_t app_start_func_addr;
+ /* k0 is used for global data - needs to be passed to other cores */
+ uint32_t k0_val;
+ /* Address of boot info block structure */
+ uint64_t boot_info_addr;
+ uint32_t flags; /* flags */
+ uint32_t pad;
+};
+
+/* similar to bootloader's linux_app_boot_info but without global data */
+struct linux_app_boot_info {
+ uint32_t labi_signature;
+ uint32_t start_core0_addr;
+ uint32_t avail_coremask;
+ uint32_t pci_console_active;
+ uint32_t icache_prefetch_disable;
+ uint64_t InitTLBStart_addr;
+ uint32_t start_app_addr;
+ uint32_t cur_exception_base;
+ uint32_t no_mark_private_data;
+ uint32_t compact_flash_common_base_addr;
+ uint32_t compact_flash_attribute_base_addr;
+ uint32_t led_display_base_addr;
+};
+
+/* If not to copy a lot of bootloader's structures
+ here is only offset of requested member */
+#define AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK 0x765c
+
+/* hardcoded in bootloader */
+#define LABI_ADDR_IN_BOOTLOADER 0x700
+
+#define LINUX_APP_BOOT_BLOCK_NAME "linux-app-boot"
+
+#define LABI_SIGNATURE 0xAABBCC01
+
+/* from uboot-headers/octeon_mem_map.h */
+#define EXCEPTION_BASE_INCR (4 * 1024)
+ /* Increment size for exception base addresses (4k minimum) */
+#define EXCEPTION_BASE_BASE 0
+#define BOOTLOADER_PRIV_DATA_BASE (EXCEPTION_BASE_BASE + 0x800)
+#define BOOTLOADER_BOOT_VECTOR (BOOTLOADER_PRIV_DATA_BASE)
+
+#endif /* __OCTEON_BOOT_H__ */
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c
new file mode 100644
index 00000000..057f0ae8
--- /dev/null
+++ b/arch/mips/cavium-octeon/serial.c
@@ -0,0 +1,137 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004-2007 Cavium Networks
+ */
+#include <linux/console.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/tty.h>
+#include <linux/irq.h>
+
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+
+#define DEBUG_UART 1
+
+unsigned int octeon_serial_in(struct uart_port *up, int offset)
+{
+ int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
+ if (offset == UART_IIR && (rv & 0xf) == 7) {
+ /* Busy interrupt, read the USR (39) and try again. */
+ cvmx_read_csr((uint64_t)(up->membase + (39 << 3)));
+ rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
+ }
+ return rv;
+}
+
+void octeon_serial_out(struct uart_port *up, int offset, int value)
+{
+ /*
+ * If bits 6 or 7 of the OCTEON UART's LCR are set, it quits
+ * working.
+ */
+ if (offset == UART_LCR)
+ value &= 0x9f;
+ cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value);
+}
+
+/*
+ * Allocated in .bss, so it is all zeroed.
+ */
+#define OCTEON_MAX_UARTS 3
+static struct plat_serial8250_port octeon_uart8250_data[OCTEON_MAX_UARTS + 1];
+static struct platform_device octeon_uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = octeon_uart8250_data,
+ },
+};
+
+static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
+{
+ p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
+ p->type = PORT_OCTEON;
+ p->iotype = UPIO_MEM;
+ p->regshift = 3; /* I/O addresses are every 8 bytes */
+ if (octeon_is_simulation())
+ /* Make simulator output fast*/
+ p->uartclk = 115200 * 16;
+ else
+ p->uartclk = octeon_get_io_clock_rate();
+ p->serial_in = octeon_serial_in;
+ p->serial_out = octeon_serial_out;
+}
+
+static int __init octeon_serial_init(void)
+{
+ int enable_uart0;
+ int enable_uart1;
+ int enable_uart2;
+ struct plat_serial8250_port *p;
+
+#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+ /*
+ * If we are configured to run as the second of two kernels,
+ * disable uart0 and enable uart1. Uart0 is owned by the first
+ * kernel
+ */
+ enable_uart0 = 0;
+ enable_uart1 = 1;
+#else
+ /*
+ * We are configured for the first kernel. We'll enable uart0
+ * if the bootloader told us to use 0, otherwise will enable
+ * uart 1.
+ */
+ enable_uart0 = (octeon_get_boot_uart() == 0);
+ enable_uart1 = (octeon_get_boot_uart() == 1);
+#ifdef CONFIG_KGDB
+ enable_uart1 = 1;
+#endif
+#endif
+
+ /* Right now CN52XX is the only chip with a third uart */
+ enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX);
+
+ p = octeon_uart8250_data;
+ if (enable_uart0) {
+ /* Add a ttyS device for hardware uart 0 */
+ octeon_uart_set_common(p);
+ p->membase = (void *) CVMX_MIO_UARTX_RBR(0);
+ p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1);
+ p->irq = OCTEON_IRQ_UART0;
+ p++;
+ }
+
+ if (enable_uart1) {
+ /* Add a ttyS device for hardware uart 1 */
+ octeon_uart_set_common(p);
+ p->membase = (void *) CVMX_MIO_UARTX_RBR(1);
+ p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1);
+ p->irq = OCTEON_IRQ_UART1;
+ p++;
+ }
+ if (enable_uart2) {
+ /* Add a ttyS device for hardware uart 2 */
+ octeon_uart_set_common(p);
+ p->membase = (void *) CVMX_MIO_UART2_RBR;
+ p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1);
+ p->irq = OCTEON_IRQ_UART2;
+ p++;
+ }
+
+ BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]);
+
+ return platform_device_register(&octeon_uart8250_device);
+}
+
+device_initcall(octeon_serial_init);
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
new file mode 100644
index 00000000..2d9028f1
--- /dev/null
+++ b/arch/mips/cavium-octeon/setup.c
@@ -0,0 +1,785 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004-2007 Cavium Networks
+ * Copyright (C) 2008 Wind River Systems
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/serial.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+#include <linux/string.h> /* for memset */
+#include <linux/tty.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/smp-ops.h>
+#include <asm/system.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+#include <asm/sections.h>
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/pci-octeon.h>
+#include <asm/octeon/cvmx-mio-defs.h>
+
+#ifdef CONFIG_CAVIUM_DECODE_RSL
+extern void cvmx_interrupt_rsl_decode(void);
+extern int __cvmx_interrupt_ecc_report_single_bit_errors;
+extern void cvmx_interrupt_rsl_enable(void);
+#endif
+
+extern struct plat_smp_ops octeon_smp_ops;
+
+#ifdef CONFIG_PCI
+extern void pci_console_init(const char *arg);
+#endif
+
+static unsigned long long MAX_MEMORY = 512ull << 20;
+
+struct octeon_boot_descriptor *octeon_boot_desc_ptr;
+
+struct cvmx_bootinfo *octeon_bootinfo;
+EXPORT_SYMBOL(octeon_bootinfo);
+
+#ifdef CONFIG_CAVIUM_RESERVE32
+uint64_t octeon_reserve32_memory;
+EXPORT_SYMBOL(octeon_reserve32_memory);
+#endif
+
+static int octeon_uart;
+
+extern asmlinkage void handle_int(void);
+extern asmlinkage void plat_irq_dispatch(void);
+
+/**
+ * Return non zero if we are currently running in the Octeon simulator
+ *
+ * Returns
+ */
+int octeon_is_simulation(void)
+{
+ return octeon_bootinfo->board_type == CVMX_BOARD_TYPE_SIM;
+}
+EXPORT_SYMBOL(octeon_is_simulation);
+
+/**
+ * Return true if Octeon is in PCI Host mode. This means
+ * Linux can control the PCI bus.
+ *
+ * Returns Non zero if Octeon in host mode.
+ */
+int octeon_is_pci_host(void)
+{
+#ifdef CONFIG_PCI
+ return octeon_bootinfo->config_flags & CVMX_BOOTINFO_CFG_FLAG_PCI_HOST;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Get the clock rate of Octeon
+ *
+ * Returns Clock rate in HZ
+ */
+uint64_t octeon_get_clock_rate(void)
+{
+ struct cvmx_sysinfo *sysinfo = cvmx_sysinfo_get();
+
+ return sysinfo->cpu_clock_hz;
+}
+EXPORT_SYMBOL(octeon_get_clock_rate);
+
+static u64 octeon_io_clock_rate;
+
+u64 octeon_get_io_clock_rate(void)
+{
+ return octeon_io_clock_rate;
+}
+EXPORT_SYMBOL(octeon_get_io_clock_rate);
+
+
+/**
+ * Write to the LCD display connected to the bootbus. This display
+ * exists on most Cavium evaluation boards. If it doesn't exist, then
+ * this function doesn't do anything.
+ *
+ * @s: String to write
+ */
+void octeon_write_lcd(const char *s)
+{
+ if (octeon_bootinfo->led_display_base_addr) {
+ void __iomem *lcd_address =
+ ioremap_nocache(octeon_bootinfo->led_display_base_addr,
+ 8);
+ int i;
+ for (i = 0; i < 8; i++, s++) {
+ if (*s)
+ iowrite8(*s, lcd_address + i);
+ else
+ iowrite8(' ', lcd_address + i);
+ }
+ iounmap(lcd_address);
+ }
+}
+
+/**
+ * Return the console uart passed by the bootloader
+ *
+ * Returns uart (0 or 1)
+ */
+int octeon_get_boot_uart(void)
+{
+ int uart;
+#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+ uart = 1;
+#else
+ uart = (octeon_boot_desc_ptr->flags & OCTEON_BL_FLAG_CONSOLE_UART1) ?
+ 1 : 0;
+#endif
+ return uart;
+}
+
+/**
+ * Get the coremask Linux was booted on.
+ *
+ * Returns Core mask
+ */
+int octeon_get_boot_coremask(void)
+{
+ return octeon_boot_desc_ptr->core_mask;
+}
+
+/**
+ * Check the hardware BIST results for a CPU
+ */
+void octeon_check_cpu_bist(void)
+{
+ const int coreid = cvmx_get_core_num();
+ unsigned long long mask;
+ unsigned long long bist_val;
+
+ /* Check BIST results for COP0 registers */
+ mask = 0x1f00000000ull;
+ bist_val = read_octeon_c0_icacheerr();
+ if (bist_val & mask)
+ pr_err("Core%d BIST Failure: CacheErr(icache) = 0x%llx\n",
+ coreid, bist_val);
+
+ bist_val = read_octeon_c0_dcacheerr();
+ if (bist_val & 1)
+ pr_err("Core%d L1 Dcache parity error: "
+ "CacheErr(dcache) = 0x%llx\n",
+ coreid, bist_val);
+
+ mask = 0xfc00000000000000ull;
+ bist_val = read_c0_cvmmemctl();
+ if (bist_val & mask)
+ pr_err("Core%d BIST Failure: COP0_CVM_MEM_CTL = 0x%llx\n",
+ coreid, bist_val);
+
+ write_octeon_c0_dcacheerr(0);
+}
+
+/**
+ * Reboot Octeon
+ *
+ * @command: Command to pass to the bootloader. Currently ignored.
+ */
+static void octeon_restart(char *command)
+{
+ /* Disable all watchdogs before soft reset. They don't get cleared */
+#ifdef CONFIG_SMP
+ int cpu;
+ for_each_online_cpu(cpu)
+ cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
+#else
+ cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+#endif
+
+ mb();
+ while (1)
+ cvmx_write_csr(CVMX_CIU_SOFT_RST, 1);
+}
+
+
+/**
+ * Permanently stop a core.
+ *
+ * @arg: Ignored.
+ */
+static void octeon_kill_core(void *arg)
+{
+ mb();
+ if (octeon_is_simulation()) {
+ /* The simulator needs the watchdog to stop for dead cores */
+ cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+ /* A break instruction causes the simulator stop a core */
+ asm volatile ("sync\nbreak");
+ }
+}
+
+
+/**
+ * Halt the system
+ */
+static void octeon_halt(void)
+{
+ smp_call_function(octeon_kill_core, NULL, 0);
+
+ switch (octeon_bootinfo->board_type) {
+ case CVMX_BOARD_TYPE_NAO38:
+ /* Driving a 1 to GPIO 12 shuts off this board */
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(12), 1);
+ cvmx_write_csr(CVMX_GPIO_TX_SET, 0x1000);
+ break;
+ default:
+ octeon_write_lcd("PowerOff");
+ break;
+ }
+
+ octeon_kill_core(NULL);
+}
+
+/**
+ * Handle all the error condition interrupts that might occur.
+ *
+ */
+#ifdef CONFIG_CAVIUM_DECODE_RSL
+static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id)
+{
+ cvmx_interrupt_rsl_decode();
+ return IRQ_HANDLED;
+}
+#endif
+
+/**
+ * Return a string representing the system type
+ *
+ * Returns
+ */
+const char *octeon_board_type_string(void)
+{
+ static char name[80];
+ sprintf(name, "%s (%s)",
+ cvmx_board_type_to_string(octeon_bootinfo->board_type),
+ octeon_model_get_string(read_c0_prid()));
+ return name;
+}
+
+const char *get_system_type(void)
+ __attribute__ ((alias("octeon_board_type_string")));
+
+void octeon_user_io_init(void)
+{
+ union octeon_cvmemctl cvmmemctl;
+ union cvmx_iob_fau_timeout fau_timeout;
+ union cvmx_pow_nw_tim nm_tim;
+
+ /* Get the current settings for CP0_CVMMEMCTL_REG */
+ cvmmemctl.u64 = read_c0_cvmmemctl();
+ /* R/W If set, marked write-buffer entries time out the same
+ * as as other entries; if clear, marked write-buffer entries
+ * use the maximum timeout. */
+ cvmmemctl.s.dismarkwblongto = 1;
+ /* R/W If set, a merged store does not clear the write-buffer
+ * entry timeout state. */
+ cvmmemctl.s.dismrgclrwbto = 0;
+ /* R/W Two bits that are the MSBs of the resultant CVMSEG LM
+ * word location for an IOBDMA. The other 8 bits come from the
+ * SCRADDR field of the IOBDMA. */
+ cvmmemctl.s.iobdmascrmsb = 0;
+ /* R/W If set, SYNCWS and SYNCS only order marked stores; if
+ * clear, SYNCWS and SYNCS only order unmarked
+ * stores. SYNCWSMARKED has no effect when DISSYNCWS is
+ * set. */
+ cvmmemctl.s.syncwsmarked = 0;
+ /* R/W If set, SYNCWS acts as SYNCW and SYNCS acts as SYNC. */
+ cvmmemctl.s.dissyncws = 0;
+ /* R/W If set, no stall happens on write buffer full. */
+ if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
+ cvmmemctl.s.diswbfst = 1;
+ else
+ cvmmemctl.s.diswbfst = 0;
+ /* R/W If set (and SX set), supervisor-level loads/stores can
+ * use XKPHYS addresses with <48>==0 */
+ cvmmemctl.s.xkmemenas = 0;
+
+ /* R/W If set (and UX set), user-level loads/stores can use
+ * XKPHYS addresses with VA<48>==0 */
+ cvmmemctl.s.xkmemenau = 0;
+
+ /* R/W If set (and SX set), supervisor-level loads/stores can
+ * use XKPHYS addresses with VA<48>==1 */
+ cvmmemctl.s.xkioenas = 0;
+
+ /* R/W If set (and UX set), user-level loads/stores can use
+ * XKPHYS addresses with VA<48>==1 */
+ cvmmemctl.s.xkioenau = 0;
+
+ /* R/W If set, all stores act as SYNCW (NOMERGE must be set
+ * when this is set) RW, reset to 0. */
+ cvmmemctl.s.allsyncw = 0;
+
+ /* R/W If set, no stores merge, and all stores reach the
+ * coherent bus in order. */
+ cvmmemctl.s.nomerge = 0;
+ /* R/W Selects the bit in the counter used for DID time-outs 0
+ * = 231, 1 = 230, 2 = 229, 3 = 214. Actual time-out is
+ * between 1x and 2x this interval. For example, with
+ * DIDTTO=3, expiration interval is between 16K and 32K. */
+ cvmmemctl.s.didtto = 0;
+ /* R/W If set, the (mem) CSR clock never turns off. */
+ cvmmemctl.s.csrckalwys = 0;
+ /* R/W If set, mclk never turns off. */
+ cvmmemctl.s.mclkalwys = 0;
+ /* R/W Selects the bit in the counter used for write buffer
+ * flush time-outs (WBFLT+11) is the bit position in an
+ * internal counter used to determine expiration. The write
+ * buffer expires between 1x and 2x this interval. For
+ * example, with WBFLT = 0, a write buffer expires between 2K
+ * and 4K cycles after the write buffer entry is allocated. */
+ cvmmemctl.s.wbfltime = 0;
+ /* R/W If set, do not put Istream in the L2 cache. */
+ cvmmemctl.s.istrnol2 = 0;
+
+ /*
+ * R/W The write buffer threshold. As per erratum Core-14752
+ * for CN63XX, a sc/scd might fail if the write buffer is
+ * full. Lowering WBTHRESH greatly lowers the chances of the
+ * write buffer ever being full and triggering the erratum.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
+ cvmmemctl.s.wbthresh = 4;
+ else
+ cvmmemctl.s.wbthresh = 10;
+
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * kernel/debug mode. */
+#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
+ cvmmemctl.s.cvmsegenak = 1;
+#else
+ cvmmemctl.s.cvmsegenak = 0;
+#endif
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * supervisor mode. */
+ cvmmemctl.s.cvmsegenas = 0;
+ /* R/W If set, CVMSEG is available for loads/stores in user
+ * mode. */
+ cvmmemctl.s.cvmsegenau = 0;
+ /* R/W Size of local memory in cache blocks, 54 (6912 bytes)
+ * is max legal value. */
+ cvmmemctl.s.lmemsz = CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE;
+
+ write_c0_cvmmemctl(cvmmemctl.u64);
+
+ if (smp_processor_id() == 0)
+ pr_notice("CVMSEG size: %d cache lines (%d bytes)\n",
+ CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
+ CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
+
+ /* Set a default for the hardware timeouts */
+ fau_timeout.u64 = 0;
+ fau_timeout.s.tout_val = 0xfff;
+ /* Disable tagwait FAU timeout */
+ fau_timeout.s.tout_enb = 0;
+ cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64);
+
+ nm_tim.u64 = 0;
+ /* 4096 cycles */
+ nm_tim.s.nw_tim = 3;
+ cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64);
+
+ write_octeon_c0_icacheerr(0);
+ write_c0_derraddr1(0);
+}
+
+/**
+ * Early entry point for arch setup
+ */
+void __init prom_init(void)
+{
+ struct cvmx_sysinfo *sysinfo;
+ int i;
+ int argc;
+#ifdef CONFIG_CAVIUM_RESERVE32
+ int64_t addr = -1;
+#endif
+ /*
+ * The bootloader passes a pointer to the boot descriptor in
+ * $a3, this is available as fw_arg3.
+ */
+ octeon_boot_desc_ptr = (struct octeon_boot_descriptor *)fw_arg3;
+ octeon_bootinfo =
+ cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
+ cvmx_bootmem_init(cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr));
+
+ sysinfo = cvmx_sysinfo_get();
+ memset(sysinfo, 0, sizeof(*sysinfo));
+ sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
+ sysinfo->phy_mem_desc_ptr =
+ cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
+ sysinfo->core_mask = octeon_bootinfo->core_mask;
+ sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
+ sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
+ sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
+ sysinfo->board_type = octeon_bootinfo->board_type;
+ sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
+ sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
+ memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
+ sizeof(sysinfo->mac_addr_base));
+ sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
+ memcpy(sysinfo->board_serial_number,
+ octeon_bootinfo->board_serial_number,
+ sizeof(sysinfo->board_serial_number));
+ sysinfo->compact_flash_common_base_addr =
+ octeon_bootinfo->compact_flash_common_base_addr;
+ sysinfo->compact_flash_attribute_base_addr =
+ octeon_bootinfo->compact_flash_attribute_base_addr;
+ sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
+ sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
+ sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ /* I/O clock runs at a different rate than the CPU. */
+ union cvmx_mio_rst_boot rst_boot;
+ rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+ octeon_io_clock_rate = 50000000 * rst_boot.s.pnr_mul;
+ } else {
+ octeon_io_clock_rate = sysinfo->cpu_clock_hz;
+ }
+
+ /*
+ * Only enable the LED controller if we're running on a CN38XX, CN58XX,
+ * or CN56XX. The CN30XX and CN31XX don't have an LED controller.
+ */
+ if (!octeon_is_simulation() &&
+ octeon_has_feature(OCTEON_FEATURE_LED_CONTROLLER)) {
+ cvmx_write_csr(CVMX_LED_EN, 0);
+ cvmx_write_csr(CVMX_LED_PRT, 0);
+ cvmx_write_csr(CVMX_LED_DBG, 0);
+ cvmx_write_csr(CVMX_LED_PRT_FMT, 0);
+ cvmx_write_csr(CVMX_LED_UDD_CNTX(0), 32);
+ cvmx_write_csr(CVMX_LED_UDD_CNTX(1), 32);
+ cvmx_write_csr(CVMX_LED_UDD_DATX(0), 0);
+ cvmx_write_csr(CVMX_LED_UDD_DATX(1), 0);
+ cvmx_write_csr(CVMX_LED_EN, 1);
+ }
+#ifdef CONFIG_CAVIUM_RESERVE32
+ /*
+ * We need to temporarily allocate all memory in the reserve32
+ * region. This makes sure the kernel doesn't allocate this
+ * memory when it is getting memory from the
+ * bootloader. Later, after the memory allocations are
+ * complete, the reserve32 will be freed.
+ *
+ * Allocate memory for RESERVED32 aligned on 2MB boundary. This
+ * is in case we later use hugetlb entries with it.
+ */
+ addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
+ 0, 0, 2 << 20,
+ "CAVIUM_RESERVE32", 0);
+ if (addr < 0)
+ pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
+ else
+ octeon_reserve32_memory = addr;
+#endif
+
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2
+ if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) {
+ pr_info("Skipping L2 locking due to reduced L2 cache size\n");
+ } else {
+ uint32_t ebase = read_c0_ebase() & 0x3ffff000;
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB
+ /* TLB refill */
+ cvmx_l2c_lock_mem_region(ebase, 0x100);
+#endif
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION
+ /* General exception */
+ cvmx_l2c_lock_mem_region(ebase + 0x180, 0x80);
+#endif
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT
+ /* Interrupt handler */
+ cvmx_l2c_lock_mem_region(ebase + 0x200, 0x80);
+#endif
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT
+ cvmx_l2c_lock_mem_region(__pa_symbol(handle_int), 0x100);
+ cvmx_l2c_lock_mem_region(__pa_symbol(plat_irq_dispatch), 0x80);
+#endif
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY
+ cvmx_l2c_lock_mem_region(__pa_symbol(memcpy), 0x480);
+#endif
+ }
+#endif
+
+ octeon_check_cpu_bist();
+
+ octeon_uart = octeon_get_boot_uart();
+
+#ifdef CONFIG_SMP
+ octeon_write_lcd("LinuxSMP");
+#else
+ octeon_write_lcd("Linux");
+#endif
+
+#ifdef CONFIG_CAVIUM_GDB
+ /*
+ * When debugging the linux kernel, force the cores to enter
+ * the debug exception handler to break in.
+ */
+ if (octeon_get_boot_debug_flag()) {
+ cvmx_write_csr(CVMX_CIU_DINT, 1 << cvmx_get_core_num());
+ cvmx_read_csr(CVMX_CIU_DINT);
+ }
+#endif
+
+ /*
+ * BIST should always be enabled when doing a soft reset. L2
+ * Cache locking for instance is not cleared unless BIST is
+ * enabled. Unfortunately due to a chip errata G-200 for
+ * Cn38XX and CN31XX, BIST msut be disabled on these parts.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) ||
+ OCTEON_IS_MODEL(OCTEON_CN31XX))
+ cvmx_write_csr(CVMX_CIU_SOFT_BIST, 0);
+ else
+ cvmx_write_csr(CVMX_CIU_SOFT_BIST, 1);
+
+ /* Default to 64MB in the simulator to speed things up */
+ if (octeon_is_simulation())
+ MAX_MEMORY = 64ull << 20;
+
+ arcs_cmdline[0] = 0;
+ argc = octeon_boot_desc_ptr->argc;
+ for (i = 0; i < argc; i++) {
+ const char *arg =
+ cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]);
+ if ((strncmp(arg, "MEM=", 4) == 0) ||
+ (strncmp(arg, "mem=", 4) == 0)) {
+ sscanf(arg + 4, "%llu", &MAX_MEMORY);
+ MAX_MEMORY <<= 20;
+ if (MAX_MEMORY == 0)
+ MAX_MEMORY = 32ull << 30;
+ } else if (strcmp(arg, "ecc_verbose") == 0) {
+#ifdef CONFIG_CAVIUM_REPORT_SINGLE_BIT_ECC
+ __cvmx_interrupt_ecc_report_single_bit_errors = 1;
+ pr_notice("Reporting of single bit ECC errors is "
+ "turned on\n");
+#endif
+ } else if (strlen(arcs_cmdline) + strlen(arg) + 1 <
+ sizeof(arcs_cmdline) - 1) {
+ strcat(arcs_cmdline, " ");
+ strcat(arcs_cmdline, arg);
+ }
+ }
+
+ if (strstr(arcs_cmdline, "console=") == NULL) {
+#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+ strcat(arcs_cmdline, " console=ttyS0,115200");
+#else
+ if (octeon_uart == 1)
+ strcat(arcs_cmdline, " console=ttyS1,115200");
+ else
+ strcat(arcs_cmdline, " console=ttyS0,115200");
+#endif
+ }
+
+ if (octeon_is_simulation()) {
+ /*
+ * The simulator uses a mtdram device pre filled with
+ * the filesystem. Also specify the calibration delay
+ * to avoid calculating it every time.
+ */
+ strcat(arcs_cmdline, " rw root=1f00 slram=root,0x40000000,+1073741824");
+ }
+
+ mips_hpt_frequency = octeon_get_clock_rate();
+
+ octeon_init_cvmcount();
+ octeon_setup_delays();
+
+ _machine_restart = octeon_restart;
+ _machine_halt = octeon_halt;
+
+ octeon_user_io_init();
+ register_smp_ops(&octeon_smp_ops);
+}
+
+/* Exclude a single page from the regions obtained in plat_mem_setup. */
+static __init void memory_exclude_page(u64 addr, u64 *mem, u64 *size)
+{
+ if (addr > *mem && addr < *mem + *size) {
+ u64 inc = addr - *mem;
+ add_memory_region(*mem, inc, BOOT_MEM_RAM);
+ *mem += inc;
+ *size -= inc;
+ }
+
+ if (addr == *mem && *size > PAGE_SIZE) {
+ *mem += PAGE_SIZE;
+ *size -= PAGE_SIZE;
+ }
+}
+
+void __init plat_mem_setup(void)
+{
+ uint64_t mem_alloc_size;
+ uint64_t total;
+ int64_t memory;
+
+ total = 0;
+
+ /* First add the init memory we will be returning. */
+ memory = __pa_symbol(&__init_begin) & PAGE_MASK;
+ mem_alloc_size = (__pa_symbol(&__init_end) & PAGE_MASK) - memory;
+ if (mem_alloc_size > 0) {
+ add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
+ total += mem_alloc_size;
+ }
+
+ /*
+ * The Mips memory init uses the first memory location for
+ * some memory vectors. When SPARSEMEM is in use, it doesn't
+ * verify that the size is big enough for the final
+ * vectors. Making the smallest chuck 4MB seems to be enough
+ * to consistently work.
+ */
+ mem_alloc_size = 4 << 20;
+ if (mem_alloc_size > MAX_MEMORY)
+ mem_alloc_size = MAX_MEMORY;
+
+ /*
+ * When allocating memory, we want incrementing addresses from
+ * bootmem_alloc so the code in add_memory_region can merge
+ * regions next to each other.
+ */
+ cvmx_bootmem_lock();
+ while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX)
+ && (total < MAX_MEMORY)) {
+#if defined(CONFIG_64BIT) || defined(CONFIG_64BIT_PHYS_ADDR)
+ memory = cvmx_bootmem_phy_alloc(mem_alloc_size,
+ __pa_symbol(&__init_end), -1,
+ 0x100000,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+#elif defined(CONFIG_HIGHMEM)
+ memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 1ull << 31,
+ 0x100000,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+#else
+ memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 512 << 20,
+ 0x100000,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+#endif
+ if (memory >= 0) {
+ u64 size = mem_alloc_size;
+
+ /*
+ * exclude a page at the beginning and end of
+ * the 256MB PCIe 'hole' so the kernel will not
+ * try to allocate multi-page buffers that
+ * span the discontinuity.
+ */
+ memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE,
+ &memory, &size);
+ memory_exclude_page(CVMX_PCIE_BAR1_PHYS_BASE +
+ CVMX_PCIE_BAR1_PHYS_SIZE,
+ &memory, &size);
+
+ /*
+ * This function automatically merges address
+ * regions next to each other if they are
+ * received in incrementing order.
+ */
+ if (size)
+ add_memory_region(memory, size, BOOT_MEM_RAM);
+ total += mem_alloc_size;
+ } else {
+ break;
+ }
+ }
+ cvmx_bootmem_unlock();
+
+#ifdef CONFIG_CAVIUM_RESERVE32
+ /*
+ * Now that we've allocated the kernel memory it is safe to
+ * free the reserved region. We free it here so that builtin
+ * drivers can use the memory.
+ */
+ if (octeon_reserve32_memory)
+ cvmx_bootmem_free_named("CAVIUM_RESERVE32");
+#endif /* CONFIG_CAVIUM_RESERVE32 */
+
+ if (total == 0)
+ panic("Unable to allocate memory from "
+ "cvmx_bootmem_phy_alloc\n");
+}
+
+/*
+ * Emit one character to the boot UART. Exported for use by the
+ * watchdog timer.
+ */
+int prom_putchar(char c)
+{
+ uint64_t lsrval;
+
+ /* Spin until there is room */
+ do {
+ lsrval = cvmx_read_csr(CVMX_MIO_UARTX_LSR(octeon_uart));
+ } while ((lsrval & 0x20) == 0);
+
+ /* Write the byte */
+ cvmx_write_csr(CVMX_MIO_UARTX_THR(octeon_uart), c & 0xffull);
+ return 1;
+}
+EXPORT_SYMBOL(prom_putchar);
+
+void prom_free_prom_memory(void)
+{
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X)) {
+ /* Check for presence of Core-14449 fix. */
+ u32 insn;
+ u32 *foo;
+
+ foo = &insn;
+
+ asm volatile("# before" : : : "memory");
+ prefetch(foo);
+ asm volatile(
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ "bal 1f\n\t"
+ "nop\n"
+ "1:\tlw %0,-12($31)\n\t"
+ ".set pop\n\t"
+ : "=r" (insn) : : "$31", "memory");
+
+ if ((insn >> 26) != 0x33)
+ panic("No PREF instruction at Core-14449 probe point.\n");
+
+ if (((insn >> 16) & 0x1f) != 28)
+ panic("Core-14449 WAR not in place (%04x).\n"
+ "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).\n", insn);
+ }
+#ifdef CONFIG_CAVIUM_DECODE_RSL
+ cvmx_interrupt_rsl_enable();
+
+ /* Add an interrupt handler for general failures. */
+ if (request_irq(OCTEON_IRQ_RML, octeon_rlm_interrupt, IRQF_SHARED,
+ "RML/RSL", octeon_rlm_interrupt)) {
+ panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
+ }
+#endif
+}
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
new file mode 100644
index 00000000..8b606423
--- /dev/null
+++ b/arch/mips/cavium-octeon/smp.c
@@ -0,0 +1,424 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004-2008, 2009, 2010 Cavium Networks
+ */
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "octeon_boot.h"
+
+volatile unsigned long octeon_processor_boot = 0xff;
+volatile unsigned long octeon_processor_sp;
+volatile unsigned long octeon_processor_gp;
+
+#ifdef CONFIG_HOTPLUG_CPU
+uint64_t octeon_bootloader_entry_addr;
+EXPORT_SYMBOL(octeon_bootloader_entry_addr);
+#endif
+
+static irqreturn_t mailbox_interrupt(int irq, void *dev_id)
+{
+ const int coreid = cvmx_get_core_num();
+ uint64_t action;
+
+ /* Load the mailbox register to figure out what we're supposed to do */
+ action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)) & 0xffff;
+
+ /* Clear the mailbox to clear the interrupt */
+ cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action);
+
+ if (action & SMP_CALL_FUNCTION)
+ smp_call_function_interrupt();
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
+
+ /* Check if we've been told to flush the icache */
+ if (action & SMP_ICACHE_FLUSH)
+ asm volatile ("synci 0($0)\n");
+ return IRQ_HANDLED;
+}
+
+/**
+ * Cause the function described by call_data to be executed on the passed
+ * cpu. When the function has finished, increment the finished field of
+ * call_data.
+ */
+void octeon_send_ipi_single(int cpu, unsigned int action)
+{
+ int coreid = cpu_logical_map(cpu);
+ /*
+ pr_info("SMP: Mailbox send cpu=%d, coreid=%d, action=%u\n", cpu,
+ coreid, action);
+ */
+ cvmx_write_csr(CVMX_CIU_MBOX_SETX(coreid), action);
+}
+
+static inline void octeon_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu_mask(i, *mask)
+ octeon_send_ipi_single(i, action);
+}
+
+/**
+ * Detect available CPUs, populate cpu_possible_map
+ */
+static void octeon_smp_hotplug_setup(void)
+{
+#ifdef CONFIG_HOTPLUG_CPU
+ struct linux_app_boot_info *labi;
+
+ labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
+ if (labi->labi_signature != LABI_SIGNATURE)
+ panic("The bootloader version on this board is incorrect.");
+
+ octeon_bootloader_entry_addr = labi->InitTLBStart_addr;
+#endif
+}
+
+static void octeon_smp_setup(void)
+{
+ const int coreid = cvmx_get_core_num();
+ int cpus;
+ int id;
+ int core_mask = octeon_get_boot_coremask();
+#ifdef CONFIG_HOTPLUG_CPU
+ unsigned int num_cores = cvmx_octeon_num_cores();
+#endif
+
+ /* The present CPUs are initially just the boot cpu (CPU 0). */
+ for (id = 0; id < NR_CPUS; id++) {
+ set_cpu_possible(id, id == 0);
+ set_cpu_present(id, id == 0);
+ }
+
+ __cpu_number_map[coreid] = 0;
+ __cpu_logical_map[0] = coreid;
+
+ /* The present CPUs get the lowest CPU numbers. */
+ cpus = 1;
+ for (id = 0; id < NR_CPUS; id++) {
+ if ((id != coreid) && (core_mask & (1 << id))) {
+ set_cpu_possible(cpus, true);
+ set_cpu_present(cpus, true);
+ __cpu_number_map[id] = cpus;
+ __cpu_logical_map[cpus] = id;
+ cpus++;
+ }
+ }
+
+#ifdef CONFIG_HOTPLUG_CPU
+ /*
+ * The possible CPUs are all those present on the chip. We
+ * will assign CPU numbers for possible cores as well. Cores
+ * are always consecutively numberd from 0.
+ */
+ for (id = 0; id < num_cores && id < NR_CPUS; id++) {
+ if (!(core_mask & (1 << id))) {
+ set_cpu_possible(cpus, true);
+ __cpu_number_map[id] = cpus;
+ __cpu_logical_map[cpus] = id;
+ cpus++;
+ }
+ }
+#endif
+
+ octeon_smp_hotplug_setup();
+}
+
+/**
+ * Firmware CPU startup hook
+ *
+ */
+static void octeon_boot_secondary(int cpu, struct task_struct *idle)
+{
+ int count;
+
+ pr_info("SMP: Booting CPU%02d (CoreId %2d)...\n", cpu,
+ cpu_logical_map(cpu));
+
+ octeon_processor_sp = __KSTK_TOS(idle);
+ octeon_processor_gp = (unsigned long)(task_thread_info(idle));
+ octeon_processor_boot = cpu_logical_map(cpu);
+ mb();
+
+ count = 10000;
+ while (octeon_processor_sp && count) {
+ /* Waiting for processor to get the SP and GP */
+ udelay(1);
+ count--;
+ }
+ if (count == 0)
+ pr_err("Secondary boot timeout\n");
+}
+
+/**
+ * After we've done initial boot, this function is called to allow the
+ * board code to clean up state, if needed
+ */
+static void __cpuinit octeon_init_secondary(void)
+{
+ unsigned int sr;
+
+ sr = set_c0_status(ST0_BEV);
+ write_c0_ebase((u32)ebase);
+ write_c0_status(sr);
+
+ octeon_check_cpu_bist();
+ octeon_init_cvmcount();
+
+ octeon_irq_setup_secondary();
+ raw_local_irq_enable();
+}
+
+/**
+ * Callout to firmware before smp_init
+ *
+ */
+void octeon_prepare_cpus(unsigned int max_cpus)
+{
+#ifdef CONFIG_HOTPLUG_CPU
+ struct linux_app_boot_info *labi;
+
+ labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
+
+ if (labi->labi_signature != LABI_SIGNATURE)
+ panic("The bootloader version on this board is incorrect.");
+#endif
+ /*
+ * Only the low order mailbox bits are used for IPIs, leave
+ * the other bits alone.
+ */
+ cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff);
+ if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
+ "SMP-IPI", mailbox_interrupt)) {
+ panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
+ }
+}
+
+/**
+ * Last chance for the board code to finish SMP initialization before
+ * the CPU is "online".
+ */
+static void octeon_smp_finish(void)
+{
+#ifdef CONFIG_CAVIUM_GDB
+ unsigned long tmp;
+ /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
+ to be not masked by this core so we know the signal is received by
+ someone */
+ asm volatile ("dmfc0 %0, $22\n"
+ "ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
+#endif
+
+ octeon_user_io_init();
+
+ /* to generate the first CPU timer interrupt */
+ write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
+}
+
+/**
+ * Hook for after all CPUs are online
+ */
+static void octeon_cpus_done(void)
+{
+#ifdef CONFIG_CAVIUM_GDB
+ unsigned long tmp;
+ /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
+ to be not masked by this core so we know the signal is received by
+ someone */
+ asm volatile ("dmfc0 %0, $22\n"
+ "ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
+#endif
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/* State of each CPU. */
+DEFINE_PER_CPU(int, cpu_state);
+
+extern void fixup_irqs(void);
+
+static DEFINE_SPINLOCK(smp_reserve_lock);
+
+static int octeon_cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ if (cpu == 0)
+ return -EBUSY;
+
+ spin_lock(&smp_reserve_lock);
+
+ cpu_clear(cpu, cpu_online_map);
+ cpu_clear(cpu, cpu_callin_map);
+ local_irq_disable();
+ fixup_irqs();
+ local_irq_enable();
+
+ flush_cache_all();
+ local_flush_tlb_all();
+
+ spin_unlock(&smp_reserve_lock);
+
+ return 0;
+}
+
+static void octeon_cpu_die(unsigned int cpu)
+{
+ int coreid = cpu_logical_map(cpu);
+ uint32_t mask, new_mask;
+ const struct cvmx_bootmem_named_block_desc *block_desc;
+
+ while (per_cpu(cpu_state, cpu) != CPU_DEAD)
+ cpu_relax();
+
+ /*
+ * This is a bit complicated strategics of getting/settig available
+ * cores mask, copied from bootloader
+ */
+
+ mask = 1 << coreid;
+ /* LINUX_APP_BOOT_BLOCK is initialized in bootoct binary */
+ block_desc = cvmx_bootmem_find_named_block(LINUX_APP_BOOT_BLOCK_NAME);
+
+ if (!block_desc) {
+ struct linux_app_boot_info *labi;
+
+ labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
+
+ labi->avail_coremask |= mask;
+ new_mask = labi->avail_coremask;
+ } else { /* alternative, already initialized */
+ uint32_t *p = (uint32_t *)PHYS_TO_XKSEG_CACHED(block_desc->base_addr +
+ AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK);
+ *p |= mask;
+ new_mask = *p;
+ }
+
+ pr_info("Reset core %d. Available Coremask = 0x%x \n", coreid, new_mask);
+ mb();
+ cvmx_write_csr(CVMX_CIU_PP_RST, 1 << coreid);
+ cvmx_write_csr(CVMX_CIU_PP_RST, 0);
+}
+
+void play_dead(void)
+{
+ int cpu = cpu_number_map(cvmx_get_core_num());
+
+ idle_task_exit();
+ octeon_processor_boot = 0xff;
+ per_cpu(cpu_state, cpu) = CPU_DEAD;
+
+ mb();
+
+ while (1) /* core will be reset here */
+ ;
+}
+
+extern void kernel_entry(unsigned long arg1, ...);
+
+static void start_after_reset(void)
+{
+ kernel_entry(0, 0, 0); /* set a2 = 0 for secondary core */
+}
+
+static int octeon_update_boot_vector(unsigned int cpu)
+{
+
+ int coreid = cpu_logical_map(cpu);
+ uint32_t avail_coremask;
+ const struct cvmx_bootmem_named_block_desc *block_desc;
+ struct boot_init_vector *boot_vect =
+ (struct boot_init_vector *)PHYS_TO_XKSEG_CACHED(BOOTLOADER_BOOT_VECTOR);
+
+ block_desc = cvmx_bootmem_find_named_block(LINUX_APP_BOOT_BLOCK_NAME);
+
+ if (!block_desc) {
+ struct linux_app_boot_info *labi;
+
+ labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
+
+ avail_coremask = labi->avail_coremask;
+ labi->avail_coremask &= ~(1 << coreid);
+ } else { /* alternative, already initialized */
+ avail_coremask = *(uint32_t *)PHYS_TO_XKSEG_CACHED(
+ block_desc->base_addr + AVAIL_COREMASK_OFFSET_IN_LINUX_APP_BOOT_BLOCK);
+ }
+
+ if (!(avail_coremask & (1 << coreid))) {
+ /* core not available, assume, that catched by simple-executive */
+ cvmx_write_csr(CVMX_CIU_PP_RST, 1 << coreid);
+ cvmx_write_csr(CVMX_CIU_PP_RST, 0);
+ }
+
+ boot_vect[coreid].app_start_func_addr =
+ (uint32_t) (unsigned long) start_after_reset;
+ boot_vect[coreid].code_addr = octeon_bootloader_entry_addr;
+
+ mb();
+
+ cvmx_write_csr(CVMX_CIU_NMI, (1 << coreid) & avail_coremask);
+
+ return 0;
+}
+
+static int __cpuinit octeon_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_UP_PREPARE:
+ octeon_update_boot_vector(cpu);
+ break;
+ case CPU_ONLINE:
+ pr_info("Cpu %d online\n", cpu);
+ break;
+ case CPU_DEAD:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static int __cpuinit register_cavium_notifier(void)
+{
+ hotcpu_notifier(octeon_cpu_callback, 0);
+ return 0;
+}
+late_initcall(register_cavium_notifier);
+
+#endif /* CONFIG_HOTPLUG_CPU */
+
+struct plat_smp_ops octeon_smp_ops = {
+ .send_ipi_single = octeon_send_ipi_single,
+ .send_ipi_mask = octeon_send_ipi_mask,
+ .init_secondary = octeon_init_secondary,
+ .smp_finish = octeon_smp_finish,
+ .cpus_done = octeon_cpus_done,
+ .boot_secondary = octeon_boot_secondary,
+ .smp_setup = octeon_smp_setup,
+ .prepare_cpus = octeon_prepare_cpus,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = octeon_cpu_disable,
+ .cpu_die = octeon_cpu_die,
+#endif
+};
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
new file mode 100644
index 00000000..61a334ac
--- /dev/null
+++ b/arch/mips/cobalt/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the Cobalt micro systems family specific parts of the kernel
+#
+
+obj-y := buttons.o irq.o lcd.o led.o reset.o rtc.o serial.o setup.o time.o
+
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_EARLY_PRINTK) += console.o
+obj-$(CONFIG_MTD_PHYSMAP) += mtd.o
diff --git a/arch/mips/cobalt/Platform b/arch/mips/cobalt/Platform
new file mode 100644
index 00000000..34123efd
--- /dev/null
+++ b/arch/mips/cobalt/Platform
@@ -0,0 +1,6 @@
+#
+# Cobalt Server
+#
+platform-$(CONFIG_MIPS_COBALT) += cobalt/
+cflags-$(CONFIG_MIPS_COBALT) += -I$(srctree)/arch/mips/include/asm/mach-cobalt
+load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000
diff --git a/arch/mips/cobalt/buttons.c b/arch/mips/cobalt/buttons.c
new file mode 100644
index 00000000..4eaec8b4
--- /dev/null
+++ b/arch/mips/cobalt/buttons.c
@@ -0,0 +1,54 @@
+/*
+ * Cobalt buttons platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+static struct resource cobalt_buttons_resource __initdata = {
+ .start = 0x1d000000,
+ .end = 0x1d000003,
+ .flags = IORESOURCE_MEM,
+};
+
+static __init int cobalt_add_buttons(void)
+{
+ struct platform_device *pd;
+ int error;
+
+ pd = platform_device_alloc("Cobalt buttons", -1);
+ if (!pd)
+ return -ENOMEM;
+
+ error = platform_device_add_resources(pd, &cobalt_buttons_resource, 1);
+ if (error)
+ goto err_free_device;
+
+ error = platform_device_add(pd);
+ if (error)
+ goto err_free_device;
+
+ return 0;
+
+ err_free_device:
+ platform_device_put(pd);
+ return error;
+}
+device_initcall(cobalt_add_buttons);
diff --git a/arch/mips/cobalt/console.c b/arch/mips/cobalt/console.c
new file mode 100644
index 00000000..d1ba701c
--- /dev/null
+++ b/arch/mips/cobalt/console.c
@@ -0,0 +1,20 @@
+/*
+ * (C) P. Horton 2006
+ */
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+
+#include <cobalt.h>
+
+#define UART_BASE ((void __iomem *)CKSEG1ADDR(0x1c800000))
+
+void prom_putchar(char c)
+{
+ if (cobalt_board_id <= COBALT_BRD_ID_QUBE1)
+ return;
+
+ while (!(readb(UART_BASE + UART_LSR) & UART_LSR_THRE))
+ ;
+
+ writeb(c, UART_BASE + UART_TX);
+}
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
new file mode 100644
index 00000000..cb9bf820
--- /dev/null
+++ b/arch/mips/cobalt/irq.c
@@ -0,0 +1,61 @@
+/*
+ * IRQ vector handles
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+
+#include <asm/i8259.h>
+#include <asm/irq_cpu.h>
+#include <asm/irq_gt641xx.h>
+#include <asm/gt64120.h>
+
+#include <irq.h>
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned pending = read_c0_status() & read_c0_cause() & ST0_IM;
+ int irq;
+
+ if (pending & CAUSEF_IP2)
+ gt641xx_irq_dispatch();
+ else if (pending & CAUSEF_IP6) {
+ irq = i8259_irq();
+ if (irq < 0)
+ spurious_interrupt();
+ else
+ do_IRQ(irq);
+ } else if (pending & CAUSEF_IP3)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 3);
+ else if (pending & CAUSEF_IP4)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 4);
+ else if (pending & CAUSEF_IP5)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 5);
+ else if (pending & CAUSEF_IP7)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+ else
+ spurious_interrupt();
+}
+
+static struct irqaction cascade = {
+ .handler = no_action,
+ .name = "cascade",
+};
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+ gt641xx_irq_init();
+ init_i8259_irqs();
+
+ setup_irq(GT641XX_CASCADE_IRQ, &cascade);
+ setup_irq(I8259_CASCADE_IRQ, &cascade);
+}
diff --git a/arch/mips/cobalt/lcd.c b/arch/mips/cobalt/lcd.c
new file mode 100644
index 00000000..0f1cd90f
--- /dev/null
+++ b/arch/mips/cobalt/lcd.c
@@ -0,0 +1,55 @@
+/*
+ * Registration of Cobalt LCD platform device.
+ *
+ * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+static struct resource cobalt_lcd_resource __initdata = {
+ .start = 0x1f000000,
+ .end = 0x1f00001f,
+ .flags = IORESOURCE_MEM,
+};
+
+static __init int cobalt_lcd_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ pdev = platform_device_alloc("cobalt-lcd", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ retval = platform_device_add_resources(pdev, &cobalt_lcd_resource, 1);
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(cobalt_lcd_add);
diff --git a/arch/mips/cobalt/led.c b/arch/mips/cobalt/led.c
new file mode 100644
index 00000000..d3ce6fa1
--- /dev/null
+++ b/arch/mips/cobalt/led.c
@@ -0,0 +1,62 @@
+/*
+ * Registration of Cobalt LED platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <cobalt.h>
+
+static struct resource cobalt_led_resource __initdata = {
+ .start = 0x1c000000,
+ .end = 0x1c000000,
+ .flags = IORESOURCE_MEM,
+};
+
+static __init int cobalt_led_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ if (cobalt_board_id == COBALT_BRD_ID_QUBE1 ||
+ cobalt_board_id == COBALT_BRD_ID_QUBE2)
+ pdev = platform_device_alloc("cobalt-qube-leds", -1);
+ else
+ pdev = platform_device_alloc("cobalt-raq-leds", -1);
+
+ if (!pdev)
+ return -ENOMEM;
+
+ retval = platform_device_add_resources(pdev, &cobalt_led_resource, 1);
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(cobalt_led_add);
diff --git a/arch/mips/cobalt/mtd.c b/arch/mips/cobalt/mtd.c
new file mode 100644
index 00000000..691d620b
--- /dev/null
+++ b/arch/mips/cobalt/mtd.c
@@ -0,0 +1,61 @@
+/*
+ * Registration of Cobalt MTD device.
+ *
+ * Copyright (C) 2006 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+static struct mtd_partition cobalt_mtd_partitions[] = {
+ {
+ .name = "firmware",
+ .offset = 0x0,
+ .size = 0x80000,
+ },
+};
+
+static struct physmap_flash_data cobalt_flash_data = {
+ .width = 1,
+ .nr_parts = 1,
+ .parts = cobalt_mtd_partitions,
+};
+
+static struct resource cobalt_mtd_resource = {
+ .start = 0x1fc00000,
+ .end = 0x1fc7ffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device cobalt_mtd = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &cobalt_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &cobalt_mtd_resource,
+};
+
+static int __init cobalt_mtd_init(void)
+{
+ platform_device_register(&cobalt_mtd);
+
+ return 0;
+}
+
+module_init(cobalt_mtd_init);
diff --git a/arch/mips/cobalt/pci.c b/arch/mips/cobalt/pci.c
new file mode 100644
index 00000000..85ec9cc3
--- /dev/null
+++ b/arch/mips/cobalt/pci.c
@@ -0,0 +1,48 @@
+/*
+ * Register PCI controller.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 2004, 05 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/gt64120.h>
+
+extern struct pci_ops gt64xxx_pci0_ops;
+
+static struct resource cobalt_mem_resource = {
+ .start = GT_DEF_PCI0_MEM0_BASE,
+ .end = GT_DEF_PCI0_MEM0_BASE + GT_DEF_PCI0_MEM0_SIZE - 1,
+ .name = "PCI memory",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource cobalt_io_resource = {
+ .start = 0x1000,
+ .end = 0xffffffUL,
+ .name = "PCI I/O",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller cobalt_pci_controller = {
+ .pci_ops = &gt64xxx_pci0_ops,
+ .mem_resource = &cobalt_mem_resource,
+ .io_resource = &cobalt_io_resource,
+ .io_offset = 0 - GT_DEF_PCI0_IO_BASE,
+ .io_map_base = CKSEG1ADDR(GT_DEF_PCI0_IO_BASE),
+};
+
+static int __init cobalt_pci_init(void)
+{
+ register_pci_controller(&cobalt_pci_controller);
+
+ return 0;
+}
+
+arch_initcall(cobalt_pci_init);
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
new file mode 100644
index 00000000..516b4428
--- /dev/null
+++ b/arch/mips/cobalt/reset.c
@@ -0,0 +1,51 @@
+/*
+ * Cobalt Reset operations
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997 by Ralf Baechle
+ * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+
+#include <asm/processor.h>
+
+#include <cobalt.h>
+
+#define RESET_PORT ((void __iomem *)CKSEG1ADDR(0x1c000000))
+#define RESET 0x0f
+
+DEFINE_LED_TRIGGER(power_off_led_trigger);
+
+static int __init ledtrig_power_off_init(void)
+{
+ led_trigger_register_simple("power-off", &power_off_led_trigger);
+ return 0;
+}
+device_initcall(ledtrig_power_off_init);
+
+void cobalt_machine_halt(void)
+{
+ /*
+ * turn on power off LED on RaQ
+ */
+ led_trigger_event(power_off_led_trigger, LED_FULL);
+
+ local_irq_disable();
+ while (1) {
+ if (cpu_wait)
+ cpu_wait();
+ }
+}
+
+void cobalt_machine_restart(char *command)
+{
+ writeb(RESET, RESET_PORT);
+
+ /* we should never get here */
+ cobalt_machine_halt();
+}
diff --git a/arch/mips/cobalt/rtc.c b/arch/mips/cobalt/rtc.c
new file mode 100644
index 00000000..3ab39898
--- /dev/null
+++ b/arch/mips/cobalt/rtc.c
@@ -0,0 +1,64 @@
+/*
+ * Registration of Cobalt RTC platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/platform_device.h>
+
+static struct resource cobalt_rtc_resource[] __initdata = {
+ {
+ .start = 0x70,
+ .end = 0x77,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .start = RTC_IRQ,
+ .end = RTC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static __init int cobalt_rtc_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ pdev = platform_device_alloc("rtc_cmos", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ retval = platform_device_add_resources(pdev, cobalt_rtc_resource,
+ ARRAY_SIZE(cobalt_rtc_resource));
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(cobalt_rtc_add);
diff --git a/arch/mips/cobalt/serial.c b/arch/mips/cobalt/serial.c
new file mode 100644
index 00000000..7cb51f57
--- /dev/null
+++ b/arch/mips/cobalt/serial.c
@@ -0,0 +1,86 @@
+/*
+ * Registration of Cobalt UART platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <cobalt.h>
+#include <irq.h>
+
+static struct resource cobalt_uart_resource[] __initdata = {
+ {
+ .start = 0x1c800000,
+ .end = 0x1c800007,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = SERIAL_IRQ,
+ .end = SERIAL_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct plat_serial8250_port cobalt_serial8250_port[] = {
+ {
+ .irq = SERIAL_IRQ,
+ .uartclk = 18432000,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .mapbase = 0x1c800000,
+ },
+ {},
+};
+
+static __init int cobalt_uart_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ /*
+ * Cobalt Qube1 has no UART.
+ */
+ if (cobalt_board_id == COBALT_BRD_ID_QUBE1)
+ return 0;
+
+ pdev = platform_device_alloc("serial8250", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->id = PLAT8250_DEV_PLATFORM;
+ pdev->dev.platform_data = cobalt_serial8250_port;
+
+ retval = platform_device_add_resources(pdev, cobalt_uart_resource, ARRAY_SIZE(cobalt_uart_resource));
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(cobalt_uart_add);
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
new file mode 100644
index 00000000..ec3b2c41
--- /dev/null
+++ b/arch/mips/cobalt/setup.c
@@ -0,0 +1,120 @@
+/*
+ * Setup pointers to hardware dependent routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 2004, 05 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/gt64120.h>
+
+#include <cobalt.h>
+
+extern void cobalt_machine_restart(char *command);
+extern void cobalt_machine_halt(void);
+
+const char *get_system_type(void)
+{
+ switch (cobalt_board_id) {
+ case COBALT_BRD_ID_QUBE1:
+ return "Cobalt Qube";
+ case COBALT_BRD_ID_RAQ1:
+ return "Cobalt RaQ";
+ case COBALT_BRD_ID_QUBE2:
+ return "Cobalt Qube2";
+ case COBALT_BRD_ID_RAQ2:
+ return "Cobalt RaQ2";
+ }
+ return "MIPS Cobalt";
+}
+
+/*
+ * Cobalt doesn't have PS/2 keyboard/mouse interfaces,
+ * keyboard conntroller is never used.
+ * Also PCI-ISA bridge DMA contoroller is never used.
+ */
+static struct resource cobalt_reserved_resources[] = {
+ { /* dma1 */
+ .start = 0x00,
+ .end = 0x1f,
+ .name = "reserved",
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO,
+ },
+ { /* keyboard */
+ .start = 0x60,
+ .end = 0x6f,
+ .name = "reserved",
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO,
+ },
+ { /* dma page reg */
+ .start = 0x80,
+ .end = 0x8f,
+ .name = "reserved",
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO,
+ },
+ { /* dma2 */
+ .start = 0xc0,
+ .end = 0xdf,
+ .name = "reserved",
+ .flags = IORESOURCE_BUSY | IORESOURCE_IO,
+ },
+};
+
+void __init plat_mem_setup(void)
+{
+ int i;
+
+ _machine_restart = cobalt_machine_restart;
+ _machine_halt = cobalt_machine_halt;
+ pm_power_off = cobalt_machine_halt;
+
+ set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE));
+
+ /* I/O port resource */
+ ioport_resource.end = 0x01ffffff;
+
+ /* These resources have been reserved by VIA SuperI/O chip. */
+ for (i = 0; i < ARRAY_SIZE(cobalt_reserved_resources); i++)
+ request_resource(&ioport_resource, cobalt_reserved_resources + i);
+}
+
+/*
+ * Prom init. We read our one and only communication with the firmware.
+ * Grab the amount of installed memory.
+ * Better boot loaders (CoLo) pass a command line too :-)
+ */
+
+void __init prom_init(void)
+{
+ unsigned long memsz;
+ int argc, i;
+ char **argv;
+
+ memsz = fw_arg0 & 0x7fff0000;
+ argc = fw_arg0 & 0x0000ffff;
+ argv = (char **)fw_arg1;
+
+ for (i = 1; i < argc; i++) {
+ strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE);
+ if (i < (argc - 1))
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+ }
+
+ add_memory_region(0x0, memsz, BOOT_MEM_RAM);
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* Nothing to do! */
+}
diff --git a/arch/mips/cobalt/time.c b/arch/mips/cobalt/time.c
new file mode 100644
index 00000000..0162f9ed
--- /dev/null
+++ b/arch/mips/cobalt/time.c
@@ -0,0 +1,54 @@
+/*
+ * Cobalt time initialization.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+
+#include <asm/gt64120.h>
+#include <asm/i8253.h>
+#include <asm/time.h>
+
+#define GT641XX_BASE_CLOCK 50000000 /* 50MHz */
+
+void __init plat_time_init(void)
+{
+ u32 start, end;
+ int i = HZ / 10;
+
+ setup_pit_timer();
+
+ gt641xx_set_base_clock(GT641XX_BASE_CLOCK);
+
+ /*
+ * MIPS counter frequency is measured during a 100msec interval
+ * using GT64111 timer0.
+ */
+ while (!gt641xx_timer0_state())
+ ;
+
+ start = read_c0_count();
+
+ while (i--)
+ while (!gt641xx_timer0_state())
+ ;
+
+ end = read_c0_count();
+
+ mips_hpt_frequency = (end - start) * 10;
+ printk(KERN_INFO "MIPS counter frequency %dHz\n", mips_hpt_frequency);
+}
diff --git a/arch/mips/configs/ar7_defconfig b/arch/mips/configs/ar7_defconfig
new file mode 100644
index 00000000..6cd5a519
--- /dev/null
+++ b/arch/mips/configs/ar7_defconfig
@@ -0,0 +1,152 @@
+CONFIG_AR7=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+CONFIG_KEXEC=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_LZMA=y
+CONFIG_EXPERT=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_MROUTE=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_CUBIC is not set
+CONFIG_TCP_CONG_WESTWOOD=y
+# CONFIG_TCP_CONG_HTCP is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_RAW=m
+CONFIG_ATM=m
+CONFIG_ATM_BR2684=m
+CONFIG_ATM_BR2684_IPFILTER=y
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_HAMRADIO=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_NETDEVICES=y
+CONFIG_FIXED_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_CPMAC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HW_RANDOM=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_AR7_WDT=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_SQUASHFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="rootfstype=squashfs,jffs2"
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig
new file mode 100644
index 00000000..ad15fb10
--- /dev/null
+++ b/arch/mips/configs/bcm47xx_defconfig
@@ -0,0 +1,624 @@
+CONFIG_BCM47XX=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_KEXEC=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_TINY_RCU=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_LZMA=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_BINFMT_MISC=m
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_IP_DCCP=m
+CONFIG_TIPC=m
+CONFIG_TIPC_ADVANCED=y
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_PKTGEN=m
+CONFIG_BT=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+CONFIG_MAC80211_MESH=y
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_ABSENT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_ATA_OVER_ETH=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_ISCSI_TCP=m
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+CONFIG_MDIO_BITBANG=m
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_B44=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_ATH_COMMON=m
+CONFIG_ATH5K=m
+CONFIG_B43=m
+CONFIG_B43LEGACY=m
+CONFIG_ZD1211RW=m
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_SIERRA_NET=m
+CONFIG_ATM_DUMMY=m
+CONFIG_ATM_TCP=m
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_W1=m
+CONFIG_W1_MASTER_MATROX=m
+CONFIG_W1_MASTER_DS2490=m
+CONFIG_W1_SLAVE_THERM=m
+CONFIG_W1_SLAVE_SMEM=m
+CONFIG_W1_SLAVE_DS2433=m
+CONFIG_W1_SLAVE_DS2760=m
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_BCM47XX_WDT=y
+CONFIG_SSB_DRIVER_GIGE=y
+CONFIG_DISPLAY_SUPPORT=m
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_USB_AUDIO=m
+CONFIG_HID=m
+CONFIG_USB_HID=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_U132_HCD=m
+CONFIG_USB_R8A66597_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRCABLE=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_MOS7720=m
+CONFIG_USB_SERIAL_MOS7840=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OTI6858=m
+CONFIG_USB_SERIAL_HP4X=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_SERIAL_DEBUG=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_IOWARRIOR=m
+CONFIG_USB_TEST=m
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_NET2280=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+CONFIG_GFS2_FS=m
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ADFS_FS=m
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_CIFS=m
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_DLM=m
+CONFIG_DLM_DEBUG=y
+CONFIG_DEBUG_FS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRC16=m
+CONFIG_CRC7=m
diff --git a/arch/mips/configs/bcm63xx_defconfig b/arch/mips/configs/bcm63xx_defconfig
new file mode 100644
index 00000000..91900513
--- /dev/null
+++ b/arch/mips/configs/bcm63xx_defconfig
@@ -0,0 +1,90 @@
+CONFIG_BCM63XX=y
+CONFIG_BCM63XX_CPU_6338=y
+CONFIG_BCM63XX_CPU_6345=y
+CONFIG_BCM63XX_CPU_6348=y
+CONFIG_BCM63XX_CPU_6358=y
+CONFIG_NO_HZ=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_TINY_RCU=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_SHMEM is not set
+# CONFIG_AIO is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_BCM63XX=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+CONFIG_MAC80211=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_BCM63XX_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_BCM63XX_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_B43=y
+# CONFIG_B43_PHY_LP is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_BCM63XX=y
+CONFIG_SERIAL_BCM63XX_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_ARB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200"
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
new file mode 100644
index 00000000..1cdff6b6
--- /dev/null
+++ b/arch/mips/configs/bigsur_defconfig
@@ -0,0 +1,292 @@
+CONFIG_SIBYTE_BIGSUR=y
+CONFIG_64BIT=y
+CONFIG_SMP=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_1000=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+# CONFIG_INET_LRO is not set
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETLABEL=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_DCCP=m
+CONFIG_SCTP_HMAC_SHA1=y
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_HAMRADIO=y
+CONFIG_AX25=m
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_SGI_IOC4=m
+CONFIG_EEPROM_LEGACY=y
+CONFIG_EEPROM_MAX6875=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_IT8213=m
+CONFIG_BLK_DEV_TC86C001=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+CONFIG_ATA=y
+CONFIG_SATA_SIL24=y
+CONFIG_PATA_SIL680=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SB1250_MAC=y
+CONFIG_CHELSIO_T3=m
+CONFIG_NETXEN_NIC=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_VT is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_SIBYTE=y
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+# CONFIG_HWMON is not set
+CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC7=m
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
new file mode 100644
index 00000000..5135dc0b
--- /dev/null
+++ b/arch/mips/configs/capcella_defconfig
@@ -0,0 +1,101 @@
+CONFIG_MACH_VR41XX=y
+CONFIG_ZAO_CAPCELLA=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_MD5SIG=y
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_IP_SCTP=m
+CONFIG_FW_LOADER=m
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_IDE_GENERIC=y
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_8139TOO=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_VR41XX=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_VR41XX=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=32M console=ttyVR0,38400"
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/configs/cavium-octeon_defconfig b/arch/mips/configs/cavium-octeon_defconfig
new file mode 100644
index 00000000..75165dfa
--- /dev/null
+++ b/arch/mips/configs/cavium-octeon_defconfig
@@ -0,0 +1,93 @@
+CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y
+CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
new file mode 100644
index 00000000..5419adb2
--- /dev/null
+++ b/arch/mips/configs/cobalt_defconfig
@@ -0,0 +1,90 @@
+CONFIG_MIPS_COBALT=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_RAID_ATTRS=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_PATA_VIA=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=y
+CONFIG_TULIP=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_COBALT_BTNS=y
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_COBALT=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_HID=m
+CONFIG_USB=m
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_COBALT_QUBE=y
+CONFIG_LEDS_COBALT_RAQ=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_CMOS=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
new file mode 100644
index 00000000..4044c9e0
--- /dev/null
+++ b/arch/mips/configs/db1000_defconfig
@@ -0,0 +1,118 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-db1000"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
new file mode 100644
index 00000000..c6b49938
--- /dev/null
+++ b/arch/mips/configs/db1100_defconfig
@@ -0,0 +1,122 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_DB1100=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-db1100"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_AU1100=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x16=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
new file mode 100644
index 00000000..1f69249b
--- /dev/null
+++ b/arch/mips/configs/db1200_defconfig
@@ -0,0 +1,170 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_DB1200=y
+CONFIG_KSM=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-db1200"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_UB=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDE_PROC_FS is not set
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_AU1550=y
+CONFIG_SPI=y
+CONFIG_SPI_AU1550=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_ADM1025=y
+CONFIG_SENSORS_LM70=y
+CONFIG_FB=y
+CONFIG_FB_AU1200=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x16=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+# CONFIG_SND_USB is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AU1XPSC=y
+CONFIG_SND_SOC_DB1200=y
+CONFIG_HIDRAW=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_AU1X=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200"
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
new file mode 100644
index 00000000..b6e21c7c
--- /dev/null
+++ b/arch/mips/configs/db1500_defconfig
@@ -0,0 +1,128 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_DB1500=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-db1500"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_PCCARD=y
+# CONFIG_CARDBUS is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_ARB is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
new file mode 100644
index 00000000..798a553c
--- /dev/null
+++ b/arch/mips/configs/db1550_defconfig
@@ -0,0 +1,157 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_DB1550=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-db1550"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_PCCARD=y
+# CONFIG_CARDBUS is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_AU1550=y
+CONFIG_BLK_DEV_UB=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS is not set
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_AU1550=y
+CONFIG_SPI=y
+CONFIG_SPI_AU1550=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_ARB is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_HRTIMER=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AU1XPSC=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+# CONFIG_JFFS2_FS_POSIX_ACL is not set
+# CONFIG_JFFS2_FS_SECURITY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
new file mode 100644
index 00000000..87d03408
--- /dev/null
+++ b/arch/mips/configs/decstation_defconfig
@@ -0,0 +1,120 @@
+CONFIG_MACH_DECSTATION=y
+CONFIG_CPU_R3000=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_TC=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_VLAN_8021Q=m
+CONFIG_CONNECTOR=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_ISCSI_TCP=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DECLANCE=y
+CONFIG_FDDI=y
+CONFIG_DEFXX=m
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_DZ is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_PMAG_BA=y
+CONFIG_FB_PMAGB_B=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_FUSE_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_UFS_FS=y
+CONFIG_UFS_FS_WRITE=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_OSF_PARTITION=y
+CONFIG_DLM=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
new file mode 100644
index 00000000..0126e66d
--- /dev/null
+++ b/arch/mips/configs/e55_defconfig
@@ -0,0 +1,43 @@
+CONFIG_MACH_VR41XX=y
+CONFIG_CASIO_E55=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_IDE_GENERIC=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_VR41XX=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_VR41XX=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M"
+# CONFIG_CRC32 is not set
diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig
new file mode 100644
index 00000000..e5b73de0
--- /dev/null
+++ b/arch/mips/configs/fuloong2e_defconfig
@@ -0,0 +1,284 @@
+CONFIG_MACH_LOONGSON=y
+CONFIG_64BIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-fuloong2e"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_PCI=y
+CONFIG_BINFMT_MISC=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION="/dev/hda3"
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_PHONET=m
+CONFIG_NET_9P=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_MTD=m
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_PHYSMAP=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_VIA82CXXX=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=m
+CONFIG_VETH=m
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NET_FC=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_MOUSE_SERIAL=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_HW_RANDOM=y
+CONFIG_RTC=y
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_VIAPRO=m
+# CONFIG_HWMON is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+CONFIG_FB_RADEON=y
+# CONFIG_FB_RADEON_I2C is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_VIA82XX=m
+CONFIG_HIDRAW=y
+# CONFIG_USB_HID is not set
+CONFIG_HID_PID=y
+CONFIG_USB_KBD=y
+CONFIG_USB_MOUSE=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_WUSB_CBAF=m
+CONFIG_USB_C67X00_HCD=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_ISP1760_HCD=m
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_R8A66597_HCD=m
+CONFIG_USB_ACM=y
+CONFIG_USB_PRINTER=y
+CONFIG_USB_WDM=m
+CONFIG_USB_TMC=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_SEVSEG=m
+CONFIG_USB_ISIGHTFW=m
+CONFIG_UIO=m
+CONFIG_UIO_CIF=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_REISERFS_FS=m
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=936
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_OMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp936"
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DEBUG2=y
+CONFIG_CIFS_EXPERIMENTAL=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_LZO=m
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC7=m
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig
new file mode 100644
index 00000000..48a40aef
--- /dev/null
+++ b/arch/mips/configs/gpr_defconfig
@@ -0,0 +1,349 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_GPR=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_IP_DCCP=m
+CONFIG_IP_SCTP=m
+CONFIG_TIPC=m
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_PKTGEN=m
+CONFIG_HAMRADIO=y
+CONFIG_AX25=m
+# CONFIG_AX25_DAMA_SLAVE is not set
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_RAM=m
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_TIFM_CORE=m
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_ATH_COMMON=y
+CONFIG_ATH_DEBUG=y
+CONFIG_ATH5K=y
+CONFIG_ATH5K_DEBUG=y
+CONFIG_WAN=y
+CONFIG_LANMEDIA=m
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=m
+CONFIG_HDLC_RAW_ETH=m
+CONFIG_HDLC_CISCO=m
+CONFIG_HDLC_FR=m
+CONFIG_HDLC_PPP=m
+CONFIG_HDLC_X25=m
+CONFIG_PCI200SYN=m
+CONFIG_WANXL=m
+CONFIG_FARSYNC=m
+CONFIG_DSCC4=m
+CONFIG_DSCC4_PCISYNC=y
+CONFIG_DSCC4_PCI_RST=y
+CONFIG_DLCI=m
+CONFIG_WAN_ROUTER_DRIVERS=m
+CONFIG_CYCLADES_SYNC=m
+CONFIG_CYCLOMX_X25=y
+CONFIG_LAPBETHER=m
+CONFIG_X25_ASY=m
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+CONFIG_ATM_FIRESTREAM=m
+CONFIG_ATM_ZATM=m
+CONFIG_ATM_NICSTAR=m
+CONFIG_ATM_IDT77252=m
+CONFIG_ATM_AMBASSADOR=m
+CONFIG_ATM_HORIZON=m
+CONFIG_ATM_IA=m
+CONFIG_ATM_FORE200E=m
+CONFIG_ATM_HE=m
+CONFIG_ATM_HE_USE_SUNI=y
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NET_FC=y
+CONFIG_NETCONSOLE=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_LM83=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_SSB=m
+CONFIG_SSB_DRIVER_PCICORE=y
+# CONFIG_VGA_ARB is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_USB_HID=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=m
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_EZUSB=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_SIERRAWIRELESS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs rw ip=auto"
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
new file mode 100644
index 00000000..d1606569
--- /dev/null
+++ b/arch/mips/configs/ip22_defconfig
@@ -0,0 +1,399 @@
+CONFIG_ARC_CONSOLE=y
+CONFIG_CPU_R5000=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_1000=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_PHONET=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_RFKILL=m
+CONFIG_CONNECTOR=m
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_MISC_DEVICES is not set
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_ISCSI_TCP=m
+CONFIG_SGIWD93_SCSI=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_MDIO_BITBANG=m
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=m
+CONFIG_SGISEEQ=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_HOSTAP=m
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_MOUSE_PS2=m
+# CONFIG_MOUSE_PS2_ALPS is not set
+# CONFIG_MOUSE_PS2_SYNAPTICS is not set
+CONFIG_MOUSE_SERIAL=m
+CONFIG_SERIO_RAW=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_IP22_ZILOG=m
+# CONFIG_HW_RANDOM is not set
+CONFIG_RAW_DRIVER=m
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=m
+CONFIG_WATCHDOG=y
+CONFIG_INDYDOG=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SGI_NEWPORT_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_HIDRAW=y
+CONFIG_HID_PID=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_DS1286=y
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_EFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
+CONFIG_UFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_CIFS=m
+CONFIG_CIFS_UPCALL=y
+CONFIG_CODA_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_LZO=m
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC32=m
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
new file mode 100644
index 00000000..0e36abcd
--- /dev/null
+++ b/arch/mips/configs/ip27_defconfig
@@ -0,0 +1,387 @@
+CONFIG_SGI_IP27=y
+CONFIG_NUMA=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
+CONFIG_SMP=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_1000=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
+CONFIG_CPUSETS=y
+CONFIG_RELAY=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_PM=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_PID=y
+CONFIG_RFKILL=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_OSD=m
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+CONFIG_SCSI_CXGB3_ISCSI=m
+CONFIG_SCSI_BNX2_ISCSI=m
+CONFIG_BE2ISCSI=m
+CONFIG_SCSI_HPSA=m
+CONFIG_SCSI_3W_SAS=m
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
+CONFIG_SCSI_MVSAS=m
+# CONFIG_SCSI_MVSAS_DEBUG is not set
+CONFIG_SCSI_DPT_I2O=m
+CONFIG_SCSI_MPT2SAS=m
+CONFIG_LIBFC=m
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_PMCRAID=m
+CONFIG_SCSI_BFA_FC=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_UEVENT=y
+CONFIG_IFB=m
+CONFIG_MACVLAN=m
+CONFIG_VETH=m
+CONFIG_PHYLIB=y
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_ICPLUS_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_NATIONAL_PHY=m
+CONFIG_STE10XP=m
+CONFIG_LSI_ET1011C_PHY=m
+CONFIG_MDIO_BITBANG=m
+CONFIG_NET_ETHERNET=y
+CONFIG_AX88796=m
+CONFIG_AX88796_93CX6=y
+CONFIG_SGI_IOC3_ETH=y
+CONFIG_SMC91X=m
+CONFIG_ETHOC=m
+CONFIG_SMSC911X=m
+CONFIG_DNET=m
+CONFIG_B44=m
+CONFIG_KS8851_MLL=m
+CONFIG_ATL2=m
+CONFIG_E1000E=m
+CONFIG_IP1000=m
+CONFIG_IGB=m
+CONFIG_IGBVF=m
+CONFIG_VIA_VELOCITY=m
+CONFIG_QLA3XXX=m
+CONFIG_ATL1E=m
+CONFIG_ATL1C=m
+CONFIG_JME=m
+CONFIG_ENIC=m
+CONFIG_IXGBE=m
+CONFIG_VXGE=m
+CONFIG_NETXEN_NIC=m
+CONFIG_NIU=m
+CONFIG_MLX4_EN=m
+# CONFIG_MLX4_DEBUG is not set
+CONFIG_TEHUTI=m
+CONFIG_BNX2X=m
+CONFIG_QLGE=m
+CONFIG_SFC=m
+CONFIG_BE2NET=m
+CONFIG_LIBERTAS_THINFIRM=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+CONFIG_PRISM54=m
+CONFIG_RTL8180=m
+CONFIG_ADM8211=m
+CONFIG_MWL8K=m
+CONFIG_ATH_COMMON=m
+CONFIG_ATH5K=m
+CONFIG_ATH9K=m
+CONFIG_B43=m
+CONFIG_B43LEGACY=m
+# CONFIG_B43LEGACY_DEBUG is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+CONFIG_IPW2100_DEBUG=y
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+CONFIG_IPW2200_DEBUG=y
+CONFIG_IWLWIFI=m
+CONFIG_IWLAGN=m
+CONFIG_IWL4965=y
+CONFIG_IWL5000=y
+CONFIG_IWL3945=m
+CONFIG_LIBERTAS=m
+CONFIG_HERMES=m
+# CONFIG_HERMES_CACHE_FW_ON_INIT is not set
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+CONFIG_P54_COMMON=m
+CONFIG_P54_PCI=m
+CONFIG_RT2X00=m
+CONFIG_RT2400PCI=m
+CONFIG_RT2500PCI=m
+CONFIG_RT61PCI=m
+CONFIG_RT2800PCI=m
+CONFIG_WL12XX=m
+CONFIG_WL1251=m
+# CONFIG_INPUT is not set
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_LIBPS2=m
+CONFIG_SERIO_RAW=m
+CONFIG_SERIO_ALTERA_PS2=m
+# CONFIG_VT is not set
+CONFIG_NOZOMI=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_ALI1535=m
+CONFIG_I2C_ALI1563=m
+CONFIG_I2C_ALI15X3=m
+CONFIG_I2C_AMD756=m
+CONFIG_I2C_AMD8111=m
+CONFIG_I2C_I801=m
+CONFIG_I2C_ISCH=m
+CONFIG_I2C_PIIX4=m
+CONFIG_I2C_NFORCE2=m
+CONFIG_I2C_SIS5595=m
+CONFIG_I2C_SIS630=m
+CONFIG_I2C_SIS96X=m
+CONFIG_I2C_VIA=m
+CONFIG_I2C_VIAPRO=m
+CONFIG_I2C_OCORES=m
+CONFIG_I2C_PCA_PLATFORM=m
+CONFIG_I2C_SIMTEC=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_TAOS_EVM=m
+CONFIG_I2C_STUB=m
+CONFIG_PPS=m
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=m
+CONFIG_MFD_PCF50633=m
+CONFIG_PCF50633_ADC=m
+CONFIG_PCF50633_GPIO=m
+# CONFIG_VGA_ARB is not set
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_BD2802=m
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_M48T35=y
+CONFIG_UIO=y
+CONFIG_UIO_AEC=m
+CONFIG_UIO_SERCOS3=m
+CONFIG_UIO_PCI_GENERIC=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_AUTOFS_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SQUASHFS=m
+CONFIG_OMFS_FS=m
+CONFIG_EXOFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_RPCSEC_GSS_KRB5=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_DLM=m
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_DEV_HIFN_795X=m
+CONFIG_CRC_T10DIF=m
diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig
new file mode 100644
index 00000000..4dbf6269
--- /dev/null
+++ b/arch/mips/configs/ip28_defconfig
@@ -0,0 +1,80 @@
+CONFIG_SGI_IP28=y
+CONFIG_ARC_CONSOLE=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_EISA=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_TCP_MD5SIG=y
+# CONFIG_IPV6 is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SGIWD93_SCSI=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_SGISEEQ=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_MOUSE_PS2_ALPS is not set
+# CONFIG_MOUSE_PS2_SYNAPTICS is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_IP22_ZILOG=y
+CONFIG_SERIAL_IP22_ZILOG_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_INDYDOG=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_PROC_KCORE=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
new file mode 100644
index 00000000..7bbd5219
--- /dev/null
+++ b/arch/mips/configs/ip32_defconfig
@@ -0,0 +1,216 @@
+CONFIG_SGI_IP32=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_BINFMT_MISC=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+# CONFIG_INET_LRO is not set
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_MD5SIG=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_CONNECTOR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_SGI_IOC4=y
+CONFIG_RAID_ATTRS=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SAS_LIBSAS=y
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+CONFIG_SCSI_AIC7XXX=y
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SGI_O2MACE_ETH=y
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+CONFIG_TULIP_MMIO=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_MACEPS2=y
+CONFIG_SERIO_RAW=y
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_WATCHDOG=y
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_GBE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_INTF_SYSFS is not set
+# CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_DRV_CMOS=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_SGI_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
new file mode 100644
index 00000000..92a60aec
--- /dev/null
+++ b/arch/mips/configs/jazz_defconfig
@@ -0,0 +1,389 @@
+CONFIG_MACH_JAZZ=y
+CONFIG_OLIVETTI_M700=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_PACKET=m
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE=m
+CONFIG_DECNET=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_HAMRADIO=y
+CONFIG_AX25=m
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_CONNECTOR=m
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_1284=y
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_ISCSI_TCP=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+CONFIG_JAZZ_ESP=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_JAZZ_SONIC=y
+CONFIG_NET_ISA=y
+CONFIG_NE2000=m
+CONFIG_NET_PCI=y
+CONFIG_PLIP=m
+CONFIG_INPUT_FF_MEMLESS=m
+CONFIG_SERIO_PARKBD=m
+CONFIG_SERIO_RAW=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_PRINTER=m
+CONFIG_PPDEV=m
+# CONFIG_HW_RANDOM is not set
+CONFIG_W1=m
+# CONFIG_HWMON is not set
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_ADFS_FS=m
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_AFS_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRC_CCITT=m
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
new file mode 100644
index 00000000..db5705e1
--- /dev/null
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -0,0 +1,63 @@
+CONFIG_MACH_TX39XX=y
+CONFIG_TOSHIBA_JMR3927=y
+# CONFIG_SECCOMP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_SLAB=y
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_TC35815=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_TXX9_CONSOLE=y
+CONFIG_SERIAL_TXX9_STDSERIAL=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_TXX9_WDT=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1742=y
+CONFIG_PROC_KCORE=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig
new file mode 100644
index 00000000..d9f3db29
--- /dev/null
+++ b/arch/mips/configs/lasat_defconfig
@@ -0,0 +1,69 @@
+CONFIG_LASAT=y
+CONFIG_PICVUE=y
+CONFIG_PICVUE_PROC=y
+CONFIG_DS1603=y
+CONFIG_LASAT_SYSCTL=y
+CONFIG_HZ_1000=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIO_RAW=y
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig
new file mode 100644
index 00000000..b6acd2f2
--- /dev/null
+++ b/arch/mips/configs/lemote2f_defconfig
@@ -0,0 +1,461 @@
+CONFIG_MACH_LOONGSON=y
+CONFIG_LEMOTE_MACH2F=y
+CONFIG_CS5536_MFGPT=y
+CONFIG_64BIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_KEXEC=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_AUDIT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_IOSCHED_DEADLINE=m
+CONFIG_PCI=y
+CONFIG_BINFMT_MISC=m
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_PM=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION="/dev/hda3"
+CONFIG_PM_RUNTIME=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_LOONGSON2_CPUFREQ=m
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=y
+CONFIG_DEFAULT_BIC=y
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_IPX=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_BT=m
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_CFG80211=m
+CONFIG_LIB80211=m
+CONFIG_LIB80211_DEBUG=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_LEDS=y
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+CONFIG_BLK_DEV_AMD74XX=y
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_DEBUG=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+CONFIG_R8169=y
+CONFIG_R8169_VLAN=y
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_CDC_EEM=m
+CONFIG_NETCONSOLE=m
+CONFIG_NETCONSOLE_DYNAMIC=y
+CONFIG_INPUT_POLLDEV=m
+CONFIG_INPUT_EVDEV=y
+# CONFIG_MOUSE_PS2_ALPS is not set
+# CONFIG_MOUSE_PS2_LOGIPS2PP is not set
+# CONFIG_MOUSE_PS2_TRACKPOINT is not set
+CONFIG_MOUSE_APPLETOUCH=m
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_8250=m
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=16
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_FOURPORT=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_HW_RANDOM=y
+CONFIG_RTC=y
+CONFIG_THERMAL=y
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_VIVI=m
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_M5602=m
+CONFIG_USB_STV06XX=m
+CONFIG_USB_GSPCA_CONEX=m
+CONFIG_USB_GSPCA_ETOMS=m
+CONFIG_USB_GSPCA_FINEPIX=m
+CONFIG_USB_GSPCA_MARS=m
+CONFIG_USB_GSPCA_MR97310A=m
+CONFIG_USB_GSPCA_OV519=m
+CONFIG_USB_GSPCA_OV534=m
+CONFIG_USB_GSPCA_PAC207=m
+CONFIG_USB_GSPCA_PAC7311=m
+CONFIG_USB_GSPCA_SN9C20X=m
+CONFIG_USB_GSPCA_SONIXB=m
+CONFIG_USB_GSPCA_SONIXJ=m
+CONFIG_USB_GSPCA_SPCA500=m
+CONFIG_USB_GSPCA_SPCA501=m
+CONFIG_USB_GSPCA_SPCA505=m
+CONFIG_USB_GSPCA_SPCA506=m
+CONFIG_USB_GSPCA_SPCA508=m
+CONFIG_USB_GSPCA_SPCA561=m
+CONFIG_USB_GSPCA_SQ905=m
+CONFIG_USB_GSPCA_SQ905C=m
+CONFIG_USB_GSPCA_STK014=m
+CONFIG_USB_GSPCA_SUNPLUS=m
+CONFIG_USB_GSPCA_T613=m
+CONFIG_USB_GSPCA_TV8532=m
+CONFIG_USB_GSPCA_VC032X=m
+CONFIG_USB_GSPCA_ZC3XX=m
+CONFIG_USB_ET61X251=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_ZR364XX=m
+CONFIG_USB_STKWEBCAM=m
+CONFIG_USB_S2255=m
+# CONFIG_RADIO_ADAPTERS is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_SIS=y
+CONFIG_FB_SIS_300=y
+CONFIG_FB_SIS_315=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_6x11=y
+CONFIG_FONT_7x14=y
+CONFIG_FONT_PEARL_8x8=y
+CONFIG_FONT_ACORN_8x8=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+CONFIG_FONT_10x18=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_HRTIMER=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_AC97_POWER_SAVE=y
+CONFIG_SND_AC97_POWER_SAVE_DEFAULT=10
+CONFIG_SND_CS5535AUDIO=m
+# CONFIG_SND_MIPS is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_HIDRAW=y
+CONFIG_USB_HIDDEV=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EZKEY=m
+CONFIG_HID_KYE=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LOGITECH=m
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_NTRIG=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_GREENASIA=m
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_WACOM=m
+CONFIG_HID_ZEROPLUS=m
+CONFIG_ZEROPLUS_FF=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_WHCI_HCD=m
+CONFIG_USB_HWA_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_LED=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_M66592=y
+CONFIG_MMC=m
+CONFIG_LEDS_CLASS=y
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+CONFIG_FB_SM7XX=y
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_BTRFS_FS=m
+CONFIG_QUOTA=y
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FSCACHE=m
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_EMBEDDED=y
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
+CONFIG_CIFS=m
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_FRAME_WARN=1024
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_T10DIF=y
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
new file mode 100644
index 00000000..5527abbb
--- /dev/null
+++ b/arch/mips/configs/malta_defconfig
@@ -0,0 +1,493 @@
+CONFIG_MIPS_MALTA=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_MIPS_MT_SMP=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_PID_NS=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_PM=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_IP_SCTP=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_PHONET=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_CLS_IND=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_RFKILL=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_OOPS=m
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_UBI=m
+CONFIG_MTD_UBI_GLUEBI=m
+CONFIG_BLK_DEV_FD=m
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT8213=m
+CONFIG_BLK_DEV_TC86C001=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_MDIO_BITBANG=m
+CONFIG_NET_ETHERNET=y
+CONFIG_AX88796=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+CONFIG_TC35815=m
+CONFIG_CHELSIO_T3=m
+CONFIG_NETXEN_NIC=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+CONFIG_PRISM54=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+CONFIG_IPW2200=m
+CONFIG_IPW2200_MONITOR=y
+CONFIG_IPW2200_PROMISCUOUS=y
+CONFIG_IPW2200_QOS=y
+CONFIG_LIBERTAS=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_NORTEL_HERMES=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_I8042 is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_CIRRUS=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_HID=m
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_CMOS=y
+CONFIG_UIO=m
+CONFIG_UIO_CIF=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V2=y
+CONFIG_AUTOFS_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC16=m
diff --git a/arch/mips/configs/markeins_defconfig b/arch/mips/configs/markeins_defconfig
new file mode 100644
index 00000000..9c9a1230
--- /dev/null
+++ b/arch/mips/configs/markeins_defconfig
@@ -0,0 +1,212 @@
+CONFIG_NEC_MARKEINS=y
+CONFIG_HZ_1000=y
+CONFIG_PREEMPT=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PCI=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_FW_LOADER=m
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_SGI_IOC4=m
+CONFIG_SCSI=m
+CONFIG_SCSI_TGT=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_NET_PCI=y
+CONFIG_NATSEMI=y
+CONFIG_QLA3XXX=m
+CONFIG_CHELSIO_T3=m
+CONFIG_NETXEN_NIC=m
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_BUS=y
+# CONFIG_HID is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=m
+CONFIG_XFS_FS=m
+# CONFIG_DNOTIFY is not set
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_SMB_FS=m
+CONFIG_NLS_DEFAULT=""
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200 mem=192m ip=bootp root=/dev/nfs rw"
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_FCRYPT=m
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
new file mode 100644
index 00000000..b5ad7387
--- /dev/null
+++ b/arch/mips/configs/mipssim_defconfig
@@ -0,0 +1,64 @@
+CONFIG_MIPS_SIM=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MIPS_SIM_NET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
+# CONFIG_CRC32 is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
new file mode 100644
index 00000000..c16de981
--- /dev/null
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -0,0 +1,62 @@
+CONFIG_MACH_VR41XX=y
+CONFIG_VICTOR_MPC30X=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_CONNECTOR=m
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_IDE_GENERIC=y
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_PEGASUS=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_VR41XX=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_VR41XX=y
+CONFIG_EXT2_FS=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73"
+# CONFIG_CRC32 is not set
diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig
new file mode 100644
index 00000000..d1142e9c
--- /dev/null
+++ b/arch/mips/configs/msp71xx_defconfig
@@ -0,0 +1,88 @@
+CONFIG_PMC_MSP=y
+CONFIG_PMC_MSP7120_GW=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_PREEMPT=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-pmc"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SHMEM is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_BRIDGE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_PMC_MSP_EVM=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_PPP=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PMCMSP=y
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_STORAGE=y
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_EMBEDDED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_AES=y
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
new file mode 100644
index 00000000..807c97ee
--- /dev/null
+++ b/arch/mips/configs/mtx1_defconfig
@@ -0,0 +1,817 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_MTX1=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_AUDIT=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_PCCARD=m
+CONFIG_YENTA=m
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_PACKET=m
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_IP_DCCP=m
+CONFIG_IP_SCTP=m
+CONFIG_TIPC=m
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_PKTGEN=m
+CONFIG_HAMRADIO=y
+CONFIG_AX25=m
+# CONFIG_AX25_DAMA_SLAVE is not set
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_IRDA_DEBUG=y
+CONFIG_IRTTY_SIR=m
+CONFIG_DONGLE=y
+CONFIG_ESI_DONGLE=m
+CONFIG_ACTISYS_DONGLE=m
+CONFIG_TEKRAM_DONGLE=m
+CONFIG_LITELINK_DONGLE=m
+CONFIG_MA600_DONGLE=m
+CONFIG_GIRBIL_DONGLE=m
+CONFIG_MCP2120_DONGLE=m
+CONFIG_OLD_BELKIN_DONGLE=m
+CONFIG_ACT200L_DONGLE=m
+CONFIG_USB_IRDA=m
+CONFIG_SIGMATEL_FIR=m
+CONFIG_TOSHIBA_FIR=m
+CONFIG_VLSI_FIR=m
+CONFIG_MCS_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_RAM=m
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_ARCNET=m
+CONFIG_ARCNET_1201=m
+CONFIG_ARCNET_1051=m
+CONFIG_ARCNET_RAW=m
+CONFIG_ARCNET_CAP=m
+CONFIG_ARCNET_COM90xx=m
+CONFIG_ARCNET_COM90xxIO=m
+CONFIG_ARCNET_RIM_I=m
+CONFIG_ARCNET_COM20020=m
+CONFIG_ARCNET_COM20020_PCI=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_HAPPYMEAL=m
+CONFIG_SUNGEM=m
+CONFIG_CASSINI=m
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=m
+CONFIG_TYPHOON=m
+CONFIG_NET_TULIP=y
+CONFIG_DE2104X=m
+CONFIG_TULIP=m
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_ULI526X=m
+CONFIG_PCMCIA_XIRCOM=m
+CONFIG_HP100=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_B44=m
+CONFIG_FORCEDETH=m
+CONFIG_E100=m
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+CONFIG_8139TOO_8129=y
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+CONFIG_TLAN=m
+CONFIG_VIA_RHINE=m
+CONFIG_ACENIC=m
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_VLAN=y
+CONFIG_SIS190=m
+CONFIG_SKGE=m
+CONFIG_SKY2=m
+CONFIG_VIA_VELOCITY=m
+CONFIG_TIGON3=m
+CONFIG_BNX2=m
+CONFIG_QLA3XXX=m
+CONFIG_CHELSIO_T1=m
+CONFIG_IXGB=m
+CONFIG_S2IO=m
+CONFIG_MYRI10GE=m
+CONFIG_TR=y
+CONFIG_IBMOL=m
+CONFIG_IBMLS=m
+CONFIG_3C359=m
+CONFIG_TMS380TR=m
+CONFIG_TMSPCI=m
+CONFIG_ABYSS=m
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_SIERRA_NET=m
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+CONFIG_ARCNET_COM20020_CS=m
+CONFIG_PCMCIA_IBMTR=m
+CONFIG_WAN=y
+CONFIG_LANMEDIA=m
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=m
+CONFIG_HDLC_RAW_ETH=m
+CONFIG_HDLC_CISCO=m
+CONFIG_HDLC_FR=m
+CONFIG_HDLC_PPP=m
+CONFIG_HDLC_X25=m
+CONFIG_PCI200SYN=m
+CONFIG_WANXL=m
+CONFIG_FARSYNC=m
+CONFIG_DSCC4=m
+CONFIG_DSCC4_PCISYNC=y
+CONFIG_DSCC4_PCI_RST=y
+CONFIG_DLCI=m
+CONFIG_WAN_ROUTER_DRIVERS=m
+CONFIG_CYCLADES_SYNC=m
+CONFIG_CYCLOMX_X25=y
+CONFIG_LAPBETHER=m
+CONFIG_X25_ASY=m
+CONFIG_ATM_TCP=m
+CONFIG_ATM_LANAI=m
+CONFIG_ATM_ENI=m
+CONFIG_ATM_FIRESTREAM=m
+CONFIG_ATM_ZATM=m
+CONFIG_ATM_NICSTAR=m
+CONFIG_ATM_IDT77252=m
+CONFIG_ATM_AMBASSADOR=m
+CONFIG_ATM_HORIZON=m
+CONFIG_ATM_IA=m
+CONFIG_ATM_FORE200E=m
+CONFIG_ATM_HE=m
+CONFIG_ATM_HE_USE_SUNI=y
+CONFIG_FDDI=y
+CONFIG_DEFXX=m
+CONFIG_SKFP=m
+CONFIG_HIPPI=y
+CONFIG_ROADRUNNER=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NET_FC=y
+CONFIG_NETCONSOLE=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_PCIPS2=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_GAMEPORT_EMU10K1=m
+CONFIG_GAMEPORT_FM801=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=48
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_JSM=m
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_GPIO=m
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_ATXP1=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_F71805F=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PC87360=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_SIS5595=m
+CONFIG_SENSORS_SMSC47M1=m
+CONFIG_SENSORS_SMSC47M192=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_VIA686A=m
+CONFIG_SENSORS_VT1211=m
+CONFIG_SENSORS_VT8231=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_SENSORS_W83627EHF=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_WDT_MTX1=y
+# CONFIG_VGA_ARB is not set
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_AD1889=m
+CONFIG_SND_ALS300=m
+CONFIG_SND_ALI5451=m
+CONFIG_SND_ATIIXP=m
+CONFIG_SND_ATIIXP_MODEM=m
+CONFIG_SND_AU8810=m
+CONFIG_SND_AU8820=m
+CONFIG_SND_AU8830=m
+CONFIG_SND_AZT3328=m
+CONFIG_SND_BT87X=m
+CONFIG_SND_CA0106=m
+CONFIG_SND_CMIPCI=m
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_DARLA20=m
+CONFIG_SND_GINA20=m
+CONFIG_SND_LAYLA20=m
+CONFIG_SND_DARLA24=m
+CONFIG_SND_GINA24=m
+CONFIG_SND_LAYLA24=m
+CONFIG_SND_MONA=m
+CONFIG_SND_MIA=m
+CONFIG_SND_ECHO3G=m
+CONFIG_SND_INDIGO=m
+CONFIG_SND_INDIGOIO=m
+CONFIG_SND_INDIGODJ=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_EMU10K1X=m
+CONFIG_SND_ENS1370=m
+CONFIG_SND_ENS1371=m
+CONFIG_SND_ES1938=m
+CONFIG_SND_ES1968=m
+CONFIG_SND_FM801=m
+CONFIG_SND_HDA_INTEL=m
+CONFIG_SND_HDSP=m
+CONFIG_SND_HDSPM=m
+CONFIG_SND_ICE1712=m
+CONFIG_SND_ICE1724=m
+CONFIG_SND_INTEL8X0=m
+CONFIG_SND_INTEL8X0M=m
+CONFIG_SND_KORG1212=m
+CONFIG_SND_MAESTRO3=m
+CONFIG_SND_MIXART=m
+CONFIG_SND_NM256=m
+CONFIG_SND_PCXHR=m
+CONFIG_SND_RIPTIDE=m
+CONFIG_SND_RME32=m
+CONFIG_SND_RME96=m
+CONFIG_SND_RME9652=m
+CONFIG_SND_SONICVIBES=m
+CONFIG_SND_TRIDENT=m
+CONFIG_SND_VIA82XX=m
+CONFIG_SND_VIA82XX_MODEM=m
+CONFIG_SND_VX222=m
+CONFIG_SND_YMFPCI=m
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_VXPOCKET=m
+CONFIG_SND_PDAUDIOCF=m
+CONFIG_SOUND_PRIME=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=m
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_U132_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_STORAGE_KARMA=m
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_AIRCABLE=m
+CONFIG_USB_SERIAL_ARK3116=m
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_FUNSOFT=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_MOS7720=m
+CONFIG_USB_SERIAL_MOS7840=m
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_HP4X=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_TEST=m
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_CXACRU=m
+CONFIG_USB_UEAGLEATM=m
+CONFIG_USB_XUSBATM=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_NET2280=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_MIDI_GADGET=m
+CONFIG_MMC=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_TIFM_SD=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_TEST=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_DS1672=m
+CONFIG_RTC_DRV_RS5C372=m
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_X1205=m
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_DS1553=m
+CONFIG_RTC_DRV_DS1742=m
+CONFIG_RTC_DRV_M48T86=m
+CONFIG_RTC_DRV_V3020=m
+CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_AFS_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig
new file mode 100644
index 00000000..e4b399fd
--- /dev/null
+++ b/arch/mips/configs/nlm_xlr_defconfig
@@ -0,0 +1,574 @@
+CONFIG_NLM_XLR_BOARD=y
+CONFIG_HIGHMEM=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
+CONFIG_SMP=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_KEXEC=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_CROSS_COMPILE="mips64-unknown-linux-gnu-"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_NAMESPACES=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs"
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_INITRAMFS_COMPRESSION_GZIP=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_DEBUG=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_NETLABEL=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_IP_DCCP=m
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_TIPC=m
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_DECNET=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+CONFIG_PHONET=m
+CONFIG_IEEE802154=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_DCB=y
+CONFIG_NET_PKTGEN=m
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_CONNECTOR=y
+CONFIG_MTD=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_OSD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_MISC_DEVICES=y
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_TGT_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_ISCSI_TCP=m
+CONFIG_LIBFCOE=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_N_HDLC=m
+# CONFIG_DEVKMEM is not set
+CONFIG_STALDRV=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=48
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_RAW_DRIVER=m
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_UIO=y
+CONFIG_UIO_PDRV=m
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+CONFIG_FSCACHE_HISTOGRAM=y
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_ADFS_FS=m
+CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=y
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_EXOFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_CIFS=m
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_CIFS_EXPERIMENTAL=y
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_AFS_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_SYSV68_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_SCHED_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_KGDB=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=0
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SMACK=y
+CONFIG_SECURITY_TOMOYO=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_CCITT=m
+CONFIG_CRC7=m
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
new file mode 100644
index 00000000..75eb1b1f
--- /dev/null
+++ b/arch/mips/configs/pb1100_defconfig
@@ -0,0 +1,124 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_PB1100=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-pb1100"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_UB=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDE_PROC_FS is not set
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_HIDRAW=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+# CONFIG_JFFS2_FS_POSIX_ACL is not set
+# CONFIG_JFFS2_FS_SECURITY is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/pb1200_defconfig b/arch/mips/configs/pb1200_defconfig
new file mode 100644
index 00000000..dcbe2704
--- /dev/null
+++ b/arch/mips/configs/pb1200_defconfig
@@ -0,0 +1,170 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_PB1200=y
+CONFIG_KSM=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-pb1200"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_UB=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDE_PROC_FS is not set
+CONFIG_BLK_DEV_IDE_AU1XXX=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_AU1550=y
+CONFIG_SPI=y
+CONFIG_SPI_AU1550=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_ADM1025=y
+CONFIG_SENSORS_LM70=y
+CONFIG_FB=y
+CONFIG_FB_AU1200=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x16=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+# CONFIG_SND_USB is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AU1XPSC=y
+CONFIG_SND_SOC_DB1200=y
+CONFIG_HIDRAW=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_AU1X=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200"
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
new file mode 100644
index 00000000..fa004871
--- /dev/null
+++ b/arch/mips/configs/pb1500_defconfig
@@ -0,0 +1,141 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_PB1500=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-pb1500"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_PCCARD=y
+# CONFIG_CARDBUS is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_UB=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_IDE_TASK_IOCTL=y
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_ARB is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_S1D13XXX=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
new file mode 100644
index 00000000..e83d6497
--- /dev/null
+++ b/arch/mips/configs/pb1550_defconfig
@@ -0,0 +1,145 @@
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_PB1550=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-pb1550"
+CONFIG_KERNEL_LZMA=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_PCCARD=y
+# CONFIG_CARDBUS is not set
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_AU1550=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_UB=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS is not set
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_AU1550=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_ARB is not set
+CONFIG_HIDRAW=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/pnx8335-stb225_defconfig b/arch/mips/configs/pnx8335-stb225_defconfig
new file mode 100644
index 00000000..f2925769
--- /dev/null
+++ b/arch/mips/configs/pnx8335-stb225_defconfig
@@ -0,0 +1,98 @@
+CONFIG_NXP_STB225=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_128=y
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_INET_AH=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL_PNX8XXX=y
+CONFIG_SERIAL_PNX8XXX_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+CONFIG_EXT2_FS=m
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_SYSCTL_SYSCALL_CHECK=y
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
new file mode 100644
index 00000000..1d1f2067
--- /dev/null
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -0,0 +1,98 @@
+CONFIG_PNX8550_JBS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_PCI=y
+CONFIG_PM=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_TCP_MD5SIG=y
+# CONFIG_IPV6 is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SGI_IOC4=m
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_OFFBOARD=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_IT8213=m
+CONFIG_BLK_DEV_TC86C001=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_ISCSI_TCP=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+CONFIG_8139TOO_TUNE_TWISTER=y
+CONFIG_8139TOO_8129=y
+CONFIG_CHELSIO_T3=m
+CONFIG_NETXEN_NIC=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIAL_PNX8XXX=y
+CONFIG_SERIAL_PNX8XXX_CONSOLE=y
+CONFIG_HW_RANDOM=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_DLM=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS1,38400n8 root=/dev/nfs ip=bootp"
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRC_CCITT=m
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
new file mode 100644
index 00000000..15c66a57
--- /dev/null
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -0,0 +1,92 @@
+CONFIG_PNX8550_STB810=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_PCI=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_OFFBOARD=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_IT8213=m
+CONFIG_BLK_DEV_TC86C001=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_ISCSI_TCP=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_NET_PCI=y
+CONFIG_NATSEMI=y
+CONFIG_CHELSIO_T3=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_HW_RANDOM=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_DLM=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS1,38400n8 root=/dev/nfs ip=bootp"
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRC_CCITT=m
diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig
new file mode 100644
index 00000000..3b0b6e8c
--- /dev/null
+++ b/arch/mips/configs/powertv_defconfig
@@ -0,0 +1,136 @@
+CONFIG_POWERTV=y
+CONFIG_BOOTLOADER_FAMILY="R2"
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_1000=y
+CONFIG_PREEMPT=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_CROSS_COMPILE="mips-linux-"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_PNP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_IPV6_TUNNEL=y
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_BRIDGE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_TBF=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=32768
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+# CONFIG_WLAN is not set
+CONFIG_USB_RTL8150=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_VGA_ARB is not set
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_CP210X=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_FUSE_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig
new file mode 100644
index 00000000..55902d9c
--- /dev/null
+++ b/arch/mips/configs/rb532_defconfig
@@ -0,0 +1,191 @@
+CONFIG_MIKROTIK_RB532=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_100=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_TINY_RCU=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_PCI_QUIRKS is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_CUBIC=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=y
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=m
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
+CONFIG_LLC2=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_CLS_IND=y
+CONFIG_HAMRADIO=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_ATA=y
+# CONFIG_ATA_VERBOSE_ERROR is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_PATA_RB532=y
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_NET_ETHERNET=y
+CONFIG_KORINA=y
+CONFIG_NET_PCI=y
+CONFIG_VIA_RHINE=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_ATMEL=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_RB532_BUTTON=y
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HW_RANDOM=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_RC32434_WDT=y
+# CONFIG_VGA_ARB is not set
+# CONFIG_HID is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_MIKROTIK_RB532=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_SQUASHFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ZLIB=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC16=m
+CONFIG_LIBCRC32C=m
diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig
new file mode 100644
index 00000000..9cba8562
--- /dev/null
+++ b/arch/mips/configs/rbtx49xx_defconfig
@@ -0,0 +1,113 @@
+CONFIG_MACH_TX49XX=y
+CONFIG_TOSHIBA_RBTX4927=y
+CONFIG_TOSHIBA_RBTX4938=y
+CONFIG_TOSHIBA_RBTX4939=y
+CONFIG_TOSHIBA_RBTX4938_MPLEX_KEEP=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+# CONFIG_SECCOMP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_EPOLL is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_RBTX4939=y
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_TXX9NDFMC=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE_TX4938=y
+CONFIG_BLK_DEV_IDE_TX4939=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_NE2000=y
+CONFIG_NET_PCI=y
+CONFIG_TC35815=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_TXX9_CONSOLE=y
+CONFIG_SERIAL_TXX9_STDSERIAL=y
+CONFIG_SPI=y
+CONFIG_SPI_TXX9=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_TXX9_WDT=m
+# CONFIG_VGA_ARB is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_TXX9ACLC=m
+CONFIG_SND_SOC_TXX9ACLC_GENERIC=m
+# CONFIG_USB_SUPPORT is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_RS5C348=y
+CONFIG_RTC_DRV_DS1742=y
+CONFIG_RTC_DRV_TX4939=y
+CONFIG_DMADEVICES=y
+CONFIG_TXX9_DMAC=m
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_JFFS2_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
new file mode 100644
index 00000000..2c0230e7
--- /dev/null
+++ b/arch/mips/configs/rm200_defconfig
@@ -0,0 +1,480 @@
+CONFIG_SNI_RM=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_ARC_CONSOLE=y
+CONFIG_HZ_1000=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PCI=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_PACKET=m
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE=m
+CONFIG_DECNET=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_HAMRADIO=y
+CONFIG_AX25=m
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_CONNECTOR=m
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+CONFIG_PARPORT_1284=y
+CONFIG_BLK_DEV_FD=m
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_BPCK6=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_SGI_IOC4=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+CONFIG_ISCSI_TCP=m
+CONFIG_SCSI_AIC94XX=m
+# CONFIG_AIC94XX_DEBUG is not set
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=m
+CONFIG_MEGARAID_MAILBOX=m
+CONFIG_SCSI_PPA=m
+CONFIG_SCSI_IMM=m
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_ISA=y
+CONFIG_NE2000=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=y
+CONFIG_VIA_VELOCITY=m
+CONFIG_QLA3XXX=m
+CONFIG_CHELSIO_T3=m
+CONFIG_NETXEN_NIC=m
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_PLIP=m
+CONFIG_INPUT_FF_MEMLESS=m
+CONFIG_SERIO_PARKBD=m
+CONFIG_SERIO_RAW=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_PRINTER=m
+CONFIG_PPDEV=m
+# CONFIG_HW_RANDOM is not set
+CONFIG_W1=m
+# CONFIG_HWMON is not set
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=m
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_USS720=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_HP4X=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_SAFE_PADDED=y
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_SISUSBVGA=m
+CONFIG_USB_LD=m
+CONFIG_USB_TEST=m
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ADFS_FS=m
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_AFS_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
new file mode 100644
index 00000000..5b0463ef
--- /dev/null
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -0,0 +1,125 @@
+CONFIG_SIBYTE_SWARM=y
+CONFIG_CPU_SB1_PASS_2_2=y
+CONFIG_64BIT=y
+CONFIG_SMP=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_HZ_1000=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
+CONFIG_CPUSETS=y
+# CONFIG_PROC_PID_CPUSET is not set
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_PCI=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_MD5SIG=y
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+CONFIG_RFKILL=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_CONNECTOR=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=9220
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_SGI_IOC4=m
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=y
+CONFIG_RAID_ATTRS=m
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=m
+CONFIG_BROADCOM_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SB1250_MAC=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_RAW=m
+# CONFIG_VT is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_FUSE_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_DLM=m
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_LZO=m
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC16=m
diff --git a/arch/mips/configs/tb0219_defconfig b/arch/mips/configs/tb0219_defconfig
new file mode 100644
index 00000000..30036b4c
--- /dev/null
+++ b/arch/mips/configs/tb0219_defconfig
@@ -0,0 +1,97 @@
+CONFIG_MACH_VR41XX=y
+CONFIG_TANBAC_TB0219=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_8139TOO=y
+CONFIG_VIA_RHINE=y
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_R8169=y
+CONFIG_VIA_VELOCITY=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_TB0219=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=m
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_VR41XX=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CRAMFS=m
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="cca=3 mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
new file mode 100644
index 00000000..81bfa1d4
--- /dev/null
+++ b/arch/mips/configs/tb0226_defconfig
@@ -0,0 +1,95 @@
+CONFIG_MACH_VR41XX=y
+CONFIG_TANBAC_TB0226=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_E100=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_VR41XX=y
+CONFIG_EXT2_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CRAMFS=m
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="cca=3 mem=32M console=ttyVR0,115200"
+CONFIG_CRC32=m
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
new file mode 100644
index 00000000..c415c4f0
--- /dev/null
+++ b/arch/mips/configs/tb0287_defconfig
@@ -0,0 +1,111 @@
+CONFIG_MACH_VR41XX=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=m
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_XIP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_PATA_SIL680=y
+CONFIG_IEEE1394=m
+CONFIG_IEEE1394_OHCI1394=m
+CONFIG_IEEE1394_SBP2=m
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_8139TOO=y
+CONFIG_VIA_RHINE=y
+CONFIG_VIA_RHINE_MMIO=y
+CONFIG_R8169=y
+CONFIG_VIA_VELOCITY=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_VR41XX=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_SM501=y
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+CONFIG_FB_SM501=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_USB=m
+CONFIG_USB_MON=m
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_XFS_FS=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CRAMFS=m
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="cca=3 mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
new file mode 100644
index 00000000..ee4b2be4
--- /dev/null
+++ b/arch/mips/configs/workpad_defconfig
@@ -0,0 +1,73 @@
+CONFIG_MACH_VR41XX=y
+CONFIG_IBM_WORKPAD=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_VRC4171=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_BLK_DEV_RAM=m
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_IDE_GENERIC=y
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PCMCIA_AXNET=m
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_VR41XX=y
+CONFIG_SERIAL_VR41XX_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_VR41XX=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_VR41XX=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M"
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
new file mode 100644
index 00000000..44a451be
--- /dev/null
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -0,0 +1,97 @@
+CONFIG_WR_PPMC=y
+CONFIG_HZ_1000=y
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_EPOLL is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_PCI=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_MROUTE=y
+CONFIG_ARPD=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_MD5SIG=y
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+CONFIG_FW_LOADER=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SGI_IOC4=m
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=y
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_E100=y
+CONFIG_QLA3XXX=m
+CONFIG_CHELSIO_T3=m
+CONFIG_NETXEN_NIC=m
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_HW_RANDOM is not set
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_DLM=m
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200n8"
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
new file mode 100644
index 00000000..f72d305a
--- /dev/null
+++ b/arch/mips/configs/yosemite_defconfig
@@ -0,0 +1,94 @@
+CONFIG_PMC_YOSEMITE=y
+CONFIG_HIGHMEM=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_HZ_1000=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_RELAY=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_PCI=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=m
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_FW_LOADER=m
+CONFIG_CONNECTOR=m
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_SGI_IOC4=m
+CONFIG_RAID_ATTRS=m
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_QLA3XXX=m
+CONFIG_CHELSIO_T3=m
+CONFIG_NETXEN_NIC=m
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FUSE_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRC16=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
new file mode 100644
index 00000000..9eb2f9c0
--- /dev/null
+++ b/arch/mips/dec/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the DECstation family specific parts of the kernel
+#
+
+obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
+ kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
+
+obj-$(CONFIG_PROM_CONSOLE) += promcon.o
+obj-$(CONFIG_TC) += tc.o
+obj-$(CONFIG_CPU_HAS_WB) += wbflush.o
diff --git a/arch/mips/dec/Platform b/arch/mips/dec/Platform
new file mode 100644
index 00000000..cf55a6f4
--- /dev/null
+++ b/arch/mips/dec/Platform
@@ -0,0 +1,8 @@
+#
+# DECstation family
+#
+platform-$(CONFIG_MACH_DECSTATION) += dec/
+cflags-$(CONFIG_MACH_DECSTATION) += \
+ -I$(srctree)/arch/mips/include/asm/mach-dec
+libs-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/prom/
+load-$(CONFIG_MACH_DECSTATION) += 0xffffffff80040000
diff --git a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c
new file mode 100644
index 00000000..7abce661
--- /dev/null
+++ b/arch/mips/dec/ecc-berr.c
@@ -0,0 +1,278 @@
+/*
+ * Bus error event handling code for systems equipped with ECC
+ * handling logic, i.e. DECstation/DECsystem 5000/200 (KN02),
+ * 5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03),
+ * 5900/260 (KN05) systems.
+ *
+ * Copyright (c) 2003, 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/irq_regs.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+#include <asm/dec/ecc.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn03.h>
+#include <asm/dec/kn05.h>
+
+static volatile u32 *kn0x_erraddr;
+static volatile u32 *kn0x_chksyn;
+
+static inline void dec_ecc_be_ack(void)
+{
+ *kn0x_erraddr = 0; /* any write clears the IRQ */
+ iob();
+}
+
+static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
+{
+ static const char excstr[] = "exception";
+ static const char intstr[] = "interrupt";
+ static const char cpustr[] = "CPU";
+ static const char dmastr[] = "DMA";
+ static const char readstr[] = "read";
+ static const char mreadstr[] = "memory read";
+ static const char writestr[] = "write";
+ static const char mwritstr[] = "partial memory write";
+ static const char timestr[] = "timeout";
+ static const char overstr[] = "overrun";
+ static const char eccstr[] = "ECC error";
+
+ const char *kind, *agent, *cycle, *event;
+ const char *status = "", *xbit = "", *fmt = "";
+ unsigned long address;
+ u16 syn = 0, sngl;
+
+ int i = 0;
+
+ u32 erraddr = *kn0x_erraddr;
+ u32 chksyn = *kn0x_chksyn;
+ int action = MIPS_BE_FATAL;
+
+ /* For non-ECC ack ASAP, so that any subsequent errors get caught. */
+ if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID)
+ dec_ecc_be_ack();
+
+ kind = invoker ? intstr : excstr;
+
+ if (!(erraddr & KN0X_EAR_VALID)) {
+ /* No idea what happened. */
+ printk(KERN_ALERT "Unidentified bus error %s\n", kind);
+ return action;
+ }
+
+ agent = (erraddr & KN0X_EAR_CPU) ? cpustr : dmastr;
+
+ if (erraddr & KN0X_EAR_ECCERR) {
+ /* An ECC error on a CPU or DMA transaction. */
+ cycle = (erraddr & KN0X_EAR_WRITE) ? mwritstr : mreadstr;
+ event = eccstr;
+ } else {
+ /* A CPU timeout or a DMA overrun. */
+ cycle = (erraddr & KN0X_EAR_WRITE) ? writestr : readstr;
+ event = (erraddr & KN0X_EAR_CPU) ? timestr : overstr;
+ }
+
+ address = erraddr & KN0X_EAR_ADDRESS;
+ /* For ECC errors on reads adjust for MT pipelining. */
+ if ((erraddr & (KN0X_EAR_WRITE | KN0X_EAR_ECCERR)) == KN0X_EAR_ECCERR)
+ address = (address & ~0xfffLL) | ((address - 5) & 0xfffLL);
+ address <<= 2;
+
+ /* Only CPU errors are fixable. */
+ if (erraddr & KN0X_EAR_CPU && is_fixup)
+ action = MIPS_BE_FIXUP;
+
+ if (erraddr & KN0X_EAR_ECCERR) {
+ static const u8 data_sbit[32] = {
+ 0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d,
+ 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34,
+ 0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,
+ 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75,
+ };
+ static const u8 data_mbit[25] = {
+ 0x07, 0x0d, 0x1f,
+ 0x2f, 0x32, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
+ 0x43, 0x45, 0x46, 0x49, 0x4c, 0x51, 0x5e,
+ 0x61, 0x6e, 0x73, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
+ };
+ static const char sbestr[] = "corrected single";
+ static const char dbestr[] = "uncorrectable double";
+ static const char mbestr[] = "uncorrectable multiple";
+
+ if (!(address & 0x4))
+ syn = chksyn; /* Low bank. */
+ else
+ syn = chksyn >> 16; /* High bank. */
+
+ if (!(syn & KN0X_ESR_VLDLO)) {
+ /* Ack now, no rewrite will happen. */
+ dec_ecc_be_ack();
+
+ fmt = KERN_ALERT "%s" "invalid\n";
+ } else {
+ sngl = syn & KN0X_ESR_SNGLO;
+ syn &= KN0X_ESR_SYNLO;
+
+ /*
+ * Multibit errors may be tagged incorrectly;
+ * check the syndrome explicitly.
+ */
+ for (i = 0; i < 25; i++)
+ if (syn == data_mbit[i])
+ break;
+
+ if (i < 25) {
+ status = mbestr;
+ } else if (!sngl) {
+ status = dbestr;
+ } else {
+ volatile u32 *ptr =
+ (void *)CKSEG1ADDR(address);
+
+ *ptr = *ptr; /* Rewrite. */
+ iob();
+
+ status = sbestr;
+ action = MIPS_BE_DISCARD;
+ }
+
+ /* Ack now, now we've rewritten (or not). */
+ dec_ecc_be_ack();
+
+ if (syn && syn == (syn & -syn)) {
+ if (syn == 0x01) {
+ fmt = KERN_ALERT "%s"
+ "%#04x -- %s bit error "
+ "at check bit C%s\n";
+ xbit = "X";
+ } else {
+ fmt = KERN_ALERT "%s"
+ "%#04x -- %s bit error "
+ "at check bit C%s%u\n";
+ }
+ i = syn >> 2;
+ } else {
+ for (i = 0; i < 32; i++)
+ if (syn == data_sbit[i])
+ break;
+ if (i < 32)
+ fmt = KERN_ALERT "%s"
+ "%#04x -- %s bit error "
+ "at data bit D%s%u\n";
+ else
+ fmt = KERN_ALERT "%s"
+ "%#04x -- %s bit error\n";
+ }
+ }
+ }
+
+ if (action != MIPS_BE_FIXUP)
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
+ kind, agent, cycle, event, address);
+
+ if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR)
+ printk(fmt, " ECC syndrome ", syn, status, xbit, i);
+
+ return action;
+}
+
+int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ return dec_ecc_be_backend(regs, is_fixup, 0);
+}
+
+irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id)
+{
+ struct pt_regs *regs = get_irq_regs();
+
+ int action = dec_ecc_be_backend(regs, 0, 1);
+
+ if (action == MIPS_BE_DISCARD)
+ return IRQ_HANDLED;
+
+ /*
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
+ *
+ * The interrupt is asynchronously delivered thus EPC and RA
+ * may be irrelevant, but are printed for a reference.
+ */
+ printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
+ regs->cp0_epc, regs->regs[31]);
+ die("Unrecoverable bus error", regs);
+}
+
+
+/*
+ * Initialization differs a bit between KN02 and KN03/KN05, so we
+ * need two variants. Once set up, all systems can be handled the
+ * same way.
+ */
+static inline void dec_kn02_be_init(void)
+{
+ volatile u32 *csr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR);
+
+ kn0x_erraddr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_ERRADDR);
+ kn0x_chksyn = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CHKSYN);
+
+ /* Preset write-only bits of the Control Register cache. */
+ cached_kn02_csr = *csr | KN02_CSR_LEDS;
+
+ /* Set normal ECC detection and generation. */
+ cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN);
+ /* Enable ECC correction. */
+ cached_kn02_csr |= KN02_CSR_CORRECT;
+ *csr = cached_kn02_csr;
+ iob();
+}
+
+static inline void dec_kn03_be_init(void)
+{
+ volatile u32 *mcr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_MCR);
+ volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
+
+ kn0x_erraddr = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_ERRADDR);
+ kn0x_chksyn = (void *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_CHKSYN);
+
+ /*
+ * Set normal ECC detection and generation, enable ECC correction.
+ * For KN05 we also need to make sure EE (?) is enabled in the MB.
+ * Otherwise DBE/IBE exceptions would be masked but bus error
+ * interrupts would still arrive, resulting in an inevitable crash
+ * if get_dbe() triggers one.
+ */
+ *mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) |
+ KN03_MCR_CORRECT;
+ if (current_cpu_type() == CPU_R4400SC)
+ *mbcs |= KN4K_MB_CSR_EE;
+ fast_iob();
+}
+
+void __init dec_ecc_be_init(void)
+{
+ if (mips_machtype == MACH_DS5000_200)
+ dec_kn02_be_init();
+ else
+ dec_kn03_be_init();
+
+ /* Clear any leftover errors from the firmware. */
+ dec_ecc_be_ack();
+}
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
new file mode 100644
index 00000000..82c85281
--- /dev/null
+++ b/arch/mips/dec/int-handler.S
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
+ * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki
+ *
+ * Written by Ralf Baechle and Andreas Busse, modified for DECstation
+ * support by Paul Antoine and Harald Koerfgen.
+ *
+ * completly rewritten:
+ * Copyright (C) 1998 Harald Koerfgen
+ *
+ * Rewritten extensively for controller-driven IRQ support
+ * by Maciej W. Rozycki.
+ */
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/ioasic_ints.h>
+#include <asm/dec/kn01.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn02xa.h>
+#include <asm/dec/kn03.h>
+
+#define KN02_CSR_BASE CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR)
+#define KN02XA_IOASIC_BASE CKSEG1ADDR(KN02XA_SLOT_BASE + IOASIC_IOCTL)
+#define KN03_IOASIC_BASE CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_IOCTL)
+
+ .text
+ .set noreorder
+/*
+ * plat_irq_dispatch: Interrupt handler for DECstations
+ *
+ * We follow the model in the Indy interrupt code by David Miller, where he
+ * says: a lot of complication here is taken away because:
+ *
+ * 1) We handle one interrupt and return, sitting in a loop
+ * and moving across all the pending IRQ bits in the cause
+ * register is _NOT_ the answer, the common case is one
+ * pending IRQ so optimize in that direction.
+ *
+ * 2) We need not check against bits in the status register
+ * IRQ mask, that would make this routine slow as hell.
+ *
+ * 3) Linux only thinks in terms of all IRQs on or all IRQs
+ * off, nothing in between like BSD spl() brain-damage.
+ *
+ * Furthermore, the IRQs on the DECstations look basically (barring
+ * software IRQs which we don't use at all) like...
+ *
+ * DS2100/3100's, aka kn01, aka Pmax:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 SCSI
+ * 3 Lance Ethernet
+ * 4 DZ11 serial
+ * 5 RTC
+ * 6 Memory Controller & Video
+ * 7 FPU
+ *
+ * DS5000/200, aka kn02, aka 3max:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 TurboChannel
+ * 3 RTC
+ * 4 Reserved
+ * 5 Memory Controller
+ * 6 Reserved
+ * 7 FPU
+ *
+ * DS5000/1xx's, aka kn02ba, aka 3min:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 TurboChannel Slot 0
+ * 3 TurboChannel Slot 1
+ * 4 TurboChannel Slot 2
+ * 5 TurboChannel Slot 3 (ASIC)
+ * 6 Halt button
+ * 7 FPU/R4k timer
+ *
+ * DS5000/2x's, aka kn02ca, aka maxine:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 Periodic Interrupt (100usec)
+ * 3 RTC
+ * 4 I/O write timeout
+ * 5 TurboChannel (ASIC)
+ * 6 Halt Keycode from Access.Bus keyboard (CTRL-ALT-ENTER)
+ * 7 FPU/R4k timer
+ *
+ * DS5000/2xx's, aka kn03, aka 3maxplus:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 System Board (ASIC)
+ * 3 RTC
+ * 4 Reserved
+ * 5 Memory
+ * 6 Halt Button
+ * 7 FPU/R4k timer
+ *
+ * We handle the IRQ according to _our_ priority (see setup.c),
+ * then we just return. If multiple IRQs are pending then we will
+ * just take another exception, big deal.
+ */
+ .align 5
+ NESTED(plat_irq_dispatch, PT_SIZE, ra)
+ .set noreorder
+
+ /*
+ * Get pending Interrupts
+ */
+ mfc0 t0,CP0_CAUSE # get pending interrupts
+ mfc0 t1,CP0_STATUS
+#ifdef CONFIG_32BIT
+ lw t2,cpu_fpu_mask
+#endif
+ andi t0,ST0_IM # CAUSE.CE may be non-zero!
+ and t0,t1 # isolate allowed ones
+
+ beqz t0,spurious
+
+#ifdef CONFIG_32BIT
+ and t2,t0
+ bnez t2,fpu # handle FPU immediately
+#endif
+
+ /*
+ * Find irq with highest priority
+ */
+ PTR_LA t1,cpu_mask_nr_tbl
+1: lw t2,(t1)
+ nop
+ and t2,t0
+ beqz t2,1b
+ addu t1,2*PTRSIZE # delay slot
+
+ /*
+ * Do the low-level stuff
+ */
+ lw a0,(-PTRSIZE)(t1)
+ nop
+ bgez a0,handle_it # irq_nr >= 0?
+ # irq_nr < 0: it is an address
+ nop
+ jr a0
+ # a trick to save a branch:
+ lui t2,(KN03_IOASIC_BASE>>16)&0xffff
+ # upper part of IOASIC Address
+
+/*
+ * Handle "IRQ Controller" Interrupts
+ * Masked Interrupts are still visible and have to be masked "by hand".
+ */
+ FEXPORT(kn02_io_int) # 3max
+ lui t0,(KN02_CSR_BASE>>16)&0xffff
+ # get interrupt status and mask
+ lw t0,(t0)
+ nop
+ andi t1,t0,KN02_IRQ_ALL
+ b 1f
+ srl t0,16 # shift interrupt mask
+
+ FEXPORT(kn02xa_io_int) # 3min/maxine
+ lui t2,(KN02XA_IOASIC_BASE>>16)&0xffff
+ # upper part of IOASIC Address
+
+ FEXPORT(kn03_io_int) # 3max+ (t2 loaded earlier)
+ lw t0,IO_REG_SIR(t2) # get status: IOASIC sir
+ lw t1,IO_REG_SIMR(t2) # get mask: IOASIC simr
+ nop
+
+1: and t0,t1 # mask out allowed ones
+
+ beqz t0,spurious
+
+ /*
+ * Find irq with highest priority
+ */
+ PTR_LA t1,asic_mask_nr_tbl
+2: lw t2,(t1)
+ nop
+ and t2,t0
+ beq zero,t2,2b
+ addu t1,2*PTRSIZE # delay slot
+
+ /*
+ * Do the low-level stuff
+ */
+ lw a0,%lo(-PTRSIZE)(t1)
+ nop
+ bgez a0,handle_it # irq_nr >= 0?
+ # irq_nr < 0: it is an address
+ nop
+ jr a0
+ nop # delay slot
+
+/*
+ * Dispatch low-priority interrupts. We reconsider all status
+ * bits again, which looks like a lose, but it makes the code
+ * simple and O(log n), so it gets compensated.
+ */
+ FEXPORT(cpu_all_int) # HALT, timers, software junk
+ li a0,DEC_CPU_IRQ_BASE
+ srl t0,CAUSEB_IP
+ li t1,CAUSEF_IP>>CAUSEB_IP # mask
+ b 1f
+ li t2,4 # nr of bits / 2
+
+ FEXPORT(kn02_all_int) # impossible ?
+ li a0,KN02_IRQ_BASE
+ li t1,KN02_IRQ_ALL # mask
+ b 1f
+ li t2,4 # nr of bits / 2
+
+ FEXPORT(asic_all_int) # various I/O ASIC junk
+ li a0,IO_IRQ_BASE
+ li t1,IO_IRQ_ALL # mask
+ b 1f
+ li t2,8 # nr of bits / 2
+
+/*
+ * Dispatch DMA interrupts -- O(log n).
+ */
+ FEXPORT(asic_dma_int) # I/O ASIC DMA events
+ li a0,IO_IRQ_BASE+IO_INR_DMA
+ srl t0,IO_INR_DMA
+ li t1,IO_IRQ_DMA>>IO_INR_DMA # mask
+ li t2,8 # nr of bits / 2
+
+ /*
+ * Find irq with highest priority.
+ * Highest irq number takes precedence.
+ */
+1: srlv t3,t1,t2
+2: xor t1,t3
+ and t3,t0,t1
+ beqz t3,3f
+ nop
+ move t0,t3
+ addu a0,t2
+3: srl t2,1
+ bnez t2,2b
+ srlv t3,t1,t2
+
+handle_it:
+ j dec_irq_dispatch
+ nop
+
+#ifdef CONFIG_32BIT
+fpu:
+ j handle_fpe_int
+ nop
+#endif
+
+spurious:
+ j spurious_interrupt
+ nop
+ END(plat_irq_dispatch)
+
+/*
+ * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
+ * and asic_mask_nr_tbl are initialized to point all interrupts here.
+ * The tables are then filled in by machine-specific initialisation
+ * in dec_setup().
+ */
+ FEXPORT(dec_intr_unimplemented)
+ move a1,t0 # cheats way of printing an arg!
+ PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%08x");
+
+ FEXPORT(asic_intr_unimplemented)
+ move a1,t0 # cheats way of printing an arg!
+ PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%08x");
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c
new file mode 100644
index 00000000..824e08c7
--- /dev/null
+++ b/arch/mips/dec/ioasic-irq.c
@@ -0,0 +1,77 @@
+/*
+ * DEC I/O ASIC interrupts.
+ *
+ * Copyright (c) 2002, 2003 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/ioasic_ints.h>
+
+static int ioasic_irq_base;
+
+static void unmask_ioasic_irq(struct irq_data *d)
+{
+ u32 simr;
+
+ simr = ioasic_read(IO_REG_SIMR);
+ simr |= (1 << (d->irq - ioasic_irq_base));
+ ioasic_write(IO_REG_SIMR, simr);
+}
+
+static void mask_ioasic_irq(struct irq_data *d)
+{
+ u32 simr;
+
+ simr = ioasic_read(IO_REG_SIMR);
+ simr &= ~(1 << (d->irq - ioasic_irq_base));
+ ioasic_write(IO_REG_SIMR, simr);
+}
+
+static void ack_ioasic_irq(struct irq_data *d)
+{
+ mask_ioasic_irq(d);
+ fast_iob();
+}
+
+static struct irq_chip ioasic_irq_type = {
+ .name = "IO-ASIC",
+ .irq_ack = ack_ioasic_irq,
+ .irq_mask = mask_ioasic_irq,
+ .irq_mask_ack = ack_ioasic_irq,
+ .irq_unmask = unmask_ioasic_irq,
+};
+
+static struct irq_chip ioasic_dma_irq_type = {
+ .name = "IO-ASIC-DMA",
+ .irq_ack = ack_ioasic_irq,
+ .irq_mask = mask_ioasic_irq,
+ .irq_mask_ack = ack_ioasic_irq,
+ .irq_unmask = unmask_ioasic_irq,
+};
+
+void __init init_ioasic_irqs(int base)
+{
+ int i;
+
+ /* Mask interrupts. */
+ ioasic_write(IO_REG_SIMR, 0);
+ fast_iob();
+
+ for (i = base; i < base + IO_INR_DMA; i++)
+ irq_set_chip_and_handler(i, &ioasic_irq_type,
+ handle_level_irq);
+ for (; i < base + IO_IRQ_LINES; i++)
+ irq_set_chip(i, &ioasic_dma_irq_type);
+
+ ioasic_irq_base = base;
+}
diff --git a/arch/mips/dec/kn01-berr.c b/arch/mips/dec/kn01-berr.c
new file mode 100644
index 00000000..94d23b4a
--- /dev/null
+++ b/arch/mips/dec/kn01-berr.c
@@ -0,0 +1,201 @@
+/*
+ * Bus error event handling code for DECstation/DECsystem 3100
+ * and 2100 (KN01) systems equipped with parity error detection
+ * logic.
+ *
+ * Copyright (c) 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/inst.h>
+#include <asm/irq_regs.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+#include <asm/dec/kn01.h>
+
+
+/* CP0 hazard avoidance. */
+#define BARRIER \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ "nop\n\t" \
+ ".set pop\n\t")
+
+/*
+ * Bits 7:0 of the Control Register are write-only -- the
+ * corresponding bits of the Status Register have a different
+ * meaning. Hence we use a cache. It speeds up things a bit
+ * as well.
+ *
+ * There is no default value -- it has to be initialized.
+ */
+u16 cached_kn01_csr;
+static DEFINE_RAW_SPINLOCK(kn01_lock);
+
+
+static inline void dec_kn01_be_ack(void)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&kn01_lock, flags);
+
+ *csr = cached_kn01_csr | KN01_CSR_MEMERR; /* Clear bus IRQ. */
+ iob();
+
+ raw_spin_unlock_irqrestore(&kn01_lock, flags);
+}
+
+static int dec_kn01_be_backend(struct pt_regs *regs, int is_fixup, int invoker)
+{
+ volatile u32 *kn01_erraddr = (void *)CKSEG1ADDR(KN01_SLOT_BASE +
+ KN01_ERRADDR);
+
+ static const char excstr[] = "exception";
+ static const char intstr[] = "interrupt";
+ static const char cpustr[] = "CPU";
+ static const char mreadstr[] = "memory read";
+ static const char readstr[] = "read";
+ static const char writestr[] = "write";
+ static const char timestr[] = "timeout";
+ static const char paritystr[] = "parity error";
+
+ int data = regs->cp0_cause & 4;
+ unsigned int __user *pc = (unsigned int __user *)regs->cp0_epc +
+ ((regs->cp0_cause & CAUSEF_BD) != 0);
+ union mips_instruction insn;
+ unsigned long entrylo, offset;
+ long asid, entryhi, vaddr;
+
+ const char *kind, *agent, *cycle, *event;
+ unsigned long address;
+
+ u32 erraddr = *kn01_erraddr;
+ int action = MIPS_BE_FATAL;
+
+ /* Ack ASAP, so that any subsequent errors get caught. */
+ dec_kn01_be_ack();
+
+ kind = invoker ? intstr : excstr;
+
+ agent = cpustr;
+
+ if (invoker)
+ address = erraddr;
+ else {
+ /* Bloody hardware doesn't record the address for reads... */
+ if (data) {
+ /* This never faults. */
+ __get_user(insn.word, pc);
+ vaddr = regs->regs[insn.i_format.rs] +
+ insn.i_format.simmediate;
+ } else
+ vaddr = (long)pc;
+ if (KSEGX(vaddr) == CKSEG0 || KSEGX(vaddr) == CKSEG1)
+ address = CPHYSADDR(vaddr);
+ else {
+ /* Peek at what physical address the CPU used. */
+ asid = read_c0_entryhi();
+ entryhi = asid & (PAGE_SIZE - 1);
+ entryhi |= vaddr & ~(PAGE_SIZE - 1);
+ write_c0_entryhi(entryhi);
+ BARRIER;
+ tlb_probe();
+ /* No need to check for presence. */
+ tlb_read();
+ entrylo = read_c0_entrylo0();
+ write_c0_entryhi(asid);
+ offset = vaddr & (PAGE_SIZE - 1);
+ address = (entrylo & ~(PAGE_SIZE - 1)) | offset;
+ }
+ }
+
+ /* Treat low 256MB as memory, high -- as I/O. */
+ if (address < 0x10000000) {
+ cycle = mreadstr;
+ event = paritystr;
+ } else {
+ cycle = invoker ? writestr : readstr;
+ event = timestr;
+ }
+
+ if (is_fixup)
+ action = MIPS_BE_FIXUP;
+
+ if (action != MIPS_BE_FIXUP)
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
+ kind, agent, cycle, event, address);
+
+ return action;
+}
+
+int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ return dec_kn01_be_backend(regs, is_fixup, 0);
+}
+
+irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ struct pt_regs *regs = get_irq_regs();
+ int action;
+
+ if (!(*csr & KN01_CSR_MEMERR))
+ return IRQ_NONE; /* Must have been video. */
+
+ action = dec_kn01_be_backend(regs, 0, 1);
+
+ if (action == MIPS_BE_DISCARD)
+ return IRQ_HANDLED;
+
+ /*
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
+ *
+ * The interrupt is asynchronously delivered thus EPC and RA
+ * may be irrelevant, but are printed for a reference.
+ */
+ printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
+ regs->cp0_epc, regs->regs[31]);
+ die("Unrecoverable bus error", regs);
+}
+
+
+void __init dec_kn01_be_init(void)
+{
+ volatile u16 *csr = (void *)CKSEG1ADDR(KN01_SLOT_BASE + KN01_CSR);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&kn01_lock, flags);
+
+ /* Preset write-only bits of the Control Register cache. */
+ cached_kn01_csr = *csr;
+ cached_kn01_csr &= KN01_CSR_STATUS | KN01_CSR_PARDIS | KN01_CSR_TXDIS;
+ cached_kn01_csr |= KN01_CSR_LEDS;
+
+ /* Enable parity error detection. */
+ cached_kn01_csr &= ~KN01_CSR_PARDIS;
+ *csr = cached_kn01_csr;
+ iob();
+
+ raw_spin_unlock_irqrestore(&kn01_lock, flags);
+
+ /* Clear any leftover errors from the firmware. */
+ dec_kn01_be_ack();
+}
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
new file mode 100644
index 00000000..37199f74
--- /dev/null
+++ b/arch/mips/dec/kn02-irq.c
@@ -0,0 +1,79 @@
+/*
+ * DECstation 5000/200 (KN02) Control and Status Register
+ * interrupts.
+ *
+ * Copyright (c) 2002, 2003, 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/dec/kn02.h>
+
+
+/*
+ * Bits 7:0 of the Control Register are write-only -- the
+ * corresponding bits of the Status Register have a different
+ * meaning. Hence we use a cache. It speeds up things a bit
+ * as well.
+ *
+ * There is no default value -- it has to be initialized.
+ */
+u32 cached_kn02_csr;
+
+static int kn02_irq_base;
+
+static void unmask_kn02_irq(struct irq_data *d)
+{
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
+
+ cached_kn02_csr |= (1 << (d->irq - kn02_irq_base + 16));
+ *csr = cached_kn02_csr;
+}
+
+static void mask_kn02_irq(struct irq_data *d)
+{
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
+
+ cached_kn02_csr &= ~(1 << (d->irq - kn02_irq_base + 16));
+ *csr = cached_kn02_csr;
+}
+
+static void ack_kn02_irq(struct irq_data *d)
+{
+ mask_kn02_irq(d);
+ iob();
+}
+
+static struct irq_chip kn02_irq_type = {
+ .name = "KN02-CSR",
+ .irq_ack = ack_kn02_irq,
+ .irq_mask = mask_kn02_irq,
+ .irq_mask_ack = ack_kn02_irq,
+ .irq_unmask = unmask_kn02_irq,
+};
+
+void __init init_kn02_irqs(int base)
+{
+ volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE +
+ KN02_CSR);
+ int i;
+
+ /* Mask interrupts. */
+ cached_kn02_csr &= ~KN02_CSR_IOINTEN;
+ *csr = cached_kn02_csr;
+ iob();
+
+ for (i = base; i < base + KN02_IRQ_LINES; i++)
+ irq_set_chip_and_handler(i, &kn02_irq_type, handle_level_irq);
+
+ kn02_irq_base = base;
+}
diff --git a/arch/mips/dec/kn02xa-berr.c b/arch/mips/dec/kn02xa-berr.c
new file mode 100644
index 00000000..07ca5405
--- /dev/null
+++ b/arch/mips/dec/kn02xa-berr.c
@@ -0,0 +1,139 @@
+/*
+ * Bus error event handling code for 5000-series systems equipped
+ * with parity error detection logic, i.e. DECstation/DECsystem
+ * 5000/120, /125, /133 (KN02-BA), 5000/150 (KN04-BA) and Personal
+ * DECstation/DECsystem 5000/20, /25, /33 (KN02-CA), 5000/50
+ * (KN04-CA) systems.
+ *
+ * Copyright (c) 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/irq_regs.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+#include <asm/dec/kn02ca.h>
+#include <asm/dec/kn02xa.h>
+#include <asm/dec/kn05.h>
+
+static inline void dec_kn02xa_be_ack(void)
+{
+ volatile u32 *mer = (void *)CKSEG1ADDR(KN02XA_MER);
+ volatile u32 *mem_intr = (void *)CKSEG1ADDR(KN02XA_MEM_INTR);
+
+ *mer = KN02CA_MER_INTR; /* Clear errors; keep the ARC IRQ. */
+ *mem_intr = 0; /* Any write clears the bus IRQ. */
+ iob();
+}
+
+static int dec_kn02xa_be_backend(struct pt_regs *regs, int is_fixup,
+ int invoker)
+{
+ volatile u32 *kn02xa_mer = (void *)CKSEG1ADDR(KN02XA_MER);
+ volatile u32 *kn02xa_ear = (void *)CKSEG1ADDR(KN02XA_EAR);
+
+ static const char excstr[] = "exception";
+ static const char intstr[] = "interrupt";
+ static const char cpustr[] = "CPU";
+ static const char mreadstr[] = "memory read";
+ static const char readstr[] = "read";
+ static const char writestr[] = "write";
+ static const char timestr[] = "timeout";
+ static const char paritystr[] = "parity error";
+ static const char lanestat[][4] = { " OK", "BAD" };
+
+ const char *kind, *agent, *cycle, *event;
+ unsigned long address;
+
+ u32 mer = *kn02xa_mer;
+ u32 ear = *kn02xa_ear;
+ int action = MIPS_BE_FATAL;
+
+ /* Ack ASAP, so that any subsequent errors get caught. */
+ dec_kn02xa_be_ack();
+
+ kind = invoker ? intstr : excstr;
+
+ /* No DMA errors? */
+ agent = cpustr;
+
+ address = ear & KN02XA_EAR_ADDRESS;
+
+ /* Low 256MB is decoded as memory, high -- as TC. */
+ if (address < 0x10000000) {
+ cycle = mreadstr;
+ event = paritystr;
+ } else {
+ cycle = invoker ? writestr : readstr;
+ event = timestr;
+ }
+
+ if (is_fixup)
+ action = MIPS_BE_FIXUP;
+
+ if (action != MIPS_BE_FIXUP)
+ printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
+ kind, agent, cycle, event, address);
+
+ if (action != MIPS_BE_FIXUP && address < 0x10000000)
+ printk(KERN_ALERT " Byte lane status %#3x -- "
+ "#3: %s, #2: %s, #1: %s, #0: %s\n",
+ (mer & KN02XA_MER_BYTERR) >> 8,
+ lanestat[(mer & KN02XA_MER_BYTERR_3) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_2) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_1) != 0],
+ lanestat[(mer & KN02XA_MER_BYTERR_0) != 0]);
+
+ return action;
+}
+
+int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ return dec_kn02xa_be_backend(regs, is_fixup, 0);
+}
+
+irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id)
+{
+ struct pt_regs *regs = get_irq_regs();
+ int action = dec_kn02xa_be_backend(regs, 0, 1);
+
+ if (action == MIPS_BE_DISCARD)
+ return IRQ_HANDLED;
+
+ /*
+ * FIXME: Find the affected processes and kill them, otherwise
+ * we must die.
+ *
+ * The interrupt is asynchronously delivered thus EPC and RA
+ * may be irrelevant, but are printed for a reference.
+ */
+ printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n",
+ regs->cp0_epc, regs->regs[31]);
+ die("Unrecoverable bus error", regs);
+}
+
+
+void __init dec_kn02xa_be_init(void)
+{
+ volatile u32 *mbcs = (void *)CKSEG1ADDR(KN4K_SLOT_BASE + KN4K_MB_CSR);
+
+ /* For KN04 we need to make sure EE (?) is enabled in the MB. */
+ if (current_cpu_type() == CPU_R4000SC)
+ *mbcs |= KN4K_MB_CSR_EE;
+ fast_iob();
+
+ /* Clear any leftover errors from the firmware. */
+ dec_kn02xa_be_ack();
+}
diff --git a/arch/mips/dec/prom/Makefile b/arch/mips/dec/prom/Makefile
new file mode 100644
index 00000000..064ae7a7
--- /dev/null
+++ b/arch/mips/dec/prom/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the DECstation prom monitor library routines
+# under Linux.
+#
+
+lib-y += init.o memory.o cmdline.o identify.o console.o
+
+lib-$(CONFIG_32BIT) += locore.o
+lib-$(CONFIG_64BIT) += call_o32.o
diff --git a/arch/mips/dec/prom/call_o32.S b/arch/mips/dec/prom/call_o32.S
new file mode 100644
index 00000000..8c849815
--- /dev/null
+++ b/arch/mips/dec/prom/call_o32.S
@@ -0,0 +1,89 @@
+/*
+ * O32 interface for the 64 (or N32) ABI.
+ *
+ * Copyright (C) 2002 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/* Maximum number of arguments supported. Must be even! */
+#define O32_ARGC 32
+/* Number of static registers we save. */
+#define O32_STATC 11
+/* Frame size for both of the above. */
+#define O32_FRAMESZ (4 * O32_ARGC + SZREG * O32_STATC)
+
+ .text
+
+/*
+ * O32 function call dispatcher, for interfacing 32-bit ROM routines.
+ *
+ * The standard 64 (N32) calling sequence is supported, with a0
+ * holding a function pointer, a1-a7 -- its first seven arguments
+ * and the stack -- remaining ones (up to O32_ARGC, including a1-a7).
+ * Static registers, gp and fp are preserved, v0 holds a result.
+ * This code relies on the called o32 function for sp and ra
+ * restoration and thus both this dispatcher and the current stack
+ * have to be placed in a KSEGx (or KUSEG) address space. Any
+ * pointers passed have to point to addresses within one of these
+ * spaces as well.
+ */
+NESTED(call_o32, O32_FRAMESZ, ra)
+ REG_SUBU sp,O32_FRAMESZ
+
+ REG_S ra,O32_FRAMESZ-1*SZREG(sp)
+ REG_S fp,O32_FRAMESZ-2*SZREG(sp)
+ REG_S gp,O32_FRAMESZ-3*SZREG(sp)
+ REG_S s7,O32_FRAMESZ-4*SZREG(sp)
+ REG_S s6,O32_FRAMESZ-5*SZREG(sp)
+ REG_S s5,O32_FRAMESZ-6*SZREG(sp)
+ REG_S s4,O32_FRAMESZ-7*SZREG(sp)
+ REG_S s3,O32_FRAMESZ-8*SZREG(sp)
+ REG_S s2,O32_FRAMESZ-9*SZREG(sp)
+ REG_S s1,O32_FRAMESZ-10*SZREG(sp)
+ REG_S s0,O32_FRAMESZ-11*SZREG(sp)
+
+ move jp,a0
+
+ sll a0,a1,zero
+ sll a1,a2,zero
+ sll a2,a3,zero
+ sll a3,a4,zero
+ sw a5,0x10(sp)
+ sw a6,0x14(sp)
+ sw a7,0x18(sp)
+
+ PTR_LA t0,O32_FRAMESZ(sp)
+ PTR_LA t1,0x1c(sp)
+ li t2,O32_ARGC-7
+1:
+ lw t3,(t0)
+ REG_ADDU t0,SZREG
+ sw t3,(t1)
+ REG_SUBU t2,1
+ REG_ADDU t1,4
+ bnez t2,1b
+
+ jalr jp
+
+ REG_L s0,O32_FRAMESZ-11*SZREG(sp)
+ REG_L s1,O32_FRAMESZ-10*SZREG(sp)
+ REG_L s2,O32_FRAMESZ-9*SZREG(sp)
+ REG_L s3,O32_FRAMESZ-8*SZREG(sp)
+ REG_L s4,O32_FRAMESZ-7*SZREG(sp)
+ REG_L s5,O32_FRAMESZ-6*SZREG(sp)
+ REG_L s6,O32_FRAMESZ-5*SZREG(sp)
+ REG_L s7,O32_FRAMESZ-4*SZREG(sp)
+ REG_L gp,O32_FRAMESZ-3*SZREG(sp)
+ REG_L fp,O32_FRAMESZ-2*SZREG(sp)
+ REG_L ra,O32_FRAMESZ-1*SZREG(sp)
+
+ REG_ADDU sp,O32_FRAMESZ
+ jr ra
+END(call_o32)
diff --git a/arch/mips/dec/prom/cmdline.c b/arch/mips/dec/prom/cmdline.c
new file mode 100644
index 00000000..c3490beb
--- /dev/null
+++ b/arch/mips/dec/prom/cmdline.c
@@ -0,0 +1,39 @@
+/*
+ * cmdline.c: read the command line passed to us by the PROM.
+ *
+ * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002, 2004 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+#include <asm/dec/prom.h>
+
+#undef PROM_DEBUG
+
+void __init prom_init_cmdline(s32 argc, s32 *argv, u32 magic)
+{
+ char *arg;
+ int start_arg, i;
+
+ /*
+ * collect args and prepare cmd_line
+ */
+ if (!prom_is_rex(magic))
+ start_arg = 1;
+ else
+ start_arg = 2;
+ for (i = start_arg; i < argc; i++) {
+ arg = (void *)(long)(argv[i]);
+ strcat(arcs_cmdline, arg);
+ if (i < (argc - 1))
+ strcat(arcs_cmdline, " ");
+ }
+
+#ifdef PROM_DEBUG
+ printk("arcs_cmdline: %s\n", &(arcs_cmdline[0]));
+#endif
+}
diff --git a/arch/mips/dec/prom/console.c b/arch/mips/dec/prom/console.c
new file mode 100644
index 00000000..caa6e047
--- /dev/null
+++ b/arch/mips/dec/prom/console.c
@@ -0,0 +1,45 @@
+/*
+ * DECstation PROM-based early console support.
+ *
+ * Copyright (C) 2004, 2007 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/dec/prom.h>
+
+static void __init prom_console_write(struct console *con, const char *s,
+ unsigned int c)
+{
+ char buf[81];
+ unsigned int chunk = sizeof(buf) - 1;
+
+ while (c > 0) {
+ if (chunk > c)
+ chunk = c;
+ memcpy(buf, s, chunk);
+ buf[chunk] = '\0';
+ prom_printf("%s", buf);
+ s += chunk;
+ c -= chunk;
+ }
+}
+
+static struct console promcons __initdata = {
+ .name = "prom",
+ .write = prom_console_write,
+ .flags = CON_BOOT | CON_PRINTBUFFER,
+ .index = -1,
+};
+
+void __init register_prom_console(void)
+{
+ register_console(&promcons);
+}
diff --git a/arch/mips/dec/prom/dectypes.h b/arch/mips/dec/prom/dectypes.h
new file mode 100644
index 00000000..707b6f1f
--- /dev/null
+++ b/arch/mips/dec/prom/dectypes.h
@@ -0,0 +1,14 @@
+#ifndef DECTYPES
+#define DECTYPES
+
+#define DS2100_3100 1 /* DS2100/3100 Pmax */
+#define DS5000_200 2 /* DS5000/200 3max */
+#define DS5000_1XX 3 /* DS5000/1xx kmin */
+#define DS5000_2X0 4 /* DS5000/2x0 3max+ */
+#define DS5800 5 /* DS5800 Isis */
+#define DS5400 6 /* DS5400 MIPSfair */
+#define DS5000_XX 7 /* DS5000/xx maxine */
+#define DS5500 11 /* DS5500 MIPSfair-2 */
+#define DS5100 12 /* DS5100 MIPSmate */
+
+#endif
diff --git a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c
new file mode 100644
index 00000000..95e26f4b
--- /dev/null
+++ b/arch/mips/dec/prom/identify.c
@@ -0,0 +1,186 @@
+/*
+ * identify.c: machine identification code.
+ *
+ * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
+ * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/kn01.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn02ba.h>
+#include <asm/dec/kn02ca.h>
+#include <asm/dec/kn03.h>
+#include <asm/dec/kn230.h>
+#include <asm/dec/prom.h>
+#include <asm/dec/system.h>
+
+#include "dectypes.h"
+
+static const char *dec_system_strings[] = {
+ [MACH_DSUNKNOWN] "unknown DECstation",
+ [MACH_DS23100] "DECstation 2100/3100",
+ [MACH_DS5100] "DECsystem 5100",
+ [MACH_DS5000_200] "DECstation 5000/200",
+ [MACH_DS5000_1XX] "DECstation 5000/1xx",
+ [MACH_DS5000_XX] "Personal DECstation 5000/xx",
+ [MACH_DS5000_2X0] "DECstation 5000/2x0",
+ [MACH_DS5400] "DECsystem 5400",
+ [MACH_DS5500] "DECsystem 5500",
+ [MACH_DS5800] "DECsystem 5800",
+ [MACH_DS5900] "DECsystem 5900",
+};
+
+const char *get_system_type(void)
+{
+#define STR_BUF_LEN 64
+ static char system[STR_BUF_LEN];
+ static int called = 0;
+
+ if (called == 0) {
+ called = 1;
+ snprintf(system, STR_BUF_LEN, "Digital %s",
+ dec_system_strings[mips_machtype]);
+ }
+
+ return system;
+}
+
+
+/*
+ * Setup essential system-specific memory addresses. We need them
+ * early. Semantically the functions belong to prom/init.c, but they
+ * are compact enough we want them inlined. --macro
+ */
+volatile u8 *dec_rtc_base;
+
+EXPORT_SYMBOL(dec_rtc_base);
+
+static inline void prom_init_kn01(void)
+{
+ dec_kn_slot_base = KN01_SLOT_BASE;
+ dec_kn_slot_size = KN01_SLOT_SIZE;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
+}
+
+static inline void prom_init_kn230(void)
+{
+ dec_kn_slot_base = KN01_SLOT_BASE;
+ dec_kn_slot_size = KN01_SLOT_SIZE;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN01_RTC);
+}
+
+static inline void prom_init_kn02(void)
+{
+ dec_kn_slot_base = KN02_SLOT_BASE;
+ dec_kn_slot_size = KN02_SLOT_SIZE;
+ dec_tc_bus = 1;
+
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + KN02_RTC);
+}
+
+static inline void prom_init_kn02xa(void)
+{
+ dec_kn_slot_base = KN02XA_SLOT_BASE;
+ dec_kn_slot_size = IOASIC_SLOT_SIZE;
+ dec_tc_bus = 1;
+
+ ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
+}
+
+static inline void prom_init_kn03(void)
+{
+ dec_kn_slot_base = KN03_SLOT_BASE;
+ dec_kn_slot_size = IOASIC_SLOT_SIZE;
+ dec_tc_bus = 1;
+
+ ioasic_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_IOCTL);
+ dec_rtc_base = (void *)CKSEG1ADDR(dec_kn_slot_base + IOASIC_TOY);
+}
+
+
+void __init prom_identify_arch(u32 magic)
+{
+ unsigned char dec_cpunum, dec_firmrev, dec_etc, dec_systype;
+ u32 dec_sysid;
+
+ if (!prom_is_rex(magic)) {
+ dec_sysid = simple_strtoul(prom_getenv("systype"),
+ (char **)0, 0);
+ } else {
+ dec_sysid = rex_getsysid();
+ if (dec_sysid == 0) {
+ printk("Zero sysid returned from PROM! "
+ "Assuming a PMAX-like machine.\n");
+ dec_sysid = 1;
+ }
+ }
+
+ dec_cpunum = (dec_sysid & 0xff000000) >> 24;
+ dec_systype = (dec_sysid & 0xff0000) >> 16;
+ dec_firmrev = (dec_sysid & 0xff00) >> 8;
+ dec_etc = dec_sysid & 0xff;
+
+ /*
+ * FIXME: This may not be an exhaustive list of DECStations/Servers!
+ * Put all model-specific initialisation calls here.
+ */
+ switch (dec_systype) {
+ case DS2100_3100:
+ mips_machtype = MACH_DS23100;
+ prom_init_kn01();
+ break;
+ case DS5100: /* DS5100 MIPSMATE */
+ mips_machtype = MACH_DS5100;
+ prom_init_kn230();
+ break;
+ case DS5000_200: /* DS5000 3max */
+ mips_machtype = MACH_DS5000_200;
+ prom_init_kn02();
+ break;
+ case DS5000_1XX: /* DS5000/100 3min */
+ mips_machtype = MACH_DS5000_1XX;
+ prom_init_kn02xa();
+ break;
+ case DS5000_2X0: /* DS5000/240 3max+ or DS5900 bigmax */
+ mips_machtype = MACH_DS5000_2X0;
+ prom_init_kn03();
+ if (!(ioasic_read(IO_REG_SIR) & KN03_IO_INR_3MAXP))
+ mips_machtype = MACH_DS5900;
+ break;
+ case DS5000_XX: /* Personal DS5000/xx maxine */
+ mips_machtype = MACH_DS5000_XX;
+ prom_init_kn02xa();
+ break;
+ case DS5800: /* DS5800 Isis */
+ mips_machtype = MACH_DS5800;
+ break;
+ case DS5400: /* DS5400 MIPSfair */
+ mips_machtype = MACH_DS5400;
+ break;
+ case DS5500: /* DS5500 MIPSfair-2 */
+ mips_machtype = MACH_DS5500;
+ break;
+ default:
+ mips_machtype = MACH_DSUNKNOWN;
+ break;
+ }
+
+ if (mips_machtype == MACH_DSUNKNOWN)
+ printk("This is an %s, id is %x\n",
+ dec_system_strings[mips_machtype], dec_systype);
+ else
+ printk("This is a %s\n", dec_system_strings[mips_machtype]);
+}
diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
new file mode 100644
index 00000000..93f1239a
--- /dev/null
+++ b/arch/mips/dec/prom/init.c
@@ -0,0 +1,135 @@
+/*
+ * init.c: PROM library initialisation code.
+ *
+ * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002, 2004 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/smp.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+
+#include <asm/dec/prom.h>
+
+
+int (*__rex_bootinit)(void);
+int (*__rex_bootread)(void);
+int (*__rex_getbitmap)(memmap *);
+unsigned long *(*__rex_slot_address)(int);
+void *(*__rex_gettcinfo)(void);
+int (*__rex_getsysid)(void);
+void (*__rex_clear_cache)(void);
+
+int (*__prom_getchar)(void);
+char *(*__prom_getenv)(char *);
+int (*__prom_printf)(char *, ...);
+
+int (*__pmax_open)(char*, int);
+int (*__pmax_lseek)(int, long, int);
+int (*__pmax_read)(int, void *, int);
+int (*__pmax_close)(int);
+
+
+/*
+ * Detect which PROM the DECSTATION has, and set the callback vectors
+ * appropriately.
+ */
+void __init which_prom(s32 magic, s32 *prom_vec)
+{
+ /*
+ * No sign of the REX PROM's magic number means we assume a non-REX
+ * machine (i.e. we're on a DS2100/3100, DS5100 or DS5000/2xx)
+ */
+ if (prom_is_rex(magic)) {
+ /*
+ * Set up prom abstraction structure with REX entry points.
+ */
+ __rex_bootinit =
+ (void *)(long)*(prom_vec + REX_PROM_BOOTINIT);
+ __rex_bootread =
+ (void *)(long)*(prom_vec + REX_PROM_BOOTREAD);
+ __rex_getbitmap =
+ (void *)(long)*(prom_vec + REX_PROM_GETBITMAP);
+ __prom_getchar =
+ (void *)(long)*(prom_vec + REX_PROM_GETCHAR);
+ __prom_getenv =
+ (void *)(long)*(prom_vec + REX_PROM_GETENV);
+ __rex_getsysid =
+ (void *)(long)*(prom_vec + REX_PROM_GETSYSID);
+ __rex_gettcinfo =
+ (void *)(long)*(prom_vec + REX_PROM_GETTCINFO);
+ __prom_printf =
+ (void *)(long)*(prom_vec + REX_PROM_PRINTF);
+ __rex_slot_address =
+ (void *)(long)*(prom_vec + REX_PROM_SLOTADDR);
+ __rex_clear_cache =
+ (void *)(long)*(prom_vec + REX_PROM_CLEARCACHE);
+ } else {
+ /*
+ * Set up prom abstraction structure with non-REX entry points.
+ */
+ __prom_getchar = (void *)PMAX_PROM_GETCHAR;
+ __prom_getenv = (void *)PMAX_PROM_GETENV;
+ __prom_printf = (void *)PMAX_PROM_PRINTF;
+ __pmax_open = (void *)PMAX_PROM_OPEN;
+ __pmax_lseek = (void *)PMAX_PROM_LSEEK;
+ __pmax_read = (void *)PMAX_PROM_READ;
+ __pmax_close = (void *)PMAX_PROM_CLOSE;
+ }
+}
+
+void __init prom_init(void)
+{
+ extern void dec_machine_halt(void);
+ static char cpu_msg[] __initdata =
+ "Sorry, this kernel is compiled for a wrong CPU type!\n";
+ s32 argc = fw_arg0;
+ s32 *argv = (void *)fw_arg1;
+ u32 magic = fw_arg2;
+ s32 *prom_vec = (void *)fw_arg3;
+
+ /*
+ * Determine which PROM we have
+ * (and therefore which machine we're on!)
+ */
+ which_prom(magic, prom_vec);
+
+ if (prom_is_rex(magic))
+ rex_clear_cache();
+
+ /* Register the early console. */
+ register_prom_console();
+
+ /* Were we compiled with the right CPU option? */
+#if defined(CONFIG_CPU_R3000)
+ if ((current_cpu_type() == CPU_R4000SC) ||
+ (current_cpu_type() == CPU_R4400SC)) {
+ static char r4k_msg[] __initdata =
+ "Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
+ printk(cpu_msg);
+ printk(r4k_msg);
+ dec_machine_halt();
+ }
+#endif
+
+#if defined(CONFIG_CPU_R4X00)
+ if ((current_cpu_type() == CPU_R3000) ||
+ (current_cpu_type() == CPU_R3000A)) {
+ static char r3k_msg[] __initdata =
+ "Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
+ printk(cpu_msg);
+ printk(r3k_msg);
+ dec_machine_halt();
+ }
+#endif
+
+ prom_meminit(magic);
+ prom_identify_arch(magic);
+ prom_init_cmdline(argc, argv, magic);
+}
diff --git a/arch/mips/dec/prom/locore.S b/arch/mips/dec/prom/locore.S
new file mode 100644
index 00000000..f72b5741
--- /dev/null
+++ b/arch/mips/dec/prom/locore.S
@@ -0,0 +1,29 @@
+/*
+ * locore.S
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+ .text
+
+/*
+ * Simple general exception handling routine. This one is used for the
+ * Memory sizing routine for pmax machines. HK
+ */
+
+NESTED(genexcept_early, 0, sp)
+ .set noat
+ .set noreorder
+
+ mfc0 k0, CP0_STATUS
+ la k1, mem_err
+
+ sw k0, 0(k1)
+
+ mfc0 k0, CP0_EPC
+ nop
+ addiu k0, 4 # skip the causing instruction
+ jr k0
+ rfe
+END(genexcept_early)
diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c
new file mode 100644
index 00000000..e95ff305
--- /dev/null
+++ b/arch/mips/dec/prom/memory.c
@@ -0,0 +1,118 @@
+/*
+ * memory.c: memory initialisation code.
+ *
+ * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/dec/machtype.h>
+#include <asm/dec/prom.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+
+volatile unsigned long mem_err; /* So we know an error occurred */
+
+/*
+ * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
+ * off the end of real memory. Only suitable for the 2100/3100's (PMAX).
+ */
+
+#define CHUNK_SIZE 0x400000
+
+static inline void pmax_setup_memory_region(void)
+{
+ volatile unsigned char *memory_page, dummy;
+ char old_handler[0x80];
+ extern char genexcept_early;
+
+ /* Install exception handler */
+ memcpy(&old_handler, (void *)(CKSEG0 + 0x80), 0x80);
+ memcpy((void *)(CKSEG0 + 0x80), &genexcept_early, 0x80);
+
+ /* read unmapped and uncached (KSEG1)
+ * DECstations have at least 4MB RAM
+ * Assume less than 480MB of RAM, as this is max for 5000/2xx
+ * FIXME this should be replaced by the first free page!
+ */
+ for (memory_page = (unsigned char *)CKSEG1 + CHUNK_SIZE;
+ mem_err == 0 && memory_page < (unsigned char *)CKSEG1 + 0x1e00000;
+ memory_page += CHUNK_SIZE) {
+ dummy = *memory_page;
+ }
+ memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80);
+
+ add_memory_region(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE,
+ BOOT_MEM_RAM);
+}
+
+/*
+ * Use the REX prom calls to get hold of the memory bitmap, and thence
+ * determine memory size.
+ */
+static inline void rex_setup_memory_region(void)
+{
+ int i, bitmap_size;
+ unsigned long mem_start = 0, mem_size = 0;
+ memmap *bm;
+
+ /* some free 64k */
+ bm = (memmap *)CKSEG0ADDR(0x28000);
+
+ bitmap_size = rex_getbitmap(bm);
+
+ for (i = 0; i < bitmap_size; i++) {
+ /* FIXME: very simplistically only add full sets of pages */
+ if (bm->bitmap[i] == 0xff)
+ mem_size += (8 * bm->pagesize);
+ else if (!mem_size)
+ mem_start += (8 * bm->pagesize);
+ else {
+ add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
+ mem_start += mem_size + (8 * bm->pagesize);
+ mem_size = 0;
+ }
+ }
+ if (mem_size)
+ add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
+}
+
+void __init prom_meminit(u32 magic)
+{
+ if (!prom_is_rex(magic))
+ pmax_setup_memory_region();
+ else
+ rex_setup_memory_region();
+}
+
+void __init prom_free_prom_memory(void)
+{
+ unsigned long end;
+
+ /*
+ * Free everything below the kernel itself but leave
+ * the first page reserved for the exception handlers.
+ */
+
+#if defined(CONFIG_DECLANCE) || defined(CONFIG_DECLANCE_MODULE)
+ /*
+ * Leave 128 KB reserved for Lance memory for
+ * IOASIC DECstations.
+ *
+ * XXX: save this address for use in dec_lance.c?
+ */
+ if (IOASIC)
+ end = __pa(&_text) - 0x00020000;
+ else
+#endif
+ end = __pa(&_text);
+
+ free_init_pages("unused PROM memory", PAGE_SIZE, end);
+}
diff --git a/arch/mips/dec/promcon.c b/arch/mips/dec/promcon.c
new file mode 100644
index 00000000..c239c25b
--- /dev/null
+++ b/arch/mips/dec/promcon.c
@@ -0,0 +1,54 @@
+/*
+ * Wrap-around code for a console using the
+ * DECstation PROM io-routines.
+ *
+ * Copyright (c) 1998 Harald Koerfgen
+ */
+
+#include <linux/tty.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+
+#include <asm/dec/prom.h>
+
+static void prom_console_write(struct console *co, const char *s,
+ unsigned count)
+{
+ unsigned i;
+
+ /*
+ * Now, do each character
+ */
+ for (i = 0; i < count; i++) {
+ if (*s == 10)
+ prom_printf("%c", 13);
+ prom_printf("%c", *s++);
+ }
+}
+
+static int __init prom_console_setup(struct console *co, char *options)
+{
+ return 0;
+}
+
+static struct console sercons = {
+ .name = "ttyS",
+ .write = prom_console_write,
+ .setup = prom_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+/*
+ * Register console.
+ */
+
+static int __init prom_console_init(void)
+{
+ register_console(&sercons);
+
+ return 0;
+}
+console_initcall(prom_console_init);
diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c
new file mode 100644
index 00000000..c15a8790
--- /dev/null
+++ b/arch/mips/dec/reset.c
@@ -0,0 +1,40 @@
+/*
+ * Reset a DECstation machine.
+ *
+ * Copyright (C) 199x the Anonymous
+ * Copyright (C) 2001, 2002, 2003 Maciej W. Rozycki
+ */
+#include <linux/interrupt.h>
+#include <linux/linkage.h>
+
+#include <asm/addrspace.h>
+
+typedef void __noreturn (* noret_func_t)(void);
+
+static inline void __noreturn back_to_prom(void)
+{
+ noret_func_t func = (void *)CKSEG1ADDR(0x1fc00000);
+
+ func();
+}
+
+void __noreturn dec_machine_restart(char *command)
+{
+ back_to_prom();
+}
+
+void __noreturn dec_machine_halt(void)
+{
+ back_to_prom();
+}
+
+void __noreturn dec_machine_power_off(void)
+{
+ /* DECstations don't have a software power switch */
+ back_to_prom();
+}
+
+irqreturn_t dec_intr_halt(int irq, void *dev_id)
+{
+ dec_machine_halt();
+}
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
new file mode 100644
index 00000000..fa45e924
--- /dev/null
+++ b/arch/mips/dec/setup.c
@@ -0,0 +1,768 @@
+/*
+ * System-specific setup, especially interrupts.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki
+ */
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/pm.h>
+#include <linux/irq.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+#include <asm/wbflush.h>
+
+#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+#include <asm/dec/ioasic_ints.h>
+#include <asm/dec/kn01.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn02ba.h>
+#include <asm/dec/kn02ca.h>
+#include <asm/dec/kn03.h>
+#include <asm/dec/kn230.h>
+#include <asm/dec/system.h>
+
+
+extern void dec_machine_restart(char *command);
+extern void dec_machine_halt(void);
+extern void dec_machine_power_off(void);
+extern irqreturn_t dec_intr_halt(int irq, void *dev_id);
+
+unsigned long dec_kn_slot_base, dec_kn_slot_size;
+
+EXPORT_SYMBOL(dec_kn_slot_base);
+EXPORT_SYMBOL(dec_kn_slot_size);
+
+int dec_tc_bus;
+
+DEFINE_SPINLOCK(ioasic_ssr_lock);
+
+volatile u32 *ioasic_base;
+
+EXPORT_SYMBOL(ioasic_base);
+
+/*
+ * IRQ routing and priority tables. Priorites are set as follows:
+ *
+ * KN01 KN230 KN02 KN02-BA KN02-CA KN03
+ *
+ * MEMORY CPU CPU CPU ASIC CPU CPU
+ * RTC CPU CPU CPU ASIC CPU CPU
+ * DMA - - - ASIC ASIC ASIC
+ * SERIAL0 CPU CPU CSR ASIC ASIC ASIC
+ * SERIAL1 - - - ASIC - ASIC
+ * SCSI CPU CPU CSR ASIC ASIC ASIC
+ * ETHERNET CPU * CSR ASIC ASIC ASIC
+ * other - - - ASIC - -
+ * TC2 - - CSR CPU ASIC ASIC
+ * TC1 - - CSR CPU ASIC ASIC
+ * TC0 - - CSR CPU ASIC ASIC
+ * other - CPU - CPU ASIC ASIC
+ * other - - - - CPU CPU
+ *
+ * * -- shared with SCSI
+ */
+
+int dec_interrupt[DEC_NR_INTS] = {
+ [0 ... DEC_NR_INTS - 1] = -1
+};
+
+EXPORT_SYMBOL(dec_interrupt);
+
+int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2] = {
+ { { .i = ~0 }, { .p = dec_intr_unimplemented } },
+};
+int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2] = {
+ { { .i = ~0 }, { .p = asic_intr_unimplemented } },
+};
+int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU);
+
+static struct irqaction ioirq = {
+ .handler = no_action,
+ .name = "cascade",
+};
+static struct irqaction fpuirq = {
+ .handler = no_action,
+ .name = "fpu",
+};
+
+static struct irqaction busirq = {
+ .flags = IRQF_DISABLED,
+ .name = "bus error",
+};
+
+static struct irqaction haltirq = {
+ .handler = dec_intr_halt,
+ .name = "halt",
+};
+
+
+/*
+ * Bus error (DBE/IBE exceptions and bus interrupts) handling setup.
+ */
+static void __init dec_be_init(void)
+{
+ switch (mips_machtype) {
+ case MACH_DS23100: /* DS2100/DS3100 Pmin/Pmax */
+ board_be_handler = dec_kn01_be_handler;
+ busirq.handler = dec_kn01_be_interrupt;
+ busirq.flags |= IRQF_SHARED;
+ dec_kn01_be_init();
+ break;
+ case MACH_DS5000_1XX: /* DS5000/1xx 3min */
+ case MACH_DS5000_XX: /* DS5000/xx Maxine */
+ board_be_handler = dec_kn02xa_be_handler;
+ busirq.handler = dec_kn02xa_be_interrupt;
+ dec_kn02xa_be_init();
+ break;
+ case MACH_DS5000_200: /* DS5000/200 3max */
+ case MACH_DS5000_2X0: /* DS5000/240 3max+ */
+ case MACH_DS5900: /* DS5900 bigmax */
+ board_be_handler = dec_ecc_be_handler;
+ busirq.handler = dec_ecc_be_interrupt;
+ dec_ecc_be_init();
+ break;
+ }
+}
+
+void __init plat_mem_setup(void)
+{
+ board_be_init = dec_be_init;
+
+ wbflush_setup();
+
+ _machine_restart = dec_machine_restart;
+ _machine_halt = dec_machine_halt;
+ pm_power_off = dec_machine_power_off;
+
+ ioport_resource.start = ~0UL;
+ ioport_resource.end = 0UL;
+}
+
+/*
+ * Machine-specific initialisation for KN01, aka DS2100 (aka Pmin)
+ * or DS3100 (aka Pmax).
+ */
+static int kn01_interrupt[DEC_NR_INTS] __initdata = {
+ [DEC_IRQ_CASCADE] = -1,
+ [DEC_IRQ_AB_RECV] = -1,
+ [DEC_IRQ_AB_XMIT] = -1,
+ [DEC_IRQ_DZ11] = DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11),
+ [DEC_IRQ_ASC] = -1,
+ [DEC_IRQ_FLOPPY] = -1,
+ [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+ [DEC_IRQ_HALT] = -1,
+ [DEC_IRQ_ISDN] = -1,
+ [DEC_IRQ_LANCE] = DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE),
+ [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN01_CPU_INR_BUS),
+ [DEC_IRQ_PSU] = -1,
+ [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC),
+ [DEC_IRQ_SCC0] = -1,
+ [DEC_IRQ_SCC1] = -1,
+ [DEC_IRQ_SII] = DEC_CPU_IRQ_NR(KN01_CPU_INR_SII),
+ [DEC_IRQ_TC0] = -1,
+ [DEC_IRQ_TC1] = -1,
+ [DEC_IRQ_TC2] = -1,
+ [DEC_IRQ_TIMER] = -1,
+ [DEC_IRQ_VIDEO] = DEC_CPU_IRQ_NR(KN01_CPU_INR_VIDEO),
+ [DEC_IRQ_ASC_MERR] = -1,
+ [DEC_IRQ_ASC_ERR] = -1,
+ [DEC_IRQ_ASC_DMA] = -1,
+ [DEC_IRQ_FLOPPY_ERR] = -1,
+ [DEC_IRQ_ISDN_ERR] = -1,
+ [DEC_IRQ_ISDN_RXDMA] = -1,
+ [DEC_IRQ_ISDN_TXDMA] = -1,
+ [DEC_IRQ_LANCE_MERR] = -1,
+ [DEC_IRQ_SCC0A_RXERR] = -1,
+ [DEC_IRQ_SCC0A_RXDMA] = -1,
+ [DEC_IRQ_SCC0A_TXERR] = -1,
+ [DEC_IRQ_SCC0A_TXDMA] = -1,
+ [DEC_IRQ_AB_RXERR] = -1,
+ [DEC_IRQ_AB_RXDMA] = -1,
+ [DEC_IRQ_AB_TXERR] = -1,
+ [DEC_IRQ_AB_TXDMA] = -1,
+ [DEC_IRQ_SCC1A_RXERR] = -1,
+ [DEC_IRQ_SCC1A_RXDMA] = -1,
+ [DEC_IRQ_SCC1A_TXERR] = -1,
+ [DEC_IRQ_SCC1A_TXDMA] = -1,
+};
+
+static int_ptr kn01_cpu_mask_nr_tbl[][2] __initdata = {
+ { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_BUS) },
+ { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_BUS) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_RTC) },
+ { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_DZ11) },
+ { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_SII) },
+ { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_SII) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_LANCE) },
+ { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE) } },
+ { { .i = DEC_CPU_IRQ_ALL },
+ { .p = cpu_all_int } },
+};
+
+static void __init dec_init_kn01(void)
+{
+ /* IRQ routing. */
+ memcpy(&dec_interrupt, &kn01_interrupt,
+ sizeof(kn01_interrupt));
+
+ /* CPU IRQ priorities. */
+ memcpy(&cpu_mask_nr_tbl, &kn01_cpu_mask_nr_tbl,
+ sizeof(kn01_cpu_mask_nr_tbl));
+
+ mips_cpu_irq_init();
+
+} /* dec_init_kn01 */
+
+
+/*
+ * Machine-specific initialisation for KN230, aka DS5100, aka MIPSmate.
+ */
+static int kn230_interrupt[DEC_NR_INTS] __initdata = {
+ [DEC_IRQ_CASCADE] = -1,
+ [DEC_IRQ_AB_RECV] = -1,
+ [DEC_IRQ_AB_XMIT] = -1,
+ [DEC_IRQ_DZ11] = DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11),
+ [DEC_IRQ_ASC] = -1,
+ [DEC_IRQ_FLOPPY] = -1,
+ [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+ [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN230_CPU_INR_HALT),
+ [DEC_IRQ_ISDN] = -1,
+ [DEC_IRQ_LANCE] = DEC_CPU_IRQ_NR(KN230_CPU_INR_LANCE),
+ [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN230_CPU_INR_BUS),
+ [DEC_IRQ_PSU] = -1,
+ [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC),
+ [DEC_IRQ_SCC0] = -1,
+ [DEC_IRQ_SCC1] = -1,
+ [DEC_IRQ_SII] = DEC_CPU_IRQ_NR(KN230_CPU_INR_SII),
+ [DEC_IRQ_TC0] = -1,
+ [DEC_IRQ_TC1] = -1,
+ [DEC_IRQ_TC2] = -1,
+ [DEC_IRQ_TIMER] = -1,
+ [DEC_IRQ_VIDEO] = -1,
+ [DEC_IRQ_ASC_MERR] = -1,
+ [DEC_IRQ_ASC_ERR] = -1,
+ [DEC_IRQ_ASC_DMA] = -1,
+ [DEC_IRQ_FLOPPY_ERR] = -1,
+ [DEC_IRQ_ISDN_ERR] = -1,
+ [DEC_IRQ_ISDN_RXDMA] = -1,
+ [DEC_IRQ_ISDN_TXDMA] = -1,
+ [DEC_IRQ_LANCE_MERR] = -1,
+ [DEC_IRQ_SCC0A_RXERR] = -1,
+ [DEC_IRQ_SCC0A_RXDMA] = -1,
+ [DEC_IRQ_SCC0A_TXERR] = -1,
+ [DEC_IRQ_SCC0A_TXDMA] = -1,
+ [DEC_IRQ_AB_RXERR] = -1,
+ [DEC_IRQ_AB_RXDMA] = -1,
+ [DEC_IRQ_AB_TXERR] = -1,
+ [DEC_IRQ_AB_TXDMA] = -1,
+ [DEC_IRQ_SCC1A_RXERR] = -1,
+ [DEC_IRQ_SCC1A_RXDMA] = -1,
+ [DEC_IRQ_SCC1A_TXERR] = -1,
+ [DEC_IRQ_SCC1A_TXDMA] = -1,
+};
+
+static int_ptr kn230_cpu_mask_nr_tbl[][2] __initdata = {
+ { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_BUS) },
+ { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_BUS) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_RTC) },
+ { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_DZ11) },
+ { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_SII) },
+ { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_SII) } },
+ { { .i = DEC_CPU_IRQ_ALL },
+ { .p = cpu_all_int } },
+};
+
+static void __init dec_init_kn230(void)
+{
+ /* IRQ routing. */
+ memcpy(&dec_interrupt, &kn230_interrupt,
+ sizeof(kn230_interrupt));
+
+ /* CPU IRQ priorities. */
+ memcpy(&cpu_mask_nr_tbl, &kn230_cpu_mask_nr_tbl,
+ sizeof(kn230_cpu_mask_nr_tbl));
+
+ mips_cpu_irq_init();
+
+} /* dec_init_kn230 */
+
+
+/*
+ * Machine-specific initialisation for KN02, aka DS5000/200, aka 3max.
+ */
+static int kn02_interrupt[DEC_NR_INTS] __initdata = {
+ [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN02_CPU_INR_CASCADE),
+ [DEC_IRQ_AB_RECV] = -1,
+ [DEC_IRQ_AB_XMIT] = -1,
+ [DEC_IRQ_DZ11] = KN02_IRQ_NR(KN02_CSR_INR_DZ11),
+ [DEC_IRQ_ASC] = KN02_IRQ_NR(KN02_CSR_INR_ASC),
+ [DEC_IRQ_FLOPPY] = -1,
+ [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+ [DEC_IRQ_HALT] = -1,
+ [DEC_IRQ_ISDN] = -1,
+ [DEC_IRQ_LANCE] = KN02_IRQ_NR(KN02_CSR_INR_LANCE),
+ [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN02_CPU_INR_BUS),
+ [DEC_IRQ_PSU] = -1,
+ [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC),
+ [DEC_IRQ_SCC0] = -1,
+ [DEC_IRQ_SCC1] = -1,
+ [DEC_IRQ_SII] = -1,
+ [DEC_IRQ_TC0] = KN02_IRQ_NR(KN02_CSR_INR_TC0),
+ [DEC_IRQ_TC1] = KN02_IRQ_NR(KN02_CSR_INR_TC1),
+ [DEC_IRQ_TC2] = KN02_IRQ_NR(KN02_CSR_INR_TC2),
+ [DEC_IRQ_TIMER] = -1,
+ [DEC_IRQ_VIDEO] = -1,
+ [DEC_IRQ_ASC_MERR] = -1,
+ [DEC_IRQ_ASC_ERR] = -1,
+ [DEC_IRQ_ASC_DMA] = -1,
+ [DEC_IRQ_FLOPPY_ERR] = -1,
+ [DEC_IRQ_ISDN_ERR] = -1,
+ [DEC_IRQ_ISDN_RXDMA] = -1,
+ [DEC_IRQ_ISDN_TXDMA] = -1,
+ [DEC_IRQ_LANCE_MERR] = -1,
+ [DEC_IRQ_SCC0A_RXERR] = -1,
+ [DEC_IRQ_SCC0A_RXDMA] = -1,
+ [DEC_IRQ_SCC0A_TXERR] = -1,
+ [DEC_IRQ_SCC0A_TXDMA] = -1,
+ [DEC_IRQ_AB_RXERR] = -1,
+ [DEC_IRQ_AB_RXDMA] = -1,
+ [DEC_IRQ_AB_TXERR] = -1,
+ [DEC_IRQ_AB_TXDMA] = -1,
+ [DEC_IRQ_SCC1A_RXERR] = -1,
+ [DEC_IRQ_SCC1A_RXDMA] = -1,
+ [DEC_IRQ_SCC1A_TXERR] = -1,
+ [DEC_IRQ_SCC1A_TXDMA] = -1,
+};
+
+static int_ptr kn02_cpu_mask_nr_tbl[][2] __initdata = {
+ { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_BUS) },
+ { .i = DEC_CPU_IRQ_NR(KN02_CPU_INR_BUS) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_RTC) },
+ { .i = DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_CASCADE) },
+ { .p = kn02_io_int } },
+ { { .i = DEC_CPU_IRQ_ALL },
+ { .p = cpu_all_int } },
+};
+
+static int_ptr kn02_asic_mask_nr_tbl[][2] __initdata = {
+ { { .i = KN02_IRQ_MASK(KN02_CSR_INR_DZ11) },
+ { .i = KN02_IRQ_NR(KN02_CSR_INR_DZ11) } },
+ { { .i = KN02_IRQ_MASK(KN02_CSR_INR_ASC) },
+ { .i = KN02_IRQ_NR(KN02_CSR_INR_ASC) } },
+ { { .i = KN02_IRQ_MASK(KN02_CSR_INR_LANCE) },
+ { .i = KN02_IRQ_NR(KN02_CSR_INR_LANCE) } },
+ { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC2) },
+ { .i = KN02_IRQ_NR(KN02_CSR_INR_TC2) } },
+ { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC1) },
+ { .i = KN02_IRQ_NR(KN02_CSR_INR_TC1) } },
+ { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC0) },
+ { .i = KN02_IRQ_NR(KN02_CSR_INR_TC0) } },
+ { { .i = KN02_IRQ_ALL },
+ { .p = kn02_all_int } },
+};
+
+static void __init dec_init_kn02(void)
+{
+ /* IRQ routing. */
+ memcpy(&dec_interrupt, &kn02_interrupt,
+ sizeof(kn02_interrupt));
+
+ /* CPU IRQ priorities. */
+ memcpy(&cpu_mask_nr_tbl, &kn02_cpu_mask_nr_tbl,
+ sizeof(kn02_cpu_mask_nr_tbl));
+
+ /* KN02 CSR IRQ priorities. */
+ memcpy(&asic_mask_nr_tbl, &kn02_asic_mask_nr_tbl,
+ sizeof(kn02_asic_mask_nr_tbl));
+
+ mips_cpu_irq_init();
+ init_kn02_irqs(KN02_IRQ_BASE);
+
+} /* dec_init_kn02 */
+
+
+/*
+ * Machine-specific initialisation for KN02-BA, aka DS5000/1xx
+ * (xx = 20, 25, 33), aka 3min. Also applies to KN04(-BA), aka
+ * DS5000/150, aka 4min.
+ */
+static int kn02ba_interrupt[DEC_NR_INTS] __initdata = {
+ [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_CASCADE),
+ [DEC_IRQ_AB_RECV] = -1,
+ [DEC_IRQ_AB_XMIT] = -1,
+ [DEC_IRQ_DZ11] = -1,
+ [DEC_IRQ_ASC] = IO_IRQ_NR(KN02BA_IO_INR_ASC),
+ [DEC_IRQ_FLOPPY] = -1,
+ [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+ [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_HALT),
+ [DEC_IRQ_ISDN] = -1,
+ [DEC_IRQ_LANCE] = IO_IRQ_NR(KN02BA_IO_INR_LANCE),
+ [DEC_IRQ_BUS] = IO_IRQ_NR(KN02BA_IO_INR_BUS),
+ [DEC_IRQ_PSU] = IO_IRQ_NR(KN02BA_IO_INR_PSU),
+ [DEC_IRQ_RTC] = IO_IRQ_NR(KN02BA_IO_INR_RTC),
+ [DEC_IRQ_SCC0] = IO_IRQ_NR(KN02BA_IO_INR_SCC0),
+ [DEC_IRQ_SCC1] = IO_IRQ_NR(KN02BA_IO_INR_SCC1),
+ [DEC_IRQ_SII] = -1,
+ [DEC_IRQ_TC0] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0),
+ [DEC_IRQ_TC1] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1),
+ [DEC_IRQ_TC2] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2),
+ [DEC_IRQ_TIMER] = -1,
+ [DEC_IRQ_VIDEO] = -1,
+ [DEC_IRQ_ASC_MERR] = IO_IRQ_NR(IO_INR_ASC_MERR),
+ [DEC_IRQ_ASC_ERR] = IO_IRQ_NR(IO_INR_ASC_ERR),
+ [DEC_IRQ_ASC_DMA] = IO_IRQ_NR(IO_INR_ASC_DMA),
+ [DEC_IRQ_FLOPPY_ERR] = -1,
+ [DEC_IRQ_ISDN_ERR] = -1,
+ [DEC_IRQ_ISDN_RXDMA] = -1,
+ [DEC_IRQ_ISDN_TXDMA] = -1,
+ [DEC_IRQ_LANCE_MERR] = IO_IRQ_NR(IO_INR_LANCE_MERR),
+ [DEC_IRQ_SCC0A_RXERR] = IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+ [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+ [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+ [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+ [DEC_IRQ_AB_RXERR] = -1,
+ [DEC_IRQ_AB_RXDMA] = -1,
+ [DEC_IRQ_AB_TXERR] = -1,
+ [DEC_IRQ_AB_TXDMA] = -1,
+ [DEC_IRQ_SCC1A_RXERR] = IO_IRQ_NR(IO_INR_SCC1A_RXERR),
+ [DEC_IRQ_SCC1A_RXDMA] = IO_IRQ_NR(IO_INR_SCC1A_RXDMA),
+ [DEC_IRQ_SCC1A_TXERR] = IO_IRQ_NR(IO_INR_SCC1A_TXERR),
+ [DEC_IRQ_SCC1A_TXDMA] = IO_IRQ_NR(IO_INR_SCC1A_TXDMA),
+};
+
+static int_ptr kn02ba_cpu_mask_nr_tbl[][2] __initdata = {
+ { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_CASCADE) },
+ { .p = kn02xa_io_int } },
+ { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC2) },
+ { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC1) },
+ { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC0) },
+ { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0) } },
+ { { .i = DEC_CPU_IRQ_ALL },
+ { .p = cpu_all_int } },
+};
+
+static int_ptr kn02ba_asic_mask_nr_tbl[][2] __initdata = {
+ { { .i = IO_IRQ_MASK(KN02BA_IO_INR_BUS) },
+ { .i = IO_IRQ_NR(KN02BA_IO_INR_BUS) } },
+ { { .i = IO_IRQ_MASK(KN02BA_IO_INR_RTC) },
+ { .i = IO_IRQ_NR(KN02BA_IO_INR_RTC) } },
+ { { .i = IO_IRQ_DMA },
+ { .p = asic_dma_int } },
+ { { .i = IO_IRQ_MASK(KN02BA_IO_INR_SCC0) },
+ { .i = IO_IRQ_NR(KN02BA_IO_INR_SCC0) } },
+ { { .i = IO_IRQ_MASK(KN02BA_IO_INR_SCC1) },
+ { .i = IO_IRQ_NR(KN02BA_IO_INR_SCC1) } },
+ { { .i = IO_IRQ_MASK(KN02BA_IO_INR_ASC) },
+ { .i = IO_IRQ_NR(KN02BA_IO_INR_ASC) } },
+ { { .i = IO_IRQ_MASK(KN02BA_IO_INR_LANCE) },
+ { .i = IO_IRQ_NR(KN02BA_IO_INR_LANCE) } },
+ { { .i = IO_IRQ_ALL },
+ { .p = asic_all_int } },
+};
+
+static void __init dec_init_kn02ba(void)
+{
+ /* IRQ routing. */
+ memcpy(&dec_interrupt, &kn02ba_interrupt,
+ sizeof(kn02ba_interrupt));
+
+ /* CPU IRQ priorities. */
+ memcpy(&cpu_mask_nr_tbl, &kn02ba_cpu_mask_nr_tbl,
+ sizeof(kn02ba_cpu_mask_nr_tbl));
+
+ /* I/O ASIC IRQ priorities. */
+ memcpy(&asic_mask_nr_tbl, &kn02ba_asic_mask_nr_tbl,
+ sizeof(kn02ba_asic_mask_nr_tbl));
+
+ mips_cpu_irq_init();
+ init_ioasic_irqs(IO_IRQ_BASE);
+
+} /* dec_init_kn02ba */
+
+
+/*
+ * Machine-specific initialisation for KN02-CA, aka DS5000/xx,
+ * (xx = 20, 25, 33), aka MAXine. Also applies to KN04(-CA), aka
+ * DS5000/50, aka 4MAXine.
+ */
+static int kn02ca_interrupt[DEC_NR_INTS] __initdata = {
+ [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_CASCADE),
+ [DEC_IRQ_AB_RECV] = IO_IRQ_NR(KN02CA_IO_INR_AB_RECV),
+ [DEC_IRQ_AB_XMIT] = IO_IRQ_NR(KN02CA_IO_INR_AB_XMIT),
+ [DEC_IRQ_DZ11] = -1,
+ [DEC_IRQ_ASC] = IO_IRQ_NR(KN02CA_IO_INR_ASC),
+ [DEC_IRQ_FLOPPY] = IO_IRQ_NR(KN02CA_IO_INR_FLOPPY),
+ [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+ [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_HALT),
+ [DEC_IRQ_ISDN] = IO_IRQ_NR(KN02CA_IO_INR_ISDN),
+ [DEC_IRQ_LANCE] = IO_IRQ_NR(KN02CA_IO_INR_LANCE),
+ [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_BUS),
+ [DEC_IRQ_PSU] = -1,
+ [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC),
+ [DEC_IRQ_SCC0] = IO_IRQ_NR(KN02CA_IO_INR_SCC0),
+ [DEC_IRQ_SCC1] = -1,
+ [DEC_IRQ_SII] = -1,
+ [DEC_IRQ_TC0] = IO_IRQ_NR(KN02CA_IO_INR_TC0),
+ [DEC_IRQ_TC1] = IO_IRQ_NR(KN02CA_IO_INR_TC1),
+ [DEC_IRQ_TC2] = -1,
+ [DEC_IRQ_TIMER] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_TIMER),
+ [DEC_IRQ_VIDEO] = IO_IRQ_NR(KN02CA_IO_INR_VIDEO),
+ [DEC_IRQ_ASC_MERR] = IO_IRQ_NR(IO_INR_ASC_MERR),
+ [DEC_IRQ_ASC_ERR] = IO_IRQ_NR(IO_INR_ASC_ERR),
+ [DEC_IRQ_ASC_DMA] = IO_IRQ_NR(IO_INR_ASC_DMA),
+ [DEC_IRQ_FLOPPY_ERR] = IO_IRQ_NR(IO_INR_FLOPPY_ERR),
+ [DEC_IRQ_ISDN_ERR] = IO_IRQ_NR(IO_INR_ISDN_ERR),
+ [DEC_IRQ_ISDN_RXDMA] = IO_IRQ_NR(IO_INR_ISDN_RXDMA),
+ [DEC_IRQ_ISDN_TXDMA] = IO_IRQ_NR(IO_INR_ISDN_TXDMA),
+ [DEC_IRQ_LANCE_MERR] = IO_IRQ_NR(IO_INR_LANCE_MERR),
+ [DEC_IRQ_SCC0A_RXERR] = IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+ [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+ [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+ [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+ [DEC_IRQ_AB_RXERR] = IO_IRQ_NR(IO_INR_AB_RXERR),
+ [DEC_IRQ_AB_RXDMA] = IO_IRQ_NR(IO_INR_AB_RXDMA),
+ [DEC_IRQ_AB_TXERR] = IO_IRQ_NR(IO_INR_AB_TXERR),
+ [DEC_IRQ_AB_TXDMA] = IO_IRQ_NR(IO_INR_AB_TXDMA),
+ [DEC_IRQ_SCC1A_RXERR] = -1,
+ [DEC_IRQ_SCC1A_RXDMA] = -1,
+ [DEC_IRQ_SCC1A_TXERR] = -1,
+ [DEC_IRQ_SCC1A_TXDMA] = -1,
+};
+
+static int_ptr kn02ca_cpu_mask_nr_tbl[][2] __initdata = {
+ { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_BUS) },
+ { .i = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_BUS) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_RTC) },
+ { .i = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_CASCADE) },
+ { .p = kn02xa_io_int } },
+ { { .i = DEC_CPU_IRQ_ALL },
+ { .p = cpu_all_int } },
+};
+
+static int_ptr kn02ca_asic_mask_nr_tbl[][2] __initdata = {
+ { { .i = IO_IRQ_DMA },
+ { .p = asic_dma_int } },
+ { { .i = IO_IRQ_MASK(KN02CA_IO_INR_SCC0) },
+ { .i = IO_IRQ_NR(KN02CA_IO_INR_SCC0) } },
+ { { .i = IO_IRQ_MASK(KN02CA_IO_INR_ASC) },
+ { .i = IO_IRQ_NR(KN02CA_IO_INR_ASC) } },
+ { { .i = IO_IRQ_MASK(KN02CA_IO_INR_LANCE) },
+ { .i = IO_IRQ_NR(KN02CA_IO_INR_LANCE) } },
+ { { .i = IO_IRQ_MASK(KN02CA_IO_INR_TC1) },
+ { .i = IO_IRQ_NR(KN02CA_IO_INR_TC1) } },
+ { { .i = IO_IRQ_MASK(KN02CA_IO_INR_TC0) },
+ { .i = IO_IRQ_NR(KN02CA_IO_INR_TC0) } },
+ { { .i = IO_IRQ_ALL },
+ { .p = asic_all_int } },
+};
+
+static void __init dec_init_kn02ca(void)
+{
+ /* IRQ routing. */
+ memcpy(&dec_interrupt, &kn02ca_interrupt,
+ sizeof(kn02ca_interrupt));
+
+ /* CPU IRQ priorities. */
+ memcpy(&cpu_mask_nr_tbl, &kn02ca_cpu_mask_nr_tbl,
+ sizeof(kn02ca_cpu_mask_nr_tbl));
+
+ /* I/O ASIC IRQ priorities. */
+ memcpy(&asic_mask_nr_tbl, &kn02ca_asic_mask_nr_tbl,
+ sizeof(kn02ca_asic_mask_nr_tbl));
+
+ mips_cpu_irq_init();
+ init_ioasic_irqs(IO_IRQ_BASE);
+
+} /* dec_init_kn02ca */
+
+
+/*
+ * Machine-specific initialisation for KN03, aka DS5000/240,
+ * aka 3max+ and DS5900, aka BIGmax. Also applies to KN05, aka
+ * DS5000/260, aka 4max+ and DS5900/260.
+ */
+static int kn03_interrupt[DEC_NR_INTS] __initdata = {
+ [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN03_CPU_INR_CASCADE),
+ [DEC_IRQ_AB_RECV] = -1,
+ [DEC_IRQ_AB_XMIT] = -1,
+ [DEC_IRQ_DZ11] = -1,
+ [DEC_IRQ_ASC] = IO_IRQ_NR(KN03_IO_INR_ASC),
+ [DEC_IRQ_FLOPPY] = -1,
+ [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU),
+ [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN03_CPU_INR_HALT),
+ [DEC_IRQ_ISDN] = -1,
+ [DEC_IRQ_LANCE] = IO_IRQ_NR(KN03_IO_INR_LANCE),
+ [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN03_CPU_INR_BUS),
+ [DEC_IRQ_PSU] = IO_IRQ_NR(KN03_IO_INR_PSU),
+ [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC),
+ [DEC_IRQ_SCC0] = IO_IRQ_NR(KN03_IO_INR_SCC0),
+ [DEC_IRQ_SCC1] = IO_IRQ_NR(KN03_IO_INR_SCC1),
+ [DEC_IRQ_SII] = -1,
+ [DEC_IRQ_TC0] = IO_IRQ_NR(KN03_IO_INR_TC0),
+ [DEC_IRQ_TC1] = IO_IRQ_NR(KN03_IO_INR_TC1),
+ [DEC_IRQ_TC2] = IO_IRQ_NR(KN03_IO_INR_TC2),
+ [DEC_IRQ_TIMER] = -1,
+ [DEC_IRQ_VIDEO] = -1,
+ [DEC_IRQ_ASC_MERR] = IO_IRQ_NR(IO_INR_ASC_MERR),
+ [DEC_IRQ_ASC_ERR] = IO_IRQ_NR(IO_INR_ASC_ERR),
+ [DEC_IRQ_ASC_DMA] = IO_IRQ_NR(IO_INR_ASC_DMA),
+ [DEC_IRQ_FLOPPY_ERR] = -1,
+ [DEC_IRQ_ISDN_ERR] = -1,
+ [DEC_IRQ_ISDN_RXDMA] = -1,
+ [DEC_IRQ_ISDN_TXDMA] = -1,
+ [DEC_IRQ_LANCE_MERR] = IO_IRQ_NR(IO_INR_LANCE_MERR),
+ [DEC_IRQ_SCC0A_RXERR] = IO_IRQ_NR(IO_INR_SCC0A_RXERR),
+ [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA),
+ [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR),
+ [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA),
+ [DEC_IRQ_AB_RXERR] = -1,
+ [DEC_IRQ_AB_RXDMA] = -1,
+ [DEC_IRQ_AB_TXERR] = -1,
+ [DEC_IRQ_AB_TXDMA] = -1,
+ [DEC_IRQ_SCC1A_RXERR] = IO_IRQ_NR(IO_INR_SCC1A_RXERR),
+ [DEC_IRQ_SCC1A_RXDMA] = IO_IRQ_NR(IO_INR_SCC1A_RXDMA),
+ [DEC_IRQ_SCC1A_TXERR] = IO_IRQ_NR(IO_INR_SCC1A_TXERR),
+ [DEC_IRQ_SCC1A_TXDMA] = IO_IRQ_NR(IO_INR_SCC1A_TXDMA),
+};
+
+static int_ptr kn03_cpu_mask_nr_tbl[][2] __initdata = {
+ { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_BUS) },
+ { .i = DEC_CPU_IRQ_NR(KN03_CPU_INR_BUS) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_RTC) },
+ { .i = DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC) } },
+ { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) },
+ { .p = kn03_io_int } },
+ { { .i = DEC_CPU_IRQ_ALL },
+ { .p = cpu_all_int } },
+};
+
+static int_ptr kn03_asic_mask_nr_tbl[][2] __initdata = {
+ { { .i = IO_IRQ_DMA },
+ { .p = asic_dma_int } },
+ { { .i = IO_IRQ_MASK(KN03_IO_INR_SCC0) },
+ { .i = IO_IRQ_NR(KN03_IO_INR_SCC0) } },
+ { { .i = IO_IRQ_MASK(KN03_IO_INR_SCC1) },
+ { .i = IO_IRQ_NR(KN03_IO_INR_SCC1) } },
+ { { .i = IO_IRQ_MASK(KN03_IO_INR_ASC) },
+ { .i = IO_IRQ_NR(KN03_IO_INR_ASC) } },
+ { { .i = IO_IRQ_MASK(KN03_IO_INR_LANCE) },
+ { .i = IO_IRQ_NR(KN03_IO_INR_LANCE) } },
+ { { .i = IO_IRQ_MASK(KN03_IO_INR_TC2) },
+ { .i = IO_IRQ_NR(KN03_IO_INR_TC2) } },
+ { { .i = IO_IRQ_MASK(KN03_IO_INR_TC1) },
+ { .i = IO_IRQ_NR(KN03_IO_INR_TC1) } },
+ { { .i = IO_IRQ_MASK(KN03_IO_INR_TC0) },
+ { .i = IO_IRQ_NR(KN03_IO_INR_TC0) } },
+ { { .i = IO_IRQ_ALL },
+ { .p = asic_all_int } },
+};
+
+static void __init dec_init_kn03(void)
+{
+ /* IRQ routing. */
+ memcpy(&dec_interrupt, &kn03_interrupt,
+ sizeof(kn03_interrupt));
+
+ /* CPU IRQ priorities. */
+ memcpy(&cpu_mask_nr_tbl, &kn03_cpu_mask_nr_tbl,
+ sizeof(kn03_cpu_mask_nr_tbl));
+
+ /* I/O ASIC IRQ priorities. */
+ memcpy(&asic_mask_nr_tbl, &kn03_asic_mask_nr_tbl,
+ sizeof(kn03_asic_mask_nr_tbl));
+
+ mips_cpu_irq_init();
+ init_ioasic_irqs(IO_IRQ_BASE);
+
+} /* dec_init_kn03 */
+
+
+void __init arch_init_irq(void)
+{
+ switch (mips_machtype) {
+ case MACH_DS23100: /* DS2100/DS3100 Pmin/Pmax */
+ dec_init_kn01();
+ break;
+ case MACH_DS5100: /* DS5100 MIPSmate */
+ dec_init_kn230();
+ break;
+ case MACH_DS5000_200: /* DS5000/200 3max */
+ dec_init_kn02();
+ break;
+ case MACH_DS5000_1XX: /* DS5000/1xx 3min */
+ dec_init_kn02ba();
+ break;
+ case MACH_DS5000_2X0: /* DS5000/240 3max+ */
+ case MACH_DS5900: /* DS5900 bigmax */
+ dec_init_kn03();
+ break;
+ case MACH_DS5000_XX: /* Personal DS5000/xx */
+ dec_init_kn02ca();
+ break;
+ case MACH_DS5800: /* DS5800 Isis */
+ panic("Don't know how to set this up!");
+ break;
+ case MACH_DS5400: /* DS5400 MIPSfair */
+ panic("Don't know how to set this up!");
+ break;
+ case MACH_DS5500: /* DS5500 MIPSfair-2 */
+ panic("Don't know how to set this up!");
+ break;
+ }
+
+ /* Free the FPU interrupt if the exception is present. */
+ if (!cpu_has_nofpuex) {
+ cpu_fpu_mask = 0;
+ dec_interrupt[DEC_IRQ_FPU] = -1;
+ }
+
+ /* Register board interrupts: FPU and cascade. */
+ if (dec_interrupt[DEC_IRQ_FPU] >= 0)
+ setup_irq(dec_interrupt[DEC_IRQ_FPU], &fpuirq);
+ if (dec_interrupt[DEC_IRQ_CASCADE] >= 0)
+ setup_irq(dec_interrupt[DEC_IRQ_CASCADE], &ioirq);
+
+ /* Register the bus error interrupt. */
+ if (dec_interrupt[DEC_IRQ_BUS] >= 0 && busirq.handler)
+ setup_irq(dec_interrupt[DEC_IRQ_BUS], &busirq);
+
+ /* Register the HALT interrupt. */
+ if (dec_interrupt[DEC_IRQ_HALT] >= 0)
+ setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
+}
+
+asmlinkage unsigned int dec_irq_dispatch(unsigned int irq)
+{
+ do_IRQ(irq);
+ return 0;
+}
diff --git a/arch/mips/dec/tc.c b/arch/mips/dec/tc.c
new file mode 100644
index 00000000..732027c7
--- /dev/null
+++ b/arch/mips/dec/tc.c
@@ -0,0 +1,95 @@
+/*
+ * TURBOchannel architecture calls.
+ *
+ * Copyright (c) Harald Koerfgen, 1998
+ * Copyright (c) 2001, 2003, 2005, 2006 Maciej W. Rozycki
+ * Copyright (c) 2005 James Simmons
+ *
+ * This file is subject to the terms and conditions of the GNU
+ * General Public License. See the file "COPYING" in the main
+ * directory of this archive for more details.
+ */
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/tc.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/paccess.h>
+
+#include <asm/dec/interrupts.h>
+#include <asm/dec/prom.h>
+#include <asm/dec/system.h>
+
+/*
+ * Protected read byte from TURBOchannel slot space.
+ */
+int tc_preadb(u8 *valp, void __iomem *addr)
+{
+ return get_dbe(*valp, (u8 *)addr);
+}
+
+/*
+ * Get TURBOchannel bus information as specified by the spec, plus
+ * the slot space base address and the number of slots.
+ */
+int __init tc_bus_get_info(struct tc_bus *tbus)
+{
+ if (!dec_tc_bus)
+ return -ENXIO;
+
+ memcpy(&tbus->info, rex_gettcinfo(), sizeof(tbus->info));
+ tbus->slot_base = CPHYSADDR((long)rex_slot_address(0));
+
+ switch (mips_machtype) {
+ case MACH_DS5000_200:
+ tbus->num_tcslots = 7;
+ break;
+ case MACH_DS5000_2X0:
+ case MACH_DS5900:
+ tbus->ext_slot_base = 0x20000000;
+ tbus->ext_slot_size = 0x20000000;
+ /* fall through */
+ case MACH_DS5000_1XX:
+ tbus->num_tcslots = 3;
+ break;
+ case MACH_DS5000_XX:
+ tbus->num_tcslots = 2;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Get the IRQ for the specified slot.
+ */
+void __init tc_device_get_irq(struct tc_dev *tdev)
+{
+ switch (tdev->slot) {
+ case 0:
+ tdev->interrupt = dec_interrupt[DEC_IRQ_TC0];
+ break;
+ case 1:
+ tdev->interrupt = dec_interrupt[DEC_IRQ_TC1];
+ break;
+ case 2:
+ tdev->interrupt = dec_interrupt[DEC_IRQ_TC2];
+ break;
+ /*
+ * Yuck! DS5000/200 onboard devices
+ */
+ case 5:
+ tdev->interrupt = dec_interrupt[DEC_IRQ_TC5];
+ break;
+ case 6:
+ tdev->interrupt = dec_interrupt[DEC_IRQ_TC6];
+ break;
+ default:
+ tdev->interrupt = -1;
+ break;
+ }
+}
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
new file mode 100644
index 00000000..ea57f39e
--- /dev/null
+++ b/arch/mips/dec/time.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ * Copyright (C) 2000, 2003 Maciej W. Rozycki
+ *
+ * This file contains the time handling details for PC-style clocks as
+ * found in some MIPS systems.
+ *
+ */
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/mc146818rtc.h>
+#include <linux/param.h>
+
+#include <asm/cpu-features.h>
+#include <asm/ds1287.h>
+#include <asm/time.h>
+#include <asm/dec/interrupts.h>
+#include <asm/dec/ioasic.h>
+#include <asm/dec/machtype.h>
+
+void read_persistent_clock(struct timespec *ts)
+{
+ unsigned int year, mon, day, hour, min, sec, real_year;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+
+ do {
+ sec = CMOS_READ(RTC_SECONDS);
+ min = CMOS_READ(RTC_MINUTES);
+ hour = CMOS_READ(RTC_HOURS);
+ day = CMOS_READ(RTC_DAY_OF_MONTH);
+ mon = CMOS_READ(RTC_MONTH);
+ year = CMOS_READ(RTC_YEAR);
+ /*
+ * The PROM will reset the year to either '72 or '73.
+ * Therefore we store the real year separately, in one
+ * of unused BBU RAM locations.
+ */
+ real_year = CMOS_READ(RTC_DEC_YEAR);
+ } while (sec != CMOS_READ(RTC_SECONDS));
+
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
+ }
+
+ year += real_year - 72 + 2000;
+
+ ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+ ts->tv_nsec = 0;
+}
+
+/*
+ * In order to set the CMOS clock precisely, rtc_mips_set_mmss has to
+ * be called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Dallas
+ * DS1287 data sheet for details.
+ */
+int rtc_mips_set_mmss(unsigned long nowtime)
+{
+ int retval = 0;
+ int real_seconds, real_minutes, cmos_minutes;
+ unsigned char save_control, save_freq_select;
+
+ /* irq are locally disabled here */
+ spin_lock(&rtc_lock);
+ /* tell the clock it's being set */
+ save_control = CMOS_READ(RTC_CONTROL);
+ CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL);
+
+ /* stop and reset prescaler */
+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
+ CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+ cmos_minutes = CMOS_READ(RTC_MINUTES);
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+ cmos_minutes = bcd2bin(cmos_minutes);
+
+ /*
+ * since we're only adjusting minutes and seconds,
+ * don't interfere with hour overflow. This avoids
+ * messing with unknown time zones but requires your
+ * RTC not to be off by more than 15 minutes
+ */
+ real_seconds = nowtime % 60;
+ real_minutes = nowtime / 60;
+ if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
+ real_minutes += 30; /* correct for half hour time zone */
+ real_minutes %= 60;
+
+ if (abs(real_minutes - cmos_minutes) < 30) {
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
+ }
+ CMOS_WRITE(real_seconds, RTC_SECONDS);
+ CMOS_WRITE(real_minutes, RTC_MINUTES);
+ } else {
+ printk_once(KERN_NOTICE
+ "set_rtc_mmss: can't update from %d to %d\n",
+ cmos_minutes, real_minutes);
+ retval = -1;
+ }
+
+ /* The following flags have to be released exactly in this order,
+ * otherwise the DS1287 will not reset the oscillator and will not
+ * update precisely 500 ms later. You won't find this mentioned
+ * in the Dallas Semiconductor data sheets, but who believes data
+ * sheets anyway ... -- Markus Kuhn
+ */
+ CMOS_WRITE(save_control, RTC_CONTROL);
+ CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ spin_unlock(&rtc_lock);
+
+ return retval;
+}
+
+void __init plat_time_init(void)
+{
+ u32 start, end;
+ int i = HZ / 10;
+
+ /* Set up the rate of periodic DS1287 interrupts. */
+ ds1287_set_base_clock(HZ);
+
+ if (cpu_has_counter) {
+ while (!ds1287_timer_state())
+ ;
+
+ start = read_c0_count();
+
+ while (i--)
+ while (!ds1287_timer_state())
+ ;
+
+ end = read_c0_count();
+
+ mips_hpt_frequency = (end - start) * 10;
+ printk(KERN_INFO "MIPS counter frequency %dHz\n",
+ mips_hpt_frequency);
+ } else if (IOASIC)
+ /* For pre-R4k systems we use the I/O ASIC's counter. */
+ dec_ioasic_clocksource_init();
+
+ ds1287_clockevent_init(dec_interrupt[DEC_IRQ_RTC]);
+}
diff --git a/arch/mips/dec/wbflush.c b/arch/mips/dec/wbflush.c
new file mode 100644
index 00000000..925c0525
--- /dev/null
+++ b/arch/mips/dec/wbflush.c
@@ -0,0 +1,94 @@
+/*
+ * Setup the right wbflush routine for the different DECstations.
+ *
+ * Created with information from:
+ * DECstation 3100 Desktop Workstation Functional Specification
+ * DECstation 5000/200 KN02 System Module Functional Specification
+ * mipsel-linux-objdump --disassemble vmunix | grep "wbflush" :-)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+
+#include <linux/init.h>
+
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+#include <asm/wbflush.h>
+
+static void wbflush_kn01(void);
+static void wbflush_kn210(void);
+static void wbflush_mips(void);
+
+void (*__wbflush) (void);
+
+void __init wbflush_setup(void)
+{
+ switch (mips_machtype) {
+ case MACH_DS23100:
+ case MACH_DS5000_200: /* DS5000 3max */
+ __wbflush = wbflush_kn01;
+ break;
+ case MACH_DS5100: /* DS5100 MIPSMATE */
+ __wbflush = wbflush_kn210;
+ break;
+ case MACH_DS5000_1XX: /* DS5000/100 3min */
+ case MACH_DS5000_XX: /* Personal DS5000/2x */
+ case MACH_DS5000_2X0: /* DS5000/240 3max+ */
+ case MACH_DS5900: /* DS5900 bigmax */
+ default:
+ __wbflush = wbflush_mips;
+ break;
+ }
+}
+
+/*
+ * For the DS3100 and DS5000/200 the R2020/R3220 writeback buffer functions
+ * as part of Coprocessor 0.
+ */
+static void wbflush_kn01(void)
+{
+ asm(".set\tpush\n\t"
+ ".set\tnoreorder\n\t"
+ "1:\tbc0f\t1b\n\t"
+ "nop\n\t"
+ ".set\tpop");
+}
+
+/*
+ * For the DS5100 the writeback buffer seems to be a part of Coprocessor 3.
+ * But CP3 has to enabled first.
+ */
+static void wbflush_kn210(void)
+{
+ asm(".set\tpush\n\t"
+ ".set\tnoreorder\n\t"
+ "mfc0\t$2,$12\n\t"
+ "lui\t$3,0x8000\n\t"
+ "or\t$3,$2,$3\n\t"
+ "mtc0\t$3,$12\n\t"
+ "nop\n"
+ "1:\tbc3f\t1b\n\t"
+ "nop\n\t"
+ "mtc0\t$2,$12\n\t"
+ "nop\n\t"
+ ".set\tpop"
+ : : : "$2", "$3");
+}
+
+/*
+ * I/O ASIC systems use a standard writeback buffer that gets flushed
+ * upon an uncached read.
+ */
+static void wbflush_mips(void)
+{
+ __fast_iob();
+}
+
+#include <linux/module.h>
+
+EXPORT_SYMBOL(__wbflush);
diff --git a/arch/mips/emma/Makefile b/arch/mips/emma/Makefile
new file mode 100644
index 00000000..4254a31e
--- /dev/null
+++ b/arch/mips/emma/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_SOC_EMMA2RH) += common/
+
+#
+# NEC EMMA2RH Mark-eins
+#
+obj-$(CONFIG_NEC_MARKEINS) += markeins/
diff --git a/arch/mips/emma/Platform b/arch/mips/emma/Platform
new file mode 100644
index 00000000..0282f7f9
--- /dev/null
+++ b/arch/mips/emma/Platform
@@ -0,0 +1,4 @@
+platform-$(CONFIG_SOC_EMMA2RH) += emma/
+cflags-$(CONFIG_SOC_EMMA2RH) += \
+ -I$(srctree)/arch/mips/include/asm/mach-emma2rh
+load-$(CONFIG_NEC_MARKEINS) += 0xffffffff88100000
diff --git a/arch/mips/emma/common/Makefile b/arch/mips/emma/common/Makefile
new file mode 100644
index 00000000..f27d84d1
--- /dev/null
+++ b/arch/mips/emma/common/Makefile
@@ -0,0 +1,10 @@
+#
+# Copyright (C) NEC Electronics Corporation 2005-2006
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+
+obj-$(CONFIG_NEC_MARKEINS) += prom.o
diff --git a/arch/mips/emma/common/prom.c b/arch/mips/emma/common/prom.c
new file mode 100644
index 00000000..708f0876
--- /dev/null
+++ b/arch/mips/emma/common/prom.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ * This file is based on the arch/mips/ddb5xxx/common/prom.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/emma/emma2rh.h>
+
+const char *get_system_type(void)
+{
+#ifdef CONFIG_NEC_MARKEINS
+ return "NEC EMMA2RH Mark-eins";
+#else
+#error Unknown NEC board
+#endif
+}
+
+/* [jsun@junsun.net] PMON passes arguments in C main() style */
+void __init prom_init(void)
+{
+ int argc = fw_arg0;
+ char **arg = (char **)fw_arg1;
+ int i;
+
+ /* if user passes kernel args, ignore the default one */
+ if (argc > 1)
+ arcs_cmdline[0] = '\0';
+
+ /* arg[0] is "g", the rest is boot parameters */
+ for (i = 1; i < argc; i++) {
+ if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+ >= sizeof(arcs_cmdline))
+ break;
+ strcat(arcs_cmdline, arg[i]);
+ strcat(arcs_cmdline, " ");
+ }
+
+#ifdef CONFIG_NEC_MARKEINS
+ add_memory_region(0, EMMA2RH_RAM_SIZE, BOOT_MEM_RAM);
+#else
+#error Unknown NEC board
+#endif
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/emma/markeins/Makefile b/arch/mips/emma/markeins/Makefile
new file mode 100644
index 00000000..f8ba2508
--- /dev/null
+++ b/arch/mips/emma/markeins/Makefile
@@ -0,0 +1,10 @@
+#
+# Copyright (C) NEC Electronics Corporation 2005-2006
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+
+obj-$(CONFIG_NEC_MARKEINS) += irq.o setup.o led.o platform.o
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c
new file mode 100644
index 00000000..3dbd7a5a
--- /dev/null
+++ b/arch/mips/emma/markeins/irq.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ * This file is based on the arch/mips/ddb5xxx/ddb5477/irq.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/delay.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <asm/emma/emma2rh.h>
+
+static void emma2rh_irq_enable(struct irq_data *d)
+{
+ unsigned int irq = d->irq - EMMA2RH_IRQ_BASE;
+ u32 reg_value, reg_bitmask, reg_index;
+
+ reg_index = EMMA2RH_BHIF_INT_EN_0 +
+ (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32);
+ reg_value = emma2rh_in32(reg_index);
+ reg_bitmask = 0x1 << (irq % 32);
+ emma2rh_out32(reg_index, reg_value | reg_bitmask);
+}
+
+static void emma2rh_irq_disable(struct irq_data *d)
+{
+ unsigned int irq = d->irq - EMMA2RH_IRQ_BASE;
+ u32 reg_value, reg_bitmask, reg_index;
+
+ reg_index = EMMA2RH_BHIF_INT_EN_0 +
+ (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32);
+ reg_value = emma2rh_in32(reg_index);
+ reg_bitmask = 0x1 << (irq % 32);
+ emma2rh_out32(reg_index, reg_value & ~reg_bitmask);
+}
+
+struct irq_chip emma2rh_irq_controller = {
+ .name = "emma2rh_irq",
+ .irq_mask = emma2rh_irq_disable,
+ .irq_unmask = emma2rh_irq_enable,
+};
+
+void emma2rh_irq_init(void)
+{
+ u32 i;
+
+ for (i = 0; i < NUM_EMMA2RH_IRQ; i++)
+ irq_set_chip_and_handler_name(EMMA2RH_IRQ_BASE + i,
+ &emma2rh_irq_controller,
+ handle_level_irq, "level");
+}
+
+static void emma2rh_sw_irq_enable(struct irq_data *d)
+{
+ unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE;
+ u32 reg;
+
+ reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
+ reg |= 1 << irq;
+ emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
+}
+
+static void emma2rh_sw_irq_disable(struct irq_data *d)
+{
+ unsigned int irq = d->irq - EMMA2RH_SW_IRQ_BASE;
+ u32 reg;
+
+ reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
+ reg &= ~(1 << irq);
+ emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg);
+}
+
+struct irq_chip emma2rh_sw_irq_controller = {
+ .name = "emma2rh_sw_irq",
+ .irq_mask = emma2rh_sw_irq_disable,
+ .irq_unmask = emma2rh_sw_irq_enable,
+};
+
+void emma2rh_sw_irq_init(void)
+{
+ u32 i;
+
+ for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++)
+ irq_set_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i,
+ &emma2rh_sw_irq_controller,
+ handle_level_irq, "level");
+}
+
+static void emma2rh_gpio_irq_enable(struct irq_data *d)
+{
+ unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
+ u32 reg;
+
+ reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+ reg |= 1 << irq;
+ emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
+}
+
+static void emma2rh_gpio_irq_disable(struct irq_data *d)
+{
+ unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
+ u32 reg;
+
+ reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+ reg &= ~(1 << irq);
+ emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
+}
+
+static void emma2rh_gpio_irq_ack(struct irq_data *d)
+{
+ unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
+
+ emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
+}
+
+static void emma2rh_gpio_irq_mask_ack(struct irq_data *d)
+{
+ unsigned int irq = d->irq - EMMA2RH_GPIO_IRQ_BASE;
+ u32 reg;
+
+ emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
+
+ reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+ reg &= ~(1 << irq);
+ emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
+}
+
+struct irq_chip emma2rh_gpio_irq_controller = {
+ .name = "emma2rh_gpio_irq",
+ .irq_ack = emma2rh_gpio_irq_ack,
+ .irq_mask = emma2rh_gpio_irq_disable,
+ .irq_mask_ack = emma2rh_gpio_irq_mask_ack,
+ .irq_unmask = emma2rh_gpio_irq_enable,
+};
+
+void emma2rh_gpio_irq_init(void)
+{
+ u32 i;
+
+ for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++)
+ irq_set_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i,
+ &emma2rh_gpio_irq_controller,
+ handle_edge_irq, "edge");
+}
+
+static struct irqaction irq_cascade = {
+ .handler = no_action,
+ .flags = 0,
+ .name = "cascade",
+ .dev_id = NULL,
+ .next = NULL,
+};
+
+/*
+ * the first level int-handler will jump here if it is a emma2rh irq
+ */
+void emma2rh_irq_dispatch(void)
+{
+ u32 intStatus;
+ u32 bitmask;
+ u32 i;
+
+ intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_0) &
+ emma2rh_in32(EMMA2RH_BHIF_INT_EN_0);
+
+#ifdef EMMA2RH_SW_CASCADE
+ if (intStatus & (1UL << EMMA2RH_SW_CASCADE)) {
+ u32 swIntStatus;
+ swIntStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT)
+ & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
+ for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
+ if (swIntStatus & bitmask) {
+ do_IRQ(EMMA2RH_SW_IRQ_BASE + i);
+ return;
+ }
+ }
+ }
+ /* Skip S/W interrupt */
+ intStatus &= ~(1UL << EMMA2RH_SW_CASCADE);
+#endif
+
+ for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
+ if (intStatus & bitmask) {
+ do_IRQ(EMMA2RH_IRQ_BASE + i);
+ return;
+ }
+ }
+
+ intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_1) &
+ emma2rh_in32(EMMA2RH_BHIF_INT_EN_1);
+
+#ifdef EMMA2RH_GPIO_CASCADE
+ if (intStatus & (1UL << (EMMA2RH_GPIO_CASCADE % 32))) {
+ u32 gpioIntStatus;
+ gpioIntStatus = emma2rh_in32(EMMA2RH_GPIO_INT_ST)
+ & emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+ for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
+ if (gpioIntStatus & bitmask) {
+ do_IRQ(EMMA2RH_GPIO_IRQ_BASE + i);
+ return;
+ }
+ }
+ }
+ /* Skip GPIO interrupt */
+ intStatus &= ~(1UL << (EMMA2RH_GPIO_CASCADE % 32));
+#endif
+
+ for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) {
+ if (intStatus & bitmask) {
+ do_IRQ(EMMA2RH_IRQ_BASE + i);
+ return;
+ }
+ }
+
+ intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_2) &
+ emma2rh_in32(EMMA2RH_BHIF_INT_EN_2);
+
+ for (i = 64, bitmask = 1; i < 96; i++, bitmask <<= 1) {
+ if (intStatus & bitmask) {
+ do_IRQ(EMMA2RH_IRQ_BASE + i);
+ return;
+ }
+ }
+}
+
+void __init arch_init_irq(void)
+{
+ u32 reg;
+
+ /* by default, interrupts are disabled. */
+ emma2rh_out32(EMMA2RH_BHIF_INT_EN_0, 0);
+ emma2rh_out32(EMMA2RH_BHIF_INT_EN_1, 0);
+ emma2rh_out32(EMMA2RH_BHIF_INT_EN_2, 0);
+ emma2rh_out32(EMMA2RH_BHIF_INT1_EN_0, 0);
+ emma2rh_out32(EMMA2RH_BHIF_INT1_EN_1, 0);
+ emma2rh_out32(EMMA2RH_BHIF_INT1_EN_2, 0);
+ emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, 0);
+
+ clear_c0_status(0xff00);
+ set_c0_status(0x0400);
+
+#define GPIO_PCI (0xf<<15)
+ /* setup GPIO interrupt for PCI interface */
+ /* direction input */
+ reg = emma2rh_in32(EMMA2RH_GPIO_DIR);
+ emma2rh_out32(EMMA2RH_GPIO_DIR, reg & ~GPIO_PCI);
+ /* disable interrupt */
+ reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+ emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg & ~GPIO_PCI);
+ /* level triggerd */
+ reg = emma2rh_in32(EMMA2RH_GPIO_INT_MODE);
+ emma2rh_out32(EMMA2RH_GPIO_INT_MODE, reg | GPIO_PCI);
+ reg = emma2rh_in32(EMMA2RH_GPIO_INT_CND_A);
+ emma2rh_out32(EMMA2RH_GPIO_INT_CND_A, reg & (~GPIO_PCI));
+ /* interrupt clear */
+ emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~GPIO_PCI);
+
+ /* init all controllers */
+ emma2rh_irq_init();
+ emma2rh_sw_irq_init();
+ emma2rh_gpio_irq_init();
+ mips_cpu_irq_init();
+
+ /* setup cascade interrupts */
+ setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_SW_CASCADE, &irq_cascade);
+ setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_GPIO_CASCADE, &irq_cascade);
+ setup_irq(MIPS_CPU_IRQ_BASE + 2, &irq_cascade);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP7)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+ else if (pending & STATUSF_IP2)
+ emma2rh_irq_dispatch();
+ else if (pending & STATUSF_IP1)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 1);
+ else if (pending & STATUSF_IP0)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 0);
+ else
+ spurious_interrupt();
+}
diff --git a/arch/mips/emma/markeins/led.c b/arch/mips/emma/markeins/led.c
new file mode 100644
index 00000000..49755896
--- /dev/null
+++ b/arch/mips/emma/markeins/led.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <asm/emma/emma2rh.h>
+
+const unsigned long clear = 0x20202020;
+
+#define LED_BASE 0xb1400038
+
+void markeins_led_clear(void)
+{
+ emma2rh_out32(LED_BASE, clear);
+ emma2rh_out32(LED_BASE + 4, clear);
+}
+
+void markeins_led(const char *str)
+{
+ int i;
+ int len = strlen(str);
+
+ markeins_led_clear();
+ if (len > 8)
+ len = 8;
+
+ if (emma2rh_in32(0xb0000800) & (0x1 << 18))
+ for (i = 0; i < len; i++)
+ emma2rh_out8(LED_BASE + i, str[i]);
+ else
+ for (i = 0; i < len; i++)
+ emma2rh_out8(LED_BASE + (i & 4) + (3 - (i & 3)),
+ str[i]);
+}
+
+void markeins_led_hex(u32 val)
+{
+ char str[10];
+
+ sprintf(str, "%08x", val);
+ markeins_led(str);
+}
diff --git a/arch/mips/emma/markeins/platform.c b/arch/mips/emma/markeins/platform.c
new file mode 100644
index 00000000..b05b08b9
--- /dev/null
+++ b/arch/mips/emma/markeins/platform.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright(C) MontaVista Software Inc, 2006
+ *
+ * Author: dmitry pervushin <dpervushin@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+#include <asm/time.h>
+#include <asm/bcache.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/traps.h>
+
+#include <asm/emma/emma2rh.h>
+
+
+#define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */
+
+static struct resource i2c_emma_resources_0[] = {
+ {
+ .name = NULL,
+ .start = EMMA2RH_IRQ_PIIC0,
+ .end = EMMA2RH_IRQ_PIIC0,
+ .flags = IORESOURCE_IRQ
+ }, {
+ .name = NULL,
+ .start = EMMA2RH_PIIC0_BASE,
+ .end = EMMA2RH_PIIC0_BASE + 0x1000,
+ .flags = 0
+ },
+};
+
+struct resource i2c_emma_resources_1[] = {
+ {
+ .name = NULL,
+ .start = EMMA2RH_IRQ_PIIC1,
+ .end = EMMA2RH_IRQ_PIIC1,
+ .flags = IORESOURCE_IRQ
+ }, {
+ .name = NULL,
+ .start = EMMA2RH_PIIC1_BASE,
+ .end = EMMA2RH_PIIC1_BASE + 0x1000,
+ .flags = 0
+ },
+};
+
+struct resource i2c_emma_resources_2[] = {
+ {
+ .name = NULL,
+ .start = EMMA2RH_IRQ_PIIC2,
+ .end = EMMA2RH_IRQ_PIIC2,
+ .flags = IORESOURCE_IRQ
+ }, {
+ .name = NULL,
+ .start = EMMA2RH_PIIC2_BASE,
+ .end = EMMA2RH_PIIC2_BASE + 0x1000,
+ .flags = 0
+ },
+};
+
+struct platform_device i2c_emma_devices[] = {
+ [0] = {
+ .name = I2C_EMMA2RH,
+ .id = 0,
+ .resource = i2c_emma_resources_0,
+ .num_resources = ARRAY_SIZE(i2c_emma_resources_0),
+ },
+ [1] = {
+ .name = I2C_EMMA2RH,
+ .id = 1,
+ .resource = i2c_emma_resources_1,
+ .num_resources = ARRAY_SIZE(i2c_emma_resources_1),
+ },
+ [2] = {
+ .name = I2C_EMMA2RH,
+ .id = 2,
+ .resource = i2c_emma_resources_2,
+ .num_resources = ARRAY_SIZE(i2c_emma_resources_2),
+ },
+};
+
+#define EMMA2RH_SERIAL_CLOCK 18544000
+#define EMMA2RH_SERIAL_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
+
+static struct plat_serial8250_port platform_serial_ports[] = {
+ [0] = {
+ .membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
+ .mapbase = EMMA2RH_PFUR0_BASE + 3,
+ .irq = EMMA2RH_IRQ_PFUR0,
+ .uartclk = EMMA2RH_SERIAL_CLOCK,
+ .regshift = 4,
+ .iotype = UPIO_MEM,
+ .flags = EMMA2RH_SERIAL_FLAGS,
+ }, [1] = {
+ .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
+ .mapbase = EMMA2RH_PFUR1_BASE + 3,
+ .irq = EMMA2RH_IRQ_PFUR1,
+ .uartclk = EMMA2RH_SERIAL_CLOCK,
+ .regshift = 4,
+ .iotype = UPIO_MEM,
+ .flags = EMMA2RH_SERIAL_FLAGS,
+ }, [2] = {
+ .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
+ .mapbase = EMMA2RH_PFUR2_BASE + 3,
+ .irq = EMMA2RH_IRQ_PFUR2,
+ .uartclk = EMMA2RH_SERIAL_CLOCK,
+ .regshift = 4,
+ .iotype = UPIO_MEM,
+ .flags = EMMA2RH_SERIAL_FLAGS,
+ }, [3] = {
+ .flags = 0,
+ },
+};
+
+static struct platform_device serial_emma = {
+ .name = "serial8250",
+ .dev = {
+ .platform_data = &platform_serial_ports,
+ },
+};
+
+static struct mtd_partition markeins_parts[] = {
+ [0] = {
+ .name = "RootFS",
+ .offset = 0x00000000,
+ .size = 0x00c00000,
+ },
+ [1] = {
+ .name = "boot code area",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00100000,
+ },
+ [2] = {
+ .name = "kernel image",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00300000,
+ },
+ [3] = {
+ .name = "RootFS2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00c00000,
+ },
+ [4] = {
+ .name = "boot code area2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00100000,
+ },
+ [5] = {
+ .name = "kernel image2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data markeins_flash_data = {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(markeins_parts),
+ .parts = markeins_parts
+};
+
+static struct resource markeins_flash_resource = {
+ .start = 0x1e000000,
+ .end = 0x02000000,
+ .flags = IORESOURCE_MEM
+};
+
+static struct platform_device markeins_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &markeins_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &markeins_flash_resource,
+};
+
+static struct platform_device *devices[] = {
+ i2c_emma_devices,
+ i2c_emma_devices + 1,
+ i2c_emma_devices + 2,
+ &serial_emma,
+ &markeins_flash_device,
+};
+
+static int __init platform_devices_setup(void)
+{
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+arch_initcall(platform_devices_setup);
diff --git a/arch/mips/emma/markeins/setup.c b/arch/mips/emma/markeins/setup.c
new file mode 100644
index 00000000..feceebcf
--- /dev/null
+++ b/arch/mips/emma/markeins/setup.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ * This file is based on the arch/mips/ddb5xxx/ddb5477/setup.c.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/time.h>
+#include <asm/reboot.h>
+
+#include <asm/emma/emma2rh.h>
+
+#define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */
+
+extern void markeins_led(const char *);
+
+static int bus_frequency;
+
+static void markeins_machine_restart(char *command)
+{
+ static void (*back_to_prom) (void) = (void (*)(void))0xbfc00000;
+
+ printk("cannot EMMA2RH Mark-eins restart.\n");
+ markeins_led("restart.");
+ back_to_prom();
+}
+
+static void markeins_machine_halt(void)
+{
+ printk("EMMA2RH Mark-eins halted.\n");
+ markeins_led("halted.");
+ while (1) ;
+}
+
+static void markeins_machine_power_off(void)
+{
+ markeins_led("poweroff.");
+ while (1) ;
+}
+
+static unsigned long __initdata emma2rh_clock[4] = {
+ 166500000, 187312500, 199800000, 210600000
+};
+
+static unsigned int __init detect_bus_frequency(unsigned long rtc_base)
+{
+ u32 reg;
+
+ /* detect from boot strap */
+ reg = emma2rh_in32(EMMA2RH_BHIF_STRAP_0);
+ reg = (reg >> 4) & 0x3;
+
+ return emma2rh_clock[reg];
+}
+
+void __init plat_time_init(void)
+{
+ u32 reg;
+ if (bus_frequency == 0)
+ bus_frequency = detect_bus_frequency(0);
+
+ reg = emma2rh_in32(EMMA2RH_BHIF_STRAP_0);
+ if ((reg & 0x3) == 0)
+ reg = (reg >> 6) & 0x3;
+ else {
+ reg = emma2rh_in32(EMMA2RH_BHIF_MAIN_CTRL);
+ reg = (reg >> 4) & 0x3;
+ }
+ mips_hpt_frequency = (bus_frequency * (4 + reg)) / 4 / 2;
+}
+
+static void markeins_board_init(void);
+extern void markeins_irq_setup(void);
+
+static void inline __init markeins_sio_setup(void)
+{
+}
+
+void __init plat_mem_setup(void)
+{
+ /* initialize board - we don't trust the loader */
+ markeins_board_init();
+
+ set_io_port_base(KSEG1ADDR(EMMA2RH_PCI_IO_BASE));
+
+ _machine_restart = markeins_machine_restart;
+ _machine_halt = markeins_machine_halt;
+ pm_power_off = markeins_machine_power_off;
+
+ /* setup resource limits */
+ ioport_resource.start = EMMA2RH_PCI_IO_BASE;
+ ioport_resource.end = EMMA2RH_PCI_IO_BASE + EMMA2RH_PCI_IO_SIZE - 1;
+ iomem_resource.start = EMMA2RH_IO_BASE;
+ iomem_resource.end = EMMA2RH_ROM_BASE - 1;
+
+ /* Reboot on panic */
+ panic_timeout = 180;
+
+ markeins_sio_setup();
+}
+
+static void __init markeins_board_init(void)
+{
+ u32 val;
+
+ val = emma2rh_in32(EMMA2RH_PBRD_INT_EN); /* open serial interrupts. */
+ emma2rh_out32(EMMA2RH_PBRD_INT_EN, val | 0xaa);
+ val = emma2rh_in32(EMMA2RH_PBRD_CLKSEL); /* set serial clocks. */
+ emma2rh_out32(EMMA2RH_PBRD_CLKSEL, val | 0x5); /* 18MHz */
+ emma2rh_out32(EMMA2RH_PCI_CONTROL, 0);
+
+ markeins_led("MVL E2RH");
+}
diff --git a/arch/mips/fw/arc/Makefile b/arch/mips/fw/arc/Makefile
new file mode 100644
index 00000000..5314b37a
--- /dev/null
+++ b/arch/mips/fw/arc/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the ARC prom monitor library routines under Linux.
+#
+
+lib-y += cmdline.o env.o file.o identify.o init.o \
+ misc.o salone.o time.o tree.o
+
+lib-$(CONFIG_ARC_MEMORY) += memory.o
+lib-$(CONFIG_ARC_CONSOLE) += arc_con.o
+lib-$(CONFIG_ARC_PROMLIB) += promlib.o
+
+ccflags-y := -Werror
diff --git a/arch/mips/fw/arc/arc_con.c b/arch/mips/fw/arc/arc_con.c
new file mode 100644
index 00000000..bc32fe64
--- /dev/null
+++ b/arch/mips/fw/arc/arc_con.c
@@ -0,0 +1,50 @@
+/*
+ * Wrap-around code for a console using the
+ * ARC io-routines.
+ *
+ * Copyright (c) 1998 Harald Koerfgen
+ * Copyright (c) 2001 Ralf Baechle
+ * Copyright (c) 2002 Thiemo Seufer
+ */
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+#include <asm/sgialib.h>
+
+static void prom_console_write(struct console *co, const char *s,
+ unsigned count)
+{
+ /* Do each character */
+ while (count--) {
+ if (*s == '\n')
+ prom_putchar('\r');
+ prom_putchar(*s++);
+ }
+}
+
+static int prom_console_setup(struct console *co, char *options)
+{
+ return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE);
+}
+
+static struct console arc_cons = {
+ .name = "arc",
+ .write = prom_console_write,
+ .setup = prom_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+/*
+ * Register console.
+ */
+
+static int __init arc_console_init(void)
+{
+ register_console(&arc_cons);
+
+ return 0;
+}
+console_initcall(arc_console_init);
diff --git a/arch/mips/fw/arc/cmdline.c b/arch/mips/fw/arc/cmdline.c
new file mode 100644
index 00000000..9fdf07e5
--- /dev/null
+++ b/arch/mips/fw/arc/cmdline.c
@@ -0,0 +1,103 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * cmdline.c: Kernel command line creation using ARCS argc/argv.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+#undef DEBUG_CMDLINE
+
+static char *ignored[] = {
+ "ConsoleIn=",
+ "ConsoleOut=",
+ "SystemPartition=",
+ "OSLoader=",
+ "OSLoadPartition=",
+ "OSLoadFilename=",
+ "OSLoadOptions="
+};
+
+static char *used_arc[][2] = {
+ { "OSLoadPartition=", "root=" },
+ { "OSLoadOptions=", "" }
+};
+
+static char * __init move_firmware_args(char* cp)
+{
+ char *s;
+ int actr, i;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ while (actr < prom_argc) {
+ for(i = 0; i < ARRAY_SIZE(used_arc); i++) {
+ int len = strlen(used_arc[i][0]);
+
+ if (!strncmp(prom_argv(actr), used_arc[i][0], len)) {
+ /* Ok, we want it. First append the replacement... */
+ strcat(cp, used_arc[i][1]);
+ cp += strlen(used_arc[i][1]);
+ /* ... and now the argument */
+ s = strchr(prom_argv(actr), '=');
+ if (s) {
+ s++;
+ strcpy(cp, s);
+ cp += strlen(s);
+ }
+ *cp++ = ' ';
+ break;
+ }
+ }
+ actr++;
+ }
+
+ return cp;
+}
+
+void __init prom_init_cmdline(void)
+{
+ char *cp;
+ int actr, i;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = arcs_cmdline;
+ /*
+ * Move ARC variables to the beginning to make sure they can be
+ * overridden by later arguments.
+ */
+ cp = move_firmware_args(cp);
+
+ while (actr < prom_argc) {
+ for (i = 0; i < ARRAY_SIZE(ignored); i++) {
+ int len = strlen(ignored[i]);
+
+ if (!strncmp(prom_argv(actr), ignored[i], len))
+ goto pic_cont;
+ }
+ /* Ok, we want it. */
+ strcpy(cp, prom_argv(actr));
+ cp += strlen(prom_argv(actr));
+ *cp++ = ' ';
+
+ pic_cont:
+ actr++;
+ }
+
+ if (cp != arcs_cmdline) /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+
+#ifdef DEBUG_CMDLINE
+ printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline);
+#endif
+}
diff --git a/arch/mips/fw/arc/env.c b/arch/mips/fw/arc/env.c
new file mode 100644
index 00000000..1118a26b
--- /dev/null
+++ b/arch/mips/fw/arc/env.c
@@ -0,0 +1,27 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * env.c: ARCS environment variable routines.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/fw/arc/types.h>
+#include <asm/sgialib.h>
+
+PCHAR __init
+ArcGetEnvironmentVariable(CHAR *name)
+{
+ return (CHAR *) ARC_CALL1(get_evar, name);
+}
+
+LONG __init
+ArcSetEnvironmentVariable(PCHAR name, PCHAR value)
+{
+ return ARC_CALL2(set_evar, name, value);
+}
diff --git a/arch/mips/fw/arc/file.c b/arch/mips/fw/arc/file.c
new file mode 100644
index 00000000..30335341
--- /dev/null
+++ b/arch/mips/fw/arc/file.c
@@ -0,0 +1,75 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * ARC firmware interface.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+
+#include <asm/fw/arc/types.h>
+#include <asm/sgialib.h>
+
+LONG
+ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer,
+ ULONG N, ULONG *Count)
+{
+ return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count);
+}
+
+LONG
+ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID)
+{
+ return ARC_CALL3(open, Path, OpenMode, FileID);
+}
+
+LONG
+ArcClose(ULONG FileID)
+{
+ return ARC_CALL1(close, FileID);
+}
+
+LONG
+ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count)
+{
+ return ARC_CALL4(read, FileID, Buffer, N, Count);
+}
+
+LONG
+ArcGetReadStatus(ULONG FileID)
+{
+ return ARC_CALL1(get_rstatus, FileID);
+}
+
+LONG
+ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count)
+{
+ return ARC_CALL4(write, FileID, Buffer, N, Count);
+}
+
+LONG
+ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode)
+{
+ return ARC_CALL3(seek, FileID, Position, SeekMode);
+}
+
+LONG
+ArcMount(char *name, enum linux_mountops op)
+{
+ return ARC_CALL2(mount, name, op);
+}
+
+LONG
+ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information)
+{
+ return ARC_CALL2(get_finfo, FileID, Information);
+}
+
+LONG ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags,
+ ULONG AttributeMask)
+{
+ return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask);
+}
diff --git a/arch/mips/fw/arc/identify.c b/arch/mips/fw/arc/identify.c
new file mode 100644
index 00000000..788060a5
--- /dev/null
+++ b/arch/mips/fw/arc/identify.c
@@ -0,0 +1,115 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * identify.c: identify machine by looking up system identifier
+ *
+ * Copyright (C) 1998 Thomas Bogendoerfer
+ *
+ * This code is based on arch/mips/sgi/kernel/system.c, which is
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+
+struct smatch {
+ char *arcname;
+ char *liname;
+ int flags;
+};
+
+static struct smatch mach_table[] = {
+ {
+ .arcname = "SGI-IP22",
+ .liname = "SGI Indy",
+ .flags = PROM_FLAG_ARCS,
+ }, {
+ .arcname = "SGI-IP27",
+ .liname = "SGI Origin",
+ .flags = PROM_FLAG_ARCS,
+ }, {
+ .arcname = "SGI-IP28",
+ .liname = "SGI IP28",
+ .flags = PROM_FLAG_ARCS,
+ }, {
+ .arcname = "SGI-IP30",
+ .liname = "SGI Octane",
+ .flags = PROM_FLAG_ARCS,
+ }, {
+ .arcname = "SGI-IP32",
+ .liname = "SGI O2",
+ .flags = PROM_FLAG_ARCS,
+ }, {
+ .arcname = "Microsoft-Jazz",
+ .liname = "Jazz MIPS_Magnum_4000",
+ .flags = 0,
+ }, {
+ .arcname = "PICA-61",
+ .liname = "Jazz Acer_PICA_61",
+ .flags = 0,
+ }, {
+ .arcname = "RM200PCI",
+ .liname = "SNI RM200_PCI",
+ .flags = PROM_FLAG_DONT_FREE_TEMP,
+ }, {
+ .arcname = "RM200PCI-R5K",
+ .liname = "SNI RM200_PCI-R5K",
+ .flags = PROM_FLAG_DONT_FREE_TEMP,
+ }
+};
+
+int prom_flags;
+
+static struct smatch * __init string_to_mach(const char *s)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mach_table); i++) {
+ if (!strcmp(s, mach_table[i].arcname))
+ return &mach_table[i];
+ }
+
+ panic("Yeee, could not determine architecture type <%s>", s);
+}
+
+char *system_type;
+
+const char *get_system_type(void)
+{
+ return system_type;
+}
+
+void __init prom_identify_arch(void)
+{
+ pcomponent *p;
+ struct smatch *mach;
+ const char *iname;
+
+ /*
+ * The root component tells us what machine architecture we have here.
+ */
+ p = ArcGetChild(PROM_NULL_COMPONENT);
+ if (p == NULL) {
+#ifdef CONFIG_SGI_IP27
+ /* IP27 PROM misbehaves, seems to not implement ARC
+ GetChild(). So we just assume it's an IP27. */
+ iname = "SGI-IP27";
+#else
+ iname = "Unknown";
+#endif
+ } else
+ iname = (char *) (long) p->iname;
+
+ printk("ARCH: %s\n", iname);
+ mach = string_to_mach(iname);
+ system_type = mach->liname;
+
+ prom_flags = mach->flags;
+}
diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c
new file mode 100644
index 00000000..629b24db
--- /dev/null
+++ b/arch/mips/fw/arc/init.c
@@ -0,0 +1,59 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * PROM library initialisation code.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <asm/sgialib.h>
+#include <asm/smp-ops.h>
+
+#undef DEBUG_PROM_INIT
+
+/* Master romvec interface. */
+struct linux_romvec *romvec;
+int prom_argc;
+LONG *_prom_argv, *_prom_envp;
+
+void __init prom_init(void)
+{
+ PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK;
+
+ romvec = ROMVECTOR;
+
+ prom_argc = fw_arg0;
+ _prom_argv = (LONG *) fw_arg1;
+ _prom_envp = (LONG *) fw_arg2;
+
+ if (pb->magic != 0x53435241) {
+ printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n",
+ (unsigned long) pb->magic);
+ while(1)
+ ;
+ }
+
+ prom_init_cmdline();
+ prom_identify_arch();
+ printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n",
+ pb->ver, pb->rev);
+ prom_meminit();
+
+#ifdef DEBUG_PROM_INIT
+ pr_info("Press a key to reboot\n");
+ ArcRead(0, &c, 1, &cnt);
+ ArcEnterInteractiveMode();
+#endif
+#ifdef CONFIG_SGI_IP27
+ {
+ extern struct plat_smp_ops ip27_smp_ops;
+
+ register_smp_ops(&ip27_smp_ops);
+ }
+#endif
+}
diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c
new file mode 100644
index 00000000..8b8eea2b
--- /dev/null
+++ b/arch/mips/fw/arc/memory.c
@@ -0,0 +1,160 @@
+/*
+ * memory.c: PROM library functions for acquiring/using memory descriptors
+ * given to us from the ARCS firmware.
+ *
+ * Copyright (C) 1996 by David S. Miller
+ * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to us
+ * from the ARCS firmware. This is only used when CONFIG_ARC_MEMORY is set
+ * because on some machines like SGI IP27 the ARC memory configuration data
+ * completly bogus and alternate easier to use mechanisms are available.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+
+#include <asm/sgialib.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/bootinfo.h>
+
+#undef DEBUG
+
+/*
+ * For ARC firmware memory functions the unit of meassuring memory is always
+ * a 4k page of memory
+ */
+#define ARC_PAGE_SHIFT 12
+
+struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current)
+{
+ return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
+}
+
+#ifdef DEBUG /* convenient for debugging */
+static char *arcs_mtypes[8] = {
+ "Exception Block",
+ "ARCS Romvec Page",
+ "Free/Contig RAM",
+ "Generic Free RAM",
+ "Bad Memory",
+ "Standalone Program Pages",
+ "ARCS Temp Storage Area",
+ "ARCS Permanent Storage Area"
+};
+
+static char *arc_mtypes[8] = {
+ "Exception Block",
+ "SystemParameterBlock",
+ "FreeMemory",
+ "Bad Memory",
+ "LoadedProgram",
+ "FirmwareTemporary",
+ "FirmwarePermanent",
+ "FreeContiguous"
+};
+#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \
+ : arc_mtypes[a.arc]
+#endif
+
+static inline int memtype_classify_arcs(union linux_memtypes type)
+{
+ switch (type.arcs) {
+ case arcs_fcontig:
+ case arcs_free:
+ return BOOT_MEM_RAM;
+ case arcs_atmp:
+ return BOOT_MEM_ROM_DATA;
+ case arcs_eblock:
+ case arcs_rvpage:
+ case arcs_bmem:
+ case arcs_prog:
+ case arcs_aperm:
+ return BOOT_MEM_RESERVED;
+ default:
+ BUG();
+ }
+ while(1); /* Nuke warning. */
+}
+
+static inline int memtype_classify_arc(union linux_memtypes type)
+{
+ switch (type.arc) {
+ case arc_free:
+ case arc_fcontig:
+ return BOOT_MEM_RAM;
+ case arc_atmp:
+ return BOOT_MEM_ROM_DATA;
+ case arc_eblock:
+ case arc_rvpage:
+ case arc_bmem:
+ case arc_prog:
+ case arc_aperm:
+ return BOOT_MEM_RESERVED;
+ default:
+ BUG();
+ }
+ while(1); /* Nuke warning. */
+}
+
+static int __init prom_memtype_classify(union linux_memtypes type)
+{
+ if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */
+ return memtype_classify_arcs(type);
+
+ return memtype_classify_arc(type);
+}
+
+void __init prom_meminit(void)
+{
+ struct linux_mdesc *p;
+
+#ifdef DEBUG
+ int i = 0;
+
+ printk("ARCS MEMORY DESCRIPTOR dump:\n");
+ p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
+ while(p) {
+ printk("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n",
+ i, p, p->base, p->pages, mtypes(p->type));
+ p = ArcGetMemoryDescriptor(p);
+ i++;
+ }
+#endif
+
+ p = PROM_NULL_MDESC;
+ while ((p = ArcGetMemoryDescriptor(p))) {
+ unsigned long base, size;
+ long type;
+
+ base = p->base << ARC_PAGE_SHIFT;
+ size = p->pages << ARC_PAGE_SHIFT;
+ type = prom_memtype_classify(p->type);
+
+ add_memory_region(base, size, type);
+ }
+}
+
+void __init prom_free_prom_memory(void)
+{
+ unsigned long addr;
+ int i;
+
+ if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
+ return;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ free_init_pages("prom memory",
+ addr, addr + boot_mem_map.map[i].size);
+ }
+}
diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c
new file mode 100644
index 00000000..29627fba
--- /dev/null
+++ b/arch/mips/fw/arc/misc.c
@@ -0,0 +1,89 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Miscellaneous ARCS PROM routines.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/bcache.h>
+
+#include <asm/fw/arc/types.h>
+#include <asm/sgialib.h>
+#include <asm/bootinfo.h>
+#include <asm/system.h>
+
+VOID
+ArcHalt(VOID)
+{
+ bc_disable();
+ local_irq_disable();
+ ARC_CALL0(halt);
+never: goto never;
+}
+
+VOID
+ArcPowerDown(VOID)
+{
+ bc_disable();
+ local_irq_disable();
+ ARC_CALL0(pdown);
+never: goto never;
+}
+
+/* XXX is this a soft reset basically? XXX */
+VOID
+ArcRestart(VOID)
+{
+ bc_disable();
+ local_irq_disable();
+ ARC_CALL0(restart);
+never: goto never;
+}
+
+VOID
+ArcReboot(VOID)
+{
+ bc_disable();
+ local_irq_disable();
+ ARC_CALL0(reboot);
+never: goto never;
+}
+
+VOID
+ArcEnterInteractiveMode(VOID)
+{
+ bc_disable();
+ local_irq_disable();
+ ARC_CALL0(imode);
+never: goto never;
+}
+
+LONG
+ArcSaveConfiguration(VOID)
+{
+ return ARC_CALL0(cfg_save);
+}
+
+struct linux_sysid *
+ArcGetSystemId(VOID)
+{
+ return (struct linux_sysid *) ARC_CALL0(get_sysid);
+}
+
+VOID __init
+ArcFlushAllCaches(VOID)
+{
+ ARC_CALL0(cache_flush);
+}
+
+DISPLAY_STATUS * __init ArcGetDisplayStatus(ULONG FileID)
+{
+ return (DISPLAY_STATUS *) ARC_CALL1(GetDisplayStatus, FileID);
+}
diff --git a/arch/mips/fw/arc/promlib.c b/arch/mips/fw/arc/promlib.c
new file mode 100644
index 00000000..b7f9dd3c
--- /dev/null
+++ b/arch/mips/fw/arc/promlib.c
@@ -0,0 +1,43 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@sgi.com)
+ * Compatibility with board caches, Ulf Carlsson
+ */
+#include <linux/kernel.h>
+#include <asm/sgialib.h>
+#include <asm/bcache.h>
+
+/*
+ * IP22 boardcache is not compatible with board caches. Thus we disable it
+ * during romvec action. Since r4xx0.c is always compiled and linked with your
+ * kernel, this shouldn't cause any harm regardless what MIPS processor you
+ * have.
+ *
+ * The ARC write and read functions seem to interfere with the serial lines
+ * in some way. You should be careful with them.
+ */
+
+void prom_putchar(char c)
+{
+ ULONG cnt;
+ CHAR it = c;
+
+ bc_disable();
+ ArcWrite(1, &it, 1, &cnt);
+ bc_enable();
+}
+
+char prom_getchar(void)
+{
+ ULONG cnt;
+ CHAR c;
+
+ bc_disable();
+ ArcRead(0, &c, 1, &cnt);
+ bc_enable();
+
+ return c;
+}
diff --git a/arch/mips/fw/arc/salone.c b/arch/mips/fw/arc/salone.c
new file mode 100644
index 00000000..9b568950
--- /dev/null
+++ b/arch/mips/fw/arc/salone.c
@@ -0,0 +1,24 @@
+/*
+ * Routines to load into memory and execute stand-along program images using
+ * ARCS PROM firmware.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ */
+#include <linux/init.h>
+#include <asm/sgialib.h>
+
+LONG __init ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr)
+{
+ return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr);
+}
+
+LONG __init ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[],
+ CHAR *Envp[])
+{
+ return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp);
+}
+
+LONG __init ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[])
+{
+ return ARC_CALL4(exec, Path, Argc, Argv, Envp);
+}
diff --git a/arch/mips/fw/arc/time.c b/arch/mips/fw/arc/time.c
new file mode 100644
index 00000000..190cdb50
--- /dev/null
+++ b/arch/mips/fw/arc/time.c
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Extracting time information from ARCS prom.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ */
+#include <linux/init.h>
+
+#include <asm/fw/arc/types.h>
+#include <asm/sgialib.h>
+
+struct linux_tinfo * __init
+ArcGetTime(VOID)
+{
+ return (struct linux_tinfo *) ARC_CALL0(get_tinfo);
+}
+
+ULONG __init
+ArcGetRelativeTime(VOID)
+{
+ return ARC_CALL0(get_rtime);
+}
diff --git a/arch/mips/fw/arc/tree.c b/arch/mips/fw/arc/tree.c
new file mode 100644
index 00000000..924a37dc
--- /dev/null
+++ b/arch/mips/fw/arc/tree.c
@@ -0,0 +1,127 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * PROM component device tree code.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <asm/fw/arc/types.h>
+#include <asm/sgialib.h>
+
+#undef DEBUG_PROM_TREE
+
+pcomponent * __init
+ArcGetPeer(pcomponent *Current)
+{
+ if (Current == PROM_NULL_COMPONENT)
+ return PROM_NULL_COMPONENT;
+
+ return (pcomponent *) ARC_CALL1(next_component, Current);
+}
+
+pcomponent * __init
+ArcGetChild(pcomponent *Current)
+{
+ return (pcomponent *) ARC_CALL1(child_component, Current);
+}
+
+pcomponent * __init
+ArcGetParent(pcomponent *Current)
+{
+ if (Current == PROM_NULL_COMPONENT)
+ return PROM_NULL_COMPONENT;
+
+ return (pcomponent *) ARC_CALL1(parent_component, Current);
+}
+
+LONG __init
+ArcGetConfigurationData(VOID *Buffer, pcomponent *Current)
+{
+ return ARC_CALL2(component_data, Buffer, Current);
+}
+
+pcomponent * __init
+ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData)
+{
+ return (pcomponent *)
+ ARC_CALL3(child_add, Current, Template, ConfigurationData);
+}
+
+LONG __init
+ArcDeleteComponent(pcomponent *ComponentToDelete)
+{
+ return ARC_CALL1(comp_del, ComponentToDelete);
+}
+
+pcomponent * __init
+ArcGetComponent(CHAR *Path)
+{
+ return (pcomponent *)ARC_CALL1(component_by_path, Path);
+}
+
+#ifdef DEBUG_PROM_TREE
+
+static char *classes[] = {
+ "system", "processor", "cache", "adapter", "controller", "peripheral",
+ "memory"
+};
+
+static char *types[] = {
+ "arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache",
+ "sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter",
+ "dti adapter", "multi-func adapter", "disk controller",
+ "tp controller", "cdrom controller", "worm controller",
+ "serial controller", "net controller", "display controller",
+ "parallel controller", "pointer controller", "keyboard controller",
+ "audio controller", "misc controller", "disk peripheral",
+ "floppy peripheral", "tp peripheral", "modem peripheral",
+ "monitor peripheral", "printer peripheral", "pointer peripheral",
+ "keyboard peripheral", "terminal peripheral", "line peripheral",
+ "net peripheral", "misc peripheral", "anonymous"
+};
+
+static char *iflags[] = {
+ "bogus", "read only", "removable", "console in", "console out",
+ "input", "output"
+};
+
+static void __init
+dump_component(pcomponent *p)
+{
+ printk("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>",
+ p, classes[p->class], types[p->type],
+ iflags[p->iflags], p->vers, p->rev);
+ printk("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n",
+ p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname);
+}
+
+static void __init
+traverse(pcomponent *p, int op)
+{
+ dump_component(p);
+ if(ArcGetChild(p))
+ traverse(ArcGetChild(p), 1);
+ if(ArcGetPeer(p) && op)
+ traverse(ArcGetPeer(p), 1);
+}
+
+void __init
+prom_testtree(void)
+{
+ pcomponent *p;
+
+ p = ArcGetChild(PROM_NULL_COMPONENT);
+ dump_component(p);
+ p = ArcGetChild(p);
+ while(p) {
+ dump_component(p);
+ p = ArcGetPeer(p);
+ }
+}
+
+#endif /* DEBUG_PROM_TREE */
diff --git a/arch/mips/fw/cfe/Makefile b/arch/mips/fw/cfe/Makefile
new file mode 100644
index 00000000..8f20044c
--- /dev/null
+++ b/arch/mips/fw/cfe/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Broadcom Common Firmware Environment support
+#
+
+lib-y += cfe_api.o
diff --git a/arch/mips/fw/cfe/cfe_api.c b/arch/mips/fw/cfe/cfe_api.c
new file mode 100644
index 00000000..d06dc5a6
--- /dev/null
+++ b/arch/mips/fw/cfe/cfe_api.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ *
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * This module contains device function stubs (small routines to
+ * call the standard "iocb" interface entry point to CFE).
+ * There should be one routine here per iocb function call.
+ *
+ * Authors: Mitch Lichtenberg, Chris Demetriou
+ */
+
+#include <asm/fw/cfe/cfe_api.h>
+#include "cfe_api_int.h"
+
+/* Cast from a native pointer to a cfe_xptr_t and back. */
+#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n))
+#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x))
+
+int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);
+
+/*
+ * Declare the dispatch function with args of "intptr_t".
+ * This makes sure whatever model we're compiling in
+ * puts the pointers in a single register. For example,
+ * combining -mlong64 and -mips1 or -mips2 would lead to
+ * trouble, since the handle and IOCB pointer will be
+ * passed in two registers each, and CFE expects one.
+ */
+
+static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb);
+static u64 cfe_handle;
+
+int cfe_init(u64 handle, u64 ept)
+{
+ cfe_dispfunc = NATIVE_FROM_XPTR(ept);
+ cfe_handle = handle;
+ return 0;
+}
+
+int cfe_iocb_dispatch(struct cfe_xiocb * xiocb)
+{
+ if (!cfe_dispfunc)
+ return -1;
+ return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb);
+}
+
+int cfe_close(int handle)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = handle;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = 0;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.xiocb_status;
+
+}
+
+int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
+ xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
+ xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
+ xiocb.plist.xiocb_cpuctl.gp_val = gp;
+ xiocb.plist.xiocb_cpuctl.sp_val = sp;
+ xiocb.plist.xiocb_cpuctl.a1_val = a1;
+ xiocb.plist.xiocb_cpuctl.start_addr = (long) fn;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.xiocb_status;
+}
+
+int cfe_cpu_stop(int cpu)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
+ xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
+ xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.xiocb_status;
+}
+
+int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
+ xiocb.plist.xiocb_envbuf.enum_idx = idx;
+ xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
+ xiocb.plist.xiocb_envbuf.name_length = namelen;
+ xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
+ xiocb.plist.xiocb_envbuf.val_length = vallen;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.xiocb_status;
+}
+
+int
+cfe_enummem(int idx, int flags, u64 *start, u64 *length, u64 *type)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = flags;
+ xiocb.xiocb_psize = sizeof(struct xiocb_meminfo);
+ xiocb.plist.xiocb_meminfo.mi_idx = idx;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (xiocb.xiocb_status < 0)
+ return xiocb.xiocb_status;
+
+ *start = xiocb.plist.xiocb_meminfo.mi_addr;
+ *length = xiocb.plist.xiocb_meminfo.mi_size;
+ *type = xiocb.plist.xiocb_meminfo.mi_type;
+
+ return 0;
+}
+
+int cfe_exit(int warm, int status)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_exitstat);
+ xiocb.plist.xiocb_exitstat.status = status;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.xiocb_status;
+}
+
+int cfe_flushcache(int flg)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = flg;
+ xiocb.xiocb_psize = 0;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.xiocb_status;
+}
+
+int cfe_getdevinfo(char *name)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
+ xiocb.plist.xiocb_buffer.buf_offset = 0;
+ xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
+ xiocb.plist.xiocb_buffer.buf_length = strlen(name);
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (xiocb.xiocb_status < 0)
+ return xiocb.xiocb_status;
+ return xiocb.plist.xiocb_buffer.buf_ioctlcmd;
+}
+
+int cfe_getenv(char *name, char *dest, int destlen)
+{
+ struct cfe_xiocb xiocb;
+
+ *dest = 0;
+
+ xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
+ xiocb.plist.xiocb_envbuf.enum_idx = 0;
+ xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
+ xiocb.plist.xiocb_envbuf.name_length = strlen(name);
+ xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest);
+ xiocb.plist.xiocb_envbuf.val_length = destlen;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.xiocb_status;
+}
+
+int cfe_getfwinfo(cfe_fwinfo_t * info)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_fwinfo);
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (xiocb.xiocb_status < 0)
+ return xiocb.xiocb_status;
+
+ info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version;
+ info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem;
+ info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags;
+ info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid;
+ info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va;
+ info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa;
+ info->fwi_bootarea_size =
+ xiocb.plist.xiocb_fwinfo.fwi_bootarea_size;
+#if 0
+ info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1;
+ info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2;
+ info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3;
+#endif
+
+ return 0;
+}
+
+int cfe_getstdhandle(int flg)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = flg;
+ xiocb.xiocb_psize = 0;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (xiocb.xiocb_status < 0)
+ return xiocb.xiocb_status;
+ return xiocb.xiocb_handle;
+}
+
+int64_t
+cfe_getticks(void)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_time);
+ xiocb.plist.xiocb_time.ticks = 0;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.plist.xiocb_time.ticks;
+
+}
+
+int cfe_inpstat(int handle)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = handle;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_inpstat);
+ xiocb.plist.xiocb_inpstat.inp_status = 0;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (xiocb.xiocb_status < 0)
+ return xiocb.xiocb_status;
+ return xiocb.plist.xiocb_inpstat.inp_status;
+}
+
+int
+cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
+ int length, int *retlen, u64 offset)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = handle;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
+ xiocb.plist.xiocb_buffer.buf_offset = offset;
+ xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum;
+ xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
+ xiocb.plist.xiocb_buffer.buf_length = length;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (retlen)
+ *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
+ return xiocb.xiocb_status;
+}
+
+int cfe_open(char *name)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
+ xiocb.plist.xiocb_buffer.buf_offset = 0;
+ xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
+ xiocb.plist.xiocb_buffer.buf_length = strlen(name);
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (xiocb.xiocb_status < 0)
+ return xiocb.xiocb_status;
+ return xiocb.xiocb_handle;
+}
+
+int cfe_read(int handle, unsigned char *buffer, int length)
+{
+ return cfe_readblk(handle, 0, buffer, length);
+}
+
+int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = handle;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
+ xiocb.plist.xiocb_buffer.buf_offset = offset;
+ xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
+ xiocb.plist.xiocb_buffer.buf_length = length;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (xiocb.xiocb_status < 0)
+ return xiocb.xiocb_status;
+ return xiocb.plist.xiocb_buffer.buf_retlen;
+}
+
+int cfe_setenv(char *name, char *val)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = 0;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
+ xiocb.plist.xiocb_envbuf.enum_idx = 0;
+ xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
+ xiocb.plist.xiocb_envbuf.name_length = strlen(name);
+ xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
+ xiocb.plist.xiocb_envbuf.val_length = strlen(val);
+
+ cfe_iocb_dispatch(&xiocb);
+
+ return xiocb.xiocb_status;
+}
+
+int cfe_write(int handle, unsigned char *buffer, int length)
+{
+ return cfe_writeblk(handle, 0, buffer, length);
+}
+
+int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length)
+{
+ struct cfe_xiocb xiocb;
+
+ xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
+ xiocb.xiocb_status = 0;
+ xiocb.xiocb_handle = handle;
+ xiocb.xiocb_flags = 0;
+ xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
+ xiocb.plist.xiocb_buffer.buf_offset = offset;
+ xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
+ xiocb.plist.xiocb_buffer.buf_length = length;
+
+ cfe_iocb_dispatch(&xiocb);
+
+ if (xiocb.xiocb_status < 0)
+ return xiocb.xiocb_status;
+ return xiocb.plist.xiocb_buffer.buf_retlen;
+}
diff --git a/arch/mips/fw/cfe/cfe_api_int.h b/arch/mips/fw/cfe/cfe_api_int.h
new file mode 100644
index 00000000..d9759e64
--- /dev/null
+++ b/arch/mips/fw/cfe/cfe_api_int.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef CFE_API_INT_H
+#define CFE_API_INT_H
+
+/*
+ * Constants.
+ */
+#define CFE_CMD_FW_GETINFO 0
+#define CFE_CMD_FW_RESTART 1
+#define CFE_CMD_FW_BOOT 2
+#define CFE_CMD_FW_CPUCTL 3
+#define CFE_CMD_FW_GETTIME 4
+#define CFE_CMD_FW_MEMENUM 5
+#define CFE_CMD_FW_FLUSHCACHE 6
+
+#define CFE_CMD_DEV_GETHANDLE 9
+#define CFE_CMD_DEV_ENUM 10
+#define CFE_CMD_DEV_OPEN 11
+#define CFE_CMD_DEV_INPSTAT 12
+#define CFE_CMD_DEV_READ 13
+#define CFE_CMD_DEV_WRITE 14
+#define CFE_CMD_DEV_IOCTL 15
+#define CFE_CMD_DEV_CLOSE 16
+#define CFE_CMD_DEV_GETINFO 17
+
+#define CFE_CMD_ENV_ENUM 20
+#define CFE_CMD_ENV_GET 22
+#define CFE_CMD_ENV_SET 23
+#define CFE_CMD_ENV_DEL 24
+
+#define CFE_CMD_MAX 32
+
+#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */
+
+/*
+ * Structures.
+ */
+
+/* eeek, signed "pointers" */
+typedef s64 cfe_xptr_t;
+
+struct xiocb_buffer {
+ u64 buf_offset; /* offset on device (bytes) */
+ cfe_xptr_t buf_ptr; /* pointer to a buffer */
+ u64 buf_length; /* length of this buffer */
+ u64 buf_retlen; /* returned length (for read ops) */
+ u64 buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */
+};
+
+struct xiocb_inpstat {
+ u64 inp_status; /* 1 means input available */
+};
+
+struct xiocb_envbuf {
+ s64 enum_idx; /* 0-based enumeration index */
+ cfe_xptr_t name_ptr; /* name string buffer */
+ s64 name_length; /* size of name buffer */
+ cfe_xptr_t val_ptr; /* value string buffer */
+ s64 val_length; /* size of value string buffer */
+};
+
+struct xiocb_cpuctl {
+ u64 cpu_number; /* cpu number to control */
+ u64 cpu_command; /* command to issue to CPU */
+ u64 start_addr; /* CPU start address */
+ u64 gp_val; /* starting GP value */
+ u64 sp_val; /* starting SP value */
+ u64 a1_val; /* starting A1 value */
+};
+
+struct xiocb_time {
+ s64 ticks; /* current time in ticks */
+};
+
+struct xiocb_exitstat{
+ s64 status;
+};
+
+struct xiocb_meminfo {
+ s64 mi_idx; /* 0-based enumeration index */
+ s64 mi_type; /* type of memory block */
+ u64 mi_addr; /* physical start address */
+ u64 mi_size; /* block size */
+};
+
+struct xiocb_fwinfo {
+ s64 fwi_version; /* major, minor, eco version */
+ s64 fwi_totalmem; /* total installed mem */
+ s64 fwi_flags; /* various flags */
+ s64 fwi_boardid; /* board ID */
+ s64 fwi_bootarea_va; /* VA of boot area */
+ s64 fwi_bootarea_pa; /* PA of boot area */
+ s64 fwi_bootarea_size; /* size of boot area */
+ s64 fwi_reserved1;
+ s64 fwi_reserved2;
+ s64 fwi_reserved3;
+};
+
+struct cfe_xiocb {
+ u64 xiocb_fcode; /* IOCB function code */
+ s64 xiocb_status; /* return status */
+ s64 xiocb_handle; /* file/device handle */
+ u64 xiocb_flags; /* flags for this IOCB */
+ u64 xiocb_psize; /* size of parameter list */
+ union {
+ /* buffer parameters */
+ struct xiocb_buffer xiocb_buffer;
+
+ /* input status parameters */
+ struct xiocb_inpstat xiocb_inpstat;
+
+ /* environment function parameters */
+ struct xiocb_envbuf xiocb_envbuf;
+
+ /* CPU control parameters */
+ struct xiocb_cpuctl xiocb_cpuctl;
+
+ /* timer parameters */
+ struct xiocb_time xiocb_time;
+
+ /* memory arena info parameters */
+ struct xiocb_meminfo xiocb_meminfo;
+
+ /* firmware information */
+ struct xiocb_fwinfo xiocb_fwinfo;
+
+ /* Exit Status */
+ struct xiocb_exitstat xiocb_exitstat;
+ } plist;
+};
+
+#endif /* CFE_API_INT_H */
diff --git a/arch/mips/fw/lib/Makefile b/arch/mips/fw/lib/Makefile
new file mode 100644
index 00000000..84befc96
--- /dev/null
+++ b/arch/mips/fw/lib/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for generic prom monitor library routines under Linux.
+#
+
+lib-$(CONFIG_64BIT) += call_o32.o
diff --git a/arch/mips/fw/lib/call_o32.S b/arch/mips/fw/lib/call_o32.S
new file mode 100644
index 00000000..e0a68713
--- /dev/null
+++ b/arch/mips/fw/lib/call_o32.S
@@ -0,0 +1,95 @@
+/*
+ * O32 interface for the 64 (or N32) ABI.
+ *
+ * Copyright (C) 2002 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+/* Maximum number of arguments supported. Must be even! */
+#define O32_ARGC 32
+/* Number of static registers we save. */
+#define O32_STATC 11
+/* Frame size for static register */
+#define O32_FRAMESZ (SZREG * O32_STATC)
+/* Frame size on new stack */
+#define O32_FRAMESZ_NEW (SZREG + 4 * O32_ARGC)
+
+ .text
+
+/*
+ * O32 function call dispatcher, for interfacing 32-bit ROM routines.
+ *
+ * The standard 64 (N32) calling sequence is supported, with a0
+ * holding a function pointer, a1 a new stack pointer, a2-a7 -- its
+ * first six arguments and the stack -- remaining ones (up to O32_ARGC,
+ * including a2-a7). Static registers, gp and fp are preserved, v0 holds
+ * a result. This code relies on the called o32 function for sp and ra
+ * restoration and this dispatcher has to be placed in a KSEGx (or KUSEG)
+ * address space. Any pointers passed have to point to addresses within
+ * one of these spaces as well.
+ */
+NESTED(call_o32, O32_FRAMESZ, ra)
+ REG_SUBU sp,O32_FRAMESZ
+
+ REG_S ra,O32_FRAMESZ-1*SZREG(sp)
+ REG_S fp,O32_FRAMESZ-2*SZREG(sp)
+ REG_S gp,O32_FRAMESZ-3*SZREG(sp)
+ REG_S s7,O32_FRAMESZ-4*SZREG(sp)
+ REG_S s6,O32_FRAMESZ-5*SZREG(sp)
+ REG_S s5,O32_FRAMESZ-6*SZREG(sp)
+ REG_S s4,O32_FRAMESZ-7*SZREG(sp)
+ REG_S s3,O32_FRAMESZ-8*SZREG(sp)
+ REG_S s2,O32_FRAMESZ-9*SZREG(sp)
+ REG_S s1,O32_FRAMESZ-10*SZREG(sp)
+ REG_S s0,O32_FRAMESZ-11*SZREG(sp)
+
+ move jp,a0
+ REG_SUBU s0,a1,O32_FRAMESZ_NEW
+ REG_S sp,O32_FRAMESZ_NEW-1*SZREG(s0)
+
+ sll a0,a2,zero
+ sll a1,a3,zero
+ sll a2,a4,zero
+ sll a3,a5,zero
+ sw a6,0x10(s0)
+ sw a7,0x14(s0)
+
+ PTR_LA t0,O32_FRAMESZ(sp)
+ PTR_LA t1,0x18(s0)
+ li t2,O32_ARGC-6
+1:
+ lw t3,(t0)
+ REG_ADDU t0,SZREG
+ sw t3,(t1)
+ REG_SUBU t2,1
+ REG_ADDU t1,4
+ bnez t2,1b
+
+ move sp,s0
+
+ jalr jp
+
+ REG_L sp,O32_FRAMESZ_NEW-1*SZREG(sp)
+
+ REG_L s0,O32_FRAMESZ-11*SZREG(sp)
+ REG_L s1,O32_FRAMESZ-10*SZREG(sp)
+ REG_L s2,O32_FRAMESZ-9*SZREG(sp)
+ REG_L s3,O32_FRAMESZ-8*SZREG(sp)
+ REG_L s4,O32_FRAMESZ-7*SZREG(sp)
+ REG_L s5,O32_FRAMESZ-6*SZREG(sp)
+ REG_L s6,O32_FRAMESZ-5*SZREG(sp)
+ REG_L s7,O32_FRAMESZ-4*SZREG(sp)
+ REG_L gp,O32_FRAMESZ-3*SZREG(sp)
+ REG_L fp,O32_FRAMESZ-2*SZREG(sp)
+ REG_L ra,O32_FRAMESZ-1*SZREG(sp)
+
+ REG_ADDU sp,O32_FRAMESZ
+ jr ra
+END(call_o32)
diff --git a/arch/mips/fw/sni/Makefile b/arch/mips/fw/sni/Makefile
new file mode 100644
index 00000000..d9740a37
--- /dev/null
+++ b/arch/mips/fw/sni/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the SNI prom monitor routines under Linux.
+#
+
+lib-$(CONFIG_SNIPROM) += sniprom.o
diff --git a/arch/mips/fw/sni/sniprom.c b/arch/mips/fw/sni/sniprom.c
new file mode 100644
index 00000000..96ba9920
--- /dev/null
+++ b/arch/mips/fw/sni/sniprom.c
@@ -0,0 +1,151 @@
+/*
+ * Big Endian PROM code for SNI RM machines
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
+ * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/console.h>
+
+#include <asm/addrspace.h>
+#include <asm/sni.h>
+#include <asm/mipsprom.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+
+/* special SNI prom calls */
+/*
+ * This does not exist in all proms - SINIX compares
+ * the prom env variable "version" against "2.0008"
+ * or greater. If lesser it tries to probe interesting
+ * registers
+ */
+#define PROM_GET_MEMCONF 58
+#define PROM_GET_HWCONF 61
+
+#define PROM_VEC (u64 *)CKSEG1ADDR(0x1fc00000)
+#define PROM_ENTRY(x) (PROM_VEC + (x))
+
+#define ___prom_putchar ((int *(*)(int))PROM_ENTRY(PROM_PUTCHAR))
+#define ___prom_getenv ((char *(*)(char *))PROM_ENTRY(PROM_GETENV))
+#define ___prom_get_memconf ((void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF))
+#define ___prom_get_hwconf ((u32 (*)(void))PROM_ENTRY(PROM_GET_HWCONF))
+
+#ifdef CONFIG_64BIT
+
+static u8 o32_stk[16384];
+#define O32_STK &o32_stk[sizeof(o32_stk)]
+
+#define __PROM_O32(fun, arg) fun arg __asm__(#fun); \
+ __asm__(#fun " = call_o32")
+
+int __PROM_O32(__prom_putchar, (int *(*)(int), void *, int));
+char *__PROM_O32(__prom_getenv, (char *(*)(char *), void *, char *));
+void __PROM_O32(__prom_get_memconf, (void (*)(void *), void *, void *));
+u32 __PROM_O32(__prom_get_hwconf, (u32 (*)(void), void *));
+
+#define _prom_putchar(x) __prom_putchar(___prom_putchar, O32_STK, x)
+#define _prom_getenv(x) __prom_getenv(___prom_getenv, O32_STK, x)
+#define _prom_get_memconf(x) __prom_get_memconf(___prom_get_memconf, O32_STK, x)
+#define _prom_get_hwconf() __prom_get_hwconf(___prom_get_hwconf, O32_STK)
+
+#else
+#define _prom_putchar(x) ___prom_putchar(x)
+#define _prom_getenv(x) ___prom_getenv(x)
+#define _prom_get_memconf(x) ___prom_get_memconf(x)
+#define _prom_get_hwconf(x) ___prom_get_hwconf(x)
+#endif
+
+void prom_putchar(char c)
+{
+ _prom_putchar(c);
+}
+
+
+char *prom_getenv(char *s)
+{
+ return _prom_getenv(s);
+}
+
+void *prom_get_hwconf(void)
+{
+ u32 hwconf = _prom_get_hwconf();
+
+ if (hwconf == 0xffffffff)
+ return NULL;
+
+ return (void *)CKSEG1ADDR(hwconf);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+/*
+ * /proc/cpuinfo system type
+ *
+ */
+char *system_type = "Unknown";
+const char *get_system_type(void)
+{
+ return system_type;
+}
+
+static void __init sni_mem_init(void)
+{
+ int i, memsize;
+ struct membank {
+ u32 size;
+ u32 base;
+ u32 size2;
+ u32 pad1;
+ u32 pad2;
+ } memconf[8];
+ int brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
+
+
+ /* MemSIZE from prom in 16MByte chunks */
+ memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;
+
+ pr_debug("IDProm memsize: %u MByte\n", memsize);
+
+ /* get memory bank layout from prom */
+ _prom_get_memconf(&memconf);
+
+ pr_debug("prom_get_mem_conf memory configuration:\n");
+ for (i = 0; i < 8 && memconf[i].size; i++) {
+ if (brd_type == SNI_BRD_PCI_TOWER ||
+ brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
+ if (memconf[i].base >= 0x20000000 &&
+ memconf[i].base < 0x30000000)
+ memconf[i].base -= 0x20000000;
+ }
+ pr_debug("Bank%d: %08x @ %08x\n", i,
+ memconf[i].size, memconf[i].base);
+ add_memory_region(memconf[i].base, memconf[i].size,
+ BOOT_MEM_RAM);
+ }
+}
+
+void __init prom_init(void)
+{
+ int argc = fw_arg0;
+ u32 *argv = (u32 *)CKSEG0ADDR(fw_arg1);
+ int i;
+
+ sni_mem_init();
+
+ /* copy prom cmdline parameters to kernel cmdline */
+ for (i = 1; i < argc; i++) {
+ strcat(arcs_cmdline, (char *)CKSEG0ADDR(argv[i]));
+ if (i < (argc - 1))
+ strcat(arcs_cmdline, " ");
+ }
+}
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
new file mode 100644
index 00000000..7897f05e
--- /dev/null
+++ b/arch/mips/include/asm/Kbuild
@@ -0,0 +1,3 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += cachectl.h sgidefs.h sysmips.h
diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h
new file mode 100644
index 00000000..9252d9b5
--- /dev/null
+++ b/arch/mips/include/asm/abi.h
@@ -0,0 +1,27 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005, 06 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2005 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_ABI_H
+#define _ASM_ABI_H
+
+#include <asm/signal.h>
+#include <asm/siginfo.h>
+
+struct mips_abi {
+ int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr,
+ sigset_t *set);
+ const unsigned long signal_return_offset;
+ int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr,
+ sigset_t *set, siginfo_t *info);
+ const unsigned long rt_signal_return_offset;
+ const unsigned long restart;
+};
+
+#endif /* _ASM_ABI_H */
diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h
new file mode 100644
index 00000000..569f80aa
--- /dev/null
+++ b/arch/mips/include/asm/addrspace.h
@@ -0,0 +1,154 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 99 Ralf Baechle
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki
+ * Copyright (C) 1990, 1999 by Silicon Graphics, Inc.
+ */
+#ifndef _ASM_ADDRSPACE_H
+#define _ASM_ADDRSPACE_H
+
+#include <spaces.h>
+
+/*
+ * Configure language
+ */
+#ifdef __ASSEMBLY__
+#define _ATYPE_
+#define _ATYPE32_
+#define _ATYPE64_
+#define _CONST64_(x) x
+#else
+#define _ATYPE_ __PTRDIFF_TYPE__
+#define _ATYPE32_ int
+#define _ATYPE64_ __s64
+#ifdef CONFIG_64BIT
+#define _CONST64_(x) x ## L
+#else
+#define _CONST64_(x) x ## LL
+#endif
+#endif
+
+/*
+ * 32-bit MIPS address spaces
+ */
+#ifdef __ASSEMBLY__
+#define _ACAST32_
+#define _ACAST64_
+#else
+#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */
+#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */
+#endif
+
+/*
+ * Returns the kernel segment base of a given address
+ */
+#define KSEGX(a) ((_ACAST32_ (a)) & 0xe0000000)
+
+/*
+ * Returns the physical address of a CKSEGx / XKPHYS address
+ */
+#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
+#define XPHYSADDR(a) ((_ACAST64_(a)) & \
+ _CONST64_(0x000000ffffffffff))
+
+#ifdef CONFIG_64BIT
+
+/*
+ * Memory segments (64bit kernel mode addresses)
+ * The compatibility segments use the full 64-bit sign extended value. Note
+ * the R8000 doesn't have them so don't reference these in generic MIPS code.
+ */
+#define XKUSEG _CONST64_(0x0000000000000000)
+#define XKSSEG _CONST64_(0x4000000000000000)
+#define XKPHYS _CONST64_(0x8000000000000000)
+#define XKSEG _CONST64_(0xc000000000000000)
+#define CKSEG0 _CONST64_(0xffffffff80000000)
+#define CKSEG1 _CONST64_(0xffffffffa0000000)
+#define CKSSEG _CONST64_(0xffffffffc0000000)
+#define CKSEG3 _CONST64_(0xffffffffe0000000)
+
+#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0)
+#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1)
+#define CKSEG2ADDR(a) (CPHYSADDR(a) | CKSEG2)
+#define CKSEG3ADDR(a) (CPHYSADDR(a) | CKSEG3)
+
+#else
+
+#define CKSEG0ADDR(a) (CPHYSADDR(a) | KSEG0)
+#define CKSEG1ADDR(a) (CPHYSADDR(a) | KSEG1)
+#define CKSEG2ADDR(a) (CPHYSADDR(a) | KSEG2)
+#define CKSEG3ADDR(a) (CPHYSADDR(a) | KSEG3)
+
+/*
+ * Map an address to a certain kernel segment
+ */
+#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0)
+#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1)
+#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2)
+#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3)
+
+/*
+ * Memory segments (32bit kernel mode addresses)
+ * These are the traditional names used in the 32-bit universe.
+ */
+#define KUSEG 0x00000000
+#define KSEG0 0x80000000
+#define KSEG1 0xa0000000
+#define KSEG2 0xc0000000
+#define KSEG3 0xe0000000
+
+#define CKUSEG 0x00000000
+#define CKSEG0 0x80000000
+#define CKSEG1 0xa0000000
+#define CKSEG2 0xc0000000
+#define CKSEG3 0xe0000000
+
+#endif
+
+/*
+ * Cache modes for XKPHYS address conversion macros
+ */
+#define K_CALG_COH_EXCL1_NOL2 0
+#define K_CALG_COH_SHRL1_NOL2 1
+#define K_CALG_UNCACHED 2
+#define K_CALG_NONCOHERENT 3
+#define K_CALG_COH_EXCL 4
+#define K_CALG_COH_SHAREABLE 5
+#define K_CALG_NOTUSED 6
+#define K_CALG_UNCACHED_ACCEL 7
+
+/*
+ * 64-bit address conversions
+ */
+#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED, (p))
+#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p))
+#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK)
+#define PHYS_TO_XKPHYS(cm, a) (_CONST64_(0x8000000000000000) | \
+ (_CONST64_(cm) << 59) | (a))
+
+/*
+ * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting
+ * the region, 3 bits for the CCA mode. This leaves 59 bits of which the
+ * R8000 implements most with its 48-bit physical address space.
+ */
+#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
+
+#ifndef CONFIG_CPU_R8000
+
+/*
+ * The R8000 doesn't have the 32-bit compat spaces so we don't define them
+ * in order to catch bugs in the source code.
+ */
+
+#define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000)
+#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
+
+#endif
+
+#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK)
+#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
+
+#endif /* _ASM_ADDRSPACE_H */
diff --git a/arch/mips/include/asm/amon.h b/arch/mips/include/asm/amon.h
new file mode 100644
index 00000000..c3dc1a68
--- /dev/null
+++ b/arch/mips/include/asm/amon.h
@@ -0,0 +1,7 @@
+/*
+ * Amon support
+ */
+
+int amon_cpu_avail(int);
+void amon_cpu_start(int, unsigned long, unsigned long,
+ unsigned long, unsigned long);
diff --git a/arch/mips/include/asm/arch_hweight.h b/arch/mips/include/asm/arch_hweight.h
new file mode 100644
index 00000000..712a7445
--- /dev/null
+++ b/arch/mips/include/asm/arch_hweight.h
@@ -0,0 +1,38 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef _ASM_ARCH_HWEIGHT_H
+#define _ASM_ARCH_HWEIGHT_H
+
+#ifdef ARCH_HAS_USABLE_BUILTIN_POPCOUNT
+
+#include <asm/types.h>
+
+static inline unsigned int __arch_hweight32(unsigned int w)
+{
+ return __builtin_popcount(w);
+}
+
+static inline unsigned int __arch_hweight16(unsigned int w)
+{
+ return __builtin_popcount(w & 0xffff);
+}
+
+static inline unsigned int __arch_hweight8(unsigned int w)
+{
+ return __builtin_popcount(w & 0xff);
+}
+
+static inline unsigned long __arch_hweight64(__u64 w)
+{
+ return __builtin_popcountll(w);
+}
+
+#else
+#include <asm-generic/bitops/arch_hweight.h>
+#endif
+
+#endif /* _ASM_ARCH_HWEIGHT_H */
diff --git a/arch/mips/include/asm/asm-offsets.h b/arch/mips/include/asm/asm-offsets.h
new file mode 100644
index 00000000..d370ee36
--- /dev/null
+++ b/arch/mips/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h
new file mode 100644
index 00000000..608cfcfb
--- /dev/null
+++ b/arch/mips/include/asm/asm.h
@@ -0,0 +1,409 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2002 Maciej W. Rozycki
+ *
+ * Some useful macros for MIPS assembler code
+ *
+ * Some of the routines below contain useless nops that will be optimized
+ * away by gas in -O mode. These nops are however required to fill delay
+ * slots in noreorder mode.
+ */
+#ifndef __ASM_ASM_H
+#define __ASM_ASM_H
+
+#include <asm/sgidefs.h>
+
+#ifndef CAT
+#ifdef __STDC__
+#define __CAT(str1, str2) str1##str2
+#else
+#define __CAT(str1, str2) str1/**/str2
+#endif
+#define CAT(str1, str2) __CAT(str1, str2)
+#endif
+
+/*
+ * PIC specific declarations
+ * Not used for the kernel but here seems to be the right place.
+ */
+#ifdef __PIC__
+#define CPRESTORE(register) \
+ .cprestore register
+#define CPADD(register) \
+ .cpadd register
+#define CPLOAD(register) \
+ .cpload register
+#else
+#define CPRESTORE(register)
+#define CPADD(register)
+#define CPLOAD(register)
+#endif
+
+/*
+ * LEAF - declare leaf routine
+ */
+#define LEAF(symbol) \
+ .globl symbol; \
+ .align 2; \
+ .type symbol, @function; \
+ .ent symbol, 0; \
+symbol: .frame sp, 0, ra
+
+/*
+ * NESTED - declare nested routine entry point
+ */
+#define NESTED(symbol, framesize, rpc) \
+ .globl symbol; \
+ .align 2; \
+ .type symbol, @function; \
+ .ent symbol, 0; \
+symbol: .frame sp, framesize, rpc
+
+/*
+ * END - mark end of function
+ */
+#define END(function) \
+ .end function; \
+ .size function, .-function
+
+/*
+ * EXPORT - export definition of symbol
+ */
+#define EXPORT(symbol) \
+ .globl symbol; \
+symbol:
+
+/*
+ * FEXPORT - export definition of a function symbol
+ */
+#define FEXPORT(symbol) \
+ .globl symbol; \
+ .type symbol, @function; \
+symbol:
+
+/*
+ * ABS - export absolute symbol
+ */
+#define ABS(symbol,value) \
+ .globl symbol; \
+symbol = value
+
+#define PANIC(msg) \
+ .set push; \
+ .set reorder; \
+ PTR_LA a0, 8f; \
+ jal panic; \
+9: b 9b; \
+ .set pop; \
+ TEXT(msg)
+
+/*
+ * Print formatted string
+ */
+#ifdef CONFIG_PRINTK
+#define PRINT(string) \
+ .set push; \
+ .set reorder; \
+ PTR_LA a0, 8f; \
+ jal printk; \
+ .set pop; \
+ TEXT(string)
+#else
+#define PRINT(string)
+#endif
+
+#define TEXT(msg) \
+ .pushsection .data; \
+8: .asciiz msg; \
+ .popsection;
+
+/*
+ * Build text tables
+ */
+#define TTABLE(string) \
+ .pushsection .text; \
+ .word 1f; \
+ .popsection \
+ .pushsection .data; \
+1: .asciiz string; \
+ .popsection
+
+/*
+ * MIPS IV pref instruction.
+ * Use with .set noreorder only!
+ *
+ * MIPS IV implementations are free to treat this as a nop. The R5000
+ * is one of them. So we should have an option not to use this instruction.
+ */
+#ifdef CONFIG_CPU_HAS_PREFETCH
+
+#define PREF(hint,addr) \
+ .set push; \
+ .set mips4; \
+ pref hint, addr; \
+ .set pop
+
+#define PREFX(hint,addr) \
+ .set push; \
+ .set mips4; \
+ prefx hint, addr; \
+ .set pop
+
+#else /* !CONFIG_CPU_HAS_PREFETCH */
+
+#define PREF(hint, addr)
+#define PREFX(hint, addr)
+
+#endif /* !CONFIG_CPU_HAS_PREFETCH */
+
+/*
+ * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
+ */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1)
+#define MOVN(rd, rs, rt) \
+ .set push; \
+ .set reorder; \
+ beqz rt, 9f; \
+ move rd, rs; \
+ .set pop; \
+9:
+#define MOVZ(rd, rs, rt) \
+ .set push; \
+ .set reorder; \
+ bnez rt, 9f; \
+ move rd, rs; \
+ .set pop; \
+9:
+#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
+#define MOVN(rd, rs, rt) \
+ .set push; \
+ .set noreorder; \
+ bnezl rt, 9f; \
+ move rd, rs; \
+ .set pop; \
+9:
+#define MOVZ(rd, rs, rt) \
+ .set push; \
+ .set noreorder; \
+ beqzl rt, 9f; \
+ move rd, rs; \
+ .set pop; \
+9:
+#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
+#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
+#define MOVN(rd, rs, rt) \
+ movn rd, rs, rt
+#define MOVZ(rd, rs, rt) \
+ movz rd, rs, rt
+#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
+
+/*
+ * Stack alignment
+ */
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
+#define ALSZ 7
+#define ALMASK ~7
+#endif
+#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
+#define ALSZ 15
+#define ALMASK ~15
+#endif
+
+/*
+ * Macros to handle different pointer/register sizes for 32/64-bit code
+ */
+
+/*
+ * Size of a register
+ */
+#ifdef __mips64
+#define SZREG 8
+#else
+#define SZREG 4
+#endif
+
+/*
+ * Use the following macros in assemblercode to load/store registers,
+ * pointers etc.
+ */
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
+#define REG_S sw
+#define REG_L lw
+#define REG_SUBU subu
+#define REG_ADDU addu
+#endif
+#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
+#define REG_S sd
+#define REG_L ld
+#define REG_SUBU dsubu
+#define REG_ADDU daddu
+#endif
+
+/*
+ * How to add/sub/load/store/shift C int variables.
+ */
+#if (_MIPS_SZINT == 32)
+#define INT_ADD add
+#define INT_ADDU addu
+#define INT_ADDI addi
+#define INT_ADDIU addiu
+#define INT_SUB sub
+#define INT_SUBU subu
+#define INT_L lw
+#define INT_S sw
+#define INT_SLL sll
+#define INT_SLLV sllv
+#define INT_SRL srl
+#define INT_SRLV srlv
+#define INT_SRA sra
+#define INT_SRAV srav
+#endif
+
+#if (_MIPS_SZINT == 64)
+#define INT_ADD dadd
+#define INT_ADDU daddu
+#define INT_ADDI daddi
+#define INT_ADDIU daddiu
+#define INT_SUB dsub
+#define INT_SUBU dsubu
+#define INT_L ld
+#define INT_S sd
+#define INT_SLL dsll
+#define INT_SLLV dsllv
+#define INT_SRL dsrl
+#define INT_SRLV dsrlv
+#define INT_SRA dsra
+#define INT_SRAV dsrav
+#endif
+
+/*
+ * How to add/sub/load/store/shift C long variables.
+ */
+#if (_MIPS_SZLONG == 32)
+#define LONG_ADD add
+#define LONG_ADDU addu
+#define LONG_ADDI addi
+#define LONG_ADDIU addiu
+#define LONG_SUB sub
+#define LONG_SUBU subu
+#define LONG_L lw
+#define LONG_S sw
+#define LONG_SLL sll
+#define LONG_SLLV sllv
+#define LONG_SRL srl
+#define LONG_SRLV srlv
+#define LONG_SRA sra
+#define LONG_SRAV srav
+
+#define LONG .word
+#define LONGSIZE 4
+#define LONGMASK 3
+#define LONGLOG 2
+#endif
+
+#if (_MIPS_SZLONG == 64)
+#define LONG_ADD dadd
+#define LONG_ADDU daddu
+#define LONG_ADDI daddi
+#define LONG_ADDIU daddiu
+#define LONG_SUB dsub
+#define LONG_SUBU dsubu
+#define LONG_L ld
+#define LONG_S sd
+#define LONG_SLL dsll
+#define LONG_SLLV dsllv
+#define LONG_SRL dsrl
+#define LONG_SRLV dsrlv
+#define LONG_SRA dsra
+#define LONG_SRAV dsrav
+
+#define LONG .dword
+#define LONGSIZE 8
+#define LONGMASK 7
+#define LONGLOG 3
+#endif
+
+/*
+ * How to add/sub/load/store/shift pointers.
+ */
+#if (_MIPS_SZPTR == 32)
+#define PTR_ADD add
+#define PTR_ADDU addu
+#define PTR_ADDI addi
+#define PTR_ADDIU addiu
+#define PTR_SUB sub
+#define PTR_SUBU subu
+#define PTR_L lw
+#define PTR_S sw
+#define PTR_LA la
+#define PTR_LI li
+#define PTR_SLL sll
+#define PTR_SLLV sllv
+#define PTR_SRL srl
+#define PTR_SRLV srlv
+#define PTR_SRA sra
+#define PTR_SRAV srav
+
+#define PTR_SCALESHIFT 2
+
+#define PTR .word
+#define PTRSIZE 4
+#define PTRLOG 2
+#endif
+
+#if (_MIPS_SZPTR == 64)
+#define PTR_ADD dadd
+#define PTR_ADDU daddu
+#define PTR_ADDI daddi
+#define PTR_ADDIU daddiu
+#define PTR_SUB dsub
+#define PTR_SUBU dsubu
+#define PTR_L ld
+#define PTR_S sd
+#define PTR_LA dla
+#define PTR_LI dli
+#define PTR_SLL dsll
+#define PTR_SLLV dsllv
+#define PTR_SRL dsrl
+#define PTR_SRLV dsrlv
+#define PTR_SRA dsra
+#define PTR_SRAV dsrav
+
+#define PTR_SCALESHIFT 3
+
+#define PTR .dword
+#define PTRSIZE 8
+#define PTRLOG 3
+#endif
+
+/*
+ * Some cp0 registers were extended to 64bit for MIPS III.
+ */
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
+#define MFC0 mfc0
+#define MTC0 mtc0
+#endif
+#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
+#define MFC0 dmfc0
+#define MTC0 dmtc0
+#endif
+
+#define SSNOP sll zero, zero, 1
+
+#ifdef CONFIG_SGI_IP28
+/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
+#include <asm/cacheops.h>
+#define R10KCBARRIER(addr) cache Cache_Barrier, addr;
+#else
+#define R10KCBARRIER(addr)
+#endif
+
+#endif /* __ASM_ASM_H */
diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h
new file mode 100644
index 00000000..2413afe2
--- /dev/null
+++ b/arch/mips/include/asm/asmmacro-32.h
@@ -0,0 +1,158 @@
+/*
+ * asmmacro.h: Assembler macros to make things easier to read.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1998, 1999, 2003 Ralf Baechle
+ */
+#ifndef _ASM_ASMMACRO_32_H
+#define _ASM_ASMMACRO_32_H
+
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+
+ .macro fpu_save_double thread status tmp1=t0
+ cfc1 \tmp1, fcr31
+ sdc1 $f0, THREAD_FPR0(\thread)
+ sdc1 $f2, THREAD_FPR2(\thread)
+ sdc1 $f4, THREAD_FPR4(\thread)
+ sdc1 $f6, THREAD_FPR6(\thread)
+ sdc1 $f8, THREAD_FPR8(\thread)
+ sdc1 $f10, THREAD_FPR10(\thread)
+ sdc1 $f12, THREAD_FPR12(\thread)
+ sdc1 $f14, THREAD_FPR14(\thread)
+ sdc1 $f16, THREAD_FPR16(\thread)
+ sdc1 $f18, THREAD_FPR18(\thread)
+ sdc1 $f20, THREAD_FPR20(\thread)
+ sdc1 $f22, THREAD_FPR22(\thread)
+ sdc1 $f24, THREAD_FPR24(\thread)
+ sdc1 $f26, THREAD_FPR26(\thread)
+ sdc1 $f28, THREAD_FPR28(\thread)
+ sdc1 $f30, THREAD_FPR30(\thread)
+ sw \tmp1, THREAD_FCR31(\thread)
+ .endm
+
+ .macro fpu_save_single thread tmp=t0
+ cfc1 \tmp, fcr31
+ swc1 $f0, THREAD_FPR0(\thread)
+ swc1 $f1, THREAD_FPR1(\thread)
+ swc1 $f2, THREAD_FPR2(\thread)
+ swc1 $f3, THREAD_FPR3(\thread)
+ swc1 $f4, THREAD_FPR4(\thread)
+ swc1 $f5, THREAD_FPR5(\thread)
+ swc1 $f6, THREAD_FPR6(\thread)
+ swc1 $f7, THREAD_FPR7(\thread)
+ swc1 $f8, THREAD_FPR8(\thread)
+ swc1 $f9, THREAD_FPR9(\thread)
+ swc1 $f10, THREAD_FPR10(\thread)
+ swc1 $f11, THREAD_FPR11(\thread)
+ swc1 $f12, THREAD_FPR12(\thread)
+ swc1 $f13, THREAD_FPR13(\thread)
+ swc1 $f14, THREAD_FPR14(\thread)
+ swc1 $f15, THREAD_FPR15(\thread)
+ swc1 $f16, THREAD_FPR16(\thread)
+ swc1 $f17, THREAD_FPR17(\thread)
+ swc1 $f18, THREAD_FPR18(\thread)
+ swc1 $f19, THREAD_FPR19(\thread)
+ swc1 $f20, THREAD_FPR20(\thread)
+ swc1 $f21, THREAD_FPR21(\thread)
+ swc1 $f22, THREAD_FPR22(\thread)
+ swc1 $f23, THREAD_FPR23(\thread)
+ swc1 $f24, THREAD_FPR24(\thread)
+ swc1 $f25, THREAD_FPR25(\thread)
+ swc1 $f26, THREAD_FPR26(\thread)
+ swc1 $f27, THREAD_FPR27(\thread)
+ swc1 $f28, THREAD_FPR28(\thread)
+ swc1 $f29, THREAD_FPR29(\thread)
+ swc1 $f30, THREAD_FPR30(\thread)
+ swc1 $f31, THREAD_FPR31(\thread)
+ sw \tmp, THREAD_FCR31(\thread)
+ .endm
+
+ .macro fpu_restore_double thread status tmp=t0
+ lw \tmp, THREAD_FCR31(\thread)
+ ldc1 $f0, THREAD_FPR0(\thread)
+ ldc1 $f2, THREAD_FPR2(\thread)
+ ldc1 $f4, THREAD_FPR4(\thread)
+ ldc1 $f6, THREAD_FPR6(\thread)
+ ldc1 $f8, THREAD_FPR8(\thread)
+ ldc1 $f10, THREAD_FPR10(\thread)
+ ldc1 $f12, THREAD_FPR12(\thread)
+ ldc1 $f14, THREAD_FPR14(\thread)
+ ldc1 $f16, THREAD_FPR16(\thread)
+ ldc1 $f18, THREAD_FPR18(\thread)
+ ldc1 $f20, THREAD_FPR20(\thread)
+ ldc1 $f22, THREAD_FPR22(\thread)
+ ldc1 $f24, THREAD_FPR24(\thread)
+ ldc1 $f26, THREAD_FPR26(\thread)
+ ldc1 $f28, THREAD_FPR28(\thread)
+ ldc1 $f30, THREAD_FPR30(\thread)
+ ctc1 \tmp, fcr31
+ .endm
+
+ .macro fpu_restore_single thread tmp=t0
+ lw \tmp, THREAD_FCR31(\thread)
+ lwc1 $f0, THREAD_FPR0(\thread)
+ lwc1 $f1, THREAD_FPR1(\thread)
+ lwc1 $f2, THREAD_FPR2(\thread)
+ lwc1 $f3, THREAD_FPR3(\thread)
+ lwc1 $f4, THREAD_FPR4(\thread)
+ lwc1 $f5, THREAD_FPR5(\thread)
+ lwc1 $f6, THREAD_FPR6(\thread)
+ lwc1 $f7, THREAD_FPR7(\thread)
+ lwc1 $f8, THREAD_FPR8(\thread)
+ lwc1 $f9, THREAD_FPR9(\thread)
+ lwc1 $f10, THREAD_FPR10(\thread)
+ lwc1 $f11, THREAD_FPR11(\thread)
+ lwc1 $f12, THREAD_FPR12(\thread)
+ lwc1 $f13, THREAD_FPR13(\thread)
+ lwc1 $f14, THREAD_FPR14(\thread)
+ lwc1 $f15, THREAD_FPR15(\thread)
+ lwc1 $f16, THREAD_FPR16(\thread)
+ lwc1 $f17, THREAD_FPR17(\thread)
+ lwc1 $f18, THREAD_FPR18(\thread)
+ lwc1 $f19, THREAD_FPR19(\thread)
+ lwc1 $f20, THREAD_FPR20(\thread)
+ lwc1 $f21, THREAD_FPR21(\thread)
+ lwc1 $f22, THREAD_FPR22(\thread)
+ lwc1 $f23, THREAD_FPR23(\thread)
+ lwc1 $f24, THREAD_FPR24(\thread)
+ lwc1 $f25, THREAD_FPR25(\thread)
+ lwc1 $f26, THREAD_FPR26(\thread)
+ lwc1 $f27, THREAD_FPR27(\thread)
+ lwc1 $f28, THREAD_FPR28(\thread)
+ lwc1 $f29, THREAD_FPR29(\thread)
+ lwc1 $f30, THREAD_FPR30(\thread)
+ lwc1 $f31, THREAD_FPR31(\thread)
+ ctc1 \tmp, fcr31
+ .endm
+
+ .macro cpu_save_nonscratch thread
+ LONG_S s0, THREAD_REG16(\thread)
+ LONG_S s1, THREAD_REG17(\thread)
+ LONG_S s2, THREAD_REG18(\thread)
+ LONG_S s3, THREAD_REG19(\thread)
+ LONG_S s4, THREAD_REG20(\thread)
+ LONG_S s5, THREAD_REG21(\thread)
+ LONG_S s6, THREAD_REG22(\thread)
+ LONG_S s7, THREAD_REG23(\thread)
+ LONG_S sp, THREAD_REG29(\thread)
+ LONG_S fp, THREAD_REG30(\thread)
+ .endm
+
+ .macro cpu_restore_nonscratch thread
+ LONG_L s0, THREAD_REG16(\thread)
+ LONG_L s1, THREAD_REG17(\thread)
+ LONG_L s2, THREAD_REG18(\thread)
+ LONG_L s3, THREAD_REG19(\thread)
+ LONG_L s4, THREAD_REG20(\thread)
+ LONG_L s5, THREAD_REG21(\thread)
+ LONG_L s6, THREAD_REG22(\thread)
+ LONG_L s7, THREAD_REG23(\thread)
+ LONG_L sp, THREAD_REG29(\thread)
+ LONG_L fp, THREAD_REG30(\thread)
+ LONG_L ra, THREAD_REG31(\thread)
+ .endm
+
+#endif /* _ASM_ASMMACRO_32_H */
diff --git a/arch/mips/include/asm/asmmacro-64.h b/arch/mips/include/asm/asmmacro-64.h
new file mode 100644
index 00000000..08a527df
--- /dev/null
+++ b/arch/mips/include/asm/asmmacro-64.h
@@ -0,0 +1,139 @@
+/*
+ * asmmacro.h: Assembler macros to make things easier to read.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_ASMMACRO_64_H
+#define _ASM_ASMMACRO_64_H
+
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+
+ .macro fpu_save_16even thread tmp=t0
+ cfc1 \tmp, fcr31
+ sdc1 $f0, THREAD_FPR0(\thread)
+ sdc1 $f2, THREAD_FPR2(\thread)
+ sdc1 $f4, THREAD_FPR4(\thread)
+ sdc1 $f6, THREAD_FPR6(\thread)
+ sdc1 $f8, THREAD_FPR8(\thread)
+ sdc1 $f10, THREAD_FPR10(\thread)
+ sdc1 $f12, THREAD_FPR12(\thread)
+ sdc1 $f14, THREAD_FPR14(\thread)
+ sdc1 $f16, THREAD_FPR16(\thread)
+ sdc1 $f18, THREAD_FPR18(\thread)
+ sdc1 $f20, THREAD_FPR20(\thread)
+ sdc1 $f22, THREAD_FPR22(\thread)
+ sdc1 $f24, THREAD_FPR24(\thread)
+ sdc1 $f26, THREAD_FPR26(\thread)
+ sdc1 $f28, THREAD_FPR28(\thread)
+ sdc1 $f30, THREAD_FPR30(\thread)
+ sw \tmp, THREAD_FCR31(\thread)
+ .endm
+
+ .macro fpu_save_16odd thread
+ sdc1 $f1, THREAD_FPR1(\thread)
+ sdc1 $f3, THREAD_FPR3(\thread)
+ sdc1 $f5, THREAD_FPR5(\thread)
+ sdc1 $f7, THREAD_FPR7(\thread)
+ sdc1 $f9, THREAD_FPR9(\thread)
+ sdc1 $f11, THREAD_FPR11(\thread)
+ sdc1 $f13, THREAD_FPR13(\thread)
+ sdc1 $f15, THREAD_FPR15(\thread)
+ sdc1 $f17, THREAD_FPR17(\thread)
+ sdc1 $f19, THREAD_FPR19(\thread)
+ sdc1 $f21, THREAD_FPR21(\thread)
+ sdc1 $f23, THREAD_FPR23(\thread)
+ sdc1 $f25, THREAD_FPR25(\thread)
+ sdc1 $f27, THREAD_FPR27(\thread)
+ sdc1 $f29, THREAD_FPR29(\thread)
+ sdc1 $f31, THREAD_FPR31(\thread)
+ .endm
+
+ .macro fpu_save_double thread status tmp
+ sll \tmp, \status, 5
+ bgez \tmp, 2f
+ fpu_save_16odd \thread
+2:
+ fpu_save_16even \thread \tmp
+ .endm
+
+ .macro fpu_restore_16even thread tmp=t0
+ lw \tmp, THREAD_FCR31(\thread)
+ ldc1 $f0, THREAD_FPR0(\thread)
+ ldc1 $f2, THREAD_FPR2(\thread)
+ ldc1 $f4, THREAD_FPR4(\thread)
+ ldc1 $f6, THREAD_FPR6(\thread)
+ ldc1 $f8, THREAD_FPR8(\thread)
+ ldc1 $f10, THREAD_FPR10(\thread)
+ ldc1 $f12, THREAD_FPR12(\thread)
+ ldc1 $f14, THREAD_FPR14(\thread)
+ ldc1 $f16, THREAD_FPR16(\thread)
+ ldc1 $f18, THREAD_FPR18(\thread)
+ ldc1 $f20, THREAD_FPR20(\thread)
+ ldc1 $f22, THREAD_FPR22(\thread)
+ ldc1 $f24, THREAD_FPR24(\thread)
+ ldc1 $f26, THREAD_FPR26(\thread)
+ ldc1 $f28, THREAD_FPR28(\thread)
+ ldc1 $f30, THREAD_FPR30(\thread)
+ ctc1 \tmp, fcr31
+ .endm
+
+ .macro fpu_restore_16odd thread
+ ldc1 $f1, THREAD_FPR1(\thread)
+ ldc1 $f3, THREAD_FPR3(\thread)
+ ldc1 $f5, THREAD_FPR5(\thread)
+ ldc1 $f7, THREAD_FPR7(\thread)
+ ldc1 $f9, THREAD_FPR9(\thread)
+ ldc1 $f11, THREAD_FPR11(\thread)
+ ldc1 $f13, THREAD_FPR13(\thread)
+ ldc1 $f15, THREAD_FPR15(\thread)
+ ldc1 $f17, THREAD_FPR17(\thread)
+ ldc1 $f19, THREAD_FPR19(\thread)
+ ldc1 $f21, THREAD_FPR21(\thread)
+ ldc1 $f23, THREAD_FPR23(\thread)
+ ldc1 $f25, THREAD_FPR25(\thread)
+ ldc1 $f27, THREAD_FPR27(\thread)
+ ldc1 $f29, THREAD_FPR29(\thread)
+ ldc1 $f31, THREAD_FPR31(\thread)
+ .endm
+
+ .macro fpu_restore_double thread status tmp
+ sll \tmp, \status, 5
+ bgez \tmp, 1f # 16 register mode?
+
+ fpu_restore_16odd \thread
+1: fpu_restore_16even \thread \tmp
+ .endm
+
+ .macro cpu_save_nonscratch thread
+ LONG_S s0, THREAD_REG16(\thread)
+ LONG_S s1, THREAD_REG17(\thread)
+ LONG_S s2, THREAD_REG18(\thread)
+ LONG_S s3, THREAD_REG19(\thread)
+ LONG_S s4, THREAD_REG20(\thread)
+ LONG_S s5, THREAD_REG21(\thread)
+ LONG_S s6, THREAD_REG22(\thread)
+ LONG_S s7, THREAD_REG23(\thread)
+ LONG_S sp, THREAD_REG29(\thread)
+ LONG_S fp, THREAD_REG30(\thread)
+ .endm
+
+ .macro cpu_restore_nonscratch thread
+ LONG_L s0, THREAD_REG16(\thread)
+ LONG_L s1, THREAD_REG17(\thread)
+ LONG_L s2, THREAD_REG18(\thread)
+ LONG_L s3, THREAD_REG19(\thread)
+ LONG_L s4, THREAD_REG20(\thread)
+ LONG_L s5, THREAD_REG21(\thread)
+ LONG_L s6, THREAD_REG22(\thread)
+ LONG_L s7, THREAD_REG23(\thread)
+ LONG_L sp, THREAD_REG29(\thread)
+ LONG_L fp, THREAD_REG30(\thread)
+ LONG_L ra, THREAD_REG31(\thread)
+ .endm
+
+#endif /* _ASM_ASMMACRO_64_H */
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
new file mode 100644
index 00000000..6c8342ae
--- /dev/null
+++ b/arch/mips/include/asm/asmmacro.h
@@ -0,0 +1,92 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Ralf Baechle
+ */
+#ifndef _ASM_ASMMACRO_H
+#define _ASM_ASMMACRO_H
+
+#include <asm/hazards.h>
+
+#ifdef CONFIG_32BIT
+#include <asm/asmmacro-32.h>
+#endif
+#ifdef CONFIG_64BIT
+#include <asm/asmmacro-64.h>
+#endif
+#ifdef CONFIG_MIPS_MT_SMTC
+#include <asm/mipsmtregs.h>
+#endif
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ .macro local_irq_enable reg=t0
+ mfc0 \reg, CP0_TCSTATUS
+ ori \reg, \reg, TCSTATUS_IXMT
+ xori \reg, \reg, TCSTATUS_IXMT
+ mtc0 \reg, CP0_TCSTATUS
+ _ehb
+ .endm
+
+ .macro local_irq_disable reg=t0
+ mfc0 \reg, CP0_TCSTATUS
+ ori \reg, \reg, TCSTATUS_IXMT
+ mtc0 \reg, CP0_TCSTATUS
+ _ehb
+ .endm
+#elif defined(CONFIG_CPU_MIPSR2)
+ .macro local_irq_enable reg=t0
+ ei
+ irq_enable_hazard
+ .endm
+
+ .macro local_irq_disable reg=t0
+ di
+ irq_disable_hazard
+ .endm
+#else
+ .macro local_irq_enable reg=t0
+ mfc0 \reg, CP0_STATUS
+ ori \reg, \reg, 1
+ mtc0 \reg, CP0_STATUS
+ irq_enable_hazard
+ .endm
+
+ .macro local_irq_disable reg=t0
+ mfc0 \reg, CP0_STATUS
+ ori \reg, \reg, 1
+ xori \reg, \reg, 1
+ mtc0 \reg, CP0_STATUS
+ irq_disable_hazard
+ .endm
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+/*
+ * Temporary until all gas have MT ASE support
+ */
+ .macro DMT reg=0
+ .word 0x41600bc1 | (\reg << 16)
+ .endm
+
+ .macro EMT reg=0
+ .word 0x41600be1 | (\reg << 16)
+ .endm
+
+ .macro DVPE reg=0
+ .word 0x41600001 | (\reg << 16)
+ .endm
+
+ .macro EVPE reg=0
+ .word 0x41600021 | (\reg << 16)
+ .endm
+
+ .macro MFTR rt=0, rd=0, u=0, sel=0
+ .word 0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
+ .endm
+
+ .macro MTTR rt=0, rd=0, u=0, sel=0
+ .word 0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
+ .endm
+
+#endif /* _ASM_ASMMACRO_H */
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
new file mode 100644
index 00000000..4a02fe89
--- /dev/null
+++ b/arch/mips/include/asm/atomic.h
@@ -0,0 +1,786 @@
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ *
+ * But use these as seldom as possible since they are much more slower
+ * than regular operations.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 97, 99, 2000, 03, 04, 06 by Ralf Baechle
+ */
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <linux/irqflags.h>
+#include <linux/types.h>
+#include <asm/barrier.h>
+#include <asm/cpu-features.h>
+#include <asm/war.h>
+#include <asm/system.h>
+
+#define ATOMIC_INIT(i) { (i) }
+
+/*
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.
+ */
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
+
+/*
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ */
+#define atomic_set(v, i) ((v)->counter = (i))
+
+/*
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v.
+ */
+static __inline__ void atomic_add(int i, atomic_t * v)
+{
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ int temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: ll %0, %1 # atomic_add \n"
+ " addu %0, %2 \n"
+ " sc %0, %1 \n"
+ " beqzl %0, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } else if (kernel_uses_llsc) {
+ int temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %0, %1 # atomic_add \n"
+ " addu %0, %2 \n"
+ " sc %0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } while (unlikely(!temp));
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ v->counter += i;
+ raw_local_irq_restore(flags);
+ }
+}
+
+/*
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+static __inline__ void atomic_sub(int i, atomic_t * v)
+{
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ int temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: ll %0, %1 # atomic_sub \n"
+ " subu %0, %2 \n"
+ " sc %0, %1 \n"
+ " beqzl %0, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } else if (kernel_uses_llsc) {
+ int temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %0, %1 # atomic_sub \n"
+ " subu %0, %2 \n"
+ " sc %0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } while (unlikely(!temp));
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ v->counter -= i;
+ raw_local_irq_restore(flags);
+ }
+}
+
+/*
+ * Same as above, but return the result value
+ */
+static __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+ int result;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ int temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: ll %1, %2 # atomic_add_return \n"
+ " addu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " beqzl %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ int temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %1, %2 # atomic_add_return \n"
+ " addu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } while (unlikely(!result));
+
+ result = temp + i;
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ result = v->counter;
+ result += i;
+ v->counter = result;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return result;
+}
+
+static __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+ int result;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ int temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: ll %1, %2 # atomic_sub_return \n"
+ " subu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " beqzl %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+
+ result = temp - i;
+ } else if (kernel_uses_llsc) {
+ int temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %1, %2 # atomic_sub_return \n"
+ " subu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } while (unlikely(!result));
+
+ result = temp - i;
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ result = v->counter;
+ result -= i;
+ v->counter = result;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return result;
+}
+
+/*
+ * atomic_sub_if_positive - conditionally subtract integer from atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically test @v and subtract @i if @v is greater or equal than @i.
+ * The function returns the old value of @v minus @i.
+ */
+static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
+{
+ int result;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ int temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: ll %1, %2 # atomic_sub_if_positive\n"
+ " subu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+ " sc %0, %2 \n"
+ " .set noreorder \n"
+ " beqzl %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set reorder \n"
+ "1: \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ int temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: ll %1, %2 # atomic_sub_if_positive\n"
+ " subu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+ " sc %0, %2 \n"
+ " .set noreorder \n"
+ " beqz %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set reorder \n"
+ "1: \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ result = v->counter;
+ result -= i;
+ if (result >= 0)
+ v->counter = result;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return result;
+}
+
+#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+#define atomic_dec_return(v) atomic_sub_return(1, (v))
+#define atomic_inc_return(v) atomic_add_return(1, (v))
+
+/*
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
+
+/*
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+
+/*
+ * atomic_dec_and_test - decrement by 1 and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+/*
+ * atomic_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic_t
+ */
+#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v)
+
+/*
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic_inc(v) atomic_add(1, (v))
+
+/*
+ * atomic_dec - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic_dec(v) atomic_sub(1, (v))
+
+/*
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define atomic_add_negative(i, v) (atomic_add_return(i, (v)) < 0)
+
+#ifdef CONFIG_64BIT
+
+#define ATOMIC64_INIT(i) { (i) }
+
+/*
+ * atomic64_read - read atomic variable
+ * @v: pointer of type atomic64_t
+ *
+ */
+#define atomic64_read(v) (*(volatile long *)&(v)->counter)
+
+/*
+ * atomic64_set - set atomic variable
+ * @v: pointer of type atomic64_t
+ * @i: required value
+ */
+#define atomic64_set(v, i) ((v)->counter = (i))
+
+/*
+ * atomic64_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically adds @i to @v.
+ */
+static __inline__ void atomic64_add(long i, atomic64_t * v)
+{
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: lld %0, %1 # atomic64_add \n"
+ " daddu %0, %2 \n"
+ " scd %0, %1 \n"
+ " beqzl %0, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } else if (kernel_uses_llsc) {
+ long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %0, %1 # atomic64_add \n"
+ " daddu %0, %2 \n"
+ " scd %0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } while (unlikely(!temp));
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ v->counter += i;
+ raw_local_irq_restore(flags);
+ }
+}
+
+/*
+ * atomic64_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+static __inline__ void atomic64_sub(long i, atomic64_t * v)
+{
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: lld %0, %1 # atomic64_sub \n"
+ " dsubu %0, %2 \n"
+ " scd %0, %1 \n"
+ " beqzl %0, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } else if (kernel_uses_llsc) {
+ long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %0, %1 # atomic64_sub \n"
+ " dsubu %0, %2 \n"
+ " scd %0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+ } while (unlikely(!temp));
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ v->counter -= i;
+ raw_local_irq_restore(flags);
+ }
+}
+
+/*
+ * Same as above, but return the result value
+ */
+static __inline__ long atomic64_add_return(long i, atomic64_t * v)
+{
+ long result;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: lld %1, %2 # atomic64_add_return \n"
+ " daddu %0, %1, %3 \n"
+ " scd %0, %2 \n"
+ " beqzl %0, 1b \n"
+ " daddu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %1, %2 # atomic64_add_return \n"
+ " daddu %0, %1, %3 \n"
+ " scd %0, %2 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } while (unlikely(!result));
+
+ result = temp + i;
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ result = v->counter;
+ result += i;
+ v->counter = result;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return result;
+}
+
+static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
+{
+ long result;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: lld %1, %2 # atomic64_sub_return \n"
+ " dsubu %0, %1, %3 \n"
+ " scd %0, %2 \n"
+ " beqzl %0, 1b \n"
+ " dsubu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %1, %2 # atomic64_sub_return \n"
+ " dsubu %0, %1, %3 \n"
+ " scd %0, %2 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } while (unlikely(!result));
+
+ result = temp - i;
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ result = v->counter;
+ result -= i;
+ v->counter = result;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return result;
+}
+
+/*
+ * atomic64_sub_if_positive - conditionally subtract integer from atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically test @v and subtract @i if @v is greater or equal than @i.
+ * The function returns the old value of @v minus @i.
+ */
+static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
+{
+ long result;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: lld %1, %2 # atomic64_sub_if_positive\n"
+ " dsubu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+ " scd %0, %2 \n"
+ " .set noreorder \n"
+ " beqzl %0, 1b \n"
+ " dsubu %0, %1, %3 \n"
+ " .set reorder \n"
+ "1: \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: lld %1, %2 # atomic64_sub_if_positive\n"
+ " dsubu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+ " scd %0, %2 \n"
+ " .set noreorder \n"
+ " beqz %0, 1b \n"
+ " dsubu %0, %1, %3 \n"
+ " .set reorder \n"
+ "1: \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ result = v->counter;
+ result -= i;
+ if (result >= 0)
+ v->counter = result;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return result;
+}
+
+#define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+ long c, old;
+ c = atomic64_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic64_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
+#define atomic64_dec_return(v) atomic64_sub_return(1, (v))
+#define atomic64_inc_return(v) atomic64_add_return(1, (v))
+
+/*
+ * atomic64_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic64_sub_and_test(i, v) (atomic64_sub_return((i), (v)) == 0)
+
+/*
+ * atomic64_inc_and_test - increment and test
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+
+/*
+ * atomic64_dec_and_test - decrement by 1 and test
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+#define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0)
+
+/*
+ * atomic64_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic64_t
+ */
+#define atomic64_dec_if_positive(v) atomic64_sub_if_positive(1, v)
+
+/*
+ * atomic64_inc - increment atomic variable
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic64_inc(v) atomic64_add(1, (v))
+
+/*
+ * atomic64_dec - decrement and test
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic64_dec(v) atomic64_sub(1, (v))
+
+/*
+ * atomic64_add_negative - add and test if negative
+ * @v: pointer of type atomic64_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0)
+
+#else /* !CONFIG_64BIT */
+
+#include <asm-generic/atomic64.h>
+
+#endif /* CONFIG_64BIT */
+
+/*
+ * atomic*_return operations are serializing but not the non-*_return
+ * versions.
+ */
+#define smp_mb__before_atomic_dec() smp_mb__before_llsc()
+#define smp_mb__after_atomic_dec() smp_llsc_mb()
+#define smp_mb__before_atomic_inc() smp_mb__before_llsc()
+#define smp_mb__after_atomic_inc() smp_llsc_mb()
+
+#include <asm-generic/atomic-long.h>
+
+#endif /* _ASM_ATOMIC_H */
diff --git a/arch/mips/include/asm/auxvec.h b/arch/mips/include/asm/auxvec.h
new file mode 100644
index 00000000..7cf7f2d2
--- /dev/null
+++ b/arch/mips/include/asm/auxvec.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_AUXVEC_H
+#define _ASM_AUXVEC_H
+
+#endif /* _ASM_AUXVEC_H */
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
new file mode 100644
index 00000000..c0884f02
--- /dev/null
+++ b/arch/mips/include/asm/barrier.h
@@ -0,0 +1,181 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_BARRIER_H
+#define __ASM_BARRIER_H
+
+/*
+ * read_barrier_depends - Flush all pending reads that subsequents reads
+ * depend on.
+ *
+ * No data-dependent reads from memory-like regions are ever reordered
+ * over this barrier. All reads preceding this primitive are guaranteed
+ * to access memory (but not necessarily other CPUs' caches) before any
+ * reads following this primitive that depend on the data return by
+ * any of the preceding reads. This primitive is much lighter weight than
+ * rmb() on most CPUs, and is never heavier weight than is
+ * rmb().
+ *
+ * These ordering constraints are respected by both the local CPU
+ * and the compiler.
+ *
+ * Ordering is not guaranteed by anything other than these primitives,
+ * not even by data dependencies. See the documentation for
+ * memory_barrier() for examples and URLs to more information.
+ *
+ * For example, the following code would force ordering (the initial
+ * value of "a" is zero, "b" is one, and "p" is "&a"):
+ *
+ * <programlisting>
+ * CPU 0 CPU 1
+ *
+ * b = 2;
+ * memory_barrier();
+ * p = &b; q = p;
+ * read_barrier_depends();
+ * d = *q;
+ * </programlisting>
+ *
+ * because the read of "*q" depends on the read of "p" and these
+ * two reads are separated by a read_barrier_depends(). However,
+ * the following code, with the same initial values for "a" and "b":
+ *
+ * <programlisting>
+ * CPU 0 CPU 1
+ *
+ * a = 2;
+ * memory_barrier();
+ * b = 3; y = b;
+ * read_barrier_depends();
+ * x = a;
+ * </programlisting>
+ *
+ * does not enforce ordering, since there is no data dependency between
+ * the read of "a" and the read of "b". Therefore, on some CPUs, such
+ * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
+ * in cases like this where there are no data dependencies.
+ */
+
+#define read_barrier_depends() do { } while(0)
+#define smp_read_barrier_depends() do { } while(0)
+
+#ifdef CONFIG_CPU_HAS_SYNC
+#define __sync() \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ ".set mips2\n\t" \
+ "sync\n\t" \
+ ".set pop" \
+ : /* no output */ \
+ : /* no input */ \
+ : "memory")
+#else
+#define __sync() do { } while(0)
+#endif
+
+#define __fast_iob() \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ "lw $0,%0\n\t" \
+ "nop\n\t" \
+ ".set pop" \
+ : /* no output */ \
+ : "m" (*(int *)CKSEG1) \
+ : "memory")
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+# define OCTEON_SYNCW_STR ".set push\n.set arch=octeon\nsyncw\nsyncw\n.set pop\n"
+# define __syncw() __asm__ __volatile__(OCTEON_SYNCW_STR : : : "memory")
+
+# define fast_wmb() __syncw()
+# define fast_rmb() barrier()
+# define fast_mb() __sync()
+# define fast_iob() do { } while (0)
+#else /* ! CONFIG_CPU_CAVIUM_OCTEON */
+# define fast_wmb() __sync()
+# define fast_rmb() __sync()
+# define fast_mb() __sync()
+# ifdef CONFIG_SGI_IP28
+# define fast_iob() \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ "lw $0,%0\n\t" \
+ "sync\n\t" \
+ "lw $0,%0\n\t" \
+ ".set pop" \
+ : /* no output */ \
+ : "m" (*(int *)CKSEG1ADDR(0x1fa00004)) \
+ : "memory")
+# else
+# define fast_iob() \
+ do { \
+ __sync(); \
+ __fast_iob(); \
+ } while (0)
+# endif
+#endif /* CONFIG_CPU_CAVIUM_OCTEON */
+
+#ifdef CONFIG_CPU_HAS_WB
+
+#include <asm/wbflush.h>
+
+#define wmb() fast_wmb()
+#define rmb() fast_rmb()
+#define mb() wbflush()
+#define iob() wbflush()
+
+#else /* !CONFIG_CPU_HAS_WB */
+
+#define wmb() fast_wmb()
+#define rmb() fast_rmb()
+#define mb() fast_mb()
+#define iob() fast_iob()
+
+#endif /* !CONFIG_CPU_HAS_WB */
+
+#if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP)
+# ifdef CONFIG_CPU_CAVIUM_OCTEON
+# define smp_mb() __sync()
+# define smp_rmb() barrier()
+# define smp_wmb() __syncw()
+# else
+# define smp_mb() __asm__ __volatile__("sync" : : :"memory")
+# define smp_rmb() __asm__ __volatile__("sync" : : :"memory")
+# define smp_wmb() __asm__ __volatile__("sync" : : :"memory")
+# endif
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#endif
+
+#if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP)
+#define __WEAK_LLSC_MB " sync \n"
+#else
+#define __WEAK_LLSC_MB " \n"
+#endif
+
+#define set_mb(var, value) \
+ do { var = value; smp_mb(); } while (0)
+
+#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define smp_mb__before_llsc() smp_wmb()
+/* Cause previous writes to become visible on all CPUs as soon as possible */
+#define nudge_writes() __asm__ __volatile__(".set push\n\t" \
+ ".set arch=octeon\n\t" \
+ "syncw\n\t" \
+ ".set pop" : : : "memory")
+#else
+#define smp_mb__before_llsc() smp_llsc_mb()
+#define nudge_writes() mb()
+#endif
+
+#endif /* __ASM_BARRIER_H */
diff --git a/arch/mips/include/asm/bcache.h b/arch/mips/include/asm/bcache.h
new file mode 100644
index 00000000..0ba9d6ef
--- /dev/null
+++ b/arch/mips/include/asm/bcache.h
@@ -0,0 +1,60 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1997, 1999 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_BCACHE_H
+#define _ASM_BCACHE_H
+
+
+/* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent,
+ chipset implemented caches. On machines with other CPUs the CPU does the
+ cache thing itself. */
+struct bcache_ops {
+ void (*bc_enable)(void);
+ void (*bc_disable)(void);
+ void (*bc_wback_inv)(unsigned long page, unsigned long size);
+ void (*bc_inv)(unsigned long page, unsigned long size);
+};
+
+extern void indy_sc_init(void);
+
+#ifdef CONFIG_BOARD_SCACHE
+
+extern struct bcache_ops *bcops;
+
+static inline void bc_enable(void)
+{
+ bcops->bc_enable();
+}
+
+static inline void bc_disable(void)
+{
+ bcops->bc_disable();
+}
+
+static inline void bc_wback_inv(unsigned long page, unsigned long size)
+{
+ bcops->bc_wback_inv(page, size);
+}
+
+static inline void bc_inv(unsigned long page, unsigned long size)
+{
+ bcops->bc_inv(page, size);
+}
+
+#else /* !defined(CONFIG_BOARD_SCACHE) */
+
+/* Not R4000 / R4400 / R4600 / R5000. */
+
+#define bc_enable() do { } while (0)
+#define bc_disable() do { } while (0)
+#define bc_wback_inv(page, size) do { } while (0)
+#define bc_inv(page, size) do { } while (0)
+
+#endif /* !defined(CONFIG_BOARD_SCACHE) */
+
+#endif /* _ASM_BCACHE_H */
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
new file mode 100644
index 00000000..2e1ad4c6
--- /dev/null
+++ b/arch/mips/include/asm/bitops.h
@@ -0,0 +1,684 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1994 - 1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_BITOPS_H
+#define _ASM_BITOPS_H
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <linux/compiler.h>
+#include <linux/irqflags.h>
+#include <linux/types.h>
+#include <asm/barrier.h>
+#include <asm/bug.h>
+#include <asm/byteorder.h> /* sigh ... */
+#include <asm/cpu-features.h>
+#include <asm/sgidefs.h>
+#include <asm/war.h>
+
+#if _MIPS_SZLONG == 32
+#define SZLONG_LOG 5
+#define SZLONG_MASK 31UL
+#define __LL "ll "
+#define __SC "sc "
+#define __INS "ins "
+#define __EXT "ext "
+#elif _MIPS_SZLONG == 64
+#define SZLONG_LOG 6
+#define SZLONG_MASK 63UL
+#define __LL "lld "
+#define __SC "scd "
+#define __INS "dins "
+#define __EXT "dext "
+#endif
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit() smp_mb__before_llsc()
+#define smp_mb__after_clear_bit() smp_llsc_mb()
+
+/*
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This function is atomic and may not be reordered. See __set_bit()
+ * if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned short bit = nr & SZLONG_MASK;
+ unsigned long temp;
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # set_bit \n"
+ " or %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " beqzl %0, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (*m)
+ : "ir" (1UL << bit), "m" (*m));
+#ifdef CONFIG_CPU_MIPSR2
+ } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
+ do {
+ __asm__ __volatile__(
+ " " __LL "%0, %1 # set_bit \n"
+ " " __INS "%0, %3, %2, 1 \n"
+ " " __SC "%0, %1 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (bit), "r" (~0));
+ } while (unlikely(!temp));
+#endif /* CONFIG_CPU_MIPSR2 */
+ } else if (kernel_uses_llsc) {
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # set_bit \n"
+ " or %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (1UL << bit));
+ } while (unlikely(!temp));
+ } else {
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+ }
+}
+
+/*
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and may not be reordered. However, it does
+ * not contain a memory barrier, so if it is used for locking purposes,
+ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
+ * in order to ensure changes are visible on other processors.
+ */
+static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned short bit = nr & SZLONG_MASK;
+ unsigned long temp;
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # clear_bit \n"
+ " and %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " beqzl %0, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (~(1UL << bit)));
+#ifdef CONFIG_CPU_MIPSR2
+ } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
+ do {
+ __asm__ __volatile__(
+ " " __LL "%0, %1 # clear_bit \n"
+ " " __INS "%0, $0, %2, 1 \n"
+ " " __SC "%0, %1 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (bit));
+ } while (unlikely(!temp));
+#endif /* CONFIG_CPU_MIPSR2 */
+ } else if (kernel_uses_llsc) {
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # clear_bit \n"
+ " and %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (~(1UL << bit)));
+ } while (unlikely(!temp));
+ } else {
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a &= ~mask;
+ raw_local_irq_restore(flags);
+ }
+}
+
+/*
+ * clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and implies release semantics before the memory
+ * operation. It can be used for an unlock.
+ */
+static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+ smp_mb__before_clear_bit();
+ clear_bit(nr, addr);
+}
+
+/*
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ *
+ * change_bit() is atomic and may not be reordered.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
+{
+ unsigned short bit = nr & SZLONG_MASK;
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # change_bit \n"
+ " xor %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " beqzl %0, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (1UL << bit));
+ } else if (kernel_uses_llsc) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # change_bit \n"
+ " xor %0, %2 \n"
+ " " __SC "%0, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m)
+ : "ir" (1UL << bit));
+ } while (unlikely(!temp));
+ } else {
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ *a ^= mask;
+ raw_local_irq_restore(flags);
+ }
+}
+
+/*
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static inline int test_and_set_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned short bit = nr & SZLONG_MASK;
+ unsigned long res;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_set_bit \n"
+ " or %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " beqzl %2, 1b \n"
+ " and %2, %0, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # test_and_set_bit \n"
+ " or %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } while (unlikely(!res));
+
+ res = temp & (1UL << bit);
+ } else {
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return res != 0;
+}
+
+/*
+ * test_and_set_bit_lock - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and implies acquire ordering semantics
+ * after the memory operation.
+ */
+static inline int test_and_set_bit_lock(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned short bit = nr & SZLONG_MASK;
+ unsigned long res;
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_set_bit \n"
+ " or %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " beqzl %2, 1b \n"
+ " and %2, %0, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # test_and_set_bit \n"
+ " or %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } while (unlikely(!res));
+
+ res = temp & (1UL << bit);
+ } else {
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a |= mask;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return res != 0;
+}
+/*
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static inline int test_and_clear_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned short bit = nr & SZLONG_MASK;
+ unsigned long res;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_clear_bit \n"
+ " or %2, %0, %3 \n"
+ " xor %2, %3 \n"
+ " " __SC "%2, %1 \n"
+ " beqzl %2, 1b \n"
+ " and %2, %0, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+#ifdef CONFIG_CPU_MIPSR2
+ } else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ do {
+ __asm__ __volatile__(
+ " " __LL "%0, %1 # test_and_clear_bit \n"
+ " " __EXT "%2, %0, %3, 1 \n"
+ " " __INS "%0, $0, %3, 1 \n"
+ " " __SC "%0, %1 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "ir" (bit)
+ : "memory");
+ } while (unlikely(!temp));
+#endif
+ } else if (kernel_uses_llsc) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # test_and_clear_bit \n"
+ " or %2, %0, %3 \n"
+ " xor %2, %3 \n"
+ " " __SC "%2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } while (unlikely(!res));
+
+ res = temp & (1UL << bit);
+ } else {
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a &= ~mask;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return res != 0;
+}
+
+/*
+ * test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static inline int test_and_change_bit(unsigned long nr,
+ volatile unsigned long *addr)
+{
+ unsigned short bit = nr & SZLONG_MASK;
+ unsigned long res;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: " __LL "%0, %1 # test_and_change_bit \n"
+ " xor %2, %0, %3 \n"
+ " " __SC "%2, %1 \n"
+ " beqzl %2, 1b \n"
+ " and %2, %0, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " " __LL "%0, %1 # test_and_change_bit \n"
+ " xor %2, %0, %3 \n"
+ " " __SC "\t%2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "+m" (*m), "=&r" (res)
+ : "r" (1UL << bit)
+ : "memory");
+ } while (unlikely(!res));
+
+ res = temp & (1UL << bit);
+ } else {
+ volatile unsigned long *a = addr;
+ unsigned long mask;
+ unsigned long flags;
+
+ a += nr >> SZLONG_LOG;
+ mask = 1UL << bit;
+ raw_local_irq_save(flags);
+ res = (mask & *a);
+ *a ^= mask;
+ raw_local_irq_restore(flags);
+ }
+
+ smp_llsc_mb();
+
+ return res != 0;
+}
+
+#include <asm-generic/bitops/non-atomic.h>
+
+/*
+ * __clear_bit_unlock - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * __clear_bit() is non-atomic and implies release semantics before the memory
+ * operation. It can be used for an unlock if no other CPUs can concurrently
+ * modify other bits in the word.
+ */
+static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
+{
+ smp_mb();
+ __clear_bit(nr, addr);
+}
+
+/*
+ * Return the bit position (0..63) of the most significant 1 bit in a word
+ * Returns -1 if no 1 bit exists
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+ int num;
+
+ if (BITS_PER_LONG == 32 &&
+ __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
+ __asm__(
+ " .set push \n"
+ " .set mips32 \n"
+ " clz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (num)
+ : "r" (word));
+
+ return 31 - num;
+ }
+
+ if (BITS_PER_LONG == 64 &&
+ __builtin_constant_p(cpu_has_mips64) && cpu_has_mips64) {
+ __asm__(
+ " .set push \n"
+ " .set mips64 \n"
+ " dclz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (num)
+ : "r" (word));
+
+ return 63 - num;
+ }
+
+ num = BITS_PER_LONG - 1;
+
+#if BITS_PER_LONG == 64
+ if (!(word & (~0ul << 32))) {
+ num -= 32;
+ word <<= 32;
+ }
+#endif
+ if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
+ num -= 16;
+ word <<= 16;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
+ num -= 8;
+ word <<= 8;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
+ num -= 4;
+ word <<= 4;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
+ num -= 2;
+ word <<= 2;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-1))))
+ num -= 1;
+ return num;
+}
+
+/*
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Returns 0..SZLONG-1
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+ return __fls(word & -word);
+}
+
+/*
+ * fls - find last bit set.
+ * @word: The word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+static inline int fls(int x)
+{
+ int r;
+
+ if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
+ __asm__("clz %0, %1" : "=r" (x) : "r" (x));
+
+ return 32 - x;
+ }
+
+ r = 32;
+ if (!x)
+ return 0;
+ if (!(x & 0xffff0000u)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xff000000u)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xf0000000u)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xc0000000u)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x80000000u)) {
+ x <<= 1;
+ r -= 1;
+ }
+ return r;
+}
+
+#include <asm-generic/bitops/fls64.h>
+
+/*
+ * ffs - find first bit set.
+ * @word: The word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static inline int ffs(int word)
+{
+ if (!word)
+ return 0;
+
+ return fls(word & -word);
+}
+
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/find.h>
+
+#ifdef __KERNEL__
+
+#include <asm-generic/bitops/sched.h>
+
+#include <asm/arch_hweight.h>
+#include <asm-generic/bitops/const_hweight.h>
+
+#include <asm-generic/bitops/le.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_BITOPS_H */
diff --git a/arch/mips/include/asm/bitsperlong.h b/arch/mips/include/asm/bitsperlong.h
new file mode 100644
index 00000000..3e4c10a8
--- /dev/null
+++ b/arch/mips/include/asm/bitsperlong.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_MIPS_BITSPERLONG_H
+#define __ASM_MIPS_BITSPERLONG_H
+
+#define __BITS_PER_LONG _MIPS_SZLONG
+
+#include <asm-generic/bitsperlong.h>
+
+#endif /* __ASM_MIPS_BITSPERLONG_H */
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
new file mode 100644
index 00000000..35cd1bab
--- /dev/null
+++ b/arch/mips/include/asm/bootinfo.h
@@ -0,0 +1,140 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 2003 by Ralf Baechle
+ * Copyright (C) 1995, 1996 Andreas Busse
+ * Copyright (C) 1995, 1996 Stoned Elipot
+ * Copyright (C) 1995, 1996 Paul M. Antoine.
+ * Copyright (C) 2009 Zhang Le
+ */
+#ifndef _ASM_BOOTINFO_H
+#define _ASM_BOOTINFO_H
+
+#include <linux/types.h>
+#include <asm/setup.h>
+
+/*
+ * The MACH_ IDs are sort of equivalent to PCI product IDs. As such the
+ * numbers do not necessarily reflect technical relations or similarities
+ * between systems.
+ */
+
+/*
+ * Valid machtype values for group unknown
+ */
+#define MACH_UNKNOWN 0 /* whatever... */
+
+/*
+ * Valid machtype for group DEC
+ */
+#define MACH_DSUNKNOWN 0
+#define MACH_DS23100 1 /* DECstation 2100 or 3100 */
+#define MACH_DS5100 2 /* DECsystem 5100 */
+#define MACH_DS5000_200 3 /* DECstation 5000/200 */
+#define MACH_DS5000_1XX 4 /* DECstation 5000/120, 125, 133, 150 */
+#define MACH_DS5000_XX 5 /* DECstation 5000/20, 25, 33, 50 */
+#define MACH_DS5000_2X0 6 /* DECstation 5000/240, 260 */
+#define MACH_DS5400 7 /* DECsystem 5400 */
+#define MACH_DS5500 8 /* DECsystem 5500 */
+#define MACH_DS5800 9 /* DECsystem 5800 */
+#define MACH_DS5900 10 /* DECsystem 5900 */
+
+/*
+ * Valid machtype for group PMC-MSP
+ */
+#define MACH_MSP4200_EVAL 0 /* PMC-Sierra MSP4200 Evaluation */
+#define MACH_MSP4200_GW 1 /* PMC-Sierra MSP4200 Gateway demo */
+#define MACH_MSP4200_FPGA 2 /* PMC-Sierra MSP4200 Emulation */
+#define MACH_MSP7120_EVAL 3 /* PMC-Sierra MSP7120 Evaluation */
+#define MACH_MSP7120_GW 4 /* PMC-Sierra MSP7120 Residential GW */
+#define MACH_MSP7120_FPGA 5 /* PMC-Sierra MSP7120 Emulation */
+#define MACH_MSP_OTHER 255 /* PMC-Sierra unknown board type */
+
+/*
+ * Valid machtype for group Mikrotik
+ */
+#define MACH_MIKROTIK_RB532 0 /* Mikrotik RouterBoard 532 */
+#define MACH_MIKROTIK_RB532A 1 /* Mikrotik RouterBoard 532A */
+
+/*
+ * Valid machtype for Loongson family
+ */
+#define MACH_LOONGSON_UNKNOWN 0
+#define MACH_LEMOTE_FL2E 1
+#define MACH_LEMOTE_FL2F 2
+#define MACH_LEMOTE_ML2F7 3
+#define MACH_LEMOTE_YL2F89 4
+#define MACH_DEXXON_GDIUM2F10 5
+#define MACH_LEMOTE_NAS 6
+#define MACH_LEMOTE_LL2F 7
+#define MACH_LOONGSON_END 8
+
+/*
+ * Valid machtype for group INGENIC
+ */
+#define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */
+#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */
+
+extern char *system_type;
+const char *get_system_type(void);
+
+extern unsigned long mips_machtype;
+
+#define BOOT_MEM_MAP_MAX 32
+#define BOOT_MEM_RAM 1
+#define BOOT_MEM_ROM_DATA 2
+#define BOOT_MEM_RESERVED 3
+
+/*
+ * A memory map that's built upon what was determined
+ * or specified on the command line.
+ */
+struct boot_mem_map {
+ int nr_map;
+ struct boot_mem_map_entry {
+ phys_t addr; /* start of memory segment */
+ phys_t size; /* size of memory segment */
+ long type; /* type of memory segment */
+ } map[BOOT_MEM_MAP_MAX];
+};
+
+extern struct boot_mem_map boot_mem_map;
+
+extern void add_memory_region(phys_t start, phys_t size, long type);
+
+extern void prom_init(void);
+extern void prom_free_prom_memory(void);
+
+extern void free_init_pages(const char *what,
+ unsigned long begin, unsigned long end);
+
+/*
+ * Initial kernel command line, usually setup by prom_init()
+ */
+extern char arcs_cmdline[COMMAND_LINE_SIZE];
+
+/*
+ * Registers a0, a1, a3 and a4 as passed to the kernel entry by firmware
+ */
+extern unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
+
+/*
+ * Platform memory detection hook called by setup_arch
+ */
+extern void plat_mem_setup(void);
+
+#ifdef CONFIG_SWIOTLB
+/*
+ * Optional platform hook to call swiotlb_setup().
+ */
+extern void plat_swiotlb_setup(void);
+
+#else
+
+static inline void plat_swiotlb_setup(void) {}
+
+#endif /* CONFIG_SWIOTLB */
+
+#endif /* _ASM_BOOTINFO_H */
diff --git a/arch/mips/include/asm/branch.h b/arch/mips/include/asm/branch.h
new file mode 100644
index 00000000..37c6857c
--- /dev/null
+++ b/arch/mips/include/asm/branch.h
@@ -0,0 +1,38 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle
+ */
+#ifndef _ASM_BRANCH_H
+#define _ASM_BRANCH_H
+
+#include <asm/ptrace.h>
+
+static inline int delay_slot(struct pt_regs *regs)
+{
+ return regs->cp0_cause & CAUSEF_BD;
+}
+
+static inline unsigned long exception_epc(struct pt_regs *regs)
+{
+ if (!delay_slot(regs))
+ return regs->cp0_epc;
+
+ return regs->cp0_epc + 4;
+}
+
+extern int __compute_return_epc(struct pt_regs *regs);
+
+static inline int compute_return_epc(struct pt_regs *regs)
+{
+ if (!delay_slot(regs)) {
+ regs->cp0_epc += 4;
+ return 0;
+ }
+
+ return __compute_return_epc(regs);
+}
+
+#endif /* _ASM_BRANCH_H */
diff --git a/arch/mips/include/asm/break.h b/arch/mips/include/asm/break.h
new file mode 100644
index 00000000..9161e684
--- /dev/null
+++ b/arch/mips/include/asm/break.h
@@ -0,0 +1,37 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 2003 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef __ASM_BREAK_H
+#define __ASM_BREAK_H
+
+/*
+ * The following break codes are or were in use for specific purposes in
+ * other MIPS operating systems. Linux/MIPS doesn't use all of them. The
+ * unused ones are here as placeholders; we might encounter them in
+ * non-Linux/MIPS object files or make use of them in the future.
+ */
+#define BRK_USERBP 0 /* User bp (used by debuggers) */
+#define BRK_KERNELBP 1 /* Break in the kernel */
+#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */
+#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */
+#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */
+#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */
+#define BRK_OVERFLOW 6 /* Overflow check */
+#define BRK_DIVZERO 7 /* Divide by zero check */
+#define BRK_RANGE 8 /* Range error check */
+#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */
+#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */
+#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */
+#define BRK_BUG 512 /* Used by BUG() */
+#define BRK_KDB 513 /* Used in KDB_ENTER() */
+#define BRK_MEMU 514 /* Used by FPU emulator */
+#define BRK_KPROBE_BP 515 /* Kprobe break */
+#define BRK_KPROBE_SSTEPBP 516 /* Kprobe single step software implementation */
+#define BRK_MULOVF 1023 /* Multiply overflow */
+
+#endif /* __ASM_BREAK_H */
diff --git a/arch/mips/include/asm/bug.h b/arch/mips/include/asm/bug.h
new file mode 100644
index 00000000..540c98a8
--- /dev/null
+++ b/arch/mips/include/asm/bug.h
@@ -0,0 +1,43 @@
+#ifndef __ASM_BUG_H
+#define __ASM_BUG_H
+
+#include <linux/compiler.h>
+#include <asm/sgidefs.h>
+
+#ifdef CONFIG_BUG
+
+#include <asm/break.h>
+
+static inline void __noreturn BUG(void)
+{
+ __asm__ __volatile__("break %0" : : "i" (BRK_BUG));
+ unreachable();
+}
+
+#define HAVE_ARCH_BUG
+
+#if (_MIPS_ISA > _MIPS_ISA_MIPS1)
+
+static inline void __BUG_ON(unsigned long condition)
+{
+ if (__builtin_constant_p(condition)) {
+ if (condition)
+ BUG();
+ else
+ return;
+ }
+ __asm__ __volatile__("tne $0, %0, %1"
+ : : "r" (condition), "i" (BRK_BUG));
+}
+
+#define BUG_ON(C) __BUG_ON((unsigned long)(C))
+
+#define HAVE_ARCH_BUG_ON
+
+#endif /* _MIPS_ISA > _MIPS_ISA_MIPS1 */
+
+#endif
+
+#include <asm-generic/bug.h>
+
+#endif /* __ASM_BUG_H */
diff --git a/arch/mips/include/asm/bugs.h b/arch/mips/include/asm/bugs.h
new file mode 100644
index 00000000..b160a706
--- /dev/null
+++ b/arch/mips/include/asm/bugs.h
@@ -0,0 +1,54 @@
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Copyright (C) 2007 Maciej W. Rozycki
+ *
+ * Needs:
+ * void check_bugs(void);
+ */
+#ifndef _ASM_BUGS_H
+#define _ASM_BUGS_H
+
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+
+#include <asm/cpu.h>
+#include <asm/cpu-info.h>
+
+extern int daddiu_bug;
+
+extern void check_bugs64_early(void);
+
+extern void check_bugs32(void);
+extern void check_bugs64(void);
+
+static inline void check_bugs_early(void)
+{
+#ifdef CONFIG_64BIT
+ check_bugs64_early();
+#endif
+}
+
+static inline void check_bugs(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ cpu_data[cpu].udelay_val = loops_per_jiffy;
+ check_bugs32();
+#ifdef CONFIG_64BIT
+ check_bugs64();
+#endif
+}
+
+static inline int r4k_daddiu_bug(void)
+{
+#ifdef CONFIG_64BIT
+ WARN_ON(daddiu_bug < 0);
+ return daddiu_bug != 0;
+#else
+ return 0;
+#endif
+}
+
+#endif /* _ASM_BUGS_H */
diff --git a/arch/mips/include/asm/byteorder.h b/arch/mips/include/asm/byteorder.h
new file mode 100644
index 00000000..9579051f
--- /dev/null
+++ b/arch/mips/include/asm/byteorder.h
@@ -0,0 +1,19 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 99, 2003 by Ralf Baechle
+ */
+#ifndef _ASM_BYTEORDER_H
+#define _ASM_BYTEORDER_H
+
+#if defined(__MIPSEB__)
+#include <linux/byteorder/big_endian.h>
+#elif defined(__MIPSEL__)
+#include <linux/byteorder/little_endian.h>
+#else
+# error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???"
+#endif
+
+#endif /* _ASM_BYTEORDER_H */
diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
new file mode 100644
index 00000000..b4db69fb
--- /dev/null
+++ b/arch/mips/include/asm/cache.h
@@ -0,0 +1,22 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 98, 99, 2000, 2003 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_CACHE_H
+#define _ASM_CACHE_H
+
+#include <kmalloc.h>
+
+#define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#define SMP_CACHE_SHIFT L1_CACHE_SHIFT
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
+
+#endif /* _ASM_CACHE_H */
diff --git a/arch/mips/include/asm/cachectl.h b/arch/mips/include/asm/cachectl.h
new file mode 100644
index 00000000..f3ce7218
--- /dev/null
+++ b/arch/mips/include/asm/cachectl.h
@@ -0,0 +1,26 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996 by Ralf Baechle
+ */
+#ifndef _ASM_CACHECTL
+#define _ASM_CACHECTL
+
+/*
+ * Options for cacheflush system call
+ */
+#define ICACHE (1<<0) /* flush instruction cache */
+#define DCACHE (1<<1) /* writeback and flush data cache */
+#define BCACHE (ICACHE|DCACHE) /* flush both caches */
+
+/*
+ * Caching modes for the cachectl(2) call
+ *
+ * cachectl(2) is currently not supported and returns ENOSYS.
+ */
+#define CACHEABLE 0 /* make pages cacheable */
+#define UNCACHEABLE 1 /* make pages uncacheable */
+
+#endif /* _ASM_CACHECTL */
diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h
new file mode 100644
index 00000000..40bb9fde
--- /dev/null
+++ b/arch/mips/include/asm/cacheflush.h
@@ -0,0 +1,117 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_CACHEFLUSH_H
+#define _ASM_CACHEFLUSH_H
+
+/* Keep includes the same across arches. */
+#include <linux/mm.h>
+#include <asm/cpu-features.h>
+
+/* Cache flushing:
+ *
+ * - flush_cache_all() flushes entire cache
+ * - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ * - flush_cache_dup mm(mm) handles cache flushing when forking
+ * - flush_cache_page(mm, vmaddr, pfn) flushes a single page
+ * - flush_cache_range(vma, start, end) flushes a range of pages
+ * - flush_icache_range(start, end) flush a range of instructions
+ * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
+ *
+ * MIPS specific flush operations:
+ *
+ * - flush_cache_sigtramp() flush signal trampoline
+ * - flush_icache_all() flush the entire instruction cache
+ * - flush_data_cache_page() flushes a page from the data cache
+ */
+extern void (*flush_cache_all)(void);
+extern void (*__flush_cache_all)(void);
+extern void (*flush_cache_mm)(struct mm_struct *mm);
+#define flush_cache_dup_mm(mm) do { (void) (mm); } while (0)
+extern void (*flush_cache_range)(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end);
+extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
+extern void __flush_dcache_page(struct page *page);
+
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+static inline void flush_dcache_page(struct page *page)
+{
+ if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc)
+ __flush_dcache_page(page);
+
+}
+
+#define flush_dcache_mmap_lock(mapping) do { } while (0)
+#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+
+#define ARCH_HAS_FLUSH_ANON_PAGE
+extern void __flush_anon_page(struct page *, unsigned long);
+static inline void flush_anon_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vmaddr)
+{
+ if (cpu_has_dc_aliases && PageAnon(page))
+ __flush_anon_page(page, vmaddr);
+}
+
+static inline void flush_icache_page(struct vm_area_struct *vma,
+ struct page *page)
+{
+}
+
+extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+extern void (*local_flush_icache_range)(unsigned long start, unsigned long end);
+
+extern void (*__flush_cache_vmap)(void);
+
+static inline void flush_cache_vmap(unsigned long start, unsigned long end)
+{
+ if (cpu_has_dc_aliases)
+ __flush_cache_vmap();
+}
+
+extern void (*__flush_cache_vunmap)(void);
+
+static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
+{
+ if (cpu_has_dc_aliases)
+ __flush_cache_vunmap();
+}
+
+extern void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len);
+
+extern void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len);
+
+extern void (*flush_cache_sigtramp)(unsigned long addr);
+extern void (*flush_icache_all)(void);
+extern void (*local_flush_data_cache_page)(void * addr);
+extern void (*flush_data_cache_page)(unsigned long addr);
+
+/*
+ * This flag is used to indicate that the page pointed to by a pte
+ * is dirty and requires cleaning before returning it to the user.
+ */
+#define PG_dcache_dirty PG_arch_1
+
+#define Page_dcache_dirty(page) \
+ test_bit(PG_dcache_dirty, &(page)->flags)
+#define SetPageDcacheDirty(page) \
+ set_bit(PG_dcache_dirty, &(page)->flags)
+#define ClearPageDcacheDirty(page) \
+ clear_bit(PG_dcache_dirty, &(page)->flags)
+
+/* Run kernel code uncached, useful for cache probing functions. */
+unsigned long run_uncached(void *func);
+
+extern void *kmap_coherent(struct page *page, unsigned long addr);
+extern void kunmap_coherent(void);
+
+#endif /* _ASM_CACHEFLUSH_H */
diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h
new file mode 100644
index 00000000..8f99c11a
--- /dev/null
+++ b/arch/mips/include/asm/cacheops.h
@@ -0,0 +1,87 @@
+/*
+ * Cache operations for the cache instruction.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle
+ * (C) Copyright 1999 Silicon Graphics, Inc.
+ */
+#ifndef __ASM_CACHEOPS_H
+#define __ASM_CACHEOPS_H
+
+/*
+ * Cache Operations available on all MIPS processors with R4000-style caches
+ */
+#define Index_Invalidate_I 0x00
+#define Index_Writeback_Inv_D 0x01
+#define Index_Load_Tag_I 0x04
+#define Index_Load_Tag_D 0x05
+#define Index_Store_Tag_I 0x08
+#define Index_Store_Tag_D 0x09
+#if defined(CONFIG_CPU_LOONGSON2)
+#define Hit_Invalidate_I 0x00
+#else
+#define Hit_Invalidate_I 0x10
+#endif
+#define Hit_Invalidate_D 0x11
+#define Hit_Writeback_Inv_D 0x15
+
+/*
+ * R4000-specific cacheops
+ */
+#define Create_Dirty_Excl_D 0x0d
+#define Fill 0x14
+#define Hit_Writeback_I 0x18
+#define Hit_Writeback_D 0x19
+
+/*
+ * R4000SC and R4400SC-specific cacheops
+ */
+#define Index_Invalidate_SI 0x02
+#define Index_Writeback_Inv_SD 0x03
+#define Index_Load_Tag_SI 0x06
+#define Index_Load_Tag_SD 0x07
+#define Index_Store_Tag_SI 0x0A
+#define Index_Store_Tag_SD 0x0B
+#define Create_Dirty_Excl_SD 0x0f
+#define Hit_Invalidate_SI 0x12
+#define Hit_Invalidate_SD 0x13
+#define Hit_Writeback_Inv_SD 0x17
+#define Hit_Writeback_SD 0x1b
+#define Hit_Set_Virtual_SI 0x1e
+#define Hit_Set_Virtual_SD 0x1f
+
+/*
+ * R5000-specific cacheops
+ */
+#define R5K_Page_Invalidate_S 0x17
+
+/*
+ * RM7000-specific cacheops
+ */
+#define Page_Invalidate_T 0x16
+#define Index_Store_Tag_T 0x0a
+#define Index_Load_Tag_T 0x06
+
+/*
+ * R10000-specific cacheops
+ *
+ * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
+ * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
+ */
+#define Index_Writeback_Inv_S 0x03
+#define Index_Load_Tag_S 0x07
+#define Index_Store_Tag_S 0x0B
+#define Hit_Invalidate_S 0x13
+#define Cache_Barrier 0x14
+#define Hit_Writeback_Inv_S 0x17
+#define Index_Load_Data_I 0x18
+#define Index_Load_Data_D 0x19
+#define Index_Load_Data_S 0x1b
+#define Index_Store_Data_I 0x1c
+#define Index_Store_Data_D 0x1d
+#define Index_Store_Data_S 0x1f
+
+#endif /* __ASM_CACHEOPS_H */
diff --git a/arch/mips/include/asm/cevt-r4k.h b/arch/mips/include/asm/cevt-r4k.h
new file mode 100644
index 00000000..65f9bdd0
--- /dev/null
+++ b/arch/mips/include/asm/cevt-r4k.h
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Kevin D. Kissell
+ */
+
+/*
+ * Definitions used for common event timer implementation
+ * for MIPS 4K-type processors and their MIPS MT variants.
+ * Avoids unsightly extern declarations in C files.
+ */
+#ifndef __ASM_CEVT_R4K_H
+#define __ASM_CEVT_R4K_H
+
+#include <linux/clockchips.h>
+#include <asm/time.h>
+
+DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+
+void mips_event_handler(struct clock_event_device *dev);
+int c0_compare_int_usable(void);
+void mips_set_clock_mode(enum clock_event_mode, struct clock_event_device *);
+irqreturn_t c0_compare_interrupt(int, void *);
+
+extern struct irqaction c0_compare_irqaction;
+extern int cp0_timer_irq_installed;
+
+/*
+ * Possibly handle a performance counter interrupt.
+ * Return true if the timer interrupt should not be checked
+ */
+
+static inline int handle_perf_irq(int r2)
+{
+ /*
+ * The performance counter overflow interrupt may be shared with the
+ * timer interrupt (cp0_perfcount_irq < 0). If it is and a
+ * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
+ * and we can't reliably determine if a counter interrupt has also
+ * happened (!r2) then don't check for a timer interrupt.
+ */
+ return (cp0_perfcount_irq < 0) &&
+ perf_irq() == IRQ_HANDLED &&
+ !r2;
+}
+
+#endif /* __ASM_CEVT_R4K_H */
diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h
new file mode 100644
index 00000000..f2f7c6c2
--- /dev/null
+++ b/arch/mips/include/asm/checksum.h
@@ -0,0 +1,260 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 97, 98, 99, 2001 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2001 Thiemo Seufer.
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+#include <linux/in6.h>
+
+#include <asm/uaccess.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum);
+
+__wsum __csum_partial_copy_user(const void *src, void *dst,
+ int len, __wsum sum, int *err_ptr);
+
+/*
+ * this is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros the rest of the buffer.
+ */
+static inline
+__wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len,
+ __wsum sum, int *err_ptr)
+{
+ might_fault();
+ return __csum_partial_copy_user((__force void *)src, dst,
+ len, sum, err_ptr);
+}
+
+/*
+ * Copy and checksum to user
+ */
+#define HAVE_CSUM_COPY_USER
+static inline
+__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len,
+ __wsum sum, int *err_ptr)
+{
+ might_fault();
+ if (access_ok(VERIFY_WRITE, dst, len))
+ return __csum_partial_copy_user(src, (__force void *)dst,
+ len, sum, err_ptr);
+ if (len)
+ *err_ptr = -EFAULT;
+
+ return (__force __wsum)-1; /* invalid checksum */
+}
+
+/*
+ * the same as csum_partial, but copies from user space (but on MIPS
+ * we have just one address space, so this is identical to the above)
+ */
+__wsum csum_partial_copy_nocheck(const void *src, void *dst,
+ int len, __wsum sum);
+
+/*
+ * Fold a partial checksum without adding pseudo headers
+ */
+static inline __sum16 csum_fold(__wsum sum)
+{
+ __asm__(
+ " .set push # csum_fold\n"
+ " .set noat \n"
+ " sll $1, %0, 16 \n"
+ " addu %0, $1 \n"
+ " sltu $1, %0, $1 \n"
+ " srl %0, %0, 16 \n"
+ " addu %0, $1 \n"
+ " xori %0, 0xffff \n"
+ " .set pop"
+ : "=r" (sum)
+ : "0" (sum));
+
+ return (__force __sum16)sum;
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ *
+ * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
+ * Arnt Gulbrandsen.
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ const unsigned int *word = iph;
+ const unsigned int *stop = word + ihl;
+ unsigned int csum;
+ int carry;
+
+ csum = word[0];
+ csum += word[1];
+ carry = (csum < word[1]);
+ csum += carry;
+
+ csum += word[2];
+ carry = (csum < word[2]);
+ csum += carry;
+
+ csum += word[3];
+ carry = (csum < word[3]);
+ csum += carry;
+
+ word += 4;
+ do {
+ csum += *word;
+ carry = (csum < *word);
+ csum += carry;
+ word++;
+ } while (word != stop);
+
+ return csum_fold(csum);
+}
+
+static inline __wsum csum_tcpudp_nofold(__be32 saddr,
+ __be32 daddr, unsigned short len, unsigned short proto,
+ __wsum sum)
+{
+ __asm__(
+ " .set push # csum_tcpudp_nofold\n"
+ " .set noat \n"
+#ifdef CONFIG_32BIT
+ " addu %0, %2 \n"
+ " sltu $1, %0, %2 \n"
+ " addu %0, $1 \n"
+
+ " addu %0, %3 \n"
+ " sltu $1, %0, %3 \n"
+ " addu %0, $1 \n"
+
+ " addu %0, %4 \n"
+ " sltu $1, %0, %4 \n"
+ " addu %0, $1 \n"
+#endif
+#ifdef CONFIG_64BIT
+ " daddu %0, %2 \n"
+ " daddu %0, %3 \n"
+ " daddu %0, %4 \n"
+ " dsll32 $1, %0, 0 \n"
+ " daddu %0, $1 \n"
+ " dsra32 %0, %0, 0 \n"
+#endif
+ " .set pop"
+ : "=r" (sum)
+ : "0" ((__force unsigned long)daddr),
+ "r" ((__force unsigned long)saddr),
+#ifdef __MIPSEL__
+ "r" ((proto + len) << 8),
+#else
+ "r" (proto + len),
+#endif
+ "r" ((__force unsigned long)sum));
+
+ return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+ unsigned short len,
+ unsigned short proto,
+ __wsum sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+static inline __sum16 ip_compute_csum(const void *buff, int len)
+{
+ return csum_fold(csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+ const struct in6_addr *daddr,
+ __u32 len, unsigned short proto,
+ __wsum sum)
+{
+ __asm__(
+ " .set push # csum_ipv6_magic\n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " addu %0, %5 # proto (long in network byte order)\n"
+ " sltu $1, %0, %5 \n"
+ " addu %0, $1 \n"
+
+ " addu %0, %6 # csum\n"
+ " sltu $1, %0, %6 \n"
+ " lw %1, 0(%2) # four words source address\n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 4(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 8(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 12(%2) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 0(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 4(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 8(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " lw %1, 12(%3) \n"
+ " addu %0, $1 \n"
+ " addu %0, %1 \n"
+ " sltu $1, %0, %1 \n"
+
+ " addu %0, $1 # Add final carry\n"
+ " .set pop"
+ : "=r" (sum), "=r" (proto)
+ : "r" (saddr), "r" (daddr),
+ "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
+
+ return csum_fold(sum);
+}
+
+#endif /* _ASM_CHECKSUM_H */
diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h
new file mode 100644
index 00000000..83894aa7
--- /dev/null
+++ b/arch/mips/include/asm/clock.h
@@ -0,0 +1,64 @@
+#ifndef __ASM_MIPS_CLOCK_H
+#define __ASM_MIPS_CLOCK_H
+
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/seq_file.h>
+#include <linux/clk.h>
+
+extern void (*cpu_wait) (void);
+
+struct clk;
+
+struct clk_ops {
+ void (*init) (struct clk *clk);
+ void (*enable) (struct clk *clk);
+ void (*disable) (struct clk *clk);
+ void (*recalc) (struct clk *clk);
+ int (*set_rate) (struct clk *clk, unsigned long rate, int algo_id);
+ long (*round_rate) (struct clk *clk, unsigned long rate);
+};
+
+struct clk {
+ struct list_head node;
+ const char *name;
+ int id;
+ struct module *owner;
+
+ struct clk *parent;
+ struct clk_ops *ops;
+
+ struct kref kref;
+
+ unsigned long rate;
+ unsigned long flags;
+};
+
+#define CLK_ALWAYS_ENABLED (1 << 0)
+#define CLK_RATE_PROPAGATES (1 << 1)
+
+/* Should be defined by processor-specific code */
+void arch_init_clk_ops(struct clk_ops **, int type);
+
+int clk_init(void);
+
+int __clk_enable(struct clk *);
+void __clk_disable(struct clk *);
+
+void clk_recalc_rate(struct clk *);
+
+int clk_register(struct clk *);
+void clk_unregister(struct clk *);
+
+/* the exported API, in addition to clk_set_rate */
+/**
+ * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
+ * @clk: clock source
+ * @rate: desired clock rate in Hz
+ * @algo_id: algorithm id to be passed down to ops->set_rate
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
+
+#endif /* __ASM_MIPS_CLOCK_H */
diff --git a/arch/mips/include/asm/cmp.h b/arch/mips/include/asm/cmp.h
new file mode 100644
index 00000000..89a73fb9
--- /dev/null
+++ b/arch/mips/include/asm/cmp.h
@@ -0,0 +1,18 @@
+#ifndef _ASM_CMP_H
+#define _ASM_CMP_H
+
+/*
+ * Definitions for CMP multitasking on MIPS cores
+ */
+struct task_struct;
+
+extern void cmp_smp_setup(void);
+extern void cmp_smp_finish(void);
+extern void cmp_boot_secondary(int cpu, struct task_struct *t);
+extern void cmp_init_secondary(void);
+extern void cmp_cpus_done(void);
+extern void cmp_prepare_cpus(unsigned int max_cpus);
+
+/* This is platform specific */
+extern void cmp_send_ipi(int cpu, unsigned int action);
+#endif /* _ASM_CMP_H */
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
new file mode 100644
index 00000000..d8d1c280
--- /dev/null
+++ b/arch/mips/include/asm/cmpxchg.h
@@ -0,0 +1,121 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 06, 07 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_CMPXCHG_H
+#define __ASM_CMPXCHG_H
+
+#include <linux/irqflags.h>
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+#define __cmpxchg_asm(ld, st, m, old, new) \
+({ \
+ __typeof(*(m)) __ret; \
+ \
+ if (kernel_uses_llsc && R10000_LLSC_WAR) { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set mips3 \n" \
+ "1: " ld " %0, %2 # __cmpxchg_asm \n" \
+ " bne %0, %z3, 2f \n" \
+ " .set mips0 \n" \
+ " move $1, %z4 \n" \
+ " .set mips3 \n" \
+ " " st " $1, %1 \n" \
+ " beqzl $1, 1b \n" \
+ "2: \n" \
+ " .set pop \n" \
+ : "=&r" (__ret), "=R" (*m) \
+ : "R" (*m), "Jr" (old), "Jr" (new) \
+ : "memory"); \
+ } else if (kernel_uses_llsc) { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set mips3 \n" \
+ "1: " ld " %0, %2 # __cmpxchg_asm \n" \
+ " bne %0, %z3, 2f \n" \
+ " .set mips0 \n" \
+ " move $1, %z4 \n" \
+ " .set mips3 \n" \
+ " " st " $1, %1 \n" \
+ " beqz $1, 1b \n" \
+ " .set pop \n" \
+ "2: \n" \
+ : "=&r" (__ret), "=R" (*m) \
+ : "R" (*m), "Jr" (old), "Jr" (new) \
+ : "memory"); \
+ } else { \
+ unsigned long __flags; \
+ \
+ raw_local_irq_save(__flags); \
+ __ret = *m; \
+ if (__ret == old) \
+ *m = new; \
+ raw_local_irq_restore(__flags); \
+ } \
+ \
+ __ret; \
+})
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg().
+ */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+#define __cmpxchg(ptr, old, new, pre_barrier, post_barrier) \
+({ \
+ __typeof__(ptr) __ptr = (ptr); \
+ __typeof__(*(ptr)) __old = (old); \
+ __typeof__(*(ptr)) __new = (new); \
+ __typeof__(*(ptr)) __res = 0; \
+ \
+ pre_barrier; \
+ \
+ switch (sizeof(*(__ptr))) { \
+ case 4: \
+ __res = __cmpxchg_asm("ll", "sc", __ptr, __old, __new); \
+ break; \
+ case 8: \
+ if (sizeof(long) == 8) { \
+ __res = __cmpxchg_asm("lld", "scd", __ptr, \
+ __old, __new); \
+ break; \
+ } \
+ default: \
+ __cmpxchg_called_with_bad_pointer(); \
+ break; \
+ } \
+ \
+ post_barrier; \
+ \
+ __res; \
+})
+
+#define cmpxchg(ptr, old, new) __cmpxchg(ptr, old, new, smp_mb__before_llsc(), smp_llsc_mb())
+#define cmpxchg_local(ptr, old, new) __cmpxchg(ptr, old, new, , )
+
+#define cmpxchg64(ptr, o, n) \
+ ({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg((ptr), (o), (n)); \
+ })
+
+#ifdef CONFIG_64BIT
+#define cmpxchg64_local(ptr, o, n) \
+ ({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg_local((ptr), (o), (n)); \
+ })
+#else
+#include <asm-generic/cmpxchg-local.h>
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+#endif
+
+#endif /* __ASM_CMPXCHG_H */
diff --git a/arch/mips/include/asm/compat-signal.h b/arch/mips/include/asm/compat-signal.h
new file mode 100644
index 00000000..368a99e5
--- /dev/null
+++ b/arch/mips/include/asm/compat-signal.h
@@ -0,0 +1,119 @@
+#ifndef __ASM_COMPAT_SIGNAL_H
+#define __ASM_COMPAT_SIGNAL_H
+
+#include <linux/bug.h>
+#include <linux/compat.h>
+#include <linux/compiler.h>
+
+#include <asm/signal.h>
+#include <asm/siginfo.h>
+
+#include <asm/uaccess.h>
+
+#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct compat_siginfo {
+ int si_signo;
+ int si_code;
+ int si_errno;
+
+ union {
+ int _pad[SI_PAD_SIZE32];
+
+ /* kill() */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ compat_uid_t _uid; /* sender's uid */
+ } _kill;
+
+ /* SIGCHLD */
+ struct {
+ compat_pid_t _pid; /* which child */
+ compat_uid_t _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* IRIX SIGCHLD */
+ struct {
+ compat_pid_t _pid; /* which child */
+ compat_clock_t _utime;
+ int _status; /* exit code */
+ compat_clock_t _stime;
+ } _irix_sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ s32 _addr; /* faulting insn/memory ref. */
+ } _sigfault;
+
+ /* SIGPOLL, SIGXFSZ (To do ...) */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+
+ /* POSIX.1b timers */
+ struct {
+ timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval;/* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ compat_pid_t _pid; /* sender's pid */
+ compat_uid_t _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ } _sifields;
+} compat_siginfo_t;
+
+static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d,
+ const sigset_t *s)
+{
+ int err;
+
+ BUG_ON(sizeof(*d) != sizeof(*s));
+ BUG_ON(_NSIG_WORDS != 2);
+
+ err = __put_user(s->sig[0], &d->sig[0]);
+ err |= __put_user(s->sig[0] >> 32, &d->sig[1]);
+ err |= __put_user(s->sig[1], &d->sig[2]);
+ err |= __put_user(s->sig[1] >> 32, &d->sig[3]);
+
+ return err;
+}
+
+static inline int __copy_conv_sigset_from_user(sigset_t *d,
+ const compat_sigset_t __user *s)
+{
+ int err;
+ union sigset_u {
+ sigset_t s;
+ compat_sigset_t c;
+ } *u = (union sigset_u *) d;
+
+ BUG_ON(sizeof(*d) != sizeof(*s));
+ BUG_ON(_NSIG_WORDS != 2);
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ err = __get_user(u->c.sig[1], &s->sig[0]);
+ err |= __get_user(u->c.sig[0], &s->sig[1]);
+ err |= __get_user(u->c.sig[3], &s->sig[2]);
+ err |= __get_user(u->c.sig[2], &s->sig[3]);
+#endif
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ err = __get_user(u->c.sig[0], &s->sig[0]);
+ err |= __get_user(u->c.sig[1], &s->sig[1]);
+ err |= __get_user(u->c.sig[2], &s->sig[2]);
+ err |= __get_user(u->c.sig[3], &s->sig[3]);
+#endif
+
+ return err;
+}
+
+#endif /* __ASM_COMPAT_SIGNAL_H */
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
new file mode 100644
index 00000000..dbc51065
--- /dev/null
+++ b/arch/mips/include/asm/compat.h
@@ -0,0 +1,228 @@
+#ifndef _ASM_COMPAT_H
+#define _ASM_COMPAT_H
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/thread_info.h>
+#include <linux/types.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+
+#define COMPAT_USER_HZ 100
+#define COMPAT_UTS_MACHINE "mips\0\0\0"
+
+typedef u32 compat_size_t;
+typedef s32 compat_ssize_t;
+typedef s32 compat_time_t;
+typedef s32 compat_clock_t;
+typedef s32 compat_suseconds_t;
+
+typedef s32 compat_pid_t;
+typedef s32 __compat_uid_t;
+typedef s32 __compat_gid_t;
+typedef __compat_uid_t __compat_uid32_t;
+typedef __compat_gid_t __compat_gid32_t;
+typedef u32 compat_mode_t;
+typedef u32 compat_ino_t;
+typedef u32 compat_dev_t;
+typedef s32 compat_off_t;
+typedef s64 compat_loff_t;
+typedef u32 compat_nlink_t;
+typedef s32 compat_ipc_pid_t;
+typedef s32 compat_daddr_t;
+typedef s32 compat_caddr_t;
+typedef struct {
+ s32 val[2];
+} compat_fsid_t;
+typedef s32 compat_timer_t;
+typedef s32 compat_key_t;
+
+typedef s32 compat_int_t;
+typedef s32 compat_long_t;
+typedef s64 compat_s64;
+typedef u32 compat_uint_t;
+typedef u32 compat_ulong_t;
+typedef u64 compat_u64;
+
+struct compat_timespec {
+ compat_time_t tv_sec;
+ s32 tv_nsec;
+};
+
+struct compat_timeval {
+ compat_time_t tv_sec;
+ s32 tv_usec;
+};
+
+struct compat_stat {
+ compat_dev_t st_dev;
+ s32 st_pad1[3];
+ compat_ino_t st_ino;
+ compat_mode_t st_mode;
+ compat_nlink_t st_nlink;
+ __compat_uid_t st_uid;
+ __compat_gid_t st_gid;
+ compat_dev_t st_rdev;
+ s32 st_pad2[2];
+ compat_off_t st_size;
+ s32 st_pad3;
+ compat_time_t st_atime;
+ s32 st_atime_nsec;
+ compat_time_t st_mtime;
+ s32 st_mtime_nsec;
+ compat_time_t st_ctime;
+ s32 st_ctime_nsec;
+ s32 st_blksize;
+ s32 st_blocks;
+ s32 st_pad4[14];
+};
+
+struct compat_flock {
+ short l_type;
+ short l_whence;
+ compat_off_t l_start;
+ compat_off_t l_len;
+ s32 l_sysid;
+ compat_pid_t l_pid;
+ short __unused;
+ s32 pad[4];
+};
+
+#define F_GETLK64 33
+#define F_SETLK64 34
+#define F_SETLKW64 35
+
+struct compat_flock64 {
+ short l_type;
+ short l_whence;
+ compat_loff_t l_start;
+ compat_loff_t l_len;
+ compat_pid_t l_pid;
+};
+
+struct compat_statfs {
+ int f_type;
+ int f_bsize;
+ int f_frsize;
+ int f_blocks;
+ int f_bfree;
+ int f_files;
+ int f_ffree;
+ int f_bavail;
+ compat_fsid_t f_fsid;
+ int f_namelen;
+ int f_spare[6];
+};
+
+#define COMPAT_RLIM_INFINITY 0x7fffffffUL
+
+typedef u32 compat_old_sigset_t; /* at least 32 bits */
+
+#define _COMPAT_NSIG 128 /* Don't ask !$@#% ... */
+#define _COMPAT_NSIG_BPW 32
+
+typedef u32 compat_sigset_word;
+
+#define COMPAT_OFF_T_MAX 0x7fffffff
+#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
+
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately converted them already.
+ */
+typedef u32 compat_uptr_t;
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+ /* cast to a __user pointer via "unsigned long" makes sparse happy */
+ return (void __user *)(unsigned long)(long)uptr;
+}
+
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+ return (u32)(unsigned long)uptr;
+}
+
+static inline void __user *arch_compat_alloc_user_space(long len)
+{
+ struct pt_regs *regs = (struct pt_regs *)
+ ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1;
+
+ return (void __user *) (regs->regs[29] - len);
+}
+
+struct compat_ipc64_perm {
+ compat_key_t key;
+ __compat_uid32_t uid;
+ __compat_gid32_t gid;
+ __compat_uid32_t cuid;
+ __compat_gid32_t cgid;
+ compat_mode_t mode;
+ unsigned short seq;
+ unsigned short __pad2;
+ compat_ulong_t __unused1;
+ compat_ulong_t __unused2;
+};
+
+struct compat_semid64_ds {
+ struct compat_ipc64_perm sem_perm;
+ compat_time_t sem_otime;
+ compat_time_t sem_ctime;
+ compat_ulong_t sem_nsems;
+ compat_ulong_t __unused1;
+ compat_ulong_t __unused2;
+};
+
+struct compat_msqid64_ds {
+ struct compat_ipc64_perm msg_perm;
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused1;
+#endif
+ compat_time_t msg_stime;
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused1;
+#endif
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused2;
+#endif
+ compat_time_t msg_rtime;
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused2;
+#endif
+#ifndef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused3;
+#endif
+ compat_time_t msg_ctime;
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ compat_ulong_t __unused3;
+#endif
+ compat_ulong_t msg_cbytes;
+ compat_ulong_t msg_qnum;
+ compat_ulong_t msg_qbytes;
+ compat_pid_t msg_lspid;
+ compat_pid_t msg_lrpid;
+ compat_ulong_t __unused4;
+ compat_ulong_t __unused5;
+};
+
+struct compat_shmid64_ds {
+ struct compat_ipc64_perm shm_perm;
+ compat_size_t shm_segsz;
+ compat_time_t shm_atime;
+ compat_time_t shm_dtime;
+ compat_time_t shm_ctime;
+ compat_pid_t shm_cpid;
+ compat_pid_t shm_lpid;
+ compat_ulong_t shm_nattch;
+ compat_ulong_t __unused1;
+ compat_ulong_t __unused2;
+};
+
+static inline int is_compat_task(void)
+{
+ return test_thread_flag(TIF_32BIT);
+}
+
+#endif /* _ASM_COMPAT_H */
diff --git a/arch/mips/include/asm/compiler.h b/arch/mips/include/asm/compiler.h
new file mode 100644
index 00000000..71f5c5cf
--- /dev/null
+++ b/arch/mips/include/asm/compiler.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2004, 2007 Maciej W. Rozycki
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_COMPILER_H
+#define _ASM_COMPILER_H
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define GCC_IMM_ASM() "n"
+#define GCC_REG_ACCUM "$0"
+#else
+#define GCC_IMM_ASM() "rn"
+#define GCC_REG_ACCUM "accum"
+#endif
+
+#endif /* _ASM_COMPILER_H */
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h
new file mode 100644
index 00000000..3532e2c5
--- /dev/null
+++ b/arch/mips/include/asm/cop2.h
@@ -0,0 +1,35 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Wind River Systems,
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_COP2_H
+#define __ASM_COP2_H
+
+#include <linux/notifier.h>
+
+enum cu2_ops {
+ CU2_EXCEPTION,
+ CU2_LWC2_OP,
+ CU2_LDC2_OP,
+ CU2_SWC2_OP,
+ CU2_SDC2_OP,
+};
+
+extern int register_cu2_notifier(struct notifier_block *nb);
+extern int cu2_notifier_call_chain(unsigned long val, void *v);
+
+#define cu2_notifier(fn, pri) \
+({ \
+ static struct notifier_block fn##_nb = { \
+ .notifier_call = fn, \
+ .priority = pri \
+ }; \
+ \
+ register_cu2_notifier(&fn##_nb); \
+})
+
+#endif /* __ASM_COP2_H */
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
new file mode 100644
index 00000000..ca400f7c
--- /dev/null
+++ b/arch/mips/include/asm/cpu-features.h
@@ -0,0 +1,255 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
+ */
+#ifndef __ASM_CPU_FEATURES_H
+#define __ASM_CPU_FEATURES_H
+
+#include <asm/cpu.h>
+#include <asm/cpu-info.h>
+#include <cpu-feature-overrides.h>
+
+#ifndef current_cpu_type
+#define current_cpu_type() current_cpu_data.cputype
+#endif
+
+/*
+ * SMP assumption: Options of CPU 0 are a superset of all processors.
+ * This is true for all known MIPS systems.
+ */
+#ifndef cpu_has_tlb
+#define cpu_has_tlb (cpu_data[0].options & MIPS_CPU_TLB)
+#endif
+#ifndef cpu_has_4kex
+#define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX)
+#endif
+#ifndef cpu_has_3k_cache
+#define cpu_has_3k_cache (cpu_data[0].options & MIPS_CPU_3K_CACHE)
+#endif
+#define cpu_has_6k_cache 0
+#define cpu_has_8k_cache 0
+#ifndef cpu_has_4k_cache
+#define cpu_has_4k_cache (cpu_data[0].options & MIPS_CPU_4K_CACHE)
+#endif
+#ifndef cpu_has_tx39_cache
+#define cpu_has_tx39_cache (cpu_data[0].options & MIPS_CPU_TX39_CACHE)
+#endif
+#ifndef cpu_has_octeon_cache
+#define cpu_has_octeon_cache 0
+#endif
+#ifndef cpu_has_fpu
+#define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU)
+#define raw_cpu_has_fpu (raw_current_cpu_data.options & MIPS_CPU_FPU)
+#else
+#define raw_cpu_has_fpu cpu_has_fpu
+#endif
+#ifndef cpu_has_32fpr
+#define cpu_has_32fpr (cpu_data[0].options & MIPS_CPU_32FPR)
+#endif
+#ifndef cpu_has_counter
+#define cpu_has_counter (cpu_data[0].options & MIPS_CPU_COUNTER)
+#endif
+#ifndef cpu_has_watch
+#define cpu_has_watch (cpu_data[0].options & MIPS_CPU_WATCH)
+#endif
+#ifndef cpu_has_divec
+#define cpu_has_divec (cpu_data[0].options & MIPS_CPU_DIVEC)
+#endif
+#ifndef cpu_has_vce
+#define cpu_has_vce (cpu_data[0].options & MIPS_CPU_VCE)
+#endif
+#ifndef cpu_has_cache_cdex_p
+#define cpu_has_cache_cdex_p (cpu_data[0].options & MIPS_CPU_CACHE_CDEX_P)
+#endif
+#ifndef cpu_has_cache_cdex_s
+#define cpu_has_cache_cdex_s (cpu_data[0].options & MIPS_CPU_CACHE_CDEX_S)
+#endif
+#ifndef cpu_has_prefetch
+#define cpu_has_prefetch (cpu_data[0].options & MIPS_CPU_PREFETCH)
+#endif
+#ifndef cpu_has_mcheck
+#define cpu_has_mcheck (cpu_data[0].options & MIPS_CPU_MCHECK)
+#endif
+#ifndef cpu_has_ejtag
+#define cpu_has_ejtag (cpu_data[0].options & MIPS_CPU_EJTAG)
+#endif
+#ifndef cpu_has_llsc
+#define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC)
+#endif
+#ifndef kernel_uses_llsc
+#define kernel_uses_llsc cpu_has_llsc
+#endif
+#ifndef cpu_has_mips16
+#define cpu_has_mips16 (cpu_data[0].ases & MIPS_ASE_MIPS16)
+#endif
+#ifndef cpu_has_mdmx
+#define cpu_has_mdmx (cpu_data[0].ases & MIPS_ASE_MDMX)
+#endif
+#ifndef cpu_has_mips3d
+#define cpu_has_mips3d (cpu_data[0].ases & MIPS_ASE_MIPS3D)
+#endif
+#ifndef cpu_has_smartmips
+#define cpu_has_smartmips (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
+#endif
+#ifndef kernel_uses_smartmips_rixi
+#define kernel_uses_smartmips_rixi 0
+#endif
+#ifndef cpu_has_vtag_icache
+#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
+#endif
+#ifndef cpu_has_dc_aliases
+#define cpu_has_dc_aliases (cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES)
+#endif
+#ifndef cpu_has_ic_fills_f_dc
+#define cpu_has_ic_fills_f_dc (cpu_data[0].icache.flags & MIPS_CACHE_IC_F_DC)
+#endif
+#ifndef cpu_has_pindexed_dcache
+#define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX)
+#endif
+
+/*
+ * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors
+ * such as the R10000 have I-Caches that snoop local stores; the embedded ones
+ * don't. For maintaining I-cache coherency this means we need to flush the
+ * D-cache all the way back to whever the I-cache does refills from, so the
+ * I-cache has a chance to see the new data at all. Then we have to flush the
+ * I-cache also.
+ * Note we may have been rescheduled and may no longer be running on the CPU
+ * that did the store so we can't optimize this into only doing the flush on
+ * the local CPU.
+ */
+#ifndef cpu_icache_snoops_remote_store
+#ifdef CONFIG_SMP
+#define cpu_icache_snoops_remote_store (cpu_data[0].icache.flags & MIPS_IC_SNOOPS_REMOTE)
+#else
+#define cpu_icache_snoops_remote_store 1
+#endif
+#endif
+
+# ifndef cpu_has_mips32r1
+# define cpu_has_mips32r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R1)
+# endif
+# ifndef cpu_has_mips32r2
+# define cpu_has_mips32r2 (cpu_data[0].isa_level & MIPS_CPU_ISA_M32R2)
+# endif
+# ifndef cpu_has_mips64r1
+# define cpu_has_mips64r1 (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R1)
+# endif
+# ifndef cpu_has_mips64r2
+# define cpu_has_mips64r2 (cpu_data[0].isa_level & MIPS_CPU_ISA_M64R2)
+# endif
+
+/*
+ * Shortcuts ...
+ */
+#define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2)
+#define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2)
+#define cpu_has_mips_r1 (cpu_has_mips32r1 | cpu_has_mips64r1)
+#define cpu_has_mips_r2 (cpu_has_mips32r2 | cpu_has_mips64r2)
+#define cpu_has_mips_r (cpu_has_mips32r1 | cpu_has_mips32r2 | \
+ cpu_has_mips64r1 | cpu_has_mips64r2)
+
+#ifndef cpu_has_mips_r2_exec_hazard
+#define cpu_has_mips_r2_exec_hazard cpu_has_mips_r2
+#endif
+
+/*
+ * MIPS32, MIPS64, VR5500, IDT32332, IDT32334 and maybe a few other
+ * pre-MIPS32/MIPS53 processors have CLO, CLZ. The IDT RC64574 is 64-bit and
+ * has CLO and CLZ but not DCLO nor DCLZ. For 64-bit kernels
+ * cpu_has_clo_clz also indicates the availability of DCLO and DCLZ.
+ */
+# ifndef cpu_has_clo_clz
+# define cpu_has_clo_clz cpu_has_mips_r
+# endif
+
+#ifndef cpu_has_dsp
+#define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP)
+#endif
+
+#ifndef cpu_has_mipsmt
+#define cpu_has_mipsmt (cpu_data[0].ases & MIPS_ASE_MIPSMT)
+#endif
+
+#ifndef cpu_has_userlocal
+#define cpu_has_userlocal (cpu_data[0].options & MIPS_CPU_ULRI)
+#endif
+
+#ifdef CONFIG_32BIT
+# ifndef cpu_has_nofpuex
+# define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX)
+# endif
+# ifndef cpu_has_64bits
+# define cpu_has_64bits (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
+# endif
+# ifndef cpu_has_64bit_zero_reg
+# define cpu_has_64bit_zero_reg (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
+# endif
+# ifndef cpu_has_64bit_gp_regs
+# define cpu_has_64bit_gp_regs 0
+# endif
+# ifndef cpu_has_64bit_addresses
+# define cpu_has_64bit_addresses 0
+# endif
+# ifndef cpu_vmbits
+# define cpu_vmbits 31
+# endif
+#endif
+
+#ifdef CONFIG_64BIT
+# ifndef cpu_has_nofpuex
+# define cpu_has_nofpuex 0
+# endif
+# ifndef cpu_has_64bits
+# define cpu_has_64bits 1
+# endif
+# ifndef cpu_has_64bit_zero_reg
+# define cpu_has_64bit_zero_reg 1
+# endif
+# ifndef cpu_has_64bit_gp_regs
+# define cpu_has_64bit_gp_regs 1
+# endif
+# ifndef cpu_has_64bit_addresses
+# define cpu_has_64bit_addresses 1
+# endif
+# ifndef cpu_vmbits
+# define cpu_vmbits cpu_data[0].vmbits
+# define __NEED_VMBITS_PROBE
+# endif
+#endif
+
+#if defined(CONFIG_CPU_MIPSR2_IRQ_VI) && !defined(cpu_has_vint)
+# define cpu_has_vint (cpu_data[0].options & MIPS_CPU_VINT)
+#elif !defined(cpu_has_vint)
+# define cpu_has_vint 0
+#endif
+
+#if defined(CONFIG_CPU_MIPSR2_IRQ_EI) && !defined(cpu_has_veic)
+# define cpu_has_veic (cpu_data[0].options & MIPS_CPU_VEIC)
+#elif !defined(cpu_has_veic)
+# define cpu_has_veic 0
+#endif
+
+#ifndef cpu_has_inclusive_pcaches
+#define cpu_has_inclusive_pcaches (cpu_data[0].options & MIPS_CPU_INCLUSIVE_CACHES)
+#endif
+
+#ifndef cpu_dcache_line_size
+#define cpu_dcache_line_size() cpu_data[0].dcache.linesz
+#endif
+#ifndef cpu_icache_line_size
+#define cpu_icache_line_size() cpu_data[0].icache.linesz
+#endif
+#ifndef cpu_scache_line_size
+#define cpu_scache_line_size() cpu_data[0].scache.linesz
+#endif
+
+#ifndef cpu_hwrena_impl_bits
+#define cpu_hwrena_impl_bits 0
+#endif
+
+#endif /* __ASM_CPU_FEATURES_H */
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
new file mode 100644
index 00000000..c454550e
--- /dev/null
+++ b/arch/mips/include/asm/cpu-info.h
@@ -0,0 +1,94 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 Waldorf GMBH
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004 Maciej W. Rozycki
+ */
+#ifndef __ASM_CPU_INFO_H
+#define __ASM_CPU_INFO_H
+
+#include <linux/types.h>
+
+#include <asm/cache.h>
+
+/*
+ * Descriptor for a cache
+ */
+struct cache_desc {
+ unsigned int waysize; /* Bytes per way */
+ unsigned short sets; /* Number of lines per set */
+ unsigned char ways; /* Number of ways */
+ unsigned char linesz; /* Size of line in bytes */
+ unsigned char waybit; /* Bits to select in a cache set */
+ unsigned char flags; /* Flags describing cache properties */
+};
+
+/*
+ * Flag definitions
+ */
+#define MIPS_CACHE_NOT_PRESENT 0x00000001
+#define MIPS_CACHE_VTAG 0x00000002 /* Virtually tagged cache */
+#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */
+#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */
+#define MIPS_IC_SNOOPS_REMOTE 0x00000010 /* Ic snoops remote stores */
+#define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */
+
+struct cpuinfo_mips {
+ unsigned int udelay_val;
+ unsigned int asid_cache;
+
+ /*
+ * Capability and feature descriptor structure for MIPS CPU
+ */
+ unsigned long options;
+ unsigned long ases;
+ unsigned int processor_id;
+ unsigned int fpu_id;
+ unsigned int cputype;
+ int isa_level;
+ int tlbsize;
+ struct cache_desc icache; /* Primary I-cache */
+ struct cache_desc dcache; /* Primary D or combined I/D cache */
+ struct cache_desc scache; /* Secondary cache */
+ struct cache_desc tcache; /* Tertiary/split secondary cache */
+ int srsets; /* Shadow register sets */
+ int core; /* physical core number */
+#ifdef CONFIG_64BIT
+ int vmbits; /* Virtual memory size in bits */
+#endif
+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
+ /*
+ * In the MIPS MT "SMTC" model, each TC is considered
+ * to be a "CPU" for the purposes of scheduling, but
+ * exception resources, ASID spaces, etc, are common
+ * to all TCs within the same VPE.
+ */
+ int vpe_id; /* Virtual Processor number */
+#endif
+#ifdef CONFIG_MIPS_MT_SMTC
+ int tc_id; /* Thread Context number */
+#endif
+ void *data; /* Additional data */
+ unsigned int watch_reg_count; /* Number that exist */
+ unsigned int watch_reg_use_cnt; /* Usable by ptrace */
+#define NUM_WATCH_REGS 4
+ u16 watch_reg_masks[NUM_WATCH_REGS];
+ unsigned int kscratch_mask; /* Usable KScratch mask. */
+} __attribute__((aligned(SMP_CACHE_BYTES)));
+
+extern struct cpuinfo_mips cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+#define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
+
+extern void cpu_probe(void);
+extern void cpu_report(void);
+
+extern const char *__cpu_name[];
+#define cpu_name_string() __cpu_name[smp_processor_id()]
+
+#endif /* __ASM_CPU_INFO_H */
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
new file mode 100644
index 00000000..5f95a4bf
--- /dev/null
+++ b/arch/mips/include/asm/cpu.h
@@ -0,0 +1,325 @@
+/*
+ * cpu.h: Values of the PRId register used to match up
+ * various MIPS cpu types.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2004 Maciej W. Rozycki
+ */
+#ifndef _ASM_CPU_H
+#define _ASM_CPU_H
+
+/* Assigned Company values for bits 23:16 of the PRId Register
+ (CP0 register 15, select 0). As of the MIPS32 and MIPS64 specs from
+ MTI, the PRId register is defined in this (backwards compatible)
+ way:
+
+ +----------------+----------------+----------------+----------------+
+ | Company Options| Company ID | Processor ID | Revision |
+ +----------------+----------------+----------------+----------------+
+ 31 24 23 16 15 8 7
+
+ I don't have docs for all the previous processors, but my impression is
+ that bits 16-23 have been 0 for all MIPS processors before the MIPS32/64
+ spec.
+*/
+
+#define PRID_COMP_LEGACY 0x000000
+#define PRID_COMP_MIPS 0x010000
+#define PRID_COMP_BROADCOM 0x020000
+#define PRID_COMP_ALCHEMY 0x030000
+#define PRID_COMP_SIBYTE 0x040000
+#define PRID_COMP_SANDCRAFT 0x050000
+#define PRID_COMP_NXP 0x060000
+#define PRID_COMP_TOSHIBA 0x070000
+#define PRID_COMP_LSI 0x080000
+#define PRID_COMP_LEXRA 0x0b0000
+#define PRID_COMP_NETLOGIC 0x0c0000
+#define PRID_COMP_CAVIUM 0x0d0000
+#define PRID_COMP_INGENIC 0xd00000
+
+/*
+ * Assigned values for the product ID register. In order to detect a
+ * certain CPU type exactly eventually additional registers may need to
+ * be examined. These are valid when 23:16 == PRID_COMP_LEGACY
+ */
+#define PRID_IMP_R2000 0x0100
+#define PRID_IMP_AU1_REV1 0x0100
+#define PRID_IMP_AU1_REV2 0x0200
+#define PRID_IMP_R3000 0x0200 /* Same as R2000A */
+#define PRID_IMP_R6000 0x0300 /* Same as R3000A */
+#define PRID_IMP_R4000 0x0400
+#define PRID_IMP_R6000A 0x0600
+#define PRID_IMP_R10000 0x0900
+#define PRID_IMP_R4300 0x0b00
+#define PRID_IMP_VR41XX 0x0c00
+#define PRID_IMP_R12000 0x0e00
+#define PRID_IMP_R14000 0x0f00
+#define PRID_IMP_R8000 0x1000
+#define PRID_IMP_PR4450 0x1200
+#define PRID_IMP_R4600 0x2000
+#define PRID_IMP_R4700 0x2100
+#define PRID_IMP_TX39 0x2200
+#define PRID_IMP_R4640 0x2200
+#define PRID_IMP_R4650 0x2200 /* Same as R4640 */
+#define PRID_IMP_R5000 0x2300
+#define PRID_IMP_TX49 0x2d00
+#define PRID_IMP_SONIC 0x2400
+#define PRID_IMP_MAGIC 0x2500
+#define PRID_IMP_RM7000 0x2700
+#define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */
+#define PRID_IMP_RM9000 0x3400
+#define PRID_IMP_LOONGSON1 0x4200
+#define PRID_IMP_R5432 0x5400
+#define PRID_IMP_R5500 0x5500
+#define PRID_IMP_LOONGSON2 0x6300
+
+#define PRID_IMP_UNKNOWN 0xff00
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_MIPS
+ */
+
+#define PRID_IMP_4KC 0x8000
+#define PRID_IMP_5KC 0x8100
+#define PRID_IMP_20KC 0x8200
+#define PRID_IMP_4KEC 0x8400
+#define PRID_IMP_4KSC 0x8600
+#define PRID_IMP_25KF 0x8800
+#define PRID_IMP_5KE 0x8900
+#define PRID_IMP_4KECR2 0x9000
+#define PRID_IMP_4KEMPR2 0x9100
+#define PRID_IMP_4KSD 0x9200
+#define PRID_IMP_24K 0x9300
+#define PRID_IMP_34K 0x9500
+#define PRID_IMP_24KE 0x9600
+#define PRID_IMP_74K 0x9700
+#define PRID_IMP_1004K 0x9900
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
+ */
+
+#define PRID_IMP_SB1 0x0100
+#define PRID_IMP_SB1A 0x1100
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_SANDCRAFT
+ */
+
+#define PRID_IMP_SR71000 0x0400
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
+ */
+
+#define PRID_IMP_BMIPS32_REV4 0x4000
+#define PRID_IMP_BMIPS32_REV8 0x8000
+#define PRID_IMP_BMIPS3300 0x9000
+#define PRID_IMP_BMIPS3300_ALT 0x9100
+#define PRID_IMP_BMIPS3300_BUG 0x0000
+#define PRID_IMP_BMIPS43XX 0xa000
+#define PRID_IMP_BMIPS5000 0x5a00
+
+#define PRID_REV_BMIPS4380_LO 0x0040
+#define PRID_REV_BMIPS4380_HI 0x006f
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
+ */
+
+#define PRID_IMP_CAVIUM_CN38XX 0x0000
+#define PRID_IMP_CAVIUM_CN31XX 0x0100
+#define PRID_IMP_CAVIUM_CN30XX 0x0200
+#define PRID_IMP_CAVIUM_CN58XX 0x0300
+#define PRID_IMP_CAVIUM_CN56XX 0x0400
+#define PRID_IMP_CAVIUM_CN50XX 0x0600
+#define PRID_IMP_CAVIUM_CN52XX 0x0700
+#define PRID_IMP_CAVIUM_CN63XX 0x9000
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
+ */
+
+#define PRID_IMP_JZRISC 0x0200
+
+/*
+ * These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC
+ */
+#define PRID_IMP_NETLOGIC_XLR732 0x0000
+#define PRID_IMP_NETLOGIC_XLR716 0x0200
+#define PRID_IMP_NETLOGIC_XLR532 0x0900
+#define PRID_IMP_NETLOGIC_XLR308 0x0600
+#define PRID_IMP_NETLOGIC_XLR532C 0x0800
+#define PRID_IMP_NETLOGIC_XLR516C 0x0a00
+#define PRID_IMP_NETLOGIC_XLR508C 0x0b00
+#define PRID_IMP_NETLOGIC_XLR308C 0x0f00
+#define PRID_IMP_NETLOGIC_XLS608 0x8000
+#define PRID_IMP_NETLOGIC_XLS408 0x8800
+#define PRID_IMP_NETLOGIC_XLS404 0x8c00
+#define PRID_IMP_NETLOGIC_XLS208 0x8e00
+#define PRID_IMP_NETLOGIC_XLS204 0x8f00
+#define PRID_IMP_NETLOGIC_XLS108 0xce00
+#define PRID_IMP_NETLOGIC_XLS104 0xcf00
+#define PRID_IMP_NETLOGIC_XLS616B 0x4000
+#define PRID_IMP_NETLOGIC_XLS608B 0x4a00
+#define PRID_IMP_NETLOGIC_XLS416B 0x4400
+#define PRID_IMP_NETLOGIC_XLS412B 0x4c00
+#define PRID_IMP_NETLOGIC_XLS408B 0x4e00
+#define PRID_IMP_NETLOGIC_XLS404B 0x4f00
+
+/*
+ * Definitions for 7:0 on legacy processors
+ */
+
+#define PRID_REV_MASK 0x00ff
+
+#define PRID_REV_TX4927 0x0022
+#define PRID_REV_TX4937 0x0030
+#define PRID_REV_R4400 0x0040
+#define PRID_REV_R3000A 0x0030
+#define PRID_REV_R3000 0x0020
+#define PRID_REV_R2000A 0x0010
+#define PRID_REV_TX3912 0x0010
+#define PRID_REV_TX3922 0x0030
+#define PRID_REV_TX3927 0x0040
+#define PRID_REV_VR4111 0x0050
+#define PRID_REV_VR4181 0x0050 /* Same as VR4111 */
+#define PRID_REV_VR4121 0x0060
+#define PRID_REV_VR4122 0x0070
+#define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */
+#define PRID_REV_VR4130 0x0080
+#define PRID_REV_34K_V1_0_2 0x0022
+#define PRID_REV_LOONGSON2E 0x0002
+#define PRID_REV_LOONGSON2F 0x0003
+
+/*
+ * Older processors used to encode processor version and revision in two
+ * 4-bit bitfields, the 4K seems to simply count up and even newer MTI cores
+ * have switched to use the 8-bits as 3:3:2 bitfield with the last field as
+ * the patch number. *ARGH*
+ */
+#define PRID_REV_ENCODE_44(ver, rev) \
+ ((ver) << 4 | (rev))
+#define PRID_REV_ENCODE_332(ver, rev, patch) \
+ ((ver) << 5 | (rev) << 2 | (patch))
+
+/*
+ * FPU implementation/revision register (CP1 control register 0).
+ *
+ * +---------------------------------+----------------+----------------+
+ * | 0 | Implementation | Revision |
+ * +---------------------------------+----------------+----------------+
+ * 31 16 15 8 7 0
+ */
+
+#define FPIR_IMP_NONE 0x0000
+
+enum cpu_type_enum {
+ CPU_UNKNOWN,
+
+ /*
+ * R2000 class processors
+ */
+ CPU_R2000, CPU_R3000, CPU_R3000A, CPU_R3041, CPU_R3051, CPU_R3052,
+ CPU_R3081, CPU_R3081E,
+
+ /*
+ * R6000 class processors
+ */
+ CPU_R6000, CPU_R6000A,
+
+ /*
+ * R4000 class processors
+ */
+ CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310,
+ CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650,
+ CPU_R4700, CPU_R5000, CPU_R5000A, CPU_R5500, CPU_NEVADA, CPU_R5432,
+ CPU_R10000, CPU_R12000, CPU_R14000, CPU_VR41XX, CPU_VR4111, CPU_VR4121,
+ CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
+ CPU_SR71000, CPU_RM9000, CPU_TX49XX,
+
+ /*
+ * R8000 class processors
+ */
+ CPU_R8000,
+
+ /*
+ * TX3900 class processors
+ */
+ CPU_TX3912, CPU_TX3922, CPU_TX3927,
+
+ /*
+ * MIPS32 class processors
+ */
+ CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
+ CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
+ CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC,
+
+ /*
+ * MIPS64 class processors
+ */
+ CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
+ CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
+ CPU_XLR,
+
+ CPU_LAST
+};
+
+
+/*
+ * ISA Level encodings
+ *
+ */
+#define MIPS_CPU_ISA_I 0x00000001
+#define MIPS_CPU_ISA_II 0x00000002
+#define MIPS_CPU_ISA_III 0x00000004
+#define MIPS_CPU_ISA_IV 0x00000008
+#define MIPS_CPU_ISA_V 0x00000010
+#define MIPS_CPU_ISA_M32R1 0x00000020
+#define MIPS_CPU_ISA_M32R2 0x00000040
+#define MIPS_CPU_ISA_M64R1 0x00000080
+#define MIPS_CPU_ISA_M64R2 0x00000100
+
+#define MIPS_CPU_ISA_32BIT (MIPS_CPU_ISA_I | MIPS_CPU_ISA_II | \
+ MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 )
+#define MIPS_CPU_ISA_64BIT (MIPS_CPU_ISA_III | MIPS_CPU_ISA_IV | \
+ MIPS_CPU_ISA_V | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)
+
+/*
+ * CPU Option encodings
+ */
+#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */
+#define MIPS_CPU_4KEX 0x00000002 /* "R4K" exception model */
+#define MIPS_CPU_3K_CACHE 0x00000004 /* R3000-style caches */
+#define MIPS_CPU_4K_CACHE 0x00000008 /* R4000-style caches */
+#define MIPS_CPU_TX39_CACHE 0x00000010 /* TX3900-style caches */
+#define MIPS_CPU_FPU 0x00000020 /* CPU has FPU */
+#define MIPS_CPU_32FPR 0x00000040 /* 32 dbl. prec. FP registers */
+#define MIPS_CPU_COUNTER 0x00000080 /* Cycle count/compare */
+#define MIPS_CPU_WATCH 0x00000100 /* watchpoint registers */
+#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */
+#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */
+#define MIPS_CPU_CACHE_CDEX_P 0x00000800 /* Create_Dirty_Exclusive CACHE op */
+#define MIPS_CPU_CACHE_CDEX_S 0x00001000 /* ... same for seconary cache ... */
+#define MIPS_CPU_MCHECK 0x00002000 /* Machine check exception */
+#define MIPS_CPU_EJTAG 0x00004000 /* EJTAG exception */
+#define MIPS_CPU_NOFPUEX 0x00008000 /* no FPU exception */
+#define MIPS_CPU_LLSC 0x00010000 /* CPU has ll/sc instructions */
+#define MIPS_CPU_INCLUSIVE_CACHES 0x00020000 /* P-cache subset enforced */
+#define MIPS_CPU_PREFETCH 0x00040000 /* CPU has usable prefetch */
+#define MIPS_CPU_VINT 0x00080000 /* CPU supports MIPSR2 vectored interrupts */
+#define MIPS_CPU_VEIC 0x00100000 /* CPU supports MIPSR2 external interrupt controller mode */
+#define MIPS_CPU_ULRI 0x00200000 /* CPU has ULRI feature */
+
+/*
+ * CPU ASE encodings
+ */
+#define MIPS_ASE_MIPS16 0x00000001 /* code compression */
+#define MIPS_ASE_MDMX 0x00000002 /* MIPS digital media extension */
+#define MIPS_ASE_MIPS3D 0x00000004 /* MIPS-3D */
+#define MIPS_ASE_SMARTMIPS 0x00000008 /* SmartMIPS */
+#define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */
+#define MIPS_ASE_MIPSMT 0x00000020 /* CPU supports MIPS MT */
+
+
+#endif /* _ASM_CPU_H */
diff --git a/arch/mips/include/asm/cputime.h b/arch/mips/include/asm/cputime.h
new file mode 100644
index 00000000..c00eacbd
--- /dev/null
+++ b/arch/mips/include/asm/cputime.h
@@ -0,0 +1,6 @@
+#ifndef __MIPS_CPUTIME_H
+#define __MIPS_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __MIPS_CPUTIME_H */
diff --git a/arch/mips/include/asm/current.h b/arch/mips/include/asm/current.h
new file mode 100644
index 00000000..4c51401b
--- /dev/null
+++ b/arch/mips/include/asm/current.h
@@ -0,0 +1 @@
+#include <asm-generic/current.h>
diff --git a/arch/mips/include/asm/debug.h b/arch/mips/include/asm/debug.h
new file mode 100644
index 00000000..1fd5a2b3
--- /dev/null
+++ b/arch/mips/include/asm/debug.h
@@ -0,0 +1,48 @@
+/*
+ * Debug macros for run-time debugging.
+ * Turned on/off with CONFIG_RUNTIME_DEBUG option.
+ *
+ * Copyright (C) 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef _ASM_DEBUG_H
+#define _ASM_DEBUG_H
+
+
+/*
+ * run-time macros for catching spurious errors. Eable CONFIG_RUNTIME_DEBUG in
+ * kernel hacking config menu to use them.
+ *
+ * Use them as run-time debugging aid. NEVER USE THEM AS ERROR HANDLING CODE!!!
+ */
+
+#ifdef CONFIG_RUNTIME_DEBUG
+
+#include <linux/kernel.h>
+
+#define db_assert(x) if (!(x)) { \
+ panic("assertion failed at %s:%d: %s", __FILE__, __LINE__, #x); }
+#define db_warn(x) if (!(x)) { \
+ printk(KERN_WARNING "warning at %s:%d: %s", __FILE__, __LINE__, #x); }
+#define db_verify(x, y) db_assert(x y)
+#define db_verify_warn(x, y) db_warn(x y)
+#define db_run(x) do { x; } while (0)
+
+#else
+
+#define db_assert(x)
+#define db_warn(x)
+#define db_verify(x, y) x
+#define db_verify_warn(x, y) x
+#define db_run(x)
+
+#endif
+
+#endif /* _ASM_DEBUG_H */
diff --git a/arch/mips/include/asm/dec/ecc.h b/arch/mips/include/asm/dec/ecc.h
new file mode 100644
index 00000000..707ffdbc
--- /dev/null
+++ b/arch/mips/include/asm/dec/ecc.h
@@ -0,0 +1,55 @@
+/*
+ * include/asm-mips/dec/ecc.h
+ *
+ * ECC handling logic definitions common to DECstation/DECsystem
+ * 5000/200 (KN02), 5000/240 (KN03), 5000/260 (KN05) and
+ * DECsystem 5900 (KN03), 5900/260 (KN05) systems.
+ *
+ * Copyright (C) 2003 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MIPS_DEC_ECC_H
+#define __ASM_MIPS_DEC_ECC_H
+
+/*
+ * Error Address Register bits.
+ * The register is r/wc -- any write clears it.
+ */
+#define KN0X_EAR_VALID (1<<31) /* error data valid, bus IRQ */
+#define KN0X_EAR_CPU (1<<30) /* CPU/DMA transaction */
+#define KN0X_EAR_WRITE (1<<29) /* write/read transaction */
+#define KN0X_EAR_ECCERR (1<<28) /* ECC/timeout or overrun */
+#define KN0X_EAR_RES_27 (1<<27) /* unused */
+#define KN0X_EAR_ADDRESS (0x7ffffff<<0) /* address involved */
+
+/*
+ * Error Syndrome Register bits.
+ * The register is frozen when EAR.VALID is set, otherwise it records bits
+ * from the last memory read. The register is r/wc -- any write clears it.
+ */
+#define KN0X_ESR_VLDHI (1<<31) /* error data valid hi word */
+#define KN0X_ESR_CHKHI (0x7f<<24) /* check bits read from mem */
+#define KN0X_ESR_SNGHI (1<<23) /* single/double bit error */
+#define KN0X_ESR_SYNHI (0x7f<<16) /* syndrome from ECC logic */
+#define KN0X_ESR_VLDLO (1<<15) /* error data valid lo word */
+#define KN0X_ESR_CHKLO (0x7f<<8) /* check bits read from mem */
+#define KN0X_ESR_SNGLO (1<<7) /* single/double bit error */
+#define KN0X_ESR_SYNLO (0x7f<<0) /* syndrome from ECC logic */
+
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+
+struct pt_regs;
+
+extern void dec_ecc_be_init(void);
+extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id);
+#endif
+
+#endif /* __ASM_MIPS_DEC_ECC_H */
diff --git a/arch/mips/include/asm/dec/interrupts.h b/arch/mips/include/asm/dec/interrupts.h
new file mode 100644
index 00000000..e10d3410
--- /dev/null
+++ b/arch/mips/include/asm/dec/interrupts.h
@@ -0,0 +1,126 @@
+/*
+ * Miscellaneous definitions used to initialise the interrupt vector table
+ * with the machine-specific interrupt routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997 by Paul M. Antoine.
+ * reworked 1998 by Harald Koerfgen.
+ * Copyright (C) 2001, 2002, 2003 Maciej W. Rozycki
+ */
+
+#ifndef __ASM_DEC_INTERRUPTS_H
+#define __ASM_DEC_INTERRUPTS_H
+
+#include <irq.h>
+#include <asm/mipsregs.h>
+
+
+/*
+ * The list of possible system devices which provide an
+ * interrupt. Not all devices exist on a given system.
+ */
+#define DEC_IRQ_CASCADE 0 /* cascade from CSR or I/O ASIC */
+
+/* Ordinary interrupts */
+#define DEC_IRQ_AB_RECV 1 /* ACCESS.bus receive */
+#define DEC_IRQ_AB_XMIT 2 /* ACCESS.bus transmit */
+#define DEC_IRQ_DZ11 3 /* DZ11 (DC7085) serial */
+#define DEC_IRQ_ASC 4 /* ASC (NCR53C94) SCSI */
+#define DEC_IRQ_FLOPPY 5 /* 82077 FDC */
+#define DEC_IRQ_FPU 6 /* R3k FPU */
+#define DEC_IRQ_HALT 7 /* HALT button or from ACCESS.Bus */
+#define DEC_IRQ_ISDN 8 /* Am79C30A ISDN */
+#define DEC_IRQ_LANCE 9 /* LANCE (Am7990) Ethernet */
+#define DEC_IRQ_BUS 10 /* memory, I/O bus read/write errors */
+#define DEC_IRQ_PSU 11 /* power supply unit warning */
+#define DEC_IRQ_RTC 12 /* DS1287 RTC */
+#define DEC_IRQ_SCC0 13 /* SCC (Z85C30) serial #0 */
+#define DEC_IRQ_SCC1 14 /* SCC (Z85C30) serial #1 */
+#define DEC_IRQ_SII 15 /* SII (DC7061) SCSI */
+#define DEC_IRQ_TC0 16 /* TURBOchannel slot #0 */
+#define DEC_IRQ_TC1 17 /* TURBOchannel slot #1 */
+#define DEC_IRQ_TC2 18 /* TURBOchannel slot #2 */
+#define DEC_IRQ_TIMER 19 /* ARC periodic timer */
+#define DEC_IRQ_VIDEO 20 /* framebuffer */
+
+/* I/O ASIC DMA interrupts */
+#define DEC_IRQ_ASC_MERR 21 /* ASC memory read error */
+#define DEC_IRQ_ASC_ERR 22 /* ASC page overrun */
+#define DEC_IRQ_ASC_DMA 23 /* ASC buffer pointer loaded */
+#define DEC_IRQ_FLOPPY_ERR 24 /* FDC error */
+#define DEC_IRQ_ISDN_ERR 25 /* ISDN memory read/overrun error */
+#define DEC_IRQ_ISDN_RXDMA 26 /* ISDN recv buffer pointer loaded */
+#define DEC_IRQ_ISDN_TXDMA 27 /* ISDN xmit buffer pointer loaded */
+#define DEC_IRQ_LANCE_MERR 28 /* LANCE memory read error */
+#define DEC_IRQ_SCC0A_RXERR 29 /* SCC0A (printer) receive overrun */
+#define DEC_IRQ_SCC0A_RXDMA 30 /* SCC0A receive half page */
+#define DEC_IRQ_SCC0A_TXERR 31 /* SCC0A xmit memory read/overrun */
+#define DEC_IRQ_SCC0A_TXDMA 32 /* SCC0A transmit page end */
+#define DEC_IRQ_AB_RXERR 33 /* ACCESS.bus receive overrun */
+#define DEC_IRQ_AB_RXDMA 34 /* ACCESS.bus receive half page */
+#define DEC_IRQ_AB_TXERR 35 /* ACCESS.bus xmit memory read/ovrn */
+#define DEC_IRQ_AB_TXDMA 36 /* ACCESS.bus transmit page end */
+#define DEC_IRQ_SCC1A_RXERR 37 /* SCC1A (modem) receive overrun */
+#define DEC_IRQ_SCC1A_RXDMA 38 /* SCC1A receive half page */
+#define DEC_IRQ_SCC1A_TXERR 39 /* SCC1A xmit memory read/overrun */
+#define DEC_IRQ_SCC1A_TXDMA 40 /* SCC1A transmit page end */
+
+/* TC5 & TC6 are virtual slots for KN02's onboard devices */
+#define DEC_IRQ_TC5 DEC_IRQ_ASC /* virtual PMAZ-AA */
+#define DEC_IRQ_TC6 DEC_IRQ_LANCE /* virtual PMAD-AA */
+
+#define DEC_NR_INTS 41
+
+
+/* Largest of cpu mask_nr tables. */
+#define DEC_MAX_CPU_INTS 6
+/* Largest of asic mask_nr tables. */
+#define DEC_MAX_ASIC_INTS 9
+
+
+/*
+ * CPU interrupt bits common to all systems.
+ */
+#define DEC_CPU_INR_FPU 7 /* R3k FPU */
+#define DEC_CPU_INR_SW1 1 /* software #1 */
+#define DEC_CPU_INR_SW0 0 /* software #0 */
+
+#define DEC_CPU_IRQ_BASE MIPS_CPU_IRQ_BASE /* first IRQ assigned to CPU */
+
+#define DEC_CPU_IRQ_NR(n) ((n) + DEC_CPU_IRQ_BASE)
+#define DEC_CPU_IRQ_MASK(n) (1 << ((n) + CAUSEB_IP))
+#define DEC_CPU_IRQ_ALL (0xff << CAUSEB_IP)
+
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Interrupt table structures to hide differences between systems.
+ */
+typedef union { int i; void *p; } int_ptr;
+extern int dec_interrupt[DEC_NR_INTS];
+extern int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2];
+extern int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2];
+extern int cpu_fpu_mask;
+
+
+/*
+ * Common interrupt routine prototypes for all DECStations
+ */
+extern void kn02_io_int(void);
+extern void kn02xa_io_int(void);
+extern void kn03_io_int(void);
+extern void asic_dma_int(void);
+extern void asic_all_int(void);
+extern void kn02_all_int(void);
+extern void cpu_all_int(void);
+
+extern void dec_intr_unimplemented(void);
+extern void asic_intr_unimplemented(void);
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/mips/include/asm/dec/ioasic.h b/arch/mips/include/asm/dec/ioasic.h
new file mode 100644
index 00000000..98badd6b
--- /dev/null
+++ b/arch/mips/include/asm/dec/ioasic.h
@@ -0,0 +1,38 @@
+/*
+ * include/asm-mips/dec/ioasic.h
+ *
+ * DEC I/O ASIC access operations.
+ *
+ * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __ASM_DEC_IOASIC_H
+#define __ASM_DEC_IOASIC_H
+
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+extern spinlock_t ioasic_ssr_lock;
+
+extern volatile u32 *ioasic_base;
+
+static inline void ioasic_write(unsigned int reg, u32 v)
+{
+ ioasic_base[reg / 4] = v;
+}
+
+static inline u32 ioasic_read(unsigned int reg)
+{
+ return ioasic_base[reg / 4];
+}
+
+extern void init_ioasic_irqs(int base);
+
+extern void dec_ioasic_clocksource_init(void);
+
+#endif /* __ASM_DEC_IOASIC_H */
diff --git a/arch/mips/include/asm/dec/ioasic_addrs.h b/arch/mips/include/asm/dec/ioasic_addrs.h
new file mode 100644
index 00000000..4cbc1f8a
--- /dev/null
+++ b/arch/mips/include/asm/dec/ioasic_addrs.h
@@ -0,0 +1,152 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Definitions for the address map in the JUNKIO Asic
+ *
+ * Created with Information from:
+ *
+ * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual"
+ *
+ * and the Mach Sources
+ *
+ * Copyright (C) 199x the Anonymous
+ * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ */
+
+#ifndef __ASM_MIPS_DEC_IOASIC_ADDRS_H
+#define __ASM_MIPS_DEC_IOASIC_ADDRS_H
+
+#define IOASIC_SLOT_SIZE 0x00040000
+
+/*
+ * Address ranges decoded by the I/O ASIC for onboard devices.
+ */
+#define IOASIC_SYS_ROM (0*IOASIC_SLOT_SIZE) /* system board ROM */
+#define IOASIC_IOCTL (1*IOASIC_SLOT_SIZE) /* I/O ASIC */
+#define IOASIC_ESAR (2*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */
+#define IOASIC_LANCE (3*IOASIC_SLOT_SIZE) /* LANCE Ethernet */
+#define IOASIC_SCC0 (4*IOASIC_SLOT_SIZE) /* SCC #0 */
+#define IOASIC_VDAC_HI (5*IOASIC_SLOT_SIZE) /* VDAC (maxine) */
+#define IOASIC_SCC1 (6*IOASIC_SLOT_SIZE) /* SCC #1 (3min, 3max+) */
+#define IOASIC_VDAC_LO (7*IOASIC_SLOT_SIZE) /* VDAC (maxine) */
+#define IOASIC_TOY (8*IOASIC_SLOT_SIZE) /* RTC */
+#define IOASIC_ISDN (9*IOASIC_SLOT_SIZE) /* ISDN (maxine) */
+#define IOASIC_ERRADDR (9*IOASIC_SLOT_SIZE) /* bus error address (3max+) */
+#define IOASIC_CHKSYN (10*IOASIC_SLOT_SIZE) /* ECC syndrome (3max+) */
+#define IOASIC_ACC_BUS (10*IOASIC_SLOT_SIZE) /* ACCESS.bus (maxine) */
+#define IOASIC_MCR (11*IOASIC_SLOT_SIZE) /* memory control (3max+) */
+#define IOASIC_FLOPPY (11*IOASIC_SLOT_SIZE) /* FDC (maxine) */
+#define IOASIC_SCSI (12*IOASIC_SLOT_SIZE) /* ASC SCSI */
+#define IOASIC_FDC_DMA (13*IOASIC_SLOT_SIZE) /* FDC DMA (maxine) */
+#define IOASIC_SCSI_DMA (14*IOASIC_SLOT_SIZE) /* ??? */
+#define IOASIC_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */
+
+
+/*
+ * Offsets for I/O ASIC registers
+ * (relative to (dec_kn_slot_base + IOASIC_IOCTL)).
+ */
+ /* all systems */
+#define IO_REG_SCSI_DMA_P 0x00 /* SCSI DMA Pointer */
+#define IO_REG_SCSI_DMA_BP 0x10 /* SCSI DMA Buffer Pointer */
+#define IO_REG_LANCE_DMA_P 0x20 /* LANCE DMA Pointer */
+#define IO_REG_SCC0A_T_DMA_P 0x30 /* SCC0A Transmit DMA Pointer */
+#define IO_REG_SCC0A_R_DMA_P 0x40 /* SCC0A Receive DMA Pointer */
+
+ /* except Maxine */
+#define IO_REG_SCC1A_T_DMA_P 0x50 /* SCC1A Transmit DMA Pointer */
+#define IO_REG_SCC1A_R_DMA_P 0x60 /* SCC1A Receive DMA Pointer */
+
+ /* Maxine */
+#define IO_REG_AB_T_DMA_P 0x50 /* ACCESS.bus Transmit DMA Pointer */
+#define IO_REG_AB_R_DMA_P 0x60 /* ACCESS.bus Receive DMA Pointer */
+#define IO_REG_FLOPPY_DMA_P 0x70 /* Floppy DMA Pointer */
+#define IO_REG_ISDN_T_DMA_P 0x80 /* ISDN Transmit DMA Pointer */
+#define IO_REG_ISDN_T_DMA_BP 0x90 /* ISDN Transmit DMA Buffer Pointer */
+#define IO_REG_ISDN_R_DMA_P 0xa0 /* ISDN Receive DMA Pointer */
+#define IO_REG_ISDN_R_DMA_BP 0xb0 /* ISDN Receive DMA Buffer Pointer */
+
+ /* all systems */
+#define IO_REG_DATA_0 0xc0 /* System Data Buffer 0 */
+#define IO_REG_DATA_1 0xd0 /* System Data Buffer 1 */
+#define IO_REG_DATA_2 0xe0 /* System Data Buffer 2 */
+#define IO_REG_DATA_3 0xf0 /* System Data Buffer 3 */
+
+ /* all systems */
+#define IO_REG_SSR 0x100 /* System Support Register */
+#define IO_REG_SIR 0x110 /* System Interrupt Register */
+#define IO_REG_SIMR 0x120 /* System Interrupt Mask Reg. */
+#define IO_REG_SAR 0x130 /* System Address Register */
+
+ /* Maxine */
+#define IO_REG_ISDN_T_DATA 0x140 /* ISDN Xmit Data Register */
+#define IO_REG_ISDN_R_DATA 0x150 /* ISDN Receive Data Register */
+
+ /* all systems */
+#define IO_REG_LANCE_SLOT 0x160 /* LANCE I/O Slot Register */
+#define IO_REG_SCSI_SLOT 0x170 /* SCSI Slot Register */
+#define IO_REG_SCC0A_SLOT 0x180 /* SCC0A DMA Slot Register */
+
+ /* except Maxine */
+#define IO_REG_SCC1A_SLOT 0x190 /* SCC1A DMA Slot Register */
+
+ /* Maxine */
+#define IO_REG_AB_SLOT 0x190 /* ACCESS.bus DMA Slot Register */
+#define IO_REG_FLOPPY_SLOT 0x1a0 /* Floppy Slot Register */
+
+ /* all systems */
+#define IO_REG_SCSI_SCR 0x1b0 /* SCSI Partial-Word DMA Control */
+#define IO_REG_SCSI_SDR0 0x1c0 /* SCSI DMA Partial Word 0 */
+#define IO_REG_SCSI_SDR1 0x1d0 /* SCSI DMA Partial Word 1 */
+#define IO_REG_FCTR 0x1e0 /* Free-Running Counter */
+#define IO_REG_RES_31 0x1f0 /* unused */
+
+
+/*
+ * The upper 16 bits of the System Support Register are a part of the
+ * I/O ASIC's internal DMA engine and thus are common to all I/O ASIC
+ * machines. The exception is the Maxine, which makes use of the
+ * FLOPPY and ISDN bits (otherwise unused) and has a different SCC
+ * wiring.
+ */
+ /* all systems */
+#define IO_SSR_SCC0A_TX_DMA_EN (1<<31) /* SCC0A transmit DMA enable */
+#define IO_SSR_SCC0A_RX_DMA_EN (1<<30) /* SCC0A receive DMA enable */
+#define IO_SSR_RES_27 (1<<27) /* unused */
+#define IO_SSR_RES_26 (1<<26) /* unused */
+#define IO_SSR_RES_25 (1<<25) /* unused */
+#define IO_SSR_RES_24 (1<<24) /* unused */
+#define IO_SSR_RES_23 (1<<23) /* unused */
+#define IO_SSR_SCSI_DMA_DIR (1<<18) /* SCSI DMA direction */
+#define IO_SSR_SCSI_DMA_EN (1<<17) /* SCSI DMA enable */
+#define IO_SSR_LANCE_DMA_EN (1<<16) /* LANCE DMA enable */
+
+ /* except Maxine */
+#define IO_SSR_SCC1A_TX_DMA_EN (1<<29) /* SCC1A transmit DMA enable */
+#define IO_SSR_SCC1A_RX_DMA_EN (1<<28) /* SCC1A receive DMA enable */
+#define IO_SSR_RES_22 (1<<22) /* unused */
+#define IO_SSR_RES_21 (1<<21) /* unused */
+#define IO_SSR_RES_20 (1<<20) /* unused */
+#define IO_SSR_RES_19 (1<<19) /* unused */
+
+ /* Maxine */
+#define IO_SSR_AB_TX_DMA_EN (1<<29) /* ACCESS.bus xmit DMA enable */
+#define IO_SSR_AB_RX_DMA_EN (1<<28) /* ACCESS.bus recv DMA enable */
+#define IO_SSR_FLOPPY_DMA_DIR (1<<22) /* Floppy DMA direction */
+#define IO_SSR_FLOPPY_DMA_EN (1<<21) /* Floppy DMA enable */
+#define IO_SSR_ISDN_TX_DMA_EN (1<<20) /* ISDN transmit DMA enable */
+#define IO_SSR_ISDN_RX_DMA_EN (1<<19) /* ISDN receive DMA enable */
+
+/*
+ * The lower 16 bits are system-specific. Bits 15,11:8 are common and
+ * defined here. The rest is defined in system-specific headers.
+ */
+#define KN0X_IO_SSR_DIAGDN (1<<15) /* diagnostic jumper */
+#define KN0X_IO_SSR_SCC_RST (1<<11) /* ~SCC0,1 (Z85C30) reset */
+#define KN0X_IO_SSR_RTC_RST (1<<10) /* ~RTC (DS1287) reset */
+#define KN0X_IO_SSR_ASC_RST (1<<9) /* ~ASC (NCR53C94) reset */
+#define KN0X_IO_SSR_LANCE_RST (1<<8) /* ~LANCE (Am7990) reset */
+
+#endif /* __ASM_MIPS_DEC_IOASIC_ADDRS_H */
diff --git a/arch/mips/include/asm/dec/ioasic_ints.h b/arch/mips/include/asm/dec/ioasic_ints.h
new file mode 100644
index 00000000..9aaa9869
--- /dev/null
+++ b/arch/mips/include/asm/dec/ioasic_ints.h
@@ -0,0 +1,74 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Definitions for the interrupt related bits in the I/O ASIC
+ * interrupt status register (and the interrupt mask register, of course)
+ *
+ * Created with Information from:
+ *
+ * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual"
+ *
+ * and the Mach Sources
+ *
+ * Copyright (C) 199x the Anonymous
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+
+#ifndef __ASM_DEC_IOASIC_INTS_H
+#define __ASM_DEC_IOASIC_INTS_H
+
+/*
+ * The upper 16 bits are a part of the I/O ASIC's internal DMA engine
+ * and thus are common to all I/O ASIC machines. The exception is
+ * the Maxine, which makes use of the FLOPPY and ISDN bits (otherwise
+ * unused) and has a different SCC wiring.
+ */
+ /* all systems */
+#define IO_INR_SCC0A_TXDMA 31 /* SCC0A transmit page end */
+#define IO_INR_SCC0A_TXERR 30 /* SCC0A transmit memory read error */
+#define IO_INR_SCC0A_RXDMA 29 /* SCC0A receive half page */
+#define IO_INR_SCC0A_RXERR 28 /* SCC0A receive overrun */
+#define IO_INR_ASC_DMA 19 /* ASC buffer pointer loaded */
+#define IO_INR_ASC_ERR 18 /* ASC page overrun */
+#define IO_INR_ASC_MERR 17 /* ASC memory read error */
+#define IO_INR_LANCE_MERR 16 /* LANCE memory read error */
+
+ /* except Maxine */
+#define IO_INR_SCC1A_TXDMA 27 /* SCC1A transmit page end */
+#define IO_INR_SCC1A_TXERR 26 /* SCC1A transmit memory read error */
+#define IO_INR_SCC1A_RXDMA 25 /* SCC1A receive half page */
+#define IO_INR_SCC1A_RXERR 24 /* SCC1A receive overrun */
+#define IO_INR_RES_23 23 /* unused */
+#define IO_INR_RES_22 22 /* unused */
+#define IO_INR_RES_21 21 /* unused */
+#define IO_INR_RES_20 20 /* unused */
+
+ /* Maxine */
+#define IO_INR_AB_TXDMA 27 /* ACCESS.bus transmit page end */
+#define IO_INR_AB_TXERR 26 /* ACCESS.bus xmit memory read error */
+#define IO_INR_AB_RXDMA 25 /* ACCESS.bus receive half page */
+#define IO_INR_AB_RXERR 24 /* ACCESS.bus receive overrun */
+#define IO_INR_FLOPPY_ERR 23 /* FDC error */
+#define IO_INR_ISDN_TXDMA 22 /* ISDN xmit buffer pointer loaded */
+#define IO_INR_ISDN_RXDMA 21 /* ISDN recv buffer pointer loaded */
+#define IO_INR_ISDN_ERR 20 /* ISDN memory read/overrun error */
+
+#define IO_INR_DMA 16 /* first DMA IRQ */
+
+/*
+ * The lower 16 bits are system-specific and thus defined in
+ * system-specific headers.
+ */
+
+
+#define IO_IRQ_BASE 8 /* first IRQ assigned to I/O ASIC */
+#define IO_IRQ_LINES 32 /* number of I/O ASIC interrupts */
+
+#define IO_IRQ_NR(n) ((n) + IO_IRQ_BASE)
+#define IO_IRQ_MASK(n) (1 << (n))
+#define IO_IRQ_ALL 0x0000ffff
+#define IO_IRQ_DMA 0xffff0000
+
+#endif /* __ASM_DEC_IOASIC_INTS_H */
diff --git a/arch/mips/include/asm/dec/kn01.h b/arch/mips/include/asm/dec/kn01.h
new file mode 100644
index 00000000..88d9ffd7
--- /dev/null
+++ b/arch/mips/include/asm/dec/kn01.h
@@ -0,0 +1,89 @@
+/*
+ * Hardware info about DECstation DS2100/3100 systems (otherwise known as
+ * pmin/pmax or KN01).
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
+ * are by courtesy of Chris Fraser.
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
+ */
+#ifndef __ASM_MIPS_DEC_KN01_H
+#define __ASM_MIPS_DEC_KN01_H
+
+#define KN01_SLOT_BASE 0x10000000
+#define KN01_SLOT_SIZE 0x01000000
+
+/*
+ * Address ranges for devices.
+ */
+#define KN01_PMASK (0*KN01_SLOT_SIZE) /* color plane mask */
+#define KN01_PCC (1*KN01_SLOT_SIZE) /* PCC (DC503) cursor */
+#define KN01_VDAC (2*KN01_SLOT_SIZE) /* color map */
+#define KN01_RES_3 (3*KN01_SLOT_SIZE) /* unused */
+#define KN01_RES_4 (4*KN01_SLOT_SIZE) /* unused */
+#define KN01_RES_5 (5*KN01_SLOT_SIZE) /* unused */
+#define KN01_RES_6 (6*KN01_SLOT_SIZE) /* unused */
+#define KN01_ERRADDR (7*KN01_SLOT_SIZE) /* write error address */
+#define KN01_LANCE (8*KN01_SLOT_SIZE) /* LANCE (Am7990) Ethernet */
+#define KN01_LANCE_MEM (9*KN01_SLOT_SIZE) /* LANCE buffer memory */
+#define KN01_SII (10*KN01_SLOT_SIZE) /* SII (DC7061) SCSI */
+#define KN01_SII_MEM (11*KN01_SLOT_SIZE) /* SII buffer memory */
+#define KN01_DZ11 (12*KN01_SLOT_SIZE) /* DZ11 (DC7085) serial */
+#define KN01_RTC (13*KN01_SLOT_SIZE) /* DS1287 RTC (bytes #0) */
+#define KN01_ESAR (13*KN01_SLOT_SIZE) /* MAC address (bytes #1) */
+#define KN01_CSR (14*KN01_SLOT_SIZE) /* system ctrl & status reg */
+#define KN01_SYS_ROM (15*KN01_SLOT_SIZE) /* system board ROM */
+
+
+/*
+ * Frame buffer memory address.
+ */
+#define KN01_VFB_MEM 0x0fc00000
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN01_CPU_INR_BUS 6 /* memory, I/O bus read/write errors */
+#define KN01_CPU_INR_VIDEO 6 /* PCC area detect #2 */
+#define KN01_CPU_INR_RTC 5 /* DS1287 RTC */
+#define KN01_CPU_INR_DZ11 4 /* DZ11 (DC7085) serial */
+#define KN01_CPU_INR_LANCE 3 /* LANCE (Am7990) Ethernet */
+#define KN01_CPU_INR_SII 2 /* SII (DC7061) SCSI */
+
+
+/*
+ * System Control & Status Register bits.
+ */
+#define KN01_CSR_MNFMOD (1<<15) /* MNFMOD manufacturing jumper */
+#define KN01_CSR_STATUS (1<<14) /* self-test result status output */
+#define KN01_CSR_PARDIS (1<<13) /* parity error disable */
+#define KN01_CSR_CRSRTST (1<<12) /* PCC test output */
+#define KN01_CSR_MONO (1<<11) /* mono/color fb SIMM installed */
+#define KN01_CSR_MEMERR (1<<10) /* write timeout error status & ack*/
+#define KN01_CSR_VINT (1<<9) /* PCC area detect #2 status & ack */
+#define KN01_CSR_TXDIS (1<<8) /* DZ11 transmit disable */
+#define KN01_CSR_VBGTRG (1<<2) /* blue DAC voltage over green (r/o) */
+#define KN01_CSR_VRGTRG (1<<1) /* red DAC voltage over green (r/o) */
+#define KN01_CSR_VRGTRB (1<<0) /* red DAC voltage over blue (r/o) */
+#define KN01_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */
+
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+struct pt_regs;
+
+extern u16 cached_kn01_csr;
+
+extern void dec_kn01_be_init(void);
+extern int dec_kn01_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_kn01_be_interrupt(int irq, void *dev_id);
+#endif
+
+#endif /* __ASM_MIPS_DEC_KN01_H */
diff --git a/arch/mips/include/asm/dec/kn02.h b/arch/mips/include/asm/dec/kn02.h
new file mode 100644
index 00000000..93430b5f
--- /dev/null
+++ b/arch/mips/include/asm/dec/kn02.h
@@ -0,0 +1,91 @@
+/*
+ * Hardware info about DECstation 5000/200 systems (otherwise known as
+ * 3max or KN02).
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
+ * are by courtesy of Chris Fraser.
+ * Copyright (C) 2002, 2003, 2005 Maciej W. Rozycki
+ */
+#ifndef __ASM_MIPS_DEC_KN02_H
+#define __ASM_MIPS_DEC_KN02_H
+
+#define KN02_SLOT_BASE 0x1fc00000
+#define KN02_SLOT_SIZE 0x00080000
+
+/*
+ * Address ranges decoded by the "system slot" logic for onboard devices.
+ */
+#define KN02_SYS_ROM (0*KN02_SLOT_SIZE) /* system board ROM */
+#define KN02_RES_1 (1*KN02_SLOT_SIZE) /* unused */
+#define KN02_CHKSYN (2*KN02_SLOT_SIZE) /* ECC syndrome */
+#define KN02_ERRADDR (3*KN02_SLOT_SIZE) /* bus error address */
+#define KN02_DZ11 (4*KN02_SLOT_SIZE) /* DZ11 (DC7085) serial */
+#define KN02_RTC (5*KN02_SLOT_SIZE) /* DS1287 RTC */
+#define KN02_CSR (6*KN02_SLOT_SIZE) /* system ctrl & status reg */
+#define KN02_SYS_ROM_7 (7*KN02_SLOT_SIZE) /* system board ROM (alias) */
+
+
+/*
+ * System Control & Status Register bits.
+ */
+#define KN02_CSR_RES_28 (0xf<<28) /* unused */
+#define KN02_CSR_PSU (1<<27) /* power supply unit warning */
+#define KN02_CSR_NVRAM (1<<26) /* ~NVRAM clear jumper */
+#define KN02_CSR_REFEVEN (1<<25) /* mem refresh bank toggle */
+#define KN02_CSR_NRMOD (1<<24) /* ~NRMOD manufact. jumper */
+#define KN02_CSR_IOINTEN (0xff<<16) /* IRQ mask bits */
+#define KN02_CSR_DIAGCHK (1<<15) /* diagn/norml ECC reads */
+#define KN02_CSR_DIAGGEN (1<<14) /* diagn/norml ECC writes */
+#define KN02_CSR_CORRECT (1<<13) /* ECC correct/check */
+#define KN02_CSR_LEDIAG (1<<12) /* ECC diagn. latch strobe */
+#define KN02_CSR_TXDIS (1<<11) /* DZ11 transmit disable */
+#define KN02_CSR_BNK32M (1<<10) /* 32M/8M stride */
+#define KN02_CSR_DIAGDN (1<<9) /* DIAGDN manufact. jumper */
+#define KN02_CSR_BAUD38 (1<<8) /* DZ11 38/19kbps ext. rate */
+#define KN02_CSR_IOINT (0xff<<0) /* IRQ status bits (r/o) */
+#define KN02_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */
+
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN02_CPU_INR_RES_6 6 /* unused */
+#define KN02_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */
+#define KN02_CPU_INR_RES_4 4 /* unused */
+#define KN02_CPU_INR_RTC 3 /* DS1287 RTC */
+#define KN02_CPU_INR_CASCADE 2 /* CSR cascade */
+
+/*
+ * CSR interrupt bits.
+ */
+#define KN02_CSR_INR_DZ11 7 /* DZ11 (DC7085) serial */
+#define KN02_CSR_INR_LANCE 6 /* LANCE (Am7990) Ethernet */
+#define KN02_CSR_INR_ASC 5 /* ASC (NCR53C94) SCSI */
+#define KN02_CSR_INR_RES_4 4 /* unused */
+#define KN02_CSR_INR_RES_3 3 /* unused */
+#define KN02_CSR_INR_TC2 2 /* TURBOchannel slot #2 */
+#define KN02_CSR_INR_TC1 1 /* TURBOchannel slot #1 */
+#define KN02_CSR_INR_TC0 0 /* TURBOchannel slot #0 */
+
+
+#define KN02_IRQ_BASE 8 /* first IRQ assigned to CSR */
+#define KN02_IRQ_LINES 8 /* number of CSR interrupts */
+
+#define KN02_IRQ_NR(n) ((n) + KN02_IRQ_BASE)
+#define KN02_IRQ_MASK(n) (1 << (n))
+#define KN02_IRQ_ALL 0xff
+
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+extern u32 cached_kn02_csr;
+extern void init_kn02_irqs(int base);
+#endif
+
+#endif /* __ASM_MIPS_DEC_KN02_H */
diff --git a/arch/mips/include/asm/dec/kn02ba.h b/arch/mips/include/asm/dec/kn02ba.h
new file mode 100644
index 00000000..c957a4f1
--- /dev/null
+++ b/arch/mips/include/asm/dec/kn02ba.h
@@ -0,0 +1,67 @@
+/*
+ * include/asm-mips/dec/kn02ba.h
+ *
+ * DECstation 5000/1xx (3min or KN02-BA) definitions.
+ *
+ * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MIPS_DEC_KN02BA_H
+#define __ASM_MIPS_DEC_KN02BA_H
+
+#include <asm/dec/kn02xa.h> /* For common definitions. */
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN02BA_CPU_INR_HALT 6 /* HALT button */
+#define KN02BA_CPU_INR_CASCADE 5 /* I/O ASIC cascade */
+#define KN02BA_CPU_INR_TC2 4 /* TURBOchannel slot #2 */
+#define KN02BA_CPU_INR_TC1 3 /* TURBOchannel slot #1 */
+#define KN02BA_CPU_INR_TC0 2 /* TURBOchannel slot #0 */
+
+/*
+ * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits.
+ */
+#define KN02BA_IO_INR_RES_15 15 /* unused */
+#define KN02BA_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */
+#define KN02BA_IO_INR_RES_13 13 /* unused */
+#define KN02BA_IO_INR_BUS 12 /* memory, I/O bus read/write errors */
+#define KN02BA_IO_INR_RES_11 11 /* unused */
+#define KN02BA_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */
+#define KN02BA_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */
+#define KN02BA_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */
+#define KN02BA_IO_INR_SCC1 7 /* SCC (Z85C30) serial #1 */
+#define KN02BA_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */
+#define KN02BA_IO_INR_RTC 5 /* DS1287 RTC */
+#define KN02BA_IO_INR_PSU 4 /* power supply unit warning */
+#define KN02BA_IO_INR_RES_3 3 /* unused */
+#define KN02BA_IO_INR_ASC_DATA 2 /* SCSI data ready (for PIO) */
+#define KN02BA_IO_INR_PBNC 1 /* ~HALT button debouncer */
+#define KN02BA_IO_INR_PBNO 0 /* HALT button debouncer */
+
+
+/*
+ * Memory Error Register bits.
+ */
+#define KN02BA_MER_RES_27 (1<<27) /* unused */
+
+/*
+ * Memory Size Register bits.
+ */
+#define KN02BA_MSR_RES_17 (0x3ff<<17) /* unused */
+
+/*
+ * I/O ASIC System Support Register bits.
+ */
+#define KN02BA_IO_SSR_TXDIS1 (1<<14) /* SCC1 transmit disable */
+#define KN02BA_IO_SSR_TXDIS0 (1<<13) /* SCC0 transmit disable */
+#define KN02BA_IO_SSR_RES_12 (1<<12) /* unused */
+
+#define KN02BA_IO_SSR_LEDS (0xff<<0) /* ~diagnostic LEDs */
+
+#endif /* __ASM_MIPS_DEC_KN02BA_H */
diff --git a/arch/mips/include/asm/dec/kn02ca.h b/arch/mips/include/asm/dec/kn02ca.h
new file mode 100644
index 00000000..92c0fe25
--- /dev/null
+++ b/arch/mips/include/asm/dec/kn02ca.h
@@ -0,0 +1,79 @@
+/*
+ * include/asm-mips/dec/kn02ca.h
+ *
+ * Personal DECstation 5000/xx (Maxine or KN02-CA) definitions.
+ *
+ * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MIPS_DEC_KN02CA_H
+#define __ASM_MIPS_DEC_KN02CA_H
+
+#include <asm/dec/kn02xa.h> /* For common definitions. */
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN02CA_CPU_INR_HALT 6 /* HALT from ACCESS.Bus */
+#define KN02CA_CPU_INR_CASCADE 5 /* I/O ASIC cascade */
+#define KN02CA_CPU_INR_BUS 4 /* memory, I/O bus read/write errors */
+#define KN02CA_CPU_INR_RTC 3 /* DS1287 RTC */
+#define KN02CA_CPU_INR_TIMER 2 /* ARC periodic timer */
+
+/*
+ * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits.
+ */
+#define KN02CA_IO_INR_FLOPPY 15 /* 82077 FDC */
+#define KN02CA_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */
+#define KN02CA_IO_INR_POWERON 13 /* (*) ACCESS.Bus/power-on reset */
+#define KN02CA_IO_INR_TC0 12 /* TURBOchannel slot #0 */
+#define KN02CA_IO_INR_TIMER 12 /* ARC periodic timer (?) */
+#define KN02CA_IO_INR_ISDN 11 /* Am79C30A ISDN */
+#define KN02CA_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */
+#define KN02CA_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */
+#define KN02CA_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */
+#define KN02CA_IO_INR_HDFLOPPY 7 /* (*) HD (1.44MB) floppy status */
+#define KN02CA_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */
+#define KN02CA_IO_INR_TC1 5 /* TURBOchannel slot #1 */
+#define KN02CA_IO_INR_XDFLOPPY 4 /* (*) XD (2.88MB) floppy status */
+#define KN02CA_IO_INR_VIDEO 3 /* framebuffer */
+#define KN02CA_IO_INR_XVIDEO 2 /* ~framebuffer */
+#define KN02CA_IO_INR_AB_XMIT 1 /* ACCESS.bus transmit */
+#define KN02CA_IO_INR_AB_RECV 0 /* ACCESS.bus receive */
+
+
+/*
+ * Memory Error Register bits.
+ */
+#define KN02CA_MER_INTR (1<<27) /* ARC IRQ status & ack */
+
+/*
+ * Memory Size Register bits.
+ */
+#define KN02CA_MSR_INTREN (1<<26) /* ARC periodic IRQ enable */
+#define KN02CA_MSR_MS10EN (1<<25) /* 10/1ms IRQ period select */
+#define KN02CA_MSR_PFORCE (0xf<<21) /* byte lane error force */
+#define KN02CA_MSR_MABEN (1<<20) /* A side VFB address enable */
+#define KN02CA_MSR_LASTBANK (0x7<<17) /* onboard RAM bank # */
+
+/*
+ * I/O ASIC System Support Register bits.
+ */
+#define KN03CA_IO_SSR_RES_14 (1<<14) /* unused */
+#define KN03CA_IO_SSR_RES_13 (1<<13) /* unused */
+#define KN03CA_IO_SSR_ISDN_RST (1<<12) /* ~ISDN (Am79C30A) reset */
+
+#define KN03CA_IO_SSR_FLOPPY_RST (1<<7) /* ~FDC (82077) reset */
+#define KN03CA_IO_SSR_VIDEO_RST (1<<6) /* ~framebuffer reset */
+#define KN03CA_IO_SSR_AB_RST (1<<5) /* ACCESS.bus reset */
+#define KN03CA_IO_SSR_RES_4 (1<<4) /* unused */
+#define KN03CA_IO_SSR_RES_3 (1<<4) /* unused */
+#define KN03CA_IO_SSR_RES_2 (1<<2) /* unused */
+#define KN03CA_IO_SSR_RES_1 (1<<1) /* unused */
+#define KN03CA_IO_SSR_LED (1<<0) /* power LED */
+
+#endif /* __ASM_MIPS_DEC_KN02CA_H */
diff --git a/arch/mips/include/asm/dec/kn02xa.h b/arch/mips/include/asm/dec/kn02xa.h
new file mode 100644
index 00000000..b56b4577
--- /dev/null
+++ b/arch/mips/include/asm/dec/kn02xa.h
@@ -0,0 +1,84 @@
+/*
+ * Hardware info common to DECstation 5000/1xx systems (otherwise
+ * known as 3min or kn02ba) and Personal DECstations 5000/xx ones
+ * (otherwise known as maxine or kn02ca).
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
+ * are by courtesy of Chris Fraser.
+ * Copyright (C) 2000, 2002, 2003, 2005 Maciej W. Rozycki
+ *
+ * These are addresses which have to be known early in the boot process.
+ * For other addresses refer to tc.h, ioasic_addrs.h and friends.
+ */
+#ifndef __ASM_MIPS_DEC_KN02XA_H
+#define __ASM_MIPS_DEC_KN02XA_H
+
+#include <asm/dec/ioasic_addrs.h>
+
+#define KN02XA_SLOT_BASE 0x1c000000
+
+/*
+ * Memory control ASIC registers.
+ */
+#define KN02XA_MER 0x0c400000 /* memory error register */
+#define KN02XA_MSR 0x0c800000 /* memory size register */
+
+/*
+ * CPU control ASIC registers.
+ */
+#define KN02XA_MEM_CONF 0x0e000000 /* write timeout config */
+#define KN02XA_EAR 0x0e000004 /* error address register */
+#define KN02XA_BOOT0 0x0e000008 /* boot 0 register */
+#define KN02XA_MEM_INTR 0x0e00000c /* write err IRQ stat & ack */
+
+/*
+ * Memory Error Register bits, common definitions.
+ * The rest is defined in system-specific headers.
+ */
+#define KN02XA_MER_RES_28 (0xf<<28) /* unused */
+#define KN02XA_MER_RES_17 (0x3ff<<17) /* unused */
+#define KN02XA_MER_PAGERR (1<<16) /* 2k page boundary error */
+#define KN02XA_MER_TRANSERR (1<<15) /* transfer length error */
+#define KN02XA_MER_PARDIS (1<<14) /* parity error disable */
+#define KN02XA_MER_SIZE (1<<13) /* r/o mirror of MSR_SIZE */
+#define KN02XA_MER_RES_12 (1<<12) /* unused */
+#define KN02XA_MER_BYTERR (0xf<<8) /* byte lane error bitmask: */
+#define KN02XA_MER_BYTERR_3 (0x8<<8) /* byte lane #3 */
+#define KN02XA_MER_BYTERR_2 (0x4<<8) /* byte lane #2 */
+#define KN02XA_MER_BYTERR_1 (0x2<<8) /* byte lane #1 */
+#define KN02XA_MER_BYTERR_0 (0x1<<8) /* byte lane #0 */
+#define KN02XA_MER_RES_0 (0xff<<0) /* unused */
+
+/*
+ * Memory Size Register bits, common definitions.
+ * The rest is defined in system-specific headers.
+ */
+#define KN02XA_MSR_RES_27 (0x1f<<27) /* unused */
+#define KN02XA_MSR_RES_14 (0x7<<14) /* unused */
+#define KN02XA_MSR_SIZE (1<<13) /* 16M/4M stride */
+#define KN02XA_MSR_RES_0 (0x1fff<<0) /* unused */
+
+/*
+ * Error Address Register bits.
+ */
+#define KN02XA_EAR_RES_29 (0x7<<29) /* unused */
+#define KN02XA_EAR_ADDRESS (0x7ffffff<<2) /* address involved */
+#define KN02XA_EAR_RES_0 (0x3<<0) /* unused */
+
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+
+struct pt_regs;
+
+extern void dec_kn02xa_be_init(void);
+extern int dec_kn02xa_be_handler(struct pt_regs *regs, int is_fixup);
+extern irqreturn_t dec_kn02xa_be_interrupt(int irq, void *dev_id);
+#endif
+
+#endif /* __ASM_MIPS_DEC_KN02XA_H */
diff --git a/arch/mips/include/asm/dec/kn03.h b/arch/mips/include/asm/dec/kn03.h
new file mode 100644
index 00000000..edede923
--- /dev/null
+++ b/arch/mips/include/asm/dec/kn03.h
@@ -0,0 +1,74 @@
+/*
+ * Hardware info about DECstation 5000/2x0 systems (otherwise known as
+ * 3max+) and DECsystem 5900 systems (otherwise known as bigmax) which
+ * differ mechanically but are otherwise identical (both are known as
+ * KN03).
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995,1996 by Paul M. Antoine, some code and definitions
+ * are by courtesy of Chris Fraser.
+ * Copyright (C) 2000, 2002, 2003, 2005 Maciej W. Rozycki
+ */
+#ifndef __ASM_MIPS_DEC_KN03_H
+#define __ASM_MIPS_DEC_KN03_H
+
+#include <asm/dec/ecc.h>
+#include <asm/dec/ioasic_addrs.h>
+
+#define KN03_SLOT_BASE 0x1f800000
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN03_CPU_INR_HALT 6 /* HALT button */
+#define KN03_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */
+#define KN03_CPU_INR_RES_4 4 /* unused */
+#define KN03_CPU_INR_RTC 3 /* DS1287 RTC */
+#define KN03_CPU_INR_CASCADE 2 /* I/O ASIC cascade */
+
+/*
+ * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits.
+ */
+#define KN03_IO_INR_3MAXP 15 /* (*) 3max+/bigmax ID */
+#define KN03_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */
+#define KN03_IO_INR_TC2 13 /* TURBOchannel slot #2 */
+#define KN03_IO_INR_TC1 12 /* TURBOchannel slot #1 */
+#define KN03_IO_INR_TC0 11 /* TURBOchannel slot #0 */
+#define KN03_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */
+#define KN03_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */
+#define KN03_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */
+#define KN03_IO_INR_SCC1 7 /* SCC (Z85C30) serial #1 */
+#define KN03_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */
+#define KN03_IO_INR_RTC 5 /* DS1287 RTC */
+#define KN03_IO_INR_PSU 4 /* power supply unit warning */
+#define KN03_IO_INR_RES_3 3 /* unused */
+#define KN03_IO_INR_ASC_DATA 2 /* SCSI data ready (for PIO) */
+#define KN03_IO_INR_PBNC 1 /* ~HALT button debouncer */
+#define KN03_IO_INR_PBNO 0 /* HALT button debouncer */
+
+
+/*
+ * Memory Control Register bits.
+ */
+#define KN03_MCR_RES_16 (0xffff<<16) /* unused */
+#define KN03_MCR_DIAGCHK (1<<15) /* diagn/norml ECC reads */
+#define KN03_MCR_DIAGGEN (1<<14) /* diagn/norml ECC writes */
+#define KN03_MCR_CORRECT (1<<13) /* ECC correct/check */
+#define KN03_MCR_RES_11 (0x3<<12) /* unused */
+#define KN03_MCR_BNK32M (1<<10) /* 32M/8M stride */
+#define KN03_MCR_RES_7 (0x7<<7) /* unused */
+#define KN03_MCR_CHECK (0x7f<<0) /* diagnostic check bits */
+
+/*
+ * I/O ASIC System Support Register bits.
+ */
+#define KN03_IO_SSR_TXDIS1 (1<<14) /* SCC1 transmit disable */
+#define KN03_IO_SSR_TXDIS0 (1<<13) /* SCC0 transmit disable */
+#define KN03_IO_SSR_RES_12 (1<<12) /* unused */
+
+#define KN03_IO_SSR_LEDS (0xff<<0) /* ~diagnostic LEDs */
+
+#endif /* __ASM_MIPS_DEC_KN03_H */
diff --git a/arch/mips/include/asm/dec/kn05.h b/arch/mips/include/asm/dec/kn05.h
new file mode 100644
index 00000000..56d22dc8
--- /dev/null
+++ b/arch/mips/include/asm/dec/kn05.h
@@ -0,0 +1,76 @@
+/*
+ * include/asm-mips/dec/kn05.h
+ *
+ * DECstation/DECsystem 5000/260 (4max+ or KN05), 5000/150 (4min
+ * or KN04-BA), Personal DECstation/DECsystem 5000/50 (4maxine or
+ * KN04-CA) and DECsystem 5900/260 (KN05) R4k CPU card MB ASIC
+ * definitions.
+ *
+ * Copyright (C) 2002, 2003, 2005, 2008 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * WARNING! All this information is pure guesswork based on the
+ * ROM. It is provided here in hope it will give someone some
+ * food for thought. No documentation for the KN05 nor the KN04
+ * module has been located so far.
+ */
+#ifndef __ASM_MIPS_DEC_KN05_H
+#define __ASM_MIPS_DEC_KN05_H
+
+#include <asm/dec/ioasic_addrs.h>
+
+/*
+ * The oncard MB (Memory Buffer) ASIC provides an additional address
+ * decoder. Certain address ranges within the "high" 16 slots are
+ * passed to the I/O ASIC's decoder like with the KN03 or KN02-BA/CA.
+ * Others are handled locally. "Low" slots are always passed.
+ */
+#define KN4K_SLOT_BASE 0x1fc00000
+
+#define KN4K_MB_ROM (0*IOASIC_SLOT_SIZE) /* KN05/KN04 card ROM */
+#define KN4K_IOCTL (1*IOASIC_SLOT_SIZE) /* I/O ASIC */
+#define KN4K_ESAR (2*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */
+#define KN4K_LANCE (3*IOASIC_SLOT_SIZE) /* LANCE Ethernet */
+#define KN4K_MB_INT (4*IOASIC_SLOT_SIZE) /* MB interrupt register */
+#define KN4K_MB_EA (5*IOASIC_SLOT_SIZE) /* MB error address? */
+#define KN4K_MB_EC (6*IOASIC_SLOT_SIZE) /* MB error ??? */
+#define KN4K_MB_CSR (7*IOASIC_SLOT_SIZE) /* MB control & status */
+#define KN4K_RES_08 (8*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_09 (9*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_10 (10*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_11 (11*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_SCSI (12*IOASIC_SLOT_SIZE) /* ASC SCSI */
+#define KN4K_RES_13 (13*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_14 (14*IOASIC_SLOT_SIZE) /* unused? */
+#define KN4K_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */
+
+/*
+ * Bits for the MB interrupt register.
+ * The register appears read-only.
+ */
+#define KN4K_MB_INT_TC (1<<0) /* TURBOchannel? */
+#define KN4K_MB_INT_RTC (1<<1) /* RTC? */
+#define KN4K_MB_INT_MT (1<<3) /* I/O ASIC cascade */
+
+/*
+ * Bits for the MB control & status register.
+ * Set to 0x00bf8001 for KN05 and to 0x003f8000 for KN04 by the firmware.
+ */
+#define KN4K_MB_CSR_PF (1<<0) /* PreFetching enable? */
+#define KN4K_MB_CSR_F (1<<1) /* ??? */
+#define KN4K_MB_CSR_ECC (0xff<<2) /* ??? */
+#define KN4K_MB_CSR_OD (1<<10) /* ??? */
+#define KN4K_MB_CSR_CP (1<<11) /* ??? */
+#define KN4K_MB_CSR_UNC (1<<12) /* ??? */
+#define KN4K_MB_CSR_IM (1<<13) /* ??? */
+#define KN4K_MB_CSR_NC (1<<14) /* ??? */
+#define KN4K_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */
+#define KN4K_MB_CSR_MSK (0x1f<<16) /* CPU Int[4:0] mask */
+#define KN4K_MB_CSR_FW (1<<21) /* ??? */
+#define KN4K_MB_CSR_W (1<<31) /* ??? */
+
+#endif /* __ASM_MIPS_DEC_KN05_H */
diff --git a/arch/mips/include/asm/dec/kn230.h b/arch/mips/include/asm/dec/kn230.h
new file mode 100644
index 00000000..ff1bf17d
--- /dev/null
+++ b/arch/mips/include/asm/dec/kn230.h
@@ -0,0 +1,26 @@
+/*
+ * include/asm-mips/dec/kn230.h
+ *
+ * DECsystem 5100 (MIPSmate or KN230) definitions.
+ *
+ * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MIPS_DEC_KN230_H
+#define __ASM_MIPS_DEC_KN230_H
+
+/*
+ * CPU interrupt bits.
+ */
+#define KN230_CPU_INR_HALT 6 /* HALT button */
+#define KN230_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */
+#define KN230_CPU_INR_RTC 4 /* DS1287 RTC */
+#define KN230_CPU_INR_SII 3 /* SII (DC7061) SCSI */
+#define KN230_CPU_INR_LANCE 3 /* LANCE (Am7990) Ethernet */
+#define KN230_CPU_INR_DZ11 2 /* DZ11 (DC7085) serial */
+
+#endif /* __ASM_MIPS_DEC_KN230_H */
diff --git a/arch/mips/include/asm/dec/machtype.h b/arch/mips/include/asm/dec/machtype.h
new file mode 100644
index 00000000..a6ecdebc
--- /dev/null
+++ b/arch/mips/include/asm/dec/machtype.h
@@ -0,0 +1,27 @@
+/*
+ * Various machine type macros
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1998, 2000 Harald Koerfgen
+ */
+
+#ifndef __ASM_DEC_MACHTYPE_H
+#define __ASM_DEC_MACHTYPE_H
+
+#include <asm/bootinfo.h>
+
+#define TURBOCHANNEL (mips_machtype == MACH_DS5000_200 || \
+ mips_machtype == MACH_DS5000_1XX || \
+ mips_machtype == MACH_DS5000_XX || \
+ mips_machtype == MACH_DS5000_2X0 || \
+ mips_machtype == MACH_DS5900)
+
+#define IOASIC (mips_machtype == MACH_DS5000_1XX || \
+ mips_machtype == MACH_DS5000_XX || \
+ mips_machtype == MACH_DS5000_2X0 || \
+ mips_machtype == MACH_DS5900)
+
+#endif
diff --git a/arch/mips/include/asm/dec/prom.h b/arch/mips/include/asm/dec/prom.h
new file mode 100644
index 00000000..c0ead631
--- /dev/null
+++ b/arch/mips/include/asm/dec/prom.h
@@ -0,0 +1,174 @@
+/*
+ * include/asm-mips/dec/prom.h
+ *
+ * DECstation PROM interface.
+ *
+ * Copyright (C) 2002 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Based on arch/mips/dec/prom/prom.h by the Anonymous.
+ */
+#ifndef _ASM_DEC_PROM_H
+#define _ASM_DEC_PROM_H
+
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+
+/*
+ * PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's.
+ * Many of these will work for MIPSen as well!
+ */
+#define VEC_RESET (u64 *)CKSEG1ADDR(0x1fc00000)
+ /* Prom base address */
+
+#define PMAX_PROM_ENTRY(x) (VEC_RESET + (x)) /* Prom jump table */
+
+#define PMAX_PROM_HALT PMAX_PROM_ENTRY(2) /* valid on MIPSen */
+#define PMAX_PROM_AUTOBOOT PMAX_PROM_ENTRY(5) /* valid on MIPSen */
+#define PMAX_PROM_OPEN PMAX_PROM_ENTRY(6)
+#define PMAX_PROM_READ PMAX_PROM_ENTRY(7)
+#define PMAX_PROM_CLOSE PMAX_PROM_ENTRY(10)
+#define PMAX_PROM_LSEEK PMAX_PROM_ENTRY(11)
+#define PMAX_PROM_GETCHAR PMAX_PROM_ENTRY(12)
+#define PMAX_PROM_PUTCHAR PMAX_PROM_ENTRY(13) /* 12 on MIPSen */
+#define PMAX_PROM_GETS PMAX_PROM_ENTRY(15)
+#define PMAX_PROM_PRINTF PMAX_PROM_ENTRY(17)
+#define PMAX_PROM_GETENV PMAX_PROM_ENTRY(33) /* valid on MIPSen */
+
+
+/*
+ * Magic number indicating REX PROM available on DECstation. Found in
+ * register a2 on transfer of control to program from PROM.
+ */
+#define REX_PROM_MAGIC 0x30464354
+
+#ifdef CONFIG_64BIT
+
+#define prom_is_rex(magic) 1 /* KN04 and KN05 are REX PROMs. */
+
+#else /* !CONFIG_64BIT */
+
+#define prom_is_rex(magic) ((magic) == REX_PROM_MAGIC)
+
+#endif /* !CONFIG_64BIT */
+
+
+/*
+ * 3MIN/MAXINE PROM entry points for DS5000/1xx's, DS5000/xx's and
+ * DS5000/2x0.
+ */
+#define REX_PROM_GETBITMAP 0x84/4 /* get mem bitmap */
+#define REX_PROM_GETCHAR 0x24/4 /* getch() */
+#define REX_PROM_GETENV 0x64/4 /* get env. variable */
+#define REX_PROM_GETSYSID 0x80/4 /* get system id */
+#define REX_PROM_GETTCINFO 0xa4/4
+#define REX_PROM_PRINTF 0x30/4 /* printf() */
+#define REX_PROM_SLOTADDR 0x6c/4 /* slotaddr */
+#define REX_PROM_BOOTINIT 0x54/4 /* open() */
+#define REX_PROM_BOOTREAD 0x58/4 /* read() */
+#define REX_PROM_CLEARCACHE 0x7c/4
+
+
+/*
+ * Used by rex_getbitmap().
+ */
+typedef struct {
+ int pagesize;
+ unsigned char bitmap[0];
+} memmap;
+
+
+/*
+ * Function pointers as read from a PROM's callback vector.
+ */
+extern int (*__rex_bootinit)(void);
+extern int (*__rex_bootread)(void);
+extern int (*__rex_getbitmap)(memmap *);
+extern unsigned long *(*__rex_slot_address)(int);
+extern void *(*__rex_gettcinfo)(void);
+extern int (*__rex_getsysid)(void);
+extern void (*__rex_clear_cache)(void);
+
+extern int (*__prom_getchar)(void);
+extern char *(*__prom_getenv)(char *);
+extern int (*__prom_printf)(char *, ...);
+
+extern int (*__pmax_open)(char*, int);
+extern int (*__pmax_lseek)(int, long, int);
+extern int (*__pmax_read)(int, void *, int);
+extern int (*__pmax_close)(int);
+
+
+#ifdef CONFIG_64BIT
+
+/*
+ * On MIPS64 we have to call PROM functions via a helper
+ * dispatcher to accommodate ABI incompatibilities.
+ */
+#define __DEC_PROM_O32(fun, arg) fun arg __asm__(#fun); \
+ __asm__(#fun " = call_o32")
+
+int __DEC_PROM_O32(_rex_bootinit, (int (*)(void)));
+int __DEC_PROM_O32(_rex_bootread, (int (*)(void)));
+int __DEC_PROM_O32(_rex_getbitmap, (int (*)(memmap *), memmap *));
+unsigned long *__DEC_PROM_O32(_rex_slot_address,
+ (unsigned long *(*)(int), int));
+void *__DEC_PROM_O32(_rex_gettcinfo, (void *(*)(void)));
+int __DEC_PROM_O32(_rex_getsysid, (int (*)(void)));
+void __DEC_PROM_O32(_rex_clear_cache, (void (*)(void)));
+
+int __DEC_PROM_O32(_prom_getchar, (int (*)(void)));
+char *__DEC_PROM_O32(_prom_getenv, (char *(*)(char *), char *));
+int __DEC_PROM_O32(_prom_printf, (int (*)(char *, ...), char *, ...));
+
+
+#define rex_bootinit() _rex_bootinit(__rex_bootinit)
+#define rex_bootread() _rex_bootread(__rex_bootread)
+#define rex_getbitmap(x) _rex_getbitmap(__rex_getbitmap, x)
+#define rex_slot_address(x) _rex_slot_address(__rex_slot_address, x)
+#define rex_gettcinfo() _rex_gettcinfo(__rex_gettcinfo)
+#define rex_getsysid() _rex_getsysid(__rex_getsysid)
+#define rex_clear_cache() _rex_clear_cache(__rex_clear_cache)
+
+#define prom_getchar() _prom_getchar(__prom_getchar)
+#define prom_getenv(x) _prom_getenv(__prom_getenv, x)
+#define prom_printf(x...) _prom_printf(__prom_printf, x)
+
+#else /* !CONFIG_64BIT */
+
+/*
+ * On plain MIPS we just call PROM functions directly.
+ */
+#define rex_bootinit __rex_bootinit
+#define rex_bootread __rex_bootread
+#define rex_getbitmap __rex_getbitmap
+#define rex_slot_address __rex_slot_address
+#define rex_gettcinfo __rex_gettcinfo
+#define rex_getsysid __rex_getsysid
+#define rex_clear_cache __rex_clear_cache
+
+#define prom_getchar __prom_getchar
+#define prom_getenv __prom_getenv
+#define prom_printf __prom_printf
+
+#define pmax_open __pmax_open
+#define pmax_lseek __pmax_lseek
+#define pmax_read __pmax_read
+#define pmax_close __pmax_close
+
+#endif /* !CONFIG_64BIT */
+
+
+extern void prom_meminit(u32);
+extern void prom_identify_arch(u32);
+extern void prom_init_cmdline(s32, s32 *, u32);
+
+extern void register_prom_console(void);
+extern void unregister_prom_console(void);
+
+#endif /* _ASM_DEC_PROM_H */
diff --git a/arch/mips/include/asm/dec/system.h b/arch/mips/include/asm/dec/system.h
new file mode 100644
index 00000000..b2afaccd
--- /dev/null
+++ b/arch/mips/include/asm/dec/system.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-mips/dec/system.h
+ *
+ * Generic DECstation/DECsystem bits.
+ *
+ * Copyright (C) 2005, 2006 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_DEC_SYSTEM_H
+#define __ASM_DEC_SYSTEM_H
+
+extern unsigned long dec_kn_slot_base, dec_kn_slot_size;
+extern int dec_tc_bus;
+
+#endif /* __ASM_DEC_SYSTEM_H */
diff --git a/arch/mips/include/asm/delay.h b/arch/mips/include/asm/delay.h
new file mode 100644
index 00000000..e7cd7827
--- /dev/null
+++ b/arch/mips/include/asm/delay.h
@@ -0,0 +1,32 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 by Waldorf Electronics
+ * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
+ */
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+#include <linux/param.h>
+
+extern void __delay(unsigned int loops);
+extern void __ndelay(unsigned int ns);
+extern void __udelay(unsigned int us);
+
+#define ndelay(ns) __ndelay(ns)
+#define udelay(us) __udelay(us)
+
+/* make sure "usecs *= ..." in udelay do not overflow. */
+#if HZ >= 1000
+#define MAX_UDELAY_MS 1
+#elif HZ <= 200
+#define MAX_UDELAY_MS 5
+#else
+#define MAX_UDELAY_MS (1000 / HZ)
+#endif
+
+#endif /* _ASM_DELAY_H */
diff --git a/arch/mips/include/asm/device.h b/arch/mips/include/asm/device.h
new file mode 100644
index 00000000..c94fafba
--- /dev/null
+++ b/arch/mips/include/asm/device.h
@@ -0,0 +1,19 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#ifndef _ASM_MIPS_DEVICE_H
+#define _ASM_MIPS_DEVICE_H
+
+struct dma_map_ops;
+
+struct dev_archdata {
+ /* DMA operations on that device */
+ struct dma_map_ops *dma_ops;
+};
+
+struct pdev_archdata {
+};
+
+#endif /* _ASM_MIPS_DEVICE_H*/
diff --git a/arch/mips/include/asm/div64.h b/arch/mips/include/asm/div64.h
new file mode 100644
index 00000000..dc5ea573
--- /dev/null
+++ b/arch/mips/include/asm/div64.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2000, 2004 Maciej W. Rozycki
+ * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_DIV64_H
+#define __ASM_DIV64_H
+
+#include <asm-generic/div64.h>
+
+#if BITS_PER_LONG == 64
+
+#include <linux/types.h>
+
+/*
+ * No traps on overflows for any of these...
+ */
+
+#define __div64_32(n, base) \
+({ \
+ unsigned long __cf, __tmp, __tmp2, __i; \
+ unsigned long __quot32, __mod32; \
+ unsigned long __high, __low; \
+ unsigned long long __n; \
+ \
+ __high = *__n >> 32; \
+ __low = __n; \
+ __asm__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set noreorder \n" \
+ " move %2, $0 \n" \
+ " move %3, $0 \n" \
+ " b 1f \n" \
+ " li %4, 0x21 \n" \
+ "0: \n" \
+ " sll $1, %0, 0x1 \n" \
+ " srl %3, %0, 0x1f \n" \
+ " or %0, $1, %5 \n" \
+ " sll %1, %1, 0x1 \n" \
+ " sll %2, %2, 0x1 \n" \
+ "1: \n" \
+ " bnez %3, 2f \n" \
+ " sltu %5, %0, %z6 \n" \
+ " bnez %5, 3f \n" \
+ "2: \n" \
+ " addiu %4, %4, -1 \n" \
+ " subu %0, %0, %z6 \n" \
+ " addiu %2, %2, 1 \n" \
+ "3: \n" \
+ " bnez %4, 0b\n\t" \
+ " srl %5, %1, 0x1f\n\t" \
+ " .set pop" \
+ : "=&r" (__mod32), "=&r" (__tmp), \
+ "=&r" (__quot32), "=&r" (__cf), \
+ "=&r" (__i), "=&r" (__tmp2) \
+ : "Jr" (base), "0" (__high), "1" (__low)); \
+ \
+ (__n) = __quot32; \
+ __mod32; \
+})
+
+#endif /* BITS_PER_LONG == 64 */
+
+#endif /* __ASM_DIV64_H */
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
new file mode 100644
index 00000000..7aa37ddf
--- /dev/null
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -0,0 +1,90 @@
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
+
+#include <asm/scatterlist.h>
+#include <asm/cache.h>
+#include <asm-generic/dma-coherent.h>
+
+#ifndef CONFIG_SGI_IP27 /* Kludge to fix 2.6.39 build for IP27 */
+#include <dma-coherence.h>
+#endif
+
+extern struct dma_map_ops *mips_dma_map_ops;
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+{
+ if (dev && dev->archdata.dma_ops)
+ return dev->archdata.dma_ops;
+ else
+ return mips_dma_map_ops;
+}
+
+static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
+{
+ if (!dev->dma_mask)
+ return 0;
+
+ return addr + size <= *dev->dma_mask;
+}
+
+static inline void dma_mark_clean(void *addr, size_t size) {}
+
+#include <asm-generic/dma-mapping-common.h>
+
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ return ops->dma_supported(dev, mask);
+}
+
+static inline int dma_mapping_error(struct device *dev, u64 mask)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ return ops->mapping_error(dev, mask);
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+ if(!dev->dma_mask || !dma_supported(dev, mask))
+ return -EIO;
+
+ *dev->dma_mask = mask;
+
+ return 0;
+}
+
+extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction);
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ void *ret;
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
+ ret = ops->alloc_coherent(dev, size, dma_handle, gfp);
+
+ debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
+
+ return ret;
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
+ ops->free_coherent(dev, size, vaddr, dma_handle);
+
+ debug_dma_free_coherent(dev, size, vaddr, dma_handle);
+}
+
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag);
+
+void dma_free_noncoherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+
+#endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h
new file mode 100644
index 00000000..2d47da62
--- /dev/null
+++ b/arch/mips/include/asm/dma.h
@@ -0,0 +1,318 @@
+/*
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen
+ * and John Boyd, Nov. 1992.
+ *
+ * NOTE: all this is true *only* for ISA/EISA expansions on Mips boards
+ * and can only be used for expansion cards. Onboard DMA controllers, such
+ * as the R4030 on Jazz boards behave totally different!
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+#include <asm/io.h> /* need byte IO */
+#include <linux/spinlock.h> /* And spinlocks */
+#include <linux/delay.h>
+#include <asm/system.h>
+
+
+#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
+#define dma_outb outb_p
+#else
+#define dma_outb outb
+#endif
+
+#define dma_inb inb
+
+/*
+ * NOTES about DMA transfers:
+ *
+ * controller 1: channels 0-3, byte operations, ports 00-1F
+ * controller 2: channels 4-7, word operations, ports C0-DF
+ *
+ * - ALL registers are 8 bits only, regardless of transfer size
+ * - channel 4 is not used - cascades 1 into 2.
+ * - channels 0-3 are byte - addresses/counts are for physical bytes
+ * - channels 5-7 are word - addresses/counts are for physical words
+ * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+ * - transfer count loaded to registers is 1 less than actual count
+ * - controller 2 offsets are all even (2x offsets for controller 1)
+ * - page registers for 5-7 don't use data bit 0, represent 128K pages
+ * - page registers for 0-3 use bit 0, represent 64K pages
+ *
+ * DMA transfers are limited to the lower 16MB of _physical_ memory.
+ * Note that addresses loaded into registers must be _physical_ addresses,
+ * not logical addresses (which may differ if paging is active).
+ *
+ * Address mapping for channels 0-3:
+ *
+ * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses)
+ * | ... | | ... | | ... |
+ * | ... | | ... | | ... |
+ * | ... | | ... | | ... |
+ * P7 ... P0 A7 ... A0 A7 ... A0
+ * | Page | Addr MSB | Addr LSB | (DMA registers)
+ *
+ * Address mapping for channels 5-7:
+ *
+ * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses)
+ * | ... | \ \ ... \ \ \ ... \ \
+ * | ... | \ \ ... \ \ \ ... \ (not used)
+ * | ... | \ \ ... \ \ \ ... \
+ * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0
+ * | Page | Addr MSB | Addr LSB | (DMA registers)
+ *
+ * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+ * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+ * the hardware level, so odd-byte transfers aren't possible).
+ *
+ * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+ * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more,
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation.
+ *
+ */
+
+#ifndef CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN
+#define MAX_DMA_CHANNELS 8
+#endif
+
+/*
+ * The maximum address in KSEG0 that we can perform a DMA transfer to on this
+ * platform. This describes only the PC style part of the DMA logic like on
+ * Deskstations or Acer PICA but not the much more versatile DMA logic used
+ * for the local devices on Acer PICA or Magnums.
+ */
+#if defined(CONFIG_SGI_IP22) || defined(CONFIG_SGI_IP28)
+/* don't care; ISA bus master won't work, ISA slave DMA supports 32bit addr */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+#else
+#define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000)
+#endif
+#define MAX_DMA_PFN PFN_DOWN(virt_to_phys((void *)MAX_DMA_ADDRESS))
+
+#ifndef MAX_DMA32_PFN
+#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT))
+#endif
+
+/* 8237 DMA controllers */
+#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
+#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
+
+/* DMA controller registers */
+#define DMA1_CMD_REG 0x08 /* command register (w) */
+#define DMA1_STAT_REG 0x08 /* status register (r) */
+#define DMA1_REQ_REG 0x09 /* request register (w) */
+#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
+#define DMA1_MODE_REG 0x0B /* mode register (w) */
+#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
+#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
+#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
+#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
+#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
+
+#define DMA2_CMD_REG 0xD0 /* command register (w) */
+#define DMA2_STAT_REG 0xD0 /* status register (r) */
+#define DMA2_REQ_REG 0xD2 /* request register (w) */
+#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
+#define DMA2_MODE_REG 0xD6 /* mode register (w) */
+#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
+#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
+#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
+#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
+#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
+
+#define DMA_ADDR_0 0x00 /* DMA address registers */
+#define DMA_ADDR_1 0x02
+#define DMA_ADDR_2 0x04
+#define DMA_ADDR_3 0x06
+#define DMA_ADDR_4 0xC0
+#define DMA_ADDR_5 0xC4
+#define DMA_ADDR_6 0xC8
+#define DMA_ADDR_7 0xCC
+
+#define DMA_CNT_0 0x01 /* DMA count registers */
+#define DMA_CNT_1 0x03
+#define DMA_CNT_2 0x05
+#define DMA_CNT_3 0x07
+#define DMA_CNT_4 0xC2
+#define DMA_CNT_5 0xC6
+#define DMA_CNT_6 0xCA
+#define DMA_CNT_7 0xCE
+
+#define DMA_PAGE_0 0x87 /* DMA page registers */
+#define DMA_PAGE_1 0x83
+#define DMA_PAGE_2 0x81
+#define DMA_PAGE_3 0x82
+#define DMA_PAGE_5 0x8B
+#define DMA_PAGE_6 0x89
+#define DMA_PAGE_7 0x8A
+
+#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+#define DMA_AUTOINIT 0x10
+
+extern spinlock_t dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_spin_lock, flags);
+ return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+ spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(dmanr, DMA1_MASK_REG);
+ else
+ dma_outb(dmanr & 3, DMA2_MASK_REG);
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(dmanr | 4, DMA1_MASK_REG);
+ else
+ dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while holding the DMA lock ! ---
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(0, DMA1_CLEAR_FF_REG);
+ else
+ dma_outb(0, DMA2_CLEAR_FF_REG);
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+ if (dmanr<=3)
+ dma_outb(mode | dmanr, DMA1_MODE_REG);
+ else
+ dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
+}
+
+/* Set only the page register bits of the transfer address.
+ * This is used for successive transfers when we know the contents of
+ * the lower 16 bits of the DMA current address register, but a 64k boundary
+ * may have been crossed.
+ */
+static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+{
+ switch(dmanr) {
+ case 0:
+ dma_outb(pagenr, DMA_PAGE_0);
+ break;
+ case 1:
+ dma_outb(pagenr, DMA_PAGE_1);
+ break;
+ case 2:
+ dma_outb(pagenr, DMA_PAGE_2);
+ break;
+ case 3:
+ dma_outb(pagenr, DMA_PAGE_3);
+ break;
+ case 5:
+ dma_outb(pagenr & 0xfe, DMA_PAGE_5);
+ break;
+ case 6:
+ dma_outb(pagenr & 0xfe, DMA_PAGE_6);
+ break;
+ case 7:
+ dma_outb(pagenr & 0xfe, DMA_PAGE_7);
+ break;
+ }
+}
+
+
+/* Set transfer address & page bits for specific DMA channel.
+ * Assumes dma flipflop is clear.
+ */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+ set_dma_page(dmanr, a>>16);
+ if (dmanr <= 3) {
+ dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+ dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+ } else {
+ dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+ dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+ }
+}
+
+
+/* Set transfer size (max 64k for DMA0..3, 128k for DMA5..7) for
+ * a specific DMA channel.
+ * You must ensure the parameters are valid.
+ * NOTE: from a manual: "the number of transfers is one more
+ * than the initial word count"! This is taken into account.
+ * Assumes dma flip-flop is clear.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+ count--;
+ if (dmanr <= 3) {
+ dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+ dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+ } else {
+ dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ }
+}
+
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
+ * Assumes DMA flip-flop is clear.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+ unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+ : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+
+ /* using short to get 16-bit wrap around */
+ unsigned short count;
+
+ count = 1 + dma_inb(io_port);
+ count += dma_inb(io_port) << 8;
+
+ return (dmanr<=3)? count : (count<<1);
+}
+
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr); /* release it again */
+
+/* From PCI */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy (0)
+#endif
+
+#endif /* _ASM_DMA_H */
diff --git a/arch/mips/include/asm/ds1287.h b/arch/mips/include/asm/ds1287.h
new file mode 100644
index 00000000..3af0b8fb
--- /dev/null
+++ b/arch/mips/include/asm/ds1287.h
@@ -0,0 +1,27 @@
+/*
+ * DS1287 timer functions.
+ *
+ * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef __ASM_DS1287_H
+#define __ASM_DS1287_H
+
+extern int ds1287_timer_state(void);
+extern void ds1287_set_base_clock(unsigned int clock);
+extern int ds1287_clockevent_init(int irq);
+
+#endif
diff --git a/arch/mips/include/asm/dsp.h b/arch/mips/include/asm/dsp.h
new file mode 100644
index 00000000..e9bfc081
--- /dev/null
+++ b/arch/mips/include/asm/dsp.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2005 Mips Technologies
+ * Author: Chris Dearman, chris@mips.com derived from fpu.h
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_DSP_H
+#define _ASM_DSP_H
+
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/hazards.h>
+#include <asm/mipsregs.h>
+
+#define DSP_DEFAULT 0x00000000
+#define DSP_MASK 0x3ff
+
+#define __enable_dsp_hazard() \
+do { \
+ asm("_ehb"); \
+} while (0)
+
+static inline void __init_dsp(void)
+{
+ mthi1(0);
+ mtlo1(0);
+ mthi2(0);
+ mtlo2(0);
+ mthi3(0);
+ mtlo3(0);
+ wrdsp(DSP_DEFAULT, DSP_MASK);
+}
+
+static inline void init_dsp(void)
+{
+ if (cpu_has_dsp)
+ __init_dsp();
+}
+
+#define __save_dsp(tsk) \
+do { \
+ tsk->thread.dsp.dspr[0] = mfhi1(); \
+ tsk->thread.dsp.dspr[1] = mflo1(); \
+ tsk->thread.dsp.dspr[2] = mfhi2(); \
+ tsk->thread.dsp.dspr[3] = mflo2(); \
+ tsk->thread.dsp.dspr[4] = mfhi3(); \
+ tsk->thread.dsp.dspr[5] = mflo3(); \
+ tsk->thread.dsp.dspcontrol = rddsp(DSP_MASK); \
+} while (0)
+
+#define save_dsp(tsk) \
+do { \
+ if (cpu_has_dsp) \
+ __save_dsp(tsk); \
+} while (0)
+
+#define __restore_dsp(tsk) \
+do { \
+ mthi1(tsk->thread.dsp.dspr[0]); \
+ mtlo1(tsk->thread.dsp.dspr[1]); \
+ mthi2(tsk->thread.dsp.dspr[2]); \
+ mtlo2(tsk->thread.dsp.dspr[3]); \
+ mthi3(tsk->thread.dsp.dspr[4]); \
+ mtlo3(tsk->thread.dsp.dspr[5]); \
+ wrdsp(tsk->thread.dsp.dspcontrol, DSP_MASK); \
+} while (0)
+
+#define restore_dsp(tsk) \
+do { \
+ if (cpu_has_dsp) \
+ __restore_dsp(tsk); \
+} while (0)
+
+#define __get_dsp_regs(tsk) \
+({ \
+ if (tsk == current) \
+ __save_dsp(current); \
+ \
+ tsk->thread.dsp.dspr; \
+})
+
+#endif /* _ASM_DSP_H */
diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h
new file mode 100644
index 00000000..4da0c1fe
--- /dev/null
+++ b/arch/mips/include/asm/edac.h
@@ -0,0 +1,34 @@
+#ifndef ASM_EDAC_H
+#define ASM_EDAC_H
+
+/* ECC atomic, DMA, SMP and interrupt safe scrub function */
+
+static inline void atomic_scrub(void *va, u32 size)
+{
+ unsigned long *virt_addr = va;
+ unsigned long temp;
+ u32 i;
+
+ for (i = 0; i < size / sizeof(unsigned long); i++) {
+ /*
+ * Very carefully read and write to memory atomically
+ * so we are interrupt, DMA and SMP safe.
+ *
+ * Intel: asm("lock; addl $0, %0"::"m"(*virt_addr));
+ */
+
+ __asm__ __volatile__ (
+ " .set mips2 \n"
+ "1: ll %0, %1 # atomic_scrub \n"
+ " addu %0, $0 \n"
+ " sc %0, %1 \n"
+ " beqz %0, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (temp), "=m" (*virt_addr)
+ : "m" (*virt_addr));
+
+ virt_addr++;
+ }
+}
+
+#endif
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
new file mode 100644
index 00000000..455c0ac7
--- /dev/null
+++ b/arch/mips/include/asm/elf.h
@@ -0,0 +1,384 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Much of this is taken from binutils and GNU libc ...
+ */
+#ifndef _ASM_ELF_H
+#define _ASM_ELF_H
+
+
+/* ELF header e_flags defines. */
+/* MIPS architecture level. */
+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
+#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */
+#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
+#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32 R2 code. */
+#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64 R2 code. */
+
+/* The ABI of a file. */
+#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
+#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */
+
+#define PT_MIPS_REGINFO 0x70000000
+#define PT_MIPS_RTPROC 0x70000001
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Flags in the e_flags field of the header */
+#define EF_MIPS_NOREORDER 0x00000001
+#define EF_MIPS_PIC 0x00000002
+#define EF_MIPS_CPIC 0x00000004
+#define EF_MIPS_ABI2 0x00000020
+#define EF_MIPS_OPTIONS_FIRST 0x00000080
+#define EF_MIPS_32BITMODE 0x00000100
+#define EF_MIPS_ABI 0x0000f000
+#define EF_MIPS_ARCH 0xf0000000
+
+#define DT_MIPS_RLD_VERSION 0x70000001
+#define DT_MIPS_TIME_STAMP 0x70000002
+#define DT_MIPS_ICHECKSUM 0x70000003
+#define DT_MIPS_IVERSION 0x70000004
+#define DT_MIPS_FLAGS 0x70000005
+ #define RHF_NONE 0x00000000
+ #define RHF_HARDWAY 0x00000001
+ #define RHF_NOTPOT 0x00000002
+ #define RHF_SGI_ONLY 0x00000010
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_CONFLICT 0x70000008
+#define DT_MIPS_LIBLIST 0x70000009
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+#define DT_MIPS_CONFLICTNO 0x7000000b
+#define DT_MIPS_LIBLISTNO 0x70000010
+#define DT_MIPS_SYMTABNO 0x70000011
+#define DT_MIPS_UNREFEXTNO 0x70000012
+#define DT_MIPS_GOTSYM 0x70000013
+#define DT_MIPS_HIPAGENO 0x70000014
+#define DT_MIPS_RLD_MAP 0x70000016
+
+#define R_MIPS_NONE 0
+#define R_MIPS_16 1
+#define R_MIPS_32 2
+#define R_MIPS_REL32 3
+#define R_MIPS_26 4
+#define R_MIPS_HI16 5
+#define R_MIPS_LO16 6
+#define R_MIPS_GPREL16 7
+#define R_MIPS_LITERAL 8
+#define R_MIPS_GOT16 9
+#define R_MIPS_PC16 10
+#define R_MIPS_CALL16 11
+#define R_MIPS_GPREL32 12
+/* The remaining relocs are defined on Irix, although they are not
+ in the MIPS ELF ABI. */
+#define R_MIPS_UNUSED1 13
+#define R_MIPS_UNUSED2 14
+#define R_MIPS_UNUSED3 15
+#define R_MIPS_SHIFT5 16
+#define R_MIPS_SHIFT6 17
+#define R_MIPS_64 18
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+/*
+ * The following two relocation types are specified in the MIPS ABI
+ * conformance guide version 1.2 but not yet in the psABI.
+ */
+#define R_MIPS_GOTHI16 22
+#define R_MIPS_GOTLO16 23
+#define R_MIPS_SUB 24
+#define R_MIPS_INSERT_A 25
+#define R_MIPS_INSERT_B 26
+#define R_MIPS_DELETE 27
+#define R_MIPS_HIGHER 28
+#define R_MIPS_HIGHEST 29
+/*
+ * The following two relocation types are specified in the MIPS ABI
+ * conformance guide version 1.2 but not yet in the psABI.
+ */
+#define R_MIPS_CALLHI16 30
+#define R_MIPS_CALLLO16 31
+/*
+ * This range is reserved for vendor specific relocations.
+ */
+#define R_MIPS_LOVENDOR 100
+#define R_MIPS_HIVENDOR 127
+
+#define SHN_MIPS_ACCOMON 0xff00 /* Allocated common symbols */
+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */
+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */
+
+#define SHT_MIPS_LIST 0x70000000
+#define SHT_MIPS_CONFLICT 0x70000002
+#define SHT_MIPS_GPTAB 0x70000003
+#define SHT_MIPS_UCODE 0x70000004
+#define SHT_MIPS_DEBUG 0x70000005
+#define SHT_MIPS_REGINFO 0x70000006
+#define SHT_MIPS_PACKAGE 0x70000007
+#define SHT_MIPS_PACKSYM 0x70000008
+#define SHT_MIPS_RELD 0x70000009
+#define SHT_MIPS_IFACE 0x7000000b
+#define SHT_MIPS_CONTENT 0x7000000c
+#define SHT_MIPS_OPTIONS 0x7000000d
+#define SHT_MIPS_SHDR 0x70000010
+#define SHT_MIPS_FDESC 0x70000011
+#define SHT_MIPS_EXTSYM 0x70000012
+#define SHT_MIPS_DENSE 0x70000013
+#define SHT_MIPS_PDESC 0x70000014
+#define SHT_MIPS_LOCSYM 0x70000015
+#define SHT_MIPS_AUXSYM 0x70000016
+#define SHT_MIPS_OPTSYM 0x70000017
+#define SHT_MIPS_LOCSTR 0x70000018
+#define SHT_MIPS_LINE 0x70000019
+#define SHT_MIPS_RFDESC 0x7000001a
+#define SHT_MIPS_DELTASYM 0x7000001b
+#define SHT_MIPS_DELTAINST 0x7000001c
+#define SHT_MIPS_DELTACLASS 0x7000001d
+#define SHT_MIPS_DWARF 0x7000001e
+#define SHT_MIPS_DELTADECL 0x7000001f
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+#define SHT_MIPS_EVENTS 0x70000021
+#define SHT_MIPS_TRANSLATE 0x70000022
+#define SHT_MIPS_PIXIE 0x70000023
+#define SHT_MIPS_XLATE 0x70000024
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+#define SHT_MIPS_WHIRL 0x70000026
+#define SHT_MIPS_EH_REGION 0x70000027
+#define SHT_MIPS_XLATE_OLD 0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+#define SHF_MIPS_GPREL 0x10000000
+#define SHF_MIPS_MERGE 0x20000000
+#define SHF_MIPS_ADDR 0x40000000
+#define SHF_MIPS_STRING 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL 0x04000000
+#define SHF_MIPS_NAMES 0x02000000
+#define SHF_MIPS_NODUPES 0x01000000
+
+#ifndef ELF_ARCH
+/* ELF register definitions */
+#define ELF_NGREG 45
+#define ELF_NFPREG 33
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#ifdef CONFIG_32BIT
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(hdr) \
+({ \
+ int __res = 1; \
+ struct elfhdr *__h = (hdr); \
+ \
+ if (__h->e_machine != EM_MIPS) \
+ __res = 0; \
+ if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
+ __res = 0; \
+ if ((__h->e_flags & EF_MIPS_ABI2) != 0) \
+ __res = 0; \
+ if (((__h->e_flags & EF_MIPS_ABI) != 0) && \
+ ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \
+ __res = 0; \
+ \
+ __res; \
+})
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+
+#endif /* CONFIG_32BIT */
+
+#ifdef CONFIG_64BIT
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(hdr) \
+({ \
+ int __res = 1; \
+ struct elfhdr *__h = (hdr); \
+ \
+ if (__h->e_machine != EM_MIPS) \
+ __res = 0; \
+ if (__h->e_ident[EI_CLASS] != ELFCLASS64) \
+ __res = 0; \
+ \
+ __res; \
+})
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS64
+
+#endif /* CONFIG_64BIT */
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#ifdef __MIPSEB__
+#define ELF_DATA ELFDATA2MSB
+#elif defined(__MIPSEL__)
+#define ELF_DATA ELFDATA2LSB
+#endif
+#define ELF_ARCH EM_MIPS
+
+#endif /* !defined(ELF_ARCH) */
+
+struct mips_abi;
+
+extern struct mips_abi mips_abi;
+extern struct mips_abi mips_abi_32;
+extern struct mips_abi mips_abi_n32;
+
+#ifdef CONFIG_32BIT
+
+#define SET_PERSONALITY(ex) \
+do { \
+ if (personality(current->personality) != PER_LINUX) \
+ set_personality(PER_LINUX); \
+ \
+ current->thread.abi = &mips_abi; \
+} while (0)
+
+#endif /* CONFIG_32BIT */
+
+#ifdef CONFIG_64BIT
+
+#ifdef CONFIG_MIPS32_N32
+#define __SET_PERSONALITY32_N32() \
+ do { \
+ set_thread_flag(TIF_32BIT_ADDR); \
+ current->thread.abi = &mips_abi_n32; \
+ } while (0)
+#else
+#define __SET_PERSONALITY32_N32() \
+ do { } while (0)
+#endif
+
+#ifdef CONFIG_MIPS32_O32
+#define __SET_PERSONALITY32_O32() \
+ do { \
+ set_thread_flag(TIF_32BIT_REGS); \
+ set_thread_flag(TIF_32BIT_ADDR); \
+ current->thread.abi = &mips_abi_32; \
+ } while (0)
+#else
+#define __SET_PERSONALITY32_O32() \
+ do { } while (0)
+#endif
+
+#ifdef CONFIG_MIPS32_COMPAT
+#define __SET_PERSONALITY32(ex) \
+do { \
+ if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \
+ ((ex).e_flags & EF_MIPS_ABI) == 0) \
+ __SET_PERSONALITY32_N32(); \
+ else \
+ __SET_PERSONALITY32_O32(); \
+} while (0)
+#else
+#define __SET_PERSONALITY32(ex) do { } while (0)
+#endif
+
+#define SET_PERSONALITY(ex) \
+do { \
+ unsigned int p; \
+ \
+ clear_thread_flag(TIF_32BIT_REGS); \
+ clear_thread_flag(TIF_32BIT_ADDR); \
+ \
+ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ __SET_PERSONALITY32(ex); \
+ else \
+ current->thread.abi = &mips_abi; \
+ \
+ p = personality(current->personality); \
+ if (p != PER_LINUX32 && p != PER_LINUX) \
+ set_personality(PER_LINUX); \
+} while (0)
+
+#endif /* CONFIG_64BIT */
+
+struct pt_regs;
+struct task_struct;
+
+extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
+extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
+extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
+
+#ifndef ELF_CORE_COPY_REGS
+#define ELF_CORE_COPY_REGS(elf_regs, regs) \
+ elf_dump_regs((elf_greg_t *)&(elf_regs), regs);
+#endif
+#ifndef ELF_CORE_COPY_TASK_REGS
+#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
+#endif
+#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \
+ dump_task_fpu(tsk, elf_fpregs)
+
+#define ELF_EXEC_PAGESIZE PAGE_SIZE
+
+/* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. This could be done in userspace,
+ but it's not easy, and we've already done it here. */
+
+#define ELF_HWCAP (0)
+
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization. This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ */
+
+#define ELF_PLATFORM __elf_platform
+extern const char *__elf_platform;
+
+/*
+ * See comments in asm-alpha/elf.h, this is the same thing
+ * on the MIPS.
+ */
+#define ELF_PLAT_INIT(_r, load_addr) do { \
+ _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \
+ _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \
+ _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0; \
+ _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0; \
+ _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0; \
+ _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0; \
+ _r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0; \
+ _r->regs[30] = _r->regs[31] = 0; \
+} while (0)
+
+/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
+ use of this is to invoke "./ld.so someprog" to test out a new version of
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+#ifndef ELF_ET_DYN_BASE
+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
+#endif
+
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+ int uses_interp);
+
+struct mm_struct;
+extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+#define arch_randomize_brk arch_randomize_brk
+
+#endif /* _ASM_ELF_H */
diff --git a/arch/mips/include/asm/emergency-restart.h b/arch/mips/include/asm/emergency-restart.h
new file mode 100644
index 00000000..108d8c48
--- /dev/null
+++ b/arch/mips/include/asm/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/mips/include/asm/emma/emma2rh.h b/arch/mips/include/asm/emma/emma2rh.h
new file mode 100644
index 00000000..c1449d20
--- /dev/null
+++ b/arch/mips/include/asm/emma/emma2rh.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2005-2006
+ *
+ * This file based on include/asm-mips/ddb5xxx/ddb5xxx.h
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_EMMA_EMMA2RH_H
+#define __ASM_EMMA_EMMA2RH_H
+
+#include <irq.h>
+
+/*
+ * EMMA2RH registers
+ */
+#define REGBASE 0x10000000
+
+#define EMMA2RH_BHIF_STRAP_0 (0x000010+REGBASE)
+#define EMMA2RH_BHIF_INT_ST_0 (0x000030+REGBASE)
+#define EMMA2RH_BHIF_INT_ST_1 (0x000034+REGBASE)
+#define EMMA2RH_BHIF_INT_ST_2 (0x000038+REGBASE)
+#define EMMA2RH_BHIF_INT_EN_0 (0x000040+REGBASE)
+#define EMMA2RH_BHIF_INT_EN_1 (0x000044+REGBASE)
+#define EMMA2RH_BHIF_INT_EN_2 (0x000048+REGBASE)
+#define EMMA2RH_BHIF_INT1_EN_0 (0x000050+REGBASE)
+#define EMMA2RH_BHIF_INT1_EN_1 (0x000054+REGBASE)
+#define EMMA2RH_BHIF_INT1_EN_2 (0x000058+REGBASE)
+#define EMMA2RH_BHIF_SW_INT (0x000070+REGBASE)
+#define EMMA2RH_BHIF_SW_INT_EN (0x000080+REGBASE)
+#define EMMA2RH_BHIF_SW_INT_CLR (0x000090+REGBASE)
+#define EMMA2RH_BHIF_MAIN_CTRL (0x0000b4+REGBASE)
+#define EMMA2RH_BHIF_EXCEPT_VECT_BASE_ADDRESS (0x0000c0+REGBASE)
+#define EMMA2RH_GPIO_DIR (0x110d20+REGBASE)
+#define EMMA2RH_GPIO_INT_ST (0x110d30+REGBASE)
+#define EMMA2RH_GPIO_INT_MASK (0x110d3c+REGBASE)
+#define EMMA2RH_GPIO_INT_MODE (0x110d48+REGBASE)
+#define EMMA2RH_GPIO_INT_CND_A (0x110d54+REGBASE)
+#define EMMA2RH_GPIO_INT_CND_B (0x110d60+REGBASE)
+#define EMMA2RH_PBRD_INT_EN (0x100010+REGBASE)
+#define EMMA2RH_PBRD_CLKSEL (0x100028+REGBASE)
+#define EMMA2RH_PFUR0_BASE (0x101000+REGBASE)
+#define EMMA2RH_PFUR1_BASE (0x102000+REGBASE)
+#define EMMA2RH_PFUR2_BASE (0x103000+REGBASE)
+#define EMMA2RH_PIIC0_BASE (0x107000+REGBASE)
+#define EMMA2RH_PIIC1_BASE (0x108000+REGBASE)
+#define EMMA2RH_PIIC2_BASE (0x109000+REGBASE)
+#define EMMA2RH_PCI_CONTROL (0x200000+REGBASE)
+#define EMMA2RH_PCI_ARBIT_CTR (0x200004+REGBASE)
+#define EMMA2RH_PCI_IWIN0_CTR (0x200010+REGBASE)
+#define EMMA2RH_PCI_IWIN1_CTR (0x200014+REGBASE)
+#define EMMA2RH_PCI_INIT_ESWP (0x200018+REGBASE)
+#define EMMA2RH_PCI_INT (0x200020+REGBASE)
+#define EMMA2RH_PCI_INT_EN (0x200024+REGBASE)
+#define EMMA2RH_PCI_TWIN_CTR (0x200030+REGBASE)
+#define EMMA2RH_PCI_TWIN_BADR (0x200034+REGBASE)
+#define EMMA2RH_PCI_TWIN0_DADR (0x200038+REGBASE)
+#define EMMA2RH_PCI_TWIN1_DADR (0x20003c+REGBASE)
+
+/*
+ * Memory map (physical address)
+ *
+ * Note most of the following address must be properly aligned by the
+ * corresponding size. For example, if PCI_IO_SIZE is 16MB, then
+ * PCI_IO_BASE must be aligned along 16MB boundary.
+ */
+
+/* the actual ram size is detected at run-time */
+#define EMMA2RH_RAM_BASE 0x00000000
+#define EMMA2RH_RAM_SIZE 0x10000000 /* less than 256MB */
+
+#define EMMA2RH_IO_BASE 0x10000000
+#define EMMA2RH_IO_SIZE 0x01000000 /* 16 MB */
+
+#define EMMA2RH_GENERALIO_BASE 0x11000000
+#define EMMA2RH_GENERALIO_SIZE 0x01000000 /* 16 MB */
+
+#define EMMA2RH_PCI_IO_BASE 0x12000000
+#define EMMA2RH_PCI_IO_SIZE 0x02000000 /* 32 MB */
+
+#define EMMA2RH_PCI_MEM_BASE 0x14000000
+#define EMMA2RH_PCI_MEM_SIZE 0x08000000 /* 128 MB */
+
+#define EMMA2RH_ROM_BASE 0x1c000000
+#define EMMA2RH_ROM_SIZE 0x04000000 /* 64 MB */
+
+#define EMMA2RH_PCI_CONFIG_BASE EMMA2RH_PCI_IO_BASE
+#define EMMA2RH_PCI_CONFIG_SIZE EMMA2RH_PCI_IO_SIZE
+
+#define NUM_EMMA2RH_IRQ 96
+
+#define EMMA2RH_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
+
+/*
+ * emma2rh irq defs
+ */
+
+#define EMMA2RH_IRQ_INT(n) (EMMA2RH_IRQ_BASE + (n))
+
+#define EMMA2RH_IRQ_PFUR0 EMMA2RH_IRQ_INT(49)
+#define EMMA2RH_IRQ_PFUR1 EMMA2RH_IRQ_INT(50)
+#define EMMA2RH_IRQ_PFUR2 EMMA2RH_IRQ_INT(51)
+#define EMMA2RH_IRQ_PIIC0 EMMA2RH_IRQ_INT(56)
+#define EMMA2RH_IRQ_PIIC1 EMMA2RH_IRQ_INT(57)
+#define EMMA2RH_IRQ_PIIC2 EMMA2RH_IRQ_INT(58)
+
+/*
+ * EMMA2RH Register Access
+ */
+
+#define EMMA2RH_BASE (0xa0000000)
+
+static inline void emma2rh_sync(void)
+{
+ volatile u32 *p = (volatile u32 *)0xbfc00000;
+ (void)(*p);
+}
+
+static inline void emma2rh_out32(u32 offset, u32 val)
+{
+ *(volatile u32 *)(EMMA2RH_BASE | offset) = val;
+ emma2rh_sync();
+}
+
+static inline u32 emma2rh_in32(u32 offset)
+{
+ u32 val = *(volatile u32 *)(EMMA2RH_BASE | offset);
+ return val;
+}
+
+static inline void emma2rh_out16(u32 offset, u16 val)
+{
+ *(volatile u16 *)(EMMA2RH_BASE | offset) = val;
+ emma2rh_sync();
+}
+
+static inline u16 emma2rh_in16(u32 offset)
+{
+ u16 val = *(volatile u16 *)(EMMA2RH_BASE | offset);
+ return val;
+}
+
+static inline void emma2rh_out8(u32 offset, u8 val)
+{
+ *(volatile u8 *)(EMMA2RH_BASE | offset) = val;
+ emma2rh_sync();
+}
+
+static inline u8 emma2rh_in8(u32 offset)
+{
+ u8 val = *(volatile u8 *)(EMMA2RH_BASE | offset);
+ return val;
+}
+
+/**
+ * IIC registers map
+ **/
+
+/*---------------------------------------------------------------------------*/
+/* CNT - Control register (00H R/W) */
+/*---------------------------------------------------------------------------*/
+#define SPT 0x00000001
+#define STT 0x00000002
+#define ACKE 0x00000004
+#define WTIM 0x00000008
+#define SPIE 0x00000010
+#define WREL 0x00000020
+#define LREL 0x00000040
+#define IICE 0x00000080
+#define CNT_RESERVED 0x000000ff /* reserved bit 0 */
+
+#define I2C_EMMA_START (IICE | STT)
+#define I2C_EMMA_STOP (IICE | SPT)
+#define I2C_EMMA_REPSTART I2C_EMMA_START
+
+/*---------------------------------------------------------------------------*/
+/* STA - Status register (10H Read) */
+/*---------------------------------------------------------------------------*/
+#define MSTS 0x00000080
+#define ALD 0x00000040
+#define EXC 0x00000020
+#define COI 0x00000010
+#define TRC 0x00000008
+#define ACKD 0x00000004
+#define STD 0x00000002
+#define SPD 0x00000001
+
+/*---------------------------------------------------------------------------*/
+/* CSEL - Clock select register (20H R/W) */
+/*---------------------------------------------------------------------------*/
+#define FCL 0x00000080
+#define ND50 0x00000040
+#define CLD 0x00000020
+#define DAD 0x00000010
+#define SMC 0x00000008
+#define DFC 0x00000004
+#define CL 0x00000003
+#define CSEL_RESERVED 0x000000ff /* reserved bit 0 */
+
+#define FAST397 0x0000008b
+#define FAST297 0x0000008a
+#define FAST347 0x0000000b
+#define FAST260 0x0000000a
+#define FAST130 0x00000008
+#define STANDARD108 0x00000083
+#define STANDARD83 0x00000082
+#define STANDARD95 0x00000003
+#define STANDARD73 0x00000002
+#define STANDARD36 0x00000001
+#define STANDARD71 0x00000000
+
+/*---------------------------------------------------------------------------*/
+/* SVA - Slave address register (30H R/W) */
+/*---------------------------------------------------------------------------*/
+#define SVA 0x000000fe
+
+/*---------------------------------------------------------------------------*/
+/* SHR - Shift register (40H R/W) */
+/*---------------------------------------------------------------------------*/
+#define SR 0x000000ff
+
+/*---------------------------------------------------------------------------*/
+/* INT - Interrupt register (50H R/W) */
+/* INTM - Interrupt mask register (60H R/W) */
+/*---------------------------------------------------------------------------*/
+#define INTE0 0x00000001
+
+/***********************************************************************
+ * I2C registers
+ ***********************************************************************
+ */
+#define I2C_EMMA_CNT 0x00
+#define I2C_EMMA_STA 0x10
+#define I2C_EMMA_CSEL 0x20
+#define I2C_EMMA_SVA 0x30
+#define I2C_EMMA_SHR 0x40
+#define I2C_EMMA_INT 0x50
+#define I2C_EMMA_INTM 0x60
+
+/*
+ * include the board dependent part
+ */
+#ifdef CONFIG_NEC_MARKEINS
+#include <asm/emma/markeins.h>
+#else
+#error "Unknown EMMA2RH board!"
+#endif
+
+#endif /* __ASM_EMMA_EMMA2RH_H */
diff --git a/arch/mips/include/asm/emma/markeins.h b/arch/mips/include/asm/emma/markeins.h
new file mode 100644
index 00000000..bf2d229c
--- /dev/null
+++ b/arch/mips/include/asm/emma/markeins.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2005-2006
+ *
+ * This file based on include/asm-mips/ddb5xxx/ddb5xxx.h
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MARKEINS_H
+#define MARKEINS_H
+
+#define NUM_EMMA2RH_IRQ_SW 32
+#define NUM_EMMA2RH_IRQ_GPIO 32
+
+#define EMMA2RH_SW_CASCADE (EMMA2RH_IRQ_INT(7) - EMMA2RH_IRQ_INT(0))
+#define EMMA2RH_GPIO_CASCADE (EMMA2RH_IRQ_INT(46) - EMMA2RH_IRQ_INT(0))
+
+#define EMMA2RH_SW_IRQ_BASE (EMMA2RH_IRQ_BASE + NUM_EMMA2RH_IRQ)
+#define EMMA2RH_GPIO_IRQ_BASE (EMMA2RH_SW_IRQ_BASE + NUM_EMMA2RH_IRQ_SW)
+
+#define EMMA2RH_SW_IRQ_INT(n) (EMMA2RH_SW_IRQ_BASE + (n))
+
+#define MARKEINS_PCI_IRQ_INTA EMMA2RH_GPIO_IRQ_BASE+15
+#define MARKEINS_PCI_IRQ_INTB EMMA2RH_GPIO_IRQ_BASE+16
+#define MARKEINS_PCI_IRQ_INTC EMMA2RH_GPIO_IRQ_BASE+17
+#define MARKEINS_PCI_IRQ_INTD EMMA2RH_GPIO_IRQ_BASE+18
+
+#endif /* CONFIG_MARKEINS */
diff --git a/arch/mips/include/asm/errno.h b/arch/mips/include/asm/errno.h
new file mode 100644
index 00000000..6dcd3583
--- /dev/null
+++ b/arch/mips/include/asm/errno.h
@@ -0,0 +1,135 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999, 2001, 2002 by Ralf Baechle
+ */
+#ifndef _ASM_ERRNO_H
+#define _ASM_ERRNO_H
+
+/*
+ * These error numbers are intended to be MIPS ABI compatible
+ */
+
+#include <asm-generic/errno-base.h>
+
+#define ENOMSG 35 /* No message of desired type */
+#define EIDRM 36 /* Identifier removed */
+#define ECHRNG 37 /* Channel number out of range */
+#define EL2NSYNC 38 /* Level 2 not synchronized */
+#define EL3HLT 39 /* Level 3 halted */
+#define EL3RST 40 /* Level 3 reset */
+#define ELNRNG 41 /* Link number out of range */
+#define EUNATCH 42 /* Protocol driver not attached */
+#define ENOCSI 43 /* No CSI structure available */
+#define EL2HLT 44 /* Level 2 halted */
+#define EDEADLK 45 /* Resource deadlock would occur */
+#define ENOLCK 46 /* No record locks available */
+#define EBADE 50 /* Invalid exchange */
+#define EBADR 51 /* Invalid request descriptor */
+#define EXFULL 52 /* Exchange full */
+#define ENOANO 53 /* No anode */
+#define EBADRQC 54 /* Invalid request code */
+#define EBADSLT 55 /* Invalid slot */
+#define EDEADLOCK 56 /* File locking deadlock error */
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EDOTDOT 73 /* RFS specific error */
+#define EMULTIHOP 74 /* Multihop attempted */
+#define EBADMSG 77 /* Not a data message */
+#define ENAMETOOLONG 78 /* File name too long */
+#define EOVERFLOW 79 /* Value too large for defined data type */
+#define ENOTUNIQ 80 /* Name not unique on network */
+#define EBADFD 81 /* File descriptor in bad state */
+#define EREMCHG 82 /* Remote address changed */
+#define ELIBACC 83 /* Can not access a needed shared library */
+#define ELIBBAD 84 /* Accessing a corrupted shared library */
+#define ELIBSCN 85 /* .lib section in a.out corrupted */
+#define ELIBMAX 86 /* Attempting to link in too many shared libraries */
+#define ELIBEXEC 87 /* Cannot exec a shared library directly */
+#define EILSEQ 88 /* Illegal byte sequence */
+#define ENOSYS 89 /* Function not implemented */
+#define ELOOP 90 /* Too many symbolic links encountered */
+#define ERESTART 91 /* Interrupted system call should be restarted */
+#define ESTRPIPE 92 /* Streams pipe error */
+#define ENOTEMPTY 93 /* Directory not empty */
+#define EUSERS 94 /* Too many users */
+#define ENOTSOCK 95 /* Socket operation on non-socket */
+#define EDESTADDRREQ 96 /* Destination address required */
+#define EMSGSIZE 97 /* Message too long */
+#define EPROTOTYPE 98 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 99 /* Protocol not available */
+#define EPROTONOSUPPORT 120 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 121 /* Socket type not supported */
+#define EOPNOTSUPP 122 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 123 /* Protocol family not supported */
+#define EAFNOSUPPORT 124 /* Address family not supported by protocol */
+#define EADDRINUSE 125 /* Address already in use */
+#define EADDRNOTAVAIL 126 /* Cannot assign requested address */
+#define ENETDOWN 127 /* Network is down */
+#define ENETUNREACH 128 /* Network is unreachable */
+#define ENETRESET 129 /* Network dropped connection because of reset */
+#define ECONNABORTED 130 /* Software caused connection abort */
+#define ECONNRESET 131 /* Connection reset by peer */
+#define ENOBUFS 132 /* No buffer space available */
+#define EISCONN 133 /* Transport endpoint is already connected */
+#define ENOTCONN 134 /* Transport endpoint is not connected */
+#define EUCLEAN 135 /* Structure needs cleaning */
+#define ENOTNAM 137 /* Not a XENIX named type file */
+#define ENAVAIL 138 /* No XENIX semaphores available */
+#define EISNAM 139 /* Is a named type file */
+#define EREMOTEIO 140 /* Remote I/O error */
+#define EINIT 141 /* Reserved */
+#define EREMDEV 142 /* Error 142 */
+#define ESHUTDOWN 143 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 144 /* Too many references: cannot splice */
+#define ETIMEDOUT 145 /* Connection timed out */
+#define ECONNREFUSED 146 /* Connection refused */
+#define EHOSTDOWN 147 /* Host is down */
+#define EHOSTUNREACH 148 /* No route to host */
+#define EWOULDBLOCK EAGAIN /* Operation would block */
+#define EALREADY 149 /* Operation already in progress */
+#define EINPROGRESS 150 /* Operation now in progress */
+#define ESTALE 151 /* Stale NFS file handle */
+#define ECANCELED 158 /* AIO operation canceled */
+
+/*
+ * These error are Linux extensions.
+ */
+#define ENOMEDIUM 159 /* No medium found */
+#define EMEDIUMTYPE 160 /* Wrong medium type */
+#define ENOKEY 161 /* Required key not available */
+#define EKEYEXPIRED 162 /* Key has expired */
+#define EKEYREVOKED 163 /* Key has been revoked */
+#define EKEYREJECTED 164 /* Key was rejected by service */
+
+/* for robust mutexes */
+#define EOWNERDEAD 165 /* Owner died */
+#define ENOTRECOVERABLE 166 /* State not recoverable */
+
+#define ERFKILL 167 /* Operation not possible due to RF-kill */
+
+#define EHWPOISON 168 /* Memory page has hardware error */
+
+#define EDQUOT 1133 /* Quota exceeded */
+
+#ifdef __KERNEL__
+
+/* The biggest error number defined here or in <linux/errno.h>. */
+#define EMAXERRNO 1133
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_ERRNO_H */
diff --git a/arch/mips/include/asm/fb.h b/arch/mips/include/asm/fb.h
new file mode 100644
index 00000000..bd3f68c9
--- /dev/null
+++ b/arch/mips/include/asm/fb.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+ unsigned long off)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+}
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+ return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff --git a/arch/mips/include/asm/fcntl.h b/arch/mips/include/asm/fcntl.h
new file mode 100644
index 00000000..75eddedc
--- /dev/null
+++ b/arch/mips/include/asm/fcntl.h
@@ -0,0 +1,77 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle
+ */
+#ifndef _ASM_FCNTL_H
+#define _ASM_FCNTL_H
+
+
+#define O_APPEND 0x0008
+#define O_DSYNC 0x0010 /* used to be O_SYNC, see below */
+#define O_NONBLOCK 0x0080
+#define O_CREAT 0x0100 /* not fcntl */
+#define O_TRUNC 0x0200 /* not fcntl */
+#define O_EXCL 0x0400 /* not fcntl */
+#define O_NOCTTY 0x0800 /* not fcntl */
+#define FASYNC 0x1000 /* fcntl, for BSD compatibility */
+#define O_LARGEFILE 0x2000 /* allow large file opens */
+/*
+ * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag. We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics. It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ *
+ * This has the nice side-effect that we can simply test for O_DSYNC
+ * wherever we do not care if O_DSYNC or O_SYNC is used.
+ *
+ * Note: __O_SYNC must never be used directly.
+ */
+#define __O_SYNC 0x4000
+#define O_SYNC (__O_SYNC|O_DSYNC)
+#define O_DIRECT 0x8000 /* direct disk access hint */
+
+#define F_GETLK 14
+#define F_SETLK 6
+#define F_SETLKW 7
+
+#define F_SETOWN 24 /* for sockets. */
+#define F_GETOWN 23 /* for sockets. */
+
+#ifndef __mips64
+#define F_GETLK64 33 /* using 'struct flock64' */
+#define F_SETLK64 34
+#define F_SETLKW64 35
+#endif
+
+/*
+ * The flavours of struct flock. "struct flock" is the ABI compliant
+ * variant. Finally struct flock64 is the LFS variant of struct flock. As
+ * a historic accident and inconsistence with the ABI definition it doesn't
+ * contain all the same fields as struct flock.
+ */
+
+#ifdef CONFIG_32BIT
+#include <linux/types.h>
+
+struct flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ long l_sysid;
+ __kernel_pid_t l_pid;
+ long pad[4];
+};
+
+#define HAVE_ARCH_STRUCT_FLOCK
+
+#endif /* CONFIG_32BIT */
+
+#include <asm-generic/fcntl.h>
+
+#endif /* _ASM_FCNTL_H */
diff --git a/arch/mips/include/asm/fixmap.h b/arch/mips/include/asm/fixmap.h
new file mode 100644
index 00000000..0b89b83e
--- /dev/null
+++ b/arch/mips/include/asm/fixmap.h
@@ -0,0 +1,125 @@
+/*
+ * fixmap.h: compile-time virtual memory allocation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998 Ingo Molnar
+ *
+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ */
+
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+#include <asm/page.h>
+#ifdef CONFIG_HIGHMEM
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
+#endif
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * highger than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+
+/*
+ * on UP currently we will have no trace of the fixmap mechanizm,
+ * no page table allocations, etc. This might change in the
+ * future, say framebuffers for the console driver(s) could be
+ * fix-mapped?
+ */
+enum fixed_addresses {
+#define FIX_N_COLOURS 8
+ FIX_CMAP_BEGIN,
+#ifdef CONFIG_MIPS_MT_SMTC
+ FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * NR_CPUS * 2),
+#else
+ FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * 2),
+#endif
+#ifdef CONFIG_HIGHMEM
+ /* reserved pte's for temporary kernel mappings */
+ FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
+ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#endif
+ __end_of_fixed_addresses
+};
+
+/*
+ * used by vmalloc.c.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap, and leave one page empty
+ * at the top of mem..
+ */
+#ifdef CONFIG_BCM63XX
+#define FIXADDR_TOP ((unsigned long)(long)(int)0xff000000)
+#else
+#if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
+#define FIXADDR_TOP ((unsigned long)(long)(int)(0xff000000 - 0x20000))
+#else
+#define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000)
+#endif
+#endif
+#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
+
+#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+ /*
+ * this branch gets completely eliminated after inlining,
+ * except when someone tries to use fixaddr indices in an
+ * illegal way. (such as mixing up address types or using
+ * out-of-range indices).
+ *
+ * If it doesn't get removed, the linker will complain
+ * loudly with a reasonably clear error message..
+ */
+ if (idx >= __end_of_fixed_addresses)
+ __this_fixmap_does_not_exist();
+
+ return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+ BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+ return __virt_to_fix(vaddr);
+}
+
+#define kmap_get_fixmap_pte(vaddr) \
+ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+
+/*
+ * Called from pgtable_init()
+ */
+extern void fixrange_init(unsigned long start, unsigned long end,
+ pgd_t *pgd_base);
+
+
+#endif
diff --git a/arch/mips/include/asm/floppy.h b/arch/mips/include/asm/floppy.h
new file mode 100644
index 00000000..c5c7c0e6
--- /dev/null
+++ b/arch/mips/include/asm/floppy.h
@@ -0,0 +1,56 @@
+/*
+ * Architecture specific parts of the Floppy driver
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 - 2000 Ralf Baechle
+ */
+#ifndef _ASM_FLOPPY_H
+#define _ASM_FLOPPY_H
+
+#include <linux/dma-mapping.h>
+
+static inline void fd_cacheflush(char * addr, long size)
+{
+ dma_cache_sync(NULL, addr, size, DMA_BIDIRECTIONAL);
+}
+
+#define MAX_BUFFER_SECTORS 24
+
+
+/*
+ * And on Mips's the CMOS info fails also ...
+ *
+ * FIXME: This information should come from the ARC configuration tree
+ * or wherever a particular machine has stored this ...
+ */
+#define FLOPPY0_TYPE fd_drive_type(0)
+#define FLOPPY1_TYPE fd_drive_type(1)
+
+#define FDC1 fd_getfdaddr1();
+
+#define N_FDC 1 /* do you *really* want a second controller? */
+#define N_DRIVE 8
+
+/*
+ * The DMA channel used by the floppy controller cannot access data at
+ * addresses >= 16MB
+ *
+ * Went back to the 1MB limit, as some people had problems with the floppy
+ * driver otherwise. It doesn't matter much for performance anyway, as most
+ * floppy accesses go through the track buffer.
+ *
+ * On MIPSes using vdma, this actually means that *all* transfers go thru
+ * the * track buffer since 0x1000000 is always smaller than KSEG0/1.
+ * Actually this needs to be a bit more complicated since the so much different
+ * hardware available with MIPS CPUs ...
+ */
+#define CROSS_64KB(a, s) ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)
+
+#define EXTRA_FLOPPY_PARAMS
+
+#include <floppy.h>
+
+#endif /* _ASM_FLOPPY_H */
diff --git a/arch/mips/include/asm/fpregdef.h b/arch/mips/include/asm/fpregdef.h
new file mode 100644
index 00000000..2b5fddc8
--- /dev/null
+++ b/arch/mips/include/asm/fpregdef.h
@@ -0,0 +1,99 @@
+/*
+ * Definitions for the FPU register names
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 Ralf Baechle
+ * Copyright (C) 1985 MIPS Computer Systems, Inc.
+ * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_FPREGDEF_H
+#define _ASM_FPREGDEF_H
+
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
+ * These definitions only cover the R3000-ish 16/32 register model.
+ * But we're trying to be R3000 friendly anyway ...
+ */
+#define fv0 $f0 /* return value */
+#define fv0f $f1
+#define fv1 $f2
+#define fv1f $f3
+#define fa0 $f12 /* argument registers */
+#define fa0f $f13
+#define fa1 $f14
+#define fa1f $f15
+#define ft0 $f4 /* caller saved */
+#define ft0f $f5
+#define ft1 $f6
+#define ft1f $f7
+#define ft2 $f8
+#define ft2f $f9
+#define ft3 $f10
+#define ft3f $f11
+#define ft4 $f16
+#define ft4f $f17
+#define ft5 $f18
+#define ft5f $f19
+#define fs0 $f20 /* callee saved */
+#define fs0f $f21
+#define fs1 $f22
+#define fs1f $f23
+#define fs2 $f24
+#define fs2f $f25
+#define fs3 $f26
+#define fs3f $f27
+#define fs4 $f28
+#define fs4f $f29
+#define fs5 $f30
+#define fs5f $f31
+
+#define fcr31 $31 /* FPU status register */
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
+
+#define fv0 $f0 /* return value */
+#define fv1 $f2
+#define fa0 $f12 /* argument registers */
+#define fa1 $f13
+#define fa2 $f14
+#define fa3 $f15
+#define fa4 $f16
+#define fa5 $f17
+#define fa6 $f18
+#define fa7 $f19
+#define ft0 $f4 /* caller saved */
+#define ft1 $f5
+#define ft2 $f6
+#define ft3 $f7
+#define ft4 $f8
+#define ft5 $f9
+#define ft6 $f10
+#define ft7 $f11
+#define ft8 $f20
+#define ft9 $f21
+#define ft10 $f22
+#define ft11 $f23
+#define ft12 $f1
+#define ft13 $f3
+#define fs0 $f24 /* callee saved */
+#define fs1 $f25
+#define fs2 $f26
+#define fs3 $f27
+#define fs4 $f28
+#define fs5 $f29
+#define fs6 $f30
+#define fs7 $f31
+
+#define fcr31 $31
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
+
+#endif /* _ASM_FPREGDEF_H */
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
new file mode 100644
index 00000000..7fcef8ef
--- /dev/null
+++ b/arch/mips/include/asm/fpu.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2002 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_FPU_H
+#define _ASM_FPU_H
+
+#include <linux/sched.h>
+#include <linux/thread_info.h>
+#include <linux/bitops.h>
+
+#include <asm/mipsregs.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/hazards.h>
+#include <asm/processor.h>
+#include <asm/current.h>
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+#include <asm/mips_mt.h>
+#endif
+
+struct sigcontext;
+struct sigcontext32;
+
+extern void fpu_emulator_init_fpu(void);
+extern void _init_fpu(void);
+extern void _save_fp(struct task_struct *);
+extern void _restore_fp(struct task_struct *);
+
+#define __enable_fpu() \
+do { \
+ set_c0_status(ST0_CU1); \
+ enable_fpu_hazard(); \
+} while (0)
+
+#define __disable_fpu() \
+do { \
+ clear_c0_status(ST0_CU1); \
+ disable_fpu_hazard(); \
+} while (0)
+
+#define enable_fpu() \
+do { \
+ if (cpu_has_fpu) \
+ __enable_fpu(); \
+} while (0)
+
+#define disable_fpu() \
+do { \
+ if (cpu_has_fpu) \
+ __disable_fpu(); \
+} while (0)
+
+
+#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU)
+
+static inline int __is_fpu_owner(void)
+{
+ return test_thread_flag(TIF_USEDFPU);
+}
+
+static inline int is_fpu_owner(void)
+{
+ return cpu_has_fpu && __is_fpu_owner();
+}
+
+static inline void __own_fpu(void)
+{
+ __enable_fpu();
+ KSTK_STATUS(current) |= ST0_CU1;
+ set_thread_flag(TIF_USEDFPU);
+}
+
+static inline void own_fpu_inatomic(int restore)
+{
+ if (cpu_has_fpu && !__is_fpu_owner()) {
+ __own_fpu();
+ if (restore)
+ _restore_fp(current);
+ }
+}
+
+static inline void own_fpu(int restore)
+{
+ preempt_disable();
+ own_fpu_inatomic(restore);
+ preempt_enable();
+}
+
+static inline void lose_fpu(int save)
+{
+ preempt_disable();
+ if (is_fpu_owner()) {
+ if (save)
+ _save_fp(current);
+ KSTK_STATUS(current) &= ~ST0_CU1;
+ clear_thread_flag(TIF_USEDFPU);
+ __disable_fpu();
+ }
+ preempt_enable();
+}
+
+static inline void init_fpu(void)
+{
+ preempt_disable();
+ if (cpu_has_fpu) {
+ __own_fpu();
+ _init_fpu();
+ } else {
+ fpu_emulator_init_fpu();
+ }
+ preempt_enable();
+}
+
+static inline void save_fp(struct task_struct *tsk)
+{
+ if (cpu_has_fpu)
+ _save_fp(tsk);
+}
+
+static inline void restore_fp(struct task_struct *tsk)
+{
+ if (cpu_has_fpu)
+ _restore_fp(tsk);
+}
+
+static inline fpureg_t *get_fpu_regs(struct task_struct *tsk)
+{
+ if (tsk == current) {
+ preempt_disable();
+ if (is_fpu_owner())
+ _save_fp(current);
+ preempt_enable();
+ }
+
+ return tsk->thread.fpu.fpr;
+}
+
+#endif /* _ASM_FPU_H */
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
new file mode 100644
index 00000000..3b409270
--- /dev/null
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -0,0 +1,68 @@
+/*
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Further private data for which no space exists in mips_fpu_struct.
+ * This should be subsumed into the mips_fpu_struct structure as
+ * defined in processor.h as soon as the absurd wired absolute assembler
+ * offsets become dynamic at compile time.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ */
+#ifndef _ASM_FPU_EMULATOR_H
+#define _ASM_FPU_EMULATOR_H
+
+#include <asm/break.h>
+#include <asm/inst.h>
+#include <asm/local.h>
+
+#ifdef CONFIG_DEBUG_FS
+
+struct mips_fpu_emulator_stats {
+ local_t emulated;
+ local_t loads;
+ local_t stores;
+ local_t cp1ops;
+ local_t cp1xops;
+ local_t errors;
+};
+
+DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
+
+#define MIPS_FPU_EMU_INC_STATS(M) \
+do { \
+ preempt_disable(); \
+ __local_inc(&__get_cpu_var(fpuemustats).M); \
+ preempt_enable(); \
+} while (0)
+
+#else
+#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
+#endif /* CONFIG_DEBUG_FS */
+
+extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
+ unsigned long cpc);
+extern int do_dsemulret(struct pt_regs *xcp);
+
+/*
+ * Instruction inserted following the badinst to further tag the sequence
+ */
+#define BD_COOKIE 0x0000bd36 /* tne $0, $0 with baggage */
+
+/*
+ * Break instruction with special math emu break code set
+ */
+#define BREAK_MATH (0x0000000d | (BRK_MEMU << 16))
+
+#endif /* _ASM_FPU_EMULATOR_H */
diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h
new file mode 100644
index 00000000..ce35c9af
--- /dev/null
+++ b/arch/mips/include/asm/ftrace.h
@@ -0,0 +1,90 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive for
+ * more details.
+ *
+ * Copyright (C) 2009 DSLab, Lanzhou University, China
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#ifndef _ASM_MIPS_FTRACE_H
+#define _ASM_MIPS_FTRACE_H
+
+#ifdef CONFIG_FUNCTION_TRACER
+
+#define MCOUNT_ADDR ((unsigned long)(_mcount))
+#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
+
+#ifndef __ASSEMBLY__
+extern void _mcount(void);
+#define mcount _mcount
+
+#define safe_load(load, src, dst, error) \
+do { \
+ asm volatile ( \
+ "1: " load " %[" STR(dst) "], 0(%[" STR(src) "])\n"\
+ " li %[" STR(error) "], 0\n" \
+ "2:\n" \
+ \
+ ".section .fixup, \"ax\"\n" \
+ "3: li %[" STR(error) "], 1\n" \
+ " j 2b\n" \
+ ".previous\n" \
+ \
+ ".section\t__ex_table,\"a\"\n\t" \
+ STR(PTR) "\t1b, 3b\n\t" \
+ ".previous\n" \
+ \
+ : [dst] "=&r" (dst), [error] "=r" (error)\
+ : [src] "r" (src) \
+ : "memory" \
+ ); \
+} while (0)
+
+#define safe_store(store, src, dst, error) \
+do { \
+ asm volatile ( \
+ "1: " store " %[" STR(src) "], 0(%[" STR(dst) "])\n"\
+ " li %[" STR(error) "], 0\n" \
+ "2:\n" \
+ \
+ ".section .fixup, \"ax\"\n" \
+ "3: li %[" STR(error) "], 1\n" \
+ " j 2b\n" \
+ ".previous\n" \
+ \
+ ".section\t__ex_table,\"a\"\n\t"\
+ STR(PTR) "\t1b, 3b\n\t" \
+ ".previous\n" \
+ \
+ : [error] "=r" (error) \
+ : [dst] "r" (dst), [src] "r" (src)\
+ : "memory" \
+ ); \
+} while (0)
+
+#define safe_load_code(dst, src, error) \
+ safe_load(STR(lw), src, dst, error)
+#define safe_store_code(src, dst, error) \
+ safe_store(STR(sw), src, dst, error)
+
+#define safe_load_stack(dst, src, error) \
+ safe_load(STR(PTR_L), src, dst, error)
+
+#define safe_store_stack(src, dst, error) \
+ safe_store(STR(PTR_S), src, dst, error)
+
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+ return addr;
+}
+
+struct dyn_arch_ftrace {
+};
+
+#endif /* CONFIG_DYNAMIC_FTRACE */
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_FUNCTION_TRACER */
+#endif /* _ASM_MIPS_FTRACE_H */
diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h
new file mode 100644
index 00000000..6ebf1734
--- /dev/null
+++ b/arch/mips/include/asm/futex.h
@@ -0,0 +1,206 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <asm/barrier.h>
+#include <asm/errno.h>
+#include <asm/war.h>
+
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+{ \
+ if (cpu_has_llsc && R10000_LLSC_WAR) { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set mips3 \n" \
+ "1: ll %1, %4 # __futex_atomic_op \n" \
+ " .set mips0 \n" \
+ " " insn " \n" \
+ " .set mips3 \n" \
+ "2: sc $1, %2 \n" \
+ " beqzl $1, 1b \n" \
+ __WEAK_LLSC_MB \
+ "3: \n" \
+ " .set pop \n" \
+ " .set mips0 \n" \
+ " .section .fixup,\"ax\" \n" \
+ "4: li %0, %6 \n" \
+ " j 3b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " "__UA_ADDR "\t1b, 4b \n" \
+ " "__UA_ADDR "\t2b, 4b \n" \
+ " .previous \n" \
+ : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \
+ : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \
+ : "memory"); \
+ } else if (cpu_has_llsc) { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set mips3 \n" \
+ "1: ll %1, %4 # __futex_atomic_op \n" \
+ " .set mips0 \n" \
+ " " insn " \n" \
+ " .set mips3 \n" \
+ "2: sc $1, %2 \n" \
+ " beqz $1, 1b \n" \
+ __WEAK_LLSC_MB \
+ "3: \n" \
+ " .set pop \n" \
+ " .set mips0 \n" \
+ " .section .fixup,\"ax\" \n" \
+ "4: li %0, %6 \n" \
+ " j 3b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " "__UA_ADDR "\t1b, 4b \n" \
+ " "__UA_ADDR "\t2b, 4b \n" \
+ " .previous \n" \
+ : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \
+ : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \
+ : "memory"); \
+ } else \
+ ret = -ENOSYS; \
+}
+
+static inline int
+futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
+{
+ int op = (encoded_op >> 28) & 7;
+ int cmp = (encoded_op >> 24) & 15;
+ int oparg = (encoded_op << 8) >> 20;
+ int cmparg = (encoded_op << 20) >> 20;
+ int oldval = 0, ret;
+ if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+ oparg = 1 << oparg;
+
+ if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32)))
+ return -EFAULT;
+
+ pagefault_disable();
+
+ switch (op) {
+ case FUTEX_OP_SET:
+ __futex_atomic_op("move $1, %z5", ret, oldval, uaddr, oparg);
+ break;
+
+ case FUTEX_OP_ADD:
+ __futex_atomic_op("addu $1, %1, %z5",
+ ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+ __futex_atomic_op("or $1, %1, %z5",
+ ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_ANDN:
+ __futex_atomic_op("and $1, %1, %z5",
+ ret, oldval, uaddr, ~oparg);
+ break;
+ case FUTEX_OP_XOR:
+ __futex_atomic_op("xor $1, %1, %z5",
+ ret, oldval, uaddr, oparg);
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+
+ pagefault_enable();
+
+ if (!ret) {
+ switch (cmp) {
+ case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+ case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+ case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+ case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+ case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+ case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+ default: ret = -ENOSYS;
+ }
+ }
+ return ret;
+}
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ u32 oldval, u32 newval)
+{
+ int ret = 0;
+ u32 val;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ return -EFAULT;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ "# futex_atomic_cmpxchg_inatomic \n"
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: ll %1, %3 \n"
+ " bne %1, %z4, 3f \n"
+ " .set mips0 \n"
+ " move $1, %z5 \n"
+ " .set mips3 \n"
+ "2: sc $1, %2 \n"
+ " beqzl $1, 1b \n"
+ __WEAK_LLSC_MB
+ "3: \n"
+ " .set pop \n"
+ " .section .fixup,\"ax\" \n"
+ "4: li %0, %6 \n"
+ " j 3b \n"
+ " .previous \n"
+ " .section __ex_table,\"a\" \n"
+ " "__UA_ADDR "\t1b, 4b \n"
+ " "__UA_ADDR "\t2b, 4b \n"
+ " .previous \n"
+ : "+r" (ret), "=&r" (val), "=R" (*uaddr)
+ : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ __asm__ __volatile__(
+ "# futex_atomic_cmpxchg_inatomic \n"
+ " .set push \n"
+ " .set noat \n"
+ " .set mips3 \n"
+ "1: ll %1, %3 \n"
+ " bne %1, %z4, 3f \n"
+ " .set mips0 \n"
+ " move $1, %z5 \n"
+ " .set mips3 \n"
+ "2: sc $1, %2 \n"
+ " beqz $1, 1b \n"
+ __WEAK_LLSC_MB
+ "3: \n"
+ " .set pop \n"
+ " .section .fixup,\"ax\" \n"
+ "4: li %0, %6 \n"
+ " j 3b \n"
+ " .previous \n"
+ " .section __ex_table,\"a\" \n"
+ " "__UA_ADDR "\t1b, 4b \n"
+ " "__UA_ADDR "\t2b, 4b \n"
+ " .previous \n"
+ : "+r" (ret), "=&r" (val), "=R" (*uaddr)
+ : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT)
+ : "memory");
+ } else
+ return -ENOSYS;
+
+ *uval = val;
+ return ret;
+}
+
+#endif
+#endif /* _ASM_FUTEX_H */
diff --git a/arch/mips/include/asm/fw/arc/hinv.h b/arch/mips/include/asm/fw/arc/hinv.h
new file mode 100644
index 00000000..e6ff4add
--- /dev/null
+++ b/arch/mips/include/asm/fw/arc/hinv.h
@@ -0,0 +1,175 @@
+/*
+ * ARCS hardware/memory inventory/configuration and system ID definitions.
+ */
+#ifndef _ASM_ARC_HINV_H
+#define _ASM_ARC_HINV_H
+
+#include <asm/sgidefs.h>
+#include <asm/fw/arc/types.h>
+
+/* configuration query defines */
+typedef enum configclass {
+ SystemClass,
+ ProcessorClass,
+ CacheClass,
+#ifndef _NT_PROM
+ MemoryClass,
+ AdapterClass,
+ ControllerClass,
+ PeripheralClass
+#else /* _NT_PROM */
+ AdapterClass,
+ ControllerClass,
+ PeripheralClass,
+ MemoryClass
+#endif /* _NT_PROM */
+} CONFIGCLASS;
+
+typedef enum configtype {
+ ARC,
+ CPU,
+ FPU,
+ PrimaryICache,
+ PrimaryDCache,
+ SecondaryICache,
+ SecondaryDCache,
+ SecondaryCache,
+#ifndef _NT_PROM
+ Memory,
+#endif
+ EISAAdapter,
+ TCAdapter,
+ SCSIAdapter,
+ DTIAdapter,
+ MultiFunctionAdapter,
+ DiskController,
+ TapeController,
+ CDROMController,
+ WORMController,
+ SerialController,
+ NetworkController,
+ DisplayController,
+ ParallelController,
+ PointerController,
+ KeyboardController,
+ AudioController,
+ OtherController,
+ DiskPeripheral,
+ FloppyDiskPeripheral,
+ TapePeripheral,
+ ModemPeripheral,
+ MonitorPeripheral,
+ PrinterPeripheral,
+ PointerPeripheral,
+ KeyboardPeripheral,
+ TerminalPeripheral,
+ LinePeripheral,
+ NetworkPeripheral,
+#ifdef _NT_PROM
+ Memory,
+#endif
+ OtherPeripheral,
+
+ /* new stuff for IP30 */
+ /* added without moving anything */
+ /* except ANONYMOUS. */
+
+ XTalkAdapter,
+ PCIAdapter,
+ GIOAdapter,
+ TPUAdapter,
+
+ Anonymous
+} CONFIGTYPE;
+
+typedef enum {
+ Failed = 1,
+ ReadOnly = 2,
+ Removable = 4,
+ ConsoleIn = 8,
+ ConsoleOut = 16,
+ Input = 32,
+ Output = 64
+} IDENTIFIERFLAG;
+
+#ifndef NULL /* for GetChild(NULL); */
+#define NULL 0
+#endif
+
+union key_u {
+ struct {
+#ifdef _MIPSEB
+ unsigned char c_bsize; /* block size in lines */
+ unsigned char c_lsize; /* line size in bytes/tag */
+ unsigned short c_size; /* cache size in 4K pages */
+#else /* _MIPSEL */
+ unsigned short c_size; /* cache size in 4K pages */
+ unsigned char c_lsize; /* line size in bytes/tag */
+ unsigned char c_bsize; /* block size in lines */
+#endif /* _MIPSEL */
+ } cache;
+ ULONG FullKey;
+};
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+#define SGI_ARCS_VERS 64 /* sgi 64-bit version */
+#define SGI_ARCS_REV 0 /* rev .00 */
+#else
+#define SGI_ARCS_VERS 1 /* first version */
+#define SGI_ARCS_REV 10 /* rev .10, 3/04/92 */
+#endif
+
+typedef struct component {
+ CONFIGCLASS Class;
+ CONFIGTYPE Type;
+ IDENTIFIERFLAG Flags;
+ USHORT Version;
+ USHORT Revision;
+ ULONG Key;
+ ULONG AffinityMask;
+ ULONG ConfigurationDataSize;
+ ULONG IdentifierLength;
+ char *Identifier;
+} COMPONENT;
+
+/* internal structure that holds pathname parsing data */
+struct cfgdata {
+ char *name; /* full name */
+ int minlen; /* minimum length to match */
+ CONFIGTYPE type; /* type of token */
+};
+
+/* System ID */
+typedef struct systemid {
+ CHAR VendorId[8];
+ CHAR ProductId[8];
+} SYSTEMID;
+
+/* memory query functions */
+typedef enum memorytype {
+ ExceptionBlock,
+ SPBPage, /* ARCS == SystemParameterBlock */
+#ifndef _NT_PROM
+ FreeContiguous,
+ FreeMemory,
+ BadMemory,
+ LoadedProgram,
+ FirmwareTemporary,
+ FirmwarePermanent
+#else /* _NT_PROM */
+ FreeMemory,
+ BadMemory,
+ LoadedProgram,
+ FirmwareTemporary,
+ FirmwarePermanent,
+ FreeContiguous
+#endif /* _NT_PROM */
+} MEMORYTYPE;
+
+typedef struct memorydescriptor {
+ MEMORYTYPE Type;
+ LONG BasePage;
+ LONG PageCount;
+} MEMORYDESCRIPTOR;
+
+#endif /* _ASM_ARC_HINV_H */
diff --git a/arch/mips/include/asm/fw/arc/types.h b/arch/mips/include/asm/fw/arc/types.h
new file mode 100644
index 00000000..b9adcd6f
--- /dev/null
+++ b/arch/mips/include/asm/fw/arc/types.h
@@ -0,0 +1,86 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1999 Ralf Baechle (ralf@gnu.org)
+ * Copyright 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_ARC_TYPES_H
+#define _ASM_ARC_TYPES_H
+
+
+#ifdef CONFIG_ARC32
+
+typedef char CHAR;
+typedef short SHORT;
+typedef long LARGE_INTEGER __attribute__ ((__mode__ (__DI__)));
+typedef long LONG __attribute__ ((__mode__ (__SI__)));
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned long ULONG __attribute__ ((__mode__ (__SI__)));
+typedef void VOID;
+
+/* The pointer types. Note that we're using a 64-bit compiler but all
+ pointer in the ARC structures are only 32-bit, so we need some disgusting
+ workarounds. Keep your vomit bag handy. */
+typedef LONG _PCHAR;
+typedef LONG _PSHORT;
+typedef LONG _PLARGE_INTEGER;
+typedef LONG _PLONG;
+typedef LONG _PUCHAR;
+typedef LONG _PUSHORT;
+typedef LONG _PULONG;
+typedef LONG _PVOID;
+
+#endif /* CONFIG_ARC32 */
+
+#ifdef CONFIG_ARC64
+
+typedef char CHAR;
+typedef short SHORT;
+typedef long LARGE_INTEGER __attribute__ ((__mode__ (__DI__)));
+typedef long LONG __attribute__ ((__mode__ (__DI__)));
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned long ULONG __attribute__ ((__mode__ (__DI__)));
+typedef void VOID;
+
+/* The pointer types. We're 64-bit and the firmware is also 64-bit, so
+ live is sane ... */
+typedef CHAR *_PCHAR;
+typedef SHORT *_PSHORT;
+typedef LARGE_INTEGER *_PLARGE_INTEGER;
+typedef LONG *_PLONG;
+typedef UCHAR *_PUCHAR;
+typedef USHORT *_PUSHORT;
+typedef ULONG *_PULONG;
+typedef VOID *_PVOID;
+
+#endif /* CONFIG_ARC64 */
+
+typedef CHAR *PCHAR;
+typedef SHORT *PSHORT;
+typedef LARGE_INTEGER *PLARGE_INTEGER;
+typedef LONG *PLONG;
+typedef UCHAR *PUCHAR;
+typedef USHORT *PUSHORT;
+typedef ULONG *PULONG;
+typedef VOID *PVOID;
+
+/*
+ * Return type of ArcGetDisplayStatus()
+ */
+typedef struct {
+ USHORT CursorXPosition;
+ USHORT CursorYPosition;
+ USHORT CursorMaxXPosition;
+ USHORT CursorMaxYPosition;
+ USHORT ForegroundColor;
+ USHORT BackgroundColor;
+ UCHAR HighIntensity;
+ UCHAR Underscored;
+ UCHAR ReverseVideo;
+} DISPLAY_STATUS;
+
+#endif /* _ASM_ARC_TYPES_H */
diff --git a/arch/mips/include/asm/fw/cfe/cfe_api.h b/arch/mips/include/asm/fw/cfe/cfe_api.h
new file mode 100644
index 00000000..0995575d
--- /dev/null
+++ b/arch/mips/include/asm/fw/cfe/cfe_api.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * This file contains declarations for doing callbacks to
+ * cfe from an application. It should be the only header
+ * needed by the application to use this library
+ *
+ * Authors: Mitch Lichtenberg, Chris Demetriou
+ */
+#ifndef CFE_API_H
+#define CFE_API_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+typedef long intptr_t;
+
+
+/*
+ * Constants
+ */
+
+/* Seal indicating CFE's presence, passed to user program. */
+#define CFE_EPTSEAL 0x43464531
+
+#define CFE_MI_RESERVED 0 /* memory is reserved, do not use */
+#define CFE_MI_AVAILABLE 1 /* memory is available */
+
+#define CFE_FLG_WARMSTART 0x00000001
+#define CFE_FLG_FULL_ARENA 0x00000001
+#define CFE_FLG_ENV_PERMANENT 0x00000001
+
+#define CFE_CPU_CMD_START 1
+#define CFE_CPU_CMD_STOP 0
+
+#define CFE_STDHANDLE_CONSOLE 0
+
+#define CFE_DEV_NETWORK 1
+#define CFE_DEV_DISK 2
+#define CFE_DEV_FLASH 3
+#define CFE_DEV_SERIAL 4
+#define CFE_DEV_CPU 5
+#define CFE_DEV_NVRAM 6
+#define CFE_DEV_CLOCK 7
+#define CFE_DEV_OTHER 8
+#define CFE_DEV_MASK 0x0F
+
+#define CFE_CACHE_FLUSH_D 1
+#define CFE_CACHE_INVAL_I 2
+#define CFE_CACHE_INVAL_D 4
+#define CFE_CACHE_INVAL_L2 8
+
+#define CFE_FWI_64BIT 0x00000001
+#define CFE_FWI_32BIT 0x00000002
+#define CFE_FWI_RELOC 0x00000004
+#define CFE_FWI_UNCACHED 0x00000008
+#define CFE_FWI_MULTICPU 0x00000010
+#define CFE_FWI_FUNCSIM 0x00000020
+#define CFE_FWI_RTLSIM 0x00000040
+
+typedef struct {
+ int64_t fwi_version; /* major, minor, eco version */
+ int64_t fwi_totalmem; /* total installed mem */
+ int64_t fwi_flags; /* various flags */
+ int64_t fwi_boardid; /* board ID */
+ int64_t fwi_bootarea_va; /* VA of boot area */
+ int64_t fwi_bootarea_pa; /* PA of boot area */
+ int64_t fwi_bootarea_size; /* size of boot area */
+} cfe_fwinfo_t;
+
+
+/*
+ * Defines and prototypes for functions which take no arguments.
+ */
+int64_t cfe_getticks(void);
+
+/*
+ * Defines and prototypes for the rest of the functions.
+ */
+int cfe_close(int handle);
+int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1);
+int cfe_cpu_stop(int cpu);
+int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen);
+int cfe_enummem(int idx, int flags, uint64_t * start, uint64_t * length,
+ uint64_t * type);
+int cfe_exit(int warm, int status);
+int cfe_flushcache(int flg);
+int cfe_getdevinfo(char *name);
+int cfe_getenv(char *name, char *dest, int destlen);
+int cfe_getfwinfo(cfe_fwinfo_t * info);
+int cfe_getstdhandle(int flg);
+int cfe_init(uint64_t handle, uint64_t ept);
+int cfe_inpstat(int handle);
+int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
+ int length, int *retlen, uint64_t offset);
+int cfe_open(char *name);
+int cfe_read(int handle, unsigned char *buffer, int length);
+int cfe_readblk(int handle, int64_t offset, unsigned char *buffer,
+ int length);
+int cfe_setenv(char *name, char *val);
+int cfe_write(int handle, unsigned char *buffer, int length);
+int cfe_writeblk(int handle, int64_t offset, unsigned char *buffer,
+ int length);
+
+#endif /* CFE_API_H */
diff --git a/arch/mips/include/asm/fw/cfe/cfe_error.h b/arch/mips/include/asm/fw/cfe/cfe_error.h
new file mode 100644
index 00000000..b8037463
--- /dev/null
+++ b/arch/mips/include/asm/fw/cfe/cfe_error.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * CFE's global error code list is here.
+ *
+ * Author: Mitch Lichtenberg
+ */
+
+#define CFE_OK 0
+#define CFE_ERR -1 /* generic error */
+#define CFE_ERR_INV_COMMAND -2
+#define CFE_ERR_EOF -3
+#define CFE_ERR_IOERR -4
+#define CFE_ERR_NOMEM -5
+#define CFE_ERR_DEVNOTFOUND -6
+#define CFE_ERR_DEVOPEN -7
+#define CFE_ERR_INV_PARAM -8
+#define CFE_ERR_ENVNOTFOUND -9
+#define CFE_ERR_ENVREADONLY -10
+
+#define CFE_ERR_NOTELF -11
+#define CFE_ERR_NOT32BIT -12
+#define CFE_ERR_WRONGENDIAN -13
+#define CFE_ERR_BADELFVERS -14
+#define CFE_ERR_NOTMIPS -15
+#define CFE_ERR_BADELFFMT -16
+#define CFE_ERR_BADADDR -17
+
+#define CFE_ERR_FILENOTFOUND -18
+#define CFE_ERR_UNSUPPORTED -19
+
+#define CFE_ERR_HOSTUNKNOWN -20
+
+#define CFE_ERR_TIMEOUT -21
+
+#define CFE_ERR_PROTOCOLERR -22
+
+#define CFE_ERR_NETDOWN -23
+#define CFE_ERR_NONAMESERVER -24
+
+#define CFE_ERR_NOHANDLES -25
+#define CFE_ERR_ALREADYBOUND -26
+
+#define CFE_ERR_CANNOTSET -27
+#define CFE_ERR_NOMORE -28
+#define CFE_ERR_BADFILESYS -29
+#define CFE_ERR_FSNOTAVAIL -30
+
+#define CFE_ERR_INVBOOTBLOCK -31
+#define CFE_ERR_WRONGDEVTYPE -32
+#define CFE_ERR_BBCHECKSUM -33
+#define CFE_ERR_BOOTPROGCHKSUM -34
+
+#define CFE_ERR_LDRNOTAVAIL -35
+
+#define CFE_ERR_NOTREADY -36
+
+#define CFE_ERR_GETMEM -37
+#define CFE_ERR_SETMEM -38
+
+#define CFE_ERR_NOTCONN -39
+#define CFE_ERR_ADDRINUSE -40
diff --git a/arch/mips/include/asm/gcmpregs.h b/arch/mips/include/asm/gcmpregs.h
new file mode 100644
index 00000000..c0cf76a2
--- /dev/null
+++ b/arch/mips/include/asm/gcmpregs.h
@@ -0,0 +1,125 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 07 MIPS Technologies, Inc.
+ *
+ * Multiprocessor Subsystem Register Definitions
+ *
+ */
+#ifndef _ASM_GCMPREGS_H
+#define _ASM_GCMPREGS_H
+
+
+/* Offsets to major blocks within GCMP from GCMP base */
+#define GCMP_GCB_OFS 0x0000 /* Global Control Block */
+#define GCMP_CLCB_OFS 0x2000 /* Core Local Control Block */
+#define GCMP_COCB_OFS 0x4000 /* Core Other Control Block */
+#define GCMP_GDB_OFS 0x8000 /* Global Debug Block */
+
+/* Offsets to individual GCMP registers from GCMP base */
+#define GCMPOFS(block, tag, reg) \
+ (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS)
+#define GCMPOFSn(block, tag, reg, n) \
+ (GCMP_##block##_OFS + GCMP_##tag##_##reg##_OFS(n))
+
+#define GCMPGCBOFS(reg) GCMPOFS(GCB, GCB, reg)
+#define GCMPGCBOFSn(reg, n) GCMPOFSn(GCB, GCB, reg, n)
+#define GCMPCLCBOFS(reg) GCMPOFS(CLCB, CCB, reg)
+#define GCMPCOCBOFS(reg) GCMPOFS(COCB, CCB, reg)
+#define GCMPGDBOFS(reg) GCMPOFS(GDB, GDB, reg)
+
+/* GCMP register access */
+#define GCMPGCB(reg) REGP(_gcmp_base, GCMPGCBOFS(reg))
+#define GCMPGCBn(reg, n) REGP(_gcmp_base, GCMPGCBOFSn(reg, n))
+#define GCMPCLCB(reg) REGP(_gcmp_base, GCMPCLCBOFS(reg))
+#define GCMPCOCB(reg) REGP(_gcmp_base, GCMPCOCBOFS(reg))
+#define GCMPGDB(reg) REGP(_gcmp_base, GCMPGDBOFS(reg))
+
+/* Mask generation */
+#define GCMPMSK(block, reg, bits) (MSK(bits)<<GCMP_##block##_##reg##_SHF)
+#define GCMPGCBMSK(reg, bits) GCMPMSK(GCB, reg, bits)
+#define GCMPCCBMSK(reg, bits) GCMPMSK(CCB, reg, bits)
+#define GCMPGDBMSK(reg, bits) GCMPMSK(GDB, reg, bits)
+
+/* GCB registers */
+#define GCMP_GCB_GC_OFS 0x0000 /* Global Config Register */
+#define GCMP_GCB_GC_NUMIOCU_SHF 8
+#define GCMP_GCB_GC_NUMIOCU_MSK GCMPGCBMSK(GC_NUMIOCU, 4)
+#define GCMP_GCB_GC_NUMCORES_SHF 0
+#define GCMP_GCB_GC_NUMCORES_MSK GCMPGCBMSK(GC_NUMCORES, 8)
+#define GCMP_GCB_GCMPB_OFS 0x0008 /* Global GCMP Base */
+#define GCMP_GCB_GCMPB_GCMPBASE_SHF 15
+#define GCMP_GCB_GCMPB_GCMPBASE_MSK GCMPGCBMSK(GCMPB_GCMPBASE, 17)
+#define GCMP_GCB_GCMPB_CMDEFTGT_SHF 0
+#define GCMP_GCB_GCMPB_CMDEFTGT_MSK GCMPGCBMSK(GCMPB_CMDEFTGT, 2)
+#define GCMP_GCB_GCMPB_CMDEFTGT_DISABLED 0
+#define GCMP_GCB_GCMPB_CMDEFTGT_MEM 1
+#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU1 2
+#define GCMP_GCB_GCMPB_CMDEFTGT_IOCU2 3
+#define GCMP_GCB_CCMC_OFS 0x0010 /* Global CM Control */
+#define GCMP_GCB_GCSRAP_OFS 0x0020 /* Global CSR Access Privilege */
+#define GCMP_GCB_GCSRAP_CMACCESS_SHF 0
+#define GCMP_GCB_GCSRAP_CMACCESS_MSK GCMPGCBMSK(GCSRAP_CMACCESS, 8)
+#define GCMP_GCB_GCMPREV_OFS 0x0030 /* GCMP Revision Register */
+#define GCMP_GCB_GCMEM_OFS 0x0040 /* Global CM Error Mask */
+#define GCMP_GCB_GCMEC_OFS 0x0048 /* Global CM Error Cause */
+#define GCMP_GCB_GMEC_ERROR_TYPE_SHF 27
+#define GCMP_GCB_GMEC_ERROR_TYPE_MSK GCMPGCBMSK(GMEC_ERROR_TYPE, 5)
+#define GCMP_GCB_GMEC_ERROR_INFO_SHF 0
+#define GCMP_GCB_GMEC_ERROR_INFO_MSK GCMPGCBMSK(GMEC_ERROR_INFO, 27)
+#define GCMP_GCB_GCMEA_OFS 0x0050 /* Global CM Error Address */
+#define GCMP_GCB_GCMEO_OFS 0x0058 /* Global CM Error Multiple */
+#define GCMP_GCB_GMEO_ERROR_2ND_SHF 0
+#define GCMP_GCB_GMEO_ERROR_2ND_MSK GCMPGCBMSK(GMEO_ERROR_2ND, 5)
+#define GCMP_GCB_GICBA_OFS 0x0080 /* Global Interrupt Controller Base Address */
+#define GCMP_GCB_GICBA_BASE_SHF 17
+#define GCMP_GCB_GICBA_BASE_MSK GCMPGCBMSK(GICBA_BASE, 15)
+#define GCMP_GCB_GICBA_EN_SHF 0
+#define GCMP_GCB_GICBA_EN_MSK GCMPGCBMSK(GICBA_EN, 1)
+
+/* GCB Regions */
+#define GCMP_GCB_CMxBASE_OFS(n) (0x0090+16*(n)) /* Global Region[0-3] Base Address */
+#define GCMP_GCB_CMxBASE_BASE_SHF 16
+#define GCMP_GCB_CMxBASE_BASE_MSK GCMPGCBMSK(CMxBASE_BASE, 16)
+#define GCMP_GCB_CMxMASK_OFS(n) (0x0098+16*(n)) /* Global Region[0-3] Address Mask */
+#define GCMP_GCB_CMxMASK_MASK_SHF 16
+#define GCMP_GCB_CMxMASK_MASK_MSK GCMPGCBMSK(CMxMASK_MASK, 16)
+#define GCMP_GCB_CMxMASK_CMREGTGT_SHF 0
+#define GCMP_GCB_CMxMASK_CMREGTGT_MSK GCMPGCBMSK(CMxMASK_CMREGTGT, 2)
+#define GCMP_GCB_CMxMASK_CMREGTGT_MEM 0
+#define GCMP_GCB_CMxMASK_CMREGTGT_MEM1 1
+#define GCMP_GCB_CMxMASK_CMREGTGT_IOCU1 2
+#define GCMP_GCB_CMxMASK_CMREGTGT_IOCU2 3
+
+
+/* Core local/Core other control block registers */
+#define GCMP_CCB_RESETR_OFS 0x0000 /* Reset Release */
+#define GCMP_CCB_RESETR_INRESET_SHF 0
+#define GCMP_CCB_RESETR_INRESET_MSK GCMPCCBMSK(RESETR_INRESET, 16)
+#define GCMP_CCB_COHCTL_OFS 0x0008 /* Coherence Control */
+#define GCMP_CCB_COHCTL_DOMAIN_SHF 0
+#define GCMP_CCB_COHCTL_DOMAIN_MSK GCMPCCBMSK(COHCTL_DOMAIN, 8)
+#define GCMP_CCB_CFG_OFS 0x0010 /* Config */
+#define GCMP_CCB_CFG_IOCUTYPE_SHF 10
+#define GCMP_CCB_CFG_IOCUTYPE_MSK GCMPCCBMSK(CFG_IOCUTYPE, 2)
+#define GCMP_CCB_CFG_IOCUTYPE_CPU 0
+#define GCMP_CCB_CFG_IOCUTYPE_NCIOCU 1
+#define GCMP_CCB_CFG_IOCUTYPE_CIOCU 2
+#define GCMP_CCB_CFG_NUMVPE_SHF 0
+#define GCMP_CCB_CFG_NUMVPE_MSK GCMPCCBMSK(CFG_NUMVPE, 10)
+#define GCMP_CCB_OTHER_OFS 0x0018 /* Other Address */
+#define GCMP_CCB_OTHER_CORENUM_SHF 16
+#define GCMP_CCB_OTHER_CORENUM_MSK GCMPCCBMSK(OTHER_CORENUM, 16)
+#define GCMP_CCB_RESETBASE_OFS 0x0020 /* Reset Exception Base */
+#define GCMP_CCB_RESETBASE_BEV_SHF 12
+#define GCMP_CCB_RESETBASE_BEV_MSK GCMPCCBMSK(RESETBASE_BEV, 20)
+#define GCMP_CCB_ID_OFS 0x0028 /* Identification */
+#define GCMP_CCB_DINTGROUP_OFS 0x0030 /* DINT Group Participate */
+#define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */
+
+extern int __init gcmp_probe(unsigned long, unsigned long);
+extern int __init gcmp_niocu(void);
+extern void __init gcmp_setregion(int, unsigned long, unsigned long, int);
+#endif /* _ASM_GCMPREGS_H */
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
new file mode 100644
index 00000000..86548da6
--- /dev/null
+++ b/arch/mips/include/asm/gic.h
@@ -0,0 +1,342 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 07 MIPS Technologies, Inc.
+ *
+ * GIC Register Definitions
+ *
+ */
+#ifndef _ASM_GICREGS_H
+#define _ASM_GICREGS_H
+
+#undef GICISBYTELITTLEENDIAN
+
+/* Constants */
+#define GIC_POL_POS 1
+#define GIC_POL_NEG 0
+#define GIC_TRIG_EDGE 1
+#define GIC_TRIG_LEVEL 0
+
+#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
+
+#define MSK(n) ((1 << (n)) - 1)
+#define REG32(addr) (*(volatile unsigned int *) (addr))
+#define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS)
+#define REGP(base, phys) REG32((unsigned long)(base) + (phys))
+
+/* Accessors */
+#define GIC_REG(segment, offset) \
+ REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
+#define GIC_REG_ADDR(segment, offset) \
+ REG32(_gic_base + segment##_##SECTION_OFS + offset)
+
+#define GIC_ABS_REG(segment, offset) \
+ (_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
+#define GIC_REG_ABS_ADDR(segment, offset) \
+ (_gic_base + segment##_##SECTION_OFS + offset)
+
+#ifdef GICISBYTELITTLEENDIAN
+#define GICREAD(reg, data) (data) = (reg), (data) = le32_to_cpu(data)
+#define GICWRITE(reg, data) (reg) = cpu_to_le32(data)
+#define GICBIS(reg, bits) \
+ ({unsigned int data; \
+ GICREAD(reg, data); \
+ data |= bits; \
+ GICWRITE(reg, data); \
+ })
+
+#else
+#define GICREAD(reg, data) (data) = (reg)
+#define GICWRITE(reg, data) (reg) = (data)
+#define GICBIS(reg, bits) (reg) |= (bits)
+#endif
+
+
+/* GIC Address Space */
+#define SHARED_SECTION_OFS 0x0000
+#define SHARED_SECTION_SIZE 0x8000
+#define VPE_LOCAL_SECTION_OFS 0x8000
+#define VPE_LOCAL_SECTION_SIZE 0x4000
+#define VPE_OTHER_SECTION_OFS 0xc000
+#define VPE_OTHER_SECTION_SIZE 0x4000
+#define USM_VISIBLE_SECTION_OFS 0x10000
+#define USM_VISIBLE_SECTION_SIZE 0x10000
+
+/* Register Map for Shared Section */
+
+#define GIC_SH_CONFIG_OFS 0x0000
+
+/* Shared Global Counter */
+#define GIC_SH_COUNTER_31_00_OFS 0x0010
+#define GIC_SH_COUNTER_63_32_OFS 0x0014
+#define GIC_SH_REVISIONID_OFS 0x0020
+
+/* Interrupt Polarity */
+#define GIC_SH_POL_31_0_OFS 0x0100
+#define GIC_SH_POL_63_32_OFS 0x0104
+#define GIC_SH_POL_95_64_OFS 0x0108
+#define GIC_SH_POL_127_96_OFS 0x010c
+#define GIC_SH_POL_159_128_OFS 0x0110
+#define GIC_SH_POL_191_160_OFS 0x0114
+#define GIC_SH_POL_223_192_OFS 0x0118
+#define GIC_SH_POL_255_224_OFS 0x011c
+
+/* Edge/Level Triggering */
+#define GIC_SH_TRIG_31_0_OFS 0x0180
+#define GIC_SH_TRIG_63_32_OFS 0x0184
+#define GIC_SH_TRIG_95_64_OFS 0x0188
+#define GIC_SH_TRIG_127_96_OFS 0x018c
+#define GIC_SH_TRIG_159_128_OFS 0x0190
+#define GIC_SH_TRIG_191_160_OFS 0x0194
+#define GIC_SH_TRIG_223_192_OFS 0x0198
+#define GIC_SH_TRIG_255_224_OFS 0x019c
+
+/* Dual Edge Triggering */
+#define GIC_SH_DUAL_31_0_OFS 0x0200
+#define GIC_SH_DUAL_63_32_OFS 0x0204
+#define GIC_SH_DUAL_95_64_OFS 0x0208
+#define GIC_SH_DUAL_127_96_OFS 0x020c
+#define GIC_SH_DUAL_159_128_OFS 0x0210
+#define GIC_SH_DUAL_191_160_OFS 0x0214
+#define GIC_SH_DUAL_223_192_OFS 0x0218
+#define GIC_SH_DUAL_255_224_OFS 0x021c
+
+/* Set/Clear corresponding bit in Edge Detect Register */
+#define GIC_SH_WEDGE_OFS 0x0280
+
+/* Reset Mask - Disables Interrupt */
+#define GIC_SH_RMASK_31_0_OFS 0x0300
+#define GIC_SH_RMASK_63_32_OFS 0x0304
+#define GIC_SH_RMASK_95_64_OFS 0x0308
+#define GIC_SH_RMASK_127_96_OFS 0x030c
+#define GIC_SH_RMASK_159_128_OFS 0x0310
+#define GIC_SH_RMASK_191_160_OFS 0x0314
+#define GIC_SH_RMASK_223_192_OFS 0x0318
+#define GIC_SH_RMASK_255_224_OFS 0x031c
+
+/* Set Mask (WO) - Enables Interrupt */
+#define GIC_SH_SMASK_31_0_OFS 0x0380
+#define GIC_SH_SMASK_63_32_OFS 0x0384
+#define GIC_SH_SMASK_95_64_OFS 0x0388
+#define GIC_SH_SMASK_127_96_OFS 0x038c
+#define GIC_SH_SMASK_159_128_OFS 0x0390
+#define GIC_SH_SMASK_191_160_OFS 0x0394
+#define GIC_SH_SMASK_223_192_OFS 0x0398
+#define GIC_SH_SMASK_255_224_OFS 0x039c
+
+/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
+#define GIC_SH_MASK_31_0_OFS 0x0400
+#define GIC_SH_MASK_63_32_OFS 0x0404
+#define GIC_SH_MASK_95_64_OFS 0x0408
+#define GIC_SH_MASK_127_96_OFS 0x040c
+#define GIC_SH_MASK_159_128_OFS 0x0410
+#define GIC_SH_MASK_191_160_OFS 0x0414
+#define GIC_SH_MASK_223_192_OFS 0x0418
+#define GIC_SH_MASK_255_224_OFS 0x041c
+
+/* Pending Global Interrupts (RO) */
+#define GIC_SH_PEND_31_0_OFS 0x0480
+#define GIC_SH_PEND_63_32_OFS 0x0484
+#define GIC_SH_PEND_95_64_OFS 0x0488
+#define GIC_SH_PEND_127_96_OFS 0x048c
+#define GIC_SH_PEND_159_128_OFS 0x0490
+#define GIC_SH_PEND_191_160_OFS 0x0494
+#define GIC_SH_PEND_223_192_OFS 0x0498
+#define GIC_SH_PEND_255_224_OFS 0x049c
+
+#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
+
+/* Maps Interrupt X to a Pin */
+#define GIC_SH_MAP_TO_PIN(intr) \
+ (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr))
+
+#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
+
+/* Maps Interrupt X to a VPE */
+#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
+ (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4))
+#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))
+
+/* Convert an interrupt number to a byte offset/bit for multi-word registers */
+#define GIC_INTR_OFS(intr) (((intr) / 32)*4)
+#define GIC_INTR_BIT(intr) ((intr) % 32)
+
+/* Polarity : Reset Value is always 0 */
+#define GIC_SH_SET_POLARITY_OFS 0x0100
+#define GIC_SET_POLARITY(intr, pol) \
+ GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \
+ GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr))
+
+/* Triggering : Reset Value is always 0 */
+#define GIC_SH_SET_TRIGGER_OFS 0x0180
+#define GIC_SET_TRIGGER(intr, trig) \
+ GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \
+ GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr))
+
+/* Mask manipulation */
+#define GIC_SH_SMASK_OFS 0x0380
+#define GIC_SET_INTR_MASK(intr) \
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \
+ GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
+#define GIC_SH_RMASK_OFS 0x0300
+#define GIC_CLR_INTR_MASK(intr) \
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \
+ GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
+
+/* Register Map for Local Section */
+#define GIC_VPE_CTL_OFS 0x0000
+#define GIC_VPE_PEND_OFS 0x0004
+#define GIC_VPE_MASK_OFS 0x0008
+#define GIC_VPE_RMASK_OFS 0x000c
+#define GIC_VPE_SMASK_OFS 0x0010
+#define GIC_VPE_WD_MAP_OFS 0x0040
+#define GIC_VPE_COMPARE_MAP_OFS 0x0044
+#define GIC_VPE_TIMER_MAP_OFS 0x0048
+#define GIC_VPE_PERFCTR_MAP_OFS 0x0050
+#define GIC_VPE_SWINT0_MAP_OFS 0x0054
+#define GIC_VPE_SWINT1_MAP_OFS 0x0058
+#define GIC_VPE_OTHER_ADDR_OFS 0x0080
+#define GIC_VPE_WD_CONFIG0_OFS 0x0090
+#define GIC_VPE_WD_COUNT0_OFS 0x0094
+#define GIC_VPE_WD_INITIAL0_OFS 0x0098
+#define GIC_VPE_COMPARE_LO_OFS 0x00a0
+#define GIC_VPE_COMPARE_HI 0x00a4
+
+#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100
+#define GIC_VPE_EIC_SS(intr) \
+ (GIC_EIC_SHADOW_SET_BASE + (4 * intr))
+
+#define GIC_VPE_EIC_VEC_BASE 0x0800
+#define GIC_VPE_EIC_VEC(intr) \
+ (GIC_VPE_EIC_VEC_BASE + (4 * intr))
+
+#define GIC_VPE_TENABLE_NMI_OFS 0x1000
+#define GIC_VPE_TENABLE_YQ_OFS 0x1004
+#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080
+#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084
+
+/* User Mode Visible Section Register Map */
+#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000
+#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004
+
+/* Masks */
+#define GIC_SH_CONFIG_COUNTSTOP_SHF 28
+#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
+
+#define GIC_SH_CONFIG_COUNTBITS_SHF 24
+#define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF)
+
+#define GIC_SH_CONFIG_NUMINTRS_SHF 16
+#define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
+
+#define GIC_SH_CONFIG_NUMVPES_SHF 0
+#define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF)
+
+#define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31))
+#define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31))
+
+#define GIC_MAP_TO_PIN_SHF 31
+#define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF)
+#define GIC_MAP_TO_NMI_SHF 30
+#define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF)
+#define GIC_MAP_TO_YQ_SHF 29
+#define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF)
+#define GIC_MAP_SHF 0
+#define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF)
+
+/* GIC_VPE_CTL Masks */
+#define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2
+#define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF)
+#define GIC_VPE_CTL_TIMER_RTBL_SHF 1
+#define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF)
+#define GIC_VPE_CTL_EIC_MODE_SHF 0
+#define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF)
+
+/* GIC_VPE_PEND Masks */
+#define GIC_VPE_PEND_WD_SHF 0
+#define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF)
+#define GIC_VPE_PEND_CMP_SHF 1
+#define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF)
+#define GIC_VPE_PEND_TIMER_SHF 2
+#define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF)
+#define GIC_VPE_PEND_PERFCOUNT_SHF 3
+#define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF)
+#define GIC_VPE_PEND_SWINT0_SHF 4
+#define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF)
+#define GIC_VPE_PEND_SWINT1_SHF 5
+#define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF)
+
+/* GIC_VPE_RMASK Masks */
+#define GIC_VPE_RMASK_WD_SHF 0
+#define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF)
+#define GIC_VPE_RMASK_CMP_SHF 1
+#define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF)
+#define GIC_VPE_RMASK_TIMER_SHF 2
+#define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF)
+#define GIC_VPE_RMASK_PERFCNT_SHF 3
+#define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF)
+#define GIC_VPE_RMASK_SWINT0_SHF 4
+#define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF)
+#define GIC_VPE_RMASK_SWINT1_SHF 5
+#define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF)
+
+/* GIC_VPE_SMASK Masks */
+#define GIC_VPE_SMASK_WD_SHF 0
+#define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF)
+#define GIC_VPE_SMASK_CMP_SHF 1
+#define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF)
+#define GIC_VPE_SMASK_TIMER_SHF 2
+#define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF)
+#define GIC_VPE_SMASK_PERFCNT_SHF 3
+#define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF)
+#define GIC_VPE_SMASK_SWINT0_SHF 4
+#define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF)
+#define GIC_VPE_SMASK_SWINT1_SHF 5
+#define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF)
+
+/*
+ * Set the Mapping of Interrupt X to a VPE.
+ */
+#define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \
+ GIC_SH_MAP_TO_VPE_REG_BIT(vpe))
+
+struct gic_pcpu_mask {
+ DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
+};
+
+struct gic_pending_regs {
+ DECLARE_BITMAP(pending, GIC_NUM_INTRS);
+};
+
+struct gic_intrmask_regs {
+ DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
+};
+
+/*
+ * Interrupt Meta-data specification. The ipiflag helps
+ * in building ipi_map.
+ */
+struct gic_intr_map {
+ unsigned int cpunum; /* Directed to this CPU */
+#define GIC_UNUSED 0xdead /* Dummy data */
+ unsigned int pin; /* Directed to this Pin */
+ unsigned int polarity; /* Polarity : +/- */
+ unsigned int trigtype; /* Trigger : Edge/Levl */
+ unsigned int flags; /* Misc flags */
+#define GIC_FLAG_IPI 0x01
+#define GIC_FLAG_TRANSPARENT 0x02
+};
+
+extern void gic_init(unsigned long gic_base_addr,
+ unsigned long gic_addrspace_size, struct gic_intr_map *intrmap,
+ unsigned int intrmap_size, unsigned int irqbase);
+
+extern unsigned int gic_get_int(void);
+extern void gic_send_ipi(unsigned int intr);
+extern unsigned int plat_ipi_call_int_xlate(unsigned int);
+extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
+
+#endif /* _ASM_GICREGS_H */
diff --git a/arch/mips/include/asm/gpio.h b/arch/mips/include/asm/gpio.h
new file mode 100644
index 00000000..06e46faf
--- /dev/null
+++ b/arch/mips/include/asm/gpio.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_MIPS_GPIO_H
+#define __ASM_MIPS_GPIO_H
+
+#include <gpio.h>
+
+#endif /* __ASM_MIPS_GPIO_H */
diff --git a/arch/mips/include/asm/gt64120.h b/arch/mips/include/asm/gt64120.h
new file mode 100644
index 00000000..e64b4109
--- /dev/null
+++ b/arch/mips/include/asm/gt64120.h
@@ -0,0 +1,580 @@
+/*
+ * Copyright (C) 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#ifndef _ASM_GT64120_H
+#define _ASM_GT64120_H
+
+#include <linux/clocksource.h>
+
+#include <asm/addrspace.h>
+#include <asm/byteorder.h>
+
+#define MSK(n) ((1 << (n)) - 1)
+
+/*
+ * Register offset addresses
+ */
+/* CPU Configuration. */
+#define GT_CPU_OFS 0x000
+
+#define GT_MULTI_OFS 0x120
+
+/* CPU Address Decode. */
+#define GT_SCS10LD_OFS 0x008
+#define GT_SCS10HD_OFS 0x010
+#define GT_SCS32LD_OFS 0x018
+#define GT_SCS32HD_OFS 0x020
+#define GT_CS20LD_OFS 0x028
+#define GT_CS20HD_OFS 0x030
+#define GT_CS3BOOTLD_OFS 0x038
+#define GT_CS3BOOTHD_OFS 0x040
+#define GT_PCI0IOLD_OFS 0x048
+#define GT_PCI0IOHD_OFS 0x050
+#define GT_PCI0M0LD_OFS 0x058
+#define GT_PCI0M0HD_OFS 0x060
+#define GT_ISD_OFS 0x068
+
+#define GT_PCI0M1LD_OFS 0x080
+#define GT_PCI0M1HD_OFS 0x088
+#define GT_PCI1IOLD_OFS 0x090
+#define GT_PCI1IOHD_OFS 0x098
+#define GT_PCI1M0LD_OFS 0x0a0
+#define GT_PCI1M0HD_OFS 0x0a8
+#define GT_PCI1M1LD_OFS 0x0b0
+#define GT_PCI1M1HD_OFS 0x0b8
+#define GT_PCI1M1LD_OFS 0x0b0
+#define GT_PCI1M1HD_OFS 0x0b8
+
+#define GT_SCS10AR_OFS 0x0d0
+#define GT_SCS32AR_OFS 0x0d8
+#define GT_CS20R_OFS 0x0e0
+#define GT_CS3BOOTR_OFS 0x0e8
+
+#define GT_PCI0IOREMAP_OFS 0x0f0
+#define GT_PCI0M0REMAP_OFS 0x0f8
+#define GT_PCI0M1REMAP_OFS 0x100
+#define GT_PCI1IOREMAP_OFS 0x108
+#define GT_PCI1M0REMAP_OFS 0x110
+#define GT_PCI1M1REMAP_OFS 0x118
+
+/* CPU Error Report. */
+#define GT_CPUERR_ADDRLO_OFS 0x070
+#define GT_CPUERR_ADDRHI_OFS 0x078
+
+#define GT_CPUERR_DATALO_OFS 0x128 /* GT-64120A only */
+#define GT_CPUERR_DATAHI_OFS 0x130 /* GT-64120A only */
+#define GT_CPUERR_PARITY_OFS 0x138 /* GT-64120A only */
+
+/* CPU Sync Barrier. */
+#define GT_PCI0SYNC_OFS 0x0c0
+#define GT_PCI1SYNC_OFS 0x0c8
+
+/* SDRAM and Device Address Decode. */
+#define GT_SCS0LD_OFS 0x400
+#define GT_SCS0HD_OFS 0x404
+#define GT_SCS1LD_OFS 0x408
+#define GT_SCS1HD_OFS 0x40c
+#define GT_SCS2LD_OFS 0x410
+#define GT_SCS2HD_OFS 0x414
+#define GT_SCS3LD_OFS 0x418
+#define GT_SCS3HD_OFS 0x41c
+#define GT_CS0LD_OFS 0x420
+#define GT_CS0HD_OFS 0x424
+#define GT_CS1LD_OFS 0x428
+#define GT_CS1HD_OFS 0x42c
+#define GT_CS2LD_OFS 0x430
+#define GT_CS2HD_OFS 0x434
+#define GT_CS3LD_OFS 0x438
+#define GT_CS3HD_OFS 0x43c
+#define GT_BOOTLD_OFS 0x440
+#define GT_BOOTHD_OFS 0x444
+
+#define GT_ADERR_OFS 0x470
+
+/* SDRAM Configuration. */
+#define GT_SDRAM_CFG_OFS 0x448
+
+#define GT_SDRAM_OPMODE_OFS 0x474
+#define GT_SDRAM_BM_OFS 0x478
+#define GT_SDRAM_ADDRDECODE_OFS 0x47c
+
+/* SDRAM Parameters. */
+#define GT_SDRAM_B0_OFS 0x44c
+#define GT_SDRAM_B1_OFS 0x450
+#define GT_SDRAM_B2_OFS 0x454
+#define GT_SDRAM_B3_OFS 0x458
+
+/* Device Parameters. */
+#define GT_DEV_B0_OFS 0x45c
+#define GT_DEV_B1_OFS 0x460
+#define GT_DEV_B2_OFS 0x464
+#define GT_DEV_B3_OFS 0x468
+#define GT_DEV_BOOT_OFS 0x46c
+
+/* ECC. */
+#define GT_ECC_ERRDATALO 0x480 /* GT-64120A only */
+#define GT_ECC_ERRDATAHI 0x484 /* GT-64120A only */
+#define GT_ECC_MEM 0x488 /* GT-64120A only */
+#define GT_ECC_CALC 0x48c /* GT-64120A only */
+#define GT_ECC_ERRADDR 0x490 /* GT-64120A only */
+
+/* DMA Record. */
+#define GT_DMA0_CNT_OFS 0x800
+#define GT_DMA1_CNT_OFS 0x804
+#define GT_DMA2_CNT_OFS 0x808
+#define GT_DMA3_CNT_OFS 0x80c
+#define GT_DMA0_SA_OFS 0x810
+#define GT_DMA1_SA_OFS 0x814
+#define GT_DMA2_SA_OFS 0x818
+#define GT_DMA3_SA_OFS 0x81c
+#define GT_DMA0_DA_OFS 0x820
+#define GT_DMA1_DA_OFS 0x824
+#define GT_DMA2_DA_OFS 0x828
+#define GT_DMA3_DA_OFS 0x82c
+#define GT_DMA0_NEXT_OFS 0x830
+#define GT_DMA1_NEXT_OFS 0x834
+#define GT_DMA2_NEXT_OFS 0x838
+#define GT_DMA3_NEXT_OFS 0x83c
+
+#define GT_DMA0_CUR_OFS 0x870
+#define GT_DMA1_CUR_OFS 0x874
+#define GT_DMA2_CUR_OFS 0x878
+#define GT_DMA3_CUR_OFS 0x87c
+
+/* DMA Channel Control. */
+#define GT_DMA0_CTRL_OFS 0x840
+#define GT_DMA1_CTRL_OFS 0x844
+#define GT_DMA2_CTRL_OFS 0x848
+#define GT_DMA3_CTRL_OFS 0x84c
+
+/* DMA Arbiter. */
+#define GT_DMA_ARB_OFS 0x860
+
+/* Timer/Counter. */
+#define GT_TC0_OFS 0x850
+#define GT_TC1_OFS 0x854
+#define GT_TC2_OFS 0x858
+#define GT_TC3_OFS 0x85c
+
+#define GT_TC_CONTROL_OFS 0x864
+
+/* PCI Internal. */
+#define GT_PCI0_CMD_OFS 0xc00
+#define GT_PCI0_TOR_OFS 0xc04
+#define GT_PCI0_BS_SCS10_OFS 0xc08
+#define GT_PCI0_BS_SCS32_OFS 0xc0c
+#define GT_PCI0_BS_CS20_OFS 0xc10
+#define GT_PCI0_BS_CS3BT_OFS 0xc14
+
+#define GT_PCI1_IACK_OFS 0xc30
+#define GT_PCI0_IACK_OFS 0xc34
+
+#define GT_PCI0_BARE_OFS 0xc3c
+#define GT_PCI0_PREFMBR_OFS 0xc40
+
+#define GT_PCI0_SCS10_BAR_OFS 0xc48
+#define GT_PCI0_SCS32_BAR_OFS 0xc4c
+#define GT_PCI0_CS20_BAR_OFS 0xc50
+#define GT_PCI0_CS3BT_BAR_OFS 0xc54
+#define GT_PCI0_SSCS10_BAR_OFS 0xc58
+#define GT_PCI0_SSCS32_BAR_OFS 0xc5c
+
+#define GT_PCI0_SCS3BT_BAR_OFS 0xc64
+
+#define GT_PCI1_CMD_OFS 0xc80
+#define GT_PCI1_TOR_OFS 0xc84
+#define GT_PCI1_BS_SCS10_OFS 0xc88
+#define GT_PCI1_BS_SCS32_OFS 0xc8c
+#define GT_PCI1_BS_CS20_OFS 0xc90
+#define GT_PCI1_BS_CS3BT_OFS 0xc94
+
+#define GT_PCI1_BARE_OFS 0xcbc
+#define GT_PCI1_PREFMBR_OFS 0xcc0
+
+#define GT_PCI1_SCS10_BAR_OFS 0xcc8
+#define GT_PCI1_SCS32_BAR_OFS 0xccc
+#define GT_PCI1_CS20_BAR_OFS 0xcd0
+#define GT_PCI1_CS3BT_BAR_OFS 0xcd4
+#define GT_PCI1_SSCS10_BAR_OFS 0xcd8
+#define GT_PCI1_SSCS32_BAR_OFS 0xcdc
+
+#define GT_PCI1_SCS3BT_BAR_OFS 0xce4
+
+#define GT_PCI1_CFGADDR_OFS 0xcf0
+#define GT_PCI1_CFGDATA_OFS 0xcf4
+#define GT_PCI0_CFGADDR_OFS 0xcf8
+#define GT_PCI0_CFGDATA_OFS 0xcfc
+
+/* Interrupts. */
+#define GT_INTRCAUSE_OFS 0xc18
+#define GT_INTRMASK_OFS 0xc1c
+
+#define GT_PCI0_ICMASK_OFS 0xc24
+#define GT_PCI0_SERR0MASK_OFS 0xc28
+
+#define GT_CPU_INTSEL_OFS 0xc70
+#define GT_PCI0_INTSEL_OFS 0xc74
+
+#define GT_HINTRCAUSE_OFS 0xc98
+#define GT_HINTRMASK_OFS 0xc9c
+
+#define GT_PCI0_HICMASK_OFS 0xca4
+#define GT_PCI1_SERR1MASK_OFS 0xca8
+
+
+/*
+ * I2O Support Registers
+ */
+#define INBOUND_MESSAGE_REGISTER0_PCI_SIDE 0x010
+#define INBOUND_MESSAGE_REGISTER1_PCI_SIDE 0x014
+#define OUTBOUND_MESSAGE_REGISTER0_PCI_SIDE 0x018
+#define OUTBOUND_MESSAGE_REGISTER1_PCI_SIDE 0x01c
+#define INBOUND_DOORBELL_REGISTER_PCI_SIDE 0x020
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI_SIDE 0x024
+#define INBOUND_INTERRUPT_MASK_REGISTER_PCI_SIDE 0x028
+#define OUTBOUND_DOORBELL_REGISTER_PCI_SIDE 0x02c
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI_SIDE 0x030
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI_SIDE 0x034
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI_SIDE 0x040
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI_SIDE 0x044
+#define QUEUE_CONTROL_REGISTER_PCI_SIDE 0x050
+#define QUEUE_BASE_ADDRESS_REGISTER_PCI_SIDE 0x054
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI_SIDE 0x060
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI_SIDE 0x064
+#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI_SIDE 0x068
+#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI_SIDE 0x06c
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI_SIDE 0x070
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI_SIDE 0x074
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI_SIDE 0x078
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI_SIDE 0x07c
+
+#define INBOUND_MESSAGE_REGISTER0_CPU_SIDE 0x1c10
+#define INBOUND_MESSAGE_REGISTER1_CPU_SIDE 0x1c14
+#define OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE 0x1c18
+#define OUTBOUND_MESSAGE_REGISTER1_CPU_SIDE 0x1c1c
+#define INBOUND_DOORBELL_REGISTER_CPU_SIDE 0x1c20
+#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE 0x1c24
+#define INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE 0x1c28
+#define OUTBOUND_DOORBELL_REGISTER_CPU_SIDE 0x1c2c
+#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE 0x1c30
+#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE 0x1c34
+#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU_SIDE 0x1c40
+#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU_SIDE 0x1c44
+#define QUEUE_CONTROL_REGISTER_CPU_SIDE 0x1c50
+#define QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE 0x1c54
+#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE 0x1c60
+#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE 0x1c64
+#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE 0x1c68
+#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE 0x1c6c
+#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE 0x1c70
+#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE 0x1c74
+#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE 0x1c78
+#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE 0x1c7c
+
+/*
+ * Register encodings
+ */
+#define GT_CPU_ENDIAN_SHF 12
+#define GT_CPU_ENDIAN_MSK (MSK(1) << GT_CPU_ENDIAN_SHF)
+#define GT_CPU_ENDIAN_BIT GT_CPU_ENDIAN_MSK
+#define GT_CPU_WR_SHF 16
+#define GT_CPU_WR_MSK (MSK(1) << GT_CPU_WR_SHF)
+#define GT_CPU_WR_BIT GT_CPU_WR_MSK
+#define GT_CPU_WR_DXDXDXDX 0
+#define GT_CPU_WR_DDDD 1
+
+
+#define GT_PCI_DCRM_SHF 21
+#define GT_PCI_LD_SHF 0
+#define GT_PCI_LD_MSK (MSK(15) << GT_PCI_LD_SHF)
+#define GT_PCI_HD_SHF 0
+#define GT_PCI_HD_MSK (MSK(7) << GT_PCI_HD_SHF)
+#define GT_PCI_REMAP_SHF 0
+#define GT_PCI_REMAP_MSK (MSK(11) << GT_PCI_REMAP_SHF)
+
+
+#define GT_CFGADDR_CFGEN_SHF 31
+#define GT_CFGADDR_CFGEN_MSK (MSK(1) << GT_CFGADDR_CFGEN_SHF)
+#define GT_CFGADDR_CFGEN_BIT GT_CFGADDR_CFGEN_MSK
+
+#define GT_CFGADDR_BUSNUM_SHF 16
+#define GT_CFGADDR_BUSNUM_MSK (MSK(8) << GT_CFGADDR_BUSNUM_SHF)
+
+#define GT_CFGADDR_DEVNUM_SHF 11
+#define GT_CFGADDR_DEVNUM_MSK (MSK(5) << GT_CFGADDR_DEVNUM_SHF)
+
+#define GT_CFGADDR_FUNCNUM_SHF 8
+#define GT_CFGADDR_FUNCNUM_MSK (MSK(3) << GT_CFGADDR_FUNCNUM_SHF)
+
+#define GT_CFGADDR_REGNUM_SHF 2
+#define GT_CFGADDR_REGNUM_MSK (MSK(6) << GT_CFGADDR_REGNUM_SHF)
+
+
+#define GT_SDRAM_BM_ORDER_SHF 2
+#define GT_SDRAM_BM_ORDER_MSK (MSK(1) << GT_SDRAM_BM_ORDER_SHF)
+#define GT_SDRAM_BM_ORDER_BIT GT_SDRAM_BM_ORDER_MSK
+#define GT_SDRAM_BM_ORDER_SUB 1
+#define GT_SDRAM_BM_ORDER_LIN 0
+
+#define GT_SDRAM_BM_RSVD_ALL1 0xffb
+
+
+#define GT_SDRAM_ADDRDECODE_ADDR_SHF 0
+#define GT_SDRAM_ADDRDECODE_ADDR_MSK (MSK(3) << GT_SDRAM_ADDRDECODE_ADDR_SHF)
+#define GT_SDRAM_ADDRDECODE_ADDR_0 0
+#define GT_SDRAM_ADDRDECODE_ADDR_1 1
+#define GT_SDRAM_ADDRDECODE_ADDR_2 2
+#define GT_SDRAM_ADDRDECODE_ADDR_3 3
+#define GT_SDRAM_ADDRDECODE_ADDR_4 4
+#define GT_SDRAM_ADDRDECODE_ADDR_5 5
+#define GT_SDRAM_ADDRDECODE_ADDR_6 6
+#define GT_SDRAM_ADDRDECODE_ADDR_7 7
+
+
+#define GT_SDRAM_B0_CASLAT_SHF 0
+#define GT_SDRAM_B0_CASLAT_MSK (MSK(2) << GT_SDRAM_B0__SHF)
+#define GT_SDRAM_B0_CASLAT_2 1
+#define GT_SDRAM_B0_CASLAT_3 2
+
+#define GT_SDRAM_B0_FTDIS_SHF 2
+#define GT_SDRAM_B0_FTDIS_MSK (MSK(1) << GT_SDRAM_B0_FTDIS_SHF)
+#define GT_SDRAM_B0_FTDIS_BIT GT_SDRAM_B0_FTDIS_MSK
+
+#define GT_SDRAM_B0_SRASPRCHG_SHF 3
+#define GT_SDRAM_B0_SRASPRCHG_MSK (MSK(1) << GT_SDRAM_B0_SRASPRCHG_SHF)
+#define GT_SDRAM_B0_SRASPRCHG_BIT GT_SDRAM_B0_SRASPRCHG_MSK
+#define GT_SDRAM_B0_SRASPRCHG_2 0
+#define GT_SDRAM_B0_SRASPRCHG_3 1
+
+#define GT_SDRAM_B0_B0COMPAB_SHF 4
+#define GT_SDRAM_B0_B0COMPAB_MSK (MSK(1) << GT_SDRAM_B0_B0COMPAB_SHF)
+#define GT_SDRAM_B0_B0COMPAB_BIT GT_SDRAM_B0_B0COMPAB_MSK
+
+#define GT_SDRAM_B0_64BITINT_SHF 5
+#define GT_SDRAM_B0_64BITINT_MSK (MSK(1) << GT_SDRAM_B0_64BITINT_SHF)
+#define GT_SDRAM_B0_64BITINT_BIT GT_SDRAM_B0_64BITINT_MSK
+#define GT_SDRAM_B0_64BITINT_2 0
+#define GT_SDRAM_B0_64BITINT_4 1
+
+#define GT_SDRAM_B0_BW_SHF 6
+#define GT_SDRAM_B0_BW_MSK (MSK(1) << GT_SDRAM_B0_BW_SHF)
+#define GT_SDRAM_B0_BW_BIT GT_SDRAM_B0_BW_MSK
+#define GT_SDRAM_B0_BW_32 0
+#define GT_SDRAM_B0_BW_64 1
+
+#define GT_SDRAM_B0_BLODD_SHF 7
+#define GT_SDRAM_B0_BLODD_MSK (MSK(1) << GT_SDRAM_B0_BLODD_SHF)
+#define GT_SDRAM_B0_BLODD_BIT GT_SDRAM_B0_BLODD_MSK
+
+#define GT_SDRAM_B0_PAR_SHF 8
+#define GT_SDRAM_B0_PAR_MSK (MSK(1) << GT_SDRAM_B0_PAR_SHF)
+#define GT_SDRAM_B0_PAR_BIT GT_SDRAM_B0_PAR_MSK
+
+#define GT_SDRAM_B0_BYPASS_SHF 9
+#define GT_SDRAM_B0_BYPASS_MSK (MSK(1) << GT_SDRAM_B0_BYPASS_SHF)
+#define GT_SDRAM_B0_BYPASS_BIT GT_SDRAM_B0_BYPASS_MSK
+
+#define GT_SDRAM_B0_SRAS2SCAS_SHF 10
+#define GT_SDRAM_B0_SRAS2SCAS_MSK (MSK(1) << GT_SDRAM_B0_SRAS2SCAS_SHF)
+#define GT_SDRAM_B0_SRAS2SCAS_BIT GT_SDRAM_B0_SRAS2SCAS_MSK
+#define GT_SDRAM_B0_SRAS2SCAS_2 0
+#define GT_SDRAM_B0_SRAS2SCAS_3 1
+
+#define GT_SDRAM_B0_SIZE_SHF 11
+#define GT_SDRAM_B0_SIZE_MSK (MSK(1) << GT_SDRAM_B0_SIZE_SHF)
+#define GT_SDRAM_B0_SIZE_BIT GT_SDRAM_B0_SIZE_MSK
+#define GT_SDRAM_B0_SIZE_16M 0
+#define GT_SDRAM_B0_SIZE_64M 1
+
+#define GT_SDRAM_B0_EXTPAR_SHF 12
+#define GT_SDRAM_B0_EXTPAR_MSK (MSK(1) << GT_SDRAM_B0_EXTPAR_SHF)
+#define GT_SDRAM_B0_EXTPAR_BIT GT_SDRAM_B0_EXTPAR_MSK
+
+#define GT_SDRAM_B0_BLEN_SHF 13
+#define GT_SDRAM_B0_BLEN_MSK (MSK(1) << GT_SDRAM_B0_BLEN_SHF)
+#define GT_SDRAM_B0_BLEN_BIT GT_SDRAM_B0_BLEN_MSK
+#define GT_SDRAM_B0_BLEN_8 0
+#define GT_SDRAM_B0_BLEN_4 1
+
+
+#define GT_SDRAM_CFG_REFINT_SHF 0
+#define GT_SDRAM_CFG_REFINT_MSK (MSK(14) << GT_SDRAM_CFG_REFINT_SHF)
+
+#define GT_SDRAM_CFG_NINTERLEAVE_SHF 14
+#define GT_SDRAM_CFG_NINTERLEAVE_MSK (MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
+#define GT_SDRAM_CFG_NINTERLEAVE_BIT GT_SDRAM_CFG_NINTERLEAVE_MSK
+
+#define GT_SDRAM_CFG_RMW_SHF 15
+#define GT_SDRAM_CFG_RMW_MSK (MSK(1) << GT_SDRAM_CFG_RMW_SHF)
+#define GT_SDRAM_CFG_RMW_BIT GT_SDRAM_CFG_RMW_MSK
+
+#define GT_SDRAM_CFG_NONSTAGREF_SHF 16
+#define GT_SDRAM_CFG_NONSTAGREF_MSK (MSK(1) << GT_SDRAM_CFG_NONSTAGREF_SHF)
+#define GT_SDRAM_CFG_NONSTAGREF_BIT GT_SDRAM_CFG_NONSTAGREF_MSK
+
+#define GT_SDRAM_CFG_DUPCNTL_SHF 19
+#define GT_SDRAM_CFG_DUPCNTL_MSK (MSK(1) << GT_SDRAM_CFG_DUPCNTL_SHF)
+#define GT_SDRAM_CFG_DUPCNTL_BIT GT_SDRAM_CFG_DUPCNTL_MSK
+
+#define GT_SDRAM_CFG_DUPBA_SHF 20
+#define GT_SDRAM_CFG_DUPBA_MSK (MSK(1) << GT_SDRAM_CFG_DUPBA_SHF)
+#define GT_SDRAM_CFG_DUPBA_BIT GT_SDRAM_CFG_DUPBA_MSK
+
+#define GT_SDRAM_CFG_DUPEOT0_SHF 21
+#define GT_SDRAM_CFG_DUPEOT0_MSK (MSK(1) << GT_SDRAM_CFG_DUPEOT0_SHF)
+#define GT_SDRAM_CFG_DUPEOT0_BIT GT_SDRAM_CFG_DUPEOT0_MSK
+
+#define GT_SDRAM_CFG_DUPEOT1_SHF 22
+#define GT_SDRAM_CFG_DUPEOT1_MSK (MSK(1) << GT_SDRAM_CFG_DUPEOT1_SHF)
+#define GT_SDRAM_CFG_DUPEOT1_BIT GT_SDRAM_CFG_DUPEOT1_MSK
+
+#define GT_SDRAM_OPMODE_OP_SHF 0
+#define GT_SDRAM_OPMODE_OP_MSK (MSK(3) << GT_SDRAM_OPMODE_OP_SHF)
+#define GT_SDRAM_OPMODE_OP_NORMAL 0
+#define GT_SDRAM_OPMODE_OP_NOP 1
+#define GT_SDRAM_OPMODE_OP_PRCHG 2
+#define GT_SDRAM_OPMODE_OP_MODE 3
+#define GT_SDRAM_OPMODE_OP_CBR 4
+
+#define GT_TC_CONTROL_ENTC0_SHF 0
+#define GT_TC_CONTROL_ENTC0_MSK (MSK(1) << GT_TC_CONTROL_ENTC0_SHF)
+#define GT_TC_CONTROL_ENTC0_BIT GT_TC_CONTROL_ENTC0_MSK
+#define GT_TC_CONTROL_SELTC0_SHF 1
+#define GT_TC_CONTROL_SELTC0_MSK (MSK(1) << GT_TC_CONTROL_SELTC0_SHF)
+#define GT_TC_CONTROL_SELTC0_BIT GT_TC_CONTROL_SELTC0_MSK
+
+
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_SHF 0
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS3BOOTDIS_SHF)
+#define GT_PCI0_BARE_SWSCS3BOOTDIS_BIT GT_PCI0_BARE_SWSCS3BOOTDIS_MSK
+
+#define GT_PCI0_BARE_SWSCS32DIS_SHF 1
+#define GT_PCI0_BARE_SWSCS32DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS32DIS_SHF)
+#define GT_PCI0_BARE_SWSCS32DIS_BIT GT_PCI0_BARE_SWSCS32DIS_MSK
+
+#define GT_PCI0_BARE_SWSCS10DIS_SHF 2
+#define GT_PCI0_BARE_SWSCS10DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS10DIS_SHF)
+#define GT_PCI0_BARE_SWSCS10DIS_BIT GT_PCI0_BARE_SWSCS10DIS_MSK
+
+#define GT_PCI0_BARE_INTIODIS_SHF 3
+#define GT_PCI0_BARE_INTIODIS_MSK (MSK(1) << GT_PCI0_BARE_INTIODIS_SHF)
+#define GT_PCI0_BARE_INTIODIS_BIT GT_PCI0_BARE_INTIODIS_MSK
+
+#define GT_PCI0_BARE_INTMEMDIS_SHF 4
+#define GT_PCI0_BARE_INTMEMDIS_MSK (MSK(1) << GT_PCI0_BARE_INTMEMDIS_SHF)
+#define GT_PCI0_BARE_INTMEMDIS_BIT GT_PCI0_BARE_INTMEMDIS_MSK
+
+#define GT_PCI0_BARE_CS3BOOTDIS_SHF 5
+#define GT_PCI0_BARE_CS3BOOTDIS_MSK (MSK(1) << GT_PCI0_BARE_CS3BOOTDIS_SHF)
+#define GT_PCI0_BARE_CS3BOOTDIS_BIT GT_PCI0_BARE_CS3BOOTDIS_MSK
+
+#define GT_PCI0_BARE_CS20DIS_SHF 6
+#define GT_PCI0_BARE_CS20DIS_MSK (MSK(1) << GT_PCI0_BARE_CS20DIS_SHF)
+#define GT_PCI0_BARE_CS20DIS_BIT GT_PCI0_BARE_CS20DIS_MSK
+
+#define GT_PCI0_BARE_SCS32DIS_SHF 7
+#define GT_PCI0_BARE_SCS32DIS_MSK (MSK(1) << GT_PCI0_BARE_SCS32DIS_SHF)
+#define GT_PCI0_BARE_SCS32DIS_BIT GT_PCI0_BARE_SCS32DIS_MSK
+
+#define GT_PCI0_BARE_SCS10DIS_SHF 8
+#define GT_PCI0_BARE_SCS10DIS_MSK (MSK(1) << GT_PCI0_BARE_SCS10DIS_SHF)
+#define GT_PCI0_BARE_SCS10DIS_BIT GT_PCI0_BARE_SCS10DIS_MSK
+
+
+#define GT_INTRCAUSE_MASABORT0_SHF 18
+#define GT_INTRCAUSE_MASABORT0_MSK (MSK(1) << GT_INTRCAUSE_MASABORT0_SHF)
+#define GT_INTRCAUSE_MASABORT0_BIT GT_INTRCAUSE_MASABORT0_MSK
+
+#define GT_INTRCAUSE_TARABORT0_SHF 19
+#define GT_INTRCAUSE_TARABORT0_MSK (MSK(1) << GT_INTRCAUSE_TARABORT0_SHF)
+#define GT_INTRCAUSE_TARABORT0_BIT GT_INTRCAUSE_TARABORT0_MSK
+
+
+#define GT_PCI0_CFGADDR_REGNUM_SHF 2
+#define GT_PCI0_CFGADDR_REGNUM_MSK (MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF)
+#define GT_PCI0_CFGADDR_FUNCTNUM_SHF 8
+#define GT_PCI0_CFGADDR_FUNCTNUM_MSK (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
+#define GT_PCI0_CFGADDR_DEVNUM_SHF 11
+#define GT_PCI0_CFGADDR_DEVNUM_MSK (MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF)
+#define GT_PCI0_CFGADDR_BUSNUM_SHF 16
+#define GT_PCI0_CFGADDR_BUSNUM_MSK (MSK(8) << GT_PCI0_CFGADDR_BUSNUM_SHF)
+#define GT_PCI0_CFGADDR_CONFIGEN_SHF 31
+#define GT_PCI0_CFGADDR_CONFIGEN_MSK (MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF)
+#define GT_PCI0_CFGADDR_CONFIGEN_BIT GT_PCI0_CFGADDR_CONFIGEN_MSK
+
+#define GT_PCI0_CMD_MBYTESWAP_SHF 0
+#define GT_PCI0_CMD_MBYTESWAP_MSK (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
+#define GT_PCI0_CMD_MBYTESWAP_BIT GT_PCI0_CMD_MBYTESWAP_MSK
+#define GT_PCI0_CMD_MWORDSWAP_SHF 10
+#define GT_PCI0_CMD_MWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
+#define GT_PCI0_CMD_MWORDSWAP_BIT GT_PCI0_CMD_MWORDSWAP_MSK
+#define GT_PCI0_CMD_SBYTESWAP_SHF 16
+#define GT_PCI0_CMD_SBYTESWAP_MSK (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
+#define GT_PCI0_CMD_SBYTESWAP_BIT GT_PCI0_CMD_SBYTESWAP_MSK
+#define GT_PCI0_CMD_SWORDSWAP_SHF 11
+#define GT_PCI0_CMD_SWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
+#define GT_PCI0_CMD_SWORDSWAP_BIT GT_PCI0_CMD_SWORDSWAP_MSK
+
+#define GT_INTR_T0EXP_SHF 8
+#define GT_INTR_T0EXP_MSK (MSK(1) << GT_INTR_T0EXP_SHF)
+#define GT_INTR_T0EXP_BIT GT_INTR_T0EXP_MSK
+#define GT_INTR_RETRYCTR0_SHF 20
+#define GT_INTR_RETRYCTR0_MSK (MSK(1) << GT_INTR_RETRYCTR0_SHF)
+#define GT_INTR_RETRYCTR0_BIT GT_INTR_RETRYCTR0_MSK
+
+/*
+ * Misc
+ */
+#define GT_DEF_PCI0_IO_BASE 0x10000000UL
+#define GT_DEF_PCI0_IO_SIZE 0x02000000UL
+#define GT_DEF_PCI0_MEM0_BASE 0x12000000UL
+#define GT_DEF_PCI0_MEM0_SIZE 0x02000000UL
+#define GT_DEF_BASE 0x14000000UL
+
+#define GT_MAX_BANKSIZE (256 * 1024 * 1024) /* Max 256MB bank */
+#define GT_LATTIM_MIN 6 /* Minimum lat */
+
+/*
+ * The gt64120_dep.h file must define the following macros
+ *
+ * GT_READ(ofs, data_pointer)
+ * GT_WRITE(ofs, data) - read/write GT64120 registers in 32bit
+ *
+ * TIMER - gt64120 timer irq, temporary solution until
+ * full gt64120 cascade interrupt support is in place
+ */
+
+#include <mach-gt64120.h>
+
+/*
+ * Because of an error/peculiarity in the Galileo chip, we need to swap the
+ * bytes when running bigendian. We also provide non-swapping versions.
+ */
+#define __GT_READ(ofs) \
+ (*(volatile u32 *)(GT64120_BASE+(ofs)))
+#define __GT_WRITE(ofs, data) \
+ do { *(volatile u32 *)(GT64120_BASE+(ofs)) = (data); } while (0)
+#define GT_READ(ofs) le32_to_cpu(__GT_READ(ofs))
+#define GT_WRITE(ofs, data) __GT_WRITE(ofs, cpu_to_le32(data))
+
+extern void gt641xx_set_base_clock(unsigned int clock);
+extern int gt641xx_timer0_state(void);
+
+#endif /* _ASM_GT64120_H */
diff --git a/arch/mips/include/asm/hardirq.h b/arch/mips/include/asm/hardirq.h
new file mode 100644
index 00000000..c977a86c
--- /dev/null
+++ b/arch/mips/include/asm/hardirq.h
@@ -0,0 +1,18 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 98, 99, 2000, 01, 05 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_HARDIRQ_H
+#define _ASM_HARDIRQ_H
+
+extern void ack_bad_irq(unsigned int irq);
+#define ack_bad_irq ack_bad_irq
+
+#include <asm-generic/hardirq.h>
+
+#endif /* _ASM_HARDIRQ_H */
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
new file mode 100644
index 00000000..4e332165
--- /dev/null
+++ b/arch/mips/include/asm/hazards.h
@@ -0,0 +1,273 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 04, 07 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) MIPS Technologies, Inc.
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef _ASM_HAZARDS_H
+#define _ASM_HAZARDS_H
+
+#ifdef __ASSEMBLY__
+#define ASMMACRO(name, code...) .macro name; code; .endm
+#else
+
+#include <asm/cpu-features.h>
+
+#define ASMMACRO(name, code...) \
+__asm__(".macro " #name "; " #code "; .endm"); \
+ \
+static inline void name(void) \
+{ \
+ __asm__ __volatile__ (#name); \
+}
+
+/*
+ * MIPS R2 instruction hazard barrier. Needs to be called as a subroutine.
+ */
+extern void mips_ihb(void);
+
+#endif
+
+ASMMACRO(_ssnop,
+ sll $0, $0, 1
+ )
+
+ASMMACRO(_ehb,
+ sll $0, $0, 3
+ )
+
+/*
+ * TLB hazards
+ */
+#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_CPU_CAVIUM_OCTEON)
+
+/*
+ * MIPSR2 defines ehb for hazard avoidance
+ */
+
+ASMMACRO(mtc0_tlbw_hazard,
+ _ehb
+ )
+ASMMACRO(tlbw_use_hazard,
+ _ehb
+ )
+ASMMACRO(tlb_probe_hazard,
+ _ehb
+ )
+ASMMACRO(irq_enable_hazard,
+ _ehb
+ )
+ASMMACRO(irq_disable_hazard,
+ _ehb
+ )
+ASMMACRO(back_to_back_c0_hazard,
+ _ehb
+ )
+/*
+ * gcc has a tradition of misscompiling the previous construct using the
+ * address of a label as argument to inline assembler. Gas otoh has the
+ * annoying difference between la and dla which are only usable for 32-bit
+ * rsp. 64-bit code, so can't be used without conditional compilation.
+ * The alterantive is switching the assembler to 64-bit code which happens
+ * to work right even for 32-bit code ...
+ */
+#define instruction_hazard() \
+do { \
+ unsigned long tmp; \
+ \
+ __asm__ __volatile__( \
+ " .set mips64r2 \n" \
+ " dla %0, 1f \n" \
+ " jr.hb %0 \n" \
+ " .set mips0 \n" \
+ "1: \n" \
+ : "=r" (tmp)); \
+} while (0)
+
+#elif defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MIPS_ALCHEMY)
+
+/*
+ * These are slightly complicated by the fact that we guarantee R1 kernels to
+ * run fine on R2 processors.
+ */
+ASMMACRO(mtc0_tlbw_hazard,
+ _ssnop; _ssnop; _ehb
+ )
+ASMMACRO(tlbw_use_hazard,
+ _ssnop; _ssnop; _ssnop; _ehb
+ )
+ASMMACRO(tlb_probe_hazard,
+ _ssnop; _ssnop; _ssnop; _ehb
+ )
+ASMMACRO(irq_enable_hazard,
+ _ssnop; _ssnop; _ssnop; _ehb
+ )
+ASMMACRO(irq_disable_hazard,
+ _ssnop; _ssnop; _ssnop; _ehb
+ )
+ASMMACRO(back_to_back_c0_hazard,
+ _ssnop; _ssnop; _ssnop; _ehb
+ )
+/*
+ * gcc has a tradition of misscompiling the previous construct using the
+ * address of a label as argument to inline assembler. Gas otoh has the
+ * annoying difference between la and dla which are only usable for 32-bit
+ * rsp. 64-bit code, so can't be used without conditional compilation.
+ * The alterantive is switching the assembler to 64-bit code which happens
+ * to work right even for 32-bit code ...
+ */
+#define __instruction_hazard() \
+do { \
+ unsigned long tmp; \
+ \
+ __asm__ __volatile__( \
+ " .set mips64r2 \n" \
+ " dla %0, 1f \n" \
+ " jr.hb %0 \n" \
+ " .set mips0 \n" \
+ "1: \n" \
+ : "=r" (tmp)); \
+} while (0)
+
+#define instruction_hazard() \
+do { \
+ if (cpu_has_mips_r2) \
+ __instruction_hazard(); \
+} while (0)
+
+#elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
+ defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
+ defined(CONFIG_CPU_R5500)
+
+/*
+ * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
+ */
+
+ASMMACRO(mtc0_tlbw_hazard,
+ )
+ASMMACRO(tlbw_use_hazard,
+ )
+ASMMACRO(tlb_probe_hazard,
+ )
+ASMMACRO(irq_enable_hazard,
+ )
+ASMMACRO(irq_disable_hazard,
+ )
+ASMMACRO(back_to_back_c0_hazard,
+ )
+#define instruction_hazard() do { } while (0)
+
+#elif defined(CONFIG_CPU_RM9000)
+
+/*
+ * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent
+ * use of the JTLB for instructions should not occur for 4 cpu cycles and use
+ * for data translations should not occur for 3 cpu cycles.
+ */
+
+ASMMACRO(mtc0_tlbw_hazard,
+ _ssnop; _ssnop; _ssnop; _ssnop
+ )
+ASMMACRO(tlbw_use_hazard,
+ _ssnop; _ssnop; _ssnop; _ssnop
+ )
+ASMMACRO(tlb_probe_hazard,
+ _ssnop; _ssnop; _ssnop; _ssnop
+ )
+ASMMACRO(irq_enable_hazard,
+ )
+ASMMACRO(irq_disable_hazard,
+ )
+ASMMACRO(back_to_back_c0_hazard,
+ )
+#define instruction_hazard() do { } while (0)
+
+#elif defined(CONFIG_CPU_SB1)
+
+/*
+ * Mostly like R4000 for historic reasons
+ */
+ASMMACRO(mtc0_tlbw_hazard,
+ )
+ASMMACRO(tlbw_use_hazard,
+ )
+ASMMACRO(tlb_probe_hazard,
+ )
+ASMMACRO(irq_enable_hazard,
+ )
+ASMMACRO(irq_disable_hazard,
+ _ssnop; _ssnop; _ssnop
+ )
+ASMMACRO(back_to_back_c0_hazard,
+ )
+#define instruction_hazard() do { } while (0)
+
+#else
+
+/*
+ * Finally the catchall case for all other processors including R4000, R4400,
+ * R4600, R4700, R5000, RM7000, NEC VR41xx etc.
+ *
+ * The taken branch will result in a two cycle penalty for the two killed
+ * instructions on R4000 / R4400. Other processors only have a single cycle
+ * hazard so this is nice trick to have an optimal code for a range of
+ * processors.
+ */
+ASMMACRO(mtc0_tlbw_hazard,
+ nop; nop
+ )
+ASMMACRO(tlbw_use_hazard,
+ nop; nop; nop
+ )
+ASMMACRO(tlb_probe_hazard,
+ nop; nop; nop
+ )
+ASMMACRO(irq_enable_hazard,
+ _ssnop; _ssnop; _ssnop;
+ )
+ASMMACRO(irq_disable_hazard,
+ nop; nop; nop
+ )
+ASMMACRO(back_to_back_c0_hazard,
+ _ssnop; _ssnop; _ssnop;
+ )
+#define instruction_hazard() do { } while (0)
+
+#endif
+
+
+/* FPU hazards */
+
+#if defined(CONFIG_CPU_SB1)
+ASMMACRO(enable_fpu_hazard,
+ .set push;
+ .set mips64;
+ .set noreorder;
+ _ssnop;
+ bnezl $0, .+4;
+ _ssnop;
+ .set pop
+)
+ASMMACRO(disable_fpu_hazard,
+)
+
+#elif defined(CONFIG_CPU_MIPSR2)
+ASMMACRO(enable_fpu_hazard,
+ _ehb
+)
+ASMMACRO(disable_fpu_hazard,
+ _ehb
+)
+#else
+ASMMACRO(enable_fpu_hazard,
+ nop; nop; nop; nop
+)
+ASMMACRO(disable_fpu_hazard,
+ _ehb
+)
+#endif
+
+#endif /* _ASM_HAZARDS_H */
diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h
new file mode 100644
index 00000000..77e64408
--- /dev/null
+++ b/arch/mips/include/asm/highmem.h
@@ -0,0 +1,63 @@
+/*
+ * highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual addresses.
+ *
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ * Gerhard.Wichert@pdb.siemens.de
+ *
+ *
+ * Redesigned the x86 32-bit VM architecture to deal with
+ * up to 16 Terabyte physical memory. With current x86 CPUs
+ * we now support up to 64 Gigabytes physical RAM.
+ *
+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+ */
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <asm/kmap_types.h>
+
+/* undef for production */
+#define HIGHMEM_DEBUG 1
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+extern pte_t *pkmap_page_table;
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define LAST_PKMAP 1024
+#define LAST_PKMAP_MASK (LAST_PKMAP-1)
+#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern void * kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+extern void *__kmap_atomic(struct page *page);
+extern void __kunmap_atomic(void *kvaddr);
+extern void *kmap_atomic_pfn(unsigned long pfn);
+extern struct page *kmap_atomic_to_page(void *ptr);
+
+#define flush_cache_kmaps() flush_cache_all()
+
+extern void kmap_init(void);
+
+#define kmap_prot PAGE_KERNEL
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
new file mode 100644
index 00000000..c565b7c3
--- /dev/null
+++ b/arch/mips/include/asm/hugetlb.h
@@ -0,0 +1,115 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008, 2009 Cavium Networks, Inc.
+ */
+
+#ifndef __ASM_HUGETLB_H
+#define __ASM_HUGETLB_H
+
+#include <asm/page.h>
+
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+ unsigned long addr,
+ unsigned long len)
+{
+ return 0;
+}
+
+static inline int prepare_hugepage_range(struct file *file,
+ unsigned long addr,
+ unsigned long len)
+{
+ unsigned long task_size = STACK_TOP;
+ struct hstate *h = hstate_file(file);
+
+ if (len & ~huge_page_mask(h))
+ return -EINVAL;
+ if (addr & ~huge_page_mask(h))
+ return -EINVAL;
+ if (len > task_size)
+ return -ENOMEM;
+ if (task_size - len < addr)
+ return -EINVAL;
+ return 0;
+}
+
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+}
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+ unsigned long addr,
+ unsigned long end,
+ unsigned long floor,
+ unsigned long ceiling)
+{
+ free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ set_pte_at(mm, addr, ptep, pte);
+}
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ pte_t clear;
+ pte_t pte = *ptep;
+
+ pte_val(clear) = (unsigned long)invalid_pte_table;
+ set_pte_at(mm, addr, ptep, clear);
+ return pte;
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ flush_tlb_mm(vma->vm_mm);
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+ unsigned long val = pte_val(pte) & ~_PAGE_GLOBAL;
+ return !val || (val == (unsigned long)invalid_pte_table);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+ return pte_wrprotect(pte);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr,
+ pte_t *ptep, pte_t pte,
+ int dirty)
+{
+ return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+ return *ptep;
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+ return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+#endif /* __ASM_HUGETLB_H */
diff --git a/arch/mips/include/asm/hw_irq.h b/arch/mips/include/asm/hw_irq.h
new file mode 100644
index 00000000..77adda29
--- /dev/null
+++ b/arch/mips/include/asm/hw_irq.h
@@ -0,0 +1,20 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 2001, 2002 by Ralf Baechle
+ */
+#ifndef __ASM_HW_IRQ_H
+#define __ASM_HW_IRQ_H
+
+#include <asm/atomic.h>
+
+extern atomic_t irq_err_count;
+
+/*
+ * interrupt-retrigger: NOP for now. This may not be appropriate for all
+ * machines, we'll see ...
+ */
+
+#endif /* __ASM_HW_IRQ_H */
diff --git a/arch/mips/include/asm/i8253.h b/arch/mips/include/asm/i8253.h
new file mode 100644
index 00000000..9ad01136
--- /dev/null
+++ b/arch/mips/include/asm/i8253.h
@@ -0,0 +1,24 @@
+/*
+ * Machine specific IO port address definition for generic.
+ * Written by Osamu Tomita <tomita@cinet.co.jp>
+ */
+#ifndef __ASM_I8253_H
+#define __ASM_I8253_H
+
+#include <linux/spinlock.h>
+
+/* i8253A PIT registers */
+#define PIT_MODE 0x43
+#define PIT_CH0 0x40
+#define PIT_CH2 0x42
+
+#define PIT_LATCH LATCH
+
+extern raw_spinlock_t i8253_lock;
+
+extern void setup_pit_timer(void);
+
+#define inb_pit inb_p
+#define outb_pit outb_p
+
+#endif /* __ASM_I8253_H */
diff --git a/arch/mips/include/asm/i8259.h b/arch/mips/include/asm/i8259.h
new file mode 100644
index 00000000..c7e27844
--- /dev/null
+++ b/arch/mips/include/asm/i8259.h
@@ -0,0 +1,86 @@
+/*
+ * include/asm-mips/i8259.h
+ *
+ * i8259A interrupt definitions.
+ *
+ * Copyright (C) 2003 Maciej W. Rozycki
+ * Copyright (C) 2003 Ralf Baechle <ralf@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_I8259_H
+#define _ASM_I8259_H
+
+#include <linux/compiler.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <irq.h>
+
+/* i8259A PIC registers */
+#define PIC_MASTER_CMD 0x20
+#define PIC_MASTER_IMR 0x21
+#define PIC_MASTER_ISR PIC_MASTER_CMD
+#define PIC_MASTER_POLL PIC_MASTER_ISR
+#define PIC_MASTER_OCW3 PIC_MASTER_ISR
+#define PIC_SLAVE_CMD 0xa0
+#define PIC_SLAVE_IMR 0xa1
+
+/* i8259A PIC related value */
+#define PIC_CASCADE_IR 2
+#define MASTER_ICW4_DEFAULT 0x01
+#define SLAVE_ICW4_DEFAULT 0x01
+#define PIC_ICW4_AEOI 2
+
+extern raw_spinlock_t i8259A_lock;
+
+extern int i8259A_irq_pending(unsigned int irq);
+extern void make_8259A_irq(unsigned int irq);
+
+extern void init_i8259_irqs(void);
+
+/*
+ * Do the traditional i8259 interrupt polling thing. This is for the few
+ * cases where no better interrupt acknowledge method is available and we
+ * absolutely must touch the i8259.
+ */
+static inline int i8259_irq(void)
+{
+ int irq;
+
+ raw_spin_lock(&i8259A_lock);
+
+ /* Perform an interrupt acknowledge cycle on controller 1. */
+ outb(0x0C, PIC_MASTER_CMD); /* prepare for poll */
+ irq = inb(PIC_MASTER_CMD) & 7;
+ if (irq == PIC_CASCADE_IR) {
+ /*
+ * Interrupt is cascaded so perform interrupt
+ * acknowledge on controller 2.
+ */
+ outb(0x0C, PIC_SLAVE_CMD); /* prepare for poll */
+ irq = (inb(PIC_SLAVE_CMD) & 7) + 8;
+ }
+
+ if (unlikely(irq == 7)) {
+ /*
+ * This may be a spurious interrupt.
+ *
+ * Read the interrupt status register (ISR). If the most
+ * significant bit is not set then there is no valid
+ * interrupt.
+ */
+ outb(0x0B, PIC_MASTER_ISR); /* ISR register */
+ if(~inb(PIC_MASTER_ISR) & 0x80)
+ irq = -1;
+ }
+
+ raw_spin_unlock(&i8259A_lock);
+
+ return likely(irq >= 0) ? irq + I8259A_IRQ_BASE : irq;
+}
+
+#endif /* _ASM_I8259_H */
diff --git a/arch/mips/include/asm/ide.h b/arch/mips/include/asm/ide.h
new file mode 100644
index 00000000..bb674c3b
--- /dev/null
+++ b/arch/mips/include/asm/ide.h
@@ -0,0 +1,13 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This file contains the MIPS architecture specific IDE code.
+ */
+#ifndef __ASM_IDE_H
+#define __ASM_IDE_H
+
+#include <ide.h>
+
+#endif /* __ASM_IDE_H */
diff --git a/arch/mips/include/asm/inst.h b/arch/mips/include/asm/inst.h
new file mode 100644
index 00000000..7ebfc392
--- /dev/null
+++ b/arch/mips/include/asm/inst.h
@@ -0,0 +1,421 @@
+/*
+ * Format of an instruction in memory.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 2000 by Ralf Baechle
+ * Copyright (C) 2006 by Thiemo Seufer
+ */
+#ifndef _ASM_INST_H
+#define _ASM_INST_H
+
+/*
+ * Major opcodes; before MIPS IV cop1x was called cop3.
+ */
+enum major_op {
+ spec_op, bcond_op, j_op, jal_op,
+ beq_op, bne_op, blez_op, bgtz_op,
+ addi_op, addiu_op, slti_op, sltiu_op,
+ andi_op, ori_op, xori_op, lui_op,
+ cop0_op, cop1_op, cop2_op, cop1x_op,
+ beql_op, bnel_op, blezl_op, bgtzl_op,
+ daddi_op, daddiu_op, ldl_op, ldr_op,
+ spec2_op, jalx_op, mdmx_op, spec3_op,
+ lb_op, lh_op, lwl_op, lw_op,
+ lbu_op, lhu_op, lwr_op, lwu_op,
+ sb_op, sh_op, swl_op, sw_op,
+ sdl_op, sdr_op, swr_op, cache_op,
+ ll_op, lwc1_op, lwc2_op, pref_op,
+ lld_op, ldc1_op, ldc2_op, ld_op,
+ sc_op, swc1_op, swc2_op, major_3b_op,
+ scd_op, sdc1_op, sdc2_op, sd_op
+};
+
+/*
+ * func field of spec opcode.
+ */
+enum spec_op {
+ sll_op, movc_op, srl_op, sra_op,
+ sllv_op, pmon_op, srlv_op, srav_op,
+ jr_op, jalr_op, movz_op, movn_op,
+ syscall_op, break_op, spim_op, sync_op,
+ mfhi_op, mthi_op, mflo_op, mtlo_op,
+ dsllv_op, spec2_unused_op, dsrlv_op, dsrav_op,
+ mult_op, multu_op, div_op, divu_op,
+ dmult_op, dmultu_op, ddiv_op, ddivu_op,
+ add_op, addu_op, sub_op, subu_op,
+ and_op, or_op, xor_op, nor_op,
+ spec3_unused_op, spec4_unused_op, slt_op, sltu_op,
+ dadd_op, daddu_op, dsub_op, dsubu_op,
+ tge_op, tgeu_op, tlt_op, tltu_op,
+ teq_op, spec5_unused_op, tne_op, spec6_unused_op,
+ dsll_op, spec7_unused_op, dsrl_op, dsra_op,
+ dsll32_op, spec8_unused_op, dsrl32_op, dsra32_op
+};
+
+/*
+ * func field of spec2 opcode.
+ */
+enum spec2_op {
+ madd_op, maddu_op, mul_op, spec2_3_unused_op,
+ msub_op, msubu_op, /* more unused ops */
+ clz_op = 0x20, clo_op,
+ dclz_op = 0x24, dclo_op,
+ sdbpp_op = 0x3f
+};
+
+/*
+ * func field of spec3 opcode.
+ */
+enum spec3_op {
+ ext_op, dextm_op, dextu_op, dext_op,
+ ins_op, dinsm_op, dinsu_op, dins_op,
+ lx_op = 0x0a,
+ bshfl_op = 0x20,
+ dbshfl_op = 0x24,
+ rdhwr_op = 0x3b
+};
+
+/*
+ * rt field of bcond opcodes.
+ */
+enum rt_op {
+ bltz_op, bgez_op, bltzl_op, bgezl_op,
+ spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07,
+ tgei_op, tgeiu_op, tlti_op, tltiu_op,
+ teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op,
+ bltzal_op, bgezal_op, bltzall_op, bgezall_op,
+ rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17,
+ rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b,
+ bposge32_op, rt_op_0x1d, rt_op_0x1e, rt_op_0x1f
+};
+
+/*
+ * rs field of cop opcodes.
+ */
+enum cop_op {
+ mfc_op = 0x00, dmfc_op = 0x01,
+ cfc_op = 0x02, mtc_op = 0x04,
+ dmtc_op = 0x05, ctc_op = 0x06,
+ bc_op = 0x08, cop_op = 0x10,
+ copm_op = 0x18
+};
+
+/*
+ * rt field of cop.bc_op opcodes
+ */
+enum bcop_op {
+ bcf_op, bct_op, bcfl_op, bctl_op
+};
+
+/*
+ * func field of cop0 coi opcodes.
+ */
+enum cop0_coi_func {
+ tlbr_op = 0x01, tlbwi_op = 0x02,
+ tlbwr_op = 0x06, tlbp_op = 0x08,
+ rfe_op = 0x10, eret_op = 0x18
+};
+
+/*
+ * func field of cop0 com opcodes.
+ */
+enum cop0_com_func {
+ tlbr1_op = 0x01, tlbw_op = 0x02,
+ tlbp1_op = 0x08, dctr_op = 0x09,
+ dctw_op = 0x0a
+};
+
+/*
+ * fmt field of cop1 opcodes.
+ */
+enum cop1_fmt {
+ s_fmt, d_fmt, e_fmt, q_fmt,
+ w_fmt, l_fmt
+};
+
+/*
+ * func field of cop1 instructions using d, s or w format.
+ */
+enum cop1_sdw_func {
+ fadd_op = 0x00, fsub_op = 0x01,
+ fmul_op = 0x02, fdiv_op = 0x03,
+ fsqrt_op = 0x04, fabs_op = 0x05,
+ fmov_op = 0x06, fneg_op = 0x07,
+ froundl_op = 0x08, ftruncl_op = 0x09,
+ fceill_op = 0x0a, ffloorl_op = 0x0b,
+ fround_op = 0x0c, ftrunc_op = 0x0d,
+ fceil_op = 0x0e, ffloor_op = 0x0f,
+ fmovc_op = 0x11, fmovz_op = 0x12,
+ fmovn_op = 0x13, frecip_op = 0x15,
+ frsqrt_op = 0x16, fcvts_op = 0x20,
+ fcvtd_op = 0x21, fcvte_op = 0x22,
+ fcvtw_op = 0x24, fcvtl_op = 0x25,
+ fcmp_op = 0x30
+};
+
+/*
+ * func field of cop1x opcodes (MIPS IV).
+ */
+enum cop1x_func {
+ lwxc1_op = 0x00, ldxc1_op = 0x01,
+ pfetch_op = 0x07, swxc1_op = 0x08,
+ sdxc1_op = 0x09, madd_s_op = 0x20,
+ madd_d_op = 0x21, madd_e_op = 0x22,
+ msub_s_op = 0x28, msub_d_op = 0x29,
+ msub_e_op = 0x2a, nmadd_s_op = 0x30,
+ nmadd_d_op = 0x31, nmadd_e_op = 0x32,
+ nmsub_s_op = 0x38, nmsub_d_op = 0x39,
+ nmsub_e_op = 0x3a
+};
+
+/*
+ * func field for mad opcodes (MIPS IV).
+ */
+enum mad_func {
+ madd_fp_op = 0x08, msub_fp_op = 0x0a,
+ nmadd_fp_op = 0x0c, nmsub_fp_op = 0x0e
+};
+
+/*
+ * func field for special3 lx opcodes (Cavium Octeon).
+ */
+enum lx_func {
+ lwx_op = 0x00,
+ lhx_op = 0x04,
+ lbux_op = 0x06,
+ ldx_op = 0x08,
+ lwux_op = 0x10,
+ lhux_op = 0x14,
+ lbx_op = 0x16,
+};
+
+/*
+ * Damn ... bitfields depend from byteorder :-(
+ */
+#ifdef __MIPSEB__
+struct j_format { /* Jump format */
+ unsigned int opcode : 6;
+ unsigned int target : 26;
+};
+
+struct i_format { /* Immediate format (addi, lw, ...) */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int rt : 5;
+ signed int simmediate : 16;
+};
+
+struct u_format { /* Unsigned immediate format (ori, xori, ...) */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int rt : 5;
+ unsigned int uimmediate : 16;
+};
+
+struct c_format { /* Cache (>= R6000) format */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int c_op : 3;
+ unsigned int cache : 2;
+ unsigned int simmediate : 16;
+};
+
+struct r_format { /* Register format */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int rt : 5;
+ unsigned int rd : 5;
+ unsigned int re : 5;
+ unsigned int func : 6;
+};
+
+struct p_format { /* Performance counter format (R10000) */
+ unsigned int opcode : 6;
+ unsigned int rs : 5;
+ unsigned int rt : 5;
+ unsigned int rd : 5;
+ unsigned int re : 5;
+ unsigned int func : 6;
+};
+
+struct f_format { /* FPU register format */
+ unsigned int opcode : 6;
+ unsigned int : 1;
+ unsigned int fmt : 4;
+ unsigned int rt : 5;
+ unsigned int rd : 5;
+ unsigned int re : 5;
+ unsigned int func : 6;
+};
+
+struct ma_format { /* FPU multipy and add format (MIPS IV) */
+ unsigned int opcode : 6;
+ unsigned int fr : 5;
+ unsigned int ft : 5;
+ unsigned int fs : 5;
+ unsigned int fd : 5;
+ unsigned int func : 4;
+ unsigned int fmt : 2;
+};
+
+struct b_format { /* BREAK and SYSCALL */
+ unsigned int opcode:6;
+ unsigned int code:20;
+ unsigned int func:6;
+};
+
+#elif defined(__MIPSEL__)
+
+struct j_format { /* Jump format */
+ unsigned int target : 26;
+ unsigned int opcode : 6;
+};
+
+struct i_format { /* Immediate format */
+ signed int simmediate : 16;
+ unsigned int rt : 5;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct u_format { /* Unsigned immediate format */
+ unsigned int uimmediate : 16;
+ unsigned int rt : 5;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct c_format { /* Cache (>= R6000) format */
+ unsigned int simmediate : 16;
+ unsigned int cache : 2;
+ unsigned int c_op : 3;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct r_format { /* Register format */
+ unsigned int func : 6;
+ unsigned int re : 5;
+ unsigned int rd : 5;
+ unsigned int rt : 5;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct p_format { /* Performance counter format (R10000) */
+ unsigned int func : 6;
+ unsigned int re : 5;
+ unsigned int rd : 5;
+ unsigned int rt : 5;
+ unsigned int rs : 5;
+ unsigned int opcode : 6;
+};
+
+struct f_format { /* FPU register format */
+ unsigned int func : 6;
+ unsigned int re : 5;
+ unsigned int rd : 5;
+ unsigned int rt : 5;
+ unsigned int fmt : 4;
+ unsigned int : 1;
+ unsigned int opcode : 6;
+};
+
+struct ma_format { /* FPU multipy and add format (MIPS IV) */
+ unsigned int fmt : 2;
+ unsigned int func : 4;
+ unsigned int fd : 5;
+ unsigned int fs : 5;
+ unsigned int ft : 5;
+ unsigned int fr : 5;
+ unsigned int opcode : 6;
+};
+
+struct b_format { /* BREAK and SYSCALL */
+ unsigned int func:6;
+ unsigned int code:20;
+ unsigned int opcode:6;
+};
+
+#else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */
+#error "MIPS but neither __MIPSEL__ nor __MIPSEB__?"
+#endif
+
+union mips_instruction {
+ unsigned int word;
+ unsigned short halfword[2];
+ unsigned char byte[4];
+ struct j_format j_format;
+ struct i_format i_format;
+ struct u_format u_format;
+ struct c_format c_format;
+ struct r_format r_format;
+ struct f_format f_format;
+ struct ma_format ma_format;
+ struct b_format b_format;
+};
+
+/* HACHACHAHCAHC ... */
+
+/* In case some other massaging is needed, keep MIPSInst as wrapper */
+
+#define MIPSInst(x) x
+
+#define I_OPCODE_SFT 26
+#define MIPSInst_OPCODE(x) (MIPSInst(x) >> I_OPCODE_SFT)
+
+#define I_JTARGET_SFT 0
+#define MIPSInst_JTARGET(x) (MIPSInst(x) & 0x03ffffff)
+
+#define I_RS_SFT 21
+#define MIPSInst_RS(x) ((MIPSInst(x) & 0x03e00000) >> I_RS_SFT)
+
+#define I_RT_SFT 16
+#define MIPSInst_RT(x) ((MIPSInst(x) & 0x001f0000) >> I_RT_SFT)
+
+#define I_IMM_SFT 0
+#define MIPSInst_SIMM(x) ((int)((short)(MIPSInst(x) & 0xffff)))
+#define MIPSInst_UIMM(x) (MIPSInst(x) & 0xffff)
+
+#define I_CACHEOP_SFT 18
+#define MIPSInst_CACHEOP(x) ((MIPSInst(x) & 0x001c0000) >> I_CACHEOP_SFT)
+
+#define I_CACHESEL_SFT 16
+#define MIPSInst_CACHESEL(x) ((MIPSInst(x) & 0x00030000) >> I_CACHESEL_SFT)
+
+#define I_RD_SFT 11
+#define MIPSInst_RD(x) ((MIPSInst(x) & 0x0000f800) >> I_RD_SFT)
+
+#define I_RE_SFT 6
+#define MIPSInst_RE(x) ((MIPSInst(x) & 0x000007c0) >> I_RE_SFT)
+
+#define I_FUNC_SFT 0
+#define MIPSInst_FUNC(x) (MIPSInst(x) & 0x0000003f)
+
+#define I_FFMT_SFT 21
+#define MIPSInst_FFMT(x) ((MIPSInst(x) & 0x01e00000) >> I_FFMT_SFT)
+
+#define I_FT_SFT 16
+#define MIPSInst_FT(x) ((MIPSInst(x) & 0x001f0000) >> I_FT_SFT)
+
+#define I_FS_SFT 11
+#define MIPSInst_FS(x) ((MIPSInst(x) & 0x0000f800) >> I_FS_SFT)
+
+#define I_FD_SFT 6
+#define MIPSInst_FD(x) ((MIPSInst(x) & 0x000007c0) >> I_FD_SFT)
+
+#define I_FR_SFT 21
+#define MIPSInst_FR(x) ((MIPSInst(x) & 0x03e00000) >> I_FR_SFT)
+
+#define I_FMA_FUNC_SFT 2
+#define MIPSInst_FMA_FUNC(x) ((MIPSInst(x) & 0x0000003c) >> I_FMA_FUNC_SFT)
+
+#define I_FMA_FFMT_SFT 0
+#define MIPSInst_FMA_FFMT(x) (MIPSInst(x) & 0x00000003)
+
+typedef unsigned int mips_instruction;
+
+#endif /* _ASM_INST_H */
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
new file mode 100644
index 00000000..b04e4de5
--- /dev/null
+++ b/arch/mips/include/asm/io.h
@@ -0,0 +1,629 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995 Waldorf GmbH
+ * Copyright (C) 1994 - 2000, 06 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ */
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/byteorder.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm-generic/iomap.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/processor.h>
+#include <asm/string.h>
+
+#include <ioremap.h>
+#include <mangle-port.h>
+
+/*
+ * Slowdown I/O port space accesses for antique hardware.
+ */
+#undef CONF_SLOWDOWN_IO
+
+/*
+ * Raw operations are never swapped in software. OTOH values that raw
+ * operations are working on may or may not have been swapped by the bus
+ * hardware. An example use would be for flash memory that's used for
+ * execute in place.
+ */
+# define __raw_ioswabb(a, x) (x)
+# define __raw_ioswabw(a, x) (x)
+# define __raw_ioswabl(a, x) (x)
+# define __raw_ioswabq(a, x) (x)
+# define ____raw_ioswabq(a, x) (x)
+
+/* ioswab[bwlq], __mem_ioswab[bwlq] are defined in mangle-port.h */
+
+#define IO_SPACE_LIMIT 0xffff
+
+/*
+ * On MIPS I/O ports are memory mapped, so we access them using normal
+ * load/store instructions. mips_io_port_base is the virtual address to
+ * which all ports are being mapped. For sake of efficiency some code
+ * assumes that this is an address that can be loaded with a single lui
+ * instruction, so the lower 16 bits must be zero. Should be true on
+ * on any sane architecture; generic code does not use this assumption.
+ */
+extern const unsigned long mips_io_port_base;
+
+/*
+ * Gcc will generate code to load the value of mips_io_port_base after each
+ * function call which may be fairly wasteful in some cases. So we don't
+ * play quite by the book. We tell gcc mips_io_port_base is a long variable
+ * which solves the code generation issue. Now we need to violate the
+ * aliasing rules a little to make initialization possible and finally we
+ * will need the barrier() to fight side effects of the aliasing chat.
+ * This trickery will eventually collapse under gcc's optimizer. Oh well.
+ */
+static inline void set_io_port_base(unsigned long base)
+{
+ * (unsigned long *) &mips_io_port_base = base;
+ barrier();
+}
+
+/*
+ * Thanks to James van Artsdalen for a better timing-fix than
+ * the two short jumps: using outb's to a nonexistent port seems
+ * to guarantee better timings even on fast machines.
+ *
+ * On the other hand, I'd like to be sure of a non-existent port:
+ * I feel a bit unsafe about using 0x80 (should be safe, though)
+ *
+ * Linus
+ *
+ */
+
+#define __SLOW_DOWN_IO \
+ __asm__ __volatile__( \
+ "sb\t$0,0x80(%0)" \
+ : : "r" (mips_io_port_base));
+
+#ifdef CONF_SLOWDOWN_IO
+#ifdef REALLY_SLOW_IO
+#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
+#else
+#define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+#else
+#define SLOW_DOWN_IO
+#endif
+
+/*
+ * virt_to_phys - map virtual addresses to physical
+ * @address: address to remap
+ *
+ * The returned physical address is the physical (CPU) mapping for
+ * the memory address given. It is only valid to use this function on
+ * addresses directly mapped or allocated via kmalloc.
+ *
+ * This function does not give bus mappings for DMA transfers. In
+ * almost all conceivable cases a device driver should not be using
+ * this function
+ */
+static inline unsigned long virt_to_phys(volatile const void *address)
+{
+ return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET;
+}
+
+/*
+ * phys_to_virt - map physical address to virtual
+ * @address: address to remap
+ *
+ * The returned virtual address is a current CPU mapping for
+ * the memory address given. It is only valid to use this function on
+ * addresses that have a kernel mapping
+ *
+ * This function does not handle bus mappings for DMA transfers. In
+ * almost all conceivable cases a device driver should not be using
+ * this function
+ */
+static inline void * phys_to_virt(unsigned long address)
+{
+ return (void *)(address + PAGE_OFFSET - PHYS_OFFSET);
+}
+
+/*
+ * ISA I/O bus memory addresses are 1:1 with the physical address.
+ */
+static inline unsigned long isa_virt_to_bus(volatile void * address)
+{
+ return (unsigned long)address - PAGE_OFFSET;
+}
+
+static inline void * isa_bus_to_virt(unsigned long address)
+{
+ return (void *)(address + PAGE_OFFSET);
+}
+
+#define isa_page_to_bus page_to_phys
+
+/*
+ * However PCI ones are not necessarily 1:1 and therefore these interfaces
+ * are forbidden in portable PCI drivers.
+ *
+ * Allow them for x86 for legacy drivers, though.
+ */
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+/*
+ * Change "struct page" to physical address.
+ */
+#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
+
+extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags);
+extern void __iounmap(const volatile void __iomem *addr);
+
+static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
+ unsigned long flags)
+{
+ void __iomem *addr = plat_ioremap(offset, size, flags);
+
+ if (addr)
+ return addr;
+
+#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
+
+ if (cpu_has_64bit_addresses) {
+ u64 base = UNCAC_BASE;
+
+ /*
+ * R10000 supports a 2 bit uncached attribute therefore
+ * UNCAC_BASE may not equal IO_BASE.
+ */
+ if (flags == _CACHE_UNCACHED)
+ base = (u64) IO_BASE;
+ return (void __iomem *) (unsigned long) (base + offset);
+ } else if (__builtin_constant_p(offset) &&
+ __builtin_constant_p(size) && __builtin_constant_p(flags)) {
+ phys_t phys_addr, last_addr;
+
+ phys_addr = fixup_bigphys_addr(offset, size);
+
+ /* Don't allow wraparound or zero size. */
+ last_addr = phys_addr + size - 1;
+ if (!size || last_addr < phys_addr)
+ return NULL;
+
+ /*
+ * Map uncached objects in the low 512MB of address
+ * space using KSEG1.
+ */
+ if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) &&
+ flags == _CACHE_UNCACHED)
+ return (void __iomem *)
+ (unsigned long)CKSEG1ADDR(phys_addr);
+ }
+
+ return __ioremap(offset, size, flags);
+
+#undef __IS_LOW512
+}
+
+/*
+ * ioremap - map bus memory into CPU space
+ * @offset: bus address of the memory
+ * @size: size of the resource to map
+ *
+ * ioremap performs a platform specific sequence of operations to
+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
+ * writew/writel functions and the other mmio helpers. The returned
+ * address is not guaranteed to be usable directly as a virtual
+ * address.
+ */
+#define ioremap(offset, size) \
+ __ioremap_mode((offset), (size), _CACHE_UNCACHED)
+
+/*
+ * ioremap_nocache - map bus memory into CPU space
+ * @offset: bus address of the memory
+ * @size: size of the resource to map
+ *
+ * ioremap_nocache performs a platform specific sequence of operations to
+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
+ * writew/writel functions and the other mmio helpers. The returned
+ * address is not guaranteed to be usable directly as a virtual
+ * address.
+ *
+ * This version of ioremap ensures that the memory is marked uncachable
+ * on the CPU as well as honouring existing caching rules from things like
+ * the PCI bus. Note that there are other caches and buffers on many
+ * busses. In particular driver authors should read up on PCI writes
+ *
+ * It's useful if some control registers are in such an area and
+ * write combining or read caching is not desirable:
+ */
+#define ioremap_nocache(offset, size) \
+ __ioremap_mode((offset), (size), _CACHE_UNCACHED)
+
+/*
+ * ioremap_cachable - map bus memory into CPU space
+ * @offset: bus address of the memory
+ * @size: size of the resource to map
+ *
+ * ioremap_nocache performs a platform specific sequence of operations to
+ * make bus memory CPU accessible via the readb/readw/readl/writeb/
+ * writew/writel functions and the other mmio helpers. The returned
+ * address is not guaranteed to be usable directly as a virtual
+ * address.
+ *
+ * This version of ioremap ensures that the memory is marked cachable by
+ * the CPU. Also enables full write-combining. Useful for some
+ * memory-like regions on I/O busses.
+ */
+#define ioremap_cachable(offset, size) \
+ __ioremap_mode((offset), (size), _page_cachable_default)
+
+/*
+ * These two are MIPS specific ioremap variant. ioremap_cacheable_cow
+ * requests a cachable mapping, ioremap_uncached_accelerated requests a
+ * mapping using the uncached accelerated mode which isn't supported on
+ * all processors.
+ */
+#define ioremap_cacheable_cow(offset, size) \
+ __ioremap_mode((offset), (size), _CACHE_CACHABLE_COW)
+#define ioremap_uncached_accelerated(offset, size) \
+ __ioremap_mode((offset), (size), _CACHE_UNCACHED_ACCELERATED)
+
+static inline void iounmap(const volatile void __iomem *addr)
+{
+ if (plat_iounmap(addr))
+ return;
+
+#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
+
+ if (cpu_has_64bit_addresses ||
+ (__builtin_constant_p(addr) && __IS_KSEG1(addr)))
+ return;
+
+ __iounmap(addr);
+
+#undef __IS_KSEG1
+}
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define war_octeon_io_reorder_wmb() wmb()
+#else
+#define war_octeon_io_reorder_wmb() do { } while (0)
+#endif
+
+#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
+ \
+static inline void pfx##write##bwlq(type val, \
+ volatile void __iomem *mem) \
+{ \
+ volatile type *__mem; \
+ type __val; \
+ \
+ war_octeon_io_reorder_wmb(); \
+ \
+ __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
+ \
+ __val = pfx##ioswab##bwlq(__mem, val); \
+ \
+ if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
+ *__mem = __val; \
+ else if (cpu_has_64bits) { \
+ unsigned long __flags; \
+ type __tmp; \
+ \
+ if (irq) \
+ local_irq_save(__flags); \
+ __asm__ __volatile__( \
+ ".set mips3" "\t\t# __writeq""\n\t" \
+ "dsll32 %L0, %L0, 0" "\n\t" \
+ "dsrl32 %L0, %L0, 0" "\n\t" \
+ "dsll32 %M0, %M0, 0" "\n\t" \
+ "or %L0, %L0, %M0" "\n\t" \
+ ".set push" "\n\t" \
+ ".set noreorder" "\n\t" \
+ ".set nomacro" "\n\t" \
+ "sd %L0, %2" "\n\t" \
+ ".set pop" "\n\t" \
+ ".set mips0" "\n" \
+ : "=r" (__tmp) \
+ : "0" (__val), "R" (*__mem)); \
+ if (irq) \
+ local_irq_restore(__flags); \
+ } else \
+ BUG(); \
+} \
+ \
+static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
+{ \
+ volatile type *__mem; \
+ type __val; \
+ \
+ __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
+ \
+ if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \
+ __val = *__mem; \
+ else if (cpu_has_64bits) { \
+ unsigned long __flags; \
+ \
+ if (irq) \
+ local_irq_save(__flags); \
+ __asm__ __volatile__( \
+ ".set mips3" "\t\t# __readq" "\n\t" \
+ ".set push" "\n\t" \
+ ".set noreorder" "\n\t" \
+ ".set nomacro" "\n\t" \
+ "ld %L0, %1" "\n\t" \
+ ".set pop" "\n\t" \
+ "dsra32 %M0, %L0, 0" "\n\t" \
+ "sll %L0, %L0, 0" "\n\t" \
+ ".set mips0" "\n" \
+ : "=r" (__val) \
+ : "R" (*__mem)); \
+ if (irq) \
+ local_irq_restore(__flags); \
+ } else { \
+ __val = 0; \
+ BUG(); \
+ } \
+ \
+ return pfx##ioswab##bwlq(__mem, __val); \
+}
+
+#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
+ \
+static inline void pfx##out##bwlq##p(type val, unsigned long port) \
+{ \
+ volatile type *__addr; \
+ type __val; \
+ \
+ war_octeon_io_reorder_wmb(); \
+ \
+ __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
+ \
+ __val = pfx##ioswab##bwlq(__addr, val); \
+ \
+ /* Really, we want this to be atomic */ \
+ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
+ \
+ *__addr = __val; \
+ slow; \
+} \
+ \
+static inline type pfx##in##bwlq##p(unsigned long port) \
+{ \
+ volatile type *__addr; \
+ type __val; \
+ \
+ __addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
+ \
+ BUILD_BUG_ON(sizeof(type) > sizeof(unsigned long)); \
+ \
+ __val = *__addr; \
+ slow; \
+ \
+ return pfx##ioswab##bwlq(__addr, __val); \
+}
+
+#define __BUILD_MEMORY_PFX(bus, bwlq, type) \
+ \
+__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
+
+#define BUILDIO_MEM(bwlq, type) \
+ \
+__BUILD_MEMORY_PFX(__raw_, bwlq, type) \
+__BUILD_MEMORY_PFX(, bwlq, type) \
+__BUILD_MEMORY_PFX(__mem_, bwlq, type) \
+
+BUILDIO_MEM(b, u8)
+BUILDIO_MEM(w, u16)
+BUILDIO_MEM(l, u32)
+BUILDIO_MEM(q, u64)
+
+#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
+
+#define BUILDIO_IOPORT(bwlq, type) \
+ __BUILD_IOPORT_PFX(, bwlq, type) \
+ __BUILD_IOPORT_PFX(__mem_, bwlq, type)
+
+BUILDIO_IOPORT(b, u8)
+BUILDIO_IOPORT(w, u16)
+BUILDIO_IOPORT(l, u32)
+#ifdef CONFIG_64BIT
+BUILDIO_IOPORT(q, u64)
+#endif
+
+#define __BUILDIO(bwlq, type) \
+ \
+__BUILD_MEMORY_SINGLE(____raw_, bwlq, type, 0)
+
+__BUILDIO(q, u64)
+
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+#define readq_relaxed readq
+
+#define readb_be(addr) \
+ __raw_readb((__force unsigned *)(addr))
+#define readw_be(addr) \
+ be16_to_cpu(__raw_readw((__force unsigned *)(addr)))
+#define readl_be(addr) \
+ be32_to_cpu(__raw_readl((__force unsigned *)(addr)))
+#define readq_be(addr) \
+ be64_to_cpu(__raw_readq((__force unsigned *)(addr)))
+
+#define writeb_be(val, addr) \
+ __raw_writeb((val), (__force unsigned *)(addr))
+#define writew_be(val, addr) \
+ __raw_writew(cpu_to_be16((val)), (__force unsigned *)(addr))
+#define writel_be(val, addr) \
+ __raw_writel(cpu_to_be32((val)), (__force unsigned *)(addr))
+#define writeq_be(val, addr) \
+ __raw_writeq(cpu_to_be64((val)), (__force unsigned *)(addr))
+
+/*
+ * Some code tests for these symbols
+ */
+#define readq readq
+#define writeq writeq
+
+#define __BUILD_MEMORY_STRING(bwlq, type) \
+ \
+static inline void writes##bwlq(volatile void __iomem *mem, \
+ const void *addr, unsigned int count) \
+{ \
+ const volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ __mem_write##bwlq(*__addr, mem); \
+ __addr++; \
+ } \
+} \
+ \
+static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ *__addr = __mem_read##bwlq(mem); \
+ __addr++; \
+ } \
+}
+
+#define __BUILD_IOPORT_STRING(bwlq, type) \
+ \
+static inline void outs##bwlq(unsigned long port, const void *addr, \
+ unsigned int count) \
+{ \
+ const volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ __mem_out##bwlq(*__addr, port); \
+ __addr++; \
+ } \
+} \
+ \
+static inline void ins##bwlq(unsigned long port, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ *__addr = __mem_in##bwlq(port); \
+ __addr++; \
+ } \
+}
+
+#define BUILDSTRING(bwlq, type) \
+ \
+__BUILD_MEMORY_STRING(bwlq, type) \
+__BUILD_IOPORT_STRING(bwlq, type)
+
+BUILDSTRING(b, u8)
+BUILDSTRING(w, u16)
+BUILDSTRING(l, u32)
+#ifdef CONFIG_64BIT
+BUILDSTRING(q, u64)
+#endif
+
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define mmiowb() wmb()
+#else
+/* Depends on MIPS II instruction set */
+#define mmiowb() asm volatile ("sync" ::: "memory")
+#endif
+
+static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
+{
+ memset((void __force *) addr, val, count);
+}
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
+{
+ memcpy(dst, (void __force *) src, count);
+}
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
+{
+ memcpy((void __force *) dst, src, count);
+}
+
+/*
+ * The caches on some architectures aren't dma-coherent and have need to
+ * handle this in software. There are three types of operations that
+ * can be applied to dma buffers.
+ *
+ * - dma_cache_wback_inv(start, size) makes caches and coherent by
+ * writing the content of the caches back to memory, if necessary.
+ * The function also invalidates the affected part of the caches as
+ * necessary before DMA transfers from outside to memory.
+ * - dma_cache_wback(start, size) makes caches and coherent by
+ * writing the content of the caches back to memory, if necessary.
+ * The function also invalidates the affected part of the caches as
+ * necessary before DMA transfers from outside to memory.
+ * - dma_cache_inv(start, size) invalidates the affected parts of the
+ * caches. Dirty lines of the caches may be written back or simply
+ * be discarded. This operation is necessary before dma operations
+ * to the memory.
+ *
+ * This API used to be exported; it now is for arch code internal use only.
+ */
+#ifdef CONFIG_DMA_NONCOHERENT
+
+extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
+extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
+extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
+
+#define dma_cache_wback_inv(start, size) _dma_cache_wback_inv(start, size)
+#define dma_cache_wback(start, size) _dma_cache_wback(start, size)
+#define dma_cache_inv(start, size) _dma_cache_inv(start, size)
+
+#else /* Sane hardware */
+
+#define dma_cache_wback_inv(start,size) \
+ do { (void) (start); (void) (size); } while (0)
+#define dma_cache_wback(start,size) \
+ do { (void) (start); (void) (size); } while (0)
+#define dma_cache_inv(start,size) \
+ do { (void) (start); (void) (size); } while (0)
+
+#endif /* CONFIG_DMA_NONCOHERENT */
+
+/*
+ * Read a 32-bit register that requires a 64-bit read cycle on the bus.
+ * Avoid interrupt mucking, just adjust the address for 4-byte access.
+ * Assume the addresses are 8-byte aligned.
+ */
+#ifdef __MIPSEB__
+#define __CSR_32_ADJUST 4
+#else
+#define __CSR_32_ADJUST 0
+#endif
+
+#define csr_out32(v, a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST) = (v))
+#define csr_in32(a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST))
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p) p
+
+#endif /* _ASM_IO_H */
diff --git a/arch/mips/include/asm/ioctl.h b/arch/mips/include/asm/ioctl.h
new file mode 100644
index 00000000..c515a1a4
--- /dev/null
+++ b/arch/mips/include/asm/ioctl.h
@@ -0,0 +1,27 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 99, 2001 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2009 Wind River Systems
+ * Written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_IOCTL_H
+#define __ASM_IOCTL_H
+
+#define _IOC_SIZEBITS 13
+#define _IOC_DIRBITS 3
+
+/*
+ * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
+ * And this turns out useful to catch old ioctl numbers in header
+ * files for us.
+ */
+#define _IOC_NONE 1U
+#define _IOC_READ 2U
+#define _IOC_WRITE 4U
+
+#include <asm-generic/ioctl.h>
+
+#endif /* __ASM_IOCTL_H */
diff --git a/arch/mips/include/asm/ioctls.h b/arch/mips/include/asm/ioctls.h
new file mode 100644
index 00000000..92403c3d
--- /dev/null
+++ b/arch/mips/include/asm/ioctls.h
@@ -0,0 +1,110 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 2001 Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#ifndef __ASM_IOCTLS_H
+#define __ASM_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#define TCGETA 0x5401
+#define TCSETA 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
+#define TCSETAW 0x5403
+#define TCSETAF 0x5404
+
+#define TCSBRK 0x5405
+#define TCXONC 0x5406
+#define TCFLSH 0x5407
+
+#define TCGETS 0x540d
+#define TCSETS 0x540e
+#define TCSETSW 0x540f
+#define TCSETSF 0x5410
+
+#define TIOCEXCL 0x740d /* set exclusive use of tty */
+#define TIOCNXCL 0x740e /* reset exclusive use of tty */
+#define TIOCOUTQ 0x7472 /* output queue size */
+#define TIOCSTI 0x5472 /* simulate terminal input */
+#define TIOCMGET 0x741d /* get all modem bits */
+#define TIOCMBIS 0x741b /* bis modem bits */
+#define TIOCMBIC 0x741c /* bic modem bits */
+#define TIOCMSET 0x741a /* set all modem bits */
+#define TIOCPKT 0x5470 /* pty: set/clear packet mode */
+#define TIOCPKT_DATA 0x00 /* data packet */
+#define TIOCPKT_FLUSHREAD 0x01 /* flush packet */
+#define TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
+#define TIOCPKT_STOP 0x04 /* stop output */
+#define TIOCPKT_START 0x08 /* start output */
+#define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
+#define TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
+#define TIOCPKT_IOCTL 0x40 /* state change of pty driver */
+#define TIOCSWINSZ _IOW('t', 103, struct winsize) /* set window size */
+#define TIOCGWINSZ _IOR('t', 104, struct winsize) /* get window size */
+#define TIOCNOTTY 0x5471 /* void tty association */
+#define TIOCSETD 0x7401
+#define TIOCGETD 0x7400
+
+#define FIOCLEX 0x6601
+#define FIONCLEX 0x6602
+#define FIOASYNC 0x667d
+#define FIONBIO 0x667e
+#define FIOQSIZE 0x667f
+
+#define TIOCGLTC 0x7474 /* get special local chars */
+#define TIOCSLTC 0x7475 /* set special local chars */
+#define TIOCSPGRP _IOW('t', 118, int) /* set pgrp of tty */
+#define TIOCGPGRP _IOR('t', 119, int) /* get pgrp of tty */
+#define TIOCCONS _IOW('t', 120, int) /* become virtual console */
+
+#define FIONREAD 0x467f
+#define TIOCINQ FIONREAD
+
+#define TIOCGETP 0x7408
+#define TIOCSETP 0x7409
+#define TIOCSETN 0x740a /* TIOCSETP wo flush */
+
+/* #define TIOCSETA _IOW('t', 20, struct termios) set termios struct */
+/* #define TIOCSETAW _IOW('t', 21, struct termios) drain output, set */
+/* #define TIOCSETAF _IOW('t', 22, struct termios) drn out, fls in, set */
+/* #define TIOCGETD _IOR('t', 26, int) get line discipline */
+/* #define TIOCSETD _IOW('t', 27, int) set line discipline */
+ /* 127-124 compat */
+
+#define TIOCSBRK 0x5427 /* BSD compatibility */
+#define TIOCCBRK 0x5428 /* BSD compatibility */
+#define TIOCGSID 0x7416 /* Return the session ID of FD */
+#define TCGETS2 _IOR('T', 0x2A, struct termios2)
+#define TCSETS2 _IOW('T', 0x2B, struct termios2)
+#define TCSETSW2 _IOW('T', 0x2C, struct termios2)
+#define TCSETSF2 _IOW('T', 0x2D, struct termios2)
+#define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
+#define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */
+#define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */
+#define TIOCVHANGUP 0x5437
+
+/* I hope the range from 0x5480 on is free ... */
+#define TIOCSCTTY 0x5480 /* become controlling tty */
+#define TIOCGSOFTCAR 0x5481
+#define TIOCSSOFTCAR 0x5482
+#define TIOCLINUX 0x5483
+#define TIOCGSERIAL 0x5484
+#define TIOCSSERIAL 0x5485
+#define TCSBRKP 0x5486 /* Needed for POSIX tcsendbreak() */
+#define TIOCSERCONFIG 0x5488
+#define TIOCSERGWILD 0x5489
+#define TIOCSERSWILD 0x548a
+#define TIOCGLCKTRMIOS 0x548b
+#define TIOCSLCKTRMIOS 0x548c
+#define TIOCSERGSTRUCT 0x548d /* For debugging only */
+#define TIOCSERGETLSR 0x548e /* Get line status register */
+#define TIOCSERGETMULTI 0x548f /* Get multiport config */
+#define TIOCSERSETMULTI 0x5490 /* Set multiport config */
+#define TIOCMIWAIT 0x5491 /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT 0x5492 /* read serial port inline interrupt counts */
+
+#endif /* __ASM_IOCTLS_H */
diff --git a/arch/mips/include/asm/ip32/crime.h b/arch/mips/include/asm/ip32/crime.h
new file mode 100644
index 00000000..7c36b0e5
--- /dev/null
+++ b/arch/mips/include/asm/ip32/crime.h
@@ -0,0 +1,158 @@
+/*
+ * Definitions for the SGI CRIME (CPU, Rendering, Interconnect and Memory
+ * Engine)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Harald Koerfgen
+ */
+
+#ifndef __ASM_CRIME_H__
+#define __ASM_CRIME_H__
+
+/*
+ * Address map
+ */
+#define CRIME_BASE 0x14000000 /* physical */
+
+struct sgi_crime {
+ volatile unsigned long id;
+#define CRIME_ID_MASK 0xff
+#define CRIME_ID_IDBITS 0xf0
+#define CRIME_ID_IDVALUE 0xa0
+#define CRIME_ID_REV 0x0f
+#define CRIME_REV_PETTY 0x00
+#define CRIME_REV_11 0x11
+#define CRIME_REV_13 0x13
+#define CRIME_REV_14 0x14
+
+ volatile unsigned long control;
+#define CRIME_CONTROL_MASK 0x3fff
+#define CRIME_CONTROL_TRITON_SYSADC 0x2000
+#define CRIME_CONTROL_CRIME_SYSADC 0x1000
+#define CRIME_CONTROL_HARD_RESET 0x0800
+#define CRIME_CONTROL_SOFT_RESET 0x0400
+#define CRIME_CONTROL_DOG_ENA 0x0200
+#define CRIME_CONTROL_ENDIANESS 0x0100
+#define CRIME_CONTROL_ENDIAN_BIG 0x0100
+#define CRIME_CONTROL_ENDIAN_LITTLE 0x0000
+#define CRIME_CONTROL_CQUEUE_HWM 0x000f
+#define CRIME_CONTROL_CQUEUE_SHFT 0
+#define CRIME_CONTROL_WBUF_HWM 0x00f0
+#define CRIME_CONTROL_WBUF_SHFT 8
+
+ volatile unsigned long istat;
+ volatile unsigned long imask;
+ volatile unsigned long soft_int;
+ volatile unsigned long hard_int;
+#define MACE_VID_IN1_INT BIT(0)
+#define MACE_VID_IN2_INT BIT(1)
+#define MACE_VID_OUT_INT BIT(2)
+#define MACE_ETHERNET_INT BIT(3)
+#define MACE_SUPERIO_INT BIT(4)
+#define MACE_MISC_INT BIT(5)
+#define MACE_AUDIO_INT BIT(6)
+#define MACE_PCI_BRIDGE_INT BIT(7)
+#define MACEPCI_SCSI0_INT BIT(8)
+#define MACEPCI_SCSI1_INT BIT(9)
+#define MACEPCI_SLOT0_INT BIT(10)
+#define MACEPCI_SLOT1_INT BIT(11)
+#define MACEPCI_SLOT2_INT BIT(12)
+#define MACEPCI_SHARED0_INT BIT(13)
+#define MACEPCI_SHARED1_INT BIT(14)
+#define MACEPCI_SHARED2_INT BIT(15)
+#define CRIME_GBE0_INT BIT(16)
+#define CRIME_GBE1_INT BIT(17)
+#define CRIME_GBE2_INT BIT(18)
+#define CRIME_GBE3_INT BIT(19)
+#define CRIME_CPUERR_INT BIT(20)
+#define CRIME_MEMERR_INT BIT(21)
+#define CRIME_RE_EMPTY_E_INT BIT(22)
+#define CRIME_RE_FULL_E_INT BIT(23)
+#define CRIME_RE_IDLE_E_INT BIT(24)
+#define CRIME_RE_EMPTY_L_INT BIT(25)
+#define CRIME_RE_FULL_L_INT BIT(26)
+#define CRIME_RE_IDLE_L_INT BIT(27)
+#define CRIME_SOFT0_INT BIT(28)
+#define CRIME_SOFT1_INT BIT(29)
+#define CRIME_SOFT2_INT BIT(30)
+#define CRIME_SYSCORERR_INT CRIME_SOFT2_INT
+#define CRIME_VICE_INT BIT(31)
+/* Masks for deciding who handles the interrupt */
+#define CRIME_MACE_INT_MASK 0x8f
+#define CRIME_MACEISA_INT_MASK 0x70
+#define CRIME_MACEPCI_INT_MASK 0xff00
+#define CRIME_CRIME_INT_MASK 0xffff0000
+
+ volatile unsigned long watchdog;
+#define CRIME_DOG_POWER_ON_RESET 0x00010000
+#define CRIME_DOG_WARM_RESET 0x00080000
+#define CRIME_DOG_TIMEOUT (CRIME_DOG_POWER_ON_RESET|CRIME_DOG_WARM_RESET)
+#define CRIME_DOG_VALUE 0x00007fff
+
+ volatile unsigned long timer;
+#define CRIME_MASTER_FREQ 66666500 /* Crime upcounter frequency */
+#define CRIME_NS_PER_TICK 15 /* for delay_calibrate */
+
+ volatile unsigned long cpu_error_addr;
+#define CRIME_CPU_ERROR_ADDR_MASK 0x3ffffffff
+
+ volatile unsigned long cpu_error_stat;
+#define CRIME_CPU_ERROR_MASK 0x7 /* cpu error stat is 3 bits */
+#define CRIME_CPU_ERROR_CPU_ILL_ADDR 0x4
+#define CRIME_CPU_ERROR_VICE_WRT_PRTY 0x2
+#define CRIME_CPU_ERROR_CPU_WRT_PRTY 0x1
+
+ unsigned long _pad0[54];
+
+ volatile unsigned long mc_ctrl;
+ volatile unsigned long bank_ctrl[8];
+#define CRIME_MEM_BANK_CONTROL_MASK 0x11f /* 9 bits 7:5 reserved */
+#define CRIME_MEM_BANK_CONTROL_ADDR 0x01f
+#define CRIME_MEM_BANK_CONTROL_SDRAM_SIZE 0x100
+#define CRIME_MAXBANKS 8
+
+ volatile unsigned long mem_ref_counter;
+#define CRIME_MEM_REF_COUNTER_MASK 0x3ff /* 10bit */
+
+ volatile unsigned long mem_error_stat;
+#define CRIME_MEM_ERROR_STAT_MASK 0x0ff7ffff /* 28-bit register */
+#define CRIME_MEM_ERROR_MACE_ID 0x0000007f
+#define CRIME_MEM_ERROR_MACE_ACCESS 0x00000080
+#define CRIME_MEM_ERROR_RE_ID 0x00007f00
+#define CRIME_MEM_ERROR_RE_ACCESS 0x00008000
+#define CRIME_MEM_ERROR_GBE_ACCESS 0x00010000
+#define CRIME_MEM_ERROR_VICE_ACCESS 0x00020000
+#define CRIME_MEM_ERROR_CPU_ACCESS 0x00040000
+#define CRIME_MEM_ERROR_RESERVED 0x00080000
+#define CRIME_MEM_ERROR_SOFT_ERR 0x00100000
+#define CRIME_MEM_ERROR_HARD_ERR 0x00200000
+#define CRIME_MEM_ERROR_MULTIPLE 0x00400000
+#define CRIME_MEM_ERROR_ECC 0x01800000
+#define CRIME_MEM_ERROR_MEM_ECC_RD 0x00800000
+#define CRIME_MEM_ERROR_MEM_ECC_RMW 0x01000000
+#define CRIME_MEM_ERROR_INV 0x0e000000
+#define CRIME_MEM_ERROR_INV_MEM_ADDR_RD 0x02000000
+#define CRIME_MEM_ERROR_INV_MEM_ADDR_WR 0x04000000
+#define CRIME_MEM_ERROR_INV_MEM_ADDR_RMW 0x08000000
+
+ volatile unsigned long mem_error_addr;
+#define CRIME_MEM_ERROR_ADDR_MASK 0x3fffffff
+
+ volatile unsigned long mem_ecc_syn;
+#define CRIME_MEM_ERROR_ECC_SYN_MASK 0xffffffff
+
+ volatile unsigned long mem_ecc_chk;
+#define CRIME_MEM_ERROR_ECC_CHK_MASK 0xffffffff
+
+ volatile unsigned long mem_ecc_repl;
+#define CRIME_MEM_ERROR_ECC_REPL_MASK 0xffffffff
+};
+
+extern struct sgi_crime __iomem *crime;
+
+#define CRIME_HI_MEM_BASE 0x40000000 /* this is where whole 1G of RAM is mapped */
+
+#endif /* __ASM_CRIME_H__ */
diff --git a/arch/mips/include/asm/ip32/ip32_ints.h b/arch/mips/include/asm/ip32/ip32_ints.h
new file mode 100644
index 00000000..85bc5302
--- /dev/null
+++ b/arch/mips/include/asm/ip32/ip32_ints.h
@@ -0,0 +1,114 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Harald Koerfgen
+ */
+
+#ifndef __ASM_IP32_INTS_H
+#define __ASM_IP32_INTS_H
+
+#include <asm/irq.h>
+
+/*
+ * This list reflects the assignment of interrupt numbers to
+ * interrupting events. Order is fairly irrelevant to handling
+ * priority. This differs from irix.
+ */
+
+enum ip32_irq_no {
+ /*
+ * CPU interrupts are 0 ... 7
+ */
+
+ CRIME_IRQ_BASE = MIPS_CPU_IRQ_BASE + 8,
+
+ /*
+ * MACE
+ */
+ MACE_VID_IN1_IRQ = CRIME_IRQ_BASE,
+ MACE_VID_IN2_IRQ,
+ MACE_VID_OUT_IRQ,
+ MACE_ETHERNET_IRQ,
+ /* SUPERIO, MISC, and AUDIO are MACEISA */
+ __MACE_SUPERIO,
+ __MACE_MISC,
+ __MACE_AUDIO,
+ MACE_PCI_BRIDGE_IRQ,
+
+ /*
+ * MACEPCI
+ */
+ MACEPCI_SCSI0_IRQ,
+ MACEPCI_SCSI1_IRQ,
+ MACEPCI_SLOT0_IRQ,
+ MACEPCI_SLOT1_IRQ,
+ MACEPCI_SLOT2_IRQ,
+ MACEPCI_SHARED0_IRQ,
+ MACEPCI_SHARED1_IRQ,
+ MACEPCI_SHARED2_IRQ,
+
+ /*
+ * CRIME
+ */
+ CRIME_GBE0_IRQ,
+ CRIME_GBE1_IRQ,
+ CRIME_GBE2_IRQ,
+ CRIME_GBE3_IRQ,
+ CRIME_CPUERR_IRQ,
+ CRIME_MEMERR_IRQ,
+ CRIME_RE_EMPTY_E_IRQ,
+ CRIME_RE_FULL_E_IRQ,
+ CRIME_RE_IDLE_E_IRQ,
+ CRIME_RE_EMPTY_L_IRQ,
+ CRIME_RE_FULL_L_IRQ,
+ CRIME_RE_IDLE_L_IRQ,
+ CRIME_SOFT0_IRQ,
+ CRIME_SOFT1_IRQ,
+ CRIME_SOFT2_IRQ,
+ CRIME_SYSCORERR_IRQ = CRIME_SOFT2_IRQ,
+ CRIME_VICE_IRQ,
+
+ /*
+ * MACEISA
+ */
+ MACEISA_AUDIO_SW_IRQ,
+ MACEISA_AUDIO_SC_IRQ,
+ MACEISA_AUDIO1_DMAT_IRQ,
+ MACEISA_AUDIO1_OF_IRQ,
+ MACEISA_AUDIO2_DMAT_IRQ,
+ MACEISA_AUDIO2_MERR_IRQ,
+ MACEISA_AUDIO3_DMAT_IRQ,
+ MACEISA_AUDIO3_MERR_IRQ,
+ MACEISA_RTC_IRQ,
+ MACEISA_KEYB_IRQ,
+ /* MACEISA_KEYB_POLL is not an IRQ */
+ __MACEISA_KEYB_POLL,
+ MACEISA_MOUSE_IRQ,
+ /* MACEISA_MOUSE_POLL is not an IRQ */
+ __MACEISA_MOUSE_POLL,
+ MACEISA_TIMER0_IRQ,
+ MACEISA_TIMER1_IRQ,
+ MACEISA_TIMER2_IRQ,
+ MACEISA_PARALLEL_IRQ,
+ MACEISA_PAR_CTXA_IRQ,
+ MACEISA_PAR_CTXB_IRQ,
+ MACEISA_PAR_MERR_IRQ,
+ MACEISA_SERIAL1_IRQ,
+ MACEISA_SERIAL1_TDMAT_IRQ,
+ MACEISA_SERIAL1_TDMAPR_IRQ,
+ MACEISA_SERIAL1_TDMAME_IRQ,
+ MACEISA_SERIAL1_RDMAT_IRQ,
+ MACEISA_SERIAL1_RDMAOR_IRQ,
+ MACEISA_SERIAL2_IRQ,
+ MACEISA_SERIAL2_TDMAT_IRQ,
+ MACEISA_SERIAL2_TDMAPR_IRQ,
+ MACEISA_SERIAL2_TDMAME_IRQ,
+ MACEISA_SERIAL2_RDMAT_IRQ,
+ MACEISA_SERIAL2_RDMAOR_IRQ,
+
+ IP32_IRQ_MAX = MACEISA_SERIAL2_RDMAOR_IRQ
+};
+
+#endif /* __ASM_IP32_INTS_H */
diff --git a/arch/mips/include/asm/ip32/mace.h b/arch/mips/include/asm/ip32/mace.h
new file mode 100644
index 00000000..d08d7c67
--- /dev/null
+++ b/arch/mips/include/asm/ip32/mace.h
@@ -0,0 +1,365 @@
+/*
+ * Definitions for the SGI MACE (Multimedia, Audio and Communications Engine)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Harald Koerfgen
+ * Copyright (C) 2004 Ladislav Michl
+ */
+
+#ifndef __ASM_MACE_H__
+#define __ASM_MACE_H__
+
+/*
+ * Address map
+ */
+#define MACE_BASE 0x1f000000 /* physical */
+
+/*
+ * PCI interface
+ */
+struct mace_pci {
+ volatile unsigned int error_addr;
+ volatile unsigned int error;
+#define MACEPCI_ERROR_MASTER_ABORT BIT(31)
+#define MACEPCI_ERROR_TARGET_ABORT BIT(30)
+#define MACEPCI_ERROR_DATA_PARITY_ERR BIT(29)
+#define MACEPCI_ERROR_RETRY_ERR BIT(28)
+#define MACEPCI_ERROR_ILLEGAL_CMD BIT(27)
+#define MACEPCI_ERROR_SYSTEM_ERR BIT(26)
+#define MACEPCI_ERROR_INTERRUPT_TEST BIT(25)
+#define MACEPCI_ERROR_PARITY_ERR BIT(24)
+#define MACEPCI_ERROR_OVERRUN BIT(23)
+#define MACEPCI_ERROR_RSVD BIT(22)
+#define MACEPCI_ERROR_MEMORY_ADDR BIT(21)
+#define MACEPCI_ERROR_CONFIG_ADDR BIT(20)
+#define MACEPCI_ERROR_MASTER_ABORT_ADDR_VALID BIT(19)
+#define MACEPCI_ERROR_TARGET_ABORT_ADDR_VALID BIT(18)
+#define MACEPCI_ERROR_DATA_PARITY_ADDR_VALID BIT(17)
+#define MACEPCI_ERROR_RETRY_ADDR_VALID BIT(16)
+#define MACEPCI_ERROR_SIG_TABORT BIT(4)
+#define MACEPCI_ERROR_DEVSEL_MASK 0xc0
+#define MACEPCI_ERROR_DEVSEL_FAST 0
+#define MACEPCI_ERROR_DEVSEL_MED 0x40
+#define MACEPCI_ERROR_DEVSEL_SLOW 0x80
+#define MACEPCI_ERROR_FBB BIT(1)
+#define MACEPCI_ERROR_66MHZ BIT(0)
+ volatile unsigned int control;
+#define MACEPCI_CONTROL_INT(x) BIT(x)
+#define MACEPCI_CONTROL_INT_MASK 0xff
+#define MACEPCI_CONTROL_SERR_ENA BIT(8)
+#define MACEPCI_CONTROL_ARB_N6 BIT(9)
+#define MACEPCI_CONTROL_PARITY_ERR BIT(10)
+#define MACEPCI_CONTROL_MRMRA_ENA BIT(11)
+#define MACEPCI_CONTROL_ARB_N3 BIT(12)
+#define MACEPCI_CONTROL_ARB_N4 BIT(13)
+#define MACEPCI_CONTROL_ARB_N5 BIT(14)
+#define MACEPCI_CONTROL_PARK_LIU BIT(15)
+#define MACEPCI_CONTROL_INV_INT(x) BIT(16+x)
+#define MACEPCI_CONTROL_INV_INT_MASK 0x00ff0000
+#define MACEPCI_CONTROL_OVERRUN_INT BIT(24)
+#define MACEPCI_CONTROL_PARITY_INT BIT(25)
+#define MACEPCI_CONTROL_SERR_INT BIT(26)
+#define MACEPCI_CONTROL_IT_INT BIT(27)
+#define MACEPCI_CONTROL_RE_INT BIT(28)
+#define MACEPCI_CONTROL_DPED_INT BIT(29)
+#define MACEPCI_CONTROL_TAR_INT BIT(30)
+#define MACEPCI_CONTROL_MAR_INT BIT(31)
+ volatile unsigned int rev;
+ unsigned int _pad[0xcf8/4 - 4];
+ volatile unsigned int config_addr;
+ union {
+ volatile unsigned char b[4];
+ volatile unsigned short w[2];
+ volatile unsigned int l;
+ } config_data;
+};
+#define MACEPCI_LOW_MEMORY 0x1a000000
+#define MACEPCI_LOW_IO 0x18000000
+#define MACEPCI_SWAPPED_VIEW 0
+#define MACEPCI_NATIVE_VIEW 0x40000000
+#define MACEPCI_IO 0x80000000
+#define MACEPCI_HI_MEMORY 0x280000000
+#define MACEPCI_HI_IO 0x100000000
+
+/*
+ * Video interface
+ */
+struct mace_video {
+ unsigned long xxx; /* later... */
+};
+
+/*
+ * Ethernet interface
+ */
+struct mace_ethernet {
+ volatile unsigned long mac_ctrl;
+ volatile unsigned long int_stat;
+ volatile unsigned long dma_ctrl;
+ volatile unsigned long timer;
+ volatile unsigned long tx_int_al;
+ volatile unsigned long rx_int_al;
+ volatile unsigned long tx_info;
+ volatile unsigned long tx_info_al;
+ volatile unsigned long rx_buff;
+ volatile unsigned long rx_buff_al1;
+ volatile unsigned long rx_buff_al2;
+ volatile unsigned long diag;
+ volatile unsigned long phy_data;
+ volatile unsigned long phy_regs;
+ volatile unsigned long phy_trans_go;
+ volatile unsigned long backoff_seed;
+ /*===================================*/
+ volatile unsigned long imq_reserved[4];
+ volatile unsigned long mac_addr;
+ volatile unsigned long mac_addr2;
+ volatile unsigned long mcast_filter;
+ volatile unsigned long tx_ring_base;
+ /* Following are read-only registers for debugging */
+ volatile unsigned long tx_pkt1_hdr;
+ volatile unsigned long tx_pkt1_ptr[3];
+ volatile unsigned long tx_pkt2_hdr;
+ volatile unsigned long tx_pkt2_ptr[3];
+ /*===================================*/
+ volatile unsigned long rx_fifo;
+};
+
+/*
+ * Peripherals
+ */
+
+/* Audio registers */
+struct mace_audio {
+ volatile unsigned long control;
+ volatile unsigned long codec_control; /* codec status control */
+ volatile unsigned long codec_mask; /* codec status input mask */
+ volatile unsigned long codec_read; /* codec status read data */
+ struct {
+ volatile unsigned long control; /* channel control */
+ volatile unsigned long read_ptr; /* channel read pointer */
+ volatile unsigned long write_ptr; /* channel write pointer */
+ volatile unsigned long depth; /* channel depth */
+ } chan[3];
+};
+
+
+/* register definitions for parallel port DMA */
+struct mace_parport {
+ /* 0 - do nothing,
+ * 1 - pulse terminal count to the device after buffer is drained */
+#define MACEPAR_CONTEXT_LASTFLAG BIT(63)
+ /* Should not cross 4K page boundary */
+#define MACEPAR_CONTEXT_DATA_BOUND 0x0000000000001000UL
+#define MACEPAR_CONTEXT_DATALEN_MASK 0x00000fff00000000UL
+#define MACEPAR_CONTEXT_DATALEN_SHIFT 32
+ /* Can be arbitrarily aligned on any byte boundary on output,
+ * 64 byte aligned on input */
+#define MACEPAR_CONTEXT_BASEADDR_MASK 0x00000000ffffffffUL
+ volatile u64 context_a;
+ volatile u64 context_b;
+ /* 0 - mem->device, 1 - device->mem */
+#define MACEPAR_CTLSTAT_DIRECTION BIT(0)
+ /* 0 - channel frozen, 1 - channel enabled */
+#define MACEPAR_CTLSTAT_ENABLE BIT(1)
+ /* 0 - channel active, 1 - complete channel reset */
+#define MACEPAR_CTLSTAT_RESET BIT(2)
+#define MACEPAR_CTLSTAT_CTXB_VALID BIT(3)
+#define MACEPAR_CTLSTAT_CTXA_VALID BIT(4)
+ volatile u64 cntlstat; /* Control/Status register */
+#define MACEPAR_DIAG_CTXINUSE BIT(0)
+ /* 1 - Dma engine is enabled and processing something */
+#define MACEPAR_DIAG_DMACTIVE BIT(1)
+ /* Counter of bytes left */
+#define MACEPAR_DIAG_CTRMASK 0x0000000000003ffcUL
+#define MACEPAR_DIAG_CTRSHIFT 2
+ volatile u64 diagnostic; /* RO: diagnostic register */
+};
+
+/* ISA Control and DMA registers */
+struct mace_isactrl {
+ volatile unsigned long ringbase;
+#define MACEISA_RINGBUFFERS_SIZE (8 * 4096)
+
+ volatile unsigned long misc;
+#define MACEISA_FLASH_WE BIT(0) /* 1=> Enable FLASH writes */
+#define MACEISA_PWD_CLEAR BIT(1) /* 1=> PWD CLEAR jumper detected */
+#define MACEISA_NIC_DEASSERT BIT(2)
+#define MACEISA_NIC_DATA BIT(3)
+#define MACEISA_LED_RED BIT(4) /* 0=> Illuminate red LED */
+#define MACEISA_LED_GREEN BIT(5) /* 0=> Illuminate green LED */
+#define MACEISA_DP_RAM_ENABLE BIT(6)
+
+ volatile unsigned long istat;
+ volatile unsigned long imask;
+#define MACEISA_AUDIO_SW_INT BIT(0)
+#define MACEISA_AUDIO_SC_INT BIT(1)
+#define MACEISA_AUDIO1_DMAT_INT BIT(2)
+#define MACEISA_AUDIO1_OF_INT BIT(3)
+#define MACEISA_AUDIO2_DMAT_INT BIT(4)
+#define MACEISA_AUDIO2_MERR_INT BIT(5)
+#define MACEISA_AUDIO3_DMAT_INT BIT(6)
+#define MACEISA_AUDIO3_MERR_INT BIT(7)
+#define MACEISA_RTC_INT BIT(8)
+#define MACEISA_KEYB_INT BIT(9)
+#define MACEISA_KEYB_POLL_INT BIT(10)
+#define MACEISA_MOUSE_INT BIT(11)
+#define MACEISA_MOUSE_POLL_INT BIT(12)
+#define MACEISA_TIMER0_INT BIT(13)
+#define MACEISA_TIMER1_INT BIT(14)
+#define MACEISA_TIMER2_INT BIT(15)
+#define MACEISA_PARALLEL_INT BIT(16)
+#define MACEISA_PAR_CTXA_INT BIT(17)
+#define MACEISA_PAR_CTXB_INT BIT(18)
+#define MACEISA_PAR_MERR_INT BIT(19)
+#define MACEISA_SERIAL1_INT BIT(20)
+#define MACEISA_SERIAL1_TDMAT_INT BIT(21)
+#define MACEISA_SERIAL1_TDMAPR_INT BIT(22)
+#define MACEISA_SERIAL1_TDMAME_INT BIT(23)
+#define MACEISA_SERIAL1_RDMAT_INT BIT(24)
+#define MACEISA_SERIAL1_RDMAOR_INT BIT(25)
+#define MACEISA_SERIAL2_INT BIT(26)
+#define MACEISA_SERIAL2_TDMAT_INT BIT(27)
+#define MACEISA_SERIAL2_TDMAPR_INT BIT(28)
+#define MACEISA_SERIAL2_TDMAME_INT BIT(29)
+#define MACEISA_SERIAL2_RDMAT_INT BIT(30)
+#define MACEISA_SERIAL2_RDMAOR_INT BIT(31)
+
+ volatile unsigned long _pad[0x2000/8 - 4];
+
+ volatile unsigned long dp_ram[0x400];
+ struct mace_parport parport;
+};
+
+/* Keyboard & Mouse registers
+ * -> drivers/input/serio/maceps2.c */
+struct mace_ps2port {
+ volatile unsigned long tx;
+ volatile unsigned long rx;
+ volatile unsigned long control;
+ volatile unsigned long status;
+};
+
+struct mace_ps2 {
+ struct mace_ps2port keyb;
+ struct mace_ps2port mouse;
+};
+
+/* I2C registers
+ * -> drivers/i2c/algos/i2c-algo-sgi.c */
+struct mace_i2c {
+ volatile unsigned long config;
+#define MACEI2C_RESET BIT(0)
+#define MACEI2C_FAST BIT(1)
+#define MACEI2C_DATA_OVERRIDE BIT(2)
+#define MACEI2C_CLOCK_OVERRIDE BIT(3)
+#define MACEI2C_DATA_STATUS BIT(4)
+#define MACEI2C_CLOCK_STATUS BIT(5)
+ volatile unsigned long control;
+ volatile unsigned long data;
+};
+
+/* Timer registers */
+typedef union {
+ volatile unsigned long ust_msc;
+ struct reg {
+ volatile unsigned int ust;
+ volatile unsigned int msc;
+ } reg;
+} timer_reg;
+
+struct mace_timers {
+ volatile unsigned long ust;
+#define MACE_UST_PERIOD_NS 960
+
+ volatile unsigned long compare1;
+ volatile unsigned long compare2;
+ volatile unsigned long compare3;
+
+ timer_reg audio_in;
+ timer_reg audio_out1;
+ timer_reg audio_out2;
+ timer_reg video_in1;
+ timer_reg video_in2;
+ timer_reg video_out;
+};
+
+struct mace_perif {
+ struct mace_audio audio;
+ char _pad0[0x10000 - sizeof(struct mace_audio)];
+
+ struct mace_isactrl ctrl;
+ char _pad1[0x10000 - sizeof(struct mace_isactrl)];
+
+ struct mace_ps2 ps2;
+ char _pad2[0x10000 - sizeof(struct mace_ps2)];
+
+ struct mace_i2c i2c;
+ char _pad3[0x10000 - sizeof(struct mace_i2c)];
+
+ struct mace_timers timers;
+ char _pad4[0x10000 - sizeof(struct mace_timers)];
+};
+
+
+/*
+ * ISA peripherals
+ */
+
+/* Parallel port */
+struct mace_parallel {
+};
+
+struct mace_ecp1284 { /* later... */
+};
+
+/* Serial port */
+struct mace_serial {
+ volatile unsigned long xxx; /* later... */
+};
+
+struct mace_isa {
+ struct mace_parallel parallel;
+ char _pad1[0x8000 - sizeof(struct mace_parallel)];
+
+ struct mace_ecp1284 ecp1284;
+ char _pad2[0x8000 - sizeof(struct mace_ecp1284)];
+
+ struct mace_serial serial1;
+ char _pad3[0x8000 - sizeof(struct mace_serial)];
+
+ struct mace_serial serial2;
+ char _pad4[0x8000 - sizeof(struct mace_serial)];
+
+ volatile unsigned char rtc[0x10000];
+};
+
+struct sgi_mace {
+ char _reserved[0x80000];
+
+ struct mace_pci pci;
+ char _pad0[0x80000 - sizeof(struct mace_pci)];
+
+ struct mace_video video_in1;
+ char _pad1[0x80000 - sizeof(struct mace_video)];
+
+ struct mace_video video_in2;
+ char _pad2[0x80000 - sizeof(struct mace_video)];
+
+ struct mace_video video_out;
+ char _pad3[0x80000 - sizeof(struct mace_video)];
+
+ struct mace_ethernet eth;
+ char _pad4[0x80000 - sizeof(struct mace_ethernet)];
+
+ struct mace_perif perif;
+ char _pad5[0x80000 - sizeof(struct mace_perif)];
+
+ struct mace_isa isa;
+ char _pad6[0x80000 - sizeof(struct mace_isa)];
+};
+
+extern struct sgi_mace __iomem *mace;
+
+#endif /* __ASM_MACE_H__ */
diff --git a/arch/mips/include/asm/ipcbuf.h b/arch/mips/include/asm/ipcbuf.h
new file mode 100644
index 00000000..d47d08f2
--- /dev/null
+++ b/arch/mips/include/asm/ipcbuf.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_IPCBUF_H
+#define _ASM_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for alpha architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit seq
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct ipc64_perm
+{
+ __kernel_key_t key;
+ __kernel_uid_t uid;
+ __kernel_gid_t gid;
+ __kernel_uid_t cuid;
+ __kernel_gid_t cgid;
+ __kernel_mode_t mode;
+ unsigned short seq;
+ unsigned short __pad1;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+#endif /* _ASM_IPCBUF_H */
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
new file mode 100644
index 00000000..0ec01294
--- /dev/null
+++ b/arch/mips/include/asm/irq.h
@@ -0,0 +1,148 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02, 03 by Ralf Baechle
+ */
+#ifndef _ASM_IRQ_H
+#define _ASM_IRQ_H
+
+#include <linux/linkage.h>
+#include <linux/smp.h>
+
+#include <asm/mipsmtregs.h>
+
+#include <irq.h>
+
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+ return;
+}
+
+#ifdef CONFIG_I8259
+static inline int irq_canonicalize(int irq)
+{
+ return ((irq == I8259A_IRQ_BASE + 2) ? I8259A_IRQ_BASE + 9 : irq);
+}
+#else
+#define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */
+#endif
+
+#ifdef CONFIG_MIPS_MT_SMTC
+
+struct irqaction;
+
+extern unsigned long irq_hwmask[];
+extern int setup_irq_smtc(unsigned int irq, struct irqaction * new,
+ unsigned long hwmask);
+
+static inline void smtc_im_ack_irq(unsigned int irq)
+{
+ if (irq_hwmask[irq] & ST0_IM)
+ set_c0_status(irq_hwmask[irq] & ST0_IM);
+}
+
+#else
+
+static inline void smtc_im_ack_irq(unsigned int irq)
+{
+}
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+#include <linux/cpumask.h>
+
+extern int plat_set_irq_affinity(struct irq_data *d,
+ const struct cpumask *affinity, bool force);
+extern void smtc_forward_irq(struct irq_data *d);
+
+/*
+ * IRQ affinity hook invoked at the beginning of interrupt dispatch
+ * if option is enabled.
+ *
+ * Up through Linux 2.6.22 (at least) cpumask operations are very
+ * inefficient on MIPS. Initial prototypes of SMTC IRQ affinity
+ * used a "fast path" per-IRQ-descriptor cache of affinity information
+ * to reduce latency. As there is a project afoot to optimize the
+ * cpumask implementations, this version is optimistically assuming
+ * that cpumask.h macro overhead is reasonable during interrupt dispatch.
+ */
+static inline int handle_on_other_cpu(unsigned int irq)
+{
+ struct irq_data *d = irq_get_irq_data(irq);
+
+ if (cpumask_test_cpu(smp_processor_id(), d->affinity))
+ return 0;
+ smtc_forward_irq(d);
+ return 1;
+}
+
+#else /* Not doing SMTC affinity */
+
+static inline int handle_on_other_cpu(unsigned int irq) { return 0; }
+
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
+
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
+
+static inline void smtc_im_backstop(unsigned int irq)
+{
+ if (irq_hwmask[irq] & 0x0000ff00)
+ write_c0_tccontext(read_c0_tccontext() &
+ ~(irq_hwmask[irq] & 0x0000ff00));
+}
+
+/*
+ * Clear interrupt mask handling "backstop" if irq_hwmask
+ * entry so indicates. This implies that the ack() or end()
+ * functions will take over re-enabling the low-level mask.
+ * Otherwise it will be done on return from exception.
+ */
+static inline int smtc_handle_on_other_cpu(unsigned int irq)
+{
+ int ret = handle_on_other_cpu(irq);
+
+ if (!ret)
+ smtc_im_backstop(irq);
+ return ret;
+}
+
+#else
+
+static inline void smtc_im_backstop(unsigned int irq) { }
+static inline int smtc_handle_on_other_cpu(unsigned int irq)
+{
+ return handle_on_other_cpu(irq);
+}
+
+#endif
+
+extern void do_IRQ(unsigned int irq);
+
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+
+extern void do_IRQ_no_affinity(unsigned int irq);
+
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
+
+extern void arch_init_irq(void);
+extern void spurious_interrupt(void);
+
+extern int allocate_irqno(void);
+extern void alloc_legacy_irqno(void);
+extern void free_irqno(unsigned int irq);
+
+/*
+ * Before R2 the timer and performance counter interrupts were both fixed to
+ * IE7. Since R2 their number has to be read from the c0_intctl register.
+ */
+#define CP0_LEGACY_COMPARE_IRQ 7
+
+extern int cp0_compare_irq;
+extern int cp0_compare_irq_shift;
+extern int cp0_perfcount_irq;
+
+#endif /* _ASM_IRQ_H */
diff --git a/arch/mips/include/asm/irq_cpu.h b/arch/mips/include/asm/irq_cpu.h
new file mode 100644
index 00000000..ef6a07cd
--- /dev/null
+++ b/arch/mips/include/asm/irq_cpu.h
@@ -0,0 +1,20 @@
+/*
+ * include/asm-mips/irq_cpu.h
+ *
+ * MIPS CPU interrupt definitions.
+ *
+ * Copyright (C) 2002 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_IRQ_CPU_H
+#define _ASM_IRQ_CPU_H
+
+extern void mips_cpu_irq_init(void);
+extern void rm7k_cpu_irq_init(void);
+extern void rm9k_cpu_irq_init(void);
+
+#endif /* _ASM_IRQ_CPU_H */
diff --git a/arch/mips/include/asm/irq_gt641xx.h b/arch/mips/include/asm/irq_gt641xx.h
new file mode 100644
index 00000000..250a2407
--- /dev/null
+++ b/arch/mips/include/asm/irq_gt641xx.h
@@ -0,0 +1,60 @@
+/*
+ * Galileo/Marvell GT641xx IRQ definitions.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef _ASM_IRQ_GT641XX_H
+#define _ASM_IRQ_GT641XX_H
+
+#ifndef GT641XX_IRQ_BASE
+#define GT641XX_IRQ_BASE 8
+#endif
+
+#define GT641XX_MEMORY_OUT_OF_RANGE_IRQ (GT641XX_IRQ_BASE + 1)
+#define GT641XX_DMA_OUT_OF_RANGE_IRQ (GT641XX_IRQ_BASE + 2)
+#define GT641XX_CPU_ACCESS_OUT_OF_RANGE_IRQ (GT641XX_IRQ_BASE + 3)
+#define GT641XX_DMA0_IRQ (GT641XX_IRQ_BASE + 4)
+#define GT641XX_DMA1_IRQ (GT641XX_IRQ_BASE + 5)
+#define GT641XX_DMA2_IRQ (GT641XX_IRQ_BASE + 6)
+#define GT641XX_DMA3_IRQ (GT641XX_IRQ_BASE + 7)
+#define GT641XX_TIMER0_IRQ (GT641XX_IRQ_BASE + 8)
+#define GT641XX_TIMER1_IRQ (GT641XX_IRQ_BASE + 9)
+#define GT641XX_TIMER2_IRQ (GT641XX_IRQ_BASE + 10)
+#define GT641XX_TIMER3_IRQ (GT641XX_IRQ_BASE + 11)
+#define GT641XX_PCI_0_MASTER_READ_ERROR_IRQ (GT641XX_IRQ_BASE + 12)
+#define GT641XX_PCI_0_SLAVE_WRITE_ERROR_IRQ (GT641XX_IRQ_BASE + 13)
+#define GT641XX_PCI_0_MASTER_WRITE_ERROR_IRQ (GT641XX_IRQ_BASE + 14)
+#define GT641XX_PCI_0_SLAVE_READ_ERROR_IRQ (GT641XX_IRQ_BASE + 15)
+#define GT641XX_PCI_0_ADDRESS_ERROR_IRQ (GT641XX_IRQ_BASE + 16)
+#define GT641XX_MEMORY_ERROR_IRQ (GT641XX_IRQ_BASE + 17)
+#define GT641XX_PCI_0_MASTER_ABORT_IRQ (GT641XX_IRQ_BASE + 18)
+#define GT641XX_PCI_0_TARGET_ABORT_IRQ (GT641XX_IRQ_BASE + 19)
+#define GT641XX_PCI_0_RETRY_TIMEOUT_IRQ (GT641XX_IRQ_BASE + 20)
+#define GT641XX_CPU_INT0_IRQ (GT641XX_IRQ_BASE + 21)
+#define GT641XX_CPU_INT1_IRQ (GT641XX_IRQ_BASE + 22)
+#define GT641XX_CPU_INT2_IRQ (GT641XX_IRQ_BASE + 23)
+#define GT641XX_CPU_INT3_IRQ (GT641XX_IRQ_BASE + 24)
+#define GT641XX_CPU_INT4_IRQ (GT641XX_IRQ_BASE + 25)
+#define GT641XX_PCI_INT0_IRQ (GT641XX_IRQ_BASE + 26)
+#define GT641XX_PCI_INT1_IRQ (GT641XX_IRQ_BASE + 27)
+#define GT641XX_PCI_INT2_IRQ (GT641XX_IRQ_BASE + 28)
+#define GT641XX_PCI_INT3_IRQ (GT641XX_IRQ_BASE + 29)
+
+extern void gt641xx_irq_dispatch(void);
+extern void gt641xx_irq_init(void);
+
+#endif /* _ASM_IRQ_GT641XX_H */
diff --git a/arch/mips/include/asm/irq_regs.h b/arch/mips/include/asm/irq_regs.h
new file mode 100644
index 00000000..33bd2a06
--- /dev/null
+++ b/arch/mips/include/asm/irq_regs.h
@@ -0,0 +1,21 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_IRQ_REGS_H
+#define __ASM_IRQ_REGS_H
+
+#define ARCH_HAS_OWN_IRQ_REGS
+
+#include <linux/thread_info.h>
+
+static inline struct pt_regs *get_irq_regs(void)
+{
+ return current_thread_info()->regs;
+}
+
+#endif /* __ASM_IRQ_REGS_H */
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h
new file mode 100644
index 00000000..309cbcd6
--- /dev/null
+++ b/arch/mips/include/asm/irqflags.h
@@ -0,0 +1,288 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1996 by Paul M. Antoine
+ * Copyright (C) 1999 Silicon Graphics
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/compiler.h>
+#include <asm/hazards.h>
+
+__asm__(
+ " .macro arch_local_irq_enable \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n"
+ " ori $1, 0x400 \n"
+ " xori $1, 0x400 \n"
+ " mtc0 $1, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ " ei \n"
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+ " xori $1,0x1e \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_enable_hazard \n"
+ " .set pop \n"
+ " .endm");
+
+extern void smtc_ipi_replay(void);
+
+static inline void arch_local_irq_enable(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC kernel needs to do a software replay of queued
+ * IPIs, at the cost of call overhead on each local_irq_enable()
+ */
+ smtc_ipi_replay();
+#endif
+ __asm__ __volatile__(
+ "arch_local_irq_enable"
+ : /* no outputs */
+ : /* no inputs */
+ : "memory");
+}
+
+
+/*
+ * For cli() we have to insert nops to make sure that the new value
+ * has actually arrived in the status register before the end of this
+ * macro.
+ * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs
+ * no nops at all.
+ */
+/*
+ * For TX49, operating only IE bit is not enough.
+ *
+ * If mfc0 $12 follows store and the mfc0 is last instruction of a
+ * page and fetching the next instruction causes TLB miss, the result
+ * of the mfc0 might wrongly contain EXL bit.
+ *
+ * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008
+ *
+ * Workaround: mask EXL bit of the result or place a nop before mfc0.
+ */
+__asm__(
+ " .macro arch_local_irq_disable\n"
+ " .set push \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 $1, $2, 1 \n"
+ " ori $1, 0x400 \n"
+ " .set noreorder \n"
+ " mtc0 $1, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ " di \n"
+#else
+ " mfc0 $1,$12 \n"
+ " ori $1,0x1f \n"
+ " xori $1,0x1f \n"
+ " .set noreorder \n"
+ " mtc0 $1,$12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+static inline void arch_local_irq_disable(void)
+{
+ __asm__ __volatile__(
+ "arch_local_irq_disable"
+ : /* no outputs */
+ : /* no inputs */
+ : "memory");
+}
+
+__asm__(
+ " .macro arch_local_save_flags flags \n"
+ " .set push \n"
+ " .set reorder \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 \\flags, $2, 1 \n"
+#else
+ " mfc0 \\flags, $12 \n"
+#endif
+ " .set pop \n"
+ " .endm \n");
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile("arch_local_save_flags %0" : "=r" (flags));
+ return flags;
+}
+
+__asm__(
+ " .macro arch_local_irq_save result \n"
+ " .set push \n"
+ " .set reorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ " mfc0 \\result, $2, 1 \n"
+ " ori $1, \\result, 0x400 \n"
+ " .set noreorder \n"
+ " mtc0 $1, $2, 1 \n"
+ " andi \\result, \\result, 0x400 \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ " di \\result \n"
+ " andi \\result, 1 \n"
+#else
+ " mfc0 \\result, $12 \n"
+ " ori $1, \\result, 0x1f \n"
+ " xori $1, 0x1f \n"
+ " .set noreorder \n"
+ " mtc0 $1, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+ asm volatile("arch_local_irq_save\t%0"
+ : "=r" (flags)
+ : /* no inputs */
+ : "memory");
+ return flags;
+}
+
+__asm__(
+ " .macro arch_local_irq_restore flags \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+#ifdef CONFIG_MIPS_MT_SMTC
+ "mfc0 $1, $2, 1 \n"
+ "andi \\flags, 0x400 \n"
+ "ori $1, 0x400 \n"
+ "xori $1, 0x400 \n"
+ "or \\flags, $1 \n"
+ "mtc0 \\flags, $2, 1 \n"
+#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
+ /*
+ * Slow, but doesn't suffer from a relatively unlikely race
+ * condition we're having since days 1.
+ */
+ " beqz \\flags, 1f \n"
+ " di \n"
+ " ei \n"
+ "1: \n"
+#elif defined(CONFIG_CPU_MIPSR2)
+ /*
+ * Fast, dangerous. Life is fun, life is good.
+ */
+ " mfc0 $1, $12 \n"
+ " ins $1, \\flags, 0, 1 \n"
+ " mtc0 $1, $12 \n"
+#else
+ " mfc0 $1, $12 \n"
+ " andi \\flags, 1 \n"
+ " ori $1, 0x1f \n"
+ " xori $1, 0x1f \n"
+ " or \\flags, $1 \n"
+ " mtc0 \\flags, $12 \n"
+#endif
+ " irq_disable_hazard \n"
+ " .set pop \n"
+ " .endm \n");
+
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ unsigned long __tmp1;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC kernel needs to do a software replay of queued
+ * IPIs, at the cost of branch and call overhead on each
+ * local_irq_restore()
+ */
+ if (unlikely(!(flags & 0x0400)))
+ smtc_ipi_replay();
+#endif
+
+ __asm__ __volatile__(
+ "arch_local_irq_restore\t%0"
+ : "=r" (__tmp1)
+ : "0" (flags)
+ : "memory");
+}
+
+static inline void __arch_local_irq_restore(unsigned long flags)
+{
+ unsigned long __tmp1;
+
+ __asm__ __volatile__(
+ "arch_local_irq_restore\t%0"
+ : "=r" (__tmp1)
+ : "0" (flags)
+ : "memory");
+}
+
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU
+ */
+ return flags & 0x400;
+#else
+ return !(flags & 1);
+#endif
+}
+
+#endif
+
+/*
+ * Do the CPU's IRQ-state tracing from assembly code.
+ */
+#ifdef CONFIG_TRACE_IRQFLAGS
+/* Reload some registers clobbered by trace_hardirqs_on */
+#ifdef CONFIG_64BIT
+# define TRACE_IRQS_RELOAD_REGS \
+ LONG_L $11, PT_R11(sp); \
+ LONG_L $10, PT_R10(sp); \
+ LONG_L $9, PT_R9(sp); \
+ LONG_L $8, PT_R8(sp); \
+ LONG_L $7, PT_R7(sp); \
+ LONG_L $6, PT_R6(sp); \
+ LONG_L $5, PT_R5(sp); \
+ LONG_L $4, PT_R4(sp); \
+ LONG_L $2, PT_R2(sp)
+#else
+# define TRACE_IRQS_RELOAD_REGS \
+ LONG_L $7, PT_R7(sp); \
+ LONG_L $6, PT_R6(sp); \
+ LONG_L $5, PT_R5(sp); \
+ LONG_L $4, PT_R4(sp); \
+ LONG_L $2, PT_R2(sp)
+#endif
+# define TRACE_IRQS_ON \
+ CLI; /* make sure trace_hardirqs_on() is called in kernel level */ \
+ jal trace_hardirqs_on
+# define TRACE_IRQS_ON_RELOAD \
+ TRACE_IRQS_ON; \
+ TRACE_IRQS_RELOAD_REGS
+# define TRACE_IRQS_OFF \
+ jal trace_hardirqs_off
+#else
+# define TRACE_IRQS_ON
+# define TRACE_IRQS_ON_RELOAD
+# define TRACE_IRQS_OFF
+#endif
+
+#endif /* _ASM_IRQFLAGS_H */
diff --git a/arch/mips/include/asm/isadep.h b/arch/mips/include/asm/isadep.h
new file mode 100644
index 00000000..24c6cda7
--- /dev/null
+++ b/arch/mips/include/asm/isadep.h
@@ -0,0 +1,34 @@
+/*
+ * Various ISA level dependent constants.
+ * Most of the following constants reflect the different layout
+ * of Coprocessor 0 registers.
+ *
+ * Copyright (c) 1998 Harald Koerfgen
+ */
+
+#ifndef __ASM_ISADEP_H
+#define __ASM_ISADEP_H
+
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+/*
+ * R2000 or R3000
+ */
+
+/*
+ * kernel or user mode? (CP0_STATUS)
+ */
+#define KU_MASK 0x08
+#define KU_USER 0x08
+#define KU_KERN 0x00
+
+#else
+/*
+ * kernel or user mode?
+ */
+#define KU_MASK 0x18
+#define KU_USER 0x10
+#define KU_KERN 0x00
+
+#endif
+
+#endif /* __ASM_ISADEP_H */
diff --git a/arch/mips/include/asm/jazz.h b/arch/mips/include/asm/jazz.h
new file mode 100644
index 00000000..83f449de
--- /dev/null
+++ b/arch/mips/include/asm/jazz.h
@@ -0,0 +1,310 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 - 1998 by Andreas Busse and Ralf Baechle
+ */
+#ifndef __ASM_JAZZ_H
+#define __ASM_JAZZ_H
+
+/*
+ * The addresses below are virtual address. The mappings are
+ * created on startup via wired entries in the tlb. The Mips
+ * Magnum R3000 and R4000 machines are similar in many aspects,
+ * but many hardware register are accessible at 0xb9000000 in
+ * instead of 0xe0000000.
+ */
+
+#define JAZZ_LOCAL_IO_SPACE 0xe0000000
+
+/*
+ * Revision numbers in PICA_ASIC_REVISION
+ *
+ * 0xf0000000 - Rev1
+ * 0xf0000001 - Rev2
+ * 0xf0000002 - Rev3
+ */
+#define PICA_ASIC_REVISION 0xe0000008
+
+/*
+ * The segments of the seven segment LED are mapped
+ * to the control bits as follows:
+ *
+ * (7)
+ * ---------
+ * | |
+ * (2) | | (6)
+ * | (1) |
+ * ---------
+ * | |
+ * (3) | | (5)
+ * | (4) |
+ * --------- . (0)
+ */
+#define PICA_LED 0xe000f000
+
+/*
+ * Some characters for the LED control registers
+ * The original Mips machines seem to have a LED display
+ * with integrated decoder while the Acer machines can
+ * control each of the seven segments and the dot independently.
+ * It's only a toy, anyway...
+ */
+#define LED_DOT 0x01
+#define LED_SPACE 0x00
+#define LED_0 0xfc
+#define LED_1 0x60
+#define LED_2 0xda
+#define LED_3 0xf2
+#define LED_4 0x66
+#define LED_5 0xb6
+#define LED_6 0xbe
+#define LED_7 0xe0
+#define LED_8 0xfe
+#define LED_9 0xf6
+#define LED_A 0xee
+#define LED_b 0x3e
+#define LED_C 0x9c
+#define LED_d 0x7a
+#define LED_E 0x9e
+#define LED_F 0x8e
+
+#ifndef __ASSEMBLY__
+
+static __inline__ void pica_set_led(unsigned int bits)
+{
+ volatile unsigned int *led_register = (unsigned int *) PICA_LED;
+
+ *led_register = bits;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * Base address of the Sonic Ethernet adapter in Jazz machines.
+ */
+#define JAZZ_ETHERNET_BASE 0xe0001000
+
+/*
+ * Base address of the 53C94 SCSI hostadapter in Jazz machines.
+ */
+#define JAZZ_SCSI_BASE 0xe0002000
+
+/*
+ * i8042 keyboard controller for JAZZ and PICA chipsets.
+ * This address is just a guess and seems to differ from
+ * other mips machines such as RC3xxx...
+ */
+#define JAZZ_KEYBOARD_ADDRESS 0xe0005000
+#define JAZZ_KEYBOARD_DATA 0xe0005000
+#define JAZZ_KEYBOARD_COMMAND 0xe0005001
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned char data;
+ unsigned char command;
+} jazz_keyboard_hardware;
+
+#define jazz_kh ((keyboard_hardware *) JAZZ_KEYBOARD_ADDRESS)
+
+typedef struct {
+ unsigned char pad0[3];
+ unsigned char data;
+ unsigned char pad1[3];
+ unsigned char command;
+} mips_keyboard_hardware;
+
+/*
+ * For now. Needs to be changed for RC3xxx support. See below.
+ */
+#define keyboard_hardware jazz_keyboard_hardware
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * i8042 keyboard controller for most other Mips machines.
+ */
+#define MIPS_KEYBOARD_ADDRESS 0xb9005000
+#define MIPS_KEYBOARD_DATA 0xb9005003
+#define MIPS_KEYBOARD_COMMAND 0xb9005007
+
+/*
+ * Serial and parallel ports (WD 16C552) on the Mips JAZZ
+ */
+#define JAZZ_SERIAL1_BASE (unsigned int)0xe0006000
+#define JAZZ_SERIAL2_BASE (unsigned int)0xe0007000
+#define JAZZ_PARALLEL_BASE (unsigned int)0xe0008000
+
+/*
+ * Dummy Device Address. Used in jazzdma.c
+ */
+#define JAZZ_DUMMY_DEVICE 0xe000d000
+
+/*
+ * JAZZ timer registers and interrupt no.
+ * Note that the hardware timer interrupt is actually on
+ * cpu level 6, but to keep compatibility with PC stuff
+ * it is remapped to vector 0. See arch/mips/kernel/entry.S.
+ */
+#define JAZZ_TIMER_INTERVAL 0xe0000228
+#define JAZZ_TIMER_REGISTER 0xe0000230
+
+/*
+ * DRAM configuration register
+ */
+#ifndef __ASSEMBLY__
+#ifdef __MIPSEL__
+typedef struct {
+ unsigned int bank2 : 3;
+ unsigned int bank1 : 3;
+ unsigned int mem_bus_width : 1;
+ unsigned int reserved2 : 1;
+ unsigned int page_mode : 1;
+ unsigned int reserved1 : 23;
+} dram_configuration;
+#else /* defined (__MIPSEB__) */
+typedef struct {
+ unsigned int reserved1 : 23;
+ unsigned int page_mode : 1;
+ unsigned int reserved2 : 1;
+ unsigned int mem_bus_width : 1;
+ unsigned int bank1 : 3;
+ unsigned int bank2 : 3;
+} dram_configuration;
+#endif
+#endif /* !__ASSEMBLY__ */
+
+#define PICA_DRAM_CONFIG 0xe00fffe0
+
+/*
+ * JAZZ interrupt control registers
+ */
+#define JAZZ_IO_IRQ_SOURCE 0xe0010000
+#define JAZZ_IO_IRQ_ENABLE 0xe0010002
+
+/*
+ * JAZZ Interrupt Level definitions
+ *
+ * This is somewhat broken. For reasons which nobody can remember anymore
+ * we remap the Jazz interrupts to the usual ISA style interrupt numbers.
+ */
+#define JAZZ_IRQ_START 24
+#define JAZZ_IRQ_END (24 + 9)
+#define JAZZ_PARALLEL_IRQ (JAZZ_IRQ_START + 0)
+#define JAZZ_FLOPPY_IRQ (JAZZ_IRQ_START + 1)
+#define JAZZ_SOUND_IRQ (JAZZ_IRQ_START + 2)
+#define JAZZ_VIDEO_IRQ (JAZZ_IRQ_START + 3)
+#define JAZZ_ETHERNET_IRQ (JAZZ_IRQ_START + 4)
+#define JAZZ_SCSI_IRQ (JAZZ_IRQ_START + 5)
+#define JAZZ_KEYBOARD_IRQ (JAZZ_IRQ_START + 6)
+#define JAZZ_MOUSE_IRQ (JAZZ_IRQ_START + 7)
+#define JAZZ_SERIAL1_IRQ (JAZZ_IRQ_START + 8)
+#define JAZZ_SERIAL2_IRQ (JAZZ_IRQ_START + 9)
+
+#define JAZZ_TIMER_IRQ (MIPS_CPU_IRQ_BASE+6)
+
+
+/*
+ * JAZZ DMA Channels
+ * Note: Channels 4...7 are not used with respect to the Acer PICA-61
+ * chipset which does not provide these DMA channels.
+ */
+#define JAZZ_SCSI_DMA 0 /* SCSI */
+#define JAZZ_FLOPPY_DMA 1 /* FLOPPY */
+#define JAZZ_AUDIOL_DMA 2 /* AUDIO L */
+#define JAZZ_AUDIOR_DMA 3 /* AUDIO R */
+
+/*
+ * JAZZ R4030 MCT_ADR chip (DMA controller)
+ * Note: Virtual Addresses !
+ */
+#define JAZZ_R4030_CONFIG 0xE0000000 /* R4030 config register */
+#define JAZZ_R4030_REVISION 0xE0000008 /* same as PICA_ASIC_REVISION */
+#define JAZZ_R4030_INV_ADDR 0xE0000010 /* Invalid Address register */
+
+#define JAZZ_R4030_TRSTBL_BASE 0xE0000018 /* Translation Table Base */
+#define JAZZ_R4030_TRSTBL_LIM 0xE0000020 /* Translation Table Limit */
+#define JAZZ_R4030_TRSTBL_INV 0xE0000028 /* Translation Table Invalidate */
+
+#define JAZZ_R4030_CACHE_MTNC 0xE0000030 /* Cache Maintenance */
+#define JAZZ_R4030_R_FAIL_ADDR 0xE0000038 /* Remote Failed Address */
+#define JAZZ_R4030_M_FAIL_ADDR 0xE0000040 /* Memory Failed Address */
+
+#define JAZZ_R4030_CACHE_PTAG 0xE0000048 /* I/O Cache Physical Tag */
+#define JAZZ_R4030_CACHE_LTAG 0xE0000050 /* I/O Cache Logical Tag */
+#define JAZZ_R4030_CACHE_BMASK 0xE0000058 /* I/O Cache Byte Mask */
+#define JAZZ_R4030_CACHE_BWIN 0xE0000060 /* I/O Cache Buffer Window */
+
+/*
+ * Remote Speed Registers.
+ *
+ * 0: free, 1: Ethernet, 2: SCSI, 3: Floppy,
+ * 4: RTC, 5: Kb./Mouse 6: serial 1, 7: serial 2,
+ * 8: parallel, 9: NVRAM, 10: CPU, 11: PROM,
+ * 12: reserved, 13: free, 14: 7seg LED, 15: ???
+ */
+#define JAZZ_R4030_REM_SPEED 0xE0000070 /* 16 Remote Speed Registers */
+ /* 0xE0000070,78,80... 0xE00000E8 */
+#define JAZZ_R4030_IRQ_ENABLE 0xE00000E8 /* Internal Interrupt Enable */
+#define JAZZ_R4030_INVAL_ADDR 0xE0000010 /* Invalid address Register */
+#define JAZZ_R4030_IRQ_SOURCE 0xE0000200 /* Interrupt Source Register */
+#define JAZZ_R4030_I386_ERROR 0xE0000208 /* i386/EISA Bus Error */
+
+/*
+ * Virtual (E)ISA controller address
+ */
+#define JAZZ_EISA_IRQ_ACK 0xE0000238 /* EISA interrupt acknowledge */
+
+/*
+ * Access the R4030 DMA and I/O Controller
+ */
+#ifndef __ASSEMBLY__
+
+static inline void r4030_delay(void)
+{
+__asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\treorder");
+}
+
+static inline unsigned short r4030_read_reg16(unsigned long addr)
+{
+ unsigned short ret = *((volatile unsigned short *)addr);
+ r4030_delay();
+ return ret;
+}
+
+static inline unsigned int r4030_read_reg32(unsigned long addr)
+{
+ unsigned int ret = *((volatile unsigned int *)addr);
+ r4030_delay();
+ return ret;
+}
+
+static inline void r4030_write_reg16(unsigned long addr, unsigned val)
+{
+ *((volatile unsigned short *)addr) = val;
+ r4030_delay();
+}
+
+static inline void r4030_write_reg32(unsigned long addr, unsigned val)
+{
+ *((volatile unsigned int *)addr) = val;
+ r4030_delay();
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#define JAZZ_FDC_BASE 0xe0003000
+#define JAZZ_RTC_BASE 0xe0004000
+#define JAZZ_PORT_BASE 0xe2000000
+
+#define JAZZ_EISA_BASE 0xe3000000
+
+#endif /* __ASM_JAZZ_H */
diff --git a/arch/mips/include/asm/jazzdma.h b/arch/mips/include/asm/jazzdma.h
new file mode 100644
index 00000000..8bb37bba
--- /dev/null
+++ b/arch/mips/include/asm/jazzdma.h
@@ -0,0 +1,95 @@
+/*
+ * Helpfile for jazzdma.c -- Mips Jazz R4030 DMA controller support
+ */
+#ifndef _ASM_JAZZDMA_H
+#define _ASM_JAZZDMA_H
+
+/*
+ * Prototypes and macros
+ */
+extern unsigned long vdma_alloc(unsigned long paddr, unsigned long size);
+extern int vdma_free(unsigned long laddr);
+extern int vdma_remap(unsigned long laddr, unsigned long paddr,
+ unsigned long size);
+extern unsigned long vdma_phys2log(unsigned long paddr);
+extern unsigned long vdma_log2phys(unsigned long laddr);
+extern void vdma_stats(void); /* for debugging only */
+
+extern void vdma_enable(int channel);
+extern void vdma_disable(int channel);
+extern void vdma_set_mode(int channel, int mode);
+extern void vdma_set_addr(int channel, long addr);
+extern void vdma_set_count(int channel, int count);
+extern int vdma_get_residue(int channel);
+extern int vdma_get_enable(int channel);
+
+/*
+ * some definitions used by the driver functions
+ */
+#define VDMA_PAGESIZE 4096
+#define VDMA_PGTBL_ENTRIES 4096
+#define VDMA_PGTBL_SIZE (sizeof(VDMA_PGTBL_ENTRY) * VDMA_PGTBL_ENTRIES)
+#define VDMA_PAGE_EMPTY 0xff000000
+
+/*
+ * Macros to get page no. and offset of a given address
+ * Note that VDMA_PAGE() works for physical addresses only
+ */
+#define VDMA_PAGE(a) ((unsigned int)(a) >> 12)
+#define VDMA_OFFSET(a) ((unsigned int)(a) & (VDMA_PAGESIZE-1))
+
+/*
+ * error code returned by vdma_alloc()
+ * (See also arch/mips/kernel/jazzdma.c)
+ */
+#define VDMA_ERROR 0xffffffff
+
+/*
+ * VDMA pagetable entry description
+ */
+typedef volatile struct VDMA_PGTBL_ENTRY {
+ unsigned int frame; /* physical frame no. */
+ unsigned int owner; /* owner of this entry (0=free) */
+} VDMA_PGTBL_ENTRY;
+
+
+/*
+ * DMA channel control registers
+ * in the R4030 MCT_ADR chip
+ */
+#define JAZZ_R4030_CHNL_MODE 0xE0000100 /* 8 DMA Channel Mode Registers, */
+ /* 0xE0000100,120,140... */
+#define JAZZ_R4030_CHNL_ENABLE 0xE0000108 /* 8 DMA Channel Enable Regs, */
+ /* 0xE0000108,128,148... */
+#define JAZZ_R4030_CHNL_COUNT 0xE0000110 /* 8 DMA Channel Byte Cnt Regs, */
+ /* 0xE0000110,130,150... */
+#define JAZZ_R4030_CHNL_ADDR 0xE0000118 /* 8 DMA Channel Address Regs, */
+ /* 0xE0000118,138,158... */
+
+/* channel enable register bits */
+
+#define R4030_CHNL_ENABLE (1<<0)
+#define R4030_CHNL_WRITE (1<<1)
+#define R4030_TC_INTR (1<<8)
+#define R4030_MEM_INTR (1<<9)
+#define R4030_ADDR_INTR (1<<10)
+
+/*
+ * Channel mode register bits
+ */
+#define R4030_MODE_ATIME_40 (0) /* device access time on remote bus */
+#define R4030_MODE_ATIME_80 (1)
+#define R4030_MODE_ATIME_120 (2)
+#define R4030_MODE_ATIME_160 (3)
+#define R4030_MODE_ATIME_200 (4)
+#define R4030_MODE_ATIME_240 (5)
+#define R4030_MODE_ATIME_280 (6)
+#define R4030_MODE_ATIME_320 (7)
+#define R4030_MODE_WIDTH_8 (1<<3) /* device data bus width */
+#define R4030_MODE_WIDTH_16 (2<<3)
+#define R4030_MODE_WIDTH_32 (3<<3)
+#define R4030_MODE_INTR_EN (1<<5)
+#define R4030_MODE_BURST (1<<6) /* Rev. 2 only */
+#define R4030_MODE_FAST_ACK (1<<7) /* Rev. 2 only */
+
+#endif /* _ASM_JAZZDMA_H */
diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h
new file mode 100644
index 00000000..1881b316
--- /dev/null
+++ b/arch/mips/include/asm/jump_label.h
@@ -0,0 +1,50 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2010 Cavium Networks, Inc.
+ */
+#ifndef _ASM_MIPS_JUMP_LABEL_H
+#define _ASM_MIPS_JUMP_LABEL_H
+
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+
+#define JUMP_LABEL_NOP_SIZE 4
+
+#ifdef CONFIG_64BIT
+#define WORD_INSN ".dword"
+#else
+#define WORD_INSN ".word"
+#endif
+
+static __always_inline bool arch_static_branch(struct jump_label_key *key)
+{
+ asm goto("1:\tnop\n\t"
+ "nop\n\t"
+ ".pushsection __jump_table, \"aw\"\n\t"
+ WORD_INSN " 1b, %l[l_yes], %0\n\t"
+ ".popsection\n\t"
+ : : "i" (key) : : l_yes);
+ return false;
+l_yes:
+ return true;
+}
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_64BIT
+typedef u64 jump_label_t;
+#else
+typedef u32 jump_label_t;
+#endif
+
+struct jump_entry {
+ jump_label_t code;
+ jump_label_t target;
+ jump_label_t key;
+};
+
+#endif /* _ASM_MIPS_JUMP_LABEL_H */
diff --git a/arch/mips/include/asm/kdebug.h b/arch/mips/include/asm/kdebug.h
new file mode 100644
index 00000000..6a9af5fc
--- /dev/null
+++ b/arch/mips/include/asm/kdebug.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_MIPS_KDEBUG_H
+#define _ASM_MIPS_KDEBUG_H
+
+#include <linux/notifier.h>
+
+enum die_val {
+ DIE_OOPS = 1,
+ DIE_FP,
+ DIE_TRAP,
+ DIE_RI,
+ DIE_PAGE_FAULT,
+ DIE_BREAK,
+ DIE_SSTEPBP
+};
+
+#endif /* _ASM_MIPS_KDEBUG_H */
diff --git a/arch/mips/include/asm/kexec.h b/arch/mips/include/asm/kexec.h
new file mode 100644
index 00000000..4314892a
--- /dev/null
+++ b/arch/mips/include/asm/kexec.h
@@ -0,0 +1,30 @@
+/*
+ * kexec.h for kexec
+ * Created by <nschichan@corp.free.fr> on Thu Oct 12 14:59:34 2006
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#ifndef _MIPS_KEXEC
+# define _MIPS_KEXEC
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (0x20000000)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (0x20000000)
+ /* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000)
+
+#define KEXEC_CONTROL_PAGE_SIZE 4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_MIPS
+
+static inline void crash_setup_regs(struct pt_regs *newregs,
+ struct pt_regs *oldregs)
+{
+ /* Dummy implementation for now */
+}
+
+#endif /* !_MIPS_KEXEC */
diff --git a/arch/mips/include/asm/kgdb.h b/arch/mips/include/asm/kgdb.h
new file mode 100644
index 00000000..e6c0b0e1
--- /dev/null
+++ b/arch/mips/include/asm/kgdb.h
@@ -0,0 +1,45 @@
+#ifndef __ASM_KGDB_H_
+#define __ASM_KGDB_H_
+
+#ifdef __KERNEL__
+
+#include <asm/sgidefs.h>
+
+#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS32)
+
+#define KGDB_GDB_REG_SIZE 32
+#define GDB_SIZEOF_REG sizeof(u32)
+
+#elif (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
+ (_MIPS_ISA == _MIPS_ISA_MIPS64)
+
+#ifdef CONFIG_32BIT
+#define KGDB_GDB_REG_SIZE 32
+#define GDB_SIZEOF_REG sizeof(u32)
+#else /* CONFIG_CPU_32BIT */
+#define KGDB_GDB_REG_SIZE 64
+#define GDB_SIZEOF_REG sizeof(u64)
+#endif
+#else
+#error "Need to set KGDB_GDB_REG_SIZE for MIPS ISA"
+#endif /* _MIPS_ISA */
+
+#define BUFMAX 2048
+#define DBG_MAX_REG_NUM 72
+#define NUMREGBYTES (DBG_MAX_REG_NUM * sizeof(GDB_SIZEOF_REG))
+#define NUMCRITREGBYTES (12 * sizeof(GDB_SIZEOF_REG))
+#define BREAK_INSTR_SIZE 4
+#define CACHE_FLUSH_IS_SAFE 0
+
+extern void arch_kgdb_breakpoint(void);
+extern int kgdb_early_setup;
+extern void *saved_vectors[32];
+extern void handle_exception(struct pt_regs *regs);
+extern void breakinst(void);
+extern int kgdb_ll_trap(int cmd, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig);
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_KGDB_H_ */
diff --git a/arch/mips/include/asm/kmap_types.h b/arch/mips/include/asm/kmap_types.h
new file mode 100644
index 00000000..58e91ed0
--- /dev/null
+++ b/arch/mips/include/asm/kmap_types.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define __WITH_KM_FENCE
+#endif
+
+#include <asm-generic/kmap_types.h>
+
+#undef __WITH_KM_FENCE
+
+#endif
diff --git a/arch/mips/include/asm/kprobes.h b/arch/mips/include/asm/kprobes.h
new file mode 100644
index 00000000..e6ea4d4d
--- /dev/null
+++ b/arch/mips/include/asm/kprobes.h
@@ -0,0 +1,92 @@
+/*
+ * Kernel Probes (KProbes)
+ * include/asm-mips/kprobes.h
+ *
+ * Copyright 2006 Sony Corp.
+ * Copyright 2010 Cavium Networks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_KPROBES_H
+#define _ASM_KPROBES_H
+
+#include <linux/ptrace.h>
+#include <linux/types.h>
+
+#include <asm/cacheflush.h>
+#include <asm/kdebug.h>
+#include <asm/inst.h>
+
+#define __ARCH_WANT_KPROBES_INSN_SLOT
+
+struct kprobe;
+struct pt_regs;
+
+typedef union mips_instruction kprobe_opcode_t;
+
+#define MAX_INSN_SIZE 2
+
+#define flush_insn_slot(p) \
+do { \
+ flush_icache_range((unsigned long)p->addr, \
+ (unsigned long)p->addr + \
+ (MAX_INSN_SIZE * sizeof(kprobe_opcode_t))); \
+} while (0)
+
+
+#define kretprobe_blacklist_size 0
+
+void arch_remove_kprobe(struct kprobe *p);
+
+/* Architecture specific copy of original instruction*/
+struct arch_specific_insn {
+ /* copy of the original instruction */
+ kprobe_opcode_t *insn;
+};
+
+struct prev_kprobe {
+ struct kprobe *kp;
+ unsigned long status;
+ unsigned long old_SR;
+ unsigned long saved_SR;
+ unsigned long saved_epc;
+};
+
+#define MAX_JPROBES_STACK_SIZE 128
+#define MAX_JPROBES_STACK_ADDR \
+ (((unsigned long)current_thread_info()) + THREAD_SIZE - 32 - sizeof(struct pt_regs))
+
+#define MIN_JPROBES_STACK_SIZE(ADDR) \
+ ((((ADDR) + MAX_JPROBES_STACK_SIZE) > MAX_JPROBES_STACK_ADDR) \
+ ? MAX_JPROBES_STACK_ADDR - (ADDR) \
+ : MAX_JPROBES_STACK_SIZE)
+
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+ unsigned long kprobe_status;
+ unsigned long kprobe_old_SR;
+ unsigned long kprobe_saved_SR;
+ unsigned long kprobe_saved_epc;
+ unsigned long jprobe_saved_sp;
+ struct pt_regs jprobe_saved_regs;
+ u8 jprobes_stack[MAX_JPROBES_STACK_SIZE];
+ struct prev_kprobe prev_kprobe;
+};
+
+extern int kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data);
+
+#endif /* _ASM_KPROBES_H */
diff --git a/arch/mips/include/asm/kspd.h b/arch/mips/include/asm/kspd.h
new file mode 100644
index 00000000..4e9e724c
--- /dev/null
+++ b/arch/mips/include/asm/kspd.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _ASM_KSPD_H
+#define _ASM_KSPD_H
+
+struct kspd_notifications {
+ void (*kspd_sp_exit)(int sp_id);
+
+ struct list_head list;
+};
+
+#ifdef CONFIG_MIPS_APSP_KSPD
+extern void kspd_notify(struct kspd_notifications *notify);
+#else
+static inline void kspd_notify(struct kspd_notifications *notify)
+{
+}
+#endif
+
+#endif
diff --git a/arch/mips/include/asm/lasat/ds1603.h b/arch/mips/include/asm/lasat/ds1603.h
new file mode 100644
index 00000000..edcd7544
--- /dev/null
+++ b/arch/mips/include/asm/lasat/ds1603.h
@@ -0,0 +1,18 @@
+#include <asm/addrspace.h>
+
+/* Lasat 100 */
+#define DS1603_REG_100 (KSEG1ADDR(0x1c810000))
+#define DS1603_RST_100 (1 << 2)
+#define DS1603_CLK_100 (1 << 0)
+#define DS1603_DATA_SHIFT_100 1
+#define DS1603_DATA_100 (1 << DS1603_DATA_SHIFT_100)
+
+/* Lasat 200 */
+#define DS1603_REG_200 (KSEG1ADDR(0x11000000))
+#define DS1603_RST_200 (1 << 3)
+#define DS1603_CLK_200 (1 << 4)
+#define DS1603_DATA_200 (1 << 5)
+
+#define DS1603_DATA_REG_200 (DS1603_REG_200 + 0x10000)
+#define DS1603_DATA_READ_SHIFT_200 9
+#define DS1603_DATA_READ_200 (1 << DS1603_DATA_READ_SHIFT_200)
diff --git a/arch/mips/include/asm/lasat/eeprom.h b/arch/mips/include/asm/lasat/eeprom.h
new file mode 100644
index 00000000..3dac2036
--- /dev/null
+++ b/arch/mips/include/asm/lasat/eeprom.h
@@ -0,0 +1,17 @@
+#include <asm/addrspace.h>
+
+/* lasat 100 */
+#define AT93C_REG_100 KSEG1ADDR(0x1c810000)
+#define AT93C_RDATA_REG_100 AT93C_REG_100
+#define AT93C_RDATA_SHIFT_100 4
+#define AT93C_WDATA_SHIFT_100 4
+#define AT93C_CS_M_100 (1 << 5)
+#define AT93C_CLK_M_100 (1 << 3)
+
+/* lasat 200 */
+#define AT93C_REG_200 KSEG1ADDR(0x11000000)
+#define AT93C_RDATA_REG_200 (AT93C_REG_200+0x10000)
+#define AT93C_RDATA_SHIFT_200 8
+#define AT93C_WDATA_SHIFT_200 2
+#define AT93C_CS_M_200 (1 << 0)
+#define AT93C_CLK_M_200 (1 << 1)
diff --git a/arch/mips/include/asm/lasat/head.h b/arch/mips/include/asm/lasat/head.h
new file mode 100644
index 00000000..f5589f31
--- /dev/null
+++ b/arch/mips/include/asm/lasat/head.h
@@ -0,0 +1,22 @@
+/*
+ * Image header stuff
+ */
+#ifndef _HEAD_H
+#define _HEAD_H
+
+#define LASAT_K_MAGIC0_VAL 0xfedeabba
+#define LASAT_K_MAGIC1_VAL 0x00bedead
+
+#ifndef _LANGUAGE_ASSEMBLY
+#include <linux/types.h>
+struct bootloader_header {
+ u32 magic[2];
+ u32 version;
+ u32 image_start;
+ u32 image_size;
+ u32 kernel_start;
+ u32 kernel_entry;
+};
+#endif
+
+#endif /* _HEAD_H */
diff --git a/arch/mips/include/asm/lasat/lasat.h b/arch/mips/include/asm/lasat/lasat.h
new file mode 100644
index 00000000..a1ada1c2
--- /dev/null
+++ b/arch/mips/include/asm/lasat/lasat.h
@@ -0,0 +1,259 @@
+/*
+ * lasat.h
+ *
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Configuration for LASAT boards, loads the appropriate include files.
+ */
+#ifndef _LASAT_H
+#define _LASAT_H
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+extern struct lasat_misc {
+ volatile u32 *reset_reg;
+ volatile u32 *flash_wp_reg;
+ u32 flash_wp_bit;
+} *lasat_misc;
+
+enum lasat_mtdparts {
+ LASAT_MTD_BOOTLOADER,
+ LASAT_MTD_SERVICE,
+ LASAT_MTD_NORMAL,
+ LASAT_MTD_CONFIG,
+ LASAT_MTD_FS,
+ LASAT_MTD_LAST
+};
+
+/*
+ * The format of the data record in the EEPROM.
+ * See Documentation/LASAT/eeprom.txt for a detailed description
+ * of the fields in this struct, and the LASAT Hardware Configuration
+ * field specification for a detailed description of the config
+ * field.
+ */
+#include <linux/types.h>
+
+#define LASAT_EEPROM_VERSION 7
+struct lasat_eeprom_struct {
+ unsigned int version;
+ unsigned int cfg[3];
+ unsigned char hwaddr[6];
+ unsigned char print_partno[12];
+ unsigned char term0;
+ unsigned char print_serial[14];
+ unsigned char term1;
+ unsigned char prod_partno[12];
+ unsigned char term2;
+ unsigned char prod_serial[14];
+ unsigned char term3;
+ unsigned char passwd_hash[16];
+ unsigned char pwdnull;
+ unsigned char vendid;
+ unsigned char ts_ref;
+ unsigned char ts_signoff;
+ unsigned char reserved[11];
+ unsigned char debugaccess;
+ unsigned short prid;
+ unsigned int serviceflag;
+ unsigned int ipaddr;
+ unsigned int netmask;
+ unsigned int crc32;
+};
+
+struct lasat_eeprom_struct_pre7 {
+ unsigned int version;
+ unsigned int flags[3];
+ unsigned char hwaddr0[6];
+ unsigned char hwaddr1[6];
+ unsigned char print_partno[9];
+ unsigned char term0;
+ unsigned char print_serial[14];
+ unsigned char term1;
+ unsigned char prod_partno[9];
+ unsigned char term2;
+ unsigned char prod_serial[14];
+ unsigned char term3;
+ unsigned char passwd_hash[24];
+ unsigned char pwdnull;
+ unsigned char vendor;
+ unsigned char ts_ref;
+ unsigned char ts_signoff;
+ unsigned char reserved[6];
+ unsigned int writecount;
+ unsigned int ipaddr;
+ unsigned int netmask;
+ unsigned int crc32;
+};
+
+/* Configuration descriptor encoding - see the doc for details */
+
+#define LASAT_W0_DSCTYPE(v) (((v)) & 0xf)
+#define LASAT_W0_BMID(v) (((v) >> 0x04) & 0xf)
+#define LASAT_W0_CPUTYPE(v) (((v) >> 0x08) & 0xf)
+#define LASAT_W0_BUSSPEED(v) (((v) >> 0x0c) & 0xf)
+#define LASAT_W0_CPUCLK(v) (((v) >> 0x10) & 0xf)
+#define LASAT_W0_SDRAMBANKSZ(v) (((v) >> 0x14) & 0xf)
+#define LASAT_W0_SDRAMBANKS(v) (((v) >> 0x18) & 0xf)
+#define LASAT_W0_L2CACHE(v) (((v) >> 0x1c) & 0xf)
+
+#define LASAT_W1_EDHAC(v) (((v)) & 0xf)
+#define LASAT_W1_HIFN(v) (((v) >> 0x04) & 0x1)
+#define LASAT_W1_ISDN(v) (((v) >> 0x05) & 0x1)
+#define LASAT_W1_IDE(v) (((v) >> 0x06) & 0x1)
+#define LASAT_W1_HDLC(v) (((v) >> 0x07) & 0x1)
+#define LASAT_W1_USVERSION(v) (((v) >> 0x08) & 0x1)
+#define LASAT_W1_4MACS(v) (((v) >> 0x09) & 0x1)
+#define LASAT_W1_EXTSERIAL(v) (((v) >> 0x0a) & 0x1)
+#define LASAT_W1_FLASHSIZE(v) (((v) >> 0x0c) & 0xf)
+#define LASAT_W1_PCISLOTS(v) (((v) >> 0x10) & 0xf)
+#define LASAT_W1_PCI1OPT(v) (((v) >> 0x14) & 0xf)
+#define LASAT_W1_PCI2OPT(v) (((v) >> 0x18) & 0xf)
+#define LASAT_W1_PCI3OPT(v) (((v) >> 0x1c) & 0xf)
+
+/* Routines specific to LASAT boards */
+
+#define LASAT_BMID_MASQUERADE2 0
+#define LASAT_BMID_MASQUERADEPRO 1
+#define LASAT_BMID_SAFEPIPE25 2
+#define LASAT_BMID_SAFEPIPE50 3
+#define LASAT_BMID_SAFEPIPE100 4
+#define LASAT_BMID_SAFEPIPE5000 5
+#define LASAT_BMID_SAFEPIPE7000 6
+#define LASAT_BMID_SAFEPIPE1000 7
+#if 0
+#define LASAT_BMID_SAFEPIPE30 7
+#define LASAT_BMID_SAFEPIPE5100 8
+#define LASAT_BMID_SAFEPIPE7100 9
+#endif
+#define LASAT_BMID_UNKNOWN 0xf
+#define LASAT_MAX_BMID_NAMES 9 /* no larger than 15! */
+
+#define LASAT_HAS_EDHAC (1 << 0)
+#define LASAT_EDHAC_FAST (1 << 1)
+#define LASAT_HAS_EADI (1 << 2)
+#define LASAT_HAS_HIFN (1 << 3)
+#define LASAT_HAS_ISDN (1 << 4)
+#define LASAT_HAS_LEASEDLINE_IF (1 << 5)
+#define LASAT_HAS_HDC (1 << 6)
+
+#define LASAT_PRID_MASQUERADE2 0
+#define LASAT_PRID_MASQUERADEPRO 1
+#define LASAT_PRID_SAFEPIPE25 2
+#define LASAT_PRID_SAFEPIPE50 3
+#define LASAT_PRID_SAFEPIPE100 4
+#define LASAT_PRID_SAFEPIPE5000 5
+#define LASAT_PRID_SAFEPIPE7000 6
+#define LASAT_PRID_SAFEPIPE30 7
+#define LASAT_PRID_SAFEPIPE5100 8
+#define LASAT_PRID_SAFEPIPE7100 9
+
+#define LASAT_PRID_SAFEPIPE1110 10
+#define LASAT_PRID_SAFEPIPE3020 11
+#define LASAT_PRID_SAFEPIPE3030 12
+#define LASAT_PRID_SAFEPIPE5020 13
+#define LASAT_PRID_SAFEPIPE5030 14
+#define LASAT_PRID_SAFEPIPE1120 15
+#define LASAT_PRID_SAFEPIPE1130 16
+#define LASAT_PRID_SAFEPIPE6010 17
+#define LASAT_PRID_SAFEPIPE6110 18
+#define LASAT_PRID_SAFEPIPE6210 19
+#define LASAT_PRID_SAFEPIPE1020 20
+#define LASAT_PRID_SAFEPIPE1040 21
+#define LASAT_PRID_SAFEPIPE1060 22
+
+struct lasat_info {
+ unsigned int li_cpu_hz;
+ unsigned int li_bus_hz;
+ unsigned int li_bmid;
+ unsigned int li_memsize;
+ unsigned int li_flash_size;
+ unsigned int li_prid;
+ unsigned char li_bmstr[16];
+ unsigned char li_namestr[32];
+ unsigned char li_typestr[16];
+ /* Info on the Flash layout */
+ unsigned int li_flash_base;
+ unsigned long li_flashpart_base[LASAT_MTD_LAST];
+ unsigned long li_flashpart_size[LASAT_MTD_LAST];
+ struct lasat_eeprom_struct li_eeprom_info;
+ unsigned int li_eeprom_upgrade_version;
+ unsigned int li_debugaccess;
+};
+
+extern struct lasat_info lasat_board_info;
+
+static inline unsigned long lasat_flash_partition_start(int partno)
+{
+ if (partno < 0 || partno >= LASAT_MTD_LAST)
+ return 0;
+
+ return lasat_board_info.li_flashpart_base[partno];
+}
+
+static inline unsigned long lasat_flash_partition_size(int partno)
+{
+ if (partno < 0 || partno >= LASAT_MTD_LAST)
+ return 0;
+
+ return lasat_board_info.li_flashpart_size[partno];
+}
+
+/* Called from setup() to initialize the global board_info struct */
+extern int lasat_init_board_info(void);
+
+/* Write the modified EEPROM info struct */
+extern void lasat_write_eeprom_info(void);
+
+#define N_MACHTYPES 2
+/* for calibration of delays */
+
+/* the lasat_ndelay function is necessary because it is used at an
+ * early stage of the boot process where ndelay is not calibrated.
+ * It is used for the bit-banging rtc and eeprom drivers */
+
+#include <linux/delay.h>
+#include <linux/smp.h>
+
+/* calculating with the slowest board with 100 MHz clock */
+#define LASAT_100_DIVIDER 20
+/* All 200's run at 250 MHz clock */
+#define LASAT_200_DIVIDER 8
+
+extern unsigned int lasat_ndelay_divider;
+
+static inline void lasat_ndelay(unsigned int ns)
+{
+ __delay(ns / lasat_ndelay_divider);
+}
+
+#define IS_LASAT_200() (current_cpu_data.cputype == CPU_R5000)
+
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
+#define LASAT_SERVICEMODE_MAGIC_1 0xdeadbeef
+#define LASAT_SERVICEMODE_MAGIC_2 0xfedeabba
+
+/* Lasat 100 boards */
+#define LASAT_GT_BASE (KSEG1ADDR(0x14000000))
+
+/* Lasat 200 boards */
+#define Vrc5074_PHYS_BASE 0x1fa00000
+#define Vrc5074_BASE (KSEG1ADDR(Vrc5074_PHYS_BASE))
+#define PCI_WINDOW1 0x1a000000
+
+#endif /* _LASAT_H */
diff --git a/arch/mips/include/asm/lasat/lasatint.h b/arch/mips/include/asm/lasat/lasatint.h
new file mode 100644
index 00000000..e0d2458b
--- /dev/null
+++ b/arch/mips/include/asm/lasat/lasatint.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_LASAT_LASATINT_H
+#define __ASM_LASAT_LASATINT_H
+
+/* lasat 100 */
+#define LASAT_INT_STATUS_REG_100 (KSEG1ADDR(0x1c880000))
+#define LASAT_INT_MASK_REG_100 (KSEG1ADDR(0x1c890000))
+#define LASATINT_MASK_SHIFT_100 0
+
+/* lasat 200 */
+#define LASAT_INT_STATUS_REG_200 (KSEG1ADDR(0x1104003c))
+#define LASAT_INT_MASK_REG_200 (KSEG1ADDR(0x1104003c))
+#define LASATINT_MASK_SHIFT_200 16
+
+#endif /* __ASM_LASAT_LASATINT_H */
diff --git a/arch/mips/include/asm/lasat/picvue.h b/arch/mips/include/asm/lasat/picvue.h
new file mode 100644
index 00000000..42a492ed
--- /dev/null
+++ b/arch/mips/include/asm/lasat/picvue.h
@@ -0,0 +1,15 @@
+/* Lasat 100 */
+#define PVC_REG_100 KSEG1ADDR(0x1c820000)
+#define PVC_DATA_SHIFT_100 0
+#define PVC_DATA_M_100 0xFF
+#define PVC_E_100 (1 << 8)
+#define PVC_RW_100 (1 << 9)
+#define PVC_RS_100 (1 << 10)
+
+/* Lasat 200 */
+#define PVC_REG_200 KSEG1ADDR(0x11000000)
+#define PVC_DATA_SHIFT_200 24
+#define PVC_DATA_M_200 (0xFF << PVC_DATA_SHIFT_200)
+#define PVC_E_200 (1 << 16)
+#define PVC_RW_200 (1 << 17)
+#define PVC_RS_200 (1 << 18)
diff --git a/arch/mips/include/asm/lasat/serial.h b/arch/mips/include/asm/lasat/serial.h
new file mode 100644
index 00000000..1c37d705
--- /dev/null
+++ b/arch/mips/include/asm/lasat/serial.h
@@ -0,0 +1,13 @@
+#include <asm/lasat/lasat.h>
+
+/* Lasat 100 boards serial configuration */
+#define LASAT_BASE_BAUD_100 (7372800 / 16)
+#define LASAT_UART_REGS_BASE_100 0x1c8b0000
+#define LASAT_UART_REGS_SHIFT_100 2
+#define LASATINT_UART_100 16
+
+/* * LASAT 200 boards serial configuration */
+#define LASAT_BASE_BAUD_200 (100000000 / 16 / 12)
+#define LASAT_UART_REGS_BASE_200 (Vrc5074_PHYS_BASE + 0x0300)
+#define LASAT_UART_REGS_SHIFT_200 3
+#define LASATINT_UART_200 21
diff --git a/arch/mips/include/asm/linkage.h b/arch/mips/include/asm/linkage.h
new file mode 100644
index 00000000..e9a940d1
--- /dev/null
+++ b/arch/mips/include/asm/linkage.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#ifdef __ASSEMBLY__
+#include <asm/asm.h>
+#endif
+
+#define __weak __attribute__((weak))
+
+#endif
diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h
new file mode 100644
index 00000000..fffc8307
--- /dev/null
+++ b/arch/mips/include/asm/local.h
@@ -0,0 +1,196 @@
+#ifndef _ARCH_MIPS_LOCAL_H
+#define _ARCH_MIPS_LOCAL_H
+
+#include <linux/percpu.h>
+#include <linux/bitops.h>
+#include <asm/atomic.h>
+#include <asm/cmpxchg.h>
+#include <asm/war.h>
+
+typedef struct
+{
+ atomic_long_t a;
+} local_t;
+
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
+
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l, i) atomic_long_set(&(l)->a, (i))
+
+#define local_add(i, l) atomic_long_add((i), (&(l)->a))
+#define local_sub(i, l) atomic_long_sub((i), (&(l)->a))
+#define local_inc(l) atomic_long_inc(&(l)->a)
+#define local_dec(l) atomic_long_dec(&(l)->a)
+
+/*
+ * Same as above, but return the result value
+ */
+static __inline__ long local_add_return(long i, local_t * l)
+{
+ unsigned long result;
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_add_return \n"
+ " addu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqzl %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_add_return \n"
+ " addu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqz %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ result = l->a.counter;
+ result += i;
+ l->a.counter = result;
+ local_irq_restore(flags);
+ }
+
+ return result;
+}
+
+static __inline__ long local_sub_return(long i, local_t * l)
+{
+ unsigned long result;
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_return \n"
+ " subu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqzl %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1:" __LL "%1, %2 # local_sub_return \n"
+ " subu %0, %1, %3 \n"
+ __SC "%0, %2 \n"
+ " beqz %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " .set mips0 \n"
+ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+ : "Ir" (i), "m" (l->a.counter)
+ : "memory");
+ } else {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ result = l->a.counter;
+ result -= i;
+ l->a.counter = result;
+ local_irq_restore(flags);
+ }
+
+ return result;
+}
+
+#define local_cmpxchg(l, o, n) \
+ ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+#define local_add_unless(l, a, u) \
+({ \
+ long c, old; \
+ c = local_read(l); \
+ while (c != (u) && (old = local_cmpxchg((l), c, c + (a))) != c) \
+ c = old; \
+ c != (u); \
+})
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_dec_return(l) local_sub_return(1, (l))
+#define local_inc_return(l) local_add_return(1, (l))
+
+/*
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_sub_and_test(i, l) (local_sub_return((i), (l)) == 0)
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+/*
+ * local_dec_and_test - decrement by 1 and test
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0)
+
+/*
+ * local_add_negative - add and test if negative
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define local_add_negative(i, l) (local_add_return(i, (l)) < 0)
+
+/* Use these for per-cpu local_t variables: on some archs they are
+ * much more efficient than these naive implementations. Note they take
+ * a variable, not an address.
+ */
+
+#define __local_inc(l) ((l)->a.counter++)
+#define __local_dec(l) ((l)->a.counter++)
+#define __local_add(i, l) ((l)->a.counter+=(i))
+#define __local_sub(i, l) ((l)->a.counter-=(i))
+
+#endif /* _ARCH_MIPS_LOCAL_H */
diff --git a/arch/mips/include/asm/local64.h b/arch/mips/include/asm/local64.h
new file mode 100644
index 00000000..36c93b5c
--- /dev/null
+++ b/arch/mips/include/asm/local64.h
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
diff --git a/arch/mips/include/asm/m48t37.h b/arch/mips/include/asm/m48t37.h
new file mode 100644
index 00000000..cabf8626
--- /dev/null
+++ b/arch/mips/include/asm/m48t37.h
@@ -0,0 +1,35 @@
+/*
+ * Registers for the SGS-Thomson M48T37 Timekeeper RAM chip
+ */
+#ifndef _ASM_M48T37_H
+#define _ASM_M48T37_H
+
+#include <linux/spinlock.h>
+
+extern spinlock_t rtc_lock;
+
+struct m48t37_rtc {
+ volatile u8 pad[0x7ff0]; /* NVRAM */
+ volatile u8 flags;
+ volatile u8 century;
+ volatile u8 alarm_sec;
+ volatile u8 alarm_min;
+ volatile u8 alarm_hour;
+ volatile u8 alarm_data;
+ volatile u8 interrupts;
+ volatile u8 watchdog;
+ volatile u8 control;
+ volatile u8 sec;
+ volatile u8 min;
+ volatile u8 hour;
+ volatile u8 day;
+ volatile u8 date;
+ volatile u8 month;
+ volatile u8 year;
+};
+
+#define M48T37_RTC_SET 0x80
+#define M48T37_RTC_STOPPED 0x80
+#define M48T37_RTC_READ 0x40
+
+#endif /* _ASM_M48T37_H */
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h
new file mode 100644
index 00000000..07d3fadb
--- /dev/null
+++ b/arch/mips/include/asm/mach-ar7/ar7.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2006,2007 Eugene Konev <ejka@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __AR7_H__
+#define __AR7_H__
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+
+#include <asm/addrspace.h>
+
+#define AR7_SDRAM_BASE 0x14000000
+
+#define AR7_REGS_BASE 0x08610000
+
+#define AR7_REGS_MAC0 (AR7_REGS_BASE + 0x0000)
+#define AR7_REGS_GPIO (AR7_REGS_BASE + 0x0900)
+/* 0x08610A00 - 0x08610BFF (512 bytes, 128 bytes / clock) */
+#define AR7_REGS_POWER (AR7_REGS_BASE + 0x0a00)
+#define AR7_REGS_CLOCKS (AR7_REGS_POWER + 0x80)
+#define UR8_REGS_CLOCKS (AR7_REGS_POWER + 0x20)
+#define AR7_REGS_UART0 (AR7_REGS_BASE + 0x0e00)
+#define AR7_REGS_USB (AR7_REGS_BASE + 0x1200)
+#define AR7_REGS_RESET (AR7_REGS_BASE + 0x1600)
+#define AR7_REGS_PINSEL (AR7_REGS_BASE + 0x160C)
+#define AR7_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1800)
+#define AR7_REGS_DCL (AR7_REGS_BASE + 0x1a00)
+#define AR7_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1c00)
+#define AR7_REGS_MDIO (AR7_REGS_BASE + 0x1e00)
+#define AR7_REGS_IRQ (AR7_REGS_BASE + 0x2400)
+#define AR7_REGS_MAC1 (AR7_REGS_BASE + 0x2800)
+
+#define AR7_REGS_WDT (AR7_REGS_BASE + 0x1f00)
+#define UR8_REGS_WDT (AR7_REGS_BASE + 0x0b00)
+#define UR8_REGS_UART1 (AR7_REGS_BASE + 0x0f00)
+
+/* Titan registers */
+#define TITAN_REGS_ESWITCH_BASE (0x08640000)
+#define TITAN_REGS_MAC0 (TITAN_REGS_ESWITCH_BASE)
+#define TITAN_REGS_MAC1 (TITAN_REGS_ESWITCH_BASE + 0x0800)
+#define TITAN_REGS_MDIO (TITAN_REGS_ESWITCH_BASE + 0x02000)
+#define TITAN_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1c00)
+#define TITAN_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1300)
+
+#define AR7_RESET_PERIPHERAL 0x0
+#define AR7_RESET_SOFTWARE 0x4
+#define AR7_RESET_STATUS 0x8
+
+#define AR7_RESET_BIT_CPMAC_LO 17
+#define AR7_RESET_BIT_CPMAC_HI 21
+#define AR7_RESET_BIT_MDIO 22
+#define AR7_RESET_BIT_EPHY 26
+
+#define TITAN_RESET_BIT_EPHY1 28
+
+/* GPIO control registers */
+#define AR7_GPIO_INPUT 0x0
+#define AR7_GPIO_OUTPUT 0x4
+#define AR7_GPIO_DIR 0x8
+#define AR7_GPIO_ENABLE 0xc
+#define TITAN_GPIO_INPUT_0 0x0
+#define TITAN_GPIO_INPUT_1 0x4
+#define TITAN_GPIO_OUTPUT_0 0x8
+#define TITAN_GPIO_OUTPUT_1 0xc
+#define TITAN_GPIO_DIR_0 0x10
+#define TITAN_GPIO_DIR_1 0x14
+#define TITAN_GPIO_ENBL_0 0x18
+#define TITAN_GPIO_ENBL_1 0x1c
+
+#define AR7_CHIP_7100 0x18
+#define AR7_CHIP_7200 0x2b
+#define AR7_CHIP_7300 0x05
+#define AR7_CHIP_TITAN 0x07
+#define TITAN_CHIP_1050 0x0f
+#define TITAN_CHIP_1055 0x0e
+#define TITAN_CHIP_1056 0x0d
+#define TITAN_CHIP_1060 0x07
+
+/* Interrupts */
+#define AR7_IRQ_UART0 15
+#define AR7_IRQ_UART1 16
+
+/* Clocks */
+#define AR7_AFE_CLOCK 35328000
+#define AR7_REF_CLOCK 25000000
+#define AR7_XTAL_CLOCK 24000000
+
+/* DCL */
+#define AR7_WDT_HW_ENA 0x10
+
+struct plat_cpmac_data {
+ int reset_bit;
+ int power_bit;
+ u32 phy_mask;
+ char dev_addr[6];
+};
+
+struct plat_dsl_data {
+ int reset_bit_dsl;
+ int reset_bit_sar;
+};
+
+extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock;
+
+static inline int ar7_is_titan(void)
+{
+ return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x24)) & 0xffff) ==
+ AR7_CHIP_TITAN;
+}
+
+static inline u16 ar7_chip_id(void)
+{
+ return ar7_is_titan() ? AR7_CHIP_TITAN : (readl((void *)
+ KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff);
+}
+
+static inline u16 titan_chip_id(void)
+{
+ unsigned int val = readl((void *)KSEG1ADDR(AR7_REGS_GPIO +
+ TITAN_GPIO_INPUT_1));
+ return ((val >> 12) & 0x0f);
+}
+
+static inline u8 ar7_chip_rev(void)
+{
+ return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + (ar7_is_titan() ? 0x24 :
+ 0x14))) >> 16) & 0xff;
+}
+
+struct clk {
+ unsigned int rate;
+};
+
+static inline int ar7_has_high_cpmac(void)
+{
+ u16 chip_id = ar7_chip_id();
+ switch (chip_id) {
+ case AR7_CHIP_7100:
+ case AR7_CHIP_7200:
+ return 0;
+ case AR7_CHIP_7300:
+ return 1;
+ default:
+ return -ENXIO;
+ }
+}
+#define ar7_has_high_vlynq ar7_has_high_cpmac
+#define ar7_has_second_uart ar7_has_high_cpmac
+
+static inline void ar7_device_enable(u32 bit)
+{
+ void *reset_reg =
+ (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PERIPHERAL);
+ writel(readl(reset_reg) | (1 << bit), reset_reg);
+ msleep(20);
+}
+
+static inline void ar7_device_disable(u32 bit)
+{
+ void *reset_reg =
+ (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PERIPHERAL);
+ writel(readl(reset_reg) & ~(1 << bit), reset_reg);
+ msleep(20);
+}
+
+static inline void ar7_device_reset(u32 bit)
+{
+ ar7_device_disable(bit);
+ ar7_device_enable(bit);
+}
+
+static inline void ar7_device_on(u32 bit)
+{
+ void *power_reg = (void *)KSEG1ADDR(AR7_REGS_POWER);
+ writel(readl(power_reg) | (1 << bit), power_reg);
+ msleep(20);
+}
+
+static inline void ar7_device_off(u32 bit)
+{
+ void *power_reg = (void *)KSEG1ADDR(AR7_REGS_POWER);
+ writel(readl(power_reg) & ~(1 << bit), power_reg);
+ msleep(20);
+}
+
+int __init ar7_gpio_init(void);
+void __init ar7_init_clocks(void);
+
+#endif /* __AR7_H__ */
diff --git a/arch/mips/include/asm/mach-ar7/gpio.h b/arch/mips/include/asm/mach-ar7/gpio.h
new file mode 100644
index 00000000..c177cd1e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ar7/gpio.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2009 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __AR7_GPIO_H__
+#define __AR7_GPIO_H__
+
+#include <asm/mach-ar7/ar7.h>
+
+#define AR7_GPIO_MAX 32
+#define TITAN_GPIO_MAX 51
+#define NR_BUILTIN_GPIO TITAN_GPIO_MAX
+
+#define gpio_to_irq(gpio) -1
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+
+#define gpio_cansleep __gpio_cansleep
+
+/* Board specific GPIO functions */
+int ar7_gpio_enable(unsigned gpio);
+int ar7_gpio_disable(unsigned gpio);
+
+#include <asm-generic/gpio.h>
+
+#endif
diff --git a/arch/mips/include/asm/mach-ar7/irq.h b/arch/mips/include/asm/mach-ar7/irq.h
new file mode 100644
index 00000000..39e9757e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ar7/irq.h
@@ -0,0 +1,16 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Shamelessly copied from asm-mips/mach-emma2rh/
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#ifndef __ASM_AR7_IRQ_H
+#define __ASM_AR7_IRQ_H
+
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif /* __ASM_AR7_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ar7/prom.h b/arch/mips/include/asm/mach-ar7/prom.h
new file mode 100644
index 00000000..088f61fe
--- /dev/null
+++ b/arch/mips/include/asm/mach-ar7/prom.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2006, 2007 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __PROM_H__
+#define __PROM_H__
+
+extern char *prom_getenv(const char *name);
+extern void prom_meminit(void);
+
+#endif /* __PROM_H__ */
diff --git a/arch/mips/include/asm/mach-ar7/spaces.h b/arch/mips/include/asm/mach-ar7/spaces.h
new file mode 100644
index 00000000..ac28f273
--- /dev/null
+++ b/arch/mips/include/asm/mach-ar7/spaces.h
@@ -0,0 +1,22 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_AR7_SPACES_H
+#define _ASM_AR7_SPACES_H
+
+/*
+ * This handles the memory map.
+ * We handle pages at KSEG0 for kernels with 32 bit address space.
+ */
+#define PAGE_OFFSET 0x94000000UL
+#define PHYS_OFFSET 0x14000000UL
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_AR7_SPACES_H */
diff --git a/arch/mips/include/asm/mach-ar7/war.h b/arch/mips/include/asm/mach-ar7/war.h
new file mode 100644
index 00000000..f4862b56
--- /dev/null
+++ b/arch/mips/include/asm/mach-ar7/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_AR7_WAR_H
+#define __ASM_MIPS_MACH_AR7_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_AR7_WAR_H */
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
new file mode 100644
index 00000000..cda1c807
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -0,0 +1,233 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SoC register definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_AR71XX_REGS_H
+#define __ASM_MACH_AR71XX_REGS_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+
+#define AR71XX_APB_BASE 0x18000000
+#define AR71XX_SPI_BASE 0x1f000000
+#define AR71XX_SPI_SIZE 0x01000000
+
+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE 0x100
+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE 0x100
+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE 0x100
+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE 0x100
+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE 0x100
+
+#define AR913X_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
+#define AR913X_WMAC_SIZE 0x30000
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_PCI_WIN0 0x7c
+#define AR71XX_DDR_REG_PCI_WIN1 0x80
+#define AR71XX_DDR_REG_PCI_WIN2 0x84
+#define AR71XX_DDR_REG_PCI_WIN3 0x88
+#define AR71XX_DDR_REG_PCI_WIN4 0x8c
+#define AR71XX_DDR_REG_PCI_WIN5 0x90
+#define AR71XX_DDR_REG_PCI_WIN6 0x94
+#define AR71XX_DDR_REG_PCI_WIN7 0x98
+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
+#define AR71XX_DDR_REG_FLUSH_USB 0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0 0x7c
+#define AR724X_DDR_REG_FLUSH_GE1 0x80
+#define AR724X_DDR_REG_FLUSH_USB 0x84
+#define AR724X_DDR_REG_FLUSH_PCIE 0x88
+
+#define AR913X_DDR_REG_FLUSH_GE0 0x7c
+#define AR913X_DDR_REG_FLUSH_GE1 0x80
+#define AR913X_DDR_REG_FLUSH_USB 0x84
+#define AR913X_DDR_REG_FLUSH_WMAC 0x88
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG 0x00
+#define AR71XX_PLL_REG_SEC_CONFIG 0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
+
+#define AR71XX_PLL_DIV_SHIFT 3
+#define AR71XX_PLL_DIV_MASK 0x1f
+#define AR71XX_CPU_DIV_SHIFT 16
+#define AR71XX_CPU_DIV_MASK 0x3
+#define AR71XX_DDR_DIV_SHIFT 18
+#define AR71XX_DDR_DIV_MASK 0x3
+#define AR71XX_AHB_DIV_SHIFT 20
+#define AR71XX_AHB_DIV_MASK 0x7
+
+#define AR724X_PLL_REG_CPU_CONFIG 0x00
+#define AR724X_PLL_REG_PCIE_CONFIG 0x18
+
+#define AR724X_PLL_DIV_SHIFT 0
+#define AR724X_PLL_DIV_MASK 0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT 10
+#define AR724X_PLL_REF_DIV_MASK 0xf
+#define AR724X_AHB_DIV_SHIFT 19
+#define AR724X_AHB_DIV_MASK 0x1
+#define AR724X_DDR_DIV_SHIFT 22
+#define AR724X_DDR_DIV_MASK 0x3
+
+#define AR913X_PLL_REG_CPU_CONFIG 0x00
+#define AR913X_PLL_REG_ETH_CONFIG 0x04
+#define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14
+#define AR913X_PLL_REG_ETH1_INT_CLOCK 0x18
+
+#define AR913X_PLL_DIV_SHIFT 0
+#define AR913X_PLL_DIV_MASK 0x3ff
+#define AR913X_DDR_DIV_SHIFT 22
+#define AR913X_DDR_DIV_MASK 0x3
+#define AR913X_AHB_DIV_SHIFT 19
+#define AR913X_AHB_DIV_MASK 0x1
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER 0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
+#define AR71XX_RESET_REG_WDOG_CTRL 0x08
+#define AR71XX_RESET_REG_WDOG 0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
+#define AR71XX_RESET_REG_RESET_MODULE 0x24
+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
+#define AR71XX_RESET_REG_PERFC0 0x30
+#define AR71XX_RESET_REG_PERFC1 0x34
+#define AR71XX_RESET_REG_REV_ID 0x90
+
+#define AR913X_RESET_REG_GLOBAL_INT_STATUS 0x18
+#define AR913X_RESET_REG_RESET_MODULE 0x1c
+#define AR913X_RESET_REG_PERF_CTRL 0x20
+#define AR913X_RESET_REG_PERFC0 0x24
+#define AR913X_RESET_REG_PERFC1 0x28
+
+#define AR724X_RESET_REG_RESET_MODULE 0x1c
+
+#define MISC_INT_DMA BIT(7)
+#define MISC_INT_OHCI BIT(6)
+#define MISC_INT_PERFC BIT(5)
+#define MISC_INT_WDOG BIT(4)
+#define MISC_INT_UART BIT(3)
+#define MISC_INT_GPIO BIT(2)
+#define MISC_INT_ERROR BIT(1)
+#define MISC_INT_TIMER BIT(0)
+
+#define AR71XX_RESET_EXTERNAL BIT(28)
+#define AR71XX_RESET_FULL_CHIP BIT(24)
+#define AR71XX_RESET_CPU_NMI BIT(21)
+#define AR71XX_RESET_CPU_COLD BIT(20)
+#define AR71XX_RESET_DMA BIT(19)
+#define AR71XX_RESET_SLIC BIT(18)
+#define AR71XX_RESET_STEREO BIT(17)
+#define AR71XX_RESET_DDR BIT(16)
+#define AR71XX_RESET_GE1_MAC BIT(13)
+#define AR71XX_RESET_GE1_PHY BIT(12)
+#define AR71XX_RESET_USBSUS_OVERRIDE BIT(10)
+#define AR71XX_RESET_GE0_MAC BIT(9)
+#define AR71XX_RESET_GE0_PHY BIT(8)
+#define AR71XX_RESET_USB_OHCI_DLL BIT(6)
+#define AR71XX_RESET_USB_HOST BIT(5)
+#define AR71XX_RESET_USB_PHY BIT(4)
+#define AR71XX_RESET_PCI_BUS BIT(1)
+#define AR71XX_RESET_PCI_CORE BIT(0)
+
+#define AR724X_RESET_GE1_MDIO BIT(23)
+#define AR724X_RESET_GE0_MDIO BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
+#define AR724X_RESET_PCIE_PHY BIT(7)
+#define AR724X_RESET_PCIE BIT(6)
+#define AR724X_RESET_OHCI_DLL BIT(3)
+
+#define AR913X_RESET_AMBA2WMAC BIT(22)
+
+#define REV_ID_MAJOR_MASK 0xfff0
+#define REV_ID_MAJOR_AR71XX 0x00a0
+#define REV_ID_MAJOR_AR913X 0x00b0
+#define REV_ID_MAJOR_AR7240 0x00c0
+#define REV_ID_MAJOR_AR7241 0x0100
+#define REV_ID_MAJOR_AR7242 0x1100
+
+#define AR71XX_REV_ID_MINOR_MASK 0x3
+#define AR71XX_REV_ID_MINOR_AR7130 0x0
+#define AR71XX_REV_ID_MINOR_AR7141 0x1
+#define AR71XX_REV_ID_MINOR_AR7161 0x2
+#define AR71XX_REV_ID_REVISION_MASK 0x3
+#define AR71XX_REV_ID_REVISION_SHIFT 2
+
+#define AR913X_REV_ID_MINOR_MASK 0x3
+#define AR913X_REV_ID_MINOR_AR9130 0x0
+#define AR913X_REV_ID_MINOR_AR9132 0x1
+#define AR913X_REV_ID_REVISION_MASK 0x3
+#define AR913X_REV_ID_REVISION_SHIFT 2
+
+#define AR724X_REV_ID_REVISION_MASK 0x3
+
+/*
+ * SPI block
+ */
+#define AR71XX_SPI_REG_FS 0x00 /* Function Select */
+#define AR71XX_SPI_REG_CTRL 0x04 /* SPI Control */
+#define AR71XX_SPI_REG_IOC 0x08 /* SPI I/O Control */
+#define AR71XX_SPI_REG_RDS 0x0c /* Read Data Shift */
+
+#define AR71XX_SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
+
+#define AR71XX_SPI_CTRL_RD BIT(6) /* Remap Disable */
+#define AR71XX_SPI_CTRL_DIV_MASK 0x3f
+
+#define AR71XX_SPI_IOC_DO BIT(0) /* Data Out pin */
+#define AR71XX_SPI_IOC_CLK BIT(8) /* CLK pin */
+#define AR71XX_SPI_IOC_CS(n) BIT(16 + (n))
+#define AR71XX_SPI_IOC_CS0 AR71XX_SPI_IOC_CS(0)
+#define AR71XX_SPI_IOC_CS1 AR71XX_SPI_IOC_CS(1)
+#define AR71XX_SPI_IOC_CS2 AR71XX_SPI_IOC_CS(2)
+#define AR71XX_SPI_IOC_CS_ALL (AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
+ AR71XX_SPI_IOC_CS2)
+
+/*
+ * GPIO block
+ */
+#define AR71XX_GPIO_REG_OE 0x00
+#define AR71XX_GPIO_REG_IN 0x04
+#define AR71XX_GPIO_REG_OUT 0x08
+#define AR71XX_GPIO_REG_SET 0x0c
+#define AR71XX_GPIO_REG_CLEAR 0x10
+#define AR71XX_GPIO_REG_INT_MODE 0x14
+#define AR71XX_GPIO_REG_INT_TYPE 0x18
+#define AR71XX_GPIO_REG_INT_POLARITY 0x1c
+#define AR71XX_GPIO_REG_INT_PENDING 0x20
+#define AR71XX_GPIO_REG_INT_ENABLE 0x24
+#define AR71XX_GPIO_REG_FUNC 0x28
+
+#define AR71XX_GPIO_COUNT 16
+#define AR724X_GPIO_COUNT 18
+#define AR913X_GPIO_COUNT 22
+
+#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
new file mode 100644
index 00000000..6a9f1685
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -0,0 +1,96 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_ATH79_H
+#define __ASM_MACH_ATH79_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+enum ath79_soc_type {
+ ATH79_SOC_UNKNOWN,
+ ATH79_SOC_AR7130,
+ ATH79_SOC_AR7141,
+ ATH79_SOC_AR7161,
+ ATH79_SOC_AR7240,
+ ATH79_SOC_AR7241,
+ ATH79_SOC_AR7242,
+ ATH79_SOC_AR9130,
+ ATH79_SOC_AR9132
+};
+
+extern enum ath79_soc_type ath79_soc;
+
+static inline int soc_is_ar71xx(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7130 ||
+ ath79_soc == ATH79_SOC_AR7141 ||
+ ath79_soc == ATH79_SOC_AR7161);
+}
+
+static inline int soc_is_ar724x(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7240 ||
+ ath79_soc == ATH79_SOC_AR7241 ||
+ ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar7240(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7240);
+}
+
+static inline int soc_is_ar7241(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7241);
+}
+
+static inline int soc_is_ar7242(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar913x(void)
+{
+ return (ath79_soc == ATH79_SOC_AR9130 ||
+ ath79_soc == ATH79_SOC_AR9132);
+}
+
+extern void __iomem *ath79_ddr_base;
+extern void __iomem *ath79_pll_base;
+extern void __iomem *ath79_reset_base;
+
+static inline void ath79_pll_wr(unsigned reg, u32 val)
+{
+ __raw_writel(val, ath79_pll_base + reg);
+}
+
+static inline u32 ath79_pll_rr(unsigned reg)
+{
+ return __raw_readl(ath79_pll_base + reg);
+}
+
+static inline void ath79_reset_wr(unsigned reg, u32 val)
+{
+ __raw_writel(val, ath79_reset_base + reg);
+}
+
+static inline u32 ath79_reset_rr(unsigned reg)
+{
+ return __raw_readl(ath79_reset_base + reg);
+}
+
+void ath79_device_reset_set(u32 mask);
+void ath79_device_reset_clear(u32 mask);
+
+#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
new file mode 100644
index 00000000..aa2283e6
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
@@ -0,0 +1,23 @@
+/*
+ * Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_SPI_PLATFORM_H
+#define _ATH79_SPI_PLATFORM_H
+
+struct ath79_spi_platform_data {
+ unsigned bus_num;
+ unsigned num_chipselect;
+};
+
+struct ath79_spi_controller_data {
+ unsigned gpio;
+};
+
+#endif /* _ATH79_SPI_PLATFORM_H */
diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
new file mode 100644
index 00000000..4476fa03
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
@@ -0,0 +1,56 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific CPU feature overrides
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This file was derived from: include/asm-mips/cpu-features.h
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_sb1_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+
+#define cpu_has_prefetch 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+
+#define cpu_has_mips16 1
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 1
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_64bit_gp_regs 0
+#define cpu_has_64bit_addresses 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#endif /* __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ath79/gpio.h b/arch/mips/include/asm/mach-ath79/gpio.h
new file mode 100644
index 00000000..60dcb627
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/gpio.h
@@ -0,0 +1,26 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO API definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_MACH_ATH79_GPIO_H
+#define __ASM_MACH_ATH79_GPIO_H
+
+#define ARCH_NR_GPIOS 64
+#include <asm-generic/gpio.h>
+
+int gpio_to_irq(unsigned gpio);
+int irq_to_gpio(unsigned irq);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+
+#define gpio_cansleep __gpio_cansleep
+
+#endif /* __ASM_MACH_ATH79_GPIO_H */
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
new file mode 100644
index 00000000..189bc6eb
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/irq.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_ATH79_IRQ_H
+#define __ASM_MACH_ATH79_IRQ_H
+
+#define MIPS_CPU_IRQ_BASE 0
+#define NR_IRQS 16
+
+#define ATH79_MISC_IRQ_BASE 8
+#define ATH79_MISC_IRQ_COUNT 8
+
+#define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2)
+#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3)
+#define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4)
+#define ATH79_CPU_IRQ_GE1 (MIPS_CPU_IRQ_BASE + 5)
+#define ATH79_CPU_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6)
+#define ATH79_CPU_IRQ_TIMER (MIPS_CPU_IRQ_BASE + 7)
+
+#define ATH79_MISC_IRQ_TIMER (ATH79_MISC_IRQ_BASE + 0)
+#define ATH79_MISC_IRQ_ERROR (ATH79_MISC_IRQ_BASE + 1)
+#define ATH79_MISC_IRQ_GPIO (ATH79_MISC_IRQ_BASE + 2)
+#define ATH79_MISC_IRQ_UART (ATH79_MISC_IRQ_BASE + 3)
+#define ATH79_MISC_IRQ_WDOG (ATH79_MISC_IRQ_BASE + 4)
+#define ATH79_MISC_IRQ_PERFC (ATH79_MISC_IRQ_BASE + 5)
+#define ATH79_MISC_IRQ_OHCI (ATH79_MISC_IRQ_BASE + 6)
+#define ATH79_MISC_IRQ_DMA (ATH79_MISC_IRQ_BASE + 7)
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_ATH79_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ath79/kernel-entry-init.h b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
new file mode 100644
index 00000000..d8d046bc
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
@@ -0,0 +1,32 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific kernel entry setup
+ *
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_KERNEL_ENTRY_H
+#define __ASM_MACH_ATH79_KERNEL_ENTRY_H
+
+ /*
+ * Some bootloaders set the 'Kseg0 coherency algorithm' to
+ * 'Cacheable, noncoherent, write-through, no write allocate'
+ * and this cause performance issues. Let's go and change it to
+ * 'Cacheable, noncoherent, write-back, write allocate'
+ */
+ .macro kernel_entry_setup
+ mfc0 t0, CP0_CONFIG
+ li t1, ~CONF_CM_CMASK
+ and t0, t1
+ ori t0, CONF_CM_CACHABLE_NONCOHERENT
+ mtc0 t0, CP0_CONFIG
+ nop
+ .endm
+
+ .macro smp_slave_setup
+ .endm
+
+#endif /* __ASM_MACH_ATH79_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-ath79/war.h b/arch/mips/include/asm/mach-ath79/war.h
new file mode 100644
index 00000000..323d9f1d
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_ATH79_WAR_H
+#define __ASM_MACH_ATH79_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MACH_ATH79_WAR_H */
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h
new file mode 100644
index 00000000..f260ebed
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1000.h
@@ -0,0 +1,1538 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Include file for Alchemy Semiconductor's Au1k CPU.
+ *
+ * Copyright 2000-2001, 2006-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+ /*
+ * some definitions add by takuzo@sm.sony.co.jp and sato@sm.sony.co.jp
+ */
+
+#ifndef _AU1000_H_
+#define _AU1000_H_
+
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+#include <linux/delay.h>
+#include <linux/types.h>
+
+#include <linux/io.h>
+#include <linux/irq.h>
+
+/* cpu pipeline flush */
+void static inline au_sync(void)
+{
+ __asm__ volatile ("sync");
+}
+
+void static inline au_sync_udelay(int us)
+{
+ __asm__ volatile ("sync");
+ udelay(us);
+}
+
+void static inline au_sync_delay(int ms)
+{
+ __asm__ volatile ("sync");
+ mdelay(ms);
+}
+
+void static inline au_writeb(u8 val, unsigned long reg)
+{
+ *(volatile u8 *)reg = val;
+}
+
+void static inline au_writew(u16 val, unsigned long reg)
+{
+ *(volatile u16 *)reg = val;
+}
+
+void static inline au_writel(u32 val, unsigned long reg)
+{
+ *(volatile u32 *)reg = val;
+}
+
+static inline u8 au_readb(unsigned long reg)
+{
+ return *(volatile u8 *)reg;
+}
+
+static inline u16 au_readw(unsigned long reg)
+{
+ return *(volatile u16 *)reg;
+}
+
+static inline u32 au_readl(unsigned long reg)
+{
+ return *(volatile u32 *)reg;
+}
+
+/* Early Au1000 have a write-only SYS_CPUPLL register. */
+static inline int au1xxx_cpu_has_pll_wo(void)
+{
+ switch (read_c0_prid()) {
+ case 0x00030100: /* Au1000 DA */
+ case 0x00030201: /* Au1000 HA */
+ case 0x00030202: /* Au1000 HB */
+ return 1;
+ }
+ return 0;
+}
+
+/* does CPU need CONFIG[OD] set to fix tons of errata? */
+static inline int au1xxx_cpu_needs_config_od(void)
+{
+ /*
+ * c0_config.od (bit 19) was write only (and read as 0) on the
+ * early revisions of Alchemy SOCs. It disables the bus trans-
+ * action overlapping and needs to be set to fix various errata.
+ */
+ switch (read_c0_prid()) {
+ case 0x00030100: /* Au1000 DA */
+ case 0x00030201: /* Au1000 HA */
+ case 0x00030202: /* Au1000 HB */
+ case 0x01030200: /* Au1500 AB */
+ /*
+ * Au1100/Au1200 errata actually keep silence about this bit,
+ * so we set it just in case for those revisions that require
+ * it to be set according to the (now gone) cpu_table.
+ */
+ case 0x02030200: /* Au1100 AB */
+ case 0x02030201: /* Au1100 BA */
+ case 0x02030202: /* Au1100 BC */
+ case 0x04030201: /* Au1200 AC */
+ return 1;
+ }
+ return 0;
+}
+
+#define ALCHEMY_CPU_UNKNOWN -1
+#define ALCHEMY_CPU_AU1000 0
+#define ALCHEMY_CPU_AU1500 1
+#define ALCHEMY_CPU_AU1100 2
+#define ALCHEMY_CPU_AU1550 3
+#define ALCHEMY_CPU_AU1200 4
+
+static inline int alchemy_get_cputype(void)
+{
+ switch (read_c0_prid() & 0xffff0000) {
+ case 0x00030000:
+ return ALCHEMY_CPU_AU1000;
+ break;
+ case 0x01030000:
+ return ALCHEMY_CPU_AU1500;
+ break;
+ case 0x02030000:
+ return ALCHEMY_CPU_AU1100;
+ break;
+ case 0x03030000:
+ return ALCHEMY_CPU_AU1550;
+ break;
+ case 0x04030000:
+ case 0x05030000:
+ return ALCHEMY_CPU_AU1200;
+ break;
+ }
+
+ return ALCHEMY_CPU_UNKNOWN;
+}
+
+/* return number of uarts on a given cputype */
+static inline int alchemy_get_uarts(int type)
+{
+ switch (type) {
+ case ALCHEMY_CPU_AU1000:
+ return 4;
+ case ALCHEMY_CPU_AU1500:
+ case ALCHEMY_CPU_AU1200:
+ return 2;
+ case ALCHEMY_CPU_AU1100:
+ case ALCHEMY_CPU_AU1550:
+ return 3;
+ }
+ return 0;
+}
+
+/* enable an UART block if it isn't already */
+static inline void alchemy_uart_enable(u32 uart_phys)
+{
+ void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys);
+
+ /* reset, enable clock, deassert reset */
+ if ((__raw_readl(addr + 0x100) & 3) != 3) {
+ __raw_writel(0, addr + 0x100);
+ wmb();
+ __raw_writel(1, addr + 0x100);
+ wmb();
+ }
+ __raw_writel(3, addr + 0x100);
+ wmb();
+}
+
+static inline void alchemy_uart_disable(u32 uart_phys)
+{
+ void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys);
+ __raw_writel(0, addr + 0x100); /* UART_MOD_CNTRL */
+ wmb();
+}
+
+static inline void alchemy_uart_putchar(u32 uart_phys, u8 c)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys);
+ int timeout, i;
+
+ /* check LSR TX_EMPTY bit */
+ timeout = 0xffffff;
+ do {
+ if (__raw_readl(base + 0x1c) & 0x20)
+ break;
+ /* slow down */
+ for (i = 10000; i; i--)
+ asm volatile ("nop");
+ } while (--timeout);
+
+ __raw_writel(c, base + 0x04); /* tx */
+ wmb();
+}
+
+/* return number of ethernet MACs on a given cputype */
+static inline int alchemy_get_macs(int type)
+{
+ switch (type) {
+ case ALCHEMY_CPU_AU1000:
+ case ALCHEMY_CPU_AU1500:
+ case ALCHEMY_CPU_AU1550:
+ return 2;
+ case ALCHEMY_CPU_AU1100:
+ return 1;
+ }
+ return 0;
+}
+
+/* arch/mips/au1000/common/clocks.c */
+extern void set_au1x00_speed(unsigned int new_freq);
+extern unsigned int get_au1x00_speed(void);
+extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
+extern unsigned long get_au1x00_uart_baud_base(void);
+extern unsigned long au1xxx_calc_clock(void);
+
+/* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */
+void alchemy_sleep_au1000(void);
+void alchemy_sleep_au1550(void);
+void au_sleep(void);
+
+
+/* SOC Interrupt numbers */
+
+#define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 8)
+#define AU1000_INTC0_INT_LAST (AU1000_INTC0_INT_BASE + 31)
+#define AU1000_INTC1_INT_BASE (AU1000_INTC0_INT_LAST + 1)
+#define AU1000_INTC1_INT_LAST (AU1000_INTC1_INT_BASE + 31)
+#define AU1000_MAX_INTR AU1000_INTC1_INT_LAST
+
+enum soc_au1000_ints {
+ AU1000_FIRST_INT = AU1000_INTC0_INT_BASE,
+ AU1000_UART0_INT = AU1000_FIRST_INT,
+ AU1000_UART1_INT,
+ AU1000_UART2_INT,
+ AU1000_UART3_INT,
+ AU1000_SSI0_INT,
+ AU1000_SSI1_INT,
+ AU1000_DMA_INT_BASE,
+
+ AU1000_TOY_INT = AU1000_FIRST_INT + 14,
+ AU1000_TOY_MATCH0_INT,
+ AU1000_TOY_MATCH1_INT,
+ AU1000_TOY_MATCH2_INT,
+ AU1000_RTC_INT,
+ AU1000_RTC_MATCH0_INT,
+ AU1000_RTC_MATCH1_INT,
+ AU1000_RTC_MATCH2_INT,
+ AU1000_IRDA_TX_INT,
+ AU1000_IRDA_RX_INT,
+ AU1000_USB_DEV_REQ_INT,
+ AU1000_USB_DEV_SUS_INT,
+ AU1000_USB_HOST_INT,
+ AU1000_ACSYNC_INT,
+ AU1000_MAC0_DMA_INT,
+ AU1000_MAC1_DMA_INT,
+ AU1000_I2S_UO_INT,
+ AU1000_AC97C_INT,
+ AU1000_GPIO0_INT,
+ AU1000_GPIO1_INT,
+ AU1000_GPIO2_INT,
+ AU1000_GPIO3_INT,
+ AU1000_GPIO4_INT,
+ AU1000_GPIO5_INT,
+ AU1000_GPIO6_INT,
+ AU1000_GPIO7_INT,
+ AU1000_GPIO8_INT,
+ AU1000_GPIO9_INT,
+ AU1000_GPIO10_INT,
+ AU1000_GPIO11_INT,
+ AU1000_GPIO12_INT,
+ AU1000_GPIO13_INT,
+ AU1000_GPIO14_INT,
+ AU1000_GPIO15_INT,
+ AU1000_GPIO16_INT,
+ AU1000_GPIO17_INT,
+ AU1000_GPIO18_INT,
+ AU1000_GPIO19_INT,
+ AU1000_GPIO20_INT,
+ AU1000_GPIO21_INT,
+ AU1000_GPIO22_INT,
+ AU1000_GPIO23_INT,
+ AU1000_GPIO24_INT,
+ AU1000_GPIO25_INT,
+ AU1000_GPIO26_INT,
+ AU1000_GPIO27_INT,
+ AU1000_GPIO28_INT,
+ AU1000_GPIO29_INT,
+ AU1000_GPIO30_INT,
+ AU1000_GPIO31_INT,
+};
+
+enum soc_au1100_ints {
+ AU1100_FIRST_INT = AU1000_INTC0_INT_BASE,
+ AU1100_UART0_INT = AU1100_FIRST_INT,
+ AU1100_UART1_INT,
+ AU1100_SD_INT,
+ AU1100_UART3_INT,
+ AU1100_SSI0_INT,
+ AU1100_SSI1_INT,
+ AU1100_DMA_INT_BASE,
+
+ AU1100_TOY_INT = AU1100_FIRST_INT + 14,
+ AU1100_TOY_MATCH0_INT,
+ AU1100_TOY_MATCH1_INT,
+ AU1100_TOY_MATCH2_INT,
+ AU1100_RTC_INT,
+ AU1100_RTC_MATCH0_INT,
+ AU1100_RTC_MATCH1_INT,
+ AU1100_RTC_MATCH2_INT,
+ AU1100_IRDA_TX_INT,
+ AU1100_IRDA_RX_INT,
+ AU1100_USB_DEV_REQ_INT,
+ AU1100_USB_DEV_SUS_INT,
+ AU1100_USB_HOST_INT,
+ AU1100_ACSYNC_INT,
+ AU1100_MAC0_DMA_INT,
+ AU1100_GPIO208_215_INT,
+ AU1100_LCD_INT,
+ AU1100_AC97C_INT,
+ AU1100_GPIO0_INT,
+ AU1100_GPIO1_INT,
+ AU1100_GPIO2_INT,
+ AU1100_GPIO3_INT,
+ AU1100_GPIO4_INT,
+ AU1100_GPIO5_INT,
+ AU1100_GPIO6_INT,
+ AU1100_GPIO7_INT,
+ AU1100_GPIO8_INT,
+ AU1100_GPIO9_INT,
+ AU1100_GPIO10_INT,
+ AU1100_GPIO11_INT,
+ AU1100_GPIO12_INT,
+ AU1100_GPIO13_INT,
+ AU1100_GPIO14_INT,
+ AU1100_GPIO15_INT,
+ AU1100_GPIO16_INT,
+ AU1100_GPIO17_INT,
+ AU1100_GPIO18_INT,
+ AU1100_GPIO19_INT,
+ AU1100_GPIO20_INT,
+ AU1100_GPIO21_INT,
+ AU1100_GPIO22_INT,
+ AU1100_GPIO23_INT,
+ AU1100_GPIO24_INT,
+ AU1100_GPIO25_INT,
+ AU1100_GPIO26_INT,
+ AU1100_GPIO27_INT,
+ AU1100_GPIO28_INT,
+ AU1100_GPIO29_INT,
+ AU1100_GPIO30_INT,
+ AU1100_GPIO31_INT,
+};
+
+enum soc_au1500_ints {
+ AU1500_FIRST_INT = AU1000_INTC0_INT_BASE,
+ AU1500_UART0_INT = AU1500_FIRST_INT,
+ AU1500_PCI_INTA,
+ AU1500_PCI_INTB,
+ AU1500_UART3_INT,
+ AU1500_PCI_INTC,
+ AU1500_PCI_INTD,
+ AU1500_DMA_INT_BASE,
+
+ AU1500_TOY_INT = AU1500_FIRST_INT + 14,
+ AU1500_TOY_MATCH0_INT,
+ AU1500_TOY_MATCH1_INT,
+ AU1500_TOY_MATCH2_INT,
+ AU1500_RTC_INT,
+ AU1500_RTC_MATCH0_INT,
+ AU1500_RTC_MATCH1_INT,
+ AU1500_RTC_MATCH2_INT,
+ AU1500_PCI_ERR_INT,
+ AU1500_RESERVED_INT,
+ AU1500_USB_DEV_REQ_INT,
+ AU1500_USB_DEV_SUS_INT,
+ AU1500_USB_HOST_INT,
+ AU1500_ACSYNC_INT,
+ AU1500_MAC0_DMA_INT,
+ AU1500_MAC1_DMA_INT,
+ AU1500_AC97C_INT = AU1500_FIRST_INT + 31,
+ AU1500_GPIO0_INT,
+ AU1500_GPIO1_INT,
+ AU1500_GPIO2_INT,
+ AU1500_GPIO3_INT,
+ AU1500_GPIO4_INT,
+ AU1500_GPIO5_INT,
+ AU1500_GPIO6_INT,
+ AU1500_GPIO7_INT,
+ AU1500_GPIO8_INT,
+ AU1500_GPIO9_INT,
+ AU1500_GPIO10_INT,
+ AU1500_GPIO11_INT,
+ AU1500_GPIO12_INT,
+ AU1500_GPIO13_INT,
+ AU1500_GPIO14_INT,
+ AU1500_GPIO15_INT,
+ AU1500_GPIO200_INT,
+ AU1500_GPIO201_INT,
+ AU1500_GPIO202_INT,
+ AU1500_GPIO203_INT,
+ AU1500_GPIO20_INT,
+ AU1500_GPIO204_INT,
+ AU1500_GPIO205_INT,
+ AU1500_GPIO23_INT,
+ AU1500_GPIO24_INT,
+ AU1500_GPIO25_INT,
+ AU1500_GPIO26_INT,
+ AU1500_GPIO27_INT,
+ AU1500_GPIO28_INT,
+ AU1500_GPIO206_INT,
+ AU1500_GPIO207_INT,
+ AU1500_GPIO208_215_INT,
+};
+
+enum soc_au1550_ints {
+ AU1550_FIRST_INT = AU1000_INTC0_INT_BASE,
+ AU1550_UART0_INT = AU1550_FIRST_INT,
+ AU1550_PCI_INTA,
+ AU1550_PCI_INTB,
+ AU1550_DDMA_INT,
+ AU1550_CRYPTO_INT,
+ AU1550_PCI_INTC,
+ AU1550_PCI_INTD,
+ AU1550_PCI_RST_INT,
+ AU1550_UART1_INT,
+ AU1550_UART3_INT,
+ AU1550_PSC0_INT,
+ AU1550_PSC1_INT,
+ AU1550_PSC2_INT,
+ AU1550_PSC3_INT,
+ AU1550_TOY_INT,
+ AU1550_TOY_MATCH0_INT,
+ AU1550_TOY_MATCH1_INT,
+ AU1550_TOY_MATCH2_INT,
+ AU1550_RTC_INT,
+ AU1550_RTC_MATCH0_INT,
+ AU1550_RTC_MATCH1_INT,
+ AU1550_RTC_MATCH2_INT,
+
+ AU1550_NAND_INT = AU1550_FIRST_INT + 23,
+ AU1550_USB_DEV_REQ_INT,
+ AU1550_USB_DEV_SUS_INT,
+ AU1550_USB_HOST_INT,
+ AU1550_MAC0_DMA_INT,
+ AU1550_MAC1_DMA_INT,
+ AU1550_GPIO0_INT = AU1550_FIRST_INT + 32,
+ AU1550_GPIO1_INT,
+ AU1550_GPIO2_INT,
+ AU1550_GPIO3_INT,
+ AU1550_GPIO4_INT,
+ AU1550_GPIO5_INT,
+ AU1550_GPIO6_INT,
+ AU1550_GPIO7_INT,
+ AU1550_GPIO8_INT,
+ AU1550_GPIO9_INT,
+ AU1550_GPIO10_INT,
+ AU1550_GPIO11_INT,
+ AU1550_GPIO12_INT,
+ AU1550_GPIO13_INT,
+ AU1550_GPIO14_INT,
+ AU1550_GPIO15_INT,
+ AU1550_GPIO200_INT,
+ AU1550_GPIO201_205_INT, /* Logical or of GPIO201:205 */
+ AU1550_GPIO16_INT,
+ AU1550_GPIO17_INT,
+ AU1550_GPIO20_INT,
+ AU1550_GPIO21_INT,
+ AU1550_GPIO22_INT,
+ AU1550_GPIO23_INT,
+ AU1550_GPIO24_INT,
+ AU1550_GPIO25_INT,
+ AU1550_GPIO26_INT,
+ AU1550_GPIO27_INT,
+ AU1550_GPIO28_INT,
+ AU1550_GPIO206_INT,
+ AU1550_GPIO207_INT,
+ AU1550_GPIO208_215_INT, /* Logical or of GPIO208:215 */
+};
+
+enum soc_au1200_ints {
+ AU1200_FIRST_INT = AU1000_INTC0_INT_BASE,
+ AU1200_UART0_INT = AU1200_FIRST_INT,
+ AU1200_SWT_INT,
+ AU1200_SD_INT,
+ AU1200_DDMA_INT,
+ AU1200_MAE_BE_INT,
+ AU1200_GPIO200_INT,
+ AU1200_GPIO201_INT,
+ AU1200_GPIO202_INT,
+ AU1200_UART1_INT,
+ AU1200_MAE_FE_INT,
+ AU1200_PSC0_INT,
+ AU1200_PSC1_INT,
+ AU1200_AES_INT,
+ AU1200_CAMERA_INT,
+ AU1200_TOY_INT,
+ AU1200_TOY_MATCH0_INT,
+ AU1200_TOY_MATCH1_INT,
+ AU1200_TOY_MATCH2_INT,
+ AU1200_RTC_INT,
+ AU1200_RTC_MATCH0_INT,
+ AU1200_RTC_MATCH1_INT,
+ AU1200_RTC_MATCH2_INT,
+ AU1200_GPIO203_INT,
+ AU1200_NAND_INT,
+ AU1200_GPIO204_INT,
+ AU1200_GPIO205_INT,
+ AU1200_GPIO206_INT,
+ AU1200_GPIO207_INT,
+ AU1200_GPIO208_215_INT, /* Logical OR of 208:215 */
+ AU1200_USB_INT,
+ AU1200_LCD_INT,
+ AU1200_MAE_BOTH_INT,
+ AU1200_GPIO0_INT,
+ AU1200_GPIO1_INT,
+ AU1200_GPIO2_INT,
+ AU1200_GPIO3_INT,
+ AU1200_GPIO4_INT,
+ AU1200_GPIO5_INT,
+ AU1200_GPIO6_INT,
+ AU1200_GPIO7_INT,
+ AU1200_GPIO8_INT,
+ AU1200_GPIO9_INT,
+ AU1200_GPIO10_INT,
+ AU1200_GPIO11_INT,
+ AU1200_GPIO12_INT,
+ AU1200_GPIO13_INT,
+ AU1200_GPIO14_INT,
+ AU1200_GPIO15_INT,
+ AU1200_GPIO16_INT,
+ AU1200_GPIO17_INT,
+ AU1200_GPIO18_INT,
+ AU1200_GPIO19_INT,
+ AU1200_GPIO20_INT,
+ AU1200_GPIO21_INT,
+ AU1200_GPIO22_INT,
+ AU1200_GPIO23_INT,
+ AU1200_GPIO24_INT,
+ AU1200_GPIO25_INT,
+ AU1200_GPIO26_INT,
+ AU1200_GPIO27_INT,
+ AU1200_GPIO28_INT,
+ AU1200_GPIO29_INT,
+ AU1200_GPIO30_INT,
+ AU1200_GPIO31_INT,
+};
+
+#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+
+/*
+ * SDRAM register offsets
+ */
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
+ defined(CONFIG_SOC_AU1100)
+#define MEM_SDMODE0 0x0000
+#define MEM_SDMODE1 0x0004
+#define MEM_SDMODE2 0x0008
+#define MEM_SDADDR0 0x000C
+#define MEM_SDADDR1 0x0010
+#define MEM_SDADDR2 0x0014
+#define MEM_SDREFCFG 0x0018
+#define MEM_SDPRECMD 0x001C
+#define MEM_SDAUTOREF 0x0020
+#define MEM_SDWRMD0 0x0024
+#define MEM_SDWRMD1 0x0028
+#define MEM_SDWRMD2 0x002C
+#define MEM_SDSLEEP 0x0030
+#define MEM_SDSMCKE 0x0034
+
+/*
+ * MEM_SDMODE register content definitions
+ */
+#define MEM_SDMODE_F (1 << 22)
+#define MEM_SDMODE_SR (1 << 21)
+#define MEM_SDMODE_BS (1 << 20)
+#define MEM_SDMODE_RS (3 << 18)
+#define MEM_SDMODE_CS (7 << 15)
+#define MEM_SDMODE_TRAS (15 << 11)
+#define MEM_SDMODE_TMRD (3 << 9)
+#define MEM_SDMODE_TWR (3 << 7)
+#define MEM_SDMODE_TRP (3 << 5)
+#define MEM_SDMODE_TRCD (3 << 3)
+#define MEM_SDMODE_TCL (7 << 0)
+
+#define MEM_SDMODE_BS_2Bank (0 << 20)
+#define MEM_SDMODE_BS_4Bank (1 << 20)
+#define MEM_SDMODE_RS_11Row (0 << 18)
+#define MEM_SDMODE_RS_12Row (1 << 18)
+#define MEM_SDMODE_RS_13Row (2 << 18)
+#define MEM_SDMODE_RS_N(N) ((N) << 18)
+#define MEM_SDMODE_CS_7Col (0 << 15)
+#define MEM_SDMODE_CS_8Col (1 << 15)
+#define MEM_SDMODE_CS_9Col (2 << 15)
+#define MEM_SDMODE_CS_10Col (3 << 15)
+#define MEM_SDMODE_CS_11Col (4 << 15)
+#define MEM_SDMODE_CS_N(N) ((N) << 15)
+#define MEM_SDMODE_TRAS_N(N) ((N) << 11)
+#define MEM_SDMODE_TMRD_N(N) ((N) << 9)
+#define MEM_SDMODE_TWR_N(N) ((N) << 7)
+#define MEM_SDMODE_TRP_N(N) ((N) << 5)
+#define MEM_SDMODE_TRCD_N(N) ((N) << 3)
+#define MEM_SDMODE_TCL_N(N) ((N) << 0)
+
+/*
+ * MEM_SDADDR register contents definitions
+ */
+#define MEM_SDADDR_E (1 << 20)
+#define MEM_SDADDR_CSBA (0x03FF << 10)
+#define MEM_SDADDR_CSMASK (0x03FF << 0)
+#define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12)
+#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22)
+
+/*
+ * MEM_SDREFCFG register content definitions
+ */
+#define MEM_SDREFCFG_TRC (15 << 28)
+#define MEM_SDREFCFG_TRPM (3 << 26)
+#define MEM_SDREFCFG_E (1 << 25)
+#define MEM_SDREFCFG_RE (0x1ffffff << 0)
+#define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC)
+#define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM)
+#define MEM_SDREFCFG_REF_N(N) (N)
+#endif
+
+/***********************************************************************/
+
+/*
+ * Au1550 SDRAM Register Offsets
+ */
+
+/***********************************************************************/
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+#define MEM_SDMODE0 0x0800
+#define MEM_SDMODE1 0x0808
+#define MEM_SDMODE2 0x0810
+#define MEM_SDADDR0 0x0820
+#define MEM_SDADDR1 0x0828
+#define MEM_SDADDR2 0x0830
+#define MEM_SDCONFIGA 0x0840
+#define MEM_SDCONFIGB 0x0848
+#define MEM_SDSTAT 0x0850
+#define MEM_SDERRADDR 0x0858
+#define MEM_SDSTRIDE0 0x0860
+#define MEM_SDSTRIDE1 0x0868
+#define MEM_SDSTRIDE2 0x0870
+#define MEM_SDWRMD0 0x0880
+#define MEM_SDWRMD1 0x0888
+#define MEM_SDWRMD2 0x0890
+#define MEM_SDPRECMD 0x08C0
+#define MEM_SDAUTOREF 0x08C8
+#define MEM_SDSREF 0x08D0
+#define MEM_SDSLEEP MEM_SDSREF
+
+#endif
+
+/*
+ * Physical base addresses for integrated peripherals
+ * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200
+ */
+
+#define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */
+#define AU1000_USBD_PHYS_ADDR 0x10200000 /* 0123 */
+#define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */
+#define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */
+#define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */
+#define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */
+#define AU1100_SD0_PHYS_ADDR 0x10600000 /* 24 */
+#define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */
+#define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */
+#define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */
+#define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */
+#define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */
+#define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */
+#define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */
+#define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */
+#define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */
+#define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */
+#define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */
+#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */
+#define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */
+#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */
+#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */
+#define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */
+#define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */
+
+
+#ifdef CONFIG_SOC_AU1000
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define USBH_PHYS_ADDR 0x10100000
+#define IRDA_PHYS_ADDR 0x10300000
+#define SSI0_PHYS_ADDR 0x11600000
+#define SSI1_PHYS_ADDR 0x11680000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/********************************************************************/
+
+#ifdef CONFIG_SOC_AU1500
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define USBH_PHYS_ADDR 0x10100000
+#define PCI_PHYS_ADDR 0x14005000
+#define PCI_MEM_PHYS_ADDR 0x400000000ULL
+#define PCI_IO_PHYS_ADDR 0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/********************************************************************/
+
+#ifdef CONFIG_SOC_AU1100
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define USBH_PHYS_ADDR 0x10100000
+#define IRDA_PHYS_ADDR 0x10300000
+#define SSI0_PHYS_ADDR 0x11600000
+#define SSI1_PHYS_ADDR 0x11680000
+#define LCD_PHYS_ADDR 0x15000000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_SOC_AU1550
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define USBH_PHYS_ADDR 0x14020000
+#define PCI_PHYS_ADDR 0x14005000
+#define PE_PHYS_ADDR 0x14008000
+#define PSC0_PHYS_ADDR 0x11A00000
+#define PSC1_PHYS_ADDR 0x11B00000
+#define PSC2_PHYS_ADDR 0x10A00000
+#define PSC3_PHYS_ADDR 0x10B00000
+#define PCI_MEM_PHYS_ADDR 0x400000000ULL
+#define PCI_IO_PHYS_ADDR 0x500000000ULL
+#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
+#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/***********************************************************************/
+
+#ifdef CONFIG_SOC_AU1200
+#define MEM_PHYS_ADDR 0x14000000
+#define STATIC_MEM_PHYS_ADDR 0x14001000
+#define AES_PHYS_ADDR 0x10300000
+#define CIM_PHYS_ADDR 0x14004000
+#define USBM_PHYS_ADDR 0x14020000
+#define USBH_PHYS_ADDR 0x14020100
+#define PSC0_PHYS_ADDR 0x11A00000
+#define PSC1_PHYS_ADDR 0x11B00000
+#define LCD_PHYS_ADDR 0x15000000
+#define SWCNT_PHYS_ADDR 0x1110010C
+#define MAEFE_PHYS_ADDR 0x14012000
+#define MAEBE_PHYS_ADDR 0x14010000
+#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
+#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
+#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
+#endif
+
+/* Static Bus Controller */
+#define MEM_STCFG0 0xB4001000
+#define MEM_STTIME0 0xB4001004
+#define MEM_STADDR0 0xB4001008
+
+#define MEM_STCFG1 0xB4001010
+#define MEM_STTIME1 0xB4001014
+#define MEM_STADDR1 0xB4001018
+
+#define MEM_STCFG2 0xB4001020
+#define MEM_STTIME2 0xB4001024
+#define MEM_STADDR2 0xB4001028
+
+#define MEM_STCFG3 0xB4001030
+#define MEM_STTIME3 0xB4001034
+#define MEM_STADDR3 0xB4001038
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+#define MEM_STNDCTL 0xB4001100
+#define MEM_STSTAT 0xB4001104
+
+#define MEM_STNAND_CMD 0x0
+#define MEM_STNAND_ADDR 0x4
+#define MEM_STNAND_DATA 0x20
+#endif
+
+
+
+
+/* Au1000 */
+#ifdef CONFIG_SOC_AU1000
+
+#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
+#define USB_HOST_CONFIG 0xB017FFFC
+#define FOR_PLATFORM_C_USB_HOST_INT AU1000_USB_HOST_INT
+#endif /* CONFIG_SOC_AU1000 */
+
+/* Au1500 */
+#ifdef CONFIG_SOC_AU1500
+
+#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
+#define USB_HOST_CONFIG 0xB017fffc
+#define FOR_PLATFORM_C_USB_HOST_INT AU1500_USB_HOST_INT
+#endif /* CONFIG_SOC_AU1500 */
+
+/* Au1100 */
+#ifdef CONFIG_SOC_AU1100
+
+#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
+#define USB_HOST_CONFIG 0xB017FFFC
+#define FOR_PLATFORM_C_USB_HOST_INT AU1100_USB_HOST_INT
+#endif /* CONFIG_SOC_AU1100 */
+
+#ifdef CONFIG_SOC_AU1550
+
+#define USB_OHCI_BASE 0x14020000 /* phys addr for ioremap */
+#define USB_OHCI_LEN 0x00060000
+#define USB_HOST_CONFIG 0xB4027ffc
+#define FOR_PLATFORM_C_USB_HOST_INT AU1550_USB_HOST_INT
+#endif /* CONFIG_SOC_AU1550 */
+
+
+#ifdef CONFIG_SOC_AU1200
+
+#define USB_UOC_BASE 0x14020020
+#define USB_UOC_LEN 0x20
+#define USB_OHCI_BASE 0x14020100
+#define USB_OHCI_LEN 0x100
+#define USB_EHCI_BASE 0x14020200
+#define USB_EHCI_LEN 0x100
+#define USB_UDC_BASE 0x14022000
+#define USB_UDC_LEN 0x2000
+#define USB_MSR_BASE 0xB4020000
+#define USB_MSR_MCFG 4
+#define USBMSRMCFG_OMEMEN 0
+#define USBMSRMCFG_OBMEN 1
+#define USBMSRMCFG_EMEMEN 2
+#define USBMSRMCFG_EBMEN 3
+#define USBMSRMCFG_DMEMEN 4
+#define USBMSRMCFG_DBMEN 5
+#define USBMSRMCFG_GMEMEN 6
+#define USBMSRMCFG_OHCCLKEN 16
+#define USBMSRMCFG_EHCCLKEN 17
+#define USBMSRMCFG_UDCCLKEN 18
+#define USBMSRMCFG_PHYPLLEN 19
+#define USBMSRMCFG_RDCOMB 30
+#define USBMSRMCFG_PFEN 31
+
+#define FOR_PLATFORM_C_USB_HOST_INT AU1200_USB_INT
+
+#endif /* CONFIG_SOC_AU1200 */
+
+/* Programmable Counters 0 and 1 */
+#define SYS_BASE 0xB1900000
+#define SYS_COUNTER_CNTRL (SYS_BASE + 0x14)
+# define SYS_CNTRL_E1S (1 << 23)
+# define SYS_CNTRL_T1S (1 << 20)
+# define SYS_CNTRL_M21 (1 << 19)
+# define SYS_CNTRL_M11 (1 << 18)
+# define SYS_CNTRL_M01 (1 << 17)
+# define SYS_CNTRL_C1S (1 << 16)
+# define SYS_CNTRL_BP (1 << 14)
+# define SYS_CNTRL_EN1 (1 << 13)
+# define SYS_CNTRL_BT1 (1 << 12)
+# define SYS_CNTRL_EN0 (1 << 11)
+# define SYS_CNTRL_BT0 (1 << 10)
+# define SYS_CNTRL_E0 (1 << 8)
+# define SYS_CNTRL_E0S (1 << 7)
+# define SYS_CNTRL_32S (1 << 5)
+# define SYS_CNTRL_T0S (1 << 4)
+# define SYS_CNTRL_M20 (1 << 3)
+# define SYS_CNTRL_M10 (1 << 2)
+# define SYS_CNTRL_M00 (1 << 1)
+# define SYS_CNTRL_C0S (1 << 0)
+
+/* Programmable Counter 0 Registers */
+#define SYS_TOYTRIM (SYS_BASE + 0)
+#define SYS_TOYWRITE (SYS_BASE + 4)
+#define SYS_TOYMATCH0 (SYS_BASE + 8)
+#define SYS_TOYMATCH1 (SYS_BASE + 0xC)
+#define SYS_TOYMATCH2 (SYS_BASE + 0x10)
+#define SYS_TOYREAD (SYS_BASE + 0x40)
+
+/* Programmable Counter 1 Registers */
+#define SYS_RTCTRIM (SYS_BASE + 0x44)
+#define SYS_RTCWRITE (SYS_BASE + 0x48)
+#define SYS_RTCMATCH0 (SYS_BASE + 0x4C)
+#define SYS_RTCMATCH1 (SYS_BASE + 0x50)
+#define SYS_RTCMATCH2 (SYS_BASE + 0x54)
+#define SYS_RTCREAD (SYS_BASE + 0x58)
+
+/* I2S Controller */
+#define I2S_DATA 0xB1000000
+# define I2S_DATA_MASK 0xffffff
+#define I2S_CONFIG 0xB1000004
+# define I2S_CONFIG_XU (1 << 25)
+# define I2S_CONFIG_XO (1 << 24)
+# define I2S_CONFIG_RU (1 << 23)
+# define I2S_CONFIG_RO (1 << 22)
+# define I2S_CONFIG_TR (1 << 21)
+# define I2S_CONFIG_TE (1 << 20)
+# define I2S_CONFIG_TF (1 << 19)
+# define I2S_CONFIG_RR (1 << 18)
+# define I2S_CONFIG_RE (1 << 17)
+# define I2S_CONFIG_RF (1 << 16)
+# define I2S_CONFIG_PD (1 << 11)
+# define I2S_CONFIG_LB (1 << 10)
+# define I2S_CONFIG_IC (1 << 9)
+# define I2S_CONFIG_FM_BIT 7
+# define I2S_CONFIG_FM_MASK (0x3 << I2S_CONFIG_FM_BIT)
+# define I2S_CONFIG_FM_I2S (0x0 << I2S_CONFIG_FM_BIT)
+# define I2S_CONFIG_FM_LJ (0x1 << I2S_CONFIG_FM_BIT)
+# define I2S_CONFIG_FM_RJ (0x2 << I2S_CONFIG_FM_BIT)
+# define I2S_CONFIG_TN (1 << 6)
+# define I2S_CONFIG_RN (1 << 5)
+# define I2S_CONFIG_SZ_BIT 0
+# define I2S_CONFIG_SZ_MASK (0x1F << I2S_CONFIG_SZ_BIT)
+
+#define I2S_CONTROL 0xB1000008
+# define I2S_CONTROL_D (1 << 1)
+# define I2S_CONTROL_CE (1 << 0)
+
+/* USB Host Controller */
+#ifndef USB_OHCI_LEN
+#define USB_OHCI_LEN 0x00100000
+#endif
+
+#ifndef CONFIG_SOC_AU1200
+
+/* USB Device Controller */
+#define USBD_EP0RD 0xB0200000
+#define USBD_EP0WR 0xB0200004
+#define USBD_EP2WR 0xB0200008
+#define USBD_EP3WR 0xB020000C
+#define USBD_EP4RD 0xB0200010
+#define USBD_EP5RD 0xB0200014
+#define USBD_INTEN 0xB0200018
+#define USBD_INTSTAT 0xB020001C
+# define USBDEV_INT_SOF (1 << 12)
+# define USBDEV_INT_HF_BIT 6
+# define USBDEV_INT_HF_MASK (0x3f << USBDEV_INT_HF_BIT)
+# define USBDEV_INT_CMPLT_BIT 0
+# define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT)
+#define USBD_CONFIG 0xB0200020
+#define USBD_EP0CS 0xB0200024
+#define USBD_EP2CS 0xB0200028
+#define USBD_EP3CS 0xB020002C
+#define USBD_EP4CS 0xB0200030
+#define USBD_EP5CS 0xB0200034
+# define USBDEV_CS_SU (1 << 14)
+# define USBDEV_CS_NAK (1 << 13)
+# define USBDEV_CS_ACK (1 << 12)
+# define USBDEV_CS_BUSY (1 << 11)
+# define USBDEV_CS_TSIZE_BIT 1
+# define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT)
+# define USBDEV_CS_STALL (1 << 0)
+#define USBD_EP0RDSTAT 0xB0200040
+#define USBD_EP0WRSTAT 0xB0200044
+#define USBD_EP2WRSTAT 0xB0200048
+#define USBD_EP3WRSTAT 0xB020004C
+#define USBD_EP4RDSTAT 0xB0200050
+#define USBD_EP5RDSTAT 0xB0200054
+# define USBDEV_FSTAT_FLUSH (1 << 6)
+# define USBDEV_FSTAT_UF (1 << 5)
+# define USBDEV_FSTAT_OF (1 << 4)
+# define USBDEV_FSTAT_FCNT_BIT 0
+# define USBDEV_FSTAT_FCNT_MASK (0x0f << USBDEV_FSTAT_FCNT_BIT)
+#define USBD_ENABLE 0xB0200058
+# define USBDEV_ENABLE (1 << 1)
+# define USBDEV_CE (1 << 0)
+
+#endif /* !CONFIG_SOC_AU1200 */
+
+/* Ethernet Controllers */
+
+/* 4 byte offsets from AU1000_ETH_BASE */
+#define MAC_CONTROL 0x0
+# define MAC_RX_ENABLE (1 << 2)
+# define MAC_TX_ENABLE (1 << 3)
+# define MAC_DEF_CHECK (1 << 5)
+# define MAC_SET_BL(X) (((X) & 0x3) << 6)
+# define MAC_AUTO_PAD (1 << 8)
+# define MAC_DISABLE_RETRY (1 << 10)
+# define MAC_DISABLE_BCAST (1 << 11)
+# define MAC_LATE_COL (1 << 12)
+# define MAC_HASH_MODE (1 << 13)
+# define MAC_HASH_ONLY (1 << 15)
+# define MAC_PASS_ALL (1 << 16)
+# define MAC_INVERSE_FILTER (1 << 17)
+# define MAC_PROMISCUOUS (1 << 18)
+# define MAC_PASS_ALL_MULTI (1 << 19)
+# define MAC_FULL_DUPLEX (1 << 20)
+# define MAC_NORMAL_MODE 0
+# define MAC_INT_LOOPBACK (1 << 21)
+# define MAC_EXT_LOOPBACK (1 << 22)
+# define MAC_DISABLE_RX_OWN (1 << 23)
+# define MAC_BIG_ENDIAN (1 << 30)
+# define MAC_RX_ALL (1 << 31)
+#define MAC_ADDRESS_HIGH 0x4
+#define MAC_ADDRESS_LOW 0x8
+#define MAC_MCAST_HIGH 0xC
+#define MAC_MCAST_LOW 0x10
+#define MAC_MII_CNTRL 0x14
+# define MAC_MII_BUSY (1 << 0)
+# define MAC_MII_READ 0
+# define MAC_MII_WRITE (1 << 1)
+# define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6)
+# define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11)
+#define MAC_MII_DATA 0x18
+#define MAC_FLOW_CNTRL 0x1C
+# define MAC_FLOW_CNTRL_BUSY (1 << 0)
+# define MAC_FLOW_CNTRL_ENABLE (1 << 1)
+# define MAC_PASS_CONTROL (1 << 2)
+# define MAC_SET_PAUSE(X) (((X) & 0xffff) << 16)
+#define MAC_VLAN1_TAG 0x20
+#define MAC_VLAN2_TAG 0x24
+
+/* Ethernet Controller Enable */
+
+# define MAC_EN_CLOCK_ENABLE (1 << 0)
+# define MAC_EN_RESET0 (1 << 1)
+# define MAC_EN_TOSS (0 << 2)
+# define MAC_EN_CACHEABLE (1 << 3)
+# define MAC_EN_RESET1 (1 << 4)
+# define MAC_EN_RESET2 (1 << 5)
+# define MAC_DMA_RESET (1 << 6)
+
+/* Ethernet Controller DMA Channels */
+
+#define MAC0_TX_DMA_ADDR 0xB4004000
+#define MAC1_TX_DMA_ADDR 0xB4004200
+/* offsets from MAC_TX_RING_ADDR address */
+#define MAC_TX_BUFF0_STATUS 0x0
+# define TX_FRAME_ABORTED (1 << 0)
+# define TX_JAB_TIMEOUT (1 << 1)
+# define TX_NO_CARRIER (1 << 2)
+# define TX_LOSS_CARRIER (1 << 3)
+# define TX_EXC_DEF (1 << 4)
+# define TX_LATE_COLL_ABORT (1 << 5)
+# define TX_EXC_COLL (1 << 6)
+# define TX_UNDERRUN (1 << 7)
+# define TX_DEFERRED (1 << 8)
+# define TX_LATE_COLL (1 << 9)
+# define TX_COLL_CNT_MASK (0xF << 10)
+# define TX_PKT_RETRY (1 << 31)
+#define MAC_TX_BUFF0_ADDR 0x4
+# define TX_DMA_ENABLE (1 << 0)
+# define TX_T_DONE (1 << 1)
+# define TX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3)
+#define MAC_TX_BUFF0_LEN 0x8
+#define MAC_TX_BUFF1_STATUS 0x10
+#define MAC_TX_BUFF1_ADDR 0x14
+#define MAC_TX_BUFF1_LEN 0x18
+#define MAC_TX_BUFF2_STATUS 0x20
+#define MAC_TX_BUFF2_ADDR 0x24
+#define MAC_TX_BUFF2_LEN 0x28
+#define MAC_TX_BUFF3_STATUS 0x30
+#define MAC_TX_BUFF3_ADDR 0x34
+#define MAC_TX_BUFF3_LEN 0x38
+
+#define MAC0_RX_DMA_ADDR 0xB4004100
+#define MAC1_RX_DMA_ADDR 0xB4004300
+/* offsets from MAC_RX_RING_ADDR */
+#define MAC_RX_BUFF0_STATUS 0x0
+# define RX_FRAME_LEN_MASK 0x3fff
+# define RX_WDOG_TIMER (1 << 14)
+# define RX_RUNT (1 << 15)
+# define RX_OVERLEN (1 << 16)
+# define RX_COLL (1 << 17)
+# define RX_ETHER (1 << 18)
+# define RX_MII_ERROR (1 << 19)
+# define RX_DRIBBLING (1 << 20)
+# define RX_CRC_ERROR (1 << 21)
+# define RX_VLAN1 (1 << 22)
+# define RX_VLAN2 (1 << 23)
+# define RX_LEN_ERROR (1 << 24)
+# define RX_CNTRL_FRAME (1 << 25)
+# define RX_U_CNTRL_FRAME (1 << 26)
+# define RX_MCAST_FRAME (1 << 27)
+# define RX_BCAST_FRAME (1 << 28)
+# define RX_FILTER_FAIL (1 << 29)
+# define RX_PACKET_FILTER (1 << 30)
+# define RX_MISSED_FRAME (1 << 31)
+
+# define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN | \
+ RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \
+ RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME)
+#define MAC_RX_BUFF0_ADDR 0x4
+# define RX_DMA_ENABLE (1 << 0)
+# define RX_T_DONE (1 << 1)
+# define RX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3)
+# define RX_SET_BUFF_ADDR(X) ((X) & 0xffffffc0)
+#define MAC_RX_BUFF1_STATUS 0x10
+#define MAC_RX_BUFF1_ADDR 0x14
+#define MAC_RX_BUFF2_STATUS 0x20
+#define MAC_RX_BUFF2_ADDR 0x24
+#define MAC_RX_BUFF3_STATUS 0x30
+#define MAC_RX_BUFF3_ADDR 0x34
+
+#define UART_RX 0 /* Receive buffer */
+#define UART_TX 4 /* Transmit buffer */
+#define UART_IER 8 /* Interrupt Enable Register */
+#define UART_IIR 0xC /* Interrupt ID Register */
+#define UART_FCR 0x10 /* FIFO Control Register */
+#define UART_LCR 0x14 /* Line Control Register */
+#define UART_MCR 0x18 /* Modem Control Register */
+#define UART_LSR 0x1C /* Line Status Register */
+#define UART_MSR 0x20 /* Modem Status Register */
+#define UART_CLK 0x28 /* Baud Rate Clock Divider */
+#define UART_MOD_CNTRL 0x100 /* Module Control */
+
+/* SSIO */
+#define SSI0_STATUS 0xB1600000
+# define SSI_STATUS_BF (1 << 4)
+# define SSI_STATUS_OF (1 << 3)
+# define SSI_STATUS_UF (1 << 2)
+# define SSI_STATUS_D (1 << 1)
+# define SSI_STATUS_B (1 << 0)
+#define SSI0_INT 0xB1600004
+# define SSI_INT_OI (1 << 3)
+# define SSI_INT_UI (1 << 2)
+# define SSI_INT_DI (1 << 1)
+#define SSI0_INT_ENABLE 0xB1600008
+# define SSI_INTE_OIE (1 << 3)
+# define SSI_INTE_UIE (1 << 2)
+# define SSI_INTE_DIE (1 << 1)
+#define SSI0_CONFIG 0xB1600020
+# define SSI_CONFIG_AO (1 << 24)
+# define SSI_CONFIG_DO (1 << 23)
+# define SSI_CONFIG_ALEN_BIT 20
+# define SSI_CONFIG_ALEN_MASK (0x7 << 20)
+# define SSI_CONFIG_DLEN_BIT 16
+# define SSI_CONFIG_DLEN_MASK (0x7 << 16)
+# define SSI_CONFIG_DD (1 << 11)
+# define SSI_CONFIG_AD (1 << 10)
+# define SSI_CONFIG_BM_BIT 8
+# define SSI_CONFIG_BM_MASK (0x3 << 8)
+# define SSI_CONFIG_CE (1 << 7)
+# define SSI_CONFIG_DP (1 << 6)
+# define SSI_CONFIG_DL (1 << 5)
+# define SSI_CONFIG_EP (1 << 4)
+#define SSI0_ADATA 0xB1600024
+# define SSI_AD_D (1 << 24)
+# define SSI_AD_ADDR_BIT 16
+# define SSI_AD_ADDR_MASK (0xff << 16)
+# define SSI_AD_DATA_BIT 0
+# define SSI_AD_DATA_MASK (0xfff << 0)
+#define SSI0_CLKDIV 0xB1600028
+#define SSI0_CONTROL 0xB1600100
+# define SSI_CONTROL_CD (1 << 1)
+# define SSI_CONTROL_E (1 << 0)
+
+/* SSI1 */
+#define SSI1_STATUS 0xB1680000
+#define SSI1_INT 0xB1680004
+#define SSI1_INT_ENABLE 0xB1680008
+#define SSI1_CONFIG 0xB1680020
+#define SSI1_ADATA 0xB1680024
+#define SSI1_CLKDIV 0xB1680028
+#define SSI1_ENABLE 0xB1680100
+
+/*
+ * Register content definitions
+ */
+#define SSI_STATUS_BF (1 << 4)
+#define SSI_STATUS_OF (1 << 3)
+#define SSI_STATUS_UF (1 << 2)
+#define SSI_STATUS_D (1 << 1)
+#define SSI_STATUS_B (1 << 0)
+
+/* SSI_INT */
+#define SSI_INT_OI (1 << 3)
+#define SSI_INT_UI (1 << 2)
+#define SSI_INT_DI (1 << 1)
+
+/* SSI_INTEN */
+#define SSI_INTEN_OIE (1 << 3)
+#define SSI_INTEN_UIE (1 << 2)
+#define SSI_INTEN_DIE (1 << 1)
+
+#define SSI_CONFIG_AO (1 << 24)
+#define SSI_CONFIG_DO (1 << 23)
+#define SSI_CONFIG_ALEN (7 << 20)
+#define SSI_CONFIG_DLEN (15 << 16)
+#define SSI_CONFIG_DD (1 << 11)
+#define SSI_CONFIG_AD (1 << 10)
+#define SSI_CONFIG_BM (3 << 8)
+#define SSI_CONFIG_CE (1 << 7)
+#define SSI_CONFIG_DP (1 << 6)
+#define SSI_CONFIG_DL (1 << 5)
+#define SSI_CONFIG_EP (1 << 4)
+#define SSI_CONFIG_ALEN_N(N) ((N-1) << 20)
+#define SSI_CONFIG_DLEN_N(N) ((N-1) << 16)
+#define SSI_CONFIG_BM_HI (0 << 8)
+#define SSI_CONFIG_BM_LO (1 << 8)
+#define SSI_CONFIG_BM_CY (2 << 8)
+
+#define SSI_ADATA_D (1 << 24)
+#define SSI_ADATA_ADDR (0xFF << 16)
+#define SSI_ADATA_DATA 0x0FFF
+#define SSI_ADATA_ADDR_N(N) (N << 16)
+
+#define SSI_ENABLE_CD (1 << 1)
+#define SSI_ENABLE_E (1 << 0)
+
+/* IrDA Controller */
+#define IRDA_BASE 0xB0300000
+#define IR_RING_PTR_STATUS (IRDA_BASE + 0x00)
+#define IR_RING_BASE_ADDR_H (IRDA_BASE + 0x04)
+#define IR_RING_BASE_ADDR_L (IRDA_BASE + 0x08)
+#define IR_RING_SIZE (IRDA_BASE + 0x0C)
+#define IR_RING_PROMPT (IRDA_BASE + 0x10)
+#define IR_RING_ADDR_CMPR (IRDA_BASE + 0x14)
+#define IR_INT_CLEAR (IRDA_BASE + 0x18)
+#define IR_CONFIG_1 (IRDA_BASE + 0x20)
+# define IR_RX_INVERT_LED (1 << 0)
+# define IR_TX_INVERT_LED (1 << 1)
+# define IR_ST (1 << 2)
+# define IR_SF (1 << 3)
+# define IR_SIR (1 << 4)
+# define IR_MIR (1 << 5)
+# define IR_FIR (1 << 6)
+# define IR_16CRC (1 << 7)
+# define IR_TD (1 << 8)
+# define IR_RX_ALL (1 << 9)
+# define IR_DMA_ENABLE (1 << 10)
+# define IR_RX_ENABLE (1 << 11)
+# define IR_TX_ENABLE (1 << 12)
+# define IR_LOOPBACK (1 << 14)
+# define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \
+ IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
+#define IR_SIR_FLAGS (IRDA_BASE + 0x24)
+#define IR_ENABLE (IRDA_BASE + 0x28)
+# define IR_RX_STATUS (1 << 9)
+# define IR_TX_STATUS (1 << 10)
+#define IR_READ_PHY_CONFIG (IRDA_BASE + 0x2C)
+#define IR_WRITE_PHY_CONFIG (IRDA_BASE + 0x30)
+#define IR_MAX_PKT_LEN (IRDA_BASE + 0x34)
+#define IR_RX_BYTE_CNT (IRDA_BASE + 0x38)
+#define IR_CONFIG_2 (IRDA_BASE + 0x3C)
+# define IR_MODE_INV (1 << 0)
+# define IR_ONE_PIN (1 << 1)
+#define IR_INTERFACE_CONFIG (IRDA_BASE + 0x40)
+
+/* GPIO */
+#define SYS_PINFUNC 0xB190002C
+# define SYS_PF_USB (1 << 15) /* 2nd USB device/host */
+# define SYS_PF_U3 (1 << 14) /* GPIO23/U3TXD */
+# define SYS_PF_U2 (1 << 13) /* GPIO22/U2TXD */
+# define SYS_PF_U1 (1 << 12) /* GPIO21/U1TXD */
+# define SYS_PF_SRC (1 << 11) /* GPIO6/SROMCKE */
+# define SYS_PF_CK5 (1 << 10) /* GPIO3/CLK5 */
+# define SYS_PF_CK4 (1 << 9) /* GPIO2/CLK4 */
+# define SYS_PF_IRF (1 << 8) /* GPIO15/IRFIRSEL */
+# define SYS_PF_UR3 (1 << 7) /* GPIO[14:9]/UART3 */
+# define SYS_PF_I2D (1 << 6) /* GPIO8/I2SDI */
+# define SYS_PF_I2S (1 << 5) /* I2S/GPIO[29:31] */
+# define SYS_PF_NI2 (1 << 4) /* NI2/GPIO[24:28] */
+# define SYS_PF_U0 (1 << 3) /* U0TXD/GPIO20 */
+# define SYS_PF_RD (1 << 2) /* IRTXD/GPIO19 */
+# define SYS_PF_A97 (1 << 1) /* AC97/SSL1 */
+# define SYS_PF_S0 (1 << 0) /* SSI_0/GPIO[16:18] */
+
+/* Au1100 only */
+# define SYS_PF_PC (1 << 18) /* PCMCIA/GPIO[207:204] */
+# define SYS_PF_LCD (1 << 17) /* extern lcd/GPIO[203:200] */
+# define SYS_PF_CS (1 << 16) /* EXTCLK0/32KHz to gpio2 */
+# define SYS_PF_EX0 (1 << 9) /* GPIO2/clock */
+
+/* Au1550 only. Redefines lots of pins */
+# define SYS_PF_PSC2_MASK (7 << 17)
+# define SYS_PF_PSC2_AC97 0
+# define SYS_PF_PSC2_SPI 0
+# define SYS_PF_PSC2_I2S (1 << 17)
+# define SYS_PF_PSC2_SMBUS (3 << 17)
+# define SYS_PF_PSC2_GPIO (7 << 17)
+# define SYS_PF_PSC3_MASK (7 << 20)
+# define SYS_PF_PSC3_AC97 0
+# define SYS_PF_PSC3_SPI 0
+# define SYS_PF_PSC3_I2S (1 << 20)
+# define SYS_PF_PSC3_SMBUS (3 << 20)
+# define SYS_PF_PSC3_GPIO (7 << 20)
+# define SYS_PF_PSC1_S1 (1 << 1)
+# define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2))
+
+/* Au1200 only */
+#ifdef CONFIG_SOC_AU1200
+#define SYS_PINFUNC_DMA (1 << 31)
+#define SYS_PINFUNC_S0A (1 << 30)
+#define SYS_PINFUNC_S1A (1 << 29)
+#define SYS_PINFUNC_LP0 (1 << 28)
+#define SYS_PINFUNC_LP1 (1 << 27)
+#define SYS_PINFUNC_LD16 (1 << 26)
+#define SYS_PINFUNC_LD8 (1 << 25)
+#define SYS_PINFUNC_LD1 (1 << 24)
+#define SYS_PINFUNC_LD0 (1 << 23)
+#define SYS_PINFUNC_P1A (3 << 21)
+#define SYS_PINFUNC_P1B (1 << 20)
+#define SYS_PINFUNC_FS3 (1 << 19)
+#define SYS_PINFUNC_P0A (3 << 17)
+#define SYS_PINFUNC_CS (1 << 16)
+#define SYS_PINFUNC_CIM (1 << 15)
+#define SYS_PINFUNC_P1C (1 << 14)
+#define SYS_PINFUNC_U1T (1 << 12)
+#define SYS_PINFUNC_U1R (1 << 11)
+#define SYS_PINFUNC_EX1 (1 << 10)
+#define SYS_PINFUNC_EX0 (1 << 9)
+#define SYS_PINFUNC_U0R (1 << 8)
+#define SYS_PINFUNC_MC (1 << 7)
+#define SYS_PINFUNC_S0B (1 << 6)
+#define SYS_PINFUNC_S0C (1 << 5)
+#define SYS_PINFUNC_P0B (1 << 4)
+#define SYS_PINFUNC_U0T (1 << 3)
+#define SYS_PINFUNC_S1B (1 << 2)
+#endif
+
+/* Power Management */
+#define SYS_SCRATCH0 0xB1900018
+#define SYS_SCRATCH1 0xB190001C
+#define SYS_WAKEMSK 0xB1900034
+#define SYS_ENDIAN 0xB1900038
+#define SYS_POWERCTRL 0xB190003C
+#define SYS_WAKESRC 0xB190005C
+#define SYS_SLPPWR 0xB1900078
+#define SYS_SLEEP 0xB190007C
+
+#define SYS_WAKEMSK_D2 (1 << 9)
+#define SYS_WAKEMSK_M2 (1 << 8)
+#define SYS_WAKEMSK_GPIO(x) (1 << (x))
+
+/* Clock Controller */
+#define SYS_FREQCTRL0 0xB1900020
+# define SYS_FC_FRDIV2_BIT 22
+# define SYS_FC_FRDIV2_MASK (0xff << SYS_FC_FRDIV2_BIT)
+# define SYS_FC_FE2 (1 << 21)
+# define SYS_FC_FS2 (1 << 20)
+# define SYS_FC_FRDIV1_BIT 12
+# define SYS_FC_FRDIV1_MASK (0xff << SYS_FC_FRDIV1_BIT)
+# define SYS_FC_FE1 (1 << 11)
+# define SYS_FC_FS1 (1 << 10)
+# define SYS_FC_FRDIV0_BIT 2
+# define SYS_FC_FRDIV0_MASK (0xff << SYS_FC_FRDIV0_BIT)
+# define SYS_FC_FE0 (1 << 1)
+# define SYS_FC_FS0 (1 << 0)
+#define SYS_FREQCTRL1 0xB1900024
+# define SYS_FC_FRDIV5_BIT 22
+# define SYS_FC_FRDIV5_MASK (0xff << SYS_FC_FRDIV5_BIT)
+# define SYS_FC_FE5 (1 << 21)
+# define SYS_FC_FS5 (1 << 20)
+# define SYS_FC_FRDIV4_BIT 12
+# define SYS_FC_FRDIV4_MASK (0xff << SYS_FC_FRDIV4_BIT)
+# define SYS_FC_FE4 (1 << 11)
+# define SYS_FC_FS4 (1 << 10)
+# define SYS_FC_FRDIV3_BIT 2
+# define SYS_FC_FRDIV3_MASK (0xff << SYS_FC_FRDIV3_BIT)
+# define SYS_FC_FE3 (1 << 1)
+# define SYS_FC_FS3 (1 << 0)
+#define SYS_CLKSRC 0xB1900028
+# define SYS_CS_ME1_BIT 27
+# define SYS_CS_ME1_MASK (0x7 << SYS_CS_ME1_BIT)
+# define SYS_CS_DE1 (1 << 26)
+# define SYS_CS_CE1 (1 << 25)
+# define SYS_CS_ME0_BIT 22
+# define SYS_CS_ME0_MASK (0x7 << SYS_CS_ME0_BIT)
+# define SYS_CS_DE0 (1 << 21)
+# define SYS_CS_CE0 (1 << 20)
+# define SYS_CS_MI2_BIT 17
+# define SYS_CS_MI2_MASK (0x7 << SYS_CS_MI2_BIT)
+# define SYS_CS_DI2 (1 << 16)
+# define SYS_CS_CI2 (1 << 15)
+#ifdef CONFIG_SOC_AU1100
+# define SYS_CS_ML_BIT 7
+# define SYS_CS_ML_MASK (0x7 << SYS_CS_ML_BIT)
+# define SYS_CS_DL (1 << 6)
+# define SYS_CS_CL (1 << 5)
+#else
+# define SYS_CS_MUH_BIT 12
+# define SYS_CS_MUH_MASK (0x7 << SYS_CS_MUH_BIT)
+# define SYS_CS_DUH (1 << 11)
+# define SYS_CS_CUH (1 << 10)
+# define SYS_CS_MUD_BIT 7
+# define SYS_CS_MUD_MASK (0x7 << SYS_CS_MUD_BIT)
+# define SYS_CS_DUD (1 << 6)
+# define SYS_CS_CUD (1 << 5)
+#endif
+# define SYS_CS_MIR_BIT 2
+# define SYS_CS_MIR_MASK (0x7 << SYS_CS_MIR_BIT)
+# define SYS_CS_DIR (1 << 1)
+# define SYS_CS_CIR (1 << 0)
+
+# define SYS_CS_MUX_AUX 0x1
+# define SYS_CS_MUX_FQ0 0x2
+# define SYS_CS_MUX_FQ1 0x3
+# define SYS_CS_MUX_FQ2 0x4
+# define SYS_CS_MUX_FQ3 0x5
+# define SYS_CS_MUX_FQ4 0x6
+# define SYS_CS_MUX_FQ5 0x7
+#define SYS_CPUPLL 0xB1900060
+#define SYS_AUXPLL 0xB1900064
+
+/* AC97 Controller */
+#define AC97C_CONFIG 0xB0000000
+# define AC97C_RECV_SLOTS_BIT 13
+# define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT)
+# define AC97C_XMIT_SLOTS_BIT 3
+# define AC97C_XMIT_SLOTS_MASK (0x3ff << AC97C_XMIT_SLOTS_BIT)
+# define AC97C_SG (1 << 2)
+# define AC97C_SYNC (1 << 1)
+# define AC97C_RESET (1 << 0)
+#define AC97C_STATUS 0xB0000004
+# define AC97C_XU (1 << 11)
+# define AC97C_XO (1 << 10)
+# define AC97C_RU (1 << 9)
+# define AC97C_RO (1 << 8)
+# define AC97C_READY (1 << 7)
+# define AC97C_CP (1 << 6)
+# define AC97C_TR (1 << 5)
+# define AC97C_TE (1 << 4)
+# define AC97C_TF (1 << 3)
+# define AC97C_RR (1 << 2)
+# define AC97C_RE (1 << 1)
+# define AC97C_RF (1 << 0)
+#define AC97C_DATA 0xB0000008
+#define AC97C_CMD 0xB000000C
+# define AC97C_WD_BIT 16
+# define AC97C_READ (1 << 7)
+# define AC97C_INDEX_MASK 0x7f
+#define AC97C_CNTRL 0xB0000010
+# define AC97C_RS (1 << 1)
+# define AC97C_CE (1 << 0)
+
+#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+/* Au1500 PCI Controller */
+#define Au1500_CFG_BASE 0xB4005000 /* virtual, KSEG1 addr */
+#define Au1500_PCI_CMEM (Au1500_CFG_BASE + 0)
+#define Au1500_PCI_CFG (Au1500_CFG_BASE + 4)
+# define PCI_ERROR ((1 << 22) | (1 << 23) | (1 << 24) | \
+ (1 << 25) | (1 << 26) | (1 << 27))
+#define Au1500_PCI_B2BMASK_CCH (Au1500_CFG_BASE + 8)
+#define Au1500_PCI_B2B0_VID (Au1500_CFG_BASE + 0xC)
+#define Au1500_PCI_B2B1_ID (Au1500_CFG_BASE + 0x10)
+#define Au1500_PCI_MWMASK_DEV (Au1500_CFG_BASE + 0x14)
+#define Au1500_PCI_MWBASE_REV_CCL (Au1500_CFG_BASE + 0x18)
+#define Au1500_PCI_ERR_ADDR (Au1500_CFG_BASE + 0x1C)
+#define Au1500_PCI_SPEC_INTACK (Au1500_CFG_BASE + 0x20)
+#define Au1500_PCI_ID (Au1500_CFG_BASE + 0x100)
+#define Au1500_PCI_STATCMD (Au1500_CFG_BASE + 0x104)
+#define Au1500_PCI_CLASSREV (Au1500_CFG_BASE + 0x108)
+#define Au1500_PCI_HDRTYPE (Au1500_CFG_BASE + 0x10C)
+#define Au1500_PCI_MBAR (Au1500_CFG_BASE + 0x110)
+
+#define Au1500_PCI_HDR 0xB4005100 /* virtual, KSEG1 addr */
+
+/*
+ * All of our structures, like PCI resource, have 32-bit members.
+ * Drivers are expected to do an ioremap on the PCI MEM resource, but it's
+ * hard to store 0x4 0000 0000 in a 32-bit type. We require a small patch
+ * to __ioremap to check for addresses between (u32)Au1500_PCI_MEM_START and
+ * (u32)Au1500_PCI_MEM_END and change those to the full 36-bit PCI MEM
+ * addresses. For PCI I/O, it's simpler because we get to do the ioremap
+ * ourselves and then adjust the device's resources.
+ */
+#define Au1500_EXT_CFG 0x600000000ULL
+#define Au1500_EXT_CFG_TYPE1 0x680000000ULL
+#define Au1500_PCI_IO_START 0x500000000ULL
+#define Au1500_PCI_IO_END 0x5000FFFFFULL
+#define Au1500_PCI_MEM_START 0x440000000ULL
+#define Au1500_PCI_MEM_END 0x44FFFFFFFULL
+
+#define PCI_IO_START 0x00001000
+#define PCI_IO_END 0x000FFFFF
+#define PCI_MEM_START 0x40000000
+#define PCI_MEM_END 0x4FFFFFFF
+
+#define PCI_FIRST_DEVFN (0 << 3)
+#define PCI_LAST_DEVFN (19 << 3)
+
+#define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */
+#define IOPORT_RESOURCE_END 0xffffffff
+#define IOMEM_RESOURCE_START 0x10000000
+#define IOMEM_RESOURCE_END 0xfffffffffULL
+
+#else /* Au1000 and Au1100 and Au1200 */
+
+/* Don't allow any legacy ports probing */
+#define IOPORT_RESOURCE_START 0x10000000
+#define IOPORT_RESOURCE_END 0xffffffff
+#define IOMEM_RESOURCE_START 0x10000000
+#define IOMEM_RESOURCE_END 0xfffffffffULL
+
+#define PCI_IO_START 0
+#define PCI_IO_END 0
+#define PCI_MEM_START 0
+#define PCI_MEM_END 0
+#define PCI_FIRST_DEVFN 0
+#define PCI_LAST_DEVFN 0
+
+#endif
+
+#endif
diff --git a/arch/mips/include/asm/mach-au1x00/au1000_dma.h b/arch/mips/include/asm/mach-au1x00/au1000_dma.h
new file mode 100644
index 00000000..59f5b55b
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1000_dma.h
@@ -0,0 +1,454 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Defines for using and allocating DMA channels on the Alchemy
+ * Au1x00 MIPS processors.
+ *
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_AU1000_DMA_H
+#define __ASM_AU1000_DMA_H
+
+#include <linux/io.h> /* need byte IO */
+#include <linux/spinlock.h> /* And spinlocks */
+#include <linux/delay.h>
+#include <asm/system.h>
+
+#define NUM_AU1000_DMA_CHANNELS 8
+
+/* DMA Channel Register Offsets */
+#define DMA_MODE_SET 0x00000000
+#define DMA_MODE_READ DMA_MODE_SET
+#define DMA_MODE_CLEAR 0x00000004
+/* DMA Mode register bits follow */
+#define DMA_DAH_MASK (0x0f << 20)
+#define DMA_DID_BIT 16
+#define DMA_DID_MASK (0x0f << DMA_DID_BIT)
+#define DMA_DS (1 << 15)
+#define DMA_BE (1 << 13)
+#define DMA_DR (1 << 12)
+#define DMA_TS8 (1 << 11)
+#define DMA_DW_BIT 9
+#define DMA_DW_MASK (0x03 << DMA_DW_BIT)
+#define DMA_DW8 (0 << DMA_DW_BIT)
+#define DMA_DW16 (1 << DMA_DW_BIT)
+#define DMA_DW32 (2 << DMA_DW_BIT)
+#define DMA_NC (1 << 8)
+#define DMA_IE (1 << 7)
+#define DMA_HALT (1 << 6)
+#define DMA_GO (1 << 5)
+#define DMA_AB (1 << 4)
+#define DMA_D1 (1 << 3)
+#define DMA_BE1 (1 << 2)
+#define DMA_D0 (1 << 1)
+#define DMA_BE0 (1 << 0)
+
+#define DMA_PERIPHERAL_ADDR 0x00000008
+#define DMA_BUFFER0_START 0x0000000C
+#define DMA_BUFFER1_START 0x00000014
+#define DMA_BUFFER0_COUNT 0x00000010
+#define DMA_BUFFER1_COUNT 0x00000018
+#define DMA_BAH_BIT 16
+#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT)
+#define DMA_COUNT_BIT 0
+#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT)
+
+/* DMA Device IDs follow */
+enum {
+ DMA_ID_UART0_TX = 0,
+ DMA_ID_UART0_RX,
+ DMA_ID_GP04,
+ DMA_ID_GP05,
+ DMA_ID_AC97C_TX,
+ DMA_ID_AC97C_RX,
+ DMA_ID_UART3_TX,
+ DMA_ID_UART3_RX,
+ DMA_ID_USBDEV_EP0_RX,
+ DMA_ID_USBDEV_EP0_TX,
+ DMA_ID_USBDEV_EP2_TX,
+ DMA_ID_USBDEV_EP3_TX,
+ DMA_ID_USBDEV_EP4_RX,
+ DMA_ID_USBDEV_EP5_RX,
+ DMA_ID_I2S_TX,
+ DMA_ID_I2S_RX,
+ DMA_NUM_DEV
+};
+
+/* DMA Device ID's for 2nd bank (AU1100) follow */
+enum {
+ DMA_ID_SD0_TX = 0,
+ DMA_ID_SD0_RX,
+ DMA_ID_SD1_TX,
+ DMA_ID_SD1_RX,
+ DMA_NUM_DEV_BANK2
+};
+
+struct dma_chan {
+ int dev_id; /* this channel is allocated if >= 0, */
+ /* free otherwise */
+ unsigned int io;
+ const char *dev_str;
+ int irq;
+ void *irq_dev;
+ unsigned int fifo_addr;
+ unsigned int mode;
+};
+
+/* These are in arch/mips/au1000/common/dma.c */
+extern struct dma_chan au1000_dma_table[];
+extern int request_au1000_dma(int dev_id,
+ const char *dev_str,
+ irq_handler_t irqhandler,
+ unsigned long irqflags,
+ void *irq_dev_id);
+extern void free_au1000_dma(unsigned int dmanr);
+extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
+ int length, int *eof, void *data);
+extern void dump_au1000_dma_channel(unsigned int dmanr);
+extern spinlock_t au1000_dma_spin_lock;
+
+static inline struct dma_chan *get_dma_chan(unsigned int dmanr)
+{
+ if (dmanr >= NUM_AU1000_DMA_CHANNELS ||
+ au1000_dma_table[dmanr].dev_id < 0)
+ return NULL;
+ return &au1000_dma_table[dmanr];
+}
+
+static inline unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&au1000_dma_spin_lock, flags);
+ return flags;
+}
+
+static inline void release_dma_lock(unsigned long flags)
+{
+ spin_unlock_irqrestore(&au1000_dma_spin_lock, flags);
+}
+
+/*
+ * Set the DMA buffer enable bits in the mode register.
+ */
+static inline void enable_dma_buffer0(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ au_writel(DMA_BE0, chan->io + DMA_MODE_SET);
+}
+
+static inline void enable_dma_buffer1(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ au_writel(DMA_BE1, chan->io + DMA_MODE_SET);
+}
+static inline void enable_dma_buffers(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
+}
+
+static inline void start_dma(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ au_writel(DMA_GO, chan->io + DMA_MODE_SET);
+}
+
+#define DMA_HALT_POLL 0x5000
+
+static inline void halt_dma(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+ int i;
+
+ if (!chan)
+ return;
+ au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
+
+ /* Poll the halt bit */
+ for (i = 0; i < DMA_HALT_POLL; i++)
+ if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
+ break;
+ if (i == DMA_HALT_POLL)
+ printk(KERN_INFO "halt_dma: HALT poll expired!\n");
+}
+
+static inline void disable_dma(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ halt_dma(dmanr);
+
+ /* Now we can disable the buffers */
+ au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
+}
+
+static inline int dma_halted(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return 1;
+ return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
+}
+
+/* Initialize a DMA channel. */
+static inline void init_dma(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+ u32 mode;
+
+ if (!chan)
+ return;
+
+ disable_dma(dmanr);
+
+ /* Set device FIFO address */
+ au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR);
+
+ mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
+ if (chan->irq)
+ mode |= DMA_IE;
+
+ au_writel(~mode, chan->io + DMA_MODE_CLEAR);
+ au_writel(mode, chan->io + DMA_MODE_SET);
+}
+
+/*
+ * Set mode for a specific DMA channel
+ */
+static inline void set_dma_mode(unsigned int dmanr, unsigned int mode)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ /*
+ * set_dma_mode is only allowed to change endianess, direction,
+ * transfer size, device FIFO width, and coherency settings.
+ * Make sure anything else is masked off.
+ */
+ mode &= (DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
+ chan->mode &= ~(DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
+ chan->mode |= mode;
+}
+
+static inline unsigned int get_dma_mode(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return 0;
+ return chan->mode;
+}
+
+static inline int get_dma_active_buffer(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return -1;
+ return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
+}
+
+/*
+ * Set the device FIFO address for a specific DMA channel - only
+ * applicable to GPO4 and GPO5. All the other devices have fixed
+ * FIFO addresses.
+ */
+static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+
+ if (chan->mode & DMA_DS) /* second bank of device IDs */
+ return;
+
+ if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
+ return;
+
+ au_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR);
+}
+
+/*
+ * Clear the DMA buffer done bits in the mode register.
+ */
+static inline void clear_dma_done0(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
+}
+
+static inline void clear_dma_done1(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
+}
+
+/*
+ * This does nothing - not applicable to Au1000 DMA.
+ */
+static inline void set_dma_page(unsigned int dmanr, char pagenr)
+{
+}
+
+/*
+ * Set Buffer 0 transfer address for specific DMA channel.
+ */
+static inline void set_dma_addr0(unsigned int dmanr, unsigned int a)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ au_writel(a, chan->io + DMA_BUFFER0_START);
+}
+
+/*
+ * Set Buffer 1 transfer address for specific DMA channel.
+ */
+static inline void set_dma_addr1(unsigned int dmanr, unsigned int a)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ au_writel(a, chan->io + DMA_BUFFER1_START);
+}
+
+
+/*
+ * Set Buffer 0 transfer size (max 64k) for a specific DMA channel.
+ */
+static inline void set_dma_count0(unsigned int dmanr, unsigned int count)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ count &= DMA_COUNT_MASK;
+ au_writel(count, chan->io + DMA_BUFFER0_COUNT);
+}
+
+/*
+ * Set Buffer 1 transfer size (max 64k) for a specific DMA channel.
+ */
+static inline void set_dma_count1(unsigned int dmanr, unsigned int count)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ count &= DMA_COUNT_MASK;
+ au_writel(count, chan->io + DMA_BUFFER1_COUNT);
+}
+
+/*
+ * Set both buffer transfer sizes (max 64k) for a specific DMA channel.
+ */
+static inline void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return;
+ count &= DMA_COUNT_MASK;
+ au_writel(count, chan->io + DMA_BUFFER0_COUNT);
+ au_writel(count, chan->io + DMA_BUFFER1_COUNT);
+}
+
+/*
+ * Returns which buffer has its done bit set in the mode register.
+ * Returns -1 if neither or both done bits set.
+ */
+static inline unsigned int get_dma_buffer_done(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return 0;
+ return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
+}
+
+
+/*
+ * Returns the DMA channel's Buffer Done IRQ number.
+ */
+static inline int get_dma_done_irq(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return -1;
+ return chan->irq;
+}
+
+/*
+ * Get DMA residue count. Returns the number of _bytes_ left to transfer.
+ */
+static inline int get_dma_residue(unsigned int dmanr)
+{
+ int curBufCntReg, count;
+ struct dma_chan *chan = get_dma_chan(dmanr);
+
+ if (!chan)
+ return 0;
+
+ curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ?
+ DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT;
+
+ count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK;
+
+ if ((chan->mode & DMA_DW_MASK) == DMA_DW16)
+ count <<= 1;
+ else if ((chan->mode & DMA_DW_MASK) == DMA_DW32)
+ count <<= 2;
+
+ return count;
+}
+
+#endif /* __ASM_AU1000_DMA_H */
diff --git a/arch/mips/include/asm/mach-au1x00/au1100_mmc.h b/arch/mips/include/asm/mach-au1x00/au1100_mmc.h
new file mode 100644
index 00000000..94000a3b
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1100_mmc.h
@@ -0,0 +1,208 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Defines for using the MMC/SD controllers on the
+ * Alchemy Au1100 mips processor.
+ *
+ * Copyright (c) 2003 Embedded Edge, LLC.
+ * Author: Embedded Edge, LLC.
+ * dan@embeddededge.com or tim@embeddededge.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+/*
+ * AU1100 MMC/SD definitions.
+ *
+ * From "AMD Alchemy Solutions Au1100 Processor Data Book - Preliminary"
+ * June, 2003
+ */
+
+#ifndef __ASM_AU1100_MMC_H
+#define __ASM_AU1100_MMC_H
+
+#include <linux/leds.h>
+
+struct au1xmmc_platform_data {
+ int(*cd_setup)(void *mmc_host, int on);
+ int(*card_inserted)(void *mmc_host);
+ int(*card_readonly)(void *mmc_host);
+ void(*set_power)(void *mmc_host, int state);
+ struct led_classdev *led;
+ unsigned long mask_host_caps;
+};
+
+#define SD0_BASE 0xB0600000
+#define SD1_BASE 0xB0680000
+
+
+/*
+ * Register offsets.
+ */
+#define SD_TXPORT (0x0000)
+#define SD_RXPORT (0x0004)
+#define SD_CONFIG (0x0008)
+#define SD_ENABLE (0x000C)
+#define SD_CONFIG2 (0x0010)
+#define SD_BLKSIZE (0x0014)
+#define SD_STATUS (0x0018)
+#define SD_DEBUG (0x001C)
+#define SD_CMD (0x0020)
+#define SD_CMDARG (0x0024)
+#define SD_RESP3 (0x0028)
+#define SD_RESP2 (0x002C)
+#define SD_RESP1 (0x0030)
+#define SD_RESP0 (0x0034)
+#define SD_TIMEOUT (0x0038)
+
+
+/*
+ * SD_TXPORT bit definitions.
+ */
+#define SD_TXPORT_TXD (0x000000ff)
+
+
+/*
+ * SD_RXPORT bit definitions.
+ */
+#define SD_RXPORT_RXD (0x000000ff)
+
+
+/*
+ * SD_CONFIG bit definitions.
+ */
+#define SD_CONFIG_DIV (0x000001ff)
+#define SD_CONFIG_DE (0x00000200)
+#define SD_CONFIG_NE (0x00000400)
+#define SD_CONFIG_TU (0x00000800)
+#define SD_CONFIG_TO (0x00001000)
+#define SD_CONFIG_RU (0x00002000)
+#define SD_CONFIG_RO (0x00004000)
+#define SD_CONFIG_I (0x00008000)
+#define SD_CONFIG_CR (0x00010000)
+#define SD_CONFIG_RAT (0x00020000)
+#define SD_CONFIG_DD (0x00040000)
+#define SD_CONFIG_DT (0x00080000)
+#define SD_CONFIG_SC (0x00100000)
+#define SD_CONFIG_RC (0x00200000)
+#define SD_CONFIG_WC (0x00400000)
+#define SD_CONFIG_xxx (0x00800000)
+#define SD_CONFIG_TH (0x01000000)
+#define SD_CONFIG_TE (0x02000000)
+#define SD_CONFIG_TA (0x04000000)
+#define SD_CONFIG_RH (0x08000000)
+#define SD_CONFIG_RA (0x10000000)
+#define SD_CONFIG_RF (0x20000000)
+#define SD_CONFIG_CD (0x40000000)
+#define SD_CONFIG_SI (0x80000000)
+
+
+/*
+ * SD_ENABLE bit definitions.
+ */
+#define SD_ENABLE_CE (0x00000001)
+#define SD_ENABLE_R (0x00000002)
+
+
+/*
+ * SD_CONFIG2 bit definitions.
+ */
+#define SD_CONFIG2_EN (0x00000001)
+#define SD_CONFIG2_FF (0x00000002)
+#define SD_CONFIG2_xx1 (0x00000004)
+#define SD_CONFIG2_DF (0x00000008)
+#define SD_CONFIG2_DC (0x00000010)
+#define SD_CONFIG2_xx2 (0x000000e0)
+#define SD_CONFIG2_WB (0x00000100)
+#define SD_CONFIG2_RW (0x00000200)
+
+
+/*
+ * SD_BLKSIZE bit definitions.
+ */
+#define SD_BLKSIZE_BS (0x000007ff)
+#define SD_BLKSIZE_BS_SHIFT (0)
+#define SD_BLKSIZE_BC (0x01ff0000)
+#define SD_BLKSIZE_BC_SHIFT (16)
+
+
+/*
+ * SD_STATUS bit definitions.
+ */
+#define SD_STATUS_DCRCW (0x00000007)
+#define SD_STATUS_xx1 (0x00000008)
+#define SD_STATUS_CB (0x00000010)
+#define SD_STATUS_DB (0x00000020)
+#define SD_STATUS_CF (0x00000040)
+#define SD_STATUS_D3 (0x00000080)
+#define SD_STATUS_xx2 (0x00000300)
+#define SD_STATUS_NE (0x00000400)
+#define SD_STATUS_TU (0x00000800)
+#define SD_STATUS_TO (0x00001000)
+#define SD_STATUS_RU (0x00002000)
+#define SD_STATUS_RO (0x00004000)
+#define SD_STATUS_I (0x00008000)
+#define SD_STATUS_CR (0x00010000)
+#define SD_STATUS_RAT (0x00020000)
+#define SD_STATUS_DD (0x00040000)
+#define SD_STATUS_DT (0x00080000)
+#define SD_STATUS_SC (0x00100000)
+#define SD_STATUS_RC (0x00200000)
+#define SD_STATUS_WC (0x00400000)
+#define SD_STATUS_xx3 (0x00800000)
+#define SD_STATUS_TH (0x01000000)
+#define SD_STATUS_TE (0x02000000)
+#define SD_STATUS_TA (0x04000000)
+#define SD_STATUS_RH (0x08000000)
+#define SD_STATUS_RA (0x10000000)
+#define SD_STATUS_RF (0x20000000)
+#define SD_STATUS_CD (0x40000000)
+#define SD_STATUS_SI (0x80000000)
+
+
+/*
+ * SD_CMD bit definitions.
+ */
+#define SD_CMD_GO (0x00000001)
+#define SD_CMD_RY (0x00000002)
+#define SD_CMD_xx1 (0x0000000c)
+#define SD_CMD_CT_MASK (0x000000f0)
+#define SD_CMD_CT_0 (0x00000000)
+#define SD_CMD_CT_1 (0x00000010)
+#define SD_CMD_CT_2 (0x00000020)
+#define SD_CMD_CT_3 (0x00000030)
+#define SD_CMD_CT_4 (0x00000040)
+#define SD_CMD_CT_5 (0x00000050)
+#define SD_CMD_CT_6 (0x00000060)
+#define SD_CMD_CT_7 (0x00000070)
+#define SD_CMD_CI (0x0000ff00)
+#define SD_CMD_CI_SHIFT (8)
+#define SD_CMD_RT_MASK (0x00ff0000)
+#define SD_CMD_RT_0 (0x00000000)
+#define SD_CMD_RT_1 (0x00010000)
+#define SD_CMD_RT_2 (0x00020000)
+#define SD_CMD_RT_3 (0x00030000)
+#define SD_CMD_RT_4 (0x00040000)
+#define SD_CMD_RT_5 (0x00050000)
+#define SD_CMD_RT_6 (0x00060000)
+#define SD_CMD_RT_1B (0x00810000)
+
+
+#endif /* __ASM_AU1100_MMC_H */
diff --git a/arch/mips/include/asm/mach-au1x00/au1550_spi.h b/arch/mips/include/asm/mach-au1x00/au1550_spi.h
new file mode 100644
index 00000000..08e1958e
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1550_spi.h
@@ -0,0 +1,15 @@
+/*
+ * au1550_spi.h - Au1550 PSC SPI controller driver - platform data structure
+ */
+
+#ifndef _AU1550_SPI_H_
+#define _AU1550_SPI_H_
+
+struct au1550_spi_info {
+ u32 mainclk_hz; /* main input clock frequency of PSC */
+ u16 num_chipselect; /* number of chipselects supported */
+ void (*activate_cs)(struct au1550_spi_info *spi, int cs, int polarity);
+ void (*deactivate_cs)(struct au1550_spi_info *spi, int cs, int polarity);
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx.h b/arch/mips/include/asm/mach-au1x00/au1xxx.h
new file mode 100644
index 00000000..1b365509
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx.h
@@ -0,0 +1,43 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _AU1XXX_H_
+#define _AU1XXX_H_
+
+#include <asm/mach-au1x00/au1000.h>
+
+#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \
+ defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
+#include <asm/mach-db1x00/db1x00.h>
+
+#elif defined(CONFIG_MIPS_PB1550)
+#include <asm/mach-pb1x00/pb1550.h>
+
+#elif defined(CONFIG_MIPS_PB1200)
+#include <asm/mach-pb1x00/pb1200.h>
+
+#elif defined(CONFIG_MIPS_DB1200)
+#include <asm/mach-db1x00/db1200.h>
+
+#endif
+
+#endif /* _AU1XXX_H_ */
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
new file mode 100644
index 00000000..2fdacfe8
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
@@ -0,0 +1,361 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Include file for Alchemy Semiconductor's Au1550 Descriptor
+ * Based DMA Controller.
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ * dan@embeddededge.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Specifics for the Au1xxx Descriptor-Based DMA Controller,
+ * first seen in the AU1550 part.
+ */
+#ifndef _AU1000_DBDMA_H_
+#define _AU1000_DBDMA_H_
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+typedef volatile struct dbdma_global {
+ u32 ddma_config;
+ u32 ddma_intstat;
+ u32 ddma_throttle;
+ u32 ddma_inten;
+} dbdma_global_t;
+
+/* General Configuration. */
+#define DDMA_CONFIG_AF (1 << 2)
+#define DDMA_CONFIG_AH (1 << 1)
+#define DDMA_CONFIG_AL (1 << 0)
+
+#define DDMA_THROTTLE_EN (1 << 31)
+
+/* The structure of a DMA Channel. */
+typedef volatile struct au1xxx_dma_channel {
+ u32 ddma_cfg; /* See below */
+ u32 ddma_desptr; /* 32-byte aligned pointer to descriptor */
+ u32 ddma_statptr; /* word aligned pointer to status word */
+ u32 ddma_dbell; /* A write activates channel operation */
+ u32 ddma_irq; /* If bit 0 set, interrupt pending */
+ u32 ddma_stat; /* See below */
+ u32 ddma_bytecnt; /* Byte count, valid only when chan idle */
+ /* Remainder, up to the 256 byte boundary, is reserved. */
+} au1x_dma_chan_t;
+
+#define DDMA_CFG_SED (1 << 9) /* source DMA level/edge detect */
+#define DDMA_CFG_SP (1 << 8) /* source DMA polarity */
+#define DDMA_CFG_DED (1 << 7) /* destination DMA level/edge detect */
+#define DDMA_CFG_DP (1 << 6) /* destination DMA polarity */
+#define DDMA_CFG_SYNC (1 << 5) /* Sync static bus controller */
+#define DDMA_CFG_PPR (1 << 4) /* PCI posted read/write control */
+#define DDMA_CFG_DFN (1 << 3) /* Descriptor fetch non-coherent */
+#define DDMA_CFG_SBE (1 << 2) /* Source big endian */
+#define DDMA_CFG_DBE (1 << 1) /* Destination big endian */
+#define DDMA_CFG_EN (1 << 0) /* Channel enable */
+
+/*
+ * Always set when descriptor processing done, regardless of
+ * interrupt enable state. Reflected in global intstat, don't
+ * clear this until global intstat is read/used.
+ */
+#define DDMA_IRQ_IN (1 << 0)
+
+#define DDMA_STAT_DB (1 << 2) /* Doorbell pushed */
+#define DDMA_STAT_V (1 << 1) /* Descriptor valid */
+#define DDMA_STAT_H (1 << 0) /* Channel Halted */
+
+/*
+ * "Standard" DDMA Descriptor.
+ * Must be 32-byte aligned.
+ */
+typedef volatile struct au1xxx_ddma_desc {
+ u32 dscr_cmd0; /* See below */
+ u32 dscr_cmd1; /* See below */
+ u32 dscr_source0; /* source phys address */
+ u32 dscr_source1; /* See below */
+ u32 dscr_dest0; /* Destination address */
+ u32 dscr_dest1; /* See below */
+ u32 dscr_stat; /* completion status */
+ u32 dscr_nxtptr; /* Next descriptor pointer (mostly) */
+ /*
+ * First 32 bytes are HW specific!!!
+ * Lets have some SW data following -- make sure it's 32 bytes.
+ */
+ u32 sw_status;
+ u32 sw_context;
+ u32 sw_reserved[6];
+} au1x_ddma_desc_t;
+
+#define DSCR_CMD0_V (1 << 31) /* Descriptor valid */
+#define DSCR_CMD0_MEM (1 << 30) /* mem-mem transfer */
+#define DSCR_CMD0_SID_MASK (0x1f << 25) /* Source ID */
+#define DSCR_CMD0_DID_MASK (0x1f << 20) /* Destination ID */
+#define DSCR_CMD0_SW_MASK (0x3 << 18) /* Source Width */
+#define DSCR_CMD0_DW_MASK (0x3 << 16) /* Destination Width */
+#define DSCR_CMD0_ARB (0x1 << 15) /* Set for Hi Pri */
+#define DSCR_CMD0_DT_MASK (0x3 << 13) /* Descriptor Type */
+#define DSCR_CMD0_SN (0x1 << 12) /* Source non-coherent */
+#define DSCR_CMD0_DN (0x1 << 11) /* Destination non-coherent */
+#define DSCR_CMD0_SM (0x1 << 10) /* Stride mode */
+#define DSCR_CMD0_IE (0x1 << 8) /* Interrupt Enable */
+#define DSCR_CMD0_SP (0x1 << 4) /* Status pointer select */
+#define DSCR_CMD0_CV (0x1 << 2) /* Clear Valid when done */
+#define DSCR_CMD0_ST_MASK (0x3 << 0) /* Status instruction */
+
+#define SW_STATUS_INUSE (1 << 0)
+
+/* Command 0 device IDs. */
+#ifdef CONFIG_SOC_AU1550
+#define DSCR_CMD0_UART0_TX 0
+#define DSCR_CMD0_UART0_RX 1
+#define DSCR_CMD0_UART3_TX 2
+#define DSCR_CMD0_UART3_RX 3
+#define DSCR_CMD0_DMA_REQ0 4
+#define DSCR_CMD0_DMA_REQ1 5
+#define DSCR_CMD0_DMA_REQ2 6
+#define DSCR_CMD0_DMA_REQ3 7
+#define DSCR_CMD0_USBDEV_RX0 8
+#define DSCR_CMD0_USBDEV_TX0 9
+#define DSCR_CMD0_USBDEV_TX1 10
+#define DSCR_CMD0_USBDEV_TX2 11
+#define DSCR_CMD0_USBDEV_RX3 12
+#define DSCR_CMD0_USBDEV_RX4 13
+#define DSCR_CMD0_PSC0_TX 14
+#define DSCR_CMD0_PSC0_RX 15
+#define DSCR_CMD0_PSC1_TX 16
+#define DSCR_CMD0_PSC1_RX 17
+#define DSCR_CMD0_PSC2_TX 18
+#define DSCR_CMD0_PSC2_RX 19
+#define DSCR_CMD0_PSC3_TX 20
+#define DSCR_CMD0_PSC3_RX 21
+#define DSCR_CMD0_PCI_WRITE 22
+#define DSCR_CMD0_NAND_FLASH 23
+#define DSCR_CMD0_MAC0_RX 24
+#define DSCR_CMD0_MAC0_TX 25
+#define DSCR_CMD0_MAC1_RX 26
+#define DSCR_CMD0_MAC1_TX 27
+#endif /* CONFIG_SOC_AU1550 */
+
+#ifdef CONFIG_SOC_AU1200
+#define DSCR_CMD0_UART0_TX 0
+#define DSCR_CMD0_UART0_RX 1
+#define DSCR_CMD0_UART1_TX 2
+#define DSCR_CMD0_UART1_RX 3
+#define DSCR_CMD0_DMA_REQ0 4
+#define DSCR_CMD0_DMA_REQ1 5
+#define DSCR_CMD0_MAE_BE 6
+#define DSCR_CMD0_MAE_FE 7
+#define DSCR_CMD0_SDMS_TX0 8
+#define DSCR_CMD0_SDMS_RX0 9
+#define DSCR_CMD0_SDMS_TX1 10
+#define DSCR_CMD0_SDMS_RX1 11
+#define DSCR_CMD0_AES_TX 13
+#define DSCR_CMD0_AES_RX 12
+#define DSCR_CMD0_PSC0_TX 14
+#define DSCR_CMD0_PSC0_RX 15
+#define DSCR_CMD0_PSC1_TX 16
+#define DSCR_CMD0_PSC1_RX 17
+#define DSCR_CMD0_CIM_RXA 18
+#define DSCR_CMD0_CIM_RXB 19
+#define DSCR_CMD0_CIM_RXC 20
+#define DSCR_CMD0_MAE_BOTH 21
+#define DSCR_CMD0_LCD 22
+#define DSCR_CMD0_NAND_FLASH 23
+#define DSCR_CMD0_PSC0_SYNC 24
+#define DSCR_CMD0_PSC1_SYNC 25
+#define DSCR_CMD0_CIM_SYNC 26
+#endif /* CONFIG_SOC_AU1200 */
+
+#define DSCR_CMD0_THROTTLE 30
+#define DSCR_CMD0_ALWAYS 31
+#define DSCR_NDEV_IDS 32
+/* This macro is used to find/create custom device types */
+#define DSCR_DEV2CUSTOM_ID(x, d) (((((x) & 0xFFFF) << 8) | 0x32000000) | \
+ ((d) & 0xFF))
+#define DSCR_CUSTOM2DEV_ID(x) ((x) & 0xFF)
+
+#define DSCR_CMD0_SID(x) (((x) & 0x1f) << 25)
+#define DSCR_CMD0_DID(x) (((x) & 0x1f) << 20)
+
+/* Source/Destination transfer width. */
+#define DSCR_CMD0_BYTE 0
+#define DSCR_CMD0_HALFWORD 1
+#define DSCR_CMD0_WORD 2
+
+#define DSCR_CMD0_SW(x) (((x) & 0x3) << 18)
+#define DSCR_CMD0_DW(x) (((x) & 0x3) << 16)
+
+/* DDMA Descriptor Type. */
+#define DSCR_CMD0_STANDARD 0
+#define DSCR_CMD0_LITERAL 1
+#define DSCR_CMD0_CMP_BRANCH 2
+
+#define DSCR_CMD0_DT(x) (((x) & 0x3) << 13)
+
+/* Status Instruction. */
+#define DSCR_CMD0_ST_NOCHANGE 0 /* Don't change */
+#define DSCR_CMD0_ST_CURRENT 1 /* Write current status */
+#define DSCR_CMD0_ST_CMD0 2 /* Write cmd0 with V cleared */
+#define DSCR_CMD0_ST_BYTECNT 3 /* Write remaining byte count */
+
+#define DSCR_CMD0_ST(x) (((x) & 0x3) << 0)
+
+/* Descriptor Command 1. */
+#define DSCR_CMD1_SUPTR_MASK (0xf << 28) /* upper 4 bits of src addr */
+#define DSCR_CMD1_DUPTR_MASK (0xf << 24) /* upper 4 bits of dest addr */
+#define DSCR_CMD1_FL_MASK (0x3 << 22) /* Flag bits */
+#define DSCR_CMD1_BC_MASK (0x3fffff) /* Byte count */
+
+/* Flag description. */
+#define DSCR_CMD1_FL_MEM_STRIDE0 0
+#define DSCR_CMD1_FL_MEM_STRIDE1 1
+#define DSCR_CMD1_FL_MEM_STRIDE2 2
+
+#define DSCR_CMD1_FL(x) (((x) & 0x3) << 22)
+
+/* Source1, 1-dimensional stride. */
+#define DSCR_SRC1_STS_MASK (3 << 30) /* Src xfer size */
+#define DSCR_SRC1_SAM_MASK (3 << 28) /* Src xfer movement */
+#define DSCR_SRC1_SB_MASK (0x3fff << 14) /* Block size */
+#define DSCR_SRC1_SB(x) (((x) & 0x3fff) << 14)
+#define DSCR_SRC1_SS_MASK (0x3fff << 0) /* Stride */
+#define DSCR_SRC1_SS(x) (((x) & 0x3fff) << 0)
+
+/* Dest1, 1-dimensional stride. */
+#define DSCR_DEST1_DTS_MASK (3 << 30) /* Dest xfer size */
+#define DSCR_DEST1_DAM_MASK (3 << 28) /* Dest xfer movement */
+#define DSCR_DEST1_DB_MASK (0x3fff << 14) /* Block size */
+#define DSCR_DEST1_DB(x) (((x) & 0x3fff) << 14)
+#define DSCR_DEST1_DS_MASK (0x3fff << 0) /* Stride */
+#define DSCR_DEST1_DS(x) (((x) & 0x3fff) << 0)
+
+#define DSCR_xTS_SIZE1 0
+#define DSCR_xTS_SIZE2 1
+#define DSCR_xTS_SIZE4 2
+#define DSCR_xTS_SIZE8 3
+#define DSCR_SRC1_STS(x) (((x) & 3) << 30)
+#define DSCR_DEST1_DTS(x) (((x) & 3) << 30)
+
+#define DSCR_xAM_INCREMENT 0
+#define DSCR_xAM_DECREMENT 1
+#define DSCR_xAM_STATIC 2
+#define DSCR_xAM_BURST 3
+#define DSCR_SRC1_SAM(x) (((x) & 3) << 28)
+#define DSCR_DEST1_DAM(x) (((x) & 3) << 28)
+
+/* The next descriptor pointer. */
+#define DSCR_NXTPTR_MASK (0x07ffffff)
+#define DSCR_NXTPTR(x) ((x) >> 5)
+#define DSCR_GET_NXTPTR(x) ((x) << 5)
+#define DSCR_NXTPTR_MS (1 << 27)
+
+/* The number of DBDMA channels. */
+#define NUM_DBDMA_CHANS 16
+
+/*
+ * DDMA API definitions
+ * FIXME: may not fit to this header file
+ */
+typedef struct dbdma_device_table {
+ u32 dev_id;
+ u32 dev_flags;
+ u32 dev_tsize;
+ u32 dev_devwidth;
+ u32 dev_physaddr; /* If FIFO */
+ u32 dev_intlevel;
+ u32 dev_intpolarity;
+} dbdev_tab_t;
+
+
+typedef struct dbdma_chan_config {
+ spinlock_t lock;
+
+ u32 chan_flags;
+ u32 chan_index;
+ dbdev_tab_t *chan_src;
+ dbdev_tab_t *chan_dest;
+ au1x_dma_chan_t *chan_ptr;
+ au1x_ddma_desc_t *chan_desc_base;
+ u32 cdb_membase; /* kmalloc base of above */
+ au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr;
+ void *chan_callparam;
+ void (*chan_callback)(int, void *);
+} chan_tab_t;
+
+#define DEV_FLAGS_INUSE (1 << 0)
+#define DEV_FLAGS_ANYUSE (1 << 1)
+#define DEV_FLAGS_OUT (1 << 2)
+#define DEV_FLAGS_IN (1 << 3)
+#define DEV_FLAGS_BURSTABLE (1 << 4)
+#define DEV_FLAGS_SYNC (1 << 5)
+/* end DDMA API definitions */
+
+/*
+ * External functions for drivers to use.
+ * Use this to allocate a DBDMA channel. The device IDs are one of
+ * the DSCR_CMD0 devices IDs, which is usually redefined to a more
+ * meaningful name. The 'callback' is called during DMA completion
+ * interrupt.
+ */
+extern u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+ void (*callback)(int, void *),
+ void *callparam);
+
+#define DBDMA_MEM_CHAN DSCR_CMD0_ALWAYS
+
+/* Set the device width of an in/out FIFO. */
+u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
+
+/* Allocate a ring of descriptors for DBDMA. */
+u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
+
+/* Put buffers on source/destination descriptors. */
+u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
+u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
+
+/* Get a buffer from the destination descriptor. */
+u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);
+
+void au1xxx_dbdma_stop(u32 chanid);
+void au1xxx_dbdma_start(u32 chanid);
+void au1xxx_dbdma_reset(u32 chanid);
+u32 au1xxx_get_dma_residue(u32 chanid);
+
+void au1xxx_dbdma_chan_free(u32 chanid);
+void au1xxx_dbdma_dump(u32 chanid);
+
+u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr);
+
+u32 au1xxx_ddma_add_device(dbdev_tab_t *dev);
+extern void au1xxx_ddma_del_device(u32 devid);
+void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
+
+/*
+ * Flags for the put_source/put_dest functions.
+ */
+#define DDMA_FLAGS_IE (1 << 0)
+#define DDMA_FLAGS_NOIE (1 << 1)
+
+#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* _AU1000_DBDMA_H_ */
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
new file mode 100644
index 00000000..49dc8d9d
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h
@@ -0,0 +1,18 @@
+#ifndef __AU1X00_ETH_DATA_H
+#define __AU1X00_ETH_DATA_H
+
+/* Platform specific PHY configuration passed to the MAC driver */
+struct au1000_eth_platform_data {
+ int phy_static_config;
+ int phy_search_highest_addr;
+ int phy1_search_mac0;
+ int phy_addr;
+ int phy_busid;
+ int phy_irq;
+ char mac[6];
+};
+
+void __init au1xxx_override_eth_cfg(unsigned port,
+ struct au1000_eth_platform_data *eth_data);
+
+#endif /* __AU1X00_ETH_DATA_H */
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h b/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h
new file mode 100644
index 00000000..5656c72d
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_ide.h
@@ -0,0 +1,177 @@
+/*
+ * include/asm-mips/mach-au1x00/au1xxx_ide.h version 01.30.00 Aug. 02 2005
+ *
+ * BRIEF MODULE DESCRIPTION
+ * AMD Alchemy Au1xxx IDE interface routines over the Static Bus
+ *
+ * Copyright (c) 2003-2005 AMD, Personal Connectivity Solutions
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Note: for more information, please refer "AMD Alchemy Au1200/Au1550 IDE
+ * Interface and Linux Device Driver" Application Note.
+ */
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+#define DMA_WAIT_TIMEOUT 100
+#define NUM_DESCRIPTORS PRD_ENTRIES
+#else /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
+#define NUM_DESCRIPTORS 2
+#endif
+
+#ifndef AU1XXX_ATA_RQSIZE
+#define AU1XXX_ATA_RQSIZE 128
+#endif
+
+/* Disable Burstable-Support for DBDMA */
+#ifndef CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
+#define CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON 0
+#endif
+
+typedef struct {
+ u32 tx_dev_id, rx_dev_id, target_dev_id;
+ u32 tx_chan, rx_chan;
+ void *tx_desc_head, *rx_desc_head;
+ ide_hwif_t *hwif;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ ide_drive_t *drive;
+ struct dbdma_cmd *dma_table_cpu;
+ dma_addr_t dma_table_dma;
+#endif
+ int irq;
+ u32 regbase;
+} _auide_hwif;
+
+/******************************************************************************/
+/* PIO Mode timing calculation : */
+/* */
+/* Static Bus Spec ATA Spec */
+/* Tcsoe = t1 */
+/* Toecs = t9 */
+/* Twcs = t9 */
+/* Tcsh = t2i | t2 */
+/* Tcsoff = t2i | t2 */
+/* Twp = t2 */
+/* Tcsw = t1 */
+/* Tpm = 0 */
+/* Ta = t1+t2 */
+/******************************************************************************/
+
+#define TCSOE_MASK (0x07 << 29)
+#define TOECS_MASK (0x07 << 26)
+#define TWCS_MASK (0x07 << 28)
+#define TCSH_MASK (0x0F << 24)
+#define TCSOFF_MASK (0x07 << 20)
+#define TWP_MASK (0x3F << 14)
+#define TCSW_MASK (0x0F << 10)
+#define TPM_MASK (0x0F << 6)
+#define TA_MASK (0x3F << 0)
+#define TS_MASK (1 << 8)
+
+/* Timing parameters PIO mode 0 */
+#define SBC_IDE_PIO0_TCSOE (0x04 << 29)
+#define SBC_IDE_PIO0_TOECS (0x01 << 26)
+#define SBC_IDE_PIO0_TWCS (0x02 << 28)
+#define SBC_IDE_PIO0_TCSH (0x08 << 24)
+#define SBC_IDE_PIO0_TCSOFF (0x07 << 20)
+#define SBC_IDE_PIO0_TWP (0x10 << 14)
+#define SBC_IDE_PIO0_TCSW (0x04 << 10)
+#define SBC_IDE_PIO0_TPM (0x00 << 6)
+#define SBC_IDE_PIO0_TA (0x15 << 0)
+/* Timing parameters PIO mode 1 */
+#define SBC_IDE_PIO1_TCSOE (0x03 << 29)
+#define SBC_IDE_PIO1_TOECS (0x01 << 26)
+#define SBC_IDE_PIO1_TWCS (0x01 << 28)
+#define SBC_IDE_PIO1_TCSH (0x06 << 24)
+#define SBC_IDE_PIO1_TCSOFF (0x06 << 20)
+#define SBC_IDE_PIO1_TWP (0x08 << 14)
+#define SBC_IDE_PIO1_TCSW (0x03 << 10)
+#define SBC_IDE_PIO1_TPM (0x00 << 6)
+#define SBC_IDE_PIO1_TA (0x0B << 0)
+/* Timing parameters PIO mode 2 */
+#define SBC_IDE_PIO2_TCSOE (0x05 << 29)
+#define SBC_IDE_PIO2_TOECS (0x01 << 26)
+#define SBC_IDE_PIO2_TWCS (0x01 << 28)
+#define SBC_IDE_PIO2_TCSH (0x07 << 24)
+#define SBC_IDE_PIO2_TCSOFF (0x07 << 20)
+#define SBC_IDE_PIO2_TWP (0x1F << 14)
+#define SBC_IDE_PIO2_TCSW (0x05 << 10)
+#define SBC_IDE_PIO2_TPM (0x00 << 6)
+#define SBC_IDE_PIO2_TA (0x22 << 0)
+/* Timing parameters PIO mode 3 */
+#define SBC_IDE_PIO3_TCSOE (0x05 << 29)
+#define SBC_IDE_PIO3_TOECS (0x01 << 26)
+#define SBC_IDE_PIO3_TWCS (0x01 << 28)
+#define SBC_IDE_PIO3_TCSH (0x0D << 24)
+#define SBC_IDE_PIO3_TCSOFF (0x0D << 20)
+#define SBC_IDE_PIO3_TWP (0x15 << 14)
+#define SBC_IDE_PIO3_TCSW (0x05 << 10)
+#define SBC_IDE_PIO3_TPM (0x00 << 6)
+#define SBC_IDE_PIO3_TA (0x1A << 0)
+/* Timing parameters PIO mode 4 */
+#define SBC_IDE_PIO4_TCSOE (0x04 << 29)
+#define SBC_IDE_PIO4_TOECS (0x01 << 26)
+#define SBC_IDE_PIO4_TWCS (0x01 << 28)
+#define SBC_IDE_PIO4_TCSH (0x04 << 24)
+#define SBC_IDE_PIO4_TCSOFF (0x04 << 20)
+#define SBC_IDE_PIO4_TWP (0x0D << 14)
+#define SBC_IDE_PIO4_TCSW (0x03 << 10)
+#define SBC_IDE_PIO4_TPM (0x00 << 6)
+#define SBC_IDE_PIO4_TA (0x12 << 0)
+/* Timing parameters MDMA mode 0 */
+#define SBC_IDE_MDMA0_TCSOE (0x03 << 29)
+#define SBC_IDE_MDMA0_TOECS (0x01 << 26)
+#define SBC_IDE_MDMA0_TWCS (0x01 << 28)
+#define SBC_IDE_MDMA0_TCSH (0x07 << 24)
+#define SBC_IDE_MDMA0_TCSOFF (0x07 << 20)
+#define SBC_IDE_MDMA0_TWP (0x0C << 14)
+#define SBC_IDE_MDMA0_TCSW (0x03 << 10)
+#define SBC_IDE_MDMA0_TPM (0x00 << 6)
+#define SBC_IDE_MDMA0_TA (0x0F << 0)
+/* Timing parameters MDMA mode 1 */
+#define SBC_IDE_MDMA1_TCSOE (0x05 << 29)
+#define SBC_IDE_MDMA1_TOECS (0x01 << 26)
+#define SBC_IDE_MDMA1_TWCS (0x01 << 28)
+#define SBC_IDE_MDMA1_TCSH (0x05 << 24)
+#define SBC_IDE_MDMA1_TCSOFF (0x05 << 20)
+#define SBC_IDE_MDMA1_TWP (0x0F << 14)
+#define SBC_IDE_MDMA1_TCSW (0x05 << 10)
+#define SBC_IDE_MDMA1_TPM (0x00 << 6)
+#define SBC_IDE_MDMA1_TA (0x15 << 0)
+/* Timing parameters MDMA mode 2 */
+#define SBC_IDE_MDMA2_TCSOE (0x04 << 29)
+#define SBC_IDE_MDMA2_TOECS (0x01 << 26)
+#define SBC_IDE_MDMA2_TWCS (0x01 << 28)
+#define SBC_IDE_MDMA2_TCSH (0x04 << 24)
+#define SBC_IDE_MDMA2_TCSOFF (0x04 << 20)
+#define SBC_IDE_MDMA2_TWP (0x0D << 14)
+#define SBC_IDE_MDMA2_TCSW (0x04 << 10)
+#define SBC_IDE_MDMA2_TPM (0x00 << 6)
+#define SBC_IDE_MDMA2_TA (0x12 << 0)
+
+#define SBC_IDE_TIMING(mode) \
+ (SBC_IDE_##mode##_TWCS | \
+ SBC_IDE_##mode##_TCSH | \
+ SBC_IDE_##mode##_TCSOFF | \
+ SBC_IDE_##mode##_TWP | \
+ SBC_IDE_##mode##_TCSW | \
+ SBC_IDE_##mode##_TPM | \
+ SBC_IDE_##mode##_TA)
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h b/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h
new file mode 100644
index 00000000..892b7f16
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_psc.h
@@ -0,0 +1,505 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Include file for Alchemy Semiconductor's Au1k CPU.
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ * dan@embeddededge.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Specifics for the Au1xxx Programmable Serial Controllers, first
+ * seen in the AU1550 part.
+ */
+#ifndef _AU1000_PSC_H_
+#define _AU1000_PSC_H_
+
+/* The PSC base addresses. */
+#ifdef CONFIG_SOC_AU1550
+#define PSC0_BASE_ADDR 0xb1a00000
+#define PSC1_BASE_ADDR 0xb1b00000
+#define PSC2_BASE_ADDR 0xb0a00000
+#define PSC3_BASE_ADDR 0xb0b00000
+#endif
+
+#ifdef CONFIG_SOC_AU1200
+#define PSC0_BASE_ADDR 0xb1a00000
+#define PSC1_BASE_ADDR 0xb1b00000
+#endif
+
+/*
+ * The PSC select and control registers are common to all protocols.
+ */
+#define PSC_SEL_OFFSET 0x00000000
+#define PSC_CTRL_OFFSET 0x00000004
+
+#define PSC_SEL_CLK_MASK (3 << 4)
+#define PSC_SEL_CLK_INTCLK (0 << 4)
+#define PSC_SEL_CLK_EXTCLK (1 << 4)
+#define PSC_SEL_CLK_SERCLK (2 << 4)
+
+#define PSC_SEL_PS_MASK 0x00000007
+#define PSC_SEL_PS_DISABLED 0
+#define PSC_SEL_PS_SPIMODE 2
+#define PSC_SEL_PS_I2SMODE 3
+#define PSC_SEL_PS_AC97MODE 4
+#define PSC_SEL_PS_SMBUSMODE 5
+
+#define PSC_CTRL_DISABLE 0
+#define PSC_CTRL_SUSPEND 2
+#define PSC_CTRL_ENABLE 3
+
+/* AC97 Registers. */
+#define PSC_AC97CFG_OFFSET 0x00000008
+#define PSC_AC97MSK_OFFSET 0x0000000c
+#define PSC_AC97PCR_OFFSET 0x00000010
+#define PSC_AC97STAT_OFFSET 0x00000014
+#define PSC_AC97EVNT_OFFSET 0x00000018
+#define PSC_AC97TXRX_OFFSET 0x0000001c
+#define PSC_AC97CDC_OFFSET 0x00000020
+#define PSC_AC97RST_OFFSET 0x00000024
+#define PSC_AC97GPO_OFFSET 0x00000028
+#define PSC_AC97GPI_OFFSET 0x0000002c
+
+#define AC97_PSC_SEL (AC97_PSC_BASE + PSC_SEL_OFFSET)
+#define AC97_PSC_CTRL (AC97_PSC_BASE + PSC_CTRL_OFFSET)
+#define PSC_AC97CFG (AC97_PSC_BASE + PSC_AC97CFG_OFFSET)
+#define PSC_AC97MSK (AC97_PSC_BASE + PSC_AC97MSK_OFFSET)
+#define PSC_AC97PCR (AC97_PSC_BASE + PSC_AC97PCR_OFFSET)
+#define PSC_AC97STAT (AC97_PSC_BASE + PSC_AC97STAT_OFFSET)
+#define PSC_AC97EVNT (AC97_PSC_BASE + PSC_AC97EVNT_OFFSET)
+#define PSC_AC97TXRX (AC97_PSC_BASE + PSC_AC97TXRX_OFFSET)
+#define PSC_AC97CDC (AC97_PSC_BASE + PSC_AC97CDC_OFFSET)
+#define PSC_AC97RST (AC97_PSC_BASE + PSC_AC97RST_OFFSET)
+#define PSC_AC97GPO (AC97_PSC_BASE + PSC_AC97GPO_OFFSET)
+#define PSC_AC97GPI (AC97_PSC_BASE + PSC_AC97GPI_OFFSET)
+
+/* AC97 Config Register. */
+#define PSC_AC97CFG_RT_MASK (3 << 30)
+#define PSC_AC97CFG_RT_FIFO1 (0 << 30)
+#define PSC_AC97CFG_RT_FIFO2 (1 << 30)
+#define PSC_AC97CFG_RT_FIFO4 (2 << 30)
+#define PSC_AC97CFG_RT_FIFO8 (3 << 30)
+
+#define PSC_AC97CFG_TT_MASK (3 << 28)
+#define PSC_AC97CFG_TT_FIFO1 (0 << 28)
+#define PSC_AC97CFG_TT_FIFO2 (1 << 28)
+#define PSC_AC97CFG_TT_FIFO4 (2 << 28)
+#define PSC_AC97CFG_TT_FIFO8 (3 << 28)
+
+#define PSC_AC97CFG_DD_DISABLE (1 << 27)
+#define PSC_AC97CFG_DE_ENABLE (1 << 26)
+#define PSC_AC97CFG_SE_ENABLE (1 << 25)
+
+#define PSC_AC97CFG_LEN_MASK (0xf << 21)
+#define PSC_AC97CFG_TXSLOT_MASK (0x3ff << 11)
+#define PSC_AC97CFG_RXSLOT_MASK (0x3ff << 1)
+#define PSC_AC97CFG_GE_ENABLE (1)
+
+/* Enable slots 3-12. */
+#define PSC_AC97CFG_TXSLOT_ENA(x) (1 << (((x) - 3) + 11))
+#define PSC_AC97CFG_RXSLOT_ENA(x) (1 << (((x) - 3) + 1))
+
+/*
+ * The word length equation is ((x) * 2) + 2, so choose 'x' appropriately.
+ * The only sensible numbers are 7, 9, or possibly 11. Nah, just do the
+ * arithmetic in the macro.
+ */
+#define PSC_AC97CFG_SET_LEN(x) (((((x) - 2) / 2) & 0xf) << 21)
+#define PSC_AC97CFG_GET_LEN(x) (((((x) >> 21) & 0xf) * 2) + 2)
+
+/* AC97 Mask Register. */
+#define PSC_AC97MSK_GR (1 << 25)
+#define PSC_AC97MSK_CD (1 << 24)
+#define PSC_AC97MSK_RR (1 << 13)
+#define PSC_AC97MSK_RO (1 << 12)
+#define PSC_AC97MSK_RU (1 << 11)
+#define PSC_AC97MSK_TR (1 << 10)
+#define PSC_AC97MSK_TO (1 << 9)
+#define PSC_AC97MSK_TU (1 << 8)
+#define PSC_AC97MSK_RD (1 << 5)
+#define PSC_AC97MSK_TD (1 << 4)
+#define PSC_AC97MSK_ALLMASK (PSC_AC97MSK_GR | PSC_AC97MSK_CD | \
+ PSC_AC97MSK_RR | PSC_AC97MSK_RO | \
+ PSC_AC97MSK_RU | PSC_AC97MSK_TR | \
+ PSC_AC97MSK_TO | PSC_AC97MSK_TU | \
+ PSC_AC97MSK_RD | PSC_AC97MSK_TD)
+
+/* AC97 Protocol Control Register. */
+#define PSC_AC97PCR_RC (1 << 6)
+#define PSC_AC97PCR_RP (1 << 5)
+#define PSC_AC97PCR_RS (1 << 4)
+#define PSC_AC97PCR_TC (1 << 2)
+#define PSC_AC97PCR_TP (1 << 1)
+#define PSC_AC97PCR_TS (1 << 0)
+
+/* AC97 Status register (read only). */
+#define PSC_AC97STAT_CB (1 << 26)
+#define PSC_AC97STAT_CP (1 << 25)
+#define PSC_AC97STAT_CR (1 << 24)
+#define PSC_AC97STAT_RF (1 << 13)
+#define PSC_AC97STAT_RE (1 << 12)
+#define PSC_AC97STAT_RR (1 << 11)
+#define PSC_AC97STAT_TF (1 << 10)
+#define PSC_AC97STAT_TE (1 << 9)
+#define PSC_AC97STAT_TR (1 << 8)
+#define PSC_AC97STAT_RB (1 << 5)
+#define PSC_AC97STAT_TB (1 << 4)
+#define PSC_AC97STAT_DI (1 << 2)
+#define PSC_AC97STAT_DR (1 << 1)
+#define PSC_AC97STAT_SR (1 << 0)
+
+/* AC97 Event Register. */
+#define PSC_AC97EVNT_GR (1 << 25)
+#define PSC_AC97EVNT_CD (1 << 24)
+#define PSC_AC97EVNT_RR (1 << 13)
+#define PSC_AC97EVNT_RO (1 << 12)
+#define PSC_AC97EVNT_RU (1 << 11)
+#define PSC_AC97EVNT_TR (1 << 10)
+#define PSC_AC97EVNT_TO (1 << 9)
+#define PSC_AC97EVNT_TU (1 << 8)
+#define PSC_AC97EVNT_RD (1 << 5)
+#define PSC_AC97EVNT_TD (1 << 4)
+
+/* CODEC Command Register. */
+#define PSC_AC97CDC_RD (1 << 25)
+#define PSC_AC97CDC_ID_MASK (3 << 23)
+#define PSC_AC97CDC_INDX_MASK (0x7f << 16)
+#define PSC_AC97CDC_ID(x) (((x) & 0x03) << 23)
+#define PSC_AC97CDC_INDX(x) (((x) & 0x7f) << 16)
+
+/* AC97 Reset Control Register. */
+#define PSC_AC97RST_RST (1 << 1)
+#define PSC_AC97RST_SNC (1 << 0)
+
+/* PSC in I2S Mode. */
+typedef struct psc_i2s {
+ u32 psc_sel;
+ u32 psc_ctrl;
+ u32 psc_i2scfg;
+ u32 psc_i2smsk;
+ u32 psc_i2spcr;
+ u32 psc_i2sstat;
+ u32 psc_i2sevent;
+ u32 psc_i2stxrx;
+ u32 psc_i2sudf;
+} psc_i2s_t;
+
+#define PSC_I2SCFG_OFFSET 0x08
+#define PSC_I2SMASK_OFFSET 0x0C
+#define PSC_I2SPCR_OFFSET 0x10
+#define PSC_I2SSTAT_OFFSET 0x14
+#define PSC_I2SEVENT_OFFSET 0x18
+#define PSC_I2SRXTX_OFFSET 0x1C
+#define PSC_I2SUDF_OFFSET 0x20
+
+/* I2S Config Register. */
+#define PSC_I2SCFG_RT_MASK (3 << 30)
+#define PSC_I2SCFG_RT_FIFO1 (0 << 30)
+#define PSC_I2SCFG_RT_FIFO2 (1 << 30)
+#define PSC_I2SCFG_RT_FIFO4 (2 << 30)
+#define PSC_I2SCFG_RT_FIFO8 (3 << 30)
+
+#define PSC_I2SCFG_TT_MASK (3 << 28)
+#define PSC_I2SCFG_TT_FIFO1 (0 << 28)
+#define PSC_I2SCFG_TT_FIFO2 (1 << 28)
+#define PSC_I2SCFG_TT_FIFO4 (2 << 28)
+#define PSC_I2SCFG_TT_FIFO8 (3 << 28)
+
+#define PSC_I2SCFG_DD_DISABLE (1 << 27)
+#define PSC_I2SCFG_DE_ENABLE (1 << 26)
+#define PSC_I2SCFG_SET_WS(x) (((((x) / 2) - 1) & 0x7f) << 16)
+#define PSC_I2SCFG_WS(n) ((n & 0xFF) << 16)
+#define PSC_I2SCFG_WS_MASK (PSC_I2SCFG_WS(0x3F))
+#define PSC_I2SCFG_WI (1 << 15)
+
+#define PSC_I2SCFG_DIV_MASK (3 << 13)
+#define PSC_I2SCFG_DIV2 (0 << 13)
+#define PSC_I2SCFG_DIV4 (1 << 13)
+#define PSC_I2SCFG_DIV8 (2 << 13)
+#define PSC_I2SCFG_DIV16 (3 << 13)
+
+#define PSC_I2SCFG_BI (1 << 12)
+#define PSC_I2SCFG_BUF (1 << 11)
+#define PSC_I2SCFG_MLJ (1 << 10)
+#define PSC_I2SCFG_XM (1 << 9)
+
+/* The word length equation is simply LEN+1. */
+#define PSC_I2SCFG_SET_LEN(x) ((((x) - 1) & 0x1f) << 4)
+#define PSC_I2SCFG_GET_LEN(x) ((((x) >> 4) & 0x1f) + 1)
+
+#define PSC_I2SCFG_LB (1 << 2)
+#define PSC_I2SCFG_MLF (1 << 1)
+#define PSC_I2SCFG_MS (1 << 0)
+
+/* I2S Mask Register. */
+#define PSC_I2SMSK_RR (1 << 13)
+#define PSC_I2SMSK_RO (1 << 12)
+#define PSC_I2SMSK_RU (1 << 11)
+#define PSC_I2SMSK_TR (1 << 10)
+#define PSC_I2SMSK_TO (1 << 9)
+#define PSC_I2SMSK_TU (1 << 8)
+#define PSC_I2SMSK_RD (1 << 5)
+#define PSC_I2SMSK_TD (1 << 4)
+#define PSC_I2SMSK_ALLMASK (PSC_I2SMSK_RR | PSC_I2SMSK_RO | \
+ PSC_I2SMSK_RU | PSC_I2SMSK_TR | \
+ PSC_I2SMSK_TO | PSC_I2SMSK_TU | \
+ PSC_I2SMSK_RD | PSC_I2SMSK_TD)
+
+/* I2S Protocol Control Register. */
+#define PSC_I2SPCR_RC (1 << 6)
+#define PSC_I2SPCR_RP (1 << 5)
+#define PSC_I2SPCR_RS (1 << 4)
+#define PSC_I2SPCR_TC (1 << 2)
+#define PSC_I2SPCR_TP (1 << 1)
+#define PSC_I2SPCR_TS (1 << 0)
+
+/* I2S Status register (read only). */
+#define PSC_I2SSTAT_RF (1 << 13)
+#define PSC_I2SSTAT_RE (1 << 12)
+#define PSC_I2SSTAT_RR (1 << 11)
+#define PSC_I2SSTAT_TF (1 << 10)
+#define PSC_I2SSTAT_TE (1 << 9)
+#define PSC_I2SSTAT_TR (1 << 8)
+#define PSC_I2SSTAT_RB (1 << 5)
+#define PSC_I2SSTAT_TB (1 << 4)
+#define PSC_I2SSTAT_DI (1 << 2)
+#define PSC_I2SSTAT_DR (1 << 1)
+#define PSC_I2SSTAT_SR (1 << 0)
+
+/* I2S Event Register. */
+#define PSC_I2SEVNT_RR (1 << 13)
+#define PSC_I2SEVNT_RO (1 << 12)
+#define PSC_I2SEVNT_RU (1 << 11)
+#define PSC_I2SEVNT_TR (1 << 10)
+#define PSC_I2SEVNT_TO (1 << 9)
+#define PSC_I2SEVNT_TU (1 << 8)
+#define PSC_I2SEVNT_RD (1 << 5)
+#define PSC_I2SEVNT_TD (1 << 4)
+
+/* PSC in SPI Mode. */
+typedef struct psc_spi {
+ u32 psc_sel;
+ u32 psc_ctrl;
+ u32 psc_spicfg;
+ u32 psc_spimsk;
+ u32 psc_spipcr;
+ u32 psc_spistat;
+ u32 psc_spievent;
+ u32 psc_spitxrx;
+} psc_spi_t;
+
+/* SPI Config Register. */
+#define PSC_SPICFG_RT_MASK (3 << 30)
+#define PSC_SPICFG_RT_FIFO1 (0 << 30)
+#define PSC_SPICFG_RT_FIFO2 (1 << 30)
+#define PSC_SPICFG_RT_FIFO4 (2 << 30)
+#define PSC_SPICFG_RT_FIFO8 (3 << 30)
+
+#define PSC_SPICFG_TT_MASK (3 << 28)
+#define PSC_SPICFG_TT_FIFO1 (0 << 28)
+#define PSC_SPICFG_TT_FIFO2 (1 << 28)
+#define PSC_SPICFG_TT_FIFO4 (2 << 28)
+#define PSC_SPICFG_TT_FIFO8 (3 << 28)
+
+#define PSC_SPICFG_DD_DISABLE (1 << 27)
+#define PSC_SPICFG_DE_ENABLE (1 << 26)
+#define PSC_SPICFG_CLR_BAUD(x) ((x) & ~((0x3f) << 15))
+#define PSC_SPICFG_SET_BAUD(x) (((x) & 0x3f) << 15)
+
+#define PSC_SPICFG_SET_DIV(x) (((x) & 0x03) << 13)
+#define PSC_SPICFG_DIV2 0
+#define PSC_SPICFG_DIV4 1
+#define PSC_SPICFG_DIV8 2
+#define PSC_SPICFG_DIV16 3
+
+#define PSC_SPICFG_BI (1 << 12)
+#define PSC_SPICFG_PSE (1 << 11)
+#define PSC_SPICFG_CGE (1 << 10)
+#define PSC_SPICFG_CDE (1 << 9)
+
+#define PSC_SPICFG_CLR_LEN(x) ((x) & ~((0x1f) << 4))
+#define PSC_SPICFG_SET_LEN(x) (((x-1) & 0x1f) << 4)
+
+#define PSC_SPICFG_LB (1 << 3)
+#define PSC_SPICFG_MLF (1 << 1)
+#define PSC_SPICFG_MO (1 << 0)
+
+/* SPI Mask Register. */
+#define PSC_SPIMSK_MM (1 << 16)
+#define PSC_SPIMSK_RR (1 << 13)
+#define PSC_SPIMSK_RO (1 << 12)
+#define PSC_SPIMSK_RU (1 << 11)
+#define PSC_SPIMSK_TR (1 << 10)
+#define PSC_SPIMSK_TO (1 << 9)
+#define PSC_SPIMSK_TU (1 << 8)
+#define PSC_SPIMSK_SD (1 << 5)
+#define PSC_SPIMSK_MD (1 << 4)
+#define PSC_SPIMSK_ALLMASK (PSC_SPIMSK_MM | PSC_SPIMSK_RR | \
+ PSC_SPIMSK_RO | PSC_SPIMSK_TO | \
+ PSC_SPIMSK_TU | PSC_SPIMSK_SD | \
+ PSC_SPIMSK_MD)
+
+/* SPI Protocol Control Register. */
+#define PSC_SPIPCR_RC (1 << 6)
+#define PSC_SPIPCR_SP (1 << 5)
+#define PSC_SPIPCR_SS (1 << 4)
+#define PSC_SPIPCR_TC (1 << 2)
+#define PSC_SPIPCR_MS (1 << 0)
+
+/* SPI Status register (read only). */
+#define PSC_SPISTAT_RF (1 << 13)
+#define PSC_SPISTAT_RE (1 << 12)
+#define PSC_SPISTAT_RR (1 << 11)
+#define PSC_SPISTAT_TF (1 << 10)
+#define PSC_SPISTAT_TE (1 << 9)
+#define PSC_SPISTAT_TR (1 << 8)
+#define PSC_SPISTAT_SB (1 << 5)
+#define PSC_SPISTAT_MB (1 << 4)
+#define PSC_SPISTAT_DI (1 << 2)
+#define PSC_SPISTAT_DR (1 << 1)
+#define PSC_SPISTAT_SR (1 << 0)
+
+/* SPI Event Register. */
+#define PSC_SPIEVNT_MM (1 << 16)
+#define PSC_SPIEVNT_RR (1 << 13)
+#define PSC_SPIEVNT_RO (1 << 12)
+#define PSC_SPIEVNT_RU (1 << 11)
+#define PSC_SPIEVNT_TR (1 << 10)
+#define PSC_SPIEVNT_TO (1 << 9)
+#define PSC_SPIEVNT_TU (1 << 8)
+#define PSC_SPIEVNT_SD (1 << 5)
+#define PSC_SPIEVNT_MD (1 << 4)
+
+/* Transmit register control. */
+#define PSC_SPITXRX_LC (1 << 29)
+#define PSC_SPITXRX_SR (1 << 28)
+
+/* PSC in SMBus (I2C) Mode. */
+typedef struct psc_smb {
+ u32 psc_sel;
+ u32 psc_ctrl;
+ u32 psc_smbcfg;
+ u32 psc_smbmsk;
+ u32 psc_smbpcr;
+ u32 psc_smbstat;
+ u32 psc_smbevnt;
+ u32 psc_smbtxrx;
+ u32 psc_smbtmr;
+} psc_smb_t;
+
+/* SMBus Config Register. */
+#define PSC_SMBCFG_RT_MASK (3 << 30)
+#define PSC_SMBCFG_RT_FIFO1 (0 << 30)
+#define PSC_SMBCFG_RT_FIFO2 (1 << 30)
+#define PSC_SMBCFG_RT_FIFO4 (2 << 30)
+#define PSC_SMBCFG_RT_FIFO8 (3 << 30)
+
+#define PSC_SMBCFG_TT_MASK (3 << 28)
+#define PSC_SMBCFG_TT_FIFO1 (0 << 28)
+#define PSC_SMBCFG_TT_FIFO2 (1 << 28)
+#define PSC_SMBCFG_TT_FIFO4 (2 << 28)
+#define PSC_SMBCFG_TT_FIFO8 (3 << 28)
+
+#define PSC_SMBCFG_DD_DISABLE (1 << 27)
+#define PSC_SMBCFG_DE_ENABLE (1 << 26)
+
+#define PSC_SMBCFG_SET_DIV(x) (((x) & 0x03) << 13)
+#define PSC_SMBCFG_DIV2 0
+#define PSC_SMBCFG_DIV4 1
+#define PSC_SMBCFG_DIV8 2
+#define PSC_SMBCFG_DIV16 3
+
+#define PSC_SMBCFG_GCE (1 << 9)
+#define PSC_SMBCFG_SFM (1 << 8)
+
+#define PSC_SMBCFG_SET_SLV(x) (((x) & 0x7f) << 1)
+
+/* SMBus Mask Register. */
+#define PSC_SMBMSK_DN (1 << 30)
+#define PSC_SMBMSK_AN (1 << 29)
+#define PSC_SMBMSK_AL (1 << 28)
+#define PSC_SMBMSK_RR (1 << 13)
+#define PSC_SMBMSK_RO (1 << 12)
+#define PSC_SMBMSK_RU (1 << 11)
+#define PSC_SMBMSK_TR (1 << 10)
+#define PSC_SMBMSK_TO (1 << 9)
+#define PSC_SMBMSK_TU (1 << 8)
+#define PSC_SMBMSK_SD (1 << 5)
+#define PSC_SMBMSK_MD (1 << 4)
+#define PSC_SMBMSK_ALLMASK (PSC_SMBMSK_DN | PSC_SMBMSK_AN | \
+ PSC_SMBMSK_AL | PSC_SMBMSK_RR | \
+ PSC_SMBMSK_RO | PSC_SMBMSK_TO | \
+ PSC_SMBMSK_TU | PSC_SMBMSK_SD | \
+ PSC_SMBMSK_MD)
+
+/* SMBus Protocol Control Register. */
+#define PSC_SMBPCR_DC (1 << 2)
+#define PSC_SMBPCR_MS (1 << 0)
+
+/* SMBus Status register (read only). */
+#define PSC_SMBSTAT_BB (1 << 28)
+#define PSC_SMBSTAT_RF (1 << 13)
+#define PSC_SMBSTAT_RE (1 << 12)
+#define PSC_SMBSTAT_RR (1 << 11)
+#define PSC_SMBSTAT_TF (1 << 10)
+#define PSC_SMBSTAT_TE (1 << 9)
+#define PSC_SMBSTAT_TR (1 << 8)
+#define PSC_SMBSTAT_SB (1 << 5)
+#define PSC_SMBSTAT_MB (1 << 4)
+#define PSC_SMBSTAT_DI (1 << 2)
+#define PSC_SMBSTAT_DR (1 << 1)
+#define PSC_SMBSTAT_SR (1 << 0)
+
+/* SMBus Event Register. */
+#define PSC_SMBEVNT_DN (1 << 30)
+#define PSC_SMBEVNT_AN (1 << 29)
+#define PSC_SMBEVNT_AL (1 << 28)
+#define PSC_SMBEVNT_RR (1 << 13)
+#define PSC_SMBEVNT_RO (1 << 12)
+#define PSC_SMBEVNT_RU (1 << 11)
+#define PSC_SMBEVNT_TR (1 << 10)
+#define PSC_SMBEVNT_TO (1 << 9)
+#define PSC_SMBEVNT_TU (1 << 8)
+#define PSC_SMBEVNT_SD (1 << 5)
+#define PSC_SMBEVNT_MD (1 << 4)
+#define PSC_SMBEVNT_ALLCLR (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | \
+ PSC_SMBEVNT_AL | PSC_SMBEVNT_RR | \
+ PSC_SMBEVNT_RO | PSC_SMBEVNT_TO | \
+ PSC_SMBEVNT_TU | PSC_SMBEVNT_SD | \
+ PSC_SMBEVNT_MD)
+
+/* Transmit register control. */
+#define PSC_SMBTXRX_RSR (1 << 28)
+#define PSC_SMBTXRX_STP (1 << 29)
+#define PSC_SMBTXRX_DATAMASK 0xff
+
+/* SMBus protocol timers register. */
+#define PSC_SMBTMR_SET_TH(x) (((x) & 0x03) << 30)
+#define PSC_SMBTMR_SET_PS(x) (((x) & 0x1f) << 25)
+#define PSC_SMBTMR_SET_PU(x) (((x) & 0x1f) << 20)
+#define PSC_SMBTMR_SET_SH(x) (((x) & 0x1f) << 15)
+#define PSC_SMBTMR_SET_SU(x) (((x) & 0x1f) << 10)
+#define PSC_SMBTMR_SET_CL(x) (((x) & 0x1f) << 5)
+#define PSC_SMBTMR_SET_CH(x) (((x) & 0x1f) << 0)
+
+#endif /* _AU1000_PSC_H_ */
diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
new file mode 100644
index 00000000..d5df0cab
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_mcheck 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 1
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_vint 0
+#define cpu_has_veic 0
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
new file mode 100644
index 00000000..1f41a522
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
@@ -0,0 +1,689 @@
+/*
+ * GPIO functions for Au1000, Au1500, Au1100, Au1550, Au1200
+ *
+ * Copyright (c) 2009 Manuel Lauss.
+ *
+ * Licensed under the terms outlined in the file COPYING.
+ */
+
+#ifndef _ALCHEMY_GPIO_AU1000_H_
+#define _ALCHEMY_GPIO_AU1000_H_
+
+#include <asm/mach-au1x00/au1000.h>
+
+/* The default GPIO numberspace as documented in the Alchemy manuals.
+ * GPIO0-31 from GPIO1 block, GPIO200-215 from GPIO2 block.
+ */
+#define ALCHEMY_GPIO1_BASE 0
+#define ALCHEMY_GPIO2_BASE 200
+
+#define ALCHEMY_GPIO1_NUM 32
+#define ALCHEMY_GPIO2_NUM 16
+#define ALCHEMY_GPIO1_MAX (ALCHEMY_GPIO1_BASE + ALCHEMY_GPIO1_NUM - 1)
+#define ALCHEMY_GPIO2_MAX (ALCHEMY_GPIO2_BASE + ALCHEMY_GPIO2_NUM - 1)
+
+#define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off))
+
+/* GPIO1 registers within SYS_ area */
+#define SYS_TRIOUTRD 0x100
+#define SYS_TRIOUTCLR 0x100
+#define SYS_OUTPUTRD 0x108
+#define SYS_OUTPUTSET 0x108
+#define SYS_OUTPUTCLR 0x10C
+#define SYS_PINSTATERD 0x110
+#define SYS_PININPUTEN 0x110
+
+/* register offsets within GPIO2 block */
+#define GPIO2_DIR 0x00
+#define GPIO2_OUTPUT 0x08
+#define GPIO2_PINSTATE 0x0C
+#define GPIO2_INTENABLE 0x10
+#define GPIO2_ENABLE 0x14
+
+struct gpio;
+
+static inline int au1000_gpio1_to_irq(int gpio)
+{
+ return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
+}
+
+static inline int au1000_gpio2_to_irq(int gpio)
+{
+ return -ENXIO;
+}
+
+static inline int au1000_irq_to_gpio(int irq)
+{
+ if ((irq >= AU1000_GPIO0_INT) && (irq <= AU1000_GPIO31_INT))
+ return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO0_INT) + 0;
+
+ return -ENXIO;
+}
+
+static inline int au1500_gpio1_to_irq(int gpio)
+{
+ gpio -= ALCHEMY_GPIO1_BASE;
+
+ switch (gpio) {
+ case 0 ... 15:
+ case 20:
+ case 23 ... 28: return MAKE_IRQ(1, gpio);
+ }
+
+ return -ENXIO;
+}
+
+static inline int au1500_gpio2_to_irq(int gpio)
+{
+ gpio -= ALCHEMY_GPIO2_BASE;
+
+ switch (gpio) {
+ case 0 ... 3: return MAKE_IRQ(1, 16 + gpio - 0);
+ case 4 ... 5: return MAKE_IRQ(1, 21 + gpio - 4);
+ case 6 ... 7: return MAKE_IRQ(1, 29 + gpio - 6);
+ }
+
+ return -ENXIO;
+}
+
+static inline int au1500_irq_to_gpio(int irq)
+{
+ switch (irq) {
+ case AU1500_GPIO0_INT ... AU1500_GPIO15_INT:
+ case AU1500_GPIO20_INT:
+ case AU1500_GPIO23_INT ... AU1500_GPIO28_INT:
+ return ALCHEMY_GPIO1_BASE + (irq - AU1500_GPIO0_INT) + 0;
+ case AU1500_GPIO200_INT ... AU1500_GPIO203_INT:
+ return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO200_INT) + 0;
+ case AU1500_GPIO204_INT ... AU1500_GPIO205_INT:
+ return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO204_INT) + 4;
+ case AU1500_GPIO206_INT ... AU1500_GPIO207_INT:
+ return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO206_INT) + 6;
+ case AU1500_GPIO208_215_INT:
+ return ALCHEMY_GPIO2_BASE + 8;
+ }
+
+ return -ENXIO;
+}
+
+static inline int au1100_gpio1_to_irq(int gpio)
+{
+ return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
+}
+
+static inline int au1100_gpio2_to_irq(int gpio)
+{
+ gpio -= ALCHEMY_GPIO2_BASE;
+
+ if ((gpio >= 8) && (gpio <= 15))
+ return MAKE_IRQ(0, 29); /* shared GPIO208_215 */
+
+ return -ENXIO;
+}
+
+static inline int au1100_irq_to_gpio(int irq)
+{
+ switch (irq) {
+ case AU1100_GPIO0_INT ... AU1100_GPIO31_INT:
+ return ALCHEMY_GPIO1_BASE + (irq - AU1100_GPIO0_INT) + 0;
+ case AU1100_GPIO208_215_INT:
+ return ALCHEMY_GPIO2_BASE + 8;
+ }
+
+ return -ENXIO;
+}
+
+static inline int au1550_gpio1_to_irq(int gpio)
+{
+ gpio -= ALCHEMY_GPIO1_BASE;
+
+ switch (gpio) {
+ case 0 ... 15:
+ case 20 ... 28: return MAKE_IRQ(1, gpio);
+ case 16 ... 17: return MAKE_IRQ(1, 18 + gpio - 16);
+ }
+
+ return -ENXIO;
+}
+
+static inline int au1550_gpio2_to_irq(int gpio)
+{
+ gpio -= ALCHEMY_GPIO2_BASE;
+
+ switch (gpio) {
+ case 0: return MAKE_IRQ(1, 16);
+ case 1 ... 5: return MAKE_IRQ(1, 17); /* shared GPIO201_205 */
+ case 6 ... 7: return MAKE_IRQ(1, 29 + gpio - 6);
+ case 8 ... 15: return MAKE_IRQ(1, 31); /* shared GPIO208_215 */
+ }
+
+ return -ENXIO;
+}
+
+static inline int au1550_irq_to_gpio(int irq)
+{
+ switch (irq) {
+ case AU1550_GPIO0_INT ... AU1550_GPIO15_INT:
+ return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO0_INT) + 0;
+ case AU1550_GPIO200_INT:
+ case AU1550_GPIO201_205_INT:
+ return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO200_INT) + 0;
+ case AU1550_GPIO16_INT ... AU1550_GPIO28_INT:
+ return ALCHEMY_GPIO1_BASE + (irq - AU1550_GPIO16_INT) + 16;
+ case AU1550_GPIO206_INT ... AU1550_GPIO208_215_INT:
+ return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO206_INT) + 6;
+ }
+
+ return -ENXIO;
+}
+
+static inline int au1200_gpio1_to_irq(int gpio)
+{
+ return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
+}
+
+static inline int au1200_gpio2_to_irq(int gpio)
+{
+ gpio -= ALCHEMY_GPIO2_BASE;
+
+ switch (gpio) {
+ case 0 ... 2: return MAKE_IRQ(0, 5 + gpio - 0);
+ case 3: return MAKE_IRQ(0, 22);
+ case 4 ... 7: return MAKE_IRQ(0, 24 + gpio - 4);
+ case 8 ... 15: return MAKE_IRQ(0, 28); /* shared GPIO208_215 */
+ }
+
+ return -ENXIO;
+}
+
+static inline int au1200_irq_to_gpio(int irq)
+{
+ switch (irq) {
+ case AU1200_GPIO0_INT ... AU1200_GPIO31_INT:
+ return ALCHEMY_GPIO1_BASE + (irq - AU1200_GPIO0_INT) + 0;
+ case AU1200_GPIO200_INT ... AU1200_GPIO202_INT:
+ return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO200_INT) + 0;
+ case AU1200_GPIO203_INT:
+ return ALCHEMY_GPIO2_BASE + 3;
+ case AU1200_GPIO204_INT ... AU1200_GPIO208_215_INT:
+ return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO204_INT) + 4;
+ }
+
+ return -ENXIO;
+}
+
+/*
+ * GPIO1 block macros for common linux gpio functions.
+ */
+static inline void alchemy_gpio1_set_value(int gpio, int v)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
+ unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
+ unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR;
+ __raw_writel(mask, base + r);
+ wmb();
+}
+
+static inline int alchemy_gpio1_get_value(int gpio)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
+ unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
+ return __raw_readl(base + SYS_PINSTATERD) & mask;
+}
+
+static inline int alchemy_gpio1_direction_input(int gpio)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
+ unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
+ __raw_writel(mask, base + SYS_TRIOUTCLR);
+ wmb();
+ return 0;
+}
+
+static inline int alchemy_gpio1_direction_output(int gpio, int v)
+{
+ /* hardware switches to "output" mode when one of the two
+ * "set_value" registers is accessed.
+ */
+ alchemy_gpio1_set_value(gpio, v);
+ return 0;
+}
+
+static inline int alchemy_gpio1_is_valid(int gpio)
+{
+ return ((gpio >= ALCHEMY_GPIO1_BASE) && (gpio <= ALCHEMY_GPIO1_MAX));
+}
+
+static inline int alchemy_gpio1_to_irq(int gpio)
+{
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1000:
+ return au1000_gpio1_to_irq(gpio);
+ case ALCHEMY_CPU_AU1100:
+ return au1100_gpio1_to_irq(gpio);
+ case ALCHEMY_CPU_AU1500:
+ return au1500_gpio1_to_irq(gpio);
+ case ALCHEMY_CPU_AU1550:
+ return au1550_gpio1_to_irq(gpio);
+ case ALCHEMY_CPU_AU1200:
+ return au1200_gpio1_to_irq(gpio);
+ }
+ return -ENXIO;
+}
+
+/*
+ * GPIO2 block macros for common linux GPIO functions. The 'gpio'
+ * parameter must be in range of ALCHEMY_GPIO2_BASE..ALCHEMY_GPIO2_MAX.
+ */
+static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+ unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE);
+ unsigned long d = __raw_readl(base + GPIO2_DIR);
+
+ if (to_out)
+ d |= mask;
+ else
+ d &= ~mask;
+ __raw_writel(d, base + GPIO2_DIR);
+ wmb();
+}
+
+static inline void alchemy_gpio2_set_value(int gpio, int v)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+ unsigned long mask;
+ mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE);
+ __raw_writel(mask, base + GPIO2_OUTPUT);
+ wmb();
+}
+
+static inline int alchemy_gpio2_get_value(int gpio)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+ return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
+}
+
+static inline int alchemy_gpio2_direction_input(int gpio)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ __alchemy_gpio2_mod_dir(gpio, 0);
+ local_irq_restore(flags);
+ return 0;
+}
+
+static inline int alchemy_gpio2_direction_output(int gpio, int v)
+{
+ unsigned long flags;
+ alchemy_gpio2_set_value(gpio, v);
+ local_irq_save(flags);
+ __alchemy_gpio2_mod_dir(gpio, 1);
+ local_irq_restore(flags);
+ return 0;
+}
+
+static inline int alchemy_gpio2_is_valid(int gpio)
+{
+ return ((gpio >= ALCHEMY_GPIO2_BASE) && (gpio <= ALCHEMY_GPIO2_MAX));
+}
+
+static inline int alchemy_gpio2_to_irq(int gpio)
+{
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1000:
+ return au1000_gpio2_to_irq(gpio);
+ case ALCHEMY_CPU_AU1100:
+ return au1100_gpio2_to_irq(gpio);
+ case ALCHEMY_CPU_AU1500:
+ return au1500_gpio2_to_irq(gpio);
+ case ALCHEMY_CPU_AU1550:
+ return au1550_gpio2_to_irq(gpio);
+ case ALCHEMY_CPU_AU1200:
+ return au1200_gpio2_to_irq(gpio);
+ }
+ return -ENXIO;
+}
+
+/**********************************************************************/
+
+/* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before
+ * SYS_PININPUTEN is written to at least once. On Au1550/Au1200 this
+ * register enables use of GPIOs as wake source.
+ */
+static inline void alchemy_gpio1_input_enable(void)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
+ __raw_writel(0, base + SYS_PININPUTEN); /* the write op is key */
+ wmb();
+}
+
+/* GPIO2 shared interrupts and control */
+
+static inline void __alchemy_gpio2_mod_int(int gpio2, int en)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+ unsigned long r = __raw_readl(base + GPIO2_INTENABLE);
+ if (en)
+ r |= 1 << gpio2;
+ else
+ r &= ~(1 << gpio2);
+ __raw_writel(r, base + GPIO2_INTENABLE);
+ wmb();
+}
+
+/**
+ * alchemy_gpio2_enable_int - Enable a GPIO2 pins' shared irq contribution.
+ * @gpio2: The GPIO2 pin to activate (200...215).
+ *
+ * GPIO208-215 have one shared interrupt line to the INTC. They are
+ * and'ed with a per-pin enable bit and finally or'ed together to form
+ * a single irq request (useful for active-high sources).
+ * With this function, a pins' individual contribution to the int request
+ * can be enabled. As with all other GPIO-based interrupts, the INTC
+ * must be programmed to accept the GPIO208_215 interrupt as well.
+ *
+ * NOTE: Calling this macro is only necessary for GPIO208-215; all other
+ * GPIO2-based interrupts have their own request to the INTC. Please
+ * consult your Alchemy databook for more information!
+ *
+ * NOTE: On the Au1550, GPIOs 201-205 also have a shared interrupt request
+ * line to the INTC, GPIO201_205. This function can be used for those
+ * as well.
+ *
+ * NOTE: 'gpio2' parameter must be in range of the GPIO2 numberspace
+ * (200-215 by default). No sanity checks are made,
+ */
+static inline void alchemy_gpio2_enable_int(int gpio2)
+{
+ unsigned long flags;
+
+ gpio2 -= ALCHEMY_GPIO2_BASE;
+
+ /* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1100:
+ case ALCHEMY_CPU_AU1500:
+ gpio2 -= 8;
+ }
+
+ local_irq_save(flags);
+ __alchemy_gpio2_mod_int(gpio2, 1);
+ local_irq_restore(flags);
+}
+
+/**
+ * alchemy_gpio2_disable_int - Disable a GPIO2 pins' shared irq contribution.
+ * @gpio2: The GPIO2 pin to activate (200...215).
+ *
+ * see function alchemy_gpio2_enable_int() for more information.
+ */
+static inline void alchemy_gpio2_disable_int(int gpio2)
+{
+ unsigned long flags;
+
+ gpio2 -= ALCHEMY_GPIO2_BASE;
+
+ /* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1100:
+ case ALCHEMY_CPU_AU1500:
+ gpio2 -= 8;
+ }
+
+ local_irq_save(flags);
+ __alchemy_gpio2_mod_int(gpio2, 0);
+ local_irq_restore(flags);
+}
+
+/**
+ * alchemy_gpio2_enable - Activate GPIO2 block.
+ *
+ * The GPIO2 block must be enabled excplicitly to work. On systems
+ * where this isn't done by the bootloader, this macro can be used.
+ */
+static inline void alchemy_gpio2_enable(void)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+ __raw_writel(3, base + GPIO2_ENABLE); /* reset, clock enabled */
+ wmb();
+ __raw_writel(1, base + GPIO2_ENABLE); /* clock enabled */
+ wmb();
+}
+
+/**
+ * alchemy_gpio2_disable - disable GPIO2 block.
+ *
+ * Disable and put GPIO2 block in low-power mode.
+ */
+static inline void alchemy_gpio2_disable(void)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+ __raw_writel(2, base + GPIO2_ENABLE); /* reset, clock disabled */
+ wmb();
+}
+
+/**********************************************************************/
+
+/* wrappers for on-chip gpios; can be used before gpio chips have been
+ * registered with gpiolib.
+ */
+static inline int alchemy_gpio_direction_input(int gpio)
+{
+ return (gpio >= ALCHEMY_GPIO2_BASE) ?
+ alchemy_gpio2_direction_input(gpio) :
+ alchemy_gpio1_direction_input(gpio);
+}
+
+static inline int alchemy_gpio_direction_output(int gpio, int v)
+{
+ return (gpio >= ALCHEMY_GPIO2_BASE) ?
+ alchemy_gpio2_direction_output(gpio, v) :
+ alchemy_gpio1_direction_output(gpio, v);
+}
+
+static inline int alchemy_gpio_get_value(int gpio)
+{
+ return (gpio >= ALCHEMY_GPIO2_BASE) ?
+ alchemy_gpio2_get_value(gpio) :
+ alchemy_gpio1_get_value(gpio);
+}
+
+static inline void alchemy_gpio_set_value(int gpio, int v)
+{
+ if (gpio >= ALCHEMY_GPIO2_BASE)
+ alchemy_gpio2_set_value(gpio, v);
+ else
+ alchemy_gpio1_set_value(gpio, v);
+}
+
+static inline int alchemy_gpio_is_valid(int gpio)
+{
+ return (gpio >= ALCHEMY_GPIO2_BASE) ?
+ alchemy_gpio2_is_valid(gpio) :
+ alchemy_gpio1_is_valid(gpio);
+}
+
+static inline int alchemy_gpio_cansleep(int gpio)
+{
+ return 0; /* Alchemy never gets tired */
+}
+
+static inline int alchemy_gpio_to_irq(int gpio)
+{
+ return (gpio >= ALCHEMY_GPIO2_BASE) ?
+ alchemy_gpio2_to_irq(gpio) :
+ alchemy_gpio1_to_irq(gpio);
+}
+
+static inline int alchemy_irq_to_gpio(int irq)
+{
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1000:
+ return au1000_irq_to_gpio(irq);
+ case ALCHEMY_CPU_AU1100:
+ return au1100_irq_to_gpio(irq);
+ case ALCHEMY_CPU_AU1500:
+ return au1500_irq_to_gpio(irq);
+ case ALCHEMY_CPU_AU1550:
+ return au1550_irq_to_gpio(irq);
+ case ALCHEMY_CPU_AU1200:
+ return au1200_irq_to_gpio(irq);
+ }
+ return -ENXIO;
+}
+
+/**********************************************************************/
+
+/* Linux gpio framework integration.
+ *
+ * 4 use cases of Au1000-Au1200 GPIOS:
+ *(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y:
+ * Board must register gpiochips.
+ *(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n:
+ * 2 (1 for Au1000) gpio_chips are registered.
+ *
+ *(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y:
+ * the boards' gpio.h must provide the linux gpio wrapper functions,
+ *
+ *(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n:
+ * inlinable gpio functions are provided which enable access to the
+ * Au1000 gpios only by using the numbers straight out of the data-
+ * sheets.
+
+ * Cases 1 and 3 are intended for boards which want to provide their own
+ * GPIO namespace and -operations (i.e. for example you have 8 GPIOs
+ * which are in part provided by spare Au1000 GPIO pins and in part by
+ * an external FPGA but you still want them to be accssible in linux
+ * as gpio0-7. The board can of course use the alchemy_gpioX_* functions
+ * as required).
+ */
+
+#ifndef CONFIG_GPIOLIB
+
+
+#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */
+
+static inline int gpio_direction_input(int gpio)
+{
+ return alchemy_gpio_direction_input(gpio);
+}
+
+static inline int gpio_direction_output(int gpio, int v)
+{
+ return alchemy_gpio_direction_output(gpio, v);
+}
+
+static inline int gpio_get_value(int gpio)
+{
+ return alchemy_gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(int gpio, int v)
+{
+ alchemy_gpio_set_value(gpio, v);
+}
+
+static inline int gpio_get_value_cansleep(unsigned gpio)
+{
+ return gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value_cansleep(unsigned gpio, int value)
+{
+ gpio_set_value(gpio, value);
+}
+
+static inline int gpio_is_valid(int gpio)
+{
+ return alchemy_gpio_is_valid(gpio);
+}
+
+static inline int gpio_cansleep(int gpio)
+{
+ return alchemy_gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(int gpio)
+{
+ return alchemy_gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(int irq)
+{
+ return alchemy_irq_to_gpio(irq);
+}
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+ return 0;
+}
+
+static inline int gpio_request_one(unsigned gpio,
+ unsigned long flags, const char *label)
+{
+ return 0;
+}
+
+static inline int gpio_request_array(struct gpio *array, size_t num)
+{
+ return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+}
+
+static inline void gpio_free_array(struct gpio *array, size_t num)
+{
+}
+
+static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
+{
+ return -ENOSYS;
+}
+
+static inline int gpio_export(unsigned gpio, bool direction_may_change)
+{
+ return -ENOSYS;
+}
+
+static inline int gpio_export_link(struct device *dev, const char *name,
+ unsigned gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
+{
+ return -ENOSYS;
+}
+
+static inline void gpio_unexport(unsigned gpio)
+{
+}
+
+#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
+
+
+#else /* CONFIG GPIOLIB */
+
+
+ /* using gpiolib to provide up to 2 gpio_chips for on-chip gpios */
+#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (2) */
+
+/* get everything through gpiolib */
+#define gpio_to_irq __gpio_to_irq
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define irq_to_gpio alchemy_irq_to_gpio
+
+#include <asm-generic/gpio.h>
+
+#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
+
+
+#endif /* !CONFIG_GPIOLIB */
+
+#endif /* _ALCHEMY_GPIO_AU1000_H_ */
diff --git a/arch/mips/include/asm/mach-au1x00/gpio.h b/arch/mips/include/asm/mach-au1x00/gpio.h
new file mode 100644
index 00000000..c3f60cdc
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/gpio.h
@@ -0,0 +1,10 @@
+#ifndef _ALCHEMY_GPIO_H_
+#define _ALCHEMY_GPIO_H_
+
+#if defined(CONFIG_ALCHEMY_GPIOINT_AU1000)
+
+#include <asm/mach-au1x00/gpio-au1000.h>
+
+#endif
+
+#endif /* _ALCHEMY_GPIO_H_ */
diff --git a/arch/mips/include/asm/mach-au1x00/ioremap.h b/arch/mips/include/asm/mach-au1x00/ioremap.h
new file mode 100644
index 00000000..75a94ad3
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/ioremap.h
@@ -0,0 +1,42 @@
+/*
+ * include/asm-mips/mach-au1x00/ioremap.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_AU1X00_IOREMAP_H
+#define __ASM_MACH_AU1X00_IOREMAP_H
+
+#include <linux/types.h>
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI)
+extern phys_t __fixup_bigphys_addr(phys_t, phys_t);
+#else
+static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+#endif
+
+/*
+ * Allow physical addresses to be fixed up to help 36-bit peripherals.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return __fixup_bigphys_addr(phys_addr, size);
+}
+
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+ unsigned long flags)
+{
+ return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+ return 0;
+}
+
+#endif /* __ASM_MACH_AU1X00_IOREMAP_H */
diff --git a/arch/mips/include/asm/mach-au1x00/prom.h b/arch/mips/include/asm/mach-au1x00/prom.h
new file mode 100644
index 00000000..4c0e09cf
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/prom.h
@@ -0,0 +1,12 @@
+#ifndef __AU1X00_PROM_H
+#define __AU1X00_PROM_H
+
+extern int prom_argc;
+extern char **prom_argv;
+extern char **prom_envp;
+
+extern void prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+extern int prom_get_ethernet_addr(char *ethernet_addr);
+
+#endif
diff --git a/arch/mips/include/asm/mach-au1x00/war.h b/arch/mips/include/asm/mach-au1x00/war.h
new file mode 100644
index 00000000..dd57d03d
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_AU1X00_WAR_H
+#define __ASM_MIPS_MACH_AU1X00_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_AU1X00_WAR_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
new file mode 100644
index 00000000..d008f47a
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ASM_BCM47XX_H
+#define __ASM_BCM47XX_H
+
+/* SSB bus */
+extern struct ssb_bus ssb_bcm47xx;
+
+#endif /* __ASM_BCM47XX_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
new file mode 100644
index 00000000..98504142
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -0,0 +1,65 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
+ */
+
+#ifndef __BCM47XX_GPIO_H
+#define __BCM47XX_GPIO_H
+
+#include <linux/ssb/ssb_embedded.h>
+#include <asm/mach-bcm47xx/bcm47xx.h>
+
+#define BCM47XX_EXTIF_GPIO_LINES 5
+#define BCM47XX_CHIPCO_GPIO_LINES 16
+
+extern int gpio_request(unsigned gpio, const char *label);
+extern void gpio_free(unsigned gpio);
+extern int gpio_to_irq(unsigned gpio);
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+ ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
+ return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+ /* first set the gpio out value */
+ ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
+ /* then set the gpio mode */
+ ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
+ return 0;
+}
+
+static inline int gpio_intmask(unsigned gpio, int value)
+{
+ ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
+ value ? 1 << gpio : 0);
+ return 0;
+}
+
+static inline int gpio_polarity(unsigned gpio, int value)
+{
+ ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
+ value ? 1 << gpio : 0);
+ return 0;
+}
+
+
+/* cansleep wrappers */
+#include <asm-generic/gpio.h>
+
+#endif /* __BCM47XX_GPIO_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h
new file mode 100644
index 00000000..184d5ecb
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005, Broadcom Corporation
+ * Copyright (C) 2006, Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __NVRAM_H
+#define __NVRAM_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+struct nvram_header {
+ u32 magic;
+ u32 len;
+ u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
+ u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
+ u32 config_ncdl; /* ncdl values for memc */
+};
+
+#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
+#define NVRAM_VERSION 1
+#define NVRAM_HEADER_SIZE 20
+#define NVRAM_SPACE 0x8000
+
+#define FLASH_MIN 0x00020000 /* Minimum flash size */
+
+#define NVRAM_MAX_VALUE_LEN 255
+#define NVRAM_MAX_PARAM_LEN 64
+
+#define NVRAM_ERR_INV_PARAM -8
+#define NVRAM_ERR_ENVNOTFOUND -9
+
+extern int nvram_getenv(char *name, char *val, size_t val_len);
+
+static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
+{
+ if (strchr(buf, ':'))
+ sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
+ &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
+ &macaddr[5]);
+ else if (strchr(buf, '-'))
+ sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
+ &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
+ &macaddr[5]);
+ else
+ printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
+}
+
+#endif
diff --git a/arch/mips/include/asm/mach-bcm47xx/war.h b/arch/mips/include/asm/mach-bcm47xx/war.h
new file mode 100644
index 00000000..87cd4651
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm47xx/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_BCM47XX_WAR_H
+#define __ASM_MIPS_MACH_BCM47XX_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_BCM47XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h
new file mode 100644
index 00000000..fa3e7e61
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h
@@ -0,0 +1,12 @@
+#ifndef BCM63XX_BOARD_H_
+#define BCM63XX_BOARD_H_
+
+const char *board_get_name(void);
+
+void board_prom_init(void);
+
+void board_setup(void);
+
+int board_register_devices(void);
+
+#endif /* ! BCM63XX_BOARD_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h
new file mode 100644
index 00000000..8fcf8df4
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h
@@ -0,0 +1,11 @@
+#ifndef BCM63XX_CLK_H_
+#define BCM63XX_CLK_H_
+
+struct clk {
+ void (*set)(struct clk *, int);
+ unsigned int rate;
+ unsigned int usage;
+ int id;
+};
+
+#endif /* ! BCM63XX_CLK_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
new file mode 100644
index 00000000..96a2391a
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -0,0 +1,553 @@
+#ifndef BCM63XX_CPU_H_
+#define BCM63XX_CPU_H_
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+/*
+ * Macro to fetch bcm63xx cpu id and revision, should be optimized at
+ * compile time if only one CPU support is enabled (idea stolen from
+ * arm mach-types)
+ */
+#define BCM6338_CPU_ID 0x6338
+#define BCM6345_CPU_ID 0x6345
+#define BCM6348_CPU_ID 0x6348
+#define BCM6358_CPU_ID 0x6358
+
+void __init bcm63xx_cpu_init(void);
+u16 __bcm63xx_get_cpu_id(void);
+u16 bcm63xx_get_cpu_rev(void);
+unsigned int bcm63xx_get_cpu_freq(void);
+
+#ifdef CONFIG_BCM63XX_CPU_6338
+# ifdef bcm63xx_get_cpu_id
+# undef bcm63xx_get_cpu_id
+# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+# define BCMCPU_RUNTIME_DETECT
+# else
+# define bcm63xx_get_cpu_id() BCM6338_CPU_ID
+# endif
+# define BCMCPU_IS_6338() (bcm63xx_get_cpu_id() == BCM6338_CPU_ID)
+#else
+# define BCMCPU_IS_6338() (0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6345
+# ifdef bcm63xx_get_cpu_id
+# undef bcm63xx_get_cpu_id
+# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+# define BCMCPU_RUNTIME_DETECT
+# else
+# define bcm63xx_get_cpu_id() BCM6345_CPU_ID
+# endif
+# define BCMCPU_IS_6345() (bcm63xx_get_cpu_id() == BCM6345_CPU_ID)
+#else
+# define BCMCPU_IS_6345() (0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6348
+# ifdef bcm63xx_get_cpu_id
+# undef bcm63xx_get_cpu_id
+# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+# define BCMCPU_RUNTIME_DETECT
+# else
+# define bcm63xx_get_cpu_id() BCM6348_CPU_ID
+# endif
+# define BCMCPU_IS_6348() (bcm63xx_get_cpu_id() == BCM6348_CPU_ID)
+#else
+# define BCMCPU_IS_6348() (0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6358
+# ifdef bcm63xx_get_cpu_id
+# undef bcm63xx_get_cpu_id
+# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+# define BCMCPU_RUNTIME_DETECT
+# else
+# define bcm63xx_get_cpu_id() BCM6358_CPU_ID
+# endif
+# define BCMCPU_IS_6358() (bcm63xx_get_cpu_id() == BCM6358_CPU_ID)
+#else
+# define BCMCPU_IS_6358() (0)
+#endif
+
+#ifndef bcm63xx_get_cpu_id
+#error "No CPU support configured"
+#endif
+
+/*
+ * While registers sets are (mostly) the same across 63xx CPU, base
+ * address of these sets do change.
+ */
+enum bcm63xx_regs_set {
+ RSET_DSL_LMEM = 0,
+ RSET_PERF,
+ RSET_TIMER,
+ RSET_WDT,
+ RSET_UART0,
+ RSET_UART1,
+ RSET_GPIO,
+ RSET_SPI,
+ RSET_UDC0,
+ RSET_OHCI0,
+ RSET_OHCI_PRIV,
+ RSET_USBH_PRIV,
+ RSET_MPI,
+ RSET_PCMCIA,
+ RSET_DSL,
+ RSET_ENET0,
+ RSET_ENET1,
+ RSET_ENETDMA,
+ RSET_EHCI0,
+ RSET_SDRAM,
+ RSET_MEMC,
+ RSET_DDR,
+};
+
+#define RSET_DSL_LMEM_SIZE (64 * 1024 * 4)
+#define RSET_DSL_SIZE 4096
+#define RSET_WDT_SIZE 12
+#define RSET_ENET_SIZE 2048
+#define RSET_ENETDMA_SIZE 2048
+#define RSET_UART_SIZE 24
+#define RSET_UDC_SIZE 256
+#define RSET_OHCI_SIZE 256
+#define RSET_EHCI_SIZE 256
+#define RSET_PCMCIA_SIZE 12
+
+/*
+ * 6338 register sets base address
+ */
+#define BCM_6338_DSL_LMEM_BASE (0xfff00000)
+#define BCM_6338_PERF_BASE (0xfffe0000)
+#define BCM_6338_BB_BASE (0xfffe0100)
+#define BCM_6338_TIMER_BASE (0xfffe0200)
+#define BCM_6338_WDT_BASE (0xfffe021c)
+#define BCM_6338_UART0_BASE (0xfffe0300)
+#define BCM_6338_UART1_BASE (0xdeadbeef)
+#define BCM_6338_GPIO_BASE (0xfffe0400)
+#define BCM_6338_SPI_BASE (0xfffe0c00)
+#define BCM_6338_UDC0_BASE (0xdeadbeef)
+#define BCM_6338_USBDMA_BASE (0xfffe2400)
+#define BCM_6338_OHCI0_BASE (0xdeadbeef)
+#define BCM_6338_OHCI_PRIV_BASE (0xfffe3000)
+#define BCM_6338_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6338_MPI_BASE (0xfffe3160)
+#define BCM_6338_PCMCIA_BASE (0xdeadbeef)
+#define BCM_6338_SDRAM_REGS_BASE (0xfffe3100)
+#define BCM_6338_DSL_BASE (0xfffe1000)
+#define BCM_6338_SAR_BASE (0xfffe2000)
+#define BCM_6338_UBUS_BASE (0xdeadbeef)
+#define BCM_6338_ENET0_BASE (0xfffe2800)
+#define BCM_6338_ENET1_BASE (0xdeadbeef)
+#define BCM_6338_ENETDMA_BASE (0xfffe2400)
+#define BCM_6338_EHCI0_BASE (0xdeadbeef)
+#define BCM_6338_SDRAM_BASE (0xfffe3100)
+#define BCM_6338_MEMC_BASE (0xdeadbeef)
+#define BCM_6338_DDR_BASE (0xdeadbeef)
+
+/*
+ * 6345 register sets base address
+ */
+#define BCM_6345_DSL_LMEM_BASE (0xfff00000)
+#define BCM_6345_PERF_BASE (0xfffe0000)
+#define BCM_6345_BB_BASE (0xfffe0100)
+#define BCM_6345_TIMER_BASE (0xfffe0200)
+#define BCM_6345_WDT_BASE (0xfffe021c)
+#define BCM_6345_UART0_BASE (0xfffe0300)
+#define BCM_6345_UART1_BASE (0xdeadbeef)
+#define BCM_6345_GPIO_BASE (0xfffe0400)
+#define BCM_6345_SPI_BASE (0xdeadbeef)
+#define BCM_6345_UDC0_BASE (0xdeadbeef)
+#define BCM_6345_USBDMA_BASE (0xfffe2800)
+#define BCM_6345_ENET0_BASE (0xfffe1800)
+#define BCM_6345_ENETDMA_BASE (0xfffe2800)
+#define BCM_6345_PCMCIA_BASE (0xfffe2028)
+#define BCM_6345_MPI_BASE (0xdeadbeef)
+#define BCM_6345_OHCI0_BASE (0xfffe2100)
+#define BCM_6345_OHCI_PRIV_BASE (0xfffe2200)
+#define BCM_6345_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6345_SDRAM_REGS_BASE (0xfffe2300)
+#define BCM_6345_DSL_BASE (0xdeadbeef)
+#define BCM_6345_SAR_BASE (0xdeadbeef)
+#define BCM_6345_UBUS_BASE (0xdeadbeef)
+#define BCM_6345_ENET1_BASE (0xdeadbeef)
+#define BCM_6345_EHCI0_BASE (0xdeadbeef)
+#define BCM_6345_SDRAM_BASE (0xfffe2300)
+#define BCM_6345_MEMC_BASE (0xdeadbeef)
+#define BCM_6345_DDR_BASE (0xdeadbeef)
+
+/*
+ * 6348 register sets base address
+ */
+#define BCM_6348_DSL_LMEM_BASE (0xfff00000)
+#define BCM_6348_PERF_BASE (0xfffe0000)
+#define BCM_6348_TIMER_BASE (0xfffe0200)
+#define BCM_6348_WDT_BASE (0xfffe021c)
+#define BCM_6348_UART0_BASE (0xfffe0300)
+#define BCM_6348_UART1_BASE (0xdeadbeef)
+#define BCM_6348_GPIO_BASE (0xfffe0400)
+#define BCM_6348_SPI_BASE (0xfffe0c00)
+#define BCM_6348_UDC0_BASE (0xfffe1000)
+#define BCM_6348_OHCI0_BASE (0xfffe1b00)
+#define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00)
+#define BCM_6348_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6348_MPI_BASE (0xfffe2000)
+#define BCM_6348_PCMCIA_BASE (0xfffe2054)
+#define BCM_6348_SDRAM_REGS_BASE (0xfffe2300)
+#define BCM_6348_DSL_BASE (0xfffe3000)
+#define BCM_6348_ENET0_BASE (0xfffe6000)
+#define BCM_6348_ENET1_BASE (0xfffe6800)
+#define BCM_6348_ENETDMA_BASE (0xfffe7000)
+#define BCM_6348_EHCI0_BASE (0xdeadbeef)
+#define BCM_6348_SDRAM_BASE (0xfffe2300)
+#define BCM_6348_MEMC_BASE (0xdeadbeef)
+#define BCM_6348_DDR_BASE (0xdeadbeef)
+
+/*
+ * 6358 register sets base address
+ */
+#define BCM_6358_DSL_LMEM_BASE (0xfff00000)
+#define BCM_6358_PERF_BASE (0xfffe0000)
+#define BCM_6358_TIMER_BASE (0xfffe0040)
+#define BCM_6358_WDT_BASE (0xfffe005c)
+#define BCM_6358_UART0_BASE (0xfffe0100)
+#define BCM_6358_UART1_BASE (0xfffe0120)
+#define BCM_6358_GPIO_BASE (0xfffe0080)
+#define BCM_6358_SPI_BASE (0xdeadbeef)
+#define BCM_6358_UDC0_BASE (0xfffe0800)
+#define BCM_6358_OHCI0_BASE (0xfffe1400)
+#define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef)
+#define BCM_6358_USBH_PRIV_BASE (0xfffe1500)
+#define BCM_6358_MPI_BASE (0xfffe1000)
+#define BCM_6358_PCMCIA_BASE (0xfffe1054)
+#define BCM_6358_SDRAM_REGS_BASE (0xfffe2300)
+#define BCM_6358_DSL_BASE (0xfffe3000)
+#define BCM_6358_ENET0_BASE (0xfffe4000)
+#define BCM_6358_ENET1_BASE (0xfffe4800)
+#define BCM_6358_ENETDMA_BASE (0xfffe5000)
+#define BCM_6358_EHCI0_BASE (0xfffe1300)
+#define BCM_6358_SDRAM_BASE (0xdeadbeef)
+#define BCM_6358_MEMC_BASE (0xfffe1200)
+#define BCM_6358_DDR_BASE (0xfffe12a0)
+
+
+extern const unsigned long *bcm63xx_regs_base;
+
+static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
+{
+#ifdef BCMCPU_RUNTIME_DETECT
+ return bcm63xx_regs_base[set];
+#else
+#ifdef CONFIG_BCM63XX_CPU_6338
+ switch (set) {
+ case RSET_DSL_LMEM:
+ return BCM_6338_DSL_LMEM_BASE;
+ case RSET_PERF:
+ return BCM_6338_PERF_BASE;
+ case RSET_TIMER:
+ return BCM_6338_TIMER_BASE;
+ case RSET_WDT:
+ return BCM_6338_WDT_BASE;
+ case RSET_UART0:
+ return BCM_6338_UART0_BASE;
+ case RSET_UART1:
+ return BCM_6338_UART1_BASE;
+ case RSET_GPIO:
+ return BCM_6338_GPIO_BASE;
+ case RSET_SPI:
+ return BCM_6338_SPI_BASE;
+ case RSET_UDC0:
+ return BCM_6338_UDC0_BASE;
+ case RSET_OHCI0:
+ return BCM_6338_OHCI0_BASE;
+ case RSET_OHCI_PRIV:
+ return BCM_6338_OHCI_PRIV_BASE;
+ case RSET_USBH_PRIV:
+ return BCM_6338_USBH_PRIV_BASE;
+ case RSET_MPI:
+ return BCM_6338_MPI_BASE;
+ case RSET_PCMCIA:
+ return BCM_6338_PCMCIA_BASE;
+ case RSET_DSL:
+ return BCM_6338_DSL_BASE;
+ case RSET_ENET0:
+ return BCM_6338_ENET0_BASE;
+ case RSET_ENET1:
+ return BCM_6338_ENET1_BASE;
+ case RSET_ENETDMA:
+ return BCM_6338_ENETDMA_BASE;
+ case RSET_EHCI0:
+ return BCM_6338_EHCI0_BASE;
+ case RSET_SDRAM:
+ return BCM_6338_SDRAM_BASE;
+ case RSET_MEMC:
+ return BCM_6338_MEMC_BASE;
+ case RSET_DDR:
+ return BCM_6338_DDR_BASE;
+ }
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6345
+ switch (set) {
+ case RSET_DSL_LMEM:
+ return BCM_6345_DSL_LMEM_BASE;
+ case RSET_PERF:
+ return BCM_6345_PERF_BASE;
+ case RSET_TIMER:
+ return BCM_6345_TIMER_BASE;
+ case RSET_WDT:
+ return BCM_6345_WDT_BASE;
+ case RSET_UART0:
+ return BCM_6345_UART0_BASE;
+ case RSET_UART1:
+ return BCM_6345_UART1_BASE;
+ case RSET_GPIO:
+ return BCM_6345_GPIO_BASE;
+ case RSET_SPI:
+ return BCM_6345_SPI_BASE;
+ case RSET_UDC0:
+ return BCM_6345_UDC0_BASE;
+ case RSET_OHCI0:
+ return BCM_6345_OHCI0_BASE;
+ case RSET_OHCI_PRIV:
+ return BCM_6345_OHCI_PRIV_BASE;
+ case RSET_USBH_PRIV:
+ return BCM_6345_USBH_PRIV_BASE;
+ case RSET_MPI:
+ return BCM_6345_MPI_BASE;
+ case RSET_PCMCIA:
+ return BCM_6345_PCMCIA_BASE;
+ case RSET_DSL:
+ return BCM_6345_DSL_BASE;
+ case RSET_ENET0:
+ return BCM_6345_ENET0_BASE;
+ case RSET_ENET1:
+ return BCM_6345_ENET1_BASE;
+ case RSET_ENETDMA:
+ return BCM_6345_ENETDMA_BASE;
+ case RSET_EHCI0:
+ return BCM_6345_EHCI0_BASE;
+ case RSET_SDRAM:
+ return BCM_6345_SDRAM_BASE;
+ case RSET_MEMC:
+ return BCM_6345_MEMC_BASE;
+ case RSET_DDR:
+ return BCM_6345_DDR_BASE;
+ }
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+ switch (set) {
+ case RSET_DSL_LMEM:
+ return BCM_6348_DSL_LMEM_BASE;
+ case RSET_PERF:
+ return BCM_6348_PERF_BASE;
+ case RSET_TIMER:
+ return BCM_6348_TIMER_BASE;
+ case RSET_WDT:
+ return BCM_6348_WDT_BASE;
+ case RSET_UART0:
+ return BCM_6348_UART0_BASE;
+ case RSET_UART1:
+ return BCM_6348_UART1_BASE;
+ case RSET_GPIO:
+ return BCM_6348_GPIO_BASE;
+ case RSET_SPI:
+ return BCM_6348_SPI_BASE;
+ case RSET_UDC0:
+ return BCM_6348_UDC0_BASE;
+ case RSET_OHCI0:
+ return BCM_6348_OHCI0_BASE;
+ case RSET_OHCI_PRIV:
+ return BCM_6348_OHCI_PRIV_BASE;
+ case RSET_USBH_PRIV:
+ return BCM_6348_USBH_PRIV_BASE;
+ case RSET_MPI:
+ return BCM_6348_MPI_BASE;
+ case RSET_PCMCIA:
+ return BCM_6348_PCMCIA_BASE;
+ case RSET_DSL:
+ return BCM_6348_DSL_BASE;
+ case RSET_ENET0:
+ return BCM_6348_ENET0_BASE;
+ case RSET_ENET1:
+ return BCM_6348_ENET1_BASE;
+ case RSET_ENETDMA:
+ return BCM_6348_ENETDMA_BASE;
+ case RSET_EHCI0:
+ return BCM_6348_EHCI0_BASE;
+ case RSET_SDRAM:
+ return BCM_6348_SDRAM_BASE;
+ case RSET_MEMC:
+ return BCM_6348_MEMC_BASE;
+ case RSET_DDR:
+ return BCM_6348_DDR_BASE;
+ }
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6358
+ switch (set) {
+ case RSET_DSL_LMEM:
+ return BCM_6358_DSL_LMEM_BASE;
+ case RSET_PERF:
+ return BCM_6358_PERF_BASE;
+ case RSET_TIMER:
+ return BCM_6358_TIMER_BASE;
+ case RSET_WDT:
+ return BCM_6358_WDT_BASE;
+ case RSET_UART0:
+ return BCM_6358_UART0_BASE;
+ case RSET_UART1:
+ return BCM_6358_UART1_BASE;
+ case RSET_GPIO:
+ return BCM_6358_GPIO_BASE;
+ case RSET_SPI:
+ return BCM_6358_SPI_BASE;
+ case RSET_UDC0:
+ return BCM_6358_UDC0_BASE;
+ case RSET_OHCI0:
+ return BCM_6358_OHCI0_BASE;
+ case RSET_OHCI_PRIV:
+ return BCM_6358_OHCI_PRIV_BASE;
+ case RSET_USBH_PRIV:
+ return BCM_6358_USBH_PRIV_BASE;
+ case RSET_MPI:
+ return BCM_6358_MPI_BASE;
+ case RSET_PCMCIA:
+ return BCM_6358_PCMCIA_BASE;
+ case RSET_ENET0:
+ return BCM_6358_ENET0_BASE;
+ case RSET_ENET1:
+ return BCM_6358_ENET1_BASE;
+ case RSET_ENETDMA:
+ return BCM_6358_ENETDMA_BASE;
+ case RSET_DSL:
+ return BCM_6358_DSL_BASE;
+ case RSET_EHCI0:
+ return BCM_6358_EHCI0_BASE;
+ case RSET_SDRAM:
+ return BCM_6358_SDRAM_BASE;
+ case RSET_MEMC:
+ return BCM_6358_MEMC_BASE;
+ case RSET_DDR:
+ return BCM_6358_DDR_BASE;
+ }
+#endif
+#endif
+ /* unreached */
+ return 0;
+}
+
+/*
+ * IRQ number changes across CPU too
+ */
+enum bcm63xx_irq {
+ IRQ_TIMER = 0,
+ IRQ_UART0,
+ IRQ_UART1,
+ IRQ_DSL,
+ IRQ_ENET0,
+ IRQ_ENET1,
+ IRQ_ENET_PHY,
+ IRQ_OHCI0,
+ IRQ_EHCI0,
+ IRQ_PCMCIA0,
+ IRQ_ENET0_RXDMA,
+ IRQ_ENET0_TXDMA,
+ IRQ_ENET1_RXDMA,
+ IRQ_ENET1_TXDMA,
+ IRQ_PCI,
+ IRQ_PCMCIA,
+};
+
+/*
+ * 6338 irqs
+ */
+#define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6338_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
+#define BCM_6338_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6338_DG_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5)
+#define BCM_6338_ATM_IRQ (IRQ_INTERNAL_BASE + 6)
+#define BCM_6338_UDC0_IRQ (IRQ_INTERNAL_BASE + 7)
+#define BCM_6338_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6338_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6338_SDRAM_IRQ (IRQ_INTERNAL_BASE + 10)
+#define BCM_6338_USB_CNTL_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 11)
+#define BCM_6338_USB_CNTL_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6338_USB_BULK_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13)
+#define BCM_6338_USB_BULK_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 14)
+#define BCM_6338_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
+#define BCM_6338_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16)
+#define BCM_6338_SDIO_IRQ (IRQ_INTERNAL_BASE + 17)
+
+/*
+ * 6345 irqs
+ */
+#define BCM_6345_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3)
+#define BCM_6345_ATM_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6345_USB_IRQ (IRQ_INTERNAL_BASE + 5)
+#define BCM_6345_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6345_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6345_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 1)
+#define BCM_6345_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 2)
+#define BCM_6345_EBI_RX_IRQ (IRQ_INTERNAL_BASE + 13 + 5)
+#define BCM_6345_EBI_TX_IRQ (IRQ_INTERNAL_BASE + 13 + 6)
+#define BCM_6345_RESERVED_RX_IRQ (IRQ_INTERNAL_BASE + 13 + 9)
+#define BCM_6345_RESERVED_TX_IRQ (IRQ_INTERNAL_BASE + 13 + 10)
+#define BCM_6345_USB_BULK_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 13)
+#define BCM_6345_USB_BULK_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 14)
+#define BCM_6345_USB_CNTL_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 15)
+#define BCM_6345_USB_CNTL_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 16)
+#define BCM_6345_USB_ISO_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 17)
+#define BCM_6345_USB_ISO_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 18)
+
+/*
+ * 6348 irqs
+ */
+#define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7)
+#define BCM_6348_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20)
+#define BCM_6348_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 21)
+#define BCM_6348_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 22)
+#define BCM_6348_ENET1_TXDMA_IRQ (IRQ_INTERNAL_BASE + 23)
+#define BCM_6348_PCMCIA_IRQ (IRQ_INTERNAL_BASE + 24)
+#define BCM_6348_PCI_IRQ (IRQ_INTERNAL_BASE + 24)
+
+/*
+ * 6358 irqs
+ */
+#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
+#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
+#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
+#define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6358_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6358_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
+#define BCM_6358_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
+#define BCM_6358_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16)
+#define BCM_6358_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 17)
+#define BCM_6358_ENET1_TXDMA_IRQ (IRQ_INTERNAL_BASE + 18)
+#define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29)
+#define BCM_6358_PCI_IRQ (IRQ_INTERNAL_BASE + 31)
+#define BCM_6358_PCMCIA_IRQ (IRQ_INTERNAL_BASE + 24)
+
+extern const int *bcm63xx_irqs;
+
+static inline int bcm63xx_get_irq_number(enum bcm63xx_irq irq)
+{
+ return bcm63xx_irqs[irq];
+}
+
+/*
+ * return installed memory size
+ */
+unsigned int bcm63xx_get_memory_size(void);
+
+#endif /* !BCM63XX_CPU_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h
new file mode 100644
index 00000000..b1821c86
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h
@@ -0,0 +1,10 @@
+#ifndef BCM63XX_CS_H
+#define BCM63XX_CS_H
+
+int bcm63xx_set_cs_base(unsigned int cs, u32 base, unsigned int size);
+int bcm63xx_set_cs_timing(unsigned int cs, unsigned int wait,
+ unsigned int setup, unsigned int hold);
+int bcm63xx_set_cs_param(unsigned int cs, u32 flags);
+int bcm63xx_set_cs_status(unsigned int cs, int enable);
+
+#endif /* !BCM63XX_CS_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h
new file mode 100644
index 00000000..b587d45c
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h
@@ -0,0 +1,13 @@
+#ifndef __BCM63XX_DSP_H
+#define __BCM63XX_DSP_H
+
+struct bcm63xx_dsp_platform_data {
+ unsigned gpio_rst;
+ unsigned gpio_int;
+ unsigned cs;
+ unsigned ext_irq;
+};
+
+int __init bcm63xx_dsp_register(const struct bcm63xx_dsp_platform_data *pd);
+
+#endif /* __BCM63XX_DSP_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
new file mode 100644
index 00000000..d53f6111
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
@@ -0,0 +1,45 @@
+#ifndef BCM63XX_DEV_ENET_H_
+#define BCM63XX_DEV_ENET_H_
+
+#include <linux/if_ether.h>
+#include <linux/init.h>
+
+/*
+ * on board ethernet platform data
+ */
+struct bcm63xx_enet_platform_data {
+ char mac_addr[ETH_ALEN];
+
+ int has_phy;
+
+ /* if has_phy, then set use_internal_phy */
+ int use_internal_phy;
+
+ /* or fill phy info to use an external one */
+ int phy_id;
+ int has_phy_interrupt;
+ int phy_interrupt;
+
+ /* if has_phy, use autonegociated pause parameters or force
+ * them */
+ int pause_auto;
+ int pause_rx;
+ int pause_tx;
+
+ /* if !has_phy, set desired forced speed/duplex */
+ int force_speed_100;
+ int force_duplex_full;
+
+ /* if !has_phy, set callback to perform mii device
+ * init/remove */
+ int (*mii_config)(struct net_device *dev, int probe,
+ int (*mii_read)(struct net_device *dev,
+ int phy_id, int reg),
+ void (*mii_write)(struct net_device *dev,
+ int phy_id, int reg, int val));
+};
+
+int __init bcm63xx_enet_register(int unit,
+ const struct bcm63xx_enet_platform_data *pd);
+
+#endif /* ! BCM63XX_DEV_ENET_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h
new file mode 100644
index 00000000..c549344b
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_PCI_H_
+#define BCM63XX_DEV_PCI_H_
+
+extern int bcm63xx_pci_enabled;
+
+#endif /* BCM63XX_DEV_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h
new file mode 100644
index 00000000..2beb3969
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h
@@ -0,0 +1,13 @@
+#ifndef BCM63XX_DEV_PCMCIA_H_
+#define BCM63XX_DEV_PCMCIA_H_
+
+/*
+ * PCMCIA driver platform data
+ */
+struct bcm63xx_pcmcia_platform_data {
+ unsigned int ready_gpio;
+};
+
+int bcm63xx_pcmcia_register(void);
+
+#endif /* BCM63XX_DEV_PCMCIA_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
new file mode 100644
index 00000000..23c705ba
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_UART_H_
+#define BCM63XX_DEV_UART_H_
+
+int bcm63xx_uart_register(unsigned int id);
+
+#endif /* BCM63XX_DEV_UART_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
new file mode 100644
index 00000000..3999ec0a
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -0,0 +1,26 @@
+#ifndef BCM63XX_GPIO_H
+#define BCM63XX_GPIO_H
+
+#include <linux/init.h>
+
+int __init bcm63xx_gpio_init(void);
+
+static inline unsigned long bcm63xx_gpio_count(void)
+{
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6358_CPU_ID:
+ return 40;
+ case BCM6338_CPU_ID:
+ return 8;
+ case BCM6345_CPU_ID:
+ return 16;
+ case BCM6348_CPU_ID:
+ default:
+ return 37;
+ }
+}
+
+#define BCM63XX_GPIO_DIR_OUT 0x0
+#define BCM63XX_GPIO_DIR_IN 0x1
+
+#endif /* !BCM63XX_GPIO_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
new file mode 100644
index 00000000..91180fac
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
@@ -0,0 +1,93 @@
+#ifndef BCM63XX_IO_H_
+#define BCM63XX_IO_H_
+
+#include "bcm63xx_cpu.h"
+
+/*
+ * Physical memory map, RAM is mapped at 0x0.
+ *
+ * Note that size MUST be a power of two.
+ */
+#define BCM_PCMCIA_COMMON_BASE_PA (0x20000000)
+#define BCM_PCMCIA_COMMON_SIZE (16 * 1024 * 1024)
+#define BCM_PCMCIA_COMMON_END_PA (BCM_PCMCIA_COMMON_BASE_PA + \
+ BCM_PCMCIA_COMMON_SIZE - 1)
+
+#define BCM_PCMCIA_ATTR_BASE_PA (0x21000000)
+#define BCM_PCMCIA_ATTR_SIZE (16 * 1024 * 1024)
+#define BCM_PCMCIA_ATTR_END_PA (BCM_PCMCIA_ATTR_BASE_PA + \
+ BCM_PCMCIA_ATTR_SIZE - 1)
+
+#define BCM_PCMCIA_IO_BASE_PA (0x22000000)
+#define BCM_PCMCIA_IO_SIZE (64 * 1024)
+#define BCM_PCMCIA_IO_END_PA (BCM_PCMCIA_IO_BASE_PA + \
+ BCM_PCMCIA_IO_SIZE - 1)
+
+#define BCM_PCI_MEM_BASE_PA (0x30000000)
+#define BCM_PCI_MEM_SIZE (128 * 1024 * 1024)
+#define BCM_PCI_MEM_END_PA (BCM_PCI_MEM_BASE_PA + \
+ BCM_PCI_MEM_SIZE - 1)
+
+#define BCM_PCI_IO_BASE_PA (0x08000000)
+#define BCM_PCI_IO_SIZE (64 * 1024)
+#define BCM_PCI_IO_END_PA (BCM_PCI_IO_BASE_PA + \
+ BCM_PCI_IO_SIZE - 1)
+#define BCM_PCI_IO_HALF_PA (BCM_PCI_IO_BASE_PA + \
+ (BCM_PCI_IO_SIZE / 2) - 1)
+
+#define BCM_CB_MEM_BASE_PA (0x38000000)
+#define BCM_CB_MEM_SIZE (128 * 1024 * 1024)
+#define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \
+ BCM_CB_MEM_SIZE - 1)
+
+
+/*
+ * Internal registers are accessed through KSEG3
+ */
+#define BCM_REGS_VA(x) ((void __iomem *)(x))
+
+#define bcm_readb(a) (*(volatile unsigned char *) BCM_REGS_VA(a))
+#define bcm_readw(a) (*(volatile unsigned short *) BCM_REGS_VA(a))
+#define bcm_readl(a) (*(volatile unsigned int *) BCM_REGS_VA(a))
+#define bcm_writeb(v, a) (*(volatile unsigned char *) BCM_REGS_VA((a)) = (v))
+#define bcm_writew(v, a) (*(volatile unsigned short *) BCM_REGS_VA((a)) = (v))
+#define bcm_writel(v, a) (*(volatile unsigned int *) BCM_REGS_VA((a)) = (v))
+
+/*
+ * IO helpers to access register set for current CPU
+ */
+#define bcm_rset_readb(s, o) bcm_readb(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_readw(s, o) bcm_readw(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_readl(s, o) bcm_readl(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writeb(s, v, o) bcm_writeb((v), \
+ bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writew(s, v, o) bcm_writew((v), \
+ bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writel(s, v, o) bcm_writel((v), \
+ bcm63xx_regset_address(s) + (o))
+
+/*
+ * helpers for frequently used register sets
+ */
+#define bcm_perf_readl(o) bcm_rset_readl(RSET_PERF, (o))
+#define bcm_perf_writel(v, o) bcm_rset_writel(RSET_PERF, (v), (o))
+#define bcm_timer_readl(o) bcm_rset_readl(RSET_TIMER, (o))
+#define bcm_timer_writel(v, o) bcm_rset_writel(RSET_TIMER, (v), (o))
+#define bcm_wdt_readl(o) bcm_rset_readl(RSET_WDT, (o))
+#define bcm_wdt_writel(v, o) bcm_rset_writel(RSET_WDT, (v), (o))
+#define bcm_gpio_readl(o) bcm_rset_readl(RSET_GPIO, (o))
+#define bcm_gpio_writel(v, o) bcm_rset_writel(RSET_GPIO, (v), (o))
+#define bcm_uart0_readl(o) bcm_rset_readl(RSET_UART0, (o))
+#define bcm_uart0_writel(v, o) bcm_rset_writel(RSET_UART0, (v), (o))
+#define bcm_mpi_readl(o) bcm_rset_readl(RSET_MPI, (o))
+#define bcm_mpi_writel(v, o) bcm_rset_writel(RSET_MPI, (v), (o))
+#define bcm_pcmcia_readl(o) bcm_rset_readl(RSET_PCMCIA, (o))
+#define bcm_pcmcia_writel(v, o) bcm_rset_writel(RSET_PCMCIA, (v), (o))
+#define bcm_sdram_readl(o) bcm_rset_readl(RSET_SDRAM, (o))
+#define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o))
+#define bcm_memc_readl(o) bcm_rset_readl(RSET_MEMC, (o))
+#define bcm_memc_writel(v, o) bcm_rset_writel(RSET_MEMC, (v), (o))
+#define bcm_ddr_readl(o) bcm_rset_readl(RSET_DDR, (o))
+#define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o))
+
+#endif /* ! BCM63XX_IO_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
new file mode 100644
index 00000000..5f95577c
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
@@ -0,0 +1,15 @@
+#ifndef BCM63XX_IRQ_H_
+#define BCM63XX_IRQ_H_
+
+#include <bcm63xx_cpu.h>
+
+#define IRQ_MIPS_BASE 0
+#define IRQ_INTERNAL_BASE 8
+
+#define IRQ_EXT_BASE (IRQ_MIPS_BASE + 3)
+#define IRQ_EXT_0 (IRQ_EXT_BASE + 0)
+#define IRQ_EXT_1 (IRQ_EXT_BASE + 1)
+#define IRQ_EXT_2 (IRQ_EXT_BASE + 2)
+#define IRQ_EXT_3 (IRQ_EXT_BASE + 3)
+
+#endif /* ! BCM63XX_IRQ_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
new file mode 100644
index 00000000..85fd2750
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -0,0 +1,772 @@
+#ifndef BCM63XX_REGS_H_
+#define BCM63XX_REGS_H_
+
+/*************************************************************************
+ * _REG relative to RSET_PERF
+ *************************************************************************/
+
+/* Chip Identifier / Revision register */
+#define PERF_REV_REG 0x0
+#define REV_CHIPID_SHIFT 16
+#define REV_CHIPID_MASK (0xffff << REV_CHIPID_SHIFT)
+#define REV_REVID_SHIFT 0
+#define REV_REVID_MASK (0xffff << REV_REVID_SHIFT)
+
+/* Clock Control register */
+#define PERF_CKCTL_REG 0x4
+
+#define CKCTL_6338_ADSLPHY_EN (1 << 0)
+#define CKCTL_6338_MPI_EN (1 << 1)
+#define CKCTL_6338_DRAM_EN (1 << 2)
+#define CKCTL_6338_ENET_EN (1 << 4)
+#define CKCTL_6338_USBS_EN (1 << 4)
+#define CKCTL_6338_SAR_EN (1 << 5)
+#define CKCTL_6338_SPI_EN (1 << 9)
+
+#define CKCTL_6338_ALL_SAFE_EN (CKCTL_6338_ADSLPHY_EN | \
+ CKCTL_6338_MPI_EN | \
+ CKCTL_6338_ENET_EN | \
+ CKCTL_6338_SAR_EN | \
+ CKCTL_6338_SPI_EN)
+
+#define CKCTL_6345_CPU_EN (1 << 0)
+#define CKCTL_6345_BUS_EN (1 << 1)
+#define CKCTL_6345_EBI_EN (1 << 2)
+#define CKCTL_6345_UART_EN (1 << 3)
+#define CKCTL_6345_ADSLPHY_EN (1 << 4)
+#define CKCTL_6345_ENET_EN (1 << 7)
+#define CKCTL_6345_USBH_EN (1 << 8)
+
+#define CKCTL_6345_ALL_SAFE_EN (CKCTL_6345_ENET_EN | \
+ CKCTL_6345_USBH_EN | \
+ CKCTL_6345_ADSLPHY_EN)
+
+#define CKCTL_6348_ADSLPHY_EN (1 << 0)
+#define CKCTL_6348_MPI_EN (1 << 1)
+#define CKCTL_6348_SDRAM_EN (1 << 2)
+#define CKCTL_6348_M2M_EN (1 << 3)
+#define CKCTL_6348_ENET_EN (1 << 4)
+#define CKCTL_6348_SAR_EN (1 << 5)
+#define CKCTL_6348_USBS_EN (1 << 6)
+#define CKCTL_6348_USBH_EN (1 << 8)
+#define CKCTL_6348_SPI_EN (1 << 9)
+
+#define CKCTL_6348_ALL_SAFE_EN (CKCTL_6348_ADSLPHY_EN | \
+ CKCTL_6348_M2M_EN | \
+ CKCTL_6348_ENET_EN | \
+ CKCTL_6348_SAR_EN | \
+ CKCTL_6348_USBS_EN | \
+ CKCTL_6348_USBH_EN | \
+ CKCTL_6348_SPI_EN)
+
+#define CKCTL_6358_ENET_EN (1 << 4)
+#define CKCTL_6358_ADSLPHY_EN (1 << 5)
+#define CKCTL_6358_PCM_EN (1 << 8)
+#define CKCTL_6358_SPI_EN (1 << 9)
+#define CKCTL_6358_USBS_EN (1 << 10)
+#define CKCTL_6358_SAR_EN (1 << 11)
+#define CKCTL_6358_EMUSB_EN (1 << 17)
+#define CKCTL_6358_ENET0_EN (1 << 18)
+#define CKCTL_6358_ENET1_EN (1 << 19)
+#define CKCTL_6358_USBSU_EN (1 << 20)
+#define CKCTL_6358_EPHY_EN (1 << 21)
+
+#define CKCTL_6358_ALL_SAFE_EN (CKCTL_6358_ENET_EN | \
+ CKCTL_6358_ADSLPHY_EN | \
+ CKCTL_6358_PCM_EN | \
+ CKCTL_6358_SPI_EN | \
+ CKCTL_6358_USBS_EN | \
+ CKCTL_6358_SAR_EN | \
+ CKCTL_6358_EMUSB_EN | \
+ CKCTL_6358_ENET0_EN | \
+ CKCTL_6358_ENET1_EN | \
+ CKCTL_6358_USBSU_EN | \
+ CKCTL_6358_EPHY_EN)
+
+/* System PLL Control register */
+#define PERF_SYS_PLL_CTL_REG 0x8
+#define SYS_PLL_SOFT_RESET 0x1
+
+/* Interrupt Mask register */
+#define PERF_IRQMASK_REG 0xc
+#define PERF_IRQSTAT_REG 0x10
+
+/* Interrupt Status register */
+#define PERF_IRQSTAT_REG 0x10
+
+/* External Interrupt Configuration register */
+#define PERF_EXTIRQ_CFG_REG 0x14
+#define EXTIRQ_CFG_SENSE(x) (1 << (x))
+#define EXTIRQ_CFG_STAT(x) (1 << (x + 5))
+#define EXTIRQ_CFG_CLEAR(x) (1 << (x + 10))
+#define EXTIRQ_CFG_MASK(x) (1 << (x + 15))
+#define EXTIRQ_CFG_BOTHEDGE(x) (1 << (x + 20))
+#define EXTIRQ_CFG_LEVELSENSE(x) (1 << (x + 25))
+
+#define EXTIRQ_CFG_CLEAR_ALL (0xf << 10)
+#define EXTIRQ_CFG_MASK_ALL (0xf << 15)
+
+/* Soft Reset register */
+#define PERF_SOFTRESET_REG 0x28
+
+#define SOFTRESET_6338_SPI_MASK (1 << 0)
+#define SOFTRESET_6338_ENET_MASK (1 << 2)
+#define SOFTRESET_6338_USBH_MASK (1 << 3)
+#define SOFTRESET_6338_USBS_MASK (1 << 4)
+#define SOFTRESET_6338_ADSL_MASK (1 << 5)
+#define SOFTRESET_6338_DMAMEM_MASK (1 << 6)
+#define SOFTRESET_6338_SAR_MASK (1 << 7)
+#define SOFTRESET_6338_ACLC_MASK (1 << 8)
+#define SOFTRESET_6338_ADSLMIPSPLL_MASK (1 << 10)
+#define SOFTRESET_6338_ALL (SOFTRESET_6338_SPI_MASK | \
+ SOFTRESET_6338_ENET_MASK | \
+ SOFTRESET_6338_USBH_MASK | \
+ SOFTRESET_6338_USBS_MASK | \
+ SOFTRESET_6338_ADSL_MASK | \
+ SOFTRESET_6338_DMAMEM_MASK | \
+ SOFTRESET_6338_SAR_MASK | \
+ SOFTRESET_6338_ACLC_MASK | \
+ SOFTRESET_6338_ADSLMIPSPLL_MASK)
+
+#define SOFTRESET_6348_SPI_MASK (1 << 0)
+#define SOFTRESET_6348_ENET_MASK (1 << 2)
+#define SOFTRESET_6348_USBH_MASK (1 << 3)
+#define SOFTRESET_6348_USBS_MASK (1 << 4)
+#define SOFTRESET_6348_ADSL_MASK (1 << 5)
+#define SOFTRESET_6348_DMAMEM_MASK (1 << 6)
+#define SOFTRESET_6348_SAR_MASK (1 << 7)
+#define SOFTRESET_6348_ACLC_MASK (1 << 8)
+#define SOFTRESET_6348_ADSLMIPSPLL_MASK (1 << 10)
+
+#define SOFTRESET_6348_ALL (SOFTRESET_6348_SPI_MASK | \
+ SOFTRESET_6348_ENET_MASK | \
+ SOFTRESET_6348_USBH_MASK | \
+ SOFTRESET_6348_USBS_MASK | \
+ SOFTRESET_6348_ADSL_MASK | \
+ SOFTRESET_6348_DMAMEM_MASK | \
+ SOFTRESET_6348_SAR_MASK | \
+ SOFTRESET_6348_ACLC_MASK | \
+ SOFTRESET_6348_ADSLMIPSPLL_MASK)
+
+/* MIPS PLL control register */
+#define PERF_MIPSPLLCTL_REG 0x34
+#define MIPSPLLCTL_N1_SHIFT 20
+#define MIPSPLLCTL_N1_MASK (0x7 << MIPSPLLCTL_N1_SHIFT)
+#define MIPSPLLCTL_N2_SHIFT 15
+#define MIPSPLLCTL_N2_MASK (0x1f << MIPSPLLCTL_N2_SHIFT)
+#define MIPSPLLCTL_M1REF_SHIFT 12
+#define MIPSPLLCTL_M1REF_MASK (0x7 << MIPSPLLCTL_M1REF_SHIFT)
+#define MIPSPLLCTL_M2REF_SHIFT 9
+#define MIPSPLLCTL_M2REF_MASK (0x7 << MIPSPLLCTL_M2REF_SHIFT)
+#define MIPSPLLCTL_M1CPU_SHIFT 6
+#define MIPSPLLCTL_M1CPU_MASK (0x7 << MIPSPLLCTL_M1CPU_SHIFT)
+#define MIPSPLLCTL_M1BUS_SHIFT 3
+#define MIPSPLLCTL_M1BUS_MASK (0x7 << MIPSPLLCTL_M1BUS_SHIFT)
+#define MIPSPLLCTL_M2BUS_SHIFT 0
+#define MIPSPLLCTL_M2BUS_MASK (0x7 << MIPSPLLCTL_M2BUS_SHIFT)
+
+/* ADSL PHY PLL Control register */
+#define PERF_ADSLPLLCTL_REG 0x38
+#define ADSLPLLCTL_N1_SHIFT 20
+#define ADSLPLLCTL_N1_MASK (0x7 << ADSLPLLCTL_N1_SHIFT)
+#define ADSLPLLCTL_N2_SHIFT 15
+#define ADSLPLLCTL_N2_MASK (0x1f << ADSLPLLCTL_N2_SHIFT)
+#define ADSLPLLCTL_M1REF_SHIFT 12
+#define ADSLPLLCTL_M1REF_MASK (0x7 << ADSLPLLCTL_M1REF_SHIFT)
+#define ADSLPLLCTL_M2REF_SHIFT 9
+#define ADSLPLLCTL_M2REF_MASK (0x7 << ADSLPLLCTL_M2REF_SHIFT)
+#define ADSLPLLCTL_M1CPU_SHIFT 6
+#define ADSLPLLCTL_M1CPU_MASK (0x7 << ADSLPLLCTL_M1CPU_SHIFT)
+#define ADSLPLLCTL_M1BUS_SHIFT 3
+#define ADSLPLLCTL_M1BUS_MASK (0x7 << ADSLPLLCTL_M1BUS_SHIFT)
+#define ADSLPLLCTL_M2BUS_SHIFT 0
+#define ADSLPLLCTL_M2BUS_MASK (0x7 << ADSLPLLCTL_M2BUS_SHIFT)
+
+#define ADSLPLLCTL_VAL(n1, n2, m1ref, m2ref, m1cpu, m1bus, m2bus) \
+ (((n1) << ADSLPLLCTL_N1_SHIFT) | \
+ ((n2) << ADSLPLLCTL_N2_SHIFT) | \
+ ((m1ref) << ADSLPLLCTL_M1REF_SHIFT) | \
+ ((m2ref) << ADSLPLLCTL_M2REF_SHIFT) | \
+ ((m1cpu) << ADSLPLLCTL_M1CPU_SHIFT) | \
+ ((m1bus) << ADSLPLLCTL_M1BUS_SHIFT) | \
+ ((m2bus) << ADSLPLLCTL_M2BUS_SHIFT))
+
+
+/*************************************************************************
+ * _REG relative to RSET_TIMER
+ *************************************************************************/
+
+#define BCM63XX_TIMER_COUNT 4
+#define TIMER_T0_ID 0
+#define TIMER_T1_ID 1
+#define TIMER_T2_ID 2
+#define TIMER_WDT_ID 3
+
+/* Timer irqstat register */
+#define TIMER_IRQSTAT_REG 0
+#define TIMER_IRQSTAT_TIMER_CAUSE(x) (1 << (x))
+#define TIMER_IRQSTAT_TIMER0_CAUSE (1 << 0)
+#define TIMER_IRQSTAT_TIMER1_CAUSE (1 << 1)
+#define TIMER_IRQSTAT_TIMER2_CAUSE (1 << 2)
+#define TIMER_IRQSTAT_WDT_CAUSE (1 << 3)
+#define TIMER_IRQSTAT_TIMER_IR_EN(x) (1 << ((x) + 8))
+#define TIMER_IRQSTAT_TIMER0_IR_EN (1 << 8)
+#define TIMER_IRQSTAT_TIMER1_IR_EN (1 << 9)
+#define TIMER_IRQSTAT_TIMER2_IR_EN (1 << 10)
+
+/* Timer control register */
+#define TIMER_CTLx_REG(x) (0x4 + (x * 4))
+#define TIMER_CTL0_REG 0x4
+#define TIMER_CTL1_REG 0x8
+#define TIMER_CTL2_REG 0xC
+#define TIMER_CTL_COUNTDOWN_MASK (0x3fffffff)
+#define TIMER_CTL_MONOTONIC_MASK (1 << 30)
+#define TIMER_CTL_ENABLE_MASK (1 << 31)
+
+
+/*************************************************************************
+ * _REG relative to RSET_WDT
+ *************************************************************************/
+
+/* Watchdog default count register */
+#define WDT_DEFVAL_REG 0x0
+
+/* Watchdog control register */
+#define WDT_CTL_REG 0x4
+
+/* Watchdog control register constants */
+#define WDT_START_1 (0xff00)
+#define WDT_START_2 (0x00ff)
+#define WDT_STOP_1 (0xee00)
+#define WDT_STOP_2 (0x00ee)
+
+/* Watchdog reset length register */
+#define WDT_RSTLEN_REG 0x8
+
+
+/*************************************************************************
+ * _REG relative to RSET_UARTx
+ *************************************************************************/
+
+/* UART Control Register */
+#define UART_CTL_REG 0x0
+#define UART_CTL_RXTMOUTCNT_SHIFT 0
+#define UART_CTL_RXTMOUTCNT_MASK (0x1f << UART_CTL_RXTMOUTCNT_SHIFT)
+#define UART_CTL_RSTTXDN_SHIFT 5
+#define UART_CTL_RSTTXDN_MASK (1 << UART_CTL_RSTTXDN_SHIFT)
+#define UART_CTL_RSTRXFIFO_SHIFT 6
+#define UART_CTL_RSTRXFIFO_MASK (1 << UART_CTL_RSTRXFIFO_SHIFT)
+#define UART_CTL_RSTTXFIFO_SHIFT 7
+#define UART_CTL_RSTTXFIFO_MASK (1 << UART_CTL_RSTTXFIFO_SHIFT)
+#define UART_CTL_STOPBITS_SHIFT 8
+#define UART_CTL_STOPBITS_MASK (0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_1 (0x7 << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_2 (0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_BITSPERSYM_SHIFT 12
+#define UART_CTL_BITSPERSYM_MASK (0x3 << UART_CTL_BITSPERSYM_SHIFT)
+#define UART_CTL_XMITBRK_SHIFT 14
+#define UART_CTL_XMITBRK_MASK (1 << UART_CTL_XMITBRK_SHIFT)
+#define UART_CTL_RSVD_SHIFT 15
+#define UART_CTL_RSVD_MASK (1 << UART_CTL_RSVD_SHIFT)
+#define UART_CTL_RXPAREVEN_SHIFT 16
+#define UART_CTL_RXPAREVEN_MASK (1 << UART_CTL_RXPAREVEN_SHIFT)
+#define UART_CTL_RXPAREN_SHIFT 17
+#define UART_CTL_RXPAREN_MASK (1 << UART_CTL_RXPAREN_SHIFT)
+#define UART_CTL_TXPAREVEN_SHIFT 18
+#define UART_CTL_TXPAREVEN_MASK (1 << UART_CTL_TXPAREVEN_SHIFT)
+#define UART_CTL_TXPAREN_SHIFT 18
+#define UART_CTL_TXPAREN_MASK (1 << UART_CTL_TXPAREN_SHIFT)
+#define UART_CTL_LOOPBACK_SHIFT 20
+#define UART_CTL_LOOPBACK_MASK (1 << UART_CTL_LOOPBACK_SHIFT)
+#define UART_CTL_RXEN_SHIFT 21
+#define UART_CTL_RXEN_MASK (1 << UART_CTL_RXEN_SHIFT)
+#define UART_CTL_TXEN_SHIFT 22
+#define UART_CTL_TXEN_MASK (1 << UART_CTL_TXEN_SHIFT)
+#define UART_CTL_BRGEN_SHIFT 23
+#define UART_CTL_BRGEN_MASK (1 << UART_CTL_BRGEN_SHIFT)
+
+/* UART Baudword register */
+#define UART_BAUD_REG 0x4
+
+/* UART Misc Control register */
+#define UART_MCTL_REG 0x8
+#define UART_MCTL_DTR_SHIFT 0
+#define UART_MCTL_DTR_MASK (1 << UART_MCTL_DTR_SHIFT)
+#define UART_MCTL_RTS_SHIFT 1
+#define UART_MCTL_RTS_MASK (1 << UART_MCTL_RTS_SHIFT)
+#define UART_MCTL_RXFIFOTHRESH_SHIFT 8
+#define UART_MCTL_RXFIFOTHRESH_MASK (0xf << UART_MCTL_RXFIFOTHRESH_SHIFT)
+#define UART_MCTL_TXFIFOTHRESH_SHIFT 12
+#define UART_MCTL_TXFIFOTHRESH_MASK (0xf << UART_MCTL_TXFIFOTHRESH_SHIFT)
+#define UART_MCTL_RXFIFOFILL_SHIFT 16
+#define UART_MCTL_RXFIFOFILL_MASK (0x1f << UART_MCTL_RXFIFOFILL_SHIFT)
+#define UART_MCTL_TXFIFOFILL_SHIFT 24
+#define UART_MCTL_TXFIFOFILL_MASK (0x1f << UART_MCTL_TXFIFOFILL_SHIFT)
+
+/* UART External Input Configuration register */
+#define UART_EXTINP_REG 0xc
+#define UART_EXTINP_RI_SHIFT 0
+#define UART_EXTINP_RI_MASK (1 << UART_EXTINP_RI_SHIFT)
+#define UART_EXTINP_CTS_SHIFT 1
+#define UART_EXTINP_CTS_MASK (1 << UART_EXTINP_CTS_SHIFT)
+#define UART_EXTINP_DCD_SHIFT 2
+#define UART_EXTINP_DCD_MASK (1 << UART_EXTINP_DCD_SHIFT)
+#define UART_EXTINP_DSR_SHIFT 3
+#define UART_EXTINP_DSR_MASK (1 << UART_EXTINP_DSR_SHIFT)
+#define UART_EXTINP_IRSTAT(x) (1 << (x + 4))
+#define UART_EXTINP_IRMASK(x) (1 << (x + 8))
+#define UART_EXTINP_IR_RI 0
+#define UART_EXTINP_IR_CTS 1
+#define UART_EXTINP_IR_DCD 2
+#define UART_EXTINP_IR_DSR 3
+#define UART_EXTINP_RI_NOSENSE_SHIFT 16
+#define UART_EXTINP_RI_NOSENSE_MASK (1 << UART_EXTINP_RI_NOSENSE_SHIFT)
+#define UART_EXTINP_CTS_NOSENSE_SHIFT 17
+#define UART_EXTINP_CTS_NOSENSE_MASK (1 << UART_EXTINP_CTS_NOSENSE_SHIFT)
+#define UART_EXTINP_DCD_NOSENSE_SHIFT 18
+#define UART_EXTINP_DCD_NOSENSE_MASK (1 << UART_EXTINP_DCD_NOSENSE_SHIFT)
+#define UART_EXTINP_DSR_NOSENSE_SHIFT 19
+#define UART_EXTINP_DSR_NOSENSE_MASK (1 << UART_EXTINP_DSR_NOSENSE_SHIFT)
+
+/* UART Interrupt register */
+#define UART_IR_REG 0x10
+#define UART_IR_MASK(x) (1 << (x + 16))
+#define UART_IR_STAT(x) (1 << (x))
+#define UART_IR_EXTIP 0
+#define UART_IR_TXUNDER 1
+#define UART_IR_TXOVER 2
+#define UART_IR_TXTRESH 3
+#define UART_IR_TXRDLATCH 4
+#define UART_IR_TXEMPTY 5
+#define UART_IR_RXUNDER 6
+#define UART_IR_RXOVER 7
+#define UART_IR_RXTIMEOUT 8
+#define UART_IR_RXFULL 9
+#define UART_IR_RXTHRESH 10
+#define UART_IR_RXNOTEMPTY 11
+#define UART_IR_RXFRAMEERR 12
+#define UART_IR_RXPARERR 13
+#define UART_IR_RXBRK 14
+#define UART_IR_TXDONE 15
+
+/* UART Fifo register */
+#define UART_FIFO_REG 0x14
+#define UART_FIFO_VALID_SHIFT 0
+#define UART_FIFO_VALID_MASK 0xff
+#define UART_FIFO_FRAMEERR_SHIFT 8
+#define UART_FIFO_FRAMEERR_MASK (1 << UART_FIFO_FRAMEERR_SHIFT)
+#define UART_FIFO_PARERR_SHIFT 9
+#define UART_FIFO_PARERR_MASK (1 << UART_FIFO_PARERR_SHIFT)
+#define UART_FIFO_BRKDET_SHIFT 10
+#define UART_FIFO_BRKDET_MASK (1 << UART_FIFO_BRKDET_SHIFT)
+#define UART_FIFO_ANYERR_MASK (UART_FIFO_FRAMEERR_MASK | \
+ UART_FIFO_PARERR_MASK | \
+ UART_FIFO_BRKDET_MASK)
+
+
+/*************************************************************************
+ * _REG relative to RSET_GPIO
+ *************************************************************************/
+
+/* GPIO registers */
+#define GPIO_CTL_HI_REG 0x0
+#define GPIO_CTL_LO_REG 0x4
+#define GPIO_DATA_HI_REG 0x8
+#define GPIO_DATA_LO_REG 0xC
+
+/* GPIO mux registers and constants */
+#define GPIO_MODE_REG 0x18
+
+#define GPIO_MODE_6348_G4_DIAG 0x00090000
+#define GPIO_MODE_6348_G4_UTOPIA 0x00080000
+#define GPIO_MODE_6348_G4_LEGACY_LED 0x00030000
+#define GPIO_MODE_6348_G4_MII_SNOOP 0x00020000
+#define GPIO_MODE_6348_G4_EXT_EPHY 0x00010000
+#define GPIO_MODE_6348_G3_DIAG 0x00009000
+#define GPIO_MODE_6348_G3_UTOPIA 0x00008000
+#define GPIO_MODE_6348_G3_EXT_MII 0x00007000
+#define GPIO_MODE_6348_G2_DIAG 0x00000900
+#define GPIO_MODE_6348_G2_PCI 0x00000500
+#define GPIO_MODE_6348_G1_DIAG 0x00000090
+#define GPIO_MODE_6348_G1_UTOPIA 0x00000080
+#define GPIO_MODE_6348_G1_SPI_UART 0x00000060
+#define GPIO_MODE_6348_G1_SPI_MASTER 0x00000060
+#define GPIO_MODE_6348_G1_MII_PCCARD 0x00000040
+#define GPIO_MODE_6348_G1_MII_SNOOP 0x00000020
+#define GPIO_MODE_6348_G1_EXT_EPHY 0x00000010
+#define GPIO_MODE_6348_G0_DIAG 0x00000009
+#define GPIO_MODE_6348_G0_EXT_MII 0x00000007
+
+#define GPIO_MODE_6358_EXTRACS (1 << 5)
+#define GPIO_MODE_6358_UART1 (1 << 6)
+#define GPIO_MODE_6358_EXTRA_SPI_SS (1 << 7)
+#define GPIO_MODE_6358_SERIAL_LED (1 << 10)
+#define GPIO_MODE_6358_UTOPIA (1 << 12)
+
+
+/*************************************************************************
+ * _REG relative to RSET_ENET
+ *************************************************************************/
+
+/* Receiver Configuration register */
+#define ENET_RXCFG_REG 0x0
+#define ENET_RXCFG_ALLMCAST_SHIFT 1
+#define ENET_RXCFG_ALLMCAST_MASK (1 << ENET_RXCFG_ALLMCAST_SHIFT)
+#define ENET_RXCFG_PROMISC_SHIFT 3
+#define ENET_RXCFG_PROMISC_MASK (1 << ENET_RXCFG_PROMISC_SHIFT)
+#define ENET_RXCFG_LOOPBACK_SHIFT 4
+#define ENET_RXCFG_LOOPBACK_MASK (1 << ENET_RXCFG_LOOPBACK_SHIFT)
+#define ENET_RXCFG_ENFLOW_SHIFT 5
+#define ENET_RXCFG_ENFLOW_MASK (1 << ENET_RXCFG_ENFLOW_SHIFT)
+
+/* Receive Maximum Length register */
+#define ENET_RXMAXLEN_REG 0x4
+#define ENET_RXMAXLEN_SHIFT 0
+#define ENET_RXMAXLEN_MASK (0x7ff << ENET_RXMAXLEN_SHIFT)
+
+/* Transmit Maximum Length register */
+#define ENET_TXMAXLEN_REG 0x8
+#define ENET_TXMAXLEN_SHIFT 0
+#define ENET_TXMAXLEN_MASK (0x7ff << ENET_TXMAXLEN_SHIFT)
+
+/* MII Status/Control register */
+#define ENET_MIISC_REG 0x10
+#define ENET_MIISC_MDCFREQDIV_SHIFT 0
+#define ENET_MIISC_MDCFREQDIV_MASK (0x7f << ENET_MIISC_MDCFREQDIV_SHIFT)
+#define ENET_MIISC_PREAMBLEEN_SHIFT 7
+#define ENET_MIISC_PREAMBLEEN_MASK (1 << ENET_MIISC_PREAMBLEEN_SHIFT)
+
+/* MII Data register */
+#define ENET_MIIDATA_REG 0x14
+#define ENET_MIIDATA_DATA_SHIFT 0
+#define ENET_MIIDATA_DATA_MASK (0xffff << ENET_MIIDATA_DATA_SHIFT)
+#define ENET_MIIDATA_TA_SHIFT 16
+#define ENET_MIIDATA_TA_MASK (0x3 << ENET_MIIDATA_TA_SHIFT)
+#define ENET_MIIDATA_REG_SHIFT 18
+#define ENET_MIIDATA_REG_MASK (0x1f << ENET_MIIDATA_REG_SHIFT)
+#define ENET_MIIDATA_PHYID_SHIFT 23
+#define ENET_MIIDATA_PHYID_MASK (0x1f << ENET_MIIDATA_PHYID_SHIFT)
+#define ENET_MIIDATA_OP_READ_MASK (0x6 << 28)
+#define ENET_MIIDATA_OP_WRITE_MASK (0x5 << 28)
+
+/* Ethernet Interrupt Mask register */
+#define ENET_IRMASK_REG 0x18
+
+/* Ethernet Interrupt register */
+#define ENET_IR_REG 0x1c
+#define ENET_IR_MII (1 << 0)
+#define ENET_IR_MIB (1 << 1)
+#define ENET_IR_FLOWC (1 << 2)
+
+/* Ethernet Control register */
+#define ENET_CTL_REG 0x2c
+#define ENET_CTL_ENABLE_SHIFT 0
+#define ENET_CTL_ENABLE_MASK (1 << ENET_CTL_ENABLE_SHIFT)
+#define ENET_CTL_DISABLE_SHIFT 1
+#define ENET_CTL_DISABLE_MASK (1 << ENET_CTL_DISABLE_SHIFT)
+#define ENET_CTL_SRESET_SHIFT 2
+#define ENET_CTL_SRESET_MASK (1 << ENET_CTL_SRESET_SHIFT)
+#define ENET_CTL_EPHYSEL_SHIFT 3
+#define ENET_CTL_EPHYSEL_MASK (1 << ENET_CTL_EPHYSEL_SHIFT)
+
+/* Transmit Control register */
+#define ENET_TXCTL_REG 0x30
+#define ENET_TXCTL_FD_SHIFT 0
+#define ENET_TXCTL_FD_MASK (1 << ENET_TXCTL_FD_SHIFT)
+
+/* Transmit Watermask register */
+#define ENET_TXWMARK_REG 0x34
+#define ENET_TXWMARK_WM_SHIFT 0
+#define ENET_TXWMARK_WM_MASK (0x3f << ENET_TXWMARK_WM_SHIFT)
+
+/* MIB Control register */
+#define ENET_MIBCTL_REG 0x38
+#define ENET_MIBCTL_RDCLEAR_SHIFT 0
+#define ENET_MIBCTL_RDCLEAR_MASK (1 << ENET_MIBCTL_RDCLEAR_SHIFT)
+
+/* Perfect Match Data Low register */
+#define ENET_PML_REG(x) (0x58 + (x) * 8)
+#define ENET_PMH_REG(x) (0x5c + (x) * 8)
+#define ENET_PMH_DATAVALID_SHIFT 16
+#define ENET_PMH_DATAVALID_MASK (1 << ENET_PMH_DATAVALID_SHIFT)
+
+/* MIB register */
+#define ENET_MIB_REG(x) (0x200 + (x) * 4)
+#define ENET_MIB_REG_COUNT 55
+
+
+/*************************************************************************
+ * _REG relative to RSET_ENETDMA
+ *************************************************************************/
+
+/* Controller Configuration Register */
+#define ENETDMA_CFG_REG (0x0)
+#define ENETDMA_CFG_EN_SHIFT 0
+#define ENETDMA_CFG_EN_MASK (1 << ENETDMA_CFG_EN_SHIFT)
+#define ENETDMA_CFG_FLOWCH_MASK(x) (1 << ((x >> 1) + 1))
+
+/* Flow Control Descriptor Low Threshold register */
+#define ENETDMA_FLOWCL_REG(x) (0x4 + (x) * 6)
+
+/* Flow Control Descriptor High Threshold register */
+#define ENETDMA_FLOWCH_REG(x) (0x8 + (x) * 6)
+
+/* Flow Control Descriptor Buffer Alloca Threshold register */
+#define ENETDMA_BUFALLOC_REG(x) (0xc + (x) * 6)
+#define ENETDMA_BUFALLOC_FORCE_SHIFT 31
+#define ENETDMA_BUFALLOC_FORCE_MASK (1 << ENETDMA_BUFALLOC_FORCE_SHIFT)
+
+/* Channel Configuration register */
+#define ENETDMA_CHANCFG_REG(x) (0x100 + (x) * 0x10)
+#define ENETDMA_CHANCFG_EN_SHIFT 0
+#define ENETDMA_CHANCFG_EN_MASK (1 << ENETDMA_CHANCFG_EN_SHIFT)
+#define ENETDMA_CHANCFG_PKTHALT_SHIFT 1
+#define ENETDMA_CHANCFG_PKTHALT_MASK (1 << ENETDMA_CHANCFG_PKTHALT_SHIFT)
+
+/* Interrupt Control/Status register */
+#define ENETDMA_IR_REG(x) (0x104 + (x) * 0x10)
+#define ENETDMA_IR_BUFDONE_MASK (1 << 0)
+#define ENETDMA_IR_PKTDONE_MASK (1 << 1)
+#define ENETDMA_IR_NOTOWNER_MASK (1 << 2)
+
+/* Interrupt Mask register */
+#define ENETDMA_IRMASK_REG(x) (0x108 + (x) * 0x10)
+
+/* Maximum Burst Length */
+#define ENETDMA_MAXBURST_REG(x) (0x10C + (x) * 0x10)
+
+/* Ring Start Address register */
+#define ENETDMA_RSTART_REG(x) (0x200 + (x) * 0x10)
+
+/* State Ram Word 2 */
+#define ENETDMA_SRAM2_REG(x) (0x204 + (x) * 0x10)
+
+/* State Ram Word 3 */
+#define ENETDMA_SRAM3_REG(x) (0x208 + (x) * 0x10)
+
+/* State Ram Word 4 */
+#define ENETDMA_SRAM4_REG(x) (0x20c + (x) * 0x10)
+
+
+/*************************************************************************
+ * _REG relative to RSET_OHCI_PRIV
+ *************************************************************************/
+
+#define OHCI_PRIV_REG 0x0
+#define OHCI_PRIV_PORT1_HOST_SHIFT 0
+#define OHCI_PRIV_PORT1_HOST_MASK (1 << OHCI_PRIV_PORT1_HOST_SHIFT)
+#define OHCI_PRIV_REG_SWAP_SHIFT 3
+#define OHCI_PRIV_REG_SWAP_MASK (1 << OHCI_PRIV_REG_SWAP_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_USBH_PRIV
+ *************************************************************************/
+
+#define USBH_PRIV_SWAP_REG 0x0
+#define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT 4
+#define USBH_PRIV_SWAP_EHCI_ENDN_MASK (1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT)
+#define USBH_PRIV_SWAP_EHCI_DATA_SHIFT 3
+#define USBH_PRIV_SWAP_EHCI_DATA_MASK (1 << USBH_PRIV_SWAP_EHCI_DATA_SHIFT)
+#define USBH_PRIV_SWAP_OHCI_ENDN_SHIFT 1
+#define USBH_PRIV_SWAP_OHCI_ENDN_MASK (1 << USBH_PRIV_SWAP_OHCI_ENDN_SHIFT)
+#define USBH_PRIV_SWAP_OHCI_DATA_SHIFT 0
+#define USBH_PRIV_SWAP_OHCI_DATA_MASK (1 << USBH_PRIV_SWAP_OHCI_DATA_SHIFT)
+
+#define USBH_PRIV_TEST_REG 0x24
+
+
+/*************************************************************************
+ * _REG relative to RSET_MPI
+ *************************************************************************/
+
+/* well known (hard wired) chip select */
+#define MPI_CS_PCMCIA_COMMON 4
+#define MPI_CS_PCMCIA_ATTR 5
+#define MPI_CS_PCMCIA_IO 6
+
+/* Chip select base register */
+#define MPI_CSBASE_REG(x) (0x0 + (x) * 8)
+#define MPI_CSBASE_BASE_SHIFT 13
+#define MPI_CSBASE_BASE_MASK (0x1ffff << MPI_CSBASE_BASE_SHIFT)
+#define MPI_CSBASE_SIZE_SHIFT 0
+#define MPI_CSBASE_SIZE_MASK (0xf << MPI_CSBASE_SIZE_SHIFT)
+
+#define MPI_CSBASE_SIZE_8K 0
+#define MPI_CSBASE_SIZE_16K 1
+#define MPI_CSBASE_SIZE_32K 2
+#define MPI_CSBASE_SIZE_64K 3
+#define MPI_CSBASE_SIZE_128K 4
+#define MPI_CSBASE_SIZE_256K 5
+#define MPI_CSBASE_SIZE_512K 6
+#define MPI_CSBASE_SIZE_1M 7
+#define MPI_CSBASE_SIZE_2M 8
+#define MPI_CSBASE_SIZE_4M 9
+#define MPI_CSBASE_SIZE_8M 10
+#define MPI_CSBASE_SIZE_16M 11
+#define MPI_CSBASE_SIZE_32M 12
+#define MPI_CSBASE_SIZE_64M 13
+#define MPI_CSBASE_SIZE_128M 14
+#define MPI_CSBASE_SIZE_256M 15
+
+/* Chip select control register */
+#define MPI_CSCTL_REG(x) (0x4 + (x) * 8)
+#define MPI_CSCTL_ENABLE_MASK (1 << 0)
+#define MPI_CSCTL_WAIT_SHIFT 1
+#define MPI_CSCTL_WAIT_MASK (0x7 << MPI_CSCTL_WAIT_SHIFT)
+#define MPI_CSCTL_DATA16_MASK (1 << 4)
+#define MPI_CSCTL_SYNCMODE_MASK (1 << 7)
+#define MPI_CSCTL_TSIZE_MASK (1 << 8)
+#define MPI_CSCTL_ENDIANSWAP_MASK (1 << 10)
+#define MPI_CSCTL_SETUP_SHIFT 16
+#define MPI_CSCTL_SETUP_MASK (0xf << MPI_CSCTL_SETUP_SHIFT)
+#define MPI_CSCTL_HOLD_SHIFT 20
+#define MPI_CSCTL_HOLD_MASK (0xf << MPI_CSCTL_HOLD_SHIFT)
+
+/* PCI registers */
+#define MPI_SP0_RANGE_REG 0x100
+#define MPI_SP0_REMAP_REG 0x104
+#define MPI_SP0_REMAP_ENABLE_MASK (1 << 0)
+#define MPI_SP1_RANGE_REG 0x10C
+#define MPI_SP1_REMAP_REG 0x110
+#define MPI_SP1_REMAP_ENABLE_MASK (1 << 0)
+
+#define MPI_L2PCFG_REG 0x11C
+#define MPI_L2PCFG_CFG_TYPE_SHIFT 0
+#define MPI_L2PCFG_CFG_TYPE_MASK (0x3 << MPI_L2PCFG_CFG_TYPE_SHIFT)
+#define MPI_L2PCFG_REG_SHIFT 2
+#define MPI_L2PCFG_REG_MASK (0x3f << MPI_L2PCFG_REG_SHIFT)
+#define MPI_L2PCFG_FUNC_SHIFT 8
+#define MPI_L2PCFG_FUNC_MASK (0x7 << MPI_L2PCFG_FUNC_SHIFT)
+#define MPI_L2PCFG_DEVNUM_SHIFT 11
+#define MPI_L2PCFG_DEVNUM_MASK (0x1f << MPI_L2PCFG_DEVNUM_SHIFT)
+#define MPI_L2PCFG_CFG_USEREG_MASK (1 << 30)
+#define MPI_L2PCFG_CFG_SEL_MASK (1 << 31)
+
+#define MPI_L2PMEMRANGE1_REG 0x120
+#define MPI_L2PMEMBASE1_REG 0x124
+#define MPI_L2PMEMREMAP1_REG 0x128
+#define MPI_L2PMEMRANGE2_REG 0x12C
+#define MPI_L2PMEMBASE2_REG 0x130
+#define MPI_L2PMEMREMAP2_REG 0x134
+#define MPI_L2PIORANGE_REG 0x138
+#define MPI_L2PIOBASE_REG 0x13C
+#define MPI_L2PIOREMAP_REG 0x140
+#define MPI_L2P_BASE_MASK (0xffff8000)
+#define MPI_L2PREMAP_ENABLED_MASK (1 << 0)
+#define MPI_L2PREMAP_IS_CARDBUS_MASK (1 << 2)
+
+#define MPI_PCIMODESEL_REG 0x144
+#define MPI_PCIMODESEL_BAR1_NOSWAP_MASK (1 << 0)
+#define MPI_PCIMODESEL_BAR2_NOSWAP_MASK (1 << 1)
+#define MPI_PCIMODESEL_EXT_ARB_MASK (1 << 2)
+#define MPI_PCIMODESEL_PREFETCH_SHIFT 4
+#define MPI_PCIMODESEL_PREFETCH_MASK (0xf << MPI_PCIMODESEL_PREFETCH_SHIFT)
+
+#define MPI_LOCBUSCTL_REG 0x14C
+#define MPI_LOCBUSCTL_EN_PCI_GPIO_MASK (1 << 0)
+#define MPI_LOCBUSCTL_U2P_NOSWAP_MASK (1 << 1)
+
+#define MPI_LOCINT_REG 0x150
+#define MPI_LOCINT_MASK(x) (1 << (x + 16))
+#define MPI_LOCINT_STAT(x) (1 << (x))
+#define MPI_LOCINT_DIR_FAILED 6
+#define MPI_LOCINT_EXT_PCI_INT 7
+#define MPI_LOCINT_SERR 8
+#define MPI_LOCINT_CSERR 9
+
+#define MPI_PCICFGCTL_REG 0x178
+#define MPI_PCICFGCTL_CFGADDR_SHIFT 2
+#define MPI_PCICFGCTL_CFGADDR_MASK (0x1f << MPI_PCICFGCTL_CFGADDR_SHIFT)
+#define MPI_PCICFGCTL_WRITEEN_MASK (1 << 7)
+
+#define MPI_PCICFGDATA_REG 0x17C
+
+/* PCI host bridge custom register */
+#define BCMPCI_REG_TIMERS 0x40
+#define REG_TIMER_TRDY_SHIFT 0
+#define REG_TIMER_TRDY_MASK (0xff << REG_TIMER_TRDY_SHIFT)
+#define REG_TIMER_RETRY_SHIFT 8
+#define REG_TIMER_RETRY_MASK (0xff << REG_TIMER_RETRY_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_PCMCIA
+ *************************************************************************/
+
+#define PCMCIA_C1_REG 0x0
+#define PCMCIA_C1_CD1_MASK (1 << 0)
+#define PCMCIA_C1_CD2_MASK (1 << 1)
+#define PCMCIA_C1_VS1_MASK (1 << 2)
+#define PCMCIA_C1_VS2_MASK (1 << 3)
+#define PCMCIA_C1_VS1OE_MASK (1 << 6)
+#define PCMCIA_C1_VS2OE_MASK (1 << 7)
+#define PCMCIA_C1_CBIDSEL_SHIFT (8)
+#define PCMCIA_C1_CBIDSEL_MASK (0x1f << PCMCIA_C1_CBIDSEL_SHIFT)
+#define PCMCIA_C1_EN_PCMCIA_GPIO_MASK (1 << 13)
+#define PCMCIA_C1_EN_PCMCIA_MASK (1 << 14)
+#define PCMCIA_C1_EN_CARDBUS_MASK (1 << 15)
+#define PCMCIA_C1_RESET_MASK (1 << 18)
+
+#define PCMCIA_C2_REG 0x8
+#define PCMCIA_C2_DATA16_MASK (1 << 0)
+#define PCMCIA_C2_BYTESWAP_MASK (1 << 1)
+#define PCMCIA_C2_RWCOUNT_SHIFT 2
+#define PCMCIA_C2_RWCOUNT_MASK (0x3f << PCMCIA_C2_RWCOUNT_SHIFT)
+#define PCMCIA_C2_INACTIVE_SHIFT 8
+#define PCMCIA_C2_INACTIVE_MASK (0x3f << PCMCIA_C2_INACTIVE_SHIFT)
+#define PCMCIA_C2_SETUP_SHIFT 16
+#define PCMCIA_C2_SETUP_MASK (0x3f << PCMCIA_C2_SETUP_SHIFT)
+#define PCMCIA_C2_HOLD_SHIFT 24
+#define PCMCIA_C2_HOLD_MASK (0x3f << PCMCIA_C2_HOLD_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_SDRAM
+ *************************************************************************/
+
+#define SDRAM_CFG_REG 0x0
+#define SDRAM_CFG_ROW_SHIFT 4
+#define SDRAM_CFG_ROW_MASK (0x3 << SDRAM_CFG_ROW_SHIFT)
+#define SDRAM_CFG_COL_SHIFT 6
+#define SDRAM_CFG_COL_MASK (0x3 << SDRAM_CFG_COL_SHIFT)
+#define SDRAM_CFG_32B_SHIFT 10
+#define SDRAM_CFG_32B_MASK (1 << SDRAM_CFG_32B_SHIFT)
+#define SDRAM_CFG_BANK_SHIFT 13
+#define SDRAM_CFG_BANK_MASK (1 << SDRAM_CFG_BANK_SHIFT)
+
+#define SDRAM_PRIO_REG 0x2C
+#define SDRAM_PRIO_MIPS_SHIFT 29
+#define SDRAM_PRIO_MIPS_MASK (1 << SDRAM_PRIO_MIPS_SHIFT)
+#define SDRAM_PRIO_ADSL_SHIFT 30
+#define SDRAM_PRIO_ADSL_MASK (1 << SDRAM_PRIO_ADSL_SHIFT)
+#define SDRAM_PRIO_EN_SHIFT 31
+#define SDRAM_PRIO_EN_MASK (1 << SDRAM_PRIO_EN_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_MEMC
+ *************************************************************************/
+
+#define MEMC_CFG_REG 0x4
+#define MEMC_CFG_32B_SHIFT 1
+#define MEMC_CFG_32B_MASK (1 << MEMC_CFG_32B_SHIFT)
+#define MEMC_CFG_COL_SHIFT 3
+#define MEMC_CFG_COL_MASK (0x3 << MEMC_CFG_COL_SHIFT)
+#define MEMC_CFG_ROW_SHIFT 6
+#define MEMC_CFG_ROW_MASK (0x3 << MEMC_CFG_ROW_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_DDR
+ *************************************************************************/
+
+#define DDR_DMIPSPLLCFG_REG 0x18
+#define DMIPSPLLCFG_M1_SHIFT 0
+#define DMIPSPLLCFG_M1_MASK (0xff << DMIPSPLLCFG_M1_SHIFT)
+#define DMIPSPLLCFG_N1_SHIFT 23
+#define DMIPSPLLCFG_N1_MASK (0x3f << DMIPSPLLCFG_N1_SHIFT)
+#define DMIPSPLLCFG_N2_SHIFT 29
+#define DMIPSPLLCFG_N2_MASK (0x7 << DMIPSPLLCFG_N2_SHIFT)
+
+#endif /* BCM63XX_REGS_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
new file mode 100644
index 00000000..c0fce833
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
@@ -0,0 +1,11 @@
+#ifndef BCM63XX_TIMER_H_
+#define BCM63XX_TIMER_H_
+
+int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data);
+void bcm63xx_timer_unregister(int id);
+int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us);
+int bcm63xx_timer_enable(int id);
+int bcm63xx_timer_disable(int id);
+unsigned int bcm63xx_timer_countdown(unsigned int countdown_us);
+
+#endif /* !BCM63XX_TIMER_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
new file mode 100644
index 00000000..ed72e6a2
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
@@ -0,0 +1,97 @@
+#ifndef __BCM963XX_TAG_H
+#define __BCM963XX_TAG_H
+
+#define TAGVER_LEN 4 /* Length of Tag Version */
+#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */
+#define SIG1_LEN 20 /* Company Signature 1 Length */
+#define SIG2_LEN 14 /* Company Signature 2 Length */
+#define BOARDID_LEN 16 /* Length of BoardId */
+#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
+#define CHIPID_LEN 6 /* Chip Id Length */
+#define IMAGE_LEN 10 /* Length of Length Field */
+#define ADDRESS_LEN 12 /* Length of Address field */
+#define DUALFLAG_LEN 2 /* Dual Image flag Length */
+#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */
+#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
+#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
+#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
+#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
+#define CRC_LEN 4 /* Length of CRC in bytes */
+#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
+
+#define NUM_PIRELLI 2
+#define IMAGETAG_CRC_START 0xFFFFFFFF
+
+#define PIRELLI_BOARDS { \
+ "AGPF-S0", \
+ "DWV-S0", \
+}
+
+/*
+ * The broadcom firmware assumes the rootfs starts the image,
+ * therefore uses the rootfs start (flash_image_address)
+ * to determine where to flash the image. Since we have the kernel first
+ * we have to give it the kernel address, but the crc uses the length
+ * associated with this address (root_length), which is added to the kernel
+ * length (kernel_length) to determine the length of image to flash and thus
+ * needs to be rootfs + deadcode (jffs2 EOF marker)
+*/
+
+struct bcm_tag {
+ /* 0-3: Version of the image tag */
+ char tag_version[TAGVER_LEN];
+ /* 4-23: Company Line 1 */
+ char sig_1[SIG1_LEN];
+ /* 24-37: Company Line 2 */
+ char sig_2[SIG2_LEN];
+ /* 38-43: Chip this image is for */
+ char chip_id[CHIPID_LEN];
+ /* 44-59: Board name */
+ char board_id[BOARDID_LEN];
+ /* 60-61: Map endianness -- 1 BE 0 LE */
+ char big_endian[ENDIANFLAG_LEN];
+ /* 62-71: Total length of image */
+ char total_length[IMAGE_LEN];
+ /* 72-83: Address in memory of CFE */
+ char cfe__address[ADDRESS_LEN];
+ /* 84-93: Size of CFE */
+ char cfe_length[IMAGE_LEN];
+ /* 94-105: Address in memory of image start
+ * (kernel for OpenWRT, rootfs for stock firmware)
+ */
+ char flash_image_start[ADDRESS_LEN];
+ /* 106-115: Size of rootfs */
+ char root_length[IMAGE_LEN];
+ /* 116-127: Address in memory of kernel */
+ char kernel_address[ADDRESS_LEN];
+ /* 128-137: Size of kernel */
+ char kernel_length[IMAGE_LEN];
+ /* 138-139: Unused at the moment */
+ char dual_image[DUALFLAG_LEN];
+ /* 140-141: Unused at the moment */
+ char inactive_flag[INACTIVEFLAG_LEN];
+ /* 142-161: RSA Signature (not used; some vendors may use this) */
+ char rsa_signature[RSASIG_LEN];
+ /* 162-191: Compilation and related information (not used in OpenWrt) */
+ char information1[TAGINFO1_LEN];
+ /* 192-195: Version flash layout */
+ char flash_layout_ver[FLASHLAYOUTVER_LEN];
+ /* 196-199: kernel+rootfs CRC32 */
+ char fskernel_crc[CRC_LEN];
+ /* 200-215: Unused except on Alice Gate where is is information */
+ char information2[TAGINFO2_LEN];
+ /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
+ char image_crc[CRC_LEN];
+ /* 220-223: CRC32 of rootfs partition */
+ char rootfs_crc[CRC_LEN];
+ /* 224-227: CRC32 of kernel partition */
+ char kernel_crc[CRC_LEN];
+ /* 228-235: Unused at present */
+ char reserved1[8];
+ /* 236-239: CRC32 of header excluding last 20 bytes */
+ char header_crc[CRC_LEN];
+ /* 240-255: Unused at present */
+ char reserved2[16];
+};
+
+#endif /* __BCM63XX_TAG_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
new file mode 100644
index 00000000..474daaa5
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -0,0 +1,62 @@
+#ifndef BOARD_BCM963XX_H_
+#define BOARD_BCM963XX_H_
+
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_dsp.h>
+
+/*
+ * flash mapping
+ */
+#define BCM963XX_CFE_VERSION_OFFSET 0x570
+#define BCM963XX_NVRAM_OFFSET 0x580
+
+/*
+ * nvram structure
+ */
+struct bcm963xx_nvram {
+ u32 version;
+ u8 reserved1[256];
+ u8 name[16];
+ u32 main_tp_number;
+ u32 psi_size;
+ u32 mac_addr_count;
+ u8 mac_addr_base[6];
+ u8 reserved2[2];
+ u32 checksum_old;
+ u8 reserved3[720];
+ u32 checksum_high;
+};
+
+/*
+ * board definition
+ */
+struct board_info {
+ u8 name[16];
+ unsigned int expected_cpu_id;
+
+ /* enabled feature/device */
+ unsigned int has_enet0:1;
+ unsigned int has_enet1:1;
+ unsigned int has_pci:1;
+ unsigned int has_pccard:1;
+ unsigned int has_ohci0:1;
+ unsigned int has_ehci0:1;
+ unsigned int has_dsp:1;
+ unsigned int has_uart0:1;
+ unsigned int has_uart1:1;
+
+ /* ethernet config */
+ struct bcm63xx_enet_platform_data enet0;
+ struct bcm63xx_enet_platform_data enet1;
+
+ /* DSP config */
+ struct bcm63xx_dsp_platform_data dsp;
+
+ /* GPIO LEDs */
+ struct gpio_led leds[5];
+};
+
+#endif /* ! BOARD_BCM963XX_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
new file mode 100644
index 00000000..f453c01d
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
@@ -0,0 +1,51 @@
+#ifndef __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H
+
+#include <bcm63xx_cpu.h>
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
+#define cpu_has_counter 1
+#define cpu_has_watch 0
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+#define cpu_has_vtag_icache 0
+
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
+#define cpu_has_dc_aliases 0
+#endif
+
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_pindexed_dcache 0
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+
+#define cpu_dcache_line_size() 16
+#define cpu_icache_line_size() 16
+#define cpu_scache_line_size() 0
+
+#endif /* __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/gpio.h b/arch/mips/include/asm/mach-bcm63xx/gpio.h
new file mode 100644
index 00000000..1eb534de
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/gpio.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_MIPS_MACH_BCM63XX_GPIO_H
+#define __ASM_MIPS_MACH_BCM63XX_GPIO_H
+
+#include <bcm63xx_gpio.h>
+
+#define gpio_to_irq(gpio) -1
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+
+#define gpio_cansleep __gpio_cansleep
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_MIPS_MACH_BCM63XX_GPIO_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/war.h b/arch/mips/include/asm/mach-bcm63xx/war.h
new file mode 100644
index 00000000..8e3f3fdf
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_BCM63XX_WAR_H
+#define __ASM_MIPS_MACH_BCM63XX_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_BCM63XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
new file mode 100644
index 00000000..0d5a42b5
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -0,0 +1,90 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 Cavium Networks
+ */
+#ifndef __ASM_MACH_CAVIUM_OCTEON_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_CAVIUM_OCTEON_CPU_FEATURE_OVERRIDES_H
+
+#include <linux/types.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Cavium Octeons are MIPS64v2 processors
+ */
+#define cpu_dcache_line_size() 128
+#define cpu_icache_line_size() 128
+
+
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 0
+#define cpu_has_tx39_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+
+#define cpu_has_llsc 1
+/*
+ * We Disable LL/SC on non SMP systems as it is faster to disable
+ * interrupts for atomic access than a LL/SC.
+ */
+#ifdef CONFIG_SMP
+# define kernel_uses_llsc 1
+#else
+# define kernel_uses_llsc 0
+#endif
+#define cpu_has_vtag_icache 1
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_64bits 1
+#define cpu_has_octeon_cache 1
+#define cpu_has_saa octeon_has_saa()
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 1
+#define cpu_has_mips_r2_exec_hazard 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+#define cpu_has_vint 0
+#define cpu_has_veic 0
+#define cpu_hwrena_impl_bits 0xc0000000
+
+#define kernel_uses_smartmips_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
+
+#define ARCH_HAS_IRQ_PER_CPU 1
+#define ARCH_HAS_SPINLOCK_PREFETCH 1
+#define spin_lock_prefetch(x) prefetch(x)
+#define PREFETCH_STRIDE 128
+
+#ifdef __OCTEON__
+/*
+ * All gcc versions that have OCTEON support define __OCTEON__ and have the
+ * __builtin_popcount support.
+ */
+#define ARCH_HAS_USABLE_BUILTIN_POPCOUNT 1
+#endif
+
+static inline int octeon_has_saa(void)
+{
+ int id;
+ asm volatile ("mfc0 %0, $15,0" : "=r" (id));
+ return id >= 0x000d0300;
+}
+
+/*
+ * The last 256MB are reserved for device to device mappings and the
+ * BAR1 hole.
+ */
+#define MAX_DMA32_PFN (((1ULL << 32) - (1ULL << 28)) >> PAGE_SHIFT)
+
+#endif
diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
new file mode 100644
index 00000000..be8fb424
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
@@ -0,0 +1,72 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
+ *
+ *
+ * Similar to mach-generic/dma-coherence.h except
+ * plat_device_is_coherent hard coded to return 1.
+ *
+ */
+#ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
+#define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
+
+struct device;
+
+extern void octeon_pci_dma_init(void);
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+ size_t size)
+{
+ BUG();
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ BUG();
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ BUG();
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ BUG();
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ BUG();
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+ return 1;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ BUG();
+}
+
+dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
+phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
+
+struct dma_map_ops;
+extern struct dma_map_ops *octeon_pci_dma_map_ops;
+extern char *octeon_swiotlb;
+
+#endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
new file mode 100644
index 00000000..5b05f186
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -0,0 +1,101 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004-2008 Cavium Networks
+ */
+#ifndef __OCTEON_IRQ_H__
+#define __OCTEON_IRQ_H__
+
+#define NR_IRQS OCTEON_IRQ_LAST
+#define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0
+
+enum octeon_irq {
+/* 1 - 8 represent the 8 MIPS standard interrupt sources */
+ OCTEON_IRQ_SW0 = 1,
+ OCTEON_IRQ_SW1,
+/* CIU0, CUI2, CIU4 are 3, 4, 5 */
+ OCTEON_IRQ_5 = 6,
+ OCTEON_IRQ_PERF,
+ OCTEON_IRQ_TIMER,
+/* sources in CIU_INTX_EN0 */
+ OCTEON_IRQ_WORKQ0,
+ OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16,
+ OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16,
+ OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,
+ OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,
+ OCTEON_IRQ_MBOX1,
+ OCTEON_IRQ_UART0,
+ OCTEON_IRQ_UART1,
+ OCTEON_IRQ_UART2,
+ OCTEON_IRQ_PCI_INT0,
+ OCTEON_IRQ_PCI_INT1,
+ OCTEON_IRQ_PCI_INT2,
+ OCTEON_IRQ_PCI_INT3,
+ OCTEON_IRQ_PCI_MSI0,
+ OCTEON_IRQ_PCI_MSI1,
+ OCTEON_IRQ_PCI_MSI2,
+ OCTEON_IRQ_PCI_MSI3,
+
+ OCTEON_IRQ_TWSI,
+ OCTEON_IRQ_TWSI2,
+ OCTEON_IRQ_RML,
+ OCTEON_IRQ_TRACE0,
+ OCTEON_IRQ_GMX_DRP0 = OCTEON_IRQ_TRACE0 + 4,
+ OCTEON_IRQ_IPD_DRP = OCTEON_IRQ_GMX_DRP0 + 5,
+ OCTEON_IRQ_KEY_ZERO,
+ OCTEON_IRQ_TIMER0,
+ OCTEON_IRQ_TIMER1,
+ OCTEON_IRQ_TIMER2,
+ OCTEON_IRQ_TIMER3,
+ OCTEON_IRQ_USB0,
+ OCTEON_IRQ_USB1,
+ OCTEON_IRQ_PCM,
+ OCTEON_IRQ_MPI,
+ OCTEON_IRQ_POWIQ,
+ OCTEON_IRQ_IPDPPTHR,
+ OCTEON_IRQ_MII0,
+ OCTEON_IRQ_MII1,
+ OCTEON_IRQ_BOOTDMA,
+
+ OCTEON_IRQ_NAND,
+ OCTEON_IRQ_MIO, /* Summary of MIO_BOOT_ERR */
+ OCTEON_IRQ_IOB, /* Summary of IOB_INT_SUM */
+ OCTEON_IRQ_FPA, /* Summary of FPA_INT_SUM */
+ OCTEON_IRQ_POW, /* Summary of POW_ECC_ERR */
+ OCTEON_IRQ_L2C, /* Summary of L2C_INT_STAT */
+ OCTEON_IRQ_IPD, /* Summary of IPD_INT_SUM */
+ OCTEON_IRQ_PIP, /* Summary of PIP_INT_REG */
+ OCTEON_IRQ_PKO, /* Summary of PKO_REG_ERROR */
+ OCTEON_IRQ_ZIP, /* Summary of ZIP_ERROR */
+ OCTEON_IRQ_TIM, /* Summary of TIM_REG_ERROR */
+ OCTEON_IRQ_RAD, /* Summary of RAD_REG_ERROR */
+ OCTEON_IRQ_KEY, /* Summary of KEY_INT_SUM */
+ OCTEON_IRQ_DFA, /* Summary of DFA */
+ OCTEON_IRQ_USBCTL, /* Summary of USBN0_INT_SUM */
+ OCTEON_IRQ_SLI, /* Summary of SLI_INT_SUM */
+ OCTEON_IRQ_DPI, /* Summary of DPI_INT_SUM */
+ OCTEON_IRQ_AGX0, /* Summary of GMX0*+PCS0_INT*_REG */
+ OCTEON_IRQ_AGL = OCTEON_IRQ_AGX0 + 5,
+ OCTEON_IRQ_PTP,
+ OCTEON_IRQ_PEM0,
+ OCTEON_IRQ_PEM1,
+ OCTEON_IRQ_SRIO0,
+ OCTEON_IRQ_SRIO1,
+ OCTEON_IRQ_LMC0,
+ OCTEON_IRQ_DFM = OCTEON_IRQ_LMC0 + 4, /* Summary of DFM */
+ OCTEON_IRQ_RST,
+};
+
+#ifdef CONFIG_PCI_MSI
+/* 152 - 407 represent the MSI interrupts 0-255 */
+#define OCTEON_IRQ_MSI_BIT0 (OCTEON_IRQ_RST + 1)
+
+#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255)
+#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1)
+#else
+#define OCTEON_IRQ_LAST (OCTEON_IRQ_RST + 1)
+#endif
+
+#endif
diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
new file mode 100644
index 00000000..dedef7d2
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
@@ -0,0 +1,136 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2008 Cavium Networks, Inc
+ */
+#ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
+#define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
+
+
+#define CP0_CYCLE_COUNTER $9, 6
+#define CP0_CVMCTL_REG $9, 7
+#define CP0_CVMMEMCTL_REG $11,7
+#define CP0_PRID_REG $15, 0
+#define CP0_PRID_OCTEON_PASS1 0x000d0000
+#define CP0_PRID_OCTEON_CN30XX 0x000d0200
+
+.macro kernel_entry_setup
+ # Registers set by bootloader:
+ # (only 32 bits set by bootloader, all addresses are physical
+ # addresses, and need to have the appropriate memory region set
+ # by the kernel
+ # a0 = argc
+ # a1 = argv (kseg0 compat addr)
+ # a2 = 1 if init core, zero otherwise
+ # a3 = address of boot descriptor block
+ .set push
+ .set arch=octeon
+ # Read the cavium mem control register
+ dmfc0 v0, CP0_CVMMEMCTL_REG
+ # Clear the lower 6 bits, the CVMSEG size
+ dins v0, $0, 0, 6
+ ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
+ dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register
+ dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register
+#ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
+ # Disable unaligned load/store support but leave HW fixup enabled
+ or v0, v0, 0x5001
+ xor v0, v0, 0x1001
+#else
+ # Disable unaligned load/store and HW fixup support
+ or v0, v0, 0x5001
+ xor v0, v0, 0x5001
+#endif
+ # Read the processor ID register
+ mfc0 v1, CP0_PRID_REG
+ # Disable instruction prefetching (Octeon Pass1 errata)
+ or v0, v0, 0x2000
+ # Skip reenable of prefetching for Octeon Pass1
+ beq v1, CP0_PRID_OCTEON_PASS1, skip
+ nop
+ # Reenable instruction prefetching, not on Pass1
+ xor v0, v0, 0x2000
+ # Strip off pass number off of processor id
+ srl v1, 8
+ sll v1, 8
+ # CN30XX needs some extra stuff turned off for better performance
+ bne v1, CP0_PRID_OCTEON_CN30XX, skip
+ nop
+ # CN30XX Use random Icache replacement
+ or v0, v0, 0x400
+ # CN30XX Disable instruction prefetching
+ or v0, v0, 0x2000
+skip:
+ # First clear off CvmCtl[IPPCI] bit and move the performance
+ # counters interrupt to IRQ 6
+ li v1, ~(7 << 7)
+ and v0, v0, v1
+ ori v0, v0, (6 << 7)
+ # Write the cavium control register
+ dmtc0 v0, CP0_CVMCTL_REG
+ sync
+ # Flush dcache after config change
+ cache 9, 0($0)
+ # Get my core id
+ rdhwr v0, $0
+ # Jump the master to kernel_entry
+ bne a2, zero, octeon_main_processor
+ nop
+
+#ifdef CONFIG_SMP
+
+ #
+ # All cores other than the master need to wait here for SMP bootstrap
+ # to begin
+ #
+
+ # This is the variable where the next core to boot os stored
+ PTR_LA t0, octeon_processor_boot
+octeon_spin_wait_boot:
+ # Get the core id of the next to be booted
+ LONG_L t1, (t0)
+ # Keep looping if it isn't me
+ bne t1, v0, octeon_spin_wait_boot
+ nop
+ # Get my GP from the global variable
+ PTR_LA t0, octeon_processor_gp
+ LONG_L gp, (t0)
+ # Get my SP from the global variable
+ PTR_LA t0, octeon_processor_sp
+ LONG_L sp, (t0)
+ # Set the SP global variable to zero so the master knows we've started
+ LONG_S zero, (t0)
+#ifdef __OCTEON__
+ syncw
+ syncw
+#else
+ sync
+#endif
+ # Jump to the normal Linux SMP entry point
+ j smp_bootstrap
+ nop
+#else /* CONFIG_SMP */
+
+ #
+ # Someone tried to boot SMP with a non SMP kernel. All extra cores
+ # will halt here.
+ #
+octeon_wait_forever:
+ wait
+ b octeon_wait_forever
+ nop
+
+#endif /* CONFIG_SMP */
+octeon_main_processor:
+ .set pop
+.endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ .endm
+
+#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-cavium-octeon/war.h b/arch/mips/include/asm/mach-cavium-octeon/war.h
new file mode 100644
index 00000000..c4712d7c
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/war.h
@@ -0,0 +1,26 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2008 Cavium Networks <support@caviumnetworks.com>
+ */
+#ifndef __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H
+#define __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H */
diff --git a/arch/mips/include/asm/mach-cobalt/cobalt.h b/arch/mips/include/asm/mach-cobalt/cobalt.h
new file mode 100644
index 00000000..5b9fce73
--- /dev/null
+++ b/arch/mips/include/asm/mach-cobalt/cobalt.h
@@ -0,0 +1,22 @@
+/*
+ * The Cobalt board ID information.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997 Cobalt Microserver
+ * Copyright (C) 1997, 2003 Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 Liam Davies (ldavies@agile.tv)
+ */
+#ifndef __ASM_COBALT_H
+#define __ASM_COBALT_H
+
+extern int cobalt_board_id;
+
+#define COBALT_BRD_ID_QUBE1 0x3
+#define COBALT_BRD_ID_RAQ1 0x4
+#define COBALT_BRD_ID_QUBE2 0x5
+#define COBALT_BRD_ID_RAQ2 0x6
+
+#endif /* __ASM_COBALT_H */
diff --git a/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h
new file mode 100644
index 00000000..b3314cf5
--- /dev/null
+++ b/arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h
@@ -0,0 +1,56 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006, 07 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_COBALT_CPU_FEATURE_OVERRIDES_H
+#define __ASM_COBALT_CPU_FEATURE_OVERRIDES_H
+
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_fpu 1
+#define cpu_has_32fpr 1
+#define cpu_has_counter 1
+#define cpu_has_watch 0
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 0
+#define cpu_has_mcheck 0
+#define cpu_has_ejtag 0
+
+#define cpu_has_inclusive_pcaches 0
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+#define cpu_scache_line_size() 0
+
+#ifdef CONFIG_64BIT
+#define cpu_has_llsc 0
+#else
+#define cpu_has_llsc 1
+#endif
+
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+#define cpu_has_vtag_icache 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_icache_snoops_remote_store 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_COBALT_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-cobalt/irq.h b/arch/mips/include/asm/mach-cobalt/irq.h
new file mode 100644
index 00000000..9da9acf5
--- /dev/null
+++ b/arch/mips/include/asm/mach-cobalt/irq.h
@@ -0,0 +1,57 @@
+/*
+ * Cobalt IRQ definitions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997 Cobalt Microserver
+ * Copyright (C) 1997, 2003 Ralf Baechle
+ * Copyright (C) 2001-2003 Liam Davies (ldavies@agile.tv)
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ */
+#ifndef _ASM_COBALT_IRQ_H
+#define _ASM_COBALT_IRQ_H
+
+/*
+ * i8259 interrupts used on Cobalt:
+ *
+ * 8 - RTC
+ * 9 - PCI slot
+ * 14 - IDE0
+ * 15 - IDE1(no connector on board)
+ */
+#define I8259A_IRQ_BASE 0
+
+#define PCISLOT_IRQ (I8259A_IRQ_BASE + 9)
+
+/*
+ * CPU interrupts used on Cobalt:
+ *
+ * 0 - Software interrupt 0 (unused)
+ * 1 - Software interrupt 0 (unused)
+ * 2 - cascade GT64111
+ * 3 - ethernet or SCSI host controller
+ * 4 - ethernet
+ * 5 - 16550 UART
+ * 6 - cascade i8259
+ * 7 - CP0 counter
+ */
+#define MIPS_CPU_IRQ_BASE 16
+
+#define GT641XX_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 2)
+#define RAQ2_SCSI_IRQ (MIPS_CPU_IRQ_BASE + 3)
+#define ETH0_IRQ (MIPS_CPU_IRQ_BASE + 3)
+#define QUBE1_ETH0_IRQ (MIPS_CPU_IRQ_BASE + 4)
+#define ETH1_IRQ (MIPS_CPU_IRQ_BASE + 4)
+#define SERIAL_IRQ (MIPS_CPU_IRQ_BASE + 5)
+#define SCSI_IRQ (MIPS_CPU_IRQ_BASE + 5)
+#define I8259_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 6)
+
+#define GT641XX_IRQ_BASE 24
+
+#include <asm/irq_gt641xx.h>
+
+#define NR_IRQS (GT641XX_PCI_INT3_IRQ + 1)
+
+#endif /* _ASM_COBALT_IRQ_H */
diff --git a/arch/mips/include/asm/mach-cobalt/mach-gt64120.h b/arch/mips/include/asm/mach-cobalt/mach-gt64120.h
new file mode 100644
index 00000000..f8afec3f
--- /dev/null
+++ b/arch/mips/include/asm/mach-cobalt/mach-gt64120.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2006 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef _COBALT_MACH_GT64120_H
+#define _COBALT_MACH_GT64120_H
+
+/*
+ * Cobalt uses GT64111. GT64111 is almost the same as GT64120.
+ */
+
+#define GT64120_BASE CKSEG1ADDR(GT_DEF_BASE)
+
+#endif /* _COBALT_MACH_GT64120_H */
diff --git a/arch/mips/include/asm/mach-cobalt/war.h b/arch/mips/include/asm/mach-cobalt/war.h
new file mode 100644
index 00000000..97884fd1
--- /dev/null
+++ b/arch/mips/include/asm/mach-cobalt/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_COBALT_WAR_H
+#define __ASM_MIPS_MACH_COBALT_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_COBALT_WAR_H */
diff --git a/arch/mips/include/asm/mach-db1x00/bcsr.h b/arch/mips/include/asm/mach-db1x00/bcsr.h
new file mode 100644
index 00000000..618d2de0
--- /dev/null
+++ b/arch/mips/include/asm/mach-db1x00/bcsr.h
@@ -0,0 +1,238 @@
+/*
+ * bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction.
+ *
+ * All Alchemy development boards (except, of course, the weird PB1000)
+ * have a few registers in a CPLD with standardised layout; they mostly
+ * only differ in base address and bit meanings in the RESETS and BOARD
+ * registers.
+ *
+ * All data taken from the official AMD board documentation sheets.
+ */
+
+#ifndef _DB1XXX_BCSR_H_
+#define _DB1XXX_BCSR_H_
+
+
+/* BCSR base addresses on various boards. BCSR base 2 refers to the
+ * physical address of the first HEXLEDS register, which is usually
+ * a variable offset from the WHOAMI register.
+ */
+
+/* DB1000, DB1100, DB1500, PB1100, PB1500 */
+#define DB1000_BCSR_PHYS_ADDR 0x0E000000
+#define DB1000_BCSR_HEXLED_OFS 0x01000000
+
+#define DB1550_BCSR_PHYS_ADDR 0x0F000000
+#define DB1550_BCSR_HEXLED_OFS 0x00400000
+
+#define PB1550_BCSR_PHYS_ADDR 0x0F000000
+#define PB1550_BCSR_HEXLED_OFS 0x00800000
+
+#define DB1200_BCSR_PHYS_ADDR 0x19800000
+#define DB1200_BCSR_HEXLED_OFS 0x00400000
+
+#define PB1200_BCSR_PHYS_ADDR 0x0D800000
+#define PB1200_BCSR_HEXLED_OFS 0x00400000
+
+
+enum bcsr_id {
+ /* BCSR base 1 */
+ BCSR_WHOAMI = 0,
+ BCSR_STATUS,
+ BCSR_SWITCHES,
+ BCSR_RESETS,
+ BCSR_PCMCIA,
+ BCSR_BOARD,
+ BCSR_LEDS,
+ BCSR_SYSTEM,
+ /* Au1200/1300 based boards */
+ BCSR_INTCLR,
+ BCSR_INTSET,
+ BCSR_MASKCLR,
+ BCSR_MASKSET,
+ BCSR_SIGSTAT,
+ BCSR_INTSTAT,
+
+ /* BCSR base 2 */
+ BCSR_HEXLEDS,
+ BCSR_RSVD1,
+ BCSR_HEXCLEAR,
+
+ BCSR_CNT,
+};
+
+/* register offsets, valid for all Db1xxx/Pb1xxx boards */
+#define BCSR_REG_WHOAMI 0x00
+#define BCSR_REG_STATUS 0x04
+#define BCSR_REG_SWITCHES 0x08
+#define BCSR_REG_RESETS 0x0c
+#define BCSR_REG_PCMCIA 0x10
+#define BCSR_REG_BOARD 0x14
+#define BCSR_REG_LEDS 0x18
+#define BCSR_REG_SYSTEM 0x1c
+/* Au1200/Au1300 based boards: CPLD IRQ muxer */
+#define BCSR_REG_INTCLR 0x20
+#define BCSR_REG_INTSET 0x24
+#define BCSR_REG_MASKCLR 0x28
+#define BCSR_REG_MASKSET 0x2c
+#define BCSR_REG_SIGSTAT 0x30
+#define BCSR_REG_INTSTAT 0x34
+
+/* hexled control, offset from BCSR base 2 */
+#define BCSR_REG_HEXLEDS 0x00
+#define BCSR_REG_HEXCLEAR 0x08
+
+/*
+ * Register Bits and Pieces.
+ */
+#define BCSR_WHOAMI_DCID(x) ((x) & 0xf)
+#define BCSR_WHOAMI_CPLD(x) (((x) >> 4) & 0xf)
+#define BCSR_WHOAMI_BOARD(x) (((x) >> 8) & 0xf)
+
+/* register "WHOAMI" bits 11:8 identify the board */
+enum bcsr_whoami_boards {
+ BCSR_WHOAMI_PB1500 = 1,
+ BCSR_WHOAMI_PB1500R2,
+ BCSR_WHOAMI_PB1100,
+ BCSR_WHOAMI_DB1000,
+ BCSR_WHOAMI_DB1100,
+ BCSR_WHOAMI_DB1500,
+ BCSR_WHOAMI_DB1550,
+ BCSR_WHOAMI_PB1550_DDR,
+ BCSR_WHOAMI_PB1550 = BCSR_WHOAMI_PB1550_DDR,
+ BCSR_WHOAMI_PB1550_SDR,
+ BCSR_WHOAMI_PB1200_DDR1,
+ BCSR_WHOAMI_PB1200 = BCSR_WHOAMI_PB1200_DDR1,
+ BCSR_WHOAMI_PB1200_DDR2,
+ BCSR_WHOAMI_DB1200,
+};
+
+/* STATUS reg. Unless otherwise noted, they're valid on all boards.
+ * PB1200 = DB1200.
+ */
+#define BCSR_STATUS_PC0VS 0x0003
+#define BCSR_STATUS_PC1VS 0x000C
+#define BCSR_STATUS_PC0FI 0x0010
+#define BCSR_STATUS_PC1FI 0x0020
+#define BCSR_STATUS_PB1550_SWAPBOOT 0x0040
+#define BCSR_STATUS_SRAMWIDTH 0x0080
+#define BCSR_STATUS_FLASHBUSY 0x0100
+#define BCSR_STATUS_ROMBUSY 0x0400
+#define BCSR_STATUS_SD0WP 0x0400 /* DB1200 */
+#define BCSR_STATUS_SD1WP 0x0800
+#define BCSR_STATUS_USBOTGID 0x0800 /* PB/DB1550 */
+#define BCSR_STATUS_DB1000_SWAPBOOT 0x2000
+#define BCSR_STATUS_DB1200_SWAPBOOT 0x0040 /* DB1200 */
+#define BCSR_STATUS_IDECBLID 0x0200 /* DB1200 */
+#define BCSR_STATUS_DB1200_U0RXD 0x1000 /* DB1200 */
+#define BCSR_STATUS_DB1200_U1RXD 0x2000 /* DB1200 */
+#define BCSR_STATUS_FLASHDEN 0xC000
+#define BCSR_STATUS_DB1550_U0RXD 0x1000 /* DB1550 */
+#define BCSR_STATUS_DB1550_U3RXD 0x2000 /* DB1550 */
+#define BCSR_STATUS_PB1550_U0RXD 0x1000 /* PB1550 */
+#define BCSR_STATUS_PB1550_U1RXD 0x2000 /* PB1550 */
+#define BCSR_STATUS_PB1550_U3RXD 0x8000 /* PB1550 */
+
+
+/* DB/PB1000,1100,1500,1550 */
+#define BCSR_RESETS_PHY0 0x0001
+#define BCSR_RESETS_PHY1 0x0002
+#define BCSR_RESETS_DC 0x0004
+#define BCSR_RESETS_FIR_SEL 0x2000
+#define BCSR_RESETS_IRDA_MODE_MASK 0xC000
+#define BCSR_RESETS_IRDA_MODE_FULL 0x0000
+#define BCSR_RESETS_PB1550_WSCFSM 0x2000
+#define BCSR_RESETS_IRDA_MODE_OFF 0x4000
+#define BCSR_RESETS_IRDA_MODE_2_3 0x8000
+#define BCSR_RESETS_IRDA_MODE_1_3 0xC000
+#define BCSR_RESETS_DMAREQ 0x8000 /* PB1550 */
+
+#define BCSR_BOARD_PCIM66EN 0x0001
+#define BCSR_BOARD_SD0PWR 0x0040
+#define BCSR_BOARD_SD1PWR 0x0080
+#define BCSR_BOARD_PCIM33 0x0100
+#define BCSR_BOARD_PCIEXTARB 0x0200
+#define BCSR_BOARD_GPIO200RST 0x0400
+#define BCSR_BOARD_PCICLKOUT 0x0800
+#define BCSR_BOARD_PCICFG 0x1000
+#define BCSR_BOARD_SPISEL 0x4000 /* PB/DB1550 */
+#define BCSR_BOARD_SD0WP 0x4000 /* DB1100 */
+#define BCSR_BOARD_SD1WP 0x8000 /* DB1100 */
+
+
+/* DB/PB1200 */
+#define BCSR_RESETS_ETH 0x0001
+#define BCSR_RESETS_CAMERA 0x0002
+#define BCSR_RESETS_DC 0x0004
+#define BCSR_RESETS_IDE 0x0008
+#define BCSR_RESETS_TV 0x0010 /* DB1200 */
+/* Not resets but in the same register */
+#define BCSR_RESETS_PWMR1MUX 0x0800 /* DB1200 */
+#define BCSR_RESETS_PB1200_WSCFSM 0x0800 /* PB1200 */
+#define BCSR_RESETS_PSC0MUX 0x1000
+#define BCSR_RESETS_PSC1MUX 0x2000
+#define BCSR_RESETS_SPISEL 0x4000
+#define BCSR_RESETS_SD1MUX 0x8000 /* PB1200 */
+
+#define BCSR_BOARD_LCDVEE 0x0001
+#define BCSR_BOARD_LCDVDD 0x0002
+#define BCSR_BOARD_LCDBL 0x0004
+#define BCSR_BOARD_CAMSNAP 0x0010
+#define BCSR_BOARD_CAMPWR 0x0020
+#define BCSR_BOARD_SD0PWR 0x0040
+
+
+#define BCSR_SWITCHES_DIP 0x00FF
+#define BCSR_SWITCHES_DIP_1 0x0080
+#define BCSR_SWITCHES_DIP_2 0x0040
+#define BCSR_SWITCHES_DIP_3 0x0020
+#define BCSR_SWITCHES_DIP_4 0x0010
+#define BCSR_SWITCHES_DIP_5 0x0008
+#define BCSR_SWITCHES_DIP_6 0x0004
+#define BCSR_SWITCHES_DIP_7 0x0002
+#define BCSR_SWITCHES_DIP_8 0x0001
+#define BCSR_SWITCHES_ROTARY 0x0F00
+
+
+#define BCSR_PCMCIA_PC0VPP 0x0003
+#define BCSR_PCMCIA_PC0VCC 0x000C
+#define BCSR_PCMCIA_PC0DRVEN 0x0010
+#define BCSR_PCMCIA_PC0RST 0x0080
+#define BCSR_PCMCIA_PC1VPP 0x0300
+#define BCSR_PCMCIA_PC1VCC 0x0C00
+#define BCSR_PCMCIA_PC1DRVEN 0x1000
+#define BCSR_PCMCIA_PC1RST 0x8000
+
+
+#define BCSR_LEDS_DECIMALS 0x0003
+#define BCSR_LEDS_LED0 0x0100
+#define BCSR_LEDS_LED1 0x0200
+#define BCSR_LEDS_LED2 0x0400
+#define BCSR_LEDS_LED3 0x0800
+
+
+#define BCSR_SYSTEM_RESET 0x8000 /* clear to reset */
+#define BCSR_SYSTEM_PWROFF 0x4000 /* set to power off */
+#define BCSR_SYSTEM_VDDI 0x001F /* PB1xxx boards */
+
+
+
+
+/* initialize BCSR for a board. Provide the PHYSICAL addresses of both
+ * BCSR spaces.
+ */
+void __init bcsr_init(unsigned long bcsr1_phys, unsigned long bcsr2_phys);
+
+/* read a board register */
+unsigned short bcsr_read(enum bcsr_id reg);
+
+/* write to a board register */
+void bcsr_write(enum bcsr_id reg, unsigned short val);
+
+/* modify a register. clear bits set in 'clr', set bits set in 'set' */
+void bcsr_mod(enum bcsr_id reg, unsigned short clr, unsigned short set);
+
+/* install CPLD IRQ demuxer (DB1200/PB1200) */
+void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq);
+
+#endif
diff --git a/arch/mips/include/asm/mach-db1x00/db1200.h b/arch/mips/include/asm/mach-db1x00/db1200.h
new file mode 100644
index 00000000..3404248f
--- /dev/null
+++ b/arch/mips/include/asm/mach-db1x00/db1200.h
@@ -0,0 +1,86 @@
+/*
+ * AMD Alchemy DBAu1200 Reference Board
+ * Board register defines.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_DB1200_H
+#define __ASM_DB1200_H
+
+#include <linux/types.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+
+/* Bit positions for the different interrupt sources */
+#define BCSR_INT_IDE 0x0001
+#define BCSR_INT_ETH 0x0002
+#define BCSR_INT_PC0 0x0004
+#define BCSR_INT_PC0STSCHG 0x0008
+#define BCSR_INT_PC1 0x0010
+#define BCSR_INT_PC1STSCHG 0x0020
+#define BCSR_INT_DC 0x0040
+#define BCSR_INT_FLASHBUSY 0x0080
+#define BCSR_INT_PC0INSERT 0x0100
+#define BCSR_INT_PC0EJECT 0x0200
+#define BCSR_INT_PC1INSERT 0x0400
+#define BCSR_INT_PC1EJECT 0x0800
+#define BCSR_INT_SD0INSERT 0x1000
+#define BCSR_INT_SD0EJECT 0x2000
+
+#define IDE_PHYS_ADDR 0x18800000
+#define IDE_REG_SHIFT 5
+#define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1
+#define IDE_RQSIZE 128
+
+#define DB1200_IDE_PHYS_ADDR IDE_PHYS_ADDR
+#define DB1200_IDE_PHYS_LEN (16 << IDE_REG_SHIFT)
+#define DB1200_ETH_PHYS_ADDR 0x19000300
+#define DB1200_NAND_PHYS_ADDR 0x20000000
+
+/*
+ * External Interrupts for DBAu1200 as of 8/6/2004.
+ * Bit positions in the CPLD registers can be calculated by taking
+ * the interrupt define and subtracting the DB1200_INT_BEGIN value.
+ *
+ * Example: IDE bis pos is = 64 - 64
+ * ETH bit pos is = 65 - 64
+ */
+enum external_db1200_ints {
+ DB1200_INT_BEGIN = AU1000_MAX_INTR + 1,
+
+ DB1200_IDE_INT = DB1200_INT_BEGIN,
+ DB1200_ETH_INT,
+ DB1200_PC0_INT,
+ DB1200_PC0_STSCHG_INT,
+ DB1200_PC1_INT,
+ DB1200_PC1_STSCHG_INT,
+ DB1200_DC_INT,
+ DB1200_FLASHBUSY_INT,
+ DB1200_PC0_INSERT_INT,
+ DB1200_PC0_EJECT_INT,
+ DB1200_PC1_INSERT_INT,
+ DB1200_PC1_EJECT_INT,
+ DB1200_SD0_INSERT_INT,
+ DB1200_SD0_EJECT_INT,
+
+ DB1200_INT_END = DB1200_INT_BEGIN + 15,
+};
+
+#endif /* __ASM_DB1200_H */
diff --git a/arch/mips/include/asm/mach-db1x00/db1x00.h b/arch/mips/include/asm/mach-db1x00/db1x00.h
new file mode 100644
index 00000000..a919dac5
--- /dev/null
+++ b/arch/mips/include/asm/mach-db1x00/db1x00.h
@@ -0,0 +1,79 @@
+/*
+ * AMD Alchemy DBAu1x00 Reference Boards
+ *
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_DB1X00_H
+#define __ASM_DB1X00_H
+
+#include <asm/mach-au1x00/au1xxx_psc.h>
+
+#ifdef CONFIG_MIPS_DB1550
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX
+
+#define SPI_PSC_BASE PSC0_BASE_ADDR
+#define AC97_PSC_BASE PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE PSC2_BASE_ADDR
+#define I2S_PSC_BASE PSC3_BASE_ADDR
+
+#define NAND_PHYS_ADDR 0x20000000
+
+#endif
+
+/*
+ * NAND defines
+ *
+ * Timing values as described in databook, * ns value stripped of the
+ * lower 2 bits.
+ * These defines are here rather than an Au1550 generic file because
+ * the parts chosen on another board may be different and may require
+ * different timings.
+ */
+#define NAND_T_H (18 >> 2)
+#define NAND_T_PUL (30 >> 2)
+#define NAND_T_SU (30 >> 2)
+#define NAND_T_WH (30 >> 2)
+
+/* Bitfield shift amounts */
+#define NAND_T_H_SHIFT 0
+#define NAND_T_PUL_SHIFT 4
+#define NAND_T_SU_SHIFT 8
+#define NAND_T_WH_SHIFT 12
+
+#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
+ ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+ ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
+ ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT))
+#define NAND_CS 1
+
+/* Should be done by YAMON */
+#define NAND_STCFG 0x00400005 /* 8-bit NAND */
+#define NAND_STTIME 0x00007774 /* valid for 396 MHz SD=2 only */
+#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
+
+#endif /* __ASM_DB1X00_H */
diff --git a/arch/mips/include/asm/mach-dec/mc146818rtc.h b/arch/mips/include/asm/mach-dec/mc146818rtc.h
new file mode 100644
index 00000000..6724e99e
--- /dev/null
+++ b/arch/mips/include/asm/mach-dec/mc146818rtc.h
@@ -0,0 +1,43 @@
+/*
+ * RTC definitions for DECstation style attached Dallas DS1287 chip.
+ *
+ * Copyright (C) 1998, 2001 by Ralf Baechle
+ * Copyright (C) 1998 by Harald Koerfgen
+ * Copyright (C) 2002, 2005 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MIPS_DEC_RTC_DEC_H
+#define __ASM_MIPS_DEC_RTC_DEC_H
+
+#include <linux/types.h>
+#include <asm/addrspace.h>
+#include <asm/dec/system.h>
+
+extern volatile u8 *dec_rtc_base;
+
+#define ARCH_RTC_LOCATION
+
+#define RTC_PORT(x) CPHYSADDR((long)dec_rtc_base)
+#define RTC_IO_EXTENT dec_kn_slot_size
+#define RTC_IOMAPPED 0
+#undef RTC_IRQ
+
+#define RTC_DEC_YEAR 0x3f /* Where we store the real year on DECs. */
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+ return dec_rtc_base[addr * 4];
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+ dec_rtc_base[addr * 4] = data;
+}
+
+#define RTC_ALWAYS_BCD 0
+
+#endif /* __ASM_MIPS_DEC_RTC_DEC_H */
diff --git a/arch/mips/include/asm/mach-dec/war.h b/arch/mips/include/asm/mach-dec/war.h
new file mode 100644
index 00000000..ca5e2ef9
--- /dev/null
+++ b/arch/mips/include/asm/mach-dec/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_DEC_WAR_H
+#define __ASM_MIPS_MACH_DEC_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_DEC_WAR_H */
diff --git a/arch/mips/include/asm/mach-emma2rh/irq.h b/arch/mips/include/asm/mach-emma2rh/irq.h
new file mode 100644
index 00000000..5439eb85
--- /dev/null
+++ b/arch/mips/include/asm/mach-emma2rh/irq.h
@@ -0,0 +1,15 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#ifndef __ASM_MACH_EMMA2RH_IRQ_H
+#define __ASM_MACH_EMMA2RH_IRQ_H
+
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_EMMA2RH_IRQ_H */
diff --git a/arch/mips/include/asm/mach-emma2rh/war.h b/arch/mips/include/asm/mach-emma2rh/war.h
new file mode 100644
index 00000000..b660a4c3
--- /dev/null
+++ b/arch/mips/include/asm/mach-emma2rh/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_EMMA2RH_WAR_H
+#define __ASM_MIPS_MACH_EMMA2RH_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_EMMA2RH_WAR_H */
diff --git a/arch/mips/include/asm/mach-generic/cpu-feature-overrides.h b/arch/mips/include/asm/mach-generic/cpu-feature-overrides.h
new file mode 100644
index 00000000..7c185bb0
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/cpu-feature-overrides.h
@@ -0,0 +1,13 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Ralf Baechle
+ */
+#ifndef __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H
+
+/* Intentionally empty file ... */
+
+#endif /* __ASM_MACH_GENERIC_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h
new file mode 100644
index 00000000..8da98073
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/dma-coherence.h
@@ -0,0 +1,71 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
+ *
+ */
+#ifndef __ASM_MACH_GENERIC_DMA_COHERENCE_H
+#define __ASM_MACH_GENERIC_DMA_COHERENCE_H
+
+struct device;
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+ size_t size)
+{
+ return virt_to_phys(addr);
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ return page_to_phys(page);
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return dma_addr;
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+#ifdef CONFIG_DMA_COHERENT
+ return 1;
+#endif
+#ifdef CONFIG_DMA_NONCOHERENT
+ return 0;
+#endif
+}
+
+#endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-generic/floppy.h b/arch/mips/include/asm/mach-generic/floppy.h
new file mode 100644
index 00000000..001a8ce1
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/floppy.h
@@ -0,0 +1,139 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 2003 by Ralf Baechle
+ */
+#ifndef __ASM_MACH_GENERIC_FLOPPY_H
+#define __ASM_MACH_GENERIC_FLOPPY_H
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/dma.h>
+#include <asm/floppy.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+
+/*
+ * How to access the FDC's registers.
+ */
+static inline unsigned char fd_inb(unsigned int port)
+{
+ return inb_p(port);
+}
+
+static inline void fd_outb(unsigned char value, unsigned int port)
+{
+ outb_p(value, port);
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static inline void fd_enable_dma(void)
+{
+ enable_dma(FLOPPY_DMA);
+}
+
+static inline void fd_disable_dma(void)
+{
+ disable_dma(FLOPPY_DMA);
+}
+
+static inline int fd_request_dma(void)
+{
+ return request_dma(FLOPPY_DMA, "floppy");
+}
+
+static inline void fd_free_dma(void)
+{
+ free_dma(FLOPPY_DMA);
+}
+
+static inline void fd_clear_dma_ff(void)
+{
+ clear_dma_ff(FLOPPY_DMA);
+}
+
+static inline void fd_set_dma_mode(char mode)
+{
+ set_dma_mode(FLOPPY_DMA, mode);
+}
+
+static inline void fd_set_dma_addr(char *addr)
+{
+ set_dma_addr(FLOPPY_DMA, (unsigned long) addr);
+}
+
+static inline void fd_set_dma_count(unsigned int count)
+{
+ set_dma_count(FLOPPY_DMA, count);
+}
+
+static inline int fd_get_dma_residue(void)
+{
+ return get_dma_residue(FLOPPY_DMA);
+}
+
+static inline void fd_enable_irq(void)
+{
+ enable_irq(FLOPPY_IRQ);
+}
+
+static inline void fd_disable_irq(void)
+{
+ disable_irq(FLOPPY_IRQ);
+}
+
+static inline int fd_request_irq(void)
+{
+ return request_irq(FLOPPY_IRQ, floppy_interrupt,
+ IRQF_DISABLED, "floppy", NULL);
+}
+
+static inline void fd_free_irq(void)
+{
+ free_irq(FLOPPY_IRQ, NULL);
+}
+
+#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL);
+
+
+static inline unsigned long fd_getfdaddr1(void)
+{
+ return 0x3f0;
+}
+
+static inline unsigned long fd_dma_mem_alloc(unsigned long size)
+{
+ unsigned long mem;
+
+ mem = __get_dma_pages(GFP_KERNEL, get_order(size));
+
+ return mem;
+}
+
+static inline void fd_dma_mem_free(unsigned long addr, unsigned long size)
+{
+ free_pages(addr, get_order(size));
+}
+
+static inline unsigned long fd_drive_type(unsigned long n)
+{
+ if (n == 0)
+ return 4; /* 3,5", 1.44mb */
+
+ return 0;
+}
+
+#endif /* __ASM_MACH_GENERIC_FLOPPY_H */
diff --git a/arch/mips/include/asm/mach-generic/gpio.h b/arch/mips/include/asm/mach-generic/gpio.h
new file mode 100644
index 00000000..b4e70208
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/gpio.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_MACH_GENERIC_GPIO_H
+#define __ASM_MACH_GENERIC_GPIO_H
+
+#ifdef CONFIG_GPIOLIB
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#else
+int gpio_request(unsigned gpio, const char *label);
+void gpio_free(unsigned gpio);
+int gpio_direction_input(unsigned gpio);
+int gpio_direction_output(unsigned gpio, int value);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+#endif
+int gpio_to_irq(unsigned gpio);
+int irq_to_gpio(unsigned irq);
+
+#include <asm-generic/gpio.h> /* cansleep wrappers */
+
+#endif /* __ASM_MACH_GENERIC_GPIO_H */
diff --git a/arch/mips/include/asm/mach-generic/ide.h b/arch/mips/include/asm/mach-generic/ide.h
new file mode 100644
index 00000000..9c93a5b3
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/ide.h
@@ -0,0 +1,138 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994-1996 Linus Torvalds & authors
+ *
+ * Copied from i386; many of the especially older MIPS or ISA-based platforms
+ * are basically identical. Using this file probably implies i8259 PIC
+ * support in a system but the very least interrupt numbers 0 - 15 need to
+ * be put aside for legacy devices.
+ */
+#ifndef __ASM_MACH_GENERIC_IDE_H
+#define __ASM_MACH_GENERIC_IDE_H
+
+#ifdef __KERNEL__
+
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <asm/processor.h>
+
+/* MIPS port and memory-mapped I/O string operations. */
+static inline void __ide_flush_prologue(void)
+{
+#ifdef CONFIG_SMP
+ if (cpu_has_dc_aliases)
+ preempt_disable();
+#endif
+}
+
+static inline void __ide_flush_epilogue(void)
+{
+#ifdef CONFIG_SMP
+ if (cpu_has_dc_aliases)
+ preempt_enable();
+#endif
+}
+
+static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size)
+{
+ if (cpu_has_dc_aliases) {
+ unsigned long end = addr + size;
+
+ while (addr < end) {
+ local_flush_data_cache_page((void *)addr);
+ addr += PAGE_SIZE;
+ }
+ }
+}
+
+/*
+ * insw() and gang might be called with interrupts disabled, so we can't
+ * send IPIs for flushing due to the potencial of deadlocks, see the comment
+ * above smp_call_function() in arch/mips/kernel/smp.c. We work around the
+ * problem by disabling preemption so we know we actually perform the flush
+ * on the processor that actually has the lines to be flushed which hopefully
+ * is even better for performance anyway.
+ */
+static inline void __ide_insw(unsigned long port, void *addr,
+ unsigned int count)
+{
+ __ide_flush_prologue();
+ insw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+ __ide_flush_epilogue();
+}
+
+static inline void __ide_insl(unsigned long port, void *addr, unsigned int count)
+{
+ __ide_flush_prologue();
+ insl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+ __ide_flush_epilogue();
+}
+
+static inline void __ide_outsw(unsigned long port, const void *addr,
+ unsigned long count)
+{
+ __ide_flush_prologue();
+ outsw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+ __ide_flush_epilogue();
+}
+
+static inline void __ide_outsl(unsigned long port, const void *addr,
+ unsigned long count)
+{
+ __ide_flush_prologue();
+ outsl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+ __ide_flush_epilogue();
+}
+
+static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count)
+{
+ __ide_flush_prologue();
+ readsw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+ __ide_flush_epilogue();
+}
+
+static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count)
+{
+ __ide_flush_prologue();
+ readsl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+ __ide_flush_epilogue();
+}
+
+static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count)
+{
+ __ide_flush_prologue();
+ writesw(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 2);
+ __ide_flush_epilogue();
+}
+
+static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count)
+{
+ __ide_flush_prologue();
+ writesl(port, addr, count);
+ __ide_flush_dcache_range((unsigned long)addr, count * 4);
+ __ide_flush_epilogue();
+}
+
+/* ide_insw calls insw, not __ide_insw. Why? */
+#undef insw
+#undef insl
+#undef outsw
+#undef outsl
+#define insw(port, addr, count) __ide_insw(port, addr, count)
+#define insl(port, addr, count) __ide_insl(port, addr, count)
+#define outsw(port, addr, count) __ide_outsw(port, addr, count)
+#define outsl(port, addr, count) __ide_outsl(port, addr, count)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_MACH_GENERIC_IDE_H */
diff --git a/arch/mips/include/asm/mach-generic/ioremap.h b/arch/mips/include/asm/mach-generic/ioremap.h
new file mode 100644
index 00000000..b379938d
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/ioremap.h
@@ -0,0 +1,34 @@
+/*
+ * include/asm-mips/mach-generic/ioremap.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_GENERIC_IOREMAP_H
+#define __ASM_MACH_GENERIC_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+ unsigned long flags)
+{
+ return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+ return 0;
+}
+
+#endif /* __ASM_MACH_GENERIC_IOREMAP_H */
diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h
new file mode 100644
index 00000000..70d9a251
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/irq.h
@@ -0,0 +1,45 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#ifndef __ASM_MACH_GENERIC_IRQ_H
+#define __ASM_MACH_GENERIC_IRQ_H
+
+#ifndef NR_IRQS
+#define NR_IRQS 128
+#endif
+
+#ifdef CONFIG_I8259
+#ifndef I8259A_IRQ_BASE
+#define I8259A_IRQ_BASE 0
+#endif
+#endif
+
+#ifdef CONFIG_IRQ_CPU
+
+#ifndef MIPS_CPU_IRQ_BASE
+#ifdef CONFIG_I8259
+#define MIPS_CPU_IRQ_BASE 16
+#else
+#define MIPS_CPU_IRQ_BASE 0
+#endif /* CONFIG_I8259 */
+#endif
+
+#ifdef CONFIG_IRQ_CPU_RM7K
+#ifndef RM7K_CPU_IRQ_BASE
+#define RM7K_CPU_IRQ_BASE (MIPS_CPU_IRQ_BASE+8)
+#endif
+#endif
+
+#ifdef CONFIG_IRQ_CPU_RM9K
+#ifndef RM9K_CPU_IRQ_BASE
+#define RM9K_CPU_IRQ_BASE (MIPS_CPU_IRQ_BASE+12)
+#endif
+#endif
+
+#endif /* CONFIG_IRQ_CPU */
+
+#endif /* __ASM_MACH_GENERIC_IRQ_H */
diff --git a/arch/mips/include/asm/mach-generic/kernel-entry-init.h b/arch/mips/include/asm/mach-generic/kernel-entry-init.h
new file mode 100644
index 00000000..7e66505f
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/kernel-entry-init.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Embedded Alley Solutions, Inc
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_GENERIC_KERNEL_ENTRY_H
+#define __ASM_MACH_GENERIC_KERNEL_ENTRY_H
+
+/* Intentionally empty macro, used in head.S. Override in
+ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
+ */
+.macro kernel_entry_setup
+.endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ .endm
+
+
+#endif /* __ASM_MACH_GENERIC_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-generic/kmalloc.h b/arch/mips/include/asm/mach-generic/kmalloc.h
new file mode 100644
index 00000000..a5d66908
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/kmalloc.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_MACH_GENERIC_KMALLOC_H
+#define __ASM_MACH_GENERIC_KMALLOC_H
+
+
+#ifndef CONFIG_DMA_COHERENT
+/*
+ * Total overkill for most systems but need as a safe default.
+ * Set this one if any device in the system might do non-coherent DMA.
+ */
+#define ARCH_DMA_MINALIGN 128
+#endif
+
+#endif /* __ASM_MACH_GENERIC_KMALLOC_H */
diff --git a/arch/mips/include/asm/mach-generic/mangle-port.h b/arch/mips/include/asm/mach-generic/mangle-port.h
new file mode 100644
index 00000000..f49dc990
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/mangle-port.h
@@ -0,0 +1,52 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ */
+#ifndef __ASM_MACH_GENERIC_MANGLE_PORT_H
+#define __ASM_MACH_GENERIC_MANGLE_PORT_H
+
+#define __swizzle_addr_b(port) (port)
+#define __swizzle_addr_w(port) (port)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+/*
+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+ * less sane hardware forces software to fiddle with this...
+ *
+ * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
+ * you can't have the numerical value of data and byte addresses within
+ * multibyte quantities both preserved at the same time. Hence two
+ * variations of functions: non-prefixed ones that preserve the value
+ * and prefixed ones that preserve byte addresses. The latters are
+ * typically used for moving raw data between a peripheral and memory (cf.
+ * string I/O functions), hence the "__mem_" prefix.
+ */
+#if defined(CONFIG_SWAP_IO_SPACE)
+
+# define ioswabb(a, x) (x)
+# define __mem_ioswabb(a, x) (x)
+# define ioswabw(a, x) le16_to_cpu(x)
+# define __mem_ioswabw(a, x) (x)
+# define ioswabl(a, x) le32_to_cpu(x)
+# define __mem_ioswabl(a, x) (x)
+# define ioswabq(a, x) le64_to_cpu(x)
+# define __mem_ioswabq(a, x) (x)
+
+#else
+
+# define ioswabb(a, x) (x)
+# define __mem_ioswabb(a, x) (x)
+# define ioswabw(a, x) (x)
+# define __mem_ioswabw(a, x) cpu_to_le16(x)
+# define ioswabl(a, x) (x)
+# define __mem_ioswabl(a, x) cpu_to_le32(x)
+# define ioswabq(a, x) (x)
+# define __mem_ioswabq(a, x) cpu_to_le32(x)
+
+#endif
+
+#endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */
diff --git a/arch/mips/include/asm/mach-generic/mc146818rtc.h b/arch/mips/include/asm/mach-generic/mc146818rtc.h
new file mode 100644
index 00000000..0b9a942f
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/mc146818rtc.h
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 2001, 03 by Ralf Baechle
+ *
+ * RTC routines for PC style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_GENERIC_MC146818RTC_H
+#define __ASM_MACH_GENERIC_MC146818RTC_H
+
+#include <asm/io.h>
+
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_IRQ 8
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ return inb_p(RTC_PORT(1));
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ outb_p(data, RTC_PORT(1));
+}
+
+#define RTC_ALWAYS_BCD 1
+
+#ifndef mc146818_decode_year
+#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900)
+#endif
+
+#endif /* __ASM_MACH_GENERIC_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h
new file mode 100644
index 00000000..c9fa4b14
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/spaces.h
@@ -0,0 +1,85 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_MACH_GENERIC_SPACES_H
+#define _ASM_MACH_GENERIC_SPACES_H
+
+#include <linux/const.h>
+
+/*
+ * This gives the physical RAM offset.
+ */
+#ifndef PHYS_OFFSET
+#define PHYS_OFFSET _AC(0, UL)
+#endif
+
+#ifdef CONFIG_32BIT
+
+#define CAC_BASE _AC(0x80000000, UL)
+#define IO_BASE _AC(0xa0000000, UL)
+#define UNCAC_BASE _AC(0xa0000000, UL)
+
+#ifndef MAP_BASE
+#define MAP_BASE _AC(0xc0000000, UL)
+#endif
+
+/*
+ * Memory above this physical address will be considered highmem.
+ */
+#ifndef HIGHMEM_START
+#define HIGHMEM_START _AC(0x20000000, UL)
+#endif
+
+#endif /* CONFIG_32BIT */
+
+#ifdef CONFIG_64BIT
+
+#ifndef CAC_BASE
+#ifdef CONFIG_DMA_NONCOHERENT
+#define CAC_BASE _AC(0x9800000000000000, UL)
+#else
+#define CAC_BASE _AC(0xa800000000000000, UL)
+#endif
+#endif
+
+#ifndef IO_BASE
+#define IO_BASE _AC(0x9000000000000000, UL)
+#endif
+
+#ifndef UNCAC_BASE
+#define UNCAC_BASE _AC(0x9000000000000000, UL)
+#endif
+
+#ifndef MAP_BASE
+#define MAP_BASE _AC(0xc000000000000000, UL)
+#endif
+
+/*
+ * Memory above this physical address will be considered highmem.
+ * Fixme: 59 bits is a fictive number and makes assumptions about processors
+ * in the distant future. Nobody will care for a few years :-)
+ */
+#ifndef HIGHMEM_START
+#define HIGHMEM_START (_AC(1, UL) << _AC(59, UL))
+#endif
+
+#define TO_PHYS(x) ( ((x) & TO_PHYS_MASK))
+#define TO_CAC(x) (CAC_BASE | ((x) & TO_PHYS_MASK))
+#define TO_UNCAC(x) (UNCAC_BASE | ((x) & TO_PHYS_MASK))
+
+#endif /* CONFIG_64BIT */
+
+/*
+ * This handles the memory map.
+ */
+#ifndef PAGE_OFFSET
+#define PAGE_OFFSET (CAC_BASE + PHYS_OFFSET)
+#endif
+
+#endif /* __ASM_MACH_GENERIC_SPACES_H */
diff --git a/arch/mips/include/asm/mach-generic/topology.h b/arch/mips/include/asm/mach-generic/topology.h
new file mode 100644
index 00000000..5428f333
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/topology.h
@@ -0,0 +1 @@
+#include <asm-generic/topology.h>
diff --git a/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h
new file mode 100644
index 00000000..9c873515
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h
@@ -0,0 +1,44 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 07 Ralf Baechle
+ */
+#ifndef __ASM_MACH_IP22_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_IP22_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * IP22 with a variety of processors so we can't use defaults for everything.
+ */
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+#define cpu_has_fpu 1
+#define cpu_has_32fpr 1
+#define cpu_has_counter 1
+#define cpu_has_mips16 0
+#define cpu_has_divec 0
+#define cpu_has_cache_cdex_p 1
+#define cpu_has_prefetch 0
+#define cpu_has_mcheck 0
+#define cpu_has_ejtag 0
+
+#define cpu_has_llsc 1
+#define cpu_has_vtag_icache 0 /* Needs to change for R8000 */
+#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
+#define cpu_has_ic_fills_f_dc 0
+
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 1
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_MACH_IP22_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ip22/spaces.h b/arch/mips/include/asm/mach-ip22/spaces.h
new file mode 100644
index 00000000..7f9fa6f6
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip22/spaces.h
@@ -0,0 +1,27 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_MACH_IP22_SPACES_H
+#define _ASM_MACH_IP22_SPACES_H
+
+
+#ifdef CONFIG_64BIT
+
+#define PAGE_OFFSET 0xffffffff80000000UL
+
+#define CAC_BASE 0xffffffff80000000
+#define IO_BASE 0xffffffffa0000000
+#define UNCAC_BASE 0xffffffffa0000000
+#define MAP_BASE 0xc000000000000000
+
+#endif /* CONFIG_64BIT */
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_MACH_IP22_SPACES_H */
diff --git a/arch/mips/include/asm/mach-ip22/war.h b/arch/mips/include/asm/mach-ip22/war.h
new file mode 100644
index 00000000..a44fa965
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip22/war.h
@@ -0,0 +1,29 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_IP22_WAR_H
+#define __ASM_MIPS_MACH_IP22_WAR_H
+
+/*
+ * R4600 CPU modules for the Indy come with both V1.7 and V2.0 processors.
+ */
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 1
+#define R4600_V1_HIT_CACHEOP_WAR 1
+#define R4600_V2_HIT_CACHEOP_WAR 1
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_IP22_WAR_H */
diff --git a/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h
new file mode 100644
index 00000000..7d3112b1
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h
@@ -0,0 +1,54 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 07 Ralf Baechle
+ */
+#ifndef __ASM_MACH_IP27_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_IP27_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * IP27 only comes with R10000 family processors all using the same config
+ */
+#define cpu_has_watch 1
+#define cpu_has_mips16 0
+#define cpu_has_divec 0
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 0
+#define cpu_has_ejtag 0
+
+#define cpu_has_llsc 1
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+#define cpu_icache_snoops_remote_store 1
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 1
+
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_6k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_8k_cache 0
+#define cpu_has_tx39_cache 0
+
+#define cpu_has_inclusive_pcaches 1
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 64
+#define cpu_scache_line_size() 128
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_MACH_IP27_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h
new file mode 100644
index 00000000..016d0989
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h
@@ -0,0 +1,77 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
+ *
+ */
+#ifndef __ASM_MACH_IP27_DMA_COHERENCE_H
+#define __ASM_MACH_IP27_DMA_COHERENCE_H
+
+#include <asm/pci/bridge.h>
+
+#define pdev_to_baddr(pdev, addr) \
+ (BRIDGE_CONTROLLER(pdev->bus)->baddr + (addr))
+#define dev_to_baddr(dev, addr) \
+ pdev_to_baddr(to_pci_dev(dev), (addr))
+
+struct device;
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+ size_t size)
+{
+ dma_addr_t pa = dev_to_baddr(dev, virt_to_phys(addr));
+
+ return pa;
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));
+
+ return pa;
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return dma_addr & ~(0xffUL << 56);
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+ return 1; /* IP27 non-cohernet mode is unsupported */
+}
+
+#endif /* __ASM_MACH_IP27_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-ip27/irq.h b/arch/mips/include/asm/mach-ip27/irq.h
new file mode 100644
index 00000000..cf4384bf
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/irq.h
@@ -0,0 +1,22 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000, 01, 02, 03 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 Kanoj Sarcar
+ */
+#ifndef __ASM_MACH_IP27_IRQ_H
+#define __ASM_MACH_IP27_IRQ_H
+
+/*
+ * A hardwired interrupt number is completly stupid for this system - a
+ * large configuration might have thousands if not tenthousands of
+ * interrupts.
+ */
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_IP27_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ip27/kernel-entry-init.h b/arch/mips/include/asm/mach-ip27/kernel-entry-init.h
new file mode 100644
index 00000000..624d66c7
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/kernel-entry-init.h
@@ -0,0 +1,59 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2005 Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_IP27_KERNEL_ENTRY_H
+#define __ASM_MACH_IP27_KERNEL_ENTRY_H
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/klkernvars.h>
+
+/*
+ * Returns the local nasid into res.
+ */
+ .macro GET_NASID_ASM res
+ dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
+ ld \res, (\res)
+ and \res, NSRI_NODEID_MASK
+ dsrl \res, NSRI_NODEID_SHFT
+ .endm
+
+/*
+ * Intentionally empty macro, used in head.S. Override in
+ * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
+ */
+ .macro kernel_entry_setup
+ GET_NASID_ASM t1
+ move t2, t1 # text and data are here
+ MAPPED_KERNEL_SETUP_TLB
+ .endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ GET_NASID_ASM t1
+ dli t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \
+ KLDIR_OFF_POINTER + CAC_BASE
+ dsll t1, NASID_SHFT
+ or t0, t0, t1
+ ld t0, 0(t0) # t0 points to kern_vars struct
+ lh t1, KV_RO_NASID_OFFSET(t0)
+ lh t2, KV_RW_NASID_OFFSET(t0)
+ MAPPED_KERNEL_SETUP_TLB
+
+ /*
+ * We might not get launched at the address the kernel is linked to,
+ * so we jump there.
+ */
+ PTR_LA t0, 0f
+ jr t0
+0:
+ .endm
+
+#endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-ip27/kmalloc.h b/arch/mips/include/asm/mach-ip27/kmalloc.h
new file mode 100644
index 00000000..82c23ce2
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/kmalloc.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_MACH_IP27_KMALLOC_H
+#define __ASM_MACH_IP27_KMALLOC_H
+
+/*
+ * All happy, no need to define ARCH_DMA_MINALIGN
+ */
+
+#endif /* __ASM_MACH_IP27_KMALLOC_H */
diff --git a/arch/mips/include/asm/mach-ip27/mangle-port.h b/arch/mips/include/asm/mach-ip27/mangle-port.h
new file mode 100644
index 00000000..f6e4912e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/mangle-port.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ */
+#ifndef __ASM_MACH_IP27_MANGLE_PORT_H
+#define __ASM_MACH_IP27_MANGLE_PORT_H
+
+#define __swizzle_addr_b(port) (port)
+#define __swizzle_addr_w(port) ((port) ^ 2)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+# define ioswabb(a, x) (x)
+# define __mem_ioswabb(a, x) (x)
+# define ioswabw(a, x) (x)
+# define __mem_ioswabw(a, x) cpu_to_le16(x)
+# define ioswabl(a, x) (x)
+# define __mem_ioswabl(a, x) cpu_to_le32(x)
+# define ioswabq(a, x) (x)
+# define __mem_ioswabq(a, x) cpu_to_le32(x)
+
+#endif /* __ASM_MACH_IP27_MANGLE_PORT_H */
diff --git a/arch/mips/include/asm/mach-ip27/mmzone.h b/arch/mips/include/asm/mach-ip27/mmzone.h
new file mode 100644
index 00000000..986a3b9b
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/mmzone.h
@@ -0,0 +1,36 @@
+#ifndef _ASM_MACH_MMZONE_H
+#define _ASM_MACH_MMZONE_H
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/hub.h>
+
+#define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr))
+
+#define LEVELS_PER_SLICE 128
+
+struct slice_data {
+ unsigned long irq_enable_mask[2];
+ int level_to_irq[LEVELS_PER_SLICE];
+};
+
+struct hub_data {
+ kern_vars_t kern_vars;
+ DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
+ cpumask_t h_cpus;
+ unsigned long slice_map;
+ unsigned long irq_alloc_mask[2];
+ struct slice_data slice[2];
+};
+
+struct node_data {
+ struct pglist_data pglist;
+ struct hub_data hub;
+};
+
+extern struct node_data *__node_data[];
+
+#define NODE_DATA(n) (&__node_data[(n)]->pglist)
+#define hub_data(n) (&__node_data[(n)]->hub)
+
+#endif /* _ASM_MACH_MMZONE_H */
diff --git a/arch/mips/include/asm/mach-ip27/spaces.h b/arch/mips/include/asm/mach-ip27/spaces.h
new file mode 100644
index 00000000..b18802a0
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/spaces.h
@@ -0,0 +1,30 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 99 Ralf Baechle
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki
+ * Copyright (C) 1990, 1999 by Silicon Graphics, Inc.
+ */
+#ifndef _ASM_MACH_IP27_SPACES_H
+#define _ASM_MACH_IP27_SPACES_H
+
+/*
+ * IP27 uses the R10000's uncached attribute feature. Attribute 3 selects
+ * uncached memory addressing.
+ */
+
+#define HSPEC_BASE 0x9000000000000000
+#define IO_BASE 0x9200000000000000
+#define MSPEC_BASE 0x9400000000000000
+#define UNCAC_BASE 0x9600000000000000
+
+#define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK))
+#define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK))
+
+#define HIGHMEM_START (~0UL)
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* _ASM_MACH_IP27_SPACES_H */
diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h
new file mode 100644
index 00000000..1b1a7d16
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/topology.h
@@ -0,0 +1,58 @@
+#ifndef _ASM_MACH_TOPOLOGY_H
+#define _ASM_MACH_TOPOLOGY_H 1
+
+#include <asm/sn/hub.h>
+#include <asm/sn/types.h>
+#include <asm/mmzone.h>
+
+struct cpuinfo_ip27 {
+// cpuid_t p_cpuid; /* PROM assigned cpuid */
+ cnodeid_t p_nodeid; /* my node ID in compact-id-space */
+ nasid_t p_nasid; /* my node ID in numa-as-id-space */
+ unsigned char p_slice; /* Physical position on node board */
+#if 0
+ unsigned long loops_per_sec;
+ unsigned long ipi_count;
+ unsigned long irq_attempt[NR_IRQS];
+ unsigned long smp_local_irq_count;
+ unsigned long prof_multiplier;
+ unsigned long prof_counter;
+#endif
+};
+
+extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
+
+#define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid)
+#define parent_node(node) (node)
+#define cpumask_of_node(node) ((node) == -1 ? \
+ cpu_all_mask : \
+ &hub_data(node)->h_cpus)
+struct pci_bus;
+extern int pcibus_to_node(struct pci_bus *);
+
+#define cpumask_of_pcibus(bus) (cpu_online_mask)
+
+extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
+
+#define node_distance(from, to) (__node_distances[(from)][(to)])
+
+/* sched_domains SD_NODE_INIT for SGI IP27 machines */
+#define SD_NODE_INIT (struct sched_domain) { \
+ .parent = NULL, \
+ .child = NULL, \
+ .groups = NULL, \
+ .min_interval = 8, \
+ .max_interval = 32, \
+ .busy_factor = 32, \
+ .imbalance_pct = 125, \
+ .cache_nice_tries = 1, \
+ .flags = SD_LOAD_BALANCE | \
+ SD_BALANCE_EXEC, \
+ .last_balance = jiffies, \
+ .balance_interval = 1, \
+ .nr_balance_failed = 0, \
+}
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_MACH_TOPOLOGY_H */
diff --git a/arch/mips/include/asm/mach-ip27/war.h b/arch/mips/include/asm/mach-ip27/war.h
new file mode 100644
index 00000000..e2ddcc9b
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip27/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_IP27_WAR_H
+#define __ASM_MIPS_MACH_IP27_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 1
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_IP27_WAR_H */
diff --git a/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h
new file mode 100644
index 00000000..9a53b326
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip28/cpu-feature-overrides.h
@@ -0,0 +1,50 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Ralf Baechle
+ * 6/2004 pf
+ */
+#ifndef __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * IP28 only comes with R10000 family processors all using the same config
+ */
+#define cpu_has_watch 1
+#define cpu_has_mips16 0
+#define cpu_has_divec 0
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 0
+#define cpu_has_ejtag 0
+
+#define cpu_has_llsc 1
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases 0 /* see probe_pcache() */
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+#define cpu_icache_snoops_remote_store 1
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 1
+
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+
+#define cpu_has_inclusive_pcaches 1
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 64
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_MACH_IP28_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ip28/spaces.h b/arch/mips/include/asm/mach-ip28/spaces.h
new file mode 100644
index 00000000..05aabb27
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip28/spaces.h
@@ -0,0 +1,22 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2002 Maciej W. Rozycki
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
+ * 2004 pf
+ */
+#ifndef _ASM_MACH_IP28_SPACES_H
+#define _ASM_MACH_IP28_SPACES_H
+
+#define CAC_BASE 0xa800000000000000
+
+#define HIGHMEM_START (~0UL)
+
+#define PHYS_OFFSET _AC(0x20000000, UL)
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* _ASM_MACH_IP28_SPACES_H */
diff --git a/arch/mips/include/asm/mach-ip28/war.h b/arch/mips/include/asm/mach-ip28/war.h
new file mode 100644
index 00000000..a1baafab
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip28/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_IP28_WAR_H
+#define __ASM_MIPS_MACH_IP28_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 1
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_IP28_WAR_H */
diff --git a/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h
new file mode 100644
index 00000000..6782fcce
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h
@@ -0,0 +1,50 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh
+ * Copyright (C) 2005, 07 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
+
+
+/*
+ * R5000 has an interesting "restriction": ll(d)/sc(d)
+ * instructions to XKPHYS region simply do uncached bus
+ * requests. This breaks all the atomic bitops functions.
+ * so, for 64bit IP32 kernel we just don't use ll/sc.
+ * This does not affect luserland.
+ */
+#if (defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)) && defined(CONFIG_64BIT)
+#define cpu_has_llsc 0
+#else
+#define cpu_has_llsc 1
+#endif
+
+/* Settings which are common for all ip32 CPUs */
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_fpu 1
+#define cpu_has_32fpr 1
+#define cpu_has_counter 1
+#define cpu_has_mips16 0
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_mcheck 0
+#define cpu_has_ejtag 0
+#define cpu_has_vtag_icache 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+#define cpu_has_4k_cache 1
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h
new file mode 100644
index 00000000..c8fb5aac
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip32/dma-coherence.h
@@ -0,0 +1,99 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
+ *
+ */
+#ifndef __ASM_MACH_IP32_DMA_COHERENCE_H
+#define __ASM_MACH_IP32_DMA_COHERENCE_H
+
+#include <asm/ip32/crime.h>
+
+struct device;
+
+/*
+ * Few notes.
+ * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x40000000+256M
+ * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for
+ * native-endian)
+ * 3. All other devices see memory as one big chunk at 0x40000000
+ * 4. Non-PCI devices will pass NULL as struct device*
+ *
+ * Thus we translate differently, depending on device.
+ */
+
+#define RAM_OFFSET_MASK 0x3fffffffUL
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+ size_t size)
+{
+ dma_addr_t pa = virt_to_phys(addr) & RAM_OFFSET_MASK;
+
+ if (dev == NULL)
+ pa += CRIME_HI_MEM_BASE;
+
+ return pa;
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ dma_addr_t pa;
+
+ pa = page_to_phys(page) & RAM_OFFSET_MASK;
+
+ if (dev == NULL)
+ pa += CRIME_HI_MEM_BASE;
+
+ return pa;
+}
+
+/* This is almost certainly wrong but it's what dma-ip32.c used to use */
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ unsigned long addr = dma_addr & RAM_OFFSET_MASK;
+
+ if (dma_addr >= 256*1024*1024)
+ addr += CRIME_HI_MEM_BASE;
+
+ return addr;
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+ return 0; /* IP32 is non-cohernet */
+}
+
+#endif /* __ASM_MACH_IP32_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-ip32/kmalloc.h b/arch/mips/include/asm/mach-ip32/kmalloc.h
new file mode 100644
index 00000000..042ca926
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip32/kmalloc.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_MACH_IP32_KMALLOC_H
+#define __ASM_MACH_IP32_KMALLOC_H
+
+
+#if defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_RM7000)
+#define ARCH_DMA_MINALIGN 32
+#else
+#define ARCH_DMA_MINALIGN 128
+#endif
+
+#endif /* __ASM_MACH_IP32_KMALLOC_H */
diff --git a/arch/mips/include/asm/mach-ip32/mangle-port.h b/arch/mips/include/asm/mach-ip32/mangle-port.h
new file mode 100644
index 00000000..f1d0f175
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip32/mangle-port.h
@@ -0,0 +1,26 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Ladislav Michl
+ * Copyright (C) 2004 Ralf Baechle
+ */
+#ifndef __ASM_MACH_IP32_MANGLE_PORT_H
+#define __ASM_MACH_IP32_MANGLE_PORT_H
+
+#define __swizzle_addr_b(port) ((port) ^ 3)
+#define __swizzle_addr_w(port) ((port) ^ 2)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+# define ioswabb(a, x) (x)
+# define __mem_ioswabb(a, x) (x)
+# define ioswabw(a, x) (x)
+# define __mem_ioswabw(a, x) cpu_to_le16(x)
+# define ioswabl(a, x) (x)
+# define __mem_ioswabl(a, x) cpu_to_le32(x)
+# define ioswabq(a, x) (x)
+# define __mem_ioswabq(a, x) cpu_to_le32(x)
+
+#endif /* __ASM_MACH_IP32_MANGLE_PORT_H */
diff --git a/arch/mips/include/asm/mach-ip32/mc146818rtc.h b/arch/mips/include/asm/mach-ip32/mc146818rtc.h
new file mode 100644
index 00000000..6b6bab43
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip32/mc146818rtc.h
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 2001, 03 by Ralf Baechle
+ * Copyright (C) 2000 Harald Koerfgen
+ *
+ * RTC routines for IP32 style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_IP32_MC146818RTC_H
+#define __ASM_MACH_IP32_MC146818RTC_H
+
+#include <asm/ip32/mace.h>
+
+#define RTC_PORT(x) (0x70 + (x))
+
+static unsigned char CMOS_READ(unsigned long addr)
+{
+ return mace->isa.rtc[addr << 8];
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+ mace->isa.rtc[addr << 8] = data;
+}
+
+/*
+ * FIXME: Do it right. For now just assume that no one lives in 20th century
+ * and no O2 user in 22th century ;-)
+ */
+#define mc146818_decode_year(year) ((year) + 2000)
+
+#define RTC_ALWAYS_BCD 0
+
+#endif /* __ASM_MACH_IP32_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-ip32/war.h b/arch/mips/include/asm/mach-ip32/war.h
new file mode 100644
index 00000000..d194056d
--- /dev/null
+++ b/arch/mips/include/asm/mach-ip32/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_IP32_WAR_H
+#define __ASM_MIPS_MACH_IP32_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_IP32_WAR_H */
diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h
new file mode 100644
index 00000000..302101b5
--- /dev/null
+++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h
@@ -0,0 +1,67 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_JAZZ_DMA_COHERENCE_H
+#define __ASM_MACH_JAZZ_DMA_COHERENCE_H
+
+#include <asm/jazzdma.h>
+
+struct device;
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+{
+ return vdma_alloc(virt_to_phys(addr), size);
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ return vdma_alloc(page_to_phys(page), PAGE_SIZE);
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return vdma_log2phys(dma_addr);
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
+{
+ vdma_free(dma_addr);
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+ return 0;
+}
+
+#endif /* __ASM_MACH_JAZZ_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-jazz/floppy.h b/arch/mips/include/asm/mach-jazz/floppy.h
new file mode 100644
index 00000000..56e9ca6a
--- /dev/null
+++ b/arch/mips/include/asm/mach-jazz/floppy.h
@@ -0,0 +1,135 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 2003 by Ralf Baechle
+ */
+#ifndef __ASM_MACH_JAZZ_FLOPPY_H
+#define __ASM_MACH_JAZZ_FLOPPY_H
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <asm/addrspace.h>
+#include <asm/jazz.h>
+#include <asm/jazzdma.h>
+#include <asm/pgtable.h>
+
+static inline unsigned char fd_inb(unsigned int port)
+{
+ unsigned char c;
+
+ c = *(volatile unsigned char *) port;
+ udelay(1);
+
+ return c;
+}
+
+static inline void fd_outb(unsigned char value, unsigned int port)
+{
+ *(volatile unsigned char *) port = value;
+}
+
+/*
+ * How to access the floppy DMA functions.
+ */
+static inline void fd_enable_dma(void)
+{
+ vdma_enable(JAZZ_FLOPPY_DMA);
+}
+
+static inline void fd_disable_dma(void)
+{
+ vdma_disable(JAZZ_FLOPPY_DMA);
+}
+
+static inline int fd_request_dma(void)
+{
+ return 0;
+}
+
+static inline void fd_free_dma(void)
+{
+}
+
+static inline void fd_clear_dma_ff(void)
+{
+}
+
+static inline void fd_set_dma_mode(char mode)
+{
+ vdma_set_mode(JAZZ_FLOPPY_DMA, mode);
+}
+
+static inline void fd_set_dma_addr(char *a)
+{
+ vdma_set_addr(JAZZ_FLOPPY_DMA, vdma_phys2log(CPHYSADDR((unsigned long)a)));
+}
+
+static inline void fd_set_dma_count(unsigned int count)
+{
+ vdma_set_count(JAZZ_FLOPPY_DMA, count);
+}
+
+static inline int fd_get_dma_residue(void)
+{
+ return vdma_get_residue(JAZZ_FLOPPY_DMA);
+}
+
+static inline void fd_enable_irq(void)
+{
+}
+
+static inline void fd_disable_irq(void)
+{
+}
+
+static inline int fd_request_irq(void)
+{
+ return request_irq(FLOPPY_IRQ, floppy_interrupt,
+ IRQF_DISABLED, "floppy", NULL);
+}
+
+static inline void fd_free_irq(void)
+{
+ free_irq(FLOPPY_IRQ, NULL);
+}
+
+static inline unsigned long fd_getfdaddr1(void)
+{
+ return JAZZ_FDC_BASE;
+}
+
+static inline unsigned long fd_dma_mem_alloc(unsigned long size)
+{
+ unsigned long mem;
+
+ mem = __get_dma_pages(GFP_KERNEL, get_order(size));
+ if(!mem)
+ return 0;
+ vdma_alloc(CPHYSADDR(mem), size); /* XXX error checking */
+
+ return mem;
+}
+
+static inline void fd_dma_mem_free(unsigned long addr, unsigned long size)
+{
+ vdma_free(vdma_phys2log(CPHYSADDR(addr)));
+ free_pages(addr, get_order(size));
+}
+
+static inline unsigned long fd_drive_type(unsigned long n)
+{
+ /* XXX This is wrong for machines with ED 2.88mb disk drives like the
+ Olivetti M700. Anyway, we should suck this from the ARC
+ firmware. */
+ if (n == 0)
+ return 4; /* 3,5", 1.44mb */
+
+ return 0;
+}
+
+#endif /* __ASM_MACH_JAZZ_FLOPPY_H */
diff --git a/arch/mips/include/asm/mach-jazz/mc146818rtc.h b/arch/mips/include/asm/mach-jazz/mc146818rtc.h
new file mode 100644
index 00000000..987f727a
--- /dev/null
+++ b/arch/mips/include/asm/mach-jazz/mc146818rtc.h
@@ -0,0 +1,38 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 2001, 03 by Ralf Baechle
+ * Copyright (C) 2007 Thomas Bogendoerfer
+ *
+ * RTC routines for Jazz style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_JAZZ_MC146818RTC_H
+#define __ASM_MACH_JAZZ_MC146818RTC_H
+
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/jazz.h>
+
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_IRQ 8
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ return *(volatile char *)JAZZ_RTC_BASE;
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ *(volatile char *)JAZZ_RTC_BASE = data;
+}
+
+#define RTC_ALWAYS_BCD 0
+
+#define mc146818_decode_year(year) ((year) + 1980)
+
+#endif /* __ASM_MACH_JAZZ_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-jazz/war.h b/arch/mips/include/asm/mach-jazz/war.h
new file mode 100644
index 00000000..6158ee86
--- /dev/null
+++ b/arch/mips/include/asm/mach-jazz/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_JAZZ_WAR_H
+#define __ASM_MIPS_MACH_JAZZ_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_JAZZ_WAR_H */
diff --git a/arch/mips/include/asm/mach-jz4740/base.h b/arch/mips/include/asm/mach-jz4740/base.h
new file mode 100644
index 00000000..f3731860
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/base.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_MACH_JZ4740_BASE_H__
+#define __ASM_MACH_JZ4740_BASE_H__
+
+#define JZ4740_CPM_BASE_ADDR 0x10000000
+#define JZ4740_INTC_BASE_ADDR 0x10001000
+#define JZ4740_WDT_BASE_ADDR 0x10002000
+#define JZ4740_TCU_BASE_ADDR 0x10002010
+#define JZ4740_RTC_BASE_ADDR 0x10003000
+#define JZ4740_GPIO_BASE_ADDR 0x10010000
+#define JZ4740_AIC_BASE_ADDR 0x10020000
+#define JZ4740_MSC_BASE_ADDR 0x10021000
+#define JZ4740_UART0_BASE_ADDR 0x10030000
+#define JZ4740_UART1_BASE_ADDR 0x10031000
+#define JZ4740_I2C_BASE_ADDR 0x10042000
+#define JZ4740_SSI_BASE_ADDR 0x10043000
+#define JZ4740_SADC_BASE_ADDR 0x10070000
+#define JZ4740_EMC_BASE_ADDR 0x13010000
+#define JZ4740_DMAC_BASE_ADDR 0x13020000
+#define JZ4740_UHC_BASE_ADDR 0x13030000
+#define JZ4740_UDC_BASE_ADDR 0x13040000
+#define JZ4740_LCD_BASE_ADDR 0x13050000
+#define JZ4740_SLCD_BASE_ADDR 0x13050000
+#define JZ4740_CIM_BASE_ADDR 0x13060000
+#define JZ4740_IPU_BASE_ADDR 0x13080000
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
new file mode 100644
index 00000000..1b7408dd
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_JZ4740_CLOCK_H__
+#define __ASM_JZ4740_CLOCK_H__
+
+enum jz4740_wait_mode {
+ JZ4740_WAIT_MODE_IDLE,
+ JZ4740_WAIT_MODE_SLEEP,
+};
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
+
+void jz4740_clock_udc_enable_auto_suspend(void);
+void jz4740_clock_udc_disable_auto_suspend(void);
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h b/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h
new file mode 100644
index 00000000..d12e5c64
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h
@@ -0,0 +1,51 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef __ASM_MACH_JZ4740_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_JZ4740_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
+#define cpu_has_counter 0
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+#define kernel_uses_llsc 1
+#define cpu_has_vtag_icache 1
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_pindexed_dcache 0
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/dma.h b/arch/mips/include/asm/mach-jz4740/dma.h
new file mode 100644
index 00000000..a3be1218
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/dma.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ7420/JZ4740 DMA definitions
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_DMA_H__
+#define __ASM_MACH_JZ4740_DMA_H__
+
+struct jz4740_dma_chan;
+
+enum jz4740_dma_request_type {
+ JZ4740_DMA_TYPE_AUTO_REQUEST = 8,
+ JZ4740_DMA_TYPE_UART_TRANSMIT = 20,
+ JZ4740_DMA_TYPE_UART_RECEIVE = 21,
+ JZ4740_DMA_TYPE_SPI_TRANSMIT = 22,
+ JZ4740_DMA_TYPE_SPI_RECEIVE = 23,
+ JZ4740_DMA_TYPE_AIC_TRANSMIT = 24,
+ JZ4740_DMA_TYPE_AIC_RECEIVE = 25,
+ JZ4740_DMA_TYPE_MMC_TRANSMIT = 26,
+ JZ4740_DMA_TYPE_MMC_RECEIVE = 27,
+ JZ4740_DMA_TYPE_TCU = 28,
+ JZ4740_DMA_TYPE_SADC = 29,
+ JZ4740_DMA_TYPE_SLCD = 30,
+};
+
+enum jz4740_dma_width {
+ JZ4740_DMA_WIDTH_32BIT = 0,
+ JZ4740_DMA_WIDTH_8BIT = 1,
+ JZ4740_DMA_WIDTH_16BIT = 2,
+};
+
+enum jz4740_dma_transfer_size {
+ JZ4740_DMA_TRANSFER_SIZE_4BYTE = 0,
+ JZ4740_DMA_TRANSFER_SIZE_1BYTE = 1,
+ JZ4740_DMA_TRANSFER_SIZE_2BYTE = 2,
+ JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3,
+ JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4,
+};
+
+enum jz4740_dma_flags {
+ JZ4740_DMA_SRC_AUTOINC = 0x2,
+ JZ4740_DMA_DST_AUTOINC = 0x1,
+};
+
+enum jz4740_dma_mode {
+ JZ4740_DMA_MODE_SINGLE = 0,
+ JZ4740_DMA_MODE_BLOCK = 1,
+};
+
+struct jz4740_dma_config {
+ enum jz4740_dma_width src_width;
+ enum jz4740_dma_width dst_width;
+ enum jz4740_dma_transfer_size transfer_size;
+ enum jz4740_dma_request_type request_type;
+ enum jz4740_dma_flags flags;
+ enum jz4740_dma_mode mode;
+};
+
+typedef void (*jz4740_dma_complete_callback_t)(struct jz4740_dma_chan *, int, void *);
+
+struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name);
+void jz4740_dma_free(struct jz4740_dma_chan *dma);
+
+void jz4740_dma_configure(struct jz4740_dma_chan *dma,
+ const struct jz4740_dma_config *config);
+
+
+void jz4740_dma_enable(struct jz4740_dma_chan *dma);
+void jz4740_dma_disable(struct jz4740_dma_chan *dma);
+
+void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src);
+void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst);
+void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count);
+
+uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma);
+
+void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
+ jz4740_dma_complete_callback_t cb);
+
+#endif /* __ASM_JZ4740_DMA_H__ */
diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h
new file mode 100644
index 00000000..7b747037
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/gpio.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 GPIO pin definitions
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _JZ_GPIO_H
+#define _JZ_GPIO_H
+
+#include <linux/types.h>
+
+enum jz_gpio_function {
+ JZ_GPIO_FUNC_NONE,
+ JZ_GPIO_FUNC1,
+ JZ_GPIO_FUNC2,
+ JZ_GPIO_FUNC3,
+};
+
+
+/*
+ Usually a driver for a SoC component has to request several gpio pins and
+ configure them as funcion pins.
+ jz_gpio_bulk_request can be used to ease this process.
+ Usually one would do something like:
+
+ const static struct jz_gpio_bulk_request i2c_pins[] = {
+ JZ_GPIO_BULK_PIN(I2C_SDA),
+ JZ_GPIO_BULK_PIN(I2C_SCK),
+ };
+
+ inside the probe function:
+
+ ret = jz_gpio_bulk_request(i2c_pins, ARRAY_SIZE(i2c_pins));
+ if (ret) {
+ ...
+
+ inside the remove function:
+
+ jz_gpio_bulk_free(i2c_pins, ARRAY_SIZE(i2c_pins));
+
+
+*/
+struct jz_gpio_bulk_request {
+ int gpio;
+ const char *name;
+ enum jz_gpio_function function;
+};
+
+#define JZ_GPIO_BULK_PIN(pin) { \
+ .gpio = JZ_GPIO_ ## pin, \
+ .name = #pin, \
+ .function = JZ_GPIO_FUNC_ ## pin \
+}
+
+int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num);
+void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num);
+void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num);
+void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num);
+void jz_gpio_enable_pullup(unsigned gpio);
+void jz_gpio_disable_pullup(unsigned gpio);
+int jz_gpio_set_function(int gpio, enum jz_gpio_function function);
+
+int jz_gpio_port_direction_input(int port, uint32_t mask);
+int jz_gpio_port_direction_output(int port, uint32_t mask);
+void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
+uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
+
+#include <asm/mach-generic/gpio.h>
+
+#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
+#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
+#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
+#define JZ_GPIO_PORTD(x) ((x) + 32 * 3)
+
+/* Port A function pins */
+#define JZ_GPIO_MEM_DATA0 JZ_GPIO_PORTA(0)
+#define JZ_GPIO_MEM_DATA1 JZ_GPIO_PORTA(1)
+#define JZ_GPIO_MEM_DATA2 JZ_GPIO_PORTA(2)
+#define JZ_GPIO_MEM_DATA3 JZ_GPIO_PORTA(3)
+#define JZ_GPIO_MEM_DATA4 JZ_GPIO_PORTA(4)
+#define JZ_GPIO_MEM_DATA5 JZ_GPIO_PORTA(5)
+#define JZ_GPIO_MEM_DATA6 JZ_GPIO_PORTA(6)
+#define JZ_GPIO_MEM_DATA7 JZ_GPIO_PORTA(7)
+#define JZ_GPIO_MEM_DATA8 JZ_GPIO_PORTA(8)
+#define JZ_GPIO_MEM_DATA9 JZ_GPIO_PORTA(9)
+#define JZ_GPIO_MEM_DATA10 JZ_GPIO_PORTA(10)
+#define JZ_GPIO_MEM_DATA11 JZ_GPIO_PORTA(11)
+#define JZ_GPIO_MEM_DATA12 JZ_GPIO_PORTA(12)
+#define JZ_GPIO_MEM_DATA13 JZ_GPIO_PORTA(13)
+#define JZ_GPIO_MEM_DATA14 JZ_GPIO_PORTA(14)
+#define JZ_GPIO_MEM_DATA15 JZ_GPIO_PORTA(15)
+#define JZ_GPIO_MEM_DATA16 JZ_GPIO_PORTA(16)
+#define JZ_GPIO_MEM_DATA17 JZ_GPIO_PORTA(17)
+#define JZ_GPIO_MEM_DATA18 JZ_GPIO_PORTA(18)
+#define JZ_GPIO_MEM_DATA19 JZ_GPIO_PORTA(19)
+#define JZ_GPIO_MEM_DATA20 JZ_GPIO_PORTA(20)
+#define JZ_GPIO_MEM_DATA21 JZ_GPIO_PORTA(21)
+#define JZ_GPIO_MEM_DATA22 JZ_GPIO_PORTA(22)
+#define JZ_GPIO_MEM_DATA23 JZ_GPIO_PORTA(23)
+#define JZ_GPIO_MEM_DATA24 JZ_GPIO_PORTA(24)
+#define JZ_GPIO_MEM_DATA25 JZ_GPIO_PORTA(25)
+#define JZ_GPIO_MEM_DATA26 JZ_GPIO_PORTA(26)
+#define JZ_GPIO_MEM_DATA27 JZ_GPIO_PORTA(27)
+#define JZ_GPIO_MEM_DATA28 JZ_GPIO_PORTA(28)
+#define JZ_GPIO_MEM_DATA29 JZ_GPIO_PORTA(29)
+#define JZ_GPIO_MEM_DATA30 JZ_GPIO_PORTA(30)
+#define JZ_GPIO_MEM_DATA31 JZ_GPIO_PORTA(31)
+
+#define JZ_GPIO_FUNC_MEM_DATA0 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA1 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA2 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA3 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA4 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA5 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA6 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA7 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA8 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA9 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA10 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA11 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA12 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA13 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA14 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA15 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA16 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA17 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA18 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA19 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA20 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA21 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA22 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA23 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA24 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA25 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA26 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA27 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA28 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA29 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA30 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DATA31 JZ_GPIO_FUNC1
+
+/* Port B function pins */
+#define JZ_GPIO_MEM_ADDR0 JZ_GPIO_PORTB(0)
+#define JZ_GPIO_MEM_ADDR1 JZ_GPIO_PORTB(1)
+#define JZ_GPIO_MEM_ADDR2 JZ_GPIO_PORTB(2)
+#define JZ_GPIO_MEM_ADDR3 JZ_GPIO_PORTB(3)
+#define JZ_GPIO_MEM_ADDR4 JZ_GPIO_PORTB(4)
+#define JZ_GPIO_MEM_ADDR5 JZ_GPIO_PORTB(5)
+#define JZ_GPIO_MEM_ADDR6 JZ_GPIO_PORTB(6)
+#define JZ_GPIO_MEM_ADDR7 JZ_GPIO_PORTB(7)
+#define JZ_GPIO_MEM_ADDR8 JZ_GPIO_PORTB(8)
+#define JZ_GPIO_MEM_ADDR9 JZ_GPIO_PORTB(9)
+#define JZ_GPIO_MEM_ADDR10 JZ_GPIO_PORTB(10)
+#define JZ_GPIO_MEM_ADDR11 JZ_GPIO_PORTB(11)
+#define JZ_GPIO_MEM_ADDR12 JZ_GPIO_PORTB(12)
+#define JZ_GPIO_MEM_ADDR13 JZ_GPIO_PORTB(13)
+#define JZ_GPIO_MEM_ADDR14 JZ_GPIO_PORTB(14)
+#define JZ_GPIO_MEM_ADDR15 JZ_GPIO_PORTB(15)
+#define JZ_GPIO_MEM_ADDR16 JZ_GPIO_PORTB(16)
+#define JZ_GPIO_LCD_CLS JZ_GPIO_PORTB(17)
+#define JZ_GPIO_LCD_SPL JZ_GPIO_PORTB(18)
+#define JZ_GPIO_MEM_DCS JZ_GPIO_PORTB(19)
+#define JZ_GPIO_MEM_RAS JZ_GPIO_PORTB(20)
+#define JZ_GPIO_MEM_CAS JZ_GPIO_PORTB(21)
+#define JZ_GPIO_MEM_SDWE JZ_GPIO_PORTB(22)
+#define JZ_GPIO_MEM_CKE JZ_GPIO_PORTB(23)
+#define JZ_GPIO_MEM_CKO JZ_GPIO_PORTB(24)
+#define JZ_GPIO_MEM_CS0 JZ_GPIO_PORTB(25)
+#define JZ_GPIO_MEM_CS1 JZ_GPIO_PORTB(26)
+#define JZ_GPIO_MEM_CS2 JZ_GPIO_PORTB(27)
+#define JZ_GPIO_MEM_CS3 JZ_GPIO_PORTB(28)
+#define JZ_GPIO_MEM_RD JZ_GPIO_PORTB(29)
+#define JZ_GPIO_MEM_WR JZ_GPIO_PORTB(30)
+#define JZ_GPIO_MEM_WE0 JZ_GPIO_PORTB(31)
+
+#define JZ_GPIO_FUNC_MEM_ADDR0 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR1 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR2 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR3 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR4 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR5 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR6 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR7 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR8 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR9 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR10 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR11 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR12 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR13 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR14 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR15 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_ADDR16 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_CLS JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_SPL JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_DCS JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_RAS JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CAS JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_SDWE JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CKE JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CKO JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CS0 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CS1 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CS2 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_CS3 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_RD JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WR JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WE0 JZ_GPIO_FUNC1
+
+
+#define JZ_GPIO_MEM_ADDR21 JZ_GPIO_PORTB(17)
+#define JZ_GPIO_MEM_ADDR22 JZ_GPIO_PORTB(18)
+
+#define JZ_GPIO_FUNC_MEM_ADDR21 JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_ADDR22 JZ_GPIO_FUNC2
+
+/* Port C function pins */
+#define JZ_GPIO_LCD_DATA0 JZ_GPIO_PORTC(0)
+#define JZ_GPIO_LCD_DATA1 JZ_GPIO_PORTC(1)
+#define JZ_GPIO_LCD_DATA2 JZ_GPIO_PORTC(2)
+#define JZ_GPIO_LCD_DATA3 JZ_GPIO_PORTC(3)
+#define JZ_GPIO_LCD_DATA4 JZ_GPIO_PORTC(4)
+#define JZ_GPIO_LCD_DATA5 JZ_GPIO_PORTC(5)
+#define JZ_GPIO_LCD_DATA6 JZ_GPIO_PORTC(6)
+#define JZ_GPIO_LCD_DATA7 JZ_GPIO_PORTC(7)
+#define JZ_GPIO_LCD_DATA8 JZ_GPIO_PORTC(8)
+#define JZ_GPIO_LCD_DATA9 JZ_GPIO_PORTC(9)
+#define JZ_GPIO_LCD_DATA10 JZ_GPIO_PORTC(10)
+#define JZ_GPIO_LCD_DATA11 JZ_GPIO_PORTC(11)
+#define JZ_GPIO_LCD_DATA12 JZ_GPIO_PORTC(12)
+#define JZ_GPIO_LCD_DATA13 JZ_GPIO_PORTC(13)
+#define JZ_GPIO_LCD_DATA14 JZ_GPIO_PORTC(14)
+#define JZ_GPIO_LCD_DATA15 JZ_GPIO_PORTC(15)
+#define JZ_GPIO_LCD_DATA16 JZ_GPIO_PORTC(16)
+#define JZ_GPIO_LCD_DATA17 JZ_GPIO_PORTC(17)
+#define JZ_GPIO_LCD_PCLK JZ_GPIO_PORTC(18)
+#define JZ_GPIO_LCD_HSYNC JZ_GPIO_PORTC(19)
+#define JZ_GPIO_LCD_VSYNC JZ_GPIO_PORTC(20)
+#define JZ_GPIO_LCD_DE JZ_GPIO_PORTC(21)
+#define JZ_GPIO_LCD_PS JZ_GPIO_PORTC(22)
+#define JZ_GPIO_LCD_REV JZ_GPIO_PORTC(23)
+#define JZ_GPIO_MEM_WE1 JZ_GPIO_PORTC(24)
+#define JZ_GPIO_MEM_WE2 JZ_GPIO_PORTC(25)
+#define JZ_GPIO_MEM_WE3 JZ_GPIO_PORTC(26)
+#define JZ_GPIO_MEM_WAIT JZ_GPIO_PORTC(27)
+#define JZ_GPIO_MEM_FRE JZ_GPIO_PORTC(28)
+#define JZ_GPIO_MEM_FWE JZ_GPIO_PORTC(29)
+
+#define JZ_GPIO_FUNC_LCD_DATA0 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA1 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA2 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA3 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA4 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA5 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA6 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA7 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA8 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA9 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA10 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA11 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA12 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA13 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA14 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA15 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA16 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DATA17 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_PCLK JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_VSYNC JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_HSYNC JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_DE JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_PS JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_LCD_REV JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WE1 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WE2 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WE3 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_WAIT JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_FRE JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MEM_FWE JZ_GPIO_FUNC1
+
+
+#define JZ_GPIO_MEM_ADDR19 JZ_GPIO_PORTB(22)
+#define JZ_GPIO_MEM_ADDR20 JZ_GPIO_PORTB(23)
+
+#define JZ_GPIO_FUNC_MEM_ADDR19 JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_ADDR20 JZ_GPIO_FUNC2
+
+/* Port D function pins */
+#define JZ_GPIO_CIM_DATA0 JZ_GPIO_PORTD(0)
+#define JZ_GPIO_CIM_DATA1 JZ_GPIO_PORTD(1)
+#define JZ_GPIO_CIM_DATA2 JZ_GPIO_PORTD(2)
+#define JZ_GPIO_CIM_DATA3 JZ_GPIO_PORTD(3)
+#define JZ_GPIO_CIM_DATA4 JZ_GPIO_PORTD(4)
+#define JZ_GPIO_CIM_DATA5 JZ_GPIO_PORTD(5)
+#define JZ_GPIO_CIM_DATA6 JZ_GPIO_PORTD(6)
+#define JZ_GPIO_CIM_DATA7 JZ_GPIO_PORTD(7)
+#define JZ_GPIO_MSC_CMD JZ_GPIO_PORTD(8)
+#define JZ_GPIO_MSC_CLK JZ_GPIO_PORTD(9)
+#define JZ_GPIO_MSC_DATA0 JZ_GPIO_PORTD(10)
+#define JZ_GPIO_MSC_DATA1 JZ_GPIO_PORTD(11)
+#define JZ_GPIO_MSC_DATA2 JZ_GPIO_PORTD(12)
+#define JZ_GPIO_MSC_DATA3 JZ_GPIO_PORTD(13)
+#define JZ_GPIO_CIM_MCLK JZ_GPIO_PORTD(14)
+#define JZ_GPIO_CIM_PCLK JZ_GPIO_PORTD(15)
+#define JZ_GPIO_CIM_VSYNC JZ_GPIO_PORTD(16)
+#define JZ_GPIO_CIM_HSYNC JZ_GPIO_PORTD(17)
+#define JZ_GPIO_SPI_CLK JZ_GPIO_PORTD(18)
+#define JZ_GPIO_SPI_CE0 JZ_GPIO_PORTD(19)
+#define JZ_GPIO_SPI_DT JZ_GPIO_PORTD(20)
+#define JZ_GPIO_SPI_DR JZ_GPIO_PORTD(21)
+#define JZ_GPIO_SPI_CE1 JZ_GPIO_PORTD(22)
+#define JZ_GPIO_PWM0 JZ_GPIO_PORTD(23)
+#define JZ_GPIO_PWM1 JZ_GPIO_PORTD(24)
+#define JZ_GPIO_PWM2 JZ_GPIO_PORTD(25)
+#define JZ_GPIO_PWM3 JZ_GPIO_PORTD(26)
+#define JZ_GPIO_PWM4 JZ_GPIO_PORTD(27)
+#define JZ_GPIO_PWM5 JZ_GPIO_PORTD(28)
+#define JZ_GPIO_PWM6 JZ_GPIO_PORTD(30)
+#define JZ_GPIO_PWM7 JZ_GPIO_PORTD(31)
+
+#define JZ_GPIO_FUNC_CIM_DATA JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_CIM_DATA0 JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA1 JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA2 JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA3 JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA4 JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA5 JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA6 JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_CIM_DATA7 JZ_GPIO_FUNC_CIM_DATA
+#define JZ_GPIO_FUNC_MSC_CMD JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MSC_CLK JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MSC_DATA JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_MSC_DATA0 JZ_GPIO_FUNC_MSC_DATA
+#define JZ_GPIO_FUNC_MSC_DATA1 JZ_GPIO_FUNC_MSC_DATA
+#define JZ_GPIO_FUNC_MSC_DATA2 JZ_GPIO_FUNC_MSC_DATA
+#define JZ_GPIO_FUNC_MSC_DATA3 JZ_GPIO_FUNC_MSC_DATA
+#define JZ_GPIO_FUNC_CIM_MCLK JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_CIM_PCLK JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_CIM_VSYNC JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_CIM_HSYNC JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_CLK JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_CE0 JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_DT JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_DR JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_SPI_CE1 JZ_GPIO_FUNC1
+
+#define JZ_GPIO_FUNC_PWM JZ_GPIO_FUNC1
+#define JZ_GPIO_FUNC_PWM0 JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM1 JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM2 JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM3 JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM4 JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM5 JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM6 JZ_GPIO_FUNC_PWM
+#define JZ_GPIO_FUNC_PWM7 JZ_GPIO_FUNC_PWM
+
+#define JZ_GPIO_MEM_SCLK_RSTN JZ_GPIO_PORTD(18)
+#define JZ_GPIO_MEM_BCLK JZ_GPIO_PORTD(19)
+#define JZ_GPIO_MEM_SDATO JZ_GPIO_PORTD(20)
+#define JZ_GPIO_MEM_SDATI JZ_GPIO_PORTD(21)
+#define JZ_GPIO_MEM_SYNC JZ_GPIO_PORTD(22)
+#define JZ_GPIO_I2C_SDA JZ_GPIO_PORTD(23)
+#define JZ_GPIO_I2C_SCK JZ_GPIO_PORTD(24)
+#define JZ_GPIO_UART0_TXD JZ_GPIO_PORTD(25)
+#define JZ_GPIO_UART0_RXD JZ_GPIO_PORTD(26)
+#define JZ_GPIO_MEM_ADDR17 JZ_GPIO_PORTD(27)
+#define JZ_GPIO_MEM_ADDR18 JZ_GPIO_PORTD(28)
+#define JZ_GPIO_UART0_CTS JZ_GPIO_PORTD(30)
+#define JZ_GPIO_UART0_RTS JZ_GPIO_PORTD(31)
+
+#define JZ_GPIO_FUNC_MEM_SCLK_RSTN JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_BCLK JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_SDATO JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_SDATI JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_SYNC JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_I2C_SDA JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_I2C_SCK JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_UART0_TXD JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_UART0_RXD JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_ADDR17 JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_MEM_ADDR18 JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_UART0_CTS JZ_GPIO_FUNC2
+#define JZ_GPIO_FUNC_UART0_RTS JZ_GPIO_FUNC2
+
+#define JZ_GPIO_UART1_RXD JZ_GPIO_PORTD(30)
+#define JZ_GPIO_UART1_TXD JZ_GPIO_PORTD(31)
+
+#define JZ_GPIO_FUNC_UART1_RXD JZ_GPIO_FUNC3
+#define JZ_GPIO_FUNC_UART1_TXD JZ_GPIO_FUNC3
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
new file mode 100644
index 00000000..a865c983
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_IRQ_H__
+#define __ASM_MACH_JZ4740_IRQ_H__
+
+#define MIPS_CPU_IRQ_BASE 0
+#define JZ4740_IRQ_BASE 8
+
+/* 1st-level interrupts */
+#define JZ4740_IRQ(x) (JZ4740_IRQ_BASE + (x))
+#define JZ4740_IRQ_I2C JZ4740_IRQ(1)
+#define JZ4740_IRQ_UHC JZ4740_IRQ(3)
+#define JZ4740_IRQ_UART1 JZ4740_IRQ(8)
+#define JZ4740_IRQ_UART0 JZ4740_IRQ(9)
+#define JZ4740_IRQ_SADC JZ4740_IRQ(12)
+#define JZ4740_IRQ_MSC JZ4740_IRQ(14)
+#define JZ4740_IRQ_RTC JZ4740_IRQ(15)
+#define JZ4740_IRQ_SSI JZ4740_IRQ(16)
+#define JZ4740_IRQ_CIM JZ4740_IRQ(17)
+#define JZ4740_IRQ_AIC JZ4740_IRQ(18)
+#define JZ4740_IRQ_ETH JZ4740_IRQ(19)
+#define JZ4740_IRQ_DMAC JZ4740_IRQ(20)
+#define JZ4740_IRQ_TCU2 JZ4740_IRQ(21)
+#define JZ4740_IRQ_TCU1 JZ4740_IRQ(22)
+#define JZ4740_IRQ_TCU0 JZ4740_IRQ(23)
+#define JZ4740_IRQ_UDC JZ4740_IRQ(24)
+#define JZ4740_IRQ_GPIO3 JZ4740_IRQ(25)
+#define JZ4740_IRQ_GPIO2 JZ4740_IRQ(26)
+#define JZ4740_IRQ_GPIO1 JZ4740_IRQ(27)
+#define JZ4740_IRQ_GPIO0 JZ4740_IRQ(28)
+#define JZ4740_IRQ_IPU JZ4740_IRQ(29)
+#define JZ4740_IRQ_LCD JZ4740_IRQ(30)
+
+/* 2nd-level interrupts */
+#define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(32) + (X))
+
+#define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
+#define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x))
+
+#define JZ4740_IRQ_ADC_BASE JZ4740_IRQ(176)
+
+#define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_fb.h b/arch/mips/include/asm/mach-jz4740/jz4740_fb.h
new file mode 100644
index 00000000..6a50e6f7
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_fb.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_JZ4740_FB_H__
+#define __ASM_MACH_JZ4740_JZ4740_FB_H__
+
+#include <linux/fb.h>
+
+enum jz4740_fb_lcd_type {
+ JZ_LCD_TYPE_GENERIC_16_BIT = 0,
+ JZ_LCD_TYPE_GENERIC_18_BIT = 0 | (1 << 4),
+ JZ_LCD_TYPE_SPECIAL_TFT_1 = 1,
+ JZ_LCD_TYPE_SPECIAL_TFT_2 = 2,
+ JZ_LCD_TYPE_SPECIAL_TFT_3 = 3,
+ JZ_LCD_TYPE_NON_INTERLACED_CCIR656 = 5,
+ JZ_LCD_TYPE_INTERLACED_CCIR656 = 7,
+ JZ_LCD_TYPE_SINGLE_COLOR_STN = 8,
+ JZ_LCD_TYPE_SINGLE_MONOCHROME_STN = 9,
+ JZ_LCD_TYPE_DUAL_COLOR_STN = 10,
+ JZ_LCD_TYPE_DUAL_MONOCHROME_STN = 11,
+ JZ_LCD_TYPE_8BIT_SERIAL = 12,
+};
+
+#define JZ4740_FB_SPECIAL_TFT_CONFIG(start, stop) (((start) << 16) | (stop))
+
+/*
+* width: width of the lcd display in mm
+* height: height of the lcd display in mm
+* num_modes: size of modes
+* modes: list of valid video modes
+* bpp: bits per pixel for the lcd
+* lcd_type: lcd type
+*/
+
+struct jz4740_fb_platform_data {
+ unsigned int width;
+ unsigned int height;
+
+ size_t num_modes;
+ struct fb_videomode *modes;
+
+ unsigned int bpp;
+ enum jz4740_fb_lcd_type lcd_type;
+
+ struct {
+ uint32_t spl;
+ uint32_t cls;
+ uint32_t ps;
+ uint32_t rev;
+ } special_tft_config;
+
+ unsigned pixclk_falling_edge:1;
+ unsigned date_enable_active_low:1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h b/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h
new file mode 100644
index 00000000..8543f432
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h
@@ -0,0 +1,15 @@
+#ifndef __LINUX_MMC_JZ4740_MMC
+#define __LINUX_MMC_JZ4740_MMC
+
+struct jz4740_mmc_platform_data {
+ int gpio_power;
+ int gpio_card_detect;
+ int gpio_read_only;
+ unsigned card_detect_active_low:1;
+ unsigned read_only_active_low:1;
+ unsigned power_active_low:1;
+
+ unsigned data_1bit:1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
new file mode 100644
index 00000000..bb5b9a4e
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC NAND controller driver
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_JZ4740_NAND_H__
+#define __ASM_MACH_JZ4740_JZ4740_NAND_H__
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+struct jz_nand_platform_data {
+ int num_partitions;
+ struct mtd_partition *partitions;
+
+ struct nand_ecclayout *ecc_layout;
+
+ unsigned int busy_gpio;
+
+ void (*ident_callback)(struct platform_device *, struct nand_chip *,
+ struct mtd_partition **, int *num_partitions);
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
new file mode 100644
index 00000000..564ab81d
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/platform.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#ifndef __JZ4740_PLATFORM_H
+#define __JZ4740_PLATFORM_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_device jz4740_usb_ohci_device;
+extern struct platform_device jz4740_udc_device;
+extern struct platform_device jz4740_mmc_device;
+extern struct platform_device jz4740_rtc_device;
+extern struct platform_device jz4740_i2c_device;
+extern struct platform_device jz4740_nand_device;
+extern struct platform_device jz4740_framebuffer_device;
+extern struct platform_device jz4740_i2s_device;
+extern struct platform_device jz4740_pcm_device;
+extern struct platform_device jz4740_codec_device;
+extern struct platform_device jz4740_adc_device;
+extern struct platform_device jz4740_wdt_device;
+
+void jz4740_serial_device_register(void);
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/timer.h b/arch/mips/include/asm/mach-jz4740/timer.h
new file mode 100644
index 00000000..9baa03ce
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/timer.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform timer support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_MACH_JZ4740_TIMER
+#define __ASM_MACH_JZ4740_TIMER
+
+void jz4740_timer_enable_watchdog(void);
+void jz4740_timer_disable_watchdog(void);
+
+#endif
diff --git a/arch/mips/include/asm/mach-jz4740/war.h b/arch/mips/include/asm/mach-jz4740/war.h
new file mode 100644
index 00000000..3a5bc17e
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_JZ4740_WAR_H
+#define __ASM_MIPS_MACH_JZ4740_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_JZ4740_WAR_H */
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
new file mode 100644
index 00000000..ce2f0292
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -0,0 +1,63 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+#ifndef _LANTIQ_H__
+#define _LANTIQ_H__
+
+#include <linux/irq.h>
+
+/* generic reg access functions */
+#define ltq_r32(reg) __raw_readl(reg)
+#define ltq_w32(val, reg) __raw_writel(val, reg)
+#define ltq_w32_mask(clear, set, reg) \
+ ltq_w32((ltq_r32(reg) & ~(clear)) | (set), reg)
+#define ltq_r8(reg) __raw_readb(reg)
+#define ltq_w8(val, reg) __raw_writeb(val, reg)
+
+/* register access macros for EBU and CGU */
+#define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y))
+#define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x))
+#define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y))
+#define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x))
+
+extern __iomem void *ltq_ebu_membase;
+extern __iomem void *ltq_cgu_membase;
+
+extern unsigned int ltq_get_cpu_ver(void);
+extern unsigned int ltq_get_soc_type(void);
+
+/* clock speeds */
+#define CLOCK_60M 60000000
+#define CLOCK_83M 83333333
+#define CLOCK_111M 111111111
+#define CLOCK_133M 133333333
+#define CLOCK_167M 166666667
+#define CLOCK_200M 200000000
+#define CLOCK_266M 266666666
+#define CLOCK_333M 333333333
+#define CLOCK_400M 400000000
+
+/* spinlock all ebu i/o */
+extern spinlock_t ebu_lock;
+
+/* some irq helpers */
+extern void ltq_disable_irq(struct irq_data *data);
+extern void ltq_mask_and_ack_irq(struct irq_data *data);
+extern void ltq_enable_irq(struct irq_data *data);
+
+/* find out what caused the last cpu reset */
+extern int ltq_reset_cause(void);
+#define LTQ_RST_CAUSE_WDTRST 0x20
+
+#define IOPORT_RESOURCE_START 0x10000000
+#define IOPORT_RESOURCE_END 0xffffffff
+#define IOMEM_RESOURCE_START 0x10000000
+#define IOMEM_RESOURCE_END 0xffffffff
+#define LTQ_FLASH_START 0x10000000
+#define LTQ_FLASH_MAX 0x04000000
+
+#endif
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
new file mode 100644
index 00000000..a305f1d0
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
@@ -0,0 +1,53 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_PLATFORM_H__
+#define _LANTIQ_PLATFORM_H__
+
+#include <linux/mtd/partitions.h>
+#include <linux/socket.h>
+
+/* struct used to pass info to the pci core */
+enum {
+ PCI_CLOCK_INT = 0,
+ PCI_CLOCK_EXT
+};
+
+#define PCI_EXIN0 0x0001
+#define PCI_EXIN1 0x0002
+#define PCI_EXIN2 0x0004
+#define PCI_EXIN3 0x0008
+#define PCI_EXIN4 0x0010
+#define PCI_EXIN5 0x0020
+#define PCI_EXIN_MAX 6
+
+#define PCI_GNT1 0x0040
+#define PCI_GNT2 0x0080
+#define PCI_GNT3 0x0100
+#define PCI_GNT4 0x0200
+
+#define PCI_REQ1 0x0400
+#define PCI_REQ2 0x0800
+#define PCI_REQ3 0x1000
+#define PCI_REQ4 0x2000
+#define PCI_REQ_SHIFT 10
+#define PCI_REQ_MASK 0xf
+
+struct ltq_pci_data {
+ int clock;
+ int gpio;
+ int irq[16];
+};
+
+/* struct used to pass info to network drivers */
+struct ltq_eth_data {
+ struct sockaddr mac;
+ int mii_mode;
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-lantiq/war.h b/arch/mips/include/asm/mach-lantiq/war.h
new file mode 100644
index 00000000..01b08ef3
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/war.h
@@ -0,0 +1,24 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H
+#define __ASM_MIPS_MACH_LANTIQ_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif
diff --git a/arch/mips/include/asm/mach-lantiq/xway/irq.h b/arch/mips/include/asm/mach-lantiq/xway/irq.h
new file mode 100644
index 00000000..a1471d2d
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/xway/irq.h
@@ -0,0 +1,18 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef __LANTIQ_IRQ_H
+#define __LANTIQ_IRQ_H
+
+#include <lantiq_irq.h>
+
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
new file mode 100644
index 00000000..b4465a88
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -0,0 +1,66 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_XWAY_IRQ_H__
+#define _LANTIQ_XWAY_IRQ_H__
+
+#define INT_NUM_IRQ0 8
+#define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0)
+#define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32)
+#define INT_NUM_IM2_IRL0 (INT_NUM_IRQ0 + 64)
+#define INT_NUM_IM3_IRL0 (INT_NUM_IRQ0 + 96)
+#define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128)
+#define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
+
+#define LTQ_ASC_TIR(x) (INT_NUM_IM3_IRL0 + (x * 8))
+#define LTQ_ASC_RIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 1)
+#define LTQ_ASC_EIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 2)
+
+#define LTQ_ASC_ASE_TIR INT_NUM_IM2_IRL0
+#define LTQ_ASC_ASE_RIR (INT_NUM_IM2_IRL0 + 2)
+#define LTQ_ASC_ASE_EIR (INT_NUM_IM2_IRL0 + 3)
+
+#define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15)
+#define LTQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14)
+#define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16)
+
+#define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21)
+#define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23)
+
+#define LTQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23)
+#define LTQ_USB_INT (INT_NUM_IM1_IRL0 + 22)
+#define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23)
+
+#define MIPS_CPU_TIMER_IRQ 7
+
+#define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0)
+#define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1)
+#define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2)
+#define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3)
+#define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4)
+#define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5)
+#define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6)
+#define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7)
+#define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8)
+#define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9)
+#define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10)
+#define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11)
+#define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25)
+#define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26)
+#define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27)
+#define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28)
+#define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29)
+#define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30)
+#define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16)
+#define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21)
+
+#define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24)
+
+#define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14)
+
+#endif
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
new file mode 100644
index 00000000..8a3c6be6
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
@@ -0,0 +1,141 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_XWAY_H__
+#define _LTQ_XWAY_H__
+
+#ifdef CONFIG_SOC_TYPE_XWAY
+
+#include <lantiq.h>
+
+/* Chip IDs */
+#define SOC_ID_DANUBE1 0x129
+#define SOC_ID_DANUBE2 0x12B
+#define SOC_ID_TWINPASS 0x12D
+#define SOC_ID_AMAZON_SE 0x152
+#define SOC_ID_ARX188 0x16C
+#define SOC_ID_ARX168 0x16D
+#define SOC_ID_ARX182 0x16F
+
+/* SoC Types */
+#define SOC_TYPE_DANUBE 0x01
+#define SOC_TYPE_TWINPASS 0x02
+#define SOC_TYPE_AR9 0x03
+#define SOC_TYPE_VR9 0x04
+#define SOC_TYPE_AMAZON_SE 0x05
+
+/* ASC0/1 - serial port */
+#define LTQ_ASC0_BASE_ADDR 0x1E100400
+#define LTQ_ASC1_BASE_ADDR 0x1E100C00
+#define LTQ_ASC_SIZE 0x400
+
+/* RCU - reset control unit */
+#define LTQ_RCU_BASE_ADDR 0x1F203000
+#define LTQ_RCU_SIZE 0x1000
+
+/* GPTU - general purpose timer unit */
+#define LTQ_GPTU_BASE_ADDR 0x18000300
+#define LTQ_GPTU_SIZE 0x100
+
+/* EBU - external bus unit */
+#define LTQ_EBU_GPIO_START 0x14000000
+#define LTQ_EBU_GPIO_SIZE 0x1000
+
+#define LTQ_EBU_BASE_ADDR 0x1E105300
+#define LTQ_EBU_SIZE 0x100
+
+#define LTQ_EBU_BUSCON0 0x0060
+#define LTQ_EBU_PCC_CON 0x0090
+#define LTQ_EBU_PCC_IEN 0x00A4
+#define LTQ_EBU_PCC_ISTAT 0x00A0
+#define LTQ_EBU_BUSCON1 0x0064
+#define LTQ_EBU_ADDRSEL1 0x0024
+#define EBU_WRDIS 0x80000000
+
+/* CGU - clock generation unit */
+#define LTQ_CGU_BASE_ADDR 0x1F103000
+#define LTQ_CGU_SIZE 0x1000
+
+/* ICU - interrupt control unit */
+#define LTQ_ICU_BASE_ADDR 0x1F880200
+#define LTQ_ICU_SIZE 0x100
+
+/* EIU - external interrupt unit */
+#define LTQ_EIU_BASE_ADDR 0x1F101000
+#define LTQ_EIU_SIZE 0x1000
+
+/* PMU - power management unit */
+#define LTQ_PMU_BASE_ADDR 0x1F102000
+#define LTQ_PMU_SIZE 0x1000
+
+#define PMU_DMA 0x0020
+#define PMU_USB 0x8041
+#define PMU_LED 0x0800
+#define PMU_GPT 0x1000
+#define PMU_PPE 0x2000
+#define PMU_FPI 0x4000
+#define PMU_SWITCH 0x10000000
+
+/* ETOP - ethernet */
+#define LTQ_ETOP_BASE_ADDR 0x1E180000
+#define LTQ_ETOP_SIZE 0x40000
+
+/* DMA */
+#define LTQ_DMA_BASE_ADDR 0x1E104100
+#define LTQ_DMA_SIZE 0x800
+
+/* PCI */
+#define PCI_CR_BASE_ADDR 0x1E105400
+#define PCI_CR_SIZE 0x400
+
+/* WDT */
+#define LTQ_WDT_BASE_ADDR 0x1F8803F0
+#define LTQ_WDT_SIZE 0x10
+
+/* STP - serial to parallel conversion unit */
+#define LTQ_STP_BASE_ADDR 0x1E100BB0
+#define LTQ_STP_SIZE 0x40
+
+/* GPIO */
+#define LTQ_GPIO0_BASE_ADDR 0x1E100B10
+#define LTQ_GPIO1_BASE_ADDR 0x1E100B40
+#define LTQ_GPIO2_BASE_ADDR 0x1E100B70
+#define LTQ_GPIO_SIZE 0x30
+
+/* SSC */
+#define LTQ_SSC_BASE_ADDR 0x1e100800
+#define LTQ_SSC_SIZE 0x100
+
+/* MEI - dsl core */
+#define LTQ_MEI_BASE_ADDR 0x1E116000
+
+/* DEU - data encryption unit */
+#define LTQ_DEU_BASE_ADDR 0x1E103100
+
+/* MPS - multi processor unit (voice) */
+#define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000)
+#define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
+
+/* request a non-gpio and set the PIO config */
+extern int ltq_gpio_request(unsigned int pin, unsigned int alt0,
+ unsigned int alt1, unsigned int dir, const char *name);
+extern void ltq_pmu_enable(unsigned int module);
+extern void ltq_pmu_disable(unsigned int module);
+
+static inline int ltq_is_ar9(void)
+{
+ return (ltq_get_soc_type() == SOC_TYPE_AR9);
+}
+
+static inline int ltq_is_vr9(void)
+{
+ return (ltq_get_soc_type() == SOC_TYPE_VR9);
+}
+
+#endif /* CONFIG_SOC_TYPE_XWAY */
+#endif /* _LTQ_XWAY_H__ */
diff --git a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
new file mode 100644
index 00000000..872943a4
--- /dev/null
+++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
@@ -0,0 +1,60 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef LTQ_DMA_H__
+#define LTQ_DMA_H__
+
+#define LTQ_DESC_SIZE 0x08 /* each descriptor is 64bit */
+#define LTQ_DESC_NUM 0x40 /* 64 descriptors / channel */
+
+#define LTQ_DMA_OWN BIT(31) /* owner bit */
+#define LTQ_DMA_C BIT(30) /* complete bit */
+#define LTQ_DMA_SOP BIT(29) /* start of packet */
+#define LTQ_DMA_EOP BIT(28) /* end of packet */
+#define LTQ_DMA_TX_OFFSET(x) ((x & 0x1f) << 23) /* data bytes offset */
+#define LTQ_DMA_RX_OFFSET(x) ((x & 0x7) << 23) /* data bytes offset */
+#define LTQ_DMA_SIZE_MASK (0xffff) /* the size field is 16 bit */
+
+struct ltq_dma_desc {
+ u32 ctl;
+ u32 addr;
+};
+
+struct ltq_dma_channel {
+ int nr; /* the channel number */
+ int irq; /* the mapped irq */
+ int desc; /* the current descriptor */
+ struct ltq_dma_desc *desc_base; /* the descriptor base */
+ int phys; /* physical addr */
+};
+
+enum {
+ DMA_PORT_ETOP = 0,
+ DMA_PORT_DEU,
+};
+
+extern void ltq_dma_enable_irq(struct ltq_dma_channel *ch);
+extern void ltq_dma_disable_irq(struct ltq_dma_channel *ch);
+extern void ltq_dma_ack_irq(struct ltq_dma_channel *ch);
+extern void ltq_dma_open(struct ltq_dma_channel *ch);
+extern void ltq_dma_close(struct ltq_dma_channel *ch);
+extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch);
+extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch);
+extern void ltq_dma_free(struct ltq_dma_channel *ch);
+extern void ltq_dma_init_port(int p);
+
+#endif
diff --git a/arch/mips/include/asm/mach-lasat/irq.h b/arch/mips/include/asm/mach-lasat/irq.h
new file mode 100644
index 00000000..3a282419
--- /dev/null
+++ b/arch/mips/include/asm/mach-lasat/irq.h
@@ -0,0 +1,13 @@
+#ifndef _ASM_MACH_LASAT_IRQ_H
+#define _ASM_MACH_LASAT_IRQ_H
+
+#define LASAT_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 2)
+
+#define LASAT_IRQ_BASE 8
+#define LASAT_IRQ_END 23
+
+#define NR_IRQS 24
+
+#include_next <irq.h>
+
+#endif /* _ASM_MACH_LASAT_IRQ_H */
diff --git a/arch/mips/include/asm/mach-lasat/mach-gt64120.h b/arch/mips/include/asm/mach-lasat/mach-gt64120.h
new file mode 100644
index 00000000..1a9ad45c
--- /dev/null
+++ b/arch/mips/include/asm/mach-lasat/mach-gt64120.h
@@ -0,0 +1,27 @@
+/*
+ * This is a direct copy of the ev96100.h file, with a global
+ * search and replace. The numbers are the same.
+ *
+ * The reason I'm duplicating this is so that the 64120/96100
+ * defines won't be confusing in the source code.
+ */
+#ifndef _ASM_GT64120_LASAT_GT64120_DEP_H
+#define _ASM_GT64120_LASAT_GT64120_DEP_H
+
+/*
+ * GT64120 config space base address on Lasat 100
+ */
+#define GT64120_BASE (KSEG1ADDR(0x14000000))
+
+/*
+ * PCI Bus allocation
+ *
+ * (Guessing ...)
+ */
+#define GT_PCI_MEM_BASE 0x12000000UL
+#define GT_PCI_MEM_SIZE 0x02000000UL
+#define GT_PCI_IO_BASE 0x10000000UL
+#define GT_PCI_IO_SIZE 0x02000000UL
+#define GT_ISA_IO_BASE PCI_IO_BASE
+
+#endif /* _ASM_GT64120_LASAT_GT64120_DEP_H */
diff --git a/arch/mips/include/asm/mach-lasat/war.h b/arch/mips/include/asm/mach-lasat/war.h
new file mode 100644
index 00000000..bb1e0325
--- /dev/null
+++ b/arch/mips/include/asm/mach-lasat/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_LASAT_WAR_H
+#define __ASM_MIPS_MACH_LASAT_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_LASAT_WAR_H */
diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
new file mode 100644
index 00000000..675bd864
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
@@ -0,0 +1,60 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
+ * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
+ * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
+ *
+ * reference: /proc/cpuinfo,
+ * arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
+ * arch/mips/kernel/proc.c(show_cpuinfo),
+ * loongson2f user manual.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+#define cpu_scache_line_size() 32
+
+
+#define cpu_has_32fpr 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_4kex 1
+#define cpu_has_64bits 1
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_counter 1
+#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
+#define cpu_has_divec 0
+#define cpu_has_dsp 0
+#define cpu_has_ejtag 0
+#define cpu_has_fpu 1
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_inclusive_pcaches 1
+#define cpu_has_llsc 1
+#define cpu_has_mcheck 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips16 0
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips3d 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+#define cpu_has_mipsmt 0
+#define cpu_has_prefetch 0
+#define cpu_has_smartmips 0
+#define cpu_has_tlb 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_userlocal 0
+#define cpu_has_vce 0
+#define cpu_has_veic 0
+#define cpu_has_vint 0
+#define cpu_has_vtag_icache 0
+#define cpu_has_watch 1
+
+#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
new file mode 100644
index 00000000..2a8e2bb5
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h
@@ -0,0 +1,305 @@
+/*
+ * The header file of cs5536 south bridge.
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu <liujl@lemote.com>
+ */
+
+#ifndef _CS5536_H
+#define _CS5536_H
+
+#include <linux/types.h>
+
+extern void _rdmsr(u32 msr, u32 *hi, u32 *lo);
+extern void _wrmsr(u32 msr, u32 hi, u32 lo);
+
+/*
+ * MSR module base
+ */
+#define CS5536_SB_MSR_BASE (0x00000000)
+#define CS5536_GLIU_MSR_BASE (0x10000000)
+#define CS5536_ILLEGAL_MSR_BASE (0x20000000)
+#define CS5536_USB_MSR_BASE (0x40000000)
+#define CS5536_IDE_MSR_BASE (0x60000000)
+#define CS5536_DIVIL_MSR_BASE (0x80000000)
+#define CS5536_ACC_MSR_BASE (0xa0000000)
+#define CS5536_UNUSED_MSR_BASE (0xc0000000)
+#define CS5536_GLCP_MSR_BASE (0xe0000000)
+
+#define SB_MSR_REG(offset) (CS5536_SB_MSR_BASE | (offset))
+#define GLIU_MSR_REG(offset) (CS5536_GLIU_MSR_BASE | (offset))
+#define ILLEGAL_MSR_REG(offset) (CS5536_ILLEGAL_MSR_BASE | (offset))
+#define USB_MSR_REG(offset) (CS5536_USB_MSR_BASE | (offset))
+#define IDE_MSR_REG(offset) (CS5536_IDE_MSR_BASE | (offset))
+#define DIVIL_MSR_REG(offset) (CS5536_DIVIL_MSR_BASE | (offset))
+#define ACC_MSR_REG(offset) (CS5536_ACC_MSR_BASE | (offset))
+#define UNUSED_MSR_REG(offset) (CS5536_UNUSED_MSR_BASE | (offset))
+#define GLCP_MSR_REG(offset) (CS5536_GLCP_MSR_BASE | (offset))
+
+/*
+ * BAR SPACE OF VIRTUAL PCI :
+ * range for pci probe use, length is the actual size.
+ */
+/* IO space for all DIVIL modules */
+#define CS5536_IRQ_RANGE 0xffffffe0 /* USERD FOR PCI PROBE */
+#define CS5536_IRQ_LENGTH 0x20 /* THE REGS ACTUAL LENGTH */
+#define CS5536_SMB_RANGE 0xfffffff8
+#define CS5536_SMB_LENGTH 0x08
+#define CS5536_GPIO_RANGE 0xffffff00
+#define CS5536_GPIO_LENGTH 0x100
+#define CS5536_MFGPT_RANGE 0xffffffc0
+#define CS5536_MFGPT_LENGTH 0x40
+#define CS5536_ACPI_RANGE 0xffffffe0
+#define CS5536_ACPI_LENGTH 0x20
+#define CS5536_PMS_RANGE 0xffffff80
+#define CS5536_PMS_LENGTH 0x80
+/* IO space for IDE */
+#define CS5536_IDE_RANGE 0xfffffff0
+#define CS5536_IDE_LENGTH 0x10
+/* IO space for ACC */
+#define CS5536_ACC_RANGE 0xffffff80
+#define CS5536_ACC_LENGTH 0x80
+/* MEM space for ALL USB modules */
+#define CS5536_OHCI_RANGE 0xfffff000
+#define CS5536_OHCI_LENGTH 0x1000
+#define CS5536_EHCI_RANGE 0xfffff000
+#define CS5536_EHCI_LENGTH 0x1000
+
+/*
+ * PCI MSR ACCESS
+ */
+#define PCI_MSR_CTRL 0xF0
+#define PCI_MSR_ADDR 0xF4
+#define PCI_MSR_DATA_LO 0xF8
+#define PCI_MSR_DATA_HI 0xFC
+
+/**************** MSR *****************************/
+
+/*
+ * GLIU STANDARD MSR
+ */
+#define GLIU_CAP 0x00
+#define GLIU_CONFIG 0x01
+#define GLIU_SMI 0x02
+#define GLIU_ERROR 0x03
+#define GLIU_PM 0x04
+#define GLIU_DIAG 0x05
+
+/*
+ * GLIU SPEC. MSR
+ */
+#define GLIU_P2D_BM0 0x20
+#define GLIU_P2D_BM1 0x21
+#define GLIU_P2D_BM2 0x22
+#define GLIU_P2D_BMK0 0x23
+#define GLIU_P2D_BMK1 0x24
+#define GLIU_P2D_BM3 0x25
+#define GLIU_P2D_BM4 0x26
+#define GLIU_COH 0x80
+#define GLIU_PAE 0x81
+#define GLIU_ARB 0x82
+#define GLIU_ASMI 0x83
+#define GLIU_AERR 0x84
+#define GLIU_DEBUG 0x85
+#define GLIU_PHY_CAP 0x86
+#define GLIU_NOUT_RESP 0x87
+#define GLIU_NOUT_WDATA 0x88
+#define GLIU_WHOAMI 0x8B
+#define GLIU_SLV_DIS 0x8C
+#define GLIU_IOD_BM0 0xE0
+#define GLIU_IOD_BM1 0xE1
+#define GLIU_IOD_BM2 0xE2
+#define GLIU_IOD_BM3 0xE3
+#define GLIU_IOD_BM4 0xE4
+#define GLIU_IOD_BM5 0xE5
+#define GLIU_IOD_BM6 0xE6
+#define GLIU_IOD_BM7 0xE7
+#define GLIU_IOD_BM8 0xE8
+#define GLIU_IOD_BM9 0xE9
+#define GLIU_IOD_SC0 0xEA
+#define GLIU_IOD_SC1 0xEB
+#define GLIU_IOD_SC2 0xEC
+#define GLIU_IOD_SC3 0xED
+#define GLIU_IOD_SC4 0xEE
+#define GLIU_IOD_SC5 0xEF
+#define GLIU_IOD_SC6 0xF0
+#define GLIU_IOD_SC7 0xF1
+
+/*
+ * SB STANDARD
+ */
+#define SB_CAP 0x00
+#define SB_CONFIG 0x01
+#define SB_SMI 0x02
+#define SB_ERROR 0x03
+#define SB_MAR_ERR_EN 0x00000001
+#define SB_TAR_ERR_EN 0x00000002
+#define SB_RSVD_BIT1 0x00000004
+#define SB_EXCEP_ERR_EN 0x00000008
+#define SB_SYSE_ERR_EN 0x00000010
+#define SB_PARE_ERR_EN 0x00000020
+#define SB_TAS_ERR_EN 0x00000040
+#define SB_MAR_ERR_FLAG 0x00010000
+#define SB_TAR_ERR_FLAG 0x00020000
+#define SB_RSVD_BIT2 0x00040000
+#define SB_EXCEP_ERR_FLAG 0x00080000
+#define SB_SYSE_ERR_FLAG 0x00100000
+#define SB_PARE_ERR_FLAG 0x00200000
+#define SB_TAS_ERR_FLAG 0x00400000
+#define SB_PM 0x04
+#define SB_DIAG 0x05
+
+/*
+ * SB SPEC.
+ */
+#define SB_CTRL 0x10
+#define SB_R0 0x20
+#define SB_R1 0x21
+#define SB_R2 0x22
+#define SB_R3 0x23
+#define SB_R4 0x24
+#define SB_R5 0x25
+#define SB_R6 0x26
+#define SB_R7 0x27
+#define SB_R8 0x28
+#define SB_R9 0x29
+#define SB_R10 0x2A
+#define SB_R11 0x2B
+#define SB_R12 0x2C
+#define SB_R13 0x2D
+#define SB_R14 0x2E
+#define SB_R15 0x2F
+
+/*
+ * GLCP STANDARD
+ */
+#define GLCP_CAP 0x00
+#define GLCP_CONFIG 0x01
+#define GLCP_SMI 0x02
+#define GLCP_ERROR 0x03
+#define GLCP_PM 0x04
+#define GLCP_DIAG 0x05
+
+/*
+ * GLCP SPEC.
+ */
+#define GLCP_CLK_DIS_DELAY 0x08
+#define GLCP_PM_CLK_DISABLE 0x09
+#define GLCP_GLB_PM 0x0B
+#define GLCP_DBG_OUT 0x0C
+#define GLCP_RSVD1 0x0D
+#define GLCP_SOFT_COM 0x0E
+#define SOFT_BAR_SMB_FLAG 0x00000001
+#define SOFT_BAR_GPIO_FLAG 0x00000002
+#define SOFT_BAR_MFGPT_FLAG 0x00000004
+#define SOFT_BAR_IRQ_FLAG 0x00000008
+#define SOFT_BAR_PMS_FLAG 0x00000010
+#define SOFT_BAR_ACPI_FLAG 0x00000020
+#define SOFT_BAR_IDE_FLAG 0x00000400
+#define SOFT_BAR_ACC_FLAG 0x00000800
+#define SOFT_BAR_OHCI_FLAG 0x00001000
+#define SOFT_BAR_EHCI_FLAG 0x00002000
+#define GLCP_RSVD2 0x0F
+#define GLCP_CLK_OFF 0x10
+#define GLCP_CLK_ACTIVE 0x11
+#define GLCP_CLK_DISABLE 0x12
+#define GLCP_CLK4ACK 0x13
+#define GLCP_SYS_RST 0x14
+#define GLCP_RSVD3 0x15
+#define GLCP_DBG_CLK_CTRL 0x16
+#define GLCP_CHIP_REV_ID 0x17
+
+/* PIC */
+#define PIC_YSEL_LOW 0x20
+#define PIC_YSEL_LOW_USB_SHIFT 8
+#define PIC_YSEL_LOW_ACC_SHIFT 16
+#define PIC_YSEL_LOW_FLASH_SHIFT 24
+#define PIC_YSEL_HIGH 0x21
+#define PIC_ZSEL_LOW 0x22
+#define PIC_ZSEL_HIGH 0x23
+#define PIC_IRQM_PRIM 0x24
+#define PIC_IRQM_LPC 0x25
+#define PIC_XIRR_STS_LOW 0x26
+#define PIC_XIRR_STS_HIGH 0x27
+#define PCI_SHDW 0x34
+
+/*
+ * DIVIL STANDARD
+ */
+#define DIVIL_CAP 0x00
+#define DIVIL_CONFIG 0x01
+#define DIVIL_SMI 0x02
+#define DIVIL_ERROR 0x03
+#define DIVIL_PM 0x04
+#define DIVIL_DIAG 0x05
+
+/*
+ * DIVIL SPEC.
+ */
+#define DIVIL_LBAR_IRQ 0x08
+#define DIVIL_LBAR_KEL 0x09
+#define DIVIL_LBAR_SMB 0x0B
+#define DIVIL_LBAR_GPIO 0x0C
+#define DIVIL_LBAR_MFGPT 0x0D
+#define DIVIL_LBAR_ACPI 0x0E
+#define DIVIL_LBAR_PMS 0x0F
+#define DIVIL_LEG_IO 0x14
+#define DIVIL_BALL_OPTS 0x15
+#define DIVIL_SOFT_IRQ 0x16
+#define DIVIL_SOFT_RESET 0x17
+
+/* MFGPT */
+#define MFGPT_IRQ 0x28
+
+/*
+ * IDE STANDARD
+ */
+#define IDE_CAP 0x00
+#define IDE_CONFIG 0x01
+#define IDE_SMI 0x02
+#define IDE_ERROR 0x03
+#define IDE_PM 0x04
+#define IDE_DIAG 0x05
+
+/*
+ * IDE SPEC.
+ */
+#define IDE_IO_BAR 0x08
+#define IDE_CFG 0x10
+#define IDE_DTC 0x12
+#define IDE_CAST 0x13
+#define IDE_ETC 0x14
+#define IDE_INTERNAL_PM 0x15
+
+/*
+ * ACC STANDARD
+ */
+#define ACC_CAP 0x00
+#define ACC_CONFIG 0x01
+#define ACC_SMI 0x02
+#define ACC_ERROR 0x03
+#define ACC_PM 0x04
+#define ACC_DIAG 0x05
+
+/*
+ * USB STANDARD
+ */
+#define USB_CAP 0x00
+#define USB_CONFIG 0x01
+#define USB_SMI 0x02
+#define USB_ERROR 0x03
+#define USB_PM 0x04
+#define USB_DIAG 0x05
+
+/*
+ * USB SPEC.
+ */
+#define USB_OHCI 0x08
+#define USB_EHCI 0x09
+
+/****************** NATIVE ***************************/
+/* GPIO : I/O SPACE; REG : 32BITS */
+#define GPIOL_OUT_VAL 0x00
+#define GPIOL_OUT_EN 0x04
+
+#endif /* _CS5536_H */
diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
new file mode 100644
index 00000000..4b493d67
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h
@@ -0,0 +1,35 @@
+/*
+ * cs5536 mfgpt header file
+ */
+
+#ifndef _CS5536_MFGPT_H
+#define _CS5536_MFGPT_H
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+#ifdef CONFIG_CS5536_MFGPT
+extern void setup_mfgpt0_timer(void);
+extern void disable_mfgpt0_counter(void);
+extern void enable_mfgpt0_counter(void);
+#else
+static inline void __maybe_unused setup_mfgpt0_timer(void)
+{
+}
+static inline void __maybe_unused disable_mfgpt0_counter(void)
+{
+}
+static inline void __maybe_unused enable_mfgpt0_counter(void)
+{
+}
+#endif
+
+#define MFGPT_TICK_RATE 14318000
+#define COMPARE ((MFGPT_TICK_RATE + HZ/2) / HZ)
+
+#define MFGPT_BASE mfgpt_base
+#define MFGPT0_CMP2 (MFGPT_BASE + 2)
+#define MFGPT0_CNT (MFGPT_BASE + 4)
+#define MFGPT0_SETUP (MFGPT_BASE + 6)
+
+#endif /*!_CS5536_MFGPT_H */
diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
new file mode 100644
index 00000000..0dca9c89
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h
@@ -0,0 +1,153 @@
+/*
+ * the definition file of cs5536 Virtual Support Module(VSM).
+ * pci configuration space can be accessed through the VSM, so
+ * there is no need of the MSR read/write now, except the spec.
+ * MSR registers which are not implemented yet.
+ *
+ * Copyright (C) 2007 Lemote Inc.
+ * Author : jlliu, liujl@lemote.com
+ */
+
+#ifndef _CS5536_PCI_H
+#define _CS5536_PCI_H
+
+#include <linux/types.h>
+#include <linux/pci_regs.h>
+
+extern void cs5536_pci_conf_write4(int function, int reg, u32 value);
+extern u32 cs5536_pci_conf_read4(int function, int reg);
+
+#define CS5536_ACC_INTR 9
+#define CS5536_IDE_INTR 14
+#define CS5536_USB_INTR 11
+#define CS5536_MFGPT_INTR 5
+#define CS5536_UART1_INTR 4
+#define CS5536_UART2_INTR 3
+
+/************** PCI BUS DEVICE FUNCTION ***************/
+
+/*
+ * PCI bus device function
+ */
+#define PCI_BUS_CS5536 0
+#define PCI_IDSEL_CS5536 14
+
+/********** STANDARD PCI-2.2 EXPANSION ****************/
+
+/*
+ * PCI configuration space
+ * we have to virtualize the PCI configure space head, so we should
+ * define the necessary IDs and some others.
+ */
+
+/* CONFIG of PCI VENDOR ID*/
+#define CFG_PCI_VENDOR_ID(mod_dev_id, sys_vendor_id) \
+ (((mod_dev_id) << 16) | (sys_vendor_id))
+
+/* VENDOR ID */
+#define CS5536_VENDOR_ID 0x1022
+
+/* DEVICE ID */
+#define CS5536_ISA_DEVICE_ID 0x2090
+#define CS5536_IDE_DEVICE_ID 0x209a
+#define CS5536_ACC_DEVICE_ID 0x2093
+#define CS5536_OHCI_DEVICE_ID 0x2094
+#define CS5536_EHCI_DEVICE_ID 0x2095
+
+/* CLASS CODE : CLASS SUB-CLASS INTERFACE */
+#define CS5536_ISA_CLASS_CODE 0x060100
+#define CS5536_IDE_CLASS_CODE 0x010180
+#define CS5536_ACC_CLASS_CODE 0x040100
+#define CS5536_OHCI_CLASS_CODE 0x0C0310
+#define CS5536_EHCI_CLASS_CODE 0x0C0320
+
+/* BHLC : BIST HEADER-TYPE LATENCY-TIMER CACHE-LINE-SIZE */
+
+#define CFG_PCI_CACHE_LINE_SIZE(header_type, latency_timer) \
+ ((PCI_NONE_BIST << 24) | ((header_type) << 16) \
+ | ((latency_timer) << 8) | PCI_NORMAL_CACHE_LINE_SIZE);
+
+#define PCI_NONE_BIST 0x00 /* RO not implemented yet. */
+#define PCI_BRIDGE_HEADER_TYPE 0x80 /* RO */
+#define PCI_NORMAL_HEADER_TYPE 0x00
+#define PCI_NORMAL_LATENCY_TIMER 0x00
+#define PCI_NORMAL_CACHE_LINE_SIZE 0x08 /* RW */
+
+/* BAR */
+#define PCI_BAR0_REG 0x10
+#define PCI_BAR1_REG 0x14
+#define PCI_BAR2_REG 0x18
+#define PCI_BAR3_REG 0x1c
+#define PCI_BAR4_REG 0x20
+#define PCI_BAR5_REG 0x24
+#define PCI_BAR_COUNT 6
+#define PCI_BAR_RANGE_MASK 0xFFFFFFFF
+
+/* CARDBUS CIS POINTER */
+#define PCI_CARDBUS_CIS_POINTER 0x00000000
+
+/* SUBSYSTEM VENDOR ID */
+#define CS5536_SUB_VENDOR_ID CS5536_VENDOR_ID
+
+/* SUBSYSTEM ID */
+#define CS5536_ISA_SUB_ID CS5536_ISA_DEVICE_ID
+#define CS5536_IDE_SUB_ID CS5536_IDE_DEVICE_ID
+#define CS5536_ACC_SUB_ID CS5536_ACC_DEVICE_ID
+#define CS5536_OHCI_SUB_ID CS5536_OHCI_DEVICE_ID
+#define CS5536_EHCI_SUB_ID CS5536_EHCI_DEVICE_ID
+
+/* EXPANSION ROM BAR */
+#define PCI_EXPANSION_ROM_BAR 0x00000000
+
+/* CAPABILITIES POINTER */
+#define PCI_CAPLIST_POINTER 0x00000000
+#define PCI_CAPLIST_USB_POINTER 0x40
+/* INTERRUPT */
+
+#define CFG_PCI_INTERRUPT_LINE(pin, mod_intr) \
+ ((PCI_MAX_LATENCY << 24) | (PCI_MIN_GRANT << 16) | \
+ ((pin) << 8) | (mod_intr))
+
+#define PCI_MAX_LATENCY 0x40
+#define PCI_MIN_GRANT 0x00
+#define PCI_DEFAULT_PIN 0x01
+
+/*********** EXPANSION PCI REG ************************/
+
+/*
+ * ISA EXPANSION
+ */
+#define PCI_UART1_INT_REG 0x50
+#define PCI_UART2_INT_REG 0x54
+#define PCI_ISA_FIXUP_REG 0x58
+
+/*
+ * IDE EXPANSION
+ */
+#define PCI_IDE_CFG_REG 0x40
+#define CS5536_IDE_FLASH_SIGNATURE 0xDEADBEEF
+#define PCI_IDE_DTC_REG 0x48
+#define PCI_IDE_CAST_REG 0x4C
+#define PCI_IDE_ETC_REG 0x50
+#define PCI_IDE_PM_REG 0x54
+#define PCI_IDE_INT_REG 0x60
+
+/*
+ * ACC EXPANSION
+ */
+#define PCI_ACC_INT_REG 0x50
+
+/*
+ * OHCI EXPANSION : INTTERUPT IS IMPLEMENTED BY THE OHCI
+ */
+#define PCI_OHCI_PM_REG 0x40
+#define PCI_OHCI_INT_REG 0x50
+
+/*
+ * EHCI EXPANSION
+ */
+#define PCI_EHCI_LEGSMIEN_REG 0x50
+#define PCI_EHCI_LEGSMISTS_REG 0x54
+#define PCI_EHCI_FLADJ_REG 0x60
+
+#endif /* _CS5536_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h
new file mode 100644
index 00000000..21c4eced
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h
@@ -0,0 +1,31 @@
+/*
+ * the read/write interfaces for Virtual Support Module(VSM)
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#ifndef _CS5536_VSM_H
+#define _CS5536_VSM_H
+
+#include <linux/types.h>
+
+typedef void (*cs5536_pci_vsm_write)(int reg, u32 value);
+typedef u32 (*cs5536_pci_vsm_read)(int reg);
+
+#define DECLARE_CS5536_MODULE(name) \
+extern void pci_##name##_write_reg(int reg, u32 value); \
+extern u32 pci_##name##_read_reg(int reg);
+
+/* ide module */
+DECLARE_CS5536_MODULE(ide)
+/* acc module */
+DECLARE_CS5536_MODULE(acc)
+/* ohci module */
+DECLARE_CS5536_MODULE(ohci)
+/* isa module */
+DECLARE_CS5536_MODULE(isa)
+/* ehci module */
+DECLARE_CS5536_MODULE(ehci)
+
+#endif /* _CS5536_VSM_H */
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
new file mode 100644
index 00000000..981c75f9
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h
@@ -0,0 +1,72 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006, 07 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ */
+#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H
+#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H
+
+struct device;
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+ size_t size)
+{
+ return virt_to_phys(addr) | 0x80000000;
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ return page_to_phys(page) | 0x80000000;
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
+{
+#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
+ return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
+#else
+ return dma_addr & 0x7fffffff;
+#endif
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+ return 0;
+}
+
+#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-loongson/gpio.h b/arch/mips/include/asm/mach-loongson/gpio.h
new file mode 100644
index 00000000..e30e73d4
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/gpio.h
@@ -0,0 +1,35 @@
+/*
+ * STLS2F GPIO Support
+ *
+ * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
+ * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __STLS2F_GPIO_H
+#define __STLS2F_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+extern void gpio_set_value(unsigned gpio, int value);
+extern int gpio_get_value(unsigned gpio);
+extern int gpio_cansleep(unsigned gpio);
+
+/* The chip can do interrupt
+ * but it has not been tested and doc not clear
+ */
+static inline int gpio_to_irq(int gpio)
+{
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(int gpio)
+{
+ return -EINVAL;
+}
+
+#endif /* __STLS2F_GPIO_H */
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
new file mode 100644
index 00000000..1e29b9dd
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_LOONGSON_H
+#define __ASM_MACH_LOONGSON_LOONGSON_H
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+/* loongson internal northbridge initialization */
+extern void bonito_irq_init(void);
+
+/* machine-specific reboot/halt operation */
+extern void mach_prepare_reboot(void);
+extern void mach_prepare_shutdown(void);
+
+/* environment arguments from bootloader */
+extern unsigned long cpu_clock_freq;
+extern unsigned long memsize, highmemsize;
+
+/* loongson-specific command line, env and memory initialization */
+extern void __init prom_init_memory(void);
+extern void __init prom_init_cmdline(void);
+extern void __init prom_init_machtype(void);
+extern void __init prom_init_env(void);
+#ifdef CONFIG_LOONGSON_UART_BASE
+extern unsigned long _loongson_uart_base, loongson_uart_base;
+extern void prom_init_loongson_uart_base(void);
+#endif
+
+static inline void prom_init_uart_base(void)
+{
+#ifdef CONFIG_LOONGSON_UART_BASE
+ prom_init_loongson_uart_base();
+#endif
+}
+
+/* irq operation functions */
+extern void bonito_irqdispatch(void);
+extern void __init bonito_irq_init(void);
+extern void __init mach_init_irq(void);
+extern void mach_irq_dispatch(unsigned int pending);
+extern int mach_i8259_irq(void);
+
+/* We need this in some places... */
+#define delay() ({ \
+ int x; \
+ for (x = 0; x < 100000; x++) \
+ __asm__ __volatile__(""); \
+})
+
+#define LOONGSON_REG(x) \
+ (*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x)))
+
+#define LOONGSON_IRQ_BASE 32
+#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */
+
+#include <linux/interrupt.h>
+static inline void do_perfcnt_IRQ(void)
+{
+#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
+ do_IRQ(LOONGSON2_PERFCNT_IRQ);
+#endif
+}
+
+#define LOONGSON_FLASH_BASE 0x1c000000
+#define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */
+#define LOONGSON_FLASH_TOP (LOONGSON_FLASH_BASE+LOONGSON_FLASH_SIZE-1)
+
+#define LOONGSON_LIO0_BASE 0x1e000000
+#define LOONGSON_LIO0_SIZE 0x01C00000 /* 28M */
+#define LOONGSON_LIO0_TOP (LOONGSON_LIO0_BASE+LOONGSON_LIO0_SIZE-1)
+
+#define LOONGSON_BOOT_BASE 0x1fc00000
+#define LOONGSON_BOOT_SIZE 0x00100000 /* 1M */
+#define LOONGSON_BOOT_TOP (LOONGSON_BOOT_BASE+LOONGSON_BOOT_SIZE-1)
+#define LOONGSON_REG_BASE 0x1fe00000
+#define LOONGSON_REG_SIZE 0x00100000 /* 256Bytes + 256Bytes + ??? */
+#define LOONGSON_REG_TOP (LOONGSON_REG_BASE+LOONGSON_REG_SIZE-1)
+
+#define LOONGSON_LIO1_BASE 0x1ff00000
+#define LOONGSON_LIO1_SIZE 0x00100000 /* 1M */
+#define LOONGSON_LIO1_TOP (LOONGSON_LIO1_BASE+LOONGSON_LIO1_SIZE-1)
+
+#define LOONGSON_PCILO0_BASE 0x10000000
+#define LOONGSON_PCILO1_BASE 0x14000000
+#define LOONGSON_PCILO2_BASE 0x18000000
+#define LOONGSON_PCILO_BASE LOONGSON_PCILO0_BASE
+#define LOONGSON_PCILO_SIZE 0x0c000000 /* 64M * 3 */
+#define LOONGSON_PCILO_TOP (LOONGSON_PCILO0_BASE+LOONGSON_PCILO_SIZE-1)
+
+#define LOONGSON_PCICFG_BASE 0x1fe80000
+#define LOONGSON_PCICFG_SIZE 0x00000800 /* 2K */
+#define LOONGSON_PCICFG_TOP (LOONGSON_PCICFG_BASE+LOONGSON_PCICFG_SIZE-1)
+#define LOONGSON_PCIIO_BASE 0x1fd00000
+#define LOONGSON_PCIIO_SIZE 0x00100000 /* 1M */
+#define LOONGSON_PCIIO_TOP (LOONGSON_PCIIO_BASE+LOONGSON_PCIIO_SIZE-1)
+
+/* Loongson Register Bases */
+
+#define LOONGSON_PCICONFIGBASE 0x00
+#define LOONGSON_REGBASE 0x100
+
+/* PCI Configuration Registers */
+
+#define LOONGSON_PCI_REG(x) LOONGSON_REG(LOONGSON_PCICONFIGBASE + (x))
+#define LOONGSON_PCIDID LOONGSON_PCI_REG(0x00)
+#define LOONGSON_PCICMD LOONGSON_PCI_REG(0x04)
+#define LOONGSON_PCICLASS LOONGSON_PCI_REG(0x08)
+#define LOONGSON_PCILTIMER LOONGSON_PCI_REG(0x0c)
+#define LOONGSON_PCIBASE0 LOONGSON_PCI_REG(0x10)
+#define LOONGSON_PCIBASE1 LOONGSON_PCI_REG(0x14)
+#define LOONGSON_PCIBASE2 LOONGSON_PCI_REG(0x18)
+#define LOONGSON_PCIBASE3 LOONGSON_PCI_REG(0x1c)
+#define LOONGSON_PCIBASE4 LOONGSON_PCI_REG(0x20)
+#define LOONGSON_PCIEXPRBASE LOONGSON_PCI_REG(0x30)
+#define LOONGSON_PCIINT LOONGSON_PCI_REG(0x3c)
+
+#define LOONGSON_PCI_ISR4C LOONGSON_PCI_REG(0x4c)
+
+#define LOONGSON_PCICMD_PERR_CLR 0x80000000
+#define LOONGSON_PCICMD_SERR_CLR 0x40000000
+#define LOONGSON_PCICMD_MABORT_CLR 0x20000000
+#define LOONGSON_PCICMD_MTABORT_CLR 0x10000000
+#define LOONGSON_PCICMD_TABORT_CLR 0x08000000
+#define LOONGSON_PCICMD_MPERR_CLR 0x01000000
+#define LOONGSON_PCICMD_PERRRESPEN 0x00000040
+#define LOONGSON_PCICMD_ASTEPEN 0x00000080
+#define LOONGSON_PCICMD_SERREN 0x00000100
+#define LOONGSON_PCILTIMER_BUSLATENCY 0x0000ff00
+#define LOONGSON_PCILTIMER_BUSLATENCY_SHIFT 8
+
+/* Loongson h/w Configuration */
+
+#define LOONGSON_GENCFG_OFFSET 0x4
+#define LOONGSON_GENCFG LOONGSON_REG(LOONGSON_REGBASE + LOONGSON_GENCFG_OFFSET)
+
+#define LOONGSON_GENCFG_DEBUGMODE 0x00000001
+#define LOONGSON_GENCFG_SNOOPEN 0x00000002
+#define LOONGSON_GENCFG_CPUSELFRESET 0x00000004
+
+#define LOONGSON_GENCFG_FORCE_IRQA 0x00000008
+#define LOONGSON_GENCFG_IRQA_ISOUT 0x00000010
+#define LOONGSON_GENCFG_IRQA_FROM_INT1 0x00000020
+#define LOONGSON_GENCFG_BYTESWAP 0x00000040
+
+#define LOONGSON_GENCFG_UNCACHED 0x00000080
+#define LOONGSON_GENCFG_PREFETCHEN 0x00000100
+#define LOONGSON_GENCFG_WBEHINDEN 0x00000200
+#define LOONGSON_GENCFG_CACHEALG 0x00000c00
+#define LOONGSON_GENCFG_CACHEALG_SHIFT 10
+#define LOONGSON_GENCFG_PCIQUEUE 0x00001000
+#define LOONGSON_GENCFG_CACHESTOP 0x00002000
+#define LOONGSON_GENCFG_MSTRBYTESWAP 0x00004000
+#define LOONGSON_GENCFG_BUSERREN 0x00008000
+#define LOONGSON_GENCFG_NORETRYTIMEOUT 0x00010000
+#define LOONGSON_GENCFG_SHORTCOPYTIMEOUT 0x00020000
+
+/* PCI address map control */
+
+#define LOONGSON_PCIMAP LOONGSON_REG(LOONGSON_REGBASE + 0x10)
+#define LOONGSON_PCIMEMBASECFG LOONGSON_REG(LOONGSON_REGBASE + 0x14)
+#define LOONGSON_PCIMAP_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x18)
+
+/* GPIO Regs - r/w */
+
+#define LOONGSON_GPIODATA LOONGSON_REG(LOONGSON_REGBASE + 0x1c)
+#define LOONGSON_GPIOIE LOONGSON_REG(LOONGSON_REGBASE + 0x20)
+
+/* ICU Configuration Regs - r/w */
+
+#define LOONGSON_INTEDGE LOONGSON_REG(LOONGSON_REGBASE + 0x24)
+#define LOONGSON_INTSTEER LOONGSON_REG(LOONGSON_REGBASE + 0x28)
+#define LOONGSON_INTPOL LOONGSON_REG(LOONGSON_REGBASE + 0x2c)
+
+/* ICU Enable Regs - IntEn & IntISR are r/o. */
+
+#define LOONGSON_INTENSET LOONGSON_REG(LOONGSON_REGBASE + 0x30)
+#define LOONGSON_INTENCLR LOONGSON_REG(LOONGSON_REGBASE + 0x34)
+#define LOONGSON_INTEN LOONGSON_REG(LOONGSON_REGBASE + 0x38)
+#define LOONGSON_INTISR LOONGSON_REG(LOONGSON_REGBASE + 0x3c)
+
+/* ICU */
+#define LOONGSON_ICU_MBOXES 0x0000000f
+#define LOONGSON_ICU_MBOXES_SHIFT 0
+#define LOONGSON_ICU_DMARDY 0x00000010
+#define LOONGSON_ICU_DMAEMPTY 0x00000020
+#define LOONGSON_ICU_COPYRDY 0x00000040
+#define LOONGSON_ICU_COPYEMPTY 0x00000080
+#define LOONGSON_ICU_COPYERR 0x00000100
+#define LOONGSON_ICU_PCIIRQ 0x00000200
+#define LOONGSON_ICU_MASTERERR 0x00000400
+#define LOONGSON_ICU_SYSTEMERR 0x00000800
+#define LOONGSON_ICU_DRAMPERR 0x00001000
+#define LOONGSON_ICU_RETRYERR 0x00002000
+#define LOONGSON_ICU_GPIOS 0x01ff0000
+#define LOONGSON_ICU_GPIOS_SHIFT 16
+#define LOONGSON_ICU_GPINS 0x7e000000
+#define LOONGSON_ICU_GPINS_SHIFT 25
+#define LOONGSON_ICU_MBOX(N) (1<<(LOONGSON_ICU_MBOXES_SHIFT+(N)))
+#define LOONGSON_ICU_GPIO(N) (1<<(LOONGSON_ICU_GPIOS_SHIFT+(N)))
+#define LOONGSON_ICU_GPIN(N) (1<<(LOONGSON_ICU_GPINS_SHIFT+(N)))
+
+/* PCI prefetch window base & mask */
+
+#define LOONGSON_MEM_WIN_BASE_L LOONGSON_REG(LOONGSON_REGBASE + 0x40)
+#define LOONGSON_MEM_WIN_BASE_H LOONGSON_REG(LOONGSON_REGBASE + 0x44)
+#define LOONGSON_MEM_WIN_MASK_L LOONGSON_REG(LOONGSON_REGBASE + 0x48)
+#define LOONGSON_MEM_WIN_MASK_H LOONGSON_REG(LOONGSON_REGBASE + 0x4c)
+
+/* PCI_Hit*_Sel_* */
+
+#define LOONGSON_PCI_HIT0_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x50)
+#define LOONGSON_PCI_HIT0_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x54)
+#define LOONGSON_PCI_HIT1_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x58)
+#define LOONGSON_PCI_HIT1_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x5c)
+#define LOONGSON_PCI_HIT2_SEL_L LOONGSON_REG(LOONGSON_REGBASE + 0x60)
+#define LOONGSON_PCI_HIT2_SEL_H LOONGSON_REG(LOONGSON_REGBASE + 0x64)
+
+/* PXArb Config & Status */
+
+#define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68)
+#define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c)
+
+/* pcimap */
+
+#define LOONGSON_PCIMAP_PCIMAP_LO0 0x0000003f
+#define LOONGSON_PCIMAP_PCIMAP_LO0_SHIFT 0
+#define LOONGSON_PCIMAP_PCIMAP_LO1 0x00000fc0
+#define LOONGSON_PCIMAP_PCIMAP_LO1_SHIFT 6
+#define LOONGSON_PCIMAP_PCIMAP_LO2 0x0003f000
+#define LOONGSON_PCIMAP_PCIMAP_LO2_SHIFT 12
+#define LOONGSON_PCIMAP_PCIMAP_2 0x00040000
+#define LOONGSON_PCIMAP_WIN(WIN, ADDR) \
+ ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
+
+#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
+#include <linux/cpufreq.h>
+extern void loongson2_cpu_wait(void);
+extern struct cpufreq_frequency_table loongson2_clockmod_table[];
+
+/* Chip Config */
+#define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80)
+#endif
+
+/*
+ * address windows configuration module
+ *
+ * loongson2e do not have this module
+ */
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+
+/* address window config module base address */
+#define LOONGSON_ADDRWINCFG_BASE 0x3ff00000ul
+#define LOONGSON_ADDRWINCFG_SIZE 0x180
+
+extern unsigned long _loongson_addrwincfg_base;
+#define LOONGSON_ADDRWINCFG(offset) \
+ (*(volatile u64 *)(_loongson_addrwincfg_base + (offset)))
+
+#define CPU_WIN0_BASE LOONGSON_ADDRWINCFG(0x00)
+#define CPU_WIN1_BASE LOONGSON_ADDRWINCFG(0x08)
+#define CPU_WIN2_BASE LOONGSON_ADDRWINCFG(0x10)
+#define CPU_WIN3_BASE LOONGSON_ADDRWINCFG(0x18)
+
+#define CPU_WIN0_MASK LOONGSON_ADDRWINCFG(0x20)
+#define CPU_WIN1_MASK LOONGSON_ADDRWINCFG(0x28)
+#define CPU_WIN2_MASK LOONGSON_ADDRWINCFG(0x30)
+#define CPU_WIN3_MASK LOONGSON_ADDRWINCFG(0x38)
+
+#define CPU_WIN0_MMAP LOONGSON_ADDRWINCFG(0x40)
+#define CPU_WIN1_MMAP LOONGSON_ADDRWINCFG(0x48)
+#define CPU_WIN2_MMAP LOONGSON_ADDRWINCFG(0x50)
+#define CPU_WIN3_MMAP LOONGSON_ADDRWINCFG(0x58)
+
+#define PCIDMA_WIN0_BASE LOONGSON_ADDRWINCFG(0x60)
+#define PCIDMA_WIN1_BASE LOONGSON_ADDRWINCFG(0x68)
+#define PCIDMA_WIN2_BASE LOONGSON_ADDRWINCFG(0x70)
+#define PCIDMA_WIN3_BASE LOONGSON_ADDRWINCFG(0x78)
+
+#define PCIDMA_WIN0_MASK LOONGSON_ADDRWINCFG(0x80)
+#define PCIDMA_WIN1_MASK LOONGSON_ADDRWINCFG(0x88)
+#define PCIDMA_WIN2_MASK LOONGSON_ADDRWINCFG(0x90)
+#define PCIDMA_WIN3_MASK LOONGSON_ADDRWINCFG(0x98)
+
+#define PCIDMA_WIN0_MMAP LOONGSON_ADDRWINCFG(0xa0)
+#define PCIDMA_WIN1_MMAP LOONGSON_ADDRWINCFG(0xa8)
+#define PCIDMA_WIN2_MMAP LOONGSON_ADDRWINCFG(0xb0)
+#define PCIDMA_WIN3_MMAP LOONGSON_ADDRWINCFG(0xb8)
+
+#define ADDRWIN_WIN0 0
+#define ADDRWIN_WIN1 1
+#define ADDRWIN_WIN2 2
+#define ADDRWIN_WIN3 3
+
+#define ADDRWIN_MAP_DST_DDR 0
+#define ADDRWIN_MAP_DST_PCI 1
+#define ADDRWIN_MAP_DST_LIO 1
+
+/*
+ * s: CPU, PCIDMA
+ * d: DDR, PCI, LIO
+ * win: 0, 1, 2, 3
+ * src: map source
+ * dst: map destination
+ * size: ~mask + 1
+ */
+#define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
+ s##_WIN##w##_BASE = (src); \
+ s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
+ s##_WIN##w##_MASK = ~(size-1); \
+} while (0)
+
+#define LOONGSON_ADDRWIN_CPUTOPCI(win, src, dst, size) \
+ LOONGSON_ADDRWIN_CFG(CPU, PCI, win, src, dst, size)
+#define LOONGSON_ADDRWIN_CPUTODDR(win, src, dst, size) \
+ LOONGSON_ADDRWIN_CFG(CPU, DDR, win, src, dst, size)
+#define LOONGSON_ADDRWIN_PCITODDR(win, src, dst, size) \
+ LOONGSON_ADDRWIN_CFG(PCIDMA, DDR, win, src, dst, size)
+
+#endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
+#endif /* __ASM_MACH_LOONGSON_LOONGSON_H */
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h
new file mode 100644
index 00000000..43213388
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/machine.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_MACHINE_H
+#define __ASM_MACH_LOONGSON_MACHINE_H
+
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
+#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E
+
+#endif
+
+/* use fuloong2f as the default machine of LEMOTE_MACH2F */
+#ifdef CONFIG_LEMOTE_MACH2F
+
+#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2F
+
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MACHINE_H */
diff --git a/arch/mips/include/asm/mach-loongson/mc146818rtc.h b/arch/mips/include/asm/mach-loongson/mc146818rtc.h
new file mode 100644
index 00000000..ed7fe978
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/mc146818rtc.h
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * RTC routines for PC style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_LOONGSON_MC146818RTC_H
+#define __ASM_MACH_LOONGSON_MC146818RTC_H
+
+#include <linux/io.h>
+
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_IRQ 8
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ return inb_p(RTC_PORT(1));
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+ outb_p(addr, RTC_PORT(0));
+ outb_p(data, RTC_PORT(1));
+}
+
+#define RTC_ALWAYS_BCD 0
+
+#ifndef mc146818_decode_year
+#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h
new file mode 100644
index 00000000..3b23ee86
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/mem.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_MEM_H
+#define __ASM_MACH_LOONGSON_MEM_H
+
+/*
+ * high memory space
+ *
+ * in loongson2e, starts from 512M
+ * in loongson2f, starts from 2G 256M
+ */
+#ifdef CONFIG_CPU_LOONGSON2E
+#define LOONGSON_HIGHMEM_START 0x20000000
+#else
+#define LOONGSON_HIGHMEM_START 0x90000000
+#endif
+
+/*
+ * the peripheral registers(MMIO):
+ *
+ * On the Lemote Loongson 2e system, reside between 0x1000:0000 and 0x2000:0000.
+ * On the Lemote Loongson 2f system, reside between 0x1000:0000 and 0x8000:0000.
+ */
+
+#define LOONGSON_MMIO_MEM_START 0x10000000
+
+#ifdef CONFIG_CPU_LOONGSON2E
+#define LOONGSON_MMIO_MEM_END 0x20000000
+#else
+#define LOONGSON_MMIO_MEM_END 0x80000000
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MEM_H */
diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h
new file mode 100644
index 00000000..bc99dab4
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/pci.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.org>
+ * Copyright (c) 2009 Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_PCI_H_
+#define __ASM_MACH_LOONGSON_PCI_H_
+
+extern struct pci_ops loongson_pci_ops;
+
+/* this is an offset from mips_io_port_base */
+#define LOONGSON_PCI_IO_START 0x00004000UL
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+
+/*
+ * we use address window2 to map cpu address space to pci space
+ * window2: cpu [1G, 2G] -> pci [1G, 2G]
+ * why not use window 0 & 1? because they are used by cpu when booting.
+ * window0: cpu [0, 256M] -> ddr [0, 256M]
+ * window1: cpu [256M, 512M] -> pci [256M, 512M]
+ */
+
+/* the smallest LOONGSON_CPU_MEM_SRC can be 512M */
+#define LOONGSON_CPU_MEM_SRC 0x40000000ul /* 1G */
+#define LOONGSON_PCI_MEM_DST LOONGSON_CPU_MEM_SRC
+
+#define LOONGSON_PCI_MEM_START LOONGSON_PCI_MEM_DST
+#define LOONGSON_PCI_MEM_END (0x80000000ul-1) /* 2G */
+
+#define MMAP_CPUTOPCI_SIZE (LOONGSON_PCI_MEM_END - \
+ LOONGSON_PCI_MEM_START + 1)
+
+#else /* loongson2f/32bit & loongson2e */
+
+/* this pci memory space is mapped by pcimap in pci.c */
+#define LOONGSON_PCI_MEM_START LOONGSON_PCILO1_BASE
+#define LOONGSON_PCI_MEM_END (LOONGSON_PCILO1_BASE + 0x04000000 * 2)
+/* this is an offset from mips_io_port_base */
+#define LOONGSON_PCI_IO_START 0x00004000UL
+
+#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
+#endif /* !__ASM_MACH_LOONGSON_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-loongson/war.h b/arch/mips/include/asm/mach-loongson/war.h
new file mode 100644
index 00000000..4b971c3f
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_LOONGSON_WAR_H
+#define __ASM_MACH_LOONGSON_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MACH_LEMOTE_WAR_H */
diff --git a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
new file mode 100644
index 00000000..2848cea4
--- /dev/null
+++ b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
@@ -0,0 +1,68 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 2004 Chris Dearman
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
+
+
+/*
+ * CPU feature overrides for MIPS boards
+ */
+#ifdef CONFIG_CPU_MIPS32
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+/* #define cpu_has_fpu ? */
+/* #define cpu_has_32fpr ? */
+#define cpu_has_counter 1
+/* #define cpu_has_watch ? */
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+/* #define cpu_has_cache_cdex_p ? */
+/* #define cpu_has_cache_cdex_s ? */
+/* #define cpu_has_prefetch ? */
+#define cpu_has_mcheck 1
+/* #define cpu_has_ejtag ? */
+#define cpu_has_llsc 1
+/* #define cpu_has_vtag_icache ? */
+/* #define cpu_has_dc_aliases ? */
+/* #define cpu_has_ic_fills_f_dc ? */
+#define cpu_has_nofpuex 0
+/* #define cpu_has_64bits ? */
+/* #define cpu_has_64bit_zero_reg ? */
+/* #define cpu_has_inclusive_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
+#endif
+
+#ifdef CONFIG_CPU_MIPS64
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+/* #define cpu_has_fpu ? */
+/* #define cpu_has_32fpr ? */
+#define cpu_has_counter 1
+/* #define cpu_has_watch ? */
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+/* #define cpu_has_cache_cdex_p ? */
+/* #define cpu_has_cache_cdex_s ? */
+/* #define cpu_has_prefetch ? */
+#define cpu_has_mcheck 1
+/* #define cpu_has_ejtag ? */
+#define cpu_has_llsc 1
+/* #define cpu_has_vtag_icache ? */
+/* #define cpu_has_dc_aliases ? */
+/* #define cpu_has_ic_fills_f_dc ? */
+#define cpu_has_nofpuex 0
+/* #define cpu_has_64bits ? */
+/* #define cpu_has_64bit_zero_reg ? */
+/* #define cpu_has_inclusive_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
+#endif
+
+#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-malta/irq.h b/arch/mips/include/asm/mach-malta/irq.h
new file mode 100644
index 00000000..9b9da266
--- /dev/null
+++ b/arch/mips/include/asm/mach-malta/irq.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_MIPS_IRQ_H
+#define __ASM_MACH_MIPS_IRQ_H
+
+
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_MIPS_IRQ_H */
diff --git a/arch/mips/include/asm/mach-malta/kernel-entry-init.h b/arch/mips/include/asm/mach-malta/kernel-entry-init.h
new file mode 100644
index 00000000..0b793e7b
--- /dev/null
+++ b/arch/mips/include/asm/mach-malta/kernel-entry-init.h
@@ -0,0 +1,52 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Chris Dearman (chris@mips.com)
+ * Copyright (C) 2007 Mips Technologies, Inc.
+ */
+#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
+#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
+
+ .macro kernel_entry_setup
+#ifdef CONFIG_MIPS_MT_SMTC
+ mfc0 t0, CP0_CONFIG
+ bgez t0, 9f
+ mfc0 t0, CP0_CONFIG, 1
+ bgez t0, 9f
+ mfc0 t0, CP0_CONFIG, 2
+ bgez t0, 9f
+ mfc0 t0, CP0_CONFIG, 3
+ and t0, 1<<2
+ bnez t0, 0f
+9:
+ /* Assume we came from YAMON... */
+ PTR_LA v0, 0x9fc00534 /* YAMON print */
+ lw v0, (v0)
+ move a0, zero
+ PTR_LA a1, nonmt_processor
+ jal v0
+
+ PTR_LA v0, 0x9fc00520 /* YAMON exit */
+ lw v0, (v0)
+ li a0, 1
+ jal v0
+
+1: b 1b
+
+ __INITDATA
+nonmt_processor:
+ .asciz "SMTC kernel requires the MT ASE to run\n"
+ __FINIT
+0:
+#endif
+ .endm
+
+/*
+ * Do SMP slave processor setup necessary before we can safely execute C code.
+ */
+ .macro smp_slave_setup
+ .endm
+
+#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */
diff --git a/arch/mips/include/asm/mach-malta/mach-gt64120.h b/arch/mips/include/asm/mach-malta/mach-gt64120.h
new file mode 100644
index 00000000..0f863148
--- /dev/null
+++ b/arch/mips/include/asm/mach-malta/mach-gt64120.h
@@ -0,0 +1,19 @@
+/*
+ * This is a direct copy of the ev96100.h file, with a global
+ * search and replace. The numbers are the same.
+ *
+ * The reason I'm duplicating this is so that the 64120/96100
+ * defines won't be confusing in the source code.
+ */
+#ifndef _ASM_MACH_MIPS_MACH_GT64120_DEP_H
+#define _ASM_MACH_MIPS_MACH_GT64120_DEP_H
+
+#define MIPS_GT_BASE 0x1be00000
+
+extern unsigned long _pcictrl_gt64120;
+/*
+ * GT64120 config space base address
+ */
+#define GT64120_BASE _pcictrl_gt64120
+
+#endif /* _ASM_MACH_MIPS_MACH_GT64120_DEP_H */
diff --git a/arch/mips/include/asm/mach-malta/mc146818rtc.h b/arch/mips/include/asm/mach-malta/mc146818rtc.h
new file mode 100644
index 00000000..ea612f37
--- /dev/null
+++ b/arch/mips/include/asm/mach-malta/mc146818rtc.h
@@ -0,0 +1,48 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2003 by Ralf Baechle
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * RTC routines for Malta style attached PIIX4 device, which contains a
+ * Motorola MC146818A-compatible Real Time Clock.
+ */
+#ifndef __ASM_MACH_MALTA_MC146818RTC_H
+#define __ASM_MACH_MALTA_MC146818RTC_H
+
+#include <asm/io.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/malta.h>
+
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_IRQ 8
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+ outb(addr, MALTA_RTC_ADR_REG);
+ return inb(MALTA_RTC_DAT_REG);
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+ outb(addr, MALTA_RTC_ADR_REG);
+ outb(data, MALTA_RTC_DAT_REG);
+}
+
+#define RTC_ALWAYS_BCD 0
+
+#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900)
+
+#endif /* __ASM_MACH_MALTA_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-malta/war.h b/arch/mips/include/asm/mach-malta/war.h
new file mode 100644
index 00000000..7c6931d5
--- /dev/null
+++ b/arch/mips/include/asm/mach-malta/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_MIPS_WAR_H
+#define __ASM_MIPS_MACH_MIPS_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 1
+#define MIPS_CACHE_SYNC_WAR 1
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */
diff --git a/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h b/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h
new file mode 100644
index 00000000..779b0220
--- /dev/null
+++ b/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h
@@ -0,0 +1,65 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 2004 Chris Dearman
+ */
+#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
+
+
+/*
+ * CPU feature overrides for MIPS boards
+ */
+#ifdef CONFIG_CPU_MIPS32
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+#define cpu_has_fpu 0
+/* #define cpu_has_32fpr ? */
+#define cpu_has_counter 1
+/* #define cpu_has_watch ? */
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+/* #define cpu_has_cache_cdex_p ? */
+/* #define cpu_has_cache_cdex_s ? */
+/* #define cpu_has_prefetch ? */
+#define cpu_has_mcheck 1
+/* #define cpu_has_ejtag ? */
+#define cpu_has_llsc 1
+/* #define cpu_has_vtag_icache ? */
+/* #define cpu_has_dc_aliases ? */
+/* #define cpu_has_ic_fills_f_dc ? */
+#define cpu_has_nofpuex 0
+/* #define cpu_has_64bits ? */
+/* #define cpu_has_64bit_zero_reg ? */
+/* #define cpu_has_inclusive_pcaches ? */
+#endif
+
+#ifdef CONFIG_CPU_MIPS64
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+/* #define cpu_has_fpu ? */
+/* #define cpu_has_32fpr ? */
+#define cpu_has_counter 1
+/* #define cpu_has_watch ? */
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+/* #define cpu_has_cache_cdex_p ? */
+/* #define cpu_has_cache_cdex_s ? */
+/* #define cpu_has_prefetch ? */
+#define cpu_has_mcheck 1
+/* #define cpu_has_ejtag ? */
+#define cpu_has_llsc 1
+/* #define cpu_has_vtag_icache ? */
+/* #define cpu_has_dc_aliases ? */
+/* #define cpu_has_ic_fills_f_dc ? */
+#define cpu_has_nofpuex 0
+/* #define cpu_has_64bits ? */
+/* #define cpu_has_64bit_zero_reg ? */
+/* #define cpu_has_inclusive_pcaches ? */
+#endif
+
+#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-mipssim/war.h b/arch/mips/include/asm/mach-mipssim/war.h
new file mode 100644
index 00000000..c8a74a35
--- /dev/null
+++ b/arch/mips/include/asm/mach-mipssim/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_MIPSSIM_WAR_H
+#define __ASM_MIPS_MACH_MIPSSIM_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_MIPSSIM_WAR_H */
diff --git a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
new file mode 100644
index 00000000..3b728275
--- /dev/null
+++ b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
@@ -0,0 +1,47 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011 Netlogic Microsystems
+ * Copyright (C) 2003 Ralf Baechle
+ */
+#ifndef __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+#define cpu_has_watch 1
+#define cpu_has_mips16 0
+#define cpu_has_counter 1
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 1
+#define cpu_has_ejtag 1
+
+#define cpu_has_llsc 1
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+#define cpu_icache_snoops_remote_store 0
+
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 1
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 1
+#define cpu_has_mips64r2 0
+
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#endif /* __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-netlogic/irq.h b/arch/mips/include/asm/mach-netlogic/irq.h
new file mode 100644
index 00000000..b5902458
--- /dev/null
+++ b/arch/mips/include/asm/mach-netlogic/irq.h
@@ -0,0 +1,14 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011 Netlogic Microsystems.
+ */
+#ifndef __ASM_NETLOGIC_IRQ_H
+#define __ASM_NETLOGIC_IRQ_H
+
+#define NR_IRQS 64
+#define MIPS_CPU_IRQ_BASE 0
+
+#endif /* __ASM_NETLOGIC_IRQ_H */
diff --git a/arch/mips/include/asm/mach-netlogic/war.h b/arch/mips/include/asm/mach-netlogic/war.h
new file mode 100644
index 00000000..22da8932
--- /dev/null
+++ b/arch/mips/include/asm/mach-netlogic/war.h
@@ -0,0 +1,26 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011 Netlogic Microsystems.
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_NLM_WAR_H
+#define __ASM_MIPS_MACH_NLM_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_NLM_WAR_H */
diff --git a/arch/mips/include/asm/mach-pb1x00/mc146818rtc.h b/arch/mips/include/asm/mach-pb1x00/mc146818rtc.h
new file mode 100644
index 00000000..622c5871
--- /dev/null
+++ b/arch/mips/include/asm/mach-pb1x00/mc146818rtc.h
@@ -0,0 +1,34 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 2001, 03 by Ralf Baechle
+ *
+ * RTC routines for PC style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_AU1XX_MC146818RTC_H
+#define __ASM_MACH_AU1XX_MC146818RTC_H
+
+#include <asm/io.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#define RTC_PORT(x) (0x0c000000 + (x))
+#define RTC_IRQ 8
+#define PB1500_RTC_ADDR 0x0c000000
+
+static inline unsigned char CMOS_READ(unsigned long offset)
+{
+ offset <<= 2;
+ return (u8)(au_readl(offset + PB1500_RTC_ADDR) & 0xff);
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long offset)
+{
+ offset <<= 2;
+ au_writel(data, offset + PB1500_RTC_ADDR);
+}
+
+#define RTC_ALWAYS_BCD 1
+
+#endif /* __ASM_MACH_AU1XX_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1000.h b/arch/mips/include/asm/mach-pb1x00/pb1000.h
new file mode 100644
index 00000000..65059255
--- /dev/null
+++ b/arch/mips/include/asm/mach-pb1x00/pb1000.h
@@ -0,0 +1,87 @@
+/*
+ * Alchemy Semi Pb1000 Reference Board
+ *
+ * Copyright 2001, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_PB1000_H
+#define __ASM_PB1000_H
+
+/* PCMCIA PB1000 specific defines */
+#define PCMCIA_MAX_SOCK 1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
+
+#define PB1000_PCR 0xBE000000
+# define PCR_SLOT_0_VPP0 (1 << 0)
+# define PCR_SLOT_0_VPP1 (1 << 1)
+# define PCR_SLOT_0_VCC0 (1 << 2)
+# define PCR_SLOT_0_VCC1 (1 << 3)
+# define PCR_SLOT_0_RST (1 << 4)
+# define PCR_SLOT_1_VPP0 (1 << 8)
+# define PCR_SLOT_1_VPP1 (1 << 9)
+# define PCR_SLOT_1_VCC0 (1 << 10)
+# define PCR_SLOT_1_VCC1 (1 << 11)
+# define PCR_SLOT_1_RST (1 << 12)
+
+#define PB1000_MDR 0xBE000004
+# define MDR_PI (1 << 5) /* PCMCIA int latch */
+# define MDR_EPI (1 << 14) /* enable PCMCIA int */
+# define MDR_CPI (1 << 15) /* clear PCMCIA int */
+
+#define PB1000_ACR1 0xBE000008
+# define ACR1_SLOT_0_CD1 (1 << 0) /* card detect 1 */
+# define ACR1_SLOT_0_CD2 (1 << 1) /* card detect 2 */
+# define ACR1_SLOT_0_READY (1 << 2) /* ready */
+# define ACR1_SLOT_0_STATUS (1 << 3) /* status change */
+# define ACR1_SLOT_0_VS1 (1 << 4) /* voltage sense 1 */
+# define ACR1_SLOT_0_VS2 (1 << 5) /* voltage sense 2 */
+# define ACR1_SLOT_0_INPACK (1 << 6) /* inpack pin status */
+# define ACR1_SLOT_1_CD1 (1 << 8) /* card detect 1 */
+# define ACR1_SLOT_1_CD2 (1 << 9) /* card detect 2 */
+# define ACR1_SLOT_1_READY (1 << 10) /* ready */
+# define ACR1_SLOT_1_STATUS (1 << 11) /* status change */
+# define ACR1_SLOT_1_VS1 (1 << 12) /* voltage sense 1 */
+# define ACR1_SLOT_1_VS2 (1 << 13) /* voltage sense 2 */
+# define ACR1_SLOT_1_INPACK (1 << 14) /* inpack pin status */
+
+#define CPLD_AUX0 0xBE00000C
+#define CPLD_AUX1 0xBE000010
+#define CPLD_AUX2 0xBE000014
+
+/* Voltage levels */
+
+/* VPPEN1 - VPPEN0 */
+#define VPP_GND ((0 << 1) | (0 << 0))
+#define VPP_5V ((1 << 1) | (0 << 0))
+#define VPP_3V ((0 << 1) | (1 << 0))
+#define VPP_12V ((0 << 1) | (1 << 0))
+#define VPP_HIZ ((1 << 1) | (1 << 0))
+
+/* VCCEN1 - VCCEN0 */
+#define VCC_3V ((0 << 1) | (1 << 0))
+#define VCC_5V ((1 << 1) | (0 << 0))
+#define VCC_HIZ ((0 << 1) | (0 << 0))
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT) \
+ ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
+#endif /* __ASM_PB1000_H */
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1200.h b/arch/mips/include/asm/mach-pb1x00/pb1200.h
new file mode 100644
index 00000000..fce4332e
--- /dev/null
+++ b/arch/mips/include/asm/mach-pb1x00/pb1200.h
@@ -0,0 +1,141 @@
+/*
+ * AMD Alchemy Pb1200 Reference Board
+ * Board Registers defines.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_PB1200_H
+#define __ASM_PB1200_H
+
+#include <linux/types.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX
+
+/*
+ * SPI and SMB are muxed on the Pb1200 board.
+ * Refer to board documentation.
+ */
+#define SPI_PSC_BASE PSC0_BASE_ADDR
+#define SMBUS_PSC_BASE PSC0_BASE_ADDR
+/*
+ * AC97 and I2S are muxed on the Pb1200 board.
+ * Refer to board documentation.
+ */
+#define AC97_PSC_BASE PSC1_BASE_ADDR
+#define I2S_PSC_BASE PSC1_BASE_ADDR
+
+
+#define BCSR_SYSTEM_VDDI 0x001F
+#define BCSR_SYSTEM_POWEROFF 0x4000
+#define BCSR_SYSTEM_RESET 0x8000
+
+/* Bit positions for the different interrupt sources */
+#define BCSR_INT_IDE 0x0001
+#define BCSR_INT_ETH 0x0002
+#define BCSR_INT_PC0 0x0004
+#define BCSR_INT_PC0STSCHG 0x0008
+#define BCSR_INT_PC1 0x0010
+#define BCSR_INT_PC1STSCHG 0x0020
+#define BCSR_INT_DC 0x0040
+#define BCSR_INT_FLASHBUSY 0x0080
+#define BCSR_INT_PC0INSERT 0x0100
+#define BCSR_INT_PC0EJECT 0x0200
+#define BCSR_INT_PC1INSERT 0x0400
+#define BCSR_INT_PC1EJECT 0x0800
+#define BCSR_INT_SD0INSERT 0x1000
+#define BCSR_INT_SD0EJECT 0x2000
+#define BCSR_INT_SD1INSERT 0x4000
+#define BCSR_INT_SD1EJECT 0x8000
+
+#define SMC91C111_PHYS_ADDR 0x0D000300
+#define SMC91C111_INT PB1200_ETH_INT
+
+#define IDE_PHYS_ADDR 0x0C800000
+#define IDE_REG_SHIFT 5
+#define IDE_PHYS_LEN (16 << IDE_REG_SHIFT)
+#define IDE_INT PB1200_IDE_INT
+#define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1
+#define IDE_RQSIZE 128
+
+#define NAND_PHYS_ADDR 0x1C000000
+
+/*
+ * Timing values as described in databook, * ns value stripped of
+ * lower 2 bits.
+ * These defines are here rather than an Au1200 generic file because
+ * the parts chosen on another board may be different and may require
+ * different timings.
+ */
+#define NAND_T_H (18 >> 2)
+#define NAND_T_PUL (30 >> 2)
+#define NAND_T_SU (30 >> 2)
+#define NAND_T_WH (30 >> 2)
+
+/* Bitfield shift amounts */
+#define NAND_T_H_SHIFT 0
+#define NAND_T_PUL_SHIFT 4
+#define NAND_T_SU_SHIFT 8
+#define NAND_T_WH_SHIFT 12
+
+#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
+ ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+ ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
+ ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT))
+
+/*
+ * External Interrupts for Pb1200 as of 8/6/2004.
+ * Bit positions in the CPLD registers can be calculated by taking
+ * the interrupt define and subtracting the PB1200_INT_BEGIN value.
+ *
+ * Example: IDE bis pos is = 64 - 64
+ * ETH bit pos is = 65 - 64
+ */
+enum external_pb1200_ints {
+ PB1200_INT_BEGIN = AU1000_MAX_INTR + 1,
+
+ PB1200_IDE_INT = PB1200_INT_BEGIN,
+ PB1200_ETH_INT,
+ PB1200_PC0_INT,
+ PB1200_PC0_STSCHG_INT,
+ PB1200_PC1_INT,
+ PB1200_PC1_STSCHG_INT,
+ PB1200_DC_INT,
+ PB1200_FLASHBUSY_INT,
+ PB1200_PC0_INSERT_INT,
+ PB1200_PC0_EJECT_INT,
+ PB1200_PC1_INSERT_INT,
+ PB1200_PC1_EJECT_INT,
+ PB1200_SD0_INSERT_INT,
+ PB1200_SD0_EJECT_INT,
+ PB1200_SD1_INSERT_INT,
+ PB1200_SD1_EJECT_INT,
+
+ PB1200_INT_END = PB1200_INT_BEGIN + 15
+};
+
+/* NAND chip select */
+#define NAND_CS 1
+
+#endif /* __ASM_PB1200_H */
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1550.h b/arch/mips/include/asm/mach-pb1x00/pb1550.h
new file mode 100644
index 00000000..f835c88e
--- /dev/null
+++ b/arch/mips/include/asm/mach-pb1x00/pb1550.h
@@ -0,0 +1,73 @@
+/*
+ * AMD Alchemy Semi PB1550 Reference Board
+ * Board Registers defines.
+ *
+ * Copyright 2004 Embedded Edge LLC.
+ * Copyright 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_PB1550_H
+#define __ASM_PB1550_H
+
+#include <linux/types.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX
+
+#define SPI_PSC_BASE PSC0_BASE_ADDR
+#define AC97_PSC_BASE PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE PSC2_BASE_ADDR
+#define I2S_PSC_BASE PSC3_BASE_ADDR
+
+/*
+ * Timing values as described in databook, * ns value stripped of
+ * lower 2 bits.
+ * These defines are here rather than an SOC1550 generic file because
+ * the parts chosen on another board may be different and may require
+ * different timings.
+ */
+#define NAND_T_H (18 >> 2)
+#define NAND_T_PUL (30 >> 2)
+#define NAND_T_SU (30 >> 2)
+#define NAND_T_WH (30 >> 2)
+
+/* Bitfield shift amounts */
+#define NAND_T_H_SHIFT 0
+#define NAND_T_PUL_SHIFT 4
+#define NAND_T_SU_SHIFT 8
+#define NAND_T_WH_SHIFT 12
+
+#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
+ ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
+ ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
+ ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT))
+
+#define NAND_CS 1
+
+/* Should be done by YAMON */
+#define NAND_STCFG 0x00400005 /* 8-bit NAND */
+#define NAND_STTIME 0x00007774 /* valid for 396 MHz SD=2 only */
+#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
+
+#endif /* __ASM_PB1550_H */
diff --git a/arch/mips/include/asm/mach-pnx833x/gpio.h b/arch/mips/include/asm/mach-pnx833x/gpio.h
new file mode 100644
index 00000000..ed3a88da
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx833x/gpio.h
@@ -0,0 +1,172 @@
+/*
+ * gpio.h: GPIO Support for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __ASM_MIPS_MACH_PNX833X_GPIO_H
+#define __ASM_MIPS_MACH_PNX833X_GPIO_H
+
+/* BIG FAT WARNING: races danger!
+ No protections exist here. Current users are only early init code,
+ when locking is not needed because no concurrency yet exists there,
+ and GPIO IRQ dispatcher, which does locking.
+ However, if many uses will ever happen, proper locking will be needed
+ - including locking between different uses
+*/
+
+#include "pnx833x.h"
+
+#define SET_REG_BIT(reg, bit) do { (reg |= (1 << (bit))); } while (0)
+#define CLEAR_REG_BIT(reg, bit) do { (reg &= ~(1 << (bit))); } while (0)
+
+/* Initialize GPIO to a known state */
+static inline void pnx833x_gpio_init(void)
+{
+ PNX833X_PIO_DIR = 0;
+ PNX833X_PIO_DIR2 = 0;
+ PNX833X_PIO_SEL = 0;
+ PNX833X_PIO_SEL2 = 0;
+ PNX833X_PIO_INT_EDGE = 0;
+ PNX833X_PIO_INT_HI = 0;
+ PNX833X_PIO_INT_LO = 0;
+
+ /* clear any GPIO interrupt requests */
+ PNX833X_PIO_INT_CLEAR = 0xffff;
+ PNX833X_PIO_INT_CLEAR = 0;
+ PNX833X_PIO_INT_ENABLE = 0;
+}
+
+/* Select GPIO direction for a pin */
+static inline void pnx833x_gpio_select_input(unsigned int pin)
+{
+ if (pin < 32)
+ CLEAR_REG_BIT(PNX833X_PIO_DIR, pin);
+ else
+ CLEAR_REG_BIT(PNX833X_PIO_DIR2, pin & 31);
+}
+static inline void pnx833x_gpio_select_output(unsigned int pin)
+{
+ if (pin < 32)
+ SET_REG_BIT(PNX833X_PIO_DIR, pin);
+ else
+ SET_REG_BIT(PNX833X_PIO_DIR2, pin & 31);
+}
+
+/* Select GPIO or alternate function for a pin */
+static inline void pnx833x_gpio_select_function_io(unsigned int pin)
+{
+ if (pin < 32)
+ CLEAR_REG_BIT(PNX833X_PIO_SEL, pin);
+ else
+ CLEAR_REG_BIT(PNX833X_PIO_SEL2, pin & 31);
+}
+static inline void pnx833x_gpio_select_function_alt(unsigned int pin)
+{
+ if (pin < 32)
+ SET_REG_BIT(PNX833X_PIO_SEL, pin);
+ else
+ SET_REG_BIT(PNX833X_PIO_SEL2, pin & 31);
+}
+
+/* Read GPIO pin */
+static inline int pnx833x_gpio_read(unsigned int pin)
+{
+ if (pin < 32)
+ return (PNX833X_PIO_IN >> pin) & 1;
+ else
+ return (PNX833X_PIO_IN2 >> (pin & 31)) & 1;
+}
+
+/* Write GPIO pin */
+static inline void pnx833x_gpio_write(unsigned int val, unsigned int pin)
+{
+ if (pin < 32) {
+ if (val)
+ SET_REG_BIT(PNX833X_PIO_OUT, pin);
+ else
+ CLEAR_REG_BIT(PNX833X_PIO_OUT, pin);
+ } else {
+ if (val)
+ SET_REG_BIT(PNX833X_PIO_OUT2, pin & 31);
+ else
+ CLEAR_REG_BIT(PNX833X_PIO_OUT2, pin & 31);
+ }
+}
+
+/* Configure GPIO interrupt */
+#define GPIO_INT_NONE 0
+#define GPIO_INT_LEVEL_LOW 1
+#define GPIO_INT_LEVEL_HIGH 2
+#define GPIO_INT_EDGE_RISING 3
+#define GPIO_INT_EDGE_FALLING 4
+#define GPIO_INT_EDGE_BOTH 5
+static inline void pnx833x_gpio_setup_irq(int when, unsigned int pin)
+{
+ switch (when) {
+ case GPIO_INT_LEVEL_LOW:
+ CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin);
+ CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin);
+ SET_REG_BIT(PNX833X_PIO_INT_LO, pin);
+ break;
+ case GPIO_INT_LEVEL_HIGH:
+ CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin);
+ SET_REG_BIT(PNX833X_PIO_INT_HI, pin);
+ CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin);
+ break;
+ case GPIO_INT_EDGE_RISING:
+ SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin);
+ SET_REG_BIT(PNX833X_PIO_INT_HI, pin);
+ CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin);
+ break;
+ case GPIO_INT_EDGE_FALLING:
+ SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin);
+ CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin);
+ SET_REG_BIT(PNX833X_PIO_INT_LO, pin);
+ break;
+ case GPIO_INT_EDGE_BOTH:
+ SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin);
+ SET_REG_BIT(PNX833X_PIO_INT_HI, pin);
+ SET_REG_BIT(PNX833X_PIO_INT_LO, pin);
+ break;
+ default:
+ CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin);
+ CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin);
+ CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin);
+ break;
+ }
+}
+
+/* Enable/disable GPIO interrupt */
+static inline void pnx833x_gpio_enable_irq(unsigned int pin)
+{
+ SET_REG_BIT(PNX833X_PIO_INT_ENABLE, pin);
+}
+static inline void pnx833x_gpio_disable_irq(unsigned int pin)
+{
+ CLEAR_REG_BIT(PNX833X_PIO_INT_ENABLE, pin);
+}
+
+/* Clear GPIO interrupt request */
+static inline void pnx833x_gpio_clear_irq(unsigned int pin)
+{
+ SET_REG_BIT(PNX833X_PIO_INT_CLEAR, pin);
+ CLEAR_REG_BIT(PNX833X_PIO_INT_CLEAR, pin);
+}
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx833x/irq-mapping.h b/arch/mips/include/asm/mach-pnx833x/irq-mapping.h
new file mode 100644
index 00000000..6d702645
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx833x/irq-mapping.h
@@ -0,0 +1,125 @@
+
+/*
+ * irq.h: IRQ mappings for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_MIPS_MACH_PNX833X_IRQ_MAPPING_H
+#define __ASM_MIPS_MACH_PNX833X_IRQ_MAPPING_H
+/*
+ * The "IRQ numbers" are completely virtual.
+ *
+ * In PNX8330/1, we have 48 interrupt lines, numbered from 1 to 48.
+ * Let's use numbers 1..48 for PIC interrupts, number 0 for timer interrupt,
+ * numbers 49..64 for (virtual) GPIO interrupts.
+ *
+ * In PNX8335, we have 57 interrupt lines, numbered from 1 to 57,
+ * connected to PIC, which uses core hardware interrupt 2, and also
+ * a timer interrupt through hardware interrupt 5.
+ * Let's use numbers 1..64 for PIC interrupts, number 0 for timer interrupt,
+ * numbers 65..80 for (virtual) GPIO interrupts.
+ *
+ */
+#include <irq.h>
+
+#define PNX833X_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7)
+
+/* Interrupts supported by PIC */
+#define PNX833X_PIC_I2C0_INT (PNX833X_PIC_IRQ_BASE + 1)
+#define PNX833X_PIC_I2C1_INT (PNX833X_PIC_IRQ_BASE + 2)
+#define PNX833X_PIC_UART0_INT (PNX833X_PIC_IRQ_BASE + 3)
+#define PNX833X_PIC_UART1_INT (PNX833X_PIC_IRQ_BASE + 4)
+#define PNX833X_PIC_TS_IN0_DV_INT (PNX833X_PIC_IRQ_BASE + 5)
+#define PNX833X_PIC_TS_IN0_DMA_INT (PNX833X_PIC_IRQ_BASE + 6)
+#define PNX833X_PIC_GPIO_INT (PNX833X_PIC_IRQ_BASE + 7)
+#define PNX833X_PIC_AUDIO_DEC_INT (PNX833X_PIC_IRQ_BASE + 8)
+#define PNX833X_PIC_VIDEO_DEC_INT (PNX833X_PIC_IRQ_BASE + 9)
+#define PNX833X_PIC_CONFIG_INT (PNX833X_PIC_IRQ_BASE + 10)
+#define PNX833X_PIC_AOI_INT (PNX833X_PIC_IRQ_BASE + 11)
+#define PNX833X_PIC_SYNC_INT (PNX833X_PIC_IRQ_BASE + 12)
+#define PNX8330_PIC_SPU_INT (PNX833X_PIC_IRQ_BASE + 13)
+#define PNX8335_PIC_SATA_INT (PNX833X_PIC_IRQ_BASE + 13)
+#define PNX833X_PIC_OSD_INT (PNX833X_PIC_IRQ_BASE + 14)
+#define PNX833X_PIC_DISP1_INT (PNX833X_PIC_IRQ_BASE + 15)
+#define PNX833X_PIC_DEINTERLACER_INT (PNX833X_PIC_IRQ_BASE + 16)
+#define PNX833X_PIC_DISPLAY2_INT (PNX833X_PIC_IRQ_BASE + 17)
+#define PNX833X_PIC_VC_INT (PNX833X_PIC_IRQ_BASE + 18)
+#define PNX833X_PIC_SC_INT (PNX833X_PIC_IRQ_BASE + 19)
+#define PNX833X_PIC_IDE_INT (PNX833X_PIC_IRQ_BASE + 20)
+#define PNX833X_PIC_IDE_DMA_INT (PNX833X_PIC_IRQ_BASE + 21)
+#define PNX833X_PIC_TS_IN1_DV_INT (PNX833X_PIC_IRQ_BASE + 22)
+#define PNX833X_PIC_TS_IN1_DMA_INT (PNX833X_PIC_IRQ_BASE + 23)
+#define PNX833X_PIC_SGDX_DMA_INT (PNX833X_PIC_IRQ_BASE + 24)
+#define PNX833X_PIC_TS_OUT_INT (PNX833X_PIC_IRQ_BASE + 25)
+#define PNX833X_PIC_IR_INT (PNX833X_PIC_IRQ_BASE + 26)
+#define PNX833X_PIC_VMSP1_INT (PNX833X_PIC_IRQ_BASE + 27)
+#define PNX833X_PIC_VMSP2_INT (PNX833X_PIC_IRQ_BASE + 28)
+#define PNX833X_PIC_PIBC_INT (PNX833X_PIC_IRQ_BASE + 29)
+#define PNX833X_PIC_TS_IN0_TRD_INT (PNX833X_PIC_IRQ_BASE + 30)
+#define PNX833X_PIC_SGDX_TPD_INT (PNX833X_PIC_IRQ_BASE + 31)
+#define PNX833X_PIC_USB_INT (PNX833X_PIC_IRQ_BASE + 32)
+#define PNX833X_PIC_TS_IN1_TRD_INT (PNX833X_PIC_IRQ_BASE + 33)
+#define PNX833X_PIC_CLOCK_INT (PNX833X_PIC_IRQ_BASE + 34)
+#define PNX833X_PIC_SGDX_PARSER_INT (PNX833X_PIC_IRQ_BASE + 35)
+#define PNX833X_PIC_VMSP_DMA_INT (PNX833X_PIC_IRQ_BASE + 36)
+
+#if defined(CONFIG_SOC_PNX8335)
+#define PNX8335_PIC_MIU_INT (PNX833X_PIC_IRQ_BASE + 37)
+#define PNX8335_PIC_AVCHIP_IRQ_INT (PNX833X_PIC_IRQ_BASE + 38)
+#define PNX8335_PIC_SYNC_HD_INT (PNX833X_PIC_IRQ_BASE + 39)
+#define PNX8335_PIC_DISP_HD_INT (PNX833X_PIC_IRQ_BASE + 40)
+#define PNX8335_PIC_DISP_SCALER_INT (PNX833X_PIC_IRQ_BASE + 41)
+#define PNX8335_PIC_OSD_HD1_INT (PNX833X_PIC_IRQ_BASE + 42)
+#define PNX8335_PIC_DTL_WRITER_Y_INT (PNX833X_PIC_IRQ_BASE + 43)
+#define PNX8335_PIC_DTL_WRITER_C_INT (PNX833X_PIC_IRQ_BASE + 44)
+#define PNX8335_PIC_DTL_EMULATOR_Y_IR_INT (PNX833X_PIC_IRQ_BASE + 45)
+#define PNX8335_PIC_DTL_EMULATOR_C_IR_INT (PNX833X_PIC_IRQ_BASE + 46)
+#define PNX8335_PIC_DENC_TTX_INT (PNX833X_PIC_IRQ_BASE + 47)
+#define PNX8335_PIC_MMI_SIF0_INT (PNX833X_PIC_IRQ_BASE + 48)
+#define PNX8335_PIC_MMI_SIF1_INT (PNX833X_PIC_IRQ_BASE + 49)
+#define PNX8335_PIC_MMI_CDMMU_INT (PNX833X_PIC_IRQ_BASE + 50)
+#define PNX8335_PIC_PIBCS_INT (PNX833X_PIC_IRQ_BASE + 51)
+#define PNX8335_PIC_ETHERNET_INT (PNX833X_PIC_IRQ_BASE + 52)
+#define PNX8335_PIC_VMSP1_0_INT (PNX833X_PIC_IRQ_BASE + 53)
+#define PNX8335_PIC_VMSP1_1_INT (PNX833X_PIC_IRQ_BASE + 54)
+#define PNX8335_PIC_VMSP1_DMA_INT (PNX833X_PIC_IRQ_BASE + 55)
+#define PNX8335_PIC_TDGR_DE_INT (PNX833X_PIC_IRQ_BASE + 56)
+#define PNX8335_PIC_IR1_IRQ_INT (PNX833X_PIC_IRQ_BASE + 57)
+#endif
+
+/* GPIO interrupts */
+#define PNX833X_GPIO_0_INT (PNX833X_GPIO_IRQ_BASE + 0)
+#define PNX833X_GPIO_1_INT (PNX833X_GPIO_IRQ_BASE + 1)
+#define PNX833X_GPIO_2_INT (PNX833X_GPIO_IRQ_BASE + 2)
+#define PNX833X_GPIO_3_INT (PNX833X_GPIO_IRQ_BASE + 3)
+#define PNX833X_GPIO_4_INT (PNX833X_GPIO_IRQ_BASE + 4)
+#define PNX833X_GPIO_5_INT (PNX833X_GPIO_IRQ_BASE + 5)
+#define PNX833X_GPIO_6_INT (PNX833X_GPIO_IRQ_BASE + 6)
+#define PNX833X_GPIO_7_INT (PNX833X_GPIO_IRQ_BASE + 7)
+#define PNX833X_GPIO_8_INT (PNX833X_GPIO_IRQ_BASE + 8)
+#define PNX833X_GPIO_9_INT (PNX833X_GPIO_IRQ_BASE + 9)
+#define PNX833X_GPIO_10_INT (PNX833X_GPIO_IRQ_BASE + 10)
+#define PNX833X_GPIO_11_INT (PNX833X_GPIO_IRQ_BASE + 11)
+#define PNX833X_GPIO_12_INT (PNX833X_GPIO_IRQ_BASE + 12)
+#define PNX833X_GPIO_13_INT (PNX833X_GPIO_IRQ_BASE + 13)
+#define PNX833X_GPIO_14_INT (PNX833X_GPIO_IRQ_BASE + 14)
+#define PNX833X_GPIO_15_INT (PNX833X_GPIO_IRQ_BASE + 15)
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx833x/irq.h b/arch/mips/include/asm/mach-pnx833x/irq.h
new file mode 100644
index 00000000..745114b1
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx833x/irq.h
@@ -0,0 +1,53 @@
+/*
+ * irq.h: IRQ mappings for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_MIPS_MACH_PNX833X_IRQ_H
+#define __ASM_MIPS_MACH_PNX833X_IRQ_H
+/*
+ * The "IRQ numbers" are completely virtual.
+ *
+ * In PNX8330/1, we have 48 interrupt lines, numbered from 1 to 48.
+ * Let's use numbers 1..48 for PIC interrupts, number 0 for timer interrupt,
+ * numbers 49..64 for (virtual) GPIO interrupts.
+ *
+ * In PNX8335, we have 57 interrupt lines, numbered from 1 to 57,
+ * connected to PIC, which uses core hardware interrupt 2, and also
+ * a timer interrupt through hardware interrupt 5.
+ * Let's use numbers 1..64 for PIC interrupts, number 0 for timer interrupt,
+ * numbers 65..80 for (virtual) GPIO interrupts.
+ *
+ */
+#if defined(CONFIG_SOC_PNX8335)
+ #define PNX833X_PIC_NUM_IRQ 58
+#else
+ #define PNX833X_PIC_NUM_IRQ 37
+#endif
+
+#define MIPS_CPU_NUM_IRQ 8
+#define PNX833X_GPIO_NUM_IRQ 16
+
+#define MIPS_CPU_IRQ_BASE 0
+#define PNX833X_PIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + MIPS_CPU_NUM_IRQ)
+#define PNX833X_GPIO_IRQ_BASE (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ)
+#define NR_IRQS (MIPS_CPU_NUM_IRQ + PNX833X_PIC_NUM_IRQ + PNX833X_GPIO_NUM_IRQ)
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx833x/pnx833x.h b/arch/mips/include/asm/mach-pnx833x/pnx833x.h
new file mode 100644
index 00000000..100f5287
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx833x/pnx833x.h
@@ -0,0 +1,202 @@
+/*
+ * pnx833x.h: Register mappings for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __ASM_MIPS_MACH_PNX833X_PNX833X_H
+#define __ASM_MIPS_MACH_PNX833X_PNX833X_H
+
+/* All regs are accessed in KSEG1 */
+#define PNX833X_BASE (0xa0000000ul + 0x17E00000ul)
+
+#define PNX833X_REG(offs) (*((volatile unsigned long *)(PNX833X_BASE + offs)))
+
+/* Registers are named exactly as in PNX833X docs, just with PNX833X_ prefix */
+
+/* Read access to multibit fields */
+#define PNX833X_BIT(val, reg, field) ((val) & PNX833X_##reg##_##field)
+#define PNX833X_REGBIT(reg, field) PNX833X_BIT(PNX833X_##reg, reg, field)
+
+/* Use PNX833X_FIELD to extract a field from val */
+#define PNX_FIELD(cpu, val, reg, field) \
+ (((val) & PNX##cpu##_##reg##_##field##_MASK) >> \
+ PNX##cpu##_##reg##_##field##_SHIFT)
+#define PNX833X_FIELD(val, reg, field) PNX_FIELD(833X, val, reg, field)
+#define PNX8330_FIELD(val, reg, field) PNX_FIELD(8330, val, reg, field)
+#define PNX8335_FIELD(val, reg, field) PNX_FIELD(8335, val, reg, field)
+
+/* Use PNX833X_REGFIELD to extract a field from a register */
+#define PNX833X_REGFIELD(reg, field) PNX833X_FIELD(PNX833X_##reg, reg, field)
+#define PNX8330_REGFIELD(reg, field) PNX8330_FIELD(PNX8330_##reg, reg, field)
+#define PNX8335_REGFIELD(reg, field) PNX8335_FIELD(PNX8335_##reg, reg, field)
+
+
+#define PNX_WRITEFIELD(cpu, val, reg, field) \
+ (PNX##cpu##_##reg = (PNX##cpu##_##reg & ~(PNX##cpu##_##reg##_##field##_MASK)) | \
+ ((val) << PNX##cpu##_##reg##_##field##_SHIFT))
+#define PNX833X_WRITEFIELD(val, reg, field) \
+ PNX_WRITEFIELD(833X, val, reg, field)
+#define PNX8330_WRITEFIELD(val, reg, field) \
+ PNX_WRITEFIELD(8330, val, reg, field)
+#define PNX8335_WRITEFIELD(val, reg, field) \
+ PNX_WRITEFIELD(8335, val, reg, field)
+
+
+/* Macros to detect CPU type */
+
+#define PNX833X_CONFIG_MODULE_ID PNX833X_REG(0x7FFC)
+#define PNX833X_CONFIG_MODULE_ID_MAJREV_MASK 0x0000f000
+#define PNX833X_CONFIG_MODULE_ID_MAJREV_SHIFT 12
+#define PNX8330_CONFIG_MODULE_MAJREV 4
+#define PNX8335_CONFIG_MODULE_MAJREV 5
+#define CPU_IS_PNX8330 (PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == \
+ PNX8330_CONFIG_MODULE_MAJREV)
+#define CPU_IS_PNX8335 (PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == \
+ PNX8335_CONFIG_MODULE_MAJREV)
+
+
+
+#define PNX833X_RESET_CONTROL PNX833X_REG(0x8004)
+#define PNX833X_RESET_CONTROL_2 PNX833X_REG(0x8014)
+
+#define PNX833X_PIC_REG(offs) PNX833X_REG(0x01000 + (offs))
+#define PNX833X_PIC_INT_PRIORITY PNX833X_PIC_REG(0x0)
+#define PNX833X_PIC_INT_SRC PNX833X_PIC_REG(0x4)
+#define PNX833X_PIC_INT_SRC_INT_SRC_MASK 0x00000FF8ul /* bits 11:3 */
+#define PNX833X_PIC_INT_SRC_INT_SRC_SHIFT 3
+#define PNX833X_PIC_INT_REG(irq) PNX833X_PIC_REG(0x10 + 4*(irq))
+
+#define PNX833X_CLOCK_CPUCP_CTL PNX833X_REG(0x9228)
+#define PNX833X_CLOCK_CPUCP_CTL_EXIT_RESET 0x00000002ul /* bit 1 */
+#define PNX833X_CLOCK_CPUCP_CTL_DIV_CLOCK_MASK 0x00000018ul /* bits 4:3 */
+#define PNX833X_CLOCK_CPUCP_CTL_DIV_CLOCK_SHIFT 3
+
+#define PNX8335_CLOCK_PLL_CPU_CTL PNX833X_REG(0x9020)
+#define PNX8335_CLOCK_PLL_CPU_CTL_FREQ_MASK 0x1f
+#define PNX8335_CLOCK_PLL_CPU_CTL_FREQ_SHIFT 0
+
+#define PNX833X_CONFIG_MUX PNX833X_REG(0x7004)
+#define PNX833X_CONFIG_MUX_IDE_MUX 0x00000080 /* bit 7 */
+
+#define PNX8330_CONFIG_POLYFUSE_7 PNX833X_REG(0x7040)
+#define PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_MASK 0x00180000
+#define PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_SHIFT 19
+
+#define PNX833X_PIO_IN PNX833X_REG(0xF000)
+#define PNX833X_PIO_OUT PNX833X_REG(0xF004)
+#define PNX833X_PIO_DIR PNX833X_REG(0xF008)
+#define PNX833X_PIO_SEL PNX833X_REG(0xF014)
+#define PNX833X_PIO_INT_EDGE PNX833X_REG(0xF020)
+#define PNX833X_PIO_INT_HI PNX833X_REG(0xF024)
+#define PNX833X_PIO_INT_LO PNX833X_REG(0xF028)
+#define PNX833X_PIO_INT_STATUS PNX833X_REG(0xFFE0)
+#define PNX833X_PIO_INT_ENABLE PNX833X_REG(0xFFE4)
+#define PNX833X_PIO_INT_CLEAR PNX833X_REG(0xFFE8)
+#define PNX833X_PIO_IN2 PNX833X_REG(0xF05C)
+#define PNX833X_PIO_OUT2 PNX833X_REG(0xF060)
+#define PNX833X_PIO_DIR2 PNX833X_REG(0xF064)
+#define PNX833X_PIO_SEL2 PNX833X_REG(0xF068)
+
+#define PNX833X_UART0_PORTS_START (PNX833X_BASE + 0xB000)
+#define PNX833X_UART0_PORTS_END (PNX833X_BASE + 0xBFFF)
+#define PNX833X_UART1_PORTS_START (PNX833X_BASE + 0xC000)
+#define PNX833X_UART1_PORTS_END (PNX833X_BASE + 0xCFFF)
+
+#define PNX833X_USB_PORTS_START (PNX833X_BASE + 0x19000)
+#define PNX833X_USB_PORTS_END (PNX833X_BASE + 0x19FFF)
+
+#define PNX833X_CONFIG_USB PNX833X_REG(0x7008)
+
+#define PNX833X_I2C0_PORTS_START (PNX833X_BASE + 0xD000)
+#define PNX833X_I2C0_PORTS_END (PNX833X_BASE + 0xDFFF)
+#define PNX833X_I2C1_PORTS_START (PNX833X_BASE + 0xE000)
+#define PNX833X_I2C1_PORTS_END (PNX833X_BASE + 0xEFFF)
+
+#define PNX833X_IDE_PORTS_START (PNX833X_BASE + 0x1A000)
+#define PNX833X_IDE_PORTS_END (PNX833X_BASE + 0x1AFFF)
+#define PNX833X_IDE_MODULE_ID PNX833X_REG(0x1AFFC)
+
+#define PNX833X_IDE_MODULE_ID_MODULE_ID_MASK 0xFFFF0000
+#define PNX833X_IDE_MODULE_ID_MODULE_ID_SHIFT 16
+#define PNX833X_IDE_MODULE_ID_VALUE 0xA009
+
+
+#define PNX833X_MIU_SEL0 PNX833X_REG(0x2004)
+#define PNX833X_MIU_SEL0_TIMING PNX833X_REG(0x2008)
+#define PNX833X_MIU_SEL1 PNX833X_REG(0x200C)
+#define PNX833X_MIU_SEL1_TIMING PNX833X_REG(0x2010)
+#define PNX833X_MIU_SEL2 PNX833X_REG(0x2014)
+#define PNX833X_MIU_SEL2_TIMING PNX833X_REG(0x2018)
+#define PNX833X_MIU_SEL3 PNX833X_REG(0x201C)
+#define PNX833X_MIU_SEL3_TIMING PNX833X_REG(0x2020)
+
+#define PNX833X_MIU_SEL0_SPI_MODE_ENABLE_MASK (1 << 14)
+#define PNX833X_MIU_SEL0_SPI_MODE_ENABLE_SHIFT 14
+
+#define PNX833X_MIU_SEL0_BURST_MODE_ENABLE_MASK (1 << 7)
+#define PNX833X_MIU_SEL0_BURST_MODE_ENABLE_SHIFT 7
+
+#define PNX833X_MIU_SEL0_BURST_PAGE_LEN_MASK (0xF << 9)
+#define PNX833X_MIU_SEL0_BURST_PAGE_LEN_SHIFT 9
+
+#define PNX833X_MIU_CONFIG_SPI PNX833X_REG(0x2000)
+
+#define PNX833X_MIU_CONFIG_SPI_OPCODE_MASK (0xFF << 3)
+#define PNX833X_MIU_CONFIG_SPI_OPCODE_SHIFT 3
+
+#define PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_MASK (1 << 2)
+#define PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_SHIFT 2
+
+#define PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_MASK (1 << 1)
+#define PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_SHIFT 1
+
+#define PNX833X_MIU_CONFIG_SPI_SYNC_MASK (1 << 0)
+#define PNX833X_MIU_CONFIG_SPI_SYNC_SHIFT 0
+
+#define PNX833X_WRITE_CONFIG_SPI(opcode, data_enable, addr_enable, sync) \
+ (PNX833X_MIU_CONFIG_SPI = \
+ ((opcode) << PNX833X_MIU_CONFIG_SPI_OPCODE_SHIFT) | \
+ ((data_enable) << PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_SHIFT) | \
+ ((addr_enable) << PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_SHIFT) | \
+ ((sync) << PNX833X_MIU_CONFIG_SPI_SYNC_SHIFT))
+
+#define PNX8335_IP3902_PORTS_START (PNX833X_BASE + 0x2F000)
+#define PNX8335_IP3902_PORTS_END (PNX833X_BASE + 0x2FFFF)
+#define PNX8335_IP3902_MODULE_ID PNX833X_REG(0x2FFFC)
+
+#define PNX8335_IP3902_MODULE_ID_MODULE_ID_MASK 0xFFFF0000
+#define PNX8335_IP3902_MODULE_ID_MODULE_ID_SHIFT 16
+#define PNX8335_IP3902_MODULE_ID_VALUE 0x3902
+
+ /* I/O location(gets remapped)*/
+#define PNX8335_NAND_BASE 0x18000000
+/* I/O location with CLE high */
+#define PNX8335_NAND_CLE_MASK 0x00100000
+/* I/O location with ALE high */
+#define PNX8335_NAND_ALE_MASK 0x00010000
+
+#define PNX8335_SATA_PORTS_START (PNX833X_BASE + 0x2E000)
+#define PNX8335_SATA_PORTS_END (PNX833X_BASE + 0x2EFFF)
+#define PNX8335_SATA_MODULE_ID PNX833X_REG(0x2EFFC)
+
+#define PNX8335_SATA_MODULE_ID_MODULE_ID_MASK 0xFFFF0000
+#define PNX8335_SATA_MODULE_ID_MODULE_ID_SHIFT 16
+#define PNX8335_SATA_MODULE_ID_VALUE 0xA099
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx833x/war.h b/arch/mips/include/asm/mach-pnx833x/war.h
new file mode 100644
index 00000000..82cd1e97
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx833x/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_PNX833X_WAR_H
+#define __ASM_MIPS_MACH_PNX833X_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_PNX8550_WAR_H */
diff --git a/arch/mips/include/asm/mach-pnx8550/cm.h b/arch/mips/include/asm/mach-pnx8550/cm.h
new file mode 100644
index 00000000..bb0a56c7
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/cm.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Clock module specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_CM_H
+#define __PNX8550_CM_H
+
+#define PNX8550_CM_BASE 0xBBE47000
+
+#define PNX8550_CM_PLL0_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x000)
+#define PNX8550_CM_PLL1_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x004)
+#define PNX8550_CM_PLL2_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x008)
+#define PNX8550_CM_PLL3_CTL *(volatile unsigned long *)(PNX8550_CM_BASE + 0x00C)
+
+// Table not complete.....
+
+#define PNX8550_CM_PLL_BLOCKED_MASK 0x80000000
+#define PNX8550_CM_PLL_LOCK_MASK 0x40000000
+#define PNX8550_CM_PLL_CURRENT_ADJ_MASK 0x3c000000
+#define PNX8550_CM_PLL_N_MASK 0x01ff0000
+#define PNX8550_CM_PLL_M_MASK 0x00003f00
+#define PNX8550_CM_PLL_P_MASK 0x0000000c
+#define PNX8550_CM_PLL_PD_MASK 0x00000002
+
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx8550/glb.h b/arch/mips/include/asm/mach-pnx8550/glb.h
new file mode 100644
index 00000000..07aa85e6
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/glb.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PNX8550 global definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_GLB_H
+#define __PNX8550_GLB_H
+
+#define PNX8550_GLB1_BASE 0xBBE63000
+#define PNX8550_GLB2_BASE 0xBBE4d000
+#define PNX8550_RESET_BASE 0xBBE60000
+
+/* PCI Inta Output Enable Registers */
+#define PNX8550_GLB2_ENAB_INTA_O *(volatile unsigned long *)(PNX8550_GLB2_BASE + 0x050)
+
+/* Bit 1:Enable DAC Powerdown
+ 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+*/
+#define PNX8550_GLB_DAC_PD 0x2
+/* Bit 0:Enable of PCI inta output
+ 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+*/
+#define PNX8550_GLB_ENABLE_INTA_O 0x1
+
+/* PCI Direct Mappings */
+#define PNX8550_PCIMEM 0x12000000
+#define PNX8550_PCIMEM_SIZE 0x08000000
+#define PNX8550_PCIIO 0x1c000000
+#define PNX8550_PCIIO_SIZE 0x02000000 /* 32M */
+
+#define PNX8550_PORT_BASE KSEG1
+
+// GPIO def
+#define PNX8550_GPIO_BASE 0x1Be00000
+
+#define PNX8550_GPIO_DIRQ0 (PNX8550_GPIO_BASE + 0x104500)
+#define PNX8550_GPIO_MC1 (PNX8550_GPIO_BASE + 0x104004)
+#define PNX8550_GPIO_MC_31_BIT 30
+#define PNX8550_GPIO_MC_30_BIT 28
+#define PNX8550_GPIO_MC_29_BIT 26
+#define PNX8550_GPIO_MC_28_BIT 24
+#define PNX8550_GPIO_MC_27_BIT 22
+#define PNX8550_GPIO_MC_26_BIT 20
+#define PNX8550_GPIO_MC_25_BIT 18
+#define PNX8550_GPIO_MC_24_BIT 16
+#define PNX8550_GPIO_MC_23_BIT 14
+#define PNX8550_GPIO_MC_22_BIT 12
+#define PNX8550_GPIO_MC_21_BIT 10
+#define PNX8550_GPIO_MC_20_BIT 8
+#define PNX8550_GPIO_MC_19_BIT 6
+#define PNX8550_GPIO_MC_18_BIT 4
+#define PNX8550_GPIO_MC_17_BIT 2
+#define PNX8550_GPIO_MC_16_BIT 0
+
+#define PNX8550_GPIO_MODE_PRIMOP 0x1
+#define PNX8550_GPIO_MODE_NO_OPENDR 0x2
+#define PNX8550_GPIO_MODE_OPENDR 0x3
+
+// RESET module
+#define PNX8550_RST_CTL *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x0)
+#define PNX8550_RST_CAUSE *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x4)
+#define PNX8550_RST_EN_WATCHDOG *(volatile unsigned long *)(PNX8550_RESET_BASE + 0x8)
+
+#define PNX8550_RST_REL_MIPS_RST_N 0x8
+#define PNX8550_RST_DO_SW_RST 0x4
+#define PNX8550_RST_REL_SYS_RST_OUT 0x2
+#define PNX8550_RST_ASSERT_SYS_RST_OUT 0x1
+#endif
diff --git a/arch/mips/include/asm/mach-pnx8550/int.h b/arch/mips/include/asm/mach-pnx8550/int.h
new file mode 100644
index 00000000..0e0668b5
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/int.h
@@ -0,0 +1,140 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Interrupt specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_INT_H
+#define __PNX8550_INT_H
+
+#define PNX8550_GIC_BASE 0xBBE3E000
+
+#define PNX8550_GIC_PRIMASK_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x000)
+#define PNX8550_GIC_PRIMASK_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x004)
+#define PNX8550_GIC_VECTOR_0 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x100)
+#define PNX8550_GIC_VECTOR_1 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x104)
+#define PNX8550_GIC_PEND_1_31 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x200)
+#define PNX8550_GIC_PEND_32_63 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x204)
+#define PNX8550_GIC_PEND_64_70 *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x208)
+#define PNX8550_GIC_FEATURES *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x300)
+#define PNX8550_GIC_REQ(x) *(volatile unsigned long *)(PNX8550_GIC_BASE + 0x400 + (x)*4)
+#define PNX8550_GIC_MOD_ID *(volatile unsigned long *)(PNX8550_GIC_BASE + 0xFFC)
+
+// cp0 is two software + six hw exceptions
+#define PNX8550_INT_CP0_TOTINT 8
+#define PNX8550_INT_CP0_MIN 0
+#define PNX8550_INT_CP0_MAX (PNX8550_INT_CP0_MIN + PNX8550_INT_CP0_TOTINT - 1)
+
+#define MIPS_CPU_GIC_IRQ 2
+#define MIPS_CPU_TIMER_IRQ 7
+
+// GIC are 71 exceptions connected to cp0's first hardware exception
+#define PNX8550_INT_GIC_TOTINT 71
+#define PNX8550_INT_GIC_MIN (PNX8550_INT_CP0_MAX+1)
+#define PNX8550_INT_GIC_MAX (PNX8550_INT_GIC_MIN + PNX8550_INT_GIC_TOTINT - 1)
+
+#define PNX8550_INT_UNDEF (PNX8550_INT_GIC_MIN+0)
+#define PNX8550_INT_IPC_TARGET0_MIPS (PNX8550_INT_GIC_MIN+1)
+#define PNX8550_INT_IPC_TARGET1_TM32_1 (PNX8550_INT_GIC_MIN+2)
+#define PNX8550_INT_IPC_TARGET1_TM32_2 (PNX8550_INT_GIC_MIN+3)
+#define PNX8550_INT_RESERVED_4 (PNX8550_INT_GIC_MIN+4)
+#define PNX8550_INT_USB (PNX8550_INT_GIC_MIN+5)
+#define PNX8550_INT_GPIO_EQ1 (PNX8550_INT_GIC_MIN+6)
+#define PNX8550_INT_GPIO_EQ2 (PNX8550_INT_GIC_MIN+7)
+#define PNX8550_INT_GPIO_EQ3 (PNX8550_INT_GIC_MIN+8)
+#define PNX8550_INT_GPIO_EQ4 (PNX8550_INT_GIC_MIN+9)
+
+#define PNX8550_INT_GPIO_EQ5 (PNX8550_INT_GIC_MIN+10)
+#define PNX8550_INT_GPIO_EQ6 (PNX8550_INT_GIC_MIN+11)
+#define PNX8550_INT_RESERVED_12 (PNX8550_INT_GIC_MIN+12)
+#define PNX8550_INT_QVCP1 (PNX8550_INT_GIC_MIN+13)
+#define PNX8550_INT_QVCP2 (PNX8550_INT_GIC_MIN+14)
+#define PNX8550_INT_I2C1 (PNX8550_INT_GIC_MIN+15)
+#define PNX8550_INT_I2C2 (PNX8550_INT_GIC_MIN+16)
+#define PNX8550_INT_ISO_UART1 (PNX8550_INT_GIC_MIN+17)
+#define PNX8550_INT_ISO_UART2 (PNX8550_INT_GIC_MIN+18)
+#define PNX8550_INT_UART1 (PNX8550_INT_GIC_MIN+19)
+
+#define PNX8550_INT_UART2 (PNX8550_INT_GIC_MIN+20)
+#define PNX8550_INT_QNTR (PNX8550_INT_GIC_MIN+21)
+#define PNX8550_INT_RESERVED22 (PNX8550_INT_GIC_MIN+22)
+#define PNX8550_INT_T_DSC (PNX8550_INT_GIC_MIN+23)
+#define PNX8550_INT_M_DSC (PNX8550_INT_GIC_MIN+24)
+#define PNX8550_INT_RESERVED25 (PNX8550_INT_GIC_MIN+25)
+#define PNX8550_INT_2D_DRAW_ENG (PNX8550_INT_GIC_MIN+26)
+#define PNX8550_INT_MEM_BASED_SCALAR1 (PNX8550_INT_GIC_MIN+27)
+#define PNX8550_INT_VIDEO_MPEG (PNX8550_INT_GIC_MIN+28)
+#define PNX8550_INT_VIDEO_INPUT_P1 (PNX8550_INT_GIC_MIN+29)
+
+#define PNX8550_INT_VIDEO_INPUT_P2 (PNX8550_INT_GIC_MIN+30)
+#define PNX8550_INT_SPDI1 (PNX8550_INT_GIC_MIN+31)
+#define PNX8550_INT_SPDO (PNX8550_INT_GIC_MIN+32)
+#define PNX8550_INT_AUDIO_INPUT1 (PNX8550_INT_GIC_MIN+33)
+#define PNX8550_INT_AUDIO_OUTPUT1 (PNX8550_INT_GIC_MIN+34)
+#define PNX8550_INT_AUDIO_INPUT2 (PNX8550_INT_GIC_MIN+35)
+#define PNX8550_INT_AUDIO_OUTPUT2 (PNX8550_INT_GIC_MIN+36)
+#define PNX8550_INT_MEMBASED_SCALAR2 (PNX8550_INT_GIC_MIN+37)
+#define PNX8550_INT_VPK (PNX8550_INT_GIC_MIN+38)
+#define PNX8550_INT_MPEG1_MIPS (PNX8550_INT_GIC_MIN+39)
+
+#define PNX8550_INT_MPEG1_TM (PNX8550_INT_GIC_MIN+40)
+#define PNX8550_INT_MPEG2_MIPS (PNX8550_INT_GIC_MIN+41)
+#define PNX8550_INT_MPEG2_TM (PNX8550_INT_GIC_MIN+42)
+#define PNX8550_INT_TS_DMA (PNX8550_INT_GIC_MIN+43)
+#define PNX8550_INT_EDMA (PNX8550_INT_GIC_MIN+44)
+#define PNX8550_INT_TM_DEBUG1 (PNX8550_INT_GIC_MIN+45)
+#define PNX8550_INT_TM_DEBUG2 (PNX8550_INT_GIC_MIN+46)
+#define PNX8550_INT_PCI_INTA (PNX8550_INT_GIC_MIN+47)
+#define PNX8550_INT_CLOCK_MODULE (PNX8550_INT_GIC_MIN+48)
+#define PNX8550_INT_PCI_XIO_INTA_PCI (PNX8550_INT_GIC_MIN+49)
+
+#define PNX8550_INT_PCI_XIO_INTB_DMA (PNX8550_INT_GIC_MIN+50)
+#define PNX8550_INT_PCI_XIO_INTC_GPPM (PNX8550_INT_GIC_MIN+51)
+#define PNX8550_INT_PCI_XIO_INTD_GPXIO (PNX8550_INT_GIC_MIN+52)
+#define PNX8550_INT_DVD_CSS (PNX8550_INT_GIC_MIN+53)
+#define PNX8550_INT_VLD (PNX8550_INT_GIC_MIN+54)
+#define PNX8550_INT_GPIO_TSU_7_0 (PNX8550_INT_GIC_MIN+55)
+#define PNX8550_INT_GPIO_TSU_15_8 (PNX8550_INT_GIC_MIN+56)
+#define PNX8550_INT_GPIO_CTU_IR (PNX8550_INT_GIC_MIN+57)
+#define PNX8550_INT_GPIO0 (PNX8550_INT_GIC_MIN+58)
+#define PNX8550_INT_GPIO1 (PNX8550_INT_GIC_MIN+59)
+
+#define PNX8550_INT_GPIO2 (PNX8550_INT_GIC_MIN+60)
+#define PNX8550_INT_GPIO3 (PNX8550_INT_GIC_MIN+61)
+#define PNX8550_INT_GPIO4 (PNX8550_INT_GIC_MIN+62)
+#define PNX8550_INT_GPIO5 (PNX8550_INT_GIC_MIN+63)
+#define PNX8550_INT_GPIO6 (PNX8550_INT_GIC_MIN+64)
+#define PNX8550_INT_GPIO7 (PNX8550_INT_GIC_MIN+65)
+#define PNX8550_INT_PMAN_SECURITY (PNX8550_INT_GIC_MIN+66)
+#define PNX8550_INT_I2C3 (PNX8550_INT_GIC_MIN+67)
+#define PNX8550_INT_RESERVED_68 (PNX8550_INT_GIC_MIN+68)
+#define PNX8550_INT_SPDI2 (PNX8550_INT_GIC_MIN+69)
+
+#define PNX8550_INT_I2C4 (PNX8550_INT_GIC_MIN+70)
+
+// Timer are 3 exceptions connected to cp0's 7th hardware exception
+#define PNX8550_INT_TIMER_TOTINT 3
+#define PNX8550_INT_TIMER_MIN (PNX8550_INT_GIC_MAX+1)
+#define PNX8550_INT_TIMER_MAX (PNX8550_INT_TIMER_MIN + PNX8550_INT_TIMER_TOTINT - 1)
+
+#define PNX8550_INT_TIMER1 (PNX8550_INT_TIMER_MIN+0)
+#define PNX8550_INT_TIMER2 (PNX8550_INT_TIMER_MIN+1)
+#define PNX8550_INT_TIMER3 (PNX8550_INT_TIMER_MIN+2)
+#define PNX8550_INT_WATCHDOG PNX8550_INT_TIMER3
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx8550/kernel-entry-init.h b/arch/mips/include/asm/mach-pnx8550/kernel-entry-init.h
new file mode 100644
index 00000000..bdde00c9
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/kernel-entry-init.h
@@ -0,0 +1,262 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Embedded Alley Solutions, Inc
+ */
+#ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H
+#define __ASM_MACH_KERNEL_ENTRY_INIT_H
+
+#include <asm/cacheops.h>
+#include <asm/addrspace.h>
+
+#define CO_CONFIGPR_VALID 0x3F1F41FF /* valid bits to write to ConfigPR */
+#define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;
+#define CACHE_OPC 0xBC000000 /* MIPS cache instruction opcode */
+#define ICACHE_LINE_SIZE 32 /* Instruction cache line size bytes */
+#define DCACHE_LINE_SIZE 32 /* Data cache line size in bytes */
+
+#define ICACHE_SET_COUNT 256 /* Instruction cache set count */
+#define DCACHE_SET_COUNT 128 /* Data cache set count */
+
+#define ICACHE_SET_SIZE (ICACHE_SET_COUNT * ICACHE_LINE_SIZE)
+#define DCACHE_SET_SIZE (DCACHE_SET_COUNT * DCACHE_LINE_SIZE)
+
+ .macro kernel_entry_setup
+ .set push
+ .set noreorder
+ /*
+ * PNX8550 entry point, when running a non compressed
+ * kernel. When loading a zImage, the head.S code in
+ * arch/mips/zboot/pnx8550 will init the caches and,
+ * decompress the kernel, and branch to kernel_entry.
+ */
+cache_begin: li t0, (1<<28)
+ mtc0 t0, CP0_STATUS /* cp0 usable */
+ HAZARD_CP0
+
+ mtc0 zero, CP0_CAUSE
+ HAZARD_CP0
+
+
+ /* Set static virtual to phys address translation and TLB disabled */
+ mfc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ and t0, ~((1<<19) | (1<<20)) /* TLB/MAP cleared */
+ mtc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */
+
+ init_icache
+ nop
+ init_dcache
+ nop
+
+ cachePr4450ICReset
+ nop
+
+ cachePr4450DCReset
+ nop
+
+ /* read ConfigPR into t0 */
+ mfc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+
+ /* enable the TLB */
+ or t0, (1<<19)
+
+ /* disable the ICACHE: at least 10x slower */
+ /* or t0, (1<<26) */
+
+ /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set */
+ /* or t0, (1<<27) */
+
+ and t0, CO_CONFIGPR_VALID
+
+ /* enable TLB. */
+ mtc0 t0, CP0_CONFIG, 7
+ HAZARD_CP0
+cache_end:
+ /* Setup CMEM_0 to MMIO address space, 2MB */
+ lui t0, 0x1BE0
+ addi t0, t0, 0x3
+ mtc0 $8, $22, 4
+ nop
+
+ /* Setup CMEM_1, 128MB */
+ lui t0, 0x1000
+ addi t0, t0, 0xf
+ mtc0 $8, $22, 5
+ nop
+
+
+ /* Setup CMEM_2, 32MB */
+ lui t0, 0x1C00
+ addi t0, t0, 0xb
+ mtc0 $8, $22, 6
+ nop
+
+ /* Setup CMEM_3, 0MB */
+ lui t0, 0x0
+ addi t0, t0, 0x0
+ mtc0 $8, $22, 7
+ nop
+
+ /* Enable cache */
+ mfc0 t0, CP0_CONFIG
+ HAZARD_CP0
+ and t0, t0, 0xFFFFFFF8
+ or t0, t0, 3
+ mtc0 t0, CP0_CONFIG
+ HAZARD_CP0
+ .set pop
+ .endm
+
+ .macro init_icache
+ .set push
+ .set noreorder
+
+ /* Get Cache Configuration */
+ mfc0 t3, CP0_CONFIG, 1
+ HAZARD_CP0
+
+ /* get cache Line size */
+
+ srl t1, t3, 19 /* C0_CONFIGPR_IL_SHIFT */
+ andi t1, t1, 0x7 /* C0_CONFIGPR_IL_MASK */
+ beq t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */
+ nop
+ addiu t0, t1, 1
+ ori t1, zero, 1
+ sllv t1, t1, t0
+
+ /* get max cache Index */
+ srl t2, t3, 22 /* C0_CONFIGPR_IS_SHIFT */
+ andi t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */
+ addiu t0, t2, 6
+ ori t2, zero, 1
+ sllv t2, t2, t0
+
+ /* get max cache way */
+ srl t3, t3, 16 /* C0_CONFIGPR_IA_SHIFT */
+ andi t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */
+ addiu t3, t3, 1
+
+ /* total no of cache lines */
+ multu t2, t3 /* max index * max way */
+ mflo t2
+ addiu t2, t2, -1
+
+ move t0, zero
+pr4450_next_instruction_cache_set:
+ cache Index_Invalidate_I, 0(t0)
+ addu t0, t0, t1 /* add bytes in a line */
+ bne t2, zero, pr4450_next_instruction_cache_set
+ addiu t2, t2, -1 /* reduce no of lines to invalidate by one */
+pr4450_instr_cache_invalidated:
+ .set pop
+ .endm
+
+ .macro init_dcache
+ .set push
+ .set noreorder
+ move t1, zero
+
+ /* Store Tag Information */
+ mtc0 zero, CP0_TAGLO, 0
+ HAZARD_CP0
+
+ mtc0 zero, CP0_TAGHI, 0
+ HAZARD_CP0
+
+ /* Cache size is 16384 = 512 lines x 32 bytes per line */
+ or t2, zero, (128*4)-1 /* 512 lines */
+ /* Invalidate all lines */
+2:
+ cache Index_Store_Tag_D, 0(t1)
+ addiu t2, t2, -1
+ bne t2, zero, 2b
+ addiu t1, t1, 32 /* 32 bytes in a line */
+ .set pop
+ .endm
+
+ .macro cachePr4450ICReset
+ .set push
+ .set noreorder
+
+ /* Save CP0 status reg on entry; */
+ /* disable interrupts during cache reset */
+ mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */
+ HAZARD_CP0
+
+ mtc0 zero, CP0_STATUS /* disable CPU interrupts */
+ HAZARD_CP0
+
+ or t1, zero, zero /* T1 = starting cache index (0) */
+ ori t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */
+
+ icache_invd_loop:
+ /* 9 == register t1 */
+ .word CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
+ (0 * ICACHE_SET_SIZE) /* invalidate inst cache WAY0 */
+ .word CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
+ (1 * ICACHE_SET_SIZE) /* invalidate inst cache WAY1 */
+
+ addiu t1, t1, ICACHE_LINE_SIZE /* T1 = next cache line index */
+ bne t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */
+ addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */
+
+ /* Initialize the latches in the instruction cache tag */
+ /* that drive the way selection tri-state bus drivers, by doing a */
+ /* dummy load while the instruction cache is still disabled. */
+ /* TODO: Is this needed ? */
+ la t1, KSEG0 /* T1 = cached memory base address */
+ lw zero, 0x0000(t1) /* (dummy read of first memory word) */
+
+ mtc0 t0, CP0_STATUS /* restore interrupt status on entry */
+ HAZARD_CP0
+ .set pop
+ .endm
+
+ .macro cachePr4450DCReset
+ .set push
+ .set noreorder
+ mfc0 t0, CP0_STATUS /* T0 = interrupt status on entry */
+ HAZARD_CP0
+ mtc0 zero, CP0_STATUS /* disable CPU interrupts */
+ HAZARD_CP0
+
+ /* Writeback/invalidate entire data cache sets/ways/lines */
+ or t1, zero, zero /* T1 = starting cache index (0) */
+ ori t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */
+
+ dcache_wbinvd_loop:
+ /* 9 == register t1 */
+ .word CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (0 * DCACHE_SET_SIZE) /* writeback/invalidate WAY0 */
+ .word CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (1 * DCACHE_SET_SIZE) /* writeback/invalidate WAY1 */
+ .word CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (2 * DCACHE_SET_SIZE) /* writeback/invalidate WAY2 */
+ .word CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
+ (3 * DCACHE_SET_SIZE) /* writeback/invalidate WAY3 */
+
+ addiu t1, t1, DCACHE_LINE_SIZE /* T1 = next data cache line index */
+ bne t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */
+ addiu t2, t2, -1 /* decrement T2 set cnt (delay slot) */
+
+ /* Initialize the latches in the data cache tag that drive the way
+ selection tri-state bus drivers, by doing a dummy load while the
+ data cache is still in the disabled mode. TODO: Is this needed ? */
+ la t1, KSEG0 /* T1 = cached memory base address */
+ lw zero, 0x0000(t1) /* (dummy read of first memory word) */
+
+ mtc0 t0, CP0_STATUS /* restore interrupt status on entry */
+ HAZARD_CP0
+ .set pop
+ .endm
+
+#endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */
diff --git a/arch/mips/include/asm/mach-pnx8550/nand.h b/arch/mips/include/asm/mach-pnx8550/nand.h
new file mode 100644
index 00000000..aefbc514
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/nand.h
@@ -0,0 +1,121 @@
+#ifndef __PNX8550_NAND_H
+#define __PNX8550_NAND_H
+
+#define PNX8550_NAND_BASE_ADDR 0x10000000
+#define PNX8550_PCIXIO_BASE 0xBBE40000
+
+#define PNX8550_DMA_EXT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x800)
+#define PNX8550_DMA_INT_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x804)
+#define PNX8550_DMA_TRANS_SIZE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x808)
+#define PNX8550_DMA_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x80c)
+#define PNX8550_XIO_SEL0 *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x814)
+#define PNX8550_GPXIO_ADDR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x820)
+#define PNX8550_GPXIO_WR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x824)
+#define PNX8550_GPXIO_RD *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x828)
+#define PNX8550_GPXIO_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x82C)
+#define PNX8550_XIO_FLASH_CTRL *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0x830)
+#define PNX8550_GPXIO_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb0)
+#define PNX8550_GPXIO_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb4)
+#define PNX8550_GPXIO_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfb8)
+#define PNX8550_DMA_INT_STATUS *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd0)
+#define PNX8550_DMA_INT_ENABLE *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd4)
+#define PNX8550_DMA_INT_CLEAR *(volatile unsigned long *)(PNX8550_PCIXIO_BASE + 0xfd8)
+
+#define PNX8550_XIO_SEL0_EN_16BIT 0x00800000
+#define PNX8550_XIO_SEL0_USE_ACK 0x00400000
+#define PNX8550_XIO_SEL0_REN_HIGH 0x00100000
+#define PNX8550_XIO_SEL0_REN_LOW 0x00040000
+#define PNX8550_XIO_SEL0_WEN_HIGH 0x00010000
+#define PNX8550_XIO_SEL0_WEN_LOW 0x00004000
+#define PNX8550_XIO_SEL0_WAIT 0x00000200
+#define PNX8550_XIO_SEL0_OFFSET 0x00000020
+#define PNX8550_XIO_SEL0_TYPE_68360 0x00000000
+#define PNX8550_XIO_SEL0_TYPE_NOR 0x00000008
+#define PNX8550_XIO_SEL0_TYPE_NAND 0x00000010
+#define PNX8550_XIO_SEL0_TYPE_IDE 0x00000018
+#define PNX8550_XIO_SEL0_SIZE_8MB 0x00000000
+#define PNX8550_XIO_SEL0_SIZE_16MB 0x00000002
+#define PNX8550_XIO_SEL0_SIZE_32MB 0x00000004
+#define PNX8550_XIO_SEL0_SIZE_64MB 0x00000006
+#define PNX8550_XIO_SEL0_ENAB 0x00000001
+
+#define PNX8550_SEL0_DEFAULT ((PNX8550_XIO_SEL0_EN_16BIT) | \
+ (PNX8550_XIO_SEL0_REN_HIGH*0)| \
+ (PNX8550_XIO_SEL0_REN_LOW*2) | \
+ (PNX8550_XIO_SEL0_WEN_HIGH*0)| \
+ (PNX8550_XIO_SEL0_WEN_LOW*2) | \
+ (PNX8550_XIO_SEL0_WAIT*4) | \
+ (PNX8550_XIO_SEL0_OFFSET*0) | \
+ (PNX8550_XIO_SEL0_TYPE_NAND) | \
+ (PNX8550_XIO_SEL0_SIZE_32MB) | \
+ (PNX8550_XIO_SEL0_ENAB))
+
+#define PNX8550_GPXIO_PENDING 0x00000200
+#define PNX8550_GPXIO_DONE 0x00000100
+#define PNX8550_GPXIO_CLR_DONE 0x00000080
+#define PNX8550_GPXIO_INIT 0x00000040
+#define PNX8550_GPXIO_READ_CMD 0x00000010
+#define PNX8550_GPXIO_BEN 0x0000000F
+
+#define PNX8550_XIO_FLASH_64MB 0x00200000
+#define PNX8550_XIO_FLASH_INC_DATA 0x00100000
+#define PNX8550_XIO_FLASH_CMD_PH 0x000C0000
+#define PNX8550_XIO_FLASH_CMD_PH2 0x00080000
+#define PNX8550_XIO_FLASH_CMD_PH1 0x00040000
+#define PNX8550_XIO_FLASH_CMD_PH0 0x00000000
+#define PNX8550_XIO_FLASH_ADR_PH 0x00030000
+#define PNX8550_XIO_FLASH_ADR_PH3 0x00030000
+#define PNX8550_XIO_FLASH_ADR_PH2 0x00020000
+#define PNX8550_XIO_FLASH_ADR_PH1 0x00010000
+#define PNX8550_XIO_FLASH_ADR_PH0 0x00000000
+#define PNX8550_XIO_FLASH_CMD_B(x) ((x<<8) & 0x0000FF00)
+#define PNX8550_XIO_FLASH_CMD_A(x) (x & 0x000000FF)
+
+#define PNX8550_XIO_INT_ACK 0x00004000
+#define PNX8550_XIO_INT_COMPL 0x00002000
+#define PNX8550_XIO_INT_NONSUP 0x00000200
+#define PNX8550_XIO_INT_ABORT 0x00000004
+
+#define PNX8550_DMA_CTRL_SINGLE_DATA 0x00000400
+#define PNX8550_DMA_CTRL_SND2XIO 0x00000200
+#define PNX8550_DMA_CTRL_FIX_ADDR 0x00000100
+#define PNX8550_DMA_CTRL_BURST_8 0x00000000
+#define PNX8550_DMA_CTRL_BURST_16 0x00000020
+#define PNX8550_DMA_CTRL_BURST_32 0x00000040
+#define PNX8550_DMA_CTRL_BURST_64 0x00000060
+#define PNX8550_DMA_CTRL_BURST_128 0x00000080
+#define PNX8550_DMA_CTRL_BURST_256 0x000000A0
+#define PNX8550_DMA_CTRL_BURST_512 0x000000C0
+#define PNX8550_DMA_CTRL_BURST_NORES 0x000000E0
+#define PNX8550_DMA_CTRL_INIT_DMA 0x00000010
+#define PNX8550_DMA_CTRL_CMD_TYPE 0x0000000F
+
+/* see PCI system arch, page 100 for the full list: */
+#define PNX8550_DMA_CTRL_PCI_CMD_READ 0x00000006
+#define PNX8550_DMA_CTRL_PCI_CMD_WRITE 0x00000007
+
+#define PNX8550_DMA_INT_STAT_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_STAT_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_STAT_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_STAT_PERR5 (1<<5)
+#define PNX8550_DMA_INT_STAT_PERR4 (1<<4)
+#define PNX8550_DMA_INT_STAT_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_STAT_T_ABORT (1<<1)
+
+#define PNX8550_DMA_INT_EN_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_EN_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_EN_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_EN_PERR5 (1<<5)
+#define PNX8550_DMA_INT_EN_PERR4 (1<<4)
+#define PNX8550_DMA_INT_EN_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_EN_T_ABORT (1<<1)
+
+#define PNX8550_DMA_INT_CLR_ACK_DONE (1<<14)
+#define PNX8550_DMA_INT_CLR_DMA_DONE (1<<12)
+#define PNX8550_DMA_INT_CLR_DMA_ERR (1<<9)
+#define PNX8550_DMA_INT_CLR_PERR5 (1<<5)
+#define PNX8550_DMA_INT_CLR_PERR4 (1<<4)
+#define PNX8550_DMA_INT_CLR_M_ABORT (1<<2)
+#define PNX8550_DMA_INT_CLR_T_ABORT (1<<1)
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx8550/pci.h b/arch/mips/include/asm/mach-pnx8550/pci.h
new file mode 100644
index 00000000..b921508d
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/pci.h
@@ -0,0 +1,185 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * PCI specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_PCI_H
+#define __PNX8550_PCI_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+#define PCI_CMD_IOR 0x20
+#define PCI_CMD_IOW 0x30
+#define PCI_CMD_CONFIG_READ 0xa0
+#define PCI_CMD_CONFIG_WRITE 0xb0
+
+#define PCI_IO_TIMEOUT 1000
+#define PCI_IO_RETRY 5
+/* Timeout for IO and CFG accesses.
+ This is in 1/1024 th of a jiffie(=10ms)
+ i.e. approx 10us */
+#define PCI_IO_JIFFIES_TIMEOUT 40
+#define PCI_IO_JIFFIES_SHIFT 10
+
+#define PCI_BYTE_ENABLE_MASK 0x0000000f
+#define PCI_CFG_BUS_SHIFT 16
+#define PCI_CFG_FUNC_SHIFT 8
+#define PCI_CFG_REG_SHIFT 2
+
+#define PCI_BASE 0x1be00000
+#define PCI_SETUP 0x00040010
+#define PCI_DIS_REQGNT (1<<30)
+#define PCI_DIS_REQGNTA (1<<29)
+#define PCI_DIS_REQGNTB (1<<28)
+#define PCI_D2_SUPPORT (1<<27)
+#define PCI_D1_SUPPORT (1<<26)
+#define PCI_EN_TA (1<<24)
+#define PCI_EN_PCI2MMI (1<<23)
+#define PCI_EN_XIO (1<<22)
+#define PCI_BASE18_PREF (1<<21)
+#define SIZE_16M 0x3
+#define SIZE_32M 0x4
+#define SIZE_64M 0x5
+#define SIZE_128M 0x6
+#define PCI_SETUP_BASE18_SIZE(X) (X<<18)
+#define PCI_SETUP_BASE18_EN (1<<17)
+#define PCI_SETUP_BASE14_PREF (1<<16)
+#define PCI_SETUP_BASE14_SIZE(X) (X<<12)
+#define PCI_SETUP_BASE14_EN (1<<11)
+#define PCI_SETUP_BASE10_PREF (1<<10)
+#define PCI_SETUP_BASE10_SIZE(X) (X<<7)
+#define PCI_SETUP_CFGMANAGE_EN (1<<1)
+#define PCI_SETUP_PCIARB_EN (1<<0)
+
+#define PCI_CTRL 0x040014
+#define PCI_SWPB_DCS_PCI (1<<16)
+#define PCI_SWPB_PCI_PCI (1<<15)
+#define PCI_SWPB_PCI_DCS (1<<14)
+#define PCI_REG_WR_POST (1<<13)
+#define PCI_XIO_WR_POST (1<<12)
+#define PCI_PCI2_WR_POST (1<<13)
+#define PCI_PCI1_WR_POST (1<<12)
+#define PCI_SERR_SEEN (1<<11)
+#define PCI_B10_SPEC_RD (1<<6)
+#define PCI_B14_SPEC_RD (1<<5)
+#define PCI_B18_SPEC_RD (1<<4)
+#define PCI_B10_NOSUBWORD (1<<3)
+#define PCI_B14_NOSUBWORD (1<<2)
+#define PCI_B18_NOSUBWORD (1<<1)
+#define PCI_RETRY_TMREN (1<<0)
+
+#define PCI_BASE1_LO 0x040018
+#define PCI_BASE1_HI 0x04001C
+#define PCI_BASE2_LO 0x040020
+#define PCI_BASE2_HI 0x040024
+#define PCI_RDLIFETIM 0x040028
+#define PCI_GPPM_ADDR 0x04002C
+#define PCI_GPPM_WDAT 0x040030
+#define PCI_GPPM_RDAT 0x040034
+#define PCI_GPPM_CTRL 0x040038
+#define GPPM_DONE (1<<10)
+#define INIT_PCI_CYCLE (1<<9)
+#define GPPM_CMD(X) (((X)&0xf)<<4)
+#define GPPM_BYTEEN(X) ((X)&0xf)
+#define PCI_UNLOCKREG 0x04003C
+#define UNLOCK_SSID(X) (((X)&0xff)<<8)
+#define UNLOCK_SETUP(X) (((X)&0xff)<<0)
+#define UNLOCK_MAGIC 0xCA
+#define PCI_DEV_VEND_ID 0x040040
+#define DEVICE_ID(X) (((X)>>16)&0xffff)
+#define VENDOR_ID(X) (((X)&0xffff))
+#define PCI_CFG_CMDSTAT 0x040044
+#define PCI_CFG_STATUS(X) (((X)>>16)&0xffff)
+#define PCI_CFG_COMMAND(X) ((X)&0xffff)
+#define PCI_CLASS_REV 0x040048
+#define PCI_CLASSCODE(X) (((X)>>8)&0xffffff)
+#define PCI_REVID(X) ((X)&0xff)
+#define PCI_LAT_TMR 0x04004c
+#define PCI_BASE10 0x040050
+#define PCI_BASE14 0x040054
+#define PCI_BASE18 0x040058
+#define PCI_SUBSYS_ID 0x04006c
+#define PCI_CAP_PTR 0x040074
+#define PCI_CFG_MISC 0x04007c
+#define PCI_PMC 0x040080
+#define PCI_PWR_STATE 0x040084
+#define PCI_IO 0x040088
+#define PCI_SLVTUNING 0x04008C
+#define PCI_DMATUNING 0x040090
+#define PCI_DMAEADDR 0x040800
+#define PCI_DMAIADDR 0x040804
+#define PCI_DMALEN 0x040808
+#define PCI_DMACTRL 0x04080C
+#define PCI_XIOCTRL 0x040810
+#define PCI_SEL0PROF 0x040814
+#define PCI_SEL1PROF 0x040818
+#define PCI_SEL2PROF 0x04081C
+#define PCI_GPXIOADDR 0x040820
+#define PCI_NANDCTRLS 0x400830
+#define PCI_SEL3PROF 0x040834
+#define PCI_SEL4PROF 0x040838
+#define PCI_GPXIO_STAT 0x040FB0
+#define PCI_GPXIO_IMASK 0x040FB4
+#define PCI_GPXIO_ICLR 0x040FB8
+#define PCI_GPXIO_ISET 0x040FBC
+#define PCI_GPPM_STATUS 0x040FC0
+#define GPPM_DONE (1<<10)
+#define GPPM_ERR (1<<9)
+#define GPPM_MPAR_ERR (1<<8)
+#define GPPM_PAR_ERR (1<<7)
+#define GPPM_R_MABORT (1<<2)
+#define GPPM_R_TABORT (1<<1)
+#define PCI_GPPM_IMASK 0x040FC4
+#define PCI_GPPM_ICLR 0x040FC8
+#define PCI_GPPM_ISET 0x040FCC
+#define PCI_DMA_STATUS 0x040FD0
+#define PCI_DMA_IMASK 0x040FD4
+#define PCI_DMA_ICLR 0x040FD8
+#define PCI_DMA_ISET 0x040FDC
+#define PCI_ISTATUS 0x040FE0
+#define PCI_IMASK 0x040FE4
+#define PCI_ICLR 0x040FE8
+#define PCI_ISET 0x040FEC
+#define PCI_MOD_ID 0x040FFC
+
+/*
+ * PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF 0
+#define PCI_CFG_TYPE0_FUNC_SHF 8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF 0
+#define PCI_CFG_TYPE1_FUNC_SHF 8
+#define PCI_CFG_TYPE1_DEV_SHF 11
+#define PCI_CFG_TYPE1_BUS_SHF 16
+
+/*
+ * Ethernet device DP83816 definition
+ */
+#define DP83816_IRQ_ETHER 66
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx8550/uart.h b/arch/mips/include/asm/mach-pnx8550/uart.h
new file mode 100644
index 00000000..ad7608d4
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/uart.h
@@ -0,0 +1,30 @@
+#ifndef __IP3106_UART_H
+#define __IP3106_UART_H
+
+#include <int.h>
+
+/* early macros for kgdb use. fixme: clean this up */
+
+#define UART_BASE 0xbbe4a000 /* PNX8550 */
+
+#define PNX8550_UART_PORT0 (UART_BASE)
+#define PNX8550_UART_PORT1 (UART_BASE + 0x1000)
+
+#define PNX8550_UART_INT(x) (PNX8550_INT_GIC_MIN+19+x)
+#define IRQ_TO_UART(x) (x-PNX8550_INT_GIC_MIN-19)
+
+/* early macros needed for prom/kgdb */
+
+#define ip3106_lcr(base, port) *(volatile u32 *)(base+(port*0x1000) + 0x000)
+#define ip3106_mcr(base, port) *(volatile u32 *)(base+(port*0x1000) + 0x004)
+#define ip3106_baud(base, port) *(volatile u32 *)(base+(port*0x1000) + 0x008)
+#define ip3106_cfg(base, port) *(volatile u32 *)(base+(port*0x1000) + 0x00C)
+#define ip3106_fifo(base, port) *(volatile u32 *)(base+(port*0x1000) + 0x028)
+#define ip3106_istat(base, port) *(volatile u32 *)(base+(port*0x1000) + 0xFE0)
+#define ip3106_ien(base, port) *(volatile u32 *)(base+(port*0x1000) + 0xFE4)
+#define ip3106_iclr(base, port) *(volatile u32 *)(base+(port*0x1000) + 0xFE8)
+#define ip3106_iset(base, port) *(volatile u32 *)(base+(port*0x1000) + 0xFEC)
+#define ip3106_pd(base, port) *(volatile u32 *)(base+(port*0x1000) + 0xFF4)
+#define ip3106_mid(base, port) *(volatile u32 *)(base+(port*0x1000) + 0xFFC)
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx8550/usb.h b/arch/mips/include/asm/mach-pnx8550/usb.h
new file mode 100644
index 00000000..483b7fc6
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/usb.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * USB specific definitions
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef __PNX8550_USB_H
+#define __PNX8550_USB_H
+
+/*
+ * USB Host controller
+ */
+
+#define PNX8550_USB_OHCI_OP_BASE 0x1be48000
+#define PNX8550_USB_OHCI_OP_LEN 0x1000
+
+#endif
diff --git a/arch/mips/include/asm/mach-pnx8550/war.h b/arch/mips/include/asm/mach-pnx8550/war.h
new file mode 100644
index 00000000..d0458dd0
--- /dev/null
+++ b/arch/mips/include/asm/mach-pnx8550/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_PNX8550_WAR_H
+#define __ASM_MIPS_MACH_PNX8550_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_PNX8550_WAR_H */
diff --git a/arch/mips/include/asm/mach-powertv/asic.h b/arch/mips/include/asm/mach-powertv/asic.h
new file mode 100644
index 00000000..c7077a64
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/asic.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ASM_MACH_POWERTV_ASIC_H
+#define _ASM_MACH_POWERTV_ASIC_H
+
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <asm/mach-powertv/asic_regs.h>
+
+#define DVR_CAPABLE (1<<0)
+#define PCIE_CAPABLE (1<<1)
+#define FFS_CAPABLE (1<<2)
+#define DISPLAY_CAPABLE (1<<3)
+
+/* Platform Family types
+ * For compitability, the new value must be added in the end */
+enum family_type {
+ FAMILY_8500,
+ FAMILY_8500RNG,
+ FAMILY_4500,
+ FAMILY_1500,
+ FAMILY_8600,
+ FAMILY_4600,
+ FAMILY_4600VZA,
+ FAMILY_8600VZB,
+ FAMILY_1500VZE,
+ FAMILY_1500VZF,
+ FAMILY_8700,
+ FAMILIES
+};
+
+/* Register maps for each ASIC */
+extern const struct register_map calliope_register_map;
+extern const struct register_map cronus_register_map;
+extern const struct register_map gaia_register_map;
+extern const struct register_map zeus_register_map;
+
+extern struct resource dvr_cronus_resources[];
+extern struct resource dvr_gaia_resources[];
+extern struct resource dvr_zeus_resources[];
+extern struct resource non_dvr_calliope_resources[];
+extern struct resource non_dvr_cronus_resources[];
+extern struct resource non_dvr_cronuslite_resources[];
+extern struct resource non_dvr_gaia_resources[];
+extern struct resource non_dvr_vz_calliope_resources[];
+extern struct resource non_dvr_vze_calliope_resources[];
+extern struct resource non_dvr_vzf_calliope_resources[];
+extern struct resource non_dvr_zeus_resources[];
+
+extern void powertv_platform_init(void);
+extern void platform_alloc_bootmem(void);
+extern enum asic_type platform_get_asic(void);
+extern enum family_type platform_get_family(void);
+extern int platform_supports_dvr(void);
+extern int platform_supports_ffs(void);
+extern int platform_supports_pcie(void);
+extern int platform_supports_display(void);
+extern void configure_platform(void);
+
+/* Platform Resources */
+#define ASIC_RESOURCE_GET_EXISTS 1
+extern struct resource *asic_resource_get(const char *name);
+extern void platform_release_memory(void *baddr, int size);
+
+/* USB configuration */
+struct usb_hcd; /* Forward reference */
+extern void platform_configure_usb_ehci(void);
+extern void platform_unconfigure_usb_ehci(void);
+extern void platform_configure_usb_ohci(void);
+extern void platform_unconfigure_usb_ohci(void);
+
+/* Resource for ASIC registers */
+extern struct resource asic_resource;
+extern int platform_usb_devices_init(struct platform_device **echi_dev,
+ struct platform_device **ohci_dev);
+
+/* Reboot Cause */
+extern void set_reboot_cause(char code, unsigned int data, unsigned int data2);
+extern void set_locked_reboot_cause(char code, unsigned int data,
+ unsigned int data2);
+
+enum sys_reboot_type {
+ sys_unknown_reboot = 0x00, /* Unknown reboot cause */
+ sys_davic_change = 0x01, /* Reboot due to change in DAVIC
+ * mode */
+ sys_user_reboot = 0x02, /* Reboot initiated by user */
+ sys_system_reboot = 0x03, /* Reboot initiated by OS */
+ sys_trap_reboot = 0x04, /* Reboot due to a CPU trap */
+ sys_silent_reboot = 0x05, /* Silent reboot */
+ sys_boot_ldr_reboot = 0x06, /* Bootloader reboot */
+ sys_power_up_reboot = 0x07, /* Power on bootup. Older
+ * drivers may report as
+ * userReboot. */
+ sys_code_change = 0x08, /* Reboot to take code change.
+ * Older drivers may report as
+ * userReboot. */
+ sys_hardware_reset = 0x09, /* HW watchdog or front-panel
+ * reset button reset. Older
+ * drivers may report as
+ * userReboot. */
+ sys_watchdogInterrupt = 0x0A /* Pre-watchdog interrupt */
+};
+
+#endif /* _ASM_MACH_POWERTV_ASIC_H */
diff --git a/arch/mips/include/asm/mach-powertv/asic_reg_map.h b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
new file mode 100644
index 00000000..20348e81
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
@@ -0,0 +1,90 @@
+/*
+ * asic_reg_map.h
+ *
+ * A macro-enclosed list of the elements for the register_map structure for
+ * use in defining and manipulating the structure.
+ *
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+REGISTER_MAP_ELEMENT(eic_slow0_strt_add)
+REGISTER_MAP_ELEMENT(eic_cfg_bits)
+REGISTER_MAP_ELEMENT(eic_ready_status)
+REGISTER_MAP_ELEMENT(chipver3)
+REGISTER_MAP_ELEMENT(chipver2)
+REGISTER_MAP_ELEMENT(chipver1)
+REGISTER_MAP_ELEMENT(chipver0)
+REGISTER_MAP_ELEMENT(uart1_intstat)
+REGISTER_MAP_ELEMENT(uart1_inten)
+REGISTER_MAP_ELEMENT(uart1_config1)
+REGISTER_MAP_ELEMENT(uart1_config2)
+REGISTER_MAP_ELEMENT(uart1_divisorhi)
+REGISTER_MAP_ELEMENT(uart1_divisorlo)
+REGISTER_MAP_ELEMENT(uart1_data)
+REGISTER_MAP_ELEMENT(uart1_status)
+REGISTER_MAP_ELEMENT(int_stat_3)
+REGISTER_MAP_ELEMENT(int_stat_2)
+REGISTER_MAP_ELEMENT(int_stat_1)
+REGISTER_MAP_ELEMENT(int_stat_0)
+REGISTER_MAP_ELEMENT(int_config)
+REGISTER_MAP_ELEMENT(int_int_scan)
+REGISTER_MAP_ELEMENT(ien_int_3)
+REGISTER_MAP_ELEMENT(ien_int_2)
+REGISTER_MAP_ELEMENT(ien_int_1)
+REGISTER_MAP_ELEMENT(ien_int_0)
+REGISTER_MAP_ELEMENT(int_level_3_3)
+REGISTER_MAP_ELEMENT(int_level_3_2)
+REGISTER_MAP_ELEMENT(int_level_3_1)
+REGISTER_MAP_ELEMENT(int_level_3_0)
+REGISTER_MAP_ELEMENT(int_level_2_3)
+REGISTER_MAP_ELEMENT(int_level_2_2)
+REGISTER_MAP_ELEMENT(int_level_2_1)
+REGISTER_MAP_ELEMENT(int_level_2_0)
+REGISTER_MAP_ELEMENT(int_level_1_3)
+REGISTER_MAP_ELEMENT(int_level_1_2)
+REGISTER_MAP_ELEMENT(int_level_1_1)
+REGISTER_MAP_ELEMENT(int_level_1_0)
+REGISTER_MAP_ELEMENT(int_level_0_3)
+REGISTER_MAP_ELEMENT(int_level_0_2)
+REGISTER_MAP_ELEMENT(int_level_0_1)
+REGISTER_MAP_ELEMENT(int_level_0_0)
+REGISTER_MAP_ELEMENT(int_docsis_en)
+REGISTER_MAP_ELEMENT(mips_pll_setup)
+REGISTER_MAP_ELEMENT(fs432x4b4_usb_ctl)
+REGISTER_MAP_ELEMENT(test_bus)
+REGISTER_MAP_ELEMENT(crt_spare)
+REGISTER_MAP_ELEMENT(usb2_ohci_int_mask)
+REGISTER_MAP_ELEMENT(usb2_strap)
+REGISTER_MAP_ELEMENT(ehci_hcapbase)
+REGISTER_MAP_ELEMENT(ohci_hc_revision)
+REGISTER_MAP_ELEMENT(bcm1_bs_lmi_steer)
+REGISTER_MAP_ELEMENT(usb2_control)
+REGISTER_MAP_ELEMENT(usb2_stbus_obc)
+REGISTER_MAP_ELEMENT(usb2_stbus_mess_size)
+REGISTER_MAP_ELEMENT(usb2_stbus_chunk_size)
+REGISTER_MAP_ELEMENT(pcie_regs)
+REGISTER_MAP_ELEMENT(tim_ch)
+REGISTER_MAP_ELEMENT(tim_cl)
+REGISTER_MAP_ELEMENT(gpio_dout)
+REGISTER_MAP_ELEMENT(gpio_din)
+REGISTER_MAP_ELEMENT(gpio_dir)
+REGISTER_MAP_ELEMENT(watchdog)
+REGISTER_MAP_ELEMENT(front_panel)
+REGISTER_MAP_ELEMENT(misc_clk_ctl1)
+REGISTER_MAP_ELEMENT(misc_clk_ctl2)
+REGISTER_MAP_ELEMENT(crt_ext_ctl)
+REGISTER_MAP_ELEMENT(register_maps)
diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h b/arch/mips/include/asm/mach-powertv/asic_regs.h
new file mode 100644
index 00000000..deecb26a
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/asic_regs.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __ASM_MACH_POWERTV_ASIC_H_
+#define __ASM_MACH_POWERTV_ASIC_H_
+#include <linux/io.h>
+
+/* ASIC types */
+enum asic_type {
+ ASIC_UNKNOWN,
+ ASIC_ZEUS,
+ ASIC_CALLIOPE,
+ ASIC_CRONUS,
+ ASIC_CRONUSLITE,
+ ASIC_GAIA,
+ ASICS /* Number of supported ASICs */
+};
+
+/* hardcoded values read from Chip Version registers */
+#define CRONUS_10 0x0B4C1C20
+#define CRONUS_11 0x0B4C1C21
+#define CRONUSLITE_10 0x0B4C1C40
+
+#define NAND_FLASH_BASE 0x03000000
+#define CALLIOPE_IO_BASE 0x08000000
+#define GAIA_IO_BASE 0x09000000
+#define CRONUS_IO_BASE 0x09000000
+#define ZEUS_IO_BASE 0x09000000
+
+#define ASIC_IO_SIZE 0x01000000
+
+/* Definitions for backward compatibility */
+#define UART1_INTSTAT uart1_intstat
+#define UART1_INTEN uart1_inten
+#define UART1_CONFIG1 uart1_config1
+#define UART1_CONFIG2 uart1_config2
+#define UART1_DIVISORHI uart1_divisorhi
+#define UART1_DIVISORLO uart1_divisorlo
+#define UART1_DATA uart1_data
+#define UART1_STATUS uart1_status
+
+/* ASIC register enumeration */
+union register_map_entry {
+ unsigned long phys;
+ u32 *virt;
+};
+
+#define REGISTER_MAP_ELEMENT(x) union register_map_entry x;
+struct register_map {
+#include <asm/mach-powertv/asic_reg_map.h>
+};
+#undef REGISTER_MAP_ELEMENT
+
+/**
+ * register_map_offset_phys - add an offset to the physical address
+ * @map: Pointer to the &struct register_map
+ * @offset: Value to add
+ *
+ * Only adds the base to non-zero physical addresses
+ */
+static inline void register_map_offset_phys(struct register_map *map,
+ unsigned long offset)
+{
+#define REGISTER_MAP_ELEMENT(x) do { \
+ if (map->x.phys != 0) \
+ map->x.phys += offset; \
+ } while (false);
+
+#include <asm/mach-powertv/asic_reg_map.h>
+#undef REGISTER_MAP_ELEMENT
+}
+
+/**
+ * register_map_virtualize - Convert &register_map to virtual addresses
+ * @map: Pointer to &register_map to virtualize
+ */
+static inline void register_map_virtualize(struct register_map *map)
+{
+#define REGISTER_MAP_ELEMENT(x) do { \
+ map->x.virt = (!map->x.phys) ? NULL : \
+ UNCAC_ADDR(phys_to_virt(map->x.phys)); \
+ } while (false);
+
+#include <asm/mach-powertv/asic_reg_map.h>
+#undef REGISTER_MAP_ELEMENT
+}
+
+extern struct register_map _asic_register_map;
+extern unsigned long asic_phy_base;
+
+/*
+ * Macros to interface to registers through their ioremapped address
+ * asic_reg_phys_addr Returns the physical address of the given register
+ * asic_reg_addr Returns the iomapped virtual address of the given
+ * register.
+ */
+#define asic_reg_addr(x) (_asic_register_map.x.virt)
+#define asic_reg_phys_addr(x) (virt_to_phys((void *) CAC_ADDR( \
+ (unsigned long) asic_reg_addr(x))))
+
+/*
+ * The asic_reg macro is gone. It should be replaced by either asic_read or
+ * asic_write, as appropriate.
+ */
+
+#define asic_read(x) readl(asic_reg_addr(x))
+#define asic_write(v, x) writel(v, asic_reg_addr(x))
+
+extern void asic_irq_init(void);
+#endif
diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h
new file mode 100644
index 00000000..a8e72cf1
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h
@@ -0,0 +1,119 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Version from mach-generic modified to support PowerTV port
+ * Portions Copyright (C) 2009 Cisco Systems, Inc.
+ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
+ *
+ */
+
+#ifndef __ASM_MACH_POWERTV_DMA_COHERENCE_H
+#define __ASM_MACH_POWERTV_DMA_COHERENCE_H
+
+#include <linux/sched.h>
+#include <linux/version.h>
+#include <linux/device.h>
+#include <asm/mach-powertv/asic.h>
+
+static inline bool is_kseg2(void *addr)
+{
+ return (unsigned long)addr >= KSEG2;
+}
+
+static inline unsigned long virt_to_phys_from_pte(void *addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *ptep, pte;
+
+ unsigned long virt_addr = (unsigned long)addr;
+ unsigned long phys_addr = 0UL;
+
+ /* get the page global directory. */
+ pgd = pgd_offset_k(virt_addr);
+
+ if (!pgd_none(*pgd)) {
+ /* get the page upper directory */
+ pud = pud_offset(pgd, virt_addr);
+ if (!pud_none(*pud)) {
+ /* get the page middle directory */
+ pmd = pmd_offset(pud, virt_addr);
+ if (!pmd_none(*pmd)) {
+ /* get a pointer to the page table entry */
+ ptep = pte_offset(pmd, virt_addr);
+ pte = *ptep;
+ /* check for a valid page */
+ if (pte_present(pte)) {
+ /* get the physical address the page is
+ * referring to */
+ phys_addr = (unsigned long)
+ page_to_phys(pte_page(pte));
+ /* add the offset within the page */
+ phys_addr |= (virt_addr & ~PAGE_MASK);
+ }
+ }
+ }
+ }
+
+ return phys_addr;
+}
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+ size_t size)
+{
+ if (is_kseg2(addr))
+ return phys_to_dma(virt_to_phys_from_pte(addr));
+ else
+ return phys_to_dma(virt_to_phys(addr));
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ return phys_to_dma(page_to_phys(page));
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return dma_to_phys(dma_addr);
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+ return 0;
+}
+
+#endif /* __ASM_MACH_POWERTV_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-powertv/interrupts.h b/arch/mips/include/asm/mach-powertv/interrupts.h
new file mode 100644
index 00000000..4fd652ce
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/interrupts.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ASM_MACH_POWERTV_INTERRUPTS_H_
+#define _ASM_MACH_POWERTV_INTERRUPTS_H_
+
+/*
+ * Defines for all of the interrupt lines
+ */
+
+/* Definitions for backward compatibility */
+#define kIrq_Uart1 irq_uart1
+
+#define ibase 0
+
+/*------------- Register: int_stat_3 */
+/* 126 unused (bit 31) */
+#define irq_asc2video (ibase+126) /* ASC 2 Video Interrupt */
+#define irq_asc1video (ibase+125) /* ASC 1 Video Interrupt */
+#define irq_comms_block_wd (ibase+124) /* ASC 1 Video Interrupt */
+#define irq_fdma_mailbox (ibase+123) /* FDMA Mailbox Output */
+#define irq_fdma_gp (ibase+122) /* FDMA GP Output */
+#define irq_mips_pic (ibase+121) /* MIPS Performance Counter
+ * Interrupt */
+#define irq_mips_timer (ibase+120) /* MIPS Timer Interrupt */
+#define irq_memory_protect (ibase+119) /* Memory Protection Interrupt
+ * -- Ored by glue logic inside
+ * SPARC ILC (see
+ * INT_MEM_PROT_STAT, below,
+ * for individual interrupts)
+ */
+/* 118 unused (bit 22) */
+#define irq_sbag (ibase+117) /* SBAG Interrupt -- Ored by
+ * glue logic inside SPARC ILC
+ * (see INT_SBAG_STAT, below,
+ * for individual interrupts) */
+#define irq_qam_b_fec (ibase+116) /* QAM B FEC Interrupt */
+#define irq_qam_a_fec (ibase+115) /* QAM A FEC Interrupt */
+/* 114 unused (bit 18) */
+#define irq_mailbox (ibase+113) /* Mailbox Debug Interrupt --
+ * Ored by glue logic inside
+ * SPARC ILC (see
+ * INT_MAILBOX_STAT, below, for
+ * individual interrupts) */
+#define irq_fuse_stat1 (ibase+112) /* Fuse Status 1 */
+#define irq_fuse_stat2 (ibase+111) /* Fuse Status 2 */
+#define irq_fuse_stat3 (ibase+110) /* Blitter Interrupt / Fuse
+ * Status 3 */
+#define irq_blitter (ibase+110) /* Blitter Interrupt / Fuse
+ * Status 3 */
+#define irq_avc1_pp0 (ibase+109) /* AVC Decoder #1 PP0
+ * Interrupt */
+#define irq_avc1_pp1 (ibase+108) /* AVC Decoder #1 PP1
+ * Interrupt */
+#define irq_avc1_mbe (ibase+107) /* AVC Decoder #1 MBE
+ * Interrupt */
+#define irq_avc2_pp0 (ibase+106) /* AVC Decoder #2 PP0
+ * Interrupt */
+#define irq_avc2_pp1 (ibase+105) /* AVC Decoder #2 PP1
+ * Interrupt */
+#define irq_avc2_mbe (ibase+104) /* AVC Decoder #2 MBE
+ * Interrupt */
+#define irq_zbug_spi (ibase+103) /* Zbug SPI Slave Interrupt */
+#define irq_qam_mod2 (ibase+102) /* QAM Modulator 2 DMA
+ * Interrupt */
+#define irq_ir_rx (ibase+101) /* IR RX 2 Interrupt */
+#define irq_aud_dsp2 (ibase+100) /* Audio DSP #2 Interrupt */
+#define irq_aud_dsp1 (ibase+99) /* Audio DSP #1 Interrupt */
+#define irq_docsis (ibase+98) /* DOCSIS Debug Interrupt */
+#define irq_sd_dvp1 (ibase+97) /* SD DVP #1 Interrupt */
+#define irq_sd_dvp2 (ibase+96) /* SD DVP #2 Interrupt */
+/*------------- Register: int_stat_2 */
+#define irq_hd_dvp (ibase+95) /* HD DVP Interrupt */
+#define kIrq_Prewatchdog (ibase+94) /* watchdog Pre-Interrupt */
+#define irq_timer2 (ibase+93) /* Programmable Timer
+ * Interrupt 2 */
+#define irq_1394 (ibase+92) /* 1394 Firewire Interrupt */
+#define irq_usbohci (ibase+91) /* USB 2.0 OHCI Interrupt */
+#define irq_usbehci (ibase+90) /* USB 2.0 EHCI Interrupt */
+#define irq_pciexp (ibase+89) /* PCI Express 0 Interrupt */
+#define irq_pciexp0 (ibase+89) /* PCI Express 0 Interrupt */
+#define irq_afe1 (ibase+88) /* AFE 1 Interrupt */
+#define irq_sata (ibase+87) /* SATA 1 Interrupt */
+#define irq_sata1 (ibase+87) /* SATA 1 Interrupt */
+#define irq_dtcp (ibase+86) /* DTCP Interrupt */
+#define irq_pciexp1 (ibase+85) /* PCI Express 1 Interrupt */
+/* 84 unused (bit 20) */
+/* 83 unused (bit 19) */
+/* 82 unused (bit 18) */
+#define irq_sata2 (ibase+81) /* SATA2 Interrupt */
+#define irq_uart2 (ibase+80) /* UART2 Interrupt */
+#define irq_legacy_usb (ibase+79) /* Legacy USB Host ISR (1.1
+ * Host module) */
+#define irq_pod (ibase+78) /* POD Interrupt */
+#define irq_slave_usb (ibase+77) /* Slave USB */
+#define irq_denc1 (ibase+76) /* DENC #1 VTG Interrupt */
+#define irq_vbi_vtg (ibase+75) /* VBI VTG Interrupt */
+#define irq_afe2 (ibase+74) /* AFE 2 Interrupt */
+#define irq_denc2 (ibase+73) /* DENC #2 VTG Interrupt */
+#define irq_asc2 (ibase+72) /* ASC #2 Interrupt */
+#define irq_asc1 (ibase+71) /* ASC #1 Interrupt */
+#define irq_mod_dma (ibase+70) /* Modulator DMA Interrupt */
+#define irq_byte_eng1 (ibase+69) /* Byte Engine Interrupt [1] */
+#define irq_byte_eng0 (ibase+68) /* Byte Engine Interrupt [0] */
+/* 67 unused (bit 03) */
+/* 66 unused (bit 02) */
+/* 65 unused (bit 01) */
+/* 64 unused (bit 00) */
+/*------------- Register: int_stat_1 */
+/* 63 unused (bit 31) */
+/* 62 unused (bit 30) */
+/* 61 unused (bit 29) */
+/* 60 unused (bit 28) */
+/* 59 unused (bit 27) */
+/* 58 unused (bit 26) */
+/* 57 unused (bit 25) */
+/* 56 unused (bit 24) */
+#define irq_buf_dma_mem2mem (ibase+55) /* BufDMA Memory to Memory
+ * Interrupt */
+#define irq_buf_dma_usbtransmit (ibase+54) /* BufDMA USB Transmit
+ * Interrupt */
+#define irq_buf_dma_qpskpodtransmit (ibase+53) /* BufDMA QPSK/POD Tramsit
+ * Interrupt */
+#define irq_buf_dma_transmit_error (ibase+52) /* BufDMA Transmit Error
+ * Interrupt */
+#define irq_buf_dma_usbrecv (ibase+51) /* BufDMA USB Receive
+ * Interrupt */
+#define irq_buf_dma_qpskpodrecv (ibase+50) /* BufDMA QPSK/POD Receive
+ * Interrupt */
+#define irq_buf_dma_recv_error (ibase+49) /* BufDMA Receive Error
+ * Interrupt */
+#define irq_qamdma_transmit_play (ibase+48) /* QAMDMA Transmit/Play
+ * Interrupt */
+#define irq_qamdma_transmit_error (ibase+47) /* QAMDMA Transmit Error
+ * Interrupt */
+#define irq_qamdma_recv2high (ibase+46) /* QAMDMA Receive 2 High
+ * (Chans 63-32) */
+#define irq_qamdma_recv2low (ibase+45) /* QAMDMA Receive 2 Low
+ * (Chans 31-0) */
+#define irq_qamdma_recv1high (ibase+44) /* QAMDMA Receive 1 High
+ * (Chans 63-32) */
+#define irq_qamdma_recv1low (ibase+43) /* QAMDMA Receive 1 Low
+ * (Chans 31-0) */
+#define irq_qamdma_recv_error (ibase+42) /* QAMDMA Receive Error
+ * Interrupt */
+#define irq_mpegsplice (ibase+41) /* MPEG Splice Interrupt */
+#define irq_deinterlace_rdy (ibase+40) /* Deinterlacer Frame Ready
+ * Interrupt */
+#define irq_ext_in0 (ibase+39) /* External Interrupt irq_in0 */
+#define irq_gpio3 (ibase+38) /* GP I/O IRQ 3 - From GP I/O
+ * Module */
+#define irq_gpio2 (ibase+37) /* GP I/O IRQ 2 - From GP I/O
+ * Module (ABE_intN) */
+#define irq_pcrcmplt1 (ibase+36) /* PCR Capture Complete or
+ * Discontinuity 1 */
+#define irq_pcrcmplt2 (ibase+35) /* PCR Capture Complete or
+ * Discontinuity 2 */
+#define irq_parse_peierr (ibase+34) /* PID Parser Error Detect
+ * (PEI) */
+#define irq_parse_cont_err (ibase+33) /* PID Parser continuity error
+ * detect */
+#define irq_ds1framer (ibase+32) /* DS1 Framer Interrupt */
+/*------------- Register: int_stat_0 */
+#define irq_gpio1 (ibase+31) /* GP I/O IRQ 1 - From GP I/O
+ * Module */
+#define irq_gpio0 (ibase+30) /* GP I/O IRQ 0 - From GP I/O
+ * Module */
+#define irq_qpsk_out_aloha (ibase+29) /* QPSK Output Slotted Aloha
+ * (chan 3) Transmission
+ * Completed OK */
+#define irq_qpsk_out_tdma (ibase+28) /* QPSK Output TDMA (chan 2)
+ * Transmission Completed OK */
+#define irq_qpsk_out_reserve (ibase+27) /* QPSK Output Reservation
+ * (chan 1) Transmission
+ * Completed OK */
+#define irq_qpsk_out_aloha_err (ibase+26) /* QPSK Output Slotted Aloha
+ * (chan 3)Transmission
+ * completed with Errors. */
+#define irq_qpsk_out_tdma_err (ibase+25) /* QPSK Output TDMA (chan 2)
+ * Transmission completed with
+ * Errors. */
+#define irq_qpsk_out_rsrv_err (ibase+24) /* QPSK Output Reservation
+ * (chan 1) Transmission
+ * completed with Errors */
+#define irq_aloha_fail (ibase+23) /* Unsuccessful Resend of Aloha
+ * for N times. Aloha retry
+ * timeout for channel 3. */
+#define irq_timer1 (ibase+22) /* Programmable Timer
+ * Interrupt */
+#define irq_keyboard (ibase+21) /* Keyboard Module Interrupt */
+#define irq_i2c (ibase+20) /* I2C Module Interrupt */
+#define irq_spi (ibase+19) /* SPI Module Interrupt */
+#define irq_irblaster (ibase+18) /* IR Blaster Interrupt */
+#define irq_splice_detect (ibase+17) /* PID Key Change Interrupt or
+ * Splice Detect Interrupt */
+#define irq_se_micro (ibase+16) /* Secure Micro I/F Module
+ * Interrupt */
+#define irq_uart1 (ibase+15) /* UART Interrupt */
+#define irq_irrecv (ibase+14) /* IR Receiver Interrupt */
+#define irq_host_int1 (ibase+13) /* Host-to-Host Interrupt 1 */
+#define irq_host_int0 (ibase+12) /* Host-to-Host Interrupt 0 */
+#define irq_qpsk_hecerr (ibase+11) /* QPSK HEC Error Interrupt */
+#define irq_qpsk_crcerr (ibase+10) /* QPSK AAL-5 CRC Error
+ * Interrupt */
+/* 9 unused (bit 09) */
+/* 8 unused (bit 08) */
+#define irq_psicrcerr (ibase+7) /* QAM PSI CRC Error
+ * Interrupt */
+#define irq_psilength_err (ibase+6) /* QAM PSI Length Error
+ * Interrupt */
+#define irq_esfforward (ibase+5) /* ESF Interrupt Mark From
+ * Forward Path Reference -
+ * every 3ms when forward Mbits
+ * and forward slot control
+ * bytes are updated. */
+#define irq_esfreverse (ibase+4) /* ESF Interrupt Mark from
+ * Reverse Path Reference -
+ * delayed from forward mark by
+ * the ranging delay plus a
+ * fixed amount. When reverse
+ * Mbits and reverse slot
+ * control bytes are updated.
+ * Occurs every 3ms for 3.0M and
+ * 1.554 M upstream rates and
+ * every 6 ms for 256K upstream
+ * rate. */
+#define irq_aloha_timeout (ibase+3) /* Slotted-Aloha timeout on
+ * Channel 1. */
+#define irq_reservation (ibase+2) /* Partial (or Incremental)
+ * Reservation Message Completed
+ * or Slotted aloha verify for
+ * channel 1. */
+#define irq_aloha3 (ibase+1) /* Slotted-Aloha Message Verify
+ * Interrupt or Reservation
+ * increment completed for
+ * channel 3. */
+#define irq_mpeg_d (ibase+0) /* MPEG Decoder Interrupt */
+#endif /* _ASM_MACH_POWERTV_INTERRUPTS_H_ */
diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h
new file mode 100644
index 00000000..c86ef094
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/ioremap.h
@@ -0,0 +1,167 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Portions Copyright (C) Cisco Systems, Inc.
+ */
+#ifndef __ASM_MACH_POWERTV_IOREMAP_H
+#define __ASM_MACH_POWERTV_IOREMAP_H
+
+#include <linux/types.h>
+#include <linux/log2.h>
+#include <linux/compiler.h>
+
+#include <asm/pgtable-bits.h>
+#include <asm/addrspace.h>
+
+/* We're going to mess with bits, so get sizes */
+#define IOR_BPC 8 /* Bits per char */
+#define IOR_PHYS_BITS (IOR_BPC * sizeof(phys_addr_t))
+#define IOR_DMA_BITS (IOR_BPC * sizeof(dma_addr_t))
+
+/*
+ * Define the granularity of physical/DMA mapping in terms of the number
+ * of bits that defines the offset within a grain. These will be the
+ * least significant bits of the address. The rest of a physical or DMA
+ * address will be used to index into an appropriate table to find the
+ * offset to add to the address to yield the corresponding DMA or physical
+ * address, respectively.
+ */
+#define IOR_LSBITS 22 /* Bits in a grain */
+
+/*
+ * Compute the number of most significant address bits after removing those
+ * used for the offset within a grain and then compute the number of table
+ * entries for the conversion.
+ */
+#define IOR_PHYS_MSBITS (IOR_PHYS_BITS - IOR_LSBITS)
+#define IOR_NUM_PHYS_TO_DMA ((phys_addr_t) 1 << IOR_PHYS_MSBITS)
+
+#define IOR_DMA_MSBITS (IOR_DMA_BITS - IOR_LSBITS)
+#define IOR_NUM_DMA_TO_PHYS ((dma_addr_t) 1 << IOR_DMA_MSBITS)
+
+/*
+ * Define data structures used as elements in the arrays for the conversion
+ * between physical and DMA addresses. We do some slightly fancy math to
+ * compute the width of the offset element of the conversion tables so
+ * that we can have the smallest conversion tables. Next, round up the
+ * sizes to the next higher power of two, i.e. the offset element will have
+ * 8, 16, 32, 64, etc. bits. This eliminates the need to mask off any
+ * bits. Finally, we compute a shift value that puts the most significant
+ * bits of the offset into the most significant bits of the offset element.
+ * This makes it more efficient on processors without barrel shifters and
+ * easier to see the values if the conversion table is dumped in binary.
+ */
+#define _IOR_OFFSET_WIDTH(n) (1 << order_base_2(n))
+#define IOR_OFFSET_WIDTH(n) \
+ (_IOR_OFFSET_WIDTH(n) < 8 ? 8 : _IOR_OFFSET_WIDTH(n))
+
+#define IOR_PHYS_OFFSET_BITS IOR_OFFSET_WIDTH(IOR_PHYS_MSBITS)
+#define IOR_PHYS_SHIFT (IOR_PHYS_BITS - IOR_PHYS_OFFSET_BITS)
+
+#define IOR_DMA_OFFSET_BITS IOR_OFFSET_WIDTH(IOR_DMA_MSBITS)
+#define IOR_DMA_SHIFT (IOR_DMA_BITS - IOR_DMA_OFFSET_BITS)
+
+struct ior_phys_to_dma {
+ dma_addr_t offset:IOR_DMA_OFFSET_BITS __packed
+ __aligned((IOR_DMA_OFFSET_BITS / IOR_BPC));
+};
+
+struct ior_dma_to_phys {
+ dma_addr_t offset:IOR_PHYS_OFFSET_BITS __packed
+ __aligned((IOR_PHYS_OFFSET_BITS / IOR_BPC));
+};
+
+extern struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
+extern struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
+
+static inline dma_addr_t _phys_to_dma_offset_raw(phys_addr_t phys)
+{
+ return (dma_addr_t)_ior_phys_to_dma[phys >> IOR_LSBITS].offset;
+}
+
+static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma)
+{
+ return (dma_addr_t)_ior_dma_to_phys[dma >> IOR_LSBITS].offset;
+}
+
+/* These are not portable and should not be used in drivers. Drivers should
+ * be using ioremap() and friends to map physical addresses to virtual
+ * addresses and dma_map*() and friends to map virtual addresses into DMA
+ * addresses and back.
+ */
+static inline dma_addr_t phys_to_dma(phys_addr_t phys)
+{
+ return phys + (_phys_to_dma_offset_raw(phys) << IOR_PHYS_SHIFT);
+}
+
+static inline phys_addr_t dma_to_phys(dma_addr_t dma)
+{
+ return dma + (_dma_to_phys_offset_raw(dma) << IOR_DMA_SHIFT);
+}
+
+extern void ioremap_add_map(dma_addr_t phys, phys_addr_t alias,
+ dma_addr_t size);
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+
+/*
+ * Handle the special case of addresses the area aliased into the first
+ * 512 MiB of the processor's physical address space. These turn into either
+ * kseg0 or kseg1 addresses, depending on flags.
+ */
+static inline void __iomem *plat_ioremap(phys_t start, unsigned long size,
+ unsigned long flags)
+{
+ phys_addr_t start_offset;
+ void __iomem *result = NULL;
+
+ /* Start by checking to see whether this is an aliased address */
+ start_offset = _dma_to_phys_offset_raw(start);
+
+ /*
+ * If:
+ * o the memory is aliased into the first 512 MiB, and
+ * o the start and end are in the same RAM bank, and
+ * o we don't have a zero size or wrap around, and
+ * o we are supposed to create an uncached mapping,
+ * handle this is a kseg0 or kseg1 address
+ */
+ if (start_offset != 0) {
+ phys_addr_t last;
+ dma_addr_t dma_to_phys_offset;
+
+ last = start + size - 1;
+ dma_to_phys_offset =
+ _dma_to_phys_offset_raw(last) << IOR_DMA_SHIFT;
+
+ if (dma_to_phys_offset == start_offset &&
+ size != 0 && start <= last) {
+ phys_t adjusted_start;
+ adjusted_start = start + start_offset;
+ if (flags == _CACHE_UNCACHED)
+ result = (void __iomem *) (unsigned long)
+ CKSEG1ADDR(adjusted_start);
+ else
+ result = (void __iomem *) (unsigned long)
+ CKSEG0ADDR(adjusted_start);
+ }
+ }
+
+ return result;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+ return 0;
+}
+#endif /* __ASM_MACH_POWERTV_IOREMAP_H */
diff --git a/arch/mips/include/asm/mach-powertv/irq.h b/arch/mips/include/asm/mach-powertv/irq.h
new file mode 100644
index 00000000..4bd5d0c6
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/irq.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ASM_MACH_POWERTV_IRQ_H
+#define _ASM_MACH_POWERTV_IRQ_H
+#include <asm/mach-powertv/interrupts.h>
+
+#define MIPS_CPU_IRQ_BASE ibase
+#define NR_IRQS 127
+#endif
diff --git a/arch/mips/include/asm/mach-powertv/powertv-clock.h b/arch/mips/include/asm/mach-powertv/powertv-clock.h
new file mode 100644
index 00000000..6f3e9a0f
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/powertv-clock.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+/*
+ * Local definitions for the powertv PCI code
+ */
+
+#ifndef _POWERTV_PCI_POWERTV_PCI_H_
+#define _POWERTV_PCI_POWERTV_PCI_H_
+extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+extern int asic_pcie_init(void);
+extern int asic_pcie_init(void);
+
+extern int log_level;
+#endif
diff --git a/arch/mips/include/asm/mach-powertv/war.h b/arch/mips/include/asm/mach-powertv/war.h
new file mode 100644
index 00000000..7ac05ecc
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/war.h
@@ -0,0 +1,28 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This version for the PowerTV platform copied from the Malta version.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ */
+#ifndef __ASM_MACH_POWERTV_WAR_H
+#define __ASM_MACH_POWERTV_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 1
+#define MIPS_CACHE_SYNC_WAR 1
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MACH_POWERTV_WAR_H */
diff --git a/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h b/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
new file mode 100644
index 00000000..c3e4d3a4
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
@@ -0,0 +1,76 @@
+/*
+ * IDT RC32434 specific CPU feature overrides
+ *
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ *
+ * This file was derived from: include/asm-mips/cpu-features.h
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef __ASM_MACH_RC32434_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_RC32434_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * The IDT RC32434 SOC has a built-in MIPS 4Kc core.
+ */
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_sb1_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+
+#define cpu_has_vtag_icache 0
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+
+/* #define cpu_has_nofpuex ? */
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_64bit_gp_regs 0
+#define cpu_has_64bit_addresses 0
+
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_dcache_line_size() 16
+#define cpu_icache_line_size() 16
+
+#endif /* __ASM_MACH_RC32434_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-rc32434/ddr.h b/arch/mips/include/asm/mach-rc32434/ddr.h
new file mode 100644
index 00000000..291e2cf9
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/ddr.h
@@ -0,0 +1,141 @@
+/*
+ * Definitions for the DDR registers
+ *
+ * Copyright 2002 Ryan Holm <ryan.holmQVist@idt.com>
+ * Copyright 2008 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _ASM_RC32434_DDR_H_
+#define _ASM_RC32434_DDR_H_
+
+#include <asm/mach-rc32434/rb.h>
+
+/* DDR register structure */
+struct ddr_ram {
+ u32 ddrbase;
+ u32 ddrmask;
+ u32 res1;
+ u32 res2;
+ u32 ddrc;
+ u32 ddrabase;
+ u32 ddramask;
+ u32 ddramap;
+ u32 ddrcust;
+ u32 ddrrdc;
+ u32 ddrspare;
+};
+
+#define DDR0_PHYS_ADDR 0x18018000
+
+/* DDR banks masks */
+#define DDR_MASK 0xffff0000
+#define DDR0_BASE_MSK DDR_MASK
+#define DDR1_BASE_MSK DDR_MASK
+
+/* DDR bank0 registers */
+#define RC32434_DDR0_ATA_BIT 5
+#define RC32434_DDR0_ATA_MSK 0x000000E0
+#define RC32434_DDR0_DBW_BIT 8
+#define RC32434_DDR0_DBW_MSK 0x00000100
+#define RC32434_DDR0_WR_BIT 9
+#define RC32434_DDR0_WR_MSK 0x00000600
+#define RC32434_DDR0_PS_BIT 11
+#define RC32434_DDR0_PS_MSK 0x00001800
+#define RC32434_DDR0_DTYPE_BIT 13
+#define RC32434_DDR0_DTYPE_MSK 0x0000e000
+#define RC32434_DDR0_RFC_BIT 16
+#define RC32434_DDR0_RFC_MSK 0x000f0000
+#define RC32434_DDR0_RP_BIT 20
+#define RC32434_DDR0_RP_MSK 0x00300000
+#define RC32434_DDR0_AP_BIT 22
+#define RC32434_DDR0_AP_MSK 0x00400000
+#define RC32434_DDR0_RCD_BIT 23
+#define RC32434_DDR0_RCD_MSK 0x01800000
+#define RC32434_DDR0_CL_BIT 25
+#define RC32434_DDR0_CL_MSK 0x06000000
+#define RC32434_DDR0_DBM_BIT 27
+#define RC32434_DDR0_DBM_MSK 0x08000000
+#define RC32434_DDR0_SDS_BIT 28
+#define RC32434_DDR0_SDS_MSK 0x10000000
+#define RC32434_DDR0_ATP_BIT 29
+#define RC32434_DDR0_ATP_MSK 0x60000000
+#define RC32434_DDR0_RE_BIT 31
+#define RC32434_DDR0_RE_MSK 0x80000000
+
+/* DDR bank C registers */
+#define RC32434_DDRC_MSK(x) BIT_TO_MASK(x)
+#define RC32434_DDRC_CES_BIT 0
+#define RC32434_DDRC_ACE_BIT 1
+
+/* Custom DDR bank registers */
+#define RC32434_DCST_MSK(x) BIT_TO_MASK(x)
+#define RC32434_DCST_CS_BIT 0
+#define RC32434_DCST_CS_MSK 0x00000003
+#define RC32434_DCST_WE_BIT 2
+#define RC32434_DCST_RAS_BIT 3
+#define RC32434_DCST_CAS_BIT 4
+#define RC32434_DSCT_CKE_BIT 5
+#define RC32434_DSCT_BA_BIT 6
+#define RC32434_DSCT_BA_MSK 0x000000c0
+
+/* DDR QSC registers */
+#define RC32434_QSC_DM_BIT 0
+#define RC32434_QSC_DM_MSK 0x00000003
+#define RC32434_QSC_DQSBS_BIT 2
+#define RC32434_QSC_DQSBS_MSK 0x000000fc
+#define RC32434_QSC_DB_BIT 8
+#define RC32434_QSC_DB_MSK 0x00000100
+#define RC32434_QSC_DBSP_BIT 9
+#define RC32434_QSC_DBSP_MSK 0x01fffe00
+#define RC32434_QSC_BDP_BIT 25
+#define RC32434_QSC_BDP_MSK 0x7e000000
+
+/* DDR LLC registers */
+#define RC32434_LLC_EAO_BIT 0
+#define RC32434_LLC_EAO_MSK 0x00000001
+#define RC32434_LLC_EO_BIT 1
+#define RC32434_LLC_EO_MSK 0x0000003e
+#define RC32434_LLC_FS_BIT 6
+#define RC32434_LLC_FS_MSK 0x000000c0
+#define RC32434_LLC_AS_BIT 8
+#define RC32434_LLC_AS_MSK 0x00000700
+#define RC32434_LLC_SP_BIT 11
+#define RC32434_LLC_SP_MSK 0x001ff800
+
+/* DDR LLFC registers */
+#define RC32434_LLFC_MSK(x) BIT_TO_MASK(x)
+#define RC32434_LLFC_MEN_BIT 0
+#define RC32434_LLFC_EAN_BIT 1
+#define RC32434_LLFC_FF_BIT 2
+
+/* DDR DLLTA registers */
+#define RC32434_DLLTA_ADDR_BIT 2
+#define RC32434_DLLTA_ADDR_MSK 0xfffffffc
+
+/* DDR DLLED registers */
+#define RC32434_DLLED_MSK(x) BIT_TO_MASK(x)
+#define RC32434_DLLED_DBE_BIT 0
+#define RC32434_DLLED_DTE_BIT 1
+
+#endif /* _ASM_RC32434_DDR_H_ */
diff --git a/arch/mips/include/asm/mach-rc32434/dma.h b/arch/mips/include/asm/mach-rc32434/dma.h
new file mode 100644
index 00000000..5f898b58
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/dma.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2002 Integrated Device Technology, Inc.
+ * All rights reserved.
+ *
+ * DMA register definition.
+ *
+ * Author : ryan.holmQVist@idt.com
+ * Date : 20011005
+ */
+
+#ifndef __ASM_RC32434_DMA_H
+#define __ASM_RC32434_DMA_H
+
+#include <asm/mach-rc32434/rb.h>
+
+#define DMA0_BASE_ADDR 0x18040000
+
+/*
+ * DMA descriptor (in physical memory).
+ */
+
+struct dma_desc {
+ u32 control; /* Control. use DMAD_* */
+ u32 ca; /* Current Address. */
+ u32 devcs; /* Device control and status. */
+ u32 link; /* Next descriptor in chain. */
+};
+
+#define DMA_DESC_SIZ sizeof(struct dma_desc)
+#define DMA_DESC_COUNT_BIT 0
+#define DMA_DESC_COUNT_MSK 0x0003ffff
+#define DMA_DESC_DS_BIT 20
+#define DMA_DESC_DS_MSK 0x00300000
+
+#define DMA_DESC_DEV_CMD_BIT 22
+#define DMA_DESC_DEV_CMD_MSK 0x01c00000
+
+/* DMA command sizes */
+#define DMA_DESC_DEV_CMD_BYTE 0
+#define DMA_DESC_DEV_CMD_HLF_WD 1
+#define DMA_DESC_DEV_CMD_WORD 2
+#define DMA_DESC_DEV_CMD_2WORDS 3
+#define DMA_DESC_DEV_CMD_4WORDS 4
+#define DMA_DESC_DEV_CMD_6WORDS 5
+#define DMA_DESC_DEV_CMD_8WORDS 6
+#define DMA_DESC_DEV_CMD_16WORDS 7
+
+/* DMA descriptors interrupts */
+#define DMA_DESC_COF (1 << 25) /* Chain on finished */
+#define DMA_DESC_COD (1 << 26) /* Chain on done */
+#define DMA_DESC_IOF (1 << 27) /* Interrupt on finished */
+#define DMA_DESC_IOD (1 << 28) /* Interrupt on done */
+#define DMA_DESC_TERM (1 << 29) /* Terminated */
+#define DMA_DESC_DONE (1 << 30) /* Done */
+#define DMA_DESC_FINI (1 << 31) /* Finished */
+
+/*
+ * DMA register (within Internal Register Map).
+ */
+
+struct dma_reg {
+ u32 dmac; /* Control. */
+ u32 dmas; /* Status. */
+ u32 dmasm; /* Mask. */
+ u32 dmadptr; /* Descriptor pointer. */
+ u32 dmandptr; /* Next descriptor pointer. */
+};
+
+/* DMA channels specific registers */
+#define DMA_CHAN_RUN_BIT (1 << 0)
+#define DMA_CHAN_DONE_BIT (1 << 1)
+#define DMA_CHAN_MODE_BIT (1 << 2)
+#define DMA_CHAN_MODE_MSK 0x0000000c
+#define DMA_CHAN_MODE_AUTO 0
+#define DMA_CHAN_MODE_BURST 1
+#define DMA_CHAN_MODE_XFRT 2
+#define DMA_CHAN_MODE_RSVD 3
+#define DMA_CHAN_ACT_BIT (1 << 4)
+
+/* DMA status registers */
+#define DMA_STAT_FINI (1 << 0)
+#define DMA_STAT_DONE (1 << 1)
+#define DMA_STAT_CHAIN (1 << 2)
+#define DMA_STAT_ERR (1 << 3)
+#define DMA_STAT_HALT (1 << 4)
+
+/*
+ * DMA channel definitions
+ */
+
+#define DMA_CHAN_ETH_RCV 0
+#define DMA_CHAN_ETH_XMT 1
+#define DMA_CHAN_MEM_TO_FIFO 2
+#define DMA_CHAN_FIFO_TO_MEM 3
+#define DMA_CHAN_PCI_TO_MEM 4
+#define DMA_CHAN_MEM_TO_PCI 5
+#define DMA_CHAN_COUNT 6
+
+struct dma_channel {
+ struct dma_reg ch[DMA_CHAN_COUNT];
+};
+
+#endif /* __ASM_RC32434_DMA_H */
diff --git a/arch/mips/include/asm/mach-rc32434/dma_v.h b/arch/mips/include/asm/mach-rc32434/dma_v.h
new file mode 100644
index 00000000..173a9f91
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/dma_v.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2002 Integrated Device Technology, Inc.
+ * All rights reserved.
+ *
+ * DMA register definition.
+ *
+ * Author : ryan.holmQVist@idt.com
+ * Date : 20011005
+ */
+
+#ifndef _ASM_RC32434_DMA_V_H_
+#define _ASM_RC32434_DMA_V_H_
+
+#include <asm/mach-rc32434/dma.h>
+#include <asm/mach-rc32434/rc32434.h>
+
+#define DMA_CHAN_OFFSET 0x14
+#define IS_DMA_USED(X) (((X) & \
+ (DMA_DESC_FINI | DMA_DESC_DONE | DMA_DESC_TERM)) \
+ != 0)
+#define DMA_COUNT(count) ((count) & DMA_DESC_COUNT_MSK)
+
+#define DMA_HALT_TIMEOUT 500
+
+static inline int rc32434_halt_dma(struct dma_reg *ch)
+{
+ int timeout = 1;
+ if (__raw_readl(&ch->dmac) & DMA_CHAN_RUN_BIT) {
+ __raw_writel(0, &ch->dmac);
+ for (timeout = DMA_HALT_TIMEOUT; timeout > 0; timeout--) {
+ if (__raw_readl(&ch->dmas) & DMA_STAT_HALT) {
+ __raw_writel(0, &ch->dmas);
+ break;
+ }
+ }
+ }
+
+ return timeout ? 0 : 1;
+}
+
+static inline void rc32434_start_dma(struct dma_reg *ch, u32 dma_addr)
+{
+ __raw_writel(0, &ch->dmandptr);
+ __raw_writel(dma_addr, &ch->dmadptr);
+}
+
+static inline void rc32434_chain_dma(struct dma_reg *ch, u32 dma_addr)
+{
+ __raw_writel(dma_addr, &ch->dmandptr);
+}
+
+#endif /* _ASM_RC32434_DMA_V_H_ */
diff --git a/arch/mips/include/asm/mach-rc32434/eth.h b/arch/mips/include/asm/mach-rc32434/eth.h
new file mode 100644
index 00000000..a25cbc56
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/eth.h
@@ -0,0 +1,220 @@
+/*
+ * Definitions for the Ethernet registers
+ *
+ * Copyright 2002 Allend Stichter <allen.stichter@idt.com>
+ * Copyright 2008 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_RC32434_ETH_H
+#define __ASM_RC32434_ETH_H
+
+
+#define ETH0_BASE_ADDR 0x18060000
+
+struct eth_regs {
+ u32 ethintfc;
+ u32 ethfifott;
+ u32 etharc;
+ u32 ethhash0;
+ u32 ethhash1;
+ u32 ethu0[4]; /* Reserved. */
+ u32 ethpfs;
+ u32 ethmcp;
+ u32 eth_u1[10]; /* Reserved. */
+ u32 ethspare;
+ u32 eth_u2[42]; /* Reserved. */
+ u32 ethsal0;
+ u32 ethsah0;
+ u32 ethsal1;
+ u32 ethsah1;
+ u32 ethsal2;
+ u32 ethsah2;
+ u32 ethsal3;
+ u32 ethsah3;
+ u32 ethrbc;
+ u32 ethrpc;
+ u32 ethrupc;
+ u32 ethrfc;
+ u32 ethtbc;
+ u32 ethgpf;
+ u32 eth_u9[50]; /* Reserved. */
+ u32 ethmac1;
+ u32 ethmac2;
+ u32 ethipgt;
+ u32 ethipgr;
+ u32 ethclrt;
+ u32 ethmaxf;
+ u32 eth_u10; /* Reserved. */
+ u32 ethmtest;
+ u32 miimcfg;
+ u32 miimcmd;
+ u32 miimaddr;
+ u32 miimwtd;
+ u32 miimrdd;
+ u32 miimind;
+ u32 eth_u11; /* Reserved. */
+ u32 eth_u12; /* Reserved. */
+ u32 ethcfsa0;
+ u32 ethcfsa1;
+ u32 ethcfsa2;
+};
+
+/* Ethernet interrupt registers */
+#define ETH_INT_FC_EN (1 << 0)
+#define ETH_INT_FC_ITS (1 << 1)
+#define ETH_INT_FC_RIP (1 << 2)
+#define ETH_INT_FC_JAM (1 << 3)
+#define ETH_INT_FC_OVR (1 << 4)
+#define ETH_INT_FC_UND (1 << 5)
+#define ETH_INT_FC_IOC 0x000000c0
+
+/* Ethernet FIFO registers */
+#define ETH_FIFI_TT_TTH_BIT 0
+#define ETH_FIFO_TT_TTH 0x0000007f
+
+/* Ethernet ARC/multicast registers */
+#define ETH_ARC_PRO (1 << 0)
+#define ETH_ARC_AM (1 << 1)
+#define ETH_ARC_AFM (1 << 2)
+#define ETH_ARC_AB (1 << 3)
+
+/* Ethernet SAL registers */
+#define ETH_SAL_BYTE_5 0x000000ff
+#define ETH_SAL_BYTE_4 0x0000ff00
+#define ETH_SAL_BYTE_3 0x00ff0000
+#define ETH_SAL_BYTE_2 0xff000000
+
+/* Ethernet SAH registers */
+#define ETH_SAH_BYTE1 0x000000ff
+#define ETH_SAH_BYTE0 0x0000ff00
+
+/* Ethernet GPF register */
+#define ETH_GPF_PTV 0x0000ffff
+
+/* Ethernet PFG register */
+#define ETH_PFS_PFD (1 << 0)
+
+/* Ethernet CFSA[0-3] registers */
+#define ETH_CFSA0_CFSA4 0x000000ff
+#define ETH_CFSA0_CFSA5 0x0000ff00
+#define ETH_CFSA1_CFSA2 0x000000ff
+#define ETH_CFSA1_CFSA3 0x0000ff00
+#define ETH_CFSA1_CFSA0 0x000000ff
+#define ETH_CFSA1_CFSA1 0x0000ff00
+
+/* Ethernet MAC1 registers */
+#define ETH_MAC1_RE (1 << 0)
+#define ETH_MAC1_PAF (1 << 1)
+#define ETH_MAC1_RFC (1 << 2)
+#define ETH_MAC1_TFC (1 << 3)
+#define ETH_MAC1_LB (1 << 4)
+#define ETH_MAC1_MR (1 << 31)
+
+/* Ethernet MAC2 registers */
+#define ETH_MAC2_FD (1 << 0)
+#define ETH_MAC2_FLC (1 << 1)
+#define ETH_MAC2_HFE (1 << 2)
+#define ETH_MAC2_DC (1 << 3)
+#define ETH_MAC2_CEN (1 << 4)
+#define ETH_MAC2_PE (1 << 5)
+#define ETH_MAC2_VPE (1 << 6)
+#define ETH_MAC2_APE (1 << 7)
+#define ETH_MAC2_PPE (1 << 8)
+#define ETH_MAC2_LPE (1 << 9)
+#define ETH_MAC2_NB (1 << 12)
+#define ETH_MAC2_BP (1 << 13)
+#define ETH_MAC2_ED (1 << 14)
+
+/* Ethernet IPGT register */
+#define ETH_IPGT 0x0000007f
+
+/* Ethernet IPGR registers */
+#define ETH_IPGR_IPGR2 0x0000007f
+#define ETH_IPGR_IPGR1 0x00007f00
+
+/* Ethernet CLRT registers */
+#define ETH_CLRT_MAX_RET 0x0000000f
+#define ETH_CLRT_COL_WIN 0x00003f00
+
+/* Ethernet MAXF register */
+#define ETH_MAXF 0x0000ffff
+
+/* Ethernet test registers */
+#define ETH_TEST_REG (1 << 2)
+#define ETH_MCP_DIV 0x000000ff
+
+/* MII registers */
+#define ETH_MII_CFG_RSVD 0x0000000c
+#define ETH_MII_CMD_RD (1 << 0)
+#define ETH_MII_CMD_SCN (1 << 1)
+#define ETH_MII_REG_ADDR 0x0000001f
+#define ETH_MII_PHY_ADDR 0x00001f00
+#define ETH_MII_WTD_DATA 0x0000ffff
+#define ETH_MII_RDD_DATA 0x0000ffff
+#define ETH_MII_IND_BSY (1 << 0)
+#define ETH_MII_IND_SCN (1 << 1)
+#define ETH_MII_IND_NV (1 << 2)
+
+/*
+ * Values for the DEVCS field of the Ethernet DMA Rx and Tx descriptors.
+ */
+
+#define ETH_RX_FD (1 << 0)
+#define ETH_RX_LD (1 << 1)
+#define ETH_RX_ROK (1 << 2)
+#define ETH_RX_FM (1 << 3)
+#define ETH_RX_MP (1 << 4)
+#define ETH_RX_BP (1 << 5)
+#define ETH_RX_VLT (1 << 6)
+#define ETH_RX_CF (1 << 7)
+#define ETH_RX_OVR (1 << 8)
+#define ETH_RX_CRC (1 << 9)
+#define ETH_RX_CV (1 << 10)
+#define ETH_RX_DB (1 << 11)
+#define ETH_RX_LE (1 << 12)
+#define ETH_RX_LOR (1 << 13)
+#define ETH_RX_CES (1 << 14)
+#define ETH_RX_LEN_BIT 16
+#define ETH_RX_LEN 0xffff0000
+
+#define ETH_TX_FD (1 << 0)
+#define ETH_TX_LD (1 << 1)
+#define ETH_TX_OEN (1 << 2)
+#define ETH_TX_PEN (1 << 3)
+#define ETH_TX_CEN (1 << 4)
+#define ETH_TX_HEN (1 << 5)
+#define ETH_TX_TOK (1 << 6)
+#define ETH_TX_MP (1 << 7)
+#define ETH_TX_BP (1 << 8)
+#define ETH_TX_UND (1 << 9)
+#define ETH_TX_OF (1 << 10)
+#define ETH_TX_ED (1 << 11)
+#define ETH_TX_EC (1 << 12)
+#define ETH_TX_LC (1 << 13)
+#define ETH_TX_TD (1 << 14)
+#define ETH_TX_CRC (1 << 15)
+#define ETH_TX_LE (1 << 16)
+#define ETH_TX_CC 0x001E0000
+
+#endif /* __ASM_RC32434_ETH_H */
diff --git a/arch/mips/include/asm/mach-rc32434/gpio.h b/arch/mips/include/asm/mach-rc32434/gpio.h
new file mode 100644
index 00000000..12ee8d51
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/gpio.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2002 Integrated Device Technology, Inc.
+ * All rights reserved.
+ *
+ * GPIO register definition.
+ *
+ * Author : ryan.holmQVist@idt.com
+ * Date : 20011005
+ * Copyright (C) 2001, 2002 Ryan Holm <ryan.holmQVist@idt.com>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#ifndef _RC32434_GPIO_H_
+#define _RC32434_GPIO_H_
+
+#include <linux/types.h>
+#include <asm-generic/gpio.h>
+
+#define NR_BUILTIN_GPIO 32
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(gpio) (8 + 4 * 32 + gpio)
+#define irq_to_gpio(irq) (irq - (8 + 4 * 32))
+
+struct rb532_gpio_reg {
+ u32 gpiofunc; /* GPIO Function Register
+ * gpiofunc[x]==0 bit = gpio
+ * func[x]==1 bit = altfunc
+ */
+ u32 gpiocfg; /* GPIO Configuration Register
+ * gpiocfg[x]==0 bit = input
+ * gpiocfg[x]==1 bit = output
+ */
+ u32 gpiod; /* GPIO Data Register
+ * gpiod[x] read/write gpio pinX status
+ */
+ u32 gpioilevel; /* GPIO Interrupt Status Register
+ * interrupt level (see gpioistat)
+ */
+ u32 gpioistat; /* Gpio Interrupt Status Register
+ * istat[x] = (gpiod[x] == level[x])
+ * cleared in ISR (STICKY bits)
+ */
+ u32 gpionmien; /* GPIO Non-maskable Interrupt Enable Register */
+};
+
+/* UART GPIO signals */
+#define RC32434_UART0_SOUT (1 << 0)
+#define RC32434_UART0_SIN (1 << 1)
+#define RC32434_UART0_RTS (1 << 2)
+#define RC32434_UART0_CTS (1 << 3)
+
+/* M & P bus GPIO signals */
+#define RC32434_MP_BIT_22 (1 << 4)
+#define RC32434_MP_BIT_23 (1 << 5)
+#define RC32434_MP_BIT_24 (1 << 6)
+#define RC32434_MP_BIT_25 (1 << 7)
+
+/* CPU GPIO signals */
+#define RC32434_CPU_GPIO (1 << 8)
+
+/* Reserved GPIO signals */
+#define RC32434_AF_SPARE_6 (1 << 9)
+#define RC32434_AF_SPARE_4 (1 << 10)
+#define RC32434_AF_SPARE_3 (1 << 11)
+#define RC32434_AF_SPARE_2 (1 << 12)
+
+/* PCI messaging unit */
+#define RC32434_PCI_MSU_GPIO (1 << 13)
+
+/* NAND GPIO signals */
+#define GPIO_RDY 8
+#define GPIO_WPX 9
+#define GPIO_ALE 10
+#define GPIO_CLE 11
+
+/* Compact Flash GPIO pin */
+#define CF_GPIO_NUM 13
+
+/* S1 button GPIO (shared with UART0_SIN) */
+#define GPIO_BTN_S1 1
+
+extern void rb532_gpio_set_ilevel(int bit, unsigned gpio);
+extern void rb532_gpio_set_istat(int bit, unsigned gpio);
+extern void rb532_gpio_set_func(unsigned gpio);
+
+#endif /* _RC32434_GPIO_H_ */
diff --git a/arch/mips/include/asm/mach-rc32434/integ.h b/arch/mips/include/asm/mach-rc32434/integ.h
new file mode 100644
index 00000000..fa65bc3d
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/integ.h
@@ -0,0 +1,59 @@
+/*
+ * Definitions for the Watchdog registers
+ *
+ * Copyright 2002 Ryan Holm <ryan.holmQVist@idt.com>
+ * Copyright 2008 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __RC32434_INTEG_H__
+#define __RC32434_INTEG_H__
+
+#include <asm/mach-rc32434/rb.h>
+
+#define INTEG0_BASE_ADDR 0x18030030
+
+struct integ {
+ u32 errcs; /* sticky use ERRCS_ */
+ u32 wtcount; /* Watchdog timer count reg. */
+ u32 wtcompare; /* Watchdog timer timeout value. */
+ u32 wtc; /* Watchdog timer control. use WTC_ */
+};
+
+/* Error counters */
+#define RC32434_ERR_WTO 0
+#define RC32434_ERR_WNE 1
+#define RC32434_ERR_UCW 2
+#define RC32434_ERR_UCR 3
+#define RC32434_ERR_UPW 4
+#define RC32434_ERR_UPR 5
+#define RC32434_ERR_UDW 6
+#define RC32434_ERR_UDR 7
+#define RC32434_ERR_SAE 8
+#define RC32434_ERR_WRE 9
+
+/* Watchdog control bits */
+#define RC32434_WTC_EN 0
+#define RC32434_WTC_TO 1
+
+#endif /* __RC32434_INTEG_H__ */
diff --git a/arch/mips/include/asm/mach-rc32434/irq.h b/arch/mips/include/asm/mach-rc32434/irq.h
new file mode 100644
index 00000000..023a5b10
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/irq.h
@@ -0,0 +1,36 @@
+#ifndef __ASM_RC32434_IRQ_H
+#define __ASM_RC32434_IRQ_H
+
+#define NR_IRQS 256
+
+#include <asm/mach-generic/irq.h>
+#include <asm/mach-rc32434/rb.h>
+
+/* Interrupt Controller */
+#define IC_GROUP0_PEND (REGBASE + 0x38000)
+#define IC_GROUP0_MASK (REGBASE + 0x38008)
+#define IC_GROUP_OFFSET 0x0C
+
+#define NUM_INTR_GROUPS 5
+
+/* 16550 UARTs */
+#define GROUP0_IRQ_BASE 8 /* GRP2 IRQ numbers start here */
+ /* GRP3 IRQ numbers start here */
+#define GROUP1_IRQ_BASE (GROUP0_IRQ_BASE + 32)
+ /* GRP4 IRQ numbers start here */
+#define GROUP2_IRQ_BASE (GROUP1_IRQ_BASE + 32)
+ /* GRP5 IRQ numbers start here */
+#define GROUP3_IRQ_BASE (GROUP2_IRQ_BASE + 32)
+#define GROUP4_IRQ_BASE (GROUP3_IRQ_BASE + 32)
+
+#define UART0_IRQ (GROUP3_IRQ_BASE + 0)
+
+#define ETH0_DMA_RX_IRQ (GROUP1_IRQ_BASE + 0)
+#define ETH0_DMA_TX_IRQ (GROUP1_IRQ_BASE + 1)
+#define ETH0_RX_OVR_IRQ (GROUP3_IRQ_BASE + 9)
+#define ETH0_TX_UND_IRQ (GROUP3_IRQ_BASE + 10)
+
+#define GPIO_MAPPED_IRQ_BASE GROUP4_IRQ_BASE
+#define GPIO_MAPPED_IRQ_GROUP 4
+
+#endif /* __ASM_RC32434_IRQ_H */
diff --git a/arch/mips/include/asm/mach-rc32434/pci.h b/arch/mips/include/asm/mach-rc32434/pci.h
new file mode 100644
index 00000000..410638f2
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/pci.h
@@ -0,0 +1,481 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Copyright 2004 IDT Inc. (rischelp@idt.com)
+ *
+ * Initial Release
+ */
+
+#ifndef _ASM_RC32434_PCI_H_
+#define _ASM_RC32434_PCI_H_
+
+#define epld_mask ((volatile unsigned char *)0xB900000d)
+
+#define PCI0_BASE_ADDR 0x18080000
+#define PCI_LBA_COUNT 4
+
+struct pci_map {
+ u32 address; /* Address. */
+ u32 control; /* Control. */
+ u32 mapping; /* mapping. */
+};
+
+struct pci_reg {
+ u32 pcic;
+ u32 pcis;
+ u32 pcism;
+ u32 pcicfga;
+ u32 pcicfgd;
+ volatile struct pci_map pcilba[PCI_LBA_COUNT];
+ u32 pcidac;
+ u32 pcidas;
+ u32 pcidasm;
+ u32 pcidad;
+ u32 pcidma8c;
+ u32 pcidma9c;
+ u32 pcitc;
+};
+
+#define PCI_MSU_COUNT 2
+
+struct pci_msu {
+ u32 pciim[PCI_MSU_COUNT];
+ u32 pciom[PCI_MSU_COUNT];
+ u32 pciid;
+ u32 pciiic;
+ u32 pciiim;
+ u32 pciiod;
+ u32 pciioic;
+ u32 pciioim;
+};
+
+/*
+ * PCI Control Register
+ */
+
+#define PCI_CTL_EN (1 << 0)
+#define PCI_CTL_TNR (1 << 1)
+#define PCI_CTL_SCE (1 << 2)
+#define PCI_CTL_IEN (1 << 3)
+#define PCI_CTL_AAA (1 << 4)
+#define PCI_CTL_EAP (1 << 5)
+#define PCI_CTL_PCIM_BIT 6
+#define PCI_CTL_PCIM 0x000001c0
+
+#define PCI_CTL_PCIM_DIS 0
+#define PCI_CTL_PCIM_TNR 1 /* Satellite - target not ready */
+#define PCI_CTL_PCIM_SUS 2 /* Satellite - suspended CPU. */
+#define PCI_CTL_PCIM_EXT 3 /* Host - external arbiter. */
+#define PCI_CTL PCIM_PRIO 4 /* Host - fixed priority arb. */
+#define PCI_CTL_PCIM_RR 5 /* Host - round robin priority. */
+#define PCI_CTL_PCIM_RSVD6 6
+#define PCI_CTL_PCIM_RSVD7 7
+
+#define PCI_CTL_IGM (1 << 9)
+
+/*
+ * PCI Status Register
+ */
+
+#define PCI_STAT_EED (1 << 0)
+#define PCI_STAT_WR (1 << 1)
+#define PCI_STAT_NMI (1 << 2)
+#define PCI_STAT_II (1 << 3)
+#define PCI_STAT_CWE (1 << 4)
+#define PCI_STAT_CRE (1 << 5)
+#define PCI_STAT_MDPE (1 << 6)
+#define PCI_STAT_STA (1 << 7)
+#define PCI_STAT_RTA (1 << 8)
+#define PCI_STAT_RMA (1 << 9)
+#define PCI_STAT_SSE (1 << 10)
+#define PCI_STAT_OSE (1 << 11)
+#define PCI_STAT_PE (1 << 12)
+#define PCI_STAT_TAE (1 << 13)
+#define PCI_STAT_RLE (1 << 14)
+#define PCI_STAT_BME (1 << 15)
+#define PCI_STAT_PRD (1 << 16)
+#define PCI_STAT_RIP (1 << 17)
+
+/*
+ * PCI Status Mask Register
+ */
+
+#define PCI_STATM_EED PCI_STAT_EED
+#define PCI_STATM_WR PCI_STAT_WR
+#define PCI_STATM_NMI PCI_STAT_NMI
+#define PCI_STATM_II PCI_STAT_II
+#define PCI_STATM_CWE PCI_STAT_CWE
+#define PCI_STATM_CRE PCI_STAT_CRE
+#define PCI_STATM_MDPE PCI_STAT_MDPE
+#define PCI_STATM_STA PCI_STAT_STA
+#define PCI_STATM_RTA PCI_STAT_RTA
+#define PCI_STATM_RMA PCI_STAT_RMA
+#define PCI_STATM_SSE PCI_STAT_SSE
+#define PCI_STATM_OSE PCI_STAT_OSE
+#define PCI_STATM_PE PCI_STAT_PE
+#define PCI_STATM_TAE PCI_STAT_TAE
+#define PCI_STATM_RLE PCI_STAT_RLE
+#define PCI_STATM_BME PCI_STAT_BME
+#define PCI_STATM_PRD PCI_STAT_PRD
+#define PCI_STATM_RIP PCI_STAT_RIP
+
+/*
+ * PCI Configuration Address Register
+ */
+#define PCI_CFGA_REG_BIT 2
+#define PCI_CFGA_REG 0x000000fc
+#define PCI_CFGA_REG_ID (0x00 >> 2) /* use PCFGID */
+#define PCI_CFGA_REG_04 (0x04 >> 2) /* use PCFG04_ */
+#define PCI_CFGA_REG_08 (0x08 >> 2) /* use PCFG08_ */
+#define PCI_CFGA_REG_0C (0x0C >> 2) /* use PCFG0C_ */
+#define PCI_CFGA_REG_PBA0 (0x10 >> 2) /* use PCIPBA_ */
+#define PCI_CFGA_REG_PBA1 (0x14 >> 2) /* use PCIPBA_ */
+#define PCI_CFGA_REG_PBA2 (0x18 >> 2) /* use PCIPBA_ */
+#define PCI_CFGA_REG_PBA3 (0x1c >> 2) /* use PCIPBA_ */
+#define PCI_CFGA_REG_SUBSYS (0x2c >> 2) /* use PCFGSS_ */
+#define PCI_CFGA_REG_3C (0x3C >> 2) /* use PCFG3C_ */
+#define PCI_CFGA_REG_PBBA0C (0x44 >> 2) /* use PCIPBAC_ */
+#define PCI_CFGA_REG_PBA0M (0x48 >> 2)
+#define PCI_CFGA_REG_PBA1C (0x4c >> 2) /* use PCIPBAC_ */
+#define PCI_CFGA_REG_PBA1M (0x50 >> 2)
+#define PCI_CFGA_REG_PBA2C (0x54 >> 2) /* use PCIPBAC_ */
+#define PCI_CFGA_REG_PBA2M (0x58 >> 2)
+#define PCI_CFGA_REG_PBA3C (0x5c >> 2) /* use PCIPBAC_ */
+#define PCI_CFGA_REG_PBA3M (0x60 >> 2)
+#define PCI_CFGA_REG_PMGT (0x64 >> 2)
+#define PCI_CFGA_FUNC_BIT 8
+#define PCI_CFGA_FUNC 0x00000700
+#define PCI_CFGA_DEV_BIT 11
+#define PCI_CFGA_DEV 0x0000f800
+#define PCI_CFGA_DEV_INTERN 0
+#define PCI_CFGA_BUS_BIT 16
+#define PCI CFGA_BUS 0x00ff0000
+#define PCI_CFGA_BUS_TYPE0 0
+#define PCI_CFGA_EN (1 << 31)
+
+/* PCI CFG04 commands */
+#define PCI_CFG04_CMD_IO_ENA (1 << 0)
+#define PCI_CFG04_CMD_MEM_ENA (1 << 1)
+#define PCI_CFG04_CMD_BM_ENA (1 << 2)
+#define PCI_CFG04_CMD_MW_INV (1 << 4)
+#define PCI_CFG04_CMD_PAR_ENA (1 << 6)
+#define PCI_CFG04_CMD_SER_ENA (1 << 8)
+#define PCI_CFG04_CMD_FAST_ENA (1 << 9)
+
+/* PCI CFG04 status fields */
+#define PCI_CFG04_STAT_BIT 16
+#define PCI_CFG04_STAT 0xffff0000
+#define PCI_CFG04_STAT_66_MHZ (1 << 21)
+#define PCI_CFG04_STAT_FBB (1 << 23)
+#define PCI_CFG04_STAT_MDPE (1 << 24)
+#define PCI_CFG04_STAT_DST (1 << 25)
+#define PCI_CFG04_STAT_STA (1 << 27)
+#define PCI_CFG04_STAT_RTA (1 << 28)
+#define PCI_CFG04_STAT_RMA (1 << 29)
+#define PCI_CFG04_STAT_SSE (1 << 30)
+#define PCI_CFG04_STAT_PE (1 << 31)
+
+#define PCI_PBA_MSI (1 << 0)
+#define PCI_PBA_P (1 << 2)
+
+/* PCI PBAC registers */
+#define PCI_PBAC_MSI (1 << 0)
+#define PCI_PBAC_P (1 << 1)
+#define PCI_PBAC_SIZE_BIT 2
+#define PCI_PBAC_SIZE 0x0000007c
+#define PCI_PBAC_SB (1 << 7)
+#define PCI_PBAC_PP (1 << 8)
+#define PCI_PBAC_MR_BIT 9
+#define PCI_PBAC_MR 0x00000600
+#define PCI_PBAC_MR_RD 0
+#define PCI_PBAC_MR_RD_LINE 1
+#define PCI_PBAC_MR_RD_MULT 2
+#define PCI_PBAC_MRL (1 << 11)
+#define PCI_PBAC_MRM (1 << 12)
+#define PCI_PBAC_TRP (1 << 13)
+
+#define PCI_CFG40_TRDY_TIM 0x000000ff
+#define PCI_CFG40_RET_LIM 0x0000ff00
+
+/*
+ * PCI Local Base Address [0|1|2|3] Register
+ */
+
+#define PCI_LBA_BADDR_BIT 0
+#define PCI_LBA_BADDR 0xffffff00
+
+/*
+ * PCI Local Base Address Control Register
+ */
+
+#define PCI_LBAC_MSI (1 << 0)
+#define PCI_LBAC_MSI_MEM 0
+#define PCI_LBAC_MSI_IO 1
+#define PCI_LBAC_SIZE_BIT 2
+#define PCI_LBAC_SIZE 0x0000007c
+#define PCI_LBAC_SB (1 << 7)
+#define PCI_LBAC_RT (1 << 8)
+#define PCI_LBAC_RT_NO_PREF 0
+#define PCI_LBAC_RT_PREF 1
+
+/*
+ * PCI Local Base Address [0|1|2|3] Mapping Register
+ */
+#define PCI_LBAM_MADDR_BIT 8
+#define PCI_LBAM_MADDR 0xffffff00
+
+/*
+ * PCI Decoupled Access Control Register
+ */
+#define PCI_DAC_DEN (1 << 0)
+
+/*
+ * PCI Decoupled Access Status Register
+ */
+#define PCI_DAS_D (1 << 0)
+#define PCI_DAS_B (1 << 1)
+#define PCI_DAS_E (1 << 2)
+#define PCI_DAS_OFE (1 << 3)
+#define PCI_DAS_OFF (1 << 4)
+#define PCI_DAS_IFE (1 << 5)
+#define PCI_DAS_IFF (1 << 6)
+
+/*
+ * PCI DMA Channel 8 Configuration Register
+ */
+#define PCI_DMA8C_MBS_BIT 0
+#define PCI_DMA8C_MBS 0x00000fff /* Maximum Burst Size. */
+#define PCI_DMA8C_OUR (1 << 12)
+
+/*
+ * PCI DMA Channel 9 Configuration Register
+ */
+#define PCI_DMA9C_MBS_BIT 0 /* Maximum Burst Size. */
+#define PCI_DMA9C_MBS 0x00000fff
+
+/*
+ * PCI to Memory(DMA Channel 8) AND Memory to PCI DMA(DMA Channel 9)Descriptors
+ */
+
+#define PCI_DMAD_PT_BIT 22 /* in DEVCMD field (descriptor) */
+#define PCI_DMAD_PT 0x00c00000 /* preferred transaction field */
+/* These are for reads (DMA channel 8) */
+#define PCI_DMAD_DEVCMD_MR 0 /* memory read */
+#define PCI_DMAD_DEVCMD_MRL 1 /* memory read line */
+#define PCI_DMAD_DEVCMD_MRM 2 /* memory read multiple */
+#define PCI_DMAD_DEVCMD_IOR 3 /* I/O read */
+/* These are for writes (DMA channel 9) */
+#define PCI_DMAD_DEVCMD_MW 0 /* memory write */
+#define PCI_DMAD_DEVCMD_MWI 1 /* memory write invalidate */
+#define PCI_DMAD_DEVCMD_IOW 3 /* I/O write */
+
+/* Swap byte field applies to both DMA channel 8 and 9 */
+#define PCI_DMAD_SB (1 << 24) /* swap byte field */
+
+
+/*
+ * PCI Target Control Register
+ */
+
+#define PCI_TC_RTIMER_BIT 0
+#define PCI_TC_RTIMER 0x000000ff
+#define PCI_TC_DTIMER_BIT 8
+#define PCI_TC_DTIMER 0x0000ff00
+#define PCI_TC_RDR (1 << 18)
+#define PCI_TC_DDT (1 << 19)
+
+/*
+ * PCI messaging unit [applies to both inbound and outbound registers ]
+ */
+#define PCI_MSU_M0 (1 << 0)
+#define PCI_MSU_M1 (1 << 1)
+#define PCI_MSU_DB (1 << 2)
+
+#define PCI_MSG_ADDR 0xB8088010
+#define PCI0_ADDR 0xB8080000
+#define rc32434_pci ((struct pci_reg *) PCI0_ADDR)
+#define rc32434_pci_msg ((struct pci_msu *) PCI_MSG_ADDR)
+
+#define PCIM_SHFT 0x6
+#define PCIM_BIT_LEN 0x7
+#define PCIM_H_EA 0x3
+#define PCIM_H_IA_FIX 0x4
+#define PCIM_H_IA_RR 0x5
+#if 0
+#define PCI_ADDR_START 0x13000000
+#endif
+
+#define PCI_ADDR_START 0x50000000
+
+#define CPUTOPCI_MEM_WIN 0x02000000
+#define CPUTOPCI_IO_WIN 0x00100000
+#define PCILBA_SIZE_SHFT 2
+#define PCILBA_SIZE_MASK 0x1F
+#define SIZE_256MB 0x1C
+#define SIZE_128MB 0x1B
+#define SIZE_64MB 0x1A
+#define SIZE_32MB 0x19
+#define SIZE_16MB 0x18
+#define SIZE_4MB 0x16
+#define SIZE_2MB 0x15
+#define SIZE_1MB 0x14
+#define KORINA_CONFIG0_ADDR 0x80000000
+#define KORINA_CONFIG1_ADDR 0x80000004
+#define KORINA_CONFIG2_ADDR 0x80000008
+#define KORINA_CONFIG3_ADDR 0x8000000C
+#define KORINA_CONFIG4_ADDR 0x80000010
+#define KORINA_CONFIG5_ADDR 0x80000014
+#define KORINA_CONFIG6_ADDR 0x80000018
+#define KORINA_CONFIG7_ADDR 0x8000001C
+#define KORINA_CONFIG8_ADDR 0x80000020
+#define KORINA_CONFIG9_ADDR 0x80000024
+#define KORINA_CONFIG10_ADDR 0x80000028
+#define KORINA_CONFIG11_ADDR 0x8000002C
+#define KORINA_CONFIG12_ADDR 0x80000030
+#define KORINA_CONFIG13_ADDR 0x80000034
+#define KORINA_CONFIG14_ADDR 0x80000038
+#define KORINA_CONFIG15_ADDR 0x8000003C
+#define KORINA_CONFIG16_ADDR 0x80000040
+#define KORINA_CONFIG17_ADDR 0x80000044
+#define KORINA_CONFIG18_ADDR 0x80000048
+#define KORINA_CONFIG19_ADDR 0x8000004C
+#define KORINA_CONFIG20_ADDR 0x80000050
+#define KORINA_CONFIG21_ADDR 0x80000054
+#define KORINA_CONFIG22_ADDR 0x80000058
+#define KORINA_CONFIG23_ADDR 0x8000005C
+#define KORINA_CONFIG24_ADDR 0x80000060
+#define KORINA_CONFIG25_ADDR 0x80000064
+#define KORINA_CMD (PCI_CFG04_CMD_IO_ENA | \
+ PCI_CFG04_CMD_MEM_ENA | \
+ PCI_CFG04_CMD_BM_ENA | \
+ PCI_CFG04_CMD_MW_INV | \
+ PCI_CFG04_CMD_PAR_ENA | \
+ PCI_CFG04_CMD_SER_ENA)
+
+#define KORINA_STAT (PCI_CFG04_STAT_MDPE | \
+ PCI_CFG04_STAT_STA | \
+ PCI_CFG04_STAT_RTA | \
+ PCI_CFG04_STAT_RMA | \
+ PCI_CFG04_STAT_SSE | \
+ PCI_CFG04_STAT_PE)
+
+#define KORINA_CNFG1 ((KORINA_STAT<<16)|KORINA_CMD)
+
+#define KORINA_REVID 0
+#define KORINA_CLASS_CODE 0
+#define KORINA_CNFG2 ((KORINA_CLASS_CODE<<8) | \
+ KORINA_REVID)
+
+#define KORINA_CACHE_LINE_SIZE 4
+#define KORINA_MASTER_LAT 0x3c
+#define KORINA_HEADER_TYPE 0
+#define KORINA_BIST 0
+
+#define KORINA_CNFG3 ((KORINA_BIST << 24) | \
+ (KORINA_HEADER_TYPE<<16) | \
+ (KORINA_MASTER_LAT<<8) | \
+ KORINA_CACHE_LINE_SIZE)
+
+#define KORINA_BAR0 0x00000008 /* 128 MB Memory */
+#define KORINA_BAR1 0x18800001 /* 1 MB IO */
+#define KORINA_BAR2 0x18000001 /* 2 MB IO window for Korina
+ internal Registers */
+#define KORINA_BAR3 0x48000008 /* Spare 128 MB Memory */
+
+#define KORINA_CNFG4 KORINA_BAR0
+#define KORINA_CNFG5 KORINA_BAR1
+#define KORINA_CNFG6 KORINA_BAR2
+#define KORINA_CNFG7 KORINA_BAR3
+
+#define KORINA_SUBSYS_VENDOR_ID 0x011d
+#define KORINA_SUBSYSTEM_ID 0x0214
+#define KORINA_CNFG8 0
+#define KORINA_CNFG9 0
+#define KORINA_CNFG10 0
+#define KORINA_CNFG11 ((KORINA_SUBSYS_VENDOR_ID<<16) | \
+ KORINA_SUBSYSTEM_ID)
+#define KORINA_INT_LINE 1
+#define KORINA_INT_PIN 1
+#define KORINA_MIN_GNT 8
+#define KORINA_MAX_LAT 0x38
+#define KORINA_CNFG12 0
+#define KORINA_CNFG13 0
+#define KORINA_CNFG14 0
+#define KORINA_CNFG15 ((KORINA_MAX_LAT<<24) | \
+ (KORINA_MIN_GNT<<16) | \
+ (KORINA_INT_PIN<<8) | \
+ KORINA_INT_LINE)
+#define KORINA_RETRY_LIMIT 0x80
+#define KORINA_TRDY_LIMIT 0x80
+#define KORINA_CNFG16 ((KORINA_RETRY_LIMIT<<8) | \
+ KORINA_TRDY_LIMIT)
+#define PCI_PBAxC_R 0x0
+#define PCI_PBAxC_RL 0x1
+#define PCI_PBAxC_RM 0x2
+#define SIZE_SHFT 2
+
+#if defined(__MIPSEB__)
+#define KORINA_PBA0C (PCI_PBAC_MRL | PCI_PBAC_SB | \
+ ((PCI_PBAxC_RM & 0x3) << PCI_PBAC_MR_BIT) | \
+ PCI_PBAC_PP | \
+ (SIZE_128MB<<SIZE_SHFT) | \
+ PCI_PBAC_P)
+#else
+#define KORINA_PBA0C (PCI_PBAC_MRL | \
+ ((PCI_PBAxC_RM & 0x3) << PCI_PBAC_MR_BIT) | \
+ PCI_PBAC_PP | \
+ (SIZE_128MB<<SIZE_SHFT) | \
+ PCI_PBAC_P)
+#endif
+#define KORINA_CNFG17 KORINA_PBA0C
+#define KORINA_PBA0M 0x0
+#define KORINA_CNFG18 KORINA_PBA0M
+
+#if defined(__MIPSEB__)
+#define KORINA_PBA1C ((SIZE_1MB<<SIZE_SHFT) | PCI_PBAC_SB | \
+ PCI_PBAC_MSI)
+#else
+#define KORINA_PBA1C ((SIZE_1MB<<SIZE_SHFT) | \
+ PCI_PBAC_MSI)
+#endif
+#define KORINA_CNFG19 KORINA_PBA1C
+#define KORINA_PBA1M 0x0
+#define KORINA_CNFG20 KORINA_PBA1M
+
+#if defined(__MIPSEB__)
+#define KORINA_PBA2C ((SIZE_2MB<<SIZE_SHFT) | PCI_PBAC_SB | \
+ PCI_PBAC_MSI)
+#else
+#define KORINA_PBA2C ((SIZE_2MB<<SIZE_SHFT) | \
+ PCI_PBAC_MSI)
+#endif
+#define KORINA_CNFG21 KORINA_PBA2C
+#define KORINA_PBA2M 0x18000000
+#define KORINA_CNFG22 KORINA_PBA2M
+#define KORINA_PBA3C 0
+#define KORINA_CNFG23 KORINA_PBA3C
+#define KORINA_PBA3M 0
+#define KORINA_CNFG24 KORINA_PBA3M
+
+#define PCITC_DTIMER_VAL 8
+#define PCITC_RTIMER_VAL 0x10
+
+#endif /* __ASM_RC32434_PCI_H */
diff --git a/arch/mips/include/asm/mach-rc32434/prom.h b/arch/mips/include/asm/mach-rc32434/prom.h
new file mode 100644
index 00000000..660707f1
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/prom.h
@@ -0,0 +1,40 @@
+/*
+ * Definitions for the PROM
+ *
+ * Copyright 2002 Ryan Holm <ryan.holmQVist@idt.com>
+ * Copyright 2008 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define PROM_ENTRY(x) (0xbfc00000 + ((x) * 8))
+
+#define SR_NMI 0x00180000
+#define SERIAL_SPEED_ENTRY 0x00000001
+
+#define FREQ_TAG "HZ="
+#define KMAC_TAG "kmac="
+#define MEM_TAG "mem="
+#define BOARD_TAG "board="
+
+#define BOARD_RB532 "500"
+#define BOARD_RB532A "500r5"
diff --git a/arch/mips/include/asm/mach-rc32434/rb.h b/arch/mips/include/asm/mach-rc32434/rb.h
new file mode 100644
index 00000000..6dc5f8df
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/rb.h
@@ -0,0 +1,89 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2004 IDT Inc.
+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ */
+#ifndef __ASM_RC32434_RB_H
+#define __ASM_RC32434_RB_H
+
+#include <linux/genhd.h>
+
+#define REGBASE 0x18000000
+#define IDT434_REG_BASE ((volatile void *) KSEG1ADDR(REGBASE))
+#define UART0BASE 0x58000
+#define RST (1 << 15)
+#define DEV0BASE 0x010000
+#define DEV0MASK 0x010004
+#define DEV0C 0x010008
+#define DEV0T 0x01000C
+#define DEV1BASE 0x010010
+#define DEV1MASK 0x010014
+#define DEV1C 0x010018
+#define DEV1TC 0x01001C
+#define DEV2BASE 0x010020
+#define DEV2MASK 0x010024
+#define DEV2C 0x010028
+#define DEV2TC 0x01002C
+#define DEV3BASE 0x010030
+#define DEV3MASK 0x010034
+#define DEV3C 0x010038
+#define DEV3TC 0x01003C
+#define BTCS 0x010040
+#define BTCOMPARE 0x010044
+#define GPIOBASE 0x050000
+/* Offsets relative to GPIOBASE */
+#define GPIOFUNC 0x00
+#define GPIOCFG 0x04
+#define GPIOD 0x08
+#define GPIOILEVEL 0x0C
+#define GPIOISTAT 0x10
+#define GPIONMIEN 0x14
+#define IMASK6 0x38
+#define LO_WPX (1 << 0)
+#define LO_ALE (1 << 1)
+#define LO_CLE (1 << 2)
+#define LO_CEX (1 << 3)
+#define LO_FOFF (1 << 5)
+#define LO_SPICS (1 << 6)
+#define LO_ULED (1 << 7)
+
+#define BIT_TO_MASK(x) (1 << x)
+
+struct dev_reg {
+ u32 base;
+ u32 mask;
+ u32 ctl;
+ u32 timing;
+};
+
+struct korina_device {
+ char *name;
+ unsigned char mac[6];
+ struct net_device *dev;
+};
+
+struct cf_device {
+ int gpio_pin;
+ void *dev;
+ struct gendisk *gd;
+};
+
+struct mpmc_device {
+ unsigned char state;
+ spinlock_t lock;
+ void __iomem *base;
+};
+
+extern void set_latch_u5(unsigned char or_mask, unsigned char nand_mask);
+extern unsigned char get_latch_u5(void);
+
+#endif /* __ASM_RC32434_RB_H */
diff --git a/arch/mips/include/asm/mach-rc32434/rc32434.h b/arch/mips/include/asm/mach-rc32434/rc32434.h
new file mode 100644
index 00000000..fce25d42
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/rc32434.h
@@ -0,0 +1,19 @@
+/*
+ * Definitions for IDT RC323434 CPU.
+ */
+
+#ifndef _ASM_RC32434_RC32434_H_
+#define _ASM_RC32434_RC32434_H_
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#define IDT_CLOCK_MULT 2
+
+/* cpu pipeline flush */
+static inline void rc32434_sync(void)
+{
+ __asm__ volatile ("sync");
+}
+
+#endif /* _ASM_RC32434_RC32434_H_ */
diff --git a/arch/mips/include/asm/mach-rc32434/timer.h b/arch/mips/include/asm/mach-rc32434/timer.h
new file mode 100644
index 00000000..e49b1d57
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/timer.h
@@ -0,0 +1,65 @@
+/*
+ * Definitions for timer registers
+ *
+ * Copyright 2004 Philip Rischel <rischelp@idt.com>
+ * Copyright 2008 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_RC32434_TIMER_H
+#define __ASM_RC32434_TIMER_H
+
+#include <asm/mach-rc32434/rb.h>
+
+#define TIMER0_BASE_ADDR 0x18028000
+#define TIMER_COUNT 3
+
+struct timer_counter {
+ u32 count;
+ u32 compare;
+ u32 ctc; /*use CTC_ */
+};
+
+struct timer {
+ struct timer_counter tim[TIMER_COUNT];
+ u32 rcount; /* use RCOUNT_ */
+ u32 rcompare; /* use RCOMPARE_ */
+ u32 rtc; /* use RTC_ */
+};
+
+#define RC32434_CTC_EN_BIT 0
+#define RC32434_CTC_TO_BIT 1
+
+/* Real time clock registers */
+#define RC32434_RTC_MSK(x) BIT_TO_MASK(x)
+#define RC32434_RTC_CE_BIT 0
+#define RC32434_RTC_TO_BIT 1
+#define RC32434_RTC_RQE_BIT 2
+
+/* Counter registers */
+#define RC32434_RCOUNT_BIT 0
+#define RC32434_RCOUNT_MSK 0x0000ffff
+#define RC32434_RCOMP_BIT 0
+#define RC32434_RCOMP_MSK 0x0000ffff
+
+#endif /* __ASM_RC32434_TIMER_H */
diff --git a/arch/mips/include/asm/mach-rc32434/war.h b/arch/mips/include/asm/mach-rc32434/war.h
new file mode 100644
index 00000000..3ddf187e
--- /dev/null
+++ b/arch/mips/include/asm/mach-rc32434/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_MIPS_WAR_H
+#define __ASM_MIPS_MACH_MIPS_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 1
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */
diff --git a/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h b/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h
new file mode 100644
index 00000000..ccf54336
--- /dev/null
+++ b/arch/mips/include/asm/mach-rm/cpu-feature-overrides.h
@@ -0,0 +1,43 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * SNI RM200 C apparently was only shipped with R4600 V2.0 and R5000 processors.
+ */
+#ifndef __ASM_MACH_RM200_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_RM200_CPU_FEATURE_OVERRIDES_H
+
+#include <cpu-feature-overrides.h>
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_4k_cache 1
+#define cpu_has_fpu 1
+#define cpu_has_32fpr 1
+#define cpu_has_counter 1
+#define cpu_has_watch 0
+#define cpu_has_mips16 0
+#define cpu_has_divec 0
+#define cpu_has_cache_cdex_p 1
+#define cpu_has_prefetch 0
+#define cpu_has_mcheck 0
+#define cpu_has_ejtag 0
+#define cpu_has_llsc 1
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases (PAGE_SIZE < 0x4000)
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 1
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_MACH_RM200_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-rm/mc146818rtc.h b/arch/mips/include/asm/mach-rm/mc146818rtc.h
new file mode 100644
index 00000000..145bce09
--- /dev/null
+++ b/arch/mips/include/asm/mach-rm/mc146818rtc.h
@@ -0,0 +1,21 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 by Ralf Baechle
+ *
+ * RTC routines for PC style attached Dallas chip with ARC epoch.
+ */
+#ifndef __ASM_MACH_RM_MC146818RTC_H
+#define __ASM_MACH_RM_MC146818RTC_H
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900)
+#else
+#define mc146818_decode_year(year) ((year) + 1980)
+#endif
+
+#include_next <mc146818rtc.h>
+
+#endif /* __ASM_MACH_RM_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-rm/war.h b/arch/mips/include/asm/mach-rm/war.h
new file mode 100644
index 00000000..948d3129
--- /dev/null
+++ b/arch/mips/include/asm/mach-rm/war.h
@@ -0,0 +1,29 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_RM_WAR_H
+#define __ASM_MIPS_MACH_RM_WAR_H
+
+/*
+ * The RM200C seems to have been shipped only with V2.0 R4600s
+ */
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 1
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_RM_WAR_H */
diff --git a/arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h
new file mode 100644
index 00000000..1c1f9241
--- /dev/null
+++ b/arch/mips/include/asm/mach-sibyte/cpu-feature-overrides.h
@@ -0,0 +1,47 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_SIBYTE_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_SIBYTE_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * Sibyte are MIPS64 processors wired to a specific configuration
+ */
+#define cpu_has_watch 1
+#define cpu_has_mips16 0
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 1
+#define cpu_has_ejtag 1
+
+#define cpu_has_llsc 1
+#define cpu_has_vtag_icache 1
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+#define cpu_icache_snoops_remote_store 0
+
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 1
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 1
+#define cpu_has_mips64r2 0
+
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+#define cpu_scache_line_size() 32
+
+#endif /* __ASM_MACH_SIBYTE_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h
new file mode 100644
index 00000000..743385d7
--- /dev/null
+++ b/arch/mips/include/asm/mach-sibyte/war.h
@@ -0,0 +1,41 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_SIBYTE_WAR_H
+#define __ASM_MIPS_MACH_SIBYTE_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+
+#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
+ defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
+
+#ifndef __ASSEMBLY__
+extern int sb1250_m3_workaround_needed(void);
+#endif
+
+#define BCM1250_M3_WAR sb1250_m3_workaround_needed()
+#define SIBYTE_1956_WAR 1
+
+#else
+
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+
+#endif
+
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_SIBYTE_WAR_H */
diff --git a/arch/mips/include/asm/mach-tx39xx/ioremap.h b/arch/mips/include/asm/mach-tx39xx/ioremap.h
new file mode 100644
index 00000000..93c6c04f
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx39xx/ioremap.h
@@ -0,0 +1,38 @@
+/*
+ * include/asm-mips/mach-tx39xx/ioremap.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_TX39XX_IOREMAP_H
+#define __ASM_MACH_TX39XX_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+ unsigned long flags)
+{
+#define TXX9_DIRECTMAP_BASE 0xff000000ul
+ if (offset >= TXX9_DIRECTMAP_BASE &&
+ offset < TXX9_DIRECTMAP_BASE + 0xff0000)
+ return (void __iomem *)offset;
+ return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+ return (unsigned long)addr >= TXX9_DIRECTMAP_BASE;
+}
+
+#endif /* __ASM_MACH_TX39XX_IOREMAP_H */
diff --git a/arch/mips/include/asm/mach-tx39xx/mangle-port.h b/arch/mips/include/asm/mach-tx39xx/mangle-port.h
new file mode 100644
index 00000000..ef0b502f
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx39xx/mangle-port.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_TX39XX_MANGLE_PORT_H
+#define __ASM_MACH_TX39XX_MANGLE_PORT_H
+
+#if defined(CONFIG_TOSHIBA_JMR3927)
+extern unsigned long (*__swizzle_addr_b)(unsigned long port);
+#define NEEDS_TXX9_SWIZZLE_ADDR_B
+#else
+#define __swizzle_addr_b(port) (port)
+#endif
+#define __swizzle_addr_w(port) (port)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+#define ioswabb(a, x) (x)
+#define __mem_ioswabb(a, x) (x)
+#define ioswabw(a, x) le16_to_cpu(x)
+#define __mem_ioswabw(a, x) (x)
+#define ioswabl(a, x) le32_to_cpu(x)
+#define __mem_ioswabl(a, x) (x)
+#define ioswabq(a, x) le64_to_cpu(x)
+#define __mem_ioswabq(a, x) (x)
+
+#endif /* __ASM_MACH_TX39XX_MANGLE_PORT_H */
diff --git a/arch/mips/include/asm/mach-tx39xx/war.h b/arch/mips/include/asm/mach-tx39xx/war.h
new file mode 100644
index 00000000..43381461
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx39xx/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_TX39XX_WAR_H
+#define __ASM_MIPS_MACH_TX39XX_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_TX39XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h
new file mode 100644
index 00000000..275eaf92
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_TX49XX_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_TX49XX_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_llsc 1
+#define cpu_has_64bits 1
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+#define cpu_has_vtag_icache 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_MACH_TX49XX_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-tx49xx/ioremap.h b/arch/mips/include/asm/mach-tx49xx/ioremap.h
new file mode 100644
index 00000000..1e7beae7
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx49xx/ioremap.h
@@ -0,0 +1,43 @@
+/*
+ * include/asm-mips/mach-tx49xx/ioremap.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_MACH_TX49XX_IOREMAP_H
+#define __ASM_MACH_TX49XX_IOREMAP_H
+
+#include <linux/types.h>
+
+/*
+ * Allow physical addresses to be fixed up to help peripherals located
+ * outside the low 32-bit range -- generic pass-through version.
+ */
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+ unsigned long flags)
+{
+#ifdef CONFIG_64BIT
+#define TXX9_DIRECTMAP_BASE 0xfff000000ul
+#else
+#define TXX9_DIRECTMAP_BASE 0xff000000ul
+#endif
+ if (offset >= TXX9_DIRECTMAP_BASE &&
+ offset < TXX9_DIRECTMAP_BASE + 0x400000)
+ return (void __iomem *)(unsigned long)(int)offset;
+ return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+ return (unsigned long)addr >=
+ (unsigned long)(int)(TXX9_DIRECTMAP_BASE & 0xffffffff);
+}
+
+#endif /* __ASM_MACH_TX49XX_IOREMAP_H */
diff --git a/arch/mips/include/asm/mach-tx49xx/kmalloc.h b/arch/mips/include/asm/mach-tx49xx/kmalloc.h
new file mode 100644
index 00000000..ff9a8b86
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx49xx/kmalloc.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_MACH_TX49XX_KMALLOC_H
+#define __ASM_MACH_TX49XX_KMALLOC_H
+
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
+
+#endif /* __ASM_MACH_TX49XX_KMALLOC_H */
diff --git a/arch/mips/include/asm/mach-tx49xx/mangle-port.h b/arch/mips/include/asm/mach-tx49xx/mangle-port.h
new file mode 100644
index 00000000..5e6912fd
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx49xx/mangle-port.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_MACH_TX49XX_MANGLE_PORT_H
+#define __ASM_MACH_TX49XX_MANGLE_PORT_H
+
+#define __swizzle_addr_b(port) (port)
+#define __swizzle_addr_w(port) (port)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+#define ioswabb(a, x) (x)
+#define __mem_ioswabb(a, x) (x)
+#if defined(CONFIG_TOSHIBA_RBTX4939) && \
+ (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)) && \
+ defined(__BIG_ENDIAN)
+#define NEEDS_TXX9_IOSWABW
+extern u16 (*ioswabw)(volatile u16 *a, u16 x);
+extern u16 (*__mem_ioswabw)(volatile u16 *a, u16 x);
+#else
+#define ioswabw(a, x) le16_to_cpu(x)
+#define __mem_ioswabw(a, x) (x)
+#endif
+#define ioswabl(a, x) le32_to_cpu(x)
+#define __mem_ioswabl(a, x) (x)
+#define ioswabq(a, x) le64_to_cpu(x)
+#define __mem_ioswabq(a, x) (x)
+
+#endif /* __ASM_MACH_TX49XX_MANGLE_PORT_H */
diff --git a/arch/mips/include/asm/mach-tx49xx/war.h b/arch/mips/include/asm/mach-tx49xx/war.h
new file mode 100644
index 00000000..39b5d117
--- /dev/null
+++ b/arch/mips/include/asm/mach-tx49xx/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_TX49XX_WAR_H
+#define __ASM_MIPS_MACH_TX49XX_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 1
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_TX49XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-vr41xx/irq.h b/arch/mips/include/asm/mach-vr41xx/irq.h
new file mode 100644
index 00000000..862058d3
--- /dev/null
+++ b/arch/mips/include/asm/mach-vr41xx/irq.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_MACH_VR41XX_IRQ_H
+#define __ASM_MACH_VR41XX_IRQ_H
+
+#include <asm/vr41xx/irq.h> /* for MIPS_CPU_IRQ_BASE */
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_VR41XX_IRQ_H */
diff --git a/arch/mips/include/asm/mach-vr41xx/war.h b/arch/mips/include/asm/mach-vr41xx/war.h
new file mode 100644
index 00000000..56a38926
--- /dev/null
+++ b/arch/mips/include/asm/mach-vr41xx/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_VR41XX_WAR_H
+#define __ASM_MIPS_MACH_VR41XX_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_VR41XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h b/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h
new file mode 100644
index 00000000..83746b84
--- /dev/null
+++ b/arch/mips/include/asm/mach-wrppmc/mach-gt64120.h
@@ -0,0 +1,83 @@
+/*
+ * This is a direct copy of the ev96100.h file, with a global
+ * search and replace. The numbers are the same.
+ *
+ * The reason I'm duplicating this is so that the 64120/96100
+ * defines won't be confusing in the source code.
+ */
+#ifndef __ASM_MIPS_GT64120_H
+#define __ASM_MIPS_GT64120_H
+
+/*
+ * This is the CPU physical memory map of PPMC Board:
+ *
+ * 0x00000000-0x03FFFFFF - 64MB SDRAM (SCS[0]#)
+ * 0x1C000000-0x1C000000 - LED (CS0)
+ * 0x1C800000-0x1C800007 - UART 16550 port (CS1)
+ * 0x1F000000-0x1F000000 - MailBox (CS3)
+ * 0x1FC00000-0x20000000 - 4MB Flash (BOOT CS)
+ */
+
+#define WRPPMC_SDRAM_SCS0_BASE 0x00000000
+#define WRPPMC_SDRAM_SCS0_SIZE 0x04000000
+
+#define WRPPMC_UART16550_BASE 0x1C800000
+#define WRPPMC_UART16550_CLOCK 3686400 /* 3.68MHZ */
+
+#define WRPPMC_LED_BASE 0x1C000000
+#define WRPPMC_MBOX_BASE 0x1F000000
+
+#define WRPPMC_BOOTROM_BASE 0x1FC00000
+#define WRPPMC_BOOTROM_SIZE 0x00400000 /* 4M Flash */
+
+#define WRPPMC_MIPS_TIMER_IRQ 7 /* MIPS compare/count timer interrupt */
+#define WRPPMC_UART16550_IRQ 6
+#define WRPPMC_PCI_INTA_IRQ 3
+
+/*
+ * PCI Bus I/O and Memory resources allocation
+ *
+ * NOTE: We only have PCI_0 hose interface
+ */
+#define GT_PCI_MEM_BASE 0x13000000UL
+#define GT_PCI_MEM_SIZE 0x02000000UL
+#define GT_PCI_IO_BASE 0x11000000UL
+#define GT_PCI_IO_SIZE 0x02000000UL
+
+/*
+ * PCI interrupts will come in on either the INTA or INTD interrupt lines,
+ * which are mapped to the #2 and #5 interrupt pins of the MIPS. On our
+ * boards, they all either come in on IntD or they all come in on IntA, they
+ * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the
+ * "requested" interrupt numbers and go through the list whenever we get an
+ * IntA/D.
+ *
+ * Interrupts < 8 are directly wired to the processor; PCI INTA is 8 and
+ * INTD is 11.
+ */
+#define GT_TIMER 4
+#define GT_INTA 2
+#define GT_INTD 5
+
+#ifndef __ASSEMBLY__
+
+/*
+ * GT64120 internal register space base address
+ */
+extern unsigned long gt64120_base;
+
+#define GT64120_BASE (gt64120_base)
+
+/* define WRPPMC_EARLY_DEBUG to enable early output something to UART */
+#undef WRPPMC_EARLY_DEBUG
+
+#ifdef WRPPMC_EARLY_DEBUG
+extern void wrppmc_led_on(int mask);
+extern void wrppmc_led_off(int mask);
+extern void wrppmc_early_printk(const char *fmt, ...);
+#else
+#define wrppmc_early_printk(fmt, ...) do {} while (0)
+#endif /* WRPPMC_EARLY_DEBUG */
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_MIPS_GT64120_H */
diff --git a/arch/mips/include/asm/mach-wrppmc/war.h b/arch/mips/include/asm/mach-wrppmc/war.h
new file mode 100644
index 00000000..ac48629b
--- /dev/null
+++ b/arch/mips/include/asm/mach-wrppmc/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_WRPPMC_WAR_H
+#define __ASM_MIPS_MACH_WRPPMC_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_WRPPMC_WAR_H */
diff --git a/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h b/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h
new file mode 100644
index 00000000..470e5e9e
--- /dev/null
+++ b/arch/mips/include/asm/mach-yosemite/cpu-feature-overrides.h
@@ -0,0 +1,47 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H
+
+/*
+ * Momentum Jaguar ATX always has the RM9000 processor.
+ */
+#define cpu_has_watch 1
+#define cpu_has_mips16 0
+#define cpu_has_divec 0
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+#define cpu_has_mcheck 0
+#define cpu_has_ejtag 0
+
+#define cpu_has_llsc 1
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+#define cpu_icache_snoops_remote_store 0
+
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 1
+
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+#define cpu_scache_line_size() 32
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_MACH_YOSEMITE_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-yosemite/war.h b/arch/mips/include/asm/mach-yosemite/war.h
new file mode 100644
index 00000000..e5c6d53e
--- /dev/null
+++ b/arch/mips/include/asm/mach-yosemite/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_YOSEMITE_WAR_H
+#define __ASM_MIPS_MACH_YOSEMITE_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 1
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_YOSEMITE_WAR_H */
diff --git a/arch/mips/include/asm/mc146818-time.h b/arch/mips/include/asm/mc146818-time.h
new file mode 100644
index 00000000..4a08dbe3
--- /dev/null
+++ b/arch/mips/include/asm/mc146818-time.h
@@ -0,0 +1,119 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef __ASM_MC146818_TIME_H
+#define __ASM_MC146818_TIME_H
+
+#include <linux/bcd.h>
+#include <linux/mc146818rtc.h>
+#include <linux/time.h>
+
+/*
+ * For check timing call set_rtc_mmss() 500ms; used in timer interrupt.
+ */
+#define USEC_AFTER 500000
+#define USEC_BEFORE 500000
+
+/*
+ * In order to set the CMOS clock precisely, set_rtc_mmss has to be
+ * called 500 ms after the second nowtime has started, because when
+ * nowtime is written into the registers of the CMOS clock, it will
+ * jump to the next second precisely 500 ms later. Check the Motorola
+ * MC146818A or Dallas DS12887 data sheet for details.
+ *
+ * BUG: This routine does not handle hour overflow properly; it just
+ * sets the minutes. Usually you'll only notice that after reboot!
+ */
+static inline int mc146818_set_rtc_mmss(unsigned long nowtime)
+{
+ int real_seconds, real_minutes, cmos_minutes;
+ unsigned char save_control, save_freq_select;
+ int retval = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+ CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+ CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+ cmos_minutes = CMOS_READ(RTC_MINUTES);
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+ cmos_minutes = bcd2bin(cmos_minutes);
+
+ /*
+ * since we're only adjusting minutes and seconds,
+ * don't interfere with hour overflow. This avoids
+ * messing with unknown time zones but requires your
+ * RTC not to be off by more than 15 minutes
+ */
+ real_seconds = nowtime % 60;
+ real_minutes = nowtime / 60;
+ if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+ real_minutes += 30; /* correct for half hour time zone */
+ real_minutes %= 60;
+
+ if (abs(real_minutes - cmos_minutes) < 30) {
+ if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
+ }
+ CMOS_WRITE(real_seconds, RTC_SECONDS);
+ CMOS_WRITE(real_minutes, RTC_MINUTES);
+ } else {
+ printk_once(KERN_NOTICE
+ "set_rtc_mmss: can't update from %d to %d\n",
+ cmos_minutes, real_minutes);
+ retval = -1;
+ }
+
+ /* The following flags have to be released exactly in this order,
+ * otherwise the DS12887 (popular MC146818A clone with integrated
+ * battery and quartz) will not reset the oscillator and will not
+ * update precisely 500 ms later. You won't find this mentioned in
+ * the Dallas Semiconductor data sheets, but who believes data
+ * sheets anyway ... -- Markus Kuhn
+ */
+ CMOS_WRITE(save_control, RTC_CONTROL);
+ CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ return retval;
+}
+
+static inline unsigned long mc146818_get_cmos_time(void)
+{
+ unsigned int year, mon, day, hour, min, sec;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+
+ do {
+ sec = CMOS_READ(RTC_SECONDS);
+ min = CMOS_READ(RTC_MINUTES);
+ hour = CMOS_READ(RTC_HOURS);
+ day = CMOS_READ(RTC_DAY_OF_MONTH);
+ mon = CMOS_READ(RTC_MONTH);
+ year = CMOS_READ(RTC_YEAR);
+ } while (sec != CMOS_READ(RTC_SECONDS));
+
+ if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
+ }
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ year = mc146818_decode_year(year);
+
+ return mktime(year, mon, day, hour, min, sec);
+}
+
+#endif /* __ASM_MC146818_TIME_H */
diff --git a/arch/mips/include/asm/mc146818rtc.h b/arch/mips/include/asm/mc146818rtc.h
new file mode 100644
index 00000000..68b4da6d
--- /dev/null
+++ b/arch/mips/include/asm/mc146818rtc.h
@@ -0,0 +1,16 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Machine dependent access functions for RTC registers.
+ *
+ * Copyright (C) 1996, 1997, 1998, 2000 Ralf Baechle
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <mc146818rtc.h>
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mips-boards/bonito64.h b/arch/mips/include/asm/mips-boards/bonito64.h
new file mode 100644
index 00000000..d14e2adc
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/bonito64.h
@@ -0,0 +1,431 @@
+/*
+ * Bonito Register Map
+ *
+ * This file is the original bonito.h from Algorithmics with minor changes
+ * to fit into linux.
+ *
+ * Copyright (c) 1999 Algorithmics Ltd
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2001 MIPS Technologies, Inc. All rights reserved.
+ *
+ * Algorithmics gives permission for anyone to use and modify this file
+ * without any obligation or license condition except that you retain
+ * this copyright message in any source redistribution in whole or part.
+ *
+ */
+
+/* Revision 1.48 autogenerated on 08/17/99 15:20:01 */
+/* This bonito64 version editted from bonito.h Revision 1.48 on 11/09/00 */
+
+#ifndef _ASM_MIPS_BOARDS_BONITO64_H
+#define _ASM_MIPS_BOARDS_BONITO64_H
+
+#ifdef __ASSEMBLY__
+
+/* offsets from base register */
+#define BONITO(x) (x)
+
+#else
+
+/*
+ * Algorithmics Bonito64 system controller register base.
+ */
+extern unsigned long _pcictrl_bonito;
+extern unsigned long _pcictrl_bonito_pcicfg;
+
+#define BONITO(x) *(volatile u32 *)(_pcictrl_bonito + (x))
+
+#endif /* __ASSEMBLY__ */
+
+
+#define BONITO_BOOT_BASE 0x1fc00000
+#define BONITO_BOOT_SIZE 0x00100000
+#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1)
+#define BONITO_FLASH_BASE 0x1c000000
+#define BONITO_FLASH_SIZE 0x03000000
+#define BONITO_FLASH_TOP (BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1)
+#define BONITO_SOCKET_BASE 0x1f800000
+#define BONITO_SOCKET_SIZE 0x00400000
+#define BONITO_SOCKET_TOP (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1)
+#define BONITO_REG_BASE 0x1fe00000
+#define BONITO_REG_SIZE 0x00040000
+#define BONITO_REG_TOP (BONITO_REG_BASE+BONITO_REG_SIZE-1)
+#define BONITO_DEV_BASE 0x1ff00000
+#define BONITO_DEV_SIZE 0x00100000
+#define BONITO_DEV_TOP (BONITO_DEV_BASE+BONITO_DEV_SIZE-1)
+#define BONITO_PCILO_BASE 0x10000000
+#define BONITO_PCILO_SIZE 0x0c000000
+#define BONITO_PCILO_TOP (BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1)
+#define BONITO_PCILO0_BASE 0x10000000
+#define BONITO_PCILO1_BASE 0x14000000
+#define BONITO_PCILO2_BASE 0x18000000
+#define BONITO_PCIHI_BASE 0x20000000
+#define BONITO_PCIHI_SIZE 0x20000000
+#define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
+#define BONITO_PCIIO_BASE 0x1fd00000
+#define BONITO_PCIIO_SIZE 0x00100000
+#define BONITO_PCIIO_TOP (BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
+#define BONITO_PCICFG_BASE 0x1fe80000
+#define BONITO_PCICFG_SIZE 0x00080000
+#define BONITO_PCICFG_TOP (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1)
+
+
+/* Bonito Register Bases */
+
+#define BONITO_PCICONFIGBASE 0x00
+#define BONITO_REGBASE 0x100
+
+
+/* PCI Configuration Registers */
+
+#define BONITO_PCI_REG(x) BONITO(BONITO_PCICONFIGBASE + (x))
+#define BONITO_PCIDID BONITO_PCI_REG(0x00)
+#define BONITO_PCICMD BONITO_PCI_REG(0x04)
+#define BONITO_PCICLASS BONITO_PCI_REG(0x08)
+#define BONITO_PCILTIMER BONITO_PCI_REG(0x0c)
+#define BONITO_PCIBASE0 BONITO_PCI_REG(0x10)
+#define BONITO_PCIBASE1 BONITO_PCI_REG(0x14)
+#define BONITO_PCIBASE2 BONITO_PCI_REG(0x18)
+#define BONITO_PCIEXPRBASE BONITO_PCI_REG(0x30)
+#define BONITO_PCIINT BONITO_PCI_REG(0x3c)
+
+#define BONITO_PCICMD_PERR_CLR 0x80000000
+#define BONITO_PCICMD_SERR_CLR 0x40000000
+#define BONITO_PCICMD_MABORT_CLR 0x20000000
+#define BONITO_PCICMD_MTABORT_CLR 0x10000000
+#define BONITO_PCICMD_TABORT_CLR 0x08000000
+#define BONITO_PCICMD_MPERR_CLR 0x01000000
+#define BONITO_PCICMD_PERRRESPEN 0x00000040
+#define BONITO_PCICMD_ASTEPEN 0x00000080
+#define BONITO_PCICMD_SERREN 0x00000100
+#define BONITO_PCILTIMER_BUSLATENCY 0x0000ff00
+#define BONITO_PCILTIMER_BUSLATENCY_SHIFT 8
+
+
+
+
+/* 1. Bonito h/w Configuration */
+/* Power on register */
+
+#define BONITO_BONPONCFG BONITO(BONITO_REGBASE + 0x00)
+
+#define BONITO_BONPONCFG_SYSCONTROLLERRD 0x00040000
+#define BONITO_BONPONCFG_ROMCS1SAMP 0x00020000
+#define BONITO_BONPONCFG_ROMCS0SAMP 0x00010000
+#define BONITO_BONPONCFG_CPUBIGEND 0x00004000
+/* Added by RPF 11-9-00 */
+#define BONITO_BONPONCFG_BURSTORDER 0x00001000
+/* --- */
+#define BONITO_BONPONCFG_CPUPARITY 0x00002000
+#define BONITO_BONPONCFG_CPUTYPE 0x00000007
+#define BONITO_BONPONCFG_CPUTYPE_SHIFT 0
+#define BONITO_BONPONCFG_PCIRESET_OUT 0x00000008
+#define BONITO_BONPONCFG_IS_ARBITER 0x00000010
+#define BONITO_BONPONCFG_ROMBOOT 0x000000c0
+#define BONITO_BONPONCFG_ROMBOOT_SHIFT 6
+
+#define BONITO_BONPONCFG_ROMBOOT_FLASH (0x0<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_SOCKET (0x1<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_SDRAM (0x2<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+#define BONITO_BONPONCFG_ROMBOOT_CPURESET (0x3<<BONITO_BONPONCFG_ROMBOOT_SHIFT)
+
+#define BONITO_BONPONCFG_ROMCS0WIDTH 0x00000100
+#define BONITO_BONPONCFG_ROMCS1WIDTH 0x00000200
+#define BONITO_BONPONCFG_ROMCS0FAST 0x00000400
+#define BONITO_BONPONCFG_ROMCS1FAST 0x00000800
+#define BONITO_BONPONCFG_CONFIG_DIS 0x00000020
+
+
+/* Other Bonito configuration */
+
+#define BONITO_BONGENCFG_OFFSET 0x4
+#define BONITO_BONGENCFG BONITO(BONITO_REGBASE + BONITO_BONGENCFG_OFFSET)
+
+#define BONITO_BONGENCFG_DEBUGMODE 0x00000001
+#define BONITO_BONGENCFG_SNOOPEN 0x00000002
+#define BONITO_BONGENCFG_CPUSELFRESET 0x00000004
+
+#define BONITO_BONGENCFG_FORCE_IRQA 0x00000008
+#define BONITO_BONGENCFG_IRQA_ISOUT 0x00000010
+#define BONITO_BONGENCFG_IRQA_FROM_INT1 0x00000020
+#define BONITO_BONGENCFG_BYTESWAP 0x00000040
+
+#define BONITO_BONGENCFG_UNCACHED 0x00000080
+#define BONITO_BONGENCFG_PREFETCHEN 0x00000100
+#define BONITO_BONGENCFG_WBEHINDEN 0x00000200
+#define BONITO_BONGENCFG_CACHEALG 0x00000c00
+#define BONITO_BONGENCFG_CACHEALG_SHIFT 10
+#define BONITO_BONGENCFG_PCIQUEUE 0x00001000
+#define BONITO_BONGENCFG_CACHESTOP 0x00002000
+#define BONITO_BONGENCFG_MSTRBYTESWAP 0x00004000
+#define BONITO_BONGENCFG_BUSERREN 0x00008000
+#define BONITO_BONGENCFG_NORETRYTIMEOUT 0x00010000
+#define BONITO_BONGENCFG_SHORTCOPYTIMEOUT 0x00020000
+
+/* 2. IO & IDE configuration */
+
+#define BONITO_IODEVCFG BONITO(BONITO_REGBASE + 0x08)
+
+/* 3. IO & IDE configuration */
+
+#define BONITO_SDCFG BONITO(BONITO_REGBASE + 0x0c)
+
+/* 4. PCI address map control */
+
+#define BONITO_PCIMAP BONITO(BONITO_REGBASE + 0x10)
+#define BONITO_PCIMEMBASECFG BONITO(BONITO_REGBASE + 0x14)
+#define BONITO_PCIMAP_CFG BONITO(BONITO_REGBASE + 0x18)
+
+/* 5. ICU & GPIO regs */
+
+/* GPIO Regs - r/w */
+
+#define BONITO_GPIODATA_OFFSET 0x1c
+#define BONITO_GPIODATA BONITO(BONITO_REGBASE + BONITO_GPIODATA_OFFSET)
+#define BONITO_GPIOIE BONITO(BONITO_REGBASE + 0x20)
+
+/* ICU Configuration Regs - r/w */
+
+#define BONITO_INTEDGE BONITO(BONITO_REGBASE + 0x24)
+#define BONITO_INTSTEER BONITO(BONITO_REGBASE + 0x28)
+#define BONITO_INTPOL BONITO(BONITO_REGBASE + 0x2c)
+
+/* ICU Enable Regs - IntEn & IntISR are r/o. */
+
+#define BONITO_INTENSET BONITO(BONITO_REGBASE + 0x30)
+#define BONITO_INTENCLR BONITO(BONITO_REGBASE + 0x34)
+#define BONITO_INTEN BONITO(BONITO_REGBASE + 0x38)
+#define BONITO_INTISR BONITO(BONITO_REGBASE + 0x3c)
+
+/* PCI mail boxes */
+
+#define BONITO_PCIMAIL0_OFFSET 0x40
+#define BONITO_PCIMAIL1_OFFSET 0x44
+#define BONITO_PCIMAIL2_OFFSET 0x48
+#define BONITO_PCIMAIL3_OFFSET 0x4c
+#define BONITO_PCIMAIL0 BONITO(BONITO_REGBASE + 0x40)
+#define BONITO_PCIMAIL1 BONITO(BONITO_REGBASE + 0x44)
+#define BONITO_PCIMAIL2 BONITO(BONITO_REGBASE + 0x48)
+#define BONITO_PCIMAIL3 BONITO(BONITO_REGBASE + 0x4c)
+
+
+/* 6. PCI cache */
+
+#define BONITO_PCICACHECTRL BONITO(BONITO_REGBASE + 0x50)
+#define BONITO_PCICACHETAG BONITO(BONITO_REGBASE + 0x54)
+
+#define BONITO_PCIBADADDR BONITO(BONITO_REGBASE + 0x58)
+#define BONITO_PCIMSTAT BONITO(BONITO_REGBASE + 0x5c)
+
+
+/*
+#define BONITO_PCIRDPOST BONITO(BONITO_REGBASE + 0x60)
+#define BONITO_PCIDATA BONITO(BONITO_REGBASE + 0x64)
+*/
+
+/* 7. IDE DMA & Copier */
+
+#define BONITO_CONFIGBASE 0x000
+#define BONITO_BONITOBASE 0x100
+#define BONITO_LDMABASE 0x200
+#define BONITO_COPBASE 0x300
+#define BONITO_REG_BLOCKMASK 0x300
+
+#define BONITO_LDMACTRL BONITO(BONITO_LDMABASE + 0x0)
+#define BONITO_LDMASTAT BONITO(BONITO_LDMABASE + 0x0)
+#define BONITO_LDMAADDR BONITO(BONITO_LDMABASE + 0x4)
+#define BONITO_LDMAGO BONITO(BONITO_LDMABASE + 0x8)
+#define BONITO_LDMADATA BONITO(BONITO_LDMABASE + 0xc)
+
+#define BONITO_COPCTRL BONITO(BONITO_COPBASE + 0x0)
+#define BONITO_COPSTAT BONITO(BONITO_COPBASE + 0x0)
+#define BONITO_COPPADDR BONITO(BONITO_COPBASE + 0x4)
+#define BONITO_COPDADDR BONITO(BONITO_COPBASE + 0x8)
+#define BONITO_COPGO BONITO(BONITO_COPBASE + 0xc)
+
+
+/* ###### Bit Definitions for individual Registers #### */
+
+/* Gen DMA. */
+
+#define BONITO_IDECOPDADDR_DMA_DADDR 0x0ffffffc
+#define BONITO_IDECOPDADDR_DMA_DADDR_SHIFT 2
+#define BONITO_IDECOPPADDR_DMA_PADDR 0xfffffffc
+#define BONITO_IDECOPPADDR_DMA_PADDR_SHIFT 2
+#define BONITO_IDECOPGO_DMA_SIZE 0x0000fffe
+#define BONITO_IDECOPGO_DMA_SIZE_SHIFT 0
+#define BONITO_IDECOPGO_DMA_WRITE 0x00010000
+#define BONITO_IDECOPGO_DMAWCOUNT 0x000f0000
+#define BONITO_IDECOPGO_DMAWCOUNT_SHIFT 16
+
+#define BONITO_IDECOPCTRL_DMA_STARTBIT 0x80000000
+#define BONITO_IDECOPCTRL_DMA_RSTBIT 0x40000000
+
+/* DRAM - sdCfg */
+
+#define BONITO_SDCFG_AROWBITS 0x00000003
+#define BONITO_SDCFG_AROWBITS_SHIFT 0
+#define BONITO_SDCFG_ACOLBITS 0x0000000c
+#define BONITO_SDCFG_ACOLBITS_SHIFT 2
+#define BONITO_SDCFG_ABANKBIT 0x00000010
+#define BONITO_SDCFG_ASIDES 0x00000020
+#define BONITO_SDCFG_AABSENT 0x00000040
+#define BONITO_SDCFG_AWIDTH64 0x00000080
+
+#define BONITO_SDCFG_BROWBITS 0x00000300
+#define BONITO_SDCFG_BROWBITS_SHIFT 8
+#define BONITO_SDCFG_BCOLBITS 0x00000c00
+#define BONITO_SDCFG_BCOLBITS_SHIFT 10
+#define BONITO_SDCFG_BBANKBIT 0x00001000
+#define BONITO_SDCFG_BSIDES 0x00002000
+#define BONITO_SDCFG_BABSENT 0x00004000
+#define BONITO_SDCFG_BWIDTH64 0x00008000
+
+#define BONITO_SDCFG_EXTRDDATA 0x00010000
+#define BONITO_SDCFG_EXTRASCAS 0x00020000
+#define BONITO_SDCFG_EXTPRECH 0x00040000
+#define BONITO_SDCFG_EXTRASWIDTH 0x00180000
+#define BONITO_SDCFG_EXTRASWIDTH_SHIFT 19
+/* Changed by RPF 11-9-00 */
+#define BONITO_SDCFG_DRAMMODESET 0x00200000
+/* --- */
+#define BONITO_SDCFG_DRAMEXTREGS 0x00400000
+#define BONITO_SDCFG_DRAMPARITY 0x00800000
+/* Added by RPF 11-9-00 */
+#define BONITO_SDCFG_DRAMBURSTLEN 0x03000000
+#define BONITO_SDCFG_DRAMBURSTLEN_SHIFT 24
+#define BONITO_SDCFG_DRAMMODESET_DONE 0x80000000
+/* --- */
+
+/* PCI Cache - pciCacheCtrl */
+
+#define BONITO_PCICACHECTRL_CACHECMD 0x00000007
+#define BONITO_PCICACHECTRL_CACHECMD_SHIFT 0
+#define BONITO_PCICACHECTRL_CACHECMDLINE 0x00000018
+#define BONITO_PCICACHECTRL_CACHECMDLINE_SHIFT 3
+#define BONITO_PCICACHECTRL_CMDEXEC 0x00000020
+
+#define BONITO_PCICACHECTRL_IOBCCOH_PRES 0x00000100
+#define BONITO_PCICACHECTRL_IOBCCOH_EN 0x00000200
+#define BONITO_PCICACHECTRL_CPUCOH_PRES 0x00000400
+#define BONITO_PCICACHECTRL_CPUCOH_EN 0x00000800
+
+#define BONITO_IODEVCFG_BUFFBIT_CS0 0x00000001
+#define BONITO_IODEVCFG_SPEEDBIT_CS0 0x00000002
+#define BONITO_IODEVCFG_MOREABITS_CS0 0x00000004
+
+#define BONITO_IODEVCFG_BUFFBIT_CS1 0x00000008
+#define BONITO_IODEVCFG_SPEEDBIT_CS1 0x00000010
+#define BONITO_IODEVCFG_MOREABITS_CS1 0x00000020
+
+#define BONITO_IODEVCFG_BUFFBIT_CS2 0x00000040
+#define BONITO_IODEVCFG_SPEEDBIT_CS2 0x00000080
+#define BONITO_IODEVCFG_MOREABITS_CS2 0x00000100
+
+#define BONITO_IODEVCFG_BUFFBIT_CS3 0x00000200
+#define BONITO_IODEVCFG_SPEEDBIT_CS3 0x00000400
+#define BONITO_IODEVCFG_MOREABITS_CS3 0x00000800
+
+#define BONITO_IODEVCFG_BUFFBIT_IDE 0x00001000
+#define BONITO_IODEVCFG_SPEEDBIT_IDE 0x00002000
+#define BONITO_IODEVCFG_WORDSWAPBIT_IDE 0x00004000
+#define BONITO_IODEVCFG_MODEBIT_IDE 0x00008000
+#define BONITO_IODEVCFG_DMAON_IDE 0x001f0000
+#define BONITO_IODEVCFG_DMAON_IDE_SHIFT 16
+#define BONITO_IODEVCFG_DMAOFF_IDE 0x01e00000
+#define BONITO_IODEVCFG_DMAOFF_IDE_SHIFT 21
+#define BONITO_IODEVCFG_EPROMSPLIT 0x02000000
+/* Added by RPF 11-9-00 */
+#define BONITO_IODEVCFG_CPUCLOCKPERIOD 0xfc000000
+#define BONITO_IODEVCFG_CPUCLOCKPERIOD_SHIFT 26
+/* --- */
+
+/* gpio */
+#define BONITO_GPIO_GPIOW 0x000003ff
+#define BONITO_GPIO_GPIOW_SHIFT 0
+#define BONITO_GPIO_GPIOR 0x01ff0000
+#define BONITO_GPIO_GPIOR_SHIFT 16
+#define BONITO_GPIO_GPINR 0xfe000000
+#define BONITO_GPIO_GPINR_SHIFT 25
+#define BONITO_GPIO_IOW(N) (1<<(BONITO_GPIO_GPIOW_SHIFT+(N)))
+#define BONITO_GPIO_IOR(N) (1<<(BONITO_GPIO_GPIOR_SHIFT+(N)))
+#define BONITO_GPIO_INR(N) (1<<(BONITO_GPIO_GPINR_SHIFT+(N)))
+
+/* ICU */
+#define BONITO_ICU_MBOXES 0x0000000f
+#define BONITO_ICU_MBOXES_SHIFT 0
+#define BONITO_ICU_DMARDY 0x00000010
+#define BONITO_ICU_DMAEMPTY 0x00000020
+#define BONITO_ICU_COPYRDY 0x00000040
+#define BONITO_ICU_COPYEMPTY 0x00000080
+#define BONITO_ICU_COPYERR 0x00000100
+#define BONITO_ICU_PCIIRQ 0x00000200
+#define BONITO_ICU_MASTERERR 0x00000400
+#define BONITO_ICU_SYSTEMERR 0x00000800
+#define BONITO_ICU_DRAMPERR 0x00001000
+#define BONITO_ICU_RETRYERR 0x00002000
+#define BONITO_ICU_GPIOS 0x01ff0000
+#define BONITO_ICU_GPIOS_SHIFT 16
+#define BONITO_ICU_GPINS 0x7e000000
+#define BONITO_ICU_GPINS_SHIFT 25
+#define BONITO_ICU_MBOX(N) (1<<(BONITO_ICU_MBOXES_SHIFT+(N)))
+#define BONITO_ICU_GPIO(N) (1<<(BONITO_ICU_GPIOS_SHIFT+(N)))
+#define BONITO_ICU_GPIN(N) (1<<(BONITO_ICU_GPINS_SHIFT+(N)))
+
+/* pcimap */
+
+#define BONITO_PCIMAP_PCIMAP_LO0 0x0000003f
+#define BONITO_PCIMAP_PCIMAP_LO0_SHIFT 0
+#define BONITO_PCIMAP_PCIMAP_LO1 0x00000fc0
+#define BONITO_PCIMAP_PCIMAP_LO1_SHIFT 6
+#define BONITO_PCIMAP_PCIMAP_LO2 0x0003f000
+#define BONITO_PCIMAP_PCIMAP_LO2_SHIFT 12
+#define BONITO_PCIMAP_PCIMAP_2 0x00040000
+#define BONITO_PCIMAP_WIN(WIN, ADDR) ((((ADDR)>>26) & BONITO_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
+
+#define BONITO_PCIMAP_WINSIZE (1<<26)
+#define BONITO_PCIMAP_WINOFFSET(ADDR) ((ADDR) & (BONITO_PCIMAP_WINSIZE - 1))
+#define BONITO_PCIMAP_WINBASE(ADDR) ((ADDR) << 26)
+
+/* pcimembaseCfg */
+
+#define BONITO_PCIMEMBASECFG_MASK 0xf0000000
+#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK 0x0000001f
+#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT 0
+#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS 0x000003e0
+#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT 5
+#define BONITO_PCIMEMBASECFG_MEMBASE0_CACHED 0x00000400
+#define BONITO_PCIMEMBASECFG_MEMBASE0_IO 0x00000800
+
+#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK 0x0001f000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK_SHIFT 12
+#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS 0x003e0000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS_SHIFT 17
+#define BONITO_PCIMEMBASECFG_MEMBASE1_CACHED 0x00400000
+#define BONITO_PCIMEMBASECFG_MEMBASE1_IO 0x00800000
+
+#define BONITO_PCIMEMBASECFG_ASHIFT 23
+#define BONITO_PCIMEMBASECFG_AMASK 0x007fffff
+#define BONITO_PCIMEMBASECFGSIZE(WIN, SIZE) (((~((SIZE)-1))>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)
+#define BONITO_PCIMEMBASECFGBASE(WIN, BASE) (((BASE)>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS)
+
+#define BONITO_PCIMEMBASECFG_SIZE(WIN, CFG) (((((~(CFG)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)) << (BONITO_PCIMEMBASECFG_ASHIFT - BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) | BONITO_PCIMEMBASECFG_AMASK)
+
+
+#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+#define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT)
+
+#define BONITO_PCITOPHYS(WIN, ADDR, CFG) ( \
+ (((ADDR) & (~(BONITO_PCIMEMBASECFG_MASK))) & (~(BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG)))) | \
+ (BONITO_PCIMEMBASECFG_ADDRTRANS(WIN, CFG)) \
+ )
+
+/* PCICmd */
+
+#define BONITO_PCICMD_MEMEN 0x00000002
+#define BONITO_PCICMD_MSTREN 0x00000004
+
+
+#endif /* _ASM_MIPS_BOARDS_BONITO64_H */
diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h
new file mode 100644
index 00000000..46c08563
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/generic.h
@@ -0,0 +1,100 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Defines of the MIPS boards specific address-MAP, registers, etc.
+ */
+#ifndef __ASM_MIPS_BOARDS_GENERIC_H
+#define __ASM_MIPS_BOARDS_GENERIC_H
+
+#include <asm/addrspace.h>
+#include <asm/byteorder.h>
+#include <asm/mips-boards/bonito64.h>
+
+/*
+ * Display register base.
+ */
+#define ASCII_DISPLAY_WORD_BASE 0x1f000410
+#define ASCII_DISPLAY_POS_BASE 0x1f000418
+
+
+/*
+ * Yamon Prom print address.
+ */
+#define YAMON_PROM_PRINT_ADDR 0x1fc00504
+
+
+/*
+ * Reset register.
+ */
+#define SOFTRES_REG 0x1f000500
+#define GORESET 0x42
+
+/*
+ * Revision register.
+ */
+#define MIPS_REVISION_REG 0x1fc00010
+#define MIPS_REVISION_CORID_QED_RM5261 0
+#define MIPS_REVISION_CORID_CORE_LV 1
+#define MIPS_REVISION_CORID_BONITO64 2
+#define MIPS_REVISION_CORID_CORE_20K 3
+#define MIPS_REVISION_CORID_CORE_FPGA 4
+#define MIPS_REVISION_CORID_CORE_MSC 5
+#define MIPS_REVISION_CORID_CORE_EMUL 6
+#define MIPS_REVISION_CORID_CORE_FPGA2 7
+#define MIPS_REVISION_CORID_CORE_FPGAR2 8
+#define MIPS_REVISION_CORID_CORE_FPGA3 9
+#define MIPS_REVISION_CORID_CORE_24K 10
+#define MIPS_REVISION_CORID_CORE_FPGA4 11
+#define MIPS_REVISION_CORID_CORE_FPGA5 12
+
+/**** Artificial corid defines ****/
+/*
+ * CoreEMUL with Bonito System Controller is treated like a Core20K
+ * CoreEMUL with SOC-it 101 System Controller is treated like a CoreMSC
+ */
+#define MIPS_REVISION_CORID_CORE_EMUL_BON -1
+#define MIPS_REVISION_CORID_CORE_EMUL_MSC -2
+
+#define MIPS_REVISION_CORID (((*(volatile u32 *)ioremap(MIPS_REVISION_REG, 4)) >> 10) & 0x3f)
+
+#define MIPS_REVISION_SCON_OTHER 0
+#define MIPS_REVISION_SCON_SOCITSC 1
+#define MIPS_REVISION_SCON_SOCITSCP 2
+
+/* Artificial SCON defines for MIPS_REVISION_SCON_OTHER */
+#define MIPS_REVISION_SCON_UNKNOWN -1
+#define MIPS_REVISION_SCON_GT64120 -2
+#define MIPS_REVISION_SCON_BONITO -3
+#define MIPS_REVISION_SCON_BRTL -4
+#define MIPS_REVISION_SCON_SOCIT -5
+#define MIPS_REVISION_SCON_ROCIT -6
+
+#define MIPS_REVISION_SCONID (((*(volatile u32 *)ioremap(MIPS_REVISION_REG, 4)) >> 24) & 0xff)
+
+extern int mips_revision_sconid;
+
+#ifdef CONFIG_PCI
+extern void mips_pcibios_init(void);
+#else
+#define mips_pcibios_init() do { } while (0)
+#endif
+
+#ifdef CONFIG_KGDB
+extern void kgdb_config(void);
+#endif
+
+#endif /* __ASM_MIPS_BOARDS_GENERIC_H */
diff --git a/arch/mips/include/asm/mips-boards/launch.h b/arch/mips/include/asm/mips-boards/launch.h
new file mode 100644
index 00000000..d8ae7f95
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/launch.h
@@ -0,0 +1,35 @@
+/*
+ *
+ */
+
+#ifndef _ASSEMBLER_
+
+struct cpulaunch {
+ unsigned long pc;
+ unsigned long gp;
+ unsigned long sp;
+ unsigned long a0;
+ unsigned long _pad[3]; /* pad to cache line size to avoid thrashing */
+ unsigned long flags;
+};
+
+#else
+
+#define LOG2CPULAUNCH 5
+#define LAUNCH_PC 0
+#define LAUNCH_GP 4
+#define LAUNCH_SP 8
+#define LAUNCH_A0 12
+#define LAUNCH_FLAGS 28
+
+#endif
+
+#define LAUNCH_FREADY 1
+#define LAUNCH_FGO 2
+#define LAUNCH_FGONE 4
+
+#define CPULAUNCH 0x00000f00
+#define NCPULAUNCH 8
+
+/* Polling period in count cycles for secondary CPU's */
+#define LAUNCHPERIOD 10000
diff --git a/arch/mips/include/asm/mips-boards/malta.h b/arch/mips/include/asm/mips-boards/malta.h
new file mode 100644
index 00000000..c1891578
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/malta.h
@@ -0,0 +1,102 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Defines of the Malta board specific address-MAP, registers, etc.
+ */
+#ifndef __ASM_MIPS_BOARDS_MALTA_H
+#define __ASM_MIPS_BOARDS_MALTA_H
+
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/mips-boards/msc01_pci.h>
+#include <asm/gt64120.h>
+
+/* Mips interrupt controller found in SOCit variations */
+#define MIPS_MSC01_IC_REG_BASE 0x1bc40000
+#define MIPS_SOCITSC_IC_REG_BASE 0x1ffa0000
+
+/*
+ * Malta I/O ports base address for the Galileo GT64120 and Algorithmics
+ * Bonito system controllers.
+ */
+#define MALTA_GT_PORT_BASE get_gt_port_base(GT_PCI0IOLD_OFS)
+#define MALTA_BONITO_PORT_BASE ((unsigned long)ioremap (0x1fd00000, 0x10000))
+#define MALTA_MSC_PORT_BASE get_msc_port_base(MSC01_PCI_SC2PIOBASL)
+
+static inline unsigned long get_gt_port_base(unsigned long reg)
+{
+ unsigned long addr;
+ addr = GT_READ(reg);
+ return (unsigned long) ioremap (((addr & 0xffff) << 21), 0x10000);
+}
+
+static inline unsigned long get_msc_port_base(unsigned long reg)
+{
+ unsigned long addr;
+ MSC_READ(reg, addr);
+ return (unsigned long) ioremap(addr, 0x10000);
+}
+
+/*
+ * GCMP Specific definitions
+ */
+#define GCMP_BASE_ADDR 0x1fbf8000
+#define GCMP_ADDRSPACE_SZ (256 * 1024)
+
+/*
+ * GIC Specific definitions
+ */
+#define GIC_BASE_ADDR 0x1bdc0000
+#define GIC_ADDRSPACE_SZ (128 * 1024)
+
+/*
+ * MSC01 BIU Specific definitions
+ * FIXME : These should be elsewhere ?
+ */
+#define MSC01_BIU_REG_BASE 0x1bc80000
+#define MSC01_BIU_ADDRSPACE_SZ (256 * 1024)
+#define MSC01_SC_CFG_OFS 0x0110
+#define MSC01_SC_CFG_GICPRES_MSK 0x00000004
+#define MSC01_SC_CFG_GICPRES_SHF 2
+#define MSC01_SC_CFG_GICENA_SHF 3
+
+/*
+ * Malta RTC-device indirect register access.
+ */
+#define MALTA_RTC_ADR_REG 0x70
+#define MALTA_RTC_DAT_REG 0x71
+
+/*
+ * Malta SMSC FDC37M817 Super I/O Controller register.
+ */
+#define SMSC_CONFIG_REG 0x3f0
+#define SMSC_DATA_REG 0x3f1
+
+#define SMSC_CONFIG_DEVNUM 0x7
+#define SMSC_CONFIG_ACTIVATE 0x30
+#define SMSC_CONFIG_ENTER 0x55
+#define SMSC_CONFIG_EXIT 0xaa
+
+#define SMSC_CONFIG_DEVNUM_FLOPPY 0
+
+#define SMSC_CONFIG_ACTIVATE_ENABLE 1
+
+#define SMSC_WRITE(x, a) outb(x, a)
+
+#define MALTA_JMPRS_REG 0x1f000210
+
+#endif /* __ASM_MIPS_BOARDS_MALTA_H */
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
new file mode 100644
index 00000000..d11aa02a
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -0,0 +1,107 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Defines for the Malta interrupt controller.
+ *
+ */
+#ifndef _MIPS_MALTAINT_H
+#define _MIPS_MALTAINT_H
+
+#include <irq.h>
+
+/*
+ * Interrupts 0..15 are used for Malta ISA compatible interrupts
+ */
+#define MALTA_INT_BASE 0
+
+/* CPU interrupt offsets */
+#define MIPSCPU_INT_SW0 0
+#define MIPSCPU_INT_SW1 1
+#define MIPSCPU_INT_MB0 2
+#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0
+#define MIPSCPU_INT_MB1 3
+#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1
+#define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */
+#define MIPSCPU_INT_MB2 4
+#define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */
+#define MIPSCPU_INT_MB3 5
+#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3
+#define MIPSCPU_INT_MB4 6
+#define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4
+
+/*
+ * Interrupts 64..127 are used for Soc-it Classic interrupts
+ */
+#define MSC01C_INT_BASE 64
+
+/* SOC-it Classic interrupt offsets */
+#define MSC01C_INT_TMR 0
+#define MSC01C_INT_PCI 1
+
+/*
+ * Interrupts 64..127 are used for Soc-it EIC interrupts
+ */
+#define MSC01E_INT_BASE 64
+
+/* SOC-it EIC interrupt offsets */
+#define MSC01E_INT_SW0 1
+#define MSC01E_INT_SW1 2
+#define MSC01E_INT_MB0 3
+#define MSC01E_INT_I8259A MSC01E_INT_MB0
+#define MSC01E_INT_MB1 4
+#define MSC01E_INT_SMI MSC01E_INT_MB1
+#define MSC01E_INT_MB2 5
+#define MSC01E_INT_MB3 6
+#define MSC01E_INT_COREHI MSC01E_INT_MB3
+#define MSC01E_INT_MB4 7
+#define MSC01E_INT_CORELO MSC01E_INT_MB4
+#define MSC01E_INT_TMR 8
+#define MSC01E_INT_PCI 9
+#define MSC01E_INT_PERFCTR 10
+#define MSC01E_INT_CPUCTR 11
+
+/* GIC's Nomenclature for Core Interrupt Pins on the Malta */
+#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
+#define GIC_CPU_INT1 1 /* . */
+#define GIC_CPU_INT2 2 /* . */
+#define GIC_CPU_INT3 3 /* . */
+#define GIC_CPU_INT4 4 /* . */
+#define GIC_CPU_INT5 5 /* Core Interrupt 5 */
+
+#define GIC_EXT_INTR(x) x
+
+/* External Interrupts used for IPI */
+#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16
+#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17
+#define GIC_IPI_EXT_INTR_RESCHED_VPE1 18
+#define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19
+#define GIC_IPI_EXT_INTR_RESCHED_VPE2 20
+#define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21
+#define GIC_IPI_EXT_INTR_RESCHED_VPE3 22
+#define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23
+
+#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
+
+#ifndef __ASSEMBLY__
+extern void maltaint_init(void);
+#endif
+
+#endif /* !(_MIPS_MALTAINT_H) */
diff --git a/arch/mips/include/asm/mips-boards/msc01_pci.h b/arch/mips/include/asm/mips-boards/msc01_pci.h
new file mode 100644
index 00000000..e036b7dd
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/msc01_pci.h
@@ -0,0 +1,258 @@
+/*
+ * PCI Register definitions for the MIPS System Controller.
+ *
+ * Copyright (C) 2002, 2005 MIPS Technologies, Inc. All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_MIPS_BOARDS_MSC01_PCI_H
+#define __ASM_MIPS_BOARDS_MSC01_PCI_H
+
+/*
+ * Register offset addresses
+ */
+
+#define MSC01_PCI_ID_OFS 0x0000
+#define MSC01_PCI_SC2PMBASL_OFS 0x0208
+#define MSC01_PCI_SC2PMMSKL_OFS 0x0218
+#define MSC01_PCI_SC2PMMAPL_OFS 0x0228
+#define MSC01_PCI_SC2PIOBASL_OFS 0x0248
+#define MSC01_PCI_SC2PIOMSKL_OFS 0x0258
+#define MSC01_PCI_SC2PIOMAPL_OFS 0x0268
+#define MSC01_PCI_P2SCMSKL_OFS 0x0308
+#define MSC01_PCI_P2SCMAPL_OFS 0x0318
+#define MSC01_PCI_INTCFG_OFS 0x0600
+#define MSC01_PCI_INTSTAT_OFS 0x0608
+#define MSC01_PCI_CFGADDR_OFS 0x0610
+#define MSC01_PCI_CFGDATA_OFS 0x0618
+#define MSC01_PCI_IACK_OFS 0x0620
+#define MSC01_PCI_HEAD0_OFS 0x2000 /* DevID, VendorID */
+#define MSC01_PCI_HEAD1_OFS 0x2008 /* Status, Command */
+#define MSC01_PCI_HEAD2_OFS 0x2010 /* Class code, RevID */
+#define MSC01_PCI_HEAD3_OFS 0x2018 /* bist, header, latency */
+#define MSC01_PCI_HEAD4_OFS 0x2020 /* BAR 0 */
+#define MSC01_PCI_HEAD5_OFS 0x2028 /* BAR 1 */
+#define MSC01_PCI_HEAD6_OFS 0x2030 /* BAR 2 */
+#define MSC01_PCI_HEAD7_OFS 0x2038 /* BAR 3 */
+#define MSC01_PCI_HEAD8_OFS 0x2040 /* BAR 4 */
+#define MSC01_PCI_HEAD9_OFS 0x2048 /* BAR 5 */
+#define MSC01_PCI_HEAD10_OFS 0x2050 /* CardBus CIS Ptr */
+#define MSC01_PCI_HEAD11_OFS 0x2058 /* SubSystem ID, -VendorID */
+#define MSC01_PCI_HEAD12_OFS 0x2060 /* ROM BAR */
+#define MSC01_PCI_HEAD13_OFS 0x2068 /* Capabilities ptr */
+#define MSC01_PCI_HEAD14_OFS 0x2070 /* reserved */
+#define MSC01_PCI_HEAD15_OFS 0x2078 /* Maxl, ming, intpin, int */
+#define MSC01_PCI_BAR0_OFS 0x2220
+#define MSC01_PCI_CFG_OFS 0x2380
+#define MSC01_PCI_SWAP_OFS 0x2388
+
+
+/*****************************************************************************
+ * Register encodings
+ ****************************************************************************/
+
+#define MSC01_PCI_ID_ID_SHF 16
+#define MSC01_PCI_ID_ID_MSK 0x00ff0000
+#define MSC01_PCI_ID_ID_HOSTBRIDGE 82
+#define MSC01_PCI_ID_MAR_SHF 8
+#define MSC01_PCI_ID_MAR_MSK 0x0000ff00
+#define MSC01_PCI_ID_MIR_SHF 0
+#define MSC01_PCI_ID_MIR_MSK 0x000000ff
+
+#define MSC01_PCI_SC2PMBASL_BAS_SHF 24
+#define MSC01_PCI_SC2PMBASL_BAS_MSK 0xff000000
+
+#define MSC01_PCI_SC2PMMSKL_MSK_SHF 24
+#define MSC01_PCI_SC2PMMSKL_MSK_MSK 0xff000000
+
+#define MSC01_PCI_SC2PMMAPL_MAP_SHF 24
+#define MSC01_PCI_SC2PMMAPL_MAP_MSK 0xff000000
+
+#define MSC01_PCI_SC2PIOBASL_BAS_SHF 24
+#define MSC01_PCI_SC2PIOBASL_BAS_MSK 0xff000000
+
+#define MSC01_PCI_SC2PIOMSKL_MSK_SHF 24
+#define MSC01_PCI_SC2PIOMSKL_MSK_MSK 0xff000000
+
+#define MSC01_PCI_SC2PIOMAPL_MAP_SHF 24
+#define MSC01_PCI_SC2PIOMAPL_MAP_MSK 0xff000000
+
+#define MSC01_PCI_P2SCMSKL_MSK_SHF 24
+#define MSC01_PCI_P2SCMSKL_MSK_MSK 0xff000000
+
+#define MSC01_PCI_P2SCMAPL_MAP_SHF 24
+#define MSC01_PCI_P2SCMAPL_MAP_MSK 0xff000000
+
+#define MSC01_PCI_INTCFG_RST_SHF 10
+#define MSC01_PCI_INTCFG_RST_MSK 0x00000400
+#define MSC01_PCI_INTCFG_RST_BIT 0x00000400
+#define MSC01_PCI_INTCFG_MWE_SHF 9
+#define MSC01_PCI_INTCFG_MWE_MSK 0x00000200
+#define MSC01_PCI_INTCFG_MWE_BIT 0x00000200
+#define MSC01_PCI_INTCFG_DTO_SHF 8
+#define MSC01_PCI_INTCFG_DTO_MSK 0x00000100
+#define MSC01_PCI_INTCFG_DTO_BIT 0x00000100
+#define MSC01_PCI_INTCFG_MA_SHF 7
+#define MSC01_PCI_INTCFG_MA_MSK 0x00000080
+#define MSC01_PCI_INTCFG_MA_BIT 0x00000080
+#define MSC01_PCI_INTCFG_TA_SHF 6
+#define MSC01_PCI_INTCFG_TA_MSK 0x00000040
+#define MSC01_PCI_INTCFG_TA_BIT 0x00000040
+#define MSC01_PCI_INTCFG_RTY_SHF 5
+#define MSC01_PCI_INTCFG_RTY_MSK 0x00000020
+#define MSC01_PCI_INTCFG_RTY_BIT 0x00000020
+#define MSC01_PCI_INTCFG_MWP_SHF 4
+#define MSC01_PCI_INTCFG_MWP_MSK 0x00000010
+#define MSC01_PCI_INTCFG_MWP_BIT 0x00000010
+#define MSC01_PCI_INTCFG_MRP_SHF 3
+#define MSC01_PCI_INTCFG_MRP_MSK 0x00000008
+#define MSC01_PCI_INTCFG_MRP_BIT 0x00000008
+#define MSC01_PCI_INTCFG_SWP_SHF 2
+#define MSC01_PCI_INTCFG_SWP_MSK 0x00000004
+#define MSC01_PCI_INTCFG_SWP_BIT 0x00000004
+#define MSC01_PCI_INTCFG_SRP_SHF 1
+#define MSC01_PCI_INTCFG_SRP_MSK 0x00000002
+#define MSC01_PCI_INTCFG_SRP_BIT 0x00000002
+#define MSC01_PCI_INTCFG_SE_SHF 0
+#define MSC01_PCI_INTCFG_SE_MSK 0x00000001
+#define MSC01_PCI_INTCFG_SE_BIT 0x00000001
+
+#define MSC01_PCI_INTSTAT_RST_SHF 10
+#define MSC01_PCI_INTSTAT_RST_MSK 0x00000400
+#define MSC01_PCI_INTSTAT_RST_BIT 0x00000400
+#define MSC01_PCI_INTSTAT_MWE_SHF 9
+#define MSC01_PCI_INTSTAT_MWE_MSK 0x00000200
+#define MSC01_PCI_INTSTAT_MWE_BIT 0x00000200
+#define MSC01_PCI_INTSTAT_DTO_SHF 8
+#define MSC01_PCI_INTSTAT_DTO_MSK 0x00000100
+#define MSC01_PCI_INTSTAT_DTO_BIT 0x00000100
+#define MSC01_PCI_INTSTAT_MA_SHF 7
+#define MSC01_PCI_INTSTAT_MA_MSK 0x00000080
+#define MSC01_PCI_INTSTAT_MA_BIT 0x00000080
+#define MSC01_PCI_INTSTAT_TA_SHF 6
+#define MSC01_PCI_INTSTAT_TA_MSK 0x00000040
+#define MSC01_PCI_INTSTAT_TA_BIT 0x00000040
+#define MSC01_PCI_INTSTAT_RTY_SHF 5
+#define MSC01_PCI_INTSTAT_RTY_MSK 0x00000020
+#define MSC01_PCI_INTSTAT_RTY_BIT 0x00000020
+#define MSC01_PCI_INTSTAT_MWP_SHF 4
+#define MSC01_PCI_INTSTAT_MWP_MSK 0x00000010
+#define MSC01_PCI_INTSTAT_MWP_BIT 0x00000010
+#define MSC01_PCI_INTSTAT_MRP_SHF 3
+#define MSC01_PCI_INTSTAT_MRP_MSK 0x00000008
+#define MSC01_PCI_INTSTAT_MRP_BIT 0x00000008
+#define MSC01_PCI_INTSTAT_SWP_SHF 2
+#define MSC01_PCI_INTSTAT_SWP_MSK 0x00000004
+#define MSC01_PCI_INTSTAT_SWP_BIT 0x00000004
+#define MSC01_PCI_INTSTAT_SRP_SHF 1
+#define MSC01_PCI_INTSTAT_SRP_MSK 0x00000002
+#define MSC01_PCI_INTSTAT_SRP_BIT 0x00000002
+#define MSC01_PCI_INTSTAT_SE_SHF 0
+#define MSC01_PCI_INTSTAT_SE_MSK 0x00000001
+#define MSC01_PCI_INTSTAT_SE_BIT 0x00000001
+
+#define MSC01_PCI_CFGADDR_BNUM_SHF 16
+#define MSC01_PCI_CFGADDR_BNUM_MSK 0x00ff0000
+#define MSC01_PCI_CFGADDR_DNUM_SHF 11
+#define MSC01_PCI_CFGADDR_DNUM_MSK 0x0000f800
+#define MSC01_PCI_CFGADDR_FNUM_SHF 8
+#define MSC01_PCI_CFGADDR_FNUM_MSK 0x00000700
+#define MSC01_PCI_CFGADDR_RNUM_SHF 2
+#define MSC01_PCI_CFGADDR_RNUM_MSK 0x000000fc
+
+#define MSC01_PCI_CFGDATA_DATA_SHF 0
+#define MSC01_PCI_CFGDATA_DATA_MSK 0xffffffff
+
+/* The defines below are ONLY valid for a MEM bar! */
+#define MSC01_PCI_BAR0_SIZE_SHF 4
+#define MSC01_PCI_BAR0_SIZE_MSK 0xfffffff0
+#define MSC01_PCI_BAR0_P_SHF 3
+#define MSC01_PCI_BAR0_P_MSK 0x00000008
+#define MSC01_PCI_BAR0_P_BIT MSC01_PCI_BAR0_P_MSK
+#define MSC01_PCI_BAR0_D_SHF 1
+#define MSC01_PCI_BAR0_D_MSK 0x00000006
+#define MSC01_PCI_BAR0_T_SHF 0
+#define MSC01_PCI_BAR0_T_MSK 0x00000001
+#define MSC01_PCI_BAR0_T_BIT MSC01_PCI_BAR0_T_MSK
+
+
+#define MSC01_PCI_CFG_RA_SHF 17
+#define MSC01_PCI_CFG_RA_MSK 0x00020000
+#define MSC01_PCI_CFG_RA_BIT MSC01_PCI_CFG_RA_MSK
+#define MSC01_PCI_CFG_G_SHF 16
+#define MSC01_PCI_CFG_G_MSK 0x00010000
+#define MSC01_PCI_CFG_G_BIT MSC01_PCI_CFG_G_MSK
+#define MSC01_PCI_CFG_EN_SHF 15
+#define MSC01_PCI_CFG_EN_MSK 0x00008000
+#define MSC01_PCI_CFG_EN_BIT MSC01_PCI_CFG_EN_MSK
+#define MSC01_PCI_CFG_MAXRTRY_SHF 0
+#define MSC01_PCI_CFG_MAXRTRY_MSK 0x00000fff
+
+#define MSC01_PCI_SWAP_IO_SHF 18
+#define MSC01_PCI_SWAP_IO_MSK 0x000c0000
+#define MSC01_PCI_SWAP_MEM_SHF 16
+#define MSC01_PCI_SWAP_MEM_MSK 0x00030000
+#define MSC01_PCI_SWAP_BAR0_SHF 0
+#define MSC01_PCI_SWAP_BAR0_MSK 0x00000003
+#define MSC01_PCI_SWAP_NOSWAP 0
+#define MSC01_PCI_SWAP_BYTESWAP 1
+
+/*
+ * MIPS System controller PCI register base.
+ *
+ * FIXME - are these macros specific to Malta and co or to the MSC? If the
+ * latter, they should be moved elsewhere.
+ */
+#define MIPS_MSC01_PCI_REG_BASE 0x1bd00000
+#define MIPS_SOCITSC_PCI_REG_BASE 0x1ff10000
+
+extern unsigned long _pcictrl_msc;
+
+#define MSC01_PCI_REG_BASE _pcictrl_msc
+
+#define MSC_WRITE(reg, data) do { *(volatile u32 *)(reg) = data; } while (0)
+#define MSC_READ(reg, data) do { data = *(volatile u32 *)(reg); } while (0)
+
+/*
+ * Registers absolute addresses
+ */
+
+#define MSC01_PCI_ID (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS)
+#define MSC01_PCI_SC2PMBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS)
+#define MSC01_PCI_SC2PMMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS)
+#define MSC01_PCI_SC2PMMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS)
+#define MSC01_PCI_SC2PIOBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS)
+#define MSC01_PCI_SC2PIOMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS)
+#define MSC01_PCI_SC2PIOMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS)
+#define MSC01_PCI_P2SCMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS)
+#define MSC01_PCI_P2SCMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS)
+#define MSC01_PCI_INTCFG (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS)
+#define MSC01_PCI_INTSTAT (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS)
+#define MSC01_PCI_CFGADDR (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS)
+#define MSC01_PCI_CFGDATA (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS)
+#define MSC01_PCI_IACK (MSC01_PCI_REG_BASE + MSC01_PCI_IACK_OFS)
+#define MSC01_PCI_HEAD0 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD0_OFS)
+#define MSC01_PCI_HEAD1 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD1_OFS)
+#define MSC01_PCI_HEAD2 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD2_OFS)
+#define MSC01_PCI_HEAD3 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD3_OFS)
+#define MSC01_PCI_HEAD4 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD4_OFS)
+#define MSC01_PCI_HEAD5 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD5_OFS)
+#define MSC01_PCI_HEAD6 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD6_OFS)
+#define MSC01_PCI_HEAD7 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD7_OFS)
+#define MSC01_PCI_HEAD8 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD8_OFS)
+#define MSC01_PCI_HEAD9 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD9_OFS)
+#define MSC01_PCI_HEAD10 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD10_OFS)
+#define MSC01_PCI_HEAD11 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD12 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD13 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD14 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_HEAD15 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS)
+#define MSC01_PCI_BAR0 (MSC01_PCI_REG_BASE + MSC01_PCI_BAR0_OFS)
+#define MSC01_PCI_CFG (MSC01_PCI_REG_BASE + MSC01_PCI_CFG_OFS)
+#define MSC01_PCI_SWAP (MSC01_PCI_REG_BASE + MSC01_PCI_SWAP_OFS)
+
+#endif /* __ASM_MIPS_BOARDS_MSC01_PCI_H */
diff --git a/arch/mips/include/asm/mips-boards/piix4.h b/arch/mips/include/asm/mips-boards/piix4.h
new file mode 100644
index 00000000..2971d60f
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/piix4.h
@@ -0,0 +1,80 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Register definitions for Intel PIIX4 South Bridge Device.
+ */
+#ifndef __ASM_MIPS_BOARDS_PIIX4_H
+#define __ASM_MIPS_BOARDS_PIIX4_H
+
+/************************************************************************
+ * IO register offsets
+ ************************************************************************/
+#define PIIX4_ICTLR1_ICW1 0x20
+#define PIIX4_ICTLR1_ICW2 0x21
+#define PIIX4_ICTLR1_ICW3 0x21
+#define PIIX4_ICTLR1_ICW4 0x21
+#define PIIX4_ICTLR2_ICW1 0xa0
+#define PIIX4_ICTLR2_ICW2 0xa1
+#define PIIX4_ICTLR2_ICW3 0xa1
+#define PIIX4_ICTLR2_ICW4 0xa1
+#define PIIX4_ICTLR1_OCW1 0x21
+#define PIIX4_ICTLR1_OCW2 0x20
+#define PIIX4_ICTLR1_OCW3 0x20
+#define PIIX4_ICTLR1_OCW4 0x20
+#define PIIX4_ICTLR2_OCW1 0xa1
+#define PIIX4_ICTLR2_OCW2 0xa0
+#define PIIX4_ICTLR2_OCW3 0xa0
+#define PIIX4_ICTLR2_OCW4 0xa0
+
+
+/************************************************************************
+ * Register encodings.
+ ************************************************************************/
+#define PIIX4_OCW2_NSEOI (0x1 << 5)
+#define PIIX4_OCW2_SEOI (0x3 << 5)
+#define PIIX4_OCW2_RNSEOI (0x5 << 5)
+#define PIIX4_OCW2_RAEOIS (0x4 << 5)
+#define PIIX4_OCW2_RAEOIC (0x0 << 5)
+#define PIIX4_OCW2_RSEOI (0x7 << 5)
+#define PIIX4_OCW2_SP (0x6 << 5)
+#define PIIX4_OCW2_NOP (0x2 << 5)
+
+#define PIIX4_OCW2_SEL (0x0 << 3)
+
+#define PIIX4_OCW2_ILS_0 0
+#define PIIX4_OCW2_ILS_1 1
+#define PIIX4_OCW2_ILS_2 2
+#define PIIX4_OCW2_ILS_3 3
+#define PIIX4_OCW2_ILS_4 4
+#define PIIX4_OCW2_ILS_5 5
+#define PIIX4_OCW2_ILS_6 6
+#define PIIX4_OCW2_ILS_7 7
+#define PIIX4_OCW2_ILS_8 0
+#define PIIX4_OCW2_ILS_9 1
+#define PIIX4_OCW2_ILS_10 2
+#define PIIX4_OCW2_ILS_11 3
+#define PIIX4_OCW2_ILS_12 4
+#define PIIX4_OCW2_ILS_13 5
+#define PIIX4_OCW2_ILS_14 6
+#define PIIX4_OCW2_ILS_15 7
+
+#define PIIX4_OCW3_SEL (0x1 << 3)
+
+#define PIIX4_OCW3_IRR 0x2
+#define PIIX4_OCW3_ISR 0x3
+
+#endif /* __ASM_MIPS_BOARDS_PIIX4_H */
diff --git a/arch/mips/include/asm/mips-boards/prom.h b/arch/mips/include/asm/mips-boards/prom.h
new file mode 100644
index 00000000..a9db576a
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/prom.h
@@ -0,0 +1,47 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * MIPS boards bootprom interface for the Linux kernel.
+ *
+ */
+
+#ifndef _MIPS_PROM_H
+#define _MIPS_PROM_H
+
+extern char *prom_getcmdline(void);
+extern char *prom_getenv(char *name);
+extern void prom_init_cmdline(void);
+extern void prom_meminit(void);
+extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
+extern void mips_display_message(const char *str);
+extern void mips_display_word(unsigned int num);
+extern void mips_scroll_message(void);
+extern int get_ethernet_addr(char *ethernet_addr);
+
+/* Memory descriptor management. */
+#define PROM_MAX_PMEMBLOCKS 32
+struct prom_pmemblock {
+ unsigned long base; /* Within KSEG0. */
+ unsigned int size; /* In bytes. */
+ unsigned int type; /* free or prom memory */
+};
+
+#endif /* !(_MIPS_PROM_H) */
diff --git a/arch/mips/include/asm/mips-boards/sim.h b/arch/mips/include/asm/mips-boards/sim.h
new file mode 100644
index 00000000..acb7c233
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/sim.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _ASM_MIPS_BOARDS_SIM_H
+#define _ASM_MIPS_BOARDS_SIM_H
+
+#define STATS_ON 1
+#define STATS_OFF 2
+#define STATS_CLEAR 3
+#define STATS_DUMP 4
+#define TRACE_ON 5
+#define TRACE_OFF 6
+
+
+#define simcfg(code) \
+({ \
+ __asm__ __volatile__( \
+ "sltiu $0,$0, %0" \
+ ::"i"(code) \
+ ); \
+})
+
+
+
+#endif
diff --git a/arch/mips/include/asm/mips-boards/simint.h b/arch/mips/include/asm/mips-boards/simint.h
new file mode 100644
index 00000000..8ef6db76
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/simint.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#ifndef _MIPS_SIMINT_H
+#define _MIPS_SIMINT_H
+
+#include <irq.h>
+
+#define SIM_INT_BASE 0
+#define MIPSCPU_INT_MB0 2
+#define MIPS_CPU_TIMER_IRQ 7
+
+
+#define MSC01E_INT_BASE 64
+
+#define MSC01E_INT_CPUCTR 11
+
+#endif
diff --git a/arch/mips/include/asm/mips_machine.h b/arch/mips/include/asm/mips_machine.h
new file mode 100644
index 00000000..363bb352
--- /dev/null
+++ b/arch/mips/include/asm/mips_machine.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_MIPS_MACHINE_H
+#define __ASM_MIPS_MACHINE_H
+
+#include <linux/init.h>
+#include <linux/stddef.h>
+
+#include <asm/bootinfo.h>
+
+struct mips_machine {
+ unsigned long mach_type;
+ const char *mach_id;
+ const char *mach_name;
+ void (*mach_setup)(void);
+};
+
+#define MIPS_MACHINE(_type, _id, _name, _setup) \
+static const char machine_name_##_type[] __initconst \
+ __aligned(1) = _name; \
+static const char machine_id_##_type[] __initconst \
+ __aligned(1) = _id; \
+static struct mips_machine machine_##_type \
+ __used __section(.mips.machines.init) = \
+{ \
+ .mach_type = _type, \
+ .mach_id = machine_id_##_type, \
+ .mach_name = machine_name_##_type, \
+ .mach_setup = _setup, \
+};
+
+extern long __mips_machines_start;
+extern long __mips_machines_end;
+
+#ifdef CONFIG_MIPS_MACHINE
+int mips_machtype_setup(char *id) __init;
+void mips_machine_setup(void) __init;
+void mips_set_machine_name(const char *name) __init;
+char *mips_get_machine_name(void);
+#else
+static inline int mips_machtype_setup(char *id) { return 1; }
+static inline void mips_machine_setup(void) { }
+static inline void mips_set_machine_name(const char *name) { }
+static inline char *mips_get_machine_name(void) { return NULL; }
+#endif /* CONFIG_MIPS_MACHINE */
+
+#endif /* __ASM_MIPS_MACHINE_H */
diff --git a/arch/mips/include/asm/mips_mt.h b/arch/mips/include/asm/mips_mt.h
new file mode 100644
index 00000000..ac793520
--- /dev/null
+++ b/arch/mips/include/asm/mips_mt.h
@@ -0,0 +1,26 @@
+/*
+ * Definitions and decalrations for MIPS MT support
+ * that are common between SMTC, VSMP, and/or AP/SP
+ * kernel models.
+ */
+#ifndef __ASM_MIPS_MT_H
+#define __ASM_MIPS_MT_H
+
+#include <linux/cpumask.h>
+
+/*
+ * How many VPEs and TCs is Linux allowed to use? 0 means no limit.
+ */
+extern int tclimit;
+extern int vpelimit;
+
+extern cpumask_t mt_fpu_cpumask;
+extern unsigned long mt_fpemul_threshold;
+
+extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value);
+extern void mips_mt_set_cpuoptions(void);
+
+struct class;
+extern struct class *mt_class;
+
+#endif /* __ASM_MIPS_MT_H */
diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h
new file mode 100644
index 00000000..c9420aa9
--- /dev/null
+++ b/arch/mips/include/asm/mipsmtregs.h
@@ -0,0 +1,395 @@
+/*
+ * MT regs definitions, follows on from mipsregs.h
+ * Copyright (C) 2004 - 2005 MIPS Technologies, Inc. All rights reserved.
+ * Elizabeth Clarke et. al.
+ *
+ */
+#ifndef _ASM_MIPSMTREGS_H
+#define _ASM_MIPSMTREGS_H
+
+#include <asm/mipsregs.h>
+#include <asm/war.h>
+
+#ifndef __ASSEMBLY__
+
+/*
+ * C macros
+ */
+
+#define read_c0_mvpcontrol() __read_32bit_c0_register($0, 1)
+#define write_c0_mvpcontrol(val) __write_32bit_c0_register($0, 1, val)
+
+#define read_c0_mvpconf0() __read_32bit_c0_register($0, 2)
+#define read_c0_mvpconf1() __read_32bit_c0_register($0, 3)
+
+#define read_c0_vpecontrol() __read_32bit_c0_register($1, 1)
+#define write_c0_vpecontrol(val) __write_32bit_c0_register($1, 1, val)
+
+#define read_c0_vpeconf0() __read_32bit_c0_register($1, 2)
+#define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val)
+
+#define read_c0_tcstatus() __read_32bit_c0_register($2, 1)
+#define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val)
+
+#define read_c0_tcbind() __read_32bit_c0_register($2, 2)
+
+#define read_c0_tccontext() __read_32bit_c0_register($2, 5)
+#define write_c0_tccontext(val) __write_32bit_c0_register($2, 5, val)
+
+#else /* Assembly */
+/*
+ * Macros for use in assembly language code
+ */
+
+#define CP0_MVPCONTROL $0, 1
+#define CP0_MVPCONF0 $0, 2
+#define CP0_MVPCONF1 $0, 3
+#define CP0_VPECONTROL $1, 1
+#define CP0_VPECONF0 $1, 2
+#define CP0_VPECONF1 $1, 3
+#define CP0_YQMASK $1, 4
+#define CP0_VPESCHEDULE $1, 5
+#define CP0_VPESCHEFBK $1, 6
+#define CP0_TCSTATUS $2, 1
+#define CP0_TCBIND $2, 2
+#define CP0_TCRESTART $2, 3
+#define CP0_TCHALT $2, 4
+#define CP0_TCCONTEXT $2, 5
+#define CP0_TCSCHEDULE $2, 6
+#define CP0_TCSCHEFBK $2, 7
+#define CP0_SRSCONF0 $6, 1
+#define CP0_SRSCONF1 $6, 2
+#define CP0_SRSCONF2 $6, 3
+#define CP0_SRSCONF3 $6, 4
+#define CP0_SRSCONF4 $6, 5
+
+#endif
+
+/* MVPControl fields */
+#define MVPCONTROL_EVP (_ULCAST_(1))
+
+#define MVPCONTROL_VPC_SHIFT 1
+#define MVPCONTROL_VPC (_ULCAST_(1) << MVPCONTROL_VPC_SHIFT)
+
+#define MVPCONTROL_STLB_SHIFT 2
+#define MVPCONTROL_STLB (_ULCAST_(1) << MVPCONTROL_STLB_SHIFT)
+
+
+/* MVPConf0 fields */
+#define MVPCONF0_PTC_SHIFT 0
+#define MVPCONF0_PTC ( _ULCAST_(0xff))
+#define MVPCONF0_PVPE_SHIFT 10
+#define MVPCONF0_PVPE ( _ULCAST_(0xf) << MVPCONF0_PVPE_SHIFT)
+#define MVPCONF0_TCA_SHIFT 15
+#define MVPCONF0_TCA ( _ULCAST_(1) << MVPCONF0_TCA_SHIFT)
+#define MVPCONF0_PTLBE_SHIFT 16
+#define MVPCONF0_PTLBE (_ULCAST_(0x3ff) << MVPCONF0_PTLBE_SHIFT)
+#define MVPCONF0_TLBS_SHIFT 29
+#define MVPCONF0_TLBS (_ULCAST_(1) << MVPCONF0_TLBS_SHIFT)
+#define MVPCONF0_M_SHIFT 31
+#define MVPCONF0_M (_ULCAST_(0x1) << MVPCONF0_M_SHIFT)
+
+
+/* config3 fields */
+#define CONFIG3_MT_SHIFT 2
+#define CONFIG3_MT (_ULCAST_(1) << CONFIG3_MT_SHIFT)
+
+
+/* VPEControl fields (per VPE) */
+#define VPECONTROL_TARGTC (_ULCAST_(0xff))
+
+#define VPECONTROL_TE_SHIFT 15
+#define VPECONTROL_TE (_ULCAST_(1) << VPECONTROL_TE_SHIFT)
+#define VPECONTROL_EXCPT_SHIFT 16
+#define VPECONTROL_EXCPT (_ULCAST_(0x7) << VPECONTROL_EXCPT_SHIFT)
+
+/* Thread Exception Codes for EXCPT field */
+#define THREX_TU 0
+#define THREX_TO 1
+#define THREX_IYQ 2
+#define THREX_GSX 3
+#define THREX_YSCH 4
+#define THREX_GSSCH 5
+
+#define VPECONTROL_GSI_SHIFT 20
+#define VPECONTROL_GSI (_ULCAST_(1) << VPECONTROL_GSI_SHIFT)
+#define VPECONTROL_YSI_SHIFT 21
+#define VPECONTROL_YSI (_ULCAST_(1) << VPECONTROL_YSI_SHIFT)
+
+/* VPEConf0 fields (per VPE) */
+#define VPECONF0_VPA_SHIFT 0
+#define VPECONF0_VPA (_ULCAST_(1) << VPECONF0_VPA_SHIFT)
+#define VPECONF0_MVP_SHIFT 1
+#define VPECONF0_MVP (_ULCAST_(1) << VPECONF0_MVP_SHIFT)
+#define VPECONF0_XTC_SHIFT 21
+#define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT)
+
+/* TCStatus fields (per TC) */
+#define TCSTATUS_TASID (_ULCAST_(0xff))
+#define TCSTATUS_IXMT_SHIFT 10
+#define TCSTATUS_IXMT (_ULCAST_(1) << TCSTATUS_IXMT_SHIFT)
+#define TCSTATUS_TKSU_SHIFT 11
+#define TCSTATUS_TKSU (_ULCAST_(3) << TCSTATUS_TKSU_SHIFT)
+#define TCSTATUS_A_SHIFT 13
+#define TCSTATUS_A (_ULCAST_(1) << TCSTATUS_A_SHIFT)
+#define TCSTATUS_DA_SHIFT 15
+#define TCSTATUS_DA (_ULCAST_(1) << TCSTATUS_DA_SHIFT)
+#define TCSTATUS_DT_SHIFT 20
+#define TCSTATUS_DT (_ULCAST_(1) << TCSTATUS_DT_SHIFT)
+#define TCSTATUS_TDS_SHIFT 21
+#define TCSTATUS_TDS (_ULCAST_(1) << TCSTATUS_TDS_SHIFT)
+#define TCSTATUS_TSST_SHIFT 22
+#define TCSTATUS_TSST (_ULCAST_(1) << TCSTATUS_TSST_SHIFT)
+#define TCSTATUS_RNST_SHIFT 23
+#define TCSTATUS_RNST (_ULCAST_(3) << TCSTATUS_RNST_SHIFT)
+/* Codes for RNST */
+#define TC_RUNNING 0
+#define TC_WAITING 1
+#define TC_YIELDING 2
+#define TC_GATED 3
+
+#define TCSTATUS_TMX_SHIFT 27
+#define TCSTATUS_TMX (_ULCAST_(1) << TCSTATUS_TMX_SHIFT)
+/* TCStatus TCU bits can use same definitions/offsets as CU bits in Status */
+
+/* TCBind */
+#define TCBIND_CURVPE_SHIFT 0
+#define TCBIND_CURVPE (_ULCAST_(0xf))
+
+#define TCBIND_CURTC_SHIFT 21
+
+#define TCBIND_CURTC (_ULCAST_(0xff) << TCBIND_CURTC_SHIFT)
+
+/* TCHalt */
+#define TCHALT_H (_ULCAST_(1))
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned int dvpe(void)
+{
+ int res = 0;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " .set mips32r2 \n"
+ " .word 0x41610001 # dvpe $1 \n"
+ " move %0, $1 \n"
+ " ehb \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+
+ return res;
+}
+
+static inline void __raw_evpe(void)
+{
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " .set mips32r2 \n"
+ " .word 0x41600021 # evpe \n"
+ " ehb \n"
+ " .set pop \n");
+}
+
+/* Enable virtual processor execution if previous suggested it should be.
+ EVPE_ENABLE to force */
+
+#define EVPE_ENABLE MVPCONTROL_EVP
+
+static inline void evpe(int previous)
+{
+ if ((previous & MVPCONTROL_EVP))
+ __raw_evpe();
+}
+
+static inline unsigned int dmt(void)
+{
+ int res;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips32r2 \n"
+ " .set noat \n"
+ " .word 0x41610BC1 # dmt $1 \n"
+ " ehb \n"
+ " move %0, $1 \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+
+ return res;
+}
+
+static inline void __raw_emt(void)
+{
+ __asm__ __volatile__(
+ " .set noreorder \n"
+ " .set mips32r2 \n"
+ " .word 0x41600be1 # emt \n"
+ " ehb \n"
+ " .set mips0 \n"
+ " .set reorder");
+}
+
+/* enable multi-threaded execution if previous suggested it should be.
+ EMT_ENABLE to force */
+
+#define EMT_ENABLE VPECONTROL_TE
+
+static inline void emt(int previous)
+{
+ if ((previous & EMT_ENABLE))
+ __raw_emt();
+}
+
+static inline void ehb(void)
+{
+ __asm__ __volatile__(
+ " .set mips32r2 \n"
+ " ehb \n"
+ " .set mips0 \n");
+}
+
+#define mftc0(rt,sel) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " # mftc0 $1, $" #rt ", " #sel " \n" \
+ " .word 0x41000800 | (" #rt " << 16) | " #sel " \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mftgpr(rt) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set mips32r2 \n" \
+ " # mftgpr $1," #rt " \n" \
+ " .word 0x41000820 | (" #rt " << 16) \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mftr(rt, u, sel) \
+({ \
+ unsigned long __res; \
+ \
+ __asm__ __volatile__( \
+ " mftr %0, " #rt ", " #u ", " #sel " \n" \
+ : "=r" (__res)); \
+ \
+ __res; \
+})
+
+#define mttgpr(rd,v) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mttgpr $1, " #rd " \n" \
+ " .word 0x41810020 | (" #rd " << 11) \n" \
+ " .set pop \n" \
+ : : "r" (v)); \
+} while (0)
+
+#define mttc0(rd, sel, v) \
+({ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips32r2 \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mttc0 %0," #rd ", " #sel " \n" \
+ " .word 0x41810000 | (" #rd " << 11) | " #sel " \n" \
+ " .set pop \n" \
+ : \
+ : "r" (v)); \
+})
+
+
+#define mttr(rd, u, sel, v) \
+({ \
+ __asm__ __volatile__( \
+ "mttr %0," #rd ", " #u ", " #sel \
+ : : "r" (v)); \
+})
+
+
+#define settc(tc) \
+do { \
+ write_c0_vpecontrol((read_c0_vpecontrol()&~VPECONTROL_TARGTC) | (tc)); \
+ ehb(); \
+} while (0)
+
+
+/* you *must* set the target tc (settc) before trying to use these */
+#define read_vpe_c0_vpecontrol() mftc0(1, 1)
+#define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val)
+#define read_vpe_c0_vpeconf0() mftc0(1, 2)
+#define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
+#define read_vpe_c0_count() mftc0(9, 0)
+#define write_vpe_c0_count(val) mttc0(9, 0, val)
+#define read_vpe_c0_status() mftc0(12, 0)
+#define write_vpe_c0_status(val) mttc0(12, 0, val)
+#define read_vpe_c0_cause() mftc0(13, 0)
+#define write_vpe_c0_cause(val) mttc0(13, 0, val)
+#define read_vpe_c0_config() mftc0(16, 0)
+#define write_vpe_c0_config(val) mttc0(16, 0, val)
+#define read_vpe_c0_config1() mftc0(16, 1)
+#define write_vpe_c0_config1(val) mttc0(16, 1, val)
+#define read_vpe_c0_config7() mftc0(16, 7)
+#define write_vpe_c0_config7(val) mttc0(16, 7, val)
+#define read_vpe_c0_ebase() mftc0(15, 1)
+#define write_vpe_c0_ebase(val) mttc0(15, 1, val)
+#define write_vpe_c0_compare(val) mttc0(11, 0, val)
+#define read_vpe_c0_badvaddr() mftc0(8, 0)
+#define read_vpe_c0_epc() mftc0(14, 0)
+#define write_vpe_c0_epc(val) mttc0(14, 0, val)
+
+
+/* TC */
+#define read_tc_c0_tcstatus() mftc0(2, 1)
+#define write_tc_c0_tcstatus(val) mttc0(2, 1, val)
+#define read_tc_c0_tcbind() mftc0(2, 2)
+#define write_tc_c0_tcbind(val) mttc0(2, 2, val)
+#define read_tc_c0_tcrestart() mftc0(2, 3)
+#define write_tc_c0_tcrestart(val) mttc0(2, 3, val)
+#define read_tc_c0_tchalt() mftc0(2, 4)
+#define write_tc_c0_tchalt(val) mttc0(2, 4, val)
+#define read_tc_c0_tccontext() mftc0(2, 5)
+#define write_tc_c0_tccontext(val) mttc0(2, 5, val)
+
+/* GPR */
+#define read_tc_gpr_sp() mftgpr(29)
+#define write_tc_gpr_sp(val) mttgpr(29, val)
+#define read_tc_gpr_gp() mftgpr(28)
+#define write_tc_gpr_gp(val) mttgpr(28, val)
+
+__BUILD_SET_C0(mvpcontrol)
+
+#endif /* Not __ASSEMBLY__ */
+
+#endif
diff --git a/arch/mips/include/asm/mipsprom.h b/arch/mips/include/asm/mipsprom.h
new file mode 100644
index 00000000..146d41b6
--- /dev/null
+++ b/arch/mips/include/asm/mipsprom.h
@@ -0,0 +1,76 @@
+#ifndef __ASM_MIPS_PROM_H
+#define __ASM_MIPS_PROM_H
+
+#define PROM_RESET 0
+#define PROM_EXEC 1
+#define PROM_RESTART 2
+#define PROM_REINIT 3
+#define PROM_REBOOT 4
+#define PROM_AUTOBOOT 5
+#define PROM_OPEN 6
+#define PROM_READ 7
+#define PROM_WRITE 8
+#define PROM_IOCTL 9
+#define PROM_CLOSE 10
+#define PROM_GETCHAR 11
+#define PROM_PUTCHAR 12
+#define PROM_SHOWCHAR 13 /* XXX */
+#define PROM_GETS 14 /* XXX */
+#define PROM_PUTS 15 /* XXX */
+#define PROM_PRINTF 16 /* XXX */
+
+/* What are these for? */
+#define PROM_INITPROTO 17 /* XXX */
+#define PROM_PROTOENABLE 18 /* XXX */
+#define PROM_PROTODISABLE 19 /* XXX */
+#define PROM_GETPKT 20 /* XXX */
+#define PROM_PUTPKT 21 /* XXX */
+
+/* More PROM shit. Probably has to do with VME RMW cycles??? */
+#define PROM_ORW_RMW 22 /* XXX */
+#define PROM_ORH_RMW 23 /* XXX */
+#define PROM_ORB_RMW 24 /* XXX */
+#define PROM_ANDW_RMW 25 /* XXX */
+#define PROM_ANDH_RMW 26 /* XXX */
+#define PROM_ANDB_RMW 27 /* XXX */
+
+/* Cache handling stuff */
+#define PROM_FLUSHCACHE 28 /* XXX */
+#define PROM_CLEARCACHE 29 /* XXX */
+
+/* Libc alike stuff */
+#define PROM_SETJMP 30 /* XXX */
+#define PROM_LONGJMP 31 /* XXX */
+#define PROM_BEVUTLB 32 /* XXX */
+#define PROM_GETENV 33 /* XXX */
+#define PROM_SETENV 34 /* XXX */
+#define PROM_ATOB 35 /* XXX */
+#define PROM_STRCMP 36 /* XXX */
+#define PROM_STRLEN 37 /* XXX */
+#define PROM_STRCPY 38 /* XXX */
+#define PROM_STRCAT 39 /* XXX */
+
+/* Misc stuff */
+#define PROM_PARSER 40 /* XXX */
+#define PROM_RANGE 41 /* XXX */
+#define PROM_ARGVIZE 42 /* XXX */
+#define PROM_HELP 43 /* XXX */
+
+/* Entry points for some PROM commands */
+#define PROM_DUMPCMD 44 /* XXX */
+#define PROM_SETENVCMD 45 /* XXX */
+#define PROM_UNSETENVCMD 46 /* XXX */
+#define PROM_PRINTENVCMD 47 /* XXX */
+#define PROM_BEVEXCEPT 48 /* XXX */
+#define PROM_ENABLECMD 49 /* XXX */
+#define PROM_DISABLECMD 50 /* XXX */
+
+#define PROM_CLEARNOFAULT 51 /* XXX */
+#define PROM_NOTIMPLEMENT 52 /* XXX */
+
+#define PROM_NV_GET 53 /* XXX */
+#define PROM_NV_SET 54 /* XXX */
+
+extern char *prom_getenv(char *);
+
+#endif /* __ASM_MIPS_PROM_H */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
new file mode 100644
index 00000000..6a6f8a8f
--- /dev/null
+++ b/arch/mips/include/asm/mipsregs.h
@@ -0,0 +1,1665 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Modified for further R[236]000 support by Paul M. Antoine, 1996.
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000, 07 MIPS Technologies, Inc.
+ * Copyright (C) 2003, 2004 Maciej W. Rozycki
+ */
+#ifndef _ASM_MIPSREGS_H
+#define _ASM_MIPSREGS_H
+
+#include <linux/linkage.h>
+#include <asm/hazards.h>
+#include <asm/war.h>
+
+/*
+ * The following macros are especially useful for __asm__
+ * inline assembler.
+ */
+#ifndef __STR
+#define __STR(x) #x
+#endif
+#ifndef STR
+#define STR(x) __STR(x)
+#endif
+
+/*
+ * Configure language
+ */
+#ifdef __ASSEMBLY__
+#define _ULCAST_
+#else
+#define _ULCAST_ (unsigned long)
+#endif
+
+/*
+ * Coprocessor 0 register names
+ */
+#define CP0_INDEX $0
+#define CP0_RANDOM $1
+#define CP0_ENTRYLO0 $2
+#define CP0_ENTRYLO1 $3
+#define CP0_CONF $3
+#define CP0_CONTEXT $4
+#define CP0_PAGEMASK $5
+#define CP0_WIRED $6
+#define CP0_INFO $7
+#define CP0_BADVADDR $8
+#define CP0_COUNT $9
+#define CP0_ENTRYHI $10
+#define CP0_COMPARE $11
+#define CP0_STATUS $12
+#define CP0_CAUSE $13
+#define CP0_EPC $14
+#define CP0_PRID $15
+#define CP0_CONFIG $16
+#define CP0_LLADDR $17
+#define CP0_WATCHLO $18
+#define CP0_WATCHHI $19
+#define CP0_XCONTEXT $20
+#define CP0_FRAMEMASK $21
+#define CP0_DIAGNOSTIC $22
+#define CP0_DEBUG $23
+#define CP0_DEPC $24
+#define CP0_PERFORMANCE $25
+#define CP0_ECC $26
+#define CP0_CACHEERR $27
+#define CP0_TAGLO $28
+#define CP0_TAGHI $29
+#define CP0_ERROREPC $30
+#define CP0_DESAVE $31
+
+/*
+ * R4640/R4650 cp0 register names. These registers are listed
+ * here only for completeness; without MMU these CPUs are not useable
+ * by Linux. A future ELKS port might take make Linux run on them
+ * though ...
+ */
+#define CP0_IBASE $0
+#define CP0_IBOUND $1
+#define CP0_DBASE $2
+#define CP0_DBOUND $3
+#define CP0_CALG $17
+#define CP0_IWATCH $18
+#define CP0_DWATCH $19
+
+/*
+ * Coprocessor 0 Set 1 register names
+ */
+#define CP0_S1_DERRADDR0 $26
+#define CP0_S1_DERRADDR1 $27
+#define CP0_S1_INTCONTROL $20
+
+/*
+ * Coprocessor 0 Set 2 register names
+ */
+#define CP0_S2_SRSCTL $12 /* MIPSR2 */
+
+/*
+ * Coprocessor 0 Set 3 register names
+ */
+#define CP0_S3_SRSMAP $12 /* MIPSR2 */
+
+/*
+ * TX39 Series
+ */
+#define CP0_TX39_CACHE $7
+
+/*
+ * Coprocessor 1 (FPU) register names
+ */
+#define CP1_REVISION $0
+#define CP1_STATUS $31
+
+/*
+ * FPU Status Register Values
+ */
+/*
+ * Status Register Values
+ */
+
+#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
+#define FPU_CSR_COND 0x00800000 /* $fcc0 */
+#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
+#define FPU_CSR_COND1 0x02000000 /* $fcc1 */
+#define FPU_CSR_COND2 0x04000000 /* $fcc2 */
+#define FPU_CSR_COND3 0x08000000 /* $fcc3 */
+#define FPU_CSR_COND4 0x10000000 /* $fcc4 */
+#define FPU_CSR_COND5 0x20000000 /* $fcc5 */
+#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
+#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
+
+/*
+ * Bits 18 - 20 of the FPU Status Register will be read as 0,
+ * and should be written as zero.
+ */
+#define FPU_CSR_RSVD 0x001c0000
+
+/*
+ * X the exception cause indicator
+ * E the exception enable
+ * S the sticky/flag bit
+*/
+#define FPU_CSR_ALL_X 0x0003f000
+#define FPU_CSR_UNI_X 0x00020000
+#define FPU_CSR_INV_X 0x00010000
+#define FPU_CSR_DIV_X 0x00008000
+#define FPU_CSR_OVF_X 0x00004000
+#define FPU_CSR_UDF_X 0x00002000
+#define FPU_CSR_INE_X 0x00001000
+
+#define FPU_CSR_ALL_E 0x00000f80
+#define FPU_CSR_INV_E 0x00000800
+#define FPU_CSR_DIV_E 0x00000400
+#define FPU_CSR_OVF_E 0x00000200
+#define FPU_CSR_UDF_E 0x00000100
+#define FPU_CSR_INE_E 0x00000080
+
+#define FPU_CSR_ALL_S 0x0000007c
+#define FPU_CSR_INV_S 0x00000040
+#define FPU_CSR_DIV_S 0x00000020
+#define FPU_CSR_OVF_S 0x00000010
+#define FPU_CSR_UDF_S 0x00000008
+#define FPU_CSR_INE_S 0x00000004
+
+/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
+#define FPU_CSR_RM 0x00000003
+#define FPU_CSR_RN 0x0 /* nearest */
+#define FPU_CSR_RZ 0x1 /* towards zero */
+#define FPU_CSR_RU 0x2 /* towards +Infinity */
+#define FPU_CSR_RD 0x3 /* towards -Infinity */
+
+
+/*
+ * Values for PageMask register
+ */
+#ifdef CONFIG_CPU_VR41XX
+
+/* Why doesn't stupidity hurt ... */
+
+#define PM_1K 0x00000000
+#define PM_4K 0x00001800
+#define PM_16K 0x00007800
+#define PM_64K 0x0001f800
+#define PM_256K 0x0007f800
+
+#else
+
+#define PM_4K 0x00000000
+#define PM_8K 0x00002000
+#define PM_16K 0x00006000
+#define PM_32K 0x0000e000
+#define PM_64K 0x0001e000
+#define PM_128K 0x0003e000
+#define PM_256K 0x0007e000
+#define PM_512K 0x000fe000
+#define PM_1M 0x001fe000
+#define PM_2M 0x003fe000
+#define PM_4M 0x007fe000
+#define PM_8M 0x00ffe000
+#define PM_16M 0x01ffe000
+#define PM_32M 0x03ffe000
+#define PM_64M 0x07ffe000
+#define PM_256M 0x1fffe000
+#define PM_1G 0x7fffe000
+
+#endif
+
+/*
+ * Default page size for a given kernel configuration
+ */
+#ifdef CONFIG_PAGE_SIZE_4KB
+#define PM_DEFAULT_MASK PM_4K
+#elif defined(CONFIG_PAGE_SIZE_8KB)
+#define PM_DEFAULT_MASK PM_8K
+#elif defined(CONFIG_PAGE_SIZE_16KB)
+#define PM_DEFAULT_MASK PM_16K
+#elif defined(CONFIG_PAGE_SIZE_32KB)
+#define PM_DEFAULT_MASK PM_32K
+#elif defined(CONFIG_PAGE_SIZE_64KB)
+#define PM_DEFAULT_MASK PM_64K
+#else
+#error Bad page size configuration!
+#endif
+
+/*
+ * Default huge tlb size for a given kernel configuration
+ */
+#ifdef CONFIG_PAGE_SIZE_4KB
+#define PM_HUGE_MASK PM_1M
+#elif defined(CONFIG_PAGE_SIZE_8KB)
+#define PM_HUGE_MASK PM_4M
+#elif defined(CONFIG_PAGE_SIZE_16KB)
+#define PM_HUGE_MASK PM_16M
+#elif defined(CONFIG_PAGE_SIZE_32KB)
+#define PM_HUGE_MASK PM_64M
+#elif defined(CONFIG_PAGE_SIZE_64KB)
+#define PM_HUGE_MASK PM_256M
+#elif defined(CONFIG_HUGETLB_PAGE)
+#error Bad page size configuration for hugetlbfs!
+#endif
+
+/*
+ * Values used for computation of new tlb entries
+ */
+#define PL_4K 12
+#define PL_16K 14
+#define PL_64K 16
+#define PL_256K 18
+#define PL_1M 20
+#define PL_4M 22
+#define PL_16M 24
+#define PL_64M 26
+#define PL_256M 28
+
+/*
+ * PageGrain bits
+ */
+#define PG_RIE (_ULCAST_(1) << 31)
+#define PG_XIE (_ULCAST_(1) << 30)
+#define PG_ELPA (_ULCAST_(1) << 29)
+#define PG_ESP (_ULCAST_(1) << 28)
+
+/*
+ * R4x00 interrupt enable / cause bits
+ */
+#define IE_SW0 (_ULCAST_(1) << 8)
+#define IE_SW1 (_ULCAST_(1) << 9)
+#define IE_IRQ0 (_ULCAST_(1) << 10)
+#define IE_IRQ1 (_ULCAST_(1) << 11)
+#define IE_IRQ2 (_ULCAST_(1) << 12)
+#define IE_IRQ3 (_ULCAST_(1) << 13)
+#define IE_IRQ4 (_ULCAST_(1) << 14)
+#define IE_IRQ5 (_ULCAST_(1) << 15)
+
+/*
+ * R4x00 interrupt cause bits
+ */
+#define C_SW0 (_ULCAST_(1) << 8)
+#define C_SW1 (_ULCAST_(1) << 9)
+#define C_IRQ0 (_ULCAST_(1) << 10)
+#define C_IRQ1 (_ULCAST_(1) << 11)
+#define C_IRQ2 (_ULCAST_(1) << 12)
+#define C_IRQ3 (_ULCAST_(1) << 13)
+#define C_IRQ4 (_ULCAST_(1) << 14)
+#define C_IRQ5 (_ULCAST_(1) << 15)
+
+/*
+ * Bitfields in the R4xx0 cp0 status register
+ */
+#define ST0_IE 0x00000001
+#define ST0_EXL 0x00000002
+#define ST0_ERL 0x00000004
+#define ST0_KSU 0x00000018
+# define KSU_USER 0x00000010
+# define KSU_SUPERVISOR 0x00000008
+# define KSU_KERNEL 0x00000000
+#define ST0_UX 0x00000020
+#define ST0_SX 0x00000040
+#define ST0_KX 0x00000080
+#define ST0_DE 0x00010000
+#define ST0_CE 0x00020000
+
+/*
+ * Setting c0_status.co enables Hit_Writeback and Hit_Writeback_Invalidate
+ * cacheops in userspace. This bit exists only on RM7000 and RM9000
+ * processors.
+ */
+#define ST0_CO 0x08000000
+
+/*
+ * Bitfields in the R[23]000 cp0 status register.
+ */
+#define ST0_IEC 0x00000001
+#define ST0_KUC 0x00000002
+#define ST0_IEP 0x00000004
+#define ST0_KUP 0x00000008
+#define ST0_IEO 0x00000010
+#define ST0_KUO 0x00000020
+/* bits 6 & 7 are reserved on R[23]000 */
+#define ST0_ISC 0x00010000
+#define ST0_SWC 0x00020000
+#define ST0_CM 0x00080000
+
+/*
+ * Bits specific to the R4640/R4650
+ */
+#define ST0_UM (_ULCAST_(1) << 4)
+#define ST0_IL (_ULCAST_(1) << 23)
+#define ST0_DL (_ULCAST_(1) << 24)
+
+/*
+ * Enable the MIPS MDMX and DSP ASEs
+ */
+#define ST0_MX 0x01000000
+
+/*
+ * Bitfields in the TX39 family CP0 Configuration Register 3
+ */
+#define TX39_CONF_ICS_SHIFT 19
+#define TX39_CONF_ICS_MASK 0x00380000
+#define TX39_CONF_ICS_1KB 0x00000000
+#define TX39_CONF_ICS_2KB 0x00080000
+#define TX39_CONF_ICS_4KB 0x00100000
+#define TX39_CONF_ICS_8KB 0x00180000
+#define TX39_CONF_ICS_16KB 0x00200000
+
+#define TX39_CONF_DCS_SHIFT 16
+#define TX39_CONF_DCS_MASK 0x00070000
+#define TX39_CONF_DCS_1KB 0x00000000
+#define TX39_CONF_DCS_2KB 0x00010000
+#define TX39_CONF_DCS_4KB 0x00020000
+#define TX39_CONF_DCS_8KB 0x00030000
+#define TX39_CONF_DCS_16KB 0x00040000
+
+#define TX39_CONF_CWFON 0x00004000
+#define TX39_CONF_WBON 0x00002000
+#define TX39_CONF_RF_SHIFT 10
+#define TX39_CONF_RF_MASK 0x00000c00
+#define TX39_CONF_DOZE 0x00000200
+#define TX39_CONF_HALT 0x00000100
+#define TX39_CONF_LOCK 0x00000080
+#define TX39_CONF_ICE 0x00000020
+#define TX39_CONF_DCE 0x00000010
+#define TX39_CONF_IRSIZE_SHIFT 2
+#define TX39_CONF_IRSIZE_MASK 0x0000000c
+#define TX39_CONF_DRSIZE_SHIFT 0
+#define TX39_CONF_DRSIZE_MASK 0x00000003
+
+/*
+ * Status register bits available in all MIPS CPUs.
+ */
+#define ST0_IM 0x0000ff00
+#define STATUSB_IP0 8
+#define STATUSF_IP0 (_ULCAST_(1) << 8)
+#define STATUSB_IP1 9
+#define STATUSF_IP1 (_ULCAST_(1) << 9)
+#define STATUSB_IP2 10
+#define STATUSF_IP2 (_ULCAST_(1) << 10)
+#define STATUSB_IP3 11
+#define STATUSF_IP3 (_ULCAST_(1) << 11)
+#define STATUSB_IP4 12
+#define STATUSF_IP4 (_ULCAST_(1) << 12)
+#define STATUSB_IP5 13
+#define STATUSF_IP5 (_ULCAST_(1) << 13)
+#define STATUSB_IP6 14
+#define STATUSF_IP6 (_ULCAST_(1) << 14)
+#define STATUSB_IP7 15
+#define STATUSF_IP7 (_ULCAST_(1) << 15)
+#define STATUSB_IP8 0
+#define STATUSF_IP8 (_ULCAST_(1) << 0)
+#define STATUSB_IP9 1
+#define STATUSF_IP9 (_ULCAST_(1) << 1)
+#define STATUSB_IP10 2
+#define STATUSF_IP10 (_ULCAST_(1) << 2)
+#define STATUSB_IP11 3
+#define STATUSF_IP11 (_ULCAST_(1) << 3)
+#define STATUSB_IP12 4
+#define STATUSF_IP12 (_ULCAST_(1) << 4)
+#define STATUSB_IP13 5
+#define STATUSF_IP13 (_ULCAST_(1) << 5)
+#define STATUSB_IP14 6
+#define STATUSF_IP14 (_ULCAST_(1) << 6)
+#define STATUSB_IP15 7
+#define STATUSF_IP15 (_ULCAST_(1) << 7)
+#define ST0_CH 0x00040000
+#define ST0_NMI 0x00080000
+#define ST0_SR 0x00100000
+#define ST0_TS 0x00200000
+#define ST0_BEV 0x00400000
+#define ST0_RE 0x02000000
+#define ST0_FR 0x04000000
+#define ST0_CU 0xf0000000
+#define ST0_CU0 0x10000000
+#define ST0_CU1 0x20000000
+#define ST0_CU2 0x40000000
+#define ST0_CU3 0x80000000
+#define ST0_XX 0x80000000 /* MIPS IV naming */
+
+/*
+ * Bitfields and bit numbers in the coprocessor 0 IntCtl register. (MIPSR2)
+ *
+ * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
+ */
+#define INTCTLB_IPPCI 26
+#define INTCTLF_IPPCI (_ULCAST_(7) << INTCTLB_IPPCI)
+#define INTCTLB_IPTI 29
+#define INTCTLF_IPTI (_ULCAST_(7) << INTCTLB_IPTI)
+
+/*
+ * Bitfields and bit numbers in the coprocessor 0 cause register.
+ *
+ * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
+ */
+#define CAUSEB_EXCCODE 2
+#define CAUSEF_EXCCODE (_ULCAST_(31) << 2)
+#define CAUSEB_IP 8
+#define CAUSEF_IP (_ULCAST_(255) << 8)
+#define CAUSEB_IP0 8
+#define CAUSEF_IP0 (_ULCAST_(1) << 8)
+#define CAUSEB_IP1 9
+#define CAUSEF_IP1 (_ULCAST_(1) << 9)
+#define CAUSEB_IP2 10
+#define CAUSEF_IP2 (_ULCAST_(1) << 10)
+#define CAUSEB_IP3 11
+#define CAUSEF_IP3 (_ULCAST_(1) << 11)
+#define CAUSEB_IP4 12
+#define CAUSEF_IP4 (_ULCAST_(1) << 12)
+#define CAUSEB_IP5 13
+#define CAUSEF_IP5 (_ULCAST_(1) << 13)
+#define CAUSEB_IP6 14
+#define CAUSEF_IP6 (_ULCAST_(1) << 14)
+#define CAUSEB_IP7 15
+#define CAUSEF_IP7 (_ULCAST_(1) << 15)
+#define CAUSEB_IV 23
+#define CAUSEF_IV (_ULCAST_(1) << 23)
+#define CAUSEB_CE 28
+#define CAUSEF_CE (_ULCAST_(3) << 28)
+#define CAUSEB_TI 30
+#define CAUSEF_TI (_ULCAST_(1) << 30)
+#define CAUSEB_BD 31
+#define CAUSEF_BD (_ULCAST_(1) << 31)
+
+/*
+ * Bits in the coprocessor 0 config register.
+ */
+/* Generic bits. */
+#define CONF_CM_CACHABLE_NO_WA 0
+#define CONF_CM_CACHABLE_WA 1
+#define CONF_CM_UNCACHED 2
+#define CONF_CM_CACHABLE_NONCOHERENT 3
+#define CONF_CM_CACHABLE_CE 4
+#define CONF_CM_CACHABLE_COW 5
+#define CONF_CM_CACHABLE_CUW 6
+#define CONF_CM_CACHABLE_ACCELERATED 7
+#define CONF_CM_CMASK 7
+#define CONF_BE (_ULCAST_(1) << 15)
+
+/* Bits common to various processors. */
+#define CONF_CU (_ULCAST_(1) << 3)
+#define CONF_DB (_ULCAST_(1) << 4)
+#define CONF_IB (_ULCAST_(1) << 5)
+#define CONF_DC (_ULCAST_(7) << 6)
+#define CONF_IC (_ULCAST_(7) << 9)
+#define CONF_EB (_ULCAST_(1) << 13)
+#define CONF_EM (_ULCAST_(1) << 14)
+#define CONF_SM (_ULCAST_(1) << 16)
+#define CONF_SC (_ULCAST_(1) << 17)
+#define CONF_EW (_ULCAST_(3) << 18)
+#define CONF_EP (_ULCAST_(15)<< 24)
+#define CONF_EC (_ULCAST_(7) << 28)
+#define CONF_CM (_ULCAST_(1) << 31)
+
+/* Bits specific to the R4xx0. */
+#define R4K_CONF_SW (_ULCAST_(1) << 20)
+#define R4K_CONF_SS (_ULCAST_(1) << 21)
+#define R4K_CONF_SB (_ULCAST_(3) << 22)
+
+/* Bits specific to the R5000. */
+#define R5K_CONF_SE (_ULCAST_(1) << 12)
+#define R5K_CONF_SS (_ULCAST_(3) << 20)
+
+/* Bits specific to the RM7000. */
+#define RM7K_CONF_SE (_ULCAST_(1) << 3)
+#define RM7K_CONF_TE (_ULCAST_(1) << 12)
+#define RM7K_CONF_CLK (_ULCAST_(1) << 16)
+#define RM7K_CONF_TC (_ULCAST_(1) << 17)
+#define RM7K_CONF_SI (_ULCAST_(3) << 20)
+#define RM7K_CONF_SC (_ULCAST_(1) << 31)
+
+/* Bits specific to the R10000. */
+#define R10K_CONF_DN (_ULCAST_(3) << 3)
+#define R10K_CONF_CT (_ULCAST_(1) << 5)
+#define R10K_CONF_PE (_ULCAST_(1) << 6)
+#define R10K_CONF_PM (_ULCAST_(3) << 7)
+#define R10K_CONF_EC (_ULCAST_(15)<< 9)
+#define R10K_CONF_SB (_ULCAST_(1) << 13)
+#define R10K_CONF_SK (_ULCAST_(1) << 14)
+#define R10K_CONF_SS (_ULCAST_(7) << 16)
+#define R10K_CONF_SC (_ULCAST_(7) << 19)
+#define R10K_CONF_DC (_ULCAST_(7) << 26)
+#define R10K_CONF_IC (_ULCAST_(7) << 29)
+
+/* Bits specific to the VR41xx. */
+#define VR41_CONF_CS (_ULCAST_(1) << 12)
+#define VR41_CONF_P4K (_ULCAST_(1) << 13)
+#define VR41_CONF_BP (_ULCAST_(1) << 16)
+#define VR41_CONF_M16 (_ULCAST_(1) << 20)
+#define VR41_CONF_AD (_ULCAST_(1) << 23)
+
+/* Bits specific to the R30xx. */
+#define R30XX_CONF_FDM (_ULCAST_(1) << 19)
+#define R30XX_CONF_REV (_ULCAST_(1) << 22)
+#define R30XX_CONF_AC (_ULCAST_(1) << 23)
+#define R30XX_CONF_RF (_ULCAST_(1) << 24)
+#define R30XX_CONF_HALT (_ULCAST_(1) << 25)
+#define R30XX_CONF_FPINT (_ULCAST_(7) << 26)
+#define R30XX_CONF_DBR (_ULCAST_(1) << 29)
+#define R30XX_CONF_SB (_ULCAST_(1) << 30)
+#define R30XX_CONF_LOCK (_ULCAST_(1) << 31)
+
+/* Bits specific to the TX49. */
+#define TX49_CONF_DC (_ULCAST_(1) << 16)
+#define TX49_CONF_IC (_ULCAST_(1) << 17) /* conflict with CONF_SC */
+#define TX49_CONF_HALT (_ULCAST_(1) << 18)
+#define TX49_CONF_CWFON (_ULCAST_(1) << 27)
+
+/* Bits specific to the MIPS32/64 PRA. */
+#define MIPS_CONF_MT (_ULCAST_(7) << 7)
+#define MIPS_CONF_AR (_ULCAST_(7) << 10)
+#define MIPS_CONF_AT (_ULCAST_(3) << 13)
+#define MIPS_CONF_M (_ULCAST_(1) << 31)
+
+/*
+ * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above.
+ */
+#define MIPS_CONF1_FP (_ULCAST_(1) << 0)
+#define MIPS_CONF1_EP (_ULCAST_(1) << 1)
+#define MIPS_CONF1_CA (_ULCAST_(1) << 2)
+#define MIPS_CONF1_WR (_ULCAST_(1) << 3)
+#define MIPS_CONF1_PC (_ULCAST_(1) << 4)
+#define MIPS_CONF1_MD (_ULCAST_(1) << 5)
+#define MIPS_CONF1_C2 (_ULCAST_(1) << 6)
+#define MIPS_CONF1_DA (_ULCAST_(7) << 7)
+#define MIPS_CONF1_DL (_ULCAST_(7) << 10)
+#define MIPS_CONF1_DS (_ULCAST_(7) << 13)
+#define MIPS_CONF1_IA (_ULCAST_(7) << 16)
+#define MIPS_CONF1_IL (_ULCAST_(7) << 19)
+#define MIPS_CONF1_IS (_ULCAST_(7) << 22)
+#define MIPS_CONF1_TLBS (_ULCAST_(63)<< 25)
+
+#define MIPS_CONF2_SA (_ULCAST_(15)<< 0)
+#define MIPS_CONF2_SL (_ULCAST_(15)<< 4)
+#define MIPS_CONF2_SS (_ULCAST_(15)<< 8)
+#define MIPS_CONF2_SU (_ULCAST_(15)<< 12)
+#define MIPS_CONF2_TA (_ULCAST_(15)<< 16)
+#define MIPS_CONF2_TL (_ULCAST_(15)<< 20)
+#define MIPS_CONF2_TS (_ULCAST_(15)<< 24)
+#define MIPS_CONF2_TU (_ULCAST_(7) << 28)
+
+#define MIPS_CONF3_TL (_ULCAST_(1) << 0)
+#define MIPS_CONF3_SM (_ULCAST_(1) << 1)
+#define MIPS_CONF3_MT (_ULCAST_(1) << 2)
+#define MIPS_CONF3_SP (_ULCAST_(1) << 4)
+#define MIPS_CONF3_VINT (_ULCAST_(1) << 5)
+#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6)
+#define MIPS_CONF3_LPA (_ULCAST_(1) << 7)
+#define MIPS_CONF3_DSP (_ULCAST_(1) << 10)
+#define MIPS_CONF3_ULRI (_ULCAST_(1) << 13)
+
+#define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0)
+#define MIPS_CONF4_MMUEXTDEF (_ULCAST_(3) << 14)
+#define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14)
+
+#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
+
+#define MIPS_CONF7_RPS (_ULCAST_(1) << 2)
+
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
+ */
+#define MIPS_FPIR_S (_ULCAST_(1) << 16)
+#define MIPS_FPIR_D (_ULCAST_(1) << 17)
+#define MIPS_FPIR_PS (_ULCAST_(1) << 18)
+#define MIPS_FPIR_3D (_ULCAST_(1) << 19)
+#define MIPS_FPIR_W (_ULCAST_(1) << 20)
+#define MIPS_FPIR_L (_ULCAST_(1) << 21)
+#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Functions to access the R10000 performance counters. These are basically
+ * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
+ * performance counter number encoded into bits 1 ... 5 of the instruction.
+ * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware
+ * disassembler these will look like an access to sel 0 or 1.
+ */
+#define read_r10k_perf_cntr(counter) \
+({ \
+ unsigned int __res; \
+ __asm__ __volatile__( \
+ "mfpc\t%0, %1" \
+ : "=r" (__res) \
+ : "i" (counter)); \
+ \
+ __res; \
+})
+
+#define write_r10k_perf_cntr(counter,val) \
+do { \
+ __asm__ __volatile__( \
+ "mtpc\t%0, %1" \
+ : \
+ : "r" (val), "i" (counter)); \
+} while (0)
+
+#define read_r10k_perf_event(counter) \
+({ \
+ unsigned int __res; \
+ __asm__ __volatile__( \
+ "mfps\t%0, %1" \
+ : "=r" (__res) \
+ : "i" (counter)); \
+ \
+ __res; \
+})
+
+#define write_r10k_perf_cntl(counter,val) \
+do { \
+ __asm__ __volatile__( \
+ "mtps\t%0, %1" \
+ : \
+ : "r" (val), "i" (counter)); \
+} while (0)
+
+
+/*
+ * Macros to access the system control coprocessor
+ */
+
+#define __read_32bit_c0_register(source, sel) \
+({ int __res; \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mfc0\t%0, " #source ", " #sel "\n\t" \
+ ".set\tmips0\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __read_64bit_c0_register(source, sel) \
+({ unsigned long long __res; \
+ if (sizeof(unsigned long) == 4) \
+ __res = __read_64bit_c0_split(source, sel); \
+ else if (sel == 0) \
+ __asm__ __volatile__( \
+ ".set\tmips3\n\t" \
+ "dmfc0\t%0, " #source "\n\t" \
+ ".set\tmips0" \
+ : "=r" (__res)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dmfc0\t%0, " #source ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __write_32bit_c0_register(register, sel, value) \
+do { \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mtc0\t%z0, " #register "\n\t" \
+ : : "Jr" ((unsigned int)(value))); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mtc0\t%z0, " #register ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : : "Jr" ((unsigned int)(value))); \
+} while (0)
+
+#define __write_64bit_c0_register(register, sel, value) \
+do { \
+ if (sizeof(unsigned long) == 4) \
+ __write_64bit_c0_split(register, sel, value); \
+ else if (sel == 0) \
+ __asm__ __volatile__( \
+ ".set\tmips3\n\t" \
+ "dmtc0\t%z0, " #register "\n\t" \
+ ".set\tmips0" \
+ : : "Jr" (value)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dmtc0\t%z0, " #register ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : : "Jr" (value)); \
+} while (0)
+
+#define __read_ulong_c0_register(reg, sel) \
+ ((sizeof(unsigned long) == 4) ? \
+ (unsigned long) __read_32bit_c0_register(reg, sel) : \
+ (unsigned long) __read_64bit_c0_register(reg, sel))
+
+#define __write_ulong_c0_register(reg, sel, val) \
+do { \
+ if (sizeof(unsigned long) == 4) \
+ __write_32bit_c0_register(reg, sel, val); \
+ else \
+ __write_64bit_c0_register(reg, sel, val); \
+} while (0)
+
+/*
+ * On RM7000/RM9000 these are uses to access cop0 set 1 registers
+ */
+#define __read_32bit_c0_ctrl_register(source) \
+({ int __res; \
+ __asm__ __volatile__( \
+ "cfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __write_32bit_c0_ctrl_register(register, value) \
+do { \
+ __asm__ __volatile__( \
+ "ctc0\t%z0, " #register "\n\t" \
+ : : "Jr" ((unsigned int)(value))); \
+} while (0)
+
+/*
+ * These versions are only needed for systems with more than 38 bits of
+ * physical address space running the 32-bit kernel. That's none atm :-)
+ */
+#define __read_64bit_c0_split(source, sel) \
+({ \
+ unsigned long long __val; \
+ unsigned long __flags; \
+ \
+ local_irq_save(__flags); \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dmfc0\t%M0, " #source "\n\t" \
+ "dsll\t%L0, %M0, 32\n\t" \
+ "dsra\t%M0, %M0, 32\n\t" \
+ "dsra\t%L0, %L0, 32\n\t" \
+ ".set\tmips0" \
+ : "=r" (__val)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dmfc0\t%M0, " #source ", " #sel "\n\t" \
+ "dsll\t%L0, %M0, 32\n\t" \
+ "dsra\t%M0, %M0, 32\n\t" \
+ "dsra\t%L0, %L0, 32\n\t" \
+ ".set\tmips0" \
+ : "=r" (__val)); \
+ local_irq_restore(__flags); \
+ \
+ __val; \
+})
+
+#define __write_64bit_c0_split(source, sel, val) \
+do { \
+ unsigned long __flags; \
+ \
+ local_irq_save(__flags); \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dsll\t%L0, %L0, 32\n\t" \
+ "dsrl\t%L0, %L0, 32\n\t" \
+ "dsll\t%M0, %M0, 32\n\t" \
+ "or\t%L0, %L0, %M0\n\t" \
+ "dmtc0\t%L0, " #source "\n\t" \
+ ".set\tmips0" \
+ : : "r" (val)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dsll\t%L0, %L0, 32\n\t" \
+ "dsrl\t%L0, %L0, 32\n\t" \
+ "dsll\t%M0, %M0, 32\n\t" \
+ "or\t%L0, %L0, %M0\n\t" \
+ "dmtc0\t%L0, " #source ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : : "r" (val)); \
+ local_irq_restore(__flags); \
+} while (0)
+
+#define read_c0_index() __read_32bit_c0_register($0, 0)
+#define write_c0_index(val) __write_32bit_c0_register($0, 0, val)
+
+#define read_c0_random() __read_32bit_c0_register($1, 0)
+#define write_c0_random(val) __write_32bit_c0_register($1, 0, val)
+
+#define read_c0_entrylo0() __read_ulong_c0_register($2, 0)
+#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val)
+
+#define read_c0_entrylo1() __read_ulong_c0_register($3, 0)
+#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val)
+
+#define read_c0_conf() __read_32bit_c0_register($3, 0)
+#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val)
+
+#define read_c0_context() __read_ulong_c0_register($4, 0)
+#define write_c0_context(val) __write_ulong_c0_register($4, 0, val)
+
+#define read_c0_userlocal() __read_ulong_c0_register($4, 2)
+#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val)
+
+#define read_c0_pagemask() __read_32bit_c0_register($5, 0)
+#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
+
+#define read_c0_pagegrain() __read_32bit_c0_register($5, 1)
+#define write_c0_pagegrain(val) __write_32bit_c0_register($5, 1, val)
+
+#define read_c0_wired() __read_32bit_c0_register($6, 0)
+#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val)
+
+#define read_c0_info() __read_32bit_c0_register($7, 0)
+
+#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */
+#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val)
+
+#define read_c0_badvaddr() __read_ulong_c0_register($8, 0)
+#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val)
+
+#define read_c0_count() __read_32bit_c0_register($9, 0)
+#define write_c0_count(val) __write_32bit_c0_register($9, 0, val)
+
+#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */
+#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val)
+
+#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */
+#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val)
+
+#define read_c0_entryhi() __read_ulong_c0_register($10, 0)
+#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val)
+
+#define read_c0_compare() __read_32bit_c0_register($11, 0)
+#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val)
+
+#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */
+#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val)
+
+#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */
+#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val)
+
+#define read_c0_status() __read_32bit_c0_register($12, 0)
+#ifdef CONFIG_MIPS_MT_SMTC
+#define write_c0_status(val) \
+do { \
+ __write_32bit_c0_register($12, 0, val); \
+ __ehb(); \
+} while (0)
+#else
+/*
+ * Legacy non-SMTC code, which may be hazardous
+ * but which might not support EHB
+ */
+#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+#define read_c0_cause() __read_32bit_c0_register($13, 0)
+#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val)
+
+#define read_c0_epc() __read_ulong_c0_register($14, 0)
+#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val)
+
+#define read_c0_prid() __read_32bit_c0_register($15, 0)
+
+#define read_c0_config() __read_32bit_c0_register($16, 0)
+#define read_c0_config1() __read_32bit_c0_register($16, 1)
+#define read_c0_config2() __read_32bit_c0_register($16, 2)
+#define read_c0_config3() __read_32bit_c0_register($16, 3)
+#define read_c0_config4() __read_32bit_c0_register($16, 4)
+#define read_c0_config5() __read_32bit_c0_register($16, 5)
+#define read_c0_config6() __read_32bit_c0_register($16, 6)
+#define read_c0_config7() __read_32bit_c0_register($16, 7)
+#define write_c0_config(val) __write_32bit_c0_register($16, 0, val)
+#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val)
+#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val)
+#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val)
+#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val)
+#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val)
+#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val)
+#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val)
+
+/*
+ * The WatchLo register. There may be up to 8 of them.
+ */
+#define read_c0_watchlo0() __read_ulong_c0_register($18, 0)
+#define read_c0_watchlo1() __read_ulong_c0_register($18, 1)
+#define read_c0_watchlo2() __read_ulong_c0_register($18, 2)
+#define read_c0_watchlo3() __read_ulong_c0_register($18, 3)
+#define read_c0_watchlo4() __read_ulong_c0_register($18, 4)
+#define read_c0_watchlo5() __read_ulong_c0_register($18, 5)
+#define read_c0_watchlo6() __read_ulong_c0_register($18, 6)
+#define read_c0_watchlo7() __read_ulong_c0_register($18, 7)
+#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val)
+#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val)
+#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val)
+#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val)
+#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val)
+#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val)
+#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val)
+#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val)
+
+/*
+ * The WatchHi register. There may be up to 8 of them.
+ */
+#define read_c0_watchhi0() __read_32bit_c0_register($19, 0)
+#define read_c0_watchhi1() __read_32bit_c0_register($19, 1)
+#define read_c0_watchhi2() __read_32bit_c0_register($19, 2)
+#define read_c0_watchhi3() __read_32bit_c0_register($19, 3)
+#define read_c0_watchhi4() __read_32bit_c0_register($19, 4)
+#define read_c0_watchhi5() __read_32bit_c0_register($19, 5)
+#define read_c0_watchhi6() __read_32bit_c0_register($19, 6)
+#define read_c0_watchhi7() __read_32bit_c0_register($19, 7)
+
+#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val)
+#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val)
+#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val)
+#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val)
+#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val)
+#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val)
+#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val)
+#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val)
+
+#define read_c0_xcontext() __read_ulong_c0_register($20, 0)
+#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val)
+
+#define read_c0_intcontrol() __read_32bit_c0_ctrl_register($20)
+#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val)
+
+#define read_c0_framemask() __read_32bit_c0_register($21, 0)
+#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val)
+
+/* RM9000 PerfControl performance counter control register */
+#define read_c0_perfcontrol() __read_32bit_c0_register($22, 0)
+#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_diag() __read_32bit_c0_register($22, 0)
+#define write_c0_diag(val) __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_diag1() __read_32bit_c0_register($22, 1)
+#define write_c0_diag1(val) __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_diag2() __read_32bit_c0_register($22, 2)
+#define write_c0_diag2(val) __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_diag3() __read_32bit_c0_register($22, 3)
+#define write_c0_diag3(val) __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_diag4() __read_32bit_c0_register($22, 4)
+#define write_c0_diag4(val) __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_diag5() __read_32bit_c0_register($22, 5)
+#define write_c0_diag5(val) __write_32bit_c0_register($22, 5, val)
+
+#define read_c0_debug() __read_32bit_c0_register($23, 0)
+#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val)
+
+#define read_c0_depc() __read_ulong_c0_register($24, 0)
+#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val)
+
+/*
+ * MIPS32 / MIPS64 performance counters
+ */
+#define read_c0_perfctrl0() __read_32bit_c0_register($25, 0)
+#define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val)
+#define read_c0_perfcntr0() __read_32bit_c0_register($25, 1)
+#define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val)
+#define read_c0_perfctrl1() __read_32bit_c0_register($25, 2)
+#define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val)
+#define read_c0_perfcntr1() __read_32bit_c0_register($25, 3)
+#define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val)
+#define read_c0_perfctrl2() __read_32bit_c0_register($25, 4)
+#define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val)
+#define read_c0_perfcntr2() __read_32bit_c0_register($25, 5)
+#define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val)
+#define read_c0_perfctrl3() __read_32bit_c0_register($25, 6)
+#define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val)
+#define read_c0_perfcntr3() __read_32bit_c0_register($25, 7)
+#define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val)
+
+/* RM9000 PerfCount performance counter register */
+#define read_c0_perfcount() __read_64bit_c0_register($25, 0)
+#define write_c0_perfcount(val) __write_64bit_c0_register($25, 0, val)
+
+#define read_c0_ecc() __read_32bit_c0_register($26, 0)
+#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val)
+
+#define read_c0_derraddr0() __read_ulong_c0_register($26, 1)
+#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val)
+
+#define read_c0_cacheerr() __read_32bit_c0_register($27, 0)
+
+#define read_c0_derraddr1() __read_ulong_c0_register($27, 1)
+#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val)
+
+#define read_c0_taglo() __read_32bit_c0_register($28, 0)
+#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val)
+
+#define read_c0_dtaglo() __read_32bit_c0_register($28, 2)
+#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val)
+
+#define read_c0_ddatalo() __read_32bit_c0_register($28, 3)
+#define write_c0_ddatalo(val) __write_32bit_c0_register($28, 3, val)
+
+#define read_c0_staglo() __read_32bit_c0_register($28, 4)
+#define write_c0_staglo(val) __write_32bit_c0_register($28, 4, val)
+
+#define read_c0_taghi() __read_32bit_c0_register($29, 0)
+#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val)
+
+#define read_c0_errorepc() __read_ulong_c0_register($30, 0)
+#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val)
+
+/* MIPSR2 */
+#define read_c0_hwrena() __read_32bit_c0_register($7, 0)
+#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val)
+
+#define read_c0_intctl() __read_32bit_c0_register($12, 1)
+#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val)
+
+#define read_c0_srsctl() __read_32bit_c0_register($12, 2)
+#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val)
+
+#define read_c0_srsmap() __read_32bit_c0_register($12, 3)
+#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val)
+
+#define read_c0_ebase() __read_32bit_c0_register($15, 1)
+#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val)
+
+
+/* Cavium OCTEON (cnMIPS) */
+#define read_c0_cvmcount() __read_ulong_c0_register($9, 6)
+#define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val)
+
+#define read_c0_cvmctl() __read_64bit_c0_register($9, 7)
+#define write_c0_cvmctl(val) __write_64bit_c0_register($9, 7, val)
+
+#define read_c0_cvmmemctl() __read_64bit_c0_register($11, 7)
+#define write_c0_cvmmemctl(val) __write_64bit_c0_register($11, 7, val)
+/*
+ * The cacheerr registers are not standardized. On OCTEON, they are
+ * 64 bits wide.
+ */
+#define read_octeon_c0_icacheerr() __read_64bit_c0_register($27, 0)
+#define write_octeon_c0_icacheerr(val) __write_64bit_c0_register($27, 0, val)
+
+#define read_octeon_c0_dcacheerr() __read_64bit_c0_register($27, 1)
+#define write_octeon_c0_dcacheerr(val) __write_64bit_c0_register($27, 1, val)
+
+/* BMIPS3300 */
+#define read_c0_brcm_config_0() __read_32bit_c0_register($22, 0)
+#define write_c0_brcm_config_0(val) __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_brcm_bus_pll() __read_32bit_c0_register($22, 4)
+#define write_c0_brcm_bus_pll(val) __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_brcm_reset() __read_32bit_c0_register($22, 5)
+#define write_c0_brcm_reset(val) __write_32bit_c0_register($22, 5, val)
+
+/* BMIPS4380 */
+#define read_c0_brcm_cmt_intr() __read_32bit_c0_register($22, 1)
+#define write_c0_brcm_cmt_intr(val) __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_brcm_cmt_ctrl() __read_32bit_c0_register($22, 2)
+#define write_c0_brcm_cmt_ctrl(val) __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_brcm_cmt_local() __read_32bit_c0_register($22, 3)
+#define write_c0_brcm_cmt_local(val) __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_brcm_config_1() __read_32bit_c0_register($22, 5)
+#define write_c0_brcm_config_1(val) __write_32bit_c0_register($22, 5, val)
+
+#define read_c0_brcm_cbr() __read_32bit_c0_register($22, 6)
+#define write_c0_brcm_cbr(val) __write_32bit_c0_register($22, 6, val)
+
+/* BMIPS5000 */
+#define read_c0_brcm_config() __read_32bit_c0_register($22, 0)
+#define write_c0_brcm_config(val) __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_brcm_mode() __read_32bit_c0_register($22, 1)
+#define write_c0_brcm_mode(val) __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_brcm_action() __read_32bit_c0_register($22, 2)
+#define write_c0_brcm_action(val) __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_brcm_edsp() __read_32bit_c0_register($22, 3)
+#define write_c0_brcm_edsp(val) __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_brcm_bootvec() __read_32bit_c0_register($22, 4)
+#define write_c0_brcm_bootvec(val) __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_brcm_sleepcount() __read_32bit_c0_register($22, 7)
+#define write_c0_brcm_sleepcount(val) __write_32bit_c0_register($22, 7, val)
+
+/*
+ * Macros to access the floating point coprocessor control registers
+ */
+#define read_32bit_cp1_register(source) \
+({ int __res; \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set\treorder\n\t" \
+ /* gas fails to assemble cfc1 for some archs (octeon).*/ \
+ ".set\tmips1\n\t" \
+ "cfc1\t%0,"STR(source)"\n\t" \
+ ".set\tpop" \
+ : "=r" (__res)); \
+ __res;})
+
+#define rddsp(mask) \
+({ \
+ unsigned int __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # rddsp $1, %x1 \n" \
+ " .word 0x7c000cb8 | (%x1 << 16) \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__res) \
+ : "i" (mask)); \
+ __res; \
+})
+
+#define wrdsp(val, mask) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # wrdsp $1, %x1 \n" \
+ " .word 0x7c2004f8 | (%x1 << 11) \n" \
+ " .set pop \n" \
+ : \
+ : "r" (val), "i" (mask)); \
+} while (0)
+
+#if 0 /* Need DSP ASE capable assembler ... */
+#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
+#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
+#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
+#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
+
+#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
+#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
+#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
+#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
+
+#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
+#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
+#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
+#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
+
+#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
+#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
+#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
+#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
+
+#else
+
+#define mfhi0() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac0 \n" \
+ " .word 0x00000810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi1() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac1 \n" \
+ " .word 0x00200810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi2() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac2 \n" \
+ " .word 0x00400810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi3() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac3 \n" \
+ " .word 0x00600810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo0() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac0 \n" \
+ " .word 0x00000812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo1() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac1 \n" \
+ " .word 0x00200812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo2() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac2 \n" \
+ " .word 0x00400812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo3() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac3 \n" \
+ " .word 0x00600812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mthi0(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac0 \n" \
+ " .word 0x00200011 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi1(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac1 \n" \
+ " .word 0x00200811 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi2(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac2 \n" \
+ " .word 0x00201011 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi3(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac3 \n" \
+ " .word 0x00201811 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo0(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac0 \n" \
+ " .word 0x00200013 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo1(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac1 \n" \
+ " .word 0x00200813 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo2(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac2 \n" \
+ " .word 0x00201013 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo3(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac3 \n" \
+ " .word 0x00201813 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#endif
+
+/*
+ * TLB operations.
+ *
+ * It is responsibility of the caller to take care of any TLB hazards.
+ */
+static inline void tlb_probe(void)
+{
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "tlbp\n\t"
+ ".set reorder");
+}
+
+static inline void tlb_read(void)
+{
+#if MIPS34K_MISSED_ITLB_WAR
+ int res = 0;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " .set mips32r2 \n"
+ " .word 0x41610001 # dvpe $1 \n"
+ " move %0, $1 \n"
+ " ehb \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+#endif
+
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "tlbr\n\t"
+ ".set reorder");
+
+#if MIPS34K_MISSED_ITLB_WAR
+ if ((res & _ULCAST_(1)))
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " .set noat \n"
+ " .set mips32r2 \n"
+ " .word 0x41600021 # evpe \n"
+ " ehb \n"
+ " .set pop \n");
+#endif
+}
+
+static inline void tlb_write_indexed(void)
+{
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "tlbwi\n\t"
+ ".set reorder");
+}
+
+static inline void tlb_write_random(void)
+{
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "tlbwr\n\t"
+ ".set reorder");
+}
+
+/*
+ * Manipulate bits in a c0 register.
+ */
+#ifndef CONFIG_MIPS_MT_SMTC
+/*
+ * SMTC Linux requires shutting-down microthread scheduling
+ * during CP0 register read-modify-write sequences.
+ */
+#define __BUILD_SET_C0(name) \
+static inline unsigned int \
+set_c0_##name(unsigned int set) \
+{ \
+ unsigned int res, new; \
+ \
+ res = read_c0_##name(); \
+ new = res | set; \
+ write_c0_##name(new); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+clear_c0_##name(unsigned int clear) \
+{ \
+ unsigned int res, new; \
+ \
+ res = read_c0_##name(); \
+ new = res & ~clear; \
+ write_c0_##name(new); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+change_c0_##name(unsigned int change, unsigned int val) \
+{ \
+ unsigned int res, new; \
+ \
+ res = read_c0_##name(); \
+ new = res & ~change; \
+ new |= (val & change); \
+ write_c0_##name(new); \
+ \
+ return res; \
+}
+
+#else /* SMTC versions that manage MT scheduling */
+
+#include <linux/irqflags.h>
+
+/*
+ * This is a duplicate of dmt() in mipsmtregs.h to avoid problems with
+ * header file recursion.
+ */
+static inline unsigned int __dmt(void)
+{
+ int res;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips32r2 \n"
+ " .set noat \n"
+ " .word 0x41610BC1 # dmt $1 \n"
+ " ehb \n"
+ " move %0, $1 \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+
+ return res;
+}
+
+#define __VPECONTROL_TE_SHIFT 15
+#define __VPECONTROL_TE (1UL << __VPECONTROL_TE_SHIFT)
+
+#define __EMT_ENABLE __VPECONTROL_TE
+
+static inline void __emt(unsigned int previous)
+{
+ if ((previous & __EMT_ENABLE))
+ __asm__ __volatile__(
+ " .set mips32r2 \n"
+ " .word 0x41600be1 # emt \n"
+ " ehb \n"
+ " .set mips0 \n");
+}
+
+static inline void __ehb(void)
+{
+ __asm__ __volatile__(
+ " .set mips32r2 \n"
+ " ehb \n" " .set mips0 \n");
+}
+
+/*
+ * Note that local_irq_save/restore affect TC-specific IXMT state,
+ * not Status.IE as in non-SMTC kernel.
+ */
+
+#define __BUILD_SET_C0(name) \
+static inline unsigned int \
+set_c0_##name(unsigned int set) \
+{ \
+ unsigned int res; \
+ unsigned int new; \
+ unsigned int omt; \
+ unsigned long flags; \
+ \
+ local_irq_save(flags); \
+ omt = __dmt(); \
+ res = read_c0_##name(); \
+ new = res | set; \
+ write_c0_##name(new); \
+ __emt(omt); \
+ local_irq_restore(flags); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+clear_c0_##name(unsigned int clear) \
+{ \
+ unsigned int res; \
+ unsigned int new; \
+ unsigned int omt; \
+ unsigned long flags; \
+ \
+ local_irq_save(flags); \
+ omt = __dmt(); \
+ res = read_c0_##name(); \
+ new = res & ~clear; \
+ write_c0_##name(new); \
+ __emt(omt); \
+ local_irq_restore(flags); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+change_c0_##name(unsigned int change, unsigned int newbits) \
+{ \
+ unsigned int res; \
+ unsigned int new; \
+ unsigned int omt; \
+ unsigned long flags; \
+ \
+ local_irq_save(flags); \
+ \
+ omt = __dmt(); \
+ res = read_c0_##name(); \
+ new = res & ~change; \
+ new |= (newbits & change); \
+ write_c0_##name(new); \
+ __emt(omt); \
+ local_irq_restore(flags); \
+ \
+ return res; \
+}
+#endif
+
+__BUILD_SET_C0(status)
+__BUILD_SET_C0(cause)
+__BUILD_SET_C0(config)
+__BUILD_SET_C0(intcontrol)
+__BUILD_SET_C0(intctl)
+__BUILD_SET_C0(srsmap)
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MIPSREGS_H */
diff --git a/arch/mips/include/asm/mman.h b/arch/mips/include/asm/mman.h
new file mode 100644
index 00000000..785b4ea4
--- /dev/null
+++ b/arch/mips/include/asm/mman.h
@@ -0,0 +1,86 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999, 2002 by Ralf Baechle
+ */
+#ifndef _ASM_MMAN_H
+#define _ASM_MMAN_H
+
+/*
+ * Protections are chosen from these bits, OR'd together. The
+ * implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ * without PROT_READ. The only guarantees are that no writing will be
+ * allowed without PROT_WRITE and no access will be allowed for PROT_NONE.
+ */
+#define PROT_NONE 0x00 /* page can not be accessed */
+#define PROT_READ 0x01 /* page can be read */
+#define PROT_WRITE 0x02 /* page can be written */
+#define PROT_EXEC 0x04 /* page can be executed */
+/* 0x08 reserved for PROT_EXEC_NOFLUSH */
+#define PROT_SEM 0x10 /* page may be used for atomic ops */
+#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
+#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */
+
+/*
+ * Flags for mmap
+ */
+#define MAP_SHARED 0x001 /* Share changes */
+#define MAP_PRIVATE 0x002 /* Changes are private */
+#define MAP_TYPE 0x00f /* Mask for type of mapping */
+#define MAP_FIXED 0x010 /* Interpret addr exactly */
+
+/* not used by linux, but here to make sure we don't clash with ABI defines */
+#define MAP_RENAME 0x020 /* Assign page to file */
+#define MAP_AUTOGROW 0x040 /* File may grow by writing */
+#define MAP_LOCAL 0x080 /* Copy on fork/sproc */
+#define MAP_AUTORSRV 0x100 /* Logical swap reserved on demand */
+
+/* These are linux-specific */
+#define MAP_NORESERVE 0x0400 /* don't check for reservations */
+#define MAP_ANONYMOUS 0x0800 /* don't use a file */
+#define MAP_GROWSDOWN 0x1000 /* stack-like segment */
+#define MAP_DENYWRITE 0x2000 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x4000 /* mark it as an executable */
+#define MAP_LOCKED 0x8000 /* pages are locked */
+#define MAP_POPULATE 0x10000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x20000 /* do not block on IO */
+#define MAP_STACK 0x40000 /* give out an address that is best suited for process/thread stacks */
+#define MAP_HUGETLB 0x80000 /* create a huge page mapping */
+
+/*
+ * Flags for msync
+ */
+#define MS_ASYNC 0x0001 /* sync memory asynchronously */
+#define MS_INVALIDATE 0x0002 /* invalidate mappings & caches */
+#define MS_SYNC 0x0004 /* synchronous memory sync */
+
+/*
+ * Flags for mlockall
+ */
+#define MCL_CURRENT 1 /* lock all current mappings */
+#define MCL_FUTURE 2 /* lock all future mappings */
+
+#define MADV_NORMAL 0 /* no further special treatment */
+#define MADV_RANDOM 1 /* expect random page references */
+#define MADV_SEQUENTIAL 2 /* expect sequential page references */
+#define MADV_WILLNEED 3 /* will need these pages */
+#define MADV_DONTNEED 4 /* don't need these pages */
+
+/* common parameters: try to keep these consistent across architectures */
+#define MADV_REMOVE 9 /* remove these pages & resources */
+#define MADV_DONTFORK 10 /* don't inherit across fork */
+#define MADV_DOFORK 11 /* do inherit across fork */
+
+#define MADV_MERGEABLE 12 /* KSM may merge identical pages */
+#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */
+#define MADV_HWPOISON 100 /* poison a page for testing */
+
+#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
+#define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */
+
+/* compatibility flags */
+#define MAP_FILE 0
+
+#endif /* _ASM_MMAN_H */
diff --git a/arch/mips/include/asm/mmu.h b/arch/mips/include/asm/mmu.h
new file mode 100644
index 00000000..c4361389
--- /dev/null
+++ b/arch/mips/include/asm/mmu.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_MMU_H
+#define __ASM_MMU_H
+
+typedef struct {
+ unsigned long asid[NR_CPUS];
+ void *vdso;
+} mm_context_t;
+
+#endif /* __ASM_MMU_H */
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h
new file mode 100644
index 00000000..73c0d457
--- /dev/null
+++ b/arch/mips/include/asm/mmu_context.h
@@ -0,0 +1,322 @@
+/*
+ * Switch a MMU context.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+#include <asm/hazards.h>
+#include <asm/tlbflush.h>
+#ifdef CONFIG_MIPS_MT_SMTC
+#include <asm/mipsmtregs.h>
+#include <asm/smtc.h>
+#endif /* SMTC */
+#include <asm-generic/mm_hooks.h>
+
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+
+#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
+ tlbmiss_handler_setup_pgd((unsigned long)(pgd))
+
+extern void tlbmiss_handler_setup_pgd(unsigned long pgd);
+
+#define TLBMISS_HANDLER_SETUP() \
+ do { \
+ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \
+ write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
+ } while (0)
+
+
+static inline unsigned long get_current_pgd(void)
+{
+ return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL);
+}
+
+#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/
+
+/*
+ * For the fast tlb miss handlers, we keep a per cpu array of pointers
+ * to the current pgd for each processor. Also, the proc. id is stuffed
+ * into the context register.
+ */
+extern unsigned long pgd_current[];
+
+#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
+ pgd_current[smp_processor_id()] = (unsigned long)(pgd)
+
+#ifdef CONFIG_32BIT
+#define TLBMISS_HANDLER_SETUP() \
+ write_c0_context((unsigned long) smp_processor_id() << 25); \
+ back_to_back_c0_hazard(); \
+ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+#endif
+#ifdef CONFIG_64BIT
+#define TLBMISS_HANDLER_SETUP() \
+ write_c0_context((unsigned long) smp_processor_id() << 26); \
+ back_to_back_c0_hazard(); \
+ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+#endif
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+#define ASID_INC 0x40
+#define ASID_MASK 0xfc0
+
+#elif defined(CONFIG_CPU_R8000)
+
+#define ASID_INC 0x10
+#define ASID_MASK 0xff0
+
+#elif defined(CONFIG_CPU_RM9000)
+
+#define ASID_INC 0x1
+#define ASID_MASK 0xfff
+
+/* SMTC/34K debug hack - but maybe we'll keep it */
+#elif defined(CONFIG_MIPS_MT_SMTC)
+
+#define ASID_INC 0x1
+extern unsigned long smtc_asid_mask;
+#define ASID_MASK (smtc_asid_mask)
+#define HW_ASID_MASK 0xff
+/* End SMTC/34K debug hack */
+#else /* FIXME: not correct for R6000 */
+
+#define ASID_INC 0x1
+#define ASID_MASK 0xff
+
+#endif
+
+#define cpu_context(cpu, mm) ((mm)->context.asid[cpu])
+#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
+#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+/*
+ * All unused by hardware upper bits will be considered
+ * as a software asid extension.
+ */
+#define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
+#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
+
+#ifndef CONFIG_MIPS_MT_SMTC
+/* Normal, classic MIPS get_new_mmu_context */
+static inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
+{
+ unsigned long asid = asid_cache(cpu);
+
+ if (! ((asid += ASID_INC) & ASID_MASK) ) {
+ if (cpu_has_vtag_icache)
+ flush_icache_all();
+ local_flush_tlb_all(); /* start new asid cycle */
+ if (!asid) /* fix version if needed */
+ asid = ASID_FIRST_VERSION;
+ }
+ cpu_context(cpu, mm) = asid_cache(cpu) = asid;
+}
+
+#else /* CONFIG_MIPS_MT_SMTC */
+
+#define get_new_mmu_context(mm, cpu) smtc_get_new_mmu_context((mm), (cpu))
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ int i;
+
+ for_each_online_cpu(i)
+ cpu_context(i, mm) = 0;
+
+ return 0;
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned long flags;
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned long oldasid;
+ unsigned long mtflags;
+ int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
+ local_irq_save(flags);
+ mtflags = dvpe();
+#else /* Not SMTC */
+ local_irq_save(flags);
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ /* Check if our ASID is of an older version and thus invalid */
+ if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK)
+ get_new_mmu_context(next, cpu);
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * If the EntryHi ASID being replaced happens to be
+ * the value flagged at ASID recycling time as having
+ * an extended life, clear the bit showing it being
+ * in use by this "CPU", and if that's the last bit,
+ * free up the ASID value for use and flush any old
+ * instances of it from the TLB.
+ */
+ oldasid = (read_c0_entryhi() & ASID_MASK);
+ if(smtc_live_asid[mytlb][oldasid]) {
+ smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
+ if(smtc_live_asid[mytlb][oldasid] == 0)
+ smtc_flush_tlb_asid(oldasid);
+ }
+ /*
+ * Tread softly on EntryHi, and so long as we support
+ * having ASID_MASK smaller than the hardware maximum,
+ * make sure no "soft" bits become "hard"...
+ */
+ write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
+ cpu_asid(cpu, next));
+ ehb(); /* Make sure it propagates to TCStatus */
+ evpe(mtflags);
+#else
+ write_c0_entryhi(cpu_asid(cpu, next));
+#endif /* CONFIG_MIPS_MT_SMTC */
+ TLBMISS_HANDLER_SETUP_PGD(next->pgd);
+
+ /*
+ * Mark current->active_mm as not "active" anymore.
+ * We don't want to mislead possible IPI tlb flush routines.
+ */
+ cpumask_clear_cpu(cpu, mm_cpumask(prev));
+ cpumask_set_cpu(cpu, mm_cpumask(next));
+
+ local_irq_restore(flags);
+}
+
+/*
+ * Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+static inline void destroy_context(struct mm_struct *mm)
+{
+}
+
+#define deactivate_mm(tsk, mm) do { } while (0)
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+static inline void
+activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+ unsigned long flags;
+ unsigned int cpu = smp_processor_id();
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned long oldasid;
+ unsigned long mtflags;
+ int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ local_irq_save(flags);
+
+ /* Unconditionally get a new ASID. */
+ get_new_mmu_context(next, cpu);
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /* See comments for similar code above */
+ mtflags = dvpe();
+ oldasid = read_c0_entryhi() & ASID_MASK;
+ if(smtc_live_asid[mytlb][oldasid]) {
+ smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
+ if(smtc_live_asid[mytlb][oldasid] == 0)
+ smtc_flush_tlb_asid(oldasid);
+ }
+ /* See comments for similar code above */
+ write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) |
+ cpu_asid(cpu, next));
+ ehb(); /* Make sure it propagates to TCStatus */
+ evpe(mtflags);
+#else
+ write_c0_entryhi(cpu_asid(cpu, next));
+#endif /* CONFIG_MIPS_MT_SMTC */
+ TLBMISS_HANDLER_SETUP_PGD(next->pgd);
+
+ /* mark mmu ownership change */
+ cpumask_clear_cpu(cpu, mm_cpumask(prev));
+ cpumask_set_cpu(cpu, mm_cpumask(next));
+
+ local_irq_restore(flags);
+}
+
+/*
+ * If mm is currently active_mm, we can't really drop it. Instead,
+ * we will get a new one for it.
+ */
+static inline void
+drop_mmu_context(struct mm_struct *mm, unsigned cpu)
+{
+ unsigned long flags;
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned long oldasid;
+ /* Can't use spinlock because called from TLB flush within DVPE */
+ unsigned int prevvpe;
+ int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id;
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ local_irq_save(flags);
+
+ if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
+ get_new_mmu_context(mm, cpu);
+#ifdef CONFIG_MIPS_MT_SMTC
+ /* See comments for similar code above */
+ prevvpe = dvpe();
+ oldasid = (read_c0_entryhi() & ASID_MASK);
+ if (smtc_live_asid[mytlb][oldasid]) {
+ smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu);
+ if(smtc_live_asid[mytlb][oldasid] == 0)
+ smtc_flush_tlb_asid(oldasid);
+ }
+ /* See comments for similar code above */
+ write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK)
+ | cpu_asid(cpu, mm));
+ ehb(); /* Make sure it propagates to TCStatus */
+ evpe(prevvpe);
+#else /* not CONFIG_MIPS_MT_SMTC */
+ write_c0_entryhi(cpu_asid(cpu, mm));
+#endif /* CONFIG_MIPS_MT_SMTC */
+ } else {
+ /* will get a new context next time */
+#ifndef CONFIG_MIPS_MT_SMTC
+ cpu_context(cpu, mm) = 0;
+#else /* SMTC */
+ int i;
+
+ /* SMTC shares the TLB (and ASIDs) across VPEs */
+ for_each_online_cpu(i) {
+ if((smtc_status & SMTC_TLB_SHARED)
+ || (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))
+ cpu_context(i, mm) = 0;
+ }
+#endif /* CONFIG_MIPS_MT_SMTC */
+ }
+ local_irq_restore(flags);
+}
+
+#endif /* _ASM_MMU_CONTEXT_H */
diff --git a/arch/mips/include/asm/mmzone.h b/arch/mips/include/asm/mmzone.h
new file mode 100644
index 00000000..f53ec54c
--- /dev/null
+++ b/arch/mips/include/asm/mmzone.h
@@ -0,0 +1,17 @@
+/*
+ * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99
+ * Rewritten for Linux 2.6 by Christoph Hellwig (hch@lst.de) Jan 2004
+ */
+#ifndef _ASM_MMZONE_H_
+#define _ASM_MMZONE_H_
+
+#include <asm/page.h>
+#include <mmzone.h>
+
+#ifdef CONFIG_DISCONTIGMEM
+
+#define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT)
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* _ASM_MMZONE_H_ */
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
new file mode 100644
index 00000000..bc01a02c
--- /dev/null
+++ b/arch/mips/include/asm/module.h
@@ -0,0 +1,142 @@
+#ifndef _ASM_MODULE_H
+#define _ASM_MODULE_H
+
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+struct mod_arch_specific {
+ /* Data Bus Error exception tables */
+ struct list_head dbe_list;
+ const struct exception_table_entry *dbe_start;
+ const struct exception_table_entry *dbe_end;
+};
+
+typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
+
+typedef struct {
+ Elf64_Addr r_offset; /* Address of relocation. */
+ Elf64_Word r_sym; /* Symbol index. */
+ Elf64_Byte r_ssym; /* Special symbol. */
+ Elf64_Byte r_type3; /* Third relocation. */
+ Elf64_Byte r_type2; /* Second relocation. */
+ Elf64_Byte r_type; /* First relocation. */
+} Elf64_Mips_Rel;
+
+typedef struct {
+ Elf64_Addr r_offset; /* Address of relocation. */
+ Elf64_Word r_sym; /* Symbol index. */
+ Elf64_Byte r_ssym; /* Special symbol. */
+ Elf64_Byte r_type3; /* Third relocation. */
+ Elf64_Byte r_type2; /* Second relocation. */
+ Elf64_Byte r_type; /* First relocation. */
+ Elf64_Sxword r_addend; /* Addend. */
+} Elf64_Mips_Rela;
+
+#ifdef CONFIG_32BIT
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Addr Elf32_Addr
+
+#define Elf_Mips_Rel Elf32_Rel
+#define Elf_Mips_Rela Elf32_Rela
+
+#define ELF_MIPS_R_SYM(rel) ELF32_R_SYM(rel.r_info)
+#define ELF_MIPS_R_TYPE(rel) ELF32_R_TYPE(rel.r_info)
+
+#endif
+
+#ifdef CONFIG_64BIT
+
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
+#define Elf_Addr Elf64_Addr
+
+#define Elf_Mips_Rel Elf64_Mips_Rel
+#define Elf_Mips_Rela Elf64_Mips_Rela
+
+#define ELF_MIPS_R_SYM(rel) (rel.r_sym)
+#define ELF_MIPS_R_TYPE(rel) (rel.r_type)
+
+#endif
+
+#ifdef CONFIG_MODULES
+/* Given an address, look for it in the exception tables. */
+const struct exception_table_entry*search_module_dbetables(unsigned long addr);
+#else
+/* Given an address, look for it in the exception tables. */
+static inline const struct exception_table_entry *
+search_module_dbetables(unsigned long addr)
+{
+ return NULL;
+}
+#endif
+
+#ifdef CONFIG_CPU_MIPS32_R1
+#define MODULE_PROC_FAMILY "MIPS32_R1 "
+#elif defined CONFIG_CPU_MIPS32_R2
+#define MODULE_PROC_FAMILY "MIPS32_R2 "
+#elif defined CONFIG_CPU_MIPS64_R1
+#define MODULE_PROC_FAMILY "MIPS64_R1 "
+#elif defined CONFIG_CPU_MIPS64_R2
+#define MODULE_PROC_FAMILY "MIPS64_R2 "
+#elif defined CONFIG_CPU_R3000
+#define MODULE_PROC_FAMILY "R3000 "
+#elif defined CONFIG_CPU_TX39XX
+#define MODULE_PROC_FAMILY "TX39XX "
+#elif defined CONFIG_CPU_VR41XX
+#define MODULE_PROC_FAMILY "VR41XX "
+#elif defined CONFIG_CPU_R4300
+#define MODULE_PROC_FAMILY "R4300 "
+#elif defined CONFIG_CPU_R4X00
+#define MODULE_PROC_FAMILY "R4X00 "
+#elif defined CONFIG_CPU_TX49XX
+#define MODULE_PROC_FAMILY "TX49XX "
+#elif defined CONFIG_CPU_R5000
+#define MODULE_PROC_FAMILY "R5000 "
+#elif defined CONFIG_CPU_R5432
+#define MODULE_PROC_FAMILY "R5432 "
+#elif defined CONFIG_CPU_R5500
+#define MODULE_PROC_FAMILY "R5500 "
+#elif defined CONFIG_CPU_R6000
+#define MODULE_PROC_FAMILY "R6000 "
+#elif defined CONFIG_CPU_NEVADA
+#define MODULE_PROC_FAMILY "NEVADA "
+#elif defined CONFIG_CPU_R8000
+#define MODULE_PROC_FAMILY "R8000 "
+#elif defined CONFIG_CPU_R10000
+#define MODULE_PROC_FAMILY "R10000 "
+#elif defined CONFIG_CPU_RM7000
+#define MODULE_PROC_FAMILY "RM7000 "
+#elif defined CONFIG_CPU_RM9000
+#define MODULE_PROC_FAMILY "RM9000 "
+#elif defined CONFIG_CPU_SB1
+#define MODULE_PROC_FAMILY "SB1 "
+#elif defined CONFIG_CPU_LOONGSON2
+#define MODULE_PROC_FAMILY "LOONGSON2 "
+#elif defined CONFIG_CPU_CAVIUM_OCTEON
+#define MODULE_PROC_FAMILY "OCTEON "
+#elif defined CONFIG_CPU_XLR
+#define MODULE_PROC_FAMILY "XLR "
+#else
+#error MODULE_PROC_FAMILY undefined for your processor configuration
+#endif
+
+#ifdef CONFIG_32BIT
+#define MODULE_KERNEL_TYPE "32BIT "
+#elif defined CONFIG_64BIT
+#define MODULE_KERNEL_TYPE "64BIT "
+#endif
+
+#ifdef CONFIG_MIPS_MT_SMTC
+#define MODULE_KERNEL_SMTC "MT_SMTC "
+#else
+#define MODULE_KERNEL_SMTC ""
+#endif
+
+#define MODULE_ARCH_VERMAGIC \
+ MODULE_PROC_FAMILY MODULE_KERNEL_TYPE MODULE_KERNEL_SMTC
+
+#endif /* _ASM_MODULE_H */
diff --git a/arch/mips/include/asm/msc01_ic.h b/arch/mips/include/asm/msc01_ic.h
new file mode 100644
index 00000000..d92406ae
--- /dev/null
+++ b/arch/mips/include/asm/msc01_ic.h
@@ -0,0 +1,147 @@
+/*
+ * PCI Register definitions for the MIPS System Controller.
+ *
+ * Copyright (C) 2004 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __ASM_MIPS_BOARDS_MSC01_IC_H
+#define __ASM_MIPS_BOARDS_MSC01_IC_H
+
+/*****************************************************************************
+ * Register offset addresses
+ *****************************************************************************/
+
+#define MSC01_IC_RST_OFS 0x00008 /* Software reset */
+#define MSC01_IC_ENAL_OFS 0x00100 /* Int_in enable mask 31:0 */
+#define MSC01_IC_ENAH_OFS 0x00108 /* Int_in enable mask 63:32 */
+#define MSC01_IC_DISL_OFS 0x00120 /* Int_in disable mask 31:0 */
+#define MSC01_IC_DISH_OFS 0x00128 /* Int_in disable mask 63:32 */
+#define MSC01_IC_ISBL_OFS 0x00140 /* Raw int_in 31:0 */
+#define MSC01_IC_ISBH_OFS 0x00148 /* Raw int_in 63:32 */
+#define MSC01_IC_ISAL_OFS 0x00160 /* Masked int_in 31:0 */
+#define MSC01_IC_ISAH_OFS 0x00168 /* Masked int_in 63:32 */
+#define MSC01_IC_LVL_OFS 0x00180 /* Disable priority int_out */
+#define MSC01_IC_RAMW_OFS 0x00180 /* Shadow set RAM (EI) */
+#define MSC01_IC_OSB_OFS 0x00188 /* Raw int_out */
+#define MSC01_IC_OSA_OFS 0x00190 /* Masked int_out */
+#define MSC01_IC_GENA_OFS 0x00198 /* Global HW int enable */
+#define MSC01_IC_BASE_OFS 0x001a0 /* Base address of IC_VEC */
+#define MSC01_IC_VEC_OFS 0x001b0 /* Active int's vector address */
+#define MSC01_IC_EOI_OFS 0x001c0 /* Enable lower level ints */
+#define MSC01_IC_CFG_OFS 0x001c8 /* Configuration register */
+#define MSC01_IC_TRLD_OFS 0x001d0 /* Interval timer reload val */
+#define MSC01_IC_TVAL_OFS 0x001e0 /* Interval timer current val */
+#define MSC01_IC_TCFG_OFS 0x001f0 /* Interval timer config */
+#define MSC01_IC_SUP_OFS 0x00200 /* Set up int_in line 0 */
+#define MSC01_IC_ENA_OFS 0x00800 /* Int_in enable mask 63:0 */
+#define MSC01_IC_DIS_OFS 0x00820 /* Int_in disable mask 63:0 */
+#define MSC01_IC_ISB_OFS 0x00840 /* Raw int_in 63:0 */
+#define MSC01_IC_ISA_OFS 0x00860 /* Masked int_in 63:0 */
+
+/*****************************************************************************
+ * Register field encodings
+ *****************************************************************************/
+
+#define MSC01_IC_RST_RST_SHF 0
+#define MSC01_IC_RST_RST_MSK 0x00000001
+#define MSC01_IC_RST_RST_BIT MSC01_IC_RST_RST_MSK
+#define MSC01_IC_LVL_LVL_SHF 0
+#define MSC01_IC_LVL_LVL_MSK 0x000000ff
+#define MSC01_IC_LVL_SPUR_SHF 16
+#define MSC01_IC_LVL_SPUR_MSK 0x00010000
+#define MSC01_IC_LVL_SPUR_BIT MSC01_IC_LVL_SPUR_MSK
+#define MSC01_IC_RAMW_RIPL_SHF 0
+#define MSC01_IC_RAMW_RIPL_MSK 0x0000003f
+#define MSC01_IC_RAMW_DATA_SHF 6
+#define MSC01_IC_RAMW_DATA_MSK 0x00000fc0
+#define MSC01_IC_RAMW_ADDR_SHF 25
+#define MSC01_IC_RAMW_ADDR_MSK 0x7e000000
+#define MSC01_IC_RAMW_READ_SHF 31
+#define MSC01_IC_RAMW_READ_MSK 0x80000000
+#define MSC01_IC_RAMW_READ_BIT MSC01_IC_RAMW_READ_MSK
+#define MSC01_IC_OSB_OSB_SHF 0
+#define MSC01_IC_OSB_OSB_MSK 0x000000ff
+#define MSC01_IC_OSA_OSA_SHF 0
+#define MSC01_IC_OSA_OSA_MSK 0x000000ff
+#define MSC01_IC_GENA_GENA_SHF 0
+#define MSC01_IC_GENA_GENA_MSK 0x00000001
+#define MSC01_IC_GENA_GENA_BIT MSC01_IC_GENA_GENA_MSK
+#define MSC01_IC_CFG_DIS_SHF 0
+#define MSC01_IC_CFG_DIS_MSK 0x00000001
+#define MSC01_IC_CFG_DIS_BIT MSC01_IC_CFG_DIS_MSK
+#define MSC01_IC_CFG_SHFT_SHF 8
+#define MSC01_IC_CFG_SHFT_MSK 0x00000f00
+#define MSC01_IC_TCFG_ENA_SHF 0
+#define MSC01_IC_TCFG_ENA_MSK 0x00000001
+#define MSC01_IC_TCFG_ENA_BIT MSC01_IC_TCFG_ENA_MSK
+#define MSC01_IC_TCFG_INT_SHF 8
+#define MSC01_IC_TCFG_INT_MSK 0x00000100
+#define MSC01_IC_TCFG_INT_BIT MSC01_IC_TCFG_INT_MSK
+#define MSC01_IC_TCFG_EDGE_SHF 16
+#define MSC01_IC_TCFG_EDGE_MSK 0x00010000
+#define MSC01_IC_TCFG_EDGE_BIT MSC01_IC_TCFG_EDGE_MSK
+#define MSC01_IC_SUP_PRI_SHF 0
+#define MSC01_IC_SUP_PRI_MSK 0x00000007
+#define MSC01_IC_SUP_EDGE_SHF 8
+#define MSC01_IC_SUP_EDGE_MSK 0x00000100
+#define MSC01_IC_SUP_EDGE_BIT MSC01_IC_SUP_EDGE_MSK
+#define MSC01_IC_SUP_STEP 8
+
+/*
+ * MIPS System controller interrupt register base.
+ *
+ */
+
+/*****************************************************************************
+ * Absolute register addresses
+ *****************************************************************************/
+
+#define MSC01_IC_RST (MSC01_IC_REG_BASE + MSC01_IC_RST_OFS)
+#define MSC01_IC_ENAL (MSC01_IC_REG_BASE + MSC01_IC_ENAL_OFS)
+#define MSC01_IC_ENAH (MSC01_IC_REG_BASE + MSC01_IC_ENAH_OFS)
+#define MSC01_IC_DISL (MSC01_IC_REG_BASE + MSC01_IC_DISL_OFS)
+#define MSC01_IC_DISH (MSC01_IC_REG_BASE + MSC01_IC_DISH_OFS)
+#define MSC01_IC_ISBL (MSC01_IC_REG_BASE + MSC01_IC_ISBL_OFS)
+#define MSC01_IC_ISBH (MSC01_IC_REG_BASE + MSC01_IC_ISBH_OFS)
+#define MSC01_IC_ISAL (MSC01_IC_REG_BASE + MSC01_IC_ISAL_OFS)
+#define MSC01_IC_ISAH (MSC01_IC_REG_BASE + MSC01_IC_ISAH_OFS)
+#define MSC01_IC_LVL (MSC01_IC_REG_BASE + MSC01_IC_LVL_OFS)
+#define MSC01_IC_RAMW (MSC01_IC_REG_BASE + MSC01_IC_RAMW_OFS)
+#define MSC01_IC_OSB (MSC01_IC_REG_BASE + MSC01_IC_OSB_OFS)
+#define MSC01_IC_OSA (MSC01_IC_REG_BASE + MSC01_IC_OSA_OFS)
+#define MSC01_IC_GENA (MSC01_IC_REG_BASE + MSC01_IC_GENA_OFS)
+#define MSC01_IC_BASE (MSC01_IC_REG_BASE + MSC01_IC_BASE_OFS)
+#define MSC01_IC_VEC (MSC01_IC_REG_BASE + MSC01_IC_VEC_OFS)
+#define MSC01_IC_EOI (MSC01_IC_REG_BASE + MSC01_IC_EOI_OFS)
+#define MSC01_IC_CFG (MSC01_IC_REG_BASE + MSC01_IC_CFG_OFS)
+#define MSC01_IC_TRLD (MSC01_IC_REG_BASE + MSC01_IC_TRLD_OFS)
+#define MSC01_IC_TVAL (MSC01_IC_REG_BASE + MSC01_IC_TVAL_OFS)
+#define MSC01_IC_TCFG (MSC01_IC_REG_BASE + MSC01_IC_TCFG_OFS)
+#define MSC01_IC_SUP (MSC01_IC_REG_BASE + MSC01_IC_SUP_OFS)
+#define MSC01_IC_ENA (MSC01_IC_REG_BASE + MSC01_IC_ENA_OFS)
+#define MSC01_IC_DIS (MSC01_IC_REG_BASE + MSC01_IC_DIS_OFS)
+#define MSC01_IC_ISB (MSC01_IC_REG_BASE + MSC01_IC_ISB_OFS)
+#define MSC01_IC_ISA (MSC01_IC_REG_BASE + MSC01_IC_ISA_OFS)
+
+/*
+ * Soc-it interrupts are configurable.
+ * Every board describes its IRQ mapping with this table.
+ */
+typedef struct msc_irqmap {
+ int im_irq;
+ int im_type;
+ int im_lvl;
+} msc_irqmap_t;
+
+/* im_type */
+#define MSC01_IRQ_LEVEL 0
+#define MSC01_IRQ_EDGE 1
+
+extern void __init init_msc_irqs(unsigned long icubase, unsigned int base, msc_irqmap_t *imp, int nirq);
+extern void ll_msc_irq(void);
+
+#endif /* __ASM_MIPS_BOARDS_MSC01_IC_H */
diff --git a/arch/mips/include/asm/msgbuf.h b/arch/mips/include/asm/msgbuf.h
new file mode 100644
index 00000000..0d6c7f14
--- /dev/null
+++ b/arch/mips/include/asm/msgbuf.h
@@ -0,0 +1,47 @@
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+
+/*
+ * The msqid64_ds structure for the MIPS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - extension of time_t to 64-bit on 32-bitsystem to solve the y2038 problem
+ * - 2 miscellaneous unsigned long values
+ */
+
+struct msqid64_ds {
+ struct ipc64_perm msg_perm;
+#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN)
+ unsigned long __unused1;
+#endif
+ __kernel_time_t msg_stime; /* last msgsnd time */
+#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN)
+ unsigned long __unused1;
+#endif
+#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN)
+ unsigned long __unused2;
+#endif
+ __kernel_time_t msg_rtime; /* last msgrcv time */
+#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN)
+ unsigned long __unused2;
+#endif
+#if defined(CONFIG_32BIT) && !defined(CONFIG_CPU_LITTLE_ENDIAN)
+ unsigned long __unused3;
+#endif
+ __kernel_time_t msg_ctime; /* last change time */
+#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_LITTLE_ENDIAN)
+ unsigned long __unused3;
+#endif
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
+ __kernel_pid_t msg_lspid; /* pid of last msgsnd */
+ __kernel_pid_t msg_lrpid; /* last receive pid */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+#endif /* _ASM_MSGBUF_H */
diff --git a/arch/mips/include/asm/mutex.h b/arch/mips/include/asm/mutex.h
new file mode 100644
index 00000000..458c1f7f
--- /dev/null
+++ b/arch/mips/include/asm/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/mips/include/asm/netlogic/interrupt.h b/arch/mips/include/asm/netlogic/interrupt.h
new file mode 100644
index 00000000..a85aadb6
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/interrupt.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_INTERRUPT_H
+#define _ASM_NLM_INTERRUPT_H
+
+/* Defines for the IRQ numbers */
+
+#define IRQ_IPI_SMP_FUNCTION 3
+#define IRQ_IPI_SMP_RESCHEDULE 4
+#define IRQ_MSGRING 6
+#define IRQ_TIMER 7
+
+#endif
diff --git a/arch/mips/include/asm/netlogic/mips-extns.h b/arch/mips/include/asm/netlogic/mips-extns.h
new file mode 100644
index 00000000..8c53d0ba
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/mips-extns.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_MIPS_EXTS_H
+#define _ASM_NLM_MIPS_EXTS_H
+
+/*
+ * XLR and XLP interrupt request and interrupt mask registers
+ */
+#define read_c0_eirr() __read_64bit_c0_register($9, 6)
+#define read_c0_eimr() __read_64bit_c0_register($9, 7)
+#define write_c0_eirr(val) __write_64bit_c0_register($9, 6, val)
+
+/*
+ * Writing EIMR in 32 bit is a special case, the lower 8 bit of the
+ * EIMR is shadowed in the status register, so we cannot save and
+ * restore status register for split read.
+ */
+#define write_c0_eimr(val) \
+do { \
+ if (sizeof(unsigned long) == 4) { \
+ unsigned long __flags; \
+ \
+ local_irq_save(__flags); \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dsll\t%L0, %L0, 32\n\t" \
+ "dsrl\t%L0, %L0, 32\n\t" \
+ "dsll\t%M0, %M0, 32\n\t" \
+ "or\t%L0, %L0, %M0\n\t" \
+ "dmtc0\t%L0, $9, 7\n\t" \
+ ".set\tmips0" \
+ : : "r" (val)); \
+ __flags = (__flags & 0xffff00ff) | (((val) & 0xff) << 8);\
+ local_irq_restore(__flags); \
+ } else \
+ __write_64bit_c0_register($9, 7, (val)); \
+} while (0)
+
+static inline int hard_smp_processor_id(void)
+{
+ return __read_32bit_c0_register($15, 1) & 0x3ff;
+}
+
+#endif /*_ASM_NLM_MIPS_EXTS_H */
diff --git a/arch/mips/include/asm/netlogic/psb-bootinfo.h b/arch/mips/include/asm/netlogic/psb-bootinfo.h
new file mode 100644
index 00000000..6878307f
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/psb-bootinfo.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NETLOGIC_BOOTINFO_H
+#define _ASM_NETLOGIC_BOOTINFO_H
+
+struct psb_info {
+ uint64_t boot_level;
+ uint64_t io_base;
+ uint64_t output_device;
+ uint64_t uart_print;
+ uint64_t led_output;
+ uint64_t init;
+ uint64_t exit;
+ uint64_t warm_reset;
+ uint64_t wakeup;
+ uint64_t online_cpu_map;
+ uint64_t master_reentry_sp;
+ uint64_t master_reentry_gp;
+ uint64_t master_reentry_fn;
+ uint64_t slave_reentry_fn;
+ uint64_t magic_dword;
+ uint64_t uart_putchar;
+ uint64_t size;
+ uint64_t uart_getchar;
+ uint64_t nmi_handler;
+ uint64_t psb_version;
+ uint64_t mac_addr;
+ uint64_t cpu_frequency;
+ uint64_t board_version;
+ uint64_t malloc;
+ uint64_t free;
+ uint64_t global_shmem_addr;
+ uint64_t global_shmem_size;
+ uint64_t psb_os_cpu_map;
+ uint64_t userapp_cpu_map;
+ uint64_t wakeup_os;
+ uint64_t psb_mem_map;
+ uint64_t board_major_version;
+ uint64_t board_minor_version;
+ uint64_t board_manf_revision;
+ uint64_t board_serial_number;
+ uint64_t psb_physaddr_map;
+ uint64_t xlr_loaderip_config;
+ uint64_t bldr_envp;
+ uint64_t avail_mem_map;
+};
+
+enum {
+ NETLOGIC_IO_SPACE = 0x10,
+ PCIX_IO_SPACE,
+ PCIX_CFG_SPACE,
+ PCIX_MEMORY_SPACE,
+ HT_IO_SPACE,
+ HT_CFG_SPACE,
+ HT_MEMORY_SPACE,
+ SRAM_SPACE,
+ FLASH_CONTROLLER_SPACE
+};
+
+#define NLM_MAX_ARGS 64
+#define NLM_MAX_ENVS 32
+
+/* This is what netlboot passes and linux boot_mem_map is subtly different */
+#define NLM_BOOT_MEM_MAP_MAX 32
+struct nlm_boot_mem_map {
+ int nr_map;
+ struct nlm_boot_mem_map_entry {
+ uint64_t addr; /* start of memory segment */
+ uint64_t size; /* size of memory segment */
+ uint32_t type; /* type of memory segment */
+ } map[NLM_BOOT_MEM_MAP_MAX];
+};
+
+/* Pointer to saved boot loader info */
+extern struct psb_info nlm_prom_info;
+
+#endif
diff --git a/arch/mips/include/asm/netlogic/xlr/gpio.h b/arch/mips/include/asm/netlogic/xlr/gpio.h
new file mode 100644
index 00000000..51f6ad4a
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlr/gpio.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_GPIO_H
+#define _ASM_NLM_GPIO_H
+
+#define NETLOGIC_GPIO_INT_EN_REG 0
+#define NETLOGIC_GPIO_INPUT_INVERSION_REG 1
+#define NETLOGIC_GPIO_IO_DIR_REG 2
+#define NETLOGIC_GPIO_IO_DATA_WR_REG 3
+#define NETLOGIC_GPIO_IO_DATA_RD_REG 4
+
+#define NETLOGIC_GPIO_SWRESET_REG 8
+#define NETLOGIC_GPIO_DRAM1_CNTRL_REG 9
+#define NETLOGIC_GPIO_DRAM1_RATIO_REG 10
+#define NETLOGIC_GPIO_DRAM1_RESET_REG 11
+#define NETLOGIC_GPIO_DRAM1_STATUS_REG 12
+#define NETLOGIC_GPIO_DRAM2_CNTRL_REG 13
+#define NETLOGIC_GPIO_DRAM2_RATIO_REG 14
+#define NETLOGIC_GPIO_DRAM2_RESET_REG 15
+#define NETLOGIC_GPIO_DRAM2_STATUS_REG 16
+
+#define NETLOGIC_GPIO_PWRON_RESET_CFG_REG 21
+#define NETLOGIC_GPIO_BIST_ALL_GO_STATUS_REG 24
+#define NETLOGIC_GPIO_BIST_CPU_GO_STATUS_REG 25
+#define NETLOGIC_GPIO_BIST_DEV_GO_STATUS_REG 26
+
+#define NETLOGIC_GPIO_FUSE_BANK_REG 35
+#define NETLOGIC_GPIO_CPU_RESET_REG 40
+#define NETLOGIC_GPIO_RNG_REG 43
+
+#define NETLOGIC_PWRON_RESET_PCMCIA_BOOT 17
+#define NETLOGIC_GPIO_LED_BITMAP 0x1700000
+#define NETLOGIC_GPIO_LED_0_SHIFT 20
+#define NETLOGIC_GPIO_LED_1_SHIFT 24
+
+#define NETLOGIC_GPIO_LED_OUTPUT_CODE_RESET 0x01
+#define NETLOGIC_GPIO_LED_OUTPUT_CODE_HARD_RESET 0x02
+#define NETLOGIC_GPIO_LED_OUTPUT_CODE_SOFT_RESET 0x03
+#define NETLOGIC_GPIO_LED_OUTPUT_CODE_MAIN 0x04
+
+#endif
diff --git a/arch/mips/include/asm/netlogic/xlr/iomap.h b/arch/mips/include/asm/netlogic/xlr/iomap.h
new file mode 100644
index 00000000..2e3a4dd5
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlr/iomap.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_IOMAP_H
+#define _ASM_NLM_IOMAP_H
+
+#define DEFAULT_NETLOGIC_IO_BASE CKSEG1ADDR(0x1ef00000)
+#define NETLOGIC_IO_DDR2_CHN0_OFFSET 0x01000
+#define NETLOGIC_IO_DDR2_CHN1_OFFSET 0x02000
+#define NETLOGIC_IO_DDR2_CHN2_OFFSET 0x03000
+#define NETLOGIC_IO_DDR2_CHN3_OFFSET 0x04000
+#define NETLOGIC_IO_PIC_OFFSET 0x08000
+#define NETLOGIC_IO_UART_0_OFFSET 0x14000
+#define NETLOGIC_IO_UART_1_OFFSET 0x15100
+
+#define NETLOGIC_IO_SIZE 0x1000
+
+#define NETLOGIC_IO_BRIDGE_OFFSET 0x00000
+
+#define NETLOGIC_IO_RLD2_CHN0_OFFSET 0x05000
+#define NETLOGIC_IO_RLD2_CHN1_OFFSET 0x06000
+
+#define NETLOGIC_IO_SRAM_OFFSET 0x07000
+
+#define NETLOGIC_IO_PCIX_OFFSET 0x09000
+#define NETLOGIC_IO_HT_OFFSET 0x0A000
+
+#define NETLOGIC_IO_SECURITY_OFFSET 0x0B000
+
+#define NETLOGIC_IO_GMAC_0_OFFSET 0x0C000
+#define NETLOGIC_IO_GMAC_1_OFFSET 0x0D000
+#define NETLOGIC_IO_GMAC_2_OFFSET 0x0E000
+#define NETLOGIC_IO_GMAC_3_OFFSET 0x0F000
+
+/* XLS devices */
+#define NETLOGIC_IO_GMAC_4_OFFSET 0x20000
+#define NETLOGIC_IO_GMAC_5_OFFSET 0x21000
+#define NETLOGIC_IO_GMAC_6_OFFSET 0x22000
+#define NETLOGIC_IO_GMAC_7_OFFSET 0x23000
+
+#define NETLOGIC_IO_PCIE_0_OFFSET 0x1E000
+#define NETLOGIC_IO_PCIE_1_OFFSET 0x1F000
+#define NETLOGIC_IO_SRIO_0_OFFSET 0x1E000
+#define NETLOGIC_IO_SRIO_1_OFFSET 0x1F000
+
+#define NETLOGIC_IO_USB_0_OFFSET 0x24000
+#define NETLOGIC_IO_USB_1_OFFSET 0x25000
+
+#define NETLOGIC_IO_COMP_OFFSET 0x1D000
+/* end XLS devices */
+
+/* XLR devices */
+#define NETLOGIC_IO_SPI4_0_OFFSET 0x10000
+#define NETLOGIC_IO_XGMAC_0_OFFSET 0x11000
+#define NETLOGIC_IO_SPI4_1_OFFSET 0x12000
+#define NETLOGIC_IO_XGMAC_1_OFFSET 0x13000
+/* end XLR devices */
+
+#define NETLOGIC_IO_I2C_0_OFFSET 0x16000
+#define NETLOGIC_IO_I2C_1_OFFSET 0x17000
+
+#define NETLOGIC_IO_GPIO_OFFSET 0x18000
+#define NETLOGIC_IO_FLASH_OFFSET 0x19000
+#define NETLOGIC_IO_TB_OFFSET 0x1C000
+
+#define NETLOGIC_CPLD_OFFSET KSEG1ADDR(0x1d840000)
+
+/*
+ * Base Address (Virtual) of the PCI Config address space
+ * For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28)
+ * Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes
+ * ie 1<<24 = 16M
+ */
+#define DEFAULT_PCI_CONFIG_BASE 0x18000000
+#define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000
+#define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+typedef volatile __u32 nlm_reg_t;
+extern unsigned long netlogic_io_base;
+
+/* FIXME read once in write_reg */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define netlogic_read_reg(base, offset) ((base)[(offset)])
+#define netlogic_write_reg(base, offset, value) ((base)[(offset)] = (value))
+#else
+#define netlogic_read_reg(base, offset) (be32_to_cpu((base)[(offset)]))
+#define netlogic_write_reg(base, offset, value) \
+ ((base)[(offset)] = cpu_to_be32((value)))
+#endif
+
+#define netlogic_read_reg_le32(base, offset) (le32_to_cpu((base)[(offset)]))
+#define netlogic_write_reg_le32(base, offset, value) \
+ ((base)[(offset)] = cpu_to_le32((value)))
+#define netlogic_io_mmio(offset) ((nlm_reg_t *)(netlogic_io_base+(offset)))
+#endif /* __ASSEMBLY__ */
+#endif
diff --git a/arch/mips/include/asm/netlogic/xlr/pic.h b/arch/mips/include/asm/netlogic/xlr/pic.h
new file mode 100644
index 00000000..5cceb746
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlr/pic.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_XLR_PIC_H
+#define _ASM_NLM_XLR_PIC_H
+
+#define PIC_CLKS_PER_SEC 66666666ULL
+/* PIC hardware interrupt numbers */
+#define PIC_IRT_WD_INDEX 0
+#define PIC_IRT_TIMER_0_INDEX 1
+#define PIC_IRT_TIMER_1_INDEX 2
+#define PIC_IRT_TIMER_2_INDEX 3
+#define PIC_IRT_TIMER_3_INDEX 4
+#define PIC_IRT_TIMER_4_INDEX 5
+#define PIC_IRT_TIMER_5_INDEX 6
+#define PIC_IRT_TIMER_6_INDEX 7
+#define PIC_IRT_TIMER_7_INDEX 8
+#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX
+#define PIC_IRT_UART_0_INDEX 9
+#define PIC_IRT_UART_1_INDEX 10
+#define PIC_IRT_I2C_0_INDEX 11
+#define PIC_IRT_I2C_1_INDEX 12
+#define PIC_IRT_PCMCIA_INDEX 13
+#define PIC_IRT_GPIO_INDEX 14
+#define PIC_IRT_HYPER_INDEX 15
+#define PIC_IRT_PCIX_INDEX 16
+/* XLS */
+#define PIC_IRT_CDE_INDEX 15
+#define PIC_IRT_BRIDGE_TB_XLS_INDEX 16
+/* XLS */
+#define PIC_IRT_GMAC0_INDEX 17
+#define PIC_IRT_GMAC1_INDEX 18
+#define PIC_IRT_GMAC2_INDEX 19
+#define PIC_IRT_GMAC3_INDEX 20
+#define PIC_IRT_XGS0_INDEX 21
+#define PIC_IRT_XGS1_INDEX 22
+#define PIC_IRT_HYPER_FATAL_INDEX 23
+#define PIC_IRT_PCIX_FATAL_INDEX 24
+#define PIC_IRT_BRIDGE_AERR_INDEX 25
+#define PIC_IRT_BRIDGE_BERR_INDEX 26
+#define PIC_IRT_BRIDGE_TB_XLR_INDEX 27
+#define PIC_IRT_BRIDGE_AERR_NMI_INDEX 28
+/* XLS */
+#define PIC_IRT_GMAC4_INDEX 21
+#define PIC_IRT_GMAC5_INDEX 22
+#define PIC_IRT_GMAC6_INDEX 23
+#define PIC_IRT_GMAC7_INDEX 24
+#define PIC_IRT_BRIDGE_ERR_INDEX 25
+#define PIC_IRT_PCIE_LINK0_INDEX 26
+#define PIC_IRT_PCIE_LINK1_INDEX 27
+#define PIC_IRT_PCIE_LINK2_INDEX 23
+#define PIC_IRT_PCIE_LINK3_INDEX 24
+#define PIC_IRT_PCIE_XLSB0_LINK2_INDEX 28
+#define PIC_IRT_PCIE_XLSB0_LINK3_INDEX 29
+#define PIC_IRT_SRIO_LINK0_INDEX 26
+#define PIC_IRT_SRIO_LINK1_INDEX 27
+#define PIC_IRT_SRIO_LINK2_INDEX 28
+#define PIC_IRT_SRIO_LINK3_INDEX 29
+#define PIC_IRT_PCIE_INT_INDEX 28
+#define PIC_IRT_PCIE_FATAL_INDEX 29
+#define PIC_IRT_GPIO_B_INDEX 30
+#define PIC_IRT_USB_INDEX 31
+/* XLS */
+#define PIC_NUM_IRTS 32
+
+
+#define PIC_CLOCK_TIMER 7
+
+/* PIC Registers */
+#define PIC_CTRL 0x00
+#define PIC_IPI 0x04
+#define PIC_INT_ACK 0x06
+
+#define WD_MAX_VAL_0 0x08
+#define WD_MAX_VAL_1 0x09
+#define WD_MASK_0 0x0a
+#define WD_MASK_1 0x0b
+#define WD_HEARBEAT_0 0x0c
+#define WD_HEARBEAT_1 0x0d
+
+#define PIC_IRT_0_BASE 0x40
+#define PIC_IRT_1_BASE 0x80
+#define PIC_TIMER_MAXVAL_0_BASE 0x100
+#define PIC_TIMER_MAXVAL_1_BASE 0x110
+#define PIC_TIMER_COUNT_0_BASE 0x120
+#define PIC_TIMER_COUNT_1_BASE 0x130
+
+#define PIC_IRT_0(picintr) (PIC_IRT_0_BASE + (picintr))
+#define PIC_IRT_1(picintr) (PIC_IRT_1_BASE + (picintr))
+
+#define PIC_TIMER_MAXVAL_0(i) (PIC_TIMER_MAXVAL_0_BASE + (i))
+#define PIC_TIMER_MAXVAL_1(i) (PIC_TIMER_MAXVAL_1_BASE + (i))
+#define PIC_TIMER_COUNT_0(i) (PIC_TIMER_COUNT_0_BASE + (i))
+#define PIC_TIMER_COUNT_1(i) (PIC_TIMER_COUNT_0_BASE + (i))
+
+/*
+ * Mapping between hardware interrupt numbers and IRQs on CPU
+ * we use a simple scheme to map PIC interrupts 0-31 to IRQs
+ * 8-39. This leaves the IRQ 0-7 for cpu interrupts like
+ * count/compare and FMN
+ */
+#define PIC_IRQ_BASE 8
+#define PIC_INTR_TO_IRQ(i) (PIC_IRQ_BASE + (i))
+#define PIC_IRQ_TO_INTR(i) ((i) - PIC_IRQ_BASE)
+
+#define PIC_IRT_FIRST_IRQ PIC_IRQ_BASE
+#define PIC_WD_IRQ PIC_INTR_TO_IRQ(PIC_IRT_WD_INDEX)
+#define PIC_TIMER_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_0_INDEX)
+#define PIC_TIMER_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_1_INDEX)
+#define PIC_TIMER_2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_2_INDEX)
+#define PIC_TIMER_3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_3_INDEX)
+#define PIC_TIMER_4_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_4_INDEX)
+#define PIC_TIMER_5_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_5_INDEX)
+#define PIC_TIMER_6_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_6_INDEX)
+#define PIC_TIMER_7_IRQ PIC_INTR_TO_IRQ(PIC_IRT_TIMER_7_INDEX)
+#define PIC_CLOCK_IRQ (PIC_TIMER_7_IRQ)
+#define PIC_UART_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_UART_0_INDEX)
+#define PIC_UART_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_UART_1_INDEX)
+#define PIC_I2C_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_I2C_0_INDEX)
+#define PIC_I2C_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_I2C_1_INDEX)
+#define PIC_PCMCIA_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCMCIA_INDEX)
+#define PIC_GPIO_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GPIO_INDEX)
+#define PIC_HYPER_IRQ PIC_INTR_TO_IRQ(PIC_IRT_HYPER_INDEX)
+#define PIC_PCIX_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIX_INDEX)
+/* XLS */
+#define PIC_CDE_IRQ PIC_INTR_TO_IRQ(PIC_IRT_CDE_INDEX)
+#define PIC_BRIDGE_TB_XLS_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_TB_XLS_INDEX)
+/* end XLS */
+#define PIC_GMAC_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC0_INDEX)
+#define PIC_GMAC_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC1_INDEX)
+#define PIC_GMAC_2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC2_INDEX)
+#define PIC_GMAC_3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC3_INDEX)
+#define PIC_XGS_0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_XGS0_INDEX)
+#define PIC_XGS_1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_XGS1_INDEX)
+#define PIC_HYPER_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_HYPER_FATAL_INDEX)
+#define PIC_PCIX_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIX_FATAL_INDEX)
+#define PIC_BRIDGE_AERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_AERR_INDEX)
+#define PIC_BRIDGE_BERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_BERR_INDEX)
+#define PIC_BRIDGE_TB_XLR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_TB_XLR_INDEX)
+#define PIC_BRIDGE_AERR_NMI_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_AERR_NMI_INDEX)
+/* XLS defines */
+#define PIC_GMAC_4_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC4_INDEX)
+#define PIC_GMAC_5_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC5_INDEX)
+#define PIC_GMAC_6_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC6_INDEX)
+#define PIC_GMAC_7_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GMAC7_INDEX)
+#define PIC_BRIDGE_ERR_IRQ PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_ERR_INDEX)
+#define PIC_PCIE_LINK0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK0_INDEX)
+#define PIC_PCIE_LINK1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK1_INDEX)
+#define PIC_PCIE_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK2_INDEX)
+#define PIC_PCIE_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK3_INDEX)
+#define PIC_PCIE_XLSB0_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_XLSB0_LINK2_INDEX)
+#define PIC_PCIE_XLSB0_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_XLSB0_LINK3_INDEX)
+#define PIC_SRIO_LINK0_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK0_INDEX)
+#define PIC_SRIO_LINK1_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK1_INDEX)
+#define PIC_SRIO_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK2_INDEX)
+#define PIC_SRIO_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK3_INDEX)
+#define PIC_PCIE_INT_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_INT__INDEX)
+#define PIC_PCIE_FATAL_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_FATAL_INDEX)
+#define PIC_GPIO_B_IRQ PIC_INTR_TO_IRQ(PIC_IRT_GPIO_B_INDEX)
+#define PIC_USB_IRQ PIC_INTR_TO_IRQ(PIC_IRT_USB_INDEX)
+#define PIC_IRT_LAST_IRQ PIC_USB_IRQ
+/* end XLS */
+
+#ifndef __ASSEMBLY__
+static inline void pic_send_ipi(u32 ipi)
+{
+ nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+
+ netlogic_write_reg(mmio, PIC_IPI, ipi);
+}
+
+static inline u32 pic_read_control(void)
+{
+ nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+
+ return netlogic_read_reg(mmio, PIC_CTRL);
+}
+
+static inline void pic_write_control(u32 control)
+{
+ nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+
+ netlogic_write_reg(mmio, PIC_CTRL, control);
+}
+
+static inline void pic_update_control(u32 control)
+{
+ nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+
+ netlogic_write_reg(mmio, PIC_CTRL,
+ (control | netlogic_read_reg(mmio, PIC_CTRL)));
+}
+
+#define PIC_IRQ_IS_EDGE_TRIGGERED(irq) (((irq) >= PIC_TIMER_0_IRQ) && \
+ ((irq) <= PIC_TIMER_7_IRQ))
+#define PIC_IRQ_IS_IRT(irq) (((irq) >= PIC_IRT_FIRST_IRQ) && \
+ ((irq) <= PIC_IRT_LAST_IRQ))
+#endif
+
+#endif /* _ASM_NLM_XLR_PIC_H */
diff --git a/arch/mips/include/asm/netlogic/xlr/xlr.h b/arch/mips/include/asm/netlogic/xlr/xlr.h
new file mode 100644
index 00000000..3e637269
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlr/xlr.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_XLR_H
+#define _ASM_NLM_XLR_H
+
+/* Platform UART functions */
+struct uart_port;
+unsigned int nlm_xlr_uart_in(struct uart_port *, int);
+void nlm_xlr_uart_out(struct uart_port *, int, int);
+
+/* SMP support functions */
+struct irq_desc;
+void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
+void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
+int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
+void nlm_smp_irq_init(void);
+void nlm_boot_smp_nmi(void);
+void prom_pre_boot_secondary_cpus(void);
+
+extern struct plat_smp_ops nlm_smp_ops;
+extern unsigned long nlm_common_ebase;
+
+/* XLS B silicon "Rook" */
+static inline unsigned int nlm_chip_is_xls_b(void)
+{
+ uint32_t prid = read_c0_prid();
+
+ return ((prid & 0xf000) == 0x4000);
+}
+
+/*
+ * XLR chip types
+ */
+ /* The XLS product line has chip versions 0x[48c]? */
+static inline unsigned int nlm_chip_is_xls(void)
+{
+ uint32_t prid = read_c0_prid();
+
+ return ((prid & 0xf000) == 0x8000 || (prid & 0xf000) == 0x4000 ||
+ (prid & 0xf000) == 0xc000);
+}
+
+#endif /* _ASM_NLM_XLR_H */
diff --git a/arch/mips/include/asm/nile4.h b/arch/mips/include/asm/nile4.h
new file mode 100644
index 00000000..af0e51a9
--- /dev/null
+++ b/arch/mips/include/asm/nile4.h
@@ -0,0 +1,309 @@
+/*
+ * asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions
+ *
+ * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
+ * Sony Software Development Center Europe (SDCE), Brussels
+ *
+ * This file is based on the following documentation:
+ *
+ * NEC Vrc 5074 System Controller Data Sheet, June 1998
+ */
+
+#ifndef _ASM_NILE4_H
+#define _ASM_NILE4_H
+
+#define NILE4_BASE 0xbfa00000
+#define NILE4_SIZE 0x00200000 /* 2 MB */
+
+
+ /*
+ * Physical Device Address Registers (PDARs)
+ */
+
+#define NILE4_SDRAM0 0x0000 /* SDRAM Bank 0 [R/W] */
+#define NILE4_SDRAM1 0x0008 /* SDRAM Bank 1 [R/W] */
+#define NILE4_DCS2 0x0010 /* Device Chip-Select 2 [R/W] */
+#define NILE4_DCS3 0x0018 /* Device Chip-Select 3 [R/W] */
+#define NILE4_DCS4 0x0020 /* Device Chip-Select 4 [R/W] */
+#define NILE4_DCS5 0x0028 /* Device Chip-Select 5 [R/W] */
+#define NILE4_DCS6 0x0030 /* Device Chip-Select 6 [R/W] */
+#define NILE4_DCS7 0x0038 /* Device Chip-Select 7 [R/W] */
+#define NILE4_DCS8 0x0040 /* Device Chip-Select 8 [R/W] */
+#define NILE4_PCIW0 0x0060 /* PCI Address Window 0 [R/W] */
+#define NILE4_PCIW1 0x0068 /* PCI Address Window 1 [R/W] */
+#define NILE4_INTCS 0x0070 /* Controller Internal Registers and Devices */
+ /* [R/W] */
+#define NILE4_BOOTCS 0x0078 /* Boot ROM Chip-Select [R/W] */
+
+
+ /*
+ * CPU Interface Registers
+ */
+
+#define NILE4_CPUSTAT 0x0080 /* CPU Status [R/W] */
+#define NILE4_INTCTRL 0x0088 /* Interrupt Control [R/W] */
+#define NILE4_INTSTAT0 0x0090 /* Interrupt Status 0 [R] */
+#define NILE4_INTSTAT1 0x0098 /* Interrupt Status 1 and CPU Interrupt */
+ /* Enable [R/W] */
+#define NILE4_INTCLR 0x00A0 /* Interrupt Clear [R/W] */
+#define NILE4_INTPPES 0x00A8 /* PCI Interrupt Control [R/W] */
+
+
+ /*
+ * Memory-Interface Registers
+ */
+
+#define NILE4_MEMCTRL 0x00C0 /* Memory Control */
+#define NILE4_ACSTIME 0x00C8 /* Memory Access Timing [R/W] */
+#define NILE4_CHKERR 0x00D0 /* Memory Check Error Status [R] */
+
+
+ /*
+ * PCI-Bus Registers
+ */
+
+#define NILE4_PCICTRL 0x00E0 /* PCI Control [R/W] */
+#define NILE4_PCIARB 0x00E8 /* PCI Arbiter [R/W] */
+#define NILE4_PCIINIT0 0x00F0 /* PCI Master (Initiator) 0 [R/W] */
+#define NILE4_PCIINIT1 0x00F8 /* PCI Master (Initiator) 1 [R/W] */
+#define NILE4_PCIERR 0x00B8 /* PCI Error [R/W] */
+
+
+ /*
+ * Local-Bus Registers
+ */
+
+#define NILE4_LCNFG 0x0100 /* Local Bus Configuration [R/W] */
+#define NILE4_LCST2 0x0110 /* Local Bus Chip-Select Timing 2 [R/W] */
+#define NILE4_LCST3 0x0118 /* Local Bus Chip-Select Timing 3 [R/W] */
+#define NILE4_LCST4 0x0120 /* Local Bus Chip-Select Timing 4 [R/W] */
+#define NILE4_LCST5 0x0128 /* Local Bus Chip-Select Timing 5 [R/W] */
+#define NILE4_LCST6 0x0130 /* Local Bus Chip-Select Timing 6 [R/W] */
+#define NILE4_LCST7 0x0138 /* Local Bus Chip-Select Timing 7 [R/W] */
+#define NILE4_LCST8 0x0140 /* Local Bus Chip-Select Timing 8 [R/W] */
+#define NILE4_DCSFN 0x0150 /* Device Chip-Select Muxing and Output */
+ /* Enables [R/W] */
+#define NILE4_DCSIO 0x0158 /* Device Chip-Selects As I/O Bits [R/W] */
+#define NILE4_BCST 0x0178 /* Local Boot Chip-Select Timing [R/W] */
+
+
+ /*
+ * DMA Registers
+ */
+
+#define NILE4_DMACTRL0 0x0180 /* DMA Control 0 [R/W] */
+#define NILE4_DMASRCA0 0x0188 /* DMA Source Address 0 [R/W] */
+#define NILE4_DMADESA0 0x0190 /* DMA Destination Address 0 [R/W] */
+#define NILE4_DMACTRL1 0x0198 /* DMA Control 1 [R/W] */
+#define NILE4_DMASRCA1 0x01A0 /* DMA Source Address 1 [R/W] */
+#define NILE4_DMADESA1 0x01A8 /* DMA Destination Address 1 [R/W] */
+
+
+ /*
+ * Timer Registers
+ */
+
+#define NILE4_T0CTRL 0x01C0 /* SDRAM Refresh Control [R/W] */
+#define NILE4_T0CNTR 0x01C8 /* SDRAM Refresh Counter [R/W] */
+#define NILE4_T1CTRL 0x01D0 /* CPU-Bus Read Time-Out Control [R/W] */
+#define NILE4_T1CNTR 0x01D8 /* CPU-Bus Read Time-Out Counter [R/W] */
+#define NILE4_T2CTRL 0x01E0 /* General-Purpose Timer Control [R/W] */
+#define NILE4_T2CNTR 0x01E8 /* General-Purpose Timer Counter [R/W] */
+#define NILE4_T3CTRL 0x01F0 /* Watchdog Timer Control [R/W] */
+#define NILE4_T3CNTR 0x01F8 /* Watchdog Timer Counter [R/W] */
+
+
+ /*
+ * PCI Configuration Space Registers
+ */
+
+#define NILE4_PCI_BASE 0x0200
+
+#define NILE4_VID 0x0200 /* PCI Vendor ID [R] */
+#define NILE4_DID 0x0202 /* PCI Device ID [R] */
+#define NILE4_PCICMD 0x0204 /* PCI Command [R/W] */
+#define NILE4_PCISTS 0x0206 /* PCI Status [R/W] */
+#define NILE4_REVID 0x0208 /* PCI Revision ID [R] */
+#define NILE4_CLASS 0x0209 /* PCI Class Code [R] */
+#define NILE4_CLSIZ 0x020C /* PCI Cache Line Size [R/W] */
+#define NILE4_MLTIM 0x020D /* PCI Latency Timer [R/W] */
+#define NILE4_HTYPE 0x020E /* PCI Header Type [R] */
+#define NILE4_BIST 0x020F /* BIST [R] (unimplemented) */
+#define NILE4_BARC 0x0210 /* PCI Base Address Register Control [R/W] */
+#define NILE4_BAR0 0x0218 /* PCI Base Address Register 0 [R/W] */
+#define NILE4_BAR1 0x0220 /* PCI Base Address Register 1 [R/W] */
+#define NILE4_CIS 0x0228 /* PCI Cardbus CIS Pointer [R] */
+ /* (unimplemented) */
+#define NILE4_SSVID 0x022C /* PCI Sub-System Vendor ID [R/W] */
+#define NILE4_SSID 0x022E /* PCI Sub-System ID [R/W] */
+#define NILE4_ROM 0x0230 /* Expansion ROM Base Address [R] */
+ /* (unimplemented) */
+#define NILE4_INTLIN 0x023C /* PCI Interrupt Line [R/W] */
+#define NILE4_INTPIN 0x023D /* PCI Interrupt Pin [R] */
+#define NILE4_MINGNT 0x023E /* PCI Min_Gnt [R] (unimplemented) */
+#define NILE4_MAXLAT 0x023F /* PCI Max_Lat [R] (unimplemented) */
+#define NILE4_BAR2 0x0240 /* PCI Base Address Register 2 [R/W] */
+#define NILE4_BAR3 0x0248 /* PCI Base Address Register 3 [R/W] */
+#define NILE4_BAR4 0x0250 /* PCI Base Address Register 4 [R/W] */
+#define NILE4_BAR5 0x0258 /* PCI Base Address Register 5 [R/W] */
+#define NILE4_BAR6 0x0260 /* PCI Base Address Register 6 [R/W] */
+#define NILE4_BAR7 0x0268 /* PCI Base Address Register 7 [R/W] */
+#define NILE4_BAR8 0x0270 /* PCI Base Address Register 8 [R/W] */
+#define NILE4_BARB 0x0278 /* PCI Base Address Register BOOT [R/W] */
+
+
+ /*
+ * Serial-Port Registers
+ */
+
+#define NILE4_UART_BASE 0x0300
+
+#define NILE4_UARTRBR 0x0300 /* UART Receiver Data Buffer [R] */
+#define NILE4_UARTTHR 0x0300 /* UART Transmitter Data Holding [W] */
+#define NILE4_UARTIER 0x0308 /* UART Interrupt Enable [R/W] */
+#define NILE4_UARTDLL 0x0300 /* UART Divisor Latch LSB [R/W] */
+#define NILE4_UARTDLM 0x0308 /* UART Divisor Latch MSB [R/W] */
+#define NILE4_UARTIIR 0x0310 /* UART Interrupt ID [R] */
+#define NILE4_UARTFCR 0x0310 /* UART FIFO Control [W] */
+#define NILE4_UARTLCR 0x0318 /* UART Line Control [R/W] */
+#define NILE4_UARTMCR 0x0320 /* UART Modem Control [R/W] */
+#define NILE4_UARTLSR 0x0328 /* UART Line Status [R/W] */
+#define NILE4_UARTMSR 0x0330 /* UART Modem Status [R/W] */
+#define NILE4_UARTSCR 0x0338 /* UART Scratch [R/W] */
+
+#define NILE4_UART_BASE_BAUD 520833 /* 100 MHz / 12 / 16 */
+
+
+ /*
+ * Interrupt Lines
+ */
+
+#define NILE4_INT_CPCE 0 /* CPU-Interface Parity-Error Interrupt */
+#define NILE4_INT_CNTD 1 /* CPU No-Target Decode Interrupt */
+#define NILE4_INT_MCE 2 /* Memory-Check Error Interrupt */
+#define NILE4_INT_DMA 3 /* DMA Controller Interrupt */
+#define NILE4_INT_UART 4 /* UART Interrupt */
+#define NILE4_INT_WDOG 5 /* Watchdog Timer Interrupt */
+#define NILE4_INT_GPT 6 /* General-Purpose Timer Interrupt */
+#define NILE4_INT_LBRTD 7 /* Local-Bus Ready Timer Interrupt */
+#define NILE4_INT_INTA 8 /* PCI Interrupt Signal INTA# */
+#define NILE4_INT_INTB 9 /* PCI Interrupt Signal INTB# */
+#define NILE4_INT_INTC 10 /* PCI Interrupt Signal INTC# */
+#define NILE4_INT_INTD 11 /* PCI Interrupt Signal INTD# */
+#define NILE4_INT_INTE 12 /* PCI Interrupt Signal INTE# (ISA cascade) */
+#define NILE4_INT_RESV 13 /* Reserved */
+#define NILE4_INT_PCIS 14 /* PCI SERR# Interrupt */
+#define NILE4_INT_PCIE 15 /* PCI Internal Error Interrupt */
+
+
+ /*
+ * Nile 4 Register Access
+ */
+
+static inline void nile4_sync(void)
+{
+ volatile u32 *p = (volatile u32 *)0xbfc00000;
+ (void)(*p);
+}
+
+static inline void nile4_out32(u32 offset, u32 val)
+{
+ *(volatile u32 *)(NILE4_BASE+offset) = val;
+ nile4_sync();
+}
+
+static inline u32 nile4_in32(u32 offset)
+{
+ u32 val = *(volatile u32 *)(NILE4_BASE+offset);
+ nile4_sync();
+ return val;
+}
+
+static inline void nile4_out16(u32 offset, u16 val)
+{
+ *(volatile u16 *)(NILE4_BASE+offset) = val;
+ nile4_sync();
+}
+
+static inline u16 nile4_in16(u32 offset)
+{
+ u16 val = *(volatile u16 *)(NILE4_BASE+offset);
+ nile4_sync();
+ return val;
+}
+
+static inline void nile4_out8(u32 offset, u8 val)
+{
+ *(volatile u8 *)(NILE4_BASE+offset) = val;
+ nile4_sync();
+}
+
+static inline u8 nile4_in8(u32 offset)
+{
+ u8 val = *(volatile u8 *)(NILE4_BASE+offset);
+ nile4_sync();
+ return val;
+}
+
+
+ /*
+ * Physical Device Address Registers
+ */
+
+extern void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width,
+ int on_memory_bus, int visible);
+
+
+ /*
+ * PCI Master Registers
+ */
+
+#define NILE4_PCICMD_IACK 0 /* PCI Interrupt Acknowledge */
+#define NILE4_PCICMD_IO 1 /* PCI I/O Space */
+#define NILE4_PCICMD_MEM 3 /* PCI Memory Space */
+#define NILE4_PCICMD_CFG 5 /* PCI Configuration Space */
+
+
+ /*
+ * PCI Address Spaces
+ *
+ * Note that these are multiplexed using PCIINIT[01]!
+ */
+
+#define NILE4_PCI_IO_BASE 0xa6000000
+#define NILE4_PCI_MEM_BASE 0xa8000000
+#define NILE4_PCI_CFG_BASE NILE4_PCI_MEM_BASE
+#define NILE4_PCI_IACK_BASE NILE4_PCI_IO_BASE
+
+
+extern void nile4_set_pmr(u32 pmr, u32 type, u32 addr);
+
+
+ /*
+ * Interrupt Programming
+ */
+
+#define NUM_I8259_INTERRUPTS 16
+#define NUM_NILE4_INTERRUPTS 16
+
+#define IRQ_I8259_CASCADE NILE4_INT_INTE
+#define is_i8259_irq(irq) ((irq) < NUM_I8259_INTERRUPTS)
+#define nile4_to_irq(n) ((n)+NUM_I8259_INTERRUPTS)
+#define irq_to_nile4(n) ((n)-NUM_I8259_INTERRUPTS)
+
+extern void nile4_map_irq(int nile4_irq, int cpu_irq);
+extern void nile4_map_irq_all(int cpu_irq);
+extern void nile4_enable_irq(unsigned int nile4_irq);
+extern void nile4_disable_irq(unsigned int nile4_irq);
+extern void nile4_disable_irq_all(void);
+extern u16 nile4_get_irq_stat(int cpu_irq);
+extern void nile4_enable_irq_output(int cpu_irq);
+extern void nile4_disable_irq_output(int cpu_irq);
+extern void nile4_set_pci_irq_polarity(int pci_irq, int high);
+extern void nile4_set_pci_irq_level_or_edge(int pci_irq, int level);
+extern void nile4_clear_irq(int nile4_irq);
+extern void nile4_clear_irq_mask(u32 mask);
+extern u8 nile4_i8259_iack(void);
+extern void nile4_dump_irq_status(void); /* Debug */
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-agl-defs.h b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
new file mode 100644
index 00000000..30d68f23
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
@@ -0,0 +1,1446 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_AGL_DEFS_H__
+#define __CVMX_AGL_DEFS_H__
+
+#define CVMX_AGL_GMX_BAD_REG (CVMX_ADD_IO_SEG(0x00011800E0000518ull))
+#define CVMX_AGL_GMX_BIST (CVMX_ADD_IO_SEG(0x00011800E0000400ull))
+#define CVMX_AGL_GMX_DRV_CTL (CVMX_ADD_IO_SEG(0x00011800E00007F0ull))
+#define CVMX_AGL_GMX_INF_MODE (CVMX_ADD_IO_SEG(0x00011800E00007F8ull))
+#define CVMX_AGL_GMX_PRTX_CFG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000010ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM0(offset) (CVMX_ADD_IO_SEG(0x00011800E0000180ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM1(offset) (CVMX_ADD_IO_SEG(0x00011800E0000188ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM2(offset) (CVMX_ADD_IO_SEG(0x00011800E0000190ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM3(offset) (CVMX_ADD_IO_SEG(0x00011800E0000198ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM4(offset) (CVMX_ADD_IO_SEG(0x00011800E00001A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM5(offset) (CVMX_ADD_IO_SEG(0x00011800E00001A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CAM_EN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000108ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_ADR_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000100ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_DECISION(offset) (CVMX_ADD_IO_SEG(0x00011800E0000040ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_CHK(offset) (CVMX_ADD_IO_SEG(0x00011800E0000020ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000018ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_MAX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000030ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_FRM_MIN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000028ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_IFG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000058ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_INT_EN(offset) (CVMX_ADD_IO_SEG(0x00011800E0000008ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_INT_REG(offset) (CVMX_ADD_IO_SEG(0x00011800E0000000ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_JABBER(offset) (CVMX_ADD_IO_SEG(0x00011800E0000038ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_PAUSE_DROP_TIME(offset) (CVMX_ADD_IO_SEG(0x00011800E0000068ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_RX_INBND(offset) (CVMX_ADD_IO_SEG(0x00011800E0000060ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000050ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS(offset) (CVMX_ADD_IO_SEG(0x00011800E0000088ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000098ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DMAC(offset) (CVMX_ADD_IO_SEG(0x00011800E00000A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_OCTS_DRP(offset) (CVMX_ADD_IO_SEG(0x00011800E00000B8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS(offset) (CVMX_ADD_IO_SEG(0x00011800E0000080ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(offset) (CVMX_ADD_IO_SEG(0x00011800E00000C0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000090ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DMAC(offset) (CVMX_ADD_IO_SEG(0x00011800E00000A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(offset) (CVMX_ADD_IO_SEG(0x00011800E00000B0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RXX_UDD_SKP(offset) (CVMX_ADD_IO_SEG(0x00011800E0000048ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_RX_BP_DROPX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000420ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_BP_OFFX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000460ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_BP_ONX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000440ull) + ((offset) & 1) * 8)
+#define CVMX_AGL_GMX_RX_PRT_INFO (CVMX_ADD_IO_SEG(0x00011800E00004E8ull))
+#define CVMX_AGL_GMX_RX_TX_STATUS (CVMX_ADD_IO_SEG(0x00011800E00007E8ull))
+#define CVMX_AGL_GMX_SMACX(offset) (CVMX_ADD_IO_SEG(0x00011800E0000230ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_STAT_BP (CVMX_ADD_IO_SEG(0x00011800E0000520ull))
+#define CVMX_AGL_GMX_TXX_APPEND(offset) (CVMX_ADD_IO_SEG(0x00011800E0000218ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_CLK(offset) (CVMX_ADD_IO_SEG(0x00011800E0000208ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000270ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_MIN_PKT(offset) (CVMX_ADD_IO_SEG(0x00011800E0000240ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_INTERVAL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000248ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_PKT_TIME(offset) (CVMX_ADD_IO_SEG(0x00011800E0000238ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_TOGO(offset) (CVMX_ADD_IO_SEG(0x00011800E0000258ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_PAUSE_ZERO(offset) (CVMX_ADD_IO_SEG(0x00011800E0000260ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_SOFT_PAUSE(offset) (CVMX_ADD_IO_SEG(0x00011800E0000250ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT0(offset) (CVMX_ADD_IO_SEG(0x00011800E0000280ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT1(offset) (CVMX_ADD_IO_SEG(0x00011800E0000288ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT2(offset) (CVMX_ADD_IO_SEG(0x00011800E0000290ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT3(offset) (CVMX_ADD_IO_SEG(0x00011800E0000298ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT4(offset) (CVMX_ADD_IO_SEG(0x00011800E00002A0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT5(offset) (CVMX_ADD_IO_SEG(0x00011800E00002A8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT6(offset) (CVMX_ADD_IO_SEG(0x00011800E00002B0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT7(offset) (CVMX_ADD_IO_SEG(0x00011800E00002B8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT8(offset) (CVMX_ADD_IO_SEG(0x00011800E00002C0ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STAT9(offset) (CVMX_ADD_IO_SEG(0x00011800E00002C8ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_STATS_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0000268ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TXX_THRESH(offset) (CVMX_ADD_IO_SEG(0x00011800E0000210ull) + ((offset) & 1) * 2048)
+#define CVMX_AGL_GMX_TX_BP (CVMX_ADD_IO_SEG(0x00011800E00004D0ull))
+#define CVMX_AGL_GMX_TX_COL_ATTEMPT (CVMX_ADD_IO_SEG(0x00011800E0000498ull))
+#define CVMX_AGL_GMX_TX_IFG (CVMX_ADD_IO_SEG(0x00011800E0000488ull))
+#define CVMX_AGL_GMX_TX_INT_EN (CVMX_ADD_IO_SEG(0x00011800E0000508ull))
+#define CVMX_AGL_GMX_TX_INT_REG (CVMX_ADD_IO_SEG(0x00011800E0000500ull))
+#define CVMX_AGL_GMX_TX_JAM (CVMX_ADD_IO_SEG(0x00011800E0000490ull))
+#define CVMX_AGL_GMX_TX_LFSR (CVMX_ADD_IO_SEG(0x00011800E00004F8ull))
+#define CVMX_AGL_GMX_TX_OVR_BP (CVMX_ADD_IO_SEG(0x00011800E00004C8ull))
+#define CVMX_AGL_GMX_TX_PAUSE_PKT_DMAC (CVMX_ADD_IO_SEG(0x00011800E00004A0ull))
+#define CVMX_AGL_GMX_TX_PAUSE_PKT_TYPE (CVMX_ADD_IO_SEG(0x00011800E00004A8ull))
+#define CVMX_AGL_PRTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011800E0002000ull) + ((offset) & 1) * 8)
+
+union cvmx_agl_gmx_bad_reg {
+ uint64_t u64;
+ struct cvmx_agl_gmx_bad_reg_s {
+ uint64_t reserved_38_63:26;
+ uint64_t txpsh1:1;
+ uint64_t txpop1:1;
+ uint64_t ovrflw1:1;
+ uint64_t txpsh:1;
+ uint64_t txpop:1;
+ uint64_t ovrflw:1;
+ uint64_t reserved_27_31:5;
+ uint64_t statovr:1;
+ uint64_t reserved_24_25:2;
+ uint64_t loststat:2;
+ uint64_t reserved_4_21:18;
+ uint64_t out_ovr:2;
+ uint64_t reserved_0_1:2;
+ } s;
+ struct cvmx_agl_gmx_bad_reg_cn52xx {
+ uint64_t reserved_38_63:26;
+ uint64_t txpsh1:1;
+ uint64_t txpop1:1;
+ uint64_t ovrflw1:1;
+ uint64_t txpsh:1;
+ uint64_t txpop:1;
+ uint64_t ovrflw:1;
+ uint64_t reserved_27_31:5;
+ uint64_t statovr:1;
+ uint64_t reserved_23_25:3;
+ uint64_t loststat:1;
+ uint64_t reserved_4_21:18;
+ uint64_t out_ovr:2;
+ uint64_t reserved_0_1:2;
+ } cn52xx;
+ struct cvmx_agl_gmx_bad_reg_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_bad_reg_cn56xx {
+ uint64_t reserved_35_63:29;
+ uint64_t txpsh:1;
+ uint64_t txpop:1;
+ uint64_t ovrflw:1;
+ uint64_t reserved_27_31:5;
+ uint64_t statovr:1;
+ uint64_t reserved_23_25:3;
+ uint64_t loststat:1;
+ uint64_t reserved_3_21:19;
+ uint64_t out_ovr:1;
+ uint64_t reserved_0_1:2;
+ } cn56xx;
+ struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_bad_reg_s cn63xx;
+ struct cvmx_agl_gmx_bad_reg_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_bist {
+ uint64_t u64;
+ struct cvmx_agl_gmx_bist_s {
+ uint64_t reserved_25_63:39;
+ uint64_t status:25;
+ } s;
+ struct cvmx_agl_gmx_bist_cn52xx {
+ uint64_t reserved_10_63:54;
+ uint64_t status:10;
+ } cn52xx;
+ struct cvmx_agl_gmx_bist_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_bist_cn52xx cn56xx;
+ struct cvmx_agl_gmx_bist_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_bist_s cn63xx;
+ struct cvmx_agl_gmx_bist_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_drv_ctl {
+ uint64_t u64;
+ struct cvmx_agl_gmx_drv_ctl_s {
+ uint64_t reserved_49_63:15;
+ uint64_t byp_en1:1;
+ uint64_t reserved_45_47:3;
+ uint64_t pctl1:5;
+ uint64_t reserved_37_39:3;
+ uint64_t nctl1:5;
+ uint64_t reserved_17_31:15;
+ uint64_t byp_en:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pctl:5;
+ uint64_t reserved_5_7:3;
+ uint64_t nctl:5;
+ } s;
+ struct cvmx_agl_gmx_drv_ctl_s cn52xx;
+ struct cvmx_agl_gmx_drv_ctl_s cn52xxp1;
+ struct cvmx_agl_gmx_drv_ctl_cn56xx {
+ uint64_t reserved_17_63:47;
+ uint64_t byp_en:1;
+ uint64_t reserved_13_15:3;
+ uint64_t pctl:5;
+ uint64_t reserved_5_7:3;
+ uint64_t nctl:5;
+ } cn56xx;
+ struct cvmx_agl_gmx_drv_ctl_cn56xx cn56xxp1;
+};
+
+union cvmx_agl_gmx_inf_mode {
+ uint64_t u64;
+ struct cvmx_agl_gmx_inf_mode_s {
+ uint64_t reserved_2_63:62;
+ uint64_t en:1;
+ uint64_t reserved_0_0:1;
+ } s;
+ struct cvmx_agl_gmx_inf_mode_s cn52xx;
+ struct cvmx_agl_gmx_inf_mode_s cn52xxp1;
+ struct cvmx_agl_gmx_inf_mode_s cn56xx;
+ struct cvmx_agl_gmx_inf_mode_s cn56xxp1;
+};
+
+union cvmx_agl_gmx_prtx_cfg {
+ uint64_t u64;
+ struct cvmx_agl_gmx_prtx_cfg_s {
+ uint64_t reserved_14_63:50;
+ uint64_t tx_idle:1;
+ uint64_t rx_idle:1;
+ uint64_t reserved_9_11:3;
+ uint64_t speed_msb:1;
+ uint64_t reserved_7_7:1;
+ uint64_t burst:1;
+ uint64_t tx_en:1;
+ uint64_t rx_en:1;
+ uint64_t slottime:1;
+ uint64_t duplex:1;
+ uint64_t speed:1;
+ uint64_t en:1;
+ } s;
+ struct cvmx_agl_gmx_prtx_cfg_cn52xx {
+ uint64_t reserved_6_63:58;
+ uint64_t tx_en:1;
+ uint64_t rx_en:1;
+ uint64_t slottime:1;
+ uint64_t duplex:1;
+ uint64_t speed:1;
+ uint64_t en:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_prtx_cfg_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xx;
+ struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_prtx_cfg_s cn63xx;
+ struct cvmx_agl_gmx_prtx_cfg_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam0 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s {
+ uint64_t adr:64;
+ } s;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xx;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam1 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s {
+ uint64_t adr:64;
+ } s;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xx;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam2 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s {
+ uint64_t adr:64;
+ } s;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xx;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam3 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s {
+ uint64_t adr:64;
+ } s;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xx;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam4 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s {
+ uint64_t adr:64;
+ } s;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xx;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam5 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s {
+ uint64_t adr:64;
+ } s;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xx;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_cam_en {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s {
+ uint64_t reserved_8_63:56;
+ uint64_t en:8;
+ } s;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xx;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_adr_ctl {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s {
+ uint64_t reserved_4_63:60;
+ uint64_t cam_mode:1;
+ uint64_t mcst:2;
+ uint64_t bcst:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xx;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_decision {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_decision_s {
+ uint64_t reserved_5_63:59;
+ uint64_t cnt:5;
+ } s;
+ struct cvmx_agl_gmx_rxx_decision_s cn52xx;
+ struct cvmx_agl_gmx_rxx_decision_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_decision_s cn56xx;
+ struct cvmx_agl_gmx_rxx_decision_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_decision_s cn63xx;
+ struct cvmx_agl_gmx_rxx_decision_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_frm_chk {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_frm_chk_s {
+ uint64_t reserved_10_63:54;
+ uint64_t niberr:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_frm_chk_cn52xx {
+ uint64_t reserved_9_63:55;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t reserved_1_1:1;
+ uint64_t minerr:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xx;
+ struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_chk_s cn63xx;
+ struct cvmx_agl_gmx_rxx_frm_chk_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_frm_ctl {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s {
+ uint64_t reserved_13_63:51;
+ uint64_t ptp_mode:1;
+ uint64_t reserved_11_11:1;
+ uint64_t null_dis:1;
+ uint64_t pre_align:1;
+ uint64_t pad_len:1;
+ uint64_t vlan_len:1;
+ uint64_t pre_free:1;
+ uint64_t ctl_smac:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_drp:1;
+ uint64_t pre_strp:1;
+ uint64_t pre_chk:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx {
+ uint64_t reserved_10_63:54;
+ uint64_t pre_align:1;
+ uint64_t pad_len:1;
+ uint64_t vlan_len:1;
+ uint64_t pre_free:1;
+ uint64_t ctl_smac:1;
+ uint64_t ctl_mcst:1;
+ uint64_t ctl_bck:1;
+ uint64_t ctl_drp:1;
+ uint64_t pre_strp:1;
+ uint64_t pre_chk:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xx;
+ struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_frm_max {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_frm_max_s {
+ uint64_t reserved_16_63:48;
+ uint64_t len:16;
+ } s;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn52xx;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn56xx;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn63xx;
+ struct cvmx_agl_gmx_rxx_frm_max_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_frm_min {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_frm_min_s {
+ uint64_t reserved_16_63:48;
+ uint64_t len:16;
+ } s;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn52xx;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn56xx;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn63xx;
+ struct cvmx_agl_gmx_rxx_frm_min_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_ifg {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_ifg_s {
+ uint64_t reserved_4_63:60;
+ uint64_t ifg:4;
+ } s;
+ struct cvmx_agl_gmx_rxx_ifg_s cn52xx;
+ struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_ifg_s cn56xx;
+ struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_ifg_s cn63xx;
+ struct cvmx_agl_gmx_rxx_ifg_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_int_en {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_int_en_s {
+ uint64_t reserved_20_63:44;
+ uint64_t pause_drp:1;
+ uint64_t phy_dupx:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_link:1;
+ uint64_t ifgerr:1;
+ uint64_t coldet:1;
+ uint64_t falerr:1;
+ uint64_t rsverr:1;
+ uint64_t pcterr:1;
+ uint64_t ovrerr:1;
+ uint64_t niberr:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_int_en_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t pause_drp:1;
+ uint64_t reserved_16_18:3;
+ uint64_t ifgerr:1;
+ uint64_t coldet:1;
+ uint64_t falerr:1;
+ uint64_t rsverr:1;
+ uint64_t pcterr:1;
+ uint64_t ovrerr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t reserved_1_1:1;
+ uint64_t minerr:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_rxx_int_en_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xx;
+ struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_int_en_s cn63xx;
+ struct cvmx_agl_gmx_rxx_int_en_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_int_reg {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_int_reg_s {
+ uint64_t reserved_20_63:44;
+ uint64_t pause_drp:1;
+ uint64_t phy_dupx:1;
+ uint64_t phy_spd:1;
+ uint64_t phy_link:1;
+ uint64_t ifgerr:1;
+ uint64_t coldet:1;
+ uint64_t falerr:1;
+ uint64_t rsverr:1;
+ uint64_t pcterr:1;
+ uint64_t ovrerr:1;
+ uint64_t niberr:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t carext:1;
+ uint64_t minerr:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_int_reg_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t pause_drp:1;
+ uint64_t reserved_16_18:3;
+ uint64_t ifgerr:1;
+ uint64_t coldet:1;
+ uint64_t falerr:1;
+ uint64_t rsverr:1;
+ uint64_t pcterr:1;
+ uint64_t ovrerr:1;
+ uint64_t reserved_9_9:1;
+ uint64_t skperr:1;
+ uint64_t rcverr:1;
+ uint64_t lenerr:1;
+ uint64_t alnerr:1;
+ uint64_t fcserr:1;
+ uint64_t jabber:1;
+ uint64_t maxerr:1;
+ uint64_t reserved_1_1:1;
+ uint64_t minerr:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xx;
+ struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xxp1;
+ struct cvmx_agl_gmx_rxx_int_reg_s cn63xx;
+ struct cvmx_agl_gmx_rxx_int_reg_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_jabber {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_jabber_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt:16;
+ } s;
+ struct cvmx_agl_gmx_rxx_jabber_s cn52xx;
+ struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_jabber_s cn56xx;
+ struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_jabber_s cn63xx;
+ struct cvmx_agl_gmx_rxx_jabber_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_pause_drop_time {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s {
+ uint64_t reserved_16_63:48;
+ uint64_t status:16;
+ } s;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xx;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xx;
+ struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_rx_inbnd {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s {
+ uint64_t reserved_4_63:60;
+ uint64_t duplex:1;
+ uint64_t speed:2;
+ uint64_t status:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xx;
+ struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_ctl {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s {
+ uint64_t reserved_1_63:63;
+ uint64_t rd_clr:1;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_octs {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_octs_s {
+ uint64_t reserved_48_63:16;
+ uint64_t cnt:48;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_octs_ctl {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s {
+ uint64_t reserved_48_63:16;
+ uint64_t cnt:48;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_octs_dmac {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s {
+ uint64_t reserved_48_63:16;
+ uint64_t cnt:48;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_octs_drp {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s {
+ uint64_t reserved_48_63:16;
+ uint64_t cnt:48;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts_bad {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts_ctl {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts_dmac {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_stats_pkts_drp {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xx;
+ struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rxx_udd_skp {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rxx_udd_skp_s {
+ uint64_t reserved_9_63:55;
+ uint64_t fcssel:1;
+ uint64_t reserved_7_7:1;
+ uint64_t len:7;
+ } s;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn52xx;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn63xx;
+ struct cvmx_agl_gmx_rxx_udd_skp_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rx_bp_dropx {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rx_bp_dropx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t mark:6;
+ } s;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn52xx;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn63xx;
+ struct cvmx_agl_gmx_rx_bp_dropx_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rx_bp_offx {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rx_bp_offx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t mark:6;
+ } s;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn52xx;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn56xx;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn63xx;
+ struct cvmx_agl_gmx_rx_bp_offx_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rx_bp_onx {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rx_bp_onx_s {
+ uint64_t reserved_9_63:55;
+ uint64_t mark:9;
+ } s;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn52xx;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn56xx;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn63xx;
+ struct cvmx_agl_gmx_rx_bp_onx_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rx_prt_info {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rx_prt_info_s {
+ uint64_t reserved_18_63:46;
+ uint64_t drop:2;
+ uint64_t reserved_2_15:14;
+ uint64_t commit:2;
+ } s;
+ struct cvmx_agl_gmx_rx_prt_info_s cn52xx;
+ struct cvmx_agl_gmx_rx_prt_info_s cn52xxp1;
+ struct cvmx_agl_gmx_rx_prt_info_cn56xx {
+ uint64_t reserved_17_63:47;
+ uint64_t drop:1;
+ uint64_t reserved_1_15:15;
+ uint64_t commit:1;
+ } cn56xx;
+ struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_rx_prt_info_s cn63xx;
+ struct cvmx_agl_gmx_rx_prt_info_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_rx_tx_status {
+ uint64_t u64;
+ struct cvmx_agl_gmx_rx_tx_status_s {
+ uint64_t reserved_6_63:58;
+ uint64_t tx:2;
+ uint64_t reserved_2_3:2;
+ uint64_t rx:2;
+ } s;
+ struct cvmx_agl_gmx_rx_tx_status_s cn52xx;
+ struct cvmx_agl_gmx_rx_tx_status_s cn52xxp1;
+ struct cvmx_agl_gmx_rx_tx_status_cn56xx {
+ uint64_t reserved_5_63:59;
+ uint64_t tx:1;
+ uint64_t reserved_1_3:3;
+ uint64_t rx:1;
+ } cn56xx;
+ struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_rx_tx_status_s cn63xx;
+ struct cvmx_agl_gmx_rx_tx_status_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_smacx {
+ uint64_t u64;
+ struct cvmx_agl_gmx_smacx_s {
+ uint64_t reserved_48_63:16;
+ uint64_t smac:48;
+ } s;
+ struct cvmx_agl_gmx_smacx_s cn52xx;
+ struct cvmx_agl_gmx_smacx_s cn52xxp1;
+ struct cvmx_agl_gmx_smacx_s cn56xx;
+ struct cvmx_agl_gmx_smacx_s cn56xxp1;
+ struct cvmx_agl_gmx_smacx_s cn63xx;
+ struct cvmx_agl_gmx_smacx_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_stat_bp {
+ uint64_t u64;
+ struct cvmx_agl_gmx_stat_bp_s {
+ uint64_t reserved_17_63:47;
+ uint64_t bp:1;
+ uint64_t cnt:16;
+ } s;
+ struct cvmx_agl_gmx_stat_bp_s cn52xx;
+ struct cvmx_agl_gmx_stat_bp_s cn52xxp1;
+ struct cvmx_agl_gmx_stat_bp_s cn56xx;
+ struct cvmx_agl_gmx_stat_bp_s cn56xxp1;
+ struct cvmx_agl_gmx_stat_bp_s cn63xx;
+ struct cvmx_agl_gmx_stat_bp_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_append {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_append_s {
+ uint64_t reserved_4_63:60;
+ uint64_t force_fcs:1;
+ uint64_t fcs:1;
+ uint64_t pad:1;
+ uint64_t preamble:1;
+ } s;
+ struct cvmx_agl_gmx_txx_append_s cn52xx;
+ struct cvmx_agl_gmx_txx_append_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_append_s cn56xx;
+ struct cvmx_agl_gmx_txx_append_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_append_s cn63xx;
+ struct cvmx_agl_gmx_txx_append_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_clk {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_clk_s {
+ uint64_t reserved_6_63:58;
+ uint64_t clk_cnt:6;
+ } s;
+ struct cvmx_agl_gmx_txx_clk_s cn63xx;
+ struct cvmx_agl_gmx_txx_clk_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_ctl {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_ctl_s {
+ uint64_t reserved_2_63:62;
+ uint64_t xsdef_en:1;
+ uint64_t xscol_en:1;
+ } s;
+ struct cvmx_agl_gmx_txx_ctl_s cn52xx;
+ struct cvmx_agl_gmx_txx_ctl_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_ctl_s cn56xx;
+ struct cvmx_agl_gmx_txx_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_ctl_s cn63xx;
+ struct cvmx_agl_gmx_txx_ctl_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_min_pkt {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_min_pkt_s {
+ uint64_t reserved_8_63:56;
+ uint64_t min_size:8;
+ } s;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn52xx;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn56xx;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn63xx;
+ struct cvmx_agl_gmx_txx_min_pkt_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_pause_pkt_interval {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s {
+ uint64_t reserved_16_63:48;
+ uint64_t interval:16;
+ } s;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_pause_pkt_time {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s {
+ uint64_t reserved_16_63:48;
+ uint64_t time:16;
+ } s;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xx;
+ struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_pause_togo {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_pause_togo_s {
+ uint64_t reserved_16_63:48;
+ uint64_t time:16;
+ } s;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn52xx;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn56xx;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn63xx;
+ struct cvmx_agl_gmx_txx_pause_togo_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_pause_zero {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_pause_zero_s {
+ uint64_t reserved_1_63:63;
+ uint64_t send:1;
+ } s;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn52xx;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn56xx;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn63xx;
+ struct cvmx_agl_gmx_txx_pause_zero_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_soft_pause {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_soft_pause_s {
+ uint64_t reserved_16_63:48;
+ uint64_t time:16;
+ } s;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn52xx;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn56xx;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn63xx;
+ struct cvmx_agl_gmx_txx_soft_pause_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat0 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat0_s {
+ uint64_t xsdef:32;
+ uint64_t xscol:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat0_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat0_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat0_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat0_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat0_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat0_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat1 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat1_s {
+ uint64_t scol:32;
+ uint64_t mcol:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat1_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat1_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat1_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat1_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat1_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat1_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat2 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat2_s {
+ uint64_t reserved_48_63:16;
+ uint64_t octs:48;
+ } s;
+ struct cvmx_agl_gmx_txx_stat2_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat2_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat2_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat2_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat2_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat2_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat3 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat3_s {
+ uint64_t reserved_32_63:32;
+ uint64_t pkts:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat3_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat3_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat3_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat3_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat3_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat3_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat4 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat4_s {
+ uint64_t hist1:32;
+ uint64_t hist0:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat4_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat4_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat4_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat4_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat4_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat4_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat5 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat5_s {
+ uint64_t hist3:32;
+ uint64_t hist2:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat5_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat5_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat5_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat5_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat5_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat5_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat6 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat6_s {
+ uint64_t hist5:32;
+ uint64_t hist4:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat6_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat6_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat6_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat6_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat6_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat6_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat7 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat7_s {
+ uint64_t hist7:32;
+ uint64_t hist6:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat7_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat7_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat7_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat7_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat7_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat7_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat8 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat8_s {
+ uint64_t mcst:32;
+ uint64_t bcst:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat8_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat8_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat8_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat8_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat8_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat8_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stat9 {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stat9_s {
+ uint64_t undflw:32;
+ uint64_t ctl:32;
+ } s;
+ struct cvmx_agl_gmx_txx_stat9_s cn52xx;
+ struct cvmx_agl_gmx_txx_stat9_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stat9_s cn56xx;
+ struct cvmx_agl_gmx_txx_stat9_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stat9_s cn63xx;
+ struct cvmx_agl_gmx_txx_stat9_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_stats_ctl {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_stats_ctl_s {
+ uint64_t reserved_1_63:63;
+ uint64_t rd_clr:1;
+ } s;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn52xx;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn63xx;
+ struct cvmx_agl_gmx_txx_stats_ctl_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_txx_thresh {
+ uint64_t u64;
+ struct cvmx_agl_gmx_txx_thresh_s {
+ uint64_t reserved_6_63:58;
+ uint64_t cnt:6;
+ } s;
+ struct cvmx_agl_gmx_txx_thresh_s cn52xx;
+ struct cvmx_agl_gmx_txx_thresh_s cn52xxp1;
+ struct cvmx_agl_gmx_txx_thresh_s cn56xx;
+ struct cvmx_agl_gmx_txx_thresh_s cn56xxp1;
+ struct cvmx_agl_gmx_txx_thresh_s cn63xx;
+ struct cvmx_agl_gmx_txx_thresh_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_bp {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_bp_s {
+ uint64_t reserved_2_63:62;
+ uint64_t bp:2;
+ } s;
+ struct cvmx_agl_gmx_tx_bp_s cn52xx;
+ struct cvmx_agl_gmx_tx_bp_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_bp_cn56xx {
+ uint64_t reserved_1_63:63;
+ uint64_t bp:1;
+ } cn56xx;
+ struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_bp_s cn63xx;
+ struct cvmx_agl_gmx_tx_bp_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_col_attempt {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_col_attempt_s {
+ uint64_t reserved_5_63:59;
+ uint64_t limit:5;
+ } s;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn52xx;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn56xx;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn63xx;
+ struct cvmx_agl_gmx_tx_col_attempt_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_ifg {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_ifg_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ifg2:4;
+ uint64_t ifg1:4;
+ } s;
+ struct cvmx_agl_gmx_tx_ifg_s cn52xx;
+ struct cvmx_agl_gmx_tx_ifg_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_ifg_s cn56xx;
+ struct cvmx_agl_gmx_tx_ifg_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_ifg_s cn63xx;
+ struct cvmx_agl_gmx_tx_ifg_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_int_en {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_int_en_s {
+ uint64_t reserved_22_63:42;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_18_19:2;
+ uint64_t late_col:2;
+ uint64_t reserved_14_15:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xscol:2;
+ uint64_t reserved_4_7:4;
+ uint64_t undflw:2;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+ } s;
+ struct cvmx_agl_gmx_tx_int_en_cn52xx {
+ uint64_t reserved_18_63:46;
+ uint64_t late_col:2;
+ uint64_t reserved_14_15:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xscol:2;
+ uint64_t reserved_4_7:4;
+ uint64_t undflw:2;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_tx_int_en_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_tx_int_en_cn56xx {
+ uint64_t reserved_17_63:47;
+ uint64_t late_col:1;
+ uint64_t reserved_13_15:3;
+ uint64_t xsdef:1;
+ uint64_t reserved_9_11:3;
+ uint64_t xscol:1;
+ uint64_t reserved_3_7:5;
+ uint64_t undflw:1;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+ } cn56xx;
+ struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_int_en_s cn63xx;
+ struct cvmx_agl_gmx_tx_int_en_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_int_reg {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_int_reg_s {
+ uint64_t reserved_22_63:42;
+ uint64_t ptp_lost:2;
+ uint64_t reserved_18_19:2;
+ uint64_t late_col:2;
+ uint64_t reserved_14_15:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xscol:2;
+ uint64_t reserved_4_7:4;
+ uint64_t undflw:2;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+ } s;
+ struct cvmx_agl_gmx_tx_int_reg_cn52xx {
+ uint64_t reserved_18_63:46;
+ uint64_t late_col:2;
+ uint64_t reserved_14_15:2;
+ uint64_t xsdef:2;
+ uint64_t reserved_10_11:2;
+ uint64_t xscol:2;
+ uint64_t reserved_4_7:4;
+ uint64_t undflw:2;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+ } cn52xx;
+ struct cvmx_agl_gmx_tx_int_reg_cn52xx cn52xxp1;
+ struct cvmx_agl_gmx_tx_int_reg_cn56xx {
+ uint64_t reserved_17_63:47;
+ uint64_t late_col:1;
+ uint64_t reserved_13_15:3;
+ uint64_t xsdef:1;
+ uint64_t reserved_9_11:3;
+ uint64_t xscol:1;
+ uint64_t reserved_3_7:5;
+ uint64_t undflw:1;
+ uint64_t reserved_1_1:1;
+ uint64_t pko_nxa:1;
+ } cn56xx;
+ struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_int_reg_s cn63xx;
+ struct cvmx_agl_gmx_tx_int_reg_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_jam {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_jam_s {
+ uint64_t reserved_8_63:56;
+ uint64_t jam:8;
+ } s;
+ struct cvmx_agl_gmx_tx_jam_s cn52xx;
+ struct cvmx_agl_gmx_tx_jam_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_jam_s cn56xx;
+ struct cvmx_agl_gmx_tx_jam_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_jam_s cn63xx;
+ struct cvmx_agl_gmx_tx_jam_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_lfsr {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_lfsr_s {
+ uint64_t reserved_16_63:48;
+ uint64_t lfsr:16;
+ } s;
+ struct cvmx_agl_gmx_tx_lfsr_s cn52xx;
+ struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_lfsr_s cn56xx;
+ struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_lfsr_s cn63xx;
+ struct cvmx_agl_gmx_tx_lfsr_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_ovr_bp {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_ovr_bp_s {
+ uint64_t reserved_10_63:54;
+ uint64_t en:2;
+ uint64_t reserved_6_7:2;
+ uint64_t bp:2;
+ uint64_t reserved_2_3:2;
+ uint64_t ign_full:2;
+ } s;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn52xx;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_ovr_bp_cn56xx {
+ uint64_t reserved_9_63:55;
+ uint64_t en:1;
+ uint64_t reserved_5_7:3;
+ uint64_t bp:1;
+ uint64_t reserved_1_3:3;
+ uint64_t ign_full:1;
+ } cn56xx;
+ struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn63xx;
+ struct cvmx_agl_gmx_tx_ovr_bp_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_pause_pkt_dmac {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s {
+ uint64_t reserved_48_63:16;
+ uint64_t dmac:48;
+ } s;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xxp1;
+};
+
+union cvmx_agl_gmx_tx_pause_pkt_type {
+ uint64_t u64;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s {
+ uint64_t reserved_16_63:48;
+ uint64_t type:16;
+ } s;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xx;
+ struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xxp1;
+};
+
+union cvmx_agl_prtx_ctl {
+ uint64_t u64;
+ struct cvmx_agl_prtx_ctl_s {
+ uint64_t drv_byp:1;
+ uint64_t reserved_62_62:1;
+ uint64_t cmp_pctl:6;
+ uint64_t reserved_54_55:2;
+ uint64_t cmp_nctl:6;
+ uint64_t reserved_46_47:2;
+ uint64_t drv_pctl:6;
+ uint64_t reserved_38_39:2;
+ uint64_t drv_nctl:6;
+ uint64_t reserved_29_31:3;
+ uint64_t clk_set:5;
+ uint64_t clkrx_byp:1;
+ uint64_t reserved_21_22:2;
+ uint64_t clkrx_set:5;
+ uint64_t clktx_byp:1;
+ uint64_t reserved_13_14:2;
+ uint64_t clktx_set:5;
+ uint64_t reserved_5_7:3;
+ uint64_t dllrst:1;
+ uint64_t comp:1;
+ uint64_t enable:1;
+ uint64_t clkrst:1;
+ uint64_t mode:1;
+ } s;
+ struct cvmx_agl_prtx_ctl_s cn63xx;
+ struct cvmx_agl_prtx_ctl_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-asm.h b/arch/mips/include/asm/octeon/cvmx-asm.h
new file mode 100644
index 00000000..5de5de95
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-asm.h
@@ -0,0 +1,139 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * This is file defines ASM primitives for the executive.
+ */
+#ifndef __CVMX_ASM_H__
+#define __CVMX_ASM_H__
+
+#include "octeon-model.h"
+
+/* other useful stuff */
+#define CVMX_SYNC asm volatile ("sync" : : : "memory")
+/* String version of SYNCW macro for using in inline asm constructs */
+#define CVMX_SYNCW_STR "syncw\nsyncw\n"
+#ifdef __OCTEON__
+
+/* Deprecated, will be removed in future release */
+#define CVMX_SYNCIO asm volatile ("nop")
+
+#define CVMX_SYNCIOBDMA asm volatile ("synciobdma" : : : "memory")
+
+/* Deprecated, will be removed in future release */
+#define CVMX_SYNCIOALL asm volatile ("nop")
+
+/*
+ * We actually use two syncw instructions in a row when we need a write
+ * memory barrier. This is because the CN3XXX series of Octeons have
+ * errata Core-401. This can cause a single syncw to not enforce
+ * ordering under very rare conditions. Even if it is rare, better safe
+ * than sorry.
+ */
+#define CVMX_SYNCW asm volatile ("syncw\n\tsyncw" : : : "memory")
+
+/*
+ * Define new sync instructions to be normal SYNC instructions for
+ * operating systems that use threads.
+ */
+#define CVMX_SYNCWS CVMX_SYNCW
+#define CVMX_SYNCS CVMX_SYNC
+#define CVMX_SYNCWS_STR CVMX_SYNCW_STR
+#else
+/*
+ * Not using a Cavium compiler, always use the slower sync so the
+ * assembler stays happy.
+ */
+/* Deprecated, will be removed in future release */
+#define CVMX_SYNCIO asm volatile ("nop")
+
+#define CVMX_SYNCIOBDMA asm volatile ("sync" : : : "memory")
+
+/* Deprecated, will be removed in future release */
+#define CVMX_SYNCIOALL asm volatile ("nop")
+
+#define CVMX_SYNCW asm volatile ("sync" : : : "memory")
+#define CVMX_SYNCWS CVMX_SYNCW
+#define CVMX_SYNCS CVMX_SYNC
+#define CVMX_SYNCWS_STR CVMX_SYNCW_STR
+#endif
+
+/*
+ * CVMX_PREPARE_FOR_STORE makes each byte of the block unpredictable
+ * (actually old value or zero) until that byte is stored to (by this or
+ * another processor. Note that the value of each byte is not only
+ * unpredictable, but may also change again - up until the point when one
+ * of the cores stores to the byte.
+ */
+#define CVMX_PREPARE_FOR_STORE(address, offset) \
+ asm volatile ("pref 30, " CVMX_TMP_STR(offset) "(%[rbase])" : : \
+ [rbase] "d" (address))
+/*
+ * This is a command headed to the L2 controller to tell it to clear
+ * its dirty bit for a block. Basically, SW is telling HW that the
+ * current version of the block will not be used.
+ */
+#define CVMX_DONT_WRITE_BACK(address, offset) \
+ asm volatile ("pref 29, " CVMX_TMP_STR(offset) "(%[rbase])" : : \
+ [rbase] "d" (address))
+
+/* flush stores, invalidate entire icache */
+#define CVMX_ICACHE_INVALIDATE \
+ { CVMX_SYNC; asm volatile ("synci 0($0)" : : ); }
+
+/* flush stores, invalidate entire icache */
+#define CVMX_ICACHE_INVALIDATE2 \
+ { CVMX_SYNC; asm volatile ("cache 0, 0($0)" : : ); }
+
+/* complete prefetches, invalidate entire dcache */
+#define CVMX_DCACHE_INVALIDATE \
+ { CVMX_SYNC; asm volatile ("cache 9, 0($0)" : : ); }
+
+#define CVMX_CACHE(op, address, offset) \
+ asm volatile ("cache " CVMX_TMP_STR(op) ", " CVMX_TMP_STR(offset) "(%[rbase])" \
+ : : [rbase] "d" (address) )
+/* fetch and lock the state. */
+#define CVMX_CACHE_LCKL2(address, offset) CVMX_CACHE(31, address, offset)
+/* unlock the state. */
+#define CVMX_CACHE_WBIL2(address, offset) CVMX_CACHE(23, address, offset)
+/* invalidate the cache block and clear the USED bits for the block */
+#define CVMX_CACHE_WBIL2I(address, offset) CVMX_CACHE(3, address, offset)
+/* load virtual tag and data for the L2 cache block into L2C_TAD0_TAG register */
+#define CVMX_CACHE_LTGL2I(address, offset) CVMX_CACHE(7, address, offset)
+
+#define CVMX_POP(result, input) \
+ asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
+#define CVMX_DPOP(result, input) \
+ asm ("dpop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
+
+/* some new cop0-like stuff */
+#define CVMX_RDHWR(result, regstr) \
+ asm volatile ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result))
+#define CVMX_RDHWRNV(result, regstr) \
+ asm ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result))
+#endif /* __CVMX_ASM_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
new file mode 100644
index 00000000..4e4c3a82
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
@@ -0,0 +1,275 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Header file containing the ABI with the bootloader.
+ */
+
+#ifndef __CVMX_BOOTINFO_H__
+#define __CVMX_BOOTINFO_H__
+
+/*
+ * Current major and minor versions of the CVMX bootinfo block that is
+ * passed from the bootloader to the application. This is versioned
+ * so that applications can properly handle multiple bootloader
+ * versions.
+ */
+#define CVMX_BOOTINFO_MAJ_VER 1
+#define CVMX_BOOTINFO_MIN_VER 2
+
+#if (CVMX_BOOTINFO_MAJ_VER == 1)
+#define CVMX_BOOTINFO_OCTEON_SERIAL_LEN 20
+/*
+ * This structure is populated by the bootloader. For binary
+ * compatibility the only changes that should be made are
+ * adding members to the end of the structure, and the minor
+ * version should be incremented at that time.
+ * If an incompatible change is made, the major version
+ * must be incremented, and the minor version should be reset
+ * to 0.
+ */
+struct cvmx_bootinfo {
+ uint32_t major_version;
+ uint32_t minor_version;
+
+ uint64_t stack_top;
+ uint64_t heap_base;
+ uint64_t heap_end;
+ uint64_t desc_vaddr;
+
+ uint32_t exception_base_addr;
+ uint32_t stack_size;
+ uint32_t flags;
+ uint32_t core_mask;
+ /* DRAM size in megabytes */
+ uint32_t dram_size;
+ /* physical address of free memory descriptor block*/
+ uint32_t phy_mem_desc_addr;
+ /* used to pass flags from app to debugger */
+ uint32_t debugger_flags_base_addr;
+
+ /* CPU clock speed, in hz */
+ uint32_t eclock_hz;
+
+ /* DRAM clock speed, in hz */
+ uint32_t dclock_hz;
+
+ uint32_t reserved0;
+ uint16_t board_type;
+ uint8_t board_rev_major;
+ uint8_t board_rev_minor;
+ uint16_t reserved1;
+ uint8_t reserved2;
+ uint8_t reserved3;
+ char board_serial_number[CVMX_BOOTINFO_OCTEON_SERIAL_LEN];
+ uint8_t mac_addr_base[6];
+ uint8_t mac_addr_count;
+#if (CVMX_BOOTINFO_MIN_VER >= 1)
+ /*
+ * Several boards support compact flash on the Octeon boot
+ * bus. The CF memory spaces may be mapped to different
+ * addresses on different boards. These are the physical
+ * addresses, so care must be taken to use the correct
+ * XKPHYS/KSEG0 addressing depending on the application's
+ * ABI. These values will be 0 if CF is not present.
+ */
+ uint64_t compact_flash_common_base_addr;
+ uint64_t compact_flash_attribute_base_addr;
+ /*
+ * Base address of the LED display (as on EBT3000 board)
+ * This will be 0 if LED display not present.
+ */
+ uint64_t led_display_base_addr;
+#endif
+#if (CVMX_BOOTINFO_MIN_VER >= 2)
+ /* DFA reference clock in hz (if applicable)*/
+ uint32_t dfa_ref_clock_hz;
+
+ /*
+ * flags indicating various configuration options. These
+ * flags supercede the 'flags' variable and should be used
+ * instead if available.
+ */
+ uint32_t config_flags;
+#endif
+
+};
+
+#define CVMX_BOOTINFO_CFG_FLAG_PCI_HOST (1ull << 0)
+#define CVMX_BOOTINFO_CFG_FLAG_PCI_TARGET (1ull << 1)
+#define CVMX_BOOTINFO_CFG_FLAG_DEBUG (1ull << 2)
+#define CVMX_BOOTINFO_CFG_FLAG_NO_MAGIC (1ull << 3)
+/* This flag is set if the TLB mappings are not contained in the
+ * 0x10000000 - 0x20000000 boot bus region. */
+#define CVMX_BOOTINFO_CFG_FLAG_OVERSIZE_TLB_MAPPING (1ull << 4)
+#define CVMX_BOOTINFO_CFG_FLAG_BREAK (1ull << 5)
+
+#endif /* (CVMX_BOOTINFO_MAJ_VER == 1) */
+
+/* Type defines for board and chip types */
+enum cvmx_board_types_enum {
+ CVMX_BOARD_TYPE_NULL = 0,
+ CVMX_BOARD_TYPE_SIM = 1,
+ CVMX_BOARD_TYPE_EBT3000 = 2,
+ CVMX_BOARD_TYPE_KODAMA = 3,
+ CVMX_BOARD_TYPE_NIAGARA = 4,
+ CVMX_BOARD_TYPE_NAC38 = 5, /* formerly NAO38 */
+ CVMX_BOARD_TYPE_THUNDER = 6,
+ CVMX_BOARD_TYPE_TRANTOR = 7,
+ CVMX_BOARD_TYPE_EBH3000 = 8,
+ CVMX_BOARD_TYPE_EBH3100 = 9,
+ CVMX_BOARD_TYPE_HIKARI = 10,
+ CVMX_BOARD_TYPE_CN3010_EVB_HS5 = 11,
+ CVMX_BOARD_TYPE_CN3005_EVB_HS5 = 12,
+ CVMX_BOARD_TYPE_KBP = 13,
+ /* Deprecated, CVMX_BOARD_TYPE_CN3010_EVB_HS5 supports the CN3020 */
+ CVMX_BOARD_TYPE_CN3020_EVB_HS5 = 14,
+ CVMX_BOARD_TYPE_EBT5800 = 15,
+ CVMX_BOARD_TYPE_NICPRO2 = 16,
+ CVMX_BOARD_TYPE_EBH5600 = 17,
+ CVMX_BOARD_TYPE_EBH5601 = 18,
+ CVMX_BOARD_TYPE_EBH5200 = 19,
+ CVMX_BOARD_TYPE_BBGW_REF = 20,
+ CVMX_BOARD_TYPE_NIC_XLE_4G = 21,
+ CVMX_BOARD_TYPE_EBT5600 = 22,
+ CVMX_BOARD_TYPE_EBH5201 = 23,
+ CVMX_BOARD_TYPE_EBT5200 = 24,
+ CVMX_BOARD_TYPE_CB5600 = 25,
+ CVMX_BOARD_TYPE_CB5601 = 26,
+ CVMX_BOARD_TYPE_CB5200 = 27,
+ /* Special 'generic' board type, supports many boards */
+ CVMX_BOARD_TYPE_GENERIC = 28,
+ CVMX_BOARD_TYPE_EBH5610 = 29,
+ CVMX_BOARD_TYPE_MAX,
+
+ /*
+ * The range from CVMX_BOARD_TYPE_MAX to
+ * CVMX_BOARD_TYPE_CUST_DEFINED_MIN is reserved for future
+ * SDK use.
+ */
+
+ /*
+ * Set aside a range for customer boards. These numbers are managed
+ * by Cavium.
+ */
+ CVMX_BOARD_TYPE_CUST_DEFINED_MIN = 10000,
+ CVMX_BOARD_TYPE_CUST_WSX16 = 10001,
+ CVMX_BOARD_TYPE_CUST_NS0216 = 10002,
+ CVMX_BOARD_TYPE_CUST_NB5 = 10003,
+ CVMX_BOARD_TYPE_CUST_WMR500 = 10004,
+ CVMX_BOARD_TYPE_CUST_DEFINED_MAX = 20000,
+
+ /*
+ * Set aside a range for customer private use. The SDK won't
+ * use any numbers in this range.
+ */
+ CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
+ CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
+
+ /* The remaining range is reserved for future use. */
+};
+
+enum cvmx_chip_types_enum {
+ CVMX_CHIP_TYPE_NULL = 0,
+ CVMX_CHIP_SIM_TYPE_DEPRECATED = 1,
+ CVMX_CHIP_TYPE_OCTEON_SAMPLE = 2,
+ CVMX_CHIP_TYPE_MAX,
+};
+
+/* Compatibility alias for NAC38 name change, planned to be removed
+ * from SDK 1.7 */
+#define CVMX_BOARD_TYPE_NAO38 CVMX_BOARD_TYPE_NAC38
+
+/* Functions to return string based on type */
+#define ENUM_BRD_TYPE_CASE(x) \
+ case x: return(#x + 16); /* Skip CVMX_BOARD_TYPE_ */
+static inline const char *cvmx_board_type_to_string(enum
+ cvmx_board_types_enum type)
+{
+ switch (type) {
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NULL)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_SIM)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT3000)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KODAMA)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIAGARA)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NAC38)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_THUNDER)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_TRANTOR)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH3000)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH3100)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_HIKARI)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3010_EVB_HS5)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3005_EVB_HS5)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KBP)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3020_EVB_HS5)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5800)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NICPRO2)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5600)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5601)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5200)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_BBGW_REF)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC_XLE_4G)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5600)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5201)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5200)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5600)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5601)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5200)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_GENERIC)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5610)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_MAX)
+
+ /* Customer boards listed here */
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DEFINED_MIN)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_WSX16)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NS0216)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NB5)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_WMR500)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DEFINED_MAX)
+
+ /* Customer private range */
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
+ }
+ return "Unsupported Board";
+}
+
+#define ENUM_CHIP_TYPE_CASE(x) \
+ case x: return(#x + 15); /* Skip CVMX_CHIP_TYPE */
+static inline const char *cvmx_chip_type_to_string(enum
+ cvmx_chip_types_enum type)
+{
+ switch (type) {
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_NULL)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_SIM_TYPE_DEPRECATED)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_OCTEON_SAMPLE)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_MAX)
+ }
+ return "Unsupported Chip";
+}
+
+#endif /* __CVMX_BOOTINFO_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h
new file mode 100644
index 00000000..877845b8
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h
@@ -0,0 +1,373 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Simple allocate only memory allocator. Used to allocate memory at
+ * application start time.
+ */
+
+#ifndef __CVMX_BOOTMEM_H__
+#define __CVMX_BOOTMEM_H__
+/* Must be multiple of 8, changing breaks ABI */
+#define CVMX_BOOTMEM_NAME_LEN 128
+
+/* Can change without breaking ABI */
+#define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64
+
+/* minimum alignment of bootmem alloced blocks */
+#define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull)
+
+/* Flags for cvmx_bootmem_phy_mem* functions */
+/* Allocate from end of block instead of beginning */
+#define CVMX_BOOTMEM_FLAG_END_ALLOC (1 << 0)
+
+/* Don't do any locking. */
+#define CVMX_BOOTMEM_FLAG_NO_LOCKING (1 << 1)
+
+/* First bytes of each free physical block of memory contain this structure,
+ * which is used to maintain the free memory list. Since the bootloader is
+ * only 32 bits, there is a union providing 64 and 32 bit versions. The
+ * application init code converts addresses to 64 bit addresses before the
+ * application starts.
+ */
+struct cvmx_bootmem_block_header {
+ /*
+ * Note: these are referenced from assembly routines in the
+ * bootloader, so this structure should not be changed
+ * without changing those routines as well.
+ */
+ uint64_t next_block_addr;
+ uint64_t size;
+
+};
+
+/*
+ * Structure for named memory blocks. Number of descriptors available
+ * can be changed without affecting compatibility, but name length
+ * changes require a bump in the bootmem descriptor version Note: This
+ * structure must be naturally 64 bit aligned, as a single memory
+ * image will be used by both 32 and 64 bit programs.
+ */
+struct cvmx_bootmem_named_block_desc {
+ /* Base address of named block */
+ uint64_t base_addr;
+ /*
+ * Size actually allocated for named block (may differ from
+ * requested).
+ */
+ uint64_t size;
+ /* name of named block */
+ char name[CVMX_BOOTMEM_NAME_LEN];
+};
+
+/* Current descriptor versions */
+/* CVMX bootmem descriptor major version */
+#define CVMX_BOOTMEM_DESC_MAJ_VER 3
+
+/* CVMX bootmem descriptor minor version */
+#define CVMX_BOOTMEM_DESC_MIN_VER 0
+
+/* First three members of cvmx_bootmem_desc_t are left in original
+ * positions for backwards compatibility.
+ */
+struct cvmx_bootmem_desc {
+ /* spinlock to control access to list */
+ uint32_t lock;
+ /* flags for indicating various conditions */
+ uint32_t flags;
+ uint64_t head_addr;
+
+ /* Incremented when incompatible changes made */
+ uint32_t major_version;
+
+ /*
+ * Incremented changed when compatible changes made, reset to
+ * zero when major incremented.
+ */
+ uint32_t minor_version;
+
+ uint64_t app_data_addr;
+ uint64_t app_data_size;
+
+ /* number of elements in named blocks array */
+ uint32_t named_block_num_blocks;
+
+ /* length of name array in bootmem blocks */
+ uint32_t named_block_name_len;
+ /* address of named memory block descriptors */
+ uint64_t named_block_array_addr;
+
+};
+
+/**
+ * Initialize the boot alloc memory structures. This is
+ * normally called inside of cvmx_user_app_init()
+ *
+ * @mem_desc_ptr: Address of the free memory list
+ */
+extern int cvmx_bootmem_init(void *mem_desc_ptr);
+
+/**
+ * Allocate a block of memory from the free list that was passed
+ * to the application by the bootloader.
+ * This is an allocate-only algorithm, so freeing memory is not possible.
+ *
+ * @size: Size in bytes of block to allocate
+ * @alignment: Alignment required - must be power of 2
+ *
+ * Returns pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment);
+
+/**
+ * Allocate a block of memory from the free list that was
+ * passed to the application by the bootloader at a specific
+ * address. This is an allocate-only algorithm, so
+ * freeing memory is not possible. Allocation will fail if
+ * memory cannot be allocated at the specified address.
+ *
+ * @size: Size in bytes of block to allocate
+ * @address: Physical address to allocate memory at. If this memory is not
+ * available, the allocation fails.
+ * @alignment: Alignment required - must be power of 2
+ * Returns pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address,
+ uint64_t alignment);
+
+/**
+ * Allocate a block of memory from the free list that was
+ * passed to the application by the bootloader within a specified
+ * address range. This is an allocate-only algorithm, so
+ * freeing memory is not possible. Allocation will fail if
+ * memory cannot be allocated in the requested range.
+ *
+ * @size: Size in bytes of block to allocate
+ * @min_addr: defines the minimum address of the range
+ * @max_addr: defines the maximum address of the range
+ * @alignment: Alignment required - must be power of 2
+ * Returns pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment,
+ uint64_t min_addr, uint64_t max_addr);
+
+/**
+ * Frees a previously allocated named bootmem block.
+ *
+ * @name: name of block to free
+ *
+ * Returns 0 on failure,
+ * !0 on success
+ */
+
+
+/**
+ * Allocate a block of memory from the free list that was passed
+ * to the application by the bootloader, and assign it a name in the
+ * global named block table. (part of the cvmx_bootmem_descriptor_t structure)
+ * Named blocks can later be freed.
+ *
+ * @size: Size in bytes of block to allocate
+ * @alignment: Alignment required - must be power of 2
+ * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
+ *
+ * Returns a pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment,
+ char *name);
+
+
+
+/**
+ * Allocate a block of memory from the free list that was passed
+ * to the application by the bootloader, and assign it a name in the
+ * global named block table. (part of the cvmx_bootmem_descriptor_t structure)
+ * Named blocks can later be freed.
+ *
+ * @size: Size in bytes of block to allocate
+ * @address: Physical address to allocate memory at. If this
+ * memory is not available, the allocation fails.
+ * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN
+ * bytes
+ *
+ * Returns a pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
+ char *name);
+
+
+
+/**
+ * Allocate a block of memory from a specific range of the free list
+ * that was passed to the application by the bootloader, and assign it
+ * a name in the global named block table. (part of the
+ * cvmx_bootmem_descriptor_t structure) Named blocks can later be
+ * freed. If request cannot be satisfied within the address range
+ * specified, NULL is returned
+ *
+ * @size: Size in bytes of block to allocate
+ * @min_addr: minimum address of range
+ * @max_addr: maximum address of range
+ * @align: Alignment of memory to be allocated. (must be a power of 2)
+ * @name: name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
+ *
+ * Returns a pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
+ uint64_t max_addr, uint64_t align,
+ char *name);
+
+extern int cvmx_bootmem_free_named(char *name);
+
+/**
+ * Finds a named bootmem block by name.
+ *
+ * @name: name of block to free
+ *
+ * Returns pointer to named block descriptor on success
+ * 0 on failure
+ */
+struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name);
+
+/**
+ * Allocates a block of physical memory from the free list, at
+ * (optional) requested address and alignment.
+ *
+ * @req_size: size of region to allocate. All requests are rounded up
+ * to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size
+ *
+ * @address_min: Minimum address that block can occupy.
+ *
+ * @address_max: Specifies the maximum address_min (inclusive) that
+ * the allocation can use.
+ *
+ * @alignment: Requested alignment of the block. If this alignment
+ * cannot be met, the allocation fails. This must be a
+ * power of 2. (Note: Alignment of
+ * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
+ * internally enforced. Requested alignments of less than
+ * CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
+ * CVMX_BOOTMEM_ALIGNMENT_SIZE.)
+ *
+ * @flags: Flags to control options for the allocation.
+ *
+ * Returns physical address of block allocated, or -1 on failure
+ */
+int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min,
+ uint64_t address_max, uint64_t alignment,
+ uint32_t flags);
+
+/**
+ * Allocates a named block of physical memory from the free list, at
+ * (optional) requested address and alignment.
+ *
+ * @param size size of region to allocate. All requests are rounded
+ * up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE
+ * bytes size
+ * @param min_addr Minimum address that block can occupy.
+ * @param max_addr Specifies the maximum address_min (inclusive) that
+ * the allocation can use.
+ * @param alignment Requested alignment of the block. If this
+ * alignment cannot be met, the allocation fails.
+ * This must be a power of 2. (Note: Alignment of
+ * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
+ * internally enforced. Requested alignments of less
+ * than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
+ * CVMX_BOOTMEM_ALIGNMENT_SIZE.)
+ * @param name name to assign to named block
+ * @param flags Flags to control options for the allocation.
+ *
+ * @return physical address of block allocated, or -1 on failure
+ */
+int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
+ uint64_t max_addr,
+ uint64_t alignment,
+ char *name, uint32_t flags);
+
+/**
+ * Finds a named memory block by name.
+ * Also used for finding an unused entry in the named block table.
+ *
+ * @name: Name of memory block to find. If NULL pointer given, then
+ * finds unused descriptor, if available.
+ *
+ * @flags: Flags to control options for the allocation.
+ *
+ * Returns Pointer to memory block descriptor, NULL if not found.
+ * If NULL returned when name parameter is NULL, then no memory
+ * block descriptors are available.
+ */
+struct cvmx_bootmem_named_block_desc *
+cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags);
+
+/**
+ * Frees a named block.
+ *
+ * @name: name of block to free
+ * @flags: flags for passing options
+ *
+ * Returns 0 on failure
+ * 1 on success
+ */
+int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags);
+
+/**
+ * Frees a block to the bootmem allocator list. This must
+ * be used with care, as the size provided must match the size
+ * of the block that was allocated, or the list will become
+ * corrupted.
+ *
+ * IMPORTANT: This is only intended to be used as part of named block
+ * frees and initial population of the free memory list.
+ * *
+ *
+ * @phy_addr: physical address of block
+ * @size: size of block in bytes.
+ * @flags: flags for passing options
+ *
+ * Returns 1 on success,
+ * 0 on failure
+ */
+int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags);
+
+/**
+ * Locks the bootmem allocator. This is useful in certain situations
+ * where multiple allocations must be made without being interrupted.
+ * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
+ *
+ */
+void cvmx_bootmem_lock(void);
+
+/**
+ * Unlocks the bootmem allocator. This is useful in certain situations
+ * where multiple allocations must be made without being interrupted.
+ * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
+ *
+ */
+void cvmx_bootmem_unlock(void);
+
+#endif /* __CVMX_BOOTMEM_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
new file mode 100644
index 00000000..27cead37
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
@@ -0,0 +1,2297 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_CIU_DEFS_H__
+#define __CVMX_CIU_DEFS_H__
+
+#define CVMX_CIU_BIST (CVMX_ADD_IO_SEG(0x0001070000000730ull))
+#define CVMX_CIU_BLOCK_INT (CVMX_ADD_IO_SEG(0x00010700000007C0ull))
+#define CVMX_CIU_DINT (CVMX_ADD_IO_SEG(0x0001070000000720ull))
+#define CVMX_CIU_FUSE (CVMX_ADD_IO_SEG(0x0001070000000728ull))
+#define CVMX_CIU_GSTOP (CVMX_ADD_IO_SEG(0x0001070000000710ull))
+#define CVMX_CIU_INT33_SUM0 (CVMX_ADD_IO_SEG(0x0001070000000110ull))
+#define CVMX_CIU_INTX_EN0(offset) (CVMX_ADD_IO_SEG(0x0001070000000200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN0_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN0_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006200ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1(offset) (CVMX_ADD_IO_SEG(0x0001070000000208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN1_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006208ull) + ((offset) & 63) * 16)
+#define CVMX_CIU_INTX_EN4_0(offset) (CVMX_ADD_IO_SEG(0x0001070000000C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_0_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_0_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006C80ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1(offset) (CVMX_ADD_IO_SEG(0x0001070000000C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1_W1C(offset) (CVMX_ADD_IO_SEG(0x0001070000002C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_EN4_1_W1S(offset) (CVMX_ADD_IO_SEG(0x0001070000006C88ull) + ((offset) & 15) * 16)
+#define CVMX_CIU_INTX_SUM0(offset) (CVMX_ADD_IO_SEG(0x0001070000000000ull) + ((offset) & 63) * 8)
+#define CVMX_CIU_INTX_SUM4(offset) (CVMX_ADD_IO_SEG(0x0001070000000C00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_INT_DBG_SEL (CVMX_ADD_IO_SEG(0x00010700000007D0ull))
+#define CVMX_CIU_INT_SUM1 (CVMX_ADD_IO_SEG(0x0001070000000108ull))
+#define CVMX_CIU_MBOX_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001070000000680ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_MBOX_SETX(offset) (CVMX_ADD_IO_SEG(0x0001070000000600ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_NMI (CVMX_ADD_IO_SEG(0x0001070000000718ull))
+#define CVMX_CIU_PCI_INTA (CVMX_ADD_IO_SEG(0x0001070000000750ull))
+#define CVMX_CIU_PP_DBG (CVMX_ADD_IO_SEG(0x0001070000000708ull))
+#define CVMX_CIU_PP_POKEX(offset) (CVMX_ADD_IO_SEG(0x0001070000000580ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_PP_RST (CVMX_ADD_IO_SEG(0x0001070000000700ull))
+#define CVMX_CIU_QLM0 (CVMX_ADD_IO_SEG(0x0001070000000780ull))
+#define CVMX_CIU_QLM1 (CVMX_ADD_IO_SEG(0x0001070000000788ull))
+#define CVMX_CIU_QLM2 (CVMX_ADD_IO_SEG(0x0001070000000790ull))
+#define CVMX_CIU_QLM_DCOK (CVMX_ADD_IO_SEG(0x0001070000000760ull))
+#define CVMX_CIU_QLM_JTGC (CVMX_ADD_IO_SEG(0x0001070000000768ull))
+#define CVMX_CIU_QLM_JTGD (CVMX_ADD_IO_SEG(0x0001070000000770ull))
+#define CVMX_CIU_SOFT_BIST (CVMX_ADD_IO_SEG(0x0001070000000738ull))
+#define CVMX_CIU_SOFT_PRST (CVMX_ADD_IO_SEG(0x0001070000000748ull))
+#define CVMX_CIU_SOFT_PRST1 (CVMX_ADD_IO_SEG(0x0001070000000758ull))
+#define CVMX_CIU_SOFT_RST (CVMX_ADD_IO_SEG(0x0001070000000740ull))
+#define CVMX_CIU_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001070000000480ull) + ((offset) & 3) * 8)
+#define CVMX_CIU_WDOGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000500ull) + ((offset) & 15) * 8)
+
+union cvmx_ciu_bist {
+ uint64_t u64;
+ struct cvmx_ciu_bist_s {
+ uint64_t reserved_5_63:59;
+ uint64_t bist:5;
+ } s;
+ struct cvmx_ciu_bist_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t bist:4;
+ } cn30xx;
+ struct cvmx_ciu_bist_cn30xx cn31xx;
+ struct cvmx_ciu_bist_cn30xx cn38xx;
+ struct cvmx_ciu_bist_cn30xx cn38xxp2;
+ struct cvmx_ciu_bist_cn50xx {
+ uint64_t reserved_2_63:62;
+ uint64_t bist:2;
+ } cn50xx;
+ struct cvmx_ciu_bist_cn52xx {
+ uint64_t reserved_3_63:61;
+ uint64_t bist:3;
+ } cn52xx;
+ struct cvmx_ciu_bist_cn52xx cn52xxp1;
+ struct cvmx_ciu_bist_cn30xx cn56xx;
+ struct cvmx_ciu_bist_cn30xx cn56xxp1;
+ struct cvmx_ciu_bist_cn30xx cn58xx;
+ struct cvmx_ciu_bist_cn30xx cn58xxp1;
+ struct cvmx_ciu_bist_s cn63xx;
+ struct cvmx_ciu_bist_s cn63xxp1;
+};
+
+union cvmx_ciu_block_int {
+ uint64_t u64;
+ struct cvmx_ciu_block_int_s {
+ uint64_t reserved_43_63:21;
+ uint64_t ptp:1;
+ uint64_t dpi:1;
+ uint64_t dfm:1;
+ uint64_t reserved_34_39:6;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t reserved_31_31:1;
+ uint64_t iob:1;
+ uint64_t reserved_29_29:1;
+ uint64_t agl:1;
+ uint64_t reserved_27_27:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t reserved_18_19:2;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t sli:1;
+ uint64_t reserved_2_2:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } s;
+ struct cvmx_ciu_block_int_s cn63xx;
+ struct cvmx_ciu_block_int_s cn63xxp1;
+};
+
+union cvmx_ciu_dint {
+ uint64_t u64;
+ struct cvmx_ciu_dint_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dint:16;
+ } s;
+ struct cvmx_ciu_dint_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t dint:1;
+ } cn30xx;
+ struct cvmx_ciu_dint_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t dint:2;
+ } cn31xx;
+ struct cvmx_ciu_dint_s cn38xx;
+ struct cvmx_ciu_dint_s cn38xxp2;
+ struct cvmx_ciu_dint_cn31xx cn50xx;
+ struct cvmx_ciu_dint_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t dint:4;
+ } cn52xx;
+ struct cvmx_ciu_dint_cn52xx cn52xxp1;
+ struct cvmx_ciu_dint_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t dint:12;
+ } cn56xx;
+ struct cvmx_ciu_dint_cn56xx cn56xxp1;
+ struct cvmx_ciu_dint_s cn58xx;
+ struct cvmx_ciu_dint_s cn58xxp1;
+ struct cvmx_ciu_dint_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t dint:6;
+ } cn63xx;
+ struct cvmx_ciu_dint_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_fuse {
+ uint64_t u64;
+ struct cvmx_ciu_fuse_s {
+ uint64_t reserved_16_63:48;
+ uint64_t fuse:16;
+ } s;
+ struct cvmx_ciu_fuse_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t fuse:1;
+ } cn30xx;
+ struct cvmx_ciu_fuse_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t fuse:2;
+ } cn31xx;
+ struct cvmx_ciu_fuse_s cn38xx;
+ struct cvmx_ciu_fuse_s cn38xxp2;
+ struct cvmx_ciu_fuse_cn31xx cn50xx;
+ struct cvmx_ciu_fuse_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t fuse:4;
+ } cn52xx;
+ struct cvmx_ciu_fuse_cn52xx cn52xxp1;
+ struct cvmx_ciu_fuse_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t fuse:12;
+ } cn56xx;
+ struct cvmx_ciu_fuse_cn56xx cn56xxp1;
+ struct cvmx_ciu_fuse_s cn58xx;
+ struct cvmx_ciu_fuse_s cn58xxp1;
+ struct cvmx_ciu_fuse_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t fuse:6;
+ } cn63xx;
+ struct cvmx_ciu_fuse_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_gstop {
+ uint64_t u64;
+ struct cvmx_ciu_gstop_s {
+ uint64_t reserved_1_63:63;
+ uint64_t gstop:1;
+ } s;
+ struct cvmx_ciu_gstop_s cn30xx;
+ struct cvmx_ciu_gstop_s cn31xx;
+ struct cvmx_ciu_gstop_s cn38xx;
+ struct cvmx_ciu_gstop_s cn38xxp2;
+ struct cvmx_ciu_gstop_s cn50xx;
+ struct cvmx_ciu_gstop_s cn52xx;
+ struct cvmx_ciu_gstop_s cn52xxp1;
+ struct cvmx_ciu_gstop_s cn56xx;
+ struct cvmx_ciu_gstop_s cn56xxp1;
+ struct cvmx_ciu_gstop_s cn58xx;
+ struct cvmx_ciu_gstop_s cn58xxp1;
+ struct cvmx_ciu_gstop_s cn63xx;
+ struct cvmx_ciu_gstop_s cn63xxp1;
+};
+
+union cvmx_ciu_intx_en0 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en0_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en0_cn30xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_47_47:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn30xx;
+ struct cvmx_ciu_intx_en0_cn31xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn31xx;
+ struct cvmx_ciu_intx_en0_cn38xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn38xx;
+ struct cvmx_ciu_intx_en0_cn38xx cn38xxp2;
+ struct cvmx_ciu_intx_en0_cn30xx cn50xx;
+ struct cvmx_ciu_intx_en0_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en0_cn52xx cn52xxp1;
+ struct cvmx_ciu_intx_en0_cn56xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn56xx;
+ struct cvmx_ciu_intx_en0_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_en0_cn38xx cn58xx;
+ struct cvmx_ciu_intx_en0_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_en0_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en0_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en0_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en0_w1c_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en0_w1c_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en0_w1c_s cn56xx;
+ struct cvmx_ciu_intx_en0_w1c_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en0_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en0_w1s_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en0_w1s_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en0_w1s_s cn56xx;
+ struct cvmx_ciu_intx_en0_w1s_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en1 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en1_s {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en1_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t wdog:1;
+ } cn30xx;
+ struct cvmx_ciu_intx_en1_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t wdog:2;
+ } cn31xx;
+ struct cvmx_ciu_intx_en1_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn38xx;
+ struct cvmx_ciu_intx_en1_cn38xx cn38xxp2;
+ struct cvmx_ciu_intx_en1_cn31xx cn50xx;
+ struct cvmx_ciu_intx_en1_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en1_cn52xxp1 {
+ uint64_t reserved_19_63:45;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xxp1;
+ struct cvmx_ciu_intx_en1_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en1_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_en1_cn38xx cn58xx;
+ struct cvmx_ciu_intx_en1_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_en1_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en1_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en1_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en1_w1c_s {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en1_w1c_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en1_w1c_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en1_w1c_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en1_w1c_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en1_w1c_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en1_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en1_w1s_s {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en1_w1s_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en1_w1s_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en1_w1s_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en1_w1s_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en1_w1s_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en4_0 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_0_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en4_0_cn50xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_47_47:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn50xx;
+ struct cvmx_ciu_intx_en4_0_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_0_cn52xx cn52xxp1;
+ struct cvmx_ciu_intx_en4_0_cn56xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn56xx;
+ struct cvmx_ciu_intx_en4_0_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_en4_0_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en4_0_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_en4_0_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en4_0_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en4_0_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_0_w1c_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en4_0_w1c_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_0_w1c_s cn56xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en4_0_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_0_w1s_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en4_0_w1s_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_0_w1s_s cn56xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en4_1 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_1_s {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en4_1_cn50xx {
+ uint64_t reserved_2_63:62;
+ uint64_t wdog:2;
+ } cn50xx;
+ struct cvmx_ciu_intx_en4_1_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_1_cn52xxp1 {
+ uint64_t reserved_19_63:45;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xxp1;
+ struct cvmx_ciu_intx_en4_1_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en4_1_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_en4_1_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en4_1_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_en4_1_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en4_1_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en4_1_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_1_w1c_s {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en4_1_w1c_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_en4_1_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_1_w1s_s {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en4_1_w1s_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_sum0 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_sum0_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_sum0_cn30xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_47_47:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn30xx;
+ struct cvmx_ciu_intx_sum0_cn31xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn31xx;
+ struct cvmx_ciu_intx_sum0_cn38xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn38xx;
+ struct cvmx_ciu_intx_sum0_cn38xx cn38xxp2;
+ struct cvmx_ciu_intx_sum0_cn30xx cn50xx;
+ struct cvmx_ciu_intx_sum0_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_sum0_cn52xx cn52xxp1;
+ struct cvmx_ciu_intx_sum0_cn56xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn56xx;
+ struct cvmx_ciu_intx_sum0_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_sum0_cn38xx cn58xx;
+ struct cvmx_ciu_intx_sum0_cn38xx cn58xxp1;
+ struct cvmx_ciu_intx_sum0_cn52xx cn63xx;
+ struct cvmx_ciu_intx_sum0_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_intx_sum4 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_sum4_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_sum4_cn50xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_47_47:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn50xx;
+ struct cvmx_ciu_intx_sum4_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_sum4_cn52xx cn52xxp1;
+ struct cvmx_ciu_intx_sum4_cn56xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn56xx;
+ struct cvmx_ciu_intx_sum4_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_sum4_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_sum4_cn58xx cn58xxp1;
+ struct cvmx_ciu_intx_sum4_cn52xx cn63xx;
+ struct cvmx_ciu_intx_sum4_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_int33_sum0 {
+ uint64_t u64;
+ struct cvmx_ciu_int33_sum0_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_int33_sum0_s cn63xx;
+ struct cvmx_ciu_int33_sum0_s cn63xxp1;
+};
+
+union cvmx_ciu_int_dbg_sel {
+ uint64_t u64;
+ struct cvmx_ciu_int_dbg_sel_s {
+ uint64_t reserved_19_63:45;
+ uint64_t sel:3;
+ uint64_t reserved_10_15:6;
+ uint64_t irq:2;
+ uint64_t reserved_3_7:5;
+ uint64_t pp:3;
+ } s;
+ struct cvmx_ciu_int_dbg_sel_s cn63xx;
+};
+
+union cvmx_ciu_int_sum1 {
+ uint64_t u64;
+ struct cvmx_ciu_int_sum1_s {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_int_sum1_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t wdog:1;
+ } cn30xx;
+ struct cvmx_ciu_int_sum1_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t wdog:2;
+ } cn31xx;
+ struct cvmx_ciu_int_sum1_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn38xx;
+ struct cvmx_ciu_int_sum1_cn38xx cn38xxp2;
+ struct cvmx_ciu_int_sum1_cn31xx cn50xx;
+ struct cvmx_ciu_int_sum1_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_int_sum1_cn52xxp1 {
+ uint64_t reserved_19_63:45;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xxp1;
+ struct cvmx_ciu_int_sum1_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_int_sum1_cn56xx cn56xxp1;
+ struct cvmx_ciu_int_sum1_cn38xx cn58xx;
+ struct cvmx_ciu_int_sum1_cn38xx cn58xxp1;
+ struct cvmx_ciu_int_sum1_cn63xx {
+ uint64_t rst:1;
+ uint64_t reserved_57_62:6;
+ uint64_t dfm:1;
+ uint64_t reserved_53_55:3;
+ uint64_t lmc0:1;
+ uint64_t srio1:1;
+ uint64_t srio0:1;
+ uint64_t pem1:1;
+ uint64_t pem0:1;
+ uint64_t ptp:1;
+ uint64_t agl:1;
+ uint64_t reserved_37_45:9;
+ uint64_t agx0:1;
+ uint64_t dpi:1;
+ uint64_t sli:1;
+ uint64_t usb:1;
+ uint64_t dfa:1;
+ uint64_t key:1;
+ uint64_t rad:1;
+ uint64_t tim:1;
+ uint64_t zip:1;
+ uint64_t pko:1;
+ uint64_t pip:1;
+ uint64_t ipd:1;
+ uint64_t l2c:1;
+ uint64_t pow:1;
+ uint64_t fpa:1;
+ uint64_t iob:1;
+ uint64_t mio:1;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t reserved_6_17:12;
+ uint64_t wdog:6;
+ } cn63xx;
+ struct cvmx_ciu_int_sum1_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_mbox_clrx {
+ uint64_t u64;
+ struct cvmx_ciu_mbox_clrx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bits:32;
+ } s;
+ struct cvmx_ciu_mbox_clrx_s cn30xx;
+ struct cvmx_ciu_mbox_clrx_s cn31xx;
+ struct cvmx_ciu_mbox_clrx_s cn38xx;
+ struct cvmx_ciu_mbox_clrx_s cn38xxp2;
+ struct cvmx_ciu_mbox_clrx_s cn50xx;
+ struct cvmx_ciu_mbox_clrx_s cn52xx;
+ struct cvmx_ciu_mbox_clrx_s cn52xxp1;
+ struct cvmx_ciu_mbox_clrx_s cn56xx;
+ struct cvmx_ciu_mbox_clrx_s cn56xxp1;
+ struct cvmx_ciu_mbox_clrx_s cn58xx;
+ struct cvmx_ciu_mbox_clrx_s cn58xxp1;
+ struct cvmx_ciu_mbox_clrx_s cn63xx;
+ struct cvmx_ciu_mbox_clrx_s cn63xxp1;
+};
+
+union cvmx_ciu_mbox_setx {
+ uint64_t u64;
+ struct cvmx_ciu_mbox_setx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bits:32;
+ } s;
+ struct cvmx_ciu_mbox_setx_s cn30xx;
+ struct cvmx_ciu_mbox_setx_s cn31xx;
+ struct cvmx_ciu_mbox_setx_s cn38xx;
+ struct cvmx_ciu_mbox_setx_s cn38xxp2;
+ struct cvmx_ciu_mbox_setx_s cn50xx;
+ struct cvmx_ciu_mbox_setx_s cn52xx;
+ struct cvmx_ciu_mbox_setx_s cn52xxp1;
+ struct cvmx_ciu_mbox_setx_s cn56xx;
+ struct cvmx_ciu_mbox_setx_s cn56xxp1;
+ struct cvmx_ciu_mbox_setx_s cn58xx;
+ struct cvmx_ciu_mbox_setx_s cn58xxp1;
+ struct cvmx_ciu_mbox_setx_s cn63xx;
+ struct cvmx_ciu_mbox_setx_s cn63xxp1;
+};
+
+union cvmx_ciu_nmi {
+ uint64_t u64;
+ struct cvmx_ciu_nmi_s {
+ uint64_t reserved_16_63:48;
+ uint64_t nmi:16;
+ } s;
+ struct cvmx_ciu_nmi_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t nmi:1;
+ } cn30xx;
+ struct cvmx_ciu_nmi_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t nmi:2;
+ } cn31xx;
+ struct cvmx_ciu_nmi_s cn38xx;
+ struct cvmx_ciu_nmi_s cn38xxp2;
+ struct cvmx_ciu_nmi_cn31xx cn50xx;
+ struct cvmx_ciu_nmi_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t nmi:4;
+ } cn52xx;
+ struct cvmx_ciu_nmi_cn52xx cn52xxp1;
+ struct cvmx_ciu_nmi_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t nmi:12;
+ } cn56xx;
+ struct cvmx_ciu_nmi_cn56xx cn56xxp1;
+ struct cvmx_ciu_nmi_s cn58xx;
+ struct cvmx_ciu_nmi_s cn58xxp1;
+ struct cvmx_ciu_nmi_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t nmi:6;
+ } cn63xx;
+ struct cvmx_ciu_nmi_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_pci_inta {
+ uint64_t u64;
+ struct cvmx_ciu_pci_inta_s {
+ uint64_t reserved_2_63:62;
+ uint64_t intr:2;
+ } s;
+ struct cvmx_ciu_pci_inta_s cn30xx;
+ struct cvmx_ciu_pci_inta_s cn31xx;
+ struct cvmx_ciu_pci_inta_s cn38xx;
+ struct cvmx_ciu_pci_inta_s cn38xxp2;
+ struct cvmx_ciu_pci_inta_s cn50xx;
+ struct cvmx_ciu_pci_inta_s cn52xx;
+ struct cvmx_ciu_pci_inta_s cn52xxp1;
+ struct cvmx_ciu_pci_inta_s cn56xx;
+ struct cvmx_ciu_pci_inta_s cn56xxp1;
+ struct cvmx_ciu_pci_inta_s cn58xx;
+ struct cvmx_ciu_pci_inta_s cn58xxp1;
+ struct cvmx_ciu_pci_inta_s cn63xx;
+ struct cvmx_ciu_pci_inta_s cn63xxp1;
+};
+
+union cvmx_ciu_pp_dbg {
+ uint64_t u64;
+ struct cvmx_ciu_pp_dbg_s {
+ uint64_t reserved_16_63:48;
+ uint64_t ppdbg:16;
+ } s;
+ struct cvmx_ciu_pp_dbg_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t ppdbg:1;
+ } cn30xx;
+ struct cvmx_ciu_pp_dbg_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t ppdbg:2;
+ } cn31xx;
+ struct cvmx_ciu_pp_dbg_s cn38xx;
+ struct cvmx_ciu_pp_dbg_s cn38xxp2;
+ struct cvmx_ciu_pp_dbg_cn31xx cn50xx;
+ struct cvmx_ciu_pp_dbg_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t ppdbg:4;
+ } cn52xx;
+ struct cvmx_ciu_pp_dbg_cn52xx cn52xxp1;
+ struct cvmx_ciu_pp_dbg_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t ppdbg:12;
+ } cn56xx;
+ struct cvmx_ciu_pp_dbg_cn56xx cn56xxp1;
+ struct cvmx_ciu_pp_dbg_s cn58xx;
+ struct cvmx_ciu_pp_dbg_s cn58xxp1;
+ struct cvmx_ciu_pp_dbg_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t ppdbg:6;
+ } cn63xx;
+ struct cvmx_ciu_pp_dbg_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_pp_pokex {
+ uint64_t u64;
+ struct cvmx_ciu_pp_pokex_s {
+ uint64_t poke:64;
+ } s;
+ struct cvmx_ciu_pp_pokex_s cn30xx;
+ struct cvmx_ciu_pp_pokex_s cn31xx;
+ struct cvmx_ciu_pp_pokex_s cn38xx;
+ struct cvmx_ciu_pp_pokex_s cn38xxp2;
+ struct cvmx_ciu_pp_pokex_s cn50xx;
+ struct cvmx_ciu_pp_pokex_s cn52xx;
+ struct cvmx_ciu_pp_pokex_s cn52xxp1;
+ struct cvmx_ciu_pp_pokex_s cn56xx;
+ struct cvmx_ciu_pp_pokex_s cn56xxp1;
+ struct cvmx_ciu_pp_pokex_s cn58xx;
+ struct cvmx_ciu_pp_pokex_s cn58xxp1;
+ struct cvmx_ciu_pp_pokex_s cn63xx;
+ struct cvmx_ciu_pp_pokex_s cn63xxp1;
+};
+
+union cvmx_ciu_pp_rst {
+ uint64_t u64;
+ struct cvmx_ciu_pp_rst_s {
+ uint64_t reserved_16_63:48;
+ uint64_t rst:15;
+ uint64_t rst0:1;
+ } s;
+ struct cvmx_ciu_pp_rst_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t rst0:1;
+ } cn30xx;
+ struct cvmx_ciu_pp_rst_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t rst:1;
+ uint64_t rst0:1;
+ } cn31xx;
+ struct cvmx_ciu_pp_rst_s cn38xx;
+ struct cvmx_ciu_pp_rst_s cn38xxp2;
+ struct cvmx_ciu_pp_rst_cn31xx cn50xx;
+ struct cvmx_ciu_pp_rst_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t rst:3;
+ uint64_t rst0:1;
+ } cn52xx;
+ struct cvmx_ciu_pp_rst_cn52xx cn52xxp1;
+ struct cvmx_ciu_pp_rst_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t rst:11;
+ uint64_t rst0:1;
+ } cn56xx;
+ struct cvmx_ciu_pp_rst_cn56xx cn56xxp1;
+ struct cvmx_ciu_pp_rst_s cn58xx;
+ struct cvmx_ciu_pp_rst_s cn58xxp1;
+ struct cvmx_ciu_pp_rst_cn63xx {
+ uint64_t reserved_6_63:58;
+ uint64_t rst:5;
+ uint64_t rst0:1;
+ } cn63xx;
+ struct cvmx_ciu_pp_rst_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_qlm0 {
+ uint64_t u64;
+ struct cvmx_ciu_qlm0_s {
+ uint64_t g2bypass:1;
+ uint64_t reserved_53_62:10;
+ uint64_t g2deemph:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2margin:5;
+ uint64_t reserved_32_39:8;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } s;
+ struct cvmx_ciu_qlm0_s cn63xx;
+ struct cvmx_ciu_qlm0_cn63xxp1 {
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_20_30:11;
+ uint64_t txdeemph:4;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } cn63xxp1;
+};
+
+union cvmx_ciu_qlm1 {
+ uint64_t u64;
+ struct cvmx_ciu_qlm1_s {
+ uint64_t g2bypass:1;
+ uint64_t reserved_53_62:10;
+ uint64_t g2deemph:5;
+ uint64_t reserved_45_47:3;
+ uint64_t g2margin:5;
+ uint64_t reserved_32_39:8;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } s;
+ struct cvmx_ciu_qlm1_s cn63xx;
+ struct cvmx_ciu_qlm1_cn63xxp1 {
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_20_30:11;
+ uint64_t txdeemph:4;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } cn63xxp1;
+};
+
+union cvmx_ciu_qlm2 {
+ uint64_t u64;
+ struct cvmx_ciu_qlm2_s {
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_21_30:10;
+ uint64_t txdeemph:5;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } s;
+ struct cvmx_ciu_qlm2_s cn63xx;
+ struct cvmx_ciu_qlm2_cn63xxp1 {
+ uint64_t reserved_32_63:32;
+ uint64_t txbypass:1;
+ uint64_t reserved_20_30:11;
+ uint64_t txdeemph:4;
+ uint64_t reserved_13_15:3;
+ uint64_t txmargin:5;
+ uint64_t reserved_4_7:4;
+ uint64_t lane_en:4;
+ } cn63xxp1;
+};
+
+union cvmx_ciu_qlm_dcok {
+ uint64_t u64;
+ struct cvmx_ciu_qlm_dcok_s {
+ uint64_t reserved_4_63:60;
+ uint64_t qlm_dcok:4;
+ } s;
+ struct cvmx_ciu_qlm_dcok_cn52xx {
+ uint64_t reserved_2_63:62;
+ uint64_t qlm_dcok:2;
+ } cn52xx;
+ struct cvmx_ciu_qlm_dcok_cn52xx cn52xxp1;
+ struct cvmx_ciu_qlm_dcok_s cn56xx;
+ struct cvmx_ciu_qlm_dcok_s cn56xxp1;
+};
+
+union cvmx_ciu_qlm_jtgc {
+ uint64_t u64;
+ struct cvmx_ciu_qlm_jtgc_s {
+ uint64_t reserved_11_63:53;
+ uint64_t clk_div:3;
+ uint64_t reserved_6_7:2;
+ uint64_t mux_sel:2;
+ uint64_t bypass:4;
+ } s;
+ struct cvmx_ciu_qlm_jtgc_cn52xx {
+ uint64_t reserved_11_63:53;
+ uint64_t clk_div:3;
+ uint64_t reserved_5_7:3;
+ uint64_t mux_sel:1;
+ uint64_t reserved_2_3:2;
+ uint64_t bypass:2;
+ } cn52xx;
+ struct cvmx_ciu_qlm_jtgc_cn52xx cn52xxp1;
+ struct cvmx_ciu_qlm_jtgc_s cn56xx;
+ struct cvmx_ciu_qlm_jtgc_s cn56xxp1;
+ struct cvmx_ciu_qlm_jtgc_cn63xx {
+ uint64_t reserved_11_63:53;
+ uint64_t clk_div:3;
+ uint64_t reserved_6_7:2;
+ uint64_t mux_sel:2;
+ uint64_t reserved_3_3:1;
+ uint64_t bypass:3;
+ } cn63xx;
+ struct cvmx_ciu_qlm_jtgc_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_qlm_jtgd {
+ uint64_t u64;
+ struct cvmx_ciu_qlm_jtgd_s {
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_44_60:17;
+ uint64_t select:4;
+ uint64_t reserved_37_39:3;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+ } s;
+ struct cvmx_ciu_qlm_jtgd_cn52xx {
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_42_60:19;
+ uint64_t select:2;
+ uint64_t reserved_37_39:3;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+ } cn52xx;
+ struct cvmx_ciu_qlm_jtgd_cn52xx cn52xxp1;
+ struct cvmx_ciu_qlm_jtgd_s cn56xx;
+ struct cvmx_ciu_qlm_jtgd_cn56xxp1 {
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_37_60:24;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+ } cn56xxp1;
+ struct cvmx_ciu_qlm_jtgd_cn63xx {
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_43_60:18;
+ uint64_t select:3;
+ uint64_t reserved_37_39:3;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+ } cn63xx;
+ struct cvmx_ciu_qlm_jtgd_cn63xx cn63xxp1;
+};
+
+union cvmx_ciu_soft_bist {
+ uint64_t u64;
+ struct cvmx_ciu_soft_bist_s {
+ uint64_t reserved_1_63:63;
+ uint64_t soft_bist:1;
+ } s;
+ struct cvmx_ciu_soft_bist_s cn30xx;
+ struct cvmx_ciu_soft_bist_s cn31xx;
+ struct cvmx_ciu_soft_bist_s cn38xx;
+ struct cvmx_ciu_soft_bist_s cn38xxp2;
+ struct cvmx_ciu_soft_bist_s cn50xx;
+ struct cvmx_ciu_soft_bist_s cn52xx;
+ struct cvmx_ciu_soft_bist_s cn52xxp1;
+ struct cvmx_ciu_soft_bist_s cn56xx;
+ struct cvmx_ciu_soft_bist_s cn56xxp1;
+ struct cvmx_ciu_soft_bist_s cn58xx;
+ struct cvmx_ciu_soft_bist_s cn58xxp1;
+ struct cvmx_ciu_soft_bist_s cn63xx;
+ struct cvmx_ciu_soft_bist_s cn63xxp1;
+};
+
+union cvmx_ciu_soft_prst {
+ uint64_t u64;
+ struct cvmx_ciu_soft_prst_s {
+ uint64_t reserved_3_63:61;
+ uint64_t host64:1;
+ uint64_t npi:1;
+ uint64_t soft_prst:1;
+ } s;
+ struct cvmx_ciu_soft_prst_s cn30xx;
+ struct cvmx_ciu_soft_prst_s cn31xx;
+ struct cvmx_ciu_soft_prst_s cn38xx;
+ struct cvmx_ciu_soft_prst_s cn38xxp2;
+ struct cvmx_ciu_soft_prst_s cn50xx;
+ struct cvmx_ciu_soft_prst_cn52xx {
+ uint64_t reserved_1_63:63;
+ uint64_t soft_prst:1;
+ } cn52xx;
+ struct cvmx_ciu_soft_prst_cn52xx cn52xxp1;
+ struct cvmx_ciu_soft_prst_cn52xx cn56xx;
+ struct cvmx_ciu_soft_prst_cn52xx cn56xxp1;
+ struct cvmx_ciu_soft_prst_s cn58xx;
+ struct cvmx_ciu_soft_prst_s cn58xxp1;
+ struct cvmx_ciu_soft_prst_cn52xx cn63xx;
+ struct cvmx_ciu_soft_prst_cn52xx cn63xxp1;
+};
+
+union cvmx_ciu_soft_prst1 {
+ uint64_t u64;
+ struct cvmx_ciu_soft_prst1_s {
+ uint64_t reserved_1_63:63;
+ uint64_t soft_prst:1;
+ } s;
+ struct cvmx_ciu_soft_prst1_s cn52xx;
+ struct cvmx_ciu_soft_prst1_s cn52xxp1;
+ struct cvmx_ciu_soft_prst1_s cn56xx;
+ struct cvmx_ciu_soft_prst1_s cn56xxp1;
+ struct cvmx_ciu_soft_prst1_s cn63xx;
+ struct cvmx_ciu_soft_prst1_s cn63xxp1;
+};
+
+union cvmx_ciu_soft_rst {
+ uint64_t u64;
+ struct cvmx_ciu_soft_rst_s {
+ uint64_t reserved_1_63:63;
+ uint64_t soft_rst:1;
+ } s;
+ struct cvmx_ciu_soft_rst_s cn30xx;
+ struct cvmx_ciu_soft_rst_s cn31xx;
+ struct cvmx_ciu_soft_rst_s cn38xx;
+ struct cvmx_ciu_soft_rst_s cn38xxp2;
+ struct cvmx_ciu_soft_rst_s cn50xx;
+ struct cvmx_ciu_soft_rst_s cn52xx;
+ struct cvmx_ciu_soft_rst_s cn52xxp1;
+ struct cvmx_ciu_soft_rst_s cn56xx;
+ struct cvmx_ciu_soft_rst_s cn56xxp1;
+ struct cvmx_ciu_soft_rst_s cn58xx;
+ struct cvmx_ciu_soft_rst_s cn58xxp1;
+ struct cvmx_ciu_soft_rst_s cn63xx;
+ struct cvmx_ciu_soft_rst_s cn63xxp1;
+};
+
+union cvmx_ciu_timx {
+ uint64_t u64;
+ struct cvmx_ciu_timx_s {
+ uint64_t reserved_37_63:27;
+ uint64_t one_shot:1;
+ uint64_t len:36;
+ } s;
+ struct cvmx_ciu_timx_s cn30xx;
+ struct cvmx_ciu_timx_s cn31xx;
+ struct cvmx_ciu_timx_s cn38xx;
+ struct cvmx_ciu_timx_s cn38xxp2;
+ struct cvmx_ciu_timx_s cn50xx;
+ struct cvmx_ciu_timx_s cn52xx;
+ struct cvmx_ciu_timx_s cn52xxp1;
+ struct cvmx_ciu_timx_s cn56xx;
+ struct cvmx_ciu_timx_s cn56xxp1;
+ struct cvmx_ciu_timx_s cn58xx;
+ struct cvmx_ciu_timx_s cn58xxp1;
+ struct cvmx_ciu_timx_s cn63xx;
+ struct cvmx_ciu_timx_s cn63xxp1;
+};
+
+union cvmx_ciu_wdogx {
+ uint64_t u64;
+ struct cvmx_ciu_wdogx_s {
+ uint64_t reserved_46_63:18;
+ uint64_t gstopen:1;
+ uint64_t dstop:1;
+ uint64_t cnt:24;
+ uint64_t len:16;
+ uint64_t state:2;
+ uint64_t mode:2;
+ } s;
+ struct cvmx_ciu_wdogx_s cn30xx;
+ struct cvmx_ciu_wdogx_s cn31xx;
+ struct cvmx_ciu_wdogx_s cn38xx;
+ struct cvmx_ciu_wdogx_s cn38xxp2;
+ struct cvmx_ciu_wdogx_s cn50xx;
+ struct cvmx_ciu_wdogx_s cn52xx;
+ struct cvmx_ciu_wdogx_s cn52xxp1;
+ struct cvmx_ciu_wdogx_s cn56xx;
+ struct cvmx_ciu_wdogx_s cn56xxp1;
+ struct cvmx_ciu_wdogx_s cn58xx;
+ struct cvmx_ciu_wdogx_s cn58xxp1;
+ struct cvmx_ciu_wdogx_s cn63xx;
+ struct cvmx_ciu_wdogx_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-gpio-defs.h b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
new file mode 100644
index 00000000..395564e8
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
@@ -0,0 +1,245 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_GPIO_DEFS_H__
+#define __CVMX_GPIO_DEFS_H__
+
+#define CVMX_GPIO_BIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000800ull) + ((offset) & 15) * 8)
+#define CVMX_GPIO_BOOT_ENA (CVMX_ADD_IO_SEG(0x00010700000008A8ull))
+#define CVMX_GPIO_CLK_GENX(offset) (CVMX_ADD_IO_SEG(0x00010700000008C0ull) + ((offset) & 3) * 8)
+#define CVMX_GPIO_CLK_QLMX(offset) (CVMX_ADD_IO_SEG(0x00010700000008E0ull) + ((offset) & 1) * 8)
+#define CVMX_GPIO_DBG_ENA (CVMX_ADD_IO_SEG(0x00010700000008A0ull))
+#define CVMX_GPIO_INT_CLR (CVMX_ADD_IO_SEG(0x0001070000000898ull))
+#define CVMX_GPIO_RX_DAT (CVMX_ADD_IO_SEG(0x0001070000000880ull))
+#define CVMX_GPIO_TX_CLR (CVMX_ADD_IO_SEG(0x0001070000000890ull))
+#define CVMX_GPIO_TX_SET (CVMX_ADD_IO_SEG(0x0001070000000888ull))
+#define CVMX_GPIO_XBIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000900ull) + ((offset) & 31) * 8 - 8*16)
+
+union cvmx_gpio_bit_cfgx {
+ uint64_t u64;
+ struct cvmx_gpio_bit_cfgx_s {
+ uint64_t reserved_17_63:47;
+ uint64_t synce_sel:2;
+ uint64_t clk_gen:1;
+ uint64_t clk_sel:2;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t int_type:1;
+ uint64_t int_en:1;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+ } s;
+ struct cvmx_gpio_bit_cfgx_cn30xx {
+ uint64_t reserved_12_63:52;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t int_type:1;
+ uint64_t int_en:1;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+ } cn30xx;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn31xx;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn38xx;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn50xx;
+ struct cvmx_gpio_bit_cfgx_cn52xx {
+ uint64_t reserved_15_63:49;
+ uint64_t clk_gen:1;
+ uint64_t clk_sel:2;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t int_type:1;
+ uint64_t int_en:1;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+ } cn52xx;
+ struct cvmx_gpio_bit_cfgx_cn52xx cn52xxp1;
+ struct cvmx_gpio_bit_cfgx_cn52xx cn56xx;
+ struct cvmx_gpio_bit_cfgx_cn52xx cn56xxp1;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn58xx;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1;
+ struct cvmx_gpio_bit_cfgx_s cn63xx;
+ struct cvmx_gpio_bit_cfgx_s cn63xxp1;
+};
+
+union cvmx_gpio_boot_ena {
+ uint64_t u64;
+ struct cvmx_gpio_boot_ena_s {
+ uint64_t reserved_12_63:52;
+ uint64_t boot_ena:4;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_gpio_boot_ena_s cn30xx;
+ struct cvmx_gpio_boot_ena_s cn31xx;
+ struct cvmx_gpio_boot_ena_s cn50xx;
+};
+
+union cvmx_gpio_clk_genx {
+ uint64_t u64;
+ struct cvmx_gpio_clk_genx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t n:32;
+ } s;
+ struct cvmx_gpio_clk_genx_s cn52xx;
+ struct cvmx_gpio_clk_genx_s cn52xxp1;
+ struct cvmx_gpio_clk_genx_s cn56xx;
+ struct cvmx_gpio_clk_genx_s cn56xxp1;
+ struct cvmx_gpio_clk_genx_s cn63xx;
+ struct cvmx_gpio_clk_genx_s cn63xxp1;
+};
+
+union cvmx_gpio_clk_qlmx {
+ uint64_t u64;
+ struct cvmx_gpio_clk_qlmx_s {
+ uint64_t reserved_3_63:61;
+ uint64_t div:1;
+ uint64_t lane_sel:2;
+ } s;
+ struct cvmx_gpio_clk_qlmx_s cn63xx;
+ struct cvmx_gpio_clk_qlmx_s cn63xxp1;
+};
+
+union cvmx_gpio_dbg_ena {
+ uint64_t u64;
+ struct cvmx_gpio_dbg_ena_s {
+ uint64_t reserved_21_63:43;
+ uint64_t dbg_ena:21;
+ } s;
+ struct cvmx_gpio_dbg_ena_s cn30xx;
+ struct cvmx_gpio_dbg_ena_s cn31xx;
+ struct cvmx_gpio_dbg_ena_s cn50xx;
+};
+
+union cvmx_gpio_int_clr {
+ uint64_t u64;
+ struct cvmx_gpio_int_clr_s {
+ uint64_t reserved_16_63:48;
+ uint64_t type:16;
+ } s;
+ struct cvmx_gpio_int_clr_s cn30xx;
+ struct cvmx_gpio_int_clr_s cn31xx;
+ struct cvmx_gpio_int_clr_s cn38xx;
+ struct cvmx_gpio_int_clr_s cn38xxp2;
+ struct cvmx_gpio_int_clr_s cn50xx;
+ struct cvmx_gpio_int_clr_s cn52xx;
+ struct cvmx_gpio_int_clr_s cn52xxp1;
+ struct cvmx_gpio_int_clr_s cn56xx;
+ struct cvmx_gpio_int_clr_s cn56xxp1;
+ struct cvmx_gpio_int_clr_s cn58xx;
+ struct cvmx_gpio_int_clr_s cn58xxp1;
+ struct cvmx_gpio_int_clr_s cn63xx;
+ struct cvmx_gpio_int_clr_s cn63xxp1;
+};
+
+union cvmx_gpio_rx_dat {
+ uint64_t u64;
+ struct cvmx_gpio_rx_dat_s {
+ uint64_t reserved_24_63:40;
+ uint64_t dat:24;
+ } s;
+ struct cvmx_gpio_rx_dat_s cn30xx;
+ struct cvmx_gpio_rx_dat_s cn31xx;
+ struct cvmx_gpio_rx_dat_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t dat:16;
+ } cn38xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn38xxp2;
+ struct cvmx_gpio_rx_dat_s cn50xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn52xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn52xxp1;
+ struct cvmx_gpio_rx_dat_cn38xx cn56xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn56xxp1;
+ struct cvmx_gpio_rx_dat_cn38xx cn58xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn58xxp1;
+ struct cvmx_gpio_rx_dat_cn38xx cn63xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn63xxp1;
+};
+
+union cvmx_gpio_tx_clr {
+ uint64_t u64;
+ struct cvmx_gpio_tx_clr_s {
+ uint64_t reserved_24_63:40;
+ uint64_t clr:24;
+ } s;
+ struct cvmx_gpio_tx_clr_s cn30xx;
+ struct cvmx_gpio_tx_clr_s cn31xx;
+ struct cvmx_gpio_tx_clr_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t clr:16;
+ } cn38xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn38xxp2;
+ struct cvmx_gpio_tx_clr_s cn50xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn52xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn52xxp1;
+ struct cvmx_gpio_tx_clr_cn38xx cn56xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn56xxp1;
+ struct cvmx_gpio_tx_clr_cn38xx cn58xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn58xxp1;
+ struct cvmx_gpio_tx_clr_cn38xx cn63xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn63xxp1;
+};
+
+union cvmx_gpio_tx_set {
+ uint64_t u64;
+ struct cvmx_gpio_tx_set_s {
+ uint64_t reserved_24_63:40;
+ uint64_t set:24;
+ } s;
+ struct cvmx_gpio_tx_set_s cn30xx;
+ struct cvmx_gpio_tx_set_s cn31xx;
+ struct cvmx_gpio_tx_set_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t set:16;
+ } cn38xx;
+ struct cvmx_gpio_tx_set_cn38xx cn38xxp2;
+ struct cvmx_gpio_tx_set_s cn50xx;
+ struct cvmx_gpio_tx_set_cn38xx cn52xx;
+ struct cvmx_gpio_tx_set_cn38xx cn52xxp1;
+ struct cvmx_gpio_tx_set_cn38xx cn56xx;
+ struct cvmx_gpio_tx_set_cn38xx cn56xxp1;
+ struct cvmx_gpio_tx_set_cn38xx cn58xx;
+ struct cvmx_gpio_tx_set_cn38xx cn58xxp1;
+ struct cvmx_gpio_tx_set_cn38xx cn63xx;
+ struct cvmx_gpio_tx_set_cn38xx cn63xxp1;
+};
+
+union cvmx_gpio_xbit_cfgx {
+ uint64_t u64;
+ struct cvmx_gpio_xbit_cfgx_s {
+ uint64_t reserved_12_63:52;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t reserved_2_3:2;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+ } s;
+ struct cvmx_gpio_xbit_cfgx_s cn30xx;
+ struct cvmx_gpio_xbit_cfgx_s cn31xx;
+ struct cvmx_gpio_xbit_cfgx_s cn50xx;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-errata.h b/arch/mips/include/asm/octeon/cvmx-helper-errata.h
new file mode 100644
index 00000000..5fc99189
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-helper-errata.h
@@ -0,0 +1,33 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_HELPER_ERRATA_H__
+#define __CVMX_HELPER_ERRATA_H__
+
+extern void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm);
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-jtag.h b/arch/mips/include/asm/octeon/cvmx-helper-jtag.h
new file mode 100644
index 00000000..29f016dd
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-helper-jtag.h
@@ -0,0 +1,43 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Helper utilities for qlm_jtag.
+ *
+ */
+
+#ifndef __CVMX_HELPER_JTAG_H__
+#define __CVMX_HELPER_JTAG_H__
+
+extern void cvmx_helper_qlm_jtag_init(void);
+extern uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data);
+extern void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits);
+extern void cvmx_helper_qlm_jtag_update(int qlm);
+
+#endif /* __CVMX_HELPER_JTAG_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-iob-defs.h b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
new file mode 100644
index 00000000..d7d856c2
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
@@ -0,0 +1,612 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_IOB_DEFS_H__
+#define __CVMX_IOB_DEFS_H__
+
+#define CVMX_IOB_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011800F00007F8ull))
+#define CVMX_IOB_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011800F0000050ull))
+#define CVMX_IOB_DWB_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000028ull))
+#define CVMX_IOB_FAU_TIMEOUT (CVMX_ADD_IO_SEG(0x00011800F0000000ull))
+#define CVMX_IOB_I2C_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000010ull))
+#define CVMX_IOB_INB_CONTROL_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000078ull))
+#define CVMX_IOB_INB_CONTROL_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F0000088ull))
+#define CVMX_IOB_INB_DATA_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000070ull))
+#define CVMX_IOB_INB_DATA_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F0000080ull))
+#define CVMX_IOB_INT_ENB (CVMX_ADD_IO_SEG(0x00011800F0000060ull))
+#define CVMX_IOB_INT_SUM (CVMX_ADD_IO_SEG(0x00011800F0000058ull))
+#define CVMX_IOB_N2C_L2C_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000020ull))
+#define CVMX_IOB_N2C_RSP_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000008ull))
+#define CVMX_IOB_OUTB_COM_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000040ull))
+#define CVMX_IOB_OUTB_CONTROL_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000098ull))
+#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F00000A8ull))
+#define CVMX_IOB_OUTB_DATA_MATCH (CVMX_ADD_IO_SEG(0x00011800F0000090ull))
+#define CVMX_IOB_OUTB_DATA_MATCH_ENB (CVMX_ADD_IO_SEG(0x00011800F00000A0ull))
+#define CVMX_IOB_OUTB_FPA_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000048ull))
+#define CVMX_IOB_OUTB_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000038ull))
+#define CVMX_IOB_P2C_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000018ull))
+#define CVMX_IOB_PKT_ERR (CVMX_ADD_IO_SEG(0x00011800F0000068ull))
+#define CVMX_IOB_TO_CMB_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00000B0ull))
+
+union cvmx_iob_bist_status {
+ uint64_t u64;
+ struct cvmx_iob_bist_status_s {
+ uint64_t reserved_23_63:41;
+ uint64_t xmdfif:1;
+ uint64_t xmcfif:1;
+ uint64_t iorfif:1;
+ uint64_t rsdfif:1;
+ uint64_t iocfif:1;
+ uint64_t icnrcb:1;
+ uint64_t icr0:1;
+ uint64_t icr1:1;
+ uint64_t icnr1:1;
+ uint64_t icnr0:1;
+ uint64_t ibdr0:1;
+ uint64_t ibdr1:1;
+ uint64_t ibr0:1;
+ uint64_t ibr1:1;
+ uint64_t icnrt:1;
+ uint64_t ibrq0:1;
+ uint64_t ibrq1:1;
+ uint64_t icrn0:1;
+ uint64_t icrn1:1;
+ uint64_t icrp0:1;
+ uint64_t icrp1:1;
+ uint64_t ibd:1;
+ uint64_t icd:1;
+ } s;
+ struct cvmx_iob_bist_status_cn30xx {
+ uint64_t reserved_18_63:46;
+ uint64_t icnrcb:1;
+ uint64_t icr0:1;
+ uint64_t icr1:1;
+ uint64_t icnr1:1;
+ uint64_t icnr0:1;
+ uint64_t ibdr0:1;
+ uint64_t ibdr1:1;
+ uint64_t ibr0:1;
+ uint64_t ibr1:1;
+ uint64_t icnrt:1;
+ uint64_t ibrq0:1;
+ uint64_t ibrq1:1;
+ uint64_t icrn0:1;
+ uint64_t icrn1:1;
+ uint64_t icrp0:1;
+ uint64_t icrp1:1;
+ uint64_t ibd:1;
+ uint64_t icd:1;
+ } cn30xx;
+ struct cvmx_iob_bist_status_cn30xx cn31xx;
+ struct cvmx_iob_bist_status_cn30xx cn38xx;
+ struct cvmx_iob_bist_status_cn30xx cn38xxp2;
+ struct cvmx_iob_bist_status_cn30xx cn50xx;
+ struct cvmx_iob_bist_status_cn30xx cn52xx;
+ struct cvmx_iob_bist_status_cn30xx cn52xxp1;
+ struct cvmx_iob_bist_status_cn30xx cn56xx;
+ struct cvmx_iob_bist_status_cn30xx cn56xxp1;
+ struct cvmx_iob_bist_status_cn30xx cn58xx;
+ struct cvmx_iob_bist_status_cn30xx cn58xxp1;
+ struct cvmx_iob_bist_status_s cn63xx;
+ struct cvmx_iob_bist_status_s cn63xxp1;
+};
+
+union cvmx_iob_ctl_status {
+ uint64_t u64;
+ struct cvmx_iob_ctl_status_s {
+ uint64_t reserved_10_63:54;
+ uint64_t xmc_per:4;
+ uint64_t rr_mode:1;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+ } s;
+ struct cvmx_iob_ctl_status_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+ } cn30xx;
+ struct cvmx_iob_ctl_status_cn30xx cn31xx;
+ struct cvmx_iob_ctl_status_cn30xx cn38xx;
+ struct cvmx_iob_ctl_status_cn30xx cn38xxp2;
+ struct cvmx_iob_ctl_status_cn30xx cn50xx;
+ struct cvmx_iob_ctl_status_cn52xx {
+ uint64_t reserved_6_63:58;
+ uint64_t rr_mode:1;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+ } cn52xx;
+ struct cvmx_iob_ctl_status_cn30xx cn52xxp1;
+ struct cvmx_iob_ctl_status_cn30xx cn56xx;
+ struct cvmx_iob_ctl_status_cn30xx cn56xxp1;
+ struct cvmx_iob_ctl_status_cn30xx cn58xx;
+ struct cvmx_iob_ctl_status_cn30xx cn58xxp1;
+ struct cvmx_iob_ctl_status_s cn63xx;
+ struct cvmx_iob_ctl_status_s cn63xxp1;
+};
+
+union cvmx_iob_dwb_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_dwb_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_dwb_pri_cnt_s cn38xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_dwb_pri_cnt_s cn52xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_dwb_pri_cnt_s cn56xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_dwb_pri_cnt_s cn58xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_dwb_pri_cnt_s cn63xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn63xxp1;
+};
+
+union cvmx_iob_fau_timeout {
+ uint64_t u64;
+ struct cvmx_iob_fau_timeout_s {
+ uint64_t reserved_13_63:51;
+ uint64_t tout_enb:1;
+ uint64_t tout_val:12;
+ } s;
+ struct cvmx_iob_fau_timeout_s cn30xx;
+ struct cvmx_iob_fau_timeout_s cn31xx;
+ struct cvmx_iob_fau_timeout_s cn38xx;
+ struct cvmx_iob_fau_timeout_s cn38xxp2;
+ struct cvmx_iob_fau_timeout_s cn50xx;
+ struct cvmx_iob_fau_timeout_s cn52xx;
+ struct cvmx_iob_fau_timeout_s cn52xxp1;
+ struct cvmx_iob_fau_timeout_s cn56xx;
+ struct cvmx_iob_fau_timeout_s cn56xxp1;
+ struct cvmx_iob_fau_timeout_s cn58xx;
+ struct cvmx_iob_fau_timeout_s cn58xxp1;
+ struct cvmx_iob_fau_timeout_s cn63xx;
+ struct cvmx_iob_fau_timeout_s cn63xxp1;
+};
+
+union cvmx_iob_i2c_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_i2c_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_i2c_pri_cnt_s cn38xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_i2c_pri_cnt_s cn52xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_i2c_pri_cnt_s cn56xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_i2c_pri_cnt_s cn58xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_i2c_pri_cnt_s cn63xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn63xxp1;
+};
+
+union cvmx_iob_inb_control_match {
+ uint64_t u64;
+ struct cvmx_iob_inb_control_match_s {
+ uint64_t reserved_29_63:35;
+ uint64_t mask:8;
+ uint64_t opc:4;
+ uint64_t dst:9;
+ uint64_t src:8;
+ } s;
+ struct cvmx_iob_inb_control_match_s cn30xx;
+ struct cvmx_iob_inb_control_match_s cn31xx;
+ struct cvmx_iob_inb_control_match_s cn38xx;
+ struct cvmx_iob_inb_control_match_s cn38xxp2;
+ struct cvmx_iob_inb_control_match_s cn50xx;
+ struct cvmx_iob_inb_control_match_s cn52xx;
+ struct cvmx_iob_inb_control_match_s cn52xxp1;
+ struct cvmx_iob_inb_control_match_s cn56xx;
+ struct cvmx_iob_inb_control_match_s cn56xxp1;
+ struct cvmx_iob_inb_control_match_s cn58xx;
+ struct cvmx_iob_inb_control_match_s cn58xxp1;
+ struct cvmx_iob_inb_control_match_s cn63xx;
+ struct cvmx_iob_inb_control_match_s cn63xxp1;
+};
+
+union cvmx_iob_inb_control_match_enb {
+ uint64_t u64;
+ struct cvmx_iob_inb_control_match_enb_s {
+ uint64_t reserved_29_63:35;
+ uint64_t mask:8;
+ uint64_t opc:4;
+ uint64_t dst:9;
+ uint64_t src:8;
+ } s;
+ struct cvmx_iob_inb_control_match_enb_s cn30xx;
+ struct cvmx_iob_inb_control_match_enb_s cn31xx;
+ struct cvmx_iob_inb_control_match_enb_s cn38xx;
+ struct cvmx_iob_inb_control_match_enb_s cn38xxp2;
+ struct cvmx_iob_inb_control_match_enb_s cn50xx;
+ struct cvmx_iob_inb_control_match_enb_s cn52xx;
+ struct cvmx_iob_inb_control_match_enb_s cn52xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cn56xx;
+ struct cvmx_iob_inb_control_match_enb_s cn56xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cn58xx;
+ struct cvmx_iob_inb_control_match_enb_s cn58xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cn63xx;
+ struct cvmx_iob_inb_control_match_enb_s cn63xxp1;
+};
+
+union cvmx_iob_inb_data_match {
+ uint64_t u64;
+ struct cvmx_iob_inb_data_match_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_iob_inb_data_match_s cn30xx;
+ struct cvmx_iob_inb_data_match_s cn31xx;
+ struct cvmx_iob_inb_data_match_s cn38xx;
+ struct cvmx_iob_inb_data_match_s cn38xxp2;
+ struct cvmx_iob_inb_data_match_s cn50xx;
+ struct cvmx_iob_inb_data_match_s cn52xx;
+ struct cvmx_iob_inb_data_match_s cn52xxp1;
+ struct cvmx_iob_inb_data_match_s cn56xx;
+ struct cvmx_iob_inb_data_match_s cn56xxp1;
+ struct cvmx_iob_inb_data_match_s cn58xx;
+ struct cvmx_iob_inb_data_match_s cn58xxp1;
+ struct cvmx_iob_inb_data_match_s cn63xx;
+ struct cvmx_iob_inb_data_match_s cn63xxp1;
+};
+
+union cvmx_iob_inb_data_match_enb {
+ uint64_t u64;
+ struct cvmx_iob_inb_data_match_enb_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_iob_inb_data_match_enb_s cn30xx;
+ struct cvmx_iob_inb_data_match_enb_s cn31xx;
+ struct cvmx_iob_inb_data_match_enb_s cn38xx;
+ struct cvmx_iob_inb_data_match_enb_s cn38xxp2;
+ struct cvmx_iob_inb_data_match_enb_s cn50xx;
+ struct cvmx_iob_inb_data_match_enb_s cn52xx;
+ struct cvmx_iob_inb_data_match_enb_s cn52xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cn56xx;
+ struct cvmx_iob_inb_data_match_enb_s cn56xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cn58xx;
+ struct cvmx_iob_inb_data_match_enb_s cn58xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cn63xx;
+ struct cvmx_iob_inb_data_match_enb_s cn63xxp1;
+};
+
+union cvmx_iob_int_enb {
+ uint64_t u64;
+ struct cvmx_iob_int_enb_s {
+ uint64_t reserved_6_63:58;
+ uint64_t p_dat:1;
+ uint64_t np_dat:1;
+ uint64_t p_eop:1;
+ uint64_t p_sop:1;
+ uint64_t np_eop:1;
+ uint64_t np_sop:1;
+ } s;
+ struct cvmx_iob_int_enb_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t p_eop:1;
+ uint64_t p_sop:1;
+ uint64_t np_eop:1;
+ uint64_t np_sop:1;
+ } cn30xx;
+ struct cvmx_iob_int_enb_cn30xx cn31xx;
+ struct cvmx_iob_int_enb_cn30xx cn38xx;
+ struct cvmx_iob_int_enb_cn30xx cn38xxp2;
+ struct cvmx_iob_int_enb_s cn50xx;
+ struct cvmx_iob_int_enb_s cn52xx;
+ struct cvmx_iob_int_enb_s cn52xxp1;
+ struct cvmx_iob_int_enb_s cn56xx;
+ struct cvmx_iob_int_enb_s cn56xxp1;
+ struct cvmx_iob_int_enb_s cn58xx;
+ struct cvmx_iob_int_enb_s cn58xxp1;
+ struct cvmx_iob_int_enb_s cn63xx;
+ struct cvmx_iob_int_enb_s cn63xxp1;
+};
+
+union cvmx_iob_int_sum {
+ uint64_t u64;
+ struct cvmx_iob_int_sum_s {
+ uint64_t reserved_6_63:58;
+ uint64_t p_dat:1;
+ uint64_t np_dat:1;
+ uint64_t p_eop:1;
+ uint64_t p_sop:1;
+ uint64_t np_eop:1;
+ uint64_t np_sop:1;
+ } s;
+ struct cvmx_iob_int_sum_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t p_eop:1;
+ uint64_t p_sop:1;
+ uint64_t np_eop:1;
+ uint64_t np_sop:1;
+ } cn30xx;
+ struct cvmx_iob_int_sum_cn30xx cn31xx;
+ struct cvmx_iob_int_sum_cn30xx cn38xx;
+ struct cvmx_iob_int_sum_cn30xx cn38xxp2;
+ struct cvmx_iob_int_sum_s cn50xx;
+ struct cvmx_iob_int_sum_s cn52xx;
+ struct cvmx_iob_int_sum_s cn52xxp1;
+ struct cvmx_iob_int_sum_s cn56xx;
+ struct cvmx_iob_int_sum_s cn56xxp1;
+ struct cvmx_iob_int_sum_s cn58xx;
+ struct cvmx_iob_int_sum_s cn58xxp1;
+ struct cvmx_iob_int_sum_s cn63xx;
+ struct cvmx_iob_int_sum_s cn63xxp1;
+};
+
+union cvmx_iob_n2c_l2c_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn52xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xxp1;
+};
+
+union cvmx_iob_n2c_rsp_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn52xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xxp1;
+};
+
+union cvmx_iob_outb_com_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_outb_com_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_outb_com_pri_cnt_s cn38xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_outb_com_pri_cnt_s cn52xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cn56xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cn58xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cn63xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn63xxp1;
+};
+
+union cvmx_iob_outb_control_match {
+ uint64_t u64;
+ struct cvmx_iob_outb_control_match_s {
+ uint64_t reserved_26_63:38;
+ uint64_t mask:8;
+ uint64_t eot:1;
+ uint64_t dst:8;
+ uint64_t src:9;
+ } s;
+ struct cvmx_iob_outb_control_match_s cn30xx;
+ struct cvmx_iob_outb_control_match_s cn31xx;
+ struct cvmx_iob_outb_control_match_s cn38xx;
+ struct cvmx_iob_outb_control_match_s cn38xxp2;
+ struct cvmx_iob_outb_control_match_s cn50xx;
+ struct cvmx_iob_outb_control_match_s cn52xx;
+ struct cvmx_iob_outb_control_match_s cn52xxp1;
+ struct cvmx_iob_outb_control_match_s cn56xx;
+ struct cvmx_iob_outb_control_match_s cn56xxp1;
+ struct cvmx_iob_outb_control_match_s cn58xx;
+ struct cvmx_iob_outb_control_match_s cn58xxp1;
+ struct cvmx_iob_outb_control_match_s cn63xx;
+ struct cvmx_iob_outb_control_match_s cn63xxp1;
+};
+
+union cvmx_iob_outb_control_match_enb {
+ uint64_t u64;
+ struct cvmx_iob_outb_control_match_enb_s {
+ uint64_t reserved_26_63:38;
+ uint64_t mask:8;
+ uint64_t eot:1;
+ uint64_t dst:8;
+ uint64_t src:9;
+ } s;
+ struct cvmx_iob_outb_control_match_enb_s cn30xx;
+ struct cvmx_iob_outb_control_match_enb_s cn31xx;
+ struct cvmx_iob_outb_control_match_enb_s cn38xx;
+ struct cvmx_iob_outb_control_match_enb_s cn38xxp2;
+ struct cvmx_iob_outb_control_match_enb_s cn50xx;
+ struct cvmx_iob_outb_control_match_enb_s cn52xx;
+ struct cvmx_iob_outb_control_match_enb_s cn52xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cn56xx;
+ struct cvmx_iob_outb_control_match_enb_s cn56xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cn58xx;
+ struct cvmx_iob_outb_control_match_enb_s cn58xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cn63xx;
+ struct cvmx_iob_outb_control_match_enb_s cn63xxp1;
+};
+
+union cvmx_iob_outb_data_match {
+ uint64_t u64;
+ struct cvmx_iob_outb_data_match_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_iob_outb_data_match_s cn30xx;
+ struct cvmx_iob_outb_data_match_s cn31xx;
+ struct cvmx_iob_outb_data_match_s cn38xx;
+ struct cvmx_iob_outb_data_match_s cn38xxp2;
+ struct cvmx_iob_outb_data_match_s cn50xx;
+ struct cvmx_iob_outb_data_match_s cn52xx;
+ struct cvmx_iob_outb_data_match_s cn52xxp1;
+ struct cvmx_iob_outb_data_match_s cn56xx;
+ struct cvmx_iob_outb_data_match_s cn56xxp1;
+ struct cvmx_iob_outb_data_match_s cn58xx;
+ struct cvmx_iob_outb_data_match_s cn58xxp1;
+ struct cvmx_iob_outb_data_match_s cn63xx;
+ struct cvmx_iob_outb_data_match_s cn63xxp1;
+};
+
+union cvmx_iob_outb_data_match_enb {
+ uint64_t u64;
+ struct cvmx_iob_outb_data_match_enb_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_iob_outb_data_match_enb_s cn30xx;
+ struct cvmx_iob_outb_data_match_enb_s cn31xx;
+ struct cvmx_iob_outb_data_match_enb_s cn38xx;
+ struct cvmx_iob_outb_data_match_enb_s cn38xxp2;
+ struct cvmx_iob_outb_data_match_enb_s cn50xx;
+ struct cvmx_iob_outb_data_match_enb_s cn52xx;
+ struct cvmx_iob_outb_data_match_enb_s cn52xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cn56xx;
+ struct cvmx_iob_outb_data_match_enb_s cn56xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cn58xx;
+ struct cvmx_iob_outb_data_match_enb_s cn58xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cn63xx;
+ struct cvmx_iob_outb_data_match_enb_s cn63xxp1;
+};
+
+union cvmx_iob_outb_fpa_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_outb_fpa_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn38xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn52xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn56xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn58xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn63xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn63xxp1;
+};
+
+union cvmx_iob_outb_req_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_outb_req_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_outb_req_pri_cnt_s cn38xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_outb_req_pri_cnt_s cn52xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cn56xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cn58xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cn63xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn63xxp1;
+};
+
+union cvmx_iob_p2c_req_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_p2c_req_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn38xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn52xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn56xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn58xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn58xxp1;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn63xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn63xxp1;
+};
+
+union cvmx_iob_pkt_err {
+ uint64_t u64;
+ struct cvmx_iob_pkt_err_s {
+ uint64_t reserved_12_63:52;
+ uint64_t vport:6;
+ uint64_t port:6;
+ } s;
+ struct cvmx_iob_pkt_err_cn30xx {
+ uint64_t reserved_6_63:58;
+ uint64_t port:6;
+ } cn30xx;
+ struct cvmx_iob_pkt_err_cn30xx cn31xx;
+ struct cvmx_iob_pkt_err_cn30xx cn38xx;
+ struct cvmx_iob_pkt_err_cn30xx cn38xxp2;
+ struct cvmx_iob_pkt_err_cn30xx cn50xx;
+ struct cvmx_iob_pkt_err_cn30xx cn52xx;
+ struct cvmx_iob_pkt_err_cn30xx cn52xxp1;
+ struct cvmx_iob_pkt_err_cn30xx cn56xx;
+ struct cvmx_iob_pkt_err_cn30xx cn56xxp1;
+ struct cvmx_iob_pkt_err_cn30xx cn58xx;
+ struct cvmx_iob_pkt_err_cn30xx cn58xxp1;
+ struct cvmx_iob_pkt_err_s cn63xx;
+ struct cvmx_iob_pkt_err_s cn63xxp1;
+};
+
+union cvmx_iob_to_cmb_credits {
+ uint64_t u64;
+ struct cvmx_iob_to_cmb_credits_s {
+ uint64_t reserved_9_63:55;
+ uint64_t pko_rd:3;
+ uint64_t ncb_rd:3;
+ uint64_t ncb_wr:3;
+ } s;
+ struct cvmx_iob_to_cmb_credits_s cn52xx;
+ struct cvmx_iob_to_cmb_credits_s cn63xx;
+ struct cvmx_iob_to_cmb_credits_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-ipd-defs.h b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
new file mode 100644
index 00000000..e0a5bfe8
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
@@ -0,0 +1,959 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_IPD_DEFS_H__
+#define __CVMX_IPD_DEFS_H__
+
+#define CVMX_IPD_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000000ull))
+#define CVMX_IPD_1st_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000150ull))
+#define CVMX_IPD_2nd_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000158ull))
+#define CVMX_IPD_BIST_STATUS (CVMX_ADD_IO_SEG(0x00014F00000007F8ull))
+#define CVMX_IPD_BP_PRT_RED_END (CVMX_ADD_IO_SEG(0x00014F0000000328ull))
+#define CVMX_IPD_CLK_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000338ull))
+#define CVMX_IPD_CTL_STATUS (CVMX_ADD_IO_SEG(0x00014F0000000018ull))
+#define CVMX_IPD_INT_ENB (CVMX_ADD_IO_SEG(0x00014F0000000160ull))
+#define CVMX_IPD_INT_SUM (CVMX_ADD_IO_SEG(0x00014F0000000168ull))
+#define CVMX_IPD_NOT_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000008ull))
+#define CVMX_IPD_PACKET_MBUFF_SIZE (CVMX_ADD_IO_SEG(0x00014F0000000010ull))
+#define CVMX_IPD_PKT_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000358ull))
+#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000028ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) (CVMX_ADD_IO_SEG(0x00014F0000000368ull) + ((offset) & 63) * 8 - 8*36)
+#define CVMX_IPD_PORTX_BP_PAGE_CNT3(offset) (CVMX_ADD_IO_SEG(0x00014F00000003D0ull) + ((offset) & 63) * 8 - 8*40)
+#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000388ull) + ((offset) & 63) * 8 - 8*36)
+#define CVMX_IPD_PORT_BP_COUNTERS3_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000003B0ull) + ((offset) & 63) * 8 - 8*40)
+#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000001B8ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_PORT_QOS_INTX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000808ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000848ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_PORT_QOS_X_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000888ull) + ((offset) & 511) * 8)
+#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000348ull))
+#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000350ull))
+#define CVMX_IPD_PTR_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000320ull))
+#define CVMX_IPD_PWP_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000340ull))
+#define CVMX_IPD_QOS0_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(0)
+#define CVMX_IPD_QOS1_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(1)
+#define CVMX_IPD_QOS2_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(2)
+#define CVMX_IPD_QOS3_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(3)
+#define CVMX_IPD_QOS4_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(4)
+#define CVMX_IPD_QOS5_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(5)
+#define CVMX_IPD_QOS6_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(6)
+#define CVMX_IPD_QOS7_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(7)
+#define CVMX_IPD_QOSX_RED_MARKS(offset) (CVMX_ADD_IO_SEG(0x00014F0000000178ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_QUE0_FREE_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000330ull))
+#define CVMX_IPD_RED_PORT_ENABLE (CVMX_ADD_IO_SEG(0x00014F00000002D8ull))
+#define CVMX_IPD_RED_PORT_ENABLE2 (CVMX_ADD_IO_SEG(0x00014F00000003A8ull))
+#define CVMX_IPD_RED_QUE0_PARAM CVMX_IPD_RED_QUEX_PARAM(0)
+#define CVMX_IPD_RED_QUE1_PARAM CVMX_IPD_RED_QUEX_PARAM(1)
+#define CVMX_IPD_RED_QUE2_PARAM CVMX_IPD_RED_QUEX_PARAM(2)
+#define CVMX_IPD_RED_QUE3_PARAM CVMX_IPD_RED_QUEX_PARAM(3)
+#define CVMX_IPD_RED_QUE4_PARAM CVMX_IPD_RED_QUEX_PARAM(4)
+#define CVMX_IPD_RED_QUE5_PARAM CVMX_IPD_RED_QUEX_PARAM(5)
+#define CVMX_IPD_RED_QUE6_PARAM CVMX_IPD_RED_QUEX_PARAM(6)
+#define CVMX_IPD_RED_QUE7_PARAM CVMX_IPD_RED_QUEX_PARAM(7)
+#define CVMX_IPD_RED_QUEX_PARAM(offset) (CVMX_ADD_IO_SEG(0x00014F00000002E0ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000148ull))
+#define CVMX_IPD_SUB_PORT_FCS (CVMX_ADD_IO_SEG(0x00014F0000000170ull))
+#define CVMX_IPD_SUB_PORT_QOS_CNT (CVMX_ADD_IO_SEG(0x00014F0000000800ull))
+#define CVMX_IPD_WQE_FPA_QUEUE (CVMX_ADD_IO_SEG(0x00014F0000000020ull))
+#define CVMX_IPD_WQE_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000360ull))
+
+union cvmx_ipd_1st_mbuff_skip {
+ uint64_t u64;
+ struct cvmx_ipd_1st_mbuff_skip_s {
+ uint64_t reserved_6_63:58;
+ uint64_t skip_sz:6;
+ } s;
+ struct cvmx_ipd_1st_mbuff_skip_s cn30xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn31xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn38xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn38xxp2;
+ struct cvmx_ipd_1st_mbuff_skip_s cn50xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn52xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn52xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cn56xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn56xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cn58xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn58xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cn63xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn63xxp1;
+};
+
+union cvmx_ipd_1st_next_ptr_back {
+ uint64_t u64;
+ struct cvmx_ipd_1st_next_ptr_back_s {
+ uint64_t reserved_4_63:60;
+ uint64_t back:4;
+ } s;
+ struct cvmx_ipd_1st_next_ptr_back_s cn30xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn31xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn38xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn38xxp2;
+ struct cvmx_ipd_1st_next_ptr_back_s cn50xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn52xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn52xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cn56xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn56xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cn58xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn58xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cn63xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn63xxp1;
+};
+
+union cvmx_ipd_2nd_next_ptr_back {
+ uint64_t u64;
+ struct cvmx_ipd_2nd_next_ptr_back_s {
+ uint64_t reserved_4_63:60;
+ uint64_t back:4;
+ } s;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn30xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn31xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn38xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn38xxp2;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn50xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn52xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn52xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn56xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn56xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn58xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn58xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn63xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn63xxp1;
+};
+
+union cvmx_ipd_bist_status {
+ uint64_t u64;
+ struct cvmx_ipd_bist_status_s {
+ uint64_t reserved_18_63:46;
+ uint64_t csr_mem:1;
+ uint64_t csr_ncmd:1;
+ uint64_t pwq_wqed:1;
+ uint64_t pwq_wp1:1;
+ uint64_t pwq_pow:1;
+ uint64_t ipq_pbe1:1;
+ uint64_t ipq_pbe0:1;
+ uint64_t pbm3:1;
+ uint64_t pbm2:1;
+ uint64_t pbm1:1;
+ uint64_t pbm0:1;
+ uint64_t pbm_word:1;
+ uint64_t pwq1:1;
+ uint64_t pwq0:1;
+ uint64_t prc_off:1;
+ uint64_t ipd_old:1;
+ uint64_t ipd_new:1;
+ uint64_t pwp:1;
+ } s;
+ struct cvmx_ipd_bist_status_cn30xx {
+ uint64_t reserved_16_63:48;
+ uint64_t pwq_wqed:1;
+ uint64_t pwq_wp1:1;
+ uint64_t pwq_pow:1;
+ uint64_t ipq_pbe1:1;
+ uint64_t ipq_pbe0:1;
+ uint64_t pbm3:1;
+ uint64_t pbm2:1;
+ uint64_t pbm1:1;
+ uint64_t pbm0:1;
+ uint64_t pbm_word:1;
+ uint64_t pwq1:1;
+ uint64_t pwq0:1;
+ uint64_t prc_off:1;
+ uint64_t ipd_old:1;
+ uint64_t ipd_new:1;
+ uint64_t pwp:1;
+ } cn30xx;
+ struct cvmx_ipd_bist_status_cn30xx cn31xx;
+ struct cvmx_ipd_bist_status_cn30xx cn38xx;
+ struct cvmx_ipd_bist_status_cn30xx cn38xxp2;
+ struct cvmx_ipd_bist_status_cn30xx cn50xx;
+ struct cvmx_ipd_bist_status_s cn52xx;
+ struct cvmx_ipd_bist_status_s cn52xxp1;
+ struct cvmx_ipd_bist_status_s cn56xx;
+ struct cvmx_ipd_bist_status_s cn56xxp1;
+ struct cvmx_ipd_bist_status_cn30xx cn58xx;
+ struct cvmx_ipd_bist_status_cn30xx cn58xxp1;
+ struct cvmx_ipd_bist_status_s cn63xx;
+ struct cvmx_ipd_bist_status_s cn63xxp1;
+};
+
+union cvmx_ipd_bp_prt_red_end {
+ uint64_t u64;
+ struct cvmx_ipd_bp_prt_red_end_s {
+ uint64_t reserved_44_63:20;
+ uint64_t prt_enb:44;
+ } s;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx {
+ uint64_t reserved_36_63:28;
+ uint64_t prt_enb:36;
+ } cn30xx;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn31xx;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xx;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xxp2;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn50xx;
+ struct cvmx_ipd_bp_prt_red_end_cn52xx {
+ uint64_t reserved_40_63:24;
+ uint64_t prt_enb:40;
+ } cn52xx;
+ struct cvmx_ipd_bp_prt_red_end_cn52xx cn52xxp1;
+ struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xx;
+ struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xxp1;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xx;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xxp1;
+ struct cvmx_ipd_bp_prt_red_end_s cn63xx;
+ struct cvmx_ipd_bp_prt_red_end_s cn63xxp1;
+};
+
+union cvmx_ipd_clk_count {
+ uint64_t u64;
+ struct cvmx_ipd_clk_count_s {
+ uint64_t clk_cnt:64;
+ } s;
+ struct cvmx_ipd_clk_count_s cn30xx;
+ struct cvmx_ipd_clk_count_s cn31xx;
+ struct cvmx_ipd_clk_count_s cn38xx;
+ struct cvmx_ipd_clk_count_s cn38xxp2;
+ struct cvmx_ipd_clk_count_s cn50xx;
+ struct cvmx_ipd_clk_count_s cn52xx;
+ struct cvmx_ipd_clk_count_s cn52xxp1;
+ struct cvmx_ipd_clk_count_s cn56xx;
+ struct cvmx_ipd_clk_count_s cn56xxp1;
+ struct cvmx_ipd_clk_count_s cn58xx;
+ struct cvmx_ipd_clk_count_s cn58xxp1;
+ struct cvmx_ipd_clk_count_s cn63xx;
+ struct cvmx_ipd_clk_count_s cn63xxp1;
+};
+
+union cvmx_ipd_ctl_status {
+ uint64_t u64;
+ struct cvmx_ipd_ctl_status_s {
+ uint64_t reserved_18_63:46;
+ uint64_t use_sop:1;
+ uint64_t rst_done:1;
+ uint64_t clken:1;
+ uint64_t no_wptr:1;
+ uint64_t pq_apkt:1;
+ uint64_t pq_nabuf:1;
+ uint64_t ipd_full:1;
+ uint64_t pkt_off:1;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } s;
+ struct cvmx_ipd_ctl_status_cn30xx {
+ uint64_t reserved_10_63:54;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn30xx;
+ struct cvmx_ipd_ctl_status_cn30xx cn31xx;
+ struct cvmx_ipd_ctl_status_cn30xx cn38xx;
+ struct cvmx_ipd_ctl_status_cn38xxp2 {
+ uint64_t reserved_9_63:55;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn38xxp2;
+ struct cvmx_ipd_ctl_status_cn50xx {
+ uint64_t reserved_15_63:49;
+ uint64_t no_wptr:1;
+ uint64_t pq_apkt:1;
+ uint64_t pq_nabuf:1;
+ uint64_t ipd_full:1;
+ uint64_t pkt_off:1;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn50xx;
+ struct cvmx_ipd_ctl_status_cn50xx cn52xx;
+ struct cvmx_ipd_ctl_status_cn50xx cn52xxp1;
+ struct cvmx_ipd_ctl_status_cn50xx cn56xx;
+ struct cvmx_ipd_ctl_status_cn50xx cn56xxp1;
+ struct cvmx_ipd_ctl_status_cn58xx {
+ uint64_t reserved_12_63:52;
+ uint64_t ipd_full:1;
+ uint64_t pkt_off:1;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn58xx;
+ struct cvmx_ipd_ctl_status_cn58xx cn58xxp1;
+ struct cvmx_ipd_ctl_status_s cn63xx;
+ struct cvmx_ipd_ctl_status_cn63xxp1 {
+ uint64_t reserved_16_63:48;
+ uint64_t clken:1;
+ uint64_t no_wptr:1;
+ uint64_t pq_apkt:1;
+ uint64_t pq_nabuf:1;
+ uint64_t ipd_full:1;
+ uint64_t pkt_off:1;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn63xxp1;
+};
+
+union cvmx_ipd_int_enb {
+ uint64_t u64;
+ struct cvmx_ipd_int_enb_s {
+ uint64_t reserved_12_63:52;
+ uint64_t pq_sub:1;
+ uint64_t pq_add:1;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } s;
+ struct cvmx_ipd_int_enb_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } cn30xx;
+ struct cvmx_ipd_int_enb_cn30xx cn31xx;
+ struct cvmx_ipd_int_enb_cn38xx {
+ uint64_t reserved_10_63:54;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } cn38xx;
+ struct cvmx_ipd_int_enb_cn30xx cn38xxp2;
+ struct cvmx_ipd_int_enb_cn38xx cn50xx;
+ struct cvmx_ipd_int_enb_s cn52xx;
+ struct cvmx_ipd_int_enb_s cn52xxp1;
+ struct cvmx_ipd_int_enb_s cn56xx;
+ struct cvmx_ipd_int_enb_s cn56xxp1;
+ struct cvmx_ipd_int_enb_cn38xx cn58xx;
+ struct cvmx_ipd_int_enb_cn38xx cn58xxp1;
+ struct cvmx_ipd_int_enb_s cn63xx;
+ struct cvmx_ipd_int_enb_s cn63xxp1;
+};
+
+union cvmx_ipd_int_sum {
+ uint64_t u64;
+ struct cvmx_ipd_int_sum_s {
+ uint64_t reserved_12_63:52;
+ uint64_t pq_sub:1;
+ uint64_t pq_add:1;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } s;
+ struct cvmx_ipd_int_sum_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } cn30xx;
+ struct cvmx_ipd_int_sum_cn30xx cn31xx;
+ struct cvmx_ipd_int_sum_cn38xx {
+ uint64_t reserved_10_63:54;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } cn38xx;
+ struct cvmx_ipd_int_sum_cn30xx cn38xxp2;
+ struct cvmx_ipd_int_sum_cn38xx cn50xx;
+ struct cvmx_ipd_int_sum_s cn52xx;
+ struct cvmx_ipd_int_sum_s cn52xxp1;
+ struct cvmx_ipd_int_sum_s cn56xx;
+ struct cvmx_ipd_int_sum_s cn56xxp1;
+ struct cvmx_ipd_int_sum_cn38xx cn58xx;
+ struct cvmx_ipd_int_sum_cn38xx cn58xxp1;
+ struct cvmx_ipd_int_sum_s cn63xx;
+ struct cvmx_ipd_int_sum_s cn63xxp1;
+};
+
+union cvmx_ipd_not_1st_mbuff_skip {
+ uint64_t u64;
+ struct cvmx_ipd_not_1st_mbuff_skip_s {
+ uint64_t reserved_6_63:58;
+ uint64_t skip_sz:6;
+ } s;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn30xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn31xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn38xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn38xxp2;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn50xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn52xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn52xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn56xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn56xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn58xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn58xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn63xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn63xxp1;
+};
+
+union cvmx_ipd_packet_mbuff_size {
+ uint64_t u64;
+ struct cvmx_ipd_packet_mbuff_size_s {
+ uint64_t reserved_12_63:52;
+ uint64_t mb_size:12;
+ } s;
+ struct cvmx_ipd_packet_mbuff_size_s cn30xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn31xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn38xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn38xxp2;
+ struct cvmx_ipd_packet_mbuff_size_s cn50xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn52xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn52xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cn56xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn56xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cn58xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn58xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cn63xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn63xxp1;
+};
+
+union cvmx_ipd_pkt_ptr_valid {
+ uint64_t u64;
+ struct cvmx_ipd_pkt_ptr_valid_s {
+ uint64_t reserved_29_63:35;
+ uint64_t ptr:29;
+ } s;
+ struct cvmx_ipd_pkt_ptr_valid_s cn30xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn31xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn38xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn50xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn52xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn52xxp1;
+ struct cvmx_ipd_pkt_ptr_valid_s cn56xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn56xxp1;
+ struct cvmx_ipd_pkt_ptr_valid_s cn58xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn58xxp1;
+ struct cvmx_ipd_pkt_ptr_valid_s cn63xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn63xxp1;
+};
+
+union cvmx_ipd_portx_bp_page_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_portx_bp_page_cnt_s {
+ uint64_t reserved_18_63:46;
+ uint64_t bp_enb:1;
+ uint64_t page_cnt:17;
+ } s;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn30xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn31xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn38xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn38xxp2;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn50xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn52xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn52xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn56xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn56xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn58xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn63xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn63xxp1;
+};
+
+union cvmx_ipd_portx_bp_page_cnt2 {
+ uint64_t u64;
+ struct cvmx_ipd_portx_bp_page_cnt2_s {
+ uint64_t reserved_18_63:46;
+ uint64_t bp_enb:1;
+ uint64_t page_cnt:17;
+ } s;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn52xx;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn52xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn56xx;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn56xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn63xx;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn63xxp1;
+};
+
+union cvmx_ipd_portx_bp_page_cnt3 {
+ uint64_t u64;
+ struct cvmx_ipd_portx_bp_page_cnt3_s {
+ uint64_t reserved_18_63:46;
+ uint64_t bp_enb:1;
+ uint64_t page_cnt:17;
+ } s;
+ struct cvmx_ipd_portx_bp_page_cnt3_s cn63xx;
+ struct cvmx_ipd_portx_bp_page_cnt3_s cn63xxp1;
+};
+
+union cvmx_ipd_port_bp_counters2_pairx {
+ uint64_t u64;
+ struct cvmx_ipd_port_bp_counters2_pairx_s {
+ uint64_t reserved_25_63:39;
+ uint64_t cnt_val:25;
+ } s;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn52xx;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn52xxp1;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn56xx;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn56xxp1;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn63xx;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn63xxp1;
+};
+
+union cvmx_ipd_port_bp_counters3_pairx {
+ uint64_t u64;
+ struct cvmx_ipd_port_bp_counters3_pairx_s {
+ uint64_t reserved_25_63:39;
+ uint64_t cnt_val:25;
+ } s;
+ struct cvmx_ipd_port_bp_counters3_pairx_s cn63xx;
+ struct cvmx_ipd_port_bp_counters3_pairx_s cn63xxp1;
+};
+
+union cvmx_ipd_port_bp_counters_pairx {
+ uint64_t u64;
+ struct cvmx_ipd_port_bp_counters_pairx_s {
+ uint64_t reserved_25_63:39;
+ uint64_t cnt_val:25;
+ } s;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn30xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn31xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn38xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn38xxp2;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn50xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn52xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn52xxp1;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn56xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn56xxp1;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn58xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn58xxp1;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn63xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn63xxp1;
+};
+
+union cvmx_ipd_port_qos_x_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_port_qos_x_cnt_s {
+ uint64_t wmark:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_ipd_port_qos_x_cnt_s cn52xx;
+ struct cvmx_ipd_port_qos_x_cnt_s cn52xxp1;
+ struct cvmx_ipd_port_qos_x_cnt_s cn56xx;
+ struct cvmx_ipd_port_qos_x_cnt_s cn56xxp1;
+ struct cvmx_ipd_port_qos_x_cnt_s cn63xx;
+ struct cvmx_ipd_port_qos_x_cnt_s cn63xxp1;
+};
+
+union cvmx_ipd_port_qos_intx {
+ uint64_t u64;
+ struct cvmx_ipd_port_qos_intx_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_ipd_port_qos_intx_s cn52xx;
+ struct cvmx_ipd_port_qos_intx_s cn52xxp1;
+ struct cvmx_ipd_port_qos_intx_s cn56xx;
+ struct cvmx_ipd_port_qos_intx_s cn56xxp1;
+ struct cvmx_ipd_port_qos_intx_s cn63xx;
+ struct cvmx_ipd_port_qos_intx_s cn63xxp1;
+};
+
+union cvmx_ipd_port_qos_int_enbx {
+ uint64_t u64;
+ struct cvmx_ipd_port_qos_int_enbx_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_ipd_port_qos_int_enbx_s cn52xx;
+ struct cvmx_ipd_port_qos_int_enbx_s cn52xxp1;
+ struct cvmx_ipd_port_qos_int_enbx_s cn56xx;
+ struct cvmx_ipd_port_qos_int_enbx_s cn56xxp1;
+ struct cvmx_ipd_port_qos_int_enbx_s cn63xx;
+ struct cvmx_ipd_port_qos_int_enbx_s cn63xxp1;
+};
+
+union cvmx_ipd_prc_hold_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s {
+ uint64_t reserved_39_63:25;
+ uint64_t max_pkt:3;
+ uint64_t praddr:3;
+ uint64_t ptr:29;
+ uint64_t cena:1;
+ uint64_t raddr:3;
+ } s;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn30xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn31xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn38xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn50xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn52xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn52xxp1;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xxp1;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xxp1;
+};
+
+union cvmx_ipd_prc_port_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s {
+ uint64_t reserved_44_63:20;
+ uint64_t max_pkt:7;
+ uint64_t ptr:29;
+ uint64_t cena:1;
+ uint64_t raddr:7;
+ } s;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn30xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn31xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn38xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn50xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn52xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn52xxp1;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xxp1;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xxp1;
+};
+
+union cvmx_ipd_ptr_count {
+ uint64_t u64;
+ struct cvmx_ipd_ptr_count_s {
+ uint64_t reserved_19_63:45;
+ uint64_t pktv_cnt:1;
+ uint64_t wqev_cnt:1;
+ uint64_t pfif_cnt:3;
+ uint64_t pkt_pcnt:7;
+ uint64_t wqe_pcnt:7;
+ } s;
+ struct cvmx_ipd_ptr_count_s cn30xx;
+ struct cvmx_ipd_ptr_count_s cn31xx;
+ struct cvmx_ipd_ptr_count_s cn38xx;
+ struct cvmx_ipd_ptr_count_s cn38xxp2;
+ struct cvmx_ipd_ptr_count_s cn50xx;
+ struct cvmx_ipd_ptr_count_s cn52xx;
+ struct cvmx_ipd_ptr_count_s cn52xxp1;
+ struct cvmx_ipd_ptr_count_s cn56xx;
+ struct cvmx_ipd_ptr_count_s cn56xxp1;
+ struct cvmx_ipd_ptr_count_s cn58xx;
+ struct cvmx_ipd_ptr_count_s cn58xxp1;
+ struct cvmx_ipd_ptr_count_s cn63xx;
+ struct cvmx_ipd_ptr_count_s cn63xxp1;
+};
+
+union cvmx_ipd_pwp_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s {
+ uint64_t reserved_61_63:3;
+ uint64_t max_cnts:7;
+ uint64_t wraddr:8;
+ uint64_t praddr:8;
+ uint64_t ptr:29;
+ uint64_t cena:1;
+ uint64_t raddr:8;
+ } s;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn30xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn31xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn38xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn50xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn52xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn52xxp1;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xxp1;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xxp1;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xxp1;
+};
+
+union cvmx_ipd_qosx_red_marks {
+ uint64_t u64;
+ struct cvmx_ipd_qosx_red_marks_s {
+ uint64_t drop:32;
+ uint64_t pass:32;
+ } s;
+ struct cvmx_ipd_qosx_red_marks_s cn30xx;
+ struct cvmx_ipd_qosx_red_marks_s cn31xx;
+ struct cvmx_ipd_qosx_red_marks_s cn38xx;
+ struct cvmx_ipd_qosx_red_marks_s cn38xxp2;
+ struct cvmx_ipd_qosx_red_marks_s cn50xx;
+ struct cvmx_ipd_qosx_red_marks_s cn52xx;
+ struct cvmx_ipd_qosx_red_marks_s cn52xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cn56xx;
+ struct cvmx_ipd_qosx_red_marks_s cn56xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cn58xx;
+ struct cvmx_ipd_qosx_red_marks_s cn58xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cn63xx;
+ struct cvmx_ipd_qosx_red_marks_s cn63xxp1;
+};
+
+union cvmx_ipd_que0_free_page_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_que0_free_page_cnt_s {
+ uint64_t reserved_32_63:32;
+ uint64_t q0_pcnt:32;
+ } s;
+ struct cvmx_ipd_que0_free_page_cnt_s cn30xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn31xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn38xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn38xxp2;
+ struct cvmx_ipd_que0_free_page_cnt_s cn50xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn52xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn52xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cn56xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn56xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cn58xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cn63xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn63xxp1;
+};
+
+union cvmx_ipd_red_port_enable {
+ uint64_t u64;
+ struct cvmx_ipd_red_port_enable_s {
+ uint64_t prb_dly:14;
+ uint64_t avg_dly:14;
+ uint64_t prt_enb:36;
+ } s;
+ struct cvmx_ipd_red_port_enable_s cn30xx;
+ struct cvmx_ipd_red_port_enable_s cn31xx;
+ struct cvmx_ipd_red_port_enable_s cn38xx;
+ struct cvmx_ipd_red_port_enable_s cn38xxp2;
+ struct cvmx_ipd_red_port_enable_s cn50xx;
+ struct cvmx_ipd_red_port_enable_s cn52xx;
+ struct cvmx_ipd_red_port_enable_s cn52xxp1;
+ struct cvmx_ipd_red_port_enable_s cn56xx;
+ struct cvmx_ipd_red_port_enable_s cn56xxp1;
+ struct cvmx_ipd_red_port_enable_s cn58xx;
+ struct cvmx_ipd_red_port_enable_s cn58xxp1;
+ struct cvmx_ipd_red_port_enable_s cn63xx;
+ struct cvmx_ipd_red_port_enable_s cn63xxp1;
+};
+
+union cvmx_ipd_red_port_enable2 {
+ uint64_t u64;
+ struct cvmx_ipd_red_port_enable2_s {
+ uint64_t reserved_8_63:56;
+ uint64_t prt_enb:8;
+ } s;
+ struct cvmx_ipd_red_port_enable2_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t prt_enb:4;
+ } cn52xx;
+ struct cvmx_ipd_red_port_enable2_cn52xx cn52xxp1;
+ struct cvmx_ipd_red_port_enable2_cn52xx cn56xx;
+ struct cvmx_ipd_red_port_enable2_cn52xx cn56xxp1;
+ struct cvmx_ipd_red_port_enable2_s cn63xx;
+ struct cvmx_ipd_red_port_enable2_s cn63xxp1;
+};
+
+union cvmx_ipd_red_quex_param {
+ uint64_t u64;
+ struct cvmx_ipd_red_quex_param_s {
+ uint64_t reserved_49_63:15;
+ uint64_t use_pcnt:1;
+ uint64_t new_con:8;
+ uint64_t avg_con:8;
+ uint64_t prb_con:32;
+ } s;
+ struct cvmx_ipd_red_quex_param_s cn30xx;
+ struct cvmx_ipd_red_quex_param_s cn31xx;
+ struct cvmx_ipd_red_quex_param_s cn38xx;
+ struct cvmx_ipd_red_quex_param_s cn38xxp2;
+ struct cvmx_ipd_red_quex_param_s cn50xx;
+ struct cvmx_ipd_red_quex_param_s cn52xx;
+ struct cvmx_ipd_red_quex_param_s cn52xxp1;
+ struct cvmx_ipd_red_quex_param_s cn56xx;
+ struct cvmx_ipd_red_quex_param_s cn56xxp1;
+ struct cvmx_ipd_red_quex_param_s cn58xx;
+ struct cvmx_ipd_red_quex_param_s cn58xxp1;
+ struct cvmx_ipd_red_quex_param_s cn63xx;
+ struct cvmx_ipd_red_quex_param_s cn63xxp1;
+};
+
+union cvmx_ipd_sub_port_bp_page_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s {
+ uint64_t reserved_31_63:33;
+ uint64_t port:6;
+ uint64_t page_cnt:25;
+ } s;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn30xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn31xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn38xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn38xxp2;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn50xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn52xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn52xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xxp1;
+};
+
+union cvmx_ipd_sub_port_fcs {
+ uint64_t u64;
+ struct cvmx_ipd_sub_port_fcs_s {
+ uint64_t reserved_40_63:24;
+ uint64_t port_bit2:4;
+ uint64_t reserved_32_35:4;
+ uint64_t port_bit:32;
+ } s;
+ struct cvmx_ipd_sub_port_fcs_cn30xx {
+ uint64_t reserved_3_63:61;
+ uint64_t port_bit:3;
+ } cn30xx;
+ struct cvmx_ipd_sub_port_fcs_cn30xx cn31xx;
+ struct cvmx_ipd_sub_port_fcs_cn38xx {
+ uint64_t reserved_32_63:32;
+ uint64_t port_bit:32;
+ } cn38xx;
+ struct cvmx_ipd_sub_port_fcs_cn38xx cn38xxp2;
+ struct cvmx_ipd_sub_port_fcs_cn30xx cn50xx;
+ struct cvmx_ipd_sub_port_fcs_s cn52xx;
+ struct cvmx_ipd_sub_port_fcs_s cn52xxp1;
+ struct cvmx_ipd_sub_port_fcs_s cn56xx;
+ struct cvmx_ipd_sub_port_fcs_s cn56xxp1;
+ struct cvmx_ipd_sub_port_fcs_cn38xx cn58xx;
+ struct cvmx_ipd_sub_port_fcs_cn38xx cn58xxp1;
+ struct cvmx_ipd_sub_port_fcs_s cn63xx;
+ struct cvmx_ipd_sub_port_fcs_s cn63xxp1;
+};
+
+union cvmx_ipd_sub_port_qos_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_sub_port_qos_cnt_s {
+ uint64_t reserved_41_63:23;
+ uint64_t port_qos:9;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn52xx;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn52xxp1;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn56xx;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn56xxp1;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn63xx;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn63xxp1;
+};
+
+union cvmx_ipd_wqe_fpa_queue {
+ uint64_t u64;
+ struct cvmx_ipd_wqe_fpa_queue_s {
+ uint64_t reserved_3_63:61;
+ uint64_t wqe_pool:3;
+ } s;
+ struct cvmx_ipd_wqe_fpa_queue_s cn30xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn31xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn38xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn38xxp2;
+ struct cvmx_ipd_wqe_fpa_queue_s cn50xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn52xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn52xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cn56xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn56xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cn58xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn58xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cn63xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn63xxp1;
+};
+
+union cvmx_ipd_wqe_ptr_valid {
+ uint64_t u64;
+ struct cvmx_ipd_wqe_ptr_valid_s {
+ uint64_t reserved_29_63:35;
+ uint64_t ptr:29;
+ } s;
+ struct cvmx_ipd_wqe_ptr_valid_s cn30xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn31xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn38xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn50xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn52xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn52xxp1;
+ struct cvmx_ipd_wqe_ptr_valid_s cn56xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn56xxp1;
+ struct cvmx_ipd_wqe_ptr_valid_s cn58xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn58xxp1;
+ struct cvmx_ipd_wqe_ptr_valid_s cn63xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
new file mode 100644
index 00000000..7a50a0be
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
@@ -0,0 +1,1569 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_L2C_DEFS_H__
+#define __CVMX_L2C_DEFS_H__
+
+#define CVMX_L2C_BIG_CTL (CVMX_ADD_IO_SEG(0x0001180080800030ull))
+#define CVMX_L2C_BST (CVMX_ADD_IO_SEG(0x00011800808007F8ull))
+#define CVMX_L2C_BST0 (CVMX_ADD_IO_SEG(0x00011800800007F8ull))
+#define CVMX_L2C_BST1 (CVMX_ADD_IO_SEG(0x00011800800007F0ull))
+#define CVMX_L2C_BST2 (CVMX_ADD_IO_SEG(0x00011800800007E8ull))
+#define CVMX_L2C_BST_MEMX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F8ull))
+#define CVMX_L2C_BST_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F0ull))
+#define CVMX_L2C_BST_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F8ull))
+#define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull))
+#define CVMX_L2C_COP0_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080940000ull) + ((offset) & 16383) * 8)
+#define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull))
+#define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull))
+#define CVMX_L2C_DUT (CVMX_ADD_IO_SEG(0x0001180080000050ull))
+#define CVMX_L2C_DUT_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080E00000ull) + ((offset) & 2047) * 8)
+#define CVMX_L2C_ERR_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E0ull))
+#define CVMX_L2C_ERR_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E8ull))
+#define CVMX_L2C_ERR_VBFX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F0ull))
+#define CVMX_L2C_ERR_XMC (CVMX_ADD_IO_SEG(0x00011800808007D8ull))
+#define CVMX_L2C_GRPWRR0 (CVMX_ADD_IO_SEG(0x00011800800000C8ull))
+#define CVMX_L2C_GRPWRR1 (CVMX_ADD_IO_SEG(0x00011800800000D0ull))
+#define CVMX_L2C_INT_EN (CVMX_ADD_IO_SEG(0x0001180080000100ull))
+#define CVMX_L2C_INT_ENA (CVMX_ADD_IO_SEG(0x0001180080800020ull))
+#define CVMX_L2C_INT_REG (CVMX_ADD_IO_SEG(0x0001180080800018ull))
+#define CVMX_L2C_INT_STAT (CVMX_ADD_IO_SEG(0x00011800800000F8ull))
+#define CVMX_L2C_IOCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800420ull))
+#define CVMX_L2C_IORX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800428ull))
+#define CVMX_L2C_LCKBASE (CVMX_ADD_IO_SEG(0x0001180080000058ull))
+#define CVMX_L2C_LCKOFF (CVMX_ADD_IO_SEG(0x0001180080000060ull))
+#define CVMX_L2C_LFB0 (CVMX_ADD_IO_SEG(0x0001180080000038ull))
+#define CVMX_L2C_LFB1 (CVMX_ADD_IO_SEG(0x0001180080000040ull))
+#define CVMX_L2C_LFB2 (CVMX_ADD_IO_SEG(0x0001180080000048ull))
+#define CVMX_L2C_LFB3 (CVMX_ADD_IO_SEG(0x00011800800000B8ull))
+#define CVMX_L2C_OOB (CVMX_ADD_IO_SEG(0x00011800800000D8ull))
+#define CVMX_L2C_OOB1 (CVMX_ADD_IO_SEG(0x00011800800000E0ull))
+#define CVMX_L2C_OOB2 (CVMX_ADD_IO_SEG(0x00011800800000E8ull))
+#define CVMX_L2C_OOB3 (CVMX_ADD_IO_SEG(0x00011800800000F0ull))
+#define CVMX_L2C_PFC0 CVMX_L2C_PFCX(0)
+#define CVMX_L2C_PFC1 CVMX_L2C_PFCX(1)
+#define CVMX_L2C_PFC2 CVMX_L2C_PFCX(2)
+#define CVMX_L2C_PFC3 CVMX_L2C_PFCX(3)
+#define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull))
+#define CVMX_L2C_PFCX(offset) (CVMX_ADD_IO_SEG(0x0001180080000098ull) + ((offset) & 3) * 8)
+#define CVMX_L2C_PPGRP (CVMX_ADD_IO_SEG(0x00011800800000C0ull))
+#define CVMX_L2C_QOS_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080880200ull))
+#define CVMX_L2C_QOS_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080880000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_QOS_WGT (CVMX_ADD_IO_SEG(0x0001180080800008ull))
+#define CVMX_L2C_RSCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800410ull))
+#define CVMX_L2C_RSDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800418ull))
+#define CVMX_L2C_SPAR0 (CVMX_ADD_IO_SEG(0x0001180080000068ull))
+#define CVMX_L2C_SPAR1 (CVMX_ADD_IO_SEG(0x0001180080000070ull))
+#define CVMX_L2C_SPAR2 (CVMX_ADD_IO_SEG(0x0001180080000078ull))
+#define CVMX_L2C_SPAR3 (CVMX_ADD_IO_SEG(0x0001180080000080ull))
+#define CVMX_L2C_SPAR4 (CVMX_ADD_IO_SEG(0x0001180080000088ull))
+#define CVMX_L2C_TADX_ECC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00018ull))
+#define CVMX_L2C_TADX_ECC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00020ull))
+#define CVMX_L2C_TADX_IEN(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00000ull))
+#define CVMX_L2C_TADX_INT(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00028ull))
+#define CVMX_L2C_TADX_PFC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00400ull))
+#define CVMX_L2C_TADX_PFC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00408ull))
+#define CVMX_L2C_TADX_PFC2(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00410ull))
+#define CVMX_L2C_TADX_PFC3(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00418ull))
+#define CVMX_L2C_TADX_PRF(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00008ull))
+#define CVMX_L2C_TADX_TAG(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00010ull))
+#define CVMX_L2C_VER_ID (CVMX_ADD_IO_SEG(0x00011800808007E0ull))
+#define CVMX_L2C_VER_IOB (CVMX_ADD_IO_SEG(0x00011800808007F0ull))
+#define CVMX_L2C_VER_MSC (CVMX_ADD_IO_SEG(0x00011800808007D0ull))
+#define CVMX_L2C_VER_PP (CVMX_ADD_IO_SEG(0x00011800808007E8ull))
+#define CVMX_L2C_VIRTID_IOBX(block_id) (CVMX_ADD_IO_SEG(0x00011800808C0200ull))
+#define CVMX_L2C_VIRTID_PPX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_VRT_CTL (CVMX_ADD_IO_SEG(0x0001180080800010ull))
+#define CVMX_L2C_VRT_MEMX(offset) (CVMX_ADD_IO_SEG(0x0001180080900000ull) + ((offset) & 1023) * 8)
+#define CVMX_L2C_WPAR_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080840200ull))
+#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_XMCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800400ull))
+#define CVMX_L2C_XMC_CMD (CVMX_ADD_IO_SEG(0x0001180080800028ull))
+#define CVMX_L2C_XMDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800408ull))
+
+union cvmx_l2c_big_ctl {
+ uint64_t u64;
+ struct cvmx_l2c_big_ctl_s {
+ uint64_t reserved_8_63:56;
+ uint64_t maxdram:4;
+ uint64_t reserved_1_3:3;
+ uint64_t disable:1;
+ } s;
+ struct cvmx_l2c_big_ctl_s cn63xx;
+};
+
+union cvmx_l2c_bst {
+ uint64_t u64;
+ struct cvmx_l2c_bst_s {
+ uint64_t reserved_38_63:26;
+ uint64_t dutfl:6;
+ uint64_t reserved_17_31:15;
+ uint64_t ioccmdfl:1;
+ uint64_t reserved_13_15:3;
+ uint64_t iocdatfl:1;
+ uint64_t reserved_9_11:3;
+ uint64_t dutresfl:1;
+ uint64_t reserved_5_7:3;
+ uint64_t vrtfl:1;
+ uint64_t reserved_1_3:3;
+ uint64_t tdffl:1;
+ } s;
+ struct cvmx_l2c_bst_s cn63xx;
+ struct cvmx_l2c_bst_s cn63xxp1;
+};
+
+union cvmx_l2c_bst0 {
+ uint64_t u64;
+ struct cvmx_l2c_bst0_s {
+ uint64_t reserved_24_63:40;
+ uint64_t dtbnk:1;
+ uint64_t wlb_msk:4;
+ uint64_t dtcnt:13;
+ uint64_t dt:1;
+ uint64_t stin_msk:1;
+ uint64_t wlb_dat:4;
+ } s;
+ struct cvmx_l2c_bst0_cn30xx {
+ uint64_t reserved_23_63:41;
+ uint64_t wlb_msk:4;
+ uint64_t reserved_15_18:4;
+ uint64_t dtcnt:9;
+ uint64_t dt:1;
+ uint64_t reserved_4_4:1;
+ uint64_t wlb_dat:4;
+ } cn30xx;
+ struct cvmx_l2c_bst0_cn31xx {
+ uint64_t reserved_23_63:41;
+ uint64_t wlb_msk:4;
+ uint64_t reserved_16_18:3;
+ uint64_t dtcnt:10;
+ uint64_t dt:1;
+ uint64_t stin_msk:1;
+ uint64_t wlb_dat:4;
+ } cn31xx;
+ struct cvmx_l2c_bst0_cn38xx {
+ uint64_t reserved_19_63:45;
+ uint64_t dtcnt:13;
+ uint64_t dt:1;
+ uint64_t stin_msk:1;
+ uint64_t wlb_dat:4;
+ } cn38xx;
+ struct cvmx_l2c_bst0_cn38xx cn38xxp2;
+ struct cvmx_l2c_bst0_cn50xx {
+ uint64_t reserved_24_63:40;
+ uint64_t dtbnk:1;
+ uint64_t wlb_msk:4;
+ uint64_t reserved_16_18:3;
+ uint64_t dtcnt:10;
+ uint64_t dt:1;
+ uint64_t stin_msk:1;
+ uint64_t wlb_dat:4;
+ } cn50xx;
+ struct cvmx_l2c_bst0_cn50xx cn52xx;
+ struct cvmx_l2c_bst0_cn50xx cn52xxp1;
+ struct cvmx_l2c_bst0_s cn56xx;
+ struct cvmx_l2c_bst0_s cn56xxp1;
+ struct cvmx_l2c_bst0_s cn58xx;
+ struct cvmx_l2c_bst0_s cn58xxp1;
+};
+
+union cvmx_l2c_bst1 {
+ uint64_t u64;
+ struct cvmx_l2c_bst1_s {
+ uint64_t reserved_9_63:55;
+ uint64_t l2t:9;
+ } s;
+ struct cvmx_l2c_bst1_cn30xx {
+ uint64_t reserved_16_63:48;
+ uint64_t vwdf:4;
+ uint64_t lrf:2;
+ uint64_t vab_vwcf:1;
+ uint64_t reserved_5_8:4;
+ uint64_t l2t:5;
+ } cn30xx;
+ struct cvmx_l2c_bst1_cn30xx cn31xx;
+ struct cvmx_l2c_bst1_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t vwdf:4;
+ uint64_t lrf:2;
+ uint64_t vab_vwcf:1;
+ uint64_t l2t:9;
+ } cn38xx;
+ struct cvmx_l2c_bst1_cn38xx cn38xxp2;
+ struct cvmx_l2c_bst1_cn38xx cn50xx;
+ struct cvmx_l2c_bst1_cn52xx {
+ uint64_t reserved_19_63:45;
+ uint64_t plc2:1;
+ uint64_t plc1:1;
+ uint64_t plc0:1;
+ uint64_t vwdf:4;
+ uint64_t reserved_11_11:1;
+ uint64_t ilc:1;
+ uint64_t vab_vwcf:1;
+ uint64_t l2t:9;
+ } cn52xx;
+ struct cvmx_l2c_bst1_cn52xx cn52xxp1;
+ struct cvmx_l2c_bst1_cn56xx {
+ uint64_t reserved_24_63:40;
+ uint64_t plc2:1;
+ uint64_t plc1:1;
+ uint64_t plc0:1;
+ uint64_t ilc:1;
+ uint64_t vwdf1:4;
+ uint64_t vwdf0:4;
+ uint64_t vab_vwcf1:1;
+ uint64_t reserved_10_10:1;
+ uint64_t vab_vwcf0:1;
+ uint64_t l2t:9;
+ } cn56xx;
+ struct cvmx_l2c_bst1_cn56xx cn56xxp1;
+ struct cvmx_l2c_bst1_cn38xx cn58xx;
+ struct cvmx_l2c_bst1_cn38xx cn58xxp1;
+};
+
+union cvmx_l2c_bst2 {
+ uint64_t u64;
+ struct cvmx_l2c_bst2_s {
+ uint64_t reserved_16_63:48;
+ uint64_t mrb:4;
+ uint64_t reserved_4_11:8;
+ uint64_t ipcbst:1;
+ uint64_t picbst:1;
+ uint64_t xrdmsk:1;
+ uint64_t xrddat:1;
+ } s;
+ struct cvmx_l2c_bst2_cn30xx {
+ uint64_t reserved_16_63:48;
+ uint64_t mrb:4;
+ uint64_t rmdf:4;
+ uint64_t reserved_4_7:4;
+ uint64_t ipcbst:1;
+ uint64_t reserved_2_2:1;
+ uint64_t xrdmsk:1;
+ uint64_t xrddat:1;
+ } cn30xx;
+ struct cvmx_l2c_bst2_cn30xx cn31xx;
+ struct cvmx_l2c_bst2_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t mrb:4;
+ uint64_t rmdf:4;
+ uint64_t rhdf:4;
+ uint64_t ipcbst:1;
+ uint64_t picbst:1;
+ uint64_t xrdmsk:1;
+ uint64_t xrddat:1;
+ } cn38xx;
+ struct cvmx_l2c_bst2_cn38xx cn38xxp2;
+ struct cvmx_l2c_bst2_cn30xx cn50xx;
+ struct cvmx_l2c_bst2_cn30xx cn52xx;
+ struct cvmx_l2c_bst2_cn30xx cn52xxp1;
+ struct cvmx_l2c_bst2_cn56xx {
+ uint64_t reserved_16_63:48;
+ uint64_t mrb:4;
+ uint64_t rmdb:4;
+ uint64_t rhdb:4;
+ uint64_t ipcbst:1;
+ uint64_t picbst:1;
+ uint64_t xrdmsk:1;
+ uint64_t xrddat:1;
+ } cn56xx;
+ struct cvmx_l2c_bst2_cn56xx cn56xxp1;
+ struct cvmx_l2c_bst2_cn56xx cn58xx;
+ struct cvmx_l2c_bst2_cn56xx cn58xxp1;
+};
+
+union cvmx_l2c_bst_memx {
+ uint64_t u64;
+ struct cvmx_l2c_bst_memx_s {
+ uint64_t start_bist:1;
+ uint64_t clear_bist:1;
+ uint64_t reserved_5_61:57;
+ uint64_t rdffl:1;
+ uint64_t vbffl:4;
+ } s;
+ struct cvmx_l2c_bst_memx_s cn63xx;
+ struct cvmx_l2c_bst_memx_s cn63xxp1;
+};
+
+union cvmx_l2c_bst_tdtx {
+ uint64_t u64;
+ struct cvmx_l2c_bst_tdtx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t fbfrspfl:8;
+ uint64_t sbffl:8;
+ uint64_t fbffl:8;
+ uint64_t l2dfl:8;
+ } s;
+ struct cvmx_l2c_bst_tdtx_s cn63xx;
+ struct cvmx_l2c_bst_tdtx_cn63xxp1 {
+ uint64_t reserved_24_63:40;
+ uint64_t sbffl:8;
+ uint64_t fbffl:8;
+ uint64_t l2dfl:8;
+ } cn63xxp1;
+};
+
+union cvmx_l2c_bst_ttgx {
+ uint64_t u64;
+ struct cvmx_l2c_bst_ttgx_s {
+ uint64_t reserved_17_63:47;
+ uint64_t lrufl:1;
+ uint64_t tagfl:16;
+ } s;
+ struct cvmx_l2c_bst_ttgx_s cn63xx;
+ struct cvmx_l2c_bst_ttgx_s cn63xxp1;
+};
+
+union cvmx_l2c_cfg {
+ uint64_t u64;
+ struct cvmx_l2c_cfg_s {
+ uint64_t reserved_20_63:44;
+ uint64_t bstrun:1;
+ uint64_t lbist:1;
+ uint64_t xor_bank:1;
+ uint64_t dpres1:1;
+ uint64_t dpres0:1;
+ uint64_t dfill_dis:1;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } s;
+ struct cvmx_l2c_cfg_cn30xx {
+ uint64_t reserved_14_63:50;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } cn30xx;
+ struct cvmx_l2c_cfg_cn30xx cn31xx;
+ struct cvmx_l2c_cfg_cn30xx cn38xx;
+ struct cvmx_l2c_cfg_cn30xx cn38xxp2;
+ struct cvmx_l2c_cfg_cn50xx {
+ uint64_t reserved_20_63:44;
+ uint64_t bstrun:1;
+ uint64_t lbist:1;
+ uint64_t reserved_14_17:4;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } cn50xx;
+ struct cvmx_l2c_cfg_cn50xx cn52xx;
+ struct cvmx_l2c_cfg_cn50xx cn52xxp1;
+ struct cvmx_l2c_cfg_s cn56xx;
+ struct cvmx_l2c_cfg_s cn56xxp1;
+ struct cvmx_l2c_cfg_cn58xx {
+ uint64_t reserved_20_63:44;
+ uint64_t bstrun:1;
+ uint64_t lbist:1;
+ uint64_t reserved_15_17:3;
+ uint64_t dfill_dis:1;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } cn58xx;
+ struct cvmx_l2c_cfg_cn58xxp1 {
+ uint64_t reserved_15_63:49;
+ uint64_t dfill_dis:1;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } cn58xxp1;
+};
+
+union cvmx_l2c_cop0_mapx {
+ uint64_t u64;
+ struct cvmx_l2c_cop0_mapx_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_l2c_cop0_mapx_s cn63xx;
+ struct cvmx_l2c_cop0_mapx_s cn63xxp1;
+};
+
+union cvmx_l2c_ctl {
+ uint64_t u64;
+ struct cvmx_l2c_ctl_s {
+ uint64_t reserved_28_63:36;
+ uint64_t disstgl2i:1;
+ uint64_t l2dfsbe:1;
+ uint64_t l2dfdbe:1;
+ uint64_t discclk:1;
+ uint64_t maxvab:4;
+ uint64_t maxlfb:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t ef_ena:1;
+ uint64_t ef_cnt:7;
+ uint64_t vab_thresh:4;
+ uint64_t disecc:1;
+ uint64_t disidxalias:1;
+ } s;
+ struct cvmx_l2c_ctl_s cn63xx;
+ struct cvmx_l2c_ctl_cn63xxp1 {
+ uint64_t reserved_25_63:39;
+ uint64_t discclk:1;
+ uint64_t maxvab:4;
+ uint64_t maxlfb:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t xmc_arb_mode:1;
+ uint64_t ef_ena:1;
+ uint64_t ef_cnt:7;
+ uint64_t vab_thresh:4;
+ uint64_t disecc:1;
+ uint64_t disidxalias:1;
+ } cn63xxp1;
+};
+
+union cvmx_l2c_dbg {
+ uint64_t u64;
+ struct cvmx_l2c_dbg_s {
+ uint64_t reserved_15_63:49;
+ uint64_t lfb_enum:4;
+ uint64_t lfb_dmp:1;
+ uint64_t ppnum:4;
+ uint64_t set:3;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } s;
+ struct cvmx_l2c_dbg_cn30xx {
+ uint64_t reserved_13_63:51;
+ uint64_t lfb_enum:2;
+ uint64_t lfb_dmp:1;
+ uint64_t reserved_7_9:3;
+ uint64_t ppnum:1;
+ uint64_t reserved_5_5:1;
+ uint64_t set:2;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } cn30xx;
+ struct cvmx_l2c_dbg_cn31xx {
+ uint64_t reserved_14_63:50;
+ uint64_t lfb_enum:3;
+ uint64_t lfb_dmp:1;
+ uint64_t reserved_7_9:3;
+ uint64_t ppnum:1;
+ uint64_t reserved_5_5:1;
+ uint64_t set:2;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } cn31xx;
+ struct cvmx_l2c_dbg_s cn38xx;
+ struct cvmx_l2c_dbg_s cn38xxp2;
+ struct cvmx_l2c_dbg_cn50xx {
+ uint64_t reserved_14_63:50;
+ uint64_t lfb_enum:3;
+ uint64_t lfb_dmp:1;
+ uint64_t reserved_7_9:3;
+ uint64_t ppnum:1;
+ uint64_t set:3;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } cn50xx;
+ struct cvmx_l2c_dbg_cn52xx {
+ uint64_t reserved_14_63:50;
+ uint64_t lfb_enum:3;
+ uint64_t lfb_dmp:1;
+ uint64_t reserved_8_9:2;
+ uint64_t ppnum:2;
+ uint64_t set:3;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } cn52xx;
+ struct cvmx_l2c_dbg_cn52xx cn52xxp1;
+ struct cvmx_l2c_dbg_s cn56xx;
+ struct cvmx_l2c_dbg_s cn56xxp1;
+ struct cvmx_l2c_dbg_s cn58xx;
+ struct cvmx_l2c_dbg_s cn58xxp1;
+};
+
+union cvmx_l2c_dut {
+ uint64_t u64;
+ struct cvmx_l2c_dut_s {
+ uint64_t reserved_32_63:32;
+ uint64_t dtena:1;
+ uint64_t reserved_30_30:1;
+ uint64_t dt_vld:1;
+ uint64_t dt_tag:29;
+ } s;
+ struct cvmx_l2c_dut_s cn30xx;
+ struct cvmx_l2c_dut_s cn31xx;
+ struct cvmx_l2c_dut_s cn38xx;
+ struct cvmx_l2c_dut_s cn38xxp2;
+ struct cvmx_l2c_dut_s cn50xx;
+ struct cvmx_l2c_dut_s cn52xx;
+ struct cvmx_l2c_dut_s cn52xxp1;
+ struct cvmx_l2c_dut_s cn56xx;
+ struct cvmx_l2c_dut_s cn56xxp1;
+ struct cvmx_l2c_dut_s cn58xx;
+ struct cvmx_l2c_dut_s cn58xxp1;
+};
+
+union cvmx_l2c_dut_mapx {
+ uint64_t u64;
+ struct cvmx_l2c_dut_mapx_s {
+ uint64_t reserved_38_63:26;
+ uint64_t tag:28;
+ uint64_t reserved_1_9:9;
+ uint64_t valid:1;
+ } s;
+ struct cvmx_l2c_dut_mapx_s cn63xx;
+ struct cvmx_l2c_dut_mapx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_tdtx {
+ uint64_t u64;
+ struct cvmx_l2c_err_tdtx_s {
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ uint64_t vdbe:1;
+ uint64_t vsbe:1;
+ uint64_t syn:10;
+ uint64_t reserved_21_49:29;
+ uint64_t wayidx:17;
+ uint64_t reserved_2_3:2;
+ uint64_t type:2;
+ } s;
+ struct cvmx_l2c_err_tdtx_s cn63xx;
+ struct cvmx_l2c_err_tdtx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_ttgx {
+ uint64_t u64;
+ struct cvmx_l2c_err_ttgx_s {
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ uint64_t noway:1;
+ uint64_t reserved_56_60:5;
+ uint64_t syn:6;
+ uint64_t reserved_21_49:29;
+ uint64_t wayidx:14;
+ uint64_t reserved_2_6:5;
+ uint64_t type:2;
+ } s;
+ struct cvmx_l2c_err_ttgx_s cn63xx;
+ struct cvmx_l2c_err_ttgx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_vbfx {
+ uint64_t u64;
+ struct cvmx_l2c_err_vbfx_s {
+ uint64_t reserved_62_63:2;
+ uint64_t vdbe:1;
+ uint64_t vsbe:1;
+ uint64_t vsyn:10;
+ uint64_t reserved_2_49:48;
+ uint64_t type:2;
+ } s;
+ struct cvmx_l2c_err_vbfx_s cn63xx;
+ struct cvmx_l2c_err_vbfx_s cn63xxp1;
+};
+
+union cvmx_l2c_err_xmc {
+ uint64_t u64;
+ struct cvmx_l2c_err_xmc_s {
+ uint64_t cmd:6;
+ uint64_t reserved_52_57:6;
+ uint64_t sid:4;
+ uint64_t reserved_38_47:10;
+ uint64_t addr:38;
+ } s;
+ struct cvmx_l2c_err_xmc_s cn63xx;
+ struct cvmx_l2c_err_xmc_s cn63xxp1;
+};
+
+union cvmx_l2c_grpwrr0 {
+ uint64_t u64;
+ struct cvmx_l2c_grpwrr0_s {
+ uint64_t plc1rmsk:32;
+ uint64_t plc0rmsk:32;
+ } s;
+ struct cvmx_l2c_grpwrr0_s cn52xx;
+ struct cvmx_l2c_grpwrr0_s cn52xxp1;
+ struct cvmx_l2c_grpwrr0_s cn56xx;
+ struct cvmx_l2c_grpwrr0_s cn56xxp1;
+};
+
+union cvmx_l2c_grpwrr1 {
+ uint64_t u64;
+ struct cvmx_l2c_grpwrr1_s {
+ uint64_t ilcrmsk:32;
+ uint64_t plc2rmsk:32;
+ } s;
+ struct cvmx_l2c_grpwrr1_s cn52xx;
+ struct cvmx_l2c_grpwrr1_s cn52xxp1;
+ struct cvmx_l2c_grpwrr1_s cn56xx;
+ struct cvmx_l2c_grpwrr1_s cn56xxp1;
+};
+
+union cvmx_l2c_int_en {
+ uint64_t u64;
+ struct cvmx_l2c_int_en_s {
+ uint64_t reserved_9_63:55;
+ uint64_t lck2ena:1;
+ uint64_t lckena:1;
+ uint64_t l2ddeden:1;
+ uint64_t l2dsecen:1;
+ uint64_t l2tdeden:1;
+ uint64_t l2tsecen:1;
+ uint64_t oob3en:1;
+ uint64_t oob2en:1;
+ uint64_t oob1en:1;
+ } s;
+ struct cvmx_l2c_int_en_s cn52xx;
+ struct cvmx_l2c_int_en_s cn52xxp1;
+ struct cvmx_l2c_int_en_s cn56xx;
+ struct cvmx_l2c_int_en_s cn56xxp1;
+};
+
+union cvmx_l2c_int_ena {
+ uint64_t u64;
+ struct cvmx_l2c_int_ena_s {
+ uint64_t reserved_8_63:56;
+ uint64_t bigrd:1;
+ uint64_t bigwr:1;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+ } s;
+ struct cvmx_l2c_int_ena_s cn63xx;
+ struct cvmx_l2c_int_ena_cn63xxp1 {
+ uint64_t reserved_6_63:58;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+ } cn63xxp1;
+};
+
+union cvmx_l2c_int_reg {
+ uint64_t u64;
+ struct cvmx_l2c_int_reg_s {
+ uint64_t reserved_17_63:47;
+ uint64_t tad0:1;
+ uint64_t reserved_8_15:8;
+ uint64_t bigrd:1;
+ uint64_t bigwr:1;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+ } s;
+ struct cvmx_l2c_int_reg_s cn63xx;
+ struct cvmx_l2c_int_reg_cn63xxp1 {
+ uint64_t reserved_17_63:47;
+ uint64_t tad0:1;
+ uint64_t reserved_6_15:10;
+ uint64_t vrtpe:1;
+ uint64_t vrtadrng:1;
+ uint64_t vrtidrng:1;
+ uint64_t vrtwr:1;
+ uint64_t holewr:1;
+ uint64_t holerd:1;
+ } cn63xxp1;
+};
+
+union cvmx_l2c_int_stat {
+ uint64_t u64;
+ struct cvmx_l2c_int_stat_s {
+ uint64_t reserved_9_63:55;
+ uint64_t lck2:1;
+ uint64_t lck:1;
+ uint64_t l2dded:1;
+ uint64_t l2dsec:1;
+ uint64_t l2tded:1;
+ uint64_t l2tsec:1;
+ uint64_t oob3:1;
+ uint64_t oob2:1;
+ uint64_t oob1:1;
+ } s;
+ struct cvmx_l2c_int_stat_s cn52xx;
+ struct cvmx_l2c_int_stat_s cn52xxp1;
+ struct cvmx_l2c_int_stat_s cn56xx;
+ struct cvmx_l2c_int_stat_s cn56xxp1;
+};
+
+union cvmx_l2c_iocx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_iocx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_iocx_pfc_s cn63xx;
+ struct cvmx_l2c_iocx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_iorx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_iorx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_iorx_pfc_s cn63xx;
+ struct cvmx_l2c_iorx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_lckbase {
+ uint64_t u64;
+ struct cvmx_l2c_lckbase_s {
+ uint64_t reserved_31_63:33;
+ uint64_t lck_base:27;
+ uint64_t reserved_1_3:3;
+ uint64_t lck_ena:1;
+ } s;
+ struct cvmx_l2c_lckbase_s cn30xx;
+ struct cvmx_l2c_lckbase_s cn31xx;
+ struct cvmx_l2c_lckbase_s cn38xx;
+ struct cvmx_l2c_lckbase_s cn38xxp2;
+ struct cvmx_l2c_lckbase_s cn50xx;
+ struct cvmx_l2c_lckbase_s cn52xx;
+ struct cvmx_l2c_lckbase_s cn52xxp1;
+ struct cvmx_l2c_lckbase_s cn56xx;
+ struct cvmx_l2c_lckbase_s cn56xxp1;
+ struct cvmx_l2c_lckbase_s cn58xx;
+ struct cvmx_l2c_lckbase_s cn58xxp1;
+};
+
+union cvmx_l2c_lckoff {
+ uint64_t u64;
+ struct cvmx_l2c_lckoff_s {
+ uint64_t reserved_10_63:54;
+ uint64_t lck_offset:10;
+ } s;
+ struct cvmx_l2c_lckoff_s cn30xx;
+ struct cvmx_l2c_lckoff_s cn31xx;
+ struct cvmx_l2c_lckoff_s cn38xx;
+ struct cvmx_l2c_lckoff_s cn38xxp2;
+ struct cvmx_l2c_lckoff_s cn50xx;
+ struct cvmx_l2c_lckoff_s cn52xx;
+ struct cvmx_l2c_lckoff_s cn52xxp1;
+ struct cvmx_l2c_lckoff_s cn56xx;
+ struct cvmx_l2c_lckoff_s cn56xxp1;
+ struct cvmx_l2c_lckoff_s cn58xx;
+ struct cvmx_l2c_lckoff_s cn58xxp1;
+};
+
+union cvmx_l2c_lfb0 {
+ uint64_t u64;
+ struct cvmx_l2c_lfb0_s {
+ uint64_t reserved_32_63:32;
+ uint64_t stcpnd:1;
+ uint64_t stpnd:1;
+ uint64_t stinv:1;
+ uint64_t stcfl:1;
+ uint64_t vam:1;
+ uint64_t inxt:4;
+ uint64_t itl:1;
+ uint64_t ihd:1;
+ uint64_t set:3;
+ uint64_t vabnum:4;
+ uint64_t sid:9;
+ uint64_t cmd:4;
+ uint64_t vld:1;
+ } s;
+ struct cvmx_l2c_lfb0_cn30xx {
+ uint64_t reserved_32_63:32;
+ uint64_t stcpnd:1;
+ uint64_t stpnd:1;
+ uint64_t stinv:1;
+ uint64_t stcfl:1;
+ uint64_t vam:1;
+ uint64_t reserved_25_26:2;
+ uint64_t inxt:2;
+ uint64_t itl:1;
+ uint64_t ihd:1;
+ uint64_t reserved_20_20:1;
+ uint64_t set:2;
+ uint64_t reserved_16_17:2;
+ uint64_t vabnum:2;
+ uint64_t sid:9;
+ uint64_t cmd:4;
+ uint64_t vld:1;
+ } cn30xx;
+ struct cvmx_l2c_lfb0_cn31xx {
+ uint64_t reserved_32_63:32;
+ uint64_t stcpnd:1;
+ uint64_t stpnd:1;
+ uint64_t stinv:1;
+ uint64_t stcfl:1;
+ uint64_t vam:1;
+ uint64_t reserved_26_26:1;
+ uint64_t inxt:3;
+ uint64_t itl:1;
+ uint64_t ihd:1;
+ uint64_t reserved_20_20:1;
+ uint64_t set:2;
+ uint64_t reserved_17_17:1;
+ uint64_t vabnum:3;
+ uint64_t sid:9;
+ uint64_t cmd:4;
+ uint64_t vld:1;
+ } cn31xx;
+ struct cvmx_l2c_lfb0_s cn38xx;
+ struct cvmx_l2c_lfb0_s cn38xxp2;
+ struct cvmx_l2c_lfb0_cn50xx {
+ uint64_t reserved_32_63:32;
+ uint64_t stcpnd:1;
+ uint64_t stpnd:1;
+ uint64_t stinv:1;
+ uint64_t stcfl:1;
+ uint64_t vam:1;
+ uint64_t reserved_26_26:1;
+ uint64_t inxt:3;
+ uint64_t itl:1;
+ uint64_t ihd:1;
+ uint64_t set:3;
+ uint64_t reserved_17_17:1;
+ uint64_t vabnum:3;
+ uint64_t sid:9;
+ uint64_t cmd:4;
+ uint64_t vld:1;
+ } cn50xx;
+ struct cvmx_l2c_lfb0_cn50xx cn52xx;
+ struct cvmx_l2c_lfb0_cn50xx cn52xxp1;
+ struct cvmx_l2c_lfb0_s cn56xx;
+ struct cvmx_l2c_lfb0_s cn56xxp1;
+ struct cvmx_l2c_lfb0_s cn58xx;
+ struct cvmx_l2c_lfb0_s cn58xxp1;
+};
+
+union cvmx_l2c_lfb1 {
+ uint64_t u64;
+ struct cvmx_l2c_lfb1_s {
+ uint64_t reserved_19_63:45;
+ uint64_t dsgoing:1;
+ uint64_t bid:2;
+ uint64_t wtrsp:1;
+ uint64_t wtdw:1;
+ uint64_t wtdq:1;
+ uint64_t wtwhp:1;
+ uint64_t wtwhf:1;
+ uint64_t wtwrm:1;
+ uint64_t wtstm:1;
+ uint64_t wtrda:1;
+ uint64_t wtstdt:1;
+ uint64_t wtstrsp:1;
+ uint64_t wtstrsc:1;
+ uint64_t wtvtm:1;
+ uint64_t wtmfl:1;
+ uint64_t prbrty:1;
+ uint64_t wtprb:1;
+ uint64_t vld:1;
+ } s;
+ struct cvmx_l2c_lfb1_s cn30xx;
+ struct cvmx_l2c_lfb1_s cn31xx;
+ struct cvmx_l2c_lfb1_s cn38xx;
+ struct cvmx_l2c_lfb1_s cn38xxp2;
+ struct cvmx_l2c_lfb1_s cn50xx;
+ struct cvmx_l2c_lfb1_s cn52xx;
+ struct cvmx_l2c_lfb1_s cn52xxp1;
+ struct cvmx_l2c_lfb1_s cn56xx;
+ struct cvmx_l2c_lfb1_s cn56xxp1;
+ struct cvmx_l2c_lfb1_s cn58xx;
+ struct cvmx_l2c_lfb1_s cn58xxp1;
+};
+
+union cvmx_l2c_lfb2 {
+ uint64_t u64;
+ struct cvmx_l2c_lfb2_s {
+ uint64_t reserved_0_63:64;
+ } s;
+ struct cvmx_l2c_lfb2_cn30xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:19;
+ uint64_t lfb_idx:8;
+ } cn30xx;
+ struct cvmx_l2c_lfb2_cn31xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:17;
+ uint64_t lfb_idx:10;
+ } cn31xx;
+ struct cvmx_l2c_lfb2_cn31xx cn38xx;
+ struct cvmx_l2c_lfb2_cn31xx cn38xxp2;
+ struct cvmx_l2c_lfb2_cn50xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:20;
+ uint64_t lfb_idx:7;
+ } cn50xx;
+ struct cvmx_l2c_lfb2_cn52xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:18;
+ uint64_t lfb_idx:9;
+ } cn52xx;
+ struct cvmx_l2c_lfb2_cn52xx cn52xxp1;
+ struct cvmx_l2c_lfb2_cn56xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:16;
+ uint64_t lfb_idx:11;
+ } cn56xx;
+ struct cvmx_l2c_lfb2_cn56xx cn56xxp1;
+ struct cvmx_l2c_lfb2_cn56xx cn58xx;
+ struct cvmx_l2c_lfb2_cn56xx cn58xxp1;
+};
+
+union cvmx_l2c_lfb3 {
+ uint64_t u64;
+ struct cvmx_l2c_lfb3_s {
+ uint64_t reserved_5_63:59;
+ uint64_t stpartdis:1;
+ uint64_t lfb_hwm:4;
+ } s;
+ struct cvmx_l2c_lfb3_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t stpartdis:1;
+ uint64_t reserved_2_3:2;
+ uint64_t lfb_hwm:2;
+ } cn30xx;
+ struct cvmx_l2c_lfb3_cn31xx {
+ uint64_t reserved_5_63:59;
+ uint64_t stpartdis:1;
+ uint64_t reserved_3_3:1;
+ uint64_t lfb_hwm:3;
+ } cn31xx;
+ struct cvmx_l2c_lfb3_s cn38xx;
+ struct cvmx_l2c_lfb3_s cn38xxp2;
+ struct cvmx_l2c_lfb3_cn31xx cn50xx;
+ struct cvmx_l2c_lfb3_cn31xx cn52xx;
+ struct cvmx_l2c_lfb3_cn31xx cn52xxp1;
+ struct cvmx_l2c_lfb3_s cn56xx;
+ struct cvmx_l2c_lfb3_s cn56xxp1;
+ struct cvmx_l2c_lfb3_s cn58xx;
+ struct cvmx_l2c_lfb3_s cn58xxp1;
+};
+
+union cvmx_l2c_oob {
+ uint64_t u64;
+ struct cvmx_l2c_oob_s {
+ uint64_t reserved_2_63:62;
+ uint64_t dwbena:1;
+ uint64_t stena:1;
+ } s;
+ struct cvmx_l2c_oob_s cn52xx;
+ struct cvmx_l2c_oob_s cn52xxp1;
+ struct cvmx_l2c_oob_s cn56xx;
+ struct cvmx_l2c_oob_s cn56xxp1;
+};
+
+union cvmx_l2c_oob1 {
+ uint64_t u64;
+ struct cvmx_l2c_oob1_s {
+ uint64_t fadr:27;
+ uint64_t fsrc:1;
+ uint64_t reserved_34_35:2;
+ uint64_t sadr:14;
+ uint64_t reserved_14_19:6;
+ uint64_t size:14;
+ } s;
+ struct cvmx_l2c_oob1_s cn52xx;
+ struct cvmx_l2c_oob1_s cn52xxp1;
+ struct cvmx_l2c_oob1_s cn56xx;
+ struct cvmx_l2c_oob1_s cn56xxp1;
+};
+
+union cvmx_l2c_oob2 {
+ uint64_t u64;
+ struct cvmx_l2c_oob2_s {
+ uint64_t fadr:27;
+ uint64_t fsrc:1;
+ uint64_t reserved_34_35:2;
+ uint64_t sadr:14;
+ uint64_t reserved_14_19:6;
+ uint64_t size:14;
+ } s;
+ struct cvmx_l2c_oob2_s cn52xx;
+ struct cvmx_l2c_oob2_s cn52xxp1;
+ struct cvmx_l2c_oob2_s cn56xx;
+ struct cvmx_l2c_oob2_s cn56xxp1;
+};
+
+union cvmx_l2c_oob3 {
+ uint64_t u64;
+ struct cvmx_l2c_oob3_s {
+ uint64_t fadr:27;
+ uint64_t fsrc:1;
+ uint64_t reserved_34_35:2;
+ uint64_t sadr:14;
+ uint64_t reserved_14_19:6;
+ uint64_t size:14;
+ } s;
+ struct cvmx_l2c_oob3_s cn52xx;
+ struct cvmx_l2c_oob3_s cn52xxp1;
+ struct cvmx_l2c_oob3_s cn56xx;
+ struct cvmx_l2c_oob3_s cn56xxp1;
+};
+
+union cvmx_l2c_pfcx {
+ uint64_t u64;
+ struct cvmx_l2c_pfcx_s {
+ uint64_t reserved_36_63:28;
+ uint64_t pfcnt0:36;
+ } s;
+ struct cvmx_l2c_pfcx_s cn30xx;
+ struct cvmx_l2c_pfcx_s cn31xx;
+ struct cvmx_l2c_pfcx_s cn38xx;
+ struct cvmx_l2c_pfcx_s cn38xxp2;
+ struct cvmx_l2c_pfcx_s cn50xx;
+ struct cvmx_l2c_pfcx_s cn52xx;
+ struct cvmx_l2c_pfcx_s cn52xxp1;
+ struct cvmx_l2c_pfcx_s cn56xx;
+ struct cvmx_l2c_pfcx_s cn56xxp1;
+ struct cvmx_l2c_pfcx_s cn58xx;
+ struct cvmx_l2c_pfcx_s cn58xxp1;
+};
+
+union cvmx_l2c_pfctl {
+ uint64_t u64;
+ struct cvmx_l2c_pfctl_s {
+ uint64_t reserved_36_63:28;
+ uint64_t cnt3rdclr:1;
+ uint64_t cnt2rdclr:1;
+ uint64_t cnt1rdclr:1;
+ uint64_t cnt0rdclr:1;
+ uint64_t cnt3ena:1;
+ uint64_t cnt3clr:1;
+ uint64_t cnt3sel:6;
+ uint64_t cnt2ena:1;
+ uint64_t cnt2clr:1;
+ uint64_t cnt2sel:6;
+ uint64_t cnt1ena:1;
+ uint64_t cnt1clr:1;
+ uint64_t cnt1sel:6;
+ uint64_t cnt0ena:1;
+ uint64_t cnt0clr:1;
+ uint64_t cnt0sel:6;
+ } s;
+ struct cvmx_l2c_pfctl_s cn30xx;
+ struct cvmx_l2c_pfctl_s cn31xx;
+ struct cvmx_l2c_pfctl_s cn38xx;
+ struct cvmx_l2c_pfctl_s cn38xxp2;
+ struct cvmx_l2c_pfctl_s cn50xx;
+ struct cvmx_l2c_pfctl_s cn52xx;
+ struct cvmx_l2c_pfctl_s cn52xxp1;
+ struct cvmx_l2c_pfctl_s cn56xx;
+ struct cvmx_l2c_pfctl_s cn56xxp1;
+ struct cvmx_l2c_pfctl_s cn58xx;
+ struct cvmx_l2c_pfctl_s cn58xxp1;
+};
+
+union cvmx_l2c_ppgrp {
+ uint64_t u64;
+ struct cvmx_l2c_ppgrp_s {
+ uint64_t reserved_24_63:40;
+ uint64_t pp11grp:2;
+ uint64_t pp10grp:2;
+ uint64_t pp9grp:2;
+ uint64_t pp8grp:2;
+ uint64_t pp7grp:2;
+ uint64_t pp6grp:2;
+ uint64_t pp5grp:2;
+ uint64_t pp4grp:2;
+ uint64_t pp3grp:2;
+ uint64_t pp2grp:2;
+ uint64_t pp1grp:2;
+ uint64_t pp0grp:2;
+ } s;
+ struct cvmx_l2c_ppgrp_cn52xx {
+ uint64_t reserved_8_63:56;
+ uint64_t pp3grp:2;
+ uint64_t pp2grp:2;
+ uint64_t pp1grp:2;
+ uint64_t pp0grp:2;
+ } cn52xx;
+ struct cvmx_l2c_ppgrp_cn52xx cn52xxp1;
+ struct cvmx_l2c_ppgrp_s cn56xx;
+ struct cvmx_l2c_ppgrp_s cn56xxp1;
+};
+
+union cvmx_l2c_qos_iobx {
+ uint64_t u64;
+ struct cvmx_l2c_qos_iobx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t dwblvl:2;
+ uint64_t reserved_2_3:2;
+ uint64_t lvl:2;
+ } s;
+ struct cvmx_l2c_qos_iobx_s cn63xx;
+ struct cvmx_l2c_qos_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_qos_ppx {
+ uint64_t u64;
+ struct cvmx_l2c_qos_ppx_s {
+ uint64_t reserved_2_63:62;
+ uint64_t lvl:2;
+ } s;
+ struct cvmx_l2c_qos_ppx_s cn63xx;
+ struct cvmx_l2c_qos_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_qos_wgt {
+ uint64_t u64;
+ struct cvmx_l2c_qos_wgt_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wgt3:8;
+ uint64_t wgt2:8;
+ uint64_t wgt1:8;
+ uint64_t wgt0:8;
+ } s;
+ struct cvmx_l2c_qos_wgt_s cn63xx;
+ struct cvmx_l2c_qos_wgt_s cn63xxp1;
+};
+
+union cvmx_l2c_rscx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_rscx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_rscx_pfc_s cn63xx;
+ struct cvmx_l2c_rscx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_rsdx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_rsdx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_rsdx_pfc_s cn63xx;
+ struct cvmx_l2c_rsdx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_spar0 {
+ uint64_t u64;
+ struct cvmx_l2c_spar0_s {
+ uint64_t reserved_32_63:32;
+ uint64_t umsk3:8;
+ uint64_t umsk2:8;
+ uint64_t umsk1:8;
+ uint64_t umsk0:8;
+ } s;
+ struct cvmx_l2c_spar0_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t umsk0:4;
+ } cn30xx;
+ struct cvmx_l2c_spar0_cn31xx {
+ uint64_t reserved_12_63:52;
+ uint64_t umsk1:4;
+ uint64_t reserved_4_7:4;
+ uint64_t umsk0:4;
+ } cn31xx;
+ struct cvmx_l2c_spar0_s cn38xx;
+ struct cvmx_l2c_spar0_s cn38xxp2;
+ struct cvmx_l2c_spar0_cn50xx {
+ uint64_t reserved_16_63:48;
+ uint64_t umsk1:8;
+ uint64_t umsk0:8;
+ } cn50xx;
+ struct cvmx_l2c_spar0_s cn52xx;
+ struct cvmx_l2c_spar0_s cn52xxp1;
+ struct cvmx_l2c_spar0_s cn56xx;
+ struct cvmx_l2c_spar0_s cn56xxp1;
+ struct cvmx_l2c_spar0_s cn58xx;
+ struct cvmx_l2c_spar0_s cn58xxp1;
+};
+
+union cvmx_l2c_spar1 {
+ uint64_t u64;
+ struct cvmx_l2c_spar1_s {
+ uint64_t reserved_32_63:32;
+ uint64_t umsk7:8;
+ uint64_t umsk6:8;
+ uint64_t umsk5:8;
+ uint64_t umsk4:8;
+ } s;
+ struct cvmx_l2c_spar1_s cn38xx;
+ struct cvmx_l2c_spar1_s cn38xxp2;
+ struct cvmx_l2c_spar1_s cn56xx;
+ struct cvmx_l2c_spar1_s cn56xxp1;
+ struct cvmx_l2c_spar1_s cn58xx;
+ struct cvmx_l2c_spar1_s cn58xxp1;
+};
+
+union cvmx_l2c_spar2 {
+ uint64_t u64;
+ struct cvmx_l2c_spar2_s {
+ uint64_t reserved_32_63:32;
+ uint64_t umsk11:8;
+ uint64_t umsk10:8;
+ uint64_t umsk9:8;
+ uint64_t umsk8:8;
+ } s;
+ struct cvmx_l2c_spar2_s cn38xx;
+ struct cvmx_l2c_spar2_s cn38xxp2;
+ struct cvmx_l2c_spar2_s cn56xx;
+ struct cvmx_l2c_spar2_s cn56xxp1;
+ struct cvmx_l2c_spar2_s cn58xx;
+ struct cvmx_l2c_spar2_s cn58xxp1;
+};
+
+union cvmx_l2c_spar3 {
+ uint64_t u64;
+ struct cvmx_l2c_spar3_s {
+ uint64_t reserved_32_63:32;
+ uint64_t umsk15:8;
+ uint64_t umsk14:8;
+ uint64_t umsk13:8;
+ uint64_t umsk12:8;
+ } s;
+ struct cvmx_l2c_spar3_s cn38xx;
+ struct cvmx_l2c_spar3_s cn38xxp2;
+ struct cvmx_l2c_spar3_s cn58xx;
+ struct cvmx_l2c_spar3_s cn58xxp1;
+};
+
+union cvmx_l2c_spar4 {
+ uint64_t u64;
+ struct cvmx_l2c_spar4_s {
+ uint64_t reserved_8_63:56;
+ uint64_t umskiob:8;
+ } s;
+ struct cvmx_l2c_spar4_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t umskiob:4;
+ } cn30xx;
+ struct cvmx_l2c_spar4_cn30xx cn31xx;
+ struct cvmx_l2c_spar4_s cn38xx;
+ struct cvmx_l2c_spar4_s cn38xxp2;
+ struct cvmx_l2c_spar4_s cn50xx;
+ struct cvmx_l2c_spar4_s cn52xx;
+ struct cvmx_l2c_spar4_s cn52xxp1;
+ struct cvmx_l2c_spar4_s cn56xx;
+ struct cvmx_l2c_spar4_s cn56xxp1;
+ struct cvmx_l2c_spar4_s cn58xx;
+ struct cvmx_l2c_spar4_s cn58xxp1;
+};
+
+union cvmx_l2c_tadx_ecc0 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_ecc0_s {
+ uint64_t reserved_58_63:6;
+ uint64_t ow3ecc:10;
+ uint64_t reserved_42_47:6;
+ uint64_t ow2ecc:10;
+ uint64_t reserved_26_31:6;
+ uint64_t ow1ecc:10;
+ uint64_t reserved_10_15:6;
+ uint64_t ow0ecc:10;
+ } s;
+ struct cvmx_l2c_tadx_ecc0_s cn63xx;
+ struct cvmx_l2c_tadx_ecc0_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_ecc1 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_ecc1_s {
+ uint64_t reserved_58_63:6;
+ uint64_t ow7ecc:10;
+ uint64_t reserved_42_47:6;
+ uint64_t ow6ecc:10;
+ uint64_t reserved_26_31:6;
+ uint64_t ow5ecc:10;
+ uint64_t reserved_10_15:6;
+ uint64_t ow4ecc:10;
+ } s;
+ struct cvmx_l2c_tadx_ecc1_s cn63xx;
+ struct cvmx_l2c_tadx_ecc1_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_ien {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_ien_s {
+ uint64_t reserved_9_63:55;
+ uint64_t wrdislmc:1;
+ uint64_t rddislmc:1;
+ uint64_t noway:1;
+ uint64_t vbfdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t tagsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t l2dsbe:1;
+ } s;
+ struct cvmx_l2c_tadx_ien_s cn63xx;
+ struct cvmx_l2c_tadx_ien_cn63xxp1 {
+ uint64_t reserved_7_63:57;
+ uint64_t noway:1;
+ uint64_t vbfdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t tagsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t l2dsbe:1;
+ } cn63xxp1;
+};
+
+union cvmx_l2c_tadx_int {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_int_s {
+ uint64_t reserved_9_63:55;
+ uint64_t wrdislmc:1;
+ uint64_t rddislmc:1;
+ uint64_t noway:1;
+ uint64_t vbfdbe:1;
+ uint64_t vbfsbe:1;
+ uint64_t tagdbe:1;
+ uint64_t tagsbe:1;
+ uint64_t l2ddbe:1;
+ uint64_t l2dsbe:1;
+ } s;
+ struct cvmx_l2c_tadx_int_s cn63xx;
+};
+
+union cvmx_l2c_tadx_pfc0 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_pfc0_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_tadx_pfc0_s cn63xx;
+ struct cvmx_l2c_tadx_pfc0_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc1 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_pfc1_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_tadx_pfc1_s cn63xx;
+ struct cvmx_l2c_tadx_pfc1_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc2 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_pfc2_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_tadx_pfc2_s cn63xx;
+ struct cvmx_l2c_tadx_pfc2_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_pfc3 {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_pfc3_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_tadx_pfc3_s cn63xx;
+ struct cvmx_l2c_tadx_pfc3_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_prf {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_prf_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt3sel:8;
+ uint64_t cnt2sel:8;
+ uint64_t cnt1sel:8;
+ uint64_t cnt0sel:8;
+ } s;
+ struct cvmx_l2c_tadx_prf_s cn63xx;
+ struct cvmx_l2c_tadx_prf_s cn63xxp1;
+};
+
+union cvmx_l2c_tadx_tag {
+ uint64_t u64;
+ struct cvmx_l2c_tadx_tag_s {
+ uint64_t reserved_46_63:18;
+ uint64_t ecc:6;
+ uint64_t reserved_36_39:4;
+ uint64_t tag:19;
+ uint64_t reserved_4_16:13;
+ uint64_t use:1;
+ uint64_t valid:1;
+ uint64_t dirty:1;
+ uint64_t lock:1;
+ } s;
+ struct cvmx_l2c_tadx_tag_s cn63xx;
+ struct cvmx_l2c_tadx_tag_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_id {
+ uint64_t u64;
+ struct cvmx_l2c_ver_id_s {
+ uint64_t mask:64;
+ } s;
+ struct cvmx_l2c_ver_id_s cn63xx;
+ struct cvmx_l2c_ver_id_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_iob {
+ uint64_t u64;
+ struct cvmx_l2c_ver_iob_s {
+ uint64_t reserved_1_63:63;
+ uint64_t mask:1;
+ } s;
+ struct cvmx_l2c_ver_iob_s cn63xx;
+ struct cvmx_l2c_ver_iob_s cn63xxp1;
+};
+
+union cvmx_l2c_ver_msc {
+ uint64_t u64;
+ struct cvmx_l2c_ver_msc_s {
+ uint64_t reserved_2_63:62;
+ uint64_t invl2:1;
+ uint64_t dwb:1;
+ } s;
+ struct cvmx_l2c_ver_msc_s cn63xx;
+};
+
+union cvmx_l2c_ver_pp {
+ uint64_t u64;
+ struct cvmx_l2c_ver_pp_s {
+ uint64_t reserved_6_63:58;
+ uint64_t mask:6;
+ } s;
+ struct cvmx_l2c_ver_pp_s cn63xx;
+ struct cvmx_l2c_ver_pp_s cn63xxp1;
+};
+
+union cvmx_l2c_virtid_iobx {
+ uint64_t u64;
+ struct cvmx_l2c_virtid_iobx_s {
+ uint64_t reserved_14_63:50;
+ uint64_t dwbid:6;
+ uint64_t reserved_6_7:2;
+ uint64_t id:6;
+ } s;
+ struct cvmx_l2c_virtid_iobx_s cn63xx;
+ struct cvmx_l2c_virtid_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_virtid_ppx {
+ uint64_t u64;
+ struct cvmx_l2c_virtid_ppx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t id:6;
+ } s;
+ struct cvmx_l2c_virtid_ppx_s cn63xx;
+ struct cvmx_l2c_virtid_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_vrt_ctl {
+ uint64_t u64;
+ struct cvmx_l2c_vrt_ctl_s {
+ uint64_t reserved_9_63:55;
+ uint64_t ooberr:1;
+ uint64_t reserved_7_7:1;
+ uint64_t memsz:3;
+ uint64_t numid:3;
+ uint64_t enable:1;
+ } s;
+ struct cvmx_l2c_vrt_ctl_s cn63xx;
+ struct cvmx_l2c_vrt_ctl_s cn63xxp1;
+};
+
+union cvmx_l2c_vrt_memx {
+ uint64_t u64;
+ struct cvmx_l2c_vrt_memx_s {
+ uint64_t reserved_36_63:28;
+ uint64_t parity:4;
+ uint64_t data:32;
+ } s;
+ struct cvmx_l2c_vrt_memx_s cn63xx;
+ struct cvmx_l2c_vrt_memx_s cn63xxp1;
+};
+
+union cvmx_l2c_wpar_iobx {
+ uint64_t u64;
+ struct cvmx_l2c_wpar_iobx_s {
+ uint64_t reserved_16_63:48;
+ uint64_t mask:16;
+ } s;
+ struct cvmx_l2c_wpar_iobx_s cn63xx;
+ struct cvmx_l2c_wpar_iobx_s cn63xxp1;
+};
+
+union cvmx_l2c_wpar_ppx {
+ uint64_t u64;
+ struct cvmx_l2c_wpar_ppx_s {
+ uint64_t reserved_16_63:48;
+ uint64_t mask:16;
+ } s;
+ struct cvmx_l2c_wpar_ppx_s cn63xx;
+ struct cvmx_l2c_wpar_ppx_s cn63xxp1;
+};
+
+union cvmx_l2c_xmcx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_xmcx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_xmcx_pfc_s cn63xx;
+ struct cvmx_l2c_xmcx_pfc_s cn63xxp1;
+};
+
+union cvmx_l2c_xmc_cmd {
+ uint64_t u64;
+ struct cvmx_l2c_xmc_cmd_s {
+ uint64_t inuse:1;
+ uint64_t cmd:6;
+ uint64_t reserved_38_56:19;
+ uint64_t addr:38;
+ } s;
+ struct cvmx_l2c_xmc_cmd_s cn63xx;
+ struct cvmx_l2c_xmc_cmd_s cn63xxp1;
+};
+
+union cvmx_l2c_xmdx_pfc {
+ uint64_t u64;
+ struct cvmx_l2c_xmdx_pfc_s {
+ uint64_t count:64;
+ } s;
+ struct cvmx_l2c_xmdx_pfc_s cn63xx;
+ struct cvmx_l2c_xmdx_pfc_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c.h b/arch/mips/include/asm/octeon/cvmx-l2c.h
new file mode 100644
index 00000000..2c8ff9e3
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2c.h
@@ -0,0 +1,360 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Interface to the Level 2 Cache (L2C) control, measurement, and debugging
+ * facilities.
+ */
+
+#ifndef __CVMX_L2C_H__
+#define __CVMX_L2C_H__
+
+#define CVMX_L2_ASSOC cvmx_l2c_get_num_assoc() /* Deprecated macro, use function */
+#define CVMX_L2_SET_BITS cvmx_l2c_get_set_bits() /* Deprecated macro, use function */
+#define CVMX_L2_SETS cvmx_l2c_get_num_sets() /* Deprecated macro, use function */
+
+
+#define CVMX_L2C_IDX_ADDR_SHIFT 7 /* based on 128 byte cache line size */
+#define CVMX_L2C_IDX_MASK (cvmx_l2c_get_num_sets() - 1)
+
+/* Defines for index aliasing computations */
+#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT (CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits())
+#define CVMX_L2C_ALIAS_MASK (CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT)
+#define CVMX_L2C_MEMBANK_SELECT_SIZE 4096
+
+/* Defines for Virtualizations, valid only from Octeon II onwards. */
+#define CVMX_L2C_VRT_MAX_VIRTID_ALLOWED ((OCTEON_IS_MODEL(OCTEON_CN63XX)) ? 64 : 0)
+#define CVMX_L2C_VRT_MAX_MEMSZ_ALLOWED ((OCTEON_IS_MODEL(OCTEON_CN63XX)) ? 32 : 0)
+
+union cvmx_l2c_tag {
+ uint64_t u64;
+ struct {
+ uint64_t reserved:28;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:32; /* Phys mem (not all bits valid) */
+ } s;
+};
+
+/* Number of L2C Tag-and-data sections (TADs) that are connected to LMC. */
+#define CVMX_L2C_TADS 1
+
+ /* L2C Performance Counter events. */
+enum cvmx_l2c_event {
+ CVMX_L2C_EVENT_CYCLES = 0,
+ CVMX_L2C_EVENT_INSTRUCTION_MISS = 1,
+ CVMX_L2C_EVENT_INSTRUCTION_HIT = 2,
+ CVMX_L2C_EVENT_DATA_MISS = 3,
+ CVMX_L2C_EVENT_DATA_HIT = 4,
+ CVMX_L2C_EVENT_MISS = 5,
+ CVMX_L2C_EVENT_HIT = 6,
+ CVMX_L2C_EVENT_VICTIM_HIT = 7,
+ CVMX_L2C_EVENT_INDEX_CONFLICT = 8,
+ CVMX_L2C_EVENT_TAG_PROBE = 9,
+ CVMX_L2C_EVENT_TAG_UPDATE = 10,
+ CVMX_L2C_EVENT_TAG_COMPLETE = 11,
+ CVMX_L2C_EVENT_TAG_DIRTY = 12,
+ CVMX_L2C_EVENT_DATA_STORE_NOP = 13,
+ CVMX_L2C_EVENT_DATA_STORE_READ = 14,
+ CVMX_L2C_EVENT_DATA_STORE_WRITE = 15,
+ CVMX_L2C_EVENT_FILL_DATA_VALID = 16,
+ CVMX_L2C_EVENT_WRITE_REQUEST = 17,
+ CVMX_L2C_EVENT_READ_REQUEST = 18,
+ CVMX_L2C_EVENT_WRITE_DATA_VALID = 19,
+ CVMX_L2C_EVENT_XMC_NOP = 20,
+ CVMX_L2C_EVENT_XMC_LDT = 21,
+ CVMX_L2C_EVENT_XMC_LDI = 22,
+ CVMX_L2C_EVENT_XMC_LDD = 23,
+ CVMX_L2C_EVENT_XMC_STF = 24,
+ CVMX_L2C_EVENT_XMC_STT = 25,
+ CVMX_L2C_EVENT_XMC_STP = 26,
+ CVMX_L2C_EVENT_XMC_STC = 27,
+ CVMX_L2C_EVENT_XMC_DWB = 28,
+ CVMX_L2C_EVENT_XMC_PL2 = 29,
+ CVMX_L2C_EVENT_XMC_PSL1 = 30,
+ CVMX_L2C_EVENT_XMC_IOBLD = 31,
+ CVMX_L2C_EVENT_XMC_IOBST = 32,
+ CVMX_L2C_EVENT_XMC_IOBDMA = 33,
+ CVMX_L2C_EVENT_XMC_IOBRSP = 34,
+ CVMX_L2C_EVENT_XMC_BUS_VALID = 35,
+ CVMX_L2C_EVENT_XMC_MEM_DATA = 36,
+ CVMX_L2C_EVENT_XMC_REFL_DATA = 37,
+ CVMX_L2C_EVENT_XMC_IOBRSP_DATA = 38,
+ CVMX_L2C_EVENT_RSC_NOP = 39,
+ CVMX_L2C_EVENT_RSC_STDN = 40,
+ CVMX_L2C_EVENT_RSC_FILL = 41,
+ CVMX_L2C_EVENT_RSC_REFL = 42,
+ CVMX_L2C_EVENT_RSC_STIN = 43,
+ CVMX_L2C_EVENT_RSC_SCIN = 44,
+ CVMX_L2C_EVENT_RSC_SCFL = 45,
+ CVMX_L2C_EVENT_RSC_SCDN = 46,
+ CVMX_L2C_EVENT_RSC_DATA_VALID = 47,
+ CVMX_L2C_EVENT_RSC_VALID_FILL = 48,
+ CVMX_L2C_EVENT_RSC_VALID_STRSP = 49,
+ CVMX_L2C_EVENT_RSC_VALID_REFL = 50,
+ CVMX_L2C_EVENT_LRF_REQ = 51,
+ CVMX_L2C_EVENT_DT_RD_ALLOC = 52,
+ CVMX_L2C_EVENT_DT_WR_INVAL = 53,
+ CVMX_L2C_EVENT_MAX
+};
+
+/* L2C Performance Counter events for Octeon2. */
+enum cvmx_l2c_tad_event {
+ CVMX_L2C_TAD_EVENT_NONE = 0,
+ CVMX_L2C_TAD_EVENT_TAG_HIT = 1,
+ CVMX_L2C_TAD_EVENT_TAG_MISS = 2,
+ CVMX_L2C_TAD_EVENT_TAG_NOALLOC = 3,
+ CVMX_L2C_TAD_EVENT_TAG_VICTIM = 4,
+ CVMX_L2C_TAD_EVENT_SC_FAIL = 5,
+ CVMX_L2C_TAD_EVENT_SC_PASS = 6,
+ CVMX_L2C_TAD_EVENT_LFB_VALID = 7,
+ CVMX_L2C_TAD_EVENT_LFB_WAIT_LFB = 8,
+ CVMX_L2C_TAD_EVENT_LFB_WAIT_VAB = 9,
+ CVMX_L2C_TAD_EVENT_QUAD0_INDEX = 128,
+ CVMX_L2C_TAD_EVENT_QUAD0_READ = 129,
+ CVMX_L2C_TAD_EVENT_QUAD0_BANK = 130,
+ CVMX_L2C_TAD_EVENT_QUAD0_WDAT = 131,
+ CVMX_L2C_TAD_EVENT_QUAD1_INDEX = 144,
+ CVMX_L2C_TAD_EVENT_QUAD1_READ = 145,
+ CVMX_L2C_TAD_EVENT_QUAD1_BANK = 146,
+ CVMX_L2C_TAD_EVENT_QUAD1_WDAT = 147,
+ CVMX_L2C_TAD_EVENT_QUAD2_INDEX = 160,
+ CVMX_L2C_TAD_EVENT_QUAD2_READ = 161,
+ CVMX_L2C_TAD_EVENT_QUAD2_BANK = 162,
+ CVMX_L2C_TAD_EVENT_QUAD2_WDAT = 163,
+ CVMX_L2C_TAD_EVENT_QUAD3_INDEX = 176,
+ CVMX_L2C_TAD_EVENT_QUAD3_READ = 177,
+ CVMX_L2C_TAD_EVENT_QUAD3_BANK = 178,
+ CVMX_L2C_TAD_EVENT_QUAD3_WDAT = 179,
+ CVMX_L2C_TAD_EVENT_MAX
+};
+
+/**
+ * Configure one of the four L2 Cache performance counters to capture event
+ * occurrences.
+ *
+ * @counter: The counter to configure. Range 0..3.
+ * @event: The type of L2 Cache event occurrence to count.
+ * @clear_on_read: When asserted, any read of the performance counter
+ * clears the counter.
+ *
+ * @note The routine does not clear the counter.
+ */
+void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event, uint32_t clear_on_read);
+
+/**
+ * Read the given L2 Cache performance counter. The counter must be configured
+ * before reading, but this routine does not enforce this requirement.
+ *
+ * @counter: The counter to configure. Range 0..3.
+ *
+ * Returns The current counter value.
+ */
+uint64_t cvmx_l2c_read_perf(uint32_t counter);
+
+/**
+ * Return the L2 Cache way partitioning for a given core.
+ *
+ * @core: The core processor of interest.
+ *
+ * Returns The mask specifying the partitioning. 0 bits in mask indicates
+ * the cache 'ways' that a core can evict from.
+ * -1 on error
+ */
+int cvmx_l2c_get_core_way_partition(uint32_t core);
+
+/**
+ * Partitions the L2 cache for a core
+ *
+ * @core: The core that the partitioning applies to.
+ * @mask: The partitioning of the ways expressed as a binary
+ * mask. A 0 bit allows the core to evict cache lines from
+ * a way, while a 1 bit blocks the core from evicting any
+ * lines from that way. There must be at least one allowed
+ * way (0 bit) in the mask.
+ *
+
+ * @note If any ways are blocked for all cores and the HW blocks, then
+ * those ways will never have any cache lines evicted from them.
+ * All cores and the hardware blocks are free to read from all
+ * ways regardless of the partitioning.
+ */
+int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask);
+
+/**
+ * Return the L2 Cache way partitioning for the hw blocks.
+ *
+ * Returns The mask specifying the reserved way. 0 bits in mask indicates
+ * the cache 'ways' that a core can evict from.
+ * -1 on error
+ */
+int cvmx_l2c_get_hw_way_partition(void);
+
+/**
+ * Partitions the L2 cache for the hardware blocks.
+ *
+ * @mask: The partitioning of the ways expressed as a binary
+ * mask. A 0 bit allows the core to evict cache lines from
+ * a way, while a 1 bit blocks the core from evicting any
+ * lines from that way. There must be at least one allowed
+ * way (0 bit) in the mask.
+ *
+
+ * @note If any ways are blocked for all cores and the HW blocks, then
+ * those ways will never have any cache lines evicted from them.
+ * All cores and the hardware blocks are free to read from all
+ * ways regardless of the partitioning.
+ */
+int cvmx_l2c_set_hw_way_partition(uint32_t mask);
+
+
+/**
+ * Locks a line in the L2 cache at the specified physical address
+ *
+ * @addr: physical address of line to lock
+ *
+ * Returns 0 on success,
+ * 1 if line not locked.
+ */
+int cvmx_l2c_lock_line(uint64_t addr);
+
+/**
+ * Locks a specified memory region in the L2 cache.
+ *
+ * Note that if not all lines can be locked, that means that all
+ * but one of the ways (associations) available to the locking
+ * core are locked. Having only 1 association available for
+ * normal caching may have a significant adverse affect on performance.
+ * Care should be taken to ensure that enough of the L2 cache is left
+ * unlocked to allow for normal caching of DRAM.
+ *
+ * @start: Physical address of the start of the region to lock
+ * @len: Length (in bytes) of region to lock
+ *
+ * Returns Number of requested lines that where not locked.
+ * 0 on success (all locked)
+ */
+int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len);
+
+/**
+ * Unlock and flush a cache line from the L2 cache.
+ * IMPORTANT: Must only be run by one core at a time due to use
+ * of L2C debug features.
+ * Note that this function will flush a matching but unlocked cache line.
+ * (If address is not in L2, no lines are flushed.)
+ *
+ * @address: Physical address to unlock
+ *
+ * Returns 0: line not unlocked
+ * 1: line unlocked
+ */
+int cvmx_l2c_unlock_line(uint64_t address);
+
+/**
+ * Unlocks a region of memory that is locked in the L2 cache
+ *
+ * @start: start physical address
+ * @len: length (in bytes) to unlock
+ *
+ * Returns Number of locked lines that the call unlocked
+ */
+int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len);
+
+/**
+ * Read the L2 controller tag for a given location in L2
+ *
+ * @association:
+ * Which association to read line from
+ * @index: Which way to read from.
+ *
+ * Returns l2c tag structure for line requested.
+ */
+union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index);
+
+/* Wrapper providing a deprecated old function name */
+static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, uint32_t index) __attribute__((deprecated));
+static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association, uint32_t index)
+{
+ return cvmx_l2c_get_tag(association, index);
+}
+
+
+/**
+ * Returns the cache index for a given physical address
+ *
+ * @addr: physical address
+ *
+ * Returns L2 cache index
+ */
+uint32_t cvmx_l2c_address_to_index(uint64_t addr);
+
+/**
+ * Flushes (and unlocks) the entire L2 cache.
+ * IMPORTANT: Must only be run by one core at a time due to use
+ * of L2C debug features.
+ */
+void cvmx_l2c_flush(void);
+
+/**
+ *
+ * Returns Returns the size of the L2 cache in bytes,
+ * -1 on error (unrecognized model)
+ */
+int cvmx_l2c_get_cache_size_bytes(void);
+
+/**
+ * Return the number of sets in the L2 Cache
+ *
+ * Returns
+ */
+int cvmx_l2c_get_num_sets(void);
+
+/**
+ * Return log base 2 of the number of sets in the L2 cache
+ * Returns
+ */
+int cvmx_l2c_get_set_bits(void);
+/**
+ * Return the number of associations in the L2 Cache
+ *
+ * Returns
+ */
+int cvmx_l2c_get_num_assoc(void);
+
+/**
+ * Flush a line from the L2 cache
+ * This should only be called from one core at a time, as this routine
+ * sets the core to the 'debug' core in order to flush the line.
+ *
+ * @assoc: Association (or way) to flush
+ * @index: Index to flush
+ */
+void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index);
+
+#endif /* __CVMX_L2C_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
new file mode 100644
index 00000000..60543e0e
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
@@ -0,0 +1,357 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_L2D_DEFS_H__
+#define __CVMX_L2D_DEFS_H__
+
+#define CVMX_L2D_BST0 (CVMX_ADD_IO_SEG(0x0001180080000780ull))
+#define CVMX_L2D_BST1 (CVMX_ADD_IO_SEG(0x0001180080000788ull))
+#define CVMX_L2D_BST2 (CVMX_ADD_IO_SEG(0x0001180080000790ull))
+#define CVMX_L2D_BST3 (CVMX_ADD_IO_SEG(0x0001180080000798ull))
+#define CVMX_L2D_ERR (CVMX_ADD_IO_SEG(0x0001180080000010ull))
+#define CVMX_L2D_FADR (CVMX_ADD_IO_SEG(0x0001180080000018ull))
+#define CVMX_L2D_FSYN0 (CVMX_ADD_IO_SEG(0x0001180080000020ull))
+#define CVMX_L2D_FSYN1 (CVMX_ADD_IO_SEG(0x0001180080000028ull))
+#define CVMX_L2D_FUS0 (CVMX_ADD_IO_SEG(0x00011800800007A0ull))
+#define CVMX_L2D_FUS1 (CVMX_ADD_IO_SEG(0x00011800800007A8ull))
+#define CVMX_L2D_FUS2 (CVMX_ADD_IO_SEG(0x00011800800007B0ull))
+#define CVMX_L2D_FUS3 (CVMX_ADD_IO_SEG(0x00011800800007B8ull))
+
+union cvmx_l2d_bst0 {
+ uint64_t u64;
+ struct cvmx_l2d_bst0_s {
+ uint64_t reserved_35_63:29;
+ uint64_t ftl:1;
+ uint64_t q0stat:34;
+ } s;
+ struct cvmx_l2d_bst0_s cn30xx;
+ struct cvmx_l2d_bst0_s cn31xx;
+ struct cvmx_l2d_bst0_s cn38xx;
+ struct cvmx_l2d_bst0_s cn38xxp2;
+ struct cvmx_l2d_bst0_s cn50xx;
+ struct cvmx_l2d_bst0_s cn52xx;
+ struct cvmx_l2d_bst0_s cn52xxp1;
+ struct cvmx_l2d_bst0_s cn56xx;
+ struct cvmx_l2d_bst0_s cn56xxp1;
+ struct cvmx_l2d_bst0_s cn58xx;
+ struct cvmx_l2d_bst0_s cn58xxp1;
+};
+
+union cvmx_l2d_bst1 {
+ uint64_t u64;
+ struct cvmx_l2d_bst1_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q1stat:34;
+ } s;
+ struct cvmx_l2d_bst1_s cn30xx;
+ struct cvmx_l2d_bst1_s cn31xx;
+ struct cvmx_l2d_bst1_s cn38xx;
+ struct cvmx_l2d_bst1_s cn38xxp2;
+ struct cvmx_l2d_bst1_s cn50xx;
+ struct cvmx_l2d_bst1_s cn52xx;
+ struct cvmx_l2d_bst1_s cn52xxp1;
+ struct cvmx_l2d_bst1_s cn56xx;
+ struct cvmx_l2d_bst1_s cn56xxp1;
+ struct cvmx_l2d_bst1_s cn58xx;
+ struct cvmx_l2d_bst1_s cn58xxp1;
+};
+
+union cvmx_l2d_bst2 {
+ uint64_t u64;
+ struct cvmx_l2d_bst2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q2stat:34;
+ } s;
+ struct cvmx_l2d_bst2_s cn30xx;
+ struct cvmx_l2d_bst2_s cn31xx;
+ struct cvmx_l2d_bst2_s cn38xx;
+ struct cvmx_l2d_bst2_s cn38xxp2;
+ struct cvmx_l2d_bst2_s cn50xx;
+ struct cvmx_l2d_bst2_s cn52xx;
+ struct cvmx_l2d_bst2_s cn52xxp1;
+ struct cvmx_l2d_bst2_s cn56xx;
+ struct cvmx_l2d_bst2_s cn56xxp1;
+ struct cvmx_l2d_bst2_s cn58xx;
+ struct cvmx_l2d_bst2_s cn58xxp1;
+};
+
+union cvmx_l2d_bst3 {
+ uint64_t u64;
+ struct cvmx_l2d_bst3_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q3stat:34;
+ } s;
+ struct cvmx_l2d_bst3_s cn30xx;
+ struct cvmx_l2d_bst3_s cn31xx;
+ struct cvmx_l2d_bst3_s cn38xx;
+ struct cvmx_l2d_bst3_s cn38xxp2;
+ struct cvmx_l2d_bst3_s cn50xx;
+ struct cvmx_l2d_bst3_s cn52xx;
+ struct cvmx_l2d_bst3_s cn52xxp1;
+ struct cvmx_l2d_bst3_s cn56xx;
+ struct cvmx_l2d_bst3_s cn56xxp1;
+ struct cvmx_l2d_bst3_s cn58xx;
+ struct cvmx_l2d_bst3_s cn58xxp1;
+};
+
+union cvmx_l2d_err {
+ uint64_t u64;
+ struct cvmx_l2d_err_s {
+ uint64_t reserved_6_63:58;
+ uint64_t bmhclsel:1;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } s;
+ struct cvmx_l2d_err_s cn30xx;
+ struct cvmx_l2d_err_s cn31xx;
+ struct cvmx_l2d_err_s cn38xx;
+ struct cvmx_l2d_err_s cn38xxp2;
+ struct cvmx_l2d_err_s cn50xx;
+ struct cvmx_l2d_err_s cn52xx;
+ struct cvmx_l2d_err_s cn52xxp1;
+ struct cvmx_l2d_err_s cn56xx;
+ struct cvmx_l2d_err_s cn56xxp1;
+ struct cvmx_l2d_err_s cn58xx;
+ struct cvmx_l2d_err_s cn58xxp1;
+};
+
+union cvmx_l2d_fadr {
+ uint64_t u64;
+ struct cvmx_l2d_fadr_s {
+ uint64_t reserved_19_63:45;
+ uint64_t fadru:1;
+ uint64_t fowmsk:4;
+ uint64_t fset:3;
+ uint64_t fadr:11;
+ } s;
+ struct cvmx_l2d_fadr_cn30xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t reserved_13_13:1;
+ uint64_t fset:2;
+ uint64_t reserved_9_10:2;
+ uint64_t fadr:9;
+ } cn30xx;
+ struct cvmx_l2d_fadr_cn31xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t reserved_13_13:1;
+ uint64_t fset:2;
+ uint64_t reserved_10_10:1;
+ uint64_t fadr:10;
+ } cn31xx;
+ struct cvmx_l2d_fadr_cn38xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t fset:3;
+ uint64_t fadr:11;
+ } cn38xx;
+ struct cvmx_l2d_fadr_cn38xx cn38xxp2;
+ struct cvmx_l2d_fadr_cn50xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t fset:3;
+ uint64_t reserved_8_10:3;
+ uint64_t fadr:8;
+ } cn50xx;
+ struct cvmx_l2d_fadr_cn52xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t fset:3;
+ uint64_t reserved_10_10:1;
+ uint64_t fadr:10;
+ } cn52xx;
+ struct cvmx_l2d_fadr_cn52xx cn52xxp1;
+ struct cvmx_l2d_fadr_s cn56xx;
+ struct cvmx_l2d_fadr_s cn56xxp1;
+ struct cvmx_l2d_fadr_s cn58xx;
+ struct cvmx_l2d_fadr_s cn58xxp1;
+};
+
+union cvmx_l2d_fsyn0 {
+ uint64_t u64;
+ struct cvmx_l2d_fsyn0_s {
+ uint64_t reserved_20_63:44;
+ uint64_t fsyn_ow1:10;
+ uint64_t fsyn_ow0:10;
+ } s;
+ struct cvmx_l2d_fsyn0_s cn30xx;
+ struct cvmx_l2d_fsyn0_s cn31xx;
+ struct cvmx_l2d_fsyn0_s cn38xx;
+ struct cvmx_l2d_fsyn0_s cn38xxp2;
+ struct cvmx_l2d_fsyn0_s cn50xx;
+ struct cvmx_l2d_fsyn0_s cn52xx;
+ struct cvmx_l2d_fsyn0_s cn52xxp1;
+ struct cvmx_l2d_fsyn0_s cn56xx;
+ struct cvmx_l2d_fsyn0_s cn56xxp1;
+ struct cvmx_l2d_fsyn0_s cn58xx;
+ struct cvmx_l2d_fsyn0_s cn58xxp1;
+};
+
+union cvmx_l2d_fsyn1 {
+ uint64_t u64;
+ struct cvmx_l2d_fsyn1_s {
+ uint64_t reserved_20_63:44;
+ uint64_t fsyn_ow3:10;
+ uint64_t fsyn_ow2:10;
+ } s;
+ struct cvmx_l2d_fsyn1_s cn30xx;
+ struct cvmx_l2d_fsyn1_s cn31xx;
+ struct cvmx_l2d_fsyn1_s cn38xx;
+ struct cvmx_l2d_fsyn1_s cn38xxp2;
+ struct cvmx_l2d_fsyn1_s cn50xx;
+ struct cvmx_l2d_fsyn1_s cn52xx;
+ struct cvmx_l2d_fsyn1_s cn52xxp1;
+ struct cvmx_l2d_fsyn1_s cn56xx;
+ struct cvmx_l2d_fsyn1_s cn56xxp1;
+ struct cvmx_l2d_fsyn1_s cn58xx;
+ struct cvmx_l2d_fsyn1_s cn58xxp1;
+};
+
+union cvmx_l2d_fus0 {
+ uint64_t u64;
+ struct cvmx_l2d_fus0_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q0fus:34;
+ } s;
+ struct cvmx_l2d_fus0_s cn30xx;
+ struct cvmx_l2d_fus0_s cn31xx;
+ struct cvmx_l2d_fus0_s cn38xx;
+ struct cvmx_l2d_fus0_s cn38xxp2;
+ struct cvmx_l2d_fus0_s cn50xx;
+ struct cvmx_l2d_fus0_s cn52xx;
+ struct cvmx_l2d_fus0_s cn52xxp1;
+ struct cvmx_l2d_fus0_s cn56xx;
+ struct cvmx_l2d_fus0_s cn56xxp1;
+ struct cvmx_l2d_fus0_s cn58xx;
+ struct cvmx_l2d_fus0_s cn58xxp1;
+};
+
+union cvmx_l2d_fus1 {
+ uint64_t u64;
+ struct cvmx_l2d_fus1_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q1fus:34;
+ } s;
+ struct cvmx_l2d_fus1_s cn30xx;
+ struct cvmx_l2d_fus1_s cn31xx;
+ struct cvmx_l2d_fus1_s cn38xx;
+ struct cvmx_l2d_fus1_s cn38xxp2;
+ struct cvmx_l2d_fus1_s cn50xx;
+ struct cvmx_l2d_fus1_s cn52xx;
+ struct cvmx_l2d_fus1_s cn52xxp1;
+ struct cvmx_l2d_fus1_s cn56xx;
+ struct cvmx_l2d_fus1_s cn56xxp1;
+ struct cvmx_l2d_fus1_s cn58xx;
+ struct cvmx_l2d_fus1_s cn58xxp1;
+};
+
+union cvmx_l2d_fus2 {
+ uint64_t u64;
+ struct cvmx_l2d_fus2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q2fus:34;
+ } s;
+ struct cvmx_l2d_fus2_s cn30xx;
+ struct cvmx_l2d_fus2_s cn31xx;
+ struct cvmx_l2d_fus2_s cn38xx;
+ struct cvmx_l2d_fus2_s cn38xxp2;
+ struct cvmx_l2d_fus2_s cn50xx;
+ struct cvmx_l2d_fus2_s cn52xx;
+ struct cvmx_l2d_fus2_s cn52xxp1;
+ struct cvmx_l2d_fus2_s cn56xx;
+ struct cvmx_l2d_fus2_s cn56xxp1;
+ struct cvmx_l2d_fus2_s cn58xx;
+ struct cvmx_l2d_fus2_s cn58xxp1;
+};
+
+union cvmx_l2d_fus3 {
+ uint64_t u64;
+ struct cvmx_l2d_fus3_s {
+ uint64_t reserved_40_63:24;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_34_36:3;
+ uint64_t q3fus:34;
+ } s;
+ struct cvmx_l2d_fus3_cn30xx {
+ uint64_t reserved_35_63:29;
+ uint64_t crip_64k:1;
+ uint64_t q3fus:34;
+ } cn30xx;
+ struct cvmx_l2d_fus3_cn31xx {
+ uint64_t reserved_35_63:29;
+ uint64_t crip_128k:1;
+ uint64_t q3fus:34;
+ } cn31xx;
+ struct cvmx_l2d_fus3_cn38xx {
+ uint64_t reserved_36_63:28;
+ uint64_t crip_256k:1;
+ uint64_t crip_512k:1;
+ uint64_t q3fus:34;
+ } cn38xx;
+ struct cvmx_l2d_fus3_cn38xx cn38xxp2;
+ struct cvmx_l2d_fus3_cn50xx {
+ uint64_t reserved_40_63:24;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_36_36:1;
+ uint64_t crip_32k:1;
+ uint64_t crip_64k:1;
+ uint64_t q3fus:34;
+ } cn50xx;
+ struct cvmx_l2d_fus3_cn52xx {
+ uint64_t reserved_40_63:24;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_36_36:1;
+ uint64_t crip_128k:1;
+ uint64_t crip_256k:1;
+ uint64_t q3fus:34;
+ } cn52xx;
+ struct cvmx_l2d_fus3_cn52xx cn52xxp1;
+ struct cvmx_l2d_fus3_cn56xx {
+ uint64_t reserved_40_63:24;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_36_36:1;
+ uint64_t crip_512k:1;
+ uint64_t crip_1024k:1;
+ uint64_t q3fus:34;
+ } cn56xx;
+ struct cvmx_l2d_fus3_cn56xx cn56xxp1;
+ struct cvmx_l2d_fus3_cn58xx {
+ uint64_t reserved_39_63:25;
+ uint64_t ema_ctl:2;
+ uint64_t reserved_36_36:1;
+ uint64_t crip_512k:1;
+ uint64_t crip_1024k:1;
+ uint64_t q3fus:34;
+ } cn58xx;
+ struct cvmx_l2d_fus3_cn58xx cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2t-defs.h b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
new file mode 100644
index 00000000..873968f5
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
@@ -0,0 +1,140 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_L2T_DEFS_H__
+#define __CVMX_L2T_DEFS_H__
+
+#define CVMX_L2T_ERR (CVMX_ADD_IO_SEG(0x0001180080000008ull))
+
+union cvmx_l2t_err {
+ uint64_t u64;
+ struct cvmx_l2t_err_s {
+ uint64_t reserved_29_63:35;
+ uint64_t fadru:1;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t fset:3;
+ uint64_t fadr:10;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } s;
+ struct cvmx_l2t_err_cn30xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t reserved_23_23:1;
+ uint64_t fset:2;
+ uint64_t reserved_19_20:2;
+ uint64_t fadr:8;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn30xx;
+ struct cvmx_l2t_err_cn31xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t reserved_23_23:1;
+ uint64_t fset:2;
+ uint64_t reserved_20_20:1;
+ uint64_t fadr:9;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn31xx;
+ struct cvmx_l2t_err_cn38xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t fset:3;
+ uint64_t fadr:10;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn38xx;
+ struct cvmx_l2t_err_cn38xx cn38xxp2;
+ struct cvmx_l2t_err_cn50xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t fset:3;
+ uint64_t reserved_18_20:3;
+ uint64_t fadr:7;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn50xx;
+ struct cvmx_l2t_err_cn52xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t fset:3;
+ uint64_t reserved_20_20:1;
+ uint64_t fadr:9;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn52xx;
+ struct cvmx_l2t_err_cn52xx cn52xxp1;
+ struct cvmx_l2t_err_s cn56xx;
+ struct cvmx_l2t_err_s cn56xxp1;
+ struct cvmx_l2t_err_s cn58xx;
+ struct cvmx_l2t_err_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-led-defs.h b/arch/mips/include/asm/octeon/cvmx-led-defs.h
new file mode 100644
index 00000000..e25173bb
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-led-defs.h
@@ -0,0 +1,227 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_LED_DEFS_H__
+#define __CVMX_LED_DEFS_H__
+
+#define CVMX_LED_BLINK (CVMX_ADD_IO_SEG(0x0001180000001A48ull))
+#define CVMX_LED_CLK_PHASE (CVMX_ADD_IO_SEG(0x0001180000001A08ull))
+#define CVMX_LED_CYLON (CVMX_ADD_IO_SEG(0x0001180000001AF8ull))
+#define CVMX_LED_DBG (CVMX_ADD_IO_SEG(0x0001180000001A18ull))
+#define CVMX_LED_EN (CVMX_ADD_IO_SEG(0x0001180000001A00ull))
+#define CVMX_LED_POLARITY (CVMX_ADD_IO_SEG(0x0001180000001A50ull))
+#define CVMX_LED_PRT (CVMX_ADD_IO_SEG(0x0001180000001A10ull))
+#define CVMX_LED_PRT_FMT (CVMX_ADD_IO_SEG(0x0001180000001A30ull))
+#define CVMX_LED_PRT_STATUSX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A80ull) + ((offset) & 7) * 8)
+#define CVMX_LED_UDD_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A20ull) + ((offset) & 1) * 8)
+#define CVMX_LED_UDD_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001A38ull) + ((offset) & 1) * 8)
+#define CVMX_LED_UDD_DAT_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001180000001AC8ull) + ((offset) & 1) * 16)
+#define CVMX_LED_UDD_DAT_SETX(offset) (CVMX_ADD_IO_SEG(0x0001180000001AC0ull) + ((offset) & 1) * 16)
+
+union cvmx_led_blink {
+ uint64_t u64;
+ struct cvmx_led_blink_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rate:8;
+ } s;
+ struct cvmx_led_blink_s cn38xx;
+ struct cvmx_led_blink_s cn38xxp2;
+ struct cvmx_led_blink_s cn56xx;
+ struct cvmx_led_blink_s cn56xxp1;
+ struct cvmx_led_blink_s cn58xx;
+ struct cvmx_led_blink_s cn58xxp1;
+};
+
+union cvmx_led_clk_phase {
+ uint64_t u64;
+ struct cvmx_led_clk_phase_s {
+ uint64_t reserved_7_63:57;
+ uint64_t phase:7;
+ } s;
+ struct cvmx_led_clk_phase_s cn38xx;
+ struct cvmx_led_clk_phase_s cn38xxp2;
+ struct cvmx_led_clk_phase_s cn56xx;
+ struct cvmx_led_clk_phase_s cn56xxp1;
+ struct cvmx_led_clk_phase_s cn58xx;
+ struct cvmx_led_clk_phase_s cn58xxp1;
+};
+
+union cvmx_led_cylon {
+ uint64_t u64;
+ struct cvmx_led_cylon_s {
+ uint64_t reserved_16_63:48;
+ uint64_t rate:16;
+ } s;
+ struct cvmx_led_cylon_s cn38xx;
+ struct cvmx_led_cylon_s cn38xxp2;
+ struct cvmx_led_cylon_s cn56xx;
+ struct cvmx_led_cylon_s cn56xxp1;
+ struct cvmx_led_cylon_s cn58xx;
+ struct cvmx_led_cylon_s cn58xxp1;
+};
+
+union cvmx_led_dbg {
+ uint64_t u64;
+ struct cvmx_led_dbg_s {
+ uint64_t reserved_1_63:63;
+ uint64_t dbg_en:1;
+ } s;
+ struct cvmx_led_dbg_s cn38xx;
+ struct cvmx_led_dbg_s cn38xxp2;
+ struct cvmx_led_dbg_s cn56xx;
+ struct cvmx_led_dbg_s cn56xxp1;
+ struct cvmx_led_dbg_s cn58xx;
+ struct cvmx_led_dbg_s cn58xxp1;
+};
+
+union cvmx_led_en {
+ uint64_t u64;
+ struct cvmx_led_en_s {
+ uint64_t reserved_1_63:63;
+ uint64_t en:1;
+ } s;
+ struct cvmx_led_en_s cn38xx;
+ struct cvmx_led_en_s cn38xxp2;
+ struct cvmx_led_en_s cn56xx;
+ struct cvmx_led_en_s cn56xxp1;
+ struct cvmx_led_en_s cn58xx;
+ struct cvmx_led_en_s cn58xxp1;
+};
+
+union cvmx_led_polarity {
+ uint64_t u64;
+ struct cvmx_led_polarity_s {
+ uint64_t reserved_1_63:63;
+ uint64_t polarity:1;
+ } s;
+ struct cvmx_led_polarity_s cn38xx;
+ struct cvmx_led_polarity_s cn38xxp2;
+ struct cvmx_led_polarity_s cn56xx;
+ struct cvmx_led_polarity_s cn56xxp1;
+ struct cvmx_led_polarity_s cn58xx;
+ struct cvmx_led_polarity_s cn58xxp1;
+};
+
+union cvmx_led_prt {
+ uint64_t u64;
+ struct cvmx_led_prt_s {
+ uint64_t reserved_8_63:56;
+ uint64_t prt_en:8;
+ } s;
+ struct cvmx_led_prt_s cn38xx;
+ struct cvmx_led_prt_s cn38xxp2;
+ struct cvmx_led_prt_s cn56xx;
+ struct cvmx_led_prt_s cn56xxp1;
+ struct cvmx_led_prt_s cn58xx;
+ struct cvmx_led_prt_s cn58xxp1;
+};
+
+union cvmx_led_prt_fmt {
+ uint64_t u64;
+ struct cvmx_led_prt_fmt_s {
+ uint64_t reserved_4_63:60;
+ uint64_t format:4;
+ } s;
+ struct cvmx_led_prt_fmt_s cn38xx;
+ struct cvmx_led_prt_fmt_s cn38xxp2;
+ struct cvmx_led_prt_fmt_s cn56xx;
+ struct cvmx_led_prt_fmt_s cn56xxp1;
+ struct cvmx_led_prt_fmt_s cn58xx;
+ struct cvmx_led_prt_fmt_s cn58xxp1;
+};
+
+union cvmx_led_prt_statusx {
+ uint64_t u64;
+ struct cvmx_led_prt_statusx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t status:6;
+ } s;
+ struct cvmx_led_prt_statusx_s cn38xx;
+ struct cvmx_led_prt_statusx_s cn38xxp2;
+ struct cvmx_led_prt_statusx_s cn56xx;
+ struct cvmx_led_prt_statusx_s cn56xxp1;
+ struct cvmx_led_prt_statusx_s cn58xx;
+ struct cvmx_led_prt_statusx_s cn58xxp1;
+};
+
+union cvmx_led_udd_cntx {
+ uint64_t u64;
+ struct cvmx_led_udd_cntx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t cnt:6;
+ } s;
+ struct cvmx_led_udd_cntx_s cn38xx;
+ struct cvmx_led_udd_cntx_s cn38xxp2;
+ struct cvmx_led_udd_cntx_s cn56xx;
+ struct cvmx_led_udd_cntx_s cn56xxp1;
+ struct cvmx_led_udd_cntx_s cn58xx;
+ struct cvmx_led_udd_cntx_s cn58xxp1;
+};
+
+union cvmx_led_udd_datx {
+ uint64_t u64;
+ struct cvmx_led_udd_datx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t dat:32;
+ } s;
+ struct cvmx_led_udd_datx_s cn38xx;
+ struct cvmx_led_udd_datx_s cn38xxp2;
+ struct cvmx_led_udd_datx_s cn56xx;
+ struct cvmx_led_udd_datx_s cn56xxp1;
+ struct cvmx_led_udd_datx_s cn58xx;
+ struct cvmx_led_udd_datx_s cn58xxp1;
+};
+
+union cvmx_led_udd_dat_clrx {
+ uint64_t u64;
+ struct cvmx_led_udd_dat_clrx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t clr:32;
+ } s;
+ struct cvmx_led_udd_dat_clrx_s cn38xx;
+ struct cvmx_led_udd_dat_clrx_s cn38xxp2;
+ struct cvmx_led_udd_dat_clrx_s cn56xx;
+ struct cvmx_led_udd_dat_clrx_s cn56xxp1;
+ struct cvmx_led_udd_dat_clrx_s cn58xx;
+ struct cvmx_led_udd_dat_clrx_s cn58xxp1;
+};
+
+union cvmx_led_udd_dat_setx {
+ uint64_t u64;
+ struct cvmx_led_udd_dat_setx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t set:32;
+ } s;
+ struct cvmx_led_udd_dat_setx_s cn38xx;
+ struct cvmx_led_udd_dat_setx_s cn38xxp2;
+ struct cvmx_led_udd_dat_setx_s cn56xx;
+ struct cvmx_led_udd_dat_setx_s cn56xxp1;
+ struct cvmx_led_udd_dat_setx_s cn58xx;
+ struct cvmx_led_udd_dat_setx_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-mio-defs.h b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
new file mode 100644
index 00000000..52b14a33
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
@@ -0,0 +1,2371 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_MIO_DEFS_H__
+#define __CVMX_MIO_DEFS_H__
+
+#define CVMX_MIO_BOOT_BIST_STAT (CVMX_ADD_IO_SEG(0x00011800000000F8ull))
+#define CVMX_MIO_BOOT_COMP (CVMX_ADD_IO_SEG(0x00011800000000B8ull))
+#define CVMX_MIO_BOOT_DMA_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000100ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_INTX(offset) (CVMX_ADD_IO_SEG(0x0001180000000138ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_INT_ENX(offset) (CVMX_ADD_IO_SEG(0x0001180000000150ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_DMA_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000120ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_BOOT_ERR (CVMX_ADD_IO_SEG(0x00011800000000A0ull))
+#define CVMX_MIO_BOOT_INT (CVMX_ADD_IO_SEG(0x00011800000000A8ull))
+#define CVMX_MIO_BOOT_LOC_ADR (CVMX_ADD_IO_SEG(0x0001180000000090ull))
+#define CVMX_MIO_BOOT_LOC_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000080ull) + ((offset) & 1) * 8)
+#define CVMX_MIO_BOOT_LOC_DAT (CVMX_ADD_IO_SEG(0x0001180000000098ull))
+#define CVMX_MIO_BOOT_PIN_DEFS (CVMX_ADD_IO_SEG(0x00011800000000C0ull))
+#define CVMX_MIO_BOOT_REG_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000000ull) + ((offset) & 7) * 8)
+#define CVMX_MIO_BOOT_REG_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000040ull) + ((offset) & 7) * 8)
+#define CVMX_MIO_BOOT_THR (CVMX_ADD_IO_SEG(0x00011800000000B0ull))
+#define CVMX_MIO_FUS_BNK_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001520ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_FUS_DAT0 (CVMX_ADD_IO_SEG(0x0001180000001400ull))
+#define CVMX_MIO_FUS_DAT1 (CVMX_ADD_IO_SEG(0x0001180000001408ull))
+#define CVMX_MIO_FUS_DAT2 (CVMX_ADD_IO_SEG(0x0001180000001410ull))
+#define CVMX_MIO_FUS_DAT3 (CVMX_ADD_IO_SEG(0x0001180000001418ull))
+#define CVMX_MIO_FUS_EMA (CVMX_ADD_IO_SEG(0x0001180000001550ull))
+#define CVMX_MIO_FUS_PDF (CVMX_ADD_IO_SEG(0x0001180000001420ull))
+#define CVMX_MIO_FUS_PLL (CVMX_ADD_IO_SEG(0x0001180000001580ull))
+#define CVMX_MIO_FUS_PROG (CVMX_ADD_IO_SEG(0x0001180000001510ull))
+#define CVMX_MIO_FUS_PROG_TIMES (CVMX_ADD_IO_SEG(0x0001180000001518ull))
+#define CVMX_MIO_FUS_RCMD (CVMX_ADD_IO_SEG(0x0001180000001500ull))
+#define CVMX_MIO_FUS_READ_TIMES (CVMX_ADD_IO_SEG(0x0001180000001570ull))
+#define CVMX_MIO_FUS_REPAIR_RES0 (CVMX_ADD_IO_SEG(0x0001180000001558ull))
+#define CVMX_MIO_FUS_REPAIR_RES1 (CVMX_ADD_IO_SEG(0x0001180000001560ull))
+#define CVMX_MIO_FUS_REPAIR_RES2 (CVMX_ADD_IO_SEG(0x0001180000001568ull))
+#define CVMX_MIO_FUS_SPR_REPAIR_RES (CVMX_ADD_IO_SEG(0x0001180000001548ull))
+#define CVMX_MIO_FUS_SPR_REPAIR_SUM (CVMX_ADD_IO_SEG(0x0001180000001540ull))
+#define CVMX_MIO_FUS_UNLOCK (CVMX_ADD_IO_SEG(0x0001180000001578ull))
+#define CVMX_MIO_FUS_WADR (CVMX_ADD_IO_SEG(0x0001180000001508ull))
+#define CVMX_MIO_GPIO_COMP (CVMX_ADD_IO_SEG(0x00011800000000C8ull))
+#define CVMX_MIO_NDF_DMA_CFG (CVMX_ADD_IO_SEG(0x0001180000000168ull))
+#define CVMX_MIO_NDF_DMA_INT (CVMX_ADD_IO_SEG(0x0001180000000170ull))
+#define CVMX_MIO_NDF_DMA_INT_EN (CVMX_ADD_IO_SEG(0x0001180000000178ull))
+#define CVMX_MIO_PLL_CTL (CVMX_ADD_IO_SEG(0x0001180000001448ull))
+#define CVMX_MIO_PLL_SETTING (CVMX_ADD_IO_SEG(0x0001180000001440ull))
+#define CVMX_MIO_PTP_CLOCK_CFG (CVMX_ADD_IO_SEG(0x0001070000000F00ull))
+#define CVMX_MIO_PTP_CLOCK_COMP (CVMX_ADD_IO_SEG(0x0001070000000F18ull))
+#define CVMX_MIO_PTP_CLOCK_HI (CVMX_ADD_IO_SEG(0x0001070000000F10ull))
+#define CVMX_MIO_PTP_CLOCK_LO (CVMX_ADD_IO_SEG(0x0001070000000F08ull))
+#define CVMX_MIO_PTP_EVT_CNT (CVMX_ADD_IO_SEG(0x0001070000000F28ull))
+#define CVMX_MIO_PTP_TIMESTAMP (CVMX_ADD_IO_SEG(0x0001070000000F20ull))
+#define CVMX_MIO_RST_BOOT (CVMX_ADD_IO_SEG(0x0001180000001600ull))
+#define CVMX_MIO_RST_CFG (CVMX_ADD_IO_SEG(0x0001180000001610ull))
+#define CVMX_MIO_RST_CTLX(offset) (CVMX_ADD_IO_SEG(0x0001180000001618ull) + ((offset) & 1) * 8)
+#define CVMX_MIO_RST_DELAY (CVMX_ADD_IO_SEG(0x0001180000001608ull))
+#define CVMX_MIO_RST_INT (CVMX_ADD_IO_SEG(0x0001180000001628ull))
+#define CVMX_MIO_RST_INT_EN (CVMX_ADD_IO_SEG(0x0001180000001630ull))
+#define CVMX_MIO_TWSX_INT(offset) (CVMX_ADD_IO_SEG(0x0001180000001010ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_SW_TWSI(offset) (CVMX_ADD_IO_SEG(0x0001180000001000ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_SW_TWSI_EXT(offset) (CVMX_ADD_IO_SEG(0x0001180000001018ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_TWSX_TWSI_SW(offset) (CVMX_ADD_IO_SEG(0x0001180000001008ull) + ((offset) & 1) * 512)
+#define CVMX_MIO_UART2_DLH (CVMX_ADD_IO_SEG(0x0001180000000488ull))
+#define CVMX_MIO_UART2_DLL (CVMX_ADD_IO_SEG(0x0001180000000480ull))
+#define CVMX_MIO_UART2_FAR (CVMX_ADD_IO_SEG(0x0001180000000520ull))
+#define CVMX_MIO_UART2_FCR (CVMX_ADD_IO_SEG(0x0001180000000450ull))
+#define CVMX_MIO_UART2_HTX (CVMX_ADD_IO_SEG(0x0001180000000708ull))
+#define CVMX_MIO_UART2_IER (CVMX_ADD_IO_SEG(0x0001180000000408ull))
+#define CVMX_MIO_UART2_IIR (CVMX_ADD_IO_SEG(0x0001180000000410ull))
+#define CVMX_MIO_UART2_LCR (CVMX_ADD_IO_SEG(0x0001180000000418ull))
+#define CVMX_MIO_UART2_LSR (CVMX_ADD_IO_SEG(0x0001180000000428ull))
+#define CVMX_MIO_UART2_MCR (CVMX_ADD_IO_SEG(0x0001180000000420ull))
+#define CVMX_MIO_UART2_MSR (CVMX_ADD_IO_SEG(0x0001180000000430ull))
+#define CVMX_MIO_UART2_RBR (CVMX_ADD_IO_SEG(0x0001180000000400ull))
+#define CVMX_MIO_UART2_RFL (CVMX_ADD_IO_SEG(0x0001180000000608ull))
+#define CVMX_MIO_UART2_RFW (CVMX_ADD_IO_SEG(0x0001180000000530ull))
+#define CVMX_MIO_UART2_SBCR (CVMX_ADD_IO_SEG(0x0001180000000620ull))
+#define CVMX_MIO_UART2_SCR (CVMX_ADD_IO_SEG(0x0001180000000438ull))
+#define CVMX_MIO_UART2_SFE (CVMX_ADD_IO_SEG(0x0001180000000630ull))
+#define CVMX_MIO_UART2_SRR (CVMX_ADD_IO_SEG(0x0001180000000610ull))
+#define CVMX_MIO_UART2_SRT (CVMX_ADD_IO_SEG(0x0001180000000638ull))
+#define CVMX_MIO_UART2_SRTS (CVMX_ADD_IO_SEG(0x0001180000000618ull))
+#define CVMX_MIO_UART2_STT (CVMX_ADD_IO_SEG(0x0001180000000700ull))
+#define CVMX_MIO_UART2_TFL (CVMX_ADD_IO_SEG(0x0001180000000600ull))
+#define CVMX_MIO_UART2_TFR (CVMX_ADD_IO_SEG(0x0001180000000528ull))
+#define CVMX_MIO_UART2_THR (CVMX_ADD_IO_SEG(0x0001180000000440ull))
+#define CVMX_MIO_UART2_USR (CVMX_ADD_IO_SEG(0x0001180000000538ull))
+#define CVMX_MIO_UARTX_DLH(offset) (CVMX_ADD_IO_SEG(0x0001180000000888ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_DLL(offset) (CVMX_ADD_IO_SEG(0x0001180000000880ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_FAR(offset) (CVMX_ADD_IO_SEG(0x0001180000000920ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_FCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000850ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_HTX(offset) (CVMX_ADD_IO_SEG(0x0001180000000B08ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_IER(offset) (CVMX_ADD_IO_SEG(0x0001180000000808ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_IIR(offset) (CVMX_ADD_IO_SEG(0x0001180000000810ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_LCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000818ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_LSR(offset) (CVMX_ADD_IO_SEG(0x0001180000000828ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_MCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000820ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_MSR(offset) (CVMX_ADD_IO_SEG(0x0001180000000830ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RBR(offset) (CVMX_ADD_IO_SEG(0x0001180000000800ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RFL(offset) (CVMX_ADD_IO_SEG(0x0001180000000A08ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_RFW(offset) (CVMX_ADD_IO_SEG(0x0001180000000930ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SBCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000A20ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SCR(offset) (CVMX_ADD_IO_SEG(0x0001180000000838ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SFE(offset) (CVMX_ADD_IO_SEG(0x0001180000000A30ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRR(offset) (CVMX_ADD_IO_SEG(0x0001180000000A10ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRT(offset) (CVMX_ADD_IO_SEG(0x0001180000000A38ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_SRTS(offset) (CVMX_ADD_IO_SEG(0x0001180000000A18ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_STT(offset) (CVMX_ADD_IO_SEG(0x0001180000000B00ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_TFL(offset) (CVMX_ADD_IO_SEG(0x0001180000000A00ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_TFR(offset) (CVMX_ADD_IO_SEG(0x0001180000000928ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_THR(offset) (CVMX_ADD_IO_SEG(0x0001180000000840ull) + ((offset) & 1) * 1024)
+#define CVMX_MIO_UARTX_USR(offset) (CVMX_ADD_IO_SEG(0x0001180000000938ull) + ((offset) & 1) * 1024)
+
+union cvmx_mio_boot_bist_stat {
+ uint64_t u64;
+ struct cvmx_mio_boot_bist_stat_s {
+ uint64_t reserved_0_63:64;
+ } s;
+ struct cvmx_mio_boot_bist_stat_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t ncbo_1:1;
+ uint64_t ncbo_0:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn30xx;
+ struct cvmx_mio_boot_bist_stat_cn30xx cn31xx;
+ struct cvmx_mio_boot_bist_stat_cn38xx {
+ uint64_t reserved_3_63:61;
+ uint64_t ncbo_0:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn38xx;
+ struct cvmx_mio_boot_bist_stat_cn38xx cn38xxp2;
+ struct cvmx_mio_boot_bist_stat_cn50xx {
+ uint64_t reserved_6_63:58;
+ uint64_t pcm_1:1;
+ uint64_t pcm_0:1;
+ uint64_t ncbo_1:1;
+ uint64_t ncbo_0:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn50xx;
+ struct cvmx_mio_boot_bist_stat_cn52xx {
+ uint64_t reserved_6_63:58;
+ uint64_t ndf:2;
+ uint64_t ncbo_0:1;
+ uint64_t dma:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn52xx;
+ struct cvmx_mio_boot_bist_stat_cn52xxp1 {
+ uint64_t reserved_4_63:60;
+ uint64_t ncbo_0:1;
+ uint64_t dma:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn52xxp1;
+ struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xx;
+ struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xxp1;
+ struct cvmx_mio_boot_bist_stat_cn38xx cn58xx;
+ struct cvmx_mio_boot_bist_stat_cn38xx cn58xxp1;
+ struct cvmx_mio_boot_bist_stat_cn63xx {
+ uint64_t reserved_9_63:55;
+ uint64_t stat:9;
+ } cn63xx;
+ struct cvmx_mio_boot_bist_stat_cn63xx cn63xxp1;
+};
+
+union cvmx_mio_boot_comp {
+ uint64_t u64;
+ struct cvmx_mio_boot_comp_s {
+ uint64_t reserved_0_63:64;
+ } s;
+ struct cvmx_mio_boot_comp_cn50xx {
+ uint64_t reserved_10_63:54;
+ uint64_t pctl:5;
+ uint64_t nctl:5;
+ } cn50xx;
+ struct cvmx_mio_boot_comp_cn50xx cn52xx;
+ struct cvmx_mio_boot_comp_cn50xx cn52xxp1;
+ struct cvmx_mio_boot_comp_cn50xx cn56xx;
+ struct cvmx_mio_boot_comp_cn50xx cn56xxp1;
+ struct cvmx_mio_boot_comp_cn63xx {
+ uint64_t reserved_12_63:52;
+ uint64_t pctl:6;
+ uint64_t nctl:6;
+ } cn63xx;
+ struct cvmx_mio_boot_comp_cn63xx cn63xxp1;
+};
+
+union cvmx_mio_boot_dma_cfgx {
+ uint64_t u64;
+ struct cvmx_mio_boot_dma_cfgx_s {
+ uint64_t en:1;
+ uint64_t rw:1;
+ uint64_t clr:1;
+ uint64_t reserved_60_60:1;
+ uint64_t swap32:1;
+ uint64_t swap16:1;
+ uint64_t swap8:1;
+ uint64_t endian:1;
+ uint64_t size:20;
+ uint64_t adr:36;
+ } s;
+ struct cvmx_mio_boot_dma_cfgx_s cn52xx;
+ struct cvmx_mio_boot_dma_cfgx_s cn52xxp1;
+ struct cvmx_mio_boot_dma_cfgx_s cn56xx;
+ struct cvmx_mio_boot_dma_cfgx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_cfgx_s cn63xx;
+ struct cvmx_mio_boot_dma_cfgx_s cn63xxp1;
+};
+
+union cvmx_mio_boot_dma_intx {
+ uint64_t u64;
+ struct cvmx_mio_boot_dma_intx_s {
+ uint64_t reserved_2_63:62;
+ uint64_t dmarq:1;
+ uint64_t done:1;
+ } s;
+ struct cvmx_mio_boot_dma_intx_s cn52xx;
+ struct cvmx_mio_boot_dma_intx_s cn52xxp1;
+ struct cvmx_mio_boot_dma_intx_s cn56xx;
+ struct cvmx_mio_boot_dma_intx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_intx_s cn63xx;
+ struct cvmx_mio_boot_dma_intx_s cn63xxp1;
+};
+
+union cvmx_mio_boot_dma_int_enx {
+ uint64_t u64;
+ struct cvmx_mio_boot_dma_int_enx_s {
+ uint64_t reserved_2_63:62;
+ uint64_t dmarq:1;
+ uint64_t done:1;
+ } s;
+ struct cvmx_mio_boot_dma_int_enx_s cn52xx;
+ struct cvmx_mio_boot_dma_int_enx_s cn52xxp1;
+ struct cvmx_mio_boot_dma_int_enx_s cn56xx;
+ struct cvmx_mio_boot_dma_int_enx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_int_enx_s cn63xx;
+ struct cvmx_mio_boot_dma_int_enx_s cn63xxp1;
+};
+
+union cvmx_mio_boot_dma_timx {
+ uint64_t u64;
+ struct cvmx_mio_boot_dma_timx_s {
+ uint64_t dmack_pi:1;
+ uint64_t dmarq_pi:1;
+ uint64_t tim_mult:2;
+ uint64_t rd_dly:3;
+ uint64_t ddr:1;
+ uint64_t width:1;
+ uint64_t reserved_48_54:7;
+ uint64_t pause:6;
+ uint64_t dmack_h:6;
+ uint64_t we_n:6;
+ uint64_t we_a:6;
+ uint64_t oe_n:6;
+ uint64_t oe_a:6;
+ uint64_t dmack_s:6;
+ uint64_t dmarq:6;
+ } s;
+ struct cvmx_mio_boot_dma_timx_s cn52xx;
+ struct cvmx_mio_boot_dma_timx_s cn52xxp1;
+ struct cvmx_mio_boot_dma_timx_s cn56xx;
+ struct cvmx_mio_boot_dma_timx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_timx_s cn63xx;
+ struct cvmx_mio_boot_dma_timx_s cn63xxp1;
+};
+
+union cvmx_mio_boot_err {
+ uint64_t u64;
+ struct cvmx_mio_boot_err_s {
+ uint64_t reserved_2_63:62;
+ uint64_t wait_err:1;
+ uint64_t adr_err:1;
+ } s;
+ struct cvmx_mio_boot_err_s cn30xx;
+ struct cvmx_mio_boot_err_s cn31xx;
+ struct cvmx_mio_boot_err_s cn38xx;
+ struct cvmx_mio_boot_err_s cn38xxp2;
+ struct cvmx_mio_boot_err_s cn50xx;
+ struct cvmx_mio_boot_err_s cn52xx;
+ struct cvmx_mio_boot_err_s cn52xxp1;
+ struct cvmx_mio_boot_err_s cn56xx;
+ struct cvmx_mio_boot_err_s cn56xxp1;
+ struct cvmx_mio_boot_err_s cn58xx;
+ struct cvmx_mio_boot_err_s cn58xxp1;
+ struct cvmx_mio_boot_err_s cn63xx;
+ struct cvmx_mio_boot_err_s cn63xxp1;
+};
+
+union cvmx_mio_boot_int {
+ uint64_t u64;
+ struct cvmx_mio_boot_int_s {
+ uint64_t reserved_2_63:62;
+ uint64_t wait_int:1;
+ uint64_t adr_int:1;
+ } s;
+ struct cvmx_mio_boot_int_s cn30xx;
+ struct cvmx_mio_boot_int_s cn31xx;
+ struct cvmx_mio_boot_int_s cn38xx;
+ struct cvmx_mio_boot_int_s cn38xxp2;
+ struct cvmx_mio_boot_int_s cn50xx;
+ struct cvmx_mio_boot_int_s cn52xx;
+ struct cvmx_mio_boot_int_s cn52xxp1;
+ struct cvmx_mio_boot_int_s cn56xx;
+ struct cvmx_mio_boot_int_s cn56xxp1;
+ struct cvmx_mio_boot_int_s cn58xx;
+ struct cvmx_mio_boot_int_s cn58xxp1;
+ struct cvmx_mio_boot_int_s cn63xx;
+ struct cvmx_mio_boot_int_s cn63xxp1;
+};
+
+union cvmx_mio_boot_loc_adr {
+ uint64_t u64;
+ struct cvmx_mio_boot_loc_adr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t adr:5;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_mio_boot_loc_adr_s cn30xx;
+ struct cvmx_mio_boot_loc_adr_s cn31xx;
+ struct cvmx_mio_boot_loc_adr_s cn38xx;
+ struct cvmx_mio_boot_loc_adr_s cn38xxp2;
+ struct cvmx_mio_boot_loc_adr_s cn50xx;
+ struct cvmx_mio_boot_loc_adr_s cn52xx;
+ struct cvmx_mio_boot_loc_adr_s cn52xxp1;
+ struct cvmx_mio_boot_loc_adr_s cn56xx;
+ struct cvmx_mio_boot_loc_adr_s cn56xxp1;
+ struct cvmx_mio_boot_loc_adr_s cn58xx;
+ struct cvmx_mio_boot_loc_adr_s cn58xxp1;
+ struct cvmx_mio_boot_loc_adr_s cn63xx;
+ struct cvmx_mio_boot_loc_adr_s cn63xxp1;
+};
+
+union cvmx_mio_boot_loc_cfgx {
+ uint64_t u64;
+ struct cvmx_mio_boot_loc_cfgx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t en:1;
+ uint64_t reserved_28_30:3;
+ uint64_t base:25;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_mio_boot_loc_cfgx_s cn30xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn31xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn38xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn38xxp2;
+ struct cvmx_mio_boot_loc_cfgx_s cn50xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn52xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn52xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cn56xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn56xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cn58xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn58xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cn63xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn63xxp1;
+};
+
+union cvmx_mio_boot_loc_dat {
+ uint64_t u64;
+ struct cvmx_mio_boot_loc_dat_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_mio_boot_loc_dat_s cn30xx;
+ struct cvmx_mio_boot_loc_dat_s cn31xx;
+ struct cvmx_mio_boot_loc_dat_s cn38xx;
+ struct cvmx_mio_boot_loc_dat_s cn38xxp2;
+ struct cvmx_mio_boot_loc_dat_s cn50xx;
+ struct cvmx_mio_boot_loc_dat_s cn52xx;
+ struct cvmx_mio_boot_loc_dat_s cn52xxp1;
+ struct cvmx_mio_boot_loc_dat_s cn56xx;
+ struct cvmx_mio_boot_loc_dat_s cn56xxp1;
+ struct cvmx_mio_boot_loc_dat_s cn58xx;
+ struct cvmx_mio_boot_loc_dat_s cn58xxp1;
+ struct cvmx_mio_boot_loc_dat_s cn63xx;
+ struct cvmx_mio_boot_loc_dat_s cn63xxp1;
+};
+
+union cvmx_mio_boot_pin_defs {
+ uint64_t u64;
+ struct cvmx_mio_boot_pin_defs_s {
+ uint64_t reserved_16_63:48;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t dmack_p2:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p0:1;
+ uint64_t term:2;
+ uint64_t nand:1;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_mio_boot_pin_defs_cn52xx {
+ uint64_t reserved_16_63:48;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t reserved_13_13:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p0:1;
+ uint64_t term:2;
+ uint64_t nand:1;
+ uint64_t reserved_0_7:8;
+ } cn52xx;
+ struct cvmx_mio_boot_pin_defs_cn56xx {
+ uint64_t reserved_16_63:48;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t dmack_p2:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p0:1;
+ uint64_t term:2;
+ uint64_t reserved_0_8:9;
+ } cn56xx;
+ struct cvmx_mio_boot_pin_defs_cn52xx cn63xx;
+ struct cvmx_mio_boot_pin_defs_cn52xx cn63xxp1;
+};
+
+union cvmx_mio_boot_reg_cfgx {
+ uint64_t u64;
+ struct cvmx_mio_boot_reg_cfgx_s {
+ uint64_t reserved_44_63:20;
+ uint64_t dmack:2;
+ uint64_t tim_mult:2;
+ uint64_t rd_dly:3;
+ uint64_t sam:1;
+ uint64_t we_ext:2;
+ uint64_t oe_ext:2;
+ uint64_t en:1;
+ uint64_t orbit:1;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t size:12;
+ uint64_t base:16;
+ } s;
+ struct cvmx_mio_boot_reg_cfgx_cn30xx {
+ uint64_t reserved_37_63:27;
+ uint64_t sam:1;
+ uint64_t we_ext:2;
+ uint64_t oe_ext:2;
+ uint64_t en:1;
+ uint64_t orbit:1;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t size:12;
+ uint64_t base:16;
+ } cn30xx;
+ struct cvmx_mio_boot_reg_cfgx_cn30xx cn31xx;
+ struct cvmx_mio_boot_reg_cfgx_cn38xx {
+ uint64_t reserved_32_63:32;
+ uint64_t en:1;
+ uint64_t orbit:1;
+ uint64_t reserved_28_29:2;
+ uint64_t size:12;
+ uint64_t base:16;
+ } cn38xx;
+ struct cvmx_mio_boot_reg_cfgx_cn38xx cn38xxp2;
+ struct cvmx_mio_boot_reg_cfgx_cn50xx {
+ uint64_t reserved_42_63:22;
+ uint64_t tim_mult:2;
+ uint64_t rd_dly:3;
+ uint64_t sam:1;
+ uint64_t we_ext:2;
+ uint64_t oe_ext:2;
+ uint64_t en:1;
+ uint64_t orbit:1;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t size:12;
+ uint64_t base:16;
+ } cn50xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn52xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn52xxp1;
+ struct cvmx_mio_boot_reg_cfgx_s cn56xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn56xxp1;
+ struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xx;
+ struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xxp1;
+ struct cvmx_mio_boot_reg_cfgx_s cn63xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn63xxp1;
+};
+
+union cvmx_mio_boot_reg_timx {
+ uint64_t u64;
+ struct cvmx_mio_boot_reg_timx_s {
+ uint64_t pagem:1;
+ uint64_t waitm:1;
+ uint64_t pages:2;
+ uint64_t ale:6;
+ uint64_t page:6;
+ uint64_t wait:6;
+ uint64_t pause:6;
+ uint64_t wr_hld:6;
+ uint64_t rd_hld:6;
+ uint64_t we:6;
+ uint64_t oe:6;
+ uint64_t ce:6;
+ uint64_t adr:6;
+ } s;
+ struct cvmx_mio_boot_reg_timx_s cn30xx;
+ struct cvmx_mio_boot_reg_timx_s cn31xx;
+ struct cvmx_mio_boot_reg_timx_cn38xx {
+ uint64_t pagem:1;
+ uint64_t waitm:1;
+ uint64_t pages:2;
+ uint64_t reserved_54_59:6;
+ uint64_t page:6;
+ uint64_t wait:6;
+ uint64_t pause:6;
+ uint64_t wr_hld:6;
+ uint64_t rd_hld:6;
+ uint64_t we:6;
+ uint64_t oe:6;
+ uint64_t ce:6;
+ uint64_t adr:6;
+ } cn38xx;
+ struct cvmx_mio_boot_reg_timx_cn38xx cn38xxp2;
+ struct cvmx_mio_boot_reg_timx_s cn50xx;
+ struct cvmx_mio_boot_reg_timx_s cn52xx;
+ struct cvmx_mio_boot_reg_timx_s cn52xxp1;
+ struct cvmx_mio_boot_reg_timx_s cn56xx;
+ struct cvmx_mio_boot_reg_timx_s cn56xxp1;
+ struct cvmx_mio_boot_reg_timx_s cn58xx;
+ struct cvmx_mio_boot_reg_timx_s cn58xxp1;
+ struct cvmx_mio_boot_reg_timx_s cn63xx;
+ struct cvmx_mio_boot_reg_timx_s cn63xxp1;
+};
+
+union cvmx_mio_boot_thr {
+ uint64_t u64;
+ struct cvmx_mio_boot_thr_s {
+ uint64_t reserved_22_63:42;
+ uint64_t dma_thr:6;
+ uint64_t reserved_14_15:2;
+ uint64_t fif_cnt:6;
+ uint64_t reserved_6_7:2;
+ uint64_t fif_thr:6;
+ } s;
+ struct cvmx_mio_boot_thr_cn30xx {
+ uint64_t reserved_14_63:50;
+ uint64_t fif_cnt:6;
+ uint64_t reserved_6_7:2;
+ uint64_t fif_thr:6;
+ } cn30xx;
+ struct cvmx_mio_boot_thr_cn30xx cn31xx;
+ struct cvmx_mio_boot_thr_cn30xx cn38xx;
+ struct cvmx_mio_boot_thr_cn30xx cn38xxp2;
+ struct cvmx_mio_boot_thr_cn30xx cn50xx;
+ struct cvmx_mio_boot_thr_s cn52xx;
+ struct cvmx_mio_boot_thr_s cn52xxp1;
+ struct cvmx_mio_boot_thr_s cn56xx;
+ struct cvmx_mio_boot_thr_s cn56xxp1;
+ struct cvmx_mio_boot_thr_cn30xx cn58xx;
+ struct cvmx_mio_boot_thr_cn30xx cn58xxp1;
+ struct cvmx_mio_boot_thr_s cn63xx;
+ struct cvmx_mio_boot_thr_s cn63xxp1;
+};
+
+union cvmx_mio_fus_bnk_datx {
+ uint64_t u64;
+ struct cvmx_mio_fus_bnk_datx_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_mio_fus_bnk_datx_s cn50xx;
+ struct cvmx_mio_fus_bnk_datx_s cn52xx;
+ struct cvmx_mio_fus_bnk_datx_s cn52xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cn56xx;
+ struct cvmx_mio_fus_bnk_datx_s cn56xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cn58xx;
+ struct cvmx_mio_fus_bnk_datx_s cn58xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cn63xx;
+ struct cvmx_mio_fus_bnk_datx_s cn63xxp1;
+};
+
+union cvmx_mio_fus_dat0 {
+ uint64_t u64;
+ struct cvmx_mio_fus_dat0_s {
+ uint64_t reserved_32_63:32;
+ uint64_t man_info:32;
+ } s;
+ struct cvmx_mio_fus_dat0_s cn30xx;
+ struct cvmx_mio_fus_dat0_s cn31xx;
+ struct cvmx_mio_fus_dat0_s cn38xx;
+ struct cvmx_mio_fus_dat0_s cn38xxp2;
+ struct cvmx_mio_fus_dat0_s cn50xx;
+ struct cvmx_mio_fus_dat0_s cn52xx;
+ struct cvmx_mio_fus_dat0_s cn52xxp1;
+ struct cvmx_mio_fus_dat0_s cn56xx;
+ struct cvmx_mio_fus_dat0_s cn56xxp1;
+ struct cvmx_mio_fus_dat0_s cn58xx;
+ struct cvmx_mio_fus_dat0_s cn58xxp1;
+ struct cvmx_mio_fus_dat0_s cn63xx;
+ struct cvmx_mio_fus_dat0_s cn63xxp1;
+};
+
+union cvmx_mio_fus_dat1 {
+ uint64_t u64;
+ struct cvmx_mio_fus_dat1_s {
+ uint64_t reserved_32_63:32;
+ uint64_t man_info:32;
+ } s;
+ struct cvmx_mio_fus_dat1_s cn30xx;
+ struct cvmx_mio_fus_dat1_s cn31xx;
+ struct cvmx_mio_fus_dat1_s cn38xx;
+ struct cvmx_mio_fus_dat1_s cn38xxp2;
+ struct cvmx_mio_fus_dat1_s cn50xx;
+ struct cvmx_mio_fus_dat1_s cn52xx;
+ struct cvmx_mio_fus_dat1_s cn52xxp1;
+ struct cvmx_mio_fus_dat1_s cn56xx;
+ struct cvmx_mio_fus_dat1_s cn56xxp1;
+ struct cvmx_mio_fus_dat1_s cn58xx;
+ struct cvmx_mio_fus_dat1_s cn58xxp1;
+ struct cvmx_mio_fus_dat1_s cn63xx;
+ struct cvmx_mio_fus_dat1_s cn63xxp1;
+};
+
+union cvmx_mio_fus_dat2 {
+ uint64_t u64;
+ struct cvmx_mio_fus_dat2_s {
+ uint64_t reserved_35_63:29;
+ uint64_t dorm_crypto:1;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_30_31:2;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t reserved_0_15:16;
+ } s;
+ struct cvmx_mio_fus_dat2_cn30xx {
+ uint64_t reserved_29_63:35;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t pll_off:4;
+ uint64_t reserved_1_11:11;
+ uint64_t pp_dis:1;
+ } cn30xx;
+ struct cvmx_mio_fus_dat2_cn31xx {
+ uint64_t reserved_29_63:35;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t pll_off:4;
+ uint64_t reserved_2_11:10;
+ uint64_t pp_dis:2;
+ } cn31xx;
+ struct cvmx_mio_fus_dat2_cn38xx {
+ uint64_t reserved_29_63:35;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t pp_dis:16;
+ } cn38xx;
+ struct cvmx_mio_fus_dat2_cn38xx cn38xxp2;
+ struct cvmx_mio_fus_dat2_cn50xx {
+ uint64_t reserved_34_63:30;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_30_31:2;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t reserved_2_15:14;
+ uint64_t pp_dis:2;
+ } cn50xx;
+ struct cvmx_mio_fus_dat2_cn52xx {
+ uint64_t reserved_34_63:30;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_30_31:2;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t reserved_4_15:12;
+ uint64_t pp_dis:4;
+ } cn52xx;
+ struct cvmx_mio_fus_dat2_cn52xx cn52xxp1;
+ struct cvmx_mio_fus_dat2_cn56xx {
+ uint64_t reserved_34_63:30;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_30_31:2;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t reserved_12_15:4;
+ uint64_t pp_dis:12;
+ } cn56xx;
+ struct cvmx_mio_fus_dat2_cn56xx cn56xxp1;
+ struct cvmx_mio_fus_dat2_cn58xx {
+ uint64_t reserved_30_63:34;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t pp_dis:16;
+ } cn58xx;
+ struct cvmx_mio_fus_dat2_cn58xx cn58xxp1;
+ struct cvmx_mio_fus_dat2_cn63xx {
+ uint64_t reserved_35_63:29;
+ uint64_t dorm_crypto:1;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_29_31:3;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t reserved_24_25:2;
+ uint64_t chip_id:8;
+ uint64_t reserved_6_15:10;
+ uint64_t pp_dis:6;
+ } cn63xx;
+ struct cvmx_mio_fus_dat2_cn63xx cn63xxp1;
+};
+
+union cvmx_mio_fus_dat3 {
+ uint64_t u64;
+ struct cvmx_mio_fus_dat3_s {
+ uint64_t reserved_58_63:6;
+ uint64_t pll_ctl:10;
+ uint64_t dfa_info_dte:3;
+ uint64_t dfa_info_clm:4;
+ uint64_t reserved_40_40:1;
+ uint64_t ema:2;
+ uint64_t efus_lck_rsv:1;
+ uint64_t efus_lck_man:1;
+ uint64_t pll_half_dis:1;
+ uint64_t l2c_crip:3;
+ uint64_t pll_div4:1;
+ uint64_t reserved_29_30:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } s;
+ struct cvmx_mio_fus_dat3_cn30xx {
+ uint64_t reserved_32_63:32;
+ uint64_t pll_div4:1;
+ uint64_t reserved_29_30:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } cn30xx;
+ struct cvmx_mio_fus_dat3_cn31xx {
+ uint64_t reserved_32_63:32;
+ uint64_t pll_div4:1;
+ uint64_t zip_crip:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } cn31xx;
+ struct cvmx_mio_fus_dat3_cn38xx {
+ uint64_t reserved_31_63:33;
+ uint64_t zip_crip:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } cn38xx;
+ struct cvmx_mio_fus_dat3_cn38xxp2 {
+ uint64_t reserved_29_63:35;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } cn38xxp2;
+ struct cvmx_mio_fus_dat3_cn38xx cn50xx;
+ struct cvmx_mio_fus_dat3_cn38xx cn52xx;
+ struct cvmx_mio_fus_dat3_cn38xx cn52xxp1;
+ struct cvmx_mio_fus_dat3_cn38xx cn56xx;
+ struct cvmx_mio_fus_dat3_cn38xx cn56xxp1;
+ struct cvmx_mio_fus_dat3_cn38xx cn58xx;
+ struct cvmx_mio_fus_dat3_cn38xx cn58xxp1;
+ struct cvmx_mio_fus_dat3_cn63xx {
+ uint64_t reserved_58_63:6;
+ uint64_t pll_ctl:10;
+ uint64_t dfa_info_dte:3;
+ uint64_t dfa_info_clm:4;
+ uint64_t reserved_40_40:1;
+ uint64_t ema:2;
+ uint64_t efus_lck_rsv:1;
+ uint64_t efus_lck_man:1;
+ uint64_t pll_half_dis:1;
+ uint64_t l2c_crip:3;
+ uint64_t reserved_31_31:1;
+ uint64_t zip_info:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t reserved_0_23:24;
+ } cn63xx;
+ struct cvmx_mio_fus_dat3_cn63xx cn63xxp1;
+};
+
+union cvmx_mio_fus_ema {
+ uint64_t u64;
+ struct cvmx_mio_fus_ema_s {
+ uint64_t reserved_7_63:57;
+ uint64_t eff_ema:3;
+ uint64_t reserved_3_3:1;
+ uint64_t ema:3;
+ } s;
+ struct cvmx_mio_fus_ema_s cn50xx;
+ struct cvmx_mio_fus_ema_s cn52xx;
+ struct cvmx_mio_fus_ema_s cn52xxp1;
+ struct cvmx_mio_fus_ema_s cn56xx;
+ struct cvmx_mio_fus_ema_s cn56xxp1;
+ struct cvmx_mio_fus_ema_cn58xx {
+ uint64_t reserved_2_63:62;
+ uint64_t ema:2;
+ } cn58xx;
+ struct cvmx_mio_fus_ema_cn58xx cn58xxp1;
+ struct cvmx_mio_fus_ema_s cn63xx;
+ struct cvmx_mio_fus_ema_s cn63xxp1;
+};
+
+union cvmx_mio_fus_pdf {
+ uint64_t u64;
+ struct cvmx_mio_fus_pdf_s {
+ uint64_t pdf:64;
+ } s;
+ struct cvmx_mio_fus_pdf_s cn50xx;
+ struct cvmx_mio_fus_pdf_s cn52xx;
+ struct cvmx_mio_fus_pdf_s cn52xxp1;
+ struct cvmx_mio_fus_pdf_s cn56xx;
+ struct cvmx_mio_fus_pdf_s cn56xxp1;
+ struct cvmx_mio_fus_pdf_s cn58xx;
+ struct cvmx_mio_fus_pdf_s cn63xx;
+ struct cvmx_mio_fus_pdf_s cn63xxp1;
+};
+
+union cvmx_mio_fus_pll {
+ uint64_t u64;
+ struct cvmx_mio_fus_pll_s {
+ uint64_t reserved_8_63:56;
+ uint64_t c_cout_rst:1;
+ uint64_t c_cout_sel:2;
+ uint64_t pnr_cout_rst:1;
+ uint64_t pnr_cout_sel:2;
+ uint64_t rfslip:1;
+ uint64_t fbslip:1;
+ } s;
+ struct cvmx_mio_fus_pll_cn50xx {
+ uint64_t reserved_2_63:62;
+ uint64_t rfslip:1;
+ uint64_t fbslip:1;
+ } cn50xx;
+ struct cvmx_mio_fus_pll_cn50xx cn52xx;
+ struct cvmx_mio_fus_pll_cn50xx cn52xxp1;
+ struct cvmx_mio_fus_pll_cn50xx cn56xx;
+ struct cvmx_mio_fus_pll_cn50xx cn56xxp1;
+ struct cvmx_mio_fus_pll_cn50xx cn58xx;
+ struct cvmx_mio_fus_pll_cn50xx cn58xxp1;
+ struct cvmx_mio_fus_pll_s cn63xx;
+ struct cvmx_mio_fus_pll_s cn63xxp1;
+};
+
+union cvmx_mio_fus_prog {
+ uint64_t u64;
+ struct cvmx_mio_fus_prog_s {
+ uint64_t reserved_2_63:62;
+ uint64_t soft:1;
+ uint64_t prog:1;
+ } s;
+ struct cvmx_mio_fus_prog_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t prog:1;
+ } cn30xx;
+ struct cvmx_mio_fus_prog_cn30xx cn31xx;
+ struct cvmx_mio_fus_prog_cn30xx cn38xx;
+ struct cvmx_mio_fus_prog_cn30xx cn38xxp2;
+ struct cvmx_mio_fus_prog_cn30xx cn50xx;
+ struct cvmx_mio_fus_prog_cn30xx cn52xx;
+ struct cvmx_mio_fus_prog_cn30xx cn52xxp1;
+ struct cvmx_mio_fus_prog_cn30xx cn56xx;
+ struct cvmx_mio_fus_prog_cn30xx cn56xxp1;
+ struct cvmx_mio_fus_prog_cn30xx cn58xx;
+ struct cvmx_mio_fus_prog_cn30xx cn58xxp1;
+ struct cvmx_mio_fus_prog_s cn63xx;
+ struct cvmx_mio_fus_prog_s cn63xxp1;
+};
+
+union cvmx_mio_fus_prog_times {
+ uint64_t u64;
+ struct cvmx_mio_fus_prog_times_s {
+ uint64_t reserved_35_63:29;
+ uint64_t vgate_pin:1;
+ uint64_t fsrc_pin:1;
+ uint64_t prog_pin:1;
+ uint64_t reserved_6_31:26;
+ uint64_t setup:6;
+ } s;
+ struct cvmx_mio_fus_prog_times_cn50xx {
+ uint64_t reserved_33_63:31;
+ uint64_t prog_pin:1;
+ uint64_t out:8;
+ uint64_t sclk_lo:4;
+ uint64_t sclk_hi:12;
+ uint64_t setup:8;
+ } cn50xx;
+ struct cvmx_mio_fus_prog_times_cn50xx cn52xx;
+ struct cvmx_mio_fus_prog_times_cn50xx cn52xxp1;
+ struct cvmx_mio_fus_prog_times_cn50xx cn56xx;
+ struct cvmx_mio_fus_prog_times_cn50xx cn56xxp1;
+ struct cvmx_mio_fus_prog_times_cn50xx cn58xx;
+ struct cvmx_mio_fus_prog_times_cn50xx cn58xxp1;
+ struct cvmx_mio_fus_prog_times_cn63xx {
+ uint64_t reserved_35_63:29;
+ uint64_t vgate_pin:1;
+ uint64_t fsrc_pin:1;
+ uint64_t prog_pin:1;
+ uint64_t out:7;
+ uint64_t sclk_lo:4;
+ uint64_t sclk_hi:15;
+ uint64_t setup:6;
+ } cn63xx;
+ struct cvmx_mio_fus_prog_times_cn63xx cn63xxp1;
+};
+
+union cvmx_mio_fus_rcmd {
+ uint64_t u64;
+ struct cvmx_mio_fus_rcmd_s {
+ uint64_t reserved_24_63:40;
+ uint64_t dat:8;
+ uint64_t reserved_13_15:3;
+ uint64_t pend:1;
+ uint64_t reserved_9_11:3;
+ uint64_t efuse:1;
+ uint64_t addr:8;
+ } s;
+ struct cvmx_mio_fus_rcmd_cn30xx {
+ uint64_t reserved_24_63:40;
+ uint64_t dat:8;
+ uint64_t reserved_13_15:3;
+ uint64_t pend:1;
+ uint64_t reserved_9_11:3;
+ uint64_t efuse:1;
+ uint64_t reserved_7_7:1;
+ uint64_t addr:7;
+ } cn30xx;
+ struct cvmx_mio_fus_rcmd_cn30xx cn31xx;
+ struct cvmx_mio_fus_rcmd_cn30xx cn38xx;
+ struct cvmx_mio_fus_rcmd_cn30xx cn38xxp2;
+ struct cvmx_mio_fus_rcmd_cn30xx cn50xx;
+ struct cvmx_mio_fus_rcmd_s cn52xx;
+ struct cvmx_mio_fus_rcmd_s cn52xxp1;
+ struct cvmx_mio_fus_rcmd_s cn56xx;
+ struct cvmx_mio_fus_rcmd_s cn56xxp1;
+ struct cvmx_mio_fus_rcmd_cn30xx cn58xx;
+ struct cvmx_mio_fus_rcmd_cn30xx cn58xxp1;
+ struct cvmx_mio_fus_rcmd_s cn63xx;
+ struct cvmx_mio_fus_rcmd_s cn63xxp1;
+};
+
+union cvmx_mio_fus_read_times {
+ uint64_t u64;
+ struct cvmx_mio_fus_read_times_s {
+ uint64_t reserved_26_63:38;
+ uint64_t sch:4;
+ uint64_t fsh:4;
+ uint64_t prh:4;
+ uint64_t sdh:4;
+ uint64_t setup:10;
+ } s;
+ struct cvmx_mio_fus_read_times_s cn63xx;
+ struct cvmx_mio_fus_read_times_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res0 {
+ uint64_t u64;
+ struct cvmx_mio_fus_repair_res0_s {
+ uint64_t reserved_55_63:9;
+ uint64_t too_many:1;
+ uint64_t repair2:18;
+ uint64_t repair1:18;
+ uint64_t repair0:18;
+ } s;
+ struct cvmx_mio_fus_repair_res0_s cn63xx;
+ struct cvmx_mio_fus_repair_res0_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res1 {
+ uint64_t u64;
+ struct cvmx_mio_fus_repair_res1_s {
+ uint64_t reserved_54_63:10;
+ uint64_t repair5:18;
+ uint64_t repair4:18;
+ uint64_t repair3:18;
+ } s;
+ struct cvmx_mio_fus_repair_res1_s cn63xx;
+ struct cvmx_mio_fus_repair_res1_s cn63xxp1;
+};
+
+union cvmx_mio_fus_repair_res2 {
+ uint64_t u64;
+ struct cvmx_mio_fus_repair_res2_s {
+ uint64_t reserved_18_63:46;
+ uint64_t repair6:18;
+ } s;
+ struct cvmx_mio_fus_repair_res2_s cn63xx;
+ struct cvmx_mio_fus_repair_res2_s cn63xxp1;
+};
+
+union cvmx_mio_fus_spr_repair_res {
+ uint64_t u64;
+ struct cvmx_mio_fus_spr_repair_res_s {
+ uint64_t reserved_42_63:22;
+ uint64_t repair2:14;
+ uint64_t repair1:14;
+ uint64_t repair0:14;
+ } s;
+ struct cvmx_mio_fus_spr_repair_res_s cn30xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn31xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn38xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn50xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn52xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn52xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cn56xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn56xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cn58xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn58xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cn63xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn63xxp1;
+};
+
+union cvmx_mio_fus_spr_repair_sum {
+ uint64_t u64;
+ struct cvmx_mio_fus_spr_repair_sum_s {
+ uint64_t reserved_1_63:63;
+ uint64_t too_many:1;
+ } s;
+ struct cvmx_mio_fus_spr_repair_sum_s cn30xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn31xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn38xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn50xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn52xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn52xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cn56xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn56xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cn58xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn58xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cn63xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn63xxp1;
+};
+
+union cvmx_mio_fus_unlock {
+ uint64_t u64;
+ struct cvmx_mio_fus_unlock_s {
+ uint64_t reserved_24_63:40;
+ uint64_t key:24;
+ } s;
+ struct cvmx_mio_fus_unlock_s cn30xx;
+ struct cvmx_mio_fus_unlock_s cn31xx;
+};
+
+union cvmx_mio_fus_wadr {
+ uint64_t u64;
+ struct cvmx_mio_fus_wadr_s {
+ uint64_t reserved_10_63:54;
+ uint64_t addr:10;
+ } s;
+ struct cvmx_mio_fus_wadr_s cn30xx;
+ struct cvmx_mio_fus_wadr_s cn31xx;
+ struct cvmx_mio_fus_wadr_s cn38xx;
+ struct cvmx_mio_fus_wadr_s cn38xxp2;
+ struct cvmx_mio_fus_wadr_cn50xx {
+ uint64_t reserved_2_63:62;
+ uint64_t addr:2;
+ } cn50xx;
+ struct cvmx_mio_fus_wadr_cn52xx {
+ uint64_t reserved_3_63:61;
+ uint64_t addr:3;
+ } cn52xx;
+ struct cvmx_mio_fus_wadr_cn52xx cn52xxp1;
+ struct cvmx_mio_fus_wadr_cn52xx cn56xx;
+ struct cvmx_mio_fus_wadr_cn52xx cn56xxp1;
+ struct cvmx_mio_fus_wadr_cn50xx cn58xx;
+ struct cvmx_mio_fus_wadr_cn50xx cn58xxp1;
+ struct cvmx_mio_fus_wadr_cn63xx {
+ uint64_t reserved_4_63:60;
+ uint64_t addr:4;
+ } cn63xx;
+ struct cvmx_mio_fus_wadr_cn63xx cn63xxp1;
+};
+
+union cvmx_mio_gpio_comp {
+ uint64_t u64;
+ struct cvmx_mio_gpio_comp_s {
+ uint64_t reserved_12_63:52;
+ uint64_t pctl:6;
+ uint64_t nctl:6;
+ } s;
+ struct cvmx_mio_gpio_comp_s cn63xx;
+ struct cvmx_mio_gpio_comp_s cn63xxp1;
+};
+
+union cvmx_mio_ndf_dma_cfg {
+ uint64_t u64;
+ struct cvmx_mio_ndf_dma_cfg_s {
+ uint64_t en:1;
+ uint64_t rw:1;
+ uint64_t clr:1;
+ uint64_t reserved_60_60:1;
+ uint64_t swap32:1;
+ uint64_t swap16:1;
+ uint64_t swap8:1;
+ uint64_t endian:1;
+ uint64_t size:20;
+ uint64_t adr:36;
+ } s;
+ struct cvmx_mio_ndf_dma_cfg_s cn52xx;
+ struct cvmx_mio_ndf_dma_cfg_s cn63xx;
+ struct cvmx_mio_ndf_dma_cfg_s cn63xxp1;
+};
+
+union cvmx_mio_ndf_dma_int {
+ uint64_t u64;
+ struct cvmx_mio_ndf_dma_int_s {
+ uint64_t reserved_1_63:63;
+ uint64_t done:1;
+ } s;
+ struct cvmx_mio_ndf_dma_int_s cn52xx;
+ struct cvmx_mio_ndf_dma_int_s cn63xx;
+ struct cvmx_mio_ndf_dma_int_s cn63xxp1;
+};
+
+union cvmx_mio_ndf_dma_int_en {
+ uint64_t u64;
+ struct cvmx_mio_ndf_dma_int_en_s {
+ uint64_t reserved_1_63:63;
+ uint64_t done:1;
+ } s;
+ struct cvmx_mio_ndf_dma_int_en_s cn52xx;
+ struct cvmx_mio_ndf_dma_int_en_s cn63xx;
+ struct cvmx_mio_ndf_dma_int_en_s cn63xxp1;
+};
+
+union cvmx_mio_pll_ctl {
+ uint64_t u64;
+ struct cvmx_mio_pll_ctl_s {
+ uint64_t reserved_5_63:59;
+ uint64_t bw_ctl:5;
+ } s;
+ struct cvmx_mio_pll_ctl_s cn30xx;
+ struct cvmx_mio_pll_ctl_s cn31xx;
+};
+
+union cvmx_mio_pll_setting {
+ uint64_t u64;
+ struct cvmx_mio_pll_setting_s {
+ uint64_t reserved_17_63:47;
+ uint64_t setting:17;
+ } s;
+ struct cvmx_mio_pll_setting_s cn30xx;
+ struct cvmx_mio_pll_setting_s cn31xx;
+};
+
+union cvmx_mio_ptp_clock_cfg {
+ uint64_t u64;
+ struct cvmx_mio_ptp_clock_cfg_s {
+ uint64_t reserved_24_63:40;
+ uint64_t evcnt_in:6;
+ uint64_t evcnt_edge:1;
+ uint64_t evcnt_en:1;
+ uint64_t tstmp_in:6;
+ uint64_t tstmp_edge:1;
+ uint64_t tstmp_en:1;
+ uint64_t ext_clk_in:6;
+ uint64_t ext_clk_en:1;
+ uint64_t ptp_en:1;
+ } s;
+ struct cvmx_mio_ptp_clock_cfg_s cn63xx;
+ struct cvmx_mio_ptp_clock_cfg_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_comp {
+ uint64_t u64;
+ struct cvmx_mio_ptp_clock_comp_s {
+ uint64_t nanosec:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_clock_comp_s cn63xx;
+ struct cvmx_mio_ptp_clock_comp_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_hi {
+ uint64_t u64;
+ struct cvmx_mio_ptp_clock_hi_s {
+ uint64_t nanosec:64;
+ } s;
+ struct cvmx_mio_ptp_clock_hi_s cn63xx;
+ struct cvmx_mio_ptp_clock_hi_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_clock_lo {
+ uint64_t u64;
+ struct cvmx_mio_ptp_clock_lo_s {
+ uint64_t reserved_32_63:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_clock_lo_s cn63xx;
+ struct cvmx_mio_ptp_clock_lo_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_evt_cnt {
+ uint64_t u64;
+ struct cvmx_mio_ptp_evt_cnt_s {
+ uint64_t cntr:64;
+ } s;
+ struct cvmx_mio_ptp_evt_cnt_s cn63xx;
+ struct cvmx_mio_ptp_evt_cnt_s cn63xxp1;
+};
+
+union cvmx_mio_ptp_timestamp {
+ uint64_t u64;
+ struct cvmx_mio_ptp_timestamp_s {
+ uint64_t nanosec:64;
+ } s;
+ struct cvmx_mio_ptp_timestamp_s cn63xx;
+ struct cvmx_mio_ptp_timestamp_s cn63xxp1;
+};
+
+union cvmx_mio_rst_boot {
+ uint64_t u64;
+ struct cvmx_mio_rst_boot_s {
+ uint64_t reserved_36_63:28;
+ uint64_t c_mul:6;
+ uint64_t pnr_mul:6;
+ uint64_t qlm2_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm0_spd:4;
+ uint64_t lboot:10;
+ uint64_t rboot:1;
+ uint64_t rboot_pin:1;
+ } s;
+ struct cvmx_mio_rst_boot_s cn63xx;
+ struct cvmx_mio_rst_boot_s cn63xxp1;
+};
+
+union cvmx_mio_rst_cfg {
+ uint64_t u64;
+ struct cvmx_mio_rst_cfg_s {
+ uint64_t bist_delay:58;
+ uint64_t reserved_3_5:3;
+ uint64_t cntl_clr_bist:1;
+ uint64_t warm_clr_bist:1;
+ uint64_t soft_clr_bist:1;
+ } s;
+ struct cvmx_mio_rst_cfg_s cn63xx;
+ struct cvmx_mio_rst_cfg_cn63xxp1 {
+ uint64_t bist_delay:58;
+ uint64_t reserved_2_5:4;
+ uint64_t warm_clr_bist:1;
+ uint64_t soft_clr_bist:1;
+ } cn63xxp1;
+};
+
+union cvmx_mio_rst_ctlx {
+ uint64_t u64;
+ struct cvmx_mio_rst_ctlx_s {
+ uint64_t reserved_10_63:54;
+ uint64_t prst_link:1;
+ uint64_t rst_done:1;
+ uint64_t rst_link:1;
+ uint64_t host_mode:1;
+ uint64_t prtmode:2;
+ uint64_t rst_drv:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_val:1;
+ } s;
+ struct cvmx_mio_rst_ctlx_s cn63xx;
+ struct cvmx_mio_rst_ctlx_cn63xxp1 {
+ uint64_t reserved_9_63:55;
+ uint64_t rst_done:1;
+ uint64_t rst_link:1;
+ uint64_t host_mode:1;
+ uint64_t prtmode:2;
+ uint64_t rst_drv:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_val:1;
+ } cn63xxp1;
+};
+
+union cvmx_mio_rst_delay {
+ uint64_t u64;
+ struct cvmx_mio_rst_delay_s {
+ uint64_t reserved_32_63:32;
+ uint64_t soft_rst_dly:16;
+ uint64_t warm_rst_dly:16;
+ } s;
+ struct cvmx_mio_rst_delay_s cn63xx;
+ struct cvmx_mio_rst_delay_s cn63xxp1;
+};
+
+union cvmx_mio_rst_int {
+ uint64_t u64;
+ struct cvmx_mio_rst_int_s {
+ uint64_t reserved_10_63:54;
+ uint64_t perst1:1;
+ uint64_t perst0:1;
+ uint64_t reserved_2_7:6;
+ uint64_t rst_link1:1;
+ uint64_t rst_link0:1;
+ } s;
+ struct cvmx_mio_rst_int_s cn63xx;
+ struct cvmx_mio_rst_int_s cn63xxp1;
+};
+
+union cvmx_mio_rst_int_en {
+ uint64_t u64;
+ struct cvmx_mio_rst_int_en_s {
+ uint64_t reserved_10_63:54;
+ uint64_t perst1:1;
+ uint64_t perst0:1;
+ uint64_t reserved_2_7:6;
+ uint64_t rst_link1:1;
+ uint64_t rst_link0:1;
+ } s;
+ struct cvmx_mio_rst_int_en_s cn63xx;
+ struct cvmx_mio_rst_int_en_s cn63xxp1;
+};
+
+union cvmx_mio_twsx_int {
+ uint64_t u64;
+ struct cvmx_mio_twsx_int_s {
+ uint64_t reserved_12_63:52;
+ uint64_t scl:1;
+ uint64_t sda:1;
+ uint64_t scl_ovr:1;
+ uint64_t sda_ovr:1;
+ uint64_t reserved_7_7:1;
+ uint64_t core_en:1;
+ uint64_t ts_en:1;
+ uint64_t st_en:1;
+ uint64_t reserved_3_3:1;
+ uint64_t core_int:1;
+ uint64_t ts_int:1;
+ uint64_t st_int:1;
+ } s;
+ struct cvmx_mio_twsx_int_s cn30xx;
+ struct cvmx_mio_twsx_int_s cn31xx;
+ struct cvmx_mio_twsx_int_s cn38xx;
+ struct cvmx_mio_twsx_int_cn38xxp2 {
+ uint64_t reserved_7_63:57;
+ uint64_t core_en:1;
+ uint64_t ts_en:1;
+ uint64_t st_en:1;
+ uint64_t reserved_3_3:1;
+ uint64_t core_int:1;
+ uint64_t ts_int:1;
+ uint64_t st_int:1;
+ } cn38xxp2;
+ struct cvmx_mio_twsx_int_s cn50xx;
+ struct cvmx_mio_twsx_int_s cn52xx;
+ struct cvmx_mio_twsx_int_s cn52xxp1;
+ struct cvmx_mio_twsx_int_s cn56xx;
+ struct cvmx_mio_twsx_int_s cn56xxp1;
+ struct cvmx_mio_twsx_int_s cn58xx;
+ struct cvmx_mio_twsx_int_s cn58xxp1;
+ struct cvmx_mio_twsx_int_s cn63xx;
+ struct cvmx_mio_twsx_int_s cn63xxp1;
+};
+
+union cvmx_mio_twsx_sw_twsi {
+ uint64_t u64;
+ struct cvmx_mio_twsx_sw_twsi_s {
+ uint64_t v:1;
+ uint64_t slonly:1;
+ uint64_t eia:1;
+ uint64_t op:4;
+ uint64_t r:1;
+ uint64_t sovr:1;
+ uint64_t size:3;
+ uint64_t scr:2;
+ uint64_t a:10;
+ uint64_t ia:5;
+ uint64_t eop_ia:3;
+ uint64_t d:32;
+ } s;
+ struct cvmx_mio_twsx_sw_twsi_s cn30xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn31xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn38xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn38xxp2;
+ struct cvmx_mio_twsx_sw_twsi_s cn50xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn52xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn52xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cn56xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn56xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cn58xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn58xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cn63xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn63xxp1;
+};
+
+union cvmx_mio_twsx_sw_twsi_ext {
+ uint64_t u64;
+ struct cvmx_mio_twsx_sw_twsi_ext_s {
+ uint64_t reserved_40_63:24;
+ uint64_t ia:8;
+ uint64_t d:32;
+ } s;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn30xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn31xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn38xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn38xxp2;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn50xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn52xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn52xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn56xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn56xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn58xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn58xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn63xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn63xxp1;
+};
+
+union cvmx_mio_twsx_twsi_sw {
+ uint64_t u64;
+ struct cvmx_mio_twsx_twsi_sw_s {
+ uint64_t v:2;
+ uint64_t reserved_32_61:30;
+ uint64_t d:32;
+ } s;
+ struct cvmx_mio_twsx_twsi_sw_s cn30xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn31xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn38xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn38xxp2;
+ struct cvmx_mio_twsx_twsi_sw_s cn50xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn52xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn52xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cn56xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn56xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cn58xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn58xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cn63xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_dlh {
+ uint64_t u64;
+ struct cvmx_mio_uartx_dlh_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dlh:8;
+ } s;
+ struct cvmx_mio_uartx_dlh_s cn30xx;
+ struct cvmx_mio_uartx_dlh_s cn31xx;
+ struct cvmx_mio_uartx_dlh_s cn38xx;
+ struct cvmx_mio_uartx_dlh_s cn38xxp2;
+ struct cvmx_mio_uartx_dlh_s cn50xx;
+ struct cvmx_mio_uartx_dlh_s cn52xx;
+ struct cvmx_mio_uartx_dlh_s cn52xxp1;
+ struct cvmx_mio_uartx_dlh_s cn56xx;
+ struct cvmx_mio_uartx_dlh_s cn56xxp1;
+ struct cvmx_mio_uartx_dlh_s cn58xx;
+ struct cvmx_mio_uartx_dlh_s cn58xxp1;
+ struct cvmx_mio_uartx_dlh_s cn63xx;
+ struct cvmx_mio_uartx_dlh_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_dll {
+ uint64_t u64;
+ struct cvmx_mio_uartx_dll_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dll:8;
+ } s;
+ struct cvmx_mio_uartx_dll_s cn30xx;
+ struct cvmx_mio_uartx_dll_s cn31xx;
+ struct cvmx_mio_uartx_dll_s cn38xx;
+ struct cvmx_mio_uartx_dll_s cn38xxp2;
+ struct cvmx_mio_uartx_dll_s cn50xx;
+ struct cvmx_mio_uartx_dll_s cn52xx;
+ struct cvmx_mio_uartx_dll_s cn52xxp1;
+ struct cvmx_mio_uartx_dll_s cn56xx;
+ struct cvmx_mio_uartx_dll_s cn56xxp1;
+ struct cvmx_mio_uartx_dll_s cn58xx;
+ struct cvmx_mio_uartx_dll_s cn58xxp1;
+ struct cvmx_mio_uartx_dll_s cn63xx;
+ struct cvmx_mio_uartx_dll_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_far {
+ uint64_t u64;
+ struct cvmx_mio_uartx_far_s {
+ uint64_t reserved_1_63:63;
+ uint64_t far:1;
+ } s;
+ struct cvmx_mio_uartx_far_s cn30xx;
+ struct cvmx_mio_uartx_far_s cn31xx;
+ struct cvmx_mio_uartx_far_s cn38xx;
+ struct cvmx_mio_uartx_far_s cn38xxp2;
+ struct cvmx_mio_uartx_far_s cn50xx;
+ struct cvmx_mio_uartx_far_s cn52xx;
+ struct cvmx_mio_uartx_far_s cn52xxp1;
+ struct cvmx_mio_uartx_far_s cn56xx;
+ struct cvmx_mio_uartx_far_s cn56xxp1;
+ struct cvmx_mio_uartx_far_s cn58xx;
+ struct cvmx_mio_uartx_far_s cn58xxp1;
+ struct cvmx_mio_uartx_far_s cn63xx;
+ struct cvmx_mio_uartx_far_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_fcr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_fcr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rxtrig:2;
+ uint64_t txtrig:2;
+ uint64_t reserved_3_3:1;
+ uint64_t txfr:1;
+ uint64_t rxfr:1;
+ uint64_t en:1;
+ } s;
+ struct cvmx_mio_uartx_fcr_s cn30xx;
+ struct cvmx_mio_uartx_fcr_s cn31xx;
+ struct cvmx_mio_uartx_fcr_s cn38xx;
+ struct cvmx_mio_uartx_fcr_s cn38xxp2;
+ struct cvmx_mio_uartx_fcr_s cn50xx;
+ struct cvmx_mio_uartx_fcr_s cn52xx;
+ struct cvmx_mio_uartx_fcr_s cn52xxp1;
+ struct cvmx_mio_uartx_fcr_s cn56xx;
+ struct cvmx_mio_uartx_fcr_s cn56xxp1;
+ struct cvmx_mio_uartx_fcr_s cn58xx;
+ struct cvmx_mio_uartx_fcr_s cn58xxp1;
+ struct cvmx_mio_uartx_fcr_s cn63xx;
+ struct cvmx_mio_uartx_fcr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_htx {
+ uint64_t u64;
+ struct cvmx_mio_uartx_htx_s {
+ uint64_t reserved_1_63:63;
+ uint64_t htx:1;
+ } s;
+ struct cvmx_mio_uartx_htx_s cn30xx;
+ struct cvmx_mio_uartx_htx_s cn31xx;
+ struct cvmx_mio_uartx_htx_s cn38xx;
+ struct cvmx_mio_uartx_htx_s cn38xxp2;
+ struct cvmx_mio_uartx_htx_s cn50xx;
+ struct cvmx_mio_uartx_htx_s cn52xx;
+ struct cvmx_mio_uartx_htx_s cn52xxp1;
+ struct cvmx_mio_uartx_htx_s cn56xx;
+ struct cvmx_mio_uartx_htx_s cn56xxp1;
+ struct cvmx_mio_uartx_htx_s cn58xx;
+ struct cvmx_mio_uartx_htx_s cn58xxp1;
+ struct cvmx_mio_uartx_htx_s cn63xx;
+ struct cvmx_mio_uartx_htx_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_ier {
+ uint64_t u64;
+ struct cvmx_mio_uartx_ier_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ptime:1;
+ uint64_t reserved_4_6:3;
+ uint64_t edssi:1;
+ uint64_t elsi:1;
+ uint64_t etbei:1;
+ uint64_t erbfi:1;
+ } s;
+ struct cvmx_mio_uartx_ier_s cn30xx;
+ struct cvmx_mio_uartx_ier_s cn31xx;
+ struct cvmx_mio_uartx_ier_s cn38xx;
+ struct cvmx_mio_uartx_ier_s cn38xxp2;
+ struct cvmx_mio_uartx_ier_s cn50xx;
+ struct cvmx_mio_uartx_ier_s cn52xx;
+ struct cvmx_mio_uartx_ier_s cn52xxp1;
+ struct cvmx_mio_uartx_ier_s cn56xx;
+ struct cvmx_mio_uartx_ier_s cn56xxp1;
+ struct cvmx_mio_uartx_ier_s cn58xx;
+ struct cvmx_mio_uartx_ier_s cn58xxp1;
+ struct cvmx_mio_uartx_ier_s cn63xx;
+ struct cvmx_mio_uartx_ier_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_iir {
+ uint64_t u64;
+ struct cvmx_mio_uartx_iir_s {
+ uint64_t reserved_8_63:56;
+ uint64_t fen:2;
+ uint64_t reserved_4_5:2;
+ uint64_t iid:4;
+ } s;
+ struct cvmx_mio_uartx_iir_s cn30xx;
+ struct cvmx_mio_uartx_iir_s cn31xx;
+ struct cvmx_mio_uartx_iir_s cn38xx;
+ struct cvmx_mio_uartx_iir_s cn38xxp2;
+ struct cvmx_mio_uartx_iir_s cn50xx;
+ struct cvmx_mio_uartx_iir_s cn52xx;
+ struct cvmx_mio_uartx_iir_s cn52xxp1;
+ struct cvmx_mio_uartx_iir_s cn56xx;
+ struct cvmx_mio_uartx_iir_s cn56xxp1;
+ struct cvmx_mio_uartx_iir_s cn58xx;
+ struct cvmx_mio_uartx_iir_s cn58xxp1;
+ struct cvmx_mio_uartx_iir_s cn63xx;
+ struct cvmx_mio_uartx_iir_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_lcr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_lcr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dlab:1;
+ uint64_t brk:1;
+ uint64_t reserved_5_5:1;
+ uint64_t eps:1;
+ uint64_t pen:1;
+ uint64_t stop:1;
+ uint64_t cls:2;
+ } s;
+ struct cvmx_mio_uartx_lcr_s cn30xx;
+ struct cvmx_mio_uartx_lcr_s cn31xx;
+ struct cvmx_mio_uartx_lcr_s cn38xx;
+ struct cvmx_mio_uartx_lcr_s cn38xxp2;
+ struct cvmx_mio_uartx_lcr_s cn50xx;
+ struct cvmx_mio_uartx_lcr_s cn52xx;
+ struct cvmx_mio_uartx_lcr_s cn52xxp1;
+ struct cvmx_mio_uartx_lcr_s cn56xx;
+ struct cvmx_mio_uartx_lcr_s cn56xxp1;
+ struct cvmx_mio_uartx_lcr_s cn58xx;
+ struct cvmx_mio_uartx_lcr_s cn58xxp1;
+ struct cvmx_mio_uartx_lcr_s cn63xx;
+ struct cvmx_mio_uartx_lcr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_lsr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_lsr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ferr:1;
+ uint64_t temt:1;
+ uint64_t thre:1;
+ uint64_t bi:1;
+ uint64_t fe:1;
+ uint64_t pe:1;
+ uint64_t oe:1;
+ uint64_t dr:1;
+ } s;
+ struct cvmx_mio_uartx_lsr_s cn30xx;
+ struct cvmx_mio_uartx_lsr_s cn31xx;
+ struct cvmx_mio_uartx_lsr_s cn38xx;
+ struct cvmx_mio_uartx_lsr_s cn38xxp2;
+ struct cvmx_mio_uartx_lsr_s cn50xx;
+ struct cvmx_mio_uartx_lsr_s cn52xx;
+ struct cvmx_mio_uartx_lsr_s cn52xxp1;
+ struct cvmx_mio_uartx_lsr_s cn56xx;
+ struct cvmx_mio_uartx_lsr_s cn56xxp1;
+ struct cvmx_mio_uartx_lsr_s cn58xx;
+ struct cvmx_mio_uartx_lsr_s cn58xxp1;
+ struct cvmx_mio_uartx_lsr_s cn63xx;
+ struct cvmx_mio_uartx_lsr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_mcr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_mcr_s {
+ uint64_t reserved_6_63:58;
+ uint64_t afce:1;
+ uint64_t loop:1;
+ uint64_t out2:1;
+ uint64_t out1:1;
+ uint64_t rts:1;
+ uint64_t dtr:1;
+ } s;
+ struct cvmx_mio_uartx_mcr_s cn30xx;
+ struct cvmx_mio_uartx_mcr_s cn31xx;
+ struct cvmx_mio_uartx_mcr_s cn38xx;
+ struct cvmx_mio_uartx_mcr_s cn38xxp2;
+ struct cvmx_mio_uartx_mcr_s cn50xx;
+ struct cvmx_mio_uartx_mcr_s cn52xx;
+ struct cvmx_mio_uartx_mcr_s cn52xxp1;
+ struct cvmx_mio_uartx_mcr_s cn56xx;
+ struct cvmx_mio_uartx_mcr_s cn56xxp1;
+ struct cvmx_mio_uartx_mcr_s cn58xx;
+ struct cvmx_mio_uartx_mcr_s cn58xxp1;
+ struct cvmx_mio_uartx_mcr_s cn63xx;
+ struct cvmx_mio_uartx_mcr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_msr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_msr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dcd:1;
+ uint64_t ri:1;
+ uint64_t dsr:1;
+ uint64_t cts:1;
+ uint64_t ddcd:1;
+ uint64_t teri:1;
+ uint64_t ddsr:1;
+ uint64_t dcts:1;
+ } s;
+ struct cvmx_mio_uartx_msr_s cn30xx;
+ struct cvmx_mio_uartx_msr_s cn31xx;
+ struct cvmx_mio_uartx_msr_s cn38xx;
+ struct cvmx_mio_uartx_msr_s cn38xxp2;
+ struct cvmx_mio_uartx_msr_s cn50xx;
+ struct cvmx_mio_uartx_msr_s cn52xx;
+ struct cvmx_mio_uartx_msr_s cn52xxp1;
+ struct cvmx_mio_uartx_msr_s cn56xx;
+ struct cvmx_mio_uartx_msr_s cn56xxp1;
+ struct cvmx_mio_uartx_msr_s cn58xx;
+ struct cvmx_mio_uartx_msr_s cn58xxp1;
+ struct cvmx_mio_uartx_msr_s cn63xx;
+ struct cvmx_mio_uartx_msr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_rbr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_rbr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rbr:8;
+ } s;
+ struct cvmx_mio_uartx_rbr_s cn30xx;
+ struct cvmx_mio_uartx_rbr_s cn31xx;
+ struct cvmx_mio_uartx_rbr_s cn38xx;
+ struct cvmx_mio_uartx_rbr_s cn38xxp2;
+ struct cvmx_mio_uartx_rbr_s cn50xx;
+ struct cvmx_mio_uartx_rbr_s cn52xx;
+ struct cvmx_mio_uartx_rbr_s cn52xxp1;
+ struct cvmx_mio_uartx_rbr_s cn56xx;
+ struct cvmx_mio_uartx_rbr_s cn56xxp1;
+ struct cvmx_mio_uartx_rbr_s cn58xx;
+ struct cvmx_mio_uartx_rbr_s cn58xxp1;
+ struct cvmx_mio_uartx_rbr_s cn63xx;
+ struct cvmx_mio_uartx_rbr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_rfl {
+ uint64_t u64;
+ struct cvmx_mio_uartx_rfl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t rfl:7;
+ } s;
+ struct cvmx_mio_uartx_rfl_s cn30xx;
+ struct cvmx_mio_uartx_rfl_s cn31xx;
+ struct cvmx_mio_uartx_rfl_s cn38xx;
+ struct cvmx_mio_uartx_rfl_s cn38xxp2;
+ struct cvmx_mio_uartx_rfl_s cn50xx;
+ struct cvmx_mio_uartx_rfl_s cn52xx;
+ struct cvmx_mio_uartx_rfl_s cn52xxp1;
+ struct cvmx_mio_uartx_rfl_s cn56xx;
+ struct cvmx_mio_uartx_rfl_s cn56xxp1;
+ struct cvmx_mio_uartx_rfl_s cn58xx;
+ struct cvmx_mio_uartx_rfl_s cn58xxp1;
+ struct cvmx_mio_uartx_rfl_s cn63xx;
+ struct cvmx_mio_uartx_rfl_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_rfw {
+ uint64_t u64;
+ struct cvmx_mio_uartx_rfw_s {
+ uint64_t reserved_10_63:54;
+ uint64_t rffe:1;
+ uint64_t rfpe:1;
+ uint64_t rfwd:8;
+ } s;
+ struct cvmx_mio_uartx_rfw_s cn30xx;
+ struct cvmx_mio_uartx_rfw_s cn31xx;
+ struct cvmx_mio_uartx_rfw_s cn38xx;
+ struct cvmx_mio_uartx_rfw_s cn38xxp2;
+ struct cvmx_mio_uartx_rfw_s cn50xx;
+ struct cvmx_mio_uartx_rfw_s cn52xx;
+ struct cvmx_mio_uartx_rfw_s cn52xxp1;
+ struct cvmx_mio_uartx_rfw_s cn56xx;
+ struct cvmx_mio_uartx_rfw_s cn56xxp1;
+ struct cvmx_mio_uartx_rfw_s cn58xx;
+ struct cvmx_mio_uartx_rfw_s cn58xxp1;
+ struct cvmx_mio_uartx_rfw_s cn63xx;
+ struct cvmx_mio_uartx_rfw_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_sbcr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_sbcr_s {
+ uint64_t reserved_1_63:63;
+ uint64_t sbcr:1;
+ } s;
+ struct cvmx_mio_uartx_sbcr_s cn30xx;
+ struct cvmx_mio_uartx_sbcr_s cn31xx;
+ struct cvmx_mio_uartx_sbcr_s cn38xx;
+ struct cvmx_mio_uartx_sbcr_s cn38xxp2;
+ struct cvmx_mio_uartx_sbcr_s cn50xx;
+ struct cvmx_mio_uartx_sbcr_s cn52xx;
+ struct cvmx_mio_uartx_sbcr_s cn52xxp1;
+ struct cvmx_mio_uartx_sbcr_s cn56xx;
+ struct cvmx_mio_uartx_sbcr_s cn56xxp1;
+ struct cvmx_mio_uartx_sbcr_s cn58xx;
+ struct cvmx_mio_uartx_sbcr_s cn58xxp1;
+ struct cvmx_mio_uartx_sbcr_s cn63xx;
+ struct cvmx_mio_uartx_sbcr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_scr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_scr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t scr:8;
+ } s;
+ struct cvmx_mio_uartx_scr_s cn30xx;
+ struct cvmx_mio_uartx_scr_s cn31xx;
+ struct cvmx_mio_uartx_scr_s cn38xx;
+ struct cvmx_mio_uartx_scr_s cn38xxp2;
+ struct cvmx_mio_uartx_scr_s cn50xx;
+ struct cvmx_mio_uartx_scr_s cn52xx;
+ struct cvmx_mio_uartx_scr_s cn52xxp1;
+ struct cvmx_mio_uartx_scr_s cn56xx;
+ struct cvmx_mio_uartx_scr_s cn56xxp1;
+ struct cvmx_mio_uartx_scr_s cn58xx;
+ struct cvmx_mio_uartx_scr_s cn58xxp1;
+ struct cvmx_mio_uartx_scr_s cn63xx;
+ struct cvmx_mio_uartx_scr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_sfe {
+ uint64_t u64;
+ struct cvmx_mio_uartx_sfe_s {
+ uint64_t reserved_1_63:63;
+ uint64_t sfe:1;
+ } s;
+ struct cvmx_mio_uartx_sfe_s cn30xx;
+ struct cvmx_mio_uartx_sfe_s cn31xx;
+ struct cvmx_mio_uartx_sfe_s cn38xx;
+ struct cvmx_mio_uartx_sfe_s cn38xxp2;
+ struct cvmx_mio_uartx_sfe_s cn50xx;
+ struct cvmx_mio_uartx_sfe_s cn52xx;
+ struct cvmx_mio_uartx_sfe_s cn52xxp1;
+ struct cvmx_mio_uartx_sfe_s cn56xx;
+ struct cvmx_mio_uartx_sfe_s cn56xxp1;
+ struct cvmx_mio_uartx_sfe_s cn58xx;
+ struct cvmx_mio_uartx_sfe_s cn58xxp1;
+ struct cvmx_mio_uartx_sfe_s cn63xx;
+ struct cvmx_mio_uartx_sfe_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_srr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_srr_s {
+ uint64_t reserved_3_63:61;
+ uint64_t stfr:1;
+ uint64_t srfr:1;
+ uint64_t usr:1;
+ } s;
+ struct cvmx_mio_uartx_srr_s cn30xx;
+ struct cvmx_mio_uartx_srr_s cn31xx;
+ struct cvmx_mio_uartx_srr_s cn38xx;
+ struct cvmx_mio_uartx_srr_s cn38xxp2;
+ struct cvmx_mio_uartx_srr_s cn50xx;
+ struct cvmx_mio_uartx_srr_s cn52xx;
+ struct cvmx_mio_uartx_srr_s cn52xxp1;
+ struct cvmx_mio_uartx_srr_s cn56xx;
+ struct cvmx_mio_uartx_srr_s cn56xxp1;
+ struct cvmx_mio_uartx_srr_s cn58xx;
+ struct cvmx_mio_uartx_srr_s cn58xxp1;
+ struct cvmx_mio_uartx_srr_s cn63xx;
+ struct cvmx_mio_uartx_srr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_srt {
+ uint64_t u64;
+ struct cvmx_mio_uartx_srt_s {
+ uint64_t reserved_2_63:62;
+ uint64_t srt:2;
+ } s;
+ struct cvmx_mio_uartx_srt_s cn30xx;
+ struct cvmx_mio_uartx_srt_s cn31xx;
+ struct cvmx_mio_uartx_srt_s cn38xx;
+ struct cvmx_mio_uartx_srt_s cn38xxp2;
+ struct cvmx_mio_uartx_srt_s cn50xx;
+ struct cvmx_mio_uartx_srt_s cn52xx;
+ struct cvmx_mio_uartx_srt_s cn52xxp1;
+ struct cvmx_mio_uartx_srt_s cn56xx;
+ struct cvmx_mio_uartx_srt_s cn56xxp1;
+ struct cvmx_mio_uartx_srt_s cn58xx;
+ struct cvmx_mio_uartx_srt_s cn58xxp1;
+ struct cvmx_mio_uartx_srt_s cn63xx;
+ struct cvmx_mio_uartx_srt_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_srts {
+ uint64_t u64;
+ struct cvmx_mio_uartx_srts_s {
+ uint64_t reserved_1_63:63;
+ uint64_t srts:1;
+ } s;
+ struct cvmx_mio_uartx_srts_s cn30xx;
+ struct cvmx_mio_uartx_srts_s cn31xx;
+ struct cvmx_mio_uartx_srts_s cn38xx;
+ struct cvmx_mio_uartx_srts_s cn38xxp2;
+ struct cvmx_mio_uartx_srts_s cn50xx;
+ struct cvmx_mio_uartx_srts_s cn52xx;
+ struct cvmx_mio_uartx_srts_s cn52xxp1;
+ struct cvmx_mio_uartx_srts_s cn56xx;
+ struct cvmx_mio_uartx_srts_s cn56xxp1;
+ struct cvmx_mio_uartx_srts_s cn58xx;
+ struct cvmx_mio_uartx_srts_s cn58xxp1;
+ struct cvmx_mio_uartx_srts_s cn63xx;
+ struct cvmx_mio_uartx_srts_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_stt {
+ uint64_t u64;
+ struct cvmx_mio_uartx_stt_s {
+ uint64_t reserved_2_63:62;
+ uint64_t stt:2;
+ } s;
+ struct cvmx_mio_uartx_stt_s cn30xx;
+ struct cvmx_mio_uartx_stt_s cn31xx;
+ struct cvmx_mio_uartx_stt_s cn38xx;
+ struct cvmx_mio_uartx_stt_s cn38xxp2;
+ struct cvmx_mio_uartx_stt_s cn50xx;
+ struct cvmx_mio_uartx_stt_s cn52xx;
+ struct cvmx_mio_uartx_stt_s cn52xxp1;
+ struct cvmx_mio_uartx_stt_s cn56xx;
+ struct cvmx_mio_uartx_stt_s cn56xxp1;
+ struct cvmx_mio_uartx_stt_s cn58xx;
+ struct cvmx_mio_uartx_stt_s cn58xxp1;
+ struct cvmx_mio_uartx_stt_s cn63xx;
+ struct cvmx_mio_uartx_stt_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_tfl {
+ uint64_t u64;
+ struct cvmx_mio_uartx_tfl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t tfl:7;
+ } s;
+ struct cvmx_mio_uartx_tfl_s cn30xx;
+ struct cvmx_mio_uartx_tfl_s cn31xx;
+ struct cvmx_mio_uartx_tfl_s cn38xx;
+ struct cvmx_mio_uartx_tfl_s cn38xxp2;
+ struct cvmx_mio_uartx_tfl_s cn50xx;
+ struct cvmx_mio_uartx_tfl_s cn52xx;
+ struct cvmx_mio_uartx_tfl_s cn52xxp1;
+ struct cvmx_mio_uartx_tfl_s cn56xx;
+ struct cvmx_mio_uartx_tfl_s cn56xxp1;
+ struct cvmx_mio_uartx_tfl_s cn58xx;
+ struct cvmx_mio_uartx_tfl_s cn58xxp1;
+ struct cvmx_mio_uartx_tfl_s cn63xx;
+ struct cvmx_mio_uartx_tfl_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_tfr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_tfr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t tfr:8;
+ } s;
+ struct cvmx_mio_uartx_tfr_s cn30xx;
+ struct cvmx_mio_uartx_tfr_s cn31xx;
+ struct cvmx_mio_uartx_tfr_s cn38xx;
+ struct cvmx_mio_uartx_tfr_s cn38xxp2;
+ struct cvmx_mio_uartx_tfr_s cn50xx;
+ struct cvmx_mio_uartx_tfr_s cn52xx;
+ struct cvmx_mio_uartx_tfr_s cn52xxp1;
+ struct cvmx_mio_uartx_tfr_s cn56xx;
+ struct cvmx_mio_uartx_tfr_s cn56xxp1;
+ struct cvmx_mio_uartx_tfr_s cn58xx;
+ struct cvmx_mio_uartx_tfr_s cn58xxp1;
+ struct cvmx_mio_uartx_tfr_s cn63xx;
+ struct cvmx_mio_uartx_tfr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_thr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_thr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t thr:8;
+ } s;
+ struct cvmx_mio_uartx_thr_s cn30xx;
+ struct cvmx_mio_uartx_thr_s cn31xx;
+ struct cvmx_mio_uartx_thr_s cn38xx;
+ struct cvmx_mio_uartx_thr_s cn38xxp2;
+ struct cvmx_mio_uartx_thr_s cn50xx;
+ struct cvmx_mio_uartx_thr_s cn52xx;
+ struct cvmx_mio_uartx_thr_s cn52xxp1;
+ struct cvmx_mio_uartx_thr_s cn56xx;
+ struct cvmx_mio_uartx_thr_s cn56xxp1;
+ struct cvmx_mio_uartx_thr_s cn58xx;
+ struct cvmx_mio_uartx_thr_s cn58xxp1;
+ struct cvmx_mio_uartx_thr_s cn63xx;
+ struct cvmx_mio_uartx_thr_s cn63xxp1;
+};
+
+union cvmx_mio_uartx_usr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_usr_s {
+ uint64_t reserved_5_63:59;
+ uint64_t rff:1;
+ uint64_t rfne:1;
+ uint64_t tfe:1;
+ uint64_t tfnf:1;
+ uint64_t busy:1;
+ } s;
+ struct cvmx_mio_uartx_usr_s cn30xx;
+ struct cvmx_mio_uartx_usr_s cn31xx;
+ struct cvmx_mio_uartx_usr_s cn38xx;
+ struct cvmx_mio_uartx_usr_s cn38xxp2;
+ struct cvmx_mio_uartx_usr_s cn50xx;
+ struct cvmx_mio_uartx_usr_s cn52xx;
+ struct cvmx_mio_uartx_usr_s cn52xxp1;
+ struct cvmx_mio_uartx_usr_s cn56xx;
+ struct cvmx_mio_uartx_usr_s cn56xxp1;
+ struct cvmx_mio_uartx_usr_s cn58xx;
+ struct cvmx_mio_uartx_usr_s cn58xxp1;
+ struct cvmx_mio_uartx_usr_s cn63xx;
+ struct cvmx_mio_uartx_usr_s cn63xxp1;
+};
+
+union cvmx_mio_uart2_dlh {
+ uint64_t u64;
+ struct cvmx_mio_uart2_dlh_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dlh:8;
+ } s;
+ struct cvmx_mio_uart2_dlh_s cn52xx;
+ struct cvmx_mio_uart2_dlh_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_dll {
+ uint64_t u64;
+ struct cvmx_mio_uart2_dll_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dll:8;
+ } s;
+ struct cvmx_mio_uart2_dll_s cn52xx;
+ struct cvmx_mio_uart2_dll_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_far {
+ uint64_t u64;
+ struct cvmx_mio_uart2_far_s {
+ uint64_t reserved_1_63:63;
+ uint64_t far:1;
+ } s;
+ struct cvmx_mio_uart2_far_s cn52xx;
+ struct cvmx_mio_uart2_far_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_fcr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_fcr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rxtrig:2;
+ uint64_t txtrig:2;
+ uint64_t reserved_3_3:1;
+ uint64_t txfr:1;
+ uint64_t rxfr:1;
+ uint64_t en:1;
+ } s;
+ struct cvmx_mio_uart2_fcr_s cn52xx;
+ struct cvmx_mio_uart2_fcr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_htx {
+ uint64_t u64;
+ struct cvmx_mio_uart2_htx_s {
+ uint64_t reserved_1_63:63;
+ uint64_t htx:1;
+ } s;
+ struct cvmx_mio_uart2_htx_s cn52xx;
+ struct cvmx_mio_uart2_htx_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_ier {
+ uint64_t u64;
+ struct cvmx_mio_uart2_ier_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ptime:1;
+ uint64_t reserved_4_6:3;
+ uint64_t edssi:1;
+ uint64_t elsi:1;
+ uint64_t etbei:1;
+ uint64_t erbfi:1;
+ } s;
+ struct cvmx_mio_uart2_ier_s cn52xx;
+ struct cvmx_mio_uart2_ier_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_iir {
+ uint64_t u64;
+ struct cvmx_mio_uart2_iir_s {
+ uint64_t reserved_8_63:56;
+ uint64_t fen:2;
+ uint64_t reserved_4_5:2;
+ uint64_t iid:4;
+ } s;
+ struct cvmx_mio_uart2_iir_s cn52xx;
+ struct cvmx_mio_uart2_iir_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_lcr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_lcr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dlab:1;
+ uint64_t brk:1;
+ uint64_t reserved_5_5:1;
+ uint64_t eps:1;
+ uint64_t pen:1;
+ uint64_t stop:1;
+ uint64_t cls:2;
+ } s;
+ struct cvmx_mio_uart2_lcr_s cn52xx;
+ struct cvmx_mio_uart2_lcr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_lsr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_lsr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ferr:1;
+ uint64_t temt:1;
+ uint64_t thre:1;
+ uint64_t bi:1;
+ uint64_t fe:1;
+ uint64_t pe:1;
+ uint64_t oe:1;
+ uint64_t dr:1;
+ } s;
+ struct cvmx_mio_uart2_lsr_s cn52xx;
+ struct cvmx_mio_uart2_lsr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_mcr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_mcr_s {
+ uint64_t reserved_6_63:58;
+ uint64_t afce:1;
+ uint64_t loop:1;
+ uint64_t out2:1;
+ uint64_t out1:1;
+ uint64_t rts:1;
+ uint64_t dtr:1;
+ } s;
+ struct cvmx_mio_uart2_mcr_s cn52xx;
+ struct cvmx_mio_uart2_mcr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_msr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_msr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dcd:1;
+ uint64_t ri:1;
+ uint64_t dsr:1;
+ uint64_t cts:1;
+ uint64_t ddcd:1;
+ uint64_t teri:1;
+ uint64_t ddsr:1;
+ uint64_t dcts:1;
+ } s;
+ struct cvmx_mio_uart2_msr_s cn52xx;
+ struct cvmx_mio_uart2_msr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_rbr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_rbr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rbr:8;
+ } s;
+ struct cvmx_mio_uart2_rbr_s cn52xx;
+ struct cvmx_mio_uart2_rbr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_rfl {
+ uint64_t u64;
+ struct cvmx_mio_uart2_rfl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t rfl:7;
+ } s;
+ struct cvmx_mio_uart2_rfl_s cn52xx;
+ struct cvmx_mio_uart2_rfl_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_rfw {
+ uint64_t u64;
+ struct cvmx_mio_uart2_rfw_s {
+ uint64_t reserved_10_63:54;
+ uint64_t rffe:1;
+ uint64_t rfpe:1;
+ uint64_t rfwd:8;
+ } s;
+ struct cvmx_mio_uart2_rfw_s cn52xx;
+ struct cvmx_mio_uart2_rfw_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_sbcr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_sbcr_s {
+ uint64_t reserved_1_63:63;
+ uint64_t sbcr:1;
+ } s;
+ struct cvmx_mio_uart2_sbcr_s cn52xx;
+ struct cvmx_mio_uart2_sbcr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_scr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_scr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t scr:8;
+ } s;
+ struct cvmx_mio_uart2_scr_s cn52xx;
+ struct cvmx_mio_uart2_scr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_sfe {
+ uint64_t u64;
+ struct cvmx_mio_uart2_sfe_s {
+ uint64_t reserved_1_63:63;
+ uint64_t sfe:1;
+ } s;
+ struct cvmx_mio_uart2_sfe_s cn52xx;
+ struct cvmx_mio_uart2_sfe_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_srr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_srr_s {
+ uint64_t reserved_3_63:61;
+ uint64_t stfr:1;
+ uint64_t srfr:1;
+ uint64_t usr:1;
+ } s;
+ struct cvmx_mio_uart2_srr_s cn52xx;
+ struct cvmx_mio_uart2_srr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_srt {
+ uint64_t u64;
+ struct cvmx_mio_uart2_srt_s {
+ uint64_t reserved_2_63:62;
+ uint64_t srt:2;
+ } s;
+ struct cvmx_mio_uart2_srt_s cn52xx;
+ struct cvmx_mio_uart2_srt_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_srts {
+ uint64_t u64;
+ struct cvmx_mio_uart2_srts_s {
+ uint64_t reserved_1_63:63;
+ uint64_t srts:1;
+ } s;
+ struct cvmx_mio_uart2_srts_s cn52xx;
+ struct cvmx_mio_uart2_srts_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_stt {
+ uint64_t u64;
+ struct cvmx_mio_uart2_stt_s {
+ uint64_t reserved_2_63:62;
+ uint64_t stt:2;
+ } s;
+ struct cvmx_mio_uart2_stt_s cn52xx;
+ struct cvmx_mio_uart2_stt_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_tfl {
+ uint64_t u64;
+ struct cvmx_mio_uart2_tfl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t tfl:7;
+ } s;
+ struct cvmx_mio_uart2_tfl_s cn52xx;
+ struct cvmx_mio_uart2_tfl_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_tfr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_tfr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t tfr:8;
+ } s;
+ struct cvmx_mio_uart2_tfr_s cn52xx;
+ struct cvmx_mio_uart2_tfr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_thr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_thr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t thr:8;
+ } s;
+ struct cvmx_mio_uart2_thr_s cn52xx;
+ struct cvmx_mio_uart2_thr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_usr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_usr_s {
+ uint64_t reserved_5_63:59;
+ uint64_t rff:1;
+ uint64_t rfne:1;
+ uint64_t tfe:1;
+ uint64_t tfnf:1;
+ uint64_t busy:1;
+ } s;
+ struct cvmx_mio_uart2_usr_s cn52xx;
+ struct cvmx_mio_uart2_usr_s cn52xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
new file mode 100644
index 00000000..7057c447
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
@@ -0,0 +1,334 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_MIXX_DEFS_H__
+#define __CVMX_MIXX_DEFS_H__
+
+#define CVMX_MIXX_BIST(offset) (CVMX_ADD_IO_SEG(0x0001070000100078ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_CTL(offset) (CVMX_ADD_IO_SEG(0x0001070000100020ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_INTENA(offset) (CVMX_ADD_IO_SEG(0x0001070000100050ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100030ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRHWM(offset) (CVMX_ADD_IO_SEG(0x0001070000100028ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRING1(offset) (CVMX_ADD_IO_SEG(0x0001070000100010ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_IRING2(offset) (CVMX_ADD_IO_SEG(0x0001070000100018ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ISR(offset) (CVMX_ADD_IO_SEG(0x0001070000100048ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100040ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORHWM(offset) (CVMX_ADD_IO_SEG(0x0001070000100038ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORING1(offset) (CVMX_ADD_IO_SEG(0x0001070000100000ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_ORING2(offset) (CVMX_ADD_IO_SEG(0x0001070000100008ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_REMCNT(offset) (CVMX_ADD_IO_SEG(0x0001070000100058ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_TSCTL(offset) (CVMX_ADD_IO_SEG(0x0001070000100068ull) + ((offset) & 1) * 2048)
+#define CVMX_MIXX_TSTAMP(offset) (CVMX_ADD_IO_SEG(0x0001070000100060ull) + ((offset) & 1) * 2048)
+
+union cvmx_mixx_bist {
+ uint64_t u64;
+ struct cvmx_mixx_bist_s {
+ uint64_t reserved_6_63:58;
+ uint64_t opfdat:1;
+ uint64_t mrgdat:1;
+ uint64_t mrqdat:1;
+ uint64_t ipfdat:1;
+ uint64_t irfdat:1;
+ uint64_t orfdat:1;
+ } s;
+ struct cvmx_mixx_bist_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t mrqdat:1;
+ uint64_t ipfdat:1;
+ uint64_t irfdat:1;
+ uint64_t orfdat:1;
+ } cn52xx;
+ struct cvmx_mixx_bist_cn52xx cn52xxp1;
+ struct cvmx_mixx_bist_cn52xx cn56xx;
+ struct cvmx_mixx_bist_cn52xx cn56xxp1;
+ struct cvmx_mixx_bist_s cn63xx;
+ struct cvmx_mixx_bist_s cn63xxp1;
+};
+
+union cvmx_mixx_ctl {
+ uint64_t u64;
+ struct cvmx_mixx_ctl_s {
+ uint64_t reserved_12_63:52;
+ uint64_t ts_thresh:4;
+ uint64_t crc_strip:1;
+ uint64_t busy:1;
+ uint64_t en:1;
+ uint64_t reset:1;
+ uint64_t lendian:1;
+ uint64_t nbtarb:1;
+ uint64_t mrq_hwm:2;
+ } s;
+ struct cvmx_mixx_ctl_cn52xx {
+ uint64_t reserved_8_63:56;
+ uint64_t crc_strip:1;
+ uint64_t busy:1;
+ uint64_t en:1;
+ uint64_t reset:1;
+ uint64_t lendian:1;
+ uint64_t nbtarb:1;
+ uint64_t mrq_hwm:2;
+ } cn52xx;
+ struct cvmx_mixx_ctl_cn52xx cn52xxp1;
+ struct cvmx_mixx_ctl_cn52xx cn56xx;
+ struct cvmx_mixx_ctl_cn52xx cn56xxp1;
+ struct cvmx_mixx_ctl_s cn63xx;
+ struct cvmx_mixx_ctl_s cn63xxp1;
+};
+
+union cvmx_mixx_intena {
+ uint64_t u64;
+ struct cvmx_mixx_intena_s {
+ uint64_t reserved_8_63:56;
+ uint64_t tsena:1;
+ uint64_t orunena:1;
+ uint64_t irunena:1;
+ uint64_t data_drpena:1;
+ uint64_t ithena:1;
+ uint64_t othena:1;
+ uint64_t ivfena:1;
+ uint64_t ovfena:1;
+ } s;
+ struct cvmx_mixx_intena_cn52xx {
+ uint64_t reserved_7_63:57;
+ uint64_t orunena:1;
+ uint64_t irunena:1;
+ uint64_t data_drpena:1;
+ uint64_t ithena:1;
+ uint64_t othena:1;
+ uint64_t ivfena:1;
+ uint64_t ovfena:1;
+ } cn52xx;
+ struct cvmx_mixx_intena_cn52xx cn52xxp1;
+ struct cvmx_mixx_intena_cn52xx cn56xx;
+ struct cvmx_mixx_intena_cn52xx cn56xxp1;
+ struct cvmx_mixx_intena_s cn63xx;
+ struct cvmx_mixx_intena_s cn63xxp1;
+};
+
+union cvmx_mixx_ircnt {
+ uint64_t u64;
+ struct cvmx_mixx_ircnt_s {
+ uint64_t reserved_20_63:44;
+ uint64_t ircnt:20;
+ } s;
+ struct cvmx_mixx_ircnt_s cn52xx;
+ struct cvmx_mixx_ircnt_s cn52xxp1;
+ struct cvmx_mixx_ircnt_s cn56xx;
+ struct cvmx_mixx_ircnt_s cn56xxp1;
+ struct cvmx_mixx_ircnt_s cn63xx;
+ struct cvmx_mixx_ircnt_s cn63xxp1;
+};
+
+union cvmx_mixx_irhwm {
+ uint64_t u64;
+ struct cvmx_mixx_irhwm_s {
+ uint64_t reserved_40_63:24;
+ uint64_t ibplwm:20;
+ uint64_t irhwm:20;
+ } s;
+ struct cvmx_mixx_irhwm_s cn52xx;
+ struct cvmx_mixx_irhwm_s cn52xxp1;
+ struct cvmx_mixx_irhwm_s cn56xx;
+ struct cvmx_mixx_irhwm_s cn56xxp1;
+ struct cvmx_mixx_irhwm_s cn63xx;
+ struct cvmx_mixx_irhwm_s cn63xxp1;
+};
+
+union cvmx_mixx_iring1 {
+ uint64_t u64;
+ struct cvmx_mixx_iring1_s {
+ uint64_t reserved_60_63:4;
+ uint64_t isize:20;
+ uint64_t ibase:37;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_mixx_iring1_cn52xx {
+ uint64_t reserved_60_63:4;
+ uint64_t isize:20;
+ uint64_t reserved_36_39:4;
+ uint64_t ibase:33;
+ uint64_t reserved_0_2:3;
+ } cn52xx;
+ struct cvmx_mixx_iring1_cn52xx cn52xxp1;
+ struct cvmx_mixx_iring1_cn52xx cn56xx;
+ struct cvmx_mixx_iring1_cn52xx cn56xxp1;
+ struct cvmx_mixx_iring1_s cn63xx;
+ struct cvmx_mixx_iring1_s cn63xxp1;
+};
+
+union cvmx_mixx_iring2 {
+ uint64_t u64;
+ struct cvmx_mixx_iring2_s {
+ uint64_t reserved_52_63:12;
+ uint64_t itlptr:20;
+ uint64_t reserved_20_31:12;
+ uint64_t idbell:20;
+ } s;
+ struct cvmx_mixx_iring2_s cn52xx;
+ struct cvmx_mixx_iring2_s cn52xxp1;
+ struct cvmx_mixx_iring2_s cn56xx;
+ struct cvmx_mixx_iring2_s cn56xxp1;
+ struct cvmx_mixx_iring2_s cn63xx;
+ struct cvmx_mixx_iring2_s cn63xxp1;
+};
+
+union cvmx_mixx_isr {
+ uint64_t u64;
+ struct cvmx_mixx_isr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ts:1;
+ uint64_t orun:1;
+ uint64_t irun:1;
+ uint64_t data_drp:1;
+ uint64_t irthresh:1;
+ uint64_t orthresh:1;
+ uint64_t idblovf:1;
+ uint64_t odblovf:1;
+ } s;
+ struct cvmx_mixx_isr_cn52xx {
+ uint64_t reserved_7_63:57;
+ uint64_t orun:1;
+ uint64_t irun:1;
+ uint64_t data_drp:1;
+ uint64_t irthresh:1;
+ uint64_t orthresh:1;
+ uint64_t idblovf:1;
+ uint64_t odblovf:1;
+ } cn52xx;
+ struct cvmx_mixx_isr_cn52xx cn52xxp1;
+ struct cvmx_mixx_isr_cn52xx cn56xx;
+ struct cvmx_mixx_isr_cn52xx cn56xxp1;
+ struct cvmx_mixx_isr_s cn63xx;
+ struct cvmx_mixx_isr_s cn63xxp1;
+};
+
+union cvmx_mixx_orcnt {
+ uint64_t u64;
+ struct cvmx_mixx_orcnt_s {
+ uint64_t reserved_20_63:44;
+ uint64_t orcnt:20;
+ } s;
+ struct cvmx_mixx_orcnt_s cn52xx;
+ struct cvmx_mixx_orcnt_s cn52xxp1;
+ struct cvmx_mixx_orcnt_s cn56xx;
+ struct cvmx_mixx_orcnt_s cn56xxp1;
+ struct cvmx_mixx_orcnt_s cn63xx;
+ struct cvmx_mixx_orcnt_s cn63xxp1;
+};
+
+union cvmx_mixx_orhwm {
+ uint64_t u64;
+ struct cvmx_mixx_orhwm_s {
+ uint64_t reserved_20_63:44;
+ uint64_t orhwm:20;
+ } s;
+ struct cvmx_mixx_orhwm_s cn52xx;
+ struct cvmx_mixx_orhwm_s cn52xxp1;
+ struct cvmx_mixx_orhwm_s cn56xx;
+ struct cvmx_mixx_orhwm_s cn56xxp1;
+ struct cvmx_mixx_orhwm_s cn63xx;
+ struct cvmx_mixx_orhwm_s cn63xxp1;
+};
+
+union cvmx_mixx_oring1 {
+ uint64_t u64;
+ struct cvmx_mixx_oring1_s {
+ uint64_t reserved_60_63:4;
+ uint64_t osize:20;
+ uint64_t obase:37;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_mixx_oring1_cn52xx {
+ uint64_t reserved_60_63:4;
+ uint64_t osize:20;
+ uint64_t reserved_36_39:4;
+ uint64_t obase:33;
+ uint64_t reserved_0_2:3;
+ } cn52xx;
+ struct cvmx_mixx_oring1_cn52xx cn52xxp1;
+ struct cvmx_mixx_oring1_cn52xx cn56xx;
+ struct cvmx_mixx_oring1_cn52xx cn56xxp1;
+ struct cvmx_mixx_oring1_s cn63xx;
+ struct cvmx_mixx_oring1_s cn63xxp1;
+};
+
+union cvmx_mixx_oring2 {
+ uint64_t u64;
+ struct cvmx_mixx_oring2_s {
+ uint64_t reserved_52_63:12;
+ uint64_t otlptr:20;
+ uint64_t reserved_20_31:12;
+ uint64_t odbell:20;
+ } s;
+ struct cvmx_mixx_oring2_s cn52xx;
+ struct cvmx_mixx_oring2_s cn52xxp1;
+ struct cvmx_mixx_oring2_s cn56xx;
+ struct cvmx_mixx_oring2_s cn56xxp1;
+ struct cvmx_mixx_oring2_s cn63xx;
+ struct cvmx_mixx_oring2_s cn63xxp1;
+};
+
+union cvmx_mixx_remcnt {
+ uint64_t u64;
+ struct cvmx_mixx_remcnt_s {
+ uint64_t reserved_52_63:12;
+ uint64_t iremcnt:20;
+ uint64_t reserved_20_31:12;
+ uint64_t oremcnt:20;
+ } s;
+ struct cvmx_mixx_remcnt_s cn52xx;
+ struct cvmx_mixx_remcnt_s cn52xxp1;
+ struct cvmx_mixx_remcnt_s cn56xx;
+ struct cvmx_mixx_remcnt_s cn56xxp1;
+ struct cvmx_mixx_remcnt_s cn63xx;
+ struct cvmx_mixx_remcnt_s cn63xxp1;
+};
+
+union cvmx_mixx_tsctl {
+ uint64_t u64;
+ struct cvmx_mixx_tsctl_s {
+ uint64_t reserved_21_63:43;
+ uint64_t tsavl:5;
+ uint64_t reserved_13_15:3;
+ uint64_t tstot:5;
+ uint64_t reserved_5_7:3;
+ uint64_t tscnt:5;
+ } s;
+ struct cvmx_mixx_tsctl_s cn63xx;
+ struct cvmx_mixx_tsctl_s cn63xxp1;
+};
+
+union cvmx_mixx_tstamp {
+ uint64_t u64;
+ struct cvmx_mixx_tstamp_s {
+ uint64_t tstamp:64;
+ } s;
+ struct cvmx_mixx_tstamp_s cn63xx;
+ struct cvmx_mixx_tstamp_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-npei-defs.h b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
new file mode 100644
index 00000000..9899a9d2
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
@@ -0,0 +1,2479 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_NPEI_DEFS_H__
+#define __CVMX_NPEI_DEFS_H__
+
+#define CVMX_NPEI_BAR1_INDEXX(offset) (0x0000000000000000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_BIST_STATUS (0x0000000000000580ull)
+#define CVMX_NPEI_BIST_STATUS2 (0x0000000000000680ull)
+#define CVMX_NPEI_CTL_PORT0 (0x0000000000000250ull)
+#define CVMX_NPEI_CTL_PORT1 (0x0000000000000260ull)
+#define CVMX_NPEI_CTL_STATUS (0x0000000000000570ull)
+#define CVMX_NPEI_CTL_STATUS2 (0x0000000000003C00ull)
+#define CVMX_NPEI_DATA_OUT_CNT (0x00000000000005F0ull)
+#define CVMX_NPEI_DBG_DATA (0x0000000000000510ull)
+#define CVMX_NPEI_DBG_SELECT (0x0000000000000500ull)
+#define CVMX_NPEI_DMA0_INT_LEVEL (0x00000000000005C0ull)
+#define CVMX_NPEI_DMA1_INT_LEVEL (0x00000000000005D0ull)
+#define CVMX_NPEI_DMAX_COUNTS(offset) (0x0000000000000450ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_DBELL(offset) (0x00000000000003B0ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) (0x0000000000000400ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMAX_NADDR(offset) (0x00000000000004A0ull + ((offset) & 7) * 16)
+#define CVMX_NPEI_DMA_CNTS (0x00000000000005E0ull)
+#define CVMX_NPEI_DMA_CONTROL (0x00000000000003A0ull)
+#define CVMX_NPEI_DMA_PCIE_REQ_NUM (0x00000000000005B0ull)
+#define CVMX_NPEI_DMA_STATE1 (0x00000000000006C0ull)
+#define CVMX_NPEI_DMA_STATE1_P1 (0x0000000000000680ull)
+#define CVMX_NPEI_DMA_STATE2 (0x00000000000006D0ull)
+#define CVMX_NPEI_DMA_STATE2_P1 (0x0000000000000690ull)
+#define CVMX_NPEI_DMA_STATE3_P1 (0x00000000000006A0ull)
+#define CVMX_NPEI_DMA_STATE4_P1 (0x00000000000006B0ull)
+#define CVMX_NPEI_DMA_STATE5_P1 (0x00000000000006C0ull)
+#define CVMX_NPEI_INT_A_ENB (0x0000000000000560ull)
+#define CVMX_NPEI_INT_A_ENB2 (0x0000000000003CE0ull)
+#define CVMX_NPEI_INT_A_SUM (0x0000000000000550ull)
+#define CVMX_NPEI_INT_ENB (0x0000000000000540ull)
+#define CVMX_NPEI_INT_ENB2 (0x0000000000003CD0ull)
+#define CVMX_NPEI_INT_INFO (0x0000000000000590ull)
+#define CVMX_NPEI_INT_SUM (0x0000000000000530ull)
+#define CVMX_NPEI_INT_SUM2 (0x0000000000003CC0ull)
+#define CVMX_NPEI_LAST_WIN_RDATA0 (0x0000000000000600ull)
+#define CVMX_NPEI_LAST_WIN_RDATA1 (0x0000000000000610ull)
+#define CVMX_NPEI_MEM_ACCESS_CTL (0x00000000000004F0ull)
+#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) (0x0000000000000340ull + ((offset) & 31) * 16 - 16*12)
+#define CVMX_NPEI_MSI_ENB0 (0x0000000000003C50ull)
+#define CVMX_NPEI_MSI_ENB1 (0x0000000000003C60ull)
+#define CVMX_NPEI_MSI_ENB2 (0x0000000000003C70ull)
+#define CVMX_NPEI_MSI_ENB3 (0x0000000000003C80ull)
+#define CVMX_NPEI_MSI_RCV0 (0x0000000000003C10ull)
+#define CVMX_NPEI_MSI_RCV1 (0x0000000000003C20ull)
+#define CVMX_NPEI_MSI_RCV2 (0x0000000000003C30ull)
+#define CVMX_NPEI_MSI_RCV3 (0x0000000000003C40ull)
+#define CVMX_NPEI_MSI_RD_MAP (0x0000000000003CA0ull)
+#define CVMX_NPEI_MSI_W1C_ENB0 (0x0000000000003CF0ull)
+#define CVMX_NPEI_MSI_W1C_ENB1 (0x0000000000003D00ull)
+#define CVMX_NPEI_MSI_W1C_ENB2 (0x0000000000003D10ull)
+#define CVMX_NPEI_MSI_W1C_ENB3 (0x0000000000003D20ull)
+#define CVMX_NPEI_MSI_W1S_ENB0 (0x0000000000003D30ull)
+#define CVMX_NPEI_MSI_W1S_ENB1 (0x0000000000003D40ull)
+#define CVMX_NPEI_MSI_W1S_ENB2 (0x0000000000003D50ull)
+#define CVMX_NPEI_MSI_W1S_ENB3 (0x0000000000003D60ull)
+#define CVMX_NPEI_MSI_WR_MAP (0x0000000000003C90ull)
+#define CVMX_NPEI_PCIE_CREDIT_CNT (0x0000000000003D70ull)
+#define CVMX_NPEI_PCIE_MSI_RCV (0x0000000000003CB0ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B1 (0x0000000000000650ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B2 (0x0000000000000660ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B3 (0x0000000000000670ull)
+#define CVMX_NPEI_PKTX_CNTS(offset) (0x0000000000002400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) (0x0000000000002800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) (0x0000000000002C00ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) (0x0000000000003000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) (0x0000000000003400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_IN_BP(offset) (0x0000000000003800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) (0x0000000000001400ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) (0x0000000000001800ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) (0x0000000000001C00ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKT_CNT_INT (0x0000000000001110ull)
+#define CVMX_NPEI_PKT_CNT_INT_ENB (0x0000000000001130ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ES (0x00000000000010B0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_NS (0x00000000000010A0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ROR (0x0000000000001090ull)
+#define CVMX_NPEI_PKT_DPADDR (0x0000000000001080ull)
+#define CVMX_NPEI_PKT_INPUT_CONTROL (0x0000000000001150ull)
+#define CVMX_NPEI_PKT_INSTR_ENB (0x0000000000001000ull)
+#define CVMX_NPEI_PKT_INSTR_RD_SIZE (0x0000000000001190ull)
+#define CVMX_NPEI_PKT_INSTR_SIZE (0x0000000000001020ull)
+#define CVMX_NPEI_PKT_INT_LEVELS (0x0000000000001100ull)
+#define CVMX_NPEI_PKT_IN_BP (0x00000000000006B0ull)
+#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) (0x0000000000002000ull + ((offset) & 31) * 16)
+#define CVMX_NPEI_PKT_IN_INSTR_COUNTS (0x00000000000006A0ull)
+#define CVMX_NPEI_PKT_IN_PCIE_PORT (0x00000000000011A0ull)
+#define CVMX_NPEI_PKT_IPTR (0x0000000000001070ull)
+#define CVMX_NPEI_PKT_OUTPUT_WMARK (0x0000000000001160ull)
+#define CVMX_NPEI_PKT_OUT_BMODE (0x00000000000010D0ull)
+#define CVMX_NPEI_PKT_OUT_ENB (0x0000000000001010ull)
+#define CVMX_NPEI_PKT_PCIE_PORT (0x00000000000010E0ull)
+#define CVMX_NPEI_PKT_PORT_IN_RST (0x0000000000000690ull)
+#define CVMX_NPEI_PKT_SLIST_ES (0x0000000000001050ull)
+#define CVMX_NPEI_PKT_SLIST_ID_SIZE (0x0000000000001180ull)
+#define CVMX_NPEI_PKT_SLIST_NS (0x0000000000001040ull)
+#define CVMX_NPEI_PKT_SLIST_ROR (0x0000000000001030ull)
+#define CVMX_NPEI_PKT_TIME_INT (0x0000000000001120ull)
+#define CVMX_NPEI_PKT_TIME_INT_ENB (0x0000000000001140ull)
+#define CVMX_NPEI_RSL_INT_BLOCKS (0x0000000000000520ull)
+#define CVMX_NPEI_SCRATCH_1 (0x0000000000000270ull)
+#define CVMX_NPEI_STATE1 (0x0000000000000620ull)
+#define CVMX_NPEI_STATE2 (0x0000000000000630ull)
+#define CVMX_NPEI_STATE3 (0x0000000000000640ull)
+#define CVMX_NPEI_WINDOW_CTL (0x0000000000000380ull)
+#define CVMX_NPEI_WIN_RD_ADDR (0x0000000000000210ull)
+#define CVMX_NPEI_WIN_RD_DATA (0x0000000000000240ull)
+#define CVMX_NPEI_WIN_WR_ADDR (0x0000000000000200ull)
+#define CVMX_NPEI_WIN_WR_DATA (0x0000000000000220ull)
+#define CVMX_NPEI_WIN_WR_MASK (0x0000000000000230ull)
+
+union cvmx_npei_bar1_indexx {
+ uint32_t u32;
+ struct cvmx_npei_bar1_indexx_s {
+ uint32_t reserved_18_31:14;
+ uint32_t addr_idx:14;
+ uint32_t ca:1;
+ uint32_t end_swp:2;
+ uint32_t addr_v:1;
+ } s;
+ struct cvmx_npei_bar1_indexx_s cn52xx;
+ struct cvmx_npei_bar1_indexx_s cn52xxp1;
+ struct cvmx_npei_bar1_indexx_s cn56xx;
+ struct cvmx_npei_bar1_indexx_s cn56xxp1;
+};
+
+union cvmx_npei_bist_status {
+ uint64_t u64;
+ struct cvmx_npei_bist_status_s {
+ uint64_t pkt_rdf:1;
+ uint64_t reserved_60_62:3;
+ uint64_t pcr_gim:1;
+ uint64_t pkt_pif:1;
+ uint64_t pcsr_int:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_sl:1;
+ uint64_t reserved_50_52:3;
+ uint64_t pkt_ind:1;
+ uint64_t pkt_slm:1;
+ uint64_t reserved_36_47:12;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t reserved_31_31:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t reserved_2_2:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } s;
+ struct cvmx_npei_bist_status_cn52xx {
+ uint64_t pkt_rdf:1;
+ uint64_t reserved_60_62:3;
+ uint64_t pcr_gim:1;
+ uint64_t pkt_pif:1;
+ uint64_t pcsr_int:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_sl:1;
+ uint64_t pkt_imem:1;
+ uint64_t pkt_pfm:1;
+ uint64_t pkt_pof:1;
+ uint64_t reserved_48_49:2;
+ uint64_t pkt_pop0:1;
+ uint64_t pkt_pop1:1;
+ uint64_t d0_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t d4_mem:1;
+ uint64_t ds_mem:1;
+ uint64_t reserved_36_39:4;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t d4_pst:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t dif4:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn52xx;
+ struct cvmx_npei_bist_status_cn52xxp1 {
+ uint64_t reserved_46_63:18;
+ uint64_t d0_mem0:1;
+ uint64_t d1_mem1:1;
+ uint64_t d2_mem2:1;
+ uint64_t d3_mem3:1;
+ uint64_t dr0_mem:1;
+ uint64_t d0_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t dr1_mem:1;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t dr2_mem:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t dr3_mem:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn52xxp1;
+ struct cvmx_npei_bist_status_cn52xx cn56xx;
+ struct cvmx_npei_bist_status_cn56xxp1 {
+ uint64_t reserved_58_63:6;
+ uint64_t pcsr_int:1;
+ uint64_t pcsr_im:1;
+ uint64_t pcsr_cnt:1;
+ uint64_t pcsr_id:1;
+ uint64_t pcsr_sl:1;
+ uint64_t pkt_pout:1;
+ uint64_t pkt_imem:1;
+ uint64_t pkt_cntm:1;
+ uint64_t pkt_ind:1;
+ uint64_t pkt_slm:1;
+ uint64_t pkt_odf:1;
+ uint64_t pkt_oif:1;
+ uint64_t pkt_out:1;
+ uint64_t pkt_i0:1;
+ uint64_t pkt_i1:1;
+ uint64_t pkt_s0:1;
+ uint64_t pkt_s1:1;
+ uint64_t d0_mem:1;
+ uint64_t d1_mem:1;
+ uint64_t d2_mem:1;
+ uint64_t d3_mem:1;
+ uint64_t d4_mem:1;
+ uint64_t d0_pst:1;
+ uint64_t d1_pst:1;
+ uint64_t d2_pst:1;
+ uint64_t d3_pst:1;
+ uint64_t d4_pst:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t p2n1_po:1;
+ uint64_t p2n1_no:1;
+ uint64_t p2n1_co:1;
+ uint64_t p2n0_po:1;
+ uint64_t p2n0_no:1;
+ uint64_t p2n0_co:1;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t csm0:1;
+ uint64_t csm1:1;
+ uint64_t dif0:1;
+ uint64_t dif1:1;
+ uint64_t dif2:1;
+ uint64_t dif3:1;
+ uint64_t dif4:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn56xxp1;
+};
+
+union cvmx_npei_bist_status2 {
+ uint64_t u64;
+ struct cvmx_npei_bist_status2_s {
+ uint64_t reserved_14_63:50;
+ uint64_t prd_tag:1;
+ uint64_t prd_st0:1;
+ uint64_t prd_st1:1;
+ uint64_t prd_err:1;
+ uint64_t nrd_st:1;
+ uint64_t nwe_st:1;
+ uint64_t nwe_wr0:1;
+ uint64_t nwe_wr1:1;
+ uint64_t pkt_rd:1;
+ uint64_t psc_p0:1;
+ uint64_t psc_p1:1;
+ uint64_t pkt_gd:1;
+ uint64_t pkt_gl:1;
+ uint64_t pkt_blk:1;
+ } s;
+ struct cvmx_npei_bist_status2_s cn52xx;
+ struct cvmx_npei_bist_status2_s cn56xx;
+};
+
+union cvmx_npei_ctl_port0 {
+ uint64_t u64;
+ struct cvmx_npei_ctl_port0_s {
+ uint64_t reserved_21_63:43;
+ uint64_t waitl_com:1;
+ uint64_t intd:1;
+ uint64_t intc:1;
+ uint64_t intb:1;
+ uint64_t inta:1;
+ uint64_t intd_map:2;
+ uint64_t intc_map:2;
+ uint64_t intb_map:2;
+ uint64_t inta_map:2;
+ uint64_t ctlp_ro:1;
+ uint64_t reserved_6_6:1;
+ uint64_t ptlp_ro:1;
+ uint64_t bar2_enb:1;
+ uint64_t bar2_esx:2;
+ uint64_t bar2_cax:1;
+ uint64_t wait_com:1;
+ } s;
+ struct cvmx_npei_ctl_port0_s cn52xx;
+ struct cvmx_npei_ctl_port0_s cn52xxp1;
+ struct cvmx_npei_ctl_port0_s cn56xx;
+ struct cvmx_npei_ctl_port0_s cn56xxp1;
+};
+
+union cvmx_npei_ctl_port1 {
+ uint64_t u64;
+ struct cvmx_npei_ctl_port1_s {
+ uint64_t reserved_21_63:43;
+ uint64_t waitl_com:1;
+ uint64_t intd:1;
+ uint64_t intc:1;
+ uint64_t intb:1;
+ uint64_t inta:1;
+ uint64_t intd_map:2;
+ uint64_t intc_map:2;
+ uint64_t intb_map:2;
+ uint64_t inta_map:2;
+ uint64_t ctlp_ro:1;
+ uint64_t reserved_6_6:1;
+ uint64_t ptlp_ro:1;
+ uint64_t bar2_enb:1;
+ uint64_t bar2_esx:2;
+ uint64_t bar2_cax:1;
+ uint64_t wait_com:1;
+ } s;
+ struct cvmx_npei_ctl_port1_s cn52xx;
+ struct cvmx_npei_ctl_port1_s cn52xxp1;
+ struct cvmx_npei_ctl_port1_s cn56xx;
+ struct cvmx_npei_ctl_port1_s cn56xxp1;
+};
+
+union cvmx_npei_ctl_status {
+ uint64_t u64;
+ struct cvmx_npei_ctl_status_s {
+ uint64_t reserved_44_63:20;
+ uint64_t p1_ntags:6;
+ uint64_t p0_ntags:6;
+ uint64_t cfg_rtry:16;
+ uint64_t ring_en:1;
+ uint64_t lnk_rst:1;
+ uint64_t arb:1;
+ uint64_t pkt_bp:4;
+ uint64_t host_mode:1;
+ uint64_t chip_rev:8;
+ } s;
+ struct cvmx_npei_ctl_status_s cn52xx;
+ struct cvmx_npei_ctl_status_cn52xxp1 {
+ uint64_t reserved_44_63:20;
+ uint64_t p1_ntags:6;
+ uint64_t p0_ntags:6;
+ uint64_t cfg_rtry:16;
+ uint64_t reserved_15_15:1;
+ uint64_t lnk_rst:1;
+ uint64_t arb:1;
+ uint64_t reserved_9_12:4;
+ uint64_t host_mode:1;
+ uint64_t chip_rev:8;
+ } cn52xxp1;
+ struct cvmx_npei_ctl_status_s cn56xx;
+ struct cvmx_npei_ctl_status_cn56xxp1 {
+ uint64_t reserved_15_63:49;
+ uint64_t lnk_rst:1;
+ uint64_t arb:1;
+ uint64_t pkt_bp:4;
+ uint64_t host_mode:1;
+ uint64_t chip_rev:8;
+ } cn56xxp1;
+};
+
+union cvmx_npei_ctl_status2 {
+ uint64_t u64;
+ struct cvmx_npei_ctl_status2_s {
+ uint64_t reserved_16_63:48;
+ uint64_t mps:1;
+ uint64_t mrrs:3;
+ uint64_t c1_w_flt:1;
+ uint64_t c0_w_flt:1;
+ uint64_t c1_b1_s:3;
+ uint64_t c0_b1_s:3;
+ uint64_t c1_wi_d:1;
+ uint64_t c1_b0_d:1;
+ uint64_t c0_wi_d:1;
+ uint64_t c0_b0_d:1;
+ } s;
+ struct cvmx_npei_ctl_status2_s cn52xx;
+ struct cvmx_npei_ctl_status2_s cn52xxp1;
+ struct cvmx_npei_ctl_status2_s cn56xx;
+ struct cvmx_npei_ctl_status2_s cn56xxp1;
+};
+
+union cvmx_npei_data_out_cnt {
+ uint64_t u64;
+ struct cvmx_npei_data_out_cnt_s {
+ uint64_t reserved_44_63:20;
+ uint64_t p1_ucnt:16;
+ uint64_t p1_fcnt:6;
+ uint64_t p0_ucnt:16;
+ uint64_t p0_fcnt:6;
+ } s;
+ struct cvmx_npei_data_out_cnt_s cn52xx;
+ struct cvmx_npei_data_out_cnt_s cn52xxp1;
+ struct cvmx_npei_data_out_cnt_s cn56xx;
+ struct cvmx_npei_data_out_cnt_s cn56xxp1;
+};
+
+union cvmx_npei_dbg_data {
+ uint64_t u64;
+ struct cvmx_npei_dbg_data_s {
+ uint64_t reserved_28_63:36;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t reserved_25_26:2;
+ uint64_t qlm1_spd:2;
+ uint64_t c_mul:5;
+ uint64_t dsel_ext:1;
+ uint64_t data:17;
+ } s;
+ struct cvmx_npei_dbg_data_cn52xx {
+ uint64_t reserved_29_63:35;
+ uint64_t qlm0_link_width:1;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t qlm1_mode:2;
+ uint64_t qlm1_spd:2;
+ uint64_t c_mul:5;
+ uint64_t dsel_ext:1;
+ uint64_t data:17;
+ } cn52xx;
+ struct cvmx_npei_dbg_data_cn52xx cn52xxp1;
+ struct cvmx_npei_dbg_data_cn56xx {
+ uint64_t reserved_29_63:35;
+ uint64_t qlm2_rev_lanes:1;
+ uint64_t qlm0_rev_lanes:1;
+ uint64_t qlm3_spd:2;
+ uint64_t qlm1_spd:2;
+ uint64_t c_mul:5;
+ uint64_t dsel_ext:1;
+ uint64_t data:17;
+ } cn56xx;
+ struct cvmx_npei_dbg_data_cn56xx cn56xxp1;
+};
+
+union cvmx_npei_dbg_select {
+ uint64_t u64;
+ struct cvmx_npei_dbg_select_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbg_sel:16;
+ } s;
+ struct cvmx_npei_dbg_select_s cn52xx;
+ struct cvmx_npei_dbg_select_s cn52xxp1;
+ struct cvmx_npei_dbg_select_s cn56xx;
+ struct cvmx_npei_dbg_select_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_counts {
+ uint64_t u64;
+ struct cvmx_npei_dmax_counts_s {
+ uint64_t reserved_39_63:25;
+ uint64_t fcnt:7;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npei_dmax_counts_s cn52xx;
+ struct cvmx_npei_dmax_counts_s cn52xxp1;
+ struct cvmx_npei_dmax_counts_s cn56xx;
+ struct cvmx_npei_dmax_counts_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_dbell {
+ uint32_t u32;
+ struct cvmx_npei_dmax_dbell_s {
+ uint32_t reserved_16_31:16;
+ uint32_t dbell:16;
+ } s;
+ struct cvmx_npei_dmax_dbell_s cn52xx;
+ struct cvmx_npei_dmax_dbell_s cn52xxp1;
+ struct cvmx_npei_dmax_dbell_s cn56xx;
+ struct cvmx_npei_dmax_dbell_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_ibuff_saddr {
+ uint64_t u64;
+ struct cvmx_npei_dmax_ibuff_saddr_s {
+ uint64_t reserved_37_63:27;
+ uint64_t idle:1;
+ uint64_t saddr:29;
+ uint64_t reserved_0_6:7;
+ } s;
+ struct cvmx_npei_dmax_ibuff_saddr_s cn52xx;
+ struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 {
+ uint64_t reserved_36_63:28;
+ uint64_t saddr:29;
+ uint64_t reserved_0_6:7;
+ } cn52xxp1;
+ struct cvmx_npei_dmax_ibuff_saddr_s cn56xx;
+ struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 cn56xxp1;
+};
+
+union cvmx_npei_dmax_naddr {
+ uint64_t u64;
+ struct cvmx_npei_dmax_naddr_s {
+ uint64_t reserved_36_63:28;
+ uint64_t addr:36;
+ } s;
+ struct cvmx_npei_dmax_naddr_s cn52xx;
+ struct cvmx_npei_dmax_naddr_s cn52xxp1;
+ struct cvmx_npei_dmax_naddr_s cn56xx;
+ struct cvmx_npei_dmax_naddr_s cn56xxp1;
+};
+
+union cvmx_npei_dma0_int_level {
+ uint64_t u64;
+ struct cvmx_npei_dma0_int_level_s {
+ uint64_t time:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_dma0_int_level_s cn52xx;
+ struct cvmx_npei_dma0_int_level_s cn52xxp1;
+ struct cvmx_npei_dma0_int_level_s cn56xx;
+ struct cvmx_npei_dma0_int_level_s cn56xxp1;
+};
+
+union cvmx_npei_dma1_int_level {
+ uint64_t u64;
+ struct cvmx_npei_dma1_int_level_s {
+ uint64_t time:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_dma1_int_level_s cn52xx;
+ struct cvmx_npei_dma1_int_level_s cn52xxp1;
+ struct cvmx_npei_dma1_int_level_s cn56xx;
+ struct cvmx_npei_dma1_int_level_s cn56xxp1;
+};
+
+union cvmx_npei_dma_cnts {
+ uint64_t u64;
+ struct cvmx_npei_dma_cnts_s {
+ uint64_t dma1:32;
+ uint64_t dma0:32;
+ } s;
+ struct cvmx_npei_dma_cnts_s cn52xx;
+ struct cvmx_npei_dma_cnts_s cn52xxp1;
+ struct cvmx_npei_dma_cnts_s cn56xx;
+ struct cvmx_npei_dma_cnts_s cn56xxp1;
+};
+
+union cvmx_npei_dma_control {
+ uint64_t u64;
+ struct cvmx_npei_dma_control_s {
+ uint64_t reserved_40_63:24;
+ uint64_t p_32b_m:1;
+ uint64_t dma4_enb:1;
+ uint64_t dma3_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma0_enb:1;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t csize:14;
+ } s;
+ struct cvmx_npei_dma_control_s cn52xx;
+ struct cvmx_npei_dma_control_cn52xxp1 {
+ uint64_t reserved_38_63:26;
+ uint64_t dma3_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma0_enb:1;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t csize:14;
+ } cn52xxp1;
+ struct cvmx_npei_dma_control_s cn56xx;
+ struct cvmx_npei_dma_control_cn56xxp1 {
+ uint64_t reserved_39_63:25;
+ uint64_t dma4_enb:1;
+ uint64_t dma3_enb:1;
+ uint64_t dma2_enb:1;
+ uint64_t dma1_enb:1;
+ uint64_t dma0_enb:1;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t csize:14;
+ } cn56xxp1;
+};
+
+union cvmx_npei_dma_pcie_req_num {
+ uint64_t u64;
+ struct cvmx_npei_dma_pcie_req_num_s {
+ uint64_t dma_arb:1;
+ uint64_t reserved_53_62:10;
+ uint64_t pkt_cnt:5;
+ uint64_t reserved_45_47:3;
+ uint64_t dma4_cnt:5;
+ uint64_t reserved_37_39:3;
+ uint64_t dma3_cnt:5;
+ uint64_t reserved_29_31:3;
+ uint64_t dma2_cnt:5;
+ uint64_t reserved_21_23:3;
+ uint64_t dma1_cnt:5;
+ uint64_t reserved_13_15:3;
+ uint64_t dma0_cnt:5;
+ uint64_t reserved_5_7:3;
+ uint64_t dma_cnt:5;
+ } s;
+ struct cvmx_npei_dma_pcie_req_num_s cn52xx;
+ struct cvmx_npei_dma_pcie_req_num_s cn56xx;
+};
+
+union cvmx_npei_dma_state1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state1_s {
+ uint64_t reserved_40_63:24;
+ uint64_t d4_dwe:8;
+ uint64_t d3_dwe:8;
+ uint64_t d2_dwe:8;
+ uint64_t d1_dwe:8;
+ uint64_t d0_dwe:8;
+ } s;
+ struct cvmx_npei_dma_state1_s cn52xx;
+};
+
+union cvmx_npei_dma_state1_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state1_p1_s {
+ uint64_t reserved_60_63:4;
+ uint64_t d0_difst:7;
+ uint64_t d1_difst:7;
+ uint64_t d2_difst:7;
+ uint64_t d3_difst:7;
+ uint64_t d4_difst:7;
+ uint64_t d0_reqst:5;
+ uint64_t d1_reqst:5;
+ uint64_t d2_reqst:5;
+ uint64_t d3_reqst:5;
+ uint64_t d4_reqst:5;
+ } s;
+ struct cvmx_npei_dma_state1_p1_cn52xxp1 {
+ uint64_t reserved_60_63:4;
+ uint64_t d0_difst:7;
+ uint64_t d1_difst:7;
+ uint64_t d2_difst:7;
+ uint64_t d3_difst:7;
+ uint64_t reserved_25_31:7;
+ uint64_t d0_reqst:5;
+ uint64_t d1_reqst:5;
+ uint64_t d2_reqst:5;
+ uint64_t d3_reqst:5;
+ uint64_t reserved_0_4:5;
+ } cn52xxp1;
+ struct cvmx_npei_dma_state1_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state2 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state2_s {
+ uint64_t reserved_28_63:36;
+ uint64_t ndwe:4;
+ uint64_t reserved_21_23:3;
+ uint64_t ndre:5;
+ uint64_t reserved_10_15:6;
+ uint64_t prd:10;
+ } s;
+ struct cvmx_npei_dma_state2_s cn52xx;
+};
+
+union cvmx_npei_dma_state2_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state2_p1_s {
+ uint64_t reserved_45_63:19;
+ uint64_t d0_dffst:9;
+ uint64_t d1_dffst:9;
+ uint64_t d2_dffst:9;
+ uint64_t d3_dffst:9;
+ uint64_t d4_dffst:9;
+ } s;
+ struct cvmx_npei_dma_state2_p1_cn52xxp1 {
+ uint64_t reserved_45_63:19;
+ uint64_t d0_dffst:9;
+ uint64_t d1_dffst:9;
+ uint64_t d2_dffst:9;
+ uint64_t d3_dffst:9;
+ uint64_t reserved_0_8:9;
+ } cn52xxp1;
+ struct cvmx_npei_dma_state2_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state3_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state3_p1_s {
+ uint64_t reserved_60_63:4;
+ uint64_t d0_drest:15;
+ uint64_t d1_drest:15;
+ uint64_t d2_drest:15;
+ uint64_t d3_drest:15;
+ } s;
+ struct cvmx_npei_dma_state3_p1_s cn52xxp1;
+ struct cvmx_npei_dma_state3_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state4_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state4_p1_s {
+ uint64_t reserved_52_63:12;
+ uint64_t d0_dwest:13;
+ uint64_t d1_dwest:13;
+ uint64_t d2_dwest:13;
+ uint64_t d3_dwest:13;
+ } s;
+ struct cvmx_npei_dma_state4_p1_s cn52xxp1;
+ struct cvmx_npei_dma_state4_p1_s cn56xxp1;
+};
+
+union cvmx_npei_dma_state5_p1 {
+ uint64_t u64;
+ struct cvmx_npei_dma_state5_p1_s {
+ uint64_t reserved_28_63:36;
+ uint64_t d4_drest:15;
+ uint64_t d4_dwest:13;
+ } s;
+ struct cvmx_npei_dma_state5_p1_s cn56xxp1;
+};
+
+union cvmx_npei_int_a_enb {
+ uint64_t u64;
+ struct cvmx_npei_int_a_enb_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } s;
+ struct cvmx_npei_int_a_enb_s cn52xx;
+ struct cvmx_npei_int_a_enb_cn52xxp1 {
+ uint64_t reserved_2_63:62;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_a_enb_s cn56xx;
+};
+
+union cvmx_npei_int_a_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_int_a_enb2_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } s;
+ struct cvmx_npei_int_a_enb2_s cn52xx;
+ struct cvmx_npei_int_a_enb2_cn52xxp1 {
+ uint64_t reserved_2_63:62;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_a_enb2_s cn56xx;
+};
+
+union cvmx_npei_int_a_sum {
+ uint64_t u64;
+ struct cvmx_npei_int_a_sum_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pout_err:1;
+ uint64_t pin_bp:1;
+ uint64_t p1_rdlk:1;
+ uint64_t p0_rdlk:1;
+ uint64_t pgl_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pop_err:1;
+ uint64_t pins_err:1;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } s;
+ struct cvmx_npei_int_a_sum_s cn52xx;
+ struct cvmx_npei_int_a_sum_cn52xxp1 {
+ uint64_t reserved_2_63:62;
+ uint64_t dma1_cpl:1;
+ uint64_t dma0_cpl:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_a_sum_s cn56xx;
+};
+
+union cvmx_npei_int_enb {
+ uint64_t u64;
+ struct cvmx_npei_int_enb_s {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npei_int_enb_s cn52xx;
+ struct cvmx_npei_int_enb_cn52xxp1 {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_enb_s cn56xx;
+ struct cvmx_npei_int_enb_cn56xxp1 {
+ uint64_t mio_inta:1;
+ uint64_t reserved_61_62:2;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn56xxp1;
+};
+
+union cvmx_npei_int_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_int_enb2_s {
+ uint64_t reserved_62_63:2;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npei_int_enb2_s cn52xx;
+ struct cvmx_npei_int_enb2_cn52xxp1 {
+ uint64_t reserved_62_63:2;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_enb2_s cn56xx;
+ struct cvmx_npei_int_enb2_cn56xxp1 {
+ uint64_t reserved_61_63:3;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn56xxp1;
+};
+
+union cvmx_npei_int_info {
+ uint64_t u64;
+ struct cvmx_npei_int_info_s {
+ uint64_t reserved_12_63:52;
+ uint64_t pidbof:6;
+ uint64_t psldbof:6;
+ } s;
+ struct cvmx_npei_int_info_s cn52xx;
+ struct cvmx_npei_int_info_s cn56xx;
+ struct cvmx_npei_int_info_s cn56xxp1;
+};
+
+union cvmx_npei_int_sum {
+ uint64_t u64;
+ struct cvmx_npei_int_sum_s {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t pidbof:1;
+ uint64_t psldbof:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npei_int_sum_s cn52xx;
+ struct cvmx_npei_int_sum_cn52xxp1 {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t reserved_15_18:4;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn52xxp1;
+ struct cvmx_npei_int_sum_s cn56xx;
+ struct cvmx_npei_int_sum_cn56xxp1 {
+ uint64_t mio_inta:1;
+ uint64_t reserved_61_62:2;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t reserved_29_29:1;
+ uint64_t c1_se:1;
+ uint64_t reserved_27_27:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t reserved_22_22:1;
+ uint64_t c0_se:1;
+ uint64_t reserved_20_20:1;
+ uint64_t c0_aeri:1;
+ uint64_t reserved_15_18:4;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t dma4dbo:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn56xxp1;
+};
+
+union cvmx_npei_int_sum2 {
+ uint64_t u64;
+ struct cvmx_npei_int_sum2_s {
+ uint64_t mio_inta:1;
+ uint64_t reserved_62_62:1;
+ uint64_t int_a:1;
+ uint64_t c1_ldwn:1;
+ uint64_t c0_ldwn:1;
+ uint64_t c1_exc:1;
+ uint64_t c0_exc:1;
+ uint64_t c1_up_wf:1;
+ uint64_t c0_up_wf:1;
+ uint64_t c1_un_wf:1;
+ uint64_t c0_un_wf:1;
+ uint64_t c1_un_bx:1;
+ uint64_t c1_un_wi:1;
+ uint64_t c1_un_b2:1;
+ uint64_t c1_un_b1:1;
+ uint64_t c1_un_b0:1;
+ uint64_t c1_up_bx:1;
+ uint64_t c1_up_wi:1;
+ uint64_t c1_up_b2:1;
+ uint64_t c1_up_b1:1;
+ uint64_t c1_up_b0:1;
+ uint64_t c0_un_bx:1;
+ uint64_t c0_un_wi:1;
+ uint64_t c0_un_b2:1;
+ uint64_t c0_un_b1:1;
+ uint64_t c0_un_b0:1;
+ uint64_t c0_up_bx:1;
+ uint64_t c0_up_wi:1;
+ uint64_t c0_up_b2:1;
+ uint64_t c0_up_b1:1;
+ uint64_t c0_up_b0:1;
+ uint64_t c1_hpint:1;
+ uint64_t c1_pmei:1;
+ uint64_t c1_wake:1;
+ uint64_t crs1_dr:1;
+ uint64_t c1_se:1;
+ uint64_t crs1_er:1;
+ uint64_t c1_aeri:1;
+ uint64_t c0_hpint:1;
+ uint64_t c0_pmei:1;
+ uint64_t c0_wake:1;
+ uint64_t crs0_dr:1;
+ uint64_t c0_se:1;
+ uint64_t crs0_er:1;
+ uint64_t c0_aeri:1;
+ uint64_t reserved_15_18:4;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t dma1fi:1;
+ uint64_t dma0fi:1;
+ uint64_t reserved_8_8:1;
+ uint64_t dma3dbo:1;
+ uint64_t dma2dbo:1;
+ uint64_t dma1dbo:1;
+ uint64_t dma0dbo:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npei_int_sum2_s cn52xx;
+ struct cvmx_npei_int_sum2_s cn52xxp1;
+ struct cvmx_npei_int_sum2_s cn56xx;
+};
+
+union cvmx_npei_last_win_rdata0 {
+ uint64_t u64;
+ struct cvmx_npei_last_win_rdata0_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_npei_last_win_rdata0_s cn52xx;
+ struct cvmx_npei_last_win_rdata0_s cn52xxp1;
+ struct cvmx_npei_last_win_rdata0_s cn56xx;
+ struct cvmx_npei_last_win_rdata0_s cn56xxp1;
+};
+
+union cvmx_npei_last_win_rdata1 {
+ uint64_t u64;
+ struct cvmx_npei_last_win_rdata1_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_npei_last_win_rdata1_s cn52xx;
+ struct cvmx_npei_last_win_rdata1_s cn52xxp1;
+ struct cvmx_npei_last_win_rdata1_s cn56xx;
+ struct cvmx_npei_last_win_rdata1_s cn56xxp1;
+};
+
+union cvmx_npei_mem_access_ctl {
+ uint64_t u64;
+ struct cvmx_npei_mem_access_ctl_s {
+ uint64_t reserved_14_63:50;
+ uint64_t max_word:4;
+ uint64_t timer:10;
+ } s;
+ struct cvmx_npei_mem_access_ctl_s cn52xx;
+ struct cvmx_npei_mem_access_ctl_s cn52xxp1;
+ struct cvmx_npei_mem_access_ctl_s cn56xx;
+ struct cvmx_npei_mem_access_ctl_s cn56xxp1;
+};
+
+union cvmx_npei_mem_access_subidx {
+ uint64_t u64;
+ struct cvmx_npei_mem_access_subidx_s {
+ uint64_t reserved_42_63:22;
+ uint64_t zero:1;
+ uint64_t port:2;
+ uint64_t nmerge:1;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t nsr:1;
+ uint64_t nsw:1;
+ uint64_t ror:1;
+ uint64_t row:1;
+ uint64_t ba:30;
+ } s;
+ struct cvmx_npei_mem_access_subidx_s cn52xx;
+ struct cvmx_npei_mem_access_subidx_s cn52xxp1;
+ struct cvmx_npei_mem_access_subidx_s cn56xx;
+ struct cvmx_npei_mem_access_subidx_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb0 {
+ uint64_t u64;
+ struct cvmx_npei_msi_enb0_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_npei_msi_enb0_s cn52xx;
+ struct cvmx_npei_msi_enb0_s cn52xxp1;
+ struct cvmx_npei_msi_enb0_s cn56xx;
+ struct cvmx_npei_msi_enb0_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb1 {
+ uint64_t u64;
+ struct cvmx_npei_msi_enb1_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_npei_msi_enb1_s cn52xx;
+ struct cvmx_npei_msi_enb1_s cn52xxp1;
+ struct cvmx_npei_msi_enb1_s cn56xx;
+ struct cvmx_npei_msi_enb1_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_msi_enb2_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_npei_msi_enb2_s cn52xx;
+ struct cvmx_npei_msi_enb2_s cn52xxp1;
+ struct cvmx_npei_msi_enb2_s cn56xx;
+ struct cvmx_npei_msi_enb2_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb3 {
+ uint64_t u64;
+ struct cvmx_npei_msi_enb3_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_npei_msi_enb3_s cn52xx;
+ struct cvmx_npei_msi_enb3_s cn52xxp1;
+ struct cvmx_npei_msi_enb3_s cn56xx;
+ struct cvmx_npei_msi_enb3_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv0 {
+ uint64_t u64;
+ struct cvmx_npei_msi_rcv0_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_npei_msi_rcv0_s cn52xx;
+ struct cvmx_npei_msi_rcv0_s cn52xxp1;
+ struct cvmx_npei_msi_rcv0_s cn56xx;
+ struct cvmx_npei_msi_rcv0_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv1 {
+ uint64_t u64;
+ struct cvmx_npei_msi_rcv1_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_npei_msi_rcv1_s cn52xx;
+ struct cvmx_npei_msi_rcv1_s cn52xxp1;
+ struct cvmx_npei_msi_rcv1_s cn56xx;
+ struct cvmx_npei_msi_rcv1_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv2 {
+ uint64_t u64;
+ struct cvmx_npei_msi_rcv2_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_npei_msi_rcv2_s cn52xx;
+ struct cvmx_npei_msi_rcv2_s cn52xxp1;
+ struct cvmx_npei_msi_rcv2_s cn56xx;
+ struct cvmx_npei_msi_rcv2_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv3 {
+ uint64_t u64;
+ struct cvmx_npei_msi_rcv3_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_npei_msi_rcv3_s cn52xx;
+ struct cvmx_npei_msi_rcv3_s cn52xxp1;
+ struct cvmx_npei_msi_rcv3_s cn56xx;
+ struct cvmx_npei_msi_rcv3_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rd_map {
+ uint64_t u64;
+ struct cvmx_npei_msi_rd_map_s {
+ uint64_t reserved_16_63:48;
+ uint64_t rd_int:8;
+ uint64_t msi_int:8;
+ } s;
+ struct cvmx_npei_msi_rd_map_s cn52xx;
+ struct cvmx_npei_msi_rd_map_s cn52xxp1;
+ struct cvmx_npei_msi_rd_map_s cn56xx;
+ struct cvmx_npei_msi_rd_map_s cn56xxp1;
+};
+
+union cvmx_npei_msi_w1c_enb0 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1c_enb0_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_npei_msi_w1c_enb0_s cn52xx;
+ struct cvmx_npei_msi_w1c_enb0_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb1 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1c_enb1_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_npei_msi_w1c_enb1_s cn52xx;
+ struct cvmx_npei_msi_w1c_enb1_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1c_enb2_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_npei_msi_w1c_enb2_s cn52xx;
+ struct cvmx_npei_msi_w1c_enb2_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb3 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1c_enb3_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_npei_msi_w1c_enb3_s cn52xx;
+ struct cvmx_npei_msi_w1c_enb3_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb0 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1s_enb0_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_npei_msi_w1s_enb0_s cn52xx;
+ struct cvmx_npei_msi_w1s_enb0_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb1 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1s_enb1_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_npei_msi_w1s_enb1_s cn52xx;
+ struct cvmx_npei_msi_w1s_enb1_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb2 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1s_enb2_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_npei_msi_w1s_enb2_s cn52xx;
+ struct cvmx_npei_msi_w1s_enb2_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb3 {
+ uint64_t u64;
+ struct cvmx_npei_msi_w1s_enb3_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_npei_msi_w1s_enb3_s cn52xx;
+ struct cvmx_npei_msi_w1s_enb3_s cn56xx;
+};
+
+union cvmx_npei_msi_wr_map {
+ uint64_t u64;
+ struct cvmx_npei_msi_wr_map_s {
+ uint64_t reserved_16_63:48;
+ uint64_t ciu_int:8;
+ uint64_t msi_int:8;
+ } s;
+ struct cvmx_npei_msi_wr_map_s cn52xx;
+ struct cvmx_npei_msi_wr_map_s cn52xxp1;
+ struct cvmx_npei_msi_wr_map_s cn56xx;
+ struct cvmx_npei_msi_wr_map_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_credit_cnt {
+ uint64_t u64;
+ struct cvmx_npei_pcie_credit_cnt_s {
+ uint64_t reserved_48_63:16;
+ uint64_t p1_ccnt:8;
+ uint64_t p1_ncnt:8;
+ uint64_t p1_pcnt:8;
+ uint64_t p0_ccnt:8;
+ uint64_t p0_ncnt:8;
+ uint64_t p0_pcnt:8;
+ } s;
+ struct cvmx_npei_pcie_credit_cnt_s cn52xx;
+ struct cvmx_npei_pcie_credit_cnt_s cn56xx;
+};
+
+union cvmx_npei_pcie_msi_rcv {
+ uint64_t u64;
+ struct cvmx_npei_pcie_msi_rcv_s {
+ uint64_t reserved_8_63:56;
+ uint64_t intr:8;
+ } s;
+ struct cvmx_npei_pcie_msi_rcv_s cn52xx;
+ struct cvmx_npei_pcie_msi_rcv_s cn52xxp1;
+ struct cvmx_npei_pcie_msi_rcv_s cn56xx;
+ struct cvmx_npei_pcie_msi_rcv_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b1 {
+ uint64_t u64;
+ struct cvmx_npei_pcie_msi_rcv_b1_s {
+ uint64_t reserved_16_63:48;
+ uint64_t intr:8;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_npei_pcie_msi_rcv_b1_s cn52xx;
+ struct cvmx_npei_pcie_msi_rcv_b1_s cn52xxp1;
+ struct cvmx_npei_pcie_msi_rcv_b1_s cn56xx;
+ struct cvmx_npei_pcie_msi_rcv_b1_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b2 {
+ uint64_t u64;
+ struct cvmx_npei_pcie_msi_rcv_b2_s {
+ uint64_t reserved_24_63:40;
+ uint64_t intr:8;
+ uint64_t reserved_0_15:16;
+ } s;
+ struct cvmx_npei_pcie_msi_rcv_b2_s cn52xx;
+ struct cvmx_npei_pcie_msi_rcv_b2_s cn52xxp1;
+ struct cvmx_npei_pcie_msi_rcv_b2_s cn56xx;
+ struct cvmx_npei_pcie_msi_rcv_b2_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b3 {
+ uint64_t u64;
+ struct cvmx_npei_pcie_msi_rcv_b3_s {
+ uint64_t reserved_32_63:32;
+ uint64_t intr:8;
+ uint64_t reserved_0_23:24;
+ } s;
+ struct cvmx_npei_pcie_msi_rcv_b3_s cn52xx;
+ struct cvmx_npei_pcie_msi_rcv_b3_s cn52xxp1;
+ struct cvmx_npei_pcie_msi_rcv_b3_s cn56xx;
+ struct cvmx_npei_pcie_msi_rcv_b3_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_cnts {
+ uint64_t u64;
+ struct cvmx_npei_pktx_cnts_s {
+ uint64_t reserved_54_63:10;
+ uint64_t timer:22;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_pktx_cnts_s cn52xx;
+ struct cvmx_npei_pktx_cnts_s cn56xx;
+};
+
+union cvmx_npei_pktx_in_bp {
+ uint64_t u64;
+ struct cvmx_npei_pktx_in_bp_s {
+ uint64_t wmark:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_pktx_in_bp_s cn52xx;
+ struct cvmx_npei_pktx_in_bp_s cn56xx;
+};
+
+union cvmx_npei_pktx_instr_baddr {
+ uint64_t u64;
+ struct cvmx_npei_pktx_instr_baddr_s {
+ uint64_t addr:61;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_npei_pktx_instr_baddr_s cn52xx;
+ struct cvmx_npei_pktx_instr_baddr_s cn56xx;
+};
+
+union cvmx_npei_pktx_instr_baoff_dbell {
+ uint64_t u64;
+ struct cvmx_npei_pktx_instr_baoff_dbell_s {
+ uint64_t aoff:32;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx;
+ struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx;
+};
+
+union cvmx_npei_pktx_instr_fifo_rsize {
+ uint64_t u64;
+ struct cvmx_npei_pktx_instr_fifo_rsize_s {
+ uint64_t max:9;
+ uint64_t rrp:9;
+ uint64_t wrp:9;
+ uint64_t fcnt:5;
+ uint64_t rsize:32;
+ } s;
+ struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx;
+ struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx;
+};
+
+union cvmx_npei_pktx_instr_header {
+ uint64_t u64;
+ struct cvmx_npei_pktx_instr_header_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t reserved_38_42:5;
+ uint64_t rparmode:2;
+ uint64_t reserved_35_35:1;
+ uint64_t rskp_len:7;
+ uint64_t reserved_22_27:6;
+ uint64_t use_ihdr:1;
+ uint64_t reserved_16_20:5;
+ uint64_t par_mode:2;
+ uint64_t reserved_13_13:1;
+ uint64_t skp_len:7;
+ uint64_t reserved_0_5:6;
+ } s;
+ struct cvmx_npei_pktx_instr_header_s cn52xx;
+ struct cvmx_npei_pktx_instr_header_s cn56xx;
+};
+
+union cvmx_npei_pktx_slist_baddr {
+ uint64_t u64;
+ struct cvmx_npei_pktx_slist_baddr_s {
+ uint64_t addr:60;
+ uint64_t reserved_0_3:4;
+ } s;
+ struct cvmx_npei_pktx_slist_baddr_s cn52xx;
+ struct cvmx_npei_pktx_slist_baddr_s cn56xx;
+};
+
+union cvmx_npei_pktx_slist_baoff_dbell {
+ uint64_t u64;
+ struct cvmx_npei_pktx_slist_baoff_dbell_s {
+ uint64_t aoff:32;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx;
+ struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx;
+};
+
+union cvmx_npei_pktx_slist_fifo_rsize {
+ uint64_t u64;
+ struct cvmx_npei_pktx_slist_fifo_rsize_s {
+ uint64_t reserved_32_63:32;
+ uint64_t rsize:32;
+ } s;
+ struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx;
+ struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx;
+};
+
+union cvmx_npei_pkt_cnt_int {
+ uint64_t u64;
+ struct cvmx_npei_pkt_cnt_int_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_npei_pkt_cnt_int_s cn52xx;
+ struct cvmx_npei_pkt_cnt_int_s cn56xx;
+};
+
+union cvmx_npei_pkt_cnt_int_enb {
+ uint64_t u64;
+ struct cvmx_npei_pkt_cnt_int_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_npei_pkt_cnt_int_enb_s cn52xx;
+ struct cvmx_npei_pkt_cnt_int_enb_s cn56xx;
+};
+
+union cvmx_npei_pkt_data_out_es {
+ uint64_t u64;
+ struct cvmx_npei_pkt_data_out_es_s {
+ uint64_t es:64;
+ } s;
+ struct cvmx_npei_pkt_data_out_es_s cn52xx;
+ struct cvmx_npei_pkt_data_out_es_s cn56xx;
+};
+
+union cvmx_npei_pkt_data_out_ns {
+ uint64_t u64;
+ struct cvmx_npei_pkt_data_out_ns_s {
+ uint64_t reserved_32_63:32;
+ uint64_t nsr:32;
+ } s;
+ struct cvmx_npei_pkt_data_out_ns_s cn52xx;
+ struct cvmx_npei_pkt_data_out_ns_s cn56xx;
+};
+
+union cvmx_npei_pkt_data_out_ror {
+ uint64_t u64;
+ struct cvmx_npei_pkt_data_out_ror_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ror:32;
+ } s;
+ struct cvmx_npei_pkt_data_out_ror_s cn52xx;
+ struct cvmx_npei_pkt_data_out_ror_s cn56xx;
+};
+
+union cvmx_npei_pkt_dpaddr {
+ uint64_t u64;
+ struct cvmx_npei_pkt_dpaddr_s {
+ uint64_t reserved_32_63:32;
+ uint64_t dptr:32;
+ } s;
+ struct cvmx_npei_pkt_dpaddr_s cn52xx;
+ struct cvmx_npei_pkt_dpaddr_s cn56xx;
+};
+
+union cvmx_npei_pkt_in_bp {
+ uint64_t u64;
+ struct cvmx_npei_pkt_in_bp_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bp:32;
+ } s;
+ struct cvmx_npei_pkt_in_bp_s cn52xx;
+ struct cvmx_npei_pkt_in_bp_s cn56xx;
+};
+
+union cvmx_npei_pkt_in_donex_cnts {
+ uint64_t u64;
+ struct cvmx_npei_pkt_in_donex_cnts_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_pkt_in_donex_cnts_s cn52xx;
+ struct cvmx_npei_pkt_in_donex_cnts_s cn56xx;
+};
+
+union cvmx_npei_pkt_in_instr_counts {
+ uint64_t u64;
+ struct cvmx_npei_pkt_in_instr_counts_s {
+ uint64_t wr_cnt:32;
+ uint64_t rd_cnt:32;
+ } s;
+ struct cvmx_npei_pkt_in_instr_counts_s cn52xx;
+ struct cvmx_npei_pkt_in_instr_counts_s cn56xx;
+};
+
+union cvmx_npei_pkt_in_pcie_port {
+ uint64_t u64;
+ struct cvmx_npei_pkt_in_pcie_port_s {
+ uint64_t pp:64;
+ } s;
+ struct cvmx_npei_pkt_in_pcie_port_s cn52xx;
+ struct cvmx_npei_pkt_in_pcie_port_s cn56xx;
+};
+
+union cvmx_npei_pkt_input_control {
+ uint64_t u64;
+ struct cvmx_npei_pkt_input_control_s {
+ uint64_t reserved_23_63:41;
+ uint64_t pkt_rr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t d_nsr:1;
+ uint64_t d_esr:2;
+ uint64_t d_ror:1;
+ uint64_t use_csr:1;
+ uint64_t nsr:1;
+ uint64_t esr:2;
+ uint64_t ror:1;
+ } s;
+ struct cvmx_npei_pkt_input_control_s cn52xx;
+ struct cvmx_npei_pkt_input_control_s cn56xx;
+};
+
+union cvmx_npei_pkt_instr_enb {
+ uint64_t u64;
+ struct cvmx_npei_pkt_instr_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enb:32;
+ } s;
+ struct cvmx_npei_pkt_instr_enb_s cn52xx;
+ struct cvmx_npei_pkt_instr_enb_s cn56xx;
+};
+
+union cvmx_npei_pkt_instr_rd_size {
+ uint64_t u64;
+ struct cvmx_npei_pkt_instr_rd_size_s {
+ uint64_t rdsize:64;
+ } s;
+ struct cvmx_npei_pkt_instr_rd_size_s cn52xx;
+ struct cvmx_npei_pkt_instr_rd_size_s cn56xx;
+};
+
+union cvmx_npei_pkt_instr_size {
+ uint64_t u64;
+ struct cvmx_npei_pkt_instr_size_s {
+ uint64_t reserved_32_63:32;
+ uint64_t is_64b:32;
+ } s;
+ struct cvmx_npei_pkt_instr_size_s cn52xx;
+ struct cvmx_npei_pkt_instr_size_s cn56xx;
+};
+
+union cvmx_npei_pkt_int_levels {
+ uint64_t u64;
+ struct cvmx_npei_pkt_int_levels_s {
+ uint64_t reserved_54_63:10;
+ uint64_t time:22;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_npei_pkt_int_levels_s cn52xx;
+ struct cvmx_npei_pkt_int_levels_s cn56xx;
+};
+
+union cvmx_npei_pkt_iptr {
+ uint64_t u64;
+ struct cvmx_npei_pkt_iptr_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iptr:32;
+ } s;
+ struct cvmx_npei_pkt_iptr_s cn52xx;
+ struct cvmx_npei_pkt_iptr_s cn56xx;
+};
+
+union cvmx_npei_pkt_out_bmode {
+ uint64_t u64;
+ struct cvmx_npei_pkt_out_bmode_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bmode:32;
+ } s;
+ struct cvmx_npei_pkt_out_bmode_s cn52xx;
+ struct cvmx_npei_pkt_out_bmode_s cn56xx;
+};
+
+union cvmx_npei_pkt_out_enb {
+ uint64_t u64;
+ struct cvmx_npei_pkt_out_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enb:32;
+ } s;
+ struct cvmx_npei_pkt_out_enb_s cn52xx;
+ struct cvmx_npei_pkt_out_enb_s cn56xx;
+};
+
+union cvmx_npei_pkt_output_wmark {
+ uint64_t u64;
+ struct cvmx_npei_pkt_output_wmark_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wmark:32;
+ } s;
+ struct cvmx_npei_pkt_output_wmark_s cn52xx;
+ struct cvmx_npei_pkt_output_wmark_s cn56xx;
+};
+
+union cvmx_npei_pkt_pcie_port {
+ uint64_t u64;
+ struct cvmx_npei_pkt_pcie_port_s {
+ uint64_t pp:64;
+ } s;
+ struct cvmx_npei_pkt_pcie_port_s cn52xx;
+ struct cvmx_npei_pkt_pcie_port_s cn56xx;
+};
+
+union cvmx_npei_pkt_port_in_rst {
+ uint64_t u64;
+ struct cvmx_npei_pkt_port_in_rst_s {
+ uint64_t in_rst:32;
+ uint64_t out_rst:32;
+ } s;
+ struct cvmx_npei_pkt_port_in_rst_s cn52xx;
+ struct cvmx_npei_pkt_port_in_rst_s cn56xx;
+};
+
+union cvmx_npei_pkt_slist_es {
+ uint64_t u64;
+ struct cvmx_npei_pkt_slist_es_s {
+ uint64_t es:64;
+ } s;
+ struct cvmx_npei_pkt_slist_es_s cn52xx;
+ struct cvmx_npei_pkt_slist_es_s cn56xx;
+};
+
+union cvmx_npei_pkt_slist_id_size {
+ uint64_t u64;
+ struct cvmx_npei_pkt_slist_id_size_s {
+ uint64_t reserved_23_63:41;
+ uint64_t isize:7;
+ uint64_t bsize:16;
+ } s;
+ struct cvmx_npei_pkt_slist_id_size_s cn52xx;
+ struct cvmx_npei_pkt_slist_id_size_s cn56xx;
+};
+
+union cvmx_npei_pkt_slist_ns {
+ uint64_t u64;
+ struct cvmx_npei_pkt_slist_ns_s {
+ uint64_t reserved_32_63:32;
+ uint64_t nsr:32;
+ } s;
+ struct cvmx_npei_pkt_slist_ns_s cn52xx;
+ struct cvmx_npei_pkt_slist_ns_s cn56xx;
+};
+
+union cvmx_npei_pkt_slist_ror {
+ uint64_t u64;
+ struct cvmx_npei_pkt_slist_ror_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ror:32;
+ } s;
+ struct cvmx_npei_pkt_slist_ror_s cn52xx;
+ struct cvmx_npei_pkt_slist_ror_s cn56xx;
+};
+
+union cvmx_npei_pkt_time_int {
+ uint64_t u64;
+ struct cvmx_npei_pkt_time_int_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_npei_pkt_time_int_s cn52xx;
+ struct cvmx_npei_pkt_time_int_s cn56xx;
+};
+
+union cvmx_npei_pkt_time_int_enb {
+ uint64_t u64;
+ struct cvmx_npei_pkt_time_int_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_npei_pkt_time_int_enb_s cn52xx;
+ struct cvmx_npei_pkt_time_int_enb_s cn56xx;
+};
+
+union cvmx_npei_rsl_int_blocks {
+ uint64_t u64;
+ struct cvmx_npei_rsl_int_blocks_s {
+ uint64_t reserved_31_63:33;
+ uint64_t iob:1;
+ uint64_t lmc1:1;
+ uint64_t agl:1;
+ uint64_t reserved_24_27:4;
+ uint64_t asxpcs1:1;
+ uint64_t asxpcs0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc0:1;
+ uint64_t l2c:1;
+ uint64_t usb1:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npei:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } s;
+ struct cvmx_npei_rsl_int_blocks_s cn52xx;
+ struct cvmx_npei_rsl_int_blocks_s cn52xxp1;
+ struct cvmx_npei_rsl_int_blocks_s cn56xx;
+ struct cvmx_npei_rsl_int_blocks_s cn56xxp1;
+};
+
+union cvmx_npei_scratch_1 {
+ uint64_t u64;
+ struct cvmx_npei_scratch_1_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_npei_scratch_1_s cn52xx;
+ struct cvmx_npei_scratch_1_s cn52xxp1;
+ struct cvmx_npei_scratch_1_s cn56xx;
+ struct cvmx_npei_scratch_1_s cn56xxp1;
+};
+
+union cvmx_npei_state1 {
+ uint64_t u64;
+ struct cvmx_npei_state1_s {
+ uint64_t cpl1:12;
+ uint64_t cpl0:12;
+ uint64_t arb:1;
+ uint64_t csr:39;
+ } s;
+ struct cvmx_npei_state1_s cn52xx;
+ struct cvmx_npei_state1_s cn52xxp1;
+ struct cvmx_npei_state1_s cn56xx;
+ struct cvmx_npei_state1_s cn56xxp1;
+};
+
+union cvmx_npei_state2 {
+ uint64_t u64;
+ struct cvmx_npei_state2_s {
+ uint64_t reserved_48_63:16;
+ uint64_t npei:1;
+ uint64_t rac:1;
+ uint64_t csm1:15;
+ uint64_t csm0:15;
+ uint64_t nnp0:8;
+ uint64_t nnd:8;
+ } s;
+ struct cvmx_npei_state2_s cn52xx;
+ struct cvmx_npei_state2_s cn52xxp1;
+ struct cvmx_npei_state2_s cn56xx;
+ struct cvmx_npei_state2_s cn56xxp1;
+};
+
+union cvmx_npei_state3 {
+ uint64_t u64;
+ struct cvmx_npei_state3_s {
+ uint64_t reserved_56_63:8;
+ uint64_t psm1:15;
+ uint64_t psm0:15;
+ uint64_t nsm1:13;
+ uint64_t nsm0:13;
+ } s;
+ struct cvmx_npei_state3_s cn52xx;
+ struct cvmx_npei_state3_s cn52xxp1;
+ struct cvmx_npei_state3_s cn56xx;
+ struct cvmx_npei_state3_s cn56xxp1;
+};
+
+union cvmx_npei_win_rd_addr {
+ uint64_t u64;
+ struct cvmx_npei_win_rd_addr_s {
+ uint64_t reserved_51_63:13;
+ uint64_t ld_cmd:2;
+ uint64_t iobit:1;
+ uint64_t rd_addr:48;
+ } s;
+ struct cvmx_npei_win_rd_addr_s cn52xx;
+ struct cvmx_npei_win_rd_addr_s cn52xxp1;
+ struct cvmx_npei_win_rd_addr_s cn56xx;
+ struct cvmx_npei_win_rd_addr_s cn56xxp1;
+};
+
+union cvmx_npei_win_rd_data {
+ uint64_t u64;
+ struct cvmx_npei_win_rd_data_s {
+ uint64_t rd_data:64;
+ } s;
+ struct cvmx_npei_win_rd_data_s cn52xx;
+ struct cvmx_npei_win_rd_data_s cn52xxp1;
+ struct cvmx_npei_win_rd_data_s cn56xx;
+ struct cvmx_npei_win_rd_data_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_addr {
+ uint64_t u64;
+ struct cvmx_npei_win_wr_addr_s {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t wr_addr:46;
+ uint64_t reserved_0_1:2;
+ } s;
+ struct cvmx_npei_win_wr_addr_s cn52xx;
+ struct cvmx_npei_win_wr_addr_s cn52xxp1;
+ struct cvmx_npei_win_wr_addr_s cn56xx;
+ struct cvmx_npei_win_wr_addr_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_data {
+ uint64_t u64;
+ struct cvmx_npei_win_wr_data_s {
+ uint64_t wr_data:64;
+ } s;
+ struct cvmx_npei_win_wr_data_s cn52xx;
+ struct cvmx_npei_win_wr_data_s cn52xxp1;
+ struct cvmx_npei_win_wr_data_s cn56xx;
+ struct cvmx_npei_win_wr_data_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_mask {
+ uint64_t u64;
+ struct cvmx_npei_win_wr_mask_s {
+ uint64_t reserved_8_63:56;
+ uint64_t wr_mask:8;
+ } s;
+ struct cvmx_npei_win_wr_mask_s cn52xx;
+ struct cvmx_npei_win_wr_mask_s cn52xxp1;
+ struct cvmx_npei_win_wr_mask_s cn56xx;
+ struct cvmx_npei_win_wr_mask_s cn56xxp1;
+};
+
+union cvmx_npei_window_ctl {
+ uint64_t u64;
+ struct cvmx_npei_window_ctl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t time:32;
+ } s;
+ struct cvmx_npei_window_ctl_s cn52xx;
+ struct cvmx_npei_window_ctl_s cn52xxp1;
+ struct cvmx_npei_window_ctl_s cn56xx;
+ struct cvmx_npei_window_ctl_s cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-npi-defs.h b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
new file mode 100644
index 00000000..f089c780
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
@@ -0,0 +1,1615 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_NPI_DEFS_H__
+#define __CVMX_NPI_DEFS_H__
+
+#define CVMX_NPI_BASE_ADDR_INPUT0 CVMX_NPI_BASE_ADDR_INPUTX(0)
+#define CVMX_NPI_BASE_ADDR_INPUT1 CVMX_NPI_BASE_ADDR_INPUTX(1)
+#define CVMX_NPI_BASE_ADDR_INPUT2 CVMX_NPI_BASE_ADDR_INPUTX(2)
+#define CVMX_NPI_BASE_ADDR_INPUT3 CVMX_NPI_BASE_ADDR_INPUTX(3)
+#define CVMX_NPI_BASE_ADDR_INPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000070ull) + ((offset) & 3) * 16)
+#define CVMX_NPI_BASE_ADDR_OUTPUT0 CVMX_NPI_BASE_ADDR_OUTPUTX(0)
+#define CVMX_NPI_BASE_ADDR_OUTPUT1 CVMX_NPI_BASE_ADDR_OUTPUTX(1)
+#define CVMX_NPI_BASE_ADDR_OUTPUT2 CVMX_NPI_BASE_ADDR_OUTPUTX(2)
+#define CVMX_NPI_BASE_ADDR_OUTPUT3 CVMX_NPI_BASE_ADDR_OUTPUTX(3)
+#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F00000000B8ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F00000003F8ull))
+#define CVMX_NPI_BUFF_SIZE_OUTPUT0 CVMX_NPI_BUFF_SIZE_OUTPUTX(0)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT1 CVMX_NPI_BUFF_SIZE_OUTPUTX(1)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT2 CVMX_NPI_BUFF_SIZE_OUTPUTX(2)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT3 CVMX_NPI_BUFF_SIZE_OUTPUTX(3)
+#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F00000000E0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_COMP_CTL (CVMX_ADD_IO_SEG(0x00011F0000000218ull))
+#define CVMX_NPI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000000010ull))
+#define CVMX_NPI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000000008ull))
+#define CVMX_NPI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000128ull))
+#define CVMX_NPI_DMA_HIGHP_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000000148ull))
+#define CVMX_NPI_DMA_HIGHP_NADDR (CVMX_ADD_IO_SEG(0x00011F0000000158ull))
+#define CVMX_NPI_DMA_LOWP_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000000140ull))
+#define CVMX_NPI_DMA_LOWP_NADDR (CVMX_ADD_IO_SEG(0x00011F0000000150ull))
+#define CVMX_NPI_HIGHP_DBELL (CVMX_ADD_IO_SEG(0x00011F0000000120ull))
+#define CVMX_NPI_HIGHP_IBUFF_SADDR (CVMX_ADD_IO_SEG(0x00011F0000000110ull))
+#define CVMX_NPI_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000138ull))
+#define CVMX_NPI_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000000020ull))
+#define CVMX_NPI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000000018ull))
+#define CVMX_NPI_LOWP_DBELL (CVMX_ADD_IO_SEG(0x00011F0000000118ull))
+#define CVMX_NPI_LOWP_IBUFF_SADDR (CVMX_ADD_IO_SEG(0x00011F0000000108ull))
+#define CVMX_NPI_MEM_ACCESS_SUBID3 CVMX_NPI_MEM_ACCESS_SUBIDX(3)
+#define CVMX_NPI_MEM_ACCESS_SUBID4 CVMX_NPI_MEM_ACCESS_SUBIDX(4)
+#define CVMX_NPI_MEM_ACCESS_SUBID5 CVMX_NPI_MEM_ACCESS_SUBIDX(5)
+#define CVMX_NPI_MEM_ACCESS_SUBID6 CVMX_NPI_MEM_ACCESS_SUBIDX(6)
+#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000028ull) + ((offset) & 7) * 8 - 8*3)
+#define CVMX_NPI_MSI_RCV (0x0000000000000190ull)
+#define CVMX_NPI_NPI_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F0000001190ull))
+#define CVMX_NPI_NUM_DESC_OUTPUT0 CVMX_NPI_NUM_DESC_OUTPUTX(0)
+#define CVMX_NPI_NUM_DESC_OUTPUT1 CVMX_NPI_NUM_DESC_OUTPUTX(1)
+#define CVMX_NPI_NUM_DESC_OUTPUT2 CVMX_NPI_NUM_DESC_OUTPUTX(2)
+#define CVMX_NPI_NUM_DESC_OUTPUT3 CVMX_NPI_NUM_DESC_OUTPUTX(3)
+#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000050ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_OUTPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000000100ull))
+#define CVMX_NPI_P0_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(0)
+#define CVMX_NPI_P0_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(0)
+#define CVMX_NPI_P0_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(0)
+#define CVMX_NPI_P0_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(0)
+#define CVMX_NPI_P1_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(1)
+#define CVMX_NPI_P1_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(1)
+#define CVMX_NPI_P1_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(1)
+#define CVMX_NPI_P1_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(1)
+#define CVMX_NPI_P2_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(2)
+#define CVMX_NPI_P2_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(2)
+#define CVMX_NPI_P2_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(2)
+#define CVMX_NPI_P2_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(2)
+#define CVMX_NPI_P3_DBPAIR_ADDR CVMX_NPI_PX_DBPAIR_ADDR(3)
+#define CVMX_NPI_P3_INSTR_ADDR CVMX_NPI_PX_INSTR_ADDR(3)
+#define CVMX_NPI_P3_INSTR_CNTS CVMX_NPI_PX_INSTR_CNTS(3)
+#define CVMX_NPI_P3_PAIR_CNTS CVMX_NPI_PX_PAIR_CNTS(3)
+#define CVMX_NPI_PCI_BAR1_INDEXX(offset) (CVMX_ADD_IO_SEG(0x00011F0000001100ull) + ((offset) & 31) * 4)
+#define CVMX_NPI_PCI_BIST_REG (CVMX_ADD_IO_SEG(0x00011F00000011C0ull))
+#define CVMX_NPI_PCI_BURST_SIZE (CVMX_ADD_IO_SEG(0x00011F00000000D8ull))
+#define CVMX_NPI_PCI_CFG00 (CVMX_ADD_IO_SEG(0x00011F0000001800ull))
+#define CVMX_NPI_PCI_CFG01 (CVMX_ADD_IO_SEG(0x00011F0000001804ull))
+#define CVMX_NPI_PCI_CFG02 (CVMX_ADD_IO_SEG(0x00011F0000001808ull))
+#define CVMX_NPI_PCI_CFG03 (CVMX_ADD_IO_SEG(0x00011F000000180Cull))
+#define CVMX_NPI_PCI_CFG04 (CVMX_ADD_IO_SEG(0x00011F0000001810ull))
+#define CVMX_NPI_PCI_CFG05 (CVMX_ADD_IO_SEG(0x00011F0000001814ull))
+#define CVMX_NPI_PCI_CFG06 (CVMX_ADD_IO_SEG(0x00011F0000001818ull))
+#define CVMX_NPI_PCI_CFG07 (CVMX_ADD_IO_SEG(0x00011F000000181Cull))
+#define CVMX_NPI_PCI_CFG08 (CVMX_ADD_IO_SEG(0x00011F0000001820ull))
+#define CVMX_NPI_PCI_CFG09 (CVMX_ADD_IO_SEG(0x00011F0000001824ull))
+#define CVMX_NPI_PCI_CFG10 (CVMX_ADD_IO_SEG(0x00011F0000001828ull))
+#define CVMX_NPI_PCI_CFG11 (CVMX_ADD_IO_SEG(0x00011F000000182Cull))
+#define CVMX_NPI_PCI_CFG12 (CVMX_ADD_IO_SEG(0x00011F0000001830ull))
+#define CVMX_NPI_PCI_CFG13 (CVMX_ADD_IO_SEG(0x00011F0000001834ull))
+#define CVMX_NPI_PCI_CFG15 (CVMX_ADD_IO_SEG(0x00011F000000183Cull))
+#define CVMX_NPI_PCI_CFG16 (CVMX_ADD_IO_SEG(0x00011F0000001840ull))
+#define CVMX_NPI_PCI_CFG17 (CVMX_ADD_IO_SEG(0x00011F0000001844ull))
+#define CVMX_NPI_PCI_CFG18 (CVMX_ADD_IO_SEG(0x00011F0000001848ull))
+#define CVMX_NPI_PCI_CFG19 (CVMX_ADD_IO_SEG(0x00011F000000184Cull))
+#define CVMX_NPI_PCI_CFG20 (CVMX_ADD_IO_SEG(0x00011F0000001850ull))
+#define CVMX_NPI_PCI_CFG21 (CVMX_ADD_IO_SEG(0x00011F0000001854ull))
+#define CVMX_NPI_PCI_CFG22 (CVMX_ADD_IO_SEG(0x00011F0000001858ull))
+#define CVMX_NPI_PCI_CFG56 (CVMX_ADD_IO_SEG(0x00011F00000018E0ull))
+#define CVMX_NPI_PCI_CFG57 (CVMX_ADD_IO_SEG(0x00011F00000018E4ull))
+#define CVMX_NPI_PCI_CFG58 (CVMX_ADD_IO_SEG(0x00011F00000018E8ull))
+#define CVMX_NPI_PCI_CFG59 (CVMX_ADD_IO_SEG(0x00011F00000018ECull))
+#define CVMX_NPI_PCI_CFG60 (CVMX_ADD_IO_SEG(0x00011F00000018F0ull))
+#define CVMX_NPI_PCI_CFG61 (CVMX_ADD_IO_SEG(0x00011F00000018F4ull))
+#define CVMX_NPI_PCI_CFG62 (CVMX_ADD_IO_SEG(0x00011F00000018F8ull))
+#define CVMX_NPI_PCI_CFG63 (CVMX_ADD_IO_SEG(0x00011F00000018FCull))
+#define CVMX_NPI_PCI_CNT_REG (CVMX_ADD_IO_SEG(0x00011F00000011B8ull))
+#define CVMX_NPI_PCI_CTL_STATUS_2 (CVMX_ADD_IO_SEG(0x00011F000000118Cull))
+#define CVMX_NPI_PCI_INT_ARB_CFG (CVMX_ADD_IO_SEG(0x00011F0000000130ull))
+#define CVMX_NPI_PCI_INT_ENB2 (CVMX_ADD_IO_SEG(0x00011F00000011A0ull))
+#define CVMX_NPI_PCI_INT_SUM2 (CVMX_ADD_IO_SEG(0x00011F0000001198ull))
+#define CVMX_NPI_PCI_READ_CMD (CVMX_ADD_IO_SEG(0x00011F0000000048ull))
+#define CVMX_NPI_PCI_READ_CMD_6 (CVMX_ADD_IO_SEG(0x00011F0000001180ull))
+#define CVMX_NPI_PCI_READ_CMD_C (CVMX_ADD_IO_SEG(0x00011F0000001184ull))
+#define CVMX_NPI_PCI_READ_CMD_E (CVMX_ADD_IO_SEG(0x00011F0000001188ull))
+#define CVMX_NPI_PCI_SCM_REG (CVMX_ADD_IO_SEG(0x00011F00000011A8ull))
+#define CVMX_NPI_PCI_TSR_REG (CVMX_ADD_IO_SEG(0x00011F00000011B0ull))
+#define CVMX_NPI_PORT32_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F00000001F8ull))
+#define CVMX_NPI_PORT33_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000200ull))
+#define CVMX_NPI_PORT34_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000208ull))
+#define CVMX_NPI_PORT35_INSTR_HDR (CVMX_ADD_IO_SEG(0x00011F0000000210ull))
+#define CVMX_NPI_PORT_BP_CONTROL (CVMX_ADD_IO_SEG(0x00011F00000001F0ull))
+#define CVMX_NPI_PX_DBPAIR_ADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000000180ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_INSTR_ADDR(offset) (CVMX_ADD_IO_SEG(0x00011F00000001C0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_INSTR_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F00000001A0ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_PX_PAIR_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000000160ull) + ((offset) & 3) * 8)
+#define CVMX_NPI_RSL_INT_BLOCKS (CVMX_ADD_IO_SEG(0x00011F0000000000ull))
+#define CVMX_NPI_SIZE_INPUT0 CVMX_NPI_SIZE_INPUTX(0)
+#define CVMX_NPI_SIZE_INPUT1 CVMX_NPI_SIZE_INPUTX(1)
+#define CVMX_NPI_SIZE_INPUT2 CVMX_NPI_SIZE_INPUTX(2)
+#define CVMX_NPI_SIZE_INPUT3 CVMX_NPI_SIZE_INPUTX(3)
+#define CVMX_NPI_SIZE_INPUTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000000078ull) + ((offset) & 3) * 16)
+#define CVMX_NPI_WIN_READ_TO (CVMX_ADD_IO_SEG(0x00011F00000001E0ull))
+
+union cvmx_npi_base_addr_inputx {
+ uint64_t u64;
+ struct cvmx_npi_base_addr_inputx_s {
+ uint64_t baddr:61;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_npi_base_addr_inputx_s cn30xx;
+ struct cvmx_npi_base_addr_inputx_s cn31xx;
+ struct cvmx_npi_base_addr_inputx_s cn38xx;
+ struct cvmx_npi_base_addr_inputx_s cn38xxp2;
+ struct cvmx_npi_base_addr_inputx_s cn50xx;
+ struct cvmx_npi_base_addr_inputx_s cn58xx;
+ struct cvmx_npi_base_addr_inputx_s cn58xxp1;
+};
+
+union cvmx_npi_base_addr_outputx {
+ uint64_t u64;
+ struct cvmx_npi_base_addr_outputx_s {
+ uint64_t baddr:61;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_npi_base_addr_outputx_s cn30xx;
+ struct cvmx_npi_base_addr_outputx_s cn31xx;
+ struct cvmx_npi_base_addr_outputx_s cn38xx;
+ struct cvmx_npi_base_addr_outputx_s cn38xxp2;
+ struct cvmx_npi_base_addr_outputx_s cn50xx;
+ struct cvmx_npi_base_addr_outputx_s cn58xx;
+ struct cvmx_npi_base_addr_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_bist_status {
+ uint64_t u64;
+ struct cvmx_npi_bist_status_s {
+ uint64_t reserved_20_63:44;
+ uint64_t csr_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pof0_bs:1;
+ uint64_t pof1_bs:1;
+ uint64_t pof2_bs:1;
+ uint64_t pof3_bs:1;
+ uint64_t pos_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dpi_bs:1;
+ } s;
+ struct cvmx_npi_bist_status_cn30xx {
+ uint64_t reserved_20_63:44;
+ uint64_t csr_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pof0_bs:1;
+ uint64_t reserved_5_7:3;
+ uint64_t pos_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dpi_bs:1;
+ } cn30xx;
+ struct cvmx_npi_bist_status_s cn31xx;
+ struct cvmx_npi_bist_status_s cn38xx;
+ struct cvmx_npi_bist_status_s cn38xxp2;
+ struct cvmx_npi_bist_status_cn50xx {
+ uint64_t reserved_20_63:44;
+ uint64_t csr_bs:1;
+ uint64_t dif_bs:1;
+ uint64_t rdp_bs:1;
+ uint64_t pcnc_bs:1;
+ uint64_t pcn_bs:1;
+ uint64_t rdn_bs:1;
+ uint64_t pcac_bs:1;
+ uint64_t pcad_bs:1;
+ uint64_t rdnl_bs:1;
+ uint64_t pgf_bs:1;
+ uint64_t pig_bs:1;
+ uint64_t pof0_bs:1;
+ uint64_t pof1_bs:1;
+ uint64_t reserved_5_6:2;
+ uint64_t pos_bs:1;
+ uint64_t nus_bs:1;
+ uint64_t dob_bs:1;
+ uint64_t pdf_bs:1;
+ uint64_t dpi_bs:1;
+ } cn50xx;
+ struct cvmx_npi_bist_status_s cn58xx;
+ struct cvmx_npi_bist_status_s cn58xxp1;
+};
+
+union cvmx_npi_buff_size_outputx {
+ uint64_t u64;
+ struct cvmx_npi_buff_size_outputx_s {
+ uint64_t reserved_23_63:41;
+ uint64_t isize:7;
+ uint64_t bsize:16;
+ } s;
+ struct cvmx_npi_buff_size_outputx_s cn30xx;
+ struct cvmx_npi_buff_size_outputx_s cn31xx;
+ struct cvmx_npi_buff_size_outputx_s cn38xx;
+ struct cvmx_npi_buff_size_outputx_s cn38xxp2;
+ struct cvmx_npi_buff_size_outputx_s cn50xx;
+ struct cvmx_npi_buff_size_outputx_s cn58xx;
+ struct cvmx_npi_buff_size_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_comp_ctl {
+ uint64_t u64;
+ struct cvmx_npi_comp_ctl_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pctl:5;
+ uint64_t nctl:5;
+ } s;
+ struct cvmx_npi_comp_ctl_s cn50xx;
+ struct cvmx_npi_comp_ctl_s cn58xx;
+ struct cvmx_npi_comp_ctl_s cn58xxp1;
+};
+
+union cvmx_npi_ctl_status {
+ uint64_t u64;
+ struct cvmx_npi_ctl_status_s {
+ uint64_t reserved_63_63:1;
+ uint64_t chip_rev:8;
+ uint64_t dis_pniw:1;
+ uint64_t out3_enb:1;
+ uint64_t out2_enb:1;
+ uint64_t out1_enb:1;
+ uint64_t out0_enb:1;
+ uint64_t ins3_enb:1;
+ uint64_t ins2_enb:1;
+ uint64_t ins1_enb:1;
+ uint64_t ins0_enb:1;
+ uint64_t ins3_64b:1;
+ uint64_t ins2_64b:1;
+ uint64_t ins1_64b:1;
+ uint64_t ins0_64b:1;
+ uint64_t pci_wdis:1;
+ uint64_t wait_com:1;
+ uint64_t reserved_37_39:3;
+ uint64_t max_word:5;
+ uint64_t reserved_10_31:22;
+ uint64_t timer:10;
+ } s;
+ struct cvmx_npi_ctl_status_cn30xx {
+ uint64_t reserved_63_63:1;
+ uint64_t chip_rev:8;
+ uint64_t dis_pniw:1;
+ uint64_t reserved_51_53:3;
+ uint64_t out0_enb:1;
+ uint64_t reserved_47_49:3;
+ uint64_t ins0_enb:1;
+ uint64_t reserved_43_45:3;
+ uint64_t ins0_64b:1;
+ uint64_t pci_wdis:1;
+ uint64_t wait_com:1;
+ uint64_t reserved_37_39:3;
+ uint64_t max_word:5;
+ uint64_t reserved_10_31:22;
+ uint64_t timer:10;
+ } cn30xx;
+ struct cvmx_npi_ctl_status_cn31xx {
+ uint64_t reserved_63_63:1;
+ uint64_t chip_rev:8;
+ uint64_t dis_pniw:1;
+ uint64_t reserved_52_53:2;
+ uint64_t out1_enb:1;
+ uint64_t out0_enb:1;
+ uint64_t reserved_48_49:2;
+ uint64_t ins1_enb:1;
+ uint64_t ins0_enb:1;
+ uint64_t reserved_44_45:2;
+ uint64_t ins1_64b:1;
+ uint64_t ins0_64b:1;
+ uint64_t pci_wdis:1;
+ uint64_t wait_com:1;
+ uint64_t reserved_37_39:3;
+ uint64_t max_word:5;
+ uint64_t reserved_10_31:22;
+ uint64_t timer:10;
+ } cn31xx;
+ struct cvmx_npi_ctl_status_s cn38xx;
+ struct cvmx_npi_ctl_status_s cn38xxp2;
+ struct cvmx_npi_ctl_status_cn31xx cn50xx;
+ struct cvmx_npi_ctl_status_s cn58xx;
+ struct cvmx_npi_ctl_status_s cn58xxp1;
+};
+
+union cvmx_npi_dbg_select {
+ uint64_t u64;
+ struct cvmx_npi_dbg_select_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbg_sel:16;
+ } s;
+ struct cvmx_npi_dbg_select_s cn30xx;
+ struct cvmx_npi_dbg_select_s cn31xx;
+ struct cvmx_npi_dbg_select_s cn38xx;
+ struct cvmx_npi_dbg_select_s cn38xxp2;
+ struct cvmx_npi_dbg_select_s cn50xx;
+ struct cvmx_npi_dbg_select_s cn58xx;
+ struct cvmx_npi_dbg_select_s cn58xxp1;
+};
+
+union cvmx_npi_dma_control {
+ uint64_t u64;
+ struct cvmx_npi_dma_control_s {
+ uint64_t reserved_36_63:28;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t hp_enb:1;
+ uint64_t lp_enb:1;
+ uint64_t csize:14;
+ } s;
+ struct cvmx_npi_dma_control_s cn30xx;
+ struct cvmx_npi_dma_control_s cn31xx;
+ struct cvmx_npi_dma_control_s cn38xx;
+ struct cvmx_npi_dma_control_s cn38xxp2;
+ struct cvmx_npi_dma_control_s cn50xx;
+ struct cvmx_npi_dma_control_s cn58xx;
+ struct cvmx_npi_dma_control_s cn58xxp1;
+};
+
+union cvmx_npi_dma_highp_counts {
+ uint64_t u64;
+ struct cvmx_npi_dma_highp_counts_s {
+ uint64_t reserved_39_63:25;
+ uint64_t fcnt:7;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npi_dma_highp_counts_s cn30xx;
+ struct cvmx_npi_dma_highp_counts_s cn31xx;
+ struct cvmx_npi_dma_highp_counts_s cn38xx;
+ struct cvmx_npi_dma_highp_counts_s cn38xxp2;
+ struct cvmx_npi_dma_highp_counts_s cn50xx;
+ struct cvmx_npi_dma_highp_counts_s cn58xx;
+ struct cvmx_npi_dma_highp_counts_s cn58xxp1;
+};
+
+union cvmx_npi_dma_highp_naddr {
+ uint64_t u64;
+ struct cvmx_npi_dma_highp_naddr_s {
+ uint64_t reserved_40_63:24;
+ uint64_t state:4;
+ uint64_t addr:36;
+ } s;
+ struct cvmx_npi_dma_highp_naddr_s cn30xx;
+ struct cvmx_npi_dma_highp_naddr_s cn31xx;
+ struct cvmx_npi_dma_highp_naddr_s cn38xx;
+ struct cvmx_npi_dma_highp_naddr_s cn38xxp2;
+ struct cvmx_npi_dma_highp_naddr_s cn50xx;
+ struct cvmx_npi_dma_highp_naddr_s cn58xx;
+ struct cvmx_npi_dma_highp_naddr_s cn58xxp1;
+};
+
+union cvmx_npi_dma_lowp_counts {
+ uint64_t u64;
+ struct cvmx_npi_dma_lowp_counts_s {
+ uint64_t reserved_39_63:25;
+ uint64_t fcnt:7;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_npi_dma_lowp_counts_s cn30xx;
+ struct cvmx_npi_dma_lowp_counts_s cn31xx;
+ struct cvmx_npi_dma_lowp_counts_s cn38xx;
+ struct cvmx_npi_dma_lowp_counts_s cn38xxp2;
+ struct cvmx_npi_dma_lowp_counts_s cn50xx;
+ struct cvmx_npi_dma_lowp_counts_s cn58xx;
+ struct cvmx_npi_dma_lowp_counts_s cn58xxp1;
+};
+
+union cvmx_npi_dma_lowp_naddr {
+ uint64_t u64;
+ struct cvmx_npi_dma_lowp_naddr_s {
+ uint64_t reserved_40_63:24;
+ uint64_t state:4;
+ uint64_t addr:36;
+ } s;
+ struct cvmx_npi_dma_lowp_naddr_s cn30xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn31xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn38xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn38xxp2;
+ struct cvmx_npi_dma_lowp_naddr_s cn50xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn58xx;
+ struct cvmx_npi_dma_lowp_naddr_s cn58xxp1;
+};
+
+union cvmx_npi_highp_dbell {
+ uint64_t u64;
+ struct cvmx_npi_highp_dbell_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbell:16;
+ } s;
+ struct cvmx_npi_highp_dbell_s cn30xx;
+ struct cvmx_npi_highp_dbell_s cn31xx;
+ struct cvmx_npi_highp_dbell_s cn38xx;
+ struct cvmx_npi_highp_dbell_s cn38xxp2;
+ struct cvmx_npi_highp_dbell_s cn50xx;
+ struct cvmx_npi_highp_dbell_s cn58xx;
+ struct cvmx_npi_highp_dbell_s cn58xxp1;
+};
+
+union cvmx_npi_highp_ibuff_saddr {
+ uint64_t u64;
+ struct cvmx_npi_highp_ibuff_saddr_s {
+ uint64_t reserved_36_63:28;
+ uint64_t saddr:36;
+ } s;
+ struct cvmx_npi_highp_ibuff_saddr_s cn30xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn31xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn38xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn38xxp2;
+ struct cvmx_npi_highp_ibuff_saddr_s cn50xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn58xx;
+ struct cvmx_npi_highp_ibuff_saddr_s cn58xxp1;
+};
+
+union cvmx_npi_input_control {
+ uint64_t u64;
+ struct cvmx_npi_input_control_s {
+ uint64_t reserved_23_63:41;
+ uint64_t pkt_rr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t d_nsr:1;
+ uint64_t d_esr:2;
+ uint64_t d_ror:1;
+ uint64_t use_csr:1;
+ uint64_t nsr:1;
+ uint64_t esr:2;
+ uint64_t ror:1;
+ } s;
+ struct cvmx_npi_input_control_cn30xx {
+ uint64_t reserved_22_63:42;
+ uint64_t pbp_dhi:13;
+ uint64_t d_nsr:1;
+ uint64_t d_esr:2;
+ uint64_t d_ror:1;
+ uint64_t use_csr:1;
+ uint64_t nsr:1;
+ uint64_t esr:2;
+ uint64_t ror:1;
+ } cn30xx;
+ struct cvmx_npi_input_control_cn30xx cn31xx;
+ struct cvmx_npi_input_control_s cn38xx;
+ struct cvmx_npi_input_control_cn30xx cn38xxp2;
+ struct cvmx_npi_input_control_s cn50xx;
+ struct cvmx_npi_input_control_s cn58xx;
+ struct cvmx_npi_input_control_s cn58xxp1;
+};
+
+union cvmx_npi_int_enb {
+ uint64_t u64;
+ struct cvmx_npi_int_enb_s {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t i3_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t p3_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t p3_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t g3_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t p3_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t p3_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t i3_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t i3_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t po3_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npi_int_enb_cn30xx {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t reserved_36_38:3;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_32_34:3;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_28_30:3;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_24_26:3;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_20_22:3;
+ uint64_t p0_perr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_12_14:3;
+ uint64_t i0_overf:1;
+ uint64_t reserved_8_10:3;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_4_6:3;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn30xx;
+ struct cvmx_npi_int_enb_cn31xx {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t reserved_37_38:2;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_33_34:2;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_29_30:2;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_25_26:2;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_21_22:2;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t reserved_17_18:2;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_13_14:2;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t reserved_9_10:2;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_5_6:2;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn31xx;
+ struct cvmx_npi_int_enb_s cn38xx;
+ struct cvmx_npi_int_enb_cn38xxp2 {
+ uint64_t reserved_42_63:22;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t i3_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t p3_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t p3_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t g3_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t p3_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t p3_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t i3_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t i3_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t po3_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn38xxp2;
+ struct cvmx_npi_int_enb_cn31xx cn50xx;
+ struct cvmx_npi_int_enb_s cn58xx;
+ struct cvmx_npi_int_enb_s cn58xxp1;
+};
+
+union cvmx_npi_int_sum {
+ uint64_t u64;
+ struct cvmx_npi_int_sum_s {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t i3_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t p3_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t p3_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t g3_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t p3_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t p3_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t i3_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t i3_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t po3_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } s;
+ struct cvmx_npi_int_sum_cn30xx {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t reserved_36_38:3;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_32_34:3;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_28_30:3;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_24_26:3;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_20_22:3;
+ uint64_t p0_perr:1;
+ uint64_t reserved_16_18:3;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_12_14:3;
+ uint64_t i0_overf:1;
+ uint64_t reserved_8_10:3;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_4_6:3;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn30xx;
+ struct cvmx_npi_int_sum_cn31xx {
+ uint64_t reserved_62_63:2;
+ uint64_t q1_a_f:1;
+ uint64_t q1_s_e:1;
+ uint64_t pdf_p_f:1;
+ uint64_t pdf_p_e:1;
+ uint64_t pcf_p_f:1;
+ uint64_t pcf_p_e:1;
+ uint64_t rdx_s_e:1;
+ uint64_t rwx_s_e:1;
+ uint64_t pnc_a_f:1;
+ uint64_t pnc_s_e:1;
+ uint64_t com_a_f:1;
+ uint64_t com_s_e:1;
+ uint64_t q3_a_f:1;
+ uint64_t q3_s_e:1;
+ uint64_t q2_a_f:1;
+ uint64_t q2_s_e:1;
+ uint64_t pcr_a_f:1;
+ uint64_t pcr_s_e:1;
+ uint64_t fcr_a_f:1;
+ uint64_t fcr_s_e:1;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t reserved_37_38:2;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t reserved_33_34:2;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t reserved_29_30:2;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t reserved_25_26:2;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t reserved_21_22:2;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t reserved_17_18:2;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t reserved_13_14:2;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t reserved_9_10:2;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t reserved_5_6:2;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn31xx;
+ struct cvmx_npi_int_sum_s cn38xx;
+ struct cvmx_npi_int_sum_cn38xxp2 {
+ uint64_t reserved_42_63:22;
+ uint64_t iobdma:1;
+ uint64_t p_dperr:1;
+ uint64_t win_rto:1;
+ uint64_t i3_pperr:1;
+ uint64_t i2_pperr:1;
+ uint64_t i1_pperr:1;
+ uint64_t i0_pperr:1;
+ uint64_t p3_ptout:1;
+ uint64_t p2_ptout:1;
+ uint64_t p1_ptout:1;
+ uint64_t p0_ptout:1;
+ uint64_t p3_pperr:1;
+ uint64_t p2_pperr:1;
+ uint64_t p1_pperr:1;
+ uint64_t p0_pperr:1;
+ uint64_t g3_rtout:1;
+ uint64_t g2_rtout:1;
+ uint64_t g1_rtout:1;
+ uint64_t g0_rtout:1;
+ uint64_t p3_perr:1;
+ uint64_t p2_perr:1;
+ uint64_t p1_perr:1;
+ uint64_t p0_perr:1;
+ uint64_t p3_rtout:1;
+ uint64_t p2_rtout:1;
+ uint64_t p1_rtout:1;
+ uint64_t p0_rtout:1;
+ uint64_t i3_overf:1;
+ uint64_t i2_overf:1;
+ uint64_t i1_overf:1;
+ uint64_t i0_overf:1;
+ uint64_t i3_rtout:1;
+ uint64_t i2_rtout:1;
+ uint64_t i1_rtout:1;
+ uint64_t i0_rtout:1;
+ uint64_t po3_2sml:1;
+ uint64_t po2_2sml:1;
+ uint64_t po1_2sml:1;
+ uint64_t po0_2sml:1;
+ uint64_t pci_rsl:1;
+ uint64_t rml_wto:1;
+ uint64_t rml_rto:1;
+ } cn38xxp2;
+ struct cvmx_npi_int_sum_cn31xx cn50xx;
+ struct cvmx_npi_int_sum_s cn58xx;
+ struct cvmx_npi_int_sum_s cn58xxp1;
+};
+
+union cvmx_npi_lowp_dbell {
+ uint64_t u64;
+ struct cvmx_npi_lowp_dbell_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbell:16;
+ } s;
+ struct cvmx_npi_lowp_dbell_s cn30xx;
+ struct cvmx_npi_lowp_dbell_s cn31xx;
+ struct cvmx_npi_lowp_dbell_s cn38xx;
+ struct cvmx_npi_lowp_dbell_s cn38xxp2;
+ struct cvmx_npi_lowp_dbell_s cn50xx;
+ struct cvmx_npi_lowp_dbell_s cn58xx;
+ struct cvmx_npi_lowp_dbell_s cn58xxp1;
+};
+
+union cvmx_npi_lowp_ibuff_saddr {
+ uint64_t u64;
+ struct cvmx_npi_lowp_ibuff_saddr_s {
+ uint64_t reserved_36_63:28;
+ uint64_t saddr:36;
+ } s;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn30xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn31xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn38xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn38xxp2;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn50xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn58xx;
+ struct cvmx_npi_lowp_ibuff_saddr_s cn58xxp1;
+};
+
+union cvmx_npi_mem_access_subidx {
+ uint64_t u64;
+ struct cvmx_npi_mem_access_subidx_s {
+ uint64_t reserved_38_63:26;
+ uint64_t shortl:1;
+ uint64_t nmerge:1;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t nsr:1;
+ uint64_t nsw:1;
+ uint64_t ror:1;
+ uint64_t row:1;
+ uint64_t ba:28;
+ } s;
+ struct cvmx_npi_mem_access_subidx_s cn30xx;
+ struct cvmx_npi_mem_access_subidx_cn31xx {
+ uint64_t reserved_36_63:28;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t nsr:1;
+ uint64_t nsw:1;
+ uint64_t ror:1;
+ uint64_t row:1;
+ uint64_t ba:28;
+ } cn31xx;
+ struct cvmx_npi_mem_access_subidx_s cn38xx;
+ struct cvmx_npi_mem_access_subidx_cn31xx cn38xxp2;
+ struct cvmx_npi_mem_access_subidx_s cn50xx;
+ struct cvmx_npi_mem_access_subidx_s cn58xx;
+ struct cvmx_npi_mem_access_subidx_s cn58xxp1;
+};
+
+union cvmx_npi_msi_rcv {
+ uint64_t u64;
+ struct cvmx_npi_msi_rcv_s {
+ uint64_t int_vec:64;
+ } s;
+ struct cvmx_npi_msi_rcv_s cn30xx;
+ struct cvmx_npi_msi_rcv_s cn31xx;
+ struct cvmx_npi_msi_rcv_s cn38xx;
+ struct cvmx_npi_msi_rcv_s cn38xxp2;
+ struct cvmx_npi_msi_rcv_s cn50xx;
+ struct cvmx_npi_msi_rcv_s cn58xx;
+ struct cvmx_npi_msi_rcv_s cn58xxp1;
+};
+
+union cvmx_npi_num_desc_outputx {
+ uint64_t u64;
+ struct cvmx_npi_num_desc_outputx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t size:32;
+ } s;
+ struct cvmx_npi_num_desc_outputx_s cn30xx;
+ struct cvmx_npi_num_desc_outputx_s cn31xx;
+ struct cvmx_npi_num_desc_outputx_s cn38xx;
+ struct cvmx_npi_num_desc_outputx_s cn38xxp2;
+ struct cvmx_npi_num_desc_outputx_s cn50xx;
+ struct cvmx_npi_num_desc_outputx_s cn58xx;
+ struct cvmx_npi_num_desc_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_output_control {
+ uint64_t u64;
+ struct cvmx_npi_output_control_s {
+ uint64_t reserved_49_63:15;
+ uint64_t pkt_rr:1;
+ uint64_t p3_bmode:1;
+ uint64_t p2_bmode:1;
+ uint64_t p1_bmode:1;
+ uint64_t p0_bmode:1;
+ uint64_t o3_es:2;
+ uint64_t o3_ns:1;
+ uint64_t o3_ro:1;
+ uint64_t o2_es:2;
+ uint64_t o2_ns:1;
+ uint64_t o2_ro:1;
+ uint64_t o1_es:2;
+ uint64_t o1_ns:1;
+ uint64_t o1_ro:1;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t o3_csrm:1;
+ uint64_t o2_csrm:1;
+ uint64_t o1_csrm:1;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_20_23:4;
+ uint64_t iptr_o3:1;
+ uint64_t iptr_o2:1;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o0:1;
+ uint64_t esr_sl3:2;
+ uint64_t nsr_sl3:1;
+ uint64_t ror_sl3:1;
+ uint64_t esr_sl2:2;
+ uint64_t nsr_sl2:1;
+ uint64_t ror_sl2:1;
+ uint64_t esr_sl1:2;
+ uint64_t nsr_sl1:1;
+ uint64_t ror_sl1:1;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } s;
+ struct cvmx_npi_output_control_cn30xx {
+ uint64_t reserved_45_63:19;
+ uint64_t p0_bmode:1;
+ uint64_t reserved_32_43:12;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t reserved_25_27:3;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_17_23:7;
+ uint64_t iptr_o0:1;
+ uint64_t reserved_4_15:12;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } cn30xx;
+ struct cvmx_npi_output_control_cn31xx {
+ uint64_t reserved_46_63:18;
+ uint64_t p1_bmode:1;
+ uint64_t p0_bmode:1;
+ uint64_t reserved_36_43:8;
+ uint64_t o1_es:2;
+ uint64_t o1_ns:1;
+ uint64_t o1_ro:1;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t reserved_26_27:2;
+ uint64_t o1_csrm:1;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_18_23:6;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o0:1;
+ uint64_t reserved_8_15:8;
+ uint64_t esr_sl1:2;
+ uint64_t nsr_sl1:1;
+ uint64_t ror_sl1:1;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } cn31xx;
+ struct cvmx_npi_output_control_s cn38xx;
+ struct cvmx_npi_output_control_cn38xxp2 {
+ uint64_t reserved_48_63:16;
+ uint64_t p3_bmode:1;
+ uint64_t p2_bmode:1;
+ uint64_t p1_bmode:1;
+ uint64_t p0_bmode:1;
+ uint64_t o3_es:2;
+ uint64_t o3_ns:1;
+ uint64_t o3_ro:1;
+ uint64_t o2_es:2;
+ uint64_t o2_ns:1;
+ uint64_t o2_ro:1;
+ uint64_t o1_es:2;
+ uint64_t o1_ns:1;
+ uint64_t o1_ro:1;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t o3_csrm:1;
+ uint64_t o2_csrm:1;
+ uint64_t o1_csrm:1;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_20_23:4;
+ uint64_t iptr_o3:1;
+ uint64_t iptr_o2:1;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o0:1;
+ uint64_t esr_sl3:2;
+ uint64_t nsr_sl3:1;
+ uint64_t ror_sl3:1;
+ uint64_t esr_sl2:2;
+ uint64_t nsr_sl2:1;
+ uint64_t ror_sl2:1;
+ uint64_t esr_sl1:2;
+ uint64_t nsr_sl1:1;
+ uint64_t ror_sl1:1;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } cn38xxp2;
+ struct cvmx_npi_output_control_cn50xx {
+ uint64_t reserved_49_63:15;
+ uint64_t pkt_rr:1;
+ uint64_t reserved_46_47:2;
+ uint64_t p1_bmode:1;
+ uint64_t p0_bmode:1;
+ uint64_t reserved_36_43:8;
+ uint64_t o1_es:2;
+ uint64_t o1_ns:1;
+ uint64_t o1_ro:1;
+ uint64_t o0_es:2;
+ uint64_t o0_ns:1;
+ uint64_t o0_ro:1;
+ uint64_t reserved_26_27:2;
+ uint64_t o1_csrm:1;
+ uint64_t o0_csrm:1;
+ uint64_t reserved_18_23:6;
+ uint64_t iptr_o1:1;
+ uint64_t iptr_o0:1;
+ uint64_t reserved_8_15:8;
+ uint64_t esr_sl1:2;
+ uint64_t nsr_sl1:1;
+ uint64_t ror_sl1:1;
+ uint64_t esr_sl0:2;
+ uint64_t nsr_sl0:1;
+ uint64_t ror_sl0:1;
+ } cn50xx;
+ struct cvmx_npi_output_control_s cn58xx;
+ struct cvmx_npi_output_control_s cn58xxp1;
+};
+
+union cvmx_npi_px_dbpair_addr {
+ uint64_t u64;
+ struct cvmx_npi_px_dbpair_addr_s {
+ uint64_t reserved_63_63:1;
+ uint64_t state:2;
+ uint64_t naddr:61;
+ } s;
+ struct cvmx_npi_px_dbpair_addr_s cn30xx;
+ struct cvmx_npi_px_dbpair_addr_s cn31xx;
+ struct cvmx_npi_px_dbpair_addr_s cn38xx;
+ struct cvmx_npi_px_dbpair_addr_s cn38xxp2;
+ struct cvmx_npi_px_dbpair_addr_s cn50xx;
+ struct cvmx_npi_px_dbpair_addr_s cn58xx;
+ struct cvmx_npi_px_dbpair_addr_s cn58xxp1;
+};
+
+union cvmx_npi_px_instr_addr {
+ uint64_t u64;
+ struct cvmx_npi_px_instr_addr_s {
+ uint64_t state:3;
+ uint64_t naddr:61;
+ } s;
+ struct cvmx_npi_px_instr_addr_s cn30xx;
+ struct cvmx_npi_px_instr_addr_s cn31xx;
+ struct cvmx_npi_px_instr_addr_s cn38xx;
+ struct cvmx_npi_px_instr_addr_s cn38xxp2;
+ struct cvmx_npi_px_instr_addr_s cn50xx;
+ struct cvmx_npi_px_instr_addr_s cn58xx;
+ struct cvmx_npi_px_instr_addr_s cn58xxp1;
+};
+
+union cvmx_npi_px_instr_cnts {
+ uint64_t u64;
+ struct cvmx_npi_px_instr_cnts_s {
+ uint64_t reserved_38_63:26;
+ uint64_t fcnt:6;
+ uint64_t avail:32;
+ } s;
+ struct cvmx_npi_px_instr_cnts_s cn30xx;
+ struct cvmx_npi_px_instr_cnts_s cn31xx;
+ struct cvmx_npi_px_instr_cnts_s cn38xx;
+ struct cvmx_npi_px_instr_cnts_s cn38xxp2;
+ struct cvmx_npi_px_instr_cnts_s cn50xx;
+ struct cvmx_npi_px_instr_cnts_s cn58xx;
+ struct cvmx_npi_px_instr_cnts_s cn58xxp1;
+};
+
+union cvmx_npi_px_pair_cnts {
+ uint64_t u64;
+ struct cvmx_npi_px_pair_cnts_s {
+ uint64_t reserved_37_63:27;
+ uint64_t fcnt:5;
+ uint64_t avail:32;
+ } s;
+ struct cvmx_npi_px_pair_cnts_s cn30xx;
+ struct cvmx_npi_px_pair_cnts_s cn31xx;
+ struct cvmx_npi_px_pair_cnts_s cn38xx;
+ struct cvmx_npi_px_pair_cnts_s cn38xxp2;
+ struct cvmx_npi_px_pair_cnts_s cn50xx;
+ struct cvmx_npi_px_pair_cnts_s cn58xx;
+ struct cvmx_npi_px_pair_cnts_s cn58xxp1;
+};
+
+union cvmx_npi_pci_burst_size {
+ uint64_t u64;
+ struct cvmx_npi_pci_burst_size_s {
+ uint64_t reserved_14_63:50;
+ uint64_t wr_brst:7;
+ uint64_t rd_brst:7;
+ } s;
+ struct cvmx_npi_pci_burst_size_s cn30xx;
+ struct cvmx_npi_pci_burst_size_s cn31xx;
+ struct cvmx_npi_pci_burst_size_s cn38xx;
+ struct cvmx_npi_pci_burst_size_s cn38xxp2;
+ struct cvmx_npi_pci_burst_size_s cn50xx;
+ struct cvmx_npi_pci_burst_size_s cn58xx;
+ struct cvmx_npi_pci_burst_size_s cn58xxp1;
+};
+
+union cvmx_npi_pci_int_arb_cfg {
+ uint64_t u64;
+ struct cvmx_npi_pci_int_arb_cfg_s {
+ uint64_t reserved_13_63:51;
+ uint64_t hostmode:1;
+ uint64_t pci_ovr:4;
+ uint64_t reserved_5_7:3;
+ uint64_t en:1;
+ uint64_t park_mod:1;
+ uint64_t park_dev:3;
+ } s;
+ struct cvmx_npi_pci_int_arb_cfg_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t en:1;
+ uint64_t park_mod:1;
+ uint64_t park_dev:3;
+ } cn30xx;
+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn31xx;
+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xx;
+ struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xxp2;
+ struct cvmx_npi_pci_int_arb_cfg_s cn50xx;
+ struct cvmx_npi_pci_int_arb_cfg_s cn58xx;
+ struct cvmx_npi_pci_int_arb_cfg_s cn58xxp1;
+};
+
+union cvmx_npi_pci_read_cmd {
+ uint64_t u64;
+ struct cvmx_npi_pci_read_cmd_s {
+ uint64_t reserved_11_63:53;
+ uint64_t cmd_size:11;
+ } s;
+ struct cvmx_npi_pci_read_cmd_s cn30xx;
+ struct cvmx_npi_pci_read_cmd_s cn31xx;
+ struct cvmx_npi_pci_read_cmd_s cn38xx;
+ struct cvmx_npi_pci_read_cmd_s cn38xxp2;
+ struct cvmx_npi_pci_read_cmd_s cn50xx;
+ struct cvmx_npi_pci_read_cmd_s cn58xx;
+ struct cvmx_npi_pci_read_cmd_s cn58xxp1;
+};
+
+union cvmx_npi_port32_instr_hdr {
+ uint64_t u64;
+ struct cvmx_npi_port32_instr_hdr_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npi_port32_instr_hdr_s cn30xx;
+ struct cvmx_npi_port32_instr_hdr_s cn31xx;
+ struct cvmx_npi_port32_instr_hdr_s cn38xx;
+ struct cvmx_npi_port32_instr_hdr_s cn38xxp2;
+ struct cvmx_npi_port32_instr_hdr_s cn50xx;
+ struct cvmx_npi_port32_instr_hdr_s cn58xx;
+ struct cvmx_npi_port32_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port33_instr_hdr {
+ uint64_t u64;
+ struct cvmx_npi_port33_instr_hdr_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npi_port33_instr_hdr_s cn31xx;
+ struct cvmx_npi_port33_instr_hdr_s cn38xx;
+ struct cvmx_npi_port33_instr_hdr_s cn38xxp2;
+ struct cvmx_npi_port33_instr_hdr_s cn50xx;
+ struct cvmx_npi_port33_instr_hdr_s cn58xx;
+ struct cvmx_npi_port33_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port34_instr_hdr {
+ uint64_t u64;
+ struct cvmx_npi_port34_instr_hdr_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npi_port34_instr_hdr_s cn38xx;
+ struct cvmx_npi_port34_instr_hdr_s cn38xxp2;
+ struct cvmx_npi_port34_instr_hdr_s cn58xx;
+ struct cvmx_npi_port34_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port35_instr_hdr {
+ uint64_t u64;
+ struct cvmx_npi_port35_instr_hdr_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t rsv_f:5;
+ uint64_t rparmode:2;
+ uint64_t rsv_e:1;
+ uint64_t rskp_len:7;
+ uint64_t rsv_d:6;
+ uint64_t use_ihdr:1;
+ uint64_t rsv_c:5;
+ uint64_t par_mode:2;
+ uint64_t rsv_b:1;
+ uint64_t skp_len:7;
+ uint64_t rsv_a:6;
+ } s;
+ struct cvmx_npi_port35_instr_hdr_s cn38xx;
+ struct cvmx_npi_port35_instr_hdr_s cn38xxp2;
+ struct cvmx_npi_port35_instr_hdr_s cn58xx;
+ struct cvmx_npi_port35_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port_bp_control {
+ uint64_t u64;
+ struct cvmx_npi_port_bp_control_s {
+ uint64_t reserved_8_63:56;
+ uint64_t bp_on:4;
+ uint64_t enb:4;
+ } s;
+ struct cvmx_npi_port_bp_control_s cn30xx;
+ struct cvmx_npi_port_bp_control_s cn31xx;
+ struct cvmx_npi_port_bp_control_s cn38xx;
+ struct cvmx_npi_port_bp_control_s cn38xxp2;
+ struct cvmx_npi_port_bp_control_s cn50xx;
+ struct cvmx_npi_port_bp_control_s cn58xx;
+ struct cvmx_npi_port_bp_control_s cn58xxp1;
+};
+
+union cvmx_npi_rsl_int_blocks {
+ uint64_t u64;
+ struct cvmx_npi_rsl_int_blocks_s {
+ uint64_t reserved_32_63:32;
+ uint64_t rint_31:1;
+ uint64_t iob:1;
+ uint64_t reserved_28_29:2;
+ uint64_t rint_27:1;
+ uint64_t rint_26:1;
+ uint64_t rint_25:1;
+ uint64_t rint_24:1;
+ uint64_t asx1:1;
+ uint64_t asx0:1;
+ uint64_t rint_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc:1;
+ uint64_t l2c:1;
+ uint64_t rint_15:1;
+ uint64_t reserved_13_14:2;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t rint_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npi:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } s;
+ struct cvmx_npi_rsl_int_blocks_cn30xx {
+ uint64_t reserved_32_63:32;
+ uint64_t rint_31:1;
+ uint64_t iob:1;
+ uint64_t rint_29:1;
+ uint64_t rint_28:1;
+ uint64_t rint_27:1;
+ uint64_t rint_26:1;
+ uint64_t rint_25:1;
+ uint64_t rint_24:1;
+ uint64_t asx1:1;
+ uint64_t asx0:1;
+ uint64_t rint_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc:1;
+ uint64_t l2c:1;
+ uint64_t rint_15:1;
+ uint64_t rint_14:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t rint_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npi:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } cn30xx;
+ struct cvmx_npi_rsl_int_blocks_cn30xx cn31xx;
+ struct cvmx_npi_rsl_int_blocks_cn38xx {
+ uint64_t reserved_32_63:32;
+ uint64_t rint_31:1;
+ uint64_t iob:1;
+ uint64_t rint_29:1;
+ uint64_t rint_28:1;
+ uint64_t rint_27:1;
+ uint64_t rint_26:1;
+ uint64_t rint_25:1;
+ uint64_t rint_24:1;
+ uint64_t asx1:1;
+ uint64_t asx0:1;
+ uint64_t rint_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc:1;
+ uint64_t l2c:1;
+ uint64_t rint_15:1;
+ uint64_t rint_14:1;
+ uint64_t rint_13:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t rint_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npi:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } cn38xx;
+ struct cvmx_npi_rsl_int_blocks_cn38xx cn38xxp2;
+ struct cvmx_npi_rsl_int_blocks_cn50xx {
+ uint64_t reserved_31_63:33;
+ uint64_t iob:1;
+ uint64_t lmc1:1;
+ uint64_t agl:1;
+ uint64_t reserved_24_27:4;
+ uint64_t asx1:1;
+ uint64_t asx0:1;
+ uint64_t reserved_21_21:1;
+ uint64_t pip:1;
+ uint64_t spx1:1;
+ uint64_t spx0:1;
+ uint64_t lmc:1;
+ uint64_t l2c:1;
+ uint64_t reserved_15_15:1;
+ uint64_t rad:1;
+ uint64_t usb:1;
+ uint64_t pow:1;
+ uint64_t tim:1;
+ uint64_t pko:1;
+ uint64_t ipd:1;
+ uint64_t reserved_8_8:1;
+ uint64_t zip:1;
+ uint64_t dfa:1;
+ uint64_t fpa:1;
+ uint64_t key:1;
+ uint64_t npi:1;
+ uint64_t gmx1:1;
+ uint64_t gmx0:1;
+ uint64_t mio:1;
+ } cn50xx;
+ struct cvmx_npi_rsl_int_blocks_cn38xx cn58xx;
+ struct cvmx_npi_rsl_int_blocks_cn38xx cn58xxp1;
+};
+
+union cvmx_npi_size_inputx {
+ uint64_t u64;
+ struct cvmx_npi_size_inputx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t size:32;
+ } s;
+ struct cvmx_npi_size_inputx_s cn30xx;
+ struct cvmx_npi_size_inputx_s cn31xx;
+ struct cvmx_npi_size_inputx_s cn38xx;
+ struct cvmx_npi_size_inputx_s cn38xxp2;
+ struct cvmx_npi_size_inputx_s cn50xx;
+ struct cvmx_npi_size_inputx_s cn58xx;
+ struct cvmx_npi_size_inputx_s cn58xxp1;
+};
+
+union cvmx_npi_win_read_to {
+ uint64_t u64;
+ struct cvmx_npi_win_read_to_s {
+ uint64_t reserved_32_63:32;
+ uint64_t time:32;
+ } s;
+ struct cvmx_npi_win_read_to_s cn30xx;
+ struct cvmx_npi_win_read_to_s cn31xx;
+ struct cvmx_npi_win_read_to_s cn38xx;
+ struct cvmx_npi_win_read_to_s cn38xxp2;
+ struct cvmx_npi_win_read_to_s cn50xx;
+ struct cvmx_npi_win_read_to_s cn58xx;
+ struct cvmx_npi_win_read_to_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-packet.h b/arch/mips/include/asm/octeon/cvmx-packet.h
new file mode 100644
index 00000000..38aefa1b
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-packet.h
@@ -0,0 +1,61 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Packet buffer defines.
+ */
+
+#ifndef __CVMX_PACKET_H__
+#define __CVMX_PACKET_H__
+
+/**
+ * This structure defines a buffer pointer on Octeon
+ */
+union cvmx_buf_ptr {
+ void *ptr;
+ uint64_t u64;
+ struct {
+ /* if set, invert the "free" pick of the overall
+ * packet. HW always sets this bit to 0 on inbound
+ * packet */
+ uint64_t i:1;
+
+ /* Indicates the amount to back up to get to the
+ * buffer start in cache lines. In most cases this is
+ * less than one complete cache line, so the value is
+ * zero */
+ uint64_t back:4;
+ /* The pool that the buffer came from / goes to */
+ uint64_t pool:3;
+ /* The size of the segment pointed to by addr (in bytes) */
+ uint64_t size:16;
+ /* Pointer to the first byte of the data, NOT buffer */
+ uint64_t addr:40;
+ } s;
+};
+
+#endif /* __CVMX_PACKET_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-pci-defs.h b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
new file mode 100644
index 00000000..6ff6d9d3
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
@@ -0,0 +1,1552 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCI_DEFS_H__
+#define __CVMX_PCI_DEFS_H__
+
+#define CVMX_PCI_BAR1_INDEXX(offset) (0x0000000000000100ull + ((offset) & 31) * 4)
+#define CVMX_PCI_BIST_REG (0x00000000000001C0ull)
+#define CVMX_PCI_CFG00 (0x0000000000000000ull)
+#define CVMX_PCI_CFG01 (0x0000000000000004ull)
+#define CVMX_PCI_CFG02 (0x0000000000000008ull)
+#define CVMX_PCI_CFG03 (0x000000000000000Cull)
+#define CVMX_PCI_CFG04 (0x0000000000000010ull)
+#define CVMX_PCI_CFG05 (0x0000000000000014ull)
+#define CVMX_PCI_CFG06 (0x0000000000000018ull)
+#define CVMX_PCI_CFG07 (0x000000000000001Cull)
+#define CVMX_PCI_CFG08 (0x0000000000000020ull)
+#define CVMX_PCI_CFG09 (0x0000000000000024ull)
+#define CVMX_PCI_CFG10 (0x0000000000000028ull)
+#define CVMX_PCI_CFG11 (0x000000000000002Cull)
+#define CVMX_PCI_CFG12 (0x0000000000000030ull)
+#define CVMX_PCI_CFG13 (0x0000000000000034ull)
+#define CVMX_PCI_CFG15 (0x000000000000003Cull)
+#define CVMX_PCI_CFG16 (0x0000000000000040ull)
+#define CVMX_PCI_CFG17 (0x0000000000000044ull)
+#define CVMX_PCI_CFG18 (0x0000000000000048ull)
+#define CVMX_PCI_CFG19 (0x000000000000004Cull)
+#define CVMX_PCI_CFG20 (0x0000000000000050ull)
+#define CVMX_PCI_CFG21 (0x0000000000000054ull)
+#define CVMX_PCI_CFG22 (0x0000000000000058ull)
+#define CVMX_PCI_CFG56 (0x00000000000000E0ull)
+#define CVMX_PCI_CFG57 (0x00000000000000E4ull)
+#define CVMX_PCI_CFG58 (0x00000000000000E8ull)
+#define CVMX_PCI_CFG59 (0x00000000000000ECull)
+#define CVMX_PCI_CFG60 (0x00000000000000F0ull)
+#define CVMX_PCI_CFG61 (0x00000000000000F4ull)
+#define CVMX_PCI_CFG62 (0x00000000000000F8ull)
+#define CVMX_PCI_CFG63 (0x00000000000000FCull)
+#define CVMX_PCI_CNT_REG (0x00000000000001B8ull)
+#define CVMX_PCI_CTL_STATUS_2 (0x000000000000018Cull)
+#define CVMX_PCI_DBELL_X(offset) (0x0000000000000080ull + ((offset) & 3) * 8)
+#define CVMX_PCI_DMA_CNT0 CVMX_PCI_DMA_CNTX(0)
+#define CVMX_PCI_DMA_CNT1 CVMX_PCI_DMA_CNTX(1)
+#define CVMX_PCI_DMA_CNTX(offset) (0x00000000000000A0ull + ((offset) & 1) * 8)
+#define CVMX_PCI_DMA_INT_LEV0 CVMX_PCI_DMA_INT_LEVX(0)
+#define CVMX_PCI_DMA_INT_LEV1 CVMX_PCI_DMA_INT_LEVX(1)
+#define CVMX_PCI_DMA_INT_LEVX(offset) (0x00000000000000A4ull + ((offset) & 1) * 8)
+#define CVMX_PCI_DMA_TIME0 CVMX_PCI_DMA_TIMEX(0)
+#define CVMX_PCI_DMA_TIME1 CVMX_PCI_DMA_TIMEX(1)
+#define CVMX_PCI_DMA_TIMEX(offset) (0x00000000000000B0ull + ((offset) & 1) * 4)
+#define CVMX_PCI_INSTR_COUNT0 CVMX_PCI_INSTR_COUNTX(0)
+#define CVMX_PCI_INSTR_COUNT1 CVMX_PCI_INSTR_COUNTX(1)
+#define CVMX_PCI_INSTR_COUNT2 CVMX_PCI_INSTR_COUNTX(2)
+#define CVMX_PCI_INSTR_COUNT3 CVMX_PCI_INSTR_COUNTX(3)
+#define CVMX_PCI_INSTR_COUNTX(offset) (0x0000000000000084ull + ((offset) & 3) * 8)
+#define CVMX_PCI_INT_ENB (0x0000000000000038ull)
+#define CVMX_PCI_INT_ENB2 (0x00000000000001A0ull)
+#define CVMX_PCI_INT_SUM (0x0000000000000030ull)
+#define CVMX_PCI_INT_SUM2 (0x0000000000000198ull)
+#define CVMX_PCI_MSI_RCV (0x00000000000000F0ull)
+#define CVMX_PCI_PKTS_SENT0 CVMX_PCI_PKTS_SENTX(0)
+#define CVMX_PCI_PKTS_SENT1 CVMX_PCI_PKTS_SENTX(1)
+#define CVMX_PCI_PKTS_SENT2 CVMX_PCI_PKTS_SENTX(2)
+#define CVMX_PCI_PKTS_SENT3 CVMX_PCI_PKTS_SENTX(3)
+#define CVMX_PCI_PKTS_SENTX(offset) (0x0000000000000040ull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKTS_SENT_INT_LEV0 CVMX_PCI_PKTS_SENT_INT_LEVX(0)
+#define CVMX_PCI_PKTS_SENT_INT_LEV1 CVMX_PCI_PKTS_SENT_INT_LEVX(1)
+#define CVMX_PCI_PKTS_SENT_INT_LEV2 CVMX_PCI_PKTS_SENT_INT_LEVX(2)
+#define CVMX_PCI_PKTS_SENT_INT_LEV3 CVMX_PCI_PKTS_SENT_INT_LEVX(3)
+#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) (0x0000000000000048ull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKTS_SENT_TIME0 CVMX_PCI_PKTS_SENT_TIMEX(0)
+#define CVMX_PCI_PKTS_SENT_TIME1 CVMX_PCI_PKTS_SENT_TIMEX(1)
+#define CVMX_PCI_PKTS_SENT_TIME2 CVMX_PCI_PKTS_SENT_TIMEX(2)
+#define CVMX_PCI_PKTS_SENT_TIME3 CVMX_PCI_PKTS_SENT_TIMEX(3)
+#define CVMX_PCI_PKTS_SENT_TIMEX(offset) (0x000000000000004Cull + ((offset) & 3) * 16)
+#define CVMX_PCI_PKT_CREDITS0 CVMX_PCI_PKT_CREDITSX(0)
+#define CVMX_PCI_PKT_CREDITS1 CVMX_PCI_PKT_CREDITSX(1)
+#define CVMX_PCI_PKT_CREDITS2 CVMX_PCI_PKT_CREDITSX(2)
+#define CVMX_PCI_PKT_CREDITS3 CVMX_PCI_PKT_CREDITSX(3)
+#define CVMX_PCI_PKT_CREDITSX(offset) (0x0000000000000044ull + ((offset) & 3) * 16)
+#define CVMX_PCI_READ_CMD_6 (0x0000000000000180ull)
+#define CVMX_PCI_READ_CMD_C (0x0000000000000184ull)
+#define CVMX_PCI_READ_CMD_E (0x0000000000000188ull)
+#define CVMX_PCI_READ_TIMEOUT (CVMX_ADD_IO_SEG(0x00011F00000000B0ull))
+#define CVMX_PCI_SCM_REG (0x00000000000001A8ull)
+#define CVMX_PCI_TSR_REG (0x00000000000001B0ull)
+#define CVMX_PCI_WIN_RD_ADDR (0x0000000000000008ull)
+#define CVMX_PCI_WIN_RD_DATA (0x0000000000000020ull)
+#define CVMX_PCI_WIN_WR_ADDR (0x0000000000000000ull)
+#define CVMX_PCI_WIN_WR_DATA (0x0000000000000010ull)
+#define CVMX_PCI_WIN_WR_MASK (0x0000000000000018ull)
+
+union cvmx_pci_bar1_indexx {
+ uint32_t u32;
+ struct cvmx_pci_bar1_indexx_s {
+ uint32_t reserved_18_31:14;
+ uint32_t addr_idx:14;
+ uint32_t ca:1;
+ uint32_t end_swp:2;
+ uint32_t addr_v:1;
+ } s;
+ struct cvmx_pci_bar1_indexx_s cn30xx;
+ struct cvmx_pci_bar1_indexx_s cn31xx;
+ struct cvmx_pci_bar1_indexx_s cn38xx;
+ struct cvmx_pci_bar1_indexx_s cn38xxp2;
+ struct cvmx_pci_bar1_indexx_s cn50xx;
+ struct cvmx_pci_bar1_indexx_s cn58xx;
+ struct cvmx_pci_bar1_indexx_s cn58xxp1;
+};
+
+union cvmx_pci_bist_reg {
+ uint64_t u64;
+ struct cvmx_pci_bist_reg_s {
+ uint64_t reserved_10_63:54;
+ uint64_t rsp_bs:1;
+ uint64_t dma0_bs:1;
+ uint64_t cmd0_bs:1;
+ uint64_t cmd_bs:1;
+ uint64_t csr2p_bs:1;
+ uint64_t csrr_bs:1;
+ uint64_t rsp2p_bs:1;
+ uint64_t csr2n_bs:1;
+ uint64_t dat2n_bs:1;
+ uint64_t dbg2n_bs:1;
+ } s;
+ struct cvmx_pci_bist_reg_s cn50xx;
+};
+
+union cvmx_pci_cfg00 {
+ uint32_t u32;
+ struct cvmx_pci_cfg00_s {
+ uint32_t devid:16;
+ uint32_t vendid:16;
+ } s;
+ struct cvmx_pci_cfg00_s cn30xx;
+ struct cvmx_pci_cfg00_s cn31xx;
+ struct cvmx_pci_cfg00_s cn38xx;
+ struct cvmx_pci_cfg00_s cn38xxp2;
+ struct cvmx_pci_cfg00_s cn50xx;
+ struct cvmx_pci_cfg00_s cn58xx;
+ struct cvmx_pci_cfg00_s cn58xxp1;
+};
+
+union cvmx_pci_cfg01 {
+ uint32_t u32;
+ struct cvmx_pci_cfg01_s {
+ uint32_t dpe:1;
+ uint32_t sse:1;
+ uint32_t rma:1;
+ uint32_t rta:1;
+ uint32_t sta:1;
+ uint32_t devt:2;
+ uint32_t mdpe:1;
+ uint32_t fbb:1;
+ uint32_t reserved_22_22:1;
+ uint32_t m66:1;
+ uint32_t cle:1;
+ uint32_t i_stat:1;
+ uint32_t reserved_11_18:8;
+ uint32_t i_dis:1;
+ uint32_t fbbe:1;
+ uint32_t see:1;
+ uint32_t ads:1;
+ uint32_t pee:1;
+ uint32_t vps:1;
+ uint32_t mwice:1;
+ uint32_t scse:1;
+ uint32_t me:1;
+ uint32_t msae:1;
+ uint32_t isae:1;
+ } s;
+ struct cvmx_pci_cfg01_s cn30xx;
+ struct cvmx_pci_cfg01_s cn31xx;
+ struct cvmx_pci_cfg01_s cn38xx;
+ struct cvmx_pci_cfg01_s cn38xxp2;
+ struct cvmx_pci_cfg01_s cn50xx;
+ struct cvmx_pci_cfg01_s cn58xx;
+ struct cvmx_pci_cfg01_s cn58xxp1;
+};
+
+union cvmx_pci_cfg02 {
+ uint32_t u32;
+ struct cvmx_pci_cfg02_s {
+ uint32_t cc:24;
+ uint32_t rid:8;
+ } s;
+ struct cvmx_pci_cfg02_s cn30xx;
+ struct cvmx_pci_cfg02_s cn31xx;
+ struct cvmx_pci_cfg02_s cn38xx;
+ struct cvmx_pci_cfg02_s cn38xxp2;
+ struct cvmx_pci_cfg02_s cn50xx;
+ struct cvmx_pci_cfg02_s cn58xx;
+ struct cvmx_pci_cfg02_s cn58xxp1;
+};
+
+union cvmx_pci_cfg03 {
+ uint32_t u32;
+ struct cvmx_pci_cfg03_s {
+ uint32_t bcap:1;
+ uint32_t brb:1;
+ uint32_t reserved_28_29:2;
+ uint32_t bcod:4;
+ uint32_t ht:8;
+ uint32_t lt:8;
+ uint32_t cls:8;
+ } s;
+ struct cvmx_pci_cfg03_s cn30xx;
+ struct cvmx_pci_cfg03_s cn31xx;
+ struct cvmx_pci_cfg03_s cn38xx;
+ struct cvmx_pci_cfg03_s cn38xxp2;
+ struct cvmx_pci_cfg03_s cn50xx;
+ struct cvmx_pci_cfg03_s cn58xx;
+ struct cvmx_pci_cfg03_s cn58xxp1;
+};
+
+union cvmx_pci_cfg04 {
+ uint32_t u32;
+ struct cvmx_pci_cfg04_s {
+ uint32_t lbase:20;
+ uint32_t lbasez:8;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pci_cfg04_s cn30xx;
+ struct cvmx_pci_cfg04_s cn31xx;
+ struct cvmx_pci_cfg04_s cn38xx;
+ struct cvmx_pci_cfg04_s cn38xxp2;
+ struct cvmx_pci_cfg04_s cn50xx;
+ struct cvmx_pci_cfg04_s cn58xx;
+ struct cvmx_pci_cfg04_s cn58xxp1;
+};
+
+union cvmx_pci_cfg05 {
+ uint32_t u32;
+ struct cvmx_pci_cfg05_s {
+ uint32_t hbase:32;
+ } s;
+ struct cvmx_pci_cfg05_s cn30xx;
+ struct cvmx_pci_cfg05_s cn31xx;
+ struct cvmx_pci_cfg05_s cn38xx;
+ struct cvmx_pci_cfg05_s cn38xxp2;
+ struct cvmx_pci_cfg05_s cn50xx;
+ struct cvmx_pci_cfg05_s cn58xx;
+ struct cvmx_pci_cfg05_s cn58xxp1;
+};
+
+union cvmx_pci_cfg06 {
+ uint32_t u32;
+ struct cvmx_pci_cfg06_s {
+ uint32_t lbase:5;
+ uint32_t lbasez:23;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pci_cfg06_s cn30xx;
+ struct cvmx_pci_cfg06_s cn31xx;
+ struct cvmx_pci_cfg06_s cn38xx;
+ struct cvmx_pci_cfg06_s cn38xxp2;
+ struct cvmx_pci_cfg06_s cn50xx;
+ struct cvmx_pci_cfg06_s cn58xx;
+ struct cvmx_pci_cfg06_s cn58xxp1;
+};
+
+union cvmx_pci_cfg07 {
+ uint32_t u32;
+ struct cvmx_pci_cfg07_s {
+ uint32_t hbase:32;
+ } s;
+ struct cvmx_pci_cfg07_s cn30xx;
+ struct cvmx_pci_cfg07_s cn31xx;
+ struct cvmx_pci_cfg07_s cn38xx;
+ struct cvmx_pci_cfg07_s cn38xxp2;
+ struct cvmx_pci_cfg07_s cn50xx;
+ struct cvmx_pci_cfg07_s cn58xx;
+ struct cvmx_pci_cfg07_s cn58xxp1;
+};
+
+union cvmx_pci_cfg08 {
+ uint32_t u32;
+ struct cvmx_pci_cfg08_s {
+ uint32_t lbasez:28;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pci_cfg08_s cn30xx;
+ struct cvmx_pci_cfg08_s cn31xx;
+ struct cvmx_pci_cfg08_s cn38xx;
+ struct cvmx_pci_cfg08_s cn38xxp2;
+ struct cvmx_pci_cfg08_s cn50xx;
+ struct cvmx_pci_cfg08_s cn58xx;
+ struct cvmx_pci_cfg08_s cn58xxp1;
+};
+
+union cvmx_pci_cfg09 {
+ uint32_t u32;
+ struct cvmx_pci_cfg09_s {
+ uint32_t hbase:25;
+ uint32_t hbasez:7;
+ } s;
+ struct cvmx_pci_cfg09_s cn30xx;
+ struct cvmx_pci_cfg09_s cn31xx;
+ struct cvmx_pci_cfg09_s cn38xx;
+ struct cvmx_pci_cfg09_s cn38xxp2;
+ struct cvmx_pci_cfg09_s cn50xx;
+ struct cvmx_pci_cfg09_s cn58xx;
+ struct cvmx_pci_cfg09_s cn58xxp1;
+};
+
+union cvmx_pci_cfg10 {
+ uint32_t u32;
+ struct cvmx_pci_cfg10_s {
+ uint32_t cisp:32;
+ } s;
+ struct cvmx_pci_cfg10_s cn30xx;
+ struct cvmx_pci_cfg10_s cn31xx;
+ struct cvmx_pci_cfg10_s cn38xx;
+ struct cvmx_pci_cfg10_s cn38xxp2;
+ struct cvmx_pci_cfg10_s cn50xx;
+ struct cvmx_pci_cfg10_s cn58xx;
+ struct cvmx_pci_cfg10_s cn58xxp1;
+};
+
+union cvmx_pci_cfg11 {
+ uint32_t u32;
+ struct cvmx_pci_cfg11_s {
+ uint32_t ssid:16;
+ uint32_t ssvid:16;
+ } s;
+ struct cvmx_pci_cfg11_s cn30xx;
+ struct cvmx_pci_cfg11_s cn31xx;
+ struct cvmx_pci_cfg11_s cn38xx;
+ struct cvmx_pci_cfg11_s cn38xxp2;
+ struct cvmx_pci_cfg11_s cn50xx;
+ struct cvmx_pci_cfg11_s cn58xx;
+ struct cvmx_pci_cfg11_s cn58xxp1;
+};
+
+union cvmx_pci_cfg12 {
+ uint32_t u32;
+ struct cvmx_pci_cfg12_s {
+ uint32_t erbar:16;
+ uint32_t erbarz:5;
+ uint32_t reserved_1_10:10;
+ uint32_t erbar_en:1;
+ } s;
+ struct cvmx_pci_cfg12_s cn30xx;
+ struct cvmx_pci_cfg12_s cn31xx;
+ struct cvmx_pci_cfg12_s cn38xx;
+ struct cvmx_pci_cfg12_s cn38xxp2;
+ struct cvmx_pci_cfg12_s cn50xx;
+ struct cvmx_pci_cfg12_s cn58xx;
+ struct cvmx_pci_cfg12_s cn58xxp1;
+};
+
+union cvmx_pci_cfg13 {
+ uint32_t u32;
+ struct cvmx_pci_cfg13_s {
+ uint32_t reserved_8_31:24;
+ uint32_t cp:8;
+ } s;
+ struct cvmx_pci_cfg13_s cn30xx;
+ struct cvmx_pci_cfg13_s cn31xx;
+ struct cvmx_pci_cfg13_s cn38xx;
+ struct cvmx_pci_cfg13_s cn38xxp2;
+ struct cvmx_pci_cfg13_s cn50xx;
+ struct cvmx_pci_cfg13_s cn58xx;
+ struct cvmx_pci_cfg13_s cn58xxp1;
+};
+
+union cvmx_pci_cfg15 {
+ uint32_t u32;
+ struct cvmx_pci_cfg15_s {
+ uint32_t ml:8;
+ uint32_t mg:8;
+ uint32_t inta:8;
+ uint32_t il:8;
+ } s;
+ struct cvmx_pci_cfg15_s cn30xx;
+ struct cvmx_pci_cfg15_s cn31xx;
+ struct cvmx_pci_cfg15_s cn38xx;
+ struct cvmx_pci_cfg15_s cn38xxp2;
+ struct cvmx_pci_cfg15_s cn50xx;
+ struct cvmx_pci_cfg15_s cn58xx;
+ struct cvmx_pci_cfg15_s cn58xxp1;
+};
+
+union cvmx_pci_cfg16 {
+ uint32_t u32;
+ struct cvmx_pci_cfg16_s {
+ uint32_t trdnpr:1;
+ uint32_t trdard:1;
+ uint32_t rdsati:1;
+ uint32_t trdrs:1;
+ uint32_t trtae:1;
+ uint32_t twsei:1;
+ uint32_t twsen:1;
+ uint32_t twtae:1;
+ uint32_t tmae:1;
+ uint32_t tslte:3;
+ uint32_t tilt:4;
+ uint32_t pbe:12;
+ uint32_t dppmr:1;
+ uint32_t reserved_2_2:1;
+ uint32_t tswc:1;
+ uint32_t mltd:1;
+ } s;
+ struct cvmx_pci_cfg16_s cn30xx;
+ struct cvmx_pci_cfg16_s cn31xx;
+ struct cvmx_pci_cfg16_s cn38xx;
+ struct cvmx_pci_cfg16_s cn38xxp2;
+ struct cvmx_pci_cfg16_s cn50xx;
+ struct cvmx_pci_cfg16_s cn58xx;
+ struct cvmx_pci_cfg16_s cn58xxp1;
+};
+
+union cvmx_pci_cfg17 {
+ uint32_t u32;
+ struct cvmx_pci_cfg17_s {
+ uint32_t tscme:32;
+ } s;
+ struct cvmx_pci_cfg17_s cn30xx;
+ struct cvmx_pci_cfg17_s cn31xx;
+ struct cvmx_pci_cfg17_s cn38xx;
+ struct cvmx_pci_cfg17_s cn38xxp2;
+ struct cvmx_pci_cfg17_s cn50xx;
+ struct cvmx_pci_cfg17_s cn58xx;
+ struct cvmx_pci_cfg17_s cn58xxp1;
+};
+
+union cvmx_pci_cfg18 {
+ uint32_t u32;
+ struct cvmx_pci_cfg18_s {
+ uint32_t tdsrps:32;
+ } s;
+ struct cvmx_pci_cfg18_s cn30xx;
+ struct cvmx_pci_cfg18_s cn31xx;
+ struct cvmx_pci_cfg18_s cn38xx;
+ struct cvmx_pci_cfg18_s cn38xxp2;
+ struct cvmx_pci_cfg18_s cn50xx;
+ struct cvmx_pci_cfg18_s cn58xx;
+ struct cvmx_pci_cfg18_s cn58xxp1;
+};
+
+union cvmx_pci_cfg19 {
+ uint32_t u32;
+ struct cvmx_pci_cfg19_s {
+ uint32_t mrbcm:1;
+ uint32_t mrbci:1;
+ uint32_t mdwe:1;
+ uint32_t mdre:1;
+ uint32_t mdrimc:1;
+ uint32_t mdrrmc:3;
+ uint32_t tmes:8;
+ uint32_t teci:1;
+ uint32_t tmei:1;
+ uint32_t tmse:1;
+ uint32_t tmdpes:1;
+ uint32_t tmapes:1;
+ uint32_t reserved_9_10:2;
+ uint32_t tibcd:1;
+ uint32_t tibde:1;
+ uint32_t reserved_6_6:1;
+ uint32_t tidomc:1;
+ uint32_t tdomc:5;
+ } s;
+ struct cvmx_pci_cfg19_s cn30xx;
+ struct cvmx_pci_cfg19_s cn31xx;
+ struct cvmx_pci_cfg19_s cn38xx;
+ struct cvmx_pci_cfg19_s cn38xxp2;
+ struct cvmx_pci_cfg19_s cn50xx;
+ struct cvmx_pci_cfg19_s cn58xx;
+ struct cvmx_pci_cfg19_s cn58xxp1;
+};
+
+union cvmx_pci_cfg20 {
+ uint32_t u32;
+ struct cvmx_pci_cfg20_s {
+ uint32_t mdsp:32;
+ } s;
+ struct cvmx_pci_cfg20_s cn30xx;
+ struct cvmx_pci_cfg20_s cn31xx;
+ struct cvmx_pci_cfg20_s cn38xx;
+ struct cvmx_pci_cfg20_s cn38xxp2;
+ struct cvmx_pci_cfg20_s cn50xx;
+ struct cvmx_pci_cfg20_s cn58xx;
+ struct cvmx_pci_cfg20_s cn58xxp1;
+};
+
+union cvmx_pci_cfg21 {
+ uint32_t u32;
+ struct cvmx_pci_cfg21_s {
+ uint32_t scmre:32;
+ } s;
+ struct cvmx_pci_cfg21_s cn30xx;
+ struct cvmx_pci_cfg21_s cn31xx;
+ struct cvmx_pci_cfg21_s cn38xx;
+ struct cvmx_pci_cfg21_s cn38xxp2;
+ struct cvmx_pci_cfg21_s cn50xx;
+ struct cvmx_pci_cfg21_s cn58xx;
+ struct cvmx_pci_cfg21_s cn58xxp1;
+};
+
+union cvmx_pci_cfg22 {
+ uint32_t u32;
+ struct cvmx_pci_cfg22_s {
+ uint32_t mac:7;
+ uint32_t reserved_19_24:6;
+ uint32_t flush:1;
+ uint32_t mra:1;
+ uint32_t mtta:1;
+ uint32_t mrv:8;
+ uint32_t mttv:8;
+ } s;
+ struct cvmx_pci_cfg22_s cn30xx;
+ struct cvmx_pci_cfg22_s cn31xx;
+ struct cvmx_pci_cfg22_s cn38xx;
+ struct cvmx_pci_cfg22_s cn38xxp2;
+ struct cvmx_pci_cfg22_s cn50xx;
+ struct cvmx_pci_cfg22_s cn58xx;
+ struct cvmx_pci_cfg22_s cn58xxp1;
+};
+
+union cvmx_pci_cfg56 {
+ uint32_t u32;
+ struct cvmx_pci_cfg56_s {
+ uint32_t reserved_23_31:9;
+ uint32_t most:3;
+ uint32_t mmbc:2;
+ uint32_t roe:1;
+ uint32_t dpere:1;
+ uint32_t ncp:8;
+ uint32_t pxcid:8;
+ } s;
+ struct cvmx_pci_cfg56_s cn30xx;
+ struct cvmx_pci_cfg56_s cn31xx;
+ struct cvmx_pci_cfg56_s cn38xx;
+ struct cvmx_pci_cfg56_s cn38xxp2;
+ struct cvmx_pci_cfg56_s cn50xx;
+ struct cvmx_pci_cfg56_s cn58xx;
+ struct cvmx_pci_cfg56_s cn58xxp1;
+};
+
+union cvmx_pci_cfg57 {
+ uint32_t u32;
+ struct cvmx_pci_cfg57_s {
+ uint32_t reserved_30_31:2;
+ uint32_t scemr:1;
+ uint32_t mcrsd:3;
+ uint32_t mostd:3;
+ uint32_t mmrbcd:2;
+ uint32_t dc:1;
+ uint32_t usc:1;
+ uint32_t scd:1;
+ uint32_t m133:1;
+ uint32_t w64:1;
+ uint32_t bn:8;
+ uint32_t dn:5;
+ uint32_t fn:3;
+ } s;
+ struct cvmx_pci_cfg57_s cn30xx;
+ struct cvmx_pci_cfg57_s cn31xx;
+ struct cvmx_pci_cfg57_s cn38xx;
+ struct cvmx_pci_cfg57_s cn38xxp2;
+ struct cvmx_pci_cfg57_s cn50xx;
+ struct cvmx_pci_cfg57_s cn58xx;
+ struct cvmx_pci_cfg57_s cn58xxp1;
+};
+
+union cvmx_pci_cfg58 {
+ uint32_t u32;
+ struct cvmx_pci_cfg58_s {
+ uint32_t pmes:5;
+ uint32_t d2s:1;
+ uint32_t d1s:1;
+ uint32_t auxc:3;
+ uint32_t dsi:1;
+ uint32_t reserved_20_20:1;
+ uint32_t pmec:1;
+ uint32_t pcimiv:3;
+ uint32_t ncp:8;
+ uint32_t pmcid:8;
+ } s;
+ struct cvmx_pci_cfg58_s cn30xx;
+ struct cvmx_pci_cfg58_s cn31xx;
+ struct cvmx_pci_cfg58_s cn38xx;
+ struct cvmx_pci_cfg58_s cn38xxp2;
+ struct cvmx_pci_cfg58_s cn50xx;
+ struct cvmx_pci_cfg58_s cn58xx;
+ struct cvmx_pci_cfg58_s cn58xxp1;
+};
+
+union cvmx_pci_cfg59 {
+ uint32_t u32;
+ struct cvmx_pci_cfg59_s {
+ uint32_t pmdia:8;
+ uint32_t bpccen:1;
+ uint32_t bd3h:1;
+ uint32_t reserved_16_21:6;
+ uint32_t pmess:1;
+ uint32_t pmedsia:2;
+ uint32_t pmds:4;
+ uint32_t pmeens:1;
+ uint32_t reserved_2_7:6;
+ uint32_t ps:2;
+ } s;
+ struct cvmx_pci_cfg59_s cn30xx;
+ struct cvmx_pci_cfg59_s cn31xx;
+ struct cvmx_pci_cfg59_s cn38xx;
+ struct cvmx_pci_cfg59_s cn38xxp2;
+ struct cvmx_pci_cfg59_s cn50xx;
+ struct cvmx_pci_cfg59_s cn58xx;
+ struct cvmx_pci_cfg59_s cn58xxp1;
+};
+
+union cvmx_pci_cfg60 {
+ uint32_t u32;
+ struct cvmx_pci_cfg60_s {
+ uint32_t reserved_24_31:8;
+ uint32_t m64:1;
+ uint32_t mme:3;
+ uint32_t mmc:3;
+ uint32_t msien:1;
+ uint32_t ncp:8;
+ uint32_t msicid:8;
+ } s;
+ struct cvmx_pci_cfg60_s cn30xx;
+ struct cvmx_pci_cfg60_s cn31xx;
+ struct cvmx_pci_cfg60_s cn38xx;
+ struct cvmx_pci_cfg60_s cn38xxp2;
+ struct cvmx_pci_cfg60_s cn50xx;
+ struct cvmx_pci_cfg60_s cn58xx;
+ struct cvmx_pci_cfg60_s cn58xxp1;
+};
+
+union cvmx_pci_cfg61 {
+ uint32_t u32;
+ struct cvmx_pci_cfg61_s {
+ uint32_t msi31t2:30;
+ uint32_t reserved_0_1:2;
+ } s;
+ struct cvmx_pci_cfg61_s cn30xx;
+ struct cvmx_pci_cfg61_s cn31xx;
+ struct cvmx_pci_cfg61_s cn38xx;
+ struct cvmx_pci_cfg61_s cn38xxp2;
+ struct cvmx_pci_cfg61_s cn50xx;
+ struct cvmx_pci_cfg61_s cn58xx;
+ struct cvmx_pci_cfg61_s cn58xxp1;
+};
+
+union cvmx_pci_cfg62 {
+ uint32_t u32;
+ struct cvmx_pci_cfg62_s {
+ uint32_t msi:32;
+ } s;
+ struct cvmx_pci_cfg62_s cn30xx;
+ struct cvmx_pci_cfg62_s cn31xx;
+ struct cvmx_pci_cfg62_s cn38xx;
+ struct cvmx_pci_cfg62_s cn38xxp2;
+ struct cvmx_pci_cfg62_s cn50xx;
+ struct cvmx_pci_cfg62_s cn58xx;
+ struct cvmx_pci_cfg62_s cn58xxp1;
+};
+
+union cvmx_pci_cfg63 {
+ uint32_t u32;
+ struct cvmx_pci_cfg63_s {
+ uint32_t reserved_16_31:16;
+ uint32_t msimd:16;
+ } s;
+ struct cvmx_pci_cfg63_s cn30xx;
+ struct cvmx_pci_cfg63_s cn31xx;
+ struct cvmx_pci_cfg63_s cn38xx;
+ struct cvmx_pci_cfg63_s cn38xxp2;
+ struct cvmx_pci_cfg63_s cn50xx;
+ struct cvmx_pci_cfg63_s cn58xx;
+ struct cvmx_pci_cfg63_s cn58xxp1;
+};
+
+union cvmx_pci_cnt_reg {
+ uint64_t u64;
+ struct cvmx_pci_cnt_reg_s {
+ uint64_t reserved_38_63:26;
+ uint64_t hm_pcix:1;
+ uint64_t hm_speed:2;
+ uint64_t ap_pcix:1;
+ uint64_t ap_speed:2;
+ uint64_t pcicnt:32;
+ } s;
+ struct cvmx_pci_cnt_reg_s cn50xx;
+ struct cvmx_pci_cnt_reg_s cn58xx;
+ struct cvmx_pci_cnt_reg_s cn58xxp1;
+};
+
+union cvmx_pci_ctl_status_2 {
+ uint32_t u32;
+ struct cvmx_pci_ctl_status_2_s {
+ uint32_t reserved_29_31:3;
+ uint32_t bb1_hole:3;
+ uint32_t bb1_siz:1;
+ uint32_t bb_ca:1;
+ uint32_t bb_es:2;
+ uint32_t bb1:1;
+ uint32_t bb0:1;
+ uint32_t erst_n:1;
+ uint32_t bar2pres:1;
+ uint32_t scmtyp:1;
+ uint32_t scm:1;
+ uint32_t en_wfilt:1;
+ uint32_t reserved_14_14:1;
+ uint32_t ap_pcix:1;
+ uint32_t ap_64ad:1;
+ uint32_t b12_bist:1;
+ uint32_t pmo_amod:1;
+ uint32_t pmo_fpc:3;
+ uint32_t tsr_hwm:3;
+ uint32_t bar2_enb:1;
+ uint32_t bar2_esx:2;
+ uint32_t bar2_cax:1;
+ } s;
+ struct cvmx_pci_ctl_status_2_s cn30xx;
+ struct cvmx_pci_ctl_status_2_cn31xx {
+ uint32_t reserved_20_31:12;
+ uint32_t erst_n:1;
+ uint32_t bar2pres:1;
+ uint32_t scmtyp:1;
+ uint32_t scm:1;
+ uint32_t en_wfilt:1;
+ uint32_t reserved_14_14:1;
+ uint32_t ap_pcix:1;
+ uint32_t ap_64ad:1;
+ uint32_t b12_bist:1;
+ uint32_t pmo_amod:1;
+ uint32_t pmo_fpc:3;
+ uint32_t tsr_hwm:3;
+ uint32_t bar2_enb:1;
+ uint32_t bar2_esx:2;
+ uint32_t bar2_cax:1;
+ } cn31xx;
+ struct cvmx_pci_ctl_status_2_s cn38xx;
+ struct cvmx_pci_ctl_status_2_cn31xx cn38xxp2;
+ struct cvmx_pci_ctl_status_2_s cn50xx;
+ struct cvmx_pci_ctl_status_2_s cn58xx;
+ struct cvmx_pci_ctl_status_2_s cn58xxp1;
+};
+
+union cvmx_pci_dbellx {
+ uint32_t u32;
+ struct cvmx_pci_dbellx_s {
+ uint32_t reserved_16_31:16;
+ uint32_t inc_val:16;
+ } s;
+ struct cvmx_pci_dbellx_s cn30xx;
+ struct cvmx_pci_dbellx_s cn31xx;
+ struct cvmx_pci_dbellx_s cn38xx;
+ struct cvmx_pci_dbellx_s cn38xxp2;
+ struct cvmx_pci_dbellx_s cn50xx;
+ struct cvmx_pci_dbellx_s cn58xx;
+ struct cvmx_pci_dbellx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_cntx {
+ uint32_t u32;
+ struct cvmx_pci_dma_cntx_s {
+ uint32_t dma_cnt:32;
+ } s;
+ struct cvmx_pci_dma_cntx_s cn30xx;
+ struct cvmx_pci_dma_cntx_s cn31xx;
+ struct cvmx_pci_dma_cntx_s cn38xx;
+ struct cvmx_pci_dma_cntx_s cn38xxp2;
+ struct cvmx_pci_dma_cntx_s cn50xx;
+ struct cvmx_pci_dma_cntx_s cn58xx;
+ struct cvmx_pci_dma_cntx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_int_levx {
+ uint32_t u32;
+ struct cvmx_pci_dma_int_levx_s {
+ uint32_t pkt_cnt:32;
+ } s;
+ struct cvmx_pci_dma_int_levx_s cn30xx;
+ struct cvmx_pci_dma_int_levx_s cn31xx;
+ struct cvmx_pci_dma_int_levx_s cn38xx;
+ struct cvmx_pci_dma_int_levx_s cn38xxp2;
+ struct cvmx_pci_dma_int_levx_s cn50xx;
+ struct cvmx_pci_dma_int_levx_s cn58xx;
+ struct cvmx_pci_dma_int_levx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_timex {
+ uint32_t u32;
+ struct cvmx_pci_dma_timex_s {
+ uint32_t dma_time:32;
+ } s;
+ struct cvmx_pci_dma_timex_s cn30xx;
+ struct cvmx_pci_dma_timex_s cn31xx;
+ struct cvmx_pci_dma_timex_s cn38xx;
+ struct cvmx_pci_dma_timex_s cn38xxp2;
+ struct cvmx_pci_dma_timex_s cn50xx;
+ struct cvmx_pci_dma_timex_s cn58xx;
+ struct cvmx_pci_dma_timex_s cn58xxp1;
+};
+
+union cvmx_pci_instr_countx {
+ uint32_t u32;
+ struct cvmx_pci_instr_countx_s {
+ uint32_t icnt:32;
+ } s;
+ struct cvmx_pci_instr_countx_s cn30xx;
+ struct cvmx_pci_instr_countx_s cn31xx;
+ struct cvmx_pci_instr_countx_s cn38xx;
+ struct cvmx_pci_instr_countx_s cn38xxp2;
+ struct cvmx_pci_instr_countx_s cn50xx;
+ struct cvmx_pci_instr_countx_s cn58xx;
+ struct cvmx_pci_instr_countx_s cn58xxp1;
+};
+
+union cvmx_pci_int_enb {
+ uint64_t u64;
+ struct cvmx_pci_int_enb_s {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t idtime1:1;
+ uint64_t idtime0:1;
+ uint64_t idcnt1:1;
+ uint64_t idcnt0:1;
+ uint64_t iptime3:1;
+ uint64_t iptime2:1;
+ uint64_t iptime1:1;
+ uint64_t iptime0:1;
+ uint64_t ipcnt3:1;
+ uint64_t ipcnt2:1;
+ uint64_t ipcnt1:1;
+ uint64_t ipcnt0:1;
+ uint64_t irsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t idperr:1;
+ uint64_t iaperr:1;
+ uint64_t iserr:1;
+ uint64_t itsr_abt:1;
+ uint64_t imsc_msg:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_per:1;
+ uint64_t imr_tto:1;
+ uint64_t imr_abt:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_wtto:1;
+ uint64_t imr_wabt:1;
+ uint64_t itr_wabt:1;
+ } s;
+ struct cvmx_pci_int_enb_cn30xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t idtime1:1;
+ uint64_t idtime0:1;
+ uint64_t idcnt1:1;
+ uint64_t idcnt0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t iptime0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t ipcnt0:1;
+ uint64_t irsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t idperr:1;
+ uint64_t iaperr:1;
+ uint64_t iserr:1;
+ uint64_t itsr_abt:1;
+ uint64_t imsc_msg:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_per:1;
+ uint64_t imr_tto:1;
+ uint64_t imr_abt:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_wtto:1;
+ uint64_t imr_wabt:1;
+ uint64_t itr_wabt:1;
+ } cn30xx;
+ struct cvmx_pci_int_enb_cn31xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t idtime1:1;
+ uint64_t idtime0:1;
+ uint64_t idcnt1:1;
+ uint64_t idcnt0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t iptime1:1;
+ uint64_t iptime0:1;
+ uint64_t reserved_19_20:2;
+ uint64_t ipcnt1:1;
+ uint64_t ipcnt0:1;
+ uint64_t irsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t idperr:1;
+ uint64_t iaperr:1;
+ uint64_t iserr:1;
+ uint64_t itsr_abt:1;
+ uint64_t imsc_msg:1;
+ uint64_t imsi_mabt:1;
+ uint64_t imsi_tabt:1;
+ uint64_t imsi_per:1;
+ uint64_t imr_tto:1;
+ uint64_t imr_abt:1;
+ uint64_t itr_abt:1;
+ uint64_t imr_wtto:1;
+ uint64_t imr_wabt:1;
+ uint64_t itr_wabt:1;
+ } cn31xx;
+ struct cvmx_pci_int_enb_s cn38xx;
+ struct cvmx_pci_int_enb_s cn38xxp2;
+ struct cvmx_pci_int_enb_cn31xx cn50xx;
+ struct cvmx_pci_int_enb_s cn58xx;
+ struct cvmx_pci_int_enb_s cn58xxp1;
+};
+
+union cvmx_pci_int_enb2 {
+ uint64_t u64;
+ struct cvmx_pci_int_enb2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t rdtime1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdcnt0:1;
+ uint64_t rptime3:1;
+ uint64_t rptime2:1;
+ uint64_t rptime1:1;
+ uint64_t rptime0:1;
+ uint64_t rpcnt3:1;
+ uint64_t rpcnt2:1;
+ uint64_t rpcnt1:1;
+ uint64_t rpcnt0:1;
+ uint64_t rrsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t rdperr:1;
+ uint64_t raperr:1;
+ uint64_t rserr:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmr_abt:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rtr_wabt:1;
+ } s;
+ struct cvmx_pci_int_enb2_cn30xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t rdtime1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdcnt0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t rptime0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t rpcnt0:1;
+ uint64_t rrsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t rdperr:1;
+ uint64_t raperr:1;
+ uint64_t rserr:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmr_abt:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rtr_wabt:1;
+ } cn30xx;
+ struct cvmx_pci_int_enb2_cn31xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t rdtime1:1;
+ uint64_t rdtime0:1;
+ uint64_t rdcnt1:1;
+ uint64_t rdcnt0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t rptime1:1;
+ uint64_t rptime0:1;
+ uint64_t reserved_19_20:2;
+ uint64_t rpcnt1:1;
+ uint64_t rpcnt0:1;
+ uint64_t rrsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t rdperr:1;
+ uint64_t raperr:1;
+ uint64_t rserr:1;
+ uint64_t rtsr_abt:1;
+ uint64_t rmsc_msg:1;
+ uint64_t rmsi_mabt:1;
+ uint64_t rmsi_tabt:1;
+ uint64_t rmsi_per:1;
+ uint64_t rmr_tto:1;
+ uint64_t rmr_abt:1;
+ uint64_t rtr_abt:1;
+ uint64_t rmr_wtto:1;
+ uint64_t rmr_wabt:1;
+ uint64_t rtr_wabt:1;
+ } cn31xx;
+ struct cvmx_pci_int_enb2_s cn38xx;
+ struct cvmx_pci_int_enb2_s cn38xxp2;
+ struct cvmx_pci_int_enb2_cn31xx cn50xx;
+ struct cvmx_pci_int_enb2_s cn58xx;
+ struct cvmx_pci_int_enb2_s cn58xxp1;
+};
+
+union cvmx_pci_int_sum {
+ uint64_t u64;
+ struct cvmx_pci_int_sum_s {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t ptime3:1;
+ uint64_t ptime2:1;
+ uint64_t ptime1:1;
+ uint64_t ptime0:1;
+ uint64_t pcnt3:1;
+ uint64_t pcnt2:1;
+ uint64_t pcnt1:1;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } s;
+ struct cvmx_pci_int_sum_cn30xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t ptime0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } cn30xx;
+ struct cvmx_pci_int_sum_cn31xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t ptime1:1;
+ uint64_t ptime0:1;
+ uint64_t reserved_19_20:2;
+ uint64_t pcnt1:1;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } cn31xx;
+ struct cvmx_pci_int_sum_s cn38xx;
+ struct cvmx_pci_int_sum_s cn38xxp2;
+ struct cvmx_pci_int_sum_cn31xx cn50xx;
+ struct cvmx_pci_int_sum_s cn58xx;
+ struct cvmx_pci_int_sum_s cn58xxp1;
+};
+
+union cvmx_pci_int_sum2 {
+ uint64_t u64;
+ struct cvmx_pci_int_sum2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t ptime3:1;
+ uint64_t ptime2:1;
+ uint64_t ptime1:1;
+ uint64_t ptime0:1;
+ uint64_t pcnt3:1;
+ uint64_t pcnt2:1;
+ uint64_t pcnt1:1;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } s;
+ struct cvmx_pci_int_sum2_cn30xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t reserved_22_24:3;
+ uint64_t ptime0:1;
+ uint64_t reserved_18_20:3;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } cn30xx;
+ struct cvmx_pci_int_sum2_cn31xx {
+ uint64_t reserved_34_63:30;
+ uint64_t ill_rd:1;
+ uint64_t ill_wr:1;
+ uint64_t win_wr:1;
+ uint64_t dma1_fi:1;
+ uint64_t dma0_fi:1;
+ uint64_t dtime1:1;
+ uint64_t dtime0:1;
+ uint64_t dcnt1:1;
+ uint64_t dcnt0:1;
+ uint64_t reserved_23_24:2;
+ uint64_t ptime1:1;
+ uint64_t ptime0:1;
+ uint64_t reserved_19_20:2;
+ uint64_t pcnt1:1;
+ uint64_t pcnt0:1;
+ uint64_t rsl_int:1;
+ uint64_t ill_rrd:1;
+ uint64_t ill_rwr:1;
+ uint64_t dperr:1;
+ uint64_t aperr:1;
+ uint64_t serr:1;
+ uint64_t tsr_abt:1;
+ uint64_t msc_msg:1;
+ uint64_t msi_mabt:1;
+ uint64_t msi_tabt:1;
+ uint64_t msi_per:1;
+ uint64_t mr_tto:1;
+ uint64_t mr_abt:1;
+ uint64_t tr_abt:1;
+ uint64_t mr_wtto:1;
+ uint64_t mr_wabt:1;
+ uint64_t tr_wabt:1;
+ } cn31xx;
+ struct cvmx_pci_int_sum2_s cn38xx;
+ struct cvmx_pci_int_sum2_s cn38xxp2;
+ struct cvmx_pci_int_sum2_cn31xx cn50xx;
+ struct cvmx_pci_int_sum2_s cn58xx;
+ struct cvmx_pci_int_sum2_s cn58xxp1;
+};
+
+union cvmx_pci_msi_rcv {
+ uint32_t u32;
+ struct cvmx_pci_msi_rcv_s {
+ uint32_t reserved_6_31:26;
+ uint32_t intr:6;
+ } s;
+ struct cvmx_pci_msi_rcv_s cn30xx;
+ struct cvmx_pci_msi_rcv_s cn31xx;
+ struct cvmx_pci_msi_rcv_s cn38xx;
+ struct cvmx_pci_msi_rcv_s cn38xxp2;
+ struct cvmx_pci_msi_rcv_s cn50xx;
+ struct cvmx_pci_msi_rcv_s cn58xx;
+ struct cvmx_pci_msi_rcv_s cn58xxp1;
+};
+
+union cvmx_pci_pkt_creditsx {
+ uint32_t u32;
+ struct cvmx_pci_pkt_creditsx_s {
+ uint32_t pkt_cnt:16;
+ uint32_t ptr_cnt:16;
+ } s;
+ struct cvmx_pci_pkt_creditsx_s cn30xx;
+ struct cvmx_pci_pkt_creditsx_s cn31xx;
+ struct cvmx_pci_pkt_creditsx_s cn38xx;
+ struct cvmx_pci_pkt_creditsx_s cn38xxp2;
+ struct cvmx_pci_pkt_creditsx_s cn50xx;
+ struct cvmx_pci_pkt_creditsx_s cn58xx;
+ struct cvmx_pci_pkt_creditsx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sentx {
+ uint32_t u32;
+ struct cvmx_pci_pkts_sentx_s {
+ uint32_t pkt_cnt:32;
+ } s;
+ struct cvmx_pci_pkts_sentx_s cn30xx;
+ struct cvmx_pci_pkts_sentx_s cn31xx;
+ struct cvmx_pci_pkts_sentx_s cn38xx;
+ struct cvmx_pci_pkts_sentx_s cn38xxp2;
+ struct cvmx_pci_pkts_sentx_s cn50xx;
+ struct cvmx_pci_pkts_sentx_s cn58xx;
+ struct cvmx_pci_pkts_sentx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sent_int_levx {
+ uint32_t u32;
+ struct cvmx_pci_pkts_sent_int_levx_s {
+ uint32_t pkt_cnt:32;
+ } s;
+ struct cvmx_pci_pkts_sent_int_levx_s cn30xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn31xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn38xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn38xxp2;
+ struct cvmx_pci_pkts_sent_int_levx_s cn50xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn58xx;
+ struct cvmx_pci_pkts_sent_int_levx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sent_timex {
+ uint32_t u32;
+ struct cvmx_pci_pkts_sent_timex_s {
+ uint32_t pkt_time:32;
+ } s;
+ struct cvmx_pci_pkts_sent_timex_s cn30xx;
+ struct cvmx_pci_pkts_sent_timex_s cn31xx;
+ struct cvmx_pci_pkts_sent_timex_s cn38xx;
+ struct cvmx_pci_pkts_sent_timex_s cn38xxp2;
+ struct cvmx_pci_pkts_sent_timex_s cn50xx;
+ struct cvmx_pci_pkts_sent_timex_s cn58xx;
+ struct cvmx_pci_pkts_sent_timex_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_6 {
+ uint32_t u32;
+ struct cvmx_pci_read_cmd_6_s {
+ uint32_t reserved_9_31:23;
+ uint32_t min_data:6;
+ uint32_t prefetch:3;
+ } s;
+ struct cvmx_pci_read_cmd_6_s cn30xx;
+ struct cvmx_pci_read_cmd_6_s cn31xx;
+ struct cvmx_pci_read_cmd_6_s cn38xx;
+ struct cvmx_pci_read_cmd_6_s cn38xxp2;
+ struct cvmx_pci_read_cmd_6_s cn50xx;
+ struct cvmx_pci_read_cmd_6_s cn58xx;
+ struct cvmx_pci_read_cmd_6_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_c {
+ uint32_t u32;
+ struct cvmx_pci_read_cmd_c_s {
+ uint32_t reserved_9_31:23;
+ uint32_t min_data:6;
+ uint32_t prefetch:3;
+ } s;
+ struct cvmx_pci_read_cmd_c_s cn30xx;
+ struct cvmx_pci_read_cmd_c_s cn31xx;
+ struct cvmx_pci_read_cmd_c_s cn38xx;
+ struct cvmx_pci_read_cmd_c_s cn38xxp2;
+ struct cvmx_pci_read_cmd_c_s cn50xx;
+ struct cvmx_pci_read_cmd_c_s cn58xx;
+ struct cvmx_pci_read_cmd_c_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_e {
+ uint32_t u32;
+ struct cvmx_pci_read_cmd_e_s {
+ uint32_t reserved_9_31:23;
+ uint32_t min_data:6;
+ uint32_t prefetch:3;
+ } s;
+ struct cvmx_pci_read_cmd_e_s cn30xx;
+ struct cvmx_pci_read_cmd_e_s cn31xx;
+ struct cvmx_pci_read_cmd_e_s cn38xx;
+ struct cvmx_pci_read_cmd_e_s cn38xxp2;
+ struct cvmx_pci_read_cmd_e_s cn50xx;
+ struct cvmx_pci_read_cmd_e_s cn58xx;
+ struct cvmx_pci_read_cmd_e_s cn58xxp1;
+};
+
+union cvmx_pci_read_timeout {
+ uint64_t u64;
+ struct cvmx_pci_read_timeout_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enb:1;
+ uint64_t cnt:31;
+ } s;
+ struct cvmx_pci_read_timeout_s cn30xx;
+ struct cvmx_pci_read_timeout_s cn31xx;
+ struct cvmx_pci_read_timeout_s cn38xx;
+ struct cvmx_pci_read_timeout_s cn38xxp2;
+ struct cvmx_pci_read_timeout_s cn50xx;
+ struct cvmx_pci_read_timeout_s cn58xx;
+ struct cvmx_pci_read_timeout_s cn58xxp1;
+};
+
+union cvmx_pci_scm_reg {
+ uint64_t u64;
+ struct cvmx_pci_scm_reg_s {
+ uint64_t reserved_32_63:32;
+ uint64_t scm:32;
+ } s;
+ struct cvmx_pci_scm_reg_s cn30xx;
+ struct cvmx_pci_scm_reg_s cn31xx;
+ struct cvmx_pci_scm_reg_s cn38xx;
+ struct cvmx_pci_scm_reg_s cn38xxp2;
+ struct cvmx_pci_scm_reg_s cn50xx;
+ struct cvmx_pci_scm_reg_s cn58xx;
+ struct cvmx_pci_scm_reg_s cn58xxp1;
+};
+
+union cvmx_pci_tsr_reg {
+ uint64_t u64;
+ struct cvmx_pci_tsr_reg_s {
+ uint64_t reserved_36_63:28;
+ uint64_t tsr:36;
+ } s;
+ struct cvmx_pci_tsr_reg_s cn30xx;
+ struct cvmx_pci_tsr_reg_s cn31xx;
+ struct cvmx_pci_tsr_reg_s cn38xx;
+ struct cvmx_pci_tsr_reg_s cn38xxp2;
+ struct cvmx_pci_tsr_reg_s cn50xx;
+ struct cvmx_pci_tsr_reg_s cn58xx;
+ struct cvmx_pci_tsr_reg_s cn58xxp1;
+};
+
+union cvmx_pci_win_rd_addr {
+ uint64_t u64;
+ struct cvmx_pci_win_rd_addr_s {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t reserved_0_47:48;
+ } s;
+ struct cvmx_pci_win_rd_addr_cn30xx {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t rd_addr:46;
+ uint64_t reserved_0_1:2;
+ } cn30xx;
+ struct cvmx_pci_win_rd_addr_cn30xx cn31xx;
+ struct cvmx_pci_win_rd_addr_cn38xx {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t rd_addr:45;
+ uint64_t reserved_0_2:3;
+ } cn38xx;
+ struct cvmx_pci_win_rd_addr_cn38xx cn38xxp2;
+ struct cvmx_pci_win_rd_addr_cn30xx cn50xx;
+ struct cvmx_pci_win_rd_addr_cn38xx cn58xx;
+ struct cvmx_pci_win_rd_addr_cn38xx cn58xxp1;
+};
+
+union cvmx_pci_win_rd_data {
+ uint64_t u64;
+ struct cvmx_pci_win_rd_data_s {
+ uint64_t rd_data:64;
+ } s;
+ struct cvmx_pci_win_rd_data_s cn30xx;
+ struct cvmx_pci_win_rd_data_s cn31xx;
+ struct cvmx_pci_win_rd_data_s cn38xx;
+ struct cvmx_pci_win_rd_data_s cn38xxp2;
+ struct cvmx_pci_win_rd_data_s cn50xx;
+ struct cvmx_pci_win_rd_data_s cn58xx;
+ struct cvmx_pci_win_rd_data_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_addr {
+ uint64_t u64;
+ struct cvmx_pci_win_wr_addr_s {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t wr_addr:45;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_pci_win_wr_addr_s cn30xx;
+ struct cvmx_pci_win_wr_addr_s cn31xx;
+ struct cvmx_pci_win_wr_addr_s cn38xx;
+ struct cvmx_pci_win_wr_addr_s cn38xxp2;
+ struct cvmx_pci_win_wr_addr_s cn50xx;
+ struct cvmx_pci_win_wr_addr_s cn58xx;
+ struct cvmx_pci_win_wr_addr_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_data {
+ uint64_t u64;
+ struct cvmx_pci_win_wr_data_s {
+ uint64_t wr_data:64;
+ } s;
+ struct cvmx_pci_win_wr_data_s cn30xx;
+ struct cvmx_pci_win_wr_data_s cn31xx;
+ struct cvmx_pci_win_wr_data_s cn38xx;
+ struct cvmx_pci_win_wr_data_s cn38xxp2;
+ struct cvmx_pci_win_wr_data_s cn50xx;
+ struct cvmx_pci_win_wr_data_s cn58xx;
+ struct cvmx_pci_win_wr_data_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_mask {
+ uint64_t u64;
+ struct cvmx_pci_win_wr_mask_s {
+ uint64_t reserved_8_63:56;
+ uint64_t wr_mask:8;
+ } s;
+ struct cvmx_pci_win_wr_mask_s cn30xx;
+ struct cvmx_pci_win_wr_mask_s cn31xx;
+ struct cvmx_pci_win_wr_mask_s cn38xx;
+ struct cvmx_pci_win_wr_mask_s cn38xxp2;
+ struct cvmx_pci_win_wr_mask_s cn50xx;
+ struct cvmx_pci_win_wr_mask_s cn58xx;
+ struct cvmx_pci_win_wr_mask_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h b/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h
new file mode 100644
index 00000000..d553f8e8
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h
@@ -0,0 +1,1365 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCIEEP_DEFS_H__
+#define __CVMX_PCIEEP_DEFS_H__
+
+#define CVMX_PCIEEP_CFG000 \
+ (0x0000000000000000ull)
+#define CVMX_PCIEEP_CFG001 \
+ (0x0000000000000004ull)
+#define CVMX_PCIEEP_CFG002 \
+ (0x0000000000000008ull)
+#define CVMX_PCIEEP_CFG003 \
+ (0x000000000000000Cull)
+#define CVMX_PCIEEP_CFG004 \
+ (0x0000000000000010ull)
+#define CVMX_PCIEEP_CFG004_MASK \
+ (0x0000000080000010ull)
+#define CVMX_PCIEEP_CFG005 \
+ (0x0000000000000014ull)
+#define CVMX_PCIEEP_CFG005_MASK \
+ (0x0000000080000014ull)
+#define CVMX_PCIEEP_CFG006 \
+ (0x0000000000000018ull)
+#define CVMX_PCIEEP_CFG006_MASK \
+ (0x0000000080000018ull)
+#define CVMX_PCIEEP_CFG007 \
+ (0x000000000000001Cull)
+#define CVMX_PCIEEP_CFG007_MASK \
+ (0x000000008000001Cull)
+#define CVMX_PCIEEP_CFG008 \
+ (0x0000000000000020ull)
+#define CVMX_PCIEEP_CFG008_MASK \
+ (0x0000000080000020ull)
+#define CVMX_PCIEEP_CFG009 \
+ (0x0000000000000024ull)
+#define CVMX_PCIEEP_CFG009_MASK \
+ (0x0000000080000024ull)
+#define CVMX_PCIEEP_CFG010 \
+ (0x0000000000000028ull)
+#define CVMX_PCIEEP_CFG011 \
+ (0x000000000000002Cull)
+#define CVMX_PCIEEP_CFG012 \
+ (0x0000000000000030ull)
+#define CVMX_PCIEEP_CFG012_MASK \
+ (0x0000000080000030ull)
+#define CVMX_PCIEEP_CFG013 \
+ (0x0000000000000034ull)
+#define CVMX_PCIEEP_CFG015 \
+ (0x000000000000003Cull)
+#define CVMX_PCIEEP_CFG016 \
+ (0x0000000000000040ull)
+#define CVMX_PCIEEP_CFG017 \
+ (0x0000000000000044ull)
+#define CVMX_PCIEEP_CFG020 \
+ (0x0000000000000050ull)
+#define CVMX_PCIEEP_CFG021 \
+ (0x0000000000000054ull)
+#define CVMX_PCIEEP_CFG022 \
+ (0x0000000000000058ull)
+#define CVMX_PCIEEP_CFG023 \
+ (0x000000000000005Cull)
+#define CVMX_PCIEEP_CFG028 \
+ (0x0000000000000070ull)
+#define CVMX_PCIEEP_CFG029 \
+ (0x0000000000000074ull)
+#define CVMX_PCIEEP_CFG030 \
+ (0x0000000000000078ull)
+#define CVMX_PCIEEP_CFG031 \
+ (0x000000000000007Cull)
+#define CVMX_PCIEEP_CFG032 \
+ (0x0000000000000080ull)
+#define CVMX_PCIEEP_CFG033 \
+ (0x0000000000000084ull)
+#define CVMX_PCIEEP_CFG034 \
+ (0x0000000000000088ull)
+#define CVMX_PCIEEP_CFG037 \
+ (0x0000000000000094ull)
+#define CVMX_PCIEEP_CFG038 \
+ (0x0000000000000098ull)
+#define CVMX_PCIEEP_CFG039 \
+ (0x000000000000009Cull)
+#define CVMX_PCIEEP_CFG040 \
+ (0x00000000000000A0ull)
+#define CVMX_PCIEEP_CFG041 \
+ (0x00000000000000A4ull)
+#define CVMX_PCIEEP_CFG042 \
+ (0x00000000000000A8ull)
+#define CVMX_PCIEEP_CFG064 \
+ (0x0000000000000100ull)
+#define CVMX_PCIEEP_CFG065 \
+ (0x0000000000000104ull)
+#define CVMX_PCIEEP_CFG066 \
+ (0x0000000000000108ull)
+#define CVMX_PCIEEP_CFG067 \
+ (0x000000000000010Cull)
+#define CVMX_PCIEEP_CFG068 \
+ (0x0000000000000110ull)
+#define CVMX_PCIEEP_CFG069 \
+ (0x0000000000000114ull)
+#define CVMX_PCIEEP_CFG070 \
+ (0x0000000000000118ull)
+#define CVMX_PCIEEP_CFG071 \
+ (0x000000000000011Cull)
+#define CVMX_PCIEEP_CFG072 \
+ (0x0000000000000120ull)
+#define CVMX_PCIEEP_CFG073 \
+ (0x0000000000000124ull)
+#define CVMX_PCIEEP_CFG074 \
+ (0x0000000000000128ull)
+#define CVMX_PCIEEP_CFG448 \
+ (0x0000000000000700ull)
+#define CVMX_PCIEEP_CFG449 \
+ (0x0000000000000704ull)
+#define CVMX_PCIEEP_CFG450 \
+ (0x0000000000000708ull)
+#define CVMX_PCIEEP_CFG451 \
+ (0x000000000000070Cull)
+#define CVMX_PCIEEP_CFG452 \
+ (0x0000000000000710ull)
+#define CVMX_PCIEEP_CFG453 \
+ (0x0000000000000714ull)
+#define CVMX_PCIEEP_CFG454 \
+ (0x0000000000000718ull)
+#define CVMX_PCIEEP_CFG455 \
+ (0x000000000000071Cull)
+#define CVMX_PCIEEP_CFG456 \
+ (0x0000000000000720ull)
+#define CVMX_PCIEEP_CFG458 \
+ (0x0000000000000728ull)
+#define CVMX_PCIEEP_CFG459 \
+ (0x000000000000072Cull)
+#define CVMX_PCIEEP_CFG460 \
+ (0x0000000000000730ull)
+#define CVMX_PCIEEP_CFG461 \
+ (0x0000000000000734ull)
+#define CVMX_PCIEEP_CFG462 \
+ (0x0000000000000738ull)
+#define CVMX_PCIEEP_CFG463 \
+ (0x000000000000073Cull)
+#define CVMX_PCIEEP_CFG464 \
+ (0x0000000000000740ull)
+#define CVMX_PCIEEP_CFG465 \
+ (0x0000000000000744ull)
+#define CVMX_PCIEEP_CFG466 \
+ (0x0000000000000748ull)
+#define CVMX_PCIEEP_CFG467 \
+ (0x000000000000074Cull)
+#define CVMX_PCIEEP_CFG468 \
+ (0x0000000000000750ull)
+#define CVMX_PCIEEP_CFG490 \
+ (0x00000000000007A8ull)
+#define CVMX_PCIEEP_CFG491 \
+ (0x00000000000007ACull)
+#define CVMX_PCIEEP_CFG492 \
+ (0x00000000000007B0ull)
+#define CVMX_PCIEEP_CFG516 \
+ (0x0000000000000810ull)
+#define CVMX_PCIEEP_CFG517 \
+ (0x0000000000000814ull)
+
+union cvmx_pcieep_cfg000 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg000_s {
+ uint32_t devid:16;
+ uint32_t vendid:16;
+ } s;
+ struct cvmx_pcieep_cfg000_s cn52xx;
+ struct cvmx_pcieep_cfg000_s cn52xxp1;
+ struct cvmx_pcieep_cfg000_s cn56xx;
+ struct cvmx_pcieep_cfg000_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg001 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg001_s {
+ uint32_t dpe:1;
+ uint32_t sse:1;
+ uint32_t rma:1;
+ uint32_t rta:1;
+ uint32_t sta:1;
+ uint32_t devt:2;
+ uint32_t mdpe:1;
+ uint32_t fbb:1;
+ uint32_t reserved_22_22:1;
+ uint32_t m66:1;
+ uint32_t cl:1;
+ uint32_t i_stat:1;
+ uint32_t reserved_11_18:8;
+ uint32_t i_dis:1;
+ uint32_t fbbe:1;
+ uint32_t see:1;
+ uint32_t ids_wcc:1;
+ uint32_t per:1;
+ uint32_t vps:1;
+ uint32_t mwice:1;
+ uint32_t scse:1;
+ uint32_t me:1;
+ uint32_t msae:1;
+ uint32_t isae:1;
+ } s;
+ struct cvmx_pcieep_cfg001_s cn52xx;
+ struct cvmx_pcieep_cfg001_s cn52xxp1;
+ struct cvmx_pcieep_cfg001_s cn56xx;
+ struct cvmx_pcieep_cfg001_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg002 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg002_s {
+ uint32_t bcc:8;
+ uint32_t sc:8;
+ uint32_t pi:8;
+ uint32_t rid:8;
+ } s;
+ struct cvmx_pcieep_cfg002_s cn52xx;
+ struct cvmx_pcieep_cfg002_s cn52xxp1;
+ struct cvmx_pcieep_cfg002_s cn56xx;
+ struct cvmx_pcieep_cfg002_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg003 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg003_s {
+ uint32_t bist:8;
+ uint32_t mfd:1;
+ uint32_t chf:7;
+ uint32_t lt:8;
+ uint32_t cls:8;
+ } s;
+ struct cvmx_pcieep_cfg003_s cn52xx;
+ struct cvmx_pcieep_cfg003_s cn52xxp1;
+ struct cvmx_pcieep_cfg003_s cn56xx;
+ struct cvmx_pcieep_cfg003_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg004 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg004_s {
+ uint32_t lbab:18;
+ uint32_t reserved_4_13:10;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pcieep_cfg004_s cn52xx;
+ struct cvmx_pcieep_cfg004_s cn52xxp1;
+ struct cvmx_pcieep_cfg004_s cn56xx;
+ struct cvmx_pcieep_cfg004_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg004_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg004_mask_s {
+ uint32_t lmask:31;
+ uint32_t enb:1;
+ } s;
+ struct cvmx_pcieep_cfg004_mask_s cn52xx;
+ struct cvmx_pcieep_cfg004_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg004_mask_s cn56xx;
+ struct cvmx_pcieep_cfg004_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg005 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg005_s {
+ uint32_t ubab:32;
+ } s;
+ struct cvmx_pcieep_cfg005_s cn52xx;
+ struct cvmx_pcieep_cfg005_s cn52xxp1;
+ struct cvmx_pcieep_cfg005_s cn56xx;
+ struct cvmx_pcieep_cfg005_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg005_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg005_mask_s {
+ uint32_t umask:32;
+ } s;
+ struct cvmx_pcieep_cfg005_mask_s cn52xx;
+ struct cvmx_pcieep_cfg005_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg005_mask_s cn56xx;
+ struct cvmx_pcieep_cfg005_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg006 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg006_s {
+ uint32_t lbab:6;
+ uint32_t reserved_4_25:22;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pcieep_cfg006_s cn52xx;
+ struct cvmx_pcieep_cfg006_s cn52xxp1;
+ struct cvmx_pcieep_cfg006_s cn56xx;
+ struct cvmx_pcieep_cfg006_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg006_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg006_mask_s {
+ uint32_t lmask:31;
+ uint32_t enb:1;
+ } s;
+ struct cvmx_pcieep_cfg006_mask_s cn52xx;
+ struct cvmx_pcieep_cfg006_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg006_mask_s cn56xx;
+ struct cvmx_pcieep_cfg006_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg007 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg007_s {
+ uint32_t ubab:32;
+ } s;
+ struct cvmx_pcieep_cfg007_s cn52xx;
+ struct cvmx_pcieep_cfg007_s cn52xxp1;
+ struct cvmx_pcieep_cfg007_s cn56xx;
+ struct cvmx_pcieep_cfg007_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg007_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg007_mask_s {
+ uint32_t umask:32;
+ } s;
+ struct cvmx_pcieep_cfg007_mask_s cn52xx;
+ struct cvmx_pcieep_cfg007_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg007_mask_s cn56xx;
+ struct cvmx_pcieep_cfg007_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg008 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg008_s {
+ uint32_t reserved_4_31:28;
+ uint32_t pf:1;
+ uint32_t typ:2;
+ uint32_t mspc:1;
+ } s;
+ struct cvmx_pcieep_cfg008_s cn52xx;
+ struct cvmx_pcieep_cfg008_s cn52xxp1;
+ struct cvmx_pcieep_cfg008_s cn56xx;
+ struct cvmx_pcieep_cfg008_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg008_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg008_mask_s {
+ uint32_t lmask:31;
+ uint32_t enb:1;
+ } s;
+ struct cvmx_pcieep_cfg008_mask_s cn52xx;
+ struct cvmx_pcieep_cfg008_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg008_mask_s cn56xx;
+ struct cvmx_pcieep_cfg008_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg009 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg009_s {
+ uint32_t ubab:25;
+ uint32_t reserved_0_6:7;
+ } s;
+ struct cvmx_pcieep_cfg009_s cn52xx;
+ struct cvmx_pcieep_cfg009_s cn52xxp1;
+ struct cvmx_pcieep_cfg009_s cn56xx;
+ struct cvmx_pcieep_cfg009_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg009_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg009_mask_s {
+ uint32_t umask:32;
+ } s;
+ struct cvmx_pcieep_cfg009_mask_s cn52xx;
+ struct cvmx_pcieep_cfg009_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg009_mask_s cn56xx;
+ struct cvmx_pcieep_cfg009_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg010 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg010_s {
+ uint32_t cisp:32;
+ } s;
+ struct cvmx_pcieep_cfg010_s cn52xx;
+ struct cvmx_pcieep_cfg010_s cn52xxp1;
+ struct cvmx_pcieep_cfg010_s cn56xx;
+ struct cvmx_pcieep_cfg010_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg011 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg011_s {
+ uint32_t ssid:16;
+ uint32_t ssvid:16;
+ } s;
+ struct cvmx_pcieep_cfg011_s cn52xx;
+ struct cvmx_pcieep_cfg011_s cn52xxp1;
+ struct cvmx_pcieep_cfg011_s cn56xx;
+ struct cvmx_pcieep_cfg011_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg012 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg012_s {
+ uint32_t eraddr:16;
+ uint32_t reserved_1_15:15;
+ uint32_t er_en:1;
+ } s;
+ struct cvmx_pcieep_cfg012_s cn52xx;
+ struct cvmx_pcieep_cfg012_s cn52xxp1;
+ struct cvmx_pcieep_cfg012_s cn56xx;
+ struct cvmx_pcieep_cfg012_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg012_mask {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg012_mask_s {
+ uint32_t mask:31;
+ uint32_t enb:1;
+ } s;
+ struct cvmx_pcieep_cfg012_mask_s cn52xx;
+ struct cvmx_pcieep_cfg012_mask_s cn52xxp1;
+ struct cvmx_pcieep_cfg012_mask_s cn56xx;
+ struct cvmx_pcieep_cfg012_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg013 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg013_s {
+ uint32_t reserved_8_31:24;
+ uint32_t cp:8;
+ } s;
+ struct cvmx_pcieep_cfg013_s cn52xx;
+ struct cvmx_pcieep_cfg013_s cn52xxp1;
+ struct cvmx_pcieep_cfg013_s cn56xx;
+ struct cvmx_pcieep_cfg013_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg015 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg015_s {
+ uint32_t ml:8;
+ uint32_t mg:8;
+ uint32_t inta:8;
+ uint32_t il:8;
+ } s;
+ struct cvmx_pcieep_cfg015_s cn52xx;
+ struct cvmx_pcieep_cfg015_s cn52xxp1;
+ struct cvmx_pcieep_cfg015_s cn56xx;
+ struct cvmx_pcieep_cfg015_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg016 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg016_s {
+ uint32_t pmes:5;
+ uint32_t d2s:1;
+ uint32_t d1s:1;
+ uint32_t auxc:3;
+ uint32_t dsi:1;
+ uint32_t reserved_20_20:1;
+ uint32_t pme_clock:1;
+ uint32_t pmsv:3;
+ uint32_t ncp:8;
+ uint32_t pmcid:8;
+ } s;
+ struct cvmx_pcieep_cfg016_s cn52xx;
+ struct cvmx_pcieep_cfg016_s cn52xxp1;
+ struct cvmx_pcieep_cfg016_s cn56xx;
+ struct cvmx_pcieep_cfg016_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg017 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg017_s {
+ uint32_t pmdia:8;
+ uint32_t bpccee:1;
+ uint32_t bd3h:1;
+ uint32_t reserved_16_21:6;
+ uint32_t pmess:1;
+ uint32_t pmedsia:2;
+ uint32_t pmds:4;
+ uint32_t pmeens:1;
+ uint32_t reserved_4_7:4;
+ uint32_t nsr:1;
+ uint32_t reserved_2_2:1;
+ uint32_t ps:2;
+ } s;
+ struct cvmx_pcieep_cfg017_s cn52xx;
+ struct cvmx_pcieep_cfg017_s cn52xxp1;
+ struct cvmx_pcieep_cfg017_s cn56xx;
+ struct cvmx_pcieep_cfg017_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg020 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg020_s {
+ uint32_t reserved_24_31:8;
+ uint32_t m64:1;
+ uint32_t mme:3;
+ uint32_t mmc:3;
+ uint32_t msien:1;
+ uint32_t ncp:8;
+ uint32_t msicid:8;
+ } s;
+ struct cvmx_pcieep_cfg020_s cn52xx;
+ struct cvmx_pcieep_cfg020_s cn52xxp1;
+ struct cvmx_pcieep_cfg020_s cn56xx;
+ struct cvmx_pcieep_cfg020_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg021 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg021_s {
+ uint32_t lmsi:30;
+ uint32_t reserved_0_1:2;
+ } s;
+ struct cvmx_pcieep_cfg021_s cn52xx;
+ struct cvmx_pcieep_cfg021_s cn52xxp1;
+ struct cvmx_pcieep_cfg021_s cn56xx;
+ struct cvmx_pcieep_cfg021_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg022 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg022_s {
+ uint32_t umsi:32;
+ } s;
+ struct cvmx_pcieep_cfg022_s cn52xx;
+ struct cvmx_pcieep_cfg022_s cn52xxp1;
+ struct cvmx_pcieep_cfg022_s cn56xx;
+ struct cvmx_pcieep_cfg022_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg023 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg023_s {
+ uint32_t reserved_16_31:16;
+ uint32_t msimd:16;
+ } s;
+ struct cvmx_pcieep_cfg023_s cn52xx;
+ struct cvmx_pcieep_cfg023_s cn52xxp1;
+ struct cvmx_pcieep_cfg023_s cn56xx;
+ struct cvmx_pcieep_cfg023_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg028 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg028_s {
+ uint32_t reserved_30_31:2;
+ uint32_t imn:5;
+ uint32_t si:1;
+ uint32_t dpt:4;
+ uint32_t pciecv:4;
+ uint32_t ncp:8;
+ uint32_t pcieid:8;
+ } s;
+ struct cvmx_pcieep_cfg028_s cn52xx;
+ struct cvmx_pcieep_cfg028_s cn52xxp1;
+ struct cvmx_pcieep_cfg028_s cn56xx;
+ struct cvmx_pcieep_cfg028_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg029 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg029_s {
+ uint32_t reserved_28_31:4;
+ uint32_t cspls:2;
+ uint32_t csplv:8;
+ uint32_t reserved_16_17:2;
+ uint32_t rber:1;
+ uint32_t reserved_12_14:3;
+ uint32_t el1al:3;
+ uint32_t el0al:3;
+ uint32_t etfs:1;
+ uint32_t pfs:2;
+ uint32_t mpss:3;
+ } s;
+ struct cvmx_pcieep_cfg029_s cn52xx;
+ struct cvmx_pcieep_cfg029_s cn52xxp1;
+ struct cvmx_pcieep_cfg029_s cn56xx;
+ struct cvmx_pcieep_cfg029_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg030 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg030_s {
+ uint32_t reserved_22_31:10;
+ uint32_t tp:1;
+ uint32_t ap_d:1;
+ uint32_t ur_d:1;
+ uint32_t fe_d:1;
+ uint32_t nfe_d:1;
+ uint32_t ce_d:1;
+ uint32_t reserved_15_15:1;
+ uint32_t mrrs:3;
+ uint32_t ns_en:1;
+ uint32_t ap_en:1;
+ uint32_t pf_en:1;
+ uint32_t etf_en:1;
+ uint32_t mps:3;
+ uint32_t ro_en:1;
+ uint32_t ur_en:1;
+ uint32_t fe_en:1;
+ uint32_t nfe_en:1;
+ uint32_t ce_en:1;
+ } s;
+ struct cvmx_pcieep_cfg030_s cn52xx;
+ struct cvmx_pcieep_cfg030_s cn52xxp1;
+ struct cvmx_pcieep_cfg030_s cn56xx;
+ struct cvmx_pcieep_cfg030_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg031 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg031_s {
+ uint32_t pnum:8;
+ uint32_t reserved_22_23:2;
+ uint32_t lbnc:1;
+ uint32_t dllarc:1;
+ uint32_t sderc:1;
+ uint32_t cpm:1;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t aslpms:2;
+ uint32_t mlw:6;
+ uint32_t mls:4;
+ } s;
+ struct cvmx_pcieep_cfg031_s cn52xx;
+ struct cvmx_pcieep_cfg031_s cn52xxp1;
+ struct cvmx_pcieep_cfg031_s cn56xx;
+ struct cvmx_pcieep_cfg031_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg032 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg032_s {
+ uint32_t reserved_30_31:2;
+ uint32_t dlla:1;
+ uint32_t scc:1;
+ uint32_t lt:1;
+ uint32_t reserved_26_26:1;
+ uint32_t nlw:6;
+ uint32_t ls:4;
+ uint32_t reserved_10_15:6;
+ uint32_t hawd:1;
+ uint32_t ecpm:1;
+ uint32_t es:1;
+ uint32_t ccc:1;
+ uint32_t rl:1;
+ uint32_t ld:1;
+ uint32_t rcb:1;
+ uint32_t reserved_2_2:1;
+ uint32_t aslpc:2;
+ } s;
+ struct cvmx_pcieep_cfg032_s cn52xx;
+ struct cvmx_pcieep_cfg032_s cn52xxp1;
+ struct cvmx_pcieep_cfg032_s cn56xx;
+ struct cvmx_pcieep_cfg032_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg033 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg033_s {
+ uint32_t ps_num:13;
+ uint32_t nccs:1;
+ uint32_t emip:1;
+ uint32_t sp_ls:2;
+ uint32_t sp_lv:8;
+ uint32_t hp_c:1;
+ uint32_t hp_s:1;
+ uint32_t pip:1;
+ uint32_t aip:1;
+ uint32_t mrlsp:1;
+ uint32_t pcp:1;
+ uint32_t abp:1;
+ } s;
+ struct cvmx_pcieep_cfg033_s cn52xx;
+ struct cvmx_pcieep_cfg033_s cn52xxp1;
+ struct cvmx_pcieep_cfg033_s cn56xx;
+ struct cvmx_pcieep_cfg033_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg034 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg034_s {
+ uint32_t reserved_25_31:7;
+ uint32_t dlls_c:1;
+ uint32_t emis:1;
+ uint32_t pds:1;
+ uint32_t mrlss:1;
+ uint32_t ccint_d:1;
+ uint32_t pd_c:1;
+ uint32_t mrls_c:1;
+ uint32_t pf_d:1;
+ uint32_t abp_d:1;
+ uint32_t reserved_13_15:3;
+ uint32_t dlls_en:1;
+ uint32_t emic:1;
+ uint32_t pcc:1;
+ uint32_t pic:2;
+ uint32_t aic:2;
+ uint32_t hpint_en:1;
+ uint32_t ccint_en:1;
+ uint32_t pd_en:1;
+ uint32_t mrls_en:1;
+ uint32_t pf_en:1;
+ uint32_t abp_en:1;
+ } s;
+ struct cvmx_pcieep_cfg034_s cn52xx;
+ struct cvmx_pcieep_cfg034_s cn52xxp1;
+ struct cvmx_pcieep_cfg034_s cn56xx;
+ struct cvmx_pcieep_cfg034_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg037 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg037_s {
+ uint32_t reserved_5_31:27;
+ uint32_t ctds:1;
+ uint32_t ctrs:4;
+ } s;
+ struct cvmx_pcieep_cfg037_s cn52xx;
+ struct cvmx_pcieep_cfg037_s cn52xxp1;
+ struct cvmx_pcieep_cfg037_s cn56xx;
+ struct cvmx_pcieep_cfg037_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg038 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg038_s {
+ uint32_t reserved_5_31:27;
+ uint32_t ctd:1;
+ uint32_t ctv:4;
+ } s;
+ struct cvmx_pcieep_cfg038_s cn52xx;
+ struct cvmx_pcieep_cfg038_s cn52xxp1;
+ struct cvmx_pcieep_cfg038_s cn56xx;
+ struct cvmx_pcieep_cfg038_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg039 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg039_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pcieep_cfg039_s cn52xx;
+ struct cvmx_pcieep_cfg039_s cn52xxp1;
+ struct cvmx_pcieep_cfg039_s cn56xx;
+ struct cvmx_pcieep_cfg039_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg040 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg040_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pcieep_cfg040_s cn52xx;
+ struct cvmx_pcieep_cfg040_s cn52xxp1;
+ struct cvmx_pcieep_cfg040_s cn56xx;
+ struct cvmx_pcieep_cfg040_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg041 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg041_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pcieep_cfg041_s cn52xx;
+ struct cvmx_pcieep_cfg041_s cn52xxp1;
+ struct cvmx_pcieep_cfg041_s cn56xx;
+ struct cvmx_pcieep_cfg041_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg042 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg042_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pcieep_cfg042_s cn52xx;
+ struct cvmx_pcieep_cfg042_s cn52xxp1;
+ struct cvmx_pcieep_cfg042_s cn56xx;
+ struct cvmx_pcieep_cfg042_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg064 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg064_s {
+ uint32_t nco:12;
+ uint32_t cv:4;
+ uint32_t pcieec:16;
+ } s;
+ struct cvmx_pcieep_cfg064_s cn52xx;
+ struct cvmx_pcieep_cfg064_s cn52xxp1;
+ struct cvmx_pcieep_cfg064_s cn56xx;
+ struct cvmx_pcieep_cfg064_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg065 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg065_s {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pcieep_cfg065_s cn52xx;
+ struct cvmx_pcieep_cfg065_s cn52xxp1;
+ struct cvmx_pcieep_cfg065_s cn56xx;
+ struct cvmx_pcieep_cfg065_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg066 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg066_s {
+ uint32_t reserved_21_31:11;
+ uint32_t urem:1;
+ uint32_t ecrcem:1;
+ uint32_t mtlpm:1;
+ uint32_t rom:1;
+ uint32_t ucm:1;
+ uint32_t cam:1;
+ uint32_t ctm:1;
+ uint32_t fcpem:1;
+ uint32_t ptlpm:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdem:1;
+ uint32_t dlpem:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pcieep_cfg066_s cn52xx;
+ struct cvmx_pcieep_cfg066_s cn52xxp1;
+ struct cvmx_pcieep_cfg066_s cn56xx;
+ struct cvmx_pcieep_cfg066_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg067 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg067_s {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pcieep_cfg067_s cn52xx;
+ struct cvmx_pcieep_cfg067_s cn52xxp1;
+ struct cvmx_pcieep_cfg067_s cn56xx;
+ struct cvmx_pcieep_cfg067_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg068 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg068_s {
+ uint32_t reserved_14_31:18;
+ uint32_t anfes:1;
+ uint32_t rtts:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrs:1;
+ uint32_t bdllps:1;
+ uint32_t btlps:1;
+ uint32_t reserved_1_5:5;
+ uint32_t res:1;
+ } s;
+ struct cvmx_pcieep_cfg068_s cn52xx;
+ struct cvmx_pcieep_cfg068_s cn52xxp1;
+ struct cvmx_pcieep_cfg068_s cn56xx;
+ struct cvmx_pcieep_cfg068_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg069 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg069_s {
+ uint32_t reserved_14_31:18;
+ uint32_t anfem:1;
+ uint32_t rttm:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrm:1;
+ uint32_t bdllpm:1;
+ uint32_t btlpm:1;
+ uint32_t reserved_1_5:5;
+ uint32_t rem:1;
+ } s;
+ struct cvmx_pcieep_cfg069_s cn52xx;
+ struct cvmx_pcieep_cfg069_s cn52xxp1;
+ struct cvmx_pcieep_cfg069_s cn56xx;
+ struct cvmx_pcieep_cfg069_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg070 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg070_s {
+ uint32_t reserved_9_31:23;
+ uint32_t ce:1;
+ uint32_t cc:1;
+ uint32_t ge:1;
+ uint32_t gc:1;
+ uint32_t fep:5;
+ } s;
+ struct cvmx_pcieep_cfg070_s cn52xx;
+ struct cvmx_pcieep_cfg070_s cn52xxp1;
+ struct cvmx_pcieep_cfg070_s cn56xx;
+ struct cvmx_pcieep_cfg070_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg071 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg071_s {
+ uint32_t dword1:32;
+ } s;
+ struct cvmx_pcieep_cfg071_s cn52xx;
+ struct cvmx_pcieep_cfg071_s cn52xxp1;
+ struct cvmx_pcieep_cfg071_s cn56xx;
+ struct cvmx_pcieep_cfg071_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg072 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg072_s {
+ uint32_t dword2:32;
+ } s;
+ struct cvmx_pcieep_cfg072_s cn52xx;
+ struct cvmx_pcieep_cfg072_s cn52xxp1;
+ struct cvmx_pcieep_cfg072_s cn56xx;
+ struct cvmx_pcieep_cfg072_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg073 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg073_s {
+ uint32_t dword3:32;
+ } s;
+ struct cvmx_pcieep_cfg073_s cn52xx;
+ struct cvmx_pcieep_cfg073_s cn52xxp1;
+ struct cvmx_pcieep_cfg073_s cn56xx;
+ struct cvmx_pcieep_cfg073_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg074 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg074_s {
+ uint32_t dword4:32;
+ } s;
+ struct cvmx_pcieep_cfg074_s cn52xx;
+ struct cvmx_pcieep_cfg074_s cn52xxp1;
+ struct cvmx_pcieep_cfg074_s cn56xx;
+ struct cvmx_pcieep_cfg074_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg448 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg448_s {
+ uint32_t rtl:16;
+ uint32_t rtltl:16;
+ } s;
+ struct cvmx_pcieep_cfg448_s cn52xx;
+ struct cvmx_pcieep_cfg448_s cn52xxp1;
+ struct cvmx_pcieep_cfg448_s cn56xx;
+ struct cvmx_pcieep_cfg448_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg449 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg449_s {
+ uint32_t omr:32;
+ } s;
+ struct cvmx_pcieep_cfg449_s cn52xx;
+ struct cvmx_pcieep_cfg449_s cn52xxp1;
+ struct cvmx_pcieep_cfg449_s cn56xx;
+ struct cvmx_pcieep_cfg449_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg450 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg450_s {
+ uint32_t lpec:8;
+ uint32_t reserved_22_23:2;
+ uint32_t link_state:6;
+ uint32_t force_link:1;
+ uint32_t reserved_8_14:7;
+ uint32_t link_num:8;
+ } s;
+ struct cvmx_pcieep_cfg450_s cn52xx;
+ struct cvmx_pcieep_cfg450_s cn52xxp1;
+ struct cvmx_pcieep_cfg450_s cn56xx;
+ struct cvmx_pcieep_cfg450_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg451 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg451_s {
+ uint32_t reserved_30_31:2;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t n_fts_cc:8;
+ uint32_t n_fts:8;
+ uint32_t ack_freq:8;
+ } s;
+ struct cvmx_pcieep_cfg451_s cn52xx;
+ struct cvmx_pcieep_cfg451_s cn52xxp1;
+ struct cvmx_pcieep_cfg451_s cn56xx;
+ struct cvmx_pcieep_cfg451_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg452 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg452_s {
+ uint32_t reserved_26_31:6;
+ uint32_t eccrc:1;
+ uint32_t reserved_22_24:3;
+ uint32_t lme:6;
+ uint32_t reserved_8_15:8;
+ uint32_t flm:1;
+ uint32_t reserved_6_6:1;
+ uint32_t dllle:1;
+ uint32_t reserved_4_4:1;
+ uint32_t ra:1;
+ uint32_t le:1;
+ uint32_t sd:1;
+ uint32_t omr:1;
+ } s;
+ struct cvmx_pcieep_cfg452_s cn52xx;
+ struct cvmx_pcieep_cfg452_s cn52xxp1;
+ struct cvmx_pcieep_cfg452_s cn56xx;
+ struct cvmx_pcieep_cfg452_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg453 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg453_s {
+ uint32_t dlld:1;
+ uint32_t reserved_26_30:5;
+ uint32_t ack_nak:1;
+ uint32_t fcd:1;
+ uint32_t ilst:24;
+ } s;
+ struct cvmx_pcieep_cfg453_s cn52xx;
+ struct cvmx_pcieep_cfg453_s cn52xxp1;
+ struct cvmx_pcieep_cfg453_s cn56xx;
+ struct cvmx_pcieep_cfg453_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg454 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg454_s {
+ uint32_t reserved_29_31:3;
+ uint32_t tmfcwt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmrt:5;
+ uint32_t reserved_11_13:3;
+ uint32_t nskps:3;
+ uint32_t reserved_4_7:4;
+ uint32_t ntss:4;
+ } s;
+ struct cvmx_pcieep_cfg454_s cn52xx;
+ struct cvmx_pcieep_cfg454_s cn52xxp1;
+ struct cvmx_pcieep_cfg454_s cn56xx;
+ struct cvmx_pcieep_cfg454_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg455 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg455_s {
+ uint32_t m_cfg0_filt:1;
+ uint32_t m_io_filt:1;
+ uint32_t msg_ctrl:1;
+ uint32_t m_cpl_ecrc_filt:1;
+ uint32_t m_ecrc_filt:1;
+ uint32_t m_cpl_len_err:1;
+ uint32_t m_cpl_attr_err:1;
+ uint32_t m_cpl_tc_err:1;
+ uint32_t m_cpl_fun_err:1;
+ uint32_t m_cpl_rid_err:1;
+ uint32_t m_cpl_tag_err:1;
+ uint32_t m_lk_filt:1;
+ uint32_t m_cfg1_filt:1;
+ uint32_t m_bar_match:1;
+ uint32_t m_pois_filt:1;
+ uint32_t m_fun:1;
+ uint32_t dfcwt:1;
+ uint32_t reserved_11_14:4;
+ uint32_t skpiv:11;
+ } s;
+ struct cvmx_pcieep_cfg455_s cn52xx;
+ struct cvmx_pcieep_cfg455_s cn52xxp1;
+ struct cvmx_pcieep_cfg455_s cn56xx;
+ struct cvmx_pcieep_cfg455_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg456 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg456_s {
+ uint32_t reserved_2_31:30;
+ uint32_t m_vend1_drp:1;
+ uint32_t m_vend0_drp:1;
+ } s;
+ struct cvmx_pcieep_cfg456_s cn52xx;
+ struct cvmx_pcieep_cfg456_s cn52xxp1;
+ struct cvmx_pcieep_cfg456_s cn56xx;
+ struct cvmx_pcieep_cfg456_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg458 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg458_s {
+ uint32_t dbg_info_l32:32;
+ } s;
+ struct cvmx_pcieep_cfg458_s cn52xx;
+ struct cvmx_pcieep_cfg458_s cn52xxp1;
+ struct cvmx_pcieep_cfg458_s cn56xx;
+ struct cvmx_pcieep_cfg458_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg459 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg459_s {
+ uint32_t dbg_info_u32:32;
+ } s;
+ struct cvmx_pcieep_cfg459_s cn52xx;
+ struct cvmx_pcieep_cfg459_s cn52xxp1;
+ struct cvmx_pcieep_cfg459_s cn56xx;
+ struct cvmx_pcieep_cfg459_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg460 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg460_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tphfcc:8;
+ uint32_t tpdfcc:12;
+ } s;
+ struct cvmx_pcieep_cfg460_s cn52xx;
+ struct cvmx_pcieep_cfg460_s cn52xxp1;
+ struct cvmx_pcieep_cfg460_s cn56xx;
+ struct cvmx_pcieep_cfg460_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg461 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg461_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tchfcc:8;
+ uint32_t tcdfcc:12;
+ } s;
+ struct cvmx_pcieep_cfg461_s cn52xx;
+ struct cvmx_pcieep_cfg461_s cn52xxp1;
+ struct cvmx_pcieep_cfg461_s cn56xx;
+ struct cvmx_pcieep_cfg461_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg462 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg462_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tchfcc:8;
+ uint32_t tcdfcc:12;
+ } s;
+ struct cvmx_pcieep_cfg462_s cn52xx;
+ struct cvmx_pcieep_cfg462_s cn52xxp1;
+ struct cvmx_pcieep_cfg462_s cn56xx;
+ struct cvmx_pcieep_cfg462_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg463 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg463_s {
+ uint32_t reserved_3_31:29;
+ uint32_t rqne:1;
+ uint32_t trbne:1;
+ uint32_t rtlpfccnr:1;
+ } s;
+ struct cvmx_pcieep_cfg463_s cn52xx;
+ struct cvmx_pcieep_cfg463_s cn52xxp1;
+ struct cvmx_pcieep_cfg463_s cn56xx;
+ struct cvmx_pcieep_cfg463_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg464 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg464_s {
+ uint32_t wrr_vc3:8;
+ uint32_t wrr_vc2:8;
+ uint32_t wrr_vc1:8;
+ uint32_t wrr_vc0:8;
+ } s;
+ struct cvmx_pcieep_cfg464_s cn52xx;
+ struct cvmx_pcieep_cfg464_s cn52xxp1;
+ struct cvmx_pcieep_cfg464_s cn56xx;
+ struct cvmx_pcieep_cfg464_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg465 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg465_s {
+ uint32_t wrr_vc7:8;
+ uint32_t wrr_vc6:8;
+ uint32_t wrr_vc5:8;
+ uint32_t wrr_vc4:8;
+ } s;
+ struct cvmx_pcieep_cfg465_s cn52xx;
+ struct cvmx_pcieep_cfg465_s cn52xxp1;
+ struct cvmx_pcieep_cfg465_s cn56xx;
+ struct cvmx_pcieep_cfg465_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg466 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg466_s {
+ uint32_t rx_queue_order:1;
+ uint32_t type_ordering:1;
+ uint32_t reserved_24_29:6;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pcieep_cfg466_s cn52xx;
+ struct cvmx_pcieep_cfg466_s cn52xxp1;
+ struct cvmx_pcieep_cfg466_s cn56xx;
+ struct cvmx_pcieep_cfg466_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg467 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg467_s {
+ uint32_t reserved_24_31:8;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pcieep_cfg467_s cn52xx;
+ struct cvmx_pcieep_cfg467_s cn52xxp1;
+ struct cvmx_pcieep_cfg467_s cn56xx;
+ struct cvmx_pcieep_cfg467_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg468 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg468_s {
+ uint32_t reserved_24_31:8;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pcieep_cfg468_s cn52xx;
+ struct cvmx_pcieep_cfg468_s cn52xxp1;
+ struct cvmx_pcieep_cfg468_s cn56xx;
+ struct cvmx_pcieep_cfg468_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg490 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg490_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pcieep_cfg490_s cn52xx;
+ struct cvmx_pcieep_cfg490_s cn52xxp1;
+ struct cvmx_pcieep_cfg490_s cn56xx;
+ struct cvmx_pcieep_cfg490_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg491 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg491_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pcieep_cfg491_s cn52xx;
+ struct cvmx_pcieep_cfg491_s cn52xxp1;
+ struct cvmx_pcieep_cfg491_s cn56xx;
+ struct cvmx_pcieep_cfg491_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg492 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg492_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pcieep_cfg492_s cn52xx;
+ struct cvmx_pcieep_cfg492_s cn52xxp1;
+ struct cvmx_pcieep_cfg492_s cn56xx;
+ struct cvmx_pcieep_cfg492_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg516 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg516_s {
+ uint32_t phy_stat:32;
+ } s;
+ struct cvmx_pcieep_cfg516_s cn52xx;
+ struct cvmx_pcieep_cfg516_s cn52xxp1;
+ struct cvmx_pcieep_cfg516_s cn56xx;
+ struct cvmx_pcieep_cfg516_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg517 {
+ uint32_t u32;
+ struct cvmx_pcieep_cfg517_s {
+ uint32_t phy_ctrl:32;
+ } s;
+ struct cvmx_pcieep_cfg517_s cn52xx;
+ struct cvmx_pcieep_cfg517_s cn52xxp1;
+ struct cvmx_pcieep_cfg517_s cn56xx;
+ struct cvmx_pcieep_cfg517_s cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
new file mode 100644
index 00000000..f8cb8890
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
@@ -0,0 +1,1506 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCIERCX_DEFS_H__
+#define __CVMX_PCIERCX_DEFS_H__
+
+#define CVMX_PCIERCX_CFG000(block_id) (0x0000000000000000ull)
+#define CVMX_PCIERCX_CFG001(block_id) (0x0000000000000004ull)
+#define CVMX_PCIERCX_CFG002(block_id) (0x0000000000000008ull)
+#define CVMX_PCIERCX_CFG003(block_id) (0x000000000000000Cull)
+#define CVMX_PCIERCX_CFG004(block_id) (0x0000000000000010ull)
+#define CVMX_PCIERCX_CFG005(block_id) (0x0000000000000014ull)
+#define CVMX_PCIERCX_CFG006(block_id) (0x0000000000000018ull)
+#define CVMX_PCIERCX_CFG007(block_id) (0x000000000000001Cull)
+#define CVMX_PCIERCX_CFG008(block_id) (0x0000000000000020ull)
+#define CVMX_PCIERCX_CFG009(block_id) (0x0000000000000024ull)
+#define CVMX_PCIERCX_CFG010(block_id) (0x0000000000000028ull)
+#define CVMX_PCIERCX_CFG011(block_id) (0x000000000000002Cull)
+#define CVMX_PCIERCX_CFG012(block_id) (0x0000000000000030ull)
+#define CVMX_PCIERCX_CFG013(block_id) (0x0000000000000034ull)
+#define CVMX_PCIERCX_CFG014(block_id) (0x0000000000000038ull)
+#define CVMX_PCIERCX_CFG015(block_id) (0x000000000000003Cull)
+#define CVMX_PCIERCX_CFG016(block_id) (0x0000000000000040ull)
+#define CVMX_PCIERCX_CFG017(block_id) (0x0000000000000044ull)
+#define CVMX_PCIERCX_CFG020(block_id) (0x0000000000000050ull)
+#define CVMX_PCIERCX_CFG021(block_id) (0x0000000000000054ull)
+#define CVMX_PCIERCX_CFG022(block_id) (0x0000000000000058ull)
+#define CVMX_PCIERCX_CFG023(block_id) (0x000000000000005Cull)
+#define CVMX_PCIERCX_CFG028(block_id) (0x0000000000000070ull)
+#define CVMX_PCIERCX_CFG029(block_id) (0x0000000000000074ull)
+#define CVMX_PCIERCX_CFG030(block_id) (0x0000000000000078ull)
+#define CVMX_PCIERCX_CFG031(block_id) (0x000000000000007Cull)
+#define CVMX_PCIERCX_CFG032(block_id) (0x0000000000000080ull)
+#define CVMX_PCIERCX_CFG033(block_id) (0x0000000000000084ull)
+#define CVMX_PCIERCX_CFG034(block_id) (0x0000000000000088ull)
+#define CVMX_PCIERCX_CFG035(block_id) (0x000000000000008Cull)
+#define CVMX_PCIERCX_CFG036(block_id) (0x0000000000000090ull)
+#define CVMX_PCIERCX_CFG037(block_id) (0x0000000000000094ull)
+#define CVMX_PCIERCX_CFG038(block_id) (0x0000000000000098ull)
+#define CVMX_PCIERCX_CFG039(block_id) (0x000000000000009Cull)
+#define CVMX_PCIERCX_CFG040(block_id) (0x00000000000000A0ull)
+#define CVMX_PCIERCX_CFG041(block_id) (0x00000000000000A4ull)
+#define CVMX_PCIERCX_CFG042(block_id) (0x00000000000000A8ull)
+#define CVMX_PCIERCX_CFG064(block_id) (0x0000000000000100ull)
+#define CVMX_PCIERCX_CFG065(block_id) (0x0000000000000104ull)
+#define CVMX_PCIERCX_CFG066(block_id) (0x0000000000000108ull)
+#define CVMX_PCIERCX_CFG067(block_id) (0x000000000000010Cull)
+#define CVMX_PCIERCX_CFG068(block_id) (0x0000000000000110ull)
+#define CVMX_PCIERCX_CFG069(block_id) (0x0000000000000114ull)
+#define CVMX_PCIERCX_CFG070(block_id) (0x0000000000000118ull)
+#define CVMX_PCIERCX_CFG071(block_id) (0x000000000000011Cull)
+#define CVMX_PCIERCX_CFG072(block_id) (0x0000000000000120ull)
+#define CVMX_PCIERCX_CFG073(block_id) (0x0000000000000124ull)
+#define CVMX_PCIERCX_CFG074(block_id) (0x0000000000000128ull)
+#define CVMX_PCIERCX_CFG075(block_id) (0x000000000000012Cull)
+#define CVMX_PCIERCX_CFG076(block_id) (0x0000000000000130ull)
+#define CVMX_PCIERCX_CFG077(block_id) (0x0000000000000134ull)
+#define CVMX_PCIERCX_CFG448(block_id) (0x0000000000000700ull)
+#define CVMX_PCIERCX_CFG449(block_id) (0x0000000000000704ull)
+#define CVMX_PCIERCX_CFG450(block_id) (0x0000000000000708ull)
+#define CVMX_PCIERCX_CFG451(block_id) (0x000000000000070Cull)
+#define CVMX_PCIERCX_CFG452(block_id) (0x0000000000000710ull)
+#define CVMX_PCIERCX_CFG453(block_id) (0x0000000000000714ull)
+#define CVMX_PCIERCX_CFG454(block_id) (0x0000000000000718ull)
+#define CVMX_PCIERCX_CFG455(block_id) (0x000000000000071Cull)
+#define CVMX_PCIERCX_CFG456(block_id) (0x0000000000000720ull)
+#define CVMX_PCIERCX_CFG458(block_id) (0x0000000000000728ull)
+#define CVMX_PCIERCX_CFG459(block_id) (0x000000000000072Cull)
+#define CVMX_PCIERCX_CFG460(block_id) (0x0000000000000730ull)
+#define CVMX_PCIERCX_CFG461(block_id) (0x0000000000000734ull)
+#define CVMX_PCIERCX_CFG462(block_id) (0x0000000000000738ull)
+#define CVMX_PCIERCX_CFG463(block_id) (0x000000000000073Cull)
+#define CVMX_PCIERCX_CFG464(block_id) (0x0000000000000740ull)
+#define CVMX_PCIERCX_CFG465(block_id) (0x0000000000000744ull)
+#define CVMX_PCIERCX_CFG466(block_id) (0x0000000000000748ull)
+#define CVMX_PCIERCX_CFG467(block_id) (0x000000000000074Cull)
+#define CVMX_PCIERCX_CFG468(block_id) (0x0000000000000750ull)
+#define CVMX_PCIERCX_CFG490(block_id) (0x00000000000007A8ull)
+#define CVMX_PCIERCX_CFG491(block_id) (0x00000000000007ACull)
+#define CVMX_PCIERCX_CFG492(block_id) (0x00000000000007B0ull)
+#define CVMX_PCIERCX_CFG515(block_id) (0x000000000000080Cull)
+#define CVMX_PCIERCX_CFG516(block_id) (0x0000000000000810ull)
+#define CVMX_PCIERCX_CFG517(block_id) (0x0000000000000814ull)
+
+union cvmx_pciercx_cfg000 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg000_s {
+ uint32_t devid:16;
+ uint32_t vendid:16;
+ } s;
+ struct cvmx_pciercx_cfg000_s cn52xx;
+ struct cvmx_pciercx_cfg000_s cn52xxp1;
+ struct cvmx_pciercx_cfg000_s cn56xx;
+ struct cvmx_pciercx_cfg000_s cn56xxp1;
+ struct cvmx_pciercx_cfg000_s cn63xx;
+ struct cvmx_pciercx_cfg000_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg001 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg001_s {
+ uint32_t dpe:1;
+ uint32_t sse:1;
+ uint32_t rma:1;
+ uint32_t rta:1;
+ uint32_t sta:1;
+ uint32_t devt:2;
+ uint32_t mdpe:1;
+ uint32_t fbb:1;
+ uint32_t reserved_22_22:1;
+ uint32_t m66:1;
+ uint32_t cl:1;
+ uint32_t i_stat:1;
+ uint32_t reserved_11_18:8;
+ uint32_t i_dis:1;
+ uint32_t fbbe:1;
+ uint32_t see:1;
+ uint32_t ids_wcc:1;
+ uint32_t per:1;
+ uint32_t vps:1;
+ uint32_t mwice:1;
+ uint32_t scse:1;
+ uint32_t me:1;
+ uint32_t msae:1;
+ uint32_t isae:1;
+ } s;
+ struct cvmx_pciercx_cfg001_s cn52xx;
+ struct cvmx_pciercx_cfg001_s cn52xxp1;
+ struct cvmx_pciercx_cfg001_s cn56xx;
+ struct cvmx_pciercx_cfg001_s cn56xxp1;
+ struct cvmx_pciercx_cfg001_s cn63xx;
+ struct cvmx_pciercx_cfg001_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg002 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg002_s {
+ uint32_t bcc:8;
+ uint32_t sc:8;
+ uint32_t pi:8;
+ uint32_t rid:8;
+ } s;
+ struct cvmx_pciercx_cfg002_s cn52xx;
+ struct cvmx_pciercx_cfg002_s cn52xxp1;
+ struct cvmx_pciercx_cfg002_s cn56xx;
+ struct cvmx_pciercx_cfg002_s cn56xxp1;
+ struct cvmx_pciercx_cfg002_s cn63xx;
+ struct cvmx_pciercx_cfg002_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg003 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg003_s {
+ uint32_t bist:8;
+ uint32_t mfd:1;
+ uint32_t chf:7;
+ uint32_t lt:8;
+ uint32_t cls:8;
+ } s;
+ struct cvmx_pciercx_cfg003_s cn52xx;
+ struct cvmx_pciercx_cfg003_s cn52xxp1;
+ struct cvmx_pciercx_cfg003_s cn56xx;
+ struct cvmx_pciercx_cfg003_s cn56xxp1;
+ struct cvmx_pciercx_cfg003_s cn63xx;
+ struct cvmx_pciercx_cfg003_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg004 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg004_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg004_s cn52xx;
+ struct cvmx_pciercx_cfg004_s cn52xxp1;
+ struct cvmx_pciercx_cfg004_s cn56xx;
+ struct cvmx_pciercx_cfg004_s cn56xxp1;
+ struct cvmx_pciercx_cfg004_s cn63xx;
+ struct cvmx_pciercx_cfg004_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg005 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg005_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg005_s cn52xx;
+ struct cvmx_pciercx_cfg005_s cn52xxp1;
+ struct cvmx_pciercx_cfg005_s cn56xx;
+ struct cvmx_pciercx_cfg005_s cn56xxp1;
+ struct cvmx_pciercx_cfg005_s cn63xx;
+ struct cvmx_pciercx_cfg005_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg006 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg006_s {
+ uint32_t slt:8;
+ uint32_t subbnum:8;
+ uint32_t sbnum:8;
+ uint32_t pbnum:8;
+ } s;
+ struct cvmx_pciercx_cfg006_s cn52xx;
+ struct cvmx_pciercx_cfg006_s cn52xxp1;
+ struct cvmx_pciercx_cfg006_s cn56xx;
+ struct cvmx_pciercx_cfg006_s cn56xxp1;
+ struct cvmx_pciercx_cfg006_s cn63xx;
+ struct cvmx_pciercx_cfg006_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg007 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg007_s {
+ uint32_t dpe:1;
+ uint32_t sse:1;
+ uint32_t rma:1;
+ uint32_t rta:1;
+ uint32_t sta:1;
+ uint32_t devt:2;
+ uint32_t mdpe:1;
+ uint32_t fbb:1;
+ uint32_t reserved_22_22:1;
+ uint32_t m66:1;
+ uint32_t reserved_16_20:5;
+ uint32_t lio_limi:4;
+ uint32_t reserved_9_11:3;
+ uint32_t io32b:1;
+ uint32_t lio_base:4;
+ uint32_t reserved_1_3:3;
+ uint32_t io32a:1;
+ } s;
+ struct cvmx_pciercx_cfg007_s cn52xx;
+ struct cvmx_pciercx_cfg007_s cn52xxp1;
+ struct cvmx_pciercx_cfg007_s cn56xx;
+ struct cvmx_pciercx_cfg007_s cn56xxp1;
+ struct cvmx_pciercx_cfg007_s cn63xx;
+ struct cvmx_pciercx_cfg007_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg008 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg008_s {
+ uint32_t ml_addr:12;
+ uint32_t reserved_16_19:4;
+ uint32_t mb_addr:12;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pciercx_cfg008_s cn52xx;
+ struct cvmx_pciercx_cfg008_s cn52xxp1;
+ struct cvmx_pciercx_cfg008_s cn56xx;
+ struct cvmx_pciercx_cfg008_s cn56xxp1;
+ struct cvmx_pciercx_cfg008_s cn63xx;
+ struct cvmx_pciercx_cfg008_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg009 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg009_s {
+ uint32_t lmem_limit:12;
+ uint32_t reserved_17_19:3;
+ uint32_t mem64b:1;
+ uint32_t lmem_base:12;
+ uint32_t reserved_1_3:3;
+ uint32_t mem64a:1;
+ } s;
+ struct cvmx_pciercx_cfg009_s cn52xx;
+ struct cvmx_pciercx_cfg009_s cn52xxp1;
+ struct cvmx_pciercx_cfg009_s cn56xx;
+ struct cvmx_pciercx_cfg009_s cn56xxp1;
+ struct cvmx_pciercx_cfg009_s cn63xx;
+ struct cvmx_pciercx_cfg009_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg010 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg010_s {
+ uint32_t umem_base:32;
+ } s;
+ struct cvmx_pciercx_cfg010_s cn52xx;
+ struct cvmx_pciercx_cfg010_s cn52xxp1;
+ struct cvmx_pciercx_cfg010_s cn56xx;
+ struct cvmx_pciercx_cfg010_s cn56xxp1;
+ struct cvmx_pciercx_cfg010_s cn63xx;
+ struct cvmx_pciercx_cfg010_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg011 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg011_s {
+ uint32_t umem_limit:32;
+ } s;
+ struct cvmx_pciercx_cfg011_s cn52xx;
+ struct cvmx_pciercx_cfg011_s cn52xxp1;
+ struct cvmx_pciercx_cfg011_s cn56xx;
+ struct cvmx_pciercx_cfg011_s cn56xxp1;
+ struct cvmx_pciercx_cfg011_s cn63xx;
+ struct cvmx_pciercx_cfg011_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg012 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg012_s {
+ uint32_t uio_limit:16;
+ uint32_t uio_base:16;
+ } s;
+ struct cvmx_pciercx_cfg012_s cn52xx;
+ struct cvmx_pciercx_cfg012_s cn52xxp1;
+ struct cvmx_pciercx_cfg012_s cn56xx;
+ struct cvmx_pciercx_cfg012_s cn56xxp1;
+ struct cvmx_pciercx_cfg012_s cn63xx;
+ struct cvmx_pciercx_cfg012_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg013 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg013_s {
+ uint32_t reserved_8_31:24;
+ uint32_t cp:8;
+ } s;
+ struct cvmx_pciercx_cfg013_s cn52xx;
+ struct cvmx_pciercx_cfg013_s cn52xxp1;
+ struct cvmx_pciercx_cfg013_s cn56xx;
+ struct cvmx_pciercx_cfg013_s cn56xxp1;
+ struct cvmx_pciercx_cfg013_s cn63xx;
+ struct cvmx_pciercx_cfg013_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg014 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg014_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg014_s cn52xx;
+ struct cvmx_pciercx_cfg014_s cn52xxp1;
+ struct cvmx_pciercx_cfg014_s cn56xx;
+ struct cvmx_pciercx_cfg014_s cn56xxp1;
+ struct cvmx_pciercx_cfg014_s cn63xx;
+ struct cvmx_pciercx_cfg014_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg015 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg015_s {
+ uint32_t reserved_28_31:4;
+ uint32_t dtsees:1;
+ uint32_t dts:1;
+ uint32_t sdt:1;
+ uint32_t pdt:1;
+ uint32_t fbbe:1;
+ uint32_t sbrst:1;
+ uint32_t mam:1;
+ uint32_t vga16d:1;
+ uint32_t vgae:1;
+ uint32_t isae:1;
+ uint32_t see:1;
+ uint32_t pere:1;
+ uint32_t inta:8;
+ uint32_t il:8;
+ } s;
+ struct cvmx_pciercx_cfg015_s cn52xx;
+ struct cvmx_pciercx_cfg015_s cn52xxp1;
+ struct cvmx_pciercx_cfg015_s cn56xx;
+ struct cvmx_pciercx_cfg015_s cn56xxp1;
+ struct cvmx_pciercx_cfg015_s cn63xx;
+ struct cvmx_pciercx_cfg015_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg016 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg016_s {
+ uint32_t pmes:5;
+ uint32_t d2s:1;
+ uint32_t d1s:1;
+ uint32_t auxc:3;
+ uint32_t dsi:1;
+ uint32_t reserved_20_20:1;
+ uint32_t pme_clock:1;
+ uint32_t pmsv:3;
+ uint32_t ncp:8;
+ uint32_t pmcid:8;
+ } s;
+ struct cvmx_pciercx_cfg016_s cn52xx;
+ struct cvmx_pciercx_cfg016_s cn52xxp1;
+ struct cvmx_pciercx_cfg016_s cn56xx;
+ struct cvmx_pciercx_cfg016_s cn56xxp1;
+ struct cvmx_pciercx_cfg016_s cn63xx;
+ struct cvmx_pciercx_cfg016_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg017 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg017_s {
+ uint32_t pmdia:8;
+ uint32_t bpccee:1;
+ uint32_t bd3h:1;
+ uint32_t reserved_16_21:6;
+ uint32_t pmess:1;
+ uint32_t pmedsia:2;
+ uint32_t pmds:4;
+ uint32_t pmeens:1;
+ uint32_t reserved_4_7:4;
+ uint32_t nsr:1;
+ uint32_t reserved_2_2:1;
+ uint32_t ps:2;
+ } s;
+ struct cvmx_pciercx_cfg017_s cn52xx;
+ struct cvmx_pciercx_cfg017_s cn52xxp1;
+ struct cvmx_pciercx_cfg017_s cn56xx;
+ struct cvmx_pciercx_cfg017_s cn56xxp1;
+ struct cvmx_pciercx_cfg017_s cn63xx;
+ struct cvmx_pciercx_cfg017_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg020 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg020_s {
+ uint32_t reserved_24_31:8;
+ uint32_t m64:1;
+ uint32_t mme:3;
+ uint32_t mmc:3;
+ uint32_t msien:1;
+ uint32_t ncp:8;
+ uint32_t msicid:8;
+ } s;
+ struct cvmx_pciercx_cfg020_s cn52xx;
+ struct cvmx_pciercx_cfg020_s cn52xxp1;
+ struct cvmx_pciercx_cfg020_s cn56xx;
+ struct cvmx_pciercx_cfg020_s cn56xxp1;
+ struct cvmx_pciercx_cfg020_s cn63xx;
+ struct cvmx_pciercx_cfg020_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg021 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg021_s {
+ uint32_t lmsi:30;
+ uint32_t reserved_0_1:2;
+ } s;
+ struct cvmx_pciercx_cfg021_s cn52xx;
+ struct cvmx_pciercx_cfg021_s cn52xxp1;
+ struct cvmx_pciercx_cfg021_s cn56xx;
+ struct cvmx_pciercx_cfg021_s cn56xxp1;
+ struct cvmx_pciercx_cfg021_s cn63xx;
+ struct cvmx_pciercx_cfg021_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg022 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg022_s {
+ uint32_t umsi:32;
+ } s;
+ struct cvmx_pciercx_cfg022_s cn52xx;
+ struct cvmx_pciercx_cfg022_s cn52xxp1;
+ struct cvmx_pciercx_cfg022_s cn56xx;
+ struct cvmx_pciercx_cfg022_s cn56xxp1;
+ struct cvmx_pciercx_cfg022_s cn63xx;
+ struct cvmx_pciercx_cfg022_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg023 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg023_s {
+ uint32_t reserved_16_31:16;
+ uint32_t msimd:16;
+ } s;
+ struct cvmx_pciercx_cfg023_s cn52xx;
+ struct cvmx_pciercx_cfg023_s cn52xxp1;
+ struct cvmx_pciercx_cfg023_s cn56xx;
+ struct cvmx_pciercx_cfg023_s cn56xxp1;
+ struct cvmx_pciercx_cfg023_s cn63xx;
+ struct cvmx_pciercx_cfg023_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg028 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg028_s {
+ uint32_t reserved_30_31:2;
+ uint32_t imn:5;
+ uint32_t si:1;
+ uint32_t dpt:4;
+ uint32_t pciecv:4;
+ uint32_t ncp:8;
+ uint32_t pcieid:8;
+ } s;
+ struct cvmx_pciercx_cfg028_s cn52xx;
+ struct cvmx_pciercx_cfg028_s cn52xxp1;
+ struct cvmx_pciercx_cfg028_s cn56xx;
+ struct cvmx_pciercx_cfg028_s cn56xxp1;
+ struct cvmx_pciercx_cfg028_s cn63xx;
+ struct cvmx_pciercx_cfg028_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg029 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg029_s {
+ uint32_t reserved_28_31:4;
+ uint32_t cspls:2;
+ uint32_t csplv:8;
+ uint32_t reserved_16_17:2;
+ uint32_t rber:1;
+ uint32_t reserved_12_14:3;
+ uint32_t el1al:3;
+ uint32_t el0al:3;
+ uint32_t etfs:1;
+ uint32_t pfs:2;
+ uint32_t mpss:3;
+ } s;
+ struct cvmx_pciercx_cfg029_s cn52xx;
+ struct cvmx_pciercx_cfg029_s cn52xxp1;
+ struct cvmx_pciercx_cfg029_s cn56xx;
+ struct cvmx_pciercx_cfg029_s cn56xxp1;
+ struct cvmx_pciercx_cfg029_s cn63xx;
+ struct cvmx_pciercx_cfg029_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg030 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg030_s {
+ uint32_t reserved_22_31:10;
+ uint32_t tp:1;
+ uint32_t ap_d:1;
+ uint32_t ur_d:1;
+ uint32_t fe_d:1;
+ uint32_t nfe_d:1;
+ uint32_t ce_d:1;
+ uint32_t reserved_15_15:1;
+ uint32_t mrrs:3;
+ uint32_t ns_en:1;
+ uint32_t ap_en:1;
+ uint32_t pf_en:1;
+ uint32_t etf_en:1;
+ uint32_t mps:3;
+ uint32_t ro_en:1;
+ uint32_t ur_en:1;
+ uint32_t fe_en:1;
+ uint32_t nfe_en:1;
+ uint32_t ce_en:1;
+ } s;
+ struct cvmx_pciercx_cfg030_s cn52xx;
+ struct cvmx_pciercx_cfg030_s cn52xxp1;
+ struct cvmx_pciercx_cfg030_s cn56xx;
+ struct cvmx_pciercx_cfg030_s cn56xxp1;
+ struct cvmx_pciercx_cfg030_s cn63xx;
+ struct cvmx_pciercx_cfg030_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg031 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg031_s {
+ uint32_t pnum:8;
+ uint32_t reserved_22_23:2;
+ uint32_t lbnc:1;
+ uint32_t dllarc:1;
+ uint32_t sderc:1;
+ uint32_t cpm:1;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t aslpms:2;
+ uint32_t mlw:6;
+ uint32_t mls:4;
+ } s;
+ struct cvmx_pciercx_cfg031_s cn52xx;
+ struct cvmx_pciercx_cfg031_s cn52xxp1;
+ struct cvmx_pciercx_cfg031_s cn56xx;
+ struct cvmx_pciercx_cfg031_s cn56xxp1;
+ struct cvmx_pciercx_cfg031_s cn63xx;
+ struct cvmx_pciercx_cfg031_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg032 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg032_s {
+ uint32_t lab:1;
+ uint32_t lbm:1;
+ uint32_t dlla:1;
+ uint32_t scc:1;
+ uint32_t lt:1;
+ uint32_t reserved_26_26:1;
+ uint32_t nlw:6;
+ uint32_t ls:4;
+ uint32_t reserved_12_15:4;
+ uint32_t lab_int_enb:1;
+ uint32_t lbm_int_enb:1;
+ uint32_t hawd:1;
+ uint32_t ecpm:1;
+ uint32_t es:1;
+ uint32_t ccc:1;
+ uint32_t rl:1;
+ uint32_t ld:1;
+ uint32_t rcb:1;
+ uint32_t reserved_2_2:1;
+ uint32_t aslpc:2;
+ } s;
+ struct cvmx_pciercx_cfg032_s cn52xx;
+ struct cvmx_pciercx_cfg032_s cn52xxp1;
+ struct cvmx_pciercx_cfg032_s cn56xx;
+ struct cvmx_pciercx_cfg032_s cn56xxp1;
+ struct cvmx_pciercx_cfg032_s cn63xx;
+ struct cvmx_pciercx_cfg032_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg033 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg033_s {
+ uint32_t ps_num:13;
+ uint32_t nccs:1;
+ uint32_t emip:1;
+ uint32_t sp_ls:2;
+ uint32_t sp_lv:8;
+ uint32_t hp_c:1;
+ uint32_t hp_s:1;
+ uint32_t pip:1;
+ uint32_t aip:1;
+ uint32_t mrlsp:1;
+ uint32_t pcp:1;
+ uint32_t abp:1;
+ } s;
+ struct cvmx_pciercx_cfg033_s cn52xx;
+ struct cvmx_pciercx_cfg033_s cn52xxp1;
+ struct cvmx_pciercx_cfg033_s cn56xx;
+ struct cvmx_pciercx_cfg033_s cn56xxp1;
+ struct cvmx_pciercx_cfg033_s cn63xx;
+ struct cvmx_pciercx_cfg033_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg034 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg034_s {
+ uint32_t reserved_25_31:7;
+ uint32_t dlls_c:1;
+ uint32_t emis:1;
+ uint32_t pds:1;
+ uint32_t mrlss:1;
+ uint32_t ccint_d:1;
+ uint32_t pd_c:1;
+ uint32_t mrls_c:1;
+ uint32_t pf_d:1;
+ uint32_t abp_d:1;
+ uint32_t reserved_13_15:3;
+ uint32_t dlls_en:1;
+ uint32_t emic:1;
+ uint32_t pcc:1;
+ uint32_t pic:2;
+ uint32_t aic:2;
+ uint32_t hpint_en:1;
+ uint32_t ccint_en:1;
+ uint32_t pd_en:1;
+ uint32_t mrls_en:1;
+ uint32_t pf_en:1;
+ uint32_t abp_en:1;
+ } s;
+ struct cvmx_pciercx_cfg034_s cn52xx;
+ struct cvmx_pciercx_cfg034_s cn52xxp1;
+ struct cvmx_pciercx_cfg034_s cn56xx;
+ struct cvmx_pciercx_cfg034_s cn56xxp1;
+ struct cvmx_pciercx_cfg034_s cn63xx;
+ struct cvmx_pciercx_cfg034_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg035 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg035_s {
+ uint32_t reserved_17_31:15;
+ uint32_t crssv:1;
+ uint32_t reserved_5_15:11;
+ uint32_t crssve:1;
+ uint32_t pmeie:1;
+ uint32_t sefee:1;
+ uint32_t senfee:1;
+ uint32_t secee:1;
+ } s;
+ struct cvmx_pciercx_cfg035_s cn52xx;
+ struct cvmx_pciercx_cfg035_s cn52xxp1;
+ struct cvmx_pciercx_cfg035_s cn56xx;
+ struct cvmx_pciercx_cfg035_s cn56xxp1;
+ struct cvmx_pciercx_cfg035_s cn63xx;
+ struct cvmx_pciercx_cfg035_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg036 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg036_s {
+ uint32_t reserved_18_31:14;
+ uint32_t pme_pend:1;
+ uint32_t pme_stat:1;
+ uint32_t pme_rid:16;
+ } s;
+ struct cvmx_pciercx_cfg036_s cn52xx;
+ struct cvmx_pciercx_cfg036_s cn52xxp1;
+ struct cvmx_pciercx_cfg036_s cn56xx;
+ struct cvmx_pciercx_cfg036_s cn56xxp1;
+ struct cvmx_pciercx_cfg036_s cn63xx;
+ struct cvmx_pciercx_cfg036_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg037 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg037_s {
+ uint32_t reserved_5_31:27;
+ uint32_t ctds:1;
+ uint32_t ctrs:4;
+ } s;
+ struct cvmx_pciercx_cfg037_s cn52xx;
+ struct cvmx_pciercx_cfg037_s cn52xxp1;
+ struct cvmx_pciercx_cfg037_s cn56xx;
+ struct cvmx_pciercx_cfg037_s cn56xxp1;
+ struct cvmx_pciercx_cfg037_s cn63xx;
+ struct cvmx_pciercx_cfg037_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg038 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg038_s {
+ uint32_t reserved_5_31:27;
+ uint32_t ctd:1;
+ uint32_t ctv:4;
+ } s;
+ struct cvmx_pciercx_cfg038_s cn52xx;
+ struct cvmx_pciercx_cfg038_s cn52xxp1;
+ struct cvmx_pciercx_cfg038_s cn56xx;
+ struct cvmx_pciercx_cfg038_s cn56xxp1;
+ struct cvmx_pciercx_cfg038_s cn63xx;
+ struct cvmx_pciercx_cfg038_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg039 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg039_s {
+ uint32_t reserved_9_31:23;
+ uint32_t cls:1;
+ uint32_t slsv:7;
+ uint32_t reserved_0_0:1;
+ } s;
+ struct cvmx_pciercx_cfg039_cn52xx {
+ uint32_t reserved_0_31:32;
+ } cn52xx;
+ struct cvmx_pciercx_cfg039_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg039_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg039_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg039_s cn63xx;
+ struct cvmx_pciercx_cfg039_cn52xx cn63xxp1;
+};
+
+union cvmx_pciercx_cfg040 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg040_s {
+ uint32_t reserved_17_31:15;
+ uint32_t cdl:1;
+ uint32_t reserved_13_15:3;
+ uint32_t cde:1;
+ uint32_t csos:1;
+ uint32_t emc:1;
+ uint32_t tm:3;
+ uint32_t sde:1;
+ uint32_t hasd:1;
+ uint32_t ec:1;
+ uint32_t tls:4;
+ } s;
+ struct cvmx_pciercx_cfg040_cn52xx {
+ uint32_t reserved_0_31:32;
+ } cn52xx;
+ struct cvmx_pciercx_cfg040_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg040_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg040_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg040_s cn63xx;
+ struct cvmx_pciercx_cfg040_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg041 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg041_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg041_s cn52xx;
+ struct cvmx_pciercx_cfg041_s cn52xxp1;
+ struct cvmx_pciercx_cfg041_s cn56xx;
+ struct cvmx_pciercx_cfg041_s cn56xxp1;
+ struct cvmx_pciercx_cfg041_s cn63xx;
+ struct cvmx_pciercx_cfg041_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg042 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg042_s {
+ uint32_t reserved_0_31:32;
+ } s;
+ struct cvmx_pciercx_cfg042_s cn52xx;
+ struct cvmx_pciercx_cfg042_s cn52xxp1;
+ struct cvmx_pciercx_cfg042_s cn56xx;
+ struct cvmx_pciercx_cfg042_s cn56xxp1;
+ struct cvmx_pciercx_cfg042_s cn63xx;
+ struct cvmx_pciercx_cfg042_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg064 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg064_s {
+ uint32_t nco:12;
+ uint32_t cv:4;
+ uint32_t pcieec:16;
+ } s;
+ struct cvmx_pciercx_cfg064_s cn52xx;
+ struct cvmx_pciercx_cfg064_s cn52xxp1;
+ struct cvmx_pciercx_cfg064_s cn56xx;
+ struct cvmx_pciercx_cfg064_s cn56xxp1;
+ struct cvmx_pciercx_cfg064_s cn63xx;
+ struct cvmx_pciercx_cfg064_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg065 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg065_s {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pciercx_cfg065_s cn52xx;
+ struct cvmx_pciercx_cfg065_s cn52xxp1;
+ struct cvmx_pciercx_cfg065_s cn56xx;
+ struct cvmx_pciercx_cfg065_s cn56xxp1;
+ struct cvmx_pciercx_cfg065_s cn63xx;
+ struct cvmx_pciercx_cfg065_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg066 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg066_s {
+ uint32_t reserved_21_31:11;
+ uint32_t urem:1;
+ uint32_t ecrcem:1;
+ uint32_t mtlpm:1;
+ uint32_t rom:1;
+ uint32_t ucm:1;
+ uint32_t cam:1;
+ uint32_t ctm:1;
+ uint32_t fcpem:1;
+ uint32_t ptlpm:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdem:1;
+ uint32_t dlpem:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pciercx_cfg066_s cn52xx;
+ struct cvmx_pciercx_cfg066_s cn52xxp1;
+ struct cvmx_pciercx_cfg066_s cn56xx;
+ struct cvmx_pciercx_cfg066_s cn56xxp1;
+ struct cvmx_pciercx_cfg066_s cn63xx;
+ struct cvmx_pciercx_cfg066_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg067 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg067_s {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } s;
+ struct cvmx_pciercx_cfg067_s cn52xx;
+ struct cvmx_pciercx_cfg067_s cn52xxp1;
+ struct cvmx_pciercx_cfg067_s cn56xx;
+ struct cvmx_pciercx_cfg067_s cn56xxp1;
+ struct cvmx_pciercx_cfg067_s cn63xx;
+ struct cvmx_pciercx_cfg067_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg068 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg068_s {
+ uint32_t reserved_14_31:18;
+ uint32_t anfes:1;
+ uint32_t rtts:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrs:1;
+ uint32_t bdllps:1;
+ uint32_t btlps:1;
+ uint32_t reserved_1_5:5;
+ uint32_t res:1;
+ } s;
+ struct cvmx_pciercx_cfg068_s cn52xx;
+ struct cvmx_pciercx_cfg068_s cn52xxp1;
+ struct cvmx_pciercx_cfg068_s cn56xx;
+ struct cvmx_pciercx_cfg068_s cn56xxp1;
+ struct cvmx_pciercx_cfg068_s cn63xx;
+ struct cvmx_pciercx_cfg068_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg069 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg069_s {
+ uint32_t reserved_14_31:18;
+ uint32_t anfem:1;
+ uint32_t rttm:1;
+ uint32_t reserved_9_11:3;
+ uint32_t rnrm:1;
+ uint32_t bdllpm:1;
+ uint32_t btlpm:1;
+ uint32_t reserved_1_5:5;
+ uint32_t rem:1;
+ } s;
+ struct cvmx_pciercx_cfg069_s cn52xx;
+ struct cvmx_pciercx_cfg069_s cn52xxp1;
+ struct cvmx_pciercx_cfg069_s cn56xx;
+ struct cvmx_pciercx_cfg069_s cn56xxp1;
+ struct cvmx_pciercx_cfg069_s cn63xx;
+ struct cvmx_pciercx_cfg069_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg070 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg070_s {
+ uint32_t reserved_9_31:23;
+ uint32_t ce:1;
+ uint32_t cc:1;
+ uint32_t ge:1;
+ uint32_t gc:1;
+ uint32_t fep:5;
+ } s;
+ struct cvmx_pciercx_cfg070_s cn52xx;
+ struct cvmx_pciercx_cfg070_s cn52xxp1;
+ struct cvmx_pciercx_cfg070_s cn56xx;
+ struct cvmx_pciercx_cfg070_s cn56xxp1;
+ struct cvmx_pciercx_cfg070_s cn63xx;
+ struct cvmx_pciercx_cfg070_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg071 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg071_s {
+ uint32_t dword1:32;
+ } s;
+ struct cvmx_pciercx_cfg071_s cn52xx;
+ struct cvmx_pciercx_cfg071_s cn52xxp1;
+ struct cvmx_pciercx_cfg071_s cn56xx;
+ struct cvmx_pciercx_cfg071_s cn56xxp1;
+ struct cvmx_pciercx_cfg071_s cn63xx;
+ struct cvmx_pciercx_cfg071_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg072 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg072_s {
+ uint32_t dword2:32;
+ } s;
+ struct cvmx_pciercx_cfg072_s cn52xx;
+ struct cvmx_pciercx_cfg072_s cn52xxp1;
+ struct cvmx_pciercx_cfg072_s cn56xx;
+ struct cvmx_pciercx_cfg072_s cn56xxp1;
+ struct cvmx_pciercx_cfg072_s cn63xx;
+ struct cvmx_pciercx_cfg072_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg073 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg073_s {
+ uint32_t dword3:32;
+ } s;
+ struct cvmx_pciercx_cfg073_s cn52xx;
+ struct cvmx_pciercx_cfg073_s cn52xxp1;
+ struct cvmx_pciercx_cfg073_s cn56xx;
+ struct cvmx_pciercx_cfg073_s cn56xxp1;
+ struct cvmx_pciercx_cfg073_s cn63xx;
+ struct cvmx_pciercx_cfg073_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg074 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg074_s {
+ uint32_t dword4:32;
+ } s;
+ struct cvmx_pciercx_cfg074_s cn52xx;
+ struct cvmx_pciercx_cfg074_s cn52xxp1;
+ struct cvmx_pciercx_cfg074_s cn56xx;
+ struct cvmx_pciercx_cfg074_s cn56xxp1;
+ struct cvmx_pciercx_cfg074_s cn63xx;
+ struct cvmx_pciercx_cfg074_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg075 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg075_s {
+ uint32_t reserved_3_31:29;
+ uint32_t fere:1;
+ uint32_t nfere:1;
+ uint32_t cere:1;
+ } s;
+ struct cvmx_pciercx_cfg075_s cn52xx;
+ struct cvmx_pciercx_cfg075_s cn52xxp1;
+ struct cvmx_pciercx_cfg075_s cn56xx;
+ struct cvmx_pciercx_cfg075_s cn56xxp1;
+ struct cvmx_pciercx_cfg075_s cn63xx;
+ struct cvmx_pciercx_cfg075_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg076 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg076_s {
+ uint32_t aeimn:5;
+ uint32_t reserved_7_26:20;
+ uint32_t femr:1;
+ uint32_t nfemr:1;
+ uint32_t fuf:1;
+ uint32_t multi_efnfr:1;
+ uint32_t efnfr:1;
+ uint32_t multi_ecr:1;
+ uint32_t ecr:1;
+ } s;
+ struct cvmx_pciercx_cfg076_s cn52xx;
+ struct cvmx_pciercx_cfg076_s cn52xxp1;
+ struct cvmx_pciercx_cfg076_s cn56xx;
+ struct cvmx_pciercx_cfg076_s cn56xxp1;
+ struct cvmx_pciercx_cfg076_s cn63xx;
+ struct cvmx_pciercx_cfg076_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg077 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg077_s {
+ uint32_t efnfsi:16;
+ uint32_t ecsi:16;
+ } s;
+ struct cvmx_pciercx_cfg077_s cn52xx;
+ struct cvmx_pciercx_cfg077_s cn52xxp1;
+ struct cvmx_pciercx_cfg077_s cn56xx;
+ struct cvmx_pciercx_cfg077_s cn56xxp1;
+ struct cvmx_pciercx_cfg077_s cn63xx;
+ struct cvmx_pciercx_cfg077_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg448 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg448_s {
+ uint32_t rtl:16;
+ uint32_t rtltl:16;
+ } s;
+ struct cvmx_pciercx_cfg448_s cn52xx;
+ struct cvmx_pciercx_cfg448_s cn52xxp1;
+ struct cvmx_pciercx_cfg448_s cn56xx;
+ struct cvmx_pciercx_cfg448_s cn56xxp1;
+ struct cvmx_pciercx_cfg448_s cn63xx;
+ struct cvmx_pciercx_cfg448_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg449 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg449_s {
+ uint32_t omr:32;
+ } s;
+ struct cvmx_pciercx_cfg449_s cn52xx;
+ struct cvmx_pciercx_cfg449_s cn52xxp1;
+ struct cvmx_pciercx_cfg449_s cn56xx;
+ struct cvmx_pciercx_cfg449_s cn56xxp1;
+ struct cvmx_pciercx_cfg449_s cn63xx;
+ struct cvmx_pciercx_cfg449_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg450 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg450_s {
+ uint32_t lpec:8;
+ uint32_t reserved_22_23:2;
+ uint32_t link_state:6;
+ uint32_t force_link:1;
+ uint32_t reserved_8_14:7;
+ uint32_t link_num:8;
+ } s;
+ struct cvmx_pciercx_cfg450_s cn52xx;
+ struct cvmx_pciercx_cfg450_s cn52xxp1;
+ struct cvmx_pciercx_cfg450_s cn56xx;
+ struct cvmx_pciercx_cfg450_s cn56xxp1;
+ struct cvmx_pciercx_cfg450_s cn63xx;
+ struct cvmx_pciercx_cfg450_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg451 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg451_s {
+ uint32_t reserved_30_31:2;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t n_fts_cc:8;
+ uint32_t n_fts:8;
+ uint32_t ack_freq:8;
+ } s;
+ struct cvmx_pciercx_cfg451_s cn52xx;
+ struct cvmx_pciercx_cfg451_s cn52xxp1;
+ struct cvmx_pciercx_cfg451_s cn56xx;
+ struct cvmx_pciercx_cfg451_s cn56xxp1;
+ struct cvmx_pciercx_cfg451_s cn63xx;
+ struct cvmx_pciercx_cfg451_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg452 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg452_s {
+ uint32_t reserved_26_31:6;
+ uint32_t eccrc:1;
+ uint32_t reserved_22_24:3;
+ uint32_t lme:6;
+ uint32_t reserved_8_15:8;
+ uint32_t flm:1;
+ uint32_t reserved_6_6:1;
+ uint32_t dllle:1;
+ uint32_t reserved_4_4:1;
+ uint32_t ra:1;
+ uint32_t le:1;
+ uint32_t sd:1;
+ uint32_t omr:1;
+ } s;
+ struct cvmx_pciercx_cfg452_s cn52xx;
+ struct cvmx_pciercx_cfg452_s cn52xxp1;
+ struct cvmx_pciercx_cfg452_s cn56xx;
+ struct cvmx_pciercx_cfg452_s cn56xxp1;
+ struct cvmx_pciercx_cfg452_s cn63xx;
+ struct cvmx_pciercx_cfg452_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg453 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg453_s {
+ uint32_t dlld:1;
+ uint32_t reserved_26_30:5;
+ uint32_t ack_nak:1;
+ uint32_t fcd:1;
+ uint32_t ilst:24;
+ } s;
+ struct cvmx_pciercx_cfg453_s cn52xx;
+ struct cvmx_pciercx_cfg453_s cn52xxp1;
+ struct cvmx_pciercx_cfg453_s cn56xx;
+ struct cvmx_pciercx_cfg453_s cn56xxp1;
+ struct cvmx_pciercx_cfg453_s cn63xx;
+ struct cvmx_pciercx_cfg453_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg454 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg454_s {
+ uint32_t reserved_29_31:3;
+ uint32_t tmfcwt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmrt:5;
+ uint32_t reserved_11_13:3;
+ uint32_t nskps:3;
+ uint32_t reserved_4_7:4;
+ uint32_t ntss:4;
+ } s;
+ struct cvmx_pciercx_cfg454_s cn52xx;
+ struct cvmx_pciercx_cfg454_s cn52xxp1;
+ struct cvmx_pciercx_cfg454_s cn56xx;
+ struct cvmx_pciercx_cfg454_s cn56xxp1;
+ struct cvmx_pciercx_cfg454_s cn63xx;
+ struct cvmx_pciercx_cfg454_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg455 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg455_s {
+ uint32_t m_cfg0_filt:1;
+ uint32_t m_io_filt:1;
+ uint32_t msg_ctrl:1;
+ uint32_t m_cpl_ecrc_filt:1;
+ uint32_t m_ecrc_filt:1;
+ uint32_t m_cpl_len_err:1;
+ uint32_t m_cpl_attr_err:1;
+ uint32_t m_cpl_tc_err:1;
+ uint32_t m_cpl_fun_err:1;
+ uint32_t m_cpl_rid_err:1;
+ uint32_t m_cpl_tag_err:1;
+ uint32_t m_lk_filt:1;
+ uint32_t m_cfg1_filt:1;
+ uint32_t m_bar_match:1;
+ uint32_t m_pois_filt:1;
+ uint32_t m_fun:1;
+ uint32_t dfcwt:1;
+ uint32_t reserved_11_14:4;
+ uint32_t skpiv:11;
+ } s;
+ struct cvmx_pciercx_cfg455_s cn52xx;
+ struct cvmx_pciercx_cfg455_s cn52xxp1;
+ struct cvmx_pciercx_cfg455_s cn56xx;
+ struct cvmx_pciercx_cfg455_s cn56xxp1;
+ struct cvmx_pciercx_cfg455_s cn63xx;
+ struct cvmx_pciercx_cfg455_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg456 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg456_s {
+ uint32_t reserved_2_31:30;
+ uint32_t m_vend1_drp:1;
+ uint32_t m_vend0_drp:1;
+ } s;
+ struct cvmx_pciercx_cfg456_s cn52xx;
+ struct cvmx_pciercx_cfg456_s cn52xxp1;
+ struct cvmx_pciercx_cfg456_s cn56xx;
+ struct cvmx_pciercx_cfg456_s cn56xxp1;
+ struct cvmx_pciercx_cfg456_s cn63xx;
+ struct cvmx_pciercx_cfg456_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg458 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg458_s {
+ uint32_t dbg_info_l32:32;
+ } s;
+ struct cvmx_pciercx_cfg458_s cn52xx;
+ struct cvmx_pciercx_cfg458_s cn52xxp1;
+ struct cvmx_pciercx_cfg458_s cn56xx;
+ struct cvmx_pciercx_cfg458_s cn56xxp1;
+ struct cvmx_pciercx_cfg458_s cn63xx;
+ struct cvmx_pciercx_cfg458_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg459 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg459_s {
+ uint32_t dbg_info_u32:32;
+ } s;
+ struct cvmx_pciercx_cfg459_s cn52xx;
+ struct cvmx_pciercx_cfg459_s cn52xxp1;
+ struct cvmx_pciercx_cfg459_s cn56xx;
+ struct cvmx_pciercx_cfg459_s cn56xxp1;
+ struct cvmx_pciercx_cfg459_s cn63xx;
+ struct cvmx_pciercx_cfg459_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg460 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg460_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tphfcc:8;
+ uint32_t tpdfcc:12;
+ } s;
+ struct cvmx_pciercx_cfg460_s cn52xx;
+ struct cvmx_pciercx_cfg460_s cn52xxp1;
+ struct cvmx_pciercx_cfg460_s cn56xx;
+ struct cvmx_pciercx_cfg460_s cn56xxp1;
+ struct cvmx_pciercx_cfg460_s cn63xx;
+ struct cvmx_pciercx_cfg460_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg461 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg461_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tchfcc:8;
+ uint32_t tcdfcc:12;
+ } s;
+ struct cvmx_pciercx_cfg461_s cn52xx;
+ struct cvmx_pciercx_cfg461_s cn52xxp1;
+ struct cvmx_pciercx_cfg461_s cn56xx;
+ struct cvmx_pciercx_cfg461_s cn56xxp1;
+ struct cvmx_pciercx_cfg461_s cn63xx;
+ struct cvmx_pciercx_cfg461_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg462 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg462_s {
+ uint32_t reserved_20_31:12;
+ uint32_t tchfcc:8;
+ uint32_t tcdfcc:12;
+ } s;
+ struct cvmx_pciercx_cfg462_s cn52xx;
+ struct cvmx_pciercx_cfg462_s cn52xxp1;
+ struct cvmx_pciercx_cfg462_s cn56xx;
+ struct cvmx_pciercx_cfg462_s cn56xxp1;
+ struct cvmx_pciercx_cfg462_s cn63xx;
+ struct cvmx_pciercx_cfg462_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg463 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg463_s {
+ uint32_t reserved_3_31:29;
+ uint32_t rqne:1;
+ uint32_t trbne:1;
+ uint32_t rtlpfccnr:1;
+ } s;
+ struct cvmx_pciercx_cfg463_s cn52xx;
+ struct cvmx_pciercx_cfg463_s cn52xxp1;
+ struct cvmx_pciercx_cfg463_s cn56xx;
+ struct cvmx_pciercx_cfg463_s cn56xxp1;
+ struct cvmx_pciercx_cfg463_s cn63xx;
+ struct cvmx_pciercx_cfg463_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg464 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg464_s {
+ uint32_t wrr_vc3:8;
+ uint32_t wrr_vc2:8;
+ uint32_t wrr_vc1:8;
+ uint32_t wrr_vc0:8;
+ } s;
+ struct cvmx_pciercx_cfg464_s cn52xx;
+ struct cvmx_pciercx_cfg464_s cn52xxp1;
+ struct cvmx_pciercx_cfg464_s cn56xx;
+ struct cvmx_pciercx_cfg464_s cn56xxp1;
+ struct cvmx_pciercx_cfg464_s cn63xx;
+ struct cvmx_pciercx_cfg464_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg465 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg465_s {
+ uint32_t wrr_vc7:8;
+ uint32_t wrr_vc6:8;
+ uint32_t wrr_vc5:8;
+ uint32_t wrr_vc4:8;
+ } s;
+ struct cvmx_pciercx_cfg465_s cn52xx;
+ struct cvmx_pciercx_cfg465_s cn52xxp1;
+ struct cvmx_pciercx_cfg465_s cn56xx;
+ struct cvmx_pciercx_cfg465_s cn56xxp1;
+ struct cvmx_pciercx_cfg465_s cn63xx;
+ struct cvmx_pciercx_cfg465_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg466 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg466_s {
+ uint32_t rx_queue_order:1;
+ uint32_t type_ordering:1;
+ uint32_t reserved_24_29:6;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pciercx_cfg466_s cn52xx;
+ struct cvmx_pciercx_cfg466_s cn52xxp1;
+ struct cvmx_pciercx_cfg466_s cn56xx;
+ struct cvmx_pciercx_cfg466_s cn56xxp1;
+ struct cvmx_pciercx_cfg466_s cn63xx;
+ struct cvmx_pciercx_cfg466_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg467 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg467_s {
+ uint32_t reserved_24_31:8;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pciercx_cfg467_s cn52xx;
+ struct cvmx_pciercx_cfg467_s cn52xxp1;
+ struct cvmx_pciercx_cfg467_s cn56xx;
+ struct cvmx_pciercx_cfg467_s cn56xxp1;
+ struct cvmx_pciercx_cfg467_s cn63xx;
+ struct cvmx_pciercx_cfg467_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg468 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg468_s {
+ uint32_t reserved_24_31:8;
+ uint32_t queue_mode:3;
+ uint32_t reserved_20_20:1;
+ uint32_t header_credits:8;
+ uint32_t data_credits:12;
+ } s;
+ struct cvmx_pciercx_cfg468_s cn52xx;
+ struct cvmx_pciercx_cfg468_s cn52xxp1;
+ struct cvmx_pciercx_cfg468_s cn56xx;
+ struct cvmx_pciercx_cfg468_s cn56xxp1;
+ struct cvmx_pciercx_cfg468_s cn63xx;
+ struct cvmx_pciercx_cfg468_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg490 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg490_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pciercx_cfg490_s cn52xx;
+ struct cvmx_pciercx_cfg490_s cn52xxp1;
+ struct cvmx_pciercx_cfg490_s cn56xx;
+ struct cvmx_pciercx_cfg490_s cn56xxp1;
+ struct cvmx_pciercx_cfg490_s cn63xx;
+ struct cvmx_pciercx_cfg490_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg491 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg491_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pciercx_cfg491_s cn52xx;
+ struct cvmx_pciercx_cfg491_s cn52xxp1;
+ struct cvmx_pciercx_cfg491_s cn56xx;
+ struct cvmx_pciercx_cfg491_s cn56xxp1;
+ struct cvmx_pciercx_cfg491_s cn63xx;
+ struct cvmx_pciercx_cfg491_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg492 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg492_s {
+ uint32_t reserved_26_31:6;
+ uint32_t header_depth:10;
+ uint32_t reserved_14_15:2;
+ uint32_t data_depth:14;
+ } s;
+ struct cvmx_pciercx_cfg492_s cn52xx;
+ struct cvmx_pciercx_cfg492_s cn52xxp1;
+ struct cvmx_pciercx_cfg492_s cn56xx;
+ struct cvmx_pciercx_cfg492_s cn56xxp1;
+ struct cvmx_pciercx_cfg492_s cn63xx;
+ struct cvmx_pciercx_cfg492_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg515 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg515_s {
+ uint32_t reserved_21_31:11;
+ uint32_t s_d_e:1;
+ uint32_t ctcrb:1;
+ uint32_t cpyts:1;
+ uint32_t dsc:1;
+ uint32_t le:9;
+ uint32_t n_fts:8;
+ } s;
+ struct cvmx_pciercx_cfg515_s cn63xx;
+ struct cvmx_pciercx_cfg515_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg516 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg516_s {
+ uint32_t phy_stat:32;
+ } s;
+ struct cvmx_pciercx_cfg516_s cn52xx;
+ struct cvmx_pciercx_cfg516_s cn52xxp1;
+ struct cvmx_pciercx_cfg516_s cn56xx;
+ struct cvmx_pciercx_cfg516_s cn56xxp1;
+ struct cvmx_pciercx_cfg516_s cn63xx;
+ struct cvmx_pciercx_cfg516_s cn63xxp1;
+};
+
+union cvmx_pciercx_cfg517 {
+ uint32_t u32;
+ struct cvmx_pciercx_cfg517_s {
+ uint32_t phy_ctrl:32;
+ } s;
+ struct cvmx_pciercx_cfg517_s cn52xx;
+ struct cvmx_pciercx_cfg517_s cn52xxp1;
+ struct cvmx_pciercx_cfg517_s cn56xx;
+ struct cvmx_pciercx_cfg517_s cn56xxp1;
+ struct cvmx_pciercx_cfg517_s cn63xx;
+ struct cvmx_pciercx_cfg517_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
new file mode 100644
index 00000000..aef84851
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
@@ -0,0 +1,394 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PESCX_DEFS_H__
+#define __CVMX_PESCX_DEFS_H__
+
+#define CVMX_PESCX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000018ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_BIST_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000418ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CFG_RD(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000030ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CFG_WR(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000028ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CPL_LUT_VALID(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000098ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000000ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_CTL_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000400ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DBG_INFO(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000008ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DBG_INFO_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800C80000A0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_DIAG_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000020ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR0_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000080ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR1_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000088ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2N_BAR2_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000090ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_PESCX_P2P_BARX_END(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000048ull) + (((offset) & 3) + ((block_id) & 1) * 0x800000ull) * 16)
+#define CVMX_PESCX_P2P_BARX_START(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000040ull) + (((offset) & 3) + ((block_id) & 1) * 0x800000ull) * 16)
+#define CVMX_PESCX_TLP_CREDITS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000038ull) + ((block_id) & 1) * 0x8000000ull)
+
+union cvmx_pescx_bist_status {
+ uint64_t u64;
+ struct cvmx_pescx_bist_status_s {
+ uint64_t reserved_13_63:51;
+ uint64_t rqdata5:1;
+ uint64_t ctlp_or:1;
+ uint64_t ntlp_or:1;
+ uint64_t ptlp_or:1;
+ uint64_t retry:1;
+ uint64_t rqdata0:1;
+ uint64_t rqdata1:1;
+ uint64_t rqdata2:1;
+ uint64_t rqdata3:1;
+ uint64_t rqdata4:1;
+ uint64_t rqhdr1:1;
+ uint64_t rqhdr0:1;
+ uint64_t sot:1;
+ } s;
+ struct cvmx_pescx_bist_status_s cn52xx;
+ struct cvmx_pescx_bist_status_cn52xxp1 {
+ uint64_t reserved_12_63:52;
+ uint64_t ctlp_or:1;
+ uint64_t ntlp_or:1;
+ uint64_t ptlp_or:1;
+ uint64_t retry:1;
+ uint64_t rqdata0:1;
+ uint64_t rqdata1:1;
+ uint64_t rqdata2:1;
+ uint64_t rqdata3:1;
+ uint64_t rqdata4:1;
+ uint64_t rqhdr1:1;
+ uint64_t rqhdr0:1;
+ uint64_t sot:1;
+ } cn52xxp1;
+ struct cvmx_pescx_bist_status_s cn56xx;
+ struct cvmx_pescx_bist_status_cn52xxp1 cn56xxp1;
+};
+
+union cvmx_pescx_bist_status2 {
+ uint64_t u64;
+ struct cvmx_pescx_bist_status2_s {
+ uint64_t reserved_14_63:50;
+ uint64_t cto_p2e:1;
+ uint64_t e2p_cpl:1;
+ uint64_t e2p_n:1;
+ uint64_t e2p_p:1;
+ uint64_t e2p_rsl:1;
+ uint64_t dbg_p2e:1;
+ uint64_t peai_p2e:1;
+ uint64_t rsl_p2e:1;
+ uint64_t pef_tpf1:1;
+ uint64_t pef_tpf0:1;
+ uint64_t pef_tnf:1;
+ uint64_t pef_tcf1:1;
+ uint64_t pef_tc0:1;
+ uint64_t ppf:1;
+ } s;
+ struct cvmx_pescx_bist_status2_s cn52xx;
+ struct cvmx_pescx_bist_status2_s cn52xxp1;
+ struct cvmx_pescx_bist_status2_s cn56xx;
+ struct cvmx_pescx_bist_status2_s cn56xxp1;
+};
+
+union cvmx_pescx_cfg_rd {
+ uint64_t u64;
+ struct cvmx_pescx_cfg_rd_s {
+ uint64_t data:32;
+ uint64_t addr:32;
+ } s;
+ struct cvmx_pescx_cfg_rd_s cn52xx;
+ struct cvmx_pescx_cfg_rd_s cn52xxp1;
+ struct cvmx_pescx_cfg_rd_s cn56xx;
+ struct cvmx_pescx_cfg_rd_s cn56xxp1;
+};
+
+union cvmx_pescx_cfg_wr {
+ uint64_t u64;
+ struct cvmx_pescx_cfg_wr_s {
+ uint64_t data:32;
+ uint64_t addr:32;
+ } s;
+ struct cvmx_pescx_cfg_wr_s cn52xx;
+ struct cvmx_pescx_cfg_wr_s cn52xxp1;
+ struct cvmx_pescx_cfg_wr_s cn56xx;
+ struct cvmx_pescx_cfg_wr_s cn56xxp1;
+};
+
+union cvmx_pescx_cpl_lut_valid {
+ uint64_t u64;
+ struct cvmx_pescx_cpl_lut_valid_s {
+ uint64_t reserved_32_63:32;
+ uint64_t tag:32;
+ } s;
+ struct cvmx_pescx_cpl_lut_valid_s cn52xx;
+ struct cvmx_pescx_cpl_lut_valid_s cn52xxp1;
+ struct cvmx_pescx_cpl_lut_valid_s cn56xx;
+ struct cvmx_pescx_cpl_lut_valid_s cn56xxp1;
+};
+
+union cvmx_pescx_ctl_status {
+ uint64_t u64;
+ struct cvmx_pescx_ctl_status_s {
+ uint64_t reserved_28_63:36;
+ uint64_t dnum:5;
+ uint64_t pbus:8;
+ uint64_t qlm_cfg:2;
+ uint64_t lane_swp:1;
+ uint64_t pm_xtoff:1;
+ uint64_t pm_xpme:1;
+ uint64_t ob_p_cmd:1;
+ uint64_t reserved_7_8:2;
+ uint64_t nf_ecrc:1;
+ uint64_t dly_one:1;
+ uint64_t lnk_enb:1;
+ uint64_t ro_ctlp:1;
+ uint64_t reserved_2_2:1;
+ uint64_t inv_ecrc:1;
+ uint64_t inv_lcrc:1;
+ } s;
+ struct cvmx_pescx_ctl_status_s cn52xx;
+ struct cvmx_pescx_ctl_status_s cn52xxp1;
+ struct cvmx_pescx_ctl_status_cn56xx {
+ uint64_t reserved_28_63:36;
+ uint64_t dnum:5;
+ uint64_t pbus:8;
+ uint64_t qlm_cfg:2;
+ uint64_t reserved_12_12:1;
+ uint64_t pm_xtoff:1;
+ uint64_t pm_xpme:1;
+ uint64_t ob_p_cmd:1;
+ uint64_t reserved_7_8:2;
+ uint64_t nf_ecrc:1;
+ uint64_t dly_one:1;
+ uint64_t lnk_enb:1;
+ uint64_t ro_ctlp:1;
+ uint64_t reserved_2_2:1;
+ uint64_t inv_ecrc:1;
+ uint64_t inv_lcrc:1;
+ } cn56xx;
+ struct cvmx_pescx_ctl_status_cn56xx cn56xxp1;
+};
+
+union cvmx_pescx_ctl_status2 {
+ uint64_t u64;
+ struct cvmx_pescx_ctl_status2_s {
+ uint64_t reserved_2_63:62;
+ uint64_t pclk_run:1;
+ uint64_t pcierst:1;
+ } s;
+ struct cvmx_pescx_ctl_status2_s cn52xx;
+ struct cvmx_pescx_ctl_status2_cn52xxp1 {
+ uint64_t reserved_1_63:63;
+ uint64_t pcierst:1;
+ } cn52xxp1;
+ struct cvmx_pescx_ctl_status2_s cn56xx;
+ struct cvmx_pescx_ctl_status2_cn52xxp1 cn56xxp1;
+};
+
+union cvmx_pescx_dbg_info {
+ uint64_t u64;
+ struct cvmx_pescx_dbg_info_s {
+ uint64_t reserved_31_63:33;
+ uint64_t ecrc_e:1;
+ uint64_t rawwpp:1;
+ uint64_t racpp:1;
+ uint64_t ramtlp:1;
+ uint64_t rarwdns:1;
+ uint64_t caar:1;
+ uint64_t racca:1;
+ uint64_t racur:1;
+ uint64_t rauc:1;
+ uint64_t rqo:1;
+ uint64_t fcuv:1;
+ uint64_t rpe:1;
+ uint64_t fcpvwt:1;
+ uint64_t dpeoosd:1;
+ uint64_t rtwdle:1;
+ uint64_t rdwdle:1;
+ uint64_t mre:1;
+ uint64_t rte:1;
+ uint64_t acto:1;
+ uint64_t rvdm:1;
+ uint64_t rumep:1;
+ uint64_t rptamrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rfemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rcemrc:1;
+ uint64_t rpoison:1;
+ uint64_t recrce:1;
+ uint64_t rtlplle:1;
+ uint64_t rtlpmal:1;
+ uint64_t spoison:1;
+ } s;
+ struct cvmx_pescx_dbg_info_s cn52xx;
+ struct cvmx_pescx_dbg_info_s cn52xxp1;
+ struct cvmx_pescx_dbg_info_s cn56xx;
+ struct cvmx_pescx_dbg_info_s cn56xxp1;
+};
+
+union cvmx_pescx_dbg_info_en {
+ uint64_t u64;
+ struct cvmx_pescx_dbg_info_en_s {
+ uint64_t reserved_31_63:33;
+ uint64_t ecrc_e:1;
+ uint64_t rawwpp:1;
+ uint64_t racpp:1;
+ uint64_t ramtlp:1;
+ uint64_t rarwdns:1;
+ uint64_t caar:1;
+ uint64_t racca:1;
+ uint64_t racur:1;
+ uint64_t rauc:1;
+ uint64_t rqo:1;
+ uint64_t fcuv:1;
+ uint64_t rpe:1;
+ uint64_t fcpvwt:1;
+ uint64_t dpeoosd:1;
+ uint64_t rtwdle:1;
+ uint64_t rdwdle:1;
+ uint64_t mre:1;
+ uint64_t rte:1;
+ uint64_t acto:1;
+ uint64_t rvdm:1;
+ uint64_t rumep:1;
+ uint64_t rptamrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rfemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rcemrc:1;
+ uint64_t rpoison:1;
+ uint64_t recrce:1;
+ uint64_t rtlplle:1;
+ uint64_t rtlpmal:1;
+ uint64_t spoison:1;
+ } s;
+ struct cvmx_pescx_dbg_info_en_s cn52xx;
+ struct cvmx_pescx_dbg_info_en_s cn52xxp1;
+ struct cvmx_pescx_dbg_info_en_s cn56xx;
+ struct cvmx_pescx_dbg_info_en_s cn56xxp1;
+};
+
+union cvmx_pescx_diag_status {
+ uint64_t u64;
+ struct cvmx_pescx_diag_status_s {
+ uint64_t reserved_4_63:60;
+ uint64_t pm_dst:1;
+ uint64_t pm_stat:1;
+ uint64_t pm_en:1;
+ uint64_t aux_en:1;
+ } s;
+ struct cvmx_pescx_diag_status_s cn52xx;
+ struct cvmx_pescx_diag_status_s cn52xxp1;
+ struct cvmx_pescx_diag_status_s cn56xx;
+ struct cvmx_pescx_diag_status_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar0_start {
+ uint64_t u64;
+ struct cvmx_pescx_p2n_bar0_start_s {
+ uint64_t addr:50;
+ uint64_t reserved_0_13:14;
+ } s;
+ struct cvmx_pescx_p2n_bar0_start_s cn52xx;
+ struct cvmx_pescx_p2n_bar0_start_s cn52xxp1;
+ struct cvmx_pescx_p2n_bar0_start_s cn56xx;
+ struct cvmx_pescx_p2n_bar0_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar1_start {
+ uint64_t u64;
+ struct cvmx_pescx_p2n_bar1_start_s {
+ uint64_t addr:38;
+ uint64_t reserved_0_25:26;
+ } s;
+ struct cvmx_pescx_p2n_bar1_start_s cn52xx;
+ struct cvmx_pescx_p2n_bar1_start_s cn52xxp1;
+ struct cvmx_pescx_p2n_bar1_start_s cn56xx;
+ struct cvmx_pescx_p2n_bar1_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar2_start {
+ uint64_t u64;
+ struct cvmx_pescx_p2n_bar2_start_s {
+ uint64_t addr:25;
+ uint64_t reserved_0_38:39;
+ } s;
+ struct cvmx_pescx_p2n_bar2_start_s cn52xx;
+ struct cvmx_pescx_p2n_bar2_start_s cn52xxp1;
+ struct cvmx_pescx_p2n_bar2_start_s cn56xx;
+ struct cvmx_pescx_p2n_bar2_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2p_barx_end {
+ uint64_t u64;
+ struct cvmx_pescx_p2p_barx_end_s {
+ uint64_t addr:52;
+ uint64_t reserved_0_11:12;
+ } s;
+ struct cvmx_pescx_p2p_barx_end_s cn52xx;
+ struct cvmx_pescx_p2p_barx_end_s cn52xxp1;
+ struct cvmx_pescx_p2p_barx_end_s cn56xx;
+ struct cvmx_pescx_p2p_barx_end_s cn56xxp1;
+};
+
+union cvmx_pescx_p2p_barx_start {
+ uint64_t u64;
+ struct cvmx_pescx_p2p_barx_start_s {
+ uint64_t addr:52;
+ uint64_t reserved_0_11:12;
+ } s;
+ struct cvmx_pescx_p2p_barx_start_s cn52xx;
+ struct cvmx_pescx_p2p_barx_start_s cn52xxp1;
+ struct cvmx_pescx_p2p_barx_start_s cn56xx;
+ struct cvmx_pescx_p2p_barx_start_s cn56xxp1;
+};
+
+union cvmx_pescx_tlp_credits {
+ uint64_t u64;
+ struct cvmx_pescx_tlp_credits_s {
+ uint64_t reserved_0_63:64;
+ } s;
+ struct cvmx_pescx_tlp_credits_cn52xx {
+ uint64_t reserved_56_63:8;
+ uint64_t peai_ppf:8;
+ uint64_t pesc_cpl:8;
+ uint64_t pesc_np:8;
+ uint64_t pesc_p:8;
+ uint64_t npei_cpl:8;
+ uint64_t npei_np:8;
+ uint64_t npei_p:8;
+ } cn52xx;
+ struct cvmx_pescx_tlp_credits_cn52xxp1 {
+ uint64_t reserved_38_63:26;
+ uint64_t peai_ppf:8;
+ uint64_t pesc_cpl:5;
+ uint64_t pesc_np:5;
+ uint64_t pesc_p:5;
+ uint64_t npei_cpl:5;
+ uint64_t npei_np:5;
+ uint64_t npei_p:5;
+ } cn52xxp1;
+ struct cvmx_pescx_tlp_credits_cn52xx cn56xx;
+ struct cvmx_pescx_tlp_credits_cn52xxp1 cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
new file mode 100644
index 00000000..5ab8679d
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
@@ -0,0 +1,225 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * cvmx-pexp-defs.h
+ *
+ * Configuration and status register (CSR) definitions for
+ * OCTEON PEXP.
+ *
+ */
+#ifndef __CVMX_PEXP_DEFS_H__
+#define __CVMX_PEXP_DEFS_H__
+
+#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) (CVMX_ADD_IO_SEG(0x00011F0000008000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000008580ull))
+#define CVMX_PEXP_NPEI_BIST_STATUS2 (CVMX_ADD_IO_SEG(0x00011F0000008680ull))
+#define CVMX_PEXP_NPEI_CTL_PORT0 (CVMX_ADD_IO_SEG(0x00011F0000008250ull))
+#define CVMX_PEXP_NPEI_CTL_PORT1 (CVMX_ADD_IO_SEG(0x00011F0000008260ull))
+#define CVMX_PEXP_NPEI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000008570ull))
+#define CVMX_PEXP_NPEI_CTL_STATUS2 (CVMX_ADD_IO_SEG(0x00011F000000BC00ull))
+#define CVMX_PEXP_NPEI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000085F0ull))
+#define CVMX_PEXP_NPEI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000008510ull))
+#define CVMX_PEXP_NPEI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000008500ull))
+#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL (CVMX_ADD_IO_SEG(0x00011F00000085C0ull))
+#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL (CVMX_ADD_IO_SEG(0x00011F00000085D0ull))
+#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000008450ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F00000083B0ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000008400ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) (CVMX_ADD_IO_SEG(0x00011F00000084A0ull) + ((offset) & 7) * 16)
+#define CVMX_PEXP_NPEI_DMA_CNTS (CVMX_ADD_IO_SEG(0x00011F00000085E0ull))
+#define CVMX_PEXP_NPEI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x00011F00000083A0ull))
+#define CVMX_PEXP_NPEI_DMA_PCIE_REQ_NUM (CVMX_ADD_IO_SEG(0x00011F00000085B0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE1 (CVMX_ADD_IO_SEG(0x00011F00000086C0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE1_P1 (CVMX_ADD_IO_SEG(0x00011F0000008680ull))
+#define CVMX_PEXP_NPEI_DMA_STATE2 (CVMX_ADD_IO_SEG(0x00011F00000086D0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE2_P1 (CVMX_ADD_IO_SEG(0x00011F0000008690ull))
+#define CVMX_PEXP_NPEI_DMA_STATE3_P1 (CVMX_ADD_IO_SEG(0x00011F00000086A0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE4_P1 (CVMX_ADD_IO_SEG(0x00011F00000086B0ull))
+#define CVMX_PEXP_NPEI_DMA_STATE5_P1 (CVMX_ADD_IO_SEG(0x00011F00000086C0ull))
+#define CVMX_PEXP_NPEI_INT_A_ENB (CVMX_ADD_IO_SEG(0x00011F0000008560ull))
+#define CVMX_PEXP_NPEI_INT_A_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BCE0ull))
+#define CVMX_PEXP_NPEI_INT_A_SUM (CVMX_ADD_IO_SEG(0x00011F0000008550ull))
+#define CVMX_PEXP_NPEI_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000008540ull))
+#define CVMX_PEXP_NPEI_INT_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BCD0ull))
+#define CVMX_PEXP_NPEI_INT_INFO (CVMX_ADD_IO_SEG(0x00011F0000008590ull))
+#define CVMX_PEXP_NPEI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000008530ull))
+#define CVMX_PEXP_NPEI_INT_SUM2 (CVMX_ADD_IO_SEG(0x00011F000000BCC0ull))
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000008600ull))
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000008610ull))
+#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000084F0ull))
+#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F0000008280ull) + ((offset) & 31) * 16 - 16*12)
+#define CVMX_PEXP_NPEI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BC50ull))
+#define CVMX_PEXP_NPEI_MSI_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BC60ull))
+#define CVMX_PEXP_NPEI_MSI_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BC70ull))
+#define CVMX_PEXP_NPEI_MSI_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BC80ull))
+#define CVMX_PEXP_NPEI_MSI_RCV0 (CVMX_ADD_IO_SEG(0x00011F000000BC10ull))
+#define CVMX_PEXP_NPEI_MSI_RCV1 (CVMX_ADD_IO_SEG(0x00011F000000BC20ull))
+#define CVMX_PEXP_NPEI_MSI_RCV2 (CVMX_ADD_IO_SEG(0x00011F000000BC30ull))
+#define CVMX_PEXP_NPEI_MSI_RCV3 (CVMX_ADD_IO_SEG(0x00011F000000BC40ull))
+#define CVMX_PEXP_NPEI_MSI_RD_MAP (CVMX_ADD_IO_SEG(0x00011F000000BCA0ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BCF0ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BD00ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BD10ull))
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BD20ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 (CVMX_ADD_IO_SEG(0x00011F000000BD30ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 (CVMX_ADD_IO_SEG(0x00011F000000BD40ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 (CVMX_ADD_IO_SEG(0x00011F000000BD50ull))
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 (CVMX_ADD_IO_SEG(0x00011F000000BD60ull))
+#define CVMX_PEXP_NPEI_MSI_WR_MAP (CVMX_ADD_IO_SEG(0x00011F000000BC90ull))
+#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F000000BD70ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F000000BCB0ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 (CVMX_ADD_IO_SEG(0x00011F0000008650ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 (CVMX_ADD_IO_SEG(0x00011F0000008660ull))
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 (CVMX_ADD_IO_SEG(0x00011F0000008670ull))
+#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F000000A400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F000000A800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F000000AC00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F000000B000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) (CVMX_ADD_IO_SEG(0x00011F000000B400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) (CVMX_ADD_IO_SEG(0x00011F000000B800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000009400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000009800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000009C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKT_CNT_INT (CVMX_ADD_IO_SEG(0x00011F0000009110ull))
+#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009130ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES (CVMX_ADD_IO_SEG(0x00011F00000090B0ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS (CVMX_ADD_IO_SEG(0x00011F00000090A0ull))
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR (CVMX_ADD_IO_SEG(0x00011F0000009090ull))
+#define CVMX_PEXP_NPEI_PKT_DPADDR (CVMX_ADD_IO_SEG(0x00011F0000009080ull))
+#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000009150ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_ENB (CVMX_ADD_IO_SEG(0x00011F0000009000ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009190ull))
+#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009020ull))
+#define CVMX_PEXP_NPEI_PKT_INT_LEVELS (CVMX_ADD_IO_SEG(0x00011F0000009100ull))
+#define CVMX_PEXP_NPEI_PKT_IN_BP (CVMX_ADD_IO_SEG(0x00011F00000086B0ull))
+#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F000000A000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS (CVMX_ADD_IO_SEG(0x00011F00000086A0ull))
+#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000091A0ull))
+#define CVMX_PEXP_NPEI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000009070ull))
+#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000009160ull))
+#define CVMX_PEXP_NPEI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000090D0ull))
+#define CVMX_PEXP_NPEI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009010ull))
+#define CVMX_PEXP_NPEI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000090E0ull))
+#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F0000008690ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ES (CVMX_ADD_IO_SEG(0x00011F0000009050ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE (CVMX_ADD_IO_SEG(0x00011F0000009180ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_NS (CVMX_ADD_IO_SEG(0x00011F0000009040ull))
+#define CVMX_PEXP_NPEI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000009030ull))
+#define CVMX_PEXP_NPEI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000009120ull))
+#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000009140ull))
+#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS (CVMX_ADD_IO_SEG(0x00011F0000008520ull))
+#define CVMX_PEXP_NPEI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F0000008270ull))
+#define CVMX_PEXP_NPEI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000008620ull))
+#define CVMX_PEXP_NPEI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000008630ull))
+#define CVMX_PEXP_NPEI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000008640ull))
+#define CVMX_PEXP_NPEI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F0000008380ull))
+#define CVMX_PEXP_SLI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010580ull))
+#define CVMX_PEXP_SLI_CTL_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010050ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010570ull))
+#define CVMX_PEXP_SLI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000105F0ull))
+#define CVMX_PEXP_SLI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000010310ull))
+#define CVMX_PEXP_SLI_DBG_SELECT (CVMX_ADD_IO_SEG(0x00011F0000010300ull))
+#define CVMX_PEXP_SLI_DMAX_CNT(offset) (CVMX_ADD_IO_SEG(0x00011F0000010400ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_DMAX_INT_LEVEL(offset) (CVMX_ADD_IO_SEG(0x00011F00000103E0ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_DMAX_TIM(offset) (CVMX_ADD_IO_SEG(0x00011F0000010420ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_INT_ENB_CIU (CVMX_ADD_IO_SEG(0x00011F0000013CD0ull))
+#define CVMX_PEXP_SLI_INT_ENB_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010340ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000010330ull))
+#define CVMX_PEXP_SLI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000010600ull))
+#define CVMX_PEXP_SLI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000010610ull))
+#define CVMX_PEXP_SLI_MAC_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F0000013D70ull))
+#define CVMX_PEXP_SLI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000102F0ull))
+#define CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F00000100E0ull) + ((offset) & 31) * 16 - 16*12)
+#define CVMX_PEXP_SLI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013C50ull))
+#define CVMX_PEXP_SLI_MSI_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013C60ull))
+#define CVMX_PEXP_SLI_MSI_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013C70ull))
+#define CVMX_PEXP_SLI_MSI_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013C80ull))
+#define CVMX_PEXP_SLI_MSI_RCV0 (CVMX_ADD_IO_SEG(0x00011F0000013C10ull))
+#define CVMX_PEXP_SLI_MSI_RCV1 (CVMX_ADD_IO_SEG(0x00011F0000013C20ull))
+#define CVMX_PEXP_SLI_MSI_RCV2 (CVMX_ADD_IO_SEG(0x00011F0000013C30ull))
+#define CVMX_PEXP_SLI_MSI_RCV3 (CVMX_ADD_IO_SEG(0x00011F0000013C40ull))
+#define CVMX_PEXP_SLI_MSI_RD_MAP (CVMX_ADD_IO_SEG(0x00011F0000013CA0ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013CF0ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013D00ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013D10ull))
+#define CVMX_PEXP_SLI_MSI_W1C_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013D20ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013D30ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB1 (CVMX_ADD_IO_SEG(0x00011F0000013D40ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB2 (CVMX_ADD_IO_SEG(0x00011F0000013D50ull))
+#define CVMX_PEXP_SLI_MSI_W1S_ENB3 (CVMX_ADD_IO_SEG(0x00011F0000013D60ull))
+#define CVMX_PEXP_SLI_MSI_WR_MAP (CVMX_ADD_IO_SEG(0x00011F0000013C90ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV (CVMX_ADD_IO_SEG(0x00011F0000013CB0ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B1 (CVMX_ADD_IO_SEG(0x00011F0000010650ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B2 (CVMX_ADD_IO_SEG(0x00011F0000010660ull))
+#define CVMX_PEXP_SLI_PCIE_MSI_RCV_B3 (CVMX_ADD_IO_SEG(0x00011F0000010670ull))
+#define CVMX_PEXP_SLI_PKTX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000012400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000012800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000012C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000013000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_INSTR_HEADER(offset) (CVMX_ADD_IO_SEG(0x00011F0000013400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_IN_BP(offset) (CVMX_ADD_IO_SEG(0x00011F0000013800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_OUT_SIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000010C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_BADDR(offset) (CVMX_ADD_IO_SEG(0x00011F0000011400ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_BAOFF_DBELL(offset) (CVMX_ADD_IO_SEG(0x00011F0000011800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKTX_SLIST_FIFO_RSIZE(offset) (CVMX_ADD_IO_SEG(0x00011F0000011C00ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKT_CNT_INT (CVMX_ADD_IO_SEG(0x00011F0000011130ull))
+#define CVMX_PEXP_SLI_PKT_CNT_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011150ull))
+#define CVMX_PEXP_SLI_PKT_CTL (CVMX_ADD_IO_SEG(0x00011F0000011220ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_ES (CVMX_ADD_IO_SEG(0x00011F00000110B0ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_NS (CVMX_ADD_IO_SEG(0x00011F00000110A0ull))
+#define CVMX_PEXP_SLI_PKT_DATA_OUT_ROR (CVMX_ADD_IO_SEG(0x00011F0000011090ull))
+#define CVMX_PEXP_SLI_PKT_DPADDR (CVMX_ADD_IO_SEG(0x00011F0000011080ull))
+#define CVMX_PEXP_SLI_PKT_INPUT_CONTROL (CVMX_ADD_IO_SEG(0x00011F0000011170ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_ENB (CVMX_ADD_IO_SEG(0x00011F0000011000ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_RD_SIZE (CVMX_ADD_IO_SEG(0x00011F00000111A0ull))
+#define CVMX_PEXP_SLI_PKT_INSTR_SIZE (CVMX_ADD_IO_SEG(0x00011F0000011020ull))
+#define CVMX_PEXP_SLI_PKT_INT_LEVELS (CVMX_ADD_IO_SEG(0x00011F0000011120ull))
+#define CVMX_PEXP_SLI_PKT_IN_BP (CVMX_ADD_IO_SEG(0x00011F0000011210ull))
+#define CVMX_PEXP_SLI_PKT_IN_DONEX_CNTS(offset) (CVMX_ADD_IO_SEG(0x00011F0000012000ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_PKT_IN_INSTR_COUNTS (CVMX_ADD_IO_SEG(0x00011F0000011200ull))
+#define CVMX_PEXP_SLI_PKT_IN_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000111B0ull))
+#define CVMX_PEXP_SLI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000011070ull))
+#define CVMX_PEXP_SLI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000011180ull))
+#define CVMX_PEXP_SLI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000110D0ull))
+#define CVMX_PEXP_SLI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011010ull))
+#define CVMX_PEXP_SLI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000110E0ull))
+#define CVMX_PEXP_SLI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F00000111F0ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_ES (CVMX_ADD_IO_SEG(0x00011F0000011050ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_NS (CVMX_ADD_IO_SEG(0x00011F0000011040ull))
+#define CVMX_PEXP_SLI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000011030ull))
+#define CVMX_PEXP_SLI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000011140ull))
+#define CVMX_PEXP_SLI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011160ull))
+#define CVMX_PEXP_SLI_S2M_PORTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011F0000013D80ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F00000103C0ull))
+#define CVMX_PEXP_SLI_SCRATCH_2 (CVMX_ADD_IO_SEG(0x00011F00000103D0ull))
+#define CVMX_PEXP_SLI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000010620ull))
+#define CVMX_PEXP_SLI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000010630ull))
+#define CVMX_PEXP_SLI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000010640ull))
+#define CVMX_PEXP_SLI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F00000102E0ull))
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pow-defs.h b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
new file mode 100644
index 00000000..39fd75b0
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
@@ -0,0 +1,761 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_POW_DEFS_H__
+#define __CVMX_POW_DEFS_H__
+
+#define CVMX_POW_BIST_STAT (CVMX_ADD_IO_SEG(0x00016700000003F8ull))
+#define CVMX_POW_DS_PC (CVMX_ADD_IO_SEG(0x0001670000000398ull))
+#define CVMX_POW_ECC_ERR (CVMX_ADD_IO_SEG(0x0001670000000218ull))
+#define CVMX_POW_INT_CTL (CVMX_ADD_IO_SEG(0x0001670000000220ull))
+#define CVMX_POW_IQ_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001670000000340ull) + ((offset) & 7) * 8)
+#define CVMX_POW_IQ_COM_CNT (CVMX_ADD_IO_SEG(0x0001670000000388ull))
+#define CVMX_POW_IQ_INT (CVMX_ADD_IO_SEG(0x0001670000000238ull))
+#define CVMX_POW_IQ_INT_EN (CVMX_ADD_IO_SEG(0x0001670000000240ull))
+#define CVMX_POW_IQ_THRX(offset) (CVMX_ADD_IO_SEG(0x00016700000003A0ull) + ((offset) & 7) * 8)
+#define CVMX_POW_NOS_CNT (CVMX_ADD_IO_SEG(0x0001670000000228ull))
+#define CVMX_POW_NW_TIM (CVMX_ADD_IO_SEG(0x0001670000000210ull))
+#define CVMX_POW_PF_RST_MSK (CVMX_ADD_IO_SEG(0x0001670000000230ull))
+#define CVMX_POW_PP_GRP_MSKX(offset) (CVMX_ADD_IO_SEG(0x0001670000000000ull) + ((offset) & 15) * 8)
+#define CVMX_POW_QOS_RNDX(offset) (CVMX_ADD_IO_SEG(0x00016700000001C0ull) + ((offset) & 7) * 8)
+#define CVMX_POW_QOS_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000180ull) + ((offset) & 7) * 8)
+#define CVMX_POW_TS_PC (CVMX_ADD_IO_SEG(0x0001670000000390ull))
+#define CVMX_POW_WA_COM_PC (CVMX_ADD_IO_SEG(0x0001670000000380ull))
+#define CVMX_POW_WA_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000300ull) + ((offset) & 7) * 8)
+#define CVMX_POW_WQ_INT (CVMX_ADD_IO_SEG(0x0001670000000200ull))
+#define CVMX_POW_WQ_INT_CNTX(offset) (CVMX_ADD_IO_SEG(0x0001670000000100ull) + ((offset) & 15) * 8)
+#define CVMX_POW_WQ_INT_PC (CVMX_ADD_IO_SEG(0x0001670000000208ull))
+#define CVMX_POW_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000080ull) + ((offset) & 15) * 8)
+#define CVMX_POW_WS_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000280ull) + ((offset) & 15) * 8)
+
+union cvmx_pow_bist_stat {
+ uint64_t u64;
+ struct cvmx_pow_bist_stat_s {
+ uint64_t reserved_32_63:32;
+ uint64_t pp:16;
+ uint64_t reserved_0_15:16;
+ } s;
+ struct cvmx_pow_bist_stat_cn30xx {
+ uint64_t reserved_17_63:47;
+ uint64_t pp:1;
+ uint64_t reserved_9_15:7;
+ uint64_t cam:1;
+ uint64_t nbt1:1;
+ uint64_t nbt0:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+ } cn30xx;
+ struct cvmx_pow_bist_stat_cn31xx {
+ uint64_t reserved_18_63:46;
+ uint64_t pp:2;
+ uint64_t reserved_9_15:7;
+ uint64_t cam:1;
+ uint64_t nbt1:1;
+ uint64_t nbt0:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+ } cn31xx;
+ struct cvmx_pow_bist_stat_cn38xx {
+ uint64_t reserved_32_63:32;
+ uint64_t pp:16;
+ uint64_t reserved_10_15:6;
+ uint64_t cam:1;
+ uint64_t nbt:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend1:1;
+ uint64_t pend0:1;
+ uint64_t adr1:1;
+ uint64_t adr0:1;
+ } cn38xx;
+ struct cvmx_pow_bist_stat_cn38xx cn38xxp2;
+ struct cvmx_pow_bist_stat_cn31xx cn50xx;
+ struct cvmx_pow_bist_stat_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t pp:4;
+ uint64_t reserved_9_15:7;
+ uint64_t cam:1;
+ uint64_t nbt1:1;
+ uint64_t nbt0:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+ } cn52xx;
+ struct cvmx_pow_bist_stat_cn52xx cn52xxp1;
+ struct cvmx_pow_bist_stat_cn56xx {
+ uint64_t reserved_28_63:36;
+ uint64_t pp:12;
+ uint64_t reserved_10_15:6;
+ uint64_t cam:1;
+ uint64_t nbt:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend1:1;
+ uint64_t pend0:1;
+ uint64_t adr1:1;
+ uint64_t adr0:1;
+ } cn56xx;
+ struct cvmx_pow_bist_stat_cn56xx cn56xxp1;
+ struct cvmx_pow_bist_stat_cn38xx cn58xx;
+ struct cvmx_pow_bist_stat_cn38xx cn58xxp1;
+ struct cvmx_pow_bist_stat_cn63xx {
+ uint64_t reserved_22_63:42;
+ uint64_t pp:6;
+ uint64_t reserved_12_15:4;
+ uint64_t cam:1;
+ uint64_t nbr:3;
+ uint64_t nbt:4;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+ } cn63xx;
+ struct cvmx_pow_bist_stat_cn63xx cn63xxp1;
+};
+
+union cvmx_pow_ds_pc {
+ uint64_t u64;
+ struct cvmx_pow_ds_pc_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ds_pc:32;
+ } s;
+ struct cvmx_pow_ds_pc_s cn30xx;
+ struct cvmx_pow_ds_pc_s cn31xx;
+ struct cvmx_pow_ds_pc_s cn38xx;
+ struct cvmx_pow_ds_pc_s cn38xxp2;
+ struct cvmx_pow_ds_pc_s cn50xx;
+ struct cvmx_pow_ds_pc_s cn52xx;
+ struct cvmx_pow_ds_pc_s cn52xxp1;
+ struct cvmx_pow_ds_pc_s cn56xx;
+ struct cvmx_pow_ds_pc_s cn56xxp1;
+ struct cvmx_pow_ds_pc_s cn58xx;
+ struct cvmx_pow_ds_pc_s cn58xxp1;
+ struct cvmx_pow_ds_pc_s cn63xx;
+ struct cvmx_pow_ds_pc_s cn63xxp1;
+};
+
+union cvmx_pow_ecc_err {
+ uint64_t u64;
+ struct cvmx_pow_ecc_err_s {
+ uint64_t reserved_45_63:19;
+ uint64_t iop_ie:13;
+ uint64_t reserved_29_31:3;
+ uint64_t iop:13;
+ uint64_t reserved_14_15:2;
+ uint64_t rpe_ie:1;
+ uint64_t rpe:1;
+ uint64_t reserved_9_11:3;
+ uint64_t syn:5;
+ uint64_t dbe_ie:1;
+ uint64_t sbe_ie:1;
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ } s;
+ struct cvmx_pow_ecc_err_s cn30xx;
+ struct cvmx_pow_ecc_err_cn31xx {
+ uint64_t reserved_14_63:50;
+ uint64_t rpe_ie:1;
+ uint64_t rpe:1;
+ uint64_t reserved_9_11:3;
+ uint64_t syn:5;
+ uint64_t dbe_ie:1;
+ uint64_t sbe_ie:1;
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ } cn31xx;
+ struct cvmx_pow_ecc_err_s cn38xx;
+ struct cvmx_pow_ecc_err_cn31xx cn38xxp2;
+ struct cvmx_pow_ecc_err_s cn50xx;
+ struct cvmx_pow_ecc_err_s cn52xx;
+ struct cvmx_pow_ecc_err_s cn52xxp1;
+ struct cvmx_pow_ecc_err_s cn56xx;
+ struct cvmx_pow_ecc_err_s cn56xxp1;
+ struct cvmx_pow_ecc_err_s cn58xx;
+ struct cvmx_pow_ecc_err_s cn58xxp1;
+ struct cvmx_pow_ecc_err_s cn63xx;
+ struct cvmx_pow_ecc_err_s cn63xxp1;
+};
+
+union cvmx_pow_int_ctl {
+ uint64_t u64;
+ struct cvmx_pow_int_ctl_s {
+ uint64_t reserved_6_63:58;
+ uint64_t pfr_dis:1;
+ uint64_t nbr_thr:5;
+ } s;
+ struct cvmx_pow_int_ctl_s cn30xx;
+ struct cvmx_pow_int_ctl_s cn31xx;
+ struct cvmx_pow_int_ctl_s cn38xx;
+ struct cvmx_pow_int_ctl_s cn38xxp2;
+ struct cvmx_pow_int_ctl_s cn50xx;
+ struct cvmx_pow_int_ctl_s cn52xx;
+ struct cvmx_pow_int_ctl_s cn52xxp1;
+ struct cvmx_pow_int_ctl_s cn56xx;
+ struct cvmx_pow_int_ctl_s cn56xxp1;
+ struct cvmx_pow_int_ctl_s cn58xx;
+ struct cvmx_pow_int_ctl_s cn58xxp1;
+ struct cvmx_pow_int_ctl_s cn63xx;
+ struct cvmx_pow_int_ctl_s cn63xxp1;
+};
+
+union cvmx_pow_iq_cntx {
+ uint64_t u64;
+ struct cvmx_pow_iq_cntx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iq_cnt:32;
+ } s;
+ struct cvmx_pow_iq_cntx_s cn30xx;
+ struct cvmx_pow_iq_cntx_s cn31xx;
+ struct cvmx_pow_iq_cntx_s cn38xx;
+ struct cvmx_pow_iq_cntx_s cn38xxp2;
+ struct cvmx_pow_iq_cntx_s cn50xx;
+ struct cvmx_pow_iq_cntx_s cn52xx;
+ struct cvmx_pow_iq_cntx_s cn52xxp1;
+ struct cvmx_pow_iq_cntx_s cn56xx;
+ struct cvmx_pow_iq_cntx_s cn56xxp1;
+ struct cvmx_pow_iq_cntx_s cn58xx;
+ struct cvmx_pow_iq_cntx_s cn58xxp1;
+ struct cvmx_pow_iq_cntx_s cn63xx;
+ struct cvmx_pow_iq_cntx_s cn63xxp1;
+};
+
+union cvmx_pow_iq_com_cnt {
+ uint64_t u64;
+ struct cvmx_pow_iq_com_cnt_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iq_cnt:32;
+ } s;
+ struct cvmx_pow_iq_com_cnt_s cn30xx;
+ struct cvmx_pow_iq_com_cnt_s cn31xx;
+ struct cvmx_pow_iq_com_cnt_s cn38xx;
+ struct cvmx_pow_iq_com_cnt_s cn38xxp2;
+ struct cvmx_pow_iq_com_cnt_s cn50xx;
+ struct cvmx_pow_iq_com_cnt_s cn52xx;
+ struct cvmx_pow_iq_com_cnt_s cn52xxp1;
+ struct cvmx_pow_iq_com_cnt_s cn56xx;
+ struct cvmx_pow_iq_com_cnt_s cn56xxp1;
+ struct cvmx_pow_iq_com_cnt_s cn58xx;
+ struct cvmx_pow_iq_com_cnt_s cn58xxp1;
+ struct cvmx_pow_iq_com_cnt_s cn63xx;
+ struct cvmx_pow_iq_com_cnt_s cn63xxp1;
+};
+
+union cvmx_pow_iq_int {
+ uint64_t u64;
+ struct cvmx_pow_iq_int_s {
+ uint64_t reserved_8_63:56;
+ uint64_t iq_int:8;
+ } s;
+ struct cvmx_pow_iq_int_s cn52xx;
+ struct cvmx_pow_iq_int_s cn52xxp1;
+ struct cvmx_pow_iq_int_s cn56xx;
+ struct cvmx_pow_iq_int_s cn56xxp1;
+ struct cvmx_pow_iq_int_s cn63xx;
+ struct cvmx_pow_iq_int_s cn63xxp1;
+};
+
+union cvmx_pow_iq_int_en {
+ uint64_t u64;
+ struct cvmx_pow_iq_int_en_s {
+ uint64_t reserved_8_63:56;
+ uint64_t int_en:8;
+ } s;
+ struct cvmx_pow_iq_int_en_s cn52xx;
+ struct cvmx_pow_iq_int_en_s cn52xxp1;
+ struct cvmx_pow_iq_int_en_s cn56xx;
+ struct cvmx_pow_iq_int_en_s cn56xxp1;
+ struct cvmx_pow_iq_int_en_s cn63xx;
+ struct cvmx_pow_iq_int_en_s cn63xxp1;
+};
+
+union cvmx_pow_iq_thrx {
+ uint64_t u64;
+ struct cvmx_pow_iq_thrx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iq_thr:32;
+ } s;
+ struct cvmx_pow_iq_thrx_s cn52xx;
+ struct cvmx_pow_iq_thrx_s cn52xxp1;
+ struct cvmx_pow_iq_thrx_s cn56xx;
+ struct cvmx_pow_iq_thrx_s cn56xxp1;
+ struct cvmx_pow_iq_thrx_s cn63xx;
+ struct cvmx_pow_iq_thrx_s cn63xxp1;
+};
+
+union cvmx_pow_nos_cnt {
+ uint64_t u64;
+ struct cvmx_pow_nos_cnt_s {
+ uint64_t reserved_12_63:52;
+ uint64_t nos_cnt:12;
+ } s;
+ struct cvmx_pow_nos_cnt_cn30xx {
+ uint64_t reserved_7_63:57;
+ uint64_t nos_cnt:7;
+ } cn30xx;
+ struct cvmx_pow_nos_cnt_cn31xx {
+ uint64_t reserved_9_63:55;
+ uint64_t nos_cnt:9;
+ } cn31xx;
+ struct cvmx_pow_nos_cnt_s cn38xx;
+ struct cvmx_pow_nos_cnt_s cn38xxp2;
+ struct cvmx_pow_nos_cnt_cn31xx cn50xx;
+ struct cvmx_pow_nos_cnt_cn52xx {
+ uint64_t reserved_10_63:54;
+ uint64_t nos_cnt:10;
+ } cn52xx;
+ struct cvmx_pow_nos_cnt_cn52xx cn52xxp1;
+ struct cvmx_pow_nos_cnt_s cn56xx;
+ struct cvmx_pow_nos_cnt_s cn56xxp1;
+ struct cvmx_pow_nos_cnt_s cn58xx;
+ struct cvmx_pow_nos_cnt_s cn58xxp1;
+ struct cvmx_pow_nos_cnt_cn63xx {
+ uint64_t reserved_11_63:53;
+ uint64_t nos_cnt:11;
+ } cn63xx;
+ struct cvmx_pow_nos_cnt_cn63xx cn63xxp1;
+};
+
+union cvmx_pow_nw_tim {
+ uint64_t u64;
+ struct cvmx_pow_nw_tim_s {
+ uint64_t reserved_10_63:54;
+ uint64_t nw_tim:10;
+ } s;
+ struct cvmx_pow_nw_tim_s cn30xx;
+ struct cvmx_pow_nw_tim_s cn31xx;
+ struct cvmx_pow_nw_tim_s cn38xx;
+ struct cvmx_pow_nw_tim_s cn38xxp2;
+ struct cvmx_pow_nw_tim_s cn50xx;
+ struct cvmx_pow_nw_tim_s cn52xx;
+ struct cvmx_pow_nw_tim_s cn52xxp1;
+ struct cvmx_pow_nw_tim_s cn56xx;
+ struct cvmx_pow_nw_tim_s cn56xxp1;
+ struct cvmx_pow_nw_tim_s cn58xx;
+ struct cvmx_pow_nw_tim_s cn58xxp1;
+ struct cvmx_pow_nw_tim_s cn63xx;
+ struct cvmx_pow_nw_tim_s cn63xxp1;
+};
+
+union cvmx_pow_pf_rst_msk {
+ uint64_t u64;
+ struct cvmx_pow_pf_rst_msk_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rst_msk:8;
+ } s;
+ struct cvmx_pow_pf_rst_msk_s cn50xx;
+ struct cvmx_pow_pf_rst_msk_s cn52xx;
+ struct cvmx_pow_pf_rst_msk_s cn52xxp1;
+ struct cvmx_pow_pf_rst_msk_s cn56xx;
+ struct cvmx_pow_pf_rst_msk_s cn56xxp1;
+ struct cvmx_pow_pf_rst_msk_s cn58xx;
+ struct cvmx_pow_pf_rst_msk_s cn58xxp1;
+ struct cvmx_pow_pf_rst_msk_s cn63xx;
+ struct cvmx_pow_pf_rst_msk_s cn63xxp1;
+};
+
+union cvmx_pow_pp_grp_mskx {
+ uint64_t u64;
+ struct cvmx_pow_pp_grp_mskx_s {
+ uint64_t reserved_48_63:16;
+ uint64_t qos7_pri:4;
+ uint64_t qos6_pri:4;
+ uint64_t qos5_pri:4;
+ uint64_t qos4_pri:4;
+ uint64_t qos3_pri:4;
+ uint64_t qos2_pri:4;
+ uint64_t qos1_pri:4;
+ uint64_t qos0_pri:4;
+ uint64_t grp_msk:16;
+ } s;
+ struct cvmx_pow_pp_grp_mskx_cn30xx {
+ uint64_t reserved_16_63:48;
+ uint64_t grp_msk:16;
+ } cn30xx;
+ struct cvmx_pow_pp_grp_mskx_cn30xx cn31xx;
+ struct cvmx_pow_pp_grp_mskx_cn30xx cn38xx;
+ struct cvmx_pow_pp_grp_mskx_cn30xx cn38xxp2;
+ struct cvmx_pow_pp_grp_mskx_s cn50xx;
+ struct cvmx_pow_pp_grp_mskx_s cn52xx;
+ struct cvmx_pow_pp_grp_mskx_s cn52xxp1;
+ struct cvmx_pow_pp_grp_mskx_s cn56xx;
+ struct cvmx_pow_pp_grp_mskx_s cn56xxp1;
+ struct cvmx_pow_pp_grp_mskx_s cn58xx;
+ struct cvmx_pow_pp_grp_mskx_s cn58xxp1;
+ struct cvmx_pow_pp_grp_mskx_s cn63xx;
+ struct cvmx_pow_pp_grp_mskx_s cn63xxp1;
+};
+
+union cvmx_pow_qos_rndx {
+ uint64_t u64;
+ struct cvmx_pow_qos_rndx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t rnd_p3:8;
+ uint64_t rnd_p2:8;
+ uint64_t rnd_p1:8;
+ uint64_t rnd:8;
+ } s;
+ struct cvmx_pow_qos_rndx_s cn30xx;
+ struct cvmx_pow_qos_rndx_s cn31xx;
+ struct cvmx_pow_qos_rndx_s cn38xx;
+ struct cvmx_pow_qos_rndx_s cn38xxp2;
+ struct cvmx_pow_qos_rndx_s cn50xx;
+ struct cvmx_pow_qos_rndx_s cn52xx;
+ struct cvmx_pow_qos_rndx_s cn52xxp1;
+ struct cvmx_pow_qos_rndx_s cn56xx;
+ struct cvmx_pow_qos_rndx_s cn56xxp1;
+ struct cvmx_pow_qos_rndx_s cn58xx;
+ struct cvmx_pow_qos_rndx_s cn58xxp1;
+ struct cvmx_pow_qos_rndx_s cn63xx;
+ struct cvmx_pow_qos_rndx_s cn63xxp1;
+};
+
+union cvmx_pow_qos_thrx {
+ uint64_t u64;
+ struct cvmx_pow_qos_thrx_s {
+ uint64_t reserved_60_63:4;
+ uint64_t des_cnt:12;
+ uint64_t buf_cnt:12;
+ uint64_t free_cnt:12;
+ uint64_t reserved_23_23:1;
+ uint64_t max_thr:11;
+ uint64_t reserved_11_11:1;
+ uint64_t min_thr:11;
+ } s;
+ struct cvmx_pow_qos_thrx_cn30xx {
+ uint64_t reserved_55_63:9;
+ uint64_t des_cnt:7;
+ uint64_t reserved_43_47:5;
+ uint64_t buf_cnt:7;
+ uint64_t reserved_31_35:5;
+ uint64_t free_cnt:7;
+ uint64_t reserved_18_23:6;
+ uint64_t max_thr:6;
+ uint64_t reserved_6_11:6;
+ uint64_t min_thr:6;
+ } cn30xx;
+ struct cvmx_pow_qos_thrx_cn31xx {
+ uint64_t reserved_57_63:7;
+ uint64_t des_cnt:9;
+ uint64_t reserved_45_47:3;
+ uint64_t buf_cnt:9;
+ uint64_t reserved_33_35:3;
+ uint64_t free_cnt:9;
+ uint64_t reserved_20_23:4;
+ uint64_t max_thr:8;
+ uint64_t reserved_8_11:4;
+ uint64_t min_thr:8;
+ } cn31xx;
+ struct cvmx_pow_qos_thrx_s cn38xx;
+ struct cvmx_pow_qos_thrx_s cn38xxp2;
+ struct cvmx_pow_qos_thrx_cn31xx cn50xx;
+ struct cvmx_pow_qos_thrx_cn52xx {
+ uint64_t reserved_58_63:6;
+ uint64_t des_cnt:10;
+ uint64_t reserved_46_47:2;
+ uint64_t buf_cnt:10;
+ uint64_t reserved_34_35:2;
+ uint64_t free_cnt:10;
+ uint64_t reserved_21_23:3;
+ uint64_t max_thr:9;
+ uint64_t reserved_9_11:3;
+ uint64_t min_thr:9;
+ } cn52xx;
+ struct cvmx_pow_qos_thrx_cn52xx cn52xxp1;
+ struct cvmx_pow_qos_thrx_s cn56xx;
+ struct cvmx_pow_qos_thrx_s cn56xxp1;
+ struct cvmx_pow_qos_thrx_s cn58xx;
+ struct cvmx_pow_qos_thrx_s cn58xxp1;
+ struct cvmx_pow_qos_thrx_cn63xx {
+ uint64_t reserved_59_63:5;
+ uint64_t des_cnt:11;
+ uint64_t reserved_47_47:1;
+ uint64_t buf_cnt:11;
+ uint64_t reserved_35_35:1;
+ uint64_t free_cnt:11;
+ uint64_t reserved_22_23:2;
+ uint64_t max_thr:10;
+ uint64_t reserved_10_11:2;
+ uint64_t min_thr:10;
+ } cn63xx;
+ struct cvmx_pow_qos_thrx_cn63xx cn63xxp1;
+};
+
+union cvmx_pow_ts_pc {
+ uint64_t u64;
+ struct cvmx_pow_ts_pc_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ts_pc:32;
+ } s;
+ struct cvmx_pow_ts_pc_s cn30xx;
+ struct cvmx_pow_ts_pc_s cn31xx;
+ struct cvmx_pow_ts_pc_s cn38xx;
+ struct cvmx_pow_ts_pc_s cn38xxp2;
+ struct cvmx_pow_ts_pc_s cn50xx;
+ struct cvmx_pow_ts_pc_s cn52xx;
+ struct cvmx_pow_ts_pc_s cn52xxp1;
+ struct cvmx_pow_ts_pc_s cn56xx;
+ struct cvmx_pow_ts_pc_s cn56xxp1;
+ struct cvmx_pow_ts_pc_s cn58xx;
+ struct cvmx_pow_ts_pc_s cn58xxp1;
+ struct cvmx_pow_ts_pc_s cn63xx;
+ struct cvmx_pow_ts_pc_s cn63xxp1;
+};
+
+union cvmx_pow_wa_com_pc {
+ uint64_t u64;
+ struct cvmx_pow_wa_com_pc_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wa_pc:32;
+ } s;
+ struct cvmx_pow_wa_com_pc_s cn30xx;
+ struct cvmx_pow_wa_com_pc_s cn31xx;
+ struct cvmx_pow_wa_com_pc_s cn38xx;
+ struct cvmx_pow_wa_com_pc_s cn38xxp2;
+ struct cvmx_pow_wa_com_pc_s cn50xx;
+ struct cvmx_pow_wa_com_pc_s cn52xx;
+ struct cvmx_pow_wa_com_pc_s cn52xxp1;
+ struct cvmx_pow_wa_com_pc_s cn56xx;
+ struct cvmx_pow_wa_com_pc_s cn56xxp1;
+ struct cvmx_pow_wa_com_pc_s cn58xx;
+ struct cvmx_pow_wa_com_pc_s cn58xxp1;
+ struct cvmx_pow_wa_com_pc_s cn63xx;
+ struct cvmx_pow_wa_com_pc_s cn63xxp1;
+};
+
+union cvmx_pow_wa_pcx {
+ uint64_t u64;
+ struct cvmx_pow_wa_pcx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wa_pc:32;
+ } s;
+ struct cvmx_pow_wa_pcx_s cn30xx;
+ struct cvmx_pow_wa_pcx_s cn31xx;
+ struct cvmx_pow_wa_pcx_s cn38xx;
+ struct cvmx_pow_wa_pcx_s cn38xxp2;
+ struct cvmx_pow_wa_pcx_s cn50xx;
+ struct cvmx_pow_wa_pcx_s cn52xx;
+ struct cvmx_pow_wa_pcx_s cn52xxp1;
+ struct cvmx_pow_wa_pcx_s cn56xx;
+ struct cvmx_pow_wa_pcx_s cn56xxp1;
+ struct cvmx_pow_wa_pcx_s cn58xx;
+ struct cvmx_pow_wa_pcx_s cn58xxp1;
+ struct cvmx_pow_wa_pcx_s cn63xx;
+ struct cvmx_pow_wa_pcx_s cn63xxp1;
+};
+
+union cvmx_pow_wq_int {
+ uint64_t u64;
+ struct cvmx_pow_wq_int_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iq_dis:16;
+ uint64_t wq_int:16;
+ } s;
+ struct cvmx_pow_wq_int_s cn30xx;
+ struct cvmx_pow_wq_int_s cn31xx;
+ struct cvmx_pow_wq_int_s cn38xx;
+ struct cvmx_pow_wq_int_s cn38xxp2;
+ struct cvmx_pow_wq_int_s cn50xx;
+ struct cvmx_pow_wq_int_s cn52xx;
+ struct cvmx_pow_wq_int_s cn52xxp1;
+ struct cvmx_pow_wq_int_s cn56xx;
+ struct cvmx_pow_wq_int_s cn56xxp1;
+ struct cvmx_pow_wq_int_s cn58xx;
+ struct cvmx_pow_wq_int_s cn58xxp1;
+ struct cvmx_pow_wq_int_s cn63xx;
+ struct cvmx_pow_wq_int_s cn63xxp1;
+};
+
+union cvmx_pow_wq_int_cntx {
+ uint64_t u64;
+ struct cvmx_pow_wq_int_cntx_s {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t ds_cnt:12;
+ uint64_t iq_cnt:12;
+ } s;
+ struct cvmx_pow_wq_int_cntx_cn30xx {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_19_23:5;
+ uint64_t ds_cnt:7;
+ uint64_t reserved_7_11:5;
+ uint64_t iq_cnt:7;
+ } cn30xx;
+ struct cvmx_pow_wq_int_cntx_cn31xx {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_21_23:3;
+ uint64_t ds_cnt:9;
+ uint64_t reserved_9_11:3;
+ uint64_t iq_cnt:9;
+ } cn31xx;
+ struct cvmx_pow_wq_int_cntx_s cn38xx;
+ struct cvmx_pow_wq_int_cntx_s cn38xxp2;
+ struct cvmx_pow_wq_int_cntx_cn31xx cn50xx;
+ struct cvmx_pow_wq_int_cntx_cn52xx {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_22_23:2;
+ uint64_t ds_cnt:10;
+ uint64_t reserved_10_11:2;
+ uint64_t iq_cnt:10;
+ } cn52xx;
+ struct cvmx_pow_wq_int_cntx_cn52xx cn52xxp1;
+ struct cvmx_pow_wq_int_cntx_s cn56xx;
+ struct cvmx_pow_wq_int_cntx_s cn56xxp1;
+ struct cvmx_pow_wq_int_cntx_s cn58xx;
+ struct cvmx_pow_wq_int_cntx_s cn58xxp1;
+ struct cvmx_pow_wq_int_cntx_cn63xx {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_23_23:1;
+ uint64_t ds_cnt:11;
+ uint64_t reserved_11_11:1;
+ uint64_t iq_cnt:11;
+ } cn63xx;
+ struct cvmx_pow_wq_int_cntx_cn63xx cn63xxp1;
+};
+
+union cvmx_pow_wq_int_pc {
+ uint64_t u64;
+ struct cvmx_pow_wq_int_pc_s {
+ uint64_t reserved_60_63:4;
+ uint64_t pc:28;
+ uint64_t reserved_28_31:4;
+ uint64_t pc_thr:20;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_pow_wq_int_pc_s cn30xx;
+ struct cvmx_pow_wq_int_pc_s cn31xx;
+ struct cvmx_pow_wq_int_pc_s cn38xx;
+ struct cvmx_pow_wq_int_pc_s cn38xxp2;
+ struct cvmx_pow_wq_int_pc_s cn50xx;
+ struct cvmx_pow_wq_int_pc_s cn52xx;
+ struct cvmx_pow_wq_int_pc_s cn52xxp1;
+ struct cvmx_pow_wq_int_pc_s cn56xx;
+ struct cvmx_pow_wq_int_pc_s cn56xxp1;
+ struct cvmx_pow_wq_int_pc_s cn58xx;
+ struct cvmx_pow_wq_int_pc_s cn58xxp1;
+ struct cvmx_pow_wq_int_pc_s cn63xx;
+ struct cvmx_pow_wq_int_pc_s cn63xxp1;
+};
+
+union cvmx_pow_wq_int_thrx {
+ uint64_t u64;
+ struct cvmx_pow_wq_int_thrx_s {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_23_23:1;
+ uint64_t ds_thr:11;
+ uint64_t reserved_11_11:1;
+ uint64_t iq_thr:11;
+ } s;
+ struct cvmx_pow_wq_int_thrx_cn30xx {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_18_23:6;
+ uint64_t ds_thr:6;
+ uint64_t reserved_6_11:6;
+ uint64_t iq_thr:6;
+ } cn30xx;
+ struct cvmx_pow_wq_int_thrx_cn31xx {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_20_23:4;
+ uint64_t ds_thr:8;
+ uint64_t reserved_8_11:4;
+ uint64_t iq_thr:8;
+ } cn31xx;
+ struct cvmx_pow_wq_int_thrx_s cn38xx;
+ struct cvmx_pow_wq_int_thrx_s cn38xxp2;
+ struct cvmx_pow_wq_int_thrx_cn31xx cn50xx;
+ struct cvmx_pow_wq_int_thrx_cn52xx {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_21_23:3;
+ uint64_t ds_thr:9;
+ uint64_t reserved_9_11:3;
+ uint64_t iq_thr:9;
+ } cn52xx;
+ struct cvmx_pow_wq_int_thrx_cn52xx cn52xxp1;
+ struct cvmx_pow_wq_int_thrx_s cn56xx;
+ struct cvmx_pow_wq_int_thrx_s cn56xxp1;
+ struct cvmx_pow_wq_int_thrx_s cn58xx;
+ struct cvmx_pow_wq_int_thrx_s cn58xxp1;
+ struct cvmx_pow_wq_int_thrx_cn63xx {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_22_23:2;
+ uint64_t ds_thr:10;
+ uint64_t reserved_10_11:2;
+ uint64_t iq_thr:10;
+ } cn63xx;
+ struct cvmx_pow_wq_int_thrx_cn63xx cn63xxp1;
+};
+
+union cvmx_pow_ws_pcx {
+ uint64_t u64;
+ struct cvmx_pow_ws_pcx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ws_pc:32;
+ } s;
+ struct cvmx_pow_ws_pcx_s cn30xx;
+ struct cvmx_pow_ws_pcx_s cn31xx;
+ struct cvmx_pow_ws_pcx_s cn38xx;
+ struct cvmx_pow_ws_pcx_s cn38xxp2;
+ struct cvmx_pow_ws_pcx_s cn50xx;
+ struct cvmx_pow_ws_pcx_s cn52xx;
+ struct cvmx_pow_ws_pcx_s cn52xxp1;
+ struct cvmx_pow_ws_pcx_s cn56xx;
+ struct cvmx_pow_ws_pcx_s cn56xxp1;
+ struct cvmx_pow_ws_pcx_s cn58xx;
+ struct cvmx_pow_ws_pcx_s cn58xxp1;
+ struct cvmx_pow_ws_pcx_s cn63xx;
+ struct cvmx_pow_ws_pcx_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
new file mode 100644
index 00000000..c45da1f3
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
@@ -0,0 +1,129 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_RNM_DEFS_H__
+#define __CVMX_RNM_DEFS_H__
+
+#include <linux/types.h>
+
+#define CVMX_RNM_BIST_STATUS (CVMX_ADD_IO_SEG(0x0001180040000008ull))
+#define CVMX_RNM_CTL_STATUS (CVMX_ADD_IO_SEG(0x0001180040000000ull))
+#define CVMX_RNM_EER_DBG (CVMX_ADD_IO_SEG(0x0001180040000018ull))
+#define CVMX_RNM_EER_KEY (CVMX_ADD_IO_SEG(0x0001180040000010ull))
+#define CVMX_RNM_SERIAL_NUM (CVMX_ADD_IO_SEG(0x0001180040000020ull))
+
+union cvmx_rnm_bist_status {
+ uint64_t u64;
+ struct cvmx_rnm_bist_status_s {
+ uint64_t reserved_2_63:62;
+ uint64_t rrc:1;
+ uint64_t mem:1;
+ } s;
+ struct cvmx_rnm_bist_status_s cn30xx;
+ struct cvmx_rnm_bist_status_s cn31xx;
+ struct cvmx_rnm_bist_status_s cn38xx;
+ struct cvmx_rnm_bist_status_s cn38xxp2;
+ struct cvmx_rnm_bist_status_s cn50xx;
+ struct cvmx_rnm_bist_status_s cn52xx;
+ struct cvmx_rnm_bist_status_s cn52xxp1;
+ struct cvmx_rnm_bist_status_s cn56xx;
+ struct cvmx_rnm_bist_status_s cn56xxp1;
+ struct cvmx_rnm_bist_status_s cn58xx;
+ struct cvmx_rnm_bist_status_s cn58xxp1;
+ struct cvmx_rnm_bist_status_s cn63xx;
+ struct cvmx_rnm_bist_status_s cn63xxp1;
+};
+
+union cvmx_rnm_ctl_status {
+ uint64_t u64;
+ struct cvmx_rnm_ctl_status_s {
+ uint64_t reserved_11_63:53;
+ uint64_t eer_lck:1;
+ uint64_t eer_val:1;
+ uint64_t ent_sel:4;
+ uint64_t exp_ent:1;
+ uint64_t rng_rst:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_en:1;
+ uint64_t ent_en:1;
+ } s;
+ struct cvmx_rnm_ctl_status_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t rng_rst:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_en:1;
+ uint64_t ent_en:1;
+ } cn30xx;
+ struct cvmx_rnm_ctl_status_cn30xx cn31xx;
+ struct cvmx_rnm_ctl_status_cn30xx cn38xx;
+ struct cvmx_rnm_ctl_status_cn30xx cn38xxp2;
+ struct cvmx_rnm_ctl_status_cn50xx {
+ uint64_t reserved_9_63:55;
+ uint64_t ent_sel:4;
+ uint64_t exp_ent:1;
+ uint64_t rng_rst:1;
+ uint64_t rnm_rst:1;
+ uint64_t rng_en:1;
+ uint64_t ent_en:1;
+ } cn50xx;
+ struct cvmx_rnm_ctl_status_cn50xx cn52xx;
+ struct cvmx_rnm_ctl_status_cn50xx cn52xxp1;
+ struct cvmx_rnm_ctl_status_cn50xx cn56xx;
+ struct cvmx_rnm_ctl_status_cn50xx cn56xxp1;
+ struct cvmx_rnm_ctl_status_cn50xx cn58xx;
+ struct cvmx_rnm_ctl_status_cn50xx cn58xxp1;
+ struct cvmx_rnm_ctl_status_s cn63xx;
+ struct cvmx_rnm_ctl_status_s cn63xxp1;
+};
+
+union cvmx_rnm_eer_dbg {
+ uint64_t u64;
+ struct cvmx_rnm_eer_dbg_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_rnm_eer_dbg_s cn63xx;
+ struct cvmx_rnm_eer_dbg_s cn63xxp1;
+};
+
+union cvmx_rnm_eer_key {
+ uint64_t u64;
+ struct cvmx_rnm_eer_key_s {
+ uint64_t key:64;
+ } s;
+ struct cvmx_rnm_eer_key_s cn63xx;
+ struct cvmx_rnm_eer_key_s cn63xxp1;
+};
+
+union cvmx_rnm_serial_num {
+ uint64_t u64;
+ struct cvmx_rnm_serial_num_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_rnm_serial_num_s cn63xx;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
new file mode 100644
index 00000000..4f3c0666
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
@@ -0,0 +1,174 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_SMIX_DEFS_H__
+#define __CVMX_SMIX_DEFS_H__
+
+#define CVMX_SMIX_CLK(offset) (CVMX_ADD_IO_SEG(0x0001180000001818ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_CMD(offset) (CVMX_ADD_IO_SEG(0x0001180000001800ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_EN(offset) (CVMX_ADD_IO_SEG(0x0001180000001820ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_RD_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001810ull) + ((offset) & 1) * 256)
+#define CVMX_SMIX_WR_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001808ull) + ((offset) & 1) * 256)
+
+union cvmx_smix_clk {
+ uint64_t u64;
+ struct cvmx_smix_clk_s {
+ uint64_t reserved_25_63:39;
+ uint64_t mode:1;
+ uint64_t reserved_21_23:3;
+ uint64_t sample_hi:5;
+ uint64_t sample_mode:1;
+ uint64_t reserved_14_14:1;
+ uint64_t clk_idle:1;
+ uint64_t preamble:1;
+ uint64_t sample:4;
+ uint64_t phase:8;
+ } s;
+ struct cvmx_smix_clk_cn30xx {
+ uint64_t reserved_21_63:43;
+ uint64_t sample_hi:5;
+ uint64_t sample_mode:1;
+ uint64_t reserved_14_14:1;
+ uint64_t clk_idle:1;
+ uint64_t preamble:1;
+ uint64_t sample:4;
+ uint64_t phase:8;
+ } cn30xx;
+ struct cvmx_smix_clk_cn30xx cn31xx;
+ struct cvmx_smix_clk_cn30xx cn38xx;
+ struct cvmx_smix_clk_cn30xx cn38xxp2;
+ struct cvmx_smix_clk_s cn50xx;
+ struct cvmx_smix_clk_s cn52xx;
+ struct cvmx_smix_clk_s cn52xxp1;
+ struct cvmx_smix_clk_s cn56xx;
+ struct cvmx_smix_clk_s cn56xxp1;
+ struct cvmx_smix_clk_cn30xx cn58xx;
+ struct cvmx_smix_clk_cn30xx cn58xxp1;
+ struct cvmx_smix_clk_s cn63xx;
+ struct cvmx_smix_clk_s cn63xxp1;
+};
+
+union cvmx_smix_cmd {
+ uint64_t u64;
+ struct cvmx_smix_cmd_s {
+ uint64_t reserved_18_63:46;
+ uint64_t phy_op:2;
+ uint64_t reserved_13_15:3;
+ uint64_t phy_adr:5;
+ uint64_t reserved_5_7:3;
+ uint64_t reg_adr:5;
+ } s;
+ struct cvmx_smix_cmd_cn30xx {
+ uint64_t reserved_17_63:47;
+ uint64_t phy_op:1;
+ uint64_t reserved_13_15:3;
+ uint64_t phy_adr:5;
+ uint64_t reserved_5_7:3;
+ uint64_t reg_adr:5;
+ } cn30xx;
+ struct cvmx_smix_cmd_cn30xx cn31xx;
+ struct cvmx_smix_cmd_cn30xx cn38xx;
+ struct cvmx_smix_cmd_cn30xx cn38xxp2;
+ struct cvmx_smix_cmd_s cn50xx;
+ struct cvmx_smix_cmd_s cn52xx;
+ struct cvmx_smix_cmd_s cn52xxp1;
+ struct cvmx_smix_cmd_s cn56xx;
+ struct cvmx_smix_cmd_s cn56xxp1;
+ struct cvmx_smix_cmd_cn30xx cn58xx;
+ struct cvmx_smix_cmd_cn30xx cn58xxp1;
+ struct cvmx_smix_cmd_s cn63xx;
+ struct cvmx_smix_cmd_s cn63xxp1;
+};
+
+union cvmx_smix_en {
+ uint64_t u64;
+ struct cvmx_smix_en_s {
+ uint64_t reserved_1_63:63;
+ uint64_t en:1;
+ } s;
+ struct cvmx_smix_en_s cn30xx;
+ struct cvmx_smix_en_s cn31xx;
+ struct cvmx_smix_en_s cn38xx;
+ struct cvmx_smix_en_s cn38xxp2;
+ struct cvmx_smix_en_s cn50xx;
+ struct cvmx_smix_en_s cn52xx;
+ struct cvmx_smix_en_s cn52xxp1;
+ struct cvmx_smix_en_s cn56xx;
+ struct cvmx_smix_en_s cn56xxp1;
+ struct cvmx_smix_en_s cn58xx;
+ struct cvmx_smix_en_s cn58xxp1;
+ struct cvmx_smix_en_s cn63xx;
+ struct cvmx_smix_en_s cn63xxp1;
+};
+
+union cvmx_smix_rd_dat {
+ uint64_t u64;
+ struct cvmx_smix_rd_dat_s {
+ uint64_t reserved_18_63:46;
+ uint64_t pending:1;
+ uint64_t val:1;
+ uint64_t dat:16;
+ } s;
+ struct cvmx_smix_rd_dat_s cn30xx;
+ struct cvmx_smix_rd_dat_s cn31xx;
+ struct cvmx_smix_rd_dat_s cn38xx;
+ struct cvmx_smix_rd_dat_s cn38xxp2;
+ struct cvmx_smix_rd_dat_s cn50xx;
+ struct cvmx_smix_rd_dat_s cn52xx;
+ struct cvmx_smix_rd_dat_s cn52xxp1;
+ struct cvmx_smix_rd_dat_s cn56xx;
+ struct cvmx_smix_rd_dat_s cn56xxp1;
+ struct cvmx_smix_rd_dat_s cn58xx;
+ struct cvmx_smix_rd_dat_s cn58xxp1;
+ struct cvmx_smix_rd_dat_s cn63xx;
+ struct cvmx_smix_rd_dat_s cn63xxp1;
+};
+
+union cvmx_smix_wr_dat {
+ uint64_t u64;
+ struct cvmx_smix_wr_dat_s {
+ uint64_t reserved_18_63:46;
+ uint64_t pending:1;
+ uint64_t val:1;
+ uint64_t dat:16;
+ } s;
+ struct cvmx_smix_wr_dat_s cn30xx;
+ struct cvmx_smix_wr_dat_s cn31xx;
+ struct cvmx_smix_wr_dat_s cn38xx;
+ struct cvmx_smix_wr_dat_s cn38xxp2;
+ struct cvmx_smix_wr_dat_s cn50xx;
+ struct cvmx_smix_wr_dat_s cn52xx;
+ struct cvmx_smix_wr_dat_s cn52xxp1;
+ struct cvmx_smix_wr_dat_s cn56xx;
+ struct cvmx_smix_wr_dat_s cn56xxp1;
+ struct cvmx_smix_wr_dat_s cn58xx;
+ struct cvmx_smix_wr_dat_s cn58xxp1;
+ struct cvmx_smix_wr_dat_s cn63xx;
+ struct cvmx_smix_wr_dat_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-spinlock.h b/arch/mips/include/asm/octeon/cvmx-spinlock.h
new file mode 100644
index 00000000..2fbf0871
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-spinlock.h
@@ -0,0 +1,232 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * Implementation of spinlocks for Octeon CVMX. Although similar in
+ * function to Linux kernel spinlocks, they are not compatible.
+ * Octeon CVMX spinlocks are only used to synchronize with the boot
+ * monitor and other non-Linux programs running in the system.
+ */
+
+#ifndef __CVMX_SPINLOCK_H__
+#define __CVMX_SPINLOCK_H__
+
+#include "cvmx-asm.h"
+
+/* Spinlocks for Octeon */
+
+/* define these to enable recursive spinlock debugging */
+/*#define CVMX_SPINLOCK_DEBUG */
+
+/**
+ * Spinlocks for Octeon CVMX
+ */
+typedef struct {
+ volatile uint32_t value;
+} cvmx_spinlock_t;
+
+/* note - macros not expanded in inline ASM, so values hardcoded */
+#define CVMX_SPINLOCK_UNLOCKED_VAL 0
+#define CVMX_SPINLOCK_LOCKED_VAL 1
+
+#define CVMX_SPINLOCK_UNLOCKED_INITIALIZER {CVMX_SPINLOCK_UNLOCKED_VAL}
+
+/**
+ * Initialize a spinlock
+ *
+ * @lock: Lock to initialize
+ */
+static inline void cvmx_spinlock_init(cvmx_spinlock_t *lock)
+{
+ lock->value = CVMX_SPINLOCK_UNLOCKED_VAL;
+}
+
+/**
+ * Return non-zero if the spinlock is currently locked
+ *
+ * @lock: Lock to check
+ * Returns Non-zero if locked
+ */
+static inline int cvmx_spinlock_locked(cvmx_spinlock_t *lock)
+{
+ return lock->value != CVMX_SPINLOCK_UNLOCKED_VAL;
+}
+
+/**
+ * Releases lock
+ *
+ * @lock: pointer to lock structure
+ */
+static inline void cvmx_spinlock_unlock(cvmx_spinlock_t *lock)
+{
+ CVMX_SYNCWS;
+ lock->value = 0;
+ CVMX_SYNCWS;
+}
+
+/**
+ * Attempts to take the lock, but does not spin if lock is not available.
+ * May take some time to acquire the lock even if it is available
+ * due to the ll/sc not succeeding.
+ *
+ * @lock: pointer to lock structure
+ *
+ * Returns 0: lock successfully taken
+ * 1: lock not taken, held by someone else
+ * These return values match the Linux semantics.
+ */
+
+static inline unsigned int cvmx_spinlock_trylock(cvmx_spinlock_t *lock)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(".set noreorder \n"
+ "1: ll %[tmp], %[val] \n"
+ /* if lock held, fail immediately */
+ " bnez %[tmp], 2f \n"
+ " li %[tmp], 1 \n"
+ " sc %[tmp], %[val] \n"
+ " beqz %[tmp], 1b \n"
+ " li %[tmp], 0 \n"
+ "2: \n"
+ ".set reorder \n" :
+ [val] "+m"(lock->value), [tmp] "=&r"(tmp)
+ : : "memory");
+
+ return tmp != 0; /* normalize to 0 or 1 */
+}
+
+/**
+ * Gets lock, spins until lock is taken
+ *
+ * @lock: pointer to lock structure
+ */
+static inline void cvmx_spinlock_lock(cvmx_spinlock_t *lock)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(".set noreorder \n"
+ "1: ll %[tmp], %[val] \n"
+ " bnez %[tmp], 1b \n"
+ " li %[tmp], 1 \n"
+ " sc %[tmp], %[val] \n"
+ " beqz %[tmp], 1b \n"
+ " nop \n"
+ ".set reorder \n" :
+ [val] "+m"(lock->value), [tmp] "=&r"(tmp)
+ : : "memory");
+
+}
+
+/** ********************************************************************
+ * Bit spinlocks
+ * These spinlocks use a single bit (bit 31) of a 32 bit word for locking.
+ * The rest of the bits in the word are left undisturbed. This enables more
+ * compact data structures as only 1 bit is consumed for the lock.
+ *
+ */
+
+/**
+ * Gets lock, spins until lock is taken
+ * Preserves the low 31 bits of the 32 bit
+ * word used for the lock.
+ *
+ *
+ * @word: word to lock bit 31 of
+ */
+static inline void cvmx_spinlock_bit_lock(uint32_t *word)
+{
+ unsigned int tmp;
+ unsigned int sav;
+
+ __asm__ __volatile__(".set noreorder \n"
+ ".set noat \n"
+ "1: ll %[tmp], %[val] \n"
+ " bbit1 %[tmp], 31, 1b \n"
+ " li $at, 1 \n"
+ " ins %[tmp], $at, 31, 1 \n"
+ " sc %[tmp], %[val] \n"
+ " beqz %[tmp], 1b \n"
+ " nop \n"
+ ".set at \n"
+ ".set reorder \n" :
+ [val] "+m"(*word), [tmp] "=&r"(tmp), [sav] "=&r"(sav)
+ : : "memory");
+
+}
+
+/**
+ * Attempts to get lock, returns immediately with success/failure
+ * Preserves the low 31 bits of the 32 bit
+ * word used for the lock.
+ *
+ *
+ * @word: word to lock bit 31 of
+ * Returns 0: lock successfully taken
+ * 1: lock not taken, held by someone else
+ * These return values match the Linux semantics.
+ */
+static inline unsigned int cvmx_spinlock_bit_trylock(uint32_t *word)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(".set noreorder\n\t"
+ ".set noat\n"
+ "1: ll %[tmp], %[val] \n"
+ /* if lock held, fail immediately */
+ " bbit1 %[tmp], 31, 2f \n"
+ " li $at, 1 \n"
+ " ins %[tmp], $at, 31, 1 \n"
+ " sc %[tmp], %[val] \n"
+ " beqz %[tmp], 1b \n"
+ " li %[tmp], 0 \n"
+ "2: \n"
+ ".set at \n"
+ ".set reorder \n" :
+ [val] "+m"(*word), [tmp] "=&r"(tmp)
+ : : "memory");
+
+ return tmp != 0; /* normalize to 0 or 1 */
+}
+
+/**
+ * Releases bit lock
+ *
+ * Unconditionally clears bit 31 of the lock word. Note that this is
+ * done non-atomically, as this implementation assumes that the rest
+ * of the bits in the word are protected by the lock.
+ *
+ * @word: word to unlock bit 31 in
+ */
+static inline void cvmx_spinlock_bit_unlock(uint32_t *word)
+{
+ CVMX_SYNCWS;
+ *word &= ~(1UL << 31);
+ CVMX_SYNCWS;
+}
+
+#endif /* __CVMX_SPINLOCK_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-sysinfo.h b/arch/mips/include/asm/octeon/cvmx-sysinfo.h
new file mode 100644
index 00000000..61dd5741
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-sysinfo.h
@@ -0,0 +1,152 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * This module provides system/board information obtained by the bootloader.
+ */
+
+#ifndef __CVMX_SYSINFO_H__
+#define __CVMX_SYSINFO_H__
+
+#define OCTEON_SERIAL_LEN 20
+/**
+ * Structure describing application specific information.
+ * __cvmx_app_init() populates this from the cvmx boot descriptor.
+ * This structure is private to simple executive applications, so
+ * no versioning is required.
+ *
+ * This structure must be provided with some fields set in order to
+ * use simple executive functions in other applications (Linux kernel,
+ * u-boot, etc.) The cvmx_sysinfo_minimal_initialize() function is
+ * provided to set the required values in these cases.
+ */
+struct cvmx_sysinfo {
+ /* System wide variables */
+ /* installed DRAM in system, in bytes */
+ uint64_t system_dram_size;
+
+ /* ptr to memory descriptor block */
+ void *phy_mem_desc_ptr;
+
+
+ /* Application image specific variables */
+ /* stack top address (virtual) */
+ uint64_t stack_top;
+ /* heap base address (virtual) */
+ uint64_t heap_base;
+ /* stack size in bytes */
+ uint32_t stack_size;
+ /* heap size in bytes */
+ uint32_t heap_size;
+ /* coremask defining cores running application */
+ uint32_t core_mask;
+ /* Deprecated, use cvmx_coremask_first_core() to select init core */
+ uint32_t init_core;
+
+ /* exception base address, as set by bootloader */
+ uint64_t exception_base_addr;
+
+ /* cpu clock speed in hz */
+ uint32_t cpu_clock_hz;
+
+ /* dram data rate in hz (data rate = 2 * clock rate */
+ uint32_t dram_data_rate_hz;
+
+
+ uint16_t board_type;
+ uint8_t board_rev_major;
+ uint8_t board_rev_minor;
+ uint8_t mac_addr_base[6];
+ uint8_t mac_addr_count;
+ char board_serial_number[OCTEON_SERIAL_LEN];
+ /*
+ * Several boards support compact flash on the Octeon boot
+ * bus. The CF memory spaces may be mapped to different
+ * addresses on different boards. These values will be 0 if
+ * CF is not present. Note that these addresses are physical
+ * addresses, and it is up to the application to use the
+ * proper addressing mode (XKPHYS, KSEG0, etc.)
+ */
+ uint64_t compact_flash_common_base_addr;
+ uint64_t compact_flash_attribute_base_addr;
+ /*
+ * Base address of the LED display (as on EBT3000 board) This
+ * will be 0 if LED display not present. Note that this
+ * address is a physical address, and it is up to the
+ * application to use the proper addressing mode (XKPHYS,
+ * KSEG0, etc.)
+ */
+ uint64_t led_display_base_addr;
+ /* DFA reference clock in hz (if applicable)*/
+ uint32_t dfa_ref_clock_hz;
+ /* configuration flags from bootloader */
+ uint32_t bootloader_config_flags;
+
+ /* Uart number used for console */
+ uint8_t console_uart_num;
+};
+
+/**
+ * This function returns the system/board information as obtained
+ * by the bootloader.
+ *
+ *
+ * Returns Pointer to the boot information structure
+ *
+ */
+
+extern struct cvmx_sysinfo *cvmx_sysinfo_get(void);
+
+/**
+ * This function is used in non-simple executive environments (such as
+ * Linux kernel, u-boot, etc.) to configure the minimal fields that
+ * are required to use simple executive files directly.
+ *
+ * Locking (if required) must be handled outside of this
+ * function
+ *
+ * @phy_mem_desc_ptr: Pointer to global physical memory descriptor
+ * (bootmem descriptor) @board_type: Octeon board
+ * type enumeration
+ *
+ * @board_rev_major:
+ * Board major revision
+ * @board_rev_minor:
+ * Board minor revision
+ * @cpu_clock_hz:
+ * CPU clock freqency in hertz
+ *
+ * Returns 0: Failure
+ * 1: success
+ */
+extern int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr,
+ uint16_t board_type,
+ uint8_t board_rev_major,
+ uint8_t board_rev_minor,
+ uint32_t cpu_clock_hz);
+
+#endif /* __CVMX_SYSINFO_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
new file mode 100644
index 00000000..594f1b68
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
@@ -0,0 +1,261 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2010 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_UCTLX_TYPEDEFS_H__
+#define __CVMX_UCTLX_TYPEDEFS_H__
+
+#define CVMX_UCTLX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A0ull))
+#define CVMX_UCTLX_CLK_RST_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000000ull))
+#define CVMX_UCTLX_EHCI_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000080ull))
+#define CVMX_UCTLX_EHCI_FLA(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A8ull))
+#define CVMX_UCTLX_ERTO_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000090ull))
+#define CVMX_UCTLX_IF_ENA(block_id) (CVMX_ADD_IO_SEG(0x000118006F000030ull))
+#define CVMX_UCTLX_INT_ENA(block_id) (CVMX_ADD_IO_SEG(0x000118006F000028ull))
+#define CVMX_UCTLX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x000118006F000020ull))
+#define CVMX_UCTLX_OHCI_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000088ull))
+#define CVMX_UCTLX_ORTO_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000098ull))
+#define CVMX_UCTLX_PPAF_WM(block_id) (CVMX_ADD_IO_SEG(0x000118006F000038ull))
+#define CVMX_UCTLX_UPHY_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F000008ull))
+#define CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(offset, block_id) (CVMX_ADD_IO_SEG(0x000118006F000010ull) + (((offset) & 1) + ((block_id) & 0) * 0x0ull) * 8)
+
+union cvmx_uctlx_bist_status {
+ uint64_t u64;
+ struct cvmx_uctlx_bist_status_s {
+ uint64_t reserved_6_63:58;
+ uint64_t data_bis:1;
+ uint64_t desc_bis:1;
+ uint64_t erbm_bis:1;
+ uint64_t orbm_bis:1;
+ uint64_t wrbm_bis:1;
+ uint64_t ppaf_bis:1;
+ } s;
+ struct cvmx_uctlx_bist_status_s cn63xx;
+ struct cvmx_uctlx_bist_status_s cn63xxp1;
+};
+
+union cvmx_uctlx_clk_rst_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_clk_rst_ctl_s {
+ uint64_t reserved_25_63:39;
+ uint64_t clear_bist:1;
+ uint64_t start_bist:1;
+ uint64_t ehci_sm:1;
+ uint64_t ohci_clkcktrst:1;
+ uint64_t ohci_sm:1;
+ uint64_t ohci_susp_lgcy:1;
+ uint64_t app_start_clk:1;
+ uint64_t o_clkdiv_rst:1;
+ uint64_t h_clkdiv_byp:1;
+ uint64_t h_clkdiv_rst:1;
+ uint64_t h_clkdiv_en:1;
+ uint64_t o_clkdiv_en:1;
+ uint64_t h_div:4;
+ uint64_t p_refclk_sel:2;
+ uint64_t p_refclk_div:2;
+ uint64_t reserved_4_4:1;
+ uint64_t p_com_on:1;
+ uint64_t p_por:1;
+ uint64_t p_prst:1;
+ uint64_t hrst:1;
+ } s;
+ struct cvmx_uctlx_clk_rst_ctl_s cn63xx;
+ struct cvmx_uctlx_clk_rst_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_ehci_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_ehci_ctl_s {
+ uint64_t reserved_20_63:44;
+ uint64_t desc_rbm:1;
+ uint64_t reg_nb:1;
+ uint64_t l2c_dc:1;
+ uint64_t l2c_bc:1;
+ uint64_t l2c_0pag:1;
+ uint64_t l2c_stt:1;
+ uint64_t l2c_buff_emod:2;
+ uint64_t l2c_desc_emod:2;
+ uint64_t inv_reg_a2:1;
+ uint64_t ehci_64b_addr_en:1;
+ uint64_t l2c_addr_msb:8;
+ } s;
+ struct cvmx_uctlx_ehci_ctl_s cn63xx;
+ struct cvmx_uctlx_ehci_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_ehci_fla {
+ uint64_t u64;
+ struct cvmx_uctlx_ehci_fla_s {
+ uint64_t reserved_6_63:58;
+ uint64_t fla:6;
+ } s;
+ struct cvmx_uctlx_ehci_fla_s cn63xx;
+ struct cvmx_uctlx_ehci_fla_s cn63xxp1;
+};
+
+union cvmx_uctlx_erto_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_erto_ctl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t to_val:27;
+ uint64_t reserved_0_4:5;
+ } s;
+ struct cvmx_uctlx_erto_ctl_s cn63xx;
+ struct cvmx_uctlx_erto_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_if_ena {
+ uint64_t u64;
+ struct cvmx_uctlx_if_ena_s {
+ uint64_t reserved_1_63:63;
+ uint64_t en:1;
+ } s;
+ struct cvmx_uctlx_if_ena_s cn63xx;
+ struct cvmx_uctlx_if_ena_s cn63xxp1;
+};
+
+union cvmx_uctlx_int_ena {
+ uint64_t u64;
+ struct cvmx_uctlx_int_ena_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ec_ovf_e:1;
+ uint64_t oc_ovf_e:1;
+ uint64_t wb_pop_e:1;
+ uint64_t wb_psh_f:1;
+ uint64_t cf_psh_f:1;
+ uint64_t or_psh_f:1;
+ uint64_t er_psh_f:1;
+ uint64_t pp_psh_f:1;
+ } s;
+ struct cvmx_uctlx_int_ena_s cn63xx;
+ struct cvmx_uctlx_int_ena_s cn63xxp1;
+};
+
+union cvmx_uctlx_int_reg {
+ uint64_t u64;
+ struct cvmx_uctlx_int_reg_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ec_ovf_e:1;
+ uint64_t oc_ovf_e:1;
+ uint64_t wb_pop_e:1;
+ uint64_t wb_psh_f:1;
+ uint64_t cf_psh_f:1;
+ uint64_t or_psh_f:1;
+ uint64_t er_psh_f:1;
+ uint64_t pp_psh_f:1;
+ } s;
+ struct cvmx_uctlx_int_reg_s cn63xx;
+ struct cvmx_uctlx_int_reg_s cn63xxp1;
+};
+
+union cvmx_uctlx_ohci_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_ohci_ctl_s {
+ uint64_t reserved_19_63:45;
+ uint64_t reg_nb:1;
+ uint64_t l2c_dc:1;
+ uint64_t l2c_bc:1;
+ uint64_t l2c_0pag:1;
+ uint64_t l2c_stt:1;
+ uint64_t l2c_buff_emod:2;
+ uint64_t l2c_desc_emod:2;
+ uint64_t inv_reg_a2:1;
+ uint64_t reserved_8_8:1;
+ uint64_t l2c_addr_msb:8;
+ } s;
+ struct cvmx_uctlx_ohci_ctl_s cn63xx;
+ struct cvmx_uctlx_ohci_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_orto_ctl {
+ uint64_t u64;
+ struct cvmx_uctlx_orto_ctl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t to_val:24;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_uctlx_orto_ctl_s cn63xx;
+ struct cvmx_uctlx_orto_ctl_s cn63xxp1;
+};
+
+union cvmx_uctlx_ppaf_wm {
+ uint64_t u64;
+ struct cvmx_uctlx_ppaf_wm_s {
+ uint64_t reserved_5_63:59;
+ uint64_t wm:5;
+ } s;
+ struct cvmx_uctlx_ppaf_wm_s cn63xx;
+ struct cvmx_uctlx_ppaf_wm_s cn63xxp1;
+};
+
+union cvmx_uctlx_uphy_ctl_status {
+ uint64_t u64;
+ struct cvmx_uctlx_uphy_ctl_status_s {
+ uint64_t reserved_10_63:54;
+ uint64_t bist_done:1;
+ uint64_t bist_err:1;
+ uint64_t hsbist:1;
+ uint64_t fsbist:1;
+ uint64_t lsbist:1;
+ uint64_t siddq:1;
+ uint64_t vtest_en:1;
+ uint64_t uphy_bist:1;
+ uint64_t bist_en:1;
+ uint64_t ate_reset:1;
+ } s;
+ struct cvmx_uctlx_uphy_ctl_status_s cn63xx;
+ struct cvmx_uctlx_uphy_ctl_status_s cn63xxp1;
+};
+
+union cvmx_uctlx_uphy_portx_ctl_status {
+ uint64_t u64;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s {
+ uint64_t reserved_43_63:21;
+ uint64_t tdata_out:4;
+ uint64_t txbiststuffenh:1;
+ uint64_t txbiststuffen:1;
+ uint64_t dmpulldown:1;
+ uint64_t dppulldown:1;
+ uint64_t vbusvldext:1;
+ uint64_t portreset:1;
+ uint64_t txhsvxtune:2;
+ uint64_t txvreftune:4;
+ uint64_t txrisetune:1;
+ uint64_t txpreemphasistune:1;
+ uint64_t txfslstune:4;
+ uint64_t sqrxtune:3;
+ uint64_t compdistune:3;
+ uint64_t loop_en:1;
+ uint64_t tclk:1;
+ uint64_t tdata_sel:1;
+ uint64_t taddr_in:4;
+ uint64_t tdata_in:8;
+ } s;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xx;
+ struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
new file mode 100644
index 00000000..7e128670
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -0,0 +1,517 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_H__
+#define __CVMX_H__
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include "cvmx-asm.h"
+#include "cvmx-packet.h"
+#include "cvmx-sysinfo.h"
+
+#include "cvmx-ciu-defs.h"
+#include "cvmx-gpio-defs.h"
+#include "cvmx-iob-defs.h"
+#include "cvmx-ipd-defs.h"
+#include "cvmx-l2c-defs.h"
+#include "cvmx-l2d-defs.h"
+#include "cvmx-l2t-defs.h"
+#include "cvmx-led-defs.h"
+#include "cvmx-mio-defs.h"
+#include "cvmx-pow-defs.h"
+
+#include "cvmx-bootinfo.h"
+#include "cvmx-bootmem.h"
+#include "cvmx-l2c.h"
+
+#ifndef CVMX_ENABLE_DEBUG_PRINTS
+#define CVMX_ENABLE_DEBUG_PRINTS 1
+#endif
+
+#if CVMX_ENABLE_DEBUG_PRINTS
+#define cvmx_dprintf printk
+#else
+#define cvmx_dprintf(...) {}
+#endif
+
+#define CVMX_MAX_CORES (16)
+#define CVMX_CACHE_LINE_SIZE (128) /* In bytes */
+#define CVMX_CACHE_LINE_MASK (CVMX_CACHE_LINE_SIZE - 1) /* In bytes */
+#define CVMX_CACHE_LINE_ALIGNED __attribute__ ((aligned(CVMX_CACHE_LINE_SIZE)))
+#define CAST64(v) ((long long)(long)(v))
+#define CASTPTR(type, v) ((type *)(long)(v))
+
+/*
+ * Returns processor ID, different Linux and simple exec versions
+ * provided in the cvmx-app-init*.c files.
+ */
+static inline uint32_t cvmx_get_proc_id(void) __attribute__ ((pure));
+static inline uint32_t cvmx_get_proc_id(void)
+{
+ uint32_t id;
+ asm("mfc0 %0, $15,0" : "=r"(id));
+ return id;
+}
+
+/* turn the variable name into a string */
+#define CVMX_TMP_STR(x) CVMX_TMP_STR2(x)
+#define CVMX_TMP_STR2(x) #x
+
+/**
+ * Builds a bit mask given the required size in bits.
+ *
+ * @bits: Number of bits in the mask
+ * Returns The mask
+ */ static inline uint64_t cvmx_build_mask(uint64_t bits)
+{
+ return ~((~0x0ull) << bits);
+}
+
+/**
+ * Builds a memory address for I/O based on the Major and Sub DID.
+ *
+ * @major_did: 5 bit major did
+ * @sub_did: 3 bit sub did
+ * Returns I/O base address
+ */
+static inline uint64_t cvmx_build_io_address(uint64_t major_did,
+ uint64_t sub_did)
+{
+ return (0x1ull << 48) | (major_did << 43) | (sub_did << 40);
+}
+
+/**
+ * Perform mask and shift to place the supplied value into
+ * the supplied bit rage.
+ *
+ * Example: cvmx_build_bits(39,24,value)
+ * <pre>
+ * 6 5 4 3 3 2 1
+ * 3 5 7 9 1 3 5 7 0
+ * +-------+-------+-------+-------+-------+-------+-------+------+
+ * 000000000000000000000000___________value000000000000000000000000
+ * </pre>
+ *
+ * @high_bit: Highest bit value can occupy (inclusive) 0-63
+ * @low_bit: Lowest bit value can occupy inclusive 0-high_bit
+ * @value: Value to use
+ * Returns Value masked and shifted
+ */
+static inline uint64_t cvmx_build_bits(uint64_t high_bit,
+ uint64_t low_bit, uint64_t value)
+{
+ return (value & cvmx_build_mask(high_bit - low_bit + 1)) << low_bit;
+}
+
+enum cvmx_mips_space {
+ CVMX_MIPS_SPACE_XKSEG = 3LL,
+ CVMX_MIPS_SPACE_XKPHYS = 2LL,
+ CVMX_MIPS_SPACE_XSSEG = 1LL,
+ CVMX_MIPS_SPACE_XUSEG = 0LL
+};
+
+/* These macros for use when using 32 bit pointers. */
+#define CVMX_MIPS32_SPACE_KSEG0 1l
+#define CVMX_ADD_SEG32(segment, add) \
+ (((int32_t)segment << 31) | (int32_t)(add))
+
+#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
+
+/* These macros simplify the process of creating common IO addresses */
+#define CVMX_ADD_SEG(segment, add) \
+ ((((uint64_t)segment) << 62) | (add))
+#ifndef CVMX_ADD_IO_SEG
+#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
+#endif
+
+/**
+ * Convert a memory pointer (void*) into a hardware compatible
+ * memory address (uint64_t). Octeon hardware widgets don't
+ * understand logical addresses.
+ *
+ * @ptr: C style memory pointer
+ * Returns Hardware physical address
+ */
+static inline uint64_t cvmx_ptr_to_phys(void *ptr)
+{
+ if (sizeof(void *) == 8) {
+ /*
+ * We're running in 64 bit mode. Normally this means
+ * that we can use 40 bits of address space (the
+ * hardware limit). Unfortunately there is one case
+ * were we need to limit this to 30 bits, sign
+ * extended 32 bit. Although these are 64 bits wide,
+ * only 30 bits can be used.
+ */
+ if ((CAST64(ptr) >> 62) == 3)
+ return CAST64(ptr) & cvmx_build_mask(30);
+ else
+ return CAST64(ptr) & cvmx_build_mask(40);
+ } else {
+ return (long)(ptr) & 0x1fffffff;
+ }
+}
+
+/**
+ * Convert a hardware physical address (uint64_t) into a
+ * memory pointer (void *).
+ *
+ * @physical_address:
+ * Hardware physical address to memory
+ * Returns Pointer to memory
+ */
+static inline void *cvmx_phys_to_ptr(uint64_t physical_address)
+{
+ if (sizeof(void *) == 8) {
+ /* Just set the top bit, avoiding any TLB uglyness */
+ return CASTPTR(void,
+ CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ physical_address));
+ } else {
+ return CASTPTR(void,
+ CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0,
+ physical_address));
+ }
+}
+
+/* The following #if controls the definition of the macro
+ CVMX_BUILD_WRITE64. This macro is used to build a store operation to
+ a full 64bit address. With a 64bit ABI, this can be done with a simple
+ pointer access. 32bit ABIs require more complicated assembly */
+
+/* We have a full 64bit ABI. Writing to a 64bit address can be done with
+ a simple volatile pointer */
+#define CVMX_BUILD_WRITE64(TYPE, ST) \
+static inline void cvmx_write64_##TYPE(uint64_t addr, TYPE##_t val) \
+{ \
+ *CASTPTR(volatile TYPE##_t, addr) = val; \
+}
+
+
+/* The following #if controls the definition of the macro
+ CVMX_BUILD_READ64. This macro is used to build a load operation from
+ a full 64bit address. With a 64bit ABI, this can be done with a simple
+ pointer access. 32bit ABIs require more complicated assembly */
+
+/* We have a full 64bit ABI. Writing to a 64bit address can be done with
+ a simple volatile pointer */
+#define CVMX_BUILD_READ64(TYPE, LT) \
+static inline TYPE##_t cvmx_read64_##TYPE(uint64_t addr) \
+{ \
+ return *CASTPTR(volatile TYPE##_t, addr); \
+}
+
+
+/* The following defines 8 functions for writing to a 64bit address. Each
+ takes two arguments, the address and the value to write.
+ cvmx_write64_int64 cvmx_write64_uint64
+ cvmx_write64_int32 cvmx_write64_uint32
+ cvmx_write64_int16 cvmx_write64_uint16
+ cvmx_write64_int8 cvmx_write64_uint8 */
+CVMX_BUILD_WRITE64(int64, "sd");
+CVMX_BUILD_WRITE64(int32, "sw");
+CVMX_BUILD_WRITE64(int16, "sh");
+CVMX_BUILD_WRITE64(int8, "sb");
+CVMX_BUILD_WRITE64(uint64, "sd");
+CVMX_BUILD_WRITE64(uint32, "sw");
+CVMX_BUILD_WRITE64(uint16, "sh");
+CVMX_BUILD_WRITE64(uint8, "sb");
+#define cvmx_write64 cvmx_write64_uint64
+
+/* The following defines 8 functions for reading from a 64bit address. Each
+ takes the address as the only argument
+ cvmx_read64_int64 cvmx_read64_uint64
+ cvmx_read64_int32 cvmx_read64_uint32
+ cvmx_read64_int16 cvmx_read64_uint16
+ cvmx_read64_int8 cvmx_read64_uint8 */
+CVMX_BUILD_READ64(int64, "ld");
+CVMX_BUILD_READ64(int32, "lw");
+CVMX_BUILD_READ64(int16, "lh");
+CVMX_BUILD_READ64(int8, "lb");
+CVMX_BUILD_READ64(uint64, "ld");
+CVMX_BUILD_READ64(uint32, "lw");
+CVMX_BUILD_READ64(uint16, "lhu");
+CVMX_BUILD_READ64(uint8, "lbu");
+#define cvmx_read64 cvmx_read64_uint64
+
+
+static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val)
+{
+ cvmx_write64(csr_addr, val);
+
+ /*
+ * Perform an immediate read after every write to an RSL
+ * register to force the write to complete. It doesn't matter
+ * what RSL read we do, so we choose CVMX_MIO_BOOT_BIST_STAT
+ * because it is fast and harmless.
+ */
+ if (((csr_addr >> 40) & 0x7ffff) == (0x118))
+ cvmx_read64(CVMX_MIO_BOOT_BIST_STAT);
+}
+
+static inline void cvmx_write_io(uint64_t io_addr, uint64_t val)
+{
+ cvmx_write64(io_addr, val);
+
+}
+
+static inline uint64_t cvmx_read_csr(uint64_t csr_addr)
+{
+ uint64_t val = cvmx_read64(csr_addr);
+ return val;
+}
+
+
+static inline void cvmx_send_single(uint64_t data)
+{
+ const uint64_t CVMX_IOBDMA_SENDSINGLE = 0xffffffffffffa200ull;
+ cvmx_write64(CVMX_IOBDMA_SENDSINGLE, data);
+}
+
+static inline void cvmx_read_csr_async(uint64_t scraddr, uint64_t csr_addr)
+{
+ union {
+ uint64_t u64;
+ struct {
+ uint64_t scraddr:8;
+ uint64_t len:8;
+ uint64_t addr:48;
+ } s;
+ } addr;
+ addr.u64 = csr_addr;
+ addr.s.scraddr = scraddr >> 3;
+ addr.s.len = 1;
+ cvmx_send_single(addr.u64);
+}
+
+/* Return true if Octeon is CN38XX pass 1 */
+static inline int cvmx_octeon_is_pass1(void)
+{
+#if OCTEON_IS_COMMON_BINARY()
+ return 0; /* Pass 1 isn't supported for common binaries */
+#else
+/* Now that we know we're built for a specific model, only check CN38XX */
+#if OCTEON_IS_MODEL(OCTEON_CN38XX)
+ return cvmx_get_proc_id() == OCTEON_CN38XX_PASS1;
+#else
+ return 0; /* Built for non CN38XX chip, we're not CN38XX pass1 */
+#endif
+#endif
+}
+
+static inline unsigned int cvmx_get_core_num(void)
+{
+ unsigned int core_num;
+ CVMX_RDHWRNV(core_num, 0);
+ return core_num;
+}
+
+/**
+ * Returns the number of bits set in the provided value.
+ * Simple wrapper for POP instruction.
+ *
+ * @val: 32 bit value to count set bits in
+ *
+ * Returns Number of bits set
+ */
+static inline uint32_t cvmx_pop(uint32_t val)
+{
+ uint32_t pop;
+ CVMX_POP(pop, val);
+ return pop;
+}
+
+/**
+ * Returns the number of bits set in the provided value.
+ * Simple wrapper for DPOP instruction.
+ *
+ * @val: 64 bit value to count set bits in
+ *
+ * Returns Number of bits set
+ */
+static inline int cvmx_dpop(uint64_t val)
+{
+ int pop;
+ CVMX_DPOP(pop, val);
+ return pop;
+}
+
+/**
+ * Provide current cycle counter as a return value
+ *
+ * Returns current cycle counter
+ */
+
+static inline uint64_t cvmx_get_cycle(void)
+{
+ uint64_t cycle;
+ CVMX_RDHWR(cycle, 31);
+ return cycle;
+}
+
+/**
+ * Wait for the specified number of cycle
+ *
+ */
+static inline void cvmx_wait(uint64_t cycles)
+{
+ uint64_t done = cvmx_get_cycle() + cycles;
+
+ while (cvmx_get_cycle() < done)
+ ; /* Spin */
+}
+
+/**
+ * Reads a chip global cycle counter. This counts CPU cycles since
+ * chip reset. The counter is 64 bit.
+ * This register does not exist on CN38XX pass 1 silicion
+ *
+ * Returns Global chip cycle count since chip reset.
+ */
+static inline uint64_t cvmx_get_cycle_global(void)
+{
+ if (cvmx_octeon_is_pass1())
+ return 0;
+ else
+ return cvmx_read64(CVMX_IPD_CLK_COUNT);
+}
+
+/**
+ * This macro spins on a field waiting for it to reach a value. It
+ * is common in code to need to wait for a specific field in a CSR
+ * to match a specific value. Conceptually this macro expands to:
+ *
+ * 1) read csr at "address" with a csr typedef of "type"
+ * 2) Check if ("type".s."field" "op" "value")
+ * 3) If #2 isn't true loop to #1 unless too much time has passed.
+ */
+#define CVMX_WAIT_FOR_FIELD64(address, type, field, op, value, timeout_usec)\
+ ( \
+{ \
+ int result; \
+ do { \
+ uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
+ cvmx_sysinfo_get()->cpu_clock_hz / 1000000; \
+ type c; \
+ while (1) { \
+ c.u64 = cvmx_read_csr(address); \
+ if ((c.s.field) op(value)) { \
+ result = 0; \
+ break; \
+ } else if (cvmx_get_cycle() > done) { \
+ result = -1; \
+ break; \
+ } else \
+ cvmx_wait(100); \
+ } \
+ } while (0); \
+ result; \
+})
+
+/***************************************************************************/
+
+static inline void cvmx_reset_octeon(void)
+{
+ union cvmx_ciu_soft_rst ciu_soft_rst;
+ ciu_soft_rst.u64 = 0;
+ ciu_soft_rst.s.soft_rst = 1;
+ cvmx_write_csr(CVMX_CIU_SOFT_RST, ciu_soft_rst.u64);
+}
+
+/* Return the number of cores available in the chip */
+static inline uint32_t cvmx_octeon_num_cores(void)
+{
+ uint32_t ciu_fuse = (uint32_t) cvmx_read_csr(CVMX_CIU_FUSE) & 0xffff;
+ return cvmx_pop(ciu_fuse);
+}
+
+/**
+ * Read a byte of fuse data
+ * @byte_addr: address to read
+ *
+ * Returns fuse value: 0 or 1
+ */
+static uint8_t cvmx_fuse_read_byte(int byte_addr)
+{
+ union cvmx_mio_fus_rcmd read_cmd;
+
+ read_cmd.u64 = 0;
+ read_cmd.s.addr = byte_addr;
+ read_cmd.s.pend = 1;
+ cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
+ while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
+ && read_cmd.s.pend)
+ ;
+ return read_cmd.s.dat;
+}
+
+/**
+ * Read a single fuse bit
+ *
+ * @fuse: Fuse number (0-1024)
+ *
+ * Returns fuse value: 0 or 1
+ */
+static inline int cvmx_fuse_read(int fuse)
+{
+ return (cvmx_fuse_read_byte(fuse >> 3) >> (fuse & 0x7)) & 1;
+}
+
+static inline int cvmx_octeon_model_CN36XX(void)
+{
+ return OCTEON_IS_MODEL(OCTEON_CN38XX)
+ && !cvmx_octeon_is_pass1()
+ && cvmx_fuse_read(264);
+}
+
+static inline int cvmx_octeon_zip_present(void)
+{
+ return octeon_has_feature(OCTEON_FEATURE_ZIP);
+}
+
+static inline int cvmx_octeon_dfa_present(void)
+{
+ if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
+ && !OCTEON_IS_MODEL(OCTEON_CN31XX)
+ && !OCTEON_IS_MODEL(OCTEON_CN58XX))
+ return 0;
+ else if (OCTEON_IS_MODEL(OCTEON_CN3020))
+ return 0;
+ else if (cvmx_octeon_is_pass1())
+ return 1;
+ else
+ return !cvmx_fuse_read(120);
+}
+
+static inline int cvmx_octeon_crypto_present(void)
+{
+ return octeon_has_feature(OCTEON_FEATURE_CRYPTO);
+}
+
+#endif /* __CVMX_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h
new file mode 100644
index 00000000..cba6fbed
--- /dev/null
+++ b/arch/mips/include/asm/octeon/octeon-feature.h
@@ -0,0 +1,142 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * File defining checks for different Octeon features.
+ */
+
+#ifndef __OCTEON_FEATURE_H__
+#define __OCTEON_FEATURE_H__
+
+enum octeon_feature {
+ /*
+ * Octeon models in the CN5XXX family and higher support
+ * atomic add instructions to memory (saa/saad).
+ */
+ OCTEON_FEATURE_SAAD,
+ /* Does this Octeon support the ZIP offload engine? */
+ OCTEON_FEATURE_ZIP,
+ /* Does this Octeon support crypto acceleration using COP2? */
+ OCTEON_FEATURE_CRYPTO,
+ /* Does this Octeon support PCI express? */
+ OCTEON_FEATURE_PCIE,
+ /* Some Octeon models support internal memory for storing
+ * cryptographic keys */
+ OCTEON_FEATURE_KEY_MEMORY,
+ /* Octeon has a LED controller for banks of external LEDs */
+ OCTEON_FEATURE_LED_CONTROLLER,
+ /* Octeon has a trace buffer */
+ OCTEON_FEATURE_TRA,
+ /* Octeon has a management port */
+ OCTEON_FEATURE_MGMT_PORT,
+ /* Octeon has a raid unit */
+ OCTEON_FEATURE_RAID,
+ /* Octeon has a builtin USB */
+ OCTEON_FEATURE_USB,
+ /* Octeon IPD can run without using work queue entries */
+ OCTEON_FEATURE_NO_WPTR,
+ /* Octeon has DFA state machines */
+ OCTEON_FEATURE_DFA,
+ /* Octeon MDIO block supports clause 45 transactions for 10
+ * Gig support */
+ OCTEON_FEATURE_MDIO_CLAUSE_45,
+};
+
+static inline int cvmx_fuse_read(int fuse);
+
+/**
+ * Determine if the current Octeon supports a specific feature. These
+ * checks have been optimized to be fairly quick, but they should still
+ * be kept out of fast path code.
+ *
+ * @feature: Feature to check for. This should always be a constant so the
+ * compiler can remove the switch statement through optimization.
+ *
+ * Returns Non zero if the feature exists. Zero if the feature does not
+ * exist.
+ */
+static inline int octeon_has_feature(enum octeon_feature feature)
+{
+ switch (feature) {
+ case OCTEON_FEATURE_SAAD:
+ return !OCTEON_IS_MODEL(OCTEON_CN3XXX);
+
+ case OCTEON_FEATURE_ZIP:
+ if (OCTEON_IS_MODEL(OCTEON_CN30XX)
+ || OCTEON_IS_MODEL(OCTEON_CN50XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX))
+ return 0;
+ else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
+ return 1;
+ else
+ return !cvmx_fuse_read(121);
+
+ case OCTEON_FEATURE_CRYPTO:
+ return !cvmx_fuse_read(90);
+
+ case OCTEON_FEATURE_PCIE:
+ case OCTEON_FEATURE_MGMT_PORT:
+ case OCTEON_FEATURE_RAID:
+ return OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX);
+
+ case OCTEON_FEATURE_KEY_MEMORY:
+ case OCTEON_FEATURE_LED_CONTROLLER:
+ return OCTEON_IS_MODEL(OCTEON_CN38XX)
+ || OCTEON_IS_MODEL(OCTEON_CN58XX)
+ || OCTEON_IS_MODEL(OCTEON_CN56XX);
+ case OCTEON_FEATURE_TRA:
+ return !(OCTEON_IS_MODEL(OCTEON_CN30XX)
+ || OCTEON_IS_MODEL(OCTEON_CN50XX));
+ case OCTEON_FEATURE_USB:
+ return !(OCTEON_IS_MODEL(OCTEON_CN38XX)
+ || OCTEON_IS_MODEL(OCTEON_CN58XX));
+ case OCTEON_FEATURE_NO_WPTR:
+ return (OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX))
+ && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+ && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X);
+ case OCTEON_FEATURE_DFA:
+ if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
+ && !OCTEON_IS_MODEL(OCTEON_CN31XX)
+ && !OCTEON_IS_MODEL(OCTEON_CN58XX))
+ return 0;
+ else if (OCTEON_IS_MODEL(OCTEON_CN3020))
+ return 0;
+ else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
+ return 1;
+ else
+ return !cvmx_fuse_read(120);
+ case OCTEON_FEATURE_MDIO_CLAUSE_45:
+ return !(OCTEON_IS_MODEL(OCTEON_CN3XXX)
+ || OCTEON_IS_MODEL(OCTEON_CN58XX)
+ || OCTEON_IS_MODEL(OCTEON_CN50XX));
+ }
+ return 0;
+}
+
+#endif /* __OCTEON_FEATURE_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
new file mode 100644
index 00000000..700f88e3
--- /dev/null
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -0,0 +1,341 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * File defining different Octeon model IDs and macros to
+ * compare them.
+ *
+ */
+
+#ifndef __OCTEON_MODEL_H__
+#define __OCTEON_MODEL_H__
+
+/*
+ * The defines below should be used with the OCTEON_IS_MODEL() macro
+ * to determine what model of chip the software is running on. Models
+ * ending in 'XX' match multiple models (families), while specific
+ * models match only that model. If a pass (revision) is specified,
+ * then only that revision will be matched. Care should be taken when
+ * checking for both specific models and families that the specific
+ * models are checked for first. While these defines are similar to
+ * the processor ID, they are not intended to be used by anything
+ * other that the OCTEON_IS_MODEL framework, and the values are
+ * subject to change at anytime without notice.
+ *
+ * NOTE: only the OCTEON_IS_MODEL() macro/function and the OCTEON_CN*
+ * macros should be used outside of this file. All other macros are
+ * for internal use only, and may change without notice.
+ */
+
+/* Flag bits in top byte */
+/* Ignores revision in model checks */
+#define OM_IGNORE_REVISION 0x01000000
+/* Check submodels */
+#define OM_CHECK_SUBMODEL 0x02000000
+/* Match all models previous than the one specified */
+#define OM_MATCH_PREVIOUS_MODELS 0x04000000
+/* Ignores the minor revison on newer parts */
+#define OM_IGNORE_MINOR_REVISION 0x08000000
+#define OM_FLAG_MASK 0xff000000
+
+#define OM_MATCH_5XXX_FAMILY_MODELS 0x20000000 /* Match all cn5XXX Octeon models. */
+#define OM_MATCH_6XXX_FAMILY_MODELS 0x40000000 /* Match all cn6XXX Octeon models. */
+
+/*
+ * CN6XXX models with new revision encoding
+ */
+#define OCTEON_CN63XX_PASS1_0 0x000d9000
+#define OCTEON_CN63XX_PASS1_1 0x000d9001
+#define OCTEON_CN63XX_PASS1_2 0x000d9002
+#define OCTEON_CN63XX_PASS2_0 0x000d9008
+
+#define OCTEON_CN63XX (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN63XX_PASS1_X (OCTEON_CN63XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN63XX_PASS2_X (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
+
+/*
+ * CN5XXX models with new revision encoding
+ */
+#define OCTEON_CN58XX_PASS1_0 0x000d0300
+#define OCTEON_CN58XX_PASS1_1 0x000d0301
+#define OCTEON_CN58XX_PASS1_2 0x000d0303
+#define OCTEON_CN58XX_PASS2_0 0x000d0308
+#define OCTEON_CN58XX_PASS2_1 0x000d0309
+#define OCTEON_CN58XX_PASS2_2 0x000d030a
+#define OCTEON_CN58XX_PASS2_3 0x000d030b
+
+#define OCTEON_CN58XX (OCTEON_CN58XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN58XX_PASS1_X (OCTEON_CN58XX_PASS1_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN58XX_PASS2_X (OCTEON_CN58XX_PASS2_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN58XX_PASS1 OCTEON_CN58XX_PASS1_X
+#define OCTEON_CN58XX_PASS2 OCTEON_CN58XX_PASS2_X
+
+#define OCTEON_CN56XX_PASS1_0 0x000d0400
+#define OCTEON_CN56XX_PASS1_1 0x000d0401
+#define OCTEON_CN56XX_PASS2_0 0x000d0408
+#define OCTEON_CN56XX_PASS2_1 0x000d0409
+
+#define OCTEON_CN56XX (OCTEON_CN56XX_PASS2_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN56XX_PASS1_X (OCTEON_CN56XX_PASS1_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN56XX_PASS2_X (OCTEON_CN56XX_PASS2_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN56XX_PASS1 OCTEON_CN56XX_PASS1_X
+#define OCTEON_CN56XX_PASS2 OCTEON_CN56XX_PASS2_X
+
+#define OCTEON_CN57XX OCTEON_CN56XX
+#define OCTEON_CN57XX_PASS1 OCTEON_CN56XX_PASS1
+#define OCTEON_CN57XX_PASS2 OCTEON_CN56XX_PASS2
+
+#define OCTEON_CN55XX OCTEON_CN56XX
+#define OCTEON_CN55XX_PASS1 OCTEON_CN56XX_PASS1
+#define OCTEON_CN55XX_PASS2 OCTEON_CN56XX_PASS2
+
+#define OCTEON_CN54XX OCTEON_CN56XX
+#define OCTEON_CN54XX_PASS1 OCTEON_CN56XX_PASS1
+#define OCTEON_CN54XX_PASS2 OCTEON_CN56XX_PASS2
+
+#define OCTEON_CN50XX_PASS1_0 0x000d0600
+
+#define OCTEON_CN50XX (OCTEON_CN50XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN50XX_PASS1_X (OCTEON_CN50XX_PASS1_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN50XX_PASS1 OCTEON_CN50XX_PASS1_X
+
+/*
+ * NOTE: Octeon CN5000F model is not identifiable using the
+ * OCTEON_IS_MODEL() functions, but are treated as CN50XX.
+ */
+
+#define OCTEON_CN52XX_PASS1_0 0x000d0700
+#define OCTEON_CN52XX_PASS2_0 0x000d0708
+
+#define OCTEON_CN52XX (OCTEON_CN52XX_PASS2_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN52XX_PASS1_X (OCTEON_CN52XX_PASS1_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN52XX_PASS2_X (OCTEON_CN52XX_PASS2_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN52XX_PASS1 OCTEON_CN52XX_PASS1_X
+#define OCTEON_CN52XX_PASS2 OCTEON_CN52XX_PASS2_X
+
+/*
+ * CN3XXX models with old revision enconding
+ */
+#define OCTEON_CN38XX_PASS1 0x000d0000
+#define OCTEON_CN38XX_PASS2 0x000d0001
+#define OCTEON_CN38XX_PASS3 0x000d0003
+#define OCTEON_CN38XX (OCTEON_CN38XX_PASS3 | OM_IGNORE_REVISION)
+
+#define OCTEON_CN36XX OCTEON_CN38XX
+#define OCTEON_CN36XX_PASS2 OCTEON_CN38XX_PASS2
+#define OCTEON_CN36XX_PASS3 OCTEON_CN38XX_PASS3
+
+/* The OCTEON_CN31XX matches CN31XX models and the CN3020 */
+#define OCTEON_CN31XX_PASS1 0x000d0100
+#define OCTEON_CN31XX_PASS1_1 0x000d0102
+#define OCTEON_CN31XX (OCTEON_CN31XX_PASS1 | OM_IGNORE_REVISION)
+
+/*
+ * This model is only used for internal checks, it is not a valid
+ * model for the OCTEON_MODEL environment variable. This matches the
+ * CN3010 and CN3005 but NOT the CN3020.
+ */
+#define OCTEON_CN30XX_PASS1 0x000d0200
+#define OCTEON_CN30XX_PASS1_1 0x000d0202
+#define OCTEON_CN30XX (OCTEON_CN30XX_PASS1 | OM_IGNORE_REVISION)
+
+#define OCTEON_CN3005_PASS1 (0x000d0210 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3005_PASS1_0 (0x000d0210 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3005_PASS1_1 (0x000d0212 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3005 (OCTEON_CN3005_PASS1 | OM_IGNORE_REVISION \
+ | OM_CHECK_SUBMODEL)
+
+#define OCTEON_CN3010_PASS1 (0x000d0200 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3010_PASS1_0 (0x000d0200 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3010_PASS1_1 (0x000d0202 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3010 (OCTEON_CN3010_PASS1 | OM_IGNORE_REVISION \
+ | OM_CHECK_SUBMODEL)
+
+#define OCTEON_CN3020_PASS1 (0x000d0110 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3020_PASS1_0 (0x000d0110 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3020_PASS1_1 (0x000d0112 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3020 (OCTEON_CN3020_PASS1 | OM_IGNORE_REVISION \
+ | OM_CHECK_SUBMODEL)
+
+
+
+/* This matches the complete family of CN3xxx CPUs, and not subsequent models */
+#define OCTEON_CN3XXX (OCTEON_CN58XX_PASS1_0 \
+ | OM_MATCH_PREVIOUS_MODELS \
+ | OM_IGNORE_REVISION)
+
+#define OCTEON_CN5XXX (OCTEON_CN58XX_PASS1_0 | OM_MATCH_5XXX_FAMILY_MODELS)
+#define OCTEON_CN6XXX (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS)
+
+/* The revision byte (low byte) has two different encodings.
+ * CN3XXX:
+ *
+ * bits
+ * <7:5>: reserved (0)
+ * <4>: alternate package
+ * <3:0>: revision
+ *
+ * CN5XXX:
+ *
+ * bits
+ * <7>: reserved (0)
+ * <6>: alternate package
+ * <5:3>: major revision
+ * <2:0>: minor revision
+ *
+ */
+
+/* Masks used for the various types of model/family/revision matching */
+#define OCTEON_38XX_FAMILY_MASK 0x00ffff00
+#define OCTEON_38XX_FAMILY_REV_MASK 0x00ffff0f
+#define OCTEON_38XX_MODEL_MASK 0x00ffff10
+#define OCTEON_38XX_MODEL_REV_MASK (OCTEON_38XX_FAMILY_REV_MASK \
+ | OCTEON_38XX_MODEL_MASK)
+
+/* CN5XXX and later use different layout of bits in the revision ID field */
+#define OCTEON_58XX_FAMILY_MASK OCTEON_38XX_FAMILY_MASK
+#define OCTEON_58XX_FAMILY_REV_MASK 0x00ffff3f
+#define OCTEON_58XX_MODEL_MASK 0x00ffffc0
+#define OCTEON_58XX_MODEL_REV_MASK (OCTEON_58XX_FAMILY_REV_MASK \
+ | OCTEON_58XX_MODEL_MASK)
+#define OCTEON_58XX_MODEL_MINOR_REV_MASK (OCTEON_58XX_MODEL_REV_MASK \
+ & 0x00fffff8)
+#define OCTEON_5XXX_MODEL_MASK 0x00ff0fc0
+
+#define __OCTEON_MATCH_MASK__(x, y, z) (((x) & (z)) == ((y) & (z)))
+
+/* NOTE: This is for internal (to this file) use only. */
+static inline int __OCTEON_IS_MODEL_COMPILE__(uint32_t arg_model,
+ uint32_t chip_model)
+{
+ uint32_t rev_and_sub = OM_IGNORE_REVISION | OM_CHECK_SUBMODEL;
+
+ if ((arg_model & OCTEON_38XX_FAMILY_MASK) < OCTEON_CN58XX_PASS1_0) {
+ if (((arg_model & OM_FLAG_MASK) == rev_and_sub) &&
+ __OCTEON_MATCH_MASK__(chip_model, arg_model,
+ OCTEON_38XX_MODEL_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == 0) &&
+ __OCTEON_MATCH_MASK__(chip_model, arg_model,
+ OCTEON_38XX_FAMILY_REV_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_REVISION) &&
+ __OCTEON_MATCH_MASK__(chip_model, arg_model,
+ OCTEON_38XX_FAMILY_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_CHECK_SUBMODEL) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_38XX_MODEL_REV_MASK))
+ return 1;
+ if ((arg_model & OM_MATCH_PREVIOUS_MODELS) &&
+ ((chip_model & OCTEON_38XX_MODEL_MASK) <
+ (arg_model & OCTEON_38XX_MODEL_MASK)))
+ return 1;
+ } else {
+ if (((arg_model & OM_FLAG_MASK) == rev_and_sub) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_MODEL_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == 0) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_FAMILY_REV_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_MINOR_REVISION) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_MODEL_MINOR_REV_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_REVISION) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_FAMILY_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_CHECK_SUBMODEL) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_MODEL_REV_MASK))
+ return 1;
+
+ if (((arg_model & OM_MATCH_5XXX_FAMILY_MODELS) == OM_MATCH_5XXX_FAMILY_MODELS) &&
+ ((chip_model) >= OCTEON_CN58XX_PASS1_0) && ((chip_model) < OCTEON_CN63XX_PASS1_0))
+ return 1;
+
+ if (((arg_model & OM_MATCH_6XXX_FAMILY_MODELS) == OM_MATCH_6XXX_FAMILY_MODELS) &&
+ ((chip_model) >= OCTEON_CN63XX_PASS1_0))
+ return 1;
+
+ if ((arg_model & OM_MATCH_PREVIOUS_MODELS) &&
+ ((chip_model & OCTEON_58XX_MODEL_MASK) <
+ (arg_model & OCTEON_58XX_MODEL_MASK)))
+ return 1;
+ }
+ return 0;
+}
+
+/* forward declarations */
+static inline uint32_t cvmx_get_proc_id(void) __attribute__ ((pure));
+static inline uint64_t cvmx_read_csr(uint64_t csr_addr);
+
+/* NOTE: This for internal use only!!!!! */
+static inline int __octeon_is_model_runtime__(uint32_t model)
+{
+ uint32_t cpuid = cvmx_get_proc_id();
+
+ /*
+ * Check for special case of mismarked 3005 samples. We only
+ * need to check if the sub model isn't being ignored.
+ */
+ if ((model & OM_CHECK_SUBMODEL) == OM_CHECK_SUBMODEL) {
+ if (cpuid == OCTEON_CN3010_PASS1 \
+ && (cvmx_read_csr(0x80011800800007B8ull) & (1ull << 34)))
+ cpuid |= 0x10;
+ }
+ return __OCTEON_IS_MODEL_COMPILE__(model, cpuid);
+}
+
+/*
+ * The OCTEON_IS_MODEL macro should be used for all Octeon model
+ * checking done in a program. This should be kept runtime if at all
+ * possible. Any compile time (#if OCTEON_IS_MODEL) usage must be
+ * condtionalized with OCTEON_IS_COMMON_BINARY() if runtime checking
+ * support is required.
+ */
+#define OCTEON_IS_MODEL(x) __octeon_is_model_runtime__(x)
+#define OCTEON_IS_COMMON_BINARY() 1
+#undef OCTEON_MODEL
+
+const char *octeon_model_get_string(uint32_t chip_id);
+const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer);
+
+#include "octeon-feature.h"
+
+#endif /* __OCTEON_MODEL_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
new file mode 100644
index 00000000..f72f768c
--- /dev/null
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -0,0 +1,262 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004-2008 Cavium Networks
+ */
+#ifndef __ASM_OCTEON_OCTEON_H
+#define __ASM_OCTEON_OCTEON_H
+
+#include "cvmx.h"
+
+extern uint64_t octeon_bootmem_alloc_range_phys(uint64_t size,
+ uint64_t alignment,
+ uint64_t min_addr,
+ uint64_t max_addr,
+ int do_locking);
+extern void *octeon_bootmem_alloc(uint64_t size, uint64_t alignment,
+ int do_locking);
+extern void *octeon_bootmem_alloc_range(uint64_t size, uint64_t alignment,
+ uint64_t min_addr, uint64_t max_addr,
+ int do_locking);
+extern void *octeon_bootmem_alloc_named(uint64_t size, uint64_t alignment,
+ char *name);
+extern void *octeon_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
+ uint64_t max_addr, uint64_t align,
+ char *name);
+extern void *octeon_bootmem_alloc_named_address(uint64_t size, uint64_t address,
+ char *name);
+extern int octeon_bootmem_free_named(char *name);
+extern void octeon_bootmem_lock(void);
+extern void octeon_bootmem_unlock(void);
+
+extern int octeon_is_simulation(void);
+extern int octeon_is_pci_host(void);
+extern int octeon_usb_is_ref_clk(void);
+extern uint64_t octeon_get_clock_rate(void);
+extern u64 octeon_get_io_clock_rate(void);
+extern const char *octeon_board_type_string(void);
+extern const char *octeon_get_pci_interrupts(void);
+extern int octeon_get_southbridge_interrupt(void);
+extern int octeon_get_boot_coremask(void);
+extern int octeon_get_boot_num_arguments(void);
+extern const char *octeon_get_boot_argument(int arg);
+extern void octeon_hal_setup_reserved32(void);
+extern void octeon_user_io_init(void);
+struct octeon_cop2_state;
+extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *state);
+extern void octeon_crypto_disable(struct octeon_cop2_state *state,
+ unsigned long flags);
+extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task);
+
+extern void octeon_init_cvmcount(void);
+extern void octeon_setup_delays(void);
+
+#define OCTEON_ARGV_MAX_ARGS 64
+#define OCTOEN_SERIAL_LEN 20
+
+struct octeon_boot_descriptor {
+ /* Start of block referenced by assembly code - do not change! */
+ uint32_t desc_version;
+ uint32_t desc_size;
+ uint64_t stack_top;
+ uint64_t heap_base;
+ uint64_t heap_end;
+ /* Only used by bootloader */
+ uint64_t entry_point;
+ uint64_t desc_vaddr;
+ /* End of This block referenced by assembly code - do not change! */
+ uint32_t exception_base_addr;
+ uint32_t stack_size;
+ uint32_t heap_size;
+ /* Argc count for application. */
+ uint32_t argc;
+ uint32_t argv[OCTEON_ARGV_MAX_ARGS];
+
+#define BOOT_FLAG_INIT_CORE (1 << 0)
+#define OCTEON_BL_FLAG_DEBUG (1 << 1)
+#define OCTEON_BL_FLAG_NO_MAGIC (1 << 2)
+ /* If set, use uart1 for console */
+#define OCTEON_BL_FLAG_CONSOLE_UART1 (1 << 3)
+ /* If set, use PCI console */
+#define OCTEON_BL_FLAG_CONSOLE_PCI (1 << 4)
+ /* Call exit on break on serial port */
+#define OCTEON_BL_FLAG_BREAK (1 << 5)
+
+ uint32_t flags;
+ uint32_t core_mask;
+ /* DRAM size in megabyes. */
+ uint32_t dram_size;
+ /* physical address of free memory descriptor block. */
+ uint32_t phy_mem_desc_addr;
+ /* used to pass flags from app to debugger. */
+ uint32_t debugger_flags_base_addr;
+ /* CPU clock speed, in hz. */
+ uint32_t eclock_hz;
+ /* DRAM clock speed, in hz. */
+ uint32_t dclock_hz;
+ /* SPI4 clock in hz. */
+ uint32_t spi_clock_hz;
+ uint16_t board_type;
+ uint8_t board_rev_major;
+ uint8_t board_rev_minor;
+ uint16_t chip_type;
+ uint8_t chip_rev_major;
+ uint8_t chip_rev_minor;
+ char board_serial_number[OCTOEN_SERIAL_LEN];
+ uint8_t mac_addr_base[6];
+ uint8_t mac_addr_count;
+ uint64_t cvmx_desc_vaddr;
+};
+
+union octeon_cvmemctl {
+ uint64_t u64;
+ struct {
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t tlbbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t l1cbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t l1dbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t dcmbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t ptgbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t wbfbist:1;
+ /* Reserved */
+ uint64_t reserved:22;
+ /* R/W If set, marked write-buffer entries time out
+ * the same as as other entries; if clear, marked
+ * write-buffer entries use the maximum timeout. */
+ uint64_t dismarkwblongto:1;
+ /* R/W If set, a merged store does not clear the
+ * write-buffer entry timeout state. */
+ uint64_t dismrgclrwbto:1;
+ /* R/W Two bits that are the MSBs of the resultant
+ * CVMSEG LM word location for an IOBDMA. The other 8
+ * bits come from the SCRADDR field of the IOBDMA. */
+ uint64_t iobdmascrmsb:2;
+ /* R/W If set, SYNCWS and SYNCS only order marked
+ * stores; if clear, SYNCWS and SYNCS only order
+ * unmarked stores. SYNCWSMARKED has no effect when
+ * DISSYNCWS is set. */
+ uint64_t syncwsmarked:1;
+ /* R/W If set, SYNCWS acts as SYNCW and SYNCS acts as
+ * SYNC. */
+ uint64_t dissyncws:1;
+ /* R/W If set, no stall happens on write buffer
+ * full. */
+ uint64_t diswbfst:1;
+ /* R/W If set (and SX set), supervisor-level
+ * loads/stores can use XKPHYS addresses with
+ * VA<48>==0 */
+ uint64_t xkmemenas:1;
+ /* R/W If set (and UX set), user-level loads/stores
+ * can use XKPHYS addresses with VA<48>==0 */
+ uint64_t xkmemenau:1;
+ /* R/W If set (and SX set), supervisor-level
+ * loads/stores can use XKPHYS addresses with
+ * VA<48>==1 */
+ uint64_t xkioenas:1;
+ /* R/W If set (and UX set), user-level loads/stores
+ * can use XKPHYS addresses with VA<48>==1 */
+ uint64_t xkioenau:1;
+ /* R/W If set, all stores act as SYNCW (NOMERGE must
+ * be set when this is set) RW, reset to 0. */
+ uint64_t allsyncw:1;
+ /* R/W If set, no stores merge, and all stores reach
+ * the coherent bus in order. */
+ uint64_t nomerge:1;
+ /* R/W Selects the bit in the counter used for DID
+ * time-outs 0 = 231, 1 = 230, 2 = 229, 3 =
+ * 214. Actual time-out is between 1x and 2x this
+ * interval. For example, with DIDTTO=3, expiration
+ * interval is between 16K and 32K. */
+ uint64_t didtto:2;
+ /* R/W If set, the (mem) CSR clock never turns off. */
+ uint64_t csrckalwys:1;
+ /* R/W If set, mclk never turns off. */
+ uint64_t mclkalwys:1;
+ /* R/W Selects the bit in the counter used for write
+ * buffer flush time-outs (WBFLT+11) is the bit
+ * position in an internal counter used to determine
+ * expiration. The write buffer expires between 1x and
+ * 2x this interval. For example, with WBFLT = 0, a
+ * write buffer expires between 2K and 4K cycles after
+ * the write buffer entry is allocated. */
+ uint64_t wbfltime:3;
+ /* R/W If set, do not put Istream in the L2 cache. */
+ uint64_t istrnol2:1;
+ /* R/W The write buffer threshold. */
+ uint64_t wbthresh:4;
+ /* Reserved */
+ uint64_t reserved2:2;
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * kernel/debug mode. */
+ uint64_t cvmsegenak:1;
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * supervisor mode. */
+ uint64_t cvmsegenas:1;
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * user mode. */
+ uint64_t cvmsegenau:1;
+ /* R/W Size of local memory in cache blocks, 54 (6912
+ * bytes) is max legal value. */
+ uint64_t lmemsz:6;
+ } s;
+};
+
+struct octeon_cf_data {
+ unsigned long base_region_bias;
+ unsigned int base_region; /* The chip select region used by CF */
+ int is16bit; /* 0 - 8bit, !0 - 16bit */
+ int dma_engine; /* -1 for no DMA */
+};
+
+struct octeon_i2c_data {
+ unsigned int sys_freq;
+ unsigned int i2c_freq;
+};
+
+extern void octeon_write_lcd(const char *s);
+extern void octeon_check_cpu_bist(void);
+extern int octeon_get_boot_debug_flag(void);
+extern int octeon_get_boot_uart(void);
+
+struct uart_port;
+extern unsigned int octeon_serial_in(struct uart_port *, int);
+extern void octeon_serial_out(struct uart_port *, int, int);
+
+/**
+ * Write a 32bit value to the Octeon NPI register space
+ *
+ * @address: Address to write to
+ * @val: Value to write
+ */
+static inline void octeon_npi_write32(uint64_t address, uint32_t val)
+{
+ cvmx_write64_uint32(address ^ 4, val);
+ cvmx_read64_uint32(address ^ 4);
+}
+
+
+/**
+ * Read a 32bit value from the Octeon NPI register space
+ *
+ * @address: Address to read
+ * Returns The result
+ */
+static inline uint32_t octeon_npi_read32(uint64_t address)
+{
+ return cvmx_read64_uint32(address ^ 4);
+}
+
+extern struct cvmx_bootinfo *octeon_bootinfo;
+
+extern uint64_t octeon_bootloader_entry_addr;
+
+extern void (*octeon_irq_setup_secondary)(void);
+
+#endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/octeon/pci-octeon.h b/arch/mips/include/asm/octeon/pci-octeon.h
new file mode 100644
index 00000000..fba2ba20
--- /dev/null
+++ b/arch/mips/include/asm/octeon/pci-octeon.h
@@ -0,0 +1,68 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2009 Cavium Networks
+ */
+
+#ifndef __PCI_OCTEON_H__
+#define __PCI_OCTEON_H__
+
+#include <linux/pci.h>
+
+/* Some PCI cards require delays when accessing config space. */
+#define PCI_CONFIG_SPACE_DELAY 10000
+
+/*
+ * The physical memory base mapped by BAR1. 256MB at the end of the
+ * first 4GB.
+ */
+#define CVMX_PCIE_BAR1_PHYS_BASE ((1ull << 32) - (1ull << 28))
+#define CVMX_PCIE_BAR1_PHYS_SIZE (1ull << 28)
+
+/*
+ * The RC base of BAR1. gen1 has a 39-bit BAR2, gen2 has 41-bit BAR2,
+ * place BAR1 so it is the same for both.
+ */
+#define CVMX_PCIE_BAR1_RC_BASE (1ull << 41)
+
+/*
+ * pcibios_map_irq() is defined inside pci-octeon.c. All it does is
+ * call the Octeon specific version pointed to by this variable. This
+ * function needs to change for PCI or PCIe based hosts.
+ */
+extern int (*octeon_pcibios_map_irq)(const struct pci_dev *dev,
+ u8 slot, u8 pin);
+
+/*
+ * For PCI (not PCIe) the BAR2 base address.
+ */
+#define OCTEON_BAR2_PCI_ADDRESS 0x8000000000ull
+
+/*
+ * For PCI (not PCIe) the base of the memory mapped by BAR1
+ */
+extern u64 octeon_bar1_pci_phys;
+
+/*
+ * The following defines are used when octeon_dma_bar_type =
+ * OCTEON_DMA_BAR_TYPE_BIG
+ */
+#define OCTEON_PCI_BAR1_HOLE_BITS 5
+#define OCTEON_PCI_BAR1_HOLE_SIZE (1ul<<(OCTEON_PCI_BAR1_HOLE_BITS+3))
+
+enum octeon_dma_bar_type {
+ OCTEON_DMA_BAR_TYPE_INVALID,
+ OCTEON_DMA_BAR_TYPE_SMALL,
+ OCTEON_DMA_BAR_TYPE_BIG,
+ OCTEON_DMA_BAR_TYPE_PCIE
+};
+
+/*
+ * This tells the DMA mapping system in dma-octeon.c how to map PCI
+ * DMA addresses.
+ */
+extern enum octeon_dma_bar_type octeon_dma_bar_type;
+
+#endif
diff --git a/arch/mips/include/asm/paccess.h b/arch/mips/include/asm/paccess.h
new file mode 100644
index 00000000..9ce5a1e7
--- /dev/null
+++ b/arch/mips/include/asm/paccess.h
@@ -0,0 +1,112 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Protected memory access. Used for everything that might take revenge
+ * by sending a DBE error like accessing possibly non-existent memory or
+ * devices.
+ */
+#ifndef _ASM_PACCESS_H
+#define _ASM_PACCESS_H
+
+#include <linux/errno.h>
+
+#ifdef CONFIG_32BIT
+#define __PA_ADDR ".word"
+#endif
+#ifdef CONFIG_64BIT
+#define __PA_ADDR ".dword"
+#endif
+
+extern asmlinkage void handle_ibe(void);
+extern asmlinkage void handle_dbe(void);
+
+#define put_dbe(x, ptr) __put_dbe((x), (ptr), sizeof(*(ptr)))
+#define get_dbe(x, ptr) __get_dbe((x), (ptr), sizeof(*(ptr)))
+
+struct __large_pstruct { unsigned long buf[100]; };
+#define __mp(x) (*(struct __large_pstruct *)(x))
+
+#define __get_dbe(x, ptr, size) \
+({ \
+ long __gu_err; \
+ __typeof__(*(ptr)) __gu_val; \
+ unsigned long __gu_addr; \
+ __asm__("":"=r" (__gu_val)); \
+ __gu_addr = (unsigned long) (ptr); \
+ __asm__("":"=r" (__gu_err)); \
+ switch (size) { \
+ case 1: __get_dbe_asm("lb"); break; \
+ case 2: __get_dbe_asm("lh"); break; \
+ case 4: __get_dbe_asm("lw"); break; \
+ case 8: __get_dbe_asm("ld"); break; \
+ default: __get_dbe_unknown(); break; \
+ } \
+ x = (__typeof__(*(ptr))) __gu_val; \
+ __gu_err; \
+})
+
+#define __get_dbe_asm(insn) \
+{ \
+ __asm__ __volatile__( \
+ "1:\t" insn "\t%1,%2\n\t" \
+ "move\t%0,$0\n" \
+ "2:\n\t" \
+ ".section\t.fixup,\"ax\"\n" \
+ "3:\tli\t%0,%3\n\t" \
+ "move\t%1,$0\n\t" \
+ "j\t2b\n\t" \
+ ".previous\n\t" \
+ ".section\t__dbe_table,\"a\"\n\t" \
+ __PA_ADDR "\t1b, 3b\n\t" \
+ ".previous" \
+ :"=r" (__gu_err), "=r" (__gu_val) \
+ :"o" (__mp(__gu_addr)), "i" (-EFAULT)); \
+}
+
+extern void __get_dbe_unknown(void);
+
+#define __put_dbe(x, ptr, size) \
+({ \
+ long __pu_err; \
+ __typeof__(*(ptr)) __pu_val; \
+ long __pu_addr; \
+ __pu_val = (x); \
+ __pu_addr = (long) (ptr); \
+ __asm__("":"=r" (__pu_err)); \
+ switch (size) { \
+ case 1: __put_dbe_asm("sb"); break; \
+ case 2: __put_dbe_asm("sh"); break; \
+ case 4: __put_dbe_asm("sw"); break; \
+ case 8: __put_dbe_asm("sd"); break; \
+ default: __put_dbe_unknown(); break; \
+ } \
+ __pu_err; \
+})
+
+#define __put_dbe_asm(insn) \
+{ \
+ __asm__ __volatile__( \
+ "1:\t" insn "\t%1,%2\n\t" \
+ "move\t%0,$0\n" \
+ "2:\n\t" \
+ ".section\t.fixup,\"ax\"\n" \
+ "3:\tli\t%0,%3\n\t" \
+ "j\t2b\n\t" \
+ ".previous\n\t" \
+ ".section\t__dbe_table,\"a\"\n\t" \
+ __PA_ADDR "\t1b, 3b\n\t" \
+ ".previous" \
+ : "=r" (__pu_err) \
+ : "r" (__pu_val), "o" (__mp(__pu_addr)), "i" (-EFAULT)); \
+}
+
+extern void __put_dbe_unknown(void);
+
+extern unsigned long search_dbe_table(unsigned long addr);
+
+#endif /* _ASM_PACCESS_H */
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
new file mode 100644
index 00000000..e59cd1ac
--- /dev/null
+++ b/arch/mips/include/asm/page.h
@@ -0,0 +1,213 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PAGE_H
+#define _ASM_PAGE_H
+
+#include <spaces.h>
+#include <linux/const.h>
+
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#ifdef CONFIG_PAGE_SIZE_4KB
+#define PAGE_SHIFT 12
+#endif
+#ifdef CONFIG_PAGE_SIZE_8KB
+#define PAGE_SHIFT 13
+#endif
+#ifdef CONFIG_PAGE_SIZE_16KB
+#define PAGE_SHIFT 14
+#endif
+#ifdef CONFIG_PAGE_SIZE_32KB
+#define PAGE_SHIFT 15
+#endif
+#ifdef CONFIG_PAGE_SIZE_64KB
+#define PAGE_SHIFT 16
+#endif
+#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
+#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
+
+#ifdef CONFIG_HUGETLB_PAGE
+#define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3)
+#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
+#define HPAGE_MASK (~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+#endif /* CONFIG_HUGETLB_PAGE */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/pfn.h>
+#include <asm/io.h>
+
+extern void build_clear_page(void);
+extern void build_copy_page(void);
+
+/*
+ * It's normally defined only for FLATMEM config but it's
+ * used in our early mem init code for all memory models.
+ * So always define it.
+ */
+#define ARCH_PFN_OFFSET PFN_UP(PHYS_OFFSET)
+
+extern void clear_page(void * page);
+extern void copy_page(void * to, void * from);
+
+extern unsigned long shm_align_mask;
+
+static inline unsigned long pages_do_alias(unsigned long addr1,
+ unsigned long addr2)
+{
+ return (addr1 ^ addr2) & shm_align_mask;
+}
+
+struct page;
+
+static inline void clear_user_page(void *addr, unsigned long vaddr,
+ struct page *page)
+{
+ extern void (*flush_data_cache_page)(unsigned long addr);
+
+ clear_page(addr);
+ if (pages_do_alias((unsigned long) addr, vaddr & PAGE_MASK))
+ flush_data_cache_page((unsigned long)addr);
+}
+
+extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
+ struct page *to);
+struct vm_area_struct;
+extern void copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma);
+
+#define __HAVE_ARCH_COPY_USER_HIGHPAGE
+
+/*
+ * These are used to make use of C type-checking..
+ */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+ #ifdef CONFIG_CPU_MIPS32
+ typedef struct { unsigned long pte_low, pte_high; } pte_t;
+ #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+ #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
+ #else
+ typedef struct { unsigned long long pte; } pte_t;
+ #define pte_val(x) ((x).pte)
+ #define __pte(x) ((pte_t) { (x) } )
+ #endif
+#else
+typedef struct { unsigned long pte; } pte_t;
+#define pte_val(x) ((x).pte)
+#define __pte(x) ((pte_t) { (x) } )
+#endif
+typedef struct page *pgtable_t;
+
+/*
+ * Right now we don't support 4-level pagetables, so all pud-related
+ * definitions come from <asm-generic/pgtable-nopud.h>.
+ */
+
+/*
+ * Finall the top of the hierarchy, the pgd
+ */
+typedef struct { unsigned long pgd; } pgd_t;
+#define pgd_val(x) ((x).pgd)
+#define __pgd(x) ((pgd_t) { (x) } )
+
+/*
+ * Manipulate page protection bits
+ */
+typedef struct { unsigned long pgprot; } pgprot_t;
+#define pgprot_val(x) ((x).pgprot)
+#define __pgprot(x) ((pgprot_t) { (x) } )
+
+/*
+ * On R4000-style MMUs where a TLB entry is mapping a adjacent even / odd
+ * pair of pages we only have a single global bit per pair of pages. When
+ * writing to the TLB make sure we always have the bit set for both pages
+ * or none. This macro is used to access the `buddy' of the pte we're just
+ * working on.
+ */
+#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * __pa()/__va() should be used only during mem init.
+ */
+#ifdef CONFIG_64BIT
+#define __pa(x) \
+({ \
+ unsigned long __x = (unsigned long)(x); \
+ __x < CKSEG0 ? XPHYSADDR(__x) : CPHYSADDR(__x); \
+})
+#else
+#define __pa(x) \
+ ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)
+#endif
+#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
+
+/*
+ * RELOC_HIDE was originally added by 6007b903dfe5f1d13e0c711ac2894bdd4a61b1ad
+ * (lmo) rsp. 8431fd094d625b94d364fe393076ccef88e6ce18 (kernel.org). The
+ * discussion can be found in lkml posting
+ * <a2ebde260608230500o3407b108hc03debb9da6e62c@mail.gmail.com> which is
+ * archived at http://lists.linuxcoding.com/kernel/2006-q3/msg17360.html
+ *
+ * It is unclear if the misscompilations mentioned in
+ * http://lkml.org/lkml/2010/8/8/138 also affect MIPS so we keep this one
+ * until GCC 3.x has been retired before we can apply
+ * https://patchwork.linux-mips.org/patch/1541/
+ */
+
+#define __pa_symbol(x) __pa(RELOC_HIDE((unsigned long)(x), 0))
+
+#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
+
+#ifdef CONFIG_FLATMEM
+
+#define pfn_valid(pfn) \
+({ \
+ unsigned long __pfn = (pfn); \
+ /* avoid <linux/bootmem.h> include hell */ \
+ extern unsigned long min_low_pfn; \
+ \
+ __pfn >= min_low_pfn && __pfn < max_mapnr; \
+})
+
+#elif defined(CONFIG_SPARSEMEM)
+
+/* pfn_valid is defined in linux/mmzone.h */
+
+#elif defined(CONFIG_NEED_MULTIPLE_NODES)
+
+#define pfn_valid(pfn) \
+({ \
+ unsigned long __pfn = (pfn); \
+ int __n = pfn_to_nid(__pfn); \
+ ((__n >= 0) ? (__pfn < NODE_DATA(__n)->node_start_pfn + \
+ NODE_DATA(__n)->node_spanned_pages) \
+ : 0); \
+})
+
+#endif
+
+#define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))
+#define virt_addr_valid(kaddr) pfn_valid(PFN_DOWN(virt_to_phys(kaddr)))
+
+#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \
+ PHYS_OFFSET)
+#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \
+ PHYS_OFFSET)
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
+#endif /* _ASM_PAGE_H */
diff --git a/arch/mips/include/asm/param.h b/arch/mips/include/asm/param.h
new file mode 100644
index 00000000..da3920fc
--- /dev/null
+++ b/arch/mips/include/asm/param.h
@@ -0,0 +1,16 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 1994 - 2000, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PARAM_H
+#define _ASM_PARAM_H
+
+#define EXEC_PAGESIZE 65536
+
+#include <asm-generic/param.h>
+
+#endif /* _ASM_PARAM_H */
diff --git a/arch/mips/include/asm/parport.h b/arch/mips/include/asm/parport.h
new file mode 100644
index 00000000..cf252af6
--- /dev/null
+++ b/arch/mips/include/asm/parport.h
@@ -0,0 +1 @@
+#include <asm-generic/parport.h>
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
new file mode 100644
index 00000000..576397c6
--- /dev/null
+++ b/arch/mips/include/asm/pci.h
@@ -0,0 +1,152 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_PCI_H
+#define _ASM_PCI_H
+
+#include <linux/mm.h>
+
+#ifdef __KERNEL__
+
+/*
+ * This file essentially defines the interface between board
+ * specific PCI code and MIPS common PCI code. Should potentially put
+ * into include/asm/pci.h file.
+ */
+
+#include <linux/ioport.h>
+
+/*
+ * Each pci channel is a top-level PCI bus seem by CPU. A machine with
+ * multiple PCI channels may have multiple PCI host controllers or a
+ * single controller supporting multiple channels.
+ */
+struct pci_controller {
+ struct pci_controller *next;
+ struct pci_bus *bus;
+
+ struct pci_ops *pci_ops;
+ struct resource *mem_resource;
+ unsigned long mem_offset;
+ struct resource *io_resource;
+ unsigned long io_offset;
+ unsigned long io_map_base;
+
+ unsigned int index;
+ /* For compatibility with current (as of July 2003) pciutils
+ and XFree86. Eventually will be removed. */
+ unsigned int need_domain_info;
+
+ int iommu;
+
+ /* Optional access methods for reading/writing the bus number
+ of the PCI controller */
+ int (*get_busno)(void);
+ void (*set_busno)(int busno);
+};
+
+/*
+ * Used by boards to register their PCI busses before the actual scanning.
+ */
+extern struct pci_controller * alloc_pci_controller(void);
+extern void register_pci_controller(struct pci_controller *hose);
+
+/*
+ * board supplied pci irq fixup routine
+ */
+extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+ already-configured bus numbers - to be used for buggy BIOSes
+ or architectures with incomplete PCI setup by the loader */
+
+extern unsigned int pcibios_assign_all_busses(void);
+
+extern unsigned long PCIBIOS_MIN_IO;
+extern unsigned long PCIBIOS_MIN_MEM;
+
+#define PCIBIOS_MIN_CARDBUS_IO 0x4000
+
+extern void pcibios_set_master(struct pci_dev *dev);
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+ /* We don't do dynamic PCI IRQ allocation */
+}
+
+#define HAVE_PCI_MMAP
+
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine);
+
+/*
+ * Dynamic DMA mapping stuff.
+ * MIPS has everything mapped statically.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/*
+ * The PCI address space does equal the physical memory address space. The
+ * networking and block device layers use this boolean for bounce buffer
+ * decisions. This is set if any hose does not have an IOMMU.
+ */
+extern unsigned int PCI_DMA_BUS_IS_PHYS;
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+ enum pci_dma_burst_strategy *strat,
+ unsigned long *strategy_parameter)
+{
+ *strat = PCI_DMA_BURST_INFINITY;
+ *strategy_parameter = ~0UL;
+}
+#endif
+
+extern void pcibios_resource_to_bus(struct pci_dev *dev,
+ struct pci_bus_region *region, struct resource *res);
+
+extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region);
+
+#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ struct pci_controller *hose = bus->sysdata;
+ return hose->need_domain_info;
+}
+
+#endif /* __KERNEL__ */
+
+/* implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>
+
+/* Do platform specific device initialization at pci_enable_device() time */
+extern int pcibios_plat_dev_init(struct pci_dev *dev);
+
+/* Chances are this interrupt is wired PC-style ... */
+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+ return channel ? 15 : 14;
+}
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+/* MSI arch hook for OCTEON */
+#define arch_setup_msi_irqs arch_setup_msi_irqs
+#endif
+
+extern int pci_probe_only;
+
+extern char * (*pcibios_plat_setup)(char *str);
+
+#endif /* _ASM_PCI_H */
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h
new file mode 100644
index 00000000..be44fb02
--- /dev/null
+++ b/arch/mips/include/asm/pci/bridge.h
@@ -0,0 +1,854 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * bridge.h - bridge chip header file, derived from IRIX <sys/PCI/bridge.h>,
+ * revision 1.76.
+ *
+ * Copyright (C) 1996, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_PCI_BRIDGE_H
+#define _ASM_PCI_BRIDGE_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/xtalk/xwidget.h> /* generic widget header */
+#include <asm/sn/types.h>
+
+/* I/O page size */
+
+#define IOPFNSHIFT 12 /* 4K per mapped page */
+
+#define IOPGSIZE (1 << IOPFNSHIFT)
+#define IOPG(x) ((x) >> IOPFNSHIFT)
+#define IOPGOFF(x) ((x) & (IOPGSIZE-1))
+
+/* Bridge RAM sizes */
+
+#define BRIDGE_ATE_RAM_SIZE 0x00000400 /* 1kB ATE RAM */
+
+#define BRIDGE_CONFIG_BASE 0x20000
+#define BRIDGE_CONFIG1_BASE 0x28000
+#define BRIDGE_CONFIG_END 0x30000
+#define BRIDGE_CONFIG_SLOT_SIZE 0x1000
+
+#define BRIDGE_SSRAM_512K 0x00080000 /* 512kB */
+#define BRIDGE_SSRAM_128K 0x00020000 /* 128kB */
+#define BRIDGE_SSRAM_64K 0x00010000 /* 64kB */
+#define BRIDGE_SSRAM_0K 0x00000000 /* 0kB */
+
+/* ========================================================================
+ * Bridge address map
+ */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * All accesses to bridge hardware registers must be done
+ * using 32-bit loads and stores.
+ */
+typedef u32 bridgereg_t;
+
+typedef u64 bridge_ate_t;
+
+/* pointers to bridge ATEs
+ * are always "pointer to volatile"
+ */
+typedef volatile bridge_ate_t *bridge_ate_p;
+
+/*
+ * It is generally preferred that hardware registers on the bridge
+ * are located from C code via this structure.
+ *
+ * Generated from Bridge spec dated 04oct95
+ */
+
+typedef volatile struct bridge_s {
+ /* Local Registers 0x000000-0x00FFFF */
+
+ /* standard widget configuration 0x000000-0x000057 */
+ widget_cfg_t b_widget; /* 0x000000 */
+
+ /* helper fieldnames for accessing bridge widget */
+
+#define b_wid_id b_widget.w_id
+#define b_wid_stat b_widget.w_status
+#define b_wid_err_upper b_widget.w_err_upper_addr
+#define b_wid_err_lower b_widget.w_err_lower_addr
+#define b_wid_control b_widget.w_control
+#define b_wid_req_timeout b_widget.w_req_timeout
+#define b_wid_int_upper b_widget.w_intdest_upper_addr
+#define b_wid_int_lower b_widget.w_intdest_lower_addr
+#define b_wid_err_cmdword b_widget.w_err_cmd_word
+#define b_wid_llp b_widget.w_llp_cfg
+#define b_wid_tflush b_widget.w_tflush
+
+ /* bridge-specific widget configuration 0x000058-0x00007F */
+ bridgereg_t _pad_000058;
+ bridgereg_t b_wid_aux_err; /* 0x00005C */
+ bridgereg_t _pad_000060;
+ bridgereg_t b_wid_resp_upper; /* 0x000064 */
+ bridgereg_t _pad_000068;
+ bridgereg_t b_wid_resp_lower; /* 0x00006C */
+ bridgereg_t _pad_000070;
+ bridgereg_t b_wid_tst_pin_ctrl; /* 0x000074 */
+ bridgereg_t _pad_000078[2];
+
+ /* PMU & Map 0x000080-0x00008F */
+ bridgereg_t _pad_000080;
+ bridgereg_t b_dir_map; /* 0x000084 */
+ bridgereg_t _pad_000088[2];
+
+ /* SSRAM 0x000090-0x00009F */
+ bridgereg_t _pad_000090;
+ bridgereg_t b_ram_perr; /* 0x000094 */
+ bridgereg_t _pad_000098[2];
+
+ /* Arbitration 0x0000A0-0x0000AF */
+ bridgereg_t _pad_0000A0;
+ bridgereg_t b_arb; /* 0x0000A4 */
+ bridgereg_t _pad_0000A8[2];
+
+ /* Number In A Can 0x0000B0-0x0000BF */
+ bridgereg_t _pad_0000B0;
+ bridgereg_t b_nic; /* 0x0000B4 */
+ bridgereg_t _pad_0000B8[2];
+
+ /* PCI/GIO 0x0000C0-0x0000FF */
+ bridgereg_t _pad_0000C0;
+ bridgereg_t b_bus_timeout; /* 0x0000C4 */
+#define b_pci_bus_timeout b_bus_timeout
+
+ bridgereg_t _pad_0000C8;
+ bridgereg_t b_pci_cfg; /* 0x0000CC */
+ bridgereg_t _pad_0000D0;
+ bridgereg_t b_pci_err_upper; /* 0x0000D4 */
+ bridgereg_t _pad_0000D8;
+ bridgereg_t b_pci_err_lower; /* 0x0000DC */
+ bridgereg_t _pad_0000E0[8];
+#define b_gio_err_lower b_pci_err_lower
+#define b_gio_err_upper b_pci_err_upper
+
+ /* Interrupt 0x000100-0x0001FF */
+ bridgereg_t _pad_000100;
+ bridgereg_t b_int_status; /* 0x000104 */
+ bridgereg_t _pad_000108;
+ bridgereg_t b_int_enable; /* 0x00010C */
+ bridgereg_t _pad_000110;
+ bridgereg_t b_int_rst_stat; /* 0x000114 */
+ bridgereg_t _pad_000118;
+ bridgereg_t b_int_mode; /* 0x00011C */
+ bridgereg_t _pad_000120;
+ bridgereg_t b_int_device; /* 0x000124 */
+ bridgereg_t _pad_000128;
+ bridgereg_t b_int_host_err; /* 0x00012C */
+
+ struct {
+ bridgereg_t __pad; /* 0x0001{30,,,68} */
+ bridgereg_t addr; /* 0x0001{34,,,6C} */
+ } b_int_addr[8]; /* 0x000130 */
+
+ bridgereg_t _pad_000170[36];
+
+ /* Device 0x000200-0x0003FF */
+ struct {
+ bridgereg_t __pad; /* 0x0002{00,,,38} */
+ bridgereg_t reg; /* 0x0002{04,,,3C} */
+ } b_device[8]; /* 0x000200 */
+
+ struct {
+ bridgereg_t __pad; /* 0x0002{40,,,78} */
+ bridgereg_t reg; /* 0x0002{44,,,7C} */
+ } b_wr_req_buf[8]; /* 0x000240 */
+
+ struct {
+ bridgereg_t __pad; /* 0x0002{80,,,88} */
+ bridgereg_t reg; /* 0x0002{84,,,8C} */
+ } b_rrb_map[2]; /* 0x000280 */
+#define b_even_resp b_rrb_map[0].reg /* 0x000284 */
+#define b_odd_resp b_rrb_map[1].reg /* 0x00028C */
+
+ bridgereg_t _pad_000290;
+ bridgereg_t b_resp_status; /* 0x000294 */
+ bridgereg_t _pad_000298;
+ bridgereg_t b_resp_clear; /* 0x00029C */
+
+ bridgereg_t _pad_0002A0[24];
+
+ char _pad_000300[0x10000 - 0x000300];
+
+ /* Internal Address Translation Entry RAM 0x010000-0x0103FF */
+ union {
+ bridge_ate_t wr; /* write-only */
+ struct {
+ bridgereg_t _p_pad;
+ bridgereg_t rd; /* read-only */
+ } hi;
+ } b_int_ate_ram[128];
+
+ char _pad_010400[0x11000 - 0x010400];
+
+ /* Internal Address Translation Entry RAM LOW 0x011000-0x0113FF */
+ struct {
+ bridgereg_t _p_pad;
+ bridgereg_t rd; /* read-only */
+ } b_int_ate_ram_lo[128];
+
+ char _pad_011400[0x20000 - 0x011400];
+
+ /* PCI Device Configuration Spaces 0x020000-0x027FFF */
+ union { /* make all access sizes available. */
+ u8 c[0x1000 / 1];
+ u16 s[0x1000 / 2];
+ u32 l[0x1000 / 4];
+ u64 d[0x1000 / 8];
+ union {
+ u8 c[0x100 / 1];
+ u16 s[0x100 / 2];
+ u32 l[0x100 / 4];
+ u64 d[0x100 / 8];
+ } f[8];
+ } b_type0_cfg_dev[8]; /* 0x020000 */
+
+ /* PCI Type 1 Configuration Space 0x028000-0x028FFF */
+ union { /* make all access sizes available. */
+ u8 c[0x1000 / 1];
+ u16 s[0x1000 / 2];
+ u32 l[0x1000 / 4];
+ u64 d[0x1000 / 8];
+ } b_type1_cfg; /* 0x028000-0x029000 */
+
+ char _pad_029000[0x007000]; /* 0x029000-0x030000 */
+
+ /* PCI Interrupt Acknowledge Cycle 0x030000 */
+ union {
+ u8 c[8 / 1];
+ u16 s[8 / 2];
+ u32 l[8 / 4];
+ u64 d[8 / 8];
+ } b_pci_iack; /* 0x030000 */
+
+ u8 _pad_030007[0x04fff8]; /* 0x030008-0x07FFFF */
+
+ /* External Address Translation Entry RAM 0x080000-0x0FFFFF */
+ bridge_ate_t b_ext_ate_ram[0x10000];
+
+ /* Reserved 0x100000-0x1FFFFF */
+ char _pad_100000[0x200000-0x100000];
+
+ /* PCI/GIO Device Spaces 0x200000-0xBFFFFF */
+ union { /* make all access sizes available. */
+ u8 c[0x100000 / 1];
+ u16 s[0x100000 / 2];
+ u32 l[0x100000 / 4];
+ u64 d[0x100000 / 8];
+ } b_devio_raw[10]; /* 0x200000 */
+
+ /* b_devio macro is a bit strange; it reflects the
+ * fact that the Bridge ASIC provides 2M for the
+ * first two DevIO windows and 1M for the other six.
+ */
+#define b_devio(n) b_devio_raw[((n)<2)?(n*2):(n+2)]
+
+ /* External Flash Proms 1,0 0xC00000-0xFFFFFF */
+ union { /* make all access sizes available. */
+ u8 c[0x400000 / 1]; /* read-only */
+ u16 s[0x400000 / 2]; /* read-write */
+ u32 l[0x400000 / 4]; /* read-only */
+ u64 d[0x400000 / 8]; /* read-only */
+ } b_external_flash; /* 0xC00000 */
+} bridge_t;
+
+/*
+ * Field formats for Error Command Word and Auxiliary Error Command Word
+ * of bridge.
+ */
+typedef struct bridge_err_cmdword_s {
+ union {
+ u32 cmd_word;
+ struct {
+ u32 didn:4, /* Destination ID */
+ sidn:4, /* Source ID */
+ pactyp:4, /* Packet type */
+ tnum:5, /* Trans Number */
+ coh:1, /* Coh Transacti */
+ ds:2, /* Data size */
+ gbr:1, /* GBR enable */
+ vbpm:1, /* VBPM message */
+ error:1, /* Error occurred */
+ barr:1, /* Barrier op */
+ rsvd:8;
+ } berr_st;
+ } berr_un;
+} bridge_err_cmdword_t;
+
+#define berr_field berr_un.berr_st
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * The values of these macros can and should be crosschecked
+ * regularly against the offsets of the like-named fields
+ * within the "bridge_t" structure above.
+ */
+
+/* Byte offset macros for Bridge internal registers */
+
+#define BRIDGE_WID_ID WIDGET_ID
+#define BRIDGE_WID_STAT WIDGET_STATUS
+#define BRIDGE_WID_ERR_UPPER WIDGET_ERR_UPPER_ADDR
+#define BRIDGE_WID_ERR_LOWER WIDGET_ERR_LOWER_ADDR
+#define BRIDGE_WID_CONTROL WIDGET_CONTROL
+#define BRIDGE_WID_REQ_TIMEOUT WIDGET_REQ_TIMEOUT
+#define BRIDGE_WID_INT_UPPER WIDGET_INTDEST_UPPER_ADDR
+#define BRIDGE_WID_INT_LOWER WIDGET_INTDEST_LOWER_ADDR
+#define BRIDGE_WID_ERR_CMDWORD WIDGET_ERR_CMD_WORD
+#define BRIDGE_WID_LLP WIDGET_LLP_CFG
+#define BRIDGE_WID_TFLUSH WIDGET_TFLUSH
+
+#define BRIDGE_WID_AUX_ERR 0x00005C /* Aux Error Command Word */
+#define BRIDGE_WID_RESP_UPPER 0x000064 /* Response Buf Upper Addr */
+#define BRIDGE_WID_RESP_LOWER 0x00006C /* Response Buf Lower Addr */
+#define BRIDGE_WID_TST_PIN_CTRL 0x000074 /* Test pin control */
+
+#define BRIDGE_DIR_MAP 0x000084 /* Direct Map reg */
+
+#define BRIDGE_RAM_PERR 0x000094 /* SSRAM Parity Error */
+
+#define BRIDGE_ARB 0x0000A4 /* Arbitration Priority reg */
+
+#define BRIDGE_NIC 0x0000B4 /* Number In A Can */
+
+#define BRIDGE_BUS_TIMEOUT 0x0000C4 /* Bus Timeout Register */
+#define BRIDGE_PCI_BUS_TIMEOUT BRIDGE_BUS_TIMEOUT
+#define BRIDGE_PCI_CFG 0x0000CC /* PCI Type 1 Config reg */
+#define BRIDGE_PCI_ERR_UPPER 0x0000D4 /* PCI error Upper Addr */
+#define BRIDGE_PCI_ERR_LOWER 0x0000DC /* PCI error Lower Addr */
+
+#define BRIDGE_INT_STATUS 0x000104 /* Interrupt Status */
+#define BRIDGE_INT_ENABLE 0x00010C /* Interrupt Enables */
+#define BRIDGE_INT_RST_STAT 0x000114 /* Reset Intr Status */
+#define BRIDGE_INT_MODE 0x00011C /* Interrupt Mode */
+#define BRIDGE_INT_DEVICE 0x000124 /* Interrupt Device */
+#define BRIDGE_INT_HOST_ERR 0x00012C /* Host Error Field */
+
+#define BRIDGE_INT_ADDR0 0x000134 /* Host Address Reg */
+#define BRIDGE_INT_ADDR_OFF 0x000008 /* Host Addr offset (1..7) */
+#define BRIDGE_INT_ADDR(x) (BRIDGE_INT_ADDR0+(x)*BRIDGE_INT_ADDR_OFF)
+
+#define BRIDGE_DEVICE0 0x000204 /* Device 0 */
+#define BRIDGE_DEVICE_OFF 0x000008 /* Device offset (1..7) */
+#define BRIDGE_DEVICE(x) (BRIDGE_DEVICE0+(x)*BRIDGE_DEVICE_OFF)
+
+#define BRIDGE_WR_REQ_BUF0 0x000244 /* Write Request Buffer 0 */
+#define BRIDGE_WR_REQ_BUF_OFF 0x000008 /* Buffer Offset (1..7) */
+#define BRIDGE_WR_REQ_BUF(x) (BRIDGE_WR_REQ_BUF0+(x)*BRIDGE_WR_REQ_BUF_OFF)
+
+#define BRIDGE_EVEN_RESP 0x000284 /* Even Device Response Buf */
+#define BRIDGE_ODD_RESP 0x00028C /* Odd Device Response Buf */
+
+#define BRIDGE_RESP_STATUS 0x000294 /* Read Response Status reg */
+#define BRIDGE_RESP_CLEAR 0x00029C /* Read Response Clear reg */
+
+/* Byte offset macros for Bridge I/O space */
+
+#define BRIDGE_ATE_RAM 0x00010000 /* Internal Addr Xlat Ram */
+
+#define BRIDGE_TYPE0_CFG_DEV0 0x00020000 /* Type 0 Cfg, Device 0 */
+#define BRIDGE_TYPE0_CFG_SLOT_OFF 0x00001000 /* Type 0 Cfg Slot Offset (1..7) */
+#define BRIDGE_TYPE0_CFG_FUNC_OFF 0x00000100 /* Type 0 Cfg Func Offset (1..7) */
+#define BRIDGE_TYPE0_CFG_DEV(s) (BRIDGE_TYPE0_CFG_DEV0+\
+ (s)*BRIDGE_TYPE0_CFG_SLOT_OFF)
+#define BRIDGE_TYPE0_CFG_DEVF(s, f) (BRIDGE_TYPE0_CFG_DEV0+\
+ (s)*BRIDGE_TYPE0_CFG_SLOT_OFF+\
+ (f)*BRIDGE_TYPE0_CFG_FUNC_OFF)
+
+#define BRIDGE_TYPE1_CFG 0x00028000 /* Type 1 Cfg space */
+
+#define BRIDGE_PCI_IACK 0x00030000 /* PCI Interrupt Ack */
+#define BRIDGE_EXT_SSRAM 0x00080000 /* Extern SSRAM (ATE) */
+
+/* Byte offset macros for Bridge device IO spaces */
+
+#define BRIDGE_DEV_CNT 8 /* Up to 8 devices per bridge */
+#define BRIDGE_DEVIO0 0x00200000 /* Device IO 0 Addr */
+#define BRIDGE_DEVIO1 0x00400000 /* Device IO 1 Addr */
+#define BRIDGE_DEVIO2 0x00600000 /* Device IO 2 Addr */
+#define BRIDGE_DEVIO_OFF 0x00100000 /* Device IO Offset (3..7) */
+
+#define BRIDGE_DEVIO_2MB 0x00200000 /* Device IO Offset (0..1) */
+#define BRIDGE_DEVIO_1MB 0x00100000 /* Device IO Offset (2..7) */
+
+#define BRIDGE_DEVIO(x) ((x)<=1 ? BRIDGE_DEVIO0+(x)*BRIDGE_DEVIO_2MB : BRIDGE_DEVIO2+((x)-2)*BRIDGE_DEVIO_1MB)
+
+#define BRIDGE_EXTERNAL_FLASH 0x00C00000 /* External Flash PROMS */
+
+/* ========================================================================
+ * Bridge register bit field definitions
+ */
+
+/* Widget part number of bridge */
+#define BRIDGE_WIDGET_PART_NUM 0xc002
+#define XBRIDGE_WIDGET_PART_NUM 0xd002
+
+/* Manufacturer of bridge */
+#define BRIDGE_WIDGET_MFGR_NUM 0x036
+#define XBRIDGE_WIDGET_MFGR_NUM 0x024
+
+/* Revision numbers for known Bridge revisions */
+#define BRIDGE_REV_A 0x1
+#define BRIDGE_REV_B 0x2
+#define BRIDGE_REV_C 0x3
+#define BRIDGE_REV_D 0x4
+
+/* Bridge widget status register bits definition */
+
+#define BRIDGE_STAT_LLP_REC_CNT (0xFFu << 24)
+#define BRIDGE_STAT_LLP_TX_CNT (0xFF << 16)
+#define BRIDGE_STAT_FLASH_SELECT (0x1 << 6)
+#define BRIDGE_STAT_PCI_GIO_N (0x1 << 5)
+#define BRIDGE_STAT_PENDING (0x1F << 0)
+
+/* Bridge widget control register bits definition */
+#define BRIDGE_CTRL_FLASH_WR_EN (0x1ul << 31)
+#define BRIDGE_CTRL_EN_CLK50 (0x1 << 30)
+#define BRIDGE_CTRL_EN_CLK40 (0x1 << 29)
+#define BRIDGE_CTRL_EN_CLK33 (0x1 << 28)
+#define BRIDGE_CTRL_RST(n) ((n) << 24)
+#define BRIDGE_CTRL_RST_MASK (BRIDGE_CTRL_RST(0xF))
+#define BRIDGE_CTRL_RST_PIN(x) (BRIDGE_CTRL_RST(0x1 << (x)))
+#define BRIDGE_CTRL_IO_SWAP (0x1 << 23)
+#define BRIDGE_CTRL_MEM_SWAP (0x1 << 22)
+#define BRIDGE_CTRL_PAGE_SIZE (0x1 << 21)
+#define BRIDGE_CTRL_SS_PAR_BAD (0x1 << 20)
+#define BRIDGE_CTRL_SS_PAR_EN (0x1 << 19)
+#define BRIDGE_CTRL_SSRAM_SIZE(n) ((n) << 17)
+#define BRIDGE_CTRL_SSRAM_SIZE_MASK (BRIDGE_CTRL_SSRAM_SIZE(0x3))
+#define BRIDGE_CTRL_SSRAM_512K (BRIDGE_CTRL_SSRAM_SIZE(0x3))
+#define BRIDGE_CTRL_SSRAM_128K (BRIDGE_CTRL_SSRAM_SIZE(0x2))
+#define BRIDGE_CTRL_SSRAM_64K (BRIDGE_CTRL_SSRAM_SIZE(0x1))
+#define BRIDGE_CTRL_SSRAM_1K (BRIDGE_CTRL_SSRAM_SIZE(0x0))
+#define BRIDGE_CTRL_F_BAD_PKT (0x1 << 16)
+#define BRIDGE_CTRL_LLP_XBAR_CRD(n) ((n) << 12)
+#define BRIDGE_CTRL_LLP_XBAR_CRD_MASK (BRIDGE_CTRL_LLP_XBAR_CRD(0xf))
+#define BRIDGE_CTRL_CLR_RLLP_CNT (0x1 << 11)
+#define BRIDGE_CTRL_CLR_TLLP_CNT (0x1 << 10)
+#define BRIDGE_CTRL_SYS_END (0x1 << 9)
+#define BRIDGE_CTRL_MAX_TRANS(n) ((n) << 4)
+#define BRIDGE_CTRL_MAX_TRANS_MASK (BRIDGE_CTRL_MAX_TRANS(0x1f))
+#define BRIDGE_CTRL_WIDGET_ID(n) ((n) << 0)
+#define BRIDGE_CTRL_WIDGET_ID_MASK (BRIDGE_CTRL_WIDGET_ID(0xf))
+
+/* Bridge Response buffer Error Upper Register bit fields definition */
+#define BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT (20)
+#define BRIDGE_RESP_ERRUPPR_DEVNUM_MASK (0x7 << BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT)
+#define BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT (16)
+#define BRIDGE_RESP_ERRUPPR_BUFNUM_MASK (0xF << BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT)
+#define BRIDGE_RESP_ERRRUPPR_BUFMASK (0xFFFF)
+
+#define BRIDGE_RESP_ERRUPPR_BUFNUM(x) \
+ (((x) & BRIDGE_RESP_ERRUPPR_BUFNUM_MASK) >> \
+ BRIDGE_RESP_ERRUPPR_BUFNUM_SHFT)
+
+#define BRIDGE_RESP_ERRUPPR_DEVICE(x) \
+ (((x) & BRIDGE_RESP_ERRUPPR_DEVNUM_MASK) >> \
+ BRIDGE_RESP_ERRUPPR_DEVNUM_SHFT)
+
+/* Bridge direct mapping register bits definition */
+#define BRIDGE_DIRMAP_W_ID_SHFT 20
+#define BRIDGE_DIRMAP_W_ID (0xf << BRIDGE_DIRMAP_W_ID_SHFT)
+#define BRIDGE_DIRMAP_RMF_64 (0x1 << 18)
+#define BRIDGE_DIRMAP_ADD512 (0x1 << 17)
+#define BRIDGE_DIRMAP_OFF (0x1ffff << 0)
+#define BRIDGE_DIRMAP_OFF_ADDRSHFT (31) /* lsbit of DIRMAP_OFF is xtalk address bit 31 */
+
+/* Bridge Arbitration register bits definition */
+#define BRIDGE_ARB_REQ_WAIT_TICK(x) ((x) << 16)
+#define BRIDGE_ARB_REQ_WAIT_TICK_MASK BRIDGE_ARB_REQ_WAIT_TICK(0x3)
+#define BRIDGE_ARB_REQ_WAIT_EN(x) ((x) << 8)
+#define BRIDGE_ARB_REQ_WAIT_EN_MASK BRIDGE_ARB_REQ_WAIT_EN(0xff)
+#define BRIDGE_ARB_FREEZE_GNT (1 << 6)
+#define BRIDGE_ARB_HPRI_RING_B2 (1 << 5)
+#define BRIDGE_ARB_HPRI_RING_B1 (1 << 4)
+#define BRIDGE_ARB_HPRI_RING_B0 (1 << 3)
+#define BRIDGE_ARB_LPRI_RING_B2 (1 << 2)
+#define BRIDGE_ARB_LPRI_RING_B1 (1 << 1)
+#define BRIDGE_ARB_LPRI_RING_B0 (1 << 0)
+
+/* Bridge Bus time-out register bits definition */
+#define BRIDGE_BUS_PCI_RETRY_HLD(x) ((x) << 16)
+#define BRIDGE_BUS_PCI_RETRY_HLD_MASK BRIDGE_BUS_PCI_RETRY_HLD(0x1f)
+#define BRIDGE_BUS_GIO_TIMEOUT (1 << 12)
+#define BRIDGE_BUS_PCI_RETRY_CNT(x) ((x) << 0)
+#define BRIDGE_BUS_PCI_RETRY_MASK BRIDGE_BUS_PCI_RETRY_CNT(0x3ff)
+
+/* Bridge interrupt status register bits definition */
+#define BRIDGE_ISR_MULTI_ERR (0x1u << 31)
+#define BRIDGE_ISR_PMU_ESIZE_FAULT (0x1 << 30)
+#define BRIDGE_ISR_UNEXP_RESP (0x1 << 29)
+#define BRIDGE_ISR_BAD_XRESP_PKT (0x1 << 28)
+#define BRIDGE_ISR_BAD_XREQ_PKT (0x1 << 27)
+#define BRIDGE_ISR_RESP_XTLK_ERR (0x1 << 26)
+#define BRIDGE_ISR_REQ_XTLK_ERR (0x1 << 25)
+#define BRIDGE_ISR_INVLD_ADDR (0x1 << 24)
+#define BRIDGE_ISR_UNSUPPORTED_XOP (0x1 << 23)
+#define BRIDGE_ISR_XREQ_FIFO_OFLOW (0x1 << 22)
+#define BRIDGE_ISR_LLP_REC_SNERR (0x1 << 21)
+#define BRIDGE_ISR_LLP_REC_CBERR (0x1 << 20)
+#define BRIDGE_ISR_LLP_RCTY (0x1 << 19)
+#define BRIDGE_ISR_LLP_TX_RETRY (0x1 << 18)
+#define BRIDGE_ISR_LLP_TCTY (0x1 << 17)
+#define BRIDGE_ISR_SSRAM_PERR (0x1 << 16)
+#define BRIDGE_ISR_PCI_ABORT (0x1 << 15)
+#define BRIDGE_ISR_PCI_PARITY (0x1 << 14)
+#define BRIDGE_ISR_PCI_SERR (0x1 << 13)
+#define BRIDGE_ISR_PCI_PERR (0x1 << 12)
+#define BRIDGE_ISR_PCI_MST_TIMEOUT (0x1 << 11)
+#define BRIDGE_ISR_GIO_MST_TIMEOUT BRIDGE_ISR_PCI_MST_TIMEOUT
+#define BRIDGE_ISR_PCI_RETRY_CNT (0x1 << 10)
+#define BRIDGE_ISR_XREAD_REQ_TIMEOUT (0x1 << 9)
+#define BRIDGE_ISR_GIO_B_ENBL_ERR (0x1 << 8)
+#define BRIDGE_ISR_INT_MSK (0xff << 0)
+#define BRIDGE_ISR_INT(x) (0x1 << (x))
+
+#define BRIDGE_ISR_LINK_ERROR \
+ (BRIDGE_ISR_LLP_REC_SNERR|BRIDGE_ISR_LLP_REC_CBERR| \
+ BRIDGE_ISR_LLP_RCTY|BRIDGE_ISR_LLP_TX_RETRY| \
+ BRIDGE_ISR_LLP_TCTY)
+
+#define BRIDGE_ISR_PCIBUS_PIOERR \
+ (BRIDGE_ISR_PCI_MST_TIMEOUT|BRIDGE_ISR_PCI_ABORT)
+
+#define BRIDGE_ISR_PCIBUS_ERROR \
+ (BRIDGE_ISR_PCIBUS_PIOERR|BRIDGE_ISR_PCI_PERR| \
+ BRIDGE_ISR_PCI_SERR|BRIDGE_ISR_PCI_RETRY_CNT| \
+ BRIDGE_ISR_PCI_PARITY)
+
+#define BRIDGE_ISR_XTALK_ERROR \
+ (BRIDGE_ISR_XREAD_REQ_TIMEOUT|BRIDGE_ISR_XREQ_FIFO_OFLOW|\
+ BRIDGE_ISR_UNSUPPORTED_XOP|BRIDGE_ISR_INVLD_ADDR| \
+ BRIDGE_ISR_REQ_XTLK_ERR|BRIDGE_ISR_RESP_XTLK_ERR| \
+ BRIDGE_ISR_BAD_XREQ_PKT|BRIDGE_ISR_BAD_XRESP_PKT| \
+ BRIDGE_ISR_UNEXP_RESP)
+
+#define BRIDGE_ISR_ERRORS \
+ (BRIDGE_ISR_LINK_ERROR|BRIDGE_ISR_PCIBUS_ERROR| \
+ BRIDGE_ISR_XTALK_ERROR|BRIDGE_ISR_SSRAM_PERR| \
+ BRIDGE_ISR_PMU_ESIZE_FAULT)
+
+/*
+ * List of Errors which are fatal and kill the system
+ */
+#define BRIDGE_ISR_ERROR_FATAL \
+ ((BRIDGE_ISR_XTALK_ERROR & ~BRIDGE_ISR_XREAD_REQ_TIMEOUT)|\
+ BRIDGE_ISR_PCI_SERR|BRIDGE_ISR_PCI_PARITY )
+
+#define BRIDGE_ISR_ERROR_DUMP \
+ (BRIDGE_ISR_PCIBUS_ERROR|BRIDGE_ISR_PMU_ESIZE_FAULT| \
+ BRIDGE_ISR_XTALK_ERROR|BRIDGE_ISR_SSRAM_PERR)
+
+/* Bridge interrupt enable register bits definition */
+#define BRIDGE_IMR_UNEXP_RESP BRIDGE_ISR_UNEXP_RESP
+#define BRIDGE_IMR_PMU_ESIZE_FAULT BRIDGE_ISR_PMU_ESIZE_FAULT
+#define BRIDGE_IMR_BAD_XRESP_PKT BRIDGE_ISR_BAD_XRESP_PKT
+#define BRIDGE_IMR_BAD_XREQ_PKT BRIDGE_ISR_BAD_XREQ_PKT
+#define BRIDGE_IMR_RESP_XTLK_ERR BRIDGE_ISR_RESP_XTLK_ERR
+#define BRIDGE_IMR_REQ_XTLK_ERR BRIDGE_ISR_REQ_XTLK_ERR
+#define BRIDGE_IMR_INVLD_ADDR BRIDGE_ISR_INVLD_ADDR
+#define BRIDGE_IMR_UNSUPPORTED_XOP BRIDGE_ISR_UNSUPPORTED_XOP
+#define BRIDGE_IMR_XREQ_FIFO_OFLOW BRIDGE_ISR_XREQ_FIFO_OFLOW
+#define BRIDGE_IMR_LLP_REC_SNERR BRIDGE_ISR_LLP_REC_SNERR
+#define BRIDGE_IMR_LLP_REC_CBERR BRIDGE_ISR_LLP_REC_CBERR
+#define BRIDGE_IMR_LLP_RCTY BRIDGE_ISR_LLP_RCTY
+#define BRIDGE_IMR_LLP_TX_RETRY BRIDGE_ISR_LLP_TX_RETRY
+#define BRIDGE_IMR_LLP_TCTY BRIDGE_ISR_LLP_TCTY
+#define BRIDGE_IMR_SSRAM_PERR BRIDGE_ISR_SSRAM_PERR
+#define BRIDGE_IMR_PCI_ABORT BRIDGE_ISR_PCI_ABORT
+#define BRIDGE_IMR_PCI_PARITY BRIDGE_ISR_PCI_PARITY
+#define BRIDGE_IMR_PCI_SERR BRIDGE_ISR_PCI_SERR
+#define BRIDGE_IMR_PCI_PERR BRIDGE_ISR_PCI_PERR
+#define BRIDGE_IMR_PCI_MST_TIMEOUT BRIDGE_ISR_PCI_MST_TIMEOUT
+#define BRIDGE_IMR_GIO_MST_TIMEOUT BRIDGE_ISR_GIO_MST_TIMEOUT
+#define BRIDGE_IMR_PCI_RETRY_CNT BRIDGE_ISR_PCI_RETRY_CNT
+#define BRIDGE_IMR_XREAD_REQ_TIMEOUT BRIDGE_ISR_XREAD_REQ_TIMEOUT
+#define BRIDGE_IMR_GIO_B_ENBL_ERR BRIDGE_ISR_GIO_B_ENBL_ERR
+#define BRIDGE_IMR_INT_MSK BRIDGE_ISR_INT_MSK
+#define BRIDGE_IMR_INT(x) BRIDGE_ISR_INT(x)
+
+/* Bridge interrupt reset register bits definition */
+#define BRIDGE_IRR_MULTI_CLR (0x1 << 6)
+#define BRIDGE_IRR_CRP_GRP_CLR (0x1 << 5)
+#define BRIDGE_IRR_RESP_BUF_GRP_CLR (0x1 << 4)
+#define BRIDGE_IRR_REQ_DSP_GRP_CLR (0x1 << 3)
+#define BRIDGE_IRR_LLP_GRP_CLR (0x1 << 2)
+#define BRIDGE_IRR_SSRAM_GRP_CLR (0x1 << 1)
+#define BRIDGE_IRR_PCI_GRP_CLR (0x1 << 0)
+#define BRIDGE_IRR_GIO_GRP_CLR (0x1 << 0)
+#define BRIDGE_IRR_ALL_CLR 0x7f
+
+#define BRIDGE_IRR_CRP_GRP (BRIDGE_ISR_UNEXP_RESP | \
+ BRIDGE_ISR_XREQ_FIFO_OFLOW)
+#define BRIDGE_IRR_RESP_BUF_GRP (BRIDGE_ISR_BAD_XRESP_PKT | \
+ BRIDGE_ISR_RESP_XTLK_ERR | \
+ BRIDGE_ISR_XREAD_REQ_TIMEOUT)
+#define BRIDGE_IRR_REQ_DSP_GRP (BRIDGE_ISR_UNSUPPORTED_XOP | \
+ BRIDGE_ISR_BAD_XREQ_PKT | \
+ BRIDGE_ISR_REQ_XTLK_ERR | \
+ BRIDGE_ISR_INVLD_ADDR)
+#define BRIDGE_IRR_LLP_GRP (BRIDGE_ISR_LLP_REC_SNERR | \
+ BRIDGE_ISR_LLP_REC_CBERR | \
+ BRIDGE_ISR_LLP_RCTY | \
+ BRIDGE_ISR_LLP_TX_RETRY | \
+ BRIDGE_ISR_LLP_TCTY)
+#define BRIDGE_IRR_SSRAM_GRP (BRIDGE_ISR_SSRAM_PERR | \
+ BRIDGE_ISR_PMU_ESIZE_FAULT)
+#define BRIDGE_IRR_PCI_GRP (BRIDGE_ISR_PCI_ABORT | \
+ BRIDGE_ISR_PCI_PARITY | \
+ BRIDGE_ISR_PCI_SERR | \
+ BRIDGE_ISR_PCI_PERR | \
+ BRIDGE_ISR_PCI_MST_TIMEOUT | \
+ BRIDGE_ISR_PCI_RETRY_CNT)
+
+#define BRIDGE_IRR_GIO_GRP (BRIDGE_ISR_GIO_B_ENBL_ERR | \
+ BRIDGE_ISR_GIO_MST_TIMEOUT)
+
+/* Bridge INT_DEV register bits definition */
+#define BRIDGE_INT_DEV_SHFT(n) ((n)*3)
+#define BRIDGE_INT_DEV_MASK(n) (0x7 << BRIDGE_INT_DEV_SHFT(n))
+#define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line))
+
+/* Bridge interrupt(x) register bits definition */
+#define BRIDGE_INT_ADDR_HOST 0x0003FF00
+#define BRIDGE_INT_ADDR_FLD 0x000000FF
+
+#define BRIDGE_TMO_PCI_RETRY_HLD_MASK 0x1f0000
+#define BRIDGE_TMO_GIO_TIMEOUT_MASK 0x001000
+#define BRIDGE_TMO_PCI_RETRY_CNT_MASK 0x0003ff
+
+#define BRIDGE_TMO_PCI_RETRY_CNT_MAX 0x3ff
+
+/*
+ * The NASID should be shifted by this amount and stored into the
+ * interrupt(x) register.
+ */
+#define BRIDGE_INT_ADDR_NASID_SHFT 8
+
+/*
+ * The BRIDGE_INT_ADDR_DEST_IO bit should be set to send an interrupt to
+ * memory.
+ */
+#define BRIDGE_INT_ADDR_DEST_IO (1 << 17)
+#define BRIDGE_INT_ADDR_DEST_MEM 0
+#define BRIDGE_INT_ADDR_MASK (1 << 17)
+
+/* Bridge device(x) register bits definition */
+#define BRIDGE_DEV_ERR_LOCK_EN 0x10000000
+#define BRIDGE_DEV_PAGE_CHK_DIS 0x08000000
+#define BRIDGE_DEV_FORCE_PCI_PAR 0x04000000
+#define BRIDGE_DEV_VIRTUAL_EN 0x02000000
+#define BRIDGE_DEV_PMU_WRGA_EN 0x01000000
+#define BRIDGE_DEV_DIR_WRGA_EN 0x00800000
+#define BRIDGE_DEV_DEV_SIZE 0x00400000
+#define BRIDGE_DEV_RT 0x00200000
+#define BRIDGE_DEV_SWAP_PMU 0x00100000
+#define BRIDGE_DEV_SWAP_DIR 0x00080000
+#define BRIDGE_DEV_PREF 0x00040000
+#define BRIDGE_DEV_PRECISE 0x00020000
+#define BRIDGE_DEV_COH 0x00010000
+#define BRIDGE_DEV_BARRIER 0x00008000
+#define BRIDGE_DEV_GBR 0x00004000
+#define BRIDGE_DEV_DEV_SWAP 0x00002000
+#define BRIDGE_DEV_DEV_IO_MEM 0x00001000
+#define BRIDGE_DEV_OFF_MASK 0x00000fff
+#define BRIDGE_DEV_OFF_ADDR_SHFT 20
+
+#define BRIDGE_DEV_PMU_BITS (BRIDGE_DEV_PMU_WRGA_EN | \
+ BRIDGE_DEV_SWAP_PMU)
+#define BRIDGE_DEV_D32_BITS (BRIDGE_DEV_DIR_WRGA_EN | \
+ BRIDGE_DEV_SWAP_DIR | \
+ BRIDGE_DEV_PREF | \
+ BRIDGE_DEV_PRECISE | \
+ BRIDGE_DEV_COH | \
+ BRIDGE_DEV_BARRIER)
+#define BRIDGE_DEV_D64_BITS (BRIDGE_DEV_DIR_WRGA_EN | \
+ BRIDGE_DEV_SWAP_DIR | \
+ BRIDGE_DEV_COH | \
+ BRIDGE_DEV_BARRIER)
+
+/* Bridge Error Upper register bit field definition */
+#define BRIDGE_ERRUPPR_DEVMASTER (0x1 << 20) /* Device was master */
+#define BRIDGE_ERRUPPR_PCIVDEV (0x1 << 19) /* Virtual Req value */
+#define BRIDGE_ERRUPPR_DEVNUM_SHFT (16)
+#define BRIDGE_ERRUPPR_DEVNUM_MASK (0x7 << BRIDGE_ERRUPPR_DEVNUM_SHFT)
+#define BRIDGE_ERRUPPR_DEVICE(err) (((err) >> BRIDGE_ERRUPPR_DEVNUM_SHFT) & 0x7)
+#define BRIDGE_ERRUPPR_ADDRMASK (0xFFFF)
+
+/* Bridge interrupt mode register bits definition */
+#define BRIDGE_INTMODE_CLR_PKT_EN(x) (0x1 << (x))
+
+/* this should be written to the xbow's link_control(x) register */
+#define BRIDGE_CREDIT 3
+
+/* RRB assignment register */
+#define BRIDGE_RRB_EN 0x8 /* after shifting down */
+#define BRIDGE_RRB_DEV 0x7 /* after shifting down */
+#define BRIDGE_RRB_VDEV 0x4 /* after shifting down */
+#define BRIDGE_RRB_PDEV 0x3 /* after shifting down */
+
+/* RRB status register */
+#define BRIDGE_RRB_VALID(r) (0x00010000<<(r))
+#define BRIDGE_RRB_INUSE(r) (0x00000001<<(r))
+
+/* RRB clear register */
+#define BRIDGE_RRB_CLEAR(r) (0x00000001<<(r))
+
+/* xbox system controller declarations */
+#define XBOX_BRIDGE_WID 8
+#define FLASH_PROM1_BASE 0xE00000 /* To read the xbox sysctlr status */
+#define XBOX_RPS_EXISTS 1 << 6 /* RPS bit in status register */
+#define XBOX_RPS_FAIL 1 << 4 /* RPS status bit in register */
+
+/* ========================================================================
+ */
+/*
+ * Macros for Xtalk to Bridge bus (PCI/GIO) PIO
+ * refer to section 4.2.1 of Bridge Spec for xtalk to PCI/GIO PIO mappings
+ */
+/* XTALK addresses that map into Bridge Bus addr space */
+#define BRIDGE_PIO32_XTALK_ALIAS_BASE 0x000040000000L
+#define BRIDGE_PIO32_XTALK_ALIAS_LIMIT 0x00007FFFFFFFL
+#define BRIDGE_PIO64_XTALK_ALIAS_BASE 0x000080000000L
+#define BRIDGE_PIO64_XTALK_ALIAS_LIMIT 0x0000BFFFFFFFL
+#define BRIDGE_PCIIO_XTALK_ALIAS_BASE 0x000100000000L
+#define BRIDGE_PCIIO_XTALK_ALIAS_LIMIT 0x0001FFFFFFFFL
+
+/* Ranges of PCI bus space that can be accessed via PIO from xtalk */
+#define BRIDGE_MIN_PIO_ADDR_MEM 0x00000000 /* 1G PCI memory space */
+#define BRIDGE_MAX_PIO_ADDR_MEM 0x3fffffff
+#define BRIDGE_MIN_PIO_ADDR_IO 0x00000000 /* 4G PCI IO space */
+#define BRIDGE_MAX_PIO_ADDR_IO 0xffffffff
+
+/* XTALK addresses that map into PCI addresses */
+#define BRIDGE_PCI_MEM32_BASE BRIDGE_PIO32_XTALK_ALIAS_BASE
+#define BRIDGE_PCI_MEM32_LIMIT BRIDGE_PIO32_XTALK_ALIAS_LIMIT
+#define BRIDGE_PCI_MEM64_BASE BRIDGE_PIO64_XTALK_ALIAS_BASE
+#define BRIDGE_PCI_MEM64_LIMIT BRIDGE_PIO64_XTALK_ALIAS_LIMIT
+#define BRIDGE_PCI_IO_BASE BRIDGE_PCIIO_XTALK_ALIAS_BASE
+#define BRIDGE_PCI_IO_LIMIT BRIDGE_PCIIO_XTALK_ALIAS_LIMIT
+
+/*
+ * Macros for Bridge bus (PCI/GIO) to Xtalk DMA
+ */
+/* Bridge Bus DMA addresses */
+#define BRIDGE_LOCAL_BASE 0
+#define BRIDGE_DMA_MAPPED_BASE 0x40000000
+#define BRIDGE_DMA_MAPPED_SIZE 0x40000000 /* 1G Bytes */
+#define BRIDGE_DMA_DIRECT_BASE 0x80000000
+#define BRIDGE_DMA_DIRECT_SIZE 0x80000000 /* 2G Bytes */
+
+#define PCI32_LOCAL_BASE BRIDGE_LOCAL_BASE
+
+/* PCI addresses of regions decoded by Bridge for DMA */
+#define PCI32_MAPPED_BASE BRIDGE_DMA_MAPPED_BASE
+#define PCI32_DIRECT_BASE BRIDGE_DMA_DIRECT_BASE
+
+#define IS_PCI32_LOCAL(x) ((ulong_t)(x) < PCI32_MAPPED_BASE)
+#define IS_PCI32_MAPPED(x) ((ulong_t)(x) < PCI32_DIRECT_BASE && \
+ (ulong_t)(x) >= PCI32_MAPPED_BASE)
+#define IS_PCI32_DIRECT(x) ((ulong_t)(x) >= PCI32_MAPPED_BASE)
+#define IS_PCI64(x) ((ulong_t)(x) >= PCI64_BASE)
+
+/*
+ * The GIO address space.
+ */
+/* Xtalk to GIO PIO */
+#define BRIDGE_GIO_MEM32_BASE BRIDGE_PIO32_XTALK_ALIAS_BASE
+#define BRIDGE_GIO_MEM32_LIMIT BRIDGE_PIO32_XTALK_ALIAS_LIMIT
+
+#define GIO_LOCAL_BASE BRIDGE_LOCAL_BASE
+
+/* GIO addresses of regions decoded by Bridge for DMA */
+#define GIO_MAPPED_BASE BRIDGE_DMA_MAPPED_BASE
+#define GIO_DIRECT_BASE BRIDGE_DMA_DIRECT_BASE
+
+#define IS_GIO_LOCAL(x) ((ulong_t)(x) < GIO_MAPPED_BASE)
+#define IS_GIO_MAPPED(x) ((ulong_t)(x) < GIO_DIRECT_BASE && \
+ (ulong_t)(x) >= GIO_MAPPED_BASE)
+#define IS_GIO_DIRECT(x) ((ulong_t)(x) >= GIO_MAPPED_BASE)
+
+/* PCI to xtalk mapping */
+
+/* given a DIR_OFF value and a pci/gio 32 bits direct address, determine
+ * which xtalk address is accessed
+ */
+#define BRIDGE_DIRECT_32_SEG_SIZE BRIDGE_DMA_DIRECT_SIZE
+#define BRIDGE_DIRECT_32_TO_XTALK(dir_off,adr) \
+ ((dir_off) * BRIDGE_DIRECT_32_SEG_SIZE + \
+ ((adr) & (BRIDGE_DIRECT_32_SEG_SIZE - 1)) + PHYS_RAMBASE)
+
+/* 64-bit address attribute masks */
+#define PCI64_ATTR_TARG_MASK 0xf000000000000000
+#define PCI64_ATTR_TARG_SHFT 60
+#define PCI64_ATTR_PREF 0x0800000000000000
+#define PCI64_ATTR_PREC 0x0400000000000000
+#define PCI64_ATTR_VIRTUAL 0x0200000000000000
+#define PCI64_ATTR_BAR 0x0100000000000000
+#define PCI64_ATTR_RMF_MASK 0x00ff000000000000
+#define PCI64_ATTR_RMF_SHFT 48
+
+#ifndef __ASSEMBLY__
+/* Address translation entry for mapped pci32 accesses */
+typedef union ate_u {
+ u64 ent;
+ struct ate_s {
+ u64 rmf:16;
+ u64 addr:36;
+ u64 targ:4;
+ u64 reserved:3;
+ u64 barrier:1;
+ u64 prefetch:1;
+ u64 precise:1;
+ u64 coherent:1;
+ u64 valid:1;
+ } field;
+} ate_t;
+#endif /* !__ASSEMBLY__ */
+
+#define ATE_V 0x01
+#define ATE_CO 0x02
+#define ATE_PREC 0x04
+#define ATE_PREF 0x08
+#define ATE_BAR 0x10
+
+#define ATE_PFNSHIFT 12
+#define ATE_TIDSHIFT 8
+#define ATE_RMFSHIFT 48
+
+#define mkate(xaddr, xid, attr) ((xaddr) & 0x0000fffffffff000ULL) | \
+ ((xid)<<ATE_TIDSHIFT) | \
+ (attr)
+
+#define BRIDGE_INTERNAL_ATES 128
+
+struct bridge_controller {
+ struct pci_controller pc;
+ struct resource mem;
+ struct resource io;
+ bridge_t *base;
+ nasid_t nasid;
+ unsigned int widget_id;
+ unsigned int irq_cpu;
+ u64 baddr;
+ unsigned int pci_int[8];
+};
+
+#define BRIDGE_CONTROLLER(bus) \
+ ((struct bridge_controller *)((bus)->sysdata))
+
+extern void register_bridge_irq(unsigned int irq);
+extern int request_bridge_irq(struct bridge_controller *bc);
+
+extern struct pci_ops bridge_pci_ops;
+
+#endif /* _ASM_PCI_BRIDGE_H */
diff --git a/arch/mips/include/asm/percpu.h b/arch/mips/include/asm/percpu.h
new file mode 100644
index 00000000..844e763e
--- /dev/null
+++ b/arch/mips/include/asm/percpu.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_PERCPU_H
+#define __ASM_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif /* __ASM_PERCPU_H */
diff --git a/arch/mips/include/asm/perf_event.h b/arch/mips/include/asm/perf_event.h
new file mode 100644
index 00000000..d0c77496
--- /dev/null
+++ b/arch/mips/include/asm/perf_event.h
@@ -0,0 +1,15 @@
+/*
+ * linux/arch/mips/include/asm/perf_event.h
+ *
+ * Copyright (C) 2010 MIPS Technologies, Inc.
+ * Author: Deng-Cheng Zhu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MIPS_PERF_EVENT_H__
+#define __MIPS_PERF_EVENT_H__
+/* Leave it empty here. The file is required by linux/perf_event.h */
+#endif /* __MIPS_PERF_EVENT_H__ */
diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
new file mode 100644
index 00000000..881d18b4
--- /dev/null
+++ b/arch/mips/include/asm/pgalloc.h
@@ -0,0 +1,132 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2001, 2003 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *pte)
+{
+ set_pmd(pmd, __pmd((unsigned long)pte));
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+ pgtable_t pte)
+{
+ set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
+}
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+/*
+ * Initialize a new pmd table with invalid pointers.
+ */
+extern void pmd_init(unsigned long page, unsigned long pagetable);
+
+#ifndef __PAGETABLE_PMD_FOLDED
+
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+{
+ set_pud(pud, __pud((unsigned long)pmd));
+}
+#endif
+
+/*
+ * Initialize a new pgd / pmd table with invalid pointers.
+ */
+extern void pgd_init(unsigned long page);
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ pgd_t *ret, *init;
+
+ ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
+ if (ret) {
+ init = pgd_offset(&init_mm, 0UL);
+ pgd_init((unsigned long)ret);
+ memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+ }
+
+ return ret;
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+ free_pages((unsigned long)pgd, PGD_ORDER);
+}
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+ unsigned long address)
+{
+ pte_t *pte;
+
+ pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, PTE_ORDER);
+
+ return pte;
+}
+
+static inline struct page *pte_alloc_one(struct mm_struct *mm,
+ unsigned long address)
+{
+ struct page *pte;
+
+ pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
+ if (pte) {
+ clear_highpage(pte);
+ pgtable_page_ctor(pte);
+ }
+ return pte;
+}
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+ free_pages((unsigned long)pte, PTE_ORDER);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+ pgtable_page_dtor(pte);
+ __free_pages(pte, PTE_ORDER);
+}
+
+#define __pte_free_tlb(tlb,pte,address) \
+do { \
+ pgtable_page_dtor(pte); \
+ tlb_remove_page((tlb), pte); \
+} while (0)
+
+#ifndef __PAGETABLE_PMD_FOLDED
+
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+ pmd_t *pmd;
+
+ pmd = (pmd_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, PMD_ORDER);
+ if (pmd)
+ pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table);
+ return pmd;
+}
+
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+ free_pages((unsigned long)pmd, PMD_ORDER);
+}
+
+#define __pmd_free_tlb(tlb, x, addr) pmd_free((tlb)->mm, x)
+
+#endif
+
+#define check_pgt_cache() do { } while (0)
+
+extern void pagetable_init(void);
+
+#endif /* _ASM_PGALLOC_H */
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
new file mode 100644
index 00000000..8a153d2f
--- /dev/null
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -0,0 +1,231 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PGTABLE_32_H
+#define _ASM_PGTABLE_32_H
+
+#include <asm/addrspace.h>
+#include <asm/page.h>
+
+#include <linux/linkage.h>
+#include <asm/cachectl.h>
+#include <asm/fixmap.h>
+
+#include <asm-generic/pgtable-nopmd.h>
+
+/*
+ * - add_wired_entry() add a fixed TLB entry, and move wired register
+ */
+extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+ unsigned long entryhi, unsigned long pagemask);
+
+/*
+ * - add_temporary_entry() add a temporary TLB entry. We use TLB entries
+ * starting at the top and working down. This is for populating the
+ * TLB before trap_init() puts the TLB miss handler in place. It
+ * should be used only for entries matching the actual page tables,
+ * to prevent inconsistencies.
+ */
+extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
+ unsigned long entryhi, unsigned long pagemask);
+
+
+/* Basically we have the same two-level (which is the logical three level
+ * Linux page table layout folded) page tables as the i386. Some day
+ * when we have proper page coloring support we can have a 1% quicker
+ * tlb refill handling mechanism, but for now it is a bit slower but
+ * works even with the cache aliasing problem the R4k and above have.
+ */
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * Entries per page directory level: we use two-level, so
+ * we don't really have any PUD/PMD directory physically.
+ */
+#define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2)
+#define PGD_ORDER (__PGD_ORDER >= 0 ? __PGD_ORDER : 0)
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 1
+#define PTE_ORDER 0
+
+#define PTRS_PER_PGD (USER_PTRS_PER_PGD * 2)
+#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
+
+#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
+#define FIRST_USER_ADDRESS 0
+
+#define VMALLOC_START MAP_BASE
+
+#define PKMAP_BASE (0xfe000000UL)
+
+#ifdef CONFIG_HIGHMEM
+# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
+#else
+# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
+#endif
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e))
+#else
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#endif
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+extern void load_pgd(unsigned long pg_dir);
+
+extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
+
+/*
+ * Empty pgd/pmd entries point to the invalid_pte_table.
+ */
+static inline int pmd_none(pmd_t pmd)
+{
+ return pmd_val(pmd) == (unsigned long) invalid_pte_table;
+}
+
+#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK)
+
+static inline int pmd_present(pmd_t pmd)
+{
+ return pmd_val(pmd) != (unsigned long) invalid_pte_table;
+}
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
+}
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+#define pte_pfn(x) ((unsigned long)((x).pte_high >> 6))
+static inline pte_t
+pfn_pte(unsigned long pfn, pgprot_t prot)
+{
+ pte_t pte;
+ pte.pte_high = (pfn << 6) | (pgprot_val(prot) & 0x3f);
+ pte.pte_low = pgprot_val(prot);
+ return pte;
+}
+
+#else
+
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+#ifdef CONFIG_CPU_VR41XX
+#define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
+#define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
+#else
+#define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT))
+#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot))
+#endif
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
+
+#define __pgd_offset(address) pgd_index(address)
+#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+
+/* to find an entry in a page-table-directory */
+#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
+
+/* Find an entry in the third-level page table.. */
+#define __pte_offset(address) \
+ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset(dir, address) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
+#define pte_offset_kernel(dir, address) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
+
+#define pte_offset_map(dir, address) \
+ ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
+#define pte_unmap(pte) ((void)(pte))
+
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+/* Swap entries must have VALID bit cleared. */
+#define __swp_type(x) (((x).val >> 10) & 0x1f)
+#define __swp_offset(x) ((x).val >> 15)
+#define __swp_entry(type,offset) \
+ ((swp_entry_t) { ((type) << 10) | ((offset) << 15) })
+
+/*
+ * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range:
+ */
+#define PTE_FILE_MAX_BITS 28
+
+#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \
+ (((_pte).pte >> 2 ) & 0x38) | \
+ (((_pte).pte >> 10) << 6 ))
+
+#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \
+ (((off) & 0x38) << 2 ) | \
+ (((off) >> 6 ) << 10) | \
+ _PAGE_FILE })
+
+#else
+
+/* Swap entries must have VALID and GLOBAL bits cleared. */
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#define __swp_type(x) (((x).val >> 2) & 0x1f)
+#define __swp_offset(x) ((x).val >> 7)
+#define __swp_entry(type,offset) \
+ ((swp_entry_t) { ((type) << 2) | ((offset) << 7) })
+#else
+#define __swp_type(x) (((x).val >> 8) & 0x1f)
+#define __swp_offset(x) ((x).val >> 13)
+#define __swp_entry(type,offset) \
+ ((swp_entry_t) { ((type) << 8) | ((offset) << 13) })
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+/*
+ * Bits 0 and 1 of pte_high are taken, use the rest for the page offset...
+ */
+#define PTE_FILE_MAX_BITS 30
+
+#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2)
+#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 })
+
+#else
+/*
+ * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range:
+ */
+#define PTE_FILE_MAX_BITS 28
+
+#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \
+ (((_pte).pte >> 2) & 0x8) | \
+ (((_pte).pte >> 8) << 4))
+
+#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \
+ (((off) & 0x8) << 2) | \
+ (((off) >> 4) << 8) | \
+ _PAGE_FILE })
+#endif
+
+#endif
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
+#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
+#else
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+#endif
+
+#endif /* _ASM_PGTABLE_32_H */
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
new file mode 100644
index 00000000..55908fd5
--- /dev/null
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -0,0 +1,290 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PGTABLE_64_H
+#define _ASM_PGTABLE_64_H
+
+#include <linux/linkage.h>
+
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/cachectl.h>
+#include <asm/fixmap.h>
+
+#ifdef CONFIG_PAGE_SIZE_64KB
+#include <asm-generic/pgtable-nopmd.h>
+#else
+#include <asm-generic/pgtable-nopud.h>
+#endif
+
+/*
+ * Each address space has 2 4K pages as its page directory, giving 1024
+ * (== PTRS_PER_PGD) 8 byte pointers to pmd tables. Each pmd table is a
+ * single 4K page, giving 512 (== PTRS_PER_PMD) 8 byte pointers to page
+ * tables. Each page table is also a single 4K page, giving 512 (==
+ * PTRS_PER_PTE) 8 byte ptes. Each pud entry is initialized to point to
+ * invalid_pmd_table, each pmd entry is initialized to point to
+ * invalid_pte_table, each pte is initialized to 0. When memory is low,
+ * and a pmd table or a page table allocation fails, empty_bad_pmd_table
+ * and empty_bad_page_table is returned back to higher layer code, so
+ * that the failure is recognized later on. Linux does not seem to
+ * handle these failures very well though. The empty_bad_page_table has
+ * invalid pte entries in it, to force page faults.
+ *
+ * Kernel mappings: kernel mappings are held in the swapper_pg_table.
+ * The layout is identical to userspace except it's indexed with the
+ * fault address - VMALLOC_START.
+ */
+
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#ifdef __PAGETABLE_PMD_FOLDED
+#define PGDIR_SHIFT (PAGE_SHIFT + PAGE_SHIFT + PTE_ORDER - 3)
+#else
+
+/* PMD_SHIFT determines the size of the area a second-level page table can map */
+#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3))
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+
+#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3))
+#endif
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * For 4kB page size we use a 3 level page tree and an 8kB pud, which
+ * permits us mapping 40 bits of virtual address space.
+ *
+ * We used to implement 41 bits by having an order 1 pmd level but that seemed
+ * rather pointless.
+ *
+ * For 8kB page size we use a 3 level page tree which permits a total of
+ * 8TB of address space. Alternatively a 33-bit / 8GB organization using
+ * two levels would be easy to implement.
+ *
+ * For 16kB page size we use a 2 level page tree which permits a total of
+ * 36 bits of virtual address space. We could add a third level but it seems
+ * like at the moment there's no need for this.
+ *
+ * For 64kB page size we use a 2 level page table tree for a total of 42 bits
+ * of virtual address space.
+ */
+#ifdef CONFIG_PAGE_SIZE_4KB
+#define PGD_ORDER 1
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 0
+#define PTE_ORDER 0
+#endif
+#ifdef CONFIG_PAGE_SIZE_8KB
+#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 0
+#define PTE_ORDER 0
+#endif
+#ifdef CONFIG_PAGE_SIZE_16KB
+#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 0
+#define PTE_ORDER 0
+#endif
+#ifdef CONFIG_PAGE_SIZE_32KB
+#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER 0
+#define PTE_ORDER 0
+#endif
+#ifdef CONFIG_PAGE_SIZE_64KB
+#define PGD_ORDER 0
+#define PUD_ORDER aieeee_attempt_to_allocate_pud
+#define PMD_ORDER aieeee_attempt_to_allocate_pmd
+#define PTE_ORDER 0
+#endif
+
+#define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
+#ifndef __PAGETABLE_PMD_FOLDED
+#define PTRS_PER_PMD ((PAGE_SIZE << PMD_ORDER) / sizeof(pmd_t))
+#endif
+#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
+
+#if PGDIR_SIZE >= TASK_SIZE64
+#define USER_PTRS_PER_PGD (1)
+#else
+#define USER_PTRS_PER_PGD (TASK_SIZE64 / PGDIR_SIZE)
+#endif
+#define FIRST_USER_ADDRESS 0UL
+
+/*
+ * TLB refill handlers also map the vmalloc area into xuseg. Avoid
+ * the first couple of pages so NULL pointer dereferences will still
+ * reliably trap.
+ */
+#define VMALLOC_START (MAP_BASE + (2 * PAGE_SIZE))
+#define VMALLOC_END \
+ (MAP_BASE + \
+ min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
+ (1UL << cpu_vmbits)) - (1UL << 32))
+
+#if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
+ VMALLOC_START != CKSSEG
+/* Load modules into 32bit-compatible segment. */
+#define MODULE_START CKSSEG
+#define MODULE_END (FIXADDR_START-2*PAGE_SIZE)
+#endif
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
+#ifndef __PAGETABLE_PMD_FOLDED
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
+#endif
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+extern pte_t invalid_pte_table[PTRS_PER_PTE];
+extern pte_t empty_bad_page_table[PTRS_PER_PTE];
+
+
+#ifndef __PAGETABLE_PMD_FOLDED
+/*
+ * For 3-level pagetables we defines these ourselves, for 2-level the
+ * definitions are supplied by <asm-generic/pgtable-nopmd.h>.
+ */
+typedef struct { unsigned long pmd; } pmd_t;
+#define pmd_val(x) ((x).pmd)
+#define __pmd(x) ((pmd_t) { (x) } )
+
+
+extern pmd_t invalid_pmd_table[PTRS_PER_PMD];
+extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
+#endif
+
+/*
+ * Empty pgd/pmd entries point to the invalid_pte_table.
+ */
+static inline int pmd_none(pmd_t pmd)
+{
+ return pmd_val(pmd) == (unsigned long) invalid_pte_table;
+}
+
+#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK)
+
+static inline int pmd_present(pmd_t pmd)
+{
+ return pmd_val(pmd) != (unsigned long) invalid_pte_table;
+}
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
+}
+#ifndef __PAGETABLE_PMD_FOLDED
+
+/*
+ * Empty pud entries point to the invalid_pmd_table.
+ */
+static inline int pud_none(pud_t pud)
+{
+ return pud_val(pud) == (unsigned long) invalid_pmd_table;
+}
+
+static inline int pud_bad(pud_t pud)
+{
+ return pud_val(pud) & ~PAGE_MASK;
+}
+
+static inline int pud_present(pud_t pud)
+{
+ return pud_val(pud) != (unsigned long) invalid_pmd_table;
+}
+
+static inline void pud_clear(pud_t *pudp)
+{
+ pud_val(*pudp) = ((unsigned long) invalid_pmd_table);
+}
+#endif
+
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+#ifdef CONFIG_CPU_VR41XX
+#define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
+#define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
+#else
+#define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT))
+#define pfn_pte(pfn, prot) __pte(((pfn) << _PFN_SHIFT) | pgprot_val(prot))
+#endif
+
+#define __pgd_offset(address) pgd_index(address)
+#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address) pmd_index(address)
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
+/* to find an entry in a page-table-directory */
+#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
+
+#ifndef __PAGETABLE_PMD_FOLDED
+static inline unsigned long pud_page_vaddr(pud_t pud)
+{
+ return pud_val(pud);
+}
+#define pud_phys(pud) virt_to_phys((void *)pud_val(pud))
+#define pud_page(pud) (pfn_to_page(pud_phys(pud) >> PAGE_SHIFT))
+
+/* Find an entry in the second-level page table.. */
+static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address)
+{
+ return (pmd_t *) pud_page_vaddr(*pud) + pmd_index(address);
+}
+#endif
+
+/* Find an entry in the third-level page table.. */
+#define __pte_offset(address) \
+ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset(dir, address) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
+#define pte_offset_kernel(dir, address) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
+#define pte_offset_map(dir, address) \
+ ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
+#define pte_unmap(pte) ((void)(pte))
+
+/*
+ * Initialize a new pgd / pmd table with invalid pointers.
+ */
+extern void pgd_init(unsigned long page);
+extern void pmd_init(unsigned long page, unsigned long pagetable);
+
+/*
+ * Non-present pages: high 24 bits are offset, next 8 bits type,
+ * low 32 bits zero.
+ */
+static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
+{ pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; }
+
+#define __swp_type(x) (((x).val >> 32) & 0xff)
+#define __swp_offset(x) ((x).val >> 40)
+#define __swp_entry(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type), (offset))) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+
+/*
+ * Bits 0, 4, 6, and 7 are taken. Let's leave bits 1, 2, 3, and 5 alone to
+ * make things easier, and only use the upper 56 bits for the page offset...
+ */
+#define PTE_FILE_MAX_BITS 56
+
+#define pte_to_pgoff(_pte) ((_pte).pte >> 8)
+#define pgoff_to_pte(off) ((pte_t) { ((off) << 8) | _PAGE_FILE })
+
+#endif /* _ASM_PGTABLE_64_H */
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
new file mode 100644
index 00000000..e9fe7e97
--- /dev/null
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -0,0 +1,228 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2002 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#ifndef _ASM_PGTABLE_BITS_H
+#define _ASM_PGTABLE_BITS_H
+
+
+/*
+ * Note that we shift the lower 32bits of each EntryLo[01] entry
+ * 6 bits to the left. That way we can convert the PFN into the
+ * physical address by a single 'and' operation and gain 6 additional
+ * bits for storing information which isn't present in a normal
+ * MIPS page table.
+ *
+ * Similar to the Alpha port, we need to keep track of the ref
+ * and mod bits in software. We have a software "yeah you can read
+ * from this page" bit, and a hardware one which actually lets the
+ * process read from the page. On the same token we have a software
+ * writable bit and the real hardware one which actually lets the
+ * process write to the page, this keeps a mod bit via the hardware
+ * dirty bit.
+ *
+ * Certain revisions of the R4000 and R5000 have a bug where if a
+ * certain sequence occurs in the last 3 instructions of an executable
+ * page, and the following page is not mapped, the cpu can do
+ * unpredictable things. The code (when it is written) to deal with
+ * this problem will be in the update_mmu_cache() code for the r4k.
+ */
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+
+#define _PAGE_PRESENT (1<<6) /* implemented in software */
+#define _PAGE_READ (1<<7) /* implemented in software */
+#define _PAGE_WRITE (1<<8) /* implemented in software */
+#define _PAGE_ACCESSED (1<<9) /* implemented in software */
+#define _PAGE_MODIFIED (1<<10) /* implemented in software */
+#define _PAGE_FILE (1<<10) /* set:pagecache unset:swap */
+
+#define _PAGE_R4KBUG (1<<0) /* workaround for r4k bug */
+#define _PAGE_GLOBAL (1<<0)
+#define _PAGE_VALID (1<<1)
+#define _PAGE_SILENT_READ (1<<1) /* synonym */
+#define _PAGE_DIRTY (1<<2) /* The MIPS dirty bit */
+#define _PAGE_SILENT_WRITE (1<<2)
+#define _CACHE_SHIFT 3
+#define _CACHE_MASK (7<<3)
+
+#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+#define _PAGE_PRESENT (1<<0) /* implemented in software */
+#define _PAGE_READ (1<<1) /* implemented in software */
+#define _PAGE_WRITE (1<<2) /* implemented in software */
+#define _PAGE_ACCESSED (1<<3) /* implemented in software */
+#define _PAGE_MODIFIED (1<<4) /* implemented in software */
+#define _PAGE_FILE (1<<4) /* set:pagecache unset:swap */
+
+#define _PAGE_GLOBAL (1<<8)
+#define _PAGE_VALID (1<<9)
+#define _PAGE_SILENT_READ (1<<9) /* synonym */
+#define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */
+#define _PAGE_SILENT_WRITE (1<<10)
+#define _CACHE_UNCACHED (1<<11)
+#define _CACHE_MASK (1<<11)
+
+#else /* 'Normal' r4K case */
+/*
+ * When using the RI/XI bit support, we have 13 bits of flags below
+ * the physical address. The RI/XI bits are placed such that a SRL 5
+ * can strip off the software bits, then a ROTR 2 can move the RI/XI
+ * into bits [63:62]. This also limits physical address to 56 bits,
+ * which is more than we need right now.
+ */
+
+/* implemented in software */
+#define _PAGE_PRESENT_SHIFT (0)
+#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
+/* implemented in software, should be unused if kernel_uses_smartmips_rixi. */
+#define _PAGE_READ_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_READ ({if (kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_READ_SHIFT; })
+/* implemented in software */
+#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
+#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
+/* implemented in software */
+#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
+#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
+/* implemented in software */
+#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
+#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
+/* set:pagecache unset:swap */
+#define _PAGE_FILE (_PAGE_MODIFIED)
+
+#ifdef CONFIG_HUGETLB_PAGE
+/* huge tlb page */
+#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
+#else
+#define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT)
+#define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */
+#endif
+
+/* Page cannot be executed */
+#define _PAGE_NO_EXEC_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
+#define _PAGE_NO_EXEC ({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_EXEC_SHIFT; })
+
+/* Page cannot be read */
+#define _PAGE_NO_READ_SHIFT (kernel_uses_smartmips_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
+#define _PAGE_NO_READ ({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_READ_SHIFT; })
+
+#define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)
+#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
+
+#define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1)
+#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
+/* synonym */
+#define _PAGE_SILENT_READ (_PAGE_VALID)
+
+/* The MIPS dirty bit */
+#define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1)
+#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT)
+#define _PAGE_SILENT_WRITE (_PAGE_DIRTY)
+
+#define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1)
+#define _CACHE_MASK (7 << _CACHE_SHIFT)
+
+#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
+
+#endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */
+
+#ifndef _PFN_SHIFT
+#define _PFN_SHIFT PAGE_SHIFT
+#endif
+#define _PFN_MASK (~((1 << (_PFN_SHIFT)) - 1))
+
+#ifndef _PAGE_NO_READ
+#define _PAGE_NO_READ ({BUG(); 0; })
+#define _PAGE_NO_READ_SHIFT ({BUG(); 0; })
+#endif
+#ifndef _PAGE_NO_EXEC
+#define _PAGE_NO_EXEC ({BUG(); 0; })
+#endif
+#ifndef _PAGE_GLOBAL_SHIFT
+#define _PAGE_GLOBAL_SHIFT ilog2(_PAGE_GLOBAL)
+#endif
+
+
+#ifndef __ASSEMBLY__
+/*
+ * pte_to_entrylo converts a page table entry (PTE) into a Mips
+ * entrylo0/1 value.
+ */
+static inline uint64_t pte_to_entrylo(unsigned long pte_val)
+{
+ if (kernel_uses_smartmips_rixi) {
+ int sa;
+#ifdef CONFIG_32BIT
+ sa = 31 - _PAGE_NO_READ_SHIFT;
+#else
+ sa = 63 - _PAGE_NO_READ_SHIFT;
+#endif
+ /*
+ * C has no way to express that this is a DSRL
+ * _PAGE_NO_EXEC_SHIFT followed by a ROTR 2. Luckily
+ * in the fast path this is done in assembly
+ */
+ return (pte_val >> _PAGE_GLOBAL_SHIFT) |
+ ((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa);
+ }
+
+ return pte_val >> _PAGE_GLOBAL_SHIFT;
+}
+#endif
+
+/*
+ * Cache attributes
+ */
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+#define _CACHE_CACHABLE_NONCOHERENT 0
+
+#elif defined(CONFIG_CPU_SB1)
+
+/* No penalty for being coherent on the SB1, so just
+ use it for "noncoherent" spaces, too. Shouldn't hurt. */
+
+#define _CACHE_UNCACHED (2<<_CACHE_SHIFT)
+#define _CACHE_CACHABLE_COW (5<<_CACHE_SHIFT)
+#define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT)
+#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT)
+
+#elif defined(CONFIG_CPU_RM9000)
+
+#define _CACHE_WT (0<<_CACHE_SHIFT)
+#define _CACHE_WTWA (1<<_CACHE_SHIFT)
+#define _CACHE_UC_B (2<<_CACHE_SHIFT)
+#define _CACHE_WB (3<<_CACHE_SHIFT)
+#define _CACHE_CWBEA (4<<_CACHE_SHIFT)
+#define _CACHE_CWB (5<<_CACHE_SHIFT)
+#define _CACHE_UCNB (6<<_CACHE_SHIFT)
+#define _CACHE_FPC (7<<_CACHE_SHIFT)
+
+#define _CACHE_UNCACHED _CACHE_UC_B
+#define _CACHE_CACHABLE_NONCOHERENT _CACHE_WB
+
+#else
+
+#define _CACHE_CACHABLE_NO_WA (0<<_CACHE_SHIFT) /* R4600 only */
+#define _CACHE_CACHABLE_WA (1<<_CACHE_SHIFT) /* R4600 only */
+#define _CACHE_UNCACHED (2<<_CACHE_SHIFT) /* R4[0246]00 */
+#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* R4[0246]00 */
+#define _CACHE_CACHABLE_CE (4<<_CACHE_SHIFT) /* R4[04]00MC only */
+#define _CACHE_CACHABLE_COW (5<<_CACHE_SHIFT) /* R4[04]00MC only */
+#define _CACHE_CACHABLE_COHERENT (5<<_CACHE_SHIFT) /* MIPS32R2 CMP */
+#define _CACHE_CACHABLE_CUW (6<<_CACHE_SHIFT) /* R4[04]00MC only */
+#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) /* R10000 only */
+
+#endif
+
+#define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ))
+#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
+
+#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
+
+#endif /* _ASM_PGTABLE_BITS_H */
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
new file mode 100644
index 00000000..7e40f377
--- /dev/null
+++ b/arch/mips/include/asm/pgtable.h
@@ -0,0 +1,423 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Ralf Baechle
+ */
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
+
+#ifdef CONFIG_32BIT
+#include <asm/pgtable-32.h>
+#endif
+#ifdef CONFIG_64BIT
+#include <asm/pgtable-64.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/pgtable-bits.h>
+
+struct mm_struct;
+struct vm_area_struct;
+
+#define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
+#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_WRITE | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
+ _page_cachable_default)
+#define PAGE_COPY __pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
+ (kernel_uses_smartmips_rixi ? _PAGE_NO_EXEC : 0) | _page_cachable_default)
+#define PAGE_READONLY __pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
+ _page_cachable_default)
+#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+ _PAGE_GLOBAL | _page_cachable_default)
+#define PAGE_USERIO __pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
+ _page_cachable_default)
+#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
+ __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
+
+/*
+ * If _PAGE_NO_EXEC is not defined, we can't do page protection for
+ * execute, and consider it to be the same as read. Also, write
+ * permissions imply read permissions. This is the closest we can get
+ * by reasonable means..
+ */
+
+/*
+ * Dummy values to fill the table in mmap.c
+ * The real values will be generated at runtime
+ */
+#define __P000 __pgprot(0)
+#define __P001 __pgprot(0)
+#define __P010 __pgprot(0)
+#define __P011 __pgprot(0)
+#define __P100 __pgprot(0)
+#define __P101 __pgprot(0)
+#define __P110 __pgprot(0)
+#define __P111 __pgprot(0)
+
+#define __S000 __pgprot(0)
+#define __S001 __pgprot(0)
+#define __S010 __pgprot(0)
+#define __S011 __pgprot(0)
+#define __S100 __pgprot(0)
+#define __S101 __pgprot(0)
+#define __S110 __pgprot(0)
+#define __S111 __pgprot(0)
+
+extern unsigned long _page_cachable_default;
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero; used
+ * for zero-mapped memory areas etc..
+ */
+
+extern unsigned long empty_zero_page;
+extern unsigned long zero_page_mask;
+
+#define ZERO_PAGE(vaddr) \
+ (virt_to_page((void *)(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))))
+
+#define is_zero_pfn is_zero_pfn
+static inline int is_zero_pfn(unsigned long pfn)
+{
+ extern unsigned long zero_pfn;
+ unsigned long offset_from_zero_pfn = pfn - zero_pfn;
+ return offset_from_zero_pfn <= (zero_page_mask >> PAGE_SHIFT);
+}
+
+#define my_zero_pfn(addr) page_to_pfn(ZERO_PAGE(addr))
+
+extern void paging_init(void);
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd))
+#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
+#define pmd_page_vaddr(pmd) pmd_val(pmd)
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+
+#define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
+#define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT)
+
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+ ptep->pte_high = pte.pte_high;
+ smp_wmb();
+ ptep->pte_low = pte.pte_low;
+ //printk("pte_high %x pte_low %x\n", ptep->pte_high, ptep->pte_low);
+
+ if (pte.pte_low & _PAGE_GLOBAL) {
+ pte_t *buddy = ptep_buddy(ptep);
+ /*
+ * Make sure the buddy is global too (if it's !none,
+ * it better already be global)
+ */
+ if (pte_none(*buddy)) {
+ buddy->pte_low |= _PAGE_GLOBAL;
+ buddy->pte_high |= _PAGE_GLOBAL;
+ }
+ }
+}
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ pte_t null = __pte(0);
+
+ /* Preserve global status for the pair */
+ if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL)
+ null.pte_low = null.pte_high = _PAGE_GLOBAL;
+
+ set_pte_at(mm, addr, ptep, null);
+}
+#else
+
+#define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL))
+#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
+
+/*
+ * Certain architectures need to do special things when pte's
+ * within a page table are directly modified. Thus, the following
+ * hook is made available.
+ */
+static inline void set_pte(pte_t *ptep, pte_t pteval)
+{
+ *ptep = pteval;
+#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
+ if (pte_val(pteval) & _PAGE_GLOBAL) {
+ pte_t *buddy = ptep_buddy(ptep);
+ /*
+ * Make sure the buddy is global too (if it's !none,
+ * it better already be global)
+ */
+ if (pte_none(*buddy))
+ pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
+ }
+#endif
+}
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX)
+ /* Preserve global status for the pair */
+ if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
+ set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL));
+ else
+#endif
+ set_pte_at(mm, addr, ptep, __pte(0));
+}
+#endif
+
+/*
+ * (pmds are folded into puds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0)
+
+#ifndef __PAGETABLE_PMD_FOLDED
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while(0)
+#endif
+
+#define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1)
+#define PMD_T_LOG2 (__builtin_ffs(sizeof(pmd_t)) - 1)
+#define PTE_T_LOG2 (__builtin_ffs(sizeof(pte_t)) - 1)
+
+/*
+ * We used to declare this array with size but gcc 3.3 and older are not able
+ * to find that this expression is a constant, so the size is dropped.
+ */
+extern pgd_t swapper_pg_dir[];
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; }
+static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte) { return pte.pte_low & _PAGE_FILE; }
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+ pte.pte_low &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+ pte.pte_high &= ~_PAGE_SILENT_WRITE;
+ return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+ pte.pte_low &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
+ pte.pte_high &= ~_PAGE_SILENT_WRITE;
+ return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+ pte.pte_low &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
+ pte.pte_high &= ~_PAGE_SILENT_READ;
+ return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+ pte.pte_low |= _PAGE_WRITE;
+ if (pte.pte_low & _PAGE_MODIFIED) {
+ pte.pte_low |= _PAGE_SILENT_WRITE;
+ pte.pte_high |= _PAGE_SILENT_WRITE;
+ }
+ return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+ pte.pte_low |= _PAGE_MODIFIED;
+ if (pte.pte_low & _PAGE_WRITE) {
+ pte.pte_low |= _PAGE_SILENT_WRITE;
+ pte.pte_high |= _PAGE_SILENT_WRITE;
+ }
+ return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+ pte.pte_low |= _PAGE_ACCESSED;
+ if (pte.pte_low & _PAGE_READ) {
+ pte.pte_low |= _PAGE_SILENT_READ;
+ pte.pte_high |= _PAGE_SILENT_READ;
+ }
+ return pte;
+}
+#else
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+ pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+ return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+ pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
+ return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+ pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
+ return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+ pte_val(pte) |= _PAGE_WRITE;
+ if (pte_val(pte) & _PAGE_MODIFIED)
+ pte_val(pte) |= _PAGE_SILENT_WRITE;
+ return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+ pte_val(pte) |= _PAGE_MODIFIED;
+ if (pte_val(pte) & _PAGE_WRITE)
+ pte_val(pte) |= _PAGE_SILENT_WRITE;
+ return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+ pte_val(pte) |= _PAGE_ACCESSED;
+ if (kernel_uses_smartmips_rixi) {
+ if (!(pte_val(pte) & _PAGE_NO_READ))
+ pte_val(pte) |= _PAGE_SILENT_READ;
+ } else {
+ if (pte_val(pte) & _PAGE_READ)
+ pte_val(pte) |= _PAGE_SILENT_READ;
+ }
+ return pte;
+}
+
+#ifdef _PAGE_HUGE
+static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_HUGE; }
+
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+ pte_val(pte) |= _PAGE_HUGE;
+ return pte;
+}
+#endif /* _PAGE_HUGE */
+#endif
+static inline int pte_special(pte_t pte) { return 0; }
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+/*
+ * Macro to make mark a page protection value as "uncacheable". Note
+ * that "protection" is really a misnomer here as the protection value
+ * contains the memory attribute bits, dirty bits, and various other
+ * bits as well.
+ */
+#define pgprot_noncached pgprot_noncached
+
+static inline pgprot_t pgprot_noncached(pgprot_t _prot)
+{
+ unsigned long prot = pgprot_val(_prot);
+
+ prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
+
+ return __pgprot(prot);
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ pte.pte_low &= _PAGE_CHG_MASK;
+ pte.pte_high &= ~0x3f;
+ pte.pte_low |= pgprot_val(newprot);
+ pte.pte_high |= pgprot_val(newprot) & 0x3f;
+ return pte;
+}
+#else
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+#endif
+
+
+extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
+ pte_t pte);
+extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
+ pte_t pte);
+
+static inline void update_mmu_cache(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep)
+{
+ pte_t pte = *ptep;
+ __update_tlb(vma, address, pte);
+ __update_cache(vma, address, pte);
+}
+
+#define kern_addr_valid(addr) (1)
+
+#ifdef CONFIG_64BIT_PHYS_ADDR
+extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+ unsigned long vaddr,
+ unsigned long pfn,
+ unsigned long size,
+ pgprot_t prot)
+{
+ phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
+ return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
+}
+#else
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+#endif
+
+#include <asm-generic/pgtable.h>
+
+/*
+ * uncached accelerated TLB map for video memory access
+ */
+#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+
+struct file;
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t *vma_prot);
+#endif
+
+/*
+ * We provide our own get_unmapped area to cope with the virtual aliasing
+ * constraints placed on us by the cache architecture.
+ */
+#define HAVE_ARCH_UNMAPPED_AREA
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
+
+#endif /* _ASM_PGTABLE_H */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h
new file mode 100644
index 00000000..a80801b0
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/cpu-feature-overrides.h
@@ -0,0 +1,21 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 04, 07 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_mips16 1
+#define cpu_has_dsp 1
+#define cpu_has_mipsmt 1
+#define cpu_has_fpu 0
+
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 1
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#endif /* __ASM_MACH_MSP71XX_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/gpio.h b/arch/mips/include/asm/pmc-sierra/msp71xx/gpio.h
new file mode 100644
index 00000000..ebdbab97
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/gpio.h
@@ -0,0 +1,46 @@
+/*
+ * include/asm-mips/pmc-sierra/msp71xx/gpio.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * @author Patrick Glass <patrickglass@gmail.com>
+ */
+
+#ifndef __PMC_MSP71XX_GPIO_H
+#define __PMC_MSP71XX_GPIO_H
+
+/* Max number of gpio's is 28 on chip plus 3 banks of I2C IO Expanders */
+#define ARCH_NR_GPIOS (28 + (3 * 8))
+
+/* new generic GPIO API - see Documentation/gpio.txt */
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+/* Setup calls for the gpio and gpio extended */
+extern void msp71xx_init_gpio(void);
+extern void msp71xx_init_gpio_extended(void);
+extern int msp71xx_set_output_drive(unsigned gpio, int value);
+
+/* Custom output drive functionss */
+static inline int gpio_set_output_drive(unsigned gpio, int value)
+{
+ return msp71xx_set_output_drive(gpio, value);
+}
+
+/* IRQ's are not supported for gpio lines */
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ return -EINVAL;
+}
+
+#endif /* __PMC_MSP71XX_GPIO_H */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_cic_int.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_cic_int.h
new file mode 100644
index 00000000..c84bcf95
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_cic_int.h
@@ -0,0 +1,151 @@
+/*
+ * Defines for the MSP interrupt controller.
+ *
+ * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved.
+ * Author: Carsten Langgaard, carstenl@mips.com
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+#ifndef _MSP_CIC_INT_H
+#define _MSP_CIC_INT_H
+
+/*
+ * The PMC-Sierra CIC interrupts are all centrally managed by the
+ * CIC sub-system.
+ * We attempt to keep the interrupt numbers as consistent as possible
+ * across all of the MSP devices, but some differences will creep in ...
+ * The interrupts which are directly forwarded to the MIPS core interrupts
+ * are assigned interrupts in the range 0-7, interrupts cascaded through
+ * the CIC are assigned interrupts 8-39. The cascade occurs on C_IRQ4
+ * (MSP_INT_CIC). Currently we don't really distinguish between VPE1
+ * and VPE0 (or thread contexts for that matter). Will have to fix.
+ * The PER interrupts are assigned interrupts in the range 40-71.
+*/
+
+
+/*
+ * IRQs directly forwarded to the CPU
+ */
+#define MSP_MIPS_INTBASE 0
+#define MSP_INT_SW0 0 /* IRQ for swint0, C_SW0 */
+#define MSP_INT_SW1 1 /* IRQ for swint1, C_SW1 */
+#define MSP_INT_MAC0 2 /* IRQ for MAC 0, C_IRQ0 */
+#define MSP_INT_MAC1 3 /* IRQ for MAC 1, C_IRQ1 */
+#define MSP_INT_USB 4 /* IRQ for USB, C_IRQ2 */
+#define MSP_INT_SAR 5 /* IRQ for ADSL2+ SAR, C_IRQ3 */
+#define MSP_INT_CIC 6 /* IRQ for CIC block, C_IRQ4 */
+#define MSP_INT_SEC 7 /* IRQ for Sec engine, C_IRQ5 */
+
+/*
+ * IRQs cascaded on CPU interrupt 4 (CAUSE bit 12, C_IRQ4)
+ * These defines should be tied to the register definitions for the CIC
+ * interrupt routine. For now, just use hard-coded values.
+ */
+#define MSP_CIC_INTBASE (MSP_MIPS_INTBASE + 8)
+#define MSP_INT_EXT0 (MSP_CIC_INTBASE + 0)
+ /* External interrupt 0 */
+#define MSP_INT_EXT1 (MSP_CIC_INTBASE + 1)
+ /* External interrupt 1 */
+#define MSP_INT_EXT2 (MSP_CIC_INTBASE + 2)
+ /* External interrupt 2 */
+#define MSP_INT_EXT3 (MSP_CIC_INTBASE + 3)
+ /* External interrupt 3 */
+#define MSP_INT_CPUIF (MSP_CIC_INTBASE + 4)
+ /* CPU interface interrupt */
+#define MSP_INT_EXT4 (MSP_CIC_INTBASE + 5)
+ /* External interrupt 4 */
+#define MSP_INT_CIC_USB (MSP_CIC_INTBASE + 6)
+ /* Cascaded IRQ for USB */
+#define MSP_INT_MBOX (MSP_CIC_INTBASE + 7)
+ /* Sec engine mailbox IRQ */
+#define MSP_INT_EXT5 (MSP_CIC_INTBASE + 8)
+ /* External interrupt 5 */
+#define MSP_INT_TDM (MSP_CIC_INTBASE + 9)
+ /* TDM interrupt */
+#define MSP_INT_CIC_MAC0 (MSP_CIC_INTBASE + 10)
+ /* Cascaded IRQ for MAC 0 */
+#define MSP_INT_CIC_MAC1 (MSP_CIC_INTBASE + 11)
+ /* Cascaded IRQ for MAC 1 */
+#define MSP_INT_CIC_SEC (MSP_CIC_INTBASE + 12)
+ /* Cascaded IRQ for sec engine */
+#define MSP_INT_PER (MSP_CIC_INTBASE + 13)
+ /* Peripheral interrupt */
+#define MSP_INT_TIMER0 (MSP_CIC_INTBASE + 14)
+ /* SLP timer 0 */
+#define MSP_INT_TIMER1 (MSP_CIC_INTBASE + 15)
+ /* SLP timer 1 */
+#define MSP_INT_TIMER2 (MSP_CIC_INTBASE + 16)
+ /* SLP timer 2 */
+#define MSP_INT_VPE0_TIMER (MSP_CIC_INTBASE + 17)
+ /* VPE0 MIPS timer */
+#define MSP_INT_BLKCP (MSP_CIC_INTBASE + 18)
+ /* Block Copy */
+#define MSP_INT_UART0 (MSP_CIC_INTBASE + 19)
+ /* UART 0 */
+#define MSP_INT_PCI (MSP_CIC_INTBASE + 20)
+ /* PCI subsystem */
+#define MSP_INT_EXT6 (MSP_CIC_INTBASE + 21)
+ /* External interrupt 5 */
+#define MSP_INT_PCI_MSI (MSP_CIC_INTBASE + 22)
+ /* PCI Message Signal */
+#define MSP_INT_CIC_SAR (MSP_CIC_INTBASE + 23)
+ /* Cascaded ADSL2+ SAR IRQ */
+#define MSP_INT_DSL (MSP_CIC_INTBASE + 24)
+ /* ADSL2+ IRQ */
+#define MSP_INT_CIC_ERR (MSP_CIC_INTBASE + 25)
+ /* SLP error condition */
+#define MSP_INT_VPE1_TIMER (MSP_CIC_INTBASE + 26)
+ /* VPE1 MIPS timer */
+#define MSP_INT_VPE0_PC (MSP_CIC_INTBASE + 27)
+ /* VPE0 Performance counter */
+#define MSP_INT_VPE1_PC (MSP_CIC_INTBASE + 28)
+ /* VPE1 Performance counter */
+#define MSP_INT_EXT7 (MSP_CIC_INTBASE + 29)
+ /* External interrupt 5 */
+#define MSP_INT_VPE0_SW (MSP_CIC_INTBASE + 30)
+ /* VPE0 Software interrupt */
+#define MSP_INT_VPE1_SW (MSP_CIC_INTBASE + 31)
+ /* VPE0 Software interrupt */
+
+/*
+ * IRQs cascaded on CIC PER interrupt (MSP_INT_PER)
+ */
+#define MSP_PER_INTBASE (MSP_CIC_INTBASE + 32)
+/* Reserved 0-1 */
+#define MSP_INT_UART1 (MSP_PER_INTBASE + 2)
+ /* UART 1 */
+/* Reserved 3-5 */
+#define MSP_INT_2WIRE (MSP_PER_INTBASE + 6)
+ /* 2-wire */
+#define MSP_INT_TM0 (MSP_PER_INTBASE + 7)
+ /* Peripheral timer block out 0 */
+#define MSP_INT_TM1 (MSP_PER_INTBASE + 8)
+ /* Peripheral timer block out 1 */
+/* Reserved 9 */
+#define MSP_INT_SPRX (MSP_PER_INTBASE + 10)
+ /* SPI RX complete */
+#define MSP_INT_SPTX (MSP_PER_INTBASE + 11)
+ /* SPI TX complete */
+#define MSP_INT_GPIO (MSP_PER_INTBASE + 12)
+ /* GPIO */
+#define MSP_INT_PER_ERR (MSP_PER_INTBASE + 13)
+ /* Peripheral error */
+/* Reserved 14-31 */
+
+#endif /* !_MSP_CIC_INT_H */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h
new file mode 100644
index 00000000..156f320c
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_gpio_macros.h
@@ -0,0 +1,343 @@
+/*
+ *
+ * Macros for external SMP-safe access to the PMC MSP71xx reference
+ * board GPIO pins
+ *
+ * Copyright 2010 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MSP_GPIO_MACROS_H__
+#define __MSP_GPIO_MACROS_H__
+
+#include <msp_regops.h>
+#include <msp_regs.h>
+
+#ifdef CONFIG_PMC_MSP7120_GW
+#define MSP_NUM_GPIOS 20
+#else
+#define MSP_NUM_GPIOS 28
+#endif
+
+/* -- GPIO Enumerations -- */
+enum msp_gpio_data {
+ MSP_GPIO_LO = 0,
+ MSP_GPIO_HI = 1,
+ MSP_GPIO_NONE, /* Special - Means pin is out of range */
+ MSP_GPIO_TOGGLE, /* Special - Sets pin to opposite */
+};
+
+enum msp_gpio_mode {
+ MSP_GPIO_INPUT = 0x0,
+ /* MSP_GPIO_ INTERRUPT = 0x1, Not supported yet */
+ MSP_GPIO_UART_INPUT = 0x2, /* Only GPIO 4 or 5 */
+ MSP_GPIO_OUTPUT = 0x8,
+ MSP_GPIO_UART_OUTPUT = 0x9, /* Only GPIO 2 or 3 */
+ MSP_GPIO_PERIF_TIMERA = 0x9, /* Only GPIO 0 or 1 */
+ MSP_GPIO_PERIF_TIMERB = 0xa, /* Only GPIO 0 or 1 */
+ MSP_GPIO_UNKNOWN = 0xb, /* No such GPIO or mode */
+};
+
+/* -- Static Tables -- */
+
+/* Maps pins to data register */
+static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = {
+ /* GPIO 0 and 1 on the first register */
+ GPIO_DATA1_REG, GPIO_DATA1_REG,
+ /* GPIO 2, 3, 4, and 5 on the second register */
+ GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG,
+ /* GPIO 6, 7, 8, and 9 on the third register */
+ GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG,
+ /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
+ GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG,
+ GPIO_DATA4_REG, GPIO_DATA4_REG,
+ /* GPIO 16 - 23 on the first strange EXTENDED register */
+ EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
+ EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
+ EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
+ /* GPIO 24 - 27 on the second strange EXTENDED register */
+ EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
+ EXTENDED_GPIO2_REG,
+};
+
+/* Maps pins to mode register */
+static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = {
+ /* GPIO 0 and 1 on the first register */
+ GPIO_CFG1_REG, GPIO_CFG1_REG,
+ /* GPIO 2, 3, 4, and 5 on the second register */
+ GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG,
+ /* GPIO 6, 7, 8, and 9 on the third register */
+ GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG,
+ /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
+ GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG,
+ GPIO_CFG4_REG, GPIO_CFG4_REG,
+ /* GPIO 16 - 23 on the first strange EXTENDED register */
+ EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
+ EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
+ EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
+ /* GPIO 24 - 27 on the second strange EXTENDED register */
+ EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
+ EXTENDED_GPIO2_REG,
+};
+
+/* Maps 'basic' pins to relative offset from 0 per register */
+static int MSP_GPIO_OFFSET[] = {
+ /* GPIO 0 and 1 on the first register */
+ 0, 0,
+ /* GPIO 2, 3, 4, and 5 on the second register */
+ 2, 2, 2, 2,
+ /* GPIO 6, 7, 8, and 9 on the third register */
+ 6, 6, 6, 6,
+ /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
+ 10, 10, 10, 10, 10, 10,
+};
+
+/* Maps MODE to allowed pin mask */
+static unsigned int MSP_GPIO_MODE_ALLOWED[] = {
+ 0xffffffff, /* Mode 0 - INPUT */
+ 0x00000, /* Mode 1 - INTERRUPT */
+ 0x00030, /* Mode 2 - UART_INPUT (GPIO 4, 5)*/
+ 0, 0, 0, 0, 0, /* Modes 3, 4, 5, 6, and 7 are reserved */
+ 0xffffffff, /* Mode 8 - OUTPUT */
+ 0x0000f, /* Mode 9 - UART_OUTPUT/
+ PERF_TIMERA (GPIO 0, 1, 2, 3) */
+ 0x00003, /* Mode a - PERF_TIMERB (GPIO 0, 1) */
+ 0x00000, /* Mode b - Not really a mode! */
+};
+
+/* -- Bit masks -- */
+
+/* This gives you the 'register relative offset gpio' number */
+#define OFFSET_GPIO_NUMBER(gpio) (gpio - MSP_GPIO_OFFSET[gpio])
+
+/* These take the 'register relative offset gpio' number */
+#define BASIC_DATA_REG_MASK(ogpio) (1 << ogpio)
+#define BASIC_MODE_REG_VALUE(mode, ogpio) \
+ (mode << BASIC_MODE_REG_SHIFT(ogpio))
+#define BASIC_MODE_REG_MASK(ogpio) \
+ BASIC_MODE_REG_VALUE(0xf, ogpio)
+#define BASIC_MODE_REG_SHIFT(ogpio) (ogpio * 4)
+#define BASIC_MODE_REG_FROM_REG(data, ogpio) \
+ ((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio))
+
+/* These take the actual GPIO number (0 through 15) */
+#define BASIC_DATA_MASK(gpio) \
+ BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
+#define BASIC_MODE_MASK(gpio) \
+ BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
+#define BASIC_MODE(mode, gpio) \
+ BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio))
+#define BASIC_MODE_SHIFT(gpio) \
+ BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio))
+#define BASIC_MODE_FROM_REG(data, gpio) \
+ BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio))
+
+/*
+ * Each extended GPIO register is 32 bits long and is responsible for up to
+ * eight GPIOs. The least significant 16 bits contain the set and clear bit
+ * pair for each of the GPIOs. The most significant 16 bits contain the
+ * disable and enable bit pair for each of the GPIOs. For example, the
+ * extended GPIO reg for GPIOs 16-23 is as follows:
+ *
+ * 31: GPIO23_DISABLE
+ * ...
+ * 19: GPIO17_DISABLE
+ * 18: GPIO17_ENABLE
+ * 17: GPIO16_DISABLE
+ * 16: GPIO16_ENABLE
+ * ...
+ * 3: GPIO17_SET
+ * 2: GPIO17_CLEAR
+ * 1: GPIO16_SET
+ * 0: GPIO16_CLEAR
+ */
+
+/* This gives the 'register relative offset gpio' number */
+#define EXTENDED_OFFSET_GPIO(gpio) (gpio < 24 ? gpio - 16 : gpio - 24)
+
+/* These take the 'register relative offset gpio' number */
+#define EXTENDED_REG_DISABLE(ogpio) (0x2 << ((ogpio * 2) + 16))
+#define EXTENDED_REG_ENABLE(ogpio) (0x1 << ((ogpio * 2) + 16))
+#define EXTENDED_REG_SET(ogpio) (0x2 << (ogpio * 2))
+#define EXTENDED_REG_CLR(ogpio) (0x1 << (ogpio * 2))
+
+/* These take the actual GPIO number (16 through 27) */
+#define EXTENDED_DISABLE(gpio) \
+ EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio))
+#define EXTENDED_ENABLE(gpio) \
+ EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio))
+#define EXTENDED_SET(gpio) \
+ EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio))
+#define EXTENDED_CLR(gpio) \
+ EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio))
+
+#define EXTENDED_FULL_MASK (0xffffffff)
+
+/* -- API inline-functions -- */
+
+/*
+ * Gets the current value of the specified pin
+ */
+static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio)
+{
+ u32 pinhi_mask = 0, pinhi_mask2 = 0;
+
+ if (gpio >= MSP_NUM_GPIOS)
+ return MSP_GPIO_NONE;
+
+ if (gpio < 16) {
+ pinhi_mask = BASIC_DATA_MASK(gpio);
+ } else {
+ /*
+ * Two cases are possible with the EXTENDED register:
+ * - In output mode (ENABLED flag set), check the CLR bit
+ * - In input mode (ENABLED flag not set), check the SET bit
+ */
+ pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio);
+ pinhi_mask2 = EXTENDED_SET(gpio);
+ }
+ if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) ||
+ (*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2))
+ return MSP_GPIO_HI;
+ else
+ return MSP_GPIO_LO;
+}
+
+/* Sets the specified pin to the specified value */
+static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio)
+{
+ if (gpio >= MSP_NUM_GPIOS)
+ return;
+
+ if (gpio < 16) {
+ if (data == MSP_GPIO_TOGGLE)
+ toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio],
+ BASIC_DATA_MASK(gpio));
+ else if (data == MSP_GPIO_HI)
+ set_reg32(MSP_GPIO_DATA_REGISTER[gpio],
+ BASIC_DATA_MASK(gpio));
+ else
+ clear_reg32(MSP_GPIO_DATA_REGISTER[gpio],
+ BASIC_DATA_MASK(gpio));
+ } else {
+ if (data == MSP_GPIO_TOGGLE) {
+ /* Special ugly case:
+ * We have to read the CLR bit.
+ * If set, we write the CLR bit.
+ * If not, we write the SET bit.
+ */
+ u32 tmpdata;
+
+ custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio],
+ tmpdata);
+ if (tmpdata & EXTENDED_CLR(gpio))
+ tmpdata = EXTENDED_CLR(gpio);
+ else
+ tmpdata = EXTENDED_SET(gpio);
+ custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio],
+ tmpdata);
+ } else {
+ u32 newdata;
+
+ if (data == MSP_GPIO_HI)
+ newdata = EXTENDED_SET(gpio);
+ else
+ newdata = EXTENDED_CLR(gpio);
+ set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio],
+ EXTENDED_FULL_MASK, newdata);
+ }
+ }
+}
+
+/* Sets the specified pin to the specified value */
+static inline void msp_gpio_pin_hi(unsigned int gpio)
+{
+ msp_gpio_pin_set(MSP_GPIO_HI, gpio);
+}
+
+/* Sets the specified pin to the specified value */
+static inline void msp_gpio_pin_lo(unsigned int gpio)
+{
+ msp_gpio_pin_set(MSP_GPIO_LO, gpio);
+}
+
+/* Sets the specified pin to the opposite value */
+static inline void msp_gpio_pin_toggle(unsigned int gpio)
+{
+ msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio);
+}
+
+/* Gets the mode of the specified pin */
+static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio)
+{
+ enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN;
+ uint32_t data;
+
+ if (gpio >= MSP_NUM_GPIOS)
+ return retval;
+
+ data = *MSP_GPIO_MODE_REGISTER[gpio];
+
+ if (gpio < 16) {
+ retval = BASIC_MODE_FROM_REG(data, gpio);
+ } else {
+ /* Extended pins can only be either INPUT or OUTPUT */
+ if (data & EXTENDED_ENABLE(gpio))
+ retval = MSP_GPIO_OUTPUT;
+ else
+ retval = MSP_GPIO_INPUT;
+ }
+
+ return retval;
+}
+
+/*
+ * Sets the specified mode on the requested pin
+ * Returns 0 on success, or -1 if that mode is not allowed on this pin
+ */
+static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio)
+{
+ u32 modemask, newmode;
+
+ if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode])
+ return -1;
+
+ if (gpio >= MSP_NUM_GPIOS)
+ return -1;
+
+ if (gpio < 16) {
+ modemask = BASIC_MODE_MASK(gpio);
+ newmode = BASIC_MODE(mode, gpio);
+ } else {
+ modemask = EXTENDED_FULL_MASK;
+ if (mode == MSP_GPIO_INPUT)
+ newmode = EXTENDED_DISABLE(gpio);
+ else
+ newmode = EXTENDED_ENABLE(gpio);
+ }
+ /* Do the set atomically */
+ set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode);
+
+ return 0;
+}
+
+#endif /* __MSP_GPIO_MACROS_H__ */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_int.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_int.h
new file mode 100644
index 00000000..1d9f0547
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_int.h
@@ -0,0 +1,43 @@
+/*
+ * Defines for the MSP interrupt handlers.
+ *
+ * Copyright (C) 2005, PMC-Sierra, Inc. All rights reserved.
+ * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+#ifndef _MSP_INT_H
+#define _MSP_INT_H
+
+/*
+ * The PMC-Sierra MSP product line has at least two different interrupt
+ * controllers, the SLP register based scheme and the CIC interrupt
+ * controller block mechanism. This file distinguishes between them
+ * so that devices see a uniform interface.
+ */
+
+#if defined(CONFIG_IRQ_MSP_SLP)
+ #include "msp_slp_int.h"
+#elif defined(CONFIG_IRQ_MSP_CIC)
+ #include "msp_cic_int.h"
+#else
+ #error "What sort of interrupt controller does *your* MSP have?"
+#endif
+
+#endif /* !_MSP_INT_H */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_pci.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_pci.h
new file mode 100644
index 00000000..41560690
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_pci.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2000-2006 PMC-Sierra INC.
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+ * 02139, USA.
+ *
+ * PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef _MSP_PCI_H_
+#define _MSP_PCI_H_
+
+#define MSP_HAS_PCI(ID) (((u32)(ID) <= 0x4236) && ((u32)(ID) >= 0x4220))
+
+/*
+ * It is convenient to program the OATRAN register so that
+ * Athena virtual address space and PCI address space are
+ * the same. This is not a requirement, just a convenience.
+ *
+ * The only hard restrictions on the value of OATRAN is that
+ * OATRAN must not be programmed to allow translated memory
+ * addresses to fall within the lowest 512MB of
+ * PCI address space. This region is hardcoded
+ * for use as Athena PCI Host Controller target
+ * access memory space to the Athena's SDRAM.
+ *
+ * Note that OATRAN applies only to memory accesses, not
+ * to I/O accesses.
+ *
+ * To program OATRAN to make Athena virtual address space
+ * and PCI address space have the same values, OATRAN
+ * is to be programmed to 0xB8000000. The top seven
+ * bits of the value mimic the seven bits clipped off
+ * by the PCI Host controller.
+ *
+ * With OATRAN at the said value, when the CPU does
+ * an access to its virtual address at, say 0xB900_5000,
+ * the address appearing on the PCI bus will be
+ * 0xB900_5000.
+ * - Michael Penner
+ */
+#define MSP_PCI_OATRAN 0xB8000000UL
+
+#define MSP_PCI_SPACE_BASE (MSP_PCI_OATRAN + 0x1002000UL)
+#define MSP_PCI_SPACE_SIZE (0x3000000UL - 0x2000)
+#define MSP_PCI_SPACE_END \
+ (MSP_PCI_SPACE_BASE + MSP_PCI_SPACE_SIZE - 1)
+#define MSP_PCI_IOSPACE_BASE (MSP_PCI_OATRAN + 0x1001000UL)
+#define MSP_PCI_IOSPACE_SIZE 0x1000
+#define MSP_PCI_IOSPACE_END \
+ (MSP_PCI_IOSPACE_BASE + MSP_PCI_IOSPACE_SIZE - 1)
+
+/* IRQ for PCI status interrupts */
+#define PCI_STAT_IRQ 20
+
+#define QFLUSH_REG_1 0xB7F40000
+
+typedef volatile unsigned int pcireg;
+typedef void * volatile ppcireg;
+
+struct pci_block_copy
+{
+ pcireg unused1; /* +0x00 */
+ pcireg unused2; /* +0x04 */
+ ppcireg unused3; /* +0x08 */
+ ppcireg unused4; /* +0x0C */
+ pcireg unused5; /* +0x10 */
+ pcireg unused6; /* +0x14 */
+ pcireg unused7; /* +0x18 */
+ ppcireg unused8; /* +0x1C */
+ ppcireg unused9; /* +0x20 */
+ pcireg unusedA; /* +0x24 */
+ ppcireg unusedB; /* +0x28 */
+ ppcireg unusedC; /* +0x2C */
+};
+
+enum
+{
+ config_device_vendor, /* 0 */
+ config_status_command, /* 1 */
+ config_class_revision, /* 2 */
+ config_BIST_header_latency_cache, /* 3 */
+ config_BAR0, /* 4 */
+ config_BAR1, /* 5 */
+ config_BAR2, /* 6 */
+ config_not_used7, /* 7 */
+ config_not_used8, /* 8 */
+ config_not_used9, /* 9 */
+ config_CIS, /* 10 */
+ config_subsystem, /* 11 */
+ config_not_used12, /* 12 */
+ config_capabilities, /* 13 */
+ config_not_used14, /* 14 */
+ config_lat_grant_irq, /* 15 */
+ config_message_control,/* 16 */
+ config_message_addr, /* 17 */
+ config_message_data, /* 18 */
+ config_VPD_addr, /* 19 */
+ config_VPD_data, /* 20 */
+ config_maxregs /* 21 - number of registers */
+};
+
+struct msp_pci_regs
+{
+ pcireg hop_unused_00; /* +0x00 */
+ pcireg hop_unused_04; /* +0x04 */
+ pcireg hop_unused_08; /* +0x08 */
+ pcireg hop_unused_0C; /* +0x0C */
+ pcireg hop_unused_10; /* +0x10 */
+ pcireg hop_unused_14; /* +0x14 */
+ pcireg hop_unused_18; /* +0x18 */
+ pcireg hop_unused_1C; /* +0x1C */
+ pcireg hop_unused_20; /* +0x20 */
+ pcireg hop_unused_24; /* +0x24 */
+ pcireg hop_unused_28; /* +0x28 */
+ pcireg hop_unused_2C; /* +0x2C */
+ pcireg hop_unused_30; /* +0x30 */
+ pcireg hop_unused_34; /* +0x34 */
+ pcireg if_control; /* +0x38 */
+ pcireg oatran; /* +0x3C */
+ pcireg reset_ctl; /* +0x40 */
+ pcireg config_addr; /* +0x44 */
+ pcireg hop_unused_48; /* +0x48 */
+ pcireg msg_signaled_int_status; /* +0x4C */
+ pcireg msg_signaled_int_mask; /* +0x50 */
+ pcireg if_status; /* +0x54 */
+ pcireg if_mask; /* +0x58 */
+ pcireg hop_unused_5C; /* +0x5C */
+ pcireg hop_unused_60; /* +0x60 */
+ pcireg hop_unused_64; /* +0x64 */
+ pcireg hop_unused_68; /* +0x68 */
+ pcireg hop_unused_6C; /* +0x6C */
+ pcireg hop_unused_70; /* +0x70 */
+
+ struct pci_block_copy pci_bc[2] __attribute__((aligned(64)));
+
+ pcireg error_hdr1; /* +0xE0 */
+ pcireg error_hdr2; /* +0xE4 */
+
+ pcireg config[config_maxregs] __attribute__((aligned(256)));
+
+};
+
+#define BPCI_CFGADDR_BUSNUM_SHF 16
+#define BPCI_CFGADDR_FUNCTNUM_SHF 8
+#define BPCI_CFGADDR_REGNUM_SHF 2
+#define BPCI_CFGADDR_ENABLE (1<<31)
+
+#define BPCI_IFCONTROL_RTO (1<<20) /* Retry timeout */
+#define BPCI_IFCONTROL_HCE (1<<16) /* Host configuration enable */
+#define BPCI_IFCONTROL_CTO_SHF 12 /* Shift count for CTO bits */
+#define BPCI_IFCONTROL_SE (1<<5) /* Enable exceptions on errors */
+#define BPCI_IFCONTROL_BIST (1<<4) /* Use BIST in per. mode */
+#define BPCI_IFCONTROL_CAP (1<<3) /* Enable capabilities */
+#define BPCI_IFCONTROL_MMC_SHF 0 /* Shift count for MMC bits */
+
+#define BPCI_IFSTATUS_MGT (1<<8) /* Master Grant timeout */
+#define BPCI_IFSTATUS_MTT (1<<9) /* Master TRDY timeout */
+#define BPCI_IFSTATUS_MRT (1<<10) /* Master retry timeout */
+#define BPCI_IFSTATUS_BC0F (1<<13) /* Block copy 0 fault */
+#define BPCI_IFSTATUS_BC1F (1<<14) /* Block copy 1 fault */
+#define BPCI_IFSTATUS_PCIU (1<<15) /* PCI unable to respond */
+#define BPCI_IFSTATUS_BSIZ (1<<16) /* PCI access with illegal size */
+#define BPCI_IFSTATUS_BADD (1<<17) /* PCI access with illegal addr */
+#define BPCI_IFSTATUS_RTO (1<<18) /* Retry time out */
+#define BPCI_IFSTATUS_SER (1<<19) /* System error */
+#define BPCI_IFSTATUS_PER (1<<20) /* Parity error */
+#define BPCI_IFSTATUS_LCA (1<<21) /* Local CPU abort */
+#define BPCI_IFSTATUS_MEM (1<<22) /* Memory prot. violation */
+#define BPCI_IFSTATUS_ARB (1<<23) /* Arbiter timed out */
+#define BPCI_IFSTATUS_STA (1<<27) /* Signaled target abort */
+#define BPCI_IFSTATUS_TA (1<<28) /* Target abort */
+#define BPCI_IFSTATUS_MA (1<<29) /* Master abort */
+#define BPCI_IFSTATUS_PEI (1<<30) /* Parity error as initiator */
+#define BPCI_IFSTATUS_PET (1<<31) /* Parity error as target */
+
+#define BPCI_RESETCTL_PR (1<<0) /* True if reset asserted */
+#define BPCI_RESETCTL_RT (1<<4) /* Release time */
+#define BPCI_RESETCTL_CT (1<<8) /* Config time */
+#define BPCI_RESETCTL_PE (1<<12) /* PCI enabled */
+#define BPCI_RESETCTL_HM (1<<13) /* PCI host mode */
+#define BPCI_RESETCTL_RI (1<<14) /* PCI reset in */
+
+extern struct msp_pci_regs msp_pci_regs
+ __attribute__((section(".register")));
+extern unsigned long msp_pci_config_space
+ __attribute__((section(".register")));
+
+#endif /* !_MSP_PCI_H_ */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
new file mode 100644
index 00000000..786d82da
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
@@ -0,0 +1,171 @@
+/*
+ * MIPS boards bootprom interface for the Linux kernel.
+ *
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ * Author: Carsten Langgaard, carstenl@mips.com
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+#ifndef _ASM_MSP_PROM_H
+#define _ASM_MSP_PROM_H
+
+#include <linux/types.h>
+
+#define DEVICEID "deviceid"
+#define FEATURES "features"
+#define PROM_ENV "prom_env"
+#define PROM_ENV_FILE "/proc/"PROM_ENV
+#define PROM_ENV_SIZE 256
+
+#define CPU_DEVID_FAMILY 0x0000ff00
+#define CPU_DEVID_REVISION 0x000000ff
+
+#define FPGA_IS_POLO(revision) \
+ (((revision >= 0xb0) && (revision < 0xd0)))
+#define FPGA_IS_5000(revision) \
+ ((revision >= 0x80) && (revision <= 0x90))
+#define FPGA_IS_ZEUS(revision) ((revision < 0x7f))
+#define FPGA_IS_DUET(revision) \
+ (((revision >= 0xa0) && (revision < 0xb0)))
+#define FPGA_IS_MSP4200(revision) ((revision >= 0xd0))
+#define FPGA_IS_MSP7100(revision) ((revision >= 0xd0))
+
+#define MACHINE_TYPE_POLO "POLO"
+#define MACHINE_TYPE_DUET "DUET"
+#define MACHINE_TYPE_ZEUS "ZEUS"
+#define MACHINE_TYPE_MSP2000REVB "MSP2000REVB"
+#define MACHINE_TYPE_MSP5000 "MSP5000"
+#define MACHINE_TYPE_MSP4200 "MSP4200"
+#define MACHINE_TYPE_MSP7120 "MSP7120"
+#define MACHINE_TYPE_MSP7130 "MSP7130"
+#define MACHINE_TYPE_OTHER "OTHER"
+
+#define MACHINE_TYPE_POLO_FPGA "POLO-FPGA"
+#define MACHINE_TYPE_DUET_FPGA "DUET-FPGA"
+#define MACHINE_TYPE_ZEUS_FPGA "ZEUS_FPGA"
+#define MACHINE_TYPE_MSP2000REVB_FPGA "MSP2000REVB-FPGA"
+#define MACHINE_TYPE_MSP5000_FPGA "MSP5000-FPGA"
+#define MACHINE_TYPE_MSP4200_FPGA "MSP4200-FPGA"
+#define MACHINE_TYPE_MSP7100_FPGA "MSP7100-FPGA"
+#define MACHINE_TYPE_OTHER_FPGA "OTHER-FPGA"
+
+/* Device Family definitions */
+#define FAMILY_FPGA 0x0000
+#define FAMILY_ZEUS 0x1000
+#define FAMILY_POLO 0x2000
+#define FAMILY_DUET 0x4000
+#define FAMILY_TRIAD 0x5000
+#define FAMILY_MSP4200 0x4200
+#define FAMILY_MSP4200_FPGA 0x4f00
+#define FAMILY_MSP7100 0x7100
+#define FAMILY_MSP7100_FPGA 0x7f00
+
+/* Device Type definitions */
+#define TYPE_MSP7120 0x7120
+#define TYPE_MSP7130 0x7130
+
+#define ENET_KEY 'E'
+#define ENETTXD_KEY 'e'
+#define PCI_KEY 'P'
+#define PCIMUX_KEY 'p'
+#define SEC_KEY 'S'
+#define SPAD_KEY 'D'
+#define TDM_KEY 'T'
+#define ZSP_KEY 'Z'
+
+#define FEATURE_NOEXIST '-'
+#define FEATURE_EXIST '+'
+
+#define ENET_MII 'M'
+#define ENET_RMII 'R'
+
+#define ENETTXD_FALLING 'F'
+#define ENETTXD_RISING 'R'
+
+#define PCI_HOST 'H'
+#define PCI_PERIPHERAL 'P'
+
+#define PCIMUX_FULL 'F'
+#define PCIMUX_SINGLE 'S'
+
+#define SEC_DUET 'D'
+#define SEC_POLO 'P'
+#define SEC_SLOW 'S'
+#define SEC_TRIAD 'T'
+
+#define SPAD_POLO 'P'
+
+#define TDM_DUET 'D' /* DUET TDMs might exist */
+#define TDM_POLO 'P' /* POLO TDMs might exist */
+#define TDM_TRIAD 'T' /* TRIAD TDMs might exist */
+
+#define ZSP_DUET 'D' /* one DUET zsp engine */
+#define ZSP_TRIAD 'T' /* two TRIAD zsp engines */
+
+extern char *prom_getenv(char *name);
+extern void prom_init_cmdline(void);
+extern void prom_meminit(void);
+extern void prom_fixup_mem_map(unsigned long start_mem,
+ unsigned long end_mem);
+
+extern int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr);
+extern unsigned long get_deviceid(void);
+extern char identify_enet(unsigned long interface_num);
+extern char identify_enetTxD(unsigned long interface_num);
+extern char identify_pci(void);
+extern char identify_sec(void);
+extern char identify_spad(void);
+extern char identify_sec(void);
+extern char identify_tdm(void);
+extern char identify_zsp(void);
+extern unsigned long identify_family(void);
+extern unsigned long identify_revision(void);
+
+/*
+ * The following macro calls prom_printf and puts the format string
+ * into an init section so it can be reclaimed.
+ */
+#define ppfinit(f, x...) \
+ do { \
+ static char _f[] __initdata = KERN_INFO f; \
+ printk(_f, ## x); \
+ } while (0)
+
+/* Memory descriptor management. */
+#define PROM_MAX_PMEMBLOCKS 7 /* 6 used */
+
+enum yamon_memtypes {
+ yamon_dontuse,
+ yamon_prom,
+ yamon_free,
+};
+
+struct prom_pmemblock {
+ unsigned long base; /* Within KSEG0. */
+ unsigned int size; /* In bytes. */
+ unsigned int type; /* free or prom memory */
+};
+
+extern int prom_argc;
+extern char **prom_argv;
+extern char **prom_envp;
+extern int *prom_vec;
+extern struct prom_pmemblock *prom_getmdesc(void);
+
+#endif /* !_ASM_MSP_PROM_H */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h
new file mode 100644
index 00000000..7d41474e
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regops.h
@@ -0,0 +1,236 @@
+/*
+ * SMP/VPE-safe functions to access "registers" (see note).
+ *
+ * NOTES:
+* - These macros use ll/sc instructions, so it is your responsibility to
+ * ensure these are available on your platform before including this file.
+ * - The MIPS32 spec states that ll/sc results are undefined for uncached
+ * accesses. This means they can't be used on HW registers accessed
+ * through kseg1. Code which requires these macros for this purpose must
+ * front-end the registers with cached memory "registers" and have a single
+ * thread update the actual HW registers.
+ * - A maximum of 2k of code can be inserted between ll and sc. Every
+ * memory accesses between the instructions will increase the chance of
+ * sc failing and having to loop.
+ * - When using custom_read_reg32/custom_write_reg32 only perform the
+ * necessary logical operations on the register value in between these
+ * two calls. All other logic should be performed before the first call.
+ * - There is a bug on the R10000 chips which has a workaround. If you
+ * are affected by this bug, make sure to define the symbol 'R10000_LLSC_WAR'
+ * to be non-zero. If you are using this header from within linux, you may
+ * include <asm/war.h> before including this file to have this defined
+ * appropriately for you.
+ *
+ * Copyright 2005-2007 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_REGOPS_H__
+#define __ASM_REGOPS_H__
+
+#include <linux/types.h>
+
+#include <asm/war.h>
+
+#ifndef R10000_LLSC_WAR
+#define R10000_LLSC_WAR 0
+#endif
+
+#if R10000_LLSC_WAR == 1
+#define __beqz "beqzl "
+#else
+#define __beqz "beqz "
+#endif
+
+#ifndef _LINUX_TYPES_H
+typedef unsigned int u32;
+#endif
+
+/*
+ * Sets all the masked bits to the corresponding value bits
+ */
+static inline void set_value_reg32(volatile u32 *const addr,
+ u32 const mask,
+ u32 const value)
+{
+ u32 temp;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips3 \n"
+ "1: ll %0, %1 # set_value_reg32 \n"
+ " and %0, %2 \n"
+ " or %0, %3 \n"
+ " sc %0, %1 \n"
+ " "__beqz"%0, 1b \n"
+ " nop \n"
+ " .set pop \n"
+ : "=&r" (temp), "=m" (*addr)
+ : "ir" (~mask), "ir" (value), "m" (*addr));
+}
+
+/*
+ * Sets all the masked bits to '1'
+ */
+static inline void set_reg32(volatile u32 *const addr,
+ u32 const mask)
+{
+ u32 temp;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips3 \n"
+ "1: ll %0, %1 # set_reg32 \n"
+ " or %0, %2 \n"
+ " sc %0, %1 \n"
+ " "__beqz"%0, 1b \n"
+ " nop \n"
+ " .set pop \n"
+ : "=&r" (temp), "=m" (*addr)
+ : "ir" (mask), "m" (*addr));
+}
+
+/*
+ * Sets all the masked bits to '0'
+ */
+static inline void clear_reg32(volatile u32 *const addr,
+ u32 const mask)
+{
+ u32 temp;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips3 \n"
+ "1: ll %0, %1 # clear_reg32 \n"
+ " and %0, %2 \n"
+ " sc %0, %1 \n"
+ " "__beqz"%0, 1b \n"
+ " nop \n"
+ " .set pop \n"
+ : "=&r" (temp), "=m" (*addr)
+ : "ir" (~mask), "m" (*addr));
+}
+
+/*
+ * Toggles all masked bits from '0' to '1' and '1' to '0'
+ */
+static inline void toggle_reg32(volatile u32 *const addr,
+ u32 const mask)
+{
+ u32 temp;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips3 \n"
+ "1: ll %0, %1 # toggle_reg32 \n"
+ " xor %0, %2 \n"
+ " sc %0, %1 \n"
+ " "__beqz"%0, 1b \n"
+ " nop \n"
+ " .set pop \n"
+ : "=&r" (temp), "=m" (*addr)
+ : "ir" (mask), "m" (*addr));
+}
+
+/*
+ * Read all masked bits others are returned as '0'
+ */
+static inline u32 read_reg32(volatile u32 *const addr,
+ u32 const mask)
+{
+ u32 temp;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " lw %0, %1 # read \n"
+ " and %0, %2 # mask \n"
+ " .set pop \n"
+ : "=&r" (temp)
+ : "m" (*addr), "ir" (mask));
+
+ return temp;
+}
+
+/*
+ * blocking_read_reg32 - Read address with blocking load
+ *
+ * Uncached writes need to be read back to ensure they reach RAM.
+ * The returned value must be 'used' to prevent from becoming a
+ * non-blocking load.
+ */
+static inline u32 blocking_read_reg32(volatile u32 *const addr)
+{
+ u32 temp;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set noreorder \n"
+ " lw %0, %1 # read \n"
+ " move %0, %0 # block \n"
+ " .set pop \n"
+ : "=&r" (temp)
+ : "m" (*addr));
+
+ return temp;
+}
+
+/*
+ * For special strange cases only:
+ *
+ * If you need custom processing within a ll/sc loop, use the following macros
+ * VERY CAREFULLY:
+ *
+ * u32 tmp; <-- Define a variable to hold the data
+ *
+ * custom_read_reg32(address, tmp); <-- Reads the address and put the value
+ * in the 'tmp' variable given
+ *
+ * From here on out, you are (basically) atomic, so don't do anything too
+ * fancy!
+ * Also, this code may loop if the end of this block fails to write
+ * everything back safely due do the other CPU, so do NOT do anything
+ * with side-effects!
+ *
+ * custom_write_reg32(address, tmp); <-- Writes back 'tmp' safely.
+ */
+#define custom_read_reg32(address, tmp) \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips3 \n" \
+ "1: ll %0, %1 #custom_read_reg32 \n" \
+ " .set pop \n" \
+ : "=r" (tmp), "=m" (*address) \
+ : "m" (*address))
+
+#define custom_write_reg32(address, tmp) \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set mips3 \n" \
+ " sc %0, %1 #custom_write_reg32 \n" \
+ " "__beqz"%0, 1b \n" \
+ " nop \n" \
+ " .set pop \n" \
+ : "=&r" (tmp), "=m" (*address) \
+ : "0" (tmp), "m" (*address))
+
+#endif /* __ASM_REGOPS_H__ */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h
new file mode 100644
index 00000000..692c1b65
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_regs.h
@@ -0,0 +1,664 @@
+/*
+ * Defines for the address space, registers and register configuration
+ * (bit masks, access macros etc) for the PMC-Sierra line of MSP products.
+ * This file contains addess maps for all the devices in the line of
+ * products but only has register definitions and configuration masks for
+ * registers which aren't definitely associated with any device. Things
+ * like clock settings, reset access, the ELB etc. Individual device
+ * drivers will reference the appropriate XXX_BASE value defined here
+ * and have individual registers offset from that.
+ *
+ * Copyright (C) 2005-2007 PMC-Sierra, Inc. All rights reserved.
+ * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+#include <asm/addrspace.h>
+#include <linux/types.h>
+
+#ifndef _ASM_MSP_REGS_H
+#define _ASM_MSP_REGS_H
+
+/*
+ ########################################################################
+ # Address space and device base definitions #
+ ########################################################################
+ */
+
+/*
+ ***************************************************************************
+ * System Logic and Peripherals (ELB, UART0, etc) device address space *
+ ***************************************************************************
+ */
+#define MSP_SLP_BASE 0x1c000000
+ /* System Logic and Peripherals */
+#define MSP_RST_BASE (MSP_SLP_BASE + 0x10)
+ /* System reset register base */
+#define MSP_RST_SIZE 0x0C /* System reset register space */
+
+#define MSP_WTIMER_BASE (MSP_SLP_BASE + 0x04C)
+ /* watchdog timer base */
+#define MSP_ITIMER_BASE (MSP_SLP_BASE + 0x054)
+ /* internal timer base */
+#define MSP_UART0_BASE (MSP_SLP_BASE + 0x100)
+ /* UART0 controller base */
+#define MSP_BCPY_CTRL_BASE (MSP_SLP_BASE + 0x120)
+ /* Block Copy controller base */
+#define MSP_BCPY_DESC_BASE (MSP_SLP_BASE + 0x160)
+ /* Block Copy descriptor base */
+
+/*
+ ***************************************************************************
+ * PCI address space *
+ ***************************************************************************
+ */
+#define MSP_PCI_BASE 0x19000000
+
+/*
+ ***************************************************************************
+ * MSbus device address space *
+ ***************************************************************************
+ */
+#define MSP_MSB_BASE 0x18000000
+ /* MSbus address start */
+#define MSP_PER_BASE (MSP_MSB_BASE + 0x400000)
+ /* Peripheral device registers */
+#define MSP_MAC0_BASE (MSP_MSB_BASE + 0x600000)
+ /* MAC A device registers */
+#define MSP_MAC1_BASE (MSP_MSB_BASE + 0x700000)
+ /* MAC B device registers */
+#define MSP_MAC_SIZE 0xE0 /* MAC register space */
+
+#define MSP_SEC_BASE (MSP_MSB_BASE + 0x800000)
+ /* Security Engine registers */
+#define MSP_MAC2_BASE (MSP_MSB_BASE + 0x900000)
+ /* MAC C device registers */
+#define MSP_ADSL2_BASE (MSP_MSB_BASE + 0xA80000)
+ /* ADSL2 device registers */
+#define MSP_USB0_BASE (MSP_MSB_BASE + 0xB00000)
+ /* USB0 device registers */
+#define MSP_USB1_BASE (MSP_MSB_BASE + 0x300000)
+ /* USB1 device registers */
+#define MSP_CPUIF_BASE (MSP_MSB_BASE + 0xC00000)
+ /* CPU interface registers */
+
+/* Devices within the MSbus peripheral block */
+#define MSP_UART1_BASE (MSP_PER_BASE + 0x030)
+ /* UART1 controller base */
+#define MSP_SPI_BASE (MSP_PER_BASE + 0x058)
+ /* SPI/MPI control registers */
+#define MSP_TWI_BASE (MSP_PER_BASE + 0x090)
+ /* Two-wire control registers */
+#define MSP_PTIMER_BASE (MSP_PER_BASE + 0x0F0)
+ /* Programmable timer control */
+
+/*
+ ***************************************************************************
+ * Physical Memory configuration address space *
+ ***************************************************************************
+ */
+#define MSP_MEM_CFG_BASE 0x17f00000
+
+#define MSP_MEM_INDIRECT_CTL_10 0x10
+
+/*
+ * Notes:
+ * 1) The SPI registers are split into two blocks, one offset from the
+ * MSP_SPI_BASE by 0x00 and the other offset from the MSP_SPI_BASE by
+ * 0x68. The SPI driver definitions for the register must be aware
+ * of this.
+ * 2) The block copy engine register are divided into two regions, one
+ * for the control/configuration of the engine proper and one for the
+ * values of the descriptors used in the copy process. These have
+ * different base defines (CTRL_BASE vs DESC_BASE)
+ * 3) These constants are for physical addresses which means that they
+ * work correctly with "ioremap" and friends. This means that device
+ * drivers will need to remap these addresses using ioremap and perhaps
+ * the readw/writew macros. Or they could use the regptr() macro
+ * defined below, but the readw/writew calls are the correct thing.
+ * 4) The UARTs have an additional status register offset from the base
+ * address. This register isn't used in the standard 8250 driver but
+ * may be used in other software. Consult the hardware datasheet for
+ * offset details.
+ * 5) For some unknown reason the security engine (MSP_SEC_BASE) registers
+ * start at an offset of 0x84 from the base address but the block of
+ * registers before this is reserved for the security engine. The
+ * driver will have to be aware of this but it makes the register
+ * definitions line up better with the documentation.
+ */
+
+/*
+ ########################################################################
+ # System register definitions. Not associated with a specific device #
+ ########################################################################
+ */
+
+/*
+ * This macro maps the physical register number into uncached space
+ * and (for C code) casts it into a u32 pointer so it can be dereferenced
+ * Normally these would be accessed with ioremap and readX/writeX, but
+ * these are convenient for a lot of internal kernel code.
+ */
+#ifdef __ASSEMBLER__
+ #define regptr(addr) (KSEG1ADDR(addr))
+#else
+ #define regptr(addr) ((volatile u32 *const)(KSEG1ADDR(addr)))
+#endif
+
+/*
+ ***************************************************************************
+ * System Logic and Peripherals (RESET, ELB, etc) registers *
+ ***************************************************************************
+ */
+
+/* System Control register definitions */
+#define DEV_ID_REG regptr(MSP_SLP_BASE + 0x00)
+ /* Device-ID RO */
+#define FWR_ID_REG regptr(MSP_SLP_BASE + 0x04)
+ /* Firmware-ID Register RW */
+#define SYS_ID_REG0 regptr(MSP_SLP_BASE + 0x08)
+ /* System-ID Register-0 RW */
+#define SYS_ID_REG1 regptr(MSP_SLP_BASE + 0x0C)
+ /* System-ID Register-1 RW */
+
+/* System Reset register definitions */
+#define RST_STS_REG regptr(MSP_SLP_BASE + 0x10)
+ /* System Reset Status RO */
+#define RST_SET_REG regptr(MSP_SLP_BASE + 0x14)
+ /* System Set Reset WO */
+#define RST_CLR_REG regptr(MSP_SLP_BASE + 0x18)
+ /* System Clear Reset WO */
+
+/* System Clock Registers */
+#define PCI_SLP_REG regptr(MSP_SLP_BASE + 0x1C)
+ /* PCI clock generator RW */
+#define URT_SLP_REG regptr(MSP_SLP_BASE + 0x20)
+ /* UART clock generator RW */
+/* reserved (MSP_SLP_BASE + 0x24) */
+/* reserved (MSP_SLP_BASE + 0x28) */
+#define PLL1_SLP_REG regptr(MSP_SLP_BASE + 0x2C)
+ /* PLL1 clock generator RW */
+#define PLL0_SLP_REG regptr(MSP_SLP_BASE + 0x30)
+ /* PLL0 clock generator RW */
+#define MIPS_SLP_REG regptr(MSP_SLP_BASE + 0x34)
+ /* MIPS clock generator RW */
+#define VE_SLP_REG regptr(MSP_SLP_BASE + 0x38)
+ /* Voice Eng clock generator RW */
+/* reserved (MSP_SLP_BASE + 0x3C) */
+#define MSB_SLP_REG regptr(MSP_SLP_BASE + 0x40)
+ /* MS-Bus clock generator RW */
+#define SMAC_SLP_REG regptr(MSP_SLP_BASE + 0x44)
+ /* Sec & MAC clock generator RW */
+#define PERF_SLP_REG regptr(MSP_SLP_BASE + 0x48)
+ /* Per & TDM clock generator RW */
+
+/* Interrupt Controller Registers */
+#define SLP_INT_STS_REG regptr(MSP_SLP_BASE + 0x70)
+ /* Interrupt status register RW */
+#define SLP_INT_MSK_REG regptr(MSP_SLP_BASE + 0x74)
+ /* Interrupt enable/mask RW */
+#define SE_MBOX_REG regptr(MSP_SLP_BASE + 0x78)
+ /* Security Engine mailbox RW */
+#define VE_MBOX_REG regptr(MSP_SLP_BASE + 0x7C)
+ /* Voice Engine mailbox RW */
+
+/* ELB Controller Registers */
+#define CS0_CNFG_REG regptr(MSP_SLP_BASE + 0x80)
+ /* ELB CS0 Configuration Reg */
+#define CS0_ADDR_REG regptr(MSP_SLP_BASE + 0x84)
+ /* ELB CS0 Base Address Reg */
+#define CS0_MASK_REG regptr(MSP_SLP_BASE + 0x88)
+ /* ELB CS0 Mask Register */
+#define CS0_ACCESS_REG regptr(MSP_SLP_BASE + 0x8C)
+ /* ELB CS0 access register */
+
+#define CS1_CNFG_REG regptr(MSP_SLP_BASE + 0x90)
+ /* ELB CS1 Configuration Reg */
+#define CS1_ADDR_REG regptr(MSP_SLP_BASE + 0x94)
+ /* ELB CS1 Base Address Reg */
+#define CS1_MASK_REG regptr(MSP_SLP_BASE + 0x98)
+ /* ELB CS1 Mask Register */
+#define CS1_ACCESS_REG regptr(MSP_SLP_BASE + 0x9C)
+ /* ELB CS1 access register */
+
+#define CS2_CNFG_REG regptr(MSP_SLP_BASE + 0xA0)
+ /* ELB CS2 Configuration Reg */
+#define CS2_ADDR_REG regptr(MSP_SLP_BASE + 0xA4)
+ /* ELB CS2 Base Address Reg */
+#define CS2_MASK_REG regptr(MSP_SLP_BASE + 0xA8)
+ /* ELB CS2 Mask Register */
+#define CS2_ACCESS_REG regptr(MSP_SLP_BASE + 0xAC)
+ /* ELB CS2 access register */
+
+#define CS3_CNFG_REG regptr(MSP_SLP_BASE + 0xB0)
+ /* ELB CS3 Configuration Reg */
+#define CS3_ADDR_REG regptr(MSP_SLP_BASE + 0xB4)
+ /* ELB CS3 Base Address Reg */
+#define CS3_MASK_REG regptr(MSP_SLP_BASE + 0xB8)
+ /* ELB CS3 Mask Register */
+#define CS3_ACCESS_REG regptr(MSP_SLP_BASE + 0xBC)
+ /* ELB CS3 access register */
+
+#define CS4_CNFG_REG regptr(MSP_SLP_BASE + 0xC0)
+ /* ELB CS4 Configuration Reg */
+#define CS4_ADDR_REG regptr(MSP_SLP_BASE + 0xC4)
+ /* ELB CS4 Base Address Reg */
+#define CS4_MASK_REG regptr(MSP_SLP_BASE + 0xC8)
+ /* ELB CS4 Mask Register */
+#define CS4_ACCESS_REG regptr(MSP_SLP_BASE + 0xCC)
+ /* ELB CS4 access register */
+
+#define CS5_CNFG_REG regptr(MSP_SLP_BASE + 0xD0)
+ /* ELB CS5 Configuration Reg */
+#define CS5_ADDR_REG regptr(MSP_SLP_BASE + 0xD4)
+ /* ELB CS5 Base Address Reg */
+#define CS5_MASK_REG regptr(MSP_SLP_BASE + 0xD8)
+ /* ELB CS5 Mask Register */
+#define CS5_ACCESS_REG regptr(MSP_SLP_BASE + 0xDC)
+ /* ELB CS5 access register */
+
+/* reserved 0xE0 - 0xE8 */
+#define ELB_1PC_EN_REG regptr(MSP_SLP_BASE + 0xEC)
+ /* ELB single PC card detect */
+
+/* reserved 0xF0 - 0xF8 */
+#define ELB_CLK_CFG_REG regptr(MSP_SLP_BASE + 0xFC)
+ /* SDRAM read/ELB timing Reg */
+
+/* Extended UART status registers */
+#define UART0_STATUS_REG regptr(MSP_UART0_BASE + 0x0c0)
+ /* UART Status Register 0 */
+#define UART1_STATUS_REG regptr(MSP_UART1_BASE + 0x170)
+ /* UART Status Register 1 */
+
+/* Performance monitoring registers */
+#define PERF_MON_CTRL_REG regptr(MSP_SLP_BASE + 0x140)
+ /* Performance monitor control */
+#define PERF_MON_CLR_REG regptr(MSP_SLP_BASE + 0x144)
+ /* Performance monitor clear */
+#define PERF_MON_CNTH_REG regptr(MSP_SLP_BASE + 0x148)
+ /* Perf monitor counter high */
+#define PERF_MON_CNTL_REG regptr(MSP_SLP_BASE + 0x14C)
+ /* Perf monitor counter low */
+
+/* System control registers */
+#define SYS_CTRL_REG regptr(MSP_SLP_BASE + 0x150)
+ /* System control register */
+#define SYS_ERR1_REG regptr(MSP_SLP_BASE + 0x154)
+ /* System Error status 1 */
+#define SYS_ERR2_REG regptr(MSP_SLP_BASE + 0x158)
+ /* System Error status 2 */
+#define SYS_INT_CFG_REG regptr(MSP_SLP_BASE + 0x15C)
+ /* System Interrupt config */
+
+/* Voice Engine Memory configuration */
+#define VE_MEM_REG regptr(MSP_SLP_BASE + 0x17C)
+ /* Voice engine memory config */
+
+/* CPU/SLP Error Status registers */
+#define CPU_ERR1_REG regptr(MSP_SLP_BASE + 0x180)
+ /* CPU/SLP Error status 1 */
+#define CPU_ERR2_REG regptr(MSP_SLP_BASE + 0x184)
+ /* CPU/SLP Error status 1 */
+
+/* Extended GPIO registers */
+#define EXTENDED_GPIO1_REG regptr(MSP_SLP_BASE + 0x188)
+#define EXTENDED_GPIO2_REG regptr(MSP_SLP_BASE + 0x18c)
+#define EXTENDED_GPIO_REG EXTENDED_GPIO1_REG
+ /* Backward-compatibility */
+
+/* System Error registers */
+#define SLP_ERR_STS_REG regptr(MSP_SLP_BASE + 0x190)
+ /* Int status for SLP errors */
+#define SLP_ERR_MSK_REG regptr(MSP_SLP_BASE + 0x194)
+ /* Int mask for SLP errors */
+#define SLP_ELB_ERST_REG regptr(MSP_SLP_BASE + 0x198)
+ /* External ELB reset */
+#define SLP_BOOT_STS_REG regptr(MSP_SLP_BASE + 0x19C)
+ /* Boot Status */
+
+/* Extended ELB addressing */
+#define CS0_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A0)
+ /* CS0 Extended address */
+#define CS1_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A4)
+ /* CS1 Extended address */
+#define CS2_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1A8)
+ /* CS2 Extended address */
+#define CS3_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1AC)
+ /* CS3 Extended address */
+/* reserved 0x1B0 */
+#define CS5_EXT_ADDR_REG regptr(MSP_SLP_BASE + 0x1B4)
+ /* CS5 Extended address */
+
+/* PLL Adjustment registers */
+#define PLL_LOCK_REG regptr(MSP_SLP_BASE + 0x200)
+ /* PLL0 lock status */
+#define PLL_ARST_REG regptr(MSP_SLP_BASE + 0x204)
+ /* PLL Analog reset status */
+#define PLL0_ADJ_REG regptr(MSP_SLP_BASE + 0x208)
+ /* PLL0 Adjustment value */
+#define PLL1_ADJ_REG regptr(MSP_SLP_BASE + 0x20C)
+ /* PLL1 Adjustment value */
+
+/*
+ ***************************************************************************
+ * Peripheral Register definitions *
+ ***************************************************************************
+ */
+
+/* Peripheral status */
+#define PER_CTRL_REG regptr(MSP_PER_BASE + 0x50)
+ /* Peripheral control register */
+#define PER_STS_REG regptr(MSP_PER_BASE + 0x54)
+ /* Peripheral status register */
+
+/* SPI/MPI Registers */
+#define SMPI_TX_SZ_REG regptr(MSP_PER_BASE + 0x58)
+ /* SPI/MPI Tx Size register */
+#define SMPI_RX_SZ_REG regptr(MSP_PER_BASE + 0x5C)
+ /* SPI/MPI Rx Size register */
+#define SMPI_CTL_REG regptr(MSP_PER_BASE + 0x60)
+ /* SPI/MPI Control register */
+#define SMPI_MS_REG regptr(MSP_PER_BASE + 0x64)
+ /* SPI/MPI Chip Select reg */
+#define SMPI_CORE_DATA_REG regptr(MSP_PER_BASE + 0xC0)
+ /* SPI/MPI Core Data reg */
+#define SMPI_CORE_CTRL_REG regptr(MSP_PER_BASE + 0xC4)
+ /* SPI/MPI Core Control reg */
+#define SMPI_CORE_STAT_REG regptr(MSP_PER_BASE + 0xC8)
+ /* SPI/MPI Core Status reg */
+#define SMPI_CORE_SSEL_REG regptr(MSP_PER_BASE + 0xCC)
+ /* SPI/MPI Core Ssel reg */
+#define SMPI_FIFO_REG regptr(MSP_PER_BASE + 0xD0)
+ /* SPI/MPI Data FIFO reg */
+
+/* Peripheral Block Error Registers */
+#define PER_ERR_STS_REG regptr(MSP_PER_BASE + 0x70)
+ /* Error Bit Status Register */
+#define PER_ERR_MSK_REG regptr(MSP_PER_BASE + 0x74)
+ /* Error Bit Mask Register */
+#define PER_HDR1_REG regptr(MSP_PER_BASE + 0x78)
+ /* Error Header 1 Register */
+#define PER_HDR2_REG regptr(MSP_PER_BASE + 0x7C)
+ /* Error Header 2 Register */
+
+/* Peripheral Block Interrupt Registers */
+#define PER_INT_STS_REG regptr(MSP_PER_BASE + 0x80)
+ /* Interrupt status register */
+#define PER_INT_MSK_REG regptr(MSP_PER_BASE + 0x84)
+ /* Interrupt Mask Register */
+#define GPIO_INT_STS_REG regptr(MSP_PER_BASE + 0x88)
+ /* GPIO interrupt status reg */
+#define GPIO_INT_MSK_REG regptr(MSP_PER_BASE + 0x8C)
+ /* GPIO interrupt MASK Reg */
+
+/* POLO GPIO registers */
+#define POLO_GPIO_DAT1_REG regptr(MSP_PER_BASE + 0x0E0)
+ /* Polo GPIO[8:0] data reg */
+#define POLO_GPIO_CFG1_REG regptr(MSP_PER_BASE + 0x0E4)
+ /* Polo GPIO[7:0] config reg */
+#define POLO_GPIO_CFG2_REG regptr(MSP_PER_BASE + 0x0E8)
+ /* Polo GPIO[15:8] config reg */
+#define POLO_GPIO_OD1_REG regptr(MSP_PER_BASE + 0x0EC)
+ /* Polo GPIO[31:0] output drive */
+#define POLO_GPIO_CFG3_REG regptr(MSP_PER_BASE + 0x170)
+ /* Polo GPIO[23:16] config reg */
+#define POLO_GPIO_DAT2_REG regptr(MSP_PER_BASE + 0x174)
+ /* Polo GPIO[15:9] data reg */
+#define POLO_GPIO_DAT3_REG regptr(MSP_PER_BASE + 0x178)
+ /* Polo GPIO[23:16] data reg */
+#define POLO_GPIO_DAT4_REG regptr(MSP_PER_BASE + 0x17C)
+ /* Polo GPIO[31:24] data reg */
+#define POLO_GPIO_DAT5_REG regptr(MSP_PER_BASE + 0x180)
+ /* Polo GPIO[39:32] data reg */
+#define POLO_GPIO_DAT6_REG regptr(MSP_PER_BASE + 0x184)
+ /* Polo GPIO[47:40] data reg */
+#define POLO_GPIO_DAT7_REG regptr(MSP_PER_BASE + 0x188)
+ /* Polo GPIO[54:48] data reg */
+#define POLO_GPIO_CFG4_REG regptr(MSP_PER_BASE + 0x18C)
+ /* Polo GPIO[31:24] config reg */
+#define POLO_GPIO_CFG5_REG regptr(MSP_PER_BASE + 0x190)
+ /* Polo GPIO[39:32] config reg */
+#define POLO_GPIO_CFG6_REG regptr(MSP_PER_BASE + 0x194)
+ /* Polo GPIO[47:40] config reg */
+#define POLO_GPIO_CFG7_REG regptr(MSP_PER_BASE + 0x198)
+ /* Polo GPIO[54:48] config reg */
+#define POLO_GPIO_OD2_REG regptr(MSP_PER_BASE + 0x19C)
+ /* Polo GPIO[54:32] output drive */
+
+/* Generic GPIO registers */
+#define GPIO_DATA1_REG regptr(MSP_PER_BASE + 0x170)
+ /* GPIO[1:0] data register */
+#define GPIO_DATA2_REG regptr(MSP_PER_BASE + 0x174)
+ /* GPIO[5:2] data register */
+#define GPIO_DATA3_REG regptr(MSP_PER_BASE + 0x178)
+ /* GPIO[9:6] data register */
+#define GPIO_DATA4_REG regptr(MSP_PER_BASE + 0x17C)
+ /* GPIO[15:10] data register */
+#define GPIO_CFG1_REG regptr(MSP_PER_BASE + 0x180)
+ /* GPIO[1:0] config register */
+#define GPIO_CFG2_REG regptr(MSP_PER_BASE + 0x184)
+ /* GPIO[5:2] config register */
+#define GPIO_CFG3_REG regptr(MSP_PER_BASE + 0x188)
+ /* GPIO[9:6] config register */
+#define GPIO_CFG4_REG regptr(MSP_PER_BASE + 0x18C)
+ /* GPIO[15:10] config register */
+#define GPIO_OD_REG regptr(MSP_PER_BASE + 0x190)
+ /* GPIO[15:0] output drive */
+
+/*
+ ***************************************************************************
+ * CPU Interface register definitions *
+ ***************************************************************************
+ */
+#define PCI_FLUSH_REG regptr(MSP_CPUIF_BASE + 0x00)
+ /* PCI-SDRAM queue flush trigger */
+#define OCP_ERR1_REG regptr(MSP_CPUIF_BASE + 0x04)
+ /* OCP Error Attribute 1 */
+#define OCP_ERR2_REG regptr(MSP_CPUIF_BASE + 0x08)
+ /* OCP Error Attribute 2 */
+#define OCP_STS_REG regptr(MSP_CPUIF_BASE + 0x0C)
+ /* OCP Error Status */
+#define CPUIF_PM_REG regptr(MSP_CPUIF_BASE + 0x10)
+ /* CPU policy configuration */
+#define CPUIF_CFG_REG regptr(MSP_CPUIF_BASE + 0x10)
+ /* Misc configuration options */
+
+/* Central Interrupt Controller Registers */
+#define MSP_CIC_BASE (MSP_CPUIF_BASE + 0x8000)
+ /* Central Interrupt registers */
+#define CIC_EXT_CFG_REG regptr(MSP_CIC_BASE + 0x00)
+ /* External interrupt config */
+#define CIC_STS_REG regptr(MSP_CIC_BASE + 0x04)
+ /* CIC Interrupt Status */
+#define CIC_VPE0_MSK_REG regptr(MSP_CIC_BASE + 0x08)
+ /* VPE0 Interrupt Mask */
+#define CIC_VPE1_MSK_REG regptr(MSP_CIC_BASE + 0x0C)
+ /* VPE1 Interrupt Mask */
+#define CIC_TC0_MSK_REG regptr(MSP_CIC_BASE + 0x10)
+ /* Thread Context 0 Int Mask */
+#define CIC_TC1_MSK_REG regptr(MSP_CIC_BASE + 0x14)
+ /* Thread Context 1 Int Mask */
+#define CIC_TC2_MSK_REG regptr(MSP_CIC_BASE + 0x18)
+ /* Thread Context 2 Int Mask */
+#define CIC_TC3_MSK_REG regptr(MSP_CIC_BASE + 0x18)
+ /* Thread Context 3 Int Mask */
+#define CIC_TC4_MSK_REG regptr(MSP_CIC_BASE + 0x18)
+ /* Thread Context 4 Int Mask */
+#define CIC_PCIMSI_STS_REG regptr(MSP_CIC_BASE + 0x18)
+#define CIC_PCIMSI_MSK_REG regptr(MSP_CIC_BASE + 0x18)
+#define CIC_PCIFLSH_REG regptr(MSP_CIC_BASE + 0x18)
+#define CIC_VPE0_SWINT_REG regptr(MSP_CIC_BASE + 0x08)
+
+
+/*
+ ***************************************************************************
+ * Memory controller registers *
+ ***************************************************************************
+ */
+#define MEM_CFG1_REG regptr(MSP_MEM_CFG_BASE + 0x00)
+#define MEM_SS_ADDR regptr(MSP_MEM_CFG_BASE + 0x00)
+#define MEM_SS_DATA regptr(MSP_MEM_CFG_BASE + 0x04)
+#define MEM_SS_WRITE regptr(MSP_MEM_CFG_BASE + 0x08)
+
+/*
+ ***************************************************************************
+ * PCI controller registers *
+ ***************************************************************************
+ */
+#define PCI_BASE_REG regptr(MSP_PCI_BASE + 0x00)
+#define PCI_CONFIG_SPACE_REG regptr(MSP_PCI_BASE + 0x800)
+#define PCI_JTAG_DEVID_REG regptr(MSP_SLP_BASE + 0x13c)
+
+/*
+ ########################################################################
+ # Register content & macro definitions #
+ ########################################################################
+ */
+
+/*
+ ***************************************************************************
+ * DEV_ID defines *
+ ***************************************************************************
+ */
+#define DEV_ID_PCI_DIS (1 << 26) /* Set if PCI disabled */
+#define DEV_ID_PCI_HOST (1 << 20) /* Set if PCI host */
+#define DEV_ID_SINGLE_PC (1 << 19) /* Set if single PC Card */
+#define DEV_ID_FAMILY (0xff << 8) /* family ID code */
+#define POLO_ZEUS_SUB_FAMILY (0x7 << 16) /* sub family for Polo/Zeus */
+
+#define MSPFPGA_ID (0x00 << 8) /* you are on your own here */
+#define MSP5000_ID (0x50 << 8)
+#define MSP4F00_ID (0x4f << 8) /* FPGA version of MSP4200 */
+#define MSP4E00_ID (0x4f << 8) /* FPGA version of MSP7120 */
+#define MSP4200_ID (0x42 << 8)
+#define MSP4000_ID (0x40 << 8)
+#define MSP2XXX_ID (0x20 << 8)
+#define MSPZEUS_ID (0x10 << 8)
+
+#define MSP2004_SUB_ID (0x0 << 16)
+#define MSP2005_SUB_ID (0x1 << 16)
+#define MSP2006_SUB_ID (0x1 << 16)
+#define MSP2007_SUB_ID (0x2 << 16)
+#define MSP2010_SUB_ID (0x3 << 16)
+#define MSP2015_SUB_ID (0x4 << 16)
+#define MSP2020_SUB_ID (0x5 << 16)
+#define MSP2100_SUB_ID (0x6 << 16)
+
+/*
+ ***************************************************************************
+ * RESET defines *
+ ***************************************************************************
+ */
+#define MSP_GR_RST (0x01 << 0) /* Global reset bit */
+#define MSP_MR_RST (0x01 << 1) /* MIPS reset bit */
+#define MSP_PD_RST (0x01 << 2) /* PVC DMA reset bit */
+#define MSP_PP_RST (0x01 << 3) /* PVC reset bit */
+/* reserved */
+#define MSP_EA_RST (0x01 << 6) /* Mac A reset bit */
+#define MSP_EB_RST (0x01 << 7) /* Mac B reset bit */
+#define MSP_SE_RST (0x01 << 8) /* Security Eng reset bit */
+#define MSP_PB_RST (0x01 << 9) /* Per block reset bit */
+#define MSP_EC_RST (0x01 << 10) /* Mac C reset bit */
+#define MSP_TW_RST (0x01 << 11) /* TWI reset bit */
+#define MSP_SPI_RST (0x01 << 12) /* SPI/MPI reset bit */
+#define MSP_U1_RST (0x01 << 13) /* UART1 reset bit */
+#define MSP_U0_RST (0x01 << 14) /* UART0 reset bit */
+
+/*
+ ***************************************************************************
+ * UART defines *
+ ***************************************************************************
+ */
+#define MSP_BASE_BAUD 25000000
+#define MSP_UART_REG_LEN 0x20
+
+/*
+ ***************************************************************************
+ * ELB defines *
+ ***************************************************************************
+ */
+#define PCCARD_32 0x02 /* Set if is PCCARD 32 (Cardbus) */
+#define SINGLE_PCCARD 0x01 /* Set to enable single PC card */
+
+/*
+ ***************************************************************************
+ * CIC defines *
+ ***************************************************************************
+ */
+
+/* CIC_EXT_CFG_REG */
+#define EXT_INT_POL(eirq) (1 << (eirq + 8))
+#define EXT_INT_EDGE(eirq) (1 << eirq)
+
+#define CIC_EXT_SET_TRIGGER_LEVEL(reg, eirq) (reg &= ~EXT_INT_EDGE(eirq))
+#define CIC_EXT_SET_TRIGGER_EDGE(reg, eirq) (reg |= EXT_INT_EDGE(eirq))
+#define CIC_EXT_SET_ACTIVE_HI(reg, eirq) (reg |= EXT_INT_POL(eirq))
+#define CIC_EXT_SET_ACTIVE_LO(reg, eirq) (reg &= ~EXT_INT_POL(eirq))
+#define CIC_EXT_SET_ACTIVE_RISING CIC_EXT_SET_ACTIVE_HI
+#define CIC_EXT_SET_ACTIVE_FALLING CIC_EXT_SET_ACTIVE_LO
+
+#define CIC_EXT_IS_TRIGGER_LEVEL(reg, eirq) \
+ ((reg & EXT_INT_EDGE(eirq)) == 0)
+#define CIC_EXT_IS_TRIGGER_EDGE(reg, eirq) (reg & EXT_INT_EDGE(eirq))
+#define CIC_EXT_IS_ACTIVE_HI(reg, eirq) (reg & EXT_INT_POL(eirq))
+#define CIC_EXT_IS_ACTIVE_LO(reg, eirq) \
+ ((reg & EXT_INT_POL(eirq)) == 0)
+#define CIC_EXT_IS_ACTIVE_RISING CIC_EXT_IS_ACTIVE_HI
+#define CIC_EXT_IS_ACTIVE_FALLING CIC_EXT_IS_ACTIVE_LO
+
+/*
+ ***************************************************************************
+ * Memory Controller defines *
+ ***************************************************************************
+ */
+
+/* Indirect memory controller registers */
+#define DDRC_CFG(n) (n)
+#define DDRC_DEBUG(n) (0x04 + n)
+#define DDRC_CTL(n) (0x40 + n)
+
+/* Macro to perform DDRC indirect write */
+#define DDRC_INDIRECT_WRITE(reg, mask, value) \
+({ \
+ *MEM_SS_ADDR = (((mask) & 0xf) << 8) | ((reg) & 0xff); \
+ *MEM_SS_DATA = (value); \
+ *MEM_SS_WRITE = 1; \
+})
+
+/*
+ ***************************************************************************
+ * SPI/MPI Mode *
+ ***************************************************************************
+ */
+#define SPI_MPI_RX_BUSY 0x00008000 /* SPI/MPI Receive Busy */
+#define SPI_MPI_FIFO_EMPTY 0x00004000 /* SPI/MPI Fifo Empty */
+#define SPI_MPI_TX_BUSY 0x00002000 /* SPI/MPI Transmit Busy */
+#define SPI_MPI_FIFO_FULL 0x00001000 /* SPI/MPU FIFO full */
+
+/*
+ ***************************************************************************
+ * SPI/MPI Control Register *
+ ***************************************************************************
+ */
+#define SPI_MPI_RX_START 0x00000004 /* Start receive command */
+#define SPI_MPI_FLUSH_Q 0x00000002 /* Flush SPI/MPI Queue */
+#define SPI_MPI_TX_START 0x00000001 /* Start Transmit Command */
+
+#endif /* !_ASM_MSP_REGS_H */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_slp_int.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_slp_int.h
new file mode 100644
index 00000000..96d4c8ce
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_slp_int.h
@@ -0,0 +1,141 @@
+/*
+ * Defines for the MSP interrupt controller.
+ *
+ * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved.
+ * Author: Carsten Langgaard, carstenl@mips.com
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+#ifndef _MSP_SLP_INT_H
+#define _MSP_SLP_INT_H
+
+/*
+ * The PMC-Sierra SLP interrupts are arranged in a 3 level cascaded
+ * hierarchical system. The first level are the direct MIPS interrupts
+ * and are assigned the interrupt range 0-7. The second level is the SLM
+ * interrupt controller and is assigned the range 8-39. The third level
+ * comprises the Peripherial block, the PCI block, the PCI MSI block and
+ * the SLP. The PCI interrupts and the SLP errors are handled by the
+ * relevant subsystems so the core interrupt code needs only concern
+ * itself with the Peripheral block. These are assigned interrupts in
+ * the range 40-71.
+ */
+
+/*
+ * IRQs directly connected to CPU
+ */
+#define MSP_MIPS_INTBASE 0
+#define MSP_INT_SW0 0 /* IRQ for swint0, C_SW0 */
+#define MSP_INT_SW1 1 /* IRQ for swint1, C_SW1 */
+#define MSP_INT_MAC0 2 /* IRQ for MAC 0, C_IRQ0 */
+#define MSP_INT_MAC1 3 /* IRQ for MAC 1, C_IRQ1 */
+#define MSP_INT_C_IRQ2 4 /* Wired off, C_IRQ2 */
+#define MSP_INT_VE 5 /* IRQ for Voice Engine, C_IRQ3 */
+#define MSP_INT_SLP 6 /* IRQ for SLM block, C_IRQ4 */
+#define MSP_INT_TIMER 7 /* IRQ for the MIPS timer, C_IRQ5 */
+
+/*
+ * IRQs cascaded on CPU interrupt 4 (CAUSE bit 12, C_IRQ4)
+ * These defines should be tied to the register definition for the SLM
+ * interrupt routine. For now, just use hard-coded values.
+ */
+#define MSP_SLP_INTBASE (MSP_MIPS_INTBASE + 8)
+#define MSP_INT_EXT0 (MSP_SLP_INTBASE + 0)
+ /* External interrupt 0 */
+#define MSP_INT_EXT1 (MSP_SLP_INTBASE + 1)
+ /* External interrupt 1 */
+#define MSP_INT_EXT2 (MSP_SLP_INTBASE + 2)
+ /* External interrupt 2 */
+#define MSP_INT_EXT3 (MSP_SLP_INTBASE + 3)
+ /* External interrupt 3 */
+/* Reserved 4-7 */
+
+/*
+ *************************************************************************
+ * DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER/DANGER *
+ * Some MSP produces have this interrupt labelled as Voice and some are *
+ * SEC mbox ... *
+ *************************************************************************
+ */
+#define MSP_INT_SLP_VE (MSP_SLP_INTBASE + 8)
+ /* Cascaded IRQ for Voice Engine*/
+#define MSP_INT_SLP_TDM (MSP_SLP_INTBASE + 9)
+ /* TDM interrupt */
+#define MSP_INT_SLP_MAC0 (MSP_SLP_INTBASE + 10)
+ /* Cascaded IRQ for MAC 0 */
+#define MSP_INT_SLP_MAC1 (MSP_SLP_INTBASE + 11)
+ /* Cascaded IRQ for MAC 1 */
+#define MSP_INT_SEC (MSP_SLP_INTBASE + 12)
+ /* IRQ for security engine */
+#define MSP_INT_PER (MSP_SLP_INTBASE + 13)
+ /* Peripheral interrupt */
+#define MSP_INT_TIMER0 (MSP_SLP_INTBASE + 14)
+ /* SLP timer 0 */
+#define MSP_INT_TIMER1 (MSP_SLP_INTBASE + 15)
+ /* SLP timer 1 */
+#define MSP_INT_TIMER2 (MSP_SLP_INTBASE + 16)
+ /* SLP timer 2 */
+#define MSP_INT_SLP_TIMER (MSP_SLP_INTBASE + 17)
+ /* Cascaded MIPS timer */
+#define MSP_INT_BLKCP (MSP_SLP_INTBASE + 18)
+ /* Block Copy */
+#define MSP_INT_UART0 (MSP_SLP_INTBASE + 19)
+ /* UART 0 */
+#define MSP_INT_PCI (MSP_SLP_INTBASE + 20)
+ /* PCI subsystem */
+#define MSP_INT_PCI_DBELL (MSP_SLP_INTBASE + 21)
+ /* PCI doorbell */
+#define MSP_INT_PCI_MSI (MSP_SLP_INTBASE + 22)
+ /* PCI Message Signal */
+#define MSP_INT_PCI_BC0 (MSP_SLP_INTBASE + 23)
+ /* PCI Block Copy 0 */
+#define MSP_INT_PCI_BC1 (MSP_SLP_INTBASE + 24)
+ /* PCI Block Copy 1 */
+#define MSP_INT_SLP_ERR (MSP_SLP_INTBASE + 25)
+ /* SLP error condition */
+#define MSP_INT_MAC2 (MSP_SLP_INTBASE + 26)
+ /* IRQ for MAC2 */
+/* Reserved 26-31 */
+
+/*
+ * IRQs cascaded on SLP PER interrupt (MSP_INT_PER)
+ */
+#define MSP_PER_INTBASE (MSP_SLP_INTBASE + 32)
+/* Reserved 0-1 */
+#define MSP_INT_UART1 (MSP_PER_INTBASE + 2)
+ /* UART 1 */
+/* Reserved 3-5 */
+#define MSP_INT_2WIRE (MSP_PER_INTBASE + 6)
+ /* 2-wire */
+#define MSP_INT_TM0 (MSP_PER_INTBASE + 7)
+ /* Peripheral timer block out 0 */
+#define MSP_INT_TM1 (MSP_PER_INTBASE + 8)
+ /* Peripheral timer block out 1 */
+/* Reserved 9 */
+#define MSP_INT_SPRX (MSP_PER_INTBASE + 10)
+ /* SPI RX complete */
+#define MSP_INT_SPTX (MSP_PER_INTBASE + 11)
+ /* SPI TX complete */
+#define MSP_INT_GPIO (MSP_PER_INTBASE + 12)
+ /* GPIO */
+#define MSP_INT_PER_ERR (MSP_PER_INTBASE + 13)
+ /* Peripheral error */
+/* Reserved 14-31 */
+
+#endif /* !_MSP_SLP_INT_H */
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h
new file mode 100644
index 00000000..4c9348df
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_usb.h
@@ -0,0 +1,144 @@
+/******************************************************************
+ * Copyright (c) 2000-2007 PMC-Sierra INC.
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+ * 02139, USA.
+ *
+ * PMC-SIERRA INC. DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
+ * SOFTWARE.
+ */
+#ifndef MSP_USB_H_
+#define MSP_USB_H_
+
+#ifdef CONFIG_MSP_HAS_DUAL_USB
+#define NUM_USB_DEVS 2
+#else
+#define NUM_USB_DEVS 1
+#endif
+
+/* Register spaces for USB host 0 */
+#define MSP_USB0_MAB_START (MSP_USB0_BASE + 0x0)
+#define MSP_USB0_MAB_END (MSP_USB0_BASE + 0x17)
+#define MSP_USB0_ID_START (MSP_USB0_BASE + 0x40000)
+#define MSP_USB0_ID_END (MSP_USB0_BASE + 0x4008f)
+#define MSP_USB0_HS_START (MSP_USB0_BASE + 0x40100)
+#define MSP_USB0_HS_END (MSP_USB0_BASE + 0x401FF)
+
+/* Register spaces for USB host 1 */
+#define MSP_USB1_MAB_START (MSP_USB1_BASE + 0x0)
+#define MSP_USB1_MAB_END (MSP_USB1_BASE + 0x17)
+#define MSP_USB1_ID_START (MSP_USB1_BASE + 0x40000)
+#define MSP_USB1_ID_END (MSP_USB1_BASE + 0x4008f)
+#define MSP_USB1_HS_START (MSP_USB1_BASE + 0x40100)
+#define MSP_USB1_HS_END (MSP_USB1_BASE + 0x401ff)
+
+/* USB Identification registers */
+struct msp_usbid_regs {
+ u32 id; /* 0x0: Identification register */
+ u32 hwgen; /* 0x4: General HW params */
+ u32 hwhost; /* 0x8: Host HW params */
+ u32 hwdev; /* 0xc: Device HW params */
+ u32 hwtxbuf; /* 0x10: Tx buffer HW params */
+ u32 hwrxbuf; /* 0x14: Rx buffer HW params */
+ u32 reserved[26];
+ u32 timer0_load; /* 0x80: General-purpose timer 0 load*/
+ u32 timer0_ctrl; /* 0x84: General-purpose timer 0 control */
+ u32 timer1_load; /* 0x88: General-purpose timer 1 load*/
+ u32 timer1_ctrl; /* 0x8c: General-purpose timer 1 control */
+};
+
+/* MSBus to AMBA registers */
+struct msp_mab_regs {
+ u32 isr; /* 0x0: Interrupt status */
+ u32 imr; /* 0x4: Interrupt mask */
+ u32 thcr0; /* 0x8: Transaction header capture 0 */
+ u32 thcr1; /* 0xc: Transaction header capture 1 */
+ u32 int_stat; /* 0x10: Interrupt status summary */
+ u32 phy_cfg; /* 0x14: USB phy config */
+};
+
+/* EHCI registers */
+struct msp_usbhs_regs {
+ u32 hciver; /* 0x0: Version and offset to operational regs */
+ u32 hcsparams; /* 0x4: Host control structural parameters */
+ u32 hccparams; /* 0x8: Host control capability parameters */
+ u32 reserved0[5];
+ u32 dciver; /* 0x20: Device interface version */
+ u32 dccparams; /* 0x24: Device control capability parameters */
+ u32 reserved1[6];
+ u32 cmd; /* 0x40: USB command */
+ u32 sts; /* 0x44: USB status */
+ u32 int_ena; /* 0x48: USB interrupt enable */
+ u32 frindex; /* 0x4c: Frame index */
+ u32 reserved3;
+ union {
+ struct {
+ u32 flb_addr; /* 0x54: Frame list base address */
+ u32 next_async_addr; /* 0x58: next asynchronous addr */
+ u32 ttctrl; /* 0x5c: embedded transaction translator
+ async buffer status */
+ u32 burst_size; /* 0x60: Controller burst size */
+ u32 tx_fifo_ctrl; /* 0x64: Tx latency FIFO tuning */
+ u32 reserved0[4];
+ u32 endpt_nak; /* 0x78: Endpoint NAK */
+ u32 endpt_nak_ena; /* 0x7c: Endpoint NAK enable */
+ u32 cfg_flag; /* 0x80: Config flag */
+ u32 port_sc1; /* 0x84: Port status & control 1 */
+ u32 reserved1[7];
+ u32 otgsc; /* 0xa4: OTG status & control */
+ u32 mode; /* 0xa8: USB controller mode */
+ } host;
+
+ struct {
+ u32 dev_addr; /* 0x54: Device address */
+ u32 endpt_list_addr; /* 0x58: Endpoint list address */
+ u32 reserved0[7];
+ u32 endpt_nak; /* 0x74 */
+ u32 endpt_nak_ctrl; /* 0x78 */
+ u32 cfg_flag; /* 0x80 */
+ u32 port_sc1; /* 0x84: Port status & control 1 */
+ u32 reserved[7];
+ u32 otgsc; /* 0xa4: OTG status & control */
+ u32 mode; /* 0xa8: USB controller mode */
+ u32 endpt_setup_stat; /* 0xac */
+ u32 endpt_prime; /* 0xb0 */
+ u32 endpt_flush; /* 0xb4 */
+ u32 endpt_stat; /* 0xb8 */
+ u32 endpt_complete; /* 0xbc */
+ u32 endpt_ctrl0; /* 0xc0 */
+ u32 endpt_ctrl1; /* 0xc4 */
+ u32 endpt_ctrl2; /* 0xc8 */
+ u32 endpt_ctrl3; /* 0xcc */
+ } device;
+ } u;
+};
+/*
+ * Container for the more-generic platform_device.
+ * This exists mainly as a way to map the non-standard register
+ * spaces and make them accessible to the USB ISR.
+ */
+struct mspusb_device {
+ struct msp_mab_regs __iomem *mab_regs;
+ struct msp_usbid_regs __iomem *usbid_regs;
+ struct msp_usbhs_regs __iomem *usbhs_regs;
+ struct platform_device dev;
+};
+
+#define to_mspusb_device(x) container_of((x), struct mspusb_device, dev)
+#define TO_HOST_ID(x) ((x) & 0x3)
+#endif /*MSP_USB_H_*/
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/war.h b/arch/mips/include/asm/pmc-sierra/msp71xx/war.h
new file mode 100644
index 00000000..9e2ee429
--- /dev/null
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/war.h
@@ -0,0 +1,30 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_PMC_SIERRA_WAR_H
+#define __ASM_MIPS_PMC_SIERRA_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#if defined(CONFIG_PMC_MSP7120_EVAL) || defined(CONFIG_PMC_MSP7120_GW) || \
+ defined(CONFIG_PMC_MSP7120_FPGA)
+#define MIPS34K_MISSED_ITLB_WAR 1
+#else
+#define MIPS34K_MISSED_ITLB_WAR 0
+#endif
+
+#endif /* __ASM_MIPS_PMC_SIERRA_WAR_H */
diff --git a/arch/mips/include/asm/pmon.h b/arch/mips/include/asm/pmon.h
new file mode 100644
index 00000000..6ad51918
--- /dev/null
+++ b/arch/mips/include/asm/pmon.h
@@ -0,0 +1,46 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 by Ralf Baechle
+ *
+ * The cpustart method is a PMC-Sierra's function to start the secondary CPU.
+ * Stock PMON 2000 has the smpfork, semlock and semunlock methods instead.
+ */
+#ifndef _ASM_PMON_H
+#define _ASM_PMON_H
+
+struct callvectors {
+ int (*open) (char*, int, int);
+ int (*close) (int);
+ int (*read) (int, void*, int);
+ int (*write) (int, void*, int);
+ off_t (*lseek) (int, off_t, int);
+ int (*printf) (const char*, ...);
+ void (*cacheflush) (void);
+ char* (*gets) (char*);
+ union {
+ int (*smpfork) (unsigned long cp, char *sp);
+ int (*cpustart) (long, void (*)(void), void *, long);
+ } _s;
+ int (*semlock) (int sem);
+ void (*semunlock) (int sem);
+};
+
+extern struct callvectors *debug_vectors;
+
+#define pmon_open(name, flags, mode) debug_vectors->open(name, flage, mode)
+#define pmon_close(fd) debug_vectors->close(fd)
+#define pmon_read(fd, buf, count) debug_vectors->read(fd, buf, count)
+#define pmon_write(fd, buf, count) debug_vectors->write(fd, buf, count)
+#define pmon_lseek(fd, off, whence) debug_vectors->lseek(fd, off, whence)
+#define pmon_printf(fmt...) debug_vectors->printf(fmt)
+#define pmon_cacheflush() debug_vectors->cacheflush()
+#define pmon_gets(s) debug_vectors->gets(s)
+#define pmon_cpustart(n, f, sp, gp) debug_vectors->_s.cpustart(n, f, sp, gp)
+#define pmon_smpfork(cp, sp) debug_vectors->_s.smpfork(cp, sp)
+#define pmon_semlock(sem) debug_vectors->semlock(sem)
+#define pmon_semunlock(sem) debug_vectors->semunlock(sem)
+
+#endif /* _ASM_PMON_H */
diff --git a/arch/mips/include/asm/poll.h b/arch/mips/include/asm/poll.h
new file mode 100644
index 00000000..47b95208
--- /dev/null
+++ b/arch/mips/include/asm/poll.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_POLL_H
+#define __ASM_POLL_H
+
+#define POLLWRNORM POLLOUT
+#define POLLWRBAND 0x0100
+
+#include <asm-generic/poll.h>
+
+#endif /* __ASM_POLL_H */
diff --git a/arch/mips/include/asm/posix_types.h b/arch/mips/include/asm/posix_types.h
new file mode 100644
index 00000000..c200102c
--- /dev/null
+++ b/arch/mips/include/asm/posix_types.h
@@ -0,0 +1,144 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_POSIX_TYPES_H
+
+#include <asm/sgidefs.h>
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long __kernel_ino_t;
+typedef unsigned int __kernel_mode_t;
+#if (_MIPS_SZLONG == 32)
+typedef unsigned long __kernel_nlink_t;
+#endif
+#if (_MIPS_SZLONG == 64)
+typedef unsigned int __kernel_nlink_t;
+#endif
+typedef long __kernel_off_t;
+typedef int __kernel_pid_t;
+typedef int __kernel_ipc_pid_t;
+typedef unsigned int __kernel_uid_t;
+typedef unsigned int __kernel_gid_t;
+#if (_MIPS_SZLONG == 32)
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+#endif
+#if (_MIPS_SZLONG == 64)
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
+typedef long __kernel_ptrdiff_t;
+#endif
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
+typedef long __kernel_daddr_t;
+typedef char * __kernel_caddr_t;
+
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+typedef __kernel_uid_t __kernel_old_uid_t;
+typedef __kernel_gid_t __kernel_old_gid_t;
+typedef unsigned int __kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+#if (_MIPS_SZLONG == 32)
+ long val[2];
+#endif
+#if (_MIPS_SZLONG == 64)
+ int val[2];
+#endif
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__)
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+ unsigned long __tmp = __fd / __NFDBITS;
+ unsigned long __rem = __fd % __NFDBITS;
+ __fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
+{
+ unsigned long __tmp = __fd / __NFDBITS;
+ unsigned long __rem = __fd % __NFDBITS;
+ __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
+{
+ unsigned long __tmp = __fd / __NFDBITS;
+ unsigned long __rem = __fd % __NFDBITS;
+ return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
+{
+ unsigned long *__tmp = __p->fds_bits;
+ int __i;
+
+ if (__builtin_constant_p(__FDSET_LONGS)) {
+ switch (__FDSET_LONGS) {
+ case 16:
+ __tmp[ 0] = 0; __tmp[ 1] = 0;
+ __tmp[ 2] = 0; __tmp[ 3] = 0;
+ __tmp[ 4] = 0; __tmp[ 5] = 0;
+ __tmp[ 6] = 0; __tmp[ 7] = 0;
+ __tmp[ 8] = 0; __tmp[ 9] = 0;
+ __tmp[10] = 0; __tmp[11] = 0;
+ __tmp[12] = 0; __tmp[13] = 0;
+ __tmp[14] = 0; __tmp[15] = 0;
+ return;
+
+ case 8:
+ __tmp[ 0] = 0; __tmp[ 1] = 0;
+ __tmp[ 2] = 0; __tmp[ 3] = 0;
+ __tmp[ 4] = 0; __tmp[ 5] = 0;
+ __tmp[ 6] = 0; __tmp[ 7] = 0;
+ return;
+
+ case 4:
+ __tmp[ 0] = 0; __tmp[ 1] = 0;
+ __tmp[ 2] = 0; __tmp[ 3] = 0;
+ return;
+ }
+ }
+ __i = __FDSET_LONGS;
+ while (__i) {
+ __i--;
+ *__tmp = 0;
+ __tmp++;
+ }
+}
+
+#endif /* defined(__KERNEL__) */
+
+#endif /* _ASM_POSIX_TYPES_H */
diff --git a/arch/mips/include/asm/prefetch.h b/arch/mips/include/asm/prefetch.h
new file mode 100644
index 00000000..a56594f3
--- /dev/null
+++ b/arch/mips/include/asm/prefetch.h
@@ -0,0 +1,87 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#ifndef __ASM_PREFETCH_H
+#define __ASM_PREFETCH_H
+
+
+/*
+ * R5000 and RM5200 implements pref and prefx instructions but they're nops, so
+ * rather than wasting time we pretend these processors don't support
+ * prefetching at all.
+ *
+ * R5432 implements Load, Store, LoadStreamed, StoreStreamed, LoadRetained,
+ * StoreRetained and WriteBackInvalidate but not Pref_PrepareForStore.
+ *
+ * Hell (and the book on my shelf I can't open ...) know what the R8000 does.
+ *
+ * RM7000 version 1.0 interprets all hints as Pref_Load; version 2.0 implements
+ * Pref_PrepareForStore also.
+ *
+ * RM9000 is MIPS IV but implements prefetching like MIPS32/MIPS64; it's
+ * Pref_WriteBackInvalidate is a nop and Pref_PrepareForStore is broken in
+ * current versions due to erratum G105.
+ *
+ * VR5500 (including VR5701 and VR7701) only implement load prefetch.
+ *
+ * Finally MIPS32 and MIPS64 implement all of the following hints.
+ */
+
+#define Pref_Load 0
+#define Pref_Store 1
+ /* 2 and 3 are reserved */
+#define Pref_LoadStreamed 4
+#define Pref_StoreStreamed 5
+#define Pref_LoadRetained 6
+#define Pref_StoreRetained 7
+ /* 8 ... 24 are reserved */
+#define Pref_WriteBackInvalidate 25
+#define Pref_PrepareForStore 30
+
+#ifdef __ASSEMBLY__
+
+ .macro __pref hint addr
+#ifdef CONFIG_CPU_HAS_PREFETCH
+ pref \hint, \addr
+#endif
+ .endm
+
+ .macro pref_load addr
+ __pref Pref_Load, \addr
+ .endm
+
+ .macro pref_store addr
+ __pref Pref_Store, \addr
+ .endm
+
+ .macro pref_load_streamed addr
+ __pref Pref_LoadStreamed, \addr
+ .endm
+
+ .macro pref_store_streamed addr
+ __pref Pref_StoreStreamed, \addr
+ .endm
+
+ .macro pref_load_retained addr
+ __pref Pref_LoadRetained, \addr
+ .endm
+
+ .macro pref_store_retained addr
+ __pref Pref_StoreRetained, \addr
+ .endm
+
+ .macro pref_wback_inv addr
+ __pref Pref_WriteBackInvalidate, \addr
+ .endm
+
+ .macro pref_prepare_for_store addr
+ __pref Pref_PrepareForStore, \addr
+ .endm
+
+#endif
+
+#endif /* __ASM_PREFETCH_H */
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
new file mode 100644
index 00000000..c104f103
--- /dev/null
+++ b/arch/mips/include/asm/processor.h
@@ -0,0 +1,361 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 Waldorf GMBH
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+#include <linux/cpumask.h>
+#include <linux/threads.h>
+
+#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/cpu-info.h>
+#include <asm/mipsregs.h>
+#include <asm/prefetch.h>
+#include <asm/system.h>
+
+/*
+ * Return current * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+/*
+ * System setup and hardware flags..
+ */
+extern void (*cpu_wait)(void);
+
+extern unsigned int vced_count, vcei_count;
+
+/*
+ * MIPS does have an arch_pick_mmap_layout()
+ */
+#define HAVE_ARCH_PICK_MMAP_LAYOUT 1
+
+/*
+ * A special page (the vdso) is mapped into all processes at the very
+ * top of the virtual memory space.
+ */
+#define SPECIAL_PAGES_SIZE PAGE_SIZE
+
+#ifdef CONFIG_32BIT
+/*
+ * User space process size: 2GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#define TASK_SIZE 0x7fff8000UL
+
+#ifdef __KERNEL__
+#define STACK_TOP_MAX TASK_SIZE
+#endif
+
+#define TASK_IS_32BIT_ADDR 1
+
+#endif
+
+#ifdef CONFIG_64BIT
+/*
+ * User space process size: 1TB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing. TASK_SIZE
+ * is limited to 1TB by the R4000 architecture; R10000 and better can
+ * support 16TB; the architectural reserve for future expansion is
+ * 8192EB ...
+ */
+#define TASK_SIZE32 0x7fff8000UL
+#define TASK_SIZE64 0x10000000000UL
+#define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
+
+#ifdef __KERNEL__
+#define STACK_TOP_MAX TASK_SIZE64
+#endif
+
+
+#define TASK_SIZE_OF(tsk) \
+ (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
+
+#define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR)
+
+#endif
+
+#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
+
+
+#define NUM_FPU_REGS 32
+
+typedef __u64 fpureg_t;
+
+/*
+ * It would be nice to add some more fields for emulator statistics, but there
+ * are a number of fixed offsets in offset.h and elsewhere that would have to
+ * be recalculated by hand. So the additional information will be private to
+ * the FPU emulator for now. See asm-mips/fpu_emulator.h.
+ */
+
+struct mips_fpu_struct {
+ fpureg_t fpr[NUM_FPU_REGS];
+ unsigned int fcr31;
+};
+
+#define NUM_DSP_REGS 6
+
+typedef __u32 dspreg_t;
+
+struct mips_dsp_state {
+ dspreg_t dspr[NUM_DSP_REGS];
+ unsigned int dspcontrol;
+};
+
+#define INIT_CPUMASK { \
+ {0,} \
+}
+
+struct mips3264_watch_reg_state {
+ /* The width of watchlo is 32 in a 32 bit kernel and 64 in a
+ 64 bit kernel. We use unsigned long as it has the same
+ property. */
+ unsigned long watchlo[NUM_WATCH_REGS];
+ /* Only the mask and IRW bits from watchhi. */
+ u16 watchhi[NUM_WATCH_REGS];
+};
+
+union mips_watch_reg_state {
+ struct mips3264_watch_reg_state mips3264;
+};
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+
+struct octeon_cop2_state {
+ /* DMFC2 rt, 0x0201 */
+ unsigned long cop2_crc_iv;
+ /* DMFC2 rt, 0x0202 (Set with DMTC2 rt, 0x1202) */
+ unsigned long cop2_crc_length;
+ /* DMFC2 rt, 0x0200 (set with DMTC2 rt, 0x4200) */
+ unsigned long cop2_crc_poly;
+ /* DMFC2 rt, 0x0402; DMFC2 rt, 0x040A */
+ unsigned long cop2_llm_dat[2];
+ /* DMFC2 rt, 0x0084 */
+ unsigned long cop2_3des_iv;
+ /* DMFC2 rt, 0x0080; DMFC2 rt, 0x0081; DMFC2 rt, 0x0082 */
+ unsigned long cop2_3des_key[3];
+ /* DMFC2 rt, 0x0088 (Set with DMTC2 rt, 0x0098) */
+ unsigned long cop2_3des_result;
+ /* DMFC2 rt, 0x0111 (FIXME: Read Pass1 Errata) */
+ unsigned long cop2_aes_inp0;
+ /* DMFC2 rt, 0x0102; DMFC2 rt, 0x0103 */
+ unsigned long cop2_aes_iv[2];
+ /* DMFC2 rt, 0x0104; DMFC2 rt, 0x0105; DMFC2 rt, 0x0106; DMFC2
+ * rt, 0x0107 */
+ unsigned long cop2_aes_key[4];
+ /* DMFC2 rt, 0x0110 */
+ unsigned long cop2_aes_keylen;
+ /* DMFC2 rt, 0x0100; DMFC2 rt, 0x0101 */
+ unsigned long cop2_aes_result[2];
+ /* DMFC2 rt, 0x0240; DMFC2 rt, 0x0241; DMFC2 rt, 0x0242; DMFC2
+ * rt, 0x0243; DMFC2 rt, 0x0244; DMFC2 rt, 0x0245; DMFC2 rt,
+ * 0x0246; DMFC2 rt, 0x0247; DMFC2 rt, 0x0248; DMFC2 rt,
+ * 0x0249; DMFC2 rt, 0x024A; DMFC2 rt, 0x024B; DMFC2 rt,
+ * 0x024C; DMFC2 rt, 0x024D; DMFC2 rt, 0x024E - Pass2 */
+ unsigned long cop2_hsh_datw[15];
+ /* DMFC2 rt, 0x0250; DMFC2 rt, 0x0251; DMFC2 rt, 0x0252; DMFC2
+ * rt, 0x0253; DMFC2 rt, 0x0254; DMFC2 rt, 0x0255; DMFC2 rt,
+ * 0x0256; DMFC2 rt, 0x0257 - Pass2 */
+ unsigned long cop2_hsh_ivw[8];
+ /* DMFC2 rt, 0x0258; DMFC2 rt, 0x0259 - Pass2 */
+ unsigned long cop2_gfm_mult[2];
+ /* DMFC2 rt, 0x025E - Pass2 */
+ unsigned long cop2_gfm_poly;
+ /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */
+ unsigned long cop2_gfm_result[2];
+};
+#define INIT_OCTEON_COP2 {0,}
+
+struct octeon_cvmseg_state {
+ unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE]
+ [cpu_dcache_line_size() / sizeof(unsigned long)];
+};
+
+#endif
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+#define ARCH_MIN_TASKALIGN 8
+
+struct mips_abi;
+
+/*
+ * If you change thread_struct remember to change the #defines below too!
+ */
+struct thread_struct {
+ /* Saved main processor registers. */
+ unsigned long reg16;
+ unsigned long reg17, reg18, reg19, reg20, reg21, reg22, reg23;
+ unsigned long reg29, reg30, reg31;
+
+ /* Saved cp0 stuff. */
+ unsigned long cp0_status;
+
+ /* Saved fpu/fpu emulator stuff. */
+ struct mips_fpu_struct fpu;
+#ifdef CONFIG_MIPS_MT_FPAFF
+ /* Emulated instruction count */
+ unsigned long emulated_fp;
+ /* Saved per-thread scheduler affinity mask */
+ cpumask_t user_cpus_allowed;
+#endif /* CONFIG_MIPS_MT_FPAFF */
+
+ /* Saved state of the DSP ASE, if available. */
+ struct mips_dsp_state dsp;
+
+ /* Saved watch register state, if available. */
+ union mips_watch_reg_state watch;
+
+ /* Other stuff associated with the thread. */
+ unsigned long cp0_badvaddr; /* Last user fault */
+ unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
+ unsigned long error_code;
+ unsigned long irix_trampoline; /* Wheee... */
+ unsigned long irix_oldctx;
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
+ struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
+#endif
+ struct mips_abi *abi;
+};
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+#define FPAFF_INIT \
+ .emulated_fp = 0, \
+ .user_cpus_allowed = INIT_CPUMASK,
+#else
+#define FPAFF_INIT
+#endif /* CONFIG_MIPS_MT_FPAFF */
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define OCTEON_INIT \
+ .cp2 = INIT_OCTEON_COP2,
+#else
+#define OCTEON_INIT
+#endif /* CONFIG_CPU_CAVIUM_OCTEON */
+
+#define INIT_THREAD { \
+ /* \
+ * Saved main processor registers \
+ */ \
+ .reg16 = 0, \
+ .reg17 = 0, \
+ .reg18 = 0, \
+ .reg19 = 0, \
+ .reg20 = 0, \
+ .reg21 = 0, \
+ .reg22 = 0, \
+ .reg23 = 0, \
+ .reg29 = 0, \
+ .reg30 = 0, \
+ .reg31 = 0, \
+ /* \
+ * Saved cp0 stuff \
+ */ \
+ .cp0_status = 0, \
+ /* \
+ * Saved FPU/FPU emulator stuff \
+ */ \
+ .fpu = { \
+ .fpr = {0,}, \
+ .fcr31 = 0, \
+ }, \
+ /* \
+ * FPU affinity state (null if not FPAFF) \
+ */ \
+ FPAFF_INIT \
+ /* \
+ * Saved DSP stuff \
+ */ \
+ .dsp = { \
+ .dspr = {0, }, \
+ .dspcontrol = 0, \
+ }, \
+ /* \
+ * saved watch register stuff \
+ */ \
+ .watch = {{{0,},},}, \
+ /* \
+ * Other stuff associated with the process \
+ */ \
+ .cp0_badvaddr = 0, \
+ .cp0_baduaddr = 0, \
+ .error_code = 0, \
+ .irix_trampoline = 0, \
+ .irix_oldctx = 0, \
+ /* \
+ * Cavium Octeon specifics (null if not Octeon) \
+ */ \
+ OCTEON_INIT \
+}
+
+struct task_struct;
+
+/* Free all resources held by a thread. */
+#define release_thread(thread) do { } while(0)
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
+extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \
+ THREAD_SIZE - 32 - sizeof(struct pt_regs))
+#define task_pt_regs(tsk) ((struct pt_regs *)__KSTK_TOS(tsk))
+#define KSTK_EIP(tsk) (task_pt_regs(tsk)->cp0_epc)
+#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29])
+#define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)
+
+#define cpu_relax() barrier()
+
+/*
+ * Return_address is a replacement for __builtin_return_address(count)
+ * which on certain architectures cannot reasonably be implemented in GCC
+ * (MIPS, Alpha) or is unusable with -fomit-frame-pointer (i386).
+ * Note that __builtin_return_address(x>=1) is forbidden because GCC
+ * aborts compilation on some CPUs. It's simply not possible to unwind
+ * some CPU's stackframes.
+ *
+ * __builtin_return_address works only for non-leaf functions. We avoid the
+ * overhead of a function call by forcing the compiler to save the return
+ * address register on the stack.
+ */
+#define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);})
+
+#ifdef CONFIG_CPU_HAS_PREFETCH
+
+#define ARCH_HAS_PREFETCH
+#define prefetch(x) __builtin_prefetch((x), 0, 1)
+
+#define ARCH_HAS_PREFETCHW
+#define prefetchw(x) __builtin_prefetch((x), 1, 1)
+
+#endif
+
+#endif /* _ASM_PROCESSOR_H */
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h
new file mode 100644
index 00000000..857d9b78
--- /dev/null
+++ b/arch/mips/include/asm/prom.h
@@ -0,0 +1,28 @@
+/*
+ * arch/mips/include/asm/prom.h
+ *
+ * Copyright (C) 2010 Cisco Systems Inc. <dediao@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASM_MIPS_PROM_H
+#define __ASM_MIPS_PROM_H
+
+#ifdef CONFIG_OF
+#include <asm/bootinfo.h>
+
+extern int early_init_dt_scan_memory_arch(unsigned long node,
+ const char *uname, int depth, void *data);
+
+extern int reserve_mem_mach(unsigned long addr, unsigned long size);
+extern void free_mem_mach(unsigned long addr, unsigned long size);
+
+extern void device_tree_init(void);
+#else /* CONFIG_OF */
+static inline void device_tree_init(void) { }
+#endif /* CONFIG_OF */
+
+#endif /* _ASM_MIPS_PROM_H */
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
new file mode 100644
index 00000000..de39b1f3
--- /dev/null
+++ b/arch/mips/include/asm/ptrace.h
@@ -0,0 +1,157 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+/* 0 - 31 are integer registers, 32 - 63 are fp registers. */
+#define FPR_BASE 32
+#define PC 64
+#define CAUSE 65
+#define BADVADDR 66
+#define MMHI 67
+#define MMLO 68
+#define FPC_CSR 69
+#define FPC_EIR 70
+#define DSP_BASE 71 /* 3 more hi / lo register pairs */
+#define DSP_CONTROL 77
+#define ACX 78
+
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call/exception. As usual the registers k0/k1 aren't being saved.
+ */
+struct pt_regs {
+#ifdef CONFIG_32BIT
+ /* Pad bytes for argument save space on the stack. */
+ unsigned long pad0[6];
+#endif
+
+ /* Saved main processor registers. */
+ unsigned long regs[32];
+
+ /* Saved special registers. */
+ unsigned long cp0_status;
+ unsigned long hi;
+ unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ unsigned long acx;
+#endif
+ unsigned long cp0_badvaddr;
+ unsigned long cp0_cause;
+ unsigned long cp0_epc;
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned long cp0_tcstatus;
+#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ unsigned long long mpl[3]; /* MTM{0,1,2} */
+ unsigned long long mtp[3]; /* MTP{0,1,2} */
+#endif
+} __attribute__ ((aligned (8)));
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+/* #define PTRACE_GETFPXREGS 18 */
+/* #define PTRACE_SETFPXREGS 19 */
+
+#define PTRACE_OLDSETOPTIONS 21
+
+#define PTRACE_GET_THREAD_AREA 25
+#define PTRACE_SET_THREAD_AREA 26
+
+/* Calls to trace a 64bit program from a 32bit program. */
+#define PTRACE_PEEKTEXT_3264 0xc0
+#define PTRACE_PEEKDATA_3264 0xc1
+#define PTRACE_POKETEXT_3264 0xc2
+#define PTRACE_POKEDATA_3264 0xc3
+#define PTRACE_GET_THREAD_AREA_3264 0xc4
+
+/* Read and write watchpoint registers. */
+enum pt_watch_style {
+ pt_watch_style_mips32,
+ pt_watch_style_mips64
+};
+struct mips32_watch_regs {
+ unsigned int watchlo[8];
+ /* Lower 16 bits of watchhi. */
+ unsigned short watchhi[8];
+ /* Valid mask and I R W bits.
+ * bit 0 -- 1 if W bit is usable.
+ * bit 1 -- 1 if R bit is usable.
+ * bit 2 -- 1 if I bit is usable.
+ * bits 3 - 11 -- Valid watchhi mask bits.
+ */
+ unsigned short watch_masks[8];
+ /* The number of valid watch register pairs. */
+ unsigned int num_valid;
+} __attribute__((aligned(8)));
+
+struct mips64_watch_regs {
+ unsigned long long watchlo[8];
+ unsigned short watchhi[8];
+ unsigned short watch_masks[8];
+ unsigned int num_valid;
+} __attribute__((aligned(8)));
+
+struct pt_watch_regs {
+ enum pt_watch_style style;
+ union {
+ struct mips32_watch_regs mips32;
+ struct mips64_watch_regs mips64;
+ };
+};
+
+#define PTRACE_GET_WATCH_REGS 0xd0
+#define PTRACE_SET_WATCH_REGS 0xd1
+
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/isadep.h>
+
+struct task_struct;
+
+extern int ptrace_getregs(struct task_struct *child, __s64 __user *data);
+extern int ptrace_setregs(struct task_struct *child, __s64 __user *data);
+
+extern int ptrace_getfpregs(struct task_struct *child, __u32 __user *data);
+extern int ptrace_setfpregs(struct task_struct *child, __u32 __user *data);
+
+extern int ptrace_get_watch_regs(struct task_struct *child,
+ struct pt_watch_regs __user *addr);
+extern int ptrace_set_watch_regs(struct task_struct *child,
+ struct pt_watch_regs __user *addr);
+
+/*
+ * Does the process account for user or for system time?
+ */
+#define user_mode(regs) (((regs)->cp0_status & KU_MASK) == KU_USER)
+
+#define regs_return_value(_regs) ((_regs)->regs[2])
+#define instruction_pointer(regs) ((regs)->cp0_epc)
+#define profile_pc(regs) instruction_pointer(regs)
+
+extern asmlinkage void syscall_trace_enter(struct pt_regs *regs);
+extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
+
+extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
+
+static inline void die_if_kernel(const char *str, struct pt_regs *regs)
+{
+ if (unlikely(!user_mode(regs)))
+ die(str, regs);
+}
+
+#endif
+
+#endif /* _ASM_PTRACE_H */
diff --git a/arch/mips/include/asm/r4k-timer.h b/arch/mips/include/asm/r4k-timer.h
new file mode 100644
index 00000000..a37d12b3
--- /dev/null
+++ b/arch/mips/include/asm/r4k-timer.h
@@ -0,0 +1,30 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef __ASM_R4K_TYPES_H
+#define __ASM_R4K_TYPES_H
+
+#include <linux/compiler.h>
+
+#ifdef CONFIG_SYNC_R4K
+
+extern void synchronise_count_master(void);
+extern void synchronise_count_slave(void);
+
+#else
+
+static inline void synchronise_count_master(void)
+{
+}
+
+static inline void synchronise_count_slave(void)
+{
+}
+
+#endif
+
+#endif /* __ASM_R4K_TYPES_H */
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
new file mode 100644
index 00000000..54ea47da
--- /dev/null
+++ b/arch/mips/include/asm/r4kcache.h
@@ -0,0 +1,444 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Inline assembly cache operations.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997 - 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef _ASM_R4KCACHE_H
+#define _ASM_R4KCACHE_H
+
+#include <asm/asm.h>
+#include <asm/cacheops.h>
+#include <asm/cpu-features.h>
+#include <asm/mipsmtregs.h>
+
+/*
+ * This macro return a properly sign-extended address suitable as base address
+ * for indexed cache operations. Two issues here:
+ *
+ * - The MIPS32 and MIPS64 specs permit an implementation to directly derive
+ * the index bits from the virtual address. This breaks with tradition
+ * set by the R4000. To keep unpleasant surprises from happening we pick
+ * an address in KSEG0 / CKSEG0.
+ * - We need a properly sign extended address for 64-bit code. To get away
+ * without ifdefs we let the compiler do it by a type cast.
+ */
+#define INDEX_BASE CKSEG0
+
+#define cache_op(op,addr) \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noreorder \n" \
+ " .set mips3\n\t \n" \
+ " cache %0, %1 \n" \
+ " .set pop \n" \
+ : \
+ : "i" (op), "R" (*(unsigned char *)(addr)))
+
+#ifdef CONFIG_MIPS_MT
+/*
+ * Temporary hacks for SMTC debug. Optionally force single-threaded
+ * execution during I-cache flushes.
+ */
+
+#define PROTECT_CACHE_FLUSHES 1
+
+#ifdef PROTECT_CACHE_FLUSHES
+
+extern int mt_protiflush;
+extern int mt_protdflush;
+extern void mt_cflush_lockdown(void);
+extern void mt_cflush_release(void);
+
+#define BEGIN_MT_IPROT \
+ unsigned long flags = 0; \
+ unsigned long mtflags = 0; \
+ if(mt_protiflush) { \
+ local_irq_save(flags); \
+ ehb(); \
+ mtflags = dvpe(); \
+ mt_cflush_lockdown(); \
+ }
+
+#define END_MT_IPROT \
+ if(mt_protiflush) { \
+ mt_cflush_release(); \
+ evpe(mtflags); \
+ local_irq_restore(flags); \
+ }
+
+#define BEGIN_MT_DPROT \
+ unsigned long flags = 0; \
+ unsigned long mtflags = 0; \
+ if(mt_protdflush) { \
+ local_irq_save(flags); \
+ ehb(); \
+ mtflags = dvpe(); \
+ mt_cflush_lockdown(); \
+ }
+
+#define END_MT_DPROT \
+ if(mt_protdflush) { \
+ mt_cflush_release(); \
+ evpe(mtflags); \
+ local_irq_restore(flags); \
+ }
+
+#else
+
+#define BEGIN_MT_IPROT
+#define BEGIN_MT_DPROT
+#define END_MT_IPROT
+#define END_MT_DPROT
+
+#endif /* PROTECT_CACHE_FLUSHES */
+
+#define __iflush_prologue \
+ unsigned long redundance; \
+ extern int mt_n_iflushes; \
+ BEGIN_MT_IPROT \
+ for (redundance = 0; redundance < mt_n_iflushes; redundance++) {
+
+#define __iflush_epilogue \
+ END_MT_IPROT \
+ }
+
+#define __dflush_prologue \
+ unsigned long redundance; \
+ extern int mt_n_dflushes; \
+ BEGIN_MT_DPROT \
+ for (redundance = 0; redundance < mt_n_dflushes; redundance++) {
+
+#define __dflush_epilogue \
+ END_MT_DPROT \
+ }
+
+#define __inv_dflush_prologue __dflush_prologue
+#define __inv_dflush_epilogue __dflush_epilogue
+#define __sflush_prologue {
+#define __sflush_epilogue }
+#define __inv_sflush_prologue __sflush_prologue
+#define __inv_sflush_epilogue __sflush_epilogue
+
+#else /* CONFIG_MIPS_MT */
+
+#define __iflush_prologue {
+#define __iflush_epilogue }
+#define __dflush_prologue {
+#define __dflush_epilogue }
+#define __inv_dflush_prologue {
+#define __inv_dflush_epilogue }
+#define __sflush_prologue {
+#define __sflush_epilogue }
+#define __inv_sflush_prologue {
+#define __inv_sflush_epilogue }
+
+#endif /* CONFIG_MIPS_MT */
+
+static inline void flush_icache_line_indexed(unsigned long addr)
+{
+ __iflush_prologue
+ cache_op(Index_Invalidate_I, addr);
+ __iflush_epilogue
+}
+
+static inline void flush_dcache_line_indexed(unsigned long addr)
+{
+ __dflush_prologue
+ cache_op(Index_Writeback_Inv_D, addr);
+ __dflush_epilogue
+}
+
+static inline void flush_scache_line_indexed(unsigned long addr)
+{
+ cache_op(Index_Writeback_Inv_SD, addr);
+}
+
+static inline void flush_icache_line(unsigned long addr)
+{
+ __iflush_prologue
+ cache_op(Hit_Invalidate_I, addr);
+ __iflush_epilogue
+}
+
+static inline void flush_dcache_line(unsigned long addr)
+{
+ __dflush_prologue
+ cache_op(Hit_Writeback_Inv_D, addr);
+ __dflush_epilogue
+}
+
+static inline void invalidate_dcache_line(unsigned long addr)
+{
+ __dflush_prologue
+ cache_op(Hit_Invalidate_D, addr);
+ __dflush_epilogue
+}
+
+static inline void invalidate_scache_line(unsigned long addr)
+{
+ cache_op(Hit_Invalidate_SD, addr);
+}
+
+static inline void flush_scache_line(unsigned long addr)
+{
+ cache_op(Hit_Writeback_Inv_SD, addr);
+}
+
+#define protected_cache_op(op,addr) \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noreorder \n" \
+ " .set mips3 \n" \
+ "1: cache %0, (%1) \n" \
+ "2: .set pop \n" \
+ " .section __ex_table,\"a\" \n" \
+ " "STR(PTR)" 1b, 2b \n" \
+ " .previous" \
+ : \
+ : "i" (op), "r" (addr))
+
+/*
+ * The next two are for badland addresses like signal trampolines.
+ */
+static inline void protected_flush_icache_line(unsigned long addr)
+{
+ protected_cache_op(Hit_Invalidate_I, addr);
+}
+
+/*
+ * R10000 / R12000 hazard - these processors don't support the Hit_Writeback_D
+ * cacheop so we use Hit_Writeback_Inv_D which is supported by all R4000-style
+ * caches. We're talking about one cacheline unnecessarily getting invalidated
+ * here so the penalty isn't overly hard.
+ */
+static inline void protected_writeback_dcache_line(unsigned long addr)
+{
+ protected_cache_op(Hit_Writeback_Inv_D, addr);
+}
+
+static inline void protected_writeback_scache_line(unsigned long addr)
+{
+ protected_cache_op(Hit_Writeback_Inv_SD, addr);
+}
+
+/*
+ * This one is RM7000-specific
+ */
+static inline void invalidate_tcache_page(unsigned long addr)
+{
+ cache_op(Page_Invalidate_T, addr);
+}
+
+#define cache16_unroll32(base,op) \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noreorder \n" \
+ " .set mips3 \n" \
+ " cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \
+ " cache %1, 0x020(%0); cache %1, 0x030(%0) \n" \
+ " cache %1, 0x040(%0); cache %1, 0x050(%0) \n" \
+ " cache %1, 0x060(%0); cache %1, 0x070(%0) \n" \
+ " cache %1, 0x080(%0); cache %1, 0x090(%0) \n" \
+ " cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) \n" \
+ " cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) \n" \
+ " cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) \n" \
+ " cache %1, 0x100(%0); cache %1, 0x110(%0) \n" \
+ " cache %1, 0x120(%0); cache %1, 0x130(%0) \n" \
+ " cache %1, 0x140(%0); cache %1, 0x150(%0) \n" \
+ " cache %1, 0x160(%0); cache %1, 0x170(%0) \n" \
+ " cache %1, 0x180(%0); cache %1, 0x190(%0) \n" \
+ " cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \
+ " cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \
+ " cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \
+ " .set pop \n" \
+ : \
+ : "r" (base), \
+ "i" (op));
+
+#define cache32_unroll32(base,op) \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noreorder \n" \
+ " .set mips3 \n" \
+ " cache %1, 0x000(%0); cache %1, 0x020(%0) \n" \
+ " cache %1, 0x040(%0); cache %1, 0x060(%0) \n" \
+ " cache %1, 0x080(%0); cache %1, 0x0a0(%0) \n" \
+ " cache %1, 0x0c0(%0); cache %1, 0x0e0(%0) \n" \
+ " cache %1, 0x100(%0); cache %1, 0x120(%0) \n" \
+ " cache %1, 0x140(%0); cache %1, 0x160(%0) \n" \
+ " cache %1, 0x180(%0); cache %1, 0x1a0(%0) \n" \
+ " cache %1, 0x1c0(%0); cache %1, 0x1e0(%0) \n" \
+ " cache %1, 0x200(%0); cache %1, 0x220(%0) \n" \
+ " cache %1, 0x240(%0); cache %1, 0x260(%0) \n" \
+ " cache %1, 0x280(%0); cache %1, 0x2a0(%0) \n" \
+ " cache %1, 0x2c0(%0); cache %1, 0x2e0(%0) \n" \
+ " cache %1, 0x300(%0); cache %1, 0x320(%0) \n" \
+ " cache %1, 0x340(%0); cache %1, 0x360(%0) \n" \
+ " cache %1, 0x380(%0); cache %1, 0x3a0(%0) \n" \
+ " cache %1, 0x3c0(%0); cache %1, 0x3e0(%0) \n" \
+ " .set pop \n" \
+ : \
+ : "r" (base), \
+ "i" (op));
+
+#define cache64_unroll32(base,op) \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noreorder \n" \
+ " .set mips3 \n" \
+ " cache %1, 0x000(%0); cache %1, 0x040(%0) \n" \
+ " cache %1, 0x080(%0); cache %1, 0x0c0(%0) \n" \
+ " cache %1, 0x100(%0); cache %1, 0x140(%0) \n" \
+ " cache %1, 0x180(%0); cache %1, 0x1c0(%0) \n" \
+ " cache %1, 0x200(%0); cache %1, 0x240(%0) \n" \
+ " cache %1, 0x280(%0); cache %1, 0x2c0(%0) \n" \
+ " cache %1, 0x300(%0); cache %1, 0x340(%0) \n" \
+ " cache %1, 0x380(%0); cache %1, 0x3c0(%0) \n" \
+ " cache %1, 0x400(%0); cache %1, 0x440(%0) \n" \
+ " cache %1, 0x480(%0); cache %1, 0x4c0(%0) \n" \
+ " cache %1, 0x500(%0); cache %1, 0x540(%0) \n" \
+ " cache %1, 0x580(%0); cache %1, 0x5c0(%0) \n" \
+ " cache %1, 0x600(%0); cache %1, 0x640(%0) \n" \
+ " cache %1, 0x680(%0); cache %1, 0x6c0(%0) \n" \
+ " cache %1, 0x700(%0); cache %1, 0x740(%0) \n" \
+ " cache %1, 0x780(%0); cache %1, 0x7c0(%0) \n" \
+ " .set pop \n" \
+ : \
+ : "r" (base), \
+ "i" (op));
+
+#define cache128_unroll32(base,op) \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noreorder \n" \
+ " .set mips3 \n" \
+ " cache %1, 0x000(%0); cache %1, 0x080(%0) \n" \
+ " cache %1, 0x100(%0); cache %1, 0x180(%0) \n" \
+ " cache %1, 0x200(%0); cache %1, 0x280(%0) \n" \
+ " cache %1, 0x300(%0); cache %1, 0x380(%0) \n" \
+ " cache %1, 0x400(%0); cache %1, 0x480(%0) \n" \
+ " cache %1, 0x500(%0); cache %1, 0x580(%0) \n" \
+ " cache %1, 0x600(%0); cache %1, 0x680(%0) \n" \
+ " cache %1, 0x700(%0); cache %1, 0x780(%0) \n" \
+ " cache %1, 0x800(%0); cache %1, 0x880(%0) \n" \
+ " cache %1, 0x900(%0); cache %1, 0x980(%0) \n" \
+ " cache %1, 0xa00(%0); cache %1, 0xa80(%0) \n" \
+ " cache %1, 0xb00(%0); cache %1, 0xb80(%0) \n" \
+ " cache %1, 0xc00(%0); cache %1, 0xc80(%0) \n" \
+ " cache %1, 0xd00(%0); cache %1, 0xd80(%0) \n" \
+ " cache %1, 0xe00(%0); cache %1, 0xe80(%0) \n" \
+ " cache %1, 0xf00(%0); cache %1, 0xf80(%0) \n" \
+ " .set pop \n" \
+ : \
+ : "r" (base), \
+ "i" (op));
+
+/* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */
+#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize) \
+static inline void blast_##pfx##cache##lsize(void) \
+{ \
+ unsigned long start = INDEX_BASE; \
+ unsigned long end = start + current_cpu_data.desc.waysize; \
+ unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \
+ unsigned long ws_end = current_cpu_data.desc.ways << \
+ current_cpu_data.desc.waybit; \
+ unsigned long ws, addr; \
+ \
+ __##pfx##flush_prologue \
+ \
+ for (ws = 0; ws < ws_end; ws += ws_inc) \
+ for (addr = start; addr < end; addr += lsize * 32) \
+ cache##lsize##_unroll32(addr|ws, indexop); \
+ \
+ __##pfx##flush_epilogue \
+} \
+ \
+static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \
+{ \
+ unsigned long start = page; \
+ unsigned long end = page + PAGE_SIZE; \
+ \
+ __##pfx##flush_prologue \
+ \
+ do { \
+ cache##lsize##_unroll32(start, hitop); \
+ start += lsize * 32; \
+ } while (start < end); \
+ \
+ __##pfx##flush_epilogue \
+} \
+ \
+static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \
+{ \
+ unsigned long indexmask = current_cpu_data.desc.waysize - 1; \
+ unsigned long start = INDEX_BASE + (page & indexmask); \
+ unsigned long end = start + PAGE_SIZE; \
+ unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \
+ unsigned long ws_end = current_cpu_data.desc.ways << \
+ current_cpu_data.desc.waybit; \
+ unsigned long ws, addr; \
+ \
+ __##pfx##flush_prologue \
+ \
+ for (ws = 0; ws < ws_end; ws += ws_inc) \
+ for (addr = start; addr < end; addr += lsize * 32) \
+ cache##lsize##_unroll32(addr|ws, indexop); \
+ \
+ __##pfx##flush_epilogue \
+}
+
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64)
+__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
+__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
+
+__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 16)
+__BUILD_BLAST_CACHE(inv_d, dcache, Index_Writeback_Inv_D, Hit_Invalidate_D, 32)
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 16)
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 32)
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 64)
+__BUILD_BLAST_CACHE(inv_s, scache, Index_Writeback_Inv_SD, Hit_Invalidate_SD, 128)
+
+/* build blast_xxx_range, protected_blast_xxx_range */
+#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \
+static inline void prot##blast_##pfx##cache##_range(unsigned long start, \
+ unsigned long end) \
+{ \
+ unsigned long lsize = cpu_##desc##_line_size(); \
+ unsigned long addr = start & ~(lsize - 1); \
+ unsigned long aend = (end - 1) & ~(lsize - 1); \
+ \
+ __##pfx##flush_prologue \
+ \
+ while (1) { \
+ prot##cache_op(hitop, addr); \
+ if (addr == aend) \
+ break; \
+ addr += lsize; \
+ } \
+ \
+ __##pfx##flush_epilogue \
+}
+
+__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_)
+__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_)
+__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_)
+__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, )
+__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, )
+/* blast_inv_dcache_range */
+__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, )
+__BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, )
+
+#endif /* _ASM_R4KCACHE_H */
diff --git a/arch/mips/include/asm/reboot.h b/arch/mips/include/asm/reboot.h
new file mode 100644
index 00000000..e48c0bfa
--- /dev/null
+++ b/arch/mips/include/asm/reboot.h
@@ -0,0 +1,15 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1999, 2001, 06 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_REBOOT_H
+#define _ASM_REBOOT_H
+
+extern void (*_machine_restart)(char *command);
+extern void (*_machine_halt)(void);
+
+#endif /* _ASM_REBOOT_H */
diff --git a/arch/mips/include/asm/reg.h b/arch/mips/include/asm/reg.h
new file mode 100644
index 00000000..910e71a1
--- /dev/null
+++ b/arch/mips/include/asm/reg.h
@@ -0,0 +1,128 @@
+/*
+ * Various register offset definitions for debuggers, core file
+ * examiners and whatnot.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 Ralf Baechle
+ * Copyright (C) 1995, 1999 Silicon Graphics
+ */
+#ifndef __ASM_MIPS_REG_H
+#define __ASM_MIPS_REG_H
+
+
+#if defined(CONFIG_32BIT) || defined(WANT_COMPAT_REG_H)
+
+#define EF_R0 6
+#define EF_R1 7
+#define EF_R2 8
+#define EF_R3 9
+#define EF_R4 10
+#define EF_R5 11
+#define EF_R6 12
+#define EF_R7 13
+#define EF_R8 14
+#define EF_R9 15
+#define EF_R10 16
+#define EF_R11 17
+#define EF_R12 18
+#define EF_R13 19
+#define EF_R14 20
+#define EF_R15 21
+#define EF_R16 22
+#define EF_R17 23
+#define EF_R18 24
+#define EF_R19 25
+#define EF_R20 26
+#define EF_R21 27
+#define EF_R22 28
+#define EF_R23 29
+#define EF_R24 30
+#define EF_R25 31
+
+/*
+ * k0/k1 unsaved
+ */
+#define EF_R26 32
+#define EF_R27 33
+
+#define EF_R28 34
+#define EF_R29 35
+#define EF_R30 36
+#define EF_R31 37
+
+/*
+ * Saved special registers
+ */
+#define EF_LO 38
+#define EF_HI 39
+
+#define EF_CP0_EPC 40
+#define EF_CP0_BADVADDR 41
+#define EF_CP0_STATUS 42
+#define EF_CP0_CAUSE 43
+#define EF_UNUSED0 44
+
+#define EF_SIZE 180
+
+#endif
+
+#if defined(CONFIG_64BIT) && !defined(WANT_COMPAT_REG_H)
+
+#define EF_R0 0
+#define EF_R1 1
+#define EF_R2 2
+#define EF_R3 3
+#define EF_R4 4
+#define EF_R5 5
+#define EF_R6 6
+#define EF_R7 7
+#define EF_R8 8
+#define EF_R9 9
+#define EF_R10 10
+#define EF_R11 11
+#define EF_R12 12
+#define EF_R13 13
+#define EF_R14 14
+#define EF_R15 15
+#define EF_R16 16
+#define EF_R17 17
+#define EF_R18 18
+#define EF_R19 19
+#define EF_R20 20
+#define EF_R21 21
+#define EF_R22 22
+#define EF_R23 23
+#define EF_R24 24
+#define EF_R25 25
+
+/*
+ * k0/k1 unsaved
+ */
+#define EF_R26 26
+#define EF_R27 27
+
+
+#define EF_R28 28
+#define EF_R29 29
+#define EF_R30 30
+#define EF_R31 31
+
+/*
+ * Saved special registers
+ */
+#define EF_LO 32
+#define EF_HI 33
+
+#define EF_CP0_EPC 34
+#define EF_CP0_BADVADDR 35
+#define EF_CP0_STATUS 36
+#define EF_CP0_CAUSE 37
+
+#define EF_SIZE 304 /* size in bytes */
+
+#endif /* CONFIG_64BIT */
+
+#endif /* __ASM_MIPS_REG_H */
diff --git a/arch/mips/include/asm/regdef.h b/arch/mips/include/asm/regdef.h
new file mode 100644
index 00000000..7c8ecb6b
--- /dev/null
+++ b/arch/mips/include/asm/regdef.h
@@ -0,0 +1,100 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1985 MIPS Computer Systems, Inc.
+ * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_REGDEF_H
+#define _ASM_REGDEF_H
+
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
+ * Symbolic register names for 32 bit ABI
+ */
+#define zero $0 /* wired zero */
+#define AT $1 /* assembler temp - uppercase because of ".set at" */
+#define v0 $2 /* return value */
+#define v1 $3
+#define a0 $4 /* argument registers */
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8 /* caller saved */
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define s0 $16 /* callee saved */
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24 /* caller saved */
+#define t9 $25
+#define jp $25 /* PIC jump register */
+#define k0 $26 /* kernel scratch */
+#define k1 $27
+#define gp $28 /* global pointer */
+#define sp $29 /* stack pointer */
+#define fp $30 /* frame pointer */
+#define s8 $30 /* same like fp! */
+#define ra $31 /* return address */
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
+
+#define zero $0 /* wired zero */
+#define AT $at /* assembler temp - uppercase because of ".set at" */
+#define v0 $2 /* return value - caller saved */
+#define v1 $3
+#define a0 $4 /* argument registers */
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define a4 $8 /* arg reg 64 bit; caller saved in 32 bit */
+#define ta0 $8
+#define a5 $9
+#define ta1 $9
+#define a6 $10
+#define ta2 $10
+#define a7 $11
+#define ta3 $11
+#define t0 $12 /* caller saved */
+#define t1 $13
+#define t2 $14
+#define t3 $15
+#define s0 $16 /* callee saved */
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24 /* caller saved */
+#define t9 $25 /* callee address for PIC/temp */
+#define jp $25 /* PIC jump register */
+#define k0 $26 /* kernel temporary */
+#define k1 $27
+#define gp $28 /* global pointer - caller saved for PIC */
+#define sp $29 /* stack pointer */
+#define fp $30 /* frame pointer */
+#define s8 $30 /* callee saved */
+#define ra $31 /* return address */
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
+
+#endif /* _ASM_REGDEF_H */
diff --git a/arch/mips/include/asm/resource.h b/arch/mips/include/asm/resource.h
new file mode 100644
index 00000000..87cb3085
--- /dev/null
+++ b/arch/mips/include/asm/resource.h
@@ -0,0 +1,35 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_RESOURCE_H
+#define _ASM_RESOURCE_H
+
+
+/*
+ * These five resource limit IDs have a MIPS/Linux-specific ordering,
+ * the rest comes from the generic header:
+ */
+#define RLIMIT_NOFILE 5 /* max number of open files */
+#define RLIMIT_AS 6 /* address space limit */
+#define RLIMIT_RSS 7 /* max resident set size */
+#define RLIMIT_NPROC 8 /* max number of processes */
+#define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway,
+ * but we keep the old value on MIPS32,
+ * for compatibility:
+ */
+#ifdef CONFIG_32BIT
+# define RLIM_INFINITY 0x7fffffffUL
+#endif
+
+#include <asm-generic/resource.h>
+
+#endif /* _ASM_RESOURCE_H */
diff --git a/arch/mips/include/asm/rm9k-ocd.h b/arch/mips/include/asm/rm9k-ocd.h
new file mode 100644
index 00000000..b0b80d9e
--- /dev/null
+++ b/arch/mips/include/asm/rm9k-ocd.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2004 by Basler Vision Technologies AG
+ * Author: Thomas Koeller <thomas.koeller@baslerweb.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#if !defined(_ASM_RM9K_OCD_H)
+#define _ASM_RM9K_OCD_H
+
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+extern volatile void __iomem * const ocd_base;
+extern volatile void __iomem * const titan_base;
+
+#define ocd_addr(__x__) (ocd_base + (__x__))
+#define titan_addr(__x__) (titan_base + (__x__))
+#define scram_addr(__x__) (scram_base + (__x__))
+
+/* OCD register access */
+#define ocd_readl(__offs__) __raw_readl(ocd_addr(__offs__))
+#define ocd_readw(__offs__) __raw_readw(ocd_addr(__offs__))
+#define ocd_readb(__offs__) __raw_readb(ocd_addr(__offs__))
+#define ocd_writel(__val__, __offs__) \
+ __raw_writel((__val__), ocd_addr(__offs__))
+#define ocd_writew(__val__, __offs__) \
+ __raw_writew((__val__), ocd_addr(__offs__))
+#define ocd_writeb(__val__, __offs__) \
+ __raw_writeb((__val__), ocd_addr(__offs__))
+
+/* TITAN register access - 32 bit-wide only */
+#define titan_readl(__offs__) __raw_readl(titan_addr(__offs__))
+#define titan_writel(__val__, __offs__) \
+ __raw_writel((__val__), titan_addr(__offs__))
+
+/* Protect access to shared TITAN registers */
+extern spinlock_t titan_lock;
+extern int titan_irqflags;
+#define lock_titan_regs() spin_lock_irqsave(&titan_lock, titan_irqflags)
+#define unlock_titan_regs() spin_unlock_irqrestore(&titan_lock, titan_irqflags)
+
+#endif /* !defined(_ASM_RM9K_OCD_H) */
diff --git a/arch/mips/include/asm/rtlx.h b/arch/mips/include/asm/rtlx.h
new file mode 100644
index 00000000..4ca3063e
--- /dev/null
+++ b/arch/mips/include/asm/rtlx.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ */
+
+#ifndef __ASM_RTLX_H_
+#define __ASM_RTLX_H_
+
+#include <irq.h>
+
+#define LX_NODE_BASE 10
+
+#define MIPS_CPU_RTLX_IRQ 0
+
+#define RTLX_VERSION 2
+#define RTLX_xID 0x12345600
+#define RTLX_ID (RTLX_xID | RTLX_VERSION)
+#define RTLX_CHANNELS 8
+
+#define RTLX_CHANNEL_STDIO 0
+#define RTLX_CHANNEL_DBG 1
+#define RTLX_CHANNEL_SYSIO 2
+
+extern int rtlx_open(int index, int can_sleep);
+extern int rtlx_release(int index);
+extern ssize_t rtlx_read(int index, void __user *buff, size_t count);
+extern ssize_t rtlx_write(int index, const void __user *buffer, size_t count);
+extern unsigned int rtlx_read_poll(int index, int can_sleep);
+extern unsigned int rtlx_write_poll(int index);
+
+enum rtlx_state {
+ RTLX_STATE_UNUSED = 0,
+ RTLX_STATE_INITIALISED,
+ RTLX_STATE_REMOTE_READY,
+ RTLX_STATE_OPENED
+};
+
+#define RTLX_BUFFER_SIZE 2048
+
+/* each channel supports read and write.
+ linux (vpe0) reads lx_buffer and writes rt_buffer
+ SP (vpe1) reads rt_buffer and writes lx_buffer
+*/
+struct rtlx_channel {
+ enum rtlx_state rt_state;
+ enum rtlx_state lx_state;
+
+ int buffer_size;
+
+ /* read and write indexes per buffer */
+ int rt_write, rt_read;
+ char *rt_buffer;
+
+ int lx_write, lx_read;
+ char *lx_buffer;
+};
+
+struct rtlx_info {
+ unsigned long id;
+ enum rtlx_state state;
+
+ struct rtlx_channel channel[RTLX_CHANNELS];
+};
+
+#endif /* __ASM_RTLX_H_ */
diff --git a/arch/mips/include/asm/scatterlist.h b/arch/mips/include/asm/scatterlist.h
new file mode 100644
index 00000000..7ee0e646
--- /dev/null
+++ b/arch/mips/include/asm/scatterlist.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_SCATTERLIST_H
+#define __ASM_SCATTERLIST_H
+
+#include <asm-generic/scatterlist.h>
+
+#endif /* __ASM_SCATTERLIST_H */
diff --git a/arch/mips/include/asm/seccomp.h b/arch/mips/include/asm/seccomp.h
new file mode 100644
index 00000000..ae6306eb
--- /dev/null
+++ b/arch/mips/include/asm/seccomp.h
@@ -0,0 +1,32 @@
+#ifndef __ASM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+/*
+ * Kludge alert:
+ *
+ * The generic seccomp code currently allows only a single compat ABI. Until
+ * this is fixed we priorize O32 as the compat ABI over N32.
+ */
+#ifdef CONFIG_MIPS32_O32
+
+#define __NR_seccomp_read_32 4003
+#define __NR_seccomp_write_32 4004
+#define __NR_seccomp_exit_32 4001
+#define __NR_seccomp_sigreturn_32 4193 /* rt_sigreturn */
+
+#elif defined(CONFIG_MIPS32_N32)
+
+#define __NR_seccomp_read_32 6000
+#define __NR_seccomp_write_32 6001
+#define __NR_seccomp_exit_32 6058
+#define __NR_seccomp_sigreturn_32 6211 /* rt_sigreturn */
+
+#endif /* CONFIG_MIPS32_O32 */
+
+#endif /* __ASM_SECCOMP_H */
diff --git a/arch/mips/include/asm/sections.h b/arch/mips/include/asm/sections.h
new file mode 100644
index 00000000..b7e37262
--- /dev/null
+++ b/arch/mips/include/asm/sections.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SECTIONS_H
+#define _ASM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif /* _ASM_SECTIONS_H */
diff --git a/arch/mips/include/asm/segment.h b/arch/mips/include/asm/segment.h
new file mode 100644
index 00000000..92ac001f
--- /dev/null
+++ b/arch/mips/include/asm/segment.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif /* _ASM_SEGMENT_H */
diff --git a/arch/mips/include/asm/sembuf.h b/arch/mips/include/asm/sembuf.h
new file mode 100644
index 00000000..7281a4de
--- /dev/null
+++ b/arch/mips/include/asm/sembuf.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/*
+ * The semid64_ds structure for the MIPS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 64-bit values
+ */
+
+struct semid64_ds {
+ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t sem_otime; /* last semop time */
+ __kernel_time_t sem_ctime; /* last change time */
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+#endif /* _ASM_SEMBUF_H */
diff --git a/arch/mips/include/asm/serial.h b/arch/mips/include/asm/serial.h
new file mode 100644
index 00000000..a0cb0caf
--- /dev/null
+++ b/arch/mips/include/asm/serial.h
@@ -0,0 +1 @@
+#include <asm-generic/serial.h>
diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h
new file mode 100644
index 00000000..50511aac
--- /dev/null
+++ b/arch/mips/include/asm/setup.h
@@ -0,0 +1,10 @@
+#ifndef _MIPS_SETUP_H
+#define _MIPS_SETUP_H
+
+#define COMMAND_LINE_SIZE 4096
+
+#ifdef __KERNEL__
+extern void setup_early_printk(void);
+#endif /* __KERNEL__ */
+
+#endif /* __SETUP_H */
diff --git a/arch/mips/include/asm/sgi/gio.h b/arch/mips/include/asm/sgi/gio.h
new file mode 100644
index 00000000..889cf028
--- /dev/null
+++ b/arch/mips/include/asm/sgi/gio.h
@@ -0,0 +1,86 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * gio.h: Definitions for SGI GIO bus
+ *
+ * Copyright (C) 2002 Ladislav Michl
+ */
+
+#ifndef _SGI_GIO_H
+#define _SGI_GIO_H
+
+/*
+ * GIO bus addresses
+ *
+ * The Indigo and Indy have two GIO bus connectors. Indigo2 (all models) have
+ * three physical connectors, but only two slots, GFX and EXP0.
+ *
+ * There is 10MB of GIO address space for GIO64 slot devices
+ * slot# slot type address range size
+ * ----- --------- ----------------------- -----
+ * 0 GFX 0x1f000000 - 0x1f3fffff 4MB
+ * 1 EXP0 0x1f400000 - 0x1f5fffff 2MB
+ * 2 EXP1 0x1f600000 - 0x1f9fffff 4MB
+ *
+ * There are un-slotted devices, HPC, I/O and misc devices, which are grouped
+ * into the HPC address space.
+ * - MISC 0x1fb00000 - 0x1fbfffff 1MB
+ *
+ * Following space is reserved and unused
+ * - RESERVED 0x18000000 - 0x1effffff 112MB
+ *
+ * GIO bus IDs
+ *
+ * Each GIO bus device identifies itself to the system by answering a
+ * read with an "ID" value. IDs are either 8 or 32 bits long. IDs less
+ * than 128 are 8 bits long, with the most significant 24 bits read from
+ * the slot undefined.
+ *
+ * 32-bit IDs are divided into
+ * bits 0:6 the product ID; ranges from 0x00 to 0x7F.
+ * bit 7 0=GIO Product ID is 8 bits wide
+ * 1=GIO Product ID is 32 bits wide.
+ * bits 8:15 manufacturer version for the product.
+ * bit 16 0=GIO32 and GIO32-bis, 1=GIO64.
+ * bit 17 0=no ROM present
+ * 1=ROM present on this board AND next three words
+ * space define the ROM.
+ * bits 18:31 up to manufacturer.
+ *
+ * IDs above 0x50/0xd0 are of 3rd party boards.
+ *
+ * 8-bit IDs
+ * 0x01 XPI low cost FDDI
+ * 0x02 GTR TokenRing
+ * 0x04 Synchronous ISDN
+ * 0x05 ATM board [*]
+ * 0x06 Canon Interface
+ * 0x07 16 bit SCSI Card [*]
+ * 0x08 JPEG (Double Wide)
+ * 0x09 JPEG (Single Wide)
+ * 0x0a XPI mez. FDDI device 0
+ * 0x0b XPI mez. FDDI device 1
+ * 0x0c SMPTE 259M Video [*]
+ * 0x0d Babblefish Compression [*]
+ * 0x0e E-Plex 8-port Ethernet
+ * 0x30 Lyon Lamb IVAS
+ * 0xb8 GIO 100BaseTX Fast Ethernet (gfe)
+ *
+ * [*] Device provide 32-bit ID.
+ *
+ */
+
+#define GIO_ID(x) (x & 0x7f)
+#define GIO_32BIT_ID 0x80
+#define GIO_REV(x) ((x >> 8) & 0xff)
+#define GIO_64BIT_IFACE 0x10000
+#define GIO_ROM_PRESENT 0x20000
+#define GIO_VENDOR_CODE(x) ((x >> 18) & 0x3fff)
+
+#define GIO_SLOT_GFX_BASE 0x1f000000
+#define GIO_SLOT_EXP0_BASE 0x1f400000
+#define GIO_SLOT_EXP1_BASE 0x1f600000
+
+#endif /* _SGI_GIO_H */
diff --git a/arch/mips/include/asm/sgi/hpc3.h b/arch/mips/include/asm/sgi/hpc3.h
new file mode 100644
index 00000000..c4729f53
--- /dev/null
+++ b/arch/mips/include/asm/sgi/hpc3.h
@@ -0,0 +1,317 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * hpc3.h: Definitions for SGI HPC3 controller
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1998 Ralf Baechle
+ */
+
+#ifndef _SGI_HPC3_H
+#define _SGI_HPC3_H
+
+#include <linux/types.h>
+#include <asm/page.h>
+
+/* An HPC DMA descriptor. */
+struct hpc_dma_desc {
+ u32 pbuf; /* physical address of data buffer */
+ u32 cntinfo; /* counter and info bits */
+#define HPCDMA_EOX 0x80000000 /* last desc in chain for tx */
+#define HPCDMA_EOR 0x80000000 /* last desc in chain for rx */
+#define HPCDMA_EOXP 0x40000000 /* end of packet for tx */
+#define HPCDMA_EORP 0x40000000 /* end of packet for rx */
+#define HPCDMA_XIE 0x20000000 /* irq generated when at end of this desc */
+#define HPCDMA_XIU 0x01000000 /* Tx buffer in use by CPU. */
+#define HPCDMA_EIPC 0x00ff0000 /* SEEQ ethernet special xternal bytecount */
+#define HPCDMA_ETXD 0x00008000 /* set to one by HPC when packet tx'd */
+#define HPCDMA_OWN 0x00004000 /* Denotes ring buffer ownership on rx */
+#define HPCDMA_BCNT 0x00003fff /* size in bytes of this dma buffer */
+
+ u32 pnext; /* paddr of next hpc_dma_desc if any */
+};
+
+/* The set of regs for each HPC3 PBUS DMA channel. */
+struct hpc3_pbus_dmacregs {
+ volatile u32 pbdma_bptr; /* pbus dma channel buffer ptr */
+ volatile u32 pbdma_dptr; /* pbus dma channel desc ptr */
+ u32 _unused0[0x1000/4 - 2]; /* padding */
+ volatile u32 pbdma_ctrl; /* pbus dma channel control register has
+ * copletely different meaning for read
+ * compared with write */
+ /* read */
+#define HPC3_PDMACTRL_INT 0x00000001 /* interrupt (cleared after read) */
+#define HPC3_PDMACTRL_ISACT 0x00000002 /* channel active */
+ /* write */
+#define HPC3_PDMACTRL_SEL 0x00000002 /* little endian transfer */
+#define HPC3_PDMACTRL_RCV 0x00000004 /* direction is receive */
+#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */
+#define HPC3_PDMACTRL_ACT 0x00000010 /* start dma transfer */
+#define HPC3_PDMACTRL_LD 0x00000020 /* load enable for ACT */
+#define HPC3_PDMACTRL_RT 0x00000040 /* Use realtime GIO bus servicing */
+#define HPC3_PDMACTRL_HW 0x0000ff00 /* DMA High-water mark */
+#define HPC3_PDMACTRL_FB 0x003f0000 /* Ptr to beginning of fifo */
+#define HPC3_PDMACTRL_FE 0x3f000000 /* Ptr to end of fifo */
+
+ u32 _unused1[0x1000/4 - 1]; /* padding */
+};
+
+/* The HPC3 SCSI registers, this does not include external ones. */
+struct hpc3_scsiregs {
+ volatile u32 cbptr; /* current dma buffer ptr, diagnostic use only */
+ volatile u32 ndptr; /* next dma descriptor ptr */
+ u32 _unused0[0x1000/4 - 2]; /* padding */
+ volatile u32 bcd; /* byte count info */
+#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */
+#define HPC3_SBCD_XIE 0x00004000 /* Send IRQ when done with cur buf */
+#define HPC3_SBCD_EOX 0x00008000 /* Indicates this is last buf in chain */
+
+ volatile u32 ctrl; /* control register */
+#define HPC3_SCTRL_IRQ 0x01 /* IRQ asserted, either dma done or parity */
+#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */
+#define HPC3_SCTRL_DIR 0x04 /* DMA direction, 1=dev2mem 0=mem2dev */
+#define HPC3_SCTRL_FLUSH 0x08 /* Tells HPC3 to flush scsi fifos */
+#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */
+#define HPC3_SCTRL_AMASK 0x20 /* DMA active inhibits PIO */
+#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */
+#define HPC3_SCTRL_PERR 0x80 /* Bad parity on HPC3 iface to scsi controller */
+
+ volatile u32 gfptr; /* current GIO fifo ptr */
+ volatile u32 dfptr; /* current device fifo ptr */
+ volatile u32 dconfig; /* DMA configuration register */
+#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */
+#define HPC3_SDCFG_D1 0x00006 /* Cycles to spend in D1 state */
+#define HPC3_SDCFG_D2 0x00038 /* Cycles to spend in D2 state */
+#define HPC3_SDCFG_D3 0x001c0 /* Cycles to spend in D3 state */
+#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */
+#define HPC3_SDCFG_HW 0x01000 /* Enable 16-bit halfword DMA accesses to scsi */
+#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */
+#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */
+#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */
+#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */
+
+ volatile u32 pconfig; /* PIO configuration register */
+#define HPC3_SPCFG_P3 0x0003 /* Cycles to spend in P3 state */
+#define HPC3_SPCFG_P2W 0x001c /* Cycles to spend in P2 state for writes */
+#define HPC3_SPCFG_P2R 0x01e0 /* Cycles to spend in P2 state for reads */
+#define HPC3_SPCFG_P1 0x0e00 /* Cycles to spend in P1 state */
+#define HPC3_SPCFG_HW 0x1000 /* Enable 16-bit halfword PIO accesses to scsi */
+#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */
+#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */
+#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */
+
+ u32 _unused1[0x1000/4 - 6]; /* padding */
+};
+
+/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */
+struct hpc3_ethregs {
+ /* Receiver registers. */
+ volatile u32 rx_cbptr; /* current dma buffer ptr, diagnostic use only */
+ volatile u32 rx_ndptr; /* next dma descriptor ptr */
+ u32 _unused0[0x1000/4 - 2]; /* padding */
+ volatile u32 rx_bcd; /* byte count info */
+#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */
+#define HPC3_ERXBCD_XIE 0x20000000 /* HPC3 interrupts cpu at end of this buf */
+#define HPC3_ERXBCD_EOX 0x80000000 /* flags this as end of descriptor chain */
+
+ volatile u32 rx_ctrl; /* control register */
+#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */
+#define HPC3_ERXCTRL_STAT6 0x00000040 /* Rdonly irq status */
+#define HPC3_ERXCTRL_STAT7 0x00000080 /* Rdonlt old/new status bit from Seeq */
+#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */
+#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */
+#define HPC3_ERXCTRL_AMASK 0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */
+#define HPC3_ERXCTRL_RBO 0x00000800 /* Receive buffer overflow if set to 1 */
+
+ volatile u32 rx_gfptr; /* current GIO fifo ptr */
+ volatile u32 rx_dfptr; /* current device fifo ptr */
+ u32 _unused1; /* padding */
+ volatile u32 reset; /* reset register */
+#define HPC3_ERST_CRESET 0x1 /* Reset dma channel and external controller */
+#define HPC3_ERST_CLRIRQ 0x2 /* Clear channel interrupt */
+#define HPC3_ERST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */
+
+ volatile u32 dconfig; /* DMA configuration register */
+#define HPC3_EDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */
+#define HPC3_EDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */
+#define HPC3_EDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */
+#define HPC3_EDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
+#define HPC3_EDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
+#define HPC3_EDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */
+#define HPC3_EDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */
+#define HPC3_EDCFG_PTO 0x30000 /* Programmed timeout value for above two */
+
+ volatile u32 pconfig; /* PIO configuration register */
+#define HPC3_EPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */
+#define HPC3_EPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */
+#define HPC3_EPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */
+#define HPC3_EPCFG_TST 0x1000 /* Diagnistic ram test feature bit */
+
+ u32 _unused2[0x1000/4 - 8]; /* padding */
+
+ /* Transmitter registers. */
+ volatile u32 tx_cbptr; /* current dma buffer ptr, diagnostic use only */
+ volatile u32 tx_ndptr; /* next dma descriptor ptr */
+ u32 _unused3[0x1000/4 - 2]; /* padding */
+ volatile u32 tx_bcd; /* byte count info */
+#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */
+#define HPC3_ETXBCD_ESAMP 0x10000000 /* if set, too late to add descriptor */
+#define HPC3_ETXBCD_XIE 0x20000000 /* Interrupt cpu at end of cur desc */
+#define HPC3_ETXBCD_EOP 0x40000000 /* Last byte of cur buf is end of packet */
+#define HPC3_ETXBCD_EOX 0x80000000 /* This buf is the end of desc chain */
+
+ volatile u32 tx_ctrl; /* control register */
+#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */
+#define HPC3_ETXCTRL_STAT4 0x00000010 /* Indicate late collision occurred */
+#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */
+#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* DMA channel endian mode, 1=little 0=big */
+#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */
+#define HPC3_ETXCTRL_AMASK 0x00000400 /* Indicates ACTIVE inhibits PIO's */
+
+ volatile u32 tx_gfptr; /* current GIO fifo ptr */
+ volatile u32 tx_dfptr; /* current device fifo ptr */
+ u32 _unused4[0x1000/4 - 4]; /* padding */
+};
+
+struct hpc3_regs {
+ /* First regs for the PBUS 8 dma channels. */
+ struct hpc3_pbus_dmacregs pbdma[8];
+
+ /* Now the HPC scsi registers, we get two scsi reg sets. */
+ struct hpc3_scsiregs scsi_chan0, scsi_chan1;
+
+ /* The SEEQ hpc3 ethernet dma/control registers. */
+ struct hpc3_ethregs ethregs;
+
+ /* Here are where the hpc3 fifo's can be directly accessed
+ * via PIO accesses. Under normal operation we never stick
+ * our grubby paws in here so it's just padding. */
+ u32 _unused0[0x18000/4];
+
+ /* HPC3 irq status regs. Due to a peculiar bug you need to
+ * look at two different register addresses to get at all of
+ * the status bits. The first reg can only reliably report
+ * bits 4:0 of the status, and the second reg can only
+ * reliably report bits 9:5 of the hpc3 irq status. I told
+ * you it was a peculiar bug. ;-)
+ */
+ volatile u32 istat0; /* Irq status, only bits <4:0> reliable. */
+#define HPC3_ISTAT_PBIMASK 0x0ff /* irq bits for pbus devs 0 --> 7 */
+#define HPC3_ISTAT_SC0MASK 0x100 /* irq bit for scsi channel 0 */
+#define HPC3_ISTAT_SC1MASK 0x200 /* irq bit for scsi channel 1 */
+
+ volatile u32 gio_misc; /* GIO misc control bits. */
+#define HPC3_GIOMISC_ERTIME 0x1 /* Enable external timer real time. */
+#define HPC3_GIOMISC_DENDIAN 0x2 /* dma descriptor endian, 1=lit 0=big */
+
+ u32 eeprom; /* EEPROM data reg. */
+#define HPC3_EEPROM_EPROT 0x01 /* Protect register enable */
+#define HPC3_EEPROM_CSEL 0x02 /* Chip select */
+#define HPC3_EEPROM_ECLK 0x04 /* EEPROM clock */
+#define HPC3_EEPROM_DATO 0x08 /* Data out */
+#define HPC3_EEPROM_DATI 0x10 /* Data in */
+
+ volatile u32 istat1; /* Irq status, only bits <9:5> reliable. */
+ volatile u32 bestat; /* Bus error interrupt status reg. */
+#define HPC3_BESTAT_BLMASK 0x000ff /* Bus lane where bad parity occurred */
+#define HPC3_BESTAT_CTYPE 0x00100 /* Bus cycle type, 0=PIO 1=DMA */
+#define HPC3_BESTAT_PIDSHIFT 9
+#define HPC3_BESTAT_PIDMASK 0x3f700 /* DMA channel parity identifier */
+
+ u32 _unused1[0x14000/4 - 5]; /* padding */
+
+ /* Now direct PIO per-HPC3 peripheral access to external regs. */
+ volatile u32 scsi0_ext[256]; /* SCSI channel 0 external regs */
+ u32 _unused2[0x7c00/4];
+ volatile u32 scsi1_ext[256]; /* SCSI channel 1 external regs */
+ u32 _unused3[0x7c00/4];
+ volatile u32 eth_ext[320]; /* Ethernet external registers */
+ u32 _unused4[0x3b00/4];
+
+ /* Per-peripheral device external registers and DMA/PIO control. */
+ volatile u32 pbus_extregs[16][256];
+ volatile u32 pbus_dmacfg[8][128];
+ /* Cycles to spend in D3 for reads */
+#define HPC3_DMACFG_D3R_MASK 0x00000001
+#define HPC3_DMACFG_D3R_SHIFT 0
+ /* Cycles to spend in D4 for reads */
+#define HPC3_DMACFG_D4R_MASK 0x0000001e
+#define HPC3_DMACFG_D4R_SHIFT 1
+ /* Cycles to spend in D5 for reads */
+#define HPC3_DMACFG_D5R_MASK 0x000001e0
+#define HPC3_DMACFG_D5R_SHIFT 5
+ /* Cycles to spend in D3 for writes */
+#define HPC3_DMACFG_D3W_MASK 0x00000200
+#define HPC3_DMACFG_D3W_SHIFT 9
+ /* Cycles to spend in D4 for writes */
+#define HPC3_DMACFG_D4W_MASK 0x00003c00
+#define HPC3_DMACFG_D4W_SHIFT 10
+ /* Cycles to spend in D5 for writes */
+#define HPC3_DMACFG_D5W_MASK 0x0003c000
+#define HPC3_DMACFG_D5W_SHIFT 14
+ /* Enable 16-bit DMA access mode */
+#define HPC3_DMACFG_DS16 0x00040000
+ /* Places halfwords on high 16 bits of bus */
+#define HPC3_DMACFG_EVENHI 0x00080000
+ /* Make this device real time */
+#define HPC3_DMACFG_RTIME 0x00200000
+ /* 5 bit burst count for DMA device */
+#define HPC3_DMACFG_BURST_MASK 0x07c00000
+#define HPC3_DMACFG_BURST_SHIFT 22
+ /* Use live pbus_dreq unsynchronized signal */
+#define HPC3_DMACFG_DRQLIVE 0x08000000
+ volatile u32 pbus_piocfg[16][64];
+ /* Cycles to spend in P2 state for reads */
+#define HPC3_PIOCFG_P2R_MASK 0x00001
+#define HPC3_PIOCFG_P2R_SHIFT 0
+ /* Cycles to spend in P3 state for reads */
+#define HPC3_PIOCFG_P3R_MASK 0x0001e
+#define HPC3_PIOCFG_P3R_SHIFT 1
+ /* Cycles to spend in P4 state for reads */
+#define HPC3_PIOCFG_P4R_MASK 0x001e0
+#define HPC3_PIOCFG_P4R_SHIFT 5
+ /* Cycles to spend in P2 state for writes */
+#define HPC3_PIOCFG_P2W_MASK 0x00200
+#define HPC3_PIOCFG_P2W_SHIFT 9
+ /* Cycles to spend in P3 state for writes */
+#define HPC3_PIOCFG_P3W_MASK 0x03c00
+#define HPC3_PIOCFG_P3W_SHIFT 10
+ /* Cycles to spend in P4 state for writes */
+#define HPC3_PIOCFG_P4W_MASK 0x3c000
+#define HPC3_PIOCFG_P4W_SHIFT 14
+ /* Enable 16-bit PIO accesses */
+#define HPC3_PIOCFG_DS16 0x40000
+ /* Place even address bits in bits <15:8> */
+#define HPC3_PIOCFG_EVENHI 0x80000
+
+ /* PBUS PROM control regs. */
+ volatile u32 pbus_promwe; /* PROM write enable register */
+#define HPC3_PROM_WENAB 0x1 /* Enable writes to the PROM */
+
+ u32 _unused5[0x0800/4 - 1];
+ volatile u32 pbus_promswap; /* Chip select swap reg */
+#define HPC3_PROM_SWAP 0x1 /* invert GIO addr bit to select prom0 or prom1 */
+
+ u32 _unused6[0x0800/4 - 1];
+ volatile u32 pbus_gout; /* PROM general purpose output reg */
+#define HPC3_PROM_STAT 0x1 /* General purpose status bit in gout */
+
+ u32 _unused7[0x1000/4 - 1];
+ volatile u32 rtcregs[14]; /* Dallas clock registers */
+ u32 _unused8[50];
+ volatile u32 bbram[8192-50-14]; /* Battery backed ram */
+};
+
+/*
+ * It is possible to have two HPC3's within the address space on
+ * one machine, though only having one is more likely on an Indy.
+ */
+extern struct hpc3_regs *hpc3c0, *hpc3c1;
+#define HPC3_CHIP0_BASE 0x1fb80000 /* physical */
+#define HPC3_CHIP1_BASE 0x1fb00000 /* physical */
+
+extern void sgihpc_init(void);
+
+#endif /* _SGI_HPC3_H */
diff --git a/arch/mips/include/asm/sgi/ioc.h b/arch/mips/include/asm/sgi/ioc.h
new file mode 100644
index 00000000..380347b6
--- /dev/null
+++ b/arch/mips/include/asm/sgi/ioc.h
@@ -0,0 +1,200 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * ioc.h: Definitions for SGI I/O Controller
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle
+ * Copyright (C) 2001, 2003 Ladislav Michl
+ */
+
+#ifndef _SGI_IOC_H
+#define _SGI_IOC_H
+
+#include <linux/types.h>
+#include <asm/sgi/pi1.h>
+
+/*
+ * All registers are 8-bit wide aligned on 32-bit boundary. Bad things
+ * happen if you try word access them. You have been warned.
+ */
+
+struct sgioc_uart_regs {
+ u8 _ctrl1[3];
+ volatile u8 ctrl1;
+ u8 _data1[3];
+ volatile u8 data1;
+ u8 _ctrl2[3];
+ volatile u8 ctrl2;
+ u8 _data2[3];
+ volatile u8 data2;
+};
+
+struct sgioc_keyb_regs {
+ u8 _data[3];
+ volatile u8 data;
+ u8 _command[3];
+ volatile u8 command;
+};
+
+struct sgint_regs {
+ u8 _istat0[3];
+ volatile u8 istat0; /* Interrupt status zero */
+#define SGINT_ISTAT0_FFULL 0x01
+#define SGINT_ISTAT0_SCSI0 0x02
+#define SGINT_ISTAT0_SCSI1 0x04
+#define SGINT_ISTAT0_ENET 0x08
+#define SGINT_ISTAT0_GFXDMA 0x10
+#define SGINT_ISTAT0_PPORT 0x20
+#define SGINT_ISTAT0_HPC2 0x40
+#define SGINT_ISTAT0_LIO2 0x80
+ u8 _imask0[3];
+ volatile u8 imask0; /* Interrupt mask zero */
+ u8 _istat1[3];
+ volatile u8 istat1; /* Interrupt status one */
+#define SGINT_ISTAT1_ISDNI 0x01
+#define SGINT_ISTAT1_PWR 0x02
+#define SGINT_ISTAT1_ISDNH 0x04
+#define SGINT_ISTAT1_LIO3 0x08
+#define SGINT_ISTAT1_HPC3 0x10
+#define SGINT_ISTAT1_AFAIL 0x20
+#define SGINT_ISTAT1_VIDEO 0x40
+#define SGINT_ISTAT1_GIO2 0x80
+ u8 _imask1[3];
+ volatile u8 imask1; /* Interrupt mask one */
+ u8 _vmeistat[3];
+ volatile u8 vmeistat; /* VME interrupt status */
+ u8 _cmeimask0[3];
+ volatile u8 cmeimask0; /* VME interrupt mask zero */
+ u8 _cmeimask1[3];
+ volatile u8 cmeimask1; /* VME interrupt mask one */
+ u8 _cmepol[3];
+ volatile u8 cmepol; /* VME polarity */
+ u8 _tclear[3];
+ volatile u8 tclear;
+ u8 _errstat[3];
+ volatile u8 errstat; /* Error status reg, reserved on INT2 */
+ u32 _unused0[2];
+ u8 _tcnt0[3];
+ volatile u8 tcnt0; /* counter 0 */
+ u8 _tcnt1[3];
+ volatile u8 tcnt1; /* counter 1 */
+ u8 _tcnt2[3];
+ volatile u8 tcnt2; /* counter 2 */
+ u8 _tcword[3];
+ volatile u8 tcword; /* control word */
+#define SGINT_TCWORD_BCD 0x01 /* Use BCD mode for counters */
+#define SGINT_TCWORD_MMASK 0x0e /* Mode bitmask. */
+#define SGINT_TCWORD_MITC 0x00 /* IRQ on terminal count (doesn't work) */
+#define SGINT_TCWORD_MOS 0x02 /* One-shot IRQ mode. */
+#define SGINT_TCWORD_MRGEN 0x04 /* Normal rate generation */
+#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */
+#define SGINT_TCWORD_MSWST 0x08 /* Software strobe */
+#define SGINT_TCWORD_MHWST 0x0a /* Hardware strobe */
+#define SGINT_TCWORD_CMASK 0x30 /* Command mask */
+#define SGINT_TCWORD_CLAT 0x00 /* Latch command */
+#define SGINT_TCWORD_CLSB 0x10 /* LSB read/write */
+#define SGINT_TCWORD_CMSB 0x20 /* MSB read/write */
+#define SGINT_TCWORD_CALL 0x30 /* Full counter read/write */
+#define SGINT_TCWORD_CNT0 0x00 /* Select counter zero */
+#define SGINT_TCWORD_CNT1 0x40 /* Select counter one */
+#define SGINT_TCWORD_CNT2 0x80 /* Select counter two */
+#define SGINT_TCWORD_CRBCK 0xc0 /* Readback command */
+};
+
+/*
+ * The timer is the good old 8254. Unlike in PCs it's clocked at exactly 1MHz
+ */
+#define SGINT_TIMER_CLOCK 1000000
+
+/*
+ * This is the constant we're using for calibrating the counter.
+ */
+#define SGINT_TCSAMP_COUNTER ((SGINT_TIMER_CLOCK / HZ) + 255)
+
+/* We need software copies of these because they are write only. */
+extern u8 sgi_ioc_reset, sgi_ioc_write;
+
+struct sgioc_regs {
+ struct pi1_regs pport;
+ u32 _unused0[2];
+ struct sgioc_uart_regs uart;
+ struct sgioc_keyb_regs kbdmouse;
+ u8 _gcsel[3];
+ volatile u8 gcsel;
+ u8 _genctrl[3];
+ volatile u8 genctrl;
+ u8 _panel[3];
+ volatile u8 panel;
+#define SGIOC_PANEL_POWERON 0x01
+#define SGIOC_PANEL_POWERINTR 0x02
+#define SGIOC_PANEL_VOLDNINTR 0x10
+#define SGIOC_PANEL_VOLDNHOLD 0x20
+#define SGIOC_PANEL_VOLUPINTR 0x40
+#define SGIOC_PANEL_VOLUPHOLD 0x80
+ u32 _unused1;
+ u8 _sysid[3];
+ volatile u8 sysid;
+#define SGIOC_SYSID_FULLHOUSE 0x01
+#define SGIOC_SYSID_BOARDREV(x) (((x) & 0x1e) >> 1)
+#define SGIOC_SYSID_CHIPREV(x) (((x) & 0xe0) >> 5)
+ u32 _unused2;
+ u8 _read[3];
+ volatile u8 read;
+ u32 _unused3;
+ u8 _dmasel[3];
+ volatile u8 dmasel;
+#define SGIOC_DMASEL_SCLK10MHZ 0x00 /* use 10MHZ serial clock */
+#define SGIOC_DMASEL_ISDNB 0x01 /* enable isdn B */
+#define SGIOC_DMASEL_ISDNA 0x02 /* enable isdn A */
+#define SGIOC_DMASEL_PPORT 0x04 /* use parallel DMA */
+#define SGIOC_DMASEL_SCLK667MHZ 0x10 /* use 6.67MHZ serial clock */
+#define SGIOC_DMASEL_SCLKEXT 0x20 /* use external serial clock */
+ u32 _unused4;
+ u8 _reset[3];
+ volatile u8 reset;
+#define SGIOC_RESET_PPORT 0x01 /* 0=parport reset, 1=nornal */
+#define SGIOC_RESET_KBDMOUSE 0x02 /* 0=kbdmouse reset, 1=normal */
+#define SGIOC_RESET_EISA 0x04 /* 0=eisa reset, 1=normal */
+#define SGIOC_RESET_ISDN 0x08 /* 0=isdn reset, 1=normal */
+#define SGIOC_RESET_LC0OFF 0x10 /* guiness: turn led off (red, else green) */
+#define SGIOC_RESET_LC1OFF 0x20 /* guiness: turn led off (green, else amber) */
+ u32 _unused5;
+ u8 _write[3];
+ volatile u8 write;
+#define SGIOC_WRITE_NTHRESH 0x01 /* use 4.5db threshold */
+#define SGIOC_WRITE_TPSPEED 0x02 /* use 100ohm TP speed */
+#define SGIOC_WRITE_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */
+#define SGIOC_WRITE_EASEL 0x08 /* 1=autoselect 0=manual cable selection */
+#define SGIOC_WRITE_U1AMODE 0x10 /* 1=PC 0=MAC UART mode */
+#define SGIOC_WRITE_U0AMODE 0x20 /* 1=PC 0=MAC UART mode */
+#define SGIOC_WRITE_MLO 0x40 /* 1=4.75V 0=+5V */
+#define SGIOC_WRITE_MHI 0x80 /* 1=5.25V 0=+5V */
+ u32 _unused6;
+ struct sgint_regs int3;
+ u32 _unused7[16];
+ volatile u32 extio; /* FullHouse only */
+#define EXTIO_S0_IRQ_3 0x8000 /* S0: vid.vsync */
+#define EXTIO_S0_IRQ_2 0x4000 /* S0: gfx.fifofull */
+#define EXTIO_S0_IRQ_1 0x2000 /* S0: gfx.int */
+#define EXTIO_S0_RETRACE 0x1000
+#define EXTIO_SG_IRQ_3 0x0800 /* SG: vid.vsync */
+#define EXTIO_SG_IRQ_2 0x0400 /* SG: gfx.fifofull */
+#define EXTIO_SG_IRQ_1 0x0200 /* SG: gfx.int */
+#define EXTIO_SG_RETRACE 0x0100
+#define EXTIO_GIO_33MHZ 0x0080
+#define EXTIO_EISA_BUSERR 0x0040
+#define EXTIO_MC_BUSERR 0x0020
+#define EXTIO_HPC3_BUSERR 0x0010
+#define EXTIO_S0_STAT_1 0x0008
+#define EXTIO_S0_STAT_0 0x0004
+#define EXTIO_SG_STAT_1 0x0002
+#define EXTIO_SG_STAT_0 0x0001
+};
+
+extern struct sgioc_regs *sgioc;
+extern struct sgint_regs *sgint;
+
+#endif
diff --git a/arch/mips/include/asm/sgi/ip22.h b/arch/mips/include/asm/sgi/ip22.h
new file mode 100644
index 00000000..c0501f91
--- /dev/null
+++ b/arch/mips/include/asm/sgi/ip22.h
@@ -0,0 +1,78 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * ip22.h: Definitions for SGI IP22 machines
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle
+ */
+
+#ifndef _SGI_IP22_H
+#define _SGI_IP22_H
+
+/*
+ * These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an SGI machine. HPC DMA and MC DMA interrupts
+ * are not supported this way. Driver is supposed to allocate HPC/MC
+ * interrupt as shareable and then look to proper status bit (see
+ * HAL2 driver). This will prevent many complications, trust me ;-)
+ */
+
+#include <irq.h>
+#include <asm/sgi/ioc.h>
+
+#define SGINT_EISA 0 /* 16 EISA irq levels (Indigo2) */
+#define SGINT_CPU MIPS_CPU_IRQ_BASE /* MIPS CPU define 8 interrupt sources */
+#define SGINT_LOCAL0 (SGINT_CPU+8) /* 8 local0 irq levels */
+#define SGINT_LOCAL1 (SGINT_CPU+16) /* 8 local1 irq levels */
+#define SGINT_LOCAL2 (SGINT_CPU+24) /* 8 local2 vectored irq levels */
+#define SGINT_LOCAL3 (SGINT_CPU+32) /* 8 local3 vectored irq levels */
+#define SGINT_END (SGINT_CPU+40) /* End of 'spaces' */
+
+/*
+ * Individual interrupt definitions for the Indy and Indigo2
+ */
+
+#define SGI_SOFT_0_IRQ SGINT_CPU + 0
+#define SGI_SOFT_1_IRQ SGINT_CPU + 1
+#define SGI_LOCAL_0_IRQ SGINT_CPU + 2
+#define SGI_LOCAL_1_IRQ SGINT_CPU + 3
+#define SGI_8254_0_IRQ SGINT_CPU + 4
+#define SGI_8254_1_IRQ SGINT_CPU + 5
+#define SGI_BUSERR_IRQ SGINT_CPU + 6
+#define SGI_TIMER_IRQ SGINT_CPU + 7
+
+#define SGI_FIFO_IRQ SGINT_LOCAL0 + 0 /* FIFO full */
+#define SGI_GIO_0_IRQ SGI_FIFO_IRQ /* GIO-0 */
+#define SGI_WD93_0_IRQ SGINT_LOCAL0 + 1 /* 1st onboard WD93 */
+#define SGI_WD93_1_IRQ SGINT_LOCAL0 + 2 /* 2nd onboard WD93 */
+#define SGI_ENET_IRQ SGINT_LOCAL0 + 3 /* onboard ethernet */
+#define SGI_MCDMA_IRQ SGINT_LOCAL0 + 4 /* MC DMA done */
+#define SGI_PARPORT_IRQ SGINT_LOCAL0 + 5 /* Parallel port */
+#define SGI_GIO_1_IRQ SGINT_LOCAL0 + 6 /* GE / GIO-1 / 2nd-HPC */
+#define SGI_MAP_0_IRQ SGINT_LOCAL0 + 7 /* Mappable interrupt 0 */
+
+#define SGI_GPL0_IRQ SGINT_LOCAL1 + 0 /* General Purpose LOCAL1_N<0> */
+#define SGI_PANEL_IRQ SGINT_LOCAL1 + 1 /* front panel */
+#define SGI_GPL2_IRQ SGINT_LOCAL1 + 2 /* General Purpose LOCAL1_N<2> */
+#define SGI_MAP_1_IRQ SGINT_LOCAL1 + 3 /* Mappable interrupt 1 */
+#define SGI_HPCDMA_IRQ SGINT_LOCAL1 + 4 /* HPC DMA done */
+#define SGI_ACFAIL_IRQ SGINT_LOCAL1 + 5 /* AC fail */
+#define SGI_VINO_IRQ SGINT_LOCAL1 + 6 /* Indy VINO */
+#define SGI_GIO_2_IRQ SGINT_LOCAL1 + 7 /* Vert retrace / GIO-2 */
+
+/* Mapped interrupts. These interrupts may be mapped to either 0, or 1 */
+#define SGI_VERT_IRQ SGINT_LOCAL2 + 0 /* INT3: newport vertical status */
+#define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */
+#define SGI_KEYBD_IRQ SGINT_LOCAL2 + 4 /* keyboard */
+#define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */
+
+#define ip22_is_fullhouse() (sgioc->sysid & SGIOC_SYSID_FULLHOUSE)
+
+extern unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg);
+extern unsigned short ip22_nvram_read(int reg);
+
+#endif
diff --git a/arch/mips/include/asm/sgi/mc.h b/arch/mips/include/asm/sgi/mc.h
new file mode 100644
index 00000000..1576c239
--- /dev/null
+++ b/arch/mips/include/asm/sgi/mc.h
@@ -0,0 +1,231 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * mc.h: Definitions for SGI Memory Controller
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+
+#ifndef _SGI_MC_H
+#define _SGI_MC_H
+
+struct sgimc_regs {
+ u32 _unused0;
+ volatile u32 cpuctrl0; /* CPU control register 0, readwrite */
+#define SGIMC_CCTRL0_REFS 0x0000000f /* REFS mask */
+#define SGIMC_CCTRL0_EREFRESH 0x00000010 /* Memory refresh enable */
+#define SGIMC_CCTRL0_EPERRGIO 0x00000020 /* GIO parity error enable */
+#define SGIMC_CCTRL0_EPERRMEM 0x00000040 /* Main mem parity error enable */
+#define SGIMC_CCTRL0_EPERRCPU 0x00000080 /* CPU bus parity error enable */
+#define SGIMC_CCTRL0_WDOG 0x00000100 /* Watchdog timer enable */
+#define SGIMC_CCTRL0_SYSINIT 0x00000200 /* System init bit */
+#define SGIMC_CCTRL0_GFXRESET 0x00000400 /* Graphics interface reset */
+#define SGIMC_CCTRL0_EISALOCK 0x00000800 /* Lock CPU from memory for EISA */
+#define SGIMC_CCTRL0_EPERRSCMD 0x00001000 /* SysCMD bus parity error enable */
+#define SGIMC_CCTRL0_IENAB 0x00002000 /* Allow interrupts from MC */
+#define SGIMC_CCTRL0_ESNOOP 0x00004000 /* Snooping I/O enable */
+#define SGIMC_CCTRL0_EPROMWR 0x00008000 /* Prom writes from cpu enable */
+#define SGIMC_CCTRL0_WRESETPMEM 0x00010000 /* Perform warm reset, preserves mem */
+#define SGIMC_CCTRL0_LENDIAN 0x00020000 /* Put MC in little-endian mode */
+#define SGIMC_CCTRL0_WRESETDMEM 0x00040000 /* Warm reset, destroys mem contents */
+#define SGIMC_CCTRL0_CMEMBADPAR 0x02000000 /* Generate bad perr from cpu to mem */
+#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */
+#define SGIMC_CCTRL0_GIOBTOB 0x08000000 /* Allow GIO back to back writes */
+ u32 _unused1;
+ volatile u32 cpuctrl1; /* CPU control register 1, readwrite */
+#define SGIMC_CCTRL1_EGIOTIMEO 0x00000010 /* GIO bus timeout enable */
+#define SGIMC_CCTRL1_FIXEDEHPC 0x00001000 /* Fixed HPC endianness */
+#define SGIMC_CCTRL1_LITTLEHPC 0x00002000 /* Little endian HPC */
+#define SGIMC_CCTRL1_FIXEDEEXP0 0x00004000 /* Fixed EXP0 endianness */
+#define SGIMC_CCTRL1_LITTLEEXP0 0x00008000 /* Little endian EXP0 */
+#define SGIMC_CCTRL1_FIXEDEEXP1 0x00010000 /* Fixed EXP1 endianness */
+#define SGIMC_CCTRL1_LITTLEEXP1 0x00020000 /* Little endian EXP1 */
+
+ u32 _unused2;
+ volatile u32 watchdogt; /* Watchdog reg rdonly, write clears */
+
+ u32 _unused3;
+ volatile u32 systemid; /* MC system ID register, readonly */
+#define SGIMC_SYSID_MASKREV 0x0000000f /* Revision of MC controller */
+#define SGIMC_SYSID_EPRESENT 0x00000010 /* Indicates presence of EISA bus */
+
+ u32 _unused4[3];
+ volatile u32 divider; /* Divider reg for RPSS */
+
+ u32 _unused5;
+ u32 eeprom; /* EEPROM byte reg for r4k */
+#define SGIMC_EEPROM_PRE 0x00000001 /* eeprom chip PRE pin assertion */
+#define SGIMC_EEPROM_CSEL 0x00000002 /* Active high, eeprom chip select */
+#define SGIMC_EEPROM_SECLOCK 0x00000004 /* EEPROM serial clock */
+#define SGIMC_EEPROM_SDATAO 0x00000008 /* Serial EEPROM data-out */
+#define SGIMC_EEPROM_SDATAI 0x00000010 /* Serial EEPROM data-in */
+
+ u32 _unused6[3];
+ volatile u32 rcntpre; /* Preload refresh counter */
+
+ u32 _unused7;
+ volatile u32 rcounter; /* Readonly refresh counter */
+
+ u32 _unused8[13];
+ volatile u32 giopar; /* Parameter word for GIO64 */
+#define SGIMC_GIOPAR_HPC64 0x00000001 /* HPC talks to GIO using 64-bits */
+#define SGIMC_GIOPAR_GFX64 0x00000002 /* GFX talks to GIO using 64-bits */
+#define SGIMC_GIOPAR_EXP064 0x00000004 /* EXP(slot0) talks using 64-bits */
+#define SGIMC_GIOPAR_EXP164 0x00000008 /* EXP(slot1) talks using 64-bits */
+#define SGIMC_GIOPAR_EISA64 0x00000010 /* EISA bus talks 64-bits to GIO */
+#define SGIMC_GIOPAR_HPC264 0x00000020 /* 2nd HPX talks 64-bits to GIO */
+#define SGIMC_GIOPAR_RTIMEGFX 0x00000040 /* GFX device has realtime attr */
+#define SGIMC_GIOPAR_RTIMEEXP0 0x00000080 /* EXP(slot0) has realtime attr */
+#define SGIMC_GIOPAR_RTIMEEXP1 0x00000100 /* EXP(slot1) has realtime attr */
+#define SGIMC_GIOPAR_MASTEREISA 0x00000200 /* EISA bus can act as bus master */
+#define SGIMC_GIOPAR_ONEBUS 0x00000400 /* Exists one GIO64 pipelined bus */
+#define SGIMC_GIOPAR_MASTERGFX 0x00000800 /* GFX can act as a bus master */
+#define SGIMC_GIOPAR_MASTEREXP0 0x00001000 /* EXP(slot0) can bus master */
+#define SGIMC_GIOPAR_MASTEREXP1 0x00002000 /* EXP(slot1) can bus master */
+#define SGIMC_GIOPAR_PLINEEXP0 0x00004000 /* EXP(slot0) has pipeline attr */
+#define SGIMC_GIOPAR_PLINEEXP1 0x00008000 /* EXP(slot1) has pipeline attr */
+
+ u32 _unused9;
+ volatile u32 cputp; /* CPU bus arb time period */
+
+ u32 _unused10[3];
+ volatile u32 lbursttp; /* Time period for long bursts */
+
+ /* MC chip can drive up to 4 bank 4 SIMMs each. All SIMMs in bank must
+ * be the same size. The size encoding for supported SIMMs is bellow */
+ u32 _unused11[9];
+ volatile u32 mconfig0; /* Memory config register zero */
+ u32 _unused12;
+ volatile u32 mconfig1; /* Memory config register one */
+#define SGIMC_MCONFIG_BASEADDR 0x000000ff /* Base address of bank*/
+#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */
+#define SGIMC_MCONFIG_BVALID 0x00002000 /* Bank is valid */
+#define SGIMC_MCONFIG_SBANKS 0x00004000 /* Number of subbanks */
+
+ u32 _unused13;
+ volatile u32 cmacc; /* Mem access config for CPU */
+ u32 _unused14;
+ volatile u32 gmacc; /* Mem access config for GIO */
+
+ /* This define applies to both cmacc and gmacc registers above. */
+#define SGIMC_MACC_ALIASBIG 0x20000000 /* 512MB home for alias */
+
+ /* Error address/status regs from GIO and CPU perspectives. */
+ u32 _unused15;
+ volatile u32 cerr; /* Error address reg for CPU */
+ u32 _unused16;
+ volatile u32 cstat; /* Status reg for CPU */
+#define SGIMC_CSTAT_RD 0x00000100 /* read parity error */
+#define SGIMC_CSTAT_PAR 0x00000200 /* CPU parity error */
+#define SGIMC_CSTAT_ADDR 0x00000400 /* memory bus error bad addr */
+#define SGIMC_CSTAT_SYSAD_PAR 0x00000800 /* sysad parity error */
+#define SGIMC_CSTAT_SYSCMD_PAR 0x00001000 /* syscmd parity error */
+#define SGIMC_CSTAT_BAD_DATA 0x00002000 /* bad data identifier */
+#define SGIMC_CSTAT_PAR_MASK 0x00001f00 /* parity error mask */
+#define SGIMC_CSTAT_RD_PAR (SGIMC_CSTAT_RD | SGIMC_CSTAT_PAR)
+
+ u32 _unused17;
+ volatile u32 gerr; /* Error address reg for GIO */
+ u32 _unused18;
+ volatile u32 gstat; /* Status reg for GIO */
+#define SGIMC_GSTAT_RD 0x00000100 /* read parity error */
+#define SGIMC_GSTAT_WR 0x00000200 /* write parity error */
+#define SGIMC_GSTAT_TIME 0x00000400 /* GIO bus timed out */
+#define SGIMC_GSTAT_PROM 0x00000800 /* write to PROM when PROM_EN not set */
+#define SGIMC_GSTAT_ADDR 0x00001000 /* parity error on addr cycle */
+#define SGIMC_GSTAT_BC 0x00002000 /* parity error on byte count cycle */
+#define SGIMC_GSTAT_PIO_RD 0x00004000 /* read data parity on pio */
+#define SGIMC_GSTAT_PIO_WR 0x00008000 /* write data parity on pio */
+
+ /* Special hard bus locking registers. */
+ u32 _unused19;
+ volatile u32 syssembit; /* Uni-bit system semaphore */
+ u32 _unused20;
+ volatile u32 mlock; /* Global GIO memory access lock */
+ u32 _unused21;
+ volatile u32 elock; /* Locks EISA from GIO accesses */
+
+ /* GIO dma control registers. */
+ u32 _unused22[15];
+ volatile u32 gio_dma_trans; /* DMA mask to translation GIO addrs */
+ u32 _unused23;
+ volatile u32 gio_dma_sbits; /* DMA GIO addr substitution bits */
+ u32 _unused24;
+ volatile u32 dma_intr_cause; /* DMA IRQ cause indicator bits */
+ u32 _unused25;
+ volatile u32 dma_ctrl; /* Main DMA control reg */
+
+ /* DMA TLB entry 0 */
+ u32 _unused26[5];
+ volatile u32 dtlb_hi0;
+ u32 _unused27;
+ volatile u32 dtlb_lo0;
+
+ /* DMA TLB entry 1 */
+ u32 _unused28;
+ volatile u32 dtlb_hi1;
+ u32 _unused29;
+ volatile u32 dtlb_lo1;
+
+ /* DMA TLB entry 2 */
+ u32 _unused30;
+ volatile u32 dtlb_hi2;
+ u32 _unused31;
+ volatile u32 dtlb_lo2;
+
+ /* DMA TLB entry 3 */
+ u32 _unused32;
+ volatile u32 dtlb_hi3;
+ u32 _unused33;
+ volatile u32 dtlb_lo3;
+
+ u32 _unused34[0x0392];
+
+ u32 _unused35;
+ volatile u32 rpsscounter; /* Chirps at 100ns */
+
+ u32 _unused36[0x1000/4-2*4];
+
+ u32 _unused37;
+ volatile u32 maddronly; /* Address DMA goes at */
+ u32 _unused38;
+ volatile u32 maddrpdeflts; /* Same as above, plus set defaults */
+ u32 _unused39;
+ volatile u32 dmasz; /* DMA count */
+ u32 _unused40;
+ volatile u32 ssize; /* DMA stride size */
+ u32 _unused41;
+ volatile u32 gmaddronly; /* Set GIO DMA but don't start trans */
+ u32 _unused42;
+ volatile u32 dmaddnpgo; /* Set GIO DMA addr + start transfer */
+ u32 _unused43;
+ volatile u32 dmamode; /* DMA mode config bit settings */
+ u32 _unused44;
+ volatile u32 dmaccount; /* Zoom and byte count for DMA */
+ u32 _unused45;
+ volatile u32 dmastart; /* Pedal to the metal. */
+ u32 _unused46;
+ volatile u32 dmarunning; /* DMA op is in progress */
+ u32 _unused47;
+ volatile u32 maddrdefstart; /* Set dma addr, defaults, and kick it */
+};
+
+extern struct sgimc_regs *sgimc;
+#define SGIMC_BASE 0x1fa00000 /* physical */
+
+/* Base location of the two ram banks found in IP2[0268] machines. */
+#define SGIMC_SEG0_BADDR 0x08000000
+#define SGIMC_SEG1_BADDR 0x20000000
+
+/* Maximum size of the above banks are per machine. */
+#define SGIMC_SEG0_SIZE_ALL 0x10000000 /* 256MB */
+#define SGIMC_SEG1_SIZE_IP20_IP22 0x08000000 /* 128MB */
+#define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */
+
+extern void sgimc_init(void);
+
+#endif /* _SGI_MC_H */
diff --git a/arch/mips/include/asm/sgi/pi1.h b/arch/mips/include/asm/sgi/pi1.h
new file mode 100644
index 00000000..c9506915
--- /dev/null
+++ b/arch/mips/include/asm/sgi/pi1.h
@@ -0,0 +1,71 @@
+/*
+ * pi1.h: Definitions for SGI PI1 parallel port
+ */
+
+#ifndef _SGI_PI1_H
+#define _SGI_PI1_H
+
+struct pi1_regs {
+ u8 _data[3];
+ volatile u8 data;
+ u8 _ctrl[3];
+ volatile u8 ctrl;
+#define PI1_CTRL_STROBE_N 0x01
+#define PI1_CTRL_AFD_N 0x02
+#define PI1_CTRL_INIT_N 0x04
+#define PI1_CTRL_SLIN_N 0x08
+#define PI1_CTRL_IRQ_ENA 0x10
+#define PI1_CTRL_DIR 0x20
+#define PI1_CTRL_SEL 0x40
+ u8 _status[3];
+ volatile u8 status;
+#define PI1_STAT_DEVID 0x03 /* bits 0-1 */
+#define PI1_STAT_NOINK 0x04 /* SGI MODE only */
+#define PI1_STAT_ERROR 0x08
+#define PI1_STAT_ONLINE 0x10
+#define PI1_STAT_PE 0x20
+#define PI1_STAT_ACK 0x40
+#define PI1_STAT_BUSY 0x80
+ u8 _dmactrl[3];
+ volatile u8 dmactrl;
+#define PI1_DMACTRL_FIFO_EMPTY 0x01 /* fifo empty R/O */
+#define PI1_DMACTRL_ABORT 0x02 /* reset DMA and internal fifo W/O */
+#define PI1_DMACTRL_STDMODE 0x00 /* bits 2-3 */
+#define PI1_DMACTRL_SGIMODE 0x04 /* bits 2-3 */
+#define PI1_DMACTRL_RICOHMODE 0x08 /* bits 2-3 */
+#define PI1_DMACTRL_HPMODE 0x0c /* bits 2-3 */
+#define PI1_DMACTRL_BLKMODE 0x10 /* block mode */
+#define PI1_DMACTRL_FIFO_CLEAR 0x20 /* clear fifo W/O */
+#define PI1_DMACTRL_READ 0x40 /* read */
+#define PI1_DMACTRL_RUN 0x80 /* pedal to the metal */
+ u8 _intstat[3];
+ volatile u8 intstat;
+#define PI1_INTSTAT_ACK 0x04
+#define PI1_INTSTAT_FEMPTY 0x08
+#define PI1_INTSTAT_NOINK 0x10
+#define PI1_INTSTAT_ONLINE 0x20
+#define PI1_INTSTAT_ERR 0x40
+#define PI1_INTSTAT_PE 0x80
+ u8 _intmask[3];
+ volatile u8 intmask; /* enabled low, reset high*/
+#define PI1_INTMASK_ACK 0x04
+#define PI1_INTMASK_FIFO_EMPTY 0x08
+#define PI1_INTMASK_NOINK 0x10
+#define PI1_INTMASK_ONLINE 0x20
+#define PI1_INTMASK_ERR 0x40
+#define PI1_INTMASK_PE 0x80
+ u8 _timer1[3];
+ volatile u8 timer1;
+#define PI1_TIME1 0x27
+ u8 _timer2[3];
+ volatile u8 timer2;
+#define PI1_TIME2 0x13
+ u8 _timer3[3];
+ volatile u8 timer3;
+#define PI1_TIME3 0x10
+ u8 _timer4[3];
+ volatile u8 timer4;
+#define PI1_TIME4 0x00
+};
+
+#endif
diff --git a/arch/mips/include/asm/sgi/seeq.h b/arch/mips/include/asm/sgi/seeq.h
new file mode 100644
index 00000000..af0ffd76
--- /dev/null
+++ b/arch/mips/include/asm/sgi/seeq.h
@@ -0,0 +1,21 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 by Ralf Baechle
+ */
+#ifndef __ASM_SGI_SEEQ_H
+#define __ASM_SGI_SEEQ_H
+
+#include <linux/if_ether.h>
+
+#include <asm/sgi/hpc3.h>
+
+struct sgiseeq_platform_data {
+ struct hpc3_regs *hpc;
+ unsigned int irq;
+ unsigned char mac[ETH_ALEN];
+};
+
+#endif /* __ASM_SGI_SEEQ_H */
diff --git a/arch/mips/include/asm/sgi/sgi.h b/arch/mips/include/asm/sgi/sgi.h
new file mode 100644
index 00000000..645cea7c
--- /dev/null
+++ b/arch/mips/include/asm/sgi/sgi.h
@@ -0,0 +1,47 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * sgi.h: Definitions specific to SGI machines.
+ *
+ * Copyright (C) 1996 David S. Miller (dm@sgi.com)
+ */
+#ifndef _ASM_SGI_SGI_H
+#define _ASM_SGI_SGI_H
+
+/* UP=UniProcessor MP=MultiProcessor(capable) */
+enum sgi_mach {
+ ip4, /* R2k UP */
+ ip5, /* R2k MP */
+ ip6, /* R3k UP */
+ ip7, /* R3k MP */
+ ip9, /* R3k UP */
+ ip12, /* R3kA UP, Indigo */
+ ip15, /* R3kA MP */
+ ip17, /* R4K UP */
+ ip19, /* R4K MP */
+ ip20, /* R4K UP, Indigo */
+ ip21, /* TFP MP */
+ ip22, /* R4x00 UP, Indigo2 */
+ ip25, /* R10k MP */
+ ip26, /* TFP UP, Indigo2 */
+ ip27, /* R10k MP, R12k MP, Origin */
+ ip28, /* R10k UP, Indigo2 */
+ ip30, /* Octane */
+ ip32, /* O2 */
+};
+
+extern enum sgi_mach sgimach;
+extern void sgi_sysinit(void);
+
+/* Many I/O space registers are byte sized and are contained within
+ * one byte per word, specifically the MSB, this macro helps out.
+ */
+#ifdef __MIPSEL__
+#define SGI_MSB(regaddr) (regaddr)
+#else
+#define SGI_MSB(regaddr) ((regaddr) | 0x3)
+#endif
+
+#endif /* _ASM_SGI_SGI_H */
diff --git a/arch/mips/include/asm/sgi/wd.h b/arch/mips/include/asm/sgi/wd.h
new file mode 100644
index 00000000..0d6c3a4d
--- /dev/null
+++ b/arch/mips/include/asm/sgi/wd.h
@@ -0,0 +1,20 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 by Ralf Baechle
+ */
+#ifndef __ASM_SGI_WD_H
+#define __ASM_SGI_WD_H
+
+#include <asm/sgi/hpc3.h>
+
+struct sgiwd93_platform_data {
+ unsigned int unit;
+ unsigned int irq;
+ struct hpc3_scsiregs *hregs;
+ unsigned char *wdregs;
+};
+
+#endif /* __ASM_SGI_WD_H */
diff --git a/arch/mips/include/asm/sgialib.h b/arch/mips/include/asm/sgialib.h
new file mode 100644
index 00000000..f5811576
--- /dev/null
+++ b/arch/mips/include/asm/sgialib.h
@@ -0,0 +1,78 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI ARCS firmware interface library for the Linux kernel.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SGIALIB_H
+#define _ASM_SGIALIB_H
+
+#include <asm/sgiarcs.h>
+
+extern struct linux_romvec *romvec;
+extern int prom_argc;
+
+extern LONG *_prom_argv, *_prom_envp;
+
+/* A 32-bit ARC PROM pass arguments and environment as 32-bit pointer.
+ These macros take care of sign extension. */
+#define prom_argv(index) ((char *) (long) _prom_argv[(index)])
+#define prom_argc(index) ((char *) (long) _prom_argc[(index)])
+
+extern int prom_flags;
+
+#define PROM_FLAG_ARCS 1
+#define PROM_FLAG_USE_AS_CONSOLE 2
+#define PROM_FLAG_DONT_FREE_TEMP 4
+
+/* Simple char-by-char console I/O. */
+extern void prom_putchar(char c);
+extern char prom_getchar(void);
+
+/* Get next memory descriptor after CURR, returns first descriptor
+ * in chain is CURR is NULL.
+ */
+extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr);
+#define PROM_NULL_MDESC ((struct linux_mdesc *) 0)
+
+/* Called by prom_init to setup the physical memory pmemblock
+ * array.
+ */
+extern void prom_meminit(void);
+
+/* PROM device tree library routines. */
+#define PROM_NULL_COMPONENT ((pcomponent *) 0)
+
+/* Get sibling component of THIS. */
+extern pcomponent *ArcGetPeer(pcomponent *this);
+
+/* Get child component of THIS. */
+extern pcomponent *ArcGetChild(pcomponent *this);
+
+/* This is called at prom_init time to identify the
+ * ARC architecture we are running on
+ */
+extern void prom_identify_arch(void);
+
+/* Environment variable routines. */
+extern PCHAR ArcGetEnvironmentVariable(PCHAR name);
+extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value);
+
+/* ARCS command line parsing. */
+extern void prom_init_cmdline(void);
+
+/* File operations. */
+extern LONG ArcRead(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
+extern LONG ArcWrite(ULONG fd, PVOID buf, ULONG num, PULONG cnt);
+
+/* Misc. routines. */
+extern VOID ArcReboot(VOID) __attribute__((noreturn));
+extern VOID ArcEnterInteractiveMode(VOID) __attribute__((noreturn));
+extern VOID ArcFlushAllCaches(VOID);
+extern DISPLAY_STATUS *ArcGetDisplayStatus(ULONG FileID);
+
+#endif /* _ASM_SGIALIB_H */
diff --git a/arch/mips/include/asm/sgiarcs.h b/arch/mips/include/asm/sgiarcs.h
new file mode 100644
index 00000000..14934295
--- /dev/null
+++ b/arch/mips/include/asm/sgiarcs.h
@@ -0,0 +1,548 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * ARC firmware interface defines.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SGIARCS_H
+#define _ASM_SGIARCS_H
+
+#include <asm/types.h>
+#include <asm/fw/arc/types.h>
+
+/* Various ARCS error codes. */
+#define PROM_ESUCCESS 0x00
+#define PROM_E2BIG 0x01
+#define PROM_EACCESS 0x02
+#define PROM_EAGAIN 0x03
+#define PROM_EBADF 0x04
+#define PROM_EBUSY 0x05
+#define PROM_EFAULT 0x06
+#define PROM_EINVAL 0x07
+#define PROM_EIO 0x08
+#define PROM_EISDIR 0x09
+#define PROM_EMFILE 0x0a
+#define PROM_EMLINK 0x0b
+#define PROM_ENAMETOOLONG 0x0c
+#define PROM_ENODEV 0x0d
+#define PROM_ENOENT 0x0e
+#define PROM_ENOEXEC 0x0f
+#define PROM_ENOMEM 0x10
+#define PROM_ENOSPC 0x11
+#define PROM_ENOTDIR 0x12
+#define PROM_ENOTTY 0x13
+#define PROM_ENXIO 0x14
+#define PROM_EROFS 0x15
+/* SGI ARCS specific errno's. */
+#define PROM_EADDRNOTAVAIL 0x1f
+#define PROM_ETIMEDOUT 0x20
+#define PROM_ECONNABORTED 0x21
+#define PROM_ENOCONNECT 0x22
+
+/* Device classes, types, and identifiers for prom
+ * device inventory queries.
+ */
+enum linux_devclass {
+ system, processor, cache, adapter, controller, peripheral, memory
+};
+
+enum linux_devtypes {
+ /* Generic stuff. */
+ Arc, Cpu, Fpu,
+
+ /* Primary insn and data caches. */
+ picache, pdcache,
+
+ /* Secondary insn, data, and combined caches. */
+ sicache, sdcache, sccache,
+
+ memdev, eisa_adapter, tc_adapter, scsi_adapter, dti_adapter,
+ multifunc_adapter, dsk_controller, tp_controller, cdrom_controller,
+ worm_controller, serial_controller, net_controller, disp_controller,
+ parallel_controller, ptr_controller, kbd_controller, audio_controller,
+ misc_controller, disk_peripheral, flpy_peripheral, tp_peripheral,
+ modem_peripheral, monitor_peripheral, printer_peripheral,
+ ptr_peripheral, kbd_peripheral, term_peripheral, line_peripheral,
+ net_peripheral, misc_peripheral, anon
+};
+
+enum linux_identifier {
+ bogus, ronly, removable, consin, consout, input, output
+};
+
+/* A prom device tree component. */
+struct linux_component {
+ enum linux_devclass class; /* node class */
+ enum linux_devtypes type; /* node type */
+ enum linux_identifier iflags; /* node flags */
+ USHORT vers; /* node version */
+ USHORT rev; /* node revision */
+ ULONG key; /* completely magic */
+ ULONG amask; /* XXX affinity mask??? */
+ ULONG cdsize; /* size of configuration data */
+ ULONG ilen; /* length of string identifier */
+ _PULONG iname; /* string identifier */
+};
+typedef struct linux_component pcomponent;
+
+struct linux_sysid {
+ char vend[8], prod[8];
+};
+
+/* ARCS prom memory descriptors. */
+enum arcs_memtypes {
+ arcs_eblock, /* exception block */
+ arcs_rvpage, /* ARCS romvec page */
+ arcs_fcontig, /* Contiguous and free */
+ arcs_free, /* Generic free memory */
+ arcs_bmem, /* Borken memory, don't use */
+ arcs_prog, /* A loaded program resides here */
+ arcs_atmp, /* ARCS temporary storage area, wish Sparc OpenBoot told this */
+ arcs_aperm, /* ARCS permanent storage... */
+};
+
+/* ARC has slightly different types than ARCS */
+enum arc_memtypes {
+ arc_eblock, /* exception block */
+ arc_rvpage, /* romvec page */
+ arc_free, /* Generic free memory */
+ arc_bmem, /* Borken memory, don't use */
+ arc_prog, /* A loaded program resides here */
+ arc_atmp, /* temporary storage area */
+ arc_aperm, /* permanent storage */
+ arc_fcontig, /* Contiguous and free */
+};
+
+union linux_memtypes {
+ enum arcs_memtypes arcs;
+ enum arc_memtypes arc;
+};
+
+struct linux_mdesc {
+ union linux_memtypes type;
+ ULONG base;
+ ULONG pages;
+};
+
+/* Time of day descriptor. */
+struct linux_tinfo {
+ unsigned short yr;
+ unsigned short mnth;
+ unsigned short day;
+ unsigned short hr;
+ unsigned short min;
+ unsigned short sec;
+ unsigned short msec;
+};
+
+/* ARCS virtual dirents. */
+struct linux_vdirent {
+ ULONG namelen;
+ unsigned char attr;
+ char fname[32]; /* XXX imperical, should be a define */
+};
+
+/* Other stuff for files. */
+enum linux_omode {
+ rdonly, wronly, rdwr, wronly_creat, rdwr_creat,
+ wronly_ssede, rdwr_ssede, dirent, dirent_creat
+};
+
+enum linux_seekmode {
+ absolute, relative
+};
+
+enum linux_mountops {
+ media_load, media_unload
+};
+
+/* This prom has a bolixed design. */
+struct linux_bigint {
+#ifdef __MIPSEL__
+ u32 lo;
+ s32 hi;
+#else /* !(__MIPSEL__) */
+ s32 hi;
+ u32 lo;
+#endif
+};
+
+struct linux_finfo {
+ struct linux_bigint begin;
+ struct linux_bigint end;
+ struct linux_bigint cur;
+ enum linux_devtypes dtype;
+ unsigned long namelen;
+ unsigned char attr;
+ char name[32]; /* XXX imperical, should be define */
+};
+
+/* This describes the vector containing function pointers to the ARC
+ firmware functions. */
+struct linux_romvec {
+ LONG load; /* Load an executable image. */
+ LONG invoke; /* Invoke a standalong image. */
+ LONG exec; /* Load and begin execution of a
+ standalone image. */
+ LONG halt; /* Halt the machine. */
+ LONG pdown; /* Power down the machine. */
+ LONG restart; /* XXX soft reset??? */
+ LONG reboot; /* Reboot the machine. */
+ LONG imode; /* Enter PROM interactive mode. */
+ LONG _unused1; /* Was ReturnFromMain(). */
+
+ /* PROM device tree interface. */
+ LONG next_component;
+ LONG child_component;
+ LONG parent_component;
+ LONG component_data;
+ LONG child_add;
+ LONG comp_del;
+ LONG component_by_path;
+
+ /* Misc. stuff. */
+ LONG cfg_save;
+ LONG get_sysid;
+
+ /* Probing for memory. */
+ LONG get_mdesc;
+ LONG _unused2; /* was Signal() */
+
+ LONG get_tinfo;
+ LONG get_rtime;
+
+ /* File type operations. */
+ LONG get_vdirent;
+ LONG open;
+ LONG close;
+ LONG read;
+ LONG get_rstatus;
+ LONG write;
+ LONG seek;
+ LONG mount;
+
+ /* Dealing with firmware environment variables. */
+ LONG get_evar;
+ LONG set_evar;
+
+ LONG get_finfo;
+ LONG set_finfo;
+
+ /* Miscellaneous. */
+ LONG cache_flush;
+ LONG TestUnicodeCharacter; /* ARC; not sure if ARCS too */
+ LONG GetDisplayStatus;
+};
+
+/* The SGI ARCS parameter block is in a fixed location for standalone
+ * programs to access PROM facilities easily.
+ */
+typedef struct _SYSTEM_PARAMETER_BLOCK {
+ ULONG magic; /* magic cookie */
+#define PROMBLOCK_MAGIC 0x53435241
+
+ ULONG len; /* length of parm block */
+ USHORT ver; /* ARCS firmware version */
+ USHORT rev; /* ARCS firmware revision */
+ _PLONG rs_block; /* Restart block. */
+ _PLONG dbg_block; /* Debug block. */
+ _PLONG gevect; /* XXX General vector??? */
+ _PLONG utlbvect; /* XXX UTLB vector??? */
+ ULONG rveclen; /* Size of romvec struct. */
+ _PVOID romvec; /* Function interface. */
+ ULONG pveclen; /* Length of private vector. */
+ _PVOID pvector; /* Private vector. */
+ ULONG adap_cnt; /* Adapter count. */
+ ULONG adap_typ0; /* First adapter type. */
+ ULONG adap_vcnt0; /* Adapter 0 vector count. */
+ _PVOID adap_vector; /* Adapter 0 vector ptr. */
+ ULONG adap_typ1; /* Second adapter type. */
+ ULONG adap_vcnt1; /* Adapter 1 vector count. */
+ _PVOID adap_vector1; /* Adapter 1 vector ptr. */
+ /* More adapter vectors go here... */
+} SYSTEM_PARAMETER_BLOCK, *PSYSTEM_PARAMETER_BLOCK;
+
+#define PROMBLOCK ((PSYSTEM_PARAMETER_BLOCK) (int)0xA0001000)
+#define ROMVECTOR ((struct linux_romvec *) (long)(PROMBLOCK)->romvec)
+
+/* Cache layout parameter block. */
+union linux_cache_key {
+ struct param {
+#ifdef __MIPSEL__
+ unsigned short size;
+ unsigned char lsize;
+ unsigned char bsize;
+#else /* !(__MIPSEL__) */
+ unsigned char bsize;
+ unsigned char lsize;
+ unsigned short size;
+#endif
+ } info;
+ unsigned long allinfo;
+};
+
+/* Configuration data. */
+struct linux_cdata {
+ char *name;
+ int mlen;
+ enum linux_devtypes type;
+};
+
+/* Common SGI ARCS firmware file descriptors. */
+#define SGIPROM_STDIN 0
+#define SGIPROM_STDOUT 1
+
+/* Common SGI ARCS firmware file types. */
+#define SGIPROM_ROFILE 0x01 /* read-only file */
+#define SGIPROM_HFILE 0x02 /* hidden file */
+#define SGIPROM_SFILE 0x04 /* System file */
+#define SGIPROM_AFILE 0x08 /* Archive file */
+#define SGIPROM_DFILE 0x10 /* Directory file */
+#define SGIPROM_DELFILE 0x20 /* Deleted file */
+
+/* SGI ARCS boot record information. */
+struct sgi_partition {
+ unsigned char flag;
+#define SGIPART_UNUSED 0x00
+#define SGIPART_ACTIVE 0x80
+
+ unsigned char shead, ssect, scyl; /* unused */
+ unsigned char systype; /* OS type, Irix or NT */
+ unsigned char ehead, esect, ecyl; /* unused */
+ unsigned char rsect0, rsect1, rsect2, rsect3;
+ unsigned char tsect0, tsect1, tsect2, tsect3;
+};
+
+#define SGIBBLOCK_MAGIC 0xaa55
+#define SGIBBLOCK_MAXPART 0x0004
+
+struct sgi_bootblock {
+ unsigned char _unused[446];
+ struct sgi_partition partitions[SGIBBLOCK_MAXPART];
+ unsigned short magic;
+};
+
+/* BIOS parameter block. */
+struct sgi_bparm_block {
+ unsigned short bytes_sect; /* bytes per sector */
+ unsigned char sect_clust; /* sectors per cluster */
+ unsigned short sect_resv; /* reserved sectors */
+ unsigned char nfats; /* # of allocation tables */
+ unsigned short nroot_dirents; /* # of root directory entries */
+ unsigned short sect_volume; /* sectors in volume */
+ unsigned char media_type; /* media descriptor */
+ unsigned short sect_fat; /* sectors per allocation table */
+ unsigned short sect_track; /* sectors per track */
+ unsigned short nheads; /* # of heads */
+ unsigned short nhsects; /* # of hidden sectors */
+};
+
+struct sgi_bsector {
+ unsigned char jmpinfo[3];
+ unsigned char manuf_name[8];
+ struct sgi_bparm_block info;
+};
+
+/* Debugging block used with SGI symmon symbolic debugger. */
+#define SMB_DEBUG_MAGIC 0xfeeddead
+struct linux_smonblock {
+ unsigned long magic;
+ void (*handler)(void); /* Breakpoint routine. */
+ unsigned long dtable_base; /* Base addr of dbg table. */
+ int (*printf)(const char *fmt, ...);
+ unsigned long btable_base; /* Breakpoint table. */
+ unsigned long mpflushreqs; /* SMP cache flush request list. */
+ unsigned long ntab; /* Name table. */
+ unsigned long stab; /* Symbol table. */
+ int smax; /* Max # of symbols. */
+};
+
+/*
+ * Macros for calling a 32-bit ARC implementation from 64-bit code
+ */
+
+#if defined(CONFIG_64BIT) && defined(CONFIG_ARC32)
+
+#define __arc_clobbers \
+ "$2", "$3" /* ... */, "$8", "$9", "$10", "$11", \
+ "$12", "$13", "$14", "$15", "$16", "$24", "$25", "$31"
+
+#define ARC_CALL0(dest) \
+({ long __res; \
+ long __vec = (long) romvec->dest; \
+ __asm__ __volatile__( \
+ "dsubu\t$29, 32\n\t" \
+ "jalr\t%1\n\t" \
+ "daddu\t$29, 32\n\t" \
+ "move\t%0, $2" \
+ : "=r" (__res), "=r" (__vec) \
+ : "1" (__vec) \
+ : __arc_clobbers, "$4", "$5", "$6", "$7"); \
+ (unsigned long) __res; \
+})
+
+#define ARC_CALL1(dest, a1) \
+({ long __res; \
+ register signed int __a1 __asm__("$4") = (int) (long) (a1); \
+ long __vec = (long) romvec->dest; \
+ __asm__ __volatile__( \
+ "dsubu\t$29, 32\n\t" \
+ "jalr\t%1\n\t" \
+ "daddu\t$29, 32\n\t" \
+ "move\t%0, $2" \
+ : "=r" (__res), "=r" (__vec) \
+ : "1" (__vec), "r" (__a1) \
+ : __arc_clobbers, "$5", "$6", "$7"); \
+ (unsigned long) __res; \
+})
+
+#define ARC_CALL2(dest, a1, a2) \
+({ long __res; \
+ register signed int __a1 __asm__("$4") = (int) (long) (a1); \
+ register signed int __a2 __asm__("$5") = (int) (long) (a2); \
+ long __vec = (long) romvec->dest; \
+ __asm__ __volatile__( \
+ "dsubu\t$29, 32\n\t" \
+ "jalr\t%1\n\t" \
+ "daddu\t$29, 32\n\t" \
+ "move\t%0, $2" \
+ : "=r" (__res), "=r" (__vec) \
+ : "1" (__vec), "r" (__a1), "r" (__a2) \
+ : __arc_clobbers, "$6", "$7"); \
+ __res; \
+})
+
+#define ARC_CALL3(dest, a1, a2, a3) \
+({ long __res; \
+ register signed int __a1 __asm__("$4") = (int) (long) (a1); \
+ register signed int __a2 __asm__("$5") = (int) (long) (a2); \
+ register signed int __a3 __asm__("$6") = (int) (long) (a3); \
+ long __vec = (long) romvec->dest; \
+ __asm__ __volatile__( \
+ "dsubu\t$29, 32\n\t" \
+ "jalr\t%1\n\t" \
+ "daddu\t$29, 32\n\t" \
+ "move\t%0, $2" \
+ : "=r" (__res), "=r" (__vec) \
+ : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \
+ : __arc_clobbers, "$7"); \
+ __res; \
+})
+
+#define ARC_CALL4(dest, a1, a2, a3, a4) \
+({ long __res; \
+ register signed int __a1 __asm__("$4") = (int) (long) (a1); \
+ register signed int __a2 __asm__("$5") = (int) (long) (a2); \
+ register signed int __a3 __asm__("$6") = (int) (long) (a3); \
+ register signed int __a4 __asm__("$7") = (int) (long) (a4); \
+ long __vec = (long) romvec->dest; \
+ __asm__ __volatile__( \
+ "dsubu\t$29, 32\n\t" \
+ "jalr\t%1\n\t" \
+ "daddu\t$29, 32\n\t" \
+ "move\t%0, $2" \
+ : "=r" (__res), "=r" (__vec) \
+ : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3), \
+ "r" (__a4) \
+ : __arc_clobbers); \
+ __res; \
+})
+
+#define ARC_CALL5(dest, a1, a2, a3, a4, a5) \
+({ long __res; \
+ register signed int __a1 __asm__("$4") = (int) (long) (a1); \
+ register signed int __a2 __asm__("$5") = (int) (long) (a2); \
+ register signed int __a3 __asm__("$6") = (int) (long) (a3); \
+ register signed int __a4 __asm__("$7") = (int) (long) (a4); \
+ register signed int __a5 = (int) (long) (a5); \
+ long __vec = (long) romvec->dest; \
+ __asm__ __volatile__( \
+ "dsubu\t$29, 32\n\t" \
+ "sw\t%7, 16($29)\n\t" \
+ "jalr\t%1\n\t" \
+ "daddu\t$29, 32\n\t" \
+ "move\t%0, $2" \
+ : "=r" (__res), "=r" (__vec) \
+ : "1" (__vec), \
+ "r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4), \
+ "r" (__a5) \
+ : __arc_clobbers); \
+ __res; \
+})
+
+#endif /* defined(CONFIG_64BIT) && defined(CONFIG_ARC32) */
+
+#if (defined(CONFIG_32BIT) && defined(CONFIG_ARC32)) || \
+ (defined(CONFIG_64BIT) && defined(CONFIG_ARC64))
+
+#define ARC_CALL0(dest) \
+({ long __res; \
+ long (*__vec)(void) = (void *) romvec->dest; \
+ \
+ __res = __vec(); \
+ __res; \
+})
+
+#define ARC_CALL1(dest, a1) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long (*__vec)(long) = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1); \
+ __res; \
+})
+
+#define ARC_CALL2(dest, a1, a2) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long __a2 = (long) (a2); \
+ long (*__vec)(long, long) = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1, __a2); \
+ __res; \
+})
+
+#define ARC_CALL3(dest, a1, a2, a3) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long __a2 = (long) (a2); \
+ long __a3 = (long) (a3); \
+ long (*__vec)(long, long, long) = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1, __a2, __a3); \
+ __res; \
+})
+
+#define ARC_CALL4(dest, a1, a2, a3, a4) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long __a2 = (long) (a2); \
+ long __a3 = (long) (a3); \
+ long __a4 = (long) (a4); \
+ long (*__vec)(long, long, long, long) = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1, __a2, __a3, __a4); \
+ __res; \
+})
+
+#define ARC_CALL5(dest, a1, a2, a3, a4, a5) \
+({ long __res; \
+ long __a1 = (long) (a1); \
+ long __a2 = (long) (a2); \
+ long __a3 = (long) (a3); \
+ long __a4 = (long) (a4); \
+ long __a5 = (long) (a5); \
+ long (*__vec)(long, long, long, long, long); \
+ __vec = (void *) romvec->dest; \
+ \
+ __res = __vec(__a1, __a2, __a3, __a4, __a5); \
+ __res; \
+})
+#endif /* both kernel and ARC either 32-bit or 64-bit */
+
+#endif /* _ASM_SGIARCS_H */
diff --git a/arch/mips/include/asm/sgidefs.h b/arch/mips/include/asm/sgidefs.h
new file mode 100644
index 00000000..876442fc
--- /dev/null
+++ b/arch/mips/include/asm/sgidefs.h
@@ -0,0 +1,44 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1999, 2001 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#ifndef __ASM_SGIDEFS_H
+#define __ASM_SGIDEFS_H
+
+/*
+ * Using a Linux compiler for building Linux seems logic but not to
+ * everybody.
+ */
+#ifndef __linux__
+#error Use a Linux compiler or give up.
+#endif
+
+/*
+ * Definitions for the ISA levels
+ *
+ * With the introduction of MIPS32 / MIPS64 instruction sets definitions
+ * MIPS ISAs are no longer subsets of each other. Therefore comparisons
+ * on these symbols except with == may result in unexpected results and
+ * are forbidden!
+ */
+#define _MIPS_ISA_MIPS1 1
+#define _MIPS_ISA_MIPS2 2
+#define _MIPS_ISA_MIPS3 3
+#define _MIPS_ISA_MIPS4 4
+#define _MIPS_ISA_MIPS5 5
+#define _MIPS_ISA_MIPS32 6
+#define _MIPS_ISA_MIPS64 7
+
+/*
+ * Subprogram calling convention
+ */
+#define _MIPS_SIM_ABI32 1
+#define _MIPS_SIM_NABI32 2
+#define _MIPS_SIM_ABI64 3
+
+#endif /* __ASM_SGIDEFS_H */
diff --git a/arch/mips/include/asm/shmbuf.h b/arch/mips/include/asm/shmbuf.h
new file mode 100644
index 00000000..f9944382
--- /dev/null
+++ b/arch/mips/include/asm/shmbuf.h
@@ -0,0 +1,38 @@
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for the MIPS architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 2 miscellaneous 32-bit rsp. 64-bit values
+ */
+
+struct shmid64_ds {
+ struct ipc64_perm shm_perm; /* operation perms */
+ size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_time_t shm_atime; /* last attach time */
+ __kernel_time_t shm_dtime; /* last detach time */
+ __kernel_time_t shm_ctime; /* last change time */
+ __kernel_pid_t shm_cpid; /* pid of creator */
+ __kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+struct shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif /* _ASM_SHMBUF_H */
diff --git a/arch/mips/include/asm/shmparam.h b/arch/mips/include/asm/shmparam.h
new file mode 100644
index 00000000..09290720
--- /dev/null
+++ b/arch/mips/include/asm/shmparam.h
@@ -0,0 +1,13 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
+#define __ARCH_FORCE_SHMLBA 1
+
+#define SHMLBA 0x40000 /* attach addr a multiple of this */
+
+#endif /* _ASM_SHMPARAM_H */
diff --git a/arch/mips/include/asm/sibyte/bcm1480_int.h b/arch/mips/include/asm/sibyte/bcm1480_int.h
new file mode 100644
index 00000000..6109557c
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/bcm1480_int.h
@@ -0,0 +1,312 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * Interrupt Mapper definitions File: bcm1480_int.h
+ *
+ * This module contains constants for manipulating the
+ * BCM1255/BCM1280/BCM1455/BCM1480's interrupt mapper and
+ * definitions for the interrupt sources.
+ *
+ * BCM1480 specification level: 1X55_1X80-UM100-D4 (11/24/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_INT_H
+#define _BCM1480_INT_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Interrupt Mapper Constants
+ ********************************************************************* */
+
+/*
+ * The interrupt mapper deals with 128-bit logical registers that are
+ * implemented as pairs of 64-bit registers, with the "low" 64 bits in
+ * a register that has an address 0x1000 higher(!) than the
+ * corresponding "high" register.
+ *
+ * For appropriate registers, bit 0 of the "high" register is a
+ * cascade bit that summarizes (as a bit-OR) the 64 bits of the "low"
+ * register.
+ */
+
+/*
+ * This entire file uses _BCM1480_ in all the symbols because it is
+ * entirely BCM1480 specific.
+ */
+
+/*
+ * Interrupt sources (Table 22)
+ */
+
+#define K_BCM1480_INT_SOURCES 128
+
+#define _BCM1480_INT_HIGH(k) (k)
+#define _BCM1480_INT_LOW(k) ((k)+64)
+
+#define K_BCM1480_INT_ADDR_TRAP _BCM1480_INT_HIGH(1)
+#define K_BCM1480_INT_GPIO_0 _BCM1480_INT_HIGH(4)
+#define K_BCM1480_INT_GPIO_1 _BCM1480_INT_HIGH(5)
+#define K_BCM1480_INT_GPIO_2 _BCM1480_INT_HIGH(6)
+#define K_BCM1480_INT_GPIO_3 _BCM1480_INT_HIGH(7)
+#define K_BCM1480_INT_PCI_INTA _BCM1480_INT_HIGH(8)
+#define K_BCM1480_INT_PCI_INTB _BCM1480_INT_HIGH(9)
+#define K_BCM1480_INT_PCI_INTC _BCM1480_INT_HIGH(10)
+#define K_BCM1480_INT_PCI_INTD _BCM1480_INT_HIGH(11)
+#define K_BCM1480_INT_CYCLE_CP0 _BCM1480_INT_HIGH(12)
+#define K_BCM1480_INT_CYCLE_CP1 _BCM1480_INT_HIGH(13)
+#define K_BCM1480_INT_CYCLE_CP2 _BCM1480_INT_HIGH(14)
+#define K_BCM1480_INT_CYCLE_CP3 _BCM1480_INT_HIGH(15)
+#define K_BCM1480_INT_TIMER_0 _BCM1480_INT_HIGH(20)
+#define K_BCM1480_INT_TIMER_1 _BCM1480_INT_HIGH(21)
+#define K_BCM1480_INT_TIMER_2 _BCM1480_INT_HIGH(22)
+#define K_BCM1480_INT_TIMER_3 _BCM1480_INT_HIGH(23)
+#define K_BCM1480_INT_DM_CH_0 _BCM1480_INT_HIGH(28)
+#define K_BCM1480_INT_DM_CH_1 _BCM1480_INT_HIGH(29)
+#define K_BCM1480_INT_DM_CH_2 _BCM1480_INT_HIGH(30)
+#define K_BCM1480_INT_DM_CH_3 _BCM1480_INT_HIGH(31)
+#define K_BCM1480_INT_MAC_0 _BCM1480_INT_HIGH(36)
+#define K_BCM1480_INT_MAC_0_CH1 _BCM1480_INT_HIGH(37)
+#define K_BCM1480_INT_MAC_1 _BCM1480_INT_HIGH(38)
+#define K_BCM1480_INT_MAC_1_CH1 _BCM1480_INT_HIGH(39)
+#define K_BCM1480_INT_MAC_2 _BCM1480_INT_HIGH(40)
+#define K_BCM1480_INT_MAC_2_CH1 _BCM1480_INT_HIGH(41)
+#define K_BCM1480_INT_MAC_3 _BCM1480_INT_HIGH(42)
+#define K_BCM1480_INT_MAC_3_CH1 _BCM1480_INT_HIGH(43)
+#define K_BCM1480_INT_PMI_LOW _BCM1480_INT_HIGH(52)
+#define K_BCM1480_INT_PMI_HIGH _BCM1480_INT_HIGH(53)
+#define K_BCM1480_INT_PMO_LOW _BCM1480_INT_HIGH(54)
+#define K_BCM1480_INT_PMO_HIGH _BCM1480_INT_HIGH(55)
+#define K_BCM1480_INT_MBOX_0_0 _BCM1480_INT_HIGH(56)
+#define K_BCM1480_INT_MBOX_0_1 _BCM1480_INT_HIGH(57)
+#define K_BCM1480_INT_MBOX_0_2 _BCM1480_INT_HIGH(58)
+#define K_BCM1480_INT_MBOX_0_3 _BCM1480_INT_HIGH(59)
+#define K_BCM1480_INT_MBOX_1_0 _BCM1480_INT_HIGH(60)
+#define K_BCM1480_INT_MBOX_1_1 _BCM1480_INT_HIGH(61)
+#define K_BCM1480_INT_MBOX_1_2 _BCM1480_INT_HIGH(62)
+#define K_BCM1480_INT_MBOX_1_3 _BCM1480_INT_HIGH(63)
+
+#define K_BCM1480_INT_BAD_ECC _BCM1480_INT_LOW(1)
+#define K_BCM1480_INT_COR_ECC _BCM1480_INT_LOW(2)
+#define K_BCM1480_INT_IO_BUS _BCM1480_INT_LOW(3)
+#define K_BCM1480_INT_PERF_CNT _BCM1480_INT_LOW(4)
+#define K_BCM1480_INT_SW_PERF_CNT _BCM1480_INT_LOW(5)
+#define K_BCM1480_INT_TRACE_FREEZE _BCM1480_INT_LOW(6)
+#define K_BCM1480_INT_SW_TRACE_FREEZE _BCM1480_INT_LOW(7)
+#define K_BCM1480_INT_WATCHDOG_TIMER_0 _BCM1480_INT_LOW(8)
+#define K_BCM1480_INT_WATCHDOG_TIMER_1 _BCM1480_INT_LOW(9)
+#define K_BCM1480_INT_WATCHDOG_TIMER_2 _BCM1480_INT_LOW(10)
+#define K_BCM1480_INT_WATCHDOG_TIMER_3 _BCM1480_INT_LOW(11)
+#define K_BCM1480_INT_PCI_ERROR _BCM1480_INT_LOW(16)
+#define K_BCM1480_INT_PCI_RESET _BCM1480_INT_LOW(17)
+#define K_BCM1480_INT_NODE_CONTROLLER _BCM1480_INT_LOW(18)
+#define K_BCM1480_INT_HOST_BRIDGE _BCM1480_INT_LOW(19)
+#define K_BCM1480_INT_PORT_0_FATAL _BCM1480_INT_LOW(20)
+#define K_BCM1480_INT_PORT_0_NONFATAL _BCM1480_INT_LOW(21)
+#define K_BCM1480_INT_PORT_1_FATAL _BCM1480_INT_LOW(22)
+#define K_BCM1480_INT_PORT_1_NONFATAL _BCM1480_INT_LOW(23)
+#define K_BCM1480_INT_PORT_2_FATAL _BCM1480_INT_LOW(24)
+#define K_BCM1480_INT_PORT_2_NONFATAL _BCM1480_INT_LOW(25)
+#define K_BCM1480_INT_LDT_SMI _BCM1480_INT_LOW(32)
+#define K_BCM1480_INT_LDT_NMI _BCM1480_INT_LOW(33)
+#define K_BCM1480_INT_LDT_INIT _BCM1480_INT_LOW(34)
+#define K_BCM1480_INT_LDT_STARTUP _BCM1480_INT_LOW(35)
+#define K_BCM1480_INT_LDT_EXT _BCM1480_INT_LOW(36)
+#define K_BCM1480_INT_SMB_0 _BCM1480_INT_LOW(40)
+#define K_BCM1480_INT_SMB_1 _BCM1480_INT_LOW(41)
+#define K_BCM1480_INT_PCMCIA _BCM1480_INT_LOW(42)
+#define K_BCM1480_INT_UART_0 _BCM1480_INT_LOW(44)
+#define K_BCM1480_INT_UART_1 _BCM1480_INT_LOW(45)
+#define K_BCM1480_INT_UART_2 _BCM1480_INT_LOW(46)
+#define K_BCM1480_INT_UART_3 _BCM1480_INT_LOW(47)
+#define K_BCM1480_INT_GPIO_4 _BCM1480_INT_LOW(52)
+#define K_BCM1480_INT_GPIO_5 _BCM1480_INT_LOW(53)
+#define K_BCM1480_INT_GPIO_6 _BCM1480_INT_LOW(54)
+#define K_BCM1480_INT_GPIO_7 _BCM1480_INT_LOW(55)
+#define K_BCM1480_INT_GPIO_8 _BCM1480_INT_LOW(56)
+#define K_BCM1480_INT_GPIO_9 _BCM1480_INT_LOW(57)
+#define K_BCM1480_INT_GPIO_10 _BCM1480_INT_LOW(58)
+#define K_BCM1480_INT_GPIO_11 _BCM1480_INT_LOW(59)
+#define K_BCM1480_INT_GPIO_12 _BCM1480_INT_LOW(60)
+#define K_BCM1480_INT_GPIO_13 _BCM1480_INT_LOW(61)
+#define K_BCM1480_INT_GPIO_14 _BCM1480_INT_LOW(62)
+#define K_BCM1480_INT_GPIO_15 _BCM1480_INT_LOW(63)
+
+/*
+ * Mask values for each interrupt
+ */
+
+#define _BCM1480_INT_MASK(w, n) _SB_MAKEMASK(w, ((n) & 0x3F))
+#define _BCM1480_INT_MASK1(n) _SB_MAKEMASK1(((n) & 0x3F))
+#define _BCM1480_INT_OFFSET(n) (((n) & 0x40) << 6)
+
+#define M_BCM1480_INT_CASCADE _BCM1480_INT_MASK1(_BCM1480_INT_HIGH(0))
+
+#define M_BCM1480_INT_ADDR_TRAP _BCM1480_INT_MASK1(K_BCM1480_INT_ADDR_TRAP)
+#define M_BCM1480_INT_GPIO_0 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_0)
+#define M_BCM1480_INT_GPIO_1 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_1)
+#define M_BCM1480_INT_GPIO_2 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_2)
+#define M_BCM1480_INT_GPIO_3 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_3)
+#define M_BCM1480_INT_PCI_INTA _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTA)
+#define M_BCM1480_INT_PCI_INTB _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTB)
+#define M_BCM1480_INT_PCI_INTC _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTC)
+#define M_BCM1480_INT_PCI_INTD _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_INTD)
+#define M_BCM1480_INT_CYCLE_CP0 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP0)
+#define M_BCM1480_INT_CYCLE_CP1 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP1)
+#define M_BCM1480_INT_CYCLE_CP2 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP2)
+#define M_BCM1480_INT_CYCLE_CP3 _BCM1480_INT_MASK1(K_BCM1480_INT_CYCLE_CP3)
+#define M_BCM1480_INT_TIMER_0 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_0)
+#define M_BCM1480_INT_TIMER_1 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_1)
+#define M_BCM1480_INT_TIMER_2 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_2)
+#define M_BCM1480_INT_TIMER_3 _BCM1480_INT_MASK1(K_BCM1480_INT_TIMER_3)
+#define M_BCM1480_INT_DM_CH_0 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_0)
+#define M_BCM1480_INT_DM_CH_1 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_1)
+#define M_BCM1480_INT_DM_CH_2 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_2)
+#define M_BCM1480_INT_DM_CH_3 _BCM1480_INT_MASK1(K_BCM1480_INT_DM_CH_3)
+#define M_BCM1480_INT_MAC_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_0)
+#define M_BCM1480_INT_MAC_0_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_0_CH1)
+#define M_BCM1480_INT_MAC_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_1)
+#define M_BCM1480_INT_MAC_1_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_1_CH1)
+#define M_BCM1480_INT_MAC_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_2)
+#define M_BCM1480_INT_MAC_2_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_2_CH1)
+#define M_BCM1480_INT_MAC_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_3)
+#define M_BCM1480_INT_MAC_3_CH1 _BCM1480_INT_MASK1(K_BCM1480_INT_MAC_3_CH1)
+#define M_BCM1480_INT_PMI_LOW _BCM1480_INT_MASK1(K_BCM1480_INT_PMI_LOW)
+#define M_BCM1480_INT_PMI_HIGH _BCM1480_INT_MASK1(K_BCM1480_INT_PMI_HIGH)
+#define M_BCM1480_INT_PMO_LOW _BCM1480_INT_MASK1(K_BCM1480_INT_PMO_LOW)
+#define M_BCM1480_INT_PMO_HIGH _BCM1480_INT_MASK1(K_BCM1480_INT_PMO_HIGH)
+#define M_BCM1480_INT_MBOX_ALL _BCM1480_INT_MASK(8, K_BCM1480_INT_MBOX_0_0)
+#define M_BCM1480_INT_MBOX_0_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_0)
+#define M_BCM1480_INT_MBOX_0_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_1)
+#define M_BCM1480_INT_MBOX_0_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_2)
+#define M_BCM1480_INT_MBOX_0_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_0_3)
+#define M_BCM1480_INT_MBOX_1_0 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_0)
+#define M_BCM1480_INT_MBOX_1_1 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_1)
+#define M_BCM1480_INT_MBOX_1_2 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_2)
+#define M_BCM1480_INT_MBOX_1_3 _BCM1480_INT_MASK1(K_BCM1480_INT_MBOX_1_3)
+#define M_BCM1480_INT_BAD_ECC _BCM1480_INT_MASK1(K_BCM1480_INT_BAD_ECC)
+#define M_BCM1480_INT_COR_ECC _BCM1480_INT_MASK1(K_BCM1480_INT_COR_ECC)
+#define M_BCM1480_INT_IO_BUS _BCM1480_INT_MASK1(K_BCM1480_INT_IO_BUS)
+#define M_BCM1480_INT_PERF_CNT _BCM1480_INT_MASK1(K_BCM1480_INT_PERF_CNT)
+#define M_BCM1480_INT_SW_PERF_CNT _BCM1480_INT_MASK1(K_BCM1480_INT_SW_PERF_CNT)
+#define M_BCM1480_INT_TRACE_FREEZE _BCM1480_INT_MASK1(K_BCM1480_INT_TRACE_FREEZE)
+#define M_BCM1480_INT_SW_TRACE_FREEZE _BCM1480_INT_MASK1(K_BCM1480_INT_SW_TRACE_FREEZE)
+#define M_BCM1480_INT_WATCHDOG_TIMER_0 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_0)
+#define M_BCM1480_INT_WATCHDOG_TIMER_1 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_1)
+#define M_BCM1480_INT_WATCHDOG_TIMER_2 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_2)
+#define M_BCM1480_INT_WATCHDOG_TIMER_3 _BCM1480_INT_MASK1(K_BCM1480_INT_WATCHDOG_TIMER_3)
+#define M_BCM1480_INT_PCI_ERROR _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_ERROR)
+#define M_BCM1480_INT_PCI_RESET _BCM1480_INT_MASK1(K_BCM1480_INT_PCI_RESET)
+#define M_BCM1480_INT_NODE_CONTROLLER _BCM1480_INT_MASK1(K_BCM1480_INT_NODE_CONTROLLER)
+#define M_BCM1480_INT_HOST_BRIDGE _BCM1480_INT_MASK1(K_BCM1480_INT_HOST_BRIDGE)
+#define M_BCM1480_INT_PORT_0_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_0_FATAL)
+#define M_BCM1480_INT_PORT_0_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_0_NONFATAL)
+#define M_BCM1480_INT_PORT_1_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_1_FATAL)
+#define M_BCM1480_INT_PORT_1_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_1_NONFATAL)
+#define M_BCM1480_INT_PORT_2_FATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_2_FATAL)
+#define M_BCM1480_INT_PORT_2_NONFATAL _BCM1480_INT_MASK1(K_BCM1480_INT_PORT_2_NONFATAL)
+#define M_BCM1480_INT_LDT_SMI _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_SMI)
+#define M_BCM1480_INT_LDT_NMI _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_NMI)
+#define M_BCM1480_INT_LDT_INIT _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_INIT)
+#define M_BCM1480_INT_LDT_STARTUP _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_STARTUP)
+#define M_BCM1480_INT_LDT_EXT _BCM1480_INT_MASK1(K_BCM1480_INT_LDT_EXT)
+#define M_BCM1480_INT_SMB_0 _BCM1480_INT_MASK1(K_BCM1480_INT_SMB_0)
+#define M_BCM1480_INT_SMB_1 _BCM1480_INT_MASK1(K_BCM1480_INT_SMB_1)
+#define M_BCM1480_INT_PCMCIA _BCM1480_INT_MASK1(K_BCM1480_INT_PCMCIA)
+#define M_BCM1480_INT_UART_0 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_0)
+#define M_BCM1480_INT_UART_1 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_1)
+#define M_BCM1480_INT_UART_2 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_2)
+#define M_BCM1480_INT_UART_3 _BCM1480_INT_MASK1(K_BCM1480_INT_UART_3)
+#define M_BCM1480_INT_GPIO_4 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_4)
+#define M_BCM1480_INT_GPIO_5 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_5)
+#define M_BCM1480_INT_GPIO_6 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_6)
+#define M_BCM1480_INT_GPIO_7 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_7)
+#define M_BCM1480_INT_GPIO_8 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_8)
+#define M_BCM1480_INT_GPIO_9 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_9)
+#define M_BCM1480_INT_GPIO_10 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_10)
+#define M_BCM1480_INT_GPIO_11 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_11)
+#define M_BCM1480_INT_GPIO_12 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_12)
+#define M_BCM1480_INT_GPIO_13 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_13)
+#define M_BCM1480_INT_GPIO_14 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_14)
+#define M_BCM1480_INT_GPIO_15 _BCM1480_INT_MASK1(K_BCM1480_INT_GPIO_15)
+
+/*
+ * Interrupt mappings (Table 18)
+ */
+
+#define K_BCM1480_INT_MAP_I0 0 /* interrupt pins on processor */
+#define K_BCM1480_INT_MAP_I1 1
+#define K_BCM1480_INT_MAP_I2 2
+#define K_BCM1480_INT_MAP_I3 3
+#define K_BCM1480_INT_MAP_I4 4
+#define K_BCM1480_INT_MAP_I5 5
+#define K_BCM1480_INT_MAP_NMI 6 /* nonmaskable */
+#define K_BCM1480_INT_MAP_DINT 7 /* debug interrupt */
+
+/*
+ * Interrupt LDT Set Register (Table 19)
+ */
+
+#define S_BCM1480_INT_HT_INTMSG 0
+#define M_BCM1480_INT_HT_INTMSG _SB_MAKEMASK(3, S_BCM1480_INT_HT_INTMSG)
+#define V_BCM1480_INT_HT_INTMSG(x) _SB_MAKEVALUE(x, S_BCM1480_INT_HT_INTMSG)
+#define G_BCM1480_INT_HT_INTMSG(x) _SB_GETVALUE(x, S_BCM1480_INT_HT_INTMSG, M_BCM1480_INT_HT_INTMSG)
+
+#define K_BCM1480_INT_HT_INTMSG_FIXED 0
+#define K_BCM1480_INT_HT_INTMSG_ARBITRATED 1
+#define K_BCM1480_INT_HT_INTMSG_SMI 2
+#define K_BCM1480_INT_HT_INTMSG_NMI 3
+#define K_BCM1480_INT_HT_INTMSG_INIT 4
+#define K_BCM1480_INT_HT_INTMSG_STARTUP 5
+#define K_BCM1480_INT_HT_INTMSG_EXTINT 6
+#define K_BCM1480_INT_HT_INTMSG_RESERVED 7
+
+#define M_BCM1480_INT_HT_TRIGGERMODE _SB_MAKEMASK1(3)
+#define V_BCM1480_INT_HT_EDGETRIGGER 0
+#define V_BCM1480_INT_HT_LEVELTRIGGER M_BCM1480_INT_HT_TRIGGERMODE
+
+#define M_BCM1480_INT_HT_DESTMODE _SB_MAKEMASK1(4)
+#define V_BCM1480_INT_HT_PHYSICALDEST 0
+#define V_BCM1480_INT_HT_LOGICALDEST M_BCM1480_INT_HT_DESTMODE
+
+#define S_BCM1480_INT_HT_INTDEST 5
+#define M_BCM1480_INT_HT_INTDEST _SB_MAKEMASK(8, S_BCM1480_INT_HT_INTDEST)
+#define V_BCM1480_INT_HT_INTDEST(x) _SB_MAKEVALUE(x, S_BCM1480_INT_HT_INTDEST)
+#define G_BCM1480_INT_HT_INTDEST(x) _SB_GETVALUE(x, S_BCM1480_INT_HT_INTDEST, M_BCM1480_INT_HT_INTDEST)
+
+#define S_BCM1480_INT_HT_VECTOR 13
+#define M_BCM1480_INT_HT_VECTOR _SB_MAKEMASK(8, S_BCM1480_INT_HT_VECTOR)
+#define V_BCM1480_INT_HT_VECTOR(x) _SB_MAKEVALUE(x, S_BCM1480_INT_HT_VECTOR)
+#define G_BCM1480_INT_HT_VECTOR(x) _SB_GETVALUE(x, S_BCM1480_INT_HT_VECTOR, M_BCM1480_INT_HT_VECTOR)
+
+/*
+ * Vector prefix (Table 4-7)
+ */
+
+#define M_BCM1480_HTVECT_RAISE_INTLDT_HIGH 0x00
+#define M_BCM1480_HTVECT_RAISE_MBOX_0 0x40
+#define M_BCM1480_HTVECT_RAISE_INTLDT_LO 0x80
+#define M_BCM1480_HTVECT_RAISE_MBOX_1 0xC0
+
+#endif /* _BCM1480_INT_H */
diff --git a/arch/mips/include/asm/sibyte/bcm1480_l2c.h b/arch/mips/include/asm/sibyte/bcm1480_l2c.h
new file mode 100644
index 00000000..fd75817f
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/bcm1480_l2c.h
@@ -0,0 +1,176 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * L2 Cache constants and macros File: bcm1480_l2c.h
+ *
+ * This module contains constants useful for manipulating the
+ * level 2 cache.
+ *
+ * BCM1400 specification level: 1280-UM100-D2 (11/14/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_L2C_H
+#define _BCM1480_L2C_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Format of level 2 cache management address (Table 55)
+ */
+
+#define S_BCM1480_L2C_MGMT_INDEX 5
+#define M_BCM1480_L2C_MGMT_INDEX _SB_MAKEMASK(12, S_BCM1480_L2C_MGMT_INDEX)
+#define V_BCM1480_L2C_MGMT_INDEX(x) _SB_MAKEVALUE(x, S_BCM1480_L2C_MGMT_INDEX)
+#define G_BCM1480_L2C_MGMT_INDEX(x) _SB_GETVALUE(x, S_BCM1480_L2C_MGMT_INDEX, M_BCM1480_L2C_MGMT_INDEX)
+
+#define S_BCM1480_L2C_MGMT_WAY 17
+#define M_BCM1480_L2C_MGMT_WAY _SB_MAKEMASK(3, S_BCM1480_L2C_MGMT_WAY)
+#define V_BCM1480_L2C_MGMT_WAY(x) _SB_MAKEVALUE(x, S_BCM1480_L2C_MGMT_WAY)
+#define G_BCM1480_L2C_MGMT_WAY(x) _SB_GETVALUE(x, S_BCM1480_L2C_MGMT_WAY, M_BCM1480_L2C_MGMT_WAY)
+
+#define M_BCM1480_L2C_MGMT_DIRTY _SB_MAKEMASK1(20)
+#define M_BCM1480_L2C_MGMT_VALID _SB_MAKEMASK1(21)
+
+#define S_BCM1480_L2C_MGMT_ECC_DIAG 22
+#define M_BCM1480_L2C_MGMT_ECC_DIAG _SB_MAKEMASK(2, S_BCM1480_L2C_MGMT_ECC_DIAG)
+#define V_BCM1480_L2C_MGMT_ECC_DIAG(x) _SB_MAKEVALUE(x, S_BCM1480_L2C_MGMT_ECC_DIAG)
+#define G_BCM1480_L2C_MGMT_ECC_DIAG(x) _SB_GETVALUE(x, S_BCM1480_L2C_MGMT_ECC_DIAG, M_BCM1480_L2C_MGMT_ECC_DIAG)
+
+#define A_BCM1480_L2C_MGMT_TAG_BASE 0x00D0000000
+
+#define BCM1480_L2C_ENTRIES_PER_WAY 4096
+#define BCM1480_L2C_NUM_WAYS 8
+
+
+/*
+ * Level 2 Cache Tag register (Table 59)
+ */
+
+#define S_BCM1480_L2C_TAG_MBZ 0
+#define M_BCM1480_L2C_TAG_MBZ _SB_MAKEMASK(5, S_BCM1480_L2C_TAG_MBZ)
+
+#define S_BCM1480_L2C_TAG_INDEX 5
+#define M_BCM1480_L2C_TAG_INDEX _SB_MAKEMASK(12, S_BCM1480_L2C_TAG_INDEX)
+#define V_BCM1480_L2C_TAG_INDEX(x) _SB_MAKEVALUE(x, S_BCM1480_L2C_TAG_INDEX)
+#define G_BCM1480_L2C_TAG_INDEX(x) _SB_GETVALUE(x, S_BCM1480_L2C_TAG_INDEX, M_BCM1480_L2C_TAG_INDEX)
+
+/* Note that index bit 16 is also tag bit 40 */
+#define S_BCM1480_L2C_TAG_TAG 17
+#define M_BCM1480_L2C_TAG_TAG _SB_MAKEMASK(23, S_BCM1480_L2C_TAG_TAG)
+#define V_BCM1480_L2C_TAG_TAG(x) _SB_MAKEVALUE(x, S_BCM1480_L2C_TAG_TAG)
+#define G_BCM1480_L2C_TAG_TAG(x) _SB_GETVALUE(x, S_BCM1480_L2C_TAG_TAG, M_BCM1480_L2C_TAG_TAG)
+
+#define S_BCM1480_L2C_TAG_ECC 40
+#define M_BCM1480_L2C_TAG_ECC _SB_MAKEMASK(6, S_BCM1480_L2C_TAG_ECC)
+#define V_BCM1480_L2C_TAG_ECC(x) _SB_MAKEVALUE(x, S_BCM1480_L2C_TAG_ECC)
+#define G_BCM1480_L2C_TAG_ECC(x) _SB_GETVALUE(x, S_BCM1480_L2C_TAG_ECC, M_BCM1480_L2C_TAG_ECC)
+
+#define S_BCM1480_L2C_TAG_WAY 46
+#define M_BCM1480_L2C_TAG_WAY _SB_MAKEMASK(3, S_BCM1480_L2C_TAG_WAY)
+#define V_BCM1480_L2C_TAG_WAY(x) _SB_MAKEVALUE(x, S_BCM1480_L2C_TAG_WAY)
+#define G_BCM1480_L2C_TAG_WAY(x) _SB_GETVALUE(x, S_BCM1480_L2C_TAG_WAY, M_BCM1480_L2C_TAG_WAY)
+
+#define M_BCM1480_L2C_TAG_DIRTY _SB_MAKEMASK1(49)
+#define M_BCM1480_L2C_TAG_VALID _SB_MAKEMASK1(50)
+
+#define S_BCM1480_L2C_DATA_ECC 51
+#define M_BCM1480_L2C_DATA_ECC _SB_MAKEMASK(10, S_BCM1480_L2C_DATA_ECC)
+#define V_BCM1480_L2C_DATA_ECC(x) _SB_MAKEVALUE(x, S_BCM1480_L2C_DATA_ECC)
+#define G_BCM1480_L2C_DATA_ECC(x) _SB_GETVALUE(x, S_BCM1480_L2C_DATA_ECC, M_BCM1480_L2C_DATA_ECC)
+
+
+/*
+ * L2 Misc0 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC0_WAY_REMOTE 0
+#define M_BCM1480_L2C_MISC0_WAY_REMOTE _SB_MAKEMASK(8, S_BCM1480_L2C_MISC0_WAY_REMOTE)
+#define G_BCM1480_L2C_MISC0_WAY_REMOTE(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC0_WAY_REMOTE, M_BCM1480_L2C_MISC0_WAY_REMOTE)
+
+#define S_BCM1480_L2C_MISC0_WAY_LOCAL 8
+#define M_BCM1480_L2C_MISC0_WAY_LOCAL _SB_MAKEMASK(8, S_BCM1480_L2C_MISC0_WAY_LOCAL)
+#define G_BCM1480_L2C_MISC0_WAY_LOCAL(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC0_WAY_LOCAL, M_BCM1480_L2C_MISC0_WAY_LOCAL)
+
+#define S_BCM1480_L2C_MISC0_WAY_ENABLE 16
+#define M_BCM1480_L2C_MISC0_WAY_ENABLE _SB_MAKEMASK(8, S_BCM1480_L2C_MISC0_WAY_ENABLE)
+#define G_BCM1480_L2C_MISC0_WAY_ENABLE(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC0_WAY_ENABLE, M_BCM1480_L2C_MISC0_WAY_ENABLE)
+
+#define S_BCM1480_L2C_MISC0_CACHE_DISABLE 24
+#define M_BCM1480_L2C_MISC0_CACHE_DISABLE _SB_MAKEMASK(2, S_BCM1480_L2C_MISC0_CACHE_DISABLE)
+#define G_BCM1480_L2C_MISC0_CACHE_DISABLE(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC0_CACHE_DISABLE, M_BCM1480_L2C_MISC0_CACHE_DISABLE)
+
+#define S_BCM1480_L2C_MISC0_CACHE_QUAD 26
+#define M_BCM1480_L2C_MISC0_CACHE_QUAD _SB_MAKEMASK(2, S_BCM1480_L2C_MISC0_CACHE_QUAD)
+#define G_BCM1480_L2C_MISC0_CACHE_QUAD(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC0_CACHE_QUAD, M_BCM1480_L2C_MISC0_CACHE_QUAD)
+
+#define S_BCM1480_L2C_MISC0_MC_PRIORITY 30
+#define M_BCM1480_L2C_MISC0_MC_PRIORITY _SB_MAKEMASK1(S_BCM1480_L2C_MISC0_MC_PRIORITY)
+
+#define S_BCM1480_L2C_MISC0_ECC_CLEANUP 31
+#define M_BCM1480_L2C_MISC0_ECC_CLEANUP _SB_MAKEMASK1(S_BCM1480_L2C_MISC0_ECC_CLEANUP)
+
+
+/*
+ * L2 Misc1 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_0 0
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_0 _SB_MAKEMASK(8, S_BCM1480_L2C_MISC1_WAY_AGENT_0)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_0(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC1_WAY_AGENT_0, M_BCM1480_L2C_MISC1_WAY_AGENT_0)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_1 8
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_1 _SB_MAKEMASK(8, S_BCM1480_L2C_MISC1_WAY_AGENT_1)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_1(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC1_WAY_AGENT_1, M_BCM1480_L2C_MISC1_WAY_AGENT_1)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_2 16
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_2 _SB_MAKEMASK(8, S_BCM1480_L2C_MISC1_WAY_AGENT_2)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_2(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC1_WAY_AGENT_2, M_BCM1480_L2C_MISC1_WAY_AGENT_2)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_3 24
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_3 _SB_MAKEMASK(8, S_BCM1480_L2C_MISC1_WAY_AGENT_3)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_3(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC1_WAY_AGENT_3, M_BCM1480_L2C_MISC1_WAY_AGENT_3)
+
+#define S_BCM1480_L2C_MISC1_WAY_AGENT_4 32
+#define M_BCM1480_L2C_MISC1_WAY_AGENT_4 _SB_MAKEMASK(8, S_BCM1480_L2C_MISC1_WAY_AGENT_4)
+#define G_BCM1480_L2C_MISC1_WAY_AGENT_4(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC1_WAY_AGENT_4, M_BCM1480_L2C_MISC1_WAY_AGENT_4)
+
+
+/*
+ * L2 Misc2 Value Register (Table 60)
+ */
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_8 0
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_8 _SB_MAKEMASK(8, S_BCM1480_L2C_MISC2_WAY_AGENT_8)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_8(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC2_WAY_AGENT_8, M_BCM1480_L2C_MISC2_WAY_AGENT_8)
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_9 8
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_9 _SB_MAKEMASK(8, S_BCM1480_L2C_MISC2_WAY_AGENT_9)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_9(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC2_WAY_AGENT_9, M_BCM1480_L2C_MISC2_WAY_AGENT_9)
+
+#define S_BCM1480_L2C_MISC2_WAY_AGENT_A 16
+#define M_BCM1480_L2C_MISC2_WAY_AGENT_A _SB_MAKEMASK(8, S_BCM1480_L2C_MISC2_WAY_AGENT_A)
+#define G_BCM1480_L2C_MISC2_WAY_AGENT_A(x) _SB_GETVALUE(x, S_BCM1480_L2C_MISC2_WAY_AGENT_A, M_BCM1480_L2C_MISC2_WAY_AGENT_A)
+
+
+#endif /* _BCM1480_L2C_H */
diff --git a/arch/mips/include/asm/sibyte/bcm1480_mc.h b/arch/mips/include/asm/sibyte/bcm1480_mc.h
new file mode 100644
index 00000000..f26a41a8
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/bcm1480_mc.h
@@ -0,0 +1,984 @@
+/* *********************************************************************
+ * BCM1280/BCM1480 Board Support Package
+ *
+ * Memory Controller constants File: bcm1480_mc.h
+ *
+ * This module contains constants and macros useful for
+ * programming the memory controller.
+ *
+ * BCM1400 specification level: 1280-UM100-D1 (11/14/03 Review Copy)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _BCM1480_MC_H
+#define _BCM1480_MC_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Memory Channel Configuration Register (Table 81)
+ */
+
+#define S_BCM1480_MC_INTLV0 0
+#define M_BCM1480_MC_INTLV0 _SB_MAKEMASK(6, S_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0(x) _SB_MAKEVALUE(x, S_BCM1480_MC_INTLV0)
+#define G_BCM1480_MC_INTLV0(x) _SB_GETVALUE(x, S_BCM1480_MC_INTLV0, M_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0_DEFAULT V_BCM1480_MC_INTLV0(0)
+
+#define S_BCM1480_MC_INTLV1 8
+#define M_BCM1480_MC_INTLV1 _SB_MAKEMASK(6, S_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1(x) _SB_MAKEVALUE(x, S_BCM1480_MC_INTLV1)
+#define G_BCM1480_MC_INTLV1(x) _SB_GETVALUE(x, S_BCM1480_MC_INTLV1, M_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1_DEFAULT V_BCM1480_MC_INTLV1(0)
+
+#define S_BCM1480_MC_INTLV2 16
+#define M_BCM1480_MC_INTLV2 _SB_MAKEMASK(6, S_BCM1480_MC_INTLV2)
+#define V_BCM1480_MC_INTLV2(x) _SB_MAKEVALUE(x, S_BCM1480_MC_INTLV2)
+#define G_BCM1480_MC_INTLV2(x) _SB_GETVALUE(x, S_BCM1480_MC_INTLV2, M_BCM1480_MC_INTLV2)
+#define V_BCM1480_MC_INTLV2_DEFAULT V_BCM1480_MC_INTLV2(0)
+
+#define S_BCM1480_MC_CS_MODE 32
+#define M_BCM1480_MC_CS_MODE _SB_MAKEMASK(8, S_BCM1480_MC_CS_MODE)
+#define V_BCM1480_MC_CS_MODE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS_MODE)
+#define G_BCM1480_MC_CS_MODE(x) _SB_GETVALUE(x, S_BCM1480_MC_CS_MODE, M_BCM1480_MC_CS_MODE)
+#define V_BCM1480_MC_CS_MODE_DEFAULT V_BCM1480_MC_CS_MODE(0)
+
+#define V_BCM1480_MC_CONFIG_DEFAULT (V_BCM1480_MC_INTLV0_DEFAULT | \
+ V_BCM1480_MC_INTLV1_DEFAULT | \
+ V_BCM1480_MC_INTLV2_DEFAULT | \
+ V_BCM1480_MC_CS_MODE_DEFAULT)
+
+#define K_BCM1480_MC_CS01_MODE 0x03
+#define K_BCM1480_MC_CS02_MODE 0x05
+#define K_BCM1480_MC_CS0123_MODE 0x0F
+#define K_BCM1480_MC_CS0246_MODE 0x55
+#define K_BCM1480_MC_CS0145_MODE 0x33
+#define K_BCM1480_MC_CS0167_MODE 0xC3
+#define K_BCM1480_MC_CSFULL_MODE 0xFF
+
+/*
+ * Chip Select Start Address Register (Table 82)
+ */
+
+#define S_BCM1480_MC_CS0_START 0
+#define M_BCM1480_MC_CS0_START _SB_MAKEMASK(12, S_BCM1480_MC_CS0_START)
+#define V_BCM1480_MC_CS0_START(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS0_START)
+#define G_BCM1480_MC_CS0_START(x) _SB_GETVALUE(x, S_BCM1480_MC_CS0_START, M_BCM1480_MC_CS0_START)
+
+#define S_BCM1480_MC_CS1_START 16
+#define M_BCM1480_MC_CS1_START _SB_MAKEMASK(12, S_BCM1480_MC_CS1_START)
+#define V_BCM1480_MC_CS1_START(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS1_START)
+#define G_BCM1480_MC_CS1_START(x) _SB_GETVALUE(x, S_BCM1480_MC_CS1_START, M_BCM1480_MC_CS1_START)
+
+#define S_BCM1480_MC_CS2_START 32
+#define M_BCM1480_MC_CS2_START _SB_MAKEMASK(12, S_BCM1480_MC_CS2_START)
+#define V_BCM1480_MC_CS2_START(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS2_START)
+#define G_BCM1480_MC_CS2_START(x) _SB_GETVALUE(x, S_BCM1480_MC_CS2_START, M_BCM1480_MC_CS2_START)
+
+#define S_BCM1480_MC_CS3_START 48
+#define M_BCM1480_MC_CS3_START _SB_MAKEMASK(12, S_BCM1480_MC_CS3_START)
+#define V_BCM1480_MC_CS3_START(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS3_START)
+#define G_BCM1480_MC_CS3_START(x) _SB_GETVALUE(x, S_BCM1480_MC_CS3_START, M_BCM1480_MC_CS3_START)
+
+/*
+ * Chip Select End Address Register (Table 83)
+ */
+
+#define S_BCM1480_MC_CS0_END 0
+#define M_BCM1480_MC_CS0_END _SB_MAKEMASK(12, S_BCM1480_MC_CS0_END)
+#define V_BCM1480_MC_CS0_END(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS0_END)
+#define G_BCM1480_MC_CS0_END(x) _SB_GETVALUE(x, S_BCM1480_MC_CS0_END, M_BCM1480_MC_CS0_END)
+
+#define S_BCM1480_MC_CS1_END 16
+#define M_BCM1480_MC_CS1_END _SB_MAKEMASK(12, S_BCM1480_MC_CS1_END)
+#define V_BCM1480_MC_CS1_END(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS1_END)
+#define G_BCM1480_MC_CS1_END(x) _SB_GETVALUE(x, S_BCM1480_MC_CS1_END, M_BCM1480_MC_CS1_END)
+
+#define S_BCM1480_MC_CS2_END 32
+#define M_BCM1480_MC_CS2_END _SB_MAKEMASK(12, S_BCM1480_MC_CS2_END)
+#define V_BCM1480_MC_CS2_END(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS2_END)
+#define G_BCM1480_MC_CS2_END(x) _SB_GETVALUE(x, S_BCM1480_MC_CS2_END, M_BCM1480_MC_CS2_END)
+
+#define S_BCM1480_MC_CS3_END 48
+#define M_BCM1480_MC_CS3_END _SB_MAKEMASK(12, S_BCM1480_MC_CS3_END)
+#define V_BCM1480_MC_CS3_END(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS3_END)
+#define G_BCM1480_MC_CS3_END(x) _SB_GETVALUE(x, S_BCM1480_MC_CS3_END, M_BCM1480_MC_CS3_END)
+
+/*
+ * Row Address Bit Select Register 0 (Table 84)
+ */
+
+#define S_BCM1480_MC_ROW00 0
+#define M_BCM1480_MC_ROW00 _SB_MAKEMASK(6, S_BCM1480_MC_ROW00)
+#define V_BCM1480_MC_ROW00(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW00)
+#define G_BCM1480_MC_ROW00(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW00, M_BCM1480_MC_ROW00)
+
+#define S_BCM1480_MC_ROW01 8
+#define M_BCM1480_MC_ROW01 _SB_MAKEMASK(6, S_BCM1480_MC_ROW01)
+#define V_BCM1480_MC_ROW01(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW01)
+#define G_BCM1480_MC_ROW01(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW01, M_BCM1480_MC_ROW01)
+
+#define S_BCM1480_MC_ROW02 16
+#define M_BCM1480_MC_ROW02 _SB_MAKEMASK(6, S_BCM1480_MC_ROW02)
+#define V_BCM1480_MC_ROW02(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW02)
+#define G_BCM1480_MC_ROW02(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW02, M_BCM1480_MC_ROW02)
+
+#define S_BCM1480_MC_ROW03 24
+#define M_BCM1480_MC_ROW03 _SB_MAKEMASK(6, S_BCM1480_MC_ROW03)
+#define V_BCM1480_MC_ROW03(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW03)
+#define G_BCM1480_MC_ROW03(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW03, M_BCM1480_MC_ROW03)
+
+#define S_BCM1480_MC_ROW04 32
+#define M_BCM1480_MC_ROW04 _SB_MAKEMASK(6, S_BCM1480_MC_ROW04)
+#define V_BCM1480_MC_ROW04(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW04)
+#define G_BCM1480_MC_ROW04(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW04, M_BCM1480_MC_ROW04)
+
+#define S_BCM1480_MC_ROW05 40
+#define M_BCM1480_MC_ROW05 _SB_MAKEMASK(6, S_BCM1480_MC_ROW05)
+#define V_BCM1480_MC_ROW05(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW05)
+#define G_BCM1480_MC_ROW05(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW05, M_BCM1480_MC_ROW05)
+
+#define S_BCM1480_MC_ROW06 48
+#define M_BCM1480_MC_ROW06 _SB_MAKEMASK(6, S_BCM1480_MC_ROW06)
+#define V_BCM1480_MC_ROW06(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW06)
+#define G_BCM1480_MC_ROW06(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW06, M_BCM1480_MC_ROW06)
+
+#define S_BCM1480_MC_ROW07 56
+#define M_BCM1480_MC_ROW07 _SB_MAKEMASK(6, S_BCM1480_MC_ROW07)
+#define V_BCM1480_MC_ROW07(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW07)
+#define G_BCM1480_MC_ROW07(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW07, M_BCM1480_MC_ROW07)
+
+/*
+ * Row Address Bit Select Register 1 (Table 85)
+ */
+
+#define S_BCM1480_MC_ROW08 0
+#define M_BCM1480_MC_ROW08 _SB_MAKEMASK(6, S_BCM1480_MC_ROW08)
+#define V_BCM1480_MC_ROW08(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW08)
+#define G_BCM1480_MC_ROW08(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW08, M_BCM1480_MC_ROW08)
+
+#define S_BCM1480_MC_ROW09 8
+#define M_BCM1480_MC_ROW09 _SB_MAKEMASK(6, S_BCM1480_MC_ROW09)
+#define V_BCM1480_MC_ROW09(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW09)
+#define G_BCM1480_MC_ROW09(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW09, M_BCM1480_MC_ROW09)
+
+#define S_BCM1480_MC_ROW10 16
+#define M_BCM1480_MC_ROW10 _SB_MAKEMASK(6, S_BCM1480_MC_ROW10)
+#define V_BCM1480_MC_ROW10(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW10)
+#define G_BCM1480_MC_ROW10(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW10, M_BCM1480_MC_ROW10)
+
+#define S_BCM1480_MC_ROW11 24
+#define M_BCM1480_MC_ROW11 _SB_MAKEMASK(6, S_BCM1480_MC_ROW11)
+#define V_BCM1480_MC_ROW11(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW11)
+#define G_BCM1480_MC_ROW11(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW11, M_BCM1480_MC_ROW11)
+
+#define S_BCM1480_MC_ROW12 32
+#define M_BCM1480_MC_ROW12 _SB_MAKEMASK(6, S_BCM1480_MC_ROW12)
+#define V_BCM1480_MC_ROW12(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW12)
+#define G_BCM1480_MC_ROW12(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW12, M_BCM1480_MC_ROW12)
+
+#define S_BCM1480_MC_ROW13 40
+#define M_BCM1480_MC_ROW13 _SB_MAKEMASK(6, S_BCM1480_MC_ROW13)
+#define V_BCM1480_MC_ROW13(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW13)
+#define G_BCM1480_MC_ROW13(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW13, M_BCM1480_MC_ROW13)
+
+#define S_BCM1480_MC_ROW14 48
+#define M_BCM1480_MC_ROW14 _SB_MAKEMASK(6, S_BCM1480_MC_ROW14)
+#define V_BCM1480_MC_ROW14(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ROW14)
+#define G_BCM1480_MC_ROW14(x) _SB_GETVALUE(x, S_BCM1480_MC_ROW14, M_BCM1480_MC_ROW14)
+
+#define K_BCM1480_MC_ROWX_BIT_SPACING 8
+
+/*
+ * Column Address Bit Select Register 0 (Table 86)
+ */
+
+#define S_BCM1480_MC_COL00 0
+#define M_BCM1480_MC_COL00 _SB_MAKEMASK(6, S_BCM1480_MC_COL00)
+#define V_BCM1480_MC_COL00(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL00)
+#define G_BCM1480_MC_COL00(x) _SB_GETVALUE(x, S_BCM1480_MC_COL00, M_BCM1480_MC_COL00)
+
+#define S_BCM1480_MC_COL01 8
+#define M_BCM1480_MC_COL01 _SB_MAKEMASK(6, S_BCM1480_MC_COL01)
+#define V_BCM1480_MC_COL01(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL01)
+#define G_BCM1480_MC_COL01(x) _SB_GETVALUE(x, S_BCM1480_MC_COL01, M_BCM1480_MC_COL01)
+
+#define S_BCM1480_MC_COL02 16
+#define M_BCM1480_MC_COL02 _SB_MAKEMASK(6, S_BCM1480_MC_COL02)
+#define V_BCM1480_MC_COL02(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL02)
+#define G_BCM1480_MC_COL02(x) _SB_GETVALUE(x, S_BCM1480_MC_COL02, M_BCM1480_MC_COL02)
+
+#define S_BCM1480_MC_COL03 24
+#define M_BCM1480_MC_COL03 _SB_MAKEMASK(6, S_BCM1480_MC_COL03)
+#define V_BCM1480_MC_COL03(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL03)
+#define G_BCM1480_MC_COL03(x) _SB_GETVALUE(x, S_BCM1480_MC_COL03, M_BCM1480_MC_COL03)
+
+#define S_BCM1480_MC_COL04 32
+#define M_BCM1480_MC_COL04 _SB_MAKEMASK(6, S_BCM1480_MC_COL04)
+#define V_BCM1480_MC_COL04(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL04)
+#define G_BCM1480_MC_COL04(x) _SB_GETVALUE(x, S_BCM1480_MC_COL04, M_BCM1480_MC_COL04)
+
+#define S_BCM1480_MC_COL05 40
+#define M_BCM1480_MC_COL05 _SB_MAKEMASK(6, S_BCM1480_MC_COL05)
+#define V_BCM1480_MC_COL05(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL05)
+#define G_BCM1480_MC_COL05(x) _SB_GETVALUE(x, S_BCM1480_MC_COL05, M_BCM1480_MC_COL05)
+
+#define S_BCM1480_MC_COL06 48
+#define M_BCM1480_MC_COL06 _SB_MAKEMASK(6, S_BCM1480_MC_COL06)
+#define V_BCM1480_MC_COL06(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL06)
+#define G_BCM1480_MC_COL06(x) _SB_GETVALUE(x, S_BCM1480_MC_COL06, M_BCM1480_MC_COL06)
+
+#define S_BCM1480_MC_COL07 56
+#define M_BCM1480_MC_COL07 _SB_MAKEMASK(6, S_BCM1480_MC_COL07)
+#define V_BCM1480_MC_COL07(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL07)
+#define G_BCM1480_MC_COL07(x) _SB_GETVALUE(x, S_BCM1480_MC_COL07, M_BCM1480_MC_COL07)
+
+/*
+ * Column Address Bit Select Register 1 (Table 87)
+ */
+
+#define S_BCM1480_MC_COL08 0
+#define M_BCM1480_MC_COL08 _SB_MAKEMASK(6, S_BCM1480_MC_COL08)
+#define V_BCM1480_MC_COL08(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL08)
+#define G_BCM1480_MC_COL08(x) _SB_GETVALUE(x, S_BCM1480_MC_COL08, M_BCM1480_MC_COL08)
+
+#define S_BCM1480_MC_COL09 8
+#define M_BCM1480_MC_COL09 _SB_MAKEMASK(6, S_BCM1480_MC_COL09)
+#define V_BCM1480_MC_COL09(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL09)
+#define G_BCM1480_MC_COL09(x) _SB_GETVALUE(x, S_BCM1480_MC_COL09, M_BCM1480_MC_COL09)
+
+#define S_BCM1480_MC_COL10 16 /* not a valid position, must be prog as 0 */
+
+#define S_BCM1480_MC_COL11 24
+#define M_BCM1480_MC_COL11 _SB_MAKEMASK(6, S_BCM1480_MC_COL11)
+#define V_BCM1480_MC_COL11(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL11)
+#define G_BCM1480_MC_COL11(x) _SB_GETVALUE(x, S_BCM1480_MC_COL11, M_BCM1480_MC_COL11)
+
+#define S_BCM1480_MC_COL12 32
+#define M_BCM1480_MC_COL12 _SB_MAKEMASK(6, S_BCM1480_MC_COL12)
+#define V_BCM1480_MC_COL12(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL12)
+#define G_BCM1480_MC_COL12(x) _SB_GETVALUE(x, S_BCM1480_MC_COL12, M_BCM1480_MC_COL12)
+
+#define S_BCM1480_MC_COL13 40
+#define M_BCM1480_MC_COL13 _SB_MAKEMASK(6, S_BCM1480_MC_COL13)
+#define V_BCM1480_MC_COL13(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL13)
+#define G_BCM1480_MC_COL13(x) _SB_GETVALUE(x, S_BCM1480_MC_COL13, M_BCM1480_MC_COL13)
+
+#define S_BCM1480_MC_COL14 48
+#define M_BCM1480_MC_COL14 _SB_MAKEMASK(6, S_BCM1480_MC_COL14)
+#define V_BCM1480_MC_COL14(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COL14)
+#define G_BCM1480_MC_COL14(x) _SB_GETVALUE(x, S_BCM1480_MC_COL14, M_BCM1480_MC_COL14)
+
+#define K_BCM1480_MC_COLX_BIT_SPACING 8
+
+/*
+ * CS0 and CS1 Bank Address Bit Select Register (Table 88)
+ */
+
+#define S_BCM1480_MC_CS01_BANK0 0
+#define M_BCM1480_MC_CS01_BANK0 _SB_MAKEMASK(6, S_BCM1480_MC_CS01_BANK0)
+#define V_BCM1480_MC_CS01_BANK0(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS01_BANK0)
+#define G_BCM1480_MC_CS01_BANK0(x) _SB_GETVALUE(x, S_BCM1480_MC_CS01_BANK0, M_BCM1480_MC_CS01_BANK0)
+
+#define S_BCM1480_MC_CS01_BANK1 8
+#define M_BCM1480_MC_CS01_BANK1 _SB_MAKEMASK(6, S_BCM1480_MC_CS01_BANK1)
+#define V_BCM1480_MC_CS01_BANK1(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS01_BANK1)
+#define G_BCM1480_MC_CS01_BANK1(x) _SB_GETVALUE(x, S_BCM1480_MC_CS01_BANK1, M_BCM1480_MC_CS01_BANK1)
+
+#define S_BCM1480_MC_CS01_BANK2 16
+#define M_BCM1480_MC_CS01_BANK2 _SB_MAKEMASK(6, S_BCM1480_MC_CS01_BANK2)
+#define V_BCM1480_MC_CS01_BANK2(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS01_BANK2)
+#define G_BCM1480_MC_CS01_BANK2(x) _SB_GETVALUE(x, S_BCM1480_MC_CS01_BANK2, M_BCM1480_MC_CS01_BANK2)
+
+/*
+ * CS2 and CS3 Bank Address Bit Select Register (Table 89)
+ */
+
+#define S_BCM1480_MC_CS23_BANK0 0
+#define M_BCM1480_MC_CS23_BANK0 _SB_MAKEMASK(6, S_BCM1480_MC_CS23_BANK0)
+#define V_BCM1480_MC_CS23_BANK0(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS23_BANK0)
+#define G_BCM1480_MC_CS23_BANK0(x) _SB_GETVALUE(x, S_BCM1480_MC_CS23_BANK0, M_BCM1480_MC_CS23_BANK0)
+
+#define S_BCM1480_MC_CS23_BANK1 8
+#define M_BCM1480_MC_CS23_BANK1 _SB_MAKEMASK(6, S_BCM1480_MC_CS23_BANK1)
+#define V_BCM1480_MC_CS23_BANK1(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS23_BANK1)
+#define G_BCM1480_MC_CS23_BANK1(x) _SB_GETVALUE(x, S_BCM1480_MC_CS23_BANK1, M_BCM1480_MC_CS23_BANK1)
+
+#define S_BCM1480_MC_CS23_BANK2 16
+#define M_BCM1480_MC_CS23_BANK2 _SB_MAKEMASK(6, S_BCM1480_MC_CS23_BANK2)
+#define V_BCM1480_MC_CS23_BANK2(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS23_BANK2)
+#define G_BCM1480_MC_CS23_BANK2(x) _SB_GETVALUE(x, S_BCM1480_MC_CS23_BANK2, M_BCM1480_MC_CS23_BANK2)
+
+#define K_BCM1480_MC_CSXX_BANKX_BIT_SPACING 8
+
+/*
+ * DRAM Command Register (Table 90)
+ */
+
+#define S_BCM1480_MC_COMMAND 0
+#define M_BCM1480_MC_COMMAND _SB_MAKEMASK(4, S_BCM1480_MC_COMMAND)
+#define V_BCM1480_MC_COMMAND(x) _SB_MAKEVALUE(x, S_BCM1480_MC_COMMAND)
+#define G_BCM1480_MC_COMMAND(x) _SB_GETVALUE(x, S_BCM1480_MC_COMMAND, M_BCM1480_MC_COMMAND)
+
+#define K_BCM1480_MC_COMMAND_EMRS 0
+#define K_BCM1480_MC_COMMAND_MRS 1
+#define K_BCM1480_MC_COMMAND_PRE 2
+#define K_BCM1480_MC_COMMAND_AR 3
+#define K_BCM1480_MC_COMMAND_SETRFSH 4
+#define K_BCM1480_MC_COMMAND_CLRRFSH 5
+#define K_BCM1480_MC_COMMAND_SETPWRDN 6
+#define K_BCM1480_MC_COMMAND_CLRPWRDN 7
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define K_BCM1480_MC_COMMAND_EMRS2 8
+#define K_BCM1480_MC_COMMAND_EMRS3 9
+#define K_BCM1480_MC_COMMAND_ENABLE_MCLK 10
+#define K_BCM1480_MC_COMMAND_DISABLE_MCLK 11
+#endif
+
+#define V_BCM1480_MC_COMMAND_EMRS V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS)
+#define V_BCM1480_MC_COMMAND_MRS V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_MRS)
+#define V_BCM1480_MC_COMMAND_PRE V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_PRE)
+#define V_BCM1480_MC_COMMAND_AR V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_AR)
+#define V_BCM1480_MC_COMMAND_SETRFSH V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_SETRFSH)
+#define V_BCM1480_MC_COMMAND_CLRRFSH V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_CLRRFSH)
+#define V_BCM1480_MC_COMMAND_SETPWRDN V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_SETPWRDN)
+#define V_BCM1480_MC_COMMAND_CLRPWRDN V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_CLRPWRDN)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define V_BCM1480_MC_COMMAND_EMRS2 V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS2)
+#define V_BCM1480_MC_COMMAND_EMRS3 V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_EMRS3)
+#define V_BCM1480_MC_COMMAND_ENABLE_MCLK V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_ENABLE_MCLK)
+#define V_BCM1480_MC_COMMAND_DISABLE_MCLK V_BCM1480_MC_COMMAND(K_BCM1480_MC_COMMAND_DISABLE_MCLK)
+#endif
+
+#define S_BCM1480_MC_CS0 4
+#define M_BCM1480_MC_CS0 _SB_MAKEMASK1(4)
+#define M_BCM1480_MC_CS1 _SB_MAKEMASK1(5)
+#define M_BCM1480_MC_CS2 _SB_MAKEMASK1(6)
+#define M_BCM1480_MC_CS3 _SB_MAKEMASK1(7)
+#define M_BCM1480_MC_CS4 _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_CS5 _SB_MAKEMASK1(9)
+#define M_BCM1480_MC_CS6 _SB_MAKEMASK1(10)
+#define M_BCM1480_MC_CS7 _SB_MAKEMASK1(11)
+
+#define M_BCM1480_MC_CS _SB_MAKEMASK(8, S_BCM1480_MC_CS0)
+#define V_BCM1480_MC_CS(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CS0)
+#define G_BCM1480_MC_CS(x) _SB_GETVALUE(x, S_BCM1480_MC_CS0, M_BCM1480_MC_CS0)
+
+#define M_BCM1480_MC_CMD_ACTIVE _SB_MAKEMASK1(16)
+
+/*
+ * DRAM Mode Register (Table 91)
+ */
+
+#define S_BCM1480_MC_EMODE 0
+#define M_BCM1480_MC_EMODE _SB_MAKEMASK(15, S_BCM1480_MC_EMODE)
+#define V_BCM1480_MC_EMODE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_EMODE)
+#define G_BCM1480_MC_EMODE(x) _SB_GETVALUE(x, S_BCM1480_MC_EMODE, M_BCM1480_MC_EMODE)
+#define V_BCM1480_MC_EMODE_DEFAULT V_BCM1480_MC_EMODE(0)
+
+#define S_BCM1480_MC_MODE 16
+#define M_BCM1480_MC_MODE _SB_MAKEMASK(15, S_BCM1480_MC_MODE)
+#define V_BCM1480_MC_MODE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_MODE)
+#define G_BCM1480_MC_MODE(x) _SB_GETVALUE(x, S_BCM1480_MC_MODE, M_BCM1480_MC_MODE)
+#define V_BCM1480_MC_MODE_DEFAULT V_BCM1480_MC_MODE(0)
+
+#define S_BCM1480_MC_DRAM_TYPE 32
+#define M_BCM1480_MC_DRAM_TYPE _SB_MAKEMASK(4, S_BCM1480_MC_DRAM_TYPE)
+#define V_BCM1480_MC_DRAM_TYPE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DRAM_TYPE)
+#define G_BCM1480_MC_DRAM_TYPE(x) _SB_GETVALUE(x, S_BCM1480_MC_DRAM_TYPE, M_BCM1480_MC_DRAM_TYPE)
+
+#define K_BCM1480_MC_DRAM_TYPE_JEDEC 0
+#define K_BCM1480_MC_DRAM_TYPE_FCRAM 1
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define K_BCM1480_MC_DRAM_TYPE_DDR2 2
+#endif
+
+#define K_BCM1480_MC_DRAM_TYPE_DDR2_PASS1 0
+
+#define V_BCM1480_MC_DRAM_TYPE_JEDEC V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_JEDEC)
+#define V_BCM1480_MC_DRAM_TYPE_FCRAM V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_FCRAM)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define V_BCM1480_MC_DRAM_TYPE_DDR2 V_BCM1480_MC_DRAM_TYPE(K_BCM1480_MC_DRAM_TYPE_DDR2)
+#endif
+
+#define M_BCM1480_MC_GANGED _SB_MAKEMASK1(36)
+#define M_BCM1480_MC_BY9_INTF _SB_MAKEMASK1(37)
+#define M_BCM1480_MC_FORCE_ECC64 _SB_MAKEMASK1(38)
+#define M_BCM1480_MC_ECC_DISABLE _SB_MAKEMASK1(39)
+
+#define S_BCM1480_MC_PG_POLICY 40
+#define M_BCM1480_MC_PG_POLICY _SB_MAKEMASK(2, S_BCM1480_MC_PG_POLICY)
+#define V_BCM1480_MC_PG_POLICY(x) _SB_MAKEVALUE(x, S_BCM1480_MC_PG_POLICY)
+#define G_BCM1480_MC_PG_POLICY(x) _SB_GETVALUE(x, S_BCM1480_MC_PG_POLICY, M_BCM1480_MC_PG_POLICY)
+
+#define K_BCM1480_MC_PG_POLICY_CLOSED 0
+#define K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK 1
+
+#define V_BCM1480_MC_PG_POLICY_CLOSED V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CLOSED)
+#define V_BCM1480_MC_PG_POLICY_CAS_TIME_CHK V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_2T_CMD _SB_MAKEMASK1(42)
+#define M_BCM1480_MC_ECC_COR_DIS _SB_MAKEMASK1(43)
+#endif
+
+#define V_BCM1480_MC_DRAMMODE_DEFAULT V_BCM1480_MC_EMODE_DEFAULT | V_BCM1480_MC_MODE_DEFAULT | V_BCM1480_MC_DRAM_TYPE_JEDEC | \
+ V_BCM1480_MC_PG_POLICY(K_BCM1480_MC_PG_POLICY_CAS_TIME_CHK)
+
+/*
+ * Memory Clock Configuration Register (Table 92)
+ */
+
+#define S_BCM1480_MC_CLK_RATIO 0
+#define M_BCM1480_MC_CLK_RATIO _SB_MAKEMASK(6, S_BCM1480_MC_CLK_RATIO)
+#define V_BCM1480_MC_CLK_RATIO(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CLK_RATIO)
+#define G_BCM1480_MC_CLK_RATIO(x) _SB_GETVALUE(x, S_BCM1480_MC_CLK_RATIO, M_BCM1480_MC_CLK_RATIO)
+
+#define V_BCM1480_MC_CLK_RATIO_DEFAULT V_BCM1480_MC_CLK_RATIO(10)
+
+#define S_BCM1480_MC_REF_RATE 8
+#define M_BCM1480_MC_REF_RATE _SB_MAKEMASK(8, S_BCM1480_MC_REF_RATE)
+#define V_BCM1480_MC_REF_RATE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_REF_RATE)
+#define G_BCM1480_MC_REF_RATE(x) _SB_GETVALUE(x, S_BCM1480_MC_REF_RATE, M_BCM1480_MC_REF_RATE)
+
+#define K_BCM1480_MC_REF_RATE_100MHz 0x31
+#define K_BCM1480_MC_REF_RATE_200MHz 0x62
+#define K_BCM1480_MC_REF_RATE_400MHz 0xC4
+
+#define V_BCM1480_MC_REF_RATE_100MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_100MHz)
+#define V_BCM1480_MC_REF_RATE_200MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_200MHz)
+#define V_BCM1480_MC_REF_RATE_400MHz V_BCM1480_MC_REF_RATE(K_BCM1480_MC_REF_RATE_400MHz)
+#define V_BCM1480_MC_REF_RATE_DEFAULT V_BCM1480_MC_REF_RATE_400MHz
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_AUTO_REF_DIS _SB_MAKEMASK1(16)
+#endif
+
+/*
+ * ODT Register (Table 99)
+ */
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_RD_ODT0_CS0 _SB_MAKEMASK1(0)
+#define M_BCM1480_MC_RD_ODT0_CS2 _SB_MAKEMASK1(1)
+#define M_BCM1480_MC_RD_ODT0_CS4 _SB_MAKEMASK1(2)
+#define M_BCM1480_MC_RD_ODT0_CS6 _SB_MAKEMASK1(3)
+#define M_BCM1480_MC_WR_ODT0_CS0 _SB_MAKEMASK1(4)
+#define M_BCM1480_MC_WR_ODT0_CS2 _SB_MAKEMASK1(5)
+#define M_BCM1480_MC_WR_ODT0_CS4 _SB_MAKEMASK1(6)
+#define M_BCM1480_MC_WR_ODT0_CS6 _SB_MAKEMASK1(7)
+#define M_BCM1480_MC_RD_ODT2_CS0 _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_RD_ODT2_CS2 _SB_MAKEMASK1(9)
+#define M_BCM1480_MC_RD_ODT2_CS4 _SB_MAKEMASK1(10)
+#define M_BCM1480_MC_RD_ODT2_CS6 _SB_MAKEMASK1(11)
+#define M_BCM1480_MC_WR_ODT2_CS0 _SB_MAKEMASK1(12)
+#define M_BCM1480_MC_WR_ODT2_CS2 _SB_MAKEMASK1(13)
+#define M_BCM1480_MC_WR_ODT2_CS4 _SB_MAKEMASK1(14)
+#define M_BCM1480_MC_WR_ODT2_CS6 _SB_MAKEMASK1(15)
+#define M_BCM1480_MC_RD_ODT4_CS0 _SB_MAKEMASK1(16)
+#define M_BCM1480_MC_RD_ODT4_CS2 _SB_MAKEMASK1(17)
+#define M_BCM1480_MC_RD_ODT4_CS4 _SB_MAKEMASK1(18)
+#define M_BCM1480_MC_RD_ODT4_CS6 _SB_MAKEMASK1(19)
+#define M_BCM1480_MC_WR_ODT4_CS0 _SB_MAKEMASK1(20)
+#define M_BCM1480_MC_WR_ODT4_CS2 _SB_MAKEMASK1(21)
+#define M_BCM1480_MC_WR_ODT4_CS4 _SB_MAKEMASK1(22)
+#define M_BCM1480_MC_WR_ODT4_CS6 _SB_MAKEMASK1(23)
+#define M_BCM1480_MC_RD_ODT6_CS0 _SB_MAKEMASK1(24)
+#define M_BCM1480_MC_RD_ODT6_CS2 _SB_MAKEMASK1(25)
+#define M_BCM1480_MC_RD_ODT6_CS4 _SB_MAKEMASK1(26)
+#define M_BCM1480_MC_RD_ODT6_CS6 _SB_MAKEMASK1(27)
+#define M_BCM1480_MC_WR_ODT6_CS0 _SB_MAKEMASK1(28)
+#define M_BCM1480_MC_WR_ODT6_CS2 _SB_MAKEMASK1(29)
+#define M_BCM1480_MC_WR_ODT6_CS4 _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_WR_ODT6_CS6 _SB_MAKEMASK1(31)
+
+#define M_BCM1480_MC_CS_ODD_ODT_EN _SB_MAKEMASK1(32)
+
+#define S_BCM1480_MC_ODT0 0
+#define M_BCM1480_MC_ODT0 _SB_MAKEMASK(8, S_BCM1480_MC_ODT0)
+#define V_BCM1480_MC_ODT0(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ODT0)
+
+#define S_BCM1480_MC_ODT2 8
+#define M_BCM1480_MC_ODT2 _SB_MAKEMASK(8, S_BCM1480_MC_ODT2)
+#define V_BCM1480_MC_ODT2(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ODT2)
+
+#define S_BCM1480_MC_ODT4 16
+#define M_BCM1480_MC_ODT4 _SB_MAKEMASK(8, S_BCM1480_MC_ODT4)
+#define V_BCM1480_MC_ODT4(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ODT4)
+
+#define S_BCM1480_MC_ODT6 24
+#define M_BCM1480_MC_ODT6 _SB_MAKEMASK(8, S_BCM1480_MC_ODT6)
+#define V_BCM1480_MC_ODT6(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ODT6)
+#endif
+
+/*
+ * Memory DLL Configuration Register (Table 93)
+ */
+
+#define S_BCM1480_MC_ADDR_COARSE_ADJ 0
+#define M_BCM1480_MC_ADDR_COARSE_ADJ _SB_MAKEMASK(6, S_BCM1480_MC_ADDR_COARSE_ADJ)
+#define V_BCM1480_MC_ADDR_COARSE_ADJ(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ADDR_COARSE_ADJ)
+#define G_BCM1480_MC_ADDR_COARSE_ADJ(x) _SB_GETVALUE(x, S_BCM1480_MC_ADDR_COARSE_ADJ, M_BCM1480_MC_ADDR_COARSE_ADJ)
+#define V_BCM1480_MC_ADDR_COARSE_ADJ_DEFAULT V_BCM1480_MC_ADDR_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_ADDR_FREQ_RANGE 8
+#define M_BCM1480_MC_ADDR_FREQ_RANGE _SB_MAKEMASK(4, S_BCM1480_MC_ADDR_FREQ_RANGE)
+#define V_BCM1480_MC_ADDR_FREQ_RANGE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ADDR_FREQ_RANGE)
+#define G_BCM1480_MC_ADDR_FREQ_RANGE(x) _SB_GETVALUE(x, S_BCM1480_MC_ADDR_FREQ_RANGE, M_BCM1480_MC_ADDR_FREQ_RANGE)
+#define V_BCM1480_MC_ADDR_FREQ_RANGE_DEFAULT V_BCM1480_MC_ADDR_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_ADDR_FINE_ADJ 8
+#define M_BCM1480_MC_ADDR_FINE_ADJ _SB_MAKEMASK(4, S_BCM1480_MC_ADDR_FINE_ADJ)
+#define V_BCM1480_MC_ADDR_FINE_ADJ(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ADDR_FINE_ADJ)
+#define G_BCM1480_MC_ADDR_FINE_ADJ(x) _SB_GETVALUE(x, S_BCM1480_MC_ADDR_FINE_ADJ, M_BCM1480_MC_ADDR_FINE_ADJ)
+#define V_BCM1480_MC_ADDR_FINE_ADJ_DEFAULT V_BCM1480_MC_ADDR_FINE_ADJ(0x8)
+
+#define S_BCM1480_MC_DQI_COARSE_ADJ 16
+#define M_BCM1480_MC_DQI_COARSE_ADJ _SB_MAKEMASK(6, S_BCM1480_MC_DQI_COARSE_ADJ)
+#define V_BCM1480_MC_DQI_COARSE_ADJ(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DQI_COARSE_ADJ)
+#define G_BCM1480_MC_DQI_COARSE_ADJ(x) _SB_GETVALUE(x, S_BCM1480_MC_DQI_COARSE_ADJ, M_BCM1480_MC_DQI_COARSE_ADJ)
+#define V_BCM1480_MC_DQI_COARSE_ADJ_DEFAULT V_BCM1480_MC_DQI_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DQI_FREQ_RANGE 24
+#define M_BCM1480_MC_DQI_FREQ_RANGE _SB_MAKEMASK(4, S_BCM1480_MC_DQI_FREQ_RANGE)
+#define V_BCM1480_MC_DQI_FREQ_RANGE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DQI_FREQ_RANGE)
+#define G_BCM1480_MC_DQI_FREQ_RANGE(x) _SB_GETVALUE(x, S_BCM1480_MC_DQI_FREQ_RANGE, M_BCM1480_MC_DQI_FREQ_RANGE)
+#define V_BCM1480_MC_DQI_FREQ_RANGE_DEFAULT V_BCM1480_MC_DQI_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DQI_FINE_ADJ 24
+#define M_BCM1480_MC_DQI_FINE_ADJ _SB_MAKEMASK(4, S_BCM1480_MC_DQI_FINE_ADJ)
+#define V_BCM1480_MC_DQI_FINE_ADJ(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DQI_FINE_ADJ)
+#define G_BCM1480_MC_DQI_FINE_ADJ(x) _SB_GETVALUE(x, S_BCM1480_MC_DQI_FINE_ADJ, M_BCM1480_MC_DQI_FINE_ADJ)
+#define V_BCM1480_MC_DQI_FINE_ADJ_DEFAULT V_BCM1480_MC_DQI_FINE_ADJ(0x8)
+
+#define S_BCM1480_MC_DQO_COARSE_ADJ 32
+#define M_BCM1480_MC_DQO_COARSE_ADJ _SB_MAKEMASK(6, S_BCM1480_MC_DQO_COARSE_ADJ)
+#define V_BCM1480_MC_DQO_COARSE_ADJ(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DQO_COARSE_ADJ)
+#define G_BCM1480_MC_DQO_COARSE_ADJ(x) _SB_GETVALUE(x, S_BCM1480_MC_DQO_COARSE_ADJ, M_BCM1480_MC_DQO_COARSE_ADJ)
+#define V_BCM1480_MC_DQO_COARSE_ADJ_DEFAULT V_BCM1480_MC_DQO_COARSE_ADJ(0x0)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DQO_FREQ_RANGE 40
+#define M_BCM1480_MC_DQO_FREQ_RANGE _SB_MAKEMASK(4, S_BCM1480_MC_DQO_FREQ_RANGE)
+#define V_BCM1480_MC_DQO_FREQ_RANGE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DQO_FREQ_RANGE)
+#define G_BCM1480_MC_DQO_FREQ_RANGE(x) _SB_GETVALUE(x, S_BCM1480_MC_DQO_FREQ_RANGE, M_BCM1480_MC_DQO_FREQ_RANGE)
+#define V_BCM1480_MC_DQO_FREQ_RANGE_DEFAULT V_BCM1480_MC_DQO_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DQO_FINE_ADJ 40
+#define M_BCM1480_MC_DQO_FINE_ADJ _SB_MAKEMASK(4, S_BCM1480_MC_DQO_FINE_ADJ)
+#define V_BCM1480_MC_DQO_FINE_ADJ(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DQO_FINE_ADJ)
+#define G_BCM1480_MC_DQO_FINE_ADJ(x) _SB_GETVALUE(x, S_BCM1480_MC_DQO_FINE_ADJ, M_BCM1480_MC_DQO_FINE_ADJ)
+#define V_BCM1480_MC_DQO_FINE_ADJ_DEFAULT V_BCM1480_MC_DQO_FINE_ADJ(0x8)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_PDSEL 44
+#define M_BCM1480_MC_DLL_PDSEL _SB_MAKEMASK(2, S_BCM1480_MC_DLL_PDSEL)
+#define V_BCM1480_MC_DLL_PDSEL(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DLL_PDSEL)
+#define G_BCM1480_MC_DLL_PDSEL(x) _SB_GETVALUE(x, S_BCM1480_MC_DLL_PDSEL, M_BCM1480_MC_DLL_PDSEL)
+#define V_BCM1480_MC_DLL_DEFAULT_PDSEL V_BCM1480_MC_DLL_PDSEL(0x0)
+
+#define M_BCM1480_MC_DLL_REGBYPASS _SB_MAKEMASK1(46)
+#define M_BCM1480_MC_DQO_SHIFT _SB_MAKEMASK1(47)
+#endif
+
+#define S_BCM1480_MC_DLL_DEFAULT 48
+#define M_BCM1480_MC_DLL_DEFAULT _SB_MAKEMASK(6, S_BCM1480_MC_DLL_DEFAULT)
+#define V_BCM1480_MC_DLL_DEFAULT(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DLL_DEFAULT)
+#define G_BCM1480_MC_DLL_DEFAULT(x) _SB_GETVALUE(x, S_BCM1480_MC_DLL_DEFAULT, M_BCM1480_MC_DLL_DEFAULT)
+#define V_BCM1480_MC_DLL_DEFAULT_DEFAULT V_BCM1480_MC_DLL_DEFAULT(0x10)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_REGCTRL 54
+#define M_BCM1480_MC_DLL_REGCTRL _SB_MAKEMASK(2, S_BCM1480_MC_DLL_REGCTRL)
+#define V_BCM1480_MC_DLL_REGCTRL(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DLL_REGCTRL)
+#define G_BCM1480_MC_DLL_REGCTRL(x) _SB_GETVALUE(x, S_BCM1480_MC_DLL_REGCTRL, M_BCM1480_MC_DLL_REGCTRL)
+#define V_BCM1480_MC_DLL_DEFAULT_REGCTRL V_BCM1480_MC_DLL_REGCTRL(0x0)
+#endif
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_FREQ_RANGE 56
+#define M_BCM1480_MC_DLL_FREQ_RANGE _SB_MAKEMASK(4, S_BCM1480_MC_DLL_FREQ_RANGE)
+#define V_BCM1480_MC_DLL_FREQ_RANGE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DLL_FREQ_RANGE)
+#define G_BCM1480_MC_DLL_FREQ_RANGE(x) _SB_GETVALUE(x, S_BCM1480_MC_DLL_FREQ_RANGE, M_BCM1480_MC_DLL_FREQ_RANGE)
+#define V_BCM1480_MC_DLL_FREQ_RANGE_DEFAULT V_BCM1480_MC_DLL_FREQ_RANGE(0x4)
+#endif
+
+#define S_BCM1480_MC_DLL_STEP_SIZE 56
+#define M_BCM1480_MC_DLL_STEP_SIZE _SB_MAKEMASK(4, S_BCM1480_MC_DLL_STEP_SIZE)
+#define V_BCM1480_MC_DLL_STEP_SIZE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DLL_STEP_SIZE)
+#define G_BCM1480_MC_DLL_STEP_SIZE(x) _SB_GETVALUE(x, S_BCM1480_MC_DLL_STEP_SIZE, M_BCM1480_MC_DLL_STEP_SIZE)
+#define V_BCM1480_MC_DLL_STEP_SIZE_DEFAULT V_BCM1480_MC_DLL_STEP_SIZE(0x8)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_DLL_BGCTRL 60
+#define M_BCM1480_MC_DLL_BGCTRL _SB_MAKEMASK(2, S_BCM1480_MC_DLL_BGCTRL)
+#define V_BCM1480_MC_DLL_BGCTRL(x) _SB_MAKEVALUE(x, S_BCM1480_MC_DLL_BGCTRL)
+#define G_BCM1480_MC_DLL_BGCTRL(x) _SB_GETVALUE(x, S_BCM1480_MC_DLL_BGCTRL, M_BCM1480_MC_DLL_BGCTRL)
+#define V_BCM1480_MC_DLL_DEFAULT_BGCTRL V_BCM1480_MC_DLL_BGCTRL(0x0)
+#endif
+
+#define M_BCM1480_MC_DLL_BYPASS _SB_MAKEMASK1(63)
+
+/*
+ * Memory Drive Configuration Register (Table 94)
+ */
+
+#define S_BCM1480_MC_RTT_BYP_PULLDOWN 0
+#define M_BCM1480_MC_RTT_BYP_PULLDOWN _SB_MAKEMASK(3, S_BCM1480_MC_RTT_BYP_PULLDOWN)
+#define V_BCM1480_MC_RTT_BYP_PULLDOWN(x) _SB_MAKEVALUE(x, S_BCM1480_MC_RTT_BYP_PULLDOWN)
+#define G_BCM1480_MC_RTT_BYP_PULLDOWN(x) _SB_GETVALUE(x, S_BCM1480_MC_RTT_BYP_PULLDOWN, M_BCM1480_MC_RTT_BYP_PULLDOWN)
+
+#define S_BCM1480_MC_RTT_BYP_PULLUP 6
+#define M_BCM1480_MC_RTT_BYP_PULLUP _SB_MAKEMASK(3, S_BCM1480_MC_RTT_BYP_PULLUP)
+#define V_BCM1480_MC_RTT_BYP_PULLUP(x) _SB_MAKEVALUE(x, S_BCM1480_MC_RTT_BYP_PULLUP)
+#define G_BCM1480_MC_RTT_BYP_PULLUP(x) _SB_GETVALUE(x, S_BCM1480_MC_RTT_BYP_PULLUP, M_BCM1480_MC_RTT_BYP_PULLUP)
+
+#define M_BCM1480_MC_RTT_BYPASS _SB_MAKEMASK1(8)
+#define M_BCM1480_MC_RTT_COMP_MOV_AVG _SB_MAKEMASK1(9)
+
+#define S_BCM1480_MC_PVT_BYP_C1_PULLDOWN 10
+#define M_BCM1480_MC_PVT_BYP_C1_PULLDOWN _SB_MAKEMASK(4, S_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+#define V_BCM1480_MC_PVT_BYP_C1_PULLDOWN(x) _SB_MAKEVALUE(x, S_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+#define G_BCM1480_MC_PVT_BYP_C1_PULLDOWN(x) _SB_GETVALUE(x, S_BCM1480_MC_PVT_BYP_C1_PULLDOWN, M_BCM1480_MC_PVT_BYP_C1_PULLDOWN)
+
+#define S_BCM1480_MC_PVT_BYP_C1_PULLUP 15
+#define M_BCM1480_MC_PVT_BYP_C1_PULLUP _SB_MAKEMASK(4, S_BCM1480_MC_PVT_BYP_C1_PULLUP)
+#define V_BCM1480_MC_PVT_BYP_C1_PULLUP(x) _SB_MAKEVALUE(x, S_BCM1480_MC_PVT_BYP_C1_PULLUP)
+#define G_BCM1480_MC_PVT_BYP_C1_PULLUP(x) _SB_GETVALUE(x, S_BCM1480_MC_PVT_BYP_C1_PULLUP, M_BCM1480_MC_PVT_BYP_C1_PULLUP)
+
+#define S_BCM1480_MC_PVT_BYP_C2_PULLDOWN 20
+#define M_BCM1480_MC_PVT_BYP_C2_PULLDOWN _SB_MAKEMASK(4, S_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+#define V_BCM1480_MC_PVT_BYP_C2_PULLDOWN(x) _SB_MAKEVALUE(x, S_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+#define G_BCM1480_MC_PVT_BYP_C2_PULLDOWN(x) _SB_GETVALUE(x, S_BCM1480_MC_PVT_BYP_C2_PULLDOWN, M_BCM1480_MC_PVT_BYP_C2_PULLDOWN)
+
+#define S_BCM1480_MC_PVT_BYP_C2_PULLUP 25
+#define M_BCM1480_MC_PVT_BYP_C2_PULLUP _SB_MAKEMASK(4, S_BCM1480_MC_PVT_BYP_C2_PULLUP)
+#define V_BCM1480_MC_PVT_BYP_C2_PULLUP(x) _SB_MAKEVALUE(x, S_BCM1480_MC_PVT_BYP_C2_PULLUP)
+#define G_BCM1480_MC_PVT_BYP_C2_PULLUP(x) _SB_GETVALUE(x, S_BCM1480_MC_PVT_BYP_C2_PULLUP, M_BCM1480_MC_PVT_BYP_C2_PULLUP)
+
+#define M_BCM1480_MC_PVT_BYPASS _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_PVT_COMP_MOV_AVG _SB_MAKEMASK1(31)
+
+#define M_BCM1480_MC_CLK_CLASS _SB_MAKEMASK1(34)
+#define M_BCM1480_MC_DATA_CLASS _SB_MAKEMASK1(35)
+#define M_BCM1480_MC_ADDR_CLASS _SB_MAKEMASK1(36)
+
+#define M_BCM1480_MC_DQ_ODT_75 _SB_MAKEMASK1(37)
+#define M_BCM1480_MC_DQ_ODT_150 _SB_MAKEMASK1(38)
+#define M_BCM1480_MC_DQS_ODT_75 _SB_MAKEMASK1(39)
+#define M_BCM1480_MC_DQS_ODT_150 _SB_MAKEMASK1(40)
+#define M_BCM1480_MC_DQS_DIFF _SB_MAKEMASK1(41)
+
+/*
+ * ECC Test Data Register (Table 95)
+ */
+
+#define S_BCM1480_MC_DATA_INVERT 0
+#define M_DATA_ECC_INVERT _SB_MAKEMASK(64, S_BCM1480_MC_ECC_INVERT)
+
+/*
+ * ECC Test ECC Register (Table 96)
+ */
+
+#define S_BCM1480_MC_ECC_INVERT 0
+#define M_BCM1480_MC_ECC_INVERT _SB_MAKEMASK(8, S_BCM1480_MC_ECC_INVERT)
+
+/*
+ * SDRAM Timing Register (Table 97)
+ */
+
+#define S_BCM1480_MC_tRCD 0
+#define M_BCM1480_MC_tRCD _SB_MAKEMASK(4, S_BCM1480_MC_tRCD)
+#define V_BCM1480_MC_tRCD(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tRCD)
+#define G_BCM1480_MC_tRCD(x) _SB_GETVALUE(x, S_BCM1480_MC_tRCD, M_BCM1480_MC_tRCD)
+#define K_BCM1480_MC_tRCD_DEFAULT 3
+#define V_BCM1480_MC_tRCD_DEFAULT V_BCM1480_MC_tRCD(K_BCM1480_MC_tRCD_DEFAULT)
+
+#define S_BCM1480_MC_tCL 4
+#define M_BCM1480_MC_tCL _SB_MAKEMASK(4, S_BCM1480_MC_tCL)
+#define V_BCM1480_MC_tCL(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tCL)
+#define G_BCM1480_MC_tCL(x) _SB_GETVALUE(x, S_BCM1480_MC_tCL, M_BCM1480_MC_tCL)
+#define K_BCM1480_MC_tCL_DEFAULT 2
+#define V_BCM1480_MC_tCL_DEFAULT V_BCM1480_MC_tCL(K_BCM1480_MC_tCL_DEFAULT)
+
+#define M_BCM1480_MC_tCrDh _SB_MAKEMASK1(8)
+
+#define S_BCM1480_MC_tWR 9
+#define M_BCM1480_MC_tWR _SB_MAKEMASK(3, S_BCM1480_MC_tWR)
+#define V_BCM1480_MC_tWR(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tWR)
+#define G_BCM1480_MC_tWR(x) _SB_GETVALUE(x, S_BCM1480_MC_tWR, M_BCM1480_MC_tWR)
+#define K_BCM1480_MC_tWR_DEFAULT 2
+#define V_BCM1480_MC_tWR_DEFAULT V_BCM1480_MC_tWR(K_BCM1480_MC_tWR_DEFAULT)
+
+#define S_BCM1480_MC_tCwD 12
+#define M_BCM1480_MC_tCwD _SB_MAKEMASK(4, S_BCM1480_MC_tCwD)
+#define V_BCM1480_MC_tCwD(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tCwD)
+#define G_BCM1480_MC_tCwD(x) _SB_GETVALUE(x, S_BCM1480_MC_tCwD, M_BCM1480_MC_tCwD)
+#define K_BCM1480_MC_tCwD_DEFAULT 1
+#define V_BCM1480_MC_tCwD_DEFAULT V_BCM1480_MC_tCwD(K_BCM1480_MC_tCwD_DEFAULT)
+
+#define S_BCM1480_MC_tRP 16
+#define M_BCM1480_MC_tRP _SB_MAKEMASK(4, S_BCM1480_MC_tRP)
+#define V_BCM1480_MC_tRP(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tRP)
+#define G_BCM1480_MC_tRP(x) _SB_GETVALUE(x, S_BCM1480_MC_tRP, M_BCM1480_MC_tRP)
+#define K_BCM1480_MC_tRP_DEFAULT 4
+#define V_BCM1480_MC_tRP_DEFAULT V_BCM1480_MC_tRP(K_BCM1480_MC_tRP_DEFAULT)
+
+#define S_BCM1480_MC_tRRD 20
+#define M_BCM1480_MC_tRRD _SB_MAKEMASK(4, S_BCM1480_MC_tRRD)
+#define V_BCM1480_MC_tRRD(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tRRD)
+#define G_BCM1480_MC_tRRD(x) _SB_GETVALUE(x, S_BCM1480_MC_tRRD, M_BCM1480_MC_tRRD)
+#define K_BCM1480_MC_tRRD_DEFAULT 2
+#define V_BCM1480_MC_tRRD_DEFAULT V_BCM1480_MC_tRRD(K_BCM1480_MC_tRRD_DEFAULT)
+
+#define S_BCM1480_MC_tRCw 24
+#define M_BCM1480_MC_tRCw _SB_MAKEMASK(5, S_BCM1480_MC_tRCw)
+#define V_BCM1480_MC_tRCw(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tRCw)
+#define G_BCM1480_MC_tRCw(x) _SB_GETVALUE(x, S_BCM1480_MC_tRCw, M_BCM1480_MC_tRCw)
+#define K_BCM1480_MC_tRCw_DEFAULT 10
+#define V_BCM1480_MC_tRCw_DEFAULT V_BCM1480_MC_tRCw(K_BCM1480_MC_tRCw_DEFAULT)
+
+#define S_BCM1480_MC_tRCr 32
+#define M_BCM1480_MC_tRCr _SB_MAKEMASK(5, S_BCM1480_MC_tRCr)
+#define V_BCM1480_MC_tRCr(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tRCr)
+#define G_BCM1480_MC_tRCr(x) _SB_GETVALUE(x, S_BCM1480_MC_tRCr, M_BCM1480_MC_tRCr)
+#define K_BCM1480_MC_tRCr_DEFAULT 9
+#define V_BCM1480_MC_tRCr_DEFAULT V_BCM1480_MC_tRCr(K_BCM1480_MC_tRCr_DEFAULT)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define S_BCM1480_MC_tFAW 40
+#define M_BCM1480_MC_tFAW _SB_MAKEMASK(6, S_BCM1480_MC_tFAW)
+#define V_BCM1480_MC_tFAW(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tFAW)
+#define G_BCM1480_MC_tFAW(x) _SB_GETVALUE(x, S_BCM1480_MC_tFAW, M_BCM1480_MC_tFAW)
+#define K_BCM1480_MC_tFAW_DEFAULT 0
+#define V_BCM1480_MC_tFAW_DEFAULT V_BCM1480_MC_tFAW(K_BCM1480_MC_tFAW_DEFAULT)
+#endif
+
+#define S_BCM1480_MC_tRFC 48
+#define M_BCM1480_MC_tRFC _SB_MAKEMASK(7, S_BCM1480_MC_tRFC)
+#define V_BCM1480_MC_tRFC(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tRFC)
+#define G_BCM1480_MC_tRFC(x) _SB_GETVALUE(x, S_BCM1480_MC_tRFC, M_BCM1480_MC_tRFC)
+#define K_BCM1480_MC_tRFC_DEFAULT 12
+#define V_BCM1480_MC_tRFC_DEFAULT V_BCM1480_MC_tRFC(K_BCM1480_MC_tRFC_DEFAULT)
+
+#define S_BCM1480_MC_tFIFO 56
+#define M_BCM1480_MC_tFIFO _SB_MAKEMASK(2, S_BCM1480_MC_tFIFO)
+#define V_BCM1480_MC_tFIFO(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tFIFO)
+#define G_BCM1480_MC_tFIFO(x) _SB_GETVALUE(x, S_BCM1480_MC_tFIFO, M_BCM1480_MC_tFIFO)
+#define K_BCM1480_MC_tFIFO_DEFAULT 0
+#define V_BCM1480_MC_tFIFO_DEFAULT V_BCM1480_MC_tFIFO(K_BCM1480_MC_tFIFO_DEFAULT)
+
+#define S_BCM1480_MC_tW2R 58
+#define M_BCM1480_MC_tW2R _SB_MAKEMASK(2, S_BCM1480_MC_tW2R)
+#define V_BCM1480_MC_tW2R(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tW2R)
+#define G_BCM1480_MC_tW2R(x) _SB_GETVALUE(x, S_BCM1480_MC_tW2R, M_BCM1480_MC_tW2R)
+#define K_BCM1480_MC_tW2R_DEFAULT 1
+#define V_BCM1480_MC_tW2R_DEFAULT V_BCM1480_MC_tW2R(K_BCM1480_MC_tW2R_DEFAULT)
+
+#define S_BCM1480_MC_tR2W 60
+#define M_BCM1480_MC_tR2W _SB_MAKEMASK(2, S_BCM1480_MC_tR2W)
+#define V_BCM1480_MC_tR2W(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tR2W)
+#define G_BCM1480_MC_tR2W(x) _SB_GETVALUE(x, S_BCM1480_MC_tR2W, M_BCM1480_MC_tR2W)
+#define K_BCM1480_MC_tR2W_DEFAULT 0
+#define V_BCM1480_MC_tR2W_DEFAULT V_BCM1480_MC_tR2W(K_BCM1480_MC_tR2W_DEFAULT)
+
+#define M_BCM1480_MC_tR2R _SB_MAKEMASK1(62)
+
+#define V_BCM1480_MC_TIMING_DEFAULT (M_BCM1480_MC_tR2R | \
+ V_BCM1480_MC_tFIFO_DEFAULT | \
+ V_BCM1480_MC_tR2W_DEFAULT | \
+ V_BCM1480_MC_tW2R_DEFAULT | \
+ V_BCM1480_MC_tRFC_DEFAULT | \
+ V_BCM1480_MC_tRCr_DEFAULT | \
+ V_BCM1480_MC_tRCw_DEFAULT | \
+ V_BCM1480_MC_tRRD_DEFAULT | \
+ V_BCM1480_MC_tRP_DEFAULT | \
+ V_BCM1480_MC_tCwD_DEFAULT | \
+ V_BCM1480_MC_tWR_DEFAULT | \
+ M_BCM1480_MC_tCrDh | \
+ V_BCM1480_MC_tCL_DEFAULT | \
+ V_BCM1480_MC_tRCD_DEFAULT)
+
+/*
+ * SDRAM Timing Register 2
+ */
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+
+#define S_BCM1480_MC_tAL 0
+#define M_BCM1480_MC_tAL _SB_MAKEMASK(4, S_BCM1480_MC_tAL)
+#define V_BCM1480_MC_tAL(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tAL)
+#define G_BCM1480_MC_tAL(x) _SB_GETVALUE(x, S_BCM1480_MC_tAL, M_BCM1480_MC_tAL)
+#define K_BCM1480_MC_tAL_DEFAULT 0
+#define V_BCM1480_MC_tAL_DEFAULT V_BCM1480_MC_tAL(K_BCM1480_MC_tAL_DEFAULT)
+
+#define S_BCM1480_MC_tRTP 4
+#define M_BCM1480_MC_tRTP _SB_MAKEMASK(3, S_BCM1480_MC_tRTP)
+#define V_BCM1480_MC_tRTP(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tRTP)
+#define G_BCM1480_MC_tRTP(x) _SB_GETVALUE(x, S_BCM1480_MC_tRTP, M_BCM1480_MC_tRTP)
+#define K_BCM1480_MC_tRTP_DEFAULT 2
+#define V_BCM1480_MC_tRTP_DEFAULT V_BCM1480_MC_tRTP(K_BCM1480_MC_tRTP_DEFAULT)
+
+#define S_BCM1480_MC_tW2W 8
+#define M_BCM1480_MC_tW2W _SB_MAKEMASK(2, S_BCM1480_MC_tW2W)
+#define V_BCM1480_MC_tW2W(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tW2W)
+#define G_BCM1480_MC_tW2W(x) _SB_GETVALUE(x, S_BCM1480_MC_tW2W, M_BCM1480_MC_tW2W)
+#define K_BCM1480_MC_tW2W_DEFAULT 0
+#define V_BCM1480_MC_tW2W_DEFAULT V_BCM1480_MC_tW2W(K_BCM1480_MC_tW2W_DEFAULT)
+
+#define S_BCM1480_MC_tRAP 12
+#define M_BCM1480_MC_tRAP _SB_MAKEMASK(4, S_BCM1480_MC_tRAP)
+#define V_BCM1480_MC_tRAP(x) _SB_MAKEVALUE(x, S_BCM1480_MC_tRAP)
+#define G_BCM1480_MC_tRAP(x) _SB_GETVALUE(x, S_BCM1480_MC_tRAP, M_BCM1480_MC_tRAP)
+#define K_BCM1480_MC_tRAP_DEFAULT 0
+#define V_BCM1480_MC_tRAP_DEFAULT V_BCM1480_MC_tRAP(K_BCM1480_MC_tRAP_DEFAULT)
+
+#endif
+
+
+
+/*
+ * Global Registers: single instances per BCM1480
+ */
+
+/*
+ * Global Configuration Register (Table 99)
+ */
+
+#define S_BCM1480_MC_BLK_SET_MARK 8
+#define M_BCM1480_MC_BLK_SET_MARK _SB_MAKEMASK(4, S_BCM1480_MC_BLK_SET_MARK)
+#define V_BCM1480_MC_BLK_SET_MARK(x) _SB_MAKEVALUE(x, S_BCM1480_MC_BLK_SET_MARK)
+#define G_BCM1480_MC_BLK_SET_MARK(x) _SB_GETVALUE(x, S_BCM1480_MC_BLK_SET_MARK, M_BCM1480_MC_BLK_SET_MARK)
+
+#define S_BCM1480_MC_BLK_CLR_MARK 12
+#define M_BCM1480_MC_BLK_CLR_MARK _SB_MAKEMASK(4, S_BCM1480_MC_BLK_CLR_MARK)
+#define V_BCM1480_MC_BLK_CLR_MARK(x) _SB_MAKEVALUE(x, S_BCM1480_MC_BLK_CLR_MARK)
+#define G_BCM1480_MC_BLK_CLR_MARK(x) _SB_GETVALUE(x, S_BCM1480_MC_BLK_CLR_MARK, M_BCM1480_MC_BLK_CLR_MARK)
+
+#define M_BCM1480_MC_PKT_PRIORITY _SB_MAKEMASK1(16)
+
+#define S_BCM1480_MC_MAX_AGE 20
+#define M_BCM1480_MC_MAX_AGE _SB_MAKEMASK(4, S_BCM1480_MC_MAX_AGE)
+#define V_BCM1480_MC_MAX_AGE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_MAX_AGE)
+#define G_BCM1480_MC_MAX_AGE(x) _SB_GETVALUE(x, S_BCM1480_MC_MAX_AGE, M_BCM1480_MC_MAX_AGE)
+
+#define M_BCM1480_MC_BERR_DISABLE _SB_MAKEMASK1(29)
+#define M_BCM1480_MC_FORCE_SEQ _SB_MAKEMASK1(30)
+#define M_BCM1480_MC_VGEN _SB_MAKEMASK1(32)
+
+#define S_BCM1480_MC_SLEW 33
+#define M_BCM1480_MC_SLEW _SB_MAKEMASK(2, S_BCM1480_MC_SLEW)
+#define V_BCM1480_MC_SLEW(x) _SB_MAKEVALUE(x, S_BCM1480_MC_SLEW)
+#define G_BCM1480_MC_SLEW(x) _SB_GETVALUE(x, S_BCM1480_MC_SLEW, M_BCM1480_MC_SLEW)
+
+#define M_BCM1480_MC_SSTL_VOLTAGE _SB_MAKEMASK1(35)
+
+/*
+ * Global Channel Interleave Register (Table 100)
+ */
+
+#define S_BCM1480_MC_INTLV0 0
+#define M_BCM1480_MC_INTLV0 _SB_MAKEMASK(6, S_BCM1480_MC_INTLV0)
+#define V_BCM1480_MC_INTLV0(x) _SB_MAKEVALUE(x, S_BCM1480_MC_INTLV0)
+#define G_BCM1480_MC_INTLV0(x) _SB_GETVALUE(x, S_BCM1480_MC_INTLV0, M_BCM1480_MC_INTLV0)
+
+#define S_BCM1480_MC_INTLV1 8
+#define M_BCM1480_MC_INTLV1 _SB_MAKEMASK(6, S_BCM1480_MC_INTLV1)
+#define V_BCM1480_MC_INTLV1(x) _SB_MAKEVALUE(x, S_BCM1480_MC_INTLV1)
+#define G_BCM1480_MC_INTLV1(x) _SB_GETVALUE(x, S_BCM1480_MC_INTLV1, M_BCM1480_MC_INTLV1)
+
+#define S_BCM1480_MC_INTLV_MODE 16
+#define M_BCM1480_MC_INTLV_MODE _SB_MAKEMASK(3, S_BCM1480_MC_INTLV_MODE)
+#define V_BCM1480_MC_INTLV_MODE(x) _SB_MAKEVALUE(x, S_BCM1480_MC_INTLV_MODE)
+#define G_BCM1480_MC_INTLV_MODE(x) _SB_GETVALUE(x, S_BCM1480_MC_INTLV_MODE, M_BCM1480_MC_INTLV_MODE)
+
+#define K_BCM1480_MC_INTLV_MODE_NONE 0x0
+#define K_BCM1480_MC_INTLV_MODE_01 0x1
+#define K_BCM1480_MC_INTLV_MODE_23 0x2
+#define K_BCM1480_MC_INTLV_MODE_01_23 0x3
+#define K_BCM1480_MC_INTLV_MODE_0123 0x4
+
+#define V_BCM1480_MC_INTLV_MODE_NONE V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_NONE)
+#define V_BCM1480_MC_INTLV_MODE_01 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_01)
+#define V_BCM1480_MC_INTLV_MODE_23 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_23)
+#define V_BCM1480_MC_INTLV_MODE_01_23 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_01_23)
+#define V_BCM1480_MC_INTLV_MODE_0123 V_BCM1480_MC_INTLV_MODE(K_BCM1480_MC_INTLV_MODE_0123)
+
+/*
+ * ECC Status Register
+ */
+
+#define S_BCM1480_MC_ECC_ERR_ADDR 0
+#define M_BCM1480_MC_ECC_ERR_ADDR _SB_MAKEMASK(37, S_BCM1480_MC_ECC_ERR_ADDR)
+#define V_BCM1480_MC_ECC_ERR_ADDR(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ECC_ERR_ADDR)
+#define G_BCM1480_MC_ECC_ERR_ADDR(x) _SB_GETVALUE(x, S_BCM1480_MC_ECC_ERR_ADDR, M_BCM1480_MC_ECC_ERR_ADDR)
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define M_BCM1480_MC_ECC_ERR_RMW _SB_MAKEMASK1(60)
+#endif
+
+#define M_BCM1480_MC_ECC_MULT_ERR_DET _SB_MAKEMASK1(61)
+#define M_BCM1480_MC_ECC_UERR_DET _SB_MAKEMASK1(62)
+#define M_BCM1480_MC_ECC_CERR_DET _SB_MAKEMASK1(63)
+
+/*
+ * Global ECC Address Register (Table 102)
+ */
+
+#define S_BCM1480_MC_ECC_CORR_ADDR 0
+#define M_BCM1480_MC_ECC_CORR_ADDR _SB_MAKEMASK(37, S_BCM1480_MC_ECC_CORR_ADDR)
+#define V_BCM1480_MC_ECC_CORR_ADDR(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ECC_CORR_ADDR)
+#define G_BCM1480_MC_ECC_CORR_ADDR(x) _SB_GETVALUE(x, S_BCM1480_MC_ECC_CORR_ADDR, M_BCM1480_MC_ECC_CORR_ADDR)
+
+/*
+ * Global ECC Correction Register (Table 103)
+ */
+
+#define S_BCM1480_MC_ECC_CORRECT 0
+#define M_BCM1480_MC_ECC_CORRECT _SB_MAKEMASK(64, S_BCM1480_MC_ECC_CORRECT)
+#define V_BCM1480_MC_ECC_CORRECT(x) _SB_MAKEVALUE(x, S_BCM1480_MC_ECC_CORRECT)
+#define G_BCM1480_MC_ECC_CORRECT(x) _SB_GETVALUE(x, S_BCM1480_MC_ECC_CORRECT, M_BCM1480_MC_ECC_CORRECT)
+
+/*
+ * Global ECC Performance Counters Control Register (Table 104)
+ */
+
+#define S_BCM1480_MC_CHANNEL_SELECT 0
+#define M_BCM1480_MC_CHANNEL_SELECT _SB_MAKEMASK(4, S_BCM1480_MC_CHANNEL_SELECT)
+#define V_BCM1480_MC_CHANNEL_SELECT(x) _SB_MAKEVALUE(x, S_BCM1480_MC_CHANNEL_SELECT)
+#define G_BCM1480_MC_CHANNEL_SELECT(x) _SB_GETVALUE(x, S_BCM1480_MC_CHANNEL_SELECT, M_BCM1480_MC_CHANNEL_SELECT)
+#define K_BCM1480_MC_CHANNEL_SELECT_0 0x1
+#define K_BCM1480_MC_CHANNEL_SELECT_1 0x2
+#define K_BCM1480_MC_CHANNEL_SELECT_2 0x4
+#define K_BCM1480_MC_CHANNEL_SELECT_3 0x8
+
+#endif /* _BCM1480_MC_H */
diff --git a/arch/mips/include/asm/sibyte/bcm1480_regs.h b/arch/mips/include/asm/sibyte/bcm1480_regs.h
new file mode 100644
index 00000000..b4077bb7
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/bcm1480_regs.h
@@ -0,0 +1,902 @@
+/* *********************************************************************
+ * BCM1255/BCM1280/BCM1455/BCM1480 Board Support Package
+ *
+ * Register Definitions File: bcm1480_regs.h
+ *
+ * This module contains the addresses of the on-chip peripherals
+ * on the BCM1280 and BCM1480.
+ *
+ * BCM1480 specification level: 1X55_1X80-UM100-D4 (11/24/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+#ifndef _BCM1480_REGS_H
+#define _BCM1480_REGS_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Pull in the BCM1250's registers since a great deal of the 1480's
+ * functions are the same as the BCM1250.
+ ********************************************************************* */
+
+#include "sb1250_regs.h"
+
+
+/* *********************************************************************
+ * Some general notes:
+ *
+ * Register addresses are grouped by function and follow the order
+ * of the User Manual.
+ *
+ * For the most part, when there is more than one peripheral
+ * of the same type on the SOC, the constants below will be
+ * offsets from the base of each peripheral. For example,
+ * the MAC registers are described as offsets from the first
+ * MAC register, and there will be a MAC_REGISTER() macro
+ * to calculate the base address of a given MAC.
+ *
+ * The information in this file is based on the BCM1X55/BCM1X80
+ * User Manual, Document 1X55_1X80-UM100-R, 22/12/03.
+ *
+ * This file is basically a "what's new" header file. Since the
+ * BCM1250 and the new BCM1480 (and derivatives) share many common
+ * features, this file contains only what's new or changed from
+ * the 1250. (above, you can see that we include the 1250 symbols
+ * to get the base functionality).
+ *
+ * In software, be sure to use the correct symbols, particularly
+ * for blocks that are different between the two chip families.
+ * All BCM1480-specific symbols have _BCM1480_ in their names,
+ * and all BCM1250-specific and "base" functions that are common in
+ * both chips have no special names (this is for compatibility with
+ * older include files). Therefore, if you're working with the
+ * SCD, which is very different on each chip, A_SCD_xxx implies
+ * the BCM1250 version and A_BCM1480_SCD_xxx implies the BCM1480
+ * version.
+ ********************************************************************* */
+
+
+/* *********************************************************************
+ * Memory Controller Registers (Section 6)
+ ********************************************************************* */
+
+#define A_BCM1480_MC_BASE_0 0x0010050000
+#define A_BCM1480_MC_BASE_1 0x0010051000
+#define A_BCM1480_MC_BASE_2 0x0010052000
+#define A_BCM1480_MC_BASE_3 0x0010053000
+#define BCM1480_MC_REGISTER_SPACING 0x1000
+
+#define A_BCM1480_MC_BASE(ctlid) (A_BCM1480_MC_BASE_0+(ctlid)*BCM1480_MC_REGISTER_SPACING)
+#define A_BCM1480_MC_REGISTER(ctlid, reg) (A_BCM1480_MC_BASE(ctlid)+(reg))
+
+#define R_BCM1480_MC_CONFIG 0x0000000100
+#define R_BCM1480_MC_CS_START 0x0000000120
+#define R_BCM1480_MC_CS_END 0x0000000140
+#define S_BCM1480_MC_CS_STARTEND 24
+
+#define R_BCM1480_MC_CS01_ROW0 0x0000000180
+#define R_BCM1480_MC_CS01_ROW1 0x00000001A0
+#define R_BCM1480_MC_CS23_ROW0 0x0000000200
+#define R_BCM1480_MC_CS23_ROW1 0x0000000220
+#define R_BCM1480_MC_CS01_COL0 0x0000000280
+#define R_BCM1480_MC_CS01_COL1 0x00000002A0
+#define R_BCM1480_MC_CS23_COL0 0x0000000300
+#define R_BCM1480_MC_CS23_COL1 0x0000000320
+
+#define R_BCM1480_MC_CSX_BASE 0x0000000180
+#define R_BCM1480_MC_CSX_ROW0 0x0000000000 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_ROW1 0x0000000020 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_COL0 0x0000000100 /* relative to CSX_BASE */
+#define R_BCM1480_MC_CSX_COL1 0x0000000120 /* relative to CSX_BASE */
+#define BCM1480_MC_CSX_SPACING 0x0000000080 /* CS23 relative to CS01 */
+
+#define R_BCM1480_MC_CS01_BA 0x0000000380
+#define R_BCM1480_MC_CS23_BA 0x00000003A0
+#define R_BCM1480_MC_DRAMCMD 0x0000000400
+#define R_BCM1480_MC_DRAMMODE 0x0000000420
+#define R_BCM1480_MC_CLOCK_CFG 0x0000000440
+#define R_BCM1480_MC_MCLK_CFG R_BCM1480_MC_CLOCK_CFG
+#define R_BCM1480_MC_TEST_DATA 0x0000000480
+#define R_BCM1480_MC_TEST_ECC 0x00000004A0
+#define R_BCM1480_MC_TIMING1 0x00000004C0
+#define R_BCM1480_MC_TIMING2 0x00000004E0
+#define R_BCM1480_MC_DLL_CFG 0x0000000500
+#define R_BCM1480_MC_DRIVE_CFG 0x0000000520
+
+#if SIBYTE_HDR_FEATURE(1480, PASS2)
+#define R_BCM1480_MC_ODT 0x0000000460
+#define R_BCM1480_MC_ECC_STATUS 0x0000000540
+#endif
+
+/* Global registers (single instance) */
+#define A_BCM1480_MC_GLB_CONFIG 0x0010054100
+#define A_BCM1480_MC_GLB_INTLV 0x0010054120
+#define A_BCM1480_MC_GLB_ECC_STATUS 0x0010054140
+#define A_BCM1480_MC_GLB_ECC_ADDR 0x0010054160
+#define A_BCM1480_MC_GLB_ECC_CORRECT 0x0010054180
+#define A_BCM1480_MC_GLB_PERF_CNT_CONTROL 0x00100541A0
+
+/* *********************************************************************
+ * L2 Cache Control Registers (Section 5)
+ ********************************************************************* */
+
+#define A_BCM1480_L2_BASE 0x0010040000
+
+#define A_BCM1480_L2_READ_TAG 0x0010040018
+#define A_BCM1480_L2_ECC_TAG 0x0010040038
+#define A_BCM1480_L2_MISC0_VALUE 0x0010040058
+#define A_BCM1480_L2_MISC1_VALUE 0x0010040078
+#define A_BCM1480_L2_MISC2_VALUE 0x0010040098
+#define A_BCM1480_L2_MISC_CONFIG 0x0010040040 /* x040 */
+#define A_BCM1480_L2_CACHE_DISABLE 0x0010040060 /* x060 */
+#define A_BCM1480_L2_MAKECACHEDISABLE(x) (A_BCM1480_L2_CACHE_DISABLE | (((x)&0xF) << 12))
+#define A_BCM1480_L2_WAY_ENABLE_3_0 0x0010040080 /* x080 */
+#define A_BCM1480_L2_WAY_ENABLE_7_4 0x00100400A0 /* x0A0 */
+#define A_BCM1480_L2_MAKE_WAY_ENABLE_LO(x) (A_BCM1480_L2_WAY_ENABLE_3_0 | (((x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_ENABLE_HI(x) (A_BCM1480_L2_WAY_ENABLE_7_4 | (((x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_DISABLE_LO(x) (A_BCM1480_L2_WAY_ENABLE_3_0 | (((~x)&0xF) << 12))
+#define A_BCM1480_L2_MAKE_WAY_DISABLE_HI(x) (A_BCM1480_L2_WAY_ENABLE_7_4 | (((~x)&0xF) << 12))
+#define A_BCM1480_L2_WAY_LOCAL_3_0 0x0010040100 /* x100 */
+#define A_BCM1480_L2_WAY_LOCAL_7_4 0x0010040120 /* x120 */
+#define A_BCM1480_L2_WAY_REMOTE_3_0 0x0010040140 /* x140 */
+#define A_BCM1480_L2_WAY_REMOTE_7_4 0x0010040160 /* x160 */
+#define A_BCM1480_L2_WAY_AGENT_3_0 0x00100400C0 /* xxC0 */
+#define A_BCM1480_L2_WAY_AGENT_7_4 0x00100400E0 /* xxE0 */
+#define A_BCM1480_L2_WAY_ENABLE(A, banks) (A | (((~(banks))&0x0F) << 8))
+#define A_BCM1480_L2_BANK_BASE 0x00D0300000
+#define A_BCM1480_L2_BANK_ADDRESS(b) (A_BCM1480_L2_BANK_BASE | (((b)&0x7)<<17))
+#define A_BCM1480_L2_MGMT_TAG_BASE 0x00D0000000
+
+
+/* *********************************************************************
+ * PCI-X Interface Registers (Section 7)
+ ********************************************************************* */
+
+#define A_BCM1480_PCI_BASE 0x0010061400
+
+#define A_BCM1480_PCI_RESET 0x0010061400
+#define A_BCM1480_PCI_DLL 0x0010061500
+
+#define A_BCM1480_PCI_TYPE00_HEADER 0x002E000000
+
+/* *********************************************************************
+ * Ethernet MAC Registers (Section 11) and DMA Registers (Section 10.6)
+ ********************************************************************* */
+
+/* No register changes with Rev.C BCM1250, but one additional MAC */
+
+#define A_BCM1480_MAC_BASE_2 0x0010066000
+
+#ifndef A_MAC_BASE_2
+#define A_MAC_BASE_2 A_BCM1480_MAC_BASE_2
+#endif
+
+#define A_BCM1480_MAC_BASE_3 0x0010067000
+#define A_MAC_BASE_3 A_BCM1480_MAC_BASE_3
+
+#define R_BCM1480_MAC_DMA_OODPKTLOST 0x00000038
+
+#ifndef R_MAC_DMA_OODPKTLOST
+#define R_MAC_DMA_OODPKTLOST R_BCM1480_MAC_DMA_OODPKTLOST
+#endif
+
+
+/* *********************************************************************
+ * DUART Registers (Section 14)
+ ********************************************************************* */
+
+/* No significant differences from BCM1250, two DUARTs */
+
+/* Conventions, per user manual:
+ * DUART generic, channels A,B,C,D
+ * DUART0 implementing channels A,B
+ * DUART1 inplementing channels C,D
+ */
+
+#define BCM1480_DUART_NUM_PORTS 4
+
+#define A_BCM1480_DUART0 0x0010060000
+#define A_BCM1480_DUART1 0x0010060400
+#define A_BCM1480_DUART(chan) ((((chan)&2) == 0)? A_BCM1480_DUART0 : A_BCM1480_DUART1)
+
+#define BCM1480_DUART_CHANREG_SPACING 0x100
+#define A_BCM1480_DUART_CHANREG(chan, reg) \
+ (A_BCM1480_DUART(chan) + \
+ BCM1480_DUART_CHANREG_SPACING * (((chan) & 1) + 1) + (reg))
+#define A_BCM1480_DUART_CTRLREG(chan, reg) \
+ (A_BCM1480_DUART(chan) + \
+ BCM1480_DUART_CHANREG_SPACING * 3 + (reg))
+
+#define DUART_IMRISR_SPACING 0x20
+#define DUART_INCHNG_SPACING 0x10
+
+#define R_BCM1480_DUART_IMRREG(chan) \
+ (R_DUART_IMR_A + ((chan) & 1) * DUART_IMRISR_SPACING)
+#define R_BCM1480_DUART_ISRREG(chan) \
+ (R_DUART_ISR_A + ((chan) & 1) * DUART_IMRISR_SPACING)
+#define R_BCM1480_DUART_INCHREG(chan) \
+ (R_DUART_IN_CHNG_A + ((chan) & 1) * DUART_INCHNG_SPACING)
+
+#define A_BCM1480_DUART_IMRREG(chan) \
+ (A_BCM1480_DUART_CTRLREG((chan), R_BCM1480_DUART_IMRREG(chan)))
+#define A_BCM1480_DUART_ISRREG(chan) \
+ (A_BCM1480_DUART_CTRLREG((chan), R_BCM1480_DUART_ISRREG(chan)))
+
+#define A_BCM1480_DUART_IN_PORT(chan) \
+ (A_BCM1480_DUART_CTRLREG((chan), R_DUART_IN_PORT))
+
+/*
+ * These constants are the absolute addresses.
+ */
+
+#define A_BCM1480_DUART_MODE_REG_1_C 0x0010060400
+#define A_BCM1480_DUART_MODE_REG_2_C 0x0010060410
+#define A_BCM1480_DUART_STATUS_C 0x0010060420
+#define A_BCM1480_DUART_CLK_SEL_C 0x0010060430
+#define A_BCM1480_DUART_FULL_CTL_C 0x0010060440
+#define A_BCM1480_DUART_CMD_C 0x0010060450
+#define A_BCM1480_DUART_RX_HOLD_C 0x0010060460
+#define A_BCM1480_DUART_TX_HOLD_C 0x0010060470
+#define A_BCM1480_DUART_OPCR_C 0x0010060480
+#define A_BCM1480_DUART_AUX_CTRL_C 0x0010060490
+
+#define A_BCM1480_DUART_MODE_REG_1_D 0x0010060500
+#define A_BCM1480_DUART_MODE_REG_2_D 0x0010060510
+#define A_BCM1480_DUART_STATUS_D 0x0010060520
+#define A_BCM1480_DUART_CLK_SEL_D 0x0010060530
+#define A_BCM1480_DUART_FULL_CTL_D 0x0010060540
+#define A_BCM1480_DUART_CMD_D 0x0010060550
+#define A_BCM1480_DUART_RX_HOLD_D 0x0010060560
+#define A_BCM1480_DUART_TX_HOLD_D 0x0010060570
+#define A_BCM1480_DUART_OPCR_D 0x0010060580
+#define A_BCM1480_DUART_AUX_CTRL_D 0x0010060590
+
+#define A_BCM1480_DUART_INPORT_CHNG_CD 0x0010060600
+#define A_BCM1480_DUART_AUX_CTRL_CD 0x0010060610
+#define A_BCM1480_DUART_ISR_C 0x0010060620
+#define A_BCM1480_DUART_IMR_C 0x0010060630
+#define A_BCM1480_DUART_ISR_D 0x0010060640
+#define A_BCM1480_DUART_IMR_D 0x0010060650
+#define A_BCM1480_DUART_OUT_PORT_CD 0x0010060660
+#define A_BCM1480_DUART_OPCR_CD 0x0010060670
+#define A_BCM1480_DUART_IN_PORT_CD 0x0010060680
+#define A_BCM1480_DUART_ISR_CD 0x0010060690
+#define A_BCM1480_DUART_IMR_CD 0x00100606A0
+#define A_BCM1480_DUART_SET_OPR_CD 0x00100606B0
+#define A_BCM1480_DUART_CLEAR_OPR_CD 0x00100606C0
+#define A_BCM1480_DUART_INPORT_CHNG_C 0x00100606D0
+#define A_BCM1480_DUART_INPORT_CHNG_D 0x00100606E0
+
+
+/* *********************************************************************
+ * Generic Bus Registers (Section 15) and PCMCIA Registers (Section 16)
+ ********************************************************************* */
+
+#define A_BCM1480_IO_PCMCIA_CFG_B 0x0010061A58
+#define A_BCM1480_IO_PCMCIA_STATUS_B 0x0010061A68
+
+/* *********************************************************************
+ * GPIO Registers (Section 17)
+ ********************************************************************* */
+
+/* One additional GPIO register, placed _before_ the BCM1250's GPIO block base */
+
+#define A_BCM1480_GPIO_INT_ADD_TYPE 0x0010061A78
+#define R_BCM1480_GPIO_INT_ADD_TYPE (-8)
+
+#define A_GPIO_INT_ADD_TYPE A_BCM1480_GPIO_INT_ADD_TYPE
+#define R_GPIO_INT_ADD_TYPE R_BCM1480_GPIO_INT_ADD_TYPE
+
+/* *********************************************************************
+ * SMBus Registers (Section 18)
+ ********************************************************************* */
+
+/* No changes from BCM1250 */
+
+/* *********************************************************************
+ * Timer Registers (Sections 4.6)
+ ********************************************************************* */
+
+/* BCM1480 has two additional watchdogs */
+
+/* Watchdog timers */
+
+#define A_BCM1480_SCD_WDOG_2 0x0010022050
+#define A_BCM1480_SCD_WDOG_3 0x0010022150
+
+#define BCM1480_SCD_NUM_WDOGS 4
+
+#define A_BCM1480_SCD_WDOG_BASE(w) (A_BCM1480_SCD_WDOG_0+((w)&2)*0x1000 + ((w)&1)*0x100)
+#define A_BCM1480_SCD_WDOG_REGISTER(w, r) (A_BCM1480_SCD_WDOG_BASE(w) + (r))
+
+#define A_BCM1480_SCD_WDOG_INIT_2 0x0010022050
+#define A_BCM1480_SCD_WDOG_CNT_2 0x0010022058
+#define A_BCM1480_SCD_WDOG_CFG_2 0x0010022060
+
+#define A_BCM1480_SCD_WDOG_INIT_3 0x0010022150
+#define A_BCM1480_SCD_WDOG_CNT_3 0x0010022158
+#define A_BCM1480_SCD_WDOG_CFG_3 0x0010022160
+
+/* BCM1480 has two additional compare registers */
+
+#define A_BCM1480_SCD_ZBBUS_CYCLE_COUNT A_SCD_ZBBUS_CYCLE_COUNT
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP_BASE 0x0010020C00
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP0 A_SCD_ZBBUS_CYCLE_CP0
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP1 A_SCD_ZBBUS_CYCLE_CP1
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP2 0x0010020C10
+#define A_BCM1480_SCD_ZBBUS_CYCLE_CP3 0x0010020C18
+
+/* *********************************************************************
+ * System Control Registers (Section 4.2)
+ ********************************************************************* */
+
+/* Scratch register in different place */
+
+#define A_BCM1480_SCD_SCRATCH 0x100200A0
+
+/* *********************************************************************
+ * System Address Trap Registers (Section 4.9)
+ ********************************************************************* */
+
+/* No changes from BCM1250 */
+
+/* *********************************************************************
+ * System Interrupt Mapper Registers (Sections 4.3-4.5)
+ ********************************************************************* */
+
+#define A_BCM1480_IMR_CPU0_BASE 0x0010020000
+#define A_BCM1480_IMR_CPU1_BASE 0x0010022000
+#define A_BCM1480_IMR_CPU2_BASE 0x0010024000
+#define A_BCM1480_IMR_CPU3_BASE 0x0010026000
+#define BCM1480_IMR_REGISTER_SPACING 0x2000
+#define BCM1480_IMR_REGISTER_SPACING_SHIFT 13
+
+#define A_BCM1480_IMR_MAPPER(cpu) (A_BCM1480_IMR_CPU0_BASE+(cpu)*BCM1480_IMR_REGISTER_SPACING)
+#define A_BCM1480_IMR_REGISTER(cpu, reg) (A_BCM1480_IMR_MAPPER(cpu)+(reg))
+
+/* Most IMR registers are 128 bits, implemented as non-contiguous
+ 64-bit registers high (_H) and low (_L) */
+#define BCM1480_IMR_HL_SPACING 0x1000
+
+#define R_BCM1480_IMR_INTERRUPT_DIAG_H 0x0010
+#define R_BCM1480_IMR_LDT_INTERRUPT_H 0x0018
+#define R_BCM1480_IMR_LDT_INTERRUPT_CLR_H 0x0020
+#define R_BCM1480_IMR_INTERRUPT_MASK_H 0x0028
+#define R_BCM1480_IMR_INTERRUPT_TRACE_H 0x0038
+#define R_BCM1480_IMR_INTERRUPT_SOURCE_STATUS_H 0x0040
+#define R_BCM1480_IMR_LDT_INTERRUPT_SET 0x0048
+#define R_BCM1480_IMR_MAILBOX_0_CPU 0x00C0
+#define R_BCM1480_IMR_MAILBOX_0_SET_CPU 0x00C8
+#define R_BCM1480_IMR_MAILBOX_0_CLR_CPU 0x00D0
+#define R_BCM1480_IMR_MAILBOX_1_CPU 0x00E0
+#define R_BCM1480_IMR_MAILBOX_1_SET_CPU 0x00E8
+#define R_BCM1480_IMR_MAILBOX_1_CLR_CPU 0x00F0
+#define R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H 0x0100
+#define BCM1480_IMR_INTERRUPT_STATUS_COUNT 8
+#define R_BCM1480_IMR_INTERRUPT_MAP_BASE_H 0x0200
+#define BCM1480_IMR_INTERRUPT_MAP_COUNT 64
+
+#define R_BCM1480_IMR_INTERRUPT_DIAG_L 0x1010
+#define R_BCM1480_IMR_LDT_INTERRUPT_L 0x1018
+#define R_BCM1480_IMR_LDT_INTERRUPT_CLR_L 0x1020
+#define R_BCM1480_IMR_INTERRUPT_MASK_L 0x1028
+#define R_BCM1480_IMR_INTERRUPT_TRACE_L 0x1038
+#define R_BCM1480_IMR_INTERRUPT_SOURCE_STATUS_L 0x1040
+#define R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L 0x1100
+#define R_BCM1480_IMR_INTERRUPT_MAP_BASE_L 0x1200
+
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU0_BASE 0x0010028000
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU1_BASE 0x0010028100
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU2_BASE 0x0010028200
+#define A_BCM1480_IMR_ALIAS_MAILBOX_CPU3_BASE 0x0010028300
+#define BCM1480_IMR_ALIAS_MAILBOX_SPACING 0100
+
+#define A_BCM1480_IMR_ALIAS_MAILBOX(cpu) (A_BCM1480_IMR_ALIAS_MAILBOX_CPU0_BASE + \
+ (cpu)*BCM1480_IMR_ALIAS_MAILBOX_SPACING)
+#define A_BCM1480_IMR_ALIAS_MAILBOX_REGISTER(cpu, reg) (A_BCM1480_IMR_ALIAS_MAILBOX(cpu)+(reg))
+
+#define R_BCM1480_IMR_ALIAS_MAILBOX_0 0x0000 /* 0x0x0 */
+#define R_BCM1480_IMR_ALIAS_MAILBOX_0_SET 0x0008 /* 0x0x8 */
+
+/*
+ * these macros work together to build the address of a mailbox
+ * register, e.g., A_BCM1480_MAILBOX_REGISTER(0,R_BCM1480_IMR_MAILBOX_SET,2)
+ * for mbox_0_set_cpu2 returns 0x00100240C8
+ */
+#define R_BCM1480_IMR_MAILBOX_CPU 0x00
+#define R_BCM1480_IMR_MAILBOX_SET 0x08
+#define R_BCM1480_IMR_MAILBOX_CLR 0x10
+#define R_BCM1480_IMR_MAILBOX_NUM_SPACING 0x20
+#define A_BCM1480_MAILBOX_REGISTER(num, reg, cpu) \
+ (A_BCM1480_IMR_CPU0_BASE + \
+ (num * R_BCM1480_IMR_MAILBOX_NUM_SPACING) + \
+ (cpu * BCM1480_IMR_REGISTER_SPACING) + \
+ (R_BCM1480_IMR_MAILBOX_0_CPU + reg))
+
+/* *********************************************************************
+ * System Performance Counter Registers (Section 4.7)
+ ********************************************************************* */
+
+/* BCM1480 has four more performance counter registers, and two control
+ registers. */
+
+#define A_BCM1480_SCD_PERF_CNT_BASE 0x00100204C0
+
+#define A_BCM1480_SCD_PERF_CNT_CFG0 0x00100204C0
+#define A_BCM1480_SCD_PERF_CNT_CFG_0 A_BCM1480_SCD_PERF_CNT_CFG0
+#define A_BCM1480_SCD_PERF_CNT_CFG1 0x00100204C8
+#define A_BCM1480_SCD_PERF_CNT_CFG_1 A_BCM1480_SCD_PERF_CNT_CFG1
+
+#define A_BCM1480_SCD_PERF_CNT_0 A_SCD_PERF_CNT_0
+#define A_BCM1480_SCD_PERF_CNT_1 A_SCD_PERF_CNT_1
+#define A_BCM1480_SCD_PERF_CNT_2 A_SCD_PERF_CNT_2
+#define A_BCM1480_SCD_PERF_CNT_3 A_SCD_PERF_CNT_3
+
+#define A_BCM1480_SCD_PERF_CNT_4 0x00100204F0
+#define A_BCM1480_SCD_PERF_CNT_5 0x00100204F8
+#define A_BCM1480_SCD_PERF_CNT_6 0x0010020500
+#define A_BCM1480_SCD_PERF_CNT_7 0x0010020508
+
+#define BCM1480_SCD_NUM_PERF_CNT 8
+#define BCM1480_SCD_PERF_CNT_SPACING 8
+#define A_BCM1480_SCD_PERF_CNT(n) (A_SCD_PERF_CNT_0+(n*BCM1480_SCD_PERF_CNT_SPACING))
+
+/* *********************************************************************
+ * System Bus Watcher Registers (Section 4.8)
+ ********************************************************************* */
+
+
+/* Same as 1250 except BUS_ERR_STATUS_DEBUG is in a different place. */
+
+#define A_BCM1480_BUS_ERR_STATUS_DEBUG 0x00100208D8
+
+/* *********************************************************************
+ * System Debug Controller Registers (Section 19)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+/* *********************************************************************
+ * System Trace Unit Registers (Sections 4.10)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+/* *********************************************************************
+ * Data Mover DMA Registers (Section 10.7)
+ ********************************************************************* */
+
+/* Same as 1250 */
+
+
+/* *********************************************************************
+ * HyperTransport Interface Registers (Section 8)
+ ********************************************************************* */
+
+#define BCM1480_HT_NUM_PORTS 3
+#define BCM1480_HT_PORT_SPACING 0x800
+#define A_BCM1480_HT_PORT_HEADER(x) (A_BCM1480_HT_PORT0_HEADER + ((x)*BCM1480_HT_PORT_SPACING))
+
+#define A_BCM1480_HT_PORT0_HEADER 0x00FE000000
+#define A_BCM1480_HT_PORT1_HEADER 0x00FE000800
+#define A_BCM1480_HT_PORT2_HEADER 0x00FE001000
+#define A_BCM1480_HT_TYPE00_HEADER 0x00FE002000
+
+
+/* *********************************************************************
+ * Node Controller Registers (Section 9)
+ ********************************************************************* */
+
+#define A_BCM1480_NC_BASE 0x00DFBD0000
+
+#define A_BCM1480_NC_RLD_FIELD 0x00DFBD0000
+#define A_BCM1480_NC_RLD_TRIGGER 0x00DFBD0020
+#define A_BCM1480_NC_RLD_BAD_ERROR 0x00DFBD0040
+#define A_BCM1480_NC_RLD_COR_ERROR 0x00DFBD0060
+#define A_BCM1480_NC_RLD_ECC_STATUS 0x00DFBD0080
+#define A_BCM1480_NC_RLD_WAY_ENABLE 0x00DFBD00A0
+#define A_BCM1480_NC_RLD_RANDOM_LFSR 0x00DFBD00C0
+
+#define A_BCM1480_NC_INTERRUPT_STATUS 0x00DFBD00E0
+#define A_BCM1480_NC_INTERRUPT_ENABLE 0x00DFBD0100
+#define A_BCM1480_NC_TIMEOUT_COUNTER 0x00DFBD0120
+#define A_BCM1480_NC_TIMEOUT_COUNTER_SEL 0x00DFBD0140
+
+#define A_BCM1480_NC_CREDIT_STATUS_REG0 0x00DFBD0200
+#define A_BCM1480_NC_CREDIT_STATUS_REG1 0x00DFBD0220
+#define A_BCM1480_NC_CREDIT_STATUS_REG2 0x00DFBD0240
+#define A_BCM1480_NC_CREDIT_STATUS_REG3 0x00DFBD0260
+#define A_BCM1480_NC_CREDIT_STATUS_REG4 0x00DFBD0280
+#define A_BCM1480_NC_CREDIT_STATUS_REG5 0x00DFBD02A0
+#define A_BCM1480_NC_CREDIT_STATUS_REG6 0x00DFBD02C0
+#define A_BCM1480_NC_CREDIT_STATUS_REG7 0x00DFBD02E0
+#define A_BCM1480_NC_CREDIT_STATUS_REG8 0x00DFBD0300
+#define A_BCM1480_NC_CREDIT_STATUS_REG9 0x00DFBD0320
+#define A_BCM1480_NC_CREDIT_STATUS_REG10 0x00DFBE0000
+#define A_BCM1480_NC_CREDIT_STATUS_REG11 0x00DFBE0020
+#define A_BCM1480_NC_CREDIT_STATUS_REG12 0x00DFBE0040
+
+#define A_BCM1480_NC_SR_TIMEOUT_COUNTER 0x00DFBE0060
+#define A_BCM1480_NC_SR_TIMEOUT_COUNTER_SEL 0x00DFBE0080
+
+
+/* *********************************************************************
+ * H&R Block Configuration Registers (Section 12.4)
+ ********************************************************************* */
+
+#define A_BCM1480_HR_BASE_0 0x00DF820000
+#define A_BCM1480_HR_BASE_1 0x00DF8A0000
+#define A_BCM1480_HR_BASE_2 0x00DF920000
+#define BCM1480_HR_REGISTER_SPACING 0x80000
+
+#define A_BCM1480_HR_BASE(idx) (A_BCM1480_HR_BASE_0 + ((idx)*BCM1480_HR_REGISTER_SPACING))
+#define A_BCM1480_HR_REGISTER(idx, reg) (A_BCM1480_HR_BASE(idx) + (reg))
+
+#define R_BCM1480_HR_CFG 0x0000000000
+
+#define R_BCM1480_HR_MAPPING 0x0000010010
+
+#define BCM1480_HR_RULE_SPACING 0x0000000010
+#define BCM1480_HR_NUM_RULES 16
+#define BCM1480_HR_OP_OFFSET 0x0000000100
+#define BCM1480_HR_TYPE_OFFSET 0x0000000108
+#define R_BCM1480_HR_RULE_OP(idx) (BCM1480_HR_OP_OFFSET + ((idx)*BCM1480_HR_RULE_SPACING))
+#define R_BCM1480_HR_RULE_TYPE(idx) (BCM1480_HR_TYPE_OFFSET + ((idx)*BCM1480_HR_RULE_SPACING))
+
+#define BCM1480_HR_LEAF_SPACING 0x0000000010
+#define BCM1480_HR_NUM_LEAVES 10
+#define BCM1480_HR_LEAF_OFFSET 0x0000000300
+#define R_BCM1480_HR_HA_LEAF0(idx) (BCM1480_HR_LEAF_OFFSET + ((idx)*BCM1480_HR_LEAF_SPACING))
+
+#define R_BCM1480_HR_EX_LEAF0 0x00000003A0
+
+#define BCM1480_HR_PATH_SPACING 0x0000000010
+#define BCM1480_HR_NUM_PATHS 16
+#define BCM1480_HR_PATH_OFFSET 0x0000000600
+#define R_BCM1480_HR_PATH(idx) (BCM1480_HR_PATH_OFFSET + ((idx)*BCM1480_HR_PATH_SPACING))
+
+#define R_BCM1480_HR_PATH_DEFAULT 0x0000000700
+
+#define BCM1480_HR_ROUTE_SPACING 8
+#define BCM1480_HR_NUM_ROUTES 512
+#define BCM1480_HR_ROUTE_OFFSET 0x0000001000
+#define R_BCM1480_HR_RT_WORD(idx) (BCM1480_HR_ROUTE_OFFSET + ((idx)*BCM1480_HR_ROUTE_SPACING))
+
+
+/* checked to here - ehs */
+/* *********************************************************************
+ * Packet Manager DMA Registers (Section 12.5)
+ ********************************************************************* */
+
+#define A_BCM1480_PM_BASE 0x0010056000
+
+#define A_BCM1480_PMI_LCL_0 0x0010058000
+#define A_BCM1480_PMO_LCL_0 0x001005C000
+#define A_BCM1480_PMI_OFFSET_0 (A_BCM1480_PMI_LCL_0 - A_BCM1480_PM_BASE)
+#define A_BCM1480_PMO_OFFSET_0 (A_BCM1480_PMO_LCL_0 - A_BCM1480_PM_BASE)
+
+#define BCM1480_PM_LCL_REGISTER_SPACING 0x100
+#define BCM1480_PM_NUM_CHANNELS 32
+
+#define A_BCM1480_PMI_LCL_BASE(idx) (A_BCM1480_PMI_LCL_0 + ((idx)*BCM1480_PM_LCL_REGISTER_SPACING))
+#define A_BCM1480_PMI_LCL_REGISTER(idx, reg) (A_BCM1480_PMI_LCL_BASE(idx) + (reg))
+#define A_BCM1480_PMO_LCL_BASE(idx) (A_BCM1480_PMO_LCL_0 + ((idx)*BCM1480_PM_LCL_REGISTER_SPACING))
+#define A_BCM1480_PMO_LCL_REGISTER(idx, reg) (A_BCM1480_PMO_LCL_BASE(idx) + (reg))
+
+#define BCM1480_PM_INT_PACKING 8
+#define BCM1480_PM_INT_FUNCTION_SPACING 0x40
+#define BCM1480_PM_INT_NUM_FUNCTIONS 3
+
+/*
+ * DMA channel registers relative to A_BCM1480_PMI_LCL_BASE(n) and A_BCM1480_PMO_LCL_BASE(n)
+ */
+
+#define R_BCM1480_PM_BASE_SIZE 0x0000000000
+#define R_BCM1480_PM_CNT 0x0000000008
+#define R_BCM1480_PM_PFCNT 0x0000000010
+#define R_BCM1480_PM_LAST 0x0000000018
+#define R_BCM1480_PM_PFINDX 0x0000000020
+#define R_BCM1480_PM_INT_WMK 0x0000000028
+#define R_BCM1480_PM_CONFIG0 0x0000000030
+#define R_BCM1480_PM_LOCALDEBUG 0x0000000078
+#define R_BCM1480_PM_CACHEABILITY 0x0000000080 /* PMI only */
+#define R_BCM1480_PM_INT_CNFG 0x0000000088
+#define R_BCM1480_PM_DESC_MERGE_TIMER 0x0000000090
+#define R_BCM1480_PM_LOCALDEBUG_PIB 0x00000000F8 /* PMI only */
+#define R_BCM1480_PM_LOCALDEBUG_POB 0x00000000F8 /* PMO only */
+
+/*
+ * Global Registers (Not Channelized)
+ */
+
+#define A_BCM1480_PMI_GLB_0 0x0010056000
+#define A_BCM1480_PMO_GLB_0 0x0010057000
+
+/*
+ * PM to TX Mapping Register relative to A_BCM1480_PMI_GLB_0 and A_BCM1480_PMO_GLB_0
+ */
+
+#define R_BCM1480_PM_PMO_MAPPING 0x00000008C8 /* PMO only */
+
+#define A_BCM1480_PM_PMO_MAPPING (A_BCM1480_PMO_GLB_0 + R_BCM1480_PM_PMO_MAPPING)
+
+/*
+ * Interrupt mapping registers
+ */
+
+
+#define A_BCM1480_PMI_INT_0 0x0010056800
+#define A_BCM1480_PMI_INT(q) (A_BCM1480_PMI_INT_0 + ((q>>8)<<8))
+#define A_BCM1480_PMI_INT_OFFSET_0 (A_BCM1480_PMI_INT_0 - A_BCM1480_PM_BASE)
+#define A_BCM1480_PMO_INT_0 0x0010057800
+#define A_BCM1480_PMO_INT(q) (A_BCM1480_PMO_INT_0 + ((q>>8)<<8))
+#define A_BCM1480_PMO_INT_OFFSET_0 (A_BCM1480_PMO_INT_0 - A_BCM1480_PM_BASE)
+
+/*
+ * Interrupt registers relative to A_BCM1480_PMI_INT_0 and A_BCM1480_PMO_INT_0
+ */
+
+#define R_BCM1480_PM_INT_ST 0x0000000000
+#define R_BCM1480_PM_INT_MSK 0x0000000040
+#define R_BCM1480_PM_INT_CLR 0x0000000080
+#define R_BCM1480_PM_MRGD_INT 0x00000000C0
+
+/*
+ * Debug registers (global)
+ */
+
+#define A_BCM1480_PM_GLOBALDEBUGMODE_PMI 0x0010056000
+#define A_BCM1480_PM_GLOBALDEBUG_PID 0x00100567F8
+#define A_BCM1480_PM_GLOBALDEBUG_PIB 0x0010056FF8
+#define A_BCM1480_PM_GLOBALDEBUGMODE_PMO 0x0010057000
+#define A_BCM1480_PM_GLOBALDEBUG_POD 0x00100577F8
+#define A_BCM1480_PM_GLOBALDEBUG_POB 0x0010057FF8
+
+/* *********************************************************************
+ * Switch performance counters
+ ********************************************************************* */
+
+#define A_BCM1480_SWPERF_CFG 0xdfb91800
+#define A_BCM1480_SWPERF_CNT0 0xdfb91880
+#define A_BCM1480_SWPERF_CNT1 0xdfb91888
+#define A_BCM1480_SWPERF_CNT2 0xdfb91890
+#define A_BCM1480_SWPERF_CNT3 0xdfb91898
+
+
+/* *********************************************************************
+ * Switch Trace Unit
+ ********************************************************************* */
+
+#define A_BCM1480_SWTRC_MATCH_CONTROL_0 0xDFB91000
+#define A_BCM1480_SWTRC_MATCH_DATA_VALUE_0 0xDFB91100
+#define A_BCM1480_SWTRC_MATCH_DATA_MASK_0 0xDFB91108
+#define A_BCM1480_SWTRC_MATCH_TAG_VALUE_0 0xDFB91200
+#define A_BCM1480_SWTRC_MATCH_TAG_MAKS_0 0xDFB91208
+#define A_BCM1480_SWTRC_EVENT_0 0xDFB91300
+#define A_BCM1480_SWTRC_SEQUENCE_0 0xDFB91400
+
+#define A_BCM1480_SWTRC_CFG 0xDFB91500
+#define A_BCM1480_SWTRC_READ 0xDFB91508
+
+#define A_BCM1480_SWDEBUG_SCHEDSTOP 0xDFB92000
+
+#define A_BCM1480_SWTRC_MATCH_CONTROL(x) (A_BCM1480_SWTRC_MATCH_CONTROL_0 + ((x)*8))
+#define A_BCM1480_SWTRC_EVENT(x) (A_BCM1480_SWTRC_EVENT_0 + ((x)*8))
+#define A_BCM1480_SWTRC_SEQUENCE(x) (A_BCM1480_SWTRC_SEQUENCE_0 + ((x)*8))
+
+#define A_BCM1480_SWTRC_MATCH_DATA_VALUE(x) (A_BCM1480_SWTRC_MATCH_DATA_VALUE_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_DATA_MASK(x) (A_BCM1480_SWTRC_MATCH_DATA_MASK_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_TAG_VALUE(x) (A_BCM1480_SWTRC_MATCH_TAG_VALUE_0 + ((x)*16))
+#define A_BCM1480_SWTRC_MATCH_TAG_MASK(x) (A_BCM1480_SWTRC_MATCH_TAG_MASK_0 + ((x)*16))
+
+
+
+/* *********************************************************************
+ * High-Speed Port Registers (Section 13)
+ ********************************************************************* */
+
+#define A_BCM1480_HSP_BASE_0 0x00DF810000
+#define A_BCM1480_HSP_BASE_1 0x00DF890000
+#define A_BCM1480_HSP_BASE_2 0x00DF910000
+#define BCM1480_HSP_REGISTER_SPACING 0x80000
+
+#define A_BCM1480_HSP_BASE(idx) (A_BCM1480_HSP_BASE_0 + ((idx)*BCM1480_HSP_REGISTER_SPACING))
+#define A_BCM1480_HSP_REGISTER(idx, reg) (A_BCM1480_HSP_BASE(idx) + (reg))
+
+#define R_BCM1480_HSP_RX_SPI4_CFG_0 0x0000000000
+#define R_BCM1480_HSP_RX_SPI4_CFG_1 0x0000000008
+#define R_BCM1480_HSP_RX_SPI4_DESKEW_OVERRIDE 0x0000000010
+#define R_BCM1480_HSP_RX_SPI4_DESKEW_DATAPATH 0x0000000018
+#define R_BCM1480_HSP_RX_SPI4_PORT_INT_EN 0x0000000020
+#define R_BCM1480_HSP_RX_SPI4_PORT_INT_STATUS 0x0000000028
+
+#define R_BCM1480_HSP_RX_SPI4_CALENDAR_0 0x0000000200
+#define R_BCM1480_HSP_RX_SPI4_CALENDAR_1 0x0000000208
+
+#define R_BCM1480_HSP_RX_PLL_CNFG 0x0000000800
+#define R_BCM1480_HSP_RX_CALIBRATION 0x0000000808
+#define R_BCM1480_HSP_RX_TEST 0x0000000810
+#define R_BCM1480_HSP_RX_DIAG_DETAILS 0x0000000818
+#define R_BCM1480_HSP_RX_DIAG_CRC_0 0x0000000820
+#define R_BCM1480_HSP_RX_DIAG_CRC_1 0x0000000828
+#define R_BCM1480_HSP_RX_DIAG_HTCMD 0x0000000830
+#define R_BCM1480_HSP_RX_DIAG_PKTCTL 0x0000000838
+
+#define R_BCM1480_HSP_RX_VIS_FLCTRL_COUNTER 0x0000000870
+
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_0 0x0000020020
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_1 0x0000020028
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_2 0x0000020030
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_3 0x0000020038
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_4 0x0000020040
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_5 0x0000020048
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_6 0x0000020050
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC_7 0x0000020058
+#define R_BCM1480_HSP_RX_PKT_RAMALLOC(idx) (R_BCM1480_HSP_RX_PKT_RAMALLOC_0 + 8*(idx))
+
+/* XXX Following registers were shuffled. Renamed/renumbered per errata. */
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_0 0x0000020078
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_1 0x0000020080
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_2 0x0000020088
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_3 0x0000020090
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_4 0x0000020098
+#define R_BCM1480_HSP_RX_HT_RAMALLOC_5 0x00000200A0
+
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_0 0x00000200B0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_1 0x00000200B8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_2 0x00000200C0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_3 0x00000200C8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_4 0x00000200D0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_5 0x00000200D8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_6 0x00000200E0
+#define R_BCM1480_HSP_RX_SPI_WATERMARK_7 0x00000200E8
+#define R_BCM1480_HSP_RX_SPI_WATERMARK(idx) (R_BCM1480_HSP_RX_SPI_WATERMARK_0 + 8*(idx))
+
+#define R_BCM1480_HSP_RX_VIS_CMDQ_0 0x00000200F0
+#define R_BCM1480_HSP_RX_VIS_CMDQ_1 0x00000200F8
+#define R_BCM1480_HSP_RX_VIS_CMDQ_2 0x0000020100
+#define R_BCM1480_HSP_RX_RAM_READCTL 0x0000020108
+#define R_BCM1480_HSP_RX_RAM_READWINDOW 0x0000020110
+#define R_BCM1480_HSP_RX_RF_READCTL 0x0000020118
+#define R_BCM1480_HSP_RX_RF_READWINDOW 0x0000020120
+
+#define R_BCM1480_HSP_TX_SPI4_CFG_0 0x0000040000
+#define R_BCM1480_HSP_TX_SPI4_CFG_1 0x0000040008
+#define R_BCM1480_HSP_TX_SPI4_TRAINING_FMT 0x0000040010
+
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_0 0x0000040020
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_1 0x0000040028
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_2 0x0000040030
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_3 0x0000040038
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_4 0x0000040040
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_5 0x0000040048
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_6 0x0000040050
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC_7 0x0000040058
+#define R_BCM1480_HSP_TX_PKT_RAMALLOC(idx) (R_BCM1480_HSP_TX_PKT_RAMALLOC_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_NPC_RAMALLOC 0x0000040078
+#define R_BCM1480_HSP_TX_RSP_RAMALLOC 0x0000040080
+#define R_BCM1480_HSP_TX_PC_RAMALLOC 0x0000040088
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_0 0x0000040090
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_1 0x0000040098
+#define R_BCM1480_HSP_TX_HTCC_RAMALLOC_2 0x00000400A0
+
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_0 0x00000400B0
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_1 0x00000400B8
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_2 0x00000400C0
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT_3 0x00000400C8
+#define R_BCM1480_HSP_TX_PKT_RXPHITCNT(idx) (R_BCM1480_HSP_TX_PKT_RXPHITCNT_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_HTIO_RXPHITCNT 0x00000400D0
+#define R_BCM1480_HSP_TX_HTCC_RXPHITCNT 0x00000400D8
+
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_0 0x00000400E0
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_1 0x00000400E8
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_2 0x00000400F0
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT_3 0x00000400F8
+#define R_BCM1480_HSP_TX_PKT_TXPHITCNT(idx) (R_BCM1480_HSP_TX_PKT_TXPHITCNT_0 + 8*(idx))
+#define R_BCM1480_HSP_TX_HTIO_TXPHITCNT 0x0000040100
+#define R_BCM1480_HSP_TX_HTCC_TXPHITCNT 0x0000040108
+
+#define R_BCM1480_HSP_TX_SPI4_CALENDAR_0 0x0000040200
+#define R_BCM1480_HSP_TX_SPI4_CALENDAR_1 0x0000040208
+
+#define R_BCM1480_HSP_TX_PLL_CNFG 0x0000040800
+#define R_BCM1480_HSP_TX_CALIBRATION 0x0000040808
+#define R_BCM1480_HSP_TX_TEST 0x0000040810
+
+#define R_BCM1480_HSP_TX_VIS_CMDQ_0 0x0000040840
+#define R_BCM1480_HSP_TX_VIS_CMDQ_1 0x0000040848
+#define R_BCM1480_HSP_TX_VIS_CMDQ_2 0x0000040850
+#define R_BCM1480_HSP_TX_RAM_READCTL 0x0000040860
+#define R_BCM1480_HSP_TX_RAM_READWINDOW 0x0000040868
+#define R_BCM1480_HSP_TX_RF_READCTL 0x0000040870
+#define R_BCM1480_HSP_TX_RF_READWINDOW 0x0000040878
+
+#define R_BCM1480_HSP_TX_SPI4_PORT_INT_STATUS 0x0000040880
+#define R_BCM1480_HSP_TX_SPI4_PORT_INT_EN 0x0000040888
+
+#define R_BCM1480_HSP_TX_NEXT_ADDR_BASE 0x000040400
+#define R_BCM1480_HSP_TX_NEXT_ADDR_REGISTER(x) (R_BCM1480_HSP_TX_NEXT_ADDR_BASE+ 8*(x))
+
+
+
+/* *********************************************************************
+ * Physical Address Map (Table 10 and Figure 7)
+ ********************************************************************* */
+
+#define A_BCM1480_PHYS_MEMORY_0 _SB_MAKE64(0x0000000000)
+#define A_BCM1480_PHYS_MEMORY_SIZE _SB_MAKE64((256*1024*1024))
+#define A_BCM1480_PHYS_SYSTEM_CTL _SB_MAKE64(0x0010000000)
+#define A_BCM1480_PHYS_IO_SYSTEM _SB_MAKE64(0x0010060000)
+#define A_BCM1480_PHYS_GENBUS _SB_MAKE64(0x0010090000)
+#define A_BCM1480_PHYS_GENBUS_END _SB_MAKE64(0x0028000000)
+#define A_BCM1480_PHYS_PCI_MISC_MATCH_BYTES _SB_MAKE64(0x0028000000)
+#define A_BCM1480_PHYS_PCI_IACK_MATCH_BYTES _SB_MAKE64(0x0029000000)
+#define A_BCM1480_PHYS_PCI_IO_MATCH_BYTES _SB_MAKE64(0x002C000000)
+#define A_BCM1480_PHYS_PCI_CFG_MATCH_BYTES _SB_MAKE64(0x002E000000)
+#define A_BCM1480_PHYS_PCI_OMAP_MATCH_BYTES _SB_MAKE64(0x002F000000)
+#define A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES _SB_MAKE64(0x0030000000)
+#define A_BCM1480_PHYS_HT_MEM_MATCH_BYTES _SB_MAKE64(0x0040000000)
+#define A_BCM1480_PHYS_HT_MEM_MATCH_BITS _SB_MAKE64(0x0060000000)
+#define A_BCM1480_PHYS_MEMORY_1 _SB_MAKE64(0x0080000000)
+#define A_BCM1480_PHYS_MEMORY_2 _SB_MAKE64(0x0090000000)
+#define A_BCM1480_PHYS_PCI_MISC_MATCH_BITS _SB_MAKE64(0x00A8000000)
+#define A_BCM1480_PHYS_PCI_IACK_MATCH_BITS _SB_MAKE64(0x00A9000000)
+#define A_BCM1480_PHYS_PCI_IO_MATCH_BITS _SB_MAKE64(0x00AC000000)
+#define A_BCM1480_PHYS_PCI_CFG_MATCH_BITS _SB_MAKE64(0x00AE000000)
+#define A_BCM1480_PHYS_PCI_OMAP_MATCH_BITS _SB_MAKE64(0x00AF000000)
+#define A_BCM1480_PHYS_PCI_MEM_MATCH_BITS _SB_MAKE64(0x00B0000000)
+#define A_BCM1480_PHYS_MEMORY_3 _SB_MAKE64(0x00C0000000)
+#define A_BCM1480_PHYS_L2_CACHE_TEST _SB_MAKE64(0x00D0000000)
+#define A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES _SB_MAKE64(0x00D8000000)
+#define A_BCM1480_PHYS_HT_IO_MATCH_BYTES _SB_MAKE64(0x00DC000000)
+#define A_BCM1480_PHYS_HT_CFG_MATCH_BYTES _SB_MAKE64(0x00DE000000)
+#define A_BCM1480_PHYS_HS_SUBSYS _SB_MAKE64(0x00DF000000)
+#define A_BCM1480_PHYS_HT_SPECIAL_MATCH_BITS _SB_MAKE64(0x00F8000000)
+#define A_BCM1480_PHYS_HT_IO_MATCH_BITS _SB_MAKE64(0x00FC000000)
+#define A_BCM1480_PHYS_HT_CFG_MATCH_BITS _SB_MAKE64(0x00FE000000)
+#define A_BCM1480_PHYS_MEMORY_EXP _SB_MAKE64(0x0100000000)
+#define A_BCM1480_PHYS_MEMORY_EXP_SIZE _SB_MAKE64((508*1024*1024*1024))
+#define A_BCM1480_PHYS_PCI_UPPER _SB_MAKE64(0x1000000000)
+#define A_BCM1480_PHYS_HT_UPPER_MATCH_BYTES _SB_MAKE64(0x2000000000)
+#define A_BCM1480_PHYS_HT_UPPER_MATCH_BITS _SB_MAKE64(0x3000000000)
+#define A_BCM1480_PHYS_HT_NODE_ALIAS _SB_MAKE64(0x4000000000)
+#define A_BCM1480_PHYS_HT_FULLACCESS _SB_MAKE64(0xF000000000)
+
+
+/* *********************************************************************
+ * L2 Cache as RAM (Table 54)
+ ********************************************************************* */
+
+#define A_BCM1480_PHYS_L2CACHE_WAY_SIZE _SB_MAKE64(0x0000020000)
+#define BCM1480_PHYS_L2CACHE_NUM_WAYS 8
+#define A_BCM1480_PHYS_L2CACHE_TOTAL_SIZE _SB_MAKE64(0x0000100000)
+#define A_BCM1480_PHYS_L2CACHE_WAY0 _SB_MAKE64(0x00D0300000)
+#define A_BCM1480_PHYS_L2CACHE_WAY1 _SB_MAKE64(0x00D0320000)
+#define A_BCM1480_PHYS_L2CACHE_WAY2 _SB_MAKE64(0x00D0340000)
+#define A_BCM1480_PHYS_L2CACHE_WAY3 _SB_MAKE64(0x00D0360000)
+#define A_BCM1480_PHYS_L2CACHE_WAY4 _SB_MAKE64(0x00D0380000)
+#define A_BCM1480_PHYS_L2CACHE_WAY5 _SB_MAKE64(0x00D03A0000)
+#define A_BCM1480_PHYS_L2CACHE_WAY6 _SB_MAKE64(0x00D03C0000)
+#define A_BCM1480_PHYS_L2CACHE_WAY7 _SB_MAKE64(0x00D03E0000)
+
+#endif /* _BCM1480_REGS_H */
diff --git a/arch/mips/include/asm/sibyte/bcm1480_scd.h b/arch/mips/include/asm/sibyte/bcm1480_scd.h
new file mode 100644
index 00000000..25ef24cb
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/bcm1480_scd.h
@@ -0,0 +1,406 @@
+/* *********************************************************************
+ * BCM1280/BCM1400 Board Support Package
+ *
+ * SCD Constants and Macros File: bcm1480_scd.h
+ *
+ * This module contains constants and macros useful for
+ * manipulating the System Control and Debug module.
+ *
+ * BCM1400 specification level: 1X55_1X80-UM100-R (12/18/03)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003,2004,2005
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+#ifndef _BCM1480_SCD_H
+#define _BCM1480_SCD_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Pull in the BCM1250's SCD since lots of stuff is the same.
+ ********************************************************************* */
+
+#include "sb1250_scd.h"
+
+/* *********************************************************************
+ * Some general notes:
+ *
+ * This file is basically a "what's new" header file. Since the
+ * BCM1250 and the new BCM1480 (and derivatives) share many common
+ * features, this file contains only what's new or changed from
+ * the 1250. (above, you can see that we include the 1250 symbols
+ * to get the base functionality).
+ *
+ * In software, be sure to use the correct symbols, particularly
+ * for blocks that are different between the two chip families.
+ * All BCM1480-specific symbols have _BCM1480_ in their names,
+ * and all BCM1250-specific and "base" functions that are common in
+ * both chips have no special names (this is for compatibility with
+ * older include files). Therefore, if you're working with the
+ * SCD, which is very different on each chip, A_SCD_xxx implies
+ * the BCM1250 version and A_BCM1480_SCD_xxx implies the BCM1480
+ * version.
+ ********************************************************************* */
+
+/* *********************************************************************
+ * System control/debug registers
+ ********************************************************************* */
+
+/*
+ * System Identification and Revision Register (Table 12)
+ * Register: SCD_SYSTEM_REVISION
+ * This register is field compatible with the 1250.
+ */
+
+/*
+ * New part definitions
+ */
+
+#define K_SYS_PART_BCM1480 0x1406
+#define K_SYS_PART_BCM1280 0x1206
+#define K_SYS_PART_BCM1455 0x1407
+#define K_SYS_PART_BCM1255 0x1257
+#define K_SYS_PART_BCM1158 0x1156
+
+/*
+ * Manufacturing Information Register (Table 14)
+ * Register: SCD_SYSTEM_MANUF
+ */
+
+/*
+ * System Configuration Register (Table 15)
+ * Register: SCD_SYSTEM_CFG
+ * Entire register is different from 1250, all new constants below
+ */
+
+#define M_BCM1480_SYS_RESERVED0 _SB_MAKEMASK1(0)
+#define M_BCM1480_SYS_HT_MINRSTCNT _SB_MAKEMASK1(1)
+#define M_BCM1480_SYS_RESERVED2 _SB_MAKEMASK1(2)
+#define M_BCM1480_SYS_RESERVED3 _SB_MAKEMASK1(3)
+#define M_BCM1480_SYS_RESERVED4 _SB_MAKEMASK1(4)
+#define M_BCM1480_SYS_IOB_DIV _SB_MAKEMASK1(5)
+
+#define S_BCM1480_SYS_PLL_DIV _SB_MAKE64(6)
+#define M_BCM1480_SYS_PLL_DIV _SB_MAKEMASK(5, S_BCM1480_SYS_PLL_DIV)
+#define V_BCM1480_SYS_PLL_DIV(x) _SB_MAKEVALUE(x, S_BCM1480_SYS_PLL_DIV)
+#define G_BCM1480_SYS_PLL_DIV(x) _SB_GETVALUE(x, S_BCM1480_SYS_PLL_DIV, M_BCM1480_SYS_PLL_DIV)
+
+#define S_BCM1480_SYS_SW_DIV _SB_MAKE64(11)
+#define M_BCM1480_SYS_SW_DIV _SB_MAKEMASK(5, S_BCM1480_SYS_SW_DIV)
+#define V_BCM1480_SYS_SW_DIV(x) _SB_MAKEVALUE(x, S_BCM1480_SYS_SW_DIV)
+#define G_BCM1480_SYS_SW_DIV(x) _SB_GETVALUE(x, S_BCM1480_SYS_SW_DIV, M_BCM1480_SYS_SW_DIV)
+
+#define M_BCM1480_SYS_PCMCIA_ENABLE _SB_MAKEMASK1(16)
+#define M_BCM1480_SYS_DUART1_ENABLE _SB_MAKEMASK1(17)
+
+#define S_BCM1480_SYS_BOOT_MODE _SB_MAKE64(18)
+#define M_BCM1480_SYS_BOOT_MODE _SB_MAKEMASK(2, S_BCM1480_SYS_BOOT_MODE)
+#define V_BCM1480_SYS_BOOT_MODE(x) _SB_MAKEVALUE(x, S_BCM1480_SYS_BOOT_MODE)
+#define G_BCM1480_SYS_BOOT_MODE(x) _SB_GETVALUE(x, S_BCM1480_SYS_BOOT_MODE, M_BCM1480_SYS_BOOT_MODE)
+#define K_BCM1480_SYS_BOOT_MODE_ROM32 0
+#define K_BCM1480_SYS_BOOT_MODE_ROM8 1
+#define K_BCM1480_SYS_BOOT_MODE_SMBUS_SMALL 2
+#define K_BCM1480_SYS_BOOT_MODE_SMBUS_BIG 3
+#define M_BCM1480_SYS_BOOT_MODE_SMBUS _SB_MAKEMASK1(19)
+
+#define M_BCM1480_SYS_PCI_HOST _SB_MAKEMASK1(20)
+#define M_BCM1480_SYS_PCI_ARBITER _SB_MAKEMASK1(21)
+#define M_BCM1480_SYS_BIG_ENDIAN _SB_MAKEMASK1(22)
+#define M_BCM1480_SYS_GENCLK_EN _SB_MAKEMASK1(23)
+#define M_BCM1480_SYS_GEN_PARITY_EN _SB_MAKEMASK1(24)
+#define M_BCM1480_SYS_RESERVED25 _SB_MAKEMASK1(25)
+
+#define S_BCM1480_SYS_CONFIG 26
+#define M_BCM1480_SYS_CONFIG _SB_MAKEMASK(6, S_BCM1480_SYS_CONFIG)
+#define V_BCM1480_SYS_CONFIG(x) _SB_MAKEVALUE(x, S_BCM1480_SYS_CONFIG)
+#define G_BCM1480_SYS_CONFIG(x) _SB_GETVALUE(x, S_BCM1480_SYS_CONFIG, M_BCM1480_SYS_CONFIG)
+
+#define M_BCM1480_SYS_RESERVED32 _SB_MAKEMASK(32, 15)
+
+#define S_BCM1480_SYS_NODEID 47
+#define M_BCM1480_SYS_NODEID _SB_MAKEMASK(4, S_BCM1480_SYS_NODEID)
+#define V_BCM1480_SYS_NODEID(x) _SB_MAKEVALUE(x, S_BCM1480_SYS_NODEID)
+#define G_BCM1480_SYS_NODEID(x) _SB_GETVALUE(x, S_BCM1480_SYS_NODEID, M_BCM1480_SYS_NODEID)
+
+#define M_BCM1480_SYS_CCNUMA_EN _SB_MAKEMASK1(51)
+#define M_BCM1480_SYS_CPU_RESET_0 _SB_MAKEMASK1(52)
+#define M_BCM1480_SYS_CPU_RESET_1 _SB_MAKEMASK1(53)
+#define M_BCM1480_SYS_CPU_RESET_2 _SB_MAKEMASK1(54)
+#define M_BCM1480_SYS_CPU_RESET_3 _SB_MAKEMASK1(55)
+#define S_BCM1480_SYS_DISABLECPU0 56
+#define M_BCM1480_SYS_DISABLECPU0 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU0)
+#define S_BCM1480_SYS_DISABLECPU1 57
+#define M_BCM1480_SYS_DISABLECPU1 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU1)
+#define S_BCM1480_SYS_DISABLECPU2 58
+#define M_BCM1480_SYS_DISABLECPU2 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU2)
+#define S_BCM1480_SYS_DISABLECPU3 59
+#define M_BCM1480_SYS_DISABLECPU3 _SB_MAKEMASK1(S_BCM1480_SYS_DISABLECPU3)
+
+#define M_BCM1480_SYS_SB_SOFTRES _SB_MAKEMASK1(60)
+#define M_BCM1480_SYS_EXT_RESET _SB_MAKEMASK1(61)
+#define M_BCM1480_SYS_SYSTEM_RESET _SB_MAKEMASK1(62)
+#define M_BCM1480_SYS_SW_FLAG _SB_MAKEMASK1(63)
+
+/*
+ * Scratch Register (Table 16)
+ * Register: SCD_SYSTEM_SCRATCH
+ * Same as BCM1250
+ */
+
+
+/*
+ * Mailbox Registers (Table 17)
+ * Registers: SCD_MBOX_{0,1}_CPU_x
+ * Same as BCM1250
+ */
+
+
+/*
+ * See bcm1480_int.h for interrupt mapper registers.
+ */
+
+
+/*
+ * Watchdog Timer Initial Count Registers (Table 23)
+ * Registers: SCD_WDOG_INIT_CNT_x
+ *
+ * The watchdogs are almost the same as the 1250, except
+ * the configuration register has more bits to control the
+ * other CPUs.
+ */
+
+
+/*
+ * Watchdog Timer Configuration Registers (Table 25)
+ * Registers: SCD_WDOG_CFG_x
+ */
+
+#define M_BCM1480_SCD_WDOG_ENABLE _SB_MAKEMASK1(0)
+
+#define S_BCM1480_SCD_WDOG_RESET_TYPE 2
+#define M_BCM1480_SCD_WDOG_RESET_TYPE _SB_MAKEMASK(5, S_BCM1480_SCD_WDOG_RESET_TYPE)
+#define V_BCM1480_SCD_WDOG_RESET_TYPE(x) _SB_MAKEVALUE(x, S_BCM1480_SCD_WDOG_RESET_TYPE)
+#define G_BCM1480_SCD_WDOG_RESET_TYPE(x) _SB_GETVALUE(x, S_BCM1480_SCD_WDOG_RESET_TYPE, M_BCM1480_SCD_WDOG_RESET_TYPE)
+
+#define K_BCM1480_SCD_WDOG_RESET_FULL 0 /* actually, (x & 1) == 0 */
+#define K_BCM1480_SCD_WDOG_RESET_SOFT 1
+#define K_BCM1480_SCD_WDOG_RESET_CPU0 3
+#define K_BCM1480_SCD_WDOG_RESET_CPU1 5
+#define K_BCM1480_SCD_WDOG_RESET_CPU2 9
+#define K_BCM1480_SCD_WDOG_RESET_CPU3 17
+#define K_BCM1480_SCD_WDOG_RESET_ALL_CPUS 31
+
+
+#define M_BCM1480_SCD_WDOG_HAS_RESET _SB_MAKEMASK1(8)
+
+/*
+ * General Timer Initial Count Registers (Table 26)
+ * Registers: SCD_TIMER_INIT_x
+ *
+ * The timer registers are the same as the BCM1250
+ */
+
+
+/*
+ * ZBbus Count Register (Table 29)
+ * Register: ZBBUS_CYCLE_COUNT
+ *
+ * Same as BCM1250
+ */
+
+/*
+ * ZBbus Compare Registers (Table 30)
+ * Registers: ZBBUS_CYCLE_CPx
+ *
+ * Same as BCM1250
+ */
+
+
+/*
+ * System Performance Counter Configuration Register (Table 31)
+ * Register: PERF_CNT_CFG_0
+ *
+ * SPC_CFG_SRC[0-3] is the same as the 1250.
+ * SPC_CFG_SRC[4-7] only exist on the 1480
+ * The clear/enable bits are in different locations on the 1250 and 1480.
+ */
+
+#define S_SPC_CFG_SRC4 32
+#define M_SPC_CFG_SRC4 _SB_MAKEMASK(8, S_SPC_CFG_SRC4)
+#define V_SPC_CFG_SRC4(x) _SB_MAKEVALUE(x, S_SPC_CFG_SRC4)
+#define G_SPC_CFG_SRC4(x) _SB_GETVALUE(x, S_SPC_CFG_SRC4, M_SPC_CFG_SRC4)
+
+#define S_SPC_CFG_SRC5 40
+#define M_SPC_CFG_SRC5 _SB_MAKEMASK(8, S_SPC_CFG_SRC5)
+#define V_SPC_CFG_SRC5(x) _SB_MAKEVALUE(x, S_SPC_CFG_SRC5)
+#define G_SPC_CFG_SRC5(x) _SB_GETVALUE(x, S_SPC_CFG_SRC5, M_SPC_CFG_SRC5)
+
+#define S_SPC_CFG_SRC6 48
+#define M_SPC_CFG_SRC6 _SB_MAKEMASK(8, S_SPC_CFG_SRC6)
+#define V_SPC_CFG_SRC6(x) _SB_MAKEVALUE(x, S_SPC_CFG_SRC6)
+#define G_SPC_CFG_SRC6(x) _SB_GETVALUE(x, S_SPC_CFG_SRC6, M_SPC_CFG_SRC6)
+
+#define S_SPC_CFG_SRC7 56
+#define M_SPC_CFG_SRC7 _SB_MAKEMASK(8, S_SPC_CFG_SRC7)
+#define V_SPC_CFG_SRC7(x) _SB_MAKEVALUE(x, S_SPC_CFG_SRC7)
+#define G_SPC_CFG_SRC7(x) _SB_GETVALUE(x, S_SPC_CFG_SRC7, M_SPC_CFG_SRC7)
+
+/*
+ * System Performance Counter Control Register (Table 32)
+ * Register: PERF_CNT_CFG_1
+ * BCM1480 specific
+ */
+#define M_BCM1480_SPC_CFG_CLEAR _SB_MAKEMASK1(0)
+#define M_BCM1480_SPC_CFG_ENABLE _SB_MAKEMASK1(1)
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_SPC_CFG_CLEAR M_BCM1480_SPC_CFG_CLEAR
+#define M_SPC_CFG_ENABLE M_BCM1480_SPC_CFG_ENABLE
+#endif
+
+/*
+ * System Performance Counters (Table 33)
+ * Registers: PERF_CNT_x
+ */
+
+#define S_BCM1480_SPC_CNT_COUNT 0
+#define M_BCM1480_SPC_CNT_COUNT _SB_MAKEMASK(40, S_BCM1480_SPC_CNT_COUNT)
+#define V_BCM1480_SPC_CNT_COUNT(x) _SB_MAKEVALUE(x, S_BCM1480_SPC_CNT_COUNT)
+#define G_BCM1480_SPC_CNT_COUNT(x) _SB_GETVALUE(x, S_BCM1480_SPC_CNT_COUNT, M_BCM1480_SPC_CNT_COUNT)
+
+#define M_BCM1480_SPC_CNT_OFLOW _SB_MAKEMASK1(40)
+
+
+/*
+ * Bus Watcher Error Status Register (Tables 36, 37)
+ * Registers: BUS_ERR_STATUS, BUS_ERR_STATUS_DEBUG
+ * Same as BCM1250.
+ */
+
+/*
+ * Bus Watcher Error Data Registers (Table 38)
+ * Registers: BUS_ERR_DATA_x
+ * Same as BCM1250.
+ */
+
+/*
+ * Bus Watcher L2 ECC Counter Register (Table 39)
+ * Register: BUS_L2_ERRORS
+ * Same as BCM1250.
+ */
+
+
+/*
+ * Bus Watcher Memory and I/O Error Counter Register (Table 40)
+ * Register: BUS_MEM_IO_ERRORS
+ * Same as BCM1250.
+ */
+
+
+/*
+ * Address Trap Registers
+ *
+ * Register layout same as BCM1250, almost. The bus agents
+ * are different, and the address trap configuration bits are
+ * slightly different.
+ */
+
+#define M_BCM1480_ATRAP_INDEX _SB_MAKEMASK(4, 0)
+#define M_BCM1480_ATRAP_ADDRESS _SB_MAKEMASK(40, 0)
+
+#define S_BCM1480_ATRAP_CFG_CNT 0
+#define M_BCM1480_ATRAP_CFG_CNT _SB_MAKEMASK(3, S_BCM1480_ATRAP_CFG_CNT)
+#define V_BCM1480_ATRAP_CFG_CNT(x) _SB_MAKEVALUE(x, S_BCM1480_ATRAP_CFG_CNT)
+#define G_BCM1480_ATRAP_CFG_CNT(x) _SB_GETVALUE(x, S_BCM1480_ATRAP_CFG_CNT, M_BCM1480_ATRAP_CFG_CNT)
+
+#define M_BCM1480_ATRAP_CFG_WRITE _SB_MAKEMASK1(3)
+#define M_BCM1480_ATRAP_CFG_ALL _SB_MAKEMASK1(4)
+#define M_BCM1480_ATRAP_CFG_INV _SB_MAKEMASK1(5)
+#define M_BCM1480_ATRAP_CFG_USESRC _SB_MAKEMASK1(6)
+#define M_BCM1480_ATRAP_CFG_SRCINV _SB_MAKEMASK1(7)
+
+#define S_BCM1480_ATRAP_CFG_AGENTID 8
+#define M_BCM1480_ATRAP_CFG_AGENTID _SB_MAKEMASK(4, S_BCM1480_ATRAP_CFG_AGENTID)
+#define V_BCM1480_ATRAP_CFG_AGENTID(x) _SB_MAKEVALUE(x, S_BCM1480_ATRAP_CFG_AGENTID)
+#define G_BCM1480_ATRAP_CFG_AGENTID(x) _SB_GETVALUE(x, S_BCM1480_ATRAP_CFG_AGENTID, M_BCM1480_ATRAP_CFG_AGENTID)
+
+
+#define K_BCM1480_BUS_AGENT_CPU0 0
+#define K_BCM1480_BUS_AGENT_CPU1 1
+#define K_BCM1480_BUS_AGENT_NC 2
+#define K_BCM1480_BUS_AGENT_IOB 3
+#define K_BCM1480_BUS_AGENT_SCD 4
+#define K_BCM1480_BUS_AGENT_L2C 6
+#define K_BCM1480_BUS_AGENT_MC 7
+#define K_BCM1480_BUS_AGENT_CPU2 8
+#define K_BCM1480_BUS_AGENT_CPU3 9
+#define K_BCM1480_BUS_AGENT_PM 10
+
+#define S_BCM1480_ATRAP_CFG_CATTR 12
+#define M_BCM1480_ATRAP_CFG_CATTR _SB_MAKEMASK(2, S_BCM1480_ATRAP_CFG_CATTR)
+#define V_BCM1480_ATRAP_CFG_CATTR(x) _SB_MAKEVALUE(x, S_BCM1480_ATRAP_CFG_CATTR)
+#define G_BCM1480_ATRAP_CFG_CATTR(x) _SB_GETVALUE(x, S_BCM1480_ATRAP_CFG_CATTR, M_BCM1480_ATRAP_CFG_CATTR)
+
+#define K_BCM1480_ATRAP_CFG_CATTR_IGNORE 0
+#define K_BCM1480_ATRAP_CFG_CATTR_UNC 1
+#define K_BCM1480_ATRAP_CFG_CATTR_NONCOH 2
+#define K_BCM1480_ATRAP_CFG_CATTR_COHERENT 3
+
+#define M_BCM1480_ATRAP_CFG_CATTRINV _SB_MAKEMASK1(14)
+
+
+/*
+ * Trace Event Registers (Table 47)
+ * Same as BCM1250.
+ */
+
+/*
+ * Trace Sequence Control Registers (Table 48)
+ * Registers: TRACE_SEQUENCE_x
+ *
+ * Same as BCM1250 except for two new fields.
+ */
+
+
+#define M_BCM1480_SCD_TRSEQ_TID_MATCH_EN _SB_MAKEMASK1(25)
+
+#define S_BCM1480_SCD_TRSEQ_SWFUNC 26
+#define M_BCM1480_SCD_TRSEQ_SWFUNC _SB_MAKEMASK(2, S_BCM1480_SCD_TRSEQ_SWFUNC)
+#define V_BCM1480_SCD_TRSEQ_SWFUNC(x) _SB_MAKEVALUE(x, S_BCM1480_SCD_TRSEQ_SWFUNC)
+#define G_BCM1480_SCD_TRSEQ_SWFUNC(x) _SB_GETVALUE(x, S_BCM1480_SCD_TRSEQ_SWFUNC, M_BCM1480_SCD_TRSEQ_SWFUNC)
+
+/*
+ * Trace Control Register (Table 49)
+ * Register: TRACE_CFG
+ *
+ * BCM1480 changes to this register (other than location of the CUR_ADDR field)
+ * are defined below.
+ */
+
+#define S_BCM1480_SCD_TRACE_CFG_MODE 16
+#define M_BCM1480_SCD_TRACE_CFG_MODE _SB_MAKEMASK(2, S_BCM1480_SCD_TRACE_CFG_MODE)
+#define V_BCM1480_SCD_TRACE_CFG_MODE(x) _SB_MAKEVALUE(x, S_BCM1480_SCD_TRACE_CFG_MODE)
+#define G_BCM1480_SCD_TRACE_CFG_MODE(x) _SB_GETVALUE(x, S_BCM1480_SCD_TRACE_CFG_MODE, M_BCM1480_SCD_TRACE_CFG_MODE)
+
+#define K_BCM1480_SCD_TRACE_CFG_MODE_BLOCKERS 0
+#define K_BCM1480_SCD_TRACE_CFG_MODE_BYTEEN_INT 1
+#define K_BCM1480_SCD_TRACE_CFG_MODE_FLOW_ID 2
+
+#endif /* _BCM1480_SCD_H */
diff --git a/arch/mips/include/asm/sibyte/bigsur.h b/arch/mips/include/asm/sibyte/bigsur.h
new file mode 100644
index 00000000..2d1a26d3
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/bigsur.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __ASM_SIBYTE_BIGSUR_H
+#define __ASM_SIBYTE_BIGSUR_H
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/bcm1480_int.h>
+
+#ifdef CONFIG_SIBYTE_BIGSUR
+#define SIBYTE_BOARD_NAME "BCM91x80A/B (BigSur)"
+#define SIBYTE_HAVE_PCMCIA 1
+#define SIBYTE_HAVE_IDE 1
+#endif
+
+/* Generic bus chip selects */
+#define LEDS_CS 3
+#define LEDS_PHYS 0x100a0000
+
+#ifdef SIBYTE_HAVE_IDE
+#define IDE_CS 4
+#define IDE_PHYS 0x100b0000
+#define K_GPIO_GB_IDE 4
+#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE)
+#endif
+
+#ifdef SIBYTE_HAVE_PCMCIA
+#define PCMCIA_CS 6
+#define PCMCIA_PHYS 0x11000000
+#define K_GPIO_PC_READY 9
+#define K_INT_PC_READY (K_INT_GPIO_0 + K_GPIO_PC_READY)
+#endif
+
+#endif /* __ASM_SIBYTE_BIGSUR_H */
diff --git a/arch/mips/include/asm/sibyte/board.h b/arch/mips/include/asm/sibyte/board.h
new file mode 100644
index 00000000..25372ae0
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/board.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _SIBYTE_BOARD_H
+#define _SIBYTE_BOARD_H
+
+#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_CRHONE) || \
+ defined(CONFIG_SIBYTE_CRHINE) || defined(CONFIG_SIBYTE_LITTLESUR)
+#include <asm/sibyte/swarm.h>
+#endif
+
+#if defined(CONFIG_SIBYTE_SENTOSA) || defined(CONFIG_SIBYTE_RHONE)
+#include <asm/sibyte/sentosa.h>
+#endif
+
+#ifdef CONFIG_SIBYTE_CARMEL
+#include <asm/sibyte/carmel.h>
+#endif
+
+#ifdef CONFIG_SIBYTE_BIGSUR
+#include <asm/sibyte/bigsur.h>
+#endif
+
+#ifdef __ASSEMBLY__
+
+#ifdef LEDS_PHYS
+#define setleds(t0, t1, c0, c1, c2, c3) \
+ li t0, (LEDS_PHYS|0xa0000000); \
+ li t1, c0; \
+ sb t1, 0x18(t0); \
+ li t1, c1; \
+ sb t1, 0x10(t0); \
+ li t1, c2; \
+ sb t1, 0x08(t0); \
+ li t1, c3; \
+ sb t1, 0x00(t0)
+#else
+#define setleds(t0, t1, c0, c1, c2, c3)
+#endif /* LEDS_PHYS */
+
+#else
+
+void swarm_setup(void);
+
+#ifdef LEDS_PHYS
+extern void setleds(char *str);
+#else
+#define setleds(s) do { } while (0)
+#endif /* LEDS_PHYS */
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _SIBYTE_BOARD_H */
diff --git a/arch/mips/include/asm/sibyte/carmel.h b/arch/mips/include/asm/sibyte/carmel.h
new file mode 100644
index 00000000..11cad713
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/carmel.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2002 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __ASM_SIBYTE_CARMEL_H
+#define __ASM_SIBYTE_CARMEL_H
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_int.h>
+
+#define SIBYTE_BOARD_NAME "Carmel"
+
+#define GPIO_PHY_INTERRUPT 2
+#define GPIO_NONMASKABLE_INT 3
+#define GPIO_CF_INSERTED 6
+#define GPIO_MONTEREY_RESET 7
+#define GPIO_QUADUART_INT 8
+#define GPIO_CF_INT 9
+#define GPIO_FPGA_CCLK 10
+#define GPIO_FPGA_DOUT 11
+#define GPIO_FPGA_DIN 12
+#define GPIO_FPGA_PGM 13
+#define GPIO_FPGA_DONE 14
+#define GPIO_FPGA_INIT 15
+
+#define LEDS_CS 2
+#define LEDS_PHYS 0x100C0000
+#define MLEDS_CS 3
+#define MLEDS_PHYS 0x100A0000
+#define UART_CS 4
+#define UART_PHYS 0x100D0000
+#define ARAVALI_CS 5
+#define ARAVALI_PHYS 0x11000000
+#define IDE_CS 6
+#define IDE_PHYS 0x100B0000
+#define ARAVALI2_CS 7
+#define ARAVALI2_PHYS 0x100E0000
+
+#if defined(CONFIG_SIBYTE_CARMEL)
+#define K_GPIO_GB_IDE 9
+#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE)
+#endif
+
+
+#endif /* __ASM_SIBYTE_CARMEL_H */
diff --git a/arch/mips/include/asm/sibyte/sb1250.h b/arch/mips/include/asm/sibyte/sb1250.h
new file mode 100644
index 00000000..80c1a052
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ASM_SIBYTE_SB1250_H
+#define _ASM_SIBYTE_SB1250_H
+
+/*
+ * yymmddpp: year, month, day, patch.
+ * should sync with Makefile EXTRAVERSION
+ */
+#define SIBYTE_RELEASE 0x02111403
+
+#define SB1250_NR_IRQS 64
+
+#define BCM1480_NR_IRQS 128
+#define BCM1480_NR_IRQS_HALF 64
+
+#define SB1250_DUART_MINOR_BASE 64
+
+#ifndef __ASSEMBLY__
+
+#include <asm/addrspace.h>
+
+/* For revision/pass information */
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/bcm1480_scd.h>
+extern unsigned int sb1_pass;
+extern unsigned int soc_pass;
+extern unsigned int soc_type;
+extern unsigned int periph_rev;
+extern unsigned int zbbus_mhz;
+
+extern void sb1250_time_init(void);
+extern void sb1250_mask_irq(int cpu, int irq);
+extern void sb1250_unmask_irq(int cpu, int irq);
+
+extern void bcm1480_time_init(void);
+extern void bcm1480_mask_irq(int cpu, int irq);
+extern void bcm1480_unmask_irq(int cpu, int irq);
+
+#define AT_spin \
+ __asm__ __volatile__ ( \
+ ".set noat\n" \
+ "li $at, 0\n" \
+ "1: beqz $at, 1b\n" \
+ ".set at\n" \
+ )
+
+#endif
+
+#define IOADDR(a) ((void __iomem *)(IO_BASE + (a)))
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_defs.h b/arch/mips/include/asm/sibyte/sb1250_defs.h
new file mode 100644
index 00000000..09365f91
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_defs.h
@@ -0,0 +1,259 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Global constants and macros File: sb1250_defs.h
+ *
+ * This file contains macros and definitions used by the other
+ * include files.
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+#ifndef _SB1250_DEFS_H
+#define _SB1250_DEFS_H
+
+/*
+ * These headers require ANSI C89 string concatenation, and GCC or other
+ * 'long long' (64-bit integer) support.
+ */
+#if !defined(__STDC__) && !defined(_MSC_VER)
+#error SiByte headers require ANSI C89 support
+#endif
+
+
+/* *********************************************************************
+ * Macros for feature tests, used to enable include file features
+ * for chip features only present in certain chip revisions.
+ *
+ * SIBYTE_HDR_FEATURES may be defined to be the mask value chip/revision
+ * which is to be exposed by the headers. If undefined, it defaults to
+ * "all features."
+ *
+ * Use like:
+ *
+ * #define SIBYTE_HDR_FEATURES SIBYTE_HDR_FMASK_112x_PASS1
+ *
+ * Generate defines only for that revision of chip.
+ *
+ * #if SIBYTE_HDR_FEATURE(chip,pass)
+ *
+ * True if header features for that revision or later of
+ * that particular chip type are enabled in SIBYTE_HDR_FEATURES.
+ * (Use this to bracket #defines for features present in a given
+ * revision and later.)
+ *
+ * Note that there is no implied ordering between chip types.
+ *
+ * Note also that 'chip' and 'pass' must textually exactly
+ * match the defines below. So, for example,
+ * SIBYTE_HDR_FEATURE(112x, PASS1) is OK, but
+ * SIBYTE_HDR_FEATURE(1120, pass1) is not (for two reasons).
+ *
+ * #if SIBYTE_HDR_FEATURE_UP_TO(chip,pass)
+ *
+ * Same as SIBYTE_HDR_FEATURE, but true for the named revision
+ * and earlier revisions of the named chip type.
+ *
+ * #if SIBYTE_HDR_FEATURE_EXACT(chip,pass)
+ *
+ * Same as SIBYTE_HDR_FEATURE, but only true for the named
+ * revision of the named chip type. (Note that this CANNOT
+ * be used to verify that you're compiling only for that
+ * particular chip/revision. It will be true any time this
+ * chip/revision is included in SIBYTE_HDR_FEATURES.)
+ *
+ * #if SIBYTE_HDR_FEATURE_CHIP(chip)
+ *
+ * True if header features for (any revision of) that chip type
+ * are enabled in SIBYTE_HDR_FEATURES. (Use this to bracket
+ * #defines for features specific to a given chip type.)
+ *
+ * Mask values currently include room for additional revisions of each
+ * chip type, but can be renumbered at will. Note that they MUST fit
+ * into 31 bits and may not include C type constructs, for safe use in
+ * CPP conditionals. Bit positions within chip types DO indicate
+ * ordering, so be careful when adding support for new minor revs.
+ ********************************************************************* */
+
+#define SIBYTE_HDR_FMASK_1250_ALL 0x000000ff
+#define SIBYTE_HDR_FMASK_1250_PASS1 0x00000001
+#define SIBYTE_HDR_FMASK_1250_PASS2 0x00000002
+#define SIBYTE_HDR_FMASK_1250_PASS3 0x00000004
+
+#define SIBYTE_HDR_FMASK_112x_ALL 0x00000f00
+#define SIBYTE_HDR_FMASK_112x_PASS1 0x00000100
+
+#define SIBYTE_HDR_FMASK_1480_ALL 0x0000f000
+#define SIBYTE_HDR_FMASK_1480_PASS1 0x00001000
+#define SIBYTE_HDR_FMASK_1480_PASS2 0x00002000
+
+/* Bit mask for chip/revision. (use _ALL for all revisions of a chip). */
+#define SIBYTE_HDR_FMASK(chip, pass) \
+ (SIBYTE_HDR_FMASK_ ## chip ## _ ## pass)
+#define SIBYTE_HDR_FMASK_ALLREVS(chip) \
+ (SIBYTE_HDR_FMASK_ ## chip ## _ALL)
+
+/* Default constant value for all chips, all revisions */
+#define SIBYTE_HDR_FMASK_ALL \
+ (SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL \
+ | SIBYTE_HDR_FMASK_1480_ALL)
+
+/* This one is used for the "original" BCM1250/BCM112x chips. We use this
+ to weed out constants and macros that do not exist on later chips like
+ the BCM1480 */
+#define SIBYTE_HDR_FMASK_1250_112x_ALL \
+ (SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL)
+#define SIBYTE_HDR_FMASK_1250_112x SIBYTE_HDR_FMASK_1250_112x_ALL
+
+#ifndef SIBYTE_HDR_FEATURES
+#define SIBYTE_HDR_FEATURES SIBYTE_HDR_FMASK_ALL
+#endif
+
+
+/* Bit mask for revisions of chip exclusively before the named revision. */
+#define SIBYTE_HDR_FMASK_BEFORE(chip, pass) \
+ ((SIBYTE_HDR_FMASK(chip, pass) - 1) & SIBYTE_HDR_FMASK_ALLREVS(chip))
+
+/* Bit mask for revisions of chip exclusively after the named revision. */
+#define SIBYTE_HDR_FMASK_AFTER(chip, pass) \
+ (~(SIBYTE_HDR_FMASK(chip, pass) \
+ | (SIBYTE_HDR_FMASK(chip, pass) - 1)) & SIBYTE_HDR_FMASK_ALLREVS(chip))
+
+
+/* True if header features enabled for (any revision of) that chip type. */
+#define SIBYTE_HDR_FEATURE_CHIP(chip) \
+ (!! (SIBYTE_HDR_FMASK_ALLREVS(chip) & SIBYTE_HDR_FEATURES))
+
+/* True for all versions of the BCM1250 and BCM1125, but not true for
+ anything else */
+#define SIBYTE_HDR_FEATURE_1250_112x \
+ (SIBYTE_HDR_FEATURE_CHIP(1250) || SIBYTE_HDR_FEATURE_CHIP(112x))
+/* (!! (SIBYTE_HDR_FEATURES & SIBYHTE_HDR_FMASK_1250_112x)) */
+
+/* True if header features enabled for that rev or later, inclusive. */
+#define SIBYTE_HDR_FEATURE(chip, pass) \
+ (!! ((SIBYTE_HDR_FMASK(chip, pass) \
+ | SIBYTE_HDR_FMASK_AFTER(chip, pass)) & SIBYTE_HDR_FEATURES))
+
+/* True if header features enabled for exactly that rev. */
+#define SIBYTE_HDR_FEATURE_EXACT(chip, pass) \
+ (!! (SIBYTE_HDR_FMASK(chip, pass) & SIBYTE_HDR_FEATURES))
+
+/* True if header features enabled for that rev or before, inclusive. */
+#define SIBYTE_HDR_FEATURE_UP_TO(chip, pass) \
+ (!! ((SIBYTE_HDR_FMASK(chip, pass) \
+ | SIBYTE_HDR_FMASK_BEFORE(chip, pass)) & SIBYTE_HDR_FEATURES))
+
+
+/* *********************************************************************
+ * Naming schemes for constants in these files:
+ *
+ * M_xxx MASK constant (identifies bits in a register).
+ * For multi-bit fields, all bits in the field will
+ * be set.
+ *
+ * K_xxx "Code" constant (value for data in a multi-bit
+ * field). The value is right justified.
+ *
+ * V_xxx "Value" constant. This is the same as the
+ * corresponding "K_xxx" constant, except it is
+ * shifted to the correct position in the register.
+ *
+ * S_xxx SHIFT constant. This is the number of bits that
+ * a field value (code) needs to be shifted
+ * (towards the left) to put the value in the right
+ * position for the register.
+ *
+ * A_xxx ADDRESS constant. This will be a physical
+ * address. Use the PHYS_TO_K1 macro to generate
+ * a K1SEG address.
+ *
+ * R_xxx RELATIVE offset constant. This is an offset from
+ * an A_xxx constant (usually the first register in
+ * a group).
+ *
+ * G_xxx(X) GET value. This macro obtains a multi-bit field
+ * from a register, masks it, and shifts it to
+ * the bottom of the register (retrieving a K_xxx
+ * value, for example).
+ *
+ * V_xxx(X) VALUE. This macro computes the value of a
+ * K_xxx constant shifted to the correct position
+ * in the register.
+ ********************************************************************* */
+
+
+
+
+/*
+ * Cast to 64-bit number. Presumably the syntax is different in
+ * assembly language.
+ *
+ * Note: you'll need to define uint32_t and uint64_t in your headers.
+ */
+
+#if !defined(__ASSEMBLY__)
+#define _SB_MAKE64(x) ((uint64_t)(x))
+#define _SB_MAKE32(x) ((uint32_t)(x))
+#else
+#define _SB_MAKE64(x) (x)
+#define _SB_MAKE32(x) (x)
+#endif
+
+
+/*
+ * Make a mask for 1 bit at position 'n'
+ */
+
+#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n))
+#define _SB_MAKEMASK1_32(n) (_SB_MAKE32(1) << _SB_MAKE32(n))
+
+/*
+ * Make a mask for 'v' bits at position 'n'
+ */
+
+#define _SB_MAKEMASK(v, n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n))
+#define _SB_MAKEMASK_32(v, n) (_SB_MAKE32((_SB_MAKE32(1)<<(v))-1) << _SB_MAKE32(n))
+
+/*
+ * Make a value at 'v' at bit position 'n'
+ */
+
+#define _SB_MAKEVALUE(v, n) (_SB_MAKE64(v) << _SB_MAKE64(n))
+#define _SB_MAKEVALUE_32(v, n) (_SB_MAKE32(v) << _SB_MAKE32(n))
+
+#define _SB_GETVALUE(v, n, m) ((_SB_MAKE64(v) & _SB_MAKE64(m)) >> _SB_MAKE64(n))
+#define _SB_GETVALUE_32(v, n, m) ((_SB_MAKE32(v) & _SB_MAKE32(m)) >> _SB_MAKE32(n))
+
+/*
+ * Macros to read/write on-chip registers
+ * XXX should we do the PHYS_TO_K1 here?
+ */
+
+
+#if defined(__mips64) && !defined(__ASSEMBLY__)
+#define SBWRITECSR(csr, val) *((volatile uint64_t *) PHYS_TO_K1(csr)) = (val)
+#define SBREADCSR(csr) (*((volatile uint64_t *) PHYS_TO_K1(csr)))
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_dma.h b/arch/mips/include/asm/sibyte/sb1250_dma.h
new file mode 100644
index 00000000..bad56171
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_dma.h
@@ -0,0 +1,594 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * DMA definitions File: sb1250_dma.h
+ *
+ * This module contains constants and macros useful for
+ * programming the SB1250's DMA controllers, both the data mover
+ * and the Ethernet DMA.
+ *
+ * SB1250 specification level: User's manual 10/21/02
+ * BCM1280 specification level: User's manual 11/24/03
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_DMA_H
+#define _SB1250_DMA_H
+
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * DMA Registers
+ ********************************************************************* */
+
+/*
+ * Ethernet and Serial DMA Configuration Register 0 (Table 7-4)
+ * Registers: DMA_CONFIG0_MAC_x_RX_CH_0
+ * Registers: DMA_CONFIG0_MAC_x_TX_CH_0
+ * Registers: DMA_CONFIG0_SER_x_RX
+ * Registers: DMA_CONFIG0_SER_x_TX
+ */
+
+
+#define M_DMA_DROP _SB_MAKEMASK1(0)
+
+#define M_DMA_CHAIN_SEL _SB_MAKEMASK1(1)
+#define M_DMA_RESERVED1 _SB_MAKEMASK1(2)
+
+#define S_DMA_DESC_TYPE _SB_MAKE64(1)
+#define M_DMA_DESC_TYPE _SB_MAKEMASK(2, S_DMA_DESC_TYPE)
+#define V_DMA_DESC_TYPE(x) _SB_MAKEVALUE(x, S_DMA_DESC_TYPE)
+#define G_DMA_DESC_TYPE(x) _SB_GETVALUE(x, S_DMA_DESC_TYPE, M_DMA_DESC_TYPE)
+
+#define K_DMA_DESC_TYPE_RING_AL 0
+#define K_DMA_DESC_TYPE_CHAIN_AL 1
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define K_DMA_DESC_TYPE_RING_UAL_WI 2
+#define K_DMA_DESC_TYPE_RING_UAL_RMW 3
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define M_DMA_EOP_INT_EN _SB_MAKEMASK1(3)
+#define M_DMA_HWM_INT_EN _SB_MAKEMASK1(4)
+#define M_DMA_LWM_INT_EN _SB_MAKEMASK1(5)
+#define M_DMA_TBX_EN _SB_MAKEMASK1(6)
+#define M_DMA_TDX_EN _SB_MAKEMASK1(7)
+
+#define S_DMA_INT_PKTCNT _SB_MAKE64(8)
+#define M_DMA_INT_PKTCNT _SB_MAKEMASK(8, S_DMA_INT_PKTCNT)
+#define V_DMA_INT_PKTCNT(x) _SB_MAKEVALUE(x, S_DMA_INT_PKTCNT)
+#define G_DMA_INT_PKTCNT(x) _SB_GETVALUE(x, S_DMA_INT_PKTCNT, M_DMA_INT_PKTCNT)
+
+#define S_DMA_RINGSZ _SB_MAKE64(16)
+#define M_DMA_RINGSZ _SB_MAKEMASK(16, S_DMA_RINGSZ)
+#define V_DMA_RINGSZ(x) _SB_MAKEVALUE(x, S_DMA_RINGSZ)
+#define G_DMA_RINGSZ(x) _SB_GETVALUE(x, S_DMA_RINGSZ, M_DMA_RINGSZ)
+
+#define S_DMA_HIGH_WATERMARK _SB_MAKE64(32)
+#define M_DMA_HIGH_WATERMARK _SB_MAKEMASK(16, S_DMA_HIGH_WATERMARK)
+#define V_DMA_HIGH_WATERMARK(x) _SB_MAKEVALUE(x, S_DMA_HIGH_WATERMARK)
+#define G_DMA_HIGH_WATERMARK(x) _SB_GETVALUE(x, S_DMA_HIGH_WATERMARK, M_DMA_HIGH_WATERMARK)
+
+#define S_DMA_LOW_WATERMARK _SB_MAKE64(48)
+#define M_DMA_LOW_WATERMARK _SB_MAKEMASK(16, S_DMA_LOW_WATERMARK)
+#define V_DMA_LOW_WATERMARK(x) _SB_MAKEVALUE(x, S_DMA_LOW_WATERMARK)
+#define G_DMA_LOW_WATERMARK(x) _SB_GETVALUE(x, S_DMA_LOW_WATERMARK, M_DMA_LOW_WATERMARK)
+
+/*
+ * Ethernet and Serial DMA Configuration Register 1 (Table 7-5)
+ * Registers: DMA_CONFIG1_MAC_x_RX_CH_0
+ * Registers: DMA_CONFIG1_DMA_x_TX_CH_0
+ * Registers: DMA_CONFIG1_SER_x_RX
+ * Registers: DMA_CONFIG1_SER_x_TX
+ */
+
+#define M_DMA_HDR_CF_EN _SB_MAKEMASK1(0)
+#define M_DMA_ASIC_XFR_EN _SB_MAKEMASK1(1)
+#define M_DMA_PRE_ADDR_EN _SB_MAKEMASK1(2)
+#define M_DMA_FLOW_CTL_EN _SB_MAKEMASK1(3)
+#define M_DMA_NO_DSCR_UPDT _SB_MAKEMASK1(4)
+#define M_DMA_L2CA _SB_MAKEMASK1(5)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_DMA_RX_XTRA_STATUS _SB_MAKEMASK1(6)
+#define M_DMA_TX_CPU_PAUSE _SB_MAKEMASK1(6)
+#define M_DMA_TX_FC_PAUSE_EN _SB_MAKEMASK1(7)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define M_DMA_MBZ1 _SB_MAKEMASK(6, 15)
+
+#define S_DMA_HDR_SIZE _SB_MAKE64(21)
+#define M_DMA_HDR_SIZE _SB_MAKEMASK(9, S_DMA_HDR_SIZE)
+#define V_DMA_HDR_SIZE(x) _SB_MAKEVALUE(x, S_DMA_HDR_SIZE)
+#define G_DMA_HDR_SIZE(x) _SB_GETVALUE(x, S_DMA_HDR_SIZE, M_DMA_HDR_SIZE)
+
+#define M_DMA_MBZ2 _SB_MAKEMASK(5, 32)
+
+#define S_DMA_ASICXFR_SIZE _SB_MAKE64(37)
+#define M_DMA_ASICXFR_SIZE _SB_MAKEMASK(9, S_DMA_ASICXFR_SIZE)
+#define V_DMA_ASICXFR_SIZE(x) _SB_MAKEVALUE(x, S_DMA_ASICXFR_SIZE)
+#define G_DMA_ASICXFR_SIZE(x) _SB_GETVALUE(x, S_DMA_ASICXFR_SIZE, M_DMA_ASICXFR_SIZE)
+
+#define S_DMA_INT_TIMEOUT _SB_MAKE64(48)
+#define M_DMA_INT_TIMEOUT _SB_MAKEMASK(16, S_DMA_INT_TIMEOUT)
+#define V_DMA_INT_TIMEOUT(x) _SB_MAKEVALUE(x, S_DMA_INT_TIMEOUT)
+#define G_DMA_INT_TIMEOUT(x) _SB_GETVALUE(x, S_DMA_INT_TIMEOUT, M_DMA_INT_TIMEOUT)
+
+/*
+ * Ethernet and Serial DMA Descriptor base address (Table 7-6)
+ */
+
+#define M_DMA_DSCRBASE_MBZ _SB_MAKEMASK(4, 0)
+
+
+/*
+ * ASIC Mode Base Address (Table 7-7)
+ */
+
+#define M_DMA_ASIC_BASE_MBZ _SB_MAKEMASK(20, 0)
+
+/*
+ * DMA Descriptor Count Registers (Table 7-8)
+ */
+
+/* No bitfields */
+
+
+/*
+ * Current Descriptor Address Register (Table 7-11)
+ */
+
+#define S_DMA_CURDSCR_ADDR _SB_MAKE64(0)
+#define M_DMA_CURDSCR_ADDR _SB_MAKEMASK(40, S_DMA_CURDSCR_ADDR)
+#define S_DMA_CURDSCR_COUNT _SB_MAKE64(40)
+#define M_DMA_CURDSCR_COUNT _SB_MAKEMASK(16, S_DMA_CURDSCR_COUNT)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_DMA_TX_CH_PAUSE_ON _SB_MAKEMASK1(56)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+/*
+ * Receive Packet Drop Registers
+ */
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_DMA_OODLOST_RX _SB_MAKE64(0)
+#define M_DMA_OODLOST_RX _SB_MAKEMASK(16, S_DMA_OODLOST_RX)
+#define G_DMA_OODLOST_RX(x) _SB_GETVALUE(x, S_DMA_OODLOST_RX, M_DMA_OODLOST_RX)
+
+#define S_DMA_EOP_COUNT_RX _SB_MAKE64(16)
+#define M_DMA_EOP_COUNT_RX _SB_MAKEMASK(8, S_DMA_EOP_COUNT_RX)
+#define G_DMA_EOP_COUNT_RX(x) _SB_GETVALUE(x, S_DMA_EOP_COUNT_RX, M_DMA_EOP_COUNT_RX)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+/* *********************************************************************
+ * DMA Descriptors
+ ********************************************************************* */
+
+/*
+ * Descriptor doubleword "A" (Table 7-12)
+ */
+
+#define S_DMA_DSCRA_OFFSET _SB_MAKE64(0)
+#define M_DMA_DSCRA_OFFSET _SB_MAKEMASK(5, S_DMA_DSCRA_OFFSET)
+#define V_DMA_DSCRA_OFFSET(x) _SB_MAKEVALUE(x, S_DMA_DSCRA_OFFSET)
+#define G_DMA_DSCRA_OFFSET(x) _SB_GETVALUE(x, S_DMA_DSCRA_OFFSET, M_DMA_DSCRA_OFFSET)
+
+/* Note: Don't shift the address over, just mask it with the mask below */
+#define S_DMA_DSCRA_A_ADDR _SB_MAKE64(5)
+#define M_DMA_DSCRA_A_ADDR _SB_MAKEMASK(35, S_DMA_DSCRA_A_ADDR)
+
+#define M_DMA_DSCRA_A_ADDR_OFFSET (M_DMA_DSCRA_OFFSET | M_DMA_DSCRA_A_ADDR)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_DMA_DSCRA_A_ADDR_UA _SB_MAKE64(0)
+#define M_DMA_DSCRA_A_ADDR_UA _SB_MAKEMASK(40, S_DMA_DSCRA_A_ADDR_UA)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define S_DMA_DSCRA_A_SIZE _SB_MAKE64(40)
+#define M_DMA_DSCRA_A_SIZE _SB_MAKEMASK(9, S_DMA_DSCRA_A_SIZE)
+#define V_DMA_DSCRA_A_SIZE(x) _SB_MAKEVALUE(x, S_DMA_DSCRA_A_SIZE)
+#define G_DMA_DSCRA_A_SIZE(x) _SB_GETVALUE(x, S_DMA_DSCRA_A_SIZE, M_DMA_DSCRA_A_SIZE)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_DMA_DSCRA_DSCR_CNT _SB_MAKE64(40)
+#define M_DMA_DSCRA_DSCR_CNT _SB_MAKEMASK(8, S_DMA_DSCRA_DSCR_CNT)
+#define G_DMA_DSCRA_DSCR_CNT(x) _SB_GETVALUE(x, S_DMA_DSCRA_DSCR_CNT, M_DMA_DSCRA_DSCR_CNT)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define M_DMA_DSCRA_INTERRUPT _SB_MAKEMASK1(49)
+#define M_DMA_DSCRA_OFFSETB _SB_MAKEMASK1(50)
+
+#define S_DMA_DSCRA_STATUS _SB_MAKE64(51)
+#define M_DMA_DSCRA_STATUS _SB_MAKEMASK(13, S_DMA_DSCRA_STATUS)
+#define V_DMA_DSCRA_STATUS(x) _SB_MAKEVALUE(x, S_DMA_DSCRA_STATUS)
+#define G_DMA_DSCRA_STATUS(x) _SB_GETVALUE(x, S_DMA_DSCRA_STATUS, M_DMA_DSCRA_STATUS)
+
+/*
+ * Descriptor doubleword "B" (Table 7-13)
+ */
+
+
+#define S_DMA_DSCRB_OPTIONS _SB_MAKE64(0)
+#define M_DMA_DSCRB_OPTIONS _SB_MAKEMASK(4, S_DMA_DSCRB_OPTIONS)
+#define V_DMA_DSCRB_OPTIONS(x) _SB_MAKEVALUE(x, S_DMA_DSCRB_OPTIONS)
+#define G_DMA_DSCRB_OPTIONS(x) _SB_GETVALUE(x, S_DMA_DSCRB_OPTIONS, M_DMA_DSCRB_OPTIONS)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_DMA_DSCRB_A_SIZE _SB_MAKE64(8)
+#define M_DMA_DSCRB_A_SIZE _SB_MAKEMASK(14, S_DMA_DSCRB_A_SIZE)
+#define V_DMA_DSCRB_A_SIZE(x) _SB_MAKEVALUE(x, S_DMA_DSCRB_A_SIZE)
+#define G_DMA_DSCRB_A_SIZE(x) _SB_GETVALUE(x, S_DMA_DSCRB_A_SIZE, M_DMA_DSCRB_A_SIZE)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define R_DMA_DSCRB_ADDR _SB_MAKE64(0x10)
+
+/* Note: Don't shift the address over, just mask it with the mask below */
+#define S_DMA_DSCRB_B_ADDR _SB_MAKE64(5)
+#define M_DMA_DSCRB_B_ADDR _SB_MAKEMASK(35, S_DMA_DSCRB_B_ADDR)
+
+#define S_DMA_DSCRB_B_SIZE _SB_MAKE64(40)
+#define M_DMA_DSCRB_B_SIZE _SB_MAKEMASK(9, S_DMA_DSCRB_B_SIZE)
+#define V_DMA_DSCRB_B_SIZE(x) _SB_MAKEVALUE(x, S_DMA_DSCRB_B_SIZE)
+#define G_DMA_DSCRB_B_SIZE(x) _SB_GETVALUE(x, S_DMA_DSCRB_B_SIZE, M_DMA_DSCRB_B_SIZE)
+
+#define M_DMA_DSCRB_B_VALID _SB_MAKEMASK1(49)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKE64(48)
+#define M_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKEMASK(2, S_DMA_DSCRB_PKT_SIZE_MSB)
+#define V_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_MAKEVALUE(x, S_DMA_DSCRB_PKT_SIZE_MSB)
+#define G_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_GETVALUE(x, S_DMA_DSCRB_PKT_SIZE_MSB, M_DMA_DSCRB_PKT_SIZE_MSB)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define S_DMA_DSCRB_PKT_SIZE _SB_MAKE64(50)
+#define M_DMA_DSCRB_PKT_SIZE _SB_MAKEMASK(14, S_DMA_DSCRB_PKT_SIZE)
+#define V_DMA_DSCRB_PKT_SIZE(x) _SB_MAKEVALUE(x, S_DMA_DSCRB_PKT_SIZE)
+#define G_DMA_DSCRB_PKT_SIZE(x) _SB_GETVALUE(x, S_DMA_DSCRB_PKT_SIZE, M_DMA_DSCRB_PKT_SIZE)
+
+/*
+ * from pass2 some bits in dscr_b are also used for rx status
+ */
+#define S_DMA_DSCRB_STATUS _SB_MAKE64(0)
+#define M_DMA_DSCRB_STATUS _SB_MAKEMASK(1, S_DMA_DSCRB_STATUS)
+#define V_DMA_DSCRB_STATUS(x) _SB_MAKEVALUE(x, S_DMA_DSCRB_STATUS)
+#define G_DMA_DSCRB_STATUS(x) _SB_GETVALUE(x, S_DMA_DSCRB_STATUS, M_DMA_DSCRB_STATUS)
+
+/*
+ * Ethernet Descriptor Status Bits (Table 7-15)
+ */
+
+#define M_DMA_ETHRX_BADIP4CS _SB_MAKEMASK1(51)
+#define M_DMA_ETHRX_DSCRERR _SB_MAKEMASK1(52)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/* Note: This bit is in the DSCR_B options field */
+#define M_DMA_ETHRX_BADTCPCS _SB_MAKEMASK1(0)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/* Note: These bits are in the DSCR_B options field */
+#define M_DMA_ETH_VLAN_FLAG _SB_MAKEMASK1(1)
+#define M_DMA_ETH_CRC_FLAG _SB_MAKEMASK1(2)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define S_DMA_ETHRX_RXCH 53
+#define M_DMA_ETHRX_RXCH _SB_MAKEMASK(2, S_DMA_ETHRX_RXCH)
+#define V_DMA_ETHRX_RXCH(x) _SB_MAKEVALUE(x, S_DMA_ETHRX_RXCH)
+#define G_DMA_ETHRX_RXCH(x) _SB_GETVALUE(x, S_DMA_ETHRX_RXCH, M_DMA_ETHRX_RXCH)
+
+#define S_DMA_ETHRX_PKTTYPE 55
+#define M_DMA_ETHRX_PKTTYPE _SB_MAKEMASK(3, S_DMA_ETHRX_PKTTYPE)
+#define V_DMA_ETHRX_PKTTYPE(x) _SB_MAKEVALUE(x, S_DMA_ETHRX_PKTTYPE)
+#define G_DMA_ETHRX_PKTTYPE(x) _SB_GETVALUE(x, S_DMA_ETHRX_PKTTYPE, M_DMA_ETHRX_PKTTYPE)
+
+#define K_DMA_ETHRX_PKTTYPE_IPV4 0
+#define K_DMA_ETHRX_PKTTYPE_ARPV4 1
+#define K_DMA_ETHRX_PKTTYPE_802 2
+#define K_DMA_ETHRX_PKTTYPE_OTHER 3
+#define K_DMA_ETHRX_PKTTYPE_USER0 4
+#define K_DMA_ETHRX_PKTTYPE_USER1 5
+#define K_DMA_ETHRX_PKTTYPE_USER2 6
+#define K_DMA_ETHRX_PKTTYPE_USER3 7
+
+#define M_DMA_ETHRX_MATCH_HASH _SB_MAKEMASK1(58)
+#define M_DMA_ETHRX_MATCH_EXACT _SB_MAKEMASK1(59)
+#define M_DMA_ETHRX_BCAST _SB_MAKEMASK1(60)
+#define M_DMA_ETHRX_MCAST _SB_MAKEMASK1(61)
+#define M_DMA_ETHRX_BAD _SB_MAKEMASK1(62)
+#define M_DMA_ETHRX_SOP _SB_MAKEMASK1(63)
+
+/*
+ * Ethernet Transmit Status Bits (Table 7-16)
+ */
+
+#define M_DMA_ETHTX_SOP _SB_MAKEMASK1(63)
+
+/*
+ * Ethernet Transmit Options (Table 7-17)
+ */
+
+#define K_DMA_ETHTX_NOTSOP _SB_MAKE64(0x00)
+#define K_DMA_ETHTX_APPENDCRC _SB_MAKE64(0x01)
+#define K_DMA_ETHTX_REPLACECRC _SB_MAKE64(0x02)
+#define K_DMA_ETHTX_APPENDCRC_APPENDPAD _SB_MAKE64(0x03)
+#define K_DMA_ETHTX_APPENDVLAN_REPLACECRC _SB_MAKE64(0x04)
+#define K_DMA_ETHTX_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x05)
+#define K_DMA_ETHTX_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x6)
+#define K_DMA_ETHTX_NOMODS _SB_MAKE64(0x07)
+#define K_DMA_ETHTX_RESERVED1 _SB_MAKE64(0x08)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC _SB_MAKE64(0x09)
+#define K_DMA_ETHTX_REPLACESADDR_REPLACECRC _SB_MAKE64(0x0A)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC_APPENDPAD _SB_MAKE64(0x0B)
+#define K_DMA_ETHTX_REPLACESADDR_APPENDVLAN_REPLACECRC _SB_MAKE64(0x0C)
+#define K_DMA_ETHTX_REPLACESADDR_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x0D)
+#define K_DMA_ETHTX_REPLACESADDR_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x0E)
+#define K_DMA_ETHTX_RESERVED2 _SB_MAKE64(0x0F)
+
+/*
+ * Serial Receive Options (Table 7-18)
+ */
+#define M_DMA_SERRX_CRC_ERROR _SB_MAKEMASK1(56)
+#define M_DMA_SERRX_ABORT _SB_MAKEMASK1(57)
+#define M_DMA_SERRX_OCTET_ERROR _SB_MAKEMASK1(58)
+#define M_DMA_SERRX_LONGFRAME_ERROR _SB_MAKEMASK1(59)
+#define M_DMA_SERRX_SHORTFRAME_ERROR _SB_MAKEMASK1(60)
+#define M_DMA_SERRX_OVERRUN_ERROR _SB_MAKEMASK1(61)
+#define M_DMA_SERRX_GOOD _SB_MAKEMASK1(62)
+#define M_DMA_SERRX_SOP _SB_MAKEMASK1(63)
+
+/*
+ * Serial Transmit Status Bits (Table 7-20)
+ */
+
+#define M_DMA_SERTX_FLAG _SB_MAKEMASK1(63)
+
+/*
+ * Serial Transmit Options (Table 7-21)
+ */
+
+#define K_DMA_SERTX_RESERVED _SB_MAKEMASK1(0)
+#define K_DMA_SERTX_APPENDCRC _SB_MAKEMASK1(1)
+#define K_DMA_SERTX_APPENDPAD _SB_MAKEMASK1(2)
+#define K_DMA_SERTX_ABORT _SB_MAKEMASK1(3)
+
+
+/* *********************************************************************
+ * Data Mover Registers
+ ********************************************************************* */
+
+/*
+ * Data Mover Descriptor Base Address Register (Table 7-22)
+ * Register: DM_DSCR_BASE_0
+ * Register: DM_DSCR_BASE_1
+ * Register: DM_DSCR_BASE_2
+ * Register: DM_DSCR_BASE_3
+ */
+
+#define M_DM_DSCR_BASE_MBZ _SB_MAKEMASK(4, 0)
+
+/* Note: Just mask the base address and then OR it in. */
+#define S_DM_DSCR_BASE_ADDR _SB_MAKE64(4)
+#define M_DM_DSCR_BASE_ADDR _SB_MAKEMASK(36, S_DM_DSCR_BASE_ADDR)
+
+#define S_DM_DSCR_BASE_RINGSZ _SB_MAKE64(40)
+#define M_DM_DSCR_BASE_RINGSZ _SB_MAKEMASK(16, S_DM_DSCR_BASE_RINGSZ)
+#define V_DM_DSCR_BASE_RINGSZ(x) _SB_MAKEVALUE(x, S_DM_DSCR_BASE_RINGSZ)
+#define G_DM_DSCR_BASE_RINGSZ(x) _SB_GETVALUE(x, S_DM_DSCR_BASE_RINGSZ, M_DM_DSCR_BASE_RINGSZ)
+
+#define S_DM_DSCR_BASE_PRIORITY _SB_MAKE64(56)
+#define M_DM_DSCR_BASE_PRIORITY _SB_MAKEMASK(3, S_DM_DSCR_BASE_PRIORITY)
+#define V_DM_DSCR_BASE_PRIORITY(x) _SB_MAKEVALUE(x, S_DM_DSCR_BASE_PRIORITY)
+#define G_DM_DSCR_BASE_PRIORITY(x) _SB_GETVALUE(x, S_DM_DSCR_BASE_PRIORITY, M_DM_DSCR_BASE_PRIORITY)
+
+#define K_DM_DSCR_BASE_PRIORITY_1 0
+#define K_DM_DSCR_BASE_PRIORITY_2 1
+#define K_DM_DSCR_BASE_PRIORITY_4 2
+#define K_DM_DSCR_BASE_PRIORITY_8 3
+#define K_DM_DSCR_BASE_PRIORITY_16 4
+
+#define M_DM_DSCR_BASE_ACTIVE _SB_MAKEMASK1(59)
+#define M_DM_DSCR_BASE_INTERRUPT _SB_MAKEMASK1(60)
+#define M_DM_DSCR_BASE_RESET _SB_MAKEMASK1(61) /* write register */
+#define M_DM_DSCR_BASE_ERROR _SB_MAKEMASK1(61) /* read register */
+#define M_DM_DSCR_BASE_ABORT _SB_MAKEMASK1(62)
+#define M_DM_DSCR_BASE_ENABL _SB_MAKEMASK1(63)
+
+/*
+ * Data Mover Descriptor Count Register (Table 7-25)
+ */
+
+/* no bitfields */
+
+/*
+ * Data Mover Current Descriptor Address (Table 7-24)
+ * Register: DM_CUR_DSCR_ADDR_0
+ * Register: DM_CUR_DSCR_ADDR_1
+ * Register: DM_CUR_DSCR_ADDR_2
+ * Register: DM_CUR_DSCR_ADDR_3
+ */
+
+#define S_DM_CUR_DSCR_DSCR_ADDR _SB_MAKE64(0)
+#define M_DM_CUR_DSCR_DSCR_ADDR _SB_MAKEMASK(40, S_DM_CUR_DSCR_DSCR_ADDR)
+
+#define S_DM_CUR_DSCR_DSCR_COUNT _SB_MAKE64(48)
+#define M_DM_CUR_DSCR_DSCR_COUNT _SB_MAKEMASK(16, S_DM_CUR_DSCR_DSCR_COUNT)
+#define V_DM_CUR_DSCR_DSCR_COUNT(r) _SB_MAKEVALUE(r, S_DM_CUR_DSCR_DSCR_COUNT)
+#define G_DM_CUR_DSCR_DSCR_COUNT(r) _SB_GETVALUE(r, S_DM_CUR_DSCR_DSCR_COUNT,\
+ M_DM_CUR_DSCR_DSCR_COUNT)
+
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/*
+ * Data Mover Channel Partial Result Registers
+ * Register: DM_PARTIAL_0
+ * Register: DM_PARTIAL_1
+ * Register: DM_PARTIAL_2
+ * Register: DM_PARTIAL_3
+ */
+#define S_DM_PARTIAL_CRC_PARTIAL _SB_MAKE64(0)
+#define M_DM_PARTIAL_CRC_PARTIAL _SB_MAKEMASK(32, S_DM_PARTIAL_CRC_PARTIAL)
+#define V_DM_PARTIAL_CRC_PARTIAL(r) _SB_MAKEVALUE(r, S_DM_PARTIAL_CRC_PARTIAL)
+#define G_DM_PARTIAL_CRC_PARTIAL(r) _SB_GETVALUE(r, S_DM_PARTIAL_CRC_PARTIAL,\
+ M_DM_PARTIAL_CRC_PARTIAL)
+
+#define S_DM_PARTIAL_TCPCS_PARTIAL _SB_MAKE64(32)
+#define M_DM_PARTIAL_TCPCS_PARTIAL _SB_MAKEMASK(16, S_DM_PARTIAL_TCPCS_PARTIAL)
+#define V_DM_PARTIAL_TCPCS_PARTIAL(r) _SB_MAKEVALUE(r, S_DM_PARTIAL_TCPCS_PARTIAL)
+#define G_DM_PARTIAL_TCPCS_PARTIAL(r) _SB_GETVALUE(r, S_DM_PARTIAL_TCPCS_PARTIAL,\
+ M_DM_PARTIAL_TCPCS_PARTIAL)
+
+#define M_DM_PARTIAL_ODD_BYTE _SB_MAKEMASK1(48)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/*
+ * Data Mover CRC Definition Registers
+ * Register: CRC_DEF_0
+ * Register: CRC_DEF_1
+ */
+#define S_CRC_DEF_CRC_INIT _SB_MAKE64(0)
+#define M_CRC_DEF_CRC_INIT _SB_MAKEMASK(32, S_CRC_DEF_CRC_INIT)
+#define V_CRC_DEF_CRC_INIT(r) _SB_MAKEVALUE(r, S_CRC_DEF_CRC_INIT)
+#define G_CRC_DEF_CRC_INIT(r) _SB_GETVALUE(r, S_CRC_DEF_CRC_INIT,\
+ M_CRC_DEF_CRC_INIT)
+
+#define S_CRC_DEF_CRC_POLY _SB_MAKE64(32)
+#define M_CRC_DEF_CRC_POLY _SB_MAKEMASK(32, S_CRC_DEF_CRC_POLY)
+#define V_CRC_DEF_CRC_POLY(r) _SB_MAKEVALUE(r, S_CRC_DEF_CRC_POLY)
+#define G_CRC_DEF_CRC_POLY(r) _SB_GETVALUE(r, S_CRC_DEF_CRC_POLY,\
+ M_CRC_DEF_CRC_POLY)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/*
+ * Data Mover CRC/Checksum Definition Registers
+ * Register: CTCP_DEF_0
+ * Register: CTCP_DEF_1
+ */
+#define S_CTCP_DEF_CRC_TXOR _SB_MAKE64(0)
+#define M_CTCP_DEF_CRC_TXOR _SB_MAKEMASK(32, S_CTCP_DEF_CRC_TXOR)
+#define V_CTCP_DEF_CRC_TXOR(r) _SB_MAKEVALUE(r, S_CTCP_DEF_CRC_TXOR)
+#define G_CTCP_DEF_CRC_TXOR(r) _SB_GETVALUE(r, S_CTCP_DEF_CRC_TXOR,\
+ M_CTCP_DEF_CRC_TXOR)
+
+#define S_CTCP_DEF_TCPCS_INIT _SB_MAKE64(32)
+#define M_CTCP_DEF_TCPCS_INIT _SB_MAKEMASK(16, S_CTCP_DEF_TCPCS_INIT)
+#define V_CTCP_DEF_TCPCS_INIT(r) _SB_MAKEVALUE(r, S_CTCP_DEF_TCPCS_INIT)
+#define G_CTCP_DEF_TCPCS_INIT(r) _SB_GETVALUE(r, S_CTCP_DEF_TCPCS_INIT,\
+ M_CTCP_DEF_TCPCS_INIT)
+
+#define S_CTCP_DEF_CRC_WIDTH _SB_MAKE64(48)
+#define M_CTCP_DEF_CRC_WIDTH _SB_MAKEMASK(2, S_CTCP_DEF_CRC_WIDTH)
+#define V_CTCP_DEF_CRC_WIDTH(r) _SB_MAKEVALUE(r, S_CTCP_DEF_CRC_WIDTH)
+#define G_CTCP_DEF_CRC_WIDTH(r) _SB_GETVALUE(r, S_CTCP_DEF_CRC_WIDTH,\
+ M_CTCP_DEF_CRC_WIDTH)
+
+#define K_CTCP_DEF_CRC_WIDTH_4 0
+#define K_CTCP_DEF_CRC_WIDTH_2 1
+#define K_CTCP_DEF_CRC_WIDTH_1 2
+
+#define M_CTCP_DEF_CRC_BIT_ORDER _SB_MAKEMASK1(50)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+
+/*
+ * Data Mover Descriptor Doubleword "A" (Table 7-26)
+ */
+
+#define S_DM_DSCRA_DST_ADDR _SB_MAKE64(0)
+#define M_DM_DSCRA_DST_ADDR _SB_MAKEMASK(40, S_DM_DSCRA_DST_ADDR)
+
+#define M_DM_DSCRA_UN_DEST _SB_MAKEMASK1(40)
+#define M_DM_DSCRA_UN_SRC _SB_MAKEMASK1(41)
+#define M_DM_DSCRA_INTERRUPT _SB_MAKEMASK1(42)
+#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1)
+#define M_DM_DSCRA_THROTTLE _SB_MAKEMASK1(43)
+#endif /* up to 1250 PASS1 */
+
+#define S_DM_DSCRA_DIR_DEST _SB_MAKE64(44)
+#define M_DM_DSCRA_DIR_DEST _SB_MAKEMASK(2, S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST(x) _SB_MAKEVALUE(x, S_DM_DSCRA_DIR_DEST)
+#define G_DM_DSCRA_DIR_DEST(x) _SB_GETVALUE(x, S_DM_DSCRA_DIR_DEST, M_DM_DSCRA_DIR_DEST)
+
+#define K_DM_DSCRA_DIR_DEST_INCR 0
+#define K_DM_DSCRA_DIR_DEST_DECR 1
+#define K_DM_DSCRA_DIR_DEST_CONST 2
+
+#define V_DM_DSCRA_DIR_DEST_INCR _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_INCR, S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST_DECR _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_DECR, S_DM_DSCRA_DIR_DEST)
+#define V_DM_DSCRA_DIR_DEST_CONST _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_CONST, S_DM_DSCRA_DIR_DEST)
+
+#define S_DM_DSCRA_DIR_SRC _SB_MAKE64(46)
+#define M_DM_DSCRA_DIR_SRC _SB_MAKEMASK(2, S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC(x) _SB_MAKEVALUE(x, S_DM_DSCRA_DIR_SRC)
+#define G_DM_DSCRA_DIR_SRC(x) _SB_GETVALUE(x, S_DM_DSCRA_DIR_SRC, M_DM_DSCRA_DIR_SRC)
+
+#define K_DM_DSCRA_DIR_SRC_INCR 0
+#define K_DM_DSCRA_DIR_SRC_DECR 1
+#define K_DM_DSCRA_DIR_SRC_CONST 2
+
+#define V_DM_DSCRA_DIR_SRC_INCR _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_INCR, S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC_DECR _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_DECR, S_DM_DSCRA_DIR_SRC)
+#define V_DM_DSCRA_DIR_SRC_CONST _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_CONST, S_DM_DSCRA_DIR_SRC)
+
+
+#define M_DM_DSCRA_ZERO_MEM _SB_MAKEMASK1(48)
+#define M_DM_DSCRA_PREFETCH _SB_MAKEMASK1(49)
+#define M_DM_DSCRA_L2C_DEST _SB_MAKEMASK1(50)
+#define M_DM_DSCRA_L2C_SRC _SB_MAKEMASK1(51)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_DM_DSCRA_RD_BKOFF _SB_MAKEMASK1(52)
+#define M_DM_DSCRA_WR_BKOFF _SB_MAKEMASK1(53)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_DM_DSCRA_TCPCS_EN _SB_MAKEMASK1(54)
+#define M_DM_DSCRA_TCPCS_RES _SB_MAKEMASK1(55)
+#define M_DM_DSCRA_TCPCS_AP _SB_MAKEMASK1(56)
+#define M_DM_DSCRA_CRC_EN _SB_MAKEMASK1(57)
+#define M_DM_DSCRA_CRC_RES _SB_MAKEMASK1(58)
+#define M_DM_DSCRA_CRC_AP _SB_MAKEMASK1(59)
+#define M_DM_DSCRA_CRC_DFN _SB_MAKEMASK1(60)
+#define M_DM_DSCRA_CRC_XBIT _SB_MAKEMASK1(61)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define M_DM_DSCRA_RESERVED2 _SB_MAKEMASK(3, 61)
+
+/*
+ * Data Mover Descriptor Doubleword "B" (Table 7-25)
+ */
+
+#define S_DM_DSCRB_SRC_ADDR _SB_MAKE64(0)
+#define M_DM_DSCRB_SRC_ADDR _SB_MAKEMASK(40, S_DM_DSCRB_SRC_ADDR)
+
+#define S_DM_DSCRB_SRC_LENGTH _SB_MAKE64(40)
+#define M_DM_DSCRB_SRC_LENGTH _SB_MAKEMASK(20, S_DM_DSCRB_SRC_LENGTH)
+#define V_DM_DSCRB_SRC_LENGTH(x) _SB_MAKEVALUE(x, S_DM_DSCRB_SRC_LENGTH)
+#define G_DM_DSCRB_SRC_LENGTH(x) _SB_GETVALUE(x, S_DM_DSCRB_SRC_LENGTH, M_DM_DSCRB_SRC_LENGTH)
+
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_genbus.h b/arch/mips/include/asm/sibyte/sb1250_genbus.h
new file mode 100644
index 00000000..94e9c7c8
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_genbus.h
@@ -0,0 +1,474 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Generic Bus Constants File: sb1250_genbus.h
+ *
+ * This module contains constants and macros useful for
+ * manipulating the SB1250's Generic Bus interface
+ *
+ * SB1250 specification level: User's manual 10/21/02
+ * BCM1280 specification level: User's Manual 11/14/03
+ *
+ *********************************************************************
+ *
+ * Copyright 2000, 2001, 2002, 2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_GENBUS_H
+#define _SB1250_GENBUS_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Generic Bus Region Configuration Registers (Table 11-4)
+ */
+
+#define S_IO_RDY_ACTIVE 0
+#define M_IO_RDY_ACTIVE _SB_MAKEMASK1(S_IO_RDY_ACTIVE)
+
+#define S_IO_ENA_RDY 1
+#define M_IO_ENA_RDY _SB_MAKEMASK1(S_IO_ENA_RDY)
+
+#define S_IO_WIDTH_SEL 2
+#define M_IO_WIDTH_SEL _SB_MAKEMASK(2, S_IO_WIDTH_SEL)
+#define K_IO_WIDTH_SEL_1 0
+#define K_IO_WIDTH_SEL_2 1
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define K_IO_WIDTH_SEL_1L 2
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+#define K_IO_WIDTH_SEL_4 3
+#define V_IO_WIDTH_SEL(x) _SB_MAKEVALUE(x, S_IO_WIDTH_SEL)
+#define G_IO_WIDTH_SEL(x) _SB_GETVALUE(x, S_IO_WIDTH_SEL, M_IO_WIDTH_SEL)
+
+#define S_IO_PARITY_ENA 4
+#define M_IO_PARITY_ENA _SB_MAKEMASK1(S_IO_PARITY_ENA)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_IO_BURST_EN 5
+#define M_IO_BURST_EN _SB_MAKEMASK1(S_IO_BURST_EN)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+#define S_IO_PARITY_ODD 6
+#define M_IO_PARITY_ODD _SB_MAKEMASK1(S_IO_PARITY_ODD)
+#define S_IO_NONMUX 7
+#define M_IO_NONMUX _SB_MAKEMASK1(S_IO_NONMUX)
+
+#define S_IO_TIMEOUT 8
+#define M_IO_TIMEOUT _SB_MAKEMASK(8, S_IO_TIMEOUT)
+#define V_IO_TIMEOUT(x) _SB_MAKEVALUE(x, S_IO_TIMEOUT)
+#define G_IO_TIMEOUT(x) _SB_GETVALUE(x, S_IO_TIMEOUT, M_IO_TIMEOUT)
+
+/*
+ * Generic Bus Region Size register (Table 11-5)
+ */
+
+#define S_IO_MULT_SIZE 0
+#define M_IO_MULT_SIZE _SB_MAKEMASK(12, S_IO_MULT_SIZE)
+#define V_IO_MULT_SIZE(x) _SB_MAKEVALUE(x, S_IO_MULT_SIZE)
+#define G_IO_MULT_SIZE(x) _SB_GETVALUE(x, S_IO_MULT_SIZE, M_IO_MULT_SIZE)
+
+#define S_IO_REGSIZE 16 /* # bits to shift size for this reg */
+
+/*
+ * Generic Bus Region Address (Table 11-6)
+ */
+
+#define S_IO_START_ADDR 0
+#define M_IO_START_ADDR _SB_MAKEMASK(14, S_IO_START_ADDR)
+#define V_IO_START_ADDR(x) _SB_MAKEVALUE(x, S_IO_START_ADDR)
+#define G_IO_START_ADDR(x) _SB_GETVALUE(x, S_IO_START_ADDR, M_IO_START_ADDR)
+
+#define S_IO_ADDRBASE 16 /* # bits to shift addr for this reg */
+
+#define M_IO_BLK_CACHE _SB_MAKEMASK1(15)
+
+
+/*
+ * Generic Bus Timing 0 Registers (Table 11-7)
+ */
+
+#define S_IO_ALE_WIDTH 0
+#define M_IO_ALE_WIDTH _SB_MAKEMASK(3, S_IO_ALE_WIDTH)
+#define V_IO_ALE_WIDTH(x) _SB_MAKEVALUE(x, S_IO_ALE_WIDTH)
+#define G_IO_ALE_WIDTH(x) _SB_GETVALUE(x, S_IO_ALE_WIDTH, M_IO_ALE_WIDTH)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_IO_EARLY_CS _SB_MAKEMASK1(3)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#define S_IO_ALE_TO_CS 4
+#define M_IO_ALE_TO_CS _SB_MAKEMASK(2, S_IO_ALE_TO_CS)
+#define V_IO_ALE_TO_CS(x) _SB_MAKEVALUE(x, S_IO_ALE_TO_CS)
+#define G_IO_ALE_TO_CS(x) _SB_GETVALUE(x, S_IO_ALE_TO_CS, M_IO_ALE_TO_CS)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_IO_BURST_WIDTH _SB_MAKE64(6)
+#define M_IO_BURST_WIDTH _SB_MAKEMASK(2, S_IO_BURST_WIDTH)
+#define V_IO_BURST_WIDTH(x) _SB_MAKEVALUE(x, S_IO_BURST_WIDTH)
+#define G_IO_BURST_WIDTH(x) _SB_GETVALUE(x, S_IO_BURST_WIDTH, M_IO_BURST_WIDTH)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#define S_IO_CS_WIDTH 8
+#define M_IO_CS_WIDTH _SB_MAKEMASK(5, S_IO_CS_WIDTH)
+#define V_IO_CS_WIDTH(x) _SB_MAKEVALUE(x, S_IO_CS_WIDTH)
+#define G_IO_CS_WIDTH(x) _SB_GETVALUE(x, S_IO_CS_WIDTH, M_IO_CS_WIDTH)
+
+#define S_IO_RDY_SMPLE 13
+#define M_IO_RDY_SMPLE _SB_MAKEMASK(3, S_IO_RDY_SMPLE)
+#define V_IO_RDY_SMPLE(x) _SB_MAKEVALUE(x, S_IO_RDY_SMPLE)
+#define G_IO_RDY_SMPLE(x) _SB_GETVALUE(x, S_IO_RDY_SMPLE, M_IO_RDY_SMPLE)
+
+
+/*
+ * Generic Bus Timing 1 Registers (Table 11-8)
+ */
+
+#define S_IO_ALE_TO_WRITE 0
+#define M_IO_ALE_TO_WRITE _SB_MAKEMASK(3, S_IO_ALE_TO_WRITE)
+#define V_IO_ALE_TO_WRITE(x) _SB_MAKEVALUE(x, S_IO_ALE_TO_WRITE)
+#define G_IO_ALE_TO_WRITE(x) _SB_GETVALUE(x, S_IO_ALE_TO_WRITE, M_IO_ALE_TO_WRITE)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) \
+ || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_IO_RDY_SYNC _SB_MAKEMASK1(3)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#define S_IO_WRITE_WIDTH 4
+#define M_IO_WRITE_WIDTH _SB_MAKEMASK(4, S_IO_WRITE_WIDTH)
+#define V_IO_WRITE_WIDTH(x) _SB_MAKEVALUE(x, S_IO_WRITE_WIDTH)
+#define G_IO_WRITE_WIDTH(x) _SB_GETVALUE(x, S_IO_WRITE_WIDTH, M_IO_WRITE_WIDTH)
+
+#define S_IO_IDLE_CYCLE 8
+#define M_IO_IDLE_CYCLE _SB_MAKEMASK(4, S_IO_IDLE_CYCLE)
+#define V_IO_IDLE_CYCLE(x) _SB_MAKEVALUE(x, S_IO_IDLE_CYCLE)
+#define G_IO_IDLE_CYCLE(x) _SB_GETVALUE(x, S_IO_IDLE_CYCLE, M_IO_IDLE_CYCLE)
+
+#define S_IO_OE_TO_CS 12
+#define M_IO_OE_TO_CS _SB_MAKEMASK(2, S_IO_OE_TO_CS)
+#define V_IO_OE_TO_CS(x) _SB_MAKEVALUE(x, S_IO_OE_TO_CS)
+#define G_IO_OE_TO_CS(x) _SB_GETVALUE(x, S_IO_OE_TO_CS, M_IO_OE_TO_CS)
+
+#define S_IO_CS_TO_OE 14
+#define M_IO_CS_TO_OE _SB_MAKEMASK(2, S_IO_CS_TO_OE)
+#define V_IO_CS_TO_OE(x) _SB_MAKEVALUE(x, S_IO_CS_TO_OE)
+#define G_IO_CS_TO_OE(x) _SB_GETVALUE(x, S_IO_CS_TO_OE, M_IO_CS_TO_OE)
+
+/*
+ * Generic Bus Interrupt Status Register (Table 11-9)
+ */
+
+#define M_IO_CS_ERR_INT _SB_MAKEMASK(0, 8)
+#define M_IO_CS0_ERR_INT _SB_MAKEMASK1(0)
+#define M_IO_CS1_ERR_INT _SB_MAKEMASK1(1)
+#define M_IO_CS2_ERR_INT _SB_MAKEMASK1(2)
+#define M_IO_CS3_ERR_INT _SB_MAKEMASK1(3)
+#define M_IO_CS4_ERR_INT _SB_MAKEMASK1(4)
+#define M_IO_CS5_ERR_INT _SB_MAKEMASK1(5)
+#define M_IO_CS6_ERR_INT _SB_MAKEMASK1(6)
+#define M_IO_CS7_ERR_INT _SB_MAKEMASK1(7)
+
+#define M_IO_RD_PAR_INT _SB_MAKEMASK1(9)
+#define M_IO_TIMEOUT_INT _SB_MAKEMASK1(10)
+#define M_IO_ILL_ADDR_INT _SB_MAKEMASK1(11)
+#define M_IO_MULT_CS_INT _SB_MAKEMASK1(12)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_IO_COH_ERR _SB_MAKEMASK1(14)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+
+/*
+ * Generic Bus Output Drive Control Register 0 (Table 14-18)
+ */
+
+#define S_IO_SLEW0 0
+#define M_IO_SLEW0 _SB_MAKEMASK(2, S_IO_SLEW0)
+#define V_IO_SLEW0(x) _SB_MAKEVALUE(x, S_IO_SLEW0)
+#define G_IO_SLEW0(x) _SB_GETVALUE(x, S_IO_SLEW0, M_IO_SLEW0)
+
+#define S_IO_DRV_A 2
+#define M_IO_DRV_A _SB_MAKEMASK(2, S_IO_DRV_A)
+#define V_IO_DRV_A(x) _SB_MAKEVALUE(x, S_IO_DRV_A)
+#define G_IO_DRV_A(x) _SB_GETVALUE(x, S_IO_DRV_A, M_IO_DRV_A)
+
+#define S_IO_DRV_B 6
+#define M_IO_DRV_B _SB_MAKEMASK(2, S_IO_DRV_B)
+#define V_IO_DRV_B(x) _SB_MAKEVALUE(x, S_IO_DRV_B)
+#define G_IO_DRV_B(x) _SB_GETVALUE(x, S_IO_DRV_B, M_IO_DRV_B)
+
+#define S_IO_DRV_C 10
+#define M_IO_DRV_C _SB_MAKEMASK(2, S_IO_DRV_C)
+#define V_IO_DRV_C(x) _SB_MAKEVALUE(x, S_IO_DRV_C)
+#define G_IO_DRV_C(x) _SB_GETVALUE(x, S_IO_DRV_C, M_IO_DRV_C)
+
+#define S_IO_DRV_D 14
+#define M_IO_DRV_D _SB_MAKEMASK(2, S_IO_DRV_D)
+#define V_IO_DRV_D(x) _SB_MAKEVALUE(x, S_IO_DRV_D)
+#define G_IO_DRV_D(x) _SB_GETVALUE(x, S_IO_DRV_D, M_IO_DRV_D)
+
+/*
+ * Generic Bus Output Drive Control Register 1 (Table 14-19)
+ */
+
+#define S_IO_DRV_E 2
+#define M_IO_DRV_E _SB_MAKEMASK(2, S_IO_DRV_E)
+#define V_IO_DRV_E(x) _SB_MAKEVALUE(x, S_IO_DRV_E)
+#define G_IO_DRV_E(x) _SB_GETVALUE(x, S_IO_DRV_E, M_IO_DRV_E)
+
+#define S_IO_DRV_F 6
+#define M_IO_DRV_F _SB_MAKEMASK(2, S_IO_DRV_F)
+#define V_IO_DRV_F(x) _SB_MAKEVALUE(x, S_IO_DRV_F)
+#define G_IO_DRV_F(x) _SB_GETVALUE(x, S_IO_DRV_F, M_IO_DRV_F)
+
+#define S_IO_SLEW1 8
+#define M_IO_SLEW1 _SB_MAKEMASK(2, S_IO_SLEW1)
+#define V_IO_SLEW1(x) _SB_MAKEVALUE(x, S_IO_SLEW1)
+#define G_IO_SLEW1(x) _SB_GETVALUE(x, S_IO_SLEW1, M_IO_SLEW1)
+
+#define S_IO_DRV_G 10
+#define M_IO_DRV_G _SB_MAKEMASK(2, S_IO_DRV_G)
+#define V_IO_DRV_G(x) _SB_MAKEVALUE(x, S_IO_DRV_G)
+#define G_IO_DRV_G(x) _SB_GETVALUE(x, S_IO_DRV_G, M_IO_DRV_G)
+
+#define S_IO_SLEW2 12
+#define M_IO_SLEW2 _SB_MAKEMASK(2, S_IO_SLEW2)
+#define V_IO_SLEW2(x) _SB_MAKEVALUE(x, S_IO_SLEW2)
+#define G_IO_SLEW2(x) _SB_GETVALUE(x, S_IO_SLEW2, M_IO_SLEW2)
+
+#define S_IO_DRV_H 14
+#define M_IO_DRV_H _SB_MAKEMASK(2, S_IO_DRV_H)
+#define V_IO_DRV_H(x) _SB_MAKEVALUE(x, S_IO_DRV_H)
+#define G_IO_DRV_H(x) _SB_GETVALUE(x, S_IO_DRV_H, M_IO_DRV_H)
+
+/*
+ * Generic Bus Output Drive Control Register 2 (Table 14-20)
+ */
+
+#define S_IO_DRV_J 2
+#define M_IO_DRV_J _SB_MAKEMASK(2, S_IO_DRV_J)
+#define V_IO_DRV_J(x) _SB_MAKEVALUE(x, S_IO_DRV_J)
+#define G_IO_DRV_J(x) _SB_GETVALUE(x, S_IO_DRV_J, M_IO_DRV_J)
+
+#define S_IO_DRV_K 6
+#define M_IO_DRV_K _SB_MAKEMASK(2, S_IO_DRV_K)
+#define V_IO_DRV_K(x) _SB_MAKEVALUE(x, S_IO_DRV_K)
+#define G_IO_DRV_K(x) _SB_GETVALUE(x, S_IO_DRV_K, M_IO_DRV_K)
+
+#define S_IO_DRV_L 10
+#define M_IO_DRV_L _SB_MAKEMASK(2, S_IO_DRV_L)
+#define V_IO_DRV_L(x) _SB_MAKEVALUE(x, S_IO_DRV_L)
+#define G_IO_DRV_L(x) _SB_GETVALUE(x, S_IO_DRV_L, M_IO_DRV_L)
+
+#define S_IO_DRV_M 14
+#define M_IO_DRV_M _SB_MAKEMASK(2, S_IO_DRV_M)
+#define V_IO_DRV_M(x) _SB_MAKEVALUE(x, S_IO_DRV_M)
+#define G_IO_DRV_M(x) _SB_GETVALUE(x, S_IO_DRV_M, M_IO_DRV_M)
+
+/*
+ * Generic Bus Output Drive Control Register 3 (Table 14-21)
+ */
+
+#define S_IO_SLEW3 0
+#define M_IO_SLEW3 _SB_MAKEMASK(2, S_IO_SLEW3)
+#define V_IO_SLEW3(x) _SB_MAKEVALUE(x, S_IO_SLEW3)
+#define G_IO_SLEW3(x) _SB_GETVALUE(x, S_IO_SLEW3, M_IO_SLEW3)
+
+#define S_IO_DRV_N 2
+#define M_IO_DRV_N _SB_MAKEMASK(2, S_IO_DRV_N)
+#define V_IO_DRV_N(x) _SB_MAKEVALUE(x, S_IO_DRV_N)
+#define G_IO_DRV_N(x) _SB_GETVALUE(x, S_IO_DRV_N, M_IO_DRV_N)
+
+#define S_IO_DRV_P 6
+#define M_IO_DRV_P _SB_MAKEMASK(2, S_IO_DRV_P)
+#define V_IO_DRV_P(x) _SB_MAKEVALUE(x, S_IO_DRV_P)
+#define G_IO_DRV_P(x) _SB_GETVALUE(x, S_IO_DRV_P, M_IO_DRV_P)
+
+#define S_IO_DRV_Q 10
+#define M_IO_DRV_Q _SB_MAKEMASK(2, S_IO_DRV_Q)
+#define V_IO_DRV_Q(x) _SB_MAKEVALUE(x, S_IO_DRV_Q)
+#define G_IO_DRV_Q(x) _SB_GETVALUE(x, S_IO_DRV_Q, M_IO_DRV_Q)
+
+#define S_IO_DRV_R 14
+#define M_IO_DRV_R _SB_MAKEMASK(2, S_IO_DRV_R)
+#define V_IO_DRV_R(x) _SB_MAKEVALUE(x, S_IO_DRV_R)
+#define G_IO_DRV_R(x) _SB_GETVALUE(x, S_IO_DRV_R, M_IO_DRV_R)
+
+
+/*
+ * PCMCIA configuration register (Table 12-6)
+ */
+
+#define M_PCMCIA_CFG_ATTRMEM _SB_MAKEMASK1(0)
+#define M_PCMCIA_CFG_3VEN _SB_MAKEMASK1(1)
+#define M_PCMCIA_CFG_5VEN _SB_MAKEMASK1(2)
+#define M_PCMCIA_CFG_VPPEN _SB_MAKEMASK1(3)
+#define M_PCMCIA_CFG_RESET _SB_MAKEMASK1(4)
+#define M_PCMCIA_CFG_APWRONEN _SB_MAKEMASK1(5)
+#define M_PCMCIA_CFG_CDMASK _SB_MAKEMASK1(6)
+#define M_PCMCIA_CFG_WPMASK _SB_MAKEMASK1(7)
+#define M_PCMCIA_CFG_RDYMASK _SB_MAKEMASK1(8)
+#define M_PCMCIA_CFG_PWRCTL _SB_MAKEMASK1(9)
+
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_PCMCIA_MODE 16
+#define M_PCMCIA_MODE _SB_MAKEMASK(3, S_PCMCIA_MODE)
+#define V_PCMCIA_MODE(x) _SB_MAKEVALUE(x, S_PCMCIA_MODE)
+#define G_PCMCIA_MODE(x) _SB_GETVALUE(x, S_PCMCIA_MODE, M_PCMCIA_MODE)
+
+#define K_PCMCIA_MODE_PCMA_NOB 0 /* standard PCMCIA "A", no "B" */
+#define K_PCMCIA_MODE_IDEA_NOB 1 /* IDE "A", no "B" */
+#define K_PCMCIA_MODE_PCMIOA_NOB 2 /* PCMCIA with I/O "A", no "B" */
+#define K_PCMCIA_MODE_PCMA_PCMB 4 /* standard PCMCIA "A", standard PCMCIA "B" */
+#define K_PCMCIA_MODE_IDEA_PCMB 5 /* IDE "A", standard PCMCIA "B" */
+#define K_PCMCIA_MODE_PCMA_IDEB 6 /* standard PCMCIA "A", IDE "B" */
+#define K_PCMCIA_MODE_IDEA_IDEB 7 /* IDE "A", IDE "B" */
+#endif
+
+
+/*
+ * PCMCIA status register (Table 12-7)
+ */
+
+#define M_PCMCIA_STATUS_CD1 _SB_MAKEMASK1(0)
+#define M_PCMCIA_STATUS_CD2 _SB_MAKEMASK1(1)
+#define M_PCMCIA_STATUS_VS1 _SB_MAKEMASK1(2)
+#define M_PCMCIA_STATUS_VS2 _SB_MAKEMASK1(3)
+#define M_PCMCIA_STATUS_WP _SB_MAKEMASK1(4)
+#define M_PCMCIA_STATUS_RDY _SB_MAKEMASK1(5)
+#define M_PCMCIA_STATUS_3VEN _SB_MAKEMASK1(6)
+#define M_PCMCIA_STATUS_5VEN _SB_MAKEMASK1(7)
+#define M_PCMCIA_STATUS_CDCHG _SB_MAKEMASK1(8)
+#define M_PCMCIA_STATUS_WPCHG _SB_MAKEMASK1(9)
+#define M_PCMCIA_STATUS_RDYCHG _SB_MAKEMASK1(10)
+
+/*
+ * GPIO Interrupt Type Register (table 13-3)
+ */
+
+#define K_GPIO_INTR_DISABLE 0
+#define K_GPIO_INTR_EDGE 1
+#define K_GPIO_INTR_LEVEL 2
+#define K_GPIO_INTR_SPLIT 3
+
+#define S_GPIO_INTR_TYPEX(n) (((n)/2)*2)
+#define M_GPIO_INTR_TYPEX(n) _SB_MAKEMASK(2, S_GPIO_INTR_TYPEX(n))
+#define V_GPIO_INTR_TYPEX(n, x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPEX(n))
+#define G_GPIO_INTR_TYPEX(n, x) _SB_GETVALUE(x, S_GPIO_INTR_TYPEX(n), M_GPIO_INTR_TYPEX(n))
+
+#define S_GPIO_INTR_TYPE0 0
+#define M_GPIO_INTR_TYPE0 _SB_MAKEMASK(2, S_GPIO_INTR_TYPE0)
+#define V_GPIO_INTR_TYPE0(x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPE0)
+#define G_GPIO_INTR_TYPE0(x) _SB_GETVALUE(x, S_GPIO_INTR_TYPE0, M_GPIO_INTR_TYPE0)
+
+#define S_GPIO_INTR_TYPE2 2
+#define M_GPIO_INTR_TYPE2 _SB_MAKEMASK(2, S_GPIO_INTR_TYPE2)
+#define V_GPIO_INTR_TYPE2(x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPE2)
+#define G_GPIO_INTR_TYPE2(x) _SB_GETVALUE(x, S_GPIO_INTR_TYPE2, M_GPIO_INTR_TYPE2)
+
+#define S_GPIO_INTR_TYPE4 4
+#define M_GPIO_INTR_TYPE4 _SB_MAKEMASK(2, S_GPIO_INTR_TYPE4)
+#define V_GPIO_INTR_TYPE4(x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPE4)
+#define G_GPIO_INTR_TYPE4(x) _SB_GETVALUE(x, S_GPIO_INTR_TYPE4, M_GPIO_INTR_TYPE4)
+
+#define S_GPIO_INTR_TYPE6 6
+#define M_GPIO_INTR_TYPE6 _SB_MAKEMASK(2, S_GPIO_INTR_TYPE6)
+#define V_GPIO_INTR_TYPE6(x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPE6)
+#define G_GPIO_INTR_TYPE6(x) _SB_GETVALUE(x, S_GPIO_INTR_TYPE6, M_GPIO_INTR_TYPE6)
+
+#define S_GPIO_INTR_TYPE8 8
+#define M_GPIO_INTR_TYPE8 _SB_MAKEMASK(2, S_GPIO_INTR_TYPE8)
+#define V_GPIO_INTR_TYPE8(x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPE8)
+#define G_GPIO_INTR_TYPE8(x) _SB_GETVALUE(x, S_GPIO_INTR_TYPE8, M_GPIO_INTR_TYPE8)
+
+#define S_GPIO_INTR_TYPE10 10
+#define M_GPIO_INTR_TYPE10 _SB_MAKEMASK(2, S_GPIO_INTR_TYPE10)
+#define V_GPIO_INTR_TYPE10(x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPE10)
+#define G_GPIO_INTR_TYPE10(x) _SB_GETVALUE(x, S_GPIO_INTR_TYPE10, M_GPIO_INTR_TYPE10)
+
+#define S_GPIO_INTR_TYPE12 12
+#define M_GPIO_INTR_TYPE12 _SB_MAKEMASK(2, S_GPIO_INTR_TYPE12)
+#define V_GPIO_INTR_TYPE12(x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPE12)
+#define G_GPIO_INTR_TYPE12(x) _SB_GETVALUE(x, S_GPIO_INTR_TYPE12, M_GPIO_INTR_TYPE12)
+
+#define S_GPIO_INTR_TYPE14 14
+#define M_GPIO_INTR_TYPE14 _SB_MAKEMASK(2, S_GPIO_INTR_TYPE14)
+#define V_GPIO_INTR_TYPE14(x) _SB_MAKEVALUE(x, S_GPIO_INTR_TYPE14)
+#define G_GPIO_INTR_TYPE14(x) _SB_GETVALUE(x, S_GPIO_INTR_TYPE14, M_GPIO_INTR_TYPE14)
+
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+
+/*
+ * GPIO Interrupt Additional Type Register
+ */
+
+#define K_GPIO_INTR_BOTHEDGE 0
+#define K_GPIO_INTR_RISEEDGE 1
+#define K_GPIO_INTR_UNPRED1 2
+#define K_GPIO_INTR_UNPRED2 3
+
+#define S_GPIO_INTR_ATYPEX(n) (((n)/2)*2)
+#define M_GPIO_INTR_ATYPEX(n) _SB_MAKEMASK(2, S_GPIO_INTR_ATYPEX(n))
+#define V_GPIO_INTR_ATYPEX(n, x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPEX(n))
+#define G_GPIO_INTR_ATYPEX(n, x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPEX(n), M_GPIO_INTR_ATYPEX(n))
+
+#define S_GPIO_INTR_ATYPE0 0
+#define M_GPIO_INTR_ATYPE0 _SB_MAKEMASK(2, S_GPIO_INTR_ATYPE0)
+#define V_GPIO_INTR_ATYPE0(x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPE0)
+#define G_GPIO_INTR_ATYPE0(x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPE0, M_GPIO_INTR_ATYPE0)
+
+#define S_GPIO_INTR_ATYPE2 2
+#define M_GPIO_INTR_ATYPE2 _SB_MAKEMASK(2, S_GPIO_INTR_ATYPE2)
+#define V_GPIO_INTR_ATYPE2(x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPE2)
+#define G_GPIO_INTR_ATYPE2(x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPE2, M_GPIO_INTR_ATYPE2)
+
+#define S_GPIO_INTR_ATYPE4 4
+#define M_GPIO_INTR_ATYPE4 _SB_MAKEMASK(2, S_GPIO_INTR_ATYPE4)
+#define V_GPIO_INTR_ATYPE4(x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPE4)
+#define G_GPIO_INTR_ATYPE4(x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPE4, M_GPIO_INTR_ATYPE4)
+
+#define S_GPIO_INTR_ATYPE6 6
+#define M_GPIO_INTR_ATYPE6 _SB_MAKEMASK(2, S_GPIO_INTR_ATYPE6)
+#define V_GPIO_INTR_ATYPE6(x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPE6)
+#define G_GPIO_INTR_ATYPE6(x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPE6, M_GPIO_INTR_ATYPE6)
+
+#define S_GPIO_INTR_ATYPE8 8
+#define M_GPIO_INTR_ATYPE8 _SB_MAKEMASK(2, S_GPIO_INTR_ATYPE8)
+#define V_GPIO_INTR_ATYPE8(x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPE8)
+#define G_GPIO_INTR_ATYPE8(x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPE8, M_GPIO_INTR_ATYPE8)
+
+#define S_GPIO_INTR_ATYPE10 10
+#define M_GPIO_INTR_ATYPE10 _SB_MAKEMASK(2, S_GPIO_INTR_ATYPE10)
+#define V_GPIO_INTR_ATYPE10(x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPE10)
+#define G_GPIO_INTR_ATYPE10(x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPE10, M_GPIO_INTR_ATYPE10)
+
+#define S_GPIO_INTR_ATYPE12 12
+#define M_GPIO_INTR_ATYPE12 _SB_MAKEMASK(2, S_GPIO_INTR_ATYPE12)
+#define V_GPIO_INTR_ATYPE12(x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPE12)
+#define G_GPIO_INTR_ATYPE12(x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPE12, M_GPIO_INTR_ATYPE12)
+
+#define S_GPIO_INTR_ATYPE14 14
+#define M_GPIO_INTR_ATYPE14 _SB_MAKEMASK(2, S_GPIO_INTR_ATYPE14)
+#define V_GPIO_INTR_ATYPE14(x) _SB_MAKEVALUE(x, S_GPIO_INTR_ATYPE14)
+#define G_GPIO_INTR_ATYPE14(x) _SB_GETVALUE(x, S_GPIO_INTR_ATYPE14, M_GPIO_INTR_ATYPE14)
+#endif
+
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_int.h b/arch/mips/include/asm/sibyte/sb1250_int.h
new file mode 100644
index 00000000..f2850b4b
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_int.h
@@ -0,0 +1,248 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Interrupt Mapper definitions File: sb1250_int.h
+ *
+ * This module contains constants for manipulating the SB1250's
+ * interrupt mapper and definitions for the interrupt sources.
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000, 2001, 2002, 2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_INT_H
+#define _SB1250_INT_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Interrupt Mapper Constants
+ ********************************************************************* */
+
+/*
+ * Interrupt sources (Table 4-8, UM 0.2)
+ *
+ * First, the interrupt numbers.
+ */
+
+#define K_INT_SOURCES 64
+
+#define K_INT_WATCHDOG_TIMER_0 0
+#define K_INT_WATCHDOG_TIMER_1 1
+#define K_INT_TIMER_0 2
+#define K_INT_TIMER_1 3
+#define K_INT_TIMER_2 4
+#define K_INT_TIMER_3 5
+#define K_INT_SMB_0 6
+#define K_INT_SMB_1 7
+#define K_INT_UART_0 8
+#define K_INT_UART_1 9
+#define K_INT_SER_0 10
+#define K_INT_SER_1 11
+#define K_INT_PCMCIA 12
+#define K_INT_ADDR_TRAP 13
+#define K_INT_PERF_CNT 14
+#define K_INT_TRACE_FREEZE 15
+#define K_INT_BAD_ECC 16
+#define K_INT_COR_ECC 17
+#define K_INT_IO_BUS 18
+#define K_INT_MAC_0 19
+#define K_INT_MAC_1 20
+#define K_INT_MAC_2 21
+#define K_INT_DM_CH_0 22
+#define K_INT_DM_CH_1 23
+#define K_INT_DM_CH_2 24
+#define K_INT_DM_CH_3 25
+#define K_INT_MBOX_0 26
+#define K_INT_MBOX_1 27
+#define K_INT_MBOX_2 28
+#define K_INT_MBOX_3 29
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define K_INT_CYCLE_CP0_INT 30
+#define K_INT_CYCLE_CP1_INT 31
+#endif /* 1250 PASS2 || 112x PASS1 */
+#define K_INT_GPIO_0 32
+#define K_INT_GPIO_1 33
+#define K_INT_GPIO_2 34
+#define K_INT_GPIO_3 35
+#define K_INT_GPIO_4 36
+#define K_INT_GPIO_5 37
+#define K_INT_GPIO_6 38
+#define K_INT_GPIO_7 39
+#define K_INT_GPIO_8 40
+#define K_INT_GPIO_9 41
+#define K_INT_GPIO_10 42
+#define K_INT_GPIO_11 43
+#define K_INT_GPIO_12 44
+#define K_INT_GPIO_13 45
+#define K_INT_GPIO_14 46
+#define K_INT_GPIO_15 47
+#define K_INT_LDT_FATAL 48
+#define K_INT_LDT_NONFATAL 49
+#define K_INT_LDT_SMI 50
+#define K_INT_LDT_NMI 51
+#define K_INT_LDT_INIT 52
+#define K_INT_LDT_STARTUP 53
+#define K_INT_LDT_EXT 54
+#define K_INT_PCI_ERROR 55
+#define K_INT_PCI_INTA 56
+#define K_INT_PCI_INTB 57
+#define K_INT_PCI_INTC 58
+#define K_INT_PCI_INTD 59
+#define K_INT_SPARE_2 60
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define K_INT_MAC_0_CH1 61
+#define K_INT_MAC_1_CH1 62
+#define K_INT_MAC_2_CH1 63
+#endif /* 1250 PASS2 || 112x PASS1 */
+
+/*
+ * Mask values for each interrupt
+ */
+
+#define M_INT_WATCHDOG_TIMER_0 _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_0)
+#define M_INT_WATCHDOG_TIMER_1 _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_1)
+#define M_INT_TIMER_0 _SB_MAKEMASK1(K_INT_TIMER_0)
+#define M_INT_TIMER_1 _SB_MAKEMASK1(K_INT_TIMER_1)
+#define M_INT_TIMER_2 _SB_MAKEMASK1(K_INT_TIMER_2)
+#define M_INT_TIMER_3 _SB_MAKEMASK1(K_INT_TIMER_3)
+#define M_INT_SMB_0 _SB_MAKEMASK1(K_INT_SMB_0)
+#define M_INT_SMB_1 _SB_MAKEMASK1(K_INT_SMB_1)
+#define M_INT_UART_0 _SB_MAKEMASK1(K_INT_UART_0)
+#define M_INT_UART_1 _SB_MAKEMASK1(K_INT_UART_1)
+#define M_INT_SER_0 _SB_MAKEMASK1(K_INT_SER_0)
+#define M_INT_SER_1 _SB_MAKEMASK1(K_INT_SER_1)
+#define M_INT_PCMCIA _SB_MAKEMASK1(K_INT_PCMCIA)
+#define M_INT_ADDR_TRAP _SB_MAKEMASK1(K_INT_ADDR_TRAP)
+#define M_INT_PERF_CNT _SB_MAKEMASK1(K_INT_PERF_CNT)
+#define M_INT_TRACE_FREEZE _SB_MAKEMASK1(K_INT_TRACE_FREEZE)
+#define M_INT_BAD_ECC _SB_MAKEMASK1(K_INT_BAD_ECC)
+#define M_INT_COR_ECC _SB_MAKEMASK1(K_INT_COR_ECC)
+#define M_INT_IO_BUS _SB_MAKEMASK1(K_INT_IO_BUS)
+#define M_INT_MAC_0 _SB_MAKEMASK1(K_INT_MAC_0)
+#define M_INT_MAC_1 _SB_MAKEMASK1(K_INT_MAC_1)
+#define M_INT_MAC_2 _SB_MAKEMASK1(K_INT_MAC_2)
+#define M_INT_DM_CH_0 _SB_MAKEMASK1(K_INT_DM_CH_0)
+#define M_INT_DM_CH_1 _SB_MAKEMASK1(K_INT_DM_CH_1)
+#define M_INT_DM_CH_2 _SB_MAKEMASK1(K_INT_DM_CH_2)
+#define M_INT_DM_CH_3 _SB_MAKEMASK1(K_INT_DM_CH_3)
+#define M_INT_MBOX_0 _SB_MAKEMASK1(K_INT_MBOX_0)
+#define M_INT_MBOX_1 _SB_MAKEMASK1(K_INT_MBOX_1)
+#define M_INT_MBOX_2 _SB_MAKEMASK1(K_INT_MBOX_2)
+#define M_INT_MBOX_3 _SB_MAKEMASK1(K_INT_MBOX_3)
+#define M_INT_MBOX_ALL _SB_MAKEMASK(4, K_INT_MBOX_0)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define M_INT_CYCLE_CP0_INT _SB_MAKEMASK1(K_INT_CYCLE_CP0_INT)
+#define M_INT_CYCLE_CP1_INT _SB_MAKEMASK1(K_INT_CYCLE_CP1_INT)
+#endif /* 1250 PASS2 || 112x PASS1 */
+#define M_INT_GPIO_0 _SB_MAKEMASK1(K_INT_GPIO_0)
+#define M_INT_GPIO_1 _SB_MAKEMASK1(K_INT_GPIO_1)
+#define M_INT_GPIO_2 _SB_MAKEMASK1(K_INT_GPIO_2)
+#define M_INT_GPIO_3 _SB_MAKEMASK1(K_INT_GPIO_3)
+#define M_INT_GPIO_4 _SB_MAKEMASK1(K_INT_GPIO_4)
+#define M_INT_GPIO_5 _SB_MAKEMASK1(K_INT_GPIO_5)
+#define M_INT_GPIO_6 _SB_MAKEMASK1(K_INT_GPIO_6)
+#define M_INT_GPIO_7 _SB_MAKEMASK1(K_INT_GPIO_7)
+#define M_INT_GPIO_8 _SB_MAKEMASK1(K_INT_GPIO_8)
+#define M_INT_GPIO_9 _SB_MAKEMASK1(K_INT_GPIO_9)
+#define M_INT_GPIO_10 _SB_MAKEMASK1(K_INT_GPIO_10)
+#define M_INT_GPIO_11 _SB_MAKEMASK1(K_INT_GPIO_11)
+#define M_INT_GPIO_12 _SB_MAKEMASK1(K_INT_GPIO_12)
+#define M_INT_GPIO_13 _SB_MAKEMASK1(K_INT_GPIO_13)
+#define M_INT_GPIO_14 _SB_MAKEMASK1(K_INT_GPIO_14)
+#define M_INT_GPIO_15 _SB_MAKEMASK1(K_INT_GPIO_15)
+#define M_INT_LDT_FATAL _SB_MAKEMASK1(K_INT_LDT_FATAL)
+#define M_INT_LDT_NONFATAL _SB_MAKEMASK1(K_INT_LDT_NONFATAL)
+#define M_INT_LDT_SMI _SB_MAKEMASK1(K_INT_LDT_SMI)
+#define M_INT_LDT_NMI _SB_MAKEMASK1(K_INT_LDT_NMI)
+#define M_INT_LDT_INIT _SB_MAKEMASK1(K_INT_LDT_INIT)
+#define M_INT_LDT_STARTUP _SB_MAKEMASK1(K_INT_LDT_STARTUP)
+#define M_INT_LDT_EXT _SB_MAKEMASK1(K_INT_LDT_EXT)
+#define M_INT_PCI_ERROR _SB_MAKEMASK1(K_INT_PCI_ERROR)
+#define M_INT_PCI_INTA _SB_MAKEMASK1(K_INT_PCI_INTA)
+#define M_INT_PCI_INTB _SB_MAKEMASK1(K_INT_PCI_INTB)
+#define M_INT_PCI_INTC _SB_MAKEMASK1(K_INT_PCI_INTC)
+#define M_INT_PCI_INTD _SB_MAKEMASK1(K_INT_PCI_INTD)
+#define M_INT_SPARE_2 _SB_MAKEMASK1(K_INT_SPARE_2)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define M_INT_MAC_0_CH1 _SB_MAKEMASK1(K_INT_MAC_0_CH1)
+#define M_INT_MAC_1_CH1 _SB_MAKEMASK1(K_INT_MAC_1_CH1)
+#define M_INT_MAC_2_CH1 _SB_MAKEMASK1(K_INT_MAC_2_CH1)
+#endif /* 1250 PASS2 || 112x PASS1 */
+
+/*
+ * Interrupt mappings
+ */
+
+#define K_INT_MAP_I0 0 /* interrupt pins on processor */
+#define K_INT_MAP_I1 1
+#define K_INT_MAP_I2 2
+#define K_INT_MAP_I3 3
+#define K_INT_MAP_I4 4
+#define K_INT_MAP_I5 5
+#define K_INT_MAP_NMI 6 /* nonmaskable */
+#define K_INT_MAP_DINT 7 /* debug interrupt */
+
+/*
+ * LDT Interrupt Set Register (table 4-5)
+ */
+
+#define S_INT_LDT_INTMSG 0
+#define M_INT_LDT_INTMSG _SB_MAKEMASK(3, S_INT_LDT_INTMSG)
+#define V_INT_LDT_INTMSG(x) _SB_MAKEVALUE(x, S_INT_LDT_INTMSG)
+#define G_INT_LDT_INTMSG(x) _SB_GETVALUE(x, S_INT_LDT_INTMSG, M_INT_LDT_INTMSG)
+
+#define K_INT_LDT_INTMSG_FIXED 0
+#define K_INT_LDT_INTMSG_ARBITRATED 1
+#define K_INT_LDT_INTMSG_SMI 2
+#define K_INT_LDT_INTMSG_NMI 3
+#define K_INT_LDT_INTMSG_INIT 4
+#define K_INT_LDT_INTMSG_STARTUP 5
+#define K_INT_LDT_INTMSG_EXTINT 6
+#define K_INT_LDT_INTMSG_RESERVED 7
+
+#define M_INT_LDT_EDGETRIGGER 0
+#define M_INT_LDT_LEVELTRIGGER _SB_MAKEMASK1(3)
+
+#define M_INT_LDT_PHYSICALDEST 0
+#define M_INT_LDT_LOGICALDEST _SB_MAKEMASK1(4)
+
+#define S_INT_LDT_INTDEST 5
+#define M_INT_LDT_INTDEST _SB_MAKEMASK(10, S_INT_LDT_INTDEST)
+#define V_INT_LDT_INTDEST(x) _SB_MAKEVALUE(x, S_INT_LDT_INTDEST)
+#define G_INT_LDT_INTDEST(x) _SB_GETVALUE(x, S_INT_LDT_INTDEST, M_INT_LDT_INTDEST)
+
+#define S_INT_LDT_VECTOR 13
+#define M_INT_LDT_VECTOR _SB_MAKEMASK(8, S_INT_LDT_VECTOR)
+#define V_INT_LDT_VECTOR(x) _SB_MAKEVALUE(x, S_INT_LDT_VECTOR)
+#define G_INT_LDT_VECTOR(x) _SB_GETVALUE(x, S_INT_LDT_VECTOR, M_INT_LDT_VECTOR)
+
+/*
+ * Vector format (Table 4-6)
+ */
+
+#define M_LDTVECT_RAISEINT 0x00
+#define M_LDTVECT_RAISEMBOX 0x40
+
+
+#endif /* 1250/112x */
diff --git a/arch/mips/include/asm/sibyte/sb1250_l2c.h b/arch/mips/include/asm/sibyte/sb1250_l2c.h
new file mode 100644
index 00000000..6554dcf0
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_l2c.h
@@ -0,0 +1,131 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * L2 Cache constants and macros File: sb1250_l2c.h
+ *
+ * This module contains constants useful for manipulating the
+ * level 2 cache.
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_L2C_H
+#define _SB1250_L2C_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Level 2 Cache Tag register (Table 5-3)
+ */
+
+#define S_L2C_TAG_MBZ 0
+#define M_L2C_TAG_MBZ _SB_MAKEMASK(5, S_L2C_TAG_MBZ)
+
+#define S_L2C_TAG_INDEX 5
+#define M_L2C_TAG_INDEX _SB_MAKEMASK(12, S_L2C_TAG_INDEX)
+#define V_L2C_TAG_INDEX(x) _SB_MAKEVALUE(x, S_L2C_TAG_INDEX)
+#define G_L2C_TAG_INDEX(x) _SB_GETVALUE(x, S_L2C_TAG_INDEX, M_L2C_TAG_INDEX)
+
+#define S_L2C_TAG_TAG 17
+#define M_L2C_TAG_TAG _SB_MAKEMASK(23, S_L2C_TAG_TAG)
+#define V_L2C_TAG_TAG(x) _SB_MAKEVALUE(x, S_L2C_TAG_TAG)
+#define G_L2C_TAG_TAG(x) _SB_GETVALUE(x, S_L2C_TAG_TAG, M_L2C_TAG_TAG)
+
+#define S_L2C_TAG_ECC 40
+#define M_L2C_TAG_ECC _SB_MAKEMASK(6, S_L2C_TAG_ECC)
+#define V_L2C_TAG_ECC(x) _SB_MAKEVALUE(x, S_L2C_TAG_ECC)
+#define G_L2C_TAG_ECC(x) _SB_GETVALUE(x, S_L2C_TAG_ECC, M_L2C_TAG_ECC)
+
+#define S_L2C_TAG_WAY 46
+#define M_L2C_TAG_WAY _SB_MAKEMASK(2, S_L2C_TAG_WAY)
+#define V_L2C_TAG_WAY(x) _SB_MAKEVALUE(x, S_L2C_TAG_WAY)
+#define G_L2C_TAG_WAY(x) _SB_GETVALUE(x, S_L2C_TAG_WAY, M_L2C_TAG_WAY)
+
+#define M_L2C_TAG_DIRTY _SB_MAKEMASK1(48)
+#define M_L2C_TAG_VALID _SB_MAKEMASK1(49)
+
+/*
+ * Format of level 2 cache management address (table 5-2)
+ */
+
+#define S_L2C_MGMT_INDEX 5
+#define M_L2C_MGMT_INDEX _SB_MAKEMASK(12, S_L2C_MGMT_INDEX)
+#define V_L2C_MGMT_INDEX(x) _SB_MAKEVALUE(x, S_L2C_MGMT_INDEX)
+#define G_L2C_MGMT_INDEX(x) _SB_GETVALUE(x, S_L2C_MGMT_INDEX, M_L2C_MGMT_INDEX)
+
+#define S_L2C_MGMT_QUADRANT 15
+#define M_L2C_MGMT_QUADRANT _SB_MAKEMASK(2, S_L2C_MGMT_QUADRANT)
+#define V_L2C_MGMT_QUADRANT(x) _SB_MAKEVALUE(x, S_L2C_MGMT_QUADRANT)
+#define G_L2C_MGMT_QUADRANT(x) _SB_GETVALUE(x, S_L2C_MGMT_QUADRANT, M_L2C_MGMT_QUADRANT)
+
+#define S_L2C_MGMT_HALF 16
+#define M_L2C_MGMT_HALF _SB_MAKEMASK(1, S_L2C_MGMT_HALF)
+
+#define S_L2C_MGMT_WAY 17
+#define M_L2C_MGMT_WAY _SB_MAKEMASK(2, S_L2C_MGMT_WAY)
+#define V_L2C_MGMT_WAY(x) _SB_MAKEVALUE(x, S_L2C_MGMT_WAY)
+#define G_L2C_MGMT_WAY(x) _SB_GETVALUE(x, S_L2C_MGMT_WAY, M_L2C_MGMT_WAY)
+
+#define S_L2C_MGMT_ECC_DIAG 21
+#define M_L2C_MGMT_ECC_DIAG _SB_MAKEMASK(2, S_L2C_MGMT_ECC_DIAG)
+#define V_L2C_MGMT_ECC_DIAG(x) _SB_MAKEVALUE(x, S_L2C_MGMT_ECC_DIAG)
+#define G_L2C_MGMT_ECC_DIAG(x) _SB_GETVALUE(x, S_L2C_MGMT_ECC_DIAG, M_L2C_MGMT_ECC_DIAG)
+
+#define S_L2C_MGMT_TAG 23
+#define M_L2C_MGMT_TAG _SB_MAKEMASK(4, S_L2C_MGMT_TAG)
+#define V_L2C_MGMT_TAG(x) _SB_MAKEVALUE(x, S_L2C_MGMT_TAG)
+#define G_L2C_MGMT_TAG(x) _SB_GETVALUE(x, S_L2C_MGMT_TAG, M_L2C_MGMT_TAG)
+
+#define M_L2C_MGMT_DIRTY _SB_MAKEMASK1(19)
+#define M_L2C_MGMT_VALID _SB_MAKEMASK1(20)
+
+#define A_L2C_MGMT_TAG_BASE 0x00D0000000
+
+#define L2C_ENTRIES_PER_WAY 4096
+#define L2C_NUM_WAYS 4
+
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+/*
+ * L2 Read Misc. register (A_L2_READ_MISC)
+ */
+#define S_L2C_MISC_NO_WAY 10
+#define M_L2C_MISC_NO_WAY _SB_MAKEMASK(4, S_L2C_MISC_NO_WAY)
+#define V_L2C_MISC_NO_WAY(x) _SB_MAKEVALUE(x, S_L2C_MISC_NO_WAY)
+#define G_L2C_MISC_NO_WAY(x) _SB_GETVALUE(x, S_L2C_MISC_NO_WAY, M_L2C_MISC_NO_WAY)
+
+#define M_L2C_MISC_ECC_CLEANUP_DIS _SB_MAKEMASK1(9)
+#define M_L2C_MISC_MC_PRIO_LOW _SB_MAKEMASK1(8)
+#define M_L2C_MISC_SOFT_DISABLE_T _SB_MAKEMASK1(7)
+#define M_L2C_MISC_SOFT_DISABLE_B _SB_MAKEMASK1(6)
+#define M_L2C_MISC_SOFT_DISABLE_R _SB_MAKEMASK1(5)
+#define M_L2C_MISC_SOFT_DISABLE_L _SB_MAKEMASK1(4)
+#define M_L2C_MISC_SCACHE_DISABLE_T _SB_MAKEMASK1(3)
+#define M_L2C_MISC_SCACHE_DISABLE_B _SB_MAKEMASK1(2)
+#define M_L2C_MISC_SCACHE_DISABLE_R _SB_MAKEMASK1(1)
+#define M_L2C_MISC_SCACHE_DISABLE_L _SB_MAKEMASK1(0)
+#endif /* 1250 PASS3 || 112x PASS1 */
+
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_ldt.h b/arch/mips/include/asm/sibyte/sb1250_ldt.h
new file mode 100644
index 00000000..1e76cf13
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_ldt.h
@@ -0,0 +1,422 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * LDT constants File: sb1250_ldt.h
+ *
+ * This module contains constants and macros to describe
+ * the LDT interface on the SB1250.
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000, 2001, 2002, 2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_LDT_H
+#define _SB1250_LDT_H
+
+#include "sb1250_defs.h"
+
+#define K_LDT_VENDOR_SIBYTE 0x166D
+#define K_LDT_DEVICE_SB1250 0x0002
+
+/*
+ * LDT Interface Type 1 (bridge) configuration header
+ */
+
+#define R_LDT_TYPE1_DEVICEID 0x0000
+#define R_LDT_TYPE1_CMDSTATUS 0x0004
+#define R_LDT_TYPE1_CLASSREV 0x0008
+#define R_LDT_TYPE1_DEVHDR 0x000C
+#define R_LDT_TYPE1_BAR0 0x0010 /* not used */
+#define R_LDT_TYPE1_BAR1 0x0014 /* not used */
+
+#define R_LDT_TYPE1_BUSID 0x0018 /* bus ID register */
+#define R_LDT_TYPE1_SECSTATUS 0x001C /* secondary status / I/O base/limit */
+#define R_LDT_TYPE1_MEMLIMIT 0x0020
+#define R_LDT_TYPE1_PREFETCH 0x0024
+#define R_LDT_TYPE1_PREF_BASE 0x0028
+#define R_LDT_TYPE1_PREF_LIMIT 0x002C
+#define R_LDT_TYPE1_IOLIMIT 0x0030
+#define R_LDT_TYPE1_CAPPTR 0x0034
+#define R_LDT_TYPE1_ROMADDR 0x0038
+#define R_LDT_TYPE1_BRCTL 0x003C
+#define R_LDT_TYPE1_CMD 0x0040
+#define R_LDT_TYPE1_LINKCTRL 0x0044
+#define R_LDT_TYPE1_LINKFREQ 0x0048
+#define R_LDT_TYPE1_RESERVED1 0x004C
+#define R_LDT_TYPE1_SRICMD 0x0050
+#define R_LDT_TYPE1_SRITXNUM 0x0054
+#define R_LDT_TYPE1_SRIRXNUM 0x0058
+#define R_LDT_TYPE1_ERRSTATUS 0x0068
+#define R_LDT_TYPE1_SRICTRL 0x006C
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define R_LDT_TYPE1_ADDSTATUS 0x0070
+#endif /* 1250 PASS2 || 112x PASS1 */
+#define R_LDT_TYPE1_TXBUFCNT 0x00C8
+#define R_LDT_TYPE1_EXPCRC 0x00DC
+#define R_LDT_TYPE1_RXCRC 0x00F0
+
+
+/*
+ * LDT Device ID register
+ */
+
+#define S_LDT_DEVICEID_VENDOR 0
+#define M_LDT_DEVICEID_VENDOR _SB_MAKEMASK_32(16, S_LDT_DEVICEID_VENDOR)
+#define V_LDT_DEVICEID_VENDOR(x) _SB_MAKEVALUE_32(x, S_LDT_DEVICEID_VENDOR)
+#define G_LDT_DEVICEID_VENDOR(x) _SB_GETVALUE_32(x, S_LDT_DEVICEID_VENDOR, M_LDT_DEVICEID_VENDOR)
+
+#define S_LDT_DEVICEID_DEVICEID 16
+#define M_LDT_DEVICEID_DEVICEID _SB_MAKEMASK_32(16, S_LDT_DEVICEID_DEVICEID)
+#define V_LDT_DEVICEID_DEVICEID(x) _SB_MAKEVALUE_32(x, S_LDT_DEVICEID_DEVICEID)
+#define G_LDT_DEVICEID_DEVICEID(x) _SB_GETVALUE_32(x, S_LDT_DEVICEID_DEVICEID, M_LDT_DEVICEID_DEVICEID)
+
+
+/*
+ * LDT Command Register (Table 8-13)
+ */
+
+#define M_LDT_CMD_IOSPACE_EN _SB_MAKEMASK1_32(0)
+#define M_LDT_CMD_MEMSPACE_EN _SB_MAKEMASK1_32(1)
+#define M_LDT_CMD_MASTER_EN _SB_MAKEMASK1_32(2)
+#define M_LDT_CMD_SPECCYC_EN _SB_MAKEMASK1_32(3)
+#define M_LDT_CMD_MEMWRINV_EN _SB_MAKEMASK1_32(4)
+#define M_LDT_CMD_VGAPALSNP_EN _SB_MAKEMASK1_32(5)
+#define M_LDT_CMD_PARERRRESP _SB_MAKEMASK1_32(6)
+#define M_LDT_CMD_WAITCYCCTRL _SB_MAKEMASK1_32(7)
+#define M_LDT_CMD_SERR_EN _SB_MAKEMASK1_32(8)
+#define M_LDT_CMD_FASTB2B_EN _SB_MAKEMASK1_32(9)
+
+/*
+ * LDT class and revision registers
+ */
+
+#define S_LDT_CLASSREV_REV 0
+#define M_LDT_CLASSREV_REV _SB_MAKEMASK_32(8, S_LDT_CLASSREV_REV)
+#define V_LDT_CLASSREV_REV(x) _SB_MAKEVALUE_32(x, S_LDT_CLASSREV_REV)
+#define G_LDT_CLASSREV_REV(x) _SB_GETVALUE_32(x, S_LDT_CLASSREV_REV, M_LDT_CLASSREV_REV)
+
+#define S_LDT_CLASSREV_CLASS 8
+#define M_LDT_CLASSREV_CLASS _SB_MAKEMASK_32(24, S_LDT_CLASSREV_CLASS)
+#define V_LDT_CLASSREV_CLASS(x) _SB_MAKEVALUE_32(x, S_LDT_CLASSREV_CLASS)
+#define G_LDT_CLASSREV_CLASS(x) _SB_GETVALUE_32(x, S_LDT_CLASSREV_CLASS, M_LDT_CLASSREV_CLASS)
+
+#define K_LDT_REV 0x01
+#define K_LDT_CLASS 0x060000
+
+/*
+ * Device Header (offset 0x0C)
+ */
+
+#define S_LDT_DEVHDR_CLINESZ 0
+#define M_LDT_DEVHDR_CLINESZ _SB_MAKEMASK_32(8, S_LDT_DEVHDR_CLINESZ)
+#define V_LDT_DEVHDR_CLINESZ(x) _SB_MAKEVALUE_32(x, S_LDT_DEVHDR_CLINESZ)
+#define G_LDT_DEVHDR_CLINESZ(x) _SB_GETVALUE_32(x, S_LDT_DEVHDR_CLINESZ, M_LDT_DEVHDR_CLINESZ)
+
+#define S_LDT_DEVHDR_LATTMR 8
+#define M_LDT_DEVHDR_LATTMR _SB_MAKEMASK_32(8, S_LDT_DEVHDR_LATTMR)
+#define V_LDT_DEVHDR_LATTMR(x) _SB_MAKEVALUE_32(x, S_LDT_DEVHDR_LATTMR)
+#define G_LDT_DEVHDR_LATTMR(x) _SB_GETVALUE_32(x, S_LDT_DEVHDR_LATTMR, M_LDT_DEVHDR_LATTMR)
+
+#define S_LDT_DEVHDR_HDRTYPE 16
+#define M_LDT_DEVHDR_HDRTYPE _SB_MAKEMASK_32(8, S_LDT_DEVHDR_HDRTYPE)
+#define V_LDT_DEVHDR_HDRTYPE(x) _SB_MAKEVALUE_32(x, S_LDT_DEVHDR_HDRTYPE)
+#define G_LDT_DEVHDR_HDRTYPE(x) _SB_GETVALUE_32(x, S_LDT_DEVHDR_HDRTYPE, M_LDT_DEVHDR_HDRTYPE)
+
+#define K_LDT_DEVHDR_HDRTYPE_TYPE1 1
+
+#define S_LDT_DEVHDR_BIST 24
+#define M_LDT_DEVHDR_BIST _SB_MAKEMASK_32(8, S_LDT_DEVHDR_BIST)
+#define V_LDT_DEVHDR_BIST(x) _SB_MAKEVALUE_32(x, S_LDT_DEVHDR_BIST)
+#define G_LDT_DEVHDR_BIST(x) _SB_GETVALUE_32(x, S_LDT_DEVHDR_BIST, M_LDT_DEVHDR_BIST)
+
+
+
+/*
+ * LDT Status Register (Table 8-14). Note that these constants
+ * assume you've read the command and status register
+ * together (32-bit read at offset 0x04)
+ *
+ * These bits also apply to the secondary status
+ * register (Table 8-15), offset 0x1C
+ */
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define M_LDT_STATUS_VGAEN _SB_MAKEMASK1_32(3)
+#endif /* 1250 PASS2 || 112x PASS1 */
+#define M_LDT_STATUS_CAPLIST _SB_MAKEMASK1_32(20)
+#define M_LDT_STATUS_66MHZCAP _SB_MAKEMASK1_32(21)
+#define M_LDT_STATUS_RESERVED2 _SB_MAKEMASK1_32(22)
+#define M_LDT_STATUS_FASTB2BCAP _SB_MAKEMASK1_32(23)
+#define M_LDT_STATUS_MSTRDPARERR _SB_MAKEMASK1_32(24)
+
+#define S_LDT_STATUS_DEVSELTIMING 25
+#define M_LDT_STATUS_DEVSELTIMING _SB_MAKEMASK_32(2, S_LDT_STATUS_DEVSELTIMING)
+#define V_LDT_STATUS_DEVSELTIMING(x) _SB_MAKEVALUE_32(x, S_LDT_STATUS_DEVSELTIMING)
+#define G_LDT_STATUS_DEVSELTIMING(x) _SB_GETVALUE_32(x, S_LDT_STATUS_DEVSELTIMING, M_LDT_STATUS_DEVSELTIMING)
+
+#define M_LDT_STATUS_SIGDTGTABORT _SB_MAKEMASK1_32(27)
+#define M_LDT_STATUS_RCVDTGTABORT _SB_MAKEMASK1_32(28)
+#define M_LDT_STATUS_RCVDMSTRABORT _SB_MAKEMASK1_32(29)
+#define M_LDT_STATUS_SIGDSERR _SB_MAKEMASK1_32(30)
+#define M_LDT_STATUS_DETPARERR _SB_MAKEMASK1_32(31)
+
+/*
+ * Bridge Control Register (Table 8-16). Note that these
+ * constants assume you've read the register as a 32-bit
+ * read (offset 0x3C)
+ */
+
+#define M_LDT_BRCTL_PARERRRESP_EN _SB_MAKEMASK1_32(16)
+#define M_LDT_BRCTL_SERR_EN _SB_MAKEMASK1_32(17)
+#define M_LDT_BRCTL_ISA_EN _SB_MAKEMASK1_32(18)
+#define M_LDT_BRCTL_VGA_EN _SB_MAKEMASK1_32(19)
+#define M_LDT_BRCTL_MSTRABORTMODE _SB_MAKEMASK1_32(21)
+#define M_LDT_BRCTL_SECBUSRESET _SB_MAKEMASK1_32(22)
+#define M_LDT_BRCTL_FASTB2B_EN _SB_MAKEMASK1_32(23)
+#define M_LDT_BRCTL_PRIDISCARD _SB_MAKEMASK1_32(24)
+#define M_LDT_BRCTL_SECDISCARD _SB_MAKEMASK1_32(25)
+#define M_LDT_BRCTL_DISCARDSTAT _SB_MAKEMASK1_32(26)
+#define M_LDT_BRCTL_DISCARDSERR_EN _SB_MAKEMASK1_32(27)
+
+/*
+ * LDT Command Register (Table 8-17). Note that these constants
+ * assume you've read the command and status register together
+ * 32-bit read at offset 0x40
+ */
+
+#define M_LDT_CMD_WARMRESET _SB_MAKEMASK1_32(16)
+#define M_LDT_CMD_DOUBLEENDED _SB_MAKEMASK1_32(17)
+
+#define S_LDT_CMD_CAPTYPE 29
+#define M_LDT_CMD_CAPTYPE _SB_MAKEMASK_32(3, S_LDT_CMD_CAPTYPE)
+#define V_LDT_CMD_CAPTYPE(x) _SB_MAKEVALUE_32(x, S_LDT_CMD_CAPTYPE)
+#define G_LDT_CMD_CAPTYPE(x) _SB_GETVALUE_32(x, S_LDT_CMD_CAPTYPE, M_LDT_CMD_CAPTYPE)
+
+/*
+ * LDT link control register (Table 8-18), and (Table 8-19)
+ */
+
+#define M_LDT_LINKCTRL_CAPSYNCFLOOD_EN _SB_MAKEMASK1_32(1)
+#define M_LDT_LINKCTRL_CRCSTARTTEST _SB_MAKEMASK1_32(2)
+#define M_LDT_LINKCTRL_CRCFORCEERR _SB_MAKEMASK1_32(3)
+#define M_LDT_LINKCTRL_LINKFAIL _SB_MAKEMASK1_32(4)
+#define M_LDT_LINKCTRL_INITDONE _SB_MAKEMASK1_32(5)
+#define M_LDT_LINKCTRL_EOC _SB_MAKEMASK1_32(6)
+#define M_LDT_LINKCTRL_XMITOFF _SB_MAKEMASK1_32(7)
+
+#define S_LDT_LINKCTRL_CRCERR 8
+#define M_LDT_LINKCTRL_CRCERR _SB_MAKEMASK_32(4, S_LDT_LINKCTRL_CRCERR)
+#define V_LDT_LINKCTRL_CRCERR(x) _SB_MAKEVALUE_32(x, S_LDT_LINKCTRL_CRCERR)
+#define G_LDT_LINKCTRL_CRCERR(x) _SB_GETVALUE_32(x, S_LDT_LINKCTRL_CRCERR, M_LDT_LINKCTRL_CRCERR)
+
+#define S_LDT_LINKCTRL_MAXIN 16
+#define M_LDT_LINKCTRL_MAXIN _SB_MAKEMASK_32(3, S_LDT_LINKCTRL_MAXIN)
+#define V_LDT_LINKCTRL_MAXIN(x) _SB_MAKEVALUE_32(x, S_LDT_LINKCTRL_MAXIN)
+#define G_LDT_LINKCTRL_MAXIN(x) _SB_GETVALUE_32(x, S_LDT_LINKCTRL_MAXIN, M_LDT_LINKCTRL_MAXIN)
+
+#define M_LDT_LINKCTRL_DWFCLN _SB_MAKEMASK1_32(19)
+
+#define S_LDT_LINKCTRL_MAXOUT 20
+#define M_LDT_LINKCTRL_MAXOUT _SB_MAKEMASK_32(3, S_LDT_LINKCTRL_MAXOUT)
+#define V_LDT_LINKCTRL_MAXOUT(x) _SB_MAKEVALUE_32(x, S_LDT_LINKCTRL_MAXOUT)
+#define G_LDT_LINKCTRL_MAXOUT(x) _SB_GETVALUE_32(x, S_LDT_LINKCTRL_MAXOUT, M_LDT_LINKCTRL_MAXOUT)
+
+#define M_LDT_LINKCTRL_DWFCOUT _SB_MAKEMASK1_32(23)
+
+#define S_LDT_LINKCTRL_WIDTHIN 24
+#define M_LDT_LINKCTRL_WIDTHIN _SB_MAKEMASK_32(3, S_LDT_LINKCTRL_WIDTHIN)
+#define V_LDT_LINKCTRL_WIDTHIN(x) _SB_MAKEVALUE_32(x, S_LDT_LINKCTRL_WIDTHIN)
+#define G_LDT_LINKCTRL_WIDTHIN(x) _SB_GETVALUE_32(x, S_LDT_LINKCTRL_WIDTHIN, M_LDT_LINKCTRL_WIDTHIN)
+
+#define M_LDT_LINKCTRL_DWFCLIN_EN _SB_MAKEMASK1_32(27)
+
+#define S_LDT_LINKCTRL_WIDTHOUT 28
+#define M_LDT_LINKCTRL_WIDTHOUT _SB_MAKEMASK_32(3, S_LDT_LINKCTRL_WIDTHOUT)
+#define V_LDT_LINKCTRL_WIDTHOUT(x) _SB_MAKEVALUE_32(x, S_LDT_LINKCTRL_WIDTHOUT)
+#define G_LDT_LINKCTRL_WIDTHOUT(x) _SB_GETVALUE_32(x, S_LDT_LINKCTRL_WIDTHOUT, M_LDT_LINKCTRL_WIDTHOUT)
+
+#define M_LDT_LINKCTRL_DWFCOUT_EN _SB_MAKEMASK1_32(31)
+
+/*
+ * LDT Link frequency register (Table 8-20) offset 0x48
+ */
+
+#define S_LDT_LINKFREQ_FREQ 8
+#define M_LDT_LINKFREQ_FREQ _SB_MAKEMASK_32(4, S_LDT_LINKFREQ_FREQ)
+#define V_LDT_LINKFREQ_FREQ(x) _SB_MAKEVALUE_32(x, S_LDT_LINKFREQ_FREQ)
+#define G_LDT_LINKFREQ_FREQ(x) _SB_GETVALUE_32(x, S_LDT_LINKFREQ_FREQ, M_LDT_LINKFREQ_FREQ)
+
+#define K_LDT_LINKFREQ_200MHZ 0
+#define K_LDT_LINKFREQ_300MHZ 1
+#define K_LDT_LINKFREQ_400MHZ 2
+#define K_LDT_LINKFREQ_500MHZ 3
+#define K_LDT_LINKFREQ_600MHZ 4
+#define K_LDT_LINKFREQ_800MHZ 5
+#define K_LDT_LINKFREQ_1000MHZ 6
+
+/*
+ * LDT SRI Command Register (Table 8-21). Note that these constants
+ * assume you've read the command and status register together
+ * 32-bit read at offset 0x50
+ */
+
+#define M_LDT_SRICMD_SIPREADY _SB_MAKEMASK1_32(16)
+#define M_LDT_SRICMD_SYNCPTRCTL _SB_MAKEMASK1_32(17)
+#define M_LDT_SRICMD_REDUCESYNCZERO _SB_MAKEMASK1_32(18)
+#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1)
+#define M_LDT_SRICMD_DISSTARVATIONCNT _SB_MAKEMASK1_32(19) /* PASS1 */
+#endif /* up to 1250 PASS1 */
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define M_LDT_SRICMD_DISMULTTXVLD _SB_MAKEMASK1_32(19)
+#define M_LDT_SRICMD_EXPENDIAN _SB_MAKEMASK1_32(26)
+#endif /* 1250 PASS2 || 112x PASS1 */
+
+
+#define S_LDT_SRICMD_RXMARGIN 20
+#define M_LDT_SRICMD_RXMARGIN _SB_MAKEMASK_32(5, S_LDT_SRICMD_RXMARGIN)
+#define V_LDT_SRICMD_RXMARGIN(x) _SB_MAKEVALUE_32(x, S_LDT_SRICMD_RXMARGIN)
+#define G_LDT_SRICMD_RXMARGIN(x) _SB_GETVALUE_32(x, S_LDT_SRICMD_RXMARGIN, M_LDT_SRICMD_RXMARGIN)
+
+#define M_LDT_SRICMD_LDTPLLCOMPAT _SB_MAKEMASK1_32(25)
+
+#define S_LDT_SRICMD_TXINITIALOFFSET 28
+#define M_LDT_SRICMD_TXINITIALOFFSET _SB_MAKEMASK_32(3, S_LDT_SRICMD_TXINITIALOFFSET)
+#define V_LDT_SRICMD_TXINITIALOFFSET(x) _SB_MAKEVALUE_32(x, S_LDT_SRICMD_TXINITIALOFFSET)
+#define G_LDT_SRICMD_TXINITIALOFFSET(x) _SB_GETVALUE_32(x, S_LDT_SRICMD_TXINITIALOFFSET, M_LDT_SRICMD_TXINITIALOFFSET)
+
+#define M_LDT_SRICMD_LINKFREQDIRECT _SB_MAKEMASK1_32(31)
+
+/*
+ * LDT Error control and status register (Table 8-22) (Table 8-23)
+ */
+
+#define M_LDT_ERRCTL_PROTFATAL_EN _SB_MAKEMASK1_32(0)
+#define M_LDT_ERRCTL_PROTNONFATAL_EN _SB_MAKEMASK1_32(1)
+#define M_LDT_ERRCTL_PROTSYNCFLOOD_EN _SB_MAKEMASK1_32(2)
+#define M_LDT_ERRCTL_OVFFATAL_EN _SB_MAKEMASK1_32(3)
+#define M_LDT_ERRCTL_OVFNONFATAL_EN _SB_MAKEMASK1_32(4)
+#define M_LDT_ERRCTL_OVFSYNCFLOOD_EN _SB_MAKEMASK1_32(5)
+#define M_LDT_ERRCTL_EOCNXAFATAL_EN _SB_MAKEMASK1_32(6)
+#define M_LDT_ERRCTL_EOCNXANONFATAL_EN _SB_MAKEMASK1_32(7)
+#define M_LDT_ERRCTL_EOCNXASYNCFLOOD_EN _SB_MAKEMASK1_32(8)
+#define M_LDT_ERRCTL_CRCFATAL_EN _SB_MAKEMASK1_32(9)
+#define M_LDT_ERRCTL_CRCNONFATAL_EN _SB_MAKEMASK1_32(10)
+#define M_LDT_ERRCTL_SERRFATAL_EN _SB_MAKEMASK1_32(11)
+#define M_LDT_ERRCTL_SRCTAGFATAL_EN _SB_MAKEMASK1_32(12)
+#define M_LDT_ERRCTL_SRCTAGNONFATAL_EN _SB_MAKEMASK1_32(13)
+#define M_LDT_ERRCTL_SRCTAGSYNCFLOOD_EN _SB_MAKEMASK1_32(14)
+#define M_LDT_ERRCTL_MAPNXAFATAL_EN _SB_MAKEMASK1_32(15)
+#define M_LDT_ERRCTL_MAPNXANONFATAL_EN _SB_MAKEMASK1_32(16)
+#define M_LDT_ERRCTL_MAPNXASYNCFLOOD_EN _SB_MAKEMASK1_32(17)
+
+#define M_LDT_ERRCTL_PROTOERR _SB_MAKEMASK1_32(24)
+#define M_LDT_ERRCTL_OVFERR _SB_MAKEMASK1_32(25)
+#define M_LDT_ERRCTL_EOCNXAERR _SB_MAKEMASK1_32(26)
+#define M_LDT_ERRCTL_SRCTAGERR _SB_MAKEMASK1_32(27)
+#define M_LDT_ERRCTL_MAPNXAERR _SB_MAKEMASK1_32(28)
+
+/*
+ * SRI Control register (Table 8-24, 8-25) Offset 0x6C
+ */
+
+#define S_LDT_SRICTRL_NEEDRESP 0
+#define M_LDT_SRICTRL_NEEDRESP _SB_MAKEMASK_32(2, S_LDT_SRICTRL_NEEDRESP)
+#define V_LDT_SRICTRL_NEEDRESP(x) _SB_MAKEVALUE_32(x, S_LDT_SRICTRL_NEEDRESP)
+#define G_LDT_SRICTRL_NEEDRESP(x) _SB_GETVALUE_32(x, S_LDT_SRICTRL_NEEDRESP, M_LDT_SRICTRL_NEEDRESP)
+
+#define S_LDT_SRICTRL_NEEDNPREQ 2
+#define M_LDT_SRICTRL_NEEDNPREQ _SB_MAKEMASK_32(2, S_LDT_SRICTRL_NEEDNPREQ)
+#define V_LDT_SRICTRL_NEEDNPREQ(x) _SB_MAKEVALUE_32(x, S_LDT_SRICTRL_NEEDNPREQ)
+#define G_LDT_SRICTRL_NEEDNPREQ(x) _SB_GETVALUE_32(x, S_LDT_SRICTRL_NEEDNPREQ, M_LDT_SRICTRL_NEEDNPREQ)
+
+#define S_LDT_SRICTRL_NEEDPREQ 4
+#define M_LDT_SRICTRL_NEEDPREQ _SB_MAKEMASK_32(2, S_LDT_SRICTRL_NEEDPREQ)
+#define V_LDT_SRICTRL_NEEDPREQ(x) _SB_MAKEVALUE_32(x, S_LDT_SRICTRL_NEEDPREQ)
+#define G_LDT_SRICTRL_NEEDPREQ(x) _SB_GETVALUE_32(x, S_LDT_SRICTRL_NEEDPREQ, M_LDT_SRICTRL_NEEDPREQ)
+
+#define S_LDT_SRICTRL_WANTRESP 8
+#define M_LDT_SRICTRL_WANTRESP _SB_MAKEMASK_32(2, S_LDT_SRICTRL_WANTRESP)
+#define V_LDT_SRICTRL_WANTRESP(x) _SB_MAKEVALUE_32(x, S_LDT_SRICTRL_WANTRESP)
+#define G_LDT_SRICTRL_WANTRESP(x) _SB_GETVALUE_32(x, S_LDT_SRICTRL_WANTRESP, M_LDT_SRICTRL_WANTRESP)
+
+#define S_LDT_SRICTRL_WANTNPREQ 10
+#define M_LDT_SRICTRL_WANTNPREQ _SB_MAKEMASK_32(2, S_LDT_SRICTRL_WANTNPREQ)
+#define V_LDT_SRICTRL_WANTNPREQ(x) _SB_MAKEVALUE_32(x, S_LDT_SRICTRL_WANTNPREQ)
+#define G_LDT_SRICTRL_WANTNPREQ(x) _SB_GETVALUE_32(x, S_LDT_SRICTRL_WANTNPREQ, M_LDT_SRICTRL_WANTNPREQ)
+
+#define S_LDT_SRICTRL_WANTPREQ 12
+#define M_LDT_SRICTRL_WANTPREQ _SB_MAKEMASK_32(2, S_LDT_SRICTRL_WANTPREQ)
+#define V_LDT_SRICTRL_WANTPREQ(x) _SB_MAKEVALUE_32(x, S_LDT_SRICTRL_WANTPREQ)
+#define G_LDT_SRICTRL_WANTPREQ(x) _SB_GETVALUE_32(x, S_LDT_SRICTRL_WANTPREQ, M_LDT_SRICTRL_WANTPREQ)
+
+#define S_LDT_SRICTRL_BUFRELSPACE 16
+#define M_LDT_SRICTRL_BUFRELSPACE _SB_MAKEMASK_32(4, S_LDT_SRICTRL_BUFRELSPACE)
+#define V_LDT_SRICTRL_BUFRELSPACE(x) _SB_MAKEVALUE_32(x, S_LDT_SRICTRL_BUFRELSPACE)
+#define G_LDT_SRICTRL_BUFRELSPACE(x) _SB_GETVALUE_32(x, S_LDT_SRICTRL_BUFRELSPACE, M_LDT_SRICTRL_BUFRELSPACE)
+
+/*
+ * LDT SRI Transmit Buffer Count register (Table 8-26)
+ */
+
+#define S_LDT_TXBUFCNT_PCMD 0
+#define M_LDT_TXBUFCNT_PCMD _SB_MAKEMASK_32(4, S_LDT_TXBUFCNT_PCMD)
+#define V_LDT_TXBUFCNT_PCMD(x) _SB_MAKEVALUE_32(x, S_LDT_TXBUFCNT_PCMD)
+#define G_LDT_TXBUFCNT_PCMD(x) _SB_GETVALUE_32(x, S_LDT_TXBUFCNT_PCMD, M_LDT_TXBUFCNT_PCMD)
+
+#define S_LDT_TXBUFCNT_PDATA 4
+#define M_LDT_TXBUFCNT_PDATA _SB_MAKEMASK_32(4, S_LDT_TXBUFCNT_PDATA)
+#define V_LDT_TXBUFCNT_PDATA(x) _SB_MAKEVALUE_32(x, S_LDT_TXBUFCNT_PDATA)
+#define G_LDT_TXBUFCNT_PDATA(x) _SB_GETVALUE_32(x, S_LDT_TXBUFCNT_PDATA, M_LDT_TXBUFCNT_PDATA)
+
+#define S_LDT_TXBUFCNT_NPCMD 8
+#define M_LDT_TXBUFCNT_NPCMD _SB_MAKEMASK_32(4, S_LDT_TXBUFCNT_NPCMD)
+#define V_LDT_TXBUFCNT_NPCMD(x) _SB_MAKEVALUE_32(x, S_LDT_TXBUFCNT_NPCMD)
+#define G_LDT_TXBUFCNT_NPCMD(x) _SB_GETVALUE_32(x, S_LDT_TXBUFCNT_NPCMD, M_LDT_TXBUFCNT_NPCMD)
+
+#define S_LDT_TXBUFCNT_NPDATA 12
+#define M_LDT_TXBUFCNT_NPDATA _SB_MAKEMASK_32(4, S_LDT_TXBUFCNT_NPDATA)
+#define V_LDT_TXBUFCNT_NPDATA(x) _SB_MAKEVALUE_32(x, S_LDT_TXBUFCNT_NPDATA)
+#define G_LDT_TXBUFCNT_NPDATA(x) _SB_GETVALUE_32(x, S_LDT_TXBUFCNT_NPDATA, M_LDT_TXBUFCNT_NPDATA)
+
+#define S_LDT_TXBUFCNT_RCMD 16
+#define M_LDT_TXBUFCNT_RCMD _SB_MAKEMASK_32(4, S_LDT_TXBUFCNT_RCMD)
+#define V_LDT_TXBUFCNT_RCMD(x) _SB_MAKEVALUE_32(x, S_LDT_TXBUFCNT_RCMD)
+#define G_LDT_TXBUFCNT_RCMD(x) _SB_GETVALUE_32(x, S_LDT_TXBUFCNT_RCMD, M_LDT_TXBUFCNT_RCMD)
+
+#define S_LDT_TXBUFCNT_RDATA 20
+#define M_LDT_TXBUFCNT_RDATA _SB_MAKEMASK_32(4, S_LDT_TXBUFCNT_RDATA)
+#define V_LDT_TXBUFCNT_RDATA(x) _SB_MAKEVALUE_32(x, S_LDT_TXBUFCNT_RDATA)
+#define G_LDT_TXBUFCNT_RDATA(x) _SB_GETVALUE_32(x, S_LDT_TXBUFCNT_RDATA, M_LDT_TXBUFCNT_RDATA)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+/*
+ * Additional Status Register
+ */
+
+#define S_LDT_ADDSTATUS_TGTDONE 0
+#define M_LDT_ADDSTATUS_TGTDONE _SB_MAKEMASK_32(8, S_LDT_ADDSTATUS_TGTDONE)
+#define V_LDT_ADDSTATUS_TGTDONE(x) _SB_MAKEVALUE_32(x, S_LDT_ADDSTATUS_TGTDONE)
+#define G_LDT_ADDSTATUS_TGTDONE(x) _SB_GETVALUE_32(x, S_LDT_ADDSTATUS_TGTDONE, M_LDT_ADDSTATUS_TGTDONE)
+#endif /* 1250 PASS2 || 112x PASS1 */
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_mac.h b/arch/mips/include/asm/sibyte/sb1250_mac.h
new file mode 100644
index 00000000..77f78728
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_mac.h
@@ -0,0 +1,656 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * MAC constants and macros File: sb1250_mac.h
+ *
+ * This module contains constants and macros for the SB1250's
+ * ethernet controllers.
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_MAC_H
+#define _SB1250_MAC_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * Ethernet MAC Registers
+ ********************************************************************* */
+
+/*
+ * MAC Configuration Register (Table 9-13)
+ * Register: MAC_CFG_0
+ * Register: MAC_CFG_1
+ * Register: MAC_CFG_2
+ */
+
+
+#define M_MAC_RESERVED0 _SB_MAKEMASK1(0)
+#define M_MAC_TX_HOLD_SOP_EN _SB_MAKEMASK1(1)
+#define M_MAC_RETRY_EN _SB_MAKEMASK1(2)
+#define M_MAC_RET_DRPREQ_EN _SB_MAKEMASK1(3)
+#define M_MAC_RET_UFL_EN _SB_MAKEMASK1(4)
+#define M_MAC_BURST_EN _SB_MAKEMASK1(5)
+
+#define S_MAC_TX_PAUSE _SB_MAKE64(6)
+#define M_MAC_TX_PAUSE_CNT _SB_MAKEMASK(3, S_MAC_TX_PAUSE)
+#define V_MAC_TX_PAUSE_CNT(x) _SB_MAKEVALUE(x, S_MAC_TX_PAUSE)
+
+#define K_MAC_TX_PAUSE_CNT_512 0
+#define K_MAC_TX_PAUSE_CNT_1K 1
+#define K_MAC_TX_PAUSE_CNT_2K 2
+#define K_MAC_TX_PAUSE_CNT_4K 3
+#define K_MAC_TX_PAUSE_CNT_8K 4
+#define K_MAC_TX_PAUSE_CNT_16K 5
+#define K_MAC_TX_PAUSE_CNT_32K 6
+#define K_MAC_TX_PAUSE_CNT_64K 7
+
+#define V_MAC_TX_PAUSE_CNT_512 V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_512)
+#define V_MAC_TX_PAUSE_CNT_1K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_1K)
+#define V_MAC_TX_PAUSE_CNT_2K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_2K)
+#define V_MAC_TX_PAUSE_CNT_4K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_4K)
+#define V_MAC_TX_PAUSE_CNT_8K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_8K)
+#define V_MAC_TX_PAUSE_CNT_16K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_16K)
+#define V_MAC_TX_PAUSE_CNT_32K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_32K)
+#define V_MAC_TX_PAUSE_CNT_64K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_64K)
+
+#define M_MAC_RESERVED1 _SB_MAKEMASK(8, 9)
+
+#define M_MAC_AP_STAT_EN _SB_MAKEMASK1(17)
+
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_TIMESTAMP _SB_MAKEMASK1(18)
+#endif
+#define M_MAC_DRP_ERRPKT_EN _SB_MAKEMASK1(19)
+#define M_MAC_DRP_FCSERRPKT_EN _SB_MAKEMASK1(20)
+#define M_MAC_DRP_CODEERRPKT_EN _SB_MAKEMASK1(21)
+#define M_MAC_DRP_DRBLERRPKT_EN _SB_MAKEMASK1(22)
+#define M_MAC_DRP_RNTPKT_EN _SB_MAKEMASK1(23)
+#define M_MAC_DRP_OSZPKT_EN _SB_MAKEMASK1(24)
+#define M_MAC_DRP_LENERRPKT_EN _SB_MAKEMASK1(25)
+
+#define M_MAC_RESERVED3 _SB_MAKEMASK(6, 26)
+
+#define M_MAC_BYPASS_SEL _SB_MAKEMASK1(32)
+#define M_MAC_HDX_EN _SB_MAKEMASK1(33)
+
+#define S_MAC_SPEED_SEL _SB_MAKE64(34)
+#define M_MAC_SPEED_SEL _SB_MAKEMASK(2, S_MAC_SPEED_SEL)
+#define V_MAC_SPEED_SEL(x) _SB_MAKEVALUE(x, S_MAC_SPEED_SEL)
+#define G_MAC_SPEED_SEL(x) _SB_GETVALUE(x, S_MAC_SPEED_SEL, M_MAC_SPEED_SEL)
+
+#define K_MAC_SPEED_SEL_10MBPS 0
+#define K_MAC_SPEED_SEL_100MBPS 1
+#define K_MAC_SPEED_SEL_1000MBPS 2
+#define K_MAC_SPEED_SEL_RESERVED 3
+
+#define V_MAC_SPEED_SEL_10MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_10MBPS)
+#define V_MAC_SPEED_SEL_100MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_100MBPS)
+#define V_MAC_SPEED_SEL_1000MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_1000MBPS)
+#define V_MAC_SPEED_SEL_RESERVED V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_RESERVED)
+
+#define M_MAC_TX_CLK_EDGE_SEL _SB_MAKEMASK1(36)
+#define M_MAC_LOOPBACK_SEL _SB_MAKEMASK1(37)
+#define M_MAC_FAST_SYNC _SB_MAKEMASK1(38)
+#define M_MAC_SS_EN _SB_MAKEMASK1(39)
+
+#define S_MAC_BYPASS_CFG _SB_MAKE64(40)
+#define M_MAC_BYPASS_CFG _SB_MAKEMASK(2, S_MAC_BYPASS_CFG)
+#define V_MAC_BYPASS_CFG(x) _SB_MAKEVALUE(x, S_MAC_BYPASS_CFG)
+#define G_MAC_BYPASS_CFG(x) _SB_GETVALUE(x, S_MAC_BYPASS_CFG, M_MAC_BYPASS_CFG)
+
+#define K_MAC_BYPASS_GMII 0
+#define K_MAC_BYPASS_ENCODED 1
+#define K_MAC_BYPASS_SOP 2
+#define K_MAC_BYPASS_EOP 3
+
+#define M_MAC_BYPASS_16 _SB_MAKEMASK1(42)
+#define M_MAC_BYPASS_FCS_CHK _SB_MAKEMASK1(43)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_RX_CH_SEL_MSB _SB_MAKEMASK1(44)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480*/
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_SPLIT_CH_SEL _SB_MAKEMASK1(45)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define S_MAC_BYPASS_IFG _SB_MAKE64(46)
+#define M_MAC_BYPASS_IFG _SB_MAKEMASK(8, S_MAC_BYPASS_IFG)
+#define V_MAC_BYPASS_IFG(x) _SB_MAKEVALUE(x, S_MAC_BYPASS_IFG)
+#define G_MAC_BYPASS_IFG(x) _SB_GETVALUE(x, S_MAC_BYPASS_IFG, M_MAC_BYPASS_IFG)
+
+#define K_MAC_FC_CMD_DISABLED 0
+#define K_MAC_FC_CMD_ENABLED 1
+#define K_MAC_FC_CMD_ENAB_FALSECARR 2
+
+#define V_MAC_FC_CMD_DISABLED V_MAC_FC_CMD(K_MAC_FC_CMD_DISABLED)
+#define V_MAC_FC_CMD_ENABLED V_MAC_FC_CMD(K_MAC_FC_CMD_ENABLED)
+#define V_MAC_FC_CMD_ENAB_FALSECARR V_MAC_FC_CMD(K_MAC_FC_CMD_ENAB_FALSECARR)
+
+#define M_MAC_FC_SEL _SB_MAKEMASK1(54)
+
+#define S_MAC_FC_CMD _SB_MAKE64(55)
+#define M_MAC_FC_CMD _SB_MAKEMASK(2, S_MAC_FC_CMD)
+#define V_MAC_FC_CMD(x) _SB_MAKEVALUE(x, S_MAC_FC_CMD)
+#define G_MAC_FC_CMD(x) _SB_GETVALUE(x, S_MAC_FC_CMD, M_MAC_FC_CMD)
+
+#define S_MAC_RX_CH_SEL _SB_MAKE64(57)
+#define M_MAC_RX_CH_SEL _SB_MAKEMASK(7, S_MAC_RX_CH_SEL)
+#define V_MAC_RX_CH_SEL(x) _SB_MAKEVALUE(x, S_MAC_RX_CH_SEL)
+#define G_MAC_RX_CH_SEL(x) _SB_GETVALUE(x, S_MAC_RX_CH_SEL, M_MAC_RX_CH_SEL)
+
+
+/*
+ * MAC Enable Registers
+ * Register: MAC_ENABLE_0
+ * Register: MAC_ENABLE_1
+ * Register: MAC_ENABLE_2
+ */
+
+#define M_MAC_RXDMA_EN0 _SB_MAKEMASK1(0)
+#define M_MAC_RXDMA_EN1 _SB_MAKEMASK1(1)
+#define M_MAC_TXDMA_EN0 _SB_MAKEMASK1(4)
+#define M_MAC_TXDMA_EN1 _SB_MAKEMASK1(5)
+
+#define M_MAC_PORT_RESET _SB_MAKEMASK1(8)
+
+#if (SIBYTE_HDR_FEATURE_CHIP(1250) || SIBYTE_HDR_FEATURE_CHIP(112x))
+#define M_MAC_RX_ENABLE _SB_MAKEMASK1(10)
+#define M_MAC_TX_ENABLE _SB_MAKEMASK1(11)
+#define M_MAC_BYP_RX_ENABLE _SB_MAKEMASK1(12)
+#define M_MAC_BYP_TX_ENABLE _SB_MAKEMASK1(13)
+#endif
+
+/*
+ * MAC reset information register (1280/1255)
+ */
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_RX_CH0_PAUSE_ON _SB_MAKEMASK1(8)
+#define M_MAC_RX_CH1_PAUSE_ON _SB_MAKEMASK1(16)
+#define M_MAC_TX_CH0_PAUSE_ON _SB_MAKEMASK1(24)
+#define M_MAC_TX_CH1_PAUSE_ON _SB_MAKEMASK1(32)
+#endif
+
+/*
+ * MAC DMA Control Register
+ * Register: MAC_TXD_CTL_0
+ * Register: MAC_TXD_CTL_1
+ * Register: MAC_TXD_CTL_2
+ */
+
+#define S_MAC_TXD_WEIGHT0 _SB_MAKE64(0)
+#define M_MAC_TXD_WEIGHT0 _SB_MAKEMASK(4, S_MAC_TXD_WEIGHT0)
+#define V_MAC_TXD_WEIGHT0(x) _SB_MAKEVALUE(x, S_MAC_TXD_WEIGHT0)
+#define G_MAC_TXD_WEIGHT0(x) _SB_GETVALUE(x, S_MAC_TXD_WEIGHT0, M_MAC_TXD_WEIGHT0)
+
+#define S_MAC_TXD_WEIGHT1 _SB_MAKE64(4)
+#define M_MAC_TXD_WEIGHT1 _SB_MAKEMASK(4, S_MAC_TXD_WEIGHT1)
+#define V_MAC_TXD_WEIGHT1(x) _SB_MAKEVALUE(x, S_MAC_TXD_WEIGHT1)
+#define G_MAC_TXD_WEIGHT1(x) _SB_GETVALUE(x, S_MAC_TXD_WEIGHT1, M_MAC_TXD_WEIGHT1)
+
+/*
+ * MAC Fifo Threshold registers (Table 9-14)
+ * Register: MAC_THRSH_CFG_0
+ * Register: MAC_THRSH_CFG_1
+ * Register: MAC_THRSH_CFG_2
+ */
+
+#define S_MAC_TX_WR_THRSH _SB_MAKE64(0)
+#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1)
+/* XXX: Can't enable, as it has the same name as a pass2+ define below. */
+/* #define M_MAC_TX_WR_THRSH _SB_MAKEMASK(6, S_MAC_TX_WR_THRSH) */
+#endif /* up to 1250 PASS1 */
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_TX_WR_THRSH _SB_MAKEMASK(7, S_MAC_TX_WR_THRSH)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+#define V_MAC_TX_WR_THRSH(x) _SB_MAKEVALUE(x, S_MAC_TX_WR_THRSH)
+#define G_MAC_TX_WR_THRSH(x) _SB_GETVALUE(x, S_MAC_TX_WR_THRSH, M_MAC_TX_WR_THRSH)
+
+#define S_MAC_TX_RD_THRSH _SB_MAKE64(8)
+#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1)
+/* XXX: Can't enable, as it has the same name as a pass2+ define below. */
+/* #define M_MAC_TX_RD_THRSH _SB_MAKEMASK(6, S_MAC_TX_RD_THRSH) */
+#endif /* up to 1250 PASS1 */
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_TX_RD_THRSH _SB_MAKEMASK(7, S_MAC_TX_RD_THRSH)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+#define V_MAC_TX_RD_THRSH(x) _SB_MAKEVALUE(x, S_MAC_TX_RD_THRSH)
+#define G_MAC_TX_RD_THRSH(x) _SB_GETVALUE(x, S_MAC_TX_RD_THRSH, M_MAC_TX_RD_THRSH)
+
+#define S_MAC_TX_RL_THRSH _SB_MAKE64(16)
+#define M_MAC_TX_RL_THRSH _SB_MAKEMASK(4, S_MAC_TX_RL_THRSH)
+#define V_MAC_TX_RL_THRSH(x) _SB_MAKEVALUE(x, S_MAC_TX_RL_THRSH)
+#define G_MAC_TX_RL_THRSH(x) _SB_GETVALUE(x, S_MAC_TX_RL_THRSH, M_MAC_TX_RL_THRSH)
+
+#define S_MAC_RX_PL_THRSH _SB_MAKE64(24)
+#define M_MAC_RX_PL_THRSH _SB_MAKEMASK(6, S_MAC_RX_PL_THRSH)
+#define V_MAC_RX_PL_THRSH(x) _SB_MAKEVALUE(x, S_MAC_RX_PL_THRSH)
+#define G_MAC_RX_PL_THRSH(x) _SB_GETVALUE(x, S_MAC_RX_PL_THRSH, M_MAC_RX_PL_THRSH)
+
+#define S_MAC_RX_RD_THRSH _SB_MAKE64(32)
+#define M_MAC_RX_RD_THRSH _SB_MAKEMASK(6, S_MAC_RX_RD_THRSH)
+#define V_MAC_RX_RD_THRSH(x) _SB_MAKEVALUE(x, S_MAC_RX_RD_THRSH)
+#define G_MAC_RX_RD_THRSH(x) _SB_GETVALUE(x, S_MAC_RX_RD_THRSH, M_MAC_RX_RD_THRSH)
+
+#define S_MAC_RX_RL_THRSH _SB_MAKE64(40)
+#define M_MAC_RX_RL_THRSH _SB_MAKEMASK(6, S_MAC_RX_RL_THRSH)
+#define V_MAC_RX_RL_THRSH(x) _SB_MAKEVALUE(x, S_MAC_RX_RL_THRSH)
+#define G_MAC_RX_RL_THRSH(x) _SB_GETVALUE(x, S_MAC_RX_RL_THRSH, M_MAC_RX_RL_THRSH)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_MAC_ENC_FC_THRSH _SB_MAKE64(56)
+#define M_MAC_ENC_FC_THRSH _SB_MAKEMASK(6, S_MAC_ENC_FC_THRSH)
+#define V_MAC_ENC_FC_THRSH(x) _SB_MAKEVALUE(x, S_MAC_ENC_FC_THRSH)
+#define G_MAC_ENC_FC_THRSH(x) _SB_GETVALUE(x, S_MAC_ENC_FC_THRSH, M_MAC_ENC_FC_THRSH)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+/*
+ * MAC Frame Configuration Registers (Table 9-15)
+ * Register: MAC_FRAME_CFG_0
+ * Register: MAC_FRAME_CFG_1
+ * Register: MAC_FRAME_CFG_2
+ */
+
+/* XXXCGD: ??? Unused in pass2? */
+#define S_MAC_IFG_RX _SB_MAKE64(0)
+#define M_MAC_IFG_RX _SB_MAKEMASK(6, S_MAC_IFG_RX)
+#define V_MAC_IFG_RX(x) _SB_MAKEVALUE(x, S_MAC_IFG_RX)
+#define G_MAC_IFG_RX(x) _SB_GETVALUE(x, S_MAC_IFG_RX, M_MAC_IFG_RX)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_MAC_PRE_LEN _SB_MAKE64(0)
+#define M_MAC_PRE_LEN _SB_MAKEMASK(6, S_MAC_PRE_LEN)
+#define V_MAC_PRE_LEN(x) _SB_MAKEVALUE(x, S_MAC_PRE_LEN)
+#define G_MAC_PRE_LEN(x) _SB_GETVALUE(x, S_MAC_PRE_LEN, M_MAC_PRE_LEN)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define S_MAC_IFG_TX _SB_MAKE64(6)
+#define M_MAC_IFG_TX _SB_MAKEMASK(6, S_MAC_IFG_TX)
+#define V_MAC_IFG_TX(x) _SB_MAKEVALUE(x, S_MAC_IFG_TX)
+#define G_MAC_IFG_TX(x) _SB_GETVALUE(x, S_MAC_IFG_TX, M_MAC_IFG_TX)
+
+#define S_MAC_IFG_THRSH _SB_MAKE64(12)
+#define M_MAC_IFG_THRSH _SB_MAKEMASK(6, S_MAC_IFG_THRSH)
+#define V_MAC_IFG_THRSH(x) _SB_MAKEVALUE(x, S_MAC_IFG_THRSH)
+#define G_MAC_IFG_THRSH(x) _SB_GETVALUE(x, S_MAC_IFG_THRSH, M_MAC_IFG_THRSH)
+
+#define S_MAC_BACKOFF_SEL _SB_MAKE64(18)
+#define M_MAC_BACKOFF_SEL _SB_MAKEMASK(4, S_MAC_BACKOFF_SEL)
+#define V_MAC_BACKOFF_SEL(x) _SB_MAKEVALUE(x, S_MAC_BACKOFF_SEL)
+#define G_MAC_BACKOFF_SEL(x) _SB_GETVALUE(x, S_MAC_BACKOFF_SEL, M_MAC_BACKOFF_SEL)
+
+#define S_MAC_LFSR_SEED _SB_MAKE64(22)
+#define M_MAC_LFSR_SEED _SB_MAKEMASK(8, S_MAC_LFSR_SEED)
+#define V_MAC_LFSR_SEED(x) _SB_MAKEVALUE(x, S_MAC_LFSR_SEED)
+#define G_MAC_LFSR_SEED(x) _SB_GETVALUE(x, S_MAC_LFSR_SEED, M_MAC_LFSR_SEED)
+
+#define S_MAC_SLOT_SIZE _SB_MAKE64(30)
+#define M_MAC_SLOT_SIZE _SB_MAKEMASK(10, S_MAC_SLOT_SIZE)
+#define V_MAC_SLOT_SIZE(x) _SB_MAKEVALUE(x, S_MAC_SLOT_SIZE)
+#define G_MAC_SLOT_SIZE(x) _SB_GETVALUE(x, S_MAC_SLOT_SIZE, M_MAC_SLOT_SIZE)
+
+#define S_MAC_MIN_FRAMESZ _SB_MAKE64(40)
+#define M_MAC_MIN_FRAMESZ _SB_MAKEMASK(8, S_MAC_MIN_FRAMESZ)
+#define V_MAC_MIN_FRAMESZ(x) _SB_MAKEVALUE(x, S_MAC_MIN_FRAMESZ)
+#define G_MAC_MIN_FRAMESZ(x) _SB_GETVALUE(x, S_MAC_MIN_FRAMESZ, M_MAC_MIN_FRAMESZ)
+
+#define S_MAC_MAX_FRAMESZ _SB_MAKE64(48)
+#define M_MAC_MAX_FRAMESZ _SB_MAKEMASK(16, S_MAC_MAX_FRAMESZ)
+#define V_MAC_MAX_FRAMESZ(x) _SB_MAKEVALUE(x, S_MAC_MAX_FRAMESZ)
+#define G_MAC_MAX_FRAMESZ(x) _SB_GETVALUE(x, S_MAC_MAX_FRAMESZ, M_MAC_MAX_FRAMESZ)
+
+/*
+ * These constants are used to configure the fields within the Frame
+ * Configuration Register.
+ */
+
+#define K_MAC_IFG_RX_10 _SB_MAKE64(0) /* See table 176, not used */
+#define K_MAC_IFG_RX_100 _SB_MAKE64(0)
+#define K_MAC_IFG_RX_1000 _SB_MAKE64(0)
+
+#define K_MAC_IFG_TX_10 _SB_MAKE64(20)
+#define K_MAC_IFG_TX_100 _SB_MAKE64(20)
+#define K_MAC_IFG_TX_1000 _SB_MAKE64(8)
+
+#define K_MAC_IFG_THRSH_10 _SB_MAKE64(4)
+#define K_MAC_IFG_THRSH_100 _SB_MAKE64(4)
+#define K_MAC_IFG_THRSH_1000 _SB_MAKE64(0)
+
+#define K_MAC_SLOT_SIZE_10 _SB_MAKE64(0)
+#define K_MAC_SLOT_SIZE_100 _SB_MAKE64(0)
+#define K_MAC_SLOT_SIZE_1000 _SB_MAKE64(0)
+
+#define V_MAC_IFG_RX_10 V_MAC_IFG_RX(K_MAC_IFG_RX_10)
+#define V_MAC_IFG_RX_100 V_MAC_IFG_RX(K_MAC_IFG_RX_100)
+#define V_MAC_IFG_RX_1000 V_MAC_IFG_RX(K_MAC_IFG_RX_1000)
+
+#define V_MAC_IFG_TX_10 V_MAC_IFG_TX(K_MAC_IFG_TX_10)
+#define V_MAC_IFG_TX_100 V_MAC_IFG_TX(K_MAC_IFG_TX_100)
+#define V_MAC_IFG_TX_1000 V_MAC_IFG_TX(K_MAC_IFG_TX_1000)
+
+#define V_MAC_IFG_THRSH_10 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_10)
+#define V_MAC_IFG_THRSH_100 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_100)
+#define V_MAC_IFG_THRSH_1000 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_1000)
+
+#define V_MAC_SLOT_SIZE_10 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_10)
+#define V_MAC_SLOT_SIZE_100 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_100)
+#define V_MAC_SLOT_SIZE_1000 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_1000)
+
+#define K_MAC_MIN_FRAMESZ_FIFO _SB_MAKE64(9)
+#define K_MAC_MIN_FRAMESZ_DEFAULT _SB_MAKE64(64)
+#define K_MAC_MAX_FRAMESZ_DEFAULT _SB_MAKE64(1518)
+#define K_MAC_MAX_FRAMESZ_JUMBO _SB_MAKE64(9216)
+
+#define V_MAC_MIN_FRAMESZ_FIFO V_MAC_MIN_FRAMESZ(K_MAC_MIN_FRAMESZ_FIFO)
+#define V_MAC_MIN_FRAMESZ_DEFAULT V_MAC_MIN_FRAMESZ(K_MAC_MIN_FRAMESZ_DEFAULT)
+#define V_MAC_MAX_FRAMESZ_DEFAULT V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_DEFAULT)
+#define V_MAC_MAX_FRAMESZ_JUMBO V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_JUMBO)
+
+/*
+ * MAC VLAN Tag Registers (Table 9-16)
+ * Register: MAC_VLANTAG_0
+ * Register: MAC_VLANTAG_1
+ * Register: MAC_VLANTAG_2
+ */
+
+#define S_MAC_VLAN_TAG _SB_MAKE64(0)
+#define M_MAC_VLAN_TAG _SB_MAKEMASK(32, S_MAC_VLAN_TAG)
+#define V_MAC_VLAN_TAG(x) _SB_MAKEVALUE(x, S_MAC_VLAN_TAG)
+#define G_MAC_VLAN_TAG(x) _SB_GETVALUE(x, S_MAC_VLAN_TAG, M_MAC_VLAN_TAG)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define S_MAC_TX_PKT_OFFSET _SB_MAKE64(32)
+#define M_MAC_TX_PKT_OFFSET _SB_MAKEMASK(8, S_MAC_TX_PKT_OFFSET)
+#define V_MAC_TX_PKT_OFFSET(x) _SB_MAKEVALUE(x, S_MAC_TX_PKT_OFFSET)
+#define G_MAC_TX_PKT_OFFSET(x) _SB_GETVALUE(x, S_MAC_TX_PKT_OFFSET, M_MAC_TX_PKT_OFFSET)
+
+#define S_MAC_TX_CRC_OFFSET _SB_MAKE64(40)
+#define M_MAC_TX_CRC_OFFSET _SB_MAKEMASK(8, S_MAC_TX_CRC_OFFSET)
+#define V_MAC_TX_CRC_OFFSET(x) _SB_MAKEVALUE(x, S_MAC_TX_CRC_OFFSET)
+#define G_MAC_TX_CRC_OFFSET(x) _SB_GETVALUE(x, S_MAC_TX_CRC_OFFSET, M_MAC_TX_CRC_OFFSET)
+
+#define M_MAC_CH_BASE_FC_EN _SB_MAKEMASK1(48)
+#endif /* 1250 PASS3 || 112x PASS1 */
+
+/*
+ * MAC Status Registers (Table 9-17)
+ * Also used for the MAC Interrupt Mask Register (Table 9-18)
+ * Register: MAC_STATUS_0
+ * Register: MAC_STATUS_1
+ * Register: MAC_STATUS_2
+ * Register: MAC_INT_MASK_0
+ * Register: MAC_INT_MASK_1
+ * Register: MAC_INT_MASK_2
+ */
+
+/*
+ * Use these constants to shift the appropriate channel
+ * into the CH0 position so the same tests can be used
+ * on each channel.
+ */
+
+#define S_MAC_RX_CH0 _SB_MAKE64(0)
+#define S_MAC_RX_CH1 _SB_MAKE64(8)
+#define S_MAC_TX_CH0 _SB_MAKE64(16)
+#define S_MAC_TX_CH1 _SB_MAKE64(24)
+
+#define S_MAC_TXCHANNELS _SB_MAKE64(16) /* this is 1st TX chan */
+#define S_MAC_CHANWIDTH _SB_MAKE64(8) /* bits between channels */
+
+/*
+ * These are the same as RX channel 0. The idea here
+ * is that you'll use one of the "S_" things above
+ * and pass just the six bits to a DMA-channel-specific ISR
+ */
+#define M_MAC_INT_CHANNEL _SB_MAKEMASK(8, 0)
+#define M_MAC_INT_EOP_COUNT _SB_MAKEMASK1(0)
+#define M_MAC_INT_EOP_TIMER _SB_MAKEMASK1(1)
+#define M_MAC_INT_EOP_SEEN _SB_MAKEMASK1(2)
+#define M_MAC_INT_HWM _SB_MAKEMASK1(3)
+#define M_MAC_INT_LWM _SB_MAKEMASK1(4)
+#define M_MAC_INT_DSCR _SB_MAKEMASK1(5)
+#define M_MAC_INT_ERR _SB_MAKEMASK1(6)
+#define M_MAC_INT_DZERO _SB_MAKEMASK1(7) /* only for TX channels */
+#define M_MAC_INT_DROP _SB_MAKEMASK1(7) /* only for RX channels */
+
+/*
+ * In the following definitions we use ch (0/1) and txrx (TX=1, RX=0, see
+ * also DMA_TX/DMA_RX in sb_regs.h).
+ */
+#define S_MAC_STATUS_CH_OFFSET(ch, txrx) _SB_MAKE64(((ch) + 2 * (txrx)) * S_MAC_CHANWIDTH)
+
+#define M_MAC_STATUS_CHANNEL(ch, txrx) _SB_MAKEVALUE(_SB_MAKEMASK(8, 0), S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_EOP_COUNT(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_COUNT, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_EOP_TIMER(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_TIMER, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_EOP_SEEN(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_SEEN, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_HWM(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_HWM, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_LWM(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_LWM, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_DSCR(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_DSCR, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_ERR(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_ERR, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_DZERO(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_DZERO, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_DROP(ch, txrx) _SB_MAKEVALUE(M_MAC_INT_DROP, S_MAC_STATUS_CH_OFFSET(ch, txrx))
+#define M_MAC_STATUS_OTHER_ERR _SB_MAKEVALUE(_SB_MAKEMASK(7, 0), 40)
+
+
+#define M_MAC_RX_UNDRFL _SB_MAKEMASK1(40)
+#define M_MAC_RX_OVRFL _SB_MAKEMASK1(41)
+#define M_MAC_TX_UNDRFL _SB_MAKEMASK1(42)
+#define M_MAC_TX_OVRFL _SB_MAKEMASK1(43)
+#define M_MAC_LTCOL_ERR _SB_MAKEMASK1(44)
+#define M_MAC_EXCOL_ERR _SB_MAKEMASK1(45)
+#define M_MAC_CNTR_OVRFL_ERR _SB_MAKEMASK1(46)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_SPLIT_EN _SB_MAKEMASK1(47) /* interrupt mask only */
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#define S_MAC_COUNTER_ADDR _SB_MAKE64(47)
+#define M_MAC_COUNTER_ADDR _SB_MAKEMASK(5, S_MAC_COUNTER_ADDR)
+#define V_MAC_COUNTER_ADDR(x) _SB_MAKEVALUE(x, S_MAC_COUNTER_ADDR)
+#define G_MAC_COUNTER_ADDR(x) _SB_GETVALUE(x, S_MAC_COUNTER_ADDR, M_MAC_COUNTER_ADDR)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_TX_PAUSE_ON _SB_MAKEMASK1(52)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+/*
+ * MAC Fifo Pointer Registers (Table 9-19) [Debug register]
+ * Register: MAC_FIFO_PTRS_0
+ * Register: MAC_FIFO_PTRS_1
+ * Register: MAC_FIFO_PTRS_2
+ */
+
+#define S_MAC_TX_WRPTR _SB_MAKE64(0)
+#define M_MAC_TX_WRPTR _SB_MAKEMASK(6, S_MAC_TX_WRPTR)
+#define V_MAC_TX_WRPTR(x) _SB_MAKEVALUE(x, S_MAC_TX_WRPTR)
+#define G_MAC_TX_WRPTR(x) _SB_GETVALUE(x, S_MAC_TX_WRPTR, M_MAC_TX_WRPTR)
+
+#define S_MAC_TX_RDPTR _SB_MAKE64(8)
+#define M_MAC_TX_RDPTR _SB_MAKEMASK(6, S_MAC_TX_RDPTR)
+#define V_MAC_TX_RDPTR(x) _SB_MAKEVALUE(x, S_MAC_TX_RDPTR)
+#define G_MAC_TX_RDPTR(x) _SB_GETVALUE(x, S_MAC_TX_RDPTR, M_MAC_TX_RDPTR)
+
+#define S_MAC_RX_WRPTR _SB_MAKE64(16)
+#define M_MAC_RX_WRPTR _SB_MAKEMASK(6, S_MAC_RX_WRPTR)
+#define V_MAC_RX_WRPTR(x) _SB_MAKEVALUE(x, S_MAC_RX_WRPTR)
+#define G_MAC_RX_WRPTR(x) _SB_GETVALUE(x, S_MAC_RX_WRPTR, M_MAC_TX_WRPTR)
+
+#define S_MAC_RX_RDPTR _SB_MAKE64(24)
+#define M_MAC_RX_RDPTR _SB_MAKEMASK(6, S_MAC_RX_RDPTR)
+#define V_MAC_RX_RDPTR(x) _SB_MAKEVALUE(x, S_MAC_RX_RDPTR)
+#define G_MAC_RX_RDPTR(x) _SB_GETVALUE(x, S_MAC_RX_RDPTR, M_MAC_TX_RDPTR)
+
+/*
+ * MAC Fifo End Of Packet Count Registers (Table 9-20) [Debug register]
+ * Register: MAC_EOPCNT_0
+ * Register: MAC_EOPCNT_1
+ * Register: MAC_EOPCNT_2
+ */
+
+#define S_MAC_TX_EOP_COUNTER _SB_MAKE64(0)
+#define M_MAC_TX_EOP_COUNTER _SB_MAKEMASK(6, S_MAC_TX_EOP_COUNTER)
+#define V_MAC_TX_EOP_COUNTER(x) _SB_MAKEVALUE(x, S_MAC_TX_EOP_COUNTER)
+#define G_MAC_TX_EOP_COUNTER(x) _SB_GETVALUE(x, S_MAC_TX_EOP_COUNTER, M_MAC_TX_EOP_COUNTER)
+
+#define S_MAC_RX_EOP_COUNTER _SB_MAKE64(8)
+#define M_MAC_RX_EOP_COUNTER _SB_MAKEMASK(6, S_MAC_RX_EOP_COUNTER)
+#define V_MAC_RX_EOP_COUNTER(x) _SB_MAKEVALUE(x, S_MAC_RX_EOP_COUNTER)
+#define G_MAC_RX_EOP_COUNTER(x) _SB_GETVALUE(x, S_MAC_RX_EOP_COUNTER, M_MAC_RX_EOP_COUNTER)
+
+/*
+ * MAC Receive Address Filter Exact Match Registers (Table 9-21)
+ * Registers: MAC_ADDR0_0 through MAC_ADDR7_0
+ * Registers: MAC_ADDR0_1 through MAC_ADDR7_1
+ * Registers: MAC_ADDR0_2 through MAC_ADDR7_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Receive Address Filter Mask Registers
+ * Registers: MAC_ADDRMASK0_0 and MAC_ADDRMASK0_1
+ * Registers: MAC_ADDRMASK1_0 and MAC_ADDRMASK1_1
+ * Registers: MAC_ADDRMASK2_0 and MAC_ADDRMASK2_1
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Receive Address Filter Hash Match Registers (Table 9-22)
+ * Registers: MAC_HASH0_0 through MAC_HASH7_0
+ * Registers: MAC_HASH0_1 through MAC_HASH7_1
+ * Registers: MAC_HASH0_2 through MAC_HASH7_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Transmit Source Address Registers (Table 9-23)
+ * Register: MAC_ETHERNET_ADDR_0
+ * Register: MAC_ETHERNET_ADDR_1
+ * Register: MAC_ETHERNET_ADDR_2
+ */
+
+/* No bitfields */
+
+/*
+ * MAC Packet Type Configuration Register
+ * Register: MAC_TYPE_CFG_0
+ * Register: MAC_TYPE_CFG_1
+ * Register: MAC_TYPE_CFG_2
+ */
+
+#define S_TYPECFG_TYPESIZE _SB_MAKE64(16)
+
+#define S_TYPECFG_TYPE0 _SB_MAKE64(0)
+#define M_TYPECFG_TYPE0 _SB_MAKEMASK(16, S_TYPECFG_TYPE0)
+#define V_TYPECFG_TYPE0(x) _SB_MAKEVALUE(x, S_TYPECFG_TYPE0)
+#define G_TYPECFG_TYPE0(x) _SB_GETVALUE(x, S_TYPECFG_TYPE0, M_TYPECFG_TYPE0)
+
+#define S_TYPECFG_TYPE1 _SB_MAKE64(0)
+#define M_TYPECFG_TYPE1 _SB_MAKEMASK(16, S_TYPECFG_TYPE1)
+#define V_TYPECFG_TYPE1(x) _SB_MAKEVALUE(x, S_TYPECFG_TYPE1)
+#define G_TYPECFG_TYPE1(x) _SB_GETVALUE(x, S_TYPECFG_TYPE1, M_TYPECFG_TYPE1)
+
+#define S_TYPECFG_TYPE2 _SB_MAKE64(0)
+#define M_TYPECFG_TYPE2 _SB_MAKEMASK(16, S_TYPECFG_TYPE2)
+#define V_TYPECFG_TYPE2(x) _SB_MAKEVALUE(x, S_TYPECFG_TYPE2)
+#define G_TYPECFG_TYPE2(x) _SB_GETVALUE(x, S_TYPECFG_TYPE2, M_TYPECFG_TYPE2)
+
+#define S_TYPECFG_TYPE3 _SB_MAKE64(0)
+#define M_TYPECFG_TYPE3 _SB_MAKEMASK(16, S_TYPECFG_TYPE3)
+#define V_TYPECFG_TYPE3(x) _SB_MAKEVALUE(x, S_TYPECFG_TYPE3)
+#define G_TYPECFG_TYPE3(x) _SB_GETVALUE(x, S_TYPECFG_TYPE3, M_TYPECFG_TYPE3)
+
+/*
+ * MAC Receive Address Filter Control Registers (Table 9-24)
+ * Register: MAC_ADFILTER_CFG_0
+ * Register: MAC_ADFILTER_CFG_1
+ * Register: MAC_ADFILTER_CFG_2
+ */
+
+#define M_MAC_ALLPKT_EN _SB_MAKEMASK1(0)
+#define M_MAC_UCAST_EN _SB_MAKEMASK1(1)
+#define M_MAC_UCAST_INV _SB_MAKEMASK1(2)
+#define M_MAC_MCAST_EN _SB_MAKEMASK1(3)
+#define M_MAC_MCAST_INV _SB_MAKEMASK1(4)
+#define M_MAC_BCAST_EN _SB_MAKEMASK1(5)
+#define M_MAC_DIRECT_INV _SB_MAKEMASK1(6)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_MAC_ALLMCAST_EN _SB_MAKEMASK1(7)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#define S_MAC_IPHDR_OFFSET _SB_MAKE64(8)
+#define M_MAC_IPHDR_OFFSET _SB_MAKEMASK(8, S_MAC_IPHDR_OFFSET)
+#define V_MAC_IPHDR_OFFSET(x) _SB_MAKEVALUE(x, S_MAC_IPHDR_OFFSET)
+#define G_MAC_IPHDR_OFFSET(x) _SB_GETVALUE(x, S_MAC_IPHDR_OFFSET, M_MAC_IPHDR_OFFSET)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_MAC_RX_CRC_OFFSET _SB_MAKE64(16)
+#define M_MAC_RX_CRC_OFFSET _SB_MAKEMASK(8, S_MAC_RX_CRC_OFFSET)
+#define V_MAC_RX_CRC_OFFSET(x) _SB_MAKEVALUE(x, S_MAC_RX_CRC_OFFSET)
+#define G_MAC_RX_CRC_OFFSET(x) _SB_GETVALUE(x, S_MAC_RX_CRC_OFFSET, M_MAC_RX_CRC_OFFSET)
+
+#define S_MAC_RX_PKT_OFFSET _SB_MAKE64(24)
+#define M_MAC_RX_PKT_OFFSET _SB_MAKEMASK(8, S_MAC_RX_PKT_OFFSET)
+#define V_MAC_RX_PKT_OFFSET(x) _SB_MAKEVALUE(x, S_MAC_RX_PKT_OFFSET)
+#define G_MAC_RX_PKT_OFFSET(x) _SB_GETVALUE(x, S_MAC_RX_PKT_OFFSET, M_MAC_RX_PKT_OFFSET)
+
+#define M_MAC_FWDPAUSE_EN _SB_MAKEMASK1(32)
+#define M_MAC_VLAN_DET_EN _SB_MAKEMASK1(33)
+
+#define S_MAC_RX_CH_MSN_SEL _SB_MAKE64(34)
+#define M_MAC_RX_CH_MSN_SEL _SB_MAKEMASK(8, S_MAC_RX_CH_MSN_SEL)
+#define V_MAC_RX_CH_MSN_SEL(x) _SB_MAKEVALUE(x, S_MAC_RX_CH_MSN_SEL)
+#define G_MAC_RX_CH_MSN_SEL(x) _SB_GETVALUE(x, S_MAC_RX_CH_MSN_SEL, M_MAC_RX_CH_MSN_SEL)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+/*
+ * MAC Receive Channel Select Registers (Table 9-25)
+ */
+
+/* no bitfields */
+
+/*
+ * MAC MII Management Interface Registers (Table 9-26)
+ * Register: MAC_MDIO_0
+ * Register: MAC_MDIO_1
+ * Register: MAC_MDIO_2
+ */
+
+#define S_MAC_MDC 0
+#define S_MAC_MDIO_DIR 1
+#define S_MAC_MDIO_OUT 2
+#define S_MAC_GENC 3
+#define S_MAC_MDIO_IN 4
+
+#define M_MAC_MDC _SB_MAKEMASK1(S_MAC_MDC)
+#define M_MAC_MDIO_DIR _SB_MAKEMASK1(S_MAC_MDIO_DIR)
+#define M_MAC_MDIO_DIR_INPUT _SB_MAKEMASK1(S_MAC_MDIO_DIR)
+#define M_MAC_MDIO_OUT _SB_MAKEMASK1(S_MAC_MDIO_OUT)
+#define M_MAC_GENC _SB_MAKEMASK1(S_MAC_GENC)
+#define M_MAC_MDIO_IN _SB_MAKEMASK1(S_MAC_MDIO_IN)
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_mc.h b/arch/mips/include/asm/sibyte/sb1250_mc.h
new file mode 100644
index 00000000..1eb1b5a8
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_mc.h
@@ -0,0 +1,550 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Memory Controller constants File: sb1250_mc.h
+ *
+ * This module contains constants and macros useful for
+ * programming the memory controller.
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000, 2001, 2002, 2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_MC_H
+#define _SB1250_MC_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Memory Channel Config Register (table 6-14)
+ */
+
+#define S_MC_RESERVED0 0
+#define M_MC_RESERVED0 _SB_MAKEMASK(8, S_MC_RESERVED0)
+
+#define S_MC_CHANNEL_SEL 8
+#define M_MC_CHANNEL_SEL _SB_MAKEMASK(8, S_MC_CHANNEL_SEL)
+#define V_MC_CHANNEL_SEL(x) _SB_MAKEVALUE(x, S_MC_CHANNEL_SEL)
+#define G_MC_CHANNEL_SEL(x) _SB_GETVALUE(x, S_MC_CHANNEL_SEL, M_MC_CHANNEL_SEL)
+
+#define S_MC_BANK0_MAP 16
+#define M_MC_BANK0_MAP _SB_MAKEMASK(4, S_MC_BANK0_MAP)
+#define V_MC_BANK0_MAP(x) _SB_MAKEVALUE(x, S_MC_BANK0_MAP)
+#define G_MC_BANK0_MAP(x) _SB_GETVALUE(x, S_MC_BANK0_MAP, M_MC_BANK0_MAP)
+
+#define K_MC_BANK0_MAP_DEFAULT 0x00
+#define V_MC_BANK0_MAP_DEFAULT V_MC_BANK0_MAP(K_MC_BANK0_MAP_DEFAULT)
+
+#define S_MC_BANK1_MAP 20
+#define M_MC_BANK1_MAP _SB_MAKEMASK(4, S_MC_BANK1_MAP)
+#define V_MC_BANK1_MAP(x) _SB_MAKEVALUE(x, S_MC_BANK1_MAP)
+#define G_MC_BANK1_MAP(x) _SB_GETVALUE(x, S_MC_BANK1_MAP, M_MC_BANK1_MAP)
+
+#define K_MC_BANK1_MAP_DEFAULT 0x08
+#define V_MC_BANK1_MAP_DEFAULT V_MC_BANK1_MAP(K_MC_BANK1_MAP_DEFAULT)
+
+#define S_MC_BANK2_MAP 24
+#define M_MC_BANK2_MAP _SB_MAKEMASK(4, S_MC_BANK2_MAP)
+#define V_MC_BANK2_MAP(x) _SB_MAKEVALUE(x, S_MC_BANK2_MAP)
+#define G_MC_BANK2_MAP(x) _SB_GETVALUE(x, S_MC_BANK2_MAP, M_MC_BANK2_MAP)
+
+#define K_MC_BANK2_MAP_DEFAULT 0x09
+#define V_MC_BANK2_MAP_DEFAULT V_MC_BANK2_MAP(K_MC_BANK2_MAP_DEFAULT)
+
+#define S_MC_BANK3_MAP 28
+#define M_MC_BANK3_MAP _SB_MAKEMASK(4, S_MC_BANK3_MAP)
+#define V_MC_BANK3_MAP(x) _SB_MAKEVALUE(x, S_MC_BANK3_MAP)
+#define G_MC_BANK3_MAP(x) _SB_GETVALUE(x, S_MC_BANK3_MAP, M_MC_BANK3_MAP)
+
+#define K_MC_BANK3_MAP_DEFAULT 0x0C
+#define V_MC_BANK3_MAP_DEFAULT V_MC_BANK3_MAP(K_MC_BANK3_MAP_DEFAULT)
+
+#define M_MC_RESERVED1 _SB_MAKEMASK(8, 32)
+
+#define S_MC_QUEUE_SIZE 40
+#define M_MC_QUEUE_SIZE _SB_MAKEMASK(4, S_MC_QUEUE_SIZE)
+#define V_MC_QUEUE_SIZE(x) _SB_MAKEVALUE(x, S_MC_QUEUE_SIZE)
+#define G_MC_QUEUE_SIZE(x) _SB_GETVALUE(x, S_MC_QUEUE_SIZE, M_MC_QUEUE_SIZE)
+#define V_MC_QUEUE_SIZE_DEFAULT V_MC_QUEUE_SIZE(0x0A)
+
+#define S_MC_AGE_LIMIT 44
+#define M_MC_AGE_LIMIT _SB_MAKEMASK(4, S_MC_AGE_LIMIT)
+#define V_MC_AGE_LIMIT(x) _SB_MAKEVALUE(x, S_MC_AGE_LIMIT)
+#define G_MC_AGE_LIMIT(x) _SB_GETVALUE(x, S_MC_AGE_LIMIT, M_MC_AGE_LIMIT)
+#define V_MC_AGE_LIMIT_DEFAULT V_MC_AGE_LIMIT(8)
+
+#define S_MC_WR_LIMIT 48
+#define M_MC_WR_LIMIT _SB_MAKEMASK(4, S_MC_WR_LIMIT)
+#define V_MC_WR_LIMIT(x) _SB_MAKEVALUE(x, S_MC_WR_LIMIT)
+#define G_MC_WR_LIMIT(x) _SB_GETVALUE(x, S_MC_WR_LIMIT, M_MC_WR_LIMIT)
+#define V_MC_WR_LIMIT_DEFAULT V_MC_WR_LIMIT(5)
+
+#define M_MC_IOB1HIGHPRIORITY _SB_MAKEMASK1(52)
+
+#define M_MC_RESERVED2 _SB_MAKEMASK(3, 53)
+
+#define S_MC_CS_MODE 56
+#define M_MC_CS_MODE _SB_MAKEMASK(4, S_MC_CS_MODE)
+#define V_MC_CS_MODE(x) _SB_MAKEVALUE(x, S_MC_CS_MODE)
+#define G_MC_CS_MODE(x) _SB_GETVALUE(x, S_MC_CS_MODE, M_MC_CS_MODE)
+
+#define K_MC_CS_MODE_MSB_CS 0
+#define K_MC_CS_MODE_INTLV_CS 15
+#define K_MC_CS_MODE_MIXED_CS_10 12
+#define K_MC_CS_MODE_MIXED_CS_30 6
+#define K_MC_CS_MODE_MIXED_CS_32 3
+
+#define V_MC_CS_MODE_MSB_CS V_MC_CS_MODE(K_MC_CS_MODE_MSB_CS)
+#define V_MC_CS_MODE_INTLV_CS V_MC_CS_MODE(K_MC_CS_MODE_INTLV_CS)
+#define V_MC_CS_MODE_MIXED_CS_10 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_10)
+#define V_MC_CS_MODE_MIXED_CS_30 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_30)
+#define V_MC_CS_MODE_MIXED_CS_32 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_32)
+
+#define M_MC_ECC_DISABLE _SB_MAKEMASK1(60)
+#define M_MC_BERR_DISABLE _SB_MAKEMASK1(61)
+#define M_MC_FORCE_SEQ _SB_MAKEMASK1(62)
+#define M_MC_DEBUG _SB_MAKEMASK1(63)
+
+#define V_MC_CONFIG_DEFAULT V_MC_WR_LIMIT_DEFAULT | V_MC_AGE_LIMIT_DEFAULT | \
+ V_MC_BANK0_MAP_DEFAULT | V_MC_BANK1_MAP_DEFAULT | \
+ V_MC_BANK2_MAP_DEFAULT | V_MC_BANK3_MAP_DEFAULT | V_MC_CHANNEL_SEL(0) | \
+ M_MC_IOB1HIGHPRIORITY | V_MC_QUEUE_SIZE_DEFAULT
+
+
+/*
+ * Memory clock config register (Table 6-15)
+ *
+ * Note: this field has been updated to be consistent with the errata to 0.2
+ */
+
+#define S_MC_CLK_RATIO 0
+#define M_MC_CLK_RATIO _SB_MAKEMASK(4, S_MC_CLK_RATIO)
+#define V_MC_CLK_RATIO(x) _SB_MAKEVALUE(x, S_MC_CLK_RATIO)
+#define G_MC_CLK_RATIO(x) _SB_GETVALUE(x, S_MC_CLK_RATIO, M_MC_CLK_RATIO)
+
+#define K_MC_CLK_RATIO_2X 4
+#define K_MC_CLK_RATIO_25X 5
+#define K_MC_CLK_RATIO_3X 6
+#define K_MC_CLK_RATIO_35X 7
+#define K_MC_CLK_RATIO_4X 8
+#define K_MC_CLK_RATIO_45X 9
+
+#define V_MC_CLK_RATIO_2X V_MC_CLK_RATIO(K_MC_CLK_RATIO_2X)
+#define V_MC_CLK_RATIO_25X V_MC_CLK_RATIO(K_MC_CLK_RATIO_25X)
+#define V_MC_CLK_RATIO_3X V_MC_CLK_RATIO(K_MC_CLK_RATIO_3X)
+#define V_MC_CLK_RATIO_35X V_MC_CLK_RATIO(K_MC_CLK_RATIO_35X)
+#define V_MC_CLK_RATIO_4X V_MC_CLK_RATIO(K_MC_CLK_RATIO_4X)
+#define V_MC_CLK_RATIO_45X V_MC_CLK_RATIO(K_MC_CLK_RATIO_45X)
+#define V_MC_CLK_RATIO_DEFAULT V_MC_CLK_RATIO_25X
+
+#define S_MC_REF_RATE 8
+#define M_MC_REF_RATE _SB_MAKEMASK(8, S_MC_REF_RATE)
+#define V_MC_REF_RATE(x) _SB_MAKEVALUE(x, S_MC_REF_RATE)
+#define G_MC_REF_RATE(x) _SB_GETVALUE(x, S_MC_REF_RATE, M_MC_REF_RATE)
+
+#define K_MC_REF_RATE_100MHz 0x62
+#define K_MC_REF_RATE_133MHz 0x81
+#define K_MC_REF_RATE_200MHz 0xC4
+
+#define V_MC_REF_RATE_100MHz V_MC_REF_RATE(K_MC_REF_RATE_100MHz)
+#define V_MC_REF_RATE_133MHz V_MC_REF_RATE(K_MC_REF_RATE_133MHz)
+#define V_MC_REF_RATE_200MHz V_MC_REF_RATE(K_MC_REF_RATE_200MHz)
+#define V_MC_REF_RATE_DEFAULT V_MC_REF_RATE_100MHz
+
+#define S_MC_CLOCK_DRIVE 16
+#define M_MC_CLOCK_DRIVE _SB_MAKEMASK(4, S_MC_CLOCK_DRIVE)
+#define V_MC_CLOCK_DRIVE(x) _SB_MAKEVALUE(x, S_MC_CLOCK_DRIVE)
+#define G_MC_CLOCK_DRIVE(x) _SB_GETVALUE(x, S_MC_CLOCK_DRIVE, M_MC_CLOCK_DRIVE)
+#define V_MC_CLOCK_DRIVE_DEFAULT V_MC_CLOCK_DRIVE(0xF)
+
+#define S_MC_DATA_DRIVE 20
+#define M_MC_DATA_DRIVE _SB_MAKEMASK(4, S_MC_DATA_DRIVE)
+#define V_MC_DATA_DRIVE(x) _SB_MAKEVALUE(x, S_MC_DATA_DRIVE)
+#define G_MC_DATA_DRIVE(x) _SB_GETVALUE(x, S_MC_DATA_DRIVE, M_MC_DATA_DRIVE)
+#define V_MC_DATA_DRIVE_DEFAULT V_MC_DATA_DRIVE(0x0)
+
+#define S_MC_ADDR_DRIVE 24
+#define M_MC_ADDR_DRIVE _SB_MAKEMASK(4, S_MC_ADDR_DRIVE)
+#define V_MC_ADDR_DRIVE(x) _SB_MAKEVALUE(x, S_MC_ADDR_DRIVE)
+#define G_MC_ADDR_DRIVE(x) _SB_GETVALUE(x, S_MC_ADDR_DRIVE, M_MC_ADDR_DRIVE)
+#define V_MC_ADDR_DRIVE_DEFAULT V_MC_ADDR_DRIVE(0x0)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define M_MC_REF_DISABLE _SB_MAKEMASK1(30)
+#endif /* 1250 PASS3 || 112x PASS1 */
+
+#define M_MC_DLL_BYPASS _SB_MAKEMASK1(31)
+
+#define S_MC_DQI_SKEW 32
+#define M_MC_DQI_SKEW _SB_MAKEMASK(8, S_MC_DQI_SKEW)
+#define V_MC_DQI_SKEW(x) _SB_MAKEVALUE(x, S_MC_DQI_SKEW)
+#define G_MC_DQI_SKEW(x) _SB_GETVALUE(x, S_MC_DQI_SKEW, M_MC_DQI_SKEW)
+#define V_MC_DQI_SKEW_DEFAULT V_MC_DQI_SKEW(0)
+
+#define S_MC_DQO_SKEW 40
+#define M_MC_DQO_SKEW _SB_MAKEMASK(8, S_MC_DQO_SKEW)
+#define V_MC_DQO_SKEW(x) _SB_MAKEVALUE(x, S_MC_DQO_SKEW)
+#define G_MC_DQO_SKEW(x) _SB_GETVALUE(x, S_MC_DQO_SKEW, M_MC_DQO_SKEW)
+#define V_MC_DQO_SKEW_DEFAULT V_MC_DQO_SKEW(0)
+
+#define S_MC_ADDR_SKEW 48
+#define M_MC_ADDR_SKEW _SB_MAKEMASK(8, S_MC_ADDR_SKEW)
+#define V_MC_ADDR_SKEW(x) _SB_MAKEVALUE(x, S_MC_ADDR_SKEW)
+#define G_MC_ADDR_SKEW(x) _SB_GETVALUE(x, S_MC_ADDR_SKEW, M_MC_ADDR_SKEW)
+#define V_MC_ADDR_SKEW_DEFAULT V_MC_ADDR_SKEW(0x0F)
+
+#define S_MC_DLL_DEFAULT 56
+#define M_MC_DLL_DEFAULT _SB_MAKEMASK(8, S_MC_DLL_DEFAULT)
+#define V_MC_DLL_DEFAULT(x) _SB_MAKEVALUE(x, S_MC_DLL_DEFAULT)
+#define G_MC_DLL_DEFAULT(x) _SB_GETVALUE(x, S_MC_DLL_DEFAULT, M_MC_DLL_DEFAULT)
+#define V_MC_DLL_DEFAULT_DEFAULT V_MC_DLL_DEFAULT(0x10)
+
+#define V_MC_CLKCONFIG_DEFAULT V_MC_DLL_DEFAULT_DEFAULT | \
+ V_MC_ADDR_SKEW_DEFAULT | \
+ V_MC_DQO_SKEW_DEFAULT | \
+ V_MC_DQI_SKEW_DEFAULT | \
+ V_MC_ADDR_DRIVE_DEFAULT | \
+ V_MC_DATA_DRIVE_DEFAULT | \
+ V_MC_CLOCK_DRIVE_DEFAULT | \
+ V_MC_REF_RATE_DEFAULT
+
+
+
+/*
+ * DRAM Command Register (Table 6-13)
+ */
+
+#define S_MC_COMMAND 0
+#define M_MC_COMMAND _SB_MAKEMASK(4, S_MC_COMMAND)
+#define V_MC_COMMAND(x) _SB_MAKEVALUE(x, S_MC_COMMAND)
+#define G_MC_COMMAND(x) _SB_GETVALUE(x, S_MC_COMMAND, M_MC_COMMAND)
+
+#define K_MC_COMMAND_EMRS 0
+#define K_MC_COMMAND_MRS 1
+#define K_MC_COMMAND_PRE 2
+#define K_MC_COMMAND_AR 3
+#define K_MC_COMMAND_SETRFSH 4
+#define K_MC_COMMAND_CLRRFSH 5
+#define K_MC_COMMAND_SETPWRDN 6
+#define K_MC_COMMAND_CLRPWRDN 7
+
+#define V_MC_COMMAND_EMRS V_MC_COMMAND(K_MC_COMMAND_EMRS)
+#define V_MC_COMMAND_MRS V_MC_COMMAND(K_MC_COMMAND_MRS)
+#define V_MC_COMMAND_PRE V_MC_COMMAND(K_MC_COMMAND_PRE)
+#define V_MC_COMMAND_AR V_MC_COMMAND(K_MC_COMMAND_AR)
+#define V_MC_COMMAND_SETRFSH V_MC_COMMAND(K_MC_COMMAND_SETRFSH)
+#define V_MC_COMMAND_CLRRFSH V_MC_COMMAND(K_MC_COMMAND_CLRRFSH)
+#define V_MC_COMMAND_SETPWRDN V_MC_COMMAND(K_MC_COMMAND_SETPWRDN)
+#define V_MC_COMMAND_CLRPWRDN V_MC_COMMAND(K_MC_COMMAND_CLRPWRDN)
+
+#define M_MC_CS0 _SB_MAKEMASK1(4)
+#define M_MC_CS1 _SB_MAKEMASK1(5)
+#define M_MC_CS2 _SB_MAKEMASK1(6)
+#define M_MC_CS3 _SB_MAKEMASK1(7)
+
+/*
+ * DRAM Mode Register (Table 6-14)
+ */
+
+#define S_MC_EMODE 0
+#define M_MC_EMODE _SB_MAKEMASK(15, S_MC_EMODE)
+#define V_MC_EMODE(x) _SB_MAKEVALUE(x, S_MC_EMODE)
+#define G_MC_EMODE(x) _SB_GETVALUE(x, S_MC_EMODE, M_MC_EMODE)
+#define V_MC_EMODE_DEFAULT V_MC_EMODE(0)
+
+#define S_MC_MODE 16
+#define M_MC_MODE _SB_MAKEMASK(15, S_MC_MODE)
+#define V_MC_MODE(x) _SB_MAKEVALUE(x, S_MC_MODE)
+#define G_MC_MODE(x) _SB_GETVALUE(x, S_MC_MODE, M_MC_MODE)
+#define V_MC_MODE_DEFAULT V_MC_MODE(0x22)
+
+#define S_MC_DRAM_TYPE 32
+#define M_MC_DRAM_TYPE _SB_MAKEMASK(3, S_MC_DRAM_TYPE)
+#define V_MC_DRAM_TYPE(x) _SB_MAKEVALUE(x, S_MC_DRAM_TYPE)
+#define G_MC_DRAM_TYPE(x) _SB_GETVALUE(x, S_MC_DRAM_TYPE, M_MC_DRAM_TYPE)
+
+#define K_MC_DRAM_TYPE_JEDEC 0
+#define K_MC_DRAM_TYPE_FCRAM 1
+#define K_MC_DRAM_TYPE_SGRAM 2
+
+#define V_MC_DRAM_TYPE_JEDEC V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_JEDEC)
+#define V_MC_DRAM_TYPE_FCRAM V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_FCRAM)
+#define V_MC_DRAM_TYPE_SGRAM V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_SGRAM)
+
+#define M_MC_EXTERNALDECODE _SB_MAKEMASK1(35)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define M_MC_PRE_ON_A8 _SB_MAKEMASK1(36)
+#define M_MC_RAM_WITH_A13 _SB_MAKEMASK1(37)
+#endif /* 1250 PASS3 || 112x PASS1 */
+
+
+
+/*
+ * SDRAM Timing Register (Table 6-15)
+ */
+
+#define M_MC_w2rIDLE_TWOCYCLES _SB_MAKEMASK1(60)
+#define M_MC_r2wIDLE_TWOCYCLES _SB_MAKEMASK1(61)
+#define M_MC_r2rIDLE_TWOCYCLES _SB_MAKEMASK1(62)
+
+#define S_MC_tFIFO 56
+#define M_MC_tFIFO _SB_MAKEMASK(4, S_MC_tFIFO)
+#define V_MC_tFIFO(x) _SB_MAKEVALUE(x, S_MC_tFIFO)
+#define G_MC_tFIFO(x) _SB_GETVALUE(x, S_MC_tFIFO, M_MC_tFIFO)
+#define K_MC_tFIFO_DEFAULT 1
+#define V_MC_tFIFO_DEFAULT V_MC_tFIFO(K_MC_tFIFO_DEFAULT)
+
+#define S_MC_tRFC 52
+#define M_MC_tRFC _SB_MAKEMASK(4, S_MC_tRFC)
+#define V_MC_tRFC(x) _SB_MAKEVALUE(x, S_MC_tRFC)
+#define G_MC_tRFC(x) _SB_GETVALUE(x, S_MC_tRFC, M_MC_tRFC)
+#define K_MC_tRFC_DEFAULT 12
+#define V_MC_tRFC_DEFAULT V_MC_tRFC(K_MC_tRFC_DEFAULT)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3)
+#define M_MC_tRFC_PLUS16 _SB_MAKEMASK1(51) /* 1250C3 and later. */
+#endif
+
+#define S_MC_tCwCr 40
+#define M_MC_tCwCr _SB_MAKEMASK(4, S_MC_tCwCr)
+#define V_MC_tCwCr(x) _SB_MAKEVALUE(x, S_MC_tCwCr)
+#define G_MC_tCwCr(x) _SB_GETVALUE(x, S_MC_tCwCr, M_MC_tCwCr)
+#define K_MC_tCwCr_DEFAULT 4
+#define V_MC_tCwCr_DEFAULT V_MC_tCwCr(K_MC_tCwCr_DEFAULT)
+
+#define S_MC_tRCr 28
+#define M_MC_tRCr _SB_MAKEMASK(4, S_MC_tRCr)
+#define V_MC_tRCr(x) _SB_MAKEVALUE(x, S_MC_tRCr)
+#define G_MC_tRCr(x) _SB_GETVALUE(x, S_MC_tRCr, M_MC_tRCr)
+#define K_MC_tRCr_DEFAULT 9
+#define V_MC_tRCr_DEFAULT V_MC_tRCr(K_MC_tRCr_DEFAULT)
+
+#define S_MC_tRCw 24
+#define M_MC_tRCw _SB_MAKEMASK(4, S_MC_tRCw)
+#define V_MC_tRCw(x) _SB_MAKEVALUE(x, S_MC_tRCw)
+#define G_MC_tRCw(x) _SB_GETVALUE(x, S_MC_tRCw, M_MC_tRCw)
+#define K_MC_tRCw_DEFAULT 10
+#define V_MC_tRCw_DEFAULT V_MC_tRCw(K_MC_tRCw_DEFAULT)
+
+#define S_MC_tRRD 20
+#define M_MC_tRRD _SB_MAKEMASK(4, S_MC_tRRD)
+#define V_MC_tRRD(x) _SB_MAKEVALUE(x, S_MC_tRRD)
+#define G_MC_tRRD(x) _SB_GETVALUE(x, S_MC_tRRD, M_MC_tRRD)
+#define K_MC_tRRD_DEFAULT 2
+#define V_MC_tRRD_DEFAULT V_MC_tRRD(K_MC_tRRD_DEFAULT)
+
+#define S_MC_tRP 16
+#define M_MC_tRP _SB_MAKEMASK(4, S_MC_tRP)
+#define V_MC_tRP(x) _SB_MAKEVALUE(x, S_MC_tRP)
+#define G_MC_tRP(x) _SB_GETVALUE(x, S_MC_tRP, M_MC_tRP)
+#define K_MC_tRP_DEFAULT 4
+#define V_MC_tRP_DEFAULT V_MC_tRP(K_MC_tRP_DEFAULT)
+
+#define S_MC_tCwD 8
+#define M_MC_tCwD _SB_MAKEMASK(4, S_MC_tCwD)
+#define V_MC_tCwD(x) _SB_MAKEVALUE(x, S_MC_tCwD)
+#define G_MC_tCwD(x) _SB_GETVALUE(x, S_MC_tCwD, M_MC_tCwD)
+#define K_MC_tCwD_DEFAULT 1
+#define V_MC_tCwD_DEFAULT V_MC_tCwD(K_MC_tCwD_DEFAULT)
+
+#define M_tCrDh _SB_MAKEMASK1(7)
+#define M_MC_tCrDh M_tCrDh
+
+#define S_MC_tCrD 4
+#define M_MC_tCrD _SB_MAKEMASK(3, S_MC_tCrD)
+#define V_MC_tCrD(x) _SB_MAKEVALUE(x, S_MC_tCrD)
+#define G_MC_tCrD(x) _SB_GETVALUE(x, S_MC_tCrD, M_MC_tCrD)
+#define K_MC_tCrD_DEFAULT 2
+#define V_MC_tCrD_DEFAULT V_MC_tCrD(K_MC_tCrD_DEFAULT)
+
+#define S_MC_tRCD 0
+#define M_MC_tRCD _SB_MAKEMASK(4, S_MC_tRCD)
+#define V_MC_tRCD(x) _SB_MAKEVALUE(x, S_MC_tRCD)
+#define G_MC_tRCD(x) _SB_GETVALUE(x, S_MC_tRCD, M_MC_tRCD)
+#define K_MC_tRCD_DEFAULT 3
+#define V_MC_tRCD_DEFAULT V_MC_tRCD(K_MC_tRCD_DEFAULT)
+
+#define V_MC_TIMING_DEFAULT V_MC_tFIFO(K_MC_tFIFO_DEFAULT) | \
+ V_MC_tRFC(K_MC_tRFC_DEFAULT) | \
+ V_MC_tCwCr(K_MC_tCwCr_DEFAULT) | \
+ V_MC_tRCr(K_MC_tRCr_DEFAULT) | \
+ V_MC_tRCw(K_MC_tRCw_DEFAULT) | \
+ V_MC_tRRD(K_MC_tRRD_DEFAULT) | \
+ V_MC_tRP(K_MC_tRP_DEFAULT) | \
+ V_MC_tCwD(K_MC_tCwD_DEFAULT) | \
+ V_MC_tCrD(K_MC_tCrD_DEFAULT) | \
+ V_MC_tRCD(K_MC_tRCD_DEFAULT) | \
+ M_MC_r2rIDLE_TWOCYCLES
+
+/*
+ * Errata says these are not the default
+ * M_MC_w2rIDLE_TWOCYCLES | \
+ * M_MC_r2wIDLE_TWOCYCLES | \
+ */
+
+
+/*
+ * Chip Select Start Address Register (Table 6-17)
+ */
+
+#define S_MC_CS0_START 0
+#define M_MC_CS0_START _SB_MAKEMASK(16, S_MC_CS0_START)
+#define V_MC_CS0_START(x) _SB_MAKEVALUE(x, S_MC_CS0_START)
+#define G_MC_CS0_START(x) _SB_GETVALUE(x, S_MC_CS0_START, M_MC_CS0_START)
+
+#define S_MC_CS1_START 16
+#define M_MC_CS1_START _SB_MAKEMASK(16, S_MC_CS1_START)
+#define V_MC_CS1_START(x) _SB_MAKEVALUE(x, S_MC_CS1_START)
+#define G_MC_CS1_START(x) _SB_GETVALUE(x, S_MC_CS1_START, M_MC_CS1_START)
+
+#define S_MC_CS2_START 32
+#define M_MC_CS2_START _SB_MAKEMASK(16, S_MC_CS2_START)
+#define V_MC_CS2_START(x) _SB_MAKEVALUE(x, S_MC_CS2_START)
+#define G_MC_CS2_START(x) _SB_GETVALUE(x, S_MC_CS2_START, M_MC_CS2_START)
+
+#define S_MC_CS3_START 48
+#define M_MC_CS3_START _SB_MAKEMASK(16, S_MC_CS3_START)
+#define V_MC_CS3_START(x) _SB_MAKEVALUE(x, S_MC_CS3_START)
+#define G_MC_CS3_START(x) _SB_GETVALUE(x, S_MC_CS3_START, M_MC_CS3_START)
+
+/*
+ * Chip Select End Address Register (Table 6-18)
+ */
+
+#define S_MC_CS0_END 0
+#define M_MC_CS0_END _SB_MAKEMASK(16, S_MC_CS0_END)
+#define V_MC_CS0_END(x) _SB_MAKEVALUE(x, S_MC_CS0_END)
+#define G_MC_CS0_END(x) _SB_GETVALUE(x, S_MC_CS0_END, M_MC_CS0_END)
+
+#define S_MC_CS1_END 16
+#define M_MC_CS1_END _SB_MAKEMASK(16, S_MC_CS1_END)
+#define V_MC_CS1_END(x) _SB_MAKEVALUE(x, S_MC_CS1_END)
+#define G_MC_CS1_END(x) _SB_GETVALUE(x, S_MC_CS1_END, M_MC_CS1_END)
+
+#define S_MC_CS2_END 32
+#define M_MC_CS2_END _SB_MAKEMASK(16, S_MC_CS2_END)
+#define V_MC_CS2_END(x) _SB_MAKEVALUE(x, S_MC_CS2_END)
+#define G_MC_CS2_END(x) _SB_GETVALUE(x, S_MC_CS2_END, M_MC_CS2_END)
+
+#define S_MC_CS3_END 48
+#define M_MC_CS3_END _SB_MAKEMASK(16, S_MC_CS3_END)
+#define V_MC_CS3_END(x) _SB_MAKEVALUE(x, S_MC_CS3_END)
+#define G_MC_CS3_END(x) _SB_GETVALUE(x, S_MC_CS3_END, M_MC_CS3_END)
+
+/*
+ * Chip Select Interleave Register (Table 6-19)
+ */
+
+#define S_MC_INTLV_RESERVED 0
+#define M_MC_INTLV_RESERVED _SB_MAKEMASK(5, S_MC_INTLV_RESERVED)
+
+#define S_MC_INTERLEAVE 7
+#define M_MC_INTERLEAVE _SB_MAKEMASK(18, S_MC_INTERLEAVE)
+#define V_MC_INTERLEAVE(x) _SB_MAKEVALUE(x, S_MC_INTERLEAVE)
+
+#define S_MC_INTLV_MBZ 25
+#define M_MC_INTLV_MBZ _SB_MAKEMASK(39, S_MC_INTLV_MBZ)
+
+/*
+ * Row Address Bits Register (Table 6-20)
+ */
+
+#define S_MC_RAS_RESERVED 0
+#define M_MC_RAS_RESERVED _SB_MAKEMASK(5, S_MC_RAS_RESERVED)
+
+#define S_MC_RAS_SELECT 12
+#define M_MC_RAS_SELECT _SB_MAKEMASK(25, S_MC_RAS_SELECT)
+#define V_MC_RAS_SELECT(x) _SB_MAKEVALUE(x, S_MC_RAS_SELECT)
+
+#define S_MC_RAS_MBZ 37
+#define M_MC_RAS_MBZ _SB_MAKEMASK(27, S_MC_RAS_MBZ)
+
+
+/*
+ * Column Address Bits Register (Table 6-21)
+ */
+
+#define S_MC_CAS_RESERVED 0
+#define M_MC_CAS_RESERVED _SB_MAKEMASK(5, S_MC_CAS_RESERVED)
+
+#define S_MC_CAS_SELECT 5
+#define M_MC_CAS_SELECT _SB_MAKEMASK(18, S_MC_CAS_SELECT)
+#define V_MC_CAS_SELECT(x) _SB_MAKEVALUE(x, S_MC_CAS_SELECT)
+
+#define S_MC_CAS_MBZ 23
+#define M_MC_CAS_MBZ _SB_MAKEMASK(41, S_MC_CAS_MBZ)
+
+
+/*
+ * Bank Address Address Bits Register (Table 6-22)
+ */
+
+#define S_MC_BA_RESERVED 0
+#define M_MC_BA_RESERVED _SB_MAKEMASK(5, S_MC_BA_RESERVED)
+
+#define S_MC_BA_SELECT 5
+#define M_MC_BA_SELECT _SB_MAKEMASK(20, S_MC_BA_SELECT)
+#define V_MC_BA_SELECT(x) _SB_MAKEVALUE(x, S_MC_BA_SELECT)
+
+#define S_MC_BA_MBZ 25
+#define M_MC_BA_MBZ _SB_MAKEMASK(39, S_MC_BA_MBZ)
+
+/*
+ * Chip Select Attribute Register (Table 6-23)
+ */
+
+#define K_MC_CS_ATTR_CLOSED 0
+#define K_MC_CS_ATTR_CASCHECK 1
+#define K_MC_CS_ATTR_HINT 2
+#define K_MC_CS_ATTR_OPEN 3
+
+#define S_MC_CS0_PAGE 0
+#define M_MC_CS0_PAGE _SB_MAKEMASK(2, S_MC_CS0_PAGE)
+#define V_MC_CS0_PAGE(x) _SB_MAKEVALUE(x, S_MC_CS0_PAGE)
+#define G_MC_CS0_PAGE(x) _SB_GETVALUE(x, S_MC_CS0_PAGE, M_MC_CS0_PAGE)
+
+#define S_MC_CS1_PAGE 16
+#define M_MC_CS1_PAGE _SB_MAKEMASK(2, S_MC_CS1_PAGE)
+#define V_MC_CS1_PAGE(x) _SB_MAKEVALUE(x, S_MC_CS1_PAGE)
+#define G_MC_CS1_PAGE(x) _SB_GETVALUE(x, S_MC_CS1_PAGE, M_MC_CS1_PAGE)
+
+#define S_MC_CS2_PAGE 32
+#define M_MC_CS2_PAGE _SB_MAKEMASK(2, S_MC_CS2_PAGE)
+#define V_MC_CS2_PAGE(x) _SB_MAKEVALUE(x, S_MC_CS2_PAGE)
+#define G_MC_CS2_PAGE(x) _SB_GETVALUE(x, S_MC_CS2_PAGE, M_MC_CS2_PAGE)
+
+#define S_MC_CS3_PAGE 48
+#define M_MC_CS3_PAGE _SB_MAKEMASK(2, S_MC_CS3_PAGE)
+#define V_MC_CS3_PAGE(x) _SB_MAKEVALUE(x, S_MC_CS3_PAGE)
+#define G_MC_CS3_PAGE(x) _SB_GETVALUE(x, S_MC_CS3_PAGE, M_MC_CS3_PAGE)
+
+/*
+ * ECC Test ECC Register (Table 6-25)
+ */
+
+#define S_MC_ECC_INVERT 0
+#define M_MC_ECC_INVERT _SB_MAKEMASK(8, S_MC_ECC_INVERT)
+
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_regs.h b/arch/mips/include/asm/sibyte/sb1250_regs.h
new file mode 100644
index 00000000..8f53ec81
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_regs.h
@@ -0,0 +1,893 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Register Definitions File: sb1250_regs.h
+ *
+ * This module contains the addresses of the on-chip peripherals
+ * on the SB1250.
+ *
+ * SB1250 specification level: 01/02/2002
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_REGS_H
+#define _SB1250_REGS_H
+
+#include "sb1250_defs.h"
+
+
+/* *********************************************************************
+ * Some general notes:
+ *
+ * For the most part, when there is more than one peripheral
+ * of the same type on the SOC, the constants below will be
+ * offsets from the base of each peripheral. For example,
+ * the MAC registers are described as offsets from the first
+ * MAC register, and there will be a MAC_REGISTER() macro
+ * to calculate the base address of a given MAC.
+ *
+ * The information in this file is based on the SB1250 SOC
+ * manual version 0.2, July 2000.
+ ********************************************************************* */
+
+
+/* *********************************************************************
+ * Memory Controller Registers
+ ********************************************************************* */
+
+/*
+ * XXX: can't remove MC base 0 if 112x, since it's used by other macros,
+ * since there is one reg there (but it could get its addr/offset constant).
+ */
+
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
+#define A_MC_BASE_0 0x0010051000
+#define A_MC_BASE_1 0x0010052000
+#define MC_REGISTER_SPACING 0x1000
+
+#define A_MC_BASE(ctlid) ((ctlid)*MC_REGISTER_SPACING+A_MC_BASE_0)
+#define A_MC_REGISTER(ctlid, reg) (A_MC_BASE(ctlid)+(reg))
+
+#define R_MC_CONFIG 0x0000000100
+#define R_MC_DRAMCMD 0x0000000120
+#define R_MC_DRAMMODE 0x0000000140
+#define R_MC_TIMING1 0x0000000160
+#define R_MC_TIMING2 0x0000000180
+#define R_MC_CS_START 0x00000001A0
+#define R_MC_CS_END 0x00000001C0
+#define R_MC_CS_INTERLEAVE 0x00000001E0
+#define S_MC_CS_STARTEND 16
+
+#define R_MC_CSX_BASE 0x0000000200
+#define R_MC_CSX_ROW 0x0000000000 /* relative to CSX_BASE, above */
+#define R_MC_CSX_COL 0x0000000020 /* relative to CSX_BASE, above */
+#define R_MC_CSX_BA 0x0000000040 /* relative to CSX_BASE, above */
+#define MC_CSX_SPACING 0x0000000060 /* relative to CSX_BASE, above */
+
+#define R_MC_CS0_ROW 0x0000000200
+#define R_MC_CS0_COL 0x0000000220
+#define R_MC_CS0_BA 0x0000000240
+#define R_MC_CS1_ROW 0x0000000260
+#define R_MC_CS1_COL 0x0000000280
+#define R_MC_CS1_BA 0x00000002A0
+#define R_MC_CS2_ROW 0x00000002C0
+#define R_MC_CS2_COL 0x00000002E0
+#define R_MC_CS2_BA 0x0000000300
+#define R_MC_CS3_ROW 0x0000000320
+#define R_MC_CS3_COL 0x0000000340
+#define R_MC_CS3_BA 0x0000000360
+#define R_MC_CS_ATTR 0x0000000380
+#define R_MC_TEST_DATA 0x0000000400
+#define R_MC_TEST_ECC 0x0000000420
+#define R_MC_MCLK_CFG 0x0000000500
+
+#endif /* 1250 & 112x */
+
+/* *********************************************************************
+ * L2 Cache Control Registers
+ ********************************************************************* */
+
+#if SIBYTE_HDR_FEATURE_1250_112x /* This L2C only on 1250/112x */
+
+#define A_L2_READ_TAG 0x0010040018
+#define A_L2_ECC_TAG 0x0010040038
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define A_L2_READ_MISC 0x0010040058
+#endif /* 1250 PASS3 || 112x PASS1 */
+#define A_L2_WAY_DISABLE 0x0010041000
+#define A_L2_MAKEDISABLE(x) (A_L2_WAY_DISABLE | (((~(x))&0x0F) << 8))
+#define A_L2_MGMT_TAG_BASE 0x00D0000000
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define A_L2_CACHE_DISABLE 0x0010042000
+#define A_L2_MAKECACHEDISABLE(x) (A_L2_CACHE_DISABLE | (((x)&0x0F) << 8))
+#define A_L2_MISC_CONFIG 0x0010043000
+#endif /* 1250 PASS2 || 112x PASS1 */
+
+/* Backward-compatibility definitions. */
+/* XXX: discourage people from using these constants. */
+#define A_L2_READ_ADDRESS A_L2_READ_TAG
+#define A_L2_EEC_ADDRESS A_L2_ECC_TAG
+
+#endif
+
+
+/* *********************************************************************
+ * PCI Interface Registers
+ ********************************************************************* */
+
+#if SIBYTE_HDR_FEATURE_1250_112x /* This PCI/HT only on 1250/112x */
+#define A_PCI_TYPE00_HEADER 0x00DE000000
+#define A_PCI_TYPE01_HEADER 0x00DE000800
+#endif
+
+
+/* *********************************************************************
+ * Ethernet DMA and MACs
+ ********************************************************************* */
+
+#define A_MAC_BASE_0 0x0010064000
+#define A_MAC_BASE_1 0x0010065000
+#if SIBYTE_HDR_FEATURE_CHIP(1250)
+#define A_MAC_BASE_2 0x0010066000
+#endif /* 1250 */
+
+#define MAC_SPACING 0x1000
+#define MAC_DMA_TXRX_SPACING 0x0400
+#define MAC_DMA_CHANNEL_SPACING 0x0100
+#define DMA_RX 0
+#define DMA_TX 1
+#define MAC_NUM_DMACHAN 2 /* channels per direction */
+
+/* XXX: not correct; depends on SOC type. */
+#define MAC_NUM_PORTS 3
+
+#define A_MAC_CHANNEL_BASE(macnum) \
+ (A_MAC_BASE_0 + \
+ MAC_SPACING*(macnum))
+
+#define A_MAC_REGISTER(macnum,reg) \
+ (A_MAC_BASE_0 + \
+ MAC_SPACING*(macnum) + (reg))
+
+
+#define R_MAC_DMA_CHANNELS 0x800 /* Relative to A_MAC_CHANNEL_BASE */
+
+#define A_MAC_DMA_CHANNEL_BASE(macnum, txrx, chan) \
+ ((A_MAC_CHANNEL_BASE(macnum)) + \
+ R_MAC_DMA_CHANNELS + \
+ (MAC_DMA_TXRX_SPACING*(txrx)) + \
+ (MAC_DMA_CHANNEL_SPACING*(chan)))
+
+#define R_MAC_DMA_CHANNEL_BASE(txrx, chan) \
+ (R_MAC_DMA_CHANNELS + \
+ (MAC_DMA_TXRX_SPACING*(txrx)) + \
+ (MAC_DMA_CHANNEL_SPACING*(chan)))
+
+#define A_MAC_DMA_REGISTER(macnum, txrx, chan, reg) \
+ (A_MAC_DMA_CHANNEL_BASE(macnum, txrx, chan) + \
+ (reg))
+
+#define R_MAC_DMA_REGISTER(txrx, chan, reg) \
+ (R_MAC_DMA_CHANNEL_BASE(txrx, chan) + \
+ (reg))
+
+/*
+ * DMA channel registers, relative to A_MAC_DMA_CHANNEL_BASE
+ */
+
+#define R_MAC_DMA_CONFIG0 0x00000000
+#define R_MAC_DMA_CONFIG1 0x00000008
+#define R_MAC_DMA_DSCR_BASE 0x00000010
+#define R_MAC_DMA_DSCR_CNT 0x00000018
+#define R_MAC_DMA_CUR_DSCRA 0x00000020
+#define R_MAC_DMA_CUR_DSCRB 0x00000028
+#define R_MAC_DMA_CUR_DSCRADDR 0x00000030
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define R_MAC_DMA_OODPKTLOST_RX 0x00000038 /* rx only */
+#endif /* 1250 PASS3 || 112x PASS1 */
+
+/*
+ * RMON Counters
+ */
+
+#define R_MAC_RMON_TX_BYTES 0x00000000
+#define R_MAC_RMON_COLLISIONS 0x00000008
+#define R_MAC_RMON_LATE_COL 0x00000010
+#define R_MAC_RMON_EX_COL 0x00000018
+#define R_MAC_RMON_FCS_ERROR 0x00000020
+#define R_MAC_RMON_TX_ABORT 0x00000028
+/* Counter #6 (0x30) now reserved */
+#define R_MAC_RMON_TX_BAD 0x00000038
+#define R_MAC_RMON_TX_GOOD 0x00000040
+#define R_MAC_RMON_TX_RUNT 0x00000048
+#define R_MAC_RMON_TX_OVERSIZE 0x00000050
+#define R_MAC_RMON_RX_BYTES 0x00000080
+#define R_MAC_RMON_RX_MCAST 0x00000088
+#define R_MAC_RMON_RX_BCAST 0x00000090
+#define R_MAC_RMON_RX_BAD 0x00000098
+#define R_MAC_RMON_RX_GOOD 0x000000A0
+#define R_MAC_RMON_RX_RUNT 0x000000A8
+#define R_MAC_RMON_RX_OVERSIZE 0x000000B0
+#define R_MAC_RMON_RX_FCS_ERROR 0x000000B8
+#define R_MAC_RMON_RX_LENGTH_ERROR 0x000000C0
+#define R_MAC_RMON_RX_CODE_ERROR 0x000000C8
+#define R_MAC_RMON_RX_ALIGN_ERROR 0x000000D0
+
+/* Updated to spec 0.2 */
+#define R_MAC_CFG 0x00000100
+#define R_MAC_THRSH_CFG 0x00000108
+#define R_MAC_VLANTAG 0x00000110
+#define R_MAC_FRAMECFG 0x00000118
+#define R_MAC_EOPCNT 0x00000120
+#define R_MAC_FIFO_PTRS 0x00000128
+#define R_MAC_ADFILTER_CFG 0x00000200
+#define R_MAC_ETHERNET_ADDR 0x00000208
+#define R_MAC_PKT_TYPE 0x00000210
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define R_MAC_ADMASK0 0x00000218
+#define R_MAC_ADMASK1 0x00000220
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+#define R_MAC_HASH_BASE 0x00000240
+#define R_MAC_ADDR_BASE 0x00000280
+#define R_MAC_CHLO0_BASE 0x00000300
+#define R_MAC_CHUP0_BASE 0x00000320
+#define R_MAC_ENABLE 0x00000400
+#define R_MAC_STATUS 0x00000408
+#define R_MAC_INT_MASK 0x00000410
+#define R_MAC_TXD_CTL 0x00000420
+#define R_MAC_MDIO 0x00000428
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define R_MAC_STATUS1 0x00000430
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+#define R_MAC_DEBUG_STATUS 0x00000448
+
+#define MAC_HASH_COUNT 8
+#define MAC_ADDR_COUNT 8
+#define MAC_CHMAP_COUNT 4
+
+
+/* *********************************************************************
+ * DUART Registers
+ ********************************************************************* */
+
+
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
+#define R_DUART_NUM_PORTS 2
+
+#define A_DUART 0x0010060000
+
+#define DUART_CHANREG_SPACING 0x100
+
+#define A_DUART_CHANREG(chan, reg) \
+ (A_DUART + DUART_CHANREG_SPACING * ((chan) + 1) + (reg))
+#endif /* 1250 & 112x */
+
+#define R_DUART_MODE_REG_1 0x000
+#define R_DUART_MODE_REG_2 0x010
+#define R_DUART_STATUS 0x020
+#define R_DUART_CLK_SEL 0x030
+#define R_DUART_CMD 0x050
+#define R_DUART_RX_HOLD 0x060
+#define R_DUART_TX_HOLD 0x070
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define R_DUART_FULL_CTL 0x040
+#define R_DUART_OPCR_X 0x080
+#define R_DUART_AUXCTL_X 0x090
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+
+/*
+ * The IMR and ISR can't be addressed with A_DUART_CHANREG,
+ * so use these macros instead.
+ */
+
+#if SIBYTE_HDR_FEATURE_1250_112x /* This MC only on 1250 & 112x */
+#define DUART_IMRISR_SPACING 0x20
+#define DUART_INCHNG_SPACING 0x10
+
+#define A_DUART_CTRLREG(reg) \
+ (A_DUART + DUART_CHANREG_SPACING * 3 + (reg))
+
+#define R_DUART_IMRREG(chan) \
+ (R_DUART_IMR_A + (chan) * DUART_IMRISR_SPACING)
+#define R_DUART_ISRREG(chan) \
+ (R_DUART_ISR_A + (chan) * DUART_IMRISR_SPACING)
+#define R_DUART_INCHREG(chan) \
+ (R_DUART_IN_CHNG_A + (chan) * DUART_INCHNG_SPACING)
+
+#define A_DUART_IMRREG(chan) A_DUART_CTRLREG(R_DUART_IMRREG(chan))
+#define A_DUART_ISRREG(chan) A_DUART_CTRLREG(R_DUART_ISRREG(chan))
+#define A_DUART_INCHREG(chan) A_DUART_CTRLREG(R_DUART_INCHREG(chan))
+#endif /* 1250 & 112x */
+
+#define R_DUART_AUX_CTRL 0x010
+#define R_DUART_ISR_A 0x020
+#define R_DUART_IMR_A 0x030
+#define R_DUART_ISR_B 0x040
+#define R_DUART_IMR_B 0x050
+#define R_DUART_OUT_PORT 0x060
+#define R_DUART_OPCR 0x070
+#define R_DUART_IN_PORT 0x080
+
+#define R_DUART_SET_OPR 0x0B0
+#define R_DUART_CLEAR_OPR 0x0C0
+#define R_DUART_IN_CHNG_A 0x0D0
+#define R_DUART_IN_CHNG_B 0x0E0
+
+
+/*
+ * These constants are the absolute addresses.
+ */
+
+#define A_DUART_MODE_REG_1_A 0x0010060100
+#define A_DUART_MODE_REG_2_A 0x0010060110
+#define A_DUART_STATUS_A 0x0010060120
+#define A_DUART_CLK_SEL_A 0x0010060130
+#define A_DUART_CMD_A 0x0010060150
+#define A_DUART_RX_HOLD_A 0x0010060160
+#define A_DUART_TX_HOLD_A 0x0010060170
+
+#define A_DUART_MODE_REG_1_B 0x0010060200
+#define A_DUART_MODE_REG_2_B 0x0010060210
+#define A_DUART_STATUS_B 0x0010060220
+#define A_DUART_CLK_SEL_B 0x0010060230
+#define A_DUART_CMD_B 0x0010060250
+#define A_DUART_RX_HOLD_B 0x0010060260
+#define A_DUART_TX_HOLD_B 0x0010060270
+
+#define A_DUART_INPORT_CHNG 0x0010060300
+#define A_DUART_AUX_CTRL 0x0010060310
+#define A_DUART_ISR_A 0x0010060320
+#define A_DUART_IMR_A 0x0010060330
+#define A_DUART_ISR_B 0x0010060340
+#define A_DUART_IMR_B 0x0010060350
+#define A_DUART_OUT_PORT 0x0010060360
+#define A_DUART_OPCR 0x0010060370
+#define A_DUART_IN_PORT 0x0010060380
+#define A_DUART_ISR 0x0010060390
+#define A_DUART_IMR 0x00100603A0
+#define A_DUART_SET_OPR 0x00100603B0
+#define A_DUART_CLEAR_OPR 0x00100603C0
+#define A_DUART_INPORT_CHNG_A 0x00100603D0
+#define A_DUART_INPORT_CHNG_B 0x00100603E0
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define A_DUART_FULL_CTL_A 0x0010060140
+#define A_DUART_FULL_CTL_B 0x0010060240
+
+#define A_DUART_OPCR_A 0x0010060180
+#define A_DUART_OPCR_B 0x0010060280
+
+#define A_DUART_INPORT_CHNG_DEBUG 0x00100603F0
+#endif /* 1250 PASS2 || 112x PASS1 */
+
+
+/* *********************************************************************
+ * Synchronous Serial Registers
+ ********************************************************************* */
+
+
+#if SIBYTE_HDR_FEATURE_1250_112x /* sync serial only on 1250/112x */
+
+#define A_SER_BASE_0 0x0010060400
+#define A_SER_BASE_1 0x0010060800
+#define SER_SPACING 0x400
+
+#define SER_DMA_TXRX_SPACING 0x80
+
+#define SER_NUM_PORTS 2
+
+#define A_SER_CHANNEL_BASE(sernum) \
+ (A_SER_BASE_0 + \
+ SER_SPACING*(sernum))
+
+#define A_SER_REGISTER(sernum,reg) \
+ (A_SER_BASE_0 + \
+ SER_SPACING*(sernum) + (reg))
+
+
+#define R_SER_DMA_CHANNELS 0 /* Relative to A_SER_BASE_x */
+
+#define A_SER_DMA_CHANNEL_BASE(sernum,txrx) \
+ ((A_SER_CHANNEL_BASE(sernum)) + \
+ R_SER_DMA_CHANNELS + \
+ (SER_DMA_TXRX_SPACING*(txrx)))
+
+#define A_SER_DMA_REGISTER(sernum, txrx, reg) \
+ (A_SER_DMA_CHANNEL_BASE(sernum, txrx) + \
+ (reg))
+
+
+/*
+ * DMA channel registers, relative to A_SER_DMA_CHANNEL_BASE
+ */
+
+#define R_SER_DMA_CONFIG0 0x00000000
+#define R_SER_DMA_CONFIG1 0x00000008
+#define R_SER_DMA_DSCR_BASE 0x00000010
+#define R_SER_DMA_DSCR_CNT 0x00000018
+#define R_SER_DMA_CUR_DSCRA 0x00000020
+#define R_SER_DMA_CUR_DSCRB 0x00000028
+#define R_SER_DMA_CUR_DSCRADDR 0x00000030
+
+#define R_SER_DMA_CONFIG0_RX 0x00000000
+#define R_SER_DMA_CONFIG1_RX 0x00000008
+#define R_SER_DMA_DSCR_BASE_RX 0x00000010
+#define R_SER_DMA_DSCR_COUNT_RX 0x00000018
+#define R_SER_DMA_CUR_DSCR_A_RX 0x00000020
+#define R_SER_DMA_CUR_DSCR_B_RX 0x00000028
+#define R_SER_DMA_CUR_DSCR_ADDR_RX 0x00000030
+
+#define R_SER_DMA_CONFIG0_TX 0x00000080
+#define R_SER_DMA_CONFIG1_TX 0x00000088
+#define R_SER_DMA_DSCR_BASE_TX 0x00000090
+#define R_SER_DMA_DSCR_COUNT_TX 0x00000098
+#define R_SER_DMA_CUR_DSCR_A_TX 0x000000A0
+#define R_SER_DMA_CUR_DSCR_B_TX 0x000000A8
+#define R_SER_DMA_CUR_DSCR_ADDR_TX 0x000000B0
+
+#define R_SER_MODE 0x00000100
+#define R_SER_MINFRM_SZ 0x00000108
+#define R_SER_MAXFRM_SZ 0x00000110
+#define R_SER_ADDR 0x00000118
+#define R_SER_USR0_ADDR 0x00000120
+#define R_SER_USR1_ADDR 0x00000128
+#define R_SER_USR2_ADDR 0x00000130
+#define R_SER_USR3_ADDR 0x00000138
+#define R_SER_CMD 0x00000140
+#define R_SER_TX_RD_THRSH 0x00000160
+#define R_SER_TX_WR_THRSH 0x00000168
+#define R_SER_RX_RD_THRSH 0x00000170
+#define R_SER_LINE_MODE 0x00000178
+#define R_SER_DMA_ENABLE 0x00000180
+#define R_SER_INT_MASK 0x00000190
+#define R_SER_STATUS 0x00000188
+#define R_SER_STATUS_DEBUG 0x000001A8
+#define R_SER_RX_TABLE_BASE 0x00000200
+#define SER_RX_TABLE_COUNT 16
+#define R_SER_TX_TABLE_BASE 0x00000300
+#define SER_TX_TABLE_COUNT 16
+
+/* RMON Counters */
+#define R_SER_RMON_TX_BYTE_LO 0x000001C0
+#define R_SER_RMON_TX_BYTE_HI 0x000001C8
+#define R_SER_RMON_RX_BYTE_LO 0x000001D0
+#define R_SER_RMON_RX_BYTE_HI 0x000001D8
+#define R_SER_RMON_TX_UNDERRUN 0x000001E0
+#define R_SER_RMON_RX_OVERFLOW 0x000001E8
+#define R_SER_RMON_RX_ERRORS 0x000001F0
+#define R_SER_RMON_RX_BADADDR 0x000001F8
+
+#endif /* 1250/112x */
+
+/* *********************************************************************
+ * Generic Bus Registers
+ ********************************************************************* */
+
+#define IO_EXT_CFG_COUNT 8
+
+#define A_IO_EXT_BASE 0x0010061000
+#define A_IO_EXT_REG(r) (A_IO_EXT_BASE + (r))
+
+#define A_IO_EXT_CFG_BASE 0x0010061000
+#define A_IO_EXT_MULT_SIZE_BASE 0x0010061100
+#define A_IO_EXT_START_ADDR_BASE 0x0010061200
+#define A_IO_EXT_TIME_CFG0_BASE 0x0010061600
+#define A_IO_EXT_TIME_CFG1_BASE 0x0010061700
+
+#define IO_EXT_REGISTER_SPACING 8
+#define A_IO_EXT_CS_BASE(cs) (A_IO_EXT_CFG_BASE+IO_EXT_REGISTER_SPACING*(cs))
+#define R_IO_EXT_REG(reg, cs) ((cs)*IO_EXT_REGISTER_SPACING + (reg))
+
+#define R_IO_EXT_CFG 0x0000
+#define R_IO_EXT_MULT_SIZE 0x0100
+#define R_IO_EXT_START_ADDR 0x0200
+#define R_IO_EXT_TIME_CFG0 0x0600
+#define R_IO_EXT_TIME_CFG1 0x0700
+
+
+#define A_IO_INTERRUPT_STATUS 0x0010061A00
+#define A_IO_INTERRUPT_DATA0 0x0010061A10
+#define A_IO_INTERRUPT_DATA1 0x0010061A18
+#define A_IO_INTERRUPT_DATA2 0x0010061A20
+#define A_IO_INTERRUPT_DATA3 0x0010061A28
+#define A_IO_INTERRUPT_ADDR0 0x0010061A30
+#define A_IO_INTERRUPT_ADDR1 0x0010061A40
+#define A_IO_INTERRUPT_PARITY 0x0010061A50
+#define A_IO_PCMCIA_CFG 0x0010061A60
+#define A_IO_PCMCIA_STATUS 0x0010061A70
+#define A_IO_DRIVE_0 0x0010061300
+#define A_IO_DRIVE_1 0x0010061308
+#define A_IO_DRIVE_2 0x0010061310
+#define A_IO_DRIVE_3 0x0010061318
+#define A_IO_DRIVE_BASE A_IO_DRIVE_0
+#define IO_DRIVE_REGISTER_SPACING 8
+#define R_IO_DRIVE(x) ((x)*IO_DRIVE_REGISTER_SPACING)
+#define A_IO_DRIVE(x) (A_IO_DRIVE_BASE + R_IO_DRIVE(x))
+
+#define R_IO_INTERRUPT_STATUS 0x0A00
+#define R_IO_INTERRUPT_DATA0 0x0A10
+#define R_IO_INTERRUPT_DATA1 0x0A18
+#define R_IO_INTERRUPT_DATA2 0x0A20
+#define R_IO_INTERRUPT_DATA3 0x0A28
+#define R_IO_INTERRUPT_ADDR0 0x0A30
+#define R_IO_INTERRUPT_ADDR1 0x0A40
+#define R_IO_INTERRUPT_PARITY 0x0A50
+#define R_IO_PCMCIA_CFG 0x0A60
+#define R_IO_PCMCIA_STATUS 0x0A70
+
+/* *********************************************************************
+ * GPIO Registers
+ ********************************************************************* */
+
+#define A_GPIO_CLR_EDGE 0x0010061A80
+#define A_GPIO_INT_TYPE 0x0010061A88
+#define A_GPIO_INPUT_INVERT 0x0010061A90
+#define A_GPIO_GLITCH 0x0010061A98
+#define A_GPIO_READ 0x0010061AA0
+#define A_GPIO_DIRECTION 0x0010061AA8
+#define A_GPIO_PIN_CLR 0x0010061AB0
+#define A_GPIO_PIN_SET 0x0010061AB8
+
+#define A_GPIO_BASE 0x0010061A80
+
+#define R_GPIO_CLR_EDGE 0x00
+#define R_GPIO_INT_TYPE 0x08
+#define R_GPIO_INPUT_INVERT 0x10
+#define R_GPIO_GLITCH 0x18
+#define R_GPIO_READ 0x20
+#define R_GPIO_DIRECTION 0x28
+#define R_GPIO_PIN_CLR 0x30
+#define R_GPIO_PIN_SET 0x38
+
+/* *********************************************************************
+ * SMBus Registers
+ ********************************************************************* */
+
+#define A_SMB_XTRA_0 0x0010060000
+#define A_SMB_XTRA_1 0x0010060008
+#define A_SMB_FREQ_0 0x0010060010
+#define A_SMB_FREQ_1 0x0010060018
+#define A_SMB_STATUS_0 0x0010060020
+#define A_SMB_STATUS_1 0x0010060028
+#define A_SMB_CMD_0 0x0010060030
+#define A_SMB_CMD_1 0x0010060038
+#define A_SMB_START_0 0x0010060040
+#define A_SMB_START_1 0x0010060048
+#define A_SMB_DATA_0 0x0010060050
+#define A_SMB_DATA_1 0x0010060058
+#define A_SMB_CONTROL_0 0x0010060060
+#define A_SMB_CONTROL_1 0x0010060068
+#define A_SMB_PEC_0 0x0010060070
+#define A_SMB_PEC_1 0x0010060078
+
+#define A_SMB_0 0x0010060000
+#define A_SMB_1 0x0010060008
+#define SMB_REGISTER_SPACING 0x8
+#define A_SMB_BASE(idx) (A_SMB_0+(idx)*SMB_REGISTER_SPACING)
+#define A_SMB_REGISTER(idx, reg) (A_SMB_BASE(idx)+(reg))
+
+#define R_SMB_XTRA 0x0000000000
+#define R_SMB_FREQ 0x0000000010
+#define R_SMB_STATUS 0x0000000020
+#define R_SMB_CMD 0x0000000030
+#define R_SMB_START 0x0000000040
+#define R_SMB_DATA 0x0000000050
+#define R_SMB_CONTROL 0x0000000060
+#define R_SMB_PEC 0x0000000070
+
+/* *********************************************************************
+ * Timer Registers
+ ********************************************************************* */
+
+/*
+ * Watchdog timers
+ */
+
+#define A_SCD_WDOG_0 0x0010020050
+#define A_SCD_WDOG_1 0x0010020150
+#define SCD_WDOG_SPACING 0x100
+#define SCD_NUM_WDOGS 2
+#define A_SCD_WDOG_BASE(w) (A_SCD_WDOG_0+SCD_WDOG_SPACING*(w))
+#define A_SCD_WDOG_REGISTER(w, r) (A_SCD_WDOG_BASE(w) + (r))
+
+#define R_SCD_WDOG_INIT 0x0000000000
+#define R_SCD_WDOG_CNT 0x0000000008
+#define R_SCD_WDOG_CFG 0x0000000010
+
+#define A_SCD_WDOG_INIT_0 0x0010020050
+#define A_SCD_WDOG_CNT_0 0x0010020058
+#define A_SCD_WDOG_CFG_0 0x0010020060
+
+#define A_SCD_WDOG_INIT_1 0x0010020150
+#define A_SCD_WDOG_CNT_1 0x0010020158
+#define A_SCD_WDOG_CFG_1 0x0010020160
+
+/*
+ * Generic timers
+ */
+
+#define A_SCD_TIMER_0 0x0010020070
+#define A_SCD_TIMER_1 0x0010020078
+#define A_SCD_TIMER_2 0x0010020170
+#define A_SCD_TIMER_3 0x0010020178
+#define SCD_NUM_TIMERS 4
+#define A_SCD_TIMER_BASE(w) (A_SCD_TIMER_0+0x08*((w)&1)+0x100*(((w)&2)>>1))
+#define A_SCD_TIMER_REGISTER(w, r) (A_SCD_TIMER_BASE(w) + (r))
+
+#define R_SCD_TIMER_INIT 0x0000000000
+#define R_SCD_TIMER_CNT 0x0000000010
+#define R_SCD_TIMER_CFG 0x0000000020
+
+#define A_SCD_TIMER_INIT_0 0x0010020070
+#define A_SCD_TIMER_CNT_0 0x0010020080
+#define A_SCD_TIMER_CFG_0 0x0010020090
+
+#define A_SCD_TIMER_INIT_1 0x0010020078
+#define A_SCD_TIMER_CNT_1 0x0010020088
+#define A_SCD_TIMER_CFG_1 0x0010020098
+
+#define A_SCD_TIMER_INIT_2 0x0010020170
+#define A_SCD_TIMER_CNT_2 0x0010020180
+#define A_SCD_TIMER_CFG_2 0x0010020190
+
+#define A_SCD_TIMER_INIT_3 0x0010020178
+#define A_SCD_TIMER_CNT_3 0x0010020188
+#define A_SCD_TIMER_CFG_3 0x0010020198
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define A_SCD_SCRATCH 0x0010020C10
+#endif /* 1250 PASS2 || 112x PASS1 */
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define A_SCD_ZBBUS_CYCLE_COUNT 0x0010030000
+#define A_SCD_ZBBUS_CYCLE_CP0 0x0010020C00
+#define A_SCD_ZBBUS_CYCLE_CP1 0x0010020C08
+#endif
+
+/* *********************************************************************
+ * System Control Registers
+ ********************************************************************* */
+
+#define A_SCD_SYSTEM_REVISION 0x0010020000
+#define A_SCD_SYSTEM_CFG 0x0010020008
+#define A_SCD_SYSTEM_MANUF 0x0010038000
+
+/* *********************************************************************
+ * System Address Trap Registers
+ ********************************************************************* */
+
+#define A_ADDR_TRAP_INDEX 0x00100200B0
+#define A_ADDR_TRAP_REG 0x00100200B8
+#define A_ADDR_TRAP_UP_0 0x0010020400
+#define A_ADDR_TRAP_UP_1 0x0010020408
+#define A_ADDR_TRAP_UP_2 0x0010020410
+#define A_ADDR_TRAP_UP_3 0x0010020418
+#define A_ADDR_TRAP_DOWN_0 0x0010020420
+#define A_ADDR_TRAP_DOWN_1 0x0010020428
+#define A_ADDR_TRAP_DOWN_2 0x0010020430
+#define A_ADDR_TRAP_DOWN_3 0x0010020438
+#define A_ADDR_TRAP_CFG_0 0x0010020440
+#define A_ADDR_TRAP_CFG_1 0x0010020448
+#define A_ADDR_TRAP_CFG_2 0x0010020450
+#define A_ADDR_TRAP_CFG_3 0x0010020458
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define A_ADDR_TRAP_REG_DEBUG 0x0010020460
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#define ADDR_TRAP_SPACING 8
+#define NUM_ADDR_TRAP 4
+#define A_ADDR_TRAP_UP(n) (A_ADDR_TRAP_UP_0 + ((n) * ADDR_TRAP_SPACING))
+#define A_ADDR_TRAP_DOWN(n) (A_ADDR_TRAP_DOWN_0 + ((n) * ADDR_TRAP_SPACING))
+#define A_ADDR_TRAP_CFG(n) (A_ADDR_TRAP_CFG_0 + ((n) * ADDR_TRAP_SPACING))
+
+
+/* *********************************************************************
+ * System Interrupt Mapper Registers
+ ********************************************************************* */
+
+#define A_IMR_CPU0_BASE 0x0010020000
+#define A_IMR_CPU1_BASE 0x0010022000
+#define IMR_REGISTER_SPACING 0x2000
+#define IMR_REGISTER_SPACING_SHIFT 13
+
+#define A_IMR_MAPPER(cpu) (A_IMR_CPU0_BASE+(cpu)*IMR_REGISTER_SPACING)
+#define A_IMR_REGISTER(cpu, reg) (A_IMR_MAPPER(cpu)+(reg))
+
+#define R_IMR_INTERRUPT_DIAG 0x0010
+#define R_IMR_INTERRUPT_LDT 0x0018
+#define R_IMR_INTERRUPT_MASK 0x0028
+#define R_IMR_INTERRUPT_TRACE 0x0038
+#define R_IMR_INTERRUPT_SOURCE_STATUS 0x0040
+#define R_IMR_LDT_INTERRUPT_SET 0x0048
+#define R_IMR_LDT_INTERRUPT 0x0018
+#define R_IMR_LDT_INTERRUPT_CLR 0x0020
+#define R_IMR_MAILBOX_CPU 0x00c0
+#define R_IMR_ALIAS_MAILBOX_CPU 0x1000
+#define R_IMR_MAILBOX_SET_CPU 0x00C8
+#define R_IMR_ALIAS_MAILBOX_SET_CPU 0x1008
+#define R_IMR_MAILBOX_CLR_CPU 0x00D0
+#define R_IMR_INTERRUPT_STATUS_BASE 0x0100
+#define R_IMR_INTERRUPT_STATUS_COUNT 7
+#define R_IMR_INTERRUPT_MAP_BASE 0x0200
+#define R_IMR_INTERRUPT_MAP_COUNT 64
+
+/*
+ * these macros work together to build the address of a mailbox
+ * register, e.g., A_MAILBOX_REGISTER(R_IMR_MAILBOX_SET_CPU,1)
+ * for mbox_0_set_cpu2 returns 0x00100240C8
+ */
+#define A_MAILBOX_REGISTER(reg,cpu) \
+ (A_IMR_CPU0_BASE + (cpu * IMR_REGISTER_SPACING) + reg)
+
+/* *********************************************************************
+ * System Performance Counter Registers
+ ********************************************************************* */
+
+#define A_SCD_PERF_CNT_CFG 0x00100204C0
+#define A_SCD_PERF_CNT_0 0x00100204D0
+#define A_SCD_PERF_CNT_1 0x00100204D8
+#define A_SCD_PERF_CNT_2 0x00100204E0
+#define A_SCD_PERF_CNT_3 0x00100204E8
+
+#define SCD_NUM_PERF_CNT 4
+#define SCD_PERF_CNT_SPACING 8
+#define A_SCD_PERF_CNT(n) (A_SCD_PERF_CNT_0+(n*SCD_PERF_CNT_SPACING))
+
+/* *********************************************************************
+ * System Bus Watcher Registers
+ ********************************************************************* */
+
+#define A_SCD_BUS_ERR_STATUS 0x0010020880
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define A_SCD_BUS_ERR_STATUS_DEBUG 0x00100208D0
+#define A_BUS_ERR_STATUS_DEBUG 0x00100208D0
+#endif /* 1250 PASS2 || 112x PASS1 */
+#define A_BUS_ERR_DATA_0 0x00100208A0
+#define A_BUS_ERR_DATA_1 0x00100208A8
+#define A_BUS_ERR_DATA_2 0x00100208B0
+#define A_BUS_ERR_DATA_3 0x00100208B8
+#define A_BUS_L2_ERRORS 0x00100208C0
+#define A_BUS_MEM_IO_ERRORS 0x00100208C8
+
+/* *********************************************************************
+ * System Debug Controller Registers
+ ********************************************************************* */
+
+#define A_SCD_JTAG_BASE 0x0010000000
+
+/* *********************************************************************
+ * System Trace Buffer Registers
+ ********************************************************************* */
+
+#define A_SCD_TRACE_CFG 0x0010020A00
+#define A_SCD_TRACE_READ 0x0010020A08
+#define A_SCD_TRACE_EVENT_0 0x0010020A20
+#define A_SCD_TRACE_EVENT_1 0x0010020A28
+#define A_SCD_TRACE_EVENT_2 0x0010020A30
+#define A_SCD_TRACE_EVENT_3 0x0010020A38
+#define A_SCD_TRACE_SEQUENCE_0 0x0010020A40
+#define A_SCD_TRACE_SEQUENCE_1 0x0010020A48
+#define A_SCD_TRACE_SEQUENCE_2 0x0010020A50
+#define A_SCD_TRACE_SEQUENCE_3 0x0010020A58
+#define A_SCD_TRACE_EVENT_4 0x0010020A60
+#define A_SCD_TRACE_EVENT_5 0x0010020A68
+#define A_SCD_TRACE_EVENT_6 0x0010020A70
+#define A_SCD_TRACE_EVENT_7 0x0010020A78
+#define A_SCD_TRACE_SEQUENCE_4 0x0010020A80
+#define A_SCD_TRACE_SEQUENCE_5 0x0010020A88
+#define A_SCD_TRACE_SEQUENCE_6 0x0010020A90
+#define A_SCD_TRACE_SEQUENCE_7 0x0010020A98
+
+#define TRACE_REGISTER_SPACING 8
+#define TRACE_NUM_REGISTERS 8
+#define A_SCD_TRACE_EVENT(n) (((n) & 4) ? \
+ (A_SCD_TRACE_EVENT_4 + (((n) & 3) * TRACE_REGISTER_SPACING)) : \
+ (A_SCD_TRACE_EVENT_0 + ((n) * TRACE_REGISTER_SPACING)))
+#define A_SCD_TRACE_SEQUENCE(n) (((n) & 4) ? \
+ (A_SCD_TRACE_SEQUENCE_4 + (((n) & 3) * TRACE_REGISTER_SPACING)) : \
+ (A_SCD_TRACE_SEQUENCE_0 + ((n) * TRACE_REGISTER_SPACING)))
+
+/* *********************************************************************
+ * System Generic DMA Registers
+ ********************************************************************* */
+
+#define A_DM_0 0x0010020B00
+#define A_DM_1 0x0010020B20
+#define A_DM_2 0x0010020B40
+#define A_DM_3 0x0010020B60
+#define DM_REGISTER_SPACING 0x20
+#define DM_NUM_CHANNELS 4
+#define A_DM_BASE(idx) (A_DM_0 + ((idx) * DM_REGISTER_SPACING))
+#define A_DM_REGISTER(idx, reg) (A_DM_BASE(idx) + (reg))
+
+#define R_DM_DSCR_BASE 0x0000000000
+#define R_DM_DSCR_COUNT 0x0000000008
+#define R_DM_CUR_DSCR_ADDR 0x0000000010
+#define R_DM_DSCR_BASE_DEBUG 0x0000000018
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define A_DM_PARTIAL_0 0x0010020ba0
+#define A_DM_PARTIAL_1 0x0010020ba8
+#define A_DM_PARTIAL_2 0x0010020bb0
+#define A_DM_PARTIAL_3 0x0010020bb8
+#define DM_PARTIAL_REGISTER_SPACING 0x8
+#define A_DM_PARTIAL(idx) (A_DM_PARTIAL_0 + ((idx) * DM_PARTIAL_REGISTER_SPACING))
+#endif /* 1250 PASS3 || 112x PASS1 */
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define A_DM_CRC_0 0x0010020b80
+#define A_DM_CRC_1 0x0010020b90
+#define DM_CRC_REGISTER_SPACING 0x10
+#define DM_CRC_NUM_CHANNELS 2
+#define A_DM_CRC_BASE(idx) (A_DM_CRC_0 + ((idx) * DM_CRC_REGISTER_SPACING))
+#define A_DM_CRC_REGISTER(idx, reg) (A_DM_CRC_BASE(idx) + (reg))
+
+#define R_CRC_DEF_0 0x00
+#define R_CTCP_DEF_0 0x08
+#endif /* 1250 PASS3 || 112x PASS1 */
+
+/* *********************************************************************
+ * Physical Address Map
+ ********************************************************************* */
+
+#if SIBYTE_HDR_FEATURE_1250_112x
+#define A_PHYS_MEMORY_0 _SB_MAKE64(0x0000000000)
+#define A_PHYS_MEMORY_SIZE _SB_MAKE64((256*1024*1024))
+#define A_PHYS_SYSTEM_CTL _SB_MAKE64(0x0010000000)
+#define A_PHYS_IO_SYSTEM _SB_MAKE64(0x0010060000)
+#define A_PHYS_GENBUS _SB_MAKE64(0x0010090000)
+#define A_PHYS_GENBUS_END _SB_MAKE64(0x0040000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BYTES_32 _SB_MAKE64(0x0040000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BITS_32 _SB_MAKE64(0x0060000000)
+#define A_PHYS_MEMORY_1 _SB_MAKE64(0x0080000000)
+#define A_PHYS_MEMORY_2 _SB_MAKE64(0x0090000000)
+#define A_PHYS_MEMORY_3 _SB_MAKE64(0x00C0000000)
+#define A_PHYS_L2_CACHE_TEST _SB_MAKE64(0x00D0000000)
+#define A_PHYS_LDT_SPECIAL_MATCH_BYTES _SB_MAKE64(0x00D8000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BYTES _SB_MAKE64(0x00DC000000)
+#define A_PHYS_LDTPCI_CFG_MATCH_BYTES _SB_MAKE64(0x00DE000000)
+#define A_PHYS_LDT_SPECIAL_MATCH_BITS _SB_MAKE64(0x00F8000000)
+#define A_PHYS_LDTPCI_IO_MATCH_BITS _SB_MAKE64(0x00FC000000)
+#define A_PHYS_LDTPCI_CFG_MATCH_BITS _SB_MAKE64(0x00FE000000)
+#define A_PHYS_MEMORY_EXP _SB_MAKE64(0x0100000000)
+#define A_PHYS_MEMORY_EXP_SIZE _SB_MAKE64((508*1024*1024*1024))
+#define A_PHYS_LDT_EXP _SB_MAKE64(0x8000000000)
+#define A_PHYS_PCI_FULLACCESS_BYTES _SB_MAKE64(0xF000000000)
+#define A_PHYS_PCI_FULLACCESS_BITS _SB_MAKE64(0xF100000000)
+#define A_PHYS_RESERVED _SB_MAKE64(0xF200000000)
+#define A_PHYS_RESERVED_SPECIAL_LDT _SB_MAKE64(0xFD00000000)
+
+#define A_PHYS_L2CACHE_WAY_SIZE _SB_MAKE64(0x0000020000)
+#define PHYS_L2CACHE_NUM_WAYS 4
+#define A_PHYS_L2CACHE_TOTAL_SIZE _SB_MAKE64(0x0000080000)
+#define A_PHYS_L2CACHE_WAY0 _SB_MAKE64(0x00D0180000)
+#define A_PHYS_L2CACHE_WAY1 _SB_MAKE64(0x00D01A0000)
+#define A_PHYS_L2CACHE_WAY2 _SB_MAKE64(0x00D01C0000)
+#define A_PHYS_L2CACHE_WAY3 _SB_MAKE64(0x00D01E0000)
+#endif
+
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_scd.h b/arch/mips/include/asm/sibyte/sb1250_scd.h
new file mode 100644
index 00000000..e49c3e89
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_scd.h
@@ -0,0 +1,654 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * SCD Constants and Macros File: sb1250_scd.h
+ *
+ * This module contains constants and macros useful for
+ * manipulating the System Control and Debug module on the 1250.
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003,2004,2005
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+#ifndef _SB1250_SCD_H
+#define _SB1250_SCD_H
+
+#include "sb1250_defs.h"
+
+/* *********************************************************************
+ * System control/debug registers
+ ********************************************************************* */
+
+/*
+ * System Revision Register (Table 4-1)
+ */
+
+#define M_SYS_RESERVED _SB_MAKEMASK(8, 0)
+
+#define S_SYS_REVISION _SB_MAKE64(8)
+#define M_SYS_REVISION _SB_MAKEMASK(8, S_SYS_REVISION)
+#define V_SYS_REVISION(x) _SB_MAKEVALUE(x, S_SYS_REVISION)
+#define G_SYS_REVISION(x) _SB_GETVALUE(x, S_SYS_REVISION, M_SYS_REVISION)
+
+#define K_SYS_REVISION_BCM1250_PASS1 0x01
+
+#define K_SYS_REVISION_BCM1250_PASS2 0x03
+#define K_SYS_REVISION_BCM1250_A1 0x03 /* Pass 2.0 WB */
+#define K_SYS_REVISION_BCM1250_A2 0x04 /* Pass 2.0 FC */
+#define K_SYS_REVISION_BCM1250_A3 0x05 /* Pass 2.1 FC */
+#define K_SYS_REVISION_BCM1250_A4 0x06 /* Pass 2.1 WB */
+#define K_SYS_REVISION_BCM1250_A6 0x07 /* OR 0x04 (A2) w/WID != 0 */
+#define K_SYS_REVISION_BCM1250_A8 0x0b /* A8/A10 */
+#define K_SYS_REVISION_BCM1250_A9 0x08
+#define K_SYS_REVISION_BCM1250_A10 K_SYS_REVISION_BCM1250_A8
+
+#define K_SYS_REVISION_BCM1250_PASS2_2 0x10
+#define K_SYS_REVISION_BCM1250_B0 K_SYS_REVISION_BCM1250_B1
+#define K_SYS_REVISION_BCM1250_B1 0x10
+#define K_SYS_REVISION_BCM1250_B2 0x11
+
+#define K_SYS_REVISION_BCM1250_C0 0x20
+#define K_SYS_REVISION_BCM1250_C1 0x21
+#define K_SYS_REVISION_BCM1250_C2 0x22
+#define K_SYS_REVISION_BCM1250_C3 0x23
+
+#if SIBYTE_HDR_FEATURE_CHIP(1250)
+/* XXX: discourage people from using these constants. */
+#define K_SYS_REVISION_PASS1 K_SYS_REVISION_BCM1250_PASS1
+#define K_SYS_REVISION_PASS2 K_SYS_REVISION_BCM1250_PASS2
+#define K_SYS_REVISION_PASS2_2 K_SYS_REVISION_BCM1250_PASS2_2
+#define K_SYS_REVISION_PASS3 K_SYS_REVISION_BCM1250_PASS3
+#define K_SYS_REVISION_BCM1250_PASS3 K_SYS_REVISION_BCM1250_C0
+#endif /* 1250 */
+
+#define K_SYS_REVISION_BCM112x_A1 0x20
+#define K_SYS_REVISION_BCM112x_A2 0x21
+#define K_SYS_REVISION_BCM112x_A3 0x22
+#define K_SYS_REVISION_BCM112x_A4 0x23
+#define K_SYS_REVISION_BCM112x_B0 0x30
+
+#define K_SYS_REVISION_BCM1480_S0 0x01
+#define K_SYS_REVISION_BCM1480_A1 0x02
+#define K_SYS_REVISION_BCM1480_A2 0x03
+#define K_SYS_REVISION_BCM1480_A3 0x04
+#define K_SYS_REVISION_BCM1480_B0 0x11
+
+/*Cache size - 23:20 of revision register*/
+#define S_SYS_L2C_SIZE _SB_MAKE64(20)
+#define M_SYS_L2C_SIZE _SB_MAKEMASK(4, S_SYS_L2C_SIZE)
+#define V_SYS_L2C_SIZE(x) _SB_MAKEVALUE(x, S_SYS_L2C_SIZE)
+#define G_SYS_L2C_SIZE(x) _SB_GETVALUE(x, S_SYS_L2C_SIZE, M_SYS_L2C_SIZE)
+
+#define K_SYS_L2C_SIZE_1MB 0
+#define K_SYS_L2C_SIZE_512KB 5
+#define K_SYS_L2C_SIZE_256KB 2
+#define K_SYS_L2C_SIZE_128KB 1
+
+#define K_SYS_L2C_SIZE_BCM1250 K_SYS_L2C_SIZE_512KB
+#define K_SYS_L2C_SIZE_BCM1125 K_SYS_L2C_SIZE_256KB
+#define K_SYS_L2C_SIZE_BCM1122 K_SYS_L2C_SIZE_128KB
+
+
+/* Number of CPU cores, bits 27:24 of revision register*/
+#define S_SYS_NUM_CPUS _SB_MAKE64(24)
+#define M_SYS_NUM_CPUS _SB_MAKEMASK(4, S_SYS_NUM_CPUS)
+#define V_SYS_NUM_CPUS(x) _SB_MAKEVALUE(x, S_SYS_NUM_CPUS)
+#define G_SYS_NUM_CPUS(x) _SB_GETVALUE(x, S_SYS_NUM_CPUS, M_SYS_NUM_CPUS)
+
+
+/* XXX: discourage people from using these constants. */
+#define S_SYS_PART _SB_MAKE64(16)
+#define M_SYS_PART _SB_MAKEMASK(16, S_SYS_PART)
+#define V_SYS_PART(x) _SB_MAKEVALUE(x, S_SYS_PART)
+#define G_SYS_PART(x) _SB_GETVALUE(x, S_SYS_PART, M_SYS_PART)
+
+/* XXX: discourage people from using these constants. */
+#define K_SYS_PART_SB1250 0x1250
+#define K_SYS_PART_BCM1120 0x1121
+#define K_SYS_PART_BCM1125 0x1123
+#define K_SYS_PART_BCM1125H 0x1124
+#define K_SYS_PART_BCM1122 0x1113
+
+
+/* The "peripheral set" (SOC type) is the low 4 bits of the "part" field. */
+#define S_SYS_SOC_TYPE _SB_MAKE64(16)
+#define M_SYS_SOC_TYPE _SB_MAKEMASK(4, S_SYS_SOC_TYPE)
+#define V_SYS_SOC_TYPE(x) _SB_MAKEVALUE(x, S_SYS_SOC_TYPE)
+#define G_SYS_SOC_TYPE(x) _SB_GETVALUE(x, S_SYS_SOC_TYPE, M_SYS_SOC_TYPE)
+
+#define K_SYS_SOC_TYPE_BCM1250 0x0
+#define K_SYS_SOC_TYPE_BCM1120 0x1
+#define K_SYS_SOC_TYPE_BCM1250_ALT 0x2 /* 1250pass2 w/ 1/4 L2. */
+#define K_SYS_SOC_TYPE_BCM1125 0x3
+#define K_SYS_SOC_TYPE_BCM1125H 0x4
+#define K_SYS_SOC_TYPE_BCM1250_ALT2 0x5 /* 1250pass2 w/ 1/2 L2. */
+#define K_SYS_SOC_TYPE_BCM1x80 0x6
+#define K_SYS_SOC_TYPE_BCM1x55 0x7
+
+/*
+ * Calculate correct SOC type given a copy of system revision register.
+ *
+ * (For the assembler version, sysrev and dest may be the same register.
+ * Also, it clobbers AT.)
+ */
+#ifdef __ASSEMBLER__
+#define SYS_SOC_TYPE(dest, sysrev) \
+ .set push ; \
+ .set reorder ; \
+ dsrl dest, sysrev, S_SYS_SOC_TYPE ; \
+ andi dest, dest, (M_SYS_SOC_TYPE >> S_SYS_SOC_TYPE); \
+ beq dest, K_SYS_SOC_TYPE_BCM1250_ALT, 991f ; \
+ beq dest, K_SYS_SOC_TYPE_BCM1250_ALT2, 991f ; \
+ b 992f ; \
+991: li dest, K_SYS_SOC_TYPE_BCM1250 ; \
+992: \
+ .set pop
+#else
+#define SYS_SOC_TYPE(sysrev) \
+ ((G_SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250_ALT \
+ || G_SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250_ALT2) \
+ ? K_SYS_SOC_TYPE_BCM1250 : G_SYS_SOC_TYPE(sysrev))
+#endif
+
+#define S_SYS_WID _SB_MAKE64(32)
+#define M_SYS_WID _SB_MAKEMASK(32, S_SYS_WID)
+#define V_SYS_WID(x) _SB_MAKEVALUE(x, S_SYS_WID)
+#define G_SYS_WID(x) _SB_GETVALUE(x, S_SYS_WID, M_SYS_WID)
+
+/*
+ * System Manufacturing Register
+ * Register: SCD_SYSTEM_MANUF
+ */
+
+#if SIBYTE_HDR_FEATURE_1250_112x
+/* Wafer ID: bits 31:0 */
+#define S_SYS_WAFERID1_200 _SB_MAKE64(0)
+#define M_SYS_WAFERID1_200 _SB_MAKEMASK(32, S_SYS_WAFERID1_200)
+#define V_SYS_WAFERID1_200(x) _SB_MAKEVALUE(x, S_SYS_WAFERID1_200)
+#define G_SYS_WAFERID1_200(x) _SB_GETVALUE(x, S_SYS_WAFERID1_200, M_SYS_WAFERID1_200)
+
+#define S_SYS_BIN _SB_MAKE64(32)
+#define M_SYS_BIN _SB_MAKEMASK(4, S_SYS_BIN)
+#define V_SYS_BIN(x) _SB_MAKEVALUE(x, S_SYS_BIN)
+#define G_SYS_BIN(x) _SB_GETVALUE(x, S_SYS_BIN, M_SYS_BIN)
+
+/* Wafer ID: bits 39:36 */
+#define S_SYS_WAFERID2_200 _SB_MAKE64(36)
+#define M_SYS_WAFERID2_200 _SB_MAKEMASK(4, S_SYS_WAFERID2_200)
+#define V_SYS_WAFERID2_200(x) _SB_MAKEVALUE(x, S_SYS_WAFERID2_200)
+#define G_SYS_WAFERID2_200(x) _SB_GETVALUE(x, S_SYS_WAFERID2_200, M_SYS_WAFERID2_200)
+
+/* Wafer ID: bits 39:0 */
+#define S_SYS_WAFERID_300 _SB_MAKE64(0)
+#define M_SYS_WAFERID_300 _SB_MAKEMASK(40, S_SYS_WAFERID_300)
+#define V_SYS_WAFERID_300(x) _SB_MAKEVALUE(x, S_SYS_WAFERID_300)
+#define G_SYS_WAFERID_300(x) _SB_GETVALUE(x, S_SYS_WAFERID_300, M_SYS_WAFERID_300)
+
+#define S_SYS_XPOS _SB_MAKE64(40)
+#define M_SYS_XPOS _SB_MAKEMASK(6, S_SYS_XPOS)
+#define V_SYS_XPOS(x) _SB_MAKEVALUE(x, S_SYS_XPOS)
+#define G_SYS_XPOS(x) _SB_GETVALUE(x, S_SYS_XPOS, M_SYS_XPOS)
+
+#define S_SYS_YPOS _SB_MAKE64(46)
+#define M_SYS_YPOS _SB_MAKEMASK(6, S_SYS_YPOS)
+#define V_SYS_YPOS(x) _SB_MAKEVALUE(x, S_SYS_YPOS)
+#define G_SYS_YPOS(x) _SB_GETVALUE(x, S_SYS_YPOS, M_SYS_YPOS)
+#endif
+
+
+/*
+ * System Config Register (Table 4-2)
+ * Register: SCD_SYSTEM_CFG
+ */
+
+#if SIBYTE_HDR_FEATURE_1250_112x
+#define M_SYS_LDT_PLL_BYP _SB_MAKEMASK1(3)
+#define M_SYS_PCI_SYNC_TEST_MODE _SB_MAKEMASK1(4)
+#define M_SYS_IOB0_DIV _SB_MAKEMASK1(5)
+#define M_SYS_IOB1_DIV _SB_MAKEMASK1(6)
+
+#define S_SYS_PLL_DIV _SB_MAKE64(7)
+#define M_SYS_PLL_DIV _SB_MAKEMASK(5, S_SYS_PLL_DIV)
+#define V_SYS_PLL_DIV(x) _SB_MAKEVALUE(x, S_SYS_PLL_DIV)
+#define G_SYS_PLL_DIV(x) _SB_GETVALUE(x, S_SYS_PLL_DIV, M_SYS_PLL_DIV)
+
+#define M_SYS_SER0_ENABLE _SB_MAKEMASK1(12)
+#define M_SYS_SER0_RSTB_EN _SB_MAKEMASK1(13)
+#define M_SYS_SER1_ENABLE _SB_MAKEMASK1(14)
+#define M_SYS_SER1_RSTB_EN _SB_MAKEMASK1(15)
+#define M_SYS_PCMCIA_ENABLE _SB_MAKEMASK1(16)
+
+#define S_SYS_BOOT_MODE _SB_MAKE64(17)
+#define M_SYS_BOOT_MODE _SB_MAKEMASK(2, S_SYS_BOOT_MODE)
+#define V_SYS_BOOT_MODE(x) _SB_MAKEVALUE(x, S_SYS_BOOT_MODE)
+#define G_SYS_BOOT_MODE(x) _SB_GETVALUE(x, S_SYS_BOOT_MODE, M_SYS_BOOT_MODE)
+#define K_SYS_BOOT_MODE_ROM32 0
+#define K_SYS_BOOT_MODE_ROM8 1
+#define K_SYS_BOOT_MODE_SMBUS_SMALL 2
+#define K_SYS_BOOT_MODE_SMBUS_BIG 3
+
+#define M_SYS_PCI_HOST _SB_MAKEMASK1(19)
+#define M_SYS_PCI_ARBITER _SB_MAKEMASK1(20)
+#define M_SYS_SOUTH_ON_LDT _SB_MAKEMASK1(21)
+#define M_SYS_BIG_ENDIAN _SB_MAKEMASK1(22)
+#define M_SYS_GENCLK_EN _SB_MAKEMASK1(23)
+#define M_SYS_LDT_TEST_EN _SB_MAKEMASK1(24)
+#define M_SYS_GEN_PARITY_EN _SB_MAKEMASK1(25)
+
+#define S_SYS_CONFIG 26
+#define M_SYS_CONFIG _SB_MAKEMASK(6, S_SYS_CONFIG)
+#define V_SYS_CONFIG(x) _SB_MAKEVALUE(x, S_SYS_CONFIG)
+#define G_SYS_CONFIG(x) _SB_GETVALUE(x, S_SYS_CONFIG, M_SYS_CONFIG)
+
+/* The following bits are writeable by JTAG only. */
+
+#define M_SYS_CLKSTOP _SB_MAKEMASK1(32)
+#define M_SYS_CLKSTEP _SB_MAKEMASK1(33)
+
+#define S_SYS_CLKCOUNT 34
+#define M_SYS_CLKCOUNT _SB_MAKEMASK(8, S_SYS_CLKCOUNT)
+#define V_SYS_CLKCOUNT(x) _SB_MAKEVALUE(x, S_SYS_CLKCOUNT)
+#define G_SYS_CLKCOUNT(x) _SB_GETVALUE(x, S_SYS_CLKCOUNT, M_SYS_CLKCOUNT)
+
+#define M_SYS_PLL_BYPASS _SB_MAKEMASK1(42)
+
+#define S_SYS_PLL_IREF 43
+#define M_SYS_PLL_IREF _SB_MAKEMASK(2, S_SYS_PLL_IREF)
+
+#define S_SYS_PLL_VCO 45
+#define M_SYS_PLL_VCO _SB_MAKEMASK(2, S_SYS_PLL_VCO)
+
+#define S_SYS_PLL_VREG 47
+#define M_SYS_PLL_VREG _SB_MAKEMASK(2, S_SYS_PLL_VREG)
+
+#define M_SYS_MEM_RESET _SB_MAKEMASK1(49)
+#define M_SYS_L2C_RESET _SB_MAKEMASK1(50)
+#define M_SYS_IO_RESET_0 _SB_MAKEMASK1(51)
+#define M_SYS_IO_RESET_1 _SB_MAKEMASK1(52)
+#define M_SYS_SCD_RESET _SB_MAKEMASK1(53)
+
+/* End of bits writable by JTAG only. */
+
+#define M_SYS_CPU_RESET_0 _SB_MAKEMASK1(54)
+#define M_SYS_CPU_RESET_1 _SB_MAKEMASK1(55)
+
+#define M_SYS_UNICPU0 _SB_MAKEMASK1(56)
+#define M_SYS_UNICPU1 _SB_MAKEMASK1(57)
+
+#define M_SYS_SB_SOFTRES _SB_MAKEMASK1(58)
+#define M_SYS_EXT_RESET _SB_MAKEMASK1(59)
+#define M_SYS_SYSTEM_RESET _SB_MAKEMASK1(60)
+
+#define M_SYS_MISR_MODE _SB_MAKEMASK1(61)
+#define M_SYS_MISR_RESET _SB_MAKEMASK1(62)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1)
+#define M_SYS_SW_FLAG _SB_MAKEMASK1(63)
+#endif /* 1250 PASS2 || 112x PASS1 */
+
+#endif
+
+
+/*
+ * Mailbox Registers (Table 4-3)
+ * Registers: SCD_MBOX_CPU_x
+ */
+
+#define S_MBOX_INT_3 0
+#define M_MBOX_INT_3 _SB_MAKEMASK(16, S_MBOX_INT_3)
+#define S_MBOX_INT_2 16
+#define M_MBOX_INT_2 _SB_MAKEMASK(16, S_MBOX_INT_2)
+#define S_MBOX_INT_1 32
+#define M_MBOX_INT_1 _SB_MAKEMASK(16, S_MBOX_INT_1)
+#define S_MBOX_INT_0 48
+#define M_MBOX_INT_0 _SB_MAKEMASK(16, S_MBOX_INT_0)
+
+/*
+ * Watchdog Registers (Table 4-8) (Table 4-9) (Table 4-10)
+ * Registers: SCD_WDOG_INIT_CNT_x
+ */
+
+#define V_SCD_WDOG_FREQ 1000000
+
+#define S_SCD_WDOG_INIT 0
+#define M_SCD_WDOG_INIT _SB_MAKEMASK(23, S_SCD_WDOG_INIT)
+
+#define S_SCD_WDOG_CNT 0
+#define M_SCD_WDOG_CNT _SB_MAKEMASK(23, S_SCD_WDOG_CNT)
+
+#define S_SCD_WDOG_ENABLE 0
+#define M_SCD_WDOG_ENABLE _SB_MAKEMASK1(S_SCD_WDOG_ENABLE)
+
+#define S_SCD_WDOG_RESET_TYPE 2
+#define M_SCD_WDOG_RESET_TYPE _SB_MAKEMASK(3, S_SCD_WDOG_RESET_TYPE)
+#define V_SCD_WDOG_RESET_TYPE(x) _SB_MAKEVALUE(x, S_SCD_WDOG_RESET_TYPE)
+#define G_SCD_WDOG_RESET_TYPE(x) _SB_GETVALUE(x, S_SCD_WDOG_RESET_TYPE, M_SCD_WDOG_RESET_TYPE)
+
+#define K_SCD_WDOG_RESET_FULL 0 /* actually, (x & 1) == 0 */
+#define K_SCD_WDOG_RESET_SOFT 1
+#define K_SCD_WDOG_RESET_CPU0 3
+#define K_SCD_WDOG_RESET_CPU1 5
+#define K_SCD_WDOG_RESET_BOTH_CPUS 7
+
+/* This feature is present in 1250 C0 and later, but *not* in 112x A revs. */
+#if SIBYTE_HDR_FEATURE(1250, PASS3)
+#define S_SCD_WDOG_HAS_RESET 8
+#define M_SCD_WDOG_HAS_RESET _SB_MAKEMASK1(S_SCD_WDOG_HAS_RESET)
+#endif
+
+
+/*
+ * Timer Registers (Table 4-11) (Table 4-12) (Table 4-13)
+ */
+
+#define V_SCD_TIMER_FREQ 1000000
+
+#define S_SCD_TIMER_INIT 0
+#define M_SCD_TIMER_INIT _SB_MAKEMASK(23, S_SCD_TIMER_INIT)
+#define V_SCD_TIMER_INIT(x) _SB_MAKEVALUE(x, S_SCD_TIMER_INIT)
+#define G_SCD_TIMER_INIT(x) _SB_GETVALUE(x, S_SCD_TIMER_INIT, M_SCD_TIMER_INIT)
+
+#define V_SCD_TIMER_WIDTH 23
+#define S_SCD_TIMER_CNT 0
+#define M_SCD_TIMER_CNT _SB_MAKEMASK(V_SCD_TIMER_WIDTH, S_SCD_TIMER_CNT)
+#define V_SCD_TIMER_CNT(x) _SB_MAKEVALUE(x, S_SCD_TIMER_CNT)
+#define G_SCD_TIMER_CNT(x) _SB_GETVALUE(x, S_SCD_TIMER_CNT, M_SCD_TIMER_CNT)
+
+#define M_SCD_TIMER_ENABLE _SB_MAKEMASK1(0)
+#define M_SCD_TIMER_MODE _SB_MAKEMASK1(1)
+#define M_SCD_TIMER_MODE_CONTINUOUS M_SCD_TIMER_MODE
+
+/*
+ * System Performance Counters
+ */
+
+#define S_SPC_CFG_SRC0 0
+#define M_SPC_CFG_SRC0 _SB_MAKEMASK(8, S_SPC_CFG_SRC0)
+#define V_SPC_CFG_SRC0(x) _SB_MAKEVALUE(x, S_SPC_CFG_SRC0)
+#define G_SPC_CFG_SRC0(x) _SB_GETVALUE(x, S_SPC_CFG_SRC0, M_SPC_CFG_SRC0)
+
+#define S_SPC_CFG_SRC1 8
+#define M_SPC_CFG_SRC1 _SB_MAKEMASK(8, S_SPC_CFG_SRC1)
+#define V_SPC_CFG_SRC1(x) _SB_MAKEVALUE(x, S_SPC_CFG_SRC1)
+#define G_SPC_CFG_SRC1(x) _SB_GETVALUE(x, S_SPC_CFG_SRC1, M_SPC_CFG_SRC1)
+
+#define S_SPC_CFG_SRC2 16
+#define M_SPC_CFG_SRC2 _SB_MAKEMASK(8, S_SPC_CFG_SRC2)
+#define V_SPC_CFG_SRC2(x) _SB_MAKEVALUE(x, S_SPC_CFG_SRC2)
+#define G_SPC_CFG_SRC2(x) _SB_GETVALUE(x, S_SPC_CFG_SRC2, M_SPC_CFG_SRC2)
+
+#define S_SPC_CFG_SRC3 24
+#define M_SPC_CFG_SRC3 _SB_MAKEMASK(8, S_SPC_CFG_SRC3)
+#define V_SPC_CFG_SRC3(x) _SB_MAKEVALUE(x, S_SPC_CFG_SRC3)
+#define G_SPC_CFG_SRC3(x) _SB_GETVALUE(x, S_SPC_CFG_SRC3, M_SPC_CFG_SRC3)
+
+#if SIBYTE_HDR_FEATURE_1250_112x
+#define M_SPC_CFG_CLEAR _SB_MAKEMASK1(32)
+#define M_SPC_CFG_ENABLE _SB_MAKEMASK1(33)
+#endif
+
+
+/*
+ * Bus Watcher
+ */
+
+#define S_SCD_BERR_TID 8
+#define M_SCD_BERR_TID _SB_MAKEMASK(10, S_SCD_BERR_TID)
+#define V_SCD_BERR_TID(x) _SB_MAKEVALUE(x, S_SCD_BERR_TID)
+#define G_SCD_BERR_TID(x) _SB_GETVALUE(x, S_SCD_BERR_TID, M_SCD_BERR_TID)
+
+#define S_SCD_BERR_RID 18
+#define M_SCD_BERR_RID _SB_MAKEMASK(4, S_SCD_BERR_RID)
+#define V_SCD_BERR_RID(x) _SB_MAKEVALUE(x, S_SCD_BERR_RID)
+#define G_SCD_BERR_RID(x) _SB_GETVALUE(x, S_SCD_BERR_RID, M_SCD_BERR_RID)
+
+#define S_SCD_BERR_DCODE 22
+#define M_SCD_BERR_DCODE _SB_MAKEMASK(3, S_SCD_BERR_DCODE)
+#define V_SCD_BERR_DCODE(x) _SB_MAKEVALUE(x, S_SCD_BERR_DCODE)
+#define G_SCD_BERR_DCODE(x) _SB_GETVALUE(x, S_SCD_BERR_DCODE, M_SCD_BERR_DCODE)
+
+#define M_SCD_BERR_MULTERRS _SB_MAKEMASK1(30)
+
+
+#define S_SCD_L2ECC_CORR_D 0
+#define M_SCD_L2ECC_CORR_D _SB_MAKEMASK(8, S_SCD_L2ECC_CORR_D)
+#define V_SCD_L2ECC_CORR_D(x) _SB_MAKEVALUE(x, S_SCD_L2ECC_CORR_D)
+#define G_SCD_L2ECC_CORR_D(x) _SB_GETVALUE(x, S_SCD_L2ECC_CORR_D, M_SCD_L2ECC_CORR_D)
+
+#define S_SCD_L2ECC_BAD_D 8
+#define M_SCD_L2ECC_BAD_D _SB_MAKEMASK(8, S_SCD_L2ECC_BAD_D)
+#define V_SCD_L2ECC_BAD_D(x) _SB_MAKEVALUE(x, S_SCD_L2ECC_BAD_D)
+#define G_SCD_L2ECC_BAD_D(x) _SB_GETVALUE(x, S_SCD_L2ECC_BAD_D, M_SCD_L2ECC_BAD_D)
+
+#define S_SCD_L2ECC_CORR_T 16
+#define M_SCD_L2ECC_CORR_T _SB_MAKEMASK(8, S_SCD_L2ECC_CORR_T)
+#define V_SCD_L2ECC_CORR_T(x) _SB_MAKEVALUE(x, S_SCD_L2ECC_CORR_T)
+#define G_SCD_L2ECC_CORR_T(x) _SB_GETVALUE(x, S_SCD_L2ECC_CORR_T, M_SCD_L2ECC_CORR_T)
+
+#define S_SCD_L2ECC_BAD_T 24
+#define M_SCD_L2ECC_BAD_T _SB_MAKEMASK(8, S_SCD_L2ECC_BAD_T)
+#define V_SCD_L2ECC_BAD_T(x) _SB_MAKEVALUE(x, S_SCD_L2ECC_BAD_T)
+#define G_SCD_L2ECC_BAD_T(x) _SB_GETVALUE(x, S_SCD_L2ECC_BAD_T, M_SCD_L2ECC_BAD_T)
+
+#define S_SCD_MEM_ECC_CORR 0
+#define M_SCD_MEM_ECC_CORR _SB_MAKEMASK(8, S_SCD_MEM_ECC_CORR)
+#define V_SCD_MEM_ECC_CORR(x) _SB_MAKEVALUE(x, S_SCD_MEM_ECC_CORR)
+#define G_SCD_MEM_ECC_CORR(x) _SB_GETVALUE(x, S_SCD_MEM_ECC_CORR, M_SCD_MEM_ECC_CORR)
+
+#define S_SCD_MEM_ECC_BAD 8
+#define M_SCD_MEM_ECC_BAD _SB_MAKEMASK(8, S_SCD_MEM_ECC_BAD)
+#define V_SCD_MEM_ECC_BAD(x) _SB_MAKEVALUE(x, S_SCD_MEM_ECC_BAD)
+#define G_SCD_MEM_ECC_BAD(x) _SB_GETVALUE(x, S_SCD_MEM_ECC_BAD, M_SCD_MEM_ECC_BAD)
+
+#define S_SCD_MEM_BUSERR 16
+#define M_SCD_MEM_BUSERR _SB_MAKEMASK(8, S_SCD_MEM_BUSERR)
+#define V_SCD_MEM_BUSERR(x) _SB_MAKEVALUE(x, S_SCD_MEM_BUSERR)
+#define G_SCD_MEM_BUSERR(x) _SB_GETVALUE(x, S_SCD_MEM_BUSERR, M_SCD_MEM_BUSERR)
+
+
+/*
+ * Address Trap Registers
+ */
+
+#if SIBYTE_HDR_FEATURE_1250_112x
+#define M_ATRAP_INDEX _SB_MAKEMASK(4, 0)
+#define M_ATRAP_ADDRESS _SB_MAKEMASK(40, 0)
+
+#define S_ATRAP_CFG_CNT 0
+#define M_ATRAP_CFG_CNT _SB_MAKEMASK(3, S_ATRAP_CFG_CNT)
+#define V_ATRAP_CFG_CNT(x) _SB_MAKEVALUE(x, S_ATRAP_CFG_CNT)
+#define G_ATRAP_CFG_CNT(x) _SB_GETVALUE(x, S_ATRAP_CFG_CNT, M_ATRAP_CFG_CNT)
+
+#define M_ATRAP_CFG_WRITE _SB_MAKEMASK1(3)
+#define M_ATRAP_CFG_ALL _SB_MAKEMASK1(4)
+#define M_ATRAP_CFG_INV _SB_MAKEMASK1(5)
+#define M_ATRAP_CFG_USESRC _SB_MAKEMASK1(6)
+#define M_ATRAP_CFG_SRCINV _SB_MAKEMASK1(7)
+
+#define S_ATRAP_CFG_AGENTID 8
+#define M_ATRAP_CFG_AGENTID _SB_MAKEMASK(4, S_ATRAP_CFG_AGENTID)
+#define V_ATRAP_CFG_AGENTID(x) _SB_MAKEVALUE(x, S_ATRAP_CFG_AGENTID)
+#define G_ATRAP_CFG_AGENTID(x) _SB_GETVALUE(x, S_ATRAP_CFG_AGENTID, M_ATRAP_CFG_AGENTID)
+
+#define K_BUS_AGENT_CPU0 0
+#define K_BUS_AGENT_CPU1 1
+#define K_BUS_AGENT_IOB0 2
+#define K_BUS_AGENT_IOB1 3
+#define K_BUS_AGENT_SCD 4
+#define K_BUS_AGENT_L2C 6
+#define K_BUS_AGENT_MC 7
+
+#define S_ATRAP_CFG_CATTR 12
+#define M_ATRAP_CFG_CATTR _SB_MAKEMASK(3, S_ATRAP_CFG_CATTR)
+#define V_ATRAP_CFG_CATTR(x) _SB_MAKEVALUE(x, S_ATRAP_CFG_CATTR)
+#define G_ATRAP_CFG_CATTR(x) _SB_GETVALUE(x, S_ATRAP_CFG_CATTR, M_ATRAP_CFG_CATTR)
+
+#define K_ATRAP_CFG_CATTR_IGNORE 0
+#define K_ATRAP_CFG_CATTR_UNC 1
+#define K_ATRAP_CFG_CATTR_CACHEABLE 2
+#define K_ATRAP_CFG_CATTR_NONCOH 3
+#define K_ATRAP_CFG_CATTR_COHERENT 4
+#define K_ATRAP_CFG_CATTR_NOTUNC 5
+#define K_ATRAP_CFG_CATTR_NOTNONCOH 6
+#define K_ATRAP_CFG_CATTR_NOTCOHERENT 7
+
+#endif /* 1250/112x */
+
+/*
+ * Trace Buffer Config register
+ */
+
+#define M_SCD_TRACE_CFG_RESET _SB_MAKEMASK1(0)
+#define M_SCD_TRACE_CFG_START_READ _SB_MAKEMASK1(1)
+#define M_SCD_TRACE_CFG_START _SB_MAKEMASK1(2)
+#define M_SCD_TRACE_CFG_STOP _SB_MAKEMASK1(3)
+#define M_SCD_TRACE_CFG_FREEZE _SB_MAKEMASK1(4)
+#define M_SCD_TRACE_CFG_FREEZE_FULL _SB_MAKEMASK1(5)
+#define M_SCD_TRACE_CFG_DEBUG_FULL _SB_MAKEMASK1(6)
+#define M_SCD_TRACE_CFG_FULL _SB_MAKEMASK1(7)
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define M_SCD_TRACE_CFG_FORCECNT _SB_MAKEMASK1(8)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+/*
+ * This field is the same on the 1250/112x and 1480, just located in
+ * a slightly different place in the register.
+ */
+#if SIBYTE_HDR_FEATURE_1250_112x
+#define S_SCD_TRACE_CFG_CUR_ADDR 10
+#else
+#if SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_SCD_TRACE_CFG_CUR_ADDR 24
+#endif /* 1480 */
+#endif /* 1250/112x */
+
+#define M_SCD_TRACE_CFG_CUR_ADDR _SB_MAKEMASK(8, S_SCD_TRACE_CFG_CUR_ADDR)
+#define V_SCD_TRACE_CFG_CUR_ADDR(x) _SB_MAKEVALUE(x, S_SCD_TRACE_CFG_CUR_ADDR)
+#define G_SCD_TRACE_CFG_CUR_ADDR(x) _SB_GETVALUE(x, S_SCD_TRACE_CFG_CUR_ADDR, M_SCD_TRACE_CFG_CUR_ADDR)
+
+/*
+ * Trace Event registers
+ */
+
+#define S_SCD_TREVT_ADDR_MATCH 0
+#define M_SCD_TREVT_ADDR_MATCH _SB_MAKEMASK(4, S_SCD_TREVT_ADDR_MATCH)
+#define V_SCD_TREVT_ADDR_MATCH(x) _SB_MAKEVALUE(x, S_SCD_TREVT_ADDR_MATCH)
+#define G_SCD_TREVT_ADDR_MATCH(x) _SB_GETVALUE(x, S_SCD_TREVT_ADDR_MATCH, M_SCD_TREVT_ADDR_MATCH)
+
+#define M_SCD_TREVT_REQID_MATCH _SB_MAKEMASK1(4)
+#define M_SCD_TREVT_DATAID_MATCH _SB_MAKEMASK1(5)
+#define M_SCD_TREVT_RESPID_MATCH _SB_MAKEMASK1(6)
+#define M_SCD_TREVT_INTERRUPT _SB_MAKEMASK1(7)
+#define M_SCD_TREVT_DEBUG_PIN _SB_MAKEMASK1(9)
+#define M_SCD_TREVT_WRITE _SB_MAKEMASK1(10)
+#define M_SCD_TREVT_READ _SB_MAKEMASK1(11)
+
+#define S_SCD_TREVT_REQID 12
+#define M_SCD_TREVT_REQID _SB_MAKEMASK(4, S_SCD_TREVT_REQID)
+#define V_SCD_TREVT_REQID(x) _SB_MAKEVALUE(x, S_SCD_TREVT_REQID)
+#define G_SCD_TREVT_REQID(x) _SB_GETVALUE(x, S_SCD_TREVT_REQID, M_SCD_TREVT_REQID)
+
+#define S_SCD_TREVT_RESPID 16
+#define M_SCD_TREVT_RESPID _SB_MAKEMASK(4, S_SCD_TREVT_RESPID)
+#define V_SCD_TREVT_RESPID(x) _SB_MAKEVALUE(x, S_SCD_TREVT_RESPID)
+#define G_SCD_TREVT_RESPID(x) _SB_GETVALUE(x, S_SCD_TREVT_RESPID, M_SCD_TREVT_RESPID)
+
+#define S_SCD_TREVT_DATAID 20
+#define M_SCD_TREVT_DATAID _SB_MAKEMASK(4, S_SCD_TREVT_DATAID)
+#define V_SCD_TREVT_DATAID(x) _SB_MAKEVALUE(x, S_SCD_TREVT_DATAID)
+#define G_SCD_TREVT_DATAID(x) _SB_GETVALUE(x, S_SCD_TREVT_DATAID, M_SCD_TREVT_DATID)
+
+#define S_SCD_TREVT_COUNT 24
+#define M_SCD_TREVT_COUNT _SB_MAKEMASK(8, S_SCD_TREVT_COUNT)
+#define V_SCD_TREVT_COUNT(x) _SB_MAKEVALUE(x, S_SCD_TREVT_COUNT)
+#define G_SCD_TREVT_COUNT(x) _SB_GETVALUE(x, S_SCD_TREVT_COUNT, M_SCD_TREVT_COUNT)
+
+/*
+ * Trace Sequence registers
+ */
+
+#define S_SCD_TRSEQ_EVENT4 0
+#define M_SCD_TRSEQ_EVENT4 _SB_MAKEMASK(4, S_SCD_TRSEQ_EVENT4)
+#define V_SCD_TRSEQ_EVENT4(x) _SB_MAKEVALUE(x, S_SCD_TRSEQ_EVENT4)
+#define G_SCD_TRSEQ_EVENT4(x) _SB_GETVALUE(x, S_SCD_TRSEQ_EVENT4, M_SCD_TRSEQ_EVENT4)
+
+#define S_SCD_TRSEQ_EVENT3 4
+#define M_SCD_TRSEQ_EVENT3 _SB_MAKEMASK(4, S_SCD_TRSEQ_EVENT3)
+#define V_SCD_TRSEQ_EVENT3(x) _SB_MAKEVALUE(x, S_SCD_TRSEQ_EVENT3)
+#define G_SCD_TRSEQ_EVENT3(x) _SB_GETVALUE(x, S_SCD_TRSEQ_EVENT3, M_SCD_TRSEQ_EVENT3)
+
+#define S_SCD_TRSEQ_EVENT2 8
+#define M_SCD_TRSEQ_EVENT2 _SB_MAKEMASK(4, S_SCD_TRSEQ_EVENT2)
+#define V_SCD_TRSEQ_EVENT2(x) _SB_MAKEVALUE(x, S_SCD_TRSEQ_EVENT2)
+#define G_SCD_TRSEQ_EVENT2(x) _SB_GETVALUE(x, S_SCD_TRSEQ_EVENT2, M_SCD_TRSEQ_EVENT2)
+
+#define S_SCD_TRSEQ_EVENT1 12
+#define M_SCD_TRSEQ_EVENT1 _SB_MAKEMASK(4, S_SCD_TRSEQ_EVENT1)
+#define V_SCD_TRSEQ_EVENT1(x) _SB_MAKEVALUE(x, S_SCD_TRSEQ_EVENT1)
+#define G_SCD_TRSEQ_EVENT1(x) _SB_GETVALUE(x, S_SCD_TRSEQ_EVENT1, M_SCD_TRSEQ_EVENT1)
+
+#define K_SCD_TRSEQ_E0 0
+#define K_SCD_TRSEQ_E1 1
+#define K_SCD_TRSEQ_E2 2
+#define K_SCD_TRSEQ_E3 3
+#define K_SCD_TRSEQ_E0_E1 4
+#define K_SCD_TRSEQ_E1_E2 5
+#define K_SCD_TRSEQ_E2_E3 6
+#define K_SCD_TRSEQ_E0_E1_E2 7
+#define K_SCD_TRSEQ_E0_E1_E2_E3 8
+#define K_SCD_TRSEQ_E0E1 9
+#define K_SCD_TRSEQ_E0E1E2 10
+#define K_SCD_TRSEQ_E0E1E2E3 11
+#define K_SCD_TRSEQ_E0E1_E2 12
+#define K_SCD_TRSEQ_E0E1_E2E3 13
+#define K_SCD_TRSEQ_E0E1_E2_E3 14
+#define K_SCD_TRSEQ_IGNORED 15
+
+#define K_SCD_TRSEQ_TRIGGER_ALL (V_SCD_TRSEQ_EVENT1(K_SCD_TRSEQ_IGNORED) | \
+ V_SCD_TRSEQ_EVENT2(K_SCD_TRSEQ_IGNORED) | \
+ V_SCD_TRSEQ_EVENT3(K_SCD_TRSEQ_IGNORED) | \
+ V_SCD_TRSEQ_EVENT4(K_SCD_TRSEQ_IGNORED))
+
+#define S_SCD_TRSEQ_FUNCTION 16
+#define M_SCD_TRSEQ_FUNCTION _SB_MAKEMASK(4, S_SCD_TRSEQ_FUNCTION)
+#define V_SCD_TRSEQ_FUNCTION(x) _SB_MAKEVALUE(x, S_SCD_TRSEQ_FUNCTION)
+#define G_SCD_TRSEQ_FUNCTION(x) _SB_GETVALUE(x, S_SCD_TRSEQ_FUNCTION, M_SCD_TRSEQ_FUNCTION)
+
+#define K_SCD_TRSEQ_FUNC_NOP 0
+#define K_SCD_TRSEQ_FUNC_START 1
+#define K_SCD_TRSEQ_FUNC_STOP 2
+#define K_SCD_TRSEQ_FUNC_FREEZE 3
+
+#define V_SCD_TRSEQ_FUNC_NOP V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_NOP)
+#define V_SCD_TRSEQ_FUNC_START V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_START)
+#define V_SCD_TRSEQ_FUNC_STOP V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_STOP)
+#define V_SCD_TRSEQ_FUNC_FREEZE V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_FREEZE)
+
+#define M_SCD_TRSEQ_ASAMPLE _SB_MAKEMASK1(18)
+#define M_SCD_TRSEQ_DSAMPLE _SB_MAKEMASK1(19)
+#define M_SCD_TRSEQ_DEBUGPIN _SB_MAKEMASK1(20)
+#define M_SCD_TRSEQ_DEBUGCPU _SB_MAKEMASK1(21)
+#define M_SCD_TRSEQ_CLEARUSE _SB_MAKEMASK1(22)
+#define M_SCD_TRSEQ_ALLD_A _SB_MAKEMASK1(23)
+#define M_SCD_TRSEQ_ALL_A _SB_MAKEMASK1(24)
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_smbus.h b/arch/mips/include/asm/sibyte/sb1250_smbus.h
new file mode 100644
index 00000000..04769923
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_smbus.h
@@ -0,0 +1,204 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * SMBUS Constants File: sb1250_smbus.h
+ *
+ * This module contains constants and macros useful for
+ * manipulating the SB1250's SMbus devices.
+ *
+ * SB1250 specification level: 10/21/02
+ * BCM1280 specification level: 11/24/03
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_SMBUS_H
+#define _SB1250_SMBUS_H
+
+#include "sb1250_defs.h"
+
+/*
+ * SMBus Clock Frequency Register (Table 14-2)
+ */
+
+#define S_SMB_FREQ_DIV 0
+#define M_SMB_FREQ_DIV _SB_MAKEMASK(13, S_SMB_FREQ_DIV)
+#define V_SMB_FREQ_DIV(x) _SB_MAKEVALUE(x, S_SMB_FREQ_DIV)
+
+#define K_SMB_FREQ_400KHZ 0x1F
+#define K_SMB_FREQ_100KHZ 0x7D
+#define K_SMB_FREQ_10KHZ 1250
+
+#define S_SMB_CMD 0
+#define M_SMB_CMD _SB_MAKEMASK(8, S_SMB_CMD)
+#define V_SMB_CMD(x) _SB_MAKEVALUE(x, S_SMB_CMD)
+
+/*
+ * SMBus control register (Table 14-4)
+ */
+
+#define M_SMB_ERR_INTR _SB_MAKEMASK1(0)
+#define M_SMB_FINISH_INTR _SB_MAKEMASK1(1)
+
+#define S_SMB_DATA_OUT 4
+#define M_SMB_DATA_OUT _SB_MAKEMASK1(S_SMB_DATA_OUT)
+#define V_SMB_DATA_OUT(x) _SB_MAKEVALUE(x, S_SMB_DATA_OUT)
+
+#define M_SMB_DATA_DIR _SB_MAKEMASK1(5)
+#define M_SMB_DATA_DIR_OUTPUT M_SMB_DATA_DIR
+#define M_SMB_CLK_OUT _SB_MAKEMASK1(6)
+#define M_SMB_DIRECT_ENABLE _SB_MAKEMASK1(7)
+
+/*
+ * SMBus status registers (Table 14-5)
+ */
+
+#define M_SMB_BUSY _SB_MAKEMASK1(0)
+#define M_SMB_ERROR _SB_MAKEMASK1(1)
+#define M_SMB_ERROR_TYPE _SB_MAKEMASK1(2)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS3) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+#define S_SMB_SCL_IN 5
+#define M_SMB_SCL_IN _SB_MAKEMASK1(S_SMB_SCL_IN)
+#define V_SMB_SCL_IN(x) _SB_MAKEVALUE(x, S_SMB_SCL_IN)
+#define G_SMB_SCL_IN(x) _SB_GETVALUE(x, S_SMB_SCL_IN, M_SMB_SCL_IN)
+#endif /* 1250 PASS3 || 112x PASS1 || 1480 */
+
+#define S_SMB_REF 6
+#define M_SMB_REF _SB_MAKEMASK1(S_SMB_REF)
+#define V_SMB_REF(x) _SB_MAKEVALUE(x, S_SMB_REF)
+#define G_SMB_REF(x) _SB_GETVALUE(x, S_SMB_REF, M_SMB_REF)
+
+#define S_SMB_DATA_IN 7
+#define M_SMB_DATA_IN _SB_MAKEMASK1(S_SMB_DATA_IN)
+#define V_SMB_DATA_IN(x) _SB_MAKEVALUE(x, S_SMB_DATA_IN)
+#define G_SMB_DATA_IN(x) _SB_GETVALUE(x, S_SMB_DATA_IN, M_SMB_DATA_IN)
+
+/*
+ * SMBus Start/Command registers (Table 14-9)
+ */
+
+#define S_SMB_ADDR 0
+#define M_SMB_ADDR _SB_MAKEMASK(7, S_SMB_ADDR)
+#define V_SMB_ADDR(x) _SB_MAKEVALUE(x, S_SMB_ADDR)
+#define G_SMB_ADDR(x) _SB_GETVALUE(x, S_SMB_ADDR, M_SMB_ADDR)
+
+#define M_SMB_QDATA _SB_MAKEMASK1(7)
+
+#define S_SMB_TT 8
+#define M_SMB_TT _SB_MAKEMASK(3, S_SMB_TT)
+#define V_SMB_TT(x) _SB_MAKEVALUE(x, S_SMB_TT)
+#define G_SMB_TT(x) _SB_GETVALUE(x, S_SMB_TT, M_SMB_TT)
+
+#define K_SMB_TT_WR1BYTE 0
+#define K_SMB_TT_WR2BYTE 1
+#define K_SMB_TT_WR3BYTE 2
+#define K_SMB_TT_CMD_RD1BYTE 3
+#define K_SMB_TT_CMD_RD2BYTE 4
+#define K_SMB_TT_RD1BYTE 5
+#define K_SMB_TT_QUICKCMD 6
+#define K_SMB_TT_EEPROMREAD 7
+
+#define V_SMB_TT_WR1BYTE V_SMB_TT(K_SMB_TT_WR1BYTE)
+#define V_SMB_TT_WR2BYTE V_SMB_TT(K_SMB_TT_WR2BYTE)
+#define V_SMB_TT_WR3BYTE V_SMB_TT(K_SMB_TT_WR3BYTE)
+#define V_SMB_TT_CMD_RD1BYTE V_SMB_TT(K_SMB_TT_CMD_RD1BYTE)
+#define V_SMB_TT_CMD_RD2BYTE V_SMB_TT(K_SMB_TT_CMD_RD2BYTE)
+#define V_SMB_TT_RD1BYTE V_SMB_TT(K_SMB_TT_RD1BYTE)
+#define V_SMB_TT_QUICKCMD V_SMB_TT(K_SMB_TT_QUICKCMD)
+#define V_SMB_TT_EEPROMREAD V_SMB_TT(K_SMB_TT_EEPROMREAD)
+
+#define M_SMB_PEC _SB_MAKEMASK1(15)
+
+/*
+ * SMBus Data Register (Table 14-6) and SMBus Extra Register (Table 14-7)
+ */
+
+#define S_SMB_LB 0
+#define M_SMB_LB _SB_MAKEMASK(8, S_SMB_LB)
+#define V_SMB_LB(x) _SB_MAKEVALUE(x, S_SMB_LB)
+
+#define S_SMB_MB 8
+#define M_SMB_MB _SB_MAKEMASK(8, S_SMB_MB)
+#define V_SMB_MB(x) _SB_MAKEVALUE(x, S_SMB_MB)
+
+
+/*
+ * SMBus Packet Error Check register (Table 14-8)
+ */
+
+#define S_SPEC_PEC 0
+#define M_SPEC_PEC _SB_MAKEMASK(8, S_SPEC_PEC)
+#define V_SPEC_MB(x) _SB_MAKEVALUE(x, S_SPEC_PEC)
+
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+
+#define S_SMB_CMDH 8
+#define M_SMB_CMDH _SB_MAKEMASK(8, S_SMB_CMDH)
+#define V_SMB_CMDH(x) _SB_MAKEVALUE(x, S_SMB_CMDH)
+
+#define M_SMB_EXTEND _SB_MAKEMASK1(14)
+
+#define S_SMB_DFMT 8
+#define M_SMB_DFMT _SB_MAKEMASK(3, S_SMB_DFMT)
+#define V_SMB_DFMT(x) _SB_MAKEVALUE(x, S_SMB_DFMT)
+#define G_SMB_DFMT(x) _SB_GETVALUE(x, S_SMB_DFMT, M_SMB_DFMT)
+
+#define K_SMB_DFMT_1BYTE 0
+#define K_SMB_DFMT_2BYTE 1
+#define K_SMB_DFMT_3BYTE 2
+#define K_SMB_DFMT_4BYTE 3
+#define K_SMB_DFMT_NODATA 4
+#define K_SMB_DFMT_CMD4BYTE 5
+#define K_SMB_DFMT_CMD5BYTE 6
+#define K_SMB_DFMT_RESERVED 7
+
+#define V_SMB_DFMT_1BYTE V_SMB_DFMT(K_SMB_DFMT_1BYTE)
+#define V_SMB_DFMT_2BYTE V_SMB_DFMT(K_SMB_DFMT_2BYTE)
+#define V_SMB_DFMT_3BYTE V_SMB_DFMT(K_SMB_DFMT_3BYTE)
+#define V_SMB_DFMT_4BYTE V_SMB_DFMT(K_SMB_DFMT_4BYTE)
+#define V_SMB_DFMT_NODATA V_SMB_DFMT(K_SMB_DFMT_NODATA)
+#define V_SMB_DFMT_CMD4BYTE V_SMB_DFMT(K_SMB_DFMT_CMD4BYTE)
+#define V_SMB_DFMT_CMD5BYTE V_SMB_DFMT(K_SMB_DFMT_CMD5BYTE)
+#define V_SMB_DFMT_RESERVED V_SMB_DFMT(K_SMB_DFMT_RESERVED)
+
+#define S_SMB_AFMT 11
+#define M_SMB_AFMT _SB_MAKEMASK(2, S_SMB_AFMT)
+#define V_SMB_AFMT(x) _SB_MAKEVALUE(x, S_SMB_AFMT)
+#define G_SMB_AFMT(x) _SB_GETVALUE(x, S_SMB_AFMT, M_SMB_AFMT)
+
+#define K_SMB_AFMT_NONE 0
+#define K_SMB_AFMT_ADDR 1
+#define K_SMB_AFMT_ADDR_CMD1BYTE 2
+#define K_SMB_AFMT_ADDR_CMD2BYTE 3
+
+#define V_SMB_AFMT_NONE V_SMB_AFMT(K_SMB_AFMT_NONE)
+#define V_SMB_AFMT_ADDR V_SMB_AFMT(K_SMB_AFMT_ADDR)
+#define V_SMB_AFMT_ADDR_CMD1BYTE V_SMB_AFMT(K_SMB_AFMT_ADDR_CMD1BYTE)
+#define V_SMB_AFMT_ADDR_CMD2BYTE V_SMB_AFMT(K_SMB_AFMT_ADDR_CMD2BYTE)
+
+#define M_SMB_DIR _SB_MAKEMASK1(13)
+
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_syncser.h b/arch/mips/include/asm/sibyte/sb1250_syncser.h
new file mode 100644
index 00000000..d4b8558e
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_syncser.h
@@ -0,0 +1,146 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * Synchronous Serial Constants File: sb1250_syncser.h
+ *
+ * This module contains constants and macros useful for
+ * manipulating the SB1250's Synchronous Serial
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_SYNCSER_H
+#define _SB1250_SYNCSER_H
+
+#include "sb1250_defs.h"
+
+/*
+ * Serial Mode Configuration Register
+ */
+
+#define M_SYNCSER_CRC_MODE _SB_MAKEMASK1(0)
+#define M_SYNCSER_MSB_FIRST _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_FLAG_NUM 2
+#define M_SYNCSER_FLAG_NUM _SB_MAKEMASK(4, S_SYNCSER_FLAG_NUM)
+#define V_SYNCSER_FLAG_NUM _SB_MAKEVALUE(x, S_SYNCSER_FLAG_NUM)
+
+#define M_SYNCSER_FLAG_EN _SB_MAKEMASK1(6)
+#define M_SYNCSER_HDLC_EN _SB_MAKEMASK1(7)
+#define M_SYNCSER_LOOP_MODE _SB_MAKEMASK1(8)
+#define M_SYNCSER_LOOPBACK _SB_MAKEMASK1(9)
+
+/*
+ * Serial Clock Source and Line Interface Mode Register
+ */
+
+#define M_SYNCSER_RXCLK_INV _SB_MAKEMASK1(0)
+#define M_SYNCSER_RXCLK_EXT _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_RXSYNC_DLY 2
+#define M_SYNCSER_RXSYNC_DLY _SB_MAKEMASK(2, S_SYNCSER_RXSYNC_DLY)
+#define V_SYNCSER_RXSYNC_DLY(x) _SB_MAKEVALUE(x, S_SYNCSER_RXSYNC_DLY)
+
+#define M_SYNCSER_RXSYNC_LOW _SB_MAKEMASK1(4)
+#define M_SYNCSER_RXSTRB_LOW _SB_MAKEMASK1(5)
+
+#define M_SYNCSER_RXSYNC_EDGE _SB_MAKEMASK1(6)
+#define M_SYNCSER_RXSYNC_INT _SB_MAKEMASK1(7)
+
+#define M_SYNCSER_TXCLK_INV _SB_MAKEMASK1(8)
+#define M_SYNCSER_TXCLK_EXT _SB_MAKEMASK1(9)
+
+#define S_SYNCSER_TXSYNC_DLY 10
+#define M_SYNCSER_TXSYNC_DLY _SB_MAKEMASK(2, S_SYNCSER_TXSYNC_DLY)
+#define V_SYNCSER_TXSYNC_DLY(x) _SB_MAKEVALUE(x, S_SYNCSER_TXSYNC_DLY)
+
+#define M_SYNCSER_TXSYNC_LOW _SB_MAKEMASK1(12)
+#define M_SYNCSER_TXSTRB_LOW _SB_MAKEMASK1(13)
+
+#define M_SYNCSER_TXSYNC_EDGE _SB_MAKEMASK1(14)
+#define M_SYNCSER_TXSYNC_INT _SB_MAKEMASK1(15)
+
+/*
+ * Serial Command Register
+ */
+
+#define M_SYNCSER_CMD_RX_EN _SB_MAKEMASK1(0)
+#define M_SYNCSER_CMD_TX_EN _SB_MAKEMASK1(1)
+#define M_SYNCSER_CMD_RX_RESET _SB_MAKEMASK1(2)
+#define M_SYNCSER_CMD_TX_RESET _SB_MAKEMASK1(3)
+#define M_SYNCSER_CMD_TX_PAUSE _SB_MAKEMASK1(5)
+
+/*
+ * Serial DMA Enable Register
+ */
+
+#define M_SYNCSER_DMA_RX_EN _SB_MAKEMASK1(0)
+#define M_SYNCSER_DMA_TX_EN _SB_MAKEMASK1(4)
+
+/*
+ * Serial Status Register
+ */
+
+#define M_SYNCSER_RX_CRCERR _SB_MAKEMASK1(0)
+#define M_SYNCSER_RX_ABORT _SB_MAKEMASK1(1)
+#define M_SYNCSER_RX_OCTET _SB_MAKEMASK1(2)
+#define M_SYNCSER_RX_LONGFRM _SB_MAKEMASK1(3)
+#define M_SYNCSER_RX_SHORTFRM _SB_MAKEMASK1(4)
+#define M_SYNCSER_RX_OVERRUN _SB_MAKEMASK1(5)
+#define M_SYNCSER_RX_SYNC_ERR _SB_MAKEMASK1(6)
+#define M_SYNCSER_TX_CRCERR _SB_MAKEMASK1(8)
+#define M_SYNCSER_TX_UNDERRUN _SB_MAKEMASK1(9)
+#define M_SYNCSER_TX_SYNC_ERR _SB_MAKEMASK1(10)
+#define M_SYNCSER_TX_PAUSE_COMPLETE _SB_MAKEMASK1(11)
+#define M_SYNCSER_RX_EOP_COUNT _SB_MAKEMASK1(16)
+#define M_SYNCSER_RX_EOP_TIMER _SB_MAKEMASK1(17)
+#define M_SYNCSER_RX_EOP_SEEN _SB_MAKEMASK1(18)
+#define M_SYNCSER_RX_HWM _SB_MAKEMASK1(19)
+#define M_SYNCSER_RX_LWM _SB_MAKEMASK1(20)
+#define M_SYNCSER_RX_DSCR _SB_MAKEMASK1(21)
+#define M_SYNCSER_RX_DERR _SB_MAKEMASK1(22)
+#define M_SYNCSER_TX_EOP_COUNT _SB_MAKEMASK1(24)
+#define M_SYNCSER_TX_EOP_TIMER _SB_MAKEMASK1(25)
+#define M_SYNCSER_TX_EOP_SEEN _SB_MAKEMASK1(26)
+#define M_SYNCSER_TX_HWM _SB_MAKEMASK1(27)
+#define M_SYNCSER_TX_LWM _SB_MAKEMASK1(28)
+#define M_SYNCSER_TX_DSCR _SB_MAKEMASK1(29)
+#define M_SYNCSER_TX_DERR _SB_MAKEMASK1(30)
+#define M_SYNCSER_TX_DZERO _SB_MAKEMASK1(31)
+
+/*
+ * Sequencer Table Entry format
+ */
+
+#define M_SYNCSER_SEQ_LAST _SB_MAKEMASK1(0)
+#define M_SYNCSER_SEQ_BYTE _SB_MAKEMASK1(1)
+
+#define S_SYNCSER_SEQ_COUNT 2
+#define M_SYNCSER_SEQ_COUNT _SB_MAKEMASK(4, S_SYNCSER_SEQ_COUNT)
+#define V_SYNCSER_SEQ_COUNT(x) _SB_MAKEVALUE(x, S_SYNCSER_SEQ_COUNT)
+
+#define M_SYNCSER_SEQ_ENABLE _SB_MAKEMASK1(6)
+#define M_SYNCSER_SEQ_STROBE _SB_MAKEMASK1(7)
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sb1250_uart.h b/arch/mips/include/asm/sibyte/sb1250_uart.h
new file mode 100644
index 00000000..d835bf28
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sb1250_uart.h
@@ -0,0 +1,362 @@
+/* *********************************************************************
+ * SB1250 Board Support Package
+ *
+ * UART Constants File: sb1250_uart.h
+ *
+ * This module contains constants and macros useful for
+ * manipulating the SB1250's UARTs
+ *
+ * SB1250 specification level: User's manual 1/02/02
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ ********************************************************************* */
+
+
+#ifndef _SB1250_UART_H
+#define _SB1250_UART_H
+
+#include "sb1250_defs.h"
+
+/* **********************************************************************
+ * DUART Registers
+ ********************************************************************** */
+
+/*
+ * DUART Mode Register #1 (Table 10-3)
+ * Register: DUART_MODE_REG_1_A
+ * Register: DUART_MODE_REG_1_B
+ */
+
+#define S_DUART_BITS_PER_CHAR 0
+#define M_DUART_BITS_PER_CHAR _SB_MAKEMASK(2, S_DUART_BITS_PER_CHAR)
+#define V_DUART_BITS_PER_CHAR(x) _SB_MAKEVALUE(x, S_DUART_BITS_PER_CHAR)
+
+#define K_DUART_BITS_PER_CHAR_RSV0 0
+#define K_DUART_BITS_PER_CHAR_RSV1 1
+#define K_DUART_BITS_PER_CHAR_7 2
+#define K_DUART_BITS_PER_CHAR_8 3
+
+#define V_DUART_BITS_PER_CHAR_RSV0 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV0)
+#define V_DUART_BITS_PER_CHAR_RSV1 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV1)
+#define V_DUART_BITS_PER_CHAR_7 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_7)
+#define V_DUART_BITS_PER_CHAR_8 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_8)
+
+
+#define M_DUART_PARITY_TYPE_EVEN 0x00
+#define M_DUART_PARITY_TYPE_ODD _SB_MAKEMASK1(2)
+
+#define S_DUART_PARITY_MODE 3
+#define M_DUART_PARITY_MODE _SB_MAKEMASK(2, S_DUART_PARITY_MODE)
+#define V_DUART_PARITY_MODE(x) _SB_MAKEVALUE(x, S_DUART_PARITY_MODE)
+
+#define K_DUART_PARITY_MODE_ADD 0
+#define K_DUART_PARITY_MODE_ADD_FIXED 1
+#define K_DUART_PARITY_MODE_NONE 2
+
+#define V_DUART_PARITY_MODE_ADD V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD)
+#define V_DUART_PARITY_MODE_ADD_FIXED V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD_FIXED)
+#define V_DUART_PARITY_MODE_NONE V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_NONE)
+
+#define M_DUART_TX_IRQ_SEL_TXRDY 0
+#define M_DUART_TX_IRQ_SEL_TXEMPT _SB_MAKEMASK1(5)
+
+#define M_DUART_RX_IRQ_SEL_RXRDY 0
+#define M_DUART_RX_IRQ_SEL_RXFULL _SB_MAKEMASK1(6)
+
+#define M_DUART_RX_RTS_ENA _SB_MAKEMASK1(7)
+
+/*
+ * DUART Mode Register #2 (Table 10-4)
+ * Register: DUART_MODE_REG_2_A
+ * Register: DUART_MODE_REG_2_B
+ */
+
+#define M_DUART_MODE_RESERVED1 _SB_MAKEMASK(3, 0) /* ignored */
+
+#define M_DUART_STOP_BIT_LEN_2 _SB_MAKEMASK1(3)
+#define M_DUART_STOP_BIT_LEN_1 0
+
+#define M_DUART_TX_CTS_ENA _SB_MAKEMASK1(4)
+
+
+#define M_DUART_MODE_RESERVED2 _SB_MAKEMASK1(5) /* must be zero */
+
+#define S_DUART_CHAN_MODE 6
+#define M_DUART_CHAN_MODE _SB_MAKEMASK(2, S_DUART_CHAN_MODE)
+#define V_DUART_CHAN_MODE(x) _SB_MAKEVALUE(x, S_DUART_CHAN_MODE)
+
+#define K_DUART_CHAN_MODE_NORMAL 0
+#define K_DUART_CHAN_MODE_LCL_LOOP 2
+#define K_DUART_CHAN_MODE_REM_LOOP 3
+
+#define V_DUART_CHAN_MODE_NORMAL V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_NORMAL)
+#define V_DUART_CHAN_MODE_LCL_LOOP V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_LCL_LOOP)
+#define V_DUART_CHAN_MODE_REM_LOOP V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_REM_LOOP)
+
+/*
+ * DUART Command Register (Table 10-5)
+ * Register: DUART_CMD_A
+ * Register: DUART_CMD_B
+ */
+
+#define M_DUART_RX_EN _SB_MAKEMASK1(0)
+#define M_DUART_RX_DIS _SB_MAKEMASK1(1)
+#define M_DUART_TX_EN _SB_MAKEMASK1(2)
+#define M_DUART_TX_DIS _SB_MAKEMASK1(3)
+
+#define S_DUART_MISC_CMD 4
+#define M_DUART_MISC_CMD _SB_MAKEMASK(3, S_DUART_MISC_CMD)
+#define V_DUART_MISC_CMD(x) _SB_MAKEVALUE(x, S_DUART_MISC_CMD)
+
+#define K_DUART_MISC_CMD_NOACTION0 0
+#define K_DUART_MISC_CMD_NOACTION1 1
+#define K_DUART_MISC_CMD_RESET_RX 2
+#define K_DUART_MISC_CMD_RESET_TX 3
+#define K_DUART_MISC_CMD_NOACTION4 4
+#define K_DUART_MISC_CMD_RESET_BREAK_INT 5
+#define K_DUART_MISC_CMD_START_BREAK 6
+#define K_DUART_MISC_CMD_STOP_BREAK 7
+
+#define V_DUART_MISC_CMD_NOACTION0 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION0)
+#define V_DUART_MISC_CMD_NOACTION1 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION1)
+#define V_DUART_MISC_CMD_RESET_RX V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_RX)
+#define V_DUART_MISC_CMD_RESET_TX V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_TX)
+#define V_DUART_MISC_CMD_NOACTION4 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION4)
+#define V_DUART_MISC_CMD_RESET_BREAK_INT V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_BREAK_INT)
+#define V_DUART_MISC_CMD_START_BREAK V_DUART_MISC_CMD(K_DUART_MISC_CMD_START_BREAK)
+#define V_DUART_MISC_CMD_STOP_BREAK V_DUART_MISC_CMD(K_DUART_MISC_CMD_STOP_BREAK)
+
+#define M_DUART_CMD_RESERVED _SB_MAKEMASK1(7)
+
+/*
+ * DUART Status Register (Table 10-6)
+ * Register: DUART_STATUS_A
+ * Register: DUART_STATUS_B
+ * READ-ONLY
+ */
+
+#define M_DUART_RX_RDY _SB_MAKEMASK1(0)
+#define M_DUART_RX_FFUL _SB_MAKEMASK1(1)
+#define M_DUART_TX_RDY _SB_MAKEMASK1(2)
+#define M_DUART_TX_EMT _SB_MAKEMASK1(3)
+#define M_DUART_OVRUN_ERR _SB_MAKEMASK1(4)
+#define M_DUART_PARITY_ERR _SB_MAKEMASK1(5)
+#define M_DUART_FRM_ERR _SB_MAKEMASK1(6)
+#define M_DUART_RCVD_BRK _SB_MAKEMASK1(7)
+
+/*
+ * DUART Baud Rate Register (Table 10-7)
+ * Register: DUART_CLK_SEL_A
+ * Register: DUART_CLK_SEL_B
+ */
+
+#define M_DUART_CLK_COUNTER _SB_MAKEMASK(12, 0)
+#define V_DUART_BAUD_RATE(x) (100000000/((x)*20)-1)
+
+/*
+ * DUART Data Registers (Table 10-8 and 10-9)
+ * Register: DUART_RX_HOLD_A
+ * Register: DUART_RX_HOLD_B
+ * Register: DUART_TX_HOLD_A
+ * Register: DUART_TX_HOLD_B
+ */
+
+#define M_DUART_RX_DATA _SB_MAKEMASK(8, 0)
+#define M_DUART_TX_DATA _SB_MAKEMASK(8, 0)
+
+/*
+ * DUART Input Port Register (Table 10-10)
+ * Register: DUART_IN_PORT
+ */
+
+#define M_DUART_IN_PIN0_VAL _SB_MAKEMASK1(0)
+#define M_DUART_IN_PIN1_VAL _SB_MAKEMASK1(1)
+#define M_DUART_IN_PIN2_VAL _SB_MAKEMASK1(2)
+#define M_DUART_IN_PIN3_VAL _SB_MAKEMASK1(3)
+#define M_DUART_IN_PIN4_VAL _SB_MAKEMASK1(4)
+#define M_DUART_IN_PIN5_VAL _SB_MAKEMASK1(5)
+#define M_DUART_RIN0_PIN _SB_MAKEMASK1(6)
+#define M_DUART_RIN1_PIN _SB_MAKEMASK1(7)
+
+/*
+ * DUART Input Port Change Status Register (Tables 10-11, 10-12, and 10-13)
+ * Register: DUART_INPORT_CHNG
+ */
+
+#define S_DUART_IN_PIN_VAL 0
+#define M_DUART_IN_PIN_VAL _SB_MAKEMASK(4, S_DUART_IN_PIN_VAL)
+
+#define S_DUART_IN_PIN_CHNG 4
+#define M_DUART_IN_PIN_CHNG _SB_MAKEMASK(4, S_DUART_IN_PIN_CHNG)
+
+
+/*
+ * DUART Output port control register (Table 10-14)
+ * Register: DUART_OPCR
+ */
+
+#define M_DUART_OPCR_RESERVED0 _SB_MAKEMASK1(0) /* must be zero */
+#define M_DUART_OPC2_SEL _SB_MAKEMASK1(1)
+#define M_DUART_OPCR_RESERVED1 _SB_MAKEMASK1(2) /* must be zero */
+#define M_DUART_OPC3_SEL _SB_MAKEMASK1(3)
+#define M_DUART_OPCR_RESERVED2 _SB_MAKEMASK(4, 4) /* must be zero */
+
+/*
+ * DUART Aux Control Register (Table 10-15)
+ * Register: DUART_AUX_CTRL
+ */
+
+#define M_DUART_IP0_CHNG_ENA _SB_MAKEMASK1(0)
+#define M_DUART_IP1_CHNG_ENA _SB_MAKEMASK1(1)
+#define M_DUART_IP2_CHNG_ENA _SB_MAKEMASK1(2)
+#define M_DUART_IP3_CHNG_ENA _SB_MAKEMASK1(3)
+#define M_DUART_ACR_RESERVED _SB_MAKEMASK(4, 4)
+
+#define M_DUART_CTS_CHNG_ENA _SB_MAKEMASK1(0)
+#define M_DUART_CIN_CHNG_ENA _SB_MAKEMASK1(2)
+
+/*
+ * DUART Interrupt Status Register (Table 10-16)
+ * Register: DUART_ISR
+ */
+
+#define M_DUART_ISR_TX_A _SB_MAKEMASK1(0)
+
+#define S_DUART_ISR_RX_A 1
+#define M_DUART_ISR_RX_A _SB_MAKEMASK1(S_DUART_ISR_RX_A)
+#define V_DUART_ISR_RX_A(x) _SB_MAKEVALUE(x, S_DUART_ISR_RX_A)
+#define G_DUART_ISR_RX_A(x) _SB_GETVALUE(x, S_DUART_ISR_RX_A, M_DUART_ISR_RX_A)
+
+#define M_DUART_ISR_BRK_A _SB_MAKEMASK1(2)
+#define M_DUART_ISR_IN_A _SB_MAKEMASK1(3)
+#define M_DUART_ISR_ALL_A _SB_MAKEMASK(4, 0)
+
+#define M_DUART_ISR_TX_B _SB_MAKEMASK1(4)
+#define M_DUART_ISR_RX_B _SB_MAKEMASK1(5)
+#define M_DUART_ISR_BRK_B _SB_MAKEMASK1(6)
+#define M_DUART_ISR_IN_B _SB_MAKEMASK1(7)
+#define M_DUART_ISR_ALL_B _SB_MAKEMASK(4, 4)
+
+/*
+ * DUART Channel A Interrupt Status Register (Table 10-17)
+ * DUART Channel B Interrupt Status Register (Table 10-18)
+ * Register: DUART_ISR_A
+ * Register: DUART_ISR_B
+ */
+
+#define M_DUART_ISR_TX _SB_MAKEMASK1(0)
+#define M_DUART_ISR_RX _SB_MAKEMASK1(1)
+#define M_DUART_ISR_BRK _SB_MAKEMASK1(2)
+#define M_DUART_ISR_IN _SB_MAKEMASK1(3)
+#define M_DUART_ISR_ALL _SB_MAKEMASK(4, 0)
+#define M_DUART_ISR_RESERVED _SB_MAKEMASK(4, 4)
+
+/*
+ * DUART Interrupt Mask Register (Table 10-19)
+ * Register: DUART_IMR
+ */
+
+#define M_DUART_IMR_TX_A _SB_MAKEMASK1(0)
+#define M_DUART_IMR_RX_A _SB_MAKEMASK1(1)
+#define M_DUART_IMR_BRK_A _SB_MAKEMASK1(2)
+#define M_DUART_IMR_IN_A _SB_MAKEMASK1(3)
+#define M_DUART_IMR_ALL_A _SB_MAKEMASK(4, 0)
+
+#define M_DUART_IMR_TX_B _SB_MAKEMASK1(4)
+#define M_DUART_IMR_RX_B _SB_MAKEMASK1(5)
+#define M_DUART_IMR_BRK_B _SB_MAKEMASK1(6)
+#define M_DUART_IMR_IN_B _SB_MAKEMASK1(7)
+#define M_DUART_IMR_ALL_B _SB_MAKEMASK(4, 4)
+
+/*
+ * DUART Channel A Interrupt Mask Register (Table 10-20)
+ * DUART Channel B Interrupt Mask Register (Table 10-21)
+ * Register: DUART_IMR_A
+ * Register: DUART_IMR_B
+ */
+
+#define M_DUART_IMR_TX _SB_MAKEMASK1(0)
+#define M_DUART_IMR_RX _SB_MAKEMASK1(1)
+#define M_DUART_IMR_BRK _SB_MAKEMASK1(2)
+#define M_DUART_IMR_IN _SB_MAKEMASK1(3)
+#define M_DUART_IMR_ALL _SB_MAKEMASK(4, 0)
+#define M_DUART_IMR_RESERVED _SB_MAKEMASK(4, 4)
+
+
+/*
+ * DUART Output Port Set Register (Table 10-22)
+ * Register: DUART_SET_OPR
+ */
+
+#define M_DUART_SET_OPR0 _SB_MAKEMASK1(0)
+#define M_DUART_SET_OPR1 _SB_MAKEMASK1(1)
+#define M_DUART_SET_OPR2 _SB_MAKEMASK1(2)
+#define M_DUART_SET_OPR3 _SB_MAKEMASK1(3)
+#define M_DUART_OPSR_RESERVED _SB_MAKEMASK(4, 4)
+
+/*
+ * DUART Output Port Clear Register (Table 10-23)
+ * Register: DUART_CLEAR_OPR
+ */
+
+#define M_DUART_CLR_OPR0 _SB_MAKEMASK1(0)
+#define M_DUART_CLR_OPR1 _SB_MAKEMASK1(1)
+#define M_DUART_CLR_OPR2 _SB_MAKEMASK1(2)
+#define M_DUART_CLR_OPR3 _SB_MAKEMASK1(3)
+#define M_DUART_OPCR_RESERVED _SB_MAKEMASK(4, 4)
+
+/*
+ * DUART Output Port RTS Register (Table 10-24)
+ * Register: DUART_OUT_PORT
+ */
+
+#define M_DUART_OUT_PIN_SET0 _SB_MAKEMASK1(0)
+#define M_DUART_OUT_PIN_SET1 _SB_MAKEMASK1(1)
+#define M_DUART_OUT_PIN_CLR0 _SB_MAKEMASK1(2)
+#define M_DUART_OUT_PIN_CLR1 _SB_MAKEMASK1(3)
+#define M_DUART_OPRR_RESERVED _SB_MAKEMASK(4, 4)
+
+#define M_DUART_OUT_PIN_SET(chan) \
+ (chan == 0 ? M_DUART_OUT_PIN_SET0 : M_DUART_OUT_PIN_SET1)
+#define M_DUART_OUT_PIN_CLR(chan) \
+ (chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1)
+
+#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) || SIBYTE_HDR_FEATURE_CHIP(1480)
+/*
+ * Full Interrupt Control Register
+ */
+
+#define S_DUART_SIG_FULL _SB_MAKE64(0)
+#define M_DUART_SIG_FULL _SB_MAKEMASK(4, S_DUART_SIG_FULL)
+#define V_DUART_SIG_FULL(x) _SB_MAKEVALUE(x, S_DUART_SIG_FULL)
+#define G_DUART_SIG_FULL(x) _SB_GETVALUE(x, S_DUART_SIG_FULL, M_DUART_SIG_FULL)
+
+#define S_DUART_INT_TIME _SB_MAKE64(4)
+#define M_DUART_INT_TIME _SB_MAKEMASK(4, S_DUART_INT_TIME)
+#define V_DUART_INT_TIME(x) _SB_MAKEVALUE(x, S_DUART_INT_TIME)
+#define G_DUART_INT_TIME(x) _SB_GETVALUE(x, S_DUART_INT_TIME, M_DUART_INT_TIME)
+#endif /* 1250 PASS2 || 112x PASS1 || 1480 */
+
+
+/* ********************************************************************** */
+
+
+#endif
diff --git a/arch/mips/include/asm/sibyte/sentosa.h b/arch/mips/include/asm/sibyte/sentosa.h
new file mode 100644
index 00000000..64c47874
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/sentosa.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __ASM_SIBYTE_SENTOSA_H
+#define __ASM_SIBYTE_SENTOSA_H
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_int.h>
+
+#ifdef CONFIG_SIBYTE_SENTOSA
+#define SIBYTE_BOARD_NAME "BCM91250E (Sentosa)"
+#endif
+#ifdef CONFIG_SIBYTE_RHONE
+#define SIBYTE_BOARD_NAME "BCM91125E (Rhone)"
+#endif
+
+/* Generic bus chip selects */
+#ifdef CONFIG_SIBYTE_RHONE
+#define LEDS_CS 6
+#define LEDS_PHYS 0x1d0a0000
+#endif
+
+/* GPIOs */
+#define K_GPIO_DBG_LED 0
+
+#endif /* __ASM_SIBYTE_SENTOSA_H */
diff --git a/arch/mips/include/asm/sibyte/swarm.h b/arch/mips/include/asm/sibyte/swarm.h
new file mode 100644
index 00000000..114d9d29
--- /dev/null
+++ b/arch/mips/include/asm/sibyte/swarm.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __ASM_SIBYTE_SWARM_H
+#define __ASM_SIBYTE_SWARM_H
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_int.h>
+
+#ifdef CONFIG_SIBYTE_SWARM
+#define SIBYTE_BOARD_NAME "BCM91250A (SWARM)"
+#define SIBYTE_HAVE_PCMCIA 1
+#define SIBYTE_HAVE_IDE 1
+#endif
+#ifdef CONFIG_SIBYTE_LITTLESUR
+#define SIBYTE_BOARD_NAME "BCM91250C2 (LittleSur)"
+#define SIBYTE_HAVE_PCMCIA 0
+#define SIBYTE_HAVE_IDE 1
+#define SIBYTE_DEFAULT_CONSOLE "cfe0"
+#endif
+#ifdef CONFIG_SIBYTE_CRHONE
+#define SIBYTE_BOARD_NAME "BCM91125C (CRhone)"
+#define SIBYTE_HAVE_PCMCIA 0
+#define SIBYTE_HAVE_IDE 0
+#endif
+#ifdef CONFIG_SIBYTE_CRHINE
+#define SIBYTE_BOARD_NAME "BCM91120C (CRhine)"
+#define SIBYTE_HAVE_PCMCIA 0
+#define SIBYTE_HAVE_IDE 0
+#endif
+
+/* Generic bus chip selects */
+#define LEDS_CS 3
+#define LEDS_PHYS 0x100a0000
+
+#ifdef SIBYTE_HAVE_IDE
+#define IDE_CS 4
+#define IDE_PHYS 0x100b0000
+#define K_GPIO_GB_IDE 4
+#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE)
+#endif
+
+#ifdef SIBYTE_HAVE_PCMCIA
+#define PCMCIA_CS 6
+#define PCMCIA_PHYS 0x11000000
+#define K_GPIO_PC_READY 9
+#define K_INT_PC_READY (K_INT_GPIO_0 + K_GPIO_PC_READY)
+#endif
+
+#endif /* __ASM_SIBYTE_SWARM_H */
diff --git a/arch/mips/include/asm/sigcontext.h b/arch/mips/include/asm/sigcontext.h
new file mode 100644
index 00000000..9e89cf99
--- /dev/null
+++ b/arch/mips/include/asm/sigcontext.h
@@ -0,0 +1,101 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+#include <linux/types.h>
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
+ * Keep this struct definition in sync with the sigcontext fragment
+ * in arch/mips/tools/offset.c
+ */
+struct sigcontext {
+ unsigned int sc_regmask; /* Unused */
+ unsigned int sc_status; /* Unused */
+ unsigned long long sc_pc;
+ unsigned long long sc_regs[32];
+ unsigned long long sc_fpregs[32];
+ unsigned int sc_acx; /* Was sc_ownedfp */
+ unsigned int sc_fpc_csr;
+ unsigned int sc_fpc_eir; /* Unused */
+ unsigned int sc_used_math;
+ unsigned int sc_dsp; /* dsp status, was sc_ssflags */
+ unsigned long long sc_mdhi;
+ unsigned long long sc_mdlo;
+ unsigned long sc_hi1; /* Was sc_cause */
+ unsigned long sc_lo1; /* Was sc_badvaddr */
+ unsigned long sc_hi2; /* Was sc_sigset[4] */
+ unsigned long sc_lo2;
+ unsigned long sc_hi3;
+ unsigned long sc_lo3;
+};
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
+
+#include <linux/posix_types.h>
+/*
+ * Keep this struct definition in sync with the sigcontext fragment
+ * in arch/mips/tools/offset.c
+ *
+ * Warning: this structure illdefined with sc_badvaddr being just an unsigned
+ * int so it was changed to unsigned long in 2.6.0-test1. This may break
+ * binary compatibility - no prisoners.
+ * DSP ASE in 2.6.12-rc4. Turn sc_mdhi and sc_mdlo into an array of four
+ * entries, add sc_dsp and sc_reserved for padding. No prisoners.
+ */
+struct sigcontext {
+ __u64 sc_regs[32];
+ __u64 sc_fpregs[32];
+ __u64 sc_mdhi;
+ __u64 sc_hi1;
+ __u64 sc_hi2;
+ __u64 sc_hi3;
+ __u64 sc_mdlo;
+ __u64 sc_lo1;
+ __u64 sc_lo2;
+ __u64 sc_lo3;
+ __u64 sc_pc;
+ __u32 sc_fpc_csr;
+ __u32 sc_used_math;
+ __u32 sc_dsp;
+ __u32 sc_reserved;
+};
+
+#ifdef __KERNEL__
+
+struct sigcontext32 {
+ __u32 sc_regmask; /* Unused */
+ __u32 sc_status; /* Unused */
+ __u64 sc_pc;
+ __u64 sc_regs[32];
+ __u64 sc_fpregs[32];
+ __u32 sc_acx; /* Only MIPS32; was sc_ownedfp */
+ __u32 sc_fpc_csr;
+ __u32 sc_fpc_eir; /* Unused */
+ __u32 sc_used_math;
+ __u32 sc_dsp; /* dsp status, was sc_ssflags */
+ __u64 sc_mdhi;
+ __u64 sc_mdlo;
+ __u32 sc_hi1; /* Was sc_cause */
+ __u32 sc_lo1; /* Was sc_badvaddr */
+ __u32 sc_hi2; /* Was sc_sigset[4] */
+ __u32 sc_lo2;
+ __u32 sc_hi3;
+ __u32 sc_lo3;
+};
+#endif /* __KERNEL__ */
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */
+
+#endif /* _ASM_SIGCONTEXT_H */
diff --git a/arch/mips/include/asm/siginfo.h b/arch/mips/include/asm/siginfo.h
new file mode 100644
index 00000000..20ebeb87
--- /dev/null
+++ b/arch/mips/include/asm/siginfo.h
@@ -0,0 +1,131 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999, 2001, 2003 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SIGINFO_H
+#define _ASM_SIGINFO_H
+
+
+#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int))
+#undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */
+
+#define HAVE_ARCH_SIGINFO_T
+
+/*
+ * We duplicate the generic versions - <asm-generic/siginfo.h> is just borked
+ * by design ...
+ */
+#define HAVE_ARCH_COPY_SIGINFO
+struct siginfo;
+
+/*
+ * Careful to keep union _sifields from shifting ...
+ */
+#ifdef CONFIG_32BIT
+#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
+#endif
+#ifdef CONFIG_64BIT
+#define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#endif
+
+#include <asm-generic/siginfo.h>
+
+typedef struct siginfo {
+ int si_signo;
+ int si_code;
+ int si_errno;
+ int __pad0[SI_MAX_SIZE / sizeof(int) - SI_PAD_SIZE - 3];
+
+ union {
+ int _pad[SI_PAD_SIZE];
+
+ /* kill() */
+ struct {
+ pid_t _pid; /* sender's pid */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+ sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ pid_t _pid; /* sender's pid */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ pid_t _pid; /* which child */
+ __ARCH_SI_UID_T _uid; /* sender's uid */
+ int _status; /* exit code */
+ clock_t _utime;
+ clock_t _stime;
+ } _sigchld;
+
+ /* IRIX SIGCHLD */
+ struct {
+ pid_t _pid; /* which child */
+ clock_t _utime;
+ int _status; /* exit code */
+ clock_t _stime;
+ } _irix_sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ void __user *_addr; /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+ int _trapno; /* TRAP # which caused the signal */
+#endif
+ short _addr_lsb;
+ } _sigfault;
+
+ /* SIGPOLL, SIGXFSZ (To do ...) */
+ struct {
+ __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} siginfo_t;
+
+/*
+ * si_code values
+ * Again these have been chosen to be IRIX compatible.
+ */
+#undef SI_ASYNCIO
+#undef SI_TIMER
+#undef SI_MESGQ
+#define SI_ASYNCIO -2 /* sent by AIO completion */
+#define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */
+#define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */
+
+#ifdef __KERNEL__
+
+/*
+ * Duplicated here because of <asm-generic/siginfo.h> braindamage ...
+ */
+#include <linux/string.h>
+
+static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
+{
+ if (from->si_code < 0)
+ memcpy(to, from, sizeof(*to));
+ else
+ /* _sigchld is currently the largest know union member */
+ memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+#endif
+
+#endif /* _ASM_SIGINFO_H */
diff --git a/arch/mips/include/asm/signal.h b/arch/mips/include/asm/signal.h
new file mode 100644
index 00000000..c783f364
--- /dev/null
+++ b/arch/mips/include/asm/signal.h
@@ -0,0 +1,139 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 97, 98, 99, 2003 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+#define _NSIG 128
+#define _NSIG_BPW (sizeof(unsigned long) * 8)
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+#define SIGHUP 1 /* Hangup (POSIX). */
+#define SIGINT 2 /* Interrupt (ANSI). */
+#define SIGQUIT 3 /* Quit (POSIX). */
+#define SIGILL 4 /* Illegal instruction (ANSI). */
+#define SIGTRAP 5 /* Trace trap (POSIX). */
+#define SIGIOT 6 /* IOT trap (4.2 BSD). */
+#define SIGABRT SIGIOT /* Abort (ANSI). */
+#define SIGEMT 7
+#define SIGFPE 8 /* Floating-point exception (ANSI). */
+#define SIGKILL 9 /* Kill, unblockable (POSIX). */
+#define SIGBUS 10 /* BUS error (4.2 BSD). */
+#define SIGSEGV 11 /* Segmentation violation (ANSI). */
+#define SIGSYS 12
+#define SIGPIPE 13 /* Broken pipe (POSIX). */
+#define SIGALRM 14 /* Alarm clock (POSIX). */
+#define SIGTERM 15 /* Termination (ANSI). */
+#define SIGUSR1 16 /* User-defined signal 1 (POSIX). */
+#define SIGUSR2 17 /* User-defined signal 2 (POSIX). */
+#define SIGCHLD 18 /* Child status has changed (POSIX). */
+#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
+#define SIGPWR 19 /* Power failure restart (System V). */
+#define SIGWINCH 20 /* Window size change (4.3 BSD, Sun). */
+#define SIGURG 21 /* Urgent condition on socket (4.2 BSD). */
+#define SIGIO 22 /* I/O now possible (4.2 BSD). */
+#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
+#define SIGSTOP 23 /* Stop, unblockable (POSIX). */
+#define SIGTSTP 24 /* Keyboard stop (POSIX). */
+#define SIGCONT 25 /* Continue (POSIX). */
+#define SIGTTIN 26 /* Background read from tty (POSIX). */
+#define SIGTTOU 27 /* Background write to tty (POSIX). */
+#define SIGVTALRM 28 /* Virtual alarm clock (4.2 BSD). */
+#define SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */
+#define SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */
+#define SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_ONSTACK 0x08000000
+#define SA_RESETHAND 0x80000000
+#define SA_RESTART 0x10000000
+#define SA_SIGINFO 0x00000008
+#define SA_NODEFER 0x40000000
+#define SA_NOCLDWAIT 0x00010000
+#define SA_NOCLDSTOP 0x00000001
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SA_RESTORER 0x04000000 /* Only for o32 */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#ifdef __KERNEL__
+
+#ifdef CONFIG_TRAD_SIGNALS
+#define sig_uses_siginfo(ka) ((ka)->sa.sa_flags & SA_SIGINFO)
+#else
+#define sig_uses_siginfo(ka) (1)
+#endif
+
+#endif /* __KERNEL__ */
+
+#define SIG_BLOCK 1 /* for blocking signals */
+#define SIG_UNBLOCK 2 /* for unblocking signals */
+#define SIG_SETMASK 3 /* for setting the signal mask */
+
+#include <asm-generic/signal-defs.h>
+
+struct sigaction {
+ unsigned int sa_flags;
+ __sighandler_t sa_handler;
+ sigset_t sa_mask;
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+
+/* IRIX compatible stack_t */
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ size_t ss_size;
+ int ss_flags;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+#include <asm/siginfo.h>
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SIGNAL_H */
diff --git a/arch/mips/include/asm/sim.h b/arch/mips/include/asm/sim.h
new file mode 100644
index 00000000..0cd719fa
--- /dev/null
+++ b/arch/mips/include/asm/sim.h
@@ -0,0 +1,82 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SIM_H
+#define _ASM_SIM_H
+
+
+#include <asm/asm-offsets.h>
+
+#define __str2(x) #x
+#define __str(x) __str2(x)
+
+#ifdef CONFIG_32BIT
+
+#define save_static_function(symbol) \
+__asm__( \
+ ".text\n\t" \
+ ".globl\t" #symbol "\n\t" \
+ ".align\t2\n\t" \
+ ".type\t" #symbol ", @function\n\t" \
+ ".ent\t" #symbol ", 0\n" \
+ #symbol":\n\t" \
+ ".frame\t$29, 0, $31\n\t" \
+ "sw\t$16,"__str(PT_R16)"($29)\t\t\t# save_static_function\n\t" \
+ "sw\t$17,"__str(PT_R17)"($29)\n\t" \
+ "sw\t$18,"__str(PT_R18)"($29)\n\t" \
+ "sw\t$19,"__str(PT_R19)"($29)\n\t" \
+ "sw\t$20,"__str(PT_R20)"($29)\n\t" \
+ "sw\t$21,"__str(PT_R21)"($29)\n\t" \
+ "sw\t$22,"__str(PT_R22)"($29)\n\t" \
+ "sw\t$23,"__str(PT_R23)"($29)\n\t" \
+ "sw\t$30,"__str(PT_R30)"($29)\n\t" \
+ "j\t_" #symbol "\n\t" \
+ ".end\t" #symbol "\n\t" \
+ ".size\t" #symbol",. - " #symbol)
+
+#define nabi_no_regargs
+
+#endif /* CONFIG_32BIT */
+
+#ifdef CONFIG_64BIT
+
+#define save_static_function(symbol) \
+__asm__( \
+ ".text\n\t" \
+ ".globl\t" #symbol "\n\t" \
+ ".align\t2\n\t" \
+ ".type\t" #symbol ", @function\n\t" \
+ ".ent\t" #symbol ", 0\n" \
+ #symbol":\n\t" \
+ ".frame\t$29, 0, $31\n\t" \
+ "sd\t$16,"__str(PT_R16)"($29)\t\t\t# save_static_function\n\t" \
+ "sd\t$17,"__str(PT_R17)"($29)\n\t" \
+ "sd\t$18,"__str(PT_R18)"($29)\n\t" \
+ "sd\t$19,"__str(PT_R19)"($29)\n\t" \
+ "sd\t$20,"__str(PT_R20)"($29)\n\t" \
+ "sd\t$21,"__str(PT_R21)"($29)\n\t" \
+ "sd\t$22,"__str(PT_R22)"($29)\n\t" \
+ "sd\t$23,"__str(PT_R23)"($29)\n\t" \
+ "sd\t$30,"__str(PT_R30)"($29)\n\t" \
+ "j\t_" #symbol "\n\t" \
+ ".end\t" #symbol "\n\t" \
+ ".size\t" #symbol",. - " #symbol)
+
+#define nabi_no_regargs \
+ unsigned long __dummy0, \
+ unsigned long __dummy1, \
+ unsigned long __dummy2, \
+ unsigned long __dummy3, \
+ unsigned long __dummy4, \
+ unsigned long __dummy5, \
+ unsigned long __dummy6, \
+ unsigned long __dummy7,
+
+#endif /* CONFIG_64BIT */
+
+#endif /* _ASM_SIM_H */
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
new file mode 100644
index 00000000..9e09af34
--- /dev/null
+++ b/arch/mips/include/asm/smp-ops.h
@@ -0,0 +1,63 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ * Copyright (C) 2000, 2001, 2002 Ralf Baechle
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ */
+#ifndef __ASM_SMP_OPS_H
+#define __ASM_SMP_OPS_H
+
+#ifdef CONFIG_SMP
+
+#include <linux/cpumask.h>
+
+struct task_struct;
+
+struct plat_smp_ops {
+ void (*send_ipi_single)(int cpu, unsigned int action);
+ void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action);
+ void (*init_secondary)(void);
+ void (*smp_finish)(void);
+ void (*cpus_done)(void);
+ void (*boot_secondary)(int cpu, struct task_struct *idle);
+ void (*smp_setup)(void);
+ void (*prepare_cpus)(unsigned int max_cpus);
+#ifdef CONFIG_HOTPLUG_CPU
+ int (*cpu_disable)(void);
+ void (*cpu_die)(unsigned int cpu);
+#endif
+};
+
+extern void register_smp_ops(struct plat_smp_ops *ops);
+
+static inline void plat_smp_setup(void)
+{
+ extern struct plat_smp_ops *mp_ops; /* private */
+
+ mp_ops->smp_setup();
+}
+
+#else /* !CONFIG_SMP */
+
+struct plat_smp_ops;
+
+static inline void plat_smp_setup(void)
+{
+ /* UP, nothing to do ... */
+}
+
+static inline void register_smp_ops(struct plat_smp_ops *ops)
+{
+}
+
+#endif /* !CONFIG_SMP */
+
+extern struct plat_smp_ops up_smp_ops;
+extern struct plat_smp_ops cmp_smp_ops;
+extern struct plat_smp_ops vsmp_smp_ops;
+
+#endif /* __ASM_SMP_OPS_H */
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
new file mode 100644
index 00000000..af423852
--- /dev/null
+++ b/arch/mips/include/asm/smp.h
@@ -0,0 +1,94 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ * Copyright (C) 2000, 2001, 2002 Ralf Baechle
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ */
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+#include <linux/bitops.h>
+#include <linux/linkage.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+
+#include <asm/atomic.h>
+#include <asm/smp-ops.h>
+
+extern int smp_num_siblings;
+extern cpumask_t cpu_sibling_map[];
+
+#define raw_smp_processor_id() (current_thread_info()->cpu)
+
+/* Map from cpu id to sequential logical cpu number. This will only
+ not be idempotent when cpus failed to come on-line. */
+extern int __cpu_number_map[NR_CPUS];
+#define cpu_number_map(cpu) __cpu_number_map[cpu]
+
+/* The reverse map from sequential logical cpu number to cpu id. */
+extern int __cpu_logical_map[NR_CPUS];
+#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
+
+#define NO_PROC_ID (-1)
+
+#define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */
+#define SMP_CALL_FUNCTION 0x2
+/* Octeon - Tell another core to flush its icache */
+#define SMP_ICACHE_FLUSH 0x4
+
+extern volatile cpumask_t cpu_callin_map;
+
+extern void asmlinkage smp_bootstrap(void);
+
+/*
+ * this function sends a 'reschedule' IPI to another CPU.
+ * it goes straight through and wastes no time serializing
+ * anything. Worst case is that we lose a reschedule ...
+ */
+static inline void smp_send_reschedule(int cpu)
+{
+ extern struct plat_smp_ops *mp_ops; /* private */
+
+ mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static inline int __cpu_disable(void)
+{
+ extern struct plat_smp_ops *mp_ops; /* private */
+
+ return mp_ops->cpu_disable();
+}
+
+static inline void __cpu_die(unsigned int cpu)
+{
+ extern struct plat_smp_ops *mp_ops; /* private */
+
+ mp_ops->cpu_die(cpu);
+}
+
+extern void play_dead(void);
+#endif
+
+extern asmlinkage void smp_call_function_interrupt(void);
+
+static inline void arch_send_call_function_single_ipi(int cpu)
+{
+ extern struct plat_smp_ops *mp_ops; /* private */
+
+ mp_ops->send_ipi_mask(&cpumask_of_cpu(cpu), SMP_CALL_FUNCTION);
+}
+
+static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+ extern struct plat_smp_ops *mp_ops; /* private */
+
+ mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
+}
+
+#endif /* __ASM_SMP_H */
diff --git a/arch/mips/include/asm/smtc.h b/arch/mips/include/asm/smtc.h
new file mode 100644
index 00000000..ea60bf08
--- /dev/null
+++ b/arch/mips/include/asm/smtc.h
@@ -0,0 +1,71 @@
+#ifndef _ASM_SMTC_MT_H
+#define _ASM_SMTC_MT_H
+
+/*
+ * Definitions for SMTC multitasking on MIPS MT cores
+ */
+
+#include <asm/mips_mt.h>
+#include <asm/smtc_ipi.h>
+
+/*
+ * System-wide SMTC status information
+ */
+
+extern unsigned int smtc_status;
+
+#define SMTC_TLB_SHARED 0x00000001
+#define SMTC_MTC_ACTIVE 0x00000002
+
+/*
+ * TLB/ASID Management information
+ */
+
+#define MAX_SMTC_TLBS 2
+#define MAX_SMTC_ASIDS 256
+#if NR_CPUS <= 8
+typedef char asiduse;
+#else
+#if NR_CPUS <= 16
+typedef short asiduse;
+#else
+typedef long asiduse;
+#endif
+#endif
+
+extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
+
+struct mm_struct;
+struct task_struct;
+
+void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu);
+void self_ipi(struct smtc_ipi *);
+void smtc_flush_tlb_asid(unsigned long asid);
+extern int smtc_build_cpu_map(int startslot);
+extern void smtc_prepare_cpus(int cpus);
+extern void smtc_smp_finish(void);
+extern void smtc_boot_secondary(int cpu, struct task_struct *t);
+extern void smtc_cpus_done(void);
+
+
+/*
+ * Sharing the TLB between multiple VPEs means that the
+ * "random" index selection function is not allowed to
+ * select the current value of the Index register. To
+ * avoid additional TLB pressure, the Index registers
+ * are "parked" with an non-Valid value.
+ */
+
+#define PARKED_INDEX ((unsigned int)0x80000000)
+
+/*
+ * Define low-level interrupt mask for IPIs, if necessary.
+ * By default, use SW interrupt 1, which requires no external
+ * hardware support, but which works only for single-core
+ * MIPS MT systems.
+ */
+#ifndef MIPS_CPU_IPI_IRQ
+#define MIPS_CPU_IPI_IRQ 1
+#endif
+
+#endif /* _ASM_SMTC_MT_H */
diff --git a/arch/mips/include/asm/smtc_ipi.h b/arch/mips/include/asm/smtc_ipi.h
new file mode 100644
index 00000000..15278dbd
--- /dev/null
+++ b/arch/mips/include/asm/smtc_ipi.h
@@ -0,0 +1,129 @@
+/*
+ * Definitions used in MIPS MT SMTC "Interprocessor Interrupt" code.
+ */
+#ifndef __ASM_SMTC_IPI_H
+#define __ASM_SMTC_IPI_H
+
+#include <linux/spinlock.h>
+
+//#define SMTC_IPI_DEBUG
+
+#ifdef SMTC_IPI_DEBUG
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#endif /* SMTC_IPI_DEBUG */
+
+/*
+ * An IPI "message"
+ */
+
+struct smtc_ipi {
+ struct smtc_ipi *flink;
+ int type;
+ void *arg;
+ int dest;
+#ifdef SMTC_IPI_DEBUG
+ int sender;
+ long stamp;
+#endif /* SMTC_IPI_DEBUG */
+};
+
+/*
+ * Defined IPI Types
+ */
+
+#define LINUX_SMP_IPI 1
+#define SMTC_CLOCK_TICK 2
+#define IRQ_AFFINITY_IPI 3
+
+/*
+ * A queue of IPI messages
+ */
+
+struct smtc_ipi_q {
+ struct smtc_ipi *head;
+ spinlock_t lock;
+ struct smtc_ipi *tail;
+ int depth;
+ int resched_flag; /* reschedule already queued */
+};
+
+static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->lock, flags);
+ if (q->head == NULL)
+ q->head = q->tail = p;
+ else
+ q->tail->flink = p;
+ p->flink = NULL;
+ q->tail = p;
+ q->depth++;
+#ifdef SMTC_IPI_DEBUG
+ p->sender = read_c0_tcbind();
+ p->stamp = read_c0_count();
+#endif /* SMTC_IPI_DEBUG */
+ spin_unlock_irqrestore(&q->lock, flags);
+}
+
+static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
+{
+ struct smtc_ipi *p;
+
+ if (q->head == NULL)
+ p = NULL;
+ else {
+ p = q->head;
+ q->head = q->head->flink;
+ q->depth--;
+ /* Arguably unnecessary, but leaves queue cleaner */
+ if (q->head == NULL)
+ q->tail = NULL;
+ }
+
+ return p;
+}
+
+static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
+{
+ unsigned long flags;
+ struct smtc_ipi *p;
+
+ spin_lock_irqsave(&q->lock, flags);
+ p = __smtc_ipi_dq(q);
+ spin_unlock_irqrestore(&q->lock, flags);
+
+ return p;
+}
+
+static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&q->lock, flags);
+ if (q->head == NULL) {
+ q->head = q->tail = p;
+ p->flink = NULL;
+ } else {
+ p->flink = q->head;
+ q->head = p;
+ }
+ q->depth++;
+ spin_unlock_irqrestore(&q->lock, flags);
+}
+
+static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q)
+{
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave(&q->lock, flags);
+ retval = q->depth;
+ spin_unlock_irqrestore(&q->lock, flags);
+ return retval;
+}
+
+extern void smtc_send_ipi(int cpu, int type, unsigned int action);
+
+#endif /* __ASM_SMTC_IPI_H */
diff --git a/arch/mips/include/asm/smtc_proc.h b/arch/mips/include/asm/smtc_proc.h
new file mode 100644
index 00000000..25da651f
--- /dev/null
+++ b/arch/mips/include/asm/smtc_proc.h
@@ -0,0 +1,23 @@
+/*
+ * Definitions for SMTC /proc entries
+ * Copyright(C) 2005 MIPS Technologies Inc.
+ */
+#ifndef __ASM_SMTC_PROC_H
+#define __ASM_SMTC_PROC_H
+
+/*
+ * per-"CPU" statistics
+ */
+
+struct smtc_cpu_proc {
+ unsigned long timerints;
+ unsigned long selfipis;
+};
+
+extern struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
+
+/* Count of number of recoveries of "stolen" FPU access rights on 34K */
+
+extern atomic_t smtc_fpu_recoveries;
+
+#endif /* __ASM_SMTC_PROC_H */
diff --git a/arch/mips/include/asm/smvp.h b/arch/mips/include/asm/smvp.h
new file mode 100644
index 00000000..0d0e80a3
--- /dev/null
+++ b/arch/mips/include/asm/smvp.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_SMVP_H
+#define _ASM_SMVP_H
+
+/*
+ * Definitions for SMVP multitasking on MIPS MT cores
+ */
+struct task_struct;
+
+extern void smvp_smp_setup(void);
+extern void smvp_smp_finish(void);
+extern void smvp_boot_secondary(int cpu, struct task_struct *t);
+extern void smvp_init_secondary(void);
+extern void smvp_smp_finish(void);
+extern void smvp_cpus_done(void);
+extern void smvp_prepare_cpus(unsigned int max_cpus);
+
+/* This is platform specific */
+extern void smvp_send_ipi(int cpu, unsigned int action);
+#endif /* _ASM_SMVP_H */
diff --git a/arch/mips/include/asm/sn/addrs.h b/arch/mips/include/asm/sn/addrs.h
new file mode 100644
index 00000000..2367b56d
--- /dev/null
+++ b/arch/mips/include/asm/sn/addrs.h
@@ -0,0 +1,431 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2000 by Ralf Baechle
+ */
+#ifndef _ASM_SN_ADDRS_H
+#define _ASM_SN_ADDRS_H
+
+
+#ifndef __ASSEMBLY__
+#include <linux/smp.h>
+#include <linux/types.h>
+#endif /* !__ASSEMBLY__ */
+
+#include <asm/addrspace.h>
+#include <asm/sn/kldir.h>
+
+#if defined(CONFIG_SGI_IP27)
+#include <asm/sn/sn0/addrs.h>
+#elif defined(CONFIG_SGI_IP35)
+#include <asm/sn/sn1/addrs.h>
+#endif
+
+
+#ifndef __ASSEMBLY__
+
+#define PS_UINT_CAST (unsigned long)
+#define UINT64_CAST (unsigned long)
+
+#define HUBREG_CAST (volatile hubreg_t *)
+
+#else /* __ASSEMBLY__ */
+
+#define PS_UINT_CAST
+#define UINT64_CAST
+#define HUBREG_CAST
+
+#endif /* __ASSEMBLY__ */
+
+
+#define NASID_GET_META(_n) ((_n) >> NASID_LOCAL_BITS)
+#ifdef CONFIG_SGI_IP27
+#define NASID_GET_LOCAL(_n) ((_n) & 0xf)
+#endif
+#define NASID_MAKE(_m, _l) (((_m) << NASID_LOCAL_BITS) | (_l))
+
+#define NODE_ADDRSPACE_MASK (NODE_ADDRSPACE_SIZE - 1)
+#define TO_NODE_ADDRSPACE(_pa) (UINT64_CAST (_pa) & NODE_ADDRSPACE_MASK)
+
+#define CHANGE_ADDR_NASID(_pa, _nasid) \
+ ((UINT64_CAST(_pa) & ~NASID_MASK) | \
+ (UINT64_CAST(_nasid) << NASID_SHFT))
+
+
+/*
+ * The following macros are used to index to the beginning of a specific
+ * node's address space.
+ */
+
+#define NODE_OFFSET(_n) (UINT64_CAST (_n) << NODE_SIZE_BITS)
+
+#define NODE_CAC_BASE(_n) (CAC_BASE + NODE_OFFSET(_n))
+#define NODE_HSPEC_BASE(_n) (HSPEC_BASE + NODE_OFFSET(_n))
+#define NODE_IO_BASE(_n) (IO_BASE + NODE_OFFSET(_n))
+#define NODE_MSPEC_BASE(_n) (MSPEC_BASE + NODE_OFFSET(_n))
+#define NODE_UNCAC_BASE(_n) (UNCAC_BASE + NODE_OFFSET(_n))
+
+#define TO_NODE(_n, _x) (NODE_OFFSET(_n) | ((_x) ))
+#define TO_NODE_CAC(_n, _x) (NODE_CAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
+#define TO_NODE_UNCAC(_n, _x) (NODE_UNCAC_BASE(_n) | ((_x) & TO_PHYS_MASK))
+#define TO_NODE_MSPEC(_n, _x) (NODE_MSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
+#define TO_NODE_HSPEC(_n, _x) (NODE_HSPEC_BASE(_n) | ((_x) & TO_PHYS_MASK))
+
+
+#define RAW_NODE_SWIN_BASE(nasid, widget) \
+ (NODE_IO_BASE(nasid) + (UINT64_CAST(widget) << SWIN_SIZE_BITS))
+
+#define WIDGETID_GET(addr) ((unsigned char)((addr >> SWIN_SIZE_BITS) & 0xff))
+
+/*
+ * The following definitions pertain to the IO special address
+ * space. They define the location of the big and little windows
+ * of any given node.
+ */
+
+#define SWIN_SIZE_BITS 24
+#define SWIN_SIZE (UINT64_CAST 1 << 24)
+#define SWIN_SIZEMASK (SWIN_SIZE - 1)
+#define SWIN_WIDGET_MASK 0xF
+
+/*
+ * Convert smallwindow address to xtalk address.
+ *
+ * 'addr' can be physical or virtual address, but will be converted
+ * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
+ */
+#define SWIN_WIDGETADDR(addr) ((addr) & SWIN_SIZEMASK)
+#define SWIN_WIDGETNUM(addr) (((addr) >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
+/*
+ * Verify if addr belongs to small window address on node with "nasid"
+ *
+ *
+ * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
+ * address
+ *
+ *
+ */
+#define NODE_SWIN_ADDR(nasid, addr) \
+ (((addr) >= NODE_SWIN_BASE(nasid, 0)) && \
+ ((addr) < (NODE_SWIN_BASE(nasid, HUB_NUM_WIDGET) + SWIN_SIZE)\
+ ))
+
+/*
+ * The following define the major position-independent aliases used
+ * in SN.
+ * UALIAS -- 256MB in size, reads in the UALIAS result in
+ * uncached references to the memory of the reader's node.
+ * CPU_UALIAS -- 128kb in size, the bottom part of UALIAS is flipped
+ * depending on which CPU does the access to provide
+ * all CPUs with unique uncached memory at low addresses.
+ * LBOOT -- 256MB in size, reads in the LBOOT area result in
+ * uncached references to the local hub's boot prom and
+ * other directory-bus connected devices.
+ * IALIAS -- 8MB in size, reads in the IALIAS result in uncached
+ * references to the local hub's registers.
+ */
+
+#define UALIAS_BASE HSPEC_BASE
+#define UALIAS_SIZE 0x10000000 /* 256 Megabytes */
+#define UALIAS_LIMIT (UALIAS_BASE + UALIAS_SIZE)
+
+/*
+ * The bottom of ualias space is flipped depending on whether you're
+ * processor 0 or 1 within a node.
+ */
+#ifdef CONFIG_SGI_IP27
+#define UALIAS_FLIP_BASE UALIAS_BASE
+#define UALIAS_FLIP_SIZE 0x20000
+#define UALIAS_FLIP_BIT 0x10000
+#define UALIAS_FLIP_ADDR(_x) (cputoslice(smp_processor_id()) ? \
+ (_x) ^ UALIAS_FLIP_BIT : (_x))
+
+#define LBOOT_BASE (HSPEC_BASE + 0x10000000)
+#define LBOOT_SIZE 0x10000000
+#define LBOOT_LIMIT (LBOOT_BASE + LBOOT_SIZE)
+#define LBOOT_STRIDE 0 /* IP27 has only one CPU PROM */
+
+#endif
+
+#define HUB_REGISTER_WIDGET 1
+#define IALIAS_BASE NODE_SWIN_BASE(0, HUB_REGISTER_WIDGET)
+#define IALIAS_SIZE 0x800000 /* 8 Megabytes */
+#define IS_IALIAS(_a) (((_a) >= IALIAS_BASE) && \
+ ((_a) < (IALIAS_BASE + IALIAS_SIZE)))
+
+/*
+ * Macro for referring to Hub's RBOOT space
+ */
+
+#ifdef CONFIG_SGI_IP27
+#define RBOOT_SIZE 0x10000000 /* 256 Megabytes */
+#define NODE_RBOOT_BASE(_n) (NODE_HSPEC_BASE(_n) + 0x30000000)
+#define NODE_RBOOT_LIMIT(_n) (NODE_RBOOT_BASE(_n) + RBOOT_SIZE)
+
+#endif
+
+/*
+ * Macros for referring the Hub's back door space
+ *
+ * These macros correctly process addresses in any node's space.
+ * WARNING: They won't work in assembler.
+ *
+ * BDDIR_ENTRY_LO returns the address of the low double-word of the dir
+ * entry corresponding to a physical (Cac or Uncac) address.
+ * BDDIR_ENTRY_HI returns the address of the high double-word of the entry.
+ * BDPRT_ENTRY returns the address of the double-word protection entry
+ * corresponding to the page containing the physical address.
+ * BDPRT_ENTRY_S Stores the value into the protection entry.
+ * BDPRT_ENTRY_L Load the value from the protection entry.
+ * BDECC_ENTRY returns the address of the ECC byte corresponding to a
+ * double-word at a specified physical address.
+ * BDECC_ENTRY_H returns the address of the two ECC bytes corresponding to a
+ * quad-word at a specified physical address.
+ */
+#define NODE_BDOOR_BASE(_n) (NODE_HSPEC_BASE(_n) + (NODE_ADDRSPACE_SIZE/2))
+
+#define NODE_BDECC_BASE(_n) (NODE_BDOOR_BASE(_n))
+#define NODE_BDDIR_BASE(_n) (NODE_BDOOR_BASE(_n) + (NODE_ADDRSPACE_SIZE/4))
+#ifdef CONFIG_SGI_IP27
+#define BDDIR_ENTRY_LO(_pa) ((HSPEC_BASE + \
+ NODE_ADDRSPACE_SIZE * 3 / 4 + \
+ 0x200) | \
+ UINT64_CAST(_pa) & NASID_MASK | \
+ UINT64_CAST(_pa) >> 2 & BDDIR_UPPER_MASK | \
+ UINT64_CAST(_pa) >> 3 & 0x1f << 4)
+
+#define BDDIR_ENTRY_HI(_pa) ((HSPEC_BASE + \
+ NODE_ADDRSPACE_SIZE * 3 / 4 + \
+ 0x208) | \
+ UINT64_CAST(_pa) & NASID_MASK | \
+ UINT64_CAST(_pa) >> 2 & BDDIR_UPPER_MASK | \
+ UINT64_CAST(_pa) >> 3 & 0x1f << 4)
+
+#define BDPRT_ENTRY(_pa, _rgn) ((HSPEC_BASE + \
+ NODE_ADDRSPACE_SIZE * 3 / 4) | \
+ UINT64_CAST(_pa) & NASID_MASK | \
+ UINT64_CAST(_pa) >> 2 & BDDIR_UPPER_MASK | \
+ (_rgn) << 3)
+#define BDPRT_ENTRY_ADDR(_pa, _rgn) (BDPRT_ENTRY((_pa), (_rgn)))
+#define BDPRT_ENTRY_S(_pa, _rgn, _val) (*(__psunsigned_t *)BDPRT_ENTRY((_pa), (_rgn))=(_val))
+#define BDPRT_ENTRY_L(_pa, _rgn) (*(__psunsigned_t *)BDPRT_ENTRY((_pa), (_rgn)))
+
+#define BDECC_ENTRY(_pa) ((HSPEC_BASE + \
+ NODE_ADDRSPACE_SIZE / 2) | \
+ UINT64_CAST(_pa) & NASID_MASK | \
+ UINT64_CAST(_pa) >> 2 & BDECC_UPPER_MASK | \
+ UINT64_CAST(_pa) >> 3 & 3)
+
+/*
+ * Macro to convert a back door directory or protection address into the
+ * raw physical address of the associated cache line or protection page.
+ */
+#define BDADDR_IS_DIR(_ba) ((UINT64_CAST (_ba) & 0x200) != 0)
+#define BDADDR_IS_PRT(_ba) ((UINT64_CAST (_ba) & 0x200) == 0)
+
+#define BDDIR_TO_MEM(_ba) (UINT64_CAST (_ba) & NASID_MASK | \
+ (UINT64_CAST(_ba) & BDDIR_UPPER_MASK)<<2 | \
+ (UINT64_CAST(_ba) & 0x1f << 4) << 3)
+
+#define BDPRT_TO_MEM(_ba) (UINT64_CAST (_ba) & NASID_MASK | \
+ (UINT64_CAST(_ba) & BDDIR_UPPER_MASK)<<2)
+
+#define BDECC_TO_MEM(_ba) (UINT64_CAST (_ba) & NASID_MASK | \
+ (UINT64_CAST(_ba) & BDECC_UPPER_MASK)<<2 | \
+ (UINT64_CAST(_ba) & 3) << 3)
+#endif /* CONFIG_SGI_IP27 */
+
+
+/*
+ * The following macros produce the correct base virtual address for
+ * the hub registers. The LOCAL_HUB_* macros produce the appropriate
+ * address for the local registers. The REMOTE_HUB_* macro produce
+ * the address for the specified hub's registers. The intent is
+ * that the appropriate PI, MD, NI, or II register would be substituted
+ * for _x.
+ */
+
+/*
+ * WARNING:
+ * When certain Hub chip workaround are defined, it's not sufficient
+ * to dereference the *_HUB_ADDR() macros. You should instead use
+ * HUB_L() and HUB_S() if you must deal with pointers to hub registers.
+ * Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
+ * They're always safe.
+ */
+#define LOCAL_HUB_ADDR(_x) (HUBREG_CAST (IALIAS_BASE + (_x)))
+#define REMOTE_HUB_ADDR(_n, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \
+ 0x800000 + (_x)))
+#ifdef CONFIG_SGI_IP27
+#define REMOTE_HUB_PI_ADDR(_n, _sn, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \
+ 0x800000 + (_x)))
+#endif /* CONFIG_SGI_IP27 */
+
+#ifndef __ASSEMBLY__
+
+#define HUB_L(_a) *(_a)
+#define HUB_S(_a, _d) *(_a) = (_d)
+
+#define LOCAL_HUB_L(_r) HUB_L(LOCAL_HUB_ADDR(_r))
+#define LOCAL_HUB_S(_r, _d) HUB_S(LOCAL_HUB_ADDR(_r), (_d))
+#define REMOTE_HUB_L(_n, _r) HUB_L(REMOTE_HUB_ADDR((_n), (_r)))
+#define REMOTE_HUB_S(_n, _r, _d) HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d))
+#define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
+#define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * The following macros are used to get to a hub/bridge register, given
+ * the base of the register space.
+ */
+#define HUB_REG_PTR(_base, _off) \
+ (HUBREG_CAST((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
+
+#define HUB_REG_PTR_L(_base, _off) \
+ HUB_L(HUB_REG_PTR((_base), (_off)))
+
+#define HUB_REG_PTR_S(_base, _off, _data) \
+ HUB_S(HUB_REG_PTR((_base), (_off)), (_data))
+
+/*
+ * Software structure locations -- permanently fixed
+ * See diagram in kldir.h
+ */
+
+#define PHYS_RAMBASE 0x0
+#define K0_RAMBASE PHYS_TO_K0(PHYS_RAMBASE)
+
+#define EX_HANDLER_OFFSET(slice) ((slice) << 16)
+#define EX_HANDLER_ADDR(nasid, slice) \
+ PHYS_TO_K0(NODE_OFFSET(nasid) | EX_HANDLER_OFFSET(slice))
+#define EX_HANDLER_SIZE 0x0400
+
+#define EX_FRAME_OFFSET(slice) ((slice) << 16 | 0x400)
+#define EX_FRAME_ADDR(nasid, slice) \
+ PHYS_TO_K0(NODE_OFFSET(nasid) | EX_FRAME_OFFSET(slice))
+#define EX_FRAME_SIZE 0x0c00
+
+#define ARCS_SPB_OFFSET 0x1000
+#define ARCS_SPB_ADDR(nasid) \
+ PHYS_TO_K0(NODE_OFFSET(nasid) | ARCS_SPB_OFFSET)
+#define ARCS_SPB_SIZE 0x0400
+
+#define KLDIR_OFFSET 0x2000
+#define KLDIR_ADDR(nasid) \
+ TO_NODE_UNCAC((nasid), KLDIR_OFFSET)
+#define KLDIR_SIZE 0x0400
+
+
+/*
+ * Software structure locations -- indirected through KLDIR
+ * See diagram in kldir.h
+ *
+ * Important: All low memory structures must only be accessed
+ * uncached, except for the symmon stacks.
+ */
+
+#define KLI_LAUNCH 0 /* Dir. entries */
+#define KLI_KLCONFIG 1
+#define KLI_NMI 2
+#define KLI_GDA 3
+#define KLI_FREEMEM 4
+#define KLI_SYMMON_STK 5
+#define KLI_PI_ERROR 6
+#define KLI_KERN_VARS 7
+#define KLI_KERN_XP 8
+#define KLI_KERN_PARTID 9
+
+#ifndef __ASSEMBLY__
+
+#define KLD_BASE(nasid) ((kldir_ent_t *) KLDIR_ADDR(nasid))
+#define KLD_LAUNCH(nasid) (KLD_BASE(nasid) + KLI_LAUNCH)
+#define KLD_NMI(nasid) (KLD_BASE(nasid) + KLI_NMI)
+#define KLD_KLCONFIG(nasid) (KLD_BASE(nasid) + KLI_KLCONFIG)
+#define KLD_PI_ERROR(nasid) (KLD_BASE(nasid) + KLI_PI_ERROR)
+#define KLD_GDA(nasid) (KLD_BASE(nasid) + KLI_GDA)
+#define KLD_SYMMON_STK(nasid) (KLD_BASE(nasid) + KLI_SYMMON_STK)
+#define KLD_FREEMEM(nasid) (KLD_BASE(nasid) + KLI_FREEMEM)
+#define KLD_KERN_VARS(nasid) (KLD_BASE(nasid) + KLI_KERN_VARS)
+#define KLD_KERN_XP(nasid) (KLD_BASE(nasid) + KLI_KERN_XP)
+#define KLD_KERN_PARTID(nasid) (KLD_BASE(nasid) + KLI_KERN_PARTID)
+
+#define LAUNCH_OFFSET(nasid, slice) \
+ (KLD_LAUNCH(nasid)->offset + \
+ KLD_LAUNCH(nasid)->stride * (slice))
+#define LAUNCH_ADDR(nasid, slice) \
+ TO_NODE_UNCAC((nasid), LAUNCH_OFFSET(nasid, slice))
+#define LAUNCH_SIZE(nasid) KLD_LAUNCH(nasid)->size
+
+#define SN_NMI_OFFSET(nasid, slice) \
+ (KLD_NMI(nasid)->offset + \
+ KLD_NMI(nasid)->stride * (slice))
+#define NMI_ADDR(nasid, slice) \
+ TO_NODE_UNCAC((nasid), SN_NMI_OFFSET(nasid, slice))
+#define NMI_SIZE(nasid) KLD_NMI(nasid)->size
+
+#define KLCONFIG_OFFSET(nasid) KLD_KLCONFIG(nasid)->offset
+#define KLCONFIG_ADDR(nasid) \
+ TO_NODE_UNCAC((nasid), KLCONFIG_OFFSET(nasid))
+#define KLCONFIG_SIZE(nasid) KLD_KLCONFIG(nasid)->size
+
+#define GDA_ADDR(nasid) KLD_GDA(nasid)->pointer
+#define GDA_SIZE(nasid) KLD_GDA(nasid)->size
+
+#define SYMMON_STK_OFFSET(nasid, slice) \
+ (KLD_SYMMON_STK(nasid)->offset + \
+ KLD_SYMMON_STK(nasid)->stride * (slice))
+#define SYMMON_STK_STRIDE(nasid) KLD_SYMMON_STK(nasid)->stride
+
+#define SYMMON_STK_ADDR(nasid, slice) \
+ TO_NODE_CAC((nasid), SYMMON_STK_OFFSET(nasid, slice))
+
+#define SYMMON_STK_SIZE(nasid) KLD_SYMMON_STK(nasid)->stride
+
+#define SYMMON_STK_END(nasid) (SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size)
+
+/* loading symmon 4k below UNIX. the arcs loader needs the topaddr for a
+ * relocatable program
+ */
+#define UNIX_DEBUG_LOADADDR 0x300000
+#define SYMMON_LOADADDR(nasid) \
+ TO_NODE(nasid, PHYS_TO_K0(UNIX_DEBUG_LOADADDR - 0x1000))
+
+#define FREEMEM_OFFSET(nasid) KLD_FREEMEM(nasid)->offset
+#define FREEMEM_ADDR(nasid) SYMMON_STK_END(nasid)
+/*
+ * XXX
+ * Fix this. FREEMEM_ADDR should be aware of if symmon is loaded.
+ * Also, it should take into account what prom thinks to be a safe
+ * address
+ PHYS_TO_K0(NODE_OFFSET(nasid) + FREEMEM_OFFSET(nasid))
+ */
+#define FREEMEM_SIZE(nasid) KLD_FREEMEM(nasid)->size
+
+#define PI_ERROR_OFFSET(nasid) KLD_PI_ERROR(nasid)->offset
+#define PI_ERROR_ADDR(nasid) \
+ TO_NODE_UNCAC((nasid), PI_ERROR_OFFSET(nasid))
+#define PI_ERROR_SIZE(nasid) KLD_PI_ERROR(nasid)->size
+
+#define NODE_OFFSET_TO_K0(_nasid, _off) \
+ PHYS_TO_K0((NODE_OFFSET(_nasid) + (_off)) | CAC_BASE)
+#define NODE_OFFSET_TO_K1(_nasid, _off) \
+ TO_UNCAC((NODE_OFFSET(_nasid) + (_off)) | UNCAC_BASE)
+#define K0_TO_NODE_OFFSET(_k0addr) \
+ ((__psunsigned_t)(_k0addr) & NODE_ADDRSPACE_MASK)
+
+#define KERN_VARS_ADDR(nasid) KLD_KERN_VARS(nasid)->pointer
+#define KERN_VARS_SIZE(nasid) KLD_KERN_VARS(nasid)->size
+
+#define KERN_XP_ADDR(nasid) KLD_KERN_XP(nasid)->pointer
+#define KERN_XP_SIZE(nasid) KLD_KERN_XP(nasid)->size
+
+#define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET)
+
+#endif /* !__ASSEMBLY__ */
+
+
+#endif /* _ASM_SN_ADDRS_H */
diff --git a/arch/mips/include/asm/sn/agent.h b/arch/mips/include/asm/sn/agent.h
new file mode 100644
index 00000000..dc81114d
--- /dev/null
+++ b/arch/mips/include/asm/sn/agent.h
@@ -0,0 +1,45 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This file has definitions for the hub and snac interfaces.
+ *
+ * Copyright (C) 1992 - 1997, 1999, 2000 Silcon Graphics, Inc.
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SGI_SN_AGENT_H
+#define _ASM_SGI_SN_AGENT_H
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+
+#if defined(CONFIG_SGI_IP27)
+#include <asm/sn/sn0/hub.h>
+#elif defined(CONFIG_SGI_IP35)
+#include <asm/sn/sn1/hub.h>
+#endif /* !CONFIG_SGI_IP27 && !CONFIG_SGI_IP35 */
+
+/*
+ * NIC register macros
+ */
+
+#if defined(CONFIG_SGI_IP27)
+#define HUB_NIC_ADDR(_cpuid) \
+ REMOTE_HUB_ADDR(COMPACT_TO_NASID_NODEID(cpu_to_node(_cpuid)), \
+ MD_MLAN_CTL)
+#endif
+
+#define SET_HUB_NIC(_my_cpuid, _val) \
+ (HUB_S(HUB_NIC_ADDR(_my_cpuid), (_val)))
+
+#define SET_MY_HUB_NIC(_v) \
+ SET_HUB_NIC(cpuid(), (_v))
+
+#define GET_HUB_NIC(_my_cpuid) \
+ (HUB_L(HUB_NIC_ADDR(_my_cpuid)))
+
+#define GET_MY_HUB_NIC() \
+ GET_HUB_NIC(cpuid())
+
+#endif /* _ASM_SGI_SN_AGENT_H */
diff --git a/arch/mips/include/asm/sn/arch.h b/arch/mips/include/asm/sn/arch.h
new file mode 100644
index 00000000..bd75945e
--- /dev/null
+++ b/arch/mips/include/asm/sn/arch.h
@@ -0,0 +1,64 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI specific setup.
+ *
+ * Copyright (C) 1995 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SN_ARCH_H
+#define _ASM_SN_ARCH_H
+
+#include <linux/types.h>
+#include <asm/sn/types.h>
+#ifdef CONFIG_SGI_IP27
+#include <asm/sn/sn0/arch.h>
+#endif
+
+typedef u64 hubreg_t;
+
+#define cputonasid(cpu) (sn_cpu_info[(cpu)].p_nasid)
+#define cputoslice(cpu) (sn_cpu_info[(cpu)].p_slice)
+#define makespnum(_nasid, _slice) \
+ (((_nasid) << CPUS_PER_NODE_SHFT) | (_slice))
+
+#define INVALID_NASID (nasid_t)-1
+#define INVALID_CNODEID (cnodeid_t)-1
+#define INVALID_PNODEID (pnodeid_t)-1
+#define INVALID_MODULE (moduleid_t)-1
+#define INVALID_PARTID (partid_t)-1
+
+extern nasid_t get_nasid(void);
+extern cnodeid_t get_cpu_cnode(cpuid_t);
+extern int get_cpu_slice(cpuid_t);
+
+/*
+ * NO ONE should access these arrays directly. The only reason we refer to
+ * them here is to avoid the procedure call that would be required in the
+ * macros below. (Really want private data members here :-)
+ */
+extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
+extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
+
+/*
+ * These macros are used by various parts of the kernel to convert
+ * between the three different kinds of node numbering. At least some
+ * of them may change to procedure calls in the future, but the macros
+ * will continue to work. Don't use the arrays above directly.
+ */
+
+#define NASID_TO_REGION(nnode) \
+ ((nnode) >> \
+ (is_fine_dirmode() ? NASID_TO_FINEREG_SHFT : NASID_TO_COARSEREG_SHFT))
+
+extern cnodeid_t nasid_to_compact_node[MAX_NASIDS];
+extern nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
+extern cnodeid_t cpuid_to_compact_node[MAXCPUS];
+
+#define NASID_TO_COMPACT_NODEID(nnode) (nasid_to_compact_node[nnode])
+#define COMPACT_TO_NASID_NODEID(cnode) (compact_to_nasid_node[cnode])
+#define CPUID_TO_COMPACT_NODEID(cpu) (cpuid_to_compact_node[(cpu)])
+
+#endif /* _ASM_SN_ARCH_H */
diff --git a/arch/mips/include/asm/sn/fru.h b/arch/mips/include/asm/sn/fru.h
new file mode 100644
index 00000000..b3e36067
--- /dev/null
+++ b/arch/mips/include/asm/sn/fru.h
@@ -0,0 +1,44 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/sn0_fru.h>
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999, 2006 Ralf Baechle (ralf@linux-mips)
+ */
+#ifndef __ASM_SN_FRU_H
+#define __ASM_SN_FRU_H
+
+#define MAX_DIMMS 8 /* max # of dimm banks */
+#define MAX_PCIDEV 8 /* max # of pci devices on a pci bus */
+
+typedef unsigned char confidence_t;
+
+typedef struct kf_mem_s {
+ confidence_t km_confidence; /* confidence level that the memory is bad
+ * is this necessary ?
+ */
+ confidence_t km_dimm[MAX_DIMMS];
+ /* confidence level that dimm[i] is bad
+ *I think this is the right number
+ */
+
+} kf_mem_t;
+
+typedef struct kf_cpu_s {
+ confidence_t kc_confidence; /* confidence level that cpu is bad */
+ confidence_t kc_icache; /* confidence level that instr. cache is bad */
+ confidence_t kc_dcache; /* confidence level that data cache is bad */
+ confidence_t kc_scache; /* confidence level that sec. cache is bad */
+ confidence_t kc_sysbus; /* confidence level that sysad/cmd/state bus is bad */
+} kf_cpu_t;
+
+typedef struct kf_pci_bus_s {
+ confidence_t kpb_belief; /* confidence level that the pci bus is bad */
+ confidence_t kpb_pcidev_belief[MAX_PCIDEV];
+ /* confidence level that the pci dev is bad */
+} kf_pci_bus_t;
+
+#endif /* __ASM_SN_FRU_H */
diff --git a/arch/mips/include/asm/sn/gda.h b/arch/mips/include/asm/sn/gda.h
new file mode 100644
index 00000000..9cb6ff77
--- /dev/null
+++ b/arch/mips/include/asm/sn/gda.h
@@ -0,0 +1,107 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/gda.h>.
+ *
+ * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ *
+ * gda.h -- Contains the data structure for the global data area,
+ * The GDA contains information communicated between the
+ * PROM, SYMMON, and the kernel.
+ */
+#ifndef _ASM_SN_GDA_H
+#define _ASM_SN_GDA_H
+
+#include <asm/sn/addrs.h>
+
+#define GDA_MAGIC 0x58464552
+
+/*
+ * GDA Version History
+ *
+ * Version # | Change
+ * -------------+-------------------------------------------------------
+ * 1 | Initial SN0 version
+ * 2 | Prom sets g_partid field to the partition number. 0 IS
+ * | a valid partition #.
+ */
+
+#define GDA_VERSION 2 /* Current GDA version # */
+
+#define G_MAGICOFF 0
+#define G_VERSIONOFF 4
+#define G_PROMOPOFF 6
+#define G_MASTEROFF 8
+#define G_VDSOFF 12
+#define G_HKDNORMOFF 16
+#define G_HKDUTLBOFF 24
+#define G_HKDXUTLBOFF 32
+#define G_PARTIDOFF 40
+#define G_TABLEOFF 128
+
+#ifndef __ASSEMBLY__
+
+typedef struct gda {
+ u32 g_magic; /* GDA magic number */
+ u16 g_version; /* Version of this structure */
+ u16 g_masterid; /* The NASID:CPUNUM of the master cpu */
+ u32 g_promop; /* Passes requests from the kernel to prom */
+ u32 g_vds; /* Store the virtual dipswitches here */
+ void **g_hooked_norm;/* ptr to pda loc for norm hndlr */
+ void **g_hooked_utlb;/* ptr to pda loc for utlb hndlr */
+ void **g_hooked_xtlb;/* ptr to pda loc for xtlb hndlr */
+ int g_partid; /* partition id */
+ int g_symmax; /* Max symbols in name table. */
+ void *g_dbstab; /* Address of idbg symbol table */
+ char *g_nametab; /* Address of idbg name table */
+ void *g_ktext_repmask;
+ /* Pointer to a mask of nodes with copies
+ * of the kernel. */
+ char g_padding[56]; /* pad out to 128 bytes */
+ nasid_t g_nasidtable[MAX_COMPACT_NODES]; /* NASID of each node,
+ * indexed by cnodeid.
+ */
+} gda_t;
+
+#define GDA ((gda_t*) GDA_ADDR(get_nasid()))
+
+#endif /* !__ASSEMBLY__ */
+/*
+ * Define: PART_GDA_VERSION
+ * Purpose: Define the minimum version of the GDA required, lower
+ * revisions assume GDA is NOT set up, and read partition
+ * information from the board info.
+ */
+#define PART_GDA_VERSION 2
+
+/*
+ * The following requests can be sent to the PROM during startup.
+ */
+
+#define PROMOP_MAGIC 0x0ead0000
+#define PROMOP_MAGIC_MASK 0x0fff0000
+
+#define PROMOP_BIST_SHIFT 11
+#define PROMOP_BIST_MASK (0x3 << 11)
+
+#define PROMOP_REG PI_ERR_STACK_ADDR_A
+
+#define PROMOP_INVALID (PROMOP_MAGIC | 0x00)
+#define PROMOP_HALT (PROMOP_MAGIC | 0x10)
+#define PROMOP_POWERDOWN (PROMOP_MAGIC | 0x20)
+#define PROMOP_RESTART (PROMOP_MAGIC | 0x30)
+#define PROMOP_REBOOT (PROMOP_MAGIC | 0x40)
+#define PROMOP_IMODE (PROMOP_MAGIC | 0x50)
+
+#define PROMOP_CMD_MASK 0x00f0
+#define PROMOP_OPTIONS_MASK 0xfff0
+
+#define PROMOP_SKIP_DIAGS 0x0100 /* don't bother running diags */
+#define PROMOP_SKIP_MEMINIT 0x0200 /* don't bother initing memory */
+#define PROMOP_SKIP_DEVINIT 0x0400 /* don't bother initing devices */
+#define PROMOP_BIST1 0x0800 /* keep track of which BIST ran */
+#define PROMOP_BIST2 0x1000 /* keep track of which BIST ran */
+
+#endif /* _ASM_SN_GDA_H */
diff --git a/arch/mips/include/asm/sn/hub.h b/arch/mips/include/asm/sn/hub.h
new file mode 100644
index 00000000..1992d925
--- /dev/null
+++ b/arch/mips/include/asm/sn/hub.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_SN_HUB_H
+#define __ASM_SN_HUB_H
+
+#include <linux/types.h>
+#include <linux/cpumask.h>
+#include <asm/sn/types.h>
+#include <asm/sn/io.h>
+#include <asm/sn/klkernvars.h>
+#include <asm/xtalk/xtalk.h>
+
+/* ip27-hubio.c */
+extern unsigned long hub_pio_map(cnodeid_t cnode, xwidgetnum_t widget,
+ unsigned long xtalk_addr, size_t size);
+extern void hub_pio_init(cnodeid_t cnode);
+
+#endif /* __ASM_SN_HUB_H */
diff --git a/arch/mips/include/asm/sn/intr.h b/arch/mips/include/asm/sn/intr.h
new file mode 100644
index 00000000..6718b644
--- /dev/null
+++ b/arch/mips/include/asm/sn/intr.h
@@ -0,0 +1,129 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997 Silicon Graphics, Inc.
+ */
+#ifndef __ASM_SN_INTR_H
+#define __ASM_SN_INTR_H
+
+/* Number of interrupt levels associated with each interrupt register. */
+#define N_INTPEND_BITS 64
+
+#define INT_PEND0_BASELVL 0
+#define INT_PEND1_BASELVL 64
+
+#define N_INTPENDJUNK_BITS 8
+#define INTPENDJUNK_CLRBIT 0x80
+
+/*
+ * Macros to manipulate the interrupt register on the calling hub chip.
+ */
+
+#define LOCAL_HUB_SEND_INTR(level) \
+ LOCAL_HUB_S(PI_INT_PEND_MOD, (0x100 | (level)))
+#define REMOTE_HUB_SEND_INTR(hub, level) \
+ REMOTE_HUB_S((hub), PI_INT_PEND_MOD, (0x100 | (level)))
+
+/*
+ * When clearing the interrupt, make sure this clear does make it
+ * to the hub. Otherwise we could end up losing interrupts.
+ * We do an uncached load of the int_pend0 register to ensure this.
+ */
+
+#define LOCAL_HUB_CLR_INTR(level) \
+do { \
+ LOCAL_HUB_S(PI_INT_PEND_MOD, (level)); \
+ LOCAL_HUB_L(PI_INT_PEND0); \
+} while (0);
+
+#define REMOTE_HUB_CLR_INTR(hub, level) \
+do { \
+ nasid_t __hub = (hub); \
+ \
+ REMOTE_HUB_S(__hub, PI_INT_PEND_MOD, (level)); \
+ REMOTE_HUB_L(__hub, PI_INT_PEND0); \
+} while (0);
+
+/*
+ * Hard-coded interrupt levels:
+ */
+
+/*
+ * L0 = SW1
+ * L1 = SW2
+ * L2 = INT_PEND0
+ * L3 = INT_PEND1
+ * L4 = RTC
+ * L5 = Profiling Timer
+ * L6 = Hub Errors
+ * L7 = Count/Compare (T5 counters)
+ */
+
+
+/*
+ * INT_PEND0 hard-coded bits.
+ */
+
+/*
+ * INT_PEND0 bits determined by hardware:
+ */
+#define RESERVED_INTR 0 /* What is this bit? */
+#define GFX_INTR_A 1
+#define GFX_INTR_B 2
+#define PG_MIG_INTR 3
+#define UART_INTR 4
+#define CC_PEND_A 5
+#define CC_PEND_B 6
+
+/*
+ * INT_PEND0 used by the kernel for itself ...
+ */
+#define CPU_RESCHED_A_IRQ 7
+#define CPU_RESCHED_B_IRQ 8
+#define CPU_CALL_A_IRQ 9
+#define CPU_CALL_B_IRQ 10
+#define MSC_MESG_INTR 11
+#define BASE_PCI_IRQ 12
+
+/*
+ * INT_PEND0 again, bits determined by hardware / hardcoded:
+ */
+#define SDISK_INTR 63 /* SABLE name */
+#define IP_PEND0_6_63 63 /* What is this bit? */
+
+/*
+ * INT_PEND1 hard-coded bits:
+ */
+#define NI_BRDCAST_ERR_A 39
+#define NI_BRDCAST_ERR_B 40
+
+#define LLP_PFAIL_INTR_A 41 /* see ml/SN/SN0/sysctlr.c */
+#define LLP_PFAIL_INTR_B 42
+
+#define TLB_INTR_A 43 /* used for tlb flush random */
+#define TLB_INTR_B 44
+
+#define IP27_INTR_0 45 /* Reserved for PROM use */
+#define IP27_INTR_1 46 /* do not use in Kernel */
+#define IP27_INTR_2 47
+#define IP27_INTR_3 48
+#define IP27_INTR_4 49
+#define IP27_INTR_5 50
+#define IP27_INTR_6 51
+#define IP27_INTR_7 52
+
+#define BRIDGE_ERROR_INTR 53 /* Setup by PROM to catch */
+ /* Bridge Errors */
+#define DEBUG_INTR_A 54
+#define DEBUG_INTR_B 55 /* Used by symmon to stop all cpus */
+#define IO_ERROR_INTR 57 /* Setup by PROM */
+#define CLK_ERR_INTR 58
+#define COR_ERR_INTR_A 59
+#define COR_ERR_INTR_B 60
+#define MD_COR_ERR_INTR 61
+#define NI_ERROR_INTR 62
+#define MSC_PANIC_INTR 63
+
+#endif /* __ASM_SN_INTR_H */
diff --git a/arch/mips/include/asm/sn/io.h b/arch/mips/include/asm/sn/io.h
new file mode 100644
index 00000000..24c6775f
--- /dev/null
+++ b/arch/mips/include/asm/sn/io.h
@@ -0,0 +1,59 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 2003 Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SN_IO_H
+#define _ASM_SN_IO_H
+
+#if defined(CONFIG_SGI_IP27)
+#include <asm/sn/sn0/hubio.h>
+#endif
+
+
+#define IIO_ITTE_BASE 0x400160 /* base of translation table entries */
+#define IIO_ITTE(bigwin) (IIO_ITTE_BASE + 8*(bigwin))
+
+#define IIO_ITTE_OFFSET_BITS 5 /* size of offset field */
+#define IIO_ITTE_OFFSET_MASK ((1<<IIO_ITTE_OFFSET_BITS)-1)
+#define IIO_ITTE_OFFSET_SHIFT 0
+
+#define IIO_ITTE_WIDGET_BITS 4 /* size of widget field */
+#define IIO_ITTE_WIDGET_MASK ((1<<IIO_ITTE_WIDGET_BITS)-1)
+#define IIO_ITTE_WIDGET_SHIFT 8
+
+#define IIO_ITTE_IOSP 1 /* I/O Space bit */
+#define IIO_ITTE_IOSP_MASK 1
+#define IIO_ITTE_IOSP_SHIFT 12
+#define HUB_PIO_MAP_TO_MEM 0
+#define HUB_PIO_MAP_TO_IO 1
+
+#define IIO_ITTE_INVALID_WIDGET 3 /* an invalid widget */
+
+#define IIO_ITTE_PUT(nasid, bigwin, io_or_mem, widget, addr) \
+ REMOTE_HUB_S((nasid), IIO_ITTE(bigwin), \
+ (((((addr) >> BWIN_SIZE_BITS) & \
+ IIO_ITTE_OFFSET_MASK) << IIO_ITTE_OFFSET_SHIFT) | \
+ (io_or_mem << IIO_ITTE_IOSP_SHIFT) | \
+ (((widget) & IIO_ITTE_WIDGET_MASK) << IIO_ITTE_WIDGET_SHIFT)))
+
+#define IIO_ITTE_DISABLE(nasid, bigwin) \
+ IIO_ITTE_PUT((nasid), HUB_PIO_MAP_TO_MEM, \
+ (bigwin), IIO_ITTE_INVALID_WIDGET, 0)
+
+#define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin))
+
+/*
+ * Macro which takes the widget number, and returns the
+ * IO PRB address of that widget.
+ * value _x is expected to be a widget number in the range
+ * 0, 8 - 0xF
+ */
+#define IIO_IOPRB(_x) (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
+ (_x) : \
+ (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
+
+#endif /* _ASM_SN_IO_H */
diff --git a/arch/mips/include/asm/sn/ioc3.h b/arch/mips/include/asm/sn/ioc3.h
new file mode 100644
index 00000000..09967777
--- /dev/null
+++ b/arch/mips/include/asm/sn/ioc3.h
@@ -0,0 +1,663 @@
+/*
+ * Copyright (C) 1999, 2000 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _IOC3_H
+#define _IOC3_H
+
+#include <linux/types.h>
+
+/* SUPERIO uart register map */
+typedef volatile struct ioc3_uartregs {
+ union {
+ volatile u8 rbr; /* read only, DLAB == 0 */
+ volatile u8 thr; /* write only, DLAB == 0 */
+ volatile u8 dll; /* DLAB == 1 */
+ } u1;
+ union {
+ volatile u8 ier; /* DLAB == 0 */
+ volatile u8 dlm; /* DLAB == 1 */
+ } u2;
+ union {
+ volatile u8 iir; /* read only */
+ volatile u8 fcr; /* write only */
+ } u3;
+ volatile u8 iu_lcr;
+ volatile u8 iu_mcr;
+ volatile u8 iu_lsr;
+ volatile u8 iu_msr;
+ volatile u8 iu_scr;
+} ioc3_uregs_t;
+
+#define iu_rbr u1.rbr
+#define iu_thr u1.thr
+#define iu_dll u1.dll
+#define iu_ier u2.ier
+#define iu_dlm u2.dlm
+#define iu_iir u3.iir
+#define iu_fcr u3.fcr
+
+struct ioc3_sioregs {
+ volatile u8 fill[0x141]; /* starts at 0x141 */
+
+ volatile u8 uartc;
+ volatile u8 kbdcg;
+
+ volatile u8 fill0[0x150 - 0x142 - 1];
+
+ volatile u8 pp_data;
+ volatile u8 pp_dsr;
+ volatile u8 pp_dcr;
+
+ volatile u8 fill1[0x158 - 0x152 - 1];
+
+ volatile u8 pp_fifa;
+ volatile u8 pp_cfgb;
+ volatile u8 pp_ecr;
+
+ volatile u8 fill2[0x168 - 0x15a - 1];
+
+ volatile u8 rtcad;
+ volatile u8 rtcdat;
+
+ volatile u8 fill3[0x170 - 0x169 - 1];
+
+ struct ioc3_uartregs uartb; /* 0x20170 */
+ struct ioc3_uartregs uarta; /* 0x20178 */
+};
+
+/* Register layout of IOC3 in configuration space. */
+struct ioc3 {
+ volatile u32 pad0[7]; /* 0x00000 */
+ volatile u32 sio_ir; /* 0x0001c */
+ volatile u32 sio_ies; /* 0x00020 */
+ volatile u32 sio_iec; /* 0x00024 */
+ volatile u32 sio_cr; /* 0x00028 */
+ volatile u32 int_out; /* 0x0002c */
+ volatile u32 mcr; /* 0x00030 */
+
+ /* General Purpose I/O registers */
+ volatile u32 gpcr_s; /* 0x00034 */
+ volatile u32 gpcr_c; /* 0x00038 */
+ volatile u32 gpdr; /* 0x0003c */
+ volatile u32 gppr_0; /* 0x00040 */
+ volatile u32 gppr_1; /* 0x00044 */
+ volatile u32 gppr_2; /* 0x00048 */
+ volatile u32 gppr_3; /* 0x0004c */
+ volatile u32 gppr_4; /* 0x00050 */
+ volatile u32 gppr_5; /* 0x00054 */
+ volatile u32 gppr_6; /* 0x00058 */
+ volatile u32 gppr_7; /* 0x0005c */
+ volatile u32 gppr_8; /* 0x00060 */
+ volatile u32 gppr_9; /* 0x00064 */
+ volatile u32 gppr_10; /* 0x00068 */
+ volatile u32 gppr_11; /* 0x0006c */
+ volatile u32 gppr_12; /* 0x00070 */
+ volatile u32 gppr_13; /* 0x00074 */
+ volatile u32 gppr_14; /* 0x00078 */
+ volatile u32 gppr_15; /* 0x0007c */
+
+ /* Parallel Port Registers */
+ volatile u32 ppbr_h_a; /* 0x00080 */
+ volatile u32 ppbr_l_a; /* 0x00084 */
+ volatile u32 ppcr_a; /* 0x00088 */
+ volatile u32 ppcr; /* 0x0008c */
+ volatile u32 ppbr_h_b; /* 0x00090 */
+ volatile u32 ppbr_l_b; /* 0x00094 */
+ volatile u32 ppcr_b; /* 0x00098 */
+
+ /* Keyboard and Mouse Registers */
+ volatile u32 km_csr; /* 0x0009c */
+ volatile u32 k_rd; /* 0x000a0 */
+ volatile u32 m_rd; /* 0x000a4 */
+ volatile u32 k_wd; /* 0x000a8 */
+ volatile u32 m_wd; /* 0x000ac */
+
+ /* Serial Port Registers */
+ volatile u32 sbbr_h; /* 0x000b0 */
+ volatile u32 sbbr_l; /* 0x000b4 */
+ volatile u32 sscr_a; /* 0x000b8 */
+ volatile u32 stpir_a; /* 0x000bc */
+ volatile u32 stcir_a; /* 0x000c0 */
+ volatile u32 srpir_a; /* 0x000c4 */
+ volatile u32 srcir_a; /* 0x000c8 */
+ volatile u32 srtr_a; /* 0x000cc */
+ volatile u32 shadow_a; /* 0x000d0 */
+ volatile u32 sscr_b; /* 0x000d4 */
+ volatile u32 stpir_b; /* 0x000d8 */
+ volatile u32 stcir_b; /* 0x000dc */
+ volatile u32 srpir_b; /* 0x000e0 */
+ volatile u32 srcir_b; /* 0x000e4 */
+ volatile u32 srtr_b; /* 0x000e8 */
+ volatile u32 shadow_b; /* 0x000ec */
+
+ /* Ethernet Registers */
+ volatile u32 emcr; /* 0x000f0 */
+ volatile u32 eisr; /* 0x000f4 */
+ volatile u32 eier; /* 0x000f8 */
+ volatile u32 ercsr; /* 0x000fc */
+ volatile u32 erbr_h; /* 0x00100 */
+ volatile u32 erbr_l; /* 0x00104 */
+ volatile u32 erbar; /* 0x00108 */
+ volatile u32 ercir; /* 0x0010c */
+ volatile u32 erpir; /* 0x00110 */
+ volatile u32 ertr; /* 0x00114 */
+ volatile u32 etcsr; /* 0x00118 */
+ volatile u32 ersr; /* 0x0011c */
+ volatile u32 etcdc; /* 0x00120 */
+ volatile u32 ebir; /* 0x00124 */
+ volatile u32 etbr_h; /* 0x00128 */
+ volatile u32 etbr_l; /* 0x0012c */
+ volatile u32 etcir; /* 0x00130 */
+ volatile u32 etpir; /* 0x00134 */
+ volatile u32 emar_h; /* 0x00138 */
+ volatile u32 emar_l; /* 0x0013c */
+ volatile u32 ehar_h; /* 0x00140 */
+ volatile u32 ehar_l; /* 0x00144 */
+ volatile u32 micr; /* 0x00148 */
+ volatile u32 midr_r; /* 0x0014c */
+ volatile u32 midr_w; /* 0x00150 */
+ volatile u32 pad1[(0x20000 - 0x00154) / 4];
+
+ /* SuperIO Registers XXX */
+ struct ioc3_sioregs sregs; /* 0x20000 */
+ volatile u32 pad2[(0x40000 - 0x20180) / 4];
+
+ /* SSRAM Diagnostic Access */
+ volatile u32 ssram[(0x80000 - 0x40000) / 4];
+
+ /* Bytebus device offsets
+ 0x80000 - Access to the generic devices selected with DEV0
+ 0x9FFFF bytebus DEV_SEL_0
+ 0xA0000 - Access to the generic devices selected with DEV1
+ 0xBFFFF bytebus DEV_SEL_1
+ 0xC0000 - Access to the generic devices selected with DEV2
+ 0xDFFFF bytebus DEV_SEL_2
+ 0xE0000 - Access to the generic devices selected with DEV3
+ 0xFFFFF bytebus DEV_SEL_3 */
+};
+
+/*
+ * Ethernet RX Buffer
+ */
+struct ioc3_erxbuf {
+ u32 w0; /* first word (valid,bcnt,cksum) */
+ u32 err; /* second word various errors */
+ /* next comes n bytes of padding */
+ /* then the received ethernet frame itself */
+};
+
+#define ERXBUF_IPCKSUM_MASK 0x0000ffff
+#define ERXBUF_BYTECNT_MASK 0x07ff0000
+#define ERXBUF_BYTECNT_SHIFT 16
+#define ERXBUF_V 0x80000000
+
+#define ERXBUF_CRCERR 0x00000001 /* aka RSV15 */
+#define ERXBUF_FRAMERR 0x00000002 /* aka RSV14 */
+#define ERXBUF_CODERR 0x00000004 /* aka RSV13 */
+#define ERXBUF_INVPREAMB 0x00000008 /* aka RSV18 */
+#define ERXBUF_LOLEN 0x00007000 /* aka RSV2_0 */
+#define ERXBUF_HILEN 0x03ff0000 /* aka RSV12_3 */
+#define ERXBUF_MULTICAST 0x04000000 /* aka RSV16 */
+#define ERXBUF_BROADCAST 0x08000000 /* aka RSV17 */
+#define ERXBUF_LONGEVENT 0x10000000 /* aka RSV19 */
+#define ERXBUF_BADPKT 0x20000000 /* aka RSV20 */
+#define ERXBUF_GOODPKT 0x40000000 /* aka RSV21 */
+#define ERXBUF_CARRIER 0x80000000 /* aka RSV22 */
+
+/*
+ * Ethernet TX Descriptor
+ */
+#define ETXD_DATALEN 104
+struct ioc3_etxd {
+ u32 cmd; /* command field */
+ u32 bufcnt; /* buffer counts field */
+ u64 p1; /* buffer pointer 1 */
+ u64 p2; /* buffer pointer 2 */
+ u8 data[ETXD_DATALEN]; /* opt. tx data */
+};
+
+#define ETXD_BYTECNT_MASK 0x000007ff /* total byte count */
+#define ETXD_INTWHENDONE 0x00001000 /* intr when done */
+#define ETXD_D0V 0x00010000 /* data 0 valid */
+#define ETXD_B1V 0x00020000 /* buf 1 valid */
+#define ETXD_B2V 0x00040000 /* buf 2 valid */
+#define ETXD_DOCHECKSUM 0x00080000 /* insert ip cksum */
+#define ETXD_CHKOFF_MASK 0x07f00000 /* cksum byte offset */
+#define ETXD_CHKOFF_SHIFT 20
+
+#define ETXD_D0CNT_MASK 0x0000007f
+#define ETXD_B1CNT_MASK 0x0007ff00
+#define ETXD_B1CNT_SHIFT 8
+#define ETXD_B2CNT_MASK 0x7ff00000
+#define ETXD_B2CNT_SHIFT 20
+
+/*
+ * Bytebus device space
+ */
+#define IOC3_BYTEBUS_DEV0 0x80000L
+#define IOC3_BYTEBUS_DEV1 0xa0000L
+#define IOC3_BYTEBUS_DEV2 0xc0000L
+#define IOC3_BYTEBUS_DEV3 0xe0000L
+
+/* ------------------------------------------------------------------------- */
+
+/* Superio Registers (PIO Access) */
+#define IOC3_SIO_BASE 0x20000
+#define IOC3_SIO_UARTC (IOC3_SIO_BASE+0x141) /* UART Config */
+#define IOC3_SIO_KBDCG (IOC3_SIO_BASE+0x142) /* KBD Config */
+#define IOC3_SIO_PP_BASE (IOC3_SIO_BASE+PP_BASE) /* Parallel Port */
+#define IOC3_SIO_RTC_BASE (IOC3_SIO_BASE+0x168) /* Real Time Clock */
+#define IOC3_SIO_UB_BASE (IOC3_SIO_BASE+UARTB_BASE) /* UART B */
+#define IOC3_SIO_UA_BASE (IOC3_SIO_BASE+UARTA_BASE) /* UART A */
+
+/* SSRAM Diagnostic Access */
+#define IOC3_SSRAM IOC3_RAM_OFF /* base of SSRAM diagnostic access */
+#define IOC3_SSRAM_LEN 0x40000 /* 256kb (address space size, may not be fully populated) */
+#define IOC3_SSRAM_DM 0x0000ffff /* data mask */
+#define IOC3_SSRAM_PM 0x00010000 /* parity mask */
+
+/* bitmasks for PCI_SCR */
+#define PCI_SCR_PAR_RESP_EN 0x00000040 /* enb PCI parity checking */
+#define PCI_SCR_SERR_EN 0x00000100 /* enable the SERR# driver */
+#define PCI_SCR_DROP_MODE_EN 0x00008000 /* drop pios on parity err */
+#define PCI_SCR_RX_SERR (0x1 << 16)
+#define PCI_SCR_DROP_MODE (0x1 << 17)
+#define PCI_SCR_SIG_PAR_ERR (0x1 << 24)
+#define PCI_SCR_SIG_TAR_ABRT (0x1 << 27)
+#define PCI_SCR_RX_TAR_ABRT (0x1 << 28)
+#define PCI_SCR_SIG_MST_ABRT (0x1 << 29)
+#define PCI_SCR_SIG_SERR (0x1 << 30)
+#define PCI_SCR_PAR_ERR (0x1 << 31)
+
+/* bitmasks for IOC3_KM_CSR */
+#define KM_CSR_K_WRT_PEND 0x00000001 /* kbd port xmitting or resetting */
+#define KM_CSR_M_WRT_PEND 0x00000002 /* mouse port xmitting or resetting */
+#define KM_CSR_K_LCB 0x00000004 /* Line Cntrl Bit for last KBD write */
+#define KM_CSR_M_LCB 0x00000008 /* same for mouse */
+#define KM_CSR_K_DATA 0x00000010 /* state of kbd data line */
+#define KM_CSR_K_CLK 0x00000020 /* state of kbd clock line */
+#define KM_CSR_K_PULL_DATA 0x00000040 /* pull kbd data line low */
+#define KM_CSR_K_PULL_CLK 0x00000080 /* pull kbd clock line low */
+#define KM_CSR_M_DATA 0x00000100 /* state of ms data line */
+#define KM_CSR_M_CLK 0x00000200 /* state of ms clock line */
+#define KM_CSR_M_PULL_DATA 0x00000400 /* pull ms data line low */
+#define KM_CSR_M_PULL_CLK 0x00000800 /* pull ms clock line low */
+#define KM_CSR_EMM_MODE 0x00001000 /* emulation mode */
+#define KM_CSR_SIM_MODE 0x00002000 /* clock X8 */
+#define KM_CSR_K_SM_IDLE 0x00004000 /* Keyboard is idle */
+#define KM_CSR_M_SM_IDLE 0x00008000 /* Mouse is idle */
+#define KM_CSR_K_TO 0x00010000 /* Keyboard trying to send/receive */
+#define KM_CSR_M_TO 0x00020000 /* Mouse trying to send/receive */
+#define KM_CSR_K_TO_EN 0x00040000 /* KM_CSR_K_TO + KM_CSR_K_TO_EN = cause
+ SIO_IR to assert */
+#define KM_CSR_M_TO_EN 0x00080000 /* KM_CSR_M_TO + KM_CSR_M_TO_EN = cause
+ SIO_IR to assert */
+#define KM_CSR_K_CLAMP_ONE 0x00100000 /* Pull K_CLK low after rec. one char */
+#define KM_CSR_M_CLAMP_ONE 0x00200000 /* Pull M_CLK low after rec. one char */
+#define KM_CSR_K_CLAMP_THREE 0x00400000 /* Pull K_CLK low after rec. three chars */
+#define KM_CSR_M_CLAMP_THREE 0x00800000 /* Pull M_CLK low after rec. three char */
+
+/* bitmasks for IOC3_K_RD and IOC3_M_RD */
+#define KM_RD_DATA_2 0x000000ff /* 3rd char recvd since last read */
+#define KM_RD_DATA_2_SHIFT 0
+#define KM_RD_DATA_1 0x0000ff00 /* 2nd char recvd since last read */
+#define KM_RD_DATA_1_SHIFT 8
+#define KM_RD_DATA_0 0x00ff0000 /* 1st char recvd since last read */
+#define KM_RD_DATA_0_SHIFT 16
+#define KM_RD_FRAME_ERR_2 0x01000000 /* framing or parity error in byte 2 */
+#define KM_RD_FRAME_ERR_1 0x02000000 /* same for byte 1 */
+#define KM_RD_FRAME_ERR_0 0x04000000 /* same for byte 0 */
+
+#define KM_RD_KBD_MSE 0x08000000 /* 0 if from kbd, 1 if from mouse */
+#define KM_RD_OFLO 0x10000000 /* 4th char recvd before this read */
+#define KM_RD_VALID_2 0x20000000 /* DATA_2 valid */
+#define KM_RD_VALID_1 0x40000000 /* DATA_1 valid */
+#define KM_RD_VALID_0 0x80000000 /* DATA_0 valid */
+#define KM_RD_VALID_ALL (KM_RD_VALID_0|KM_RD_VALID_1|KM_RD_VALID_2)
+
+/* bitmasks for IOC3_K_WD & IOC3_M_WD */
+#define KM_WD_WRT_DATA 0x000000ff /* write to keyboard/mouse port */
+#define KM_WD_WRT_DATA_SHIFT 0
+
+/* bitmasks for serial RX status byte */
+#define RXSB_OVERRUN 0x01 /* char(s) lost */
+#define RXSB_PAR_ERR 0x02 /* parity error */
+#define RXSB_FRAME_ERR 0x04 /* framing error */
+#define RXSB_BREAK 0x08 /* break character */
+#define RXSB_CTS 0x10 /* state of CTS */
+#define RXSB_DCD 0x20 /* state of DCD */
+#define RXSB_MODEM_VALID 0x40 /* DCD, CTS and OVERRUN are valid */
+#define RXSB_DATA_VALID 0x80 /* data byte, FRAME_ERR PAR_ERR & BREAK valid */
+
+/* bitmasks for serial TX control byte */
+#define TXCB_INT_WHEN_DONE 0x20 /* interrupt after this byte is sent */
+#define TXCB_INVALID 0x00 /* byte is invalid */
+#define TXCB_VALID 0x40 /* byte is valid */
+#define TXCB_MCR 0x80 /* data<7:0> to modem control register */
+#define TXCB_DELAY 0xc0 /* delay data<7:0> mSec */
+
+/* bitmasks for IOC3_SBBR_L */
+#define SBBR_L_SIZE 0x00000001 /* 0 == 1KB rings, 1 == 4KB rings */
+#define SBBR_L_BASE 0xfffff000 /* lower serial ring base addr */
+
+/* bitmasks for IOC3_SSCR_<A:B> */
+#define SSCR_RX_THRESHOLD 0x000001ff /* hiwater mark */
+#define SSCR_TX_TIMER_BUSY 0x00010000 /* TX timer in progress */
+#define SSCR_HFC_EN 0x00020000 /* hardware flow control enabled */
+#define SSCR_RX_RING_DCD 0x00040000 /* post RX record on delta-DCD */
+#define SSCR_RX_RING_CTS 0x00080000 /* post RX record on delta-CTS */
+#define SSCR_HIGH_SPD 0x00100000 /* 4X speed */
+#define SSCR_DIAG 0x00200000 /* bypass clock divider for sim */
+#define SSCR_RX_DRAIN 0x08000000 /* drain RX buffer to memory */
+#define SSCR_DMA_EN 0x10000000 /* enable ring buffer DMA */
+#define SSCR_DMA_PAUSE 0x20000000 /* pause DMA */
+#define SSCR_PAUSE_STATE 0x40000000 /* sets when PAUSE takes effect */
+#define SSCR_RESET 0x80000000 /* reset DMA channels */
+
+/* all producer/comsumer pointers are the same bitfield */
+#define PROD_CONS_PTR_4K 0x00000ff8 /* for 4K buffers */
+#define PROD_CONS_PTR_1K 0x000003f8 /* for 1K buffers */
+#define PROD_CONS_PTR_OFF 3
+
+/* bitmasks for IOC3_SRCIR_<A:B> */
+#define SRCIR_ARM 0x80000000 /* arm RX timer */
+
+/* bitmasks for IOC3_SRPIR_<A:B> */
+#define SRPIR_BYTE_CNT 0x07000000 /* bytes in packer */
+#define SRPIR_BYTE_CNT_SHIFT 24
+
+/* bitmasks for IOC3_STCIR_<A:B> */
+#define STCIR_BYTE_CNT 0x0f000000 /* bytes in unpacker */
+#define STCIR_BYTE_CNT_SHIFT 24
+
+/* bitmasks for IOC3_SHADOW_<A:B> */
+#define SHADOW_DR 0x00000001 /* data ready */
+#define SHADOW_OE 0x00000002 /* overrun error */
+#define SHADOW_PE 0x00000004 /* parity error */
+#define SHADOW_FE 0x00000008 /* framing error */
+#define SHADOW_BI 0x00000010 /* break interrupt */
+#define SHADOW_THRE 0x00000020 /* transmit holding register empty */
+#define SHADOW_TEMT 0x00000040 /* transmit shift register empty */
+#define SHADOW_RFCE 0x00000080 /* char in RX fifo has an error */
+#define SHADOW_DCTS 0x00010000 /* delta clear to send */
+#define SHADOW_DDCD 0x00080000 /* delta data carrier detect */
+#define SHADOW_CTS 0x00100000 /* clear to send */
+#define SHADOW_DCD 0x00800000 /* data carrier detect */
+#define SHADOW_DTR 0x01000000 /* data terminal ready */
+#define SHADOW_RTS 0x02000000 /* request to send */
+#define SHADOW_OUT1 0x04000000 /* 16550 OUT1 bit */
+#define SHADOW_OUT2 0x08000000 /* 16550 OUT2 bit */
+#define SHADOW_LOOP 0x10000000 /* loopback enabled */
+
+/* bitmasks for IOC3_SRTR_<A:B> */
+#define SRTR_CNT 0x00000fff /* reload value for RX timer */
+#define SRTR_CNT_VAL 0x0fff0000 /* current value of RX timer */
+#define SRTR_CNT_VAL_SHIFT 16
+#define SRTR_HZ 16000 /* SRTR clock frequency */
+
+/* bitmasks for IOC3_SIO_IR, IOC3_SIO_IEC and IOC3_SIO_IES */
+#define SIO_IR_SA_TX_MT 0x00000001 /* Serial port A TX empty */
+#define SIO_IR_SA_RX_FULL 0x00000002 /* port A RX buf full */
+#define SIO_IR_SA_RX_HIGH 0x00000004 /* port A RX hiwat */
+#define SIO_IR_SA_RX_TIMER 0x00000008 /* port A RX timeout */
+#define SIO_IR_SA_DELTA_DCD 0x00000010 /* port A delta DCD */
+#define SIO_IR_SA_DELTA_CTS 0x00000020 /* port A delta CTS */
+#define SIO_IR_SA_INT 0x00000040 /* port A pass-thru intr */
+#define SIO_IR_SA_TX_EXPLICIT 0x00000080 /* port A explicit TX thru */
+#define SIO_IR_SA_MEMERR 0x00000100 /* port A PCI error */
+#define SIO_IR_SB_TX_MT 0x00000200 /* */
+#define SIO_IR_SB_RX_FULL 0x00000400 /* */
+#define SIO_IR_SB_RX_HIGH 0x00000800 /* */
+#define SIO_IR_SB_RX_TIMER 0x00001000 /* */
+#define SIO_IR_SB_DELTA_DCD 0x00002000 /* */
+#define SIO_IR_SB_DELTA_CTS 0x00004000 /* */
+#define SIO_IR_SB_INT 0x00008000 /* */
+#define SIO_IR_SB_TX_EXPLICIT 0x00010000 /* */
+#define SIO_IR_SB_MEMERR 0x00020000 /* */
+#define SIO_IR_PP_INT 0x00040000 /* P port pass-thru intr */
+#define SIO_IR_PP_INTA 0x00080000 /* PP context A thru */
+#define SIO_IR_PP_INTB 0x00100000 /* PP context B thru */
+#define SIO_IR_PP_MEMERR 0x00200000 /* PP PCI error */
+#define SIO_IR_KBD_INT 0x00400000 /* kbd/mouse intr */
+#define SIO_IR_RT_INT 0x08000000 /* RT output pulse */
+#define SIO_IR_GEN_INT1 0x10000000 /* RT input pulse */
+#define SIO_IR_GEN_INT_SHIFT 28
+
+/* per device interrupt masks */
+#define SIO_IR_SA (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL | \
+ SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER | \
+ SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS | \
+ SIO_IR_SA_INT | SIO_IR_SA_TX_EXPLICIT | \
+ SIO_IR_SA_MEMERR)
+#define SIO_IR_SB (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL | \
+ SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER | \
+ SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS | \
+ SIO_IR_SB_INT | SIO_IR_SB_TX_EXPLICIT | \
+ SIO_IR_SB_MEMERR)
+#define SIO_IR_PP (SIO_IR_PP_INT | SIO_IR_PP_INTA | \
+ SIO_IR_PP_INTB | SIO_IR_PP_MEMERR)
+#define SIO_IR_RT (SIO_IR_RT_INT | SIO_IR_GEN_INT1)
+
+/* macro to load pending interrupts */
+#define IOC3_PENDING_INTRS(mem) (PCI_INW(&((mem)->sio_ir)) & \
+ PCI_INW(&((mem)->sio_ies_ro)))
+
+/* bitmasks for SIO_CR */
+#define SIO_CR_SIO_RESET 0x00000001 /* reset the SIO */
+#define SIO_CR_SER_A_BASE 0x000000fe /* DMA poll addr port A */
+#define SIO_CR_SER_A_BASE_SHIFT 1
+#define SIO_CR_SER_B_BASE 0x00007f00 /* DMA poll addr port B */
+#define SIO_CR_SER_B_BASE_SHIFT 8
+#define SIO_SR_CMD_PULSE 0x00078000 /* byte bus strobe length */
+#define SIO_CR_CMD_PULSE_SHIFT 15
+#define SIO_CR_ARB_DIAG 0x00380000 /* cur !enet PCI requet (ro) */
+#define SIO_CR_ARB_DIAG_TXA 0x00000000
+#define SIO_CR_ARB_DIAG_RXA 0x00080000
+#define SIO_CR_ARB_DIAG_TXB 0x00100000
+#define SIO_CR_ARB_DIAG_RXB 0x00180000
+#define SIO_CR_ARB_DIAG_PP 0x00200000
+#define SIO_CR_ARB_DIAG_IDLE 0x00400000 /* 0 -> active request (ro) */
+
+/* bitmasks for INT_OUT */
+#define INT_OUT_COUNT 0x0000ffff /* pulse interval timer */
+#define INT_OUT_MODE 0x00070000 /* mode mask */
+#define INT_OUT_MODE_0 0x00000000 /* set output to 0 */
+#define INT_OUT_MODE_1 0x00040000 /* set output to 1 */
+#define INT_OUT_MODE_1PULSE 0x00050000 /* send 1 pulse */
+#define INT_OUT_MODE_PULSES 0x00060000 /* send 1 pulse every interval */
+#define INT_OUT_MODE_SQW 0x00070000 /* toggle output every interval */
+#define INT_OUT_DIAG 0x40000000 /* diag mode */
+#define INT_OUT_INT_OUT 0x80000000 /* current state of INT_OUT */
+
+/* time constants for INT_OUT */
+#define INT_OUT_NS_PER_TICK (30 * 260) /* 30 ns PCI clock, divisor=260 */
+#define INT_OUT_TICKS_PER_PULSE 3 /* outgoing pulse lasts 3 ticks */
+#define INT_OUT_US_TO_COUNT(x) /* convert uS to a count value */ \
+ (((x) * 10 + INT_OUT_NS_PER_TICK / 200) * \
+ 100 / INT_OUT_NS_PER_TICK - 1)
+#define INT_OUT_COUNT_TO_US(x) /* convert count value to uS */ \
+ (((x) + 1) * INT_OUT_NS_PER_TICK / 1000)
+#define INT_OUT_MIN_TICKS 3 /* min period is width of pulse in "ticks" */
+#define INT_OUT_MAX_TICKS INT_OUT_COUNT /* largest possible count */
+
+/* bitmasks for GPCR */
+#define GPCR_DIR 0x000000ff /* tristate pin input or output */
+#define GPCR_DIR_PIN(x) (1<<(x)) /* access one of the DIR bits */
+#define GPCR_EDGE 0x000f0000 /* extint edge or level sensitive */
+#define GPCR_EDGE_PIN(x) (1<<((x)+15)) /* access one of the EDGE bits */
+
+/* values for GPCR */
+#define GPCR_INT_OUT_EN 0x00100000 /* enable INT_OUT to pin 0 */
+#define GPCR_MLAN_EN 0x00200000 /* enable MCR to pin 8 */
+#define GPCR_DIR_SERA_XCVR 0x00000080 /* Port A Transceiver select enable */
+#define GPCR_DIR_SERB_XCVR 0x00000040 /* Port B Transceiver select enable */
+#define GPCR_DIR_PHY_RST 0x00000020 /* ethernet PHY reset enable */
+
+/* defs for some of the generic I/O pins */
+#define GPCR_PHY_RESET 0x20 /* pin is output to PHY reset */
+#define GPCR_UARTB_MODESEL 0x40 /* pin is output to port B mode sel */
+#define GPCR_UARTA_MODESEL 0x80 /* pin is output to port A mode sel */
+
+#define GPPR_PHY_RESET_PIN 5 /* GIO pin controlling phy reset */
+#define GPPR_UARTB_MODESEL_PIN 6 /* GIO pin controlling uart b mode select */
+#define GPPR_UARTA_MODESEL_PIN 7 /* GIO pin controlling uart a mode select */
+
+#define EMCR_DUPLEX 0x00000001
+#define EMCR_PROMISC 0x00000002
+#define EMCR_PADEN 0x00000004
+#define EMCR_RXOFF_MASK 0x000001f8
+#define EMCR_RXOFF_SHIFT 3
+#define EMCR_RAMPAR 0x00000200
+#define EMCR_BADPAR 0x00000800
+#define EMCR_BUFSIZ 0x00001000
+#define EMCR_TXDMAEN 0x00002000
+#define EMCR_TXEN 0x00004000
+#define EMCR_RXDMAEN 0x00008000
+#define EMCR_RXEN 0x00010000
+#define EMCR_LOOPBACK 0x00020000
+#define EMCR_ARB_DIAG 0x001c0000
+#define EMCR_ARB_DIAG_IDLE 0x00200000
+#define EMCR_RST 0x80000000
+
+#define EISR_RXTIMERINT 0x00000001
+#define EISR_RXTHRESHINT 0x00000002
+#define EISR_RXOFLO 0x00000004
+#define EISR_RXBUFOFLO 0x00000008
+#define EISR_RXMEMERR 0x00000010
+#define EISR_RXPARERR 0x00000020
+#define EISR_TXEMPTY 0x00010000
+#define EISR_TXRTRY 0x00020000
+#define EISR_TXEXDEF 0x00040000
+#define EISR_TXLCOL 0x00080000
+#define EISR_TXGIANT 0x00100000
+#define EISR_TXBUFUFLO 0x00200000
+#define EISR_TXEXPLICIT 0x00400000
+#define EISR_TXCOLLWRAP 0x00800000
+#define EISR_TXDEFERWRAP 0x01000000
+#define EISR_TXMEMERR 0x02000000
+#define EISR_TXPARERR 0x04000000
+
+#define ERCSR_THRESH_MASK 0x000001ff /* enet RX threshold */
+#define ERCSR_RX_TMR 0x40000000 /* simulation only */
+#define ERCSR_DIAG_OFLO 0x80000000 /* simulation only */
+
+#define ERBR_ALIGNMENT 4096
+#define ERBR_L_RXRINGBASE_MASK 0xfffff000
+
+#define ERBAR_BARRIER_BIT 0x0100
+#define ERBAR_RXBARR_MASK 0xffff0000
+#define ERBAR_RXBARR_SHIFT 16
+
+#define ERCIR_RXCONSUME_MASK 0x00000fff
+
+#define ERPIR_RXPRODUCE_MASK 0x00000fff
+#define ERPIR_ARM 0x80000000
+
+#define ERTR_CNT_MASK 0x000007ff
+
+#define ETCSR_IPGT_MASK 0x0000007f
+#define ETCSR_IPGR1_MASK 0x00007f00
+#define ETCSR_IPGR1_SHIFT 8
+#define ETCSR_IPGR2_MASK 0x007f0000
+#define ETCSR_IPGR2_SHIFT 16
+#define ETCSR_NOTXCLK 0x80000000
+
+#define ETCDC_COLLCNT_MASK 0x0000ffff
+#define ETCDC_DEFERCNT_MASK 0xffff0000
+#define ETCDC_DEFERCNT_SHIFT 16
+
+#define ETBR_ALIGNMENT (64*1024)
+#define ETBR_L_RINGSZ_MASK 0x00000001
+#define ETBR_L_RINGSZ128 0
+#define ETBR_L_RINGSZ512 1
+#define ETBR_L_TXRINGBASE_MASK 0xffffc000
+
+#define ETCIR_TXCONSUME_MASK 0x0000ffff
+#define ETCIR_IDLE 0x80000000
+
+#define ETPIR_TXPRODUCE_MASK 0x0000ffff
+
+#define EBIR_TXBUFPROD_MASK 0x0000001f
+#define EBIR_TXBUFCONS_MASK 0x00001f00
+#define EBIR_TXBUFCONS_SHIFT 8
+#define EBIR_RXBUFPROD_MASK 0x007fc000
+#define EBIR_RXBUFPROD_SHIFT 14
+#define EBIR_RXBUFCONS_MASK 0xff800000
+#define EBIR_RXBUFCONS_SHIFT 23
+
+#define MICR_REGADDR_MASK 0x0000001f
+#define MICR_PHYADDR_MASK 0x000003e0
+#define MICR_PHYADDR_SHIFT 5
+#define MICR_READTRIG 0x00000400
+#define MICR_BUSY 0x00000800
+
+#define MIDR_DATA_MASK 0x0000ffff
+
+#define ERXBUF_IPCKSUM_MASK 0x0000ffff
+#define ERXBUF_BYTECNT_MASK 0x07ff0000
+#define ERXBUF_BYTECNT_SHIFT 16
+#define ERXBUF_V 0x80000000
+
+#define ERXBUF_CRCERR 0x00000001 /* aka RSV15 */
+#define ERXBUF_FRAMERR 0x00000002 /* aka RSV14 */
+#define ERXBUF_CODERR 0x00000004 /* aka RSV13 */
+#define ERXBUF_INVPREAMB 0x00000008 /* aka RSV18 */
+#define ERXBUF_LOLEN 0x00007000 /* aka RSV2_0 */
+#define ERXBUF_HILEN 0x03ff0000 /* aka RSV12_3 */
+#define ERXBUF_MULTICAST 0x04000000 /* aka RSV16 */
+#define ERXBUF_BROADCAST 0x08000000 /* aka RSV17 */
+#define ERXBUF_LONGEVENT 0x10000000 /* aka RSV19 */
+#define ERXBUF_BADPKT 0x20000000 /* aka RSV20 */
+#define ERXBUF_GOODPKT 0x40000000 /* aka RSV21 */
+#define ERXBUF_CARRIER 0x80000000 /* aka RSV22 */
+
+#define ETXD_BYTECNT_MASK 0x000007ff /* total byte count */
+#define ETXD_INTWHENDONE 0x00001000 /* intr when done */
+#define ETXD_D0V 0x00010000 /* data 0 valid */
+#define ETXD_B1V 0x00020000 /* buf 1 valid */
+#define ETXD_B2V 0x00040000 /* buf 2 valid */
+#define ETXD_DOCHECKSUM 0x00080000 /* insert ip cksum */
+#define ETXD_CHKOFF_MASK 0x07f00000 /* cksum byte offset */
+#define ETXD_CHKOFF_SHIFT 20
+
+#define ETXD_D0CNT_MASK 0x0000007f
+#define ETXD_B1CNT_MASK 0x0007ff00
+#define ETXD_B1CNT_SHIFT 8
+#define ETXD_B2CNT_MASK 0x7ff00000
+#define ETXD_B2CNT_SHIFT 20
+
+typedef enum ioc3_subdevs_e {
+ ioc3_subdev_ether,
+ ioc3_subdev_generic,
+ ioc3_subdev_nic,
+ ioc3_subdev_kbms,
+ ioc3_subdev_ttya,
+ ioc3_subdev_ttyb,
+ ioc3_subdev_ecpp,
+ ioc3_subdev_rt,
+ ioc3_nsubdevs
+} ioc3_subdev_t;
+
+/* subdevice disable bits,
+ * from the standard INFO_LBL_SUBDEVS
+ */
+#define IOC3_SDB_ETHER (1<<ioc3_subdev_ether)
+#define IOC3_SDB_GENERIC (1<<ioc3_subdev_generic)
+#define IOC3_SDB_NIC (1<<ioc3_subdev_nic)
+#define IOC3_SDB_KBMS (1<<ioc3_subdev_kbms)
+#define IOC3_SDB_TTYA (1<<ioc3_subdev_ttya)
+#define IOC3_SDB_TTYB (1<<ioc3_subdev_ttyb)
+#define IOC3_SDB_ECPP (1<<ioc3_subdev_ecpp)
+#define IOC3_SDB_RT (1<<ioc3_subdev_rt)
+
+#define IOC3_ALL_SUBDEVS ((1<<ioc3_nsubdevs)-1)
+
+#define IOC3_SDB_SERIAL (IOC3_SDB_TTYA|IOC3_SDB_TTYB)
+
+#define IOC3_STD_SUBDEVS IOC3_ALL_SUBDEVS
+
+#define IOC3_INTA_SUBDEVS IOC3_SDB_ETHER
+#define IOC3_INTB_SUBDEVS (IOC3_SDB_GENERIC|IOC3_SDB_KBMS|IOC3_SDB_SERIAL|IOC3_SDB_ECPP|IOC3_SDB_RT)
+
+#endif /* _IOC3_H */
diff --git a/arch/mips/include/asm/sn/klconfig.h b/arch/mips/include/asm/sn/klconfig.h
new file mode 100644
index 00000000..fe02900b
--- /dev/null
+++ b/arch/mips/include/asm/sn/klconfig.h
@@ -0,0 +1,898 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/klconfig.h>.
+ *
+ * Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2000 by Ralf Baechle
+ */
+#ifndef _ASM_SN_KLCONFIG_H
+#define _ASM_SN_KLCONFIG_H
+
+/*
+ * The KLCONFIG structures store info about the various BOARDs found
+ * during Hardware Discovery. In addition, it stores info about the
+ * components found on the BOARDs.
+ */
+
+/*
+ * WARNING:
+ * Certain assembly language routines (notably xxxxx.s) in the IP27PROM
+ * will depend on the format of the data structures in this file. In
+ * most cases, rearranging the fields can seriously break things.
+ * Adding fields in the beginning or middle can also break things.
+ * Add fields if necessary, to the end of a struct in such a way
+ * that offsets of existing fields do not change.
+ */
+
+#include <linux/types.h>
+#include <asm/sn/types.h>
+
+#if defined(CONFIG_SGI_IP27)
+
+#include <asm/sn/sn0/addrs.h>
+//#include <sys/SN/router.h>
+// XXX Stolen from <sys/SN/router.h>:
+#define MAX_ROUTER_PORTS (6) /* Max. number of ports on a router */
+#include <asm/sn/fru.h>
+//#include <sys/graph.h>
+//#include <sys/xtalk/xbow.h>
+
+#elif defined(CONFIG_SGI_IP35)
+
+#include <asm/sn/sn1/addrs.h>
+#include <sys/sn/router.h>
+#include <sys/graph.h>
+#include <asm/xtalk/xbow.h>
+
+#endif /* !CONFIG_SGI_IP27 && !CONFIG_SGI_IP35 */
+
+#if defined(CONFIG_SGI_IP27) || defined(CONFIG_SGI_IP35)
+#include <asm/sn/agent.h>
+#include <asm/fw/arc/types.h>
+#include <asm/fw/arc/hinv.h>
+#if defined(CONFIG_SGI_IP35)
+// The hack file has to be before vector and after sn0_fru....
+#include <asm/hack.h>
+#include <asm/sn/vector.h>
+#include <asm/xtalk/xtalk.h>
+#endif /* CONFIG_SGI_IP35 */
+#endif /* CONFIG_SGI_IP27 || CONFIG_SGI_IP35 */
+
+typedef u64 nic_t;
+
+#define KLCFGINFO_MAGIC 0xbeedbabe
+
+typedef s32 klconf_off_t;
+
+/*
+ * Some IMPORTANT OFFSETS. These are the offsets on all NODES.
+ */
+#define MAX_MODULE_ID 255
+#define SIZE_PAD 4096 /* 4k padding for structures */
+/*
+ * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets,
+ * 2 Midplanes assuming no pci card cages
+ */
+#define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 2)
+
+/* XXX if each node is guaranteed to have some memory */
+
+#define MAX_PCI_DEVS 8
+
+/* lboard_t->brd_flags fields */
+/* All bits in this field are currently used. Try the pad fields if
+ you need more flag bits */
+
+#define ENABLE_BOARD 0x01
+#define FAILED_BOARD 0x02
+#define DUPLICATE_BOARD 0x04 /* Boards like midplanes/routers which
+ are discovered twice. Use one of them */
+#define VISITED_BOARD 0x08 /* Used for compact hub numbering. */
+#define LOCAL_MASTER_IO6 0x10 /* master io6 for that node */
+#define GLOBAL_MASTER_IO6 0x20
+#define THIRD_NIC_PRESENT 0x40 /* for future use */
+#define SECOND_NIC_PRESENT 0x80 /* addons like MIO are present */
+
+/* klinfo->flags fields */
+
+#define KLINFO_ENABLE 0x01 /* This component is enabled */
+#define KLINFO_FAILED 0x02 /* This component failed */
+#define KLINFO_DEVICE 0x04 /* This component is a device */
+#define KLINFO_VISITED 0x08 /* This component has been visited */
+#define KLINFO_CONTROLLER 0x10 /* This component is a device controller */
+#define KLINFO_INSTALL 0x20 /* Install a driver */
+#define KLINFO_HEADLESS 0x40 /* Headless (or hubless) component */
+#define IS_CONSOLE_IOC3(i) ((((klinfo_t *)i)->flags) & KLINFO_INSTALL)
+
+#define GB2 0x80000000
+
+#define MAX_RSV_PTRS 32
+
+/* Structures to manage various data storage areas */
+/* The numbers must be contiguous since the array index i
+ is used in the code to allocate various areas.
+*/
+
+#define BOARD_STRUCT 0
+#define COMPONENT_STRUCT 1
+#define ERRINFO_STRUCT 2
+#define KLMALLOC_TYPE_MAX (ERRINFO_STRUCT + 1)
+#define DEVICE_STRUCT 3
+
+
+typedef struct console_s {
+ unsigned long uart_base;
+ unsigned long config_base;
+ unsigned long memory_base;
+ short baud;
+ short flag;
+ int type;
+ nasid_t nasid;
+ char wid;
+ char npci;
+ nic_t baseio_nic;
+} console_t;
+
+typedef struct klc_malloc_hdr {
+ klconf_off_t km_base;
+ klconf_off_t km_limit;
+ klconf_off_t km_current;
+} klc_malloc_hdr_t;
+
+/* Functions/macros needed to use this structure */
+
+typedef struct kl_config_hdr {
+ u64 ch_magic; /* set this to KLCFGINFO_MAGIC */
+ u32 ch_version; /* structure version number */
+ klconf_off_t ch_malloc_hdr_off; /* offset of ch_malloc_hdr */
+ klconf_off_t ch_cons_off; /* offset of ch_cons */
+ klconf_off_t ch_board_info; /* the link list of boards */
+ console_t ch_cons_info; /* address info of the console */
+ klc_malloc_hdr_t ch_malloc_hdr[KLMALLOC_TYPE_MAX];
+ confidence_t ch_sw_belief; /* confidence that software is bad*/
+ confidence_t ch_sn0net_belief; /* confidence that sn0net is bad */
+} kl_config_hdr_t;
+
+
+#define KL_CONFIG_HDR(_nasid) ((kl_config_hdr_t *)(KLCONFIG_ADDR(_nasid)))
+#define KL_CONFIG_INFO_OFFSET(_nasid) \
+ (KL_CONFIG_HDR(_nasid)->ch_board_info)
+#define KL_CONFIG_INFO_SET_OFFSET(_nasid, _off) \
+ (KL_CONFIG_HDR(_nasid)->ch_board_info = (_off))
+
+#define KL_CONFIG_INFO(_nasid) \
+ (lboard_t *)((KL_CONFIG_HDR(_nasid)->ch_board_info) ? \
+ NODE_OFFSET_TO_K1((_nasid), KL_CONFIG_HDR(_nasid)->ch_board_info) : \
+ 0)
+#define KL_CONFIG_MAGIC(_nasid) (KL_CONFIG_HDR(_nasid)->ch_magic)
+
+#define KL_CONFIG_CHECK_MAGIC(_nasid) \
+ (KL_CONFIG_HDR(_nasid)->ch_magic == KLCFGINFO_MAGIC)
+
+#define KL_CONFIG_HDR_INIT_MAGIC(_nasid) \
+ (KL_CONFIG_HDR(_nasid)->ch_magic = KLCFGINFO_MAGIC)
+
+/* --- New Macros for the changed kl_config_hdr_t structure --- */
+
+#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\
+ ((unsigned long)_k + (_k->ch_malloc_hdr_off)))
+
+#define KL_CONFIG_CH_MALLOC_HDR(_n) PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n))
+
+#define PTR_CH_CONS_INFO(_k) ((console_t *)\
+ ((unsigned long)_k + (_k->ch_cons_off)))
+
+#define KL_CONFIG_CH_CONS_INFO(_n) PTR_CH_CONS_INFO(KL_CONFIG_HDR(_n))
+
+/* ------------------------------------------------------------- */
+
+#define KL_CONFIG_INFO_START(_nasid) \
+ (klconf_off_t)(KLCONFIG_OFFSET(_nasid) + sizeof(kl_config_hdr_t))
+
+#define KL_CONFIG_BOARD_NASID(_brd) ((_brd)->brd_nasid)
+#define KL_CONFIG_BOARD_SET_NEXT(_brd, _off) ((_brd)->brd_next = (_off))
+
+#define KL_CONFIG_DUPLICATE_BOARD(_brd) ((_brd)->brd_flags & DUPLICATE_BOARD)
+
+#define XBOW_PORT_TYPE_HUB(_xbowp, _link) \
+ ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_HUB)
+#define XBOW_PORT_TYPE_IO(_xbowp, _link) \
+ ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_IO)
+
+#define XBOW_PORT_IS_ENABLED(_xbowp, _link) \
+ ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_flag & XBOW_PORT_ENABLE)
+#define XBOW_PORT_NASID(_xbowp, _link) \
+ ((_xbowp)->xbow_port_info[(_link) - BASE_XBOW_PORT].port_nasid)
+
+#define XBOW_PORT_IO 0x1
+#define XBOW_PORT_HUB 0x2
+#define XBOW_PORT_ENABLE 0x4
+
+#define SN0_PORT_FENCE_SHFT 0
+#define SN0_PORT_FENCE_MASK (1 << SN0_PORT_FENCE_SHFT)
+
+/*
+ * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD
+ * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to
+ * the LOCAL/current NODE. REMOTE means it is attached to a different
+ * node.(TBD - Need a way to treat ROUTER boards.)
+ *
+ * There are 2 different structures to represent these boards -
+ * lboard - Local board, rboard - remote board. These 2 structures
+ * can be arbitrarily mixed in the LINKED LIST of BOARDs. (Refer
+ * Figure below). The first byte of the rboard or lboard structure
+ * is used to find out its type - no unions are used.
+ * If it is a lboard, then the config info of this board will be found
+ * on the local node. (LOCAL NODE BASE + offset value gives pointer to
+ * the structure.
+ * If it is a rboard, the local structure contains the node number
+ * and the offset of the beginning of the LINKED LIST on the remote node.
+ * The details of the hardware on a remote node can be built locally,
+ * if required, by reading the LINKED LIST on the remote node and
+ * ignoring all the rboards on that node.
+ *
+ * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the
+ * First board info on the remote node. The remote node list is
+ * traversed as the local list, using the REMOTE BASE ADDRESS and not
+ * the local base address and ignoring all rboard values.
+ *
+ *
+ KLCONFIG
+
+ +------------+ +------------+ +------------+ +------------+
+ | lboard | +-->| lboard | +-->| rboard | +-->| lboard |
+ +------------+ | +------------+ | +------------+ | +------------+
+ | board info | | | board info | | |errinfo,bptr| | | board info |
+ +------------+ | +------------+ | +------------+ | +------------+
+ | offset |--+ | offset |--+ | offset |--+ |offset=NULL |
+ +------------+ +------------+ +------------+ +------------+
+
+
+ +------------+
+ | board info |
+ +------------+ +--------------------------------+
+ | compt 1 |------>| type, rev, diaginfo, size ... | (CPU)
+ +------------+ +--------------------------------+
+ | compt 2 |--+
+ +------------+ | +--------------------------------+
+ | ... | +--->| type, rev, diaginfo, size ... | (MEM_BANK)
+ +------------+ +--------------------------------+
+ | errinfo |--+
+ +------------+ | +--------------------------------+
+ +--->|r/l brd errinfo,compt err flags |
+ +--------------------------------+
+
+ *
+ * Each BOARD consists of COMPONENTs and the BOARD structure has
+ * pointers (offsets) to its COMPONENT structure.
+ * The COMPONENT structure has version info, size and speed info, revision,
+ * error info and the NIC info. This structure can accommodate any
+ * BOARD with arbitrary COMPONENT composition.
+ *
+ * The ERRORINFO part of each BOARD has error information
+ * that describes errors about the BOARD itself. It also has flags to
+ * indicate the COMPONENT(s) on the board that have errors. The error
+ * information specific to the COMPONENT is present in the respective
+ * COMPONENT structure.
+ *
+ * The ERRORINFO structure is also treated like a COMPONENT, ie. the
+ * BOARD has pointers(offset) to the ERRORINFO structure. The rboard
+ * structure also has a pointer to the ERRORINFO structure. This is
+ * the place to store ERRORINFO about a REMOTE NODE, if the HUB on
+ * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where
+ * only the CPU of the REMOTE NODE is disabled, the ERRORINFO pointer can
+ * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info
+ * which is present on the REMOTE NODE.(TBD)
+ * REMOTE ERRINFO can be stored on any of the nearest nodes
+ * or on all the nearest nodes.(TBD)
+ * Like BOARD structures, REMOTE ERRINFO structures can be built locally
+ * using the rboard errinfo pointer.
+ *
+ * In order to get useful information from this Data organization, a set of
+ * interface routines are provided (TBD). The important thing to remember while
+ * manipulating the structures, is that, the NODE number information should
+ * be used. If the NODE is non-zero (remote) then each offset should
+ * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR.
+ * This includes offsets for BOARDS, COMPONENTS and ERRORINFO.
+ *
+ * Note that these structures do not provide much info about connectivity.
+ * That info will be part of HWGRAPH, which is an extension of the cfg_t
+ * data structure. (ref IP27prom/cfg.h) It has to be extended to include
+ * the IO part of the Network(TBD).
+ *
+ * The data structures below define the above concepts.
+ */
+
+/*
+ * Values for CPU types
+ */
+#define KL_CPU_R4000 0x1 /* Standard R4000 */
+#define KL_CPU_TFP 0x2 /* TFP processor */
+#define KL_CPU_R10000 0x3 /* R10000 (T5) */
+#define KL_CPU_NONE (-1) /* no cpu present in slot */
+
+/*
+ * IP27 BOARD classes
+ */
+
+#define KLCLASS_MASK 0xf0
+#define KLCLASS_NONE 0x00
+#define KLCLASS_NODE 0x10 /* CPU, Memory and HUB board */
+#define KLCLASS_CPU KLCLASS_NODE
+#define KLCLASS_IO 0x20 /* BaseIO, 4 ch SCSI, ethernet, FDDI
+ and the non-graphics widget boards */
+#define KLCLASS_ROUTER 0x30 /* Router board */
+#define KLCLASS_MIDPLANE 0x40 /* We need to treat this as a board
+ so that we can record error info */
+#define KLCLASS_GFX 0x50 /* graphics boards */
+
+#define KLCLASS_PSEUDO_GFX 0x60 /* HDTV type cards that use a gfx
+ * hw ifc to xtalk and are not gfx
+ * class for sw purposes */
+
+#define KLCLASS_MAX 7 /* Bump this if a new CLASS is added */
+#define KLTYPE_MAX 10 /* Bump this if a new CLASS is added */
+
+#define KLCLASS_UNKNOWN 0xf0
+
+#define KLCLASS(_x) ((_x) & KLCLASS_MASK)
+
+/*
+ * IP27 board types
+ */
+
+#define KLTYPE_MASK 0x0f
+#define KLTYPE_NONE 0x00
+#define KLTYPE_EMPTY 0x00
+
+#define KLTYPE_WEIRDCPU (KLCLASS_CPU | 0x0)
+#define KLTYPE_IP27 (KLCLASS_CPU | 0x1) /* 2 CPUs(R10K) per board */
+
+#define KLTYPE_WEIRDIO (KLCLASS_IO | 0x0)
+#define KLTYPE_BASEIO (KLCLASS_IO | 0x1) /* IOC3, SuperIO, Bridge, SCSI */
+#define KLTYPE_IO6 KLTYPE_BASEIO /* Additional name */
+#define KLTYPE_4CHSCSI (KLCLASS_IO | 0x2)
+#define KLTYPE_MSCSI KLTYPE_4CHSCSI /* Additional name */
+#define KLTYPE_ETHERNET (KLCLASS_IO | 0x3)
+#define KLTYPE_MENET KLTYPE_ETHERNET /* Additional name */
+#define KLTYPE_FDDI (KLCLASS_IO | 0x4)
+#define KLTYPE_UNUSED (KLCLASS_IO | 0x5) /* XXX UNUSED */
+#define KLTYPE_HAROLD (KLCLASS_IO | 0x6) /* PCI SHOE BOX */
+#define KLTYPE_PCI KLTYPE_HAROLD
+#define KLTYPE_VME (KLCLASS_IO | 0x7) /* Any 3rd party VME card */
+#define KLTYPE_MIO (KLCLASS_IO | 0x8)
+#define KLTYPE_FC (KLCLASS_IO | 0x9)
+#define KLTYPE_LINC (KLCLASS_IO | 0xA)
+#define KLTYPE_TPU (KLCLASS_IO | 0xB) /* Tensor Processing Unit */
+#define KLTYPE_GSN_A (KLCLASS_IO | 0xC) /* Main GSN board */
+#define KLTYPE_GSN_B (KLCLASS_IO | 0xD) /* Auxiliary GSN board */
+
+#define KLTYPE_GFX (KLCLASS_GFX | 0x0) /* unknown graphics type */
+#define KLTYPE_GFX_KONA (KLCLASS_GFX | 0x1) /* KONA graphics on IP27 */
+#define KLTYPE_GFX_MGRA (KLCLASS_GFX | 0x3) /* MGRAS graphics on IP27 */
+
+#define KLTYPE_WEIRDROUTER (KLCLASS_ROUTER | 0x0)
+#define KLTYPE_ROUTER (KLCLASS_ROUTER | 0x1)
+#define KLTYPE_ROUTER2 KLTYPE_ROUTER /* Obsolete! */
+#define KLTYPE_NULL_ROUTER (KLCLASS_ROUTER | 0x2)
+#define KLTYPE_META_ROUTER (KLCLASS_ROUTER | 0x3)
+
+#define KLTYPE_WEIRDMIDPLANE (KLCLASS_MIDPLANE | 0x0)
+#define KLTYPE_MIDPLANE8 (KLCLASS_MIDPLANE | 0x1) /* 8 slot backplane */
+#define KLTYPE_MIDPLANE KLTYPE_MIDPLANE8
+#define KLTYPE_PBRICK_XBOW (KLCLASS_MIDPLANE | 0x2)
+
+#define KLTYPE_IOBRICK (KLCLASS_IOBRICK | 0x0)
+#define KLTYPE_IBRICK (KLCLASS_IOBRICK | 0x1)
+#define KLTYPE_PBRICK (KLCLASS_IOBRICK | 0x2)
+#define KLTYPE_XBRICK (KLCLASS_IOBRICK | 0x3)
+
+#define KLTYPE_PBRICK_BRIDGE KLTYPE_PBRICK
+
+/* The value of type should be more than 8 so that hinv prints
+ * out the board name from the NIC string. For values less than
+ * 8 the name of the board needs to be hard coded in a few places.
+ * When bringup started nic names had not standardized and so we
+ * had to hard code. (For people interested in history.)
+ */
+#define KLTYPE_XTHD (KLCLASS_PSEUDO_GFX | 0x9)
+
+#define KLTYPE_UNKNOWN (KLCLASS_UNKNOWN | 0xf)
+
+#define KLTYPE(_x) ((_x) & KLTYPE_MASK)
+#define IS_MIO_PRESENT(l) ((l->brd_type == KLTYPE_BASEIO) && \
+ (l->brd_flags & SECOND_NIC_PRESENT))
+#define IS_MIO_IOC3(l, n) (IS_MIO_PRESENT(l) && (n > 2))
+
+/*
+ * board structures
+ */
+
+#define MAX_COMPTS_PER_BRD 24
+
+#define LOCAL_BOARD 1
+#define REMOTE_BOARD 2
+
+#define LBOARD_STRUCT_VERSION 2
+
+typedef struct lboard_s {
+ klconf_off_t brd_next; /* Next BOARD */
+ unsigned char struct_type; /* type of structure, local or remote */
+ unsigned char brd_type; /* type+class */
+ unsigned char brd_sversion; /* version of this structure */
+ unsigned char brd_brevision; /* board revision */
+ unsigned char brd_promver; /* board prom version, if any */
+ unsigned char brd_flags; /* Enabled, Disabled etc */
+ unsigned char brd_slot; /* slot number */
+ unsigned short brd_debugsw; /* Debug switches */
+ moduleid_t brd_module; /* module to which it belongs */
+ partid_t brd_partition; /* Partition number */
+ unsigned short brd_diagval; /* diagnostic value */
+ unsigned short brd_diagparm; /* diagnostic parameter */
+ unsigned char brd_inventory; /* inventory history */
+ unsigned char brd_numcompts; /* Number of components */
+ nic_t brd_nic; /* Number in CAN */
+ nasid_t brd_nasid; /* passed parameter */
+ klconf_off_t brd_compts[MAX_COMPTS_PER_BRD]; /* pointers to COMPONENTS */
+ klconf_off_t brd_errinfo; /* Board's error information */
+ struct lboard_s *brd_parent; /* Logical parent for this brd */
+ vertex_hdl_t brd_graph_link; /* vertex hdl to connect extern compts */
+ confidence_t brd_confidence; /* confidence that the board is bad */
+ nasid_t brd_owner; /* who owns this board */
+ unsigned char brd_nic_flags; /* To handle 8 more NICs */
+ char brd_name[32];
+} lboard_t;
+
+
+/*
+ * Make sure we pass back the calias space address for local boards.
+ * klconfig board traversal and error structure extraction defines.
+ */
+
+#define BOARD_SLOT(_brd) ((_brd)->brd_slot)
+
+#define KLCF_CLASS(_brd) KLCLASS((_brd)->brd_type)
+#define KLCF_TYPE(_brd) KLTYPE((_brd)->brd_type)
+#define KLCF_REMOTE(_brd) (((_brd)->struct_type & LOCAL_BOARD) ? 0 : 1)
+#define KLCF_NUM_COMPS(_brd) ((_brd)->brd_numcompts)
+#define KLCF_MODULE_ID(_brd) ((_brd)->brd_module)
+
+#define KLCF_NEXT(_brd) \
+ ((_brd)->brd_next ? \
+ (lboard_t *)(NODE_OFFSET_TO_K1(NASID_GET(_brd), (_brd)->brd_next)):\
+ NULL)
+#define KLCF_COMP(_brd, _ndx) \
+ (klinfo_t *)(NODE_OFFSET_TO_K1(NASID_GET(_brd), \
+ (_brd)->brd_compts[(_ndx)]))
+
+#define KLCF_COMP_ERROR(_brd, _comp) \
+ (NODE_OFFSET_TO_K1(NASID_GET(_brd), (_comp)->errinfo))
+
+#define KLCF_COMP_TYPE(_comp) ((_comp)->struct_type)
+#define KLCF_BRIDGE_W_ID(_comp) ((_comp)->physid) /* Widget ID */
+
+
+
+/*
+ * Generic info structure. This stores common info about a
+ * component.
+ */
+
+typedef struct klinfo_s { /* Generic info */
+ unsigned char struct_type; /* type of this structure */
+ unsigned char struct_version; /* version of this structure */
+ unsigned char flags; /* Enabled, disabled etc */
+ unsigned char revision; /* component revision */
+ unsigned short diagval; /* result of diagnostics */
+ unsigned short diagparm; /* diagnostic parameter */
+ unsigned char inventory; /* previous inventory status */
+ nic_t nic; /* MUst be aligned properly */
+ unsigned char physid; /* physical id of component */
+ unsigned int virtid; /* virtual id as seen by system */
+ unsigned char widid; /* Widget id - if applicable */
+ nasid_t nasid; /* node number - from parent */
+ char pad1; /* pad out structure. */
+ char pad2; /* pad out structure. */
+ COMPONENT *arcs_compt; /* ptr to the arcs struct for ease*/
+ klconf_off_t errinfo; /* component specific errors */
+ unsigned short pad3; /* pci fields have moved over to */
+ unsigned short pad4; /* klbri_t */
+} klinfo_t ;
+
+#define KLCONFIG_INFO_ENABLED(_i) ((_i)->flags & KLINFO_ENABLE)
+/*
+ * Component structures.
+ * Following are the currently identified components:
+ * CPU, HUB, MEM_BANK,
+ * XBOW(consists of 16 WIDGETs, each of which can be HUB or GRAPHICS or BRIDGE)
+ * BRIDGE, IOC3, SuperIO, SCSI, FDDI
+ * ROUTER
+ * GRAPHICS
+ */
+#define KLSTRUCT_UNKNOWN 0
+#define KLSTRUCT_CPU 1
+#define KLSTRUCT_HUB 2
+#define KLSTRUCT_MEMBNK 3
+#define KLSTRUCT_XBOW 4
+#define KLSTRUCT_BRI 5
+#define KLSTRUCT_IOC3 6
+#define KLSTRUCT_PCI 7
+#define KLSTRUCT_VME 8
+#define KLSTRUCT_ROU 9
+#define KLSTRUCT_GFX 10
+#define KLSTRUCT_SCSI 11
+#define KLSTRUCT_FDDI 12
+#define KLSTRUCT_MIO 13
+#define KLSTRUCT_DISK 14
+#define KLSTRUCT_TAPE 15
+#define KLSTRUCT_CDROM 16
+#define KLSTRUCT_HUB_UART 17
+#define KLSTRUCT_IOC3ENET 18
+#define KLSTRUCT_IOC3UART 19
+#define KLSTRUCT_UNUSED 20 /* XXX UNUSED */
+#define KLSTRUCT_IOC3PCKM 21
+#define KLSTRUCT_RAD 22
+#define KLSTRUCT_HUB_TTY 23
+#define KLSTRUCT_IOC3_TTY 24
+
+/* Early Access IO proms are compatible
+ only with KLSTRUCT values up to 24. */
+
+#define KLSTRUCT_FIBERCHANNEL 25
+#define KLSTRUCT_MOD_SERIAL_NUM 26
+#define KLSTRUCT_IOC3MS 27
+#define KLSTRUCT_TPU 28
+#define KLSTRUCT_GSN_A 29
+#define KLSTRUCT_GSN_B 30
+#define KLSTRUCT_XTHD 31
+
+/*
+ * These are the indices of various components within a lboard structure.
+ */
+
+#define IP27_CPU0_INDEX 0
+#define IP27_CPU1_INDEX 1
+#define IP27_HUB_INDEX 2
+#define IP27_MEM_INDEX 3
+
+#define BASEIO_BRIDGE_INDEX 0
+#define BASEIO_IOC3_INDEX 1
+#define BASEIO_SCSI1_INDEX 2
+#define BASEIO_SCSI2_INDEX 3
+
+#define MIDPLANE_XBOW_INDEX 0
+#define ROUTER_COMPONENT_INDEX 0
+
+#define CH4SCSI_BRIDGE_INDEX 0
+
+/* Info holders for various hardware components */
+
+typedef u64 *pci_t;
+typedef u64 *vmeb_t;
+typedef u64 *vmed_t;
+typedef u64 *fddi_t;
+typedef u64 *scsi_t;
+typedef u64 *mio_t;
+typedef u64 *graphics_t;
+typedef u64 *router_t;
+
+/*
+ * The port info in ip27_cfg area translates to a lboart_t in the
+ * KLCONFIG area. But since KLCONFIG does not use pointers, lboart_t
+ * is stored in terms of a nasid and a offset from start of KLCONFIG
+ * area on that nasid.
+ */
+typedef struct klport_s {
+ nasid_t port_nasid;
+ unsigned char port_flag;
+ klconf_off_t port_offset;
+} klport_t;
+
+typedef struct klcpu_s { /* CPU */
+ klinfo_t cpu_info;
+ unsigned short cpu_prid; /* Processor PRID value */
+ unsigned short cpu_fpirr; /* FPU IRR value */
+ unsigned short cpu_speed; /* Speed in MHZ */
+ unsigned short cpu_scachesz; /* secondary cache size in MB */
+ unsigned short cpu_scachespeed;/* secondary cache speed in MHz */
+} klcpu_t ;
+
+#define CPU_STRUCT_VERSION 2
+
+typedef struct klhub_s { /* HUB */
+ klinfo_t hub_info;
+ unsigned int hub_flags; /* PCFG_HUB_xxx flags */
+ klport_t hub_port; /* hub is connected to this */
+ nic_t hub_box_nic; /* nic of containing box */
+ klconf_off_t hub_mfg_nic; /* MFG NIC string */
+ u64 hub_speed; /* Speed of hub in HZ */
+} klhub_t ;
+
+typedef struct klhub_uart_s { /* HUB */
+ klinfo_t hubuart_info;
+ unsigned int hubuart_flags; /* PCFG_HUB_xxx flags */
+ nic_t hubuart_box_nic; /* nic of containing box */
+} klhub_uart_t ;
+
+#define MEMORY_STRUCT_VERSION 2
+
+typedef struct klmembnk_s { /* MEMORY BANK */
+ klinfo_t membnk_info;
+ short membnk_memsz; /* Total memory in megabytes */
+ short membnk_dimm_select; /* bank to physical addr mapping*/
+ short membnk_bnksz[MD_MEM_BANKS]; /* Memory bank sizes */
+ short membnk_attr;
+} klmembnk_t ;
+
+#define KLCONFIG_MEMBNK_SIZE(_info, _bank) \
+ ((_info)->membnk_bnksz[(_bank)])
+
+
+#define MEMBNK_PREMIUM 1
+#define KLCONFIG_MEMBNK_PREMIUM(_info, _bank) \
+ ((_info)->membnk_attr & (MEMBNK_PREMIUM << (_bank)))
+
+#define MAX_SERIAL_NUM_SIZE 10
+
+typedef struct klmod_serial_num_s {
+ klinfo_t snum_info;
+ union {
+ char snum_str[MAX_SERIAL_NUM_SIZE];
+ unsigned long long snum_int;
+ } snum;
+} klmod_serial_num_t;
+
+/* Macros needed to access serial number structure in lboard_t.
+ Hard coded values are necessary since we cannot treat
+ serial number struct as a component without losing compatibility
+ between prom versions. */
+
+#define GET_SNUM_COMP(_l) ((klmod_serial_num_t *)\
+ KLCF_COMP(_l, _l->brd_numcompts))
+
+#define MAX_XBOW_LINKS 16
+
+typedef struct klxbow_s { /* XBOW */
+ klinfo_t xbow_info ;
+ klport_t xbow_port_info[MAX_XBOW_LINKS] ; /* Module number */
+ int xbow_master_hub_link;
+ /* type of brd connected+component struct ptr+flags */
+} klxbow_t ;
+
+#define MAX_PCI_SLOTS 8
+
+typedef struct klpci_device_s {
+ s32 pci_device_id; /* 32 bits of vendor/device ID. */
+ s32 pci_device_pad; /* 32 bits of padding. */
+} klpci_device_t;
+
+#define BRIDGE_STRUCT_VERSION 2
+
+typedef struct klbri_s { /* BRIDGE */
+ klinfo_t bri_info ;
+ unsigned char bri_eprominfo ; /* IO6prom connected to bridge */
+ unsigned char bri_bustype ; /* PCI/VME BUS bridge/GIO */
+ pci_t pci_specific ; /* PCI Board config info */
+ klpci_device_t bri_devices[MAX_PCI_DEVS] ; /* PCI IDs */
+ klconf_off_t bri_mfg_nic ;
+} klbri_t ;
+
+#define MAX_IOC3_TTY 2
+
+typedef struct klioc3_s { /* IOC3 */
+ klinfo_t ioc3_info ;
+ unsigned char ioc3_ssram ; /* Info about ssram */
+ unsigned char ioc3_nvram ; /* Info about nvram */
+ klinfo_t ioc3_superio ; /* Info about superio */
+ klconf_off_t ioc3_tty_off ;
+ klinfo_t ioc3_enet ;
+ klconf_off_t ioc3_enet_off ;
+ klconf_off_t ioc3_kbd_off ;
+} klioc3_t ;
+
+#define MAX_VME_SLOTS 8
+
+typedef struct klvmeb_s { /* VME BRIDGE - PCI CTLR */
+ klinfo_t vmeb_info ;
+ vmeb_t vmeb_specific ;
+ klconf_off_t vmeb_brdinfo[MAX_VME_SLOTS] ; /* VME Board config info */
+} klvmeb_t ;
+
+typedef struct klvmed_s { /* VME DEVICE - VME BOARD */
+ klinfo_t vmed_info ;
+ vmed_t vmed_specific ;
+ klconf_off_t vmed_brdinfo[MAX_VME_SLOTS] ; /* VME Board config info */
+} klvmed_t ;
+
+#define ROUTER_VECTOR_VERS 2
+
+/* XXX - Don't we need the number of ports here?!? */
+typedef struct klrou_s { /* ROUTER */
+ klinfo_t rou_info ;
+ unsigned int rou_flags ; /* PCFG_ROUTER_xxx flags */
+ nic_t rou_box_nic ; /* nic of the containing module */
+ klport_t rou_port[MAX_ROUTER_PORTS + 1] ; /* array index 1 to 6 */
+ klconf_off_t rou_mfg_nic ; /* MFG NIC string */
+ u64 rou_vector; /* vector from master node */
+} klrou_t ;
+
+/*
+ * Graphics Controller/Device
+ *
+ * (IP27/IO6) Prom versions 6.13 (and 6.5.1 kernels) and earlier
+ * used a couple different structures to store graphics information.
+ * For compatibility reasons, the newer data structure preserves some
+ * of the layout so that fields that are used in the old versions remain
+ * in the same place (with the same info). Determination of what version
+ * of this structure we have is done by checking the cookie field.
+ */
+#define KLGFX_COOKIE 0x0c0de000
+
+typedef struct klgfx_s { /* GRAPHICS Device */
+ klinfo_t gfx_info;
+ klconf_off_t old_gndevs; /* for compatibility with older proms */
+ klconf_off_t old_gdoff0; /* for compatibility with older proms */
+ unsigned int cookie; /* for compatibility with older proms */
+ unsigned int moduleslot;
+ struct klgfx_s *gfx_next_pipe;
+ graphics_t gfx_specific;
+ klconf_off_t pad0; /* for compatibility with older proms */
+ klconf_off_t gfx_mfg_nic;
+} klgfx_t;
+
+typedef struct klxthd_s {
+ klinfo_t xthd_info ;
+ klconf_off_t xthd_mfg_nic ; /* MFG NIC string */
+} klxthd_t ;
+
+typedef struct kltpu_s { /* TPU board */
+ klinfo_t tpu_info ;
+ klconf_off_t tpu_mfg_nic ; /* MFG NIC string */
+} kltpu_t ;
+
+typedef struct klgsn_s { /* GSN board */
+ klinfo_t gsn_info ;
+ klconf_off_t gsn_mfg_nic ; /* MFG NIC string */
+} klgsn_t ;
+
+#define MAX_SCSI_DEVS 16
+
+/*
+ * NOTE: THis is the max sized kl* structure and is used in klmalloc.c
+ * to allocate space of type COMPONENT. Make sure that if the size of
+ * any other component struct becomes more than this, then redefine
+ * that as the size to be klmalloced.
+ */
+
+typedef struct klscsi_s { /* SCSI Controller */
+ klinfo_t scsi_info ;
+ scsi_t scsi_specific ;
+ unsigned char scsi_numdevs ;
+ klconf_off_t scsi_devinfo[MAX_SCSI_DEVS] ;
+} klscsi_t ;
+
+typedef struct klscdev_s { /* SCSI device */
+ klinfo_t scdev_info ;
+ struct scsidisk_data *scdev_cfg ; /* driver fills up this */
+} klscdev_t ;
+
+typedef struct klttydev_s { /* TTY device */
+ klinfo_t ttydev_info ;
+ struct terminal_data *ttydev_cfg ; /* driver fills up this */
+} klttydev_t ;
+
+typedef struct klenetdev_s { /* ENET device */
+ klinfo_t enetdev_info ;
+ struct net_data *enetdev_cfg ; /* driver fills up this */
+} klenetdev_t ;
+
+typedef struct klkbddev_s { /* KBD device */
+ klinfo_t kbddev_info ;
+ struct keyboard_data *kbddev_cfg ; /* driver fills up this */
+} klkbddev_t ;
+
+typedef struct klmsdev_s { /* mouse device */
+ klinfo_t msdev_info ;
+ void *msdev_cfg ;
+} klmsdev_t ;
+
+#define MAX_FDDI_DEVS 10 /* XXX Is this true */
+
+typedef struct klfddi_s { /* FDDI */
+ klinfo_t fddi_info ;
+ fddi_t fddi_specific ;
+ klconf_off_t fddi_devinfo[MAX_FDDI_DEVS] ;
+} klfddi_t ;
+
+typedef struct klmio_s { /* MIO */
+ klinfo_t mio_info ;
+ mio_t mio_specific ;
+} klmio_t ;
+
+
+typedef union klcomp_s {
+ klcpu_t kc_cpu;
+ klhub_t kc_hub;
+ klmembnk_t kc_mem;
+ klxbow_t kc_xbow;
+ klbri_t kc_bri;
+ klioc3_t kc_ioc3;
+ klvmeb_t kc_vmeb;
+ klvmed_t kc_vmed;
+ klrou_t kc_rou;
+ klgfx_t kc_gfx;
+ klscsi_t kc_scsi;
+ klscdev_t kc_scsi_dev;
+ klfddi_t kc_fddi;
+ klmio_t kc_mio;
+ klmod_serial_num_t kc_snum ;
+} klcomp_t;
+
+typedef union kldev_s { /* for device structure allocation */
+ klscdev_t kc_scsi_dev ;
+ klttydev_t kc_tty_dev ;
+ klenetdev_t kc_enet_dev ;
+ klkbddev_t kc_kbd_dev ;
+} kldev_t ;
+
+/* Data structure interface routines. TBD */
+
+/* Include launch info in this file itself? TBD */
+
+/*
+ * TBD - Can the ARCS and device driver related info also be included in the
+ * KLCONFIG area. On the IO4PROM, prom device driver info is part of cfgnode_t
+ * structure, viz private to the IO4prom.
+ */
+
+/*
+ * TBD - Allocation issues.
+ *
+ * Do we need to Mark off sepatate heaps for lboard_t, rboard_t, component,
+ * errinfo and allocate from them, or have a single heap and allocate all
+ * structures from it. Debug is easier in the former method since we can
+ * dump all similar structs in one command, but there will be lots of holes,
+ * in memory and max limits are needed for number of structures.
+ * Another way to make it organized, is to have a union of all components
+ * and allocate a aligned chunk of memory greater than the biggest
+ * component.
+ */
+
+typedef union {
+ lboard_t *lbinfo ;
+} biptr_t ;
+
+
+#define BRI_PER_XBOW 6
+#define PCI_PER_BRI 8
+#define DEV_PER_PCI 16
+
+
+/* Virtual dipswitch values (starting from switch "7"): */
+
+#define VDS_NOGFX 0x8000 /* Don't enable gfx and autoboot */
+#define VDS_NOMP 0x100 /* Don't start slave processors */
+#define VDS_MANUMODE 0x80 /* Manufacturing mode */
+#define VDS_NOARB 0x40 /* No bootmaster arbitration */
+#define VDS_PODMODE 0x20 /* Go straight to POD mode */
+#define VDS_NO_DIAGS 0x10 /* Don't run any diags after BM arb */
+#define VDS_DEFAULTS 0x08 /* Use default environment values */
+#define VDS_NOMEMCLEAR 0x04 /* Don't run mem cfg code */
+#define VDS_2ND_IO4 0x02 /* Boot from the second IO4 */
+#define VDS_DEBUG_PROM 0x01 /* Print PROM debugging messages */
+
+/* external declarations of Linux kernel functions. */
+
+extern lboard_t *find_lboard(lboard_t *start, unsigned char type);
+extern klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char type);
+extern klinfo_t *find_first_component(lboard_t *brd, unsigned char type);
+extern klcpu_t *nasid_slice_to_cpuinfo(nasid_t, int);
+extern lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_class);
+
+
+extern klcpu_t *sn_get_cpuinfo(cpuid_t cpu);
+
+#endif /* _ASM_SN_KLCONFIG_H */
diff --git a/arch/mips/include/asm/sn/kldir.h b/arch/mips/include/asm/sn/kldir.h
new file mode 100644
index 00000000..1327e12e
--- /dev/null
+++ b/arch/mips/include/asm/sn/kldir.h
@@ -0,0 +1,217 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/kldir.h>, revision 1.21.
+ *
+ * Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2000 by Ralf Baechle
+ */
+#ifndef _ASM_SN_KLDIR_H
+#define _ASM_SN_KLDIR_H
+
+
+/*
+ * The kldir memory area resides at a fixed place in each node's memory and
+ * provides pointers to most other IP27 memory areas. This allows us to
+ * resize and/or relocate memory areas at a later time without breaking all
+ * firmware and kernels that use them. Indices in the array are
+ * permanently dedicated to areas listed below. Some memory areas (marked
+ * below) reside at a permanently fixed location, but are included in the
+ * directory for completeness.
+ */
+
+#define KLDIR_MAGIC 0x434d5f53505f5357
+
+/*
+ * The upper portion of the memory map applies during boot
+ * only and is overwritten by IRIX/SYMMON.
+ *
+ * MEMORY MAP PER NODE
+ *
+ * 0x2000000 (32M) +-----------------------------------------+
+ * | IO6 BUFFERS FOR FLASH ENET IOC3 |
+ * 0x1F80000 (31.5M) +-----------------------------------------+
+ * | IO6 TEXT/DATA/BSS/stack |
+ * 0x1C00000 (30M) +-----------------------------------------+
+ * | IO6 PROM DEBUG TEXT/DATA/BSS/stack |
+ * 0x0800000 (28M) +-----------------------------------------+
+ * | IP27 PROM TEXT/DATA/BSS/stack |
+ * 0x1B00000 (27M) +-----------------------------------------+
+ * | IP27 CFG |
+ * 0x1A00000 (26M) +-----------------------------------------+
+ * | Graphics PROM |
+ * 0x1800000 (24M) +-----------------------------------------+
+ * | 3rd Party PROM drivers |
+ * 0x1600000 (22M) +-----------------------------------------+
+ * | |
+ * | Free |
+ * | |
+ * +-----------------------------------------+
+ * | UNIX DEBUG Version |
+ * 0x190000 (2M--) +-----------------------------------------+
+ * | SYMMON |
+ * | (For UNIX Debug only) |
+ * 0x34000 (208K) +-----------------------------------------+
+ * | SYMMON STACK [NUM_CPU_PER_NODE] |
+ * | (For UNIX Debug only) |
+ * 0x25000 (148K) +-----------------------------------------+
+ * | KLCONFIG - II (temp) |
+ * | |
+ * | ---------------------------- |
+ * | |
+ * | UNIX NON-DEBUG Version |
+ * 0x19000 (100K) +-----------------------------------------+
+ *
+ *
+ * The lower portion of the memory map contains information that is
+ * permanent and is used by the IP27PROM, IO6PROM and IRIX.
+ *
+ * 0x19000 (100K) +-----------------------------------------+
+ * | |
+ * | PI Error Spools (32K) |
+ * | |
+ * 0x12000 (72K) +-----------------------------------------+
+ * | Unused |
+ * 0x11c00 (71K) +-----------------------------------------+
+ * | CPU 1 NMI Eframe area |
+ * 0x11a00 (70.5K) +-----------------------------------------+
+ * | CPU 0 NMI Eframe area |
+ * 0x11800 (70K) +-----------------------------------------+
+ * | CPU 1 NMI Register save area |
+ * 0x11600 (69.5K) +-----------------------------------------+
+ * | CPU 0 NMI Register save area |
+ * 0x11400 (69K) +-----------------------------------------+
+ * | GDA (1k) |
+ * 0x11000 (68K) +-----------------------------------------+
+ * | Early cache Exception stack |
+ * | and/or |
+ * | kernel/io6prom nmi registers |
+ * 0x10800 (66k) +-----------------------------------------+
+ * | cache error eframe |
+ * 0x10400 (65K) +-----------------------------------------+
+ * | Exception Handlers (UALIAS copy) |
+ * 0x10000 (64K) +-----------------------------------------+
+ * | |
+ * | |
+ * | KLCONFIG - I (permanent) (48K) |
+ * | |
+ * | |
+ * | |
+ * 0x4000 (16K) +-----------------------------------------+
+ * | NMI Handler (Protected Page) |
+ * 0x3000 (12K) +-----------------------------------------+
+ * | ARCS PVECTORS (master node only) |
+ * 0x2c00 (11K) +-----------------------------------------+
+ * | ARCS TVECTORS (master node only) |
+ * 0x2800 (10K) +-----------------------------------------+
+ * | LAUNCH [NUM_CPU] |
+ * 0x2400 (9K) +-----------------------------------------+
+ * | Low memory directory (KLDIR) |
+ * 0x2000 (8K) +-----------------------------------------+
+ * | ARCS SPB (1K) |
+ * 0x1000 (4K) +-----------------------------------------+
+ * | Early cache Exception stack |
+ * | and/or |
+ * | kernel/io6prom nmi registers |
+ * 0x800 (2k) +-----------------------------------------+
+ * | cache error eframe |
+ * 0x400 (1K) +-----------------------------------------+
+ * | Exception Handlers |
+ * 0x0 (0K) +-----------------------------------------+
+ */
+
+#ifdef __ASSEMBLY__
+#define KLDIR_OFF_MAGIC 0x00
+#define KLDIR_OFF_OFFSET 0x08
+#define KLDIR_OFF_POINTER 0x10
+#define KLDIR_OFF_SIZE 0x18
+#define KLDIR_OFF_COUNT 0x20
+#define KLDIR_OFF_STRIDE 0x28
+#endif /* __ASSEMBLY__ */
+
+/*
+ * This is defined here because IP27_SYMMON_STK_SIZE must be at least what
+ * we define here. Since it's set up in the prom. We can't redefine it later
+ * and expect more space to be allocated. The way to find out the true size
+ * of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE
+ * for a particular node.
+ */
+#define SYMMON_STACK_SIZE 0x8000
+
+#if defined(PROM)
+
+/*
+ * These defines are prom version dependent. No code other than the IP27
+ * prom should attempt to use these values.
+ */
+#define IP27_LAUNCH_OFFSET 0x2400
+#define IP27_LAUNCH_SIZE 0x400
+#define IP27_LAUNCH_COUNT 2
+#define IP27_LAUNCH_STRIDE 0x200
+
+#define IP27_KLCONFIG_OFFSET 0x4000
+#define IP27_KLCONFIG_SIZE 0xc000
+#define IP27_KLCONFIG_COUNT 1
+#define IP27_KLCONFIG_STRIDE 0
+
+#define IP27_NMI_OFFSET 0x3000
+#define IP27_NMI_SIZE 0x40
+#define IP27_NMI_COUNT 2
+#define IP27_NMI_STRIDE 0x40
+
+#define IP27_PI_ERROR_OFFSET 0x12000
+#define IP27_PI_ERROR_SIZE 0x4000
+#define IP27_PI_ERROR_COUNT 1
+#define IP27_PI_ERROR_STRIDE 0
+
+#define IP27_SYMMON_STK_OFFSET 0x25000
+#define IP27_SYMMON_STK_SIZE 0xe000
+#define IP27_SYMMON_STK_COUNT 2
+/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */
+#define IP27_SYMMON_STK_STRIDE 0x7000
+
+#define IP27_FREEMEM_OFFSET 0x19000
+#define IP27_FREEMEM_SIZE -1
+#define IP27_FREEMEM_COUNT 1
+#define IP27_FREEMEM_STRIDE 0
+
+#endif /* PROM */
+/*
+ * There will be only one of these in a partition so the IO6 must set it up.
+ */
+#define IO6_GDA_OFFSET 0x11000
+#define IO6_GDA_SIZE 0x400
+#define IO6_GDA_COUNT 1
+#define IO6_GDA_STRIDE 0
+
+/*
+ * save area of kernel nmi regs in the prom format
+ */
+#define IP27_NMI_KREGS_OFFSET 0x11400
+#define IP27_NMI_KREGS_CPU_SIZE 0x200
+/*
+ * save area of kernel nmi regs in eframe format
+ */
+#define IP27_NMI_EFRAME_OFFSET 0x11800
+#define IP27_NMI_EFRAME_SIZE 0x200
+
+#define KLDIR_ENT_SIZE 0x40
+#define KLDIR_MAX_ENTRIES (0x400 / 0x40)
+
+#ifndef __ASSEMBLY__
+typedef struct kldir_ent_s {
+ u64 magic; /* Indicates validity of entry */
+ off_t offset; /* Offset from start of node space */
+ unsigned long pointer; /* Pointer to area in some cases */
+ size_t size; /* Size in bytes */
+ u64 count; /* Repeat count if array, 1 if not */
+ size_t stride; /* Stride if array, 0 if not */
+ char rsvd[16]; /* Pad entry to 0x40 bytes */
+ /* NOTE: These 16 bytes are used in the Partition KLDIR
+ entry to store partition info. Refer to klpart.h for this. */
+} kldir_ent_t;
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_SN_KLDIR_H */
diff --git a/arch/mips/include/asm/sn/klkernvars.h b/arch/mips/include/asm/sn/klkernvars.h
new file mode 100644
index 00000000..6af25ba4
--- /dev/null
+++ b/arch/mips/include/asm/sn/klkernvars.h
@@ -0,0 +1,28 @@
+/*
+ * File ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
+ * Copyright 2000 Silicon Graphics, Inc.
+ */
+#ifndef __ASM_SN_KLKERNVARS_H
+#define __ASM_SN_KLKERNVARS_H
+
+#define KV_MAGIC_OFFSET 0x0
+#define KV_RO_NASID_OFFSET 0x4
+#define KV_RW_NASID_OFFSET 0x6
+
+#define KV_MAGIC 0x5f4b565f
+
+#ifndef __ASSEMBLY__
+
+#include <asm/sn/types.h>
+
+typedef struct kern_vars_s {
+ int kv_magic;
+ nasid_t kv_ro_nasid;
+ nasid_t kv_rw_nasid;
+ unsigned long kv_ro_baseaddr;
+ unsigned long kv_rw_baseaddr;
+} kern_vars_t;
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_SN_KLKERNVARS_H */
diff --git a/arch/mips/include/asm/sn/launch.h b/arch/mips/include/asm/sn/launch.h
new file mode 100644
index 00000000..b7c22263
--- /dev/null
+++ b/arch/mips/include/asm/sn/launch.h
@@ -0,0 +1,106 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2000 by Colin Ngam
+ */
+#ifndef _ASM_SN_LAUNCH_H
+#define _ASM_SN_LAUNCH_H
+
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+
+/*
+ * The launch data structure resides at a fixed place in each node's memory
+ * and is used to communicate between the master processor and the slave
+ * processors.
+ *
+ * The master stores launch parameters in the launch structure
+ * corresponding to a target processor that is in a slave loop, then sends
+ * an interrupt to the slave processor. The slave calls the desired
+ * function, then returns to the slave loop. The master may poll or wait
+ * for the slaves to finish.
+ *
+ * There is an array of launch structures, one per CPU on the node. One
+ * interrupt level is used per local CPU.
+ */
+
+#define LAUNCH_MAGIC 0xaddbead2addbead3
+#ifdef CONFIG_SGI_IP27
+#define LAUNCH_SIZEOF 0x100
+#define LAUNCH_PADSZ 0xa0
+#endif
+
+#define LAUNCH_OFF_MAGIC 0x00 /* Struct offsets for assembly */
+#define LAUNCH_OFF_BUSY 0x08
+#define LAUNCH_OFF_CALL 0x10
+#define LAUNCH_OFF_CALLC 0x18
+#define LAUNCH_OFF_CALLPARM 0x20
+#define LAUNCH_OFF_STACK 0x28
+#define LAUNCH_OFF_GP 0x30
+#define LAUNCH_OFF_BEVUTLB 0x38
+#define LAUNCH_OFF_BEVNORMAL 0x40
+#define LAUNCH_OFF_BEVECC 0x48
+
+#define LAUNCH_STATE_DONE 0 /* Return value of LAUNCH_POLL */
+#define LAUNCH_STATE_SENT 1
+#define LAUNCH_STATE_RECD 2
+
+/*
+ * The launch routine is called only if the complement address is correct.
+ *
+ * Before control is transferred to a routine, the complement address
+ * is zeroed (invalidated) to prevent an accidental call from a spurious
+ * interrupt.
+ *
+ * The slave_launch routine turns on the BUSY flag, and the slave loop
+ * clears the BUSY flag after control is returned to it.
+ */
+
+#ifndef __ASSEMBLY__
+
+typedef int launch_state_t;
+typedef void (*launch_proc_t)(u64 call_parm);
+
+typedef struct launch_s {
+ volatile u64 magic; /* Magic number */
+ volatile u64 busy; /* Slave currently active */
+ volatile launch_proc_t call_addr; /* Func. for slave to call */
+ volatile u64 call_addr_c; /* 1's complement of call_addr*/
+ volatile u64 call_parm; /* Single parm passed to call*/
+ volatile void *stack_addr; /* Stack pointer for slave function */
+ volatile void *gp_addr; /* Global pointer for slave func. */
+ volatile char *bevutlb;/* Address of bev utlb ex handler */
+ volatile char *bevnormal;/*Address of bev normal ex handler */
+ volatile char *bevecc;/* Address of bev cache err handler */
+ volatile char pad[160]; /* Pad to LAUNCH_SIZEOF */
+} launch_t;
+
+/*
+ * PROM entry points for launch routines are determined by IPxxprom/start.s
+ */
+
+#define LAUNCH_SLAVE (*(void (*)(int nasid, int cpu, \
+ launch_proc_t call_addr, \
+ u64 call_parm, \
+ void *stack_addr, \
+ void *gp_addr)) \
+ IP27PROM_LAUNCHSLAVE)
+
+#define LAUNCH_WAIT (*(void (*)(int nasid, int cpu, int timeout_msec)) \
+ IP27PROM_WAITSLAVE)
+
+#define LAUNCH_POLL (*(launch_state_t (*)(int nasid, int cpu)) \
+ IP27PROM_POLLSLAVE)
+
+#define LAUNCH_LOOP (*(void (*)(void)) \
+ IP27PROM_SLAVELOOP)
+
+#define LAUNCH_FLASH (*(void (*)(void)) \
+ IP27PROM_FLASHLEDS)
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_SN_LAUNCH_H */
diff --git a/arch/mips/include/asm/sn/mapped_kernel.h b/arch/mips/include/asm/sn/mapped_kernel.h
new file mode 100644
index 00000000..721496a0
--- /dev/null
+++ b/arch/mips/include/asm/sn/mapped_kernel.h
@@ -0,0 +1,54 @@
+/*
+ * File created by Kanoj Sarcar 06/06/00.
+ * Copyright 2000 Silicon Graphics, Inc.
+ */
+#ifndef __ASM_SN_MAPPED_KERNEL_H
+#define __ASM_SN_MAPPED_KERNEL_H
+
+#include <linux/mmzone.h>
+
+/*
+ * Note on how mapped kernels work: the text and data section is
+ * compiled at cksseg segment (LOADADDR = 0xc001c000), and the
+ * init/setup/data section gets a 16M virtual address bump in the
+ * ld.script file (so that tlblo0 and tlblo1 maps the sections).
+ * The vmlinux.64 section addresses are put in the xkseg range
+ * using the change-addresses makefile option. Use elfdump -of
+ * on IRIX to see where the sections go. The Origin loader loads
+ * the two sections contiguously in physical memory. The loader
+ * sets the entry point into kernel_entry using a xkphys address,
+ * but instead of using 0xa800000001160000, it uses the address
+ * 0xa800000000160000, which is where it physically loaded that
+ * code. So no jumps can be done before we have switched to using
+ * cksseg addresses.
+ */
+#include <asm/addrspace.h>
+
+#define REP_BASE CAC_BASE
+
+#ifdef CONFIG_MAPPED_KERNEL
+
+#define MAPPED_ADDR_RO_TO_PHYS(x) (x - REP_BASE)
+#define MAPPED_ADDR_RW_TO_PHYS(x) (x - REP_BASE - 16777216)
+
+#define MAPPED_KERN_RO_PHYSBASE(n) (hub_data(n)->kern_vars.kv_ro_baseaddr)
+#define MAPPED_KERN_RW_PHYSBASE(n) (hub_data(n)->kern_vars.kv_rw_baseaddr)
+
+#define MAPPED_KERN_RO_TO_PHYS(x) \
+ ((unsigned long)MAPPED_ADDR_RO_TO_PHYS(x) | \
+ MAPPED_KERN_RO_PHYSBASE(get_compact_nodeid()))
+#define MAPPED_KERN_RW_TO_PHYS(x) \
+ ((unsigned long)MAPPED_ADDR_RW_TO_PHYS(x) | \
+ MAPPED_KERN_RW_PHYSBASE(get_compact_nodeid()))
+
+#else /* CONFIG_MAPPED_KERNEL */
+
+#define MAPPED_KERN_RO_TO_PHYS(x) (x - REP_BASE)
+#define MAPPED_KERN_RW_TO_PHYS(x) (x - REP_BASE)
+
+#endif /* CONFIG_MAPPED_KERNEL */
+
+#define MAPPED_KERN_RO_TO_K0(x) PHYS_TO_K0(MAPPED_KERN_RO_TO_PHYS(x))
+#define MAPPED_KERN_RW_TO_K0(x) PHYS_TO_K0(MAPPED_KERN_RW_TO_PHYS(x))
+
+#endif /* __ASM_SN_MAPPED_KERNEL_H */
diff --git a/arch/mips/include/asm/sn/nmi.h b/arch/mips/include/asm/sn/nmi.h
new file mode 100644
index 00000000..1af49897
--- /dev/null
+++ b/arch/mips/include/asm/sn/nmi.h
@@ -0,0 +1,125 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/nmi.h>, Revision 1.5.
+ *
+ * Copyright (C) 1992 - 1997 Silicon Graphics, Inc.
+ */
+#ifndef __ASM_SN_NMI_H
+#define __ASM_SN_NMI_H
+
+#include <asm/sn/addrs.h>
+
+/*
+ * The launch data structure resides at a fixed place in each node's memory
+ * and is used to communicate between the master processor and the slave
+ * processors.
+ *
+ * The master stores launch parameters in the launch structure
+ * corresponding to a target processor that is in a slave loop, then sends
+ * an interrupt to the slave processor. The slave calls the desired
+ * function, followed by an optional rendezvous function, then returns to
+ * the slave loop. The master does not wait for the slaves before
+ * returning.
+ *
+ * There is an array of launch structures, one per CPU on the node. One
+ * interrupt level is used per CPU.
+ */
+
+#define NMI_MAGIC 0x48414d4d455201
+#define NMI_SIZEOF 0x40
+
+#define NMI_OFF_MAGIC 0x00 /* Struct offsets for assembly */
+#define NMI_OFF_FLAGS 0x08
+#define NMI_OFF_CALL 0x10
+#define NMI_OFF_CALLC 0x18
+#define NMI_OFF_CALLPARM 0x20
+#define NMI_OFF_GMASTER 0x28
+
+/*
+ * The NMI routine is called only if the complement address is
+ * correct.
+ *
+ * Before control is transferred to a routine, the complement address
+ * is zeroed (invalidated) to prevent an accidental call from a spurious
+ * interrupt.
+ *
+ */
+
+#ifndef __ASSEMBLY__
+
+typedef struct nmi_s {
+ volatile unsigned long magic; /* Magic number */
+ volatile unsigned long flags; /* Combination of flags above */
+ volatile void *call_addr; /* Routine for slave to call */
+ volatile void *call_addr_c; /* 1's complement of address */
+ volatile void *call_parm; /* Single parm passed to call */
+ volatile unsigned long gmaster; /* Flag true only on global master*/
+} nmi_t;
+
+#endif /* !__ASSEMBLY__ */
+
+/* Following definitions are needed both in the prom & the kernel
+ * to identify the format of the nmi cpu register save area in the
+ * low memory on each node.
+ */
+#ifndef __ASSEMBLY__
+
+struct reg_struct {
+ unsigned long gpr[32];
+ unsigned long sr;
+ unsigned long cause;
+ unsigned long epc;
+ unsigned long badva;
+ unsigned long error_epc;
+ unsigned long cache_err;
+ unsigned long nmi_sr;
+};
+
+#endif /* !__ASSEMBLY__ */
+
+/* These are the assembly language offsets into the reg_struct structure */
+
+#define R0_OFF 0x0
+#define R1_OFF 0x8
+#define R2_OFF 0x10
+#define R3_OFF 0x18
+#define R4_OFF 0x20
+#define R5_OFF 0x28
+#define R6_OFF 0x30
+#define R7_OFF 0x38
+#define R8_OFF 0x40
+#define R9_OFF 0x48
+#define R10_OFF 0x50
+#define R11_OFF 0x58
+#define R12_OFF 0x60
+#define R13_OFF 0x68
+#define R14_OFF 0x70
+#define R15_OFF 0x78
+#define R16_OFF 0x80
+#define R17_OFF 0x88
+#define R18_OFF 0x90
+#define R19_OFF 0x98
+#define R20_OFF 0xa0
+#define R21_OFF 0xa8
+#define R22_OFF 0xb0
+#define R23_OFF 0xb8
+#define R24_OFF 0xc0
+#define R25_OFF 0xc8
+#define R26_OFF 0xd0
+#define R27_OFF 0xd8
+#define R28_OFF 0xe0
+#define R29_OFF 0xe8
+#define R30_OFF 0xf0
+#define R31_OFF 0xf8
+#define SR_OFF 0x100
+#define CAUSE_OFF 0x108
+#define EPC_OFF 0x110
+#define BADVA_OFF 0x118
+#define ERROR_EPC_OFF 0x120
+#define CACHE_ERR_OFF 0x128
+#define NMISR_OFF 0x130
+
+#endif /* __ASM_SN_NMI_H */
diff --git a/arch/mips/include/asm/sn/sn0/addrs.h b/arch/mips/include/asm/sn/sn0/addrs.h
new file mode 100644
index 00000000..b0619009
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn0/addrs.h
@@ -0,0 +1,288 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/addrs.h>, revision 1.126.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_SN0_ADDRS_H
+#define _ASM_SN_SN0_ADDRS_H
+
+
+/*
+ * SN0 (on a T5) Address map
+ *
+ * This file contains a set of definitions and macros which are used
+ * to reference into the major address spaces (CAC, HSPEC, IO, MSPEC,
+ * and UNCAC) used by the SN0 architecture. It also contains addresses
+ * for "major" statically locatable PROM/Kernel data structures, such as
+ * the partition table, the configuration data structure, etc.
+ * We make an implicit assumption that the processor using this file
+ * follows the R10K's provisions for specifying uncached attributes;
+ * should this change, the base registers may very well become processor-
+ * dependent.
+ *
+ * For more information on the address spaces, see the "Local Resources"
+ * chapter of the Hub specification.
+ *
+ * NOTE: This header file is included both by C and by assembler source
+ * files. Please bracket any language-dependent definitions
+ * appropriately.
+ */
+
+/*
+ * Some of the macros here need to be casted to appropriate types when used
+ * from C. They definitely must not be casted from assembly language so we
+ * use some new ANSI preprocessor stuff to paste these on where needed.
+ */
+
+/*
+ * The following couple of definitions will eventually need to be variables,
+ * since the amount of address space assigned to each node depends on
+ * whether the system is running in N-mode (more nodes with less memory)
+ * or M-mode (fewer nodes with more memory). We expect that it will
+ * be a while before we need to make this decision dynamically, though,
+ * so for now we just use defines bracketed by an ifdef.
+ */
+
+#ifdef CONFIG_SGI_SN_N_MODE
+
+#define NODE_SIZE_BITS 31
+#define BWIN_SIZE_BITS 28
+
+#define NASID_BITS 9
+#define NASID_BITMASK (0x1ffLL)
+#define NASID_SHFT 31
+#define NASID_META_BITS 5
+#define NASID_LOCAL_BITS 4
+
+#define BDDIR_UPPER_MASK (UINT64_CAST 0x7ffff << 10)
+#define BDECC_UPPER_MASK (UINT64_CAST 0x3ffffff << 3)
+
+#else /* !defined(CONFIG_SGI_SN_N_MODE), assume that M-mode is desired */
+
+#define NODE_SIZE_BITS 32
+#define BWIN_SIZE_BITS 29
+
+#define NASID_BITMASK (0xffLL)
+#define NASID_BITS 8
+#define NASID_SHFT 32
+#define NASID_META_BITS 4
+#define NASID_LOCAL_BITS 4
+
+#define BDDIR_UPPER_MASK (UINT64_CAST 0xfffff << 10)
+#define BDECC_UPPER_MASK (UINT64_CAST 0x7ffffff << 3)
+
+#endif /* !defined(CONFIG_SGI_SN_N_MODE) */
+
+#define NODE_ADDRSPACE_SIZE (UINT64_CAST 1 << NODE_SIZE_BITS)
+
+#define NASID_MASK (UINT64_CAST NASID_BITMASK << NASID_SHFT)
+#define NASID_GET(_pa) (int) ((UINT64_CAST (_pa) >> \
+ NASID_SHFT) & NASID_BITMASK)
+
+#if !defined(__ASSEMBLY__)
+
+#define NODE_SWIN_BASE(nasid, widget) \
+ ((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN) \
+ : RAW_NODE_SWIN_BASE(nasid, widget))
+#else /* __ASSEMBLY__ */
+#define NODE_SWIN_BASE(nasid, widget) \
+ (NODE_IO_BASE(nasid) + (UINT64_CAST(widget) << SWIN_SIZE_BITS))
+#endif /* __ASSEMBLY__ */
+
+/*
+ * The following definitions pertain to the IO special address
+ * space. They define the location of the big and little windows
+ * of any given node.
+ */
+
+#define BWIN_INDEX_BITS 3
+#define BWIN_SIZE (UINT64_CAST 1 << BWIN_SIZE_BITS)
+#define BWIN_SIZEMASK (BWIN_SIZE - 1)
+#define BWIN_WIDGET_MASK 0x7
+#define NODE_BWIN_BASE0(nasid) (NODE_IO_BASE(nasid) + BWIN_SIZE)
+#define NODE_BWIN_BASE(nasid, bigwin) (NODE_BWIN_BASE0(nasid) + \
+ (UINT64_CAST(bigwin) << BWIN_SIZE_BITS))
+
+#define BWIN_WIDGETADDR(addr) ((addr) & BWIN_SIZEMASK)
+#define BWIN_WINDOWNUM(addr) (((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
+/*
+ * Verify if addr belongs to large window address of node with "nasid"
+ *
+ *
+ * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
+ * address
+ *
+ *
+ */
+
+#define NODE_BWIN_ADDR(nasid, addr) \
+ (((addr) >= NODE_BWIN_BASE0(nasid)) && \
+ ((addr) < (NODE_BWIN_BASE(nasid, HUB_NUM_BIG_WINDOW) + \
+ BWIN_SIZE)))
+
+/*
+ * The following define the major position-independent aliases used
+ * in SN0.
+ * CALIAS -- Varies in size, points to the first n bytes of memory
+ * on the reader's node.
+ */
+
+#define CALIAS_BASE CAC_BASE
+
+
+
+#define BRIDGE_REG_PTR(_base, _off) ((volatile bridgereg_t *) \
+ ((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
+
+#define SN0_WIDGET_BASE(_nasid, _wid) (NODE_SWIN_BASE((_nasid), (_wid)))
+
+/* Turn on sable logging for the processors whose bits are set. */
+#define SABLE_LOG_TRIGGER(_map)
+
+#ifndef __ASSEMBLY__
+#define KERN_NMI_ADDR(nasid, slice) \
+ TO_NODE_UNCAC((nasid), IP27_NMI_KREGS_OFFSET + \
+ (IP27_NMI_KREGS_CPU_SIZE * (slice)))
+#endif /* !__ASSEMBLY__ */
+
+#ifdef PROM
+
+#define MISC_PROM_BASE PHYS_TO_K0(0x01300000)
+#define MISC_PROM_SIZE 0x200000
+
+#define DIAG_BASE PHYS_TO_K0(0x01500000)
+#define DIAG_SIZE 0x300000
+
+#define ROUTE_BASE PHYS_TO_K0(0x01800000)
+#define ROUTE_SIZE 0x200000
+
+#define IP27PROM_FLASH_HDR PHYS_TO_K0(0x01300000)
+#define IP27PROM_FLASH_DATA PHYS_TO_K0(0x01301000)
+#define IP27PROM_CORP_MAX 32
+#define IP27PROM_CORP PHYS_TO_K0(0x01800000)
+#define IP27PROM_CORP_SIZE 0x10000
+#define IP27PROM_CORP_STK PHYS_TO_K0(0x01810000)
+#define IP27PROM_CORP_STKSIZE 0x2000
+#define IP27PROM_DECOMP_BUF PHYS_TO_K0(0x01900000)
+#define IP27PROM_DECOMP_SIZE 0xfff00
+
+#define IP27PROM_BASE PHYS_TO_K0(0x01a00000)
+#define IP27PROM_BASE_MAPPED (UNCAC_BASE | 0x1fc00000)
+#define IP27PROM_SIZE_MAX 0x100000
+
+#define IP27PROM_PCFG PHYS_TO_K0(0x01b00000)
+#define IP27PROM_PCFG_SIZE 0xd0000
+#define IP27PROM_ERRDMP PHYS_TO_K1(0x01bd0000)
+#define IP27PROM_ERRDMP_SIZE 0xf000
+
+#define IP27PROM_INIT_START PHYS_TO_K1(0x01bd0000)
+#define IP27PROM_CONSOLE PHYS_TO_K1(0x01bdf000)
+#define IP27PROM_CONSOLE_SIZE 0x200
+#define IP27PROM_NETUART PHYS_TO_K1(0x01bdf200)
+#define IP27PROM_NETUART_SIZE 0x100
+#define IP27PROM_UNUSED1 PHYS_TO_K1(0x01bdf300)
+#define IP27PROM_UNUSED1_SIZE 0x500
+#define IP27PROM_ELSC_BASE_A PHYS_TO_K0(0x01bdf800)
+#define IP27PROM_ELSC_BASE_B PHYS_TO_K0(0x01bdfc00)
+#define IP27PROM_STACK_A PHYS_TO_K0(0x01be0000)
+#define IP27PROM_STACK_B PHYS_TO_K0(0x01bf0000)
+#define IP27PROM_STACK_SHFT 16
+#define IP27PROM_STACK_SIZE (1 << IP27PROM_STACK_SHFT)
+#define IP27PROM_INIT_END PHYS_TO_K0(0x01c00000)
+
+#define SLAVESTACK_BASE PHYS_TO_K0(0x01580000)
+#define SLAVESTACK_SIZE 0x40000
+
+#define ENETBUFS_BASE PHYS_TO_K0(0x01f80000)
+#define ENETBUFS_SIZE 0x20000
+
+#define IO6PROM_BASE PHYS_TO_K0(0x01c00000)
+#define IO6PROM_SIZE 0x400000
+#define IO6PROM_BASE_MAPPED (UNCAC_BASE | 0x11c00000)
+#define IO6DPROM_BASE PHYS_TO_K0(0x01c00000)
+#define IO6DPROM_SIZE 0x200000
+
+#define NODEBUGUNIX_ADDR PHYS_TO_K0(0x00019000)
+#define DEBUGUNIX_ADDR PHYS_TO_K0(0x00100000)
+
+#define IP27PROM_INT_LAUNCH 10 /* and 11 */
+#define IP27PROM_INT_NETUART 12 /* through 17 */
+
+#endif /* PROM */
+
+/*
+ * needed by symmon so it needs to be outside #if PROM
+ */
+#define IP27PROM_ELSC_SHFT 10
+#define IP27PROM_ELSC_SIZE (1 << IP27PROM_ELSC_SHFT)
+
+/*
+ * This address is used by IO6PROM to build MemoryDescriptors of
+ * free memory. This address is important since unix gets loaded
+ * at this address, and this memory has to be FREE if unix is to
+ * be loaded.
+ */
+
+#define FREEMEM_BASE PHYS_TO_K0(0x2000000)
+
+#define IO6PROM_STACK_SHFT 14 /* stack per cpu */
+#define IO6PROM_STACK_SIZE (1 << IO6PROM_STACK_SHFT)
+
+/*
+ * IP27 PROM vectors
+ */
+
+#define IP27PROM_ENTRY PHYS_TO_COMPATK1(0x1fc00000)
+#define IP27PROM_RESTART PHYS_TO_COMPATK1(0x1fc00008)
+#define IP27PROM_SLAVELOOP PHYS_TO_COMPATK1(0x1fc00010)
+#define IP27PROM_PODMODE PHYS_TO_COMPATK1(0x1fc00018)
+#define IP27PROM_IOC3UARTPOD PHYS_TO_COMPATK1(0x1fc00020)
+#define IP27PROM_FLASHLEDS PHYS_TO_COMPATK1(0x1fc00028)
+#define IP27PROM_REPOD PHYS_TO_COMPATK1(0x1fc00030)
+#define IP27PROM_LAUNCHSLAVE PHYS_TO_COMPATK1(0x1fc00038)
+#define IP27PROM_WAITSLAVE PHYS_TO_COMPATK1(0x1fc00040)
+#define IP27PROM_POLLSLAVE PHYS_TO_COMPATK1(0x1fc00048)
+
+#define KL_UART_BASE LOCAL_HUB_ADDR(MD_UREG0_0) /* base of UART regs */
+#define KL_UART_CMD LOCAL_HUB_ADDR(MD_UREG0_0) /* UART command reg */
+#define KL_UART_DATA LOCAL_HUB_ADDR(MD_UREG0_1) /* UART data reg */
+#define KL_I2C_REG MD_UREG0_0 /* I2C reg */
+
+#ifndef __ASSEMBLY__
+
+/* Address 0x400 to 0x1000 ualias points to cache error eframe + misc
+ * CACHE_ERR_SP_PTR could either contain an address to the stack, or
+ * the stack could start at CACHE_ERR_SP_PTR
+ */
+#if defined(HUB_ERR_STS_WAR)
+#define CACHE_ERR_EFRAME 0x480
+#else /* HUB_ERR_STS_WAR */
+#define CACHE_ERR_EFRAME 0x400
+#endif /* HUB_ERR_STS_WAR */
+
+#define CACHE_ERR_ECCFRAME (CACHE_ERR_EFRAME + EF_SIZE)
+#define CACHE_ERR_SP_PTR (0x1000 - 32) /* why -32? TBD */
+#define CACHE_ERR_IBASE_PTR (0x1000 - 40)
+#define CACHE_ERR_SP (CACHE_ERR_SP_PTR - 16)
+#define CACHE_ERR_AREA_SIZE (ARCS_SPB_OFFSET - CACHE_ERR_EFRAME)
+
+#endif /* !__ASSEMBLY__ */
+
+#define _ARCSPROM
+
+#if defined(HUB_ERR_STS_WAR)
+
+#define ERR_STS_WAR_REGISTER IIO_IIBUSERR
+#define ERR_STS_WAR_ADDR LOCAL_HUB_ADDR(IIO_IIBUSERR)
+#define ERR_STS_WAR_PHYSADDR TO_PHYS((__psunsigned_t)ERR_STS_WAR_ADDR)
+ /* Used to match addr in error reg. */
+#define OLD_ERR_STS_WAR_OFFSET ((MD_MEM_BANKS * MD_BANK_SIZE) - 0x100)
+
+#endif /* HUB_ERR_STS_WAR */
+
+#endif /* _ASM_SN_SN0_ADDRS_H */
diff --git a/arch/mips/include/asm/sn/sn0/arch.h b/arch/mips/include/asm/sn/sn0/arch.h
new file mode 100644
index 00000000..f734f200
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn0/arch.h
@@ -0,0 +1,72 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI IP27 specific setup.
+ *
+ * Copyright (C) 1995 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_SN_SN0_ARCH_H
+#define _ASM_SN_SN0_ARCH_H
+
+
+#ifndef SN0XXL /* 128 cpu SMP max */
+/*
+ * This is the maximum number of nodes that can be part of a kernel.
+ * Effectively, it's the maximum number of compact node ids (cnodeid_t).
+ */
+#define MAX_COMPACT_NODES 64
+
+/*
+ * MAXCPUS refers to the maximum number of CPUs in a single kernel.
+ * This is not necessarily the same as MAXNODES * CPUS_PER_NODE
+ */
+#define MAXCPUS 128
+
+#else /* SN0XXL system */
+
+#define MAX_COMPACT_NODES 128
+#define MAXCPUS 256
+
+#endif /* SN0XXL */
+
+/*
+ * This is the maximum number of NASIDS that can be present in a system.
+ * (Highest NASID plus one.)
+ */
+#define MAX_NASIDS 256
+
+/*
+ * MAX_REGIONS refers to the maximum number of hardware partitioned regions.
+ */
+#define MAX_REGIONS 64
+#define MAX_NONPREMIUM_REGIONS 16
+#define MAX_PREMIUM_REGIONS MAX_REGIONS
+
+/*
+ * MAX_PARITIONS refers to the maximum number of logically defined
+ * partitions the system can support.
+ */
+#define MAX_PARTITIONS MAX_REGIONS
+
+#define NASID_MASK_BYTES ((MAX_NASIDS + 7) / 8)
+
+/*
+ * Slot constants for SN0
+ */
+#ifdef CONFIG_SGI_SN_N_MODE
+#define MAX_MEM_SLOTS 16 /* max slots per node */
+#else /* !CONFIG_SGI_SN_N_MODE, assume CONFIG_SGI_SN_M_MODE */
+#define MAX_MEM_SLOTS 32 /* max slots per node */
+#endif /* CONFIG_SGI_SN_M_MODE */
+
+#define SLOT_SHIFT (27)
+#define SLOT_MIN_MEM_SIZE (32*1024*1024)
+
+#define CPUS_PER_NODE 2 /* CPUs on a single hub */
+#define CPUS_PER_NODE_SHFT 1 /* Bits to shift in the node number */
+#define CPUS_PER_SUBNODE 2 /* CPUs on a single hub PI */
+
+#endif /* _ASM_SN_SN0_ARCH_H */
diff --git a/arch/mips/include/asm/sn/sn0/hub.h b/arch/mips/include/asm/sn/sn0/hub.h
new file mode 100644
index 00000000..3e228f8e
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn0/hub.h
@@ -0,0 +1,40 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_SN0_HUB_H
+#define _ASM_SN_SN0_HUB_H
+
+/* The secret password; used to release protection */
+#define HUB_PASSWORD 0x53474972756c6573ull
+
+#define CHIPID_HUB 0
+#define CHIPID_ROUTER 1
+
+#define HUB_REV_1_0 1
+#define HUB_REV_2_0 2
+#define HUB_REV_2_1 3
+#define HUB_REV_2_2 4
+#define HUB_REV_2_3 5
+#define HUB_REV_2_4 6
+
+#define MAX_HUB_PATH 80
+
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubpi.h>
+#include <asm/sn/sn0/hubmd.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/sn0/hubni.h>
+//#include <asm/sn/sn0/hubcore.h>
+
+/* Translation of uncached attributes */
+#define UATTR_HSPEC 0
+#define UATTR_IO 1
+#define UATTR_MSPEC 2
+#define UATTR_UNCAC 3
+
+#endif /* _ASM_SN_SN0_HUB_H */
diff --git a/arch/mips/include/asm/sn/sn0/hubio.h b/arch/mips/include/asm/sn/sn0/hubio.h
new file mode 100644
index 00000000..46286d83
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn0/hubio.h
@@ -0,0 +1,972 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/hubio.h>, Revision 1.80.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SGI_SN_SN0_HUBIO_H
+#define _ASM_SGI_SN_SN0_HUBIO_H
+
+/*
+ * Hub I/O interface registers
+ *
+ * All registers in this file are subject to change until Hub chip tapeout.
+ * In general, the longer software name should be used when available.
+ */
+
+/*
+ * Slightly friendlier names for some common registers.
+ * The hardware definitions follow.
+ */
+#define IIO_WIDGET IIO_WID /* Widget identification */
+#define IIO_WIDGET_STAT IIO_WSTAT /* Widget status register */
+#define IIO_WIDGET_CTRL IIO_WCR /* Widget control register */
+#define IIO_WIDGET_TOUT IIO_WRTO /* Widget request timeout */
+#define IIO_WIDGET_FLUSH IIO_WTFR /* Widget target flush */
+#define IIO_PROTECT IIO_ILAPR /* IO interface protection */
+#define IIO_PROTECT_OVRRD IIO_ILAPO /* IO protect override */
+#define IIO_OUTWIDGET_ACCESS IIO_IOWA /* Outbound widget access */
+#define IIO_INWIDGET_ACCESS IIO_IIWA /* Inbound widget access */
+#define IIO_INDEV_ERR_MASK IIO_IIDEM /* Inbound device error mask */
+#define IIO_LLP_CSR IIO_ILCSR /* LLP control and status */
+#define IIO_LLP_LOG IIO_ILLR /* LLP log */
+#define IIO_XTALKCC_TOUT IIO_IXCC /* Xtalk credit count timeout*/
+#define IIO_XTALKTT_TOUT IIO_IXTT /* Xtalk tail timeout */
+#define IIO_IO_ERR_CLR IIO_IECLR /* IO error clear */
+#define IIO_BTE_CRB_CNT IIO_IBCN /* IO BTE CRB count */
+
+#define IIO_LLP_CSR_IS_UP 0x00002000
+#define IIO_LLP_CSR_LLP_STAT_MASK 0x00003000
+#define IIO_LLP_CSR_LLP_STAT_SHFT 12
+
+/* key to IIO_PROTECT_OVRRD */
+#define IIO_PROTECT_OVRRD_KEY 0x53474972756c6573ull /* "SGIrules" */
+
+/* BTE register names */
+#define IIO_BTE_STAT_0 IIO_IBLS_0 /* Also BTE length/status 0 */
+#define IIO_BTE_SRC_0 IIO_IBSA_0 /* Also BTE source address 0 */
+#define IIO_BTE_DEST_0 IIO_IBDA_0 /* Also BTE dest. address 0 */
+#define IIO_BTE_CTRL_0 IIO_IBCT_0 /* Also BTE control/terminate 0 */
+#define IIO_BTE_NOTIFY_0 IIO_IBNA_0 /* Also BTE notification 0 */
+#define IIO_BTE_INT_0 IIO_IBIA_0 /* Also BTE interrupt 0 */
+#define IIO_BTE_OFF_0 0 /* Base offset from BTE 0 regs. */
+#define IIO_BTE_OFF_1 IIO_IBLS_1 - IIO_IBLS_0 /* Offset from base to BTE 1 */
+
+/* BTE register offsets from base */
+#define BTEOFF_STAT 0
+#define BTEOFF_SRC (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
+#define BTEOFF_DEST (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
+#define BTEOFF_CTRL (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
+#define BTEOFF_NOTIFY (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
+#define BTEOFF_INT (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
+
+
+/*
+ * The following definitions use the names defined in the IO interface
+ * document for ease of reference. When possible, software should
+ * generally use the longer but clearer names defined above.
+ */
+
+#define IIO_BASE 0x400000
+#define IIO_BASE_BTE0 0x410000
+#define IIO_BASE_BTE1 0x420000
+#define IIO_BASE_PERF 0x430000
+#define IIO_PERF_CNT 0x430008
+
+#define IO_PERF_SETS 32
+
+#define IIO_WID 0x400000 /* Widget identification */
+#define IIO_WSTAT 0x400008 /* Widget status */
+#define IIO_WCR 0x400020 /* Widget control */
+
+#define IIO_WSTAT_ECRAZY (1ULL << 32) /* Hub gone crazy */
+#define IIO_WSTAT_TXRETRY (1ULL << 9) /* Hub Tx Retry timeout */
+#define IIO_WSTAT_TXRETRY_MASK (0x7F)
+#define IIO_WSTAT_TXRETRY_SHFT (16)
+#define IIO_WSTAT_TXRETRY_CNT(w) (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
+ IIO_WSTAT_TXRETRY_MASK)
+
+#define IIO_ILAPR 0x400100 /* Local Access Protection */
+#define IIO_ILAPO 0x400108 /* Protection override */
+#define IIO_IOWA 0x400110 /* outbound widget access */
+#define IIO_IIWA 0x400118 /* inbound widget access */
+#define IIO_IIDEM 0x400120 /* Inbound Device Error Mask */
+#define IIO_ILCSR 0x400128 /* LLP control and status */
+#define IIO_ILLR 0x400130 /* LLP Log */
+#define IIO_IIDSR 0x400138 /* Interrupt destination */
+
+#define IIO_IIBUSERR 0x1400208 /* Reads here cause a bus error. */
+
+/* IO Interrupt Destination Register */
+#define IIO_IIDSR_SENT_SHIFT 28
+#define IIO_IIDSR_SENT_MASK 0x10000000
+#define IIO_IIDSR_ENB_SHIFT 24
+#define IIO_IIDSR_ENB_MASK 0x01000000
+#define IIO_IIDSR_NODE_SHIFT 8
+#define IIO_IIDSR_NODE_MASK 0x0000ff00
+#define IIO_IIDSR_LVL_SHIFT 0
+#define IIO_IIDSR_LVL_MASK 0x0000003f
+
+
+/* GFX Flow Control Node/Widget Register */
+#define IIO_IGFX_0 0x400140 /* gfx node/widget register 0 */
+#define IIO_IGFX_1 0x400148 /* gfx node/widget register 1 */
+#define IIO_IGFX_W_NUM_BITS 4 /* size of widget num field */
+#define IIO_IGFX_W_NUM_MASK ((1<<IIO_IGFX_W_NUM_BITS)-1)
+#define IIO_IGFX_W_NUM_SHIFT 0
+#define IIO_IGFX_N_NUM_BITS 9 /* size of node num field */
+#define IIO_IGFX_N_NUM_MASK ((1<<IIO_IGFX_N_NUM_BITS)-1)
+#define IIO_IGFX_N_NUM_SHIFT 4
+#define IIO_IGFX_P_NUM_BITS 1 /* size of processor num field */
+#define IIO_IGFX_P_NUM_MASK ((1<<IIO_IGFX_P_NUM_BITS)-1)
+#define IIO_IGFX_P_NUM_SHIFT 16
+#define IIO_IGFX_VLD_BITS 1 /* size of valid field */
+#define IIO_IGFX_VLD_MASK ((1<<IIO_IGFX_VLD_BITS)-1)
+#define IIO_IGFX_VLD_SHIFT 20
+#define IIO_IGFX_INIT(widget, node, cpu, valid) (\
+ (((widget) & IIO_IGFX_W_NUM_MASK) << IIO_IGFX_W_NUM_SHIFT) | \
+ (((node) & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) | \
+ (((cpu) & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT) | \
+ (((valid) & IIO_IGFX_VLD_MASK) << IIO_IGFX_VLD_SHIFT) )
+
+/* Scratch registers (not all bits available) */
+#define IIO_SCRATCH_REG0 0x400150
+#define IIO_SCRATCH_REG1 0x400158
+#define IIO_SCRATCH_MASK 0x0000000f00f11fff
+
+#define IIO_SCRATCH_BIT0_0 0x0000000800000000
+#define IIO_SCRATCH_BIT0_1 0x0000000400000000
+#define IIO_SCRATCH_BIT0_2 0x0000000200000000
+#define IIO_SCRATCH_BIT0_3 0x0000000100000000
+#define IIO_SCRATCH_BIT0_4 0x0000000000800000
+#define IIO_SCRATCH_BIT0_5 0x0000000000400000
+#define IIO_SCRATCH_BIT0_6 0x0000000000200000
+#define IIO_SCRATCH_BIT0_7 0x0000000000100000
+#define IIO_SCRATCH_BIT0_8 0x0000000000010000
+#define IIO_SCRATCH_BIT0_9 0x0000000000001000
+#define IIO_SCRATCH_BIT0_R 0x0000000000000fff
+
+/* IO Translation Table Entries */
+#define IIO_NUM_ITTES 7 /* ITTEs numbered 0..6 */
+ /* Hw manuals number them 1..7! */
+
+/*
+ * As a permanent workaround for a bug in the PI side of the hub, we've
+ * redefined big window 7 as small window 0.
+ */
+#define HUB_NUM_BIG_WINDOW IIO_NUM_ITTES - 1
+
+/*
+ * Use the top big window as a surrogate for the first small window
+ */
+#define SWIN0_BIGWIN HUB_NUM_BIG_WINDOW
+
+#define ILCSR_WARM_RESET 0x100
+/*
+ * The IO LLP control status register and widget control register
+ */
+#ifndef __ASSEMBLY__
+
+typedef union hubii_wid_u {
+ u64 wid_reg_value;
+ struct {
+ u64 wid_rsvd: 32, /* unused */
+ wid_rev_num: 4, /* revision number */
+ wid_part_num: 16, /* the widget type: hub=c101 */
+ wid_mfg_num: 11, /* Manufacturer id (IBM) */
+ wid_rsvd1: 1; /* Reserved */
+ } wid_fields_s;
+} hubii_wid_t;
+
+
+typedef union hubii_wcr_u {
+ u64 wcr_reg_value;
+ struct {
+ u64 wcr_rsvd: 41, /* unused */
+ wcr_e_thresh: 5, /* elasticity threshold */
+ wcr_dir_con: 1, /* widget direct connect */
+ wcr_f_bad_pkt: 1, /* Force bad llp pkt enable */
+ wcr_xbar_crd: 3, /* LLP crossbar credit */
+ wcr_rsvd1: 8, /* Reserved */
+ wcr_tag_mode: 1, /* Tag mode */
+ wcr_widget_id: 4; /* LLP crossbar credit */
+ } wcr_fields_s;
+} hubii_wcr_t;
+
+#define iwcr_dir_con wcr_fields_s.wcr_dir_con
+
+typedef union hubii_wstat_u {
+ u64 reg_value;
+ struct {
+ u64 rsvd1: 31,
+ crazy: 1, /* Crazy bit */
+ rsvd2: 8,
+ llp_tx_cnt: 8, /* LLP Xmit retry counter */
+ rsvd3: 6,
+ tx_max_rtry: 1, /* LLP Retry Timeout Signal */
+ rsvd4: 2,
+ xt_tail_to: 1, /* Xtalk Tail Timeout */
+ xt_crd_to: 1, /* Xtalk Credit Timeout */
+ pending: 4; /* Pending Requests */
+ } wstat_fields_s;
+} hubii_wstat_t;
+
+
+typedef union hubii_ilcsr_u {
+ u64 icsr_reg_value;
+ struct {
+ u64 icsr_rsvd: 22, /* unused */
+ icsr_max_burst: 10, /* max burst */
+ icsr_rsvd4: 6, /* reserved */
+ icsr_max_retry: 10, /* max retry */
+ icsr_rsvd3: 2, /* reserved */
+ icsr_lnk_stat: 2, /* link status */
+ icsr_bm8: 1, /* Bit mode 8 */
+ icsr_llp_en: 1, /* LLP enable bit */
+ icsr_rsvd2: 1, /* reserver */
+ icsr_wrm_reset: 1, /* Warm reset bit */
+ icsr_rsvd1: 2, /* Data ready offset */
+ icsr_null_to: 6; /* Null timeout */
+
+ } icsr_fields_s;
+} hubii_ilcsr_t;
+
+
+typedef union hubii_iowa_u {
+ u64 iowa_reg_value;
+ struct {
+ u64 iowa_rsvd: 48, /* unused */
+ iowa_wxoac: 8, /* xtalk widget access bits */
+ iowa_rsvd1: 7, /* xtalk widget access bits */
+ iowa_w0oac: 1; /* xtalk widget access bits */
+ } iowa_fields_s;
+} hubii_iowa_t;
+
+typedef union hubii_iiwa_u {
+ u64 iiwa_reg_value;
+ struct {
+ u64 iiwa_rsvd: 48, /* unused */
+ iiwa_wxiac: 8, /* hub wid access bits */
+ iiwa_rsvd1: 7, /* reserved */
+ iiwa_w0iac: 1; /* hub wid0 access */
+ } iiwa_fields_s;
+} hubii_iiwa_t;
+
+typedef union hubii_illr_u {
+ u64 illr_reg_value;
+ struct {
+ u64 illr_rsvd: 32, /* unused */
+ illr_cb_cnt: 16, /* checkbit error count */
+ illr_sn_cnt: 16; /* sequence number count */
+ } illr_fields_s;
+} hubii_illr_t;
+
+/* The structures below are defined to extract and modify the ii
+performance registers */
+
+/* io_perf_sel allows the caller to specify what tests will be
+ performed */
+typedef union io_perf_sel {
+ u64 perf_sel_reg;
+ struct {
+ u64 perf_rsvd : 48,
+ perf_icct : 8,
+ perf_ippr1 : 4,
+ perf_ippr0 : 4;
+ } perf_sel_bits;
+} io_perf_sel_t;
+
+/* io_perf_cnt is to extract the count from the hub registers. Due to
+ hardware problems there is only one counter, not two. */
+
+typedef union io_perf_cnt {
+ u64 perf_cnt;
+ struct {
+ u64 perf_rsvd1 : 32,
+ perf_rsvd2 : 12,
+ perf_cnt : 20;
+ } perf_cnt_bits;
+} io_perf_cnt_t;
+
+#endif /* !__ASSEMBLY__ */
+
+
+#define LNK_STAT_WORKING 0x2
+
+#define IIO_LLP_CB_MAX 0xffff
+#define IIO_LLP_SN_MAX 0xffff
+
+/* IO PRB Entries */
+#define IIO_NUM_IPRBS (9)
+#define IIO_IOPRB_0 0x400198 /* PRB entry 0 */
+#define IIO_IOPRB_8 0x4001a0 /* PRB entry 8 */
+#define IIO_IOPRB_9 0x4001a8 /* PRB entry 9 */
+#define IIO_IOPRB_A 0x4001b0 /* PRB entry a */
+#define IIO_IOPRB_B 0x4001b8 /* PRB entry b */
+#define IIO_IOPRB_C 0x4001c0 /* PRB entry c */
+#define IIO_IOPRB_D 0x4001c8 /* PRB entry d */
+#define IIO_IOPRB_E 0x4001d0 /* PRB entry e */
+#define IIO_IOPRB_F 0x4001d8 /* PRB entry f */
+
+
+#define IIO_IXCC 0x4001e0 /* Crosstalk credit count timeout */
+#define IIO_IXTCC IIO_IXCC
+#define IIO_IMEM 0x4001e8 /* Miscellaneous Enable Mask */
+#define IIO_IXTT 0x4001f0 /* Crosstalk tail timeout */
+#define IIO_IECLR 0x4001f8 /* IO error clear */
+#define IIO_IBCN 0x400200 /* IO BTE CRB count */
+
+/*
+ * IIO_IMEM Register fields.
+ */
+#define IIO_IMEM_W0ESD 0x1 /* Widget 0 shut down due to error */
+#define IIO_IMEM_B0ESD (1 << 4) /* BTE 0 shut down due to error */
+#define IIO_IMEM_B1ESD (1 << 8) /* BTE 1 Shut down due to error */
+
+/* PIO Read address Table Entries */
+#define IIO_IPCA 0x400300 /* PRB Counter adjust */
+#define IIO_NUM_PRTES 8 /* Total number of PRB table entries */
+#define IIO_PRTE_0 0x400308 /* PIO Read address table entry 0 */
+#define IIO_PRTE(_x) (IIO_PRTE_0 + (8 * (_x)))
+#define IIO_WIDPRTE(x) IIO_PRTE(((x) - 8)) /* widget ID to its PRTE num */
+#define IIO_IPDR 0x400388 /* PIO table entry deallocation */
+#define IIO_ICDR 0x400390 /* CRB Entry Deallocation */
+#define IIO_IFDR 0x400398 /* IOQ FIFO Depth */
+#define IIO_IIAP 0x4003a0 /* IIQ Arbitration Parameters */
+#define IIO_IMMR IIO_IIAP
+#define IIO_ICMR 0x4003a8 /* CRB Management Register */
+#define IIO_ICCR 0x4003b0 /* CRB Control Register */
+#define IIO_ICTO 0x4003b8 /* CRB Time Out Register */
+#define IIO_ICTP 0x4003c0 /* CRB Time Out Prescalar */
+
+
+/*
+ * ICMR register fields
+ */
+#define IIO_ICMR_PC_VLD_SHFT 36
+#define IIO_ICMR_PC_VLD_MASK (0x7fffUL << IIO_ICMR_PC_VLD_SHFT)
+
+#define IIO_ICMR_CRB_VLD_SHFT 20
+#define IIO_ICMR_CRB_VLD_MASK (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
+
+#define IIO_ICMR_FC_CNT_SHFT 16
+#define IIO_ICMR_FC_CNT_MASK (0xf << IIO_ICMR_FC_CNT_SHFT)
+
+#define IIO_ICMR_C_CNT_SHFT 4
+#define IIO_ICMR_C_CNT_MASK (0xf << IIO_ICMR_C_CNT_SHFT)
+
+#define IIO_ICMR_P_CNT_SHFT 0
+#define IIO_ICMR_P_CNT_MASK (0xf << IIO_ICMR_P_CNT_SHFT)
+
+#define IIO_ICMR_PRECISE (1UL << 52)
+#define IIO_ICMR_CLR_RPPD (1UL << 13)
+#define IIO_ICMR_CLR_RQPD (1UL << 12)
+
+/*
+ * IIO PIO Deallocation register field masks : (IIO_IPDR)
+ */
+#define IIO_IPDR_PND (1 << 4)
+
+/*
+ * IIO CRB deallocation register field masks: (IIO_ICDR)
+ */
+#define IIO_ICDR_PND (1 << 4)
+
+/*
+ * IIO CRB control register Fields: IIO_ICCR
+ */
+#define IIO_ICCR_PENDING (0x10000)
+#define IIO_ICCR_CMD_MASK (0xFF)
+#define IIO_ICCR_CMD_SHFT (7)
+#define IIO_ICCR_CMD_NOP (0x0) /* No Op */
+#define IIO_ICCR_CMD_WAKE (0x100) /* Reactivate CRB entry and process */
+#define IIO_ICCR_CMD_TIMEOUT (0x200) /* Make CRB timeout & mark invalid */
+#define IIO_ICCR_CMD_EJECT (0x400) /* Contents of entry written to memory
+ * via a WB
+ */
+#define IIO_ICCR_CMD_FLUSH (0x800)
+
+/*
+ * CRB manipulation macros
+ * The CRB macros are slightly complicated, since there are up to
+ * four registers associated with each CRB entry.
+ */
+#define IIO_NUM_CRBS 15 /* Number of CRBs */
+#define IIO_NUM_NORMAL_CRBS 12 /* Number of regular CRB entries */
+#define IIO_NUM_PC_CRBS 4 /* Number of partial cache CRBs */
+#define IIO_ICRB_OFFSET 8
+#define IIO_ICRB_0 0x400400
+/* XXX - This is now tuneable:
+ #define IIO_FIRST_PC_ENTRY 12
+ */
+
+#define IIO_ICRB_A(_x) (IIO_ICRB_0 + (4 * IIO_ICRB_OFFSET * (_x)))
+#define IIO_ICRB_B(_x) (IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET)
+#define IIO_ICRB_C(_x) (IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET)
+#define IIO_ICRB_D(_x) (IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET)
+
+/* XXX - IBUE register coming for Hub 2 */
+
+/*
+ *
+ * CRB Register description.
+ *
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
+ *
+ * Many of the fields in CRB are status bits used by hardware
+ * for implementation of the protocol. It's very dangerous to
+ * mess around with the CRB registers.
+ *
+ * It's OK to read the CRB registers and try to make sense out of the
+ * fields in CRB.
+ *
+ * Updating CRB requires all activities in Hub IIO to be quiesced.
+ * otherwise, a write to CRB could corrupt other CRB entries.
+ * CRBs are here only as a back door peek to hub IIO's status.
+ * Quiescing implies no dmas no PIOs
+ * either directly from the cpu or from sn0net.
+ * this is not something that can be done easily. So, AVOID updating
+ * CRBs.
+ */
+
+/*
+ * Fields in CRB Register A
+ */
+#ifndef __ASSEMBLY__
+typedef union icrba_u {
+ u64 reg_value;
+ struct {
+ u64 resvd: 6,
+ stall_bte0: 1, /* Stall BTE 0 */
+ stall_bte1: 1, /* Stall BTE 1 */
+ error: 1, /* CRB has an error */
+ ecode: 3, /* Error Code */
+ lnetuce: 1, /* SN0net Uncorrectable error */
+ mark: 1, /* CRB Has been marked */
+ xerr: 1, /* Error bit set in xtalk header */
+ sidn: 4, /* SIDN field from xtalk */
+ tnum: 5, /* TNUM field in xtalk */
+ addr: 38, /* Address of request */
+ valid: 1, /* Valid status */
+ iow: 1; /* IO Write operation */
+ } icrba_fields_s;
+} icrba_t;
+
+/* This is an alternate typedef for the HUB1 CRB A in order to allow
+ runtime selection of the format based on the REV_ID field of the
+ NI_STATUS_REV_ID register. */
+typedef union h1_icrba_u {
+ u64 reg_value;
+
+ struct {
+ u64 resvd: 6,
+ unused: 1, /* Unused but RW!! */
+ error: 1, /* CRB has an error */
+ ecode: 4, /* Error Code */
+ lnetuce: 1, /* SN0net Uncorrectable error */
+ mark: 1, /* CRB Has been marked */
+ xerr: 1, /* Error bit set in xtalk header */
+ sidn: 4, /* SIDN field from xtalk */
+ tnum: 5, /* TNUM field in xtalk */
+ addr: 38, /* Address of request */
+ valid: 1, /* Valid status */
+ iow: 1; /* IO Write operation */
+ } h1_icrba_fields_s;
+} h1_icrba_t;
+
+/* XXX - Is this still right? Check the spec. */
+#define ICRBN_A_CERR_SHFT 54
+#define ICRBN_A_ERR_MASK 0x3ff
+
+#endif /* !__ASSEMBLY__ */
+
+#define IIO_ICRB_ADDR_SHFT 2 /* Shift to get proper address */
+
+/*
+ * values for "ecode" field
+ */
+#define IIO_ICRB_ECODE_DERR 0 /* Directory error due to IIO access */
+#define IIO_ICRB_ECODE_PERR 1 /* Poison error on IO access */
+#define IIO_ICRB_ECODE_WERR 2 /* Write error by IIO access
+ * e.g. WINV to a Read only line.
+ */
+#define IIO_ICRB_ECODE_AERR 3 /* Access error caused by IIO access */
+#define IIO_ICRB_ECODE_PWERR 4 /* Error on partial write */
+#define IIO_ICRB_ECODE_PRERR 5 /* Error on partial read */
+#define IIO_ICRB_ECODE_TOUT 6 /* CRB timeout before deallocating */
+#define IIO_ICRB_ECODE_XTERR 7 /* Incoming xtalk pkt had error bit */
+
+
+
+/*
+ * Fields in CRB Register B
+ */
+#ifndef __ASSEMBLY__
+typedef union icrbb_u {
+ u64 reg_value;
+ struct {
+ u64 rsvd1: 5,
+ btenum: 1, /* BTE to which entry belongs to */
+ cohtrans: 1, /* Coherent transaction */
+ xtsize: 2, /* Xtalk operation size
+ * 0: Double Word
+ * 1: 32 Bytes.
+ * 2: 128 Bytes,
+ * 3: Reserved.
+ */
+ srcnode: 9, /* Source Node ID */
+ srcinit: 2, /* Source Initiator:
+ * See below for field values.
+ */
+ useold: 1, /* Use OLD command for processing */
+ imsgtype: 2, /* Incoming message type
+ * see below for field values
+ */
+ imsg: 8, /* Incoming message */
+ initator: 3, /* Initiator of original request
+ * See below for field values.
+ */
+ reqtype: 5, /* Identifies type of request
+ * See below for field values.
+ */
+ rsvd2: 7,
+ ackcnt: 11, /* Invalidate ack count */
+ resp: 1, /* data response given to processor */
+ ack: 1, /* indicates data ack received */
+ hold: 1, /* entry is gathering inval acks */
+ wb_pend:1, /* waiting for writeback to complete */
+ intvn: 1, /* Intervention */
+ stall_ib: 1, /* Stall Ibuf (from crosstalk) */
+ stall_intr: 1; /* Stall internal interrupts */
+ } icrbb_field_s;
+} icrbb_t;
+
+/* This is an alternate typedef for the HUB1 CRB B in order to allow
+ runtime selection of the format based on the REV_ID field of the
+ NI_STATUS_REV_ID register. */
+typedef union h1_icrbb_u {
+ u64 reg_value;
+ struct {
+ u64 rsvd1: 5,
+ btenum: 1, /* BTE to which entry belongs to */
+ cohtrans: 1, /* Coherent transaction */
+ xtsize: 2, /* Xtalk operation size
+ * 0: Double Word
+ * 1: 32 Bytes.
+ * 2: 128 Bytes,
+ * 3: Reserved.
+ */
+ srcnode: 9, /* Source Node ID */
+ srcinit: 2, /* Source Initiator:
+ * See below for field values.
+ */
+ useold: 1, /* Use OLD command for processing */
+ imsgtype: 2, /* Incoming message type
+ * see below for field values
+ */
+ imsg: 8, /* Incoming message */
+ initator: 3, /* Initiator of original request
+ * See below for field values.
+ */
+ rsvd2: 1,
+ pcache: 1, /* entry belongs to partial cache */
+ reqtype: 5, /* Identifies type of request
+ * See below for field values.
+ */
+ stl_ib: 1, /* stall Ibus coming from xtalk */
+ stl_intr: 1, /* Stall internal interrupts */
+ stl_bte0: 1, /* Stall BTE 0 */
+ stl_bte1: 1, /* Stall BTE 1 */
+ intrvn: 1, /* Req was target of intervention */
+ ackcnt: 11, /* Invalidate ack count */
+ resp: 1, /* data response given to processor */
+ ack: 1, /* indicates data ack received */
+ hold: 1, /* entry is gathering inval acks */
+ wb_pend:1, /* waiting for writeback to complete */
+ sleep: 1, /* xtalk req sleeping till IO-sync */
+ pnd_reply: 1, /* replies not issed due to IOQ full */
+ pnd_req: 1; /* reqs not issued due to IOQ full */
+ } h1_icrbb_field_s;
+} h1_icrbb_t;
+
+
+#define b_imsgtype icrbb_field_s.imsgtype
+#define b_btenum icrbb_field_s.btenum
+#define b_cohtrans icrbb_field_s.cohtrans
+#define b_xtsize icrbb_field_s.xtsize
+#define b_srcnode icrbb_field_s.srcnode
+#define b_srcinit icrbb_field_s.srcinit
+#define b_imsgtype icrbb_field_s.imsgtype
+#define b_imsg icrbb_field_s.imsg
+#define b_initiator icrbb_field_s.initiator
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * values for field xtsize
+ */
+#define IIO_ICRB_XTSIZE_DW 0 /* Xtalk operation size is 8 bytes */
+#define IIO_ICRB_XTSIZE_32 1 /* Xtalk operation size is 32 bytes */
+#define IIO_ICRB_XTSIZE_128 2 /* Xtalk operation size is 128 bytes */
+
+/*
+ * values for field srcinit
+ */
+#define IIO_ICRB_PROC0 0 /* Source of request is Proc 0 */
+#define IIO_ICRB_PROC1 1 /* Source of request is Proc 1 */
+#define IIO_ICRB_GB_REQ 2 /* Source is Guaranteed BW request */
+#define IIO_ICRB_IO_REQ 3 /* Source is Normal IO request */
+
+/*
+ * Values for field imsgtype
+ */
+#define IIO_ICRB_IMSGT_XTALK 0 /* Incoming Meessage from Xtalk */
+#define IIO_ICRB_IMSGT_BTE 1 /* Incoming message from BTE */
+#define IIO_ICRB_IMSGT_SN0NET 2 /* Incoming message from SN0 net */
+#define IIO_ICRB_IMSGT_CRB 3 /* Incoming message from CRB ??? */
+
+/*
+ * values for field initiator.
+ */
+#define IIO_ICRB_INIT_XTALK 0 /* Message originated in xtalk */
+#define IIO_ICRB_INIT_BTE0 0x1 /* Message originated in BTE 0 */
+#define IIO_ICRB_INIT_SN0NET 0x2 /* Message originated in SN0net */
+#define IIO_ICRB_INIT_CRB 0x3 /* Message originated in CRB ? */
+#define IIO_ICRB_INIT_BTE1 0x5 /* MEssage originated in BTE 1 */
+
+/*
+ * Values for field reqtype.
+ */
+/* XXX - Need to fix this for Hub 2 */
+#define IIO_ICRB_REQ_DWRD 0 /* Request type double word */
+#define IIO_ICRB_REQ_QCLRD 1 /* Request is Qrtr Caceh line Rd */
+#define IIO_ICRB_REQ_BLKRD 2 /* Request is block read */
+#define IIO_ICRB_REQ_RSHU 6 /* Request is BTE block read */
+#define IIO_ICRB_REQ_REXU 7 /* request is BTE Excl Read */
+#define IIO_ICRB_REQ_RDEX 8 /* Request is Read Exclusive */
+#define IIO_ICRB_REQ_WINC 9 /* Request is Write Invalidate */
+#define IIO_ICRB_REQ_BWINV 10 /* Request is BTE Winv */
+#define IIO_ICRB_REQ_PIORD 11 /* Request is PIO read */
+#define IIO_ICRB_REQ_PIOWR 12 /* Request is PIO Write */
+#define IIO_ICRB_REQ_PRDM 13 /* Request is Fetch&Op */
+#define IIO_ICRB_REQ_PWRM 14 /* Request is Store &Op */
+#define IIO_ICRB_REQ_PTPWR 15 /* Request is Peer to peer */
+#define IIO_ICRB_REQ_WB 16 /* Request is Write back */
+#define IIO_ICRB_REQ_DEX 17 /* Retained DEX Cache line */
+
+/*
+ * Fields in CRB Register C
+ */
+
+#ifndef __ASSEMBLY__
+
+typedef union icrbc_s {
+ u64 reg_value;
+ struct {
+ u64 rsvd: 6,
+ sleep: 1,
+ pricnt: 4, /* Priority count sent with Read req */
+ pripsc: 4, /* Priority Pre scalar */
+ bteop: 1, /* BTE Operation */
+ push_be: 34, /* Push address Byte enable
+ * Holds push addr, if CRB is for BTE
+ * If CRB belongs to Partial cache,
+ * this contains byte enables bits
+ * ([47:46] = 0)
+ */
+ suppl: 11, /* Supplemental field */
+ barrop: 1, /* Barrier Op bit set in xtalk req */
+ doresp: 1, /* Xtalk req needs a response */
+ gbr: 1; /* GBR bit set in xtalk packet */
+ } icrbc_field_s;
+} icrbc_t;
+
+#define c_pricnt icrbc_field_s.pricnt
+#define c_pripsc icrbc_field_s.pripsc
+#define c_bteop icrbc_field_s.bteop
+#define c_bteaddr icrbc_field_s.push_be /* push_be field has 2 names */
+#define c_benable icrbc_field_s.push_be /* push_be field has 2 names */
+#define c_suppl icrbc_field_s.suppl
+#define c_barrop icrbc_field_s.barrop
+#define c_doresp icrbc_field_s.doresp
+#define c_gbr icrbc_field_s.gbr
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * Fields in CRB Register D
+ */
+
+#ifndef __ASSEMBLY__
+typedef union icrbd_s {
+ u64 reg_value;
+ struct {
+ u64 rsvd: 38,
+ toutvld: 1, /* Timeout in progress for this CRB */
+ ctxtvld: 1, /* Context field below is valid */
+ rsvd2: 1,
+ context: 15, /* Bit vector:
+ * Has a bit set for each CRB entry
+ * which needs to be deallocated
+ * before this CRB entry is processed.
+ * Set only for barrier operations.
+ */
+ timeout: 8; /* Timeout Upper 8 bits */
+ } icrbd_field_s;
+} icrbd_t;
+
+#define icrbd_toutvld icrbd_field_s.toutvld
+#define icrbd_ctxtvld icrbd_field_s.ctxtvld
+#define icrbd_context icrbd_field_s.context
+
+
+typedef union hubii_ifdr_u {
+ u64 hi_ifdr_value;
+ struct {
+ u64 ifdr_rsvd: 49,
+ ifdr_maxrp: 7,
+ ifdr_rsvd1: 1,
+ ifdr_maxrq: 7;
+ } hi_ifdr_fields;
+} hubii_ifdr_t;
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * Hardware designed names for the BTE control registers.
+ */
+#define IIO_IBLS_0 0x410000 /* BTE length/status 0 */
+#define IIO_IBSA_0 0x410008 /* BTE source address 0 */
+#define IIO_IBDA_0 0x410010 /* BTE destination address 0 */
+#define IIO_IBCT_0 0x410018 /* BTE control/terminate 0 */
+#define IIO_IBNA_0 0x410020 /* BTE notification address 0 */
+#define IIO_IBNR_0 IIO_IBNA_0
+#define IIO_IBIA_0 0x410028 /* BTE interrupt address 0 */
+
+#define IIO_IBLS_1 0x420000 /* BTE length/status 1 */
+#define IIO_IBSA_1 0x420008 /* BTE source address 1 */
+#define IIO_IBDA_1 0x420010 /* BTE destination address 1 */
+#define IIO_IBCT_1 0x420018 /* BTE control/terminate 1 */
+#define IIO_IBNA_1 0x420020 /* BTE notification address 1 */
+#define IIO_IBNR_1 IIO_IBNA_1
+#define IIO_IBIA_1 0x420028 /* BTE interrupt address 1 */
+
+/*
+ * More miscellaneous registers
+ */
+#define IIO_IPCR 0x430000 /* Performance Control */
+#define IIO_IPPR 0x430008 /* Performance Profiling */
+
+/*
+ * IO Error Clear register bit field definitions
+ */
+#define IECLR_BTE1 (1 << 18) /* clear bte error 1 ??? */
+#define IECLR_BTE0 (1 << 17) /* clear bte error 0 ??? */
+#define IECLR_CRAZY (1 << 16) /* clear crazy bit in wstat reg */
+#define IECLR_PRB_F (1 << 15) /* clear err bit in PRB_F reg */
+#define IECLR_PRB_E (1 << 14) /* clear err bit in PRB_E reg */
+#define IECLR_PRB_D (1 << 13) /* clear err bit in PRB_D reg */
+#define IECLR_PRB_C (1 << 12) /* clear err bit in PRB_C reg */
+#define IECLR_PRB_B (1 << 11) /* clear err bit in PRB_B reg */
+#define IECLR_PRB_A (1 << 10) /* clear err bit in PRB_A reg */
+#define IECLR_PRB_9 (1 << 9) /* clear err bit in PRB_9 reg */
+#define IECLR_PRB_8 (1 << 8) /* clear err bit in PRB_8 reg */
+#define IECLR_PRB_0 (1 << 0) /* clear err bit in PRB_0 reg */
+
+/*
+ * IO PIO Read Table Entry format
+ */
+
+#ifndef __ASSEMBLY__
+
+typedef union iprte_a {
+ u64 entry;
+ struct {
+ u64 rsvd1 : 7, /* Reserved field */
+ valid : 1, /* Maps to a timeout entry */
+ rsvd2 : 1,
+ srcnode : 9, /* Node which did this PIO */
+ initiator : 2, /* If T5A or T5B or IO */
+ rsvd3 : 3,
+ addr : 38, /* Physical address of PIO */
+ rsvd4 : 3;
+ } iprte_fields;
+} iprte_a_t;
+
+#define iprte_valid iprte_fields.valid
+#define iprte_timeout iprte_fields.timeout
+#define iprte_srcnode iprte_fields.srcnode
+#define iprte_init iprte_fields.initiator
+#define iprte_addr iprte_fields.addr
+
+#endif /* !__ASSEMBLY__ */
+
+#define IPRTE_ADDRSHFT 3
+
+/*
+ * Hub IIO PRB Register format.
+ */
+
+#ifndef __ASSEMBLY__
+/*
+ * Note: Fields bnakctr, anakctr, xtalkctrmode, ovflow fields are
+ * "Status" fields, and should only be used in case of clean up after errors.
+ */
+
+typedef union iprb_u {
+ u64 reg_value;
+ struct {
+ u64 rsvd1: 15,
+ error: 1, /* Widget rcvd wr resp pkt w/ error */
+ ovflow: 5, /* Overflow count. perf measurement */
+ fire_and_forget: 1, /* Launch Write without response */
+ mode: 2, /* Widget operation Mode */
+ rsvd2: 2,
+ bnakctr: 14,
+ rsvd3: 2,
+ anakctr: 14,
+ xtalkctr: 8;
+ } iprb_fields_s;
+} iprb_t;
+
+#define iprb_regval reg_value
+
+#define iprb_error iprb_fields_s.error
+#define iprb_ovflow iprb_fields_s.ovflow
+#define iprb_ff iprb_fields_s.fire_and_forget
+#define iprb_mode iprb_fields_s.mode
+#define iprb_bnakctr iprb_fields_s.bnakctr
+#define iprb_anakctr iprb_fields_s.anakctr
+#define iprb_xtalkctr iprb_fields_s.xtalkctr
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * values for mode field in iprb_t.
+ * For details of the meanings of NAK and Accept, refer the PIO flow
+ * document
+ */
+#define IPRB_MODE_NORMAL (0)
+#define IPRB_MODE_COLLECT_A (1) /* PRB in collect A mode */
+#define IPRB_MODE_SERVICE_A (2) /* NAK B and Accept A */
+#define IPRB_MODE_SERVICE_B (3) /* NAK A and Accept B */
+
+/*
+ * IO CRB entry C_A to E_A : Partial (cache) CRBS
+ */
+#ifndef __ASSEMBLY__
+typedef union icrbp_a {
+ u64 ip_reg; /* the entire register value */
+ struct {
+ u64 error: 1, /* 63, error occurred */
+ ln_uce: 1, /* 62: uncorrectable memory */
+ ln_ae: 1, /* 61: protection violation */
+ ln_werr:1, /* 60: write access error */
+ ln_aerr:1, /* 59: sn0net: Address error */
+ ln_perr:1, /* 58: sn0net: poison error */
+ timeout:1, /* 57: CRB timed out */
+ l_bdpkt:1, /* 56: truncated pkt on sn0net */
+ c_bdpkt:1, /* 55: truncated pkt on xtalk */
+ c_err: 1, /* 54: incoming xtalk req, err set*/
+ rsvd1: 12, /* 53-42: reserved */
+ valid: 1, /* 41: Valid status */
+ sidn: 4, /* 40-37: SIDN field of xtalk rqst */
+ tnum: 5, /* 36-32: TNUM of xtalk request */
+ bo: 1, /* 31: barrier op set in xtalk rqst*/
+ resprqd:1, /* 30: xtalk rqst requires response*/
+ gbr: 1, /* 29: gbr bit set in xtalk rqst */
+ size: 2, /* 28-27: size of xtalk request */
+ excl: 4, /* 26-23: exclusive bit(s) */
+ stall: 3, /* 22-20: stall (xtalk, bte 0/1) */
+ intvn: 1, /* 19: rqst target of intervention*/
+ resp: 1, /* 18: Data response given to t5 */
+ ack: 1, /* 17: Data ack received. */
+ hold: 1, /* 16: crb gathering invalidate acks*/
+ wb: 1, /* 15: writeback pending. */
+ ack_cnt:11, /* 14-04: counter of invalidate acks*/
+ tscaler:4; /* 03-00: Timeout prescaler */
+ } ip_fmt;
+} icrbp_a_t;
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * A couple of defines to go with the above structure.
+ */
+#define ICRBP_A_CERR_SHFT 54
+#define ICRBP_A_ERR_MASK 0x3ff
+
+#ifndef __ASSEMBLY__
+typedef union hubii_idsr {
+ u64 iin_reg;
+ struct {
+ u64 rsvd1 : 35,
+ isent : 1,
+ rsvd2 : 3,
+ ienable: 1,
+ rsvd : 7,
+ node : 9,
+ rsvd4 : 1,
+ level : 7;
+ } iin_fmt;
+} hubii_idsr_t;
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * IO BTE Length/Status (IIO_IBLS) register bit field definitions
+ */
+#define IBLS_BUSY (0x1 << 20)
+#define IBLS_ERROR_SHFT 16
+#define IBLS_ERROR (0x1 << IBLS_ERROR_SHFT)
+#define IBLS_LENGTH_MASK 0xffff
+
+/*
+ * IO BTE Control/Terminate register (IBCT) register bit field definitions
+ */
+#define IBCT_POISON (0x1 << 8)
+#define IBCT_NOTIFY (0x1 << 4)
+#define IBCT_ZFIL_MODE (0x1 << 0)
+
+/*
+ * IO BTE Interrupt Address Register (IBIA) register bit field definitions
+ */
+#define IBIA_LEVEL_SHFT 16
+#define IBIA_LEVEL_MASK (0x7f << IBIA_LEVEL_SHFT)
+#define IBIA_NODE_ID_SHFT 0
+#define IBIA_NODE_ID_MASK (0x1ff)
+
+/*
+ * Miscellaneous hub constants
+ */
+
+/* Number of widgets supported by hub */
+#define HUB_NUM_WIDGET 9
+#define HUB_WIDGET_ID_MIN 0x8
+#define HUB_WIDGET_ID_MAX 0xf
+
+#define HUB_WIDGET_PART_NUM 0xc101
+#define MAX_HUBS_PER_XBOW 2
+
+/*
+ * Get a hub's widget id from widget control register
+ */
+#define IIO_WCR_WID_GET(nasid) (REMOTE_HUB_L(nasid, III_WCR) & 0xf)
+#define IIO_WST_ERROR_MASK (UINT64_CAST 1 << 32) /* Widget status error */
+
+/*
+ * Number of credits Hub widget has while sending req/response to
+ * xbow.
+ * Value of 3 is required by Xbow 1.1
+ * We may be able to increase this to 4 with Xbow 1.2.
+ */
+#define HUBII_XBOW_CREDIT 3
+#define HUBII_XBOW_REV2_CREDIT 4
+
+#endif /* _ASM_SGI_SN_SN0_HUBIO_H */
diff --git a/arch/mips/include/asm/sn/sn0/hubmd.h b/arch/mips/include/asm/sn/sn0/hubmd.h
new file mode 100644
index 00000000..14c225d8
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn0/hubmd.h
@@ -0,0 +1,789 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/hubmd.h>, revision 1.59.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_SN0_HUBMD_H
+#define _ASM_SN_SN0_HUBMD_H
+
+
+/*
+ * Hub Memory/Directory interface registers
+ */
+#define CACHE_SLINE_SIZE 128 /* Secondary cache line size on SN0 */
+
+#define MAX_REGIONS 64
+
+/* Hardware page size and shift */
+
+#define MD_PAGE_SIZE 4096 /* Page size in bytes */
+#define MD_PAGE_NUM_SHFT 12 /* Address to page number shift */
+
+/* Register offsets from LOCAL_HUB or REMOTE_HUB */
+
+#define MD_BASE 0x200000
+#define MD_BASE_PERF 0x210000
+#define MD_BASE_JUNK 0x220000
+
+#define MD_IO_PROTECT 0x200000 /* MD and core register protection */
+#define MD_IO_PROT_OVRRD 0x200008 /* Clear my bit in MD_IO_PROTECT */
+#define MD_HSPEC_PROTECT 0x200010 /* BDDIR, LBOOT, RBOOT protection */
+#define MD_MEMORY_CONFIG 0x200018 /* Memory/Directory DIMM control */
+#define MD_REFRESH_CONTROL 0x200020 /* Memory/Directory refresh ctrl */
+#define MD_FANDOP_CAC_STAT 0x200028 /* Fetch-and-op cache status */
+#define MD_MIG_DIFF_THRESH 0x200030 /* Page migr. count diff thresh. */
+#define MD_MIG_VALUE_THRESH 0x200038 /* Page migr. count abs. thresh. */
+#define MD_MIG_CANDIDATE 0x200040 /* Latest page migration candidate */
+#define MD_MIG_CANDIDATE_CLR 0x200048 /* Clear page migration candidate */
+#define MD_DIR_ERROR 0x200050 /* Directory DIMM error */
+#define MD_DIR_ERROR_CLR 0x200058 /* Directory DIMM error clear */
+#define MD_PROTOCOL_ERROR 0x200060 /* Directory protocol error */
+#define MD_PROTOCOL_ERROR_CLR 0x200068 /* Directory protocol error clear */
+#define MD_MEM_ERROR 0x200070 /* Memory DIMM error */
+#define MD_MEM_ERROR_CLR 0x200078 /* Memory DIMM error clear */
+#define MD_MISC_ERROR 0x200080 /* Miscellaneous MD error */
+#define MD_MISC_ERROR_CLR 0x200088 /* Miscellaneous MD error clear */
+#define MD_MEM_DIMM_INIT 0x200090 /* Memory DIMM mode initization. */
+#define MD_DIR_DIMM_INIT 0x200098 /* Directory DIMM mode init. */
+#define MD_MOQ_SIZE 0x2000a0 /* MD outgoing queue size */
+#define MD_MLAN_CTL 0x2000a8 /* NIC (Microlan) control register */
+
+#define MD_PERF_SEL 0x210000 /* Select perf monitor events */
+#define MD_PERF_CNT0 0x210010 /* Performance counter 0 */
+#define MD_PERF_CNT1 0x210018 /* Performance counter 1 */
+#define MD_PERF_CNT2 0x210020 /* Performance counter 2 */
+#define MD_PERF_CNT3 0x210028 /* Performance counter 3 */
+#define MD_PERF_CNT4 0x210030 /* Performance counter 4 */
+#define MD_PERF_CNT5 0x210038 /* Performance counter 5 */
+
+#define MD_UREG0_0 0x220000 /* uController/UART 0 register */
+#define MD_UREG0_1 0x220008 /* uController/UART 0 register */
+#define MD_UREG0_2 0x220010 /* uController/UART 0 register */
+#define MD_UREG0_3 0x220018 /* uController/UART 0 register */
+#define MD_UREG0_4 0x220020 /* uController/UART 0 register */
+#define MD_UREG0_5 0x220028 /* uController/UART 0 register */
+#define MD_UREG0_6 0x220030 /* uController/UART 0 register */
+#define MD_UREG0_7 0x220038 /* uController/UART 0 register */
+
+#define MD_SLOTID_USTAT 0x220048 /* Hub slot ID & UART/uCtlr status */
+#define MD_LED0 0x220050 /* Eight-bit LED for CPU A */
+#define MD_LED1 0x220058 /* Eight-bit LED for CPU B */
+
+#define MD_UREG1_0 0x220080 /* uController/UART 1 register */
+#define MD_UREG1_1 0x220088 /* uController/UART 1 register */
+#define MD_UREG1_2 0x220090 /* uController/UART 1 register */
+#define MD_UREG1_3 0x220098 /* uController/UART 1 register */
+#define MD_UREG1_4 0x2200a0 /* uController/UART 1 register */
+#define MD_UREG1_5 0x2200a8 /* uController/UART 1 register */
+#define MD_UREG1_6 0x2200b0 /* uController/UART 1 register */
+#define MD_UREG1_7 0x2200b8 /* uController/UART 1 register */
+#define MD_UREG1_8 0x2200c0 /* uController/UART 1 register */
+#define MD_UREG1_9 0x2200c8 /* uController/UART 1 register */
+#define MD_UREG1_10 0x2200d0 /* uController/UART 1 register */
+#define MD_UREG1_11 0x2200d8 /* uController/UART 1 register */
+#define MD_UREG1_12 0x2200e0 /* uController/UART 1 register */
+#define MD_UREG1_13 0x2200e8 /* uController/UART 1 register */
+#define MD_UREG1_14 0x2200f0 /* uController/UART 1 register */
+#define MD_UREG1_15 0x2200f8 /* uController/UART 1 register */
+
+#ifdef CONFIG_SGI_SN_N_MODE
+#define MD_MEM_BANKS 4 /* 4 banks of memory max in N mode */
+#else
+#define MD_MEM_BANKS 8 /* 8 banks of memory max in M mode */
+#endif
+
+/*
+ * MD_MEMORY_CONFIG fields
+ *
+ * MD_SIZE_xxx are useful for representing the size of a SIMM or bank
+ * (SIMM pair). They correspond to the values needed for the bit
+ * triplets (MMC_BANK_MASK) in the MD_MEMORY_CONFIG register for bank size.
+ * Bits not used by the MD are used by software.
+ */
+
+#define MD_SIZE_EMPTY 0 /* Valid in MEMORY_CONFIG */
+#define MD_SIZE_8MB 1
+#define MD_SIZE_16MB 2
+#define MD_SIZE_32MB 3 /* Broken in Hub 1 */
+#define MD_SIZE_64MB 4 /* Valid in MEMORY_CONFIG */
+#define MD_SIZE_128MB 5 /* Valid in MEMORY_CONFIG */
+#define MD_SIZE_256MB 6
+#define MD_SIZE_512MB 7 /* Valid in MEMORY_CONFIG */
+#define MD_SIZE_1GB 8
+#define MD_SIZE_2GB 9
+#define MD_SIZE_4GB 10
+
+#define MD_SIZE_BYTES(size) ((size) == 0 ? 0 : 0x400000L << (size))
+#define MD_SIZE_MBYTES(size) ((size) == 0 ? 0 : 4 << (size))
+
+#define MMC_FPROM_CYC_SHFT 49 /* Have to use UINT64_CAST, instead */
+#define MMC_FPROM_CYC_MASK (UINT64_CAST 31 << 49) /* of 'L' suffix, */
+#define MMC_FPROM_WR_SHFT 44 /* for assembler */
+#define MMC_FPROM_WR_MASK (UINT64_CAST 31 << 44)
+#define MMC_UCTLR_CYC_SHFT 39
+#define MMC_UCTLR_CYC_MASK (UINT64_CAST 31 << 39)
+#define MMC_UCTLR_WR_SHFT 34
+#define MMC_UCTLR_WR_MASK (UINT64_CAST 31 << 34)
+#define MMC_DIMM0_SEL_SHFT 32
+#define MMC_DIMM0_SEL_MASK (UINT64_CAST 3 << 32)
+#define MMC_IO_PROT_EN_SHFT 31
+#define MMC_IO_PROT_EN_MASK (UINT64_CAST 1 << 31)
+#define MMC_IO_PROT (UINT64_CAST 1 << 31)
+#define MMC_ARB_MLSS_SHFT 30
+#define MMC_ARB_MLSS_MASK (UINT64_CAST 1 << 30)
+#define MMC_ARB_MLSS (UINT64_CAST 1 << 30)
+#define MMC_IGNORE_ECC_SHFT 29
+#define MMC_IGNORE_ECC_MASK (UINT64_CAST 1 << 29)
+#define MMC_IGNORE_ECC (UINT64_CAST 1 << 29)
+#define MMC_DIR_PREMIUM_SHFT 28
+#define MMC_DIR_PREMIUM_MASK (UINT64_CAST 1 << 28)
+#define MMC_DIR_PREMIUM (UINT64_CAST 1 << 28)
+#define MMC_REPLY_GUAR_SHFT 24
+#define MMC_REPLY_GUAR_MASK (UINT64_CAST 15 << 24)
+#define MMC_BANK_SHFT(_b) ((_b) * 3)
+#define MMC_BANK_MASK(_b) (UINT64_CAST 7 << MMC_BANK_SHFT(_b))
+#define MMC_BANK_ALL_MASK 0xffffff
+#define MMC_RESET_DEFAULTS (UINT64_CAST 0x0f << MMC_FPROM_CYC_SHFT | \
+ UINT64_CAST 0x07 << MMC_FPROM_WR_SHFT | \
+ UINT64_CAST 0x1f << MMC_UCTLR_CYC_SHFT | \
+ UINT64_CAST 0x0f << MMC_UCTLR_WR_SHFT | \
+ MMC_IGNORE_ECC | MMC_DIR_PREMIUM | \
+ UINT64_CAST 0x0f << MMC_REPLY_GUAR_SHFT | \
+ MMC_BANK_ALL_MASK)
+
+/* MD_REFRESH_CONTROL fields */
+
+#define MRC_ENABLE_SHFT 63
+#define MRC_ENABLE_MASK (UINT64_CAST 1 << 63)
+#define MRC_ENABLE (UINT64_CAST 1 << 63)
+#define MRC_COUNTER_SHFT 12
+#define MRC_COUNTER_MASK (UINT64_CAST 0xfff << 12)
+#define MRC_CNT_THRESH_MASK 0xfff
+#define MRC_RESET_DEFAULTS (UINT64_CAST 0x400)
+
+/* MD_MEM_DIMM_INIT and MD_DIR_DIMM_INIT fields */
+
+#define MDI_SELECT_SHFT 32
+#define MDI_SELECT_MASK (UINT64_CAST 0x0f << 32)
+#define MDI_DIMM_MODE_MASK (UINT64_CAST 0xfff)
+
+/* MD_MOQ_SIZE fields */
+
+#define MMS_RP_SIZE_SHFT 8
+#define MMS_RP_SIZE_MASK (UINT64_CAST 0x3f << 8)
+#define MMS_RQ_SIZE_SHFT 0
+#define MMS_RQ_SIZE_MASK (UINT64_CAST 0x1f)
+#define MMS_RESET_DEFAULTS (0x32 << 8 | 0x12)
+
+/* MD_FANDOP_CAC_STAT fields */
+
+#define MFC_VALID_SHFT 63
+#define MFC_VALID_MASK (UINT64_CAST 1 << 63)
+#define MFC_VALID (UINT64_CAST 1 << 63)
+#define MFC_ADDR_SHFT 6
+#define MFC_ADDR_MASK (UINT64_CAST 0x3ffffff)
+
+/* MD_MLAN_CTL fields */
+
+#define MLAN_PHI1_SHFT 27
+#define MLAN_PHI1_MASK (UINT64_CAST 0x7f << 27)
+#define MLAN_PHI0_SHFT 20
+#define MLAN_PHI0_MASK (UINT64_CAST 0x7f << 27)
+#define MLAN_PULSE_SHFT 10
+#define MLAN_PULSE_MASK (UINT64_CAST 0x3ff << 10)
+#define MLAN_SAMPLE_SHFT 2
+#define MLAN_SAMPLE_MASK (UINT64_CAST 0xff << 2)
+#define MLAN_DONE_SHFT 1
+#define MLAN_DONE_MASK 2
+#define MLAN_DONE (UINT64_CAST 0x02)
+#define MLAN_RD_DATA (UINT64_CAST 0x01)
+#define MLAN_RESET_DEFAULTS (UINT64_CAST 0x31 << MLAN_PHI1_SHFT | \
+ UINT64_CAST 0x31 << MLAN_PHI0_SHFT)
+
+/* MD_SLOTID_USTAT bit definitions */
+
+#define MSU_CORECLK_TST_SHFT 7 /* You don't wanna know */
+#define MSU_CORECLK_TST_MASK (UINT64_CAST 1 << 7)
+#define MSU_CORECLK_TST (UINT64_CAST 1 << 7)
+#define MSU_CORECLK_SHFT 6 /* You don't wanna know */
+#define MSU_CORECLK_MASK (UINT64_CAST 1 << 6)
+#define MSU_CORECLK (UINT64_CAST 1 << 6)
+#define MSU_NETSYNC_SHFT 5 /* You don't wanna know */
+#define MSU_NETSYNC_MASK (UINT64_CAST 1 << 5)
+#define MSU_NETSYNC (UINT64_CAST 1 << 5)
+#define MSU_FPROMRDY_SHFT 4 /* Flash PROM ready bit */
+#define MSU_FPROMRDY_MASK (UINT64_CAST 1 << 4)
+#define MSU_FPROMRDY (UINT64_CAST 1 << 4)
+#define MSU_I2CINTR_SHFT 3 /* I2C interrupt bit */
+#define MSU_I2CINTR_MASK (UINT64_CAST 1 << 3)
+#define MSU_I2CINTR (UINT64_CAST 1 << 3)
+#define MSU_SLOTID_MASK 0xff
+#define MSU_SN0_SLOTID_SHFT 0 /* Slot ID */
+#define MSU_SN0_SLOTID_MASK (UINT64_CAST 7)
+#define MSU_SN00_SLOTID_SHFT 7
+#define MSU_SN00_SLOTID_MASK (UINT64_CAST 0x80)
+
+#define MSU_PIMM_PSC_SHFT 4
+#define MSU_PIMM_PSC_MASK (0xf << MSU_PIMM_PSC_SHFT)
+
+/* MD_MIG_DIFF_THRESH bit definitions */
+
+#define MD_MIG_DIFF_THRES_VALID_MASK (UINT64_CAST 0x1 << 63)
+#define MD_MIG_DIFF_THRES_VALID_SHFT 63
+#define MD_MIG_DIFF_THRES_VALUE_MASK (UINT64_CAST 0xfffff)
+
+/* MD_MIG_VALUE_THRESH bit definitions */
+
+#define MD_MIG_VALUE_THRES_VALID_MASK (UINT64_CAST 0x1 << 63)
+#define MD_MIG_VALUE_THRES_VALID_SHFT 63
+#define MD_MIG_VALUE_THRES_VALUE_MASK (UINT64_CAST 0xfffff)
+
+/* MD_MIG_CANDIDATE bit definitions */
+
+#define MD_MIG_CANDIDATE_VALID_MASK (UINT64_CAST 0x1 << 63)
+#define MD_MIG_CANDIDATE_VALID_SHFT 63
+#define MD_MIG_CANDIDATE_TYPE_MASK (UINT64_CAST 0x1 << 30)
+#define MD_MIG_CANDIDATE_TYPE_SHFT 30
+#define MD_MIG_CANDIDATE_OVERRUN_MASK (UINT64_CAST 0x1 << 29)
+#define MD_MIG_CANDIDATE_OVERRUN_SHFT 29
+#define MD_MIG_CANDIDATE_INITIATOR_MASK (UINT64_CAST 0x7ff << 18)
+#define MD_MIG_CANDIDATE_INITIATOR_SHFT 18
+#define MD_MIG_CANDIDATE_NODEID_MASK (UINT64_CAST 0x1ff << 20)
+#define MD_MIG_CANDIDATE_NODEID_SHFT 20
+#define MD_MIG_CANDIDATE_ADDR_MASK (UINT64_CAST 0x3ffff)
+#define MD_MIG_CANDIDATE_ADDR_SHFT 14 /* The address starts at bit 14 */
+
+/* Other MD definitions */
+
+#define MD_BANK_SHFT 29 /* log2(512 MB) */
+#define MD_BANK_MASK (UINT64_CAST 7 << 29)
+#define MD_BANK_SIZE (UINT64_CAST 1 << MD_BANK_SHFT) /* 512 MB */
+#define MD_BANK_OFFSET(_b) (UINT64_CAST (_b) << MD_BANK_SHFT)
+
+/*
+ * The following definitions cover the bit field definitions for the
+ * various MD registers. For multi-bit registers, we define both
+ * a shift amount and a mask value. By convention, if you want to
+ * isolate a field, you should mask the field and then shift it down,
+ * since this makes the masks useful without a shift.
+ */
+
+/* Directory entry states for both premium and standard SIMMs. */
+
+#define MD_DIR_SHARED (UINT64_CAST 0x0) /* 000 */
+#define MD_DIR_POISONED (UINT64_CAST 0x1) /* 001 */
+#define MD_DIR_EXCLUSIVE (UINT64_CAST 0x2) /* 010 */
+#define MD_DIR_BUSY_SHARED (UINT64_CAST 0x3) /* 011 */
+#define MD_DIR_BUSY_EXCL (UINT64_CAST 0x4) /* 100 */
+#define MD_DIR_WAIT (UINT64_CAST 0x5) /* 101 */
+#define MD_DIR_UNOWNED (UINT64_CAST 0x7) /* 111 */
+
+/*
+ * The MD_DIR_FORCE_ECC bit can be added directory entry write data
+ * to forcing the ECC to be written as-is instead of recalculated.
+ */
+
+#define MD_DIR_FORCE_ECC (UINT64_CAST 1 << 63)
+
+/*
+ * Premium SIMM directory entry shifts and masks. Each is valid only in the
+ * context(s) indicated, where A, B, and C indicate the directory entry format
+ * as shown, and low and/or high indicates which double-word of the entry.
+ *
+ * Format A: STATE = shared, FINE = 1
+ * Format B: STATE = shared, FINE = 0
+ * Format C: STATE != shared (FINE must be 0)
+ */
+
+#define MD_PDIR_MASK 0xffffffffffff /* Whole entry */
+#define MD_PDIR_ECC_SHFT 0 /* ABC low or high */
+#define MD_PDIR_ECC_MASK 0x7f
+#define MD_PDIR_PRIO_SHFT 8 /* ABC low */
+#define MD_PDIR_PRIO_MASK (0xf << 8)
+#define MD_PDIR_AX_SHFT 7 /* ABC low */
+#define MD_PDIR_AX_MASK (1 << 7)
+#define MD_PDIR_AX (1 << 7)
+#define MD_PDIR_FINE_SHFT 12 /* ABC low */
+#define MD_PDIR_FINE_MASK (1 << 12)
+#define MD_PDIR_FINE (1 << 12)
+#define MD_PDIR_OCT_SHFT 13 /* A low */
+#define MD_PDIR_OCT_MASK (7 << 13)
+#define MD_PDIR_STATE_SHFT 13 /* BC low */
+#define MD_PDIR_STATE_MASK (7 << 13)
+#define MD_PDIR_ONECNT_SHFT 16 /* BC low */
+#define MD_PDIR_ONECNT_MASK (0x3f << 16)
+#define MD_PDIR_PTR_SHFT 22 /* C low */
+#define MD_PDIR_PTR_MASK (UINT64_CAST 0x7ff << 22)
+#define MD_PDIR_VECMSB_SHFT 22 /* AB low */
+#define MD_PDIR_VECMSB_BITMASK 0x3ffffff
+#define MD_PDIR_VECMSB_BITSHFT 27
+#define MD_PDIR_VECMSB_MASK (UINT64_CAST MD_PDIR_VECMSB_BITMASK << 22)
+#define MD_PDIR_CWOFF_SHFT 7 /* C high */
+#define MD_PDIR_CWOFF_MASK (7 << 7)
+#define MD_PDIR_VECLSB_SHFT 10 /* AB high */
+#define MD_PDIR_VECLSB_BITMASK (UINT64_CAST 0x3fffffffff)
+#define MD_PDIR_VECLSB_BITSHFT 0
+#define MD_PDIR_VECLSB_MASK (MD_PDIR_VECLSB_BITMASK << 10)
+
+/*
+ * Directory initialization values
+ */
+
+#define MD_PDIR_INIT_LO (MD_DIR_UNOWNED << MD_PDIR_STATE_SHFT | \
+ MD_PDIR_AX)
+#define MD_PDIR_INIT_HI 0
+#define MD_PDIR_INIT_PROT (MD_PROT_RW << MD_PPROT_IO_SHFT | \
+ MD_PROT_RW << MD_PPROT_SHFT)
+
+/*
+ * Standard SIMM directory entry shifts and masks. Each is valid only in the
+ * context(s) indicated, where A and C indicate the directory entry format
+ * as shown, and low and/or high indicates which double-word of the entry.
+ *
+ * Format A: STATE == shared
+ * Format C: STATE != shared
+ */
+
+#define MD_SDIR_MASK 0xffff /* Whole entry */
+#define MD_SDIR_ECC_SHFT 0 /* AC low or high */
+#define MD_SDIR_ECC_MASK 0x1f
+#define MD_SDIR_PRIO_SHFT 6 /* AC low */
+#define MD_SDIR_PRIO_MASK (1 << 6)
+#define MD_SDIR_AX_SHFT 5 /* AC low */
+#define MD_SDIR_AX_MASK (1 << 5)
+#define MD_SDIR_AX (1 << 5)
+#define MD_SDIR_STATE_SHFT 7 /* AC low */
+#define MD_SDIR_STATE_MASK (7 << 7)
+#define MD_SDIR_PTR_SHFT 10 /* C low */
+#define MD_SDIR_PTR_MASK (0x3f << 10)
+#define MD_SDIR_CWOFF_SHFT 5 /* C high */
+#define MD_SDIR_CWOFF_MASK (7 << 5)
+#define MD_SDIR_VECMSB_SHFT 11 /* A low */
+#define MD_SDIR_VECMSB_BITMASK 0x1f
+#define MD_SDIR_VECMSB_BITSHFT 7
+#define MD_SDIR_VECMSB_MASK (MD_SDIR_VECMSB_BITMASK << 11)
+#define MD_SDIR_VECLSB_SHFT 5 /* A high */
+#define MD_SDIR_VECLSB_BITMASK 0x7ff
+#define MD_SDIR_VECLSB_BITSHFT 0
+#define MD_SDIR_VECLSB_MASK (MD_SDIR_VECLSB_BITMASK << 5)
+
+/*
+ * Directory initialization values
+ */
+
+#define MD_SDIR_INIT_LO (MD_DIR_UNOWNED << MD_SDIR_STATE_SHFT | \
+ MD_SDIR_AX)
+#define MD_SDIR_INIT_HI 0
+#define MD_SDIR_INIT_PROT (MD_PROT_RW << MD_SPROT_SHFT)
+
+/* Protection and migration field values */
+
+#define MD_PROT_RW (UINT64_CAST 0x6)
+#define MD_PROT_RO (UINT64_CAST 0x3)
+#define MD_PROT_NO (UINT64_CAST 0x0)
+#define MD_PROT_BAD (UINT64_CAST 0x5)
+
+/* Premium SIMM protection entry shifts and masks. */
+
+#define MD_PPROT_SHFT 0 /* Prot. field */
+#define MD_PPROT_MASK 7
+#define MD_PPROT_MIGMD_SHFT 3 /* Migration mode */
+#define MD_PPROT_MIGMD_MASK (3 << 3)
+#define MD_PPROT_REFCNT_SHFT 5 /* Reference count */
+#define MD_PPROT_REFCNT_WIDTH 0x7ffff
+#define MD_PPROT_REFCNT_MASK (MD_PPROT_REFCNT_WIDTH << 5)
+
+#define MD_PPROT_IO_SHFT 45 /* I/O Prot field */
+#define MD_PPROT_IO_MASK (UINT64_CAST 7 << 45)
+
+/* Standard SIMM protection entry shifts and masks. */
+
+#define MD_SPROT_SHFT 0 /* Prot. field */
+#define MD_SPROT_MASK 7
+#define MD_SPROT_MIGMD_SHFT 3 /* Migration mode */
+#define MD_SPROT_MIGMD_MASK (3 << 3)
+#define MD_SPROT_REFCNT_SHFT 5 /* Reference count */
+#define MD_SPROT_REFCNT_WIDTH 0x7ff
+#define MD_SPROT_REFCNT_MASK (MD_SPROT_REFCNT_WIDTH << 5)
+
+/* Migration modes used in protection entries */
+
+#define MD_PROT_MIGMD_IREL (UINT64_CAST 0x3 << 3)
+#define MD_PROT_MIGMD_IABS (UINT64_CAST 0x2 << 3)
+#define MD_PROT_MIGMD_PREL (UINT64_CAST 0x1 << 3)
+#define MD_PROT_MIGMD_OFF (UINT64_CAST 0x0 << 3)
+
+
+/*
+ * Operations on page migration threshold register
+ */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * LED register macros
+ */
+
+#define CPU_LED_ADDR(_nasid, _slice) \
+ (private.p_sn00 ? \
+ REMOTE_HUB_ADDR((_nasid), MD_UREG1_0 + ((_slice) << 5)) : \
+ REMOTE_HUB_ADDR((_nasid), MD_LED0 + ((_slice) << 3)))
+
+#define SET_CPU_LEDS(_nasid, _slice, _val) \
+ (HUB_S(CPU_LED_ADDR(_nasid, _slice), (_val)))
+
+#define SET_MY_LEDS(_v) \
+ SET_CPU_LEDS(get_nasid(), get_slice(), (_v))
+
+/*
+ * Operations on Memory/Directory DIMM control register
+ */
+
+#define DIRTYPE_PREMIUM 1
+#define DIRTYPE_STANDARD 0
+#define MD_MEMORY_CONFIG_DIR_TYPE_GET(region) (\
+ (REMOTE_HUB_L(region, MD_MEMORY_CONFIG) & MMC_DIR_PREMIUM_MASK) >> \
+ MMC_DIR_PREMIUM_SHFT)
+
+
+/*
+ * Operations on page migration count difference and absolute threshold
+ * registers
+ */
+
+#define MD_MIG_DIFF_THRESH_GET(region) ( \
+ REMOTE_HUB_L((region), MD_MIG_DIFF_THRESH) & \
+ MD_MIG_DIFF_THRES_VALUE_MASK)
+
+#define MD_MIG_DIFF_THRESH_SET(region, value) ( \
+ REMOTE_HUB_S((region), MD_MIG_DIFF_THRESH, \
+ MD_MIG_DIFF_THRES_VALID_MASK | (value)))
+
+#define MD_MIG_DIFF_THRESH_DISABLE(region) ( \
+ REMOTE_HUB_S((region), MD_MIG_DIFF_THRESH, \
+ REMOTE_HUB_L((region), MD_MIG_DIFF_THRESH) \
+ & ~MD_MIG_DIFF_THRES_VALID_MASK))
+
+#define MD_MIG_DIFF_THRESH_ENABLE(region) ( \
+ REMOTE_HUB_S((region), MD_MIG_DIFF_THRESH, \
+ REMOTE_HUB_L((region), MD_MIG_DIFF_THRESH) \
+ | MD_MIG_DIFF_THRES_VALID_MASK))
+
+#define MD_MIG_DIFF_THRESH_IS_ENABLED(region) ( \
+ REMOTE_HUB_L((region), MD_MIG_DIFF_THRESH) & \
+ MD_MIG_DIFF_THRES_VALID_MASK)
+
+#define MD_MIG_VALUE_THRESH_GET(region) ( \
+ REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) & \
+ MD_MIG_VALUE_THRES_VALUE_MASK)
+
+#define MD_MIG_VALUE_THRESH_SET(region, value) ( \
+ REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH, \
+ MD_MIG_VALUE_THRES_VALID_MASK | (value)))
+
+#define MD_MIG_VALUE_THRESH_DISABLE(region) ( \
+ REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH, \
+ REMOTE_HUB_L(region, MD_MIG_VALUE_THRESH) \
+ & ~MD_MIG_VALUE_THRES_VALID_MASK))
+
+#define MD_MIG_VALUE_THRESH_ENABLE(region) ( \
+ REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH, \
+ REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) \
+ | MD_MIG_VALUE_THRES_VALID_MASK))
+
+#define MD_MIG_VALUE_THRESH_IS_ENABLED(region) ( \
+ REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) & \
+ MD_MIG_VALUE_THRES_VALID_MASK)
+
+/*
+ * Operations on page migration candidate register
+ */
+
+#define MD_MIG_CANDIDATE_GET(my_region_id) ( \
+ REMOTE_HUB_L((my_region_id), MD_MIG_CANDIDATE_CLR))
+
+#define MD_MIG_CANDIDATE_HWPFN(value) ((value) & MD_MIG_CANDIDATE_ADDR_MASK)
+
+#define MD_MIG_CANDIDATE_NODEID(value) ( \
+ ((value) & MD_MIG_CANDIDATE_NODEID_MASK) >> MD_MIG_CANDIDATE_NODEID_SHFT)
+
+#define MD_MIG_CANDIDATE_TYPE(value) ( \
+ ((value) & MD_MIG_CANDIDATE_TYPE_MASK) >> MD_MIG_CANDIDATE_TYPE_SHFT)
+
+#define MD_MIG_CANDIDATE_VALID(value) ( \
+ ((value) & MD_MIG_CANDIDATE_VALID_MASK) >> MD_MIG_CANDIDATE_VALID_SHFT)
+
+/*
+ * Macros to retrieve fields in the protection entry
+ */
+
+/* for Premium SIMM */
+#define MD_PPROT_REFCNT_GET(value) ( \
+ ((value) & MD_PPROT_REFCNT_MASK) >> MD_PPROT_REFCNT_SHFT)
+
+#define MD_PPROT_MIGMD_GET(value) ( \
+ ((value) & MD_PPROT_MIGMD_MASK) >> MD_PPROT_MIGMD_SHFT)
+
+/* for Standard SIMM */
+#define MD_SPROT_REFCNT_GET(value) ( \
+ ((value) & MD_SPROT_REFCNT_MASK) >> MD_SPROT_REFCNT_SHFT)
+
+#define MD_SPROT_MIGMD_GET(value) ( \
+ ((value) & MD_SPROT_MIGMD_MASK) >> MD_SPROT_MIGMD_SHFT)
+
+/*
+ * Format of dir_error, mem_error, protocol_error and misc_error registers
+ */
+
+struct dir_error_reg {
+ u64 uce_vld: 1, /* 63: valid directory uce */
+ ae_vld: 1, /* 62: valid dir prot ecc error */
+ ce_vld: 1, /* 61: valid correctable ECC err*/
+ rsvd1: 19, /* 60-42: reserved */
+ bad_prot: 3, /* 41-39: encoding, bad access rights*/
+ bad_syn: 7, /* 38-32: bad dir syndrome */
+ rsvd2: 2, /* 31-30: reserved */
+ hspec_addr:27, /* 29-03: bddir space bad entry */
+ uce_ovr: 1, /* 2: multiple dir uce's */
+ ae_ovr: 1, /* 1: multiple prot ecc errs*/
+ ce_ovr: 1; /* 0: multiple correctable errs */
+};
+
+typedef union md_dir_error {
+ u64 derr_reg; /* the entire register */
+ struct dir_error_reg derr_fmt; /* the register format */
+} md_dir_error_t;
+
+
+struct mem_error_reg {
+ u64 uce_vld: 1, /* 63: valid memory uce */
+ ce_vld: 1, /* 62: valid correctable ECC err*/
+ rsvd1: 22, /* 61-40: reserved */
+ bad_syn: 8, /* 39-32: bad mem ecc syndrome */
+ address: 29, /* 31-03: bad entry pointer */
+ rsvd2: 1, /* 2: reserved */
+ uce_ovr: 1, /* 1: multiple mem uce's */
+ ce_ovr: 1; /* 0: multiple correctable errs */
+};
+
+
+typedef union md_mem_error {
+ u64 merr_reg; /* the entire register */
+ struct mem_error_reg merr_fmt; /* format of the mem_error reg */
+} md_mem_error_t;
+
+
+struct proto_error_reg {
+ u64 valid: 1, /* 63: valid protocol error */
+ rsvd1: 2, /* 62-61: reserved */
+ initiator:11, /* 60-50: id of request initiator*/
+ backoff: 2, /* 49-48: backoff control */
+ msg_type: 8, /* 47-40: type of request */
+ access: 2, /* 39-38: access rights of initiator*/
+ priority: 1, /* 37: priority level of requestor*/
+ dir_state: 4, /* 36-33: state of directory */
+ pointer_me:1, /* 32: initiator same as dir ptr */
+ address: 29, /* 31-03: request address */
+ rsvd2: 2, /* 02-01: reserved */
+ overrun: 1; /* 0: multiple protocol errs */
+};
+
+typedef union md_proto_error {
+ u64 perr_reg; /* the entire register */
+ struct proto_error_reg perr_fmt; /* format of the register */
+} md_proto_error_t;
+
+
+struct md_sdir_high_fmt {
+ unsigned short sd_hi_bvec : 11,
+ sd_hi_ecc : 5;
+};
+
+
+typedef union md_sdir_high {
+ /* The 16 bits of standard directory, upper word */
+ unsigned short sd_hi_val;
+ struct md_sdir_high_fmt sd_hi_fmt;
+}md_sdir_high_t;
+
+
+struct md_sdir_low_shared_fmt {
+ /* The meaning of lower directory, shared */
+ unsigned short sds_lo_bvec : 5,
+ sds_lo_unused: 1,
+ sds_lo_state : 3,
+ sds_lo_prio : 1,
+ sds_lo_ax : 1,
+ sds_lo_ecc : 5;
+};
+
+struct md_sdir_low_exclusive_fmt {
+ /* The meaning of lower directory, exclusive */
+ unsigned short sde_lo_ptr : 6,
+ sde_lo_state : 3,
+ sde_lo_prio : 1,
+ sde_lo_ax : 1,
+ sde_lo_ecc : 5;
+};
+
+
+typedef union md_sdir_low {
+ /* The 16 bits of standard directory, lower word */
+ unsigned short sd_lo_val;
+ struct md_sdir_low_exclusive_fmt sde_lo_fmt;
+ struct md_sdir_low_shared_fmt sds_lo_fmt;
+}md_sdir_low_t;
+
+
+
+struct md_pdir_high_fmt {
+ u64 pd_hi_unused : 16,
+ pd_hi_bvec : 38,
+ pd_hi_unused1 : 3,
+ pd_hi_ecc : 7;
+};
+
+
+typedef union md_pdir_high {
+ /* The 48 bits of standard directory, upper word */
+ u64 pd_hi_val;
+ struct md_pdir_high_fmt pd_hi_fmt;
+}md_pdir_high_t;
+
+
+struct md_pdir_low_shared_fmt {
+ /* The meaning of lower directory, shared */
+ u64 pds_lo_unused : 16,
+ pds_lo_bvec : 26,
+ pds_lo_cnt : 6,
+ pds_lo_state : 3,
+ pds_lo_ste : 1,
+ pds_lo_prio : 4,
+ pds_lo_ax : 1,
+ pds_lo_ecc : 7;
+};
+
+struct md_pdir_low_exclusive_fmt {
+ /* The meaning of lower directory, exclusive */
+ u64 pde_lo_unused : 31,
+ pde_lo_ptr : 11,
+ pde_lo_unused1 : 6,
+ pde_lo_state : 3,
+ pde_lo_ste : 1,
+ pde_lo_prio : 4,
+ pde_lo_ax : 1,
+ pde_lo_ecc : 7;
+};
+
+
+typedef union md_pdir_loent {
+ /* The 48 bits of premium directory, lower word */
+ u64 pd_lo_val;
+ struct md_pdir_low_exclusive_fmt pde_lo_fmt;
+ struct md_pdir_low_shared_fmt pds_lo_fmt;
+}md_pdir_low_t;
+
+
+/*
+ * the following two "union" definitions and two
+ * "struct" definitions are used in vmdump.c to
+ * represent directory memory information.
+ */
+
+typedef union md_dir_high {
+ md_sdir_high_t md_sdir_high;
+ md_pdir_high_t md_pdir_high;
+} md_dir_high_t;
+
+typedef union md_dir_low {
+ md_sdir_low_t md_sdir_low;
+ md_pdir_low_t md_pdir_low;
+} md_dir_low_t;
+
+typedef struct bddir_entry {
+ md_dir_low_t md_dir_low;
+ md_dir_high_t md_dir_high;
+} bddir_entry_t;
+
+typedef struct dir_mem_entry {
+ u64 prcpf[MAX_REGIONS];
+ bddir_entry_t directory_words[MD_PAGE_SIZE/CACHE_SLINE_SIZE];
+} dir_mem_entry_t;
+
+
+
+typedef union md_perf_sel {
+ u64 perf_sel_reg;
+ struct {
+ u64 perf_rsvd : 60,
+ perf_en : 1,
+ perf_sel : 3;
+ } perf_sel_bits;
+} md_perf_sel_t;
+
+typedef union md_perf_cnt {
+ u64 perf_cnt;
+ struct {
+ u64 perf_rsvd : 44,
+ perf_cnt : 20;
+ } perf_cnt_bits;
+} md_perf_cnt_t;
+
+
+#endif /* !__ASSEMBLY__ */
+
+
+#define DIR_ERROR_VALID_MASK 0xe000000000000000
+#define DIR_ERROR_VALID_SHFT 61
+#define DIR_ERROR_VALID_UCE 0x8000000000000000
+#define DIR_ERROR_VALID_AE 0x4000000000000000
+#define DIR_ERROR_VALID_CE 0x2000000000000000
+
+#define MEM_ERROR_VALID_MASK 0xc000000000000000
+#define MEM_ERROR_VALID_SHFT 62
+#define MEM_ERROR_VALID_UCE 0x8000000000000000
+#define MEM_ERROR_VALID_CE 0x4000000000000000
+
+#define PROTO_ERROR_VALID_MASK 0x8000000000000000
+
+#define MISC_ERROR_VALID_MASK 0x3ff
+
+/*
+ * Mask for hspec address that is stored in the dir error register.
+ * This represents bits 29 through 3.
+ */
+#define DIR_ERR_HSPEC_MASK 0x3ffffff8
+#define ERROR_HSPEC_MASK 0x3ffffff8
+#define ERROR_HSPEC_SHFT 3
+#define ERROR_ADDR_MASK 0xfffffff8
+#define ERROR_ADDR_SHFT 3
+
+/*
+ * MD_MISC_ERROR register defines.
+ */
+
+#define MMCE_VALID_MASK 0x3ff
+#define MMCE_ILL_MSG_SHFT 8
+#define MMCE_ILL_MSG_MASK (UINT64_CAST 0x03 << MMCE_ILL_MSG_SHFT)
+#define MMCE_ILL_REV_SHFT 6
+#define MMCE_ILL_REV_MASK (UINT64_CAST 0x03 << MMCE_ILL_REV_SHFT)
+#define MMCE_LONG_PACK_SHFT 4
+#define MMCE_LONG_PACK_MASK (UINT64_CAST 0x03 << MMCE_lONG_PACK_SHFT)
+#define MMCE_SHORT_PACK_SHFT 2
+#define MMCE_SHORT_PACK_MASK (UINT64_CAST 0x03 << MMCE_SHORT_PACK_SHFT)
+#define MMCE_BAD_DATA_SHFT 0
+#define MMCE_BAD_DATA_MASK (UINT64_CAST 0x03 << MMCE_BAD_DATA_SHFT)
+
+
+#define MD_PERF_COUNTERS 6
+#define MD_PERF_SETS 6
+
+#define MEM_DIMM_MASK 0xe0000000
+#define MEM_DIMM_SHFT 29
+
+#endif /* _ASM_SN_SN0_HUBMD_H */
diff --git a/arch/mips/include/asm/sn/sn0/hubni.h b/arch/mips/include/asm/sn/sn0/hubni.h
new file mode 100644
index 00000000..b40d3ef9
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn0/hubni.h
@@ -0,0 +1,255 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/hubni.h>, Revision 1.27.
+ *
+ * Copyright (C) 1992-1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SGI_SN0_HUBNI_H
+#define _ASM_SGI_SN0_HUBNI_H
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#endif
+
+/*
+ * Hub Network Interface registers
+ *
+ * All registers in this file are subject to change until Hub chip tapeout.
+ */
+
+#define NI_BASE 0x600000
+#define NI_BASE_TABLES 0x630000
+
+#define NI_STATUS_REV_ID 0x600000 /* Hub network status, rev, and ID */
+#define NI_PORT_RESET 0x600008 /* Reset the network interface */
+#define NI_PROTECTION 0x600010 /* NI register access permissions */
+#define NI_GLOBAL_PARMS 0x600018 /* LLP parameters */
+#define NI_SCRATCH_REG0 0x600100 /* Scratch register 0 (64 bits) */
+#define NI_SCRATCH_REG1 0x600108 /* Scratch register 1 (64 bits) */
+#define NI_DIAG_PARMS 0x600110 /* Parameters for diags */
+
+#define NI_VECTOR_PARMS 0x600200 /* Vector PIO routing parameters */
+#define NI_VECTOR 0x600208 /* Vector PIO route */
+#define NI_VECTOR_DATA 0x600210 /* Vector PIO data */
+#define NI_VECTOR_STATUS 0x600300 /* Vector PIO return status */
+#define NI_RETURN_VECTOR 0x600308 /* Vector PIO return vector */
+#define NI_VECTOR_READ_DATA 0x600310 /* Vector PIO read data */
+#define NI_VECTOR_CLEAR 0x600380 /* Vector PIO read & clear status */
+
+#define NI_IO_PROTECT 0x600400 /* PIO protection bits */
+#define NI_IO_PROT_OVRRD 0x600408 /* PIO protection bit override */
+
+#define NI_AGE_CPU0_MEMORY 0x600500 /* CPU 0 memory age control */
+#define NI_AGE_CPU0_PIO 0x600508 /* CPU 0 PIO age control */
+#define NI_AGE_CPU1_MEMORY 0x600510 /* CPU 1 memory age control */
+#define NI_AGE_CPU1_PIO 0x600518 /* CPU 1 PIO age control */
+#define NI_AGE_GBR_MEMORY 0x600520 /* GBR memory age control */
+#define NI_AGE_GBR_PIO 0x600528 /* GBR PIO age control */
+#define NI_AGE_IO_MEMORY 0x600530 /* IO memory age control */
+#define NI_AGE_IO_PIO 0x600538 /* IO PIO age control */
+#define NI_AGE_REG_MIN NI_AGE_CPU0_MEMORY
+#define NI_AGE_REG_MAX NI_AGE_IO_PIO
+
+#define NI_PORT_PARMS 0x608000 /* LLP Parameters */
+#define NI_PORT_ERROR 0x608008 /* LLP Errors */
+#define NI_PORT_ERROR_CLEAR 0x608088 /* Clear the error bits */
+
+#define NI_META_TABLE0 0x638000 /* First meta routing table entry */
+#define NI_META_TABLE(_x) (NI_META_TABLE0 + (8 * (_x)))
+#define NI_META_ENTRIES 32
+
+#define NI_LOCAL_TABLE0 0x638100 /* First local routing table entry */
+#define NI_LOCAL_TABLE(_x) (NI_LOCAL_TABLE0 + (8 * (_x)))
+#define NI_LOCAL_ENTRIES 16
+
+/*
+ * NI_STATUS_REV_ID mask and shift definitions
+ * Have to use UINT64_CAST instead of 'L' suffix, for assembler.
+ */
+
+#define NSRI_8BITMODE_SHFT 30
+#define NSRI_8BITMODE_MASK (UINT64_CAST 0x1 << 30)
+#define NSRI_LINKUP_SHFT 29
+#define NSRI_LINKUP_MASK (UINT64_CAST 0x1 << 29)
+#define NSRI_DOWNREASON_SHFT 28 /* 0=failed, 1=never came */
+#define NSRI_DOWNREASON_MASK (UINT64_CAST 0x1 << 28) /* out of reset. */
+#define NSRI_MORENODES_SHFT 18
+#define NSRI_MORENODES_MASK (UINT64_CAST 1 << 18) /* Max. # of nodes */
+#define MORE_MEMORY 0
+#define MORE_NODES 1
+#define NSRI_REGIONSIZE_SHFT 17
+#define NSRI_REGIONSIZE_MASK (UINT64_CAST 1 << 17) /* Granularity */
+#define REGIONSIZE_FINE 1
+#define REGIONSIZE_COARSE 0
+#define NSRI_NODEID_SHFT 8
+#define NSRI_NODEID_MASK (UINT64_CAST 0x1ff << 8)/* Node (Hub) ID */
+#define NSRI_REV_SHFT 4
+#define NSRI_REV_MASK (UINT64_CAST 0xf << 4) /* Chip Revision */
+#define NSRI_CHIPID_SHFT 0
+#define NSRI_CHIPID_MASK (UINT64_CAST 0xf) /* Chip type ID */
+
+/*
+ * In fine mode, each node is a region. In coarse mode, there are
+ * eight nodes per region.
+ */
+#define NASID_TO_FINEREG_SHFT 0
+#define NASID_TO_COARSEREG_SHFT 3
+
+/* NI_PORT_RESET mask definitions */
+
+#define NPR_PORTRESET (UINT64_CAST 1 << 7) /* Send warm reset */
+#define NPR_LINKRESET (UINT64_CAST 1 << 1) /* Send link reset */
+#define NPR_LOCALRESET (UINT64_CAST 1) /* Reset entire hub */
+
+/* NI_PROTECTION mask and shift definitions */
+
+#define NPROT_RESETOK (UINT64_CAST 1)
+
+/* NI_GLOBAL_PARMS mask and shift definitions */
+
+#define NGP_MAXRETRY_SHFT 48 /* Maximum retries */
+#define NGP_MAXRETRY_MASK (UINT64_CAST 0x3ff << 48)
+#define NGP_TAILTOWRAP_SHFT 32 /* Tail timeout wrap */
+#define NGP_TAILTOWRAP_MASK (UINT64_CAST 0xffff << 32)
+
+#define NGP_CREDITTOVAL_SHFT 16 /* Tail timeout wrap */
+#define NGP_CREDITTOVAL_MASK (UINT64_CAST 0xf << 16)
+#define NGP_TAILTOVAL_SHFT 4 /* Tail timeout value */
+#define NGP_TAILTOVAL_MASK (UINT64_CAST 0xf << 4)
+
+/* NI_DIAG_PARMS mask and shift definitions */
+
+#define NDP_PORTTORESET (UINT64_CAST 1 << 18) /* Port tmout reset */
+#define NDP_LLP8BITMODE (UINT64_CAST 1 << 12) /* LLP 8-bit mode */
+#define NDP_PORTDISABLE (UINT64_CAST 1 << 6) /* Port disable */
+#define NDP_SENDERROR (UINT64_CAST 1) /* Send data error */
+
+/*
+ * NI_VECTOR_PARMS mask and shift definitions.
+ * TYPE may be any of the first four PIOTYPEs defined under NI_VECTOR_STATUS.
+ */
+
+#define NVP_PIOID_SHFT 40
+#define NVP_PIOID_MASK (UINT64_CAST 0x3ff << 40)
+#define NVP_WRITEID_SHFT 32
+#define NVP_WRITEID_MASK (UINT64_CAST 0xff << 32)
+#define NVP_ADDRESS_MASK (UINT64_CAST 0xffff8) /* Bits 19:3 */
+#define NVP_TYPE_SHFT 0
+#define NVP_TYPE_MASK (UINT64_CAST 0x3)
+
+/* NI_VECTOR_STATUS mask and shift definitions */
+
+#define NVS_VALID (UINT64_CAST 1 << 63)
+#define NVS_OVERRUN (UINT64_CAST 1 << 62)
+#define NVS_TARGET_SHFT 51
+#define NVS_TARGET_MASK (UINT64_CAST 0x3ff << 51)
+#define NVS_PIOID_SHFT 40
+#define NVS_PIOID_MASK (UINT64_CAST 0x3ff << 40)
+#define NVS_WRITEID_SHFT 32
+#define NVS_WRITEID_MASK (UINT64_CAST 0xff << 32)
+#define NVS_ADDRESS_MASK (UINT64_CAST 0xfffffff8) /* Bits 31:3 */
+#define NVS_TYPE_SHFT 0
+#define NVS_TYPE_MASK (UINT64_CAST 0x7)
+#define NVS_ERROR_MASK (UINT64_CAST 0x4) /* bit set means error */
+
+
+#define PIOTYPE_READ 0 /* VECTOR_PARMS and VECTOR_STATUS */
+#define PIOTYPE_WRITE 1 /* VECTOR_PARMS and VECTOR_STATUS */
+#define PIOTYPE_UNDEFINED 2 /* VECTOR_PARMS and VECTOR_STATUS */
+#define PIOTYPE_EXCHANGE 3 /* VECTOR_PARMS and VECTOR_STATUS */
+#define PIOTYPE_ADDR_ERR 4 /* VECTOR_STATUS only */
+#define PIOTYPE_CMD_ERR 5 /* VECTOR_STATUS only */
+#define PIOTYPE_PROT_ERR 6 /* VECTOR_STATUS only */
+#define PIOTYPE_UNKNOWN 7 /* VECTOR_STATUS only */
+
+/* NI_AGE_XXX mask and shift definitions */
+
+#define NAGE_VCH_SHFT 10
+#define NAGE_VCH_MASK (UINT64_CAST 3 << 10)
+#define NAGE_CC_SHFT 8
+#define NAGE_CC_MASK (UINT64_CAST 3 << 8)
+#define NAGE_AGE_SHFT 0
+#define NAGE_AGE_MASK (UINT64_CAST 0xff)
+#define NAGE_MASK (NAGE_VCH_MASK | NAGE_CC_MASK | NAGE_AGE_MASK)
+
+#define VCHANNEL_A 0
+#define VCHANNEL_B 1
+#define VCHANNEL_ANY 2
+
+/* NI_PORT_PARMS mask and shift definitions */
+
+#define NPP_NULLTO_SHFT 10
+#define NPP_NULLTO_MASK (UINT64_CAST 0x3f << 16)
+#define NPP_MAXBURST_SHFT 0
+#define NPP_MAXBURST_MASK (UINT64_CAST 0x3ff)
+#define NPP_RESET_DFLT_HUB20 ((UINT64_CAST 1 << NPP_NULLTO_SHFT) | \
+ (UINT64_CAST 0x3f0 << NPP_MAXBURST_SHFT))
+#define NPP_RESET_DEFAULTS ((UINT64_CAST 6 << NPP_NULLTO_SHFT) | \
+ (UINT64_CAST 0x3f0 << NPP_MAXBURST_SHFT))
+
+
+/* NI_PORT_ERROR mask and shift definitions */
+
+#define NPE_LINKRESET (UINT64_CAST 1 << 37)
+#define NPE_INTERNALERROR (UINT64_CAST 1 << 36)
+#define NPE_BADMESSAGE (UINT64_CAST 1 << 35)
+#define NPE_BADDEST (UINT64_CAST 1 << 34)
+#define NPE_FIFOOVERFLOW (UINT64_CAST 1 << 33)
+#define NPE_CREDITTO_SHFT 28
+#define NPE_CREDITTO_MASK (UINT64_CAST 0xf << 28)
+#define NPE_TAILTO_SHFT 24
+#define NPE_TAILTO_MASK (UINT64_CAST 0xf << 24)
+#define NPE_RETRYCOUNT_SHFT 16
+#define NPE_RETRYCOUNT_MASK (UINT64_CAST 0xff << 16)
+#define NPE_CBERRCOUNT_SHFT 8
+#define NPE_CBERRCOUNT_MASK (UINT64_CAST 0xff << 8)
+#define NPE_SNERRCOUNT_SHFT 0
+#define NPE_SNERRCOUNT_MASK (UINT64_CAST 0xff << 0)
+#define NPE_MASK 0x3effffffff
+
+#define NPE_COUNT_MAX 0xff
+
+#define NPE_FATAL_ERRORS (NPE_LINKRESET | NPE_INTERNALERROR | \
+ NPE_BADMESSAGE | NPE_BADDEST | \
+ NPE_FIFOOVERFLOW | NPE_CREDITTO_MASK | \
+ NPE_TAILTO_MASK)
+
+/* NI_META_TABLE mask and shift definitions */
+
+#define NMT_EXIT_PORT_MASK (UINT64_CAST 0xf)
+
+/* NI_LOCAL_TABLE mask and shift definitions */
+
+#define NLT_EXIT_PORT_MASK (UINT64_CAST 0xf)
+
+#ifndef __ASSEMBLY__
+
+typedef union hubni_port_error_u {
+ u64 nipe_reg_value;
+ struct {
+ u64 nipe_rsvd: 26, /* unused */
+ nipe_lnk_reset: 1, /* link reset */
+ nipe_intl_err: 1, /* internal error */
+ nipe_bad_msg: 1, /* bad message */
+ nipe_bad_dest: 1, /* bad dest */
+ nipe_fifo_ovfl: 1, /* fifo overflow */
+ nipe_rsvd1: 1, /* unused */
+ nipe_credit_to: 4, /* credit timeout */
+ nipe_tail_to: 4, /* tail timeout */
+ nipe_retry_cnt: 8, /* retry error count */
+ nipe_cb_cnt: 8, /* checkbit error count */
+ nipe_sn_cnt: 8; /* sequence number count */
+ } nipe_fields_s;
+} hubni_port_error_t;
+
+#define NI_LLP_RETRY_MAX 0xff
+#define NI_LLP_CB_MAX 0xff
+#define NI_LLP_SN_MAX 0xff
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_SGI_SN0_HUBNI_H */
diff --git a/arch/mips/include/asm/sn/sn0/hubpi.h b/arch/mips/include/asm/sn/sn0/hubpi.h
new file mode 100644
index 00000000..e39f5f9d
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn0/hubpi.h
@@ -0,0 +1,409 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/hubpi.h>, revision 1.28.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_SN0_HUBPI_H
+#define _ASM_SN_SN0_HUBPI_H
+
+#include <linux/types.h>
+
+/*
+ * Hub I/O interface registers
+ *
+ * All registers in this file are subject to change until Hub chip tapeout.
+ * All register "addresses" are actually offsets. Use the LOCAL_HUB
+ * or REMOTE_HUB macros to synthesize an actual address
+ */
+
+#define PI_BASE 0x000000
+
+/* General protection and control registers */
+
+#define PI_CPU_PROTECT 0x000000 /* CPU Protection */
+#define PI_PROT_OVERRD 0x000008 /* Clear CPU Protection bit */
+#define PI_IO_PROTECT 0x000010 /* Interrupt Pending Protection */
+#define PI_REGION_PRESENT 0x000018 /* Indicates whether region exists */
+#define PI_CPU_NUM 0x000020 /* CPU Number ID */
+#define PI_CALIAS_SIZE 0x000028 /* Cached Alias Size */
+#define PI_MAX_CRB_TIMEOUT 0x000030 /* Maximum Timeout for CRB */
+#define PI_CRB_SFACTOR 0x000038 /* Scale factor for CRB timeout */
+
+/* CALIAS values */
+#define PI_CALIAS_SIZE_0 0
+#define PI_CALIAS_SIZE_4K 1
+#define PI_CALIAS_SIZE_8K 2
+#define PI_CALIAS_SIZE_16K 3
+#define PI_CALIAS_SIZE_32K 4
+#define PI_CALIAS_SIZE_64K 5
+#define PI_CALIAS_SIZE_128K 6
+#define PI_CALIAS_SIZE_256K 7
+#define PI_CALIAS_SIZE_512K 8
+#define PI_CALIAS_SIZE_1M 9
+#define PI_CALIAS_SIZE_2M 10
+#define PI_CALIAS_SIZE_4M 11
+#define PI_CALIAS_SIZE_8M 12
+#define PI_CALIAS_SIZE_16M 13
+#define PI_CALIAS_SIZE_32M 14
+#define PI_CALIAS_SIZE_64M 15
+
+/* Processor control and status checking */
+
+#define PI_CPU_PRESENT_A 0x000040 /* CPU Present A */
+#define PI_CPU_PRESENT_B 0x000048 /* CPU Present B */
+#define PI_CPU_ENABLE_A 0x000050 /* CPU Enable A */
+#define PI_CPU_ENABLE_B 0x000058 /* CPU Enable B */
+#define PI_REPLY_LEVEL 0x000060 /* Reply Level */
+#define PI_HARDRESET_BIT 0x020068 /* Bit cleared by s/w on SR */
+#define PI_NMI_A 0x000070 /* NMI to CPU A */
+#define PI_NMI_B 0x000078 /* NMI to CPU B */
+#define PI_NMI_OFFSET (PI_NMI_B - PI_NMI_A)
+#define PI_SOFTRESET 0x000080 /* Softreset (to both CPUs) */
+
+/* Regular Interrupt register checking. */
+
+#define PI_INT_PEND_MOD 0x000090 /* Write to set pending ints */
+#define PI_INT_PEND0 0x000098 /* Read to get pending ints */
+#define PI_INT_PEND1 0x0000a0 /* Read to get pending ints */
+#define PI_INT_MASK0_A 0x0000a8 /* Interrupt Mask 0 for CPU A */
+#define PI_INT_MASK1_A 0x0000b0 /* Interrupt Mask 1 for CPU A */
+#define PI_INT_MASK0_B 0x0000b8 /* Interrupt Mask 0 for CPU B */
+#define PI_INT_MASK1_B 0x0000c0 /* Interrupt Mask 1 for CPU B */
+
+#define PI_INT_MASK_OFFSET 0x10 /* Offset from A to B */
+
+/* Crosscall interrupts */
+
+#define PI_CC_PEND_SET_A 0x0000c8 /* CC Interrupt Pending Set, CPU A */
+#define PI_CC_PEND_SET_B 0x0000d0 /* CC Interrupt Pending Set, CPU B */
+#define PI_CC_PEND_CLR_A 0x0000d8 /* CC Interrupt Pending Clr, CPU A */
+#define PI_CC_PEND_CLR_B 0x0000e0 /* CC Interrupt Pending Clr, CPU B */
+#define PI_CC_MASK 0x0000e8 /* CC Interrupt mask */
+
+#define PI_INT_SET_OFFSET 0x08 /* Offset from A to B */
+
+/* Realtime Counter and Profiler control registers */
+
+#define PI_RT_COUNT 0x030100 /* Real Time Counter */
+#define PI_RT_COMPARE_A 0x000108 /* Real Time Compare A */
+#define PI_RT_COMPARE_B 0x000110 /* Real Time Compare B */
+#define PI_PROFILE_COMPARE 0x000118 /* L5 int to both cpus when == RTC */
+#define PI_RT_PEND_A 0x000120 /* Set if RT int for A pending */
+#define PI_RT_PEND_B 0x000128 /* Set if RT int for B pending */
+#define PI_PROF_PEND_A 0x000130 /* Set if Prof int for A pending */
+#define PI_PROF_PEND_B 0x000138 /* Set if Prof int for B pending */
+#define PI_RT_EN_A 0x000140 /* RT int for CPU A enable */
+#define PI_RT_EN_B 0x000148 /* RT int for CPU B enable */
+#define PI_PROF_EN_A 0x000150 /* PROF int for CPU A enable */
+#define PI_PROF_EN_B 0x000158 /* PROF int for CPU B enable */
+#define PI_RT_LOCAL_CTRL 0x000160 /* RT control register */
+#define PI_RT_FILTER_CTRL 0x000168 /* GCLK Filter control register */
+
+#define PI_COUNT_OFFSET 0x08 /* A to B offset for all counts */
+
+/* Built-In Self Test support */
+
+#define PI_BIST_WRITE_DATA 0x000200 /* BIST write data */
+#define PI_BIST_READ_DATA 0x000208 /* BIST read data */
+#define PI_BIST_COUNT_TARG 0x000210 /* BIST Count and Target */
+#define PI_BIST_READY 0x000218 /* BIST Ready indicator */
+#define PI_BIST_SHIFT_LOAD 0x000220 /* BIST control */
+#define PI_BIST_SHIFT_UNLOAD 0x000228 /* BIST control */
+#define PI_BIST_ENTER_RUN 0x000230 /* BIST control */
+
+/* Graphics control registers */
+
+#define PI_GFX_PAGE_A 0x000300 /* Graphics page A */
+#define PI_GFX_CREDIT_CNTR_A 0x000308 /* Graphics credit counter A */
+#define PI_GFX_BIAS_A 0x000310 /* Graphics bias A */
+#define PI_GFX_INT_CNTR_A 0x000318 /* Graphics interrupt counter A */
+#define PI_GFX_INT_CMP_A 0x000320 /* Graphics interrupt comparator A */
+#define PI_GFX_PAGE_B 0x000328 /* Graphics page B */
+#define PI_GFX_CREDIT_CNTR_B 0x000330 /* Graphics credit counter B */
+#define PI_GFX_BIAS_B 0x000338 /* Graphics bias B */
+#define PI_GFX_INT_CNTR_B 0x000340 /* Graphics interrupt counter B */
+#define PI_GFX_INT_CMP_B 0x000348 /* Graphics interrupt comparator B */
+
+#define PI_GFX_OFFSET (PI_GFX_PAGE_B - PI_GFX_PAGE_A)
+#define PI_GFX_PAGE_ENABLE 0x0000010000000000LL
+
+/* Error and timeout registers */
+#define PI_ERR_INT_PEND 0x000400 /* Error Interrupt Pending */
+#define PI_ERR_INT_MASK_A 0x000408 /* Error Interrupt mask for CPU A */
+#define PI_ERR_INT_MASK_B 0x000410 /* Error Interrupt mask for CPU B */
+#define PI_ERR_STACK_ADDR_A 0x000418 /* Error stack address for CPU A */
+#define PI_ERR_STACK_ADDR_B 0x000420 /* Error stack address for CPU B */
+#define PI_ERR_STACK_SIZE 0x000428 /* Error Stack Size */
+#define PI_ERR_STATUS0_A 0x000430 /* Error Status 0A */
+#define PI_ERR_STATUS0_A_RCLR 0x000438 /* Error Status 0A clear on read */
+#define PI_ERR_STATUS1_A 0x000440 /* Error Status 1A */
+#define PI_ERR_STATUS1_A_RCLR 0x000448 /* Error Status 1A clear on read */
+#define PI_ERR_STATUS0_B 0x000450 /* Error Status 0B */
+#define PI_ERR_STATUS0_B_RCLR 0x000458 /* Error Status 0B clear on read */
+#define PI_ERR_STATUS1_B 0x000460 /* Error Status 1B */
+#define PI_ERR_STATUS1_B_RCLR 0x000468 /* Error Status 1B clear on read */
+#define PI_SPOOL_CMP_A 0x000470 /* Spool compare for CPU A */
+#define PI_SPOOL_CMP_B 0x000478 /* Spool compare for CPU B */
+#define PI_CRB_TIMEOUT_A 0x000480 /* Timed out CRB entries for A */
+#define PI_CRB_TIMEOUT_B 0x000488 /* Timed out CRB entries for B */
+#define PI_SYSAD_ERRCHK_EN 0x000490 /* Enables SYSAD error checking */
+#define PI_BAD_CHECK_BIT_A 0x000498 /* Force SYSAD check bit error */
+#define PI_BAD_CHECK_BIT_B 0x0004a0 /* Force SYSAD check bit error */
+#define PI_NACK_CNT_A 0x0004a8 /* Consecutive NACK counter */
+#define PI_NACK_CNT_B 0x0004b0 /* " " for CPU B */
+#define PI_NACK_CMP 0x0004b8 /* NACK count compare */
+#define PI_STACKADDR_OFFSET (PI_ERR_STACK_ADDR_B - PI_ERR_STACK_ADDR_A)
+#define PI_ERRSTAT_OFFSET (PI_ERR_STATUS0_B - PI_ERR_STATUS0_A)
+#define PI_RDCLR_OFFSET (PI_ERR_STATUS0_A_RCLR - PI_ERR_STATUS0_A)
+
+/* Bits in PI_ERR_INT_PEND */
+#define PI_ERR_SPOOL_CMP_B 0x00000001 /* Spool end hit high water */
+#define PI_ERR_SPOOL_CMP_A 0x00000002
+#define PI_ERR_SPUR_MSG_B 0x00000004 /* Spurious message intr. */
+#define PI_ERR_SPUR_MSG_A 0x00000008
+#define PI_ERR_WRB_TERR_B 0x00000010 /* WRB TERR */
+#define PI_ERR_WRB_TERR_A 0x00000020
+#define PI_ERR_WRB_WERR_B 0x00000040 /* WRB WERR */
+#define PI_ERR_WRB_WERR_A 0x00000080
+#define PI_ERR_SYSSTATE_B 0x00000100 /* SysState parity error */
+#define PI_ERR_SYSSTATE_A 0x00000200
+#define PI_ERR_SYSAD_DATA_B 0x00000400 /* SysAD data parity error */
+#define PI_ERR_SYSAD_DATA_A 0x00000800
+#define PI_ERR_SYSAD_ADDR_B 0x00001000 /* SysAD addr parity error */
+#define PI_ERR_SYSAD_ADDR_A 0x00002000
+#define PI_ERR_SYSCMD_DATA_B 0x00004000 /* SysCmd data parity error */
+#define PI_ERR_SYSCMD_DATA_A 0x00008000
+#define PI_ERR_SYSCMD_ADDR_B 0x00010000 /* SysCmd addr parity error */
+#define PI_ERR_SYSCMD_ADDR_A 0x00020000
+#define PI_ERR_BAD_SPOOL_B 0x00040000 /* Error spooling to memory */
+#define PI_ERR_BAD_SPOOL_A 0x00080000
+#define PI_ERR_UNCAC_UNCORR_B 0x00100000 /* Uncached uncorrectable */
+#define PI_ERR_UNCAC_UNCORR_A 0x00200000
+#define PI_ERR_SYSSTATE_TAG_B 0x00400000 /* SysState tag parity error */
+#define PI_ERR_SYSSTATE_TAG_A 0x00800000
+#define PI_ERR_MD_UNCORR 0x01000000 /* Must be cleared in MD */
+
+#define PI_ERR_CLEAR_ALL_A 0x00aaaaaa
+#define PI_ERR_CLEAR_ALL_B 0x00555555
+
+
+/*
+ * The following three macros define all possible error int pends.
+ */
+
+#define PI_FATAL_ERR_CPU_A (PI_ERR_SYSSTATE_TAG_A | \
+ PI_ERR_BAD_SPOOL_A | \
+ PI_ERR_SYSCMD_ADDR_A | \
+ PI_ERR_SYSCMD_DATA_A | \
+ PI_ERR_SYSAD_ADDR_A | \
+ PI_ERR_SYSAD_DATA_A | \
+ PI_ERR_SYSSTATE_A)
+
+#define PI_MISC_ERR_CPU_A (PI_ERR_UNCAC_UNCORR_A | \
+ PI_ERR_WRB_WERR_A | \
+ PI_ERR_WRB_TERR_A | \
+ PI_ERR_SPUR_MSG_A | \
+ PI_ERR_SPOOL_CMP_A)
+
+#define PI_FATAL_ERR_CPU_B (PI_ERR_SYSSTATE_TAG_B | \
+ PI_ERR_BAD_SPOOL_B | \
+ PI_ERR_SYSCMD_ADDR_B | \
+ PI_ERR_SYSCMD_DATA_B | \
+ PI_ERR_SYSAD_ADDR_B | \
+ PI_ERR_SYSAD_DATA_B | \
+ PI_ERR_SYSSTATE_B)
+
+#define PI_MISC_ERR_CPU_B (PI_ERR_UNCAC_UNCORR_B | \
+ PI_ERR_WRB_WERR_B | \
+ PI_ERR_WRB_TERR_B | \
+ PI_ERR_SPUR_MSG_B | \
+ PI_ERR_SPOOL_CMP_B)
+
+#define PI_ERR_GENERIC (PI_ERR_MD_UNCORR)
+
+/*
+ * Error types for PI_ERR_STATUS0_[AB] and error stack:
+ * Use the write types if WRBRRB is 1 else use the read types
+ */
+
+/* Fields in PI_ERR_STATUS0_[AB] */
+#define PI_ERR_ST0_TYPE_MASK 0x0000000000000007
+#define PI_ERR_ST0_TYPE_SHFT 0
+#define PI_ERR_ST0_REQNUM_MASK 0x0000000000000038
+#define PI_ERR_ST0_REQNUM_SHFT 3
+#define PI_ERR_ST0_SUPPL_MASK 0x000000000001ffc0
+#define PI_ERR_ST0_SUPPL_SHFT 6
+#define PI_ERR_ST0_CMD_MASK 0x0000000001fe0000
+#define PI_ERR_ST0_CMD_SHFT 17
+#define PI_ERR_ST0_ADDR_MASK 0x3ffffffffe000000
+#define PI_ERR_ST0_ADDR_SHFT 25
+#define PI_ERR_ST0_OVERRUN_MASK 0x4000000000000000
+#define PI_ERR_ST0_OVERRUN_SHFT 62
+#define PI_ERR_ST0_VALID_MASK 0x8000000000000000
+#define PI_ERR_ST0_VALID_SHFT 63
+
+/* Fields in PI_ERR_STATUS1_[AB] */
+#define PI_ERR_ST1_SPOOL_MASK 0x00000000001fffff
+#define PI_ERR_ST1_SPOOL_SHFT 0
+#define PI_ERR_ST1_TOUTCNT_MASK 0x000000001fe00000
+#define PI_ERR_ST1_TOUTCNT_SHFT 21
+#define PI_ERR_ST1_INVCNT_MASK 0x0000007fe0000000
+#define PI_ERR_ST1_INVCNT_SHFT 29
+#define PI_ERR_ST1_CRBNUM_MASK 0x0000038000000000
+#define PI_ERR_ST1_CRBNUM_SHFT 39
+#define PI_ERR_ST1_WRBRRB_MASK 0x0000040000000000
+#define PI_ERR_ST1_WRBRRB_SHFT 42
+#define PI_ERR_ST1_CRBSTAT_MASK 0x001ff80000000000
+#define PI_ERR_ST1_CRBSTAT_SHFT 43
+#define PI_ERR_ST1_MSGSRC_MASK 0xffe0000000000000
+#define PI_ERR_ST1_MSGSRC_SHFT 53
+
+/* Fields in the error stack */
+#define PI_ERR_STK_TYPE_MASK 0x0000000000000003
+#define PI_ERR_STK_TYPE_SHFT 0
+#define PI_ERR_STK_SUPPL_MASK 0x0000000000000038
+#define PI_ERR_STK_SUPPL_SHFT 3
+#define PI_ERR_STK_REQNUM_MASK 0x00000000000001c0
+#define PI_ERR_STK_REQNUM_SHFT 6
+#define PI_ERR_STK_CRBNUM_MASK 0x0000000000000e00
+#define PI_ERR_STK_CRBNUM_SHFT 9
+#define PI_ERR_STK_WRBRRB_MASK 0x0000000000001000
+#define PI_ERR_STK_WRBRRB_SHFT 12
+#define PI_ERR_STK_CRBSTAT_MASK 0x00000000007fe000
+#define PI_ERR_STK_CRBSTAT_SHFT 13
+#define PI_ERR_STK_CMD_MASK 0x000000007f800000
+#define PI_ERR_STK_CMD_SHFT 23
+#define PI_ERR_STK_ADDR_MASK 0xffffffff80000000
+#define PI_ERR_STK_ADDR_SHFT 31
+
+/* Error type in the error status or stack on Read CRBs */
+#define PI_ERR_RD_PRERR 1
+#define PI_ERR_RD_DERR 2
+#define PI_ERR_RD_TERR 3
+
+/* Error type in the error status or stack on Write CRBs */
+#define PI_ERR_WR_WERR 0
+#define PI_ERR_WR_PWERR 1
+#define PI_ERR_WR_TERR 3
+
+/* Read or Write CRB in error status or stack */
+#define PI_ERR_RRB 0
+#define PI_ERR_WRB 1
+#define PI_ERR_ANY_CRB 2
+
+/* Address masks in the error status and error stack are not the same */
+#define ERR_STK_ADDR_SHFT 7
+#define ERR_STAT0_ADDR_SHFT 3
+
+#define PI_MIN_STACK_SIZE 4096 /* For figuring out the size to set */
+#define PI_STACK_SIZE_SHFT 12 /* 4k */
+
+#define ERR_STACK_SIZE_BYTES(_sz) \
+ ((_sz) ? (PI_MIN_STACK_SIZE << ((_sz) - 1)) : 0)
+
+#ifndef __ASSEMBLY__
+/*
+ * format of error stack and error status registers.
+ */
+
+struct err_stack_format {
+ u64 sk_addr : 33, /* address */
+ sk_cmd : 8, /* message command */
+ sk_crb_sts : 10, /* status from RRB or WRB */
+ sk_rw_rb : 1, /* RRB == 0, WRB == 1 */
+ sk_crb_num : 3, /* WRB (0 to 7) or RRB (0 to 4) */
+ sk_t5_req : 3, /* RRB T5 request number */
+ sk_suppl : 3, /* lowest 3 bit of supplemental */
+ sk_err_type: 3; /* error type */
+};
+
+typedef union pi_err_stack {
+ u64 pi_stk_word;
+ struct err_stack_format pi_stk_fmt;
+} pi_err_stack_t;
+
+struct err_status0_format {
+ u64 s0_valid : 1, /* Valid */
+ s0_ovr_run : 1, /* Overrun, spooled to memory */
+ s0_addr : 37, /* address */
+ s0_cmd : 8, /* message command */
+ s0_supl : 11, /* message supplemental field */
+ s0_t5_req : 3, /* RRB T5 request number */
+ s0_err_type: 3; /* error type */
+};
+
+typedef union pi_err_stat0 {
+ u64 pi_stat0_word;
+ struct err_status0_format pi_stat0_fmt;
+} pi_err_stat0_t;
+
+struct err_status1_format {
+ u64 s1_src : 11, /* message source */
+ s1_crb_sts : 10, /* status from RRB or WRB */
+ s1_rw_rb : 1, /* RRB == 0, WRB == 1 */
+ s1_crb_num : 3, /* WRB (0 to 7) or RRB (0 to 4) */
+ s1_inval_cnt:10, /* signed invalidate counter RRB */
+ s1_to_cnt : 8, /* crb timeout counter */
+ s1_spl_cnt : 21; /* number spooled to memory */
+};
+
+typedef union pi_err_stat1 {
+ u64 pi_stat1_word;
+ struct err_status1_format pi_stat1_fmt;
+} pi_err_stat1_t;
+
+typedef u64 rtc_time_t;
+
+#endif /* !__ASSEMBLY__ */
+
+
+/* Bits in PI_SYSAD_ERRCHK_EN */
+#define PI_SYSAD_ERRCHK_ECCGEN 0x01 /* Enable ECC generation */
+#define PI_SYSAD_ERRCHK_QUALGEN 0x02 /* Enable data quality signal gen. */
+#define PI_SYSAD_ERRCHK_SADP 0x04 /* Enable SysAD parity checking */
+#define PI_SYSAD_ERRCHK_CMDP 0x08 /* Enable SysCmd parity checking */
+#define PI_SYSAD_ERRCHK_STATE 0x10 /* Enable SysState parity checking */
+#define PI_SYSAD_ERRCHK_QUAL 0x20 /* Enable data quality checking */
+#define PI_SYSAD_CHECK_ALL 0x3f /* Generate and check all signals. */
+
+/* Interrupt pending bits on R10000 */
+
+#define HUB_IP_PEND0 0x0400
+#define HUB_IP_PEND1_CC 0x0800
+#define HUB_IP_RT 0x1000
+#define HUB_IP_PROF 0x2000
+#define HUB_IP_ERROR 0x4000
+#define HUB_IP_MASK 0x7c00
+
+/* PI_RT_LOCAL_CTRL mask and shift definitions */
+
+#define PRLC_USE_INT_SHFT 16
+#define PRLC_USE_INT_MASK (UINT64_CAST 1 << 16)
+#define PRLC_USE_INT (UINT64_CAST 1 << 16)
+#define PRLC_GCLK_SHFT 15
+#define PRLC_GCLK_MASK (UINT64_CAST 1 << 15)
+#define PRLC_GCLK (UINT64_CAST 1 << 15)
+#define PRLC_GCLK_COUNT_SHFT 8
+#define PRLC_GCLK_COUNT_MASK (UINT64_CAST 0x7f << 8)
+#define PRLC_MAX_COUNT_SHFT 1
+#define PRLC_MAX_COUNT_MASK (UINT64_CAST 0x7f << 1)
+#define PRLC_GCLK_EN_SHFT 0
+#define PRLC_GCLK_EN_MASK (UINT64_CAST 1)
+#define PRLC_GCLK_EN (UINT64_CAST 1)
+
+/* PI_RT_FILTER_CTRL mask and shift definitions */
+
+/*
+ * Bits for NACK_CNT_A/B and NACK_CMP
+ */
+#define PI_NACK_CNT_EN_SHFT 20
+#define PI_NACK_CNT_EN_MASK 0x100000
+#define PI_NACK_CNT_MASK 0x0fffff
+#define PI_NACK_CNT_MAX 0x0fffff
+
+#endif /* _ASM_SN_SN0_HUBPI_H */
diff --git a/arch/mips/include/asm/sn/sn0/ip27.h b/arch/mips/include/asm/sn/sn0/ip27.h
new file mode 100644
index 00000000..3c97e085
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn0/ip27.h
@@ -0,0 +1,85 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Derived from IRIX <sys/SN/SN0/IP27.h>.
+ *
+ * Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999, 2006 by Ralf Baechle
+ */
+#ifndef _ASM_SN_SN0_IP27_H
+#define _ASM_SN_SN0_IP27_H
+
+#include <asm/mipsregs.h>
+
+/*
+ * Simple definitions for the masks which remove SW bits from pte.
+ */
+
+#define TLBLO_HWBITSHIFT 0 /* Shift value, for masking */
+
+#ifndef __ASSEMBLY__
+
+#define CAUSE_BERRINTR IE_IRQ5
+
+#define ECCF_CACHE_ERR 0
+#define ECCF_TAGLO 1
+#define ECCF_ECC 2
+#define ECCF_ERROREPC 3
+#define ECCF_PADDR 4
+#define ECCF_SIZE (5 * sizeof(long))
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef __ASSEMBLY__
+
+/*
+ * KL_GET_CPUNUM (similar to EV_GET_SPNUM for EVEREST platform) reads
+ * the processor number of the calling processor. The proc parameters
+ * must be a register.
+ */
+#define KL_GET_CPUNUM(proc) \
+ dli proc, LOCAL_HUB(0); \
+ ld proc, PI_CPU_NUM(proc)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * R10000 status register interrupt bit mask usage for IP27.
+ */
+#define SRB_SWTIMO IE_SW0 /* 0x0100 */
+#define SRB_NET IE_SW1 /* 0x0200 */
+#define SRB_DEV0 IE_IRQ0 /* 0x0400 */
+#define SRB_DEV1 IE_IRQ1 /* 0x0800 */
+#define SRB_TIMOCLK IE_IRQ2 /* 0x1000 */
+#define SRB_PROFCLK IE_IRQ3 /* 0x2000 */
+#define SRB_ERR IE_IRQ4 /* 0x4000 */
+#define SRB_SCHEDCLK IE_IRQ5 /* 0x8000 */
+
+#define SR_IBIT_HI SRB_DEV0
+#define SR_IBIT_PROF SRB_PROFCLK
+
+#define SRB_SWTIMO_IDX 0
+#define SRB_NET_IDX 1
+#define SRB_DEV0_IDX 2
+#define SRB_DEV1_IDX 3
+#define SRB_TIMOCLK_IDX 4
+#define SRB_PROFCLK_IDX 5
+#define SRB_ERR_IDX 6
+#define SRB_SCHEDCLK_IDX 7
+
+#define NUM_CAUSE_INTRS 8
+
+#define SCACHE_LINESIZE 128
+#define SCACHE_LINEMASK (SCACHE_LINESIZE - 1)
+
+#include <asm/sn/addrs.h>
+
+#define LED_CYCLE_MASK 0x0f
+#define LED_CYCLE_SHFT 4
+
+#define SEND_NMI(_nasid, _slice) \
+ REMOTE_HUB_S((_nasid), (PI_NMI_A + ((_slice) * PI_NMI_OFFSET)), 1)
+
+#endif /* _ASM_SN_SN0_IP27_H */
diff --git a/arch/mips/include/asm/sn/sn_private.h b/arch/mips/include/asm/sn/sn_private.h
new file mode 100644
index 00000000..1a2c3025
--- /dev/null
+++ b/arch/mips/include/asm/sn/sn_private.h
@@ -0,0 +1,19 @@
+#ifndef __ASM_SN_SN_PRIVATE_H
+#define __ASM_SN_SN_PRIVATE_H
+
+#include <asm/sn/types.h>
+
+extern nasid_t master_nasid;
+
+extern void cpu_node_probe(void);
+extern cnodeid_t get_compact_nodeid(void);
+extern void hub_rtc_init(cnodeid_t);
+extern void cpu_time_init(void);
+extern void per_cpu_init(void);
+extern void install_cpu_nmi_handler(int slice);
+extern void install_ipi(void);
+extern void setup_replication_mask(void);
+extern void replicate_kernel_text(void);
+extern pfn_t node_getfirstfree(cnodeid_t);
+
+#endif /* __ASM_SN_SN_PRIVATE_H */
diff --git a/arch/mips/include/asm/sn/types.h b/arch/mips/include/asm/sn/types.h
new file mode 100644
index 00000000..74d0bb26
--- /dev/null
+++ b/arch/mips/include/asm/sn/types.h
@@ -0,0 +1,26 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Ralf Baechle
+ */
+#ifndef _ASM_SN_TYPES_H
+#define _ASM_SN_TYPES_H
+
+#include <linux/types.h>
+
+typedef unsigned long cpuid_t;
+typedef unsigned long cnodemask_t;
+typedef signed short nasid_t; /* node id in numa-as-id space */
+typedef signed short cnodeid_t; /* node id in compact-id space */
+typedef signed char partid_t; /* partition ID type */
+typedef signed short moduleid_t; /* user-visible module number type */
+typedef signed short cmoduleid_t; /* kernel compact module id type */
+typedef unsigned char clusterid_t; /* Clusterid of the cell */
+typedef unsigned long pfn_t;
+
+typedef dev_t vertex_hdl_t; /* hardware graph vertex handle */
+
+#endif /* _ASM_SN_TYPES_H */
diff --git a/arch/mips/include/asm/sni.h b/arch/mips/include/asm/sni.h
new file mode 100644
index 00000000..8c1eb02c
--- /dev/null
+++ b/arch/mips/include/asm/sni.h
@@ -0,0 +1,244 @@
+/*
+ * SNI specific definitions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998 by Ralf Baechle
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+#ifndef __ASM_SNI_H
+#define __ASM_SNI_H
+
+extern unsigned int sni_brd_type;
+
+#define SNI_BRD_10 2
+#define SNI_BRD_10NEW 3
+#define SNI_BRD_TOWER_OASIC 4
+#define SNI_BRD_MINITOWER 5
+#define SNI_BRD_PCI_TOWER 6
+#define SNI_BRD_RM200 7
+#define SNI_BRD_PCI_MTOWER 8
+#define SNI_BRD_PCI_DESKTOP 9
+#define SNI_BRD_PCI_TOWER_CPLUS 10
+#define SNI_BRD_PCI_MTOWER_CPLUS 11
+
+/* RM400 cpu types */
+#define SNI_CPU_M8021 0x01
+#define SNI_CPU_M8030 0x04
+#define SNI_CPU_M8031 0x06
+#define SNI_CPU_M8034 0x0f
+#define SNI_CPU_M8037 0x07
+#define SNI_CPU_M8040 0x05
+#define SNI_CPU_M8043 0x09
+#define SNI_CPU_M8050 0x0b
+#define SNI_CPU_M8053 0x0d
+
+#define SNI_PORT_BASE CKSEG1ADDR(0xb4000000)
+
+#ifndef __MIPSEL__
+/*
+ * ASIC PCI registers for big endian configuration.
+ */
+#define PCIMT_UCONF CKSEG1ADDR(0xbfff0004)
+#define PCIMT_IOADTIMEOUT2 CKSEG1ADDR(0xbfff000c)
+#define PCIMT_IOMEMCONF CKSEG1ADDR(0xbfff0014)
+#define PCIMT_IOMMU CKSEG1ADDR(0xbfff001c)
+#define PCIMT_IOADTIMEOUT1 CKSEG1ADDR(0xbfff0024)
+#define PCIMT_DMAACCESS CKSEG1ADDR(0xbfff002c)
+#define PCIMT_DMAHIT CKSEG1ADDR(0xbfff0034)
+#define PCIMT_ERRSTATUS CKSEG1ADDR(0xbfff003c)
+#define PCIMT_ERRADDR CKSEG1ADDR(0xbfff0044)
+#define PCIMT_SYNDROME CKSEG1ADDR(0xbfff004c)
+#define PCIMT_ITPEND CKSEG1ADDR(0xbfff0054)
+#define IT_INT2 0x01
+#define IT_INTD 0x02
+#define IT_INTC 0x04
+#define IT_INTB 0x08
+#define IT_INTA 0x10
+#define IT_EISA 0x20
+#define IT_SCSI 0x40
+#define IT_ETH 0x80
+#define PCIMT_IRQSEL CKSEG1ADDR(0xbfff005c)
+#define PCIMT_TESTMEM CKSEG1ADDR(0xbfff0064)
+#define PCIMT_ECCREG CKSEG1ADDR(0xbfff006c)
+#define PCIMT_CONFIG_ADDRESS CKSEG1ADDR(0xbfff0074)
+#define PCIMT_ASIC_ID CKSEG1ADDR(0xbfff007c) /* read */
+#define PCIMT_SOFT_RESET CKSEG1ADDR(0xbfff007c) /* write */
+#define PCIMT_PIA_OE CKSEG1ADDR(0xbfff0084)
+#define PCIMT_PIA_DATAOUT CKSEG1ADDR(0xbfff008c)
+#define PCIMT_PIA_DATAIN CKSEG1ADDR(0xbfff0094)
+#define PCIMT_CACHECONF CKSEG1ADDR(0xbfff009c)
+#define PCIMT_INVSPACE CKSEG1ADDR(0xbfff00a4)
+#else
+/*
+ * ASIC PCI registers for little endian configuration.
+ */
+#define PCIMT_UCONF CKSEG1ADDR(0xbfff0000)
+#define PCIMT_IOADTIMEOUT2 CKSEG1ADDR(0xbfff0008)
+#define PCIMT_IOMEMCONF CKSEG1ADDR(0xbfff0010)
+#define PCIMT_IOMMU CKSEG1ADDR(0xbfff0018)
+#define PCIMT_IOADTIMEOUT1 CKSEG1ADDR(0xbfff0020)
+#define PCIMT_DMAACCESS CKSEG1ADDR(0xbfff0028)
+#define PCIMT_DMAHIT CKSEG1ADDR(0xbfff0030)
+#define PCIMT_ERRSTATUS CKSEG1ADDR(0xbfff0038)
+#define PCIMT_ERRADDR CKSEG1ADDR(0xbfff0040)
+#define PCIMT_SYNDROME CKSEG1ADDR(0xbfff0048)
+#define PCIMT_ITPEND CKSEG1ADDR(0xbfff0050)
+#define IT_INT2 0x01
+#define IT_INTD 0x02
+#define IT_INTC 0x04
+#define IT_INTB 0x08
+#define IT_INTA 0x10
+#define IT_EISA 0x20
+#define IT_SCSI 0x40
+#define IT_ETH 0x80
+#define PCIMT_IRQSEL CKSEG1ADDR(0xbfff0058)
+#define PCIMT_TESTMEM CKSEG1ADDR(0xbfff0060)
+#define PCIMT_ECCREG CKSEG1ADDR(0xbfff0068)
+#define PCIMT_CONFIG_ADDRESS CKSEG1ADDR(0xbfff0070)
+#define PCIMT_ASIC_ID CKSEG1ADDR(0xbfff0078) /* read */
+#define PCIMT_SOFT_RESET CKSEG1ADDR(0xbfff0078) /* write */
+#define PCIMT_PIA_OE CKSEG1ADDR(0xbfff0080)
+#define PCIMT_PIA_DATAOUT CKSEG1ADDR(0xbfff0088)
+#define PCIMT_PIA_DATAIN CKSEG1ADDR(0xbfff0090)
+#define PCIMT_CACHECONF CKSEG1ADDR(0xbfff0098)
+#define PCIMT_INVSPACE CKSEG1ADDR(0xbfff00a0)
+#endif
+
+#define PCIMT_PCI_CONF CKSEG1ADDR(0xbfff0100)
+
+/*
+ * Data port for the PCI bus in IO space
+ */
+#define PCIMT_CONFIG_DATA 0x0cfc
+
+/*
+ * Board specific registers
+ */
+#define PCIMT_CSMSR CKSEG1ADDR(0xbfd00000)
+#define PCIMT_CSSWITCH CKSEG1ADDR(0xbfd10000)
+#define PCIMT_CSITPEND CKSEG1ADDR(0xbfd20000)
+#define PCIMT_AUTO_PO_EN CKSEG1ADDR(0xbfd30000)
+#define PCIMT_CLR_TEMP CKSEG1ADDR(0xbfd40000)
+#define PCIMT_AUTO_PO_DIS CKSEG1ADDR(0xbfd50000)
+#define PCIMT_EXMSR CKSEG1ADDR(0xbfd60000)
+#define PCIMT_UNUSED1 CKSEG1ADDR(0xbfd70000)
+#define PCIMT_CSWCSM CKSEG1ADDR(0xbfd80000)
+#define PCIMT_UNUSED2 CKSEG1ADDR(0xbfd90000)
+#define PCIMT_CSLED CKSEG1ADDR(0xbfda0000)
+#define PCIMT_CSMAPISA CKSEG1ADDR(0xbfdb0000)
+#define PCIMT_CSRSTBP CKSEG1ADDR(0xbfdc0000)
+#define PCIMT_CLRPOFF CKSEG1ADDR(0xbfdd0000)
+#define PCIMT_CSTIMER CKSEG1ADDR(0xbfde0000)
+#define PCIMT_PWDN CKSEG1ADDR(0xbfdf0000)
+
+/*
+ * A20R based boards
+ */
+#define A20R_PT_CLOCK_BASE CKSEG1ADDR(0xbc040000)
+#define A20R_PT_TIM0_ACK CKSEG1ADDR(0xbc050000)
+#define A20R_PT_TIM1_ACK CKSEG1ADDR(0xbc060000)
+
+#define SNI_A20R_IRQ_BASE MIPS_CPU_IRQ_BASE
+#define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5)
+
+#define SNI_PCIT_INT_REG CKSEG1ADDR(0xbfff000c)
+
+#define SNI_PCIT_INT_START 24
+#define SNI_PCIT_INT_END 30
+
+#define PCIT_IRQ_ETHERNET (MIPS_CPU_IRQ_BASE + 5)
+#define PCIT_IRQ_INTA (SNI_PCIT_INT_START + 0)
+#define PCIT_IRQ_INTB (SNI_PCIT_INT_START + 1)
+#define PCIT_IRQ_INTC (SNI_PCIT_INT_START + 2)
+#define PCIT_IRQ_INTD (SNI_PCIT_INT_START + 3)
+#define PCIT_IRQ_SCSI0 (SNI_PCIT_INT_START + 4)
+#define PCIT_IRQ_SCSI1 (SNI_PCIT_INT_START + 5)
+
+
+/*
+ * Interrupt 0-16 are EISA interrupts. Interrupts from 16 on are assigned
+ * to the other interrupts generated by ASIC PCI.
+ *
+ * INT2 is a wired-or of the push button interrupt, high temperature interrupt
+ * ASIC PCI interrupt.
+ */
+#define PCIMT_KEYBOARD_IRQ 1
+#define PCIMT_IRQ_INT2 24
+#define PCIMT_IRQ_INTD 25
+#define PCIMT_IRQ_INTC 26
+#define PCIMT_IRQ_INTB 27
+#define PCIMT_IRQ_INTA 28
+#define PCIMT_IRQ_EISA 29
+#define PCIMT_IRQ_SCSI 30
+
+#define PCIMT_IRQ_ETHERNET (MIPS_CPU_IRQ_BASE+6)
+
+#if 0
+#define PCIMT_IRQ_TEMPERATURE 24
+#define PCIMT_IRQ_EISA_NMI 25
+#define PCIMT_IRQ_POWER_OFF 26
+#define PCIMT_IRQ_BUTTON 27
+#endif
+
+/*
+ * Base address for the mapped 16mb EISA bus segment.
+ */
+#define PCIMT_EISA_BASE CKSEG1ADDR(0xb0000000)
+
+/* PCI EISA Interrupt acknowledge */
+#define PCIMT_INT_ACKNOWLEDGE CKSEG1ADDR(0xba000000)
+
+/*
+ * SNI ID PROM
+ *
+ * SNI_IDPROM_MEMSIZE Memsize in 16MB quantities
+ * SNI_IDPROM_BRDTYPE Board Type
+ * SNI_IDPROM_CPUTYPE CPU Type on RM400
+ */
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define __SNI_END 0
+#endif
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define __SNI_END 3
+#endif
+#define SNI_IDPROM_BASE CKSEG1ADDR(0x1ff00000)
+#define SNI_IDPROM_MEMSIZE (SNI_IDPROM_BASE + (0x28 ^ __SNI_END))
+#define SNI_IDPROM_BRDTYPE (SNI_IDPROM_BASE + (0x29 ^ __SNI_END))
+#define SNI_IDPROM_CPUTYPE (SNI_IDPROM_BASE + (0x30 ^ __SNI_END))
+
+#define SNI_IDPROM_SIZE 0x1000
+
+/* board specific init functions */
+extern void sni_a20r_init(void);
+extern void sni_pcit_init(void);
+extern void sni_rm200_init(void);
+extern void sni_pcimt_init(void);
+
+/* board specific irq init functions */
+extern void sni_a20r_irq_init(void);
+extern void sni_pcit_irq_init(void);
+extern void sni_pcit_cplus_irq_init(void);
+extern void sni_rm200_irq_init(void);
+extern void sni_pcimt_irq_init(void);
+
+/* timer inits */
+extern void sni_cpu_time_init(void);
+
+/* eisa init for RM200/400 */
+#ifdef CONFIG_EISA
+extern int sni_eisa_root_init(void);
+#else
+static inline int sni_eisa_root_init(void)
+{
+ return 0;
+}
+#endif
+
+/* common irq stuff */
+extern void (*sni_hwint)(void);
+extern struct irqaction sni_isa_irq;
+
+#endif /* __ASM_SNI_H */
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
new file mode 100644
index 00000000..9de5190f
--- /dev/null
+++ b/arch/mips/include/asm/socket.h
@@ -0,0 +1,124 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1999, 2000, 2001 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/*
+ * For setsockopt(2)
+ *
+ * This defines are ABI conformant as far as Linux supports these ...
+ */
+#define SOL_SOCKET 0xffff
+
+#define SO_DEBUG 0x0001 /* Record debugging information. */
+#define SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */
+#define SO_KEEPALIVE 0x0008 /* Keep connections alive and send
+ SIGPIPE when they die. */
+#define SO_DONTROUTE 0x0010 /* Don't do local routing. */
+#define SO_BROADCAST 0x0020 /* Allow transmission of
+ broadcast messages. */
+#define SO_LINGER 0x0080 /* Block on close of a reliable
+ socket to transmit pending data. */
+#define SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band. */
+#if 0
+To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
+#endif
+
+#define SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */
+#define SO_STYLE SO_TYPE /* Synonym */
+#define SO_ERROR 0x1007 /* get error status and clear */
+#define SO_SNDBUF 0x1001 /* Send buffer size. */
+#define SO_RCVBUF 0x1002 /* Receive buffer. */
+#define SO_SNDLOWAT 0x1003 /* send low-water mark */
+#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
+#define SO_SNDTIMEO 0x1005 /* send timeout */
+#define SO_RCVTIMEO 0x1006 /* receive timeout */
+#define SO_ACCEPTCONN 0x1009
+#define SO_PROTOCOL 0x1028 /* protocol type */
+#define SO_DOMAIN 0x1029 /* domain/socket family */
+
+/* linux-specific, might as well be the same as on i386 */
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_BSDCOMPAT 14
+
+#define SO_PASSCRED 17
+#define SO_PEERCRED 18
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_PEERSEC 30
+#define SO_SNDBUFFORCE 31
+#define SO_RCVBUFFORCE 33
+#define SO_PASSSEC 34
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+
+#define SO_MARK 36
+
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#define SO_RXQ_OVFL 40
+
+#ifdef __KERNEL__
+
+/** sock_type - Socket types
+ *
+ * Please notice that for binary compat reasons MIPS has to
+ * override the enum sock_type in include/linux/net.h, so
+ * we define ARCH_HAS_SOCKET_TYPES here.
+ *
+ * @SOCK_DGRAM - datagram (conn.less) socket
+ * @SOCK_STREAM - stream (connection) socket
+ * @SOCK_RAW - raw socket
+ * @SOCK_RDM - reliably-delivered message
+ * @SOCK_SEQPACKET - sequential packet socket
+ * @SOCK_PACKET - linux specific way of getting packets at the dev level.
+ * For writing rarp and other similar things on the user level.
+ */
+enum sock_type {
+ SOCK_DGRAM = 1,
+ SOCK_STREAM = 2,
+ SOCK_RAW = 3,
+ SOCK_RDM = 4,
+ SOCK_SEQPACKET = 5,
+ SOCK_DCCP = 6,
+ SOCK_PACKET = 10,
+};
+
+#define SOCK_MAX (SOCK_PACKET + 1)
+/* Mask which covers at least up to SOCK_MASK-1. The
+ * * remaining bits are used as flags. */
+#define SOCK_TYPE_MASK 0xf
+
+/* Flags for socket, socketpair, paccept */
+#define SOCK_CLOEXEC O_CLOEXEC
+#define SOCK_NONBLOCK O_NONBLOCK
+
+#define ARCH_HAS_SOCKET_TYPES 1
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SOCKET_H */
diff --git a/arch/mips/include/asm/sockios.h b/arch/mips/include/asm/sockios.h
new file mode 100644
index 00000000..ed1a5f78
--- /dev/null
+++ b/arch/mips/include/asm/sockios.h
@@ -0,0 +1,26 @@
+/*
+ * Socket-level I/O control calls.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 by Ralf Baechle
+ */
+#ifndef _ASM_SOCKIOS_H
+#define _ASM_SOCKIOS_H
+
+#include <asm/ioctl.h>
+
+/* Socket-level I/O control calls. */
+#define FIOGETOWN _IOR('f', 123, int)
+#define FIOSETOWN _IOW('f', 124, int)
+
+#define SIOCATMARK _IOR('s', 7, int)
+#define SIOCSPGRP _IOW('s', 8, pid_t)
+#define SIOCGPGRP _IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
+#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
+
+#endif /* _ASM_SOCKIOS_H */
diff --git a/arch/mips/include/asm/sparsemem.h b/arch/mips/include/asm/sparsemem.h
new file mode 100644
index 00000000..7165333a
--- /dev/null
+++ b/arch/mips/include/asm/sparsemem.h
@@ -0,0 +1,13 @@
+#ifndef _MIPS_SPARSEMEM_H
+#define _MIPS_SPARSEMEM_H
+#ifdef CONFIG_SPARSEMEM
+
+/*
+ * SECTION_SIZE_BITS 2^N: how big each section will be
+ * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
+ */
+#define SECTION_SIZE_BITS 28
+#define MAX_PHYSMEM_BITS 35
+
+#endif /* CONFIG_SPARSEMEM */
+#endif /* _MIPS_SPARSEMEM_H */
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h
new file mode 100644
index 00000000..ca61e846
--- /dev/null
+++ b/arch/mips/include/asm/spinlock.h
@@ -0,0 +1,458 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_SPINLOCK_H
+#define _ASM_SPINLOCK_H
+
+#include <linux/compiler.h>
+
+#include <asm/barrier.h>
+#include <asm/war.h>
+
+/*
+ * Your basic SMP spinlocks, allowing only a single CPU anywhere
+ *
+ * Simple spin lock operations. There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * These are fair FIFO ticket locks
+ *
+ * (the type definitions are in asm/spinlock_types.h)
+ */
+
+
+/*
+ * Ticket locks are conceptually two parts, one indicating the current head of
+ * the queue, and the other indicating the current tail. The lock is acquired
+ * by atomically noting the tail and incrementing it by one (thus adding
+ * ourself to the queue and noting our position), then waiting until the head
+ * becomes equal to the the initial value of the tail.
+ */
+
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+ u32 counters = ACCESS_ONCE(lock->lock);
+
+ return ((counters >> 16) ^ counters) & 0xffff;
+}
+
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+#define arch_spin_unlock_wait(x) \
+ while (arch_spin_is_locked(x)) { cpu_relax(); }
+
+static inline int arch_spin_is_contended(arch_spinlock_t *lock)
+{
+ u32 counters = ACCESS_ONCE(lock->lock);
+
+ return (((counters >> 16) - counters) & 0xffff) > 1;
+}
+#define arch_spin_is_contended arch_spin_is_contended
+
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+ int my_ticket;
+ int tmp;
+ int inc = 0x10000;
+
+ if (R10000_LLSC_WAR) {
+ __asm__ __volatile__ (
+ " .set push # arch_spin_lock \n"
+ " .set noreorder \n"
+ " \n"
+ "1: ll %[ticket], %[ticket_ptr] \n"
+ " addu %[my_ticket], %[ticket], %[inc] \n"
+ " sc %[my_ticket], %[ticket_ptr] \n"
+ " beqzl %[my_ticket], 1b \n"
+ " nop \n"
+ " srl %[my_ticket], %[ticket], 16 \n"
+ " andi %[ticket], %[ticket], 0xffff \n"
+ " andi %[my_ticket], %[my_ticket], 0xffff \n"
+ " bne %[ticket], %[my_ticket], 4f \n"
+ " subu %[ticket], %[my_ticket], %[ticket] \n"
+ "2: \n"
+ " .subsection 2 \n"
+ "4: andi %[ticket], %[ticket], 0xffff \n"
+ " sll %[ticket], 5 \n"
+ " \n"
+ "6: bnez %[ticket], 6b \n"
+ " subu %[ticket], 1 \n"
+ " \n"
+ " lhu %[ticket], %[serving_now_ptr] \n"
+ " beq %[ticket], %[my_ticket], 2b \n"
+ " subu %[ticket], %[my_ticket], %[ticket] \n"
+ " b 4b \n"
+ " subu %[ticket], %[ticket], 1 \n"
+ " .previous \n"
+ " .set pop \n"
+ : [ticket_ptr] "+m" (lock->lock),
+ [serving_now_ptr] "+m" (lock->h.serving_now),
+ [ticket] "=&r" (tmp),
+ [my_ticket] "=&r" (my_ticket)
+ : [inc] "r" (inc));
+ } else {
+ __asm__ __volatile__ (
+ " .set push # arch_spin_lock \n"
+ " .set noreorder \n"
+ " \n"
+ "1: ll %[ticket], %[ticket_ptr] \n"
+ " addu %[my_ticket], %[ticket], %[inc] \n"
+ " sc %[my_ticket], %[ticket_ptr] \n"
+ " beqz %[my_ticket], 1b \n"
+ " srl %[my_ticket], %[ticket], 16 \n"
+ " andi %[ticket], %[ticket], 0xffff \n"
+ " andi %[my_ticket], %[my_ticket], 0xffff \n"
+ " bne %[ticket], %[my_ticket], 4f \n"
+ " subu %[ticket], %[my_ticket], %[ticket] \n"
+ "2: \n"
+ " .subsection 2 \n"
+ "4: andi %[ticket], %[ticket], 0x1fff \n"
+ " sll %[ticket], 5 \n"
+ " \n"
+ "6: bnez %[ticket], 6b \n"
+ " subu %[ticket], 1 \n"
+ " \n"
+ " lhu %[ticket], %[serving_now_ptr] \n"
+ " beq %[ticket], %[my_ticket], 2b \n"
+ " subu %[ticket], %[my_ticket], %[ticket] \n"
+ " b 4b \n"
+ " subu %[ticket], %[ticket], 1 \n"
+ " .previous \n"
+ " .set pop \n"
+ : [ticket_ptr] "+m" (lock->lock),
+ [serving_now_ptr] "+m" (lock->h.serving_now),
+ [ticket] "=&r" (tmp),
+ [my_ticket] "=&r" (my_ticket)
+ : [inc] "r" (inc));
+ }
+
+ smp_llsc_mb();
+}
+
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ unsigned int serving_now = lock->h.serving_now + 1;
+ wmb();
+ lock->h.serving_now = (u16)serving_now;
+ nudge_writes();
+}
+
+static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock)
+{
+ int tmp, tmp2, tmp3;
+ int inc = 0x10000;
+
+ if (R10000_LLSC_WAR) {
+ __asm__ __volatile__ (
+ " .set push # arch_spin_trylock \n"
+ " .set noreorder \n"
+ " \n"
+ "1: ll %[ticket], %[ticket_ptr] \n"
+ " srl %[my_ticket], %[ticket], 16 \n"
+ " andi %[my_ticket], %[my_ticket], 0xffff \n"
+ " andi %[now_serving], %[ticket], 0xffff \n"
+ " bne %[my_ticket], %[now_serving], 3f \n"
+ " addu %[ticket], %[ticket], %[inc] \n"
+ " sc %[ticket], %[ticket_ptr] \n"
+ " beqzl %[ticket], 1b \n"
+ " li %[ticket], 1 \n"
+ "2: \n"
+ " .subsection 2 \n"
+ "3: b 2b \n"
+ " li %[ticket], 0 \n"
+ " .previous \n"
+ " .set pop \n"
+ : [ticket_ptr] "+m" (lock->lock),
+ [ticket] "=&r" (tmp),
+ [my_ticket] "=&r" (tmp2),
+ [now_serving] "=&r" (tmp3)
+ : [inc] "r" (inc));
+ } else {
+ __asm__ __volatile__ (
+ " .set push # arch_spin_trylock \n"
+ " .set noreorder \n"
+ " \n"
+ "1: ll %[ticket], %[ticket_ptr] \n"
+ " srl %[my_ticket], %[ticket], 16 \n"
+ " andi %[my_ticket], %[my_ticket], 0xffff \n"
+ " andi %[now_serving], %[ticket], 0xffff \n"
+ " bne %[my_ticket], %[now_serving], 3f \n"
+ " addu %[ticket], %[ticket], %[inc] \n"
+ " sc %[ticket], %[ticket_ptr] \n"
+ " beqz %[ticket], 1b \n"
+ " li %[ticket], 1 \n"
+ "2: \n"
+ " .subsection 2 \n"
+ "3: b 2b \n"
+ " li %[ticket], 0 \n"
+ " .previous \n"
+ " .set pop \n"
+ : [ticket_ptr] "+m" (lock->lock),
+ [ticket] "=&r" (tmp),
+ [my_ticket] "=&r" (tmp2),
+ [now_serving] "=&r" (tmp3)
+ : [inc] "r" (inc));
+ }
+
+ smp_llsc_mb();
+
+ return tmp;
+}
+
+/*
+ * Read-write spinlocks, allowing multiple readers but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts but no interrupt
+ * writers. For those circumstances we can "mix" irq-safe locks - any writer
+ * needs to get a irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+
+/*
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define arch_read_can_lock(rw) ((rw)->lock >= 0)
+
+/*
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define arch_write_can_lock(rw) (!(rw)->lock)
+
+static inline void arch_read_lock(arch_rwlock_t *rw)
+{
+ unsigned int tmp;
+
+ if (R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set noreorder # arch_read_lock \n"
+ "1: ll %1, %2 \n"
+ " bltz %1, 1b \n"
+ " addu %1, 1 \n"
+ " sc %1, %0 \n"
+ " beqzl %1, 1b \n"
+ " nop \n"
+ " .set reorder \n"
+ : "=m" (rw->lock), "=&r" (tmp)
+ : "m" (rw->lock)
+ : "memory");
+ } else {
+ __asm__ __volatile__(
+ " .set noreorder # arch_read_lock \n"
+ "1: ll %1, %2 \n"
+ " bltz %1, 3f \n"
+ " addu %1, 1 \n"
+ "2: sc %1, %0 \n"
+ " beqz %1, 1b \n"
+ " nop \n"
+ " .subsection 2 \n"
+ "3: ll %1, %2 \n"
+ " bltz %1, 3b \n"
+ " addu %1, 1 \n"
+ " b 2b \n"
+ " nop \n"
+ " .previous \n"
+ " .set reorder \n"
+ : "=m" (rw->lock), "=&r" (tmp)
+ : "m" (rw->lock)
+ : "memory");
+ }
+
+ smp_llsc_mb();
+}
+
+/* Note the use of sub, not subu which will make the kernel die with an
+ overflow exception if we ever try to unlock an rwlock that is already
+ unlocked or is being held by a writer. */
+static inline void arch_read_unlock(arch_rwlock_t *rw)
+{
+ unsigned int tmp;
+
+ smp_mb__before_llsc();
+
+ if (R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ "1: ll %1, %2 # arch_read_unlock \n"
+ " sub %1, 1 \n"
+ " sc %1, %0 \n"
+ " beqzl %1, 1b \n"
+ : "=m" (rw->lock), "=&r" (tmp)
+ : "m" (rw->lock)
+ : "memory");
+ } else {
+ __asm__ __volatile__(
+ " .set noreorder # arch_read_unlock \n"
+ "1: ll %1, %2 \n"
+ " sub %1, 1 \n"
+ " sc %1, %0 \n"
+ " beqz %1, 2f \n"
+ " nop \n"
+ " .subsection 2 \n"
+ "2: b 1b \n"
+ " nop \n"
+ " .previous \n"
+ " .set reorder \n"
+ : "=m" (rw->lock), "=&r" (tmp)
+ : "m" (rw->lock)
+ : "memory");
+ }
+}
+
+static inline void arch_write_lock(arch_rwlock_t *rw)
+{
+ unsigned int tmp;
+
+ if (R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set noreorder # arch_write_lock \n"
+ "1: ll %1, %2 \n"
+ " bnez %1, 1b \n"
+ " lui %1, 0x8000 \n"
+ " sc %1, %0 \n"
+ " beqzl %1, 1b \n"
+ " nop \n"
+ " .set reorder \n"
+ : "=m" (rw->lock), "=&r" (tmp)
+ : "m" (rw->lock)
+ : "memory");
+ } else {
+ __asm__ __volatile__(
+ " .set noreorder # arch_write_lock \n"
+ "1: ll %1, %2 \n"
+ " bnez %1, 3f \n"
+ " lui %1, 0x8000 \n"
+ "2: sc %1, %0 \n"
+ " beqz %1, 3f \n"
+ " nop \n"
+ " .subsection 2 \n"
+ "3: ll %1, %2 \n"
+ " bnez %1, 3b \n"
+ " lui %1, 0x8000 \n"
+ " b 2b \n"
+ " nop \n"
+ " .previous \n"
+ " .set reorder \n"
+ : "=m" (rw->lock), "=&r" (tmp)
+ : "m" (rw->lock)
+ : "memory");
+ }
+
+ smp_llsc_mb();
+}
+
+static inline void arch_write_unlock(arch_rwlock_t *rw)
+{
+ smp_mb();
+
+ __asm__ __volatile__(
+ " # arch_write_unlock \n"
+ " sw $0, %0 \n"
+ : "=m" (rw->lock)
+ : "m" (rw->lock)
+ : "memory");
+}
+
+static inline int arch_read_trylock(arch_rwlock_t *rw)
+{
+ unsigned int tmp;
+ int ret;
+
+ if (R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set noreorder # arch_read_trylock \n"
+ " li %2, 0 \n"
+ "1: ll %1, %3 \n"
+ " bltz %1, 2f \n"
+ " addu %1, 1 \n"
+ " sc %1, %0 \n"
+ " .set reorder \n"
+ " beqzl %1, 1b \n"
+ " nop \n"
+ __WEAK_LLSC_MB
+ " li %2, 1 \n"
+ "2: \n"
+ : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
+ : "m" (rw->lock)
+ : "memory");
+ } else {
+ __asm__ __volatile__(
+ " .set noreorder # arch_read_trylock \n"
+ " li %2, 0 \n"
+ "1: ll %1, %3 \n"
+ " bltz %1, 2f \n"
+ " addu %1, 1 \n"
+ " sc %1, %0 \n"
+ " beqz %1, 1b \n"
+ " nop \n"
+ " .set reorder \n"
+ __WEAK_LLSC_MB
+ " li %2, 1 \n"
+ "2: \n"
+ : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
+ : "m" (rw->lock)
+ : "memory");
+ }
+
+ return ret;
+}
+
+static inline int arch_write_trylock(arch_rwlock_t *rw)
+{
+ unsigned int tmp;
+ int ret;
+
+ if (R10000_LLSC_WAR) {
+ __asm__ __volatile__(
+ " .set noreorder # arch_write_trylock \n"
+ " li %2, 0 \n"
+ "1: ll %1, %3 \n"
+ " bnez %1, 2f \n"
+ " lui %1, 0x8000 \n"
+ " sc %1, %0 \n"
+ " beqzl %1, 1b \n"
+ " nop \n"
+ __WEAK_LLSC_MB
+ " li %2, 1 \n"
+ " .set reorder \n"
+ "2: \n"
+ : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
+ : "m" (rw->lock)
+ : "memory");
+ } else {
+ __asm__ __volatile__(
+ " .set noreorder # arch_write_trylock \n"
+ " li %2, 0 \n"
+ "1: ll %1, %3 \n"
+ " bnez %1, 2f \n"
+ " lui %1, 0x8000 \n"
+ " sc %1, %0 \n"
+ " beqz %1, 3f \n"
+ " li %2, 1 \n"
+ "2: \n"
+ __WEAK_LLSC_MB
+ " .subsection 2 \n"
+ "3: b 1b \n"
+ " li %2, 0 \n"
+ " .previous \n"
+ " .set reorder \n"
+ : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
+ : "m" (rw->lock)
+ : "memory");
+ }
+
+ return ret;
+}
+
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
+
+#define arch_spin_relax(lock) cpu_relax()
+#define arch_read_relax(lock) cpu_relax()
+#define arch_write_relax(lock) cpu_relax()
+
+#endif /* _ASM_SPINLOCK_H */
diff --git a/arch/mips/include/asm/spinlock_types.h b/arch/mips/include/asm/spinlock_types.h
new file mode 100644
index 00000000..c52f3601
--- /dev/null
+++ b/arch/mips/include/asm/spinlock_types.h
@@ -0,0 +1,37 @@
+#ifndef _ASM_SPINLOCK_TYPES_H
+#define _ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+#include <linux/types.h>
+
+#include <asm/byteorder.h>
+
+typedef union {
+ /*
+ * bits 0..15 : serving_now
+ * bits 16..31 : ticket
+ */
+ u32 lock;
+ struct {
+#ifdef __BIG_ENDIAN
+ u16 ticket;
+ u16 serving_now;
+#else
+ u16 serving_now;
+ u16 ticket;
+#endif
+ } h;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED { .lock = 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/arch/mips/include/asm/spram.h b/arch/mips/include/asm/spram.h
new file mode 100644
index 00000000..0b89006e
--- /dev/null
+++ b/arch/mips/include/asm/spram.h
@@ -0,0 +1,10 @@
+#ifndef _MIPS_SPRAM_H
+#define _MIPS_SPRAM_H
+
+#ifdef CONFIG_CPU_MIPSR2
+extern __init void spram_config(void);
+#else
+static inline void spram_config(void) { };
+#endif /* CONFIG_CPU_MIPSR2 */
+
+#endif /* _MIPS_SPRAM_H */
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
new file mode 100644
index 00000000..b4ba2449
--- /dev/null
+++ b/arch/mips/include/asm/stackframe.h
@@ -0,0 +1,614 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 99, 2001 Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
+ */
+#ifndef _ASM_STACKFRAME_H
+#define _ASM_STACKFRAME_H
+
+#include <linux/threads.h>
+
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+
+/*
+ * For SMTC kernel, global IE should be left set, and interrupts
+ * controlled exclusively via IXMT.
+ */
+#ifdef CONFIG_MIPS_MT_SMTC
+#define STATMASK 0x1e
+#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+#define STATMASK 0x3f
+#else
+#define STATMASK 0x1f
+#endif
+
+#ifdef CONFIG_MIPS_MT_SMTC
+#include <asm/mipsmtregs.h>
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ .macro SAVE_AT
+ .set push
+ .set noat
+ LONG_S $1, PT_R1(sp)
+ .set pop
+ .endm
+
+ .macro SAVE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ mflhxu v1
+ LONG_S v1, PT_LO(sp)
+ mflhxu v1
+ LONG_S v1, PT_HI(sp)
+ mflhxu v1
+ LONG_S v1, PT_ACX(sp)
+#else
+ mfhi v1
+#endif
+#ifdef CONFIG_32BIT
+ LONG_S $8, PT_R8(sp)
+ LONG_S $9, PT_R9(sp)
+#endif
+ LONG_S $10, PT_R10(sp)
+ LONG_S $11, PT_R11(sp)
+ LONG_S $12, PT_R12(sp)
+#ifndef CONFIG_CPU_HAS_SMARTMIPS
+ LONG_S v1, PT_HI(sp)
+ mflo v1
+#endif
+ LONG_S $13, PT_R13(sp)
+ LONG_S $14, PT_R14(sp)
+ LONG_S $15, PT_R15(sp)
+ LONG_S $24, PT_R24(sp)
+#ifndef CONFIG_CPU_HAS_SMARTMIPS
+ LONG_S v1, PT_LO(sp)
+#endif
+ .endm
+
+ .macro SAVE_STATIC
+ LONG_S $16, PT_R16(sp)
+ LONG_S $17, PT_R17(sp)
+ LONG_S $18, PT_R18(sp)
+ LONG_S $19, PT_R19(sp)
+ LONG_S $20, PT_R20(sp)
+ LONG_S $21, PT_R21(sp)
+ LONG_S $22, PT_R22(sp)
+ LONG_S $23, PT_R23(sp)
+ LONG_S $30, PT_R30(sp)
+ .endm
+
+#ifdef CONFIG_SMP
+#ifdef CONFIG_MIPS_MT_SMTC
+#define PTEBASE_SHIFT 19 /* TCBIND */
+#define CPU_ID_REG CP0_TCBIND
+#define CPU_ID_MFC0 mfc0
+#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
+#define PTEBASE_SHIFT 48 /* XCONTEXT */
+#define CPU_ID_REG CP0_XCONTEXT
+#define CPU_ID_MFC0 MFC0
+#else
+#define PTEBASE_SHIFT 23 /* CONTEXT */
+#define CPU_ID_REG CP0_CONTEXT
+#define CPU_ID_MFC0 MFC0
+#endif
+ .macro get_saved_sp /* SMP variation */
+ CPU_ID_MFC0 k0, CPU_ID_REG
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
+ lui k1, %hi(kernelsp)
+#else
+ lui k1, %highest(kernelsp)
+ daddiu k1, %higher(kernelsp)
+ dsll k1, 16
+ daddiu k1, %hi(kernelsp)
+ dsll k1, 16
+#endif
+ LONG_SRL k0, PTEBASE_SHIFT
+ LONG_ADDU k1, k0
+ LONG_L k1, %lo(kernelsp)(k1)
+ .endm
+
+ .macro set_saved_sp stackp temp temp2
+ CPU_ID_MFC0 \temp, CPU_ID_REG
+ LONG_SRL \temp, PTEBASE_SHIFT
+ LONG_S \stackp, kernelsp(\temp)
+ .endm
+#else
+ .macro get_saved_sp /* Uniprocessor variation */
+#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
+ /*
+ * Clear BTB (branch target buffer), forbid RAS (return address
+ * stack) to workaround the Out-of-order Issue in Loongson2F
+ * via its diagnostic register.
+ */
+ move k0, ra
+ jal 1f
+ nop
+1: jal 1f
+ nop
+1: jal 1f
+ nop
+1: jal 1f
+ nop
+1: move ra, k0
+ li k0, 3
+ mtc0 k0, $22
+#endif /* CONFIG_CPU_LOONGSON2F */
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
+ lui k1, %hi(kernelsp)
+#else
+ lui k1, %highest(kernelsp)
+ daddiu k1, %higher(kernelsp)
+ dsll k1, k1, 16
+ daddiu k1, %hi(kernelsp)
+ dsll k1, k1, 16
+#endif
+ LONG_L k1, %lo(kernelsp)(k1)
+ .endm
+
+ .macro set_saved_sp stackp temp temp2
+ LONG_S \stackp, kernelsp
+ .endm
+#endif
+
+ .macro SAVE_SOME
+ .set push
+ .set noat
+ .set reorder
+ mfc0 k0, CP0_STATUS
+ sll k0, 3 /* extract cu0 bit */
+ .set noreorder
+ bltz k0, 8f
+ move k1, sp
+ .set reorder
+ /* Called from user mode, new stack. */
+ get_saved_sp
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+8: move k0, sp
+ PTR_SUBU sp, k1, PT_SIZE
+#else
+ .set at=k0
+8: PTR_SUBU k1, PT_SIZE
+ .set noat
+ move k0, sp
+ move sp, k1
+#endif
+ LONG_S k0, PT_R29(sp)
+ LONG_S $3, PT_R3(sp)
+ /*
+ * You might think that you don't need to save $0,
+ * but the FPU emulator and gdb remote debug stub
+ * need it to operate correctly
+ */
+ LONG_S $0, PT_R0(sp)
+ mfc0 v1, CP0_STATUS
+ LONG_S $2, PT_R2(sp)
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * Ideally, these instructions would be shuffled in
+ * to cover the pipeline delay.
+ */
+ .set mips32
+ mfc0 v1, CP0_TCSTATUS
+ .set mips0
+ LONG_S v1, PT_TCSTATUS(sp)
+#endif /* CONFIG_MIPS_MT_SMTC */
+ LONG_S $4, PT_R4(sp)
+ LONG_S $5, PT_R5(sp)
+ LONG_S v1, PT_STATUS(sp)
+ mfc0 v1, CP0_CAUSE
+ LONG_S $6, PT_R6(sp)
+ LONG_S $7, PT_R7(sp)
+ LONG_S v1, PT_CAUSE(sp)
+ MFC0 v1, CP0_EPC
+#ifdef CONFIG_64BIT
+ LONG_S $8, PT_R8(sp)
+ LONG_S $9, PT_R9(sp)
+#endif
+ LONG_S $25, PT_R25(sp)
+ LONG_S $28, PT_R28(sp)
+ LONG_S $31, PT_R31(sp)
+ LONG_S v1, PT_EPC(sp)
+ ori $28, sp, _THREAD_MASK
+ xori $28, _THREAD_MASK
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ .set mips64
+ pref 0, 0($28) /* Prefetch the current pointer */
+ pref 0, PT_R31(sp) /* Prefetch the $31(ra) */
+ /* The Octeon multiplier state is affected by general multiply
+ instructions. It must be saved before and kernel code might
+ corrupt it */
+ jal octeon_mult_save
+ LONG_L v1, 0($28) /* Load the current pointer */
+ /* Restore $31(ra) that was changed by the jal */
+ LONG_L ra, PT_R31(sp)
+ pref 0, 0(v1) /* Prefetch the current thread */
+#endif
+ .set pop
+ .endm
+
+ .macro SAVE_ALL
+ SAVE_SOME
+ SAVE_AT
+ SAVE_TEMP
+ SAVE_STATIC
+ .endm
+
+ .macro RESTORE_AT
+ .set push
+ .set noat
+ LONG_L $1, PT_R1(sp)
+ .set pop
+ .endm
+
+ .macro RESTORE_TEMP
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ LONG_L $24, PT_ACX(sp)
+ mtlhx $24
+ LONG_L $24, PT_HI(sp)
+ mtlhx $24
+ LONG_L $24, PT_LO(sp)
+ mtlhx $24
+#else
+ LONG_L $24, PT_LO(sp)
+ mtlo $24
+ LONG_L $24, PT_HI(sp)
+ mthi $24
+#endif
+#ifdef CONFIG_32BIT
+ LONG_L $8, PT_R8(sp)
+ LONG_L $9, PT_R9(sp)
+#endif
+ LONG_L $10, PT_R10(sp)
+ LONG_L $11, PT_R11(sp)
+ LONG_L $12, PT_R12(sp)
+ LONG_L $13, PT_R13(sp)
+ LONG_L $14, PT_R14(sp)
+ LONG_L $15, PT_R15(sp)
+ LONG_L $24, PT_R24(sp)
+ .endm
+
+ .macro RESTORE_STATIC
+ LONG_L $16, PT_R16(sp)
+ LONG_L $17, PT_R17(sp)
+ LONG_L $18, PT_R18(sp)
+ LONG_L $19, PT_R19(sp)
+ LONG_L $20, PT_R20(sp)
+ LONG_L $21, PT_R21(sp)
+ LONG_L $22, PT_R22(sp)
+ LONG_L $23, PT_R23(sp)
+ LONG_L $30, PT_R30(sp)
+ .endm
+
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+ .macro RESTORE_SOME
+ .set push
+ .set reorder
+ .set noat
+ mfc0 a0, CP0_STATUS
+ li v1, 0xff00
+ ori a0, STATMASK
+ xori a0, STATMASK
+ mtc0 a0, CP0_STATUS
+ and a0, v1
+ LONG_L v0, PT_STATUS(sp)
+ nor v1, $0, v1
+ and v0, v1
+ or v0, a0
+ mtc0 v0, CP0_STATUS
+ LONG_L $31, PT_R31(sp)
+ LONG_L $28, PT_R28(sp)
+ LONG_L $25, PT_R25(sp)
+ LONG_L $7, PT_R7(sp)
+ LONG_L $6, PT_R6(sp)
+ LONG_L $5, PT_R5(sp)
+ LONG_L $4, PT_R4(sp)
+ LONG_L $3, PT_R3(sp)
+ LONG_L $2, PT_R2(sp)
+ .set pop
+ .endm
+
+ .macro RESTORE_SP_AND_RET
+ .set push
+ .set noreorder
+ LONG_L k0, PT_EPC(sp)
+ LONG_L sp, PT_R29(sp)
+ jr k0
+ rfe
+ .set pop
+ .endm
+
+#else
+ .macro RESTORE_SOME
+ .set push
+ .set reorder
+ .set noat
+#ifdef CONFIG_MIPS_MT_SMTC
+ .set mips32r2
+ /*
+ * We need to make sure the read-modify-write
+ * of Status below isn't perturbed by an interrupt
+ * or cross-TC access, so we need to do at least a DMT,
+ * protected by an interrupt-inhibit. But setting IXMT
+ * also creates a few-cycle window where an IPI could
+ * be queued and not be detected before potentially
+ * returning to a WAIT or user-mode loop. It must be
+ * replayed.
+ *
+ * We're in the middle of a context switch, and
+ * we can't dispatch it directly without trashing
+ * some registers, so we'll try to detect this unlikely
+ * case and program a software interrupt in the VPE,
+ * as would be done for a cross-VPE IPI. To accommodate
+ * the handling of that case, we're doing a DVPE instead
+ * of just a DMT here to protect against other threads.
+ * This is a lot of cruft to cover a tiny window.
+ * If you can find a better design, implement it!
+ *
+ */
+ mfc0 v0, CP0_TCSTATUS
+ ori v0, TCSTATUS_IXMT
+ mtc0 v0, CP0_TCSTATUS
+ _ehb
+ DVPE 5 # dvpe a1
+ jal mips_ihb
+#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ /* Restore the Octeon multiplier state */
+ jal octeon_mult_restore
+#endif
+ mfc0 a0, CP0_STATUS
+ ori a0, STATMASK
+ xori a0, STATMASK
+ mtc0 a0, CP0_STATUS
+ li v1, 0xff00
+ and a0, v1
+ LONG_L v0, PT_STATUS(sp)
+ nor v1, $0, v1
+ and v0, v1
+ or v0, a0
+ mtc0 v0, CP0_STATUS
+#ifdef CONFIG_MIPS_MT_SMTC
+/*
+ * Only after EXL/ERL have been restored to status can we
+ * restore TCStatus.IXMT.
+ */
+ LONG_L v1, PT_TCSTATUS(sp)
+ _ehb
+ mfc0 a0, CP0_TCSTATUS
+ andi v1, TCSTATUS_IXMT
+ bnez v1, 0f
+
+/*
+ * We'd like to detect any IPIs queued in the tiny window
+ * above and request an software interrupt to service them
+ * when we ERET.
+ *
+ * Computing the offset into the IPIQ array of the executing
+ * TC's IPI queue in-line would be tedious. We use part of
+ * the TCContext register to hold 16 bits of offset that we
+ * can add in-line to find the queue head.
+ */
+ mfc0 v0, CP0_TCCONTEXT
+ la a2, IPIQ
+ srl v0, v0, 16
+ addu a2, a2, v0
+ LONG_L v0, 0(a2)
+ beqz v0, 0f
+/*
+ * If we have a queue, provoke dispatch within the VPE by setting C_SW1
+ */
+ mfc0 v0, CP0_CAUSE
+ ori v0, v0, C_SW1
+ mtc0 v0, CP0_CAUSE
+0:
+ /*
+ * This test should really never branch but
+ * let's be prudent here. Having atomized
+ * the shared register modifications, we can
+ * now EVPE, and must do so before interrupts
+ * are potentially re-enabled.
+ */
+ andi a1, a1, MVPCONTROL_EVP
+ beqz a1, 1f
+ evpe
+1:
+ /* We know that TCStatua.IXMT should be set from above */
+ xori a0, a0, TCSTATUS_IXMT
+ or a0, a0, v1
+ mtc0 a0, CP0_TCSTATUS
+ _ehb
+
+ .set mips0
+#endif /* CONFIG_MIPS_MT_SMTC */
+ LONG_L v1, PT_EPC(sp)
+ MTC0 v1, CP0_EPC
+ LONG_L $31, PT_R31(sp)
+ LONG_L $28, PT_R28(sp)
+ LONG_L $25, PT_R25(sp)
+#ifdef CONFIG_64BIT
+ LONG_L $8, PT_R8(sp)
+ LONG_L $9, PT_R9(sp)
+#endif
+ LONG_L $7, PT_R7(sp)
+ LONG_L $6, PT_R6(sp)
+ LONG_L $5, PT_R5(sp)
+ LONG_L $4, PT_R4(sp)
+ LONG_L $3, PT_R3(sp)
+ LONG_L $2, PT_R2(sp)
+ .set pop
+ .endm
+
+ .macro RESTORE_SP_AND_RET
+ LONG_L sp, PT_R29(sp)
+ .set mips3
+ eret
+ .set mips0
+ .endm
+
+#endif
+
+ .macro RESTORE_SP
+ LONG_L sp, PT_R29(sp)
+ .endm
+
+ .macro RESTORE_ALL
+ RESTORE_TEMP
+ RESTORE_STATIC
+ RESTORE_AT
+ RESTORE_SOME
+ RESTORE_SP
+ .endm
+
+ .macro RESTORE_ALL_AND_RET
+ RESTORE_TEMP
+ RESTORE_STATIC
+ RESTORE_AT
+ RESTORE_SOME
+ RESTORE_SP_AND_RET
+ .endm
+
+/*
+ * Move to kernel mode and disable interrupts.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
+ */
+ .macro CLI
+#if !defined(CONFIG_MIPS_MT_SMTC)
+ mfc0 t0, CP0_STATUS
+ li t1, ST0_CU0 | STATMASK
+ or t0, t1
+ xori t0, STATMASK
+ mtc0 t0, CP0_STATUS
+#else /* CONFIG_MIPS_MT_SMTC */
+ /*
+ * For SMTC, we need to set privilege
+ * and disable interrupts only for the
+ * current TC, using the TCStatus register.
+ */
+ mfc0 t0, CP0_TCSTATUS
+ /* Fortunately CU 0 is in the same place in both registers */
+ /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
+ li t1, ST0_CU0 | 0x08001c00
+ or t0, t1
+ /* Clear TKSU, leave IXMT */
+ xori t0, 0x00001800
+ mtc0 t0, CP0_TCSTATUS
+ _ehb
+ /* We need to leave the global IE bit set, but clear EXL...*/
+ mfc0 t0, CP0_STATUS
+ ori t0, ST0_EXL | ST0_ERL
+ xori t0, ST0_EXL | ST0_ERL
+ mtc0 t0, CP0_STATUS
+#endif /* CONFIG_MIPS_MT_SMTC */
+ irq_disable_hazard
+ .endm
+
+/*
+ * Move to kernel mode and enable interrupts.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
+ */
+ .macro STI
+#if !defined(CONFIG_MIPS_MT_SMTC)
+ mfc0 t0, CP0_STATUS
+ li t1, ST0_CU0 | STATMASK
+ or t0, t1
+ xori t0, STATMASK & ~1
+ mtc0 t0, CP0_STATUS
+#else /* CONFIG_MIPS_MT_SMTC */
+ /*
+ * For SMTC, we need to set privilege
+ * and enable interrupts only for the
+ * current TC, using the TCStatus register.
+ */
+ _ehb
+ mfc0 t0, CP0_TCSTATUS
+ /* Fortunately CU 0 is in the same place in both registers */
+ /* Set TCU0, TKSU (for later inversion) and IXMT */
+ li t1, ST0_CU0 | 0x08001c00
+ or t0, t1
+ /* Clear TKSU *and* IXMT */
+ xori t0, 0x00001c00
+ mtc0 t0, CP0_TCSTATUS
+ _ehb
+ /* We need to leave the global IE bit set, but clear EXL...*/
+ mfc0 t0, CP0_STATUS
+ ori t0, ST0_EXL
+ xori t0, ST0_EXL
+ mtc0 t0, CP0_STATUS
+ /* irq_enable_hazard below should expand to EHB for 24K/34K cpus */
+#endif /* CONFIG_MIPS_MT_SMTC */
+ irq_enable_hazard
+ .endm
+
+/*
+ * Just move to kernel mode and leave interrupts as they are. Note
+ * for the R3000 this means copying the previous enable from IEp.
+ * Set cp0 enable bit as sign that we're running on the kernel stack
+ */
+ .macro KMODE
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * This gets baroque in SMTC. We want to
+ * protect the non-atomic clearing of EXL
+ * with DMT/EMT, but we don't want to take
+ * an interrupt while DMT is still in effect.
+ */
+
+ /* KMODE gets invoked from both reorder and noreorder code */
+ .set push
+ .set mips32r2
+ .set noreorder
+ mfc0 v0, CP0_TCSTATUS
+ andi v1, v0, TCSTATUS_IXMT
+ ori v0, TCSTATUS_IXMT
+ mtc0 v0, CP0_TCSTATUS
+ _ehb
+ DMT 2 # dmt v0
+ /*
+ * We don't know a priori if ra is "live"
+ */
+ move t0, ra
+ jal mips_ihb
+ nop /* delay slot */
+ move ra, t0
+#endif /* CONFIG_MIPS_MT_SMTC */
+ mfc0 t0, CP0_STATUS
+ li t1, ST0_CU0 | (STATMASK & ~1)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+ andi t2, t0, ST0_IEP
+ srl t2, 2
+ or t0, t2
+#endif
+ or t0, t1
+ xori t0, STATMASK & ~1
+ mtc0 t0, CP0_STATUS
+#ifdef CONFIG_MIPS_MT_SMTC
+ _ehb
+ andi v0, v0, VPECONTROL_TE
+ beqz v0, 2f
+ nop /* delay slot */
+ emt
+2:
+ mfc0 v0, CP0_TCSTATUS
+ /* Clear IXMT, then OR in previous value */
+ ori v0, TCSTATUS_IXMT
+ xori v0, TCSTATUS_IXMT
+ or v0, v1, v0
+ mtc0 v0, CP0_TCSTATUS
+ /*
+ * irq_disable_hazard below should expand to EHB
+ * on 24K/34K CPUS
+ */
+ .set pop
+#endif /* CONFIG_MIPS_MT_SMTC */
+ irq_disable_hazard
+ .endm
+
+#endif /* _ASM_STACKFRAME_H */
diff --git a/arch/mips/include/asm/stacktrace.h b/arch/mips/include/asm/stacktrace.h
new file mode 100644
index 00000000..0bf82818
--- /dev/null
+++ b/arch/mips/include/asm/stacktrace.h
@@ -0,0 +1,48 @@
+#ifndef _ASM_STACKTRACE_H
+#define _ASM_STACKTRACE_H
+
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_KALLSYMS
+extern int raw_show_trace;
+extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+ unsigned long pc, unsigned long *ra);
+#else
+#define raw_show_trace 1
+static inline unsigned long unwind_stack(struct task_struct *task,
+ unsigned long *sp, unsigned long pc, unsigned long *ra)
+{
+ return 0;
+}
+#endif
+
+static __always_inline void prepare_frametrace(struct pt_regs *regs)
+{
+#ifndef CONFIG_KALLSYMS
+ /*
+ * Remove any garbage that may be in regs (specially func
+ * addresses) to avoid show_raw_backtrace() to report them
+ */
+ memset(regs, 0, sizeof(*regs));
+#endif
+ __asm__ __volatile__(
+ ".set push\n\t"
+ ".set noat\n\t"
+#ifdef CONFIG_64BIT
+ "1: dla $1, 1b\n\t"
+ "sd $1, %0\n\t"
+ "sd $29, %1\n\t"
+ "sd $31, %2\n\t"
+#else
+ "1: la $1, 1b\n\t"
+ "sw $1, %0\n\t"
+ "sw $29, %1\n\t"
+ "sw $31, %2\n\t"
+#endif
+ ".set pop\n\t"
+ : "=m" (regs->cp0_epc),
+ "=m" (regs->regs[29]), "=m" (regs->regs[31])
+ : : "memory");
+}
+
+#endif /* _ASM_STACKTRACE_H */
diff --git a/arch/mips/include/asm/stat.h b/arch/mips/include/asm/stat.h
new file mode 100644
index 00000000..6e00f751
--- /dev/null
+++ b/arch/mips/include/asm/stat.h
@@ -0,0 +1,132 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999, 2000 Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_STAT_H
+#define _ASM_STAT_H
+
+#include <linux/types.h>
+
+#include <asm/sgidefs.h>
+
+#if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
+
+struct stat {
+ unsigned st_dev;
+ long st_pad1[3]; /* Reserved for network id */
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ unsigned st_rdev;
+ long st_pad2[2];
+ off_t st_size;
+ long st_pad3;
+ /*
+ * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+ * but we don't have it under Linux.
+ */
+ time_t st_atime;
+ long st_atime_nsec;
+ time_t st_mtime;
+ long st_mtime_nsec;
+ time_t st_ctime;
+ long st_ctime_nsec;
+ long st_blksize;
+ long st_blocks;
+ long st_pad4[14];
+};
+
+/*
+ * This matches struct stat64 in glibc2.1, hence the absolutely insane
+ * amounts of padding around dev_t's. The memory layout is the same as of
+ * struct stat of the 64-bit kernel.
+ */
+
+struct stat64 {
+ unsigned long st_dev;
+ unsigned long st_pad0[3]; /* Reserved for st_dev expansion */
+
+ unsigned long long st_ino;
+
+ mode_t st_mode;
+ nlink_t st_nlink;
+
+ uid_t st_uid;
+ gid_t st_gid;
+
+ unsigned long st_rdev;
+ unsigned long st_pad1[3]; /* Reserved for st_rdev expansion */
+
+ long long st_size;
+
+ /*
+ * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+ * but we don't have it under Linux.
+ */
+ time_t st_atime;
+ unsigned long st_atime_nsec; /* Reserved for st_atime expansion */
+
+ time_t st_mtime;
+ unsigned long st_mtime_nsec; /* Reserved for st_mtime expansion */
+
+ time_t st_ctime;
+ unsigned long st_ctime_nsec; /* Reserved for st_ctime expansion */
+
+ unsigned long st_blksize;
+ unsigned long st_pad2;
+
+ long long st_blocks;
+};
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+
+/* The memory layout is the same as of struct stat64 of the 32-bit kernel. */
+struct stat {
+ unsigned int st_dev;
+ unsigned int st_pad0[3]; /* Reserved for st_dev expansion */
+
+ unsigned long st_ino;
+
+ mode_t st_mode;
+ nlink_t st_nlink;
+
+ uid_t st_uid;
+ gid_t st_gid;
+
+ unsigned int st_rdev;
+ unsigned int st_pad1[3]; /* Reserved for st_rdev expansion */
+
+ off_t st_size;
+
+ /*
+ * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+ * but we don't have it under Linux.
+ */
+ unsigned int st_atime;
+ unsigned int st_atime_nsec;
+
+ unsigned int st_mtime;
+ unsigned int st_mtime_nsec;
+
+ unsigned int st_ctime;
+ unsigned int st_ctime_nsec;
+
+ unsigned int st_blksize;
+ unsigned int st_pad2;
+
+ unsigned long st_blocks;
+};
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+
+#define STAT_HAVE_NSEC 1
+
+#endif /* _ASM_STAT_H */
diff --git a/arch/mips/include/asm/statfs.h b/arch/mips/include/asm/statfs.h
new file mode 100644
index 00000000..0f805c7a
--- /dev/null
+++ b/arch/mips/include/asm/statfs.h
@@ -0,0 +1,100 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_STATFS_H
+#define _ASM_STATFS_H
+
+#include <linux/posix_types.h>
+#include <asm/sgidefs.h>
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t fsid_t;
+
+#endif
+
+struct statfs {
+ long f_type;
+#define f_fstyp f_type
+ long f_bsize;
+ long f_frsize; /* Fragment size - unsupported */
+ long f_blocks;
+ long f_bfree;
+ long f_files;
+ long f_ffree;
+ long f_bavail;
+
+ /* Linux specials */
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_flags;
+ long f_spare[5];
+};
+
+#if (_MIPS_SIM == _MIPS_SIM_ABI32) || (_MIPS_SIM == _MIPS_SIM_NABI32)
+
+/*
+ * Unlike the traditional version the LFAPI version has none of the ABI junk
+ */
+struct statfs64 {
+ __u32 f_type;
+ __u32 f_bsize;
+ __u32 f_frsize; /* Fragment size - unsupported */
+ __u32 __pad;
+ __u64 f_blocks;
+ __u64 f_bfree;
+ __u64 f_files;
+ __u64 f_ffree;
+ __u64 f_bavail;
+ __kernel_fsid_t f_fsid;
+ __u32 f_namelen;
+ __u32 f_flags;
+ __u32 f_spare[5];
+};
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+
+struct statfs64 { /* Same as struct statfs */
+ long f_type;
+ long f_bsize;
+ long f_frsize; /* Fragment size - unsupported */
+ long f_blocks;
+ long f_bfree;
+ long f_files;
+ long f_ffree;
+ long f_bavail;
+
+ /* Linux specials */
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_flags;
+ long f_spare[5];
+};
+
+struct compat_statfs64 {
+ __u32 f_type;
+ __u32 f_bsize;
+ __u32 f_frsize; /* Fragment size - unsupported */
+ __u32 __pad;
+ __u64 f_blocks;
+ __u64 f_bfree;
+ __u64 f_files;
+ __u64 f_ffree;
+ __u64 f_bavail;
+ __kernel_fsid_t f_fsid;
+ __u32 f_namelen;
+ __u32 f_flags;
+ __u32 f_spare[5];
+};
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+
+#endif /* _ASM_STATFS_H */
diff --git a/arch/mips/include/asm/string.h b/arch/mips/include/asm/string.h
new file mode 100644
index 00000000..436e3ad3
--- /dev/null
+++ b/arch/mips/include/asm/string.h
@@ -0,0 +1,143 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1994, 95, 96, 97, 98, 2000, 01 Ralf Baechle
+ * Copyright (c) 2000 by Silicon Graphics, Inc.
+ * Copyright (c) 2001 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_STRING_H
+#define _ASM_STRING_H
+
+
+/*
+ * Most of the inline functions are rather naive implementations so I just
+ * didn't bother updating them for 64-bit ...
+ */
+#ifdef CONFIG_32BIT
+
+#ifndef IN_STRING_C
+
+#define __HAVE_ARCH_STRCPY
+static __inline__ char *strcpy(char *__dest, __const__ char *__src)
+{
+ char *__xdest = __dest;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n"
+ "1:\tlbu\t$1,(%1)\n\t"
+ "addiu\t%1,1\n\t"
+ "sb\t$1,(%0)\n\t"
+ "bnez\t$1,1b\n\t"
+ "addiu\t%0,1\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "=r" (__dest), "=r" (__src)
+ : "0" (__dest), "1" (__src)
+ : "memory");
+
+ return __xdest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+static __inline__ char *strncpy(char *__dest, __const__ char *__src, size_t __n)
+{
+ char *__xdest = __dest;
+
+ if (__n == 0)
+ return __xdest;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n"
+ "1:\tlbu\t$1,(%1)\n\t"
+ "subu\t%2,1\n\t"
+ "sb\t$1,(%0)\n\t"
+ "beqz\t$1,2f\n\t"
+ "addiu\t%0,1\n\t"
+ "bnez\t%2,1b\n\t"
+ "addiu\t%1,1\n"
+ "2:\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "=r" (__dest), "=r" (__src), "=r" (__n)
+ : "0" (__dest), "1" (__src), "2" (__n)
+ : "memory");
+
+ return __xdest;
+}
+
+#define __HAVE_ARCH_STRCMP
+static __inline__ int strcmp(__const__ char *__cs, __const__ char *__ct)
+{
+ int __res;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "lbu\t%2,(%0)\n"
+ "1:\tlbu\t$1,(%1)\n\t"
+ "addiu\t%0,1\n\t"
+ "bne\t$1,%2,2f\n\t"
+ "addiu\t%1,1\n\t"
+ "bnez\t%2,1b\n\t"
+ "lbu\t%2,(%0)\n\t"
+#if defined(CONFIG_CPU_R3000)
+ "nop\n\t"
+#endif
+ "move\t%2,$1\n"
+ "2:\tsubu\t%2,$1\n"
+ "3:\t.set\tat\n\t"
+ ".set\treorder"
+ : "=r" (__cs), "=r" (__ct), "=r" (__res)
+ : "0" (__cs), "1" (__ct));
+
+ return __res;
+}
+
+#endif /* !defined(IN_STRING_C) */
+
+#define __HAVE_ARCH_STRNCMP
+static __inline__ int
+strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
+{
+ int __res;
+
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n"
+ "1:\tlbu\t%3,(%0)\n\t"
+ "beqz\t%2,2f\n\t"
+ "lbu\t$1,(%1)\n\t"
+ "subu\t%2,1\n\t"
+ "bne\t$1,%3,3f\n\t"
+ "addiu\t%0,1\n\t"
+ "bnez\t%3,1b\n\t"
+ "addiu\t%1,1\n"
+ "2:\n\t"
+#if defined(CONFIG_CPU_R3000)
+ "nop\n\t"
+#endif
+ "move\t%3,$1\n"
+ "3:\tsubu\t%3,$1\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res)
+ : "0" (__cs), "1" (__ct), "2" (__count));
+
+ return __res;
+}
+#endif /* CONFIG_32BIT */
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *__s, int __c, size_t __count);
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
+
+#endif /* _ASM_STRING_H */
diff --git a/arch/mips/include/asm/suspend.h b/arch/mips/include/asm/suspend.h
new file mode 100644
index 00000000..3adac3b5
--- /dev/null
+++ b/arch/mips/include/asm/suspend.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_SUSPEND_H
+#define __ASM_SUSPEND_H
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+#endif /* __ASM_SUSPEND_H */
diff --git a/arch/mips/include/asm/swab.h b/arch/mips/include/asm/swab.h
new file mode 100644
index 00000000..97c2f81b
--- /dev/null
+++ b/arch/mips/include/asm/swab.h
@@ -0,0 +1,59 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 99, 2003 by Ralf Baechle
+ */
+#ifndef _ASM_SWAB_H
+#define _ASM_SWAB_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#define __SWAB_64_THRU_32__
+
+#ifdef CONFIG_CPU_MIPSR2
+
+static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
+{
+ __asm__(
+ " wsbh %0, %1 \n"
+ : "=r" (x)
+ : "r" (x));
+
+ return x;
+}
+#define __arch_swab16 __arch_swab16
+
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+{
+ __asm__(
+ " wsbh %0, %1 \n"
+ " rotr %0, %0, 16 \n"
+ : "=r" (x)
+ : "r" (x));
+
+ return x;
+}
+#define __arch_swab32 __arch_swab32
+
+/*
+ * Having already checked for CONFIG_CPU_MIPSR2, enable the
+ * optimized version for 64-bit kernel on r2 CPUs.
+ */
+#ifdef CONFIG_64BIT
+static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
+{
+ __asm__(
+ " dsbh %0, %1\n"
+ " dshd %0, %0"
+ : "=r" (x)
+ : "r" (x));
+
+ return x;
+}
+#define __arch_swab64 __arch_swab64
+#endif /* CONFIG_64BIT */
+#endif /* CONFIG_CPU_MIPSR2 */
+#endif /* _ASM_SWAB_H */
diff --git a/arch/mips/include/asm/sysmips.h b/arch/mips/include/asm/sysmips.h
new file mode 100644
index 00000000..4f47b7d6
--- /dev/null
+++ b/arch/mips/include/asm/sysmips.h
@@ -0,0 +1,25 @@
+/*
+ * Definitions for the MIPS sysmips(2) call
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 by Ralf Baechle
+ */
+#ifndef _ASM_SYSMIPS_H
+#define _ASM_SYSMIPS_H
+
+/*
+ * Commands for the sysmips(2) call
+ *
+ * sysmips(2) is deprecated - though some existing software uses it.
+ * We only support the following commands.
+ */
+#define SETNAME 1 /* set hostname */
+#define FLUSH_CACHE 3 /* writeback and invalidate caches */
+#define MIPS_FIXADE 7 /* control address error fixing */
+#define MIPS_RDNVRAM 10 /* read NVRAM */
+#define MIPS_ATOMIC_SET 2001 /* atomically set variable */
+
+#endif /* _ASM_SYSMIPS_H */
diff --git a/arch/mips/include/asm/system.h b/arch/mips/include/asm/system.h
new file mode 100644
index 00000000..6018c80c
--- /dev/null
+++ b/arch/mips/include/asm/system.h
@@ -0,0 +1,235 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003, 06 by Ralf Baechle
+ * Copyright (C) 1996 by Paul M. Antoine
+ * Copyright (C) 1999 Silicon Graphics
+ * Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_SYSTEM_H
+#define _ASM_SYSTEM_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/irqflags.h>
+
+#include <asm/addrspace.h>
+#include <asm/barrier.h>
+#include <asm/cmpxchg.h>
+#include <asm/cpu-features.h>
+#include <asm/dsp.h>
+#include <asm/watch.h>
+#include <asm/war.h>
+
+
+/*
+ * switch_to(n) should switch tasks to task nr n, first
+ * checking that n isn't the current task, in which case it does nothing.
+ */
+extern asmlinkage void *resume(void *last, void *next, void *next_ti);
+
+struct task_struct;
+
+extern unsigned int ll_bit;
+extern struct task_struct *ll_task;
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+
+/*
+ * Handle the scheduler resume end of FPU affinity management. We do this
+ * inline to try to keep the overhead down. If we have been forced to run on
+ * a "CPU" with an FPU because of a previous high level of FP computation,
+ * but did not actually use the FPU during the most recent time-slice (CU1
+ * isn't set), we undo the restriction on cpus_allowed.
+ *
+ * We're not calling set_cpus_allowed() here, because we have no need to
+ * force prompt migration - we're already switching the current CPU to a
+ * different thread.
+ */
+
+#define __mips_mt_fpaff_switch_to(prev) \
+do { \
+ struct thread_info *__prev_ti = task_thread_info(prev); \
+ \
+ if (cpu_has_fpu && \
+ test_ti_thread_flag(__prev_ti, TIF_FPUBOUND) && \
+ (!(KSTK_STATUS(prev) & ST0_CU1))) { \
+ clear_ti_thread_flag(__prev_ti, TIF_FPUBOUND); \
+ prev->cpus_allowed = prev->thread.user_cpus_allowed; \
+ } \
+ next->thread.emulated_fp = 0; \
+} while(0)
+
+#else
+#define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0)
+#endif
+
+#define __clear_software_ll_bit() \
+do { \
+ if (!__builtin_constant_p(cpu_has_llsc) || !cpu_has_llsc) \
+ ll_bit = 0; \
+} while (0)
+
+#define switch_to(prev, next, last) \
+do { \
+ __mips_mt_fpaff_switch_to(prev); \
+ if (cpu_has_dsp) \
+ __save_dsp(prev); \
+ __clear_software_ll_bit(); \
+ (last) = resume(prev, next, task_thread_info(next)); \
+} while (0)
+
+#define finish_arch_switch(prev) \
+do { \
+ if (cpu_has_dsp) \
+ __restore_dsp(current); \
+ if (cpu_has_userlocal) \
+ write_c0_userlocal(current_thread_info()->tp_value); \
+ __restore_watch(); \
+} while (0)
+
+static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
+{
+ __u32 retval;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long dummy;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: ll %0, %3 # xchg_u32 \n"
+ " .set mips0 \n"
+ " move %2, %z4 \n"
+ " .set mips3 \n"
+ " sc %2, %1 \n"
+ " beqzl %2, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ : "R" (*m), "Jr" (val)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ unsigned long dummy;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " ll %0, %3 # xchg_u32 \n"
+ " .set mips0 \n"
+ " move %2, %z4 \n"
+ " .set mips3 \n"
+ " sc %2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ : "R" (*m), "Jr" (val)
+ : "memory");
+ } while (unlikely(!dummy));
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ retval = *m;
+ *m = val;
+ raw_local_irq_restore(flags); /* implies memory barrier */
+ }
+
+ smp_llsc_mb();
+
+ return retval;
+}
+
+#ifdef CONFIG_64BIT
+static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
+{
+ __u64 retval;
+
+ smp_mb__before_llsc();
+
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ unsigned long dummy;
+
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ "1: lld %0, %3 # xchg_u64 \n"
+ " move %2, %z4 \n"
+ " scd %2, %1 \n"
+ " beqzl %2, 1b \n"
+ " .set mips0 \n"
+ : "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ : "R" (*m), "Jr" (val)
+ : "memory");
+ } else if (kernel_uses_llsc) {
+ unsigned long dummy;
+
+ do {
+ __asm__ __volatile__(
+ " .set mips3 \n"
+ " lld %0, %3 # xchg_u64 \n"
+ " move %2, %z4 \n"
+ " scd %2, %1 \n"
+ " .set mips0 \n"
+ : "=&r" (retval), "=m" (*m), "=&r" (dummy)
+ : "R" (*m), "Jr" (val)
+ : "memory");
+ } while (unlikely(!dummy));
+ } else {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ retval = *m;
+ *m = val;
+ raw_local_irq_restore(flags); /* implies memory barrier */
+ }
+
+ smp_llsc_mb();
+
+ return retval;
+}
+#else
+extern __u64 __xchg_u64_unsupported_on_32bit_kernels(volatile __u64 * m, __u64 val);
+#define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
+#endif
+
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+ switch (size) {
+ case 4:
+ return __xchg_u32(ptr, x);
+ case 8:
+ return __xchg_u64(ptr, x);
+ }
+
+ return x;
+}
+
+#define xchg(ptr, x) \
+({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) & ~0xc); \
+ \
+ ((__typeof__(*(ptr))) \
+ __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))); \
+})
+
+extern void set_handler(unsigned long offset, void *addr, unsigned long len);
+extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
+
+typedef void (*vi_handler_t)(void);
+extern void *set_vi_handler(int n, vi_handler_t addr);
+
+extern void *set_except_vector(int n, void *addr);
+extern unsigned long ebase;
+extern void per_cpu_trap_init(void);
+
+/*
+ * See include/asm-ia64/system.h; prevents deadlock on SMP
+ * systems.
+ */
+#define __ARCH_WANT_UNLOCKED_CTXSW
+
+extern unsigned long arch_align_stack(unsigned long sp);
+
+#endif /* _ASM_SYSTEM_H */
diff --git a/arch/mips/include/asm/termbits.h b/arch/mips/include/asm/termbits.h
new file mode 100644
index 00000000..76630b39
--- /dev/null
+++ b/arch/mips/include/asm/termbits.h
@@ -0,0 +1,227 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 99, 2001, 06 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#ifndef _ASM_TERMBITS_H
+#define _ASM_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+/*
+ * The ABI says nothing about NCC but seems to use NCCS as
+ * replacement for it in struct termio
+ */
+#define NCCS 23
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+struct termios2 {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+struct ktermios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+/* c_cc characters */
+#define VINTR 0 /* Interrupt character [ISIG]. */
+#define VQUIT 1 /* Quit character [ISIG]. */
+#define VERASE 2 /* Erase character [ICANON]. */
+#define VKILL 3 /* Kill-line character [ICANON]. */
+#define VMIN 4 /* Minimum number of bytes read at once [!ICANON]. */
+#define VTIME 5 /* Time-out value (tenths of a second) [!ICANON]. */
+#define VEOL2 6 /* Second EOL character [ICANON]. */
+#define VSWTC 7 /* ??? */
+#define VSWTCH VSWTC
+#define VSTART 8 /* Start (X-ON) character [IXON, IXOFF]. */
+#define VSTOP 9 /* Stop (X-OFF) character [IXON, IXOFF]. */
+#define VSUSP 10 /* Suspend character [ISIG]. */
+#if 0
+/*
+ * VDSUSP is not supported
+ */
+#define VDSUSP 11 /* Delayed suspend character [ISIG]. */
+#endif
+#define VREPRINT 12 /* Reprint-line character [ICANON]. */
+#define VDISCARD 13 /* Discard character [IEXTEN]. */
+#define VWERASE 14 /* Word-erase character [ICANON]. */
+#define VLNEXT 15 /* Literal-next character [IEXTEN]. */
+#define VEOF 16 /* End-of-file character [ICANON]. */
+#define VEOL 17 /* End-of-line character [ICANON]. */
+
+/* c_iflag bits */
+#define IGNBRK 0000001 /* Ignore break condition. */
+#define BRKINT 0000002 /* Signal interrupt on break. */
+#define IGNPAR 0000004 /* Ignore characters with parity errors. */
+#define PARMRK 0000010 /* Mark parity and framing errors. */
+#define INPCK 0000020 /* Enable input parity check. */
+#define ISTRIP 0000040 /* Strip 8th bit off characters. */
+#define INLCR 0000100 /* Map NL to CR on input. */
+#define IGNCR 0000200 /* Ignore CR. */
+#define ICRNL 0000400 /* Map CR to NL on input. */
+#define IUCLC 0001000 /* Map upper case to lower case on input. */
+#define IXON 0002000 /* Enable start/stop output control. */
+#define IXANY 0004000 /* Any character will restart after stop. */
+#define IXOFF 0010000 /* Enable start/stop input control. */
+#define IMAXBEL 0020000 /* Ring bell when input queue is full. */
+#define IUTF8 0040000 /* Input is UTF-8 */
+
+/* c_oflag bits */
+#define OPOST 0000001 /* Perform output processing. */
+#define OLCUC 0000002 /* Map lower case to upper case on output. */
+#define ONLCR 0000004 /* Map NL to CR-NL on output. */
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+/*
+#define PAGEOUT ???
+#define WRAP ???
+ */
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060 /* Number of bits per byte (mask). */
+#define CS5 0000000 /* 5 bits per byte. */
+#define CS6 0000020 /* 6 bits per byte. */
+#define CS7 0000040 /* 7 bits per byte. */
+#define CS8 0000060 /* 8 bits per byte. */
+#define CSTOPB 0000100 /* Two stop bits instead of one. */
+#define CREAD 0000200 /* Enable receiver. */
+#define PARENB 0000400 /* Parity enable. */
+#define PARODD 0001000 /* Odd parity instead of even. */
+#define HUPCL 0002000 /* Hang up on last close. */
+#define CLOCAL 0004000 /* Ignore modem status lines. */
+#define CBAUDEX 0010000
+#define BOTHER 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+#define CIBAUD 002003600000 /* input baud rate */
+#define CMSPAR 010000000000 /* mark or space (stick) parity */
+#define CRTSCTS 020000000000 /* flow control */
+
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
+/* c_lflag bits */
+#define ISIG 0000001 /* Enable signals. */
+#define ICANON 0000002 /* Do erase and kill processing. */
+#define XCASE 0000004
+#define ECHO 0000010 /* Enable echo. */
+#define ECHOE 0000020 /* Visual erase for ERASE. */
+#define ECHOK 0000040 /* Echo NL after KILL. */
+#define ECHONL 0000100 /* Echo NL even if ECHO is off. */
+#define NOFLSH 0000200 /* Disable flush after interrupt. */
+#define IEXTEN 0000400 /* Enable DISCARD and LNEXT. */
+#define ECHOCTL 0001000 /* Echo control characters as ^X. */
+#define ECHOPRT 0002000 /* Hardcopy visual erase. */
+#define ECHOKE 0004000 /* Visual erase for KILL. */
+#define FLUSHO 0020000
+#define PENDIN 0040000 /* Retype pending input (state). */
+#define TOSTOP 0100000 /* Send SIGTTOU for background output. */
+#define ITOSTOP TOSTOP
+#define EXTPROC 0200000 /* External processing on pty */
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0 /* Suspend output. */
+#define TCOON 1 /* Restart suspended output. */
+#define TCIOFF 2 /* Send a STOP character. */
+#define TCION 3 /* Send a START character. */
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0 /* Discard data received but not yet read. */
+#define TCOFLUSH 1 /* Discard data written but not yet sent. */
+#define TCIOFLUSH 2 /* Discard all pending data. */
+
+/* tcsetattr uses these */
+#define TCSANOW TCSETS /* Change immediately. */
+#define TCSADRAIN TCSETSW /* Change when pending output is written. */
+#define TCSAFLUSH TCSETSF /* Flush pending input before changing. */
+
+#endif /* _ASM_TERMBITS_H */
diff --git a/arch/mips/include/asm/termios.h b/arch/mips/include/asm/termios.h
new file mode 100644
index 00000000..8f77f774
--- /dev/null
+++ b/arch/mips/include/asm/termios.h
@@ -0,0 +1,176 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_TERMIOS_H
+#define _ASM_TERMIOS_H
+
+#include <linux/errno.h>
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct sgttyb {
+ char sg_ispeed;
+ char sg_ospeed;
+ char sg_erase;
+ char sg_kill;
+ int sg_flags; /* SGI special - int, not short */
+};
+
+struct tchars {
+ char t_intrc;
+ char t_quitc;
+ char t_startc;
+ char t_stopc;
+ char t_eofc;
+ char t_brkc;
+};
+
+struct ltchars {
+ char t_suspc; /* stop process signal */
+ char t_dsuspc; /* delayed stop process signal */
+ char t_rprntc; /* reprint line */
+ char t_flushc; /* flush output (toggles) */
+ char t_werasc; /* word erase */
+ char t_lnextc; /* literal next character */
+};
+
+/* TIOCGSIZE, TIOCSSIZE not defined yet. Only needed for SunOS source
+ compatibility anyway ... */
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ char c_line; /* line discipline */
+ unsigned char c_cc[NCCS]; /* control characters */
+};
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+
+/*
+ * intr=^C quit=^\ erase=del kill=^U
+ * vmin=\1 vtime=\0 eol2=\0 swtc=\0
+ * start=^Q stop=^S susp=^Z vdsusp=
+ * reprint=^R discard=^U werase=^W lnext=^V
+ * eof=^D eol=\0
+ */
+#define INIT_C_CC "\003\034\177\025\1\0\0\0\021\023\032\0\022\017\027\026\004\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE 0x001 /* line enable */
+#define TIOCM_DTR 0x002 /* data terminal ready */
+#define TIOCM_RTS 0x004 /* request to send */
+#define TIOCM_ST 0x010 /* secondary transmit */
+#define TIOCM_SR 0x020 /* secondary receive */
+#define TIOCM_CTS 0x040 /* clear to send */
+#define TIOCM_CAR 0x100 /* carrier detect */
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RNG 0x200 /* ring */
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_DSR 0x400 /* data set ready */
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+#ifdef __KERNEL__
+
+#include <linux/string.h>
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+static inline int user_termio_to_kernel_termios(struct ktermios *termios,
+ struct termio __user *termio)
+{
+ unsigned short iflag, oflag, cflag, lflag;
+ unsigned int err;
+
+ if (!access_ok(VERIFY_READ, termio, sizeof(struct termio)))
+ return -EFAULT;
+
+ err = __get_user(iflag, &termio->c_iflag);
+ termios->c_iflag = (termios->c_iflag & 0xffff0000) | iflag;
+ err |=__get_user(oflag, &termio->c_oflag);
+ termios->c_oflag = (termios->c_oflag & 0xffff0000) | oflag;
+ err |=__get_user(cflag, &termio->c_cflag);
+ termios->c_cflag = (termios->c_cflag & 0xffff0000) | cflag;
+ err |=__get_user(lflag, &termio->c_lflag);
+ termios->c_lflag = (termios->c_lflag & 0xffff0000) | lflag;
+ err |=__get_user(termios->c_line, &termio->c_line);
+ if (err)
+ return -EFAULT;
+
+ if (__copy_from_user(termios->c_cc, termio->c_cc, NCC))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+static inline int kernel_termios_to_user_termio(struct termio __user *termio,
+ struct ktermios *termios)
+{
+ int err;
+
+ if (!access_ok(VERIFY_WRITE, termio, sizeof(struct termio)))
+ return -EFAULT;
+
+ err = __put_user(termios->c_iflag, &termio->c_iflag);
+ err |= __put_user(termios->c_oflag, &termio->c_oflag);
+ err |= __put_user(termios->c_cflag, &termio->c_cflag);
+ err |= __put_user(termios->c_lflag, &termio->c_lflag);
+ err |= __put_user(termios->c_line, &termio->c_line);
+ if (err)
+ return -EFAULT;
+
+ if (__copy_to_user(termio->c_cc, termios->c_cc, NCC))
+ return -EFAULT;
+
+ return 0;
+}
+
+static inline int user_termios_to_kernel_termios(struct ktermios __user *k,
+ struct termios2 *u)
+{
+ return copy_from_user(k, u, sizeof(struct termios2)) ? -EFAULT : 0;
+}
+
+static inline int kernel_termios_to_user_termios(struct termios2 __user *u,
+ struct ktermios *k)
+{
+ return copy_to_user(u, k, sizeof(struct termios2)) ? -EFAULT : 0;
+}
+
+static inline int user_termios_to_kernel_termios_1(struct ktermios *k,
+ struct termios __user *u)
+{
+ return copy_from_user(k, u, sizeof(struct termios)) ? -EFAULT : 0;
+}
+
+static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
+ struct ktermios *k)
+{
+ return copy_to_user(u, k, sizeof(struct termios)) ? -EFAULT : 0;
+}
+
+#endif /* defined(__KERNEL__) */
+
+#endif /* _ASM_TERMIOS_H */
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
new file mode 100644
index 00000000..97f8bf66
--- /dev/null
+++ b/arch/mips/include/asm/thread_info.h
@@ -0,0 +1,163 @@
+/* thread_info.h: MIPS low-level thread information
+ *
+ * Copyright (C) 2002 David Howells (dhowells@redhat.com)
+ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+
+#ifndef __ASSEMBLY__
+
+#include <asm/processor.h>
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ * must also be changed
+ */
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ unsigned long tp_value; /* thread pointer */
+ __u32 cpu; /* current CPU */
+ int preempt_count; /* 0 => preemptable, <0 => BUG */
+
+ mm_segment_t addr_limit; /* thread address space:
+ 0-0xBFFFFFFF for user-thead
+ 0-0xFFFFFFFF for kernel-thread
+ */
+ struct restart_block restart_block;
+ struct pt_regs *regs;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ */
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = _TIF_FIXADE, \
+ .cpu = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+/* How to get the thread information struct from C. */
+register struct thread_info *__current_thread_info __asm__("$28");
+#define current_thread_info() __current_thread_info
+
+/* thread information allocation */
+#if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_32BIT)
+#define THREAD_SIZE_ORDER (1)
+#endif
+#if defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_64BIT)
+#define THREAD_SIZE_ORDER (2)
+#endif
+#ifdef CONFIG_PAGE_SIZE_8KB
+#define THREAD_SIZE_ORDER (1)
+#endif
+#ifdef CONFIG_PAGE_SIZE_16KB
+#define THREAD_SIZE_ORDER (0)
+#endif
+#ifdef CONFIG_PAGE_SIZE_32KB
+#define THREAD_SIZE_ORDER (0)
+#endif
+#ifdef CONFIG_PAGE_SIZE_64KB
+#define THREAD_SIZE_ORDER (0)
+#endif
+
+#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
+#define THREAD_MASK (THREAD_SIZE - 1UL)
+
+#define STACK_WARN (THREAD_SIZE / 8)
+
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#define alloc_thread_info_node(tsk, node) \
+ kzalloc_node(THREAD_SIZE, GFP_KERNEL, node)
+#else
+#define alloc_thread_info_node(tsk, node) \
+ kmalloc_node(THREAD_SIZE, GFP_KERNEL, node)
+#endif
+
+#define free_thread_info(info) kfree(info)
+
+#endif /* !__ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE 0x10000000
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to
+ * access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SIGPENDING 1 /* signal pending */
+#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
+#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */
+#define TIF_SECCOMP 4 /* secure computing */
+#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
+#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
+#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
+#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
+#define TIF_FREEZE 19
+#define TIF_FIXADE 20 /* Fix address errors in software */
+#define TIF_LOGADE 21 /* Log address errors to syslog */
+#define TIF_32BIT_REGS 22 /* also implies 16/32 fprs */
+#define TIF_32BIT_ADDR 23 /* 32-bit address space (o32/n32) */
+#define TIF_FPUBOUND 24 /* thread bound to FPU-full CPU set */
+#define TIF_LOAD_WATCH 25 /* If set, load watch registers */
+#define TIF_SYSCALL_TRACE 31 /* syscall trace active */
+
+#ifdef CONFIG_MIPS32_O32
+#define TIF_32BIT TIF_32BIT_REGS
+#elif defined(CONFIG_MIPS32_N32)
+#define TIF_32BIT _TIF_32BIT_ADDR
+#endif /* CONFIG_MIPS32_O32 */
+
+#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
+#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1<<TIF_SECCOMP)
+#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
+#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_USEDFPU (1<<TIF_USEDFPU)
+#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
+#define _TIF_FIXADE (1<<TIF_FIXADE)
+#define _TIF_LOGADE (1<<TIF_LOGADE)
+#define _TIF_32BIT_REGS (1<<TIF_32BIT_REGS)
+#define _TIF_32BIT_ADDR (1<<TIF_32BIT_ADDR)
+#define _TIF_FPUBOUND (1<<TIF_FPUBOUND)
+#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)
+
+/* work to do in syscall_trace_leave() */
+#define _TIF_WORK_SYSCALL_EXIT (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
+
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK (0x0000ffef & \
+ ~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT))
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
new file mode 100644
index 00000000..bc14447e
--- /dev/null
+++ b/arch/mips/include/asm/time.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2001, 2002, MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (c) 2003 Maciej W. Rozycki
+ *
+ * include/asm-mips/time.h
+ * header file for the new style time.c file and time services.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef _ASM_TIME_H
+#define _ASM_TIME_H
+
+#include <linux/rtc.h>
+#include <linux/spinlock.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+
+extern spinlock_t rtc_lock;
+
+/*
+ * RTC ops. By default, they point to weak no-op RTC functions.
+ * rtc_mips_set_time - reverse the above translation and set time to RTC.
+ * rtc_mips_set_mmss - similar to rtc_set_time, but only min and sec need
+ * to be set. Used by RTC sync-up.
+ */
+extern int rtc_mips_set_time(unsigned long);
+extern int rtc_mips_set_mmss(unsigned long);
+
+/*
+ * board specific routines required by time_init().
+ */
+extern void plat_time_init(void);
+
+/*
+ * mips_hpt_frequency - must be set if you intend to use an R4k-compatible
+ * counter as a timer interrupt source.
+ */
+extern unsigned int mips_hpt_frequency;
+
+/*
+ * The performance counter IRQ on MIPS is a close relative to the timer IRQ
+ * so it lives here.
+ */
+extern int (*perf_irq)(void);
+
+/*
+ * Initialize the calling CPU's compare interrupt as clockevent device
+ */
+#ifdef CONFIG_CEVT_R4K_LIB
+extern unsigned int __weak get_c0_compare_int(void);
+extern int r4k_clockevent_init(void);
+#endif
+
+static inline int mips_clockevent_init(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ extern int smtc_clockevent_init(void);
+
+ return smtc_clockevent_init();
+#elif defined(CONFIG_CEVT_R4K)
+ return r4k_clockevent_init();
+#else
+ return -ENXIO;
+#endif
+}
+
+/*
+ * Initialize the count register as a clocksource
+ */
+#ifdef CONFIG_CSRC_R4K_LIB
+extern int init_r4k_clocksource(void);
+#endif
+
+static inline int init_mips_clocksource(void)
+{
+#ifdef CONFIG_CSRC_R4K
+ return init_r4k_clocksource();
+#else
+ return 0;
+#endif
+}
+
+static inline void clockevent_set_clock(struct clock_event_device *cd,
+ unsigned int clock)
+{
+ clockevents_calc_mult_shift(cd, clock, 4);
+}
+
+#endif /* _ASM_TIME_H */
diff --git a/arch/mips/include/asm/timex.h b/arch/mips/include/asm/timex.h
new file mode 100644
index 00000000..6529704a
--- /dev/null
+++ b/arch/mips/include/asm/timex.h
@@ -0,0 +1,43 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999, 2003 by Ralf Baechle
+ */
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#ifdef __KERNEL__
+
+#include <asm/mipsregs.h>
+
+/*
+ * This is the clock rate of the i8253 PIT. A MIPS system may not have
+ * a PIT by the symbol is used all over the kernel including some APIs.
+ * So keeping it defined to the number for the PIT is the only sane thing
+ * for now.
+ */
+#define CLOCK_TICK_RATE 1193182
+
+/*
+ * Standard way to access the cycle counter.
+ * Currently only used on SMP for scheduling.
+ *
+ * Only the low 32 bits are available as a continuously counting entity.
+ * But this only means we'll force a reschedule every 8 seconds or so,
+ * which isn't an evil thing.
+ *
+ * We know that all SMP capable CPUs have cycle counters.
+ */
+
+typedef unsigned int cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+ return 0;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TIMEX_H */
diff --git a/arch/mips/include/asm/titan_dep.h b/arch/mips/include/asm/titan_dep.h
new file mode 100644
index 00000000..fee1908c
--- /dev/null
+++ b/arch/mips/include/asm/titan_dep.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Board specific definititions for the PMC-Sierra Yosemite
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __TITAN_DEP_H__
+#define __TITAN_DEP_H__
+
+#include <asm/addrspace.h> /* for KSEG1ADDR() */
+#include <asm/byteorder.h> /* for cpu_to_le32() */
+
+#define TITAN_READ(ofs) \
+ (*(volatile u32 *)(ocd_base+(ofs)))
+#define TITAN_READ_16(ofs) \
+ (*(volatile u16 *)(ocd_base+(ofs)))
+#define TITAN_READ_8(ofs) \
+ (*(volatile u8 *)(ocd_base+(ofs)))
+
+#define TITAN_WRITE(ofs, data) \
+ do { *(volatile u32 *)(ocd_base+(ofs)) = (data); } while (0)
+#define TITAN_WRITE_16(ofs, data) \
+ do { *(volatile u16 *)(ocd_base+(ofs)) = (data); } while (0)
+#define TITAN_WRITE_8(ofs, data) \
+ do { *(volatile u8 *)(ocd_base+(ofs)) = (data); } while (0)
+
+/*
+ * PCI specific defines
+ */
+#define TITAN_PCI_0_CONFIG_ADDRESS 0x780
+#define TITAN_PCI_0_CONFIG_DATA 0x784
+
+/*
+ * HT specific defines
+ */
+#define RM9000x2_HTLINK_REG 0xbb000644
+#define RM9000x2_BASE_ADDR 0xbb000000
+
+#define OCD_BASE 0xfb000000UL
+#define OCD_SIZE 0x3000UL
+
+extern unsigned long ocd_base;
+
+/*
+ * OCD Registers
+ */
+#define RM9000x2_OCD_LKB5 0x0128 /* Ethernet */
+#define RM9000x2_OCD_LKM5 0x012c
+
+#define RM9000x2_OCD_LKB7 0x0138 /* HT Region 0 */
+#define RM9000x2_OCD_LKM7 0x013c
+#define RM9000x2_OCD_LKB8 0x0140 /* HT Region 1 */
+#define RM9000x2_OCD_LKM8 0x0144
+
+#define RM9000x2_OCD_LKB9 0x0148 /* Local Bus */
+#define RM9000x2_OCD_LKM9 0x014c
+#define RM9000x2_OCD_LKB10 0x0150
+#define RM9000x2_OCD_LKM10 0x0154
+#define RM9000x2_OCD_LKB11 0x0158
+#define RM9000x2_OCD_LKM11 0x015c
+#define RM9000x2_OCD_LKB12 0x0160
+#define RM9000x2_OCD_LKM12 0x0164
+
+#define RM9000x2_OCD_LKB13 0x0168 /* Scratch RAM */
+#define RM9000x2_OCD_LKM13 0x016c
+
+#define RM9000x2_OCD_LPD0 0x0200 /* Local Bus */
+#define RM9000x2_OCD_LPD1 0x0210
+#define RM9000x2_OCD_LPD2 0x0220
+#define RM9000x2_OCD_LPD3 0x0230
+
+#define RM9000x2_OCD_HTDVID 0x0600 /* HT Device Header */
+#define RM9000x2_OCD_HTSC 0x0604
+#define RM9000x2_OCD_HTCCR 0x0608
+#define RM9000x2_OCD_HTBHL 0x060c
+#define RM9000x2_OCD_HTBAR0 0x0610
+#define RM9000x2_OCD_HTBAR1 0x0614
+#define RM9000x2_OCD_HTBAR2 0x0618
+#define RM9000x2_OCD_HTBAR3 0x061c
+#define RM9000x2_OCD_HTBAR4 0x0620
+#define RM9000x2_OCD_HTBAR5 0x0624
+#define RM9000x2_OCD_HTCBCPT 0x0628
+#define RM9000x2_OCD_HTSDVID 0x062c
+#define RM9000x2_OCD_HTXRA 0x0630
+#define RM9000x2_OCD_HTCAP1 0x0634
+#define RM9000x2_OCD_HTIL 0x063c
+
+#define RM9000x2_OCD_HTLCC 0x0640 /* HT Capability Block */
+#define RM9000x2_OCD_HTLINK 0x0644
+#define RM9000x2_OCD_HTFQREV 0x0648
+
+#define RM9000x2_OCD_HTERCTL 0x0668 /* HT Controller */
+#define RM9000x2_OCD_HTRXDB 0x066c
+#define RM9000x2_OCD_HTIMPED 0x0670
+#define RM9000x2_OCD_HTSWIMP 0x0674
+#define RM9000x2_OCD_HTCAL 0x0678
+
+#define RM9000x2_OCD_HTBAA30 0x0680
+#define RM9000x2_OCD_HTBAA54 0x0684
+#define RM9000x2_OCD_HTMASK0 0x0688
+#define RM9000x2_OCD_HTMASK1 0x068c
+#define RM9000x2_OCD_HTMASK2 0x0690
+#define RM9000x2_OCD_HTMASK3 0x0694
+#define RM9000x2_OCD_HTMASK4 0x0698
+#define RM9000x2_OCD_HTMASK5 0x069c
+
+#define RM9000x2_OCD_HTIFCTL 0x06a0
+#define RM9000x2_OCD_HTPLL 0x06a4
+
+#define RM9000x2_OCD_HTSRI 0x06b0
+#define RM9000x2_OCD_HTRXNUM 0x06b4
+#define RM9000x2_OCD_HTTXNUM 0x06b8
+
+#define RM9000x2_OCD_HTTXCNT 0x06c8
+
+#define RM9000x2_OCD_HTERROR 0x06d8
+#define RM9000x2_OCD_HTRCRCE 0x06dc
+#define RM9000x2_OCD_HTEOI 0x06e0
+
+#define RM9000x2_OCD_CRCR 0x06f0
+
+#define RM9000x2_OCD_HTCFGA 0x06f8
+#define RM9000x2_OCD_HTCFGD 0x06fc
+
+#define RM9000x2_OCD_INTMSG 0x0a00
+
+#define RM9000x2_OCD_INTPIN0 0x0a40
+#define RM9000x2_OCD_INTPIN1 0x0a44
+#define RM9000x2_OCD_INTPIN2 0x0a48
+#define RM9000x2_OCD_INTPIN3 0x0a4c
+#define RM9000x2_OCD_INTPIN4 0x0a50
+#define RM9000x2_OCD_INTPIN5 0x0a54
+#define RM9000x2_OCD_INTPIN6 0x0a58
+#define RM9000x2_OCD_INTPIN7 0x0a5c
+#define RM9000x2_OCD_SEM 0x0a60
+#define RM9000x2_OCD_SEMSET 0x0a64
+#define RM9000x2_OCD_SEMCLR 0x0a68
+
+#define RM9000x2_OCD_TKT 0x0a70
+#define RM9000x2_OCD_TKTINC 0x0a74
+
+#define RM9000x2_OCD_NMICONFIG 0x0ac0 /* Interrupts */
+#define RM9000x2_OCD_INTP0PRI 0x1a80
+#define RM9000x2_OCD_INTP1PRI 0x1a80
+#define RM9000x2_OCD_INTP0STATUS0 0x1b00
+#define RM9000x2_OCD_INTP0MASK0 0x1b04
+#define RM9000x2_OCD_INTP0SET0 0x1b08
+#define RM9000x2_OCD_INTP0CLEAR0 0x1b0c
+#define RM9000x2_OCD_INTP0STATUS1 0x1b10
+#define RM9000x2_OCD_INTP0MASK1 0x1b14
+#define RM9000x2_OCD_INTP0SET1 0x1b18
+#define RM9000x2_OCD_INTP0CLEAR1 0x1b1c
+#define RM9000x2_OCD_INTP0STATUS2 0x1b20
+#define RM9000x2_OCD_INTP0MASK2 0x1b24
+#define RM9000x2_OCD_INTP0SET2 0x1b28
+#define RM9000x2_OCD_INTP0CLEAR2 0x1b2c
+#define RM9000x2_OCD_INTP0STATUS3 0x1b30
+#define RM9000x2_OCD_INTP0MASK3 0x1b34
+#define RM9000x2_OCD_INTP0SET3 0x1b38
+#define RM9000x2_OCD_INTP0CLEAR3 0x1b3c
+#define RM9000x2_OCD_INTP0STATUS4 0x1b40
+#define RM9000x2_OCD_INTP0MASK4 0x1b44
+#define RM9000x2_OCD_INTP0SET4 0x1b48
+#define RM9000x2_OCD_INTP0CLEAR4 0x1b4c
+#define RM9000x2_OCD_INTP0STATUS5 0x1b50
+#define RM9000x2_OCD_INTP0MASK5 0x1b54
+#define RM9000x2_OCD_INTP0SET5 0x1b58
+#define RM9000x2_OCD_INTP0CLEAR5 0x1b5c
+#define RM9000x2_OCD_INTP0STATUS6 0x1b60
+#define RM9000x2_OCD_INTP0MASK6 0x1b64
+#define RM9000x2_OCD_INTP0SET6 0x1b68
+#define RM9000x2_OCD_INTP0CLEAR6 0x1b6c
+#define RM9000x2_OCD_INTP0STATUS7 0x1b70
+#define RM9000x2_OCD_INTP0MASK7 0x1b74
+#define RM9000x2_OCD_INTP0SET7 0x1b78
+#define RM9000x2_OCD_INTP0CLEAR7 0x1b7c
+#define RM9000x2_OCD_INTP1STATUS0 0x2b00
+#define RM9000x2_OCD_INTP1MASK0 0x2b04
+#define RM9000x2_OCD_INTP1SET0 0x2b08
+#define RM9000x2_OCD_INTP1CLEAR0 0x2b0c
+#define RM9000x2_OCD_INTP1STATUS1 0x2b10
+#define RM9000x2_OCD_INTP1MASK1 0x2b14
+#define RM9000x2_OCD_INTP1SET1 0x2b18
+#define RM9000x2_OCD_INTP1CLEAR1 0x2b1c
+#define RM9000x2_OCD_INTP1STATUS2 0x2b20
+#define RM9000x2_OCD_INTP1MASK2 0x2b24
+#define RM9000x2_OCD_INTP1SET2 0x2b28
+#define RM9000x2_OCD_INTP1CLEAR2 0x2b2c
+#define RM9000x2_OCD_INTP1STATUS3 0x2b30
+#define RM9000x2_OCD_INTP1MASK3 0x2b34
+#define RM9000x2_OCD_INTP1SET3 0x2b38
+#define RM9000x2_OCD_INTP1CLEAR3 0x2b3c
+#define RM9000x2_OCD_INTP1STATUS4 0x2b40
+#define RM9000x2_OCD_INTP1MASK4 0x2b44
+#define RM9000x2_OCD_INTP1SET4 0x2b48
+#define RM9000x2_OCD_INTP1CLEAR4 0x2b4c
+#define RM9000x2_OCD_INTP1STATUS5 0x2b50
+#define RM9000x2_OCD_INTP1MASK5 0x2b54
+#define RM9000x2_OCD_INTP1SET5 0x2b58
+#define RM9000x2_OCD_INTP1CLEAR5 0x2b5c
+#define RM9000x2_OCD_INTP1STATUS6 0x2b60
+#define RM9000x2_OCD_INTP1MASK6 0x2b64
+#define RM9000x2_OCD_INTP1SET6 0x2b68
+#define RM9000x2_OCD_INTP1CLEAR6 0x2b6c
+#define RM9000x2_OCD_INTP1STATUS7 0x2b70
+#define RM9000x2_OCD_INTP1MASK7 0x2b74
+#define RM9000x2_OCD_INTP1SET7 0x2b78
+#define RM9000x2_OCD_INTP1CLEAR7 0x2b7c
+
+#define OCD_READ(reg) (*(volatile unsigned int *)(ocd_base + (reg)))
+#define OCD_WRITE(reg, val) \
+ do { *(volatile unsigned int *)(ocd_base + (reg)) = (val); } while (0)
+
+/*
+ * Hypertransport specific macros
+ */
+#define RM9K_WRITE(ofs, data) *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs) = data
+#define RM9K_WRITE_8(ofs, data) *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs) = data
+#define RM9K_WRITE_16(ofs, data) *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs) = data
+
+#define RM9K_READ(ofs, val) *(val) = *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs)
+#define RM9K_READ_8(ofs, val) *(val) = *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs)
+#define RM9K_READ_16(ofs, val) *(val) = *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs)
+
+#endif
diff --git a/arch/mips/include/asm/tlb.h b/arch/mips/include/asm/tlb.h
new file mode 100644
index 00000000..80d9dfcf
--- /dev/null
+++ b/arch/mips/include/asm/tlb.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_TLB_H
+#define __ASM_TLB_H
+
+/*
+ * MIPS doesn't need any special per-pte or per-vma handling, except
+ * we need to flush cache for area to be unmapped.
+ */
+#define tlb_start_vma(tlb, vma) \
+ do { \
+ if (!tlb->fullmm) \
+ flush_cache_range(vma, vma->vm_start, vma->vm_end); \
+ } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+
+/*
+ * .. because we flush the whole mm when it fills up.
+ */
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* __ASM_TLB_H */
diff --git a/arch/mips/include/asm/tlbdebug.h b/arch/mips/include/asm/tlbdebug.h
new file mode 100644
index 00000000..bb8f5c29
--- /dev/null
+++ b/arch/mips/include/asm/tlbdebug.h
@@ -0,0 +1,16 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 by Ralf Baechle
+ */
+#ifndef __ASM_TLBDEBUG_H
+#define __ASM_TLBDEBUG_H
+
+/*
+ * TLB debugging functions:
+ */
+extern void dump_tlb_all(void);
+
+#endif /* __ASM_TLBDEBUG_H */
diff --git a/arch/mips/include/asm/tlbflush.h b/arch/mips/include/asm/tlbflush.h
new file mode 100644
index 00000000..86b21de1
--- /dev/null
+++ b/arch/mips/include/asm/tlbflush.h
@@ -0,0 +1,47 @@
+#ifndef __ASM_TLBFLUSH_H
+#define __ASM_TLBFLUSH_H
+
+#include <linux/mm.h>
+
+/*
+ * TLB flushing:
+ *
+ * - flush_tlb_all() flushes all processes TLB entries
+ * - flush_tlb_mm(mm) flushes the specified mm context TLB entries
+ * - flush_tlb_page(vma, vmaddr) flushes one page
+ * - flush_tlb_range(vma, start, end) flushes a range of pages
+ * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ */
+extern void local_flush_tlb_all(void);
+extern void local_flush_tlb_mm(struct mm_struct *mm);
+extern void local_flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end);
+extern void local_flush_tlb_kernel_range(unsigned long start,
+ unsigned long end);
+extern void local_flush_tlb_page(struct vm_area_struct *vma,
+ unsigned long page);
+extern void local_flush_tlb_one(unsigned long vaddr);
+
+#ifdef CONFIG_SMP
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long,
+ unsigned long);
+extern void flush_tlb_kernel_range(unsigned long, unsigned long);
+extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
+extern void flush_tlb_one(unsigned long vaddr);
+
+#else /* CONFIG_SMP */
+
+#define flush_tlb_all() local_flush_tlb_all()
+#define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
+#define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, end)
+#define flush_tlb_kernel_range(vmaddr,end) \
+ local_flush_tlb_kernel_range(vmaddr, end)
+#define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page)
+#define flush_tlb_one(vaddr) local_flush_tlb_one(vaddr)
+
+#endif /* CONFIG_SMP */
+
+#endif /* __ASM_TLBFLUSH_H */
diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h
new file mode 100644
index 00000000..259145e0
--- /dev/null
+++ b/arch/mips/include/asm/topology.h
@@ -0,0 +1,17 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 by Ralf Baechle
+ */
+#ifndef __ASM_TOPOLOGY_H
+#define __ASM_TOPOLOGY_H
+
+#include <topology.h>
+
+#ifdef CONFIG_SMP
+#define smt_capable() (smp_num_siblings > 1)
+#endif
+
+#endif /* __ASM_TOPOLOGY_H */
diff --git a/arch/mips/include/asm/traps.h b/arch/mips/include/asm/traps.h
new file mode 100644
index 00000000..90ff2f49
--- /dev/null
+++ b/arch/mips/include/asm/traps.h
@@ -0,0 +1,28 @@
+/*
+ * Trap handling definitions.
+ *
+ * Copyright (C) 2002, 2003 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_TRAPS_H
+#define _ASM_TRAPS_H
+
+/*
+ * Possible status responses for a board_be_handler backend.
+ */
+#define MIPS_BE_DISCARD 0 /* return with no action */
+#define MIPS_BE_FIXUP 1 /* return to the fixup code */
+#define MIPS_BE_FATAL 2 /* treat as an unrecoverable error */
+
+extern void (*board_be_init)(void);
+extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
+
+extern void (*board_nmi_handler_setup)(void);
+extern void (*board_ejtag_handler_setup)(void);
+extern void (*board_bind_eic_interrupt)(int irq, int regset);
+
+#endif /* _ASM_TRAPS_H */
diff --git a/arch/mips/include/asm/txx9/boards.h b/arch/mips/include/asm/txx9/boards.h
new file mode 100644
index 00000000..cbe9476d
--- /dev/null
+++ b/arch/mips/include/asm/txx9/boards.h
@@ -0,0 +1,13 @@
+#ifdef CONFIG_TOSHIBA_JMR3927
+BOARD_VEC(jmr3927_vec)
+#endif
+#ifdef CONFIG_TOSHIBA_RBTX4927
+BOARD_VEC(rbtx4927_vec)
+BOARD_VEC(rbtx4937_vec)
+#endif
+#ifdef CONFIG_TOSHIBA_RBTX4938
+BOARD_VEC(rbtx4938_vec)
+#endif
+#ifdef CONFIG_TOSHIBA_RBTX4939
+BOARD_VEC(rbtx4939_vec)
+#endif
diff --git a/arch/mips/include/asm/txx9/dmac.h b/arch/mips/include/asm/txx9/dmac.h
new file mode 100644
index 00000000..5e9151fc
--- /dev/null
+++ b/arch/mips/include/asm/txx9/dmac.h
@@ -0,0 +1,51 @@
+/*
+ * TXx9 SoC DMA Controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_TXX9_DMAC_H
+#define __ASM_TXX9_DMAC_H
+
+#include <linux/dmaengine.h>
+
+#define TXX9_DMA_MAX_NR_CHANNELS 4
+
+/**
+ * struct txx9dmac_platform_data - Controller configuration parameters
+ * @memcpy_chan: Channel used for DMA_MEMCPY
+ * @have_64bit_regs: DMAC have 64 bit registers
+ */
+struct txx9dmac_platform_data {
+ int memcpy_chan;
+ bool have_64bit_regs;
+};
+
+/**
+ * struct txx9dmac_chan_platform_data - Channel configuration parameters
+ * @dmac_dev: A platform device for DMAC
+ */
+struct txx9dmac_chan_platform_data {
+ struct platform_device *dmac_dev;
+};
+
+/**
+ * struct txx9dmac_slave - Controller-specific information about a slave
+ * @tx_reg: physical address of data register used for
+ * memory-to-peripheral transfers
+ * @rx_reg: physical address of data register used for
+ * peripheral-to-memory transfers
+ * @reg_width: peripheral register width
+ */
+struct txx9dmac_slave {
+ u64 tx_reg;
+ u64 rx_reg;
+ unsigned int reg_width;
+};
+
+void txx9_dmac_init(int id, unsigned long baseaddr, int irq,
+ const struct txx9dmac_platform_data *pdata);
+
+#endif /* __ASM_TXX9_DMAC_H */
diff --git a/arch/mips/include/asm/txx9/generic.h b/arch/mips/include/asm/txx9/generic.h
new file mode 100644
index 00000000..64887d3c
--- /dev/null
+++ b/arch/mips/include/asm/txx9/generic.h
@@ -0,0 +1,99 @@
+/*
+ * linux/include/asm-mips/txx9/generic.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_TXX9_GENERIC_H
+#define __ASM_TXX9_GENERIC_H
+
+#include <linux/init.h>
+#include <linux/ioport.h> /* for struct resource */
+
+extern struct resource txx9_ce_res[];
+#define TXX9_CE(n) (unsigned long)(txx9_ce_res[(n)].start)
+extern unsigned int txx9_pcode;
+extern char txx9_pcode_str[8];
+void txx9_reg_res_init(unsigned int pcode, unsigned long base,
+ unsigned long size);
+
+extern unsigned int txx9_master_clock;
+extern unsigned int txx9_cpu_clock;
+extern unsigned int txx9_gbus_clock;
+#define TXX9_IMCLK (txx9_gbus_clock / 2)
+
+extern int txx9_ccfg_toeon;
+struct uart_port;
+int early_serial_txx9_setup(struct uart_port *port);
+
+struct pci_dev;
+struct txx9_board_vec {
+ const char *system;
+ void (*prom_init)(void);
+ void (*mem_setup)(void);
+ void (*irq_setup)(void);
+ void (*time_init)(void);
+ void (*arch_init)(void);
+ void (*device_init)(void);
+#ifdef CONFIG_PCI
+ int (*pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
+#endif
+};
+extern struct txx9_board_vec *txx9_board_vec;
+extern int (*txx9_irq_dispatch)(int pending);
+const char *prom_getenv(const char *name);
+void txx9_wdt_init(unsigned long base);
+void txx9_wdt_now(unsigned long base);
+void txx9_spi_init(int busid, unsigned long base, int irq);
+void txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr);
+void txx9_sio_init(unsigned long baseaddr, int irq,
+ unsigned int line, unsigned int sclk, int nocts);
+void prom_putchar(char c);
+#ifdef CONFIG_EARLY_PRINTK
+extern void (*txx9_prom_putchar)(char c);
+void txx9_sio_putchar_init(unsigned long baseaddr);
+#else
+static inline void txx9_sio_putchar_init(unsigned long baseaddr)
+{
+}
+#endif
+
+struct physmap_flash_data;
+void txx9_physmap_flash_init(int no, unsigned long addr, unsigned long size,
+ const struct physmap_flash_data *pdata);
+
+/* 8 bit version of __fls(): find first bit set (returns 0..7) */
+static inline unsigned int __fls8(unsigned char x)
+{
+ int r = 7;
+
+ if (!(x & 0xf0)) {
+ r -= 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0)) {
+ r -= 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80))
+ r -= 1;
+ return r;
+}
+
+void txx9_iocled_init(unsigned long baseaddr,
+ int basenum, unsigned int num, int lowactive,
+ const char *color, char **deftriggers);
+
+/* 7SEG LED */
+void txx9_7segled_init(unsigned int num,
+ void (*putc)(unsigned int pos, unsigned char val));
+int txx9_7segled_putc(unsigned int pos, char c);
+
+void __init txx9_aclc_init(unsigned long baseaddr, int irq,
+ unsigned int dmac_id,
+ unsigned int dma_chan_out,
+ unsigned int dma_chan_in);
+void __init txx9_sramc_init(struct resource *r);
+
+#endif /* __ASM_TXX9_GENERIC_H */
diff --git a/arch/mips/include/asm/txx9/jmr3927.h b/arch/mips/include/asm/txx9/jmr3927.h
new file mode 100644
index 00000000..a409c446
--- /dev/null
+++ b/arch/mips/include/asm/txx9/jmr3927.h
@@ -0,0 +1,180 @@
+/*
+ * Defines for the TJSYS JMR-TX3927
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ */
+#ifndef __ASM_TXX9_JMR3927_H
+#define __ASM_TXX9_JMR3927_H
+
+#include <asm/txx9/tx3927.h>
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/txx9irq.h>
+
+/* CS */
+#define JMR3927_ROMCE0 0x1fc00000 /* 4M */
+#define JMR3927_ROMCE1 0x1e000000 /* 4M */
+#define JMR3927_ROMCE2 0x14000000 /* 16M */
+#define JMR3927_ROMCE3 0x10000000 /* 64M */
+#define JMR3927_ROMCE5 0x1d000000 /* 4M */
+#define JMR3927_SDCS0 0x00000000 /* 32M */
+#define JMR3927_SDCS1 0x02000000 /* 32M */
+/* PCI Direct Mappings */
+
+#define JMR3927_PCIMEM 0x08000000
+#define JMR3927_PCIMEM_SIZE 0x08000000 /* 128M */
+#define JMR3927_PCIIO 0x15000000
+#define JMR3927_PCIIO_SIZE 0x01000000 /* 16M */
+
+#define JMR3927_SDRAM_SIZE 0x02000000 /* 32M */
+#define JMR3927_PORT_BASE KSEG1
+
+/* Address map (virtual address) */
+#define JMR3927_ROM0_BASE (KSEG1 + JMR3927_ROMCE0)
+#define JMR3927_ROM1_BASE (KSEG1 + JMR3927_ROMCE1)
+#define JMR3927_IOC_BASE (KSEG1 + JMR3927_ROMCE2)
+#define JMR3927_PCIMEM_BASE (KSEG1 + JMR3927_PCIMEM)
+#define JMR3927_PCIIO_BASE (KSEG1 + JMR3927_PCIIO)
+
+#define JMR3927_IOC_REV_ADDR (JMR3927_IOC_BASE + 0x00000000)
+#define JMR3927_IOC_NVRAMB_ADDR (JMR3927_IOC_BASE + 0x00010000)
+#define JMR3927_IOC_LED_ADDR (JMR3927_IOC_BASE + 0x00020000)
+#define JMR3927_IOC_DIPSW_ADDR (JMR3927_IOC_BASE + 0x00030000)
+#define JMR3927_IOC_BREV_ADDR (JMR3927_IOC_BASE + 0x00040000)
+#define JMR3927_IOC_DTR_ADDR (JMR3927_IOC_BASE + 0x00050000)
+#define JMR3927_IOC_INTS1_ADDR (JMR3927_IOC_BASE + 0x00080000)
+#define JMR3927_IOC_INTS2_ADDR (JMR3927_IOC_BASE + 0x00090000)
+#define JMR3927_IOC_INTM_ADDR (JMR3927_IOC_BASE + 0x000a0000)
+#define JMR3927_IOC_INTP_ADDR (JMR3927_IOC_BASE + 0x000b0000)
+#define JMR3927_IOC_RESET_ADDR (JMR3927_IOC_BASE + 0x000f0000)
+
+/* Flash ROM */
+#define JMR3927_FLASH_BASE (JMR3927_ROM0_BASE)
+#define JMR3927_FLASH_SIZE 0x00400000
+
+/* bits for IOC_REV/IOC_BREV (high byte) */
+#define JMR3927_IDT_MASK 0xfc
+#define JMR3927_REV_MASK 0x03
+#define JMR3927_IOC_IDT 0xe0
+
+/* bits for IOC_INTS1/IOC_INTS2/IOC_INTM/IOC_INTP (high byte) */
+#define JMR3927_IOC_INTB_PCIA 0
+#define JMR3927_IOC_INTB_PCIB 1
+#define JMR3927_IOC_INTB_PCIC 2
+#define JMR3927_IOC_INTB_PCID 3
+#define JMR3927_IOC_INTB_MODEM 4
+#define JMR3927_IOC_INTB_INT6 5
+#define JMR3927_IOC_INTB_INT7 6
+#define JMR3927_IOC_INTB_SOFT 7
+#define JMR3927_IOC_INTF_PCIA (1 << JMR3927_IOC_INTF_PCIA)
+#define JMR3927_IOC_INTF_PCIB (1 << JMR3927_IOC_INTB_PCIB)
+#define JMR3927_IOC_INTF_PCIC (1 << JMR3927_IOC_INTB_PCIC)
+#define JMR3927_IOC_INTF_PCID (1 << JMR3927_IOC_INTB_PCID)
+#define JMR3927_IOC_INTF_MODEM (1 << JMR3927_IOC_INTB_MODEM)
+#define JMR3927_IOC_INTF_INT6 (1 << JMR3927_IOC_INTB_INT6)
+#define JMR3927_IOC_INTF_INT7 (1 << JMR3927_IOC_INTB_INT7)
+#define JMR3927_IOC_INTF_SOFT (1 << JMR3927_IOC_INTB_SOFT)
+
+/* bits for IOC_RESET (high byte) */
+#define JMR3927_IOC_RESET_CPU 1
+#define JMR3927_IOC_RESET_PCI 2
+
+#if defined(__BIG_ENDIAN)
+#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned char *)(a)) = (d))
+#define jmr3927_ioc_reg_in(a) (*(volatile unsigned char *)(a))
+#elif defined(__LITTLE_ENDIAN)
+#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned char *)((a)^1)) = (d))
+#define jmr3927_ioc_reg_in(a) (*(volatile unsigned char *)((a)^1))
+#else
+#error "No Endian"
+#endif
+
+/* LED macro */
+#define jmr3927_led_set(n/*0-16*/) jmr3927_ioc_reg_out(~(n), JMR3927_IOC_LED_ADDR)
+
+#define jmr3927_led_and_set(n/*0-16*/) jmr3927_ioc_reg_out((~(n)) & jmr3927_ioc_reg_in(JMR3927_IOC_LED_ADDR), JMR3927_IOC_LED_ADDR)
+
+/* DIPSW4 macro */
+#define jmr3927_dipsw1() (gpio_get_value(11) == 0)
+#define jmr3927_dipsw2() (gpio_get_value(10) == 0)
+#define jmr3927_dipsw3() ((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 2) == 0)
+#define jmr3927_dipsw4() ((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 1) == 0)
+
+/*
+ * IRQ mappings
+ */
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an JMR machine. Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define JMR3927_NR_IRQ_IRC 16 /* On-Chip IRC */
+#define JMR3927_NR_IRQ_IOC 8 /* PCI/MODEM/INT[6:7] */
+
+#define JMR3927_IRQ_IRC TXX9_IRQ_BASE
+#define JMR3927_IRQ_IOC (JMR3927_IRQ_IRC + JMR3927_NR_IRQ_IRC)
+#define JMR3927_IRQ_END (JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC)
+
+#define JMR3927_IRQ_IRC_INT0 (JMR3927_IRQ_IRC + TX3927_IR_INT0)
+#define JMR3927_IRQ_IRC_INT1 (JMR3927_IRQ_IRC + TX3927_IR_INT1)
+#define JMR3927_IRQ_IRC_INT2 (JMR3927_IRQ_IRC + TX3927_IR_INT2)
+#define JMR3927_IRQ_IRC_INT3 (JMR3927_IRQ_IRC + TX3927_IR_INT3)
+#define JMR3927_IRQ_IRC_INT4 (JMR3927_IRQ_IRC + TX3927_IR_INT4)
+#define JMR3927_IRQ_IRC_INT5 (JMR3927_IRQ_IRC + TX3927_IR_INT5)
+#define JMR3927_IRQ_IRC_SIO0 (JMR3927_IRQ_IRC + TX3927_IR_SIO0)
+#define JMR3927_IRQ_IRC_SIO1 (JMR3927_IRQ_IRC + TX3927_IR_SIO1)
+#define JMR3927_IRQ_IRC_SIO(ch) (JMR3927_IRQ_IRC + TX3927_IR_SIO(ch))
+#define JMR3927_IRQ_IRC_DMA (JMR3927_IRQ_IRC + TX3927_IR_DMA)
+#define JMR3927_IRQ_IRC_PIO (JMR3927_IRQ_IRC + TX3927_IR_PIO)
+#define JMR3927_IRQ_IRC_PCI (JMR3927_IRQ_IRC + TX3927_IR_PCI)
+#define JMR3927_IRQ_IRC_TMR(ch) (JMR3927_IRQ_IRC + TX3927_IR_TMR(ch))
+#define JMR3927_IRQ_IOC_PCIA (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA)
+#define JMR3927_IRQ_IOC_PCIB (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB)
+#define JMR3927_IRQ_IOC_PCIC (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC)
+#define JMR3927_IRQ_IOC_PCID (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCID)
+#define JMR3927_IRQ_IOC_MODEM (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_MODEM)
+#define JMR3927_IRQ_IOC_INT6 (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT6)
+#define JMR3927_IRQ_IOC_INT7 (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT7)
+#define JMR3927_IRQ_IOC_SOFT (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_SOFT)
+
+/* IOC (PCI, MODEM) */
+#define JMR3927_IRQ_IOCINT JMR3927_IRQ_IRC_INT1
+/* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */
+#define JMR3927_IRQ_ETHER0 JMR3927_IRQ_IRC_INT3
+
+/* Clocks */
+#define JMR3927_CORECLK 132710400 /* 132.7MHz */
+
+/*
+ * TX3927 Pin Configuration:
+ *
+ * PCFG bits Avail Dead
+ * SELSIO[1:0]:11 RXD[1:0], TXD[1:0] PIO[6:3]
+ * SELSIOC[0]:1 CTS[0], RTS[0] INT[5:4]
+ * SELSIOC[1]:0,SELDSF:0, GSDAO[0],GPCST[3] CTS[1], RTS[1],DSF,
+ * GDBGE* PIO[2:1]
+ * SELDMA[2]:1 DMAREQ[2],DMAACK[2] PIO[13:12]
+ * SELTMR[2:0]:000 TIMER[1:0]
+ * SELCS:0,SELDMA[1]:0 PIO[11;10] SDCS_CE[7:6],
+ * DMAREQ[1],DMAACK[1]
+ * SELDMA[0]:1 DMAREQ[0],DMAACK[0] PIO[9:8]
+ * SELDMA[3]:1 DMAREQ[3],DMAACK[3] PIO[15:14]
+ * SELDONE:1 DMADONE PIO[7]
+ *
+ * Usable pins are:
+ * RXD[1;0],TXD[1:0],CTS[0],RTS[0],
+ * DMAREQ[0,2,3],DMAACK[0,2,3],DMADONE,PIO[0,10,11]
+ * INT[3:0]
+ */
+
+void jmr3927_prom_init(void);
+void jmr3927_irq_setup(void);
+struct pci_dev;
+int jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+
+#endif /* __ASM_TXX9_JMR3927_H */
diff --git a/arch/mips/include/asm/txx9/ndfmc.h b/arch/mips/include/asm/txx9/ndfmc.h
new file mode 100644
index 00000000..fa67f3df
--- /dev/null
+++ b/arch/mips/include/asm/txx9/ndfmc.h
@@ -0,0 +1,30 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2007
+ */
+#ifndef __ASM_TXX9_NDFMC_H
+#define __ASM_TXX9_NDFMC_H
+
+#define NDFMC_PLAT_FLAG_USE_BSPRT 0x01
+#define NDFMC_PLAT_FLAG_NO_RSTR 0x02
+#define NDFMC_PLAT_FLAG_HOLDADD 0x04
+#define NDFMC_PLAT_FLAG_DUMMYWRITE 0x08
+
+struct txx9ndfmc_platform_data {
+ unsigned int shift;
+ unsigned int gbus_clock;
+ unsigned int hold; /* hold time in nanosecond */
+ unsigned int spw; /* strobe pulse width in nanosecond */
+ unsigned int flags;
+ unsigned char ch_mask; /* available channel bitmask */
+ unsigned char wp_mask; /* write-protect bitmask */
+ unsigned char wide_mask; /* 16bit-nand bitmask */
+};
+
+void txx9_ndfmc_init(unsigned long baseaddr,
+ const struct txx9ndfmc_platform_data *plat_data);
+
+#endif /* __ASM_TXX9_NDFMC_H */
diff --git a/arch/mips/include/asm/txx9/pci.h b/arch/mips/include/asm/txx9/pci.h
new file mode 100644
index 00000000..3d325290
--- /dev/null
+++ b/arch/mips/include/asm/txx9/pci.h
@@ -0,0 +1,39 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_TXX9_PCI_H
+#define __ASM_TXX9_PCI_H
+
+#include <linux/pci.h>
+
+extern struct pci_controller txx9_primary_pcic;
+struct pci_controller *
+txx9_alloc_pci_controller(struct pci_controller *pcic,
+ unsigned long mem_base, unsigned long mem_size,
+ unsigned long io_base, unsigned long io_size);
+
+int txx9_pci66_check(struct pci_controller *hose, int top_bus,
+ int current_bus);
+extern int txx9_pci_mem_high __initdata;
+
+extern int txx9_pci_option;
+#define TXX9_PCI_OPT_PICMG 0x0002
+#define TXX9_PCI_OPT_CLK_33 0x0008
+#define TXX9_PCI_OPT_CLK_66 0x0010
+#define TXX9_PCI_OPT_CLK_MASK \
+ (TXX9_PCI_OPT_CLK_33 | TXX9_PCI_OPT_CLK_66)
+#define TXX9_PCI_OPT_CLK_AUTO TXX9_PCI_OPT_CLK_MASK
+
+enum txx9_pci_err_action {
+ TXX9_PCI_ERR_REPORT,
+ TXX9_PCI_ERR_IGNORE,
+ TXX9_PCI_ERR_PANIC,
+};
+extern enum txx9_pci_err_action txx9_pci_err_action;
+
+extern char * (*txx9_board_pcibios_setup)(char *str);
+char *txx9_pcibios_setup(char *str);
+
+#endif /* __ASM_TXX9_PCI_H */
diff --git a/arch/mips/include/asm/txx9/rbtx4927.h b/arch/mips/include/asm/txx9/rbtx4927.h
new file mode 100644
index 00000000..b2adab3d
--- /dev/null
+++ b/arch/mips/include/asm/txx9/rbtx4927.h
@@ -0,0 +1,92 @@
+/*
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __ASM_TXX9_RBTX4927_H
+#define __ASM_TXX9_RBTX4927_H
+
+#include <asm/txx9/tx4927.h>
+
+#define RBTX4927_PCIMEM 0x08000000
+#define RBTX4927_PCIMEM_SIZE 0x08000000
+#define RBTX4927_PCIIO 0x16000000
+#define RBTX4927_PCIIO_SIZE 0x01000000
+
+#define RBTX4927_LED_ADDR (IO_BASE + TXX9_CE(2) + 0x00001000)
+#define RBTX4927_IMASK_ADDR (IO_BASE + TXX9_CE(2) + 0x00002000)
+#define RBTX4927_IMSTAT_ADDR (IO_BASE + TXX9_CE(2) + 0x00002006)
+#define RBTX4927_SOFTINT_ADDR (IO_BASE + TXX9_CE(2) + 0x00003000)
+#define RBTX4927_SOFTRESET_ADDR (IO_BASE + TXX9_CE(2) + 0x0000f000)
+#define RBTX4927_SOFTRESETLOCK_ADDR (IO_BASE + TXX9_CE(2) + 0x0000f002)
+#define RBTX4927_PCIRESET_ADDR (IO_BASE + TXX9_CE(2) + 0x0000f006)
+#define RBTX4927_BRAMRTC_BASE (IO_BASE + TXX9_CE(2) + 0x00010000)
+#define RBTX4927_ETHER_BASE (IO_BASE + TXX9_CE(2) + 0x00020000)
+
+/* Ethernet port address */
+#define RBTX4927_ETHER_ADDR (RBTX4927_ETHER_BASE + 0x280)
+
+#define rbtx4927_imask_addr ((__u8 __iomem *)RBTX4927_IMASK_ADDR)
+#define rbtx4927_imstat_addr ((__u8 __iomem *)RBTX4927_IMSTAT_ADDR)
+#define rbtx4927_softint_addr ((__u8 __iomem *)RBTX4927_SOFTINT_ADDR)
+#define rbtx4927_softreset_addr ((__u8 __iomem *)RBTX4927_SOFTRESET_ADDR)
+#define rbtx4927_softresetlock_addr \
+ ((__u8 __iomem *)RBTX4927_SOFTRESETLOCK_ADDR)
+#define rbtx4927_pcireset_addr ((__u8 __iomem *)RBTX4927_PCIRESET_ADDR)
+
+/* bits for ISTAT/IMASK/IMSTAT */
+#define RBTX4927_INTB_PCID 0
+#define RBTX4927_INTB_PCIC 1
+#define RBTX4927_INTB_PCIB 2
+#define RBTX4927_INTB_PCIA 3
+#define RBTX4927_INTF_PCID (1 << RBTX4927_INTB_PCID)
+#define RBTX4927_INTF_PCIC (1 << RBTX4927_INTB_PCIC)
+#define RBTX4927_INTF_PCIB (1 << RBTX4927_INTB_PCIB)
+#define RBTX4927_INTF_PCIA (1 << RBTX4927_INTB_PCIA)
+
+#define RBTX4927_NR_IRQ_IOC 8 /* IOC */
+
+#define RBTX4927_IRQ_IOC (TXX9_IRQ_BASE + TX4927_NUM_IR)
+#define RBTX4927_IRQ_IOC_PCID (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCID)
+#define RBTX4927_IRQ_IOC_PCIC (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIC)
+#define RBTX4927_IRQ_IOC_PCIB (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIB)
+#define RBTX4927_IRQ_IOC_PCIA (RBTX4927_IRQ_IOC + RBTX4927_INTB_PCIA)
+
+#define RBTX4927_IRQ_IOCINT (TXX9_IRQ_BASE + TX4927_IR_INT(1))
+
+#ifdef CONFIG_PCI
+#define RBTX4927_ISA_IO_OFFSET RBTX4927_PCIIO
+#else
+#define RBTX4927_ISA_IO_OFFSET 0
+#endif
+
+#define RBTX4927_RTL_8019_BASE (RBTX4927_ETHER_ADDR - mips_io_port_base)
+#define RBTX4927_RTL_8019_IRQ (TXX9_IRQ_BASE + TX4927_IR_INT(3))
+
+void rbtx4927_prom_init(void);
+void rbtx4927_irq_setup(void);
+struct pci_dev;
+int rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+
+#endif /* __ASM_TXX9_RBTX4927_H */
diff --git a/arch/mips/include/asm/txx9/rbtx4938.h b/arch/mips/include/asm/txx9/rbtx4938.h
new file mode 100644
index 00000000..9f0441a2
--- /dev/null
+++ b/arch/mips/include/asm/txx9/rbtx4938.h
@@ -0,0 +1,145 @@
+/*
+ * Definitions for TX4937/TX4938
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TXX9_RBTX4938_H
+#define __ASM_TXX9_RBTX4938_H
+
+#include <asm/addrspace.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9/tx4938.h>
+
+/* Address map */
+#define RBTX4938_FPGA_REG_ADDR (IO_BASE + TXX9_CE(2) + 0x00000000)
+#define RBTX4938_FPGA_REV_ADDR (IO_BASE + TXX9_CE(2) + 0x00000002)
+#define RBTX4938_CONFIG1_ADDR (IO_BASE + TXX9_CE(2) + 0x00000004)
+#define RBTX4938_CONFIG2_ADDR (IO_BASE + TXX9_CE(2) + 0x00000006)
+#define RBTX4938_CONFIG3_ADDR (IO_BASE + TXX9_CE(2) + 0x00000008)
+#define RBTX4938_LED_ADDR (IO_BASE + TXX9_CE(2) + 0x00001000)
+#define RBTX4938_DIPSW_ADDR (IO_BASE + TXX9_CE(2) + 0x00001002)
+#define RBTX4938_BDIPSW_ADDR (IO_BASE + TXX9_CE(2) + 0x00001004)
+#define RBTX4938_IMASK_ADDR (IO_BASE + TXX9_CE(2) + 0x00002000)
+#define RBTX4938_IMASK2_ADDR (IO_BASE + TXX9_CE(2) + 0x00002002)
+#define RBTX4938_INTPOL_ADDR (IO_BASE + TXX9_CE(2) + 0x00002004)
+#define RBTX4938_ISTAT_ADDR (IO_BASE + TXX9_CE(2) + 0x00002006)
+#define RBTX4938_ISTAT2_ADDR (IO_BASE + TXX9_CE(2) + 0x00002008)
+#define RBTX4938_IMSTAT_ADDR (IO_BASE + TXX9_CE(2) + 0x0000200a)
+#define RBTX4938_IMSTAT2_ADDR (IO_BASE + TXX9_CE(2) + 0x0000200c)
+#define RBTX4938_SOFTINT_ADDR (IO_BASE + TXX9_CE(2) + 0x00003000)
+#define RBTX4938_PIOSEL_ADDR (IO_BASE + TXX9_CE(2) + 0x00005000)
+#define RBTX4938_SPICS_ADDR (IO_BASE + TXX9_CE(2) + 0x00005002)
+#define RBTX4938_SFPWR_ADDR (IO_BASE + TXX9_CE(2) + 0x00005008)
+#define RBTX4938_SFVOL_ADDR (IO_BASE + TXX9_CE(2) + 0x0000500a)
+#define RBTX4938_SOFTRESET_ADDR (IO_BASE + TXX9_CE(2) + 0x00007000)
+#define RBTX4938_SOFTRESETLOCK_ADDR (IO_BASE + TXX9_CE(2) + 0x00007002)
+#define RBTX4938_PCIRESET_ADDR (IO_BASE + TXX9_CE(2) + 0x00007004)
+#define RBTX4938_ETHER_BASE (IO_BASE + TXX9_CE(2) + 0x00020000)
+
+/* Ethernet port address (Jumperless Mode (W12:Open)) */
+#define RBTX4938_ETHER_ADDR (RBTX4938_ETHER_BASE + 0x280)
+
+/* bits for ISTAT/IMASK/IMSTAT */
+#define RBTX4938_INTB_PCID 0
+#define RBTX4938_INTB_PCIC 1
+#define RBTX4938_INTB_PCIB 2
+#define RBTX4938_INTB_PCIA 3
+#define RBTX4938_INTB_RTC 4
+#define RBTX4938_INTB_ATA 5
+#define RBTX4938_INTB_MODEM 6
+#define RBTX4938_INTB_SWINT 7
+#define RBTX4938_INTF_PCID (1 << RBTX4938_INTB_PCID)
+#define RBTX4938_INTF_PCIC (1 << RBTX4938_INTB_PCIC)
+#define RBTX4938_INTF_PCIB (1 << RBTX4938_INTB_PCIB)
+#define RBTX4938_INTF_PCIA (1 << RBTX4938_INTB_PCIA)
+#define RBTX4938_INTF_RTC (1 << RBTX4938_INTB_RTC)
+#define RBTX4938_INTF_ATA (1 << RBTX4938_INTB_ATA)
+#define RBTX4938_INTF_MODEM (1 << RBTX4938_INTB_MODEM)
+#define RBTX4938_INTF_SWINT (1 << RBTX4938_INTB_SWINT)
+
+#define rbtx4938_fpga_rev_addr ((__u8 __iomem *)RBTX4938_FPGA_REV_ADDR)
+#define rbtx4938_led_addr ((__u8 __iomem *)RBTX4938_LED_ADDR)
+#define rbtx4938_dipsw_addr ((__u8 __iomem *)RBTX4938_DIPSW_ADDR)
+#define rbtx4938_bdipsw_addr ((__u8 __iomem *)RBTX4938_BDIPSW_ADDR)
+#define rbtx4938_imask_addr ((__u8 __iomem *)RBTX4938_IMASK_ADDR)
+#define rbtx4938_imask2_addr ((__u8 __iomem *)RBTX4938_IMASK2_ADDR)
+#define rbtx4938_intpol_addr ((__u8 __iomem *)RBTX4938_INTPOL_ADDR)
+#define rbtx4938_istat_addr ((__u8 __iomem *)RBTX4938_ISTAT_ADDR)
+#define rbtx4938_istat2_addr ((__u8 __iomem *)RBTX4938_ISTAT2_ADDR)
+#define rbtx4938_imstat_addr ((__u8 __iomem *)RBTX4938_IMSTAT_ADDR)
+#define rbtx4938_imstat2_addr ((__u8 __iomem *)RBTX4938_IMSTAT2_ADDR)
+#define rbtx4938_softint_addr ((__u8 __iomem *)RBTX4938_SOFTINT_ADDR)
+#define rbtx4938_piosel_addr ((__u8 __iomem *)RBTX4938_PIOSEL_ADDR)
+#define rbtx4938_spics_addr ((__u8 __iomem *)RBTX4938_SPICS_ADDR)
+#define rbtx4938_sfpwr_addr ((__u8 __iomem *)RBTX4938_SFPWR_ADDR)
+#define rbtx4938_sfvol_addr ((__u8 __iomem *)RBTX4938_SFVOL_ADDR)
+#define rbtx4938_softreset_addr ((__u8 __iomem *)RBTX4938_SOFTRESET_ADDR)
+#define rbtx4938_softresetlock_addr \
+ ((__u8 __iomem *)RBTX4938_SOFTRESETLOCK_ADDR)
+#define rbtx4938_pcireset_addr ((__u8 __iomem *)RBTX4938_PCIRESET_ADDR)
+
+/*
+ * IRQ mappings
+ */
+
+#define RBTX4938_SOFT_INT0 0 /* not used */
+#define RBTX4938_SOFT_INT1 1 /* not used */
+#define RBTX4938_IRC_INT 2
+#define RBTX4938_TIMER_INT 7
+
+/* These are the virtual IRQ numbers, we divide all IRQ's into
+ * 'spaces', the 'space' determines where and how to enable/disable
+ * that particular IRQ on an RBTX4938 machine. Add new 'spaces' as new
+ * IRQ hardware is supported.
+ */
+#define RBTX4938_NR_IRQ_IOC 8
+
+#define RBTX4938_IRQ_IRC TXX9_IRQ_BASE
+#define RBTX4938_IRQ_IOC (TXX9_IRQ_BASE + TX4938_NUM_IR)
+#define RBTX4938_IRQ_END (RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC)
+
+#define RBTX4938_IRQ_IRC_ECCERR (RBTX4938_IRQ_IRC + TX4938_IR_ECCERR)
+#define RBTX4938_IRQ_IRC_WTOERR (RBTX4938_IRQ_IRC + TX4938_IR_WTOERR)
+#define RBTX4938_IRQ_IRC_INT(n) (RBTX4938_IRQ_IRC + TX4938_IR_INT(n))
+#define RBTX4938_IRQ_IRC_SIO(n) (RBTX4938_IRQ_IRC + TX4938_IR_SIO(n))
+#define RBTX4938_IRQ_IRC_DMA(ch, n) (RBTX4938_IRQ_IRC + TX4938_IR_DMA(ch, n))
+#define RBTX4938_IRQ_IRC_PIO (RBTX4938_IRQ_IRC + TX4938_IR_PIO)
+#define RBTX4938_IRQ_IRC_PDMAC (RBTX4938_IRQ_IRC + TX4938_IR_PDMAC)
+#define RBTX4938_IRQ_IRC_PCIC (RBTX4938_IRQ_IRC + TX4938_IR_PCIC)
+#define RBTX4938_IRQ_IRC_TMR(n) (RBTX4938_IRQ_IRC + TX4938_IR_TMR(n))
+#define RBTX4938_IRQ_IRC_NDFMC (RBTX4938_IRQ_IRC + TX4938_IR_NDFMC)
+#define RBTX4938_IRQ_IRC_PCIERR (RBTX4938_IRQ_IRC + TX4938_IR_PCIERR)
+#define RBTX4938_IRQ_IRC_PCIPME (RBTX4938_IRQ_IRC + TX4938_IR_PCIPME)
+#define RBTX4938_IRQ_IRC_ACLC (RBTX4938_IRQ_IRC + TX4938_IR_ACLC)
+#define RBTX4938_IRQ_IRC_ACLCPME (RBTX4938_IRQ_IRC + TX4938_IR_ACLCPME)
+#define RBTX4938_IRQ_IRC_PCIC1 (RBTX4938_IRQ_IRC + TX4938_IR_PCIC1)
+#define RBTX4938_IRQ_IRC_SPI (RBTX4938_IRQ_IRC + TX4938_IR_SPI)
+#define RBTX4938_IRQ_IOC_PCID (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCID)
+#define RBTX4938_IRQ_IOC_PCIC (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIC)
+#define RBTX4938_IRQ_IOC_PCIB (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIB)
+#define RBTX4938_IRQ_IOC_PCIA (RBTX4938_IRQ_IOC + RBTX4938_INTB_PCIA)
+#define RBTX4938_IRQ_IOC_RTC (RBTX4938_IRQ_IOC + RBTX4938_INTB_RTC)
+#define RBTX4938_IRQ_IOC_ATA (RBTX4938_IRQ_IOC + RBTX4938_INTB_ATA)
+#define RBTX4938_IRQ_IOC_MODEM (RBTX4938_IRQ_IOC + RBTX4938_INTB_MODEM)
+#define RBTX4938_IRQ_IOC_SWINT (RBTX4938_IRQ_IOC + RBTX4938_INTB_SWINT)
+
+
+/* IOC (PCI, etc) */
+#define RBTX4938_IRQ_IOCINT (TXX9_IRQ_BASE + TX4938_IR_INT(0))
+/* Onboard 10M Ether */
+#define RBTX4938_IRQ_ETHER (TXX9_IRQ_BASE + TX4938_IR_INT(1))
+
+#define RBTX4938_RTL_8019_BASE (RBTX4938_ETHER_ADDR - mips_io_port_base)
+#define RBTX4938_RTL_8019_IRQ (RBTX4938_IRQ_ETHER)
+
+void rbtx4938_prom_init(void);
+void rbtx4938_irq_setup(void);
+struct pci_dev;
+int rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+
+#endif /* __ASM_TXX9_RBTX4938_H */
diff --git a/arch/mips/include/asm/txx9/rbtx4939.h b/arch/mips/include/asm/txx9/rbtx4939.h
new file mode 100644
index 00000000..e5178997
--- /dev/null
+++ b/arch/mips/include/asm/txx9/rbtx4939.h
@@ -0,0 +1,142 @@
+/*
+ * Definitions for RBTX4939
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2005-2006
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_TXX9_RBTX4939_H
+#define __ASM_TXX9_RBTX4939_H
+
+#include <asm/addrspace.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/tx4939.h>
+
+/* Address map */
+#define RBTX4939_IOC_REG_ADDR (IO_BASE + TXX9_CE(1) + 0x00000000)
+#define RBTX4939_BOARD_REV_ADDR (IO_BASE + TXX9_CE(1) + 0x00000000)
+#define RBTX4939_IOC_REV_ADDR (IO_BASE + TXX9_CE(1) + 0x00000002)
+#define RBTX4939_CONFIG1_ADDR (IO_BASE + TXX9_CE(1) + 0x00000004)
+#define RBTX4939_CONFIG2_ADDR (IO_BASE + TXX9_CE(1) + 0x00000006)
+#define RBTX4939_CONFIG3_ADDR (IO_BASE + TXX9_CE(1) + 0x00000008)
+#define RBTX4939_CONFIG4_ADDR (IO_BASE + TXX9_CE(1) + 0x0000000a)
+#define RBTX4939_USTAT_ADDR (IO_BASE + TXX9_CE(1) + 0x00001000)
+#define RBTX4939_UDIPSW_ADDR (IO_BASE + TXX9_CE(1) + 0x00001002)
+#define RBTX4939_BDIPSW_ADDR (IO_BASE + TXX9_CE(1) + 0x00001004)
+#define RBTX4939_IEN_ADDR (IO_BASE + TXX9_CE(1) + 0x00002000)
+#define RBTX4939_IPOL_ADDR (IO_BASE + TXX9_CE(1) + 0x00002002)
+#define RBTX4939_IFAC1_ADDR (IO_BASE + TXX9_CE(1) + 0x00002004)
+#define RBTX4939_IFAC2_ADDR (IO_BASE + TXX9_CE(1) + 0x00002006)
+#define RBTX4939_SOFTINT_ADDR (IO_BASE + TXX9_CE(1) + 0x00003000)
+#define RBTX4939_ISASTAT_ADDR (IO_BASE + TXX9_CE(1) + 0x00004000)
+#define RBTX4939_PCISTAT_ADDR (IO_BASE + TXX9_CE(1) + 0x00004002)
+#define RBTX4939_ROME_ADDR (IO_BASE + TXX9_CE(1) + 0x00004004)
+#define RBTX4939_SPICS_ADDR (IO_BASE + TXX9_CE(1) + 0x00004006)
+#define RBTX4939_AUDI_ADDR (IO_BASE + TXX9_CE(1) + 0x00004008)
+#define RBTX4939_ISAGPIO_ADDR (IO_BASE + TXX9_CE(1) + 0x0000400a)
+#define RBTX4939_PE1_ADDR (IO_BASE + TXX9_CE(1) + 0x00005000)
+#define RBTX4939_PE2_ADDR (IO_BASE + TXX9_CE(1) + 0x00005002)
+#define RBTX4939_PE3_ADDR (IO_BASE + TXX9_CE(1) + 0x00005004)
+#define RBTX4939_VP_ADDR (IO_BASE + TXX9_CE(1) + 0x00005006)
+#define RBTX4939_VPRESET_ADDR (IO_BASE + TXX9_CE(1) + 0x00005008)
+#define RBTX4939_VPSOUT_ADDR (IO_BASE + TXX9_CE(1) + 0x0000500a)
+#define RBTX4939_VPSIN_ADDR (IO_BASE + TXX9_CE(1) + 0x0000500c)
+#define RBTX4939_7SEG_ADDR(s, ch) \
+ (IO_BASE + TXX9_CE(1) + 0x00006000 + (s) * 16 + ((ch) & 3) * 2)
+#define RBTX4939_SOFTRESET_ADDR (IO_BASE + TXX9_CE(1) + 0x00007000)
+#define RBTX4939_RESETEN_ADDR (IO_BASE + TXX9_CE(1) + 0x00007002)
+#define RBTX4939_RESETSTAT_ADDR (IO_BASE + TXX9_CE(1) + 0x00007004)
+#define RBTX4939_ETHER_BASE (IO_BASE + TXX9_CE(1) + 0x00020000)
+
+/* Ethernet port address */
+#define RBTX4939_ETHER_ADDR (RBTX4939_ETHER_BASE + 0x300)
+
+/* bits for IEN/IPOL/IFAC */
+#define RBTX4938_INTB_ISA0 0
+#define RBTX4938_INTB_ISA11 1
+#define RBTX4938_INTB_ISA12 2
+#define RBTX4938_INTB_ISA15 3
+#define RBTX4938_INTB_I2S 4
+#define RBTX4938_INTB_SW 5
+#define RBTX4938_INTF_ISA0 (1 << RBTX4938_INTB_ISA0)
+#define RBTX4938_INTF_ISA11 (1 << RBTX4938_INTB_ISA11)
+#define RBTX4938_INTF_ISA12 (1 << RBTX4938_INTB_ISA12)
+#define RBTX4938_INTF_ISA15 (1 << RBTX4938_INTB_ISA15)
+#define RBTX4938_INTF_I2S (1 << RBTX4938_INTB_I2S)
+#define RBTX4938_INTF_SW (1 << RBTX4938_INTB_SW)
+
+/* bits for PE1,PE2,PE3 */
+#define RBTX4939_PE1_ATA(ch) (0x01 << (ch))
+#define RBTX4939_PE1_RMII(ch) (0x04 << (ch))
+#define RBTX4939_PE2_SIO0 0x01
+#define RBTX4939_PE2_SIO2 0x02
+#define RBTX4939_PE2_SIO3 0x04
+#define RBTX4939_PE2_CIR 0x08
+#define RBTX4939_PE2_SPI 0x10
+#define RBTX4939_PE2_GPIO 0x20
+#define RBTX4939_PE3_VP 0x01
+#define RBTX4939_PE3_VP_P 0x02
+#define RBTX4939_PE3_VP_S 0x04
+
+#define rbtx4939_board_rev_addr ((u8 __iomem *)RBTX4939_BOARD_REV_ADDR)
+#define rbtx4939_ioc_rev_addr ((u8 __iomem *)RBTX4939_IOC_REV_ADDR)
+#define rbtx4939_config1_addr ((u8 __iomem *)RBTX4939_CONFIG1_ADDR)
+#define rbtx4939_config2_addr ((u8 __iomem *)RBTX4939_CONFIG2_ADDR)
+#define rbtx4939_config3_addr ((u8 __iomem *)RBTX4939_CONFIG3_ADDR)
+#define rbtx4939_config4_addr ((u8 __iomem *)RBTX4939_CONFIG4_ADDR)
+#define rbtx4939_ustat_addr ((u8 __iomem *)RBTX4939_USTAT_ADDR)
+#define rbtx4939_udipsw_addr ((u8 __iomem *)RBTX4939_UDIPSW_ADDR)
+#define rbtx4939_bdipsw_addr ((u8 __iomem *)RBTX4939_BDIPSW_ADDR)
+#define rbtx4939_ien_addr ((u8 __iomem *)RBTX4939_IEN_ADDR)
+#define rbtx4939_ipol_addr ((u8 __iomem *)RBTX4939_IPOL_ADDR)
+#define rbtx4939_ifac1_addr ((u8 __iomem *)RBTX4939_IFAC1_ADDR)
+#define rbtx4939_ifac2_addr ((u8 __iomem *)RBTX4939_IFAC2_ADDR)
+#define rbtx4939_softint_addr ((u8 __iomem *)RBTX4939_SOFTINT_ADDR)
+#define rbtx4939_isastat_addr ((u8 __iomem *)RBTX4939_ISASTAT_ADDR)
+#define rbtx4939_pcistat_addr ((u8 __iomem *)RBTX4939_PCISTAT_ADDR)
+#define rbtx4939_rome_addr ((u8 __iomem *)RBTX4939_ROME_ADDR)
+#define rbtx4939_spics_addr ((u8 __iomem *)RBTX4939_SPICS_ADDR)
+#define rbtx4939_audi_addr ((u8 __iomem *)RBTX4939_AUDI_ADDR)
+#define rbtx4939_isagpio_addr ((u8 __iomem *)RBTX4939_ISAGPIO_ADDR)
+#define rbtx4939_pe1_addr ((u8 __iomem *)RBTX4939_PE1_ADDR)
+#define rbtx4939_pe2_addr ((u8 __iomem *)RBTX4939_PE2_ADDR)
+#define rbtx4939_pe3_addr ((u8 __iomem *)RBTX4939_PE3_ADDR)
+#define rbtx4939_vp_addr ((u8 __iomem *)RBTX4939_VP_ADDR)
+#define rbtx4939_vpreset_addr ((u8 __iomem *)RBTX4939_VPRESET_ADDR)
+#define rbtx4939_vpsout_addr ((u8 __iomem *)RBTX4939_VPSOUT_ADDR)
+#define rbtx4939_vpsin_addr ((u8 __iomem *)RBTX4939_VPSIN_ADDR)
+#define rbtx4939_7seg_addr(s, ch) \
+ ((u8 __iomem *)RBTX4939_7SEG_ADDR(s, ch))
+#define rbtx4939_softreset_addr ((u8 __iomem *)RBTX4939_SOFTRESET_ADDR)
+#define rbtx4939_reseten_addr ((u8 __iomem *)RBTX4939_RESETEN_ADDR)
+#define rbtx4939_resetstat_addr ((u8 __iomem *)RBTX4939_RESETSTAT_ADDR)
+
+/*
+ * IRQ mappings
+ */
+#define RBTX4939_NR_IRQ_IOC 8
+
+#define RBTX4939_IRQ_IOC (TXX9_IRQ_BASE + TX4939_NUM_IR)
+#define RBTX4939_IRQ_END (RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC)
+
+/* IOC (ISA, etc) */
+#define RBTX4939_IRQ_IOCINT (TXX9_IRQ_BASE + TX4939_IR_INT(0))
+/* Onboard 10M Ether */
+#define RBTX4939_IRQ_ETHER (TXX9_IRQ_BASE + TX4939_IR_INT(1))
+
+void rbtx4939_prom_init(void);
+void rbtx4939_irq_setup(void);
+
+struct mtd_partition;
+struct map_info;
+struct rbtx4939_flash_data {
+ unsigned int width;
+ unsigned int nr_parts;
+ struct mtd_partition *parts;
+ void (*map_init)(struct map_info *map);
+};
+
+#endif /* __ASM_TXX9_RBTX4939_H */
diff --git a/arch/mips/include/asm/txx9/smsc_fdc37m81x.h b/arch/mips/include/asm/txx9/smsc_fdc37m81x.h
new file mode 100644
index 00000000..d1d6332b
--- /dev/null
+++ b/arch/mips/include/asm/txx9/smsc_fdc37m81x.h
@@ -0,0 +1,68 @@
+/*
+ * Interface for smsc fdc48m81x Super IO chip
+ *
+ * Author: MontaVista Software, Inc. source@mvista.com
+ *
+ * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Manish Lachwani, mlachwani@mvista.com
+ */
+
+#ifndef _SMSC_FDC37M81X_H_
+#define _SMSC_FDC37M81X_H_
+
+/* Common Registers */
+#define SMSC_FDC37M81X_CONFIG_INDEX 0x00
+#define SMSC_FDC37M81X_CONFIG_DATA 0x01
+#define SMSC_FDC37M81X_CONF 0x02
+#define SMSC_FDC37M81X_INDEX 0x03
+#define SMSC_FDC37M81X_DNUM 0x07
+#define SMSC_FDC37M81X_DID 0x20
+#define SMSC_FDC37M81X_DREV 0x21
+#define SMSC_FDC37M81X_PCNT 0x22
+#define SMSC_FDC37M81X_PMGT 0x23
+#define SMSC_FDC37M81X_OSC 0x24
+#define SMSC_FDC37M81X_CONFPA0 0x26
+#define SMSC_FDC37M81X_CONFPA1 0x27
+#define SMSC_FDC37M81X_TEST4 0x2B
+#define SMSC_FDC37M81X_TEST5 0x2C
+#define SMSC_FDC37M81X_TEST1 0x2D
+#define SMSC_FDC37M81X_TEST2 0x2E
+#define SMSC_FDC37M81X_TEST3 0x2F
+
+/* Logical device numbers */
+#define SMSC_FDC37M81X_FDD 0x00
+#define SMSC_FDC37M81X_PARALLEL 0x03
+#define SMSC_FDC37M81X_SERIAL1 0x04
+#define SMSC_FDC37M81X_SERIAL2 0x05
+#define SMSC_FDC37M81X_KBD 0x07
+#define SMSC_FDC37M81X_AUXIO 0x08
+#define SMSC_FDC37M81X_NONE 0xff
+
+/* Logical device Config Registers */
+#define SMSC_FDC37M81X_ACTIVE 0x30
+#define SMSC_FDC37M81X_BASEADDR0 0x60
+#define SMSC_FDC37M81X_BASEADDR1 0x61
+#define SMSC_FDC37M81X_INT 0x70
+#define SMSC_FDC37M81X_INT2 0x72
+#define SMSC_FDC37M81X_LDCR_F0 0xF0
+
+/* Chip Config Values */
+#define SMSC_FDC37M81X_CONFIG_ENTER 0x55
+#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa
+#define SMSC_FDC37M81X_CHIP_ID 0x4d
+
+unsigned long smsc_fdc37m81x_init(unsigned long port);
+
+void smsc_fdc37m81x_config_beg(void);
+
+void smsc_fdc37m81x_config_end(void);
+
+u8 smsc_fdc37m81x_config_get(u8 reg);
+void smsc_fdc37m81x_config_set(u8 reg, u8 val);
+
+#endif
diff --git a/arch/mips/include/asm/txx9/spi.h b/arch/mips/include/asm/txx9/spi.h
new file mode 100644
index 00000000..0d727f35
--- /dev/null
+++ b/arch/mips/include/asm/txx9/spi.h
@@ -0,0 +1,34 @@
+/*
+ * Definitions for TX4937/TX4938 SPI
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TXX9_SPI_H
+#define __ASM_TXX9_SPI_H
+
+#include <linux/errno.h>
+
+#ifdef CONFIG_SPI
+int spi_eeprom_register(int busid, int chipid, int size);
+int spi_eeprom_read(int busid, int chipid,
+ int address, unsigned char *buf, int len);
+#else
+static inline int spi_eeprom_register(int busid, int chipid, int size)
+{
+ return -ENODEV;
+}
+static inline int spi_eeprom_read(int busid, int chipid,
+ int address, unsigned char *buf, int len)
+{
+ return -ENODEV;
+}
+#endif
+
+#endif /* __ASM_TXX9_SPI_H */
diff --git a/arch/mips/include/asm/txx9/tx3927.h b/arch/mips/include/asm/txx9/tx3927.h
new file mode 100644
index 00000000..dc30c8d4
--- /dev/null
+++ b/arch/mips/include/asm/txx9/tx3927.h
@@ -0,0 +1,341 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Toshiba Corporation
+ */
+#ifndef __ASM_TXX9_TX3927_H
+#define __ASM_TXX9_TX3927_H
+
+#define TX3927_REG_BASE 0xfffe0000UL
+#define TX3927_REG_SIZE 0x00010000
+#define TX3927_SDRAMC_REG (TX3927_REG_BASE + 0x8000)
+#define TX3927_ROMC_REG (TX3927_REG_BASE + 0x9000)
+#define TX3927_DMA_REG (TX3927_REG_BASE + 0xb000)
+#define TX3927_IRC_REG (TX3927_REG_BASE + 0xc000)
+#define TX3927_PCIC_REG (TX3927_REG_BASE + 0xd000)
+#define TX3927_CCFG_REG (TX3927_REG_BASE + 0xe000)
+#define TX3927_NR_TMR 3
+#define TX3927_TMR_REG(ch) (TX3927_REG_BASE + 0xf000 + (ch) * 0x100)
+#define TX3927_NR_SIO 2
+#define TX3927_SIO_REG(ch) (TX3927_REG_BASE + 0xf300 + (ch) * 0x100)
+#define TX3927_PIO_REG (TX3927_REG_BASE + 0xf500)
+
+struct tx3927_sdramc_reg {
+ volatile unsigned long cr[8];
+ volatile unsigned long tr[3];
+ volatile unsigned long cmd;
+ volatile unsigned long smrs[2];
+};
+
+struct tx3927_romc_reg {
+ volatile unsigned long cr[8];
+};
+
+struct tx3927_dma_reg {
+ struct tx3927_dma_ch_reg {
+ volatile unsigned long cha;
+ volatile unsigned long sar;
+ volatile unsigned long dar;
+ volatile unsigned long cntr;
+ volatile unsigned long sair;
+ volatile unsigned long dair;
+ volatile unsigned long ccr;
+ volatile unsigned long csr;
+ } ch[4];
+ volatile unsigned long dbr[8];
+ volatile unsigned long tdhr;
+ volatile unsigned long mcr;
+ volatile unsigned long unused0;
+};
+
+#include <asm/byteorder.h>
+
+#ifdef __BIG_ENDIAN
+#define endian_def_s2(e1, e2) \
+ volatile unsigned short e1, e2
+#define endian_def_sb2(e1, e2, e3) \
+ volatile unsigned short e1;volatile unsigned char e2, e3
+#define endian_def_b2s(e1, e2, e3) \
+ volatile unsigned char e1, e2;volatile unsigned short e3
+#define endian_def_b4(e1, e2, e3, e4) \
+ volatile unsigned char e1, e2, e3, e4
+#else
+#define endian_def_s2(e1, e2) \
+ volatile unsigned short e2, e1
+#define endian_def_sb2(e1, e2, e3) \
+ volatile unsigned char e3, e2;volatile unsigned short e1
+#define endian_def_b2s(e1, e2, e3) \
+ volatile unsigned short e3;volatile unsigned char e2, e1
+#define endian_def_b4(e1, e2, e3, e4) \
+ volatile unsigned char e4, e3, e2, e1
+#endif
+
+struct tx3927_pcic_reg {
+ endian_def_s2(did, vid);
+ endian_def_s2(pcistat, pcicmd);
+ endian_def_b4(cc, scc, rpli, rid);
+ endian_def_b4(unused0, ht, mlt, cls);
+ volatile unsigned long ioba; /* +10 */
+ volatile unsigned long mba;
+ volatile unsigned long unused1[5];
+ endian_def_s2(svid, ssvid);
+ volatile unsigned long unused2; /* +30 */
+ endian_def_sb2(unused3, unused4, capptr);
+ volatile unsigned long unused5;
+ endian_def_b4(ml, mg, ip, il);
+ volatile unsigned long unused6; /* +40 */
+ volatile unsigned long istat;
+ volatile unsigned long iim;
+ volatile unsigned long rrt;
+ volatile unsigned long unused7[3]; /* +50 */
+ volatile unsigned long ipbmma;
+ volatile unsigned long ipbioma; /* +60 */
+ volatile unsigned long ilbmma;
+ volatile unsigned long ilbioma;
+ volatile unsigned long unused8[9];
+ volatile unsigned long tc; /* +90 */
+ volatile unsigned long tstat;
+ volatile unsigned long tim;
+ volatile unsigned long tccmd;
+ volatile unsigned long pcirrt; /* +a0 */
+ volatile unsigned long pcirrt_cmd;
+ volatile unsigned long pcirrdt;
+ volatile unsigned long unused9[3];
+ volatile unsigned long tlboap;
+ volatile unsigned long tlbiap;
+ volatile unsigned long tlbmma; /* +c0 */
+ volatile unsigned long tlbioma;
+ volatile unsigned long sc_msg;
+ volatile unsigned long sc_be;
+ volatile unsigned long tbl; /* +d0 */
+ volatile unsigned long unused10[3];
+ volatile unsigned long pwmng; /* +e0 */
+ volatile unsigned long pwmngs;
+ volatile unsigned long unused11[6];
+ volatile unsigned long req_trace; /* +100 */
+ volatile unsigned long pbapmc;
+ volatile unsigned long pbapms;
+ volatile unsigned long pbapmim;
+ volatile unsigned long bm; /* +110 */
+ volatile unsigned long cpcibrs;
+ volatile unsigned long cpcibgs;
+ volatile unsigned long pbacs;
+ volatile unsigned long iobas; /* +120 */
+ volatile unsigned long mbas;
+ volatile unsigned long lbc;
+ volatile unsigned long lbstat;
+ volatile unsigned long lbim; /* +130 */
+ volatile unsigned long pcistatim;
+ volatile unsigned long ica;
+ volatile unsigned long icd;
+ volatile unsigned long iiadp; /* +140 */
+ volatile unsigned long iscdp;
+ volatile unsigned long mmas;
+ volatile unsigned long iomas;
+ volatile unsigned long ipciaddr; /* +150 */
+ volatile unsigned long ipcidata;
+ volatile unsigned long ipcibe;
+};
+
+struct tx3927_ccfg_reg {
+ volatile unsigned long ccfg;
+ volatile unsigned long crir;
+ volatile unsigned long pcfg;
+ volatile unsigned long tear;
+ volatile unsigned long pdcr;
+};
+
+/*
+ * SDRAMC
+ */
+
+/*
+ * ROMC
+ */
+
+/*
+ * DMA
+ */
+/* bits for MCR */
+#define TX3927_DMA_MCR_EIS(ch) (0x10000000<<(ch))
+#define TX3927_DMA_MCR_DIS(ch) (0x01000000<<(ch))
+#define TX3927_DMA_MCR_RSFIF 0x00000080
+#define TX3927_DMA_MCR_FIFUM(ch) (0x00000008<<(ch))
+#define TX3927_DMA_MCR_LE 0x00000004
+#define TX3927_DMA_MCR_RPRT 0x00000002
+#define TX3927_DMA_MCR_MSTEN 0x00000001
+
+/* bits for CCRn */
+#define TX3927_DMA_CCR_DBINH 0x04000000
+#define TX3927_DMA_CCR_SBINH 0x02000000
+#define TX3927_DMA_CCR_CHRST 0x01000000
+#define TX3927_DMA_CCR_RVBYTE 0x00800000
+#define TX3927_DMA_CCR_ACKPOL 0x00400000
+#define TX3927_DMA_CCR_REQPL 0x00200000
+#define TX3927_DMA_CCR_EGREQ 0x00100000
+#define TX3927_DMA_CCR_CHDN 0x00080000
+#define TX3927_DMA_CCR_DNCTL 0x00060000
+#define TX3927_DMA_CCR_EXTRQ 0x00010000
+#define TX3927_DMA_CCR_INTRQD 0x0000e000
+#define TX3927_DMA_CCR_INTENE 0x00001000
+#define TX3927_DMA_CCR_INTENC 0x00000800
+#define TX3927_DMA_CCR_INTENT 0x00000400
+#define TX3927_DMA_CCR_CHNEN 0x00000200
+#define TX3927_DMA_CCR_XFACT 0x00000100
+#define TX3927_DMA_CCR_SNOP 0x00000080
+#define TX3927_DMA_CCR_DSTINC 0x00000040
+#define TX3927_DMA_CCR_SRCINC 0x00000020
+#define TX3927_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c)
+#define TX3927_DMA_CCR_XFSZ_1W TX3927_DMA_CCR_XFSZ(2)
+#define TX3927_DMA_CCR_XFSZ_4W TX3927_DMA_CCR_XFSZ(4)
+#define TX3927_DMA_CCR_XFSZ_8W TX3927_DMA_CCR_XFSZ(5)
+#define TX3927_DMA_CCR_XFSZ_16W TX3927_DMA_CCR_XFSZ(6)
+#define TX3927_DMA_CCR_XFSZ_32W TX3927_DMA_CCR_XFSZ(7)
+#define TX3927_DMA_CCR_MEMIO 0x00000002
+#define TX3927_DMA_CCR_ONEAD 0x00000001
+
+/* bits for CSRn */
+#define TX3927_DMA_CSR_CHNACT 0x00000100
+#define TX3927_DMA_CSR_ABCHC 0x00000080
+#define TX3927_DMA_CSR_NCHNC 0x00000040
+#define TX3927_DMA_CSR_NTRNFC 0x00000020
+#define TX3927_DMA_CSR_EXTDN 0x00000010
+#define TX3927_DMA_CSR_CFERR 0x00000008
+#define TX3927_DMA_CSR_CHERR 0x00000004
+#define TX3927_DMA_CSR_DESERR 0x00000002
+#define TX3927_DMA_CSR_SORERR 0x00000001
+
+/*
+ * IRC
+ */
+#define TX3927_IR_INT0 0
+#define TX3927_IR_INT1 1
+#define TX3927_IR_INT2 2
+#define TX3927_IR_INT3 3
+#define TX3927_IR_INT4 4
+#define TX3927_IR_INT5 5
+#define TX3927_IR_SIO0 6
+#define TX3927_IR_SIO1 7
+#define TX3927_IR_SIO(ch) (6 + (ch))
+#define TX3927_IR_DMA 8
+#define TX3927_IR_PIO 9
+#define TX3927_IR_PCI 10
+#define TX3927_IR_TMR(ch) (13 + (ch))
+#define TX3927_NUM_IR 16
+
+/*
+ * PCIC
+ */
+/* bits for PCICMD */
+/* see PCI_COMMAND_XXX in linux/pci.h */
+
+/* bits for PCISTAT */
+/* see PCI_STATUS_XXX in linux/pci.h */
+#define PCI_STATUS_NEW_CAP 0x0010
+
+/* bits for ISTAT/IIM */
+#define TX3927_PCIC_IIM_ALL 0x00001600
+
+/* bits for TC */
+#define TX3927_PCIC_TC_OF16E 0x00000020
+#define TX3927_PCIC_TC_IF8E 0x00000010
+#define TX3927_PCIC_TC_OF8E 0x00000008
+
+/* bits for TSTAT/TIM */
+#define TX3927_PCIC_TIM_ALL 0x0003ffff
+
+/* bits for IOBA/MBA */
+/* see PCI_BASE_ADDRESS_XXX in linux/pci.h */
+
+/* bits for PBAPMC */
+#define TX3927_PCIC_PBAPMC_RPBA 0x00000004
+#define TX3927_PCIC_PBAPMC_PBAEN 0x00000002
+#define TX3927_PCIC_PBAPMC_BMCEN 0x00000001
+
+/* bits for LBSTAT/LBIM */
+#define TX3927_PCIC_LBIM_ALL 0x0000003e
+
+/* bits for PCISTATIM (see also PCI_STATUS_XXX in linux/pci.h */
+#define TX3927_PCIC_PCISTATIM_ALL 0x0000f900
+
+/* bits for LBC */
+#define TX3927_PCIC_LBC_IBSE 0x00004000
+#define TX3927_PCIC_LBC_TIBSE 0x00002000
+#define TX3927_PCIC_LBC_TMFBSE 0x00001000
+#define TX3927_PCIC_LBC_HRST 0x00000800
+#define TX3927_PCIC_LBC_SRST 0x00000400
+#define TX3927_PCIC_LBC_EPCAD 0x00000200
+#define TX3927_PCIC_LBC_MSDSE 0x00000100
+#define TX3927_PCIC_LBC_CRR 0x00000080
+#define TX3927_PCIC_LBC_ILMDE 0x00000040
+#define TX3927_PCIC_LBC_ILIDE 0x00000020
+
+#define TX3927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11)
+#define TX3927_PCIC_MAX_DEVNU TX3927_PCIC_IDSEL_AD_TO_SLOT(32)
+
+/*
+ * CCFG
+ */
+/* CCFG : Chip Configuration */
+#define TX3927_CCFG_TLBOFF 0x00020000
+#define TX3927_CCFG_BEOW 0x00010000
+#define TX3927_CCFG_WR 0x00008000
+#define TX3927_CCFG_TOE 0x00004000
+#define TX3927_CCFG_PCIXARB 0x00002000
+#define TX3927_CCFG_PCI3 0x00001000
+#define TX3927_CCFG_PSNP 0x00000800
+#define TX3927_CCFG_PPRI 0x00000400
+#define TX3927_CCFG_PLLM 0x00000030
+#define TX3927_CCFG_ENDIAN 0x00000004
+#define TX3927_CCFG_HALT 0x00000002
+#define TX3927_CCFG_ACEHOLD 0x00000001
+
+/* PCFG : Pin Configuration */
+#define TX3927_PCFG_SYSCLKEN 0x08000000
+#define TX3927_PCFG_SDRCLKEN_ALL 0x07c00000
+#define TX3927_PCFG_SDRCLKEN(ch) (0x00400000<<(ch))
+#define TX3927_PCFG_PCICLKEN_ALL 0x003c0000
+#define TX3927_PCFG_PCICLKEN(ch) (0x00040000<<(ch))
+#define TX3927_PCFG_SELALL 0x0003ffff
+#define TX3927_PCFG_SELCS 0x00020000
+#define TX3927_PCFG_SELDSF 0x00010000
+#define TX3927_PCFG_SELSIOC_ALL 0x0000c000
+#define TX3927_PCFG_SELSIOC(ch) (0x00004000<<(ch))
+#define TX3927_PCFG_SELSIO_ALL 0x00003000
+#define TX3927_PCFG_SELSIO(ch) (0x00001000<<(ch))
+#define TX3927_PCFG_SELTMR_ALL 0x00000e00
+#define TX3927_PCFG_SELTMR(ch) (0x00000200<<(ch))
+#define TX3927_PCFG_SELDONE 0x00000100
+#define TX3927_PCFG_INTDMA_ALL 0x000000f0
+#define TX3927_PCFG_INTDMA(ch) (0x00000010<<(ch))
+#define TX3927_PCFG_SELDMA_ALL 0x0000000f
+#define TX3927_PCFG_SELDMA(ch) (0x00000001<<(ch))
+
+#define tx3927_sdramcptr ((struct tx3927_sdramc_reg *)TX3927_SDRAMC_REG)
+#define tx3927_romcptr ((struct tx3927_romc_reg *)TX3927_ROMC_REG)
+#define tx3927_dmaptr ((struct tx3927_dma_reg *)TX3927_DMA_REG)
+#define tx3927_pcicptr ((struct tx3927_pcic_reg *)TX3927_PCIC_REG)
+#define tx3927_ccfgptr ((struct tx3927_ccfg_reg *)TX3927_CCFG_REG)
+#define tx3927_sioptr(ch) ((struct txx927_sio_reg *)TX3927_SIO_REG(ch))
+#define tx3927_pioptr ((struct txx9_pio_reg __iomem *)TX3927_PIO_REG)
+
+#define TX3927_REV_PCODE() (tx3927_ccfgptr->crir >> 16)
+#define TX3927_ROMC_BA(ch) (tx3927_romcptr->cr[(ch)] & 0xfff00000)
+#define TX3927_ROMC_SIZE(ch) \
+ (0x00100000 << ((tx3927_romcptr->cr[(ch)] >> 8) & 0xf))
+#define TX3927_ROMC_WIDTH(ch) (32 >> ((tx3927_romcptr->cr[(ch)] >> 7) & 0x1))
+
+void tx3927_wdt_init(void);
+void tx3927_setup(void);
+void tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr);
+void tx3927_sio_init(unsigned int sclk, unsigned int cts_mask);
+struct pci_controller;
+void tx3927_pcic_setup(struct pci_controller *channel,
+ unsigned long sdram_size, int extarb);
+void tx3927_setup_pcierr_irq(void);
+void tx3927_irq_init(void);
+void tx3927_mtd_init(int ch);
+
+#endif /* __ASM_TXX9_TX3927_H */
diff --git a/arch/mips/include/asm/txx9/tx4927.h b/arch/mips/include/asm/txx9/tx4927.h
new file mode 100644
index 00000000..18c98c52
--- /dev/null
+++ b/arch/mips/include/asm/txx9/tx4927.h
@@ -0,0 +1,273 @@
+/*
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2001-2006 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __ASM_TXX9_TX4927_H
+#define __ASM_TXX9_TX4927_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9/tx4927pcic.h>
+
+#ifdef CONFIG_64BIT
+#define TX4927_REG_BASE 0xffffffffff1f0000UL
+#else
+#define TX4927_REG_BASE 0xff1f0000UL
+#endif
+#define TX4927_REG_SIZE 0x00010000
+
+#define TX4927_SDRAMC_REG (TX4927_REG_BASE + 0x8000)
+#define TX4927_EBUSC_REG (TX4927_REG_BASE + 0x9000)
+#define TX4927_DMA_REG (TX4927_REG_BASE + 0xb000)
+#define TX4927_PCIC_REG (TX4927_REG_BASE + 0xd000)
+#define TX4927_CCFG_REG (TX4927_REG_BASE + 0xe000)
+#define TX4927_IRC_REG (TX4927_REG_BASE + 0xf600)
+#define TX4927_NR_TMR 3
+#define TX4927_TMR_REG(ch) (TX4927_REG_BASE + 0xf000 + (ch) * 0x100)
+#define TX4927_NR_SIO 2
+#define TX4927_SIO_REG(ch) (TX4927_REG_BASE + 0xf300 + (ch) * 0x100)
+#define TX4927_PIO_REG (TX4927_REG_BASE + 0xf500)
+#define TX4927_ACLC_REG (TX4927_REG_BASE + 0xf700)
+
+#define TX4927_IR_ECCERR 0
+#define TX4927_IR_WTOERR 1
+#define TX4927_NUM_IR_INT 6
+#define TX4927_IR_INT(n) (2 + (n))
+#define TX4927_NUM_IR_SIO 2
+#define TX4927_IR_SIO(n) (8 + (n))
+#define TX4927_NUM_IR_DMA 4
+#define TX4927_IR_DMA(n) (10 + (n))
+#define TX4927_IR_PIO 14
+#define TX4927_IR_PDMAC 15
+#define TX4927_IR_PCIC 16
+#define TX4927_NUM_IR_TMR 3
+#define TX4927_IR_TMR(n) (17 + (n))
+#define TX4927_IR_PCIERR 22
+#define TX4927_IR_PCIPME 23
+#define TX4927_IR_ACLC 24
+#define TX4927_IR_ACLCPME 25
+#define TX4927_NUM_IR 32
+
+#define TX4927_IRC_INT 2 /* IP[2] in Status register */
+
+#define TX4927_NUM_PIO 16
+
+struct tx4927_sdramc_reg {
+ u64 cr[4];
+ u64 unused0[4];
+ u64 tr;
+ u64 unused1[2];
+ u64 cmd;
+};
+
+struct tx4927_ebusc_reg {
+ u64 cr[8];
+};
+
+struct tx4927_ccfg_reg {
+ u64 ccfg;
+ u64 crir;
+ u64 pcfg;
+ u64 toea;
+ u64 clkctr;
+ u64 unused0;
+ u64 garbc;
+ u64 unused1;
+ u64 unused2;
+ u64 ramp;
+};
+
+/*
+ * CCFG
+ */
+/* CCFG : Chip Configuration */
+#define TX4927_CCFG_WDRST 0x0000020000000000ULL
+#define TX4927_CCFG_WDREXEN 0x0000010000000000ULL
+#define TX4927_CCFG_BCFG_MASK 0x000000ff00000000ULL
+#define TX4927_CCFG_TINTDIS 0x01000000
+#define TX4927_CCFG_PCI66 0x00800000
+#define TX4927_CCFG_PCIMODE 0x00400000
+#define TX4927_CCFG_DIVMODE_MASK 0x000e0000
+#define TX4927_CCFG_DIVMODE_8 (0x0 << 17)
+#define TX4927_CCFG_DIVMODE_12 (0x1 << 17)
+#define TX4927_CCFG_DIVMODE_16 (0x2 << 17)
+#define TX4927_CCFG_DIVMODE_10 (0x3 << 17)
+#define TX4927_CCFG_DIVMODE_2 (0x4 << 17)
+#define TX4927_CCFG_DIVMODE_3 (0x5 << 17)
+#define TX4927_CCFG_DIVMODE_4 (0x6 << 17)
+#define TX4927_CCFG_DIVMODE_2_5 (0x7 << 17)
+#define TX4927_CCFG_BEOW 0x00010000
+#define TX4927_CCFG_WR 0x00008000
+#define TX4927_CCFG_TOE 0x00004000
+#define TX4927_CCFG_PCIARB 0x00002000
+#define TX4927_CCFG_PCIDIVMODE_MASK 0x00001800
+#define TX4927_CCFG_PCIDIVMODE_2_5 0x00000000
+#define TX4927_CCFG_PCIDIVMODE_3 0x00000800
+#define TX4927_CCFG_PCIDIVMODE_5 0x00001000
+#define TX4927_CCFG_PCIDIVMODE_6 0x00001800
+#define TX4927_CCFG_SYSSP_MASK 0x000000c0
+#define TX4927_CCFG_ENDIAN 0x00000004
+#define TX4927_CCFG_HALT 0x00000002
+#define TX4927_CCFG_ACEHOLD 0x00000001
+#define TX4927_CCFG_W1CBITS (TX4927_CCFG_WDRST | TX4927_CCFG_BEOW)
+
+/* PCFG : Pin Configuration */
+#define TX4927_PCFG_SDCLKDLY_MASK 0x30000000
+#define TX4927_PCFG_SDCLKDLY(d) ((d)<<28)
+#define TX4927_PCFG_SYSCLKEN 0x08000000
+#define TX4927_PCFG_SDCLKEN_ALL 0x07800000
+#define TX4927_PCFG_SDCLKEN(ch) (0x00800000<<(ch))
+#define TX4927_PCFG_PCICLKEN_ALL 0x003f0000
+#define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch))
+#define TX4927_PCFG_SEL2 0x00000200
+#define TX4927_PCFG_SEL1 0x00000100
+#define TX4927_PCFG_DMASEL_ALL 0x000000ff
+#define TX4927_PCFG_DMASEL0_MASK 0x00000003
+#define TX4927_PCFG_DMASEL1_MASK 0x0000000c
+#define TX4927_PCFG_DMASEL2_MASK 0x00000030
+#define TX4927_PCFG_DMASEL3_MASK 0x000000c0
+#define TX4927_PCFG_DMASEL0_DRQ0 0x00000000
+#define TX4927_PCFG_DMASEL0_SIO1 0x00000001
+#define TX4927_PCFG_DMASEL0_ACL0 0x00000002
+#define TX4927_PCFG_DMASEL0_ACL2 0x00000003
+#define TX4927_PCFG_DMASEL1_DRQ1 0x00000000
+#define TX4927_PCFG_DMASEL1_SIO1 0x00000004
+#define TX4927_PCFG_DMASEL1_ACL1 0x00000008
+#define TX4927_PCFG_DMASEL1_ACL3 0x0000000c
+#define TX4927_PCFG_DMASEL2_DRQ2 0x00000000 /* SEL2=0 */
+#define TX4927_PCFG_DMASEL2_SIO0 0x00000010 /* SEL2=0 */
+#define TX4927_PCFG_DMASEL2_ACL1 0x00000000 /* SEL2=1 */
+#define TX4927_PCFG_DMASEL2_ACL2 0x00000020 /* SEL2=1 */
+#define TX4927_PCFG_DMASEL2_ACL0 0x00000030 /* SEL2=1 */
+#define TX4927_PCFG_DMASEL3_DRQ3 0x00000000
+#define TX4927_PCFG_DMASEL3_SIO0 0x00000040
+#define TX4927_PCFG_DMASEL3_ACL3 0x00000080
+#define TX4927_PCFG_DMASEL3_ACL1 0x000000c0
+
+/* CLKCTR : Clock Control */
+#define TX4927_CLKCTR_ACLCKD 0x02000000
+#define TX4927_CLKCTR_PIOCKD 0x01000000
+#define TX4927_CLKCTR_DMACKD 0x00800000
+#define TX4927_CLKCTR_PCICKD 0x00400000
+#define TX4927_CLKCTR_TM0CKD 0x00100000
+#define TX4927_CLKCTR_TM1CKD 0x00080000
+#define TX4927_CLKCTR_TM2CKD 0x00040000
+#define TX4927_CLKCTR_SIO0CKD 0x00020000
+#define TX4927_CLKCTR_SIO1CKD 0x00010000
+#define TX4927_CLKCTR_ACLRST 0x00000200
+#define TX4927_CLKCTR_PIORST 0x00000100
+#define TX4927_CLKCTR_DMARST 0x00000080
+#define TX4927_CLKCTR_PCIRST 0x00000040
+#define TX4927_CLKCTR_TM0RST 0x00000010
+#define TX4927_CLKCTR_TM1RST 0x00000008
+#define TX4927_CLKCTR_TM2RST 0x00000004
+#define TX4927_CLKCTR_SIO0RST 0x00000002
+#define TX4927_CLKCTR_SIO1RST 0x00000001
+
+#define tx4927_sdramcptr \
+ ((struct tx4927_sdramc_reg __iomem *)TX4927_SDRAMC_REG)
+#define tx4927_pcicptr \
+ ((struct tx4927_pcic_reg __iomem *)TX4927_PCIC_REG)
+#define tx4927_ccfgptr \
+ ((struct tx4927_ccfg_reg __iomem *)TX4927_CCFG_REG)
+#define tx4927_ebuscptr \
+ ((struct tx4927_ebusc_reg __iomem *)TX4927_EBUSC_REG)
+#define tx4927_pioptr ((struct txx9_pio_reg __iomem *)TX4927_PIO_REG)
+
+#define TX4927_REV_PCODE() \
+ ((__u32)__raw_readq(&tx4927_ccfgptr->crir) >> 16)
+
+#define TX4927_SDRAMC_CR(ch) __raw_readq(&tx4927_sdramcptr->cr[(ch)])
+#define TX4927_SDRAMC_BA(ch) ((TX4927_SDRAMC_CR(ch) >> 49) << 21)
+#define TX4927_SDRAMC_SIZE(ch) \
+ ((((TX4927_SDRAMC_CR(ch) >> 33) & 0x7fff) + 1) << 21)
+
+#define TX4927_EBUSC_CR(ch) __raw_readq(&tx4927_ebuscptr->cr[(ch)])
+#define TX4927_EBUSC_BA(ch) ((TX4927_EBUSC_CR(ch) >> 48) << 20)
+#define TX4927_EBUSC_SIZE(ch) \
+ (0x00100000 << ((unsigned long)(TX4927_EBUSC_CR(ch) >> 8) & 0xf))
+#define TX4927_EBUSC_WIDTH(ch) \
+ (64 >> ((__u32)(TX4927_EBUSC_CR(ch) >> 20) & 0x3))
+
+/* utilities */
+static inline void txx9_clear64(__u64 __iomem *adr, __u64 bits)
+{
+#ifdef CONFIG_32BIT
+ unsigned long flags;
+ local_irq_save(flags);
+#endif
+ ____raw_writeq(____raw_readq(adr) & ~bits, adr);
+#ifdef CONFIG_32BIT
+ local_irq_restore(flags);
+#endif
+}
+static inline void txx9_set64(__u64 __iomem *adr, __u64 bits)
+{
+#ifdef CONFIG_32BIT
+ unsigned long flags;
+ local_irq_save(flags);
+#endif
+ ____raw_writeq(____raw_readq(adr) | bits, adr);
+#ifdef CONFIG_32BIT
+ local_irq_restore(flags);
+#endif
+}
+
+/* These functions are not interrupt safe. */
+static inline void tx4927_ccfg_clear(__u64 bits)
+{
+ ____raw_writeq(____raw_readq(&tx4927_ccfgptr->ccfg)
+ & ~(TX4927_CCFG_W1CBITS | bits),
+ &tx4927_ccfgptr->ccfg);
+}
+static inline void tx4927_ccfg_set(__u64 bits)
+{
+ ____raw_writeq((____raw_readq(&tx4927_ccfgptr->ccfg)
+ & ~TX4927_CCFG_W1CBITS) | bits,
+ &tx4927_ccfgptr->ccfg);
+}
+static inline void tx4927_ccfg_change(__u64 change, __u64 new)
+{
+ ____raw_writeq((____raw_readq(&tx4927_ccfgptr->ccfg)
+ & ~(TX4927_CCFG_W1CBITS | change)) |
+ new,
+ &tx4927_ccfgptr->ccfg);
+}
+
+unsigned int tx4927_get_mem_size(void);
+void tx4927_wdt_init(void);
+void tx4927_setup(void);
+void tx4927_time_init(unsigned int tmrnr);
+void tx4927_sio_init(unsigned int sclk, unsigned int cts_mask);
+int tx4927_report_pciclk(void);
+int tx4927_pciclk66_setup(void);
+void tx4927_setup_pcierr_irq(void);
+void tx4927_irq_init(void);
+void tx4927_mtd_init(int ch);
+void tx4927_dmac_init(int memcpy_chan);
+void tx4927_aclc_init(unsigned int dma_chan_out, unsigned int dma_chan_in);
+
+#endif /* __ASM_TXX9_TX4927_H */
diff --git a/arch/mips/include/asm/txx9/tx4927pcic.h b/arch/mips/include/asm/txx9/tx4927pcic.h
new file mode 100644
index 00000000..c470b8a5
--- /dev/null
+++ b/arch/mips/include/asm/txx9/tx4927pcic.h
@@ -0,0 +1,203 @@
+/*
+ * include/asm-mips/txx9/tx4927pcic.h
+ * TX4927 PCI controller definitions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_TXX9_TX4927PCIC_H
+#define __ASM_TXX9_TX4927PCIC_H
+
+#include <linux/pci.h>
+#include <linux/irqreturn.h>
+
+struct tx4927_pcic_reg {
+ u32 pciid;
+ u32 pcistatus;
+ u32 pciccrev;
+ u32 pcicfg1;
+ u32 p2gm0plbase; /* +10 */
+ u32 p2gm0pubase;
+ u32 p2gm1plbase;
+ u32 p2gm1pubase;
+ u32 p2gm2pbase; /* +20 */
+ u32 p2giopbase;
+ u32 unused0;
+ u32 pcisid;
+ u32 unused1; /* +30 */
+ u32 pcicapptr;
+ u32 unused2;
+ u32 pcicfg2;
+ u32 g2ptocnt; /* +40 */
+ u32 unused3[15];
+ u32 g2pstatus; /* +80 */
+ u32 g2pmask;
+ u32 pcisstatus;
+ u32 pcimask;
+ u32 p2gcfg; /* +90 */
+ u32 p2gstatus;
+ u32 p2gmask;
+ u32 p2gccmd;
+ u32 unused4[24]; /* +a0 */
+ u32 pbareqport; /* +100 */
+ u32 pbacfg;
+ u32 pbastatus;
+ u32 pbamask;
+ u32 pbabm; /* +110 */
+ u32 pbacreq;
+ u32 pbacgnt;
+ u32 pbacstate;
+ u64 g2pmgbase[3]; /* +120 */
+ u64 g2piogbase;
+ u32 g2pmmask[3]; /* +140 */
+ u32 g2piomask;
+ u64 g2pmpbase[3]; /* +150 */
+ u64 g2piopbase;
+ u32 pciccfg; /* +170 */
+ u32 pcicstatus;
+ u32 pcicmask;
+ u32 unused5;
+ u64 p2gmgbase[3]; /* +180 */
+ u64 p2giogbase;
+ u32 g2pcfgadrs; /* +1a0 */
+ u32 g2pcfgdata;
+ u32 unused6[8];
+ u32 g2pintack;
+ u32 g2pspc;
+ u32 unused7[12]; /* +1d0 */
+ u64 pdmca; /* +200 */
+ u64 pdmga;
+ u64 pdmpa;
+ u64 pdmctr;
+ u64 pdmcfg; /* +220 */
+ u64 pdmsts;
+};
+
+/* bits for PCICMD */
+/* see PCI_COMMAND_XXX in linux/pci_regs.h */
+
+/* bits for PCISTAT */
+/* see PCI_STATUS_XXX in linux/pci_regs.h */
+
+/* bits for IOBA/MBA */
+/* see PCI_BASE_ADDRESS_XXX in linux/pci_regs.h */
+
+/* bits for G2PSTATUS/G2PMASK */
+#define TX4927_PCIC_G2PSTATUS_ALL 0x00000003
+#define TX4927_PCIC_G2PSTATUS_TTOE 0x00000002
+#define TX4927_PCIC_G2PSTATUS_RTOE 0x00000001
+
+/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci_regs.h */
+#define TX4927_PCIC_PCISTATUS_ALL 0x0000f900
+
+/* bits for PBACFG */
+#define TX4927_PCIC_PBACFG_FIXPA 0x00000008
+#define TX4927_PCIC_PBACFG_RPBA 0x00000004
+#define TX4927_PCIC_PBACFG_PBAEN 0x00000002
+#define TX4927_PCIC_PBACFG_BMCEN 0x00000001
+
+/* bits for PBASTATUS/PBAMASK */
+#define TX4927_PCIC_PBASTATUS_ALL 0x00000001
+#define TX4927_PCIC_PBASTATUS_BM 0x00000001
+
+/* bits for G2PMnGBASE */
+#define TX4927_PCIC_G2PMnGBASE_BSDIS 0x0000002000000000ULL
+#define TX4927_PCIC_G2PMnGBASE_ECHG 0x0000001000000000ULL
+
+/* bits for G2PIOGBASE */
+#define TX4927_PCIC_G2PIOGBASE_BSDIS 0x0000002000000000ULL
+#define TX4927_PCIC_G2PIOGBASE_ECHG 0x0000001000000000ULL
+
+/* bits for PCICSTATUS/PCICMASK */
+#define TX4927_PCIC_PCICSTATUS_ALL 0x000007b8
+#define TX4927_PCIC_PCICSTATUS_PME 0x00000400
+#define TX4927_PCIC_PCICSTATUS_TLB 0x00000200
+#define TX4927_PCIC_PCICSTATUS_NIB 0x00000100
+#define TX4927_PCIC_PCICSTATUS_ZIB 0x00000080
+#define TX4927_PCIC_PCICSTATUS_PERR 0x00000020
+#define TX4927_PCIC_PCICSTATUS_SERR 0x00000010
+#define TX4927_PCIC_PCICSTATUS_GBE 0x00000008
+#define TX4927_PCIC_PCICSTATUS_IWB 0x00000002
+#define TX4927_PCIC_PCICSTATUS_E2PDONE 0x00000001
+
+/* bits for PCICCFG */
+#define TX4927_PCIC_PCICCFG_GBWC_MASK 0x0fff0000
+#define TX4927_PCIC_PCICCFG_HRST 0x00000800
+#define TX4927_PCIC_PCICCFG_SRST 0x00000400
+#define TX4927_PCIC_PCICCFG_IRBER 0x00000200
+#define TX4927_PCIC_PCICCFG_G2PMEN(ch) (0x00000100>>(ch))
+#define TX4927_PCIC_PCICCFG_G2PM0EN 0x00000100
+#define TX4927_PCIC_PCICCFG_G2PM1EN 0x00000080
+#define TX4927_PCIC_PCICCFG_G2PM2EN 0x00000040
+#define TX4927_PCIC_PCICCFG_G2PIOEN 0x00000020
+#define TX4927_PCIC_PCICCFG_TCAR 0x00000010
+#define TX4927_PCIC_PCICCFG_ICAEN 0x00000008
+
+/* bits for P2GMnGBASE */
+#define TX4927_PCIC_P2GMnGBASE_TMEMEN 0x0000004000000000ULL
+#define TX4927_PCIC_P2GMnGBASE_TBSDIS 0x0000002000000000ULL
+#define TX4927_PCIC_P2GMnGBASE_TECHG 0x0000001000000000ULL
+
+/* bits for P2GIOGBASE */
+#define TX4927_PCIC_P2GIOGBASE_TIOEN 0x0000004000000000ULL
+#define TX4927_PCIC_P2GIOGBASE_TBSDIS 0x0000002000000000ULL
+#define TX4927_PCIC_P2GIOGBASE_TECHG 0x0000001000000000ULL
+
+#define TX4927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11)
+#define TX4927_PCIC_MAX_DEVNU TX4927_PCIC_IDSEL_AD_TO_SLOT(32)
+
+/* bits for PDMCFG */
+#define TX4927_PCIC_PDMCFG_RSTFIFO 0x00200000
+#define TX4927_PCIC_PDMCFG_EXFER 0x00100000
+#define TX4927_PCIC_PDMCFG_REQDLY_MASK 0x00003800
+#define TX4927_PCIC_PDMCFG_REQDLY_NONE (0 << 11)
+#define TX4927_PCIC_PDMCFG_REQDLY_16 (1 << 11)
+#define TX4927_PCIC_PDMCFG_REQDLY_32 (2 << 11)
+#define TX4927_PCIC_PDMCFG_REQDLY_64 (3 << 11)
+#define TX4927_PCIC_PDMCFG_REQDLY_128 (4 << 11)
+#define TX4927_PCIC_PDMCFG_REQDLY_256 (5 << 11)
+#define TX4927_PCIC_PDMCFG_REQDLY_512 (6 << 11)
+#define TX4927_PCIC_PDMCFG_REQDLY_1024 (7 << 11)
+#define TX4927_PCIC_PDMCFG_ERRIE 0x00000400
+#define TX4927_PCIC_PDMCFG_NCCMPIE 0x00000200
+#define TX4927_PCIC_PDMCFG_NTCMPIE 0x00000100
+#define TX4927_PCIC_PDMCFG_CHNEN 0x00000080
+#define TX4927_PCIC_PDMCFG_XFRACT 0x00000040
+#define TX4927_PCIC_PDMCFG_BSWAP 0x00000020
+#define TX4927_PCIC_PDMCFG_XFRSIZE_MASK 0x0000000c
+#define TX4927_PCIC_PDMCFG_XFRSIZE_1DW 0x00000000
+#define TX4927_PCIC_PDMCFG_XFRSIZE_1QW 0x00000004
+#define TX4927_PCIC_PDMCFG_XFRSIZE_4QW 0x00000008
+#define TX4927_PCIC_PDMCFG_XFRDIRC 0x00000002
+#define TX4927_PCIC_PDMCFG_CHRST 0x00000001
+
+/* bits for PDMSTS */
+#define TX4927_PCIC_PDMSTS_REQCNT_MASK 0x3f000000
+#define TX4927_PCIC_PDMSTS_FIFOCNT_MASK 0x00f00000
+#define TX4927_PCIC_PDMSTS_FIFOWP_MASK 0x000c0000
+#define TX4927_PCIC_PDMSTS_FIFORP_MASK 0x00030000
+#define TX4927_PCIC_PDMSTS_ERRINT 0x00000800
+#define TX4927_PCIC_PDMSTS_DONEINT 0x00000400
+#define TX4927_PCIC_PDMSTS_CHNEN 0x00000200
+#define TX4927_PCIC_PDMSTS_XFRACT 0x00000100
+#define TX4927_PCIC_PDMSTS_ACCMP 0x00000080
+#define TX4927_PCIC_PDMSTS_NCCMP 0x00000040
+#define TX4927_PCIC_PDMSTS_NTCMP 0x00000020
+#define TX4927_PCIC_PDMSTS_CFGERR 0x00000008
+#define TX4927_PCIC_PDMSTS_PCIERR 0x00000004
+#define TX4927_PCIC_PDMSTS_CHNERR 0x00000002
+#define TX4927_PCIC_PDMSTS_DATAERR 0x00000001
+#define TX4927_PCIC_PDMSTS_ALL_CMP 0x000000e0
+#define TX4927_PCIC_PDMSTS_ALL_ERR 0x0000000f
+
+struct tx4927_pcic_reg __iomem *get_tx4927_pcicptr(
+ struct pci_controller *channel);
+void tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr,
+ struct pci_controller *channel, int extarb);
+void tx4927_report_pcic_status(void);
+char *tx4927_pcibios_setup(char *str);
+void tx4927_dump_pcic_settings(void);
+irqreturn_t tx4927_pcierr_interrupt(int irq, void *dev_id);
+
+#endif /* __ASM_TXX9_TX4927PCIC_H */
diff --git a/arch/mips/include/asm/txx9/tx4938.h b/arch/mips/include/asm/txx9/tx4938.h
new file mode 100644
index 00000000..8a178f18
--- /dev/null
+++ b/arch/mips/include/asm/txx9/tx4938.h
@@ -0,0 +1,312 @@
+/*
+ * Definitions for TX4937/TX4938
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#ifndef __ASM_TXX9_TX4938_H
+#define __ASM_TXX9_TX4938_H
+
+/* some controllers are compatible with 4927 */
+#include <asm/txx9/tx4927.h>
+
+#ifdef CONFIG_64BIT
+#define TX4938_REG_BASE 0xffffffffff1f0000UL /* == TX4937_REG_BASE */
+#else
+#define TX4938_REG_BASE 0xff1f0000UL /* == TX4937_REG_BASE */
+#endif
+#define TX4938_REG_SIZE 0x00010000 /* == TX4937_REG_SIZE */
+
+/* NDFMC, SRAMC, PCIC1, SPIC: TX4938 only */
+#define TX4938_NDFMC_REG (TX4938_REG_BASE + 0x5000)
+#define TX4938_SRAMC_REG (TX4938_REG_BASE + 0x6000)
+#define TX4938_PCIC1_REG (TX4938_REG_BASE + 0x7000)
+#define TX4938_SDRAMC_REG (TX4938_REG_BASE + 0x8000)
+#define TX4938_EBUSC_REG (TX4938_REG_BASE + 0x9000)
+#define TX4938_DMA_REG(ch) (TX4938_REG_BASE + 0xb000 + (ch) * 0x800)
+#define TX4938_PCIC_REG (TX4938_REG_BASE + 0xd000)
+#define TX4938_CCFG_REG (TX4938_REG_BASE + 0xe000)
+#define TX4938_NR_TMR 3
+#define TX4938_TMR_REG(ch) ((TX4938_REG_BASE + 0xf000) + (ch) * 0x100)
+#define TX4938_NR_SIO 2
+#define TX4938_SIO_REG(ch) ((TX4938_REG_BASE + 0xf300) + (ch) * 0x100)
+#define TX4938_PIO_REG (TX4938_REG_BASE + 0xf500)
+#define TX4938_IRC_REG (TX4938_REG_BASE + 0xf600)
+#define TX4938_ACLC_REG (TX4938_REG_BASE + 0xf700)
+#define TX4938_SPI_REG (TX4938_REG_BASE + 0xf800)
+
+struct tx4938_sramc_reg {
+ u64 cr;
+};
+
+struct tx4938_ccfg_reg {
+ u64 ccfg;
+ u64 crir;
+ u64 pcfg;
+ u64 toea;
+ u64 clkctr;
+ u64 unused0;
+ u64 garbc;
+ u64 unused1;
+ u64 unused2;
+ u64 ramp;
+ u64 unused3;
+ u64 jmpadr;
+};
+
+/*
+ * IRC
+ */
+
+#define TX4938_IR_ECCERR 0
+#define TX4938_IR_WTOERR 1
+#define TX4938_NUM_IR_INT 6
+#define TX4938_IR_INT(n) (2 + (n))
+#define TX4938_NUM_IR_SIO 2
+#define TX4938_IR_SIO(n) (8 + (n))
+#define TX4938_NUM_IR_DMA 4
+#define TX4938_IR_DMA(ch, n) ((ch ? 27 : 10) + (n)) /* 10-13, 27-30 */
+#define TX4938_IR_PIO 14
+#define TX4938_IR_PDMAC 15
+#define TX4938_IR_PCIC 16
+#define TX4938_NUM_IR_TMR 3
+#define TX4938_IR_TMR(n) (17 + (n))
+#define TX4938_IR_NDFMC 21
+#define TX4938_IR_PCIERR 22
+#define TX4938_IR_PCIPME 23
+#define TX4938_IR_ACLC 24
+#define TX4938_IR_ACLCPME 25
+#define TX4938_IR_PCIC1 26
+#define TX4938_IR_SPI 31
+#define TX4938_NUM_IR 32
+/* multiplex */
+#define TX4938_IR_ETH0 TX4938_IR_INT(4)
+#define TX4938_IR_ETH1 TX4938_IR_INT(3)
+
+#define TX4938_IRC_INT 2 /* IP[2] in Status register */
+
+#define TX4938_NUM_PIO 16
+
+/*
+ * CCFG
+ */
+/* CCFG : Chip Configuration */
+#define TX4938_CCFG_WDRST 0x0000020000000000ULL
+#define TX4938_CCFG_WDREXEN 0x0000010000000000ULL
+#define TX4938_CCFG_BCFG_MASK 0x000000ff00000000ULL
+#define TX4938_CCFG_TINTDIS 0x01000000
+#define TX4938_CCFG_PCI66 0x00800000
+#define TX4938_CCFG_PCIMODE 0x00400000
+#define TX4938_CCFG_PCI1_66 0x00200000
+#define TX4938_CCFG_DIVMODE_MASK 0x001e0000
+#define TX4938_CCFG_DIVMODE_2 (0x4 << 17)
+#define TX4938_CCFG_DIVMODE_2_5 (0xf << 17)
+#define TX4938_CCFG_DIVMODE_3 (0x5 << 17)
+#define TX4938_CCFG_DIVMODE_4 (0x6 << 17)
+#define TX4938_CCFG_DIVMODE_4_5 (0xd << 17)
+#define TX4938_CCFG_DIVMODE_8 (0x0 << 17)
+#define TX4938_CCFG_DIVMODE_10 (0xb << 17)
+#define TX4938_CCFG_DIVMODE_12 (0x1 << 17)
+#define TX4938_CCFG_DIVMODE_16 (0x2 << 17)
+#define TX4938_CCFG_DIVMODE_18 (0x9 << 17)
+#define TX4938_CCFG_BEOW 0x00010000
+#define TX4938_CCFG_WR 0x00008000
+#define TX4938_CCFG_TOE 0x00004000
+#define TX4938_CCFG_PCIARB 0x00002000
+#define TX4938_CCFG_PCIDIVMODE_MASK 0x00001c00
+#define TX4938_CCFG_PCIDIVMODE_4 (0x1 << 10)
+#define TX4938_CCFG_PCIDIVMODE_4_5 (0x3 << 10)
+#define TX4938_CCFG_PCIDIVMODE_5 (0x5 << 10)
+#define TX4938_CCFG_PCIDIVMODE_5_5 (0x7 << 10)
+#define TX4938_CCFG_PCIDIVMODE_8 (0x0 << 10)
+#define TX4938_CCFG_PCIDIVMODE_9 (0x2 << 10)
+#define TX4938_CCFG_PCIDIVMODE_10 (0x4 << 10)
+#define TX4938_CCFG_PCIDIVMODE_11 (0x6 << 10)
+#define TX4938_CCFG_PCI1DMD 0x00000100
+#define TX4938_CCFG_SYSSP_MASK 0x000000c0
+#define TX4938_CCFG_ENDIAN 0x00000004
+#define TX4938_CCFG_HALT 0x00000002
+#define TX4938_CCFG_ACEHOLD 0x00000001
+
+/* PCFG : Pin Configuration */
+#define TX4938_PCFG_ETH0_SEL 0x8000000000000000ULL
+#define TX4938_PCFG_ETH1_SEL 0x4000000000000000ULL
+#define TX4938_PCFG_ATA_SEL 0x2000000000000000ULL
+#define TX4938_PCFG_ISA_SEL 0x1000000000000000ULL
+#define TX4938_PCFG_SPI_SEL 0x0800000000000000ULL
+#define TX4938_PCFG_NDF_SEL 0x0400000000000000ULL
+#define TX4938_PCFG_SDCLKDLY_MASK 0x30000000
+#define TX4938_PCFG_SDCLKDLY(d) ((d)<<28)
+#define TX4938_PCFG_SYSCLKEN 0x08000000
+#define TX4938_PCFG_SDCLKEN_ALL 0x07800000
+#define TX4938_PCFG_SDCLKEN(ch) (0x00800000<<(ch))
+#define TX4938_PCFG_PCICLKEN_ALL 0x003f0000
+#define TX4938_PCFG_PCICLKEN(ch) (0x00010000<<(ch))
+#define TX4938_PCFG_SEL2 0x00000200
+#define TX4938_PCFG_SEL1 0x00000100
+#define TX4938_PCFG_DMASEL_ALL 0x0000000f
+#define TX4938_PCFG_DMASEL0_DRQ0 0x00000000
+#define TX4938_PCFG_DMASEL0_SIO1 0x00000001
+#define TX4938_PCFG_DMASEL1_DRQ1 0x00000000
+#define TX4938_PCFG_DMASEL1_SIO1 0x00000002
+#define TX4938_PCFG_DMASEL2_DRQ2 0x00000000
+#define TX4938_PCFG_DMASEL2_SIO0 0x00000004
+#define TX4938_PCFG_DMASEL3_DRQ3 0x00000000
+#define TX4938_PCFG_DMASEL3_SIO0 0x00000008
+
+/* CLKCTR : Clock Control */
+#define TX4938_CLKCTR_NDFCKD 0x0001000000000000ULL
+#define TX4938_CLKCTR_NDFRST 0x0000000100000000ULL
+#define TX4938_CLKCTR_ETH1CKD 0x80000000
+#define TX4938_CLKCTR_ETH0CKD 0x40000000
+#define TX4938_CLKCTR_SPICKD 0x20000000
+#define TX4938_CLKCTR_SRAMCKD 0x10000000
+#define TX4938_CLKCTR_PCIC1CKD 0x08000000
+#define TX4938_CLKCTR_DMA1CKD 0x04000000
+#define TX4938_CLKCTR_ACLCKD 0x02000000
+#define TX4938_CLKCTR_PIOCKD 0x01000000
+#define TX4938_CLKCTR_DMACKD 0x00800000
+#define TX4938_CLKCTR_PCICKD 0x00400000
+#define TX4938_CLKCTR_TM0CKD 0x00100000
+#define TX4938_CLKCTR_TM1CKD 0x00080000
+#define TX4938_CLKCTR_TM2CKD 0x00040000
+#define TX4938_CLKCTR_SIO0CKD 0x00020000
+#define TX4938_CLKCTR_SIO1CKD 0x00010000
+#define TX4938_CLKCTR_ETH1RST 0x00008000
+#define TX4938_CLKCTR_ETH0RST 0x00004000
+#define TX4938_CLKCTR_SPIRST 0x00002000
+#define TX4938_CLKCTR_SRAMRST 0x00001000
+#define TX4938_CLKCTR_PCIC1RST 0x00000800
+#define TX4938_CLKCTR_DMA1RST 0x00000400
+#define TX4938_CLKCTR_ACLRST 0x00000200
+#define TX4938_CLKCTR_PIORST 0x00000100
+#define TX4938_CLKCTR_DMARST 0x00000080
+#define TX4938_CLKCTR_PCIRST 0x00000040
+#define TX4938_CLKCTR_TM0RST 0x00000010
+#define TX4938_CLKCTR_TM1RST 0x00000008
+#define TX4938_CLKCTR_TM2RST 0x00000004
+#define TX4938_CLKCTR_SIO0RST 0x00000002
+#define TX4938_CLKCTR_SIO1RST 0x00000001
+
+/*
+ * DMA
+ */
+/* bits for MCR */
+#define TX4938_DMA_MCR_EIS(ch) (0x10000000<<(ch))
+#define TX4938_DMA_MCR_DIS(ch) (0x01000000<<(ch))
+#define TX4938_DMA_MCR_RSFIF 0x00000080
+#define TX4938_DMA_MCR_FIFUM(ch) (0x00000008<<(ch))
+#define TX4938_DMA_MCR_RPRT 0x00000002
+#define TX4938_DMA_MCR_MSTEN 0x00000001
+
+/* bits for CCRn */
+#define TX4938_DMA_CCR_IMMCHN 0x20000000
+#define TX4938_DMA_CCR_USEXFSZ 0x10000000
+#define TX4938_DMA_CCR_LE 0x08000000
+#define TX4938_DMA_CCR_DBINH 0x04000000
+#define TX4938_DMA_CCR_SBINH 0x02000000
+#define TX4938_DMA_CCR_CHRST 0x01000000
+#define TX4938_DMA_CCR_RVBYTE 0x00800000
+#define TX4938_DMA_CCR_ACKPOL 0x00400000
+#define TX4938_DMA_CCR_REQPL 0x00200000
+#define TX4938_DMA_CCR_EGREQ 0x00100000
+#define TX4938_DMA_CCR_CHDN 0x00080000
+#define TX4938_DMA_CCR_DNCTL 0x00060000
+#define TX4938_DMA_CCR_EXTRQ 0x00010000
+#define TX4938_DMA_CCR_INTRQD 0x0000e000
+#define TX4938_DMA_CCR_INTENE 0x00001000
+#define TX4938_DMA_CCR_INTENC 0x00000800
+#define TX4938_DMA_CCR_INTENT 0x00000400
+#define TX4938_DMA_CCR_CHNEN 0x00000200
+#define TX4938_DMA_CCR_XFACT 0x00000100
+#define TX4938_DMA_CCR_SMPCHN 0x00000020
+#define TX4938_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c)
+#define TX4938_DMA_CCR_XFSZ_1W TX4938_DMA_CCR_XFSZ(2)
+#define TX4938_DMA_CCR_XFSZ_2W TX4938_DMA_CCR_XFSZ(3)
+#define TX4938_DMA_CCR_XFSZ_4W TX4938_DMA_CCR_XFSZ(4)
+#define TX4938_DMA_CCR_XFSZ_8W TX4938_DMA_CCR_XFSZ(5)
+#define TX4938_DMA_CCR_XFSZ_16W TX4938_DMA_CCR_XFSZ(6)
+#define TX4938_DMA_CCR_XFSZ_32W TX4938_DMA_CCR_XFSZ(7)
+#define TX4938_DMA_CCR_MEMIO 0x00000002
+#define TX4938_DMA_CCR_SNGAD 0x00000001
+
+/* bits for CSRn */
+#define TX4938_DMA_CSR_CHNEN 0x00000400
+#define TX4938_DMA_CSR_STLXFER 0x00000200
+#define TX4938_DMA_CSR_CHNACT 0x00000100
+#define TX4938_DMA_CSR_ABCHC 0x00000080
+#define TX4938_DMA_CSR_NCHNC 0x00000040
+#define TX4938_DMA_CSR_NTRNFC 0x00000020
+#define TX4938_DMA_CSR_EXTDN 0x00000010
+#define TX4938_DMA_CSR_CFERR 0x00000008
+#define TX4938_DMA_CSR_CHERR 0x00000004
+#define TX4938_DMA_CSR_DESERR 0x00000002
+#define TX4938_DMA_CSR_SORERR 0x00000001
+
+#define tx4938_sdramcptr tx4927_sdramcptr
+#define tx4938_ebuscptr tx4927_ebuscptr
+#define tx4938_pcicptr tx4927_pcicptr
+#define tx4938_pcic1ptr \
+ ((struct tx4927_pcic_reg __iomem *)TX4938_PCIC1_REG)
+#define tx4938_ccfgptr \
+ ((struct tx4938_ccfg_reg __iomem *)TX4938_CCFG_REG)
+#define tx4938_pioptr ((struct txx9_pio_reg __iomem *)TX4938_PIO_REG)
+#define tx4938_sramcptr \
+ ((struct tx4938_sramc_reg __iomem *)TX4938_SRAMC_REG)
+
+
+#define TX4938_REV_PCODE() \
+ ((__u32)__raw_readq(&tx4938_ccfgptr->crir) >> 16)
+
+#define tx4938_ccfg_clear(bits) tx4927_ccfg_clear(bits)
+#define tx4938_ccfg_set(bits) tx4927_ccfg_set(bits)
+#define tx4938_ccfg_change(change, new) tx4927_ccfg_change(change, new)
+
+#define TX4938_SDRAMC_CR(ch) TX4927_SDRAMC_CR(ch)
+#define TX4938_SDRAMC_BA(ch) TX4927_SDRAMC_BA(ch)
+#define TX4938_SDRAMC_SIZE(ch) TX4927_SDRAMC_SIZE(ch)
+
+#define TX4938_EBUSC_CR(ch) TX4927_EBUSC_CR(ch)
+#define TX4938_EBUSC_BA(ch) TX4927_EBUSC_BA(ch)
+#define TX4938_EBUSC_SIZE(ch) TX4927_EBUSC_SIZE(ch)
+#define TX4938_EBUSC_WIDTH(ch) TX4927_EBUSC_WIDTH(ch)
+
+#define tx4938_get_mem_size() tx4927_get_mem_size()
+void tx4938_wdt_init(void);
+void tx4938_setup(void);
+void tx4938_time_init(unsigned int tmrnr);
+void tx4938_sio_init(unsigned int sclk, unsigned int cts_mask);
+void tx4938_spi_init(int busid);
+void tx4938_ethaddr_init(unsigned char *addr0, unsigned char *addr1);
+int tx4938_report_pciclk(void);
+void tx4938_report_pci1clk(void);
+int tx4938_pciclk66_setup(void);
+struct pci_dev;
+int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot);
+void tx4938_setup_pcierr_irq(void);
+void tx4938_irq_init(void);
+void tx4938_mtd_init(int ch);
+void tx4938_ndfmc_init(unsigned int hold, unsigned int spw);
+
+struct tx4938ide_platform_info {
+ /*
+ * I/O port shift, for platforms with ports that are
+ * constantly spaced and need larger than the 1-byte
+ * spacing used by ata_std_ports().
+ */
+ unsigned int ioport_shift;
+ unsigned int gbus_clock; /* 0 means no PIO mode tuning. */
+ unsigned int ebus_ch;
+};
+
+void tx4938_ata_init(unsigned int irq, unsigned int shift, int tune);
+void tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1);
+void tx4938_aclc_init(void);
+void tx4938_sramc_init(void);
+
+#endif
diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h
new file mode 100644
index 00000000..d4f342cd
--- /dev/null
+++ b/arch/mips/include/asm/txx9/tx4939.h
@@ -0,0 +1,554 @@
+/*
+ * Definitions for TX4939
+ *
+ * Copyright (C) 2000-2001,2005-2006 Toshiba Corporation
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_TXX9_TX4939_H
+#define __ASM_TXX9_TX4939_H
+
+/* some controllers are compatible with 4927/4938 */
+#include <asm/txx9/tx4938.h>
+
+#ifdef CONFIG_64BIT
+#define TX4939_REG_BASE 0xffffffffff1f0000UL /* == TX4938_REG_BASE */
+#else
+#define TX4939_REG_BASE 0xff1f0000UL /* == TX4938_REG_BASE */
+#endif
+#define TX4939_REG_SIZE 0x00010000 /* == TX4938_REG_SIZE */
+
+#define TX4939_ATA_REG(ch) (TX4939_REG_BASE + 0x3000 + (ch) * 0x1000)
+#define TX4939_NDFMC_REG (TX4939_REG_BASE + 0x5000)
+#define TX4939_SRAMC_REG (TX4939_REG_BASE + 0x6000)
+#define TX4939_CRYPTO_REG (TX4939_REG_BASE + 0x6800)
+#define TX4939_PCIC1_REG (TX4939_REG_BASE + 0x7000)
+#define TX4939_DDRC_REG (TX4939_REG_BASE + 0x8000)
+#define TX4939_EBUSC_REG (TX4939_REG_BASE + 0x9000)
+#define TX4939_VPC_REG (TX4939_REG_BASE + 0xa000)
+#define TX4939_DMA_REG(ch) (TX4939_REG_BASE + 0xb000 + (ch) * 0x800)
+#define TX4939_PCIC_REG (TX4939_REG_BASE + 0xd000)
+#define TX4939_CCFG_REG (TX4939_REG_BASE + 0xe000)
+#define TX4939_IRC_REG (TX4939_REG_BASE + 0xe800)
+#define TX4939_NR_TMR 6 /* 0xf000,0xf100,0xf200,0xfd00,0xfe00,0xff00 */
+#define TX4939_TMR_REG(ch) \
+ (TX4939_REG_BASE + 0xf000 + ((ch) + ((ch) >= 3) * 10) * 0x100)
+#define TX4939_NR_SIO 4 /* 0xf300, 0xf400, 0xf380, 0xf480 */
+#define TX4939_SIO_REG(ch) \
+ (TX4939_REG_BASE + 0xf300 + (((ch) & 1) << 8) + (((ch) & 2) << 6))
+#define TX4939_ACLC_REG (TX4939_REG_BASE + 0xf700)
+#define TX4939_SPI_REG (TX4939_REG_BASE + 0xf800)
+#define TX4939_I2C_REG (TX4939_REG_BASE + 0xf900)
+#define TX4939_I2S_REG (TX4939_REG_BASE + 0xfa00)
+#define TX4939_RTC_REG (TX4939_REG_BASE + 0xfb00)
+#define TX4939_CIR_REG (TX4939_REG_BASE + 0xfc00)
+
+#define TX4939_RNG_REG (TX4939_CRYPTO_REG + 0xb0)
+
+struct tx4939_le_reg {
+ __u32 r;
+ __u32 unused;
+};
+
+struct tx4939_ddrc_reg {
+ struct tx4939_le_reg ctl[47];
+ __u64 unused0[17];
+ __u64 winen;
+ __u64 win[4];
+};
+
+struct tx4939_ccfg_reg {
+ __u64 ccfg;
+ __u64 crir;
+ __u64 pcfg;
+ __u64 toea;
+ __u64 clkctr;
+ __u64 unused0;
+ __u64 garbc;
+ __u64 unused1[2];
+ __u64 ramp;
+ __u64 unused2[2];
+ __u64 dskwctrl;
+ __u64 mclkosc;
+ __u64 mclkctl;
+ __u64 unused3[17];
+ struct {
+ __u64 mr;
+ __u64 dr;
+ } gpio[2];
+};
+
+struct tx4939_irc_reg {
+ struct tx4939_le_reg den;
+ struct tx4939_le_reg scipb;
+ struct tx4939_le_reg dm[2];
+ struct tx4939_le_reg lvl[16];
+ struct tx4939_le_reg msk;
+ struct tx4939_le_reg edc;
+ struct tx4939_le_reg pnd0;
+ struct tx4939_le_reg cs;
+ struct tx4939_le_reg pnd1;
+ struct tx4939_le_reg dm2[2];
+ struct tx4939_le_reg dbr[2];
+ struct tx4939_le_reg dben;
+ struct tx4939_le_reg unused0[2];
+ struct tx4939_le_reg flag[2];
+ struct tx4939_le_reg pol;
+ struct tx4939_le_reg cnt;
+ struct tx4939_le_reg maskint;
+ struct tx4939_le_reg maskext;
+};
+
+struct tx4939_rtc_reg {
+ __u32 ctl;
+ __u32 adr;
+ __u32 dat;
+ __u32 tbc;
+};
+
+struct tx4939_crypto_reg {
+ struct tx4939_le_reg csr;
+ struct tx4939_le_reg idesptr;
+ struct tx4939_le_reg cdesptr;
+ struct tx4939_le_reg buserr;
+ struct tx4939_le_reg cip_tout;
+ struct tx4939_le_reg cir;
+ union {
+ struct {
+ struct tx4939_le_reg data[8];
+ struct tx4939_le_reg ctrl;
+ } gen;
+ struct {
+ struct {
+ struct tx4939_le_reg l;
+ struct tx4939_le_reg u;
+ } key[3], ini;
+ struct tx4939_le_reg ctrl;
+ } des;
+ struct {
+ struct tx4939_le_reg key[4];
+ struct tx4939_le_reg ini[4];
+ struct tx4939_le_reg ctrl;
+ } aes;
+ struct {
+ struct {
+ struct tx4939_le_reg l;
+ struct tx4939_le_reg u;
+ } cnt;
+ struct tx4939_le_reg ini[5];
+ struct tx4939_le_reg unused;
+ struct tx4939_le_reg ctrl;
+ } hash;
+ } cdr;
+ struct tx4939_le_reg unused0[7];
+ struct tx4939_le_reg rcsr;
+ struct tx4939_le_reg rpr;
+ __u64 rdr;
+ __u64 ror[3];
+ struct tx4939_le_reg unused1[2];
+ struct tx4939_le_reg xorslr;
+ struct tx4939_le_reg xorsur;
+};
+
+struct tx4939_crypto_desc {
+ __u32 src;
+ __u32 dst;
+ __u32 next;
+ __u32 ctrl;
+ __u32 index;
+ __u32 xor;
+};
+
+struct tx4939_vpc_reg {
+ struct tx4939_le_reg csr;
+ struct {
+ struct tx4939_le_reg ctrlA;
+ struct tx4939_le_reg ctrlB;
+ struct tx4939_le_reg idesptr;
+ struct tx4939_le_reg cdesptr;
+ } port[3];
+ struct tx4939_le_reg buserr;
+};
+
+struct tx4939_vpc_desc {
+ __u32 src;
+ __u32 next;
+ __u32 ctrl1;
+ __u32 ctrl2;
+};
+
+/*
+ * IRC
+ */
+#define TX4939_IR_NONE 0
+#define TX4939_IR_DDR 1
+#define TX4939_IR_WTOERR 2
+#define TX4939_NUM_IR_INT 3
+#define TX4939_IR_INT(n) (3 + (n))
+#define TX4939_NUM_IR_ETH 2
+#define TX4939_IR_ETH(n) ((n) ? 43 : 6)
+#define TX4939_IR_VIDEO 7
+#define TX4939_IR_CIR 8
+#define TX4939_NUM_IR_SIO 4
+#define TX4939_IR_SIO(n) ((n) ? 43 + (n) : 9) /* 9,44-46 */
+#define TX4939_NUM_IR_DMA 4
+#define TX4939_IR_DMA(ch, n) (((ch) ? 22 : 10) + (n)) /* 10-13,22-25 */
+#define TX4939_IR_IRC 14
+#define TX4939_IR_PDMAC 15
+#define TX4939_NUM_IR_TMR 6
+#define TX4939_IR_TMR(n) (((n) >= 3 ? 45 : 16) + (n)) /* 16-18,48-50 */
+#define TX4939_NUM_IR_ATA 2
+#define TX4939_IR_ATA(n) (19 + (n))
+#define TX4939_IR_ACLC 21
+#define TX4939_IR_CIPHER 26
+#define TX4939_IR_INTA 27
+#define TX4939_IR_INTB 28
+#define TX4939_IR_INTC 29
+#define TX4939_IR_INTD 30
+#define TX4939_IR_I2C 33
+#define TX4939_IR_SPI 34
+#define TX4939_IR_PCIC 35
+#define TX4939_IR_PCIC1 36
+#define TX4939_IR_PCIERR 37
+#define TX4939_IR_PCIPME 38
+#define TX4939_IR_NDFMC 39
+#define TX4939_IR_ACLCPME 40
+#define TX4939_IR_RTC 41
+#define TX4939_IR_RND 42
+#define TX4939_IR_I2S 47
+#define TX4939_NUM_IR 64
+
+#define TX4939_IRC_INT 2 /* IP[2] in Status register */
+
+/*
+ * CCFG
+ */
+/* CCFG : Chip Configuration */
+#define TX4939_CCFG_PCIBOOT 0x0000040000000000ULL
+#define TX4939_CCFG_WDRST 0x0000020000000000ULL
+#define TX4939_CCFG_WDREXEN 0x0000010000000000ULL
+#define TX4939_CCFG_BCFG_MASK 0x000000ff00000000ULL
+#define TX4939_CCFG_GTOT_MASK 0x06000000
+#define TX4939_CCFG_GTOT_4096 0x06000000
+#define TX4939_CCFG_GTOT_2048 0x04000000
+#define TX4939_CCFG_GTOT_1024 0x02000000
+#define TX4939_CCFG_GTOT_512 0x00000000
+#define TX4939_CCFG_TINTDIS 0x01000000
+#define TX4939_CCFG_PCI66 0x00800000
+#define TX4939_CCFG_PCIMODE 0x00400000
+#define TX4939_CCFG_SSCG 0x00100000
+#define TX4939_CCFG_MULCLK_MASK 0x000e0000
+#define TX4939_CCFG_MULCLK_8 (0x7 << 17)
+#define TX4939_CCFG_MULCLK_9 (0x0 << 17)
+#define TX4939_CCFG_MULCLK_10 (0x1 << 17)
+#define TX4939_CCFG_MULCLK_11 (0x2 << 17)
+#define TX4939_CCFG_MULCLK_12 (0x3 << 17)
+#define TX4939_CCFG_MULCLK_13 (0x4 << 17)
+#define TX4939_CCFG_MULCLK_14 (0x5 << 17)
+#define TX4939_CCFG_MULCLK_15 (0x6 << 17)
+#define TX4939_CCFG_BEOW 0x00010000
+#define TX4939_CCFG_WR 0x00008000
+#define TX4939_CCFG_TOE 0x00004000
+#define TX4939_CCFG_PCIARB 0x00002000
+#define TX4939_CCFG_YDIVMODE_MASK 0x00001c00
+#define TX4939_CCFG_YDIVMODE_2 (0x0 << 10)
+#define TX4939_CCFG_YDIVMODE_3 (0x1 << 10)
+#define TX4939_CCFG_YDIVMODE_5 (0x6 << 10)
+#define TX4939_CCFG_YDIVMODE_6 (0x7 << 10)
+#define TX4939_CCFG_PTSEL 0x00000200
+#define TX4939_CCFG_BESEL 0x00000100
+#define TX4939_CCFG_SYSSP_MASK 0x000000c0
+#define TX4939_CCFG_ACKSEL 0x00000020
+#define TX4939_CCFG_ROMW 0x00000010
+#define TX4939_CCFG_ENDIAN 0x00000004
+#define TX4939_CCFG_ARMODE 0x00000002
+#define TX4939_CCFG_ACEHOLD 0x00000001
+
+/* PCFG : Pin Configuration */
+#define TX4939_PCFG_SIO2MODE_MASK 0xc000000000000000ULL
+#define TX4939_PCFG_SIO2MODE_GPIO 0x8000000000000000ULL
+#define TX4939_PCFG_SIO2MODE_SIO2 0x4000000000000000ULL
+#define TX4939_PCFG_SIO2MODE_SIO0 0x0000000000000000ULL
+#define TX4939_PCFG_SPIMODE 0x2000000000000000ULL
+#define TX4939_PCFG_I2CMODE 0x1000000000000000ULL
+#define TX4939_PCFG_I2SMODE_MASK 0x0c00000000000000ULL
+#define TX4939_PCFG_I2SMODE_GPIO 0x0c00000000000000ULL
+#define TX4939_PCFG_I2SMODE_I2S 0x0800000000000000ULL
+#define TX4939_PCFG_I2SMODE_I2S_ALT 0x0400000000000000ULL
+#define TX4939_PCFG_I2SMODE_ACLC 0x0000000000000000ULL
+#define TX4939_PCFG_SIO3MODE 0x0200000000000000ULL
+#define TX4939_PCFG_DMASEL3 0x0004000000000000ULL
+#define TX4939_PCFG_DMASEL3_SIO0 0x0004000000000000ULL
+#define TX4939_PCFG_DMASEL3_NDFC 0x0000000000000000ULL
+#define TX4939_PCFG_VSSMODE 0x0000200000000000ULL
+#define TX4939_PCFG_VPSMODE 0x0000100000000000ULL
+#define TX4939_PCFG_ET1MODE 0x0000080000000000ULL
+#define TX4939_PCFG_ET0MODE 0x0000040000000000ULL
+#define TX4939_PCFG_ATA1MODE 0x0000020000000000ULL
+#define TX4939_PCFG_ATA0MODE 0x0000010000000000ULL
+#define TX4939_PCFG_BP_PLL 0x0000000100000000ULL
+
+#define TX4939_PCFG_SYSCLKEN 0x08000000
+#define TX4939_PCFG_PCICLKEN_ALL 0x000f0000
+#define TX4939_PCFG_PCICLKEN(ch) (0x00010000<<(ch))
+#define TX4939_PCFG_SPEED1 0x00002000
+#define TX4939_PCFG_SPEED0 0x00001000
+#define TX4939_PCFG_ITMODE 0x00000300
+#define TX4939_PCFG_DMASEL_ALL (0x00000007 | TX4939_PCFG_DMASEL3)
+#define TX4939_PCFG_DMASEL2 0x00000004
+#define TX4939_PCFG_DMASEL2_DRQ2 0x00000000
+#define TX4939_PCFG_DMASEL2_SIO0 0x00000004
+#define TX4939_PCFG_DMASEL1 0x00000002
+#define TX4939_PCFG_DMASEL1_DRQ1 0x00000000
+#define TX4939_PCFG_DMASEL0 0x00000001
+#define TX4939_PCFG_DMASEL0_DRQ0 0x00000000
+
+/* CLKCTR : Clock Control */
+#define TX4939_CLKCTR_IOSCKD 0x8000000000000000ULL
+#define TX4939_CLKCTR_SYSCKD 0x4000000000000000ULL
+#define TX4939_CLKCTR_TM5CKD 0x2000000000000000ULL
+#define TX4939_CLKCTR_TM4CKD 0x1000000000000000ULL
+#define TX4939_CLKCTR_TM3CKD 0x0800000000000000ULL
+#define TX4939_CLKCTR_CIRCKD 0x0400000000000000ULL
+#define TX4939_CLKCTR_SIO3CKD 0x0200000000000000ULL
+#define TX4939_CLKCTR_SIO2CKD 0x0100000000000000ULL
+#define TX4939_CLKCTR_SIO1CKD 0x0080000000000000ULL
+#define TX4939_CLKCTR_VPCCKD 0x0040000000000000ULL
+#define TX4939_CLKCTR_EPCICKD 0x0020000000000000ULL
+#define TX4939_CLKCTR_ETH1CKD 0x0008000000000000ULL
+#define TX4939_CLKCTR_ATA1CKD 0x0004000000000000ULL
+#define TX4939_CLKCTR_BROMCKD 0x0002000000000000ULL
+#define TX4939_CLKCTR_NDCCKD 0x0001000000000000ULL
+#define TX4939_CLKCTR_I2CCKD 0x0000800000000000ULL
+#define TX4939_CLKCTR_ETH0CKD 0x0000400000000000ULL
+#define TX4939_CLKCTR_SPICKD 0x0000200000000000ULL
+#define TX4939_CLKCTR_SRAMCKD 0x0000100000000000ULL
+#define TX4939_CLKCTR_PCI1CKD 0x0000080000000000ULL
+#define TX4939_CLKCTR_DMA1CKD 0x0000040000000000ULL
+#define TX4939_CLKCTR_ACLCKD 0x0000020000000000ULL
+#define TX4939_CLKCTR_ATA0CKD 0x0000010000000000ULL
+#define TX4939_CLKCTR_DMA0CKD 0x0000008000000000ULL
+#define TX4939_CLKCTR_PCICCKD 0x0000004000000000ULL
+#define TX4939_CLKCTR_I2SCKD 0x0000002000000000ULL
+#define TX4939_CLKCTR_TM0CKD 0x0000001000000000ULL
+#define TX4939_CLKCTR_TM1CKD 0x0000000800000000ULL
+#define TX4939_CLKCTR_TM2CKD 0x0000000400000000ULL
+#define TX4939_CLKCTR_SIO0CKD 0x0000000200000000ULL
+#define TX4939_CLKCTR_CYPCKD 0x0000000100000000ULL
+#define TX4939_CLKCTR_IOSRST 0x80000000
+#define TX4939_CLKCTR_SYSRST 0x40000000
+#define TX4939_CLKCTR_TM5RST 0x20000000
+#define TX4939_CLKCTR_TM4RST 0x10000000
+#define TX4939_CLKCTR_TM3RST 0x08000000
+#define TX4939_CLKCTR_CIRRST 0x04000000
+#define TX4939_CLKCTR_SIO3RST 0x02000000
+#define TX4939_CLKCTR_SIO2RST 0x01000000
+#define TX4939_CLKCTR_SIO1RST 0x00800000
+#define TX4939_CLKCTR_VPCRST 0x00400000
+#define TX4939_CLKCTR_EPCIRST 0x00200000
+#define TX4939_CLKCTR_ETH1RST 0x00080000
+#define TX4939_CLKCTR_ATA1RST 0x00040000
+#define TX4939_CLKCTR_BROMRST 0x00020000
+#define TX4939_CLKCTR_NDCRST 0x00010000
+#define TX4939_CLKCTR_I2CRST 0x00008000
+#define TX4939_CLKCTR_ETH0RST 0x00004000
+#define TX4939_CLKCTR_SPIRST 0x00002000
+#define TX4939_CLKCTR_SRAMRST 0x00001000
+#define TX4939_CLKCTR_PCI1RST 0x00000800
+#define TX4939_CLKCTR_DMA1RST 0x00000400
+#define TX4939_CLKCTR_ACLRST 0x00000200
+#define TX4939_CLKCTR_ATA0RST 0x00000100
+#define TX4939_CLKCTR_DMA0RST 0x00000080
+#define TX4939_CLKCTR_PCICRST 0x00000040
+#define TX4939_CLKCTR_I2SRST 0x00000020
+#define TX4939_CLKCTR_TM0RST 0x00000010
+#define TX4939_CLKCTR_TM1RST 0x00000008
+#define TX4939_CLKCTR_TM2RST 0x00000004
+#define TX4939_CLKCTR_SIO0RST 0x00000002
+#define TX4939_CLKCTR_CYPRST 0x00000001
+
+/*
+ * RTC
+ */
+#define TX4939_RTCCTL_ALME 0x00000080
+#define TX4939_RTCCTL_ALMD 0x00000040
+#define TX4939_RTCCTL_BUSY 0x00000020
+
+#define TX4939_RTCCTL_COMMAND 0x00000007
+#define TX4939_RTCCTL_COMMAND_NOP 0x00000000
+#define TX4939_RTCCTL_COMMAND_GETTIME 0x00000001
+#define TX4939_RTCCTL_COMMAND_SETTIME 0x00000002
+#define TX4939_RTCCTL_COMMAND_GETALARM 0x00000003
+#define TX4939_RTCCTL_COMMAND_SETALARM 0x00000004
+
+#define TX4939_RTCTBC_PM 0x00000080
+#define TX4939_RTCTBC_COMP 0x0000007f
+
+#define TX4939_RTC_REG_RAMSIZE 0x00000100
+#define TX4939_RTC_REG_RWBSIZE 0x00000006
+
+/*
+ * CRYPTO
+ */
+#define TX4939_CRYPTO_CSR_SAESO 0x08000000
+#define TX4939_CRYPTO_CSR_SAESI 0x04000000
+#define TX4939_CRYPTO_CSR_SDESO 0x02000000
+#define TX4939_CRYPTO_CSR_SDESI 0x01000000
+#define TX4939_CRYPTO_CSR_INDXBST_MASK 0x00700000
+#define TX4939_CRYPTO_CSR_INDXBST(n) ((n) << 20)
+#define TX4939_CRYPTO_CSR_TOINT 0x00080000
+#define TX4939_CRYPTO_CSR_DCINT 0x00040000
+#define TX4939_CRYPTO_CSR_GBINT 0x00010000
+#define TX4939_CRYPTO_CSR_INDXAST_MASK 0x0000e000
+#define TX4939_CRYPTO_CSR_INDXAST(n) ((n) << 13)
+#define TX4939_CRYPTO_CSR_CSWAP_MASK 0x00001800
+#define TX4939_CRYPTO_CSR_CSWAP_NONE 0x00000000
+#define TX4939_CRYPTO_CSR_CSWAP_IN 0x00000800
+#define TX4939_CRYPTO_CSR_CSWAP_OUT 0x00001000
+#define TX4939_CRYPTO_CSR_CSWAP_BOTH 0x00001800
+#define TX4939_CRYPTO_CSR_CDIV_MASK 0x00000600
+#define TX4939_CRYPTO_CSR_CDIV_DIV2 0x00000000
+#define TX4939_CRYPTO_CSR_CDIV_DIV1 0x00000200
+#define TX4939_CRYPTO_CSR_CDIV_DIV2ALT 0x00000400
+#define TX4939_CRYPTO_CSR_CDIV_DIV1ALT 0x00000600
+#define TX4939_CRYPTO_CSR_PDINT_MASK 0x000000c0
+#define TX4939_CRYPTO_CSR_PDINT_ALL 0x00000000
+#define TX4939_CRYPTO_CSR_PDINT_END 0x00000040
+#define TX4939_CRYPTO_CSR_PDINT_NEXT 0x00000080
+#define TX4939_CRYPTO_CSR_PDINT_NONE 0x000000c0
+#define TX4939_CRYPTO_CSR_GINTE 0x00000008
+#define TX4939_CRYPTO_CSR_RSTD 0x00000004
+#define TX4939_CRYPTO_CSR_RSTC 0x00000002
+#define TX4939_CRYPTO_CSR_ENCR 0x00000001
+
+/* bits for tx4939_crypto_reg.cdr.gen.ctrl */
+#define TX4939_CRYPTO_CTX_ENGINE_MASK 0x00000003
+#define TX4939_CRYPTO_CTX_ENGINE_DES 0x00000000
+#define TX4939_CRYPTO_CTX_ENGINE_AES 0x00000001
+#define TX4939_CRYPTO_CTX_ENGINE_MD5 0x00000002
+#define TX4939_CRYPTO_CTX_ENGINE_SHA1 0x00000003
+#define TX4939_CRYPTO_CTX_TDMS 0x00000010
+#define TX4939_CRYPTO_CTX_CMS 0x00000020
+#define TX4939_CRYPTO_CTX_DMS 0x00000040
+#define TX4939_CRYPTO_CTX_UPDATE 0x00000080
+
+/* bits for tx4939_crypto_desc.ctrl */
+#define TX4939_CRYPTO_DESC_OB_CNT_MASK 0xffe00000
+#define TX4939_CRYPTO_DESC_OB_CNT(cnt) ((cnt) << 21)
+#define TX4939_CRYPTO_DESC_IB_CNT_MASK 0x001ffc00
+#define TX4939_CRYPTO_DESC_IB_CNT(cnt) ((cnt) << 10)
+#define TX4939_CRYPTO_DESC_START 0x00000200
+#define TX4939_CRYPTO_DESC_END 0x00000100
+#define TX4939_CRYPTO_DESC_XOR 0x00000010
+#define TX4939_CRYPTO_DESC_LAST 0x00000008
+#define TX4939_CRYPTO_DESC_ERR_MASK 0x00000006
+#define TX4939_CRYPTO_DESC_ERR_NONE 0x00000000
+#define TX4939_CRYPTO_DESC_ERR_TOUT 0x00000002
+#define TX4939_CRYPTO_DESC_ERR_DIGEST 0x00000004
+#define TX4939_CRYPTO_DESC_OWN 0x00000001
+
+/* bits for tx4939_crypto_desc.index */
+#define TX4939_CRYPTO_DESC_HASH_IDX_MASK 0x00000070
+#define TX4939_CRYPTO_DESC_HASH_IDX(idx) ((idx) << 4)
+#define TX4939_CRYPTO_DESC_ENCRYPT_IDX_MASK 0x00000007
+#define TX4939_CRYPTO_DESC_ENCRYPT_IDX(idx) ((idx) << 0)
+
+#define TX4939_CRYPTO_NR_SET 6
+
+#define TX4939_CRYPTO_RCSR_INTE 0x00000008
+#define TX4939_CRYPTO_RCSR_RST 0x00000004
+#define TX4939_CRYPTO_RCSR_FIN 0x00000002
+#define TX4939_CRYPTO_RCSR_ST 0x00000001
+
+/*
+ * VPC
+ */
+#define TX4939_VPC_CSR_GBINT 0x00010000
+#define TX4939_VPC_CSR_SWAPO 0x00000020
+#define TX4939_VPC_CSR_SWAPI 0x00000010
+#define TX4939_VPC_CSR_GINTE 0x00000008
+#define TX4939_VPC_CSR_RSTD 0x00000004
+#define TX4939_VPC_CSR_RSTVPC 0x00000002
+
+#define TX4939_VPC_CTRLA_VDPSN 0x00000200
+#define TX4939_VPC_CTRLA_PBUSY 0x00000100
+#define TX4939_VPC_CTRLA_DCINT 0x00000080
+#define TX4939_VPC_CTRLA_UOINT 0x00000040
+#define TX4939_VPC_CTRLA_PDINT_MASK 0x00000030
+#define TX4939_VPC_CTRLA_PDINT_ALL 0x00000000
+#define TX4939_VPC_CTRLA_PDINT_NEXT 0x00000010
+#define TX4939_VPC_CTRLA_PDINT_NONE 0x00000030
+#define TX4939_VPC_CTRLA_VDVLDP 0x00000008
+#define TX4939_VPC_CTRLA_VDMODE 0x00000004
+#define TX4939_VPC_CTRLA_VDFOR 0x00000002
+#define TX4939_VPC_CTRLA_ENVPC 0x00000001
+
+/* bits for tx4939_vpc_desc.ctrl1 */
+#define TX4939_VPC_DESC_CTRL1_ERR_MASK 0x00000006
+#define TX4939_VPC_DESC_CTRL1_OWN 0x00000001
+
+#define tx4939_ddrcptr ((struct tx4939_ddrc_reg __iomem *)TX4939_DDRC_REG)
+#define tx4939_ebuscptr tx4938_ebuscptr
+#define tx4939_ircptr \
+ ((struct tx4939_irc_reg __iomem *)TX4939_IRC_REG)
+#define tx4939_pcicptr tx4938_pcicptr
+#define tx4939_pcic1ptr tx4938_pcic1ptr
+#define tx4939_ccfgptr \
+ ((struct tx4939_ccfg_reg __iomem *)TX4939_CCFG_REG)
+#define tx4939_sramcptr tx4938_sramcptr
+#define tx4939_rtcptr \
+ ((struct tx4939_rtc_reg __iomem *)TX4939_RTC_REG)
+#define tx4939_cryptoptr \
+ ((struct tx4939_crypto_reg __iomem *)TX4939_CRYPTO_REG)
+#define tx4939_vpcptr ((struct tx4939_vpc_reg __iomem *)TX4939_VPC_REG)
+
+#define TX4939_REV_MAJ_MIN() \
+ ((__u32)__raw_readq(&tx4939_ccfgptr->crir) & 0x00ff)
+#define TX4939_REV_PCODE() \
+ ((__u32)__raw_readq(&tx4939_ccfgptr->crir) >> 16)
+#define TX4939_CCFG_BCFG() \
+ ((__u32)((__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_BCFG_MASK) \
+ >> 32))
+
+#define tx4939_ccfg_clear(bits) tx4938_ccfg_clear(bits)
+#define tx4939_ccfg_set(bits) tx4938_ccfg_set(bits)
+#define tx4939_ccfg_change(change, new) tx4938_ccfg_change(change, new)
+
+#define TX4939_EBUSC_CR(ch) TX4927_EBUSC_CR(ch)
+#define TX4939_EBUSC_BA(ch) TX4927_EBUSC_BA(ch)
+#define TX4939_EBUSC_SIZE(ch) TX4927_EBUSC_SIZE(ch)
+#define TX4939_EBUSC_WIDTH(ch) \
+ (16 >> ((__u32)(TX4939_EBUSC_CR(ch) >> 20) & 0x1))
+
+/* SCLK0 = MSTCLK * 429/19 * 16/245 / 2 (14.745MHz for MST 20MHz) */
+#define TX4939_SCLK0(mst) \
+ ((((mst) + 245/2) / 245UL * 429 * 16 + 19) / 19 / 2)
+
+void tx4939_wdt_init(void);
+void tx4939_add_memory_regions(void);
+void tx4939_setup(void);
+void tx4939_time_init(unsigned int tmrnr);
+void tx4939_sio_init(unsigned int sclk, unsigned int cts_mask);
+void tx4939_spi_init(int busid);
+void tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1);
+int tx4939_report_pciclk(void);
+void tx4939_report_pci1clk(void);
+struct pci_dev;
+int tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot);
+int tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+void tx4939_setup_pcierr_irq(void);
+void tx4939_irq_init(void);
+int tx4939_irq(void);
+void tx4939_mtd_init(int ch);
+void tx4939_ata_init(void);
+void tx4939_rtc_init(void);
+void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
+ unsigned char ch_mask, unsigned char wide_mask);
+void tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1);
+void tx4939_aclc_init(void);
+void tx4939_sramc_init(void);
+void tx4939_rng_init(void);
+
+#endif /* __ASM_TXX9_TX4939_H */
diff --git a/arch/mips/include/asm/txx9irq.h b/arch/mips/include/asm/txx9irq.h
new file mode 100644
index 00000000..5620879b
--- /dev/null
+++ b/arch/mips/include/asm/txx9irq.h
@@ -0,0 +1,34 @@
+/*
+ * include/asm-mips/txx9irq.h
+ * TX39/TX49 interrupt controller definitions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_TXX9IRQ_H
+#define __ASM_TXX9IRQ_H
+
+#include <irq.h>
+
+#ifdef CONFIG_IRQ_CPU
+#define TXX9_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
+#else
+#ifdef CONFIG_I8259
+#define TXX9_IRQ_BASE (I8259A_IRQ_BASE + 16)
+#else
+#define TXX9_IRQ_BASE 0
+#endif
+#endif
+
+#ifdef CONFIG_CPU_TX39XX
+#define TXx9_MAX_IR 16
+#else
+#define TXx9_MAX_IR 32
+#endif
+
+void txx9_irq_init(unsigned long baseaddr);
+int txx9_irq(void);
+int txx9_irq_set_pri(int irc_irq, int new_pri);
+
+#endif /* __ASM_TXX9IRQ_H */
diff --git a/arch/mips/include/asm/txx9pio.h b/arch/mips/include/asm/txx9pio.h
new file mode 100644
index 00000000..3d6fa9f8
--- /dev/null
+++ b/arch/mips/include/asm/txx9pio.h
@@ -0,0 +1,29 @@
+/*
+ * include/asm-mips/txx9pio.h
+ * TX39/TX49 PIO controller definitions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_TXX9PIO_H
+#define __ASM_TXX9PIO_H
+
+#include <linux/types.h>
+
+struct txx9_pio_reg {
+ __u32 dout;
+ __u32 din;
+ __u32 dir;
+ __u32 od;
+ __u32 flag[2];
+ __u32 pol;
+ __u32 intc;
+ __u32 maskcpu;
+ __u32 maskext;
+};
+
+int txx9_gpio_init(unsigned long baseaddr,
+ unsigned int base, unsigned int num);
+
+#endif /* __ASM_TXX9PIO_H */
diff --git a/arch/mips/include/asm/txx9tmr.h b/arch/mips/include/asm/txx9tmr.h
new file mode 100644
index 00000000..67f70a8f
--- /dev/null
+++ b/arch/mips/include/asm/txx9tmr.h
@@ -0,0 +1,67 @@
+/*
+ * include/asm-mips/txx9tmr.h
+ * TX39/TX49 timer controller definitions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_TXX9TMR_H
+#define __ASM_TXX9TMR_H
+
+#include <linux/types.h>
+
+struct txx9_tmr_reg {
+ u32 tcr;
+ u32 tisr;
+ u32 cpra;
+ u32 cprb;
+ u32 itmr;
+ u32 unused0[3];
+ u32 ccdr;
+ u32 unused1[3];
+ u32 pgmr;
+ u32 unused2[3];
+ u32 wtmr;
+ u32 unused3[43];
+ u32 trr;
+};
+
+/* TMTCR : Timer Control */
+#define TXx9_TMTCR_TCE 0x00000080
+#define TXx9_TMTCR_CCDE 0x00000040
+#define TXx9_TMTCR_CRE 0x00000020
+#define TXx9_TMTCR_ECES 0x00000008
+#define TXx9_TMTCR_CCS 0x00000004
+#define TXx9_TMTCR_TMODE_MASK 0x00000003
+#define TXx9_TMTCR_TMODE_ITVL 0x00000000
+#define TXx9_TMTCR_TMODE_PGEN 0x00000001
+#define TXx9_TMTCR_TMODE_WDOG 0x00000002
+
+/* TMTISR : Timer Int. Status */
+#define TXx9_TMTISR_TPIBS 0x00000004
+#define TXx9_TMTISR_TPIAS 0x00000002
+#define TXx9_TMTISR_TIIS 0x00000001
+
+/* TMITMR : Interval Timer Mode */
+#define TXx9_TMITMR_TIIE 0x00008000
+#define TXx9_TMITMR_TZCE 0x00000001
+
+/* TMWTMR : Watchdog Timer Mode */
+#define TXx9_TMWTMR_TWIE 0x00008000
+#define TXx9_TMWTMR_WDIS 0x00000080
+#define TXx9_TMWTMR_TWC 0x00000001
+
+void txx9_clocksource_init(unsigned long baseaddr,
+ unsigned int imbusclk);
+void txx9_clockevent_init(unsigned long baseaddr, int irq,
+ unsigned int imbusclk);
+void txx9_tmr_init(unsigned long baseaddr);
+
+#ifdef CONFIG_CPU_TX39XX
+#define TXX9_TIMER_BITS 24
+#else
+#define TXX9_TIMER_BITS 32
+#endif
+
+#endif /* __ASM_TXX9TMR_H */
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h
new file mode 100644
index 00000000..533812b6
--- /dev/null
+++ b/arch/mips/include/asm/types.h
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 2008 Wind River Systems,
+ * written by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
+
+/*
+ * We don't use int-l64.h for the kernel anymore but still use it for
+ * userspace to avoid code changes.
+ */
+#if (_MIPS_SZLONG == 64) && !defined(__KERNEL__)
+# include <asm-generic/int-l64.h>
+#else
+# include <asm-generic/int-ll64.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+/*
+ * Don't use phys_t. You've been warned.
+ */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+typedef unsigned long long phys_t;
+#else
+typedef unsigned long phys_t;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TYPES_H */
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
new file mode 100644
index 00000000..653a412c
--- /dev/null
+++ b/arch/mips/include/asm/uaccess.h
@@ -0,0 +1,1146 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
+ */
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/thread_info.h>
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+#ifdef CONFIG_32BIT
+
+#define __UA_LIMIT 0x80000000UL
+
+#define __UA_ADDR ".word"
+#define __UA_LA "la"
+#define __UA_ADDU "addu"
+#define __UA_t0 "$8"
+#define __UA_t1 "$9"
+
+#endif /* CONFIG_32BIT */
+
+#ifdef CONFIG_64BIT
+
+extern u64 __ua_limit;
+
+#define __UA_LIMIT __ua_limit
+
+#define __UA_ADDR ".dword"
+#define __UA_LA "dla"
+#define __UA_ADDU "daddu"
+#define __UA_t0 "$12"
+#define __UA_t1 "$13"
+
+#endif /* CONFIG_64BIT */
+
+/*
+ * USER_DS is a bitmask that has the bits set that may not be set in a valid
+ * userspace address. Note that we limit 32-bit userspace to 0x7fff8000 but
+ * the arithmetic we're doing only works if the limit is a power of two, so
+ * we use 0x80000000 here on 32-bit kernels. If a process passes an invalid
+ * address in this range it's the process's problem, not ours :-)
+ */
+
+#define KERNEL_DS ((mm_segment_t) { 0UL })
+#define USER_DS ((mm_segment_t) { __UA_LIMIT })
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+#define get_ds() (KERNEL_DS)
+#define get_fs() (current_thread_info()->addr_limit)
+#define set_fs(x) (current_thread_info()->addr_limit = (x))
+
+#define segment_eq(a, b) ((a).seg == (b).seg)
+
+
+/*
+ * Is a address valid? This does a straighforward calculation rather
+ * than tests.
+ *
+ * Address valid if:
+ * - "addr" doesn't have any high-bits set
+ * - AND "size" doesn't have any high-bits set
+ * - AND "addr+size" doesn't have any high-bits set
+ * - OR we are in kernel mode.
+ *
+ * __ua_size() is a trick to avoid runtime checking of positive constant
+ * sizes; for those we already know at compile time that the size is ok.
+ */
+#define __ua_size(size) \
+ ((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
+
+/*
+ * access_ok: - Checks if a user space pointer is valid
+ * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that
+ * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
+ * to write to a block, it is always safe to read from it.
+ * @addr: User space pointer to start of block to check
+ * @size: Size of block to check
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Checks if a pointer to a block of memory in user space is valid.
+ *
+ * Returns true (nonzero) if the memory block may be valid, false (zero)
+ * if it is definitely invalid.
+ *
+ * Note that, depending on architecture, this function probably just
+ * checks that the pointer is in the user space range - after calling
+ * this function, memory access functions may still return -EFAULT.
+ */
+
+#define __access_mask get_fs().seg
+
+#define __access_ok(addr, size, mask) \
+({ \
+ unsigned long __addr = (unsigned long) (addr); \
+ unsigned long __size = size; \
+ unsigned long __mask = mask; \
+ unsigned long __ok; \
+ \
+ __chk_user_ptr(addr); \
+ __ok = (signed long)(__mask & (__addr | (__addr + __size) | \
+ __ua_size(__size))); \
+ __ok == 0; \
+})
+
+#define access_ok(type, addr, size) \
+ likely(__access_ok((addr), (size), __access_mask))
+
+/*
+ * put_user: - Write a simple value into user space.
+ * @x: Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define put_user(x,ptr) \
+ __put_user_check((x), (ptr), sizeof(*(ptr)))
+
+/*
+ * get_user: - Get a simple variable from user space.
+ * @x: Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define get_user(x,ptr) \
+ __get_user_check((x), (ptr), sizeof(*(ptr)))
+
+/*
+ * __put_user: - Write a simple value into user space, with less checking.
+ * @x: Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define __put_user(x,ptr) \
+ __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
+/*
+ * __get_user: - Get a simple variable from user space, with less checking.
+ * @x: Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define __get_user(x,ptr) \
+ __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct __user *)(x))
+
+/*
+ * Yuck. We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#ifdef CONFIG_32BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm_ll32(val, ptr)
+#endif
+#ifdef CONFIG_64BIT
+#define __GET_USER_DW(val, ptr) __get_user_asm(val, "ld", ptr)
+#endif
+
+extern void __get_user_unknown(void);
+
+#define __get_user_common(val, size, ptr) \
+do { \
+ switch (size) { \
+ case 1: __get_user_asm(val, "lb", ptr); break; \
+ case 2: __get_user_asm(val, "lh", ptr); break; \
+ case 4: __get_user_asm(val, "lw", ptr); break; \
+ case 8: __GET_USER_DW(val, ptr); break; \
+ default: __get_user_unknown(); break; \
+ } \
+} while (0)
+
+#define __get_user_nocheck(x, ptr, size) \
+({ \
+ int __gu_err; \
+ \
+ __chk_user_ptr(ptr); \
+ __get_user_common((x), size, ptr); \
+ __gu_err; \
+})
+
+#define __get_user_check(x, ptr, size) \
+({ \
+ int __gu_err = -EFAULT; \
+ const __typeof__(*(ptr)) __user * __gu_ptr = (ptr); \
+ \
+ might_fault(); \
+ if (likely(access_ok(VERIFY_READ, __gu_ptr, size))) \
+ __get_user_common((x), size, __gu_ptr); \
+ \
+ __gu_err; \
+})
+
+#define __get_user_asm(val, insn, addr) \
+{ \
+ long __gu_tmp; \
+ \
+ __asm__ __volatile__( \
+ "1: " insn " %1, %3 \n" \
+ "2: \n" \
+ " .section .fixup,\"ax\" \n" \
+ "3: li %0, %4 \n" \
+ " j 2b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " "__UA_ADDR "\t1b, 3b \n" \
+ " .previous \n" \
+ : "=r" (__gu_err), "=r" (__gu_tmp) \
+ : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \
+ \
+ (val) = (__typeof__(*(addr))) __gu_tmp; \
+}
+
+/*
+ * Get a long long 64 using 32 bit registers.
+ */
+#define __get_user_asm_ll32(val, addr) \
+{ \
+ union { \
+ unsigned long long l; \
+ __typeof__(*(addr)) t; \
+ } __gu_tmp; \
+ \
+ __asm__ __volatile__( \
+ "1: lw %1, (%3) \n" \
+ "2: lw %D1, 4(%3) \n" \
+ "3: .section .fixup,\"ax\" \n" \
+ "4: li %0, %4 \n" \
+ " move %1, $0 \n" \
+ " move %D1, $0 \n" \
+ " j 3b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " " __UA_ADDR " 1b, 4b \n" \
+ " " __UA_ADDR " 2b, 4b \n" \
+ " .previous \n" \
+ : "=r" (__gu_err), "=&r" (__gu_tmp.l) \
+ : "0" (0), "r" (addr), "i" (-EFAULT)); \
+ \
+ (val) = __gu_tmp.t; \
+}
+
+/*
+ * Yuck. We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#ifdef CONFIG_32BIT
+#define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr)
+#endif
+#ifdef CONFIG_64BIT
+#define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr)
+#endif
+
+#define __put_user_nocheck(x, ptr, size) \
+({ \
+ __typeof__(*(ptr)) __pu_val; \
+ int __pu_err = 0; \
+ \
+ __chk_user_ptr(ptr); \
+ __pu_val = (x); \
+ switch (size) { \
+ case 1: __put_user_asm("sb", ptr); break; \
+ case 2: __put_user_asm("sh", ptr); break; \
+ case 4: __put_user_asm("sw", ptr); break; \
+ case 8: __PUT_USER_DW(ptr); break; \
+ default: __put_user_unknown(); break; \
+ } \
+ __pu_err; \
+})
+
+#define __put_user_check(x, ptr, size) \
+({ \
+ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
+ __typeof__(*(ptr)) __pu_val = (x); \
+ int __pu_err = -EFAULT; \
+ \
+ might_fault(); \
+ if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) { \
+ switch (size) { \
+ case 1: __put_user_asm("sb", __pu_addr); break; \
+ case 2: __put_user_asm("sh", __pu_addr); break; \
+ case 4: __put_user_asm("sw", __pu_addr); break; \
+ case 8: __PUT_USER_DW(__pu_addr); break; \
+ default: __put_user_unknown(); break; \
+ } \
+ } \
+ __pu_err; \
+})
+
+#define __put_user_asm(insn, ptr) \
+{ \
+ __asm__ __volatile__( \
+ "1: " insn " %z2, %3 # __put_user_asm\n" \
+ "2: \n" \
+ " .section .fixup,\"ax\" \n" \
+ "3: li %0, %4 \n" \
+ " j 2b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " " __UA_ADDR " 1b, 3b \n" \
+ " .previous \n" \
+ : "=r" (__pu_err) \
+ : "0" (0), "Jr" (__pu_val), "o" (__m(ptr)), \
+ "i" (-EFAULT)); \
+}
+
+#define __put_user_asm_ll32(ptr) \
+{ \
+ __asm__ __volatile__( \
+ "1: sw %2, (%3) # __put_user_asm_ll32 \n" \
+ "2: sw %D2, 4(%3) \n" \
+ "3: \n" \
+ " .section .fixup,\"ax\" \n" \
+ "4: li %0, %4 \n" \
+ " j 3b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " " __UA_ADDR " 1b, 4b \n" \
+ " " __UA_ADDR " 2b, 4b \n" \
+ " .previous" \
+ : "=r" (__pu_err) \
+ : "0" (0), "r" (__pu_val), "r" (ptr), \
+ "i" (-EFAULT)); \
+}
+
+extern void __put_user_unknown(void);
+
+/*
+ * put_user_unaligned: - Write a simple value into user space.
+ * @x: Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define put_user_unaligned(x,ptr) \
+ __put_user_unaligned_check((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * get_user_unaligned: - Get a simple variable from user space.
+ * @x: Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define get_user_unaligned(x,ptr) \
+ __get_user_unaligned_check((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * __put_user_unaligned: - Write a simple value into user space, with less checking.
+ * @x: Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define __put_user_unaligned(x,ptr) \
+ __put_user_unaligned_nocheck((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * __get_user_unaligned: - Get a simple variable from user space, with less checking.
+ * @x: Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define __get_user_unaligned(x,ptr) \
+ __get_user__unalignednocheck((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * Yuck. We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#ifdef CONFIG_32BIT
+#define __GET_USER_UNALIGNED_DW(val, ptr) \
+ __get_user_unaligned_asm_ll32(val, ptr)
+#endif
+#ifdef CONFIG_64BIT
+#define __GET_USER_UNALIGNED_DW(val, ptr) \
+ __get_user_unaligned_asm(val, "uld", ptr)
+#endif
+
+extern void __get_user_unaligned_unknown(void);
+
+#define __get_user_unaligned_common(val, size, ptr) \
+do { \
+ switch (size) { \
+ case 1: __get_user_asm(val, "lb", ptr); break; \
+ case 2: __get_user_unaligned_asm(val, "ulh", ptr); break; \
+ case 4: __get_user_unaligned_asm(val, "ulw", ptr); break; \
+ case 8: __GET_USER_UNALIGNED_DW(val, ptr); break; \
+ default: __get_user_unaligned_unknown(); break; \
+ } \
+} while (0)
+
+#define __get_user_unaligned_nocheck(x,ptr,size) \
+({ \
+ int __gu_err; \
+ \
+ __get_user_unaligned_common((x), size, ptr); \
+ __gu_err; \
+})
+
+#define __get_user_unaligned_check(x,ptr,size) \
+({ \
+ int __gu_err = -EFAULT; \
+ const __typeof__(*(ptr)) __user * __gu_ptr = (ptr); \
+ \
+ if (likely(access_ok(VERIFY_READ, __gu_ptr, size))) \
+ __get_user_unaligned_common((x), size, __gu_ptr); \
+ \
+ __gu_err; \
+})
+
+#define __get_user_unaligned_asm(val, insn, addr) \
+{ \
+ long __gu_tmp; \
+ \
+ __asm__ __volatile__( \
+ "1: " insn " %1, %3 \n" \
+ "2: \n" \
+ " .section .fixup,\"ax\" \n" \
+ "3: li %0, %4 \n" \
+ " j 2b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " "__UA_ADDR "\t1b, 3b \n" \
+ " "__UA_ADDR "\t1b + 4, 3b \n" \
+ " .previous \n" \
+ : "=r" (__gu_err), "=r" (__gu_tmp) \
+ : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \
+ \
+ (val) = (__typeof__(*(addr))) __gu_tmp; \
+}
+
+/*
+ * Get a long long 64 using 32 bit registers.
+ */
+#define __get_user_unaligned_asm_ll32(val, addr) \
+{ \
+ unsigned long long __gu_tmp; \
+ \
+ __asm__ __volatile__( \
+ "1: ulw %1, (%3) \n" \
+ "2: ulw %D1, 4(%3) \n" \
+ " move %0, $0 \n" \
+ "3: .section .fixup,\"ax\" \n" \
+ "4: li %0, %4 \n" \
+ " move %1, $0 \n" \
+ " move %D1, $0 \n" \
+ " j 3b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " " __UA_ADDR " 1b, 4b \n" \
+ " " __UA_ADDR " 1b + 4, 4b \n" \
+ " " __UA_ADDR " 2b, 4b \n" \
+ " " __UA_ADDR " 2b + 4, 4b \n" \
+ " .previous \n" \
+ : "=r" (__gu_err), "=&r" (__gu_tmp) \
+ : "0" (0), "r" (addr), "i" (-EFAULT)); \
+ (val) = (__typeof__(*(addr))) __gu_tmp; \
+}
+
+/*
+ * Yuck. We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#ifdef CONFIG_32BIT
+#define __PUT_USER_UNALIGNED_DW(ptr) __put_user_unaligned_asm_ll32(ptr)
+#endif
+#ifdef CONFIG_64BIT
+#define __PUT_USER_UNALIGNED_DW(ptr) __put_user_unaligned_asm("usd", ptr)
+#endif
+
+#define __put_user_unaligned_nocheck(x,ptr,size) \
+({ \
+ __typeof__(*(ptr)) __pu_val; \
+ int __pu_err = 0; \
+ \
+ __pu_val = (x); \
+ switch (size) { \
+ case 1: __put_user_asm("sb", ptr); break; \
+ case 2: __put_user_unaligned_asm("ush", ptr); break; \
+ case 4: __put_user_unaligned_asm("usw", ptr); break; \
+ case 8: __PUT_USER_UNALIGNED_DW(ptr); break; \
+ default: __put_user_unaligned_unknown(); break; \
+ } \
+ __pu_err; \
+})
+
+#define __put_user_unaligned_check(x,ptr,size) \
+({ \
+ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
+ __typeof__(*(ptr)) __pu_val = (x); \
+ int __pu_err = -EFAULT; \
+ \
+ if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) { \
+ switch (size) { \
+ case 1: __put_user_asm("sb", __pu_addr); break; \
+ case 2: __put_user_unaligned_asm("ush", __pu_addr); break; \
+ case 4: __put_user_unaligned_asm("usw", __pu_addr); break; \
+ case 8: __PUT_USER_UNALGINED_DW(__pu_addr); break; \
+ default: __put_user_unaligned_unknown(); break; \
+ } \
+ } \
+ __pu_err; \
+})
+
+#define __put_user_unaligned_asm(insn, ptr) \
+{ \
+ __asm__ __volatile__( \
+ "1: " insn " %z2, %3 # __put_user_unaligned_asm\n" \
+ "2: \n" \
+ " .section .fixup,\"ax\" \n" \
+ "3: li %0, %4 \n" \
+ " j 2b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " " __UA_ADDR " 1b, 3b \n" \
+ " .previous \n" \
+ : "=r" (__pu_err) \
+ : "0" (0), "Jr" (__pu_val), "o" (__m(ptr)), \
+ "i" (-EFAULT)); \
+}
+
+#define __put_user_unaligned_asm_ll32(ptr) \
+{ \
+ __asm__ __volatile__( \
+ "1: sw %2, (%3) # __put_user_unaligned_asm_ll32 \n" \
+ "2: sw %D2, 4(%3) \n" \
+ "3: \n" \
+ " .section .fixup,\"ax\" \n" \
+ "4: li %0, %4 \n" \
+ " j 3b \n" \
+ " .previous \n" \
+ " .section __ex_table,\"a\" \n" \
+ " " __UA_ADDR " 1b, 4b \n" \
+ " " __UA_ADDR " 1b + 4, 4b \n" \
+ " " __UA_ADDR " 2b, 4b \n" \
+ " " __UA_ADDR " 2b + 4, 4b \n" \
+ " .previous" \
+ : "=r" (__pu_err) \
+ : "0" (0), "r" (__pu_val), "r" (ptr), \
+ "i" (-EFAULT)); \
+}
+
+extern void __put_user_unaligned_unknown(void);
+
+/*
+ * We're generating jump to subroutines which will be outside the range of
+ * jump instructions
+ */
+#ifdef MODULE
+#define __MODULE_JAL(destination) \
+ ".set\tnoat\n\t" \
+ __UA_LA "\t$1, " #destination "\n\t" \
+ "jalr\t$1\n\t" \
+ ".set\tat\n\t"
+#else
+#define __MODULE_JAL(destination) \
+ "jal\t" #destination "\n\t"
+#endif
+
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+#define DADDI_SCRATCH "$0"
+#else
+#define DADDI_SCRATCH "$3"
+#endif
+
+extern size_t __copy_user(void *__to, const void *__from, size_t __n);
+
+#define __invoke_copy_to_user(to, from, n) \
+({ \
+ register void __user *__cu_to_r __asm__("$4"); \
+ register const void *__cu_from_r __asm__("$5"); \
+ register long __cu_len_r __asm__("$6"); \
+ \
+ __cu_to_r = (to); \
+ __cu_from_r = (from); \
+ __cu_len_r = (n); \
+ __asm__ __volatile__( \
+ __MODULE_JAL(__copy_user) \
+ : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
+ : \
+ : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
+ DADDI_SCRATCH, "memory"); \
+ __cu_len_r; \
+})
+
+/*
+ * __copy_to_user: - Copy a block of data into user space, with less checking.
+ * @to: Destination address, in user space.
+ * @from: Source address, in kernel space.
+ * @n: Number of bytes to copy.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Copy data from kernel space to user space. Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+#define __copy_to_user(to, from, n) \
+({ \
+ void __user *__cu_to; \
+ const void *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ might_fault(); \
+ __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len); \
+ __cu_len; \
+})
+
+extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
+
+#define __copy_to_user_inatomic(to, from, n) \
+({ \
+ void __user *__cu_to; \
+ const void *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len); \
+ __cu_len; \
+})
+
+#define __copy_from_user_inatomic(to, from, n) \
+({ \
+ void *__cu_to; \
+ const void __user *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ __cu_len = __invoke_copy_from_user_inatomic(__cu_to, __cu_from, \
+ __cu_len); \
+ __cu_len; \
+})
+
+/*
+ * copy_to_user: - Copy a block of data into user space.
+ * @to: Destination address, in user space.
+ * @from: Source address, in kernel space.
+ * @n: Number of bytes to copy.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Copy data from kernel space to user space.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+#define copy_to_user(to, from, n) \
+({ \
+ void __user *__cu_to; \
+ const void *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) { \
+ might_fault(); \
+ __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, \
+ __cu_len); \
+ } \
+ __cu_len; \
+})
+
+#define __invoke_copy_from_user(to, from, n) \
+({ \
+ register void *__cu_to_r __asm__("$4"); \
+ register const void __user *__cu_from_r __asm__("$5"); \
+ register long __cu_len_r __asm__("$6"); \
+ \
+ __cu_to_r = (to); \
+ __cu_from_r = (from); \
+ __cu_len_r = (n); \
+ __asm__ __volatile__( \
+ ".set\tnoreorder\n\t" \
+ __MODULE_JAL(__copy_user) \
+ ".set\tnoat\n\t" \
+ __UA_ADDU "\t$1, %1, %2\n\t" \
+ ".set\tat\n\t" \
+ ".set\treorder" \
+ : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
+ : \
+ : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
+ DADDI_SCRATCH, "memory"); \
+ __cu_len_r; \
+})
+
+#define __invoke_copy_from_user_inatomic(to, from, n) \
+({ \
+ register void *__cu_to_r __asm__("$4"); \
+ register const void __user *__cu_from_r __asm__("$5"); \
+ register long __cu_len_r __asm__("$6"); \
+ \
+ __cu_to_r = (to); \
+ __cu_from_r = (from); \
+ __cu_len_r = (n); \
+ __asm__ __volatile__( \
+ ".set\tnoreorder\n\t" \
+ __MODULE_JAL(__copy_user_inatomic) \
+ ".set\tnoat\n\t" \
+ __UA_ADDU "\t$1, %1, %2\n\t" \
+ ".set\tat\n\t" \
+ ".set\treorder" \
+ : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
+ : \
+ : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
+ DADDI_SCRATCH, "memory"); \
+ __cu_len_r; \
+})
+
+/*
+ * __copy_from_user: - Copy a block of data from user space, with less checking.
+ * @to: Destination address, in kernel space.
+ * @from: Source address, in user space.
+ * @n: Number of bytes to copy.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Copy data from user space to kernel space. Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * If some data could not be copied, this function will pad the copied
+ * data to the requested size using zero bytes.
+ */
+#define __copy_from_user(to, from, n) \
+({ \
+ void *__cu_to; \
+ const void __user *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ might_fault(); \
+ __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \
+ __cu_len); \
+ __cu_len; \
+})
+
+/*
+ * copy_from_user: - Copy a block of data from user space.
+ * @to: Destination address, in kernel space.
+ * @from: Source address, in user space.
+ * @n: Number of bytes to copy.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Copy data from user space to kernel space.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * If some data could not be copied, this function will pad the copied
+ * data to the requested size using zero bytes.
+ */
+#define copy_from_user(to, from, n) \
+({ \
+ void *__cu_to; \
+ const void __user *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ if (access_ok(VERIFY_READ, __cu_from, __cu_len)) { \
+ might_fault(); \
+ __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \
+ __cu_len); \
+ } \
+ __cu_len; \
+})
+
+#define __copy_in_user(to, from, n) \
+({ \
+ void __user *__cu_to; \
+ const void __user *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ might_fault(); \
+ __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \
+ __cu_len); \
+ __cu_len; \
+})
+
+#define copy_in_user(to, from, n) \
+({ \
+ void __user *__cu_to; \
+ const void __user *__cu_from; \
+ long __cu_len; \
+ \
+ __cu_to = (to); \
+ __cu_from = (from); \
+ __cu_len = (n); \
+ if (likely(access_ok(VERIFY_READ, __cu_from, __cu_len) && \
+ access_ok(VERIFY_WRITE, __cu_to, __cu_len))) { \
+ might_fault(); \
+ __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \
+ __cu_len); \
+ } \
+ __cu_len; \
+})
+
+/*
+ * __clear_user: - Zero a block of memory in user space, with less checking.
+ * @to: Destination address, in user space.
+ * @n: Number of bytes to zero.
+ *
+ * Zero a block of memory in user space. Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */
+static inline __kernel_size_t
+__clear_user(void __user *addr, __kernel_size_t size)
+{
+ __kernel_size_t res;
+
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, $0\n\t"
+ "move\t$6, %2\n\t"
+ __MODULE_JAL(__bzero)
+ "move\t%0, $6"
+ : "=r" (res)
+ : "r" (addr), "r" (size)
+ : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+
+ return res;
+}
+
+#define clear_user(addr,n) \
+({ \
+ void __user * __cl_addr = (addr); \
+ unsigned long __cl_size = (n); \
+ if (__cl_size && access_ok(VERIFY_WRITE, \
+ __cl_addr, __cl_size)) \
+ __cl_size = __clear_user(__cl_addr, __cl_size); \
+ __cl_size; \
+})
+
+/*
+ * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
+ * @dst: Destination address, in kernel space. This buffer must be at
+ * least @count bytes long.
+ * @src: Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ *
+ * Copies a NUL-terminated string from userspace to kernel space.
+ * Caller must check the specified block with access_ok() before calling
+ * this function.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
+static inline long
+__strncpy_from_user(char *__to, const char __user *__from, long __len)
+{
+ long res;
+
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, %2\n\t"
+ "move\t$6, %3\n\t"
+ __MODULE_JAL(__strncpy_from_user_nocheck_asm)
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (__to), "r" (__from), "r" (__len)
+ : "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
+
+ return res;
+}
+
+/*
+ * strncpy_from_user: - Copy a NUL terminated string from userspace.
+ * @dst: Destination address, in kernel space. This buffer must be at
+ * least @count bytes long.
+ * @src: Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ *
+ * Copies a NUL-terminated string from userspace to kernel space.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
+static inline long
+strncpy_from_user(char *__to, const char __user *__from, long __len)
+{
+ long res;
+
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, %2\n\t"
+ "move\t$6, %3\n\t"
+ __MODULE_JAL(__strncpy_from_user_asm)
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (__to), "r" (__from), "r" (__len)
+ : "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
+
+ return res;
+}
+
+/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+static inline long __strlen_user(const char __user *s)
+{
+ long res;
+
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ __MODULE_JAL(__strlen_user_nocheck_asm)
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (s)
+ : "$2", "$4", __UA_t0, "$31");
+
+ return res;
+}
+
+/*
+ * strlen_user: - Get the size of a string in user space.
+ * @str: The string to measure.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Get the size of a NUL-terminated string in user space.
+ *
+ * Returns the size of the string INCLUDING the terminating NUL.
+ * On exception, returns 0.
+ *
+ * If there is a limit on the length of a valid string, you may wish to
+ * consider using strnlen_user() instead.
+ */
+static inline long strlen_user(const char __user *s)
+{
+ long res;
+
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ __MODULE_JAL(__strlen_user_asm)
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (s)
+ : "$2", "$4", __UA_t0, "$31");
+
+ return res;
+}
+
+/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+static inline long __strnlen_user(const char __user *s, long n)
+{
+ long res;
+
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, %2\n\t"
+ __MODULE_JAL(__strnlen_user_nocheck_asm)
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (s), "r" (n)
+ : "$2", "$4", "$5", __UA_t0, "$31");
+
+ return res;
+}
+
+/*
+ * strlen_user: - Get the size of a string in user space.
+ * @str: The string to measure.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Get the size of a NUL-terminated string in user space.
+ *
+ * Returns the size of the string INCLUDING the terminating NUL.
+ * On exception, returns 0.
+ *
+ * If there is a limit on the length of a valid string, you may wish to
+ * consider using strnlen_user() instead.
+ */
+static inline long strnlen_user(const char __user *s, long n)
+{
+ long res;
+
+ might_fault();
+ __asm__ __volatile__(
+ "move\t$4, %1\n\t"
+ "move\t$5, %2\n\t"
+ __MODULE_JAL(__strnlen_user_asm)
+ "move\t%0, $2"
+ : "=r" (res)
+ : "r" (s), "r" (n)
+ : "$2", "$4", "$5", __UA_t0, "$31");
+
+ return res;
+}
+
+struct exception_table_entry
+{
+ unsigned long insn;
+ unsigned long nextinsn;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+#endif /* _ASM_UACCESS_H */
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
new file mode 100644
index 00000000..dcbd4bb4
--- /dev/null
+++ b/arch/mips/include/asm/uasm.h
@@ -0,0 +1,247 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
+ * Copyright (C) 2005 Maciej W. Rozycki
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <linux/types.h>
+
+#ifdef CONFIG_EXPORT_UASM
+#include <linux/module.h>
+#define __uasminit
+#define __uasminitdata
+#define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym)
+#else
+#define __uasminit __cpuinit
+#define __uasminitdata __cpuinitdata
+#define UASM_EXPORT_SYMBOL(sym)
+#endif
+
+#define Ip_u1u2u3(op) \
+void __uasminit \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u2u1u3(op) \
+void __uasminit \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u3u1u2(op) \
+void __uasminit \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c)
+
+#define Ip_u1u2s3(op) \
+void __uasminit \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
+#define Ip_u2s3u1(op) \
+void __uasminit \
+uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c)
+
+#define Ip_u2u1s3(op) \
+void __uasminit \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c)
+
+#define Ip_u2u1msbu3(op) \
+void __uasminit \
+uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c, \
+ unsigned int d)
+
+#define Ip_u1u2(op) \
+void __uasminit uasm_i##op(u32 **buf, unsigned int a, unsigned int b)
+
+#define Ip_u1s2(op) \
+void __uasminit uasm_i##op(u32 **buf, unsigned int a, signed int b)
+
+#define Ip_u1(op) void __uasminit uasm_i##op(u32 **buf, unsigned int a)
+
+#define Ip_0(op) void __uasminit uasm_i##op(u32 **buf)
+
+Ip_u2u1s3(_addiu);
+Ip_u3u1u2(_addu);
+Ip_u2u1u3(_andi);
+Ip_u3u1u2(_and);
+Ip_u1u2s3(_beq);
+Ip_u1u2s3(_beql);
+Ip_u1s2(_bgez);
+Ip_u1s2(_bgezl);
+Ip_u1s2(_bltz);
+Ip_u1s2(_bltzl);
+Ip_u1u2s3(_bne);
+Ip_u2s3u1(_cache);
+Ip_u1u2u3(_dmfc0);
+Ip_u1u2u3(_dmtc0);
+Ip_u2u1s3(_daddiu);
+Ip_u3u1u2(_daddu);
+Ip_u2u1u3(_dsll);
+Ip_u2u1u3(_dsll32);
+Ip_u2u1u3(_dsra);
+Ip_u2u1u3(_dsrl);
+Ip_u2u1u3(_dsrl32);
+Ip_u2u1u3(_drotr);
+Ip_u2u1u3(_drotr32);
+Ip_u3u1u2(_dsubu);
+Ip_0(_eret);
+Ip_u1(_j);
+Ip_u1(_jal);
+Ip_u1(_jr);
+Ip_u2s3u1(_ld);
+Ip_u2s3u1(_ll);
+Ip_u2s3u1(_lld);
+Ip_u1s2(_lui);
+Ip_u2s3u1(_lw);
+Ip_u1u2u3(_mfc0);
+Ip_u1u2u3(_mtc0);
+Ip_u2u1u3(_ori);
+Ip_u3u1u2(_or);
+Ip_u2s3u1(_pref);
+Ip_0(_rfe);
+Ip_u2s3u1(_sc);
+Ip_u2s3u1(_scd);
+Ip_u2s3u1(_sd);
+Ip_u2u1u3(_sll);
+Ip_u2u1u3(_sra);
+Ip_u2u1u3(_srl);
+Ip_u2u1u3(_rotr);
+Ip_u3u1u2(_subu);
+Ip_u2s3u1(_sw);
+Ip_0(_tlbp);
+Ip_0(_tlbr);
+Ip_0(_tlbwi);
+Ip_0(_tlbwr);
+Ip_u3u1u2(_xor);
+Ip_u2u1u3(_xori);
+Ip_u2u1msbu3(_dins);
+Ip_u2u1msbu3(_dinsm);
+Ip_u1(_syscall);
+Ip_u1u2s3(_bbit0);
+Ip_u1u2s3(_bbit1);
+Ip_u3u1u2(_lwx);
+Ip_u3u1u2(_ldx);
+
+/* Handle labels. */
+struct uasm_label {
+ u32 *addr;
+ int lab;
+};
+
+void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid);
+#ifdef CONFIG_64BIT
+int uasm_in_compat_space_p(long addr);
+#endif
+int uasm_rel_hi(long val);
+int uasm_rel_lo(long val);
+void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr);
+void UASM_i_LA(u32 **buf, unsigned int rs, long addr);
+
+#define UASM_L_LA(lb) \
+static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
+{ \
+ uasm_build_label(lab, addr, label##lb); \
+}
+
+/* convenience macros for instructions */
+#ifdef CONFIG_64BIT
+# define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off)
+# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh)
+# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh)
+# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh)
+# define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_drotr(buf, rs, rt, sh)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd)
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd)
+# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
+# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_ldx(buf, rs, rt, rd)
+#else
+# define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
+# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh)
+# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh)
+# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh)
+# define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_rotr(buf, rs, rt, sh)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd)
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd)
+# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
+# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_lwx(buf, rs, rt, rd)
+#endif
+
+#define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off)
+#define uasm_i_beqz(buf, rs, off) uasm_i_beq(buf, rs, 0, off)
+#define uasm_i_beqzl(buf, rs, off) uasm_i_beql(buf, rs, 0, off)
+#define uasm_i_bnez(buf, rs, off) uasm_i_bne(buf, rs, 0, off)
+#define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off)
+#define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b)
+#define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0)
+#define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
+#define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
+
+static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
+ unsigned int a2, unsigned int a3)
+{
+ if (a3 < 32)
+ uasm_i_dsrl(p, a1, a2, a3);
+ else
+ uasm_i_dsrl32(p, a1, a2, a3 - 32);
+}
+
+static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1,
+ unsigned int a2, unsigned int a3)
+{
+ if (a3 < 32)
+ uasm_i_drotr(p, a1, a2, a3);
+ else
+ uasm_i_drotr32(p, a1, a2, a3 - 32);
+}
+
+static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
+ unsigned int a2, unsigned int a3)
+{
+ if (a3 < 32)
+ uasm_i_dsll(p, a1, a2, a3);
+ else
+ uasm_i_dsll32(p, a1, a2, a3 - 32);
+}
+
+/* Handle relocations. */
+struct uasm_reloc {
+ u32 *addr;
+ unsigned int type;
+ int lab;
+};
+
+/* This is zero so we can use zeroed label arrays. */
+#define UASM_LABEL_INVALID 0
+
+void uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid);
+void uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab);
+void uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off);
+void uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off);
+void uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab,
+ u32 *first, u32 *end, u32 *target);
+int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr);
+
+/* Convenience functions for labeled branches. */
+void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid);
+void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
+ unsigned int reg2, int lid);
+void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg,
+ unsigned int bit, int lid);
+void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
+ unsigned int bit, int lid);
diff --git a/arch/mips/include/asm/ucontext.h b/arch/mips/include/asm/ucontext.h
new file mode 100644
index 00000000..9bc07b9f
--- /dev/null
+++ b/arch/mips/include/asm/ucontext.h
@@ -0,0 +1 @@
+#include <asm-generic/ucontext.h>
diff --git a/arch/mips/include/asm/unaligned.h b/arch/mips/include/asm/unaligned.h
new file mode 100644
index 00000000..42f66c31
--- /dev/null
+++ b/arch/mips/include/asm/unaligned.h
@@ -0,0 +1,28 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ */
+#ifndef _ASM_MIPS_UNALIGNED_H
+#define _ASM_MIPS_UNALIGNED_H
+
+#include <linux/compiler.h>
+#if defined(__MIPSEB__)
+# include <linux/unaligned/be_struct.h>
+# include <linux/unaligned/le_byteshift.h>
+# define get_unaligned __get_unaligned_be
+# define put_unaligned __put_unaligned_be
+#elif defined(__MIPSEL__)
+# include <linux/unaligned/le_struct.h>
+# include <linux/unaligned/be_byteshift.h>
+# define get_unaligned __get_unaligned_le
+# define put_unaligned __put_unaligned_le
+#else
+# error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???"
+#endif
+
+# include <linux/unaligned/generic.h>
+
+#endif /* _ASM_MIPS_UNALIGNED_H */
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
new file mode 100644
index 00000000..6fcfc480
--- /dev/null
+++ b/arch/mips/include/asm/unistd.h
@@ -0,0 +1,1082 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto
+ * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A
+ */
+#ifndef _ASM_UNISTD_H
+#define _ASM_UNISTD_H
+
+#include <asm/sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+
+/*
+ * Linux o32 style syscalls are in the range from 4000 to 4999.
+ */
+#define __NR_Linux 4000
+#define __NR_syscall (__NR_Linux + 0)
+#define __NR_exit (__NR_Linux + 1)
+#define __NR_fork (__NR_Linux + 2)
+#define __NR_read (__NR_Linux + 3)
+#define __NR_write (__NR_Linux + 4)
+#define __NR_open (__NR_Linux + 5)
+#define __NR_close (__NR_Linux + 6)
+#define __NR_waitpid (__NR_Linux + 7)
+#define __NR_creat (__NR_Linux + 8)
+#define __NR_link (__NR_Linux + 9)
+#define __NR_unlink (__NR_Linux + 10)
+#define __NR_execve (__NR_Linux + 11)
+#define __NR_chdir (__NR_Linux + 12)
+#define __NR_time (__NR_Linux + 13)
+#define __NR_mknod (__NR_Linux + 14)
+#define __NR_chmod (__NR_Linux + 15)
+#define __NR_lchown (__NR_Linux + 16)
+#define __NR_break (__NR_Linux + 17)
+#define __NR_unused18 (__NR_Linux + 18)
+#define __NR_lseek (__NR_Linux + 19)
+#define __NR_getpid (__NR_Linux + 20)
+#define __NR_mount (__NR_Linux + 21)
+#define __NR_umount (__NR_Linux + 22)
+#define __NR_setuid (__NR_Linux + 23)
+#define __NR_getuid (__NR_Linux + 24)
+#define __NR_stime (__NR_Linux + 25)
+#define __NR_ptrace (__NR_Linux + 26)
+#define __NR_alarm (__NR_Linux + 27)
+#define __NR_unused28 (__NR_Linux + 28)
+#define __NR_pause (__NR_Linux + 29)
+#define __NR_utime (__NR_Linux + 30)
+#define __NR_stty (__NR_Linux + 31)
+#define __NR_gtty (__NR_Linux + 32)
+#define __NR_access (__NR_Linux + 33)
+#define __NR_nice (__NR_Linux + 34)
+#define __NR_ftime (__NR_Linux + 35)
+#define __NR_sync (__NR_Linux + 36)
+#define __NR_kill (__NR_Linux + 37)
+#define __NR_rename (__NR_Linux + 38)
+#define __NR_mkdir (__NR_Linux + 39)
+#define __NR_rmdir (__NR_Linux + 40)
+#define __NR_dup (__NR_Linux + 41)
+#define __NR_pipe (__NR_Linux + 42)
+#define __NR_times (__NR_Linux + 43)
+#define __NR_prof (__NR_Linux + 44)
+#define __NR_brk (__NR_Linux + 45)
+#define __NR_setgid (__NR_Linux + 46)
+#define __NR_getgid (__NR_Linux + 47)
+#define __NR_signal (__NR_Linux + 48)
+#define __NR_geteuid (__NR_Linux + 49)
+#define __NR_getegid (__NR_Linux + 50)
+#define __NR_acct (__NR_Linux + 51)
+#define __NR_umount2 (__NR_Linux + 52)
+#define __NR_lock (__NR_Linux + 53)
+#define __NR_ioctl (__NR_Linux + 54)
+#define __NR_fcntl (__NR_Linux + 55)
+#define __NR_mpx (__NR_Linux + 56)
+#define __NR_setpgid (__NR_Linux + 57)
+#define __NR_ulimit (__NR_Linux + 58)
+#define __NR_unused59 (__NR_Linux + 59)
+#define __NR_umask (__NR_Linux + 60)
+#define __NR_chroot (__NR_Linux + 61)
+#define __NR_ustat (__NR_Linux + 62)
+#define __NR_dup2 (__NR_Linux + 63)
+#define __NR_getppid (__NR_Linux + 64)
+#define __NR_getpgrp (__NR_Linux + 65)
+#define __NR_setsid (__NR_Linux + 66)
+#define __NR_sigaction (__NR_Linux + 67)
+#define __NR_sgetmask (__NR_Linux + 68)
+#define __NR_ssetmask (__NR_Linux + 69)
+#define __NR_setreuid (__NR_Linux + 70)
+#define __NR_setregid (__NR_Linux + 71)
+#define __NR_sigsuspend (__NR_Linux + 72)
+#define __NR_sigpending (__NR_Linux + 73)
+#define __NR_sethostname (__NR_Linux + 74)
+#define __NR_setrlimit (__NR_Linux + 75)
+#define __NR_getrlimit (__NR_Linux + 76)
+#define __NR_getrusage (__NR_Linux + 77)
+#define __NR_gettimeofday (__NR_Linux + 78)
+#define __NR_settimeofday (__NR_Linux + 79)
+#define __NR_getgroups (__NR_Linux + 80)
+#define __NR_setgroups (__NR_Linux + 81)
+#define __NR_reserved82 (__NR_Linux + 82)
+#define __NR_symlink (__NR_Linux + 83)
+#define __NR_unused84 (__NR_Linux + 84)
+#define __NR_readlink (__NR_Linux + 85)
+#define __NR_uselib (__NR_Linux + 86)
+#define __NR_swapon (__NR_Linux + 87)
+#define __NR_reboot (__NR_Linux + 88)
+#define __NR_readdir (__NR_Linux + 89)
+#define __NR_mmap (__NR_Linux + 90)
+#define __NR_munmap (__NR_Linux + 91)
+#define __NR_truncate (__NR_Linux + 92)
+#define __NR_ftruncate (__NR_Linux + 93)
+#define __NR_fchmod (__NR_Linux + 94)
+#define __NR_fchown (__NR_Linux + 95)
+#define __NR_getpriority (__NR_Linux + 96)
+#define __NR_setpriority (__NR_Linux + 97)
+#define __NR_profil (__NR_Linux + 98)
+#define __NR_statfs (__NR_Linux + 99)
+#define __NR_fstatfs (__NR_Linux + 100)
+#define __NR_ioperm (__NR_Linux + 101)
+#define __NR_socketcall (__NR_Linux + 102)
+#define __NR_syslog (__NR_Linux + 103)
+#define __NR_setitimer (__NR_Linux + 104)
+#define __NR_getitimer (__NR_Linux + 105)
+#define __NR_stat (__NR_Linux + 106)
+#define __NR_lstat (__NR_Linux + 107)
+#define __NR_fstat (__NR_Linux + 108)
+#define __NR_unused109 (__NR_Linux + 109)
+#define __NR_iopl (__NR_Linux + 110)
+#define __NR_vhangup (__NR_Linux + 111)
+#define __NR_idle (__NR_Linux + 112)
+#define __NR_vm86 (__NR_Linux + 113)
+#define __NR_wait4 (__NR_Linux + 114)
+#define __NR_swapoff (__NR_Linux + 115)
+#define __NR_sysinfo (__NR_Linux + 116)
+#define __NR_ipc (__NR_Linux + 117)
+#define __NR_fsync (__NR_Linux + 118)
+#define __NR_sigreturn (__NR_Linux + 119)
+#define __NR_clone (__NR_Linux + 120)
+#define __NR_setdomainname (__NR_Linux + 121)
+#define __NR_uname (__NR_Linux + 122)
+#define __NR_modify_ldt (__NR_Linux + 123)
+#define __NR_adjtimex (__NR_Linux + 124)
+#define __NR_mprotect (__NR_Linux + 125)
+#define __NR_sigprocmask (__NR_Linux + 126)
+#define __NR_create_module (__NR_Linux + 127)
+#define __NR_init_module (__NR_Linux + 128)
+#define __NR_delete_module (__NR_Linux + 129)
+#define __NR_get_kernel_syms (__NR_Linux + 130)
+#define __NR_quotactl (__NR_Linux + 131)
+#define __NR_getpgid (__NR_Linux + 132)
+#define __NR_fchdir (__NR_Linux + 133)
+#define __NR_bdflush (__NR_Linux + 134)
+#define __NR_sysfs (__NR_Linux + 135)
+#define __NR_personality (__NR_Linux + 136)
+#define __NR_afs_syscall (__NR_Linux + 137) /* Syscall for Andrew File System */
+#define __NR_setfsuid (__NR_Linux + 138)
+#define __NR_setfsgid (__NR_Linux + 139)
+#define __NR__llseek (__NR_Linux + 140)
+#define __NR_getdents (__NR_Linux + 141)
+#define __NR__newselect (__NR_Linux + 142)
+#define __NR_flock (__NR_Linux + 143)
+#define __NR_msync (__NR_Linux + 144)
+#define __NR_readv (__NR_Linux + 145)
+#define __NR_writev (__NR_Linux + 146)
+#define __NR_cacheflush (__NR_Linux + 147)
+#define __NR_cachectl (__NR_Linux + 148)
+#define __NR_sysmips (__NR_Linux + 149)
+#define __NR_unused150 (__NR_Linux + 150)
+#define __NR_getsid (__NR_Linux + 151)
+#define __NR_fdatasync (__NR_Linux + 152)
+#define __NR__sysctl (__NR_Linux + 153)
+#define __NR_mlock (__NR_Linux + 154)
+#define __NR_munlock (__NR_Linux + 155)
+#define __NR_mlockall (__NR_Linux + 156)
+#define __NR_munlockall (__NR_Linux + 157)
+#define __NR_sched_setparam (__NR_Linux + 158)
+#define __NR_sched_getparam (__NR_Linux + 159)
+#define __NR_sched_setscheduler (__NR_Linux + 160)
+#define __NR_sched_getscheduler (__NR_Linux + 161)
+#define __NR_sched_yield (__NR_Linux + 162)
+#define __NR_sched_get_priority_max (__NR_Linux + 163)
+#define __NR_sched_get_priority_min (__NR_Linux + 164)
+#define __NR_sched_rr_get_interval (__NR_Linux + 165)
+#define __NR_nanosleep (__NR_Linux + 166)
+#define __NR_mremap (__NR_Linux + 167)
+#define __NR_accept (__NR_Linux + 168)
+#define __NR_bind (__NR_Linux + 169)
+#define __NR_connect (__NR_Linux + 170)
+#define __NR_getpeername (__NR_Linux + 171)
+#define __NR_getsockname (__NR_Linux + 172)
+#define __NR_getsockopt (__NR_Linux + 173)
+#define __NR_listen (__NR_Linux + 174)
+#define __NR_recv (__NR_Linux + 175)
+#define __NR_recvfrom (__NR_Linux + 176)
+#define __NR_recvmsg (__NR_Linux + 177)
+#define __NR_send (__NR_Linux + 178)
+#define __NR_sendmsg (__NR_Linux + 179)
+#define __NR_sendto (__NR_Linux + 180)
+#define __NR_setsockopt (__NR_Linux + 181)
+#define __NR_shutdown (__NR_Linux + 182)
+#define __NR_socket (__NR_Linux + 183)
+#define __NR_socketpair (__NR_Linux + 184)
+#define __NR_setresuid (__NR_Linux + 185)
+#define __NR_getresuid (__NR_Linux + 186)
+#define __NR_query_module (__NR_Linux + 187)
+#define __NR_poll (__NR_Linux + 188)
+#define __NR_nfsservctl (__NR_Linux + 189)
+#define __NR_setresgid (__NR_Linux + 190)
+#define __NR_getresgid (__NR_Linux + 191)
+#define __NR_prctl (__NR_Linux + 192)
+#define __NR_rt_sigreturn (__NR_Linux + 193)
+#define __NR_rt_sigaction (__NR_Linux + 194)
+#define __NR_rt_sigprocmask (__NR_Linux + 195)
+#define __NR_rt_sigpending (__NR_Linux + 196)
+#define __NR_rt_sigtimedwait (__NR_Linux + 197)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 198)
+#define __NR_rt_sigsuspend (__NR_Linux + 199)
+#define __NR_pread64 (__NR_Linux + 200)
+#define __NR_pwrite64 (__NR_Linux + 201)
+#define __NR_chown (__NR_Linux + 202)
+#define __NR_getcwd (__NR_Linux + 203)
+#define __NR_capget (__NR_Linux + 204)
+#define __NR_capset (__NR_Linux + 205)
+#define __NR_sigaltstack (__NR_Linux + 206)
+#define __NR_sendfile (__NR_Linux + 207)
+#define __NR_getpmsg (__NR_Linux + 208)
+#define __NR_putpmsg (__NR_Linux + 209)
+#define __NR_mmap2 (__NR_Linux + 210)
+#define __NR_truncate64 (__NR_Linux + 211)
+#define __NR_ftruncate64 (__NR_Linux + 212)
+#define __NR_stat64 (__NR_Linux + 213)
+#define __NR_lstat64 (__NR_Linux + 214)
+#define __NR_fstat64 (__NR_Linux + 215)
+#define __NR_pivot_root (__NR_Linux + 216)
+#define __NR_mincore (__NR_Linux + 217)
+#define __NR_madvise (__NR_Linux + 218)
+#define __NR_getdents64 (__NR_Linux + 219)
+#define __NR_fcntl64 (__NR_Linux + 220)
+#define __NR_reserved221 (__NR_Linux + 221)
+#define __NR_gettid (__NR_Linux + 222)
+#define __NR_readahead (__NR_Linux + 223)
+#define __NR_setxattr (__NR_Linux + 224)
+#define __NR_lsetxattr (__NR_Linux + 225)
+#define __NR_fsetxattr (__NR_Linux + 226)
+#define __NR_getxattr (__NR_Linux + 227)
+#define __NR_lgetxattr (__NR_Linux + 228)
+#define __NR_fgetxattr (__NR_Linux + 229)
+#define __NR_listxattr (__NR_Linux + 230)
+#define __NR_llistxattr (__NR_Linux + 231)
+#define __NR_flistxattr (__NR_Linux + 232)
+#define __NR_removexattr (__NR_Linux + 233)
+#define __NR_lremovexattr (__NR_Linux + 234)
+#define __NR_fremovexattr (__NR_Linux + 235)
+#define __NR_tkill (__NR_Linux + 236)
+#define __NR_sendfile64 (__NR_Linux + 237)
+#define __NR_futex (__NR_Linux + 238)
+#define __NR_sched_setaffinity (__NR_Linux + 239)
+#define __NR_sched_getaffinity (__NR_Linux + 240)
+#define __NR_io_setup (__NR_Linux + 241)
+#define __NR_io_destroy (__NR_Linux + 242)
+#define __NR_io_getevents (__NR_Linux + 243)
+#define __NR_io_submit (__NR_Linux + 244)
+#define __NR_io_cancel (__NR_Linux + 245)
+#define __NR_exit_group (__NR_Linux + 246)
+#define __NR_lookup_dcookie (__NR_Linux + 247)
+#define __NR_epoll_create (__NR_Linux + 248)
+#define __NR_epoll_ctl (__NR_Linux + 249)
+#define __NR_epoll_wait (__NR_Linux + 250)
+#define __NR_remap_file_pages (__NR_Linux + 251)
+#define __NR_set_tid_address (__NR_Linux + 252)
+#define __NR_restart_syscall (__NR_Linux + 253)
+#define __NR_fadvise64 (__NR_Linux + 254)
+#define __NR_statfs64 (__NR_Linux + 255)
+#define __NR_fstatfs64 (__NR_Linux + 256)
+#define __NR_timer_create (__NR_Linux + 257)
+#define __NR_timer_settime (__NR_Linux + 258)
+#define __NR_timer_gettime (__NR_Linux + 259)
+#define __NR_timer_getoverrun (__NR_Linux + 260)
+#define __NR_timer_delete (__NR_Linux + 261)
+#define __NR_clock_settime (__NR_Linux + 262)
+#define __NR_clock_gettime (__NR_Linux + 263)
+#define __NR_clock_getres (__NR_Linux + 264)
+#define __NR_clock_nanosleep (__NR_Linux + 265)
+#define __NR_tgkill (__NR_Linux + 266)
+#define __NR_utimes (__NR_Linux + 267)
+#define __NR_mbind (__NR_Linux + 268)
+#define __NR_get_mempolicy (__NR_Linux + 269)
+#define __NR_set_mempolicy (__NR_Linux + 270)
+#define __NR_mq_open (__NR_Linux + 271)
+#define __NR_mq_unlink (__NR_Linux + 272)
+#define __NR_mq_timedsend (__NR_Linux + 273)
+#define __NR_mq_timedreceive (__NR_Linux + 274)
+#define __NR_mq_notify (__NR_Linux + 275)
+#define __NR_mq_getsetattr (__NR_Linux + 276)
+#define __NR_vserver (__NR_Linux + 277)
+#define __NR_waitid (__NR_Linux + 278)
+/* #define __NR_sys_setaltroot (__NR_Linux + 279) */
+#define __NR_add_key (__NR_Linux + 280)
+#define __NR_request_key (__NR_Linux + 281)
+#define __NR_keyctl (__NR_Linux + 282)
+#define __NR_set_thread_area (__NR_Linux + 283)
+#define __NR_inotify_init (__NR_Linux + 284)
+#define __NR_inotify_add_watch (__NR_Linux + 285)
+#define __NR_inotify_rm_watch (__NR_Linux + 286)
+#define __NR_migrate_pages (__NR_Linux + 287)
+#define __NR_openat (__NR_Linux + 288)
+#define __NR_mkdirat (__NR_Linux + 289)
+#define __NR_mknodat (__NR_Linux + 290)
+#define __NR_fchownat (__NR_Linux + 291)
+#define __NR_futimesat (__NR_Linux + 292)
+#define __NR_fstatat64 (__NR_Linux + 293)
+#define __NR_unlinkat (__NR_Linux + 294)
+#define __NR_renameat (__NR_Linux + 295)
+#define __NR_linkat (__NR_Linux + 296)
+#define __NR_symlinkat (__NR_Linux + 297)
+#define __NR_readlinkat (__NR_Linux + 298)
+#define __NR_fchmodat (__NR_Linux + 299)
+#define __NR_faccessat (__NR_Linux + 300)
+#define __NR_pselect6 (__NR_Linux + 301)
+#define __NR_ppoll (__NR_Linux + 302)
+#define __NR_unshare (__NR_Linux + 303)
+#define __NR_splice (__NR_Linux + 304)
+#define __NR_sync_file_range (__NR_Linux + 305)
+#define __NR_tee (__NR_Linux + 306)
+#define __NR_vmsplice (__NR_Linux + 307)
+#define __NR_move_pages (__NR_Linux + 308)
+#define __NR_set_robust_list (__NR_Linux + 309)
+#define __NR_get_robust_list (__NR_Linux + 310)
+#define __NR_kexec_load (__NR_Linux + 311)
+#define __NR_getcpu (__NR_Linux + 312)
+#define __NR_epoll_pwait (__NR_Linux + 313)
+#define __NR_ioprio_set (__NR_Linux + 314)
+#define __NR_ioprio_get (__NR_Linux + 315)
+#define __NR_utimensat (__NR_Linux + 316)
+#define __NR_signalfd (__NR_Linux + 317)
+#define __NR_timerfd (__NR_Linux + 318)
+#define __NR_eventfd (__NR_Linux + 319)
+#define __NR_fallocate (__NR_Linux + 320)
+#define __NR_timerfd_create (__NR_Linux + 321)
+#define __NR_timerfd_gettime (__NR_Linux + 322)
+#define __NR_timerfd_settime (__NR_Linux + 323)
+#define __NR_signalfd4 (__NR_Linux + 324)
+#define __NR_eventfd2 (__NR_Linux + 325)
+#define __NR_epoll_create1 (__NR_Linux + 326)
+#define __NR_dup3 (__NR_Linux + 327)
+#define __NR_pipe2 (__NR_Linux + 328)
+#define __NR_inotify_init1 (__NR_Linux + 329)
+#define __NR_preadv (__NR_Linux + 330)
+#define __NR_pwritev (__NR_Linux + 331)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332)
+#define __NR_perf_event_open (__NR_Linux + 333)
+#define __NR_accept4 (__NR_Linux + 334)
+#define __NR_recvmmsg (__NR_Linux + 335)
+#define __NR_fanotify_init (__NR_Linux + 336)
+#define __NR_fanotify_mark (__NR_Linux + 337)
+#define __NR_prlimit64 (__NR_Linux + 338)
+#define __NR_name_to_handle_at (__NR_Linux + 339)
+#define __NR_open_by_handle_at (__NR_Linux + 340)
+#define __NR_clock_adjtime (__NR_Linux + 341)
+#define __NR_syncfs (__NR_Linux + 342)
+#define __NR_setns (__NR_Linux + 343)
+
+/*
+ * Offset of the last Linux o32 flavoured syscall
+ */
+#define __NR_Linux_syscalls 343
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+
+#define __NR_O32_Linux 4000
+#define __NR_O32_Linux_syscalls 343
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+
+/*
+ * Linux 64-bit syscalls are in the range from 5000 to 5999.
+ */
+#define __NR_Linux 5000
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_set_tid_address (__NR_Linux + 212)
+#define __NR_restart_syscall (__NR_Linux + 213)
+#define __NR_semtimedop (__NR_Linux + 214)
+#define __NR_fadvise64 (__NR_Linux + 215)
+#define __NR_timer_create (__NR_Linux + 216)
+#define __NR_timer_settime (__NR_Linux + 217)
+#define __NR_timer_gettime (__NR_Linux + 218)
+#define __NR_timer_getoverrun (__NR_Linux + 219)
+#define __NR_timer_delete (__NR_Linux + 220)
+#define __NR_clock_settime (__NR_Linux + 221)
+#define __NR_clock_gettime (__NR_Linux + 222)
+#define __NR_clock_getres (__NR_Linux + 223)
+#define __NR_clock_nanosleep (__NR_Linux + 224)
+#define __NR_tgkill (__NR_Linux + 225)
+#define __NR_utimes (__NR_Linux + 226)
+#define __NR_mbind (__NR_Linux + 227)
+#define __NR_get_mempolicy (__NR_Linux + 228)
+#define __NR_set_mempolicy (__NR_Linux + 229)
+#define __NR_mq_open (__NR_Linux + 230)
+#define __NR_mq_unlink (__NR_Linux + 231)
+#define __NR_mq_timedsend (__NR_Linux + 232)
+#define __NR_mq_timedreceive (__NR_Linux + 233)
+#define __NR_mq_notify (__NR_Linux + 234)
+#define __NR_mq_getsetattr (__NR_Linux + 235)
+#define __NR_vserver (__NR_Linux + 236)
+#define __NR_waitid (__NR_Linux + 237)
+/* #define __NR_sys_setaltroot (__NR_Linux + 238) */
+#define __NR_add_key (__NR_Linux + 239)
+#define __NR_request_key (__NR_Linux + 240)
+#define __NR_keyctl (__NR_Linux + 241)
+#define __NR_set_thread_area (__NR_Linux + 242)
+#define __NR_inotify_init (__NR_Linux + 243)
+#define __NR_inotify_add_watch (__NR_Linux + 244)
+#define __NR_inotify_rm_watch (__NR_Linux + 245)
+#define __NR_migrate_pages (__NR_Linux + 246)
+#define __NR_openat (__NR_Linux + 247)
+#define __NR_mkdirat (__NR_Linux + 248)
+#define __NR_mknodat (__NR_Linux + 249)
+#define __NR_fchownat (__NR_Linux + 250)
+#define __NR_futimesat (__NR_Linux + 251)
+#define __NR_newfstatat (__NR_Linux + 252)
+#define __NR_unlinkat (__NR_Linux + 253)
+#define __NR_renameat (__NR_Linux + 254)
+#define __NR_linkat (__NR_Linux + 255)
+#define __NR_symlinkat (__NR_Linux + 256)
+#define __NR_readlinkat (__NR_Linux + 257)
+#define __NR_fchmodat (__NR_Linux + 258)
+#define __NR_faccessat (__NR_Linux + 259)
+#define __NR_pselect6 (__NR_Linux + 260)
+#define __NR_ppoll (__NR_Linux + 261)
+#define __NR_unshare (__NR_Linux + 262)
+#define __NR_splice (__NR_Linux + 263)
+#define __NR_sync_file_range (__NR_Linux + 264)
+#define __NR_tee (__NR_Linux + 265)
+#define __NR_vmsplice (__NR_Linux + 266)
+#define __NR_move_pages (__NR_Linux + 267)
+#define __NR_set_robust_list (__NR_Linux + 268)
+#define __NR_get_robust_list (__NR_Linux + 269)
+#define __NR_kexec_load (__NR_Linux + 270)
+#define __NR_getcpu (__NR_Linux + 271)
+#define __NR_epoll_pwait (__NR_Linux + 272)
+#define __NR_ioprio_set (__NR_Linux + 273)
+#define __NR_ioprio_get (__NR_Linux + 274)
+#define __NR_utimensat (__NR_Linux + 275)
+#define __NR_signalfd (__NR_Linux + 276)
+#define __NR_timerfd (__NR_Linux + 277)
+#define __NR_eventfd (__NR_Linux + 278)
+#define __NR_fallocate (__NR_Linux + 279)
+#define __NR_timerfd_create (__NR_Linux + 280)
+#define __NR_timerfd_gettime (__NR_Linux + 281)
+#define __NR_timerfd_settime (__NR_Linux + 282)
+#define __NR_signalfd4 (__NR_Linux + 283)
+#define __NR_eventfd2 (__NR_Linux + 284)
+#define __NR_epoll_create1 (__NR_Linux + 285)
+#define __NR_dup3 (__NR_Linux + 286)
+#define __NR_pipe2 (__NR_Linux + 287)
+#define __NR_inotify_init1 (__NR_Linux + 288)
+#define __NR_preadv (__NR_Linux + 289)
+#define __NR_pwritev (__NR_Linux + 290)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291)
+#define __NR_perf_event_open (__NR_Linux + 292)
+#define __NR_accept4 (__NR_Linux + 293)
+#define __NR_recvmmsg (__NR_Linux + 294)
+#define __NR_fanotify_init (__NR_Linux + 295)
+#define __NR_fanotify_mark (__NR_Linux + 296)
+#define __NR_prlimit64 (__NR_Linux + 297)
+#define __NR_name_to_handle_at (__NR_Linux + 298)
+#define __NR_open_by_handle_at (__NR_Linux + 299)
+#define __NR_clock_adjtime (__NR_Linux + 300)
+#define __NR_syncfs (__NR_Linux + 301)
+#define __NR_setns (__NR_Linux + 302)
+
+/*
+ * Offset of the last Linux 64-bit flavoured syscall
+ */
+#define __NR_Linux_syscalls 302
+
+#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
+
+#define __NR_64_Linux 5000
+#define __NR_64_Linux_syscalls 302
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+
+/*
+ * Linux N32 syscalls are in the range from 6000 to 6999.
+ */
+#define __NR_Linux 6000
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_fcntl64 (__NR_Linux + 212)
+#define __NR_set_tid_address (__NR_Linux + 213)
+#define __NR_restart_syscall (__NR_Linux + 214)
+#define __NR_semtimedop (__NR_Linux + 215)
+#define __NR_fadvise64 (__NR_Linux + 216)
+#define __NR_statfs64 (__NR_Linux + 217)
+#define __NR_fstatfs64 (__NR_Linux + 218)
+#define __NR_sendfile64 (__NR_Linux + 219)
+#define __NR_timer_create (__NR_Linux + 220)
+#define __NR_timer_settime (__NR_Linux + 221)
+#define __NR_timer_gettime (__NR_Linux + 222)
+#define __NR_timer_getoverrun (__NR_Linux + 223)
+#define __NR_timer_delete (__NR_Linux + 224)
+#define __NR_clock_settime (__NR_Linux + 225)
+#define __NR_clock_gettime (__NR_Linux + 226)
+#define __NR_clock_getres (__NR_Linux + 227)
+#define __NR_clock_nanosleep (__NR_Linux + 228)
+#define __NR_tgkill (__NR_Linux + 229)
+#define __NR_utimes (__NR_Linux + 230)
+#define __NR_mbind (__NR_Linux + 231)
+#define __NR_get_mempolicy (__NR_Linux + 232)
+#define __NR_set_mempolicy (__NR_Linux + 233)
+#define __NR_mq_open (__NR_Linux + 234)
+#define __NR_mq_unlink (__NR_Linux + 235)
+#define __NR_mq_timedsend (__NR_Linux + 236)
+#define __NR_mq_timedreceive (__NR_Linux + 237)
+#define __NR_mq_notify (__NR_Linux + 238)
+#define __NR_mq_getsetattr (__NR_Linux + 239)
+#define __NR_vserver (__NR_Linux + 240)
+#define __NR_waitid (__NR_Linux + 241)
+/* #define __NR_sys_setaltroot (__NR_Linux + 242) */
+#define __NR_add_key (__NR_Linux + 243)
+#define __NR_request_key (__NR_Linux + 244)
+#define __NR_keyctl (__NR_Linux + 245)
+#define __NR_set_thread_area (__NR_Linux + 246)
+#define __NR_inotify_init (__NR_Linux + 247)
+#define __NR_inotify_add_watch (__NR_Linux + 248)
+#define __NR_inotify_rm_watch (__NR_Linux + 249)
+#define __NR_migrate_pages (__NR_Linux + 250)
+#define __NR_openat (__NR_Linux + 251)
+#define __NR_mkdirat (__NR_Linux + 252)
+#define __NR_mknodat (__NR_Linux + 253)
+#define __NR_fchownat (__NR_Linux + 254)
+#define __NR_futimesat (__NR_Linux + 255)
+#define __NR_newfstatat (__NR_Linux + 256)
+#define __NR_unlinkat (__NR_Linux + 257)
+#define __NR_renameat (__NR_Linux + 258)
+#define __NR_linkat (__NR_Linux + 259)
+#define __NR_symlinkat (__NR_Linux + 260)
+#define __NR_readlinkat (__NR_Linux + 261)
+#define __NR_fchmodat (__NR_Linux + 262)
+#define __NR_faccessat (__NR_Linux + 263)
+#define __NR_pselect6 (__NR_Linux + 264)
+#define __NR_ppoll (__NR_Linux + 265)
+#define __NR_unshare (__NR_Linux + 266)
+#define __NR_splice (__NR_Linux + 267)
+#define __NR_sync_file_range (__NR_Linux + 268)
+#define __NR_tee (__NR_Linux + 269)
+#define __NR_vmsplice (__NR_Linux + 270)
+#define __NR_move_pages (__NR_Linux + 271)
+#define __NR_set_robust_list (__NR_Linux + 272)
+#define __NR_get_robust_list (__NR_Linux + 273)
+#define __NR_kexec_load (__NR_Linux + 274)
+#define __NR_getcpu (__NR_Linux + 275)
+#define __NR_epoll_pwait (__NR_Linux + 276)
+#define __NR_ioprio_set (__NR_Linux + 277)
+#define __NR_ioprio_get (__NR_Linux + 278)
+#define __NR_utimensat (__NR_Linux + 279)
+#define __NR_signalfd (__NR_Linux + 280)
+#define __NR_timerfd (__NR_Linux + 281)
+#define __NR_eventfd (__NR_Linux + 282)
+#define __NR_fallocate (__NR_Linux + 283)
+#define __NR_timerfd_create (__NR_Linux + 284)
+#define __NR_timerfd_gettime (__NR_Linux + 285)
+#define __NR_timerfd_settime (__NR_Linux + 286)
+#define __NR_signalfd4 (__NR_Linux + 287)
+#define __NR_eventfd2 (__NR_Linux + 288)
+#define __NR_epoll_create1 (__NR_Linux + 289)
+#define __NR_dup3 (__NR_Linux + 290)
+#define __NR_pipe2 (__NR_Linux + 291)
+#define __NR_inotify_init1 (__NR_Linux + 292)
+#define __NR_preadv (__NR_Linux + 293)
+#define __NR_pwritev (__NR_Linux + 294)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 295)
+#define __NR_perf_event_open (__NR_Linux + 296)
+#define __NR_accept4 (__NR_Linux + 297)
+#define __NR_recvmmsg (__NR_Linux + 298)
+#define __NR_getdents64 (__NR_Linux + 299)
+#define __NR_fanotify_init (__NR_Linux + 300)
+#define __NR_fanotify_mark (__NR_Linux + 301)
+#define __NR_prlimit64 (__NR_Linux + 302)
+#define __NR_name_to_handle_at (__NR_Linux + 303)
+#define __NR_open_by_handle_at (__NR_Linux + 304)
+#define __NR_clock_adjtime (__NR_Linux + 305)
+#define __NR_syncfs (__NR_Linux + 306)
+#define __NR_setns (__NR_Linux + 307)
+
+/*
+ * Offset of the last N32 flavoured syscall
+ */
+#define __NR_Linux_syscalls 307
+
+#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
+
+#define __NR_N32_Linux 6000
+#define __NR_N32_Linux_syscalls 307
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#define __ARCH_OMIT_COMPAT_SYS_GETDENTS64
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_UNAME
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+# ifdef CONFIG_32BIT
+# define __ARCH_WANT_STAT64
+# define __ARCH_WANT_SYS_TIME
+# endif
+# ifdef CONFIG_MIPS32_O32
+# define __ARCH_WANT_COMPAT_SYS_TIME
+# endif
+
+/* whitelists for checksyscalls */
+#define __IGNORE_select
+#define __IGNORE_vfork
+#define __IGNORE_time
+#define __IGNORE_uselib
+#define __IGNORE_fadvise64_64
+#define __IGNORE_getdents64
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+#define __IGNORE_truncate64
+#define __IGNORE_ftruncate64
+#define __IGNORE_stat64
+#define __IGNORE_lstat64
+#define __IGNORE_fstat64
+#define __IGNORE_fstatat64
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall")
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_UNISTD_H */
diff --git a/arch/mips/include/asm/user.h b/arch/mips/include/asm/user.h
new file mode 100644
index 00000000..afa83a4c
--- /dev/null
+++ b/arch/mips/include/asm/user.h
@@ -0,0 +1,58 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ */
+#ifndef _ASM_USER_H
+#define _ASM_USER_H
+
+#include <asm/page.h>
+#include <asm/reg.h>
+
+/*
+ * Core file format: The core file is written in such a way that gdb
+ * can understand it and provide useful information to the user (under
+ * linux we use the `trad-core' bfd, NOT the irix-core). The file
+ * contents are as follows:
+ *
+ * upage: 1 page consisting of a user struct that tells gdb
+ * what is present in the file. Directly after this is a
+ * copy of the task_struct, which is currently not used by gdb,
+ * but it may come in handy at some point. All of the registers
+ * are stored as part of the upage. The upage should always be
+ * only one page long.
+ * data: The data segment follows next. We use current->end_text to
+ * current->brk to pick up all of the user variables, plus any memory
+ * that may have been sbrk'ed. No attempt is made to determine if a
+ * page is demand-zero or if a page is totally unused, we just cover
+ * the entire range. All of the addresses are rounded in such a way
+ * that an integral number of pages is written.
+ * stack: We need the stack information in order to get a meaningful
+ * backtrace. We need to write the data from usp to
+ * current->start_stack, so we round each of these in order to be able
+ * to write an integer number of pages.
+ */
+struct user {
+ unsigned long regs[EF_SIZE / /* integer and fp regs */
+ sizeof(unsigned long) + 64];
+ size_t u_tsize; /* text size (pages) */
+ size_t u_dsize; /* data size (pages) */
+ size_t u_ssize; /* stack size (pages) */
+ unsigned long start_code; /* text starting address */
+ unsigned long start_data; /* data starting address */
+ unsigned long start_stack; /* stack starting address */
+ long int signal; /* signal causing core dump */
+ unsigned long u_ar0; /* help gdb find registers */
+ unsigned long magic; /* identifies a core file */
+ char u_comm[32]; /* user command name */
+};
+
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_DATA_START_ADDR (u.start_data)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif /* _ASM_USER_H */
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
new file mode 100644
index 00000000..cca56aa4
--- /dev/null
+++ b/arch/mips/include/asm/vdso.h
@@ -0,0 +1,29 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Cavium Networks
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#include <linux/types.h>
+
+
+#ifdef CONFIG_32BIT
+struct mips_vdso {
+ u32 signal_trampoline[2];
+ u32 rt_signal_trampoline[2];
+};
+#else /* !CONFIG_32BIT */
+struct mips_vdso {
+ u32 o32_signal_trampoline[2];
+ u32 o32_rt_signal_trampoline[2];
+ u32 rt_signal_trampoline[2];
+ u32 n32_rt_signal_trampoline[2];
+};
+#endif /* CONFIG_32BIT */
+
+#endif /* __ASM_VDSO_H */
diff --git a/arch/mips/include/asm/vga.h b/arch/mips/include/asm/vga.h
new file mode 100644
index 00000000..f4cff7e4
--- /dev/null
+++ b/arch/mips/include/asm/vga.h
@@ -0,0 +1,47 @@
+/*
+ * Access to VGA videoram
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ */
+#ifndef _ASM_VGA_H
+#define _ASM_VGA_H
+
+#include <asm/byteorder.h>
+
+/*
+ * On the PC, we can just recalculate addresses and then
+ * access the videoram directly without any black magic.
+ */
+
+#define VGA_MAP_MEM(x, s) (0xb0000000L + (unsigned long)(x))
+
+#define vga_readb(x) (*(x))
+#define vga_writeb(x, y) (*(y) = (x))
+
+#define VT_BUF_HAVE_RW
+/*
+ * These are only needed for supporting VGA or MDA text mode, which use little
+ * endian byte ordering.
+ * In other cases, we can optimize by using native byte ordering and
+ * <linux/vt_buffer.h> has already done the right job for us.
+ */
+
+#undef scr_writew
+#undef scr_readw
+
+static inline void scr_writew(u16 val, volatile u16 *addr)
+{
+ *addr = cpu_to_le16(val);
+}
+
+static inline u16 scr_readw(volatile const u16 *addr)
+{
+ return le16_to_cpu(*addr);
+}
+
+#define scr_memcpyw(d, s, c) memcpy(d, s, c)
+#define scr_memmovew(d, s, c) memmove(d, s, c)
+#define VT_BUF_HAVE_MEMCPYW
+#define VT_BUF_HAVE_MEMMOVEW
+
+#endif /* _ASM_VGA_H */
diff --git a/arch/mips/include/asm/vpe.h b/arch/mips/include/asm/vpe.h
new file mode 100644
index 00000000..c6e1b961
--- /dev/null
+++ b/arch/mips/include/asm/vpe.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#ifndef _ASM_VPE_H
+#define _ASM_VPE_H
+
+struct vpe_notifications {
+ void (*start)(int vpe);
+ void (*stop)(int vpe);
+
+ struct list_head list;
+};
+
+
+extern int vpe_notify(int index, struct vpe_notifications *notify);
+
+extern void *vpe_get_shared(int index);
+extern int vpe_getuid(int index);
+extern int vpe_getgid(int index);
+extern char *vpe_getcwd(int index);
+
+#endif /* _ASM_VPE_H */
diff --git a/arch/mips/include/asm/vr41xx/capcella.h b/arch/mips/include/asm/vr41xx/capcella.h
new file mode 100644
index 00000000..fcc65694
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/capcella.h
@@ -0,0 +1,43 @@
+/*
+ * capcella.h, Include file for ZAO Networks Capcella.
+ *
+ * Copyright (C) 2002-2004 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ZAO_CAPCELLA_H
+#define __ZAO_CAPCELLA_H
+
+#include <asm/vr41xx/irq.h>
+
+/*
+ * General-Purpose I/O Pin Number
+ */
+#define PC104PLUS_INTA_PIN 2
+#define PC104PLUS_INTB_PIN 3
+#define PC104PLUS_INTC_PIN 4
+#define PC104PLUS_INTD_PIN 5
+
+/*
+ * Interrupt Number
+ */
+#define RTL8139_1_IRQ GIU_IRQ(PC104PLUS_INTC_PIN)
+#define RTL8139_2_IRQ GIU_IRQ(PC104PLUS_INTD_PIN)
+#define PC104PLUS_INTA_IRQ GIU_IRQ(PC104PLUS_INTA_PIN)
+#define PC104PLUS_INTB_IRQ GIU_IRQ(PC104PLUS_INTB_PIN)
+#define PC104PLUS_INTC_IRQ GIU_IRQ(PC104PLUS_INTC_PIN)
+#define PC104PLUS_INTD_IRQ GIU_IRQ(PC104PLUS_INTD_PIN)
+
+#endif /* __ZAO_CAPCELLA_H */
diff --git a/arch/mips/include/asm/vr41xx/giu.h b/arch/mips/include/asm/vr41xx/giu.h
new file mode 100644
index 00000000..6a90bc1d
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/giu.h
@@ -0,0 +1,62 @@
+/*
+ * Include file for NEC VR4100 series General-purpose I/O Unit.
+ *
+ * Copyright (C) 2005-2009 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __NEC_VR41XX_GIU_H
+#define __NEC_VR41XX_GIU_H
+
+/*
+ * NEC VR4100 series GIU platform device IDs.
+ */
+enum {
+ GPIO_50PINS_PULLUPDOWN,
+ GPIO_36PINS,
+ GPIO_48PINS_EDGE_SELECT,
+};
+
+typedef enum {
+ IRQ_TRIGGER_LEVEL,
+ IRQ_TRIGGER_EDGE,
+ IRQ_TRIGGER_EDGE_FALLING,
+ IRQ_TRIGGER_EDGE_RISING,
+} irq_trigger_t;
+
+typedef enum {
+ IRQ_SIGNAL_THROUGH,
+ IRQ_SIGNAL_HOLD,
+} irq_signal_t;
+
+extern void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger,
+ irq_signal_t signal);
+
+typedef enum {
+ IRQ_LEVEL_LOW,
+ IRQ_LEVEL_HIGH,
+} irq_level_t;
+
+extern void vr41xx_set_irq_level(unsigned int pin, irq_level_t level);
+
+typedef enum {
+ GPIO_PULL_DOWN,
+ GPIO_PULL_UP,
+ GPIO_PULL_DISABLE,
+} gpio_pull_t;
+
+extern int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull);
+
+#endif /* __NEC_VR41XX_GIU_H */
diff --git a/arch/mips/include/asm/vr41xx/irq.h b/arch/mips/include/asm/vr41xx/irq.h
new file mode 100644
index 00000000..b07f7321
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/irq.h
@@ -0,0 +1,101 @@
+/*
+ * include/asm-mips/vr41xx/irq.h
+ *
+ * Interrupt numbers for NEC VR4100 series.
+ *
+ * Copyright (C) 1999 Michael Klar
+ * Copyright (C) 2001, 2002 Paul Mundt
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ * Copyright (C) 2002 TimeSys Corp.
+ * Copyright (C) 2003-2006 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef __NEC_VR41XX_IRQ_H
+#define __NEC_VR41XX_IRQ_H
+
+/*
+ * CPU core Interrupt Numbers
+ */
+#define MIPS_CPU_IRQ_BASE 0
+#define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x))
+#define MIPS_SOFTINT0_IRQ MIPS_CPU_IRQ(0)
+#define MIPS_SOFTINT1_IRQ MIPS_CPU_IRQ(1)
+#define INT0_IRQ MIPS_CPU_IRQ(2)
+#define INT1_IRQ MIPS_CPU_IRQ(3)
+#define INT2_IRQ MIPS_CPU_IRQ(4)
+#define INT3_IRQ MIPS_CPU_IRQ(5)
+#define INT4_IRQ MIPS_CPU_IRQ(6)
+#define TIMER_IRQ MIPS_CPU_IRQ(7)
+
+/*
+ * SYINT1 Interrupt Numbers
+ */
+#define SYSINT1_IRQ_BASE 8
+#define SYSINT1_IRQ(x) (SYSINT1_IRQ_BASE + (x))
+#define BATTRY_IRQ SYSINT1_IRQ(0)
+#define POWER_IRQ SYSINT1_IRQ(1)
+#define RTCLONG1_IRQ SYSINT1_IRQ(2)
+#define ELAPSEDTIME_IRQ SYSINT1_IRQ(3)
+/* RFU */
+#define PIU_IRQ SYSINT1_IRQ(5)
+#define AIU_IRQ SYSINT1_IRQ(6)
+#define KIU_IRQ SYSINT1_IRQ(7)
+#define GIUINT_IRQ SYSINT1_IRQ(8)
+#define SIU_IRQ SYSINT1_IRQ(9)
+#define BUSERR_IRQ SYSINT1_IRQ(10)
+#define SOFTINT_IRQ SYSINT1_IRQ(11)
+#define CLKRUN_IRQ SYSINT1_IRQ(12)
+#define DOZEPIU_IRQ SYSINT1_IRQ(13)
+#define SYSINT1_IRQ_LAST DOZEPIU_IRQ
+
+/*
+ * SYSINT2 Interrupt Numbers
+ */
+#define SYSINT2_IRQ_BASE 24
+#define SYSINT2_IRQ(x) (SYSINT2_IRQ_BASE + (x))
+#define RTCLONG2_IRQ SYSINT2_IRQ(0)
+#define LED_IRQ SYSINT2_IRQ(1)
+#define HSP_IRQ SYSINT2_IRQ(2)
+#define TCLOCK_IRQ SYSINT2_IRQ(3)
+#define FIR_IRQ SYSINT2_IRQ(4)
+#define CEU_IRQ SYSINT2_IRQ(4) /* same number as FIR_IRQ */
+#define DSIU_IRQ SYSINT2_IRQ(5)
+#define PCI_IRQ SYSINT2_IRQ(6)
+#define SCU_IRQ SYSINT2_IRQ(7)
+#define CSI_IRQ SYSINT2_IRQ(8)
+#define BCU_IRQ SYSINT2_IRQ(9)
+#define ETHERNET_IRQ SYSINT2_IRQ(10)
+#define SYSINT2_IRQ_LAST ETHERNET_IRQ
+
+/*
+ * GIU Interrupt Numbers
+ */
+#define GIU_IRQ_BASE 40
+#define GIU_IRQ(x) (GIU_IRQ_BASE + (x)) /* IRQ 40-71 */
+#define GIU_IRQ_LAST GIU_IRQ(31)
+
+/*
+ * VRC4173 Interrupt Numbers
+ */
+#define VRC4173_IRQ_BASE 72
+#define VRC4173_IRQ(x) (VRC4173_IRQ_BASE + (x))
+#define VRC4173_USB_IRQ VRC4173_IRQ(0)
+#define VRC4173_PCMCIA2_IRQ VRC4173_IRQ(1)
+#define VRC4173_PCMCIA1_IRQ VRC4173_IRQ(2)
+#define VRC4173_PS2CH2_IRQ VRC4173_IRQ(3)
+#define VRC4173_PS2CH1_IRQ VRC4173_IRQ(4)
+#define VRC4173_PIU_IRQ VRC4173_IRQ(5)
+#define VRC4173_AIU_IRQ VRC4173_IRQ(6)
+#define VRC4173_KIU_IRQ VRC4173_IRQ(7)
+#define VRC4173_GIU_IRQ VRC4173_IRQ(8)
+#define VRC4173_AC97_IRQ VRC4173_IRQ(9)
+#define VRC4173_AC97INT1_IRQ VRC4173_IRQ(10)
+/* RFU */
+#define VRC4173_DOZEPIU_IRQ VRC4173_IRQ(13)
+#define VRC4173_IRQ_LAST VRC4173_DOZEPIU_IRQ
+
+#endif /* __NEC_VR41XX_IRQ_H */
diff --git a/arch/mips/include/asm/vr41xx/mpc30x.h b/arch/mips/include/asm/vr41xx/mpc30x.h
new file mode 100644
index 00000000..130d09d8
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/mpc30x.h
@@ -0,0 +1,37 @@
+/*
+ * mpc30x.h, Include file for Victor MP-C303/304.
+ *
+ * Copyright (C) 2002-2004 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __VICTOR_MPC30X_H
+#define __VICTOR_MPC30X_H
+
+#include <asm/vr41xx/irq.h>
+
+/*
+ * General-Purpose I/O Pin Number
+ */
+#define VRC4173_PIN 1
+#define MQ200_PIN 4
+
+/*
+ * Interrupt Number
+ */
+#define VRC4173_CASCADE_IRQ GIU_IRQ(VRC4173_PIN)
+#define MQ200_IRQ GIU_IRQ(MQ200_PIN)
+
+#endif /* __VICTOR_MPC30X_H */
diff --git a/arch/mips/include/asm/vr41xx/pci.h b/arch/mips/include/asm/vr41xx/pci.h
new file mode 100644
index 00000000..c231a3d6
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/pci.h
@@ -0,0 +1,90 @@
+/*
+ * Include file for NEC VR4100 series PCI Control Unit.
+ *
+ * Copyright (C) 2004-2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __NEC_VR41XX_PCI_H
+#define __NEC_VR41XX_PCI_H
+
+#define PCI_MASTER_ADDRESS_MASK 0x7fffffffU
+
+struct pci_master_address_conversion {
+ uint32_t bus_base_address;
+ uint32_t address_mask;
+ uint32_t pci_base_address;
+};
+
+struct pci_target_address_conversion {
+ uint32_t address_mask;
+ uint32_t bus_base_address;
+};
+
+typedef enum {
+ CANNOT_LOCK_FROM_DEVICE,
+ CAN_LOCK_FROM_DEVICE,
+} pci_exclusive_access_t;
+
+struct pci_mailbox_address {
+ uint32_t base_address;
+};
+
+struct pci_target_address_window {
+ uint32_t base_address;
+};
+
+typedef enum {
+ PCI_ARBITRATION_MODE_FAIR,
+ PCI_ARBITRATION_MODE_ALTERNATE_0,
+ PCI_ARBITRATION_MODE_ALTERNATE_B,
+} pci_arbiter_priority_control_t;
+
+typedef enum {
+ PCI_TAKE_AWAY_GNT_DISABLE,
+ PCI_TAKE_AWAY_GNT_ENABLE,
+} pci_take_away_gnt_mode_t;
+
+struct pci_controller_unit_setup {
+ struct pci_master_address_conversion *master_memory1;
+ struct pci_master_address_conversion *master_memory2;
+
+ struct pci_target_address_conversion *target_memory1;
+ struct pci_target_address_conversion *target_memory2;
+
+ struct pci_master_address_conversion *master_io;
+
+ pci_exclusive_access_t exclusive_access;
+
+ uint32_t pci_clock_max;
+ uint8_t wait_time_limit_from_irdy_to_trdy; /* Only VR4122 is supported */
+
+ struct pci_mailbox_address *mailbox;
+ struct pci_target_address_window *target_window1;
+ struct pci_target_address_window *target_window2;
+
+ uint8_t master_latency_timer;
+ uint8_t retry_limit;
+
+ pci_arbiter_priority_control_t arbiter_priority_control;
+ pci_take_away_gnt_mode_t take_away_gnt_mode;
+
+ struct resource *mem_resource;
+ struct resource *io_resource;
+};
+
+extern void vr41xx_pciu_setup(struct pci_controller_unit_setup *setup);
+
+#endif /* __NEC_VR41XX_PCI_H */
diff --git a/arch/mips/include/asm/vr41xx/siu.h b/arch/mips/include/asm/vr41xx/siu.h
new file mode 100644
index 00000000..ca806bc4
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/siu.h
@@ -0,0 +1,58 @@
+/*
+ * Include file for NEC VR4100 series Serial Interface Unit.
+ *
+ * Copyright (C) 2005-2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __NEC_VR41XX_SIU_H
+#define __NEC_VR41XX_SIU_H
+
+#define SIU_PORTS_MAX 2
+
+typedef enum {
+ SIU_INTERFACE_RS232C,
+ SIU_INTERFACE_IRDA,
+} siu_interface_t;
+
+extern void vr41xx_select_siu_interface(siu_interface_t interface);
+
+typedef enum {
+ SIU_USE_IRDA,
+ FIR_USE_IRDA,
+} irda_use_t;
+
+extern void vr41xx_use_irda(irda_use_t use);
+
+typedef enum {
+ SHARP_IRDA,
+ TEMIC_IRDA,
+ HP_IRDA,
+} irda_module_t;
+
+typedef enum {
+ IRDA_TX_1_5MBPS,
+ IRDA_TX_4MBPS,
+} irda_speed_t;
+
+extern void vr41xx_select_irda_module(irda_module_t module, irda_speed_t speed);
+
+#ifdef CONFIG_SERIAL_VR41XX_CONSOLE
+extern void vr41xx_siu_early_setup(struct uart_port *port);
+#else
+static inline void vr41xx_siu_early_setup(struct uart_port *port) {}
+#endif
+
+#endif /* __NEC_VR41XX_SIU_H */
diff --git a/arch/mips/include/asm/vr41xx/tb0219.h b/arch/mips/include/asm/vr41xx/tb0219.h
new file mode 100644
index 00000000..c78e8243
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/tb0219.h
@@ -0,0 +1,42 @@
+/*
+ * tb0219.h, Include file for TANBAC TB0219.
+ *
+ * Copyright (C) 2002-2004 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * Modified for TANBAC TB0219:
+ * Copyright (C) 2003 Megasolution Inc. <matsu@megasolution.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __TANBAC_TB0219_H
+#define __TANBAC_TB0219_H
+
+#include <asm/vr41xx/irq.h>
+
+/*
+ * General-Purpose I/O Pin Number
+ */
+#define TB0219_PCI_SLOT1_PIN 2
+#define TB0219_PCI_SLOT2_PIN 3
+#define TB0219_PCI_SLOT3_PIN 4
+
+/*
+ * Interrupt Number
+ */
+#define TB0219_PCI_SLOT1_IRQ GIU_IRQ(TB0219_PCI_SLOT1_PIN)
+#define TB0219_PCI_SLOT2_IRQ GIU_IRQ(TB0219_PCI_SLOT2_PIN)
+#define TB0219_PCI_SLOT3_IRQ GIU_IRQ(TB0219_PCI_SLOT3_PIN)
+
+#endif /* __TANBAC_TB0219_H */
diff --git a/arch/mips/include/asm/vr41xx/tb0226.h b/arch/mips/include/asm/vr41xx/tb0226.h
new file mode 100644
index 00000000..36f5f798
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/tb0226.h
@@ -0,0 +1,43 @@
+/*
+ * tb0226.h, Include file for TANBAC TB0226.
+ *
+ * Copyright (C) 2002-2004 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __TANBAC_TB0226_H
+#define __TANBAC_TB0226_H
+
+#include <asm/vr41xx/irq.h>
+
+/*
+ * General-Purpose I/O Pin Number
+ */
+#define GD82559_1_PIN 2
+#define GD82559_2_PIN 3
+#define UPD720100_INTA_PIN 4
+#define UPD720100_INTB_PIN 8
+#define UPD720100_INTC_PIN 13
+
+/*
+ * Interrupt Number
+ */
+#define GD82559_1_IRQ GIU_IRQ(GD82559_1_PIN)
+#define GD82559_2_IRQ GIU_IRQ(GD82559_2_PIN)
+#define UPD720100_INTA_IRQ GIU_IRQ(UPD720100_INTA_PIN)
+#define UPD720100_INTB_IRQ GIU_IRQ(UPD720100_INTB_PIN)
+#define UPD720100_INTC_IRQ GIU_IRQ(UPD720100_INTC_PIN)
+
+#endif /* __TANBAC_TB0226_H */
diff --git a/arch/mips/include/asm/vr41xx/tb0287.h b/arch/mips/include/asm/vr41xx/tb0287.h
new file mode 100644
index 00000000..61bead68
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/tb0287.h
@@ -0,0 +1,43 @@
+/*
+ * tb0287.h, Include file for TANBAC TB0287 mini-ITX board.
+ *
+ * Copyright (C) 2005 Media Lab Inc. <ito@mlb.co.jp>
+ *
+ * This code is largely based on tb0219.h.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __TANBAC_TB0287_H
+#define __TANBAC_TB0287_H
+
+#include <asm/vr41xx/irq.h>
+
+/*
+ * General-Purpose I/O Pin Number
+ */
+#define TB0287_PCI_SLOT_PIN 2
+#define TB0287_SM501_PIN 3
+#define TB0287_SIL680A_PIN 8
+#define TB0287_RTL8110_PIN 13
+
+/*
+ * Interrupt Number
+ */
+#define TB0287_PCI_SLOT_IRQ GIU_IRQ(TB0287_PCI_SLOT_PIN)
+#define TB0287_SM501_IRQ GIU_IRQ(TB0287_SM501_PIN)
+#define TB0287_SIL680A_IRQ GIU_IRQ(TB0287_SIL680A_PIN)
+#define TB0287_RTL8110_IRQ GIU_IRQ(TB0287_RTL8110_PIN)
+
+#endif /* __TANBAC_TB0287_H */
diff --git a/arch/mips/include/asm/vr41xx/vr41xx.h b/arch/mips/include/asm/vr41xx/vr41xx.h
new file mode 100644
index 00000000..7b96a43b
--- /dev/null
+++ b/arch/mips/include/asm/vr41xx/vr41xx.h
@@ -0,0 +1,152 @@
+/*
+ * include/asm-mips/vr41xx/vr41xx.h
+ *
+ * Include file for NEC VR4100 series.
+ *
+ * Copyright (C) 1999 Michael Klar
+ * Copyright (C) 2001, 2002 Paul Mundt
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ * Copyright (C) 2002 TimeSys Corp.
+ * Copyright (C) 2003-2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef __NEC_VR41XX_H
+#define __NEC_VR41XX_H
+
+#include <linux/interrupt.h>
+
+/*
+ * CPU Revision
+ */
+/* VR4122 0x00000c70-0x00000c72 */
+#define PRID_VR4122_REV1_0 0x00000c70
+#define PRID_VR4122_REV2_0 0x00000c70
+#define PRID_VR4122_REV2_1 0x00000c70
+#define PRID_VR4122_REV3_0 0x00000c71
+#define PRID_VR4122_REV3_1 0x00000c72
+
+/* VR4181A 0x00000c73-0x00000c7f */
+#define PRID_VR4181A_REV1_0 0x00000c73
+#define PRID_VR4181A_REV1_1 0x00000c74
+
+/* VR4131 0x00000c80-0x00000c83 */
+#define PRID_VR4131_REV1_2 0x00000c80
+#define PRID_VR4131_REV2_0 0x00000c81
+#define PRID_VR4131_REV2_1 0x00000c82
+#define PRID_VR4131_REV2_2 0x00000c83
+
+/* VR4133 0x00000c84- */
+#define PRID_VR4133 0x00000c84
+
+/*
+ * Bus Control Uint
+ */
+extern unsigned long vr41xx_calculate_clock_frequency(void);
+extern unsigned long vr41xx_get_vtclock_frequency(void);
+extern unsigned long vr41xx_get_tclock_frequency(void);
+
+/*
+ * Clock Mask Unit
+ */
+typedef enum {
+ PIU_CLOCK,
+ SIU_CLOCK,
+ AIU_CLOCK,
+ KIU_CLOCK,
+ FIR_CLOCK,
+ DSIU_CLOCK,
+ CSI_CLOCK,
+ PCIU_CLOCK,
+ HSP_CLOCK,
+ PCI_CLOCK,
+ CEU_CLOCK,
+ ETHER0_CLOCK,
+ ETHER1_CLOCK
+} vr41xx_clock_t;
+
+extern void vr41xx_supply_clock(vr41xx_clock_t clock);
+extern void vr41xx_mask_clock(vr41xx_clock_t clock);
+
+/*
+ * Interrupt Control Unit
+ */
+extern int vr41xx_set_intassign(unsigned int irq, unsigned char intassign);
+extern int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int));
+
+#define PIUINT_COMMAND 0x0040
+#define PIUINT_DATA 0x0020
+#define PIUINT_PAGE1 0x0010
+#define PIUINT_PAGE0 0x0008
+#define PIUINT_DATALOST 0x0004
+#define PIUINT_STATUSCHANGE 0x0001
+
+extern void vr41xx_enable_piuint(uint16_t mask);
+extern void vr41xx_disable_piuint(uint16_t mask);
+
+#define AIUINT_INPUT_DMAEND 0x0800
+#define AIUINT_INPUT_DMAHALT 0x0400
+#define AIUINT_INPUT_DATALOST 0x0200
+#define AIUINT_INPUT_DATA 0x0100
+#define AIUINT_OUTPUT_DMAEND 0x0008
+#define AIUINT_OUTPUT_DMAHALT 0x0004
+#define AIUINT_OUTPUT_NODATA 0x0002
+
+extern void vr41xx_enable_aiuint(uint16_t mask);
+extern void vr41xx_disable_aiuint(uint16_t mask);
+
+#define KIUINT_DATALOST 0x0004
+#define KIUINT_DATAREADY 0x0002
+#define KIUINT_SCAN 0x0001
+
+extern void vr41xx_enable_kiuint(uint16_t mask);
+extern void vr41xx_disable_kiuint(uint16_t mask);
+
+#define DSIUINT_CTS 0x0800
+#define DSIUINT_RXERR 0x0400
+#define DSIUINT_RX 0x0200
+#define DSIUINT_TX 0x0100
+#define DSIUINT_ALL 0x0f00
+
+extern void vr41xx_enable_dsiuint(uint16_t mask);
+extern void vr41xx_disable_dsiuint(uint16_t mask);
+
+#define FIRINT_UNIT 0x0010
+#define FIRINT_RX_DMAEND 0x0008
+#define FIRINT_RX_DMAHALT 0x0004
+#define FIRINT_TX_DMAEND 0x0002
+#define FIRINT_TX_DMAHALT 0x0001
+
+extern void vr41xx_enable_firint(uint16_t mask);
+extern void vr41xx_disable_firint(uint16_t mask);
+
+extern void vr41xx_enable_pciint(void);
+extern void vr41xx_disable_pciint(void);
+
+extern void vr41xx_enable_scuint(void);
+extern void vr41xx_disable_scuint(void);
+
+#define CSIINT_TX_DMAEND 0x0040
+#define CSIINT_TX_DMAHALT 0x0020
+#define CSIINT_TX_DATA 0x0010
+#define CSIINT_TX_FIFOEMPTY 0x0008
+#define CSIINT_RX_DMAEND 0x0004
+#define CSIINT_RX_DMAHALT 0x0002
+#define CSIINT_RX_FIFOEMPTY 0x0001
+
+extern void vr41xx_enable_csiint(uint16_t mask);
+extern void vr41xx_disable_csiint(uint16_t mask);
+
+extern void vr41xx_enable_bcuint(void);
+extern void vr41xx_disable_bcuint(void);
+
+#ifdef CONFIG_SERIAL_VR41XX_CONSOLE
+extern void vr41xx_siu_setup(void);
+#else
+static inline void vr41xx_siu_setup(void) {}
+#endif
+
+#endif /* __NEC_VR41XX_H */
diff --git a/arch/mips/include/asm/war.h b/arch/mips/include/asm/war.h
new file mode 100644
index 00000000..fa133c1b
--- /dev/null
+++ b/arch/mips/include/asm/war.h
@@ -0,0 +1,244 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle
+ * Copyright (C) 2007 Maciej W. Rozycki
+ */
+#ifndef _ASM_WAR_H
+#define _ASM_WAR_H
+
+#include <war.h>
+
+/*
+ * Work around certain R4000 CPU errata (as implemented by GCC):
+ *
+ * - A double-word or a variable shift may give an incorrect result
+ * if executed immediately after starting an integer division:
+ * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
+ * erratum #28
+ * "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0", erratum
+ * #19
+ *
+ * - A double-word or a variable shift may give an incorrect result
+ * if executed while an integer multiplication is in progress:
+ * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
+ * errata #16 & #28
+ *
+ * - An integer division may give an incorrect result if started in
+ * a delay slot of a taken branch or a jump:
+ * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
+ * erratum #52
+ */
+#ifdef CONFIG_CPU_R4000_WORKAROUNDS
+#define R4000_WAR 1
+#else
+#define R4000_WAR 0
+#endif
+
+/*
+ * Work around certain R4400 CPU errata (as implemented by GCC):
+ *
+ * - A double-word or a variable shift may give an incorrect result
+ * if executed immediately after starting an integer division:
+ * "MIPS R4400MC Errata, Processor Revision 1.0", erratum #10
+ * "MIPS R4400MC Errata, Processor Revision 2.0 & 3.0", erratum #4
+ */
+#ifdef CONFIG_CPU_R4400_WORKAROUNDS
+#define R4400_WAR 1
+#else
+#define R4400_WAR 0
+#endif
+
+/*
+ * Work around the "daddi" and "daddiu" CPU errata:
+ *
+ * - The `daddi' instruction fails to trap on overflow.
+ * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
+ * erratum #23
+ *
+ * - The `daddiu' instruction can produce an incorrect result.
+ * "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
+ * erratum #41
+ * "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0", erratum
+ * #15
+ * "MIPS R4400PC/SC Errata, Processor Revision 1.0", erratum #7
+ * "MIPS R4400MC Errata, Processor Revision 1.0", erratum #5
+ */
+#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
+#define DADDI_WAR 1
+#else
+#define DADDI_WAR 0
+#endif
+
+/*
+ * Another R4600 erratum. Due to the lack of errata information the exact
+ * technical details aren't known. I've experimentally found that disabling
+ * interrupts during indexed I-cache flushes seems to be sufficient to deal
+ * with the issue.
+ */
+#ifndef R4600_V1_INDEX_ICACHEOP_WAR
+#error Check setting of R4600_V1_INDEX_ICACHEOP_WAR for your platform
+#endif
+
+/*
+ * Pleasures of the R4600 V1.x. Cite from the IDT R4600 V1.7 errata:
+ *
+ * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
+ * Hit_Invalidate_D and Create_Dirty_Excl_D should only be
+ * executed if there is no other dcache activity. If the dcache is
+ * accessed for another instruction immeidately preceding when these
+ * cache instructions are executing, it is possible that the dcache
+ * tag match outputs used by these cache instructions will be
+ * incorrect. These cache instructions should be preceded by at least
+ * four instructions that are not any kind of load or store
+ * instruction.
+ *
+ * This is not allowed: lw
+ * nop
+ * nop
+ * nop
+ * cache Hit_Writeback_Invalidate_D
+ *
+ * This is allowed: lw
+ * nop
+ * nop
+ * nop
+ * nop
+ * cache Hit_Writeback_Invalidate_D
+ */
+#ifndef R4600_V1_HIT_CACHEOP_WAR
+#error Check setting of R4600_V1_HIT_CACHEOP_WAR for your platform
+#endif
+
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ *
+ * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D,
+ * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only
+ * operate correctly if the internal data cache refill buffer is empty. These
+ * CACHE instructions should be separated from any potential data cache miss
+ * by a load instruction to an uncached address to empty the response buffer."
+ * (Revision 2.0 device errata from IDT available on http://www.idt.com/
+ * in .pdf format.)
+ */
+#ifndef R4600_V2_HIT_CACHEOP_WAR
+#error Check setting of R4600_V2_HIT_CACHEOP_WAR for your platform
+#endif
+
+/*
+ * When an interrupt happens on a CP0 register read instruction, CPU may
+ * lock up or read corrupted values of CP0 registers after it enters
+ * the exception handler.
+ *
+ * This workaround makes sure that we read a "safe" CP0 register as the
+ * first thing in the exception handler, which breaks one of the
+ * pre-conditions for this problem.
+ */
+#ifndef R5432_CP0_INTERRUPT_WAR
+#error Check setting of R5432_CP0_INTERRUPT_WAR for your platform
+#endif
+
+/*
+ * Workaround for the Sibyte M3 errata the text of which can be found at
+ *
+ * http://sibyte.broadcom.com/hw/bcm1250/docs/pass2errata.txt
+ *
+ * This will enable the use of a special TLB refill handler which does a
+ * consistency check on the information in c0_badvaddr and c0_entryhi and
+ * will just return and take the exception again if the information was
+ * found to be inconsistent.
+ */
+#ifndef BCM1250_M3_WAR
+#error Check setting of BCM1250_M3_WAR for your platform
+#endif
+
+/*
+ * This is a DUART workaround related to glitches around register accesses
+ */
+#ifndef SIBYTE_1956_WAR
+#error Check setting of SIBYTE_1956_WAR for your platform
+#endif
+
+/*
+ * Fill buffers not flushed on CACHE instructions
+ *
+ * Hit_Invalidate_I cacheops invalidate an icache line but the refill
+ * for that line can get stale data from the fill buffer instead of
+ * accessing memory if the previous icache miss was also to that line.
+ *
+ * Workaround: generate an icache refill from a different line
+ *
+ * Affects:
+ * MIPS 4K RTL revision <3.0, PRID revision <4
+ */
+#ifndef MIPS4K_ICACHE_REFILL_WAR
+#error Check setting of MIPS4K_ICACHE_REFILL_WAR for your platform
+#endif
+
+/*
+ * Missing implicit forced flush of evictions caused by CACHE
+ * instruction
+ *
+ * Evictions caused by a CACHE instructions are not forced on to the
+ * bus. The BIU gives higher priority to fetches than to the data from
+ * the eviction buffer and no collision detection is performed between
+ * fetches and pending data from the eviction buffer.
+ *
+ * Workaround: Execute a SYNC instruction after the cache instruction
+ *
+ * Affects:
+ * MIPS 5Kc,5Kf RTL revision <2.3, PRID revision <8
+ * MIPS 20Kc RTL revision <4.0, PRID revision <?
+ */
+#ifndef MIPS_CACHE_SYNC_WAR
+#error Check setting of MIPS_CACHE_SYNC_WAR for your platform
+#endif
+
+/*
+ * From TX49/H2 manual: "If the instruction (i.e. CACHE) is issued for
+ * the line which this instruction itself exists, the following
+ * operation is not guaranteed."
+ *
+ * Workaround: do two phase flushing for Index_Invalidate_I
+ */
+#ifndef TX49XX_ICACHE_INDEX_INV_WAR
+#error Check setting of TX49XX_ICACHE_INDEX_INV_WAR for your platform
+#endif
+
+/*
+ * On the RM9000 there is a problem which makes the CreateDirtyExclusive
+ * eache operation unusable on SMP systems.
+ */
+#ifndef RM9000_CDEX_SMP_WAR
+#error Check setting of RM9000_CDEX_SMP_WAR for your platform
+#endif
+
+/*
+ * The RM7000 processors and the E9000 cores have a bug (though PMC-Sierra
+ * opposes it being called that) where invalid instructions in the same
+ * I-cache line worth of instructions being fetched may case spurious
+ * exceptions.
+ */
+#ifndef ICACHE_REFILLS_WORKAROUND_WAR
+#error Check setting of ICACHE_REFILLS_WORKAROUND_WAR for your platform
+#endif
+
+/*
+ * On the R10000 up to version 2.6 (not sure about 2.7) there is a bug that
+ * may cause ll / sc and lld / scd sequences to execute non-atomically.
+ */
+#ifndef R10000_LLSC_WAR
+#error Check setting of R10000_LLSC_WAR for your platform
+#endif
+
+/*
+ * 34K core erratum: "Problems Executing the TLBR Instruction"
+ */
+#ifndef MIPS34K_MISSED_ITLB_WAR
+#error Check setting of MIPS34K_MISSED_ITLB_WAR for your platform
+#endif
+
+#endif /* _ASM_WAR_H */
diff --git a/arch/mips/include/asm/watch.h b/arch/mips/include/asm/watch.h
new file mode 100644
index 00000000..20126ec7
--- /dev/null
+++ b/arch/mips/include/asm/watch.h
@@ -0,0 +1,32 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 David Daney
+ */
+#ifndef _ASM_WATCH_H
+#define _ASM_WATCH_H
+
+#include <linux/bitops.h>
+
+#include <asm/mipsregs.h>
+
+void mips_install_watch_registers(void);
+void mips_read_watch_registers(void);
+void mips_clear_watch_registers(void);
+void mips_probe_watch_registers(struct cpuinfo_mips *c);
+
+#ifdef CONFIG_HARDWARE_WATCHPOINTS
+#define __restore_watch() do { \
+ if (unlikely(test_bit(TIF_LOAD_WATCH, \
+ &current_thread_info()->flags))) { \
+ mips_install_watch_registers(); \
+ } \
+} while (0)
+
+#else
+#define __restore_watch() do {} while (0)
+#endif
+
+#endif /* _ASM_WATCH_H */
diff --git a/arch/mips/include/asm/wbflush.h b/arch/mips/include/asm/wbflush.h
new file mode 100644
index 00000000..eadc0ac4
--- /dev/null
+++ b/arch/mips/include/asm/wbflush.h
@@ -0,0 +1,34 @@
+/*
+ * Header file for using the wbflush routine
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1998 Harald Koerfgen
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#ifndef _ASM_WBFLUSH_H
+#define _ASM_WBFLUSH_H
+
+
+#ifdef CONFIG_CPU_HAS_WB
+
+extern void (*__wbflush)(void);
+extern void wbflush_setup(void);
+
+#define wbflush() \
+ do { \
+ __sync(); \
+ __wbflush(); \
+ } while (0)
+
+#else /* !CONFIG_CPU_HAS_WB */
+
+#define wbflush_setup() do { } while (0)
+
+#define wbflush() fast_iob()
+
+#endif /* !CONFIG_CPU_HAS_WB */
+
+#endif /* _ASM_WBFLUSH_H */
diff --git a/arch/mips/include/asm/xor.h b/arch/mips/include/asm/xor.h
new file mode 100644
index 00000000..c82eb12a
--- /dev/null
+++ b/arch/mips/include/asm/xor.h
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff --git a/arch/mips/include/asm/xtalk/xtalk.h b/arch/mips/include/asm/xtalk/xtalk.h
new file mode 100644
index 00000000..79bac882
--- /dev/null
+++ b/arch/mips/include/asm/xtalk/xtalk.h
@@ -0,0 +1,52 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * xtalk.h -- platform-independent crosstalk interface, derived from
+ * IRIX <sys/PCI/bridge.h>, revision 1.38.
+ *
+ * Copyright (C) 1995 - 1997, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_XTALK_XTALK_H
+#define _ASM_XTALK_XTALK_H
+
+#ifndef __ASSEMBLY__
+/*
+ * User-level device driver visible types
+ */
+typedef char xwidgetnum_t; /* xtalk widget number (0..15) */
+
+#define XWIDGET_NONE -1
+
+typedef int xwidget_part_num_t; /* xtalk widget part number */
+
+#define XWIDGET_PART_NUM_NONE -1
+
+typedef int xwidget_rev_num_t; /* xtalk widget revision number */
+
+#define XWIDGET_REV_NUM_NONE -1
+
+typedef int xwidget_mfg_num_t; /* xtalk widget manufacturing ID */
+
+#define XWIDGET_MFG_NUM_NONE -1
+
+typedef struct xtalk_piomap_s *xtalk_piomap_t;
+
+/* It is often convenient to fold the XIO target port
+ * number into the XIO address.
+ */
+#define XIO_NOWHERE (0xFFFFFFFFFFFFFFFFull)
+#define XIO_ADDR_BITS (0x0000FFFFFFFFFFFFull)
+#define XIO_PORT_BITS (0xF000000000000000ull)
+#define XIO_PORT_SHIFT (60)
+
+#define XIO_PACKED(x) (((x)&XIO_PORT_BITS) != 0)
+#define XIO_ADDR(x) ((x)&XIO_ADDR_BITS)
+#define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT))
+#define XIO_PACK(p, o) ((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS))
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_XTALK_XTALK_H */
diff --git a/arch/mips/include/asm/xtalk/xwidget.h b/arch/mips/include/asm/xtalk/xwidget.h
new file mode 100644
index 00000000..b4a13d74
--- /dev/null
+++ b/arch/mips/include/asm/xtalk/xwidget.h
@@ -0,0 +1,167 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * xwidget.h - generic crosstalk widget header file, derived from IRIX
+ * <sys/xtalk/xtalkwidget.h>, revision 1.32.
+ *
+ * Copyright (C) 1996, 1999 Silcon Graphics, Inc.
+ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
+ */
+#ifndef _ASM_XTALK_XWIDGET_H
+#define _ASM_XTALK_XWIDGET_H
+
+#include <linux/types.h>
+#include <asm/xtalk/xtalk.h>
+
+#define WIDGET_ID 0x04
+#define WIDGET_STATUS 0x0c
+#define WIDGET_ERR_UPPER_ADDR 0x14
+#define WIDGET_ERR_LOWER_ADDR 0x1c
+#define WIDGET_CONTROL 0x24
+#define WIDGET_REQ_TIMEOUT 0x2c
+#define WIDGET_INTDEST_UPPER_ADDR 0x34
+#define WIDGET_INTDEST_LOWER_ADDR 0x3c
+#define WIDGET_ERR_CMD_WORD 0x44
+#define WIDGET_LLP_CFG 0x4c
+#define WIDGET_TFLUSH 0x54
+
+/* WIDGET_ID */
+#define WIDGET_REV_NUM 0xf0000000
+#define WIDGET_PART_NUM 0x0ffff000
+#define WIDGET_MFG_NUM 0x00000ffe
+#define WIDGET_REV_NUM_SHFT 28
+#define WIDGET_PART_NUM_SHFT 12
+#define WIDGET_MFG_NUM_SHFT 1
+
+#define XWIDGET_PART_NUM(widgetid) (((widgetid) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT)
+#define XWIDGET_REV_NUM(widgetid) (((widgetid) & WIDGET_REV_NUM) >> WIDGET_REV_NUM_SHFT)
+#define XWIDGET_MFG_NUM(widgetid) (((widgetid) & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT)
+
+/* WIDGET_STATUS */
+#define WIDGET_LLP_REC_CNT 0xff000000
+#define WIDGET_LLP_TX_CNT 0x00ff0000
+#define WIDGET_PENDING 0x0000001f
+
+/* WIDGET_ERR_UPPER_ADDR */
+#define WIDGET_ERR_UPPER_ADDR_ONLY 0x0000ffff
+
+/* WIDGET_CONTROL */
+#define WIDGET_F_BAD_PKT 0x00010000
+#define WIDGET_LLP_XBAR_CRD 0x0000f000
+#define WIDGET_LLP_XBAR_CRD_SHFT 12
+#define WIDGET_CLR_RLLP_CNT 0x00000800
+#define WIDGET_CLR_TLLP_CNT 0x00000400
+#define WIDGET_SYS_END 0x00000200
+#define WIDGET_MAX_TRANS 0x000001f0
+#define WIDGET_WIDGET_ID 0x0000000f
+
+/* WIDGET_INTDEST_UPPER_ADDR */
+#define WIDGET_INT_VECTOR 0xff000000
+#define WIDGET_INT_VECTOR_SHFT 24
+#define WIDGET_TARGET_ID 0x000f0000
+#define WIDGET_TARGET_ID_SHFT 16
+#define WIDGET_UPP_ADDR 0x0000ffff
+
+/* WIDGET_ERR_CMD_WORD */
+#define WIDGET_DIDN 0xf0000000
+#define WIDGET_SIDN 0x0f000000
+#define WIDGET_PACTYP 0x00f00000
+#define WIDGET_TNUM 0x000f8000
+#define WIDGET_COHERENT 0x00004000
+#define WIDGET_DS 0x00003000
+#define WIDGET_GBR 0x00000800
+#define WIDGET_VBPM 0x00000400
+#define WIDGET_ERROR 0x00000200
+#define WIDGET_BARRIER 0x00000100
+
+/* WIDGET_LLP_CFG */
+#define WIDGET_LLP_MAXRETRY 0x03ff0000
+#define WIDGET_LLP_MAXRETRY_SHFT 16
+#define WIDGET_LLP_NULLTIMEOUT 0x0000fc00
+#define WIDGET_LLP_NULLTIMEOUT_SHFT 10
+#define WIDGET_LLP_MAXBURST 0x000003ff
+#define WIDGET_LLP_MAXBURST_SHFT 0
+
+/*
+ * according to the crosstalk spec, only 32-bits access to the widget
+ * configuration registers is allowed. some widgets may allow 64-bits
+ * access but software should not depend on it. registers beyond the
+ * widget target flush register are widget dependent thus will not be
+ * defined here
+ */
+#ifndef __ASSEMBLY__
+typedef u32 widgetreg_t;
+
+/* widget configuration registers */
+typedef volatile struct widget_cfg {
+ widgetreg_t w_pad_0; /* 0x00 */
+ widgetreg_t w_id; /* 0x04 */
+ widgetreg_t w_pad_1; /* 0x08 */
+ widgetreg_t w_status; /* 0x0c */
+ widgetreg_t w_pad_2; /* 0x10 */
+ widgetreg_t w_err_upper_addr; /* 0x14 */
+ widgetreg_t w_pad_3; /* 0x18 */
+ widgetreg_t w_err_lower_addr; /* 0x1c */
+ widgetreg_t w_pad_4; /* 0x20 */
+ widgetreg_t w_control; /* 0x24 */
+ widgetreg_t w_pad_5; /* 0x28 */
+ widgetreg_t w_req_timeout; /* 0x2c */
+ widgetreg_t w_pad_6; /* 0x30 */
+ widgetreg_t w_intdest_upper_addr; /* 0x34 */
+ widgetreg_t w_pad_7; /* 0x38 */
+ widgetreg_t w_intdest_lower_addr; /* 0x3c */
+ widgetreg_t w_pad_8; /* 0x40 */
+ widgetreg_t w_err_cmd_word; /* 0x44 */
+ widgetreg_t w_pad_9; /* 0x48 */
+ widgetreg_t w_llp_cfg; /* 0x4c */
+ widgetreg_t w_pad_10; /* 0x50 */
+ widgetreg_t w_tflush; /* 0x54 */
+} widget_cfg_t;
+
+typedef struct {
+ unsigned didn:4;
+ unsigned sidn:4;
+ unsigned pactyp:4;
+ unsigned tnum:5;
+ unsigned ct:1;
+ unsigned ds:2;
+ unsigned gbr:1;
+ unsigned vbpm:1;
+ unsigned error:1;
+ unsigned bo:1;
+ unsigned other:8;
+} w_err_cmd_word_f;
+
+typedef union {
+ widgetreg_t r;
+ w_err_cmd_word_f f;
+} w_err_cmd_word_u;
+
+typedef struct xwidget_info_s *xwidget_info_t;
+
+/*
+ * Crosstalk Widget Hardware Identification, as defined in the Crosstalk spec.
+ */
+typedef struct xwidget_hwid_s {
+ xwidget_part_num_t part_num;
+ xwidget_rev_num_t rev_num;
+ xwidget_mfg_num_t mfg_num;
+} *xwidget_hwid_t;
+
+
+/*
+ * Returns 1 if a driver that handles devices described by hwid1 is able
+ * to manage a device with hardwareid hwid2. NOTE: We don't check rev
+ * numbers at all.
+ */
+#define XWIDGET_HARDWARE_ID_MATCH(hwid1, hwid2) \
+ (((hwid1)->part_num == (hwid2)->part_num) && \
+ (((hwid1)->mfg_num == XWIDGET_MFG_NUM_NONE) || \
+ ((hwid2)->mfg_num == XWIDGET_MFG_NUM_NONE) || \
+ ((hwid1)->mfg_num == (hwid2)->mfg_num)))
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_XTALK_XWIDGET_H */
diff --git a/arch/mips/jazz/Kconfig b/arch/mips/jazz/Kconfig
new file mode 100644
index 00000000..1f372b0d
--- /dev/null
+++ b/arch/mips/jazz/Kconfig
@@ -0,0 +1,33 @@
+config ACER_PICA_61
+ bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
+ depends on MACH_JAZZ && EXPERIMENTAL
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4400 133/150 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
+
+config MIPS_MAGNUM_4000
+ bool "Support for MIPS Magnum 4000"
+ depends on MACH_JAZZ
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_BIG_ENDIAN if EXPERIMENTAL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4000 100 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
+
+config OLIVETTI_M700
+ bool "Support for Olivetti M700-10"
+ depends on MACH_JAZZ
+ select DMA_NONCOHERENT
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ This is a machine with a R4000 100 MHz CPU. To compile a Linux
+ kernel that runs on these, say Y here. For details about Linux on
+ the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
+ <http://www.linux-mips.org/>.
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile
new file mode 100644
index 00000000..dd9d99bf
--- /dev/null
+++ b/arch/mips/jazz/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Jazz family specific parts of the kernel
+#
+
+obj-y := irq.o jazzdma.o reset.o setup.o
diff --git a/arch/mips/jazz/Platform b/arch/mips/jazz/Platform
new file mode 100644
index 00000000..3373788a
--- /dev/null
+++ b/arch/mips/jazz/Platform
@@ -0,0 +1,6 @@
+#
+# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
+#
+platform-$(CONFIG_MACH_JAZZ) += jazz/
+cflags-$(CONFIG_MACH_JAZZ) += -I$(srctree)/arch/mips/include/asm/mach-jazz
+load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
new file mode 100644
index 00000000..260df475
--- /dev/null
+++ b/arch/mips/jazz/irq.c
@@ -0,0 +1,161 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle
+ */
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8253.h>
+#include <asm/i8259.h>
+#include <asm/io.h>
+#include <asm/jazz.h>
+#include <asm/pgtable.h>
+
+static DEFINE_RAW_SPINLOCK(r4030_lock);
+
+static void enable_r4030_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq - JAZZ_IRQ_START);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&r4030_lock, flags);
+ mask |= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE);
+ r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask);
+ raw_spin_unlock_irqrestore(&r4030_lock, flags);
+}
+
+void disable_r4030_irq(struct irq_data *d)
+{
+ unsigned int mask = ~(1 << (d->irq - JAZZ_IRQ_START));
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&r4030_lock, flags);
+ mask &= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE);
+ r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask);
+ raw_spin_unlock_irqrestore(&r4030_lock, flags);
+}
+
+static struct irq_chip r4030_irq_type = {
+ .name = "R4030",
+ .irq_mask = disable_r4030_irq,
+ .irq_unmask = enable_r4030_irq,
+};
+
+void __init init_r4030_ints(void)
+{
+ int i;
+
+ for (i = JAZZ_IRQ_START; i <= JAZZ_IRQ_END; i++)
+ irq_set_chip_and_handler(i, &r4030_irq_type, handle_level_irq);
+
+ r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0);
+ r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */
+ r4030_read_reg32(JAZZ_R4030_INVAL_ADDR); /* clear error bits */
+}
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8259
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init arch_init_irq(void)
+{
+ /*
+ * this is a hack to get back the still needed wired mapping
+ * killed by init_mm()
+ */
+
+ /* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */
+ add_wired_entry(0x02000017, 0x03c00017, 0xe0000000, PM_64K);
+ /* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */
+ add_wired_entry(0x02400017, 0x02440017, 0xe2000000, PM_16M);
+ /* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */
+ add_wired_entry(0x01800017, 0x01000017, 0xe4000000, PM_4M);
+
+ init_i8259_irqs(); /* Integrated i8259 */
+ mips_cpu_irq_init();
+ init_r4030_ints();
+
+ change_c0_status(ST0_IM, IE_IRQ2 | IE_IRQ1);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status();
+ unsigned int irq;
+
+ if (pending & IE_IRQ4) {
+ r4030_read_reg32(JAZZ_TIMER_REGISTER);
+ do_IRQ(JAZZ_TIMER_IRQ);
+ } else if (pending & IE_IRQ2) {
+ irq = *(volatile u8 *)JAZZ_EISA_IRQ_ACK;
+ do_IRQ(irq);
+ } else if (pending & IE_IRQ1) {
+ irq = *(volatile u8 *)JAZZ_IO_IRQ_SOURCE >> 2;
+ if (likely(irq > 0))
+ do_IRQ(irq + JAZZ_IRQ_START - 1);
+ else
+ panic("Unimplemented loc_no_irq handler");
+ }
+}
+
+static void r4030_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Nothing to do ... */
+}
+
+struct clock_event_device r4030_clockevent = {
+ .name = "r4030",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .rating = 300,
+ .irq = JAZZ_TIMER_IRQ,
+ .set_mode = r4030_set_mode,
+};
+
+static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = dev_id;
+
+ cd->event_handler(cd);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction r4030_timer_irqaction = {
+ .handler = r4030_timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "R4030 timer",
+};
+
+void __init plat_time_init(void)
+{
+ struct clock_event_device *cd = &r4030_clockevent;
+ struct irqaction *action = &r4030_timer_irqaction;
+ unsigned int cpu = smp_processor_id();
+
+ BUG_ON(HZ != 100);
+
+ cd->cpumask = cpumask_of(cpu);
+ clockevents_register_device(cd);
+ action->dev_id = cd;
+ setup_irq(JAZZ_TIMER_IRQ, action);
+
+ /*
+ * Set clock to 100Hz.
+ *
+ * The R4030 timer receives an input clock of 1kHz which is divieded by
+ * a programmable 4-bit divider. This makes it fairly inflexible.
+ */
+ r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9);
+ setup_pit_timer();
+}
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
new file mode 100644
index 00000000..2d8e447c
--- /dev/null
+++ b/arch/mips/jazz/jazzdma.c
@@ -0,0 +1,558 @@
+/*
+ * Mips Jazz DMA controller support
+ * Copyright (C) 1995, 1996 by Andreas Busse
+ *
+ * NOTE: Some of the argument checking could be removed when
+ * things have settled down. Also, instead of returning 0xffffffff
+ * on failure of vdma_alloc() one could leave page #0 unused
+ * and return the more usual NULL pointer as logical address.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/spinlock.h>
+#include <linux/gfp.h>
+#include <asm/mipsregs.h>
+#include <asm/jazz.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/dma.h>
+#include <asm/jazzdma.h>
+#include <asm/pgtable.h>
+
+/*
+ * Set this to one to enable additional vdma debug code.
+ */
+#define CONF_DEBUG_VDMA 0
+
+static VDMA_PGTBL_ENTRY *pgtbl;
+
+static DEFINE_SPINLOCK(vdma_lock);
+
+/*
+ * Debug stuff
+ */
+#define vdma_debug ((CONF_DEBUG_VDMA) ? debuglvl : 0)
+
+static int debuglvl = 3;
+
+/*
+ * Initialize the pagetable with a one-to-one mapping of
+ * the first 16 Mbytes of main memory and declare all
+ * entries to be unused. Using this method will at least
+ * allow some early device driver operations to work.
+ */
+static inline void vdma_pgtbl_init(void)
+{
+ unsigned long paddr = 0;
+ int i;
+
+ for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
+ pgtbl[i].frame = paddr;
+ pgtbl[i].owner = VDMA_PAGE_EMPTY;
+ paddr += VDMA_PAGESIZE;
+ }
+}
+
+/*
+ * Initialize the Jazz R4030 dma controller
+ */
+static int __init vdma_init(void)
+{
+ /*
+ * Allocate 32k of memory for DMA page tables. This needs to be page
+ * aligned and should be uncached to avoid cache flushing after every
+ * update.
+ */
+ pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA,
+ get_order(VDMA_PGTBL_SIZE));
+ BUG_ON(!pgtbl);
+ dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE);
+ pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl);
+
+ /*
+ * Clear the R4030 translation table
+ */
+ vdma_pgtbl_init();
+
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, CPHYSADDR(pgtbl));
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE);
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
+
+ printk(KERN_INFO "VDMA: R4030 DMA pagetables initialized.\n");
+ return 0;
+}
+
+/*
+ * Allocate DMA pagetables using a simple first-fit algorithm
+ */
+unsigned long vdma_alloc(unsigned long paddr, unsigned long size)
+{
+ int first, last, pages, frame, i;
+ unsigned long laddr, flags;
+
+ /* check arguments */
+
+ if (paddr > 0x1fffffff) {
+ if (vdma_debug)
+ printk("vdma_alloc: Invalid physical address: %08lx\n",
+ paddr);
+ return VDMA_ERROR; /* invalid physical address */
+ }
+ if (size > 0x400000 || size == 0) {
+ if (vdma_debug)
+ printk("vdma_alloc: Invalid size: %08lx\n", size);
+ return VDMA_ERROR; /* invalid physical address */
+ }
+
+ spin_lock_irqsave(&vdma_lock, flags);
+ /*
+ * Find free chunk
+ */
+ pages = VDMA_PAGE(paddr + size) - VDMA_PAGE(paddr) + 1;
+ first = 0;
+ while (1) {
+ while (pgtbl[first].owner != VDMA_PAGE_EMPTY &&
+ first < VDMA_PGTBL_ENTRIES) first++;
+ if (first + pages > VDMA_PGTBL_ENTRIES) { /* nothing free */
+ spin_unlock_irqrestore(&vdma_lock, flags);
+ return VDMA_ERROR;
+ }
+
+ last = first + 1;
+ while (pgtbl[last].owner == VDMA_PAGE_EMPTY
+ && last - first < pages)
+ last++;
+
+ if (last - first == pages)
+ break; /* found */
+ first = last + 1;
+ }
+
+ /*
+ * Mark pages as allocated
+ */
+ laddr = (first << 12) + (paddr & (VDMA_PAGESIZE - 1));
+ frame = paddr & ~(VDMA_PAGESIZE - 1);
+
+ for (i = first; i < last; i++) {
+ pgtbl[i].frame = frame;
+ pgtbl[i].owner = laddr;
+ frame += VDMA_PAGESIZE;
+ }
+
+ /*
+ * Update translation table and return logical start address
+ */
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
+
+ if (vdma_debug > 1)
+ printk("vdma_alloc: Allocated %d pages starting from %08lx\n",
+ pages, laddr);
+
+ if (vdma_debug > 2) {
+ printk("LADDR: ");
+ for (i = first; i < last; i++)
+ printk("%08x ", i << 12);
+ printk("\nPADDR: ");
+ for (i = first; i < last; i++)
+ printk("%08x ", pgtbl[i].frame);
+ printk("\nOWNER: ");
+ for (i = first; i < last; i++)
+ printk("%08x ", pgtbl[i].owner);
+ printk("\n");
+ }
+
+ spin_unlock_irqrestore(&vdma_lock, flags);
+
+ return laddr;
+}
+
+EXPORT_SYMBOL(vdma_alloc);
+
+/*
+ * Free previously allocated dma translation pages
+ * Note that this does NOT change the translation table,
+ * it just marks the free'd pages as unused!
+ */
+int vdma_free(unsigned long laddr)
+{
+ int i;
+
+ i = laddr >> 12;
+
+ if (pgtbl[i].owner != laddr) {
+ printk
+ ("vdma_free: trying to free other's dma pages, laddr=%8lx\n",
+ laddr);
+ return -1;
+ }
+
+ while (i < VDMA_PGTBL_ENTRIES && pgtbl[i].owner == laddr) {
+ pgtbl[i].owner = VDMA_PAGE_EMPTY;
+ i++;
+ }
+
+ if (vdma_debug > 1)
+ printk("vdma_free: freed %ld pages starting from %08lx\n",
+ i - (laddr >> 12), laddr);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(vdma_free);
+
+/*
+ * Map certain page(s) to another physical address.
+ * Caller must have allocated the page(s) before.
+ */
+int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size)
+{
+ int first, pages;
+
+ if (laddr > 0xffffff) {
+ if (vdma_debug)
+ printk
+ ("vdma_map: Invalid logical address: %08lx\n",
+ laddr);
+ return -EINVAL; /* invalid logical address */
+ }
+ if (paddr > 0x1fffffff) {
+ if (vdma_debug)
+ printk
+ ("vdma_map: Invalid physical address: %08lx\n",
+ paddr);
+ return -EINVAL; /* invalid physical address */
+ }
+
+ pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
+ first = laddr >> 12;
+ if (vdma_debug)
+ printk("vdma_remap: first=%x, pages=%x\n", first, pages);
+ if (first + pages > VDMA_PGTBL_ENTRIES) {
+ if (vdma_debug)
+ printk("vdma_alloc: Invalid size: %08lx\n", size);
+ return -EINVAL;
+ }
+
+ paddr &= ~(VDMA_PAGESIZE - 1);
+ while (pages > 0 && first < VDMA_PGTBL_ENTRIES) {
+ if (pgtbl[first].owner != laddr) {
+ if (vdma_debug)
+ printk("Trying to remap other's pages.\n");
+ return -EPERM; /* not owner */
+ }
+ pgtbl[first].frame = paddr;
+ paddr += VDMA_PAGESIZE;
+ first++;
+ pages--;
+ }
+
+ /*
+ * Update translation table
+ */
+ r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0);
+
+ if (vdma_debug > 2) {
+ int i;
+ pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1;
+ first = laddr >> 12;
+ printk("LADDR: ");
+ for (i = first; i < first + pages; i++)
+ printk("%08x ", i << 12);
+ printk("\nPADDR: ");
+ for (i = first; i < first + pages; i++)
+ printk("%08x ", pgtbl[i].frame);
+ printk("\nOWNER: ");
+ for (i = first; i < first + pages; i++)
+ printk("%08x ", pgtbl[i].owner);
+ printk("\n");
+ }
+
+ return 0;
+}
+
+/*
+ * Translate a physical address to a logical address.
+ * This will return the logical address of the first
+ * match.
+ */
+unsigned long vdma_phys2log(unsigned long paddr)
+{
+ int i;
+ int frame;
+
+ frame = paddr & ~(VDMA_PAGESIZE - 1);
+
+ for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) {
+ if (pgtbl[i].frame == frame)
+ break;
+ }
+
+ if (i == VDMA_PGTBL_ENTRIES)
+ return ~0UL;
+
+ return (i << 12) + (paddr & (VDMA_PAGESIZE - 1));
+}
+
+EXPORT_SYMBOL(vdma_phys2log);
+
+/*
+ * Translate a logical DMA address to a physical address
+ */
+unsigned long vdma_log2phys(unsigned long laddr)
+{
+ return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1));
+}
+
+EXPORT_SYMBOL(vdma_log2phys);
+
+/*
+ * Print DMA statistics
+ */
+void vdma_stats(void)
+{
+ int i;
+
+ printk("vdma_stats: CONFIG: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_CONFIG));
+ printk("R4030 translation table base: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE));
+ printk("R4030 translation table limit: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM));
+ printk("vdma_stats: INV_ADDR: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_INV_ADDR));
+ printk("vdma_stats: R_FAIL_ADDR: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR));
+ printk("vdma_stats: M_FAIL_ADDR: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR));
+ printk("vdma_stats: IRQ_SOURCE: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE));
+ printk("vdma_stats: I386_ERROR: %08x\n",
+ r4030_read_reg32(JAZZ_R4030_I386_ERROR));
+ printk("vdma_chnl_modes: ");
+ for (i = 0; i < 8; i++)
+ printk("%04x ",
+ (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
+ (i << 5)));
+ printk("\n");
+ printk("vdma_chnl_enables: ");
+ for (i = 0; i < 8; i++)
+ printk("%04x ",
+ (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+ (i << 5)));
+ printk("\n");
+}
+
+/*
+ * DMA transfer functions
+ */
+
+/*
+ * Enable a DMA channel. Also clear any error conditions.
+ */
+void vdma_enable(int channel)
+{
+ int status;
+
+ if (vdma_debug)
+ printk("vdma_enable: channel %d\n", channel);
+
+ /*
+ * Check error conditions first
+ */
+ status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
+ if (status & 0x400)
+ printk("VDMA: Channel %d: Address error!\n", channel);
+ if (status & 0x200)
+ printk("VDMA: Channel %d: Memory error!\n", channel);
+
+ /*
+ * Clear all interrupt flags
+ */
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+ (channel << 5)) | R4030_TC_INTR
+ | R4030_MEM_INTR | R4030_ADDR_INTR);
+
+ /*
+ * Enable the desired channel
+ */
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+ (channel << 5)) |
+ R4030_CHNL_ENABLE);
+}
+
+EXPORT_SYMBOL(vdma_enable);
+
+/*
+ * Disable a DMA channel
+ */
+void vdma_disable(int channel)
+{
+ if (vdma_debug) {
+ int status =
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+ (channel << 5));
+
+ printk("vdma_disable: channel %d\n", channel);
+ printk("VDMA: channel %d status: %04x (%s) mode: "
+ "%02x addr: %06x count: %06x\n",
+ channel, status,
+ ((status & 0x600) ? "ERROR" : "OK"),
+ (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE +
+ (channel << 5)),
+ (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ADDR +
+ (channel << 5)),
+ (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_COUNT +
+ (channel << 5)));
+ }
+
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+ (channel << 5)) &
+ ~R4030_CHNL_ENABLE);
+
+ /*
+ * After disabling a DMA channel a remote bus register should be
+ * read to ensure that the current DMA acknowledge cycle is completed.
+ */
+ *((volatile unsigned int *) JAZZ_DUMMY_DEVICE);
+}
+
+EXPORT_SYMBOL(vdma_disable);
+
+/*
+ * Set DMA mode. This function accepts the mode values used
+ * to set a PC-style DMA controller. For the SCSI and FDC
+ * channels, we also set the default modes each time we're
+ * called.
+ * NOTE: The FAST and BURST dma modes are supported by the
+ * R4030 Rev. 2 and PICA chipsets only. I leave them disabled
+ * for now.
+ */
+void vdma_set_mode(int channel, int mode)
+{
+ if (vdma_debug)
+ printk("vdma_set_mode: channel %d, mode 0x%x\n", channel,
+ mode);
+
+ switch (channel) {
+ case JAZZ_SCSI_DMA: /* scsi */
+ r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
+/* R4030_MODE_FAST | */
+/* R4030_MODE_BURST | */
+ R4030_MODE_INTR_EN |
+ R4030_MODE_WIDTH_16 |
+ R4030_MODE_ATIME_80);
+ break;
+
+ case JAZZ_FLOPPY_DMA: /* floppy */
+ r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5),
+/* R4030_MODE_FAST | */
+/* R4030_MODE_BURST | */
+ R4030_MODE_INTR_EN |
+ R4030_MODE_WIDTH_8 |
+ R4030_MODE_ATIME_120);
+ break;
+
+ case JAZZ_AUDIOL_DMA:
+ case JAZZ_AUDIOR_DMA:
+ printk("VDMA: Audio DMA not supported yet.\n");
+ break;
+
+ default:
+ printk
+ ("VDMA: vdma_set_mode() called with unsupported channel %d!\n",
+ channel);
+ }
+
+ switch (mode) {
+ case DMA_MODE_READ:
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+ (channel << 5)) &
+ ~R4030_CHNL_WRITE);
+ break;
+
+ case DMA_MODE_WRITE:
+ r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5),
+ r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE +
+ (channel << 5)) |
+ R4030_CHNL_WRITE);
+ break;
+
+ default:
+ printk
+ ("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n",
+ mode);
+ }
+}
+
+EXPORT_SYMBOL(vdma_set_mode);
+
+/*
+ * Set Transfer Address
+ */
+void vdma_set_addr(int channel, long addr)
+{
+ if (vdma_debug)
+ printk("vdma_set_addr: channel %d, addr %lx\n", channel,
+ addr);
+
+ r4030_write_reg32(JAZZ_R4030_CHNL_ADDR + (channel << 5), addr);
+}
+
+EXPORT_SYMBOL(vdma_set_addr);
+
+/*
+ * Set Transfer Count
+ */
+void vdma_set_count(int channel, int count)
+{
+ if (vdma_debug)
+ printk("vdma_set_count: channel %d, count %08x\n", channel,
+ (unsigned) count);
+
+ r4030_write_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5), count);
+}
+
+EXPORT_SYMBOL(vdma_set_count);
+
+/*
+ * Get Residual
+ */
+int vdma_get_residue(int channel)
+{
+ int residual;
+
+ residual = r4030_read_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5));
+
+ if (vdma_debug)
+ printk("vdma_get_residual: channel %d: residual=%d\n",
+ channel, residual);
+
+ return residual;
+}
+
+/*
+ * Get DMA channel enable register
+ */
+int vdma_get_enable(int channel)
+{
+ int enable;
+
+ enable = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5));
+
+ if (vdma_debug)
+ printk("vdma_get_enable: channel %d: enable=%d\n", channel,
+ enable);
+
+ return enable;
+}
+
+arch_initcall(vdma_init);
diff --git a/arch/mips/jazz/reset.c b/arch/mips/jazz/reset.c
new file mode 100644
index 00000000..dd889fe8
--- /dev/null
+++ b/arch/mips/jazz/reset.c
@@ -0,0 +1,56 @@
+/*
+ * Reset a Jazz machine.
+ *
+ * We don't trust the firmware so we do it the classic way by poking and
+ * stabbing at the keyboard controller ...
+ */
+#include <linux/jiffies.h>
+#include <asm/jazz.h>
+
+#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+
+static void jazz_write_output(unsigned char val)
+{
+ int status;
+
+ do {
+ status = jazz_kh->command;
+ } while (status & KBD_STAT_IBF);
+ jazz_kh->data = val;
+}
+
+static void jazz_write_command(unsigned char val)
+{
+ int status;
+
+ do {
+ status = jazz_kh->command;
+ } while (status & KBD_STAT_IBF);
+ jazz_kh->command = val;
+}
+
+static unsigned char jazz_read_status(void)
+{
+ return jazz_kh->command;
+}
+
+static inline void kb_wait(void)
+{
+ unsigned long start = jiffies;
+ unsigned long timeout = start + HZ/2;
+
+ do {
+ if (! (jazz_read_status() & 0x02))
+ return;
+ } while (time_before_eq(jiffies, timeout));
+}
+
+void jazz_machine_restart(char *command)
+{
+ while(1) {
+ kb_wait();
+ jazz_write_command(0xd1);
+ kb_wait();
+ jazz_write_output(0x00);
+ }
+}
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
new file mode 100644
index 00000000..0d0f054a
--- /dev/null
+++ b/arch/mips/jazz/setup.c
@@ -0,0 +1,198 @@
+/*
+ * Setup pointers to hardware-dependent routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 1998, 2001, 07, 08 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2007 by Thomas Bogendoerfer
+ */
+#include <linux/eisa.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/console.h>
+#include <linux/screen_info.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/jazz.h>
+#include <asm/jazzdma.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+
+extern asmlinkage void jazz_handle_int(void);
+
+extern void jazz_machine_restart(char *command);
+
+static struct resource jazz_io_resources[] = {
+ {
+ .start = 0x00,
+ .end = 0x1f,
+ .name = "dma1",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x40,
+ .end = 0x5f,
+ .name = "timer",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x80,
+ .end = 0x8f,
+ .name = "dma page reg",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0xc0,
+ .end = 0xdf,
+ .name = "dma2",
+ .flags = IORESOURCE_BUSY
+ }
+};
+
+void __init plat_mem_setup(void)
+{
+ int i;
+
+ /* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */
+ add_wired_entry(0x02000017, 0x03c00017, 0xe0000000, PM_64K);
+ /* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */
+ add_wired_entry(0x02400017, 0x02440017, 0xe2000000, PM_16M);
+ /* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */
+ add_wired_entry(0x01800017, 0x01000017, 0xe4000000, PM_4M);
+
+ set_io_port_base(JAZZ_PORT_BASE);
+#ifdef CONFIG_EISA
+ EISA_bus = 1;
+#endif
+
+ /* request I/O space for devices used on all i[345]86 PCs */
+ for (i = 0; i < ARRAY_SIZE(jazz_io_resources); i++)
+ request_resource(&ioport_resource, jazz_io_resources + i);
+
+ /* The RTC is outside the port address space */
+
+ _machine_restart = jazz_machine_restart;
+
+#ifdef CONFIG_VT
+ screen_info = (struct screen_info) {
+ .orig_video_cols = 160,
+ .orig_video_lines = 64,
+ .orig_video_points = 16,
+ };
+#endif
+
+ add_preferred_console("ttyS", 0, "9600");
+}
+
+#ifdef CONFIG_OLIVETTI_M700
+#define UART_CLK 1843200
+#else
+/* Some Jazz machines seem to have an 8MHz crystal clock but I don't know
+ exactly which ones ... XXX */
+#define UART_CLK (8000000 / 16) /* ( 3072000 / 16) */
+#endif
+
+#define MEMPORT(_base, _irq) \
+ { \
+ .mapbase = (_base), \
+ .membase = (void *)(_base), \
+ .irq = (_irq), \
+ .uartclk = UART_CLK, \
+ .iotype = UPIO_MEM, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ }
+
+static struct plat_serial8250_port jazz_serial_data[] = {
+ MEMPORT(JAZZ_SERIAL1_BASE, JAZZ_SERIAL1_IRQ),
+ MEMPORT(JAZZ_SERIAL2_BASE, JAZZ_SERIAL2_IRQ),
+ { },
+};
+
+static struct platform_device jazz_serial8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = jazz_serial_data,
+ },
+};
+
+static struct resource jazz_esp_rsrc[] = {
+ {
+ .start = JAZZ_SCSI_BASE,
+ .end = JAZZ_SCSI_BASE + 31,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = JAZZ_SCSI_DMA,
+ .end = JAZZ_SCSI_DMA,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = JAZZ_SCSI_IRQ,
+ .end = JAZZ_SCSI_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device jazz_esp_pdev = {
+ .name = "jazz_esp",
+ .num_resources = ARRAY_SIZE(jazz_esp_rsrc),
+ .resource = jazz_esp_rsrc
+};
+
+static struct resource jazz_sonic_rsrc[] = {
+ {
+ .start = JAZZ_ETHERNET_BASE,
+ .end = JAZZ_ETHERNET_BASE + 0xff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = JAZZ_ETHERNET_IRQ,
+ .end = JAZZ_ETHERNET_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device jazz_sonic_pdev = {
+ .name = "jazzsonic",
+ .num_resources = ARRAY_SIZE(jazz_sonic_rsrc),
+ .resource = jazz_sonic_rsrc
+};
+
+static struct resource jazz_cmos_rsrc[] = {
+ {
+ .start = 0x70,
+ .end = 0x71,
+ .flags = IORESOURCE_IO
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device jazz_cmos_pdev = {
+ .name = "rtc_cmos",
+ .num_resources = ARRAY_SIZE(jazz_cmos_rsrc),
+ .resource = jazz_cmos_rsrc
+};
+
+static struct platform_device pcspeaker_pdev = {
+ .name = "pcspkr",
+ .id = -1,
+};
+
+static int __init jazz_setup_devinit(void)
+{
+ platform_device_register(&jazz_serial8250_device);
+ platform_device_register(&jazz_esp_pdev);
+ platform_device_register(&jazz_sonic_pdev);
+ platform_device_register(&jazz_cmos_pdev);
+ platform_device_register(&pcspeaker_pdev);
+
+ return 0;
+}
+
+device_initcall(jazz_setup_devinit);
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
new file mode 100644
index 00000000..3e7141f0
--- /dev/null
+++ b/arch/mips/jz4740/Kconfig
@@ -0,0 +1,12 @@
+choice
+ prompt "Machine type"
+ depends on MACH_JZ4740
+ default JZ4740_QI_LB60
+
+config JZ4740_QI_LB60
+ bool "Qi Hardware Ben NanoNote"
+
+endchoice
+
+config HAVE_PWM
+ bool
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
new file mode 100644
index 00000000..a9dff332
--- /dev/null
+++ b/arch/mips/jz4740/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for the Ingenic JZ4740.
+#
+
+# Object file lists.
+
+obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
+ gpio.o clock.o platform.o timer.o pwm.o serial.o
+
+obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
+
+# board specific support
+
+obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
+
+# PM support
+
+obj-$(CONFIG_PM) += pm.o
+
+ccflags-y := -Werror -Wall
diff --git a/arch/mips/jz4740/Platform b/arch/mips/jz4740/Platform
new file mode 100644
index 00000000..ba91be9c
--- /dev/null
+++ b/arch/mips/jz4740/Platform
@@ -0,0 +1,3 @@
+platform-$(CONFIG_MACH_JZ4740) += jz4740/
+cflags-$(CONFIG_MACH_JZ4740) += -I$(srctree)/arch/mips/include/asm/mach-jz4740
+load-$(CONFIG_MACH_JZ4740) += 0xffffffff80010000
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
new file mode 100644
index 00000000..c3b04be3
--- /dev/null
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -0,0 +1,495 @@
+/*
+ * linux/arch/mips/jz4740/board-qi_lb60.c
+ *
+ * QI_LB60 board support
+ *
+ * Copyright (c) 2009 Qi Hardware inc.,
+ * Author: Xiangfu Liu <xiangfu@qi-hardware.com>
+ * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or later
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/power_supply.h>
+#include <linux/power/jz4740-battery.h>
+#include <linux/power/gpio-charger.h>
+
+#include <asm/mach-jz4740/jz4740_fb.h>
+#include <asm/mach-jz4740/jz4740_mmc.h>
+#include <asm/mach-jz4740/jz4740_nand.h>
+
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/leds_pwm.h>
+
+#include <asm/mach-jz4740/platform.h>
+
+#include "clock.h"
+
+static bool is_avt2;
+
+/* GPIOs */
+#define QI_LB60_GPIO_SD_CD JZ_GPIO_PORTD(0)
+#define QI_LB60_GPIO_SD_VCC_EN_N JZ_GPIO_PORTD(2)
+
+#define QI_LB60_GPIO_KEYOUT(x) (JZ_GPIO_PORTC(10) + (x))
+#define QI_LB60_GPIO_KEYIN(x) (JZ_GPIO_PORTD(18) + (x))
+#define QI_LB60_GPIO_KEYIN8 JZ_GPIO_PORTD(26)
+
+/* NAND */
+static struct nand_ecclayout qi_lb60_ecclayout_1gb = {
+ .eccbytes = 36,
+ .eccpos = {
+ 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41
+ },
+ .oobfree = {
+ { .offset = 2, .length = 4 },
+ { .offset = 42, .length = 22 }
+ },
+};
+
+/* Early prototypes of the QI LB60 had only 1GB of NAND.
+ * In order to support these devices as well the partition and ecc layout is
+ * initialized depending on the NAND size */
+static struct mtd_partition qi_lb60_partitions_1gb[] = {
+ {
+ .name = "NAND BOOT partition",
+ .offset = 0 * 0x100000,
+ .size = 4 * 0x100000,
+ },
+ {
+ .name = "NAND KERNEL partition",
+ .offset = 4 * 0x100000,
+ .size = 4 * 0x100000,
+ },
+ {
+ .name = "NAND ROOTFS partition",
+ .offset = 8 * 0x100000,
+ .size = (504 + 512) * 0x100000,
+ },
+};
+
+static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
+ .eccbytes = 72,
+ .eccpos = {
+ 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83
+ },
+ .oobfree = {
+ { .offset = 2, .length = 10 },
+ { .offset = 84, .length = 44 },
+ },
+};
+
+static struct mtd_partition qi_lb60_partitions_2gb[] = {
+ {
+ .name = "NAND BOOT partition",
+ .offset = 0 * 0x100000,
+ .size = 4 * 0x100000,
+ },
+ {
+ .name = "NAND KERNEL partition",
+ .offset = 4 * 0x100000,
+ .size = 4 * 0x100000,
+ },
+ {
+ .name = "NAND ROOTFS partition",
+ .offset = 8 * 0x100000,
+ .size = (504 + 512 + 1024) * 0x100000,
+ },
+};
+
+static void qi_lb60_nand_ident(struct platform_device *pdev,
+ struct nand_chip *chip, struct mtd_partition **partitions,
+ int *num_partitions)
+{
+ if (chip->page_shift == 12) {
+ chip->ecc.layout = &qi_lb60_ecclayout_2gb;
+ *partitions = qi_lb60_partitions_2gb;
+ *num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb);
+ } else {
+ chip->ecc.layout = &qi_lb60_ecclayout_1gb;
+ *partitions = qi_lb60_partitions_1gb;
+ *num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb);
+ }
+}
+
+static struct jz_nand_platform_data qi_lb60_nand_pdata = {
+ .ident_callback = qi_lb60_nand_ident,
+ .busy_gpio = 94,
+};
+
+/* Keyboard*/
+
+#define KEY_QI_QI KEY_F13
+#define KEY_QI_UPRED KEY_RIGHTALT
+#define KEY_QI_VOLUP KEY_VOLUMEUP
+#define KEY_QI_VOLDOWN KEY_VOLUMEDOWN
+#define KEY_QI_FN KEY_LEFTCTRL
+
+static const uint32_t qi_lb60_keymap[] = {
+ KEY(0, 0, KEY_F1), /* S2 */
+ KEY(0, 1, KEY_F2), /* S3 */
+ KEY(0, 2, KEY_F3), /* S4 */
+ KEY(0, 3, KEY_F4), /* S5 */
+ KEY(0, 4, KEY_F5), /* S6 */
+ KEY(0, 5, KEY_F6), /* S7 */
+ KEY(0, 6, KEY_F7), /* S8 */
+
+ KEY(1, 0, KEY_Q), /* S10 */
+ KEY(1, 1, KEY_W), /* S11 */
+ KEY(1, 2, KEY_E), /* S12 */
+ KEY(1, 3, KEY_R), /* S13 */
+ KEY(1, 4, KEY_T), /* S14 */
+ KEY(1, 5, KEY_Y), /* S15 */
+ KEY(1, 6, KEY_U), /* S16 */
+ KEY(1, 7, KEY_I), /* S17 */
+ KEY(2, 0, KEY_A), /* S18 */
+ KEY(2, 1, KEY_S), /* S19 */
+ KEY(2, 2, KEY_D), /* S20 */
+ KEY(2, 3, KEY_F), /* S21 */
+ KEY(2, 4, KEY_G), /* S22 */
+ KEY(2, 5, KEY_H), /* S23 */
+ KEY(2, 6, KEY_J), /* S24 */
+ KEY(2, 7, KEY_K), /* S25 */
+ KEY(3, 0, KEY_ESC), /* S26 */
+ KEY(3, 1, KEY_Z), /* S27 */
+ KEY(3, 2, KEY_X), /* S28 */
+ KEY(3, 3, KEY_C), /* S29 */
+ KEY(3, 4, KEY_V), /* S30 */
+ KEY(3, 5, KEY_B), /* S31 */
+ KEY(3, 6, KEY_N), /* S32 */
+ KEY(3, 7, KEY_M), /* S33 */
+ KEY(4, 0, KEY_TAB), /* S34 */
+ KEY(4, 1, KEY_CAPSLOCK), /* S35 */
+ KEY(4, 2, KEY_BACKSLASH), /* S36 */
+ KEY(4, 3, KEY_APOSTROPHE), /* S37 */
+ KEY(4, 4, KEY_COMMA), /* S38 */
+ KEY(4, 5, KEY_DOT), /* S39 */
+ KEY(4, 6, KEY_SLASH), /* S40 */
+ KEY(4, 7, KEY_UP), /* S41 */
+ KEY(5, 0, KEY_O), /* S42 */
+ KEY(5, 1, KEY_L), /* S43 */
+ KEY(5, 2, KEY_EQUAL), /* S44 */
+ KEY(5, 3, KEY_QI_UPRED), /* S45 */
+ KEY(5, 4, KEY_SPACE), /* S46 */
+ KEY(5, 5, KEY_QI_QI), /* S47 */
+ KEY(5, 6, KEY_RIGHTCTRL), /* S48 */
+ KEY(5, 7, KEY_LEFT), /* S49 */
+ KEY(6, 0, KEY_F8), /* S50 */
+ KEY(6, 1, KEY_P), /* S51 */
+ KEY(6, 2, KEY_BACKSPACE),/* S52 */
+ KEY(6, 3, KEY_ENTER), /* S53 */
+ KEY(6, 4, KEY_QI_VOLUP), /* S54 */
+ KEY(6, 5, KEY_QI_VOLDOWN), /* S55 */
+ KEY(6, 6, KEY_DOWN), /* S56 */
+ KEY(6, 7, KEY_RIGHT), /* S57 */
+
+ KEY(7, 0, KEY_LEFTSHIFT), /* S58 */
+ KEY(7, 1, KEY_LEFTALT), /* S59 */
+ KEY(7, 2, KEY_QI_FN), /* S60 */
+};
+
+static const struct matrix_keymap_data qi_lb60_keymap_data = {
+ .keymap = qi_lb60_keymap,
+ .keymap_size = ARRAY_SIZE(qi_lb60_keymap),
+};
+
+static const unsigned int qi_lb60_keypad_cols[] = {
+ QI_LB60_GPIO_KEYOUT(0),
+ QI_LB60_GPIO_KEYOUT(1),
+ QI_LB60_GPIO_KEYOUT(2),
+ QI_LB60_GPIO_KEYOUT(3),
+ QI_LB60_GPIO_KEYOUT(4),
+ QI_LB60_GPIO_KEYOUT(5),
+ QI_LB60_GPIO_KEYOUT(6),
+ QI_LB60_GPIO_KEYOUT(7),
+};
+
+static const unsigned int qi_lb60_keypad_rows[] = {
+ QI_LB60_GPIO_KEYIN(0),
+ QI_LB60_GPIO_KEYIN(1),
+ QI_LB60_GPIO_KEYIN(2),
+ QI_LB60_GPIO_KEYIN(3),
+ QI_LB60_GPIO_KEYIN(4),
+ QI_LB60_GPIO_KEYIN(5),
+ QI_LB60_GPIO_KEYIN(6),
+ QI_LB60_GPIO_KEYIN8,
+};
+
+static struct matrix_keypad_platform_data qi_lb60_pdata = {
+ .keymap_data = &qi_lb60_keymap_data,
+ .col_gpios = qi_lb60_keypad_cols,
+ .row_gpios = qi_lb60_keypad_rows,
+ .num_col_gpios = ARRAY_SIZE(qi_lb60_keypad_cols),
+ .num_row_gpios = ARRAY_SIZE(qi_lb60_keypad_rows),
+ .col_scan_delay_us = 10,
+ .debounce_ms = 10,
+ .wakeup = 1,
+ .active_low = 1,
+};
+
+static struct platform_device qi_lb60_keypad = {
+ .name = "matrix-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &qi_lb60_pdata,
+ },
+};
+
+/* Display */
+static struct fb_videomode qi_lb60_video_modes[] = {
+ {
+ .name = "320x240",
+ .xres = 320,
+ .yres = 240,
+ .refresh = 30,
+ .left_margin = 140,
+ .right_margin = 273,
+ .upper_margin = 20,
+ .lower_margin = 2,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct jz4740_fb_platform_data qi_lb60_fb_pdata = {
+ .width = 60,
+ .height = 45,
+ .num_modes = ARRAY_SIZE(qi_lb60_video_modes),
+ .modes = qi_lb60_video_modes,
+ .bpp = 24,
+ .lcd_type = JZ_LCD_TYPE_8BIT_SERIAL,
+ .pixclk_falling_edge = 1,
+};
+
+struct spi_gpio_platform_data spigpio_platform_data = {
+ .sck = JZ_GPIO_PORTC(23),
+ .mosi = JZ_GPIO_PORTC(22),
+ .miso = -1,
+ .num_chipselect = 1,
+};
+
+static struct platform_device spigpio_device = {
+ .name = "spi_gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &spigpio_platform_data,
+ },
+};
+
+static struct spi_board_info qi_lb60_spi_board_info[] = {
+ {
+ .modalias = "ili8960",
+ .controller_data = (void *)JZ_GPIO_PORTC(21),
+ .chip_select = 0,
+ .bus_num = 1,
+ .max_speed_hz = 30 * 1000,
+ .mode = SPI_3WIRE,
+ },
+};
+
+/* Battery */
+static struct jz_battery_platform_data qi_lb60_battery_pdata = {
+ .gpio_charge = JZ_GPIO_PORTC(27),
+ .gpio_charge_active_low = 1,
+ .info = {
+ .name = "battery",
+ .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .voltage_max_design = 4200000,
+ .voltage_min_design = 3600000,
+ },
+};
+
+/* GPIO Key: power */
+static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = {
+ [0] = {
+ .code = KEY_POWER,
+ .gpio = JZ_GPIO_PORTD(29),
+ .active_low = 1,
+ .desc = "Power",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data qi_lb60_gpio_keys_data = {
+ .nbuttons = ARRAY_SIZE(qi_lb60_gpio_keys_buttons),
+ .buttons = qi_lb60_gpio_keys_buttons,
+};
+
+static struct platform_device qi_lb60_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &qi_lb60_gpio_keys_data,
+ }
+};
+
+static struct jz4740_mmc_platform_data qi_lb60_mmc_pdata = {
+ .gpio_card_detect = QI_LB60_GPIO_SD_CD,
+ .gpio_read_only = -1,
+ .gpio_power = QI_LB60_GPIO_SD_VCC_EN_N,
+ .power_active_low = 1,
+};
+
+/* OHCI */
+static struct regulator_consumer_supply avt2_usb_regulator_consumer =
+ REGULATOR_SUPPLY("vbus", "jz4740-ohci");
+
+static struct regulator_init_data avt2_usb_regulator_init_data = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &avt2_usb_regulator_consumer,
+ .constraints = {
+ .name = "USB power",
+ .min_uV = 5000000,
+ .max_uV = 5000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct fixed_voltage_config avt2_usb_regulator_data = {
+ .supply_name = "USB power",
+ .microvolts = 5000000,
+ .gpio = JZ_GPIO_PORTB(17),
+ .init_data = &avt2_usb_regulator_init_data,
+};
+
+static struct platform_device avt2_usb_regulator_device = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &avt2_usb_regulator_data,
+ }
+};
+
+/* beeper */
+static struct platform_device qi_lb60_pwm_beeper = {
+ .name = "pwm-beeper",
+ .id = -1,
+ .dev = {
+ .platform_data = (void *)4,
+ },
+};
+
+/* charger */
+static char *qi_lb60_batteries[] = {
+ "battery",
+};
+
+static struct gpio_charger_platform_data qi_lb60_charger_pdata = {
+ .name = "usb",
+ .type = POWER_SUPPLY_TYPE_USB,
+ .gpio = JZ_GPIO_PORTD(28),
+ .gpio_active_low = 1,
+ .supplied_to = qi_lb60_batteries,
+ .num_supplicants = ARRAY_SIZE(qi_lb60_batteries),
+};
+
+static struct platform_device qi_lb60_charger_device = {
+ .name = "gpio-charger",
+ .dev = {
+ .platform_data = &qi_lb60_charger_pdata,
+ },
+};
+
+
+static struct platform_device *jz_platform_devices[] __initdata = {
+ &jz4740_udc_device,
+ &jz4740_mmc_device,
+ &jz4740_nand_device,
+ &qi_lb60_keypad,
+ &spigpio_device,
+ &jz4740_framebuffer_device,
+ &jz4740_pcm_device,
+ &jz4740_i2s_device,
+ &jz4740_codec_device,
+ &jz4740_rtc_device,
+ &jz4740_adc_device,
+ &qi_lb60_gpio_keys,
+ &qi_lb60_pwm_beeper,
+ &qi_lb60_charger_device,
+};
+
+static void __init board_gpio_setup(void)
+{
+ /* We only need to enable/disable pullup here for pins used in generic
+ * drivers. Everything else is done by the drivers themselves. */
+ jz_gpio_disable_pullup(QI_LB60_GPIO_SD_VCC_EN_N);
+ jz_gpio_disable_pullup(QI_LB60_GPIO_SD_CD);
+}
+
+static int __init qi_lb60_init_platform_devices(void)
+{
+ jz4740_framebuffer_device.dev.platform_data = &qi_lb60_fb_pdata;
+ jz4740_nand_device.dev.platform_data = &qi_lb60_nand_pdata;
+ jz4740_adc_device.dev.platform_data = &qi_lb60_battery_pdata;
+ jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata;
+
+ jz4740_serial_device_register();
+
+ spi_register_board_info(qi_lb60_spi_board_info,
+ ARRAY_SIZE(qi_lb60_spi_board_info));
+
+ if (is_avt2) {
+ platform_device_register(&avt2_usb_regulator_device);
+ platform_device_register(&jz4740_usb_ohci_device);
+ }
+
+ return platform_add_devices(jz_platform_devices,
+ ARRAY_SIZE(jz_platform_devices));
+
+}
+
+struct jz4740_clock_board_data jz4740_clock_bdata = {
+ .ext_rate = 12000000,
+ .rtc_rate = 32768,
+};
+
+static __init int board_avt2(char *str)
+{
+ qi_lb60_mmc_pdata.card_detect_active_low = 1;
+ is_avt2 = true;
+
+ return 1;
+}
+__setup("avt2", board_avt2);
+
+static int __init qi_lb60_board_setup(void)
+{
+ printk(KERN_INFO "Qi Hardware JZ4740 QI %s setup\n",
+ is_avt2 ? "AVT2" : "LB60");
+
+ board_gpio_setup();
+
+ if (qi_lb60_init_platform_devices())
+ panic("Failed to initialize platform devices\n");
+
+ return 0;
+}
+arch_initcall(qi_lb60_board_setup);
diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c
new file mode 100644
index 00000000..330a0f2b
--- /dev/null
+++ b/arch/mips/jz4740/clock-debugfs.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC clock support debugfs entries
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include <asm/mach-jz4740/clock.h>
+#include "clock.h"
+
+static struct dentry *jz4740_clock_debugfs;
+
+static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
+{
+ struct clk *clk = data;
+ *value = clk_is_enabled(clk);
+
+ return 0;
+}
+
+static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
+{
+ struct clk *clk = data;
+
+ if (value)
+ return clk_enable(clk);
+ else
+ clk_disable(clk);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
+ jz4740_clock_debugfs_show_enabled,
+ jz4740_clock_debugfs_set_enabled,
+ "%llu\n");
+
+static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
+{
+ struct clk *clk = data;
+ *value = clk_get_rate(clk);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
+ jz4740_clock_debugfs_show_rate,
+ NULL,
+ "%llu\n");
+
+void jz4740_clock_debugfs_add_clk(struct clk *clk)
+{
+ if (!jz4740_clock_debugfs)
+ return;
+
+ clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
+ debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
+ &jz4740_clock_debugfs_ops_rate);
+ debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
+ &jz4740_clock_debugfs_ops_enabled);
+
+ if (clk->parent) {
+ char parent_path[100];
+ snprintf(parent_path, 100, "../%s", clk->parent->name);
+ clk->debugfs_parent_entry = debugfs_create_symlink("parent",
+ clk->debugfs_entry,
+ parent_path);
+ }
+}
+
+/* TODO: Locking */
+void jz4740_clock_debugfs_update_parent(struct clk *clk)
+{
+ if (clk->debugfs_parent_entry)
+ debugfs_remove(clk->debugfs_parent_entry);
+
+ if (clk->parent) {
+ char parent_path[100];
+ snprintf(parent_path, 100, "../%s", clk->parent->name);
+ clk->debugfs_parent_entry = debugfs_create_symlink("parent",
+ clk->debugfs_entry,
+ parent_path);
+ } else {
+ clk->debugfs_parent_entry = NULL;
+ }
+}
+
+void jz4740_clock_debugfs_init(void)
+{
+ jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
+ if (IS_ERR(jz4740_clock_debugfs))
+ jz4740_clock_debugfs = NULL;
+}
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
new file mode 100644
index 00000000..118a8a55
--- /dev/null
+++ b/arch/mips/jz4740/clock.c
@@ -0,0 +1,924 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC clock support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+
+#include <asm/mach-jz4740/clock.h>
+#include <asm/mach-jz4740/base.h>
+
+#include "clock.h"
+
+#define JZ_REG_CLOCK_CTRL 0x00
+#define JZ_REG_CLOCK_LOW_POWER 0x04
+#define JZ_REG_CLOCK_PLL 0x10
+#define JZ_REG_CLOCK_GATE 0x20
+#define JZ_REG_CLOCK_SLEEP_CTRL 0x24
+#define JZ_REG_CLOCK_I2S 0x60
+#define JZ_REG_CLOCK_LCD 0x64
+#define JZ_REG_CLOCK_MMC 0x68
+#define JZ_REG_CLOCK_UHC 0x6C
+#define JZ_REG_CLOCK_SPI 0x74
+
+#define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31)
+#define JZ_CLOCK_CTRL_KO_ENABLE BIT(30)
+#define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29)
+#define JZ_CLOCK_CTRL_UDIV_MASK 0x1f800000
+#define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22)
+#define JZ_CLOCK_CTRL_PLL_HALF BIT(21)
+#define JZ_CLOCK_CTRL_LDIV_MASK 0x001f0000
+#define JZ_CLOCK_CTRL_UDIV_OFFSET 23
+#define JZ_CLOCK_CTRL_LDIV_OFFSET 16
+#define JZ_CLOCK_CTRL_MDIV_OFFSET 12
+#define JZ_CLOCK_CTRL_PDIV_OFFSET 8
+#define JZ_CLOCK_CTRL_HDIV_OFFSET 4
+#define JZ_CLOCK_CTRL_CDIV_OFFSET 0
+
+#define JZ_CLOCK_GATE_UART0 BIT(0)
+#define JZ_CLOCK_GATE_TCU BIT(1)
+#define JZ_CLOCK_GATE_RTC BIT(2)
+#define JZ_CLOCK_GATE_I2C BIT(3)
+#define JZ_CLOCK_GATE_SPI BIT(4)
+#define JZ_CLOCK_GATE_AIC BIT(5)
+#define JZ_CLOCK_GATE_I2S BIT(6)
+#define JZ_CLOCK_GATE_MMC BIT(7)
+#define JZ_CLOCK_GATE_ADC BIT(8)
+#define JZ_CLOCK_GATE_CIM BIT(9)
+#define JZ_CLOCK_GATE_LCD BIT(10)
+#define JZ_CLOCK_GATE_UDC BIT(11)
+#define JZ_CLOCK_GATE_DMAC BIT(12)
+#define JZ_CLOCK_GATE_IPU BIT(13)
+#define JZ_CLOCK_GATE_UHC BIT(14)
+#define JZ_CLOCK_GATE_UART1 BIT(15)
+
+#define JZ_CLOCK_I2S_DIV_MASK 0x01ff
+
+#define JZ_CLOCK_LCD_DIV_MASK 0x01ff
+
+#define JZ_CLOCK_MMC_DIV_MASK 0x001f
+
+#define JZ_CLOCK_UHC_DIV_MASK 0x000f
+
+#define JZ_CLOCK_SPI_SRC_PLL BIT(31)
+#define JZ_CLOCK_SPI_DIV_MASK 0x000f
+
+#define JZ_CLOCK_PLL_M_MASK 0x01ff
+#define JZ_CLOCK_PLL_N_MASK 0x001f
+#define JZ_CLOCK_PLL_OD_MASK 0x0003
+#define JZ_CLOCK_PLL_STABLE BIT(10)
+#define JZ_CLOCK_PLL_BYPASS BIT(9)
+#define JZ_CLOCK_PLL_ENABLED BIT(8)
+#define JZ_CLOCK_PLL_STABLIZE_MASK 0x000f
+#define JZ_CLOCK_PLL_M_OFFSET 23
+#define JZ_CLOCK_PLL_N_OFFSET 18
+#define JZ_CLOCK_PLL_OD_OFFSET 16
+
+#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
+#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
+
+#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
+#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
+
+static void __iomem *jz_clock_base;
+static spinlock_t jz_clock_lock;
+static LIST_HEAD(jz_clocks);
+
+struct main_clk {
+ struct clk clk;
+ uint32_t div_offset;
+};
+
+struct divided_clk {
+ struct clk clk;
+ uint32_t reg;
+ uint32_t mask;
+};
+
+struct static_clk {
+ struct clk clk;
+ unsigned long rate;
+};
+
+static uint32_t jz_clk_reg_read(int reg)
+{
+ return readl(jz_clock_base + reg);
+}
+
+static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
+{
+ uint32_t val2;
+
+ spin_lock(&jz_clock_lock);
+ val2 = readl(jz_clock_base + reg);
+ val2 &= ~mask;
+ val2 |= val;
+ writel(val2, jz_clock_base + reg);
+ spin_unlock(&jz_clock_lock);
+}
+
+static void jz_clk_reg_set_bits(int reg, uint32_t mask)
+{
+ uint32_t val;
+
+ spin_lock(&jz_clock_lock);
+ val = readl(jz_clock_base + reg);
+ val |= mask;
+ writel(val, jz_clock_base + reg);
+ spin_unlock(&jz_clock_lock);
+}
+
+static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
+{
+ uint32_t val;
+
+ spin_lock(&jz_clock_lock);
+ val = readl(jz_clock_base + reg);
+ val &= ~mask;
+ writel(val, jz_clock_base + reg);
+ spin_unlock(&jz_clock_lock);
+}
+
+static int jz_clk_enable_gating(struct clk *clk)
+{
+ if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+ return -EINVAL;
+
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
+ return 0;
+}
+
+static int jz_clk_disable_gating(struct clk *clk)
+{
+ if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+ return -EINVAL;
+
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
+ return 0;
+}
+
+static int jz_clk_is_enabled_gating(struct clk *clk)
+{
+ if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+ return 1;
+
+ return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
+}
+
+static unsigned long jz_clk_static_get_rate(struct clk *clk)
+{
+ return ((struct static_clk *)clk)->rate;
+}
+
+static int jz_clk_ko_enable(struct clk *clk)
+{
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
+ return 0;
+}
+
+static int jz_clk_ko_disable(struct clk *clk)
+{
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
+ return 0;
+}
+
+static int jz_clk_ko_is_enabled(struct clk *clk)
+{
+ return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
+}
+
+static const int pllno[] = {1, 2, 2, 4};
+
+static unsigned long jz_clk_pll_get_rate(struct clk *clk)
+{
+ uint32_t val;
+ int m;
+ int n;
+ int od;
+
+ val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
+
+ if (val & JZ_CLOCK_PLL_BYPASS)
+ return clk_get_rate(clk->parent);
+
+ m = ((val >> 23) & 0x1ff) + 2;
+ n = ((val >> 18) & 0x1f) + 2;
+ od = (val >> 16) & 0x3;
+
+ return ((clk_get_rate(clk->parent) / n) * m) / pllno[od];
+}
+
+static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
+{
+ uint32_t reg;
+
+ reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+ if (reg & JZ_CLOCK_CTRL_PLL_HALF)
+ return jz_clk_pll_get_rate(clk->parent);
+ return jz_clk_pll_get_rate(clk->parent) >> 1;
+}
+
+static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
+
+static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
+ int div;
+
+ div = parent_rate / rate;
+ if (div > 32)
+ return parent_rate / 32;
+ else if (div < 1)
+ return parent_rate;
+
+ div &= (0x3 << (ffs(div) - 1));
+
+ return parent_rate / div;
+}
+
+static unsigned long jz_clk_main_get_rate(struct clk *clk)
+{
+ struct main_clk *mclk = (struct main_clk *)clk;
+ uint32_t div;
+
+ div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+
+ div >>= mclk->div_offset;
+ div &= 0xf;
+
+ if (div >= ARRAY_SIZE(jz_clk_main_divs))
+ div = ARRAY_SIZE(jz_clk_main_divs) - 1;
+
+ return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
+}
+
+static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct main_clk *mclk = (struct main_clk *)clk;
+ int i;
+ int div;
+ unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
+
+ rate = jz_clk_main_round_rate(clk, rate);
+
+ div = parent_rate / rate;
+
+ i = (ffs(div) - 1) << 1;
+ if (i > 0 && !(div & BIT(i-1)))
+ i -= 1;
+
+ jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
+ 0xf << mclk->div_offset);
+
+ return 0;
+}
+
+static struct clk_ops jz_clk_static_ops = {
+ .get_rate = jz_clk_static_get_rate,
+ .enable = jz_clk_enable_gating,
+ .disable = jz_clk_disable_gating,
+ .is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct static_clk jz_clk_ext = {
+ .clk = {
+ .name = "ext",
+ .gate_bit = JZ4740_CLK_NOT_GATED,
+ .ops = &jz_clk_static_ops,
+ },
+};
+
+static struct clk_ops jz_clk_pll_ops = {
+ .get_rate = jz_clk_pll_get_rate,
+};
+
+static struct clk jz_clk_pll = {
+ .name = "pll",
+ .parent = &jz_clk_ext.clk,
+ .ops = &jz_clk_pll_ops,
+};
+
+static struct clk_ops jz_clk_pll_half_ops = {
+ .get_rate = jz_clk_pll_half_get_rate,
+};
+
+static struct clk jz_clk_pll_half = {
+ .name = "pll half",
+ .parent = &jz_clk_pll,
+ .ops = &jz_clk_pll_half_ops,
+};
+
+static const struct clk_ops jz_clk_main_ops = {
+ .get_rate = jz_clk_main_get_rate,
+ .set_rate = jz_clk_main_set_rate,
+ .round_rate = jz_clk_main_round_rate,
+};
+
+static struct main_clk jz_clk_cpu = {
+ .clk = {
+ .name = "cclk",
+ .parent = &jz_clk_pll,
+ .ops = &jz_clk_main_ops,
+ },
+ .div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
+};
+
+static struct main_clk jz_clk_memory = {
+ .clk = {
+ .name = "mclk",
+ .parent = &jz_clk_pll,
+ .ops = &jz_clk_main_ops,
+ },
+ .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
+};
+
+static struct main_clk jz_clk_high_speed_peripheral = {
+ .clk = {
+ .name = "hclk",
+ .parent = &jz_clk_pll,
+ .ops = &jz_clk_main_ops,
+ },
+ .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
+};
+
+
+static struct main_clk jz_clk_low_speed_peripheral = {
+ .clk = {
+ .name = "pclk",
+ .parent = &jz_clk_pll,
+ .ops = &jz_clk_main_ops,
+ },
+ .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
+};
+
+static const struct clk_ops jz_clk_ko_ops = {
+ .enable = jz_clk_ko_enable,
+ .disable = jz_clk_ko_disable,
+ .is_enabled = jz_clk_ko_is_enabled,
+};
+
+static struct clk jz_clk_ko = {
+ .name = "cko",
+ .parent = &jz_clk_memory.clk,
+ .ops = &jz_clk_ko_ops,
+};
+
+static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
+{
+ if (parent == &jz_clk_pll)
+ jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
+ else if (parent == &jz_clk_ext.clk)
+ jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ return 0;
+}
+
+static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
+{
+ if (parent == &jz_clk_pll_half)
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
+ else if (parent == &jz_clk_ext.clk)
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ return 0;
+}
+
+static int jz_clk_udc_enable(struct clk *clk)
+{
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
+ JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+
+ return 0;
+}
+
+static int jz_clk_udc_disable(struct clk *clk)
+{
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
+ JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+
+ return 0;
+}
+
+static int jz_clk_udc_is_enabled(struct clk *clk)
+{
+ return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
+ JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+}
+
+static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
+{
+ if (parent == &jz_clk_pll_half)
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
+ else if (parent == &jz_clk_ext.clk)
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ return 0;
+}
+
+static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
+{
+ int div;
+
+ if (clk->parent == &jz_clk_ext.clk)
+ return -EINVAL;
+
+ div = clk_get_rate(clk->parent) / rate - 1;
+
+ if (div < 0)
+ div = 0;
+ else if (div > 63)
+ div = 63;
+
+ jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
+ JZ_CLOCK_CTRL_UDIV_MASK);
+ return 0;
+}
+
+static unsigned long jz_clk_udc_get_rate(struct clk *clk)
+{
+ int div;
+
+ if (clk->parent == &jz_clk_ext.clk)
+ return clk_get_rate(clk->parent);
+
+ div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
+ div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
+ div += 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static unsigned long jz_clk_divided_get_rate(struct clk *clk)
+{
+ struct divided_clk *dclk = (struct divided_clk *)clk;
+ int div;
+
+ if (clk->parent == &jz_clk_ext.clk)
+ return clk_get_rate(clk->parent);
+
+ div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct divided_clk *dclk = (struct divided_clk *)clk;
+ int div;
+
+ if (clk->parent == &jz_clk_ext.clk)
+ return -EINVAL;
+
+ div = clk_get_rate(clk->parent) / rate - 1;
+
+ if (div < 0)
+ div = 0;
+ else if (div > dclk->mask)
+ div = dclk->mask;
+
+ jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
+
+ return 0;
+}
+
+static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ int div;
+ unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
+
+ if (rate > 150000000)
+ return 150000000;
+
+ div = parent_rate / rate;
+ if (div < 1)
+ div = 1;
+ else if (div > 32)
+ div = 32;
+
+ return parent_rate / div;
+}
+
+static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int div;
+
+ if (rate > 150000000)
+ return -EINVAL;
+
+ div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
+ if (div < 0)
+ div = 0;
+ else if (div > 31)
+ div = 31;
+
+ jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
+ JZ_CLOCK_CTRL_LDIV_MASK);
+
+ return 0;
+}
+
+static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
+{
+ int div;
+
+ div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
+ div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
+
+ return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
+}
+
+static const struct clk_ops jz_clk_ops_ld = {
+ .set_rate = jz_clk_ldclk_set_rate,
+ .get_rate = jz_clk_ldclk_get_rate,
+ .round_rate = jz_clk_ldclk_round_rate,
+ .enable = jz_clk_enable_gating,
+ .disable = jz_clk_disable_gating,
+ .is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct clk jz_clk_ld = {
+ .name = "lcd",
+ .gate_bit = JZ_CLOCK_GATE_LCD,
+ .parent = &jz_clk_pll_half,
+ .ops = &jz_clk_ops_ld,
+};
+
+static const struct clk_ops jz_clk_i2s_ops = {
+ .set_rate = jz_clk_divided_set_rate,
+ .get_rate = jz_clk_divided_get_rate,
+ .enable = jz_clk_enable_gating,
+ .disable = jz_clk_disable_gating,
+ .is_enabled = jz_clk_is_enabled_gating,
+ .set_parent = jz_clk_i2s_set_parent,
+};
+
+static const struct clk_ops jz_clk_spi_ops = {
+ .set_rate = jz_clk_divided_set_rate,
+ .get_rate = jz_clk_divided_get_rate,
+ .enable = jz_clk_enable_gating,
+ .disable = jz_clk_disable_gating,
+ .is_enabled = jz_clk_is_enabled_gating,
+ .set_parent = jz_clk_spi_set_parent,
+};
+
+static const struct clk_ops jz_clk_divided_ops = {
+ .set_rate = jz_clk_divided_set_rate,
+ .get_rate = jz_clk_divided_get_rate,
+ .enable = jz_clk_enable_gating,
+ .disable = jz_clk_disable_gating,
+ .is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct divided_clk jz4740_clock_divided_clks[] = {
+ [0] = {
+ .clk = {
+ .name = "i2s",
+ .parent = &jz_clk_ext.clk,
+ .gate_bit = JZ_CLOCK_GATE_I2S,
+ .ops = &jz_clk_i2s_ops,
+ },
+ .reg = JZ_REG_CLOCK_I2S,
+ .mask = JZ_CLOCK_I2S_DIV_MASK,
+ },
+ [1] = {
+ .clk = {
+ .name = "spi",
+ .parent = &jz_clk_ext.clk,
+ .gate_bit = JZ_CLOCK_GATE_SPI,
+ .ops = &jz_clk_spi_ops,
+ },
+ .reg = JZ_REG_CLOCK_SPI,
+ .mask = JZ_CLOCK_SPI_DIV_MASK,
+ },
+ [2] = {
+ .clk = {
+ .name = "lcd_pclk",
+ .parent = &jz_clk_pll_half,
+ .gate_bit = JZ4740_CLK_NOT_GATED,
+ .ops = &jz_clk_divided_ops,
+ },
+ .reg = JZ_REG_CLOCK_LCD,
+ .mask = JZ_CLOCK_LCD_DIV_MASK,
+ },
+ [3] = {
+ .clk = {
+ .name = "mmc",
+ .parent = &jz_clk_pll_half,
+ .gate_bit = JZ_CLOCK_GATE_MMC,
+ .ops = &jz_clk_divided_ops,
+ },
+ .reg = JZ_REG_CLOCK_MMC,
+ .mask = JZ_CLOCK_MMC_DIV_MASK,
+ },
+ [4] = {
+ .clk = {
+ .name = "uhc",
+ .parent = &jz_clk_pll_half,
+ .gate_bit = JZ_CLOCK_GATE_UHC,
+ .ops = &jz_clk_divided_ops,
+ },
+ .reg = JZ_REG_CLOCK_UHC,
+ .mask = JZ_CLOCK_UHC_DIV_MASK,
+ },
+};
+
+static const struct clk_ops jz_clk_udc_ops = {
+ .set_parent = jz_clk_udc_set_parent,
+ .set_rate = jz_clk_udc_set_rate,
+ .get_rate = jz_clk_udc_get_rate,
+ .enable = jz_clk_udc_enable,
+ .disable = jz_clk_udc_disable,
+ .is_enabled = jz_clk_udc_is_enabled,
+};
+
+static const struct clk_ops jz_clk_simple_ops = {
+ .enable = jz_clk_enable_gating,
+ .disable = jz_clk_disable_gating,
+ .is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct clk jz4740_clock_simple_clks[] = {
+ [0] = {
+ .name = "udc",
+ .parent = &jz_clk_ext.clk,
+ .ops = &jz_clk_udc_ops,
+ },
+ [1] = {
+ .name = "uart0",
+ .parent = &jz_clk_ext.clk,
+ .gate_bit = JZ_CLOCK_GATE_UART0,
+ .ops = &jz_clk_simple_ops,
+ },
+ [2] = {
+ .name = "uart1",
+ .parent = &jz_clk_ext.clk,
+ .gate_bit = JZ_CLOCK_GATE_UART1,
+ .ops = &jz_clk_simple_ops,
+ },
+ [3] = {
+ .name = "dma",
+ .parent = &jz_clk_high_speed_peripheral.clk,
+ .gate_bit = JZ_CLOCK_GATE_UART0,
+ .ops = &jz_clk_simple_ops,
+ },
+ [4] = {
+ .name = "ipu",
+ .parent = &jz_clk_high_speed_peripheral.clk,
+ .gate_bit = JZ_CLOCK_GATE_IPU,
+ .ops = &jz_clk_simple_ops,
+ },
+ [5] = {
+ .name = "adc",
+ .parent = &jz_clk_ext.clk,
+ .gate_bit = JZ_CLOCK_GATE_ADC,
+ .ops = &jz_clk_simple_ops,
+ },
+ [6] = {
+ .name = "i2c",
+ .parent = &jz_clk_ext.clk,
+ .gate_bit = JZ_CLOCK_GATE_I2C,
+ .ops = &jz_clk_simple_ops,
+ },
+ [7] = {
+ .name = "aic",
+ .parent = &jz_clk_ext.clk,
+ .gate_bit = JZ_CLOCK_GATE_AIC,
+ .ops = &jz_clk_simple_ops,
+ },
+};
+
+static struct static_clk jz_clk_rtc = {
+ .clk = {
+ .name = "rtc",
+ .gate_bit = JZ_CLOCK_GATE_RTC,
+ .ops = &jz_clk_static_ops,
+ },
+ .rate = 32768,
+};
+
+int clk_enable(struct clk *clk)
+{
+ if (!clk->ops->enable)
+ return -EINVAL;
+
+ return clk->ops->enable(clk);
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ if (clk->ops->disable)
+ clk->ops->disable(clk);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+int clk_is_enabled(struct clk *clk)
+{
+ if (clk->ops->is_enabled)
+ return clk->ops->is_enabled(clk);
+
+ return 1;
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk->ops->get_rate)
+ return clk->ops->get_rate(clk);
+ if (clk->parent)
+ return clk_get_rate(clk->parent);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (!clk->ops->set_rate)
+ return -EINVAL;
+ return clk->ops->set_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->ops->round_rate)
+ return clk->ops->round_rate(clk, rate);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret;
+ int enabled;
+
+ if (!clk->ops->set_parent)
+ return -EINVAL;
+
+ enabled = clk_is_enabled(clk);
+ if (enabled)
+ clk_disable(clk);
+ ret = clk->ops->set_parent(clk, parent);
+ if (enabled)
+ clk_enable(clk);
+
+ jz4740_clock_debugfs_update_parent(clk);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get(struct device *dev, const char *name)
+{
+ struct clk *clk;
+
+ list_for_each_entry(clk, &jz_clocks, list) {
+ if (strcmp(clk->name, name) == 0)
+ return clk;
+ }
+ return ERR_PTR(-ENXIO);
+}
+EXPORT_SYMBOL_GPL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL_GPL(clk_put);
+
+static inline void clk_add(struct clk *clk)
+{
+ list_add_tail(&clk->list, &jz_clocks);
+
+ jz4740_clock_debugfs_add_clk(clk);
+}
+
+static void clk_register_clks(void)
+{
+ size_t i;
+
+ clk_add(&jz_clk_ext.clk);
+ clk_add(&jz_clk_pll);
+ clk_add(&jz_clk_pll_half);
+ clk_add(&jz_clk_cpu.clk);
+ clk_add(&jz_clk_high_speed_peripheral.clk);
+ clk_add(&jz_clk_low_speed_peripheral.clk);
+ clk_add(&jz_clk_ko);
+ clk_add(&jz_clk_ld);
+ clk_add(&jz_clk_rtc.clk);
+
+ for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
+ clk_add(&jz4740_clock_divided_clks[i].clk);
+
+ for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
+ clk_add(&jz4740_clock_simple_clks[i]);
+}
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
+{
+ switch (mode) {
+ case JZ4740_WAIT_MODE_IDLE:
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
+ break;
+ case JZ4740_WAIT_MODE_SLEEP:
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
+ break;
+ }
+}
+
+void jz4740_clock_udc_disable_auto_suspend(void)
+{
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
+
+void jz4740_clock_udc_enable_auto_suspend(void)
+{
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
+
+void jz4740_clock_suspend(void)
+{
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
+ JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
+}
+
+void jz4740_clock_resume(void)
+{
+ uint32_t pll;
+
+ jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
+
+ do {
+ pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
+ } while (!(pll & JZ_CLOCK_PLL_STABLE));
+
+ jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
+ JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+}
+
+static int jz4740_clock_init(void)
+{
+ uint32_t val;
+
+ jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
+ if (!jz_clock_base)
+ return -EBUSY;
+
+ spin_lock_init(&jz_clock_lock);
+
+ jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
+ jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
+
+ val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
+
+ if (val & JZ_CLOCK_SPI_SRC_PLL)
+ jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
+
+ val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+
+ if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
+ jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
+
+ if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
+ jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
+
+ jz4740_clock_debugfs_init();
+
+ clk_register_clks();
+
+ return 0;
+}
+arch_initcall(jz4740_clock_init);
diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
new file mode 100644
index 00000000..5d07499d
--- /dev/null
+++ b/arch/mips/jz4740/clock.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC clock support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_CLOCK_H__
+#define __MIPS_JZ4740_CLOCK_H__
+
+#include <linux/list.h>
+
+struct jz4740_clock_board_data {
+ unsigned long ext_rate;
+ unsigned long rtc_rate;
+};
+
+extern struct jz4740_clock_board_data jz4740_clock_bdata;
+
+void jz4740_clock_suspend(void);
+void jz4740_clock_resume(void);
+
+struct clk;
+
+struct clk_ops {
+ unsigned long (*get_rate)(struct clk *clk);
+ unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
+ int (*set_rate)(struct clk *clk, unsigned long rate);
+ int (*enable)(struct clk *clk);
+ int (*disable)(struct clk *clk);
+ int (*is_enabled)(struct clk *clk);
+
+ int (*set_parent)(struct clk *clk, struct clk *parent);
+
+};
+
+struct clk {
+ const char *name;
+ struct clk *parent;
+
+ uint32_t gate_bit;
+
+ const struct clk_ops *ops;
+
+ struct list_head list;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs_entry;
+ struct dentry *debugfs_parent_entry;
+#endif
+
+};
+
+#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
+
+int clk_is_enabled(struct clk *clk);
+
+#ifdef CONFIG_DEBUG_FS
+void jz4740_clock_debugfs_init(void);
+void jz4740_clock_debugfs_add_clk(struct clk *clk);
+void jz4740_clock_debugfs_update_parent(struct clk *clk);
+#else
+static inline void jz4740_clock_debugfs_init(void) {};
+static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
+static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
+#endif
+
+#endif
diff --git a/arch/mips/jz4740/dma.c b/arch/mips/jz4740/dma.c
new file mode 100644
index 00000000..d7feb898
--- /dev/null
+++ b/arch/mips/jz4740/dma.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC DMA support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <linux/dma-mapping.h>
+#include <asm/mach-jz4740/dma.h>
+#include <asm/mach-jz4740/base.h>
+
+#define JZ_REG_DMA_SRC_ADDR(x) (0x00 + (x) * 0x20)
+#define JZ_REG_DMA_DST_ADDR(x) (0x04 + (x) * 0x20)
+#define JZ_REG_DMA_TRANSFER_COUNT(x) (0x08 + (x) * 0x20)
+#define JZ_REG_DMA_REQ_TYPE(x) (0x0C + (x) * 0x20)
+#define JZ_REG_DMA_STATUS_CTRL(x) (0x10 + (x) * 0x20)
+#define JZ_REG_DMA_CMD(x) (0x14 + (x) * 0x20)
+#define JZ_REG_DMA_DESC_ADDR(x) (0x18 + (x) * 0x20)
+
+#define JZ_REG_DMA_CTRL 0x300
+#define JZ_REG_DMA_IRQ 0x304
+#define JZ_REG_DMA_DOORBELL 0x308
+#define JZ_REG_DMA_DOORBELL_SET 0x30C
+
+#define JZ_DMA_STATUS_CTRL_NO_DESC BIT(31)
+#define JZ_DMA_STATUS_CTRL_DESC_INV BIT(6)
+#define JZ_DMA_STATUS_CTRL_ADDR_ERR BIT(4)
+#define JZ_DMA_STATUS_CTRL_TRANSFER_DONE BIT(3)
+#define JZ_DMA_STATUS_CTRL_HALT BIT(2)
+#define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE BIT(1)
+#define JZ_DMA_STATUS_CTRL_ENABLE BIT(0)
+
+#define JZ_DMA_CMD_SRC_INC BIT(23)
+#define JZ_DMA_CMD_DST_INC BIT(22)
+#define JZ_DMA_CMD_RDIL_MASK (0xf << 16)
+#define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14)
+#define JZ_DMA_CMD_DST_WIDTH_MASK (0x3 << 12)
+#define JZ_DMA_CMD_INTERVAL_LENGTH_MASK (0x7 << 8)
+#define JZ_DMA_CMD_BLOCK_MODE BIT(7)
+#define JZ_DMA_CMD_DESC_VALID BIT(4)
+#define JZ_DMA_CMD_DESC_VALID_MODE BIT(3)
+#define JZ_DMA_CMD_VALID_IRQ_ENABLE BIT(2)
+#define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE BIT(1)
+#define JZ_DMA_CMD_LINK_ENABLE BIT(0)
+
+#define JZ_DMA_CMD_FLAGS_OFFSET 22
+#define JZ_DMA_CMD_RDIL_OFFSET 16
+#define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14
+#define JZ_DMA_CMD_DST_WIDTH_OFFSET 12
+#define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8
+#define JZ_DMA_CMD_MODE_OFFSET 7
+
+#define JZ_DMA_CTRL_PRIORITY_MASK (0x3 << 8)
+#define JZ_DMA_CTRL_HALT BIT(3)
+#define JZ_DMA_CTRL_ADDRESS_ERROR BIT(2)
+#define JZ_DMA_CTRL_ENABLE BIT(0)
+
+
+static void __iomem *jz4740_dma_base;
+static spinlock_t jz4740_dma_lock;
+
+static inline uint32_t jz4740_dma_read(size_t reg)
+{
+ return readl(jz4740_dma_base + reg);
+}
+
+static inline void jz4740_dma_write(size_t reg, uint32_t val)
+{
+ writel(val, jz4740_dma_base + reg);
+}
+
+static inline void jz4740_dma_write_mask(size_t reg, uint32_t val, uint32_t mask)
+{
+ uint32_t val2;
+ val2 = jz4740_dma_read(reg);
+ val2 &= ~mask;
+ val2 |= val;
+ jz4740_dma_write(reg, val2);
+}
+
+struct jz4740_dma_chan {
+ unsigned int id;
+ void *dev;
+ const char *name;
+
+ enum jz4740_dma_flags flags;
+ uint32_t transfer_shift;
+
+ jz4740_dma_complete_callback_t complete_cb;
+
+ unsigned used:1;
+};
+
+#define JZ4740_DMA_CHANNEL(_id) { .id = _id }
+
+struct jz4740_dma_chan jz4740_dma_channels[] = {
+ JZ4740_DMA_CHANNEL(0),
+ JZ4740_DMA_CHANNEL(1),
+ JZ4740_DMA_CHANNEL(2),
+ JZ4740_DMA_CHANNEL(3),
+ JZ4740_DMA_CHANNEL(4),
+ JZ4740_DMA_CHANNEL(5),
+};
+
+struct jz4740_dma_chan *jz4740_dma_request(void *dev, const char *name)
+{
+ unsigned int i;
+ struct jz4740_dma_chan *dma = NULL;
+
+ spin_lock(&jz4740_dma_lock);
+
+ for (i = 0; i < ARRAY_SIZE(jz4740_dma_channels); ++i) {
+ if (!jz4740_dma_channels[i].used) {
+ dma = &jz4740_dma_channels[i];
+ dma->used = 1;
+ break;
+ }
+ }
+
+ spin_unlock(&jz4740_dma_lock);
+
+ if (!dma)
+ return NULL;
+
+ dma->dev = dev;
+ dma->name = name;
+
+ return dma;
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_request);
+
+void jz4740_dma_configure(struct jz4740_dma_chan *dma,
+ const struct jz4740_dma_config *config)
+{
+ uint32_t cmd;
+
+ switch (config->transfer_size) {
+ case JZ4740_DMA_TRANSFER_SIZE_2BYTE:
+ dma->transfer_shift = 1;
+ break;
+ case JZ4740_DMA_TRANSFER_SIZE_4BYTE:
+ dma->transfer_shift = 2;
+ break;
+ case JZ4740_DMA_TRANSFER_SIZE_16BYTE:
+ dma->transfer_shift = 4;
+ break;
+ case JZ4740_DMA_TRANSFER_SIZE_32BYTE:
+ dma->transfer_shift = 5;
+ break;
+ default:
+ dma->transfer_shift = 0;
+ break;
+ }
+
+ cmd = config->flags << JZ_DMA_CMD_FLAGS_OFFSET;
+ cmd |= config->src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET;
+ cmd |= config->dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET;
+ cmd |= config->transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET;
+ cmd |= config->mode << JZ_DMA_CMD_MODE_OFFSET;
+ cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE;
+
+ jz4740_dma_write(JZ_REG_DMA_CMD(dma->id), cmd);
+ jz4740_dma_write(JZ_REG_DMA_STATUS_CTRL(dma->id), 0);
+ jz4740_dma_write(JZ_REG_DMA_REQ_TYPE(dma->id), config->request_type);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_configure);
+
+void jz4740_dma_set_src_addr(struct jz4740_dma_chan *dma, dma_addr_t src)
+{
+ jz4740_dma_write(JZ_REG_DMA_SRC_ADDR(dma->id), src);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_set_src_addr);
+
+void jz4740_dma_set_dst_addr(struct jz4740_dma_chan *dma, dma_addr_t dst)
+{
+ jz4740_dma_write(JZ_REG_DMA_DST_ADDR(dma->id), dst);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_set_dst_addr);
+
+void jz4740_dma_set_transfer_count(struct jz4740_dma_chan *dma, uint32_t count)
+{
+ count >>= dma->transfer_shift;
+ jz4740_dma_write(JZ_REG_DMA_TRANSFER_COUNT(dma->id), count);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_set_transfer_count);
+
+void jz4740_dma_set_complete_cb(struct jz4740_dma_chan *dma,
+ jz4740_dma_complete_callback_t cb)
+{
+ dma->complete_cb = cb;
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_set_complete_cb);
+
+void jz4740_dma_free(struct jz4740_dma_chan *dma)
+{
+ dma->dev = NULL;
+ dma->complete_cb = NULL;
+ dma->used = 0;
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_free);
+
+void jz4740_dma_enable(struct jz4740_dma_chan *dma)
+{
+ jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id),
+ JZ_DMA_STATUS_CTRL_NO_DESC | JZ_DMA_STATUS_CTRL_ENABLE,
+ JZ_DMA_STATUS_CTRL_HALT | JZ_DMA_STATUS_CTRL_NO_DESC |
+ JZ_DMA_STATUS_CTRL_ENABLE);
+
+ jz4740_dma_write_mask(JZ_REG_DMA_CTRL,
+ JZ_DMA_CTRL_ENABLE,
+ JZ_DMA_CTRL_HALT | JZ_DMA_CTRL_ENABLE);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_enable);
+
+void jz4740_dma_disable(struct jz4740_dma_chan *dma)
+{
+ jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
+ JZ_DMA_STATUS_CTRL_ENABLE);
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_disable);
+
+uint32_t jz4740_dma_get_residue(const struct jz4740_dma_chan *dma)
+{
+ uint32_t residue;
+ residue = jz4740_dma_read(JZ_REG_DMA_TRANSFER_COUNT(dma->id));
+ return residue << dma->transfer_shift;
+}
+EXPORT_SYMBOL_GPL(jz4740_dma_get_residue);
+
+static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma)
+{
+ (void) jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id));
+
+ jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0,
+ JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE);
+
+ if (dma->complete_cb)
+ dma->complete_cb(dma, 0, dma->dev);
+}
+
+static irqreturn_t jz4740_dma_irq(int irq, void *dev_id)
+{
+ uint32_t irq_status;
+ unsigned int i;
+
+ irq_status = readl(jz4740_dma_base + JZ_REG_DMA_IRQ);
+
+ for (i = 0; i < 6; ++i) {
+ if (irq_status & (1 << i))
+ jz4740_dma_chan_irq(&jz4740_dma_channels[i]);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int jz4740_dma_init(void)
+{
+ unsigned int ret;
+
+ jz4740_dma_base = ioremap(JZ4740_DMAC_BASE_ADDR, 0x400);
+
+ if (!jz4740_dma_base)
+ return -EBUSY;
+
+ spin_lock_init(&jz4740_dma_lock);
+
+ ret = request_irq(JZ4740_IRQ_DMAC, jz4740_dma_irq, 0, "DMA", NULL);
+
+ if (ret)
+ printk(KERN_ERR "JZ4740 DMA: Failed to request irq: %d\n", ret);
+
+ return ret;
+}
+arch_initcall(jz4740_dma_init);
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
new file mode 100644
index 00000000..43979729
--- /dev/null
+++ b/arch/mips/jz4740/gpio.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform GPIO support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/spinlock.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include <asm/mach-jz4740/base.h>
+
+#define JZ4740_GPIO_BASE_A (32*0)
+#define JZ4740_GPIO_BASE_B (32*1)
+#define JZ4740_GPIO_BASE_C (32*2)
+#define JZ4740_GPIO_BASE_D (32*3)
+
+#define JZ4740_GPIO_NUM_A 32
+#define JZ4740_GPIO_NUM_B 32
+#define JZ4740_GPIO_NUM_C 31
+#define JZ4740_GPIO_NUM_D 32
+
+#define JZ4740_IRQ_GPIO_BASE_A (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_A)
+#define JZ4740_IRQ_GPIO_BASE_B (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_B)
+#define JZ4740_IRQ_GPIO_BASE_C (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_C)
+#define JZ4740_IRQ_GPIO_BASE_D (JZ4740_IRQ_GPIO(0) + JZ4740_GPIO_BASE_D)
+
+#define JZ_REG_GPIO_PIN 0x00
+#define JZ_REG_GPIO_DATA 0x10
+#define JZ_REG_GPIO_DATA_SET 0x14
+#define JZ_REG_GPIO_DATA_CLEAR 0x18
+#define JZ_REG_GPIO_MASK 0x20
+#define JZ_REG_GPIO_MASK_SET 0x24
+#define JZ_REG_GPIO_MASK_CLEAR 0x28
+#define JZ_REG_GPIO_PULL 0x30
+#define JZ_REG_GPIO_PULL_SET 0x34
+#define JZ_REG_GPIO_PULL_CLEAR 0x38
+#define JZ_REG_GPIO_FUNC 0x40
+#define JZ_REG_GPIO_FUNC_SET 0x44
+#define JZ_REG_GPIO_FUNC_CLEAR 0x48
+#define JZ_REG_GPIO_SELECT 0x50
+#define JZ_REG_GPIO_SELECT_SET 0x54
+#define JZ_REG_GPIO_SELECT_CLEAR 0x58
+#define JZ_REG_GPIO_DIRECTION 0x60
+#define JZ_REG_GPIO_DIRECTION_SET 0x64
+#define JZ_REG_GPIO_DIRECTION_CLEAR 0x68
+#define JZ_REG_GPIO_TRIGGER 0x70
+#define JZ_REG_GPIO_TRIGGER_SET 0x74
+#define JZ_REG_GPIO_TRIGGER_CLEAR 0x78
+#define JZ_REG_GPIO_FLAG 0x80
+#define JZ_REG_GPIO_FLAG_CLEAR 0x14
+
+#define GPIO_TO_BIT(gpio) BIT(gpio & 0x1f)
+#define GPIO_TO_REG(gpio, reg) (gpio_to_jz_gpio_chip(gpio)->base + (reg))
+#define CHIP_TO_REG(chip, reg) (gpio_chip_to_jz_gpio_chip(chip)->base + (reg))
+
+struct jz_gpio_chip {
+ unsigned int irq;
+ unsigned int irq_base;
+ uint32_t wakeup;
+ uint32_t suspend_mask;
+ uint32_t edge_trigger_both;
+
+ void __iomem *base;
+
+ spinlock_t lock;
+
+ struct gpio_chip gpio_chip;
+};
+
+static struct jz_gpio_chip jz4740_gpio_chips[];
+
+static inline struct jz_gpio_chip *gpio_to_jz_gpio_chip(unsigned int gpio)
+{
+ return &jz4740_gpio_chips[gpio >> 5];
+}
+
+static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *gpio_chip)
+{
+ return container_of(gpio_chip, struct jz_gpio_chip, gpio_chip);
+}
+
+static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
+{
+ return irq_data_get_irq_chip_data(data);
+}
+
+static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
+{
+ writel(GPIO_TO_BIT(gpio), GPIO_TO_REG(gpio, reg));
+}
+
+int jz_gpio_set_function(int gpio, enum jz_gpio_function function)
+{
+ if (function == JZ_GPIO_FUNC_NONE) {
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_CLEAR);
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
+ } else {
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_FUNC_SET);
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_CLEAR);
+ switch (function) {
+ case JZ_GPIO_FUNC1:
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_CLEAR);
+ break;
+ case JZ_GPIO_FUNC3:
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_TRIGGER_SET);
+ case JZ_GPIO_FUNC2: /* Falltrough */
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_SELECT_SET);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(jz_gpio_set_function);
+
+int jz_gpio_bulk_request(const struct jz_gpio_bulk_request *request, size_t num)
+{
+ size_t i;
+ int ret;
+
+ for (i = 0; i < num; ++i, ++request) {
+ ret = gpio_request(request->gpio, request->name);
+ if (ret)
+ goto err;
+ jz_gpio_set_function(request->gpio, request->function);
+ }
+
+ return 0;
+
+err:
+ for (--request; i > 0; --i, --request) {
+ gpio_free(request->gpio);
+ jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(jz_gpio_bulk_request);
+
+void jz_gpio_bulk_free(const struct jz_gpio_bulk_request *request, size_t num)
+{
+ size_t i;
+
+ for (i = 0; i < num; ++i, ++request) {
+ gpio_free(request->gpio);
+ jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
+ }
+
+}
+EXPORT_SYMBOL_GPL(jz_gpio_bulk_free);
+
+void jz_gpio_bulk_suspend(const struct jz_gpio_bulk_request *request, size_t num)
+{
+ size_t i;
+
+ for (i = 0; i < num; ++i, ++request) {
+ jz_gpio_set_function(request->gpio, JZ_GPIO_FUNC_NONE);
+ jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_DIRECTION_CLEAR);
+ jz_gpio_write_bit(request->gpio, JZ_REG_GPIO_PULL_SET);
+ }
+}
+EXPORT_SYMBOL_GPL(jz_gpio_bulk_suspend);
+
+void jz_gpio_bulk_resume(const struct jz_gpio_bulk_request *request, size_t num)
+{
+ size_t i;
+
+ for (i = 0; i < num; ++i, ++request)
+ jz_gpio_set_function(request->gpio, request->function);
+}
+EXPORT_SYMBOL_GPL(jz_gpio_bulk_resume);
+
+void jz_gpio_enable_pullup(unsigned gpio)
+{
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_CLEAR);
+}
+EXPORT_SYMBOL_GPL(jz_gpio_enable_pullup);
+
+void jz_gpio_disable_pullup(unsigned gpio)
+{
+ jz_gpio_write_bit(gpio, JZ_REG_GPIO_PULL_SET);
+}
+EXPORT_SYMBOL_GPL(jz_gpio_disable_pullup);
+
+static int jz_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ return !!(readl(CHIP_TO_REG(chip, JZ_REG_GPIO_PIN)) & BIT(gpio));
+}
+
+static void jz_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+{
+ uint32_t __iomem *reg = CHIP_TO_REG(chip, JZ_REG_GPIO_DATA_SET);
+ reg += !value;
+ writel(BIT(gpio), reg);
+}
+
+static int jz_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
+ int value)
+{
+ writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_SET));
+ jz_gpio_set_value(chip, gpio, value);
+
+ return 0;
+}
+
+static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ writel(BIT(gpio), CHIP_TO_REG(chip, JZ_REG_GPIO_DIRECTION_CLEAR));
+
+ return 0;
+}
+
+int jz_gpio_port_direction_input(int port, uint32_t mask)
+{
+ writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
+
+ return 0;
+}
+EXPORT_SYMBOL(jz_gpio_port_direction_input);
+
+int jz_gpio_port_direction_output(int port, uint32_t mask)
+{
+ writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_SET));
+
+ return 0;
+}
+EXPORT_SYMBOL(jz_gpio_port_direction_output);
+
+void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask)
+{
+ writel(~value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_CLEAR));
+ writel(value & mask, GPIO_TO_REG(port, JZ_REG_GPIO_DATA_SET));
+}
+EXPORT_SYMBOL(jz_gpio_port_set_value);
+
+uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
+{
+ uint32_t value = readl(GPIO_TO_REG(port, JZ_REG_GPIO_PIN));
+
+ return value & mask;
+}
+EXPORT_SYMBOL(jz_gpio_port_get_value);
+
+int gpio_to_irq(unsigned gpio)
+{
+ return JZ4740_IRQ_GPIO(0) + gpio;
+}
+EXPORT_SYMBOL_GPL(gpio_to_irq);
+
+int irq_to_gpio(unsigned irq)
+{
+ return irq - JZ4740_IRQ_GPIO(0);
+}
+EXPORT_SYMBOL_GPL(irq_to_gpio);
+
+#define IRQ_TO_BIT(irq) BIT(irq_to_gpio(irq) & 0x1f)
+
+static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq)
+{
+ uint32_t value;
+ void __iomem *reg;
+ uint32_t mask = IRQ_TO_BIT(irq);
+
+ if (!(chip->edge_trigger_both & mask))
+ return;
+
+ reg = chip->base;
+
+ value = readl(chip->base + JZ_REG_GPIO_PIN);
+ if (value & mask)
+ reg += JZ_REG_GPIO_DIRECTION_CLEAR;
+ else
+ reg += JZ_REG_GPIO_DIRECTION_SET;
+
+ writel(mask, reg);
+}
+
+static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
+{
+ uint32_t flag;
+ unsigned int gpio_irq;
+ unsigned int gpio_bank;
+ struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc);
+
+ gpio_bank = JZ4740_IRQ_GPIO0 - irq;
+
+ flag = readl(chip->base + JZ_REG_GPIO_FLAG);
+
+ if (!flag)
+ return;
+
+ gpio_irq = __fls(flag);
+
+ jz_gpio_check_trigger_both(chip, irq);
+
+ gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0);
+
+ generic_handle_irq(gpio_irq);
+};
+
+static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg)
+{
+ struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
+ writel(IRQ_TO_BIT(data->irq), chip->base + reg);
+}
+
+static void jz_gpio_irq_mask(struct irq_data *data)
+{
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET);
+};
+
+static void jz_gpio_irq_unmask(struct irq_data *data)
+{
+ struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
+
+ jz_gpio_check_trigger_both(chip, data->irq);
+
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_CLEAR);
+};
+
+/* TODO: Check if function is gpio */
+static unsigned int jz_gpio_irq_startup(struct irq_data *data)
+{
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_SET);
+ jz_gpio_irq_unmask(data);
+ return 0;
+}
+
+static void jz_gpio_irq_shutdown(struct irq_data *data)
+{
+ jz_gpio_irq_mask(data);
+
+ /* Set direction to input */
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR);
+}
+
+static void jz_gpio_irq_ack(struct irq_data *data)
+{
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR);
+};
+
+static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
+{
+ struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
+ unsigned int irq = data->irq;
+
+ if (flow_type == IRQ_TYPE_EDGE_BOTH) {
+ uint32_t value = readl(chip->base + JZ_REG_GPIO_PIN);
+ if (value & IRQ_TO_BIT(irq))
+ flow_type = IRQ_TYPE_EDGE_FALLING;
+ else
+ flow_type = IRQ_TYPE_EDGE_RISING;
+ chip->edge_trigger_both |= IRQ_TO_BIT(irq);
+ } else {
+ chip->edge_trigger_both &= ~IRQ_TO_BIT(irq);
+ }
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_RISING:
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_SET);
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_SET);
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
+ jz_gpio_set_irq_bit(data, JZ_REG_GPIO_TRIGGER_CLEAR);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+ struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
+ spin_lock(&chip->lock);
+ if (on)
+ chip->wakeup |= IRQ_TO_BIT(data->irq);
+ else
+ chip->wakeup &= ~IRQ_TO_BIT(data->irq);
+ spin_unlock(&chip->lock);
+
+ irq_set_irq_wake(chip->irq, on);
+ return 0;
+}
+
+static struct irq_chip jz_gpio_irq_chip = {
+ .name = "GPIO",
+ .irq_mask = jz_gpio_irq_mask,
+ .irq_unmask = jz_gpio_irq_unmask,
+ .irq_ack = jz_gpio_irq_ack,
+ .irq_startup = jz_gpio_irq_startup,
+ .irq_shutdown = jz_gpio_irq_shutdown,
+ .irq_set_type = jz_gpio_irq_set_type,
+ .irq_set_wake = jz_gpio_irq_set_wake,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+#define JZ4740_GPIO_CHIP(_bank) { \
+ .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
+ .gpio_chip = { \
+ .label = "Bank " # _bank, \
+ .owner = THIS_MODULE, \
+ .set = jz_gpio_set_value, \
+ .get = jz_gpio_get_value, \
+ .direction_output = jz_gpio_direction_output, \
+ .direction_input = jz_gpio_direction_input, \
+ .base = JZ4740_GPIO_BASE_ ## _bank, \
+ .ngpio = JZ4740_GPIO_NUM_ ## _bank, \
+ }, \
+}
+
+static struct jz_gpio_chip jz4740_gpio_chips[] = {
+ JZ4740_GPIO_CHIP(A),
+ JZ4740_GPIO_CHIP(B),
+ JZ4740_GPIO_CHIP(C),
+ JZ4740_GPIO_CHIP(D),
+};
+
+static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip)
+{
+ chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
+ writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
+ writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
+}
+
+static int jz4740_gpio_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++)
+ jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]);
+
+ return 0;
+}
+
+static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip)
+{
+ uint32_t mask = chip->suspend_mask;
+
+ writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR);
+ writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
+}
+
+static void jz4740_gpio_resume(void)
+{
+ int i;
+
+ for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--)
+ jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]);
+}
+
+static struct syscore_ops jz4740_gpio_syscore_ops = {
+ .suspend = jz4740_gpio_suspend,
+ .resume = jz4740_gpio_resume,
+};
+
+static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
+{
+ int irq;
+
+ spin_lock_init(&chip->lock);
+
+ chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
+
+ gpiochip_add(&chip->gpio_chip);
+
+ chip->irq = JZ4740_IRQ_INTC_GPIO(id);
+ irq_set_handler_data(chip->irq, chip);
+ irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
+
+ for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
+ irq_set_lockdep_class(irq, &gpio_lock_class);
+ irq_set_chip_data(irq, chip);
+ irq_set_chip_and_handler(irq, &jz_gpio_irq_chip,
+ handle_level_irq);
+ }
+}
+
+static int __init jz4740_gpio_init(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
+ jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
+
+ register_syscore_ops(&jz4740_gpio_syscore_ops);
+
+ printk(KERN_INFO "JZ4740 GPIO initialized\n");
+
+ return 0;
+}
+arch_initcall(jz4740_gpio_init);
+
+#ifdef CONFIG_DEBUG_FS
+
+static inline void gpio_seq_reg(struct seq_file *s, struct jz_gpio_chip *chip,
+ const char *name, unsigned int reg)
+{
+ seq_printf(s, "\t%s: %08x\n", name, readl(chip->base + reg));
+}
+
+static int gpio_regs_show(struct seq_file *s, void *unused)
+{
+ struct jz_gpio_chip *chip = jz4740_gpio_chips;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i, ++chip) {
+ seq_printf(s, "==GPIO %d==\n", i);
+ gpio_seq_reg(s, chip, "Pin", JZ_REG_GPIO_PIN);
+ gpio_seq_reg(s, chip, "Data", JZ_REG_GPIO_DATA);
+ gpio_seq_reg(s, chip, "Mask", JZ_REG_GPIO_MASK);
+ gpio_seq_reg(s, chip, "Pull", JZ_REG_GPIO_PULL);
+ gpio_seq_reg(s, chip, "Func", JZ_REG_GPIO_FUNC);
+ gpio_seq_reg(s, chip, "Select", JZ_REG_GPIO_SELECT);
+ gpio_seq_reg(s, chip, "Direction", JZ_REG_GPIO_DIRECTION);
+ gpio_seq_reg(s, chip, "Trigger", JZ_REG_GPIO_TRIGGER);
+ gpio_seq_reg(s, chip, "Flag", JZ_REG_GPIO_FLAG);
+ }
+
+ return 0;
+}
+
+static int gpio_regs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, gpio_regs_show, NULL);
+}
+
+static const struct file_operations gpio_regs_operations = {
+ .open = gpio_regs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init gpio_debugfs_init(void)
+{
+ (void) debugfs_create_file("jz_regs_gpio", S_IFREG | S_IRUGO,
+ NULL, NULL, &gpio_regs_operations);
+ return 0;
+}
+subsys_initcall(gpio_debugfs_init);
+
+#endif
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
new file mode 100644
index 00000000..d82c0c43
--- /dev/null
+++ b/arch/mips/jz4740/irq.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform IRQ support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/irq_cpu.h>
+
+#include <asm/mach-jz4740/base.h>
+
+static void __iomem *jz_intc_base;
+static uint32_t jz_intc_wakeup;
+static uint32_t jz_intc_saved;
+
+#define JZ_REG_INTC_STATUS 0x00
+#define JZ_REG_INTC_MASK 0x04
+#define JZ_REG_INTC_SET_MASK 0x08
+#define JZ_REG_INTC_CLEAR_MASK 0x0c
+#define JZ_REG_INTC_PENDING 0x10
+
+#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE)
+
+static inline unsigned long intc_irq_bit(struct irq_data *data)
+{
+ return (unsigned long)irq_data_get_irq_chip_data(data);
+}
+
+static void intc_irq_unmask(struct irq_data *data)
+{
+ writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
+}
+
+static void intc_irq_mask(struct irq_data *data)
+{
+ writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK);
+}
+
+static int intc_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+ if (on)
+ jz_intc_wakeup |= intc_irq_bit(data);
+ else
+ jz_intc_wakeup &= ~intc_irq_bit(data);
+
+ return 0;
+}
+
+static struct irq_chip intc_irq_type = {
+ .name = "INTC",
+ .irq_mask = intc_irq_mask,
+ .irq_mask_ack = intc_irq_mask,
+ .irq_unmask = intc_irq_unmask,
+ .irq_set_wake = intc_irq_set_wake,
+};
+
+static irqreturn_t jz4740_cascade(int irq, void *data)
+{
+ uint32_t irq_reg;
+
+ irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
+
+ if (irq_reg)
+ generic_handle_irq(__fls(irq_reg) + JZ4740_IRQ_BASE);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction jz4740_cascade_action = {
+ .handler = jz4740_cascade,
+ .name = "JZ4740 cascade interrupt",
+};
+
+void __init arch_init_irq(void)
+{
+ int i;
+ mips_cpu_irq_init();
+
+ jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
+
+ /* Mask all irqs */
+ writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
+
+ for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) {
+ irq_set_chip_data(i, (void *)IRQ_BIT(i));
+ irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq);
+ }
+
+ setup_irq(2, &jz4740_cascade_action);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+ if (pending & STATUSF_IP2)
+ do_IRQ(2);
+ else if (pending & STATUSF_IP3)
+ do_IRQ(3);
+ else
+ spurious_interrupt();
+}
+
+void jz4740_intc_suspend(void)
+{
+ jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK);
+ writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
+ writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
+}
+
+void jz4740_intc_resume(void)
+{
+ writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
+ writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK);
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static inline void intc_seq_reg(struct seq_file *s, const char *name,
+ unsigned int reg)
+{
+ seq_printf(s, "%s:\t\t%08x\n", name, readl(jz_intc_base + reg));
+}
+
+static int intc_regs_show(struct seq_file *s, void *unused)
+{
+ intc_seq_reg(s, "Status", JZ_REG_INTC_STATUS);
+ intc_seq_reg(s, "Mask", JZ_REG_INTC_MASK);
+ intc_seq_reg(s, "Pending", JZ_REG_INTC_PENDING);
+
+ return 0;
+}
+
+static int intc_regs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, intc_regs_show, NULL);
+}
+
+static const struct file_operations intc_regs_operations = {
+ .open = intc_regs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init intc_debugfs_init(void)
+{
+ (void) debugfs_create_file("jz_regs_intc", S_IFREG | S_IRUGO,
+ NULL, NULL, &intc_regs_operations);
+ return 0;
+}
+subsys_initcall(intc_debugfs_init);
+
+#endif
diff --git a/arch/mips/jz4740/irq.h b/arch/mips/jz4740/irq.h
new file mode 100644
index 00000000..56b5eadd
--- /dev/null
+++ b/arch/mips/jz4740/irq.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_IRQ_H__
+#define __MIPS_JZ4740_IRQ_H__
+
+extern void jz4740_intc_suspend(void);
+extern void jz4740_intc_resume(void);
+
+#endif
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
new file mode 100644
index 00000000..10929e2b
--- /dev/null
+++ b/arch/mips/jz4740/platform.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform devices
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+
+#include <linux/dma-mapping.h>
+
+#include <asm/mach-jz4740/platform.h>
+#include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/irq.h>
+
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+
+#include "serial.h"
+#include "clock.h"
+
+/* OHCI controller */
+static struct resource jz4740_usb_ohci_resources[] = {
+ {
+ .start = JZ4740_UHC_BASE_ADDR,
+ .end = JZ4740_UHC_BASE_ADDR + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = JZ4740_IRQ_UHC,
+ .end = JZ4740_IRQ_UHC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device jz4740_usb_ohci_device = {
+ .name = "jz4740-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &jz4740_usb_ohci_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(jz4740_usb_ohci_resources),
+ .resource = jz4740_usb_ohci_resources,
+};
+
+/* UDC (USB gadget controller) */
+static struct resource jz4740_usb_gdt_resources[] = {
+ {
+ .start = JZ4740_UDC_BASE_ADDR,
+ .end = JZ4740_UDC_BASE_ADDR + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = JZ4740_IRQ_UDC,
+ .end = JZ4740_IRQ_UDC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device jz4740_udc_device = {
+ .name = "jz-udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(jz4740_usb_gdt_resources),
+ .resource = jz4740_usb_gdt_resources,
+};
+
+/* MMC/SD controller */
+static struct resource jz4740_mmc_resources[] = {
+ {
+ .start = JZ4740_MSC_BASE_ADDR,
+ .end = JZ4740_MSC_BASE_ADDR + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = JZ4740_IRQ_MSC,
+ .end = JZ4740_IRQ_MSC,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device jz4740_mmc_device = {
+ .name = "jz4740-mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &jz4740_mmc_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(jz4740_mmc_resources),
+ .resource = jz4740_mmc_resources,
+};
+
+/* RTC controller */
+static struct resource jz4740_rtc_resources[] = {
+ {
+ .start = JZ4740_RTC_BASE_ADDR,
+ .end = JZ4740_RTC_BASE_ADDR + 0x38 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = JZ4740_IRQ_RTC,
+ .end = JZ4740_IRQ_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device jz4740_rtc_device = {
+ .name = "jz4740-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(jz4740_rtc_resources),
+ .resource = jz4740_rtc_resources,
+};
+
+/* I2C controller */
+static struct resource jz4740_i2c_resources[] = {
+ {
+ .start = JZ4740_I2C_BASE_ADDR,
+ .end = JZ4740_I2C_BASE_ADDR + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = JZ4740_IRQ_I2C,
+ .end = JZ4740_IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device jz4740_i2c_device = {
+ .name = "jz4740-i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(jz4740_i2c_resources),
+ .resource = jz4740_i2c_resources,
+};
+
+/* NAND controller */
+static struct resource jz4740_nand_resources[] = {
+ {
+ .name = "mmio",
+ .start = JZ4740_EMC_BASE_ADDR,
+ .end = JZ4740_EMC_BASE_ADDR + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "bank",
+ .start = 0x18000000,
+ .end = 0x180C0000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device jz4740_nand_device = {
+ .name = "jz4740-nand",
+ .num_resources = ARRAY_SIZE(jz4740_nand_resources),
+ .resource = jz4740_nand_resources,
+};
+
+/* LCD controller */
+static struct resource jz4740_framebuffer_resources[] = {
+ {
+ .start = JZ4740_LCD_BASE_ADDR,
+ .end = JZ4740_LCD_BASE_ADDR + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device jz4740_framebuffer_device = {
+ .name = "jz4740-fb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources),
+ .resource = jz4740_framebuffer_resources,
+ .dev = {
+ .dma_mask = &jz4740_framebuffer_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/* I2S controller */
+static struct resource jz4740_i2s_resources[] = {
+ {
+ .start = JZ4740_AIC_BASE_ADDR,
+ .end = JZ4740_AIC_BASE_ADDR + 0x38 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device jz4740_i2s_device = {
+ .name = "jz4740-i2s",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(jz4740_i2s_resources),
+ .resource = jz4740_i2s_resources,
+};
+
+/* PCM */
+struct platform_device jz4740_pcm_device = {
+ .name = "jz4740-pcm-audio",
+ .id = -1,
+};
+
+/* Codec */
+static struct resource jz4740_codec_resources[] = {
+ {
+ .start = JZ4740_AIC_BASE_ADDR + 0x80,
+ .end = JZ4740_AIC_BASE_ADDR + 0x88 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device jz4740_codec_device = {
+ .name = "jz4740-codec",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(jz4740_codec_resources),
+ .resource = jz4740_codec_resources,
+};
+
+/* ADC controller */
+static struct resource jz4740_adc_resources[] = {
+ {
+ .start = JZ4740_SADC_BASE_ADDR,
+ .end = JZ4740_SADC_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = JZ4740_IRQ_SADC,
+ .end = JZ4740_IRQ_SADC,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = JZ4740_IRQ_ADC_BASE,
+ .end = JZ4740_IRQ_ADC_BASE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device jz4740_adc_device = {
+ .name = "jz4740-adc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(jz4740_adc_resources),
+ .resource = jz4740_adc_resources,
+};
+
+/* Serial */
+#define JZ4740_UART_DATA(_id) \
+ { \
+ .flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE, \
+ .iotype = UPIO_MEM, \
+ .regshift = 2, \
+ .serial_out = jz4740_serial_out, \
+ .type = PORT_16550, \
+ .mapbase = JZ4740_UART ## _id ## _BASE_ADDR, \
+ .irq = JZ4740_IRQ_UART ## _id, \
+ }
+
+static struct plat_serial8250_port jz4740_uart_data[] = {
+ JZ4740_UART_DATA(0),
+ JZ4740_UART_DATA(1),
+ {},
+};
+
+static struct platform_device jz4740_uart_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = jz4740_uart_data,
+ },
+};
+
+void jz4740_serial_device_register(void)
+{
+ struct plat_serial8250_port *p;
+
+ for (p = jz4740_uart_data; p->flags != 0; ++p)
+ p->uartclk = jz4740_clock_bdata.ext_rate;
+
+ platform_device_register(&jz4740_uart_device);
+}
+
+/* Watchdog */
+static struct resource jz4740_wdt_resources[] = {
+ {
+ .start = JZ4740_WDT_BASE_ADDR,
+ .end = JZ4740_WDT_BASE_ADDR + 0x10 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device jz4740_wdt_device = {
+ .name = "jz4740-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(jz4740_wdt_resources),
+ .resource = jz4740_wdt_resources,
+};
diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c
new file mode 100644
index 00000000..902d5b50
--- /dev/null
+++ b/arch/mips/jz4740/pm.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC power management support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+#include <linux/suspend.h>
+
+#include <asm/mach-jz4740/clock.h>
+
+#include "clock.h"
+#include "irq.h"
+
+static int jz4740_pm_enter(suspend_state_t state)
+{
+ jz4740_intc_suspend();
+ jz4740_clock_suspend();
+
+ jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
+
+ __asm__(".set\tmips3\n\t"
+ "wait\n\t"
+ ".set\tmips0");
+
+ jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
+
+ jz4740_clock_resume();
+ jz4740_intc_resume();
+
+ return 0;
+}
+
+static const struct platform_suspend_ops jz4740_pm_ops = {
+ .valid = suspend_valid_only_mem,
+ .enter = jz4740_pm_enter,
+};
+
+static int __init jz4740_pm_init(void)
+{
+ suspend_set_ops(&jz4740_pm_ops);
+ return 0;
+
+}
+late_initcall(jz4740_pm_init);
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
new file mode 100644
index 00000000..4a70407f
--- /dev/null
+++ b/arch/mips/jz4740/prom.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 SoC prom code
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <linux/serial_reg.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mach-jz4740/base.h>
+
+static __init void jz4740_init_cmdline(int argc, char *argv[])
+{
+ unsigned int count = COMMAND_LINE_SIZE - 1;
+ int i;
+ char *dst = &(arcs_cmdline[0]);
+ char *src;
+
+ for (i = 1; i < argc && count; ++i) {
+ src = argv[i];
+ while (*src && count) {
+ *dst++ = *src++;
+ --count;
+ }
+ *dst++ = ' ';
+ }
+ if (i > 1)
+ --dst;
+
+ *dst = 0;
+}
+
+void __init prom_init(void)
+{
+ jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1);
+ mips_machtype = MACH_INGENIC_JZ4740;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+#define UART_REG(_reg) ((void __iomem *)CKSEG1ADDR(JZ4740_UART0_BASE_ADDR + (_reg << 2)))
+
+void prom_putchar(char c)
+{
+ uint8_t lsr;
+
+ do {
+ lsr = readb(UART_REG(UART_LSR));
+ } while ((lsr & UART_LSR_TEMT) == 0);
+
+ writeb(c, UART_REG(UART_TX));
+}
diff --git a/arch/mips/jz4740/pwm.c b/arch/mips/jz4740/pwm.c
new file mode 100644
index 00000000..a26a6fae
--- /dev/null
+++ b/arch/mips/jz4740/pwm.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform PWM support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/pwm.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-jz4740/gpio.h>
+#include "timer.h"
+
+static struct clk *jz4740_pwm_clk;
+
+DEFINE_MUTEX(jz4740_pwm_mutex);
+
+struct pwm_device {
+ unsigned int id;
+ unsigned int gpio;
+ bool used;
+};
+
+static struct pwm_device jz4740_pwm_list[] = {
+ { 2, JZ_GPIO_PWM2, false },
+ { 3, JZ_GPIO_PWM3, false },
+ { 4, JZ_GPIO_PWM4, false },
+ { 5, JZ_GPIO_PWM5, false },
+ { 6, JZ_GPIO_PWM6, false },
+ { 7, JZ_GPIO_PWM7, false },
+};
+
+struct pwm_device *pwm_request(int id, const char *label)
+{
+ int ret = 0;
+ struct pwm_device *pwm;
+
+ if (id < 2 || id > 7 || !jz4740_pwm_clk)
+ return ERR_PTR(-ENODEV);
+
+ mutex_lock(&jz4740_pwm_mutex);
+
+ pwm = &jz4740_pwm_list[id - 2];
+ if (pwm->used)
+ ret = -EBUSY;
+ else
+ pwm->used = true;
+
+ mutex_unlock(&jz4740_pwm_mutex);
+
+ if (ret)
+ return ERR_PTR(ret);
+
+ ret = gpio_request(pwm->gpio, label);
+
+ if (ret) {
+ printk(KERN_ERR "Failed to request pwm gpio: %d\n", ret);
+ pwm->used = false;
+ return ERR_PTR(ret);
+ }
+
+ jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_PWM);
+
+ jz4740_timer_start(id);
+
+ return pwm;
+}
+
+void pwm_free(struct pwm_device *pwm)
+{
+ pwm_disable(pwm);
+ jz4740_timer_set_ctrl(pwm->id, 0);
+
+ jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_NONE);
+ gpio_free(pwm->gpio);
+
+ jz4740_timer_stop(pwm->id);
+
+ pwm->used = false;
+}
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ unsigned long long tmp;
+ unsigned long period, duty;
+ unsigned int prescaler = 0;
+ unsigned int id = pwm->id;
+ uint16_t ctrl;
+ bool is_enabled;
+
+ if (duty_ns < 0 || duty_ns > period_ns)
+ return -EINVAL;
+
+ tmp = (unsigned long long)clk_get_rate(jz4740_pwm_clk) * period_ns;
+ do_div(tmp, 1000000000);
+ period = tmp;
+
+ while (period > 0xffff && prescaler < 6) {
+ period >>= 2;
+ ++prescaler;
+ }
+
+ if (prescaler == 6)
+ return -EINVAL;
+
+ tmp = (unsigned long long)period * duty_ns;
+ do_div(tmp, period_ns);
+ duty = period - tmp;
+
+ if (duty >= period)
+ duty = period - 1;
+
+ is_enabled = jz4740_timer_is_enabled(id);
+ if (is_enabled)
+ pwm_disable(pwm);
+
+ jz4740_timer_set_count(id, 0);
+ jz4740_timer_set_duty(id, duty);
+ jz4740_timer_set_period(id, period);
+
+ ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_SRC_EXT |
+ JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN;
+
+ jz4740_timer_set_ctrl(id, ctrl);
+
+ if (is_enabled)
+ pwm_enable(pwm);
+
+ return 0;
+}
+
+int pwm_enable(struct pwm_device *pwm)
+{
+ uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
+
+ ctrl |= JZ_TIMER_CTRL_PWM_ENABLE;
+ jz4740_timer_set_ctrl(pwm->id, ctrl);
+ jz4740_timer_enable(pwm->id);
+
+ return 0;
+}
+
+void pwm_disable(struct pwm_device *pwm)
+{
+ uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
+
+ ctrl &= ~JZ_TIMER_CTRL_PWM_ENABLE;
+ jz4740_timer_disable(pwm->id);
+ jz4740_timer_set_ctrl(pwm->id, ctrl);
+}
+
+static int __init jz4740_pwm_init(void)
+{
+ int ret = 0;
+
+ jz4740_pwm_clk = clk_get(NULL, "ext");
+
+ if (IS_ERR(jz4740_pwm_clk)) {
+ ret = PTR_ERR(jz4740_pwm_clk);
+ jz4740_pwm_clk = NULL;
+ }
+
+ return ret;
+}
+subsys_initcall(jz4740_pwm_init);
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
new file mode 100644
index 00000000..5f1fb95c
--- /dev/null
+++ b/arch/mips/jz4740/reset.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+
+#include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/timer.h>
+
+static void jz4740_halt(void)
+{
+ while (1) {
+ __asm__(".set push;\n"
+ ".set mips3;\n"
+ "wait;\n"
+ ".set pop;\n"
+ );
+ }
+}
+
+#define JZ_REG_WDT_DATA 0x00
+#define JZ_REG_WDT_COUNTER_ENABLE 0x04
+#define JZ_REG_WDT_COUNTER 0x08
+#define JZ_REG_WDT_CTRL 0x0c
+
+static void jz4740_restart(char *command)
+{
+ void __iomem *wdt_base = ioremap(JZ4740_WDT_BASE_ADDR, 0x0f);
+
+ jz4740_timer_enable_watchdog();
+
+ writeb(0, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
+
+ writew(0, wdt_base + JZ_REG_WDT_COUNTER);
+ writew(0, wdt_base + JZ_REG_WDT_DATA);
+ writew(BIT(2), wdt_base + JZ_REG_WDT_CTRL);
+
+ writeb(1, wdt_base + JZ_REG_WDT_COUNTER_ENABLE);
+ jz4740_halt();
+}
+
+#define JZ_REG_RTC_CTRL 0x00
+#define JZ_REG_RTC_HIBERNATE 0x20
+
+#define JZ_RTC_CTRL_WRDY BIT(7)
+
+static void jz4740_power_off(void)
+{
+ void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x24);
+ uint32_t ctrl;
+
+ do {
+ ctrl = readl(rtc_base + JZ_REG_RTC_CTRL);
+ } while (!(ctrl & JZ_RTC_CTRL_WRDY));
+
+ writel(1, rtc_base + JZ_REG_RTC_HIBERNATE);
+ jz4740_halt();
+}
+
+void jz4740_reset_init(void)
+{
+ _machine_restart = jz4740_restart;
+ _machine_halt = jz4740_halt;
+ pm_power_off = jz4740_power_off;
+}
diff --git a/arch/mips/jz4740/reset.h b/arch/mips/jz4740/reset.h
new file mode 100644
index 00000000..5202ab4a
--- /dev/null
+++ b/arch/mips/jz4740/reset.h
@@ -0,0 +1,6 @@
+#ifndef __MIPS_JZ4740_RESET_H__
+#define __MIPS_JZ4740_RESET_H__
+
+extern void jz4740_reset_init(void);
+
+#endif
diff --git a/arch/mips/jz4740/serial.c b/arch/mips/jz4740/serial.c
new file mode 100644
index 00000000..d23de458
--- /dev/null
+++ b/arch/mips/jz4740/serial.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 serial support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+void jz4740_serial_out(struct uart_port *p, int offset, int value)
+{
+ switch (offset) {
+ case UART_FCR:
+ value |= 0x10; /* Enable uart module */
+ break;
+ case UART_IER:
+ value |= (value & 0x4) << 2;
+ break;
+ default:
+ break;
+ }
+ writeb(value, p->membase + (offset << p->regshift));
+}
diff --git a/arch/mips/jz4740/serial.h b/arch/mips/jz4740/serial.h
new file mode 100644
index 00000000..b9fe3ade
--- /dev/null
+++ b/arch/mips/jz4740/serial.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 serial support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_SERIAL_H__
+
+void jz4740_serial_out(struct uart_port *p, int offset, int value);
+
+#endif
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
new file mode 100644
index 00000000..d97cfbf8
--- /dev/null
+++ b/arch/mips/jz4740/setup.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ * Copyright (C) 2011, Maarten ter Huurne <maarten@treewalker.org>
+ * JZ4740 setup code
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+
+#include <asm/mach-jz4740/base.h>
+
+#include "reset.h"
+
+
+#define JZ4740_EMC_SDRAM_CTRL 0x80
+
+
+static void __init jz4740_detect_mem(void)
+{
+ void __iomem *jz_emc_base;
+ u32 ctrl, bus, bank, rows, cols;
+ phys_t size;
+
+ jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100);
+ ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL);
+ bus = 2 - ((ctrl >> 31) & 1);
+ bank = 1 + ((ctrl >> 19) & 1);
+ cols = 8 + ((ctrl >> 26) & 7);
+ rows = 11 + ((ctrl >> 20) & 3);
+ printk(KERN_DEBUG
+ "SDRAM preconfigured: bus:%u bank:%u rows:%u cols:%u\n",
+ bus, bank, rows, cols);
+ iounmap(jz_emc_base);
+
+ size = 1 << (bus + bank + cols + rows);
+ add_memory_region(0, size, BOOT_MEM_RAM);
+}
+
+void __init plat_mem_setup(void)
+{
+ jz4740_reset_init();
+ jz4740_detect_mem();
+}
+
+const char *get_system_type(void)
+{
+ return "JZ4740";
+}
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
new file mode 100644
index 00000000..f83c2dd0
--- /dev/null
+++ b/arch/mips/jz4740/time.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform time support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+
+#include <linux/clockchips.h>
+
+#include <asm/mach-jz4740/irq.h>
+#include <asm/time.h>
+
+#include "clock.h"
+#include "timer.h"
+
+#define TIMER_CLOCKEVENT 0
+#define TIMER_CLOCKSOURCE 1
+
+static uint16_t jz4740_jiffies_per_tick;
+
+static cycle_t jz4740_clocksource_read(struct clocksource *cs)
+{
+ return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
+}
+
+static struct clocksource jz4740_clocksource = {
+ .name = "jz4740-timer",
+ .rating = 200,
+ .read = jz4740_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(16),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
+{
+ struct clock_event_device *cd = devid;
+
+ jz4740_timer_ack_full(TIMER_CLOCKEVENT);
+
+ if (cd->mode != CLOCK_EVT_MODE_PERIODIC)
+ jz4740_timer_disable(TIMER_CLOCKEVENT);
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static void jz4740_clockevent_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *cd)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
+ jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
+ case CLOCK_EVT_MODE_RESUME:
+ jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
+ jz4740_timer_enable(TIMER_CLOCKEVENT);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ jz4740_timer_disable(TIMER_CLOCKEVENT);
+ break;
+ default:
+ break;
+ }
+}
+
+static int jz4740_clockevent_set_next(unsigned long evt,
+ struct clock_event_device *cd)
+{
+ jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
+ jz4740_timer_set_period(TIMER_CLOCKEVENT, evt);
+ jz4740_timer_enable(TIMER_CLOCKEVENT);
+
+ return 0;
+}
+
+static struct clock_event_device jz4740_clockevent = {
+ .name = "jz4740-timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = jz4740_clockevent_set_next,
+ .set_mode = jz4740_clockevent_set_mode,
+ .rating = 200,
+ .irq = JZ4740_IRQ_TCU0,
+};
+
+static struct irqaction timer_irqaction = {
+ .handler = jz4740_clockevent_irq,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
+ .name = "jz4740-timerirq",
+ .dev_id = &jz4740_clockevent,
+};
+
+void __init plat_time_init(void)
+{
+ int ret;
+ uint32_t clk_rate;
+ uint16_t ctrl;
+
+ jz4740_timer_init();
+
+ clk_rate = jz4740_clock_bdata.ext_rate >> 4;
+ jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
+
+ clockevent_set_clock(&jz4740_clockevent, clk_rate);
+ jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
+ jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
+ jz4740_clockevent.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&jz4740_clockevent);
+
+ ret = clocksource_register_hz(&jz4740_clocksource, clk_rate);
+
+ if (ret)
+ printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
+
+ setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
+
+ ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
+
+ jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl);
+ jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl);
+
+ jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
+ jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
+
+ jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff);
+
+ jz4740_timer_enable(TIMER_CLOCKEVENT);
+ jz4740_timer_enable(TIMER_CLOCKSOURCE);
+}
diff --git a/arch/mips/jz4740/timer.c b/arch/mips/jz4740/timer.c
new file mode 100644
index 00000000..654d5c39
--- /dev/null
+++ b/arch/mips/jz4740/timer.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform timer support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "timer.h"
+
+#include <asm/mach-jz4740/base.h>
+
+void __iomem *jz4740_timer_base;
+
+void jz4740_timer_enable_watchdog(void)
+{
+ writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
+}
+EXPORT_SYMBOL_GPL(jz4740_timer_enable_watchdog);
+
+void jz4740_timer_disable_watchdog(void)
+{
+ writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
+}
+EXPORT_SYMBOL_GPL(jz4740_timer_disable_watchdog);
+
+void __init jz4740_timer_init(void)
+{
+ jz4740_timer_base = ioremap(JZ4740_TCU_BASE_ADDR, 0x100);
+
+ if (!jz4740_timer_base)
+ panic("Failed to ioremap timer registers");
+
+ /* Disable all timer clocks except for those used as system timers */
+ writel(0x000100fc, jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
+
+ /* Timer irqs are unmasked by default, mask them */
+ writel(0x00ff00ff, jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
+}
diff --git a/arch/mips/jz4740/timer.h b/arch/mips/jz4740/timer.h
new file mode 100644
index 00000000..fca3994f
--- /dev/null
+++ b/arch/mips/jz4740/timer.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * JZ4740 platform timer support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_TIMER_H__
+#define __MIPS_JZ4740_TIMER_H__
+
+#include <linux/module.h>
+#include <linux/io.h>
+
+#define JZ_REG_TIMER_STOP 0x0C
+#define JZ_REG_TIMER_STOP_SET 0x1C
+#define JZ_REG_TIMER_STOP_CLEAR 0x2C
+#define JZ_REG_TIMER_ENABLE 0x00
+#define JZ_REG_TIMER_ENABLE_SET 0x04
+#define JZ_REG_TIMER_ENABLE_CLEAR 0x08
+#define JZ_REG_TIMER_FLAG 0x10
+#define JZ_REG_TIMER_FLAG_SET 0x14
+#define JZ_REG_TIMER_FLAG_CLEAR 0x18
+#define JZ_REG_TIMER_MASK 0x20
+#define JZ_REG_TIMER_MASK_SET 0x24
+#define JZ_REG_TIMER_MASK_CLEAR 0x28
+
+#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x30)
+#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x34)
+#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x38)
+#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x3C)
+
+#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
+#define JZ_TIMER_IRQ_FULL(x) BIT(x)
+
+#define JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN BIT(9)
+#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW BIT(8)
+#define JZ_TIMER_CTRL_PWM_ENABLE BIT(7)
+#define JZ_TIMER_CTRL_PRESCALE_MASK 0x1c
+#define JZ_TIMER_CTRL_PRESCALE_OFFSET 0x3
+#define JZ_TIMER_CTRL_PRESCALE_1 (0 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_4 (1 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_16 (2 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_64 (3 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_256 (4 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_1024 (5 << 3)
+
+#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
+
+#define JZ_TIMER_CTRL_SRC_EXT BIT(2)
+#define JZ_TIMER_CTRL_SRC_RTC BIT(1)
+#define JZ_TIMER_CTRL_SRC_PCLK BIT(0)
+
+extern void __iomem *jz4740_timer_base;
+void __init jz4740_timer_init(void);
+
+static inline void jz4740_timer_stop(unsigned int timer)
+{
+ writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
+}
+
+static inline void jz4740_timer_start(unsigned int timer)
+{
+ writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
+}
+
+static inline bool jz4740_timer_is_enabled(unsigned int timer)
+{
+ return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
+}
+
+static inline void jz4740_timer_enable(unsigned int timer)
+{
+ writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
+}
+
+static inline void jz4740_timer_disable(unsigned int timer)
+{
+ writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
+}
+
+
+static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
+{
+ writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
+}
+
+static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
+{
+ writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
+}
+
+static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
+{
+ writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
+}
+
+static inline uint16_t jz4740_timer_get_count(unsigned int timer)
+{
+ return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
+}
+
+static inline void jz4740_timer_ack_full(unsigned int timer)
+{
+ writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
+}
+
+static inline void jz4740_timer_irq_full_enable(unsigned int timer)
+{
+ writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
+ writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
+}
+
+static inline void jz4740_timer_irq_full_disable(unsigned int timer)
+{
+ writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
+}
+
+static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
+{
+ writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
+}
+
+static inline uint16_t jz4740_timer_get_ctrl(unsigned int timer)
+{
+ return readw(jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
+}
+
+#endif
diff --git a/arch/mips/kernel/.gitignore b/arch/mips/kernel/.gitignore
new file mode 100644
index 00000000..c5f676c3
--- /dev/null
+++ b/arch/mips/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/mips/kernel/8250-platform.c b/arch/mips/kernel/8250-platform.c
new file mode 100644
index 00000000..cbf3fe20
--- /dev/null
+++ b/arch/mips/kernel/8250-platform.c
@@ -0,0 +1,47 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(base, int) \
+{ \
+ .iobase = base, \
+ .irq = int, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
+ .regshift = 0, \
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+ PORT(0x3F8, 4),
+ PORT(0x2F8, 3),
+ PORT(0x3E8, 4),
+ PORT(0x2E8, 3),
+ { },
+};
+
+static struct platform_device uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = uart8250_data,
+ },
+};
+
+static int __init uart8250_init(void)
+{
+ return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250 UART probe driver");
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
new file mode 100644
index 00000000..83bba332
--- /dev/null
+++ b/arch/mips/kernel/Makefile
@@ -0,0 +1,113 @@
+#
+# Makefile for the Linux/MIPS kernel.
+#
+
+extra-y := head.o init_task.o vmlinux.lds
+
+obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
+ ptrace.o reset.o setup.o signal.o syscall.o \
+ time.o topology.o traps.o unaligned.o watch.o vdso.o
+
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_early_printk.o = -pg
+endif
+
+obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
+obj-$(CONFIG_CEVT_R4K_LIB) += cevt-r4k.o
+obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o
+obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
+obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
+obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
+obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
+obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
+obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
+obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o
+obj-$(CONFIG_CSRC_R4K_LIB) += csrc-r4k.o
+obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
+obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
+
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
+obj-$(CONFIG_MODULES) += mips_ksyms.o module.o
+
+obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
+
+obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o
+obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R5500) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
+obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o
+obj-$(CONFIG_CPU_XLR) += r4k_fpu.o r4k_switch.o
+
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_SMP_UP) += smp-up.o
+
+obj-$(CONFIG_MIPS_MT) += mips-mt.o
+obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o
+obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o
+obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o
+obj-$(CONFIG_MIPS_CMP) += smp-cmp.o
+obj-$(CONFIG_CPU_MIPSR2) += spram.o
+
+obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
+obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o
+obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o
+
+obj-$(CONFIG_I8259) += i8259.o
+obj-$(CONFIG_IRQ_CPU) += irq_cpu.o
+obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o
+obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o
+obj-$(CONFIG_MIPS_MSC) += irq-msc01.o
+obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o
+obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o
+obj-$(CONFIG_IRQ_GIC) += irq-gic.o
+
+obj-$(CONFIG_KPROBES) += kprobes.o
+obj-$(CONFIG_32BIT) += scall32-o32.o
+obj-$(CONFIG_64BIT) += scall64-64.o
+obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o
+obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o
+obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o
+
+obj-$(CONFIG_KGDB) += kgdb.o
+obj-$(CONFIG_PROC_FS) += proc.o
+
+obj-$(CONFIG_64BIT) += cpu-bugs64.o
+
+obj-$(CONFIG_I8253) += i8253.o
+
+obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
+
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
+obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
+
+obj-$(CONFIG_OF) += prom.o
+
+CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
+
+obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
+
+obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
+
+obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
+
+obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+
+CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
new file mode 100644
index 00000000..6b30fb2c
--- /dev/null
+++ b/arch/mips/kernel/asm-offsets.c
@@ -0,0 +1,341 @@
+/*
+ * offset.c: Calculate pt_regs and task_struct offsets.
+ *
+ * Copyright (C) 1996 David S. Miller
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ *
+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ */
+#include <linux/compat.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/kbuild.h>
+#include <linux/suspend.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+
+void output_ptreg_defines(void)
+{
+ COMMENT("MIPS pt_regs offsets.");
+ OFFSET(PT_R0, pt_regs, regs[0]);
+ OFFSET(PT_R1, pt_regs, regs[1]);
+ OFFSET(PT_R2, pt_regs, regs[2]);
+ OFFSET(PT_R3, pt_regs, regs[3]);
+ OFFSET(PT_R4, pt_regs, regs[4]);
+ OFFSET(PT_R5, pt_regs, regs[5]);
+ OFFSET(PT_R6, pt_regs, regs[6]);
+ OFFSET(PT_R7, pt_regs, regs[7]);
+ OFFSET(PT_R8, pt_regs, regs[8]);
+ OFFSET(PT_R9, pt_regs, regs[9]);
+ OFFSET(PT_R10, pt_regs, regs[10]);
+ OFFSET(PT_R11, pt_regs, regs[11]);
+ OFFSET(PT_R12, pt_regs, regs[12]);
+ OFFSET(PT_R13, pt_regs, regs[13]);
+ OFFSET(PT_R14, pt_regs, regs[14]);
+ OFFSET(PT_R15, pt_regs, regs[15]);
+ OFFSET(PT_R16, pt_regs, regs[16]);
+ OFFSET(PT_R17, pt_regs, regs[17]);
+ OFFSET(PT_R18, pt_regs, regs[18]);
+ OFFSET(PT_R19, pt_regs, regs[19]);
+ OFFSET(PT_R20, pt_regs, regs[20]);
+ OFFSET(PT_R21, pt_regs, regs[21]);
+ OFFSET(PT_R22, pt_regs, regs[22]);
+ OFFSET(PT_R23, pt_regs, regs[23]);
+ OFFSET(PT_R24, pt_regs, regs[24]);
+ OFFSET(PT_R25, pt_regs, regs[25]);
+ OFFSET(PT_R26, pt_regs, regs[26]);
+ OFFSET(PT_R27, pt_regs, regs[27]);
+ OFFSET(PT_R28, pt_regs, regs[28]);
+ OFFSET(PT_R29, pt_regs, regs[29]);
+ OFFSET(PT_R30, pt_regs, regs[30]);
+ OFFSET(PT_R31, pt_regs, regs[31]);
+ OFFSET(PT_LO, pt_regs, lo);
+ OFFSET(PT_HI, pt_regs, hi);
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ OFFSET(PT_ACX, pt_regs, acx);
+#endif
+ OFFSET(PT_EPC, pt_regs, cp0_epc);
+ OFFSET(PT_BVADDR, pt_regs, cp0_badvaddr);
+ OFFSET(PT_STATUS, pt_regs, cp0_status);
+ OFFSET(PT_CAUSE, pt_regs, cp0_cause);
+#ifdef CONFIG_MIPS_MT_SMTC
+ OFFSET(PT_TCSTATUS, pt_regs, cp0_tcstatus);
+#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ OFFSET(PT_MPL, pt_regs, mpl);
+ OFFSET(PT_MTP, pt_regs, mtp);
+#endif /* CONFIG_CPU_CAVIUM_OCTEON */
+ DEFINE(PT_SIZE, sizeof(struct pt_regs));
+ BLANK();
+}
+
+void output_task_defines(void)
+{
+ COMMENT("MIPS task_struct offsets.");
+ OFFSET(TASK_STATE, task_struct, state);
+ OFFSET(TASK_THREAD_INFO, task_struct, stack);
+ OFFSET(TASK_FLAGS, task_struct, flags);
+ OFFSET(TASK_MM, task_struct, mm);
+ OFFSET(TASK_PID, task_struct, pid);
+ DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
+ BLANK();
+}
+
+void output_thread_info_defines(void)
+{
+ COMMENT("MIPS thread_info offsets.");
+ OFFSET(TI_TASK, thread_info, task);
+ OFFSET(TI_EXEC_DOMAIN, thread_info, exec_domain);
+ OFFSET(TI_FLAGS, thread_info, flags);
+ OFFSET(TI_TP_VALUE, thread_info, tp_value);
+ OFFSET(TI_CPU, thread_info, cpu);
+ OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
+ OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
+ OFFSET(TI_RESTART_BLOCK, thread_info, restart_block);
+ OFFSET(TI_REGS, thread_info, regs);
+ DEFINE(_THREAD_SIZE, THREAD_SIZE);
+ DEFINE(_THREAD_MASK, THREAD_MASK);
+ BLANK();
+}
+
+void output_thread_defines(void)
+{
+ COMMENT("MIPS specific thread_struct offsets.");
+ OFFSET(THREAD_REG16, task_struct, thread.reg16);
+ OFFSET(THREAD_REG17, task_struct, thread.reg17);
+ OFFSET(THREAD_REG18, task_struct, thread.reg18);
+ OFFSET(THREAD_REG19, task_struct, thread.reg19);
+ OFFSET(THREAD_REG20, task_struct, thread.reg20);
+ OFFSET(THREAD_REG21, task_struct, thread.reg21);
+ OFFSET(THREAD_REG22, task_struct, thread.reg22);
+ OFFSET(THREAD_REG23, task_struct, thread.reg23);
+ OFFSET(THREAD_REG29, task_struct, thread.reg29);
+ OFFSET(THREAD_REG30, task_struct, thread.reg30);
+ OFFSET(THREAD_REG31, task_struct, thread.reg31);
+ OFFSET(THREAD_STATUS, task_struct,
+ thread.cp0_status);
+ OFFSET(THREAD_FPU, task_struct, thread.fpu);
+
+ OFFSET(THREAD_BVADDR, task_struct, \
+ thread.cp0_badvaddr);
+ OFFSET(THREAD_BUADDR, task_struct, \
+ thread.cp0_baduaddr);
+ OFFSET(THREAD_ECODE, task_struct, \
+ thread.error_code);
+ OFFSET(THREAD_TRAMP, task_struct, \
+ thread.irix_trampoline);
+ OFFSET(THREAD_OLDCTX, task_struct, \
+ thread.irix_oldctx);
+ BLANK();
+}
+
+void output_thread_fpu_defines(void)
+{
+ OFFSET(THREAD_FPR0, task_struct, thread.fpu.fpr[0]);
+ OFFSET(THREAD_FPR1, task_struct, thread.fpu.fpr[1]);
+ OFFSET(THREAD_FPR2, task_struct, thread.fpu.fpr[2]);
+ OFFSET(THREAD_FPR3, task_struct, thread.fpu.fpr[3]);
+ OFFSET(THREAD_FPR4, task_struct, thread.fpu.fpr[4]);
+ OFFSET(THREAD_FPR5, task_struct, thread.fpu.fpr[5]);
+ OFFSET(THREAD_FPR6, task_struct, thread.fpu.fpr[6]);
+ OFFSET(THREAD_FPR7, task_struct, thread.fpu.fpr[7]);
+ OFFSET(THREAD_FPR8, task_struct, thread.fpu.fpr[8]);
+ OFFSET(THREAD_FPR9, task_struct, thread.fpu.fpr[9]);
+ OFFSET(THREAD_FPR10, task_struct, thread.fpu.fpr[10]);
+ OFFSET(THREAD_FPR11, task_struct, thread.fpu.fpr[11]);
+ OFFSET(THREAD_FPR12, task_struct, thread.fpu.fpr[12]);
+ OFFSET(THREAD_FPR13, task_struct, thread.fpu.fpr[13]);
+ OFFSET(THREAD_FPR14, task_struct, thread.fpu.fpr[14]);
+ OFFSET(THREAD_FPR15, task_struct, thread.fpu.fpr[15]);
+ OFFSET(THREAD_FPR16, task_struct, thread.fpu.fpr[16]);
+ OFFSET(THREAD_FPR17, task_struct, thread.fpu.fpr[17]);
+ OFFSET(THREAD_FPR18, task_struct, thread.fpu.fpr[18]);
+ OFFSET(THREAD_FPR19, task_struct, thread.fpu.fpr[19]);
+ OFFSET(THREAD_FPR20, task_struct, thread.fpu.fpr[20]);
+ OFFSET(THREAD_FPR21, task_struct, thread.fpu.fpr[21]);
+ OFFSET(THREAD_FPR22, task_struct, thread.fpu.fpr[22]);
+ OFFSET(THREAD_FPR23, task_struct, thread.fpu.fpr[23]);
+ OFFSET(THREAD_FPR24, task_struct, thread.fpu.fpr[24]);
+ OFFSET(THREAD_FPR25, task_struct, thread.fpu.fpr[25]);
+ OFFSET(THREAD_FPR26, task_struct, thread.fpu.fpr[26]);
+ OFFSET(THREAD_FPR27, task_struct, thread.fpu.fpr[27]);
+ OFFSET(THREAD_FPR28, task_struct, thread.fpu.fpr[28]);
+ OFFSET(THREAD_FPR29, task_struct, thread.fpu.fpr[29]);
+ OFFSET(THREAD_FPR30, task_struct, thread.fpu.fpr[30]);
+ OFFSET(THREAD_FPR31, task_struct, thread.fpu.fpr[31]);
+
+ OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31);
+ BLANK();
+}
+
+void output_mm_defines(void)
+{
+ COMMENT("Size of struct page");
+ DEFINE(STRUCT_PAGE_SIZE, sizeof(struct page));
+ BLANK();
+ COMMENT("Linux mm_struct offsets.");
+ OFFSET(MM_USERS, mm_struct, mm_users);
+ OFFSET(MM_PGD, mm_struct, pgd);
+ OFFSET(MM_CONTEXT, mm_struct, context);
+ BLANK();
+ DEFINE(_PGD_T_SIZE, sizeof(pgd_t));
+ DEFINE(_PMD_T_SIZE, sizeof(pmd_t));
+ DEFINE(_PTE_T_SIZE, sizeof(pte_t));
+ BLANK();
+ DEFINE(_PGD_T_LOG2, PGD_T_LOG2);
+#ifndef __PAGETABLE_PMD_FOLDED
+ DEFINE(_PMD_T_LOG2, PMD_T_LOG2);
+#endif
+ DEFINE(_PTE_T_LOG2, PTE_T_LOG2);
+ BLANK();
+ DEFINE(_PGD_ORDER, PGD_ORDER);
+#ifndef __PAGETABLE_PMD_FOLDED
+ DEFINE(_PMD_ORDER, PMD_ORDER);
+#endif
+ DEFINE(_PTE_ORDER, PTE_ORDER);
+ BLANK();
+ DEFINE(_PMD_SHIFT, PMD_SHIFT);
+ DEFINE(_PGDIR_SHIFT, PGDIR_SHIFT);
+ BLANK();
+ DEFINE(_PTRS_PER_PGD, PTRS_PER_PGD);
+ DEFINE(_PTRS_PER_PMD, PTRS_PER_PMD);
+ DEFINE(_PTRS_PER_PTE, PTRS_PER_PTE);
+ BLANK();
+}
+
+#ifdef CONFIG_32BIT
+void output_sc_defines(void)
+{
+ COMMENT("Linux sigcontext offsets.");
+ OFFSET(SC_REGS, sigcontext, sc_regs);
+ OFFSET(SC_FPREGS, sigcontext, sc_fpregs);
+ OFFSET(SC_ACX, sigcontext, sc_acx);
+ OFFSET(SC_MDHI, sigcontext, sc_mdhi);
+ OFFSET(SC_MDLO, sigcontext, sc_mdlo);
+ OFFSET(SC_PC, sigcontext, sc_pc);
+ OFFSET(SC_FPC_CSR, sigcontext, sc_fpc_csr);
+ OFFSET(SC_FPC_EIR, sigcontext, sc_fpc_eir);
+ OFFSET(SC_HI1, sigcontext, sc_hi1);
+ OFFSET(SC_LO1, sigcontext, sc_lo1);
+ OFFSET(SC_HI2, sigcontext, sc_hi2);
+ OFFSET(SC_LO2, sigcontext, sc_lo2);
+ OFFSET(SC_HI3, sigcontext, sc_hi3);
+ OFFSET(SC_LO3, sigcontext, sc_lo3);
+ BLANK();
+}
+#endif
+
+#ifdef CONFIG_64BIT
+void output_sc_defines(void)
+{
+ COMMENT("Linux sigcontext offsets.");
+ OFFSET(SC_REGS, sigcontext, sc_regs);
+ OFFSET(SC_FPREGS, sigcontext, sc_fpregs);
+ OFFSET(SC_MDHI, sigcontext, sc_mdhi);
+ OFFSET(SC_MDLO, sigcontext, sc_mdlo);
+ OFFSET(SC_PC, sigcontext, sc_pc);
+ OFFSET(SC_FPC_CSR, sigcontext, sc_fpc_csr);
+ BLANK();
+}
+#endif
+
+#ifdef CONFIG_MIPS32_COMPAT
+void output_sc32_defines(void)
+{
+ COMMENT("Linux 32-bit sigcontext offsets.");
+ OFFSET(SC32_FPREGS, sigcontext32, sc_fpregs);
+ OFFSET(SC32_FPC_CSR, sigcontext32, sc_fpc_csr);
+ OFFSET(SC32_FPC_EIR, sigcontext32, sc_fpc_eir);
+ BLANK();
+}
+#endif
+
+void output_signal_defined(void)
+{
+ COMMENT("Linux signal numbers.");
+ DEFINE(_SIGHUP, SIGHUP);
+ DEFINE(_SIGINT, SIGINT);
+ DEFINE(_SIGQUIT, SIGQUIT);
+ DEFINE(_SIGILL, SIGILL);
+ DEFINE(_SIGTRAP, SIGTRAP);
+ DEFINE(_SIGIOT, SIGIOT);
+ DEFINE(_SIGABRT, SIGABRT);
+ DEFINE(_SIGEMT, SIGEMT);
+ DEFINE(_SIGFPE, SIGFPE);
+ DEFINE(_SIGKILL, SIGKILL);
+ DEFINE(_SIGBUS, SIGBUS);
+ DEFINE(_SIGSEGV, SIGSEGV);
+ DEFINE(_SIGSYS, SIGSYS);
+ DEFINE(_SIGPIPE, SIGPIPE);
+ DEFINE(_SIGALRM, SIGALRM);
+ DEFINE(_SIGTERM, SIGTERM);
+ DEFINE(_SIGUSR1, SIGUSR1);
+ DEFINE(_SIGUSR2, SIGUSR2);
+ DEFINE(_SIGCHLD, SIGCHLD);
+ DEFINE(_SIGPWR, SIGPWR);
+ DEFINE(_SIGWINCH, SIGWINCH);
+ DEFINE(_SIGURG, SIGURG);
+ DEFINE(_SIGIO, SIGIO);
+ DEFINE(_SIGSTOP, SIGSTOP);
+ DEFINE(_SIGTSTP, SIGTSTP);
+ DEFINE(_SIGCONT, SIGCONT);
+ DEFINE(_SIGTTIN, SIGTTIN);
+ DEFINE(_SIGTTOU, SIGTTOU);
+ DEFINE(_SIGVTALRM, SIGVTALRM);
+ DEFINE(_SIGPROF, SIGPROF);
+ DEFINE(_SIGXCPU, SIGXCPU);
+ DEFINE(_SIGXFSZ, SIGXFSZ);
+ BLANK();
+}
+
+void output_irq_cpustat_t_defines(void)
+{
+ COMMENT("Linux irq_cpustat_t offsets.");
+ DEFINE(IC_SOFTIRQ_PENDING,
+ offsetof(irq_cpustat_t, __softirq_pending));
+ DEFINE(IC_IRQ_CPUSTAT_T, sizeof(irq_cpustat_t));
+ BLANK();
+}
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+void output_octeon_cop2_state_defines(void)
+{
+ COMMENT("Octeon specific octeon_cop2_state offsets.");
+ OFFSET(OCTEON_CP2_CRC_IV, octeon_cop2_state, cop2_crc_iv);
+ OFFSET(OCTEON_CP2_CRC_LENGTH, octeon_cop2_state, cop2_crc_length);
+ OFFSET(OCTEON_CP2_CRC_POLY, octeon_cop2_state, cop2_crc_poly);
+ OFFSET(OCTEON_CP2_LLM_DAT, octeon_cop2_state, cop2_llm_dat);
+ OFFSET(OCTEON_CP2_3DES_IV, octeon_cop2_state, cop2_3des_iv);
+ OFFSET(OCTEON_CP2_3DES_KEY, octeon_cop2_state, cop2_3des_key);
+ OFFSET(OCTEON_CP2_3DES_RESULT, octeon_cop2_state, cop2_3des_result);
+ OFFSET(OCTEON_CP2_AES_INP0, octeon_cop2_state, cop2_aes_inp0);
+ OFFSET(OCTEON_CP2_AES_IV, octeon_cop2_state, cop2_aes_iv);
+ OFFSET(OCTEON_CP2_AES_KEY, octeon_cop2_state, cop2_aes_key);
+ OFFSET(OCTEON_CP2_AES_KEYLEN, octeon_cop2_state, cop2_aes_keylen);
+ OFFSET(OCTEON_CP2_AES_RESULT, octeon_cop2_state, cop2_aes_result);
+ OFFSET(OCTEON_CP2_GFM_MULT, octeon_cop2_state, cop2_gfm_mult);
+ OFFSET(OCTEON_CP2_GFM_POLY, octeon_cop2_state, cop2_gfm_poly);
+ OFFSET(OCTEON_CP2_GFM_RESULT, octeon_cop2_state, cop2_gfm_result);
+ OFFSET(OCTEON_CP2_HSH_DATW, octeon_cop2_state, cop2_hsh_datw);
+ OFFSET(OCTEON_CP2_HSH_IVW, octeon_cop2_state, cop2_hsh_ivw);
+ OFFSET(THREAD_CP2, task_struct, thread.cp2);
+ OFFSET(THREAD_CVMSEG, task_struct, thread.cvmseg.cvmseg);
+ BLANK();
+}
+#endif
+
+#ifdef CONFIG_HIBERNATION
+void output_pbe_defines(void)
+{
+ COMMENT(" Linux struct pbe offsets. ");
+ OFFSET(PBE_ADDRESS, pbe, address);
+ OFFSET(PBE_ORIG_ADDRESS, pbe, orig_address);
+ OFFSET(PBE_NEXT, pbe, next);
+ DEFINE(PBE_SIZE, sizeof(struct pbe));
+ BLANK();
+}
+#endif
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
new file mode 100644
index 00000000..9fdd8bcd
--- /dev/null
+++ b/arch/mips/kernel/binfmt_elfn32.c
@@ -0,0 +1,122 @@
+/*
+ * Support for n32 Linux/MIPS ELF binaries.
+ *
+ * Copyright (C) 1999, 2001 Ralf Baechle
+ * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
+ *
+ * Heavily inspired by the 32-bit Sparc compat code which is
+ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#define ELF_ARCH EM_MIPS
+#define ELF_CLASS ELFCLASS32
+#ifdef __MIPSEB__
+#define ELF_DATA ELFDATA2MSB;
+#else /* __MIPSEL__ */
+#define ELF_DATA ELFDATA2LSB;
+#endif
+
+/* ELF register definitions */
+#define ELF_NGREG 45
+#define ELF_NFPREG 33
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(hdr) \
+({ \
+ int __res = 1; \
+ struct elfhdr *__h = (hdr); \
+ \
+ if (__h->e_machine != EM_MIPS) \
+ __res = 0; \
+ if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
+ __res = 0; \
+ if (((__h->e_flags & EF_MIPS_ABI2) == 0) || \
+ ((__h->e_flags & EF_MIPS_ABI) != 0)) \
+ __res = 0; \
+ \
+ __res; \
+})
+
+#define TASK32_SIZE 0x7fff8000UL
+#undef ELF_ET_DYN_BASE
+#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
+
+#include <asm/processor.h>
+#include <linux/module.h>
+#include <linux/elfcore.h>
+#include <linux/compat.h>
+#include <linux/math64.h>
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+ struct elf_siginfo pr_info; /* Info associated with signal */
+ short pr_cursig; /* Current signal */
+ unsigned int pr_sigpend; /* Set of pending signals */
+ unsigned int pr_sighold; /* Set of held signals */
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct compat_timeval pr_utime; /* User time */
+ struct compat_timeval pr_stime; /* System time */
+ struct compat_timeval pr_cutime;/* Cumulative user time */
+ struct compat_timeval pr_cstime;/* Cumulative system time */
+ elf_gregset_t pr_reg; /* GP registers */
+ int pr_fpvalid; /* True if math co-processor being used. */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+ char pr_state; /* numeric process state */
+ char pr_sname; /* char for pr_state */
+ char pr_zomb; /* zombie */
+ char pr_nice; /* nice val */
+ unsigned int pr_flag; /* flags */
+ __kernel_uid_t pr_uid;
+ __kernel_gid_t pr_gid;
+ pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* filename of executable */
+ char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
+};
+
+#define elf_caddr_t u32
+#define init_elf_binfmt init_elfn32_binfmt
+
+#define jiffies_to_timeval jiffies_to_compat_timeval
+static __inline__ void
+jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+{
+ /*
+ * Convert jiffies to nanoseconds and separate with
+ * one divide.
+ */
+ u64 nsec = (u64)jiffies * TICK_NSEC;
+ u32 rem;
+ value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
+ value->tv_usec = rem / NSEC_PER_USEC;
+}
+
+#define ELF_CORE_EFLAGS EF_MIPS_ABI2
+
+MODULE_DESCRIPTION("Binary format loader for compatibility with n32 Linux/MIPS binaries");
+MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
+
+#undef MODULE_DESCRIPTION
+#undef MODULE_AUTHOR
+
+#undef TASK_SIZE
+#define TASK_SIZE TASK_SIZE32
+
+#include "../../../fs/binfmt_elf.c"
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
new file mode 100644
index 00000000..ff448233
--- /dev/null
+++ b/arch/mips/kernel/binfmt_elfo32.c
@@ -0,0 +1,161 @@
+/*
+ * Support for o32 Linux/MIPS ELF binaries.
+ *
+ * Copyright (C) 1999, 2001 Ralf Baechle
+ * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
+ *
+ * Heavily inspired by the 32-bit Sparc compat code which is
+ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#define ELF_ARCH EM_MIPS
+#define ELF_CLASS ELFCLASS32
+#ifdef __MIPSEB__
+#define ELF_DATA ELFDATA2MSB;
+#else /* __MIPSEL__ */
+#define ELF_DATA ELFDATA2LSB;
+#endif
+
+/* ELF register definitions */
+#define ELF_NGREG 45
+#define ELF_NFPREG 33
+
+typedef unsigned int elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(hdr) \
+({ \
+ int __res = 1; \
+ struct elfhdr *__h = (hdr); \
+ \
+ if (__h->e_machine != EM_MIPS) \
+ __res = 0; \
+ if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
+ __res = 0; \
+ if ((__h->e_flags & EF_MIPS_ABI2) != 0) \
+ __res = 0; \
+ if (((__h->e_flags & EF_MIPS_ABI) != 0) && \
+ ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \
+ __res = 0; \
+ \
+ __res; \
+})
+
+#define TASK32_SIZE 0x7fff8000UL
+#undef ELF_ET_DYN_BASE
+#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
+
+#include <asm/processor.h>
+
+/*
+ * When this file is selected, we are definitely running a 64bit kernel.
+ * So using the right regs define in asm/reg.h
+ */
+#define WANT_COMPAT_REG_H
+
+/* These MUST be defined before elf.h gets included */
+extern void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs);
+#define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs);
+#define ELF_CORE_COPY_TASK_REGS(_tsk, _dest) \
+({ \
+ int __res = 1; \
+ elf32_core_copy_regs(*(_dest), task_pt_regs(_tsk)); \
+ __res; \
+})
+
+#include <linux/module.h>
+#include <linux/elfcore.h>
+#include <linux/compat.h>
+#include <linux/math64.h>
+
+#define elf_prstatus elf_prstatus32
+struct elf_prstatus32
+{
+ struct elf_siginfo pr_info; /* Info associated with signal */
+ short pr_cursig; /* Current signal */
+ unsigned int pr_sigpend; /* Set of pending signals */
+ unsigned int pr_sighold; /* Set of held signals */
+ pid_t pr_pid;
+ pid_t pr_ppid;
+ pid_t pr_pgrp;
+ pid_t pr_sid;
+ struct compat_timeval pr_utime; /* User time */
+ struct compat_timeval pr_stime; /* System time */
+ struct compat_timeval pr_cutime;/* Cumulative user time */
+ struct compat_timeval pr_cstime;/* Cumulative system time */
+ elf_gregset_t pr_reg; /* GP registers */
+ int pr_fpvalid; /* True if math co-processor being used. */
+};
+
+#define elf_prpsinfo elf_prpsinfo32
+struct elf_prpsinfo32
+{
+ char pr_state; /* numeric process state */
+ char pr_sname; /* char for pr_state */
+ char pr_zomb; /* zombie */
+ char pr_nice; /* nice val */
+ unsigned int pr_flag; /* flags */
+ __kernel_uid_t pr_uid;
+ __kernel_gid_t pr_gid;
+ pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ /* Lots missing */
+ char pr_fname[16]; /* filename of executable */
+ char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
+};
+
+#define elf_caddr_t u32
+#define init_elf_binfmt init_elf32_binfmt
+
+#define jiffies_to_timeval jiffies_to_compat_timeval
+static inline void
+jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+{
+ /*
+ * Convert jiffies to nanoseconds and separate with
+ * one divide.
+ */
+ u64 nsec = (u64)jiffies * TICK_NSEC;
+ u32 rem;
+ value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
+ value->tv_usec = rem / NSEC_PER_USEC;
+}
+
+void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs)
+{
+ int i;
+
+ for (i = 0; i < EF_R0; i++)
+ grp[i] = 0;
+ grp[EF_R0] = 0;
+ for (i = 1; i <= 31; i++)
+ grp[EF_R0 + i] = (elf_greg_t) regs->regs[i];
+ grp[EF_R26] = 0;
+ grp[EF_R27] = 0;
+ grp[EF_LO] = (elf_greg_t) regs->lo;
+ grp[EF_HI] = (elf_greg_t) regs->hi;
+ grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc;
+ grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr;
+ grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status;
+ grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause;
+#ifdef EF_UNUSED0
+ grp[EF_UNUSED0] = 0;
+#endif
+}
+
+MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries");
+MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)");
+
+#undef MODULE_DESCRIPTION
+#undef MODULE_AUTHOR
+
+#undef TASK_SIZE
+#define TASK_SIZE TASK_SIZE32
+
+#include "../../../fs/binfmt_elf.c"
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
new file mode 100644
index 00000000..32103cc2
--- /dev/null
+++ b/arch/mips/kernel/branch.c
@@ -0,0 +1,253 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 97, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/branch.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/fpu.h>
+#include <asm/inst.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+/*
+ * Compute the return address and do emulate branch simulation, if required.
+ */
+int __compute_return_epc(struct pt_regs *regs)
+{
+ unsigned int __user *addr;
+ unsigned int bit, fcr31, dspcontrol;
+ long epc;
+ union mips_instruction insn;
+
+ epc = regs->cp0_epc;
+ if (epc & 3)
+ goto unaligned;
+
+ /*
+ * Read the instruction
+ */
+ addr = (unsigned int __user *) epc;
+ if (__get_user(insn.word, addr)) {
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+ }
+
+ switch (insn.i_format.opcode) {
+ /*
+ * jr and jalr are in r_format format.
+ */
+ case spec_op:
+ switch (insn.r_format.func) {
+ case jalr_op:
+ regs->regs[insn.r_format.rd] = epc + 8;
+ /* Fall through */
+ case jr_op:
+ regs->cp0_epc = regs->regs[insn.r_format.rs];
+ break;
+ }
+ break;
+
+ /*
+ * This group contains:
+ * bltz_op, bgez_op, bltzl_op, bgezl_op,
+ * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
+ */
+ case bcond_op:
+ switch (insn.i_format.rt) {
+ case bltz_op:
+ case bltzl_op:
+ if ((long)regs->regs[insn.i_format.rs] < 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bgez_op:
+ case bgezl_op:
+ if ((long)regs->regs[insn.i_format.rs] >= 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bltzal_op:
+ case bltzall_op:
+ regs->regs[31] = epc + 8;
+ if ((long)regs->regs[insn.i_format.rs] < 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bgezal_op:
+ case bgezall_op:
+ regs->regs[31] = epc + 8;
+ if ((long)regs->regs[insn.i_format.rs] >= 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ case bposge32_op:
+ if (!cpu_has_dsp)
+ goto sigill;
+
+ dspcontrol = rddsp(0x01);
+
+ if (dspcontrol >= 32) {
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ } else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ }
+ break;
+
+ /*
+ * These are unconditional and in j_format.
+ */
+ case jal_op:
+ regs->regs[31] = regs->cp0_epc + 8;
+ case j_op:
+ epc += 4;
+ epc >>= 28;
+ epc <<= 28;
+ epc |= (insn.j_format.target << 2);
+ regs->cp0_epc = epc;
+ break;
+
+ /*
+ * These are conditional and in i_format.
+ */
+ case beq_op:
+ case beql_op:
+ if (regs->regs[insn.i_format.rs] ==
+ regs->regs[insn.i_format.rt])
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bne_op:
+ case bnel_op:
+ if (regs->regs[insn.i_format.rs] !=
+ regs->regs[insn.i_format.rt])
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case blez_op: /* not really i_format */
+ case blezl_op:
+ /* rt field assumed to be zero */
+ if ((long)regs->regs[insn.i_format.rs] <= 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case bgtz_op:
+ case bgtzl_op:
+ /* rt field assumed to be zero */
+ if ((long)regs->regs[insn.i_format.rs] > 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ /*
+ * And now the FPA/cp1 branch instructions.
+ */
+ case cop1_op:
+ preempt_disable();
+ if (is_fpu_owner())
+ asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
+ else
+ fcr31 = current->thread.fpu.fcr31;
+ preempt_enable();
+
+ bit = (insn.i_format.rt >> 2);
+ bit += (bit != 0);
+ bit += 23;
+ switch (insn.i_format.rt & 3) {
+ case 0: /* bc1f */
+ case 2: /* bc1fl */
+ if (~fcr31 & (1 << bit))
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+
+ case 1: /* bc1t */
+ case 3: /* bc1tl */
+ if (fcr31 & (1 << bit))
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ }
+ break;
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ case lwc2_op: /* This is bbit0 on Octeon */
+ if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
+ == 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ case ldc2_op: /* This is bbit032 on Octeon */
+ if ((regs->regs[insn.i_format.rs] &
+ (1ull<<(insn.i_format.rt+32))) == 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ case swc2_op: /* This is bbit1 on Octeon */
+ if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ case sdc2_op: /* This is bbit132 on Octeon */
+ if (regs->regs[insn.i_format.rs] &
+ (1ull<<(insn.i_format.rt+32)))
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+#endif
+ }
+
+ return 0;
+
+unaligned:
+ printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
+ force_sig(SIGBUS, current);
+ return -EFAULT;
+
+sigill:
+ printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
+ force_sig(SIGBUS, current);
+ return -EFAULT;
+}
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c
new file mode 100644
index 00000000..36c3898b
--- /dev/null
+++ b/arch/mips/kernel/cevt-bcm1480.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2000,2001,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/time.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+#include <asm/sibyte/bcm1480_scd.h>
+
+#include <asm/sibyte/sb1250.h>
+
+#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0
+#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
+#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
+
+/*
+ * The general purpose timer ticks at 1MHz independent if
+ * the rest of the system
+ */
+static void sibyte_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned int cpu = smp_processor_id();
+ void __iomem *cfg, *init;
+
+ cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+ init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ __raw_writeq(0, cfg);
+ __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ cfg);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Stop the timer until we actually program a shot */
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ __raw_writeq(0, cfg);
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
+ case CLOCK_EVT_MODE_RESUME:
+ ;
+ }
+}
+
+static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
+{
+ unsigned int cpu = smp_processor_id();
+ void __iomem *cfg, *init;
+
+ cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+ init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+
+ __raw_writeq(0, cfg);
+ __raw_writeq(delta - 1, init);
+ __raw_writeq(M_SCD_TIMER_ENABLE, cfg);
+
+ return 0;
+}
+
+static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd = dev_id;
+ void __iomem *cfg;
+ unsigned long tmode;
+
+ if (cd->mode == CLOCK_EVT_MODE_PERIODIC)
+ tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
+ else
+ tmode = 0;
+
+ /* ACK interrupt */
+ cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+ ____raw_writeq(tmode, cfg);
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
+static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
+
+void __cpuinit sb1480_clockevent_init(void)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
+ struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
+ struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
+ unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
+
+ BUG_ON(cpu > 3); /* Only have 4 general purpose timers */
+
+ sprintf(name, "bcm1480-counter-%d", cpu);
+ cd->name = name;
+ cd->features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT;
+ clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(2, cd);
+ cd->rating = 200;
+ cd->irq = irq;
+ cd->cpumask = cpumask_of(cpu);
+ cd->set_next_event = sibyte_next_event;
+ cd->set_mode = sibyte_set_mode;
+ clockevents_register_device(cd);
+
+ bcm1480_mask_irq(cpu, irq);
+
+ /*
+ * Map the timer interrupt to IP[4] of this cpu
+ */
+ __raw_writeq(IMR_IP4_VAL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+ R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
+
+ bcm1480_unmask_irq(cpu, irq);
+
+ action->handler = sibyte_counter_handler;
+ action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER;
+ action->name = name;
+ action->dev_id = cd;
+
+ irq_set_affinity(irq, cpumask_of(cpu));
+ setup_irq(irq, action);
+}
diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c
new file mode 100644
index 00000000..939157e3
--- /dev/null
+++ b/arch/mips/kernel/cevt-ds1287.c
@@ -0,0 +1,130 @@
+/*
+ * DS1287 clockevent driver
+ *
+ * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/irq.h>
+
+#include <asm/time.h>
+
+int ds1287_timer_state(void)
+{
+ return (CMOS_READ(RTC_REG_C) & RTC_PF) != 0;
+}
+
+int ds1287_set_base_clock(unsigned int hz)
+{
+ u8 rate;
+
+ switch (hz) {
+ case 128:
+ rate = 0x9;
+ break;
+ case 256:
+ rate = 0x8;
+ break;
+ case 1024:
+ rate = 0x6;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ CMOS_WRITE(RTC_REF_CLCK_32KHZ | rate, RTC_REG_A);
+
+ return 0;
+}
+
+static int ds1287_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ return -EINVAL;
+}
+
+static void ds1287_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u8 val;
+
+ spin_lock(&rtc_lock);
+
+ val = CMOS_READ(RTC_REG_B);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ val |= RTC_PIE;
+ break;
+ default:
+ val &= ~RTC_PIE;
+ break;
+ }
+
+ CMOS_WRITE(val, RTC_REG_B);
+
+ spin_unlock(&rtc_lock);
+}
+
+static void ds1287_event_handler(struct clock_event_device *dev)
+{
+}
+
+static struct clock_event_device ds1287_clockevent = {
+ .name = "ds1287",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .set_next_event = ds1287_set_next_event,
+ .set_mode = ds1287_set_mode,
+ .event_handler = ds1287_event_handler,
+};
+
+static irqreturn_t ds1287_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = &ds1287_clockevent;
+
+ /* Ack the RTC interrupt. */
+ CMOS_READ(RTC_REG_C);
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ds1287_irqaction = {
+ .handler = ds1287_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "ds1287",
+};
+
+int __init ds1287_clockevent_init(int irq)
+{
+ struct clock_event_device *cd;
+
+ cd = &ds1287_clockevent;
+ cd->rating = 100;
+ cd->irq = irq;
+ clockevent_set_clock(cd, 32768);
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+ cd->cpumask = cpumask_of(0);
+
+ clockevents_register_device(&ds1287_clockevent);
+
+ return setup_irq(irq, &ds1287_irqaction);
+}
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
new file mode 100644
index 00000000..339f3639
--- /dev/null
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -0,0 +1,141 @@
+/*
+ * GT641xx clockevent routines.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+
+#include <asm/gt64120.h>
+#include <asm/time.h>
+
+static DEFINE_RAW_SPINLOCK(gt641xx_timer_lock);
+static unsigned int gt641xx_base_clock;
+
+void gt641xx_set_base_clock(unsigned int clock)
+{
+ gt641xx_base_clock = clock;
+}
+
+int gt641xx_timer0_state(void)
+{
+ if (GT_READ(GT_TC0_OFS))
+ return 0;
+
+ GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
+ GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK);
+
+ return 1;
+}
+
+static int gt641xx_timer0_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ u32 ctrl;
+
+ raw_spin_lock(&gt641xx_timer_lock);
+
+ ctrl = GT_READ(GT_TC_CONTROL_OFS);
+ ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
+ ctrl |= GT_TC_CONTROL_ENTC0_MSK;
+
+ GT_WRITE(GT_TC0_OFS, delta);
+ GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
+
+ raw_spin_unlock(&gt641xx_timer_lock);
+
+ return 0;
+}
+
+static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 ctrl;
+
+ raw_spin_lock(&gt641xx_timer_lock);
+
+ ctrl = GT_READ(GT_TC_CONTROL_OFS);
+ ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ ctrl |= GT_TC_CONTROL_ENTC0_MSK;
+ break;
+ default:
+ break;
+ }
+
+ GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
+
+ raw_spin_unlock(&gt641xx_timer_lock);
+}
+
+static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
+{
+}
+
+static struct clock_event_device gt641xx_timer0_clockevent = {
+ .name = "gt641xx-timer0",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .irq = GT641XX_TIMER0_IRQ,
+ .set_next_event = gt641xx_timer0_set_next_event,
+ .set_mode = gt641xx_timer0_set_mode,
+ .event_handler = gt641xx_timer0_event_handler,
+};
+
+static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = &gt641xx_timer0_clockevent;
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction gt641xx_timer0_irqaction = {
+ .handler = gt641xx_timer0_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "gt641xx_timer0",
+};
+
+static int __init gt641xx_timer0_clockevent_init(void)
+{
+ struct clock_event_device *cd;
+
+ if (!gt641xx_base_clock)
+ return 0;
+
+ GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
+
+ cd = &gt641xx_timer0_clockevent;
+ cd->rating = 200 + gt641xx_base_clock / 10000000;
+ clockevent_set_clock(cd, gt641xx_base_clock);
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+ cd->cpumask = cpumask_of(0);
+
+ clockevents_register_device(&gt641xx_timer0_clockevent);
+
+ return setup_irq(GT641XX_TIMER0_IRQ, &gt641xx_timer0_irqaction);
+}
+arch_initcall(gt641xx_timer0_clockevent_init);
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
new file mode 100644
index 00000000..98c5a973
--- /dev/null
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -0,0 +1,216 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+
+#include <asm/smtc_ipi.h>
+#include <asm/time.h>
+#include <asm/cevt-r4k.h>
+
+/*
+ * The SMTC Kernel for the 34K, 1004K, et. al. replaces several
+ * of these routines with SMTC-specific variants.
+ */
+
+#ifndef CONFIG_MIPS_MT_SMTC
+
+static int mips_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned int cnt;
+ int res;
+
+ cnt = read_c0_count();
+ cnt += delta;
+ write_c0_compare(cnt);
+ res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
+ return res;
+}
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+void mips_set_clock_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Nothing to do ... */
+}
+
+DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+int cp0_timer_irq_installed;
+
+#ifndef CONFIG_MIPS_MT_SMTC
+
+irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
+{
+ const int r2 = cpu_has_mips_r2;
+ struct clock_event_device *cd;
+ int cpu = smp_processor_id();
+
+ /*
+ * Suckage alert:
+ * Before R2 of the architecture there was no way to see if a
+ * performance counter interrupt was pending, so we have to run
+ * the performance counter interrupt handler anyway.
+ */
+ if (handle_perf_irq(r2))
+ goto out;
+
+ /*
+ * The same applies to performance counter interrupts. But with the
+ * above we now know that the reason we got here must be a timer
+ * interrupt. Being the paranoiacs we are we check anyway.
+ */
+ if (!r2 || (read_c0_cause() & (1 << 30))) {
+ /* Clear Count/Compare Interrupt */
+ write_c0_compare(read_c0_compare());
+ cd = &per_cpu(mips_clockevent_device, cpu);
+ cd->event_handler(cd);
+ }
+
+out:
+ return IRQ_HANDLED;
+}
+
+#endif /* Not CONFIG_MIPS_MT_SMTC */
+
+struct irqaction c0_compare_irqaction = {
+ .handler = c0_compare_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "timer",
+};
+
+
+void mips_event_handler(struct clock_event_device *dev)
+{
+}
+
+/*
+ * FIXME: This doesn't hold for the relocated E9000 compare interrupt.
+ */
+static int c0_compare_int_pending(void)
+{
+ return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP);
+}
+
+/*
+ * Compare interrupt can be routed and latched outside the core,
+ * so a single execution hazard barrier may not be enough to give
+ * it time to clear as seen in the Cause register. 4 time the
+ * pipeline depth seems reasonably conservative, and empirically
+ * works better in configurations with high CPU/bus clock ratios.
+ */
+
+#define compare_change_hazard() \
+ do { \
+ irq_disable_hazard(); \
+ irq_disable_hazard(); \
+ irq_disable_hazard(); \
+ irq_disable_hazard(); \
+ } while (0)
+
+int c0_compare_int_usable(void)
+{
+ unsigned int delta;
+ unsigned int cnt;
+
+ /*
+ * IP7 already pending? Try to clear it by acking the timer.
+ */
+ if (c0_compare_int_pending()) {
+ write_c0_compare(read_c0_count());
+ compare_change_hazard();
+ if (c0_compare_int_pending())
+ return 0;
+ }
+
+ for (delta = 0x10; delta <= 0x400000; delta <<= 1) {
+ cnt = read_c0_count();
+ cnt += delta;
+ write_c0_compare(cnt);
+ compare_change_hazard();
+ if ((int)(read_c0_count() - cnt) < 0)
+ break;
+ /* increase delta if the timer was already expired */
+ }
+
+ while ((int)(read_c0_count() - cnt) <= 0)
+ ; /* Wait for expiry */
+
+ compare_change_hazard();
+ if (!c0_compare_int_pending())
+ return 0;
+
+ write_c0_compare(read_c0_count());
+ compare_change_hazard();
+ if (c0_compare_int_pending())
+ return 0;
+
+ /*
+ * Feels like a real count / compare timer.
+ */
+ return 1;
+}
+
+#ifndef CONFIG_MIPS_MT_SMTC
+
+int __cpuinit r4k_clockevent_init(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
+ unsigned int irq;
+
+ if (!cpu_has_counter || !mips_hpt_frequency)
+ return -ENXIO;
+
+ if (!c0_compare_int_usable())
+ return -ENXIO;
+
+ /*
+ * With vectored interrupts things are getting platform specific.
+ * get_c0_compare_int is a hook to allow a platform to return the
+ * interrupt number of it's liking.
+ */
+ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+ if (get_c0_compare_int)
+ irq = get_c0_compare_int();
+
+ cd = &per_cpu(mips_clockevent_device, cpu);
+
+ cd->name = "MIPS";
+ cd->features = CLOCK_EVT_FEAT_ONESHOT;
+
+ clockevent_set_clock(cd, mips_hpt_frequency);
+
+ /* Calculate the min / max delta */
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+
+ cd->rating = 300;
+ cd->irq = irq;
+ cd->cpumask = cpumask_of(cpu);
+ cd->set_next_event = mips_next_event;
+ cd->set_mode = mips_set_clock_mode;
+ cd->event_handler = mips_event_handler;
+
+ clockevents_register_device(cd);
+
+ if (cp0_timer_irq_installed)
+ return 0;
+
+ cp0_timer_irq_installed = 1;
+
+ setup_irq(irq, &c0_compare_irqaction);
+
+ return 0;
+}
+
+#endif /* Not CONFIG_MIPS_MT_SMTC */
diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c
new file mode 100644
index 00000000..590c54f2
--- /dev/null
+++ b/arch/mips/kernel/cevt-sb1250.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
+#include <linux/smp.h>
+
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/time.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+#define IMR_IP2_VAL K_INT_MAP_I0
+#define IMR_IP3_VAL K_INT_MAP_I1
+#define IMR_IP4_VAL K_INT_MAP_I2
+
+/*
+ * The general purpose timer ticks at 1MHz independent if
+ * the rest of the system
+ */
+static void sibyte_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned int cpu = smp_processor_id();
+ void __iomem *cfg, *init;
+
+ cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+ init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ __raw_writeq(0, cfg);
+ __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ cfg);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Stop the timer until we actually program a shot */
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ __raw_writeq(0, cfg);
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
+ case CLOCK_EVT_MODE_RESUME:
+ ;
+ }
+}
+
+static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
+{
+ unsigned int cpu = smp_processor_id();
+ void __iomem *cfg, *init;
+
+ cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+ init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+
+ __raw_writeq(0, cfg);
+ __raw_writeq(delta - 1, init);
+ __raw_writeq(M_SCD_TIMER_ENABLE, cfg);
+
+ return 0;
+}
+
+static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd = dev_id;
+ void __iomem *cfg;
+ unsigned long tmode;
+
+ if (cd->mode == CLOCK_EVT_MODE_PERIODIC)
+ tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
+ else
+ tmode = 0;
+
+ /* ACK interrupt */
+ cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
+ ____raw_writeq(tmode, cfg);
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
+static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
+
+void __cpuinit sb1250_clockevent_init(void)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned int irq = K_INT_TIMER_0 + cpu;
+ struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
+ struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
+ unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
+
+ /* Only have 4 general purpose timers, and we use last one as hpt */
+ BUG_ON(cpu > 2);
+
+ sprintf(name, "sb1250-counter-%d", cpu);
+ cd->name = name;
+ cd->features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT;
+ clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(2, cd);
+ cd->rating = 200;
+ cd->irq = irq;
+ cd->cpumask = cpumask_of(cpu);
+ cd->set_next_event = sibyte_next_event;
+ cd->set_mode = sibyte_set_mode;
+ clockevents_register_device(cd);
+
+ sb1250_mask_irq(cpu, irq);
+
+ /*
+ * Map the timer interrupt to IP[4] of this cpu
+ */
+ __raw_writeq(IMR_IP4_VAL,
+ IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
+ (irq << 3)));
+
+ sb1250_unmask_irq(cpu, irq);
+
+ action->handler = sibyte_counter_handler;
+ action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER;
+ action->name = name;
+ action->dev_id = cd;
+
+ irq_set_affinity(irq, cpumask_of(cpu));
+ setup_irq(irq, action);
+}
diff --git a/arch/mips/kernel/cevt-smtc.c b/arch/mips/kernel/cevt-smtc.c
new file mode 100644
index 00000000..2e72d30b
--- /dev/null
+++ b/arch/mips/kernel/cevt-smtc.c
@@ -0,0 +1,324 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2008 Kevin D. Kissell, Paralogos sarl
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+
+#include <asm/smtc_ipi.h>
+#include <asm/time.h>
+#include <asm/cevt-r4k.h>
+
+/*
+ * Variant clock event timer support for SMTC on MIPS 34K, 1004K
+ * or other MIPS MT cores.
+ *
+ * Notes on SMTC Support:
+ *
+ * SMTC has multiple microthread TCs pretending to be Linux CPUs.
+ * But there's only one Count/Compare pair per VPE, and Compare
+ * interrupts are taken opportunisitically by available TCs
+ * bound to the VPE with the Count register. The new timer
+ * framework provides for global broadcasts, but we really
+ * want VPE-level multicasts for best behavior. So instead
+ * of invoking the high-level clock-event broadcast code,
+ * this version of SMTC support uses the historical SMTC
+ * multicast mechanisms "under the hood", appearing to the
+ * generic clock layer as if the interrupts are per-CPU.
+ *
+ * The approach taken here is to maintain a set of NR_CPUS
+ * virtual timers, and track which "CPU" needs to be alerted
+ * at each event.
+ *
+ * It's unlikely that we'll see a MIPS MT core with more than
+ * 2 VPEs, but we *know* that we won't need to handle more
+ * VPEs than we have "CPUs". So NCPUs arrays of NCPUs elements
+ * is always going to be overkill, but always going to be enough.
+ */
+
+unsigned long smtc_nexttime[NR_CPUS][NR_CPUS];
+static int smtc_nextinvpe[NR_CPUS];
+
+/*
+ * Timestamps stored are absolute values to be programmed
+ * into Count register. Valid timestamps will never be zero.
+ * If a Zero Count value is actually calculated, it is converted
+ * to be a 1, which will introduce 1 or two CPU cycles of error
+ * roughly once every four billion events, which at 1000 HZ means
+ * about once every 50 days. If that's actually a problem, one
+ * could alternate squashing 0 to 1 and to -1.
+ */
+
+#define MAKEVALID(x) (((x) == 0L) ? 1L : (x))
+#define ISVALID(x) ((x) != 0L)
+
+/*
+ * Time comparison is subtle, as it's really truncated
+ * modular arithmetic.
+ */
+
+#define IS_SOONER(a, b, reference) \
+ (((a) - (unsigned long)(reference)) < ((b) - (unsigned long)(reference)))
+
+/*
+ * CATCHUP_INCREMENT, used when the function falls behind the counter.
+ * Could be an increasing function instead of a constant;
+ */
+
+#define CATCHUP_INCREMENT 64
+
+static int mips_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+ unsigned int mtflags;
+ unsigned long timestamp, reference, previous;
+ unsigned long nextcomp = 0L;
+ int vpe = current_cpu_data.vpe_id;
+ int cpu = smp_processor_id();
+ local_irq_save(flags);
+ mtflags = dmt();
+
+ /*
+ * Maintain the per-TC virtual timer
+ * and program the per-VPE shared Count register
+ * as appropriate here...
+ */
+ reference = (unsigned long)read_c0_count();
+ timestamp = MAKEVALID(reference + delta);
+ /*
+ * To really model the clock, we have to catch the case
+ * where the current next-in-VPE timestamp is the old
+ * timestamp for the calling CPE, but the new value is
+ * in fact later. In that case, we have to do a full
+ * scan and discover the new next-in-VPE CPU id and
+ * timestamp.
+ */
+ previous = smtc_nexttime[vpe][cpu];
+ if (cpu == smtc_nextinvpe[vpe] && ISVALID(previous)
+ && IS_SOONER(previous, timestamp, reference)) {
+ int i;
+ int soonest = cpu;
+
+ /*
+ * Update timestamp array here, so that new
+ * value gets considered along with those of
+ * other virtual CPUs on the VPE.
+ */
+ smtc_nexttime[vpe][cpu] = timestamp;
+ for_each_online_cpu(i) {
+ if (ISVALID(smtc_nexttime[vpe][i])
+ && IS_SOONER(smtc_nexttime[vpe][i],
+ smtc_nexttime[vpe][soonest], reference)) {
+ soonest = i;
+ }
+ }
+ smtc_nextinvpe[vpe] = soonest;
+ nextcomp = smtc_nexttime[vpe][soonest];
+ /*
+ * Otherwise, we don't have to process the whole array rank,
+ * we just have to see if the event horizon has gotten closer.
+ */
+ } else {
+ if (!ISVALID(smtc_nexttime[vpe][smtc_nextinvpe[vpe]]) ||
+ IS_SOONER(timestamp,
+ smtc_nexttime[vpe][smtc_nextinvpe[vpe]], reference)) {
+ smtc_nextinvpe[vpe] = cpu;
+ nextcomp = timestamp;
+ }
+ /*
+ * Since next-in-VPE may me the same as the executing
+ * virtual CPU, we update the array *after* checking
+ * its value.
+ */
+ smtc_nexttime[vpe][cpu] = timestamp;
+ }
+
+ /*
+ * It may be that, in fact, we don't need to update Compare,
+ * but if we do, we want to make sure we didn't fall into
+ * a crack just behind Count.
+ */
+ if (ISVALID(nextcomp)) {
+ write_c0_compare(nextcomp);
+ ehb();
+ /*
+ * We never return an error, we just make sure
+ * that we trigger the handlers as quickly as
+ * we can if we fell behind.
+ */
+ while ((nextcomp - (unsigned long)read_c0_count())
+ > (unsigned long)LONG_MAX) {
+ nextcomp += CATCHUP_INCREMENT;
+ write_c0_compare(nextcomp);
+ ehb();
+ }
+ }
+ emt(mtflags);
+ local_irq_restore(flags);
+ return 0;
+}
+
+
+void smtc_distribute_timer(int vpe)
+{
+ unsigned long flags;
+ unsigned int mtflags;
+ int cpu;
+ struct clock_event_device *cd;
+ unsigned long nextstamp;
+ unsigned long reference;
+
+
+repeat:
+ nextstamp = 0L;
+ for_each_online_cpu(cpu) {
+ /*
+ * Find virtual CPUs within the current VPE who have
+ * unserviced timer requests whose time is now past.
+ */
+ local_irq_save(flags);
+ mtflags = dmt();
+ if (cpu_data[cpu].vpe_id == vpe &&
+ ISVALID(smtc_nexttime[vpe][cpu])) {
+ reference = (unsigned long)read_c0_count();
+ if ((smtc_nexttime[vpe][cpu] - reference)
+ > (unsigned long)LONG_MAX) {
+ smtc_nexttime[vpe][cpu] = 0L;
+ emt(mtflags);
+ local_irq_restore(flags);
+ /*
+ * We don't send IPIs to ourself.
+ */
+ if (cpu != smp_processor_id()) {
+ smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
+ } else {
+ cd = &per_cpu(mips_clockevent_device, cpu);
+ cd->event_handler(cd);
+ }
+ } else {
+ /* Local to VPE but Valid Time not yet reached. */
+ if (!ISVALID(nextstamp) ||
+ IS_SOONER(smtc_nexttime[vpe][cpu], nextstamp,
+ reference)) {
+ smtc_nextinvpe[vpe] = cpu;
+ nextstamp = smtc_nexttime[vpe][cpu];
+ }
+ emt(mtflags);
+ local_irq_restore(flags);
+ }
+ } else {
+ emt(mtflags);
+ local_irq_restore(flags);
+
+ }
+ }
+ /* Reprogram for interrupt at next soonest timestamp for VPE */
+ if (ISVALID(nextstamp)) {
+ write_c0_compare(nextstamp);
+ ehb();
+ if ((nextstamp - (unsigned long)read_c0_count())
+ > (unsigned long)LONG_MAX)
+ goto repeat;
+ }
+}
+
+
+irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
+{
+ int cpu = smp_processor_id();
+
+ /* If we're running SMTC, we've got MIPS MT and therefore MIPS32R2 */
+ handle_perf_irq(1);
+
+ if (read_c0_cause() & (1 << 30)) {
+ /* Clear Count/Compare Interrupt */
+ write_c0_compare(read_c0_compare());
+ smtc_distribute_timer(cpu_data[cpu].vpe_id);
+ }
+ return IRQ_HANDLED;
+}
+
+
+int __cpuinit smtc_clockevent_init(void)
+{
+ uint64_t mips_freq = mips_hpt_frequency;
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
+ unsigned int irq;
+ int i;
+ int j;
+
+ if (!cpu_has_counter || !mips_hpt_frequency)
+ return -ENXIO;
+ if (cpu == 0) {
+ for (i = 0; i < num_possible_cpus(); i++) {
+ smtc_nextinvpe[i] = 0;
+ for (j = 0; j < num_possible_cpus(); j++)
+ smtc_nexttime[i][j] = 0L;
+ }
+ /*
+ * SMTC also can't have the usablility test
+ * run by secondary TCs once Compare is in use.
+ */
+ if (!c0_compare_int_usable())
+ return -ENXIO;
+ }
+
+ /*
+ * With vectored interrupts things are getting platform specific.
+ * get_c0_compare_int is a hook to allow a platform to return the
+ * interrupt number of it's liking.
+ */
+ irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+ if (get_c0_compare_int)
+ irq = get_c0_compare_int();
+
+ cd = &per_cpu(mips_clockevent_device, cpu);
+
+ cd->name = "MIPS";
+ cd->features = CLOCK_EVT_FEAT_ONESHOT;
+
+ /* Calculate the min / max delta */
+ cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
+ cd->shift = 32;
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+
+ cd->rating = 300;
+ cd->irq = irq;
+ cd->cpumask = cpumask_of(cpu);
+ cd->set_next_event = mips_next_event;
+ cd->set_mode = mips_set_clock_mode;
+ cd->event_handler = mips_event_handler;
+
+ clockevents_register_device(cd);
+
+ /*
+ * On SMTC we only want to do the data structure
+ * initialization and IRQ setup once.
+ */
+ if (cpu)
+ return 0;
+ /*
+ * And we need the hwmask associated with the c0_compare
+ * vector to be initialized.
+ */
+ irq_hwmask[irq] = (0x100 << cp0_compare_irq);
+ if (cp0_timer_irq_installed)
+ return 0;
+
+ cp0_timer_irq_installed = 1;
+
+ setup_irq(irq, &c0_compare_irqaction);
+
+ return 0;
+}
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c
new file mode 100644
index 00000000..f0ab92a1
--- /dev/null
+++ b/arch/mips/kernel/cevt-txx9.c
@@ -0,0 +1,193 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Based on linux/arch/mips/kernel/cevt-r4k.c,
+ * linux/arch/mips/jmr3927/rbhma3100/setup.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/time.h>
+#include <asm/txx9tmr.h>
+
+#define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL)
+#define TIMER_CCD 0 /* 1/2 */
+#define TIMER_CLK(imclk) ((imclk) / (2 << TIMER_CCD))
+
+struct txx9_clocksource {
+ struct clocksource cs;
+ struct txx9_tmr_reg __iomem *tmrptr;
+};
+
+static cycle_t txx9_cs_read(struct clocksource *cs)
+{
+ struct txx9_clocksource *txx9_cs =
+ container_of(cs, struct txx9_clocksource, cs);
+ return __raw_readl(&txx9_cs->tmrptr->trr);
+}
+
+/* Use 1 bit smaller width to use full bits in that width */
+#define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
+
+static struct txx9_clocksource txx9_clocksource = {
+ .cs = {
+ .name = "TXx9",
+ .rating = 200,
+ .read = txx9_cs_read,
+ .mask = CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ },
+};
+
+void __init txx9_clocksource_init(unsigned long baseaddr,
+ unsigned int imbusclk)
+{
+ struct txx9_tmr_reg __iomem *tmrptr;
+
+ clocksource_register_hz(&txx9_clocksource.cs, TIMER_CLK(imbusclk));
+
+ tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
+ __raw_writel(TCR_BASE, &tmrptr->tcr);
+ __raw_writel(0, &tmrptr->tisr);
+ __raw_writel(TIMER_CCD, &tmrptr->ccdr);
+ __raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
+ __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
+ __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
+ txx9_clocksource.tmrptr = tmrptr;
+}
+
+struct txx9_clock_event_device {
+ struct clock_event_device cd;
+ struct txx9_tmr_reg __iomem *tmrptr;
+};
+
+static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
+{
+ /* stop and reset counter */
+ __raw_writel(TCR_BASE, &tmrptr->tcr);
+ /* clear pending interrupt */
+ __raw_writel(0, &tmrptr->tisr);
+}
+
+static void txx9tmr_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ struct txx9_clock_event_device *txx9_cd =
+ container_of(evt, struct txx9_clock_event_device, cd);
+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
+
+ txx9tmr_stop_and_clear(tmrptr);
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE,
+ &tmrptr->itmr);
+ /* start timer */
+ __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >>
+ evt->shift,
+ &tmrptr->cpra);
+ __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ __raw_writel(0, &tmrptr->itmr);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ __raw_writel(TIMER_CCD, &tmrptr->ccdr);
+ __raw_writel(0, &tmrptr->itmr);
+ break;
+ }
+}
+
+static int txx9tmr_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ struct txx9_clock_event_device *txx9_cd =
+ container_of(evt, struct txx9_clock_event_device, cd);
+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
+
+ txx9tmr_stop_and_clear(tmrptr);
+ /* start timer */
+ __raw_writel(delta, &tmrptr->cpra);
+ __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
+ return 0;
+}
+
+static struct txx9_clock_event_device txx9_clock_event_device = {
+ .cd = {
+ .name = "TXx9",
+ .features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_mode = txx9tmr_set_mode,
+ .set_next_event = txx9tmr_set_next_event,
+ },
+};
+
+static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
+{
+ struct txx9_clock_event_device *txx9_cd = dev_id;
+ struct clock_event_device *cd = &txx9_cd->cd;
+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
+
+ __raw_writel(0, &tmrptr->tisr); /* ack interrupt */
+ cd->event_handler(cd);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction txx9tmr_irq = {
+ .handler = txx9tmr_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "txx9tmr",
+ .dev_id = &txx9_clock_event_device,
+};
+
+void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
+ unsigned int imbusclk)
+{
+ struct clock_event_device *cd = &txx9_clock_event_device.cd;
+ struct txx9_tmr_reg __iomem *tmrptr;
+
+ tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
+ txx9tmr_stop_and_clear(tmrptr);
+ __raw_writel(TIMER_CCD, &tmrptr->ccdr);
+ __raw_writel(0, &tmrptr->itmr);
+ txx9_clock_event_device.tmrptr = tmrptr;
+
+ clockevent_set_clock(cd, TIMER_CLK(imbusclk));
+ cd->max_delta_ns =
+ clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd);
+ cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
+ cd->irq = irq;
+ cd->cpumask = cpumask_of(0),
+ clockevents_register_device(cd);
+ setup_irq(irq, &txx9tmr_irq);
+ printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n",
+ baseaddr, irq);
+}
+
+void __init txx9_tmr_init(unsigned long baseaddr)
+{
+ struct txx9_tmr_reg __iomem *tmrptr;
+
+ tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
+ /* Start once to make CounterResetEnable effective */
+ __raw_writel(TXx9_TMTCR_CRE | TXx9_TMTCR_TCE, &tmrptr->tcr);
+ /* Stop and reset the counter */
+ __raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr);
+ __raw_writel(0, &tmrptr->tisr);
+ __raw_writel(0xffffffff, &tmrptr->cpra);
+ __raw_writel(0, &tmrptr->itmr);
+ __raw_writel(0, &tmrptr->ccdr);
+ __raw_writel(0, &tmrptr->pgmr);
+ iounmap(tmrptr);
+}
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
new file mode 100644
index 00000000..f305ca14
--- /dev/null
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2003, 2004, 2007 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/stddef.h>
+
+#include <asm/bugs.h>
+#include <asm/compiler.h>
+#include <asm/cpu.h>
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static char bug64hit[] __initdata =
+ "reliable operation impossible!\n%s";
+static char nowar[] __initdata =
+ "Please report to <linux-mips@linux-mips.org>.";
+static char r4kwar[] __initdata =
+ "Enable CPU_R4000_WORKAROUNDS to rectify.";
+static char daddiwar[] __initdata =
+ "Enable CPU_DADDI_WORKAROUNDS to rectify.";
+
+static inline void align_mod(const int align, const int mod)
+{
+ asm volatile(
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".balign %0\n\t"
+ ".rept %1\n\t"
+ "nop\n\t"
+ ".endr\n\t"
+ ".set pop"
+ :
+ : GCC_IMM_ASM() (align), GCC_IMM_ASM() (mod));
+}
+
+static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
+ const int align, const int mod)
+{
+ unsigned long flags;
+ int m1, m2;
+ long p, s, lv1, lv2, lw;
+
+ /*
+ * We want the multiply and the shift to be isolated from the
+ * rest of the code to disable gcc optimizations. Hence the
+ * asm statements that execute nothing, but make gcc not know
+ * what the values of m1, m2 and s are and what lv2 and p are
+ * used for.
+ */
+
+ local_irq_save(flags);
+ /*
+ * The following code leads to a wrong result of the first
+ * dsll32 when executed on R4000 rev. 2.2 or 3.0 (PRId
+ * 00000422 or 00000430, respectively).
+ *
+ * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and
+ * 3.0" by MIPS Technologies, Inc., errata #16 and #28 for
+ * details. I got no permission to duplicate them here,
+ * sigh... --macro
+ */
+ asm volatile(
+ ""
+ : "=r" (m1), "=r" (m2), "=r" (s)
+ : "0" (5), "1" (8), "2" (5));
+ align_mod(align, mod);
+ /*
+ * The trailing nop is needed to fulfill the two-instruction
+ * requirement between reading hi/lo and staring a mult/div.
+ * Leaving it out may cause gas insert a nop itself breaking
+ * the desired alignment of the next chunk.
+ */
+ asm volatile(
+ ".set push\n\t"
+ ".set noat\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "mult %2, %3\n\t"
+ "dsll32 %0, %4, %5\n\t"
+ "mflo $0\n\t"
+ "dsll32 %1, %4, %5\n\t"
+ "nop\n\t"
+ ".set pop"
+ : "=&r" (lv1), "=r" (lw)
+ : "r" (m1), "r" (m2), "r" (s), "I" (0)
+ : "hi", "lo", GCC_REG_ACCUM);
+ /* We have to use single integers for m1 and m2 and a double
+ * one for p to be sure the mulsidi3 gcc's RTL multiplication
+ * instruction has the workaround applied. Older versions of
+ * gcc have correct umulsi3 and mulsi3, but other
+ * multiplication variants lack the workaround.
+ */
+ asm volatile(
+ ""
+ : "=r" (m1), "=r" (m2), "=r" (s)
+ : "0" (m1), "1" (m2), "2" (s));
+ align_mod(align, mod);
+ p = m1 * m2;
+ lv2 = s << 32;
+ asm volatile(
+ ""
+ : "=r" (lv2)
+ : "0" (lv2), "r" (p));
+ local_irq_restore(flags);
+
+ *v1 = lv1;
+ *v2 = lv2;
+ *w = lw;
+}
+
+static inline void check_mult_sh(void)
+{
+ long v1[8], v2[8], w[8];
+ int bug, fix, i;
+
+ printk("Checking for the multiply/shift bug... ");
+
+ /*
+ * Testing discovered false negatives for certain code offsets
+ * into cache lines. Hence we test all possible offsets for
+ * the worst assumption of an R4000 I-cache line width of 32
+ * bytes.
+ *
+ * We can't use a loop as alignment directives need to be
+ * immediates.
+ */
+ mult_sh_align_mod(&v1[0], &v2[0], &w[0], 32, 0);
+ mult_sh_align_mod(&v1[1], &v2[1], &w[1], 32, 1);
+ mult_sh_align_mod(&v1[2], &v2[2], &w[2], 32, 2);
+ mult_sh_align_mod(&v1[3], &v2[3], &w[3], 32, 3);
+ mult_sh_align_mod(&v1[4], &v2[4], &w[4], 32, 4);
+ mult_sh_align_mod(&v1[5], &v2[5], &w[5], 32, 5);
+ mult_sh_align_mod(&v1[6], &v2[6], &w[6], 32, 6);
+ mult_sh_align_mod(&v1[7], &v2[7], &w[7], 32, 7);
+
+ bug = 0;
+ for (i = 0; i < 8; i++)
+ if (v1[i] != w[i])
+ bug = 1;
+
+ if (bug == 0) {
+ printk("no.\n");
+ return;
+ }
+
+ printk("yes, workaround... ");
+
+ fix = 1;
+ for (i = 0; i < 8; i++)
+ if (v2[i] != w[i])
+ fix = 0;
+
+ if (fix == 1) {
+ printk("yes.\n");
+ return;
+ }
+
+ printk("no.\n");
+ panic(bug64hit, !R4000_WAR ? r4kwar : nowar);
+}
+
+static volatile int daddi_ov __cpuinitdata;
+
+asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
+{
+ daddi_ov = 1;
+ regs->cp0_epc += 4;
+}
+
+static inline void check_daddi(void)
+{
+ extern asmlinkage void handle_daddi_ov(void);
+ unsigned long flags;
+ void *handler;
+ long v, tmp;
+
+ printk("Checking for the daddi bug... ");
+
+ local_irq_save(flags);
+ handler = set_except_vector(12, handle_daddi_ov);
+ /*
+ * The following code fails to trigger an overflow exception
+ * when executed on R4000 rev. 2.2 or 3.0 (PRId 00000422 or
+ * 00000430, respectively).
+ *
+ * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and
+ * 3.0" by MIPS Technologies, Inc., erratum #23 for details.
+ * I got no permission to duplicate it here, sigh... --macro
+ */
+ asm volatile(
+ ".set push\n\t"
+ ".set noat\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "addiu %1, $0, %2\n\t"
+ "dsrl %1, %1, 1\n\t"
+#ifdef HAVE_AS_SET_DADDI
+ ".set daddi\n\t"
+#endif
+ "daddi %0, %1, %3\n\t"
+ ".set pop"
+ : "=r" (v), "=&r" (tmp)
+ : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
+ set_except_vector(12, handler);
+ local_irq_restore(flags);
+
+ if (daddi_ov) {
+ printk("no.\n");
+ return;
+ }
+
+ printk("yes, workaround... ");
+
+ local_irq_save(flags);
+ handler = set_except_vector(12, handle_daddi_ov);
+ asm volatile(
+ "addiu %1, $0, %2\n\t"
+ "dsrl %1, %1, 1\n\t"
+ "daddi %0, %1, %3"
+ : "=r" (v), "=&r" (tmp)
+ : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
+ set_except_vector(12, handler);
+ local_irq_restore(flags);
+
+ if (daddi_ov) {
+ printk("yes.\n");
+ return;
+ }
+
+ printk("no.\n");
+ panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
+}
+
+int daddiu_bug = -1;
+
+static inline void check_daddiu(void)
+{
+ long v, w, tmp;
+
+ printk("Checking for the daddiu bug... ");
+
+ /*
+ * The following code leads to a wrong result of daddiu when
+ * executed on R4400 rev. 1.0 (PRId 00000440).
+ *
+ * See "MIPS R4400PC/SC Errata, Processor Revision 1.0" by
+ * MIPS Technologies, Inc., erratum #7 for details.
+ *
+ * According to "MIPS R4000PC/SC Errata, Processor Revision
+ * 2.2 and 3.0" by MIPS Technologies, Inc., erratum #41 this
+ * problem affects R4000 rev. 2.2 and 3.0 (PRId 00000422 and
+ * 00000430, respectively), too. Testing failed to trigger it
+ * so far.
+ *
+ * I got no permission to duplicate the errata here, sigh...
+ * --macro
+ */
+ asm volatile(
+ ".set push\n\t"
+ ".set noat\n\t"
+ ".set noreorder\n\t"
+ ".set nomacro\n\t"
+ "addiu %2, $0, %3\n\t"
+ "dsrl %2, %2, 1\n\t"
+#ifdef HAVE_AS_SET_DADDI
+ ".set daddi\n\t"
+#endif
+ "daddiu %0, %2, %4\n\t"
+ "addiu %1, $0, %4\n\t"
+ "daddu %1, %2\n\t"
+ ".set pop"
+ : "=&r" (v), "=&r" (w), "=&r" (tmp)
+ : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
+
+ daddiu_bug = v != w;
+
+ if (!daddiu_bug) {
+ printk("no.\n");
+ return;
+ }
+
+ printk("yes, workaround... ");
+
+ asm volatile(
+ "addiu %2, $0, %3\n\t"
+ "dsrl %2, %2, 1\n\t"
+ "daddiu %0, %2, %4\n\t"
+ "addiu %1, $0, %4\n\t"
+ "daddu %1, %2"
+ : "=&r" (v), "=&r" (w), "=&r" (tmp)
+ : "I" (0xffffffffffffdb9aUL), "I" (0x1234));
+
+ if (v == w) {
+ printk("yes.\n");
+ return;
+ }
+
+ printk("no.\n");
+ panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
+}
+
+void __init check_bugs64_early(void)
+{
+ check_mult_sh();
+ check_daddiu();
+}
+
+void __init check_bugs64(void)
+{
+ check_daddi();
+}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
new file mode 100644
index 00000000..bb133d10
--- /dev/null
+++ b/arch/mips/kernel/cpu-probe.c
@@ -0,0 +1,1164 @@
+/*
+ * Processor capabilities determination functions.
+ *
+ * Copyright (C) xxxx the Anonymous
+ * Copyright (C) 1994 - 2006 Ralf Baechle
+ * Copyright (C) 2003, 2004 Maciej W. Rozycki
+ * Copyright (C) 2001, 2004 MIPS Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/smp.h>
+#include <linux/stddef.h>
+#include <linux/module.h>
+
+#include <asm/bugs.h>
+#include <asm/cpu.h>
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/watch.h>
+#include <asm/spram.h>
+#include <asm/uaccess.h>
+
+/*
+ * Not all of the MIPS CPUs have the "wait" instruction available. Moreover,
+ * the implementation of the "wait" feature differs between CPU families. This
+ * points to the function that implements CPU specific wait.
+ * The wait instruction stops the pipeline and reduces the power consumption of
+ * the CPU very much.
+ */
+void (*cpu_wait)(void);
+EXPORT_SYMBOL(cpu_wait);
+
+static void r3081_wait(void)
+{
+ unsigned long cfg = read_c0_conf();
+ write_c0_conf(cfg | R30XX_CONF_HALT);
+}
+
+static void r39xx_wait(void)
+{
+ local_irq_disable();
+ if (!need_resched())
+ write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
+ local_irq_enable();
+}
+
+extern void r4k_wait(void);
+
+/*
+ * This variant is preferable as it allows testing need_resched and going to
+ * sleep depending on the outcome atomically. Unfortunately the "It is
+ * implementation-dependent whether the pipeline restarts when a non-enabled
+ * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
+ * using this version a gamble.
+ */
+void r4k_wait_irqoff(void)
+{
+ local_irq_disable();
+ if (!need_resched())
+ __asm__(" .set push \n"
+ " .set mips3 \n"
+ " wait \n"
+ " .set pop \n");
+ local_irq_enable();
+ __asm__(" .globl __pastwait \n"
+ "__pastwait: \n");
+ return;
+}
+
+/*
+ * The RM7000 variant has to handle erratum 38. The workaround is to not
+ * have any pending stores when the WAIT instruction is executed.
+ */
+static void rm7k_wait_irqoff(void)
+{
+ local_irq_disable();
+ if (!need_resched())
+ __asm__(
+ " .set push \n"
+ " .set mips3 \n"
+ " .set noat \n"
+ " mfc0 $1, $12 \n"
+ " sync \n"
+ " mtc0 $1, $12 # stalls until W stage \n"
+ " wait \n"
+ " mtc0 $1, $12 # stalls until W stage \n"
+ " .set pop \n");
+ local_irq_enable();
+}
+
+/*
+ * The Au1xxx wait is available only if using 32khz counter or
+ * external timer source, but specifically not CP0 Counter.
+ * alchemy/common/time.c may override cpu_wait!
+ */
+static void au1k_wait(void)
+{
+ __asm__(" .set mips3 \n"
+ " cache 0x14, 0(%0) \n"
+ " cache 0x14, 32(%0) \n"
+ " sync \n"
+ " nop \n"
+ " wait \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " nop \n"
+ " .set mips0 \n"
+ : : "r" (au1k_wait));
+}
+
+static int __initdata nowait;
+
+static int __init wait_disable(char *s)
+{
+ nowait = 1;
+
+ return 1;
+}
+
+__setup("nowait", wait_disable);
+
+static int __cpuinitdata mips_fpu_disabled;
+
+static int __init fpu_disable(char *s)
+{
+ cpu_data[0].options &= ~MIPS_CPU_FPU;
+ mips_fpu_disabled = 1;
+
+ return 1;
+}
+
+__setup("nofpu", fpu_disable);
+
+int __cpuinitdata mips_dsp_disabled;
+
+static int __init dsp_disable(char *s)
+{
+ cpu_data[0].ases &= ~MIPS_ASE_DSP;
+ mips_dsp_disabled = 1;
+
+ return 1;
+}
+
+__setup("nodsp", dsp_disable);
+
+void __init check_wait(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ if (nowait) {
+ printk("Wait instruction disabled.\n");
+ return;
+ }
+
+ switch (c->cputype) {
+ case CPU_R3081:
+ case CPU_R3081E:
+ cpu_wait = r3081_wait;
+ break;
+ case CPU_TX3927:
+ cpu_wait = r39xx_wait;
+ break;
+ case CPU_R4200:
+/* case CPU_R4300: */
+ case CPU_R4600:
+ case CPU_R4640:
+ case CPU_R4650:
+ case CPU_R4700:
+ case CPU_R5000:
+ case CPU_R5500:
+ case CPU_NEVADA:
+ case CPU_4KC:
+ case CPU_4KEC:
+ case CPU_4KSC:
+ case CPU_5KC:
+ case CPU_25KF:
+ case CPU_PR4450:
+ case CPU_BMIPS3300:
+ case CPU_BMIPS4350:
+ case CPU_BMIPS4380:
+ case CPU_BMIPS5000:
+ case CPU_CAVIUM_OCTEON:
+ case CPU_CAVIUM_OCTEON_PLUS:
+ case CPU_CAVIUM_OCTEON2:
+ case CPU_JZRISC:
+ cpu_wait = r4k_wait;
+ break;
+
+ case CPU_RM7000:
+ cpu_wait = rm7k_wait_irqoff;
+ break;
+
+ case CPU_24K:
+ case CPU_34K:
+ case CPU_1004K:
+ cpu_wait = r4k_wait;
+ if (read_c0_config7() & MIPS_CONF7_WII)
+ cpu_wait = r4k_wait_irqoff;
+ break;
+
+ case CPU_74K:
+ cpu_wait = r4k_wait;
+ if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0))
+ cpu_wait = r4k_wait_irqoff;
+ break;
+
+ case CPU_TX49XX:
+ cpu_wait = r4k_wait_irqoff;
+ break;
+ case CPU_ALCHEMY:
+ cpu_wait = au1k_wait;
+ break;
+ case CPU_20KC:
+ /*
+ * WAIT on Rev1.0 has E1, E2, E3 and E16.
+ * WAIT on Rev2.0 and Rev3.0 has E16.
+ * Rev3.1 WAIT is nop, why bother
+ */
+ if ((c->processor_id & 0xff) <= 0x64)
+ break;
+
+ /*
+ * Another rev is incremeting c0_count at a reduced clock
+ * rate while in WAIT mode. So we basically have the choice
+ * between using the cp0 timer as clocksource or avoiding
+ * the WAIT instruction. Until more details are known,
+ * disable the use of WAIT for 20Kc entirely.
+ cpu_wait = r4k_wait;
+ */
+ break;
+ case CPU_RM9000:
+ if ((c->processor_id & 0x00ff) >= 0x40)
+ cpu_wait = r4k_wait;
+ break;
+ default:
+ break;
+ }
+}
+
+static inline void check_errata(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ switch (c->cputype) {
+ case CPU_34K:
+ /*
+ * Erratum "RPS May Cause Incorrect Instruction Execution"
+ * This code only handles VPE0, any SMP/SMTC/RTOS code
+ * making use of VPE1 will be responsable for that VPE.
+ */
+ if ((c->processor_id & PRID_REV_MASK) <= PRID_REV_34K_V1_0_2)
+ write_c0_config7(read_c0_config7() | MIPS_CONF7_RPS);
+ break;
+ default:
+ break;
+ }
+}
+
+void __init check_bugs32(void)
+{
+ check_errata();
+}
+
+/*
+ * Probe whether cpu has config register by trying to play with
+ * alternate cache bit and see whether it matters.
+ * It's used by cpu_probe to distinguish between R3000A and R3081.
+ */
+static inline int cpu_has_confreg(void)
+{
+#ifdef CONFIG_CPU_R3000
+ extern unsigned long r3k_cache_size(unsigned long);
+ unsigned long size1, size2;
+ unsigned long cfg = read_c0_conf();
+
+ size1 = r3k_cache_size(ST0_ISC);
+ write_c0_conf(cfg ^ R30XX_CONF_AC);
+ size2 = r3k_cache_size(ST0_ISC);
+ write_c0_conf(cfg);
+ return size1 != size2;
+#else
+ return 0;
+#endif
+}
+
+static inline void set_elf_platform(int cpu, const char *plat)
+{
+ if (cpu == 0)
+ __elf_platform = plat;
+}
+
+/*
+ * Get the FPU Implementation/Revision.
+ */
+static inline unsigned long cpu_get_fpu_id(void)
+{
+ unsigned long tmp, fpu_id;
+
+ tmp = read_c0_status();
+ __enable_fpu();
+ fpu_id = read_32bit_cp1_register(CP1_REVISION);
+ write_c0_status(tmp);
+ return fpu_id;
+}
+
+/*
+ * Check the CPU has an FPU the official way.
+ */
+static inline int __cpu_has_fpu(void)
+{
+ return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE);
+}
+
+static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
+{
+#ifdef __NEED_VMBITS_PROBE
+ write_c0_entryhi(0x3fffffffffffe000ULL);
+ back_to_back_c0_hazard();
+ c->vmbits = fls64(read_c0_entryhi() & 0x3fffffffffffe000ULL);
+#endif
+}
+
+#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
+ | MIPS_CPU_COUNTER)
+
+static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_R2000:
+ c->cputype = CPU_R2000;
+ __cpu_name[cpu] = "R2000";
+ c->isa_level = MIPS_CPU_ISA_I;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
+ MIPS_CPU_NOFPUEX;
+ if (__cpu_has_fpu())
+ c->options |= MIPS_CPU_FPU;
+ c->tlbsize = 64;
+ break;
+ case PRID_IMP_R3000:
+ if ((c->processor_id & 0xff) == PRID_REV_R3000A) {
+ if (cpu_has_confreg()) {
+ c->cputype = CPU_R3081E;
+ __cpu_name[cpu] = "R3081";
+ } else {
+ c->cputype = CPU_R3000A;
+ __cpu_name[cpu] = "R3000A";
+ }
+ break;
+ } else {
+ c->cputype = CPU_R3000;
+ __cpu_name[cpu] = "R3000";
+ }
+ c->isa_level = MIPS_CPU_ISA_I;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
+ MIPS_CPU_NOFPUEX;
+ if (__cpu_has_fpu())
+ c->options |= MIPS_CPU_FPU;
+ c->tlbsize = 64;
+ break;
+ case PRID_IMP_R4000:
+ if (read_c0_config() & CONF_SC) {
+ if ((c->processor_id & 0xff) >= PRID_REV_R4400) {
+ c->cputype = CPU_R4400PC;
+ __cpu_name[cpu] = "R4400PC";
+ } else {
+ c->cputype = CPU_R4000PC;
+ __cpu_name[cpu] = "R4000PC";
+ }
+ } else {
+ if ((c->processor_id & 0xff) >= PRID_REV_R4400) {
+ c->cputype = CPU_R4400SC;
+ __cpu_name[cpu] = "R4400SC";
+ } else {
+ c->cputype = CPU_R4000SC;
+ __cpu_name[cpu] = "R4000SC";
+ }
+ }
+
+ c->isa_level = MIPS_CPU_ISA_III;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_WATCH | MIPS_CPU_VCE |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 48;
+ break;
+ case PRID_IMP_VR41XX:
+ switch (c->processor_id & 0xf0) {
+ case PRID_REV_VR4111:
+ c->cputype = CPU_VR4111;
+ __cpu_name[cpu] = "NEC VR4111";
+ break;
+ case PRID_REV_VR4121:
+ c->cputype = CPU_VR4121;
+ __cpu_name[cpu] = "NEC VR4121";
+ break;
+ case PRID_REV_VR4122:
+ if ((c->processor_id & 0xf) < 0x3) {
+ c->cputype = CPU_VR4122;
+ __cpu_name[cpu] = "NEC VR4122";
+ } else {
+ c->cputype = CPU_VR4181A;
+ __cpu_name[cpu] = "NEC VR4181A";
+ }
+ break;
+ case PRID_REV_VR4130:
+ if ((c->processor_id & 0xf) < 0x4) {
+ c->cputype = CPU_VR4131;
+ __cpu_name[cpu] = "NEC VR4131";
+ } else {
+ c->cputype = CPU_VR4133;
+ __cpu_name[cpu] = "NEC VR4133";
+ }
+ break;
+ default:
+ printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+ c->cputype = CPU_VR41XX;
+ __cpu_name[cpu] = "NEC Vr41xx";
+ break;
+ }
+ c->isa_level = MIPS_CPU_ISA_III;
+ c->options = R4K_OPTS;
+ c->tlbsize = 32;
+ break;
+ case PRID_IMP_R4300:
+ c->cputype = CPU_R4300;
+ __cpu_name[cpu] = "R4300";
+ c->isa_level = MIPS_CPU_ISA_III;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 32;
+ break;
+ case PRID_IMP_R4600:
+ c->cputype = CPU_R4600;
+ __cpu_name[cpu] = "R4600";
+ c->isa_level = MIPS_CPU_ISA_III;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 48;
+ break;
+ #if 0
+ case PRID_IMP_R4650:
+ /*
+ * This processor doesn't have an MMU, so it's not
+ * "real easy" to run Linux on it. It is left purely
+ * for documentation. Commented out because it shares
+ * it's c0_prid id number with the TX3900.
+ */
+ c->cputype = CPU_R4650;
+ __cpu_name[cpu] = "R4650";
+ c->isa_level = MIPS_CPU_ISA_III;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
+ c->tlbsize = 48;
+ break;
+ #endif
+ case PRID_IMP_TX39:
+ c->isa_level = MIPS_CPU_ISA_I;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
+
+ if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
+ c->cputype = CPU_TX3927;
+ __cpu_name[cpu] = "TX3927";
+ c->tlbsize = 64;
+ } else {
+ switch (c->processor_id & 0xff) {
+ case PRID_REV_TX3912:
+ c->cputype = CPU_TX3912;
+ __cpu_name[cpu] = "TX3912";
+ c->tlbsize = 32;
+ break;
+ case PRID_REV_TX3922:
+ c->cputype = CPU_TX3922;
+ __cpu_name[cpu] = "TX3922";
+ c->tlbsize = 64;
+ break;
+ }
+ }
+ break;
+ case PRID_IMP_R4700:
+ c->cputype = CPU_R4700;
+ __cpu_name[cpu] = "R4700";
+ c->isa_level = MIPS_CPU_ISA_III;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 48;
+ break;
+ case PRID_IMP_TX49:
+ c->cputype = CPU_TX49XX;
+ __cpu_name[cpu] = "R49XX";
+ c->isa_level = MIPS_CPU_ISA_III;
+ c->options = R4K_OPTS | MIPS_CPU_LLSC;
+ if (!(c->processor_id & 0x08))
+ c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
+ c->tlbsize = 48;
+ break;
+ case PRID_IMP_R5000:
+ c->cputype = CPU_R5000;
+ __cpu_name[cpu] = "R5000";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 48;
+ break;
+ case PRID_IMP_R5432:
+ c->cputype = CPU_R5432;
+ __cpu_name[cpu] = "R5432";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_WATCH | MIPS_CPU_LLSC;
+ c->tlbsize = 48;
+ break;
+ case PRID_IMP_R5500:
+ c->cputype = CPU_R5500;
+ __cpu_name[cpu] = "R5500";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_WATCH | MIPS_CPU_LLSC;
+ c->tlbsize = 48;
+ break;
+ case PRID_IMP_NEVADA:
+ c->cputype = CPU_NEVADA;
+ __cpu_name[cpu] = "Nevada";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
+ c->tlbsize = 48;
+ break;
+ case PRID_IMP_R6000:
+ c->cputype = CPU_R6000;
+ __cpu_name[cpu] = "R6000";
+ c->isa_level = MIPS_CPU_ISA_II;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 32;
+ break;
+ case PRID_IMP_R6000A:
+ c->cputype = CPU_R6000A;
+ __cpu_name[cpu] = "R6000A";
+ c->isa_level = MIPS_CPU_ISA_II;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 32;
+ break;
+ case PRID_IMP_RM7000:
+ c->cputype = CPU_RM7000;
+ __cpu_name[cpu] = "RM7000";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
+ /*
+ * Undocumented RM7000: Bit 29 in the info register of
+ * the RM7000 v2.0 indicates if the TLB has 48 or 64
+ * entries.
+ *
+ * 29 1 => 64 entry JTLB
+ * 0 => 48 entry JTLB
+ */
+ c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
+ break;
+ case PRID_IMP_RM9000:
+ c->cputype = CPU_RM9000;
+ __cpu_name[cpu] = "RM9000";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
+ /*
+ * Bit 29 in the info register of the RM9000
+ * indicates if the TLB has 48 or 64 entries.
+ *
+ * 29 1 => 64 entry JTLB
+ * 0 => 48 entry JTLB
+ */
+ c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
+ break;
+ case PRID_IMP_R8000:
+ c->cputype = CPU_R8000;
+ __cpu_name[cpu] = "RM8000";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+ MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 384; /* has weird TLB: 3-way x 128 */
+ break;
+ case PRID_IMP_R10000:
+ c->cputype = CPU_R10000;
+ __cpu_name[cpu] = "R10000";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
+ MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 64;
+ break;
+ case PRID_IMP_R12000:
+ c->cputype = CPU_R12000;
+ __cpu_name[cpu] = "R12000";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
+ MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 64;
+ break;
+ case PRID_IMP_R14000:
+ c->cputype = CPU_R14000;
+ __cpu_name[cpu] = "R14000";
+ c->isa_level = MIPS_CPU_ISA_IV;
+ c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
+ MIPS_CPU_FPU | MIPS_CPU_32FPR |
+ MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
+ MIPS_CPU_LLSC;
+ c->tlbsize = 64;
+ break;
+ case PRID_IMP_LOONGSON2:
+ c->cputype = CPU_LOONGSON2;
+ __cpu_name[cpu] = "ICT Loongson-2";
+
+ switch (c->processor_id & PRID_REV_MASK) {
+ case PRID_REV_LOONGSON2E:
+ set_elf_platform(cpu, "loongson2e");
+ break;
+ case PRID_REV_LOONGSON2F:
+ set_elf_platform(cpu, "loongson2f");
+ break;
+ }
+
+ c->isa_level = MIPS_CPU_ISA_III;
+ c->options = R4K_OPTS |
+ MIPS_CPU_FPU | MIPS_CPU_LLSC |
+ MIPS_CPU_32FPR;
+ c->tlbsize = 64;
+ break;
+ }
+}
+
+static char unknown_isa[] __cpuinitdata = KERN_ERR \
+ "Unsupported ISA type, c0.config0: %d.";
+
+static inline unsigned int decode_config0(struct cpuinfo_mips *c)
+{
+ unsigned int config0;
+ int isa;
+
+ config0 = read_c0_config();
+
+ if (((config0 & MIPS_CONF_MT) >> 7) == 1)
+ c->options |= MIPS_CPU_TLB;
+ isa = (config0 & MIPS_CONF_AT) >> 13;
+ switch (isa) {
+ case 0:
+ switch ((config0 & MIPS_CONF_AR) >> 10) {
+ case 0:
+ c->isa_level = MIPS_CPU_ISA_M32R1;
+ break;
+ case 1:
+ c->isa_level = MIPS_CPU_ISA_M32R2;
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ case 2:
+ switch ((config0 & MIPS_CONF_AR) >> 10) {
+ case 0:
+ c->isa_level = MIPS_CPU_ISA_M64R1;
+ break;
+ case 1:
+ c->isa_level = MIPS_CPU_ISA_M64R2;
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ default:
+ goto unknown;
+ }
+
+ return config0 & MIPS_CONF_M;
+
+unknown:
+ panic(unknown_isa, config0);
+}
+
+static inline unsigned int decode_config1(struct cpuinfo_mips *c)
+{
+ unsigned int config1;
+
+ config1 = read_c0_config1();
+
+ if (config1 & MIPS_CONF1_MD)
+ c->ases |= MIPS_ASE_MDMX;
+ if (config1 & MIPS_CONF1_WR)
+ c->options |= MIPS_CPU_WATCH;
+ if (config1 & MIPS_CONF1_CA)
+ c->ases |= MIPS_ASE_MIPS16;
+ if (config1 & MIPS_CONF1_EP)
+ c->options |= MIPS_CPU_EJTAG;
+ if (config1 & MIPS_CONF1_FP) {
+ c->options |= MIPS_CPU_FPU;
+ c->options |= MIPS_CPU_32FPR;
+ }
+ if (cpu_has_tlb)
+ c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
+
+ return config1 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config2(struct cpuinfo_mips *c)
+{
+ unsigned int config2;
+
+ config2 = read_c0_config2();
+
+ if (config2 & MIPS_CONF2_SL)
+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+
+ return config2 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config3(struct cpuinfo_mips *c)
+{
+ unsigned int config3;
+
+ config3 = read_c0_config3();
+
+ if (config3 & MIPS_CONF3_SM)
+ c->ases |= MIPS_ASE_SMARTMIPS;
+ if (config3 & MIPS_CONF3_DSP)
+ c->ases |= MIPS_ASE_DSP;
+ if (config3 & MIPS_CONF3_VINT)
+ c->options |= MIPS_CPU_VINT;
+ if (config3 & MIPS_CONF3_VEIC)
+ c->options |= MIPS_CPU_VEIC;
+ if (config3 & MIPS_CONF3_MT)
+ c->ases |= MIPS_ASE_MIPSMT;
+ if (config3 & MIPS_CONF3_ULRI)
+ c->options |= MIPS_CPU_ULRI;
+
+ return config3 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config4(struct cpuinfo_mips *c)
+{
+ unsigned int config4;
+
+ config4 = read_c0_config4();
+
+ if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT
+ && cpu_has_tlb)
+ c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+
+ c->kscratch_mask = (config4 >> 16) & 0xff;
+
+ return config4 & MIPS_CONF_M;
+}
+
+static void __cpuinit decode_configs(struct cpuinfo_mips *c)
+{
+ int ok;
+
+ /* MIPS32 or MIPS64 compliant CPU. */
+ c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
+ MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
+
+ c->scache.flags = MIPS_CACHE_NOT_PRESENT;
+
+ ok = decode_config0(c); /* Read Config registers. */
+ BUG_ON(!ok); /* Arch spec violation! */
+ if (ok)
+ ok = decode_config1(c);
+ if (ok)
+ ok = decode_config2(c);
+ if (ok)
+ ok = decode_config3(c);
+ if (ok)
+ ok = decode_config4(c);
+
+ mips_probe_watch_registers(c);
+
+ if (cpu_has_mips_r2)
+ c->core = read_c0_ebase() & 0x3ff;
+}
+
+static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_4KC:
+ c->cputype = CPU_4KC;
+ __cpu_name[cpu] = "MIPS 4Kc";
+ break;
+ case PRID_IMP_4KEC:
+ case PRID_IMP_4KECR2:
+ c->cputype = CPU_4KEC;
+ __cpu_name[cpu] = "MIPS 4KEc";
+ break;
+ case PRID_IMP_4KSC:
+ case PRID_IMP_4KSD:
+ c->cputype = CPU_4KSC;
+ __cpu_name[cpu] = "MIPS 4KSc";
+ break;
+ case PRID_IMP_5KC:
+ c->cputype = CPU_5KC;
+ __cpu_name[cpu] = "MIPS 5Kc";
+ break;
+ case PRID_IMP_20KC:
+ c->cputype = CPU_20KC;
+ __cpu_name[cpu] = "MIPS 20Kc";
+ break;
+ case PRID_IMP_24K:
+ case PRID_IMP_24KE:
+ c->cputype = CPU_24K;
+ __cpu_name[cpu] = "MIPS 24Kc";
+ break;
+ case PRID_IMP_25KF:
+ c->cputype = CPU_25KF;
+ __cpu_name[cpu] = "MIPS 25Kc";
+ break;
+ case PRID_IMP_34K:
+ c->cputype = CPU_34K;
+ __cpu_name[cpu] = "MIPS 34Kc";
+ break;
+ case PRID_IMP_74K:
+ c->cputype = CPU_74K;
+ __cpu_name[cpu] = "MIPS 74Kc";
+ break;
+ case PRID_IMP_1004K:
+ c->cputype = CPU_1004K;
+ __cpu_name[cpu] = "MIPS 1004Kc";
+ break;
+ }
+
+ spram_config();
+}
+
+static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_AU1_REV1:
+ case PRID_IMP_AU1_REV2:
+ c->cputype = CPU_ALCHEMY;
+ switch ((c->processor_id >> 24) & 0xff) {
+ case 0:
+ __cpu_name[cpu] = "Au1000";
+ break;
+ case 1:
+ __cpu_name[cpu] = "Au1500";
+ break;
+ case 2:
+ __cpu_name[cpu] = "Au1100";
+ break;
+ case 3:
+ __cpu_name[cpu] = "Au1550";
+ break;
+ case 4:
+ __cpu_name[cpu] = "Au1200";
+ if ((c->processor_id & 0xff) == 2)
+ __cpu_name[cpu] = "Au1250";
+ break;
+ case 5:
+ __cpu_name[cpu] = "Au1210";
+ break;
+ default:
+ __cpu_name[cpu] = "Au1xxx";
+ break;
+ }
+ break;
+ }
+}
+
+static inline void cpu_probe_sibyte(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_SB1:
+ c->cputype = CPU_SB1;
+ __cpu_name[cpu] = "SiByte SB1";
+ /* FPU in pass1 is known to have issues. */
+ if ((c->processor_id & 0xff) < 0x02)
+ c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR);
+ break;
+ case PRID_IMP_SB1A:
+ c->cputype = CPU_SB1A;
+ __cpu_name[cpu] = "SiByte SB1A";
+ break;
+ }
+}
+
+static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_SR71000:
+ c->cputype = CPU_SR71000;
+ __cpu_name[cpu] = "Sandcraft SR71000";
+ c->scache.ways = 8;
+ c->tlbsize = 64;
+ break;
+ }
+}
+
+static inline void cpu_probe_nxp(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_PR4450:
+ c->cputype = CPU_PR4450;
+ __cpu_name[cpu] = "Philips PR4450";
+ c->isa_level = MIPS_CPU_ISA_M32R1;
+ break;
+ }
+}
+
+static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_BMIPS32_REV4:
+ case PRID_IMP_BMIPS32_REV8:
+ c->cputype = CPU_BMIPS32;
+ __cpu_name[cpu] = "Broadcom BMIPS32";
+ set_elf_platform(cpu, "bmips32");
+ break;
+ case PRID_IMP_BMIPS3300:
+ case PRID_IMP_BMIPS3300_ALT:
+ case PRID_IMP_BMIPS3300_BUG:
+ c->cputype = CPU_BMIPS3300;
+ __cpu_name[cpu] = "Broadcom BMIPS3300";
+ set_elf_platform(cpu, "bmips3300");
+ break;
+ case PRID_IMP_BMIPS43XX: {
+ int rev = c->processor_id & 0xff;
+
+ if (rev >= PRID_REV_BMIPS4380_LO &&
+ rev <= PRID_REV_BMIPS4380_HI) {
+ c->cputype = CPU_BMIPS4380;
+ __cpu_name[cpu] = "Broadcom BMIPS4380";
+ set_elf_platform(cpu, "bmips4380");
+ } else {
+ c->cputype = CPU_BMIPS4350;
+ __cpu_name[cpu] = "Broadcom BMIPS4350";
+ set_elf_platform(cpu, "bmips4350");
+ }
+ break;
+ }
+ case PRID_IMP_BMIPS5000:
+ c->cputype = CPU_BMIPS5000;
+ __cpu_name[cpu] = "Broadcom BMIPS5000";
+ set_elf_platform(cpu, "bmips5000");
+ c->options |= MIPS_CPU_ULRI;
+ break;
+ }
+}
+
+static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_CAVIUM_CN38XX:
+ case PRID_IMP_CAVIUM_CN31XX:
+ case PRID_IMP_CAVIUM_CN30XX:
+ c->cputype = CPU_CAVIUM_OCTEON;
+ __cpu_name[cpu] = "Cavium Octeon";
+ goto platform;
+ case PRID_IMP_CAVIUM_CN58XX:
+ case PRID_IMP_CAVIUM_CN56XX:
+ case PRID_IMP_CAVIUM_CN50XX:
+ case PRID_IMP_CAVIUM_CN52XX:
+ c->cputype = CPU_CAVIUM_OCTEON_PLUS;
+ __cpu_name[cpu] = "Cavium Octeon+";
+platform:
+ set_elf_platform(cpu, "octeon");
+ break;
+ case PRID_IMP_CAVIUM_CN63XX:
+ c->cputype = CPU_CAVIUM_OCTEON2;
+ __cpu_name[cpu] = "Cavium Octeon II";
+ set_elf_platform(cpu, "octeon2");
+ break;
+ default:
+ printk(KERN_INFO "Unknown Octeon chip!\n");
+ c->cputype = CPU_UNKNOWN;
+ break;
+ }
+}
+
+static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ /* JZRISC does not implement the CP0 counter. */
+ c->options &= ~MIPS_CPU_COUNTER;
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_JZRISC:
+ c->cputype = CPU_JZRISC;
+ __cpu_name[cpu] = "Ingenic JZRISC";
+ break;
+ default:
+ panic("Unknown Ingenic Processor ID!");
+ break;
+ }
+}
+
+static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
+{
+ decode_configs(c);
+
+ c->options = (MIPS_CPU_TLB |
+ MIPS_CPU_4KEX |
+ MIPS_CPU_COUNTER |
+ MIPS_CPU_DIVEC |
+ MIPS_CPU_WATCH |
+ MIPS_CPU_EJTAG |
+ MIPS_CPU_LLSC);
+
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_NETLOGIC_XLR732:
+ case PRID_IMP_NETLOGIC_XLR716:
+ case PRID_IMP_NETLOGIC_XLR532:
+ case PRID_IMP_NETLOGIC_XLR308:
+ case PRID_IMP_NETLOGIC_XLR532C:
+ case PRID_IMP_NETLOGIC_XLR516C:
+ case PRID_IMP_NETLOGIC_XLR508C:
+ case PRID_IMP_NETLOGIC_XLR308C:
+ c->cputype = CPU_XLR;
+ __cpu_name[cpu] = "Netlogic XLR";
+ break;
+
+ case PRID_IMP_NETLOGIC_XLS608:
+ case PRID_IMP_NETLOGIC_XLS408:
+ case PRID_IMP_NETLOGIC_XLS404:
+ case PRID_IMP_NETLOGIC_XLS208:
+ case PRID_IMP_NETLOGIC_XLS204:
+ case PRID_IMP_NETLOGIC_XLS108:
+ case PRID_IMP_NETLOGIC_XLS104:
+ case PRID_IMP_NETLOGIC_XLS616B:
+ case PRID_IMP_NETLOGIC_XLS608B:
+ case PRID_IMP_NETLOGIC_XLS416B:
+ case PRID_IMP_NETLOGIC_XLS412B:
+ case PRID_IMP_NETLOGIC_XLS408B:
+ case PRID_IMP_NETLOGIC_XLS404B:
+ c->cputype = CPU_XLR;
+ __cpu_name[cpu] = "Netlogic XLS";
+ break;
+
+ default:
+ printk(KERN_INFO "Unknown Netlogic chip id [%02x]!\n",
+ c->processor_id);
+ c->cputype = CPU_XLR;
+ break;
+ }
+
+ c->isa_level = MIPS_CPU_ISA_M64R1;
+ c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
+}
+
+#ifdef CONFIG_64BIT
+/* For use by uaccess.h */
+u64 __ua_limit;
+EXPORT_SYMBOL(__ua_limit);
+#endif
+
+const char *__cpu_name[NR_CPUS];
+const char *__elf_platform;
+
+__cpuinit void cpu_probe(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int cpu = smp_processor_id();
+
+ c->processor_id = PRID_IMP_UNKNOWN;
+ c->fpu_id = FPIR_IMP_NONE;
+ c->cputype = CPU_UNKNOWN;
+
+ c->processor_id = read_c0_prid();
+ switch (c->processor_id & 0xff0000) {
+ case PRID_COMP_LEGACY:
+ cpu_probe_legacy(c, cpu);
+ break;
+ case PRID_COMP_MIPS:
+ cpu_probe_mips(c, cpu);
+ break;
+ case PRID_COMP_ALCHEMY:
+ cpu_probe_alchemy(c, cpu);
+ break;
+ case PRID_COMP_SIBYTE:
+ cpu_probe_sibyte(c, cpu);
+ break;
+ case PRID_COMP_BROADCOM:
+ cpu_probe_broadcom(c, cpu);
+ break;
+ case PRID_COMP_SANDCRAFT:
+ cpu_probe_sandcraft(c, cpu);
+ break;
+ case PRID_COMP_NXP:
+ cpu_probe_nxp(c, cpu);
+ break;
+ case PRID_COMP_CAVIUM:
+ cpu_probe_cavium(c, cpu);
+ break;
+ case PRID_COMP_INGENIC:
+ cpu_probe_ingenic(c, cpu);
+ break;
+ case PRID_COMP_NETLOGIC:
+ cpu_probe_netlogic(c, cpu);
+ break;
+ }
+
+ BUG_ON(!__cpu_name[cpu]);
+ BUG_ON(c->cputype == CPU_UNKNOWN);
+
+ /*
+ * Platform code can force the cpu type to optimize code
+ * generation. In that case be sure the cpu type is correctly
+ * manually setup otherwise it could trigger some nasty bugs.
+ */
+ BUG_ON(current_cpu_type() != c->cputype);
+
+ if (mips_fpu_disabled)
+ c->options &= ~MIPS_CPU_FPU;
+
+ if (mips_dsp_disabled)
+ c->ases &= ~MIPS_ASE_DSP;
+
+ if (c->options & MIPS_CPU_FPU) {
+ c->fpu_id = cpu_get_fpu_id();
+
+ if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
+ c->isa_level == MIPS_CPU_ISA_M32R2 ||
+ c->isa_level == MIPS_CPU_ISA_M64R1 ||
+ c->isa_level == MIPS_CPU_ISA_M64R2) {
+ if (c->fpu_id & MIPS_FPIR_3D)
+ c->ases |= MIPS_ASE_MIPS3D;
+ }
+ }
+
+ if (cpu_has_mips_r2)
+ c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
+ else
+ c->srsets = 1;
+
+ cpu_probe_vmbits(c);
+
+#ifdef CONFIG_64BIT
+ if (cpu == 0)
+ __ua_limit = ~((1ull << cpu_vmbits) - 1);
+#endif
+}
+
+__cpuinit void cpu_report(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ printk(KERN_INFO "CPU revision is: %08x (%s)\n",
+ c->processor_id, cpu_name_string());
+ if (c->options & MIPS_CPU_FPU)
+ printk(KERN_INFO "FPU revision is: %08x\n", c->fpu_id);
+}
diff --git a/arch/mips/kernel/cpufreq/Kconfig b/arch/mips/kernel/cpufreq/Kconfig
new file mode 100644
index 00000000..58c601ee
--- /dev/null
+++ b/arch/mips/kernel/cpufreq/Kconfig
@@ -0,0 +1,41 @@
+#
+# CPU Frequency scaling
+#
+
+config MIPS_EXTERNAL_TIMER
+ bool
+
+config MIPS_CPUFREQ
+ bool
+ default y
+ depends on CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
+
+if MIPS_CPUFREQ
+
+menu "CPU Frequency scaling"
+
+source "drivers/cpufreq/Kconfig"
+
+if CPU_FREQ
+
+comment "CPUFreq processor drivers"
+
+config LOONGSON2_CPUFREQ
+ tristate "Loongson2 CPUFreq Driver"
+ select CPU_FREQ_TABLE
+ depends on MIPS_CPUFREQ
+ help
+ This option adds a CPUFreq driver for loongson processors which
+ support software configurable cpu frequency.
+
+ Loongson2F and it's successors support this feature.
+
+ For details, take a look at <file:Documentation/cpu-freq/>.
+
+ If in doubt, say N.
+
+endif # CPU_FREQ
+
+endmenu
+
+endif # MIPS_CPUFREQ
diff --git a/arch/mips/kernel/cpufreq/Makefile b/arch/mips/kernel/cpufreq/Makefile
new file mode 100644
index 00000000..c3479a43
--- /dev/null
+++ b/arch/mips/kernel/cpufreq/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the Linux/MIPS cpufreq.
+#
+
+obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o loongson2_clock.o
diff --git a/arch/mips/kernel/cpufreq/loongson2_clock.c b/arch/mips/kernel/cpufreq/loongson2_clock.c
new file mode 100644
index 00000000..cefc6e25
--- /dev/null
+++ b/arch/mips/kernel/cpufreq/loongson2_clock.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology
+ * Author: Yanhua, yanh@lemote.com
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
+
+#include <asm/clock.h>
+
+#include <loongson.h>
+
+static LIST_HEAD(clock_list);
+static DEFINE_SPINLOCK(clock_lock);
+static DEFINE_MUTEX(clock_list_sem);
+
+/* Minimum CLK support */
+enum {
+ DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT,
+ DC_87PT, DC_DISABLE, DC_RESV
+};
+
+struct cpufreq_frequency_table loongson2_clockmod_table[] = {
+ {DC_RESV, CPUFREQ_ENTRY_INVALID},
+ {DC_ZERO, CPUFREQ_ENTRY_INVALID},
+ {DC_25PT, 0},
+ {DC_37PT, 0},
+ {DC_50PT, 0},
+ {DC_62PT, 0},
+ {DC_75PT, 0},
+ {DC_87PT, 0},
+ {DC_DISABLE, 0},
+ {DC_RESV, CPUFREQ_TABLE_END},
+};
+EXPORT_SYMBOL_GPL(loongson2_clockmod_table);
+
+static struct clk cpu_clk = {
+ .name = "cpu_clk",
+ .flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES,
+ .rate = 800000000,
+};
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ return &cpu_clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+static void propagate_rate(struct clk *clk)
+{
+ struct clk *clkp;
+
+ list_for_each_entry(clkp, &clock_list, node) {
+ if (likely(clkp->parent != clk))
+ continue;
+ if (likely(clkp->ops && clkp->ops->recalc))
+ clkp->ops->recalc(clkp);
+ if (unlikely(clkp->flags & CLK_RATE_PROPAGATES))
+ propagate_rate(clkp);
+ }
+}
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return (unsigned long)clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ return clk_set_rate_ex(clk, rate, 0);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
+{
+ int ret = 0;
+ int regval;
+ int i;
+
+ if (likely(clk->ops && clk->ops->set_rate)) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&clock_lock, flags);
+ ret = clk->ops->set_rate(clk, rate, algo_id);
+ spin_unlock_irqrestore(&clock_lock, flags);
+ }
+
+ if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
+ propagate_rate(clk);
+
+ for (i = 0; loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END;
+ i++) {
+ if (loongson2_clockmod_table[i].frequency ==
+ CPUFREQ_ENTRY_INVALID)
+ continue;
+ if (rate == loongson2_clockmod_table[i].frequency)
+ break;
+ }
+ if (rate != loongson2_clockmod_table[i].frequency)
+ return -ENOTSUPP;
+
+ clk->rate = rate;
+
+ regval = LOONGSON_CHIPCFG0;
+ regval = (regval & ~0x7) | (loongson2_clockmod_table[i].index - 1);
+ LOONGSON_CHIPCFG0 = regval;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate_ex);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (likely(clk->ops && clk->ops->round_rate)) {
+ unsigned long flags, rounded;
+
+ spin_lock_irqsave(&clock_lock, flags);
+ rounded = clk->ops->round_rate(clk, rate);
+ spin_unlock_irqrestore(&clock_lock, flags);
+
+ return rounded;
+ }
+
+ return rate;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/*
+ * This is the simple version of Loongson-2 wait, Maybe we need do this in
+ * interrupt disabled content
+ */
+
+DEFINE_SPINLOCK(loongson2_wait_lock);
+void loongson2_cpu_wait(void)
+{
+ u32 cpu_freq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&loongson2_wait_lock, flags);
+ cpu_freq = LOONGSON_CHIPCFG0;
+ LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */
+ LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */
+ spin_unlock_irqrestore(&loongson2_wait_lock, flags);
+}
+EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c
new file mode 100644
index 00000000..ae5db206
--- /dev/null
+++ b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c
@@ -0,0 +1,227 @@
+/*
+ * Cpufreq driver for the loongson-2 processors
+ *
+ * The 2E revision of loongson processor not support this feature.
+ *
+ * Copyright (C) 2006 - 2008 Lemote Inc. & Insititute of Computing Technology
+ * Author: Yanhua, yanh@lemote.com
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/cpufreq.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/sched.h> /* set_cpus_allowed() */
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/clock.h>
+
+#include <loongson.h>
+
+static uint nowait;
+
+static struct clk *cpuclk;
+
+static void (*saved_cpu_wait) (void);
+
+static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
+ unsigned long val, void *data);
+
+static struct notifier_block loongson2_cpufreq_notifier_block = {
+ .notifier_call = loongson2_cpu_freq_notifier
+};
+
+static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ if (val == CPUFREQ_POSTCHANGE)
+ current_cpu_data.udelay_val = loops_per_jiffy;
+
+ return 0;
+}
+
+static unsigned int loongson2_cpufreq_get(unsigned int cpu)
+{
+ return clk_get_rate(cpuclk);
+}
+
+/*
+ * Here we notify other drivers of the proposed change and the final change.
+ */
+static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int cpu = policy->cpu;
+ unsigned int newstate = 0;
+ cpumask_t cpus_allowed;
+ struct cpufreq_freqs freqs;
+ unsigned int freq;
+
+ if (!cpu_online(cpu))
+ return -ENODEV;
+
+ cpus_allowed = current->cpus_allowed;
+ set_cpus_allowed_ptr(current, cpumask_of(cpu));
+
+ if (cpufreq_frequency_table_target
+ (policy, &loongson2_clockmod_table[0], target_freq, relation,
+ &newstate))
+ return -EINVAL;
+
+ freq =
+ ((cpu_clock_freq / 1000) *
+ loongson2_clockmod_table[newstate].index) / 8;
+ if (freq < policy->min || freq > policy->max)
+ return -EINVAL;
+
+ pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000);
+
+ freqs.cpu = cpu;
+ freqs.old = loongson2_cpufreq_get(cpu);
+ freqs.new = freq;
+ freqs.flags = 0;
+
+ if (freqs.new == freqs.old)
+ return 0;
+
+ /* notifiers */
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ set_cpus_allowed_ptr(current, &cpus_allowed);
+
+ /* setting the cpu frequency */
+ clk_set_rate(cpuclk, freq);
+
+ /* notifiers */
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ pr_debug("cpufreq: set frequency %u kHz\n", freq);
+
+ return 0;
+}
+
+static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ int i;
+
+ if (!cpu_online(policy->cpu))
+ return -ENODEV;
+
+ cpuclk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpuclk)) {
+ printk(KERN_ERR "cpufreq: couldn't get CPU clk\n");
+ return PTR_ERR(cpuclk);
+ }
+
+ cpuclk->rate = cpu_clock_freq / 1000;
+ if (!cpuclk->rate)
+ return -EINVAL;
+
+ /* clock table init */
+ for (i = 2;
+ (loongson2_clockmod_table[i].frequency != CPUFREQ_TABLE_END);
+ i++)
+ loongson2_clockmod_table[i].frequency = (cpuclk->rate * i) / 8;
+
+ policy->cur = loongson2_cpufreq_get(policy->cpu);
+
+ cpufreq_frequency_table_get_attr(&loongson2_clockmod_table[0],
+ policy->cpu);
+
+ return cpufreq_frequency_table_cpuinfo(policy,
+ &loongson2_clockmod_table[0]);
+}
+
+static int loongson2_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy,
+ &loongson2_clockmod_table[0]);
+}
+
+static int loongson2_cpufreq_exit(struct cpufreq_policy *policy)
+{
+ clk_put(cpuclk);
+ return 0;
+}
+
+static struct freq_attr *loongson2_table_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver loongson2_cpufreq_driver = {
+ .owner = THIS_MODULE,
+ .name = "loongson2",
+ .init = loongson2_cpufreq_cpu_init,
+ .verify = loongson2_cpufreq_verify,
+ .target = loongson2_cpufreq_target,
+ .get = loongson2_cpufreq_get,
+ .exit = loongson2_cpufreq_exit,
+ .attr = loongson2_table_attr,
+};
+
+static struct platform_device_id platform_device_ids[] = {
+ {
+ .name = "loongson2_cpufreq",
+ },
+ {}
+};
+
+MODULE_DEVICE_TABLE(platform, platform_device_ids);
+
+static struct platform_driver platform_driver = {
+ .driver = {
+ .name = "loongson2_cpufreq",
+ .owner = THIS_MODULE,
+ },
+ .id_table = platform_device_ids,
+};
+
+static int __init cpufreq_init(void)
+{
+ int ret;
+
+ /* Register platform stuff */
+ ret = platform_driver_register(&platform_driver);
+ if (ret)
+ return ret;
+
+ pr_info("cpufreq: Loongson-2F CPU frequency driver.\n");
+
+ cpufreq_register_notifier(&loongson2_cpufreq_notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ ret = cpufreq_register_driver(&loongson2_cpufreq_driver);
+
+ if (!ret && !nowait) {
+ saved_cpu_wait = cpu_wait;
+ cpu_wait = loongson2_cpu_wait;
+ }
+
+ return ret;
+}
+
+static void __exit cpufreq_exit(void)
+{
+ if (!nowait && saved_cpu_wait)
+ cpu_wait = saved_cpu_wait;
+ cpufreq_unregister_driver(&loongson2_cpufreq_driver);
+ cpufreq_unregister_notifier(&loongson2_cpufreq_notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ platform_driver_unregister(&platform_driver);
+}
+
+module_init(cpufreq_init);
+module_exit(cpufreq_exit);
+
+module_param(nowait, uint, 0644);
+MODULE_PARM_DESC(nowait, "Disable Loongson-2F specific wait");
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson2F");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/csrc-bcm1480.c b/arch/mips/kernel/csrc-bcm1480.c
new file mode 100644
index 00000000..f96f99c7
--- /dev/null
+++ b/arch/mips/kernel/csrc-bcm1480.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2000,2001,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/clocksource.h>
+
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/time.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+#include <asm/sibyte/bcm1480_scd.h>
+
+#include <asm/sibyte/sb1250.h>
+
+static cycle_t bcm1480_hpt_read(struct clocksource *cs)
+{
+ return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
+}
+
+struct clocksource bcm1480_clocksource = {
+ .name = "zbbus-cycles",
+ .rating = 200,
+ .read = bcm1480_hpt_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sb1480_clocksource_init(void)
+{
+ struct clocksource *cs = &bcm1480_clocksource;
+ unsigned int plldiv;
+ unsigned long zbbus;
+
+ plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
+ clocksource_register_hz(cs, zbbus);
+}
diff --git a/arch/mips/kernel/csrc-ioasic.c b/arch/mips/kernel/csrc-ioasic.c
new file mode 100644
index 00000000..46bd7fa9
--- /dev/null
+++ b/arch/mips/kernel/csrc-ioasic.c
@@ -0,0 +1,63 @@
+/*
+ * DEC I/O ASIC's counter clocksource
+ *
+ * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/clocksource.h>
+#include <linux/init.h>
+
+#include <asm/ds1287.h>
+#include <asm/time.h>
+#include <asm/dec/ioasic.h>
+#include <asm/dec/ioasic_addrs.h>
+
+static cycle_t dec_ioasic_hpt_read(struct clocksource *cs)
+{
+ return ioasic_read(IO_REG_FCTR);
+}
+
+static struct clocksource clocksource_dec = {
+ .name = "dec-ioasic",
+ .read = dec_ioasic_hpt_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init dec_ioasic_clocksource_init(void)
+{
+ unsigned int freq;
+ u32 start, end;
+ int i = HZ / 10;
+
+
+ while (!ds1287_timer_state())
+ ;
+
+ start = dec_ioasic_hpt_read(&clocksource_dec);
+
+ while (i--)
+ while (!ds1287_timer_state())
+ ;
+
+ end = dec_ioasic_hpt_read(&clocksource_dec);
+
+ freq = (end - start) * 10;
+ printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
+
+ clocksource_dec.rating = 200 + freq / 10000000;
+ clocksource_register_hz(&clocksource_dec, freq);
+}
diff --git a/arch/mips/kernel/csrc-powertv.c b/arch/mips/kernel/csrc-powertv.c
new file mode 100644
index 00000000..2e7c5232
--- /dev/null
+++ b/arch/mips/kernel/csrc-powertv.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2008 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * The file comes from kernel/csrc-r4k.c
+ */
+#include <linux/clocksource.h>
+#include <linux/init.h>
+
+#include <asm/time.h> /* Not included in linux/time.h */
+
+#include <asm/mach-powertv/asic_regs.h>
+#include "powertv-clock.h"
+
+/* MIPS PLL Register Definitions */
+#define PLL_GET_M(x) (((x) >> 8) & 0x000000FF)
+#define PLL_GET_N(x) (((x) >> 16) & 0x000000FF)
+#define PLL_GET_P(x) (((x) >> 24) & 0x00000007)
+
+/*
+ * returns: Clock frequency in kHz
+ */
+unsigned int __init mips_get_pll_freq(void)
+{
+ unsigned int pll_reg, m, n, p;
+ unsigned int fin = 54000; /* Base frequency in kHz */
+ unsigned int fout;
+
+ /* Read PLL register setting */
+ pll_reg = asic_read(mips_pll_setup);
+ m = PLL_GET_M(pll_reg);
+ n = PLL_GET_N(pll_reg);
+ p = PLL_GET_P(pll_reg);
+ pr_info("MIPS PLL Register:0x%x M=%d N=%d P=%d\n", pll_reg, m, n, p);
+
+ /* Calculate clock frequency = (2 * N * 54MHz) / (M * (2**P)) */
+ fout = ((2 * n * fin) / (m * (0x01 << p)));
+
+ pr_info("MIPS Clock Freq=%d kHz\n", fout);
+
+ return fout;
+}
+
+static cycle_t c0_hpt_read(struct clocksource *cs)
+{
+ return read_c0_count();
+}
+
+static struct clocksource clocksource_mips = {
+ .name = "powertv-counter",
+ .read = c0_hpt_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init powertv_c0_hpt_clocksource_init(void)
+{
+ unsigned int pll_freq = mips_get_pll_freq();
+
+ pr_info("CPU frequency %d.%02d MHz\n", pll_freq / 1000,
+ (pll_freq % 1000) * 100 / 1000);
+
+ mips_hpt_frequency = pll_freq / 2 * 1000;
+
+ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+
+ clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
+}
+
+/**
+ * struct tim_c - free running counter
+ * @hi: High 16 bits of the counter
+ * @lo: Low 32 bits of the counter
+ *
+ * Lays out the structure of the free running counter in memory. This counter
+ * increments at a rate of 27 MHz/8 on all platforms.
+ */
+struct tim_c {
+ unsigned int hi;
+ unsigned int lo;
+};
+
+static struct tim_c *tim_c;
+
+static cycle_t tim_c_read(struct clocksource *cs)
+{
+ unsigned int hi;
+ unsigned int next_hi;
+ unsigned int lo;
+
+ hi = readl(&tim_c->hi);
+
+ for (;;) {
+ lo = readl(&tim_c->lo);
+ next_hi = readl(&tim_c->hi);
+ if (next_hi == hi)
+ break;
+ hi = next_hi;
+ }
+
+pr_crit("%s: read %llx\n", __func__, ((u64) hi << 32) | lo);
+ return ((u64) hi << 32) | lo;
+}
+
+#define TIM_C_SIZE 48 /* # bits in the timer */
+
+static struct clocksource clocksource_tim_c = {
+ .name = "powertv-tim_c",
+ .read = tim_c_read,
+ .mask = CLOCKSOURCE_MASK(TIM_C_SIZE),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/**
+ * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock
+ *
+ * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to
+ * 1 / (27,000,000/8) seconds.
+ */
+static void __init powertv_tim_c_clocksource_init(void)
+{
+ const unsigned long counts_per_second = 27000000 / 8;
+
+ clocksource_tim_c.rating = 200;
+
+ clocksource_register_hz(&clocksource_tim_c, counts_per_second);
+ tim_c = (struct tim_c *) asic_reg_addr(tim_ch);
+}
+
+/**
+ powertv_clocksource_init - initialize all clocksources
+ */
+void __init powertv_clocksource_init(void)
+{
+ powertv_c0_hpt_clocksource_init();
+ powertv_tim_c_clocksource_init();
+}
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
new file mode 100644
index 00000000..decd1fa3
--- /dev/null
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 by Ralf Baechle
+ */
+#include <linux/clocksource.h>
+#include <linux/init.h>
+
+#include <asm/time.h>
+
+static cycle_t c0_hpt_read(struct clocksource *cs)
+{
+ return read_c0_count();
+}
+
+static struct clocksource clocksource_mips = {
+ .name = "MIPS",
+ .read = c0_hpt_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+int __init init_r4k_clocksource(void)
+{
+ if (!cpu_has_counter || !mips_hpt_frequency)
+ return -ENXIO;
+
+ /* Calculate a somewhat reasonable rating value */
+ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+
+ clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
+
+ return 0;
+}
diff --git a/arch/mips/kernel/csrc-sb1250.c b/arch/mips/kernel/csrc-sb1250.c
new file mode 100644
index 00000000..e9606d90
--- /dev/null
+++ b/arch/mips/kernel/csrc-sb1250.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/clocksource.h>
+
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/time.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+#define SB1250_HPT_NUM 3
+#define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */
+
+/*
+ * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
+ * again.
+ */
+static cycle_t sb1250_hpt_read(struct clocksource *cs)
+{
+ unsigned int count;
+
+ count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT))));
+
+ return SB1250_HPT_VALUE - count;
+}
+
+struct clocksource bcm1250_clocksource = {
+ .name = "bcm1250-counter-3",
+ .rating = 200,
+ .read = sb1250_hpt_read,
+ .mask = CLOCKSOURCE_MASK(23),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sb1250_clocksource_init(void)
+{
+ struct clocksource *cs = &bcm1250_clocksource;
+
+ /* Setup hpt using timer #3 but do not enable irq for it */
+ __raw_writeq(0,
+ IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+ R_SCD_TIMER_CFG)));
+ __raw_writeq(SB1250_HPT_VALUE,
+ IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+ R_SCD_TIMER_INIT)));
+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+ R_SCD_TIMER_CFG)));
+
+ clocksource_register_hz(cs, V_SCD_TIMER_FREQ);
+}
diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c
new file mode 100644
index 00000000..9ae813eb
--- /dev/null
+++ b/arch/mips/kernel/early_printk.c
@@ -0,0 +1,44 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2003, 06, 07 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * written by Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/console.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+
+extern void prom_putchar(char);
+
+static void __init
+early_console_write(struct console *con, const char *s, unsigned n)
+{
+ while (n-- && *s) {
+ if (*s == '\n')
+ prom_putchar('\r');
+ prom_putchar(*s);
+ s++;
+ }
+}
+
+static struct console early_console __initdata = {
+ .name = "early",
+ .write = early_console_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1
+};
+
+static int early_console_initialized __initdata;
+
+void __init setup_early_printk(void)
+{
+ if (early_console_initialized)
+ return;
+ early_console_initialized = 1;
+
+ register_console(&early_console);
+}
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
new file mode 100644
index 00000000..37acfa03
--- /dev/null
+++ b/arch/mips/kernel/entry.S
@@ -0,0 +1,192 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/isadep.h>
+#include <asm/thread_info.h>
+#include <asm/war.h>
+#ifdef CONFIG_MIPS_MT_SMTC
+#include <asm/mipsmtregs.h>
+#endif
+
+#ifndef CONFIG_PREEMPT
+#define resume_kernel restore_all
+#else
+#define __ret_from_irq ret_from_exception
+#endif
+
+ .text
+ .align 5
+#ifndef CONFIG_PREEMPT
+FEXPORT(ret_from_exception)
+ local_irq_disable # preempt stop
+ b __ret_from_irq
+#endif
+FEXPORT(ret_from_irq)
+ LONG_S s0, TI_REGS($28)
+FEXPORT(__ret_from_irq)
+ LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
+ andi t0, t0, KU_USER
+ beqz t0, resume_kernel
+
+resume_userspace:
+ local_irq_disable # make sure we dont miss an
+ # interrupt setting need_resched
+ # between sampling and return
+ LONG_L a2, TI_FLAGS($28) # current->work
+ andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace)
+ bnez t0, work_pending
+ j restore_all
+
+#ifdef CONFIG_PREEMPT
+resume_kernel:
+ local_irq_disable
+ lw t0, TI_PRE_COUNT($28)
+ bnez t0, restore_all
+need_resched:
+ LONG_L t0, TI_FLAGS($28)
+ andi t1, t0, _TIF_NEED_RESCHED
+ beqz t1, restore_all
+ LONG_L t0, PT_STATUS(sp) # Interrupts off?
+ andi t0, 1
+ beqz t0, restore_all
+ jal preempt_schedule_irq
+ b need_resched
+#endif
+
+FEXPORT(ret_from_fork)
+ jal schedule_tail # a0 = struct task_struct *prev
+
+FEXPORT(syscall_exit)
+ local_irq_disable # make sure need_resched and
+ # signals dont change between
+ # sampling and return
+ LONG_L a2, TI_FLAGS($28) # current->work
+ li t0, _TIF_ALLWORK_MASK
+ and t0, a2, t0
+ bnez t0, syscall_exit_work
+
+FEXPORT(restore_all) # restore full frame
+#ifdef CONFIG_MIPS_MT_SMTC
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
+/* Re-arm any temporarily masked interrupts not explicitly "acked" */
+ mfc0 v0, CP0_TCSTATUS
+ ori v1, v0, TCSTATUS_IXMT
+ mtc0 v1, CP0_TCSTATUS
+ andi v0, TCSTATUS_IXMT
+ _ehb
+ mfc0 t0, CP0_TCCONTEXT
+ DMT 9 # dmt t1
+ jal mips_ihb
+ mfc0 t2, CP0_STATUS
+ andi t3, t0, 0xff00
+ or t2, t2, t3
+ mtc0 t2, CP0_STATUS
+ _ehb
+ andi t1, t1, VPECONTROL_TE
+ beqz t1, 1f
+ EMT
+1:
+ mfc0 v1, CP0_TCSTATUS
+ /* We set IXMT above, XOR should clear it here */
+ xori v1, v1, TCSTATUS_IXMT
+ or v1, v0, v1
+ mtc0 v1, CP0_TCSTATUS
+ _ehb
+ xor t0, t0, t3
+ mtc0 t0, CP0_TCCONTEXT
+#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
+/* Detect and execute deferred IPI "interrupts" */
+ LONG_L s0, TI_REGS($28)
+ LONG_S sp, TI_REGS($28)
+ jal deferred_smtc_ipi
+ LONG_S s0, TI_REGS($28)
+#endif /* CONFIG_MIPS_MT_SMTC */
+ .set noat
+ RESTORE_TEMP
+ RESTORE_AT
+ RESTORE_STATIC
+FEXPORT(restore_partial) # restore partial frame
+#ifdef CONFIG_TRACE_IRQFLAGS
+ SAVE_STATIC
+ SAVE_AT
+ SAVE_TEMP
+ LONG_L v0, PT_STATUS(sp)
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+ and v0, ST0_IEP
+#else
+ and v0, ST0_IE
+#endif
+ beqz v0, 1f
+ jal trace_hardirqs_on
+ b 2f
+1: jal trace_hardirqs_off
+2:
+ RESTORE_TEMP
+ RESTORE_AT
+ RESTORE_STATIC
+#endif
+ RESTORE_SOME
+ RESTORE_SP_AND_RET
+ .set at
+
+work_pending:
+ andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
+ beqz t0, work_notifysig
+work_resched:
+ jal schedule
+
+ local_irq_disable # make sure need_resched and
+ # signals dont change between
+ # sampling and return
+ LONG_L a2, TI_FLAGS($28)
+ andi t0, a2, _TIF_WORK_MASK # is there any work to be done
+ # other than syscall tracing?
+ beqz t0, restore_all
+ andi t0, a2, _TIF_NEED_RESCHED
+ bnez t0, work_resched
+
+work_notifysig: # deal with pending signals and
+ # notify-resume requests
+ move a0, sp
+ li a1, 0
+ jal do_notify_resume # a2 already loaded
+ j resume_userspace
+
+FEXPORT(syscall_exit_work_partial)
+ SAVE_STATIC
+syscall_exit_work:
+ li t0, _TIF_WORK_SYSCALL_EXIT
+ and t0, a2 # a2 is preloaded with TI_FLAGS
+ beqz t0, work_pending # trace bit set?
+ local_irq_enable # could let syscall_trace_leave()
+ # call schedule() instead
+ move a0, sp
+ jal syscall_trace_leave
+ b resume_userspace
+
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT)
+
+/*
+ * MIPS32R2 Instruction Hazard Barrier - must be called
+ *
+ * For C code use the inline version named instruction_hazard().
+ */
+LEAF(mips_ihb)
+ .set mips32r2
+ jr.hb ra
+ nop
+ END(mips_ihb)
+
+#endif /* CONFIG_CPU_MIPSR2 or CONFIG_MIPS_MT */
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
new file mode 100644
index 00000000..feb8021a
--- /dev/null
+++ b/arch/mips/kernel/ftrace.c
@@ -0,0 +1,327 @@
+/*
+ * Code for replacing ftrace calls with jumps.
+ *
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ * Copyright (C) 2009, 2010 DSLab, Lanzhou University, China
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * Thanks goes to Steven Rostedt for writing the original x86 version.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/init.h>
+#include <linux/ftrace.h>
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cacheflush.h>
+#include <asm/uasm.h>
+
+#include <asm-generic/sections.h>
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */
+#define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */
+#define JUMP_RANGE_MASK ((1UL << 28) - 1)
+
+#define INSN_NOP 0x00000000 /* nop */
+#define INSN_JAL(addr) \
+ ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK)))
+
+static unsigned int insn_jal_ftrace_caller __read_mostly;
+static unsigned int insn_lui_v1_hi16_mcount __read_mostly;
+static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly;
+
+static inline void ftrace_dyn_arch_init_insns(void)
+{
+ u32 *buf;
+ unsigned int v1;
+
+ /* lui v1, hi16_mcount */
+ v1 = 3;
+ buf = (u32 *)&insn_lui_v1_hi16_mcount;
+ UASM_i_LA_mostly(&buf, v1, MCOUNT_ADDR);
+
+ /* jal (ftrace_caller + 8), jump over the first two instruction */
+ buf = (u32 *)&insn_jal_ftrace_caller;
+ uasm_i_jal(&buf, (FTRACE_ADDR + 8) & JUMP_RANGE_MASK);
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ /* j ftrace_graph_caller */
+ buf = (u32 *)&insn_j_ftrace_graph_caller;
+ uasm_i_j(&buf, (unsigned long)ftrace_graph_caller & JUMP_RANGE_MASK);
+#endif
+}
+
+/*
+ * Check if the address is in kernel space
+ *
+ * Clone core_kernel_text() from kernel/extable.c, but doesn't call
+ * init_kernel_text() for Ftrace doesn't trace functions in init sections.
+ */
+static inline int in_kernel_space(unsigned long ip)
+{
+ if (ip >= (unsigned long)_stext &&
+ ip <= (unsigned long)_etext)
+ return 1;
+ return 0;
+}
+
+static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
+{
+ int faulted;
+
+ /* *(unsigned int *)ip = new_code; */
+ safe_store_code(new_code, ip, faulted);
+
+ if (unlikely(faulted))
+ return -EFAULT;
+
+ flush_icache_range(ip, ip + 8);
+
+ return 0;
+}
+
+/*
+ * The details about the calling site of mcount on MIPS
+ *
+ * 1. For kernel:
+ *
+ * move at, ra
+ * jal _mcount --> nop
+ *
+ * 2. For modules:
+ *
+ * 2.1 For KBUILD_MCOUNT_RA_ADDRESS and CONFIG_32BIT
+ *
+ * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005)
+ * addiu v1, v1, low_16bit_of_mcount
+ * move at, ra
+ * move $12, ra_address
+ * jalr v1
+ * sub sp, sp, 8
+ * 1: offset = 5 instructions
+ * 2.2 For the Other situations
+ *
+ * lui v1, hi_16bit_of_mcount --> b 1f (0x10000004)
+ * addiu v1, v1, low_16bit_of_mcount
+ * move at, ra
+ * jalr v1
+ * nop | move $12, ra_address | sub sp, sp, 8
+ * 1: offset = 4 instructions
+ */
+
+#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
+#define MCOUNT_OFFSET_INSNS 5
+#else
+#define MCOUNT_OFFSET_INSNS 4
+#endif
+#define INSN_B_1F (0x10000000 | MCOUNT_OFFSET_INSNS)
+
+int ftrace_make_nop(struct module *mod,
+ struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned int new;
+ unsigned long ip = rec->ip;
+
+ /*
+ * If ip is in kernel space, no long call, otherwise, long call is
+ * needed.
+ */
+ new = in_kernel_space(ip) ? INSN_NOP : INSN_B_1F;
+
+ return ftrace_modify_code(ip, new);
+}
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned int new;
+ unsigned long ip = rec->ip;
+
+ new = in_kernel_space(ip) ? insn_jal_ftrace_caller :
+ insn_lui_v1_hi16_mcount;
+
+ return ftrace_modify_code(ip, new);
+}
+
+#define FTRACE_CALL_IP ((unsigned long)(&ftrace_call))
+
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+ unsigned int new;
+
+ new = INSN_JAL((unsigned long)func);
+
+ return ftrace_modify_code(FTRACE_CALL_IP, new);
+}
+
+int __init ftrace_dyn_arch_init(void *data)
+{
+ /* Encode the instructions when booting */
+ ftrace_dyn_arch_init_insns();
+
+ /* Remove "b ftrace_stub" to ensure ftrace_caller() is executed */
+ ftrace_modify_code(MCOUNT_ADDR, INSN_NOP);
+
+ /* The return code is retured via data */
+ *(unsigned long *)data = 0;
+
+ return 0;
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+extern void ftrace_graph_call(void);
+#define FTRACE_GRAPH_CALL_IP ((unsigned long)(&ftrace_graph_call))
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+ return ftrace_modify_code(FTRACE_GRAPH_CALL_IP,
+ insn_j_ftrace_graph_caller);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+ return ftrace_modify_code(FTRACE_GRAPH_CALL_IP, INSN_NOP);
+}
+
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifndef KBUILD_MCOUNT_RA_ADDRESS
+
+#define S_RA_SP (0xafbf << 16) /* s{d,w} ra, offset(sp) */
+#define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */
+#define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */
+
+unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
+ old_parent_ra, unsigned long parent_ra_addr, unsigned long fp)
+{
+ unsigned long sp, ip, tmp;
+ unsigned int code;
+ int faulted;
+
+ /*
+ * For module, move the ip from the return address after the
+ * instruction "lui v1, hi_16bit_of_mcount"(offset is 24), but for
+ * kernel, move after the instruction "move ra, at"(offset is 16)
+ */
+ ip = self_ra - (in_kernel_space(self_ra) ? 16 : 24);
+
+ /*
+ * search the text until finding the non-store instruction or "s{d,w}
+ * ra, offset(sp)" instruction
+ */
+ do {
+ /* get the code at "ip": code = *(unsigned int *)ip; */
+ safe_load_code(code, ip, faulted);
+
+ if (unlikely(faulted))
+ return 0;
+ /*
+ * If we hit the non-store instruction before finding where the
+ * ra is stored, then this is a leaf function and it does not
+ * store the ra on the stack
+ */
+ if ((code & S_R_SP) != S_R_SP)
+ return parent_ra_addr;
+
+ /* Move to the next instruction */
+ ip -= 4;
+ } while ((code & S_RA_SP) != S_RA_SP);
+
+ sp = fp + (code & OFFSET_MASK);
+
+ /* tmp = *(unsigned long *)sp; */
+ safe_load_stack(tmp, sp, faulted);
+ if (unlikely(faulted))
+ return 0;
+
+ if (tmp == old_parent_ra)
+ return sp;
+ return 0;
+}
+
+#endif /* !KBUILD_MCOUNT_RA_ADDRESS */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
+ unsigned long fp)
+{
+ unsigned long old_parent_ra;
+ struct ftrace_graph_ent trace;
+ unsigned long return_hooker = (unsigned long)
+ &return_to_handler;
+ int faulted, insns;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return;
+
+ /*
+ * "parent_ra_addr" is the stack address saved the return address of
+ * the caller of _mcount.
+ *
+ * if the gcc < 4.5, a leaf function does not save the return address
+ * in the stack address, so, we "emulate" one in _mcount's stack space,
+ * and hijack it directly, but for a non-leaf function, it save the
+ * return address to the its own stack space, we can not hijack it
+ * directly, but need to find the real stack address,
+ * ftrace_get_parent_addr() does it!
+ *
+ * if gcc>= 4.5, with the new -mmcount-ra-address option, for a
+ * non-leaf function, the location of the return address will be saved
+ * to $12 for us, and for a leaf function, only put a zero into $12. we
+ * do it in ftrace_graph_caller of mcount.S.
+ */
+
+ /* old_parent_ra = *parent_ra_addr; */
+ safe_load_stack(old_parent_ra, parent_ra_addr, faulted);
+ if (unlikely(faulted))
+ goto out;
+#ifndef KBUILD_MCOUNT_RA_ADDRESS
+ parent_ra_addr = (unsigned long *)ftrace_get_parent_ra_addr(self_ra,
+ old_parent_ra, (unsigned long)parent_ra_addr, fp);
+ /*
+ * If fails when getting the stack address of the non-leaf function's
+ * ra, stop function graph tracer and return
+ */
+ if (parent_ra_addr == 0)
+ goto out;
+#endif
+ /* *parent_ra_addr = return_hooker; */
+ safe_store_stack(return_hooker, parent_ra_addr, faulted);
+ if (unlikely(faulted))
+ goto out;
+
+ if (ftrace_push_return_trace(old_parent_ra, self_ra, &trace.depth, fp)
+ == -EBUSY) {
+ *parent_ra_addr = old_parent_ra;
+ return;
+ }
+
+ /*
+ * Get the recorded ip of the current mcount calling site in the
+ * __mcount_loc section, which will be used to filter the function
+ * entries configured through the tracing/set_graph_function interface.
+ */
+
+ insns = in_kernel_space(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1;
+ trace.func = self_ra - (MCOUNT_INSN_SIZE * insns);
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ current->curr_ret_stack--;
+ *parent_ra_addr = old_parent_ra;
+ }
+ return;
+out:
+ ftrace_graph_stop();
+ WARN_ON(1);
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
new file mode 100644
index 00000000..8882e576
--- /dev/null
+++ b/arch/mips/kernel/genex.S
@@ -0,0 +1,548 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2002, 2007 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/cacheops.h>
+#include <asm/irqflags.h>
+#include <asm/regdef.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/war.h>
+#include <asm/page.h>
+#include <asm/thread_info.h>
+
+#define PANIC_PIC(msg) \
+ .set push; \
+ .set reorder; \
+ PTR_LA a0,8f; \
+ .set noat; \
+ PTR_LA AT, panic; \
+ jr AT; \
+9: b 9b; \
+ .set pop; \
+ TEXT(msg)
+
+ __INIT
+
+NESTED(except_vec0_generic, 0, sp)
+ PANIC_PIC("Exception vector 0 called")
+ END(except_vec0_generic)
+
+NESTED(except_vec1_generic, 0, sp)
+ PANIC_PIC("Exception vector 1 called")
+ END(except_vec1_generic)
+
+/*
+ * General exception vector for all other CPUs.
+ *
+ * Be careful when changing this, it has to be at most 128 bytes
+ * to fit into space reserved for the exception handler.
+ */
+NESTED(except_vec3_generic, 0, sp)
+ .set push
+ .set noat
+#if R5432_CP0_INTERRUPT_WAR
+ mfc0 k0, CP0_INDEX
+#endif
+ mfc0 k1, CP0_CAUSE
+ andi k1, k1, 0x7c
+#ifdef CONFIG_64BIT
+ dsll k1, k1, 1
+#endif
+ PTR_L k0, exception_handlers(k1)
+ jr k0
+ .set pop
+ END(except_vec3_generic)
+
+/*
+ * General exception handler for CPUs with virtual coherency exception.
+ *
+ * Be careful when changing this, it has to be at most 256 (as a special
+ * exception) bytes to fit into space reserved for the exception handler.
+ */
+NESTED(except_vec3_r4000, 0, sp)
+ .set push
+ .set mips3
+ .set noat
+ mfc0 k1, CP0_CAUSE
+ li k0, 31<<2
+ andi k1, k1, 0x7c
+ .set push
+ .set noreorder
+ .set nomacro
+ beq k1, k0, handle_vced
+ li k0, 14<<2
+ beq k1, k0, handle_vcei
+#ifdef CONFIG_64BIT
+ dsll k1, k1, 1
+#endif
+ .set pop
+ PTR_L k0, exception_handlers(k1)
+ jr k0
+
+ /*
+ * Big shit, we now may have two dirty primary cache lines for the same
+ * physical address. We can safely invalidate the line pointed to by
+ * c0_badvaddr because after return from this exception handler the
+ * load / store will be re-executed.
+ */
+handle_vced:
+ MFC0 k0, CP0_BADVADDR
+ li k1, -4 # Is this ...
+ and k0, k1 # ... really needed?
+ mtc0 zero, CP0_TAGLO
+ cache Index_Store_Tag_D, (k0)
+ cache Hit_Writeback_Inv_SD, (k0)
+#ifdef CONFIG_PROC_FS
+ PTR_LA k0, vced_count
+ lw k1, (k0)
+ addiu k1, 1
+ sw k1, (k0)
+#endif
+ eret
+
+handle_vcei:
+ MFC0 k0, CP0_BADVADDR
+ cache Hit_Writeback_Inv_SD, (k0) # also cleans pi
+#ifdef CONFIG_PROC_FS
+ PTR_LA k0, vcei_count
+ lw k1, (k0)
+ addiu k1, 1
+ sw k1, (k0)
+#endif
+ eret
+ .set pop
+ END(except_vec3_r4000)
+
+ __FINIT
+
+ .align 5 /* 32 byte rollback region */
+LEAF(r4k_wait)
+ .set push
+ .set noreorder
+ /* start of rollback region */
+ LONG_L t0, TI_FLAGS($28)
+ nop
+ andi t0, _TIF_NEED_RESCHED
+ bnez t0, 1f
+ nop
+ nop
+ nop
+ .set mips3
+ wait
+ /* end of rollback region (the region size must be power of two) */
+ .set pop
+1:
+ jr ra
+ END(r4k_wait)
+
+ .macro BUILD_ROLLBACK_PROLOGUE handler
+ FEXPORT(rollback_\handler)
+ .set push
+ .set noat
+ MFC0 k0, CP0_EPC
+ PTR_LA k1, r4k_wait
+ ori k0, 0x1f /* 32 byte rollback region */
+ xori k0, 0x1f
+ bne k0, k1, 9f
+ MTC0 k0, CP0_EPC
+9:
+ .set pop
+ .endm
+
+ .align 5
+BUILD_ROLLBACK_PROLOGUE handle_int
+NESTED(handle_int, PT_SIZE, sp)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ /*
+ * Check to see if the interrupted code has just disabled
+ * interrupts and ignore this interrupt for now if so.
+ *
+ * local_irq_disable() disables interrupts and then calls
+ * trace_hardirqs_off() to track the state. If an interrupt is taken
+ * after interrupts are disabled but before the state is updated
+ * it will appear to restore_all that it is incorrectly returning with
+ * interrupts disabled
+ */
+ .set push
+ .set noat
+ mfc0 k0, CP0_STATUS
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+ and k0, ST0_IEP
+ bnez k0, 1f
+
+ mfc0 k0, CP0_EPC
+ .set noreorder
+ j k0
+ rfe
+#else
+ and k0, ST0_IE
+ bnez k0, 1f
+
+ eret
+#endif
+1:
+ .set pop
+#endif
+ SAVE_ALL
+ CLI
+ TRACE_IRQS_OFF
+
+ LONG_L s0, TI_REGS($28)
+ LONG_S sp, TI_REGS($28)
+ PTR_LA ra, ret_from_irq
+ j plat_irq_dispatch
+ END(handle_int)
+
+ __INIT
+
+/*
+ * Special interrupt vector for MIPS64 ISA & embedded MIPS processors.
+ * This is a dedicated interrupt exception vector which reduces the
+ * interrupt processing overhead. The jump instruction will be replaced
+ * at the initialization time.
+ *
+ * Be careful when changing this, it has to be at most 128 bytes
+ * to fit into space reserved for the exception handler.
+ */
+NESTED(except_vec4, 0, sp)
+1: j 1b /* Dummy, will be replaced */
+ END(except_vec4)
+
+/*
+ * EJTAG debug exception handler.
+ * The EJTAG debug exception entry point is 0xbfc00480, which
+ * normally is in the boot PROM, so the boot PROM must do a
+ * unconditional jump to this vector.
+ */
+NESTED(except_vec_ejtag_debug, 0, sp)
+ j ejtag_debug_handler
+ END(except_vec_ejtag_debug)
+
+ __FINIT
+
+/*
+ * Vectored interrupt handler.
+ * This prototype is copied to ebase + n*IntCtl.VS and patched
+ * to invoke the handler
+ */
+BUILD_ROLLBACK_PROLOGUE except_vec_vi
+NESTED(except_vec_vi, 0, sp)
+ SAVE_SOME
+ SAVE_AT
+ .set push
+ .set noreorder
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * To keep from blindly blocking *all* interrupts
+ * during service by SMTC kernel, we also want to
+ * pass the IM value to be cleared.
+ */
+FEXPORT(except_vec_vi_mori)
+ ori a0, $0, 0
+#endif /* CONFIG_MIPS_MT_SMTC */
+FEXPORT(except_vec_vi_lui)
+ lui v0, 0 /* Patched */
+ j except_vec_vi_handler
+FEXPORT(except_vec_vi_ori)
+ ori v0, 0 /* Patched */
+ .set pop
+ END(except_vec_vi)
+EXPORT(except_vec_vi_end)
+
+/*
+ * Common Vectored Interrupt code
+ * Complete the register saves and invoke the handler which is passed in $v0
+ */
+NESTED(except_vec_vi_handler, 0, sp)
+ SAVE_TEMP
+ SAVE_STATIC
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC has an interesting problem that interrupts are level-triggered,
+ * and the CLI macro will clear EXL, potentially causing a duplicate
+ * interrupt service invocation. So we need to clear the associated
+ * IM bit of Status prior to doing CLI, and restore it after the
+ * service routine has been invoked - we must assume that the
+ * service routine will have cleared the state, and any active
+ * level represents a new or otherwised unserviced event...
+ */
+ mfc0 t1, CP0_STATUS
+ and t0, a0, t1
+#ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
+ mfc0 t2, CP0_TCCONTEXT
+ or t2, t0, t2
+ mtc0 t2, CP0_TCCONTEXT
+#endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */
+ xor t1, t1, t0
+ mtc0 t1, CP0_STATUS
+ _ehb
+#endif /* CONFIG_MIPS_MT_SMTC */
+ CLI
+#ifdef CONFIG_TRACE_IRQFLAGS
+ move s0, v0
+#ifdef CONFIG_MIPS_MT_SMTC
+ move s1, a0
+#endif
+ TRACE_IRQS_OFF
+#ifdef CONFIG_MIPS_MT_SMTC
+ move a0, s1
+#endif
+ move v0, s0
+#endif
+
+ LONG_L s0, TI_REGS($28)
+ LONG_S sp, TI_REGS($28)
+ PTR_LA ra, ret_from_irq
+ jr v0
+ END(except_vec_vi_handler)
+
+/*
+ * EJTAG debug exception handler.
+ */
+NESTED(ejtag_debug_handler, PT_SIZE, sp)
+ .set push
+ .set noat
+ MTC0 k0, CP0_DESAVE
+ mfc0 k0, CP0_DEBUG
+
+ sll k0, k0, 30 # Check for SDBBP.
+ bgez k0, ejtag_return
+
+ PTR_LA k0, ejtag_debug_buffer
+ LONG_S k1, 0(k0)
+ SAVE_ALL
+ move a0, sp
+ jal ejtag_exception_handler
+ RESTORE_ALL
+ PTR_LA k0, ejtag_debug_buffer
+ LONG_L k1, 0(k0)
+
+ejtag_return:
+ MFC0 k0, CP0_DESAVE
+ .set mips32
+ deret
+ .set pop
+ END(ejtag_debug_handler)
+
+/*
+ * This buffer is reserved for the use of the EJTAG debug
+ * handler.
+ */
+ .data
+EXPORT(ejtag_debug_buffer)
+ .fill LONGSIZE
+ .previous
+
+ __INIT
+
+/*
+ * NMI debug exception handler for MIPS reference boards.
+ * The NMI debug exception entry point is 0xbfc00000, which
+ * normally is in the boot PROM, so the boot PROM must do a
+ * unconditional jump to this vector.
+ */
+NESTED(except_vec_nmi, 0, sp)
+ j nmi_handler
+ END(except_vec_nmi)
+
+ __FINIT
+
+NESTED(nmi_handler, PT_SIZE, sp)
+ .set push
+ .set noat
+ SAVE_ALL
+ move a0, sp
+ jal nmi_exception_handler
+ RESTORE_ALL
+ .set mips3
+ eret
+ .set pop
+ END(nmi_handler)
+
+ .macro __build_clear_none
+ .endm
+
+ .macro __build_clear_sti
+ TRACE_IRQS_ON
+ STI
+ .endm
+
+ .macro __build_clear_cli
+ CLI
+ TRACE_IRQS_OFF
+ .endm
+
+ .macro __build_clear_fpe
+ .set push
+ /* gas fails to assemble cfc1 for some archs (octeon).*/ \
+ .set mips1
+ cfc1 a1, fcr31
+ li a2, ~(0x3f << 12)
+ and a2, a1
+ ctc1 a2, fcr31
+ .set pop
+ TRACE_IRQS_ON
+ STI
+ .endm
+
+ .macro __build_clear_ade
+ MFC0 t0, CP0_BADVADDR
+ PTR_S t0, PT_BVADDR(sp)
+ KMODE
+ .endm
+
+ .macro __BUILD_silent exception
+ .endm
+
+ /* Gas tries to parse the PRINT argument as a string containing
+ string escapes and emits bogus warnings if it believes to
+ recognize an unknown escape code. So make the arguments
+ start with an n and gas will believe \n is ok ... */
+ .macro __BUILD_verbose nexception
+ LONG_L a1, PT_EPC(sp)
+#ifdef CONFIG_32BIT
+ PRINT("Got \nexception at %08lx\012")
+#endif
+#ifdef CONFIG_64BIT
+ PRINT("Got \nexception at %016lx\012")
+#endif
+ .endm
+
+ .macro __BUILD_count exception
+ LONG_L t0,exception_count_\exception
+ LONG_ADDIU t0, 1
+ LONG_S t0,exception_count_\exception
+ .comm exception_count\exception, 8, 8
+ .endm
+
+ .macro __BUILD_HANDLER exception handler clear verbose ext
+ .align 5
+ NESTED(handle_\exception, PT_SIZE, sp)
+ .set noat
+ SAVE_ALL
+ FEXPORT(handle_\exception\ext)
+ __BUILD_clear_\clear
+ .set at
+ __BUILD_\verbose \exception
+ move a0, sp
+ PTR_LA ra, ret_from_exception
+ j do_\handler
+ END(handle_\exception)
+ .endm
+
+ .macro BUILD_HANDLER exception handler clear verbose
+ __BUILD_HANDLER \exception \handler \clear \verbose _int
+ .endm
+
+ BUILD_HANDLER adel ade ade silent /* #4 */
+ BUILD_HANDLER ades ade ade silent /* #5 */
+ BUILD_HANDLER ibe be cli silent /* #6 */
+ BUILD_HANDLER dbe be cli silent /* #7 */
+ BUILD_HANDLER bp bp sti silent /* #9 */
+ BUILD_HANDLER ri ri sti silent /* #10 */
+ BUILD_HANDLER cpu cpu sti silent /* #11 */
+ BUILD_HANDLER ov ov sti silent /* #12 */
+ BUILD_HANDLER tr tr sti silent /* #13 */
+ BUILD_HANDLER fpe fpe fpe silent /* #15 */
+ BUILD_HANDLER mdmx mdmx sti silent /* #22 */
+#ifdef CONFIG_HARDWARE_WATCHPOINTS
+ /*
+ * For watch, interrupts will be enabled after the watch
+ * registers are read.
+ */
+ BUILD_HANDLER watch watch cli silent /* #23 */
+#else
+ BUILD_HANDLER watch watch sti verbose /* #23 */
+#endif
+ BUILD_HANDLER mcheck mcheck cli verbose /* #24 */
+ BUILD_HANDLER mt mt sti silent /* #25 */
+ BUILD_HANDLER dsp dsp sti silent /* #26 */
+ BUILD_HANDLER reserved reserved sti verbose /* others */
+
+ .align 5
+ LEAF(handle_ri_rdhwr_vivt)
+#ifdef CONFIG_MIPS_MT_SMTC
+ PANIC_PIC("handle_ri_rdhwr_vivt called")
+#else
+ .set push
+ .set noat
+ .set noreorder
+ /* check if TLB contains a entry for EPC */
+ MFC0 k1, CP0_ENTRYHI
+ andi k1, 0xff /* ASID_MASK */
+ MFC0 k0, CP0_EPC
+ PTR_SRL k0, PAGE_SHIFT + 1
+ PTR_SLL k0, PAGE_SHIFT + 1
+ or k1, k0
+ MTC0 k1, CP0_ENTRYHI
+ mtc0_tlbw_hazard
+ tlbp
+ tlb_probe_hazard
+ mfc0 k1, CP0_INDEX
+ .set pop
+ bltz k1, handle_ri /* slow path */
+ /* fall thru */
+#endif
+ END(handle_ri_rdhwr_vivt)
+
+ LEAF(handle_ri_rdhwr)
+ .set push
+ .set noat
+ .set noreorder
+ /* 0x7c03e83b: rdhwr v1,$29 */
+ MFC0 k1, CP0_EPC
+ lui k0, 0x7c03
+ lw k1, (k1)
+ ori k0, 0xe83b
+ .set reorder
+ bne k0, k1, handle_ri /* if not ours */
+ /* The insn is rdhwr. No need to check CAUSE.BD here. */
+ get_saved_sp /* k1 := current_thread_info */
+ .set noreorder
+ MFC0 k0, CP0_EPC
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+ ori k1, _THREAD_MASK
+ xori k1, _THREAD_MASK
+ LONG_L v1, TI_TP_VALUE(k1)
+ LONG_ADDIU k0, 4
+ jr k0
+ rfe
+#else
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+ LONG_ADDIU k0, 4 /* stall on $k0 */
+#else
+ .set at=v1
+ LONG_ADDIU k0, 4
+ .set noat
+#endif
+ MTC0 k0, CP0_EPC
+ /* I hope three instructions between MTC0 and ERET are enough... */
+ ori k1, _THREAD_MASK
+ xori k1, _THREAD_MASK
+ LONG_L v1, TI_TP_VALUE(k1)
+ .set mips3
+ eret
+ .set mips0
+#endif
+ .set pop
+ END(handle_ri_rdhwr)
+
+#ifdef CONFIG_64BIT
+/* A temporary overflow handler used by check_daddi(). */
+
+ __INIT
+
+ BUILD_HANDLER daddi_ov daddi_ov none silent /* #12 */
+#endif
diff --git a/arch/mips/kernel/gpio_txx9.c b/arch/mips/kernel/gpio_txx9.c
new file mode 100644
index 00000000..c6854d9d
--- /dev/null
+++ b/arch/mips/kernel/gpio_txx9.c
@@ -0,0 +1,89 @@
+/*
+ * A gpio chip driver for TXx9 SoCs
+ *
+ * Copyright (C) 2008 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/gpio.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <asm/txx9pio.h>
+
+static DEFINE_SPINLOCK(txx9_gpio_lock);
+
+static struct txx9_pio_reg __iomem *txx9_pioptr;
+
+static int txx9_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ return __raw_readl(&txx9_pioptr->din) & (1 << offset);
+}
+
+static void txx9_gpio_set_raw(unsigned int offset, int value)
+{
+ u32 val;
+ val = __raw_readl(&txx9_pioptr->dout);
+ if (value)
+ val |= 1 << offset;
+ else
+ val &= ~(1 << offset);
+ __raw_writel(val, &txx9_pioptr->dout);
+}
+
+static void txx9_gpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&txx9_gpio_lock, flags);
+ txx9_gpio_set_raw(offset, value);
+ mmiowb();
+ spin_unlock_irqrestore(&txx9_gpio_lock, flags);
+}
+
+static int txx9_gpio_dir_in(struct gpio_chip *chip, unsigned int offset)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&txx9_gpio_lock, flags);
+ __raw_writel(__raw_readl(&txx9_pioptr->dir) & ~(1 << offset),
+ &txx9_pioptr->dir);
+ mmiowb();
+ spin_unlock_irqrestore(&txx9_gpio_lock, flags);
+ return 0;
+}
+
+static int txx9_gpio_dir_out(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&txx9_gpio_lock, flags);
+ txx9_gpio_set_raw(offset, value);
+ __raw_writel(__raw_readl(&txx9_pioptr->dir) | (1 << offset),
+ &txx9_pioptr->dir);
+ mmiowb();
+ spin_unlock_irqrestore(&txx9_gpio_lock, flags);
+ return 0;
+}
+
+static struct gpio_chip txx9_gpio_chip = {
+ .get = txx9_gpio_get,
+ .set = txx9_gpio_set,
+ .direction_input = txx9_gpio_dir_in,
+ .direction_output = txx9_gpio_dir_out,
+ .label = "TXx9",
+};
+
+int __init txx9_gpio_init(unsigned long baseaddr,
+ unsigned int base, unsigned int num)
+{
+ txx9_pioptr = ioremap(baseaddr, sizeof(struct txx9_pio_reg));
+ if (!txx9_pioptr)
+ return -ENODEV;
+ txx9_gpio_chip.base = base;
+ txx9_gpio_chip.ngpio = num;
+ return gpiochip_add(&txx9_gpio_chip);
+}
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
new file mode 100644
index 00000000..ea695d96
--- /dev/null
+++ b/arch/mips/kernel/head.S
@@ -0,0 +1,232 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995 Waldorf Electronics
+ * Written by Ralf Baechle and Andreas Busse
+ * Copyright (C) 1994 - 99, 2003, 06 Ralf Baechle
+ * Copyright (C) 1996 Paul M. Antoine
+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
+ * Further modifications by David S. Miller and Harald Koerfgen
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/threads.h>
+
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/irqflags.h>
+#include <asm/regdef.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+#include <kernel-entry-init.h>
+
+ /*
+ * inputs are the text nasid in t1, data nasid in t2.
+ */
+ .macro MAPPED_KERNEL_SETUP_TLB
+#ifdef CONFIG_MAPPED_KERNEL
+ /*
+ * This needs to read the nasid - assume 0 for now.
+ * Drop in 0xffffffffc0000000 in tlbhi, 0+VG in tlblo_0,
+ * 0+DVG in tlblo_1.
+ */
+ dli t0, 0xffffffffc0000000
+ dmtc0 t0, CP0_ENTRYHI
+ li t0, 0x1c000 # Offset of text into node memory
+ dsll t1, NASID_SHFT # Shift text nasid into place
+ dsll t2, NASID_SHFT # Same for data nasid
+ or t1, t1, t0 # Physical load address of kernel text
+ or t2, t2, t0 # Physical load address of kernel data
+ dsrl t1, 12 # 4K pfn
+ dsrl t2, 12 # 4K pfn
+ dsll t1, 6 # Get pfn into place
+ dsll t2, 6 # Get pfn into place
+ li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _CACHE_CACHABLE_COW) >> 6)
+ or t0, t0, t1
+ mtc0 t0, CP0_ENTRYLO0 # physaddr, VG, cach exlwr
+ li t0, ((_PAGE_GLOBAL|_PAGE_VALID| _PAGE_DIRTY|_CACHE_CACHABLE_COW) >> 6)
+ or t0, t0, t2
+ mtc0 t0, CP0_ENTRYLO1 # physaddr, DVG, cach exlwr
+ li t0, 0x1ffe000 # MAPPED_KERN_TLBMASK, TLBPGMASK_16M
+ mtc0 t0, CP0_PAGEMASK
+ li t0, 0 # KMAP_INX
+ mtc0 t0, CP0_INDEX
+ li t0, 1
+ mtc0 t0, CP0_WIRED
+ tlbwi
+#else
+ mtc0 zero, CP0_WIRED
+#endif
+ .endm
+
+ /*
+ * For the moment disable interrupts, mark the kernel mode and
+ * set ST0_KX so that the CPU does not spit fire when using
+ * 64-bit addresses. A full initialization of the CPU's status
+ * register is done later in per_cpu_trap_init().
+ */
+ .macro setup_c0_status set clr
+ .set push
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * For SMTC, we need to set privilege and disable interrupts only for
+ * the current TC, using the TCStatus register.
+ */
+ mfc0 t0, CP0_TCSTATUS
+ /* Fortunately CU 0 is in the same place in both registers */
+ /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
+ li t1, ST0_CU0 | 0x08001c00
+ or t0, t1
+ /* Clear TKSU, leave IXMT */
+ xori t0, 0x00001800
+ mtc0 t0, CP0_TCSTATUS
+ _ehb
+ /* We need to leave the global IE bit set, but clear EXL...*/
+ mfc0 t0, CP0_STATUS
+ or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr
+ xor t0, ST0_EXL | ST0_ERL | \clr
+ mtc0 t0, CP0_STATUS
+#else
+ mfc0 t0, CP0_STATUS
+ or t0, ST0_CU0|\set|0x1f|\clr
+ xor t0, 0x1f|\clr
+ mtc0 t0, CP0_STATUS
+ .set noreorder
+ sll zero,3 # ehb
+#endif
+ .set pop
+ .endm
+
+ .macro setup_c0_status_pri
+#ifdef CONFIG_64BIT
+ setup_c0_status ST0_KX 0
+#else
+ setup_c0_status 0 0
+#endif
+ .endm
+
+ .macro setup_c0_status_sec
+#ifdef CONFIG_64BIT
+ setup_c0_status ST0_KX ST0_BEV
+#else
+ setup_c0_status 0 ST0_BEV
+#endif
+ .endm
+
+#ifndef CONFIG_NO_EXCEPT_FILL
+ /*
+ * Reserved space for exception handlers.
+ * Necessary for machines which link their kernels at KSEG0.
+ */
+ .fill 0x400
+#endif
+
+EXPORT(_stext)
+
+#ifdef CONFIG_BOOT_RAW
+ /*
+ * Give us a fighting chance of running if execution beings at the
+ * kernel load address. This is needed because this platform does
+ * not have a ELF loader yet.
+ */
+FEXPORT(__kernel_entry)
+ j kernel_entry
+#endif
+
+ __REF
+
+NESTED(kernel_entry, 16, sp) # kernel entry point
+
+ kernel_entry_setup # cpu specific setup
+
+ setup_c0_status_pri
+
+ /* We might not get launched at the address the kernel is linked to,
+ so we jump there. */
+ PTR_LA t0, 0f
+ jr t0
+0:
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * In SMTC kernel, "CLI" is thread-specific, in TCStatus.
+ * We still need to enable interrupts globally in Status,
+ * and clear EXL/ERL.
+ *
+ * TCContext is used to track interrupt levels under
+ * service in SMTC kernel. Clear for boot TC before
+ * allowing any interrupts.
+ */
+ mtc0 zero, CP0_TCCONTEXT
+
+ mfc0 t0, CP0_STATUS
+ ori t0, t0, 0xff1f
+ xori t0, t0, 0x001e
+ mtc0 t0, CP0_STATUS
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ PTR_LA t0, __bss_start # clear .bss
+ LONG_S zero, (t0)
+ PTR_LA t1, __bss_stop - LONGSIZE
+1:
+ PTR_ADDIU t0, LONGSIZE
+ LONG_S zero, (t0)
+ bne t0, t1, 1b
+
+ LONG_S a0, fw_arg0 # firmware arguments
+ LONG_S a1, fw_arg1
+ LONG_S a2, fw_arg2
+ LONG_S a3, fw_arg3
+
+ MTC0 zero, CP0_CONTEXT # clear context register
+ PTR_LA $28, init_thread_union
+ /* Set the SP after an empty pt_regs. */
+ PTR_LI sp, _THREAD_SIZE - 32 - PT_SIZE
+ PTR_ADDU sp, $28
+ back_to_back_c0_hazard
+ set_saved_sp sp, t0, t1
+ PTR_SUBU sp, 4 * SZREG # init stack pointer
+
+ j start_kernel
+ END(kernel_entry)
+
+ __CPUINIT
+
+#ifdef CONFIG_SMP
+/*
+ * SMP slave cpus entry point. Board specific code for bootstrap calls this
+ * function after setting up the stack and gp registers.
+ */
+NESTED(smp_bootstrap, 16, sp)
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * Read-modify-writes of Status must be atomic, and this
+ * is one case where CLI is invoked without EXL being
+ * necessarily set. The CLI and setup_c0_status will
+ * in fact be redundant for all but the first TC of
+ * each VPE being booted.
+ */
+ DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */
+ jal mips_ihb
+#endif /* CONFIG_MIPS_MT_SMTC */
+ setup_c0_status_sec
+ smp_slave_setup
+#ifdef CONFIG_MIPS_MT_SMTC
+ andi t2, t2, VPECONTROL_TE
+ beqz t2, 2f
+ EMT # emt
+2:
+#endif /* CONFIG_MIPS_MT_SMTC */
+ j start_secondary
+ END(smp_bootstrap)
+#endif /* CONFIG_SMP */
+
+ __FINIT
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
new file mode 100644
index 00000000..391221b6
--- /dev/null
+++ b/arch/mips/kernel/i8253.c
@@ -0,0 +1,135 @@
+/*
+ * i8253.c 8253/PIT functions
+ *
+ */
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+
+#include <asm/delay.h>
+#include <asm/i8253.h>
+#include <asm/io.h>
+#include <asm/time.h>
+
+DEFINE_RAW_SPINLOCK(i8253_lock);
+EXPORT_SYMBOL(i8253_lock);
+
+/*
+ * Initialize the PIT timer.
+ *
+ * This is also called after resume to bring the PIT into operation again.
+ */
+static void init_pit_timer(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ raw_spin_lock(&i8253_lock);
+
+ switch(mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* binary, mode 2, LSB/MSB, ch 0 */
+ outb_p(0x34, PIT_MODE);
+ outb_p(LATCH & 0xff , PIT_CH0); /* LSB */
+ outb(LATCH >> 8 , PIT_CH0); /* MSB */
+ break;
+
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
+ evt->mode == CLOCK_EVT_MODE_ONESHOT) {
+ outb_p(0x30, PIT_MODE);
+ outb_p(0, PIT_CH0);
+ outb_p(0, PIT_CH0);
+ }
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* One shot setup */
+ outb_p(0x38, PIT_MODE);
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ /* Nothing to do here */
+ break;
+ }
+ raw_spin_unlock(&i8253_lock);
+}
+
+/*
+ * Program the next event in oneshot mode
+ *
+ * Delta is given in PIT ticks
+ */
+static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
+{
+ raw_spin_lock(&i8253_lock);
+ outb_p(delta & 0xff , PIT_CH0); /* LSB */
+ outb(delta >> 8 , PIT_CH0); /* MSB */
+ raw_spin_unlock(&i8253_lock);
+
+ return 0;
+}
+
+/*
+ * On UP the PIT can serve all of the possible timer functions. On SMP systems
+ * it can be solely used for the global tick.
+ *
+ * The profiling and update capabilites are switched off once the local apic is
+ * registered. This mechanism replaces the previous #ifdef LOCAL_APIC -
+ * !using_apic_timer decisions in do_timer_interrupt_hook()
+ */
+static struct clock_event_device pit_clockevent = {
+ .name = "pit",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = init_pit_timer,
+ .set_next_event = pit_next_event,
+ .irq = 0,
+};
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ pit_clockevent.event_handler(&pit_clockevent);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq0 = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
+ .name = "timer"
+};
+
+/*
+ * Initialize the conversion factor and the min/max deltas of the clock event
+ * structure and register the clock event source with the framework.
+ */
+void __init setup_pit_timer(void)
+{
+ struct clock_event_device *cd = &pit_clockevent;
+ unsigned int cpu = smp_processor_id();
+
+ /*
+ * Start pit with the boot cpu mask and make it global after the
+ * IO_APIC has been initialized.
+ */
+ cd->cpumask = cpumask_of(cpu);
+ clockevent_set_clock(cd, CLOCK_TICK_RATE);
+ cd->max_delta_ns = clockevent_delta2ns(0x7FFF, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0xF, cd);
+ clockevents_register_device(cd);
+
+ setup_irq(0, &irq0);
+}
+
+static int __init init_pit_clocksource(void)
+{
+ if (num_possible_cpus() > 1) /* PIT does not scale! */
+ return 0;
+
+ return clocksource_i8253_init();
+}
+arch_initcall(init_pit_clocksource);
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
new file mode 100644
index 00000000..5c74eb79
--- /dev/null
+++ b/arch/mips/kernel/i8259.c
@@ -0,0 +1,334 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/syscore_ops.h>
+#include <linux/irq.h>
+
+#include <asm/i8259.h>
+#include <asm/io.h>
+
+/*
+ * This is the 'legacy' 8259A Programmable Interrupt Controller,
+ * present in the majority of PC/AT boxes.
+ * plus some generic x86 specific things if generic specifics makes
+ * any sense at all.
+ * this file should become arch/i386/kernel/irq.c when the old irq.c
+ * moves to arch independent land
+ */
+
+static int i8259A_auto_eoi = -1;
+DEFINE_RAW_SPINLOCK(i8259A_lock);
+static void disable_8259A_irq(struct irq_data *d);
+static void enable_8259A_irq(struct irq_data *d);
+static void mask_and_ack_8259A(struct irq_data *d);
+static void init_8259A(int auto_eoi);
+
+static struct irq_chip i8259A_chip = {
+ .name = "XT-PIC",
+ .irq_mask = disable_8259A_irq,
+ .irq_disable = disable_8259A_irq,
+ .irq_unmask = enable_8259A_irq,
+ .irq_mask_ack = mask_and_ack_8259A,
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+ .irq_set_affinity = plat_set_irq_affinity,
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
+};
+
+/*
+ * 8259A PIC functions to handle ISA devices:
+ */
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static unsigned int cached_irq_mask = 0xffff;
+
+#define cached_master_mask (cached_irq_mask)
+#define cached_slave_mask (cached_irq_mask >> 8)
+
+static void disable_8259A_irq(struct irq_data *d)
+{
+ unsigned int mask, irq = d->irq - I8259A_IRQ_BASE;
+ unsigned long flags;
+
+ mask = 1 << irq;
+ raw_spin_lock_irqsave(&i8259A_lock, flags);
+ cached_irq_mask |= mask;
+ if (irq & 8)
+ outb(cached_slave_mask, PIC_SLAVE_IMR);
+ else
+ outb(cached_master_mask, PIC_MASTER_IMR);
+ raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+static void enable_8259A_irq(struct irq_data *d)
+{
+ unsigned int mask, irq = d->irq - I8259A_IRQ_BASE;
+ unsigned long flags;
+
+ mask = ~(1 << irq);
+ raw_spin_lock_irqsave(&i8259A_lock, flags);
+ cached_irq_mask &= mask;
+ if (irq & 8)
+ outb(cached_slave_mask, PIC_SLAVE_IMR);
+ else
+ outb(cached_master_mask, PIC_MASTER_IMR);
+ raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+int i8259A_irq_pending(unsigned int irq)
+{
+ unsigned int mask;
+ unsigned long flags;
+ int ret;
+
+ irq -= I8259A_IRQ_BASE;
+ mask = 1 << irq;
+ raw_spin_lock_irqsave(&i8259A_lock, flags);
+ if (irq < 8)
+ ret = inb(PIC_MASTER_CMD) & mask;
+ else
+ ret = inb(PIC_SLAVE_CMD) & (mask >> 8);
+ raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+
+ return ret;
+}
+
+void make_8259A_irq(unsigned int irq)
+{
+ disable_irq_nosync(irq);
+ irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
+ enable_irq(irq);
+}
+
+/*
+ * This function assumes to be called rarely. Switching between
+ * 8259A registers is slow.
+ * This has to be protected by the irq controller spinlock
+ * before being called.
+ */
+static inline int i8259A_irq_real(unsigned int irq)
+{
+ int value;
+ int irqmask = 1 << irq;
+
+ if (irq < 8) {
+ outb(0x0B, PIC_MASTER_CMD); /* ISR register */
+ value = inb(PIC_MASTER_CMD) & irqmask;
+ outb(0x0A, PIC_MASTER_CMD); /* back to the IRR register */
+ return value;
+ }
+ outb(0x0B, PIC_SLAVE_CMD); /* ISR register */
+ value = inb(PIC_SLAVE_CMD) & (irqmask >> 8);
+ outb(0x0A, PIC_SLAVE_CMD); /* back to the IRR register */
+ return value;
+}
+
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+static void mask_and_ack_8259A(struct irq_data *d)
+{
+ unsigned int irqmask, irq = d->irq - I8259A_IRQ_BASE;
+ unsigned long flags;
+
+ irqmask = 1 << irq;
+ raw_spin_lock_irqsave(&i8259A_lock, flags);
+ /*
+ * Lightweight spurious IRQ detection. We do not want
+ * to overdo spurious IRQ handling - it's usually a sign
+ * of hardware problems, so we only do the checks we can
+ * do without slowing down good hardware unnecessarily.
+ *
+ * Note that IRQ7 and IRQ15 (the two spurious IRQs
+ * usually resulting from the 8259A-1|2 PICs) occur
+ * even if the IRQ is masked in the 8259A. Thus we
+ * can check spurious 8259A IRQs without doing the
+ * quite slow i8259A_irq_real() call for every IRQ.
+ * This does not cover 100% of spurious interrupts,
+ * but should be enough to warn the user that there
+ * is something bad going on ...
+ */
+ if (cached_irq_mask & irqmask)
+ goto spurious_8259A_irq;
+ cached_irq_mask |= irqmask;
+
+handle_real_irq:
+ if (irq & 8) {
+ inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */
+ outb(cached_slave_mask, PIC_SLAVE_IMR);
+ outb(0x60+(irq&7), PIC_SLAVE_CMD);/* 'Specific EOI' to slave */
+ outb(0x60+PIC_CASCADE_IR, PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */
+ } else {
+ inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */
+ outb(cached_master_mask, PIC_MASTER_IMR);
+ outb(0x60+irq, PIC_MASTER_CMD); /* 'Specific EOI to master */
+ }
+ smtc_im_ack_irq(irq);
+ raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+ return;
+
+spurious_8259A_irq:
+ /*
+ * this is the slow path - should happen rarely.
+ */
+ if (i8259A_irq_real(irq))
+ /*
+ * oops, the IRQ _is_ in service according to the
+ * 8259A - not spurious, go handle it.
+ */
+ goto handle_real_irq;
+
+ {
+ static int spurious_irq_mask;
+ /*
+ * At this point we can be sure the IRQ is spurious,
+ * lets ACK and report it. [once per IRQ]
+ */
+ if (!(spurious_irq_mask & irqmask)) {
+ printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq);
+ spurious_irq_mask |= irqmask;
+ }
+ atomic_inc(&irq_err_count);
+ /*
+ * Theoretically we do not have to handle this IRQ,
+ * but in Linux this does not cause problems and is
+ * simpler for us.
+ */
+ goto handle_real_irq;
+ }
+}
+
+static void i8259A_resume(void)
+{
+ if (i8259A_auto_eoi >= 0)
+ init_8259A(i8259A_auto_eoi);
+}
+
+static void i8259A_shutdown(void)
+{
+ /* Put the i8259A into a quiescent state that
+ * the kernel initialization code can get it
+ * out of.
+ */
+ if (i8259A_auto_eoi >= 0) {
+ outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
+ outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */
+ }
+}
+
+static struct syscore_ops i8259_syscore_ops = {
+ .resume = i8259A_resume,
+ .shutdown = i8259A_shutdown,
+};
+
+static int __init i8259A_init_sysfs(void)
+{
+ register_syscore_ops(&i8259_syscore_ops);
+ return 0;
+}
+
+device_initcall(i8259A_init_sysfs);
+
+static void init_8259A(int auto_eoi)
+{
+ unsigned long flags;
+
+ i8259A_auto_eoi = auto_eoi;
+
+ raw_spin_lock_irqsave(&i8259A_lock, flags);
+
+ outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
+ outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
+
+ /*
+ * outb_p - this has to work on a wide range of PC hardware.
+ */
+ outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */
+ outb_p(I8259A_IRQ_BASE + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0 mapped to I8259A_IRQ_BASE + 0x00 */
+ outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */
+ if (auto_eoi) /* master does Auto EOI */
+ outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR);
+ else /* master expects normal EOI */
+ outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR);
+
+ outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */
+ outb_p(I8259A_IRQ_BASE + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0 mapped to I8259A_IRQ_BASE + 0x08 */
+ outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */
+ outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */
+ if (auto_eoi)
+ /*
+ * In AEOI mode we just have to mask the interrupt
+ * when acking.
+ */
+ i8259A_chip.irq_mask_ack = disable_8259A_irq;
+ else
+ i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
+
+ udelay(100); /* wait for 8259A to initialize */
+
+ outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */
+ outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */
+
+ raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction irq2 = {
+ .handler = no_action,
+ .name = "cascade",
+};
+
+static struct resource pic1_io_resource = {
+ .name = "pic1",
+ .start = PIC_MASTER_CMD,
+ .end = PIC_MASTER_IMR,
+ .flags = IORESOURCE_BUSY
+};
+
+static struct resource pic2_io_resource = {
+ .name = "pic2",
+ .start = PIC_SLAVE_CMD,
+ .end = PIC_SLAVE_IMR,
+ .flags = IORESOURCE_BUSY
+};
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8259
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init init_i8259_irqs(void)
+{
+ int i;
+
+ insert_resource(&ioport_resource, &pic1_io_resource);
+ insert_resource(&ioport_resource, &pic2_io_resource);
+
+ init_8259A(0);
+
+ for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) {
+ irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq);
+ irq_set_probe(i);
+ }
+
+ setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);
+}
diff --git a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c
new file mode 100644
index 00000000..6d6ca530
--- /dev/null
+++ b/arch/mips/kernel/init_task.c
@@ -0,0 +1,35 @@
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init_task.h>
+#include <linux/fs.h>
+#include <linux/mqueue.h>
+
+#include <asm/thread_info.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by making sure
+ * the linker maps this in the .text segment right after head.S,
+ * and making head.S ensure the proper alignment.
+ *
+ * The things we do for performance..
+ */
+union thread_union init_thread_union __init_task_data
+ __attribute__((__aligned__(THREAD_SIZE))) =
+ { INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
new file mode 100644
index 00000000..0c527f65
--- /dev/null
+++ b/arch/mips/kernel/irq-gic.c
@@ -0,0 +1,258 @@
+#undef DEBUG
+
+#include <linux/bitmap.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/gic.h>
+#include <asm/gcmpregs.h>
+#include <linux/hardirq.h>
+#include <asm-generic/bitops/find.h>
+
+
+static unsigned long _gic_base;
+static unsigned int _irqbase;
+static unsigned int gic_irq_flags[GIC_NUM_INTRS];
+#define GIC_IRQ_FLAG_EDGE 0x0001
+
+struct gic_pcpu_mask pcpu_masks[NR_CPUS];
+static struct gic_pending_regs pending_regs[NR_CPUS];
+static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
+
+void gic_send_ipi(unsigned int intr)
+{
+ pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__,
+ read_c0_status());
+ GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
+}
+
+/* This is Malta specific and needs to be exported */
+static void __init vpe_local_setup(unsigned int numvpes)
+{
+ int i;
+ unsigned long timer_interrupt = 5, perf_interrupt = 5;
+ unsigned int vpe_ctl;
+
+ /*
+ * Setup the default performance counter timer interrupts
+ * for all VPEs
+ */
+ for (i = 0; i < numvpes; i++) {
+ GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
+
+ /* Are Interrupts locally routable? */
+ GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl);
+ if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK)
+ GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
+ GIC_MAP_TO_PIN_MSK | timer_interrupt);
+
+ if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK)
+ GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
+ GIC_MAP_TO_PIN_MSK | perf_interrupt);
+ }
+}
+
+unsigned int gic_get_int(void)
+{
+ unsigned int i;
+ unsigned long *pending, *intrmask, *pcpu_mask;
+ unsigned long *pending_abs, *intrmask_abs;
+
+ /* Get per-cpu bitmaps */
+ pending = pending_regs[smp_processor_id()].pending;
+ intrmask = intrmask_regs[smp_processor_id()].intrmask;
+ pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
+
+ pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
+ GIC_SH_PEND_31_0_OFS);
+ intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
+ GIC_SH_MASK_31_0_OFS);
+
+ for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) {
+ GICREAD(*pending_abs, pending[i]);
+ GICREAD(*intrmask_abs, intrmask[i]);
+ pending_abs++;
+ intrmask_abs++;
+ }
+
+ bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS);
+ bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS);
+
+ i = find_first_bit(pending, GIC_NUM_INTRS);
+
+ pr_debug("CPU%d: %s pend=%d\n", smp_processor_id(), __func__, i);
+
+ return i;
+}
+
+static void gic_irq_ack(struct irq_data *d)
+{
+ unsigned int irq = d->irq - _irqbase;
+
+ pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
+ GIC_CLR_INTR_MASK(irq);
+
+ if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE)
+ GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
+}
+
+static void gic_mask_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq - _irqbase;
+ pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
+ GIC_CLR_INTR_MASK(irq);
+}
+
+static void gic_unmask_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq - _irqbase;
+ pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
+ GIC_SET_INTR_MASK(irq);
+}
+
+#ifdef CONFIG_SMP
+
+static DEFINE_SPINLOCK(gic_lock);
+
+static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
+ bool force)
+{
+ unsigned int irq = d->irq - _irqbase;
+ cpumask_t tmp = CPU_MASK_NONE;
+ unsigned long flags;
+ int i;
+
+ pr_debug("%s(%d) called\n", __func__, irq);
+ cpumask_and(&tmp, cpumask, cpu_online_mask);
+ if (cpus_empty(tmp))
+ return -1;
+
+ /* Assumption : cpumask refers to a single CPU */
+ spin_lock_irqsave(&gic_lock, flags);
+ for (;;) {
+ /* Re-route this IRQ */
+ GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
+
+ /* Update the pcpu_masks */
+ for (i = 0; i < NR_CPUS; i++)
+ clear_bit(irq, pcpu_masks[i].pcpu_mask);
+ set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
+
+ }
+ cpumask_copy(d->affinity, cpumask);
+ spin_unlock_irqrestore(&gic_lock, flags);
+
+ return IRQ_SET_MASK_OK_NOCOPY;
+}
+#endif
+
+static struct irq_chip gic_irq_controller = {
+ .name = "MIPS GIC",
+ .irq_ack = gic_irq_ack,
+ .irq_mask = gic_mask_irq,
+ .irq_mask_ack = gic_mask_irq,
+ .irq_unmask = gic_unmask_irq,
+ .irq_eoi = gic_unmask_irq,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = gic_set_affinity,
+#endif
+};
+
+static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
+ unsigned int pin, unsigned int polarity, unsigned int trigtype,
+ unsigned int flags)
+{
+ /* Setup Intr to Pin mapping */
+ if (pin & GIC_MAP_TO_NMI_MSK) {
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
+ /* FIXME: hack to route NMI to all cpu's */
+ for (cpu = 0; cpu < NR_CPUS; cpu += 32) {
+ GICWRITE(GIC_REG_ADDR(SHARED,
+ GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)),
+ 0xffffffff);
+ }
+ } else {
+ GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
+ GIC_MAP_TO_PIN_MSK | pin);
+ /* Setup Intr to CPU mapping */
+ GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
+ }
+
+ /* Setup Intr Polarity */
+ GIC_SET_POLARITY(intr, polarity);
+
+ /* Setup Intr Trigger Type */
+ GIC_SET_TRIGGER(intr, trigtype);
+
+ /* Init Intr Masks */
+ GIC_CLR_INTR_MASK(intr);
+ /* Initialise per-cpu Interrupt software masks */
+ if (flags & GIC_FLAG_IPI)
+ set_bit(intr, pcpu_masks[cpu].pcpu_mask);
+ if (flags & GIC_FLAG_TRANSPARENT)
+ GIC_SET_INTR_MASK(intr);
+ if (trigtype == GIC_TRIG_EDGE)
+ gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE;
+}
+
+static void __init gic_basic_init(int numintrs, int numvpes,
+ struct gic_intr_map *intrmap, int mapsize)
+{
+ unsigned int i, cpu;
+
+ /* Setup defaults */
+ for (i = 0; i < numintrs; i++) {
+ GIC_SET_POLARITY(i, GIC_POL_POS);
+ GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
+ GIC_CLR_INTR_MASK(i);
+ if (i < GIC_NUM_INTRS)
+ gic_irq_flags[i] = 0;
+ }
+
+ /* Setup specifics */
+ for (i = 0; i < mapsize; i++) {
+ cpu = intrmap[i].cpunum;
+ if (cpu == GIC_UNUSED)
+ continue;
+ if (cpu == 0 && i != 0 && intrmap[i].flags == 0)
+ continue;
+ gic_setup_intr(i,
+ intrmap[i].cpunum,
+ intrmap[i].pin,
+ intrmap[i].polarity,
+ intrmap[i].trigtype,
+ intrmap[i].flags);
+ }
+
+ vpe_local_setup(numvpes);
+
+ for (i = _irqbase; i < (_irqbase + numintrs); i++)
+ irq_set_chip(i, &gic_irq_controller);
+}
+
+void __init gic_init(unsigned long gic_base_addr,
+ unsigned long gic_addrspace_size,
+ struct gic_intr_map *intr_map, unsigned int intr_map_size,
+ unsigned int irqbase)
+{
+ unsigned int gicconfig;
+ int numvpes, numintrs;
+
+ _gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
+ gic_addrspace_size);
+ _irqbase = irqbase;
+
+ GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
+ numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
+ GIC_SH_CONFIG_NUMINTRS_SHF;
+ numintrs = ((numintrs + 1) * 8);
+
+ numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
+ GIC_SH_CONFIG_NUMVPES_SHF;
+
+ pr_debug("%s called\n", __func__);
+
+ gic_basic_init(numintrs, numvpes, intr_map, intr_map_size);
+}
diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c
new file mode 100644
index 00000000..883fc6ce
--- /dev/null
+++ b/arch/mips/kernel/irq-gt641xx.c
@@ -0,0 +1,131 @@
+/*
+ * GT641xx IRQ routines.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/hardirq.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/gt64120.h>
+
+#define GT641XX_IRQ_TO_BIT(irq) (1U << (irq - GT641XX_IRQ_BASE))
+
+static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock);
+
+static void ack_gt641xx_irq(struct irq_data *d)
+{
+ unsigned long flags;
+ u32 cause;
+
+ raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
+ cause = GT_READ(GT_INTRCAUSE_OFS);
+ cause &= ~GT641XX_IRQ_TO_BIT(d->irq);
+ GT_WRITE(GT_INTRCAUSE_OFS, cause);
+ raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
+}
+
+static void mask_gt641xx_irq(struct irq_data *d)
+{
+ unsigned long flags;
+ u32 mask;
+
+ raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
+ mask = GT_READ(GT_INTRMASK_OFS);
+ mask &= ~GT641XX_IRQ_TO_BIT(d->irq);
+ GT_WRITE(GT_INTRMASK_OFS, mask);
+ raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
+}
+
+static void mask_ack_gt641xx_irq(struct irq_data *d)
+{
+ unsigned long flags;
+ u32 cause, mask;
+
+ raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
+ mask = GT_READ(GT_INTRMASK_OFS);
+ mask &= ~GT641XX_IRQ_TO_BIT(d->irq);
+ GT_WRITE(GT_INTRMASK_OFS, mask);
+
+ cause = GT_READ(GT_INTRCAUSE_OFS);
+ cause &= ~GT641XX_IRQ_TO_BIT(d->irq);
+ GT_WRITE(GT_INTRCAUSE_OFS, cause);
+ raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
+}
+
+static void unmask_gt641xx_irq(struct irq_data *d)
+{
+ unsigned long flags;
+ u32 mask;
+
+ raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
+ mask = GT_READ(GT_INTRMASK_OFS);
+ mask |= GT641XX_IRQ_TO_BIT(d->irq);
+ GT_WRITE(GT_INTRMASK_OFS, mask);
+ raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
+}
+
+static struct irq_chip gt641xx_irq_chip = {
+ .name = "GT641xx",
+ .irq_ack = ack_gt641xx_irq,
+ .irq_mask = mask_gt641xx_irq,
+ .irq_mask_ack = mask_ack_gt641xx_irq,
+ .irq_unmask = unmask_gt641xx_irq,
+};
+
+void gt641xx_irq_dispatch(void)
+{
+ u32 cause, mask;
+ int i;
+
+ cause = GT_READ(GT_INTRCAUSE_OFS);
+ mask = GT_READ(GT_INTRMASK_OFS);
+ cause &= mask;
+
+ /*
+ * bit0 : logical or of all the interrupt bits.
+ * bit30: logical or of bits[29:26,20:1].
+ * bit31: logical or of bits[25:1].
+ */
+ for (i = 1; i < 30; i++) {
+ if (cause & (1U << i)) {
+ do_IRQ(GT641XX_IRQ_BASE + i);
+ return;
+ }
+ }
+
+ atomic_inc(&irq_err_count);
+}
+
+void __init gt641xx_irq_init(void)
+{
+ int i;
+
+ GT_WRITE(GT_INTRMASK_OFS, 0);
+ GT_WRITE(GT_INTRCAUSE_OFS, 0);
+
+ /*
+ * bit0 : logical or of all the interrupt bits.
+ * bit30: logical or of bits[29:26,20:1].
+ * bit31: logical or of bits[25:1].
+ */
+ for (i = 1; i < 30; i++)
+ irq_set_chip_and_handler(GT641XX_IRQ_BASE + i,
+ &gt641xx_irq_chip, handle_level_irq);
+}
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
new file mode 100644
index 00000000..0c6afeed
--- /dev/null
+++ b/arch/mips/kernel/irq-msc01.c
@@ -0,0 +1,165 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Copyright (c) 2004 MIPS Inc
+ * Author: chris@mips.com
+ *
+ * Copyright (C) 2004, 06 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/msc01_ic.h>
+#include <asm/traps.h>
+
+static unsigned long _icctrl_msc;
+#define MSC01_IC_REG_BASE _icctrl_msc
+
+#define MSCIC_WRITE(reg, data) do { *(volatile u32 *)(reg) = data; } while (0)
+#define MSCIC_READ(reg, data) do { data = *(volatile u32 *)(reg); } while (0)
+
+static unsigned int irq_base;
+
+/* mask off an interrupt */
+static inline void mask_msc_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ if (irq < (irq_base + 32))
+ MSCIC_WRITE(MSC01_IC_DISL, 1<<(irq - irq_base));
+ else
+ MSCIC_WRITE(MSC01_IC_DISH, 1<<(irq - irq_base - 32));
+}
+
+/* unmask an interrupt */
+static inline void unmask_msc_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ if (irq < (irq_base + 32))
+ MSCIC_WRITE(MSC01_IC_ENAL, 1<<(irq - irq_base));
+ else
+ MSCIC_WRITE(MSC01_IC_ENAH, 1<<(irq - irq_base - 32));
+}
+
+/*
+ * Masks and ACKs an IRQ
+ */
+static void level_mask_and_ack_msc_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ mask_msc_irq(d);
+ if (!cpu_has_veic)
+ MSCIC_WRITE(MSC01_IC_EOI, 0);
+ /* This actually needs to be a call into platform code */
+ smtc_im_ack_irq(irq);
+}
+
+/*
+ * Masks and ACKs an IRQ
+ */
+static void edge_mask_and_ack_msc_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ mask_msc_irq(d);
+ if (!cpu_has_veic)
+ MSCIC_WRITE(MSC01_IC_EOI, 0);
+ else {
+ u32 r;
+ MSCIC_READ(MSC01_IC_SUP+irq*8, r);
+ MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT);
+ MSCIC_WRITE(MSC01_IC_SUP+irq*8, r);
+ }
+ smtc_im_ack_irq(irq);
+}
+
+/*
+ * Interrupt handler for interrupts coming from SOC-it.
+ */
+void ll_msc_irq(void)
+{
+ unsigned int irq;
+
+ /* read the interrupt vector register */
+ MSCIC_READ(MSC01_IC_VEC, irq);
+ if (irq < 64)
+ do_IRQ(irq + irq_base);
+ else {
+ /* Ignore spurious interrupt */
+ }
+}
+
+static void msc_bind_eic_interrupt(int irq, int set)
+{
+ MSCIC_WRITE(MSC01_IC_RAMW,
+ (irq<<MSC01_IC_RAMW_ADDR_SHF) | (set<<MSC01_IC_RAMW_DATA_SHF));
+}
+
+static struct irq_chip msc_levelirq_type = {
+ .name = "SOC-it-Level",
+ .irq_ack = level_mask_and_ack_msc_irq,
+ .irq_mask = mask_msc_irq,
+ .irq_mask_ack = level_mask_and_ack_msc_irq,
+ .irq_unmask = unmask_msc_irq,
+ .irq_eoi = unmask_msc_irq,
+};
+
+static struct irq_chip msc_edgeirq_type = {
+ .name = "SOC-it-Edge",
+ .irq_ack = edge_mask_and_ack_msc_irq,
+ .irq_mask = mask_msc_irq,
+ .irq_mask_ack = edge_mask_and_ack_msc_irq,
+ .irq_unmask = unmask_msc_irq,
+ .irq_eoi = unmask_msc_irq,
+};
+
+
+void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqmap_t *imp, int nirq)
+{
+ _icctrl_msc = (unsigned long) ioremap(icubase, 0x40000);
+
+ /* Reset interrupt controller - initialises all registers to 0 */
+ MSCIC_WRITE(MSC01_IC_RST, MSC01_IC_RST_RST_BIT);
+
+ board_bind_eic_interrupt = &msc_bind_eic_interrupt;
+
+ for (; nirq >= 0; nirq--, imp++) {
+ int n = imp->im_irq;
+
+ switch (imp->im_type) {
+ case MSC01_IRQ_EDGE:
+ irq_set_chip_and_handler_name(irqbase + n,
+ &msc_edgeirq_type,
+ handle_edge_irq,
+ "edge");
+ if (cpu_has_veic)
+ MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
+ else
+ MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
+ break;
+ case MSC01_IRQ_LEVEL:
+ irq_set_chip_and_handler_name(irqbase + n,
+ &msc_levelirq_type,
+ handle_level_irq,
+ "level");
+ if (cpu_has_veic)
+ MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
+ else
+ MSCIC_WRITE(MSC01_IC_SUP+n*8, imp->im_lvl);
+ }
+ }
+
+ irq_base = irqbase;
+
+ MSCIC_WRITE(MSC01_IC_GENA, MSC01_IC_GENA_GENA_BIT); /* Enable interrupt generation */
+
+}
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
new file mode 100644
index 00000000..a8a8977d
--- /dev/null
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Handler for RM7000 extended interrupts. These are a non-standard
+ * feature so we handle them separately from standard interrupts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static inline void unmask_rm7k_irq(struct irq_data *d)
+{
+ set_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE));
+}
+
+static inline void mask_rm7k_irq(struct irq_data *d)
+{
+ clear_c0_intcontrol(0x100 << (d->irq - RM7K_CPU_IRQ_BASE));
+}
+
+static struct irq_chip rm7k_irq_controller = {
+ .name = "RM7000",
+ .irq_ack = mask_rm7k_irq,
+ .irq_mask = mask_rm7k_irq,
+ .irq_mask_ack = mask_rm7k_irq,
+ .irq_unmask = unmask_rm7k_irq,
+ .irq_eoi = unmask_rm7k_irq
+};
+
+void __init rm7k_cpu_irq_init(void)
+{
+ int base = RM7K_CPU_IRQ_BASE;
+ int i;
+
+ clear_c0_intcontrol(0x00000f00); /* Mask all */
+
+ for (i = base; i < base + 4; i++)
+ irq_set_chip_and_handler(i, &rm7k_irq_controller,
+ handle_percpu_irq);
+}
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
new file mode 100644
index 00000000..38874a4b
--- /dev/null
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Handler for RM9000 extended interrupts. These are a non-standard
+ * feature so we handle them separately from standard interrupts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static inline void unmask_rm9k_irq(struct irq_data *d)
+{
+ set_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE));
+}
+
+static inline void mask_rm9k_irq(struct irq_data *d)
+{
+ clear_c0_intcontrol(0x1000 << (d->irq - RM9K_CPU_IRQ_BASE));
+}
+
+static inline void rm9k_cpu_irq_enable(struct irq_data *d)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ unmask_rm9k_irq(d);
+ local_irq_restore(flags);
+}
+
+/*
+ * Performance counter interrupts are global on all processors.
+ */
+static void local_rm9k_perfcounter_irq_startup(void *args)
+{
+ rm9k_cpu_irq_enable(args);
+}
+
+static unsigned int rm9k_perfcounter_irq_startup(struct irq_data *d)
+{
+ on_each_cpu(local_rm9k_perfcounter_irq_startup, d, 1);
+
+ return 0;
+}
+
+static void local_rm9k_perfcounter_irq_shutdown(void *args)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ mask_rm9k_irq(args);
+ local_irq_restore(flags);
+}
+
+static void rm9k_perfcounter_irq_shutdown(struct irq_data *d)
+{
+ on_each_cpu(local_rm9k_perfcounter_irq_shutdown, d, 1);
+}
+
+static struct irq_chip rm9k_irq_controller = {
+ .name = "RM9000",
+ .irq_ack = mask_rm9k_irq,
+ .irq_mask = mask_rm9k_irq,
+ .irq_mask_ack = mask_rm9k_irq,
+ .irq_unmask = unmask_rm9k_irq,
+ .irq_eoi = unmask_rm9k_irq
+};
+
+static struct irq_chip rm9k_perfcounter_irq = {
+ .name = "RM9000",
+ .irq_startup = rm9k_perfcounter_irq_startup,
+ .irq_shutdown = rm9k_perfcounter_irq_shutdown,
+ .irq_ack = mask_rm9k_irq,
+ .irq_mask = mask_rm9k_irq,
+ .irq_mask_ack = mask_rm9k_irq,
+ .irq_unmask = unmask_rm9k_irq,
+};
+
+unsigned int rm9000_perfcount_irq;
+
+EXPORT_SYMBOL(rm9000_perfcount_irq);
+
+void __init rm9k_cpu_irq_init(void)
+{
+ int base = RM9K_CPU_IRQ_BASE;
+ int i;
+
+ clear_c0_intcontrol(0x0000f000); /* Mask all */
+
+ for (i = base; i < base + 4; i++)
+ irq_set_chip_and_handler(i, &rm9k_irq_controller,
+ handle_level_irq);
+
+ rm9000_perfcount_irq = base + 1;
+ irq_set_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq,
+ handle_percpu_irq);
+}
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
new file mode 100644
index 00000000..9b734d74
--- /dev/null
+++ b/arch/mips/kernel/irq.c
@@ -0,0 +1,166 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Code to handle x86 style IRQs plus some generic interrupt stuff.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/kallsyms.h>
+#include <linux/kgdb.h>
+#include <linux/ftrace.h>
+
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_KGDB
+int kgdb_early_setup;
+#endif
+
+static unsigned long irq_map[NR_IRQS / BITS_PER_LONG];
+
+int allocate_irqno(void)
+{
+ int irq;
+
+again:
+ irq = find_first_zero_bit(irq_map, NR_IRQS);
+
+ if (irq >= NR_IRQS)
+ return -ENOSPC;
+
+ if (test_and_set_bit(irq, irq_map))
+ goto again;
+
+ return irq;
+}
+
+/*
+ * Allocate the 16 legacy interrupts for i8259 devices. This happens early
+ * in the kernel initialization so treating allocation failure as BUG() is
+ * ok.
+ */
+void __init alloc_legacy_irqno(void)
+{
+ int i;
+
+ for (i = 0; i <= 16; i++)
+ BUG_ON(test_and_set_bit(i, irq_map));
+}
+
+void free_irqno(unsigned int irq)
+{
+ smp_mb__before_clear_bit();
+ clear_bit(irq, irq_map);
+ smp_mb__after_clear_bit();
+}
+
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+ smtc_im_ack_irq(irq);
+ printk("unexpected IRQ # %d\n", irq);
+}
+
+atomic_t irq_err_count;
+
+int arch_show_interrupts(struct seq_file *p, int prec)
+{
+ seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
+ return 0;
+}
+
+asmlinkage void spurious_interrupt(void)
+{
+ atomic_inc(&irq_err_count);
+}
+
+void __init init_IRQ(void)
+{
+ int i;
+
+#ifdef CONFIG_KGDB
+ if (kgdb_early_setup)
+ return;
+#endif
+
+ for (i = 0; i < NR_IRQS; i++)
+ irq_set_noprobe(i);
+
+ arch_init_irq();
+
+#ifdef CONFIG_KGDB
+ if (!kgdb_early_setup)
+ kgdb_early_setup = 1;
+#endif
+}
+
+#ifdef DEBUG_STACKOVERFLOW
+static inline void check_stack_overflow(void)
+{
+ unsigned long sp;
+
+ __asm__ __volatile__("move %0, $sp" : "=r" (sp));
+ sp &= THREAD_MASK;
+
+ /*
+ * Check for stack overflow: is there less than STACK_WARN free?
+ * STACK_WARN is defined as 1/8 of THREAD_SIZE by default.
+ */
+ if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
+ printk("do_IRQ: stack overflow: %ld\n",
+ sp - sizeof(struct thread_info));
+ dump_stack();
+ }
+}
+#else
+static inline void check_stack_overflow(void) {}
+#endif
+
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+void __irq_entry do_IRQ(unsigned int irq)
+{
+ irq_enter();
+ check_stack_overflow();
+ if (!smtc_handle_on_other_cpu(irq))
+ generic_handle_irq(irq);
+ irq_exit();
+}
+
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+/*
+ * To avoid inefficient and in some cases pathological re-checking of
+ * IRQ affinity, we have this variant that skips the affinity check.
+ */
+
+void __irq_entry do_IRQ_no_affinity(unsigned int irq)
+{
+ irq_enter();
+ smtc_im_backstop(irq);
+ generic_handle_irq(irq);
+ irq_exit();
+}
+
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
new file mode 100644
index 00000000..6e71b284
--- /dev/null
+++ b/arch/mips/kernel/irq_cpu.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright (C) 2001 Ralf Baechle
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ *
+ * This file define the irq handler for MIPS CPU interrupts.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/*
+ * Almost all MIPS CPUs define 8 interrupt sources. They are typically
+ * level triggered (i.e., cannot be cleared from CPU; must be cleared from
+ * device). The first two are software interrupts which we don't really
+ * use or support. The last one is usually the CPU timer interrupt if
+ * counter register is present or, for CPUs with an external FPU, by
+ * convention it's the FPU exception interrupt.
+ *
+ * Don't even think about using this on SMP. You have been warned.
+ *
+ * This file exports one global function:
+ * void mips_cpu_irq_init(void);
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/system.h>
+
+static inline void unmask_mips_irq(struct irq_data *d)
+{
+ set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
+ irq_enable_hazard();
+}
+
+static inline void mask_mips_irq(struct irq_data *d)
+{
+ clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
+ irq_disable_hazard();
+}
+
+static struct irq_chip mips_cpu_irq_controller = {
+ .name = "MIPS",
+ .irq_ack = mask_mips_irq,
+ .irq_mask = mask_mips_irq,
+ .irq_mask_ack = mask_mips_irq,
+ .irq_unmask = unmask_mips_irq,
+ .irq_eoi = unmask_mips_irq,
+};
+
+/*
+ * Basically the same as above but taking care of all the MT stuff
+ */
+
+static unsigned int mips_mt_cpu_irq_startup(struct irq_data *d)
+{
+ unsigned int vpflags = dvpe();
+
+ clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
+ evpe(vpflags);
+ unmask_mips_irq(d);
+ return 0;
+}
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues. Same for mips_cpu_irq_end.
+ */
+static void mips_mt_cpu_irq_ack(struct irq_data *d)
+{
+ unsigned int vpflags = dvpe();
+ clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
+ evpe(vpflags);
+ mask_mips_irq(d);
+}
+
+static struct irq_chip mips_mt_cpu_irq_controller = {
+ .name = "MIPS",
+ .irq_startup = mips_mt_cpu_irq_startup,
+ .irq_ack = mips_mt_cpu_irq_ack,
+ .irq_mask = mask_mips_irq,
+ .irq_mask_ack = mips_mt_cpu_irq_ack,
+ .irq_unmask = unmask_mips_irq,
+ .irq_eoi = unmask_mips_irq,
+};
+
+void __init mips_cpu_irq_init(void)
+{
+ int irq_base = MIPS_CPU_IRQ_BASE;
+ int i;
+
+ /* Mask interrupts. */
+ clear_c0_status(ST0_IM);
+ clear_c0_cause(CAUSEF_IP);
+
+ /*
+ * Only MT is using the software interrupts currently, so we just
+ * leave them uninitialized for other processors.
+ */
+ if (cpu_has_mipsmt)
+ for (i = irq_base; i < irq_base + 2; i++)
+ irq_set_chip_and_handler(i, &mips_mt_cpu_irq_controller,
+ handle_percpu_irq);
+
+ for (i = irq_base + 2; i < irq_base + 8; i++)
+ irq_set_chip_and_handler(i, &mips_cpu_irq_controller,
+ handle_percpu_irq);
+}
diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c
new file mode 100644
index 00000000..b0c55b50
--- /dev/null
+++ b/arch/mips/kernel/irq_txx9.c
@@ -0,0 +1,191 @@
+/*
+ * Based on linux/arch/mips/jmr3927/rbhma3100/irq.c,
+ * linux/arch/mips/tx4927/common/tx4927_irq.c,
+ * linux/arch/mips/tx4938/common/irq.c
+ *
+ * Copyright 2001, 2003-2005 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ahennessy@mvista.com
+ * source@mvista.com
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/irq.h>
+#include <asm/txx9irq.h>
+
+struct txx9_irc_reg {
+ u32 cer;
+ u32 cr[2];
+ u32 unused0;
+ u32 ilr[8];
+ u32 unused1[4];
+ u32 imr;
+ u32 unused2[7];
+ u32 scr;
+ u32 unused3[7];
+ u32 ssr;
+ u32 unused4[7];
+ u32 csr;
+};
+
+/* IRCER : Int. Control Enable */
+#define TXx9_IRCER_ICE 0x00000001
+
+/* IRCR : Int. Control */
+#define TXx9_IRCR_LOW 0x00000000
+#define TXx9_IRCR_HIGH 0x00000001
+#define TXx9_IRCR_DOWN 0x00000002
+#define TXx9_IRCR_UP 0x00000003
+#define TXx9_IRCR_EDGE(cr) ((cr) & 0x00000002)
+
+/* IRSCR : Int. Status Control */
+#define TXx9_IRSCR_EIClrE 0x00000100
+#define TXx9_IRSCR_EIClr_MASK 0x0000000f
+
+/* IRCSR : Int. Current Status */
+#define TXx9_IRCSR_IF 0x00010000
+#define TXx9_IRCSR_ILV_MASK 0x00000700
+#define TXx9_IRCSR_IVL_MASK 0x0000001f
+
+#define irc_dlevel 0
+#define irc_elevel 1
+
+static struct txx9_irc_reg __iomem *txx9_ircptr __read_mostly;
+
+static struct {
+ unsigned char level;
+ unsigned char mode;
+} txx9irq[TXx9_MAX_IR] __read_mostly;
+
+static void txx9_irq_unmask(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
+ u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2];
+ int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
+
+ __raw_writel((__raw_readl(ilrp) & ~(0xff << ofs))
+ | (txx9irq[irq_nr].level << ofs),
+ ilrp);
+#ifdef CONFIG_CPU_TX39XX
+ /* update IRCSR */
+ __raw_writel(0, &txx9_ircptr->imr);
+ __raw_writel(irc_elevel, &txx9_ircptr->imr);
+#endif
+}
+
+static inline void txx9_irq_mask(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
+ u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2];
+ int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
+
+ __raw_writel((__raw_readl(ilrp) & ~(0xff << ofs))
+ | (irc_dlevel << ofs),
+ ilrp);
+#ifdef CONFIG_CPU_TX39XX
+ /* update IRCSR */
+ __raw_writel(0, &txx9_ircptr->imr);
+ __raw_writel(irc_elevel, &txx9_ircptr->imr);
+ /* flush write buffer */
+ __raw_readl(&txx9_ircptr->ssr);
+#else
+ mmiowb();
+#endif
+}
+
+static void txx9_irq_mask_ack(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
+
+ txx9_irq_mask(d);
+ /* clear edge detection */
+ if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode)))
+ __raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr);
+}
+
+static int txx9_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
+ u32 cr;
+ u32 __iomem *crp;
+ int ofs;
+ int mode;
+
+ if (flow_type & IRQF_TRIGGER_PROBE)
+ return 0;
+ switch (flow_type & IRQF_TRIGGER_MASK) {
+ case IRQF_TRIGGER_RISING: mode = TXx9_IRCR_UP; break;
+ case IRQF_TRIGGER_FALLING: mode = TXx9_IRCR_DOWN; break;
+ case IRQF_TRIGGER_HIGH: mode = TXx9_IRCR_HIGH; break;
+ case IRQF_TRIGGER_LOW: mode = TXx9_IRCR_LOW; break;
+ default:
+ return -EINVAL;
+ }
+ crp = &txx9_ircptr->cr[(unsigned int)irq_nr / 8];
+ cr = __raw_readl(crp);
+ ofs = (irq_nr & (8 - 1)) * 2;
+ cr &= ~(0x3 << ofs);
+ cr |= (mode & 0x3) << ofs;
+ __raw_writel(cr, crp);
+ txx9irq[irq_nr].mode = mode;
+ return 0;
+}
+
+static struct irq_chip txx9_irq_chip = {
+ .name = "TXX9",
+ .irq_ack = txx9_irq_mask_ack,
+ .irq_mask = txx9_irq_mask,
+ .irq_mask_ack = txx9_irq_mask_ack,
+ .irq_unmask = txx9_irq_unmask,
+ .irq_set_type = txx9_irq_set_type,
+};
+
+void __init txx9_irq_init(unsigned long baseaddr)
+{
+ int i;
+
+ txx9_ircptr = ioremap(baseaddr, sizeof(struct txx9_irc_reg));
+ for (i = 0; i < TXx9_MAX_IR; i++) {
+ txx9irq[i].level = 4; /* middle level */
+ txx9irq[i].mode = TXx9_IRCR_LOW;
+ irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &txx9_irq_chip,
+ handle_level_irq);
+ }
+
+ /* mask all IRC interrupts */
+ __raw_writel(0, &txx9_ircptr->imr);
+ for (i = 0; i < 8; i++)
+ __raw_writel(0, &txx9_ircptr->ilr[i]);
+ /* setup IRC interrupt mode (Low Active) */
+ for (i = 0; i < 2; i++)
+ __raw_writel(0, &txx9_ircptr->cr[i]);
+ /* enable interrupt control */
+ __raw_writel(TXx9_IRCER_ICE, &txx9_ircptr->cer);
+ __raw_writel(irc_elevel, &txx9_ircptr->imr);
+}
+
+int __init txx9_irq_set_pri(int irc_irq, int new_pri)
+{
+ int old_pri;
+
+ if ((unsigned int)irc_irq >= TXx9_MAX_IR)
+ return 0;
+ old_pri = txx9irq[irc_irq].level;
+ txx9irq[irc_irq].level = new_pri;
+ return old_pri;
+}
+
+int txx9_irq(void)
+{
+ u32 csr = __raw_readl(&txx9_ircptr->csr);
+
+ if (likely(!(csr & TXx9_IRCSR_IF)))
+ return TXX9_IRQ_BASE + (csr & (TXx9_MAX_IR - 1));
+ return -1;
+}
diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c
new file mode 100644
index 00000000..6001610c
--- /dev/null
+++ b/arch/mips/kernel/jump_label.c
@@ -0,0 +1,54 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2010 Cavium Networks, Inc.
+ */
+
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/cpu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/inst.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+#define J_RANGE_MASK ((1ul << 28) - 1)
+
+void arch_jump_label_transform(struct jump_entry *e,
+ enum jump_label_type type)
+{
+ union mips_instruction insn;
+ union mips_instruction *insn_p =
+ (union mips_instruction *)(unsigned long)e->code;
+
+ /* Jump only works within a 256MB aligned region. */
+ BUG_ON((e->target & ~J_RANGE_MASK) != (e->code & ~J_RANGE_MASK));
+
+ /* Target must have 4 byte alignment. */
+ BUG_ON((e->target & 3) != 0);
+
+ if (type == JUMP_LABEL_ENABLE) {
+ insn.j_format.opcode = j_op;
+ insn.j_format.target = (e->target & J_RANGE_MASK) >> 2;
+ } else {
+ insn.word = 0; /* nop */
+ }
+
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+ *insn_p = insn;
+
+ flush_icache_range((unsigned long)insn_p,
+ (unsigned long)insn_p + sizeof(*insn_p));
+
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+}
+
+#endif /* HAVE_JUMP_LABEL */
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c
new file mode 100644
index 00000000..f4546e97
--- /dev/null
+++ b/arch/mips/kernel/kgdb.c
@@ -0,0 +1,384 @@
+/*
+ * Originally written by Glenn Engel, Lake Stevens Instrument Division
+ *
+ * Contributed by HP Systems
+ *
+ * Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
+ * Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
+ *
+ * Copyright (C) 1995 Andreas Busse
+ *
+ * Copyright (C) 2003 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright (C) 2004-2005 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com or manish@koffee-break.com
+ *
+ * Copyright (C) 2007-2008 Wind River Systems, Inc.
+ * Author/Maintainer: Jason Wessel, jason.wessel@windriver.com
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/ptrace.h> /* for linux pt_regs struct */
+#include <linux/kgdb.h>
+#include <linux/kdebug.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <asm/inst.h>
+#include <asm/fpu.h>
+#include <asm/cacheflush.h>
+#include <asm/processor.h>
+#include <asm/sigcontext.h>
+
+static struct hard_trap_info {
+ unsigned char tt; /* Trap type code for MIPS R3xxx and R4xxx */
+ unsigned char signo; /* Signal that we map this trap into */
+} hard_trap_info[] = {
+ { 6, SIGBUS }, /* instruction bus error */
+ { 7, SIGBUS }, /* data bus error */
+ { 9, SIGTRAP }, /* break */
+/* { 11, SIGILL }, */ /* CPU unusable */
+ { 12, SIGFPE }, /* overflow */
+ { 13, SIGTRAP }, /* trap */
+ { 14, SIGSEGV }, /* virtual instruction cache coherency */
+ { 15, SIGFPE }, /* floating point exception */
+ { 23, SIGSEGV }, /* watch */
+ { 31, SIGSEGV }, /* virtual data cache coherency */
+ { 0, 0} /* Must be last */
+};
+
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
+{
+ { "zero", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[0]) },
+ { "at", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[1]) },
+ { "v0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[2]) },
+ { "v1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[3]) },
+ { "a0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[4]) },
+ { "a1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[5]) },
+ { "a2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[6]) },
+ { "a3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[7]) },
+ { "t0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[8]) },
+ { "t1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[9]) },
+ { "t2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[10]) },
+ { "t3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[11]) },
+ { "t4", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[12]) },
+ { "t5", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[13]) },
+ { "t6", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[14]) },
+ { "t7", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[15]) },
+ { "s0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[16]) },
+ { "s1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[17]) },
+ { "s2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[18]) },
+ { "s3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[19]) },
+ { "s4", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[20]) },
+ { "s5", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[21]) },
+ { "s6", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[22]) },
+ { "s7", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[23]) },
+ { "t8", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[24]) },
+ { "t9", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[25]) },
+ { "k0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[26]) },
+ { "k1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[27]) },
+ { "gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[28]) },
+ { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[29]) },
+ { "s8", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[30]) },
+ { "ra", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[31]) },
+ { "sr", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_status) },
+ { "lo", GDB_SIZEOF_REG, offsetof(struct pt_regs, lo) },
+ { "hi", GDB_SIZEOF_REG, offsetof(struct pt_regs, hi) },
+ { "bad", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_badvaddr) },
+ { "cause", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_cause) },
+ { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, cp0_epc) },
+ { "f0", GDB_SIZEOF_REG, 0 },
+ { "f1", GDB_SIZEOF_REG, 1 },
+ { "f2", GDB_SIZEOF_REG, 2 },
+ { "f3", GDB_SIZEOF_REG, 3 },
+ { "f4", GDB_SIZEOF_REG, 4 },
+ { "f5", GDB_SIZEOF_REG, 5 },
+ { "f6", GDB_SIZEOF_REG, 6 },
+ { "f7", GDB_SIZEOF_REG, 7 },
+ { "f8", GDB_SIZEOF_REG, 8 },
+ { "f9", GDB_SIZEOF_REG, 9 },
+ { "f10", GDB_SIZEOF_REG, 10 },
+ { "f11", GDB_SIZEOF_REG, 11 },
+ { "f12", GDB_SIZEOF_REG, 12 },
+ { "f13", GDB_SIZEOF_REG, 13 },
+ { "f14", GDB_SIZEOF_REG, 14 },
+ { "f15", GDB_SIZEOF_REG, 15 },
+ { "f16", GDB_SIZEOF_REG, 16 },
+ { "f17", GDB_SIZEOF_REG, 17 },
+ { "f18", GDB_SIZEOF_REG, 18 },
+ { "f19", GDB_SIZEOF_REG, 19 },
+ { "f20", GDB_SIZEOF_REG, 20 },
+ { "f21", GDB_SIZEOF_REG, 21 },
+ { "f22", GDB_SIZEOF_REG, 22 },
+ { "f23", GDB_SIZEOF_REG, 23 },
+ { "f24", GDB_SIZEOF_REG, 24 },
+ { "f25", GDB_SIZEOF_REG, 25 },
+ { "f26", GDB_SIZEOF_REG, 26 },
+ { "f27", GDB_SIZEOF_REG, 27 },
+ { "f28", GDB_SIZEOF_REG, 28 },
+ { "f29", GDB_SIZEOF_REG, 29 },
+ { "f30", GDB_SIZEOF_REG, 30 },
+ { "f31", GDB_SIZEOF_REG, 31 },
+ { "fsr", GDB_SIZEOF_REG, 0 },
+ { "fir", GDB_SIZEOF_REG, 0 },
+};
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ int fp_reg;
+
+ if (regno < 0 || regno >= DBG_MAX_REG_NUM)
+ return -EINVAL;
+
+ if (dbg_reg_def[regno].offset != -1 && regno < 38) {
+ memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+ dbg_reg_def[regno].size);
+ } else if (current && dbg_reg_def[regno].offset != -1 && regno < 72) {
+ /* FP registers 38 -> 69 */
+ if (!(regs->cp0_status & ST0_CU1))
+ return 0;
+ if (regno == 70) {
+ /* Process the fcr31/fsr (register 70) */
+ memcpy((void *)&current->thread.fpu.fcr31, mem,
+ dbg_reg_def[regno].size);
+ goto out_save;
+ } else if (regno == 71) {
+ /* Ignore the fir (register 71) */
+ goto out_save;
+ }
+ fp_reg = dbg_reg_def[regno].offset;
+ memcpy((void *)&current->thread.fpu.fpr[fp_reg], mem,
+ dbg_reg_def[regno].size);
+out_save:
+ restore_fp(current);
+ }
+
+ return 0;
+}
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ int fp_reg;
+
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return NULL;
+
+ if (dbg_reg_def[regno].offset != -1 && regno < 38) {
+ /* First 38 registers */
+ memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+ dbg_reg_def[regno].size);
+ } else if (current && dbg_reg_def[regno].offset != -1 && regno < 72) {
+ /* FP registers 38 -> 69 */
+ if (!(regs->cp0_status & ST0_CU1))
+ goto out;
+ save_fp(current);
+ if (regno == 70) {
+ /* Process the fcr31/fsr (register 70) */
+ memcpy(mem, (void *)&current->thread.fpu.fcr31,
+ dbg_reg_def[regno].size);
+ goto out;
+ } else if (regno == 71) {
+ /* Ignore the fir (register 71) */
+ memset(mem, 0, dbg_reg_def[regno].size);
+ goto out;
+ }
+ fp_reg = dbg_reg_def[regno].offset;
+ memcpy(mem, (void *)&current->thread.fpu.fpr[fp_reg],
+ dbg_reg_def[regno].size);
+ }
+
+out:
+ return dbg_reg_def[regno].name;
+
+}
+
+void arch_kgdb_breakpoint(void)
+{
+ __asm__ __volatile__(
+ ".globl breakinst\n\t"
+ ".set\tnoreorder\n\t"
+ "nop\n"
+ "breakinst:\tbreak\n\t"
+ "nop\n\t"
+ ".set\treorder");
+}
+
+static void kgdb_call_nmi_hook(void *ignored)
+{
+ kgdb_nmicallback(raw_smp_processor_id(), NULL);
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+ local_irq_enable();
+ smp_call_function(kgdb_call_nmi_hook, NULL, 0);
+ local_irq_disable();
+}
+
+static int compute_signal(int tt)
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ if (ht->tt == tt)
+ return ht->signo;
+
+ return SIGHUP; /* default for things we don't know about */
+}
+
+/*
+ * Similar to regs_to_gdb_regs() except that process is sleeping and so
+ * we may not be able to get all the info.
+ */
+void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+{
+ int reg;
+ struct thread_info *ti = task_thread_info(p);
+ unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;
+ struct pt_regs *regs = (struct pt_regs *)ksp - 1;
+#if (KGDB_GDB_REG_SIZE == 32)
+ u32 *ptr = (u32 *)gdb_regs;
+#else
+ u64 *ptr = (u64 *)gdb_regs;
+#endif
+
+ for (reg = 0; reg < 16; reg++)
+ *(ptr++) = regs->regs[reg];
+
+ /* S0 - S7 */
+ for (reg = 16; reg < 24; reg++)
+ *(ptr++) = regs->regs[reg];
+
+ for (reg = 24; reg < 28; reg++)
+ *(ptr++) = 0;
+
+ /* GP, SP, FP, RA */
+ for (reg = 28; reg < 32; reg++)
+ *(ptr++) = regs->regs[reg];
+
+ *(ptr++) = regs->cp0_status;
+ *(ptr++) = regs->lo;
+ *(ptr++) = regs->hi;
+ *(ptr++) = regs->cp0_badvaddr;
+ *(ptr++) = regs->cp0_cause;
+ *(ptr++) = regs->cp0_epc;
+}
+
+void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+{
+ regs->cp0_epc = pc;
+}
+
+/*
+ * Calls linux_debug_hook before the kernel dies. If KGDB is enabled,
+ * then try to fall into the debugger
+ */
+static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
+ void *ptr)
+{
+ struct die_args *args = (struct die_args *)ptr;
+ struct pt_regs *regs = args->regs;
+ int trap = (regs->cp0_cause & 0x7c) >> 2;
+
+ /* Userspace events, ignore. */
+ if (user_mode(regs))
+ return NOTIFY_DONE;
+
+ if (atomic_read(&kgdb_active) != -1)
+ kgdb_nmicallback(smp_processor_id(), regs);
+
+ if (kgdb_handle_exception(trap, compute_signal(trap), cmd, regs))
+ return NOTIFY_DONE;
+
+ if (atomic_read(&kgdb_setting_breakpoint))
+ if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst))
+ regs->cp0_epc += 4;
+
+ /* In SMP mode, __flush_cache_all does IPI */
+ local_irq_enable();
+ __flush_cache_all();
+
+ return NOTIFY_STOP;
+}
+
+#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
+int kgdb_ll_trap(int cmd, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig)
+{
+ struct die_args args = {
+ .regs = regs,
+ .str = str,
+ .err = err,
+ .trapnr = trap,
+ .signr = sig,
+
+ };
+
+ if (!kgdb_io_module_registered)
+ return NOTIFY_DONE;
+
+ return kgdb_mips_notify(NULL, cmd, &args);
+}
+#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
+
+static struct notifier_block kgdb_notifier = {
+ .notifier_call = kgdb_mips_notify,
+};
+
+/*
+ * Handle the 'c' command
+ */
+int kgdb_arch_handle_exception(int vector, int signo, int err_code,
+ char *remcom_in_buffer, char *remcom_out_buffer,
+ struct pt_regs *regs)
+{
+ char *ptr;
+ unsigned long address;
+
+ switch (remcom_in_buffer[0]) {
+ case 'c':
+ /* handle the optional parameter */
+ ptr = &remcom_in_buffer[1];
+ if (kgdb_hex2long(&ptr, &address))
+ regs->cp0_epc = address;
+
+ return 0;
+ }
+
+ return -1;
+}
+
+struct kgdb_arch arch_kgdb_ops;
+
+/*
+ * We use kgdb_early_setup so that functions we need to call now don't
+ * cause trouble when called again later.
+ */
+int kgdb_arch_init(void)
+{
+ union mips_instruction insn = {
+ .r_format = {
+ .opcode = spec_op,
+ .func = break_op,
+ }
+ };
+ memcpy(arch_kgdb_ops.gdb_bpt_instr, insn.byte, BREAK_INSTR_SIZE);
+
+ register_die_notifier(&kgdb_notifier);
+
+ return 0;
+}
+
+/*
+ * kgdb_arch_exit - Perform any architecture specific uninitalization.
+ *
+ * This function will handle the uninitalization of any architecture
+ * specific callbacks, for dynamic registration and unregistration.
+ */
+void kgdb_arch_exit(void)
+{
+ unregister_die_notifier(&kgdb_notifier);
+}
diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c
new file mode 100644
index 00000000..ee28683f
--- /dev/null
+++ b/arch/mips/kernel/kprobes.c
@@ -0,0 +1,557 @@
+/*
+ * Kernel Probes (KProbes)
+ * arch/mips/kernel/kprobes.c
+ *
+ * Copyright 2006 Sony Corp.
+ * Copyright 2010 Cavium Networks
+ *
+ * Some portions copied from the powerpc version.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kprobes.h>
+#include <linux/preempt.h>
+#include <linux/kdebug.h>
+#include <linux/slab.h>
+
+#include <asm/ptrace.h>
+#include <asm/break.h>
+#include <asm/inst.h>
+
+static const union mips_instruction breakpoint_insn = {
+ .b_format = {
+ .opcode = spec_op,
+ .code = BRK_KPROBE_BP,
+ .func = break_op
+ }
+};
+
+static const union mips_instruction breakpoint2_insn = {
+ .b_format = {
+ .opcode = spec_op,
+ .code = BRK_KPROBE_SSTEPBP,
+ .func = break_op
+ }
+};
+
+DEFINE_PER_CPU(struct kprobe *, current_kprobe);
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
+static int __kprobes insn_has_delayslot(union mips_instruction insn)
+{
+ switch (insn.i_format.opcode) {
+
+ /*
+ * This group contains:
+ * jr and jalr are in r_format format.
+ */
+ case spec_op:
+ switch (insn.r_format.func) {
+ case jr_op:
+ case jalr_op:
+ break;
+ default:
+ goto insn_ok;
+ }
+
+ /*
+ * This group contains:
+ * bltz_op, bgez_op, bltzl_op, bgezl_op,
+ * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
+ */
+ case bcond_op:
+
+ /*
+ * These are unconditional and in j_format.
+ */
+ case jal_op:
+ case j_op:
+
+ /*
+ * These are conditional and in i_format.
+ */
+ case beq_op:
+ case beql_op:
+ case bne_op:
+ case bnel_op:
+ case blez_op:
+ case blezl_op:
+ case bgtz_op:
+ case bgtzl_op:
+
+ /*
+ * These are the FPA/cp1 branch instructions.
+ */
+ case cop1_op:
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ case lwc2_op: /* This is bbit0 on Octeon */
+ case ldc2_op: /* This is bbit032 on Octeon */
+ case swc2_op: /* This is bbit1 on Octeon */
+ case sdc2_op: /* This is bbit132 on Octeon */
+#endif
+ return 1;
+ default:
+ break;
+ }
+insn_ok:
+ return 0;
+}
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+ union mips_instruction insn;
+ union mips_instruction prev_insn;
+ int ret = 0;
+
+ prev_insn = p->addr[-1];
+ insn = p->addr[0];
+
+ if (insn_has_delayslot(insn) || insn_has_delayslot(prev_insn)) {
+ pr_notice("Kprobes for branch and jump instructions are not supported\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* insn: must be on special executable page on mips. */
+ p->ainsn.insn = get_insn_slot();
+ if (!p->ainsn.insn) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * In the kprobe->ainsn.insn[] array we store the original
+ * instruction at index zero and a break trap instruction at
+ * index one.
+ */
+
+ memcpy(&p->ainsn.insn[0], p->addr, sizeof(kprobe_opcode_t));
+ p->ainsn.insn[1] = breakpoint2_insn;
+ p->opcode = *p->addr;
+
+out:
+ return ret;
+}
+
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+ *p->addr = breakpoint_insn;
+ flush_insn_slot(p);
+}
+
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+ *p->addr = p->opcode;
+ flush_insn_slot(p);
+}
+
+void __kprobes arch_remove_kprobe(struct kprobe *p)
+{
+ free_insn_slot(p->ainsn.insn, 0);
+}
+
+static void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+ kcb->prev_kprobe.old_SR = kcb->kprobe_old_SR;
+ kcb->prev_kprobe.saved_SR = kcb->kprobe_saved_SR;
+ kcb->prev_kprobe.saved_epc = kcb->kprobe_saved_epc;
+}
+
+static void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+ kcb->kprobe_old_SR = kcb->prev_kprobe.old_SR;
+ kcb->kprobe_saved_SR = kcb->prev_kprobe.saved_SR;
+ kcb->kprobe_saved_epc = kcb->prev_kprobe.saved_epc;
+}
+
+static void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
+{
+ __get_cpu_var(current_kprobe) = p;
+ kcb->kprobe_saved_SR = kcb->kprobe_old_SR = (regs->cp0_status & ST0_IE);
+ kcb->kprobe_saved_epc = regs->cp0_epc;
+}
+
+static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+{
+ regs->cp0_status &= ~ST0_IE;
+
+ /* single step inline if the instruction is a break */
+ if (p->opcode.word == breakpoint_insn.word ||
+ p->opcode.word == breakpoint2_insn.word)
+ regs->cp0_epc = (unsigned long)p->addr;
+ else
+ regs->cp0_epc = (unsigned long)&p->ainsn.insn[0];
+}
+
+static int __kprobes kprobe_handler(struct pt_regs *regs)
+{
+ struct kprobe *p;
+ int ret = 0;
+ kprobe_opcode_t *addr;
+ struct kprobe_ctlblk *kcb;
+
+ addr = (kprobe_opcode_t *) regs->cp0_epc;
+
+ /*
+ * We don't want to be preempted for the entire
+ * duration of kprobe processing
+ */
+ preempt_disable();
+ kcb = get_kprobe_ctlblk();
+
+ /* Check we're not actually recursing */
+ if (kprobe_running()) {
+ p = get_kprobe(addr);
+ if (p) {
+ if (kcb->kprobe_status == KPROBE_HIT_SS &&
+ p->ainsn.insn->word == breakpoint_insn.word) {
+ regs->cp0_status &= ~ST0_IE;
+ regs->cp0_status |= kcb->kprobe_saved_SR;
+ goto no_kprobe;
+ }
+ /*
+ * We have reentered the kprobe_handler(), since
+ * another probe was hit while within the handler.
+ * We here save the original kprobes variables and
+ * just single step on the instruction of the new probe
+ * without calling any user handlers.
+ */
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, regs, kcb);
+ kprobes_inc_nmissed_count(p);
+ prepare_singlestep(p, regs);
+ kcb->kprobe_status = KPROBE_REENTER;
+ return 1;
+ } else {
+ if (addr->word != breakpoint_insn.word) {
+ /*
+ * The breakpoint instruction was removed by
+ * another cpu right after we hit, no further
+ * handling of this interrupt is appropriate
+ */
+ ret = 1;
+ goto no_kprobe;
+ }
+ p = __get_cpu_var(current_kprobe);
+ if (p->break_handler && p->break_handler(p, regs))
+ goto ss_probe;
+ }
+ goto no_kprobe;
+ }
+
+ p = get_kprobe(addr);
+ if (!p) {
+ if (addr->word != breakpoint_insn.word) {
+ /*
+ * The breakpoint instruction was removed right
+ * after we hit it. Another cpu has removed
+ * either a probepoint or a debugger breakpoint
+ * at this address. In either case, no further
+ * handling of this interrupt is appropriate.
+ */
+ ret = 1;
+ }
+ /* Not one of ours: let kernel handle it */
+ goto no_kprobe;
+ }
+
+ set_current_kprobe(p, regs, kcb);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+ if (p->pre_handler && p->pre_handler(p, regs)) {
+ /* handler has already set things up, so skip ss setup */
+ return 1;
+ }
+
+ss_probe:
+ prepare_singlestep(p, regs);
+ kcb->kprobe_status = KPROBE_HIT_SS;
+ return 1;
+
+no_kprobe:
+ preempt_enable_no_resched();
+ return ret;
+
+}
+
+/*
+ * Called after single-stepping. p->addr is the address of the
+ * instruction whose first byte has been replaced by the "break 0"
+ * instruction. To avoid the SMP problems that can occur when we
+ * temporarily put back the original opcode to single-step, we
+ * single-stepped a copy of the instruction. The address of this
+ * copy is p->ainsn.insn.
+ *
+ * This function prepares to return from the post-single-step
+ * breakpoint trap.
+ */
+static void __kprobes resume_execution(struct kprobe *p,
+ struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
+{
+ unsigned long orig_epc = kcb->kprobe_saved_epc;
+ regs->cp0_epc = orig_epc + 4;
+}
+
+static inline int post_kprobe_handler(struct pt_regs *regs)
+{
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (!cur)
+ return 0;
+
+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
+ }
+
+ resume_execution(cur, regs, kcb);
+
+ regs->cp0_status |= kcb->kprobe_saved_SR;
+
+ /* Restore back the original saved kprobes variables and continue. */
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
+ goto out;
+ }
+ reset_current_kprobe();
+out:
+ preempt_enable_no_resched();
+
+ return 1;
+}
+
+static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+{
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+ return 1;
+
+ if (kcb->kprobe_status & KPROBE_HIT_SS) {
+ resume_execution(cur, regs, kcb);
+ regs->cp0_status |= kcb->kprobe_old_SR;
+
+ reset_current_kprobe();
+ preempt_enable_no_resched();
+ }
+ return 0;
+}
+
+/*
+ * Wrapper routine for handling exceptions.
+ */
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+
+ struct die_args *args = (struct die_args *)data;
+ int ret = NOTIFY_DONE;
+
+ switch (val) {
+ case DIE_BREAK:
+ if (kprobe_handler(args->regs))
+ ret = NOTIFY_STOP;
+ break;
+ case DIE_SSTEPBP:
+ if (post_kprobe_handler(args->regs))
+ ret = NOTIFY_STOP;
+ break;
+
+ case DIE_PAGE_FAULT:
+ /* kprobe_running() needs smp_processor_id() */
+ preempt_disable();
+
+ if (kprobe_running()
+ && kprobe_fault_handler(args->regs, args->trapnr))
+ ret = NOTIFY_STOP;
+ preempt_enable();
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct jprobe *jp = container_of(p, struct jprobe, kp);
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ kcb->jprobe_saved_regs = *regs;
+ kcb->jprobe_saved_sp = regs->regs[29];
+
+ memcpy(kcb->jprobes_stack, (void *)kcb->jprobe_saved_sp,
+ MIN_JPROBES_STACK_SIZE(kcb->jprobe_saved_sp));
+
+ regs->cp0_epc = (unsigned long)(jp->entry);
+
+ return 1;
+}
+
+/* Defined in the inline asm below. */
+void jprobe_return_end(void);
+
+void __kprobes jprobe_return(void)
+{
+ /* Assembler quirk necessitates this '0,code' business. */
+ asm volatile(
+ "break 0,%0\n\t"
+ ".globl jprobe_return_end\n"
+ "jprobe_return_end:\n"
+ : : "n" (BRK_KPROBE_BP) : "memory");
+}
+
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ if (regs->cp0_epc >= (unsigned long)jprobe_return &&
+ regs->cp0_epc <= (unsigned long)jprobe_return_end) {
+ *regs = kcb->jprobe_saved_regs;
+ memcpy((void *)kcb->jprobe_saved_sp, kcb->jprobes_stack,
+ MIN_JPROBES_STACK_SIZE(kcb->jprobe_saved_sp));
+ preempt_enable_no_resched();
+
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Function return probe trampoline:
+ * - init_kprobes() establishes a probepoint here
+ * - When the probed function returns, this probe causes the
+ * handlers to fire
+ */
+static void __used kretprobe_trampoline_holder(void)
+{
+ asm volatile(
+ ".set push\n\t"
+ /* Keep the assembler from reordering and placing JR here. */
+ ".set noreorder\n\t"
+ "nop\n\t"
+ ".global kretprobe_trampoline\n"
+ "kretprobe_trampoline:\n\t"
+ "nop\n\t"
+ ".set pop"
+ : : : "memory");
+}
+
+void kretprobe_trampoline(void);
+
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+{
+ ri->ret_addr = (kprobe_opcode_t *) regs->regs[31];
+
+ /* Replace the return addr with trampoline addr */
+ regs->regs[31] = (unsigned long)kretprobe_trampoline;
+}
+
+/*
+ * Called when the probe at kretprobe trampoline is hit
+ */
+static int __kprobes trampoline_probe_handler(struct kprobe *p,
+ struct pt_regs *regs)
+{
+ struct kretprobe_instance *ri = NULL;
+ struct hlist_head *head, empty_rp;
+ struct hlist_node *node, *tmp;
+ unsigned long flags, orig_ret_address = 0;
+ unsigned long trampoline_address = (unsigned long)kretprobe_trampoline;
+
+ INIT_HLIST_HEAD(&empty_rp);
+ kretprobe_hash_lock(current, &head, &flags);
+
+ /*
+ * It is possible to have multiple instances associated with a given
+ * task either because an multiple functions in the call path
+ * have a return probe installed on them, and/or more than one return
+ * return probe was registered for a target function.
+ *
+ * We can handle this because:
+ * - instances are always inserted at the head of the list
+ * - when multiple return probes are registered for the same
+ * function, the first instance's ret_addr will point to the
+ * real return address, and all the rest will point to
+ * kretprobe_trampoline
+ */
+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+ if (ri->task != current)
+ /* another task is sharing our hash bucket */
+ continue;
+
+ if (ri->rp && ri->rp->handler)
+ ri->rp->handler(ri, regs);
+
+ orig_ret_address = (unsigned long)ri->ret_addr;
+ recycle_rp_inst(ri, &empty_rp);
+
+ if (orig_ret_address != trampoline_address)
+ /*
+ * This is the real return address. Any other
+ * instances associated with this task are for
+ * other calls deeper on the call stack
+ */
+ break;
+ }
+
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
+ instruction_pointer(regs) = orig_ret_address;
+
+ reset_current_kprobe();
+ kretprobe_hash_unlock(current, &flags);
+ preempt_enable_no_resched();
+
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
+ /*
+ * By returning a non-zero value, we are telling
+ * kprobe_handler() that we don't want the post_handler
+ * to run (and have re-enabled preemption)
+ */
+ return 1;
+}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (p->addr == (kprobe_opcode_t *)kretprobe_trampoline)
+ return 1;
+
+ return 0;
+}
+
+static struct kprobe trampoline_p = {
+ .addr = (kprobe_opcode_t *)kretprobe_trampoline,
+ .pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+ return register_kprobe(&trampoline_p);
+}
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
new file mode 100644
index 00000000..29811f04
--- /dev/null
+++ b/arch/mips/kernel/kspd.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/unistd.h>
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/fs.h>
+#include <linux/syscalls.h>
+#include <linux/workqueue.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+
+#include <asm/vpe.h>
+#include <asm/rtlx.h>
+#include <asm/kspd.h>
+
+static struct workqueue_struct *workqueue;
+static struct work_struct work;
+
+extern unsigned long cpu_khz;
+
+struct mtsp_syscall {
+ int cmd;
+ unsigned char abi;
+ unsigned char size;
+};
+
+struct mtsp_syscall_ret {
+ int retval;
+ int errno;
+};
+
+struct mtsp_syscall_generic {
+ int arg0;
+ int arg1;
+ int arg2;
+ int arg3;
+ int arg4;
+ int arg5;
+ int arg6;
+};
+
+static struct list_head kspd_notifylist;
+static int sp_stopping;
+
+/* these should match with those in the SDE kit */
+#define MTSP_SYSCALL_BASE 0
+#define MTSP_SYSCALL_EXIT (MTSP_SYSCALL_BASE + 0)
+#define MTSP_SYSCALL_OPEN (MTSP_SYSCALL_BASE + 1)
+#define MTSP_SYSCALL_READ (MTSP_SYSCALL_BASE + 2)
+#define MTSP_SYSCALL_WRITE (MTSP_SYSCALL_BASE + 3)
+#define MTSP_SYSCALL_CLOSE (MTSP_SYSCALL_BASE + 4)
+#define MTSP_SYSCALL_LSEEK32 (MTSP_SYSCALL_BASE + 5)
+#define MTSP_SYSCALL_ISATTY (MTSP_SYSCALL_BASE + 6)
+#define MTSP_SYSCALL_GETTIME (MTSP_SYSCALL_BASE + 7)
+#define MTSP_SYSCALL_PIPEFREQ (MTSP_SYSCALL_BASE + 8)
+#define MTSP_SYSCALL_GETTOD (MTSP_SYSCALL_BASE + 9)
+#define MTSP_SYSCALL_IOCTL (MTSP_SYSCALL_BASE + 10)
+
+#define MTSP_O_RDONLY 0x0000
+#define MTSP_O_WRONLY 0x0001
+#define MTSP_O_RDWR 0x0002
+#define MTSP_O_NONBLOCK 0x0004
+#define MTSP_O_APPEND 0x0008
+#define MTSP_O_SHLOCK 0x0010
+#define MTSP_O_EXLOCK 0x0020
+#define MTSP_O_ASYNC 0x0040
+/* XXX: check which of these is actually O_SYNC vs O_DSYNC */
+#define MTSP_O_FSYNC O_SYNC
+#define MTSP_O_NOFOLLOW 0x0100
+#define MTSP_O_SYNC 0x0080
+#define MTSP_O_CREAT 0x0200
+#define MTSP_O_TRUNC 0x0400
+#define MTSP_O_EXCL 0x0800
+#define MTSP_O_BINARY 0x8000
+
+extern int tclimit;
+
+struct apsp_table {
+ int sp;
+ int ap;
+};
+
+/* we might want to do the mode flags too */
+struct apsp_table open_flags_table[] = {
+ { MTSP_O_RDWR, O_RDWR },
+ { MTSP_O_WRONLY, O_WRONLY },
+ { MTSP_O_CREAT, O_CREAT },
+ { MTSP_O_TRUNC, O_TRUNC },
+ { MTSP_O_NONBLOCK, O_NONBLOCK },
+ { MTSP_O_APPEND, O_APPEND },
+ { MTSP_O_NOFOLLOW, O_NOFOLLOW }
+};
+
+struct apsp_table syscall_command_table[] = {
+ { MTSP_SYSCALL_OPEN, __NR_open },
+ { MTSP_SYSCALL_CLOSE, __NR_close },
+ { MTSP_SYSCALL_READ, __NR_read },
+ { MTSP_SYSCALL_WRITE, __NR_write },
+ { MTSP_SYSCALL_LSEEK32, __NR_lseek },
+ { MTSP_SYSCALL_IOCTL, __NR_ioctl }
+};
+
+static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3)
+{
+ register long int _num __asm__("$2") = num;
+ register long int _arg0 __asm__("$4") = arg0;
+ register long int _arg1 __asm__("$5") = arg1;
+ register long int _arg2 __asm__("$6") = arg2;
+ register long int _arg3 __asm__("$7") = arg3;
+
+ mm_segment_t old_fs;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ __asm__ __volatile__ (
+ " syscall \n"
+ : "=r" (_num), "=r" (_arg3)
+ : "r" (_num), "r" (_arg0), "r" (_arg1), "r" (_arg2), "r" (_arg3));
+
+ set_fs(old_fs);
+
+ /* $a3 is error flag */
+ if (_arg3)
+ return -_num;
+
+ return _num;
+}
+
+static int translate_syscall_command(int cmd)
+{
+ int i;
+ int ret = -1;
+
+ for (i = 0; i < ARRAY_SIZE(syscall_command_table); i++) {
+ if ((cmd == syscall_command_table[i].sp))
+ return syscall_command_table[i].ap;
+ }
+
+ return ret;
+}
+
+static unsigned int translate_open_flags(int flags)
+{
+ int i;
+ unsigned int ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(open_flags_table); i++) {
+ if( (flags & open_flags_table[i].sp) ) {
+ ret |= open_flags_table[i].ap;
+ }
+ }
+
+ return ret;
+}
+
+
+static int sp_setfsuidgid(uid_t uid, gid_t gid)
+{
+ struct cred *new;
+
+ new = prepare_creds();
+ if (!new)
+ return -ENOMEM;
+
+ new->fsuid = uid;
+ new->fsgid = gid;
+
+ commit_creds(new);
+
+ return 0;
+}
+
+/*
+ * Expects a request to be on the sysio channel. Reads it. Decides whether
+ * its a linux syscall and runs it, or whatever. Puts the return code back
+ * into the request and sends the whole thing back.
+ */
+void sp_work_handle_request(void)
+{
+ struct mtsp_syscall sc;
+ struct mtsp_syscall_generic generic;
+ struct mtsp_syscall_ret ret;
+ struct kspd_notifications *n;
+ unsigned long written;
+ mm_segment_t old_fs;
+ struct timeval tv;
+ struct timezone tz;
+ int err, cmd;
+
+ char *vcwd;
+ int size;
+
+ ret.retval = -1;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall))) {
+ set_fs(old_fs);
+ printk(KERN_ERR "Expected request but nothing to read\n");
+ return;
+ }
+
+ size = sc.size;
+
+ if (size) {
+ if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size)) {
+ set_fs(old_fs);
+ printk(KERN_ERR "Expected request but nothing to read\n");
+ return;
+ }
+ }
+
+ /* Run the syscall at the privilege of the user who loaded the
+ SP program */
+
+ if (vpe_getuid(tclimit)) {
+ err = sp_setfsuidgid(vpe_getuid(tclimit), vpe_getgid(tclimit));
+ if (!err)
+ pr_err("Change of creds failed\n");
+ }
+
+ switch (sc.cmd) {
+ /* needs the flags argument translating from SDE kit to
+ linux */
+ case MTSP_SYSCALL_PIPEFREQ:
+ ret.retval = cpu_khz * 1000;
+ ret.errno = 0;
+ break;
+
+ case MTSP_SYSCALL_GETTOD:
+ memset(&tz, 0, sizeof(tz));
+ if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
+ (int)&tz, 0, 0)) == 0)
+ ret.retval = tv.tv_sec;
+ break;
+
+ case MTSP_SYSCALL_EXIT:
+ list_for_each_entry(n, &kspd_notifylist, list)
+ n->kspd_sp_exit(tclimit);
+ sp_stopping = 1;
+
+ printk(KERN_DEBUG "KSPD got exit syscall from SP exitcode %d\n",
+ generic.arg0);
+ break;
+
+ case MTSP_SYSCALL_OPEN:
+ generic.arg1 = translate_open_flags(generic.arg1);
+
+ vcwd = vpe_getcwd(tclimit);
+
+ /* change to cwd of the process that loaded the SP program */
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ sys_chdir(vcwd);
+ set_fs(old_fs);
+
+ sc.cmd = __NR_open;
+
+ /* fall through */
+
+ default:
+ if ((sc.cmd >= __NR_Linux) &&
+ (sc.cmd <= (__NR_Linux + __NR_Linux_syscalls)) )
+ cmd = sc.cmd;
+ else
+ cmd = translate_syscall_command(sc.cmd);
+
+ if (cmd >= 0) {
+ ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1,
+ generic.arg2, generic.arg3);
+ } else
+ printk(KERN_WARNING
+ "KSPD: Unknown SP syscall number %d\n", sc.cmd);
+ break;
+ } /* switch */
+
+ if (vpe_getuid(tclimit)) {
+ err = sp_setfsuidgid(0, 0);
+ if (!err)
+ pr_err("restoring old creds failed\n");
+ }
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ written = rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(ret));
+ set_fs(old_fs);
+ if (written < sizeof(ret))
+ printk("KSPD: sp_work_handle_request failed to send to SP\n");
+}
+
+static void sp_cleanup(void)
+{
+ struct files_struct *files = current->files;
+ int i, j;
+ struct fdtable *fdt;
+
+ j = 0;
+
+ /*
+ * It is safe to dereference the fd table without RCU or
+ * ->file_lock
+ */
+ fdt = files_fdtable(files);
+ for (;;) {
+ unsigned long set;
+ i = j * __NFDBITS;
+ if (i >= fdt->max_fds)
+ break;
+ set = fdt->open_fds->fds_bits[j++];
+ while (set) {
+ if (set & 1) {
+ struct file * file = xchg(&fdt->fd[i], NULL);
+ if (file)
+ filp_close(file, files);
+ }
+ i++;
+ set >>= 1;
+ }
+ }
+
+ /* Put daemon cwd back to root to avoid umount problems */
+ sys_chdir("/");
+}
+
+static int channel_open;
+
+/* the work handler */
+static void sp_work(struct work_struct *unused)
+{
+ if (!channel_open) {
+ if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) {
+ printk("KSPD: unable to open sp channel\n");
+ sp_stopping = 1;
+ } else {
+ channel_open++;
+ printk(KERN_DEBUG "KSPD: SP channel opened\n");
+ }
+ } else {
+ /* wait for some data, allow it to sleep */
+ rtlx_read_poll(RTLX_CHANNEL_SYSIO, 1);
+
+ /* Check we haven't been woken because we are stopping */
+ if (!sp_stopping)
+ sp_work_handle_request();
+ }
+
+ if (!sp_stopping)
+ queue_work(workqueue, &work);
+ else
+ sp_cleanup();
+}
+
+static void startwork(int vpe)
+{
+ sp_stopping = channel_open = 0;
+
+ if (workqueue == NULL) {
+ if ((workqueue = create_singlethread_workqueue("kspd")) == NULL) {
+ printk(KERN_ERR "unable to start kspd\n");
+ return;
+ }
+
+ INIT_WORK(&work, sp_work);
+ }
+
+ queue_work(workqueue, &work);
+}
+
+static void stopwork(int vpe)
+{
+ sp_stopping = 1;
+
+ printk(KERN_DEBUG "KSPD: SP stopping\n");
+}
+
+void kspd_notify(struct kspd_notifications *notify)
+{
+ list_add(&notify->list, &kspd_notifylist);
+}
+
+static struct vpe_notifications notify;
+static int kspd_module_init(void)
+{
+ INIT_LIST_HEAD(&kspd_notifylist);
+
+ notify.start = startwork;
+ notify.stop = stopwork;
+ vpe_notify(tclimit, &notify);
+
+ return 0;
+}
+
+static void kspd_module_exit(void)
+{
+
+}
+
+module_init(kspd_module_init);
+module_exit(kspd_module_exit);
+
+MODULE_DESCRIPTION("MIPS KSPD");
+MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
new file mode 100644
index 00000000..876a75cc
--- /dev/null
+++ b/arch/mips/kernel/linux32.c
@@ -0,0 +1,351 @@
+/*
+ * Conversion between 32-bit and 64-bit native system calls.
+ *
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Written by Ulf Carlsson (ulfc@engr.sgi.com)
+ * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com)
+ */
+#include <linux/compiler.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/highuid.h>
+#include <linux/resource.h>
+#include <linux/highmem.h>
+#include <linux/time.h>
+#include <linux/times.h>
+#include <linux/poll.h>
+#include <linux/skbuff.h>
+#include <linux/filter.h>
+#include <linux/shm.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/icmpv6.h>
+#include <linux/syscalls.h>
+#include <linux/sysctl.h>
+#include <linux/utime.h>
+#include <linux/utsname.h>
+#include <linux/personality.h>
+#include <linux/dnotify.h>
+#include <linux/module.h>
+#include <linux/binfmts.h>
+#include <linux/security.h>
+#include <linux/compat.h>
+#include <linux/vfs.h>
+#include <linux/ipc.h>
+#include <linux/slab.h>
+
+#include <net/sock.h>
+#include <net/scm.h>
+
+#include <asm/compat-signal.h>
+#include <asm/sim.h>
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/mman.h>
+
+/* Use this to get at 32-bit user passed pointers. */
+/* A() macro should be used for places where you e.g.
+ have some internal variable u32 and just want to get
+ rid of a compiler warning. AA() has to be used in
+ places where you want to convert a function argument
+ to 32bit pointer or when you e.g. access pt_regs
+ structure and want to consider 32bit registers only.
+ */
+#define A(__x) ((unsigned long)(__x))
+#define AA(__x) ((unsigned long)((int)__x))
+
+#ifdef __MIPSEB__
+#define merge_64(r1, r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
+#endif
+#ifdef __MIPSEL__
+#define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
+#endif
+
+SYSCALL_DEFINE6(32_mmap2, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, pgoff)
+{
+ unsigned long error;
+
+ error = -EINVAL;
+ if (pgoff & (~PAGE_MASK >> 12))
+ goto out;
+ error = sys_mmap_pgoff(addr, len, prot, flags, fd,
+ pgoff >> (PAGE_SHIFT-12));
+out:
+ return error;
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs)
+{
+ int error;
+ char * filename;
+
+ filename = getname(compat_ptr(regs.regs[4]));
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = compat_do_execve(filename, compat_ptr(regs.regs[5]),
+ compat_ptr(regs.regs[6]), &regs);
+ putname(filename);
+
+out:
+ return error;
+}
+
+#define RLIM_INFINITY32 0x7fffffff
+#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
+
+struct rlimit32 {
+ int rlim_cur;
+ int rlim_max;
+};
+
+SYSCALL_DEFINE4(32_truncate64, const char __user *, path,
+ unsigned long, __dummy, unsigned long, a2, unsigned long, a3)
+{
+ return sys_truncate(path, merge_64(a2, a3));
+}
+
+SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy,
+ unsigned long, a2, unsigned long, a3)
+{
+ return sys_ftruncate(fd, merge_64(a2, a3));
+}
+
+SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high,
+ unsigned int, offset_low, loff_t __user *, result,
+ unsigned int, origin)
+{
+ return sys_llseek(fd, offset_high, offset_low, result, origin);
+}
+
+/* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
+ lseek back to original location. They fail just like lseek does on
+ non-seekable files. */
+
+SYSCALL_DEFINE6(32_pread, unsigned long, fd, char __user *, buf, size_t, count,
+ unsigned long, unused, unsigned long, a4, unsigned long, a5)
+{
+ return sys_pread64(fd, buf, count, merge_64(a4, a5));
+}
+
+SYSCALL_DEFINE6(32_pwrite, unsigned int, fd, const char __user *, buf,
+ size_t, count, u32, unused, u64, a4, u64, a5)
+{
+ return sys_pwrite64(fd, buf, count, merge_64(a4, a5));
+}
+
+SYSCALL_DEFINE2(32_sched_rr_get_interval, compat_pid_t, pid,
+ struct compat_timespec __user *, interval)
+{
+ struct timespec t;
+ int ret;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs(KERNEL_DS);
+ ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
+ set_fs(old_fs);
+ if (put_user (t.tv_sec, &interval->tv_sec) ||
+ __put_user(t.tv_nsec, &interval->tv_nsec))
+ return -EFAULT;
+ return ret;
+}
+
+#ifdef CONFIG_SYSVIPC
+
+SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third,
+ unsigned long, ptr, unsigned long, fifth)
+{
+ int version, err;
+
+ version = call >> 16; /* hack for backward compatibility */
+ call &= 0xffff;
+
+ switch (call) {
+ case SEMOP:
+ /* struct sembuf is the same on 32 and 64bit :)) */
+ err = sys_semtimedop(first, compat_ptr(ptr), second, NULL);
+ break;
+ case SEMTIMEDOP:
+ err = compat_sys_semtimedop(first, compat_ptr(ptr), second,
+ compat_ptr(fifth));
+ break;
+ case SEMGET:
+ err = sys_semget(first, second, third);
+ break;
+ case SEMCTL:
+ err = compat_sys_semctl(first, second, third, compat_ptr(ptr));
+ break;
+ case MSGSND:
+ err = compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
+ break;
+ case MSGRCV:
+ err = compat_sys_msgrcv(first, second, fifth, third,
+ version, compat_ptr(ptr));
+ break;
+ case MSGGET:
+ err = sys_msgget((key_t) first, second);
+ break;
+ case MSGCTL:
+ err = compat_sys_msgctl(first, second, compat_ptr(ptr));
+ break;
+ case SHMAT:
+ err = compat_sys_shmat(first, second, third, version,
+ compat_ptr(ptr));
+ break;
+ case SHMDT:
+ err = sys_shmdt(compat_ptr(ptr));
+ break;
+ case SHMGET:
+ err = sys_shmget(first, (unsigned)second, third);
+ break;
+ case SHMCTL:
+ err = compat_sys_shmctl(first, second, compat_ptr(ptr));
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+#else
+
+SYSCALL_DEFINE6(32_ipc, u32, call, int, first, int, second, int, third,
+ u32, ptr, u32, fifth)
+{
+ return -ENOSYS;
+}
+
+#endif /* CONFIG_SYSVIPC */
+
+#ifdef CONFIG_MIPS32_N32
+SYSCALL_DEFINE4(n32_semctl, int, semid, int, semnum, int, cmd, u32, arg)
+{
+ /* compat_sys_semctl expects a pointer to union semun */
+ u32 __user *uptr = compat_alloc_user_space(sizeof(u32));
+ if (put_user(arg, uptr))
+ return -EFAULT;
+ return compat_sys_semctl(semid, semnum, cmd, uptr);
+}
+
+SYSCALL_DEFINE4(n32_msgsnd, int, msqid, u32, msgp, unsigned int, msgsz,
+ int, msgflg)
+{
+ return compat_sys_msgsnd(msqid, msgsz, msgflg, compat_ptr(msgp));
+}
+
+SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
+ int, msgtyp, int, msgflg)
+{
+ return compat_sys_msgrcv(msqid, msgsz, msgtyp, msgflg, IPC_64,
+ compat_ptr(msgp));
+}
+#endif
+
+SYSCALL_DEFINE1(32_personality, unsigned long, personality)
+{
+ unsigned int p = personality & 0xffffffff;
+ int ret;
+
+ if (personality(current->personality) == PER_LINUX32 &&
+ personality(p) == PER_LINUX)
+ p = (p & ~PER_MASK) | PER_LINUX32;
+ ret = sys_personality(p);
+ if (ret != -1 && personality(ret) == PER_LINUX32)
+ ret = (ret & ~PER_MASK) | PER_LINUX;
+ return ret;
+}
+
+SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd,
+ compat_off_t __user *, offset, s32, count)
+{
+ mm_segment_t old_fs = get_fs();
+ int ret;
+ off_t of;
+
+ if (offset && get_user(of, offset))
+ return -EFAULT;
+
+ set_fs(KERNEL_DS);
+ ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count);
+ set_fs(old_fs);
+
+ if (offset && put_user(of, offset))
+ return -EFAULT;
+
+ return ret;
+}
+
+asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,
+ size_t count)
+{
+ return sys_readahead(fd, merge_64(a2, a3), count);
+}
+
+asmlinkage long sys32_sync_file_range(int fd, int __pad,
+ unsigned long a2, unsigned long a3,
+ unsigned long a4, unsigned long a5,
+ int flags)
+{
+ return sys_sync_file_range(fd,
+ merge_64(a2, a3), merge_64(a4, a5),
+ flags);
+}
+
+asmlinkage long sys32_fadvise64_64(int fd, int __pad,
+ unsigned long a2, unsigned long a3,
+ unsigned long a4, unsigned long a5,
+ int flags)
+{
+ return sys_fadvise64_64(fd,
+ merge_64(a2, a3), merge_64(a4, a5),
+ flags);
+}
+
+asmlinkage long sys32_fallocate(int fd, int mode, unsigned offset_a2,
+ unsigned offset_a3, unsigned len_a4, unsigned len_a5)
+{
+ return sys_fallocate(fd, mode, merge_64(offset_a2, offset_a3),
+ merge_64(len_a4, len_a5));
+}
+
+save_static_function(sys32_clone);
+static int noinline __used
+_sys32_clone(nabi_no_regargs struct pt_regs regs)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+ int __user *parent_tidptr, *child_tidptr;
+
+ clone_flags = regs.regs[4];
+ newsp = regs.regs[5];
+ if (!newsp)
+ newsp = regs.regs[29];
+ parent_tidptr = (int __user *) regs.regs[6];
+
+ /* Use __dummy4 instead of getting it off the stack, so that
+ syscall() works. */
+ child_tidptr = (int __user *) __dummy4;
+ return do_fork(clone_flags, newsp, &regs, 0,
+ parent_tidptr, child_tidptr);
+}
+
+asmlinkage long sys32_lookup_dcookie(u32 a0, u32 a1, char __user *buf,
+ size_t len)
+{
+ return sys_lookup_dcookie(merge_64(a0, a1), buf, len);
+}
+
+SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags,
+ u64, a3, u64, a4, int, dfd, const char __user *, pathname)
+{
+ return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4),
+ dfd, pathname);
+}
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
new file mode 100644
index 00000000..85beb9b0
--- /dev/null
+++ b/arch/mips/kernel/machine_kexec.c
@@ -0,0 +1,85 @@
+/*
+ * machine_kexec.c for kexec
+ * Created by <nschichan@corp.free.fr> on Thu Oct 12 15:15:06 2006
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/kexec.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+
+extern const unsigned char relocate_new_kernel[];
+extern const size_t relocate_new_kernel_size;
+
+extern unsigned long kexec_start_address;
+extern unsigned long kexec_indirection_page;
+
+int
+machine_kexec_prepare(struct kimage *kimage)
+{
+ return 0;
+}
+
+void
+machine_kexec_cleanup(struct kimage *kimage)
+{
+}
+
+void
+machine_shutdown(void)
+{
+}
+
+void
+machine_crash_shutdown(struct pt_regs *regs)
+{
+}
+
+typedef void (*noretfun_t)(void) __attribute__((noreturn));
+
+void
+machine_kexec(struct kimage *image)
+{
+ unsigned long reboot_code_buffer;
+ unsigned long entry;
+ unsigned long *ptr;
+
+ reboot_code_buffer =
+ (unsigned long)page_address(image->control_code_page);
+
+ kexec_start_address = image->start;
+ kexec_indirection_page =
+ (unsigned long) phys_to_virt(image->head & PAGE_MASK);
+
+ memcpy((void*)reboot_code_buffer, relocate_new_kernel,
+ relocate_new_kernel_size);
+
+ /*
+ * The generic kexec code builds a page list with physical
+ * addresses. they are directly accessible through KSEG0 (or
+ * CKSEG0 or XPHYS if on 64bit system), hence the
+ * pys_to_virt() call.
+ */
+ for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE);
+ ptr = (entry & IND_INDIRECTION) ?
+ phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
+ if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION ||
+ *ptr & IND_DESTINATION)
+ *ptr = (unsigned long) phys_to_virt(*ptr);
+ }
+
+ /*
+ * we do not want to be bothered.
+ */
+ local_irq_disable();
+
+ printk("Will call new kernel at %08lx\n", image->start);
+ printk("Bye ...\n");
+ __flush_cache_all();
+ ((noretfun_t) reboot_code_buffer)();
+}
diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S
new file mode 100644
index 00000000..4c968e7e
--- /dev/null
+++ b/arch/mips/kernel/mcount.S
@@ -0,0 +1,202 @@
+/*
+ * MIPS specific _mcount support
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive for
+ * more details.
+ *
+ * Copyright (C) 2009 Lemote Inc. & DSLab, Lanzhou University, China
+ * Copyright (C) 2010 DSLab, Lanzhou University, China
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/ftrace.h>
+
+ .text
+ .set noreorder
+ .set noat
+
+ .macro MCOUNT_SAVE_REGS
+ PTR_SUBU sp, PT_SIZE
+ PTR_S ra, PT_R31(sp)
+ PTR_S AT, PT_R1(sp)
+ PTR_S a0, PT_R4(sp)
+ PTR_S a1, PT_R5(sp)
+ PTR_S a2, PT_R6(sp)
+ PTR_S a3, PT_R7(sp)
+#ifdef CONFIG_64BIT
+ PTR_S a4, PT_R8(sp)
+ PTR_S a5, PT_R9(sp)
+ PTR_S a6, PT_R10(sp)
+ PTR_S a7, PT_R11(sp)
+#endif
+ .endm
+
+ .macro MCOUNT_RESTORE_REGS
+ PTR_L ra, PT_R31(sp)
+ PTR_L AT, PT_R1(sp)
+ PTR_L a0, PT_R4(sp)
+ PTR_L a1, PT_R5(sp)
+ PTR_L a2, PT_R6(sp)
+ PTR_L a3, PT_R7(sp)
+#ifdef CONFIG_64BIT
+ PTR_L a4, PT_R8(sp)
+ PTR_L a5, PT_R9(sp)
+ PTR_L a6, PT_R10(sp)
+ PTR_L a7, PT_R11(sp)
+ PTR_ADDIU sp, PT_SIZE
+#else
+ PTR_ADDIU sp, (PT_SIZE + 8)
+#endif
+.endm
+
+ .macro RETURN_BACK
+ jr ra
+ move ra, AT
+ .endm
+
+/*
+ * The -mmcount-ra-address option of gcc 4.5 uses register $12 to pass
+ * the location of the parent's return address.
+ */
+#define MCOUNT_RA_ADDRESS_REG $12
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+NESTED(ftrace_caller, PT_SIZE, ra)
+ .globl _mcount
+_mcount:
+ b ftrace_stub
+ nop
+ lw t1, function_trace_stop
+ bnez t1, ftrace_stub
+ nop
+
+ MCOUNT_SAVE_REGS
+#ifdef KBUILD_MCOUNT_RA_ADDRESS
+ PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
+#endif
+
+ move a0, ra /* arg1: self return address */
+ .globl ftrace_call
+ftrace_call:
+ nop /* a placeholder for the call to a real tracing function */
+ move a1, AT /* arg2: parent's return address */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ .globl ftrace_graph_call
+ftrace_graph_call:
+ nop
+ nop
+#endif
+
+ MCOUNT_RESTORE_REGS
+ .globl ftrace_stub
+ftrace_stub:
+ RETURN_BACK
+ END(ftrace_caller)
+
+#else /* ! CONFIG_DYNAMIC_FTRACE */
+
+NESTED(_mcount, PT_SIZE, ra)
+ lw t1, function_trace_stop
+ bnez t1, ftrace_stub
+ nop
+ PTR_LA t1, ftrace_stub
+ PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */
+ bne t1, t2, static_trace
+ nop
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ PTR_L t3, ftrace_graph_return
+ bne t1, t3, ftrace_graph_caller
+ nop
+ PTR_LA t1, ftrace_graph_entry_stub
+ PTR_L t3, ftrace_graph_entry
+ bne t1, t3, ftrace_graph_caller
+ nop
+#endif
+ b ftrace_stub
+ nop
+
+static_trace:
+ MCOUNT_SAVE_REGS
+
+ move a0, ra /* arg1: self return address */
+ jalr t2 /* (1) call *ftrace_trace_function */
+ move a1, AT /* arg2: parent's return address */
+
+ MCOUNT_RESTORE_REGS
+ .globl ftrace_stub
+ftrace_stub:
+ RETURN_BACK
+ END(_mcount)
+
+#endif /* ! CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+NESTED(ftrace_graph_caller, PT_SIZE, ra)
+#ifndef CONFIG_DYNAMIC_FTRACE
+ MCOUNT_SAVE_REGS
+#endif
+
+ /* arg1: Get the location of the parent's return address */
+#ifdef KBUILD_MCOUNT_RA_ADDRESS
+#ifdef CONFIG_DYNAMIC_FTRACE
+ PTR_L a0, PT_R12(sp)
+#else
+ move a0, MCOUNT_RA_ADDRESS_REG
+#endif
+ bnez a0, 1f /* non-leaf func: stored in MCOUNT_RA_ADDRESS_REG */
+ nop
+#endif
+ PTR_LA a0, PT_R1(sp) /* leaf func: the location in current stack */
+1:
+
+ /* arg2: Get self return address */
+#ifdef CONFIG_DYNAMIC_FTRACE
+ PTR_L a1, PT_R31(sp)
+#else
+ move a1, ra
+#endif
+
+ /* arg3: Get frame pointer of current stack */
+#ifdef CONFIG_FRAME_POINTER
+ move a2, fp
+#else /* ! CONFIG_FRAME_POINTER */
+#ifdef CONFIG_64BIT
+ PTR_LA a2, PT_SIZE(sp)
+#else
+ PTR_LA a2, (PT_SIZE+8)(sp)
+#endif
+#endif
+
+ jal prepare_ftrace_return
+ nop
+ MCOUNT_RESTORE_REGS
+ RETURN_BACK
+ END(ftrace_graph_caller)
+
+ .align 2
+ .globl return_to_handler
+return_to_handler:
+ PTR_SUBU sp, PT_SIZE
+ PTR_S v0, PT_R2(sp)
+
+ jal ftrace_return_to_handler
+ PTR_S v1, PT_R3(sp)
+
+ /* restore the real parent address: v0 -> ra */
+ move ra, v0
+
+ PTR_L v0, PT_R2(sp)
+ PTR_L v1, PT_R3(sp)
+ jr ra
+ PTR_ADDIU sp, PT_SIZE
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+ .set at
+ .set reorder
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
new file mode 100644
index 00000000..802e6160
--- /dev/null
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -0,0 +1,214 @@
+/*
+ * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels
+ * Copyright (C) 2005 Mips Technologies, Inc
+ */
+#include <linux/cpu.h>
+#include <linux/cpuset.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/security.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+
+/*
+ * CPU mask used to set process affinity for MT VPEs/TCs with FPUs
+ */
+cpumask_t mt_fpu_cpumask;
+
+static int fpaff_threshold = -1;
+unsigned long mt_fpemul_threshold;
+
+/*
+ * Replacement functions for the sys_sched_setaffinity() and
+ * sys_sched_getaffinity() system calls, so that we can integrate
+ * FPU affinity with the user's requested processor affinity.
+ * This code is 98% identical with the sys_sched_setaffinity()
+ * and sys_sched_getaffinity() system calls, and should be
+ * updated when kernel/sched.c changes.
+ */
+
+/*
+ * find_process_by_pid - find a process with a matching PID value.
+ * used in sys_sched_set/getaffinity() in kernel/sched.c, so
+ * cloned here.
+ */
+static inline struct task_struct *find_process_by_pid(pid_t pid)
+{
+ return pid ? find_task_by_vpid(pid) : current;
+}
+
+/*
+ * check the target process has a UID that matches the current process's
+ */
+static bool check_same_owner(struct task_struct *p)
+{
+ const struct cred *cred = current_cred(), *pcred;
+ bool match;
+
+ rcu_read_lock();
+ pcred = __task_cred(p);
+ match = (cred->euid == pcred->euid ||
+ cred->euid == pcred->uid);
+ rcu_read_unlock();
+ return match;
+}
+
+/*
+ * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process
+ */
+asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
+ unsigned long __user *user_mask_ptr)
+{
+ cpumask_var_t cpus_allowed, new_mask, effective_mask;
+ struct thread_info *ti;
+ struct task_struct *p;
+ int retval;
+
+ if (len < sizeof(new_mask))
+ return -EINVAL;
+
+ if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
+ return -EFAULT;
+
+ get_online_cpus();
+ rcu_read_lock();
+
+ p = find_process_by_pid(pid);
+ if (!p) {
+ rcu_read_unlock();
+ put_online_cpus();
+ return -ESRCH;
+ }
+
+ /* Prevent p going away */
+ get_task_struct(p);
+ rcu_read_unlock();
+
+ if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_put_task;
+ }
+ if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_free_cpus_allowed;
+ }
+ if (!alloc_cpumask_var(&effective_mask, GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_free_new_mask;
+ }
+ retval = -EPERM;
+ if (!check_same_owner(p) && !capable(CAP_SYS_NICE))
+ goto out_unlock;
+
+ retval = security_task_setscheduler(p);
+ if (retval)
+ goto out_unlock;
+
+ /* Record new user-specified CPU set for future reference */
+ cpumask_copy(&p->thread.user_cpus_allowed, new_mask);
+
+ again:
+ /* Compute new global allowed CPU set if necessary */
+ ti = task_thread_info(p);
+ if (test_ti_thread_flag(ti, TIF_FPUBOUND) &&
+ cpus_intersects(*new_mask, mt_fpu_cpumask)) {
+ cpus_and(*effective_mask, *new_mask, mt_fpu_cpumask);
+ retval = set_cpus_allowed_ptr(p, effective_mask);
+ } else {
+ cpumask_copy(effective_mask, new_mask);
+ clear_ti_thread_flag(ti, TIF_FPUBOUND);
+ retval = set_cpus_allowed_ptr(p, new_mask);
+ }
+
+ if (!retval) {
+ cpuset_cpus_allowed(p, cpus_allowed);
+ if (!cpumask_subset(effective_mask, cpus_allowed)) {
+ /*
+ * We must have raced with a concurrent cpuset
+ * update. Just reset the cpus_allowed to the
+ * cpuset's cpus_allowed
+ */
+ cpumask_copy(new_mask, cpus_allowed);
+ goto again;
+ }
+ }
+out_unlock:
+ free_cpumask_var(effective_mask);
+out_free_new_mask:
+ free_cpumask_var(new_mask);
+out_free_cpus_allowed:
+ free_cpumask_var(cpus_allowed);
+out_put_task:
+ put_task_struct(p);
+ put_online_cpus();
+ return retval;
+}
+
+/*
+ * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process
+ */
+asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
+ unsigned long __user *user_mask_ptr)
+{
+ unsigned int real_len;
+ cpumask_t mask;
+ int retval;
+ struct task_struct *p;
+
+ real_len = sizeof(mask);
+ if (len < real_len)
+ return -EINVAL;
+
+ get_online_cpus();
+ read_lock(&tasklist_lock);
+
+ retval = -ESRCH;
+ p = find_process_by_pid(pid);
+ if (!p)
+ goto out_unlock;
+ retval = security_task_getscheduler(p);
+ if (retval)
+ goto out_unlock;
+
+ cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
+
+out_unlock:
+ read_unlock(&tasklist_lock);
+ put_online_cpus();
+ if (retval)
+ return retval;
+ if (copy_to_user(user_mask_ptr, &mask, real_len))
+ return -EFAULT;
+ return real_len;
+}
+
+
+static int __init fpaff_thresh(char *str)
+{
+ get_option(&str, &fpaff_threshold);
+ return 1;
+}
+__setup("fpaff=", fpaff_thresh);
+
+/*
+ * FPU Use Factor empirically derived from experiments on 34K
+ */
+#define FPUSEFACTOR 2000
+
+static __init int mt_fp_affinity_init(void)
+{
+ if (fpaff_threshold >= 0) {
+ mt_fpemul_threshold = fpaff_threshold;
+ } else {
+ mt_fpemul_threshold =
+ (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ;
+ }
+ printk(KERN_DEBUG "FPU Affinity set after %ld emulations\n",
+ mt_fpemul_threshold);
+
+ return 0;
+}
+arch_initcall(mt_fp_affinity_init);
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
new file mode 100644
index 00000000..b2259e7c
--- /dev/null
+++ b/arch/mips/kernel/mips-mt.c
@@ -0,0 +1,332 @@
+/*
+ * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels
+ * Copyright (C) 2005 Mips Technologies, Inc
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/security.h>
+
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/mipsmtregs.h>
+#include <asm/r4kcache.h>
+#include <asm/cacheflush.h>
+
+int vpelimit;
+
+static int __init maxvpes(char *str)
+{
+ get_option(&str, &vpelimit);
+
+ return 1;
+}
+
+__setup("maxvpes=", maxvpes);
+
+int tclimit;
+
+static int __init maxtcs(char *str)
+{
+ get_option(&str, &tclimit);
+
+ return 1;
+}
+
+__setup("maxtcs=", maxtcs);
+
+/*
+ * Dump new MIPS MT state for the core. Does not leave TCs halted.
+ * Takes an argument which taken to be a pre-call MVPControl value.
+ */
+
+void mips_mt_regdump(unsigned long mvpctl)
+{
+ unsigned long flags;
+ unsigned long vpflags;
+ unsigned long mvpconf0;
+ int nvpe;
+ int ntc;
+ int i;
+ int tc;
+ unsigned long haltval;
+ unsigned long tcstatval;
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_soft_dump(void);
+#endif /* CONFIG_MIPT_MT_SMTC */
+
+ local_irq_save(flags);
+ vpflags = dvpe();
+ printk("=== MIPS MT State Dump ===\n");
+ printk("-- Global State --\n");
+ printk(" MVPControl Passed: %08lx\n", mvpctl);
+ printk(" MVPControl Read: %08lx\n", vpflags);
+ printk(" MVPConf0 : %08lx\n", (mvpconf0 = read_c0_mvpconf0()));
+ nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+ ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
+ printk("-- per-VPE State --\n");
+ for (i = 0; i < nvpe; i++) {
+ for (tc = 0; tc < ntc; tc++) {
+ settc(tc);
+ if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) {
+ printk(" VPE %d\n", i);
+ printk(" VPEControl : %08lx\n",
+ read_vpe_c0_vpecontrol());
+ printk(" VPEConf0 : %08lx\n",
+ read_vpe_c0_vpeconf0());
+ printk(" VPE%d.Status : %08lx\n",
+ i, read_vpe_c0_status());
+ printk(" VPE%d.EPC : %08lx %pS\n",
+ i, read_vpe_c0_epc(),
+ (void *) read_vpe_c0_epc());
+ printk(" VPE%d.Cause : %08lx\n",
+ i, read_vpe_c0_cause());
+ printk(" VPE%d.Config7 : %08lx\n",
+ i, read_vpe_c0_config7());
+ break; /* Next VPE */
+ }
+ }
+ }
+ printk("-- per-TC State --\n");
+ for (tc = 0; tc < ntc; tc++) {
+ settc(tc);
+ if (read_tc_c0_tcbind() == read_c0_tcbind()) {
+ /* Are we dumping ourself? */
+ haltval = 0; /* Then we're not halted, and mustn't be */
+ tcstatval = flags; /* And pre-dump TCStatus is flags */
+ printk(" TC %d (current TC with VPE EPC above)\n", tc);
+ } else {
+ haltval = read_tc_c0_tchalt();
+ write_tc_c0_tchalt(1);
+ tcstatval = read_tc_c0_tcstatus();
+ printk(" TC %d\n", tc);
+ }
+ printk(" TCStatus : %08lx\n", tcstatval);
+ printk(" TCBind : %08lx\n", read_tc_c0_tcbind());
+ printk(" TCRestart : %08lx %pS\n",
+ read_tc_c0_tcrestart(), (void *) read_tc_c0_tcrestart());
+ printk(" TCHalt : %08lx\n", haltval);
+ printk(" TCContext : %08lx\n", read_tc_c0_tccontext());
+ if (!haltval)
+ write_tc_c0_tchalt(0);
+ }
+#ifdef CONFIG_MIPS_MT_SMTC
+ smtc_soft_dump();
+#endif /* CONFIG_MIPT_MT_SMTC */
+ printk("===========================\n");
+ evpe(vpflags);
+ local_irq_restore(flags);
+}
+
+static int mt_opt_norps;
+static int mt_opt_rpsctl = -1;
+static int mt_opt_nblsu = -1;
+static int mt_opt_forceconfig7;
+static int mt_opt_config7 = -1;
+
+static int __init rps_disable(char *s)
+{
+ mt_opt_norps = 1;
+ return 1;
+}
+__setup("norps", rps_disable);
+
+static int __init rpsctl_set(char *str)
+{
+ get_option(&str, &mt_opt_rpsctl);
+ return 1;
+}
+__setup("rpsctl=", rpsctl_set);
+
+static int __init nblsu_set(char *str)
+{
+ get_option(&str, &mt_opt_nblsu);
+ return 1;
+}
+__setup("nblsu=", nblsu_set);
+
+static int __init config7_set(char *str)
+{
+ get_option(&str, &mt_opt_config7);
+ mt_opt_forceconfig7 = 1;
+ return 1;
+}
+__setup("config7=", config7_set);
+
+/* Experimental cache flush control parameters that should go away some day */
+int mt_protiflush;
+int mt_protdflush;
+int mt_n_iflushes = 1;
+int mt_n_dflushes = 1;
+
+static int __init set_protiflush(char *s)
+{
+ mt_protiflush = 1;
+ return 1;
+}
+__setup("protiflush", set_protiflush);
+
+static int __init set_protdflush(char *s)
+{
+ mt_protdflush = 1;
+ return 1;
+}
+__setup("protdflush", set_protdflush);
+
+static int __init niflush(char *s)
+{
+ get_option(&s, &mt_n_iflushes);
+ return 1;
+}
+__setup("niflush=", niflush);
+
+static int __init ndflush(char *s)
+{
+ get_option(&s, &mt_n_dflushes);
+ return 1;
+}
+__setup("ndflush=", ndflush);
+
+static unsigned int itc_base;
+
+static int __init set_itc_base(char *str)
+{
+ get_option(&str, &itc_base);
+ return 1;
+}
+
+__setup("itcbase=", set_itc_base);
+
+void mips_mt_set_cpuoptions(void)
+{
+ unsigned int oconfig7 = read_c0_config7();
+ unsigned int nconfig7 = oconfig7;
+
+ if (mt_opt_norps) {
+ printk("\"norps\" option deprectated: use \"rpsctl=\"\n");
+ }
+ if (mt_opt_rpsctl >= 0) {
+ printk("34K return prediction stack override set to %d.\n",
+ mt_opt_rpsctl);
+ if (mt_opt_rpsctl)
+ nconfig7 |= (1 << 2);
+ else
+ nconfig7 &= ~(1 << 2);
+ }
+ if (mt_opt_nblsu >= 0) {
+ printk("34K ALU/LSU sync override set to %d.\n", mt_opt_nblsu);
+ if (mt_opt_nblsu)
+ nconfig7 |= (1 << 5);
+ else
+ nconfig7 &= ~(1 << 5);
+ }
+ if (mt_opt_forceconfig7) {
+ printk("CP0.Config7 forced to 0x%08x.\n", mt_opt_config7);
+ nconfig7 = mt_opt_config7;
+ }
+ if (oconfig7 != nconfig7) {
+ __asm__ __volatile("sync");
+ write_c0_config7(nconfig7);
+ ehb();
+ printk("Config7: 0x%08x\n", read_c0_config7());
+ }
+
+ /* Report Cache management debug options */
+ if (mt_protiflush)
+ printk("I-cache flushes single-threaded\n");
+ if (mt_protdflush)
+ printk("D-cache flushes single-threaded\n");
+ if (mt_n_iflushes != 1)
+ printk("I-Cache Flushes Repeated %d times\n", mt_n_iflushes);
+ if (mt_n_dflushes != 1)
+ printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes);
+
+ if (itc_base != 0) {
+ /*
+ * Configure ITC mapping. This code is very
+ * specific to the 34K core family, which uses
+ * a special mode bit ("ITC") in the ErrCtl
+ * register to enable access to ITC control
+ * registers via cache "tag" operations.
+ */
+ unsigned long ectlval;
+ unsigned long itcblkgrn;
+
+ /* ErrCtl register is known as "ecc" to Linux */
+ ectlval = read_c0_ecc();
+ write_c0_ecc(ectlval | (0x1 << 26));
+ ehb();
+#define INDEX_0 (0x80000000)
+#define INDEX_8 (0x80000008)
+ /* Read "cache tag" for Dcache pseudo-index 8 */
+ cache_op(Index_Load_Tag_D, INDEX_8);
+ ehb();
+ itcblkgrn = read_c0_dtaglo();
+ itcblkgrn &= 0xfffe0000;
+ /* Set for 128 byte pitch of ITC cells */
+ itcblkgrn |= 0x00000c00;
+ /* Stage in Tag register */
+ write_c0_dtaglo(itcblkgrn);
+ ehb();
+ /* Write out to ITU with CACHE op */
+ cache_op(Index_Store_Tag_D, INDEX_8);
+ /* Now set base address, and turn ITC on with 0x1 bit */
+ write_c0_dtaglo((itc_base & 0xfffffc00) | 0x1 );
+ ehb();
+ /* Write out to ITU with CACHE op */
+ cache_op(Index_Store_Tag_D, INDEX_0);
+ write_c0_ecc(ectlval);
+ ehb();
+ printk("Mapped %ld ITC cells starting at 0x%08x\n",
+ ((itcblkgrn & 0x7fe00000) >> 20), itc_base);
+ }
+}
+
+/*
+ * Function to protect cache flushes from concurrent execution
+ * depends on MP software model chosen.
+ */
+
+void mt_cflush_lockdown(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_cflush_lockdown(void);
+
+ smtc_cflush_lockdown();
+#endif /* CONFIG_MIPS_MT_SMTC */
+ /* FILL IN VSMP and AP/SP VERSIONS HERE */
+}
+
+void mt_cflush_release(void)
+{
+#ifdef CONFIG_MIPS_MT_SMTC
+ void smtc_cflush_release(void);
+
+ smtc_cflush_release();
+#endif /* CONFIG_MIPS_MT_SMTC */
+ /* FILL IN VSMP and AP/SP VERSIONS HERE */
+}
+
+struct class *mt_class;
+
+static int __init mt_init(void)
+{
+ struct class *mtc;
+
+ mtc = class_create(THIS_MODULE, "mt");
+ if (IS_ERR(mtc))
+ return PTR_ERR(mtc);
+
+ mt_class = mtc;
+
+ return 0;
+}
+
+subsys_initcall(mt_init);
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
new file mode 100644
index 00000000..1d048078
--- /dev/null
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -0,0 +1,58 @@
+/*
+ * Export MIPS-specific functions needed for loadable modules.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03, 04, 05 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc.
+ */
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/checksum.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/ftrace.h>
+
+extern void *__bzero(void *__s, size_t __count);
+extern long __strncpy_from_user_nocheck_asm(char *__to,
+ const char *__from, long __len);
+extern long __strncpy_from_user_asm(char *__to, const char *__from,
+ long __len);
+extern long __strlen_user_nocheck_asm(const char *s);
+extern long __strlen_user_asm(const char *s);
+extern long __strnlen_user_nocheck_asm(const char *s);
+extern long __strnlen_user_asm(const char *s);
+
+/*
+ * String functions
+ */
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
+
+EXPORT_SYMBOL(kernel_thread);
+
+/*
+ * Userspace access stuff.
+ */
+EXPORT_SYMBOL(__copy_user);
+EXPORT_SYMBOL(__copy_user_inatomic);
+EXPORT_SYMBOL(__bzero);
+EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm);
+EXPORT_SYMBOL(__strncpy_from_user_asm);
+EXPORT_SYMBOL(__strlen_user_nocheck_asm);
+EXPORT_SYMBOL(__strlen_user_asm);
+EXPORT_SYMBOL(__strnlen_user_nocheck_asm);
+EXPORT_SYMBOL(__strnlen_user_asm);
+
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
+EXPORT_SYMBOL(__csum_partial_copy_user);
+
+EXPORT_SYMBOL(invalid_pte_table);
+#ifdef CONFIG_FUNCTION_TRACER
+/* _mcount is defined in arch/mips/kernel/mcount.S */
+EXPORT_SYMBOL(_mcount);
+#endif
diff --git a/arch/mips/kernel/mips_machine.c b/arch/mips/kernel/mips_machine.c
new file mode 100644
index 00000000..411a058d
--- /dev/null
+++ b/arch/mips/kernel/mips_machine.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include <asm/mips_machine.h>
+
+static struct mips_machine *mips_machine __initdata;
+static char *mips_machine_name = "Unknown";
+
+#define for_each_machine(mach) \
+ for ((mach) = (struct mips_machine *)&__mips_machines_start; \
+ (mach) && \
+ (unsigned long)(mach) < (unsigned long)&__mips_machines_end; \
+ (mach)++)
+
+__init void mips_set_machine_name(const char *name)
+{
+ char *p;
+
+ if (name == NULL)
+ return;
+
+ p = kstrdup(name, GFP_KERNEL);
+ if (!p)
+ pr_err("MIPS: no memory for machine_name\n");
+
+ mips_machine_name = p;
+}
+
+char *mips_get_machine_name(void)
+{
+ return mips_machine_name;
+}
+
+__init int mips_machtype_setup(char *id)
+{
+ struct mips_machine *mach;
+
+ for_each_machine(mach) {
+ if (mach->mach_id == NULL)
+ continue;
+
+ if (strcmp(mach->mach_id, id) == 0) {
+ mips_machtype = mach->mach_type;
+ return 0;
+ }
+ }
+
+ pr_err("MIPS: no machine found for id '%s', supported machines:\n", id);
+ pr_err("%-24s %s\n", "id", "name");
+ for_each_machine(mach)
+ pr_err("%-24s %s\n", mach->mach_id, mach->mach_name);
+
+ return 1;
+}
+
+__setup("machtype=", mips_machtype_setup);
+
+__init void mips_machine_setup(void)
+{
+ struct mips_machine *mach;
+
+ for_each_machine(mach) {
+ if (mips_machtype == mach->mach_type) {
+ mips_machine = mach;
+ break;
+ }
+ }
+
+ if (!mips_machine)
+ return;
+
+ mips_set_machine_name(mips_machine->mach_name);
+ pr_info("MIPS: machine is %s\n", mips_machine_name);
+
+ if (mips_machine->mach_setup)
+ mips_machine->mach_setup();
+}
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
new file mode 100644
index 00000000..dd940b70
--- /dev/null
+++ b/arch/mips/kernel/module.c
@@ -0,0 +1,408 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2001 Rusty Russell.
+ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2005 Thiemo Seufer
+ */
+
+#undef DEBUG
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/jump_label.h>
+
+#include <asm/pgtable.h> /* MODULE_START */
+
+struct mips_hi16 {
+ struct mips_hi16 *next;
+ Elf_Addr *addr;
+ Elf_Addr value;
+};
+
+static struct mips_hi16 *mips_hi16_list;
+
+static LIST_HEAD(dbe_list);
+static DEFINE_SPINLOCK(dbe_lock);
+
+void *module_alloc(unsigned long size)
+{
+#ifdef MODULE_START
+ return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
+ GFP_KERNEL, PAGE_KERNEL, -1,
+ __builtin_return_address(0));
+#else
+ if (size == 0)
+ return NULL;
+ return vmalloc(size);
+#endif
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ vfree(module_region);
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+ char *secstrings, struct module *mod)
+{
+ return 0;
+}
+
+static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
+{
+ return 0;
+}
+
+static int apply_r_mips_32_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location += v;
+
+ return 0;
+}
+
+static int apply_r_mips_32_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = v;
+
+ return 0;
+}
+
+static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ if (v % 4) {
+ pr_err("module %s: dangerous R_MIPS_26 REL relocation\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ printk(KERN_ERR
+ "module %s: relocation overflow\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & ~0x03ffffff) |
+ ((*location + (v >> 2)) & 0x03ffffff);
+
+ return 0;
+}
+
+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ if (v % 4) {
+ pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ printk(KERN_ERR
+ "module %s: relocation overflow\n",
+ me->name);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
+
+ return 0;
+}
+
+static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ struct mips_hi16 *n;
+
+ /*
+ * We cannot relocate this one now because we don't know the value of
+ * the carry we need to add. Save the information, and let LO16 do the
+ * actual relocation.
+ */
+ n = kmalloc(sizeof *n, GFP_KERNEL);
+ if (!n)
+ return -ENOMEM;
+
+ n->addr = (Elf_Addr *)location;
+ n->value = v;
+ n->next = mips_hi16_list;
+ mips_hi16_list = n;
+
+ return 0;
+}
+
+static int apply_r_mips_hi16_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x8000LL) >> 16) & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_lo16_rel(struct module *me, u32 *location, Elf_Addr v)
+{
+ unsigned long insnlo = *location;
+ Elf_Addr val, vallo;
+
+ /* Sign extend the addend we extract from the lo insn. */
+ vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+
+ if (mips_hi16_list != NULL) {
+ struct mips_hi16 *l;
+
+ l = mips_hi16_list;
+ while (l != NULL) {
+ struct mips_hi16 *next;
+ unsigned long insn;
+
+ /*
+ * The value for the HI16 had best be the same.
+ */
+ if (v != l->value)
+ goto out_danger;
+
+ /*
+ * Do the HI16 relocation. Note that we actually don't
+ * need to know anything about the LO16 itself, except
+ * where to find the low 16 bits of the addend needed
+ * by the LO16.
+ */
+ insn = *l->addr;
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += v;
+
+ /*
+ * Account for the sign extension that will happen in
+ * the low bits.
+ */
+ val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+ insn = (insn & ~0xffff) | val;
+ *l->addr = insn;
+
+ next = l->next;
+ kfree(l);
+ l = next;
+ }
+
+ mips_hi16_list = NULL;
+ }
+
+ /*
+ * Ok, we're done with the HI16 relocs. Now deal with the LO16.
+ */
+ val = v + vallo;
+ insnlo = (insnlo & ~0xffff) | (val & 0xffff);
+ *location = insnlo;
+
+ return 0;
+
+out_danger:
+ pr_err("module %s: dangerous R_MIPS_LO16 REL relocation\n", me->name);
+
+ return -ENOEXEC;
+}
+
+static int apply_r_mips_lo16_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) | (v & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_64_rela(struct module *me, u32 *location, Elf_Addr v)
+{
+ *(Elf_Addr *)location = v;
+
+ return 0;
+}
+
+static int apply_r_mips_higher_rela(struct module *me, u32 *location,
+ Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x80008000LL) >> 32) & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_highest_rela(struct module *me, u32 *location,
+ Elf_Addr v)
+{
+ *location = (*location & 0xffff0000) |
+ ((((long long) v + 0x800080008000LL) >> 48) & 0xffff);
+
+ return 0;
+}
+
+static int (*reloc_handlers_rel[]) (struct module *me, u32 *location,
+ Elf_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32_rel,
+ [R_MIPS_26] = apply_r_mips_26_rel,
+ [R_MIPS_HI16] = apply_r_mips_hi16_rel,
+ [R_MIPS_LO16] = apply_r_mips_lo16_rel
+};
+
+static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
+ Elf_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32_rela,
+ [R_MIPS_26] = apply_r_mips_26_rela,
+ [R_MIPS_HI16] = apply_r_mips_hi16_rela,
+ [R_MIPS_LO16] = apply_r_mips_lo16_rela,
+ [R_MIPS_64] = apply_r_mips_64_rela,
+ [R_MIPS_HIGHER] = apply_r_mips_higher_rela,
+ [R_MIPS_HIGHEST] = apply_r_mips_highest_rela
+};
+
+int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *me)
+{
+ Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location;
+ unsigned int i;
+ Elf_Addr v;
+ int res;
+
+ pr_debug("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF_MIPS_R_SYM(rel[i]);
+ if (IS_ERR_VALUE(sym->st_value)) {
+ /* Ignore unresolved weak symbol */
+ if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
+ continue;
+ printk(KERN_WARNING "%s: Unknown symbol %s\n",
+ me->name, strtab + sym->st_name);
+ return -ENOENT;
+ }
+
+ v = sym->st_value;
+
+ res = reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
+int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec,
+ struct module *me)
+{
+ Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location;
+ unsigned int i;
+ Elf_Addr v;
+ int res;
+
+ pr_debug("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF_MIPS_R_SYM(rel[i]);
+ if (IS_ERR_VALUE(sym->st_value)) {
+ /* Ignore unresolved weak symbol */
+ if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
+ continue;
+ printk(KERN_WARNING "%s: Unknown symbol %s\n",
+ me->name, strtab + sym->st_name);
+ return -ENOENT;
+ }
+
+ v = sym->st_value + rel[i].r_addend;
+
+ res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
+/* Given an address, look for it in the module exception tables. */
+const struct exception_table_entry *search_module_dbetables(unsigned long addr)
+{
+ unsigned long flags;
+ const struct exception_table_entry *e = NULL;
+ struct mod_arch_specific *dbe;
+
+ spin_lock_irqsave(&dbe_lock, flags);
+ list_for_each_entry(dbe, &dbe_list, dbe_list) {
+ e = search_extable(dbe->dbe_start, dbe->dbe_end - 1, addr);
+ if (e)
+ break;
+ }
+ spin_unlock_irqrestore(&dbe_lock, flags);
+
+ /* Now, if we found one, we are running inside it now, hence
+ we cannot unload the module, hence no refcnt needed. */
+ return e;
+}
+
+/* Put in dbe list if necessary. */
+int module_finalize(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ struct module *me)
+{
+ const Elf_Shdr *s;
+ char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+ /* Make jump label nops. */
+ jump_label_apply_nops(me);
+
+ INIT_LIST_HEAD(&me->arch.dbe_list);
+ for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
+ if (strcmp("__dbe_table", secstrings + s->sh_name) != 0)
+ continue;
+ me->arch.dbe_start = (void *)s->sh_addr;
+ me->arch.dbe_end = (void *)s->sh_addr + s->sh_size;
+ spin_lock_irq(&dbe_lock);
+ list_add(&me->arch.dbe_list, &dbe_list);
+ spin_unlock_irq(&dbe_lock);
+ }
+ return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+ spin_lock_irq(&dbe_lock);
+ list_del(&mod->arch.dbe_list);
+ spin_unlock_irq(&dbe_lock);
+}
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
new file mode 100644
index 00000000..ce89c806
--- /dev/null
+++ b/arch/mips/kernel/octeon_switch.S
@@ -0,0 +1,502 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1994, 1995, 1996, by Andreas Busse
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ * written by Carsten Langgaard, carstenl@mips.com
+ */
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+
+#include <asm/asmmacro.h>
+
+/*
+ * Offset to the current process status flags, the first 32 bytes of the
+ * stack are not used.
+ */
+#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
+
+/*
+ * task_struct *resume(task_struct *prev, task_struct *next,
+ * struct thread_info *next_ti)
+ */
+ .align 7
+ LEAF(resume)
+ .set arch=octeon
+ mfc0 t1, CP0_STATUS
+ LONG_S t1, THREAD_STATUS(a0)
+ cpu_save_nonscratch a0
+ LONG_S ra, THREAD_REG31(a0)
+
+ /* check if we need to save COP2 registers */
+ PTR_L t2, TASK_THREAD_INFO(a0)
+ LONG_L t0, ST_OFF(t2)
+ bbit0 t0, 30, 1f
+
+ /* Disable COP2 in the stored process state */
+ li t1, ST0_CU2
+ xor t0, t1
+ LONG_S t0, ST_OFF(t2)
+
+ /* Enable COP2 so we can save it */
+ mfc0 t0, CP0_STATUS
+ or t0, t1
+ mtc0 t0, CP0_STATUS
+
+ /* Save COP2 */
+ daddu a0, THREAD_CP2
+ jal octeon_cop2_save
+ dsubu a0, THREAD_CP2
+
+ /* Disable COP2 now that we are done */
+ mfc0 t0, CP0_STATUS
+ li t1, ST0_CU2
+ xor t0, t1
+ mtc0 t0, CP0_STATUS
+
+1:
+#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
+ /* Check if we need to store CVMSEG state */
+ mfc0 t0, $11,7 /* CvmMemCtl */
+ bbit0 t0, 6, 3f /* Is user access enabled? */
+
+ /* Store the CVMSEG state */
+ /* Extract the size of CVMSEG */
+ andi t0, 0x3f
+ /* Multiply * (cache line size/sizeof(long)/2) */
+ sll t0, 7-LONGLOG-1
+ li t1, -32768 /* Base address of CVMSEG */
+ LONG_ADDI t2, a0, THREAD_CVMSEG /* Where to store CVMSEG to */
+ synciobdma
+2:
+ .set noreorder
+ LONG_L t8, 0(t1) /* Load from CVMSEG */
+ subu t0, 1 /* Decrement loop var */
+ LONG_L t9, LONGSIZE(t1)/* Load from CVMSEG */
+ LONG_ADDU t1, LONGSIZE*2 /* Increment loc in CVMSEG */
+ LONG_S t8, 0(t2) /* Store CVMSEG to thread storage */
+ LONG_ADDU t2, LONGSIZE*2 /* Increment loc in thread storage */
+ bnez t0, 2b /* Loop until we've copied it all */
+ LONG_S t9, -LONGSIZE(t2)/* Store CVMSEG to thread storage */
+ .set reorder
+
+ /* Disable access to CVMSEG */
+ mfc0 t0, $11,7 /* CvmMemCtl */
+ xori t0, t0, 0x40 /* Bit 6 is CVMSEG user enable */
+ mtc0 t0, $11,7 /* CvmMemCtl */
+#endif
+3:
+ /*
+ * The order of restoring the registers takes care of the race
+ * updating $28, $29 and kernelsp without disabling ints.
+ */
+ move $28, a2
+ cpu_restore_nonscratch a1
+
+#if (_THREAD_SIZE - 32) < 0x8000
+ PTR_ADDIU t0, $28, _THREAD_SIZE - 32
+#else
+ PTR_LI t0, _THREAD_SIZE - 32
+ PTR_ADDU t0, $28
+#endif
+ set_saved_sp t0, t1, t2
+
+ mfc0 t1, CP0_STATUS /* Do we really need this? */
+ li a3, 0xff01
+ and t1, a3
+ LONG_L a2, THREAD_STATUS(a1)
+ nor a3, $0, a3
+ and a2, a3
+ or a2, t1
+ mtc0 a2, CP0_STATUS
+ move v0, a0
+ jr ra
+ END(resume)
+
+/*
+ * void octeon_cop2_save(struct octeon_cop2_state *a0)
+ */
+ .align 7
+ LEAF(octeon_cop2_save)
+
+ dmfc0 t9, $9,7 /* CvmCtl register. */
+
+ /* Save the COP2 CRC state */
+ dmfc2 t0, 0x0201
+ dmfc2 t1, 0x0202
+ dmfc2 t2, 0x0200
+ sd t0, OCTEON_CP2_CRC_IV(a0)
+ sd t1, OCTEON_CP2_CRC_LENGTH(a0)
+ sd t2, OCTEON_CP2_CRC_POLY(a0)
+ /* Skip next instructions if CvmCtl[NODFA_CP2] set */
+ bbit1 t9, 28, 1f
+
+ /* Save the LLM state */
+ dmfc2 t0, 0x0402
+ dmfc2 t1, 0x040A
+ sd t0, OCTEON_CP2_LLM_DAT(a0)
+ sd t1, OCTEON_CP2_LLM_DAT+8(a0)
+
+1: bbit1 t9, 26, 3f /* done if CvmCtl[NOCRYPTO] set */
+
+ /* Save the COP2 crypto state */
+ /* this part is mostly common to both pass 1 and later revisions */
+ dmfc2 t0, 0x0084
+ dmfc2 t1, 0x0080
+ dmfc2 t2, 0x0081
+ dmfc2 t3, 0x0082
+ sd t0, OCTEON_CP2_3DES_IV(a0)
+ dmfc2 t0, 0x0088
+ sd t1, OCTEON_CP2_3DES_KEY(a0)
+ dmfc2 t1, 0x0111 /* only necessary for pass 1 */
+ sd t2, OCTEON_CP2_3DES_KEY+8(a0)
+ dmfc2 t2, 0x0102
+ sd t3, OCTEON_CP2_3DES_KEY+16(a0)
+ dmfc2 t3, 0x0103
+ sd t0, OCTEON_CP2_3DES_RESULT(a0)
+ dmfc2 t0, 0x0104
+ sd t1, OCTEON_CP2_AES_INP0(a0) /* only necessary for pass 1 */
+ dmfc2 t1, 0x0105
+ sd t2, OCTEON_CP2_AES_IV(a0)
+ dmfc2 t2, 0x0106
+ sd t3, OCTEON_CP2_AES_IV+8(a0)
+ dmfc2 t3, 0x0107
+ sd t0, OCTEON_CP2_AES_KEY(a0)
+ dmfc2 t0, 0x0110
+ sd t1, OCTEON_CP2_AES_KEY+8(a0)
+ dmfc2 t1, 0x0100
+ sd t2, OCTEON_CP2_AES_KEY+16(a0)
+ dmfc2 t2, 0x0101
+ sd t3, OCTEON_CP2_AES_KEY+24(a0)
+ mfc0 t3, $15,0 /* Get the processor ID register */
+ sd t0, OCTEON_CP2_AES_KEYLEN(a0)
+ li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */
+ sd t1, OCTEON_CP2_AES_RESULT(a0)
+ sd t2, OCTEON_CP2_AES_RESULT+8(a0)
+ /* Skip to the Pass1 version of the remainder of the COP2 state */
+ beq t3, t0, 2f
+
+ /* the non-pass1 state when !CvmCtl[NOCRYPTO] */
+ dmfc2 t1, 0x0240
+ dmfc2 t2, 0x0241
+ dmfc2 t3, 0x0242
+ dmfc2 t0, 0x0243
+ sd t1, OCTEON_CP2_HSH_DATW(a0)
+ dmfc2 t1, 0x0244
+ sd t2, OCTEON_CP2_HSH_DATW+8(a0)
+ dmfc2 t2, 0x0245
+ sd t3, OCTEON_CP2_HSH_DATW+16(a0)
+ dmfc2 t3, 0x0246
+ sd t0, OCTEON_CP2_HSH_DATW+24(a0)
+ dmfc2 t0, 0x0247
+ sd t1, OCTEON_CP2_HSH_DATW+32(a0)
+ dmfc2 t1, 0x0248
+ sd t2, OCTEON_CP2_HSH_DATW+40(a0)
+ dmfc2 t2, 0x0249
+ sd t3, OCTEON_CP2_HSH_DATW+48(a0)
+ dmfc2 t3, 0x024A
+ sd t0, OCTEON_CP2_HSH_DATW+56(a0)
+ dmfc2 t0, 0x024B
+ sd t1, OCTEON_CP2_HSH_DATW+64(a0)
+ dmfc2 t1, 0x024C
+ sd t2, OCTEON_CP2_HSH_DATW+72(a0)
+ dmfc2 t2, 0x024D
+ sd t3, OCTEON_CP2_HSH_DATW+80(a0)
+ dmfc2 t3, 0x024E
+ sd t0, OCTEON_CP2_HSH_DATW+88(a0)
+ dmfc2 t0, 0x0250
+ sd t1, OCTEON_CP2_HSH_DATW+96(a0)
+ dmfc2 t1, 0x0251
+ sd t2, OCTEON_CP2_HSH_DATW+104(a0)
+ dmfc2 t2, 0x0252
+ sd t3, OCTEON_CP2_HSH_DATW+112(a0)
+ dmfc2 t3, 0x0253
+ sd t0, OCTEON_CP2_HSH_IVW(a0)
+ dmfc2 t0, 0x0254
+ sd t1, OCTEON_CP2_HSH_IVW+8(a0)
+ dmfc2 t1, 0x0255
+ sd t2, OCTEON_CP2_HSH_IVW+16(a0)
+ dmfc2 t2, 0x0256
+ sd t3, OCTEON_CP2_HSH_IVW+24(a0)
+ dmfc2 t3, 0x0257
+ sd t0, OCTEON_CP2_HSH_IVW+32(a0)
+ dmfc2 t0, 0x0258
+ sd t1, OCTEON_CP2_HSH_IVW+40(a0)
+ dmfc2 t1, 0x0259
+ sd t2, OCTEON_CP2_HSH_IVW+48(a0)
+ dmfc2 t2, 0x025E
+ sd t3, OCTEON_CP2_HSH_IVW+56(a0)
+ dmfc2 t3, 0x025A
+ sd t0, OCTEON_CP2_GFM_MULT(a0)
+ dmfc2 t0, 0x025B
+ sd t1, OCTEON_CP2_GFM_MULT+8(a0)
+ sd t2, OCTEON_CP2_GFM_POLY(a0)
+ sd t3, OCTEON_CP2_GFM_RESULT(a0)
+ sd t0, OCTEON_CP2_GFM_RESULT+8(a0)
+ jr ra
+
+2: /* pass 1 special stuff when !CvmCtl[NOCRYPTO] */
+ dmfc2 t3, 0x0040
+ dmfc2 t0, 0x0041
+ dmfc2 t1, 0x0042
+ dmfc2 t2, 0x0043
+ sd t3, OCTEON_CP2_HSH_DATW(a0)
+ dmfc2 t3, 0x0044
+ sd t0, OCTEON_CP2_HSH_DATW+8(a0)
+ dmfc2 t0, 0x0045
+ sd t1, OCTEON_CP2_HSH_DATW+16(a0)
+ dmfc2 t1, 0x0046
+ sd t2, OCTEON_CP2_HSH_DATW+24(a0)
+ dmfc2 t2, 0x0048
+ sd t3, OCTEON_CP2_HSH_DATW+32(a0)
+ dmfc2 t3, 0x0049
+ sd t0, OCTEON_CP2_HSH_DATW+40(a0)
+ dmfc2 t0, 0x004A
+ sd t1, OCTEON_CP2_HSH_DATW+48(a0)
+ sd t2, OCTEON_CP2_HSH_IVW(a0)
+ sd t3, OCTEON_CP2_HSH_IVW+8(a0)
+ sd t0, OCTEON_CP2_HSH_IVW+16(a0)
+
+3: /* pass 1 or CvmCtl[NOCRYPTO] set */
+ jr ra
+ END(octeon_cop2_save)
+
+/*
+ * void octeon_cop2_restore(struct octeon_cop2_state *a0)
+ */
+ .align 7
+ .set push
+ .set noreorder
+ LEAF(octeon_cop2_restore)
+ /* First cache line was prefetched before the call */
+ pref 4, 128(a0)
+ dmfc0 t9, $9,7 /* CvmCtl register. */
+
+ pref 4, 256(a0)
+ ld t0, OCTEON_CP2_CRC_IV(a0)
+ pref 4, 384(a0)
+ ld t1, OCTEON_CP2_CRC_LENGTH(a0)
+ ld t2, OCTEON_CP2_CRC_POLY(a0)
+
+ /* Restore the COP2 CRC state */
+ dmtc2 t0, 0x0201
+ dmtc2 t1, 0x1202
+ bbit1 t9, 28, 2f /* Skip LLM if CvmCtl[NODFA_CP2] is set */
+ dmtc2 t2, 0x4200
+
+ /* Restore the LLM state */
+ ld t0, OCTEON_CP2_LLM_DAT(a0)
+ ld t1, OCTEON_CP2_LLM_DAT+8(a0)
+ dmtc2 t0, 0x0402
+ dmtc2 t1, 0x040A
+
+2:
+ bbit1 t9, 26, done_restore /* done if CvmCtl[NOCRYPTO] set */
+ nop
+
+ /* Restore the COP2 crypto state common to pass 1 and pass 2 */
+ ld t0, OCTEON_CP2_3DES_IV(a0)
+ ld t1, OCTEON_CP2_3DES_KEY(a0)
+ ld t2, OCTEON_CP2_3DES_KEY+8(a0)
+ dmtc2 t0, 0x0084
+ ld t0, OCTEON_CP2_3DES_KEY+16(a0)
+ dmtc2 t1, 0x0080
+ ld t1, OCTEON_CP2_3DES_RESULT(a0)
+ dmtc2 t2, 0x0081
+ ld t2, OCTEON_CP2_AES_INP0(a0) /* only really needed for pass 1 */
+ dmtc2 t0, 0x0082
+ ld t0, OCTEON_CP2_AES_IV(a0)
+ dmtc2 t1, 0x0098
+ ld t1, OCTEON_CP2_AES_IV+8(a0)
+ dmtc2 t2, 0x010A /* only really needed for pass 1 */
+ ld t2, OCTEON_CP2_AES_KEY(a0)
+ dmtc2 t0, 0x0102
+ ld t0, OCTEON_CP2_AES_KEY+8(a0)
+ dmtc2 t1, 0x0103
+ ld t1, OCTEON_CP2_AES_KEY+16(a0)
+ dmtc2 t2, 0x0104
+ ld t2, OCTEON_CP2_AES_KEY+24(a0)
+ dmtc2 t0, 0x0105
+ ld t0, OCTEON_CP2_AES_KEYLEN(a0)
+ dmtc2 t1, 0x0106
+ ld t1, OCTEON_CP2_AES_RESULT(a0)
+ dmtc2 t2, 0x0107
+ ld t2, OCTEON_CP2_AES_RESULT+8(a0)
+ mfc0 t3, $15,0 /* Get the processor ID register */
+ dmtc2 t0, 0x0110
+ li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */
+ dmtc2 t1, 0x0100
+ bne t0, t3, 3f /* Skip the next stuff for non-pass1 */
+ dmtc2 t2, 0x0101
+
+ /* this code is specific for pass 1 */
+ ld t0, OCTEON_CP2_HSH_DATW(a0)
+ ld t1, OCTEON_CP2_HSH_DATW+8(a0)
+ ld t2, OCTEON_CP2_HSH_DATW+16(a0)
+ dmtc2 t0, 0x0040
+ ld t0, OCTEON_CP2_HSH_DATW+24(a0)
+ dmtc2 t1, 0x0041
+ ld t1, OCTEON_CP2_HSH_DATW+32(a0)
+ dmtc2 t2, 0x0042
+ ld t2, OCTEON_CP2_HSH_DATW+40(a0)
+ dmtc2 t0, 0x0043
+ ld t0, OCTEON_CP2_HSH_DATW+48(a0)
+ dmtc2 t1, 0x0044
+ ld t1, OCTEON_CP2_HSH_IVW(a0)
+ dmtc2 t2, 0x0045
+ ld t2, OCTEON_CP2_HSH_IVW+8(a0)
+ dmtc2 t0, 0x0046
+ ld t0, OCTEON_CP2_HSH_IVW+16(a0)
+ dmtc2 t1, 0x0048
+ dmtc2 t2, 0x0049
+ b done_restore /* unconditional branch */
+ dmtc2 t0, 0x004A
+
+3: /* this is post-pass1 code */
+ ld t2, OCTEON_CP2_HSH_DATW(a0)
+ ld t0, OCTEON_CP2_HSH_DATW+8(a0)
+ ld t1, OCTEON_CP2_HSH_DATW+16(a0)
+ dmtc2 t2, 0x0240
+ ld t2, OCTEON_CP2_HSH_DATW+24(a0)
+ dmtc2 t0, 0x0241
+ ld t0, OCTEON_CP2_HSH_DATW+32(a0)
+ dmtc2 t1, 0x0242
+ ld t1, OCTEON_CP2_HSH_DATW+40(a0)
+ dmtc2 t2, 0x0243
+ ld t2, OCTEON_CP2_HSH_DATW+48(a0)
+ dmtc2 t0, 0x0244
+ ld t0, OCTEON_CP2_HSH_DATW+56(a0)
+ dmtc2 t1, 0x0245
+ ld t1, OCTEON_CP2_HSH_DATW+64(a0)
+ dmtc2 t2, 0x0246
+ ld t2, OCTEON_CP2_HSH_DATW+72(a0)
+ dmtc2 t0, 0x0247
+ ld t0, OCTEON_CP2_HSH_DATW+80(a0)
+ dmtc2 t1, 0x0248
+ ld t1, OCTEON_CP2_HSH_DATW+88(a0)
+ dmtc2 t2, 0x0249
+ ld t2, OCTEON_CP2_HSH_DATW+96(a0)
+ dmtc2 t0, 0x024A
+ ld t0, OCTEON_CP2_HSH_DATW+104(a0)
+ dmtc2 t1, 0x024B
+ ld t1, OCTEON_CP2_HSH_DATW+112(a0)
+ dmtc2 t2, 0x024C
+ ld t2, OCTEON_CP2_HSH_IVW(a0)
+ dmtc2 t0, 0x024D
+ ld t0, OCTEON_CP2_HSH_IVW+8(a0)
+ dmtc2 t1, 0x024E
+ ld t1, OCTEON_CP2_HSH_IVW+16(a0)
+ dmtc2 t2, 0x0250
+ ld t2, OCTEON_CP2_HSH_IVW+24(a0)
+ dmtc2 t0, 0x0251
+ ld t0, OCTEON_CP2_HSH_IVW+32(a0)
+ dmtc2 t1, 0x0252
+ ld t1, OCTEON_CP2_HSH_IVW+40(a0)
+ dmtc2 t2, 0x0253
+ ld t2, OCTEON_CP2_HSH_IVW+48(a0)
+ dmtc2 t0, 0x0254
+ ld t0, OCTEON_CP2_HSH_IVW+56(a0)
+ dmtc2 t1, 0x0255
+ ld t1, OCTEON_CP2_GFM_MULT(a0)
+ dmtc2 t2, 0x0256
+ ld t2, OCTEON_CP2_GFM_MULT+8(a0)
+ dmtc2 t0, 0x0257
+ ld t0, OCTEON_CP2_GFM_POLY(a0)
+ dmtc2 t1, 0x0258
+ ld t1, OCTEON_CP2_GFM_RESULT(a0)
+ dmtc2 t2, 0x0259
+ ld t2, OCTEON_CP2_GFM_RESULT+8(a0)
+ dmtc2 t0, 0x025E
+ dmtc2 t1, 0x025A
+ dmtc2 t2, 0x025B
+
+done_restore:
+ jr ra
+ nop
+ END(octeon_cop2_restore)
+ .set pop
+
+/*
+ * void octeon_mult_save()
+ * sp is assumed to point to a struct pt_regs
+ *
+ * NOTE: This is called in SAVE_SOME in stackframe.h. It can only
+ * safely modify k0 and k1.
+ */
+ .align 7
+ .set push
+ .set noreorder
+ LEAF(octeon_mult_save)
+ dmfc0 k0, $9,7 /* CvmCtl register. */
+ bbit1 k0, 27, 1f /* Skip CvmCtl[NOMUL] */
+ nop
+
+ /* Save the multiplier state */
+ v3mulu k0, $0, $0
+ v3mulu k1, $0, $0
+ sd k0, PT_MTP(sp) /* PT_MTP has P0 */
+ v3mulu k0, $0, $0
+ sd k1, PT_MTP+8(sp) /* PT_MTP+8 has P1 */
+ ori k1, $0, 1
+ v3mulu k1, k1, $0
+ sd k0, PT_MTP+16(sp) /* PT_MTP+16 has P2 */
+ v3mulu k0, $0, $0
+ sd k1, PT_MPL(sp) /* PT_MPL has MPL0 */
+ v3mulu k1, $0, $0
+ sd k0, PT_MPL+8(sp) /* PT_MPL+8 has MPL1 */
+ jr ra
+ sd k1, PT_MPL+16(sp) /* PT_MPL+16 has MPL2 */
+
+1: /* Resume here if CvmCtl[NOMUL] */
+ jr ra
+ END(octeon_mult_save)
+ .set pop
+
+/*
+ * void octeon_mult_restore()
+ * sp is assumed to point to a struct pt_regs
+ *
+ * NOTE: This is called in RESTORE_SOME in stackframe.h.
+ */
+ .align 7
+ .set push
+ .set noreorder
+ LEAF(octeon_mult_restore)
+ dmfc0 k1, $9,7 /* CvmCtl register. */
+ ld v0, PT_MPL(sp) /* MPL0 */
+ ld v1, PT_MPL+8(sp) /* MPL1 */
+ ld k0, PT_MPL+16(sp) /* MPL2 */
+ bbit1 k1, 27, 1f /* Skip CvmCtl[NOMUL] */
+ /* Normally falls through, so no time wasted here */
+ nop
+
+ /* Restore the multiplier state */
+ ld k1, PT_MTP+16(sp) /* P2 */
+ MTM0 v0 /* MPL0 */
+ ld v0, PT_MTP+8(sp) /* P1 */
+ MTM1 v1 /* MPL1 */
+ ld v1, PT_MTP(sp) /* P0 */
+ MTM2 k0 /* MPL2 */
+ MTP2 k1 /* P2 */
+ MTP1 v0 /* P1 */
+ jr ra
+ MTP0 v1 /* P0 */
+
+1: /* Resume here if CvmCtl[NOMUL] */
+ jr ra
+ nop
+ END(octeon_mult_restore)
+ .set pop
diff --git a/arch/mips/kernel/perf_event.c b/arch/mips/kernel/perf_event.c
new file mode 100644
index 00000000..a8244854
--- /dev/null
+++ b/arch/mips/kernel/perf_event.c
@@ -0,0 +1,588 @@
+/*
+ * Linux performance counter support for MIPS.
+ *
+ * Copyright (C) 2010 MIPS Technologies, Inc.
+ * Author: Deng-Cheng Zhu
+ *
+ * This code is based on the implementation for ARM, which is in turn
+ * based on the sparc64 perf event code and the x86 code. Performance
+ * counter access is based on the MIPS Oprofile code. And the callchain
+ * support references the code of MIPS stacktrace.c.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/uaccess.h>
+
+#include <asm/irq.h>
+#include <asm/irq_regs.h>
+#include <asm/stacktrace.h>
+#include <asm/time.h> /* For perf_irq */
+
+/* These are for 32bit counters. For 64bit ones, define them accordingly. */
+#define MAX_PERIOD ((1ULL << 32) - 1)
+#define VALID_COUNT 0x7fffffff
+#define TOTAL_BITS 32
+#define HIGHEST_BIT 31
+
+#define MIPS_MAX_HWEVENTS 4
+
+struct cpu_hw_events {
+ /* Array of events on this cpu. */
+ struct perf_event *events[MIPS_MAX_HWEVENTS];
+
+ /*
+ * Set the bit (indexed by the counter number) when the counter
+ * is used for an event.
+ */
+ unsigned long used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
+
+ /*
+ * The borrowed MSB for the performance counter. A MIPS performance
+ * counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit
+ * counters) as a factor of determining whether a counter overflow
+ * should be signaled. So here we use a separate MSB for each
+ * counter to make things easy.
+ */
+ unsigned long msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
+
+ /*
+ * Software copy of the control register for each performance counter.
+ * MIPS CPUs vary in performance counters. They use this differently,
+ * and even may not use it.
+ */
+ unsigned int saved_ctrl[MIPS_MAX_HWEVENTS];
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+ .saved_ctrl = {0},
+};
+
+/* The description of MIPS performance events. */
+struct mips_perf_event {
+ unsigned int event_id;
+ /*
+ * MIPS performance counters are indexed starting from 0.
+ * CNTR_EVEN indicates the indexes of the counters to be used are
+ * even numbers.
+ */
+ unsigned int cntr_mask;
+ #define CNTR_EVEN 0x55555555
+ #define CNTR_ODD 0xaaaaaaaa
+#ifdef CONFIG_MIPS_MT_SMP
+ enum {
+ T = 0,
+ V = 1,
+ P = 2,
+ } range;
+#else
+ #define T
+ #define V
+ #define P
+#endif
+};
+
+static struct mips_perf_event raw_event;
+static DEFINE_MUTEX(raw_event_mutex);
+
+#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+struct mips_pmu {
+ const char *name;
+ int irq;
+ irqreturn_t (*handle_irq)(int irq, void *dev);
+ int (*handle_shared_irq)(void);
+ void (*start)(void);
+ void (*stop)(void);
+ int (*alloc_counter)(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *hwc);
+ u64 (*read_counter)(unsigned int idx);
+ void (*write_counter)(unsigned int idx, u64 val);
+ void (*enable_event)(struct hw_perf_event *evt, int idx);
+ void (*disable_event)(int idx);
+ const struct mips_perf_event *(*map_raw_event)(u64 config);
+ const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
+ const struct mips_perf_event (*cache_event_map)
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+ unsigned int num_counters;
+};
+
+static const struct mips_pmu *mipspmu;
+
+static int
+mipspmu_event_set_period(struct perf_event *event,
+ struct hw_perf_event *hwc,
+ int idx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ s64 left = local64_read(&hwc->period_left);
+ s64 period = hwc->sample_period;
+ int ret = 0;
+ u64 uleft;
+ unsigned long flags;
+
+ if (unlikely(left <= -period)) {
+ left = period;
+ local64_set(&hwc->period_left, left);
+ hwc->last_period = period;
+ ret = 1;
+ }
+
+ if (unlikely(left <= 0)) {
+ left += period;
+ local64_set(&hwc->period_left, left);
+ hwc->last_period = period;
+ ret = 1;
+ }
+
+ if (left > (s64)MAX_PERIOD)
+ left = MAX_PERIOD;
+
+ local64_set(&hwc->prev_count, (u64)-left);
+
+ local_irq_save(flags);
+ uleft = (u64)(-left) & MAX_PERIOD;
+ uleft > VALID_COUNT ?
+ set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs);
+ mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT);
+ local_irq_restore(flags);
+
+ perf_event_update_userpage(event);
+
+ return ret;
+}
+
+static void mipspmu_event_update(struct perf_event *event,
+ struct hw_perf_event *hwc,
+ int idx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ unsigned long flags;
+ int shift = 64 - TOTAL_BITS;
+ s64 prev_raw_count, new_raw_count;
+ u64 delta;
+
+again:
+ prev_raw_count = local64_read(&hwc->prev_count);
+ local_irq_save(flags);
+ /* Make the counter value be a "real" one. */
+ new_raw_count = mipspmu->read_counter(idx);
+ if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) {
+ new_raw_count &= VALID_COUNT;
+ clear_bit(idx, cpuc->msbs);
+ } else
+ new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT);
+ local_irq_restore(flags);
+
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count)
+ goto again;
+
+ delta = (new_raw_count << shift) - (prev_raw_count << shift);
+ delta >>= shift;
+
+ local64_add(delta, &event->count);
+ local64_sub(delta, &hwc->period_left);
+
+ return;
+}
+
+static void mipspmu_start(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (!mipspmu)
+ return;
+
+ if (flags & PERF_EF_RELOAD)
+ WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+
+ hwc->state = 0;
+
+ /* Set the period for the event. */
+ mipspmu_event_set_period(event, hwc, hwc->idx);
+
+ /* Enable the event. */
+ mipspmu->enable_event(hwc, hwc->idx);
+}
+
+static void mipspmu_stop(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (!mipspmu)
+ return;
+
+ if (!(hwc->state & PERF_HES_STOPPED)) {
+ /* We are working on a local event. */
+ mipspmu->disable_event(hwc->idx);
+ barrier();
+ mipspmu_event_update(event, hwc, hwc->idx);
+ hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ }
+}
+
+static int mipspmu_add(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx;
+ int err = 0;
+
+ perf_pmu_disable(event->pmu);
+
+ /* To look for a free counter for this event. */
+ idx = mipspmu->alloc_counter(cpuc, hwc);
+ if (idx < 0) {
+ err = idx;
+ goto out;
+ }
+
+ /*
+ * If there is an event in the counter we are going to use then
+ * make sure it is disabled.
+ */
+ event->hw.idx = idx;
+ mipspmu->disable_event(idx);
+ cpuc->events[idx] = event;
+
+ hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ if (flags & PERF_EF_START)
+ mipspmu_start(event, PERF_EF_RELOAD);
+
+ /* Propagate our changes to the userspace mapping. */
+ perf_event_update_userpage(event);
+
+out:
+ perf_pmu_enable(event->pmu);
+ return err;
+}
+
+static void mipspmu_del(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+
+ WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+ mipspmu_stop(event, PERF_EF_UPDATE);
+ cpuc->events[idx] = NULL;
+ clear_bit(idx, cpuc->used_mask);
+
+ perf_event_update_userpage(event);
+}
+
+static void mipspmu_read(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ /* Don't read disabled counters! */
+ if (hwc->idx < 0)
+ return;
+
+ mipspmu_event_update(event, hwc, hwc->idx);
+}
+
+static void mipspmu_enable(struct pmu *pmu)
+{
+ if (mipspmu)
+ mipspmu->start();
+}
+
+static void mipspmu_disable(struct pmu *pmu)
+{
+ if (mipspmu)
+ mipspmu->stop();
+}
+
+static atomic_t active_events = ATOMIC_INIT(0);
+static DEFINE_MUTEX(pmu_reserve_mutex);
+static int (*save_perf_irq)(void);
+
+static int mipspmu_get_irq(void)
+{
+ int err;
+
+ if (mipspmu->irq >= 0) {
+ /* Request my own irq handler. */
+ err = request_irq(mipspmu->irq, mipspmu->handle_irq,
+ IRQF_DISABLED | IRQF_NOBALANCING,
+ "mips_perf_pmu", NULL);
+ if (err) {
+ pr_warning("Unable to request IRQ%d for MIPS "
+ "performance counters!\n", mipspmu->irq);
+ }
+ } else if (cp0_perfcount_irq < 0) {
+ /*
+ * We are sharing the irq number with the timer interrupt.
+ */
+ save_perf_irq = perf_irq;
+ perf_irq = mipspmu->handle_shared_irq;
+ err = 0;
+ } else {
+ pr_warning("The platform hasn't properly defined its "
+ "interrupt controller.\n");
+ err = -ENOENT;
+ }
+
+ return err;
+}
+
+static void mipspmu_free_irq(void)
+{
+ if (mipspmu->irq >= 0)
+ free_irq(mipspmu->irq, NULL);
+ else if (cp0_perfcount_irq < 0)
+ perf_irq = save_perf_irq;
+}
+
+/*
+ * mipsxx/rm9000/loongson2 have different performance counters, they have
+ * specific low-level init routines.
+ */
+static void reset_counters(void *arg);
+static int __hw_perf_event_init(struct perf_event *event);
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+ if (atomic_dec_and_mutex_lock(&active_events,
+ &pmu_reserve_mutex)) {
+ /*
+ * We must not call the destroy function with interrupts
+ * disabled.
+ */
+ on_each_cpu(reset_counters,
+ (void *)(long)mipspmu->num_counters, 1);
+ mipspmu_free_irq();
+ mutex_unlock(&pmu_reserve_mutex);
+ }
+}
+
+static int mipspmu_event_init(struct perf_event *event)
+{
+ int err = 0;
+
+ switch (event->attr.type) {
+ case PERF_TYPE_RAW:
+ case PERF_TYPE_HARDWARE:
+ case PERF_TYPE_HW_CACHE:
+ break;
+
+ default:
+ return -ENOENT;
+ }
+
+ if (!mipspmu || event->cpu >= nr_cpumask_bits ||
+ (event->cpu >= 0 && !cpu_online(event->cpu)))
+ return -ENODEV;
+
+ if (!atomic_inc_not_zero(&active_events)) {
+ if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
+ atomic_dec(&active_events);
+ return -ENOSPC;
+ }
+
+ mutex_lock(&pmu_reserve_mutex);
+ if (atomic_read(&active_events) == 0)
+ err = mipspmu_get_irq();
+
+ if (!err)
+ atomic_inc(&active_events);
+ mutex_unlock(&pmu_reserve_mutex);
+ }
+
+ if (err)
+ return err;
+
+ err = __hw_perf_event_init(event);
+ if (err)
+ hw_perf_event_destroy(event);
+
+ return err;
+}
+
+static struct pmu pmu = {
+ .pmu_enable = mipspmu_enable,
+ .pmu_disable = mipspmu_disable,
+ .event_init = mipspmu_event_init,
+ .add = mipspmu_add,
+ .del = mipspmu_del,
+ .start = mipspmu_start,
+ .stop = mipspmu_stop,
+ .read = mipspmu_read,
+};
+
+static inline unsigned int
+mipspmu_perf_event_encode(const struct mips_perf_event *pev)
+{
+/*
+ * Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for
+ * event_id.
+ */
+#ifdef CONFIG_MIPS_MT_SMP
+ return ((unsigned int)pev->range << 24) |
+ (pev->cntr_mask & 0xffff00) |
+ (pev->event_id & 0xff);
+#else
+ return (pev->cntr_mask & 0xffff00) |
+ (pev->event_id & 0xff);
+#endif
+}
+
+static const struct mips_perf_event *
+mipspmu_map_general_event(int idx)
+{
+ const struct mips_perf_event *pev;
+
+ pev = ((*mipspmu->general_event_map)[idx].event_id ==
+ UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) :
+ &(*mipspmu->general_event_map)[idx]);
+
+ return pev;
+}
+
+static const struct mips_perf_event *
+mipspmu_map_cache_event(u64 config)
+{
+ unsigned int cache_type, cache_op, cache_result;
+ const struct mips_perf_event *pev;
+
+ cache_type = (config >> 0) & 0xff;
+ if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+ return ERR_PTR(-EINVAL);
+
+ cache_op = (config >> 8) & 0xff;
+ if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+ return ERR_PTR(-EINVAL);
+
+ cache_result = (config >> 16) & 0xff;
+ if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+ return ERR_PTR(-EINVAL);
+
+ pev = &((*mipspmu->cache_event_map)
+ [cache_type]
+ [cache_op]
+ [cache_result]);
+
+ if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ return pev;
+
+}
+
+static int validate_event(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct hw_perf_event fake_hwc = event->hw;
+
+ /* Allow mixed event group. So return 1 to pass validation. */
+ if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF)
+ return 1;
+
+ return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0;
+}
+
+static int validate_group(struct perf_event *event)
+{
+ struct perf_event *sibling, *leader = event->group_leader;
+ struct cpu_hw_events fake_cpuc;
+
+ memset(&fake_cpuc, 0, sizeof(fake_cpuc));
+
+ if (!validate_event(&fake_cpuc, leader))
+ return -ENOSPC;
+
+ list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ if (!validate_event(&fake_cpuc, sibling))
+ return -ENOSPC;
+ }
+
+ if (!validate_event(&fake_cpuc, event))
+ return -ENOSPC;
+
+ return 0;
+}
+
+/* This is needed by specific irq handlers in perf_event_*.c */
+static void
+handle_associated_event(struct cpu_hw_events *cpuc,
+ int idx, struct perf_sample_data *data, struct pt_regs *regs)
+{
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc = &event->hw;
+
+ mipspmu_event_update(event, hwc, idx);
+ data->period = event->hw.last_period;
+ if (!mipspmu_event_set_period(event, hwc, idx))
+ return;
+
+ if (perf_event_overflow(event, 0, data, regs))
+ mipspmu->disable_event(idx);
+}
+
+#include "perf_event_mipsxx.c"
+
+/* Callchain handling code. */
+
+/*
+ * Leave userspace callchain empty for now. When we find a way to trace
+ * the user stack callchains, we add here.
+ */
+void perf_callchain_user(struct perf_callchain_entry *entry,
+ struct pt_regs *regs)
+{
+}
+
+static void save_raw_perf_callchain(struct perf_callchain_entry *entry,
+ unsigned long reg29)
+{
+ unsigned long *sp = (unsigned long *)reg29;
+ unsigned long addr;
+
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ if (__kernel_text_address(addr)) {
+ perf_callchain_store(entry, addr);
+ if (entry->nr >= PERF_MAX_STACK_DEPTH)
+ break;
+ }
+ }
+}
+
+void perf_callchain_kernel(struct perf_callchain_entry *entry,
+ struct pt_regs *regs)
+{
+ unsigned long sp = regs->regs[29];
+#ifdef CONFIG_KALLSYMS
+ unsigned long ra = regs->regs[31];
+ unsigned long pc = regs->cp0_epc;
+
+ if (raw_show_trace || !__kernel_text_address(pc)) {
+ unsigned long stack_page =
+ (unsigned long)task_stack_page(current);
+ if (stack_page && sp >= stack_page &&
+ sp <= stack_page + THREAD_SIZE - 32)
+ save_raw_perf_callchain(entry, sp);
+ return;
+ }
+ do {
+ perf_callchain_store(entry, pc);
+ if (entry->nr >= PERF_MAX_STACK_DEPTH)
+ break;
+ pc = unwind_stack(current, &sp, pc, &ra);
+ } while (pc);
+#else
+ save_raw_perf_callchain(entry, sp);
+#endif
+}
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
new file mode 100644
index 00000000..75266ff4
--- /dev/null
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -0,0 +1,1054 @@
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) || \
+ defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_SB1)
+
+#define M_CONFIG1_PC (1 << 4)
+
+#define M_PERFCTL_EXL (1UL << 0)
+#define M_PERFCTL_KERNEL (1UL << 1)
+#define M_PERFCTL_SUPERVISOR (1UL << 2)
+#define M_PERFCTL_USER (1UL << 3)
+#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4)
+#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
+#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
+#define M_PERFCTL_MT_EN(filter) ((filter) << 20)
+#define M_TC_EN_ALL M_PERFCTL_MT_EN(0)
+#define M_TC_EN_VPE M_PERFCTL_MT_EN(1)
+#define M_TC_EN_TC M_PERFCTL_MT_EN(2)
+#define M_PERFCTL_TCID(tcid) ((tcid) << 22)
+#define M_PERFCTL_WIDE (1UL << 30)
+#define M_PERFCTL_MORE (1UL << 31)
+
+#define M_PERFCTL_COUNT_EVENT_WHENEVER (M_PERFCTL_EXL | \
+ M_PERFCTL_KERNEL | \
+ M_PERFCTL_USER | \
+ M_PERFCTL_SUPERVISOR | \
+ M_PERFCTL_INTERRUPT_ENABLE)
+
+#ifdef CONFIG_MIPS_MT_SMP
+#define M_PERFCTL_CONFIG_MASK 0x3fff801f
+#else
+#define M_PERFCTL_CONFIG_MASK 0x1f
+#endif
+#define M_PERFCTL_EVENT_MASK 0xfe0
+
+#define M_COUNTER_OVERFLOW (1UL << 31)
+
+#ifdef CONFIG_MIPS_MT_SMP
+static int cpu_has_mipsmt_pertccounters;
+
+/*
+ * FIXME: For VSMP, vpe_id() is redefined for Perf-events, because
+ * cpu_data[cpuid].vpe_id reports 0 for _both_ CPUs.
+ */
+#if defined(CONFIG_HW_PERF_EVENTS)
+#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
+ 0 : smp_processor_id())
+#else
+#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
+ 0 : cpu_data[smp_processor_id()].vpe_id)
+#endif
+
+/* Copied from op_model_mipsxx.c */
+static inline unsigned int vpe_shift(void)
+{
+ if (num_possible_cpus() > 1)
+ return 1;
+
+ return 0;
+}
+#else /* !CONFIG_MIPS_MT_SMP */
+#define vpe_id() 0
+
+static inline unsigned int vpe_shift(void)
+{
+ return 0;
+}
+#endif /* CONFIG_MIPS_MT_SMP */
+
+static inline unsigned int
+counters_total_to_per_cpu(unsigned int counters)
+{
+ return counters >> vpe_shift();
+}
+
+static inline unsigned int
+counters_per_cpu_to_total(unsigned int counters)
+{
+ return counters << vpe_shift();
+}
+
+#define __define_perf_accessors(r, n, np) \
+ \
+static inline unsigned int r_c0_ ## r ## n(void) \
+{ \
+ unsigned int cpu = vpe_id(); \
+ \
+ switch (cpu) { \
+ case 0: \
+ return read_c0_ ## r ## n(); \
+ case 1: \
+ return read_c0_ ## r ## np(); \
+ default: \
+ BUG(); \
+ } \
+ return 0; \
+} \
+ \
+static inline void w_c0_ ## r ## n(unsigned int value) \
+{ \
+ unsigned int cpu = vpe_id(); \
+ \
+ switch (cpu) { \
+ case 0: \
+ write_c0_ ## r ## n(value); \
+ return; \
+ case 1: \
+ write_c0_ ## r ## np(value); \
+ return; \
+ default: \
+ BUG(); \
+ } \
+ return; \
+} \
+
+__define_perf_accessors(perfcntr, 0, 2)
+__define_perf_accessors(perfcntr, 1, 3)
+__define_perf_accessors(perfcntr, 2, 0)
+__define_perf_accessors(perfcntr, 3, 1)
+
+__define_perf_accessors(perfctrl, 0, 2)
+__define_perf_accessors(perfctrl, 1, 3)
+__define_perf_accessors(perfctrl, 2, 0)
+__define_perf_accessors(perfctrl, 3, 1)
+
+static inline int __n_counters(void)
+{
+ if (!(read_c0_config1() & M_CONFIG1_PC))
+ return 0;
+ if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
+ return 1;
+ if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
+ return 2;
+ if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
+ return 3;
+
+ return 4;
+}
+
+static inline int n_counters(void)
+{
+ int counters;
+
+ switch (current_cpu_type()) {
+ case CPU_R10000:
+ counters = 2;
+ break;
+
+ case CPU_R12000:
+ case CPU_R14000:
+ counters = 4;
+ break;
+
+ default:
+ counters = __n_counters();
+ }
+
+ return counters;
+}
+
+static void reset_counters(void *arg)
+{
+ int counters = (int)(long)arg;
+ switch (counters) {
+ case 4:
+ w_c0_perfctrl3(0);
+ w_c0_perfcntr3(0);
+ case 3:
+ w_c0_perfctrl2(0);
+ w_c0_perfcntr2(0);
+ case 2:
+ w_c0_perfctrl1(0);
+ w_c0_perfcntr1(0);
+ case 1:
+ w_c0_perfctrl0(0);
+ w_c0_perfcntr0(0);
+ }
+}
+
+static inline u64
+mipsxx_pmu_read_counter(unsigned int idx)
+{
+ switch (idx) {
+ case 0:
+ return r_c0_perfcntr0();
+ case 1:
+ return r_c0_perfcntr1();
+ case 2:
+ return r_c0_perfcntr2();
+ case 3:
+ return r_c0_perfcntr3();
+ default:
+ WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+ return 0;
+ }
+}
+
+static inline void
+mipsxx_pmu_write_counter(unsigned int idx, u64 val)
+{
+ switch (idx) {
+ case 0:
+ w_c0_perfcntr0(val);
+ return;
+ case 1:
+ w_c0_perfcntr1(val);
+ return;
+ case 2:
+ w_c0_perfcntr2(val);
+ return;
+ case 3:
+ w_c0_perfcntr3(val);
+ return;
+ }
+}
+
+static inline unsigned int
+mipsxx_pmu_read_control(unsigned int idx)
+{
+ switch (idx) {
+ case 0:
+ return r_c0_perfctrl0();
+ case 1:
+ return r_c0_perfctrl1();
+ case 2:
+ return r_c0_perfctrl2();
+ case 3:
+ return r_c0_perfctrl3();
+ default:
+ WARN_ONCE(1, "Invalid performance counter number (%d)\n", idx);
+ return 0;
+ }
+}
+
+static inline void
+mipsxx_pmu_write_control(unsigned int idx, unsigned int val)
+{
+ switch (idx) {
+ case 0:
+ w_c0_perfctrl0(val);
+ return;
+ case 1:
+ w_c0_perfctrl1(val);
+ return;
+ case 2:
+ w_c0_perfctrl2(val);
+ return;
+ case 3:
+ w_c0_perfctrl3(val);
+ return;
+ }
+}
+
+#ifdef CONFIG_MIPS_MT_SMP
+static DEFINE_RWLOCK(pmuint_rwlock);
+#endif
+
+/* 24K/34K/1004K cores can share the same event map. */
+static const struct mips_perf_event mipsxxcore_event_map
+ [PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
+ [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
+ [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID },
+ [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID },
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x02, CNTR_EVEN, T },
+ [PERF_COUNT_HW_BRANCH_MISSES] = { 0x02, CNTR_ODD, T },
+ [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
+};
+
+/* 74K core has different branch event code. */
+static const struct mips_perf_event mipsxx74Kcore_event_map
+ [PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN | CNTR_ODD, P },
+ [PERF_COUNT_HW_INSTRUCTIONS] = { 0x01, CNTR_EVEN | CNTR_ODD, T },
+ [PERF_COUNT_HW_CACHE_REFERENCES] = { UNSUPPORTED_PERF_EVENT_ID },
+ [PERF_COUNT_HW_CACHE_MISSES] = { UNSUPPORTED_PERF_EVENT_ID },
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x27, CNTR_EVEN, T },
+ [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T },
+ [PERF_COUNT_HW_BUS_CYCLES] = { UNSUPPORTED_PERF_EVENT_ID },
+};
+
+/* 24K/34K/1004K cores can share the same cache event map. */
+static const struct mips_perf_event mipsxxcore_cache_map
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+ /*
+ * Like some other architectures (e.g. ARM), the performance
+ * counters don't differentiate between read and write
+ * accesses/misses, so this isn't strictly correct, but it's the
+ * best we can do. Writes and reads get combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x0a, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x0b, CNTR_EVEN | CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x0a, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x0b, CNTR_EVEN | CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x09, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x09, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x09, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x09, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { 0x14, CNTR_EVEN, T },
+ /*
+ * Note that MIPS has only "hit" events countable for
+ * the prefetch operation.
+ */
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x15, CNTR_ODD, P },
+ [C(RESULT_MISS)] = { 0x16, CNTR_EVEN, P },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x15, CNTR_ODD, P },
+ [C(RESULT_MISS)] = { 0x16, CNTR_EVEN, P },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(DTLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x05, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x05, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x05, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x05, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(BPU)] = {
+ /* Using the same code for *HW_BRANCH* */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x02, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+};
+
+/* 74K core has completely different cache event map. */
+static const struct mips_perf_event mipsxx74Kcore_cache_map
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+ /*
+ * Like some other architectures (e.g. ARM), the performance
+ * counters don't differentiate between read and write
+ * accesses/misses, so this isn't strictly correct, but it's the
+ * best we can do. Writes and reads get combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x17, CNTR_ODD, T },
+ [C(RESULT_MISS)] = { 0x18, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x17, CNTR_ODD, T },
+ [C(RESULT_MISS)] = { 0x18, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x06, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x06, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { 0x34, CNTR_EVEN, T },
+ /*
+ * Note that MIPS has only "hit" events countable for
+ * the prefetch operation.
+ */
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(LL)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P },
+ [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x1c, CNTR_ODD, P },
+ [C(RESULT_MISS)] = { 0x1d, CNTR_EVEN | CNTR_ODD, P },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(DTLB)] = {
+ /* 74K core does not have specific DTLB events. */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(ITLB)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x04, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x04, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x04, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x04, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+[C(BPU)] = {
+ /* Using the same code for *HW_BRANCH* */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = { 0x27, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x27, CNTR_ODD, T },
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = { 0x27, CNTR_EVEN, T },
+ [C(RESULT_MISS)] = { 0x27, CNTR_ODD, T },
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ [C(RESULT_MISS)] = { UNSUPPORTED_PERF_EVENT_ID },
+ },
+},
+};
+
+#ifdef CONFIG_MIPS_MT_SMP
+static void
+check_and_calc_range(struct perf_event *event,
+ const struct mips_perf_event *pev)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (event->cpu >= 0) {
+ if (pev->range > V) {
+ /*
+ * The user selected an event that is processor
+ * wide, while expecting it to be VPE wide.
+ */
+ hwc->config_base |= M_TC_EN_ALL;
+ } else {
+ /*
+ * FIXME: cpu_data[event->cpu].vpe_id reports 0
+ * for both CPUs.
+ */
+ hwc->config_base |= M_PERFCTL_VPEID(event->cpu);
+ hwc->config_base |= M_TC_EN_VPE;
+ }
+ } else
+ hwc->config_base |= M_TC_EN_ALL;
+}
+#else
+static void
+check_and_calc_range(struct perf_event *event,
+ const struct mips_perf_event *pev)
+{
+}
+#endif
+
+static int __hw_perf_event_init(struct perf_event *event)
+{
+ struct perf_event_attr *attr = &event->attr;
+ struct hw_perf_event *hwc = &event->hw;
+ const struct mips_perf_event *pev;
+ int err;
+
+ /* Returning MIPS event descriptor for generic perf event. */
+ if (PERF_TYPE_HARDWARE == event->attr.type) {
+ if (event->attr.config >= PERF_COUNT_HW_MAX)
+ return -EINVAL;
+ pev = mipspmu_map_general_event(event->attr.config);
+ } else if (PERF_TYPE_HW_CACHE == event->attr.type) {
+ pev = mipspmu_map_cache_event(event->attr.config);
+ } else if (PERF_TYPE_RAW == event->attr.type) {
+ /* We are working on the global raw event. */
+ mutex_lock(&raw_event_mutex);
+ pev = mipspmu->map_raw_event(event->attr.config);
+ } else {
+ /* The event type is not (yet) supported. */
+ return -EOPNOTSUPP;
+ }
+
+ if (IS_ERR(pev)) {
+ if (PERF_TYPE_RAW == event->attr.type)
+ mutex_unlock(&raw_event_mutex);
+ return PTR_ERR(pev);
+ }
+
+ /*
+ * We allow max flexibility on how each individual counter shared
+ * by the single CPU operates (the mode exclusion and the range).
+ */
+ hwc->config_base = M_PERFCTL_INTERRUPT_ENABLE;
+
+ /* Calculate range bits and validate it. */
+ if (num_possible_cpus() > 1)
+ check_and_calc_range(event, pev);
+
+ hwc->event_base = mipspmu_perf_event_encode(pev);
+ if (PERF_TYPE_RAW == event->attr.type)
+ mutex_unlock(&raw_event_mutex);
+
+ if (!attr->exclude_user)
+ hwc->config_base |= M_PERFCTL_USER;
+ if (!attr->exclude_kernel) {
+ hwc->config_base |= M_PERFCTL_KERNEL;
+ /* MIPS kernel mode: KSU == 00b || EXL == 1 || ERL == 1 */
+ hwc->config_base |= M_PERFCTL_EXL;
+ }
+ if (!attr->exclude_hv)
+ hwc->config_base |= M_PERFCTL_SUPERVISOR;
+
+ hwc->config_base &= M_PERFCTL_CONFIG_MASK;
+ /*
+ * The event can belong to another cpu. We do not assign a local
+ * counter for it for now.
+ */
+ hwc->idx = -1;
+ hwc->config = 0;
+
+ if (!hwc->sample_period) {
+ hwc->sample_period = MAX_PERIOD;
+ hwc->last_period = hwc->sample_period;
+ local64_set(&hwc->period_left, hwc->sample_period);
+ }
+
+ err = 0;
+ if (event->group_leader != event) {
+ err = validate_group(event);
+ if (err)
+ return -EINVAL;
+ }
+
+ event->destroy = hw_perf_event_destroy;
+
+ return err;
+}
+
+static void pause_local_counters(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int counters = mipspmu->num_counters;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ switch (counters) {
+ case 4:
+ cpuc->saved_ctrl[3] = r_c0_perfctrl3();
+ w_c0_perfctrl3(cpuc->saved_ctrl[3] &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+ case 3:
+ cpuc->saved_ctrl[2] = r_c0_perfctrl2();
+ w_c0_perfctrl2(cpuc->saved_ctrl[2] &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+ case 2:
+ cpuc->saved_ctrl[1] = r_c0_perfctrl1();
+ w_c0_perfctrl1(cpuc->saved_ctrl[1] &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+ case 1:
+ cpuc->saved_ctrl[0] = r_c0_perfctrl0();
+ w_c0_perfctrl0(cpuc->saved_ctrl[0] &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER);
+ }
+ local_irq_restore(flags);
+}
+
+static void resume_local_counters(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ int counters = mipspmu->num_counters;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ switch (counters) {
+ case 4:
+ w_c0_perfctrl3(cpuc->saved_ctrl[3]);
+ case 3:
+ w_c0_perfctrl2(cpuc->saved_ctrl[2]);
+ case 2:
+ w_c0_perfctrl1(cpuc->saved_ctrl[1]);
+ case 1:
+ w_c0_perfctrl0(cpuc->saved_ctrl[0]);
+ }
+ local_irq_restore(flags);
+}
+
+static int mipsxx_pmu_handle_shared_irq(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct perf_sample_data data;
+ unsigned int counters = mipspmu->num_counters;
+ unsigned int counter;
+ int handled = IRQ_NONE;
+ struct pt_regs *regs;
+
+ if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26)))
+ return handled;
+
+ /*
+ * First we pause the local counters, so that when we are locked
+ * here, the counters are all paused. When it gets locked due to
+ * perf_disable(), the timer interrupt handler will be delayed.
+ *
+ * See also mipsxx_pmu_start().
+ */
+ pause_local_counters();
+#ifdef CONFIG_MIPS_MT_SMP
+ read_lock(&pmuint_rwlock);
+#endif
+
+ regs = get_irq_regs();
+
+ perf_sample_data_init(&data, 0);
+
+ switch (counters) {
+#define HANDLE_COUNTER(n) \
+ case n + 1: \
+ if (test_bit(n, cpuc->used_mask)) { \
+ counter = r_c0_perfcntr ## n(); \
+ if (counter & M_COUNTER_OVERFLOW) { \
+ w_c0_perfcntr ## n(counter & \
+ VALID_COUNT); \
+ if (test_and_change_bit(n, cpuc->msbs)) \
+ handle_associated_event(cpuc, \
+ n, &data, regs); \
+ handled = IRQ_HANDLED; \
+ } \
+ }
+ HANDLE_COUNTER(3)
+ HANDLE_COUNTER(2)
+ HANDLE_COUNTER(1)
+ HANDLE_COUNTER(0)
+ }
+
+ /*
+ * Do all the work for the pending perf events. We can do this
+ * in here because the performance counter interrupt is a regular
+ * interrupt, not NMI.
+ */
+ if (handled == IRQ_HANDLED)
+ irq_work_run();
+
+#ifdef CONFIG_MIPS_MT_SMP
+ read_unlock(&pmuint_rwlock);
+#endif
+ resume_local_counters();
+ return handled;
+}
+
+static irqreturn_t
+mipsxx_pmu_handle_irq(int irq, void *dev)
+{
+ return mipsxx_pmu_handle_shared_irq();
+}
+
+static void mipsxx_pmu_start(void)
+{
+#ifdef CONFIG_MIPS_MT_SMP
+ write_unlock(&pmuint_rwlock);
+#endif
+ resume_local_counters();
+}
+
+/*
+ * MIPS performance counters can be per-TC. The control registers can
+ * not be directly accessed across CPUs. Hence if we want to do global
+ * control, we need cross CPU calls. on_each_cpu() can help us, but we
+ * can not make sure this function is called with interrupts enabled. So
+ * here we pause local counters and then grab a rwlock and leave the
+ * counters on other CPUs alone. If any counter interrupt raises while
+ * we own the write lock, simply pause local counters on that CPU and
+ * spin in the handler. Also we know we won't be switched to another
+ * CPU after pausing local counters and before grabbing the lock.
+ */
+static void mipsxx_pmu_stop(void)
+{
+ pause_local_counters();
+#ifdef CONFIG_MIPS_MT_SMP
+ write_lock(&pmuint_rwlock);
+#endif
+}
+
+static int
+mipsxx_pmu_alloc_counter(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *hwc)
+{
+ int i;
+
+ /*
+ * We only need to care the counter mask. The range has been
+ * checked definitely.
+ */
+ unsigned long cntr_mask = (hwc->event_base >> 8) & 0xffff;
+
+ for (i = mipspmu->num_counters - 1; i >= 0; i--) {
+ /*
+ * Note that some MIPS perf events can be counted by both
+ * even and odd counters, wheresas many other are only by
+ * even _or_ odd counters. This introduces an issue that
+ * when the former kind of event takes the counter the
+ * latter kind of event wants to use, then the "counter
+ * allocation" for the latter event will fail. In fact if
+ * they can be dynamically swapped, they both feel happy.
+ * But here we leave this issue alone for now.
+ */
+ if (test_bit(i, &cntr_mask) &&
+ !test_and_set_bit(i, cpuc->used_mask))
+ return i;
+ }
+
+ return -EAGAIN;
+}
+
+static void
+mipsxx_pmu_enable_event(struct hw_perf_event *evt, int idx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ unsigned long flags;
+
+ WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+ local_irq_save(flags);
+ cpuc->saved_ctrl[idx] = M_PERFCTL_EVENT(evt->event_base & 0xff) |
+ (evt->config_base & M_PERFCTL_CONFIG_MASK) |
+ /* Make sure interrupt enabled. */
+ M_PERFCTL_INTERRUPT_ENABLE;
+ /*
+ * We do not actually let the counter run. Leave it until start().
+ */
+ local_irq_restore(flags);
+}
+
+static void
+mipsxx_pmu_disable_event(int idx)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ unsigned long flags;
+
+ WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
+
+ local_irq_save(flags);
+ cpuc->saved_ctrl[idx] = mipsxx_pmu_read_control(idx) &
+ ~M_PERFCTL_COUNT_EVENT_WHENEVER;
+ mipsxx_pmu_write_control(idx, cpuc->saved_ctrl[idx]);
+ local_irq_restore(flags);
+}
+
+/* 24K */
+#define IS_UNSUPPORTED_24K_EVENT(r, b) \
+ ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 || \
+ (b) == 27 || (r) == 28 || (r) == 158 || (b) == 31 || \
+ (b) == 32 || (b) == 34 || (b) == 36 || (r) == 168 || \
+ (r) == 172 || (b) == 47 || ((b) >= 56 && (b) <= 63) || \
+ ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_24K_EVENT(b) \
+ ((b) == 0 || (b) == 1 || (b) == 11)
+
+/* 34K */
+#define IS_UNSUPPORTED_34K_EVENT(r, b) \
+ ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 36 || \
+ (b) == 38 || (r) == 175 || ((b) >= 56 && (b) <= 63) || \
+ ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_34K_EVENT(b) \
+ ((b) == 0 || (b) == 1 || (b) == 11)
+#ifdef CONFIG_MIPS_MT_SMP
+#define IS_RANGE_P_34K_EVENT(r, b) \
+ ((b) == 0 || (r) == 18 || (b) == 21 || (b) == 22 || \
+ (b) == 25 || (b) == 39 || (r) == 44 || (r) == 174 || \
+ (r) == 176 || ((b) >= 50 && (b) <= 55) || \
+ ((b) >= 64 && (b) <= 67))
+#define IS_RANGE_V_34K_EVENT(r) ((r) == 47)
+#endif
+
+/* 74K */
+#define IS_UNSUPPORTED_74K_EVENT(r, b) \
+ ((r) == 5 || ((r) >= 135 && (r) <= 137) || \
+ ((b) >= 10 && (b) <= 12) || (b) == 22 || (b) == 27 || \
+ (b) == 33 || (b) == 34 || ((b) >= 47 && (b) <= 49) || \
+ (r) == 178 || (b) == 55 || (b) == 57 || (b) == 60 || \
+ (b) == 61 || (r) == 62 || (r) == 191 || \
+ ((b) >= 64 && (b) <= 127))
+#define IS_BOTH_COUNTERS_74K_EVENT(b) \
+ ((b) == 0 || (b) == 1)
+
+/* 1004K */
+#define IS_UNSUPPORTED_1004K_EVENT(r, b) \
+ ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 38 || \
+ (r) == 175 || (b) == 63 || ((b) >= 68 && (b) <= 127))
+#define IS_BOTH_COUNTERS_1004K_EVENT(b) \
+ ((b) == 0 || (b) == 1 || (b) == 11)
+#ifdef CONFIG_MIPS_MT_SMP
+#define IS_RANGE_P_1004K_EVENT(r, b) \
+ ((b) == 0 || (r) == 18 || (b) == 21 || (b) == 22 || \
+ (b) == 25 || (b) == 36 || (b) == 39 || (r) == 44 || \
+ (r) == 174 || (r) == 176 || ((b) >= 50 && (b) <= 59) || \
+ (r) == 188 || (b) == 61 || (b) == 62 || \
+ ((b) >= 64 && (b) <= 67))
+#define IS_RANGE_V_1004K_EVENT(r) ((r) == 47)
+#endif
+
+/*
+ * User can use 0-255 raw events, where 0-127 for the events of even
+ * counters, and 128-255 for odd counters. Note that bit 7 is used to
+ * indicate the parity. So, for example, when user wants to take the
+ * Event Num of 15 for odd counters (by referring to the user manual),
+ * then 128 needs to be added to 15 as the input for the event config,
+ * i.e., 143 (0x8F) to be used.
+ */
+static const struct mips_perf_event *
+mipsxx_pmu_map_raw_event(u64 config)
+{
+ unsigned int raw_id = config & 0xff;
+ unsigned int base_id = raw_id & 0x7f;
+
+ switch (current_cpu_type()) {
+ case CPU_24K:
+ if (IS_UNSUPPORTED_24K_EVENT(raw_id, base_id))
+ return ERR_PTR(-EOPNOTSUPP);
+ raw_event.event_id = base_id;
+ if (IS_BOTH_COUNTERS_24K_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+ /*
+ * This is actually doing nothing. Non-multithreading
+ * CPUs will not check and calculate the range.
+ */
+ raw_event.range = P;
+#endif
+ break;
+ case CPU_34K:
+ if (IS_UNSUPPORTED_34K_EVENT(raw_id, base_id))
+ return ERR_PTR(-EOPNOTSUPP);
+ raw_event.event_id = base_id;
+ if (IS_BOTH_COUNTERS_34K_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+ if (IS_RANGE_P_34K_EVENT(raw_id, base_id))
+ raw_event.range = P;
+ else if (unlikely(IS_RANGE_V_34K_EVENT(raw_id)))
+ raw_event.range = V;
+ else
+ raw_event.range = T;
+#endif
+ break;
+ case CPU_74K:
+ if (IS_UNSUPPORTED_74K_EVENT(raw_id, base_id))
+ return ERR_PTR(-EOPNOTSUPP);
+ raw_event.event_id = base_id;
+ if (IS_BOTH_COUNTERS_74K_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+ raw_event.range = P;
+#endif
+ break;
+ case CPU_1004K:
+ if (IS_UNSUPPORTED_1004K_EVENT(raw_id, base_id))
+ return ERR_PTR(-EOPNOTSUPP);
+ raw_event.event_id = base_id;
+ if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
+ raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
+ else
+ raw_event.cntr_mask =
+ raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+#ifdef CONFIG_MIPS_MT_SMP
+ if (IS_RANGE_P_1004K_EVENT(raw_id, base_id))
+ raw_event.range = P;
+ else if (unlikely(IS_RANGE_V_1004K_EVENT(raw_id)))
+ raw_event.range = V;
+ else
+ raw_event.range = T;
+#endif
+ break;
+ }
+
+ return &raw_event;
+}
+
+static struct mips_pmu mipsxxcore_pmu = {
+ .handle_irq = mipsxx_pmu_handle_irq,
+ .handle_shared_irq = mipsxx_pmu_handle_shared_irq,
+ .start = mipsxx_pmu_start,
+ .stop = mipsxx_pmu_stop,
+ .alloc_counter = mipsxx_pmu_alloc_counter,
+ .read_counter = mipsxx_pmu_read_counter,
+ .write_counter = mipsxx_pmu_write_counter,
+ .enable_event = mipsxx_pmu_enable_event,
+ .disable_event = mipsxx_pmu_disable_event,
+ .map_raw_event = mipsxx_pmu_map_raw_event,
+ .general_event_map = &mipsxxcore_event_map,
+ .cache_event_map = &mipsxxcore_cache_map,
+};
+
+static struct mips_pmu mipsxx74Kcore_pmu = {
+ .handle_irq = mipsxx_pmu_handle_irq,
+ .handle_shared_irq = mipsxx_pmu_handle_shared_irq,
+ .start = mipsxx_pmu_start,
+ .stop = mipsxx_pmu_stop,
+ .alloc_counter = mipsxx_pmu_alloc_counter,
+ .read_counter = mipsxx_pmu_read_counter,
+ .write_counter = mipsxx_pmu_write_counter,
+ .enable_event = mipsxx_pmu_enable_event,
+ .disable_event = mipsxx_pmu_disable_event,
+ .map_raw_event = mipsxx_pmu_map_raw_event,
+ .general_event_map = &mipsxx74Kcore_event_map,
+ .cache_event_map = &mipsxx74Kcore_cache_map,
+};
+
+static int __init
+init_hw_perf_events(void)
+{
+ int counters, irq;
+
+ pr_info("Performance counters: ");
+
+ counters = n_counters();
+ if (counters == 0) {
+ pr_cont("No available PMU.\n");
+ return -ENODEV;
+ }
+
+#ifdef CONFIG_MIPS_MT_SMP
+ cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19);
+ if (!cpu_has_mipsmt_pertccounters)
+ counters = counters_total_to_per_cpu(counters);
+#endif
+
+#ifdef MSC01E_INT_BASE
+ if (cpu_has_veic) {
+ /*
+ * Using platform specific interrupt controller defines.
+ */
+ irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
+ } else {
+#endif
+ if (cp0_perfcount_irq >= 0)
+ irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
+ else
+ irq = -1;
+#ifdef MSC01E_INT_BASE
+ }
+#endif
+
+ on_each_cpu(reset_counters, (void *)(long)counters, 1);
+
+ switch (current_cpu_type()) {
+ case CPU_24K:
+ mipsxxcore_pmu.name = "mips/24K";
+ mipsxxcore_pmu.num_counters = counters;
+ mipsxxcore_pmu.irq = irq;
+ mipspmu = &mipsxxcore_pmu;
+ break;
+ case CPU_34K:
+ mipsxxcore_pmu.name = "mips/34K";
+ mipsxxcore_pmu.num_counters = counters;
+ mipsxxcore_pmu.irq = irq;
+ mipspmu = &mipsxxcore_pmu;
+ break;
+ case CPU_74K:
+ mipsxx74Kcore_pmu.name = "mips/74K";
+ mipsxx74Kcore_pmu.num_counters = counters;
+ mipsxx74Kcore_pmu.irq = irq;
+ mipspmu = &mipsxx74Kcore_pmu;
+ break;
+ case CPU_1004K:
+ mipsxxcore_pmu.name = "mips/1004K";
+ mipsxxcore_pmu.num_counters = counters;
+ mipsxxcore_pmu.irq = irq;
+ mipspmu = &mipsxxcore_pmu;
+ break;
+ default:
+ pr_cont("Either hardware does not support performance "
+ "counters, or not yet implemented.\n");
+ return -ENODEV;
+ }
+
+ if (mipspmu)
+ pr_cont("%s PMU enabled, %d counters available to each "
+ "CPU, irq %d%s\n", mipspmu->name, counters, irq,
+ irq < 0 ? " (share with timer interrupt)" : "");
+
+ perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
+
+ return 0;
+}
+early_initcall(init_hw_perf_events);
+
+#endif /* defined(CONFIG_CPU_MIPS32)... */
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
new file mode 100644
index 00000000..e309665b
--- /dev/null
+++ b/arch/mips/kernel/proc.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 1995, 1996, 2001 Ralf Baechle
+ * Copyright (C) 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Maciej W. Rozycki
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/mips_machine.h>
+
+unsigned int vced_count, vcei_count;
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ unsigned long n = (unsigned long) v - 1;
+ unsigned int version = cpu_data[n].processor_id;
+ unsigned int fp_vers = cpu_data[n].fpu_id;
+ char fmt [64];
+ int i;
+
+#ifdef CONFIG_SMP
+ if (!cpu_isset(n, cpu_online_map))
+ return 0;
+#endif
+
+ /*
+ * For the first processor also print the system type
+ */
+ if (n == 0) {
+ seq_printf(m, "system type\t\t: %s\n", get_system_type());
+ if (mips_get_machine_name())
+ seq_printf(m, "machine\t\t\t: %s\n",
+ mips_get_machine_name());
+ }
+
+ seq_printf(m, "processor\t\t: %ld\n", n);
+ sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",
+ cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : "");
+ seq_printf(m, fmt, __cpu_name[n],
+ (version >> 4) & 0x0f, version & 0x0f,
+ (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
+ seq_printf(m, "BogoMIPS\t\t: %u.%02u\n",
+ cpu_data[n].udelay_val / (500000/HZ),
+ (cpu_data[n].udelay_val / (5000/HZ)) % 100);
+ seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
+ seq_printf(m, "microsecond timers\t: %s\n",
+ cpu_has_counter ? "yes" : "no");
+ seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize);
+ seq_printf(m, "extra interrupt vector\t: %s\n",
+ cpu_has_divec ? "yes" : "no");
+ seq_printf(m, "hardware watchpoint\t: %s",
+ cpu_has_watch ? "yes, " : "no\n");
+ if (cpu_has_watch) {
+ seq_printf(m, "count: %d, address/irw mask: [",
+ cpu_data[n].watch_reg_count);
+ for (i = 0; i < cpu_data[n].watch_reg_count; i++)
+ seq_printf(m, "%s0x%04x", i ? ", " : "" ,
+ cpu_data[n].watch_reg_masks[i]);
+ seq_printf(m, "]\n");
+ }
+ seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n",
+ cpu_has_mips16 ? " mips16" : "",
+ cpu_has_mdmx ? " mdmx" : "",
+ cpu_has_mips3d ? " mips3d" : "",
+ cpu_has_smartmips ? " smartmips" : "",
+ cpu_has_dsp ? " dsp" : "",
+ cpu_has_mipsmt ? " mt" : ""
+ );
+ seq_printf(m, "shadow register sets\t: %d\n",
+ cpu_data[n].srsets);
+ seq_printf(m, "kscratch registers\t: %d\n",
+ hweight8(cpu_data[n].kscratch_mask));
+ seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
+
+ sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
+ cpu_has_vce ? "%u" : "not available");
+ seq_printf(m, fmt, 'D', vced_count);
+ seq_printf(m, fmt, 'I', vcei_count);
+ seq_printf(m, "\n");
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ unsigned long i = *pos;
+
+ return i < NR_CPUS ? (void *) (i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
new file mode 100644
index 00000000..d2112d3c
--- /dev/null
+++ b/arch/mips/kernel/process.c
@@ -0,0 +1,487 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others.
+ * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
+ */
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/tick.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/personality.h>
+#include <linux/sys.h>
+#include <linux/user.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+#include <linux/kallsyms.h>
+#include <linux/random.h>
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/dsp.h>
+#include <asm/fpu.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/elf.h>
+#include <asm/isadep.h>
+#include <asm/inst.h>
+#include <asm/stacktrace.h>
+
+/*
+ * The idle thread. There's no useful work to be done, so just try to conserve
+ * power and have a low exit latency (ie sit in a loop waiting for somebody to
+ * say that they'd like to reschedule)
+ */
+void __noreturn cpu_idle(void)
+{
+ int cpu;
+
+ /* CPU is going idle. */
+ cpu = smp_processor_id();
+
+ /* endless idle loop with no priority at all */
+ while (1) {
+ tick_nohz_stop_sched_tick(1);
+ while (!need_resched() && cpu_online(cpu)) {
+#ifdef CONFIG_MIPS_MT_SMTC
+ extern void smtc_idle_loop_hook(void);
+
+ smtc_idle_loop_hook();
+#endif
+
+ if (cpu_wait) {
+ /* Don't trace irqs off for idle */
+ stop_critical_timings();
+ (*cpu_wait)();
+ start_critical_timings();
+ }
+ }
+#ifdef CONFIG_HOTPLUG_CPU
+ if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
+ (system_state == SYSTEM_RUNNING ||
+ system_state == SYSTEM_BOOTING))
+ play_dead();
+#endif
+ tick_nohz_restart_sched_tick();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+asmlinkage void ret_from_fork(void);
+
+void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+{
+ unsigned long status;
+
+ /* New thread loses kernel privileges. */
+ status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK);
+#ifdef CONFIG_64BIT
+ status |= test_thread_flag(TIF_32BIT_REGS) ? 0 : ST0_FR;
+#endif
+ status |= KU_USER;
+ regs->cp0_status = status;
+ clear_used_math();
+ clear_fpu_owner();
+ if (cpu_has_dsp)
+ __init_dsp();
+ regs->cp0_epc = pc;
+ regs->regs[29] = sp;
+ current_thread_info()->addr_limit = USER_DS;
+}
+
+void exit_thread(void)
+{
+}
+
+void flush_thread(void)
+{
+}
+
+int copy_thread(unsigned long clone_flags, unsigned long usp,
+ unsigned long unused, struct task_struct *p, struct pt_regs *regs)
+{
+ struct thread_info *ti = task_thread_info(p);
+ struct pt_regs *childregs;
+ unsigned long childksp;
+ p->set_child_tid = p->clear_child_tid = NULL;
+
+ childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32;
+
+ preempt_disable();
+
+ if (is_fpu_owner())
+ save_fp(p);
+
+ if (cpu_has_dsp)
+ save_dsp(p);
+
+ preempt_enable();
+
+ /* set up new TSS. */
+ childregs = (struct pt_regs *) childksp - 1;
+ /* Put the stack after the struct pt_regs. */
+ childksp = (unsigned long) childregs;
+ *childregs = *regs;
+ childregs->regs[7] = 0; /* Clear error flag */
+
+ childregs->regs[2] = 0; /* Child gets zero as return value */
+
+ if (childregs->cp0_status & ST0_CU0) {
+ childregs->regs[28] = (unsigned long) ti;
+ childregs->regs[29] = childksp;
+ ti->addr_limit = KERNEL_DS;
+ } else {
+ childregs->regs[29] = usp;
+ ti->addr_limit = USER_DS;
+ }
+ p->thread.reg29 = (unsigned long) childregs;
+ p->thread.reg31 = (unsigned long) ret_from_fork;
+
+ /*
+ * New tasks lose permission to use the fpu. This accelerates context
+ * switching for most programs since they don't use the fpu.
+ */
+ p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1);
+ childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC restores TCStatus after Status, and the CU bits
+ * are aliased there.
+ */
+ childregs->cp0_tcstatus &= ~(ST0_CU2|ST0_CU1);
+#endif
+ clear_tsk_thread_flag(p, TIF_USEDFPU);
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+ clear_tsk_thread_flag(p, TIF_FPUBOUND);
+#endif /* CONFIG_MIPS_MT_FPAFF */
+
+ if (clone_flags & CLONE_SETTLS)
+ ti->tp_value = regs->regs[7];
+
+ return 0;
+}
+
+/* Fill in the fpu structure for a core dump.. */
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+{
+ memcpy(r, &current->thread.fpu, sizeof(current->thread.fpu));
+
+ return 1;
+}
+
+void elf_dump_regs(elf_greg_t *gp, struct pt_regs *regs)
+{
+ int i;
+
+ for (i = 0; i < EF_R0; i++)
+ gp[i] = 0;
+ gp[EF_R0] = 0;
+ for (i = 1; i <= 31; i++)
+ gp[EF_R0 + i] = regs->regs[i];
+ gp[EF_R26] = 0;
+ gp[EF_R27] = 0;
+ gp[EF_LO] = regs->lo;
+ gp[EF_HI] = regs->hi;
+ gp[EF_CP0_EPC] = regs->cp0_epc;
+ gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr;
+ gp[EF_CP0_STATUS] = regs->cp0_status;
+ gp[EF_CP0_CAUSE] = regs->cp0_cause;
+#ifdef EF_UNUSED0
+ gp[EF_UNUSED0] = 0;
+#endif
+}
+
+int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
+{
+ elf_dump_regs(*regs, task_pt_regs(tsk));
+ return 1;
+}
+
+int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr)
+{
+ memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu));
+
+ return 1;
+}
+
+/*
+ * Create a kernel thread
+ */
+static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *))
+{
+ do_exit(fn(arg));
+}
+
+long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+ struct pt_regs regs;
+
+ memset(&regs, 0, sizeof(regs));
+
+ regs.regs[4] = (unsigned long) arg;
+ regs.regs[5] = (unsigned long) fn;
+ regs.cp0_epc = (unsigned long) kernel_thread_helper;
+ regs.cp0_status = read_c0_status();
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+ regs.cp0_status = (regs.cp0_status & ~(ST0_KUP | ST0_IEP | ST0_IEC)) |
+ ((regs.cp0_status & (ST0_KUC | ST0_IEC)) << 2);
+#else
+ regs.cp0_status |= ST0_EXL;
+#endif
+
+ /* Ok, create the new process.. */
+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+}
+
+/*
+ *
+ */
+struct mips_frame_info {
+ void *func;
+ unsigned long func_size;
+ int frame_size;
+ int pc_offset;
+};
+
+static inline int is_ra_save_ins(union mips_instruction *ip)
+{
+ /* sw / sd $ra, offset($sp) */
+ return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
+ ip->i_format.rs == 29 &&
+ ip->i_format.rt == 31;
+}
+
+static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
+{
+ if (ip->j_format.opcode == jal_op)
+ return 1;
+ if (ip->r_format.opcode != spec_op)
+ return 0;
+ return ip->r_format.func == jalr_op || ip->r_format.func == jr_op;
+}
+
+static inline int is_sp_move_ins(union mips_instruction *ip)
+{
+ /* addiu/daddiu sp,sp,-imm */
+ if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
+ return 0;
+ if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op)
+ return 1;
+ return 0;
+}
+
+static int get_frame_info(struct mips_frame_info *info)
+{
+ union mips_instruction *ip = info->func;
+ unsigned max_insns = info->func_size / sizeof(union mips_instruction);
+ unsigned i;
+
+ info->pc_offset = -1;
+ info->frame_size = 0;
+
+ if (!ip)
+ goto err;
+
+ if (max_insns == 0)
+ max_insns = 128U; /* unknown function size */
+ max_insns = min(128U, max_insns);
+
+ for (i = 0; i < max_insns; i++, ip++) {
+
+ if (is_jal_jalr_jr_ins(ip))
+ break;
+ if (!info->frame_size) {
+ if (is_sp_move_ins(ip))
+ info->frame_size = - ip->i_format.simmediate;
+ continue;
+ }
+ if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
+ info->pc_offset =
+ ip->i_format.simmediate / sizeof(long);
+ break;
+ }
+ }
+ if (info->frame_size && info->pc_offset >= 0) /* nested */
+ return 0;
+ if (info->pc_offset < 0) /* leaf */
+ return 1;
+ /* prologue seems boggus... */
+err:
+ return -1;
+}
+
+static struct mips_frame_info schedule_mfi __read_mostly;
+
+static int __init frame_info_init(void)
+{
+ unsigned long size = 0;
+#ifdef CONFIG_KALLSYMS
+ unsigned long ofs;
+
+ kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs);
+#endif
+ schedule_mfi.func = schedule;
+ schedule_mfi.func_size = size;
+
+ get_frame_info(&schedule_mfi);
+
+ /*
+ * Without schedule() frame info, result given by
+ * thread_saved_pc() and get_wchan() are not reliable.
+ */
+ if (schedule_mfi.pc_offset < 0)
+ printk("Can't analyze schedule() prologue at %p\n", schedule);
+
+ return 0;
+}
+
+arch_initcall(frame_info_init);
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+ struct thread_struct *t = &tsk->thread;
+
+ /* New born processes are a special case */
+ if (t->reg31 == (unsigned long) ret_from_fork)
+ return t->reg31;
+ if (schedule_mfi.pc_offset < 0)
+ return 0;
+ return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset];
+}
+
+
+#ifdef CONFIG_KALLSYMS
+/* used by show_backtrace() */
+unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
+ unsigned long pc, unsigned long *ra)
+{
+ unsigned long stack_page;
+ struct mips_frame_info info;
+ unsigned long size, ofs;
+ int leaf;
+ extern void ret_from_irq(void);
+ extern void ret_from_exception(void);
+
+ stack_page = (unsigned long)task_stack_page(task);
+ if (!stack_page)
+ return 0;
+
+ /*
+ * If we reached the bottom of interrupt context,
+ * return saved pc in pt_regs.
+ */
+ if (pc == (unsigned long)ret_from_irq ||
+ pc == (unsigned long)ret_from_exception) {
+ struct pt_regs *regs;
+ if (*sp >= stack_page &&
+ *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
+ regs = (struct pt_regs *)*sp;
+ pc = regs->cp0_epc;
+ if (__kernel_text_address(pc)) {
+ *sp = regs->regs[29];
+ *ra = regs->regs[31];
+ return pc;
+ }
+ }
+ return 0;
+ }
+ if (!kallsyms_lookup_size_offset(pc, &size, &ofs))
+ return 0;
+ /*
+ * Return ra if an exception occurred at the first instruction
+ */
+ if (unlikely(ofs == 0)) {
+ pc = *ra;
+ *ra = 0;
+ return pc;
+ }
+
+ info.func = (void *)(pc - ofs);
+ info.func_size = ofs; /* analyze from start to ofs */
+ leaf = get_frame_info(&info);
+ if (leaf < 0)
+ return 0;
+
+ if (*sp < stack_page ||
+ *sp + info.frame_size > stack_page + THREAD_SIZE - 32)
+ return 0;
+
+ if (leaf)
+ /*
+ * For some extreme cases, get_frame_info() can
+ * consider wrongly a nested function as a leaf
+ * one. In that cases avoid to return always the
+ * same value.
+ */
+ pc = pc != *ra ? *ra : 0;
+ else
+ pc = ((unsigned long *)(*sp))[info.pc_offset];
+
+ *sp += info.frame_size;
+ *ra = 0;
+ return __kernel_text_address(pc) ? pc : 0;
+}
+#endif
+
+/*
+ * get_wchan - a maintenance nightmare^W^Wpain in the ass ...
+ */
+unsigned long get_wchan(struct task_struct *task)
+{
+ unsigned long pc = 0;
+#ifdef CONFIG_KALLSYMS
+ unsigned long sp;
+ unsigned long ra = 0;
+#endif
+
+ if (!task || task == current || task->state == TASK_RUNNING)
+ goto out;
+ if (!task_stack_page(task))
+ goto out;
+
+ pc = thread_saved_pc(task);
+
+#ifdef CONFIG_KALLSYMS
+ sp = task->thread.reg29 + schedule_mfi.frame_size;
+
+ while (in_sched_functions(pc))
+ pc = unwind_stack(task, &sp, pc, &ra);
+#endif
+
+out:
+ return pc;
+}
+
+/*
+ * Don't forget that the stack pointer must be aligned on a 8 bytes
+ * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
+ */
+unsigned long arch_align_stack(unsigned long sp)
+{
+ if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+ sp -= get_random_int() & ~PAGE_MASK;
+
+ return sp & ALMASK;
+}
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
new file mode 100644
index 00000000..5b7eade4
--- /dev/null
+++ b/arch/mips/kernel/prom.c
@@ -0,0 +1,111 @@
+/*
+ * MIPS support for CONFIG_OF device tree support
+ *
+ * Copyright (C) 2010 Cisco Systems Inc. <dediao@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <linux/debugfs.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/page.h>
+#include <asm/prom.h>
+
+int __init early_init_dt_scan_memory_arch(unsigned long node,
+ const char *uname, int depth,
+ void *data)
+{
+ return early_init_dt_scan_memory(node, uname, depth, data);
+}
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+ return add_memory_region(base, size, BOOT_MEM_RAM);
+}
+
+int __init reserve_mem_mach(unsigned long addr, unsigned long size)
+{
+ return reserve_bootmem(addr, size, BOOTMEM_DEFAULT);
+}
+
+void __init free_mem_mach(unsigned long addr, unsigned long size)
+{
+ return free_bootmem(addr, size);
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+ return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init early_init_dt_setup_initrd_arch(unsigned long start,
+ unsigned long end)
+{
+ initrd_start = (unsigned long)__va(start);
+ initrd_end = (unsigned long)__va(end);
+ initrd_below_start_ok = 1;
+}
+#endif
+
+/*
+ * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+ *
+ * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
+ * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
+ * supported.
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+ const u32 *intspec, unsigned int intsize)
+{
+ return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+void __init early_init_devtree(void *params)
+{
+ /* Setup flat device-tree pointer */
+ initial_boot_params = params;
+
+ /* Retrieve various informations from the /chosen node of the
+ * device-tree, including the platform type, initrd location and
+ * size, and more ...
+ */
+ of_scan_flat_dt(early_init_dt_scan_chosen, arcs_cmdline);
+
+
+ /* Scan memory nodes */
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
+}
+
+void __init device_tree_init(void)
+{
+ unsigned long base, size;
+
+ if (!initial_boot_params)
+ return;
+
+ base = virt_to_phys((void *)initial_boot_params);
+ size = be32_to_cpu(initial_boot_params->totalsize);
+
+ /* Before we do anything, lets reserve the dt blob */
+ reserve_mem_mach(base, size);
+
+ unflatten_device_tree();
+
+ /* free the space reserved for the dt blob */
+ free_mem_mach(base, size);
+}
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
new file mode 100644
index 00000000..4e6ea1ff
--- /dev/null
+++ b/arch/mips/kernel/ptrace.c
@@ -0,0 +1,599 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc.
+ * Copyright (C) 2000 Ulf Carlsson
+ *
+ * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
+ * binaries.
+ */
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/smp.h>
+#include <linux/user.h>
+#include <linux/security.h>
+#include <linux/audit.h>
+#include <linux/seccomp.h>
+
+#include <asm/byteorder.h>
+#include <asm/cpu.h>
+#include <asm/dsp.h>
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/bootinfo.h>
+#include <asm/reg.h>
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ /* Don't load the watchpoint registers for the ex-child. */
+ clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
+}
+
+/*
+ * Read a general register set. We always use the 64-bit format, even
+ * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
+ * Registers are sign extended to fill the available space.
+ */
+int ptrace_getregs(struct task_struct *child, __s64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_WRITE, data, 38 * 8))
+ return -EIO;
+
+ regs = task_pt_regs(child);
+
+ for (i = 0; i < 32; i++)
+ __put_user((long)regs->regs[i], data + i);
+ __put_user((long)regs->lo, data + EF_LO - EF_R0);
+ __put_user((long)regs->hi, data + EF_HI - EF_R0);
+ __put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+ __put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
+ __put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
+ __put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
+
+ return 0;
+}
+
+/*
+ * Write a general register set. As for PTRACE_GETREGS, we always use
+ * the 64-bit format. On a 32-bit kernel only the lower order half
+ * (according to endianness) will be used.
+ */
+int ptrace_setregs(struct task_struct *child, __s64 __user *data)
+{
+ struct pt_regs *regs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 38 * 8))
+ return -EIO;
+
+ regs = task_pt_regs(child);
+
+ for (i = 0; i < 32; i++)
+ __get_user(regs->regs[i], data + i);
+ __get_user(regs->lo, data + EF_LO - EF_R0);
+ __get_user(regs->hi, data + EF_HI - EF_R0);
+ __get_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+
+ /* badvaddr, status, and cause may not be written. */
+
+ return 0;
+}
+
+int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
+{
+ int i;
+ unsigned int tmp;
+
+ if (!access_ok(VERIFY_WRITE, data, 33 * 8))
+ return -EIO;
+
+ if (tsk_used_math(child)) {
+ fpureg_t *fregs = get_fpu_regs(child);
+ for (i = 0; i < 32; i++)
+ __put_user(fregs[i], i + (__u64 __user *) data);
+ } else {
+ for (i = 0; i < 32; i++)
+ __put_user((__u64) -1, i + (__u64 __user *) data);
+ }
+
+ __put_user(child->thread.fpu.fcr31, data + 64);
+
+ preempt_disable();
+ if (cpu_has_fpu) {
+ unsigned int flags;
+
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
+ write_c0_status(flags);
+ }
+ } else {
+ tmp = 0;
+ }
+ preempt_enable();
+ __put_user(tmp, data + 65);
+
+ return 0;
+}
+
+int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
+{
+ fpureg_t *fregs;
+ int i;
+
+ if (!access_ok(VERIFY_READ, data, 33 * 8))
+ return -EIO;
+
+ fregs = get_fpu_regs(child);
+
+ for (i = 0; i < 32; i++)
+ __get_user(fregs[i], i + (__u64 __user *) data);
+
+ __get_user(child->thread.fpu.fcr31, data + 64);
+
+ /* FIR may not be written. */
+
+ return 0;
+}
+
+int ptrace_get_watch_regs(struct task_struct *child,
+ struct pt_watch_regs __user *addr)
+{
+ enum pt_watch_style style;
+ int i;
+
+ if (!cpu_has_watch || current_cpu_data.watch_reg_use_cnt == 0)
+ return -EIO;
+ if (!access_ok(VERIFY_WRITE, addr, sizeof(struct pt_watch_regs)))
+ return -EIO;
+
+#ifdef CONFIG_32BIT
+ style = pt_watch_style_mips32;
+#define WATCH_STYLE mips32
+#else
+ style = pt_watch_style_mips64;
+#define WATCH_STYLE mips64
+#endif
+
+ __put_user(style, &addr->style);
+ __put_user(current_cpu_data.watch_reg_use_cnt,
+ &addr->WATCH_STYLE.num_valid);
+ for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) {
+ __put_user(child->thread.watch.mips3264.watchlo[i],
+ &addr->WATCH_STYLE.watchlo[i]);
+ __put_user(child->thread.watch.mips3264.watchhi[i] & 0xfff,
+ &addr->WATCH_STYLE.watchhi[i]);
+ __put_user(current_cpu_data.watch_reg_masks[i],
+ &addr->WATCH_STYLE.watch_masks[i]);
+ }
+ for (; i < 8; i++) {
+ __put_user(0, &addr->WATCH_STYLE.watchlo[i]);
+ __put_user(0, &addr->WATCH_STYLE.watchhi[i]);
+ __put_user(0, &addr->WATCH_STYLE.watch_masks[i]);
+ }
+
+ return 0;
+}
+
+int ptrace_set_watch_regs(struct task_struct *child,
+ struct pt_watch_regs __user *addr)
+{
+ int i;
+ int watch_active = 0;
+ unsigned long lt[NUM_WATCH_REGS];
+ u16 ht[NUM_WATCH_REGS];
+
+ if (!cpu_has_watch || current_cpu_data.watch_reg_use_cnt == 0)
+ return -EIO;
+ if (!access_ok(VERIFY_READ, addr, sizeof(struct pt_watch_regs)))
+ return -EIO;
+ /* Check the values. */
+ for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) {
+ __get_user(lt[i], &addr->WATCH_STYLE.watchlo[i]);
+#ifdef CONFIG_32BIT
+ if (lt[i] & __UA_LIMIT)
+ return -EINVAL;
+#else
+ if (test_tsk_thread_flag(child, TIF_32BIT_ADDR)) {
+ if (lt[i] & 0xffffffff80000000UL)
+ return -EINVAL;
+ } else {
+ if (lt[i] & __UA_LIMIT)
+ return -EINVAL;
+ }
+#endif
+ __get_user(ht[i], &addr->WATCH_STYLE.watchhi[i]);
+ if (ht[i] & ~0xff8)
+ return -EINVAL;
+ }
+ /* Install them. */
+ for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) {
+ if (lt[i] & 7)
+ watch_active = 1;
+ child->thread.watch.mips3264.watchlo[i] = lt[i];
+ /* Set the G bit. */
+ child->thread.watch.mips3264.watchhi[i] = ht[i];
+ }
+
+ if (watch_active)
+ set_tsk_thread_flag(child, TIF_LOAD_WATCH);
+ else
+ clear_tsk_thread_flag(child, TIF_LOAD_WATCH);
+
+ return 0;
+}
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+{
+ int ret;
+ void __user *addrp = (void __user *) addr;
+ void __user *datavp = (void __user *) data;
+ unsigned long __user *datalp = (void __user *) data;
+
+ switch (request) {
+ /* when I and D space are separate, these will need to be fixed. */
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
+ case PTRACE_PEEKDATA:
+ ret = generic_ptrace_peekdata(child, addr, data);
+ break;
+
+ /* Read the word at location addr in the USER area. */
+ case PTRACE_PEEKUSR: {
+ struct pt_regs *regs;
+ unsigned long tmp = 0;
+
+ regs = task_pt_regs(child);
+ ret = 0; /* Default return value. */
+
+ switch (addr) {
+ case 0 ... 31:
+ tmp = regs->regs[addr];
+ break;
+ case FPR_BASE ... FPR_BASE + 31:
+ if (tsk_used_math(child)) {
+ fpureg_t *fregs = get_fpu_regs(child);
+
+#ifdef CONFIG_32BIT
+ /*
+ * The odd registers are actually the high
+ * order bits of the values stored in the even
+ * registers - unless we're using r2k_switch.S.
+ */
+ if (addr & 1)
+ tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+ else
+ tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
+#endif
+#ifdef CONFIG_64BIT
+ tmp = fregs[addr - FPR_BASE];
+#endif
+ } else {
+ tmp = -1; /* FP not yet used */
+ }
+ break;
+ case PC:
+ tmp = regs->cp0_epc;
+ break;
+ case CAUSE:
+ tmp = regs->cp0_cause;
+ break;
+ case BADVADDR:
+ tmp = regs->cp0_badvaddr;
+ break;
+ case MMHI:
+ tmp = regs->hi;
+ break;
+ case MMLO:
+ tmp = regs->lo;
+ break;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ case ACX:
+ tmp = regs->acx;
+ break;
+#endif
+ case FPC_CSR:
+ tmp = child->thread.fpu.fcr31;
+ break;
+ case FPC_EIR: { /* implementation / version register */
+ unsigned int flags;
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned long irqflags;
+ unsigned int mtflags;
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ preempt_disable();
+ if (!cpu_has_fpu) {
+ preempt_enable();
+ break;
+ }
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /* Read-modify-write of Status must be atomic */
+ local_irq_save(irqflags);
+ mtflags = dmt();
+#endif /* CONFIG_MIPS_MT_SMTC */
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ }
+#ifdef CONFIG_MIPS_MT_SMTC
+ emt(mtflags);
+ local_irq_restore(irqflags);
+#endif /* CONFIG_MIPS_MT_SMTC */
+ preempt_enable();
+ break;
+ }
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
+
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out;
+ }
+ dregs = __get_dsp_regs(child);
+ tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ break;
+ }
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out;
+ }
+ tmp = child->thread.dsp.dspcontrol;
+ break;
+ default:
+ tmp = 0;
+ ret = -EIO;
+ goto out;
+ }
+ ret = put_user(tmp, datalp);
+ break;
+ }
+
+ /* when I and D space are separate, this will have to be fixed. */
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ ret = generic_ptrace_pokedata(child, addr, data);
+ break;
+
+ case PTRACE_POKEUSR: {
+ struct pt_regs *regs;
+ ret = 0;
+ regs = task_pt_regs(child);
+
+ switch (addr) {
+ case 0 ... 31:
+ regs->regs[addr] = data;
+ break;
+ case FPR_BASE ... FPR_BASE + 31: {
+ fpureg_t *fregs = get_fpu_regs(child);
+
+ if (!tsk_used_math(child)) {
+ /* FP not yet used */
+ memset(&child->thread.fpu, ~0,
+ sizeof(child->thread.fpu));
+ child->thread.fpu.fcr31 = 0;
+ }
+#ifdef CONFIG_32BIT
+ /*
+ * The odd registers are actually the high order bits
+ * of the values stored in the even registers - unless
+ * we're using r2k_switch.S.
+ */
+ if (addr & 1) {
+ fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+ fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
+ } else {
+ fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+ fregs[addr - FPR_BASE] |= data;
+ }
+#endif
+#ifdef CONFIG_64BIT
+ fregs[addr - FPR_BASE] = data;
+#endif
+ break;
+ }
+ case PC:
+ regs->cp0_epc = data;
+ break;
+ case MMHI:
+ regs->hi = data;
+ break;
+ case MMLO:
+ regs->lo = data;
+ break;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ case ACX:
+ regs->acx = data;
+ break;
+#endif
+ case FPC_CSR:
+ child->thread.fpu.fcr31 = data;
+ break;
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
+
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+
+ dregs = __get_dsp_regs(child);
+ dregs[addr - DSP_BASE] = data;
+ break;
+ }
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+ child->thread.dsp.dspcontrol = data;
+ break;
+ default:
+ /* The rest are not allowed. */
+ ret = -EIO;
+ break;
+ }
+ break;
+ }
+
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs(child, datavp);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs(child, datavp);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs(child, datavp);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs(child, datavp);
+ break;
+
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(task_thread_info(child)->tp_value, datalp);
+ break;
+
+ case PTRACE_GET_WATCH_REGS:
+ ret = ptrace_get_watch_regs(child, addrp);
+ break;
+
+ case PTRACE_SET_WATCH_REGS:
+ ret = ptrace_set_watch_regs(child, addrp);
+ break;
+
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+ out:
+ return ret;
+}
+
+static inline int audit_arch(void)
+{
+ int arch = EM_MIPS;
+#ifdef CONFIG_64BIT
+ arch |= __AUDIT_ARCH_64BIT;
+#endif
+#if defined(__LITTLE_ENDIAN)
+ arch |= __AUDIT_ARCH_LE;
+#endif
+ return arch;
+}
+
+/*
+ * Notification of system call entry/exit
+ * - triggered by current->work.syscall_trace
+ */
+asmlinkage void syscall_trace_enter(struct pt_regs *regs)
+{
+ /* do the secure computing check first */
+ secure_computing(regs->regs[2]);
+
+ if (!(current->ptrace & PT_PTRACED))
+ goto out;
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ goto out;
+
+ /* The 0x80 provides a way for the tracing parent to distinguish
+ between a syscall stop and SIGTRAP delivery */
+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
+ 0x80 : 0));
+
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+ * for normal use. strace only continues with a signal if the
+ * stopping signal is not SIGTRAP. -brl
+ */
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+
+out:
+ if (unlikely(current->audit_context))
+ audit_syscall_entry(audit_arch(), regs->regs[2],
+ regs->regs[4], regs->regs[5],
+ regs->regs[6], regs->regs[7]);
+}
+
+/*
+ * Notification of system call entry/exit
+ * - triggered by current->work.syscall_trace
+ */
+asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+{
+ if (unlikely(current->audit_context))
+ audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
+ -regs->regs[2]);
+
+ if (!(current->ptrace & PT_PTRACED))
+ return;
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return;
+
+ /* The 0x80 provides a way for the tracing parent to distinguish
+ between a syscall stop and SIGTRAP delivery */
+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
+ 0x80 : 0));
+
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+ * for normal use. strace only continues with a signal if the
+ * stopping signal is not SIGTRAP. -brl
+ */
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+}
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
new file mode 100644
index 00000000..32644b4a
--- /dev/null
+++ b/arch/mips/kernel/ptrace32.c
@@ -0,0 +1,337 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 Ross Biro
+ * Copyright (C) Linus Torvalds
+ * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc.
+ * Copyright (C) 2000 Ulf Carlsson
+ *
+ * At this time Linux/MIPS64 only supports syscall tracing, even for 32-bit
+ * binaries.
+ */
+#include <linux/compiler.h>
+#include <linux/compat.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/smp.h>
+#include <linux/user.h>
+#include <linux/security.h>
+
+#include <asm/cpu.h>
+#include <asm/dsp.h>
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/bootinfo.h>
+
+/*
+ * Tracing a 32-bit process with a 64-bit strace and vice versa will not
+ * work. I don't know how to fix this.
+ */
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+ compat_ulong_t caddr, compat_ulong_t cdata)
+{
+ int addr = caddr;
+ int data = cdata;
+ int ret;
+
+ switch (request) {
+
+ /*
+ * Read 4 bytes of the other process' storage
+ * data is a pointer specifying where the user wants the
+ * 4 bytes copied into
+ * addr is a pointer in the user's storage that contains an 8 byte
+ * address in the other process of the 4 bytes that is to be read
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_PEEKTEXT_3264:
+ case PTRACE_PEEKDATA_3264: {
+ u32 tmp;
+ int copied;
+ u32 __user * addrOthers;
+
+ ret = -EIO;
+
+ /* Get the addr in the other process that we want to read */
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+
+ copied = access_process_vm(child, (u64)addrOthers, &tmp,
+ sizeof(tmp), 0);
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp, (u32 __user *) (unsigned long) data);
+ break;
+ }
+
+ /* Read the word at location addr in the USER area. */
+ case PTRACE_PEEKUSR: {
+ struct pt_regs *regs;
+ unsigned int tmp;
+
+ regs = task_pt_regs(child);
+ ret = 0; /* Default return value. */
+
+ switch (addr) {
+ case 0 ... 31:
+ tmp = regs->regs[addr];
+ break;
+ case FPR_BASE ... FPR_BASE + 31:
+ if (tsk_used_math(child)) {
+ fpureg_t *fregs = get_fpu_regs(child);
+
+ /*
+ * The odd registers are actually the high
+ * order bits of the values stored in the even
+ * registers - unless we're using r2k_switch.S.
+ */
+ if (addr & 1)
+ tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+ else
+ tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
+ } else {
+ tmp = -1; /* FP not yet used */
+ }
+ break;
+ case PC:
+ tmp = regs->cp0_epc;
+ break;
+ case CAUSE:
+ tmp = regs->cp0_cause;
+ break;
+ case BADVADDR:
+ tmp = regs->cp0_badvaddr;
+ break;
+ case MMHI:
+ tmp = regs->hi;
+ break;
+ case MMLO:
+ tmp = regs->lo;
+ break;
+ case FPC_CSR:
+ tmp = child->thread.fpu.fcr31;
+ break;
+ case FPC_EIR: { /* implementation / version register */
+ unsigned int flags;
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned int irqflags;
+ unsigned int mtflags;
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ preempt_disable();
+ if (!cpu_has_fpu) {
+ preempt_enable();
+ tmp = 0;
+ break;
+ }
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /* Read-modify-write of Status must be atomic */
+ local_irq_save(irqflags);
+ mtflags = dmt();
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ evpe(vpflags);
+ } else {
+ flags = read_c0_status();
+ __enable_fpu();
+ __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
+ write_c0_status(flags);
+ }
+#ifdef CONFIG_MIPS_MT_SMTC
+ emt(mtflags);
+ local_irq_restore(irqflags);
+#endif /* CONFIG_MIPS_MT_SMTC */
+ preempt_enable();
+ break;
+ }
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
+
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out;
+ }
+ dregs = __get_dsp_regs(child);
+ tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ break;
+ }
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ tmp = 0;
+ ret = -EIO;
+ goto out;
+ }
+ tmp = child->thread.dsp.dspcontrol;
+ break;
+ default:
+ tmp = 0;
+ ret = -EIO;
+ goto out;
+ }
+ ret = put_user(tmp, (unsigned __user *) (unsigned long) data);
+ break;
+ }
+
+ /*
+ * Write 4 bytes into the other process' storage
+ * data is the 4 bytes that the user wants written
+ * addr is a pointer in the user's storage that contains an
+ * 8 byte address in the other process where the 4 bytes
+ * that is to be written
+ * (this is run in a 32-bit process looking at a 64-bit process)
+ * when I and D space are separate, these will need to be fixed.
+ */
+ case PTRACE_POKETEXT_3264:
+ case PTRACE_POKEDATA_3264: {
+ u32 __user * addrOthers;
+
+ /* Get the addr in the other process that we want to write into */
+ ret = -EIO;
+ if (get_user(addrOthers, (u32 __user * __user *) (unsigned long) addr) != 0)
+ break;
+ ret = 0;
+ if (access_process_vm(child, (u64)addrOthers, &data,
+ sizeof(data), 1) == sizeof(data))
+ break;
+ ret = -EIO;
+ break;
+ }
+
+ case PTRACE_POKEUSR: {
+ struct pt_regs *regs;
+ ret = 0;
+ regs = task_pt_regs(child);
+
+ switch (addr) {
+ case 0 ... 31:
+ regs->regs[addr] = data;
+ break;
+ case FPR_BASE ... FPR_BASE + 31: {
+ fpureg_t *fregs = get_fpu_regs(child);
+
+ if (!tsk_used_math(child)) {
+ /* FP not yet used */
+ memset(&child->thread.fpu, ~0,
+ sizeof(child->thread.fpu));
+ child->thread.fpu.fcr31 = 0;
+ }
+ /*
+ * The odd registers are actually the high order bits
+ * of the values stored in the even registers - unless
+ * we're using r2k_switch.S.
+ */
+ if (addr & 1) {
+ fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
+ fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
+ } else {
+ fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+ /* Must cast, lest sign extension fill upper
+ bits! */
+ fregs[addr - FPR_BASE] |= (unsigned int)data;
+ }
+ break;
+ }
+ case PC:
+ regs->cp0_epc = data;
+ break;
+ case MMHI:
+ regs->hi = data;
+ break;
+ case MMLO:
+ regs->lo = data;
+ break;
+ case FPC_CSR:
+ child->thread.fpu.fcr31 = data;
+ break;
+ case DSP_BASE ... DSP_BASE + 5: {
+ dspreg_t *dregs;
+
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+
+ dregs = __get_dsp_regs(child);
+ dregs[addr - DSP_BASE] = data;
+ break;
+ }
+ case DSP_CONTROL:
+ if (!cpu_has_dsp) {
+ ret = -EIO;
+ break;
+ }
+ child->thread.dsp.dspcontrol = data;
+ break;
+ default:
+ /* The rest are not allowed. */
+ ret = -EIO;
+ break;
+ }
+ break;
+ }
+
+ case PTRACE_GETREGS:
+ ret = ptrace_getregs(child, (__s64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = ptrace_setregs(child, (__s64 __user *) (__u64) data);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = ptrace_getfpregs(child, (__u32 __user *) (__u64) data);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = ptrace_setfpregs(child, (__u32 __user *) (__u64) data);
+ break;
+
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(task_thread_info(child)->tp_value,
+ (unsigned int __user *) (unsigned long) data);
+ break;
+
+ case PTRACE_GET_THREAD_AREA_3264:
+ ret = put_user(task_thread_info(child)->tp_value,
+ (unsigned long __user *) (unsigned long) data);
+ break;
+
+ case PTRACE_GET_WATCH_REGS:
+ ret = ptrace_get_watch_regs(child,
+ (struct pt_watch_regs __user *) (unsigned long) addr);
+ break;
+
+ case PTRACE_SET_WATCH_REGS:
+ ret = ptrace_set_watch_regs(child,
+ (struct pt_watch_regs __user *) (unsigned long) addr);
+ break;
+
+ default:
+ ret = compat_ptrace_request(child, request, addr, data);
+ break;
+ }
+out:
+ return ret;
+}
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
new file mode 100644
index 00000000..61c8a0f2
--- /dev/null
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -0,0 +1,126 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1998 by Ralf Baechle
+ *
+ * Multi-arch abstraction and asm macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ *
+ * Further modifications to make this work:
+ * Copyright (c) 1998 Harald Koerfgen
+ */
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define EX(a,b) \
+9: a,##b; \
+ .section __ex_table,"a"; \
+ PTR 9b,bad_stack; \
+ .previous
+
+ .set noreorder
+ .set mips1
+ /* Save floating point context */
+LEAF(_save_fp_context)
+ li v0, 0 # assume success
+ cfc1 t1,fcr31
+ EX(swc1 $f0,(SC_FPREGS+0)(a0))
+ EX(swc1 $f1,(SC_FPREGS+8)(a0))
+ EX(swc1 $f2,(SC_FPREGS+16)(a0))
+ EX(swc1 $f3,(SC_FPREGS+24)(a0))
+ EX(swc1 $f4,(SC_FPREGS+32)(a0))
+ EX(swc1 $f5,(SC_FPREGS+40)(a0))
+ EX(swc1 $f6,(SC_FPREGS+48)(a0))
+ EX(swc1 $f7,(SC_FPREGS+56)(a0))
+ EX(swc1 $f8,(SC_FPREGS+64)(a0))
+ EX(swc1 $f9,(SC_FPREGS+72)(a0))
+ EX(swc1 $f10,(SC_FPREGS+80)(a0))
+ EX(swc1 $f11,(SC_FPREGS+88)(a0))
+ EX(swc1 $f12,(SC_FPREGS+96)(a0))
+ EX(swc1 $f13,(SC_FPREGS+104)(a0))
+ EX(swc1 $f14,(SC_FPREGS+112)(a0))
+ EX(swc1 $f15,(SC_FPREGS+120)(a0))
+ EX(swc1 $f16,(SC_FPREGS+128)(a0))
+ EX(swc1 $f17,(SC_FPREGS+136)(a0))
+ EX(swc1 $f18,(SC_FPREGS+144)(a0))
+ EX(swc1 $f19,(SC_FPREGS+152)(a0))
+ EX(swc1 $f20,(SC_FPREGS+160)(a0))
+ EX(swc1 $f21,(SC_FPREGS+168)(a0))
+ EX(swc1 $f22,(SC_FPREGS+176)(a0))
+ EX(swc1 $f23,(SC_FPREGS+184)(a0))
+ EX(swc1 $f24,(SC_FPREGS+192)(a0))
+ EX(swc1 $f25,(SC_FPREGS+200)(a0))
+ EX(swc1 $f26,(SC_FPREGS+208)(a0))
+ EX(swc1 $f27,(SC_FPREGS+216)(a0))
+ EX(swc1 $f28,(SC_FPREGS+224)(a0))
+ EX(swc1 $f29,(SC_FPREGS+232)(a0))
+ EX(swc1 $f30,(SC_FPREGS+240)(a0))
+ EX(swc1 $f31,(SC_FPREGS+248)(a0))
+ EX(sw t1,(SC_FPC_CSR)(a0))
+ cfc1 t0,$0 # implementation/version
+ jr ra
+ .set nomacro
+ EX(sw t0,(SC_FPC_EIR)(a0))
+ .set macro
+ END(_save_fp_context)
+
+/*
+ * Restore FPU state:
+ * - fp gp registers
+ * - cp1 status/control register
+ *
+ * We base the decision which registers to restore from the signal stack
+ * frame on the current content of c0_status, not on the content of the
+ * stack frame which might have been changed by the user.
+ */
+LEAF(_restore_fp_context)
+ li v0, 0 # assume success
+ EX(lw t0,(SC_FPC_CSR)(a0))
+ EX(lwc1 $f0,(SC_FPREGS+0)(a0))
+ EX(lwc1 $f1,(SC_FPREGS+8)(a0))
+ EX(lwc1 $f2,(SC_FPREGS+16)(a0))
+ EX(lwc1 $f3,(SC_FPREGS+24)(a0))
+ EX(lwc1 $f4,(SC_FPREGS+32)(a0))
+ EX(lwc1 $f5,(SC_FPREGS+40)(a0))
+ EX(lwc1 $f6,(SC_FPREGS+48)(a0))
+ EX(lwc1 $f7,(SC_FPREGS+56)(a0))
+ EX(lwc1 $f8,(SC_FPREGS+64)(a0))
+ EX(lwc1 $f9,(SC_FPREGS+72)(a0))
+ EX(lwc1 $f10,(SC_FPREGS+80)(a0))
+ EX(lwc1 $f11,(SC_FPREGS+88)(a0))
+ EX(lwc1 $f12,(SC_FPREGS+96)(a0))
+ EX(lwc1 $f13,(SC_FPREGS+104)(a0))
+ EX(lwc1 $f14,(SC_FPREGS+112)(a0))
+ EX(lwc1 $f15,(SC_FPREGS+120)(a0))
+ EX(lwc1 $f16,(SC_FPREGS+128)(a0))
+ EX(lwc1 $f17,(SC_FPREGS+136)(a0))
+ EX(lwc1 $f18,(SC_FPREGS+144)(a0))
+ EX(lwc1 $f19,(SC_FPREGS+152)(a0))
+ EX(lwc1 $f20,(SC_FPREGS+160)(a0))
+ EX(lwc1 $f21,(SC_FPREGS+168)(a0))
+ EX(lwc1 $f22,(SC_FPREGS+176)(a0))
+ EX(lwc1 $f23,(SC_FPREGS+184)(a0))
+ EX(lwc1 $f24,(SC_FPREGS+192)(a0))
+ EX(lwc1 $f25,(SC_FPREGS+200)(a0))
+ EX(lwc1 $f26,(SC_FPREGS+208)(a0))
+ EX(lwc1 $f27,(SC_FPREGS+216)(a0))
+ EX(lwc1 $f28,(SC_FPREGS+224)(a0))
+ EX(lwc1 $f29,(SC_FPREGS+232)(a0))
+ EX(lwc1 $f30,(SC_FPREGS+240)(a0))
+ EX(lwc1 $f31,(SC_FPREGS+248)(a0))
+ jr ra
+ ctc1 t0,fcr31
+ END(_restore_fp_context)
+ .set reorder
+
+ .type fault@function
+ .ent fault
+fault: li v0, -EFAULT
+ jr ra
+ .end fault
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
new file mode 100644
index 00000000..29389839
--- /dev/null
+++ b/arch/mips/kernel/r2300_switch.S
@@ -0,0 +1,170 @@
+/*
+ * r2300_switch.S: R2300 specific task switching code.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996 by Andreas Busse
+ *
+ * Multi-cpu abstraction and macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ *
+ * Further modifications to make this work:
+ * Copyright (c) 1998-2000 Harald Koerfgen
+ */
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+
+#include <asm/asmmacro.h>
+
+ .set mips1
+ .align 5
+
+/*
+ * Offset to the current process status flags, the first 32 bytes of the
+ * stack are not used.
+ */
+#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
+
+/*
+ * FPU context is saved iff the process has used it's FPU in the current
+ * time slice as indicated by TIF_USEDFPU. In any case, the CU1 bit for user
+ * space STATUS register should be 0, so that a process *always* starts its
+ * userland with FPU disabled after each context switch.
+ *
+ * FPU will be enabled as soon as the process accesses FPU again, through
+ * do_cpu() trap.
+ */
+
+/*
+ * task_struct *resume(task_struct *prev, task_struct *next,
+ * struct thread_info *next_ti) )
+ */
+LEAF(resume)
+ mfc0 t1, CP0_STATUS
+ sw t1, THREAD_STATUS(a0)
+ cpu_save_nonscratch a0
+ sw ra, THREAD_REG31(a0)
+
+ /*
+ * check if we need to save FPU registers
+ */
+ lw t3, TASK_THREAD_INFO(a0)
+ lw t0, TI_FLAGS(t3)
+ li t1, _TIF_USEDFPU
+ and t2, t0, t1
+ beqz t2, 1f
+ nor t1, zero, t1
+
+ and t0, t0, t1
+ sw t0, TI_FLAGS(t3)
+
+ /*
+ * clear saved user stack CU1 bit
+ */
+ lw t0, ST_OFF(t3)
+ li t1, ~ST0_CU1
+ and t0, t0, t1
+ sw t0, ST_OFF(t3)
+
+ fpu_save_single a0, t0 # clobbers t0
+
+1:
+ /*
+ * The order of restoring the registers takes care of the race
+ * updating $28, $29 and kernelsp without disabling ints.
+ */
+ move $28, a2
+ cpu_restore_nonscratch a1
+
+ addiu t1, $28, _THREAD_SIZE - 32
+ sw t1, kernelsp
+
+ mfc0 t1, CP0_STATUS /* Do we really need this? */
+ li a3, 0xff01
+ and t1, a3
+ lw a2, THREAD_STATUS(a1)
+ nor a3, $0, a3
+ and a2, a3
+ or a2, t1
+ mtc0 a2, CP0_STATUS
+ move v0, a0
+ jr ra
+ END(resume)
+
+/*
+ * Save a thread's fp context.
+ */
+LEAF(_save_fp)
+ fpu_save_single a0, t1 # clobbers t1
+ jr ra
+ END(_save_fp)
+
+/*
+ * Restore a thread's fp context.
+ */
+LEAF(_restore_fp)
+ fpu_restore_single a0, t1 # clobbers t1
+ jr ra
+ END(_restore_fp)
+
+/*
+ * Load the FPU with signalling NANS. This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * We initialize fcr31 to rounding to nearest, no exceptions.
+ */
+
+#define FPU_DEFAULT 0x00000000
+
+LEAF(_init_fpu)
+ mfc0 t0, CP0_STATUS
+ li t1, ST0_CU1
+ or t0, t1
+ mtc0 t0, CP0_STATUS
+
+ li t1, FPU_DEFAULT
+ ctc1 t1, fcr31
+
+ li t0, -1
+
+ mtc1 t0, $f0
+ mtc1 t0, $f1
+ mtc1 t0, $f2
+ mtc1 t0, $f3
+ mtc1 t0, $f4
+ mtc1 t0, $f5
+ mtc1 t0, $f6
+ mtc1 t0, $f7
+ mtc1 t0, $f8
+ mtc1 t0, $f9
+ mtc1 t0, $f10
+ mtc1 t0, $f11
+ mtc1 t0, $f12
+ mtc1 t0, $f13
+ mtc1 t0, $f14
+ mtc1 t0, $f15
+ mtc1 t0, $f16
+ mtc1 t0, $f17
+ mtc1 t0, $f18
+ mtc1 t0, $f19
+ mtc1 t0, $f20
+ mtc1 t0, $f21
+ mtc1 t0, $f22
+ mtc1 t0, $f23
+ mtc1 t0, $f24
+ mtc1 t0, $f25
+ mtc1 t0, $f26
+ mtc1 t0, $f27
+ mtc1 t0, $f28
+ mtc1 t0, $f29
+ mtc1 t0, $f30
+ mtc1 t0, $f31
+ jr ra
+ END(_init_fpu)
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
new file mode 100644
index 00000000..55ffe149
--- /dev/null
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -0,0 +1,188 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 98, 99, 2000, 01 Ralf Baechle
+ *
+ * Multi-arch abstraction and asm macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/errno.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+ .macro EX insn, reg, src
+ .set push
+ .set nomacro
+.ex\@: \insn \reg, \src
+ .set pop
+ .section __ex_table,"a"
+ PTR .ex\@, fault
+ .previous
+ .endm
+
+ .set noreorder
+ .set mips3
+
+LEAF(_save_fp_context)
+ cfc1 t1, fcr31
+
+#ifdef CONFIG_64BIT
+ /* Store the 16 odd double precision registers */
+ EX sdc1 $f1, SC_FPREGS+8(a0)
+ EX sdc1 $f3, SC_FPREGS+24(a0)
+ EX sdc1 $f5, SC_FPREGS+40(a0)
+ EX sdc1 $f7, SC_FPREGS+56(a0)
+ EX sdc1 $f9, SC_FPREGS+72(a0)
+ EX sdc1 $f11, SC_FPREGS+88(a0)
+ EX sdc1 $f13, SC_FPREGS+104(a0)
+ EX sdc1 $f15, SC_FPREGS+120(a0)
+ EX sdc1 $f17, SC_FPREGS+136(a0)
+ EX sdc1 $f19, SC_FPREGS+152(a0)
+ EX sdc1 $f21, SC_FPREGS+168(a0)
+ EX sdc1 $f23, SC_FPREGS+184(a0)
+ EX sdc1 $f25, SC_FPREGS+200(a0)
+ EX sdc1 $f27, SC_FPREGS+216(a0)
+ EX sdc1 $f29, SC_FPREGS+232(a0)
+ EX sdc1 $f31, SC_FPREGS+248(a0)
+#endif
+
+ /* Store the 16 even double precision registers */
+ EX sdc1 $f0, SC_FPREGS+0(a0)
+ EX sdc1 $f2, SC_FPREGS+16(a0)
+ EX sdc1 $f4, SC_FPREGS+32(a0)
+ EX sdc1 $f6, SC_FPREGS+48(a0)
+ EX sdc1 $f8, SC_FPREGS+64(a0)
+ EX sdc1 $f10, SC_FPREGS+80(a0)
+ EX sdc1 $f12, SC_FPREGS+96(a0)
+ EX sdc1 $f14, SC_FPREGS+112(a0)
+ EX sdc1 $f16, SC_FPREGS+128(a0)
+ EX sdc1 $f18, SC_FPREGS+144(a0)
+ EX sdc1 $f20, SC_FPREGS+160(a0)
+ EX sdc1 $f22, SC_FPREGS+176(a0)
+ EX sdc1 $f24, SC_FPREGS+192(a0)
+ EX sdc1 $f26, SC_FPREGS+208(a0)
+ EX sdc1 $f28, SC_FPREGS+224(a0)
+ EX sdc1 $f30, SC_FPREGS+240(a0)
+ EX sw t1, SC_FPC_CSR(a0)
+ jr ra
+ li v0, 0 # success
+ END(_save_fp_context)
+
+#ifdef CONFIG_MIPS32_COMPAT
+ /* Save 32-bit process floating point context */
+LEAF(_save_fp_context32)
+ cfc1 t1, fcr31
+
+ EX sdc1 $f0, SC32_FPREGS+0(a0)
+ EX sdc1 $f2, SC32_FPREGS+16(a0)
+ EX sdc1 $f4, SC32_FPREGS+32(a0)
+ EX sdc1 $f6, SC32_FPREGS+48(a0)
+ EX sdc1 $f8, SC32_FPREGS+64(a0)
+ EX sdc1 $f10, SC32_FPREGS+80(a0)
+ EX sdc1 $f12, SC32_FPREGS+96(a0)
+ EX sdc1 $f14, SC32_FPREGS+112(a0)
+ EX sdc1 $f16, SC32_FPREGS+128(a0)
+ EX sdc1 $f18, SC32_FPREGS+144(a0)
+ EX sdc1 $f20, SC32_FPREGS+160(a0)
+ EX sdc1 $f22, SC32_FPREGS+176(a0)
+ EX sdc1 $f24, SC32_FPREGS+192(a0)
+ EX sdc1 $f26, SC32_FPREGS+208(a0)
+ EX sdc1 $f28, SC32_FPREGS+224(a0)
+ EX sdc1 $f30, SC32_FPREGS+240(a0)
+ EX sw t1, SC32_FPC_CSR(a0)
+ cfc1 t0, $0 # implementation/version
+ EX sw t0, SC32_FPC_EIR(a0)
+
+ jr ra
+ li v0, 0 # success
+ END(_save_fp_context32)
+#endif
+
+/*
+ * Restore FPU state:
+ * - fp gp registers
+ * - cp1 status/control register
+ */
+LEAF(_restore_fp_context)
+ EX lw t0, SC_FPC_CSR(a0)
+#ifdef CONFIG_64BIT
+ EX ldc1 $f1, SC_FPREGS+8(a0)
+ EX ldc1 $f3, SC_FPREGS+24(a0)
+ EX ldc1 $f5, SC_FPREGS+40(a0)
+ EX ldc1 $f7, SC_FPREGS+56(a0)
+ EX ldc1 $f9, SC_FPREGS+72(a0)
+ EX ldc1 $f11, SC_FPREGS+88(a0)
+ EX ldc1 $f13, SC_FPREGS+104(a0)
+ EX ldc1 $f15, SC_FPREGS+120(a0)
+ EX ldc1 $f17, SC_FPREGS+136(a0)
+ EX ldc1 $f19, SC_FPREGS+152(a0)
+ EX ldc1 $f21, SC_FPREGS+168(a0)
+ EX ldc1 $f23, SC_FPREGS+184(a0)
+ EX ldc1 $f25, SC_FPREGS+200(a0)
+ EX ldc1 $f27, SC_FPREGS+216(a0)
+ EX ldc1 $f29, SC_FPREGS+232(a0)
+ EX ldc1 $f31, SC_FPREGS+248(a0)
+#endif
+ EX ldc1 $f0, SC_FPREGS+0(a0)
+ EX ldc1 $f2, SC_FPREGS+16(a0)
+ EX ldc1 $f4, SC_FPREGS+32(a0)
+ EX ldc1 $f6, SC_FPREGS+48(a0)
+ EX ldc1 $f8, SC_FPREGS+64(a0)
+ EX ldc1 $f10, SC_FPREGS+80(a0)
+ EX ldc1 $f12, SC_FPREGS+96(a0)
+ EX ldc1 $f14, SC_FPREGS+112(a0)
+ EX ldc1 $f16, SC_FPREGS+128(a0)
+ EX ldc1 $f18, SC_FPREGS+144(a0)
+ EX ldc1 $f20, SC_FPREGS+160(a0)
+ EX ldc1 $f22, SC_FPREGS+176(a0)
+ EX ldc1 $f24, SC_FPREGS+192(a0)
+ EX ldc1 $f26, SC_FPREGS+208(a0)
+ EX ldc1 $f28, SC_FPREGS+224(a0)
+ EX ldc1 $f30, SC_FPREGS+240(a0)
+ ctc1 t0, fcr31
+ jr ra
+ li v0, 0 # success
+ END(_restore_fp_context)
+
+#ifdef CONFIG_MIPS32_COMPAT
+LEAF(_restore_fp_context32)
+ /* Restore an o32 sigcontext. */
+ EX lw t0, SC32_FPC_CSR(a0)
+ EX ldc1 $f0, SC32_FPREGS+0(a0)
+ EX ldc1 $f2, SC32_FPREGS+16(a0)
+ EX ldc1 $f4, SC32_FPREGS+32(a0)
+ EX ldc1 $f6, SC32_FPREGS+48(a0)
+ EX ldc1 $f8, SC32_FPREGS+64(a0)
+ EX ldc1 $f10, SC32_FPREGS+80(a0)
+ EX ldc1 $f12, SC32_FPREGS+96(a0)
+ EX ldc1 $f14, SC32_FPREGS+112(a0)
+ EX ldc1 $f16, SC32_FPREGS+128(a0)
+ EX ldc1 $f18, SC32_FPREGS+144(a0)
+ EX ldc1 $f20, SC32_FPREGS+160(a0)
+ EX ldc1 $f22, SC32_FPREGS+176(a0)
+ EX ldc1 $f24, SC32_FPREGS+192(a0)
+ EX ldc1 $f26, SC32_FPREGS+208(a0)
+ EX ldc1 $f28, SC32_FPREGS+224(a0)
+ EX ldc1 $f30, SC32_FPREGS+240(a0)
+ ctc1 t0, fcr31
+ jr ra
+ li v0, 0 # success
+ END(_restore_fp_context32)
+#endif
+
+ .set reorder
+
+ .type fault@function
+ .ent fault
+fault: li v0, -EFAULT # failure
+ jr ra
+ .end fault
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
new file mode 100644
index 00000000..9414f935
--- /dev/null
+++ b/arch/mips/kernel/r4k_switch.S
@@ -0,0 +1,252 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1994, 1995, 1996, by Andreas Busse
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ * written by Carsten Langgaard, carstenl@mips.com
+ */
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+
+#include <asm/asmmacro.h>
+
+/*
+ * Offset to the current process status flags, the first 32 bytes of the
+ * stack are not used.
+ */
+#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
+
+/*
+ * FPU context is saved iff the process has used it's FPU in the current
+ * time slice as indicated by _TIF_USEDFPU. In any case, the CU1 bit for user
+ * space STATUS register should be 0, so that a process *always* starts its
+ * userland with FPU disabled after each context switch.
+ *
+ * FPU will be enabled as soon as the process accesses FPU again, through
+ * do_cpu() trap.
+ */
+
+/*
+ * task_struct *resume(task_struct *prev, task_struct *next,
+ * struct thread_info *next_ti)
+ */
+ .align 5
+ LEAF(resume)
+ mfc0 t1, CP0_STATUS
+ LONG_S t1, THREAD_STATUS(a0)
+ cpu_save_nonscratch a0
+ LONG_S ra, THREAD_REG31(a0)
+
+ /*
+ * check if we need to save FPU registers
+ */
+ PTR_L t3, TASK_THREAD_INFO(a0)
+ LONG_L t0, TI_FLAGS(t3)
+ li t1, _TIF_USEDFPU
+ and t2, t0, t1
+ beqz t2, 1f
+ nor t1, zero, t1
+
+ and t0, t0, t1
+ LONG_S t0, TI_FLAGS(t3)
+
+ /*
+ * clear saved user stack CU1 bit
+ */
+ LONG_L t0, ST_OFF(t3)
+ li t1, ~ST0_CU1
+ and t0, t0, t1
+ LONG_S t0, ST_OFF(t3)
+
+ fpu_save_double a0 t0 t1 # c0_status passed in t0
+ # clobbers t1
+1:
+
+ /*
+ * The order of restoring the registers takes care of the race
+ * updating $28, $29 and kernelsp without disabling ints.
+ */
+ move $28, a2
+ cpu_restore_nonscratch a1
+
+ PTR_ADDU t0, $28, _THREAD_SIZE - 32
+ set_saved_sp t0, t1, t2
+#ifdef CONFIG_MIPS_MT_SMTC
+ /* Read-modify-writes of Status must be atomic on a VPE */
+ mfc0 t2, CP0_TCSTATUS
+ ori t1, t2, TCSTATUS_IXMT
+ mtc0 t1, CP0_TCSTATUS
+ andi t2, t2, TCSTATUS_IXMT
+ _ehb
+ DMT 8 # dmt t0
+ move t1,ra
+ jal mips_ihb
+ move ra,t1
+#endif /* CONFIG_MIPS_MT_SMTC */
+ mfc0 t1, CP0_STATUS /* Do we really need this? */
+ li a3, 0xff01
+ and t1, a3
+ LONG_L a2, THREAD_STATUS(a1)
+ nor a3, $0, a3
+ and a2, a3
+ or a2, t1
+ mtc0 a2, CP0_STATUS
+#ifdef CONFIG_MIPS_MT_SMTC
+ _ehb
+ andi t0, t0, VPECONTROL_TE
+ beqz t0, 1f
+ emt
+1:
+ mfc0 t1, CP0_TCSTATUS
+ xori t1, t1, TCSTATUS_IXMT
+ or t1, t1, t2
+ mtc0 t1, CP0_TCSTATUS
+ _ehb
+#endif /* CONFIG_MIPS_MT_SMTC */
+ move v0, a0
+ jr ra
+ END(resume)
+
+/*
+ * Save a thread's fp context.
+ */
+LEAF(_save_fp)
+#ifdef CONFIG_64BIT
+ mfc0 t0, CP0_STATUS
+#endif
+ fpu_save_double a0 t0 t1 # clobbers t1
+ jr ra
+ END(_save_fp)
+
+/*
+ * Restore a thread's fp context.
+ */
+LEAF(_restore_fp)
+#ifdef CONFIG_64BIT
+ mfc0 t0, CP0_STATUS
+#endif
+ fpu_restore_double a0 t0 t1 # clobbers t1
+ jr ra
+ END(_restore_fp)
+
+/*
+ * Load the FPU with signalling NANS. This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * We initialize fcr31 to rounding to nearest, no exceptions.
+ */
+
+#define FPU_DEFAULT 0x00000000
+
+LEAF(_init_fpu)
+#ifdef CONFIG_MIPS_MT_SMTC
+ /* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */
+ mfc0 t0, CP0_TCSTATUS
+ /* Bit position is the same for Status, TCStatus */
+ li t1, ST0_CU1
+ or t0, t1
+ mtc0 t0, CP0_TCSTATUS
+#else /* Normal MIPS CU1 enable */
+ mfc0 t0, CP0_STATUS
+ li t1, ST0_CU1
+ or t0, t1
+ mtc0 t0, CP0_STATUS
+#endif /* CONFIG_MIPS_MT_SMTC */
+ enable_fpu_hazard
+
+ li t1, FPU_DEFAULT
+ ctc1 t1, fcr31
+
+ li t1, -1 # SNaN
+
+#ifdef CONFIG_64BIT
+ sll t0, t0, 5
+ bgez t0, 1f # 16 / 32 register mode?
+
+ dmtc1 t1, $f1
+ dmtc1 t1, $f3
+ dmtc1 t1, $f5
+ dmtc1 t1, $f7
+ dmtc1 t1, $f9
+ dmtc1 t1, $f11
+ dmtc1 t1, $f13
+ dmtc1 t1, $f15
+ dmtc1 t1, $f17
+ dmtc1 t1, $f19
+ dmtc1 t1, $f21
+ dmtc1 t1, $f23
+ dmtc1 t1, $f25
+ dmtc1 t1, $f27
+ dmtc1 t1, $f29
+ dmtc1 t1, $f31
+1:
+#endif
+
+#ifdef CONFIG_CPU_MIPS32
+ mtc1 t1, $f0
+ mtc1 t1, $f1
+ mtc1 t1, $f2
+ mtc1 t1, $f3
+ mtc1 t1, $f4
+ mtc1 t1, $f5
+ mtc1 t1, $f6
+ mtc1 t1, $f7
+ mtc1 t1, $f8
+ mtc1 t1, $f9
+ mtc1 t1, $f10
+ mtc1 t1, $f11
+ mtc1 t1, $f12
+ mtc1 t1, $f13
+ mtc1 t1, $f14
+ mtc1 t1, $f15
+ mtc1 t1, $f16
+ mtc1 t1, $f17
+ mtc1 t1, $f18
+ mtc1 t1, $f19
+ mtc1 t1, $f20
+ mtc1 t1, $f21
+ mtc1 t1, $f22
+ mtc1 t1, $f23
+ mtc1 t1, $f24
+ mtc1 t1, $f25
+ mtc1 t1, $f26
+ mtc1 t1, $f27
+ mtc1 t1, $f28
+ mtc1 t1, $f29
+ mtc1 t1, $f30
+ mtc1 t1, $f31
+#else
+ .set mips3
+ dmtc1 t1, $f0
+ dmtc1 t1, $f2
+ dmtc1 t1, $f4
+ dmtc1 t1, $f6
+ dmtc1 t1, $f8
+ dmtc1 t1, $f10
+ dmtc1 t1, $f12
+ dmtc1 t1, $f14
+ dmtc1 t1, $f16
+ dmtc1 t1, $f18
+ dmtc1 t1, $f20
+ dmtc1 t1, $f22
+ dmtc1 t1, $f24
+ dmtc1 t1, $f26
+ dmtc1 t1, $f28
+ dmtc1 t1, $f30
+#endif
+ jr ra
+ END(_init_fpu)
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
new file mode 100644
index 00000000..da0fbe46
--- /dev/null
+++ b/arch/mips/kernel/r6000_fpu.S
@@ -0,0 +1,87 @@
+/*
+ * r6000_fpu.S: Save/restore floating point context for signal handlers.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 by Ralf Baechle
+ *
+ * Multi-arch abstraction and asm macros for easier reading:
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ */
+#include <asm/asm.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+ .set noreorder
+ .set mips2
+ /* Save floating point context */
+ LEAF(_save_fp_context)
+ mfc0 t0,CP0_STATUS
+ sll t0,t0,2
+ bgez t0,1f
+ nop
+
+ cfc1 t1,fcr31
+ /* Store the 16 double precision registers */
+ sdc1 $f0,(SC_FPREGS+0)(a0)
+ sdc1 $f2,(SC_FPREGS+16)(a0)
+ sdc1 $f4,(SC_FPREGS+32)(a0)
+ sdc1 $f6,(SC_FPREGS+48)(a0)
+ sdc1 $f8,(SC_FPREGS+64)(a0)
+ sdc1 $f10,(SC_FPREGS+80)(a0)
+ sdc1 $f12,(SC_FPREGS+96)(a0)
+ sdc1 $f14,(SC_FPREGS+112)(a0)
+ sdc1 $f16,(SC_FPREGS+128)(a0)
+ sdc1 $f18,(SC_FPREGS+144)(a0)
+ sdc1 $f20,(SC_FPREGS+160)(a0)
+ sdc1 $f22,(SC_FPREGS+176)(a0)
+ sdc1 $f24,(SC_FPREGS+192)(a0)
+ sdc1 $f26,(SC_FPREGS+208)(a0)
+ sdc1 $f28,(SC_FPREGS+224)(a0)
+ sdc1 $f30,(SC_FPREGS+240)(a0)
+ jr ra
+ sw t0,SC_FPC_CSR(a0)
+1: jr ra
+ nop
+ END(_save_fp_context)
+
+/* Restore FPU state:
+ * - fp gp registers
+ * - cp1 status/control register
+ *
+ * We base the decision which registers to restore from the signal stack
+ * frame on the current content of c0_status, not on the content of the
+ * stack frame which might have been changed by the user.
+ */
+ LEAF(_restore_fp_context)
+ mfc0 t0,CP0_STATUS
+ sll t0,t0,2
+
+ bgez t0,1f
+ lw t0,SC_FPC_CSR(a0)
+ /* Restore the 16 double precision registers */
+ ldc1 $f0,(SC_FPREGS+0)(a0)
+ ldc1 $f2,(SC_FPREGS+16)(a0)
+ ldc1 $f4,(SC_FPREGS+32)(a0)
+ ldc1 $f6,(SC_FPREGS+48)(a0)
+ ldc1 $f8,(SC_FPREGS+64)(a0)
+ ldc1 $f10,(SC_FPREGS+80)(a0)
+ ldc1 $f12,(SC_FPREGS+96)(a0)
+ ldc1 $f14,(SC_FPREGS+112)(a0)
+ ldc1 $f16,(SC_FPREGS+128)(a0)
+ ldc1 $f18,(SC_FPREGS+144)(a0)
+ ldc1 $f20,(SC_FPREGS+160)(a0)
+ ldc1 $f22,(SC_FPREGS+176)(a0)
+ ldc1 $f24,(SC_FPREGS+192)(a0)
+ ldc1 $f26,(SC_FPREGS+208)(a0)
+ ldc1 $f28,(SC_FPREGS+224)(a0)
+ ldc1 $f30,(SC_FPREGS+240)(a0)
+ jr ra
+ ctc1 t0,fcr31
+1: jr ra
+ nop
+ END(_restore_fp_context)
diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S
new file mode 100644
index 00000000..87481f91
--- /dev/null
+++ b/arch/mips/kernel/relocate_kernel.S
@@ -0,0 +1,82 @@
+/*
+ * relocate_kernel.S for kexec
+ * Created by <nschichan@corp.free.fr> on Thu Oct 12 17:49:57 2006
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/regdef.h>
+#include <asm/page.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/addrspace.h>
+
+LEAF(relocate_new_kernel)
+ PTR_L s0, kexec_indirection_page
+ PTR_L s1, kexec_start_address
+
+process_entry:
+ PTR_L s2, (s0)
+ PTR_ADD s0, s0, SZREG
+
+ /* destination page */
+ and s3, s2, 0x1
+ beq s3, zero, 1f
+ and s4, s2, ~0x1 /* store destination addr in s4 */
+ move a0, s4
+ b process_entry
+
+1:
+ /* indirection page, update s0 */
+ and s3, s2, 0x2
+ beq s3, zero, 1f
+ and s0, s2, ~0x2
+ b process_entry
+
+1:
+ /* done page */
+ and s3, s2, 0x4
+ beq s3, zero, 1f
+ b done
+1:
+ /* source page */
+ and s3, s2, 0x8
+ beq s3, zero, process_entry
+ and s2, s2, ~0x8
+ li s6, (1 << PAGE_SHIFT) / SZREG
+
+copy_word:
+ /* copy page word by word */
+ REG_L s5, (s2)
+ REG_S s5, (s4)
+ PTR_ADD s4, s4, SZREG
+ PTR_ADD s2, s2, SZREG
+ LONG_SUB s6, s6, 1
+ beq s6, zero, process_entry
+ b copy_word
+ b process_entry
+
+done:
+ /* jump to kexec_start_address */
+ j s1
+ END(relocate_new_kernel)
+
+kexec_start_address:
+ EXPORT(kexec_start_address)
+ PTR 0x0
+ .size kexec_start_address, PTRSIZE
+
+kexec_indirection_page:
+ EXPORT(kexec_indirection_page)
+ PTR 0
+ .size kexec_indirection_page, PTRSIZE
+
+relocate_new_kernel_end:
+
+relocate_new_kernel_size:
+ EXPORT(relocate_new_kernel_size)
+ PTR relocate_new_kernel_end - relocate_new_kernel
+ .size relocate_new_kernel_size, PTRSIZE
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c
new file mode 100644
index 00000000..060563a7
--- /dev/null
+++ b/arch/mips/kernel/reset.c
@@ -0,0 +1,44 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001, 06 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/types.h>
+#include <linux/reboot.h>
+
+#include <asm/reboot.h>
+
+/*
+ * Urgs ... Too many MIPS machines to handle this in a generic way.
+ * So handle all using function pointers to machine specific
+ * functions.
+ */
+void (*_machine_restart)(char *command);
+void (*_machine_halt)(void);
+void (*pm_power_off)(void);
+
+EXPORT_SYMBOL(pm_power_off);
+
+void machine_restart(char *command)
+{
+ if (_machine_restart)
+ _machine_restart(command);
+}
+
+void machine_halt(void)
+{
+ if (_machine_halt)
+ _machine_halt();
+}
+
+void machine_power_off(void)
+{
+ if (pm_power_off)
+ pm_power_off();
+}
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
new file mode 100644
index 00000000..557ef724
--- /dev/null
+++ b/arch/mips/kernel/rtlx.c
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2005, 06 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/list.h>
+#include <linux/vmalloc.h>
+#include <linux/elf.h>
+#include <linux/seq_file.h>
+#include <linux/syscalls.h>
+#include <linux/moduleloader.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <asm/mipsmtregs.h>
+#include <asm/mips_mt.h>
+#include <asm/cacheflush.h>
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/vpe.h>
+#include <asm/rtlx.h>
+
+static struct rtlx_info *rtlx;
+static int major;
+static char module_name[] = "rtlx";
+
+static struct chan_waitqueues {
+ wait_queue_head_t rt_queue;
+ wait_queue_head_t lx_queue;
+ atomic_t in_open;
+ struct mutex mutex;
+} channel_wqs[RTLX_CHANNELS];
+
+static struct vpe_notifications notify;
+static int sp_stopping;
+
+extern void *vpe_get_shared(int index);
+
+static void rtlx_dispatch(void)
+{
+ do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ);
+}
+
+
+/* Interrupt handler may be called before rtlx_init has otherwise had
+ a chance to run.
+*/
+static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
+{
+ unsigned int vpeflags;
+ unsigned long flags;
+ int i;
+
+ /* Ought not to be strictly necessary for SMTC builds */
+ local_irq_save(flags);
+ vpeflags = dvpe();
+ set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
+ irq_enable_hazard();
+ evpe(vpeflags);
+ local_irq_restore(flags);
+
+ for (i = 0; i < RTLX_CHANNELS; i++) {
+ wake_up(&channel_wqs[i].lx_queue);
+ wake_up(&channel_wqs[i].rt_queue);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void __used dump_rtlx(void)
+{
+ int i;
+
+ printk("id 0x%lx state %d\n", rtlx->id, rtlx->state);
+
+ for (i = 0; i < RTLX_CHANNELS; i++) {
+ struct rtlx_channel *chan = &rtlx->channel[i];
+
+ printk(" rt_state %d lx_state %d buffer_size %d\n",
+ chan->rt_state, chan->lx_state, chan->buffer_size);
+
+ printk(" rt_read %d rt_write %d\n",
+ chan->rt_read, chan->rt_write);
+
+ printk(" lx_read %d lx_write %d\n",
+ chan->lx_read, chan->lx_write);
+
+ printk(" rt_buffer <%s>\n", chan->rt_buffer);
+ printk(" lx_buffer <%s>\n", chan->lx_buffer);
+ }
+}
+
+/* call when we have the address of the shared structure from the SP side. */
+static int rtlx_init(struct rtlx_info *rtlxi)
+{
+ if (rtlxi->id != RTLX_ID) {
+ printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n",
+ rtlxi, rtlxi->id);
+ return -ENOEXEC;
+ }
+
+ rtlx = rtlxi;
+
+ return 0;
+}
+
+/* notifications */
+static void starting(int vpe)
+{
+ int i;
+ sp_stopping = 0;
+
+ /* force a reload of rtlx */
+ rtlx=NULL;
+
+ /* wake up any sleeping rtlx_open's */
+ for (i = 0; i < RTLX_CHANNELS; i++)
+ wake_up_interruptible(&channel_wqs[i].lx_queue);
+}
+
+static void stopping(int vpe)
+{
+ int i;
+
+ sp_stopping = 1;
+ for (i = 0; i < RTLX_CHANNELS; i++)
+ wake_up_interruptible(&channel_wqs[i].lx_queue);
+}
+
+
+int rtlx_open(int index, int can_sleep)
+{
+ struct rtlx_info **p;
+ struct rtlx_channel *chan;
+ enum rtlx_state state;
+ int ret = 0;
+
+ if (index >= RTLX_CHANNELS) {
+ printk(KERN_DEBUG "rtlx_open index out of range\n");
+ return -ENOSYS;
+ }
+
+ if (atomic_inc_return(&channel_wqs[index].in_open) > 1) {
+ printk(KERN_DEBUG "rtlx_open channel %d already opened\n",
+ index);
+ ret = -EBUSY;
+ goto out_fail;
+ }
+
+ if (rtlx == NULL) {
+ if( (p = vpe_get_shared(tclimit)) == NULL) {
+ if (can_sleep) {
+ __wait_event_interruptible(channel_wqs[index].lx_queue,
+ (p = vpe_get_shared(tclimit)), ret);
+ if (ret)
+ goto out_fail;
+ } else {
+ printk(KERN_DEBUG "No SP program loaded, and device "
+ "opened with O_NONBLOCK\n");
+ ret = -ENOSYS;
+ goto out_fail;
+ }
+ }
+
+ smp_rmb();
+ if (*p == NULL) {
+ if (can_sleep) {
+ DEFINE_WAIT(wait);
+
+ for (;;) {
+ prepare_to_wait(
+ &channel_wqs[index].lx_queue,
+ &wait, TASK_INTERRUPTIBLE);
+ smp_rmb();
+ if (*p != NULL)
+ break;
+ if (!signal_pending(current)) {
+ schedule();
+ continue;
+ }
+ ret = -ERESTARTSYS;
+ goto out_fail;
+ }
+ finish_wait(&channel_wqs[index].lx_queue, &wait);
+ } else {
+ pr_err(" *vpe_get_shared is NULL. "
+ "Has an SP program been loaded?\n");
+ ret = -ENOSYS;
+ goto out_fail;
+ }
+ }
+
+ if ((unsigned int)*p < KSEG0) {
+ printk(KERN_WARNING "vpe_get_shared returned an "
+ "invalid pointer maybe an error code %d\n",
+ (int)*p);
+ ret = -ENOSYS;
+ goto out_fail;
+ }
+
+ if ((ret = rtlx_init(*p)) < 0)
+ goto out_ret;
+ }
+
+ chan = &rtlx->channel[index];
+
+ state = xchg(&chan->lx_state, RTLX_STATE_OPENED);
+ if (state == RTLX_STATE_OPENED) {
+ ret = -EBUSY;
+ goto out_fail;
+ }
+
+out_fail:
+ smp_mb();
+ atomic_dec(&channel_wqs[index].in_open);
+ smp_mb();
+
+out_ret:
+ return ret;
+}
+
+int rtlx_release(int index)
+{
+ if (rtlx == NULL) {
+ pr_err("rtlx_release() with null rtlx\n");
+ return 0;
+ }
+ rtlx->channel[index].lx_state = RTLX_STATE_UNUSED;
+ return 0;
+}
+
+unsigned int rtlx_read_poll(int index, int can_sleep)
+{
+ struct rtlx_channel *chan;
+
+ if (rtlx == NULL)
+ return 0;
+
+ chan = &rtlx->channel[index];
+
+ /* data available to read? */
+ if (chan->lx_read == chan->lx_write) {
+ if (can_sleep) {
+ int ret = 0;
+
+ __wait_event_interruptible(channel_wqs[index].lx_queue,
+ (chan->lx_read != chan->lx_write) ||
+ sp_stopping, ret);
+ if (ret)
+ return ret;
+
+ if (sp_stopping)
+ return 0;
+ } else
+ return 0;
+ }
+
+ return (chan->lx_write + chan->buffer_size - chan->lx_read)
+ % chan->buffer_size;
+}
+
+static inline int write_spacefree(int read, int write, int size)
+{
+ if (read == write) {
+ /*
+ * Never fill the buffer completely, so indexes are always
+ * equal if empty and only empty, or !equal if data available
+ */
+ return size - 1;
+ }
+
+ return ((read + size - write) % size) - 1;
+}
+
+unsigned int rtlx_write_poll(int index)
+{
+ struct rtlx_channel *chan = &rtlx->channel[index];
+
+ return write_spacefree(chan->rt_read, chan->rt_write,
+ chan->buffer_size);
+}
+
+ssize_t rtlx_read(int index, void __user *buff, size_t count)
+{
+ size_t lx_write, fl = 0L;
+ struct rtlx_channel *lx;
+ unsigned long failed;
+
+ if (rtlx == NULL)
+ return -ENOSYS;
+
+ lx = &rtlx->channel[index];
+
+ mutex_lock(&channel_wqs[index].mutex);
+ smp_rmb();
+ lx_write = lx->lx_write;
+
+ /* find out how much in total */
+ count = min(count,
+ (size_t)(lx_write + lx->buffer_size - lx->lx_read)
+ % lx->buffer_size);
+
+ /* then how much from the read pointer onwards */
+ fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
+
+ failed = copy_to_user(buff, lx->lx_buffer + lx->lx_read, fl);
+ if (failed)
+ goto out;
+
+ /* and if there is anything left at the beginning of the buffer */
+ if (count - fl)
+ failed = copy_to_user(buff + fl, lx->lx_buffer, count - fl);
+
+out:
+ count -= failed;
+
+ smp_wmb();
+ lx->lx_read = (lx->lx_read + count) % lx->buffer_size;
+ smp_wmb();
+ mutex_unlock(&channel_wqs[index].mutex);
+
+ return count;
+}
+
+ssize_t rtlx_write(int index, const void __user *buffer, size_t count)
+{
+ struct rtlx_channel *rt;
+ unsigned long failed;
+ size_t rt_read;
+ size_t fl;
+
+ if (rtlx == NULL)
+ return(-ENOSYS);
+
+ rt = &rtlx->channel[index];
+
+ mutex_lock(&channel_wqs[index].mutex);
+ smp_rmb();
+ rt_read = rt->rt_read;
+
+ /* total number of bytes to copy */
+ count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write,
+ rt->buffer_size));
+
+ /* first bit from write pointer to the end of the buffer, or count */
+ fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
+
+ failed = copy_from_user(rt->rt_buffer + rt->rt_write, buffer, fl);
+ if (failed)
+ goto out;
+
+ /* if there's any left copy to the beginning of the buffer */
+ if (count - fl) {
+ failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
+ }
+
+out:
+ count -= failed;
+
+ smp_wmb();
+ rt->rt_write = (rt->rt_write + count) % rt->buffer_size;
+ smp_wmb();
+ mutex_unlock(&channel_wqs[index].mutex);
+
+ return count;
+}
+
+
+static int file_open(struct inode *inode, struct file *filp)
+{
+ return rtlx_open(iminor(inode), (filp->f_flags & O_NONBLOCK) ? 0 : 1);
+}
+
+static int file_release(struct inode *inode, struct file *filp)
+{
+ return rtlx_release(iminor(inode));
+}
+
+static unsigned int file_poll(struct file *file, poll_table * wait)
+{
+ int minor;
+ unsigned int mask = 0;
+
+ minor = iminor(file->f_path.dentry->d_inode);
+
+ poll_wait(file, &channel_wqs[minor].rt_queue, wait);
+ poll_wait(file, &channel_wqs[minor].lx_queue, wait);
+
+ if (rtlx == NULL)
+ return 0;
+
+ /* data available to read? */
+ if (rtlx_read_poll(minor, 0))
+ mask |= POLLIN | POLLRDNORM;
+
+ /* space to write */
+ if (rtlx_write_poll(minor))
+ mask |= POLLOUT | POLLWRNORM;
+
+ return mask;
+}
+
+static ssize_t file_read(struct file *file, char __user * buffer, size_t count,
+ loff_t * ppos)
+{
+ int minor = iminor(file->f_path.dentry->d_inode);
+
+ /* data available? */
+ if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) {
+ return 0; // -EAGAIN makes cat whinge
+ }
+
+ return rtlx_read(minor, buffer, count);
+}
+
+static ssize_t file_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t * ppos)
+{
+ int minor;
+ struct rtlx_channel *rt;
+
+ minor = iminor(file->f_path.dentry->d_inode);
+ rt = &rtlx->channel[minor];
+
+ /* any space left... */
+ if (!rtlx_write_poll(minor)) {
+ int ret = 0;
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ __wait_event_interruptible(channel_wqs[minor].rt_queue,
+ rtlx_write_poll(minor),
+ ret);
+ if (ret)
+ return ret;
+ }
+
+ return rtlx_write(minor, buffer, count);
+}
+
+static const struct file_operations rtlx_fops = {
+ .owner = THIS_MODULE,
+ .open = file_open,
+ .release = file_release,
+ .write = file_write,
+ .read = file_read,
+ .poll = file_poll,
+ .llseek = noop_llseek,
+};
+
+static struct irqaction rtlx_irq = {
+ .handler = rtlx_interrupt,
+ .flags = IRQF_DISABLED,
+ .name = "RTLX",
+};
+
+static int rtlx_irq_num = MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ;
+
+static char register_chrdev_failed[] __initdata =
+ KERN_ERR "rtlx_module_init: unable to register device\n";
+
+static int __init rtlx_module_init(void)
+{
+ struct device *dev;
+ int i, err;
+
+ if (!cpu_has_mipsmt) {
+ printk("VPE loader: not a MIPS MT capable processor\n");
+ return -ENODEV;
+ }
+
+ if (tclimit == 0) {
+ printk(KERN_WARNING "No TCs reserved for AP/SP, not "
+ "initializing RTLX.\nPass maxtcs=<n> argument as kernel "
+ "argument\n");
+
+ return -ENODEV;
+ }
+
+ major = register_chrdev(0, module_name, &rtlx_fops);
+ if (major < 0) {
+ printk(register_chrdev_failed);
+ return major;
+ }
+
+ /* initialise the wait queues */
+ for (i = 0; i < RTLX_CHANNELS; i++) {
+ init_waitqueue_head(&channel_wqs[i].rt_queue);
+ init_waitqueue_head(&channel_wqs[i].lx_queue);
+ atomic_set(&channel_wqs[i].in_open, 0);
+ mutex_init(&channel_wqs[i].mutex);
+
+ dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
+ "%s%d", module_name, i);
+ if (IS_ERR(dev)) {
+ err = PTR_ERR(dev);
+ goto out_chrdev;
+ }
+ }
+
+ /* set up notifiers */
+ notify.start = starting;
+ notify.stop = stopping;
+ vpe_notify(tclimit, &notify);
+
+ if (cpu_has_vint)
+ set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
+ else {
+ pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
+ err = -ENODEV;
+ goto out_chrdev;
+ }
+
+ rtlx_irq.dev_id = rtlx;
+ setup_irq(rtlx_irq_num, &rtlx_irq);
+
+ return 0;
+
+out_chrdev:
+ for (i = 0; i < RTLX_CHANNELS; i++)
+ device_destroy(mt_class, MKDEV(major, i));
+
+ return err;
+}
+
+static void __exit rtlx_module_exit(void)
+{
+ int i;
+
+ for (i = 0; i < RTLX_CHANNELS; i++)
+ device_destroy(mt_class, MKDEV(major, i));
+
+ unregister_chrdev(major, module_name);
+}
+
+module_init(rtlx_module_init);
+module_exit(rtlx_module_exit);
+
+MODULE_DESCRIPTION("MIPS RTLX");
+MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
new file mode 100644
index 00000000..99e656e4
--- /dev/null
+++ b/arch/mips/kernel/scall32-o32.S
@@ -0,0 +1,607 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995-99, 2000- 02, 06 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
+ */
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/irqflags.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/isadep.h>
+#include <asm/sysmips.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+#include <asm/war.h>
+#include <asm/asm-offsets.h>
+
+/* Highest syscall used of any syscall flavour */
+#define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
+
+ .align 5
+NESTED(handle_sys, PT_SIZE, sp)
+ .set noat
+ SAVE_SOME
+ TRACE_IRQS_ON_RELOAD
+ STI
+ .set at
+
+ lw t1, PT_EPC(sp) # skip syscall on return
+
+ subu v0, v0, __NR_O32_Linux # check syscall number
+ sltiu t0, v0, __NR_O32_Linux_syscalls + 1
+ addiu t1, 4 # skip to next instruction
+ sw t1, PT_EPC(sp)
+ beqz t0, illegal_syscall
+
+ sll t0, v0, 3
+ la t1, sys_call_table
+ addu t1, t0
+ lw t2, (t1) # syscall routine
+ lw t3, 4(t1) # >= 0 if we need stack arguments
+ beqz t2, illegal_syscall
+
+ sw a3, PT_R26(sp) # save a3 for syscall restarting
+ bgez t3, stackargs
+
+stack_done:
+ lw t0, TI_FLAGS($28) # syscall tracing enabled?
+ li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ and t0, t1
+ bnez t0, syscall_trace_entry # -> yes
+
+ jalr t2 # Do The Real Thing (TM)
+
+ li t0, -EMAXERRNO - 1 # error?
+ sltu t0, t0, v0
+ sw t0, PT_R7(sp) # set error flag
+ beqz t0, 1f
+
+ lw t1, PT_R2(sp) # syscall number
+ negu v0 # error
+ sw t1, PT_R0(sp) # save it for syscall restarting
+1: sw v0, PT_R2(sp) # result
+
+o32_syscall_exit:
+ local_irq_disable # make sure need_resched and
+ # signals dont change between
+ # sampling and return
+ lw a2, TI_FLAGS($28) # current->work
+ li t0, _TIF_ALLWORK_MASK
+ and t0, a2
+ bnez t0, o32_syscall_exit_work
+
+ j restore_partial
+
+o32_syscall_exit_work:
+ j syscall_exit_work_partial
+
+/* ------------------------------------------------------------------------ */
+
+syscall_trace_entry:
+ SAVE_STATIC
+ move s0, t2
+ move a0, sp
+ jal syscall_trace_enter
+
+ move t0, s0
+ RESTORE_STATIC
+ lw a0, PT_R4(sp) # Restore argument registers
+ lw a1, PT_R5(sp)
+ lw a2, PT_R6(sp)
+ lw a3, PT_R7(sp)
+ jalr t0
+
+ li t0, -EMAXERRNO - 1 # error?
+ sltu t0, t0, v0
+ sw t0, PT_R7(sp) # set error flag
+ beqz t0, 1f
+
+ lw t1, PT_R2(sp) # syscall number
+ negu v0 # error
+ sw t1, PT_R0(sp) # save it for syscall restarting
+1: sw v0, PT_R2(sp) # result
+
+ j syscall_exit
+
+/* ------------------------------------------------------------------------ */
+
+ /*
+ * More than four arguments. Try to deal with it by copying the
+ * stack arguments from the user stack to the kernel stack.
+ * This Sucks (TM).
+ */
+stackargs:
+ lw t0, PT_R29(sp) # get old user stack pointer
+
+ /*
+ * We intentionally keep the kernel stack a little below the top of
+ * userspace so we don't have to do a slower byte accurate check here.
+ */
+ lw t5, TI_ADDR_LIMIT($28)
+ addu t4, t0, 32
+ and t5, t4
+ bltz t5, bad_stack # -> sp is bad
+
+ /* Ok, copy the args from the luser stack to the kernel stack.
+ * t3 is the precomputed number of instruction bytes needed to
+ * load or store arguments 6-8.
+ */
+
+ la t1, 5f # load up to 3 arguments
+ subu t1, t3
+1: lw t5, 16(t0) # argument #5 from usp
+ .set push
+ .set noreorder
+ .set nomacro
+ jr t1
+ addiu t1, 6f - 5f
+
+2: lw t8, 28(t0) # argument #8 from usp
+3: lw t7, 24(t0) # argument #7 from usp
+4: lw t6, 20(t0) # argument #6 from usp
+5: jr t1
+ sw t5, 16(sp) # argument #5 to ksp
+
+ sw t8, 28(sp) # argument #8 to ksp
+ sw t7, 24(sp) # argument #7 to ksp
+ sw t6, 20(sp) # argument #6 to ksp
+6: j stack_done # go back
+ nop
+ .set pop
+
+ .section __ex_table,"a"
+ PTR 1b,bad_stack
+ PTR 2b,bad_stack
+ PTR 3b,bad_stack
+ PTR 4b,bad_stack
+ .previous
+
+ /*
+ * The stackpointer for a call with more than 4 arguments is bad.
+ * We probably should handle this case a bit more drastic.
+ */
+bad_stack:
+ li v0, EFAULT
+ sw v0, PT_R2(sp)
+ li t0, 1 # set error flag
+ sw t0, PT_R7(sp)
+ j o32_syscall_exit
+
+ /*
+ * The system call does not exist in this kernel
+ */
+illegal_syscall:
+ li v0, ENOSYS # error
+ sw v0, PT_R2(sp)
+ li t0, 1 # set error flag
+ sw t0, PT_R7(sp)
+ j o32_syscall_exit
+ END(handle_sys)
+
+ LEAF(sys_syscall)
+ subu t0, a0, __NR_O32_Linux # check syscall number
+ sltiu v0, t0, __NR_O32_Linux_syscalls + 1
+ beqz t0, einval # do not recurse
+ sll t1, t0, 3
+ beqz v0, einval
+ lw t2, sys_call_table(t1) # syscall routine
+
+ /* Some syscalls like execve get their arguments from struct pt_regs
+ and claim zero arguments in the syscall table. Thus we have to
+ assume the worst case and shuffle around all potential arguments.
+ If you want performance, don't use indirect syscalls. */
+
+ move a0, a1 # shift argument registers
+ move a1, a2
+ move a2, a3
+ lw a3, 16(sp)
+ lw t4, 20(sp)
+ lw t5, 24(sp)
+ lw t6, 28(sp)
+ sw t4, 16(sp)
+ sw t5, 20(sp)
+ sw t6, 24(sp)
+ sw a0, PT_R4(sp) # .. and push back a0 - a3, some
+ sw a1, PT_R5(sp) # syscalls expect them there
+ sw a2, PT_R6(sp)
+ sw a3, PT_R7(sp)
+ sw a3, PT_R26(sp) # update a3 for syscall restarting
+ jr t2
+ /* Unreached */
+
+einval: li v0, -ENOSYS
+ jr ra
+ END(sys_syscall)
+
+ .macro fifty ptr, nargs, from=1, to=50
+ sys \ptr \nargs
+ .if \to-\from
+ fifty \ptr,\nargs,"(\from+1)",\to
+ .endif
+ .endm
+
+ .macro mille ptr, nargs, from=1, to=20
+ fifty \ptr,\nargs
+ .if \to-\from
+ mille \ptr,\nargs,"(\from+1)",\to
+ .endif
+ .endm
+
+ .macro syscalltable
+ sys sys_syscall 8 /* 4000 */
+ sys sys_exit 1
+ sys sys_fork 0
+ sys sys_read 3
+ sys sys_write 3
+ sys sys_open 3 /* 4005 */
+ sys sys_close 1
+ sys sys_waitpid 3
+ sys sys_creat 2
+ sys sys_link 2
+ sys sys_unlink 1 /* 4010 */
+ sys sys_execve 0
+ sys sys_chdir 1
+ sys sys_time 1
+ sys sys_mknod 3
+ sys sys_chmod 2 /* 4015 */
+ sys sys_lchown 3
+ sys sys_ni_syscall 0
+ sys sys_ni_syscall 0 /* was sys_stat */
+ sys sys_lseek 3
+ sys sys_getpid 0 /* 4020 */
+ sys sys_mount 5
+ sys sys_oldumount 1
+ sys sys_setuid 1
+ sys sys_getuid 0
+ sys sys_stime 1 /* 4025 */
+ sys sys_ptrace 4
+ sys sys_alarm 1
+ sys sys_ni_syscall 0 /* was sys_fstat */
+ sys sys_pause 0
+ sys sys_utime 2 /* 4030 */
+ sys sys_ni_syscall 0
+ sys sys_ni_syscall 0
+ sys sys_access 2
+ sys sys_nice 1
+ sys sys_ni_syscall 0 /* 4035 */
+ sys sys_sync 0
+ sys sys_kill 2
+ sys sys_rename 2
+ sys sys_mkdir 2
+ sys sys_rmdir 1 /* 4040 */
+ sys sys_dup 1
+ sys sysm_pipe 0
+ sys sys_times 1
+ sys sys_ni_syscall 0
+ sys sys_brk 1 /* 4045 */
+ sys sys_setgid 1
+ sys sys_getgid 0
+ sys sys_ni_syscall 0 /* was signal(2) */
+ sys sys_geteuid 0
+ sys sys_getegid 0 /* 4050 */
+ sys sys_acct 1
+ sys sys_umount 2
+ sys sys_ni_syscall 0
+ sys sys_ioctl 3
+ sys sys_fcntl 3 /* 4055 */
+ sys sys_ni_syscall 2
+ sys sys_setpgid 2
+ sys sys_ni_syscall 0
+ sys sys_olduname 1
+ sys sys_umask 1 /* 4060 */
+ sys sys_chroot 1
+ sys sys_ustat 2
+ sys sys_dup2 2
+ sys sys_getppid 0
+ sys sys_getpgrp 0 /* 4065 */
+ sys sys_setsid 0
+ sys sys_sigaction 3
+ sys sys_sgetmask 0
+ sys sys_ssetmask 1
+ sys sys_setreuid 2 /* 4070 */
+ sys sys_setregid 2
+ sys sys_sigsuspend 0
+ sys sys_sigpending 1
+ sys sys_sethostname 2
+ sys sys_setrlimit 2 /* 4075 */
+ sys sys_getrlimit 2
+ sys sys_getrusage 2
+ sys sys_gettimeofday 2
+ sys sys_settimeofday 2
+ sys sys_getgroups 2 /* 4080 */
+ sys sys_setgroups 2
+ sys sys_ni_syscall 0 /* old_select */
+ sys sys_symlink 2
+ sys sys_ni_syscall 0 /* was sys_lstat */
+ sys sys_readlink 3 /* 4085 */
+ sys sys_uselib 1
+ sys sys_swapon 2
+ sys sys_reboot 3
+ sys sys_old_readdir 3
+ sys sys_mips_mmap 6 /* 4090 */
+ sys sys_munmap 2
+ sys sys_truncate 2
+ sys sys_ftruncate 2
+ sys sys_fchmod 2
+ sys sys_fchown 3 /* 4095 */
+ sys sys_getpriority 2
+ sys sys_setpriority 3
+ sys sys_ni_syscall 0
+ sys sys_statfs 2
+ sys sys_fstatfs 2 /* 4100 */
+ sys sys_ni_syscall 0 /* was ioperm(2) */
+ sys sys_socketcall 2
+ sys sys_syslog 3
+ sys sys_setitimer 3
+ sys sys_getitimer 2 /* 4105 */
+ sys sys_newstat 2
+ sys sys_newlstat 2
+ sys sys_newfstat 2
+ sys sys_uname 1
+ sys sys_ni_syscall 0 /* 4110 was iopl(2) */
+ sys sys_vhangup 0
+ sys sys_ni_syscall 0 /* was sys_idle() */
+ sys sys_ni_syscall 0 /* was sys_vm86 */
+ sys sys_wait4 4
+ sys sys_swapoff 1 /* 4115 */
+ sys sys_sysinfo 1
+ sys sys_ipc 6
+ sys sys_fsync 1
+ sys sys_sigreturn 0
+ sys sys_clone 0 /* 4120 */
+ sys sys_setdomainname 2
+ sys sys_newuname 1
+ sys sys_ni_syscall 0 /* sys_modify_ldt */
+ sys sys_adjtimex 1
+ sys sys_mprotect 3 /* 4125 */
+ sys sys_sigprocmask 3
+ sys sys_ni_syscall 0 /* was create_module */
+ sys sys_init_module 5
+ sys sys_delete_module 1
+ sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
+ sys sys_quotactl 4
+ sys sys_getpgid 1
+ sys sys_fchdir 1
+ sys sys_bdflush 2
+ sys sys_sysfs 3 /* 4135 */
+ sys sys_personality 1
+ sys sys_ni_syscall 0 /* for afs_syscall */
+ sys sys_setfsuid 1
+ sys sys_setfsgid 1
+ sys sys_llseek 5 /* 4140 */
+ sys sys_getdents 3
+ sys sys_select 5
+ sys sys_flock 2
+ sys sys_msync 3
+ sys sys_readv 3 /* 4145 */
+ sys sys_writev 3
+ sys sys_cacheflush 3
+ sys sys_cachectl 3
+ sys sys_sysmips 4
+ sys sys_ni_syscall 0 /* 4150 */
+ sys sys_getsid 1
+ sys sys_fdatasync 1
+ sys sys_sysctl 1
+ sys sys_mlock 2
+ sys sys_munlock 2 /* 4155 */
+ sys sys_mlockall 1
+ sys sys_munlockall 0
+ sys sys_sched_setparam 2
+ sys sys_sched_getparam 2
+ sys sys_sched_setscheduler 3 /* 4160 */
+ sys sys_sched_getscheduler 1
+ sys sys_sched_yield 0
+ sys sys_sched_get_priority_max 1
+ sys sys_sched_get_priority_min 1
+ sys sys_sched_rr_get_interval 2 /* 4165 */
+ sys sys_nanosleep, 2
+ sys sys_mremap, 5
+ sys sys_accept 3
+ sys sys_bind 3
+ sys sys_connect 3 /* 4170 */
+ sys sys_getpeername 3
+ sys sys_getsockname 3
+ sys sys_getsockopt 5
+ sys sys_listen 2
+ sys sys_recv 4 /* 4175 */
+ sys sys_recvfrom 6
+ sys sys_recvmsg 3
+ sys sys_send 4
+ sys sys_sendmsg 3
+ sys sys_sendto 6 /* 4180 */
+ sys sys_setsockopt 5
+ sys sys_shutdown 2
+ sys sys_socket 3
+ sys sys_socketpair 4
+ sys sys_setresuid 3 /* 4185 */
+ sys sys_getresuid 3
+ sys sys_ni_syscall 0 /* was sys_query_module */
+ sys sys_poll 3
+ sys sys_nfsservctl 3
+ sys sys_setresgid 3 /* 4190 */
+ sys sys_getresgid 3
+ sys sys_prctl 5
+ sys sys_rt_sigreturn 0
+ sys sys_rt_sigaction 4
+ sys sys_rt_sigprocmask 4 /* 4195 */
+ sys sys_rt_sigpending 2
+ sys sys_rt_sigtimedwait 4
+ sys sys_rt_sigqueueinfo 3
+ sys sys_rt_sigsuspend 0
+ sys sys_pread64 6 /* 4200 */
+ sys sys_pwrite64 6
+ sys sys_chown 3
+ sys sys_getcwd 2
+ sys sys_capget 2
+ sys sys_capset 2 /* 4205 */
+ sys sys_sigaltstack 0
+ sys sys_sendfile 4
+ sys sys_ni_syscall 0
+ sys sys_ni_syscall 0
+ sys sys_mips_mmap2 6 /* 4210 */
+ sys sys_truncate64 4
+ sys sys_ftruncate64 4
+ sys sys_stat64 2
+ sys sys_lstat64 2
+ sys sys_fstat64 2 /* 4215 */
+ sys sys_pivot_root 2
+ sys sys_mincore 3
+ sys sys_madvise 3
+ sys sys_getdents64 3
+ sys sys_fcntl64 3 /* 4220 */
+ sys sys_ni_syscall 0
+ sys sys_gettid 0
+ sys sys_readahead 5
+ sys sys_setxattr 5
+ sys sys_lsetxattr 5 /* 4225 */
+ sys sys_fsetxattr 5
+ sys sys_getxattr 4
+ sys sys_lgetxattr 4
+ sys sys_fgetxattr 4
+ sys sys_listxattr 3 /* 4230 */
+ sys sys_llistxattr 3
+ sys sys_flistxattr 3
+ sys sys_removexattr 2
+ sys sys_lremovexattr 2
+ sys sys_fremovexattr 2 /* 4235 */
+ sys sys_tkill 2
+ sys sys_sendfile64 5
+ sys sys_futex 6
+#ifdef CONFIG_MIPS_MT_FPAFF
+ /*
+ * For FPU affinity scheduling on MIPS MT processors, we need to
+ * intercept sys_sched_xxxaffinity() calls until we get a proper hook
+ * in kernel/sched.c. Considered only temporary we only support these
+ * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
+ */
+ sys mipsmt_sys_sched_setaffinity 3
+ sys mipsmt_sys_sched_getaffinity 3
+#else
+ sys sys_sched_setaffinity 3
+ sys sys_sched_getaffinity 3 /* 4240 */
+#endif /* CONFIG_MIPS_MT_FPAFF */
+ sys sys_io_setup 2
+ sys sys_io_destroy 1
+ sys sys_io_getevents 5
+ sys sys_io_submit 3
+ sys sys_io_cancel 3 /* 4245 */
+ sys sys_exit_group 1
+ sys sys_lookup_dcookie 4
+ sys sys_epoll_create 1
+ sys sys_epoll_ctl 4
+ sys sys_epoll_wait 3 /* 4250 */
+ sys sys_remap_file_pages 5
+ sys sys_set_tid_address 1
+ sys sys_restart_syscall 0
+ sys sys_fadvise64_64 7
+ sys sys_statfs64 3 /* 4255 */
+ sys sys_fstatfs64 2
+ sys sys_timer_create 3
+ sys sys_timer_settime 4
+ sys sys_timer_gettime 2
+ sys sys_timer_getoverrun 1 /* 4260 */
+ sys sys_timer_delete 1
+ sys sys_clock_settime 2
+ sys sys_clock_gettime 2
+ sys sys_clock_getres 2
+ sys sys_clock_nanosleep 4 /* 4265 */
+ sys sys_tgkill 3
+ sys sys_utimes 2
+ sys sys_mbind 4
+ sys sys_ni_syscall 0 /* sys_get_mempolicy */
+ sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
+ sys sys_mq_open 4
+ sys sys_mq_unlink 1
+ sys sys_mq_timedsend 5
+ sys sys_mq_timedreceive 5
+ sys sys_mq_notify 2 /* 4275 */
+ sys sys_mq_getsetattr 3
+ sys sys_ni_syscall 0 /* sys_vserver */
+ sys sys_waitid 5
+ sys sys_ni_syscall 0 /* available, was setaltroot */
+ sys sys_add_key 5 /* 4280 */
+ sys sys_request_key 4
+ sys sys_keyctl 5
+ sys sys_set_thread_area 1
+ sys sys_inotify_init 0
+ sys sys_inotify_add_watch 3 /* 4285 */
+ sys sys_inotify_rm_watch 2
+ sys sys_migrate_pages 4
+ sys sys_openat 4
+ sys sys_mkdirat 3
+ sys sys_mknodat 4 /* 4290 */
+ sys sys_fchownat 5
+ sys sys_futimesat 3
+ sys sys_fstatat64 4
+ sys sys_unlinkat 3
+ sys sys_renameat 4 /* 4295 */
+ sys sys_linkat 5
+ sys sys_symlinkat 3
+ sys sys_readlinkat 4
+ sys sys_fchmodat 3
+ sys sys_faccessat 3 /* 4300 */
+ sys sys_pselect6 6
+ sys sys_ppoll 5
+ sys sys_unshare 1
+ sys sys_splice 6
+ sys sys_sync_file_range 7 /* 4305 */
+ sys sys_tee 4
+ sys sys_vmsplice 4
+ sys sys_move_pages 6
+ sys sys_set_robust_list 2
+ sys sys_get_robust_list 3 /* 4310 */
+ sys sys_kexec_load 4
+ sys sys_getcpu 3
+ sys sys_epoll_pwait 6
+ sys sys_ioprio_set 3
+ sys sys_ioprio_get 2 /* 4315 */
+ sys sys_utimensat 4
+ sys sys_signalfd 3
+ sys sys_ni_syscall 0 /* was timerfd */
+ sys sys_eventfd 1
+ sys sys_fallocate 6 /* 4320 */
+ sys sys_timerfd_create 2
+ sys sys_timerfd_gettime 2
+ sys sys_timerfd_settime 4
+ sys sys_signalfd4 4
+ sys sys_eventfd2 2 /* 4325 */
+ sys sys_epoll_create1 1
+ sys sys_dup3 3
+ sys sys_pipe2 2
+ sys sys_inotify_init1 1
+ sys sys_preadv 6 /* 4330 */
+ sys sys_pwritev 6
+ sys sys_rt_tgsigqueueinfo 4
+ sys sys_perf_event_open 5
+ sys sys_accept4 4
+ sys sys_recvmmsg 5 /* 4335 */
+ sys sys_fanotify_init 2
+ sys sys_fanotify_mark 6
+ sys sys_prlimit64 4
+ sys sys_name_to_handle_at 5
+ sys sys_open_by_handle_at 3 /* 4340 */
+ sys sys_clock_adjtime 2
+ sys sys_syncfs 1
+ sys sys_setns 2
+ .endm
+
+ /* We pre-compute the number of _instruction_ bytes needed to
+ load or store the arguments 6-8. Negative values are ignored. */
+
+ .macro sys function, nargs
+ PTR \function
+ LONG (\nargs << 2) - (5 << 2)
+ .endm
+
+ .align 3
+ .type sys_call_table,@object
+EXPORT(sys_call_table)
+ syscalltable
+ .size sys_call_table, . - sys_call_table
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
new file mode 100644
index 00000000..fb0575f4
--- /dev/null
+++ b/arch/mips/kernel/scall64-64.S
@@ -0,0 +1,432 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/irqflags.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/asm-offsets.h>
+#include <asm/sysmips.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+#include <asm/war.h>
+
+#ifndef CONFIG_BINFMT_ELF32
+/* Neither O32 nor N32, so define handle_sys here */
+#define handle_sys64 handle_sys
+#endif
+
+ .align 5
+NESTED(handle_sys64, PT_SIZE, sp)
+#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
+ /*
+ * When 32-bit compatibility is configured scall_o32.S
+ * already did this.
+ */
+ .set noat
+ SAVE_SOME
+ TRACE_IRQS_ON_RELOAD
+ STI
+ .set at
+#endif
+
+ dsubu t0, v0, __NR_64_Linux # check syscall number
+ sltiu t0, t0, __NR_64_Linux_syscalls + 1
+#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
+ ld t1, PT_EPC(sp) # skip syscall on return
+ daddiu t1, 4 # skip to next instruction
+ sd t1, PT_EPC(sp)
+#endif
+ beqz t0, illegal_syscall
+
+ dsll t0, v0, 3 # offset into table
+ ld t2, (sys_call_table - (__NR_64_Linux * 8))(t0)
+ # syscall routine
+
+ sd a3, PT_R26(sp) # save a3 for syscall restarting
+
+ li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
+ and t0, t1, t0
+ bnez t0, syscall_trace_entry
+
+ jalr t2 # Do The Real Thing (TM)
+
+ li t0, -EMAXERRNO - 1 # error?
+ sltu t0, t0, v0
+ sd t0, PT_R7(sp) # set error flag
+ beqz t0, 1f
+
+ ld t1, PT_R2(sp) # syscall number
+ dnegu v0 # error
+ sd t1, PT_R0(sp) # save it for syscall restarting
+1: sd v0, PT_R2(sp) # result
+
+n64_syscall_exit:
+ local_irq_disable # make sure need_resched and
+ # signals dont change between
+ # sampling and return
+ LONG_L a2, TI_FLAGS($28) # current->work
+ li t0, _TIF_ALLWORK_MASK
+ and t0, a2, t0
+ bnez t0, n64_syscall_exit_work
+
+ j restore_partial
+
+n64_syscall_exit_work:
+ j syscall_exit_work_partial
+
+/* ------------------------------------------------------------------------ */
+
+syscall_trace_entry:
+ SAVE_STATIC
+ move s0, t2
+ move a0, sp
+ jal syscall_trace_enter
+
+ move t0, s0
+ RESTORE_STATIC
+ ld a0, PT_R4(sp) # Restore argument registers
+ ld a1, PT_R5(sp)
+ ld a2, PT_R6(sp)
+ ld a3, PT_R7(sp)
+ ld a4, PT_R8(sp)
+ ld a5, PT_R9(sp)
+ jalr t0
+
+ li t0, -EMAXERRNO - 1 # error?
+ sltu t0, t0, v0
+ sd t0, PT_R7(sp) # set error flag
+ beqz t0, 1f
+
+ ld t1, PT_R2(sp) # syscall number
+ dnegu v0 # error
+ sd t1, PT_R0(sp) # save it for syscall restarting
+1: sd v0, PT_R2(sp) # result
+
+ j syscall_exit
+
+illegal_syscall:
+ /* This also isn't a 64-bit syscall, throw an error. */
+ li v0, ENOSYS # error
+ sd v0, PT_R2(sp)
+ li t0, 1 # set error flag
+ sd t0, PT_R7(sp)
+ j n64_syscall_exit
+ END(handle_sys64)
+
+ .align 3
+sys_call_table:
+ PTR sys_read /* 5000 */
+ PTR sys_write
+ PTR sys_open
+ PTR sys_close
+ PTR sys_newstat
+ PTR sys_newfstat /* 5005 */
+ PTR sys_newlstat
+ PTR sys_poll
+ PTR sys_lseek
+ PTR sys_mips_mmap
+ PTR sys_mprotect /* 5010 */
+ PTR sys_munmap
+ PTR sys_brk
+ PTR sys_rt_sigaction
+ PTR sys_rt_sigprocmask
+ PTR sys_ioctl /* 5015 */
+ PTR sys_pread64
+ PTR sys_pwrite64
+ PTR sys_readv
+ PTR sys_writev
+ PTR sys_access /* 5020 */
+ PTR sysm_pipe
+ PTR sys_select
+ PTR sys_sched_yield
+ PTR sys_mremap
+ PTR sys_msync /* 5025 */
+ PTR sys_mincore
+ PTR sys_madvise
+ PTR sys_shmget
+ PTR sys_shmat
+ PTR sys_shmctl /* 5030 */
+ PTR sys_dup
+ PTR sys_dup2
+ PTR sys_pause
+ PTR sys_nanosleep
+ PTR sys_getitimer /* 5035 */
+ PTR sys_setitimer
+ PTR sys_alarm
+ PTR sys_getpid
+ PTR sys_sendfile64
+ PTR sys_socket /* 5040 */
+ PTR sys_connect
+ PTR sys_accept
+ PTR sys_sendto
+ PTR sys_recvfrom
+ PTR sys_sendmsg /* 5045 */
+ PTR sys_recvmsg
+ PTR sys_shutdown
+ PTR sys_bind
+ PTR sys_listen
+ PTR sys_getsockname /* 5050 */
+ PTR sys_getpeername
+ PTR sys_socketpair
+ PTR sys_setsockopt
+ PTR sys_getsockopt
+ PTR sys_clone /* 5055 */
+ PTR sys_fork
+ PTR sys_execve
+ PTR sys_exit
+ PTR sys_wait4
+ PTR sys_kill /* 5060 */
+ PTR sys_newuname
+ PTR sys_semget
+ PTR sys_semop
+ PTR sys_semctl
+ PTR sys_shmdt /* 5065 */
+ PTR sys_msgget
+ PTR sys_msgsnd
+ PTR sys_msgrcv
+ PTR sys_msgctl
+ PTR sys_fcntl /* 5070 */
+ PTR sys_flock
+ PTR sys_fsync
+ PTR sys_fdatasync
+ PTR sys_truncate
+ PTR sys_ftruncate /* 5075 */
+ PTR sys_getdents
+ PTR sys_getcwd
+ PTR sys_chdir
+ PTR sys_fchdir
+ PTR sys_rename /* 5080 */
+ PTR sys_mkdir
+ PTR sys_rmdir
+ PTR sys_creat
+ PTR sys_link
+ PTR sys_unlink /* 5085 */
+ PTR sys_symlink
+ PTR sys_readlink
+ PTR sys_chmod
+ PTR sys_fchmod
+ PTR sys_chown /* 5090 */
+ PTR sys_fchown
+ PTR sys_lchown
+ PTR sys_umask
+ PTR sys_gettimeofday
+ PTR sys_getrlimit /* 5095 */
+ PTR sys_getrusage
+ PTR sys_sysinfo
+ PTR sys_times
+ PTR sys_ptrace
+ PTR sys_getuid /* 5100 */
+ PTR sys_syslog
+ PTR sys_getgid
+ PTR sys_setuid
+ PTR sys_setgid
+ PTR sys_geteuid /* 5105 */
+ PTR sys_getegid
+ PTR sys_setpgid
+ PTR sys_getppid
+ PTR sys_getpgrp
+ PTR sys_setsid /* 5110 */
+ PTR sys_setreuid
+ PTR sys_setregid
+ PTR sys_getgroups
+ PTR sys_setgroups
+ PTR sys_setresuid /* 5115 */
+ PTR sys_getresuid
+ PTR sys_setresgid
+ PTR sys_getresgid
+ PTR sys_getpgid
+ PTR sys_setfsuid /* 5120 */
+ PTR sys_setfsgid
+ PTR sys_getsid
+ PTR sys_capget
+ PTR sys_capset
+ PTR sys_rt_sigpending /* 5125 */
+ PTR sys_rt_sigtimedwait
+ PTR sys_rt_sigqueueinfo
+ PTR sys_rt_sigsuspend
+ PTR sys_sigaltstack
+ PTR sys_utime /* 5130 */
+ PTR sys_mknod
+ PTR sys_personality
+ PTR sys_ustat
+ PTR sys_statfs
+ PTR sys_fstatfs /* 5135 */
+ PTR sys_sysfs
+ PTR sys_getpriority
+ PTR sys_setpriority
+ PTR sys_sched_setparam
+ PTR sys_sched_getparam /* 5140 */
+ PTR sys_sched_setscheduler
+ PTR sys_sched_getscheduler
+ PTR sys_sched_get_priority_max
+ PTR sys_sched_get_priority_min
+ PTR sys_sched_rr_get_interval /* 5145 */
+ PTR sys_mlock
+ PTR sys_munlock
+ PTR sys_mlockall
+ PTR sys_munlockall
+ PTR sys_vhangup /* 5150 */
+ PTR sys_pivot_root
+ PTR sys_sysctl
+ PTR sys_prctl
+ PTR sys_adjtimex
+ PTR sys_setrlimit /* 5155 */
+ PTR sys_chroot
+ PTR sys_sync
+ PTR sys_acct
+ PTR sys_settimeofday
+ PTR sys_mount /* 5160 */
+ PTR sys_umount
+ PTR sys_swapon
+ PTR sys_swapoff
+ PTR sys_reboot
+ PTR sys_sethostname /* 5165 */
+ PTR sys_setdomainname
+ PTR sys_ni_syscall /* was create_module */
+ PTR sys_init_module
+ PTR sys_delete_module
+ PTR sys_ni_syscall /* 5170, was get_kernel_syms */
+ PTR sys_ni_syscall /* was query_module */
+ PTR sys_quotactl
+ PTR sys_nfsservctl
+ PTR sys_ni_syscall /* res. for getpmsg */
+ PTR sys_ni_syscall /* 5175 for putpmsg */
+ PTR sys_ni_syscall /* res. for afs_syscall */
+ PTR sys_ni_syscall /* res. for security */
+ PTR sys_gettid
+ PTR sys_readahead
+ PTR sys_setxattr /* 5180 */
+ PTR sys_lsetxattr
+ PTR sys_fsetxattr
+ PTR sys_getxattr
+ PTR sys_lgetxattr
+ PTR sys_fgetxattr /* 5185 */
+ PTR sys_listxattr
+ PTR sys_llistxattr
+ PTR sys_flistxattr
+ PTR sys_removexattr
+ PTR sys_lremovexattr /* 5190 */
+ PTR sys_fremovexattr
+ PTR sys_tkill
+ PTR sys_ni_syscall
+ PTR sys_futex
+ PTR sys_sched_setaffinity /* 5195 */
+ PTR sys_sched_getaffinity
+ PTR sys_cacheflush
+ PTR sys_cachectl
+ PTR sys_sysmips
+ PTR sys_io_setup /* 5200 */
+ PTR sys_io_destroy
+ PTR sys_io_getevents
+ PTR sys_io_submit
+ PTR sys_io_cancel
+ PTR sys_exit_group /* 5205 */
+ PTR sys_lookup_dcookie
+ PTR sys_epoll_create
+ PTR sys_epoll_ctl
+ PTR sys_epoll_wait
+ PTR sys_remap_file_pages /* 5210 */
+ PTR sys_rt_sigreturn
+ PTR sys_set_tid_address
+ PTR sys_restart_syscall
+ PTR sys_semtimedop
+ PTR sys_fadvise64_64 /* 5215 */
+ PTR sys_timer_create
+ PTR sys_timer_settime
+ PTR sys_timer_gettime
+ PTR sys_timer_getoverrun
+ PTR sys_timer_delete /* 5220 */
+ PTR sys_clock_settime
+ PTR sys_clock_gettime
+ PTR sys_clock_getres
+ PTR sys_clock_nanosleep
+ PTR sys_tgkill /* 5225 */
+ PTR sys_utimes
+ PTR sys_mbind
+ PTR sys_ni_syscall /* sys_get_mempolicy */
+ PTR sys_ni_syscall /* sys_set_mempolicy */
+ PTR sys_mq_open /* 5230 */
+ PTR sys_mq_unlink
+ PTR sys_mq_timedsend
+ PTR sys_mq_timedreceive
+ PTR sys_mq_notify
+ PTR sys_mq_getsetattr /* 5235 */
+ PTR sys_ni_syscall /* sys_vserver */
+ PTR sys_waitid
+ PTR sys_ni_syscall /* available, was setaltroot */
+ PTR sys_add_key
+ PTR sys_request_key /* 5240 */
+ PTR sys_keyctl
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch
+ PTR sys_inotify_rm_watch /* 5245 */
+ PTR sys_migrate_pages
+ PTR sys_openat
+ PTR sys_mkdirat
+ PTR sys_mknodat
+ PTR sys_fchownat /* 5250 */
+ PTR sys_futimesat
+ PTR sys_newfstatat
+ PTR sys_unlinkat
+ PTR sys_renameat
+ PTR sys_linkat /* 5255 */
+ PTR sys_symlinkat
+ PTR sys_readlinkat
+ PTR sys_fchmodat
+ PTR sys_faccessat
+ PTR sys_pselect6 /* 5260 */
+ PTR sys_ppoll
+ PTR sys_unshare
+ PTR sys_splice
+ PTR sys_sync_file_range
+ PTR sys_tee /* 5265 */
+ PTR sys_vmsplice
+ PTR sys_move_pages
+ PTR sys_set_robust_list
+ PTR sys_get_robust_list
+ PTR sys_kexec_load /* 5270 */
+ PTR sys_getcpu
+ PTR sys_epoll_pwait
+ PTR sys_ioprio_set
+ PTR sys_ioprio_get
+ PTR sys_utimensat /* 5275 */
+ PTR sys_signalfd
+ PTR sys_ni_syscall /* was timerfd */
+ PTR sys_eventfd
+ PTR sys_fallocate
+ PTR sys_timerfd_create /* 5280 */
+ PTR sys_timerfd_gettime
+ PTR sys_timerfd_settime
+ PTR sys_signalfd4
+ PTR sys_eventfd2
+ PTR sys_epoll_create1 /* 5285 */
+ PTR sys_dup3
+ PTR sys_pipe2
+ PTR sys_inotify_init1
+ PTR sys_preadv
+ PTR sys_pwritev /* 5290 */
+ PTR sys_rt_tgsigqueueinfo
+ PTR sys_perf_event_open
+ PTR sys_accept4
+ PTR sys_recvmmsg
+ PTR sys_fanotify_init /* 5295 */
+ PTR sys_fanotify_mark
+ PTR sys_prlimit64
+ PTR sys_name_to_handle_at
+ PTR sys_open_by_handle_at
+ PTR sys_clock_adjtime /* 5300 */
+ PTR sys_syncfs
+ PTR sys_setns
+ .size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
new file mode 100644
index 00000000..4de0c553
--- /dev/null
+++ b/arch/mips/kernel/scall64-n32.S
@@ -0,0 +1,432 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/irqflags.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+
+/* This duplicates the definition from <linux/sched.h> */
+#define PT_TRACESYS 0x00000002 /* tracing system calls */
+
+/* This duplicates the definition from <asm/signal.h> */
+#define SIGILL 4 /* Illegal instruction (ANSI). */
+
+#ifndef CONFIG_MIPS32_O32
+/* No O32, so define handle_sys here */
+#define handle_sysn32 handle_sys
+#endif
+
+ .align 5
+NESTED(handle_sysn32, PT_SIZE, sp)
+#ifndef CONFIG_MIPS32_O32
+ .set noat
+ SAVE_SOME
+ TRACE_IRQS_ON_RELOAD
+ STI
+ .set at
+#endif
+
+ dsubu t0, v0, __NR_N32_Linux # check syscall number
+ sltiu t0, t0, __NR_N32_Linux_syscalls + 1
+
+#ifndef CONFIG_MIPS32_O32
+ ld t1, PT_EPC(sp) # skip syscall on return
+ daddiu t1, 4 # skip to next instruction
+ sd t1, PT_EPC(sp)
+#endif
+ beqz t0, not_n32_scall
+
+ dsll t0, v0, 3 # offset into table
+ ld t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
+
+ sd a3, PT_R26(sp) # save a3 for syscall restarting
+
+ li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
+ and t0, t1, t0
+ bnez t0, n32_syscall_trace_entry
+
+ jalr t2 # Do The Real Thing (TM)
+
+ li t0, -EMAXERRNO - 1 # error?
+ sltu t0, t0, v0
+ sd t0, PT_R7(sp) # set error flag
+ beqz t0, 1f
+
+ ld t1, PT_R2(sp) # syscall number
+ dnegu v0 # error
+ sd t1, PT_R0(sp) # save it for syscall restarting
+1: sd v0, PT_R2(sp) # result
+
+ local_irq_disable # make sure need_resched and
+ # signals dont change between
+ # sampling and return
+ LONG_L a2, TI_FLAGS($28) # current->work
+ li t0, _TIF_ALLWORK_MASK
+ and t0, a2, t0
+ bnez t0, n32_syscall_exit_work
+
+ j restore_partial
+
+n32_syscall_exit_work:
+ j syscall_exit_work_partial
+
+/* ------------------------------------------------------------------------ */
+
+n32_syscall_trace_entry:
+ SAVE_STATIC
+ move s0, t2
+ move a0, sp
+ jal syscall_trace_enter
+
+ move t0, s0
+ RESTORE_STATIC
+ ld a0, PT_R4(sp) # Restore argument registers
+ ld a1, PT_R5(sp)
+ ld a2, PT_R6(sp)
+ ld a3, PT_R7(sp)
+ ld a4, PT_R8(sp)
+ ld a5, PT_R9(sp)
+ jalr t0
+
+ li t0, -EMAXERRNO - 1 # error?
+ sltu t0, t0, v0
+ sd t0, PT_R7(sp) # set error flag
+ beqz t0, 1f
+
+ ld t1, PT_R2(sp) # syscall number
+ dnegu v0 # error
+ sd t1, PT_R0(sp) # save it for syscall restarting
+1: sd v0, PT_R2(sp) # result
+
+ j syscall_exit
+
+not_n32_scall:
+ /* This is not an n32 compatibility syscall, pass it on to
+ the n64 syscall handlers. */
+ j handle_sys64
+
+ END(handle_sysn32)
+
+EXPORT(sysn32_call_table)
+ PTR sys_read /* 6000 */
+ PTR sys_write
+ PTR sys_open
+ PTR sys_close
+ PTR sys_newstat
+ PTR sys_newfstat /* 6005 */
+ PTR sys_newlstat
+ PTR sys_poll
+ PTR sys_lseek
+ PTR sys_mips_mmap
+ PTR sys_mprotect /* 6010 */
+ PTR sys_munmap
+ PTR sys_brk
+ PTR sys_32_rt_sigaction
+ PTR sys_32_rt_sigprocmask
+ PTR compat_sys_ioctl /* 6015 */
+ PTR sys_pread64
+ PTR sys_pwrite64
+ PTR compat_sys_readv
+ PTR compat_sys_writev
+ PTR sys_access /* 6020 */
+ PTR sysm_pipe
+ PTR compat_sys_select
+ PTR sys_sched_yield
+ PTR sys_mremap
+ PTR sys_msync /* 6025 */
+ PTR sys_mincore
+ PTR sys_madvise
+ PTR sys_shmget
+ PTR sys_shmat
+ PTR compat_sys_shmctl /* 6030 */
+ PTR sys_dup
+ PTR sys_dup2
+ PTR sys_pause
+ PTR compat_sys_nanosleep
+ PTR compat_sys_getitimer /* 6035 */
+ PTR compat_sys_setitimer
+ PTR sys_alarm
+ PTR sys_getpid
+ PTR sys_32_sendfile
+ PTR sys_socket /* 6040 */
+ PTR sys_connect
+ PTR sys_accept
+ PTR sys_sendto
+ PTR compat_sys_recvfrom
+ PTR compat_sys_sendmsg /* 6045 */
+ PTR compat_sys_recvmsg
+ PTR sys_shutdown
+ PTR sys_bind
+ PTR sys_listen
+ PTR sys_getsockname /* 6050 */
+ PTR sys_getpeername
+ PTR sys_socketpair
+ PTR compat_sys_setsockopt
+ PTR sys_getsockopt
+ PTR sys_clone /* 6055 */
+ PTR sys_fork
+ PTR sys32_execve
+ PTR sys_exit
+ PTR compat_sys_wait4
+ PTR sys_kill /* 6060 */
+ PTR sys_newuname
+ PTR sys_semget
+ PTR sys_semop
+ PTR sys_n32_semctl
+ PTR sys_shmdt /* 6065 */
+ PTR sys_msgget
+ PTR sys_n32_msgsnd
+ PTR sys_n32_msgrcv
+ PTR compat_sys_msgctl
+ PTR compat_sys_fcntl /* 6070 */
+ PTR sys_flock
+ PTR sys_fsync
+ PTR sys_fdatasync
+ PTR sys_truncate
+ PTR sys_ftruncate /* 6075 */
+ PTR compat_sys_getdents
+ PTR sys_getcwd
+ PTR sys_chdir
+ PTR sys_fchdir
+ PTR sys_rename /* 6080 */
+ PTR sys_mkdir
+ PTR sys_rmdir
+ PTR sys_creat
+ PTR sys_link
+ PTR sys_unlink /* 6085 */
+ PTR sys_symlink
+ PTR sys_readlink
+ PTR sys_chmod
+ PTR sys_fchmod
+ PTR sys_chown /* 6090 */
+ PTR sys_fchown
+ PTR sys_lchown
+ PTR sys_umask
+ PTR compat_sys_gettimeofday
+ PTR compat_sys_getrlimit /* 6095 */
+ PTR compat_sys_getrusage
+ PTR compat_sys_sysinfo
+ PTR compat_sys_times
+ PTR compat_sys_ptrace
+ PTR sys_getuid /* 6100 */
+ PTR sys_syslog
+ PTR sys_getgid
+ PTR sys_setuid
+ PTR sys_setgid
+ PTR sys_geteuid /* 6105 */
+ PTR sys_getegid
+ PTR sys_setpgid
+ PTR sys_getppid
+ PTR sys_getpgrp
+ PTR sys_setsid /* 6110 */
+ PTR sys_setreuid
+ PTR sys_setregid
+ PTR sys_getgroups
+ PTR sys_setgroups
+ PTR sys_setresuid /* 6115 */
+ PTR sys_getresuid
+ PTR sys_setresgid
+ PTR sys_getresgid
+ PTR sys_getpgid
+ PTR sys_setfsuid /* 6120 */
+ PTR sys_setfsgid
+ PTR sys_getsid
+ PTR sys_capget
+ PTR sys_capset
+ PTR sys_32_rt_sigpending /* 6125 */
+ PTR compat_sys_rt_sigtimedwait
+ PTR sys_32_rt_sigqueueinfo
+ PTR sysn32_rt_sigsuspend
+ PTR sys32_sigaltstack
+ PTR compat_sys_utime /* 6130 */
+ PTR sys_mknod
+ PTR sys_32_personality
+ PTR compat_sys_ustat
+ PTR compat_sys_statfs
+ PTR compat_sys_fstatfs /* 6135 */
+ PTR sys_sysfs
+ PTR sys_getpriority
+ PTR sys_setpriority
+ PTR sys_sched_setparam
+ PTR sys_sched_getparam /* 6140 */
+ PTR sys_sched_setscheduler
+ PTR sys_sched_getscheduler
+ PTR sys_sched_get_priority_max
+ PTR sys_sched_get_priority_min
+ PTR sys_32_sched_rr_get_interval /* 6145 */
+ PTR sys_mlock
+ PTR sys_munlock
+ PTR sys_mlockall
+ PTR sys_munlockall
+ PTR sys_vhangup /* 6150 */
+ PTR sys_pivot_root
+ PTR compat_sys_sysctl
+ PTR sys_prctl
+ PTR compat_sys_adjtimex
+ PTR compat_sys_setrlimit /* 6155 */
+ PTR sys_chroot
+ PTR sys_sync
+ PTR sys_acct
+ PTR compat_sys_settimeofday
+ PTR compat_sys_mount /* 6160 */
+ PTR sys_umount
+ PTR sys_swapon
+ PTR sys_swapoff
+ PTR sys_reboot
+ PTR sys_sethostname /* 6165 */
+ PTR sys_setdomainname
+ PTR sys_ni_syscall /* was create_module */
+ PTR sys_init_module
+ PTR sys_delete_module
+ PTR sys_ni_syscall /* 6170, was get_kernel_syms */
+ PTR sys_ni_syscall /* was query_module */
+ PTR sys_quotactl
+ PTR compat_sys_nfsservctl
+ PTR sys_ni_syscall /* res. for getpmsg */
+ PTR sys_ni_syscall /* 6175 for putpmsg */
+ PTR sys_ni_syscall /* res. for afs_syscall */
+ PTR sys_ni_syscall /* res. for security */
+ PTR sys_gettid
+ PTR sys_readahead
+ PTR sys_setxattr /* 6180 */
+ PTR sys_lsetxattr
+ PTR sys_fsetxattr
+ PTR sys_getxattr
+ PTR sys_lgetxattr
+ PTR sys_fgetxattr /* 6185 */
+ PTR sys_listxattr
+ PTR sys_llistxattr
+ PTR sys_flistxattr
+ PTR sys_removexattr
+ PTR sys_lremovexattr /* 6190 */
+ PTR sys_fremovexattr
+ PTR sys_tkill
+ PTR sys_ni_syscall
+ PTR compat_sys_futex
+ PTR compat_sys_sched_setaffinity /* 6195 */
+ PTR compat_sys_sched_getaffinity
+ PTR sys_cacheflush
+ PTR sys_cachectl
+ PTR sys_sysmips
+ PTR compat_sys_io_setup /* 6200 */
+ PTR sys_io_destroy
+ PTR compat_sys_io_getevents
+ PTR compat_sys_io_submit
+ PTR sys_io_cancel
+ PTR sys_exit_group /* 6205 */
+ PTR sys_lookup_dcookie
+ PTR sys_epoll_create
+ PTR sys_epoll_ctl
+ PTR sys_epoll_wait
+ PTR sys_remap_file_pages /* 6210 */
+ PTR sysn32_rt_sigreturn
+ PTR compat_sys_fcntl64
+ PTR sys_set_tid_address
+ PTR sys_restart_syscall
+ PTR compat_sys_semtimedop /* 6215 */
+ PTR sys_fadvise64_64
+ PTR compat_sys_statfs64
+ PTR compat_sys_fstatfs64
+ PTR sys_sendfile64
+ PTR compat_sys_timer_create /* 6220 */
+ PTR compat_sys_timer_settime
+ PTR compat_sys_timer_gettime
+ PTR sys_timer_getoverrun
+ PTR sys_timer_delete
+ PTR compat_sys_clock_settime /* 6225 */
+ PTR compat_sys_clock_gettime
+ PTR compat_sys_clock_getres
+ PTR compat_sys_clock_nanosleep
+ PTR sys_tgkill
+ PTR compat_sys_utimes /* 6230 */
+ PTR sys_ni_syscall /* sys_mbind */
+ PTR sys_ni_syscall /* sys_get_mempolicy */
+ PTR sys_ni_syscall /* sys_set_mempolicy */
+ PTR compat_sys_mq_open
+ PTR sys_mq_unlink /* 6235 */
+ PTR compat_sys_mq_timedsend
+ PTR compat_sys_mq_timedreceive
+ PTR compat_sys_mq_notify
+ PTR compat_sys_mq_getsetattr
+ PTR sys_ni_syscall /* 6240, sys_vserver */
+ PTR compat_sys_waitid
+ PTR sys_ni_syscall /* available, was setaltroot */
+ PTR sys_add_key
+ PTR sys_request_key
+ PTR sys_keyctl /* 6245 */
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch
+ PTR sys_inotify_rm_watch
+ PTR sys_migrate_pages /* 6250 */
+ PTR sys_openat
+ PTR sys_mkdirat
+ PTR sys_mknodat
+ PTR sys_fchownat
+ PTR compat_sys_futimesat /* 6255 */
+ PTR sys_newfstatat
+ PTR sys_unlinkat
+ PTR sys_renameat
+ PTR sys_linkat
+ PTR sys_symlinkat /* 6260 */
+ PTR sys_readlinkat
+ PTR sys_fchmodat
+ PTR sys_faccessat
+ PTR compat_sys_pselect6
+ PTR compat_sys_ppoll /* 6265 */
+ PTR sys_unshare
+ PTR sys_splice
+ PTR sys_sync_file_range
+ PTR sys_tee
+ PTR compat_sys_vmsplice /* 6270 */
+ PTR sys_move_pages
+ PTR compat_sys_set_robust_list
+ PTR compat_sys_get_robust_list
+ PTR compat_sys_kexec_load
+ PTR sys_getcpu /* 6275 */
+ PTR compat_sys_epoll_pwait
+ PTR sys_ioprio_set
+ PTR sys_ioprio_get
+ PTR compat_sys_utimensat
+ PTR compat_sys_signalfd /* 6280 */
+ PTR sys_ni_syscall /* was timerfd */
+ PTR sys_eventfd
+ PTR sys_fallocate
+ PTR sys_timerfd_create
+ PTR compat_sys_timerfd_gettime /* 6285 */
+ PTR compat_sys_timerfd_settime
+ PTR sys_signalfd4
+ PTR sys_eventfd2
+ PTR sys_epoll_create1
+ PTR sys_dup3 /* 6290 */
+ PTR sys_pipe2
+ PTR sys_inotify_init1
+ PTR sys_preadv
+ PTR sys_pwritev
+ PTR compat_sys_rt_tgsigqueueinfo /* 6295 */
+ PTR sys_perf_event_open
+ PTR sys_accept4
+ PTR compat_sys_recvmmsg
+ PTR sys_getdents64
+ PTR sys_fanotify_init /* 6300 */
+ PTR sys_fanotify_mark
+ PTR sys_prlimit64
+ PTR sys_name_to_handle_at
+ PTR sys_open_by_handle_at
+ PTR compat_sys_clock_adjtime /* 6305 */
+ PTR sys_syncfs
+ PTR sys_setns
+ .size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
new file mode 100644
index 00000000..4a387de0
--- /dev/null
+++ b/arch/mips/kernel/scall64-o32.S
@@ -0,0 +1,550 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2004 Thiemo Seufer
+ *
+ * Hairy, the userspace application uses a different argument passing
+ * convention than the kernel, so we have to translate things from o32
+ * to ABI64 calling convention. 64-bit syscalls are also processed
+ * here for now.
+ */
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/irqflags.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+#include <asm/sysmips.h>
+
+ .align 5
+NESTED(handle_sys, PT_SIZE, sp)
+ .set noat
+ SAVE_SOME
+ TRACE_IRQS_ON_RELOAD
+ STI
+ .set at
+ ld t1, PT_EPC(sp) # skip syscall on return
+
+ dsubu t0, v0, __NR_O32_Linux # check syscall number
+ sltiu t0, t0, __NR_O32_Linux_syscalls + 1
+ daddiu t1, 4 # skip to next instruction
+ sd t1, PT_EPC(sp)
+ beqz t0, not_o32_scall
+#if 0
+ SAVE_ALL
+ move a1, v0
+ PRINT("Scall %ld\n")
+ RESTORE_ALL
+#endif
+
+ /* We don't want to stumble over broken sign extensions from
+ userland. O32 does never use the upper half. */
+ sll a0, a0, 0
+ sll a1, a1, 0
+ sll a2, a2, 0
+ sll a3, a3, 0
+
+ dsll t0, v0, 3 # offset into table
+ ld t2, (sys_call_table - (__NR_O32_Linux * 8))(t0)
+
+ sd a3, PT_R26(sp) # save a3 for syscall restarting
+
+ /*
+ * More than four arguments. Try to deal with it by copying the
+ * stack arguments from the user stack to the kernel stack.
+ * This Sucks (TM).
+ *
+ * We intentionally keep the kernel stack a little below the top of
+ * userspace so we don't have to do a slower byte accurate check here.
+ */
+ ld t0, PT_R29(sp) # get old user stack pointer
+ daddu t1, t0, 32
+ bltz t1, bad_stack
+
+1: lw a4, 16(t0) # argument #5 from usp
+2: lw a5, 20(t0) # argument #6 from usp
+3: lw a6, 24(t0) # argument #7 from usp
+4: lw a7, 28(t0) # argument #8 from usp (for indirect syscalls)
+
+ .section __ex_table,"a"
+ PTR 1b, bad_stack
+ PTR 2b, bad_stack
+ PTR 3b, bad_stack
+ PTR 4b, bad_stack
+ .previous
+
+ li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
+ and t0, t1, t0
+ bnez t0, trace_a_syscall
+
+ jalr t2 # Do The Real Thing (TM)
+
+ li t0, -EMAXERRNO - 1 # error?
+ sltu t0, t0, v0
+ sd t0, PT_R7(sp) # set error flag
+ beqz t0, 1f
+
+ ld t1, PT_R2(sp) # syscall number
+ dnegu v0 # error
+ sd t1, PT_R0(sp) # save it for syscall restarting
+1: sd v0, PT_R2(sp) # result
+
+o32_syscall_exit:
+ local_irq_disable # make need_resched and
+ # signals dont change between
+ # sampling and return
+ LONG_L a2, TI_FLAGS($28)
+ li t0, _TIF_ALLWORK_MASK
+ and t0, a2, t0
+ bnez t0, o32_syscall_exit_work
+
+ j restore_partial
+
+o32_syscall_exit_work:
+ j syscall_exit_work_partial
+
+/* ------------------------------------------------------------------------ */
+
+trace_a_syscall:
+ SAVE_STATIC
+ sd a4, PT_R8(sp) # Save argument registers
+ sd a5, PT_R9(sp)
+ sd a6, PT_R10(sp)
+ sd a7, PT_R11(sp) # For indirect syscalls
+
+ move s0, t2 # Save syscall pointer
+ move a0, sp
+ jal syscall_trace_enter
+
+ move t0, s0
+ RESTORE_STATIC
+ ld a0, PT_R4(sp) # Restore argument registers
+ ld a1, PT_R5(sp)
+ ld a2, PT_R6(sp)
+ ld a3, PT_R7(sp)
+ ld a4, PT_R8(sp)
+ ld a5, PT_R9(sp)
+ ld a6, PT_R10(sp)
+ ld a7, PT_R11(sp) # For indirect syscalls
+ jalr t0
+
+ li t0, -EMAXERRNO - 1 # error?
+ sltu t0, t0, v0
+ sd t0, PT_R7(sp) # set error flag
+ beqz t0, 1f
+
+ ld t1, PT_R2(sp) # syscall number
+ dnegu v0 # error
+ sd t1, PT_R0(sp) # save it for syscall restarting
+1: sd v0, PT_R2(sp) # result
+
+ j syscall_exit
+
+/* ------------------------------------------------------------------------ */
+
+ /*
+ * The stackpointer for a call with more than 4 arguments is bad.
+ */
+bad_stack:
+ li v0, EFAULT
+ sd v0, PT_R2(sp)
+ li t0, 1 # set error flag
+ sd t0, PT_R7(sp)
+ j o32_syscall_exit
+
+not_o32_scall:
+ /*
+ * This is not an o32 compatibility syscall, pass it on
+ * to the 64-bit syscall handlers.
+ */
+#ifdef CONFIG_MIPS32_N32
+ j handle_sysn32
+#else
+ j handle_sys64
+#endif
+ END(handle_sys)
+
+LEAF(sys32_syscall)
+ subu t0, a0, __NR_O32_Linux # check syscall number
+ sltiu v0, t0, __NR_O32_Linux_syscalls + 1
+ beqz t0, einval # do not recurse
+ dsll t1, t0, 3
+ beqz v0, einval
+ ld t2, sys_call_table(t1) # syscall routine
+
+ move a0, a1 # shift argument registers
+ move a1, a2
+ move a2, a3
+ move a3, a4
+ move a4, a5
+ move a5, a6
+ move a6, a7
+ sd a0, PT_R4(sp) # ... and push back a0 - a3, some
+ sd a1, PT_R5(sp) # syscalls expect them there
+ sd a2, PT_R6(sp)
+ sd a3, PT_R7(sp)
+ sd a3, PT_R26(sp) # update a3 for syscall restarting
+ jr t2
+ /* Unreached */
+
+einval: li v0, -ENOSYS
+ jr ra
+ END(sys32_syscall)
+
+ .align 3
+ .type sys_call_table,@object
+sys_call_table:
+ PTR sys32_syscall /* 4000 */
+ PTR sys_exit
+ PTR sys_fork
+ PTR sys_read
+ PTR sys_write
+ PTR compat_sys_open /* 4005 */
+ PTR sys_close
+ PTR sys_waitpid
+ PTR sys_creat
+ PTR sys_link
+ PTR sys_unlink /* 4010 */
+ PTR sys32_execve
+ PTR sys_chdir
+ PTR compat_sys_time
+ PTR sys_mknod
+ PTR sys_chmod /* 4015 */
+ PTR sys_lchown
+ PTR sys_ni_syscall
+ PTR sys_ni_syscall /* was sys_stat */
+ PTR sys_lseek
+ PTR sys_getpid /* 4020 */
+ PTR compat_sys_mount
+ PTR sys_oldumount
+ PTR sys_setuid
+ PTR sys_getuid
+ PTR compat_sys_stime /* 4025 */
+ PTR compat_sys_ptrace
+ PTR sys_alarm
+ PTR sys_ni_syscall /* was sys_fstat */
+ PTR sys_pause
+ PTR compat_sys_utime /* 4030 */
+ PTR sys_ni_syscall
+ PTR sys_ni_syscall
+ PTR sys_access
+ PTR sys_nice
+ PTR sys_ni_syscall /* 4035 */
+ PTR sys_sync
+ PTR sys_kill
+ PTR sys_rename
+ PTR sys_mkdir
+ PTR sys_rmdir /* 4040 */
+ PTR sys_dup
+ PTR sysm_pipe
+ PTR compat_sys_times
+ PTR sys_ni_syscall
+ PTR sys_brk /* 4045 */
+ PTR sys_setgid
+ PTR sys_getgid
+ PTR sys_ni_syscall /* was signal 2 */
+ PTR sys_geteuid
+ PTR sys_getegid /* 4050 */
+ PTR sys_acct
+ PTR sys_umount
+ PTR sys_ni_syscall
+ PTR compat_sys_ioctl
+ PTR compat_sys_fcntl /* 4055 */
+ PTR sys_ni_syscall
+ PTR sys_setpgid
+ PTR sys_ni_syscall
+ PTR sys_olduname
+ PTR sys_umask /* 4060 */
+ PTR sys_chroot
+ PTR compat_sys_ustat
+ PTR sys_dup2
+ PTR sys_getppid
+ PTR sys_getpgrp /* 4065 */
+ PTR sys_setsid
+ PTR sys_32_sigaction
+ PTR sys_sgetmask
+ PTR sys_ssetmask
+ PTR sys_setreuid /* 4070 */
+ PTR sys_setregid
+ PTR sys32_sigsuspend
+ PTR compat_sys_sigpending
+ PTR sys_sethostname
+ PTR compat_sys_setrlimit /* 4075 */
+ PTR compat_sys_getrlimit
+ PTR compat_sys_getrusage
+ PTR compat_sys_gettimeofday
+ PTR compat_sys_settimeofday
+ PTR sys_getgroups /* 4080 */
+ PTR sys_setgroups
+ PTR sys_ni_syscall /* old_select */
+ PTR sys_symlink
+ PTR sys_ni_syscall /* was sys_lstat */
+ PTR sys_readlink /* 4085 */
+ PTR sys_uselib
+ PTR sys_swapon
+ PTR sys_reboot
+ PTR compat_sys_old_readdir
+ PTR sys_mips_mmap /* 4090 */
+ PTR sys_munmap
+ PTR sys_truncate
+ PTR sys_ftruncate
+ PTR sys_fchmod
+ PTR sys_fchown /* 4095 */
+ PTR sys_getpriority
+ PTR sys_setpriority
+ PTR sys_ni_syscall
+ PTR compat_sys_statfs
+ PTR compat_sys_fstatfs /* 4100 */
+ PTR sys_ni_syscall /* sys_ioperm */
+ PTR compat_sys_socketcall
+ PTR sys_syslog
+ PTR compat_sys_setitimer
+ PTR compat_sys_getitimer /* 4105 */
+ PTR compat_sys_newstat
+ PTR compat_sys_newlstat
+ PTR compat_sys_newfstat
+ PTR sys_uname
+ PTR sys_ni_syscall /* sys_ioperm *//* 4110 */
+ PTR sys_vhangup
+ PTR sys_ni_syscall /* was sys_idle */
+ PTR sys_ni_syscall /* sys_vm86 */
+ PTR compat_sys_wait4
+ PTR sys_swapoff /* 4115 */
+ PTR compat_sys_sysinfo
+ PTR sys_32_ipc
+ PTR sys_fsync
+ PTR sys32_sigreturn
+ PTR sys32_clone /* 4120 */
+ PTR sys_setdomainname
+ PTR sys_newuname
+ PTR sys_ni_syscall /* sys_modify_ldt */
+ PTR compat_sys_adjtimex
+ PTR sys_mprotect /* 4125 */
+ PTR compat_sys_sigprocmask
+ PTR sys_ni_syscall /* was creat_module */
+ PTR sys_init_module
+ PTR sys_delete_module
+ PTR sys_ni_syscall /* 4130, get_kernel_syms */
+ PTR sys_quotactl
+ PTR sys_getpgid
+ PTR sys_fchdir
+ PTR sys_bdflush
+ PTR sys_sysfs /* 4135 */
+ PTR sys_32_personality
+ PTR sys_ni_syscall /* for afs_syscall */
+ PTR sys_setfsuid
+ PTR sys_setfsgid
+ PTR sys_32_llseek /* 4140 */
+ PTR compat_sys_getdents
+ PTR compat_sys_select
+ PTR sys_flock
+ PTR sys_msync
+ PTR compat_sys_readv /* 4145 */
+ PTR compat_sys_writev
+ PTR sys_cacheflush
+ PTR sys_cachectl
+ PTR sys_sysmips
+ PTR sys_ni_syscall /* 4150 */
+ PTR sys_getsid
+ PTR sys_fdatasync
+ PTR compat_sys_sysctl
+ PTR sys_mlock
+ PTR sys_munlock /* 4155 */
+ PTR sys_mlockall
+ PTR sys_munlockall
+ PTR sys_sched_setparam
+ PTR sys_sched_getparam
+ PTR sys_sched_setscheduler /* 4160 */
+ PTR sys_sched_getscheduler
+ PTR sys_sched_yield
+ PTR sys_sched_get_priority_max
+ PTR sys_sched_get_priority_min
+ PTR sys_32_sched_rr_get_interval /* 4165 */
+ PTR compat_sys_nanosleep
+ PTR sys_mremap
+ PTR sys_accept
+ PTR sys_bind
+ PTR sys_connect /* 4170 */
+ PTR sys_getpeername
+ PTR sys_getsockname
+ PTR sys_getsockopt
+ PTR sys_listen
+ PTR compat_sys_recv /* 4175 */
+ PTR compat_sys_recvfrom
+ PTR compat_sys_recvmsg
+ PTR sys_send
+ PTR compat_sys_sendmsg
+ PTR sys_sendto /* 4180 */
+ PTR compat_sys_setsockopt
+ PTR sys_shutdown
+ PTR sys_socket
+ PTR sys_socketpair
+ PTR sys_setresuid /* 4185 */
+ PTR sys_getresuid
+ PTR sys_ni_syscall /* was query_module */
+ PTR sys_poll
+ PTR compat_sys_nfsservctl
+ PTR sys_setresgid /* 4190 */
+ PTR sys_getresgid
+ PTR sys_prctl
+ PTR sys32_rt_sigreturn
+ PTR sys_32_rt_sigaction
+ PTR sys_32_rt_sigprocmask /* 4195 */
+ PTR sys_32_rt_sigpending
+ PTR compat_sys_rt_sigtimedwait
+ PTR sys_32_rt_sigqueueinfo
+ PTR sys32_rt_sigsuspend
+ PTR sys_32_pread /* 4200 */
+ PTR sys_32_pwrite
+ PTR sys_chown
+ PTR sys_getcwd
+ PTR sys_capget
+ PTR sys_capset /* 4205 */
+ PTR sys32_sigaltstack
+ PTR sys_32_sendfile
+ PTR sys_ni_syscall
+ PTR sys_ni_syscall
+ PTR sys_mips_mmap2 /* 4210 */
+ PTR sys_32_truncate64
+ PTR sys_32_ftruncate64
+ PTR sys_newstat
+ PTR sys_newlstat
+ PTR sys_newfstat /* 4215 */
+ PTR sys_pivot_root
+ PTR sys_mincore
+ PTR sys_madvise
+ PTR sys_getdents64
+ PTR compat_sys_fcntl64 /* 4220 */
+ PTR sys_ni_syscall
+ PTR sys_gettid
+ PTR sys32_readahead
+ PTR sys_setxattr
+ PTR sys_lsetxattr /* 4225 */
+ PTR sys_fsetxattr
+ PTR sys_getxattr
+ PTR sys_lgetxattr
+ PTR sys_fgetxattr
+ PTR sys_listxattr /* 4230 */
+ PTR sys_llistxattr
+ PTR sys_flistxattr
+ PTR sys_removexattr
+ PTR sys_lremovexattr
+ PTR sys_fremovexattr /* 4235 */
+ PTR sys_tkill
+ PTR sys_sendfile64
+ PTR compat_sys_futex
+ PTR compat_sys_sched_setaffinity
+ PTR compat_sys_sched_getaffinity /* 4240 */
+ PTR compat_sys_io_setup
+ PTR sys_io_destroy
+ PTR compat_sys_io_getevents
+ PTR compat_sys_io_submit
+ PTR sys_io_cancel /* 4245 */
+ PTR sys_exit_group
+ PTR sys32_lookup_dcookie
+ PTR sys_epoll_create
+ PTR sys_epoll_ctl
+ PTR sys_epoll_wait /* 4250 */
+ PTR sys_remap_file_pages
+ PTR sys_set_tid_address
+ PTR sys_restart_syscall
+ PTR sys32_fadvise64_64
+ PTR compat_sys_statfs64 /* 4255 */
+ PTR compat_sys_fstatfs64
+ PTR compat_sys_timer_create
+ PTR compat_sys_timer_settime
+ PTR compat_sys_timer_gettime
+ PTR sys_timer_getoverrun /* 4260 */
+ PTR sys_timer_delete
+ PTR compat_sys_clock_settime
+ PTR compat_sys_clock_gettime
+ PTR compat_sys_clock_getres
+ PTR compat_sys_clock_nanosleep /* 4265 */
+ PTR sys_tgkill
+ PTR compat_sys_utimes
+ PTR sys_ni_syscall /* sys_mbind */
+ PTR sys_ni_syscall /* sys_get_mempolicy */
+ PTR sys_ni_syscall /* 4270 sys_set_mempolicy */
+ PTR compat_sys_mq_open
+ PTR sys_mq_unlink
+ PTR compat_sys_mq_timedsend
+ PTR compat_sys_mq_timedreceive
+ PTR compat_sys_mq_notify /* 4275 */
+ PTR compat_sys_mq_getsetattr
+ PTR sys_ni_syscall /* sys_vserver */
+ PTR sys_32_waitid
+ PTR sys_ni_syscall /* available, was setaltroot */
+ PTR sys_add_key /* 4280 */
+ PTR sys_request_key
+ PTR sys_keyctl
+ PTR sys_set_thread_area
+ PTR sys_inotify_init
+ PTR sys_inotify_add_watch /* 4285 */
+ PTR sys_inotify_rm_watch
+ PTR sys_migrate_pages
+ PTR compat_sys_openat
+ PTR sys_mkdirat
+ PTR sys_mknodat /* 4290 */
+ PTR sys_fchownat
+ PTR compat_sys_futimesat
+ PTR sys_newfstatat
+ PTR sys_unlinkat
+ PTR sys_renameat /* 4295 */
+ PTR sys_linkat
+ PTR sys_symlinkat
+ PTR sys_readlinkat
+ PTR sys_fchmodat
+ PTR sys_faccessat /* 4300 */
+ PTR compat_sys_pselect6
+ PTR compat_sys_ppoll
+ PTR sys_unshare
+ PTR sys_splice
+ PTR sys32_sync_file_range /* 4305 */
+ PTR sys_tee
+ PTR compat_sys_vmsplice
+ PTR compat_sys_move_pages
+ PTR compat_sys_set_robust_list
+ PTR compat_sys_get_robust_list /* 4310 */
+ PTR compat_sys_kexec_load
+ PTR sys_getcpu
+ PTR compat_sys_epoll_pwait
+ PTR sys_ioprio_set
+ PTR sys_ioprio_get /* 4315 */
+ PTR compat_sys_utimensat
+ PTR compat_sys_signalfd
+ PTR sys_ni_syscall /* was timerfd */
+ PTR sys_eventfd
+ PTR sys32_fallocate /* 4320 */
+ PTR sys_timerfd_create
+ PTR compat_sys_timerfd_gettime
+ PTR compat_sys_timerfd_settime
+ PTR compat_sys_signalfd4
+ PTR sys_eventfd2 /* 4325 */
+ PTR sys_epoll_create1
+ PTR sys_dup3
+ PTR sys_pipe2
+ PTR sys_inotify_init1
+ PTR compat_sys_preadv /* 4330 */
+ PTR compat_sys_pwritev
+ PTR compat_sys_rt_tgsigqueueinfo
+ PTR sys_perf_event_open
+ PTR sys_accept4
+ PTR compat_sys_recvmmsg /* 4335 */
+ PTR sys_fanotify_init
+ PTR sys_32_fanotify_mark
+ PTR sys_prlimit64
+ PTR sys_name_to_handle_at
+ PTR compat_sys_open_by_handle_at /* 4340 */
+ PTR compat_sys_clock_adjtime
+ PTR sys_syncfs
+ PTR sys_setns
+ .size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
new file mode 100644
index 00000000..8ad1d567
--- /dev/null
+++ b/arch/mips/kernel/setup.c
@@ -0,0 +1,591 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 Linus Torvalds
+ * Copyright (C) 1995 Waldorf Electronics
+ * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 Ralf Baechle
+ * Copyright (C) 1996 Stoned Elipot
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/screen_info.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <linux/root_dev.h>
+#include <linux/highmem.h>
+#include <linux/console.h>
+#include <linux/pfn.h>
+#include <linux/debugfs.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm/bugs.h>
+#include <asm/cache.h>
+#include <asm/cpu.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+#include <asm/smp-ops.h>
+#include <asm/system.h>
+#include <asm/prom.h>
+
+struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
+
+EXPORT_SYMBOL(cpu_data);
+
+#ifdef CONFIG_VT
+struct screen_info screen_info;
+#endif
+
+/*
+ * Despite it's name this variable is even if we don't have PCI
+ */
+unsigned int PCI_DMA_BUS_IS_PHYS;
+
+EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS);
+
+/*
+ * Setup information
+ *
+ * These are initialized so they are in the .data section
+ */
+unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
+
+EXPORT_SYMBOL(mips_machtype);
+
+struct boot_mem_map boot_mem_map;
+
+static char __initdata command_line[COMMAND_LINE_SIZE];
+char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
+
+#ifdef CONFIG_CMDLINE_BOOL
+static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
+#endif
+
+/*
+ * mips_io_port_base is the begin of the address space to which x86 style
+ * I/O ports are mapped.
+ */
+const unsigned long mips_io_port_base = -1;
+EXPORT_SYMBOL(mips_io_port_base);
+
+static struct resource code_resource = { .name = "Kernel code", };
+static struct resource data_resource = { .name = "Kernel data", };
+
+void __init add_memory_region(phys_t start, phys_t size, long type)
+{
+ int x = boot_mem_map.nr_map;
+ struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1;
+
+ /* Sanity check */
+ if (start + size < start) {
+ pr_warning("Trying to add an invalid memory region, skipped\n");
+ return;
+ }
+
+ /*
+ * Try to merge with previous entry if any. This is far less than
+ * perfect but is sufficient for most real world cases.
+ */
+ if (x && prev->addr + prev->size == start && prev->type == type) {
+ prev->size += size;
+ return;
+ }
+
+ if (x == BOOT_MEM_MAP_MAX) {
+ pr_err("Ooops! Too many entries in the memory map!\n");
+ return;
+ }
+
+ boot_mem_map.map[x].addr = start;
+ boot_mem_map.map[x].size = size;
+ boot_mem_map.map[x].type = type;
+ boot_mem_map.nr_map++;
+}
+
+static void __init print_memory_map(void)
+{
+ int i;
+ const int field = 2 * sizeof(unsigned long);
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ printk(KERN_INFO " memory: %0*Lx @ %0*Lx ",
+ field, (unsigned long long) boot_mem_map.map[i].size,
+ field, (unsigned long long) boot_mem_map.map[i].addr);
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ printk(KERN_CONT "(usable)\n");
+ break;
+ case BOOT_MEM_ROM_DATA:
+ printk(KERN_CONT "(ROM data)\n");
+ break;
+ case BOOT_MEM_RESERVED:
+ printk(KERN_CONT "(reserved)\n");
+ break;
+ default:
+ printk(KERN_CONT "type %lu\n", boot_mem_map.map[i].type);
+ break;
+ }
+ }
+}
+
+/*
+ * Manage initrd
+ */
+#ifdef CONFIG_BLK_DEV_INITRD
+
+static int __init rd_start_early(char *p)
+{
+ unsigned long start = memparse(p, &p);
+
+#ifdef CONFIG_64BIT
+ /* Guess if the sign extension was forgotten by bootloader */
+ if (start < XKPHYS)
+ start = (int)start;
+#endif
+ initrd_start = start;
+ initrd_end += start;
+ return 0;
+}
+early_param("rd_start", rd_start_early);
+
+static int __init rd_size_early(char *p)
+{
+ initrd_end += memparse(p, &p);
+ return 0;
+}
+early_param("rd_size", rd_size_early);
+
+/* it returns the next free pfn after initrd */
+static unsigned long __init init_initrd(void)
+{
+ unsigned long end;
+
+ /*
+ * Board specific code or command line parser should have
+ * already set up initrd_start and initrd_end. In these cases
+ * perfom sanity checks and use them if all looks good.
+ */
+ if (!initrd_start || initrd_end <= initrd_start)
+ goto disable;
+
+ if (initrd_start & ~PAGE_MASK) {
+ pr_err("initrd start must be page aligned\n");
+ goto disable;
+ }
+ if (initrd_start < PAGE_OFFSET) {
+ pr_err("initrd start < PAGE_OFFSET\n");
+ goto disable;
+ }
+
+ /*
+ * Sanitize initrd addresses. For example firmware
+ * can't guess if they need to pass them through
+ * 64-bits values if the kernel has been built in pure
+ * 32-bit. We need also to switch from KSEG0 to XKPHYS
+ * addresses now, so the code can now safely use __pa().
+ */
+ end = __pa(initrd_end);
+ initrd_end = (unsigned long)__va(end);
+ initrd_start = (unsigned long)__va(__pa(initrd_start));
+
+ ROOT_DEV = Root_RAM0;
+ return PFN_UP(end);
+disable:
+ initrd_start = 0;
+ initrd_end = 0;
+ return 0;
+}
+
+static void __init finalize_initrd(void)
+{
+ unsigned long size = initrd_end - initrd_start;
+
+ if (size == 0) {
+ printk(KERN_INFO "Initrd not found or empty");
+ goto disable;
+ }
+ if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) {
+ printk(KERN_ERR "Initrd extends beyond end of memory");
+ goto disable;
+ }
+
+ reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
+ initrd_below_start_ok = 1;
+
+ pr_info("Initial ramdisk at: 0x%lx (%lu bytes)\n",
+ initrd_start, size);
+ return;
+disable:
+ printk(KERN_CONT " - disabling initrd\n");
+ initrd_start = 0;
+ initrd_end = 0;
+}
+
+#else /* !CONFIG_BLK_DEV_INITRD */
+
+static unsigned long __init init_initrd(void)
+{
+ return 0;
+}
+
+#define finalize_initrd() do {} while (0)
+
+#endif
+
+/*
+ * Initialize the bootmem allocator. It also setup initrd related data
+ * if needed.
+ */
+#ifdef CONFIG_SGI_IP27
+
+static void __init bootmem_init(void)
+{
+ init_initrd();
+ finalize_initrd();
+}
+
+#else /* !CONFIG_SGI_IP27 */
+
+static void __init bootmem_init(void)
+{
+ unsigned long reserved_end;
+ unsigned long mapstart = ~0UL;
+ unsigned long bootmap_size;
+ int i;
+
+ /*
+ * Init any data related to initrd. It's a nop if INITRD is
+ * not selected. Once that done we can determine the low bound
+ * of usable memory.
+ */
+ reserved_end = max(init_initrd(),
+ (unsigned long) PFN_UP(__pa_symbol(&_end)));
+
+ /*
+ * max_low_pfn is not a number of pages. The number of pages
+ * of the system is given by 'max_low_pfn - min_low_pfn'.
+ */
+ min_low_pfn = ~0UL;
+ max_low_pfn = 0;
+
+ /*
+ * Find the highest page frame number we have available.
+ */
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ unsigned long start, end;
+
+ if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+ continue;
+
+ start = PFN_UP(boot_mem_map.map[i].addr);
+ end = PFN_DOWN(boot_mem_map.map[i].addr
+ + boot_mem_map.map[i].size);
+
+ if (end > max_low_pfn)
+ max_low_pfn = end;
+ if (start < min_low_pfn)
+ min_low_pfn = start;
+ if (end <= reserved_end)
+ continue;
+ if (start >= mapstart)
+ continue;
+ mapstart = max(reserved_end, start);
+ }
+
+ if (min_low_pfn >= max_low_pfn)
+ panic("Incorrect memory mapping !!!");
+ if (min_low_pfn > ARCH_PFN_OFFSET) {
+ pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
+ (min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page),
+ min_low_pfn - ARCH_PFN_OFFSET);
+ } else if (min_low_pfn < ARCH_PFN_OFFSET) {
+ pr_info("%lu free pages won't be used\n",
+ ARCH_PFN_OFFSET - min_low_pfn);
+ }
+ min_low_pfn = ARCH_PFN_OFFSET;
+
+ /*
+ * Determine low and high memory ranges
+ */
+ max_pfn = max_low_pfn;
+ if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
+#ifdef CONFIG_HIGHMEM
+ highstart_pfn = PFN_DOWN(HIGHMEM_START);
+ highend_pfn = max_low_pfn;
+#endif
+ max_low_pfn = PFN_DOWN(HIGHMEM_START);
+ }
+
+ /*
+ * Initialize the boot-time allocator with low memory only.
+ */
+ bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart,
+ min_low_pfn, max_low_pfn);
+
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ unsigned long start, end;
+
+ start = PFN_UP(boot_mem_map.map[i].addr);
+ end = PFN_DOWN(boot_mem_map.map[i].addr
+ + boot_mem_map.map[i].size);
+
+ if (start <= min_low_pfn)
+ start = min_low_pfn;
+ if (start >= end)
+ continue;
+
+#ifndef CONFIG_HIGHMEM
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+
+ /*
+ * ... finally, is the area going away?
+ */
+ if (end <= start)
+ continue;
+#endif
+
+ add_active_range(0, start, end);
+ }
+
+ /*
+ * Register fully available low RAM pages with the bootmem allocator.
+ */
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ unsigned long start, end, size;
+
+ /*
+ * Reserve usable memory.
+ */
+ if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+ continue;
+
+ start = PFN_UP(boot_mem_map.map[i].addr);
+ end = PFN_DOWN(boot_mem_map.map[i].addr
+ + boot_mem_map.map[i].size);
+ /*
+ * We are rounding up the start address of usable memory
+ * and at the end of the usable range downwards.
+ */
+ if (start >= max_low_pfn)
+ continue;
+ if (start < reserved_end)
+ start = reserved_end;
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+
+ /*
+ * ... finally, is the area going away?
+ */
+ if (end <= start)
+ continue;
+ size = end - start;
+
+ /* Register lowmem ranges */
+ free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT);
+ memory_present(0, start, end);
+ }
+
+ /*
+ * Reserve the bootmap memory.
+ */
+ reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT);
+
+ /*
+ * Reserve initrd memory if needed.
+ */
+ finalize_initrd();
+}
+
+#endif /* CONFIG_SGI_IP27 */
+
+/*
+ * arch_mem_init - initialize memory management subsystem
+ *
+ * o plat_mem_setup() detects the memory configuration and will record detected
+ * memory areas using add_memory_region.
+ *
+ * At this stage the memory configuration of the system is known to the
+ * kernel but generic memory management system is still entirely uninitialized.
+ *
+ * o bootmem_init()
+ * o sparse_init()
+ * o paging_init()
+ *
+ * At this stage the bootmem allocator is ready to use.
+ *
+ * NOTE: historically plat_mem_setup did the entire platform initialization.
+ * This was rather impractical because it meant plat_mem_setup had to
+ * get away without any kind of memory allocator. To keep old code from
+ * breaking plat_setup was just renamed to plat_setup and a second platform
+ * initialization hook for anything else was introduced.
+ */
+
+static int usermem __initdata;
+
+static int __init early_parse_mem(char *p)
+{
+ unsigned long start, size;
+
+ /*
+ * If a user specifies memory size, we
+ * blow away any automatically generated
+ * size.
+ */
+ if (usermem == 0) {
+ boot_mem_map.nr_map = 0;
+ usermem = 1;
+ }
+ start = 0;
+ size = memparse(p, &p);
+ if (*p == '@')
+ start = memparse(p + 1, &p);
+
+ add_memory_region(start, size, BOOT_MEM_RAM);
+ return 0;
+}
+early_param("mem", early_parse_mem);
+
+static void __init arch_mem_init(char **cmdline_p)
+{
+ extern void plat_mem_setup(void);
+
+ /* call board setup routine */
+ plat_mem_setup();
+
+ pr_info("Determined physical RAM map:\n");
+ print_memory_map();
+
+#ifdef CONFIG_CMDLINE_BOOL
+#ifdef CONFIG_CMDLINE_OVERRIDE
+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+#else
+ if (builtin_cmdline[0]) {
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+ strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
+ }
+ strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+#endif
+#else
+ strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
+#endif
+ strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
+
+ *cmdline_p = command_line;
+
+ parse_early_param();
+
+ if (usermem) {
+ pr_info("User-defined physical RAM map:\n");
+ print_memory_map();
+ }
+
+ bootmem_init();
+ device_tree_init();
+ sparse_init();
+ plat_swiotlb_setup();
+ paging_init();
+}
+
+static void __init resource_init(void)
+{
+ int i;
+
+ if (UNCAC_BASE != IO_BASE)
+ return;
+
+ code_resource.start = __pa_symbol(&_text);
+ code_resource.end = __pa_symbol(&_etext) - 1;
+ data_resource.start = __pa_symbol(&_etext);
+ data_resource.end = __pa_symbol(&_edata) - 1;
+
+ /*
+ * Request address space for all standard RAM.
+ */
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ struct resource *res;
+ unsigned long start, end;
+
+ start = boot_mem_map.map[i].addr;
+ end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
+ if (start >= HIGHMEM_START)
+ continue;
+ if (end >= HIGHMEM_START)
+ end = HIGHMEM_START - 1;
+
+ res = alloc_bootmem(sizeof(struct resource));
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ case BOOT_MEM_ROM_DATA:
+ res->name = "System RAM";
+ break;
+ case BOOT_MEM_RESERVED:
+ default:
+ res->name = "reserved";
+ }
+
+ res->start = start;
+ res->end = end;
+
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ request_resource(&iomem_resource, res);
+
+ /*
+ * We don't know which RAM region contains kernel data,
+ * so we try it repeatedly and let the resource manager
+ * test it.
+ */
+ request_resource(res, &code_resource);
+ request_resource(res, &data_resource);
+ }
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+ cpu_probe();
+ prom_init();
+
+#ifdef CONFIG_EARLY_PRINTK
+ setup_early_printk();
+#endif
+ cpu_report();
+ check_bugs_early();
+
+#if defined(CONFIG_VT)
+#if defined(CONFIG_VGA_CONSOLE)
+ conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+#endif
+
+ arch_mem_init(cmdline_p);
+
+ resource_init();
+ plat_smp_setup();
+}
+
+unsigned long kernelsp[NR_CPUS];
+unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
+
+#ifdef CONFIG_DEBUG_FS
+struct dentry *mips_debugfs_dir;
+static int __init debugfs_mips(void)
+{
+ struct dentry *d;
+
+ d = debugfs_create_dir("mips", NULL);
+ if (!d)
+ return -ENOMEM;
+ mips_debugfs_dir = d;
+ return 0;
+}
+arch_initcall(debugfs_mips);
+#endif
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
new file mode 100644
index 00000000..10263b40
--- /dev/null
+++ b/arch/mips/kernel/signal-common.h
@@ -0,0 +1,41 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+
+#ifndef __SIGNAL_COMMON_H
+#define __SIGNAL_COMMON_H
+
+/* #define DEBUG_SIG */
+
+#ifdef DEBUG_SIG
+# define DEBUGP(fmt, args...) printk("%s: " fmt, __func__, ##args)
+#else
+# define DEBUGP(fmt, args...)
+#endif
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+/*
+ * Determine which stack to use..
+ */
+extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+ size_t frame_size);
+/* Check and clear pending FPU exceptions in saved CSR */
+extern int fpcsr_pending(unsigned int __user *fpcsr);
+
+/* Make sure we will not lose FPU ownership */
+#ifdef CONFIG_PREEMPT
+#define lock_fpu_owner() preempt_disable()
+#define unlock_fpu_owner() preempt_enable()
+#else
+#define lock_fpu_owner() pagefault_disable()
+#define unlock_fpu_owner() pagefault_enable()
+#endif
+
+#endif /* __SIGNAL_COMMON_H */
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
new file mode 100644
index 00000000..dbbe0ce4
--- /dev/null
+++ b/arch/mips/kernel/signal.c
@@ -0,0 +1,708 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/cache.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/personality.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/compiler.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <linux/tracehook.h>
+
+#include <asm/abi.h>
+#include <asm/asm.h>
+#include <linux/bitops.h>
+#include <asm/cacheflush.h>
+#include <asm/fpu.h>
+#include <asm/sim.h>
+#include <asm/ucontext.h>
+#include <asm/cpu-features.h>
+#include <asm/war.h>
+#include <asm/vdso.h>
+
+#include "signal-common.h"
+
+static int (*save_fp_context)(struct sigcontext __user *sc);
+static int (*restore_fp_context)(struct sigcontext __user *sc);
+
+extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
+extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
+
+extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
+extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
+
+struct sigframe {
+ u32 sf_ass[4]; /* argument save space for o32 */
+ u32 sf_pad[2]; /* Was: signal trampoline */
+ struct sigcontext sf_sc;
+ sigset_t sf_mask;
+};
+
+struct rt_sigframe {
+ u32 rs_ass[4]; /* argument save space for o32 */
+ u32 rs_pad[2]; /* Was: signal trampoline */
+ struct siginfo rs_info;
+ struct ucontext rs_uc;
+};
+
+/*
+ * Helper routines
+ */
+static int protected_save_fp_context(struct sigcontext __user *sc)
+{
+ int err;
+ while (1) {
+ lock_fpu_owner();
+ own_fpu_inatomic(1);
+ err = save_fp_context(sc); /* this might fail */
+ unlock_fpu_owner();
+ if (likely(!err))
+ break;
+ /* touch the sigcontext and try again */
+ err = __put_user(0, &sc->sc_fpregs[0]) |
+ __put_user(0, &sc->sc_fpregs[31]) |
+ __put_user(0, &sc->sc_fpc_csr);
+ if (err)
+ break; /* really bad sigcontext */
+ }
+ return err;
+}
+
+static int protected_restore_fp_context(struct sigcontext __user *sc)
+{
+ int err, tmp __maybe_unused;
+ while (1) {
+ lock_fpu_owner();
+ own_fpu_inatomic(0);
+ err = restore_fp_context(sc); /* this might fail */
+ unlock_fpu_owner();
+ if (likely(!err))
+ break;
+ /* touch the sigcontext and try again */
+ err = __get_user(tmp, &sc->sc_fpregs[0]) |
+ __get_user(tmp, &sc->sc_fpregs[31]) |
+ __get_user(tmp, &sc->sc_fpc_csr);
+ if (err)
+ break; /* really bad sigcontext */
+ }
+ return err;
+}
+
+int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+{
+ int err = 0;
+ int i;
+ unsigned int used_math;
+
+ err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+
+ err |= __put_user(0, &sc->sc_regs[0]);
+ for (i = 1; i < 32; i++)
+ err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
+
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ err |= __put_user(regs->acx, &sc->sc_acx);
+#endif
+ err |= __put_user(regs->hi, &sc->sc_mdhi);
+ err |= __put_user(regs->lo, &sc->sc_mdlo);
+ if (cpu_has_dsp) {
+ err |= __put_user(mfhi1(), &sc->sc_hi1);
+ err |= __put_user(mflo1(), &sc->sc_lo1);
+ err |= __put_user(mfhi2(), &sc->sc_hi2);
+ err |= __put_user(mflo2(), &sc->sc_lo2);
+ err |= __put_user(mfhi3(), &sc->sc_hi3);
+ err |= __put_user(mflo3(), &sc->sc_lo3);
+ err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+ }
+
+ used_math = !!used_math();
+ err |= __put_user(used_math, &sc->sc_used_math);
+
+ if (used_math) {
+ /*
+ * Save FPU state to signal context. Signal handler
+ * will "inherit" current FPU state.
+ */
+ err |= protected_save_fp_context(sc);
+ }
+ return err;
+}
+
+int fpcsr_pending(unsigned int __user *fpcsr)
+{
+ int err, sig = 0;
+ unsigned int csr, enabled;
+
+ err = __get_user(csr, fpcsr);
+ enabled = FPU_CSR_UNI_X | ((csr & FPU_CSR_ALL_E) << 5);
+ /*
+ * If the signal handler set some FPU exceptions, clear it and
+ * send SIGFPE.
+ */
+ if (csr & enabled) {
+ csr &= ~enabled;
+ err |= __put_user(csr, fpcsr);
+ sig = SIGFPE;
+ }
+ return err ?: sig;
+}
+
+static int
+check_and_restore_fp_context(struct sigcontext __user *sc)
+{
+ int err, sig;
+
+ err = sig = fpcsr_pending(&sc->sc_fpc_csr);
+ if (err > 0)
+ err = 0;
+ err |= protected_restore_fp_context(sc);
+ return err ?: sig;
+}
+
+int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+{
+ unsigned int used_math;
+ unsigned long treg;
+ int err = 0;
+ int i;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+ err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ err |= __get_user(regs->acx, &sc->sc_acx);
+#endif
+ err |= __get_user(regs->hi, &sc->sc_mdhi);
+ err |= __get_user(regs->lo, &sc->sc_mdlo);
+ if (cpu_has_dsp) {
+ err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
+ err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
+ err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
+ err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ }
+
+ for (i = 1; i < 32; i++)
+ err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
+
+ err |= __get_user(used_math, &sc->sc_used_math);
+ conditional_used_math(used_math);
+
+ if (used_math) {
+ /* restore fpu context if we have used it before */
+ if (!err)
+ err = check_and_restore_fp_context(sc);
+ } else {
+ /* signal handler may have used FPU. Give it up. */
+ lose_fpu(0);
+ }
+
+ return err;
+}
+
+void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+ size_t frame_size)
+{
+ unsigned long sp;
+
+ /* Default to using normal stack */
+ sp = regs->regs[29];
+
+ /*
+ * FPU emulator may have it's own trampoline active just
+ * above the user stack, 16-bytes before the next lowest
+ * 16 byte boundary. Try to avoid trashing it.
+ */
+ sp -= 32;
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
+ sp = current->sas_ss_sp + current->sas_ss_size;
+
+ return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+
+#ifdef CONFIG_TRAD_SIGNALS
+asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+ sigset_t newset;
+ sigset_t __user *uset;
+
+ uset = (sigset_t __user *) regs.regs[4];
+ if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ current->saved_sigmask = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ return -ERESTARTNOHAND;
+}
+#endif
+
+asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+ sigset_t newset;
+ sigset_t __user *unewset;
+ size_t sigsetsize;
+
+ /* XXX Don't preclude handling different sized sigset_t's. */
+ sigsetsize = regs.regs[5];
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ unewset = (sigset_t __user *) regs.regs[4];
+ if (copy_from_user(&newset, unewset, sizeof(newset)))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ current->saved_sigmask = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ return -ERESTARTNOHAND;
+}
+
+#ifdef CONFIG_TRAD_SIGNALS
+SYSCALL_DEFINE3(sigaction, int, sig, const struct sigaction __user *, act,
+ struct sigaction __user *, oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+ int err = 0;
+
+ if (act) {
+ old_sigset_t mask;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+ return -EFAULT;
+ err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+ err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ err |= __get_user(mask, &act->sa_mask.sig[0]);
+ if (err)
+ return -EFAULT;
+
+ siginitset(&new_ka.sa.sa_mask, mask);
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+ return -EFAULT;
+ err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+ err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
+ err |= __put_user(0, &oact->sa_mask.sig[1]);
+ err |= __put_user(0, &oact->sa_mask.sig[2]);
+ err |= __put_user(0, &oact->sa_mask.sig[3]);
+ if (err)
+ return -EFAULT;
+ }
+
+ return ret;
+}
+#endif
+
+asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
+{
+ const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
+ stack_t __user *uoss = (stack_t __user *) regs.regs[5];
+ unsigned long usp = regs.regs[29];
+
+ return do_sigaltstack(uss, uoss, usp);
+}
+
+#ifdef CONFIG_TRAD_SIGNALS
+asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+ struct sigframe __user *frame;
+ sigset_t blocked;
+ int sig;
+
+ frame = (struct sigframe __user *) regs.regs[29];
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
+ goto badframe;
+
+ sigdelsetmask(&blocked, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = blocked;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ sig = restore_sigcontext(&regs, &frame->sf_sc);
+ if (sig < 0)
+ goto badframe;
+ else if (sig)
+ force_sig(sig, current);
+
+ /*
+ * Don't let your children do this ...
+ */
+ __asm__ __volatile__(
+ "move\t$29, %0\n\t"
+ "j\tsyscall_exit"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
+
+badframe:
+ force_sig(SIGSEGV, current);
+}
+#endif /* CONFIG_TRAD_SIGNALS */
+
+asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+ struct rt_sigframe __user *frame;
+ sigset_t set;
+ int sig;
+
+ frame = (struct rt_sigframe __user *) regs.regs[29];
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
+ if (sig < 0)
+ goto badframe;
+ else if (sig)
+ force_sig(sig, current);
+
+ /* It is more difficult to avoid calling this function than to
+ call it and ignore errors. */
+ do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs.regs[29]);
+
+ /*
+ * Don't let your children do this ...
+ */
+ __asm__ __volatile__(
+ "move\t$29, %0\n\t"
+ "j\tsyscall_exit"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
+
+badframe:
+ force_sig(SIGSEGV, current);
+}
+
+#ifdef CONFIG_TRAD_SIGNALS
+static int setup_frame(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set)
+{
+ struct sigframe __user *frame;
+ int err = 0;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ goto give_sigsegv;
+
+ err |= setup_sigcontext(regs, &frame->sf_sc);
+ err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+ if (err)
+ goto give_sigsegv;
+
+ /*
+ * Arguments to signal handler:
+ *
+ * a0 = signal number
+ * a1 = 0 (should be cause)
+ * a2 = pointer to struct sigcontext
+ *
+ * $25 and c0_epc point to the signal handler, $29 points to the
+ * struct sigframe.
+ */
+ regs->regs[ 4] = signr;
+ regs->regs[ 5] = 0;
+ regs->regs[ 6] = (unsigned long) &frame->sf_sc;
+ regs->regs[29] = (unsigned long) frame;
+ regs->regs[31] = (unsigned long) sig_return;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+ DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
+ current->comm, current->pid,
+ frame, regs->cp0_epc, regs->regs[31]);
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(signr, current);
+ return -EFAULT;
+}
+#endif
+
+static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set,
+ siginfo_t *info)
+{
+ struct rt_sigframe __user *frame;
+ int err = 0;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ goto give_sigsegv;
+
+ /* Create siginfo. */
+ err |= copy_siginfo_to_user(&frame->rs_info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->rs_uc.uc_flags);
+ err |= __put_user(NULL, &frame->rs_uc.uc_link);
+ err |= __put_user((void __user *)current->sas_ss_sp,
+ &frame->rs_uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->regs[29]),
+ &frame->rs_uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size,
+ &frame->rs_uc.uc_stack.ss_size);
+ err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+ err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+ if (err)
+ goto give_sigsegv;
+
+ /*
+ * Arguments to signal handler:
+ *
+ * a0 = signal number
+ * a1 = 0 (should be cause)
+ * a2 = pointer to ucontext
+ *
+ * $25 and c0_epc point to the signal handler, $29 points to
+ * the struct rt_sigframe.
+ */
+ regs->regs[ 4] = signr;
+ regs->regs[ 5] = (unsigned long) &frame->rs_info;
+ regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+ regs->regs[29] = (unsigned long) frame;
+ regs->regs[31] = (unsigned long) sig_return;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+ DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
+ current->comm, current->pid,
+ frame, regs->cp0_epc, regs->regs[31]);
+
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(signr, current);
+ return -EFAULT;
+}
+
+struct mips_abi mips_abi = {
+#ifdef CONFIG_TRAD_SIGNALS
+ .setup_frame = setup_frame,
+ .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
+#endif
+ .setup_rt_frame = setup_rt_frame,
+ .rt_signal_return_offset =
+ offsetof(struct mips_vdso, rt_signal_trampoline),
+ .restart = __NR_restart_syscall
+};
+
+static int handle_signal(unsigned long sig, siginfo_t *info,
+ struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
+{
+ int ret;
+ struct mips_abi *abi = current->thread.abi;
+ void *vdso = current->mm->context.vdso;
+
+ if (regs->regs[0]) {
+ switch(regs->regs[2]) {
+ case ERESTART_RESTARTBLOCK:
+ case ERESTARTNOHAND:
+ regs->regs[2] = EINTR;
+ break;
+ case ERESTARTSYS:
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
+ regs->regs[2] = EINTR;
+ break;
+ }
+ /* fallthrough */
+ case ERESTARTNOINTR:
+ regs->regs[7] = regs->regs[26];
+ regs->regs[2] = regs->regs[0];
+ regs->cp0_epc -= 4;
+ }
+
+ regs->regs[0] = 0; /* Don't deal with this again. */
+ }
+
+ if (sig_uses_siginfo(ka))
+ ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+ ka, regs, sig, oldset, info);
+ else
+ ret = abi->setup_frame(vdso + abi->signal_return_offset,
+ ka, regs, sig, oldset);
+
+ if (ret)
+ return ret;
+
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&current->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ return ret;
+}
+
+static void do_signal(struct pt_regs *regs)
+{
+ struct k_sigaction ka;
+ sigset_t *oldset;
+ siginfo_t info;
+ int signr;
+
+ /*
+ * We want the common case to go fast, which is why we may in certain
+ * cases get here from kernel mode. Just return without doing anything
+ * if so.
+ */
+ if (!user_mode(regs))
+ return;
+
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = &current->saved_sigmask;
+ else
+ oldset = &current->blocked;
+
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ /* Whee! Actually deliver the signal. */
+ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+ /*
+ * A signal was successfully delivered; the saved
+ * sigmask will have been stored in the signal frame,
+ * and will be restored by sigreturn, so we can simply
+ * clear the TIF_RESTORE_SIGMASK flag.
+ */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ }
+
+ return;
+ }
+
+ if (regs->regs[0]) {
+ if (regs->regs[2] == ERESTARTNOHAND ||
+ regs->regs[2] == ERESTARTSYS ||
+ regs->regs[2] == ERESTARTNOINTR) {
+ regs->regs[2] = regs->regs[0];
+ regs->regs[7] = regs->regs[26];
+ regs->cp0_epc -= 4;
+ }
+ if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
+ regs->regs[2] = current->thread.abi->restart;
+ regs->regs[7] = regs->regs[26];
+ regs->cp0_epc -= 4;
+ }
+ regs->regs[0] = 0; /* Don't deal with this again. */
+ }
+
+ /*
+ * If there's no signal to deliver, we just put the saved sigmask
+ * back
+ */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ }
+}
+
+/*
+ * notification of userspace execution resumption
+ * - triggered by the TIF_WORK_MASK flags
+ */
+asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
+ __u32 thread_info_flags)
+{
+ /* deal with pending signal delivery */
+ if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+ do_signal(regs);
+
+ if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ if (current->replacement_session_keyring)
+ key_replace_session_keyring();
+ }
+}
+
+#ifdef CONFIG_SMP
+static int smp_save_fp_context(struct sigcontext __user *sc)
+{
+ return raw_cpu_has_fpu
+ ? _save_fp_context(sc)
+ : fpu_emulator_save_context(sc);
+}
+
+static int smp_restore_fp_context(struct sigcontext __user *sc)
+{
+ return raw_cpu_has_fpu
+ ? _restore_fp_context(sc)
+ : fpu_emulator_restore_context(sc);
+}
+#endif
+
+static int signal_setup(void)
+{
+#ifdef CONFIG_SMP
+ /* For now just do the cpu_has_fpu check when the functions are invoked */
+ save_fp_context = smp_save_fp_context;
+ restore_fp_context = smp_restore_fp_context;
+#else
+ if (cpu_has_fpu) {
+ save_fp_context = _save_fp_context;
+ restore_fp_context = _restore_fp_context;
+ } else {
+ save_fp_context = fpu_emulator_save_context;
+ restore_fp_context = fpu_emulator_restore_context;
+ }
+#endif
+
+ return 0;
+}
+
+arch_initcall(signal_setup);
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
new file mode 100644
index 00000000..aae98661
--- /dev/null
+++ b/arch/mips/kernel/signal32.c
@@ -0,0 +1,827 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000, 2006 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/cache.h>
+#include <linux/compat.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/suspend.h>
+#include <linux/compiler.h>
+#include <linux/uaccess.h>
+
+#include <asm/abi.h>
+#include <asm/asm.h>
+#include <asm/compat-signal.h>
+#include <linux/bitops.h>
+#include <asm/cacheflush.h>
+#include <asm/sim.h>
+#include <asm/ucontext.h>
+#include <asm/system.h>
+#include <asm/fpu.h>
+#include <asm/war.h>
+#include <asm/vdso.h>
+
+#include "signal-common.h"
+
+static int (*save_fp_context32)(struct sigcontext32 __user *sc);
+static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
+
+extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
+extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
+
+extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
+extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_restart_syscall 4253
+
+/* 32-bit compatibility types */
+
+typedef unsigned int __sighandler32_t;
+typedef void (*vfptr_t)(void);
+
+struct sigaction32 {
+ unsigned int sa_flags;
+ __sighandler32_t sa_handler;
+ compat_sigset_t sa_mask;
+};
+
+/* IRIX compatible stack_t */
+typedef struct sigaltstack32 {
+ s32 ss_sp;
+ compat_size_t ss_size;
+ int ss_flags;
+} stack32_t;
+
+struct ucontext32 {
+ u32 uc_flags;
+ s32 uc_link;
+ stack32_t uc_stack;
+ struct sigcontext32 uc_mcontext;
+ compat_sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+struct sigframe32 {
+ u32 sf_ass[4]; /* argument save space for o32 */
+ u32 sf_pad[2]; /* Was: signal trampoline */
+ struct sigcontext32 sf_sc;
+ compat_sigset_t sf_mask;
+};
+
+struct rt_sigframe32 {
+ u32 rs_ass[4]; /* argument save space for o32 */
+ u32 rs_pad[2]; /* Was: signal trampoline */
+ compat_siginfo_t rs_info;
+ struct ucontext32 rs_uc;
+};
+
+/*
+ * sigcontext handlers
+ */
+static int protected_save_fp_context32(struct sigcontext32 __user *sc)
+{
+ int err;
+ while (1) {
+ lock_fpu_owner();
+ own_fpu_inatomic(1);
+ err = save_fp_context32(sc); /* this might fail */
+ unlock_fpu_owner();
+ if (likely(!err))
+ break;
+ /* touch the sigcontext and try again */
+ err = __put_user(0, &sc->sc_fpregs[0]) |
+ __put_user(0, &sc->sc_fpregs[31]) |
+ __put_user(0, &sc->sc_fpc_csr);
+ if (err)
+ break; /* really bad sigcontext */
+ }
+ return err;
+}
+
+static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
+{
+ int err, tmp __maybe_unused;
+ while (1) {
+ lock_fpu_owner();
+ own_fpu_inatomic(0);
+ err = restore_fp_context32(sc); /* this might fail */
+ unlock_fpu_owner();
+ if (likely(!err))
+ break;
+ /* touch the sigcontext and try again */
+ err = __get_user(tmp, &sc->sc_fpregs[0]) |
+ __get_user(tmp, &sc->sc_fpregs[31]) |
+ __get_user(tmp, &sc->sc_fpc_csr);
+ if (err)
+ break; /* really bad sigcontext */
+ }
+ return err;
+}
+
+static int setup_sigcontext32(struct pt_regs *regs,
+ struct sigcontext32 __user *sc)
+{
+ int err = 0;
+ int i;
+ u32 used_math;
+
+ err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+
+ err |= __put_user(0, &sc->sc_regs[0]);
+ for (i = 1; i < 32; i++)
+ err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
+
+ err |= __put_user(regs->hi, &sc->sc_mdhi);
+ err |= __put_user(regs->lo, &sc->sc_mdlo);
+ if (cpu_has_dsp) {
+ err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
+ err |= __put_user(mfhi1(), &sc->sc_hi1);
+ err |= __put_user(mflo1(), &sc->sc_lo1);
+ err |= __put_user(mfhi2(), &sc->sc_hi2);
+ err |= __put_user(mflo2(), &sc->sc_lo2);
+ err |= __put_user(mfhi3(), &sc->sc_hi3);
+ err |= __put_user(mflo3(), &sc->sc_lo3);
+ }
+
+ used_math = !!used_math();
+ err |= __put_user(used_math, &sc->sc_used_math);
+
+ if (used_math) {
+ /*
+ * Save FPU state to signal context. Signal handler
+ * will "inherit" current FPU state.
+ */
+ err |= protected_save_fp_context32(sc);
+ }
+ return err;
+}
+
+static int
+check_and_restore_fp_context32(struct sigcontext32 __user *sc)
+{
+ int err, sig;
+
+ err = sig = fpcsr_pending(&sc->sc_fpc_csr);
+ if (err > 0)
+ err = 0;
+ err |= protected_restore_fp_context32(sc);
+ return err ?: sig;
+}
+
+static int restore_sigcontext32(struct pt_regs *regs,
+ struct sigcontext32 __user *sc)
+{
+ u32 used_math;
+ int err = 0;
+ s32 treg;
+ int i;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+ err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+ err |= __get_user(regs->hi, &sc->sc_mdhi);
+ err |= __get_user(regs->lo, &sc->sc_mdlo);
+ if (cpu_has_dsp) {
+ err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
+ err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
+ err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
+ err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
+ err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
+ err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
+ err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
+ }
+
+ for (i = 1; i < 32; i++)
+ err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
+
+ err |= __get_user(used_math, &sc->sc_used_math);
+ conditional_used_math(used_math);
+
+ if (used_math) {
+ /* restore fpu context if we have used it before */
+ if (!err)
+ err = check_and_restore_fp_context32(sc);
+ } else {
+ /* signal handler may have used FPU. Give it up. */
+ lose_fpu(0);
+ }
+
+ return err;
+}
+
+/*
+ *
+ */
+extern void __put_sigset_unknown_nsig(void);
+extern void __get_sigset_unknown_nsig(void);
+
+static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
+{
+ int err = 0;
+
+ if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
+ return -EFAULT;
+
+ switch (_NSIG_WORDS) {
+ default:
+ __put_sigset_unknown_nsig();
+ case 2:
+ err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
+ err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
+ case 1:
+ err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
+ err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
+ }
+
+ return err;
+}
+
+static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
+{
+ int err = 0;
+ unsigned long sig[4];
+
+ if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
+ return -EFAULT;
+
+ switch (_NSIG_WORDS) {
+ default:
+ __get_sigset_unknown_nsig();
+ case 2:
+ err |= __get_user(sig[3], &ubuf->sig[3]);
+ err |= __get_user(sig[2], &ubuf->sig[2]);
+ kbuf->sig[1] = sig[2] | (sig[3] << 32);
+ case 1:
+ err |= __get_user(sig[1], &ubuf->sig[1]);
+ err |= __get_user(sig[0], &ubuf->sig[0]);
+ kbuf->sig[0] = sig[0] | (sig[1] << 32);
+ }
+
+ return err;
+}
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+
+asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+ compat_sigset_t __user *uset;
+ sigset_t newset;
+
+ uset = (compat_sigset_t __user *) regs.regs[4];
+ if (get_sigset(&newset, uset))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ current->saved_sigmask = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ return -ERESTARTNOHAND;
+}
+
+asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+ compat_sigset_t __user *uset;
+ sigset_t newset;
+ size_t sigsetsize;
+
+ /* XXX Don't preclude handling different sized sigset_t's. */
+ sigsetsize = regs.regs[5];
+ if (sigsetsize != sizeof(compat_sigset_t))
+ return -EINVAL;
+
+ uset = (compat_sigset_t __user *) regs.regs[4];
+ if (get_sigset(&newset, uset))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ current->saved_sigmask = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ return -ERESTARTNOHAND;
+}
+
+SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
+ struct sigaction32 __user *, oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+ int err = 0;
+
+ if (act) {
+ old_sigset_t mask;
+ s32 handler;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+ return -EFAULT;
+ err |= __get_user(handler, &act->sa_handler);
+ new_ka.sa.sa_handler = (void __user *)(s64)handler;
+ err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ err |= __get_user(mask, &act->sa_mask.sig[0]);
+ if (err)
+ return -EFAULT;
+
+ siginitset(&new_ka.sa.sa_mask, mask);
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+ return -EFAULT;
+ err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
+ &oact->sa_handler);
+ err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
+ err |= __put_user(0, &oact->sa_mask.sig[1]);
+ err |= __put_user(0, &oact->sa_mask.sig[2]);
+ err |= __put_user(0, &oact->sa_mask.sig[3]);
+ if (err)
+ return -EFAULT;
+ }
+
+ return ret;
+}
+
+asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
+{
+ const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
+ stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
+ unsigned long usp = regs.regs[29];
+ stack_t kss, koss;
+ int ret, err = 0;
+ mm_segment_t old_fs = get_fs();
+ s32 sp;
+
+ if (uss) {
+ if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
+ return -EFAULT;
+ err |= __get_user(sp, &uss->ss_sp);
+ kss.ss_sp = (void __user *) (long) sp;
+ err |= __get_user(kss.ss_size, &uss->ss_size);
+ err |= __get_user(kss.ss_flags, &uss->ss_flags);
+ if (err)
+ return -EFAULT;
+ }
+
+ set_fs(KERNEL_DS);
+ ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
+ uoss ? (stack_t __user *)&koss : NULL, usp);
+ set_fs(old_fs);
+
+ if (!ret && uoss) {
+ if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
+ return -EFAULT;
+ sp = (int) (unsigned long) koss.ss_sp;
+ err |= __put_user(sp, &uoss->ss_sp);
+ err |= __put_user(koss.ss_size, &uoss->ss_size);
+ err |= __put_user(koss.ss_flags, &uoss->ss_flags);
+ if (err)
+ return -EFAULT;
+ }
+ return ret;
+}
+
+int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
+{
+ int err;
+
+ if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
+ return -EFAULT;
+
+ /* If you change siginfo_t structure, please be sure
+ this code is fixed accordingly.
+ It should never copy any pad contained in the structure
+ to avoid security leaks, but must copy the generic
+ 3 ints plus the relevant union member.
+ This routine must convert siginfo from 64bit to 32bit as well
+ at the same time. */
+ err = __put_user(from->si_signo, &to->si_signo);
+ err |= __put_user(from->si_errno, &to->si_errno);
+ err |= __put_user((short)from->si_code, &to->si_code);
+ if (from->si_code < 0)
+ err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
+ else {
+ switch (from->si_code >> 16) {
+ case __SI_TIMER >> 16:
+ err |= __put_user(from->si_tid, &to->si_tid);
+ err |= __put_user(from->si_overrun, &to->si_overrun);
+ err |= __put_user(from->si_int, &to->si_int);
+ break;
+ case __SI_CHLD >> 16:
+ err |= __put_user(from->si_utime, &to->si_utime);
+ err |= __put_user(from->si_stime, &to->si_stime);
+ err |= __put_user(from->si_status, &to->si_status);
+ default:
+ err |= __put_user(from->si_pid, &to->si_pid);
+ err |= __put_user(from->si_uid, &to->si_uid);
+ break;
+ case __SI_FAULT >> 16:
+ err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
+ break;
+ case __SI_POLL >> 16:
+ err |= __put_user(from->si_band, &to->si_band);
+ err |= __put_user(from->si_fd, &to->si_fd);
+ break;
+ case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
+ case __SI_MESGQ >> 16:
+ err |= __put_user(from->si_pid, &to->si_pid);
+ err |= __put_user(from->si_uid, &to->si_uid);
+ err |= __put_user(from->si_int, &to->si_int);
+ break;
+ }
+ }
+ return err;
+}
+
+int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
+{
+ memset(to, 0, sizeof *to);
+
+ if (copy_from_user(to, from, 3*sizeof(int)) ||
+ copy_from_user(to->_sifields._pad,
+ from->_sifields._pad, SI_PAD_SIZE32))
+ return -EFAULT;
+
+ return 0;
+}
+
+asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+ struct sigframe32 __user *frame;
+ sigset_t blocked;
+ int sig;
+
+ frame = (struct sigframe32 __user *) regs.regs[29];
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
+ goto badframe;
+
+ sigdelsetmask(&blocked, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = blocked;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ sig = restore_sigcontext32(&regs, &frame->sf_sc);
+ if (sig < 0)
+ goto badframe;
+ else if (sig)
+ force_sig(sig, current);
+
+ /*
+ * Don't let your children do this ...
+ */
+ __asm__ __volatile__(
+ "move\t$29, %0\n\t"
+ "j\tsyscall_exit"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
+
+badframe:
+ force_sig(SIGSEGV, current);
+}
+
+asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+ struct rt_sigframe32 __user *frame;
+ mm_segment_t old_fs;
+ sigset_t set;
+ stack_t st;
+ s32 sp;
+ int sig;
+
+ frame = (struct rt_sigframe32 __user *) regs.regs[29];
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
+ if (sig < 0)
+ goto badframe;
+ else if (sig)
+ force_sig(sig, current);
+
+ /* The ucontext contains a stack32_t, so we must convert! */
+ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
+ goto badframe;
+ st.ss_sp = (void __user *)(long) sp;
+ if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
+ goto badframe;
+ if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
+ goto badframe;
+
+ /* It is more difficult to avoid calling this function than to
+ call it and ignore errors. */
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
+ set_fs(old_fs);
+
+ /*
+ * Don't let your children do this ...
+ */
+ __asm__ __volatile__(
+ "move\t$29, %0\n\t"
+ "j\tsyscall_exit"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
+
+badframe:
+ force_sig(SIGSEGV, current);
+}
+
+static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set)
+{
+ struct sigframe32 __user *frame;
+ int err = 0;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ goto give_sigsegv;
+
+ err |= setup_sigcontext32(regs, &frame->sf_sc);
+ err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
+
+ if (err)
+ goto give_sigsegv;
+
+ /*
+ * Arguments to signal handler:
+ *
+ * a0 = signal number
+ * a1 = 0 (should be cause)
+ * a2 = pointer to struct sigcontext
+ *
+ * $25 and c0_epc point to the signal handler, $29 points to the
+ * struct sigframe.
+ */
+ regs->regs[ 4] = signr;
+ regs->regs[ 5] = 0;
+ regs->regs[ 6] = (unsigned long) &frame->sf_sc;
+ regs->regs[29] = (unsigned long) frame;
+ regs->regs[31] = (unsigned long) sig_return;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+ DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
+ current->comm, current->pid,
+ frame, regs->cp0_epc, regs->regs[31]);
+
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(signr, current);
+ return -EFAULT;
+}
+
+static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set,
+ siginfo_t *info)
+{
+ struct rt_sigframe32 __user *frame;
+ int err = 0;
+ s32 sp;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ goto give_sigsegv;
+
+ /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
+ err |= copy_siginfo_to_user32(&frame->rs_info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->rs_uc.uc_flags);
+ err |= __put_user(0, &frame->rs_uc.uc_link);
+ sp = (int) (long) current->sas_ss_sp;
+ err |= __put_user(sp,
+ &frame->rs_uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->regs[29]),
+ &frame->rs_uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size,
+ &frame->rs_uc.uc_stack.ss_size);
+ err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
+ err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
+
+ if (err)
+ goto give_sigsegv;
+
+ /*
+ * Arguments to signal handler:
+ *
+ * a0 = signal number
+ * a1 = 0 (should be cause)
+ * a2 = pointer to ucontext
+ *
+ * $25 and c0_epc point to the signal handler, $29 points to
+ * the struct rt_sigframe32.
+ */
+ regs->regs[ 4] = signr;
+ regs->regs[ 5] = (unsigned long) &frame->rs_info;
+ regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+ regs->regs[29] = (unsigned long) frame;
+ regs->regs[31] = (unsigned long) sig_return;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+ DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
+ current->comm, current->pid,
+ frame, regs->cp0_epc, regs->regs[31]);
+
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(signr, current);
+ return -EFAULT;
+}
+
+/*
+ * o32 compatibility on 64-bit kernels, without DSP ASE
+ */
+struct mips_abi mips_abi_32 = {
+ .setup_frame = setup_frame_32,
+ .signal_return_offset =
+ offsetof(struct mips_vdso, o32_signal_trampoline),
+ .setup_rt_frame = setup_rt_frame_32,
+ .rt_signal_return_offset =
+ offsetof(struct mips_vdso, o32_rt_signal_trampoline),
+ .restart = __NR_O32_restart_syscall
+};
+
+SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
+ const struct sigaction32 __user *, act,
+ struct sigaction32 __user *, oact, unsigned int, sigsetsize)
+{
+ struct k_sigaction new_sa, old_sa;
+ int ret = -EINVAL;
+
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ goto out;
+
+ if (act) {
+ s32 handler;
+ int err = 0;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+ return -EFAULT;
+ err |= __get_user(handler, &act->sa_handler);
+ new_sa.sa.sa_handler = (void __user *)(s64)handler;
+ err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
+ err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
+ if (err)
+ return -EFAULT;
+ }
+
+ ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
+
+ if (!ret && oact) {
+ int err = 0;
+
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+ return -EFAULT;
+
+ err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
+ &oact->sa_handler);
+ err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
+ err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
+ if (err)
+ return -EFAULT;
+ }
+out:
+ return ret;
+}
+
+SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
+ compat_sigset_t __user *, oset, unsigned int, sigsetsize)
+{
+ sigset_t old_set, new_set;
+ int ret;
+ mm_segment_t old_fs = get_fs();
+
+ if (set && get_sigset(&new_set, set))
+ return -EFAULT;
+
+ set_fs(KERNEL_DS);
+ ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
+ oset ? (sigset_t __user *)&old_set : NULL,
+ sigsetsize);
+ set_fs(old_fs);
+
+ if (!ret && oset && put_sigset(&old_set, oset))
+ return -EFAULT;
+
+ return ret;
+}
+
+SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
+ unsigned int, sigsetsize)
+{
+ int ret;
+ sigset_t set;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs(KERNEL_DS);
+ ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
+ set_fs(old_fs);
+
+ if (!ret && put_sigset(&set, uset))
+ return -EFAULT;
+
+ return ret;
+}
+
+SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
+ compat_siginfo_t __user *, uinfo)
+{
+ siginfo_t info;
+ int ret;
+ mm_segment_t old_fs = get_fs();
+
+ if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
+ copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
+ return -EFAULT;
+ set_fs(KERNEL_DS);
+ ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
+ set_fs(old_fs);
+ return ret;
+}
+
+SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
+ compat_siginfo_t __user *, uinfo, int, options,
+ struct compat_rusage __user *, uru)
+{
+ siginfo_t info;
+ struct rusage ru;
+ long ret;
+ mm_segment_t old_fs = get_fs();
+
+ info.si_signo = 0;
+ set_fs(KERNEL_DS);
+ ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
+ uru ? (struct rusage __user *) &ru : NULL);
+ set_fs(old_fs);
+
+ if (ret < 0 || info.si_signo == 0)
+ return ret;
+
+ if (uru && (ret = put_compat_rusage(&ru, uru)))
+ return ret;
+
+ BUG_ON(info.si_code & __SI_MASK);
+ info.si_code |= __SI_CHLD;
+ return copy_siginfo_to_user32(uinfo, &info);
+}
+
+static int signal32_init(void)
+{
+ if (cpu_has_fpu) {
+ save_fp_context32 = _save_fp_context32;
+ restore_fp_context32 = _restore_fp_context32;
+ } else {
+ save_fp_context32 = fpu_emulator_save_context32;
+ restore_fp_context32 = fpu_emulator_restore_context32;
+ }
+
+ return 0;
+}
+
+arch_initcall(signal32_init);
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
new file mode 100644
index 00000000..ee24d814
--- /dev/null
+++ b/arch/mips/kernel/signal_n32.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/cache.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/compat.h>
+#include <linux/bitops.h>
+
+#include <asm/abi.h>
+#include <asm/asm.h>
+#include <asm/cacheflush.h>
+#include <asm/compat-signal.h>
+#include <asm/sim.h>
+#include <asm/uaccess.h>
+#include <asm/ucontext.h>
+#include <asm/system.h>
+#include <asm/fpu.h>
+#include <asm/cpu-features.h>
+#include <asm/war.h>
+#include <asm/vdso.h>
+
+#include "signal-common.h"
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_N32_restart_syscall 6214
+
+extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
+extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
+
+
+/* IRIX compatible stack_t */
+typedef struct sigaltstack32 {
+ s32 ss_sp;
+ compat_size_t ss_size;
+ int ss_flags;
+} stack32_t;
+
+struct ucontextn32 {
+ u32 uc_flags;
+ s32 uc_link;
+ stack32_t uc_stack;
+ struct sigcontext uc_mcontext;
+ compat_sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+struct rt_sigframe_n32 {
+ u32 rs_ass[4]; /* argument save space for o32 */
+ u32 rs_pad[2]; /* Was: signal trampoline */
+ struct compat_siginfo rs_info;
+ struct ucontextn32 rs_uc;
+};
+
+extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
+
+asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
+{
+ compat_sigset_t __user *unewset;
+ compat_sigset_t uset;
+ size_t sigsetsize;
+ sigset_t newset;
+
+ /* XXX Don't preclude handling different sized sigset_t's. */
+ sigsetsize = regs.regs[5];
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ unewset = (compat_sigset_t __user *) regs.regs[4];
+ if (copy_from_user(&uset, unewset, sizeof(uset)))
+ return -EFAULT;
+ sigset_from_compat(&newset, &uset);
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ current->saved_sigmask = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_thread_flag(TIF_RESTORE_SIGMASK);
+ return -ERESTARTNOHAND;
+}
+
+asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+{
+ struct rt_sigframe_n32 __user *frame;
+ mm_segment_t old_fs;
+ sigset_t set;
+ stack_t st;
+ s32 sp;
+ int sig;
+
+ frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
+ if (sig < 0)
+ goto badframe;
+ else if (sig)
+ force_sig(sig, current);
+
+ /* The ucontext contains a stack32_t, so we must convert! */
+ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
+ goto badframe;
+ st.ss_sp = (void __user *)(long) sp;
+ if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
+ goto badframe;
+ if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
+ goto badframe;
+
+ /* It is more difficult to avoid calling this function than to
+ call it and ignore errors. */
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
+ set_fs(old_fs);
+
+
+ /*
+ * Don't let your children do this ...
+ */
+ __asm__ __volatile__(
+ "move\t$29, %0\n\t"
+ "j\tsyscall_exit"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
+
+badframe:
+ force_sig(SIGSEGV, current);
+}
+
+static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
+ struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
+{
+ struct rt_sigframe_n32 __user *frame;
+ int err = 0;
+ s32 sp;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ goto give_sigsegv;
+
+ /* Create siginfo. */
+ err |= copy_siginfo_to_user32(&frame->rs_info, info);
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->rs_uc.uc_flags);
+ err |= __put_user(0, &frame->rs_uc.uc_link);
+ sp = (int) (long) current->sas_ss_sp;
+ err |= __put_user(sp,
+ &frame->rs_uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->regs[29]),
+ &frame->rs_uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size,
+ &frame->rs_uc.uc_stack.ss_size);
+ err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+ err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
+
+ if (err)
+ goto give_sigsegv;
+
+ /*
+ * Arguments to signal handler:
+ *
+ * a0 = signal number
+ * a1 = 0 (should be cause)
+ * a2 = pointer to ucontext
+ *
+ * $25 and c0_epc point to the signal handler, $29 points to
+ * the struct rt_sigframe.
+ */
+ regs->regs[ 4] = signr;
+ regs->regs[ 5] = (unsigned long) &frame->rs_info;
+ regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+ regs->regs[29] = (unsigned long) frame;
+ regs->regs[31] = (unsigned long) sig_return;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+ DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
+ current->comm, current->pid,
+ frame, regs->cp0_epc, regs->regs[31]);
+
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(signr, current);
+ return -EFAULT;
+}
+
+struct mips_abi mips_abi_n32 = {
+ .setup_rt_frame = setup_rt_frame_n32,
+ .rt_signal_return_offset =
+ offsetof(struct mips_vdso, n32_rt_signal_trampoline),
+ .restart = __NR_N32_restart_syscall
+};
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
new file mode 100644
index 00000000..cc81771b
--- /dev/null
+++ b/arch/mips/kernel/smp-cmp.c
@@ -0,0 +1,210 @@
+/*
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * Chris Dearman (chris@mips.com)
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/smp.h>
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/mips_mt.h>
+#include <asm/amon.h>
+#include <asm/gic.h>
+
+static void ipi_call_function(unsigned int cpu)
+{
+ pr_debug("CPU%d: %s cpu %d status %08x\n",
+ smp_processor_id(), __func__, cpu, read_c0_status());
+
+ gic_send_ipi(plat_ipi_call_int_xlate(cpu));
+}
+
+
+static void ipi_resched(unsigned int cpu)
+{
+ pr_debug("CPU%d: %s cpu %d status %08x\n",
+ smp_processor_id(), __func__, cpu, read_c0_status());
+
+ gic_send_ipi(plat_ipi_resched_int_xlate(cpu));
+}
+
+/*
+ * FIXME: This isn't restricted to CMP
+ * The SMVP kernel could use GIC interrupts if available
+ */
+void cmp_send_ipi_single(int cpu, unsigned int action)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (action) {
+ case SMP_CALL_FUNCTION:
+ ipi_call_function(cpu);
+ break;
+
+ case SMP_RESCHEDULE_YOURSELF:
+ ipi_resched(cpu);
+ break;
+ }
+
+ local_irq_restore(flags);
+}
+
+static void cmp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ cmp_send_ipi_single(i, action);
+}
+
+static void cmp_init_secondary(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ /* Assume GIC is present */
+ change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP6 |
+ STATUSF_IP7);
+
+ /* Enable per-cpu interrupts: platform specific */
+
+ c->core = (read_c0_ebase() >> 1) & 0xff;
+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
+ c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
+#endif
+#ifdef CONFIG_MIPS_MT_SMTC
+ c->tc_id = (read_c0_tcbind() >> TCBIND_CURTC_SHIFT) & TCBIND_CURTC;
+#endif
+}
+
+static void cmp_smp_finish(void)
+{
+ pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
+
+ /* CDFIXME: remove this? */
+ write_c0_compare(read_c0_count() + (8 * mips_hpt_frequency / HZ));
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+ /* If we have an FPU, enroll ourselves in the FPU-full mask */
+ if (cpu_has_fpu)
+ cpu_set(smp_processor_id(), mt_fpu_cpumask);
+#endif /* CONFIG_MIPS_MT_FPAFF */
+
+ local_irq_enable();
+}
+
+static void cmp_cpus_done(void)
+{
+ pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it running
+ * smp_bootstrap is the place to resume from
+ * __KSTK_TOS(idle) is apparently the stack pointer
+ * (unsigned long)idle->thread_info the gp
+ */
+static void cmp_boot_secondary(int cpu, struct task_struct *idle)
+{
+ struct thread_info *gp = task_thread_info(idle);
+ unsigned long sp = __KSTK_TOS(idle);
+ unsigned long pc = (unsigned long)&smp_bootstrap;
+ unsigned long a0 = 0;
+
+ pr_debug("SMPCMP: CPU%d: %s cpu %d\n", smp_processor_id(),
+ __func__, cpu);
+
+#if 0
+ /* Needed? */
+ flush_icache_range((unsigned long)gp,
+ (unsigned long)(gp + sizeof(struct thread_info)));
+#endif
+
+ amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0);
+}
+
+/*
+ * Common setup before any secondaries are started
+ */
+void __init cmp_smp_setup(void)
+{
+ int i;
+ int ncpu = 0;
+
+ pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+ /* If we have an FPU, enroll ourselves in the FPU-full mask */
+ if (cpu_has_fpu)
+ cpu_set(0, mt_fpu_cpumask);
+#endif /* CONFIG_MIPS_MT_FPAFF */
+
+ for (i = 1; i < NR_CPUS; i++) {
+ if (amon_cpu_avail(i)) {
+ set_cpu_possible(i, true);
+ __cpu_number_map[i] = ++ncpu;
+ __cpu_logical_map[ncpu] = i;
+ }
+ }
+
+ if (cpu_has_mipsmt) {
+ unsigned int nvpe, mvpconf0 = read_c0_mvpconf0();
+
+ nvpe = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
+ smp_num_siblings = nvpe;
+ }
+ pr_info("Detected %i available secondary CPU(s)\n", ncpu);
+}
+
+void __init cmp_prepare_cpus(unsigned int max_cpus)
+{
+ pr_debug("SMPCMP: CPU%d: %s max_cpus=%d\n",
+ smp_processor_id(), __func__, max_cpus);
+
+ /*
+ * FIXME: some of these options are per-system, some per-core and
+ * some per-cpu
+ */
+ mips_mt_set_cpuoptions();
+}
+
+struct plat_smp_ops cmp_smp_ops = {
+ .send_ipi_single = cmp_send_ipi_single,
+ .send_ipi_mask = cmp_send_ipi_mask,
+ .init_secondary = cmp_init_secondary,
+ .smp_finish = cmp_smp_finish,
+ .cpus_done = cmp_cpus_done,
+ .boot_secondary = cmp_boot_secondary,
+ .smp_setup = cmp_smp_setup,
+ .prepare_cpus = cmp_prepare_cpus,
+};
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
new file mode 100644
index 00000000..1ec56e63
--- /dev/null
+++ b/arch/mips/kernel/smp-mt.c
@@ -0,0 +1,287 @@
+/*
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Copyright (C) 2004, 05, 06 MIPS Technologies, Inc.
+ * Elizabeth Clarke (beth@mips.com)
+ * Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+#include <linux/smp.h>
+
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/mips_mt.h>
+
+static void __init smvp_copy_vpe_config(void)
+{
+ write_vpe_c0_status(
+ (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
+
+ /* set config to be the same as vpe0, particularly kseg0 coherency alg */
+ write_vpe_c0_config( read_c0_config());
+
+ /* make sure there are no software interrupts pending */
+ write_vpe_c0_cause(0);
+
+ /* Propagate Config7 */
+ write_vpe_c0_config7(read_c0_config7());
+
+ write_vpe_c0_count(read_c0_count());
+}
+
+static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
+ unsigned int ncpu)
+{
+ if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT))
+ return ncpu;
+
+ /* Deactivate all but VPE 0 */
+ if (tc != 0) {
+ unsigned long tmp = read_vpe_c0_vpeconf0();
+
+ tmp &= ~VPECONF0_VPA;
+
+ /* master VPE */
+ tmp |= VPECONF0_MVP;
+ write_vpe_c0_vpeconf0(tmp);
+
+ /* Record this as available CPU */
+ set_cpu_possible(tc, true);
+ __cpu_number_map[tc] = ++ncpu;
+ __cpu_logical_map[ncpu] = tc;
+ }
+
+ /* Disable multi-threading with TC's */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+ if (tc != 0)
+ smvp_copy_vpe_config();
+
+ return ncpu;
+}
+
+static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
+{
+ unsigned long tmp;
+
+ if (!tc)
+ return;
+
+ /* bind a TC to each VPE, May as well put all excess TC's
+ on the last VPE */
+ if (tc >= (((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1))
+ write_tc_c0_tcbind(read_tc_c0_tcbind() | ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT));
+ else {
+ write_tc_c0_tcbind(read_tc_c0_tcbind() | tc);
+
+ /* and set XTC */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (tc << VPECONF0_XTC_SHIFT));
+ }
+
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not allocated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+
+ write_tc_c0_tchalt(TCHALT_H);
+}
+
+static void vsmp_send_ipi_single(int cpu, unsigned int action)
+{
+ int i;
+ unsigned long flags;
+ int vpflags;
+
+ local_irq_save(flags);
+
+ vpflags = dvpe(); /* can't access the other CPU's registers whilst MVPE enabled */
+
+ switch (action) {
+ case SMP_CALL_FUNCTION:
+ i = C_SW1;
+ break;
+
+ case SMP_RESCHEDULE_YOURSELF:
+ default:
+ i = C_SW0;
+ break;
+ }
+
+ /* 1:1 mapping of vpe and tc... */
+ settc(cpu);
+ write_vpe_c0_cause(read_vpe_c0_cause() | i);
+ evpe(vpflags);
+
+ local_irq_restore(flags);
+}
+
+static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ vsmp_send_ipi_single(i, action);
+}
+
+static void __cpuinit vsmp_init_secondary(void)
+{
+ extern int gic_present;
+
+ /* This is Malta specific: IPI,performance and timer interrupts */
+ if (gic_present)
+ change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
+ STATUSF_IP6 | STATUSF_IP7);
+ else
+ change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
+ STATUSF_IP6 | STATUSF_IP7);
+}
+
+static void __cpuinit vsmp_smp_finish(void)
+{
+ /* CDFIXME: remove this? */
+ write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+ /* If we have an FPU, enroll ourselves in the FPU-full mask */
+ if (cpu_has_fpu)
+ cpu_set(smp_processor_id(), mt_fpu_cpumask);
+#endif /* CONFIG_MIPS_MT_FPAFF */
+
+ local_irq_enable();
+}
+
+static void vsmp_cpus_done(void)
+{
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ * smp_bootstrap is the place to resume from
+ * __KSTK_TOS(idle) is apparently the stack pointer
+ * (unsigned long)idle->thread_info the gp
+ * assumes a 1:1 mapping of TC => VPE
+ */
+static void __cpuinit vsmp_boot_secondary(int cpu, struct task_struct *idle)
+{
+ struct thread_info *gp = task_thread_info(idle);
+ dvpe();
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ settc(cpu);
+
+ /* restart */
+ write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
+
+ /* enable the tc this vpe/cpu will be running */
+ write_tc_c0_tcstatus((read_tc_c0_tcstatus() & ~TCSTATUS_IXMT) | TCSTATUS_A);
+
+ write_tc_c0_tchalt(0);
+
+ /* enable the VPE */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+
+ /* stack pointer */
+ write_tc_gpr_sp( __KSTK_TOS(idle));
+
+ /* global pointer */
+ write_tc_gpr_gp((unsigned long)gp);
+
+ flush_icache_range((unsigned long)gp,
+ (unsigned long)(gp + sizeof(struct thread_info)));
+
+ /* finally out of configuration and into chaos */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ evpe(EVPE_ENABLE);
+}
+
+/*
+ * Common setup before any secondaries are started
+ * Make sure all CPU's are in a sensible state before we boot any of the
+ * secondaries
+ */
+static void __init vsmp_smp_setup(void)
+{
+ unsigned int mvpconf0, ntc, tc, ncpu = 0;
+ unsigned int nvpe;
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+ /* If we have an FPU, enroll ourselves in the FPU-full mask */
+ if (cpu_has_fpu)
+ cpu_set(0, mt_fpu_cpumask);
+#endif /* CONFIG_MIPS_MT_FPAFF */
+ if (!cpu_has_mipsmt)
+ return;
+
+ /* disable MT so we can configure */
+ dvpe();
+ dmt();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ mvpconf0 = read_c0_mvpconf0();
+ ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT;
+
+ nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+ smp_num_siblings = nvpe;
+
+ /* we'll always have more TC's than VPE's, so loop setting everything
+ to a sensible state */
+ for (tc = 0; tc <= ntc; tc++) {
+ settc(tc);
+
+ smvp_tc_init(tc, mvpconf0);
+ ncpu = smvp_vpe_init(tc, mvpconf0, ncpu);
+ }
+
+ /* Release config state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* We'll wait until starting the secondaries before starting MVPE */
+
+ printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu);
+}
+
+static void __init vsmp_prepare_cpus(unsigned int max_cpus)
+{
+ mips_mt_set_cpuoptions();
+}
+
+struct plat_smp_ops vsmp_smp_ops = {
+ .send_ipi_single = vsmp_send_ipi_single,
+ .send_ipi_mask = vsmp_send_ipi_mask,
+ .init_secondary = vsmp_init_secondary,
+ .smp_finish = vsmp_smp_finish,
+ .cpus_done = vsmp_cpus_done,
+ .boot_secondary = vsmp_boot_secondary,
+ .smp_setup = vsmp_smp_setup,
+ .prepare_cpus = vsmp_prepare_cpus,
+};
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c
new file mode 100644
index 00000000..00500fea
--- /dev/null
+++ b/arch/mips/kernel/smp-up.c
@@ -0,0 +1,84 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006, 07 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Symmetric Uniprocessor (TM) Support
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+/*
+ * Send inter-processor interrupt
+ */
+static void up_send_ipi_single(int cpu, unsigned int action)
+{
+ panic(KERN_ERR "%s called", __func__);
+}
+
+static inline void up_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action)
+{
+ panic(KERN_ERR "%s called", __func__);
+}
+
+/*
+ * After we've done initial boot, this function is called to allow the
+ * board code to clean up state, if needed
+ */
+static void __cpuinit up_init_secondary(void)
+{
+}
+
+static void __cpuinit up_smp_finish(void)
+{
+}
+
+/* Hook for after all CPUs are online */
+static void up_cpus_done(void)
+{
+}
+
+/*
+ * Firmware CPU startup hook
+ */
+static void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle)
+{
+}
+
+static void __init up_smp_setup(void)
+{
+}
+
+static void __init up_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int up_cpu_disable(void)
+{
+ return -ENOSYS;
+}
+
+static void up_cpu_die(unsigned int cpu)
+{
+ BUG();
+}
+#endif
+
+struct plat_smp_ops up_smp_ops = {
+ .send_ipi_single = up_send_ipi_single,
+ .send_ipi_mask = up_send_ipi_mask,
+ .init_secondary = up_init_secondary,
+ .smp_finish = up_smp_finish,
+ .cpus_done = up_cpus_done,
+ .boot_secondary = up_boot_secondary,
+ .smp_setup = up_smp_setup,
+ .prepare_cpus = up_prepare_cpus,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = up_cpu_disable,
+ .cpu_die = up_cpu_die,
+#endif
+};
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
new file mode 100644
index 00000000..32a25610
--- /dev/null
+++ b/arch/mips/kernel/smp.c
@@ -0,0 +1,435 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2000, 2001 Kanoj Sarcar
+ * Copyright (C) 2000, 2001 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
+ * Copyright (C) 2000, 2001, 2003 Broadcom Corporation
+ */
+#include <linux/cache.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/threads.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/cpu.h>
+#include <linux/err.h>
+#include <linux/ftrace.h>
+
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/r4k-timer.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/time.h>
+
+#ifdef CONFIG_MIPS_MT_SMTC
+#include <asm/mipsmtregs.h>
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */
+
+int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
+EXPORT_SYMBOL(__cpu_number_map);
+
+int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
+EXPORT_SYMBOL(__cpu_logical_map);
+
+/* Number of TCs (or siblings in Intel speak) per CPU core */
+int smp_num_siblings = 1;
+EXPORT_SYMBOL(smp_num_siblings);
+
+/* representing the TCs (or siblings in Intel speak) of each logical CPU */
+cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(cpu_sibling_map);
+
+/* representing cpus for which sibling maps can be computed */
+static cpumask_t cpu_sibling_setup_map;
+
+static inline void set_cpu_sibling_map(int cpu)
+{
+ int i;
+
+ cpu_set(cpu, cpu_sibling_setup_map);
+
+ if (smp_num_siblings > 1) {
+ for_each_cpu_mask(i, cpu_sibling_setup_map) {
+ if (cpu_data[cpu].core == cpu_data[i].core) {
+ cpu_set(i, cpu_sibling_map[cpu]);
+ cpu_set(cpu, cpu_sibling_map[i]);
+ }
+ }
+ } else
+ cpu_set(cpu, cpu_sibling_map[cpu]);
+}
+
+struct plat_smp_ops *mp_ops;
+
+__cpuinit void register_smp_ops(struct plat_smp_ops *ops)
+{
+ if (mp_ops)
+ printk(KERN_WARNING "Overriding previously set SMP ops\n");
+
+ mp_ops = ops;
+}
+
+/*
+ * First C code run on the secondary CPUs after being started up by
+ * the master.
+ */
+asmlinkage __cpuinit void start_secondary(void)
+{
+ unsigned int cpu;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /* Only do cpu_probe for first TC of CPU */
+ if ((read_c0_tcbind() & TCBIND_CURTC) == 0)
+#endif /* CONFIG_MIPS_MT_SMTC */
+ cpu_probe();
+ cpu_report();
+ per_cpu_trap_init();
+ mips_clockevent_init();
+ mp_ops->init_secondary();
+
+ /*
+ * XXX parity protection should be folded in here when it's converted
+ * to an option instead of something based on .cputype
+ */
+
+ calibrate_delay();
+ preempt_disable();
+ cpu = smp_processor_id();
+ cpu_data[cpu].udelay_val = loops_per_jiffy;
+
+ notify_cpu_starting(cpu);
+
+ mp_ops->smp_finish();
+ set_cpu_sibling_map(cpu);
+
+ cpu_set(cpu, cpu_callin_map);
+
+ synchronise_count_slave();
+
+ cpu_idle();
+}
+
+/*
+ * Call into both interrupt handlers, as we share the IPI for them
+ */
+void __irq_entry smp_call_function_interrupt(void)
+{
+ irq_enter();
+ generic_smp_call_function_single_interrupt();
+ generic_smp_call_function_interrupt();
+ irq_exit();
+}
+
+static void stop_this_cpu(void *dummy)
+{
+ /*
+ * Remove this CPU:
+ */
+ cpu_clear(smp_processor_id(), cpu_online_map);
+ for (;;) {
+ if (cpu_wait)
+ (*cpu_wait)(); /* Wait if available. */
+ }
+}
+
+void smp_send_stop(void)
+{
+ smp_call_function(stop_this_cpu, NULL, 0);
+}
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+ mp_ops->cpus_done();
+ synchronise_count_master();
+}
+
+/* called from main before smp_init() */
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+ init_new_context(current, &init_mm);
+ current_thread_info()->cpu = 0;
+ mp_ops->prepare_cpus(max_cpus);
+ set_cpu_sibling_map(0);
+#ifndef CONFIG_HOTPLUG_CPU
+ init_cpu_present(&cpu_possible_map);
+#endif
+}
+
+/* preload SMP state for boot cpu */
+void __devinit smp_prepare_boot_cpu(void)
+{
+ set_cpu_possible(0, true);
+ set_cpu_online(0, true);
+ cpu_set(0, cpu_callin_map);
+}
+
+/*
+ * Called once for each "cpu_possible(cpu)". Needs to spin up the cpu
+ * and keep control until "cpu_online(cpu)" is set. Note: cpu is
+ * physical, not logical.
+ */
+static struct task_struct *cpu_idle_thread[NR_CPUS];
+
+struct create_idle {
+ struct work_struct work;
+ struct task_struct *idle;
+ struct completion done;
+ int cpu;
+};
+
+static void __cpuinit do_fork_idle(struct work_struct *work)
+{
+ struct create_idle *c_idle =
+ container_of(work, struct create_idle, work);
+
+ c_idle->idle = fork_idle(c_idle->cpu);
+ complete(&c_idle->done);
+}
+
+int __cpuinit __cpu_up(unsigned int cpu)
+{
+ struct task_struct *idle;
+
+ /*
+ * Processor goes to start_secondary(), sets online flag
+ * The following code is purely to make sure
+ * Linux can schedule processes on this slave.
+ */
+ if (!cpu_idle_thread[cpu]) {
+ /*
+ * Schedule work item to avoid forking user task
+ * Ported from arch/x86/kernel/smpboot.c
+ */
+ struct create_idle c_idle = {
+ .cpu = cpu,
+ .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+ };
+
+ INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
+ schedule_work(&c_idle.work);
+ wait_for_completion(&c_idle.done);
+ idle = cpu_idle_thread[cpu] = c_idle.idle;
+
+ if (IS_ERR(idle))
+ panic(KERN_ERR "Fork failed for CPU %d", cpu);
+ } else {
+ idle = cpu_idle_thread[cpu];
+ init_idle(idle, cpu);
+ }
+
+ mp_ops->boot_secondary(cpu, idle);
+
+ /*
+ * Trust is futile. We should really have timeouts ...
+ */
+ while (!cpu_isset(cpu, cpu_callin_map))
+ udelay(100);
+
+ cpu_set(cpu, cpu_online_map);
+
+ return 0;
+}
+
+/* Not really SMP stuff ... */
+int setup_profiling_timer(unsigned int multiplier)
+{
+ return 0;
+}
+
+static void flush_tlb_all_ipi(void *info)
+{
+ local_flush_tlb_all();
+}
+
+void flush_tlb_all(void)
+{
+ on_each_cpu(flush_tlb_all_ipi, NULL, 1);
+}
+
+static void flush_tlb_mm_ipi(void *mm)
+{
+ local_flush_tlb_mm((struct mm_struct *)mm);
+}
+
+/*
+ * Special Variant of smp_call_function for use by TLB functions:
+ *
+ * o No return value
+ * o collapses to normal function call on UP kernels
+ * o collapses to normal function call on systems with a single shared
+ * primary cache.
+ * o CONFIG_MIPS_MT_SMTC currently implies there is only one physical core.
+ */
+static inline void smp_on_other_tlbs(void (*func) (void *info), void *info)
+{
+#ifndef CONFIG_MIPS_MT_SMTC
+ smp_call_function(func, info, 1);
+#endif
+}
+
+static inline void smp_on_each_tlb(void (*func) (void *info), void *info)
+{
+ preempt_disable();
+
+ smp_on_other_tlbs(func, info);
+ func(info);
+
+ preempt_enable();
+}
+
+/*
+ * The following tlb flush calls are invoked when old translations are
+ * being torn down, or pte attributes are changing. For single threaded
+ * address spaces, a new context is obtained on the current cpu, and tlb
+ * context on other cpus are invalidated to force a new context allocation
+ * at switch_mm time, should the mm ever be used on other cpus. For
+ * multithreaded address spaces, intercpu interrupts have to be sent.
+ * Another case where intercpu interrupts are required is when the target
+ * mm might be active on another cpu (eg debuggers doing the flushes on
+ * behalf of debugees, kswapd stealing pages from another process etc).
+ * Kanoj 07/00.
+ */
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+ preempt_disable();
+
+ if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
+ smp_on_other_tlbs(flush_tlb_mm_ipi, mm);
+ } else {
+ cpumask_t mask = cpu_online_map;
+ unsigned int cpu;
+
+ cpu_clear(smp_processor_id(), mask);
+ for_each_cpu_mask(cpu, mask)
+ if (cpu_context(cpu, mm))
+ cpu_context(cpu, mm) = 0;
+ }
+ local_flush_tlb_mm(mm);
+
+ preempt_enable();
+}
+
+struct flush_tlb_data {
+ struct vm_area_struct *vma;
+ unsigned long addr1;
+ unsigned long addr2;
+};
+
+static void flush_tlb_range_ipi(void *info)
+{
+ struct flush_tlb_data *fd = info;
+
+ local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+ struct mm_struct *mm = vma->vm_mm;
+
+ preempt_disable();
+ if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
+ struct flush_tlb_data fd = {
+ .vma = vma,
+ .addr1 = start,
+ .addr2 = end,
+ };
+
+ smp_on_other_tlbs(flush_tlb_range_ipi, &fd);
+ } else {
+ cpumask_t mask = cpu_online_map;
+ unsigned int cpu;
+
+ cpu_clear(smp_processor_id(), mask);
+ for_each_cpu_mask(cpu, mask)
+ if (cpu_context(cpu, mm))
+ cpu_context(cpu, mm) = 0;
+ }
+ local_flush_tlb_range(vma, start, end);
+ preempt_enable();
+}
+
+static void flush_tlb_kernel_range_ipi(void *info)
+{
+ struct flush_tlb_data *fd = info;
+
+ local_flush_tlb_kernel_range(fd->addr1, fd->addr2);
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ struct flush_tlb_data fd = {
+ .addr1 = start,
+ .addr2 = end,
+ };
+
+ on_each_cpu(flush_tlb_kernel_range_ipi, &fd, 1);
+}
+
+static void flush_tlb_page_ipi(void *info)
+{
+ struct flush_tlb_data *fd = info;
+
+ local_flush_tlb_page(fd->vma, fd->addr1);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+ preempt_disable();
+ if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) {
+ struct flush_tlb_data fd = {
+ .vma = vma,
+ .addr1 = page,
+ };
+
+ smp_on_other_tlbs(flush_tlb_page_ipi, &fd);
+ } else {
+ cpumask_t mask = cpu_online_map;
+ unsigned int cpu;
+
+ cpu_clear(smp_processor_id(), mask);
+ for_each_cpu_mask(cpu, mask)
+ if (cpu_context(cpu, vma->vm_mm))
+ cpu_context(cpu, vma->vm_mm) = 0;
+ }
+ local_flush_tlb_page(vma, page);
+ preempt_enable();
+}
+
+static void flush_tlb_one_ipi(void *info)
+{
+ unsigned long vaddr = (unsigned long) info;
+
+ local_flush_tlb_one(vaddr);
+}
+
+void flush_tlb_one(unsigned long vaddr)
+{
+ smp_on_each_tlb(flush_tlb_one_ipi, (void *) vaddr);
+}
+
+EXPORT_SYMBOL(flush_tlb_page);
+EXPORT_SYMBOL(flush_tlb_one);
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S
new file mode 100644
index 00000000..20938a4c
--- /dev/null
+++ b/arch/mips/kernel/smtc-asm.S
@@ -0,0 +1,130 @@
+/*
+ * Assembly Language Functions for MIPS MT SMTC support
+ */
+
+/*
+ * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. */
+
+#include <asm/regdef.h>
+#include <asm/asmmacro.h>
+#include <asm/stackframe.h>
+#include <asm/irqflags.h>
+
+/*
+ * "Software Interrupt" linkage.
+ *
+ * This is invoked when an "Interrupt" is sent from one TC to another,
+ * where the TC to be interrupted is halted, has it's Restart address
+ * and Status values saved by the "remote control" thread, then modified
+ * to cause execution to begin here, in kenel mode. This code then
+ * disguises the TC state as that of an exception and transfers
+ * control to the general exception or vectored interrupt handler.
+ */
+ .set noreorder
+
+/*
+The __smtc_ipi_vector would use k0 and k1 as temporaries and
+1) Set EXL (this is per-VPE, so this can't be done by proxy!)
+2) Restore the K/CU and IXMT bits to the pre "exception" state
+ (EXL means no interrupts and access to the kernel map).
+3) Set EPC to be the saved value of TCRestart.
+4) Jump to the exception handler entry point passed by the sender.
+
+CAN WE PROVE THAT WE WON'T DO THIS IF INTS DISABLED??
+*/
+
+/*
+ * Reviled and slandered vision: Set EXL and restore K/CU/IXMT
+ * state of pre-halt thread, then save everything and call
+ * thought some function pointer to imaginary_exception, which
+ * will parse a register value or memory message queue to
+ * deliver things like interprocessor interrupts. On return
+ * from that function, jump to the global ret_from_irq code
+ * to invoke the scheduler and return as appropriate.
+ */
+
+#define PT_PADSLOT4 (PT_R0-8)
+#define PT_PADSLOT5 (PT_R0-4)
+
+ .text
+ .align 5
+FEXPORT(__smtc_ipi_vector)
+ .set noat
+ /* Disable thread scheduling to make Status update atomic */
+ DMT 27 # dmt k1
+ _ehb
+ /* Set EXL */
+ mfc0 k0,CP0_STATUS
+ ori k0,k0,ST0_EXL
+ mtc0 k0,CP0_STATUS
+ _ehb
+ /* Thread scheduling now inhibited by EXL. Restore TE state. */
+ andi k1,k1,VPECONTROL_TE
+ beqz k1,1f
+ emt
+1:
+ /*
+ * The IPI sender has put some information on the anticipated
+ * kernel stack frame. If we were in user mode, this will be
+ * built above the saved kernel SP. If we were already in the
+ * kernel, it will be built above the current CPU SP.
+ *
+ * Were we in kernel mode, as indicated by CU0?
+ */
+ sll k1,k0,3
+ .set noreorder
+ bltz k1,2f
+ move k1,sp
+ .set reorder
+ /*
+ * If previously in user mode, set CU0 and use kernel stack.
+ */
+ li k1,ST0_CU0
+ or k1,k1,k0
+ mtc0 k1,CP0_STATUS
+ _ehb
+ get_saved_sp
+ /* Interrupting TC will have pre-set values in slots in the new frame */
+2: subu k1,k1,PT_SIZE
+ /* Load TCStatus Value */
+ lw k0,PT_TCSTATUS(k1)
+ /* Write it to TCStatus to restore CU/KSU/IXMT state */
+ mtc0 k0,$2,1
+ _ehb
+ lw k0,PT_EPC(k1)
+ mtc0 k0,CP0_EPC
+ /* Save all will redundantly recompute the SP, but use it for now */
+ SAVE_ALL
+ CLI
+ TRACE_IRQS_OFF
+ /* Function to be invoked passed stack pad slot 5 */
+ lw t0,PT_PADSLOT5(sp)
+ /* Argument from sender passed in stack pad slot 4 */
+ lw a0,PT_PADSLOT4(sp)
+ LONG_L s0, TI_REGS($28)
+ LONG_S sp, TI_REGS($28)
+ PTR_LA ra, ret_from_irq
+ jr t0
+
+/*
+ * Called from idle loop to provoke processing of queued IPIs
+ * First IPI message in queue passed as argument.
+ */
+
+LEAF(self_ipi)
+ /* Before anything else, block interrupts */
+ mfc0 t0,CP0_TCSTATUS
+ ori t1,t0,TCSTATUS_IXMT
+ mtc0 t1,CP0_TCSTATUS
+ _ehb
+ /* We know we're in kernel mode, so prepare stack frame */
+ subu t1,sp,PT_SIZE
+ sw ra,PT_EPC(t1)
+ sw a0,PT_PADSLOT4(t1)
+ la t2,ipi_decode
+ sw t2,PT_PADSLOT5(t1)
+ /* Save pre-disable value of TCStatus */
+ sw t0,PT_TCSTATUS(t1)
+ j __smtc_ipi_vector
+ nop
+END(self_ipi)
diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c
new file mode 100644
index 00000000..fe256559
--- /dev/null
+++ b/arch/mips/kernel/smtc-proc.c
@@ -0,0 +1,92 @@
+/*
+ * /proc hooks for SMTC kernel
+ * Copyright (C) 2005 Mips Technologies, Inc
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/mipsregs.h>
+#include <asm/cacheflush.h>
+#include <linux/proc_fs.h>
+
+#include <asm/smtc_proc.h>
+
+/*
+ * /proc diagnostic and statistics hooks
+ */
+
+/*
+ * Statistics gathered
+ */
+unsigned long selfipis[NR_CPUS];
+
+struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
+
+static struct proc_dir_entry *smtc_stats;
+
+atomic_t smtc_fpu_recoveries;
+
+static int proc_read_smtc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int totalen = 0;
+ int len;
+ int i;
+ extern unsigned long ebase;
+
+ len = sprintf(page, "SMTC Status Word: 0x%08x\n", smtc_status);
+ totalen += len;
+ page += len;
+ len = sprintf(page, "Config7: 0x%08x\n", read_c0_config7());
+ totalen += len;
+ page += len;
+ len = sprintf(page, "EBASE: 0x%08lx\n", ebase);
+ totalen += len;
+ page += len;
+ len = sprintf(page, "Counter Interrupts taken per CPU (TC)\n");
+ totalen += len;
+ page += len;
+ for (i=0; i < NR_CPUS; i++) {
+ len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].timerints);
+ totalen += len;
+ page += len;
+ }
+ len = sprintf(page, "Self-IPIs by CPU:\n");
+ totalen += len;
+ page += len;
+ for(i = 0; i < NR_CPUS; i++) {
+ len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
+ totalen += len;
+ page += len;
+ }
+ len = sprintf(page, "%d Recoveries of \"stolen\" FPU\n",
+ atomic_read(&smtc_fpu_recoveries));
+ totalen += len;
+ page += len;
+
+ return totalen;
+}
+
+void init_smtc_stats(void)
+{
+ int i;
+
+ for (i=0; i<NR_CPUS; i++) {
+ smtc_cpu_stats[i].timerints = 0;
+ smtc_cpu_stats[i].selfipis = 0;
+ }
+
+ atomic_set(&smtc_fpu_recoveries, 0);
+
+ smtc_stats = create_proc_read_entry("smtc", 0444, NULL,
+ proc_read_smtc, NULL);
+}
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
new file mode 100644
index 00000000..cedac463
--- /dev/null
+++ b/arch/mips/kernel/smtc.c
@@ -0,0 +1,1468 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2004 Mips Technologies, Inc
+ * Copyright (C) 2008 Kevin D. Kissell
+ */
+
+#include <linux/clockchips.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/ftrace.h>
+#include <linux/slab.h>
+
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <asm/hardirq.h>
+#include <asm/hazards.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/mipsregs.h>
+#include <asm/cacheflush.h>
+#include <asm/time.h>
+#include <asm/addrspace.h>
+#include <asm/smtc.h>
+#include <asm/smtc_proc.h>
+
+/*
+ * SMTC Kernel needs to manipulate low-level CPU interrupt mask
+ * in do_IRQ. These are passed in setup_irq_smtc() and stored
+ * in this table.
+ */
+unsigned long irq_hwmask[NR_IRQS];
+
+#define LOCK_MT_PRA() \
+ local_irq_save(flags); \
+ mtflags = dmt()
+
+#define UNLOCK_MT_PRA() \
+ emt(mtflags); \
+ local_irq_restore(flags)
+
+#define LOCK_CORE_PRA() \
+ local_irq_save(flags); \
+ mtflags = dvpe()
+
+#define UNLOCK_CORE_PRA() \
+ evpe(mtflags); \
+ local_irq_restore(flags)
+
+/*
+ * Data structures purely associated with SMTC parallelism
+ */
+
+
+/*
+ * Table for tracking ASIDs whose lifetime is prolonged.
+ */
+
+asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
+
+/*
+ * Number of InterProcessor Interrupt (IPI) message buffers to allocate
+ */
+
+#define IPIBUF_PER_CPU 4
+
+struct smtc_ipi_q IPIQ[NR_CPUS];
+static struct smtc_ipi_q freeIPIq;
+
+
+/* Forward declarations */
+
+void ipi_decode(struct smtc_ipi *);
+static void post_direct_ipi(int cpu, struct smtc_ipi *pipi);
+static void setup_cross_vpe_interrupts(unsigned int nvpe);
+void init_smtc_stats(void);
+
+/* Global SMTC Status */
+
+unsigned int smtc_status;
+
+/* Boot command line configuration overrides */
+
+static int vpe0limit;
+static int ipibuffers;
+static int nostlb;
+static int asidmask;
+unsigned long smtc_asid_mask = 0xff;
+
+static int __init vpe0tcs(char *str)
+{
+ get_option(&str, &vpe0limit);
+
+ return 1;
+}
+
+static int __init ipibufs(char *str)
+{
+ get_option(&str, &ipibuffers);
+ return 1;
+}
+
+static int __init stlb_disable(char *s)
+{
+ nostlb = 1;
+ return 1;
+}
+
+static int __init asidmask_set(char *str)
+{
+ get_option(&str, &asidmask);
+ switch (asidmask) {
+ case 0x1:
+ case 0x3:
+ case 0x7:
+ case 0xf:
+ case 0x1f:
+ case 0x3f:
+ case 0x7f:
+ case 0xff:
+ smtc_asid_mask = (unsigned long)asidmask;
+ break;
+ default:
+ printk("ILLEGAL ASID mask 0x%x from command line\n", asidmask);
+ }
+ return 1;
+}
+
+__setup("vpe0tcs=", vpe0tcs);
+__setup("ipibufs=", ipibufs);
+__setup("nostlb", stlb_disable);
+__setup("asidmask=", asidmask_set);
+
+#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
+
+static int hang_trig;
+
+static int __init hangtrig_enable(char *s)
+{
+ hang_trig = 1;
+ return 1;
+}
+
+
+__setup("hangtrig", hangtrig_enable);
+
+#define DEFAULT_BLOCKED_IPI_LIMIT 32
+
+static int timerq_limit = DEFAULT_BLOCKED_IPI_LIMIT;
+
+static int __init tintq(char *str)
+{
+ get_option(&str, &timerq_limit);
+ return 1;
+}
+
+__setup("tintq=", tintq);
+
+static int imstuckcount[2][8];
+/* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */
+static int vpemask[2][8] = {
+ {0, 0, 1, 0, 0, 0, 0, 1},
+ {0, 0, 0, 0, 0, 0, 0, 1}
+};
+int tcnoprog[NR_CPUS];
+static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
+static int clock_hang_reported[NR_CPUS];
+
+#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
+
+/*
+ * Configure shared TLB - VPC configuration bit must be set by caller
+ */
+
+static void smtc_configure_tlb(void)
+{
+ int i, tlbsiz, vpes;
+ unsigned long mvpconf0;
+ unsigned long config1val;
+
+ /* Set up ASID preservation table */
+ for (vpes=0; vpes<MAX_SMTC_TLBS; vpes++) {
+ for(i = 0; i < MAX_SMTC_ASIDS; i++) {
+ smtc_live_asid[vpes][i] = 0;
+ }
+ }
+ mvpconf0 = read_c0_mvpconf0();
+
+ if ((vpes = ((mvpconf0 & MVPCONF0_PVPE)
+ >> MVPCONF0_PVPE_SHIFT) + 1) > 1) {
+ /* If we have multiple VPEs, try to share the TLB */
+ if ((mvpconf0 & MVPCONF0_TLBS) && !nostlb) {
+ /*
+ * If TLB sizing is programmable, shared TLB
+ * size is the total available complement.
+ * Otherwise, we have to take the sum of all
+ * static VPE TLB entries.
+ */
+ if ((tlbsiz = ((mvpconf0 & MVPCONF0_PTLBE)
+ >> MVPCONF0_PTLBE_SHIFT)) == 0) {
+ /*
+ * If there's more than one VPE, there had better
+ * be more than one TC, because we need one to bind
+ * to each VPE in turn to be able to read
+ * its configuration state!
+ */
+ settc(1);
+ /* Stop the TC from doing anything foolish */
+ write_tc_c0_tchalt(TCHALT_H);
+ mips_ihb();
+ /* No need to un-Halt - that happens later anyway */
+ for (i=0; i < vpes; i++) {
+ write_tc_c0_tcbind(i);
+ /*
+ * To be 100% sure we're really getting the right
+ * information, we exit the configuration state
+ * and do an IHB after each rebinding.
+ */
+ write_c0_mvpcontrol(
+ read_c0_mvpcontrol() & ~ MVPCONTROL_VPC );
+ mips_ihb();
+ /*
+ * Only count if the MMU Type indicated is TLB
+ */
+ if (((read_vpe_c0_config() & MIPS_CONF_MT) >> 7) == 1) {
+ config1val = read_vpe_c0_config1();
+ tlbsiz += ((config1val >> 25) & 0x3f) + 1;
+ }
+
+ /* Put core back in configuration state */
+ write_c0_mvpcontrol(
+ read_c0_mvpcontrol() | MVPCONTROL_VPC );
+ mips_ihb();
+ }
+ }
+ write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB);
+ ehb();
+
+ /*
+ * Setup kernel data structures to use software total,
+ * rather than read the per-VPE Config1 value. The values
+ * for "CPU 0" gets copied to all the other CPUs as part
+ * of their initialization in smtc_cpu_setup().
+ */
+
+ /* MIPS32 limits TLB indices to 64 */
+ if (tlbsiz > 64)
+ tlbsiz = 64;
+ cpu_data[0].tlbsize = current_cpu_data.tlbsize = tlbsiz;
+ smtc_status |= SMTC_TLB_SHARED;
+ local_flush_tlb_all();
+
+ printk("TLB of %d entry pairs shared by %d VPEs\n",
+ tlbsiz, vpes);
+ } else {
+ printk("WARNING: TLB Not Sharable on SMTC Boot!\n");
+ }
+ }
+}
+
+
+/*
+ * Incrementally build the CPU map out of constituent MIPS MT cores,
+ * using the specified available VPEs and TCs. Plaform code needs
+ * to ensure that each MIPS MT core invokes this routine on reset,
+ * one at a time(!).
+ *
+ * This version of the build_cpu_map and prepare_cpus routines assumes
+ * that *all* TCs of a MIPS MT core will be used for Linux, and that
+ * they will be spread across *all* available VPEs (to minimise the
+ * loss of efficiency due to exception service serialization).
+ * An improved version would pick up configuration information and
+ * possibly leave some TCs/VPEs as "slave" processors.
+ *
+ * Use c0_MVPConf0 to find out how many TCs are available, setting up
+ * cpu_possible_map and the logical/physical mappings.
+ */
+
+int __init smtc_build_cpu_map(int start_cpu_slot)
+{
+ int i, ntcs;
+
+ /*
+ * The CPU map isn't actually used for anything at this point,
+ * so it's not clear what else we should do apart from set
+ * everything up so that "logical" = "physical".
+ */
+ ntcs = ((read_c0_mvpconf0() & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
+ for (i=start_cpu_slot; i<NR_CPUS && i<ntcs; i++) {
+ set_cpu_possible(i, true);
+ __cpu_number_map[i] = i;
+ __cpu_logical_map[i] = i;
+ }
+#ifdef CONFIG_MIPS_MT_FPAFF
+ /* Initialize map of CPUs with FPUs */
+ cpus_clear(mt_fpu_cpumask);
+#endif
+
+ /* One of those TC's is the one booting, and not a secondary... */
+ printk("%i available secondary CPU TC(s)\n", i - 1);
+
+ return i;
+}
+
+/*
+ * Common setup before any secondaries are started
+ * Make sure all CPU's are in a sensible state before we boot any of the
+ * secondaries.
+ *
+ * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly
+ * as possible across the available VPEs.
+ */
+
+static void smtc_tc_setup(int vpe, int tc, int cpu)
+{
+ settc(tc);
+ write_tc_c0_tchalt(TCHALT_H);
+ mips_ihb();
+ write_tc_c0_tcstatus((read_tc_c0_tcstatus()
+ & ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT))
+ | TCSTATUS_A);
+ /*
+ * TCContext gets an offset from the base of the IPIQ array
+ * to be used in low-level code to detect the presence of
+ * an active IPI queue
+ */
+ write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16);
+ /* Bind tc to vpe */
+ write_tc_c0_tcbind(vpe);
+ /* In general, all TCs should have the same cpu_data indications */
+ memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips));
+ /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */
+ if (cpu_data[0].cputype == CPU_34K ||
+ cpu_data[0].cputype == CPU_1004K)
+ cpu_data[cpu].options &= ~MIPS_CPU_FPU;
+ cpu_data[cpu].vpe_id = vpe;
+ cpu_data[cpu].tc_id = tc;
+ /* Multi-core SMTC hasn't been tested, but be prepared */
+ cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff;
+}
+
+/*
+ * Tweak to get Count registes in as close a sync as possible.
+ * Value seems good for 34K-class cores.
+ */
+
+#define CP0_SKEW 8
+
+void smtc_prepare_cpus(int cpus)
+{
+ int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu;
+ unsigned long flags;
+ unsigned long val;
+ int nipi;
+ struct smtc_ipi *pipi;
+
+ /* disable interrupts so we can disable MT */
+ local_irq_save(flags);
+ /* disable MT so we can configure */
+ dvpe();
+ dmt();
+
+ spin_lock_init(&freeIPIq.lock);
+
+ /*
+ * We probably don't have as many VPEs as we do SMP "CPUs",
+ * but it's possible - and in any case we'll never use more!
+ */
+ for (i=0; i<NR_CPUS; i++) {
+ IPIQ[i].head = IPIQ[i].tail = NULL;
+ spin_lock_init(&IPIQ[i].lock);
+ IPIQ[i].depth = 0;
+ IPIQ[i].resched_flag = 0; /* No reschedules queued initially */
+ }
+
+ /* cpu_data index starts at zero */
+ cpu = 0;
+ cpu_data[cpu].vpe_id = 0;
+ cpu_data[cpu].tc_id = 0;
+ cpu_data[cpu].core = (read_c0_ebase() >> 1) & 0xff;
+ cpu++;
+
+ /* Report on boot-time options */
+ mips_mt_set_cpuoptions();
+ if (vpelimit > 0)
+ printk("Limit of %d VPEs set\n", vpelimit);
+ if (tclimit > 0)
+ printk("Limit of %d TCs set\n", tclimit);
+ if (nostlb) {
+ printk("Shared TLB Use Inhibited - UNSAFE for Multi-VPE Operation\n");
+ }
+ if (asidmask)
+ printk("ASID mask value override to 0x%x\n", asidmask);
+
+ /* Temporary */
+#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
+ if (hang_trig)
+ printk("Logic Analyser Trigger on suspected TC hang\n");
+#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
+
+ /* Put MVPE's into 'configuration state' */
+ write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC );
+
+ val = read_c0_mvpconf0();
+ nvpe = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+ if (vpelimit > 0 && nvpe > vpelimit)
+ nvpe = vpelimit;
+ ntc = ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
+ if (ntc > NR_CPUS)
+ ntc = NR_CPUS;
+ if (tclimit > 0 && ntc > tclimit)
+ ntc = tclimit;
+ slop = ntc % nvpe;
+ for (i = 0; i < nvpe; i++) {
+ tcpervpe[i] = ntc / nvpe;
+ if (slop) {
+ if((slop - i) > 0) tcpervpe[i]++;
+ }
+ }
+ /* Handle command line override for VPE0 */
+ if (vpe0limit > ntc) vpe0limit = ntc;
+ if (vpe0limit > 0) {
+ int slopslop;
+ if (vpe0limit < tcpervpe[0]) {
+ /* Reducing TC count - distribute to others */
+ slop = tcpervpe[0] - vpe0limit;
+ slopslop = slop % (nvpe - 1);
+ tcpervpe[0] = vpe0limit;
+ for (i = 1; i < nvpe; i++) {
+ tcpervpe[i] += slop / (nvpe - 1);
+ if(slopslop && ((slopslop - (i - 1) > 0)))
+ tcpervpe[i]++;
+ }
+ } else if (vpe0limit > tcpervpe[0]) {
+ /* Increasing TC count - steal from others */
+ slop = vpe0limit - tcpervpe[0];
+ slopslop = slop % (nvpe - 1);
+ tcpervpe[0] = vpe0limit;
+ for (i = 1; i < nvpe; i++) {
+ tcpervpe[i] -= slop / (nvpe - 1);
+ if(slopslop && ((slopslop - (i - 1) > 0)))
+ tcpervpe[i]--;
+ }
+ }
+ }
+
+ /* Set up shared TLB */
+ smtc_configure_tlb();
+
+ for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) {
+ if (tcpervpe[vpe] == 0)
+ continue;
+ if (vpe != 0)
+ printk(", ");
+ printk("VPE %d: TC", vpe);
+ for (i = 0; i < tcpervpe[vpe]; i++) {
+ /*
+ * TC 0 is bound to VPE 0 at reset,
+ * and is presumably executing this
+ * code. Leave it alone!
+ */
+ if (tc != 0) {
+ smtc_tc_setup(vpe, tc, cpu);
+ cpu++;
+ }
+ printk(" %d", tc);
+ tc++;
+ }
+ if (vpe != 0) {
+ /*
+ * Allow this VPE to control others.
+ */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() |
+ VPECONF0_MVP);
+
+ /*
+ * Clear any stale software interrupts from VPE's Cause
+ */
+ write_vpe_c0_cause(0);
+
+ /*
+ * Clear ERL/EXL of VPEs other than 0
+ * and set restricted interrupt enable/mask.
+ */
+ write_vpe_c0_status((read_vpe_c0_status()
+ & ~(ST0_BEV | ST0_ERL | ST0_EXL | ST0_IM))
+ | (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7
+ | ST0_IE));
+ /*
+ * set config to be the same as vpe0,
+ * particularly kseg0 coherency alg
+ */
+ write_vpe_c0_config(read_c0_config());
+ /* Clear any pending timer interrupt */
+ write_vpe_c0_compare(0);
+ /* Propagate Config7 */
+ write_vpe_c0_config7(read_c0_config7());
+ write_vpe_c0_count(read_c0_count() + CP0_SKEW);
+ ehb();
+ }
+ /* enable multi-threading within VPE */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE);
+ /* enable the VPE */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+ }
+
+ /*
+ * Pull any physically present but unused TCs out of circulation.
+ */
+ while (tc < (((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1)) {
+ set_cpu_possible(tc, false);
+ set_cpu_present(tc, false);
+ tc++;
+ }
+
+ /* release config state */
+ write_c0_mvpcontrol( read_c0_mvpcontrol() & ~ MVPCONTROL_VPC );
+
+ printk("\n");
+
+ /* Set up coprocessor affinity CPU mask(s) */
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+ for (tc = 0; tc < ntc; tc++) {
+ if (cpu_data[tc].options & MIPS_CPU_FPU)
+ cpu_set(tc, mt_fpu_cpumask);
+ }
+#endif
+
+ /* set up ipi interrupts... */
+
+ /* If we have multiple VPEs running, set up the cross-VPE interrupt */
+
+ setup_cross_vpe_interrupts(nvpe);
+
+ /* Set up queue of free IPI "messages". */
+ nipi = NR_CPUS * IPIBUF_PER_CPU;
+ if (ipibuffers > 0)
+ nipi = ipibuffers;
+
+ pipi = kmalloc(nipi *sizeof(struct smtc_ipi), GFP_KERNEL);
+ if (pipi == NULL)
+ panic("kmalloc of IPI message buffers failed\n");
+ else
+ printk("IPI buffer pool of %d buffers\n", nipi);
+ for (i = 0; i < nipi; i++) {
+ smtc_ipi_nq(&freeIPIq, pipi);
+ pipi++;
+ }
+
+ /* Arm multithreading and enable other VPEs - but all TCs are Halted */
+ emt(EMT_ENABLE);
+ evpe(EVPE_ENABLE);
+ local_irq_restore(flags);
+ /* Initialize SMTC /proc statistics/diagnostics */
+ init_smtc_stats();
+}
+
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ * smp_bootstrap is the place to resume from
+ * __KSTK_TOS(idle) is apparently the stack pointer
+ * (unsigned long)idle->thread_info the gp
+ *
+ */
+void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle)
+{
+ extern u32 kernelsp[NR_CPUS];
+ unsigned long flags;
+ int mtflags;
+
+ LOCK_MT_PRA();
+ if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
+ dvpe();
+ }
+ settc(cpu_data[cpu].tc_id);
+
+ /* pc */
+ write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
+
+ /* stack pointer */
+ kernelsp[cpu] = __KSTK_TOS(idle);
+ write_tc_gpr_sp(__KSTK_TOS(idle));
+
+ /* global pointer */
+ write_tc_gpr_gp((unsigned long)task_thread_info(idle));
+
+ smtc_status |= SMTC_MTC_ACTIVE;
+ write_tc_c0_tchalt(0);
+ if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
+ evpe(EVPE_ENABLE);
+ }
+ UNLOCK_MT_PRA();
+}
+
+void smtc_init_secondary(void)
+{
+ local_irq_enable();
+}
+
+void smtc_smp_finish(void)
+{
+ int cpu = smp_processor_id();
+
+ /*
+ * Lowest-numbered CPU per VPE starts a clock tick.
+ * Like per_cpu_trap_init() hack, this assumes that
+ * SMTC init code assigns TCs consdecutively and
+ * in ascending order across available VPEs.
+ */
+ if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id))
+ write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
+
+ printk("TC %d going on-line as CPU %d\n",
+ cpu_data[smp_processor_id()].tc_id, smp_processor_id());
+}
+
+void smtc_cpus_done(void)
+{
+}
+
+/*
+ * Support for SMTC-optimized driver IRQ registration
+ */
+
+/*
+ * SMTC Kernel needs to manipulate low-level CPU interrupt mask
+ * in do_IRQ. These are passed in setup_irq_smtc() and stored
+ * in this table.
+ */
+
+int setup_irq_smtc(unsigned int irq, struct irqaction * new,
+ unsigned long hwmask)
+{
+#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
+ unsigned int vpe = current_cpu_data.vpe_id;
+
+ vpemask[vpe][irq - MIPS_CPU_IRQ_BASE] = 1;
+#endif
+ irq_hwmask[irq] = hwmask;
+
+ return setup_irq(irq, new);
+}
+
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+/*
+ * Support for IRQ affinity to TCs
+ */
+
+void smtc_set_irq_affinity(unsigned int irq, cpumask_t affinity)
+{
+ /*
+ * If a "fast path" cache of quickly decodable affinity state
+ * is maintained, this is where it gets done, on a call up
+ * from the platform affinity code.
+ */
+}
+
+void smtc_forward_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+ int target;
+
+ /*
+ * OK wise guy, now figure out how to get the IRQ
+ * to be serviced on an authorized "CPU".
+ *
+ * Ideally, to handle the situation where an IRQ has multiple
+ * eligible CPUS, we would maintain state per IRQ that would
+ * allow a fair distribution of service requests. Since the
+ * expected use model is any-or-only-one, for simplicity
+ * and efficiency, we just pick the easiest one to find.
+ */
+
+ target = cpumask_first(d->affinity);
+
+ /*
+ * We depend on the platform code to have correctly processed
+ * IRQ affinity change requests to ensure that the IRQ affinity
+ * mask has been purged of bits corresponding to nonexistent and
+ * offline "CPUs", and to TCs bound to VPEs other than the VPE
+ * connected to the physical interrupt input for the interrupt
+ * in question. Otherwise we have a nasty problem with interrupt
+ * mask management. This is best handled in non-performance-critical
+ * platform IRQ affinity setting code, to minimize interrupt-time
+ * checks.
+ */
+
+ /* If no one is eligible, service locally */
+ if (target >= NR_CPUS)
+ do_IRQ_no_affinity(irq);
+ else
+ smtc_send_ipi(target, IRQ_AFFINITY_IPI, irq);
+}
+
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
+
+/*
+ * IPI model for SMTC is tricky, because interrupts aren't TC-specific.
+ * Within a VPE one TC can interrupt another by different approaches.
+ * The easiest to get right would probably be to make all TCs except
+ * the target IXMT and set a software interrupt, but an IXMT-based
+ * scheme requires that a handler must run before a new IPI could
+ * be sent, which would break the "broadcast" loops in MIPS MT.
+ * A more gonzo approach within a VPE is to halt the TC, extract
+ * its Restart, Status, and a couple of GPRs, and program the Restart
+ * address to emulate an interrupt.
+ *
+ * Within a VPE, one can be confident that the target TC isn't in
+ * a critical EXL state when halted, since the write to the Halt
+ * register could not have issued on the writing thread if the
+ * halting thread had EXL set. So k0 and k1 of the target TC
+ * can be used by the injection code. Across VPEs, one can't
+ * be certain that the target TC isn't in a critical exception
+ * state. So we try a two-step process of sending a software
+ * interrupt to the target VPE, which either handles the event
+ * itself (if it was the target) or injects the event within
+ * the VPE.
+ */
+
+static void smtc_ipi_qdump(void)
+{
+ int i;
+ struct smtc_ipi *temp;
+
+ for (i = 0; i < NR_CPUS ;i++) {
+ pr_info("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
+ i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail,
+ IPIQ[i].depth);
+ temp = IPIQ[i].head;
+
+ while (temp != IPIQ[i].tail) {
+ pr_debug("%d %d %d: ", temp->type, temp->dest,
+ (int)temp->arg);
+#ifdef SMTC_IPI_DEBUG
+ pr_debug("%u %lu\n", temp->sender, temp->stamp);
+#else
+ pr_debug("\n");
+#endif
+ temp = temp->flink;
+ }
+ }
+}
+
+/*
+ * The standard atomic.h primitives don't quite do what we want
+ * here: We need an atomic add-and-return-previous-value (which
+ * could be done with atomic_add_return and a decrement) and an
+ * atomic set/zero-and-return-previous-value (which can't really
+ * be done with the atomic.h primitives). And since this is
+ * MIPS MT, we can assume that we have LL/SC.
+ */
+static inline int atomic_postincrement(atomic_t *v)
+{
+ unsigned long result;
+
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ "1: ll %0, %2 \n"
+ " addu %1, %0, 1 \n"
+ " sc %1, %2 \n"
+ " beqz %1, 1b \n"
+ __WEAK_LLSC_MB
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "m" (v->counter)
+ : "memory");
+
+ return result;
+}
+
+void smtc_send_ipi(int cpu, int type, unsigned int action)
+{
+ int tcstatus;
+ struct smtc_ipi *pipi;
+ unsigned long flags;
+ int mtflags;
+ unsigned long tcrestart;
+ extern void r4k_wait_irqoff(void), __pastwait(void);
+ int set_resched_flag = (type == LINUX_SMP_IPI &&
+ action == SMP_RESCHEDULE_YOURSELF);
+
+ if (cpu == smp_processor_id()) {
+ printk("Cannot Send IPI to self!\n");
+ return;
+ }
+ if (set_resched_flag && IPIQ[cpu].resched_flag != 0)
+ return; /* There is a reschedule queued already */
+
+ /* Set up a descriptor, to be delivered either promptly or queued */
+ pipi = smtc_ipi_dq(&freeIPIq);
+ if (pipi == NULL) {
+ bust_spinlocks(1);
+ mips_mt_regdump(dvpe());
+ panic("IPI Msg. Buffers Depleted\n");
+ }
+ pipi->type = type;
+ pipi->arg = (void *)action;
+ pipi->dest = cpu;
+ if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
+ /* If not on same VPE, enqueue and send cross-VPE interrupt */
+ IPIQ[cpu].resched_flag |= set_resched_flag;
+ smtc_ipi_nq(&IPIQ[cpu], pipi);
+ LOCK_CORE_PRA();
+ settc(cpu_data[cpu].tc_id);
+ write_vpe_c0_cause(read_vpe_c0_cause() | C_SW1);
+ UNLOCK_CORE_PRA();
+ } else {
+ /*
+ * Not sufficient to do a LOCK_MT_PRA (dmt) here,
+ * since ASID shootdown on the other VPE may
+ * collide with this operation.
+ */
+ LOCK_CORE_PRA();
+ settc(cpu_data[cpu].tc_id);
+ /* Halt the targeted TC */
+ write_tc_c0_tchalt(TCHALT_H);
+ mips_ihb();
+
+ /*
+ * Inspect TCStatus - if IXMT is set, we have to queue
+ * a message. Otherwise, we set up the "interrupt"
+ * of the other TC
+ */
+ tcstatus = read_tc_c0_tcstatus();
+
+ if ((tcstatus & TCSTATUS_IXMT) != 0) {
+ /*
+ * If we're in the the irq-off version of the wait
+ * loop, we need to force exit from the wait and
+ * do a direct post of the IPI.
+ */
+ if (cpu_wait == r4k_wait_irqoff) {
+ tcrestart = read_tc_c0_tcrestart();
+ if (tcrestart >= (unsigned long)r4k_wait_irqoff
+ && tcrestart < (unsigned long)__pastwait) {
+ write_tc_c0_tcrestart(__pastwait);
+ tcstatus &= ~TCSTATUS_IXMT;
+ write_tc_c0_tcstatus(tcstatus);
+ goto postdirect;
+ }
+ }
+ /*
+ * Otherwise we queue the message for the target TC
+ * to pick up when he does a local_irq_restore()
+ */
+ write_tc_c0_tchalt(0);
+ UNLOCK_CORE_PRA();
+ IPIQ[cpu].resched_flag |= set_resched_flag;
+ smtc_ipi_nq(&IPIQ[cpu], pipi);
+ } else {
+postdirect:
+ post_direct_ipi(cpu, pipi);
+ write_tc_c0_tchalt(0);
+ UNLOCK_CORE_PRA();
+ }
+ }
+}
+
+/*
+ * Send IPI message to Halted TC, TargTC/TargVPE already having been set
+ */
+static void post_direct_ipi(int cpu, struct smtc_ipi *pipi)
+{
+ struct pt_regs *kstack;
+ unsigned long tcstatus;
+ unsigned long tcrestart;
+ extern u32 kernelsp[NR_CPUS];
+ extern void __smtc_ipi_vector(void);
+//printk("%s: on %d for %d\n", __func__, smp_processor_id(), cpu);
+
+ /* Extract Status, EPC from halted TC */
+ tcstatus = read_tc_c0_tcstatus();
+ tcrestart = read_tc_c0_tcrestart();
+ /* If TCRestart indicates a WAIT instruction, advance the PC */
+ if ((tcrestart & 0x80000000)
+ && ((*(unsigned int *)tcrestart & 0xfe00003f) == 0x42000020)) {
+ tcrestart += 4;
+ }
+ /*
+ * Save on TC's future kernel stack
+ *
+ * CU bit of Status is indicator that TC was
+ * already running on a kernel stack...
+ */
+ if (tcstatus & ST0_CU0) {
+ /* Note that this "- 1" is pointer arithmetic */
+ kstack = ((struct pt_regs *)read_tc_gpr_sp()) - 1;
+ } else {
+ kstack = ((struct pt_regs *)kernelsp[cpu]) - 1;
+ }
+
+ kstack->cp0_epc = (long)tcrestart;
+ /* Save TCStatus */
+ kstack->cp0_tcstatus = tcstatus;
+ /* Pass token of operation to be performed kernel stack pad area */
+ kstack->pad0[4] = (unsigned long)pipi;
+ /* Pass address of function to be called likewise */
+ kstack->pad0[5] = (unsigned long)&ipi_decode;
+ /* Set interrupt exempt and kernel mode */
+ tcstatus |= TCSTATUS_IXMT;
+ tcstatus &= ~TCSTATUS_TKSU;
+ write_tc_c0_tcstatus(tcstatus);
+ ehb();
+ /* Set TC Restart address to be SMTC IPI vector */
+ write_tc_c0_tcrestart(__smtc_ipi_vector);
+}
+
+static void ipi_resched_interrupt(void)
+{
+ scheduler_ipi();
+}
+
+static void ipi_call_interrupt(void)
+{
+ /* Invoke generic function invocation code in smp.c */
+ smp_call_function_interrupt();
+}
+
+DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+
+static void __irq_entry smtc_clock_tick_interrupt(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
+ int irq = MIPS_CPU_IRQ_BASE + 1;
+
+ irq_enter();
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+ cd = &per_cpu(mips_clockevent_device, cpu);
+ cd->event_handler(cd);
+ irq_exit();
+}
+
+void ipi_decode(struct smtc_ipi *pipi)
+{
+ void *arg_copy = pipi->arg;
+ int type_copy = pipi->type;
+
+ smtc_ipi_nq(&freeIPIq, pipi);
+
+ switch (type_copy) {
+ case SMTC_CLOCK_TICK:
+ smtc_clock_tick_interrupt();
+ break;
+
+ case LINUX_SMP_IPI:
+ switch ((int)arg_copy) {
+ case SMP_RESCHEDULE_YOURSELF:
+ ipi_resched_interrupt();
+ break;
+ case SMP_CALL_FUNCTION:
+ ipi_call_interrupt();
+ break;
+ default:
+ printk("Impossible SMTC IPI Argument %p\n", arg_copy);
+ break;
+ }
+ break;
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+ case IRQ_AFFINITY_IPI:
+ /*
+ * Accept a "forwarded" interrupt that was initially
+ * taken by a TC who doesn't have affinity for the IRQ.
+ */
+ do_IRQ_no_affinity((int)arg_copy);
+ break;
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
+ default:
+ printk("Impossible SMTC IPI Type 0x%x\n", type_copy);
+ break;
+ }
+}
+
+/*
+ * Similar to smtc_ipi_replay(), but invoked from context restore,
+ * so it reuses the current exception frame rather than set up a
+ * new one with self_ipi.
+ */
+
+void deferred_smtc_ipi(void)
+{
+ int cpu = smp_processor_id();
+
+ /*
+ * Test is not atomic, but much faster than a dequeue,
+ * and the vast majority of invocations will have a null queue.
+ * If irq_disabled when this was called, then any IPIs queued
+ * after we test last will be taken on the next irq_enable/restore.
+ * If interrupts were enabled, then any IPIs added after the
+ * last test will be taken directly.
+ */
+
+ while (IPIQ[cpu].head != NULL) {
+ struct smtc_ipi_q *q = &IPIQ[cpu];
+ struct smtc_ipi *pipi;
+ unsigned long flags;
+
+ /*
+ * It may be possible we'll come in with interrupts
+ * already enabled.
+ */
+ local_irq_save(flags);
+ spin_lock(&q->lock);
+ pipi = __smtc_ipi_dq(q);
+ spin_unlock(&q->lock);
+ if (pipi != NULL) {
+ if (pipi->type == LINUX_SMP_IPI &&
+ (int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
+ IPIQ[cpu].resched_flag = 0;
+ ipi_decode(pipi);
+ }
+ /*
+ * The use of the __raw_local restore isn't
+ * as obviously necessary here as in smtc_ipi_replay(),
+ * but it's more efficient, given that we're already
+ * running down the IPI queue.
+ */
+ __arch_local_irq_restore(flags);
+ }
+}
+
+/*
+ * Cross-VPE interrupts in the SMTC prototype use "software interrupts"
+ * set via cross-VPE MTTR manipulation of the Cause register. It would be
+ * in some regards preferable to have external logic for "doorbell" hardware
+ * interrupts.
+ */
+
+static int cpu_ipi_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_IRQ;
+
+static irqreturn_t ipi_interrupt(int irq, void *dev_idm)
+{
+ int my_vpe = cpu_data[smp_processor_id()].vpe_id;
+ int my_tc = cpu_data[smp_processor_id()].tc_id;
+ int cpu;
+ struct smtc_ipi *pipi;
+ unsigned long tcstatus;
+ int sent;
+ unsigned long flags;
+ unsigned int mtflags;
+ unsigned int vpflags;
+
+ /*
+ * So long as cross-VPE interrupts are done via
+ * MFTR/MTTR read-modify-writes of Cause, we need
+ * to stop other VPEs whenever the local VPE does
+ * anything similar.
+ */
+ local_irq_save(flags);
+ vpflags = dvpe();
+ clear_c0_cause(0x100 << MIPS_CPU_IPI_IRQ);
+ set_c0_status(0x100 << MIPS_CPU_IPI_IRQ);
+ irq_enable_hazard();
+ evpe(vpflags);
+ local_irq_restore(flags);
+
+ /*
+ * Cross-VPE Interrupt handler: Try to directly deliver IPIs
+ * queued for TCs on this VPE other than the current one.
+ * Return-from-interrupt should cause us to drain the queue
+ * for the current TC, so we ought not to have to do it explicitly here.
+ */
+
+ for_each_online_cpu(cpu) {
+ if (cpu_data[cpu].vpe_id != my_vpe)
+ continue;
+
+ pipi = smtc_ipi_dq(&IPIQ[cpu]);
+ if (pipi != NULL) {
+ if (cpu_data[cpu].tc_id != my_tc) {
+ sent = 0;
+ LOCK_MT_PRA();
+ settc(cpu_data[cpu].tc_id);
+ write_tc_c0_tchalt(TCHALT_H);
+ mips_ihb();
+ tcstatus = read_tc_c0_tcstatus();
+ if ((tcstatus & TCSTATUS_IXMT) == 0) {
+ post_direct_ipi(cpu, pipi);
+ sent = 1;
+ }
+ write_tc_c0_tchalt(0);
+ UNLOCK_MT_PRA();
+ if (!sent) {
+ smtc_ipi_req(&IPIQ[cpu], pipi);
+ }
+ } else {
+ /*
+ * ipi_decode() should be called
+ * with interrupts off
+ */
+ local_irq_save(flags);
+ if (pipi->type == LINUX_SMP_IPI &&
+ (int)pipi->arg == SMP_RESCHEDULE_YOURSELF)
+ IPIQ[cpu].resched_flag = 0;
+ ipi_decode(pipi);
+ local_irq_restore(flags);
+ }
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void ipi_irq_dispatch(void)
+{
+ do_IRQ(cpu_ipi_irq);
+}
+
+static struct irqaction irq_ipi = {
+ .handler = ipi_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .name = "SMTC_IPI"
+};
+
+static void setup_cross_vpe_interrupts(unsigned int nvpe)
+{
+ if (nvpe < 1)
+ return;
+
+ if (!cpu_has_vint)
+ panic("SMTC Kernel requires Vectored Interrupt support");
+
+ set_vi_handler(MIPS_CPU_IPI_IRQ, ipi_irq_dispatch);
+
+ setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ));
+
+ irq_set_handler(cpu_ipi_irq, handle_percpu_irq);
+}
+
+/*
+ * SMTC-specific hacks invoked from elsewhere in the kernel.
+ */
+
+ /*
+ * smtc_ipi_replay is called from raw_local_irq_restore
+ */
+
+void smtc_ipi_replay(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ /*
+ * To the extent that we've ever turned interrupts off,
+ * we may have accumulated deferred IPIs. This is subtle.
+ * we should be OK: If we pick up something and dispatch
+ * it here, that's great. If we see nothing, but concurrent
+ * with this operation, another TC sends us an IPI, IXMT
+ * is clear, and we'll handle it as a real pseudo-interrupt
+ * and not a pseudo-pseudo interrupt. The important thing
+ * is to do the last check for queued message *after* the
+ * re-enabling of interrupts.
+ */
+ while (IPIQ[cpu].head != NULL) {
+ struct smtc_ipi_q *q = &IPIQ[cpu];
+ struct smtc_ipi *pipi;
+ unsigned long flags;
+
+ /*
+ * It's just possible we'll come in with interrupts
+ * already enabled.
+ */
+ local_irq_save(flags);
+
+ spin_lock(&q->lock);
+ pipi = __smtc_ipi_dq(q);
+ spin_unlock(&q->lock);
+ /*
+ ** But use a raw restore here to avoid recursion.
+ */
+ __arch_local_irq_restore(flags);
+
+ if (pipi) {
+ self_ipi(pipi);
+ smtc_cpu_stats[cpu].selfipis++;
+ }
+ }
+}
+
+EXPORT_SYMBOL(smtc_ipi_replay);
+
+void smtc_idle_loop_hook(void)
+{
+#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
+ int im;
+ int flags;
+ int mtflags;
+ int bit;
+ int vpe;
+ int tc;
+ int hook_ntcs;
+ /*
+ * printk within DMT-protected regions can deadlock,
+ * so buffer diagnostic messages for later output.
+ */
+ char *pdb_msg;
+ char id_ho_db_msg[768]; /* worst-case use should be less than 700 */
+
+ if (atomic_read(&idle_hook_initialized) == 0) { /* fast test */
+ if (atomic_add_return(1, &idle_hook_initialized) == 1) {
+ int mvpconf0;
+ /* Tedious stuff to just do once */
+ mvpconf0 = read_c0_mvpconf0();
+ hook_ntcs = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
+ if (hook_ntcs > NR_CPUS)
+ hook_ntcs = NR_CPUS;
+ for (tc = 0; tc < hook_ntcs; tc++) {
+ tcnoprog[tc] = 0;
+ clock_hang_reported[tc] = 0;
+ }
+ for (vpe = 0; vpe < 2; vpe++)
+ for (im = 0; im < 8; im++)
+ imstuckcount[vpe][im] = 0;
+ printk("Idle loop test hook initialized for %d TCs\n", hook_ntcs);
+ atomic_set(&idle_hook_initialized, 1000);
+ } else {
+ /* Someone else is initializing in parallel - let 'em finish */
+ while (atomic_read(&idle_hook_initialized) < 1000)
+ ;
+ }
+ }
+
+ /* Have we stupidly left IXMT set somewhere? */
+ if (read_c0_tcstatus() & 0x400) {
+ write_c0_tcstatus(read_c0_tcstatus() & ~0x400);
+ ehb();
+ printk("Dangling IXMT in cpu_idle()\n");
+ }
+
+ /* Have we stupidly left an IM bit turned off? */
+#define IM_LIMIT 2000
+ local_irq_save(flags);
+ mtflags = dmt();
+ pdb_msg = &id_ho_db_msg[0];
+ im = read_c0_status();
+ vpe = current_cpu_data.vpe_id;
+ for (bit = 0; bit < 8; bit++) {
+ /*
+ * In current prototype, I/O interrupts
+ * are masked for VPE > 0
+ */
+ if (vpemask[vpe][bit]) {
+ if (!(im & (0x100 << bit)))
+ imstuckcount[vpe][bit]++;
+ else
+ imstuckcount[vpe][bit] = 0;
+ if (imstuckcount[vpe][bit] > IM_LIMIT) {
+ set_c0_status(0x100 << bit);
+ ehb();
+ imstuckcount[vpe][bit] = 0;
+ pdb_msg += sprintf(pdb_msg,
+ "Dangling IM %d fixed for VPE %d\n", bit,
+ vpe);
+ }
+ }
+ }
+
+ emt(mtflags);
+ local_irq_restore(flags);
+ if (pdb_msg != &id_ho_db_msg[0])
+ printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);
+#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
+
+ smtc_ipi_replay();
+}
+
+void smtc_soft_dump(void)
+{
+ int i;
+
+ printk("Counter Interrupts taken per CPU (TC)\n");
+ for (i=0; i < NR_CPUS; i++) {
+ printk("%d: %ld\n", i, smtc_cpu_stats[i].timerints);
+ }
+ printk("Self-IPI invocations:\n");
+ for (i=0; i < NR_CPUS; i++) {
+ printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
+ }
+ smtc_ipi_qdump();
+ printk("%d Recoveries of \"stolen\" FPU\n",
+ atomic_read(&smtc_fpu_recoveries));
+}
+
+
+/*
+ * TLB management routines special to SMTC
+ */
+
+void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
+{
+ unsigned long flags, mtflags, tcstat, prevhalt, asid;
+ int tlb, i;
+
+ /*
+ * It would be nice to be able to use a spinlock here,
+ * but this is invoked from within TLB flush routines
+ * that protect themselves with DVPE, so if a lock is
+ * held by another TC, it'll never be freed.
+ *
+ * DVPE/DMT must not be done with interrupts enabled,
+ * so even so most callers will already have disabled
+ * them, let's be really careful...
+ */
+
+ local_irq_save(flags);
+ if (smtc_status & SMTC_TLB_SHARED) {
+ mtflags = dvpe();
+ tlb = 0;
+ } else {
+ mtflags = dmt();
+ tlb = cpu_data[cpu].vpe_id;
+ }
+ asid = asid_cache(cpu);
+
+ do {
+ if (!((asid += ASID_INC) & ASID_MASK) ) {
+ if (cpu_has_vtag_icache)
+ flush_icache_all();
+ /* Traverse all online CPUs (hack requires contiguous range) */
+ for_each_online_cpu(i) {
+ /*
+ * We don't need to worry about our own CPU, nor those of
+ * CPUs who don't share our TLB.
+ */
+ if ((i != smp_processor_id()) &&
+ ((smtc_status & SMTC_TLB_SHARED) ||
+ (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))) {
+ settc(cpu_data[i].tc_id);
+ prevhalt = read_tc_c0_tchalt() & TCHALT_H;
+ if (!prevhalt) {
+ write_tc_c0_tchalt(TCHALT_H);
+ mips_ihb();
+ }
+ tcstat = read_tc_c0_tcstatus();
+ smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i);
+ if (!prevhalt)
+ write_tc_c0_tchalt(0);
+ }
+ }
+ if (!asid) /* fix version if needed */
+ asid = ASID_FIRST_VERSION;
+ local_flush_tlb_all(); /* start new asid cycle */
+ }
+ } while (smtc_live_asid[tlb][(asid & ASID_MASK)]);
+
+ /*
+ * SMTC shares the TLB within VPEs and possibly across all VPEs.
+ */
+ for_each_online_cpu(i) {
+ if ((smtc_status & SMTC_TLB_SHARED) ||
+ (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))
+ cpu_context(i, mm) = asid_cache(i) = asid;
+ }
+
+ if (smtc_status & SMTC_TLB_SHARED)
+ evpe(mtflags);
+ else
+ emt(mtflags);
+ local_irq_restore(flags);
+}
+
+/*
+ * Invoked from macros defined in mmu_context.h
+ * which must already have disabled interrupts
+ * and done a DVPE or DMT as appropriate.
+ */
+
+void smtc_flush_tlb_asid(unsigned long asid)
+{
+ int entry;
+ unsigned long ehi;
+
+ entry = read_c0_wired();
+
+ /* Traverse all non-wired entries */
+ while (entry < current_cpu_data.tlbsize) {
+ write_c0_index(entry);
+ ehb();
+ tlb_read();
+ ehb();
+ ehi = read_c0_entryhi();
+ if ((ehi & ASID_MASK) == asid) {
+ /*
+ * Invalidate only entries with specified ASID,
+ * makiing sure all entries differ.
+ */
+ write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ }
+ entry++;
+ }
+ write_c0_index(PARKED_INDEX);
+ tlbw_use_hazard();
+}
+
+/*
+ * Support for single-threading cache flush operations.
+ */
+
+static int halt_state_save[NR_CPUS];
+
+/*
+ * To really, really be sure that nothing is being done
+ * by other TCs, halt them all. This code assumes that
+ * a DVPE has already been done, so while their Halted
+ * state is theoretically architecturally unstable, in
+ * practice, it's not going to change while we're looking
+ * at it.
+ */
+
+void smtc_cflush_lockdown(void)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ if (cpu != smp_processor_id()) {
+ settc(cpu_data[cpu].tc_id);
+ halt_state_save[cpu] = read_tc_c0_tchalt();
+ write_tc_c0_tchalt(TCHALT_H);
+ }
+ }
+ mips_ihb();
+}
+
+/* It would be cheating to change the cpu_online states during a flush! */
+
+void smtc_cflush_release(void)
+{
+ int cpu;
+
+ /*
+ * Start with a hazard barrier to ensure
+ * that all CACHE ops have played through.
+ */
+ mips_ihb();
+
+ for_each_online_cpu(cpu) {
+ if (cpu != smp_processor_id()) {
+ settc(cpu_data[cpu].tc_id);
+ write_tc_c0_tchalt(halt_state_save[cpu]);
+ }
+ }
+ mips_ihb();
+}
diff --git a/arch/mips/kernel/spinlock_test.c b/arch/mips/kernel/spinlock_test.c
new file mode 100644
index 00000000..da61134d
--- /dev/null
+++ b/arch/mips/kernel/spinlock_test.c
@@ -0,0 +1,141 @@
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/hrtimer.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+
+static int ss_get(void *data, u64 *val)
+{
+ ktime_t start, finish;
+ int loops;
+ int cont;
+ DEFINE_RAW_SPINLOCK(ss_spin);
+
+ loops = 1000000;
+ cont = 1;
+
+ start = ktime_get();
+
+ while (cont) {
+ raw_spin_lock(&ss_spin);
+ loops--;
+ if (loops == 0)
+ cont = 0;
+ raw_spin_unlock(&ss_spin);
+ }
+
+ finish = ktime_get();
+
+ *val = ktime_us_delta(finish, start);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_ss, ss_get, NULL, "%llu\n");
+
+
+
+struct spin_multi_state {
+ raw_spinlock_t lock;
+ atomic_t start_wait;
+ atomic_t enter_wait;
+ atomic_t exit_wait;
+ int loops;
+};
+
+struct spin_multi_per_thread {
+ struct spin_multi_state *state;
+ ktime_t start;
+};
+
+static int multi_other(void *data)
+{
+ int loops;
+ int cont;
+ struct spin_multi_per_thread *pt = data;
+ struct spin_multi_state *s = pt->state;
+
+ loops = s->loops;
+ cont = 1;
+
+ atomic_dec(&s->enter_wait);
+
+ while (atomic_read(&s->enter_wait))
+ ; /* spin */
+
+ pt->start = ktime_get();
+
+ atomic_dec(&s->start_wait);
+
+ while (atomic_read(&s->start_wait))
+ ; /* spin */
+
+ while (cont) {
+ raw_spin_lock(&s->lock);
+ loops--;
+ if (loops == 0)
+ cont = 0;
+ raw_spin_unlock(&s->lock);
+ }
+
+ atomic_dec(&s->exit_wait);
+ while (atomic_read(&s->exit_wait))
+ ; /* spin */
+ return 0;
+}
+
+static int multi_get(void *data, u64 *val)
+{
+ ktime_t finish;
+ struct spin_multi_state ms;
+ struct spin_multi_per_thread t1, t2;
+
+ ms.lock = __RAW_SPIN_LOCK_UNLOCKED("multi_get");
+ ms.loops = 1000000;
+
+ atomic_set(&ms.start_wait, 2);
+ atomic_set(&ms.enter_wait, 2);
+ atomic_set(&ms.exit_wait, 2);
+ t1.state = &ms;
+ t2.state = &ms;
+
+ kthread_run(multi_other, &t2, "multi_get");
+
+ multi_other(&t1);
+
+ finish = ktime_get();
+
+ *val = ktime_us_delta(finish, t1.start);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n");
+
+
+extern struct dentry *mips_debugfs_dir;
+static int __init spinlock_test(void)
+{
+ struct dentry *d;
+
+ if (!mips_debugfs_dir)
+ return -ENODEV;
+
+ d = debugfs_create_file("spin_single", S_IRUGO,
+ mips_debugfs_dir, NULL,
+ &fops_ss);
+ if (!d)
+ return -ENOMEM;
+
+ d = debugfs_create_file("spin_multi", S_IRUGO,
+ mips_debugfs_dir, NULL,
+ &fops_multi);
+ if (!d)
+ return -ENOMEM;
+
+ return 0;
+}
+device_initcall(spinlock_test);
diff --git a/arch/mips/kernel/spram.c b/arch/mips/kernel/spram.c
new file mode 100644
index 00000000..1821d12a
--- /dev/null
+++ b/arch/mips/kernel/spram.c
@@ -0,0 +1,220 @@
+/*
+ * MIPS SPRAM support
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Copyright (C) 2007, 2008 MIPS Technologies, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/stddef.h>
+
+#include <asm/fpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/r4kcache.h>
+#include <asm/hazards.h>
+
+/*
+ * These definitions are correct for the 24K/34K/74K SPRAM sample
+ * implementation. The 4KS interpreted the tags differently...
+ */
+#define SPRAM_TAG0_ENABLE 0x00000080
+#define SPRAM_TAG0_PA_MASK 0xfffff000
+#define SPRAM_TAG1_SIZE_MASK 0xfffff000
+
+#define SPRAM_TAG_STRIDE 8
+
+#define ERRCTL_SPRAM (1 << 28)
+
+/* errctl access */
+#define read_c0_errctl(x) read_c0_ecc(x)
+#define write_c0_errctl(x) write_c0_ecc(x)
+
+/*
+ * Different semantics to the set_c0_* function built by __BUILD_SET_C0
+ */
+static __cpuinit unsigned int bis_c0_errctl(unsigned int set)
+{
+ unsigned int res;
+ res = read_c0_errctl();
+ write_c0_errctl(res | set);
+ return res;
+}
+
+static __cpuinit void ispram_store_tag(unsigned int offset, unsigned int data)
+{
+ unsigned int errctl;
+
+ /* enable SPRAM tag access */
+ errctl = bis_c0_errctl(ERRCTL_SPRAM);
+ ehb();
+
+ write_c0_taglo(data);
+ ehb();
+
+ cache_op(Index_Store_Tag_I, CKSEG0|offset);
+ ehb();
+
+ write_c0_errctl(errctl);
+ ehb();
+}
+
+
+static __cpuinit unsigned int ispram_load_tag(unsigned int offset)
+{
+ unsigned int data;
+ unsigned int errctl;
+
+ /* enable SPRAM tag access */
+ errctl = bis_c0_errctl(ERRCTL_SPRAM);
+ ehb();
+ cache_op(Index_Load_Tag_I, CKSEG0 | offset);
+ ehb();
+ data = read_c0_taglo();
+ ehb();
+ write_c0_errctl(errctl);
+ ehb();
+
+ return data;
+}
+
+static __cpuinit void dspram_store_tag(unsigned int offset, unsigned int data)
+{
+ unsigned int errctl;
+
+ /* enable SPRAM tag access */
+ errctl = bis_c0_errctl(ERRCTL_SPRAM);
+ ehb();
+ write_c0_dtaglo(data);
+ ehb();
+ cache_op(Index_Store_Tag_D, CKSEG0 | offset);
+ ehb();
+ write_c0_errctl(errctl);
+ ehb();
+}
+
+
+static __cpuinit unsigned int dspram_load_tag(unsigned int offset)
+{
+ unsigned int data;
+ unsigned int errctl;
+
+ errctl = bis_c0_errctl(ERRCTL_SPRAM);
+ ehb();
+ cache_op(Index_Load_Tag_D, CKSEG0 | offset);
+ ehb();
+ data = read_c0_dtaglo();
+ ehb();
+ write_c0_errctl(errctl);
+ ehb();
+
+ return data;
+}
+
+static __cpuinit void probe_spram(char *type,
+ unsigned int base,
+ unsigned int (*read)(unsigned int),
+ void (*write)(unsigned int, unsigned int))
+{
+ unsigned int firstsize = 0, lastsize = 0;
+ unsigned int firstpa = 0, lastpa = 0, pa = 0;
+ unsigned int offset = 0;
+ unsigned int size, tag0, tag1;
+ unsigned int enabled;
+ int i;
+
+ /*
+ * The limit is arbitrary but avoids the loop running away if
+ * the SPRAM tags are implemented differently
+ */
+
+ for (i = 0; i < 8; i++) {
+ tag0 = read(offset);
+ tag1 = read(offset+SPRAM_TAG_STRIDE);
+ pr_debug("DBG %s%d: tag0=%08x tag1=%08x\n",
+ type, i, tag0, tag1);
+
+ size = tag1 & SPRAM_TAG1_SIZE_MASK;
+
+ if (size == 0)
+ break;
+
+ if (i != 0) {
+ /* tags may repeat... */
+ if ((pa == firstpa && size == firstsize) ||
+ (pa == lastpa && size == lastsize))
+ break;
+ }
+
+ /* Align base with size */
+ base = (base + size - 1) & ~(size-1);
+
+ /* reprogram the base address base address and enable */
+ tag0 = (base & SPRAM_TAG0_PA_MASK) | SPRAM_TAG0_ENABLE;
+ write(offset, tag0);
+
+ base += size;
+
+ /* reread the tag */
+ tag0 = read(offset);
+ pa = tag0 & SPRAM_TAG0_PA_MASK;
+ enabled = tag0 & SPRAM_TAG0_ENABLE;
+
+ if (i == 0) {
+ firstpa = pa;
+ firstsize = size;
+ }
+
+ lastpa = pa;
+ lastsize = size;
+
+ if (strcmp(type, "DSPRAM") == 0) {
+ unsigned int *vp = (unsigned int *)(CKSEG1 | pa);
+ unsigned int v;
+#define TDAT 0x5a5aa5a5
+ vp[0] = TDAT;
+ vp[1] = ~TDAT;
+
+ mb();
+
+ v = vp[0];
+ if (v != TDAT)
+ printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
+ vp, TDAT, v);
+ v = vp[1];
+ if (v != ~TDAT)
+ printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
+ vp+1, ~TDAT, v);
+ }
+
+ pr_info("%s%d: PA=%08x,Size=%08x%s\n",
+ type, i, pa, size, enabled ? ",enabled" : "");
+ offset += 2 * SPRAM_TAG_STRIDE;
+ }
+}
+void __cpuinit spram_config(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int config0;
+
+ switch (c->cputype) {
+ case CPU_24K:
+ case CPU_34K:
+ case CPU_74K:
+ case CPU_1004K:
+ config0 = read_c0_config();
+ /* FIXME: addresses are Malta specific */
+ if (config0 & (1<<24)) {
+ probe_spram("ISPRAM", 0x1c000000,
+ &ispram_load_tag, &ispram_store_tag);
+ }
+ if (config0 & (1<<23))
+ probe_spram("DSPRAM", 0x1c100000,
+ &dspram_load_tag, &dspram_store_tag);
+ }
+}
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
new file mode 100644
index 00000000..d52ff77b
--- /dev/null
+++ b/arch/mips/kernel/stacktrace.c
@@ -0,0 +1,87 @@
+/*
+ * Stack trace management functions
+ *
+ * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ */
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/module.h>
+#include <asm/stacktrace.h>
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer:
+ */
+static void save_raw_context_stack(struct stack_trace *trace,
+ unsigned long reg29)
+{
+ unsigned long *sp = (unsigned long *)reg29;
+ unsigned long addr;
+
+ while (!kstack_end(sp)) {
+ addr = *sp++;
+ if (__kernel_text_address(addr)) {
+ if (trace->skip > 0)
+ trace->skip--;
+ else
+ trace->entries[trace->nr_entries++] = addr;
+ if (trace->nr_entries >= trace->max_entries)
+ break;
+ }
+ }
+}
+
+static void save_context_stack(struct stack_trace *trace,
+ struct task_struct *tsk, struct pt_regs *regs)
+{
+ unsigned long sp = regs->regs[29];
+#ifdef CONFIG_KALLSYMS
+ unsigned long ra = regs->regs[31];
+ unsigned long pc = regs->cp0_epc;
+
+ if (raw_show_trace || !__kernel_text_address(pc)) {
+ unsigned long stack_page =
+ (unsigned long)task_stack_page(tsk);
+ if (stack_page && sp >= stack_page &&
+ sp <= stack_page + THREAD_SIZE - 32)
+ save_raw_context_stack(trace, sp);
+ return;
+ }
+ do {
+ if (trace->skip > 0)
+ trace->skip--;
+ else
+ trace->entries[trace->nr_entries++] = pc;
+ if (trace->nr_entries >= trace->max_entries)
+ break;
+ pc = unwind_stack(tsk, &sp, pc, &ra);
+ } while (pc);
+#else
+ save_raw_context_stack(trace, sp);
+#endif
+}
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+ save_stack_trace_tsk(current, trace);
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+ struct pt_regs dummyregs;
+ struct pt_regs *regs = &dummyregs;
+
+ WARN_ON(trace->nr_entries || !trace->max_entries);
+
+ if (tsk != current) {
+ regs->regs[29] = tsk->thread.reg29;
+ regs->regs[31] = 0;
+ regs->cp0_epc = tsk->thread.reg31;
+ } else
+ prepare_frametrace(regs);
+ save_context_stack(trace, tsk, regs);
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c
new file mode 100644
index 00000000..05dd170a
--- /dev/null
+++ b/arch/mips/kernel/sync-r4k.c
@@ -0,0 +1,160 @@
+/*
+ * Count register synchronisation.
+ *
+ * All CPUs will have their count registers synchronised to the CPU0 next time
+ * value. This can cause a small timewarp for CPU0. All other CPU's should
+ * not have done anything significant (but they may have had interrupts
+ * enabled briefly - prom_smp_finish() should not be responsible for enabling
+ * interrupts...)
+ *
+ * FIXME: broken for SMTC
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irqflags.h>
+#include <linux/cpumask.h>
+
+#include <asm/r4k-timer.h>
+#include <asm/atomic.h>
+#include <asm/barrier.h>
+#include <asm/mipsregs.h>
+
+static atomic_t __cpuinitdata count_start_flag = ATOMIC_INIT(0);
+static atomic_t __cpuinitdata count_count_start = ATOMIC_INIT(0);
+static atomic_t __cpuinitdata count_count_stop = ATOMIC_INIT(0);
+static atomic_t __cpuinitdata count_reference = ATOMIC_INIT(0);
+
+#define COUNTON 100
+#define NR_LOOPS 5
+
+void __cpuinit synchronise_count_master(void)
+{
+ int i;
+ unsigned long flags;
+ unsigned int initcount;
+ int nslaves;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC needs to synchronise per VPE, not per CPU
+ * ignore for now
+ */
+ return;
+#endif
+
+ printk(KERN_INFO "Synchronize counters across %u CPUs: ",
+ num_online_cpus());
+
+ local_irq_save(flags);
+
+ /*
+ * Notify the slaves that it's time to start
+ */
+ atomic_set(&count_reference, read_c0_count());
+ atomic_set(&count_start_flag, 1);
+ smp_wmb();
+
+ /* Count will be initialised to current timer for all CPU's */
+ initcount = read_c0_count();
+
+ /*
+ * We loop a few times to get a primed instruction cache,
+ * then the last pass is more or less synchronised and
+ * the master and slaves each set their cycle counters to a known
+ * value all at once. This reduces the chance of having random offsets
+ * between the processors, and guarantees that the maximum
+ * delay between the cycle counters is never bigger than
+ * the latency of information-passing (cachelines) between
+ * two CPUs.
+ */
+
+ nslaves = num_online_cpus()-1;
+ for (i = 0; i < NR_LOOPS; i++) {
+ /* slaves loop on '!= ncpus' */
+ while (atomic_read(&count_count_start) != nslaves)
+ mb();
+ atomic_set(&count_count_stop, 0);
+ smp_wmb();
+
+ /* this lets the slaves write their count register */
+ atomic_inc(&count_count_start);
+
+ /*
+ * Everyone initialises count in the last loop:
+ */
+ if (i == NR_LOOPS-1)
+ write_c0_count(initcount);
+
+ /*
+ * Wait for all slaves to leave the synchronization point:
+ */
+ while (atomic_read(&count_count_stop) != nslaves)
+ mb();
+ atomic_set(&count_count_start, 0);
+ smp_wmb();
+ atomic_inc(&count_count_stop);
+ }
+ /* Arrange for an interrupt in a short while */
+ write_c0_compare(read_c0_count() + COUNTON);
+
+ local_irq_restore(flags);
+
+ /*
+ * i386 code reported the skew here, but the
+ * count registers were almost certainly out of sync
+ * so no point in alarming people
+ */
+ printk("done.\n");
+}
+
+void __cpuinit synchronise_count_slave(void)
+{
+ int i;
+ unsigned long flags;
+ unsigned int initcount;
+ int ncpus;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC needs to synchronise per VPE, not per CPU
+ * ignore for now
+ */
+ return;
+#endif
+
+ local_irq_save(flags);
+
+ /*
+ * Not every cpu is online at the time this gets called,
+ * so we first wait for the master to say everyone is ready
+ */
+
+ while (!atomic_read(&count_start_flag))
+ mb();
+
+ /* Count will be initialised to next expire for all CPU's */
+ initcount = atomic_read(&count_reference);
+
+ ncpus = num_online_cpus();
+ for (i = 0; i < NR_LOOPS; i++) {
+ atomic_inc(&count_count_start);
+ while (atomic_read(&count_count_start) != ncpus)
+ mb();
+
+ /*
+ * Everyone initialises count in the last loop:
+ */
+ if (i == NR_LOOPS-1)
+ write_c0_count(initcount);
+
+ atomic_inc(&count_count_stop);
+ while (atomic_read(&count_count_stop) != ncpus)
+ mb();
+ }
+ /* Arrange for an interrupt in a short while */
+ write_c0_compare(read_c0_count() + COUNTON);
+
+ local_irq_restore(flags);
+}
+#undef NR_LOOPS
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
new file mode 100644
index 00000000..d0276570
--- /dev/null
+++ b/arch/mips/kernel/syscall.c
@@ -0,0 +1,345 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 2000, 2001, 05 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ */
+#include <linux/capability.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <linux/fs.h>
+#include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <linux/string.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+#include <linux/unistd.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/compiler.h>
+#include <linux/ipc.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/elf.h>
+
+#include <asm/asm.h>
+#include <asm/branch.h>
+#include <asm/cachectl.h>
+#include <asm/cacheflush.h>
+#include <asm/asm-offsets.h>
+#include <asm/signal.h>
+#include <asm/sim.h>
+#include <asm/shmparam.h>
+#include <asm/sysmips.h>
+#include <asm/uaccess.h>
+
+/*
+ * For historic reasons the pipe(2) syscall on MIPS has an unusual calling
+ * convention. It returns results in registers $v0 / $v1 which means there
+ * is no need for it to do verify the validity of a userspace pointer
+ * argument. Historically that used to be expensive in Linux. These days
+ * the performance advantage is negligible.
+ */
+asmlinkage int sysm_pipe(nabi_no_regargs volatile struct pt_regs regs)
+{
+ int fd[2];
+ int error, res;
+
+ error = do_pipe_flags(fd, 0);
+ if (error) {
+ res = error;
+ goto out;
+ }
+ regs.regs[3] = fd[1];
+ res = fd[0];
+out:
+ return res;
+}
+
+SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long,
+ fd, off_t, offset)
+{
+ unsigned long result;
+
+ result = -EINVAL;
+ if (offset & ~PAGE_MASK)
+ goto out;
+
+ result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+
+out:
+ return result;
+}
+
+SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, pgoff)
+{
+ if (pgoff & (~PAGE_MASK >> 12))
+ return -EINVAL;
+
+ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
+}
+
+save_static_function(sys_fork);
+static int __used noinline
+_sys_fork(nabi_no_regargs struct pt_regs regs)
+{
+ return do_fork(SIGCHLD, regs.regs[29], &regs, 0, NULL, NULL);
+}
+
+save_static_function(sys_clone);
+static int __used noinline
+_sys_clone(nabi_no_regargs struct pt_regs regs)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+ int __user *parent_tidptr, *child_tidptr;
+
+ clone_flags = regs.regs[4];
+ newsp = regs.regs[5];
+ if (!newsp)
+ newsp = regs.regs[29];
+ parent_tidptr = (int __user *) regs.regs[6];
+#ifdef CONFIG_32BIT
+ /* We need to fetch the fifth argument off the stack. */
+ child_tidptr = NULL;
+ if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) {
+ int __user *__user *usp = (int __user *__user *) regs.regs[29];
+ if (regs.regs[2] == __NR_syscall) {
+ if (get_user (child_tidptr, &usp[5]))
+ return -EFAULT;
+ }
+ else if (get_user (child_tidptr, &usp[4]))
+ return -EFAULT;
+ }
+#else
+ child_tidptr = (int __user *) regs.regs[8];
+#endif
+ return do_fork(clone_flags, newsp, &regs, 0,
+ parent_tidptr, child_tidptr);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
+{
+ int error;
+ char * filename;
+
+ filename = getname((const char __user *) (long)regs.regs[4]);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = do_execve(filename,
+ (const char __user *const __user *) (long)regs.regs[5],
+ (const char __user *const __user *) (long)regs.regs[6],
+ &regs);
+ putname(filename);
+
+out:
+ return error;
+}
+
+SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
+{
+ struct thread_info *ti = task_thread_info(current);
+
+ ti->tp_value = addr;
+ if (cpu_has_userlocal)
+ write_c0_userlocal(addr);
+
+ return 0;
+}
+
+static inline int mips_atomic_set(struct pt_regs *regs,
+ unsigned long addr, unsigned long new)
+{
+ unsigned long old, tmp;
+ unsigned int err;
+
+ if (unlikely(addr & 3))
+ return -EINVAL;
+
+ if (unlikely(!access_ok(VERIFY_WRITE, addr, 4)))
+ return -EINVAL;
+
+ if (cpu_has_llsc && R10000_LLSC_WAR) {
+ __asm__ __volatile__ (
+ " .set mips3 \n"
+ " li %[err], 0 \n"
+ "1: ll %[old], (%[addr]) \n"
+ " move %[tmp], %[new] \n"
+ "2: sc %[tmp], (%[addr]) \n"
+ " beqzl %[tmp], 1b \n"
+ "3: \n"
+ " .section .fixup,\"ax\" \n"
+ "4: li %[err], %[efault] \n"
+ " j 3b \n"
+ " .previous \n"
+ " .section __ex_table,\"a\" \n"
+ " "STR(PTR)" 1b, 4b \n"
+ " "STR(PTR)" 2b, 4b \n"
+ " .previous \n"
+ " .set mips0 \n"
+ : [old] "=&r" (old),
+ [err] "=&r" (err),
+ [tmp] "=&r" (tmp)
+ : [addr] "r" (addr),
+ [new] "r" (new),
+ [efault] "i" (-EFAULT)
+ : "memory");
+ } else if (cpu_has_llsc) {
+ __asm__ __volatile__ (
+ " .set mips3 \n"
+ " li %[err], 0 \n"
+ "1: ll %[old], (%[addr]) \n"
+ " move %[tmp], %[new] \n"
+ "2: sc %[tmp], (%[addr]) \n"
+ " bnez %[tmp], 4f \n"
+ "3: \n"
+ " .subsection 2 \n"
+ "4: b 1b \n"
+ " .previous \n"
+ " \n"
+ " .section .fixup,\"ax\" \n"
+ "5: li %[err], %[efault] \n"
+ " j 3b \n"
+ " .previous \n"
+ " .section __ex_table,\"a\" \n"
+ " "STR(PTR)" 1b, 5b \n"
+ " "STR(PTR)" 2b, 5b \n"
+ " .previous \n"
+ " .set mips0 \n"
+ : [old] "=&r" (old),
+ [err] "=&r" (err),
+ [tmp] "=&r" (tmp)
+ : [addr] "r" (addr),
+ [new] "r" (new),
+ [efault] "i" (-EFAULT)
+ : "memory");
+ } else {
+ do {
+ preempt_disable();
+ ll_bit = 1;
+ ll_task = current;
+ preempt_enable();
+
+ err = __get_user(old, (unsigned int *) addr);
+ err |= __put_user(new, (unsigned int *) addr);
+ if (err)
+ break;
+ rmb();
+ } while (!ll_bit);
+ }
+
+ if (unlikely(err))
+ return err;
+
+ regs->regs[2] = old;
+ regs->regs[7] = 0; /* No error */
+
+ /*
+ * Don't let your children do this ...
+ */
+ __asm__ __volatile__(
+ " move $29, %0 \n"
+ " j syscall_exit \n"
+ : /* no outputs */
+ : "r" (regs));
+
+ /* unreached. Honestly. */
+ while (1);
+}
+
+save_static_function(sys_sysmips);
+static int __used noinline
+_sys_sysmips(nabi_no_regargs struct pt_regs regs)
+{
+ long cmd, arg1, arg2;
+
+ cmd = regs.regs[4];
+ arg1 = regs.regs[5];
+ arg2 = regs.regs[6];
+
+ switch (cmd) {
+ case MIPS_ATOMIC_SET:
+ return mips_atomic_set(&regs, arg1, arg2);
+
+ case MIPS_FIXADE:
+ if (arg1 & ~3)
+ return -EINVAL;
+
+ if (arg1 & 1)
+ set_thread_flag(TIF_FIXADE);
+ else
+ clear_thread_flag(TIF_FIXADE);
+ if (arg1 & 2)
+ set_thread_flag(TIF_LOGADE);
+ else
+ clear_thread_flag(TIF_LOGADE);
+
+ return 0;
+
+ case FLUSH_CACHE:
+ __flush_cache_all();
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+/*
+ * No implemented yet ...
+ */
+SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op)
+{
+ return -ENOSYS;
+}
+
+/*
+ * If we ever come here the user sp is bad. Zap the process right away.
+ * Due to the bad stack signaling wouldn't work.
+ */
+asmlinkage void bad_stack(void)
+{
+ do_exit(SIGSEGV);
+}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename,
+ const char *const argv[],
+ const char *const envp[])
+{
+ register unsigned long __a0 asm("$4") = (unsigned long) filename;
+ register unsigned long __a1 asm("$5") = (unsigned long) argv;
+ register unsigned long __a2 asm("$6") = (unsigned long) envp;
+ register unsigned long __a3 asm("$7");
+ unsigned long __v0;
+
+ __asm__ volatile (" \n"
+ " .set noreorder \n"
+ " li $2, %5 # __NR_execve \n"
+ " syscall \n"
+ " move %0, $2 \n"
+ " .set reorder \n"
+ : "=&r" (__v0), "=r" (__a3)
+ : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve)
+ : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24",
+ "memory");
+
+ if (__a3 == 0)
+ return __v0;
+
+ return -__v0;
+}
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
new file mode 100644
index 00000000..1083ad4e
--- /dev/null
+++ b/arch/mips/kernel/time.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (c) 2003, 2004 Maciej W. Rozycki
+ *
+ * Common time service routines for MIPS machines.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/bug.h>
+#include <linux/clockchips.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+
+#include <asm/cpu-features.h>
+#include <asm/div64.h>
+#include <asm/smtc_ipi.h>
+#include <asm/time.h>
+
+/*
+ * forward reference
+ */
+DEFINE_SPINLOCK(rtc_lock);
+EXPORT_SYMBOL(rtc_lock);
+
+int __weak rtc_mips_set_time(unsigned long sec)
+{
+ return 0;
+}
+
+int __weak rtc_mips_set_mmss(unsigned long nowtime)
+{
+ return rtc_mips_set_time(nowtime);
+}
+
+int update_persistent_clock(struct timespec now)
+{
+ return rtc_mips_set_mmss(now.tv_sec);
+}
+
+static int null_perf_irq(void)
+{
+ return 0;
+}
+
+int (*perf_irq)(void) = null_perf_irq;
+
+EXPORT_SYMBOL(perf_irq);
+
+/*
+ * time_init() - it does the following things.
+ *
+ * 1) plat_time_init() -
+ * a) (optional) set up RTC routines,
+ * b) (optional) calibrate and set the mips_hpt_frequency
+ * (only needed if you intended to use cpu counter as timer interrupt
+ * source)
+ * 2) calculate a couple of cached variables for later usage
+ */
+
+unsigned int mips_hpt_frequency;
+
+/*
+ * This function exists in order to cause an error due to a duplicate
+ * definition if platform code should have its own implementation. The hook
+ * to use instead is plat_time_init. plat_time_init does not receive the
+ * irqaction pointer argument anymore. This is because any function which
+ * initializes an interrupt timer now takes care of its own request_irq rsp.
+ * setup_irq calls and each clock_event_device should use its own
+ * struct irqrequest.
+ */
+void __init plat_timer_setup(void)
+{
+ BUG();
+}
+
+static __init int cpu_has_mfc0_count_bug(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_R4000PC:
+ case CPU_R4000SC:
+ case CPU_R4000MC:
+ /*
+ * V3.0 is documented as suffering from the mfc0 from count bug.
+ * Afaik this is the last version of the R4000. Later versions
+ * were marketed as R4400.
+ */
+ return 1;
+
+ case CPU_R4400PC:
+ case CPU_R4400SC:
+ case CPU_R4400MC:
+ /*
+ * The published errata for the R4400 up to 3.0 say the CPU
+ * has the mfc0 from count bug.
+ */
+ if ((current_cpu_data.processor_id & 0xff) <= 0x30)
+ return 1;
+
+ /*
+ * we assume newer revisions are ok
+ */
+ return 0;
+ }
+
+ return 0;
+}
+
+void __init time_init(void)
+{
+ plat_time_init();
+
+ if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())
+ init_mips_clocksource();
+}
diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c
new file mode 100644
index 00000000..cf3eb61f
--- /dev/null
+++ b/arch/mips/kernel/topology.c
@@ -0,0 +1,32 @@
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/node.h>
+#include <linux/nodemask.h>
+#include <linux/percpu.h>
+
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
+
+static int __init topology_init(void)
+{
+ int i, ret;
+
+#ifdef CONFIG_NUMA
+ for_each_online_node(i)
+ register_one_node(i);
+#endif /* CONFIG_NUMA */
+
+ for_each_present_cpu(i) {
+ struct cpu *c = &per_cpu(cpu_devices, i);
+
+ c->hotpluggable = 1;
+ ret = register_cpu(c, i);
+ if (ret)
+ printk(KERN_WARNING "topology_init: register_cpu %d "
+ "failed (%d)\n", i, ret);
+ }
+
+ return 0;
+}
+
+subsys_initcall(topology_init);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
new file mode 100644
index 00000000..e9b3af27
--- /dev/null
+++ b/arch/mips/kernel/traps.c
@@ -0,0 +1,1795 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
+ * Copyright (C) 1995, 1996 Paul M. Antoine
+ * Copyright (C) 1998 Ulf Carlsson
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000, 01 MIPS Technologies, Inc.
+ * Copyright (C) 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki
+ */
+#include <linux/bug.h>
+#include <linux/compiler.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
+#include <linux/bootmem.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/kgdb.h>
+#include <linux/kdebug.h>
+#include <linux/kprobes.h>
+#include <linux/notifier.h>
+#include <linux/kdb.h>
+#include <linux/irq.h>
+#include <linux/perf_event.h>
+
+#include <asm/bootinfo.h>
+#include <asm/branch.h>
+#include <asm/break.h>
+#include <asm/cop2.h>
+#include <asm/cpu.h>
+#include <asm/dsp.h>
+#include <asm/fpu.h>
+#include <asm/fpu_emulator.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/module.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <asm/tlbdebug.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+#include <asm/watch.h>
+#include <asm/mmu_context.h>
+#include <asm/types.h>
+#include <asm/stacktrace.h>
+#include <asm/uasm.h>
+
+extern void check_wait(void);
+extern asmlinkage void r4k_wait(void);
+extern asmlinkage void rollback_handle_int(void);
+extern asmlinkage void handle_int(void);
+extern asmlinkage void handle_tlbm(void);
+extern asmlinkage void handle_tlbl(void);
+extern asmlinkage void handle_tlbs(void);
+extern asmlinkage void handle_adel(void);
+extern asmlinkage void handle_ades(void);
+extern asmlinkage void handle_ibe(void);
+extern asmlinkage void handle_dbe(void);
+extern asmlinkage void handle_sys(void);
+extern asmlinkage void handle_bp(void);
+extern asmlinkage void handle_ri(void);
+extern asmlinkage void handle_ri_rdhwr_vivt(void);
+extern asmlinkage void handle_ri_rdhwr(void);
+extern asmlinkage void handle_cpu(void);
+extern asmlinkage void handle_ov(void);
+extern asmlinkage void handle_tr(void);
+extern asmlinkage void handle_fpe(void);
+extern asmlinkage void handle_mdmx(void);
+extern asmlinkage void handle_watch(void);
+extern asmlinkage void handle_mt(void);
+extern asmlinkage void handle_dsp(void);
+extern asmlinkage void handle_mcheck(void);
+extern asmlinkage void handle_reserved(void);
+
+extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
+ struct mips_fpu_struct *ctx, int has_fpu,
+ void *__user *fault_addr);
+
+void (*board_be_init)(void);
+int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
+void (*board_nmi_handler_setup)(void);
+void (*board_ejtag_handler_setup)(void);
+void (*board_bind_eic_interrupt)(int irq, int regset);
+
+
+static void show_raw_backtrace(unsigned long reg29)
+{
+ unsigned long *sp = (unsigned long *)(reg29 & ~3);
+ unsigned long addr;
+
+ printk("Call Trace:");
+#ifdef CONFIG_KALLSYMS
+ printk("\n");
+#endif
+ while (!kstack_end(sp)) {
+ unsigned long __user *p =
+ (unsigned long __user *)(unsigned long)sp++;
+ if (__get_user(addr, p)) {
+ printk(" (Bad stack address)");
+ break;
+ }
+ if (__kernel_text_address(addr))
+ print_ip_sym(addr);
+ }
+ printk("\n");
+}
+
+#ifdef CONFIG_KALLSYMS
+int raw_show_trace;
+static int __init set_raw_show_trace(char *str)
+{
+ raw_show_trace = 1;
+ return 1;
+}
+__setup("raw_show_trace", set_raw_show_trace);
+#endif
+
+static void show_backtrace(struct task_struct *task, const struct pt_regs *regs)
+{
+ unsigned long sp = regs->regs[29];
+ unsigned long ra = regs->regs[31];
+ unsigned long pc = regs->cp0_epc;
+
+ if (raw_show_trace || !__kernel_text_address(pc)) {
+ show_raw_backtrace(sp);
+ return;
+ }
+ printk("Call Trace:\n");
+ do {
+ print_ip_sym(pc);
+ pc = unwind_stack(task, &sp, pc, &ra);
+ } while (pc);
+ printk("\n");
+}
+
+/*
+ * This routine abuses get_user()/put_user() to reference pointers
+ * with at least a bit of error checking ...
+ */
+static void show_stacktrace(struct task_struct *task,
+ const struct pt_regs *regs)
+{
+ const int field = 2 * sizeof(unsigned long);
+ long stackdata;
+ int i;
+ unsigned long __user *sp = (unsigned long __user *)regs->regs[29];
+
+ printk("Stack :");
+ i = 0;
+ while ((unsigned long) sp & (PAGE_SIZE - 1)) {
+ if (i && ((i % (64 / field)) == 0))
+ printk("\n ");
+ if (i > 39) {
+ printk(" ...");
+ break;
+ }
+
+ if (__get_user(stackdata, sp++)) {
+ printk(" (Bad stack address)");
+ break;
+ }
+
+ printk(" %0*lx", field, stackdata);
+ i++;
+ }
+ printk("\n");
+ show_backtrace(task, regs);
+}
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+ struct pt_regs regs;
+ if (sp) {
+ regs.regs[29] = (unsigned long)sp;
+ regs.regs[31] = 0;
+ regs.cp0_epc = 0;
+ } else {
+ if (task && task != current) {
+ regs.regs[29] = task->thread.reg29;
+ regs.regs[31] = 0;
+ regs.cp0_epc = task->thread.reg31;
+#ifdef CONFIG_KGDB_KDB
+ } else if (atomic_read(&kgdb_active) != -1 &&
+ kdb_current_regs) {
+ memcpy(&regs, kdb_current_regs, sizeof(regs));
+#endif /* CONFIG_KGDB_KDB */
+ } else {
+ prepare_frametrace(&regs);
+ }
+ }
+ show_stacktrace(task, &regs);
+}
+
+/*
+ * The architecture-independent dump_stack generator
+ */
+void dump_stack(void)
+{
+ struct pt_regs regs;
+
+ prepare_frametrace(&regs);
+ show_backtrace(current, &regs);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+static void show_code(unsigned int __user *pc)
+{
+ long i;
+ unsigned short __user *pc16 = NULL;
+
+ printk("\nCode:");
+
+ if ((unsigned long)pc & 1)
+ pc16 = (unsigned short __user *)((unsigned long)pc & ~1);
+ for(i = -3 ; i < 6 ; i++) {
+ unsigned int insn;
+ if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) {
+ printk(" (Bad address in epc)\n");
+ break;
+ }
+ printk("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>'));
+ }
+}
+
+static void __show_regs(const struct pt_regs *regs)
+{
+ const int field = 2 * sizeof(unsigned long);
+ unsigned int cause = regs->cp0_cause;
+ int i;
+
+ printk("Cpu %d\n", smp_processor_id());
+
+ /*
+ * Saved main processor registers
+ */
+ for (i = 0; i < 32; ) {
+ if ((i % 4) == 0)
+ printk("$%2d :", i);
+ if (i == 0)
+ printk(" %0*lx", field, 0UL);
+ else if (i == 26 || i == 27)
+ printk(" %*s", field, "");
+ else
+ printk(" %0*lx", field, regs->regs[i]);
+
+ i++;
+ if ((i % 4) == 0)
+ printk("\n");
+ }
+
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ printk("Acx : %0*lx\n", field, regs->acx);
+#endif
+ printk("Hi : %0*lx\n", field, regs->hi);
+ printk("Lo : %0*lx\n", field, regs->lo);
+
+ /*
+ * Saved cp0 registers
+ */
+ printk("epc : %0*lx %pS\n", field, regs->cp0_epc,
+ (void *) regs->cp0_epc);
+ printk(" %s\n", print_tainted());
+ printk("ra : %0*lx %pS\n", field, regs->regs[31],
+ (void *) regs->regs[31]);
+
+ printk("Status: %08x ", (uint32_t) regs->cp0_status);
+
+ if (current_cpu_data.isa_level == MIPS_CPU_ISA_I) {
+ if (regs->cp0_status & ST0_KUO)
+ printk("KUo ");
+ if (regs->cp0_status & ST0_IEO)
+ printk("IEo ");
+ if (regs->cp0_status & ST0_KUP)
+ printk("KUp ");
+ if (regs->cp0_status & ST0_IEP)
+ printk("IEp ");
+ if (regs->cp0_status & ST0_KUC)
+ printk("KUc ");
+ if (regs->cp0_status & ST0_IEC)
+ printk("IEc ");
+ } else {
+ if (regs->cp0_status & ST0_KX)
+ printk("KX ");
+ if (regs->cp0_status & ST0_SX)
+ printk("SX ");
+ if (regs->cp0_status & ST0_UX)
+ printk("UX ");
+ switch (regs->cp0_status & ST0_KSU) {
+ case KSU_USER:
+ printk("USER ");
+ break;
+ case KSU_SUPERVISOR:
+ printk("SUPERVISOR ");
+ break;
+ case KSU_KERNEL:
+ printk("KERNEL ");
+ break;
+ default:
+ printk("BAD_MODE ");
+ break;
+ }
+ if (regs->cp0_status & ST0_ERL)
+ printk("ERL ");
+ if (regs->cp0_status & ST0_EXL)
+ printk("EXL ");
+ if (regs->cp0_status & ST0_IE)
+ printk("IE ");
+ }
+ printk("\n");
+
+ printk("Cause : %08x\n", cause);
+
+ cause = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
+ if (1 <= cause && cause <= 5)
+ printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
+
+ printk("PrId : %08x (%s)\n", read_c0_prid(),
+ cpu_name_string());
+}
+
+/*
+ * FIXME: really the generic show_regs should take a const pointer argument.
+ */
+void show_regs(struct pt_regs *regs)
+{
+ __show_regs((struct pt_regs *)regs);
+}
+
+void show_registers(struct pt_regs *regs)
+{
+ const int field = 2 * sizeof(unsigned long);
+
+ __show_regs(regs);
+ print_modules();
+ printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
+ current->comm, current->pid, current_thread_info(), current,
+ field, current_thread_info()->tp_value);
+ if (cpu_has_userlocal) {
+ unsigned long tls;
+
+ tls = read_c0_userlocal();
+ if (tls != current_thread_info()->tp_value)
+ printk("*HwTLS: %0*lx\n", field, tls);
+ }
+
+ show_stacktrace(current, regs);
+ show_code((unsigned int __user *) regs->cp0_epc);
+ printk("\n");
+}
+
+static int regs_to_trapnr(struct pt_regs *regs)
+{
+ return (regs->cp0_cause >> 2) & 0x1f;
+}
+
+static DEFINE_SPINLOCK(die_lock);
+
+void __noreturn die(const char *str, struct pt_regs *regs)
+{
+ static int die_counter;
+ int sig = SIGSEGV;
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned long dvpret = dvpe();
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP)
+ sig = 0;
+
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ bust_spinlocks(1);
+#ifdef CONFIG_MIPS_MT_SMTC
+ mips_mt_regdump(dvpret);
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ printk("%s[#%d]:\n", str, ++die_counter);
+ show_registers(regs);
+ add_taint(TAINT_DIE);
+ spin_unlock_irq(&die_lock);
+
+ if (in_interrupt())
+ panic("Fatal exception in interrupt");
+
+ if (panic_on_oops) {
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+ ssleep(5);
+ panic("Fatal exception");
+ }
+
+ do_exit(sig);
+}
+
+extern struct exception_table_entry __start___dbe_table[];
+extern struct exception_table_entry __stop___dbe_table[];
+
+__asm__(
+" .section __dbe_table, \"a\"\n"
+" .previous \n");
+
+/* Given an address, look for it in the exception tables. */
+static const struct exception_table_entry *search_dbe_tables(unsigned long addr)
+{
+ const struct exception_table_entry *e;
+
+ e = search_extable(__start___dbe_table, __stop___dbe_table - 1, addr);
+ if (!e)
+ e = search_module_dbetables(addr);
+ return e;
+}
+
+asmlinkage void do_be(struct pt_regs *regs)
+{
+ const int field = 2 * sizeof(unsigned long);
+ const struct exception_table_entry *fixup = NULL;
+ int data = regs->cp0_cause & 4;
+ int action = MIPS_BE_FATAL;
+
+ /* XXX For now. Fixme, this searches the wrong table ... */
+ if (data && !user_mode(regs))
+ fixup = search_dbe_tables(exception_epc(regs));
+
+ if (fixup)
+ action = MIPS_BE_FIXUP;
+
+ if (board_be_handler)
+ action = board_be_handler(regs, fixup != NULL);
+
+ switch (action) {
+ case MIPS_BE_DISCARD:
+ return;
+ case MIPS_BE_FIXUP:
+ if (fixup) {
+ regs->cp0_epc = fixup->nextinsn;
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Assume it would be too dangerous to continue ...
+ */
+ printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
+ data ? "Data" : "Instruction",
+ field, regs->cp0_epc, field, regs->regs[31]);
+ if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs), SIGBUS)
+ == NOTIFY_STOP)
+ return;
+
+ die_if_kernel("Oops", regs);
+ force_sig(SIGBUS, current);
+}
+
+/*
+ * ll/sc, rdhwr, sync emulation
+ */
+
+#define OPCODE 0xfc000000
+#define BASE 0x03e00000
+#define RT 0x001f0000
+#define OFFSET 0x0000ffff
+#define LL 0xc0000000
+#define SC 0xe0000000
+#define SPEC0 0x00000000
+#define SPEC3 0x7c000000
+#define RD 0x0000f800
+#define FUNC 0x0000003f
+#define SYNC 0x0000000f
+#define RDHWR 0x0000003b
+
+/*
+ * The ll_bit is cleared by r*_switch.S
+ */
+
+unsigned int ll_bit;
+struct task_struct *ll_task;
+
+static inline int simulate_ll(struct pt_regs *regs, unsigned int opcode)
+{
+ unsigned long value, __user *vaddr;
+ long offset;
+
+ /*
+ * analyse the ll instruction that just caused a ri exception
+ * and put the referenced address to addr.
+ */
+
+ /* sign extend offset */
+ offset = opcode & OFFSET;
+ offset <<= 16;
+ offset >>= 16;
+
+ vaddr = (unsigned long __user *)
+ ((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+
+ if ((unsigned long)vaddr & 3)
+ return SIGBUS;
+ if (get_user(value, vaddr))
+ return SIGSEGV;
+
+ preempt_disable();
+
+ if (ll_task == NULL || ll_task == current) {
+ ll_bit = 1;
+ } else {
+ ll_bit = 0;
+ }
+ ll_task = current;
+
+ preempt_enable();
+
+ regs->regs[(opcode & RT) >> 16] = value;
+
+ return 0;
+}
+
+static inline int simulate_sc(struct pt_regs *regs, unsigned int opcode)
+{
+ unsigned long __user *vaddr;
+ unsigned long reg;
+ long offset;
+
+ /*
+ * analyse the sc instruction that just caused a ri exception
+ * and put the referenced address to addr.
+ */
+
+ /* sign extend offset */
+ offset = opcode & OFFSET;
+ offset <<= 16;
+ offset >>= 16;
+
+ vaddr = (unsigned long __user *)
+ ((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
+ reg = (opcode & RT) >> 16;
+
+ if ((unsigned long)vaddr & 3)
+ return SIGBUS;
+
+ preempt_disable();
+
+ if (ll_bit == 0 || ll_task != current) {
+ regs->regs[reg] = 0;
+ preempt_enable();
+ return 0;
+ }
+
+ preempt_enable();
+
+ if (put_user(regs->regs[reg], vaddr))
+ return SIGSEGV;
+
+ regs->regs[reg] = 1;
+
+ return 0;
+}
+
+/*
+ * ll uses the opcode of lwc0 and sc uses the opcode of swc0. That is both
+ * opcodes are supposed to result in coprocessor unusable exceptions if
+ * executed on ll/sc-less processors. That's the theory. In practice a
+ * few processors such as NEC's VR4100 throw reserved instruction exceptions
+ * instead, so we're doing the emulation thing in both exception handlers.
+ */
+static int simulate_llsc(struct pt_regs *regs, unsigned int opcode)
+{
+ if ((opcode & OPCODE) == LL) {
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
+ return simulate_ll(regs, opcode);
+ }
+ if ((opcode & OPCODE) == SC) {
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
+ return simulate_sc(regs, opcode);
+ }
+
+ return -1; /* Must be something else ... */
+}
+
+/*
+ * Simulate trapping 'rdhwr' instructions to provide user accessible
+ * registers not implemented in hardware.
+ */
+static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode)
+{
+ struct thread_info *ti = task_thread_info(current);
+
+ if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
+ int rd = (opcode & RD) >> 11;
+ int rt = (opcode & RT) >> 16;
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
+ switch (rd) {
+ case 0: /* CPU number */
+ regs->regs[rt] = smp_processor_id();
+ return 0;
+ case 1: /* SYNCI length */
+ regs->regs[rt] = min(current_cpu_data.dcache.linesz,
+ current_cpu_data.icache.linesz);
+ return 0;
+ case 2: /* Read count register */
+ regs->regs[rt] = read_c0_count();
+ return 0;
+ case 3: /* Count register resolution */
+ switch (current_cpu_data.cputype) {
+ case CPU_20KC:
+ case CPU_25KF:
+ regs->regs[rt] = 1;
+ break;
+ default:
+ regs->regs[rt] = 2;
+ }
+ return 0;
+ case 29:
+ regs->regs[rt] = ti->tp_value;
+ return 0;
+ default:
+ return -1;
+ }
+ }
+
+ /* Not ours. */
+ return -1;
+}
+
+static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
+{
+ if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) {
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
+ return 0;
+ }
+
+ return -1; /* Must be something else ... */
+}
+
+asmlinkage void do_ov(struct pt_regs *regs)
+{
+ siginfo_t info;
+
+ die_if_kernel("Integer overflow", regs);
+
+ info.si_code = FPE_INTOVF;
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_addr = (void __user *) regs->cp0_epc;
+ force_sig_info(SIGFPE, &info, current);
+}
+
+static int process_fpemu_return(int sig, void __user *fault_addr)
+{
+ if (sig == SIGSEGV || sig == SIGBUS) {
+ struct siginfo si = {0};
+ si.si_addr = fault_addr;
+ si.si_signo = sig;
+ if (sig == SIGSEGV) {
+ if (find_vma(current->mm, (unsigned long)fault_addr))
+ si.si_code = SEGV_ACCERR;
+ else
+ si.si_code = SEGV_MAPERR;
+ } else {
+ si.si_code = BUS_ADRERR;
+ }
+ force_sig_info(sig, &si, current);
+ return 1;
+ } else if (sig) {
+ force_sig(sig, current);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
+ */
+asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
+{
+ siginfo_t info = {0};
+
+ if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
+ == NOTIFY_STOP)
+ return;
+ die_if_kernel("FP exception in kernel code", regs);
+
+ if (fcr31 & FPU_CSR_UNI_X) {
+ int sig;
+ void __user *fault_addr = NULL;
+
+ /*
+ * Unimplemented operation exception. If we've got the full
+ * software emulator on-board, let's use it...
+ *
+ * Force FPU to dump state into task/thread context. We're
+ * moving a lot of data here for what is probably a single
+ * instruction, but the alternative is to pre-decode the FP
+ * register operands before invoking the emulator, which seems
+ * a bit extreme for what should be an infrequent event.
+ */
+ /* Ensure 'resume' not overwrite saved fp context again. */
+ lose_fpu(1);
+
+ /* Run the emulator */
+ sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
+ &fault_addr);
+
+ /*
+ * We can't allow the emulated instruction to leave any of
+ * the cause bit set in $fcr31.
+ */
+ current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
+ /* Restore the hardware register state */
+ own_fpu(1); /* Using the FPU again. */
+
+ /* If something went wrong, signal */
+ process_fpemu_return(sig, fault_addr);
+
+ return;
+ } else if (fcr31 & FPU_CSR_INV_X)
+ info.si_code = FPE_FLTINV;
+ else if (fcr31 & FPU_CSR_DIV_X)
+ info.si_code = FPE_FLTDIV;
+ else if (fcr31 & FPU_CSR_OVF_X)
+ info.si_code = FPE_FLTOVF;
+ else if (fcr31 & FPU_CSR_UDF_X)
+ info.si_code = FPE_FLTUND;
+ else if (fcr31 & FPU_CSR_INE_X)
+ info.si_code = FPE_FLTRES;
+ else
+ info.si_code = __SI_FAULT;
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_addr = (void __user *) regs->cp0_epc;
+ force_sig_info(SIGFPE, &info, current);
+}
+
+static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
+ const char *str)
+{
+ siginfo_t info;
+ char b[40];
+
+#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
+ if (kgdb_ll_trap(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+ return;
+#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
+
+ if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+ return;
+
+ /*
+ * A short test says that IRIX 5.3 sends SIGTRAP for all trap
+ * insns, even for trap and break codes that indicate arithmetic
+ * failures. Weird ...
+ * But should we continue the brokenness??? --macro
+ */
+ switch (code) {
+ case BRK_OVERFLOW:
+ case BRK_DIVZERO:
+ scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
+ die_if_kernel(b, regs);
+ if (code == BRK_DIVZERO)
+ info.si_code = FPE_INTDIV;
+ else
+ info.si_code = FPE_INTOVF;
+ info.si_signo = SIGFPE;
+ info.si_errno = 0;
+ info.si_addr = (void __user *) regs->cp0_epc;
+ force_sig_info(SIGFPE, &info, current);
+ break;
+ case BRK_BUG:
+ die_if_kernel("Kernel bug detected", regs);
+ force_sig(SIGTRAP, current);
+ break;
+ case BRK_MEMU:
+ /*
+ * Address errors may be deliberately induced by the FPU
+ * emulator to retake control of the CPU after executing the
+ * instruction in the delay slot of an emulated branch.
+ *
+ * Terminate if exception was recognized as a delay slot return
+ * otherwise handle as normal.
+ */
+ if (do_dsemulret(regs))
+ return;
+
+ die_if_kernel("Math emu break/trap", regs);
+ force_sig(SIGTRAP, current);
+ break;
+ default:
+ scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
+ die_if_kernel(b, regs);
+ force_sig(SIGTRAP, current);
+ }
+}
+
+asmlinkage void do_bp(struct pt_regs *regs)
+{
+ unsigned int opcode, bcode;
+
+ if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
+ goto out_sigsegv;
+
+ /*
+ * There is the ancient bug in the MIPS assemblers that the break
+ * code starts left to bit 16 instead to bit 6 in the opcode.
+ * Gas is bug-compatible, but not always, grrr...
+ * We handle both cases with a simple heuristics. --macro
+ */
+ bcode = ((opcode >> 6) & ((1 << 20) - 1));
+ if (bcode >= (1 << 10))
+ bcode >>= 10;
+
+ /*
+ * notify the kprobe handlers, if instruction is likely to
+ * pertain to them.
+ */
+ switch (bcode) {
+ case BRK_KPROBE_BP:
+ if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+ return;
+ else
+ break;
+ case BRK_KPROBE_SSTEPBP:
+ if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
+ return;
+ else
+ break;
+ default:
+ break;
+ }
+
+ do_trap_or_bp(regs, bcode, "Break");
+ return;
+
+out_sigsegv:
+ force_sig(SIGSEGV, current);
+}
+
+asmlinkage void do_tr(struct pt_regs *regs)
+{
+ unsigned int opcode, tcode = 0;
+
+ if (__get_user(opcode, (unsigned int __user *) exception_epc(regs)))
+ goto out_sigsegv;
+
+ /* Immediate versions don't provide a code. */
+ if (!(opcode & OPCODE))
+ tcode = ((opcode >> 6) & ((1 << 10) - 1));
+
+ do_trap_or_bp(regs, tcode, "Trap");
+ return;
+
+out_sigsegv:
+ force_sig(SIGSEGV, current);
+}
+
+asmlinkage void do_ri(struct pt_regs *regs)
+{
+ unsigned int __user *epc = (unsigned int __user *)exception_epc(regs);
+ unsigned long old_epc = regs->cp0_epc;
+ unsigned int opcode = 0;
+ int status = -1;
+
+ if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), SIGILL)
+ == NOTIFY_STOP)
+ return;
+
+ die_if_kernel("Reserved instruction in kernel code", regs);
+
+ if (unlikely(compute_return_epc(regs) < 0))
+ return;
+
+ if (unlikely(get_user(opcode, epc) < 0))
+ status = SIGSEGV;
+
+ if (!cpu_has_llsc && status < 0)
+ status = simulate_llsc(regs, opcode);
+
+ if (status < 0)
+ status = simulate_rdhwr(regs, opcode);
+
+ if (status < 0)
+ status = simulate_sync(regs, opcode);
+
+ if (status < 0)
+ status = SIGILL;
+
+ if (unlikely(status > 0)) {
+ regs->cp0_epc = old_epc; /* Undo skip-over. */
+ force_sig(status, current);
+ }
+}
+
+/*
+ * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've
+ * emulated more than some threshold number of instructions, force migration to
+ * a "CPU" that has FP support.
+ */
+static void mt_ase_fp_affinity(void)
+{
+#ifdef CONFIG_MIPS_MT_FPAFF
+ if (mt_fpemul_threshold > 0 &&
+ ((current->thread.emulated_fp++ > mt_fpemul_threshold))) {
+ /*
+ * If there's no FPU present, or if the application has already
+ * restricted the allowed set to exclude any CPUs with FPUs,
+ * we'll skip the procedure.
+ */
+ if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) {
+ cpumask_t tmask;
+
+ current->thread.user_cpus_allowed
+ = current->cpus_allowed;
+ cpus_and(tmask, current->cpus_allowed,
+ mt_fpu_cpumask);
+ set_cpus_allowed_ptr(current, &tmask);
+ set_thread_flag(TIF_FPUBOUND);
+ }
+ }
+#endif /* CONFIG_MIPS_MT_FPAFF */
+}
+
+/*
+ * No lock; only written during early bootup by CPU 0.
+ */
+static RAW_NOTIFIER_HEAD(cu2_chain);
+
+int __ref register_cu2_notifier(struct notifier_block *nb)
+{
+ return raw_notifier_chain_register(&cu2_chain, nb);
+}
+
+int cu2_notifier_call_chain(unsigned long val, void *v)
+{
+ return raw_notifier_call_chain(&cu2_chain, val, v);
+}
+
+static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
+ void *data)
+{
+ struct pt_regs *regs = data;
+
+ switch (action) {
+ default:
+ die_if_kernel("Unhandled kernel unaligned access or invalid "
+ "instruction", regs);
+ /* Fall through */
+
+ case CU2_EXCEPTION:
+ force_sig(SIGILL, current);
+ }
+
+ return NOTIFY_OK;
+}
+
+asmlinkage void do_cpu(struct pt_regs *regs)
+{
+ unsigned int __user *epc;
+ unsigned long old_epc;
+ unsigned int opcode;
+ unsigned int cpid;
+ int status;
+ unsigned long __maybe_unused flags;
+
+ die_if_kernel("do_cpu invoked from kernel context!", regs);
+
+ cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
+
+ switch (cpid) {
+ case 0:
+ epc = (unsigned int __user *)exception_epc(regs);
+ old_epc = regs->cp0_epc;
+ opcode = 0;
+ status = -1;
+
+ if (unlikely(compute_return_epc(regs) < 0))
+ return;
+
+ if (unlikely(get_user(opcode, epc) < 0))
+ status = SIGSEGV;
+
+ if (!cpu_has_llsc && status < 0)
+ status = simulate_llsc(regs, opcode);
+
+ if (status < 0)
+ status = simulate_rdhwr(regs, opcode);
+
+ if (status < 0)
+ status = SIGILL;
+
+ if (unlikely(status > 0)) {
+ regs->cp0_epc = old_epc; /* Undo skip-over. */
+ force_sig(status, current);
+ }
+
+ return;
+
+ case 1:
+ if (used_math()) /* Using the FPU again. */
+ own_fpu(1);
+ else { /* First time FPU user. */
+ init_fpu();
+ set_used_math();
+ }
+
+ if (!raw_cpu_has_fpu) {
+ int sig;
+ void __user *fault_addr = NULL;
+ sig = fpu_emulator_cop1Handler(regs,
+ &current->thread.fpu,
+ 0, &fault_addr);
+ if (!process_fpemu_return(sig, fault_addr))
+ mt_ase_fp_affinity();
+ }
+
+ return;
+
+ case 2:
+ raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
+ return;
+
+ case 3:
+ break;
+ }
+
+ force_sig(SIGILL, current);
+}
+
+asmlinkage void do_mdmx(struct pt_regs *regs)
+{
+ force_sig(SIGILL, current);
+}
+
+/*
+ * Called with interrupts disabled.
+ */
+asmlinkage void do_watch(struct pt_regs *regs)
+{
+ u32 cause;
+
+ /*
+ * Clear WP (bit 22) bit of cause register so we don't loop
+ * forever.
+ */
+ cause = read_c0_cause();
+ cause &= ~(1 << 22);
+ write_c0_cause(cause);
+
+ /*
+ * If the current thread has the watch registers loaded, save
+ * their values and send SIGTRAP. Otherwise another thread
+ * left the registers set, clear them and continue.
+ */
+ if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) {
+ mips_read_watch_registers();
+ local_irq_enable();
+ force_sig(SIGTRAP, current);
+ } else {
+ mips_clear_watch_registers();
+ local_irq_enable();
+ }
+}
+
+asmlinkage void do_mcheck(struct pt_regs *regs)
+{
+ const int field = 2 * sizeof(unsigned long);
+ int multi_match = regs->cp0_status & ST0_TS;
+
+ show_regs(regs);
+
+ if (multi_match) {
+ printk("Index : %0x\n", read_c0_index());
+ printk("Pagemask: %0x\n", read_c0_pagemask());
+ printk("EntryHi : %0*lx\n", field, read_c0_entryhi());
+ printk("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
+ printk("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
+ printk("\n");
+ dump_tlb_all();
+ }
+
+ show_code((unsigned int __user *) regs->cp0_epc);
+
+ /*
+ * Some chips may have other causes of machine check (e.g. SB1
+ * graduation timer)
+ */
+ panic("Caught Machine Check exception - %scaused by multiple "
+ "matching entries in the TLB.",
+ (multi_match) ? "" : "not ");
+}
+
+asmlinkage void do_mt(struct pt_regs *regs)
+{
+ int subcode;
+
+ subcode = (read_vpe_c0_vpecontrol() & VPECONTROL_EXCPT)
+ >> VPECONTROL_EXCPT_SHIFT;
+ switch (subcode) {
+ case 0:
+ printk(KERN_DEBUG "Thread Underflow\n");
+ break;
+ case 1:
+ printk(KERN_DEBUG "Thread Overflow\n");
+ break;
+ case 2:
+ printk(KERN_DEBUG "Invalid YIELD Qualifier\n");
+ break;
+ case 3:
+ printk(KERN_DEBUG "Gating Storage Exception\n");
+ break;
+ case 4:
+ printk(KERN_DEBUG "YIELD Scheduler Exception\n");
+ break;
+ case 5:
+ printk(KERN_DEBUG "Gating Storage Schedulier Exception\n");
+ break;
+ default:
+ printk(KERN_DEBUG "*** UNKNOWN THREAD EXCEPTION %d ***\n",
+ subcode);
+ break;
+ }
+ die_if_kernel("MIPS MT Thread exception in kernel", regs);
+
+ force_sig(SIGILL, current);
+}
+
+
+asmlinkage void do_dsp(struct pt_regs *regs)
+{
+ if (cpu_has_dsp)
+ panic("Unexpected DSP exception\n");
+
+ force_sig(SIGILL, current);
+}
+
+asmlinkage void do_reserved(struct pt_regs *regs)
+{
+ /*
+ * Game over - no way to handle this if it ever occurs. Most probably
+ * caused by a new unknown cpu type or after another deadly
+ * hard/software error.
+ */
+ show_regs(regs);
+ panic("Caught reserved exception %ld - should not happen.",
+ (regs->cp0_cause & 0x7f) >> 2);
+}
+
+static int __initdata l1parity = 1;
+static int __init nol1parity(char *s)
+{
+ l1parity = 0;
+ return 1;
+}
+__setup("nol1par", nol1parity);
+static int __initdata l2parity = 1;
+static int __init nol2parity(char *s)
+{
+ l2parity = 0;
+ return 1;
+}
+__setup("nol2par", nol2parity);
+
+/*
+ * Some MIPS CPUs can enable/disable for cache parity detection, but do
+ * it different ways.
+ */
+static inline void parity_protection_init(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_24K:
+ case CPU_34K:
+ case CPU_74K:
+ case CPU_1004K:
+ {
+#define ERRCTL_PE 0x80000000
+#define ERRCTL_L2P 0x00800000
+ unsigned long errctl;
+ unsigned int l1parity_present, l2parity_present;
+
+ errctl = read_c0_ecc();
+ errctl &= ~(ERRCTL_PE|ERRCTL_L2P);
+
+ /* probe L1 parity support */
+ write_c0_ecc(errctl | ERRCTL_PE);
+ back_to_back_c0_hazard();
+ l1parity_present = (read_c0_ecc() & ERRCTL_PE);
+
+ /* probe L2 parity support */
+ write_c0_ecc(errctl|ERRCTL_L2P);
+ back_to_back_c0_hazard();
+ l2parity_present = (read_c0_ecc() & ERRCTL_L2P);
+
+ if (l1parity_present && l2parity_present) {
+ if (l1parity)
+ errctl |= ERRCTL_PE;
+ if (l1parity ^ l2parity)
+ errctl |= ERRCTL_L2P;
+ } else if (l1parity_present) {
+ if (l1parity)
+ errctl |= ERRCTL_PE;
+ } else if (l2parity_present) {
+ if (l2parity)
+ errctl |= ERRCTL_L2P;
+ } else {
+ /* No parity available */
+ }
+
+ printk(KERN_INFO "Writing ErrCtl register=%08lx\n", errctl);
+
+ write_c0_ecc(errctl);
+ back_to_back_c0_hazard();
+ errctl = read_c0_ecc();
+ printk(KERN_INFO "Readback ErrCtl register=%08lx\n", errctl);
+
+ if (l1parity_present)
+ printk(KERN_INFO "Cache parity protection %sabled\n",
+ (errctl & ERRCTL_PE) ? "en" : "dis");
+
+ if (l2parity_present) {
+ if (l1parity_present && l1parity)
+ errctl ^= ERRCTL_L2P;
+ printk(KERN_INFO "L2 cache parity protection %sabled\n",
+ (errctl & ERRCTL_L2P) ? "en" : "dis");
+ }
+ }
+ break;
+
+ case CPU_5KC:
+ write_c0_ecc(0x80000000);
+ back_to_back_c0_hazard();
+ /* Set the PE bit (bit 31) in the c0_errctl register. */
+ printk(KERN_INFO "Cache parity protection %sabled\n",
+ (read_c0_ecc() & 0x80000000) ? "en" : "dis");
+ break;
+ case CPU_20KC:
+ case CPU_25KF:
+ /* Clear the DE bit (bit 16) in the c0_status register. */
+ printk(KERN_INFO "Enable cache parity protection for "
+ "MIPS 20KC/25KF CPUs.\n");
+ clear_c0_status(ST0_DE);
+ break;
+ default:
+ break;
+ }
+}
+
+asmlinkage void cache_parity_error(void)
+{
+ const int field = 2 * sizeof(unsigned long);
+ unsigned int reg_val;
+
+ /* For the moment, report the problem and hang. */
+ printk("Cache error exception:\n");
+ printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
+ reg_val = read_c0_cacheerr();
+ printk("c0_cacheerr == %08x\n", reg_val);
+
+ printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
+ reg_val & (1<<30) ? "secondary" : "primary",
+ reg_val & (1<<31) ? "data" : "insn");
+ printk("Error bits: %s%s%s%s%s%s%s\n",
+ reg_val & (1<<29) ? "ED " : "",
+ reg_val & (1<<28) ? "ET " : "",
+ reg_val & (1<<26) ? "EE " : "",
+ reg_val & (1<<25) ? "EB " : "",
+ reg_val & (1<<24) ? "EI " : "",
+ reg_val & (1<<23) ? "E1 " : "",
+ reg_val & (1<<22) ? "E0 " : "");
+ printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
+
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ if (reg_val & (1<<22))
+ printk("DErrAddr0: 0x%0*lx\n", field, read_c0_derraddr0());
+
+ if (reg_val & (1<<23))
+ printk("DErrAddr1: 0x%0*lx\n", field, read_c0_derraddr1());
+#endif
+
+ panic("Can't handle the cache error!");
+}
+
+/*
+ * SDBBP EJTAG debug exception handler.
+ * We skip the instruction and return to the next instruction.
+ */
+void ejtag_exception_handler(struct pt_regs *regs)
+{
+ const int field = 2 * sizeof(unsigned long);
+ unsigned long depc, old_epc;
+ unsigned int debug;
+
+ printk(KERN_DEBUG "SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
+ depc = read_c0_depc();
+ debug = read_c0_debug();
+ printk(KERN_DEBUG "c0_depc = %0*lx, DEBUG = %08x\n", field, depc, debug);
+ if (debug & 0x80000000) {
+ /*
+ * In branch delay slot.
+ * We cheat a little bit here and use EPC to calculate the
+ * debug return address (DEPC). EPC is restored after the
+ * calculation.
+ */
+ old_epc = regs->cp0_epc;
+ regs->cp0_epc = depc;
+ __compute_return_epc(regs);
+ depc = regs->cp0_epc;
+ regs->cp0_epc = old_epc;
+ } else
+ depc += 4;
+ write_c0_depc(depc);
+
+#if 0
+ printk(KERN_DEBUG "\n\n----- Enable EJTAG single stepping ----\n\n");
+ write_c0_debug(debug | 0x100);
+#endif
+}
+
+/*
+ * NMI exception handler.
+ */
+NORET_TYPE void ATTRIB_NORET nmi_exception_handler(struct pt_regs *regs)
+{
+ bust_spinlocks(1);
+ printk("NMI taken!!!!\n");
+ die("NMI", regs);
+}
+
+#define VECTORSPACING 0x100 /* for EI/VI mode */
+
+unsigned long ebase;
+unsigned long exception_handlers[32];
+unsigned long vi_handlers[64];
+
+void __init *set_except_vector(int n, void *addr)
+{
+ unsigned long handler = (unsigned long) addr;
+ unsigned long old_handler = exception_handlers[n];
+
+ exception_handlers[n] = handler;
+ if (n == 0 && cpu_has_divec) {
+ unsigned long jump_mask = ~((1 << 28) - 1);
+ u32 *buf = (u32 *)(ebase + 0x200);
+ unsigned int k0 = 26;
+ if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) {
+ uasm_i_j(&buf, handler & ~jump_mask);
+ uasm_i_nop(&buf);
+ } else {
+ UASM_i_LA(&buf, k0, handler);
+ uasm_i_jr(&buf, k0);
+ uasm_i_nop(&buf);
+ }
+ local_flush_icache_range(ebase + 0x200, (unsigned long)buf);
+ }
+ return (void *)old_handler;
+}
+
+static asmlinkage void do_default_vi(void)
+{
+ show_regs(get_irq_regs());
+ panic("Caught unexpected vectored interrupt.");
+}
+
+static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
+{
+ unsigned long handler;
+ unsigned long old_handler = vi_handlers[n];
+ int srssets = current_cpu_data.srsets;
+ u32 *w;
+ unsigned char *b;
+
+ BUG_ON(!cpu_has_veic && !cpu_has_vint);
+
+ if (addr == NULL) {
+ handler = (unsigned long) do_default_vi;
+ srs = 0;
+ } else
+ handler = (unsigned long) addr;
+ vi_handlers[n] = (unsigned long) addr;
+
+ b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
+
+ if (srs >= srssets)
+ panic("Shadow register set %d not supported", srs);
+
+ if (cpu_has_veic) {
+ if (board_bind_eic_interrupt)
+ board_bind_eic_interrupt(n, srs);
+ } else if (cpu_has_vint) {
+ /* SRSMap is only defined if shadow sets are implemented */
+ if (srssets > 1)
+ change_c0_srsmap(0xf << n*4, srs << n*4);
+ }
+
+ if (srs == 0) {
+ /*
+ * If no shadow set is selected then use the default handler
+ * that does normal register saving and a standard interrupt exit
+ */
+
+ extern char except_vec_vi, except_vec_vi_lui;
+ extern char except_vec_vi_ori, except_vec_vi_end;
+ extern char rollback_except_vec_vi;
+ char *vec_start = (cpu_wait == r4k_wait) ?
+ &rollback_except_vec_vi : &except_vec_vi;
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * We need to provide the SMTC vectored interrupt handler
+ * not only with the address of the handler, but with the
+ * Status.IM bit to be masked before going there.
+ */
+ extern char except_vec_vi_mori;
+ const int mori_offset = &except_vec_vi_mori - vec_start;
+#endif /* CONFIG_MIPS_MT_SMTC */
+ const int handler_len = &except_vec_vi_end - vec_start;
+ const int lui_offset = &except_vec_vi_lui - vec_start;
+ const int ori_offset = &except_vec_vi_ori - vec_start;
+
+ if (handler_len > VECTORSPACING) {
+ /*
+ * Sigh... panicing won't help as the console
+ * is probably not configured :(
+ */
+ panic("VECTORSPACING too small");
+ }
+
+ memcpy(b, vec_start, handler_len);
+#ifdef CONFIG_MIPS_MT_SMTC
+ BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */
+
+ w = (u32 *)(b + mori_offset);
+ *w = (*w & 0xffff0000) | (0x100 << n);
+#endif /* CONFIG_MIPS_MT_SMTC */
+ w = (u32 *)(b + lui_offset);
+ *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff);
+ w = (u32 *)(b + ori_offset);
+ *w = (*w & 0xffff0000) | ((u32)handler & 0xffff);
+ local_flush_icache_range((unsigned long)b,
+ (unsigned long)(b+handler_len));
+ }
+ else {
+ /*
+ * In other cases jump directly to the interrupt handler
+ *
+ * It is the handlers responsibility to save registers if required
+ * (eg hi/lo) and return from the exception using "eret"
+ */
+ w = (u32 *)b;
+ *w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */
+ *w = 0;
+ local_flush_icache_range((unsigned long)b,
+ (unsigned long)(b+8));
+ }
+
+ return (void *)old_handler;
+}
+
+void *set_vi_handler(int n, vi_handler_t addr)
+{
+ return set_vi_srs_handler(n, addr, 0);
+}
+
+extern void cpu_cache_init(void);
+extern void tlb_init(void);
+extern void flush_tlb_handlers(void);
+
+/*
+ * Timer interrupt
+ */
+int cp0_compare_irq;
+int cp0_compare_irq_shift;
+
+/*
+ * Performance counter IRQ or -1 if shared with timer
+ */
+int cp0_perfcount_irq;
+EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
+
+static int __cpuinitdata noulri;
+
+static int __init ulri_disable(char *s)
+{
+ pr_info("Disabling ulri\n");
+ noulri = 1;
+
+ return 1;
+}
+__setup("noulri", ulri_disable);
+
+void __cpuinit per_cpu_trap_init(void)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned int status_set = ST0_CU0;
+ unsigned int hwrena = cpu_hwrena_impl_bits;
+#ifdef CONFIG_MIPS_MT_SMTC
+ int secondaryTC = 0;
+ int bootTC = (cpu == 0);
+
+ /*
+ * Only do per_cpu_trap_init() for first TC of Each VPE.
+ * Note that this hack assumes that the SMTC init code
+ * assigns TCs consecutively and in ascending order.
+ */
+
+ if (((read_c0_tcbind() & TCBIND_CURTC) != 0) &&
+ ((read_c0_tcbind() & TCBIND_CURVPE) == cpu_data[cpu - 1].vpe_id))
+ secondaryTC = 1;
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ /*
+ * Disable coprocessors and select 32-bit or 64-bit addressing
+ * and the 16/32 or 32/32 FPR register model. Reset the BEV
+ * flag that some firmware may have left set and the TS bit (for
+ * IP27). Set XX for ISA IV code to work.
+ */
+#ifdef CONFIG_64BIT
+ status_set |= ST0_FR|ST0_KX|ST0_SX|ST0_UX;
+#endif
+ if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV)
+ status_set |= ST0_XX;
+ if (cpu_has_dsp)
+ status_set |= ST0_MX;
+
+ change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
+ status_set);
+
+ if (cpu_has_mips_r2)
+ hwrena |= 0x0000000f;
+
+ if (!noulri && cpu_has_userlocal)
+ hwrena |= (1 << 29);
+
+ if (hwrena)
+ write_c0_hwrena(hwrena);
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ if (!secondaryTC) {
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ if (cpu_has_veic || cpu_has_vint) {
+ unsigned long sr = set_c0_status(ST0_BEV);
+ write_c0_ebase(ebase);
+ write_c0_status(sr);
+ /* Setting vector spacing enables EI/VI mode */
+ change_c0_intctl(0x3e0, VECTORSPACING);
+ }
+ if (cpu_has_divec) {
+ if (cpu_has_mipsmt) {
+ unsigned int vpflags = dvpe();
+ set_c0_cause(CAUSEF_IV);
+ evpe(vpflags);
+ } else
+ set_c0_cause(CAUSEF_IV);
+ }
+
+ /*
+ * Before R2 both interrupt numbers were fixed to 7, so on R2 only:
+ *
+ * o read IntCtl.IPTI to determine the timer interrupt
+ * o read IntCtl.IPPCI to determine the performance counter interrupt
+ */
+ if (cpu_has_mips_r2) {
+ cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
+ cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
+ cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
+ if (cp0_perfcount_irq == cp0_compare_irq)
+ cp0_perfcount_irq = -1;
+ } else {
+ cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
+ cp0_compare_irq_shift = cp0_compare_irq;
+ cp0_perfcount_irq = -1;
+ }
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ }
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+ cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
+
+ atomic_inc(&init_mm.mm_count);
+ current->active_mm = &init_mm;
+ BUG_ON(current->mm);
+ enter_lazy_tlb(&init_mm, current);
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ if (bootTC) {
+#endif /* CONFIG_MIPS_MT_SMTC */
+ cpu_cache_init();
+ tlb_init();
+#ifdef CONFIG_MIPS_MT_SMTC
+ } else if (!secondaryTC) {
+ /*
+ * First TC in non-boot VPE must do subset of tlb_init()
+ * for MMU countrol registers.
+ */
+ write_c0_pagemask(PM_DEFAULT_MASK);
+ write_c0_wired(0);
+ }
+#endif /* CONFIG_MIPS_MT_SMTC */
+ TLBMISS_HANDLER_SETUP();
+}
+
+/* Install CPU exception handler */
+void __init set_handler(unsigned long offset, void *addr, unsigned long size)
+{
+ memcpy((void *)(ebase + offset), addr, size);
+ local_flush_icache_range(ebase + offset, ebase + offset + size);
+}
+
+static char panic_null_cerr[] __cpuinitdata =
+ "Trying to set NULL cache error exception handler";
+
+/*
+ * Install uncached CPU exception handler.
+ * This is suitable only for the cache error exception which is the only
+ * exception handler that is being run uncached.
+ */
+void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
+ unsigned long size)
+{
+ unsigned long uncached_ebase = CKSEG1ADDR(ebase);
+
+ if (!addr)
+ panic(panic_null_cerr);
+
+ memcpy((void *)(uncached_ebase + offset), addr, size);
+}
+
+static int __initdata rdhwr_noopt;
+static int __init set_rdhwr_noopt(char *str)
+{
+ rdhwr_noopt = 1;
+ return 1;
+}
+
+__setup("rdhwr_noopt", set_rdhwr_noopt);
+
+void __init trap_init(void)
+{
+ extern char except_vec3_generic, except_vec3_r4000;
+ extern char except_vec4;
+ unsigned long i;
+ int rollback;
+
+ check_wait();
+ rollback = (cpu_wait == r4k_wait);
+
+#if defined(CONFIG_KGDB)
+ if (kgdb_early_setup)
+ return; /* Already done */
+#endif
+
+ if (cpu_has_veic || cpu_has_vint) {
+ unsigned long size = 0x200 + VECTORSPACING*64;
+ ebase = (unsigned long)
+ __alloc_bootmem(size, 1 << fls(size), 0);
+ } else {
+ ebase = CKSEG0;
+ if (cpu_has_mips_r2)
+ ebase += (read_c0_ebase() & 0x3ffff000);
+ }
+
+ per_cpu_trap_init();
+
+ /*
+ * Copy the generic exception handlers to their final destination.
+ * This will be overriden later as suitable for a particular
+ * configuration.
+ */
+ set_handler(0x180, &except_vec3_generic, 0x80);
+
+ /*
+ * Setup default vectors
+ */
+ for (i = 0; i <= 31; i++)
+ set_except_vector(i, handle_reserved);
+
+ /*
+ * Copy the EJTAG debug exception vector handler code to it's final
+ * destination.
+ */
+ if (cpu_has_ejtag && board_ejtag_handler_setup)
+ board_ejtag_handler_setup();
+
+ /*
+ * Only some CPUs have the watch exceptions.
+ */
+ if (cpu_has_watch)
+ set_except_vector(23, handle_watch);
+
+ /*
+ * Initialise interrupt handlers
+ */
+ if (cpu_has_veic || cpu_has_vint) {
+ int nvec = cpu_has_veic ? 64 : 8;
+ for (i = 0; i < nvec; i++)
+ set_vi_handler(i, NULL);
+ }
+ else if (cpu_has_divec)
+ set_handler(0x200, &except_vec4, 0x8);
+
+ /*
+ * Some CPUs can enable/disable for cache parity detection, but does
+ * it different ways.
+ */
+ parity_protection_init();
+
+ /*
+ * The Data Bus Errors / Instruction Bus Errors are signaled
+ * by external hardware. Therefore these two exceptions
+ * may have board specific handlers.
+ */
+ if (board_be_init)
+ board_be_init();
+
+ set_except_vector(0, rollback ? rollback_handle_int : handle_int);
+ set_except_vector(1, handle_tlbm);
+ set_except_vector(2, handle_tlbl);
+ set_except_vector(3, handle_tlbs);
+
+ set_except_vector(4, handle_adel);
+ set_except_vector(5, handle_ades);
+
+ set_except_vector(6, handle_ibe);
+ set_except_vector(7, handle_dbe);
+
+ set_except_vector(8, handle_sys);
+ set_except_vector(9, handle_bp);
+ set_except_vector(10, rdhwr_noopt ? handle_ri :
+ (cpu_has_vtag_icache ?
+ handle_ri_rdhwr_vivt : handle_ri_rdhwr));
+ set_except_vector(11, handle_cpu);
+ set_except_vector(12, handle_ov);
+ set_except_vector(13, handle_tr);
+
+ if (current_cpu_type() == CPU_R6000 ||
+ current_cpu_type() == CPU_R6000A) {
+ /*
+ * The R6000 is the only R-series CPU that features a machine
+ * check exception (similar to the R4000 cache error) and
+ * unaligned ldc1/sdc1 exception. The handlers have not been
+ * written yet. Well, anyway there is no R6000 machine on the
+ * current list of targets for Linux/MIPS.
+ * (Duh, crap, there is someone with a triple R6k machine)
+ */
+ //set_except_vector(14, handle_mc);
+ //set_except_vector(15, handle_ndc);
+ }
+
+
+ if (board_nmi_handler_setup)
+ board_nmi_handler_setup();
+
+ if (cpu_has_fpu && !cpu_has_nofpuex)
+ set_except_vector(15, handle_fpe);
+
+ set_except_vector(22, handle_mdmx);
+
+ if (cpu_has_mcheck)
+ set_except_vector(24, handle_mcheck);
+
+ if (cpu_has_mipsmt)
+ set_except_vector(25, handle_mt);
+
+ set_except_vector(26, handle_dsp);
+
+ if (cpu_has_vce)
+ /* Special exception: R4[04]00 uses also the divec space. */
+ memcpy((void *)(ebase + 0x180), &except_vec3_r4000, 0x100);
+ else if (cpu_has_4kex)
+ memcpy((void *)(ebase + 0x180), &except_vec3_generic, 0x80);
+ else
+ memcpy((void *)(ebase + 0x080), &except_vec3_generic, 0x80);
+
+ local_flush_icache_range(ebase, ebase + 0x400);
+ flush_tlb_handlers();
+
+ sort_extable(__start___dbe_table, __stop___dbe_table);
+
+ cu2_notifier(default_cu2_call, 0x80000000); /* Run last */
+}
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c
new file mode 100644
index 00000000..cfea1adf
--- /dev/null
+++ b/arch/mips/kernel/unaligned.c
@@ -0,0 +1,576 @@
+/*
+ * Handle unaligned accesses by emulation.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1998, 1999, 2002 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * This file contains exception handler for address error exception with the
+ * special capability to execute faulting instructions in software. The
+ * handler does not try to handle the case when the program counter points
+ * to an address not aligned to a word boundary.
+ *
+ * Putting data to unaligned addresses is a bad practice even on Intel where
+ * only the performance is affected. Much worse is that such code is non-
+ * portable. Due to several programs that die on MIPS due to alignment
+ * problems I decided to implement this handler anyway though I originally
+ * didn't intend to do this at all for user code.
+ *
+ * For now I enable fixing of address errors by default to make life easier.
+ * I however intend to disable this somewhen in the future when the alignment
+ * problems with user programs have been fixed. For programmers this is the
+ * right way to go.
+ *
+ * Fixing address errors is a per process option. The option is inherited
+ * across fork(2) and execve(2) calls. If you really want to use the
+ * option in your user programs - I discourage the use of the software
+ * emulation strongly - use the following code in your userland stuff:
+ *
+ * #include <sys/sysmips.h>
+ *
+ * ...
+ * sysmips(MIPS_FIXADE, x);
+ * ...
+ *
+ * The argument x is 0 for disabling software emulation, enabled otherwise.
+ *
+ * Below a little program to play around with this feature.
+ *
+ * #include <stdio.h>
+ * #include <sys/sysmips.h>
+ *
+ * struct foo {
+ * unsigned char bar[8];
+ * };
+ *
+ * main(int argc, char *argv[])
+ * {
+ * struct foo x = {0, 1, 2, 3, 4, 5, 6, 7};
+ * unsigned int *p = (unsigned int *) (x.bar + 3);
+ * int i;
+ *
+ * if (argc > 1)
+ * sysmips(MIPS_FIXADE, atoi(argv[1]));
+ *
+ * printf("*p = %08lx\n", *p);
+ *
+ * *p = 0xdeadface;
+ *
+ * for(i = 0; i <= 7; i++)
+ * printf("%02x ", x.bar[i]);
+ * printf("\n");
+ * }
+ *
+ * Coprocessor loads are not supported; I think this case is unimportant
+ * in the practice.
+ *
+ * TODO: Handle ndc (attempted store to doubleword in uncached memory)
+ * exception for the R6000.
+ * A store crossing a page boundary might be executed only partially.
+ * Undo the partial store in this case.
+ */
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/debugfs.h>
+#include <linux/perf_event.h>
+
+#include <asm/asm.h>
+#include <asm/branch.h>
+#include <asm/byteorder.h>
+#include <asm/cop2.h>
+#include <asm/inst.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#define STR(x) __STR(x)
+#define __STR(x) #x
+
+enum {
+ UNALIGNED_ACTION_QUIET,
+ UNALIGNED_ACTION_SIGNAL,
+ UNALIGNED_ACTION_SHOW,
+};
+#ifdef CONFIG_DEBUG_FS
+static u32 unaligned_instructions;
+static u32 unaligned_action;
+#else
+#define unaligned_action UNALIGNED_ACTION_QUIET
+#endif
+extern void show_registers(struct pt_regs *regs);
+
+static void emulate_load_store_insn(struct pt_regs *regs,
+ void __user *addr, unsigned int __user *pc)
+{
+ union mips_instruction insn;
+ unsigned long value;
+ unsigned int res;
+
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, regs, 0);
+
+ /*
+ * This load never faults.
+ */
+ __get_user(insn.word, pc);
+
+ switch (insn.i_format.opcode) {
+ /*
+ * These are instructions that a compiler doesn't generate. We
+ * can assume therefore that the code is MIPS-aware and
+ * really buggy. Emulating these instructions would break the
+ * semantics anyway.
+ */
+ case ll_op:
+ case lld_op:
+ case sc_op:
+ case scd_op:
+
+ /*
+ * For these instructions the only way to create an address
+ * error is an attempted access to kernel/supervisor address
+ * space.
+ */
+ case ldl_op:
+ case ldr_op:
+ case lwl_op:
+ case lwr_op:
+ case sdl_op:
+ case sdr_op:
+ case swl_op:
+ case swr_op:
+ case lb_op:
+ case lbu_op:
+ case sb_op:
+ goto sigbus;
+
+ /*
+ * The remaining opcodes are the ones that are really of interest.
+ */
+ case lh_op:
+ if (!access_ok(VERIFY_READ, addr, 2))
+ goto sigbus;
+
+ __asm__ __volatile__ (".set\tnoat\n"
+#ifdef __BIG_ENDIAN
+ "1:\tlb\t%0, 0(%2)\n"
+ "2:\tlbu\t$1, 1(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tlb\t%0, 1(%2)\n"
+ "2:\tlbu\t$1, 0(%2)\n\t"
+#endif
+ "sll\t%0, 0x8\n\t"
+ "or\t%0, $1\n\t"
+ "li\t%1, 0\n"
+ "3:\t.set\tat\n\t"
+ ".section\t.fixup,\"ax\"\n\t"
+ "4:\tli\t%1, %3\n\t"
+ "j\t3b\n\t"
+ ".previous\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b, 4b\n\t"
+ STR(PTR)"\t2b, 4b\n\t"
+ ".previous"
+ : "=&r" (value), "=r" (res)
+ : "r" (addr), "i" (-EFAULT));
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ regs->regs[insn.i_format.rt] = value;
+ break;
+
+ case lw_op:
+ if (!access_ok(VERIFY_READ, addr, 4))
+ goto sigbus;
+
+ __asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+ "1:\tlwl\t%0, (%2)\n"
+ "2:\tlwr\t%0, 3(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tlwl\t%0, 3(%2)\n"
+ "2:\tlwr\t%0, (%2)\n\t"
+#endif
+ "li\t%1, 0\n"
+ "3:\t.section\t.fixup,\"ax\"\n\t"
+ "4:\tli\t%1, %3\n\t"
+ "j\t3b\n\t"
+ ".previous\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b, 4b\n\t"
+ STR(PTR)"\t2b, 4b\n\t"
+ ".previous"
+ : "=&r" (value), "=r" (res)
+ : "r" (addr), "i" (-EFAULT));
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ regs->regs[insn.i_format.rt] = value;
+ break;
+
+ case lhu_op:
+ if (!access_ok(VERIFY_READ, addr, 2))
+ goto sigbus;
+
+ __asm__ __volatile__ (
+ ".set\tnoat\n"
+#ifdef __BIG_ENDIAN
+ "1:\tlbu\t%0, 0(%2)\n"
+ "2:\tlbu\t$1, 1(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tlbu\t%0, 1(%2)\n"
+ "2:\tlbu\t$1, 0(%2)\n\t"
+#endif
+ "sll\t%0, 0x8\n\t"
+ "or\t%0, $1\n\t"
+ "li\t%1, 0\n"
+ "3:\t.set\tat\n\t"
+ ".section\t.fixup,\"ax\"\n\t"
+ "4:\tli\t%1, %3\n\t"
+ "j\t3b\n\t"
+ ".previous\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b, 4b\n\t"
+ STR(PTR)"\t2b, 4b\n\t"
+ ".previous"
+ : "=&r" (value), "=r" (res)
+ : "r" (addr), "i" (-EFAULT));
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ regs->regs[insn.i_format.rt] = value;
+ break;
+
+ case lwu_op:
+#ifdef CONFIG_64BIT
+ /*
+ * A 32-bit kernel might be running on a 64-bit processor. But
+ * if we're on a 32-bit processor and an i-cache incoherency
+ * or race makes us see a 64-bit instruction here the sdl/sdr
+ * would blow up, so for now we don't handle unaligned 64-bit
+ * instructions on 32-bit kernels.
+ */
+ if (!access_ok(VERIFY_READ, addr, 4))
+ goto sigbus;
+
+ __asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+ "1:\tlwl\t%0, (%2)\n"
+ "2:\tlwr\t%0, 3(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tlwl\t%0, 3(%2)\n"
+ "2:\tlwr\t%0, (%2)\n\t"
+#endif
+ "dsll\t%0, %0, 32\n\t"
+ "dsrl\t%0, %0, 32\n\t"
+ "li\t%1, 0\n"
+ "3:\t.section\t.fixup,\"ax\"\n\t"
+ "4:\tli\t%1, %3\n\t"
+ "j\t3b\n\t"
+ ".previous\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b, 4b\n\t"
+ STR(PTR)"\t2b, 4b\n\t"
+ ".previous"
+ : "=&r" (value), "=r" (res)
+ : "r" (addr), "i" (-EFAULT));
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ regs->regs[insn.i_format.rt] = value;
+ break;
+#endif /* CONFIG_64BIT */
+
+ /* Cannot handle 64-bit instructions in 32-bit kernel */
+ goto sigill;
+
+ case ld_op:
+#ifdef CONFIG_64BIT
+ /*
+ * A 32-bit kernel might be running on a 64-bit processor. But
+ * if we're on a 32-bit processor and an i-cache incoherency
+ * or race makes us see a 64-bit instruction here the sdl/sdr
+ * would blow up, so for now we don't handle unaligned 64-bit
+ * instructions on 32-bit kernels.
+ */
+ if (!access_ok(VERIFY_READ, addr, 8))
+ goto sigbus;
+
+ __asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+ "1:\tldl\t%0, (%2)\n"
+ "2:\tldr\t%0, 7(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tldl\t%0, 7(%2)\n"
+ "2:\tldr\t%0, (%2)\n\t"
+#endif
+ "li\t%1, 0\n"
+ "3:\t.section\t.fixup,\"ax\"\n\t"
+ "4:\tli\t%1, %3\n\t"
+ "j\t3b\n\t"
+ ".previous\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b, 4b\n\t"
+ STR(PTR)"\t2b, 4b\n\t"
+ ".previous"
+ : "=&r" (value), "=r" (res)
+ : "r" (addr), "i" (-EFAULT));
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ regs->regs[insn.i_format.rt] = value;
+ break;
+#endif /* CONFIG_64BIT */
+
+ /* Cannot handle 64-bit instructions in 32-bit kernel */
+ goto sigill;
+
+ case sh_op:
+ if (!access_ok(VERIFY_WRITE, addr, 2))
+ goto sigbus;
+
+ value = regs->regs[insn.i_format.rt];
+ __asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+ ".set\tnoat\n"
+ "1:\tsb\t%1, 1(%2)\n\t"
+ "srl\t$1, %1, 0x8\n"
+ "2:\tsb\t$1, 0(%2)\n\t"
+ ".set\tat\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ ".set\tnoat\n"
+ "1:\tsb\t%1, 0(%2)\n\t"
+ "srl\t$1,%1, 0x8\n"
+ "2:\tsb\t$1, 1(%2)\n\t"
+ ".set\tat\n\t"
+#endif
+ "li\t%0, 0\n"
+ "3:\n\t"
+ ".section\t.fixup,\"ax\"\n\t"
+ "4:\tli\t%0, %3\n\t"
+ "j\t3b\n\t"
+ ".previous\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b, 4b\n\t"
+ STR(PTR)"\t2b, 4b\n\t"
+ ".previous"
+ : "=r" (res)
+ : "r" (value), "r" (addr), "i" (-EFAULT));
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ break;
+
+ case sw_op:
+ if (!access_ok(VERIFY_WRITE, addr, 4))
+ goto sigbus;
+
+ value = regs->regs[insn.i_format.rt];
+ __asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+ "1:\tswl\t%1,(%2)\n"
+ "2:\tswr\t%1, 3(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tswl\t%1, 3(%2)\n"
+ "2:\tswr\t%1, (%2)\n\t"
+#endif
+ "li\t%0, 0\n"
+ "3:\n\t"
+ ".section\t.fixup,\"ax\"\n\t"
+ "4:\tli\t%0, %3\n\t"
+ "j\t3b\n\t"
+ ".previous\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b, 4b\n\t"
+ STR(PTR)"\t2b, 4b\n\t"
+ ".previous"
+ : "=r" (res)
+ : "r" (value), "r" (addr), "i" (-EFAULT));
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ break;
+
+ case sd_op:
+#ifdef CONFIG_64BIT
+ /*
+ * A 32-bit kernel might be running on a 64-bit processor. But
+ * if we're on a 32-bit processor and an i-cache incoherency
+ * or race makes us see a 64-bit instruction here the sdl/sdr
+ * would blow up, so for now we don't handle unaligned 64-bit
+ * instructions on 32-bit kernels.
+ */
+ if (!access_ok(VERIFY_WRITE, addr, 8))
+ goto sigbus;
+
+ value = regs->regs[insn.i_format.rt];
+ __asm__ __volatile__ (
+#ifdef __BIG_ENDIAN
+ "1:\tsdl\t%1,(%2)\n"
+ "2:\tsdr\t%1, 7(%2)\n\t"
+#endif
+#ifdef __LITTLE_ENDIAN
+ "1:\tsdl\t%1, 7(%2)\n"
+ "2:\tsdr\t%1, (%2)\n\t"
+#endif
+ "li\t%0, 0\n"
+ "3:\n\t"
+ ".section\t.fixup,\"ax\"\n\t"
+ "4:\tli\t%0, %3\n\t"
+ "j\t3b\n\t"
+ ".previous\n\t"
+ ".section\t__ex_table,\"a\"\n\t"
+ STR(PTR)"\t1b, 4b\n\t"
+ STR(PTR)"\t2b, 4b\n\t"
+ ".previous"
+ : "=r" (res)
+ : "r" (value), "r" (addr), "i" (-EFAULT));
+ if (res)
+ goto fault;
+ compute_return_epc(regs);
+ break;
+#endif /* CONFIG_64BIT */
+
+ /* Cannot handle 64-bit instructions in 32-bit kernel */
+ goto sigill;
+
+ case lwc1_op:
+ case ldc1_op:
+ case swc1_op:
+ case sdc1_op:
+ /*
+ * I herewith declare: this does not happen. So send SIGBUS.
+ */
+ goto sigbus;
+
+ /*
+ * COP2 is available to implementor for application specific use.
+ * It's up to applications to register a notifier chain and do
+ * whatever they have to do, including possible sending of signals.
+ */
+ case lwc2_op:
+ cu2_notifier_call_chain(CU2_LWC2_OP, regs);
+ break;
+
+ case ldc2_op:
+ cu2_notifier_call_chain(CU2_LDC2_OP, regs);
+ break;
+
+ case swc2_op:
+ cu2_notifier_call_chain(CU2_SWC2_OP, regs);
+ break;
+
+ case sdc2_op:
+ cu2_notifier_call_chain(CU2_SDC2_OP, regs);
+ break;
+
+ default:
+ /*
+ * Pheeee... We encountered an yet unknown instruction or
+ * cache coherence problem. Die sucker, die ...
+ */
+ goto sigill;
+ }
+
+#ifdef CONFIG_DEBUG_FS
+ unaligned_instructions++;
+#endif
+
+ return;
+
+fault:
+ /* Did we have an exception handler installed? */
+ if (fixup_exception(regs))
+ return;
+
+ die_if_kernel("Unhandled kernel unaligned access", regs);
+ force_sig(SIGSEGV, current);
+
+ return;
+
+sigbus:
+ die_if_kernel("Unhandled kernel unaligned access", regs);
+ force_sig(SIGBUS, current);
+
+ return;
+
+sigill:
+ die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs);
+ force_sig(SIGILL, current);
+}
+
+asmlinkage void do_ade(struct pt_regs *regs)
+{
+ unsigned int __user *pc;
+ mm_segment_t seg;
+
+ perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
+ 1, 0, regs, regs->cp0_badvaddr);
+ /*
+ * Did we catch a fault trying to load an instruction?
+ * Or are we running in MIPS16 mode?
+ */
+ if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1))
+ goto sigbus;
+
+ pc = (unsigned int __user *) exception_epc(regs);
+ if (user_mode(regs) && !test_thread_flag(TIF_FIXADE))
+ goto sigbus;
+ if (unaligned_action == UNALIGNED_ACTION_SIGNAL)
+ goto sigbus;
+ else if (unaligned_action == UNALIGNED_ACTION_SHOW)
+ show_registers(regs);
+
+ /*
+ * Do branch emulation only if we didn't forward the exception.
+ * This is all so but ugly ...
+ */
+ seg = get_fs();
+ if (!user_mode(regs))
+ set_fs(KERNEL_DS);
+ emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc);
+ set_fs(seg);
+
+ return;
+
+sigbus:
+ die_if_kernel("Kernel unaligned instruction access", regs);
+ force_sig(SIGBUS, current);
+
+ /*
+ * XXX On return from the signal handler we should advance the epc
+ */
+}
+
+#ifdef CONFIG_DEBUG_FS
+extern struct dentry *mips_debugfs_dir;
+static int __init debugfs_unaligned(void)
+{
+ struct dentry *d;
+
+ if (!mips_debugfs_dir)
+ return -ENODEV;
+ d = debugfs_create_u32("unaligned_instructions", S_IRUGO,
+ mips_debugfs_dir, &unaligned_instructions);
+ if (!d)
+ return -ENOMEM;
+ d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR,
+ mips_debugfs_dir, &unaligned_action);
+ if (!d)
+ return -ENOMEM;
+ return 0;
+}
+__initcall(debugfs_unaligned);
+#endif
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
new file mode 100644
index 00000000..e5cdfd60
--- /dev/null
+++ b/arch/mips/kernel/vdso.c
@@ -0,0 +1,110 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, 2010 Cavium Networks, Inc.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+
+#include <asm/vdso.h>
+#include <asm/uasm.h>
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_sigreturn 4119
+#define __NR_O32_rt_sigreturn 4193
+#define __NR_N32_rt_sigreturn 6211
+
+static struct page *vdso_page;
+
+static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+{
+ uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */
+ uasm_i_syscall(&tramp, 0);
+}
+
+static int __init init_vdso(void)
+{
+ struct mips_vdso *vdso;
+
+ vdso_page = alloc_page(GFP_KERNEL);
+ if (!vdso_page)
+ panic("Cannot allocate vdso");
+
+ vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
+ if (!vdso)
+ panic("Cannot map vdso");
+ clear_page(vdso);
+
+ install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
+#ifdef CONFIG_32BIT
+ install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
+#else
+ install_trampoline(vdso->n32_rt_signal_trampoline,
+ __NR_N32_rt_sigreturn);
+ install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
+ install_trampoline(vdso->o32_rt_signal_trampoline,
+ __NR_O32_rt_sigreturn);
+#endif
+
+ vunmap(vdso);
+
+ return 0;
+}
+subsys_initcall(init_vdso);
+
+static unsigned long vdso_addr(unsigned long start)
+{
+ return STACK_TOP;
+}
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+ int ret;
+ unsigned long addr;
+ struct mm_struct *mm = current->mm;
+
+ down_write(&mm->mmap_sem);
+
+ addr = vdso_addr(mm->start_stack);
+
+ addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
+ if (IS_ERR_VALUE(addr)) {
+ ret = addr;
+ goto up_fail;
+ }
+
+ ret = install_special_mapping(mm, addr, PAGE_SIZE,
+ VM_READ|VM_EXEC|
+ VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+ VM_ALWAYSDUMP,
+ &vdso_page);
+
+ if (ret)
+ goto up_fail;
+
+ mm->context.vdso = (void *)addr;
+
+up_fail:
+ up_write(&mm->mmap_sem);
+ return ret;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
+ return "[vdso]";
+ return NULL;
+}
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
new file mode 100644
index 00000000..a81176f4
--- /dev/null
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -0,0 +1,165 @@
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm-generic/vmlinux.lds.h>
+
+#undef mips
+#define mips mips
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+PHDRS {
+ text PT_LOAD FLAGS(7); /* RWX */
+ note PT_NOTE FLAGS(4); /* R__ */
+}
+
+#ifdef CONFIG_32BIT
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
+ jiffies = jiffies_64;
+ #else
+ jiffies = jiffies_64 + 4;
+ #endif
+#else
+ jiffies = jiffies_64;
+#endif
+
+SECTIONS
+{
+#ifdef CONFIG_BOOT_ELF64
+ /* Read-only sections, merged into text segment: */
+ /* . = 0xc000000000000000; */
+
+ /* This is the value for an Origin kernel, taken from an IRIX kernel. */
+ /* . = 0xc00000000001c000; */
+
+ /* Set the vaddr for the text segment to a value
+ * >= 0xa800 0000 0001 9000 if no symmon is going to configured
+ * >= 0xa800 0000 0030 0000 otherwise
+ */
+
+ /* . = 0xa800000000300000; */
+ . = 0xffffffff80300000;
+#endif
+ . = VMLINUX_LOAD_ADDRESS;
+ /* read-only */
+ _text = .; /* Text and read-only data */
+ .text : {
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+ IRQENTRY_TEXT
+ *(.text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ } :text = 0
+ _etext = .; /* End of text section */
+
+ EXCEPTION_TABLE(16)
+
+ /* Exception table for data bus errors */
+ __dbe_table : {
+ __start___dbe_table = .;
+ *(__dbe_table)
+ __stop___dbe_table = .;
+ }
+
+ NOTES :text :note
+ .dummy : { *(.dummy) } :text
+
+ _sdata = .; /* Start of data section */
+ RODATA
+
+ /* writeable */
+ _sdata = .; /* Start of data section */
+ .data : { /* Data */
+ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */
+
+ INIT_TASK_DATA(PAGE_SIZE)
+ NOSAVE_DATA
+ CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
+ READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
+ DATA_DATA
+ CONSTRUCTORS
+ }
+ _gp = . + 0x8000;
+ .lit8 : {
+ *(.lit8)
+ }
+ .lit4 : {
+ *(.lit4)
+ }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : {
+ *(.sdata)
+ }
+ _edata = .; /* End of data section */
+
+ /* will be freed after init */
+ . = ALIGN(PAGE_SIZE); /* Init code and data */
+ __init_begin = .;
+ INIT_TEXT_SECTION(PAGE_SIZE)
+ INIT_DATA_SECTION(16)
+
+ . = ALIGN(4);
+ .mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) {
+ __mips_machines_start = .;
+ *(.mips.machines.init)
+ __mips_machines_end = .;
+ }
+
+ /* .exit.text is discarded at runtime, not link time, to deal with
+ * references from .rodata
+ */
+ .exit.text : {
+ EXIT_TEXT
+ }
+ .exit.data : {
+ EXIT_DATA
+ }
+
+ PERCPU_SECTION(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
+ . = ALIGN(PAGE_SIZE);
+ __init_end = .;
+ /* freed after init ends here */
+
+ BSS_SECTION(0, 0, 0)
+
+ _end = . ;
+
+ /* These mark the ABI of the kernel for debuggers. */
+ .mdebug.abi32 : {
+ KEEP(*(.mdebug.abi32))
+ }
+ .mdebug.abi64 : {
+ KEEP(*(.mdebug.abi64))
+ }
+
+ /* This is the MIPS specific mdebug section. */
+ .mdebug : {
+ *(.mdebug)
+ }
+
+ STABS_DEBUG
+ DWARF_DEBUG
+
+ /* These must appear regardless of . */
+ .gptab.sdata : {
+ *(.gptab.data)
+ *(.gptab.sdata)
+ }
+ .gptab.sbss : {
+ *(.gptab.bss)
+ *(.gptab.sbss)
+ }
+
+ /* Sections to be discarded */
+ DISCARDS
+ /DISCARD/ : {
+ /* ABI crap starts here */
+ *(.MIPS.options)
+ *(.options)
+ *(.pdr)
+ *(.reginfo)
+ }
+}
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
new file mode 100644
index 00000000..dbb6b408
--- /dev/null
+++ b/arch/mips/kernel/vpe.c
@@ -0,0 +1,1622 @@
+/*
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+/*
+ * VPE support module
+ *
+ * Provides support for loading a MIPS SP program on VPE1.
+ * The SP environment is rather simple, no tlb's. It needs to be relocatable
+ * (or partially linked). You should initialise your stack in the startup
+ * code. This loader looks for the symbol __start and sets up
+ * execution to resume from there. The MIPS SDE kit contains suitable examples.
+ *
+ * To load and run, simply cat a SP 'program file' to /dev/vpe1.
+ * i.e cat spapp >/dev/vpe1.
+ */
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/vmalloc.h>
+#include <linux/elf.h>
+#include <linux/seq_file.h>
+#include <linux/syscalls.h>
+#include <linux/moduleloader.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/bootmem.h>
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/cacheflush.h>
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/mips_mt.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/vpe.h>
+#include <asm/kspd.h>
+
+typedef void *vpe_handle;
+
+#ifndef ARCH_SHF_SMALL
+#define ARCH_SHF_SMALL 0
+#endif
+
+/* If this is set, the section belongs in the init part of the module */
+#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
+
+/*
+ * The number of TCs and VPEs physically available on the core
+ */
+static int hw_tcs, hw_vpes;
+static char module_name[] = "vpe";
+static int major;
+static const int minor = 1; /* fixed for now */
+
+#ifdef CONFIG_MIPS_APSP_KSPD
+static struct kspd_notifications kspd_events;
+static int kspd_events_reqd;
+#endif
+
+/* grab the likely amount of memory we will need. */
+#ifdef CONFIG_MIPS_VPE_LOADER_TOM
+#define P_SIZE (2 * 1024 * 1024)
+#else
+/* add an overhead to the max kmalloc size for non-striped symbols/etc */
+#define P_SIZE (256 * 1024)
+#endif
+
+extern unsigned long physical_memsize;
+
+#define MAX_VPES 16
+#define VPE_PATH_MAX 256
+
+enum vpe_state {
+ VPE_STATE_UNUSED = 0,
+ VPE_STATE_INUSE,
+ VPE_STATE_RUNNING
+};
+
+enum tc_state {
+ TC_STATE_UNUSED = 0,
+ TC_STATE_INUSE,
+ TC_STATE_RUNNING,
+ TC_STATE_DYNAMIC
+};
+
+struct vpe {
+ enum vpe_state state;
+
+ /* (device) minor associated with this vpe */
+ int minor;
+
+ /* elfloader stuff */
+ void *load_addr;
+ unsigned long len;
+ char *pbuffer;
+ unsigned long plen;
+ unsigned int uid, gid;
+ char cwd[VPE_PATH_MAX];
+
+ unsigned long __start;
+
+ /* tc's associated with this vpe */
+ struct list_head tc;
+
+ /* The list of vpe's */
+ struct list_head list;
+
+ /* shared symbol address */
+ void *shared_ptr;
+
+ /* the list of who wants to know when something major happens */
+ struct list_head notify;
+
+ unsigned int ntcs;
+};
+
+struct tc {
+ enum tc_state state;
+ int index;
+
+ struct vpe *pvpe; /* parent VPE */
+ struct list_head tc; /* The list of TC's with this VPE */
+ struct list_head list; /* The global list of tc's */
+};
+
+struct {
+ spinlock_t vpe_list_lock;
+ struct list_head vpe_list; /* Virtual processing elements */
+ spinlock_t tc_list_lock;
+ struct list_head tc_list; /* Thread contexts */
+} vpecontrol = {
+ .vpe_list_lock = __SPIN_LOCK_UNLOCKED(vpe_list_lock),
+ .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list),
+ .tc_list_lock = __SPIN_LOCK_UNLOCKED(tc_list_lock),
+ .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
+};
+
+static void release_progmem(void *ptr);
+
+/* get the vpe associated with this minor */
+static struct vpe *get_vpe(int minor)
+{
+ struct vpe *res, *v;
+
+ if (!cpu_has_mipsmt)
+ return NULL;
+
+ res = NULL;
+ spin_lock(&vpecontrol.vpe_list_lock);
+ list_for_each_entry(v, &vpecontrol.vpe_list, list) {
+ if (v->minor == minor) {
+ res = v;
+ break;
+ }
+ }
+ spin_unlock(&vpecontrol.vpe_list_lock);
+
+ return res;
+}
+
+/* get the vpe associated with this minor */
+static struct tc *get_tc(int index)
+{
+ struct tc *res, *t;
+
+ res = NULL;
+ spin_lock(&vpecontrol.tc_list_lock);
+ list_for_each_entry(t, &vpecontrol.tc_list, list) {
+ if (t->index == index) {
+ res = t;
+ break;
+ }
+ }
+ spin_unlock(&vpecontrol.tc_list_lock);
+
+ return NULL;
+}
+
+/* allocate a vpe and associate it with this minor (or index) */
+static struct vpe *alloc_vpe(int minor)
+{
+ struct vpe *v;
+
+ if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL)
+ return NULL;
+
+ INIT_LIST_HEAD(&v->tc);
+ spin_lock(&vpecontrol.vpe_list_lock);
+ list_add_tail(&v->list, &vpecontrol.vpe_list);
+ spin_unlock(&vpecontrol.vpe_list_lock);
+
+ INIT_LIST_HEAD(&v->notify);
+ v->minor = minor;
+
+ return v;
+}
+
+/* allocate a tc. At startup only tc0 is running, all other can be halted. */
+static struct tc *alloc_tc(int index)
+{
+ struct tc *tc;
+
+ if ((tc = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL)
+ goto out;
+
+ INIT_LIST_HEAD(&tc->tc);
+ tc->index = index;
+
+ spin_lock(&vpecontrol.tc_list_lock);
+ list_add_tail(&tc->list, &vpecontrol.tc_list);
+ spin_unlock(&vpecontrol.tc_list_lock);
+
+out:
+ return tc;
+}
+
+/* clean up and free everything */
+static void release_vpe(struct vpe *v)
+{
+ list_del(&v->list);
+ if (v->load_addr)
+ release_progmem(v);
+ kfree(v);
+}
+
+static void __maybe_unused dump_mtregs(void)
+{
+ unsigned long val;
+
+ val = read_c0_config3();
+ printk("config3 0x%lx MT %ld\n", val,
+ (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT);
+
+ val = read_c0_mvpcontrol();
+ printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val,
+ (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT,
+ (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT,
+ (val & MVPCONTROL_EVP));
+
+ val = read_c0_mvpconf0();
+ printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val,
+ (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT,
+ val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
+}
+
+/* Find some VPE program space */
+static void *alloc_progmem(unsigned long len)
+{
+ void *addr;
+
+#ifdef CONFIG_MIPS_VPE_LOADER_TOM
+ /*
+ * This means you must tell Linux to use less memory than you
+ * physically have, for example by passing a mem= boot argument.
+ */
+ addr = pfn_to_kaddr(max_low_pfn);
+ memset(addr, 0, len);
+#else
+ /* simple grab some mem for now */
+ addr = kzalloc(len, GFP_KERNEL);
+#endif
+
+ return addr;
+}
+
+static void release_progmem(void *ptr)
+{
+#ifndef CONFIG_MIPS_VPE_LOADER_TOM
+ kfree(ptr);
+#endif
+}
+
+/* Update size with this section: return offset. */
+static long get_offset(unsigned long *size, Elf_Shdr * sechdr)
+{
+ long ret;
+
+ ret = ALIGN(*size, sechdr->sh_addralign ? : 1);
+ *size = ret + sechdr->sh_size;
+ return ret;
+}
+
+/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
+ might -- code, read-only data, read-write data, small data. Tally
+ sizes, and place the offsets into sh_entsize fields: high bit means it
+ belongs in init. */
+static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
+ Elf_Shdr * sechdrs, const char *secstrings)
+{
+ static unsigned long const masks[][2] = {
+ /* NOTE: all executable code must be the first section
+ * in this array; otherwise modify the text_size
+ * finder in the two loops below */
+ {SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL},
+ {SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL},
+ {SHF_WRITE | SHF_ALLOC, ARCH_SHF_SMALL},
+ {ARCH_SHF_SMALL | SHF_ALLOC, 0}
+ };
+ unsigned int m, i;
+
+ for (i = 0; i < hdr->e_shnum; i++)
+ sechdrs[i].sh_entsize = ~0UL;
+
+ for (m = 0; m < ARRAY_SIZE(masks); ++m) {
+ for (i = 0; i < hdr->e_shnum; ++i) {
+ Elf_Shdr *s = &sechdrs[i];
+
+ // || strncmp(secstrings + s->sh_name, ".init", 5) == 0)
+ if ((s->sh_flags & masks[m][0]) != masks[m][0]
+ || (s->sh_flags & masks[m][1])
+ || s->sh_entsize != ~0UL)
+ continue;
+ s->sh_entsize =
+ get_offset((unsigned long *)&mod->core_size, s);
+ }
+
+ if (m == 0)
+ mod->core_text_size = mod->core_size;
+
+ }
+}
+
+
+/* from module-elf32.c, but subverted a little */
+
+struct mips_hi16 {
+ struct mips_hi16 *next;
+ Elf32_Addr *addr;
+ Elf32_Addr value;
+};
+
+static struct mips_hi16 *mips_hi16_list;
+static unsigned int gp_offs, gp_addr;
+
+static int apply_r_mips_none(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ return 0;
+}
+
+static int apply_r_mips_gprel16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ int rel;
+
+ if( !(*location & 0xffff) ) {
+ rel = (int)v - gp_addr;
+ }
+ else {
+ /* .sbss + gp(relative) + offset */
+ /* kludge! */
+ rel = (int)(short)((int)v + gp_offs +
+ (int)(short)(*location & 0xffff) - gp_addr);
+ }
+
+ if( (rel > 32768) || (rel < -32768) ) {
+ printk(KERN_DEBUG "VPE loader: apply_r_mips_gprel16: "
+ "relative address 0x%x out of range of gp register\n",
+ rel);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & 0xffff0000) | (rel & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_pc16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ int rel;
+ rel = (((unsigned int)v - (unsigned int)location));
+ rel >>= 2; // because the offset is in _instructions_ not bytes.
+ rel -= 1; // and one instruction less due to the branch delay slot.
+
+ if( (rel > 32768) || (rel < -32768) ) {
+ printk(KERN_DEBUG "VPE loader: "
+ "apply_r_mips_pc16: relative address out of range 0x%x\n", rel);
+ return -ENOEXEC;
+ }
+
+ *location = (*location & 0xffff0000) | (rel & 0xffff);
+
+ return 0;
+}
+
+static int apply_r_mips_32(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ *location += v;
+
+ return 0;
+}
+
+static int apply_r_mips_26(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ if (v % 4) {
+ printk(KERN_DEBUG "VPE loader: apply_r_mips_26 "
+ " unaligned relocation\n");
+ return -ENOEXEC;
+ }
+
+/*
+ * Not desperately convinced this is a good check of an overflow condition
+ * anyway. But it gets in the way of handling undefined weak symbols which
+ * we want to set to zero.
+ * if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
+ * printk(KERN_ERR
+ * "module %s: relocation overflow\n",
+ * me->name);
+ * return -ENOEXEC;
+ * }
+ */
+
+ *location = (*location & ~0x03ffffff) |
+ ((*location + (v >> 2)) & 0x03ffffff);
+ return 0;
+}
+
+static int apply_r_mips_hi16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ struct mips_hi16 *n;
+
+ /*
+ * We cannot relocate this one now because we don't know the value of
+ * the carry we need to add. Save the information, and let LO16 do the
+ * actual relocation.
+ */
+ n = kmalloc(sizeof *n, GFP_KERNEL);
+ if (!n)
+ return -ENOMEM;
+
+ n->addr = location;
+ n->value = v;
+ n->next = mips_hi16_list;
+ mips_hi16_list = n;
+
+ return 0;
+}
+
+static int apply_r_mips_lo16(struct module *me, uint32_t *location,
+ Elf32_Addr v)
+{
+ unsigned long insnlo = *location;
+ Elf32_Addr val, vallo;
+ struct mips_hi16 *l, *next;
+
+ /* Sign extend the addend we extract from the lo insn. */
+ vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
+
+ if (mips_hi16_list != NULL) {
+
+ l = mips_hi16_list;
+ while (l != NULL) {
+ unsigned long insn;
+
+ /*
+ * The value for the HI16 had best be the same.
+ */
+ if (v != l->value) {
+ printk(KERN_DEBUG "VPE loader: "
+ "apply_r_mips_lo16/hi16: \t"
+ "inconsistent value information\n");
+ goto out_free;
+ }
+
+ /*
+ * Do the HI16 relocation. Note that we actually don't
+ * need to know anything about the LO16 itself, except
+ * where to find the low 16 bits of the addend needed
+ * by the LO16.
+ */
+ insn = *l->addr;
+ val = ((insn & 0xffff) << 16) + vallo;
+ val += v;
+
+ /*
+ * Account for the sign extension that will happen in
+ * the low bits.
+ */
+ val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;
+
+ insn = (insn & ~0xffff) | val;
+ *l->addr = insn;
+
+ next = l->next;
+ kfree(l);
+ l = next;
+ }
+
+ mips_hi16_list = NULL;
+ }
+
+ /*
+ * Ok, we're done with the HI16 relocs. Now deal with the LO16.
+ */
+ val = v + vallo;
+ insnlo = (insnlo & ~0xffff) | (val & 0xffff);
+ *location = insnlo;
+
+ return 0;
+
+out_free:
+ while (l != NULL) {
+ next = l->next;
+ kfree(l);
+ l = next;
+ }
+ mips_hi16_list = NULL;
+
+ return -ENOEXEC;
+}
+
+static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
+ Elf32_Addr v) = {
+ [R_MIPS_NONE] = apply_r_mips_none,
+ [R_MIPS_32] = apply_r_mips_32,
+ [R_MIPS_26] = apply_r_mips_26,
+ [R_MIPS_HI16] = apply_r_mips_hi16,
+ [R_MIPS_LO16] = apply_r_mips_lo16,
+ [R_MIPS_GPREL16] = apply_r_mips_gprel16,
+ [R_MIPS_PC16] = apply_r_mips_pc16
+};
+
+static char *rstrs[] = {
+ [R_MIPS_NONE] = "MIPS_NONE",
+ [R_MIPS_32] = "MIPS_32",
+ [R_MIPS_26] = "MIPS_26",
+ [R_MIPS_HI16] = "MIPS_HI16",
+ [R_MIPS_LO16] = "MIPS_LO16",
+ [R_MIPS_GPREL16] = "MIPS_GPREL16",
+ [R_MIPS_PC16] = "MIPS_PC16"
+};
+
+static int apply_relocations(Elf32_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf32_Sym *sym;
+ uint32_t *location;
+ unsigned int i;
+ Elf32_Addr v;
+ int res;
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ Elf32_Word r_info = rel[i].r_info;
+
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /* This is the symbol it is referring to */
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(r_info);
+
+ if (!sym->st_value) {
+ printk(KERN_DEBUG "%s: undefined weak symbol %s\n",
+ me->name, strtab + sym->st_name);
+ /* just print the warning, dont barf */
+ }
+
+ v = sym->st_value;
+
+ res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
+ if( res ) {
+ char *r = rstrs[ELF32_R_TYPE(r_info)];
+ printk(KERN_WARNING "VPE loader: .text+0x%x "
+ "relocation type %s for symbol \"%s\" failed\n",
+ rel[i].r_offset, r ? r : "UNKNOWN",
+ strtab + sym->st_name);
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+static inline void save_gp_address(unsigned int secbase, unsigned int rel)
+{
+ gp_addr = secbase + rel;
+ gp_offs = gp_addr - (secbase & 0xffff0000);
+}
+/* end module-elf32.c */
+
+
+
+/* Change all symbols so that sh_value encodes the pointer directly. */
+static void simplify_symbols(Elf_Shdr * sechdrs,
+ unsigned int symindex,
+ const char *strtab,
+ const char *secstrings,
+ unsigned int nsecs, struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned long secbase, bssbase = 0;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+ int size;
+
+ /* find the .bss section for COMMON symbols */
+ for (i = 0; i < nsecs; i++) {
+ if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0) {
+ bssbase = sechdrs[i].sh_addr;
+ break;
+ }
+ }
+
+ for (i = 1; i < n; i++) {
+ switch (sym[i].st_shndx) {
+ case SHN_COMMON:
+ /* Allocate space for the symbol in the .bss section.
+ st_value is currently size.
+ We want it to have the address of the symbol. */
+
+ size = sym[i].st_value;
+ sym[i].st_value = bssbase;
+
+ bssbase += size;
+ break;
+
+ case SHN_ABS:
+ /* Don't need to do anything */
+ break;
+
+ case SHN_UNDEF:
+ /* ret = -ENOENT; */
+ break;
+
+ case SHN_MIPS_SCOMMON:
+ printk(KERN_DEBUG "simplify_symbols: ignoring SHN_MIPS_SCOMMON "
+ "symbol <%s> st_shndx %d\n", strtab + sym[i].st_name,
+ sym[i].st_shndx);
+ // .sbss section
+ break;
+
+ default:
+ secbase = sechdrs[sym[i].st_shndx].sh_addr;
+
+ if (strncmp(strtab + sym[i].st_name, "_gp", 3) == 0) {
+ save_gp_address(secbase, sym[i].st_value);
+ }
+
+ sym[i].st_value += secbase;
+ break;
+ }
+ }
+}
+
+#ifdef DEBUG_ELFLOADER
+static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex,
+ const char *strtab, struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+
+ printk(KERN_DEBUG "dump_elfsymbols: n %d\n", n);
+ for (i = 1; i < n; i++) {
+ printk(KERN_DEBUG " i %d name <%s> 0x%x\n", i,
+ strtab + sym[i].st_name, sym[i].st_value);
+ }
+}
+#endif
+
+/* We are prepared so configure and start the VPE... */
+static int vpe_run(struct vpe * v)
+{
+ unsigned long flags, val, dmt_flag;
+ struct vpe_notifications *n;
+ unsigned int vpeflags;
+ struct tc *t;
+
+ /* check we are the Master VPE */
+ local_irq_save(flags);
+ val = read_c0_vpeconf0();
+ if (!(val & VPECONF0_MVP)) {
+ printk(KERN_WARNING
+ "VPE loader: only Master VPE's are allowed to configure MT\n");
+ local_irq_restore(flags);
+
+ return -1;
+ }
+
+ dmt_flag = dmt();
+ vpeflags = dvpe();
+
+ if (!list_empty(&v->tc)) {
+ if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
+ evpe(vpeflags);
+ emt(dmt_flag);
+ local_irq_restore(flags);
+
+ printk(KERN_WARNING
+ "VPE loader: TC %d is already in use.\n",
+ t->index);
+ return -ENOEXEC;
+ }
+ } else {
+ evpe(vpeflags);
+ emt(dmt_flag);
+ local_irq_restore(flags);
+
+ printk(KERN_WARNING
+ "VPE loader: No TC's associated with VPE %d\n",
+ v->minor);
+
+ return -ENOEXEC;
+ }
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ settc(t->index);
+
+ /* should check it is halted, and not activated */
+ if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) {
+ evpe(vpeflags);
+ emt(dmt_flag);
+ local_irq_restore(flags);
+
+ printk(KERN_WARNING "VPE loader: TC %d is already active!\n",
+ t->index);
+
+ return -ENOEXEC;
+ }
+
+ /* Write the address we want it to start running from in the TCPC register. */
+ write_tc_c0_tcrestart((unsigned long)v->__start);
+ write_tc_c0_tccontext((unsigned long)0);
+
+ /*
+ * Mark the TC as activated, not interrupt exempt and not dynamically
+ * allocatable
+ */
+ val = read_tc_c0_tcstatus();
+ val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A;
+ write_tc_c0_tcstatus(val);
+
+ write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
+
+ /*
+ * The sde-kit passes 'memsize' to __start in $a3, so set something
+ * here... Or set $a3 to zero and define DFLT_STACK_SIZE and
+ * DFLT_HEAP_SIZE when you compile your program
+ */
+ mttgpr(6, v->ntcs);
+ mttgpr(7, physical_memsize);
+
+ /* set up VPE1 */
+ /*
+ * bind the TC to VPE 1 as late as possible so we only have the final
+ * VPE registers to set up, and so an EJTAG probe can trigger on it
+ */
+ write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | 1);
+
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~(VPECONF0_VPA));
+
+ back_to_back_c0_hazard();
+
+ /* Set up the XTC bit in vpeconf0 to point at our tc */
+ write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC))
+ | (t->index << VPECONF0_XTC_SHIFT));
+
+ back_to_back_c0_hazard();
+
+ /* enable this VPE */
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+
+ /* clear out any left overs from a previous program */
+ write_vpe_c0_status(0);
+ write_vpe_c0_cause(0);
+
+ /* take system out of configuration state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /*
+ * SMTC/SMVP kernels manage VPE enable independently,
+ * but uniprocessor kernels need to turn it on, even
+ * if that wasn't the pre-dvpe() state.
+ */
+#ifdef CONFIG_SMP
+ evpe(vpeflags);
+#else
+ evpe(EVPE_ENABLE);
+#endif
+ emt(dmt_flag);
+ local_irq_restore(flags);
+
+ list_for_each_entry(n, &v->notify, list)
+ n->start(minor);
+
+ return 0;
+}
+
+static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
+ unsigned int symindex, const char *strtab,
+ struct module *mod)
+{
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+
+ for (i = 1; i < n; i++) {
+ if (strcmp(strtab + sym[i].st_name, "__start") == 0) {
+ v->__start = sym[i].st_value;
+ }
+
+ if (strcmp(strtab + sym[i].st_name, "vpe_shared") == 0) {
+ v->shared_ptr = (void *)sym[i].st_value;
+ }
+ }
+
+ if ( (v->__start == 0) || (v->shared_ptr == NULL))
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Allocates a VPE with some program code space(the load address), copies the
+ * contents of the program (p)buffer performing relocatations/etc, free's it
+ * when finished.
+ */
+static int vpe_elfload(struct vpe * v)
+{
+ Elf_Ehdr *hdr;
+ Elf_Shdr *sechdrs;
+ long err = 0;
+ char *secstrings, *strtab = NULL;
+ unsigned int len, i, symindex = 0, strindex = 0, relocate = 0;
+ struct module mod; // so we can re-use the relocations code
+
+ memset(&mod, 0, sizeof(struct module));
+ strcpy(mod.name, "VPE loader");
+
+ hdr = (Elf_Ehdr *) v->pbuffer;
+ len = v->plen;
+
+ /* Sanity checks against insmoding binaries or wrong arch,
+ weird elf version */
+ if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
+ || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
+ || !elf_check_arch(hdr)
+ || hdr->e_shentsize != sizeof(*sechdrs)) {
+ printk(KERN_WARNING
+ "VPE loader: program wrong arch or weird elf version\n");
+
+ return -ENOEXEC;
+ }
+
+ if (hdr->e_type == ET_REL)
+ relocate = 1;
+
+ if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
+ printk(KERN_ERR "VPE loader: program length %u truncated\n",
+ len);
+
+ return -ENOEXEC;
+ }
+
+ /* Convenience variables */
+ sechdrs = (void *)hdr + hdr->e_shoff;
+ secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ sechdrs[0].sh_addr = 0;
+
+ /* And these should exist, but gcc whinges if we don't init them */
+ symindex = strindex = 0;
+
+ if (relocate) {
+ for (i = 1; i < hdr->e_shnum; i++) {
+ if (sechdrs[i].sh_type != SHT_NOBITS
+ && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) {
+ printk(KERN_ERR "VPE program length %u truncated\n",
+ len);
+ return -ENOEXEC;
+ }
+
+ /* Mark all sections sh_addr with their address in the
+ temporary image. */
+ sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
+
+ /* Internal symbols and strings. */
+ if (sechdrs[i].sh_type == SHT_SYMTAB) {
+ symindex = i;
+ strindex = sechdrs[i].sh_link;
+ strtab = (char *)hdr + sechdrs[strindex].sh_offset;
+ }
+ }
+ layout_sections(&mod, hdr, sechdrs, secstrings);
+ }
+
+ v->load_addr = alloc_progmem(mod.core_size);
+ if (!v->load_addr)
+ return -ENOMEM;
+
+ pr_info("VPE loader: loading to %p\n", v->load_addr);
+
+ if (relocate) {
+ for (i = 0; i < hdr->e_shnum; i++) {
+ void *dest;
+
+ if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+ continue;
+
+ dest = v->load_addr + sechdrs[i].sh_entsize;
+
+ if (sechdrs[i].sh_type != SHT_NOBITS)
+ memcpy(dest, (void *)sechdrs[i].sh_addr,
+ sechdrs[i].sh_size);
+ /* Update sh_addr to point to copy in image. */
+ sechdrs[i].sh_addr = (unsigned long)dest;
+
+ printk(KERN_DEBUG " section sh_name %s sh_addr 0x%x\n",
+ secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr);
+ }
+
+ /* Fix up syms, so that st_value is a pointer to location. */
+ simplify_symbols(sechdrs, symindex, strtab, secstrings,
+ hdr->e_shnum, &mod);
+
+ /* Now do relocations. */
+ for (i = 1; i < hdr->e_shnum; i++) {
+ const char *strtab = (char *)sechdrs[strindex].sh_addr;
+ unsigned int info = sechdrs[i].sh_info;
+
+ /* Not a valid relocation section? */
+ if (info >= hdr->e_shnum)
+ continue;
+
+ /* Don't bother with non-allocated sections */
+ if (!(sechdrs[info].sh_flags & SHF_ALLOC))
+ continue;
+
+ if (sechdrs[i].sh_type == SHT_REL)
+ err = apply_relocations(sechdrs, strtab, symindex, i,
+ &mod);
+ else if (sechdrs[i].sh_type == SHT_RELA)
+ err = apply_relocate_add(sechdrs, strtab, symindex, i,
+ &mod);
+ if (err < 0)
+ return err;
+
+ }
+ } else {
+ struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);
+
+ for (i = 0; i < hdr->e_phnum; i++) {
+ if (phdr->p_type == PT_LOAD) {
+ memcpy((void *)phdr->p_paddr,
+ (char *)hdr + phdr->p_offset,
+ phdr->p_filesz);
+ memset((void *)phdr->p_paddr + phdr->p_filesz,
+ 0, phdr->p_memsz - phdr->p_filesz);
+ }
+ phdr++;
+ }
+
+ for (i = 0; i < hdr->e_shnum; i++) {
+ /* Internal symbols and strings. */
+ if (sechdrs[i].sh_type == SHT_SYMTAB) {
+ symindex = i;
+ strindex = sechdrs[i].sh_link;
+ strtab = (char *)hdr + sechdrs[strindex].sh_offset;
+
+ /* mark the symtab's address for when we try to find the
+ magic symbols */
+ sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
+ }
+ }
+ }
+
+ /* make sure it's physically written out */
+ flush_icache_range((unsigned long)v->load_addr,
+ (unsigned long)v->load_addr + v->len);
+
+ if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
+ if (v->__start == 0) {
+ printk(KERN_WARNING "VPE loader: program does not contain "
+ "a __start symbol\n");
+ return -ENOEXEC;
+ }
+
+ if (v->shared_ptr == NULL)
+ printk(KERN_WARNING "VPE loader: "
+ "program does not contain vpe_shared symbol.\n"
+ " Unable to use AMVP (AP/SP) facilities.\n");
+ }
+
+ printk(" elf loaded\n");
+ return 0;
+}
+
+static void cleanup_tc(struct tc *tc)
+{
+ unsigned long flags;
+ unsigned int mtflags, vpflags;
+ int tmp;
+
+ local_irq_save(flags);
+ mtflags = dmt();
+ vpflags = dvpe();
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ settc(tc->index);
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not allocated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+
+ write_tc_c0_tchalt(TCHALT_H);
+ mips_ihb();
+
+ /* bind it to anything other than VPE1 */
+// write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE
+
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+ evpe(vpflags);
+ emt(mtflags);
+ local_irq_restore(flags);
+}
+
+static int getcwd(char *buff, int size)
+{
+ mm_segment_t old_fs;
+ int ret;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ ret = sys_getcwd(buff, size);
+
+ set_fs(old_fs);
+
+ return ret;
+}
+
+/* checks VPE is unused and gets ready to load program */
+static int vpe_open(struct inode *inode, struct file *filp)
+{
+ enum vpe_state state;
+ struct vpe_notifications *not;
+ struct vpe *v;
+ int ret;
+
+ if (minor != iminor(inode)) {
+ /* assume only 1 device at the moment. */
+ pr_warning("VPE loader: only vpe1 is supported\n");
+
+ return -ENODEV;
+ }
+
+ if ((v = get_vpe(tclimit)) == NULL) {
+ pr_warning("VPE loader: unable to get vpe\n");
+
+ return -ENODEV;
+ }
+
+ state = xchg(&v->state, VPE_STATE_INUSE);
+ if (state != VPE_STATE_UNUSED) {
+ printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n");
+
+ list_for_each_entry(not, &v->notify, list) {
+ not->stop(tclimit);
+ }
+
+ release_progmem(v->load_addr);
+ cleanup_tc(get_tc(tclimit));
+ }
+
+ /* this of-course trashes what was there before... */
+ v->pbuffer = vmalloc(P_SIZE);
+ if (!v->pbuffer) {
+ pr_warning("VPE loader: unable to allocate memory\n");
+ return -ENOMEM;
+ }
+ v->plen = P_SIZE;
+ v->load_addr = NULL;
+ v->len = 0;
+
+ v->uid = filp->f_cred->fsuid;
+ v->gid = filp->f_cred->fsgid;
+
+#ifdef CONFIG_MIPS_APSP_KSPD
+ /* get kspd to tell us when a syscall_exit happens */
+ if (!kspd_events_reqd) {
+ kspd_notify(&kspd_events);
+ kspd_events_reqd++;
+ }
+#endif
+
+ v->cwd[0] = 0;
+ ret = getcwd(v->cwd, VPE_PATH_MAX);
+ if (ret < 0)
+ printk(KERN_WARNING "VPE loader: open, getcwd returned %d\n", ret);
+
+ v->shared_ptr = NULL;
+ v->__start = 0;
+
+ return 0;
+}
+
+static int vpe_release(struct inode *inode, struct file *filp)
+{
+ struct vpe *v;
+ Elf_Ehdr *hdr;
+ int ret = 0;
+
+ v = get_vpe(tclimit);
+ if (v == NULL)
+ return -ENODEV;
+
+ hdr = (Elf_Ehdr *) v->pbuffer;
+ if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
+ if (vpe_elfload(v) >= 0) {
+ vpe_run(v);
+ } else {
+ printk(KERN_WARNING "VPE loader: ELF load failed.\n");
+ ret = -ENOEXEC;
+ }
+ } else {
+ printk(KERN_WARNING "VPE loader: only elf files are supported\n");
+ ret = -ENOEXEC;
+ }
+
+ /* It's good to be able to run the SP and if it chokes have a look at
+ the /dev/rt?. But if we reset the pointer to the shared struct we
+ lose what has happened. So perhaps if garbage is sent to the vpe
+ device, use it as a trigger for the reset. Hopefully a nice
+ executable will be along shortly. */
+ if (ret < 0)
+ v->shared_ptr = NULL;
+
+ vfree(v->pbuffer);
+ v->plen = 0;
+
+ return ret;
+}
+
+static ssize_t vpe_write(struct file *file, const char __user * buffer,
+ size_t count, loff_t * ppos)
+{
+ size_t ret = count;
+ struct vpe *v;
+
+ if (iminor(file->f_path.dentry->d_inode) != minor)
+ return -ENODEV;
+
+ v = get_vpe(tclimit);
+ if (v == NULL)
+ return -ENODEV;
+
+ if ((count + v->len) > v->plen) {
+ printk(KERN_WARNING
+ "VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
+ return -ENOMEM;
+ }
+
+ count -= copy_from_user(v->pbuffer + v->len, buffer, count);
+ if (!count)
+ return -EFAULT;
+
+ v->len += count;
+ return ret;
+}
+
+static const struct file_operations vpe_fops = {
+ .owner = THIS_MODULE,
+ .open = vpe_open,
+ .release = vpe_release,
+ .write = vpe_write,
+ .llseek = noop_llseek,
+};
+
+/* module wrapper entry points */
+/* give me a vpe */
+vpe_handle vpe_alloc(void)
+{
+ int i;
+ struct vpe *v;
+
+ /* find a vpe */
+ for (i = 1; i < MAX_VPES; i++) {
+ if ((v = get_vpe(i)) != NULL) {
+ v->state = VPE_STATE_INUSE;
+ return v;
+ }
+ }
+ return NULL;
+}
+
+EXPORT_SYMBOL(vpe_alloc);
+
+/* start running from here */
+int vpe_start(vpe_handle vpe, unsigned long start)
+{
+ struct vpe *v = vpe;
+
+ v->__start = start;
+ return vpe_run(v);
+}
+
+EXPORT_SYMBOL(vpe_start);
+
+/* halt it for now */
+int vpe_stop(vpe_handle vpe)
+{
+ struct vpe *v = vpe;
+ struct tc *t;
+ unsigned int evpe_flags;
+
+ evpe_flags = dvpe();
+
+ if ((t = list_entry(v->tc.next, struct tc, tc)) != NULL) {
+
+ settc(t->index);
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
+ }
+
+ evpe(evpe_flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(vpe_stop);
+
+/* I've done with it thank you */
+int vpe_free(vpe_handle vpe)
+{
+ struct vpe *v = vpe;
+ struct tc *t;
+ unsigned int evpe_flags;
+
+ if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
+ return -ENOEXEC;
+ }
+
+ evpe_flags = dvpe();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ settc(t->index);
+ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
+
+ /* halt the TC */
+ write_tc_c0_tchalt(TCHALT_H);
+ mips_ihb();
+
+ /* mark the TC unallocated */
+ write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
+
+ v->state = VPE_STATE_UNUSED;
+
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+ evpe(evpe_flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(vpe_free);
+
+void *vpe_get_shared(int index)
+{
+ struct vpe *v;
+
+ if ((v = get_vpe(index)) == NULL)
+ return NULL;
+
+ return v->shared_ptr;
+}
+
+EXPORT_SYMBOL(vpe_get_shared);
+
+int vpe_getuid(int index)
+{
+ struct vpe *v;
+
+ if ((v = get_vpe(index)) == NULL)
+ return -1;
+
+ return v->uid;
+}
+
+EXPORT_SYMBOL(vpe_getuid);
+
+int vpe_getgid(int index)
+{
+ struct vpe *v;
+
+ if ((v = get_vpe(index)) == NULL)
+ return -1;
+
+ return v->gid;
+}
+
+EXPORT_SYMBOL(vpe_getgid);
+
+int vpe_notify(int index, struct vpe_notifications *notify)
+{
+ struct vpe *v;
+
+ if ((v = get_vpe(index)) == NULL)
+ return -1;
+
+ list_add(&notify->list, &v->notify);
+ return 0;
+}
+
+EXPORT_SYMBOL(vpe_notify);
+
+char *vpe_getcwd(int index)
+{
+ struct vpe *v;
+
+ if ((v = get_vpe(index)) == NULL)
+ return NULL;
+
+ return v->cwd;
+}
+
+EXPORT_SYMBOL(vpe_getcwd);
+
+#ifdef CONFIG_MIPS_APSP_KSPD
+static void kspd_sp_exit( int sp_id)
+{
+ cleanup_tc(get_tc(sp_id));
+}
+#endif
+
+static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct vpe *vpe = get_vpe(tclimit);
+ struct vpe_notifications *not;
+
+ list_for_each_entry(not, &vpe->notify, list) {
+ not->stop(tclimit);
+ }
+
+ release_progmem(vpe->load_addr);
+ cleanup_tc(get_tc(tclimit));
+ vpe_stop(vpe);
+ vpe_free(vpe);
+
+ return len;
+}
+
+static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr,
+ char *buf)
+{
+ struct vpe *vpe = get_vpe(tclimit);
+
+ return sprintf(buf, "%d\n", vpe->ntcs);
+}
+
+static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct vpe *vpe = get_vpe(tclimit);
+ unsigned long new;
+ char *endp;
+
+ new = simple_strtoul(buf, &endp, 0);
+ if (endp == buf)
+ goto out_einval;
+
+ if (new == 0 || new > (hw_tcs - tclimit))
+ goto out_einval;
+
+ vpe->ntcs = new;
+
+ return len;
+
+out_einval:
+ return -EINVAL;
+}
+
+static struct device_attribute vpe_class_attributes[] = {
+ __ATTR(kill, S_IWUSR, NULL, store_kill),
+ __ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs),
+ {}
+};
+
+static void vpe_device_release(struct device *cd)
+{
+ kfree(cd);
+}
+
+struct class vpe_class = {
+ .name = "vpe",
+ .owner = THIS_MODULE,
+ .dev_release = vpe_device_release,
+ .dev_attrs = vpe_class_attributes,
+};
+
+struct device vpe_device;
+
+static int __init vpe_module_init(void)
+{
+ unsigned int mtflags, vpflags;
+ unsigned long flags, val;
+ struct vpe *v = NULL;
+ struct tc *t;
+ int tc, err;
+
+ if (!cpu_has_mipsmt) {
+ printk("VPE loader: not a MIPS MT capable processor\n");
+ return -ENODEV;
+ }
+
+ if (vpelimit == 0) {
+ printk(KERN_WARNING "No VPEs reserved for AP/SP, not "
+ "initializing VPE loader.\nPass maxvpes=<n> argument as "
+ "kernel argument\n");
+
+ return -ENODEV;
+ }
+
+ if (tclimit == 0) {
+ printk(KERN_WARNING "No TCs reserved for AP/SP, not "
+ "initializing VPE loader.\nPass maxtcs=<n> argument as "
+ "kernel argument\n");
+
+ return -ENODEV;
+ }
+
+ major = register_chrdev(0, module_name, &vpe_fops);
+ if (major < 0) {
+ printk("VPE loader: unable to register character device\n");
+ return major;
+ }
+
+ err = class_register(&vpe_class);
+ if (err) {
+ printk(KERN_ERR "vpe_class registration failed\n");
+ goto out_chrdev;
+ }
+
+ device_initialize(&vpe_device);
+ vpe_device.class = &vpe_class,
+ vpe_device.parent = NULL,
+ dev_set_name(&vpe_device, "vpe1");
+ vpe_device.devt = MKDEV(major, minor);
+ err = device_add(&vpe_device);
+ if (err) {
+ printk(KERN_ERR "Adding vpe_device failed\n");
+ goto out_class;
+ }
+
+ local_irq_save(flags);
+ mtflags = dmt();
+ vpflags = dvpe();
+
+ /* Put MVPE's into 'configuration state' */
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* dump_mtregs(); */
+
+ val = read_c0_mvpconf0();
+ hw_tcs = (val & MVPCONF0_PTC) + 1;
+ hw_vpes = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+
+ for (tc = tclimit; tc < hw_tcs; tc++) {
+ /*
+ * Must re-enable multithreading temporarily or in case we
+ * reschedule send IPIs or similar we might hang.
+ */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+ evpe(vpflags);
+ emt(mtflags);
+ local_irq_restore(flags);
+ t = alloc_tc(tc);
+ if (!t) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ local_irq_save(flags);
+ mtflags = dmt();
+ vpflags = dvpe();
+ set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ /* VPE's */
+ if (tc < hw_tcs) {
+ settc(tc);
+
+ if ((v = alloc_vpe(tc)) == NULL) {
+ printk(KERN_WARNING "VPE: unable to allocate VPE\n");
+
+ goto out_reenable;
+ }
+
+ v->ntcs = hw_tcs - tclimit;
+
+ /* add the tc to the list of this vpe's tc's. */
+ list_add(&t->tc, &v->tc);
+
+ /* deactivate all but vpe0 */
+ if (tc >= tclimit) {
+ unsigned long tmp = read_vpe_c0_vpeconf0();
+
+ tmp &= ~VPECONF0_VPA;
+
+ /* master VPE */
+ tmp |= VPECONF0_MVP;
+ write_vpe_c0_vpeconf0(tmp);
+ }
+
+ /* disable multi-threading with TC's */
+ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+ if (tc >= vpelimit) {
+ /*
+ * Set config to be the same as vpe0,
+ * particularly kseg0 coherency alg
+ */
+ write_vpe_c0_config(read_c0_config());
+ }
+ }
+
+ /* TC's */
+ t->pvpe = v; /* set the parent vpe */
+
+ if (tc >= tclimit) {
+ unsigned long tmp;
+
+ settc(tc);
+
+ /* Any TC that is bound to VPE0 gets left as is - in case
+ we are running SMTC on VPE0. A TC that is bound to any
+ other VPE gets bound to VPE0, ideally I'd like to make
+ it homeless but it doesn't appear to let me bind a TC
+ to a non-existent VPE. Which is perfectly reasonable.
+
+ The (un)bound state is visible to an EJTAG probe so may
+ notify GDB...
+ */
+
+ if (((tmp = read_tc_c0_tcbind()) & TCBIND_CURVPE)) {
+ /* tc is bound >vpe0 */
+ write_tc_c0_tcbind(tmp & ~TCBIND_CURVPE);
+
+ t->pvpe = get_vpe(0); /* set the parent vpe */
+ }
+
+ /* halt the TC */
+ write_tc_c0_tchalt(TCHALT_H);
+ mips_ihb();
+
+ tmp = read_tc_c0_tcstatus();
+
+ /* mark not activated and not dynamically allocatable */
+ tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+ tmp |= TCSTATUS_IXMT; /* interrupt exempt */
+ write_tc_c0_tcstatus(tmp);
+ }
+ }
+
+out_reenable:
+ /* release config state */
+ clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+ evpe(vpflags);
+ emt(mtflags);
+ local_irq_restore(flags);
+
+#ifdef CONFIG_MIPS_APSP_KSPD
+ kspd_events.kspd_sp_exit = kspd_sp_exit;
+#endif
+ return 0;
+
+out_class:
+ class_unregister(&vpe_class);
+out_chrdev:
+ unregister_chrdev(major, module_name);
+
+out:
+ return err;
+}
+
+static void __exit vpe_module_exit(void)
+{
+ struct vpe *v, *n;
+
+ device_del(&vpe_device);
+ unregister_chrdev(major, module_name);
+
+ /* No locking needed here */
+ list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
+ if (v->state != VPE_STATE_UNUSED)
+ release_vpe(v);
+ }
+}
+
+module_init(vpe_module_init);
+module_exit(vpe_module_exit);
+MODULE_DESCRIPTION("MIPS VPE Loader");
+MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/watch.c b/arch/mips/kernel/watch.c
new file mode 100644
index 00000000..c1540696
--- /dev/null
+++ b/arch/mips/kernel/watch.c
@@ -0,0 +1,188 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 David Daney
+ */
+
+#include <linux/sched.h>
+
+#include <asm/processor.h>
+#include <asm/watch.h>
+
+/*
+ * Install the watch registers for the current thread. A maximum of
+ * four registers are installed although the machine may have more.
+ */
+void mips_install_watch_registers(void)
+{
+ struct mips3264_watch_reg_state *watches =
+ &current->thread.watch.mips3264;
+ switch (current_cpu_data.watch_reg_use_cnt) {
+ default:
+ BUG();
+ case 4:
+ write_c0_watchlo3(watches->watchlo[3]);
+ /* Write 1 to the I, R, and W bits to clear them, and
+ 1 to G so all ASIDs are trapped. */
+ write_c0_watchhi3(0x40000007 | watches->watchhi[3]);
+ case 3:
+ write_c0_watchlo2(watches->watchlo[2]);
+ write_c0_watchhi2(0x40000007 | watches->watchhi[2]);
+ case 2:
+ write_c0_watchlo1(watches->watchlo[1]);
+ write_c0_watchhi1(0x40000007 | watches->watchhi[1]);
+ case 1:
+ write_c0_watchlo0(watches->watchlo[0]);
+ write_c0_watchhi0(0x40000007 | watches->watchhi[0]);
+ }
+}
+
+/*
+ * Read back the watchhi registers so the user space debugger has
+ * access to the I, R, and W bits. A maximum of four registers are
+ * read although the machine may have more.
+ */
+void mips_read_watch_registers(void)
+{
+ struct mips3264_watch_reg_state *watches =
+ &current->thread.watch.mips3264;
+ switch (current_cpu_data.watch_reg_use_cnt) {
+ default:
+ BUG();
+ case 4:
+ watches->watchhi[3] = (read_c0_watchhi3() & 0x0fff);
+ case 3:
+ watches->watchhi[2] = (read_c0_watchhi2() & 0x0fff);
+ case 2:
+ watches->watchhi[1] = (read_c0_watchhi1() & 0x0fff);
+ case 1:
+ watches->watchhi[0] = (read_c0_watchhi0() & 0x0fff);
+ }
+ if (current_cpu_data.watch_reg_use_cnt == 1 &&
+ (watches->watchhi[0] & 7) == 0) {
+ /* Pathological case of release 1 architecture that
+ * doesn't set the condition bits. We assume that
+ * since we got here, the watch condition was met and
+ * signal that the conditions requested in watchlo
+ * were met. */
+ watches->watchhi[0] |= (watches->watchlo[0] & 7);
+ }
+ }
+
+/*
+ * Disable all watch registers. Although only four registers are
+ * installed, all are cleared to eliminate the possibility of endless
+ * looping in the watch handler.
+ */
+void mips_clear_watch_registers(void)
+{
+ switch (current_cpu_data.watch_reg_count) {
+ default:
+ BUG();
+ case 8:
+ write_c0_watchlo7(0);
+ case 7:
+ write_c0_watchlo6(0);
+ case 6:
+ write_c0_watchlo5(0);
+ case 5:
+ write_c0_watchlo4(0);
+ case 4:
+ write_c0_watchlo3(0);
+ case 3:
+ write_c0_watchlo2(0);
+ case 2:
+ write_c0_watchlo1(0);
+ case 1:
+ write_c0_watchlo0(0);
+ }
+}
+
+__cpuinit void mips_probe_watch_registers(struct cpuinfo_mips *c)
+{
+ unsigned int t;
+
+ if ((c->options & MIPS_CPU_WATCH) == 0)
+ return;
+ /*
+ * Check which of the I,R and W bits are supported, then
+ * disable the register.
+ */
+ write_c0_watchlo0(7);
+ t = read_c0_watchlo0();
+ write_c0_watchlo0(0);
+ c->watch_reg_masks[0] = t & 7;
+
+ /* Write the mask bits and read them back to determine which
+ * can be used. */
+ c->watch_reg_count = 1;
+ c->watch_reg_use_cnt = 1;
+ t = read_c0_watchhi0();
+ write_c0_watchhi0(t | 0xff8);
+ t = read_c0_watchhi0();
+ c->watch_reg_masks[0] |= (t & 0xff8);
+ if ((t & 0x80000000) == 0)
+ return;
+
+ write_c0_watchlo1(7);
+ t = read_c0_watchlo1();
+ write_c0_watchlo1(0);
+ c->watch_reg_masks[1] = t & 7;
+
+ c->watch_reg_count = 2;
+ c->watch_reg_use_cnt = 2;
+ t = read_c0_watchhi1();
+ write_c0_watchhi1(t | 0xff8);
+ t = read_c0_watchhi1();
+ c->watch_reg_masks[1] |= (t & 0xff8);
+ if ((t & 0x80000000) == 0)
+ return;
+
+ write_c0_watchlo2(7);
+ t = read_c0_watchlo2();
+ write_c0_watchlo2(0);
+ c->watch_reg_masks[2] = t & 7;
+
+ c->watch_reg_count = 3;
+ c->watch_reg_use_cnt = 3;
+ t = read_c0_watchhi2();
+ write_c0_watchhi2(t | 0xff8);
+ t = read_c0_watchhi2();
+ c->watch_reg_masks[2] |= (t & 0xff8);
+ if ((t & 0x80000000) == 0)
+ return;
+
+ write_c0_watchlo3(7);
+ t = read_c0_watchlo3();
+ write_c0_watchlo3(0);
+ c->watch_reg_masks[3] = t & 7;
+
+ c->watch_reg_count = 4;
+ c->watch_reg_use_cnt = 4;
+ t = read_c0_watchhi3();
+ write_c0_watchhi3(t | 0xff8);
+ t = read_c0_watchhi3();
+ c->watch_reg_masks[3] |= (t & 0xff8);
+ if ((t & 0x80000000) == 0)
+ return;
+
+ /* We use at most 4, but probe and report up to 8. */
+ c->watch_reg_count = 5;
+ t = read_c0_watchhi4();
+ if ((t & 0x80000000) == 0)
+ return;
+
+ c->watch_reg_count = 6;
+ t = read_c0_watchhi5();
+ if ((t & 0x80000000) == 0)
+ return;
+
+ c->watch_reg_count = 7;
+ t = read_c0_watchhi6();
+ if ((t & 0x80000000) == 0)
+ return;
+
+ c->watch_reg_count = 8;
+}
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
new file mode 100644
index 00000000..3fccf210
--- /dev/null
+++ b/arch/mips/lantiq/Kconfig
@@ -0,0 +1,23 @@
+if LANTIQ
+
+config SOC_TYPE_XWAY
+ bool
+ default n
+
+choice
+ prompt "SoC Type"
+ default SOC_XWAY
+
+config SOC_AMAZON_SE
+ bool "Amazon SE"
+ select SOC_TYPE_XWAY
+
+config SOC_XWAY
+ bool "XWAY"
+ select SOC_TYPE_XWAY
+ select HW_HAS_PCI
+endchoice
+
+source "arch/mips/lantiq/xway/Kconfig"
+
+endif
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile
new file mode 100644
index 00000000..e5dae0e2
--- /dev/null
+++ b/arch/mips/lantiq/Makefile
@@ -0,0 +1,11 @@
+# Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+
+obj-y := irq.o setup.o clk.o prom.o devices.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform
new file mode 100644
index 00000000..f3dff057
--- /dev/null
+++ b/arch/mips/lantiq/Platform
@@ -0,0 +1,8 @@
+#
+# Lantiq
+#
+
+platform-$(CONFIG_LANTIQ) += lantiq/
+cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq
+load-$(CONFIG_LANTIQ) = 0xffffffff80002000
+cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
new file mode 100644
index 00000000..94560899
--- /dev/null
+++ b/arch/mips/lantiq/clk.c
@@ -0,0 +1,140 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/list.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+#include "clk.h"
+
+struct clk {
+ const char *name;
+ unsigned long rate;
+ unsigned long (*get_rate) (void);
+};
+
+static struct clk *cpu_clk;
+static int cpu_clk_cnt;
+
+/* lantiq socs have 3 static clocks */
+static struct clk cpu_clk_generic[] = {
+ {
+ .name = "cpu",
+ .get_rate = ltq_get_cpu_hz,
+ }, {
+ .name = "fpi",
+ .get_rate = ltq_get_fpi_hz,
+ }, {
+ .name = "io",
+ .get_rate = ltq_get_io_region_clock,
+ },
+};
+
+static struct resource ltq_cgu_resource = {
+ .name = "cgu",
+ .start = LTQ_CGU_BASE_ADDR,
+ .end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+/* remapped clock register range */
+void __iomem *ltq_cgu_membase;
+
+void clk_init(void)
+{
+ cpu_clk = cpu_clk_generic;
+ cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
+}
+
+static inline int clk_good(struct clk *clk)
+{
+ return clk && !IS_ERR(clk);
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (unlikely(!clk_good(clk)))
+ return 0;
+
+ if (clk->rate != 0)
+ return clk->rate;
+
+ if (clk->get_rate != NULL)
+ return clk->get_rate();
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ int i;
+
+ for (i = 0; i < cpu_clk_cnt; i++)
+ if (!strcmp(id, cpu_clk[i].name))
+ return &cpu_clk[i];
+ BUG();
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+ /* not used */
+}
+EXPORT_SYMBOL(clk_put);
+
+static inline u32 ltq_get_counter_resolution(void)
+{
+ u32 res;
+
+ __asm__ __volatile__(
+ ".set push\n"
+ ".set mips32r2\n"
+ "rdhwr %0, $3\n"
+ ".set pop\n"
+ : "=&r" (res)
+ : /* no input */
+ : "memory");
+
+ return res;
+}
+
+void __init plat_time_init(void)
+{
+ struct clk *clk;
+
+ if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
+ panic("Failed to insert cgu memory\n");
+
+ if (request_mem_region(ltq_cgu_resource.start,
+ resource_size(&ltq_cgu_resource), "cgu") < 0)
+ panic("Failed to request cgu memory\n");
+
+ ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
+ resource_size(&ltq_cgu_resource));
+ if (!ltq_cgu_membase) {
+ pr_err("Failed to remap cgu memory\n");
+ unreachable();
+ }
+ clk = clk_get(0, "cpu");
+ mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
+ write_c0_compare(read_c0_count());
+ clk_put(clk);
+}
diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h
new file mode 100644
index 00000000..3328925f
--- /dev/null
+++ b/arch/mips/lantiq/clk.h
@@ -0,0 +1,18 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_CLK_H__
+#define _LTQ_CLK_H__
+
+extern void clk_init(void);
+
+extern unsigned long ltq_get_cpu_hz(void);
+extern unsigned long ltq_get_fpi_hz(void);
+extern unsigned long ltq_get_io_region_clock(void);
+
+#endif
diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c
new file mode 100644
index 00000000..7b82c34c
--- /dev/null
+++ b/arch/mips/lantiq/devices.c
@@ -0,0 +1,122 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/etherdevice.h>
+#include <linux/reboot.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+
+#include <lantiq_soc.h>
+
+#include "devices.h"
+
+/* nor flash */
+static struct resource ltq_nor_resource = {
+ .name = "nor",
+ .start = LTQ_FLASH_START,
+ .end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ltq_nor = {
+ .name = "ltq_nor",
+ .resource = &ltq_nor_resource,
+ .num_resources = 1,
+};
+
+void __init ltq_register_nor(struct physmap_flash_data *data)
+{
+ ltq_nor.dev.platform_data = data;
+ platform_device_register(&ltq_nor);
+}
+
+/* watchdog */
+static struct resource ltq_wdt_resource = {
+ .name = "watchdog",
+ .start = LTQ_WDT_BASE_ADDR,
+ .end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+void __init ltq_register_wdt(void)
+{
+ platform_device_register_simple("ltq_wdt", 0, &ltq_wdt_resource, 1);
+}
+
+/* asc ports */
+static struct resource ltq_asc0_resources[] = {
+ {
+ .name = "asc0",
+ .start = LTQ_ASC0_BASE_ADDR,
+ .end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ IRQ_RES(tx, LTQ_ASC_TIR(0)),
+ IRQ_RES(rx, LTQ_ASC_RIR(0)),
+ IRQ_RES(err, LTQ_ASC_EIR(0)),
+};
+
+static struct resource ltq_asc1_resources[] = {
+ {
+ .name = "asc1",
+ .start = LTQ_ASC1_BASE_ADDR,
+ .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ IRQ_RES(tx, LTQ_ASC_TIR(1)),
+ IRQ_RES(rx, LTQ_ASC_RIR(1)),
+ IRQ_RES(err, LTQ_ASC_EIR(1)),
+};
+
+void __init ltq_register_asc(int port)
+{
+ switch (port) {
+ case 0:
+ platform_device_register_simple("ltq_asc", 0,
+ ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources));
+ break;
+ case 1:
+ platform_device_register_simple("ltq_asc", 1,
+ ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources));
+ break;
+ default:
+ break;
+ }
+}
+
+#ifdef CONFIG_PCI
+/* pci */
+static struct platform_device ltq_pci = {
+ .name = "ltq_pci",
+ .num_resources = 0,
+};
+
+void __init ltq_register_pci(struct ltq_pci_data *data)
+{
+ ltq_pci.dev.platform_data = data;
+ platform_device_register(&ltq_pci);
+}
+#else
+void __init ltq_register_pci(struct ltq_pci_data *data)
+{
+ pr_err("kernel is compiled without PCI support\n");
+}
+#endif
diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h
new file mode 100644
index 00000000..2947bb19
--- /dev/null
+++ b/arch/mips/lantiq/devices.h
@@ -0,0 +1,23 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_DEVICES_H__
+#define _LTQ_DEVICES_H__
+
+#include <lantiq_platform.h>
+#include <linux/mtd/physmap.h>
+
+#define IRQ_RES(resname, irq) \
+ {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
+
+extern void ltq_register_nor(struct physmap_flash_data *data);
+extern void ltq_register_wdt(void);
+extern void ltq_register_asc(int port);
+extern void ltq_register_pci(struct ltq_pci_data *data);
+
+#endif
diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c
new file mode 100644
index 00000000..972e05f8
--- /dev/null
+++ b/arch/mips/lantiq/early_printk.c
@@ -0,0 +1,33 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/cpu.h>
+
+#include <lantiq.h>
+#include <lantiq_soc.h>
+
+/* no ioremap possible at this early stage, lets use KSEG1 instead */
+#define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
+#define ASC_BUF 1024
+#define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048))
+#define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020))
+#define TXMASK 0x3F00
+#define TXOFFSET 8
+
+void prom_putchar(char c)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
+ if (c == '\n')
+ ltq_w32('\r', LTQ_ASC_TBUF);
+ ltq_w32(c, LTQ_ASC_TBUF);
+ local_irq_restore(flags);
+}
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
new file mode 100644
index 00000000..fc89795c
--- /dev/null
+++ b/arch/mips/lantiq/irq.c
@@ -0,0 +1,326 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq_cpu.h>
+
+#include <lantiq_soc.h>
+#include <irq.h>
+
+/* register definitions */
+#define LTQ_ICU_IM0_ISR 0x0000
+#define LTQ_ICU_IM0_IER 0x0008
+#define LTQ_ICU_IM0_IOSR 0x0010
+#define LTQ_ICU_IM0_IRSR 0x0018
+#define LTQ_ICU_IM0_IMR 0x0020
+#define LTQ_ICU_IM1_ISR 0x0028
+#define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
+
+#define LTQ_EIU_EXIN_C 0x0000
+#define LTQ_EIU_EXIN_INIC 0x0004
+#define LTQ_EIU_EXIN_INEN 0x000C
+
+/* irq numbers used by the external interrupt unit (EIU) */
+#define LTQ_EIU_IR0 (INT_NUM_IM4_IRL0 + 30)
+#define LTQ_EIU_IR1 (INT_NUM_IM3_IRL0 + 31)
+#define LTQ_EIU_IR2 (INT_NUM_IM1_IRL0 + 26)
+#define LTQ_EIU_IR3 INT_NUM_IM1_IRL0
+#define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1)
+#define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2)
+#define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30)
+
+#define MAX_EIU 6
+
+/* irqs generated by device attached to the EBU need to be acked in
+ * a special manner
+ */
+#define LTQ_ICU_EBU_IRQ 22
+
+#define ltq_icu_w32(x, y) ltq_w32((x), ltq_icu_membase + (y))
+#define ltq_icu_r32(x) ltq_r32(ltq_icu_membase + (x))
+
+#define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y))
+#define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x))
+
+static unsigned short ltq_eiu_irq[MAX_EIU] = {
+ LTQ_EIU_IR0,
+ LTQ_EIU_IR1,
+ LTQ_EIU_IR2,
+ LTQ_EIU_IR3,
+ LTQ_EIU_IR4,
+ LTQ_EIU_IR5,
+};
+
+static struct resource ltq_icu_resource = {
+ .name = "icu",
+ .start = LTQ_ICU_BASE_ADDR,
+ .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource ltq_eiu_resource = {
+ .name = "eiu",
+ .start = LTQ_EIU_BASE_ADDR,
+ .end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static void __iomem *ltq_icu_membase;
+static void __iomem *ltq_eiu_membase;
+
+void ltq_disable_irq(struct irq_data *d)
+{
+ u32 ier = LTQ_ICU_IM0_IER;
+ int irq_nr = d->irq - INT_NUM_IRQ0;
+
+ ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+ irq_nr %= INT_NUM_IM_OFFSET;
+ ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
+}
+
+void ltq_mask_and_ack_irq(struct irq_data *d)
+{
+ u32 ier = LTQ_ICU_IM0_IER;
+ u32 isr = LTQ_ICU_IM0_ISR;
+ int irq_nr = d->irq - INT_NUM_IRQ0;
+
+ ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+ isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+ irq_nr %= INT_NUM_IM_OFFSET;
+ ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
+ ltq_icu_w32((1 << irq_nr), isr);
+}
+
+static void ltq_ack_irq(struct irq_data *d)
+{
+ u32 isr = LTQ_ICU_IM0_ISR;
+ int irq_nr = d->irq - INT_NUM_IRQ0;
+
+ isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+ irq_nr %= INT_NUM_IM_OFFSET;
+ ltq_icu_w32((1 << irq_nr), isr);
+}
+
+void ltq_enable_irq(struct irq_data *d)
+{
+ u32 ier = LTQ_ICU_IM0_IER;
+ int irq_nr = d->irq - INT_NUM_IRQ0;
+
+ ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+ irq_nr %= INT_NUM_IM_OFFSET;
+ ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
+}
+
+static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
+{
+ int i;
+ int irq_nr = d->irq - INT_NUM_IRQ0;
+
+ ltq_enable_irq(d);
+ for (i = 0; i < MAX_EIU; i++) {
+ if (irq_nr == ltq_eiu_irq[i]) {
+ /* low level - we should really handle set_type */
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
+ (0x6 << (i * 4)), LTQ_EIU_EXIN_C);
+ /* clear all pending */
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i),
+ LTQ_EIU_EXIN_INIC);
+ /* enable */
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i),
+ LTQ_EIU_EXIN_INEN);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static void ltq_shutdown_eiu_irq(struct irq_data *d)
+{
+ int i;
+ int irq_nr = d->irq - INT_NUM_IRQ0;
+
+ ltq_disable_irq(d);
+ for (i = 0; i < MAX_EIU; i++) {
+ if (irq_nr == ltq_eiu_irq[i]) {
+ /* disable */
+ ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i),
+ LTQ_EIU_EXIN_INEN);
+ break;
+ }
+ }
+}
+
+static struct irq_chip ltq_irq_type = {
+ "icu",
+ .irq_enable = ltq_enable_irq,
+ .irq_disable = ltq_disable_irq,
+ .irq_unmask = ltq_enable_irq,
+ .irq_ack = ltq_ack_irq,
+ .irq_mask = ltq_disable_irq,
+ .irq_mask_ack = ltq_mask_and_ack_irq,
+};
+
+static struct irq_chip ltq_eiu_type = {
+ "eiu",
+ .irq_startup = ltq_startup_eiu_irq,
+ .irq_shutdown = ltq_shutdown_eiu_irq,
+ .irq_enable = ltq_enable_irq,
+ .irq_disable = ltq_disable_irq,
+ .irq_unmask = ltq_enable_irq,
+ .irq_ack = ltq_ack_irq,
+ .irq_mask = ltq_disable_irq,
+ .irq_mask_ack = ltq_mask_and_ack_irq,
+};
+
+static void ltq_hw_irqdispatch(int module)
+{
+ u32 irq;
+
+ irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
+ if (irq == 0)
+ return;
+
+ /* silicon bug causes only the msb set to 1 to be valid. all
+ * other bits might be bogus
+ */
+ irq = __fls(irq);
+ do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
+
+ /* if this is a EBU irq, we need to ack it or get a deadlock */
+ if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0))
+ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
+ LTQ_EBU_PCC_ISTAT);
+}
+
+#define DEFINE_HWx_IRQDISPATCH(x) \
+ static void ltq_hw ## x ## _irqdispatch(void) \
+ { \
+ ltq_hw_irqdispatch(x); \
+ }
+DEFINE_HWx_IRQDISPATCH(0)
+DEFINE_HWx_IRQDISPATCH(1)
+DEFINE_HWx_IRQDISPATCH(2)
+DEFINE_HWx_IRQDISPATCH(3)
+DEFINE_HWx_IRQDISPATCH(4)
+
+static void ltq_hw5_irqdispatch(void)
+{
+ do_IRQ(MIPS_CPU_TIMER_IRQ);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+ unsigned int i;
+
+ if (pending & CAUSEF_IP7) {
+ do_IRQ(MIPS_CPU_TIMER_IRQ);
+ goto out;
+ } else {
+ for (i = 0; i < 5; i++) {
+ if (pending & (CAUSEF_IP2 << i)) {
+ ltq_hw_irqdispatch(i);
+ goto out;
+ }
+ }
+ }
+ pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
+
+out:
+ return;
+}
+
+static struct irqaction cascade = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED,
+ .name = "cascade",
+};
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ if (insert_resource(&iomem_resource, &ltq_icu_resource) < 0)
+ panic("Failed to insert icu memory\n");
+
+ if (request_mem_region(ltq_icu_resource.start,
+ resource_size(&ltq_icu_resource), "icu") < 0)
+ panic("Failed to request icu memory\n");
+
+ ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start,
+ resource_size(&ltq_icu_resource));
+ if (!ltq_icu_membase)
+ panic("Failed to remap icu memory\n");
+
+ if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
+ panic("Failed to insert eiu memory\n");
+
+ if (request_mem_region(ltq_eiu_resource.start,
+ resource_size(&ltq_eiu_resource), "eiu") < 0)
+ panic("Failed to request eiu memory\n");
+
+ ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
+ resource_size(&ltq_eiu_resource));
+ if (!ltq_eiu_membase)
+ panic("Failed to remap eiu memory\n");
+
+ /* make sure all irqs are turned off by default */
+ for (i = 0; i < 5; i++)
+ ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
+
+ /* clear all possibly pending interrupts */
+ ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
+
+ mips_cpu_irq_init();
+
+ for (i = 2; i <= 6; i++)
+ setup_irq(i, &cascade);
+
+ if (cpu_has_vint) {
+ pr_info("Setting up vectored interrupts\n");
+ set_vi_handler(2, ltq_hw0_irqdispatch);
+ set_vi_handler(3, ltq_hw1_irqdispatch);
+ set_vi_handler(4, ltq_hw2_irqdispatch);
+ set_vi_handler(5, ltq_hw3_irqdispatch);
+ set_vi_handler(6, ltq_hw4_irqdispatch);
+ set_vi_handler(7, ltq_hw5_irqdispatch);
+ }
+
+ for (i = INT_NUM_IRQ0;
+ i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
+ if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
+ (i == LTQ_EIU_IR2))
+ irq_set_chip_and_handler(i, &ltq_eiu_type,
+ handle_level_irq);
+ /* EIU3-5 only exist on ar9 and vr9 */
+ else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) ||
+ (i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9()))
+ irq_set_chip_and_handler(i, &ltq_eiu_type,
+ handle_level_irq);
+ else
+ irq_set_chip_and_handler(i, &ltq_irq_type,
+ handle_level_irq);
+
+#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
+ set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
+ IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+#else
+ set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
+ IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+#endif
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ return CP0_LEGACY_COMPARE_IRQ;
+}
diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h
new file mode 100644
index 00000000..7e01b8c4
--- /dev/null
+++ b/arch/mips/lantiq/machtypes.h
@@ -0,0 +1,20 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_MACH_H__
+#define _LANTIQ_MACH_H__
+
+#include <asm/mips_machine.h>
+
+enum lantiq_mach_type {
+ LTQ_MACH_GENERIC = 0,
+ LTQ_MACH_EASY50712, /* Danube evaluation board */
+ LTQ_MACH_EASY50601, /* Amazon SE evaluation board */
+};
+
+#endif
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
new file mode 100644
index 00000000..56ba007b
--- /dev/null
+++ b/arch/mips/lantiq/prom.c
@@ -0,0 +1,71 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq.h>
+
+#include "prom.h"
+#include "clk.h"
+
+static struct ltq_soc_info soc_info;
+
+unsigned int ltq_get_cpu_ver(void)
+{
+ return soc_info.rev;
+}
+EXPORT_SYMBOL(ltq_get_cpu_ver);
+
+unsigned int ltq_get_soc_type(void)
+{
+ return soc_info.type;
+}
+EXPORT_SYMBOL(ltq_get_soc_type);
+
+const char *get_system_type(void)
+{
+ return soc_info.sys_type;
+}
+
+void prom_free_prom_memory(void)
+{
+}
+
+static void __init prom_init_cmdline(void)
+{
+ int argc = fw_arg0;
+ char **argv = (char **) KSEG1ADDR(fw_arg1);
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ char *p = (char *) KSEG1ADDR(argv[i]);
+
+ if (p && *p) {
+ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+ }
+ }
+}
+
+void __init prom_init(void)
+{
+ struct clk *clk;
+
+ ltq_soc_detect(&soc_info);
+ clk_init();
+ clk = clk_get(0, "cpu");
+ snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d",
+ soc_info.name, soc_info.rev);
+ clk_put(clk);
+ soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
+ pr_info("SoC: %s\n", soc_info.sys_type);
+ prom_init_cmdline();
+}
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h
new file mode 100644
index 00000000..b4229d94
--- /dev/null
+++ b/arch/mips/lantiq/prom.h
@@ -0,0 +1,25 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_PROM_H__
+#define _LTQ_PROM_H__
+
+#define LTQ_SYS_TYPE_LEN 0x100
+
+struct ltq_soc_info {
+ unsigned char *name;
+ unsigned int rev;
+ unsigned int partnum;
+ unsigned int type;
+ unsigned char sys_type[LTQ_SYS_TYPE_LEN];
+};
+
+extern void ltq_soc_detect(struct ltq_soc_info *i);
+extern void ltq_soc_setup(void);
+
+#endif
diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c
new file mode 100644
index 00000000..9b8af77e
--- /dev/null
+++ b/arch/mips/lantiq/setup.c
@@ -0,0 +1,66 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <asm/bootinfo.h>
+
+#include <lantiq_soc.h>
+
+#include "machtypes.h"
+#include "devices.h"
+#include "prom.h"
+
+void __init plat_mem_setup(void)
+{
+ /* assume 16M as default incase uboot fails to pass proper ramsize */
+ unsigned long memsize = 16;
+ char **envp = (char **) KSEG1ADDR(fw_arg2);
+
+ ioport_resource.start = IOPORT_RESOURCE_START;
+ ioport_resource.end = IOPORT_RESOURCE_END;
+ iomem_resource.start = IOMEM_RESOURCE_START;
+ iomem_resource.end = IOMEM_RESOURCE_END;
+
+ set_io_port_base((unsigned long) KSEG1);
+
+ while (*envp) {
+ char *e = (char *)KSEG1ADDR(*envp);
+ if (!strncmp(e, "memsize=", 8)) {
+ e += 8;
+ if (strict_strtoul(e, 0, &memsize))
+ pr_warn("bad memsize specified\n");
+ }
+ envp++;
+ }
+ memsize *= 1024 * 1024;
+ add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
+}
+
+static int __init
+lantiq_setup(void)
+{
+ ltq_soc_setup();
+ mips_machine_setup();
+ return 0;
+}
+
+arch_initcall(lantiq_setup);
+
+static void __init
+lantiq_generic_init(void)
+{
+ /* Nothing to do */
+}
+
+MIPS_MACHINE(LTQ_MACH_GENERIC,
+ "Generic",
+ "Generic Lantiq based board",
+ lantiq_generic_init);
diff --git a/arch/mips/lantiq/xway/Kconfig b/arch/mips/lantiq/xway/Kconfig
new file mode 100644
index 00000000..2b857de3
--- /dev/null
+++ b/arch/mips/lantiq/xway/Kconfig
@@ -0,0 +1,23 @@
+if SOC_XWAY
+
+menu "MIPS Machine"
+
+config LANTIQ_MACH_EASY50712
+ bool "Easy50712 - Danube"
+ default y
+
+endmenu
+
+endif
+
+if SOC_AMAZON_SE
+
+menu "MIPS Machine"
+
+config LANTIQ_MACH_EASY50601
+ bool "Easy50601 - Amazon SE"
+ default y
+
+endmenu
+
+endif
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
new file mode 100644
index 00000000..c517f2e7
--- /dev/null
+++ b/arch/mips/lantiq/xway/Makefile
@@ -0,0 +1,7 @@
+obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
+
+obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o
+obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o
+
+obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
+obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c
new file mode 100644
index 00000000..22d823ac
--- /dev/null
+++ b/arch/mips/lantiq/xway/clk-ase.c
@@ -0,0 +1,48 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+/* cgu registers */
+#define LTQ_CGU_SYS 0x0010
+
+unsigned int ltq_get_io_region_clock(void)
+{
+ return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_io_region_clock);
+
+unsigned int ltq_get_fpi_bus_clock(int fpi)
+{
+ return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
+
+unsigned int ltq_get_cpu_hz(void)
+{
+ if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
+ return CLOCK_266M;
+ else
+ return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_cpu_hz);
+
+unsigned int ltq_get_fpi_hz(void)
+{
+ return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_fpi_hz);
diff --git a/arch/mips/lantiq/xway/clk-xway.c b/arch/mips/lantiq/xway/clk-xway.c
new file mode 100644
index 00000000..ddd39593
--- /dev/null
+++ b/arch/mips/lantiq/xway/clk-xway.c
@@ -0,0 +1,223 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+static unsigned int ltq_ram_clocks[] = {
+ CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
+#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
+
+#define BASIC_FREQUENCY_1 35328000
+#define BASIC_FREQUENCY_2 36000000
+#define BASIS_REQUENCY_USB 12000000
+
+#define GET_BITS(x, msb, lsb) \
+ (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
+
+#define LTQ_CGU_PLL0_CFG 0x0004
+#define LTQ_CGU_PLL1_CFG 0x0008
+#define LTQ_CGU_PLL2_CFG 0x000C
+#define LTQ_CGU_SYS 0x0010
+#define LTQ_CGU_UPDATE 0x0014
+#define LTQ_CGU_IF_CLK 0x0018
+#define LTQ_CGU_OSC_CON 0x001C
+#define LTQ_CGU_SMD 0x0020
+#define LTQ_CGU_CT1SR 0x0028
+#define LTQ_CGU_CT2SR 0x002C
+#define LTQ_CGU_PCMCR 0x0030
+#define LTQ_CGU_PCI_CR 0x0034
+#define LTQ_CGU_PD_PC 0x0038
+#define LTQ_CGU_FMR 0x003C
+
+#define CGU_PLL0_PHASE_DIVIDER_ENABLE \
+ (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
+#define CGU_PLL0_BYPASS \
+ (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
+#define CGU_PLL0_CFG_DSMSEL \
+ (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
+#define CGU_PLL0_CFG_FRAC_EN \
+ (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
+#define CGU_PLL1_SRC \
+ (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
+#define CGU_PLL2_PHASE_DIVIDER_ENABLE \
+ (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
+#define CGU_SYS_FPI_SEL (1 << 6)
+#define CGU_SYS_DDR_SEL 0x3
+#define CGU_PLL0_SRC (1 << 29)
+
+#define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
+#define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
+#define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
+#define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
+#define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
+
+static unsigned int ltq_get_pll0_fdiv(void);
+
+static inline unsigned int get_input_clock(int pll)
+{
+ switch (pll) {
+ case 0:
+ if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
+ return BASIS_REQUENCY_USB;
+ else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
+ return BASIC_FREQUENCY_1;
+ else
+ return BASIC_FREQUENCY_2;
+ case 1:
+ if (CGU_PLL1_SRC)
+ return BASIS_REQUENCY_USB;
+ else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
+ return BASIC_FREQUENCY_1;
+ else
+ return BASIC_FREQUENCY_2;
+ case 2:
+ switch (CGU_PLL2_SRC) {
+ case 0:
+ return ltq_get_pll0_fdiv();
+ case 1:
+ return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
+ BASIC_FREQUENCY_1 :
+ BASIC_FREQUENCY_2;
+ case 2:
+ return BASIS_REQUENCY_USB;
+ }
+ default:
+ return 0;
+ }
+}
+
+static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
+{
+ u64 res, clock = get_input_clock(pll);
+
+ res = num * clock;
+ do_div(res, den);
+ return res;
+}
+
+static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
+ unsigned int K)
+{
+ unsigned int num = ((N + 1) << 10) + K;
+ unsigned int den = (M + 1) << 10;
+
+ return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
+ unsigned int K)
+{
+ unsigned int num = ((N + 1) << 11) + K + 512;
+ unsigned int den = (M + 1) << 11;
+
+ return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
+ unsigned int K)
+{
+ unsigned int num = K >= 512 ?
+ ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
+ unsigned int den = (M + 1) << 12;
+
+ return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
+ unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
+{
+ if (!dsmsel)
+ return mash_dsm(pll, M, N, K);
+ else if (!phase_div_en)
+ return mash_dsm(pll, M, N, K);
+ else
+ return ssff_dsm_2(pll, M, N, K);
+}
+
+static inline unsigned int ltq_get_pll0_fosc(void)
+{
+ if (CGU_PLL0_BYPASS)
+ return get_input_clock(0);
+ else
+ return !CGU_PLL0_CFG_FRAC_EN
+ ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
+ CGU_PLL0_CFG_DSMSEL,
+ CGU_PLL0_PHASE_DIVIDER_ENABLE)
+ : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
+ CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
+ CGU_PLL0_PHASE_DIVIDER_ENABLE);
+}
+
+static unsigned int ltq_get_pll0_fdiv(void)
+{
+ unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
+
+ return (ltq_get_pll0_fosc() + (div >> 1)) / div;
+}
+
+unsigned int ltq_get_io_region_clock(void)
+{
+ unsigned int ret = ltq_get_pll0_fosc();
+
+ switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
+ default:
+ case 0:
+ return (ret + 1) / 2;
+ case 1:
+ return (ret * 2 + 2) / 5;
+ case 2:
+ return (ret + 1) / 3;
+ case 3:
+ return (ret + 2) / 4;
+ }
+}
+EXPORT_SYMBOL(ltq_get_io_region_clock);
+
+unsigned int ltq_get_fpi_bus_clock(int fpi)
+{
+ unsigned int ret = ltq_get_io_region_clock();
+
+ if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
+ ret >>= 1;
+ return ret;
+}
+EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
+
+unsigned int ltq_get_cpu_hz(void)
+{
+ switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
+ case 0:
+ return CLOCK_333M;
+ case 4:
+ return DDR_HZ;
+ case 8:
+ return DDR_HZ << 1;
+ default:
+ return DDR_HZ >> 1;
+ }
+}
+EXPORT_SYMBOL(ltq_get_cpu_hz);
+
+unsigned int ltq_get_fpi_hz(void)
+{
+ unsigned int ddr_clock = DDR_HZ;
+
+ if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
+ return ddr_clock >> 1;
+ return ddr_clock;
+}
+EXPORT_SYMBOL(ltq_get_fpi_hz);
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c
new file mode 100644
index 00000000..e09e789d
--- /dev/null
+++ b/arch/mips/lantiq/xway/devices.c
@@ -0,0 +1,121 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mtd/physmap.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/etherdevice.h>
+#include <linux/reboot.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_irq.h>
+#include <lantiq_platform.h>
+
+#include "devices.h"
+
+/* gpio */
+static struct resource ltq_gpio_resource[] = {
+ {
+ .name = "gpio0",
+ .start = LTQ_GPIO0_BASE_ADDR,
+ .end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "gpio1",
+ .start = LTQ_GPIO1_BASE_ADDR,
+ .end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "gpio2",
+ .start = LTQ_GPIO2_BASE_ADDR,
+ .end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+void __init ltq_register_gpio(void)
+{
+ platform_device_register_simple("ltq_gpio", 0,
+ &ltq_gpio_resource[0], 1);
+ platform_device_register_simple("ltq_gpio", 1,
+ &ltq_gpio_resource[1], 1);
+
+ /* AR9 and VR9 have an extra gpio block */
+ if (ltq_is_ar9() || ltq_is_vr9()) {
+ platform_device_register_simple("ltq_gpio", 2,
+ &ltq_gpio_resource[2], 1);
+ }
+}
+
+/* serial to parallel conversion */
+static struct resource ltq_stp_resource = {
+ .name = "stp",
+ .start = LTQ_STP_BASE_ADDR,
+ .end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+void __init ltq_register_gpio_stp(void)
+{
+ platform_device_register_simple("ltq_stp", 0, &ltq_stp_resource, 1);
+}
+
+/* asc ports - amazon se has its own serial mapping */
+static struct resource ltq_ase_asc_resources[] = {
+ {
+ .name = "asc0",
+ .start = LTQ_ASC1_BASE_ADDR,
+ .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ IRQ_RES(tx, LTQ_ASC_ASE_TIR),
+ IRQ_RES(rx, LTQ_ASC_ASE_RIR),
+ IRQ_RES(err, LTQ_ASC_ASE_EIR),
+};
+
+void __init ltq_register_ase_asc(void)
+{
+ platform_device_register_simple("ltq_asc", 0,
+ ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources));
+}
+
+/* ethernet */
+static struct resource ltq_etop_resources = {
+ .name = "etop",
+ .start = LTQ_ETOP_BASE_ADDR,
+ .end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ltq_etop = {
+ .name = "ltq_etop",
+ .resource = &ltq_etop_resources,
+ .num_resources = 1,
+};
+
+void __init
+ltq_register_etop(struct ltq_eth_data *eth)
+{
+ if (eth) {
+ ltq_etop.dev.platform_data = eth;
+ platform_device_register(&ltq_etop);
+ }
+}
diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h
new file mode 100644
index 00000000..e9049347
--- /dev/null
+++ b/arch/mips/lantiq/xway/devices.h
@@ -0,0 +1,20 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_DEVICES_XWAY_H__
+#define _LTQ_DEVICES_XWAY_H__
+
+#include "../devices.h"
+#include <linux/phy.h>
+
+extern void ltq_register_gpio(void);
+extern void ltq_register_gpio_stp(void);
+extern void ltq_register_ase_asc(void);
+extern void ltq_register_etop(struct ltq_eth_data *eth);
+
+#endif
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
new file mode 100644
index 00000000..4278a459
--- /dev/null
+++ b/arch/mips/lantiq/xway/dma.c
@@ -0,0 +1,253 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include <lantiq_soc.h>
+#include <xway_dma.h>
+
+#define LTQ_DMA_CTRL 0x10
+#define LTQ_DMA_CPOLL 0x14
+#define LTQ_DMA_CS 0x18
+#define LTQ_DMA_CCTRL 0x1C
+#define LTQ_DMA_CDBA 0x20
+#define LTQ_DMA_CDLEN 0x24
+#define LTQ_DMA_CIS 0x28
+#define LTQ_DMA_CIE 0x2C
+#define LTQ_DMA_PS 0x40
+#define LTQ_DMA_PCTRL 0x44
+#define LTQ_DMA_IRNEN 0xf4
+
+#define DMA_DESCPT BIT(3) /* descriptor complete irq */
+#define DMA_TX BIT(8) /* TX channel direction */
+#define DMA_CHAN_ON BIT(0) /* channel on / off bit */
+#define DMA_PDEN BIT(6) /* enable packet drop */
+#define DMA_CHAN_RST BIT(1) /* channel on / off bit */
+#define DMA_RESET BIT(0) /* channel on / off bit */
+#define DMA_IRQ_ACK 0x7e /* IRQ status register */
+#define DMA_POLL BIT(31) /* turn on channel polling */
+#define DMA_CLK_DIV4 BIT(6) /* polling clock divider */
+#define DMA_2W_BURST BIT(1) /* 2 word burst length */
+#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */
+#define DMA_ETOP_ENDIANESS (0xf << 8) /* endianess swap etop channels */
+#define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */
+
+#define ltq_dma_r32(x) ltq_r32(ltq_dma_membase + (x))
+#define ltq_dma_w32(x, y) ltq_w32(x, ltq_dma_membase + (y))
+#define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \
+ ltq_dma_membase + (z))
+
+static struct resource ltq_dma_resource = {
+ .name = "dma",
+ .start = LTQ_DMA_BASE_ADDR,
+ .end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static void __iomem *ltq_dma_membase;
+
+void
+ltq_dma_enable_irq(struct ltq_dma_channel *ch)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+ ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_enable_irq);
+
+void
+ltq_dma_disable_irq(struct ltq_dma_channel *ch)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+ ltq_dma_w32_mask(1 << ch->nr, 0, LTQ_DMA_IRNEN);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_disable_irq);
+
+void
+ltq_dma_ack_irq(struct ltq_dma_channel *ch)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+ ltq_dma_w32(DMA_IRQ_ACK, LTQ_DMA_CIS);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_ack_irq);
+
+void
+ltq_dma_open(struct ltq_dma_channel *ch)
+{
+ unsigned long flag;
+
+ local_irq_save(flag);
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+ ltq_dma_w32_mask(0, DMA_CHAN_ON, LTQ_DMA_CCTRL);
+ ltq_dma_enable_irq(ch);
+ local_irq_restore(flag);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_open);
+
+void
+ltq_dma_close(struct ltq_dma_channel *ch)
+{
+ unsigned long flag;
+
+ local_irq_save(flag);
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+ ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
+ ltq_dma_disable_irq(ch);
+ local_irq_restore(flag);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_close);
+
+static void
+ltq_dma_alloc(struct ltq_dma_channel *ch)
+{
+ unsigned long flags;
+
+ ch->desc = 0;
+ ch->desc_base = dma_alloc_coherent(NULL,
+ LTQ_DESC_NUM * LTQ_DESC_SIZE,
+ &ch->phys, GFP_ATOMIC);
+ memset(ch->desc_base, 0, LTQ_DESC_NUM * LTQ_DESC_SIZE);
+
+ local_irq_save(flags);
+ ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+ ltq_dma_w32(ch->phys, LTQ_DMA_CDBA);
+ ltq_dma_w32(LTQ_DESC_NUM, LTQ_DMA_CDLEN);
+ ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
+ wmb();
+ ltq_dma_w32_mask(0, DMA_CHAN_RST, LTQ_DMA_CCTRL);
+ while (ltq_dma_r32(LTQ_DMA_CCTRL) & DMA_CHAN_RST)
+ ;
+ local_irq_restore(flags);
+}
+
+void
+ltq_dma_alloc_tx(struct ltq_dma_channel *ch)
+{
+ unsigned long flags;
+
+ ltq_dma_alloc(ch);
+
+ local_irq_save(flags);
+ ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE);
+ ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
+ ltq_dma_w32(DMA_WEIGHT | DMA_TX, LTQ_DMA_CCTRL);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_alloc_tx);
+
+void
+ltq_dma_alloc_rx(struct ltq_dma_channel *ch)
+{
+ unsigned long flags;
+
+ ltq_dma_alloc(ch);
+
+ local_irq_save(flags);
+ ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE);
+ ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
+ ltq_dma_w32(DMA_WEIGHT, LTQ_DMA_CCTRL);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_alloc_rx);
+
+void
+ltq_dma_free(struct ltq_dma_channel *ch)
+{
+ if (!ch->desc_base)
+ return;
+ ltq_dma_close(ch);
+ dma_free_coherent(NULL, LTQ_DESC_NUM * LTQ_DESC_SIZE,
+ ch->desc_base, ch->phys);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_free);
+
+void
+ltq_dma_init_port(int p)
+{
+ ltq_dma_w32(p, LTQ_DMA_PS);
+ switch (p) {
+ case DMA_PORT_ETOP:
+ /*
+ * Tell the DMA engine to swap the endianess of data frames and
+ * drop packets if the channel arbitration fails.
+ */
+ ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN,
+ LTQ_DMA_PCTRL);
+ break;
+
+ case DMA_PORT_DEU:
+ ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2),
+ LTQ_DMA_PCTRL);
+ break;
+
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL_GPL(ltq_dma_init_port);
+
+int __init
+ltq_dma_init(void)
+{
+ int i;
+
+ /* insert and request the memory region */
+ if (insert_resource(&iomem_resource, &ltq_dma_resource) < 0)
+ panic("Failed to insert dma memory\n");
+
+ if (request_mem_region(ltq_dma_resource.start,
+ resource_size(&ltq_dma_resource), "dma") < 0)
+ panic("Failed to request dma memory\n");
+
+ /* remap dma register range */
+ ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start,
+ resource_size(&ltq_dma_resource));
+ if (!ltq_dma_membase)
+ panic("Failed to remap dma memory\n");
+
+ /* power up and reset the dma engine */
+ ltq_pmu_enable(PMU_DMA);
+ ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL);
+
+ /* disable all interrupts */
+ ltq_dma_w32(0, LTQ_DMA_IRNEN);
+
+ /* reset/configure each channel */
+ for (i = 0; i < DMA_MAX_CHANNEL; i++) {
+ ltq_dma_w32(i, LTQ_DMA_CS);
+ ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL);
+ ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
+ ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
+ }
+ return 0;
+}
+
+postcore_initcall(ltq_dma_init);
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c
new file mode 100644
index 00000000..66eb52fa
--- /dev/null
+++ b/arch/mips/lantiq/xway/ebu.c
@@ -0,0 +1,53 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * EBU - the external bus unit attaches PCI, NOR and NAND
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/ioport.h>
+
+#include <lantiq_soc.h>
+
+/* all access to the ebu must be locked */
+DEFINE_SPINLOCK(ebu_lock);
+EXPORT_SYMBOL_GPL(ebu_lock);
+
+static struct resource ltq_ebu_resource = {
+ .name = "ebu",
+ .start = LTQ_EBU_BASE_ADDR,
+ .end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+/* remapped base addr of the clock unit and external bus unit */
+void __iomem *ltq_ebu_membase;
+
+static int __init lantiq_ebu_init(void)
+{
+ /* insert and request the memory region */
+ if (insert_resource(&iomem_resource, &ltq_ebu_resource) < 0)
+ panic("Failed to insert ebu memory\n");
+
+ if (request_mem_region(ltq_ebu_resource.start,
+ resource_size(&ltq_ebu_resource), "ebu") < 0)
+ panic("Failed to request ebu memory\n");
+
+ /* remap ebu register range */
+ ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start,
+ resource_size(&ltq_ebu_resource));
+ if (!ltq_ebu_membase)
+ panic("Failed to remap ebu memory\n");
+
+ /* make sure to unprotect the memory region where flash is located */
+ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
+ return 0;
+}
+
+postcore_initcall(lantiq_ebu_init);
diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
new file mode 100644
index 00000000..a321451a
--- /dev/null
+++ b/arch/mips/lantiq/xway/gpio.c
@@ -0,0 +1,195 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+
+#include <lantiq_soc.h>
+
+#define LTQ_GPIO_OUT 0x00
+#define LTQ_GPIO_IN 0x04
+#define LTQ_GPIO_DIR 0x08
+#define LTQ_GPIO_ALTSEL0 0x0C
+#define LTQ_GPIO_ALTSEL1 0x10
+#define LTQ_GPIO_OD 0x14
+
+#define PINS_PER_PORT 16
+#define MAX_PORTS 3
+
+#define ltq_gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
+#define ltq_gpio_setbit(m, r, p) ltq_w32_mask(0, (1 << p), m + r)
+#define ltq_gpio_clearbit(m, r, p) ltq_w32_mask((1 << p), 0, m + r)
+
+struct ltq_gpio {
+ void __iomem *membase;
+ struct gpio_chip chip;
+};
+
+static struct ltq_gpio ltq_gpio_port[MAX_PORTS];
+
+int gpio_to_irq(unsigned int gpio)
+{
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned int gpio)
+{
+ return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
+
+int ltq_gpio_request(unsigned int pin, unsigned int alt0,
+ unsigned int alt1, unsigned int dir, const char *name)
+{
+ int id = 0;
+
+ if (pin >= (MAX_PORTS * PINS_PER_PORT))
+ return -EINVAL;
+ if (gpio_request(pin, name)) {
+ pr_err("failed to setup lantiq gpio: %s\n", name);
+ return -EBUSY;
+ }
+ if (dir)
+ gpio_direction_output(pin, 1);
+ else
+ gpio_direction_input(pin);
+ while (pin >= PINS_PER_PORT) {
+ pin -= PINS_PER_PORT;
+ id++;
+ }
+ if (alt0)
+ ltq_gpio_setbit(ltq_gpio_port[id].membase,
+ LTQ_GPIO_ALTSEL0, pin);
+ else
+ ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+ LTQ_GPIO_ALTSEL0, pin);
+ if (alt1)
+ ltq_gpio_setbit(ltq_gpio_port[id].membase,
+ LTQ_GPIO_ALTSEL1, pin);
+ else
+ ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+ LTQ_GPIO_ALTSEL1, pin);
+ return 0;
+}
+EXPORT_SYMBOL(ltq_gpio_request);
+
+static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+ struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+ if (value)
+ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
+ else
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
+}
+
+static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+ return ltq_gpio_getbit(ltq_gpio->membase, LTQ_GPIO_IN, offset);
+}
+
+static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+ struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+
+ return 0;
+}
+
+static int ltq_gpio_direction_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+ ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+ ltq_gpio_set(chip, offset, value);
+
+ return 0;
+}
+
+static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
+{
+ struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
+ ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
+ return 0;
+}
+
+static int ltq_gpio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+
+ if (pdev->id >= MAX_PORTS) {
+ dev_err(&pdev->dev, "invalid gpio port %d\n",
+ pdev->id);
+ return -EINVAL;
+ }
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
+ pdev->id);
+ return -ENOENT;
+ }
+ res = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), dev_name(&pdev->dev));
+ if (!res) {
+ dev_err(&pdev->dev,
+ "failed to request memory for gpio port %d\n",
+ pdev->id);
+ return -EBUSY;
+ }
+ ltq_gpio_port[pdev->id].membase = devm_ioremap_nocache(&pdev->dev,
+ res->start, resource_size(res));
+ if (!ltq_gpio_port[pdev->id].membase) {
+ dev_err(&pdev->dev, "failed to remap memory for gpio port %d\n",
+ pdev->id);
+ return -ENOMEM;
+ }
+ ltq_gpio_port[pdev->id].chip.label = "ltq_gpio";
+ ltq_gpio_port[pdev->id].chip.direction_input = ltq_gpio_direction_input;
+ ltq_gpio_port[pdev->id].chip.direction_output =
+ ltq_gpio_direction_output;
+ ltq_gpio_port[pdev->id].chip.get = ltq_gpio_get;
+ ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
+ ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
+ ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
+ ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
+ platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
+ return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
+}
+
+static struct platform_driver
+ltq_gpio_driver = {
+ .probe = ltq_gpio_probe,
+ .driver = {
+ .name = "ltq_gpio",
+ .owner = THIS_MODULE,
+ },
+};
+
+int __init ltq_gpio_init(void)
+{
+ int ret = platform_driver_register(&ltq_gpio_driver);
+
+ if (ret)
+ pr_info("ltq_gpio : Error registering platfom driver!");
+ return ret;
+}
+
+postcore_initcall(ltq_gpio_init);
diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c
new file mode 100644
index 00000000..a479355a
--- /dev/null
+++ b/arch/mips/lantiq/xway/gpio_ebu.c
@@ -0,0 +1,126 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <lantiq_soc.h>
+
+/*
+ * By attaching hardware latches to the EBU it is possible to create output
+ * only gpios. This driver configures a special memory address, which when
+ * written to outputs 16 bit to the latches.
+ */
+
+#define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */
+#define LTQ_EBU_WP 0x80000000 /* write protect bit */
+
+/* we keep a shadow value of the last value written to the ebu */
+static int ltq_ebu_gpio_shadow = 0x0;
+static void __iomem *ltq_ebu_gpio_membase;
+
+static void ltq_ebu_apply(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ebu_lock, flags);
+ ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1);
+ *((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow;
+ ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
+ spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ if (value)
+ ltq_ebu_gpio_shadow |= (1 << offset);
+ else
+ ltq_ebu_gpio_shadow &= ~(1 << offset);
+ ltq_ebu_apply();
+}
+
+static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ ltq_ebu_set(chip, offset, value);
+
+ return 0;
+}
+
+static struct gpio_chip ltq_ebu_chip = {
+ .label = "ltq_ebu",
+ .direction_output = ltq_ebu_direction_output,
+ .set = ltq_ebu_set,
+ .base = 72,
+ .ngpio = 16,
+ .can_sleep = 1,
+ .owner = THIS_MODULE,
+};
+
+static int ltq_ebu_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get memory resource\n");
+ return -ENOENT;
+ }
+
+ res = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), dev_name(&pdev->dev));
+ if (!res) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ return -EBUSY;
+ }
+
+ ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start,
+ resource_size(res));
+ if (!ltq_ebu_gpio_membase) {
+ dev_err(&pdev->dev, "Failed to ioremap mem region\n");
+ return -ENOMEM;
+ }
+
+ /* grab the default shadow value passed form the platform code */
+ ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data;
+
+ /* tell the ebu controller which memory address we will be using */
+ ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1);
+
+ /* write protect the region */
+ ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
+
+ ret = gpiochip_add(&ltq_ebu_chip);
+ if (!ret)
+ ltq_ebu_apply();
+ return ret;
+}
+
+static struct platform_driver ltq_ebu_driver = {
+ .probe = ltq_ebu_probe,
+ .driver = {
+ .name = "ltq_ebu",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ltq_ebu_init(void)
+{
+ int ret = platform_driver_register(&ltq_ebu_driver);
+
+ if (ret)
+ pr_info("ltq_ebu : Error registering platfom driver!");
+ return ret;
+}
+
+postcore_initcall(ltq_ebu_init);
diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c
new file mode 100644
index 00000000..67d59d69
--- /dev/null
+++ b/arch/mips/lantiq/xway/gpio_stp.c
@@ -0,0 +1,157 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <lantiq_soc.h>
+
+#define LTQ_STP_CON0 0x00
+#define LTQ_STP_CON1 0x04
+#define LTQ_STP_CPU0 0x08
+#define LTQ_STP_CPU1 0x0C
+#define LTQ_STP_AR 0x10
+
+#define LTQ_STP_CON_SWU (1 << 31)
+#define LTQ_STP_2HZ 0
+#define LTQ_STP_4HZ (1 << 23)
+#define LTQ_STP_8HZ (2 << 23)
+#define LTQ_STP_10HZ (3 << 23)
+#define LTQ_STP_SPEED_MASK (0xf << 23)
+#define LTQ_STP_UPD_FPI (1 << 31)
+#define LTQ_STP_UPD_MASK (3 << 30)
+#define LTQ_STP_ADSL_SRC (3 << 24)
+
+#define LTQ_STP_GROUP0 (1 << 0)
+
+#define LTQ_STP_RISING 0
+#define LTQ_STP_FALLING (1 << 26)
+#define LTQ_STP_EDGE_MASK (1 << 26)
+
+#define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg)
+#define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg)
+#define ltq_stp_w32_mask(clear, set, reg) \
+ ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \
+ ltq_stp_membase + (reg))
+
+static int ltq_stp_shadow = 0xffff;
+static void __iomem *ltq_stp_membase;
+
+static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ if (value)
+ ltq_stp_shadow |= (1 << offset);
+ else
+ ltq_stp_shadow &= ~(1 << offset);
+ ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0);
+}
+
+static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ ltq_stp_set(chip, offset, value);
+
+ return 0;
+}
+
+static struct gpio_chip ltq_stp_chip = {
+ .label = "ltq_stp",
+ .direction_output = ltq_stp_direction_output,
+ .set = ltq_stp_set,
+ .base = 48,
+ .ngpio = 24,
+ .can_sleep = 1,
+ .owner = THIS_MODULE,
+};
+
+static int ltq_stp_hw_init(void)
+{
+ /* the 3 pins used to control the external stp */
+ ltq_gpio_request(4, 1, 0, 1, "stp-st");
+ ltq_gpio_request(5, 1, 0, 1, "stp-d");
+ ltq_gpio_request(6, 1, 0, 1, "stp-sh");
+
+ /* sane defaults */
+ ltq_stp_w32(0, LTQ_STP_AR);
+ ltq_stp_w32(0, LTQ_STP_CPU0);
+ ltq_stp_w32(0, LTQ_STP_CPU1);
+ ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0);
+ ltq_stp_w32(0, LTQ_STP_CON1);
+
+ /* rising or falling edge */
+ ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0);
+
+ /* per default stp 15-0 are set */
+ ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1);
+
+ /* stp are update periodically by the FPI bus */
+ ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1);
+
+ /* set stp update speed */
+ ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1);
+
+ /* tell the hardware that pin (led) 0 and 1 are controlled
+ * by the dsl arc
+ */
+ ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0);
+
+ ltq_pmu_enable(PMU_LED);
+ return 0;
+}
+
+static int __devinit ltq_stp_probe(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ int ret = 0;
+
+ if (!res)
+ return -ENOENT;
+ res = devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), dev_name(&pdev->dev));
+ if (!res) {
+ dev_err(&pdev->dev, "failed to request STP memory\n");
+ return -EBUSY;
+ }
+ ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start,
+ resource_size(res));
+ if (!ltq_stp_membase) {
+ dev_err(&pdev->dev, "failed to remap STP memory\n");
+ return -ENOMEM;
+ }
+ ret = gpiochip_add(&ltq_stp_chip);
+ if (!ret)
+ ret = ltq_stp_hw_init();
+
+ return ret;
+}
+
+static struct platform_driver ltq_stp_driver = {
+ .probe = ltq_stp_probe,
+ .driver = {
+ .name = "ltq_stp",
+ .owner = THIS_MODULE,
+ },
+};
+
+int __init ltq_stp_init(void)
+{
+ int ret = platform_driver_register(&ltq_stp_driver);
+
+ if (ret)
+ pr_info("ltq_stp: error registering platfom driver");
+ return ret;
+}
+
+postcore_initcall(ltq_stp_init);
diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c
new file mode 100644
index 00000000..d5aaf637
--- /dev/null
+++ b/arch/mips/lantiq/xway/mach-easy50601.c
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+
+#include <lantiq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+static struct mtd_partition easy50601_partitions[] = {
+ {
+ .name = "uboot",
+ .offset = 0x0,
+ .size = 0x10000,
+ },
+ {
+ .name = "uboot_env",
+ .offset = 0x10000,
+ .size = 0x10000,
+ },
+ {
+ .name = "linux",
+ .offset = 0x20000,
+ .size = 0xE0000,
+ },
+ {
+ .name = "rootfs",
+ .offset = 0x100000,
+ .size = 0x300000,
+ },
+};
+
+static struct physmap_flash_data easy50601_flash_data = {
+ .nr_parts = ARRAY_SIZE(easy50601_partitions),
+ .parts = easy50601_partitions,
+};
+
+static void __init easy50601_init(void)
+{
+ ltq_register_nor(&easy50601_flash_data);
+}
+
+MIPS_MACHINE(LTQ_MACH_EASY50601,
+ "EASY50601",
+ "EASY50601 Eval Board",
+ easy50601_init);
diff --git a/arch/mips/lantiq/xway/mach-easy50712.c b/arch/mips/lantiq/xway/mach-easy50712.c
new file mode 100644
index 00000000..ea5027b3
--- /dev/null
+++ b/arch/mips/lantiq/xway/mach-easy50712.c
@@ -0,0 +1,74 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/phy.h>
+
+#include <lantiq_soc.h>
+#include <irq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+static struct mtd_partition easy50712_partitions[] = {
+ {
+ .name = "uboot",
+ .offset = 0x0,
+ .size = 0x10000,
+ },
+ {
+ .name = "uboot_env",
+ .offset = 0x10000,
+ .size = 0x10000,
+ },
+ {
+ .name = "linux",
+ .offset = 0x20000,
+ .size = 0xe0000,
+ },
+ {
+ .name = "rootfs",
+ .offset = 0x100000,
+ .size = 0x300000,
+ },
+};
+
+static struct physmap_flash_data easy50712_flash_data = {
+ .nr_parts = ARRAY_SIZE(easy50712_partitions),
+ .parts = easy50712_partitions,
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+ .clock = PCI_CLOCK_INT,
+ .gpio = PCI_GNT1 | PCI_REQ1,
+ .irq = {
+ [14] = INT_NUM_IM0_IRL0 + 22,
+ },
+};
+
+static struct ltq_eth_data ltq_eth_data = {
+ .mii_mode = PHY_INTERFACE_MODE_MII,
+};
+
+static void __init easy50712_init(void)
+{
+ ltq_register_gpio_stp();
+ ltq_register_nor(&easy50712_flash_data);
+ ltq_register_pci(&ltq_pci_data);
+ ltq_register_etop(&ltq_eth_data);
+}
+
+MIPS_MACHINE(LTQ_MACH_EASY50712,
+ "EASY50712",
+ "EASY50712 Eval Board",
+ easy50712_init);
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c
new file mode 100644
index 00000000..9d69f01e
--- /dev/null
+++ b/arch/mips/lantiq/xway/pmu.c
@@ -0,0 +1,70 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/ioport.h>
+
+#include <lantiq_soc.h>
+
+/* PMU - the power management unit allows us to turn part of the core
+ * on and off
+ */
+
+/* the enable / disable registers */
+#define LTQ_PMU_PWDCR 0x1C
+#define LTQ_PMU_PWDSR 0x20
+
+#define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y))
+#define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x))
+
+static struct resource ltq_pmu_resource = {
+ .name = "pmu",
+ .start = LTQ_PMU_BASE_ADDR,
+ .end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static void __iomem *ltq_pmu_membase;
+
+void ltq_pmu_enable(unsigned int module)
+{
+ int err = 1000000;
+
+ ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
+ do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
+
+ if (!err)
+ panic("activating PMU module failed!\n");
+}
+EXPORT_SYMBOL(ltq_pmu_enable);
+
+void ltq_pmu_disable(unsigned int module)
+{
+ ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
+}
+EXPORT_SYMBOL(ltq_pmu_disable);
+
+int __init ltq_pmu_init(void)
+{
+ if (insert_resource(&iomem_resource, &ltq_pmu_resource) < 0)
+ panic("Failed to insert pmu memory\n");
+
+ if (request_mem_region(ltq_pmu_resource.start,
+ resource_size(&ltq_pmu_resource), "pmu") < 0)
+ panic("Failed to request pmu memory\n");
+
+ ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
+ resource_size(&ltq_pmu_resource));
+ if (!ltq_pmu_membase)
+ panic("Failed to remap pmu memory\n");
+ return 0;
+}
+
+core_initcall(ltq_pmu_init);
diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c
new file mode 100644
index 00000000..abe49f4d
--- /dev/null
+++ b/arch/mips/lantiq/xway/prom-ase.c
@@ -0,0 +1,39 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+
+#define SOC_AMAZON_SE "Amazon_SE"
+
+#define PART_SHIFT 12
+#define PART_MASK 0x0FFFFFFF
+#define REV_SHIFT 28
+#define REV_MASK 0xF0000000
+
+void __init ltq_soc_detect(struct ltq_soc_info *i)
+{
+ i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+ i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+ switch (i->partnum) {
+ case SOC_ID_AMAZON_SE:
+ i->name = SOC_AMAZON_SE;
+ i->type = SOC_TYPE_AMAZON_SE;
+ break;
+
+ default:
+ unreachable();
+ break;
+ }
+}
diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c
new file mode 100644
index 00000000..1686692a
--- /dev/null
+++ b/arch/mips/lantiq/xway/prom-xway.c
@@ -0,0 +1,54 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+
+#define SOC_DANUBE "Danube"
+#define SOC_TWINPASS "Twinpass"
+#define SOC_AR9 "AR9"
+
+#define PART_SHIFT 12
+#define PART_MASK 0x0FFFFFFF
+#define REV_SHIFT 28
+#define REV_MASK 0xF0000000
+
+void __init ltq_soc_detect(struct ltq_soc_info *i)
+{
+ i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+ i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+ switch (i->partnum) {
+ case SOC_ID_DANUBE1:
+ case SOC_ID_DANUBE2:
+ i->name = SOC_DANUBE;
+ i->type = SOC_TYPE_DANUBE;
+ break;
+
+ case SOC_ID_TWINPASS:
+ i->name = SOC_TWINPASS;
+ i->type = SOC_TYPE_DANUBE;
+ break;
+
+ case SOC_ID_ARX188:
+ case SOC_ID_ARX168:
+ case SOC_ID_ARX182:
+ i->name = SOC_AR9;
+ i->type = SOC_TYPE_AR9;
+ break;
+
+ default:
+ unreachable();
+ break;
+ }
+}
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
new file mode 100644
index 00000000..a1be36d0
--- /dev/null
+++ b/arch/mips/lantiq/xway/reset.c
@@ -0,0 +1,91 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+#include <linux/module.h>
+#include <asm/reboot.h>
+
+#include <lantiq_soc.h>
+
+#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
+#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
+
+/* register definitions */
+#define LTQ_RCU_RST 0x0010
+#define LTQ_RCU_RST_ALL 0x40000000
+
+#define LTQ_RCU_RST_STAT 0x0014
+#define LTQ_RCU_STAT_SHIFT 26
+
+static struct resource ltq_rcu_resource = {
+ .name = "rcu",
+ .start = LTQ_RCU_BASE_ADDR,
+ .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+/* remapped base addr of the reset control unit */
+static void __iomem *ltq_rcu_membase;
+
+/* This function is used by the watchdog driver */
+int ltq_reset_cause(void)
+{
+ u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT);
+ return val >> LTQ_RCU_STAT_SHIFT;
+}
+EXPORT_SYMBOL_GPL(ltq_reset_cause);
+
+static void ltq_machine_restart(char *command)
+{
+ pr_notice("System restart\n");
+ local_irq_disable();
+ ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST);
+ unreachable();
+}
+
+static void ltq_machine_halt(void)
+{
+ pr_notice("System halted.\n");
+ local_irq_disable();
+ unreachable();
+}
+
+static void ltq_machine_power_off(void)
+{
+ pr_notice("Please turn off the power now.\n");
+ local_irq_disable();
+ unreachable();
+}
+
+static int __init mips_reboot_setup(void)
+{
+ /* insert and request the memory region */
+ if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0)
+ panic("Failed to insert rcu memory\n");
+
+ if (request_mem_region(ltq_rcu_resource.start,
+ resource_size(&ltq_rcu_resource), "rcu") < 0)
+ panic("Failed to request rcu memory\n");
+
+ /* remap rcu register range */
+ ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
+ resource_size(&ltq_rcu_resource));
+ if (!ltq_rcu_membase)
+ panic("Failed to remap rcu memory\n");
+
+ _machine_restart = ltq_machine_restart;
+ _machine_halt = ltq_machine_halt;
+ pm_power_off = ltq_machine_power_off;
+
+ return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c
new file mode 100644
index 00000000..f6f32679
--- /dev/null
+++ b/arch/mips/lantiq/xway/setup-ase.c
@@ -0,0 +1,19 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+#include "devices.h"
+
+void __init ltq_soc_setup(void)
+{
+ ltq_register_ase_asc();
+ ltq_register_gpio();
+ ltq_register_wdt();
+}
diff --git a/arch/mips/lantiq/xway/setup-xway.c b/arch/mips/lantiq/xway/setup-xway.c
new file mode 100644
index 00000000..c292f643
--- /dev/null
+++ b/arch/mips/lantiq/xway/setup-xway.c
@@ -0,0 +1,20 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+#include "devices.h"
+
+void __init ltq_soc_setup(void)
+{
+ ltq_register_asc(0);
+ ltq_register_asc(1);
+ ltq_register_gpio();
+ ltq_register_wdt();
+}
diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig
new file mode 100644
index 00000000..1d2ee8a9
--- /dev/null
+++ b/arch/mips/lasat/Kconfig
@@ -0,0 +1,15 @@
+config PICVUE
+ tristate "PICVUE LCD display driver"
+ depends on LASAT
+
+config PICVUE_PROC
+ tristate "PICVUE LCD display driver /proc interface"
+ depends on PICVUE
+
+config DS1603
+ bool "DS1603 RTC driver"
+ depends on LASAT
+
+config LASAT_SYSCTL
+ bool "LASAT sysctl interface"
+ depends on LASAT
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile
new file mode 100644
index 00000000..9cc4e4db
--- /dev/null
+++ b/arch/mips/lasat/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the LASAT specific kernel interface routines under Linux.
+#
+
+obj-y += reset.o setup.o prom.o lasat_board.o \
+ at93c.o interrupt.o serial.o
+
+obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o
+obj-$(CONFIG_DS1603) += ds1603.o
+obj-$(CONFIG_PICVUE) += picvue.o
+obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o
+
+clean:
+ make -C image clean
diff --git a/arch/mips/lasat/Platform b/arch/mips/lasat/Platform
new file mode 100644
index 00000000..76025282
--- /dev/null
+++ b/arch/mips/lasat/Platform
@@ -0,0 +1,7 @@
+#
+# LASAT platforms
+#
+platform-$(CONFIG_LASAT) += lasat/
+cflags-$(CONFIG_LASAT) += \
+ -I$(srctree)/arch/mips/include/asm/mach-lasat
+load-$(CONFIG_LASAT) += 0xffffffff80000000
diff --git a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c
new file mode 100644
index 00000000..793e2347
--- /dev/null
+++ b/arch/mips/lasat/at93c.c
@@ -0,0 +1,149 @@
+/*
+ * Atmel AT93C46 serial eeprom driver
+ *
+ * Brian Murphy <brian.murphy@eicon.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <asm/lasat/lasat.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "at93c.h"
+
+#define AT93C_ADDR_SHIFT 7
+#define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1)
+#define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT)
+#define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT)
+#define AT93C_WENCMD 0x260
+#define AT93C_WDSCMD 0x200
+
+struct at93c_defs *at93c;
+
+static void at93c_reg_write(u32 val)
+{
+ *at93c->reg = val;
+}
+
+static u32 at93c_reg_read(void)
+{
+ u32 tmp = *at93c->reg;
+ return tmp;
+}
+
+static u32 at93c_datareg_read(void)
+{
+ u32 tmp = *at93c->rdata_reg;
+ return tmp;
+}
+
+static void at93c_cycle_clk(u32 data)
+{
+ at93c_reg_write(data | at93c->clk);
+ lasat_ndelay(250);
+ at93c_reg_write(data & ~at93c->clk);
+ lasat_ndelay(250);
+}
+
+static void at93c_write_databit(u8 bit)
+{
+ u32 data = at93c_reg_read();
+ if (bit)
+ data |= 1 << at93c->wdata_shift;
+ else
+ data &= ~(1 << at93c->wdata_shift);
+
+ at93c_reg_write(data);
+ lasat_ndelay(100);
+ at93c_cycle_clk(data);
+}
+
+static unsigned int at93c_read_databit(void)
+{
+ u32 data;
+
+ at93c_cycle_clk(at93c_reg_read());
+ data = (at93c_datareg_read() >> at93c->rdata_shift) & 1;
+ return data;
+}
+
+static u8 at93c_read_byte(void)
+{
+ int i;
+ u8 data = 0;
+
+ for (i = 0; i <= 7; i++) {
+ data <<= 1;
+ data |= at93c_read_databit();
+ }
+ return data;
+}
+
+static void at93c_write_bits(u32 data, int size)
+{
+ int i;
+ int shift = size - 1;
+ u32 mask = (1 << shift);
+
+ for (i = 0; i < size; i++) {
+ at93c_write_databit((data & mask) >> shift);
+ data <<= 1;
+ }
+}
+
+static void at93c_init_op(void)
+{
+ at93c_reg_write((at93c_reg_read() | at93c->cs) &
+ ~at93c->clk & ~(1 << at93c->rdata_shift));
+ lasat_ndelay(50);
+}
+
+static void at93c_end_op(void)
+{
+ at93c_reg_write(at93c_reg_read() & ~at93c->cs);
+ lasat_ndelay(250);
+}
+
+static void at93c_wait(void)
+{
+ at93c_init_op();
+ while (!at93c_read_databit())
+ ;
+ at93c_end_op();
+};
+
+static void at93c_disable_wp(void)
+{
+ at93c_init_op();
+ at93c_write_bits(AT93C_WENCMD, 10);
+ at93c_end_op();
+}
+
+static void at93c_enable_wp(void)
+{
+ at93c_init_op();
+ at93c_write_bits(AT93C_WDSCMD, 10);
+ at93c_end_op();
+}
+
+u8 at93c_read(u8 addr)
+{
+ u8 byte;
+ at93c_init_op();
+ at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10);
+ byte = at93c_read_byte();
+ at93c_end_op();
+ return byte;
+}
+
+void at93c_write(u8 addr, u8 data)
+{
+ at93c_disable_wp();
+ at93c_init_op();
+ at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10);
+ at93c_write_bits(data, 8);
+ at93c_end_op();
+ at93c_wait();
+ at93c_enable_wp();
+}
diff --git a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h
new file mode 100644
index 00000000..cfe2f99b
--- /dev/null
+++ b/arch/mips/lasat/at93c.h
@@ -0,0 +1,18 @@
+/*
+ * Atmel AT93C46 serial eeprom driver
+ *
+ * Brian Murphy <brian.murphy@eicon.com>
+ *
+ */
+
+extern struct at93c_defs {
+ volatile u32 *reg;
+ volatile u32 *rdata_reg;
+ int rdata_shift;
+ int wdata_shift;
+ u32 cs;
+ u32 clk;
+} *at93c;
+
+u8 at93c_read(u8 addr);
+void at93c_write(u8 addr, u8 data);
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c
new file mode 100644
index 00000000..c6fd96ff
--- /dev/null
+++ b/arch/mips/lasat/ds1603.c
@@ -0,0 +1,184 @@
+/*
+ * Dallas Semiconductors 1603 RTC driver
+ *
+ * Brian Murphy <brian@murphy.dk>
+ *
+ */
+#include <linux/kernel.h>
+#include <asm/lasat/lasat.h>
+#include <linux/delay.h>
+#include <asm/lasat/ds1603.h>
+#include <asm/time.h>
+
+#include "ds1603.h"
+
+#define READ_TIME_CMD 0x81
+#define SET_TIME_CMD 0x80
+#define TRIMMER_SET_CMD 0xC0
+#define TRIMMER_VALUE_MASK 0x38
+#define TRIMMER_SHIFT 3
+
+struct ds_defs *ds1603;
+
+/* HW specific register functions */
+static void rtc_reg_write(unsigned long val)
+{
+ *ds1603->reg = val;
+}
+
+static unsigned long rtc_reg_read(void)
+{
+ unsigned long tmp = *ds1603->reg;
+ return tmp;
+}
+
+static unsigned long rtc_datareg_read(void)
+{
+ unsigned long tmp = *ds1603->data_reg;
+ return tmp;
+}
+
+static void rtc_nrst_high(void)
+{
+ rtc_reg_write(rtc_reg_read() | ds1603->rst);
+}
+
+static void rtc_nrst_low(void)
+{
+ rtc_reg_write(rtc_reg_read() & ~ds1603->rst);
+}
+
+static void rtc_cycle_clock(unsigned long data)
+{
+ data |= ds1603->clk;
+ rtc_reg_write(data);
+ lasat_ndelay(250);
+ if (ds1603->data_reversed)
+ data &= ~ds1603->data;
+ else
+ data |= ds1603->data;
+ data &= ~ds1603->clk;
+ rtc_reg_write(data);
+ lasat_ndelay(250 + ds1603->huge_delay);
+}
+
+static void rtc_write_databit(unsigned int bit)
+{
+ unsigned long data = rtc_reg_read();
+ if (ds1603->data_reversed)
+ bit = !bit;
+ if (bit)
+ data |= ds1603->data;
+ else
+ data &= ~ds1603->data;
+
+ rtc_reg_write(data);
+ lasat_ndelay(50 + ds1603->huge_delay);
+ rtc_cycle_clock(data);
+}
+
+static unsigned int rtc_read_databit(void)
+{
+ unsigned int data;
+
+ data = (rtc_datareg_read() & (1 << ds1603->data_read_shift))
+ >> ds1603->data_read_shift;
+ rtc_cycle_clock(rtc_reg_read());
+ return data;
+}
+
+static void rtc_write_byte(unsigned int byte)
+{
+ int i;
+
+ for (i = 0; i <= 7; i++) {
+ rtc_write_databit(byte & 1L);
+ byte >>= 1;
+ }
+}
+
+static void rtc_write_word(unsigned long word)
+{
+ int i;
+
+ for (i = 0; i <= 31; i++) {
+ rtc_write_databit(word & 1L);
+ word >>= 1;
+ }
+}
+
+static unsigned long rtc_read_word(void)
+{
+ int i;
+ unsigned long word = 0;
+ unsigned long shift = 0;
+
+ for (i = 0; i <= 31; i++) {
+ word |= rtc_read_databit() << shift;
+ shift++;
+ }
+ return word;
+}
+
+static void rtc_init_op(void)
+{
+ rtc_nrst_high();
+
+ rtc_reg_write(rtc_reg_read() & ~ds1603->clk);
+
+ lasat_ndelay(50);
+}
+
+static void rtc_end_op(void)
+{
+ rtc_nrst_low();
+ lasat_ndelay(1000);
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+ unsigned long word;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ rtc_init_op();
+ rtc_write_byte(READ_TIME_CMD);
+ word = rtc_read_word();
+ rtc_end_op();
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ ts->tv_sec = word;
+ ts->tv_nsec = 0;
+}
+
+int rtc_mips_set_mmss(unsigned long time)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ rtc_init_op();
+ rtc_write_byte(SET_TIME_CMD);
+ rtc_write_word(time);
+ rtc_end_op();
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ return 0;
+}
+
+void ds1603_set_trimmer(unsigned int trimval)
+{
+ rtc_init_op();
+ rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK)
+ | (TRIMMER_SET_CMD));
+ rtc_end_op();
+}
+
+void ds1603_disable(void)
+{
+ ds1603_set_trimmer(TRIMMER_DISABLE_RTC);
+}
+
+void ds1603_enable(void)
+{
+ ds1603_set_trimmer(TRIMMER_DEFAULT);
+}
diff --git a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h
new file mode 100644
index 00000000..2da37040
--- /dev/null
+++ b/arch/mips/lasat/ds1603.h
@@ -0,0 +1,31 @@
+/*
+ * Dallas Semiconductors 1603 RTC driver
+ *
+ * Brian Murphy <brian@murphy.dk>
+ *
+ */
+#ifndef __DS1603_H
+#define __DS1603_H
+
+struct ds_defs {
+ volatile u32 *reg;
+ volatile u32 *data_reg;
+ u32 rst;
+ u32 clk;
+ u32 data;
+ u32 data_read_shift;
+ char data_reversed;
+ u32 huge_delay;
+};
+
+extern struct ds_defs *ds1603;
+
+void ds1603_set_trimmer(unsigned int);
+void ds1603_enable(void);
+void ds1603_disable(void);
+void ds1603_init(struct ds_defs *);
+
+#define TRIMMER_DEFAULT 3
+#define TRIMMER_DISABLE_RTC 0
+
+#endif
diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile
new file mode 100644
index 00000000..460626b6
--- /dev/null
+++ b/arch/mips/lasat/image/Makefile
@@ -0,0 +1,54 @@
+#
+# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER
+#
+# i-data Networks
+#
+# Author: Thomas Horsten <thh@i-data.com>
+#
+
+ifndef Version
+ Version = "$(USER)-test"
+endif
+
+MKLASATIMG = mklasatimg
+MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200
+KERNEL_IMAGE = vmlinux
+KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ )
+KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ )
+
+LDSCRIPT= -L$(srctree)/$(src) -Tromscript.normal
+
+HEAD_DEFINES := -D_kernel_start=0x$(KERNEL_START) \
+ -D_kernel_entry=0x$(KERNEL_ENTRY) \
+ -D VERSION="\"$(Version)\"" \
+ -D TIMESTAMP=$(shell date +%s)
+
+$(obj)/head.o: $(obj)/head.S $(KERNEL_IMAGE)
+ $(CC) -fno-pic $(HEAD_DEFINES) $(LINUXINCLUDE) -c -o $@ $<
+
+OBJECTS = head.o kImage.o
+
+rom.sw: $(obj)/rom.sw
+rom.bin: $(obj)/rom.bin
+
+$(obj)/rom.sw: $(obj)/rom.bin
+ $(MKLASATIMG) -o $@ -k $^ -m $(MKLASATIMG_ARCH)
+
+$(obj)/rom.bin: $(obj)/rom
+ $(OBJCOPY) -O binary -S $^ $@
+
+# Rule to make the bootloader
+$(obj)/rom: $(addprefix $(obj)/,$(OBJECTS))
+ $(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^
+
+$(obj)/%.o: $(obj)/%.gz
+ $(LD) -r -o $@ -b binary $<
+
+$(obj)/%.gz: $(obj)/%.bin
+ gzip -cf -9 $< > $@
+
+$(obj)/kImage.bin: $(KERNEL_IMAGE)
+ $(OBJCOPY) -O binary -S $^ $@
+
+clean:
+ rm -f rom rom.bin rom.sw kImage.bin kImage.o
diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S
new file mode 100644
index 00000000..e0ecda92
--- /dev/null
+++ b/arch/mips/lasat/image/head.S
@@ -0,0 +1,31 @@
+#include <asm/lasat/head.h>
+
+ .text
+ .section .text..start, "ax"
+ .set noreorder
+ .set mips3
+
+ /* Magic words identifying a software image */
+ .word LASAT_K_MAGIC0_VAL
+ .word LASAT_K_MAGIC1_VAL
+
+ /* Image header version */
+ .word 0x00000002
+
+ /* image start and size */
+ .word _image_start
+ .word _image_size
+
+ /* start of kernel and entrypoint in uncompressed image */
+ .word _kernel_start
+ .word _kernel_entry
+
+ /* Here we have room for future flags */
+
+ .org 0x40
+reldate:
+ .word TIMESTAMP
+
+ .org 0x50
+release:
+ .string VERSION
diff --git a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal
new file mode 100644
index 00000000..0864c963
--- /dev/null
+++ b/arch/mips/lasat/image/romscript.normal
@@ -0,0 +1,23 @@
+OUTPUT_ARCH(mips)
+
+SECTIONS
+{
+ .text :
+ {
+ *(.text..start)
+ }
+
+ /* Data in ROM */
+
+ .data ALIGN(0x10) :
+ {
+ *(.data)
+ }
+ _image_start = ADDR(.data);
+ _image_size = SIZEOF(.data);
+
+ .other :
+ {
+ *(.*)
+ }
+}
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
new file mode 100644
index 00000000..de4c1655
--- /dev/null
+++ b/arch/mips/lasat/interrupt.c
@@ -0,0 +1,134 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines for generic manipulation of the interrupts found on the
+ * Lasat boards.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/lasat/lasat.h>
+#include <asm/lasat/lasatint.h>
+
+#include <irq.h>
+
+static volatile int *lasat_int_status;
+static volatile int *lasat_int_mask;
+static volatile int lasat_int_mask_shift;
+
+void disable_lasat_irq(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq - LASAT_IRQ_BASE;
+
+ *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift;
+}
+
+void enable_lasat_irq(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq - LASAT_IRQ_BASE;
+
+ *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift;
+}
+
+static struct irq_chip lasat_irq_type = {
+ .name = "Lasat",
+ .irq_mask = disable_lasat_irq,
+ .irq_unmask = enable_lasat_irq,
+};
+
+static inline int ls1bit32(unsigned int x)
+{
+ int b = 31, s;
+
+ s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
+ s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s;
+ s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s;
+ s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s;
+ s = 1; if (x << 1 == 0) s = 0; b -= s;
+
+ return b;
+}
+
+static unsigned long (*get_int_status)(void);
+
+static unsigned long get_int_status_100(void)
+{
+ return *lasat_int_status & *lasat_int_mask;
+}
+
+static unsigned long get_int_status_200(void)
+{
+ unsigned long int_status;
+
+ int_status = *lasat_int_status;
+ int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff;
+ return int_status;
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long int_status;
+ unsigned int cause = read_c0_cause();
+ int irq;
+
+ if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */
+ do_IRQ(7);
+ return;
+ }
+
+ int_status = get_int_status();
+
+ /* if int_status == 0, then the interrupt has already been cleared */
+ if (int_status) {
+ irq = LASAT_IRQ_BASE + ls1bit32(int_status);
+
+ do_IRQ(irq);
+ }
+}
+
+static struct irqaction cascade = {
+ .handler = no_action,
+ .name = "cascade",
+};
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ if (IS_LASAT_200()) {
+ lasat_int_status = (void *)LASAT_INT_STATUS_REG_200;
+ lasat_int_mask = (void *)LASAT_INT_MASK_REG_200;
+ lasat_int_mask_shift = LASATINT_MASK_SHIFT_200;
+ get_int_status = get_int_status_200;
+ *lasat_int_mask &= 0xffff;
+ } else {
+ lasat_int_status = (void *)LASAT_INT_STATUS_REG_100;
+ lasat_int_mask = (void *)LASAT_INT_MASK_REG_100;
+ lasat_int_mask_shift = LASATINT_MASK_SHIFT_100;
+ get_int_status = get_int_status_100;
+ *lasat_int_mask = 0;
+ }
+
+ mips_cpu_irq_init();
+
+ for (i = LASAT_IRQ_BASE; i <= LASAT_IRQ_END; i++)
+ irq_set_chip_and_handler(i, &lasat_irq_type, handle_level_irq);
+
+ setup_irq(LASAT_CASCADE_IRQ, &cascade);
+}
diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c
new file mode 100644
index 00000000..577bb463
--- /dev/null
+++ b/arch/mips/lasat/lasat_board.c
@@ -0,0 +1,280 @@
+/*
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines specific to the LASAT boards
+ */
+#include <linux/types.h>
+#include <linux/crc32.h>
+#include <asm/lasat/lasat.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/mutex.h>
+#include <asm/addrspace.h>
+#include "at93c.h"
+/* New model description table */
+#include "lasat_models.h"
+
+static DEFINE_MUTEX(lasat_eeprom_mutex);
+
+#define EEPROM_CRC(data, len) (~crc32(~0, data, len))
+
+struct lasat_info lasat_board_info;
+
+int EEPROMRead(unsigned int pos, unsigned char *data, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ *data++ = at93c_read(pos++);
+
+ return 0;
+}
+
+int EEPROMWrite(unsigned int pos, unsigned char *data, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ at93c_write(pos++, *data++);
+
+ return 0;
+}
+
+static void init_flash_sizes(void)
+{
+ unsigned long *lb = lasat_board_info.li_flashpart_base;
+ unsigned long *ls = lasat_board_info.li_flashpart_size;
+ int i;
+
+ ls[LASAT_MTD_BOOTLOADER] = 0x40000;
+ ls[LASAT_MTD_SERVICE] = 0xC0000;
+ ls[LASAT_MTD_NORMAL] = 0x100000;
+
+ if (!IS_LASAT_200()) {
+ lasat_board_info.li_flash_base = 0x1e000000;
+
+ lb[LASAT_MTD_BOOTLOADER] = 0x1e400000;
+
+ if (lasat_board_info.li_flash_size > 0x200000) {
+ ls[LASAT_MTD_CONFIG] = 0x100000;
+ ls[LASAT_MTD_FS] = 0x500000;
+ }
+ } else {
+ lasat_board_info.li_flash_base = 0x10000000;
+
+ if (lasat_board_info.li_flash_size < 0x1000000) {
+ lb[LASAT_MTD_BOOTLOADER] = 0x10000000;
+ ls[LASAT_MTD_CONFIG] = 0x100000;
+ if (lasat_board_info.li_flash_size >= 0x400000)
+ ls[LASAT_MTD_FS] =
+ lasat_board_info.li_flash_size - 0x300000;
+ }
+ }
+
+ for (i = 1; i < LASAT_MTD_LAST; i++)
+ lb[i] = lb[i-1] + ls[i-1];
+}
+
+int lasat_init_board_info(void)
+{
+ int c;
+ unsigned long crc;
+ unsigned long cfg0, cfg1;
+ const struct product_info *ppi;
+ int i_n_base_models = N_BASE_MODELS;
+ const char * const * i_txt_base_models = txt_base_models;
+ int i_n_prids = N_PRIDS;
+
+ memset(&lasat_board_info, 0, sizeof(lasat_board_info));
+
+ /* First read the EEPROM info */
+ EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
+ sizeof(struct lasat_eeprom_struct));
+
+ /* Check the CRC */
+ crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
+ sizeof(struct lasat_eeprom_struct) - 4);
+
+ if (crc != lasat_board_info.li_eeprom_info.crc32) {
+ printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does "
+ "not match calculated, attempting to soldier on...\n");
+ }
+
+ if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) {
+ printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version "
+ "%d, wanted version %d, attempting to soldier on...\n",
+ (unsigned int)lasat_board_info.li_eeprom_info.version,
+ LASAT_EEPROM_VERSION);
+ }
+
+ cfg0 = lasat_board_info.li_eeprom_info.cfg[0];
+ cfg1 = lasat_board_info.li_eeprom_info.cfg[1];
+
+ if (LASAT_W0_DSCTYPE(cfg0) != 1) {
+ printk(KERN_WARNING "WARNING...\nWARNING...\n"
+ "Invalid configuration read from EEPROM, attempting to "
+ "soldier on...");
+ }
+ /* We have a valid configuration */
+
+ switch (LASAT_W0_SDRAMBANKSZ(cfg0)) {
+ case 0:
+ lasat_board_info.li_memsize = 0x0800000;
+ break;
+ case 1:
+ lasat_board_info.li_memsize = 0x1000000;
+ break;
+ case 2:
+ lasat_board_info.li_memsize = 0x2000000;
+ break;
+ case 3:
+ lasat_board_info.li_memsize = 0x4000000;
+ break;
+ case 4:
+ lasat_board_info.li_memsize = 0x8000000;
+ break;
+ default:
+ lasat_board_info.li_memsize = 0;
+ }
+
+ switch (LASAT_W0_SDRAMBANKS(cfg0)) {
+ case 0:
+ break;
+ case 1:
+ lasat_board_info.li_memsize *= 2;
+ break;
+ default:
+ break;
+ }
+
+ switch (LASAT_W0_BUSSPEED(cfg0)) {
+ case 0x0:
+ lasat_board_info.li_bus_hz = 60000000;
+ break;
+ case 0x1:
+ lasat_board_info.li_bus_hz = 66000000;
+ break;
+ case 0x2:
+ lasat_board_info.li_bus_hz = 66666667;
+ break;
+ case 0x3:
+ lasat_board_info.li_bus_hz = 80000000;
+ break;
+ case 0x4:
+ lasat_board_info.li_bus_hz = 83333333;
+ break;
+ case 0x5:
+ lasat_board_info.li_bus_hz = 100000000;
+ break;
+ }
+
+ switch (LASAT_W0_CPUCLK(cfg0)) {
+ case 0x0:
+ lasat_board_info.li_cpu_hz =
+ lasat_board_info.li_bus_hz;
+ break;
+ case 0x1:
+ lasat_board_info.li_cpu_hz =
+ lasat_board_info.li_bus_hz +
+ (lasat_board_info.li_bus_hz >> 1);
+ break;
+ case 0x2:
+ lasat_board_info.li_cpu_hz =
+ lasat_board_info.li_bus_hz +
+ lasat_board_info.li_bus_hz;
+ break;
+ case 0x3:
+ lasat_board_info.li_cpu_hz =
+ lasat_board_info.li_bus_hz +
+ lasat_board_info.li_bus_hz +
+ (lasat_board_info.li_bus_hz >> 1);
+ break;
+ case 0x4:
+ lasat_board_info.li_cpu_hz =
+ lasat_board_info.li_bus_hz +
+ lasat_board_info.li_bus_hz +
+ lasat_board_info.li_bus_hz;
+ break;
+ }
+
+ /* Flash size */
+ switch (LASAT_W1_FLASHSIZE(cfg1)) {
+ case 0:
+ lasat_board_info.li_flash_size = 0x200000;
+ break;
+ case 1:
+ lasat_board_info.li_flash_size = 0x400000;
+ break;
+ case 2:
+ lasat_board_info.li_flash_size = 0x800000;
+ break;
+ case 3:
+ lasat_board_info.li_flash_size = 0x1000000;
+ break;
+ case 4:
+ lasat_board_info.li_flash_size = 0x2000000;
+ break;
+ }
+
+ init_flash_sizes();
+
+ lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0);
+ lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid;
+ if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0)
+ lasat_board_info.li_prid = lasat_board_info.li_bmid;
+
+ /* Base model stuff */
+ if (lasat_board_info.li_bmid > i_n_base_models)
+ lasat_board_info.li_bmid = i_n_base_models;
+ strcpy(lasat_board_info.li_bmstr,
+ i_txt_base_models[lasat_board_info.li_bmid]);
+
+ /* Product ID dependent values */
+ c = lasat_board_info.li_prid;
+ if (c >= i_n_prids) {
+ strcpy(lasat_board_info.li_namestr, "Unknown Model");
+ strcpy(lasat_board_info.li_typestr, "Unknown Type");
+ } else {
+ ppi = &vendor_info_table[0].vi_product_info[c];
+ strcpy(lasat_board_info.li_namestr, ppi->pi_name);
+ if (ppi->pi_type)
+ strcpy(lasat_board_info.li_typestr, ppi->pi_type);
+ else
+ sprintf(lasat_board_info.li_typestr, "%d", 10 * c);
+ }
+
+ return 0;
+}
+
+void lasat_write_eeprom_info(void)
+{
+ unsigned long crc;
+
+ mutex_lock(&lasat_eeprom_mutex);
+
+ /* Generate the CRC */
+ crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info),
+ sizeof(struct lasat_eeprom_struct) - 4);
+ lasat_board_info.li_eeprom_info.crc32 = crc;
+
+ /* Write the EEPROM info */
+ EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info,
+ sizeof(struct lasat_eeprom_struct));
+
+ mutex_unlock(&lasat_eeprom_mutex);
+}
diff --git a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h
new file mode 100644
index 00000000..e1cbd26a
--- /dev/null
+++ b/arch/mips/lasat/lasat_models.h
@@ -0,0 +1,67 @@
+/*
+ * Model description tables
+ */
+#include <linux/kernel.h>
+
+struct product_info {
+ const char *pi_name;
+ const char *pi_type;
+};
+
+struct vendor_info {
+ const char *vi_name;
+ const struct product_info *vi_product_info;
+};
+
+/*
+ * Base models
+ */
+static const char * const txt_base_models[] = {
+ "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000",
+ "SP 1000", "Unknown"
+};
+#define N_BASE_MODELS (ARRAY_SIZE(txt_base_models) - 1)
+
+/*
+ * Eicon Networks
+ */
+static const char txt_en_mq[] = "Masquerade";
+static const char txt_en_sp[] = "Safepipe";
+
+static const struct product_info product_info_eicon[] = {
+ { txt_en_mq, "II" }, /* 0 */
+ { txt_en_mq, "Pro" }, /* 1 */
+ { txt_en_sp, "25" }, /* 2 */
+ { txt_en_sp, "50" }, /* 3 */
+ { txt_en_sp, "100" }, /* 4 */
+ { txt_en_sp, "5000" }, /* 5 */
+ { txt_en_sp, "7000" }, /* 6 */
+ { txt_en_sp, "30" }, /* 7 */
+ { txt_en_sp, "5100" }, /* 8 */
+ { txt_en_sp, "7100" }, /* 9 */
+ { txt_en_sp, "1110" }, /* 10 */
+ { txt_en_sp, "3020" }, /* 11 */
+ { txt_en_sp, "3030" }, /* 12 */
+ { txt_en_sp, "5020" }, /* 13 */
+ { txt_en_sp, "5030" }, /* 14 */
+ { txt_en_sp, "1120" }, /* 15 */
+ { txt_en_sp, "1130" }, /* 16 */
+ { txt_en_sp, "6010" }, /* 17 */
+ { txt_en_sp, "6110" }, /* 18 */
+ { txt_en_sp, "6210" }, /* 19 */
+ { txt_en_sp, "1020" }, /* 20 */
+ { txt_en_sp, "1040" }, /* 21 */
+ { txt_en_sp, "1050" }, /* 22 */
+ { txt_en_sp, "1060" }, /* 23 */
+};
+
+#define N_PRIDS ARRAY_SIZE(product_info_eicon)
+
+/*
+ * The vendor table
+ */
+static struct vendor_info const vendor_info_table[] = {
+ { "Eicon Networks", product_info_eicon },
+};
+
+#define N_VENDORS ARRAY_SIZE(vendor_info_table)
diff --git a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c
new file mode 100644
index 00000000..d3d04c39
--- /dev/null
+++ b/arch/mips/lasat/picvue.c
@@ -0,0 +1,242 @@
+/*
+ * Picvue PVC160206 display driver
+ *
+ * Brian Murphy <brian@murphy.dk>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <asm/bootinfo.h>
+#include <asm/lasat/lasat.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+
+#include "picvue.h"
+
+#define PVC_BUSY 0x80
+#define PVC_NLINES 2
+#define PVC_DISPMEM 80
+#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES
+
+struct pvc_defs *picvue;
+
+static void pvc_reg_write(u32 val)
+{
+ *picvue->reg = val;
+}
+
+static u32 pvc_reg_read(void)
+{
+ u32 tmp = *picvue->reg;
+ return tmp;
+}
+
+static void pvc_write_byte(u32 data, u8 byte)
+{
+ data |= picvue->e;
+ pvc_reg_write(data);
+ data &= ~picvue->data_mask;
+ data |= byte << picvue->data_shift;
+ pvc_reg_write(data);
+ ndelay(220);
+ pvc_reg_write(data & ~picvue->e);
+ ndelay(220);
+}
+
+static u8 pvc_read_byte(u32 data)
+{
+ u8 byte;
+
+ data |= picvue->e;
+ pvc_reg_write(data);
+ ndelay(220);
+ byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift;
+ data &= ~picvue->e;
+ pvc_reg_write(data);
+ ndelay(220);
+ return byte;
+}
+
+static u8 pvc_read_data(void)
+{
+ u32 data = pvc_reg_read();
+ u8 byte;
+ data |= picvue->rw;
+ data &= ~picvue->rs;
+ pvc_reg_write(data);
+ ndelay(40);
+ byte = pvc_read_byte(data);
+ data |= picvue->rs;
+ pvc_reg_write(data);
+ return byte;
+}
+
+#define TIMEOUT 1000
+static int pvc_wait(void)
+{
+ int i = TIMEOUT;
+ int err = 0;
+
+ while ((pvc_read_data() & PVC_BUSY) && i)
+ i--;
+ if (i == 0)
+ err = -ETIME;
+
+ return err;
+}
+
+#define MODE_INST 0
+#define MODE_DATA 1
+static void pvc_write(u8 byte, int mode)
+{
+ u32 data = pvc_reg_read();
+ data &= ~picvue->rw;
+ if (mode == MODE_DATA)
+ data |= picvue->rs;
+ else
+ data &= ~picvue->rs;
+ pvc_reg_write(data);
+ ndelay(40);
+ pvc_write_byte(data, byte);
+ if (mode == MODE_DATA)
+ data &= ~picvue->rs;
+ else
+ data |= picvue->rs;
+ pvc_reg_write(data);
+ pvc_wait();
+}
+
+void pvc_write_string(const unsigned char *str, u8 addr, int line)
+{
+ int i = 0;
+
+ if (line > 0 && (PVC_NLINES > 1))
+ addr += 0x40 * line;
+ pvc_write(0x80 | addr, MODE_INST);
+
+ while (*str != 0 && i < PVC_LINELEN) {
+ pvc_write(*str++, MODE_DATA);
+ i++;
+ }
+}
+
+void pvc_write_string_centered(const unsigned char *str, int line)
+{
+ int len = strlen(str);
+ u8 addr;
+
+ if (len > PVC_VISIBLE_CHARS)
+ addr = 0;
+ else
+ addr = (PVC_VISIBLE_CHARS - strlen(str))/2;
+
+ pvc_write_string(str, addr, line);
+}
+
+void pvc_dump_string(const unsigned char *str)
+{
+ int len = strlen(str);
+
+ pvc_write_string(str, 0, 0);
+ if (len > PVC_VISIBLE_CHARS)
+ pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1);
+}
+
+#define BM_SIZE 8
+#define MAX_PROGRAMMABLE_CHARS 8
+int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE])
+{
+ int i;
+ int addr;
+
+ if (charnum > MAX_PROGRAMMABLE_CHARS)
+ return -ENOENT;
+
+ addr = charnum * 8;
+ pvc_write(0x40 | addr, MODE_INST);
+
+ for (i = 0; i < BM_SIZE; i++)
+ pvc_write(bitmap[i], MODE_DATA);
+ return 0;
+}
+
+#define FUNC_SET_CMD 0x20
+#define EIGHT_BYTE (1 << 4)
+#define FOUR_BYTE 0
+#define TWO_LINES (1 << 3)
+#define ONE_LINE 0
+#define LARGE_FONT (1 << 2)
+#define SMALL_FONT 0
+
+static void pvc_funcset(u8 cmd)
+{
+ pvc_write(FUNC_SET_CMD | (cmd & (EIGHT_BYTE|TWO_LINES|LARGE_FONT)),
+ MODE_INST);
+}
+
+#define ENTRYMODE_CMD 0x4
+#define AUTO_INC (1 << 1)
+#define AUTO_DEC 0
+#define CURSOR_FOLLOWS_DISP (1 << 0)
+
+static void pvc_entrymode(u8 cmd)
+{
+ pvc_write(ENTRYMODE_CMD | (cmd & (AUTO_INC|CURSOR_FOLLOWS_DISP)),
+ MODE_INST);
+}
+
+#define DISP_CNT_CMD 0x08
+#define DISP_OFF 0
+#define DISP_ON (1 << 2)
+#define CUR_ON (1 << 1)
+#define CUR_BLINK (1 << 0)
+void pvc_dispcnt(u8 cmd)
+{
+ pvc_write(DISP_CNT_CMD | (cmd & (DISP_ON|CUR_ON|CUR_BLINK)), MODE_INST);
+}
+
+#define MOVE_CMD 0x10
+#define DISPLAY (1 << 3)
+#define CURSOR 0
+#define RIGHT (1 << 2)
+#define LEFT 0
+void pvc_move(u8 cmd)
+{
+ pvc_write(MOVE_CMD | (cmd & (DISPLAY|RIGHT)), MODE_INST);
+}
+
+#define CLEAR_CMD 0x1
+void pvc_clear(void)
+{
+ pvc_write(CLEAR_CMD, MODE_INST);
+}
+
+#define HOME_CMD 0x2
+void pvc_home(void)
+{
+ pvc_write(HOME_CMD, MODE_INST);
+}
+
+int pvc_init(void)
+{
+ u8 cmd = EIGHT_BYTE;
+
+ if (PVC_NLINES == 2)
+ cmd |= (SMALL_FONT|TWO_LINES);
+ else
+ cmd |= (LARGE_FONT|ONE_LINE);
+ pvc_funcset(cmd);
+ pvc_dispcnt(DISP_ON);
+ pvc_entrymode(AUTO_INC);
+
+ pvc_clear();
+ pvc_write_string_centered("Display", 0);
+ pvc_write_string_centered("Initialized", 1);
+
+ return 0;
+}
+
+module_init(pvc_init);
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h
new file mode 100644
index 00000000..2f075773
--- /dev/null
+++ b/arch/mips/lasat/picvue.h
@@ -0,0 +1,44 @@
+/*
+ * Picvue PVC160206 display driver
+ *
+ * Brian Murphy <brian.murphy@eicon.com>
+ *
+ */
+struct pvc_defs {
+ volatile u32 *reg;
+ u32 data_shift;
+ u32 data_mask;
+ u32 e;
+ u32 rw;
+ u32 rs;
+};
+
+extern struct pvc_defs *picvue;
+
+#define PVC_NLINES 2
+#define PVC_DISPMEM 80
+#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES
+#define PVC_VISIBLE_CHARS 16
+
+void pvc_write_string(const unsigned char *str, u8 addr, int line);
+void pvc_write_string_centered(const unsigned char *str, int line);
+void pvc_dump_string(const unsigned char *str);
+
+#define BM_SIZE 8
+#define MAX_PROGRAMMABLE_CHARS 8
+int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]);
+
+void pvc_dispcnt(u8 cmd);
+#define DISP_OFF 0
+#define DISP_ON (1 << 2)
+#define CUR_ON (1 << 1)
+#define CUR_BLINK (1 << 0)
+
+void pvc_move(u8 cmd);
+#define DISPLAY (1 << 3)
+#define CURSOR 0
+#define RIGHT (1 << 2)
+#define LEFT 0
+
+void pvc_clear(void);
+void pvc_home(void);
diff --git a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c
new file mode 100644
index 00000000..8e388da1
--- /dev/null
+++ b/arch/mips/lasat/picvue_proc.c
@@ -0,0 +1,216 @@
+/*
+ * Picvue PVC160206 display driver
+ *
+ * Brian Murphy <brian.murphy@eicon.com>
+ *
+ */
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+
+#include <linux/timer.h>
+#include <linux/mutex.h>
+
+#include "picvue.h"
+
+static DEFINE_MUTEX(pvc_mutex);
+static char pvc_lines[PVC_NLINES][PVC_LINELEN+1];
+static int pvc_linedata[PVC_NLINES];
+static struct proc_dir_entry *pvc_display_dir;
+static char *pvc_linename[PVC_NLINES] = {"line1", "line2"};
+#define DISPLAY_DIR_NAME "display"
+static int scroll_dir, scroll_interval;
+
+static struct timer_list timer;
+
+static void pvc_display(unsigned long data)
+{
+ int i;
+
+ pvc_clear();
+ for (i = 0; i < PVC_NLINES; i++)
+ pvc_write_string(pvc_lines[i], 0, i);
+}
+
+static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0);
+
+static int pvc_line_proc_show(struct seq_file *m, void *v)
+{
+ int lineno = *(int *)m->private;
+
+ if (lineno < 0 || lineno > PVC_NLINES) {
+ printk(KERN_WARNING "proc_read_line: invalid lineno %d\n", lineno);
+ return 0;
+ }
+
+ mutex_lock(&pvc_mutex);
+ seq_printf(m, "%s\n", pvc_lines[lineno]);
+ mutex_unlock(&pvc_mutex);
+
+ return 0;
+}
+
+static int pvc_line_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pvc_line_proc_show, PDE(inode)->data);
+}
+
+static ssize_t pvc_line_proc_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *pos)
+{
+ int lineno = *(int *)PDE(file->f_path.dentry->d_inode)->data;
+ char kbuf[PVC_LINELEN];
+ size_t len;
+
+ BUG_ON(lineno < 0 || lineno > PVC_NLINES);
+
+ len = min(count, sizeof(kbuf) - 1);
+ if (copy_from_user(kbuf, buf, len))
+ return -EFAULT;
+ kbuf[len] = '\0';
+
+ if (len > 0 && kbuf[len - 1] == '\n')
+ len--;
+
+ mutex_lock(&pvc_mutex);
+ strncpy(pvc_lines[lineno], kbuf, len);
+ pvc_lines[lineno][len] = '\0';
+ mutex_unlock(&pvc_mutex);
+
+ tasklet_schedule(&pvc_display_tasklet);
+
+ return count;
+}
+
+static const struct file_operations pvc_line_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = pvc_line_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = pvc_line_proc_write,
+};
+
+static ssize_t pvc_scroll_proc_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *pos)
+{
+ char kbuf[42];
+ size_t len;
+ int cmd;
+
+ len = min(count, sizeof(kbuf) - 1);
+ if (copy_from_user(kbuf, buf, len))
+ return -EFAULT;
+ kbuf[len] = '\0';
+
+ cmd = simple_strtol(kbuf, NULL, 10);
+
+ mutex_lock(&pvc_mutex);
+ if (scroll_interval != 0)
+ del_timer(&timer);
+
+ if (cmd == 0) {
+ scroll_dir = 0;
+ scroll_interval = 0;
+ } else {
+ if (cmd < 0) {
+ scroll_dir = -1;
+ scroll_interval = -cmd;
+ } else {
+ scroll_dir = 1;
+ scroll_interval = cmd;
+ }
+ add_timer(&timer);
+ }
+ mutex_unlock(&pvc_mutex);
+
+ return count;
+}
+
+static int pvc_scroll_proc_show(struct seq_file *m, void *v)
+{
+ mutex_lock(&pvc_mutex);
+ seq_printf(m, "%d\n", scroll_dir * scroll_interval);
+ mutex_unlock(&pvc_mutex);
+
+ return 0;
+}
+
+static int pvc_scroll_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pvc_scroll_proc_show, NULL);
+}
+
+static const struct file_operations pvc_scroll_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = pvc_scroll_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = pvc_scroll_proc_write,
+};
+
+void pvc_proc_timerfunc(unsigned long data)
+{
+ if (scroll_dir < 0)
+ pvc_move(DISPLAY|RIGHT);
+ else if (scroll_dir > 0)
+ pvc_move(DISPLAY|LEFT);
+
+ timer.expires = jiffies + scroll_interval;
+ add_timer(&timer);
+}
+
+static void pvc_proc_cleanup(void)
+{
+ int i;
+ for (i = 0; i < PVC_NLINES; i++)
+ remove_proc_entry(pvc_linename[i], pvc_display_dir);
+ remove_proc_entry("scroll", pvc_display_dir);
+ remove_proc_entry(DISPLAY_DIR_NAME, NULL);
+
+ del_timer(&timer);
+}
+
+static int __init pvc_proc_init(void)
+{
+ struct proc_dir_entry *proc_entry;
+ int i;
+
+ pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL);
+ if (pvc_display_dir == NULL)
+ goto error;
+
+ for (i = 0; i < PVC_NLINES; i++) {
+ strcpy(pvc_lines[i], "");
+ pvc_linedata[i] = i;
+ }
+ for (i = 0; i < PVC_NLINES; i++) {
+ proc_entry = proc_create_data(pvc_linename[i], 0644, pvc_display_dir,
+ &pvc_line_proc_fops, &pvc_linedata[i]);
+ if (proc_entry == NULL)
+ goto error;
+ }
+ proc_entry = proc_create("scroll", 0644, pvc_display_dir,
+ &pvc_scroll_proc_fops);
+ if (proc_entry == NULL)
+ goto error;
+
+ init_timer(&timer);
+ timer.function = pvc_proc_timerfunc;
+
+ return 0;
+error:
+ pvc_proc_cleanup();
+ return -ENOMEM;
+}
+
+module_init(pvc_proc_init);
+module_exit(pvc_proc_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c
new file mode 100644
index 00000000..20fde19a
--- /dev/null
+++ b/arch/mips/lasat/prom.c
@@ -0,0 +1,124 @@
+/*
+ * PROM interface routines.
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <asm/bootinfo.h>
+#include <asm/lasat/lasat.h>
+#include <asm/cpu.h>
+
+#include "at93c.h"
+#include <asm/lasat/eeprom.h>
+#include "prom.h"
+
+#define RESET_VECTOR 0xbfc00000
+#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n))
+#define PROM_DISPLAY_ADDR PROM_JUMP_TABLE_ENTRY(0)
+#define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1)
+#define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2)
+
+static void null_prom_display(const char *string, int pos, int clear)
+{
+}
+
+static void null_prom_monitor(void)
+{
+}
+
+static void null_prom_putc(char c)
+{
+}
+
+/* these are functions provided by the bootloader */
+static void (*__prom_putc)(char c) = null_prom_putc;
+
+void prom_putchar(char c)
+{
+ __prom_putc(c);
+}
+
+void (*prom_display)(const char *string, int pos, int clear) =
+ null_prom_display;
+void (*prom_monitor)(void) = null_prom_monitor;
+
+unsigned int lasat_ndelay_divider;
+
+static void setup_prom_vectors(void)
+{
+ u32 version = *(u32 *)(RESET_VECTOR + 0x90);
+
+ if (version >= 307) {
+ prom_display = (void *)PROM_DISPLAY_ADDR;
+ __prom_putc = (void *)PROM_PUTC_ADDR;
+ prom_monitor = (void *)PROM_MONITOR_ADDR;
+ }
+ printk(KERN_DEBUG "prom vectors set up\n");
+}
+
+static struct at93c_defs at93c_defs[N_MACHTYPES] = {
+ {
+ .reg = (void *)AT93C_REG_100,
+ .rdata_reg = (void *)AT93C_RDATA_REG_100,
+ .rdata_shift = AT93C_RDATA_SHIFT_100,
+ .wdata_shift = AT93C_WDATA_SHIFT_100,
+ .cs = AT93C_CS_M_100,
+ .clk = AT93C_CLK_M_100
+ }, {
+ .reg = (void *)AT93C_REG_200,
+ .rdata_reg = (void *)AT93C_RDATA_REG_200,
+ .rdata_shift = AT93C_RDATA_SHIFT_200,
+ .wdata_shift = AT93C_WDATA_SHIFT_200,
+ .cs = AT93C_CS_M_200,
+ .clk = AT93C_CLK_M_200
+ },
+};
+
+void __init prom_init(void)
+{
+ int argc = fw_arg0;
+ char **argv = (char **) fw_arg1;
+
+ setup_prom_vectors();
+
+ if (IS_LASAT_200()) {
+ printk(KERN_INFO "LASAT 200 board\n");
+ lasat_ndelay_divider = LASAT_200_DIVIDER;
+ at93c = &at93c_defs[1];
+ } else {
+ printk(KERN_INFO "LASAT 100 board\n");
+ lasat_ndelay_divider = LASAT_100_DIVIDER;
+ at93c = &at93c_defs[0];
+ }
+
+ lasat_init_board_info(); /* Read info from EEPROM */
+
+ /* Get the command line */
+ if (argc > 0) {
+ strncpy(arcs_cmdline, argv[0], COMMAND_LINE_SIZE-1);
+ arcs_cmdline[COMMAND_LINE_SIZE-1] = '\0';
+ }
+
+ /* Set the I/O base address */
+ set_io_port_base(KSEG1);
+
+ /* Set memory regions */
+ ioport_resource.start = 0;
+ ioport_resource.end = 0xffffffff; /* Wrong, fixme. */
+
+ add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+const char *get_system_type(void)
+{
+ return lasat_board_info.li_bmstr;
+}
diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h
new file mode 100644
index 00000000..337acbc2
--- /dev/null
+++ b/arch/mips/lasat/prom.h
@@ -0,0 +1,7 @@
+#ifndef __PROM_H
+#define __PROM_H
+
+extern void (*prom_display)(const char *string, int pos, int clear);
+extern void (*prom_monitor)(void);
+
+#endif /* __PROM_H */
diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c
new file mode 100644
index 00000000..b1e7a89f
--- /dev/null
+++ b/arch/mips/lasat/reset.c
@@ -0,0 +1,61 @@
+/*
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Reset the LASAT board.
+ */
+#include <linux/kernel.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/lasat/lasat.h>
+
+#include "picvue.h"
+#include "prom.h"
+
+static void lasat_machine_restart(char *command);
+static void lasat_machine_halt(void);
+
+/* Used to set machine to boot in service mode via /proc interface */
+int lasat_boot_to_service;
+
+static void lasat_machine_restart(char *command)
+{
+ local_irq_disable();
+
+ if (lasat_boot_to_service) {
+ *(volatile unsigned int *)0xa0000024 = 0xdeadbeef;
+ *(volatile unsigned int *)0xa00000fc = 0xfedeabba;
+ }
+ *lasat_misc->reset_reg = 0xbedead;
+ for (;;) ;
+}
+
+static void lasat_machine_halt(void)
+{
+ local_irq_disable();
+
+ prom_monitor();
+ for (;;) ;
+}
+
+void lasat_reboot_setup(void)
+{
+ _machine_restart = lasat_machine_restart;
+ _machine_halt = lasat_machine_halt;
+ pm_power_off = lasat_machine_halt;
+}
diff --git a/arch/mips/lasat/serial.c b/arch/mips/lasat/serial.c
new file mode 100644
index 00000000..5bcb6e89
--- /dev/null
+++ b/arch/mips/lasat/serial.c
@@ -0,0 +1,93 @@
+/*
+ * Registration of Lasat UART platform device.
+ *
+ * Copyright (C) 2007 Brian Murphy <brian@murphy.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/lasat/lasat.h>
+#include <asm/lasat/serial.h>
+
+static struct resource lasat_serial_res[2] __initdata;
+
+static struct plat_serial8250_port lasat_serial8250_port[] = {
+ {
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF |
+ UPF_SKIP_TEST,
+ },
+ {},
+};
+
+static __init int lasat_uart_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ pdev = platform_device_alloc("serial8250", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ if (!IS_LASAT_200()) {
+ lasat_serial_res[0].start = KSEG1ADDR(LASAT_UART_REGS_BASE_100);
+ lasat_serial_res[0].end = lasat_serial_res[0].start + LASAT_UART_REGS_SHIFT_100 * 8 - 1;
+ lasat_serial_res[0].flags = IORESOURCE_MEM;
+ lasat_serial_res[1].start = LASATINT_UART_100;
+ lasat_serial_res[1].end = LASATINT_UART_100;
+ lasat_serial_res[1].flags = IORESOURCE_IRQ;
+
+ lasat_serial8250_port[0].mapbase = LASAT_UART_REGS_BASE_100;
+ lasat_serial8250_port[0].uartclk = LASAT_BASE_BAUD_100 * 16;
+ lasat_serial8250_port[0].regshift = LASAT_UART_REGS_SHIFT_100;
+ lasat_serial8250_port[0].irq = LASATINT_UART_100;
+ } else {
+ lasat_serial_res[0].start = KSEG1ADDR(LASAT_UART_REGS_BASE_200);
+ lasat_serial_res[0].end = lasat_serial_res[0].start + LASAT_UART_REGS_SHIFT_200 * 8 - 1;
+ lasat_serial_res[0].flags = IORESOURCE_MEM;
+ lasat_serial_res[1].start = LASATINT_UART_200;
+ lasat_serial_res[1].end = LASATINT_UART_200;
+ lasat_serial_res[1].flags = IORESOURCE_IRQ;
+
+ lasat_serial8250_port[0].mapbase = LASAT_UART_REGS_BASE_200;
+ lasat_serial8250_port[0].uartclk = LASAT_BASE_BAUD_200 * 16;
+ lasat_serial8250_port[0].regshift = LASAT_UART_REGS_SHIFT_200;
+ lasat_serial8250_port[0].irq = LASATINT_UART_200;
+ }
+
+ pdev->id = PLAT8250_DEV_PLATFORM;
+ pdev->dev.platform_data = lasat_serial8250_port;
+
+ retval = platform_device_add_resources(pdev, lasat_serial_res, ARRAY_SIZE(lasat_serial_res));
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(lasat_uart_add);
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
new file mode 100644
index 00000000..dbd3163a
--- /dev/null
+++ b/arch/mips/lasat/setup.c
@@ -0,0 +1,153 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved.
+ *
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ * Brian Murphy <brian@murphy.dk>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Lasat specific setup.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+
+#include <asm/time.h>
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/lasat/lasat.h>
+#include <asm/lasat/serial.h>
+
+#ifdef CONFIG_PICVUE
+#include <linux/notifier.h>
+#endif
+
+#include "ds1603.h"
+#include <asm/lasat/ds1603.h>
+#include <asm/lasat/picvue.h>
+#include <asm/lasat/eeprom.h>
+
+#include "prom.h"
+
+int lasat_command_line;
+void lasatint_init(void);
+
+extern void lasat_reboot_setup(void);
+extern void pcisetup(void);
+extern void edhac_init(void *, void *, void *);
+extern void addrflt_init(void);
+
+struct lasat_misc lasat_misc_info[N_MACHTYPES] = {
+ {
+ .reset_reg = (void *)KSEG1ADDR(0x1c840000),
+ .flash_wp_reg = (void *)KSEG1ADDR(0x1c800000), 2
+ }, {
+ .reset_reg = (void *)KSEG1ADDR(0x11080000),
+ .flash_wp_reg = (void *)KSEG1ADDR(0x11000000), 6
+ }
+};
+
+struct lasat_misc *lasat_misc;
+
+#ifdef CONFIG_DS1603
+static struct ds_defs ds_defs[N_MACHTYPES] = {
+ { (void *)DS1603_REG_100, (void *)DS1603_REG_100,
+ DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100,
+ DS1603_DATA_SHIFT_100, 0, 0 },
+ { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200,
+ DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200,
+ DS1603_DATA_READ_SHIFT_200, 1, 2000 }
+};
+#endif
+
+#ifdef CONFIG_PICVUE
+#include "picvue.h"
+static struct pvc_defs pvc_defs[N_MACHTYPES] = {
+ { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100,
+ PVC_E_100, PVC_RW_100, PVC_RS_100 },
+ { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200,
+ PVC_E_200, PVC_RW_200, PVC_RS_200 }
+};
+#endif
+
+static int lasat_panic_display(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+#ifdef CONFIG_PICVUE
+ unsigned char *string = ptr;
+ if (string == NULL)
+ string = "Kernel Panic";
+ pvc_dump_string(string);
+#endif
+ return NOTIFY_DONE;
+}
+
+static int lasat_panic_prom_monitor(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ prom_monitor();
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block lasat_panic_block[] =
+{
+ {
+ .notifier_call = lasat_panic_display,
+ .priority = INT_MAX
+ }, {
+ .notifier_call = lasat_panic_prom_monitor,
+ .priority = INT_MIN
+ }
+};
+
+void __init plat_time_init(void)
+{
+ mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2;
+
+ change_c0_status(ST0_IM, IE_IRQ0);
+}
+
+void __init plat_mem_setup(void)
+{
+ int i;
+ int lasat_type = IS_LASAT_200() ? 1 : 0;
+
+ lasat_misc = &lasat_misc_info[lasat_type];
+#ifdef CONFIG_PICVUE
+ picvue = &pvc_defs[lasat_type];
+#endif
+
+ /* Set up panic notifier */
+ for (i = 0; i < ARRAY_SIZE(lasat_panic_block); i++)
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &lasat_panic_block[i]);
+
+ lasat_reboot_setup();
+
+#ifdef CONFIG_DS1603
+ ds1603 = &ds_defs[lasat_type];
+#endif
+
+#ifdef DYNAMIC_SERIAL_INIT
+ serial_init();
+#endif
+
+ pr_info("Lasat specific initialization complete\n");
+}
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c
new file mode 100644
index 00000000..d87ffd04
--- /dev/null
+++ b/arch/mips/lasat/sysctl.c
@@ -0,0 +1,288 @@
+/*
+ * Thomas Horsten <thh@lasat.com>
+ * Copyright (C) 2000 LASAT Networks A/S.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines specific to the LASAT boards
+ */
+#include <linux/types.h>
+#include <asm/lasat/lasat.h>
+
+#include <linux/module.h>
+#include <linux/sysctl.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/net.h>
+#include <linux/inet.h>
+#include <linux/uaccess.h>
+
+#include <asm/time.h>
+
+#ifdef CONFIG_DS1603
+#include "ds1603.h"
+#endif
+
+
+/* And the same for proc */
+int proc_dolasatstring(ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ int r;
+
+ r = proc_dostring(table, write, buffer, lenp, ppos);
+ if ((!write) || r)
+ return r;
+
+ lasat_write_eeprom_info();
+
+ return 0;
+}
+
+/* proc function to write EEPROM after changing int entry */
+int proc_dolasatint(ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ int r;
+
+ r = proc_dointvec(table, write, buffer, lenp, ppos);
+ if ((!write) || r)
+ return r;
+
+ lasat_write_eeprom_info();
+
+ return 0;
+}
+
+#ifdef CONFIG_DS1603
+static int rtctmp;
+
+/* proc function to read/write RealTime Clock */
+int proc_dolasatrtc(ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ struct timespec ts;
+ int r;
+
+ if (!write) {
+ read_persistent_clock(&ts);
+ rtctmp = ts.tv_sec;
+ /* check for time < 0 and set to 0 */
+ if (rtctmp < 0)
+ rtctmp = 0;
+ }
+ r = proc_dointvec(table, write, buffer, lenp, ppos);
+ if (r)
+ return r;
+
+ if (write)
+ rtc_mips_set_mmss(rtctmp);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_INET
+int proc_lasat_ip(ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ unsigned int ip;
+ char *p, c;
+ int len;
+ char ipbuf[32];
+
+ if (!table->data || !table->maxlen || !*lenp ||
+ (*ppos && !write)) {
+ *lenp = 0;
+ return 0;
+ }
+
+ if (write) {
+ len = 0;
+ p = buffer;
+ while (len < *lenp) {
+ if (get_user(c, p++))
+ return -EFAULT;
+ if (c == 0 || c == '\n')
+ break;
+ len++;
+ }
+ if (len >= sizeof(ipbuf)-1)
+ len = sizeof(ipbuf) - 1;
+ if (copy_from_user(ipbuf, buffer, len))
+ return -EFAULT;
+ ipbuf[len] = 0;
+ *ppos += *lenp;
+ /* Now see if we can convert it to a valid IP */
+ ip = in_aton(ipbuf);
+ *(unsigned int *)(table->data) = ip;
+ lasat_write_eeprom_info();
+ } else {
+ ip = *(unsigned int *)(table->data);
+ sprintf(ipbuf, "%d.%d.%d.%d",
+ (ip) & 0xff,
+ (ip >> 8) & 0xff,
+ (ip >> 16) & 0xff,
+ (ip >> 24) & 0xff);
+ len = strlen(ipbuf);
+ if (len > *lenp)
+ len = *lenp;
+ if (len)
+ if (copy_to_user(buffer, ipbuf, len))
+ return -EFAULT;
+ if (len < *lenp) {
+ if (put_user('\n', ((char *) buffer) + len))
+ return -EFAULT;
+ len++;
+ }
+ *lenp = len;
+ *ppos += len;
+ }
+
+ return 0;
+}
+#endif
+
+int proc_lasat_prid(ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ int r;
+
+ r = proc_dointvec(table, write, buffer, lenp, ppos);
+ if (r < 0)
+ return r;
+ if (write) {
+ lasat_board_info.li_eeprom_info.prid =
+ lasat_board_info.li_prid;
+ lasat_write_eeprom_info();
+ lasat_init_board_info();
+ }
+ return 0;
+}
+
+extern int lasat_boot_to_service;
+
+static ctl_table lasat_table[] = {
+ {
+ .procname = "cpu-hz",
+ .data = &lasat_board_info.li_cpu_hz,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .procname = "bus-hz",
+ .data = &lasat_board_info.li_bus_hz,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .procname = "bmid",
+ .data = &lasat_board_info.li_bmid,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .procname = "prid",
+ .data = &lasat_board_info.li_prid,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_lasat_prid,
+ },
+#ifdef CONFIG_INET
+ {
+ .procname = "ipaddr",
+ .data = &lasat_board_info.li_eeprom_info.ipaddr,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_lasat_ip,
+ },
+ {
+ .procname = "netmask",
+ .data = &lasat_board_info.li_eeprom_info.netmask,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_lasat_ip,
+ },
+#endif
+ {
+ .procname = "passwd_hash",
+ .data = &lasat_board_info.li_eeprom_info.passwd_hash,
+ .maxlen =
+ sizeof(lasat_board_info.li_eeprom_info.passwd_hash),
+ .mode = 0600,
+ .proc_handler = proc_dolasatstring,
+ },
+ {
+ .procname = "boot-service",
+ .data = &lasat_boot_to_service,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+#ifdef CONFIG_DS1603
+ {
+ .procname = "rtc",
+ .data = &rtctmp,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dolasatrtc,
+ },
+#endif
+ {
+ .procname = "namestr",
+ .data = &lasat_board_info.li_namestr,
+ .maxlen = sizeof(lasat_board_info.li_namestr),
+ .mode = 0444,
+ .proc_handler = proc_dostring,
+ },
+ {
+ .procname = "typestr",
+ .data = &lasat_board_info.li_typestr,
+ .maxlen = sizeof(lasat_board_info.li_typestr),
+ .mode = 0444,
+ .proc_handler = proc_dostring,
+ },
+ {}
+};
+
+static ctl_table lasat_root_table[] = {
+ {
+ .procname = "lasat",
+ .mode = 0555,
+ .child = lasat_table
+ },
+ {}
+};
+
+static int __init lasat_register_sysctl(void)
+{
+ struct ctl_table_header *lasat_table_header;
+
+ lasat_table_header =
+ register_sysctl_table(lasat_root_table);
+ if (!lasat_table_header) {
+ printk(KERN_ERR "Unable to register LASAT sysctl\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+__initcall(lasat_register_sysctl);
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
new file mode 100644
index 00000000..b2cad4fd
--- /dev/null
+++ b/arch/mips/lib/Makefile
@@ -0,0 +1,34 @@
+#
+# Makefile for MIPS-specific library files..
+#
+
+lib-y += csum_partial.o delay.o memcpy.o memcpy-inatomic.o memset.o \
+ strlen_user.o strncpy_user.o strnlen_user.o uncached.o
+
+obj-y += iomap.o
+obj-$(CONFIG_PCI) += iomap-pci.o
+
+obj-$(CONFIG_CPU_LOONGSON2) += dump_tlb.o
+obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
+obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
+obj-$(CONFIG_CPU_NEVADA) += dump_tlb.o
+obj-$(CONFIG_CPU_R10000) += dump_tlb.o
+obj-$(CONFIG_CPU_R3000) += r3k_dump_tlb.o
+obj-$(CONFIG_CPU_R4300) += dump_tlb.o
+obj-$(CONFIG_CPU_R4X00) += dump_tlb.o
+obj-$(CONFIG_CPU_R5000) += dump_tlb.o
+obj-$(CONFIG_CPU_R5432) += dump_tlb.o
+obj-$(CONFIG_CPU_R5500) += dump_tlb.o
+obj-$(CONFIG_CPU_R6000) +=
+obj-$(CONFIG_CPU_R8000) +=
+obj-$(CONFIG_CPU_RM7000) += dump_tlb.o
+obj-$(CONFIG_CPU_RM9000) += dump_tlb.o
+obj-$(CONFIG_CPU_SB1) += dump_tlb.o
+obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
+obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o
+obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += dump_tlb.o
+obj-$(CONFIG_CPU_XLR) += dump_tlb.o
+
+# libgcc-style stuff needed in the kernel
+obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c
new file mode 100644
index 00000000..beb80f31
--- /dev/null
+++ b/arch/mips/lib/ashldi3.c
@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashldi3(long long u, word_type b)
+{
+ DWunion uu, w;
+ word_type bm;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+ bm = 32 - b;
+
+ if (bm <= 0) {
+ w.s.low = 0;
+ w.s.high = (unsigned int) uu.s.low << -bm;
+ } else {
+ const unsigned int carries = (unsigned int) uu.s.low >> bm;
+
+ w.s.low = (unsigned int) uu.s.low << b;
+ w.s.high = ((unsigned int) uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
+
+EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c
new file mode 100644
index 00000000..c884a912
--- /dev/null
+++ b/arch/mips/lib/ashrdi3.c
@@ -0,0 +1,31 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __ashrdi3(long long u, word_type b)
+{
+ DWunion uu, w;
+ word_type bm;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+ bm = 32 - b;
+
+ if (bm <= 0) {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high =
+ uu.s.high >> 31;
+ w.s.low = uu.s.high >> -bm;
+ } else {
+ const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
+
+EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/mips/lib/cmpdi2.c b/arch/mips/lib/cmpdi2.c
new file mode 100644
index 00000000..8c130643
--- /dev/null
+++ b/arch/mips/lib/cmpdi2.c
@@ -0,0 +1,27 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+word_type __cmpdi2(long long a, long long b)
+{
+ const DWunion au = {
+ .ll = a
+ };
+ const DWunion bu = {
+ .ll = b
+ };
+
+ if (au.s.high < bu.s.high)
+ return 0;
+ else if (au.s.high > bu.s.high)
+ return 2;
+
+ if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
+ return 0;
+ else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
+ return 2;
+
+ return 1;
+}
+
+EXPORT_SYMBOL(__cmpdi2);
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S
new file mode 100644
index 00000000..6b876ca2
--- /dev/null
+++ b/arch/mips/lib/csum_partial.S
@@ -0,0 +1,760 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Quick'n'dirty IP checksum ...
+ *
+ * Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
+ */
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#ifdef CONFIG_64BIT
+/*
+ * As we are sharing code base with the mips32 tree (which use the o32 ABI
+ * register definitions). We need to redefine the register definitions from
+ * the n64 ABI register naming to the o32 ABI register naming.
+ */
+#undef t0
+#undef t1
+#undef t2
+#undef t3
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+
+#define USE_DOUBLE
+#endif
+
+#ifdef USE_DOUBLE
+
+#define LOAD ld
+#define LOAD32 lwu
+#define ADD daddu
+#define NBYTES 8
+
+#else
+
+#define LOAD lw
+#define LOAD32 lw
+#define ADD addu
+#define NBYTES 4
+
+#endif /* USE_DOUBLE */
+
+#define UNIT(unit) ((unit)*NBYTES)
+
+#define ADDC(sum,reg) \
+ ADD sum, reg; \
+ sltu v1, sum, reg; \
+ ADD sum, v1; \
+
+#define ADDC32(sum,reg) \
+ addu sum, reg; \
+ sltu v1, sum, reg; \
+ addu sum, v1; \
+
+#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \
+ LOAD _t0, (offset + UNIT(0))(src); \
+ LOAD _t1, (offset + UNIT(1))(src); \
+ LOAD _t2, (offset + UNIT(2))(src); \
+ LOAD _t3, (offset + UNIT(3))(src); \
+ ADDC(sum, _t0); \
+ ADDC(sum, _t1); \
+ ADDC(sum, _t2); \
+ ADDC(sum, _t3)
+
+#ifdef USE_DOUBLE
+#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \
+ CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3)
+#else
+#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \
+ CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3); \
+ CSUM_BIGCHUNK1(src, offset + 0x10, sum, _t0, _t1, _t2, _t3)
+#endif
+
+/*
+ * a0: source address
+ * a1: length of the area to checksum
+ * a2: partial checksum
+ */
+
+#define src a0
+#define sum v0
+
+ .text
+ .set noreorder
+ .align 5
+LEAF(csum_partial)
+ move sum, zero
+ move t7, zero
+
+ sltiu t8, a1, 0x8
+ bnez t8, .Lsmall_csumcpy /* < 8 bytes to copy */
+ move t2, a1
+
+ andi t7, src, 0x1 /* odd buffer? */
+
+.Lhword_align:
+ beqz t7, .Lword_align
+ andi t8, src, 0x2
+
+ lbu t0, (src)
+ LONG_SUBU a1, a1, 0x1
+#ifdef __MIPSEL__
+ sll t0, t0, 8
+#endif
+ ADDC(sum, t0)
+ PTR_ADDU src, src, 0x1
+ andi t8, src, 0x2
+
+.Lword_align:
+ beqz t8, .Ldword_align
+ sltiu t8, a1, 56
+
+ lhu t0, (src)
+ LONG_SUBU a1, a1, 0x2
+ ADDC(sum, t0)
+ sltiu t8, a1, 56
+ PTR_ADDU src, src, 0x2
+
+.Ldword_align:
+ bnez t8, .Ldo_end_words
+ move t8, a1
+
+ andi t8, src, 0x4
+ beqz t8, .Lqword_align
+ andi t8, src, 0x8
+
+ LOAD32 t0, 0x00(src)
+ LONG_SUBU a1, a1, 0x4
+ ADDC(sum, t0)
+ PTR_ADDU src, src, 0x4
+ andi t8, src, 0x8
+
+.Lqword_align:
+ beqz t8, .Loword_align
+ andi t8, src, 0x10
+
+#ifdef USE_DOUBLE
+ ld t0, 0x00(src)
+ LONG_SUBU a1, a1, 0x8
+ ADDC(sum, t0)
+#else
+ lw t0, 0x00(src)
+ lw t1, 0x04(src)
+ LONG_SUBU a1, a1, 0x8
+ ADDC(sum, t0)
+ ADDC(sum, t1)
+#endif
+ PTR_ADDU src, src, 0x8
+ andi t8, src, 0x10
+
+.Loword_align:
+ beqz t8, .Lbegin_movement
+ LONG_SRL t8, a1, 0x7
+
+#ifdef USE_DOUBLE
+ ld t0, 0x00(src)
+ ld t1, 0x08(src)
+ ADDC(sum, t0)
+ ADDC(sum, t1)
+#else
+ CSUM_BIGCHUNK1(src, 0x00, sum, t0, t1, t3, t4)
+#endif
+ LONG_SUBU a1, a1, 0x10
+ PTR_ADDU src, src, 0x10
+ LONG_SRL t8, a1, 0x7
+
+.Lbegin_movement:
+ beqz t8, 1f
+ andi t2, a1, 0x40
+
+.Lmove_128bytes:
+ CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
+ CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
+ CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
+ CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
+ LONG_SUBU t8, t8, 0x01
+ .set reorder /* DADDI_WAR */
+ PTR_ADDU src, src, 0x80
+ bnez t8, .Lmove_128bytes
+ .set noreorder
+
+1:
+ beqz t2, 1f
+ andi t2, a1, 0x20
+
+.Lmove_64bytes:
+ CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
+ CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
+ PTR_ADDU src, src, 0x40
+
+1:
+ beqz t2, .Ldo_end_words
+ andi t8, a1, 0x1c
+
+.Lmove_32bytes:
+ CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
+ andi t8, a1, 0x1c
+ PTR_ADDU src, src, 0x20
+
+.Ldo_end_words:
+ beqz t8, .Lsmall_csumcpy
+ andi t2, a1, 0x3
+ LONG_SRL t8, t8, 0x2
+
+.Lend_words:
+ LOAD32 t0, (src)
+ LONG_SUBU t8, t8, 0x1
+ ADDC(sum, t0)
+ .set reorder /* DADDI_WAR */
+ PTR_ADDU src, src, 0x4
+ bnez t8, .Lend_words
+ .set noreorder
+
+/* unknown src alignment and < 8 bytes to go */
+.Lsmall_csumcpy:
+ move a1, t2
+
+ andi t0, a1, 4
+ beqz t0, 1f
+ andi t0, a1, 2
+
+ /* Still a full word to go */
+ ulw t1, (src)
+ PTR_ADDIU src, 4
+#ifdef USE_DOUBLE
+ dsll t1, t1, 32 /* clear lower 32bit */
+#endif
+ ADDC(sum, t1)
+
+1: move t1, zero
+ beqz t0, 1f
+ andi t0, a1, 1
+
+ /* Still a halfword to go */
+ ulhu t1, (src)
+ PTR_ADDIU src, 2
+
+1: beqz t0, 1f
+ sll t1, t1, 16
+
+ lbu t2, (src)
+ nop
+
+#ifdef __MIPSEB__
+ sll t2, t2, 8
+#endif
+ or t1, t2
+
+1: ADDC(sum, t1)
+
+ /* fold checksum */
+#ifdef USE_DOUBLE
+ dsll32 v1, sum, 0
+ daddu sum, v1
+ sltu v1, sum, v1
+ dsra32 sum, sum, 0
+ addu sum, v1
+#endif
+
+ /* odd buffer alignment? */
+#ifdef CPU_MIPSR2
+ wsbh v1, sum
+ movn sum, v1, t7
+#else
+ beqz t7, 1f /* odd buffer alignment? */
+ lui v1, 0x00ff
+ addu v1, 0x00ff
+ and t0, sum, v1
+ sll t0, t0, 8
+ srl sum, sum, 8
+ and sum, sum, v1
+ or sum, sum, t0
+1:
+#endif
+ .set reorder
+ /* Add the passed partial csum. */
+ ADDC32(sum, a2)
+ jr ra
+ .set noreorder
+ END(csum_partial)
+
+
+/*
+ * checksum and copy routines based on memcpy.S
+ *
+ * csum_partial_copy_nocheck(src, dst, len, sum)
+ * __csum_partial_copy_user(src, dst, len, sum, errp)
+ *
+ * See "Spec" in memcpy.S for details. Unlike __copy_user, all
+ * function in this file use the standard calling convention.
+ */
+
+#define src a0
+#define dst a1
+#define len a2
+#define psum a3
+#define sum v0
+#define odd t8
+#define errptr t9
+
+/*
+ * The exception handler for loads requires that:
+ * 1- AT contain the address of the byte just past the end of the source
+ * of the copy,
+ * 2- src_entry <= src < AT, and
+ * 3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by __csum_partial_copy_from_user and maintained by
+ * not writing AT in __csum_partial_copy
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores stores -EFAULT to errptr and return.
+ * These handlers do not need to overwrite any data.
+ */
+
+#define EXC(inst_reg,addr,handler) \
+9: inst_reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+#ifdef USE_DOUBLE
+
+#define LOAD ld
+#define LOADL ldl
+#define LOADR ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE sd
+#define ADD daddu
+#define SUB dsubu
+#define SRL dsrl
+#define SLL dsll
+#define SLLV dsllv
+#define SRLV dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+#else
+
+#define LOAD lw
+#define LOADL lwl
+#define LOADR lwr
+#define STOREL swl
+#define STORER swr
+#define STORE sw
+#define ADD addu
+#define SUB subu
+#define SRL srl
+#define SLL sll
+#define SLLV sllv
+#define SRLV srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST LOADL
+#define STFIRST STORER
+#define STREST STOREL
+#define SHIFT_DISCARD SLLV
+#define SHIFT_DISCARD_REVERT SRLV
+#else
+#define LDFIRST LOADL
+#define LDREST LOADR
+#define STFIRST STOREL
+#define STREST STORER
+#define SHIFT_DISCARD SRLV
+#define SHIFT_DISCARD_REVERT SLLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit) (FIRST(unit)+NBYTES-1)
+
+#define ADDRMASK (NBYTES-1)
+
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+ .set noat
+#else
+ .set at=v1
+#endif
+
+LEAF(__csum_partial_copy_user)
+ PTR_ADDU AT, src, len /* See (1) above. */
+#ifdef CONFIG_64BIT
+ move errptr, a4
+#else
+ lw errptr, 16(sp)
+#endif
+FEXPORT(csum_partial_copy_nocheck)
+ move sum, zero
+ move odd, zero
+ /*
+ * Note: dst & src may be unaligned, len may be 0
+ * Temps
+ */
+ /*
+ * The "issue break"s below are very approximate.
+ * Issue delays for dcache fills will perturb the schedule, as will
+ * load queue full replay traps, etc.
+ *
+ * If len < NBYTES use byte operations.
+ */
+ sltu t2, len, NBYTES
+ and t1, dst, ADDRMASK
+ bnez t2, .Lcopy_bytes_checklen
+ and t0, src, ADDRMASK
+ andi odd, dst, 0x1 /* odd buffer? */
+ bnez t1, .Ldst_unaligned
+ nop
+ bnez t0, .Lsrc_unaligned_dst_aligned
+ /*
+ * use delay slot for fall-through
+ * src and dst are aligned; need to compute rem
+ */
+.Lboth_aligned:
+ SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
+ beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
+ nop
+ SUB len, 8*NBYTES # subtract here for bgez loop
+ .align 4
+1:
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
+EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
+EXC( LOAD t5, UNIT(5)(src), .Ll_exc_copy)
+EXC( LOAD t6, UNIT(6)(src), .Ll_exc_copy)
+EXC( LOAD t7, UNIT(7)(src), .Ll_exc_copy)
+ SUB len, len, 8*NBYTES
+ ADD src, src, 8*NBYTES
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
+ ADDC(sum, t0)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
+ ADDC(sum, t1)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
+ ADDC(sum, t2)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
+ ADDC(sum, t3)
+EXC( STORE t4, UNIT(4)(dst), .Ls_exc)
+ ADDC(sum, t4)
+EXC( STORE t5, UNIT(5)(dst), .Ls_exc)
+ ADDC(sum, t5)
+EXC( STORE t6, UNIT(6)(dst), .Ls_exc)
+ ADDC(sum, t6)
+EXC( STORE t7, UNIT(7)(dst), .Ls_exc)
+ ADDC(sum, t7)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 8*NBYTES
+ bgez len, 1b
+ .set noreorder
+ ADD len, 8*NBYTES # revert len (see above)
+
+ /*
+ * len == the number of bytes left to copy < 8*NBYTES
+ */
+.Lcleanup_both_aligned:
+#define rem t7
+ beqz len, .Ldone
+ sltu t0, len, 4*NBYTES
+ bnez t0, .Lless_than_4units
+ and rem, len, (NBYTES-1) # rem = len % NBYTES
+ /*
+ * len >= 4*NBYTES
+ */
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
+ SUB len, len, 4*NBYTES
+ ADD src, src, 4*NBYTES
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
+ ADDC(sum, t0)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
+ ADDC(sum, t1)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
+ ADDC(sum, t2)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
+ ADDC(sum, t3)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ beqz len, .Ldone
+ .set noreorder
+.Lless_than_4units:
+ /*
+ * rem = len % NBYTES
+ */
+ beq rem, len, .Lcopy_bytes
+ nop
+1:
+EXC( LOAD t0, 0(src), .Ll_exc)
+ ADD src, src, NBYTES
+ SUB len, len, NBYTES
+EXC( STORE t0, 0(dst), .Ls_exc)
+ ADDC(sum, t0)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
+ bne rem, len, 1b
+ .set noreorder
+
+ /*
+ * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
+ * A loop would do only a byte at a time with possible branch
+ * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE
+ * because can't assume read-access to dst. Instead, use
+ * STREST dst, which doesn't require read access to dst.
+ *
+ * This code should perform better than a simple loop on modern,
+ * wide-issue mips processors because the code has fewer branches and
+ * more instruction-level parallelism.
+ */
+#define bits t2
+ beqz len, .Ldone
+ ADD t1, dst, len # t1 is just past last byte of dst
+ li bits, 8*NBYTES
+ SLL rem, len, 3 # rem = number of bits to keep
+EXC( LOAD t0, 0(src), .Ll_exc)
+ SUB bits, bits, rem # bits = number of bits to discard
+ SHIFT_DISCARD t0, t0, bits
+EXC( STREST t0, -1(t1), .Ls_exc)
+ SHIFT_DISCARD_REVERT t0, t0, bits
+ .set reorder
+ ADDC(sum, t0)
+ b .Ldone
+ .set noreorder
+.Ldst_unaligned:
+ /*
+ * dst is unaligned
+ * t0 = src & ADDRMASK
+ * t1 = dst & ADDRMASK; T1 > 0
+ * len >= NBYTES
+ *
+ * Copy enough bytes to align dst
+ * Set match = (src and dst have same alignment)
+ */
+#define match rem
+EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
+ ADD t2, zero, NBYTES
+EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
+ SUB t2, t2, t1 # t2 = number of bytes copied
+ xor match, t0, t1
+EXC( STFIRST t3, FIRST(0)(dst), .Ls_exc)
+ SLL t4, t1, 3 # t4 = number of bits to discard
+ SHIFT_DISCARD t3, t3, t4
+ /* no SHIFT_DISCARD_REVERT to handle odd buffer properly */
+ ADDC(sum, t3)
+ beq len, t2, .Ldone
+ SUB len, len, t2
+ ADD dst, dst, t2
+ beqz match, .Lboth_aligned
+ ADD src, src, t2
+
+.Lsrc_unaligned_dst_aligned:
+ SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
+ beqz t0, .Lcleanup_src_unaligned
+ and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
+ SUB len, len, 4*NBYTES
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
+EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
+EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
+EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
+EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
+ ADD src, src, 4*NBYTES
+#ifdef CONFIG_CPU_SB1
+ nop # improves slotting
+#endif
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc)
+ ADDC(sum, t0)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc)
+ ADDC(sum, t1)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc)
+ ADDC(sum, t2)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc)
+ ADDC(sum, t3)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ bne len, rem, 1b
+ .set noreorder
+
+.Lcleanup_src_unaligned:
+ beqz len, .Ldone
+ and rem, len, NBYTES-1 # rem = len % NBYTES
+ beq rem, len, .Lcopy_bytes
+ nop
+1:
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+ ADD src, src, NBYTES
+ SUB len, len, NBYTES
+EXC( STORE t0, 0(dst), .Ls_exc)
+ ADDC(sum, t0)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
+ bne len, rem, 1b
+ .set noreorder
+
+.Lcopy_bytes_checklen:
+ beqz len, .Ldone
+ nop
+.Lcopy_bytes:
+ /* 0 < len < NBYTES */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define SHIFT_START 0
+#define SHIFT_INC 8
+#else
+#define SHIFT_START 8*(NBYTES-1)
+#define SHIFT_INC -8
+#endif
+ move t2, zero # partial word
+ li t3, SHIFT_START # shift
+/* use .Ll_exc_copy here to return correct sum on fault */
+#define COPY_BYTE(N) \
+EXC( lbu t0, N(src), .Ll_exc_copy); \
+ SUB len, len, 1; \
+EXC( sb t0, N(dst), .Ls_exc); \
+ SLLV t0, t0, t3; \
+ addu t3, SHIFT_INC; \
+ beqz len, .Lcopy_bytes_done; \
+ or t2, t0
+
+ COPY_BYTE(0)
+ COPY_BYTE(1)
+#ifdef USE_DOUBLE
+ COPY_BYTE(2)
+ COPY_BYTE(3)
+ COPY_BYTE(4)
+ COPY_BYTE(5)
+#endif
+EXC( lbu t0, NBYTES-2(src), .Ll_exc_copy)
+ SUB len, len, 1
+EXC( sb t0, NBYTES-2(dst), .Ls_exc)
+ SLLV t0, t0, t3
+ or t2, t0
+.Lcopy_bytes_done:
+ ADDC(sum, t2)
+.Ldone:
+ /* fold checksum */
+#ifdef USE_DOUBLE
+ dsll32 v1, sum, 0
+ daddu sum, v1
+ sltu v1, sum, v1
+ dsra32 sum, sum, 0
+ addu sum, v1
+#endif
+
+#ifdef CPU_MIPSR2
+ wsbh v1, sum
+ movn sum, v1, odd
+#else
+ beqz odd, 1f /* odd buffer alignment? */
+ lui v1, 0x00ff
+ addu v1, 0x00ff
+ and t0, sum, v1
+ sll t0, t0, 8
+ srl sum, sum, 8
+ and sum, sum, v1
+ or sum, sum, t0
+1:
+#endif
+ .set reorder
+ ADDC32(sum, psum)
+ jr ra
+ .set noreorder
+
+.Ll_exc_copy:
+ /*
+ * Copy bytes from src until faulting load address (or until a
+ * lb faults)
+ *
+ * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+ * may be more than a byte beyond the last address.
+ * Hence, the lb below may get an exception.
+ *
+ * Assumes src < THREAD_BUADDR($28)
+ */
+ LOAD t0, TI_TASK($28)
+ li t2, SHIFT_START
+ LOAD t0, THREAD_BUADDR(t0)
+1:
+EXC( lbu t1, 0(src), .Ll_exc)
+ ADD src, src, 1
+ sb t1, 0(dst) # can't fault -- we're copy_from_user
+ SLLV t1, t1, t2
+ addu t2, SHIFT_INC
+ ADDC(sum, t1)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 1
+ bne src, t0, 1b
+ .set noreorder
+.Ll_exc:
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
+ nop
+ SUB len, AT, t0 # len number of uncopied bytes
+ /*
+ * Here's where we rely on src and dst being incremented in tandem,
+ * See (3) above.
+ * dst += (fault addr - src) to put dst at first byte to clear
+ */
+ ADD dst, t0 # compute start address in a1
+ SUB dst, src
+ /*
+ * Clear len bytes starting at dst. Can't call __bzero because it
+ * might modify len. An inefficient loop for these rare times...
+ */
+ .set reorder /* DADDI_WAR */
+ SUB src, len, 1
+ beqz len, .Ldone
+ .set noreorder
+1: sb zero, 0(dst)
+ ADD dst, dst, 1
+ .set push
+ .set noat
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+ bnez src, 1b
+ SUB src, src, 1
+#else
+ li v1, 1
+ bnez src, 1b
+ SUB src, src, v1
+#endif
+ li v1, -EFAULT
+ b .Ldone
+ sw v1, (errptr)
+
+.Ls_exc:
+ li v0, -1 /* invalid checksum */
+ li v1, -EFAULT
+ jr ra
+ sw v1, (errptr)
+ .set pop
+ END(__csum_partial_copy_user)
diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c
new file mode 100644
index 00000000..5995969e
--- /dev/null
+++ b/arch/mips/lib/delay.c
@@ -0,0 +1,56 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 by Waldorf Electronics
+ * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
+ */
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/smp.h>
+
+#include <asm/compiler.h>
+#include <asm/war.h>
+
+inline void __delay(unsigned int loops)
+{
+ __asm__ __volatile__ (
+ " .set noreorder \n"
+ " .align 3 \n"
+ "1: bnez %0, 1b \n"
+ " subu %0, 1 \n"
+ " .set reorder \n"
+ : "=r" (loops)
+ : "0" (loops));
+}
+EXPORT_SYMBOL(__delay);
+
+/*
+ * Division by multiplication: you don't have to worry about
+ * loss of precision.
+ *
+ * Use only for very small delays ( < 1 msec). Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays. This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+
+void __udelay(unsigned long us)
+{
+ unsigned int lpj = raw_current_cpu_data.udelay_val;
+
+ __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
+}
+EXPORT_SYMBOL(__udelay);
+
+void __ndelay(unsigned long ns)
+{
+ unsigned int lpj = raw_current_cpu_data.udelay_val;
+
+ __delay((ns * 0x00000005ull * HZ * lpj) >> 32);
+}
+EXPORT_SYMBOL(__ndelay);
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
new file mode 100644
index 00000000..3f697255
--- /dev/null
+++ b/arch/mips/lib/dump_tlb.c
@@ -0,0 +1,111 @@
+/*
+ * Dump R4x00 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbdebug.h>
+
+static inline const char *msk2str(unsigned int mask)
+{
+ switch (mask) {
+ case PM_4K: return "4kb";
+ case PM_16K: return "16kb";
+ case PM_64K: return "64kb";
+ case PM_256K: return "256kb";
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ case PM_8K: return "8kb";
+ case PM_32K: return "32kb";
+ case PM_128K: return "128kb";
+ case PM_512K: return "512kb";
+ case PM_2M: return "2Mb";
+ case PM_8M: return "8Mb";
+ case PM_32M: return "32Mb";
+#endif
+#ifndef CONFIG_CPU_VR41XX
+ case PM_1M: return "1Mb";
+ case PM_4M: return "4Mb";
+ case PM_16M: return "16Mb";
+ case PM_64M: return "64Mb";
+ case PM_256M: return "256Mb";
+ case PM_1G: return "1Gb";
+#endif
+ }
+ return "";
+}
+
+#define BARRIER() \
+ __asm__ __volatile__( \
+ ".set\tnoreorder\n\t" \
+ "nop;nop;nop;nop;nop;nop;nop\n\t" \
+ ".set\treorder");
+
+static void dump_tlb(int first, int last)
+{
+ unsigned long s_entryhi, entryhi, asid;
+ unsigned long long entrylo0, entrylo1;
+ unsigned int s_index, pagemask, c0, c1, i;
+
+ s_entryhi = read_c0_entryhi();
+ s_index = read_c0_index();
+ asid = s_entryhi & 0xff;
+
+ for (i = first; i <= last; i++) {
+ write_c0_index(i);
+ BARRIER();
+ tlb_read();
+ BARRIER();
+ pagemask = read_c0_pagemask();
+ entryhi = read_c0_entryhi();
+ entrylo0 = read_c0_entrylo0();
+ entrylo1 = read_c0_entrylo1();
+
+ /* Unused entries have a virtual address of CKSEG0. */
+ if ((entryhi & ~0x1ffffUL) != CKSEG0
+ && (entryhi & 0xff) == asid) {
+#ifdef CONFIG_32BIT
+ int width = 8;
+#else
+ int width = 11;
+#endif
+ /*
+ * Only print entries in use
+ */
+ printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
+
+ c0 = (entrylo0 >> 3) & 7;
+ c1 = (entrylo1 >> 3) & 7;
+
+ printk("va=%0*lx asid=%02lx\n",
+ width, (entryhi & ~0x1fffUL),
+ entryhi & 0xff);
+ printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
+ width,
+ (entrylo0 << 6) & PAGE_MASK, c0,
+ (entrylo0 & 4) ? 1 : 0,
+ (entrylo0 & 2) ? 1 : 0,
+ (entrylo0 & 1) ? 1 : 0);
+ printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
+ width,
+ (entrylo1 << 6) & PAGE_MASK, c1,
+ (entrylo1 & 4) ? 1 : 0,
+ (entrylo1 & 2) ? 1 : 0,
+ (entrylo1 & 1) ? 1 : 0);
+ }
+ }
+ printk("\n");
+
+ write_c0_entryhi(s_entryhi);
+ write_c0_index(s_index);
+}
+
+void dump_tlb_all(void)
+{
+ dump_tlb(0, current_cpu_data.tlbsize - 1);
+}
diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c
new file mode 100644
index 00000000..2ab899c4
--- /dev/null
+++ b/arch/mips/lib/iomap-pci.c
@@ -0,0 +1,74 @@
+/*
+ * Implement the default iomap interfaces
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ * (C) Copyright 2006 Ralf Baechle <ralf@linux-mips.org>
+ * (C) Copyright 2007 MIPS Technologies, Inc.
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <asm/io.h>
+
+static void __iomem *ioport_map_pci(struct pci_dev *dev,
+ unsigned long port, unsigned int nr)
+{
+ struct pci_controller *ctrl = dev->bus->sysdata;
+ unsigned long base = ctrl->io_map_base;
+
+ /* This will eventually become a BUG_ON but for now be gentle */
+ if (unlikely(!ctrl->io_map_base)) {
+ struct pci_bus *bus = dev->bus;
+ char name[8];
+
+ while (bus->parent)
+ bus = bus->parent;
+
+ ctrl->io_map_base = base = mips_io_port_base;
+
+ sprintf(name, "%04x:%02x", pci_domain_nr(bus), bus->number);
+ printk(KERN_WARNING "io_map_base of root PCI bus %s unset. "
+ "Trying to continue but you better\nfix this issue or "
+ "report it to linux-mips@linux-mips.org or your "
+ "vendor.\n", name);
+#ifdef CONFIG_PCI_DOMAINS
+ panic("To avoid data corruption io_map_base MUST be set with "
+ "multiple PCI domains.");
+#endif
+ }
+
+ return (void __iomem *) (ctrl->io_map_base + port);
+}
+
+/*
+ * Create a virtual mapping cookie for a PCI BAR (memory or IO)
+ */
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+ resource_size_t start = pci_resource_start(dev, bar);
+ resource_size_t len = pci_resource_len(dev, bar);
+ unsigned long flags = pci_resource_flags(dev, bar);
+
+ if (!len || !start)
+ return NULL;
+ if (maxlen && len > maxlen)
+ len = maxlen;
+ if (flags & IORESOURCE_IO)
+ return ioport_map_pci(dev, start, len);
+ if (flags & IORESOURCE_MEM) {
+ if (flags & IORESOURCE_CACHEABLE)
+ return ioremap(start, len);
+ return ioremap_nocache(start, len);
+ }
+ /* What? */
+ return NULL;
+}
+
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
+{
+ iounmap(addr);
+}
+
+EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c
new file mode 100644
index 00000000..e3acb2da
--- /dev/null
+++ b/arch/mips/lib/iomap.c
@@ -0,0 +1,226 @@
+/*
+ * Implement the default iomap interfaces
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ * (C) Copyright 2006 Ralf Baechle <ralf@linux-mips.org>
+ * (C) Copyright 2007 MIPS Technologies, Inc.
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/module.h>
+#include <asm/io.h>
+
+/*
+ * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
+ * access or a MMIO access, these functions don't care. The info is
+ * encoded in the hardware mapping set up by the mapping functions
+ * (or the cookie itself, depending on implementation and hw).
+ *
+ * The generic routines don't assume any hardware mappings, and just
+ * encode the PIO/MMIO as part of the cookie. They coldly assume that
+ * the MMIO IO mappings are not in the low address range.
+ *
+ * Architectures for which this is not true can't use this generic
+ * implementation and should do their own copy.
+ */
+
+#define PIO_MASK 0x0ffffUL
+
+unsigned int ioread8(void __iomem *addr)
+{
+ return readb(addr);
+}
+
+EXPORT_SYMBOL(ioread8);
+
+unsigned int ioread16(void __iomem *addr)
+{
+ return readw(addr);
+}
+
+EXPORT_SYMBOL(ioread16);
+
+unsigned int ioread16be(void __iomem *addr)
+{
+ return be16_to_cpu(__raw_readw(addr));
+}
+
+EXPORT_SYMBOL(ioread16be);
+
+unsigned int ioread32(void __iomem *addr)
+{
+ return readl(addr);
+}
+
+EXPORT_SYMBOL(ioread32);
+
+unsigned int ioread32be(void __iomem *addr)
+{
+ return be32_to_cpu(__raw_readl(addr));
+}
+
+EXPORT_SYMBOL(ioread32be);
+
+void iowrite8(u8 val, void __iomem *addr)
+{
+ writeb(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite8);
+
+void iowrite16(u16 val, void __iomem *addr)
+{
+ writew(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite16);
+
+void iowrite16be(u16 val, void __iomem *addr)
+{
+ __raw_writew(cpu_to_be16(val), addr);
+}
+
+EXPORT_SYMBOL(iowrite16be);
+
+void iowrite32(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+}
+
+EXPORT_SYMBOL(iowrite32);
+
+void iowrite32be(u32 val, void __iomem *addr)
+{
+ __raw_writel(cpu_to_be32(val), addr);
+}
+
+EXPORT_SYMBOL(iowrite32be);
+
+/*
+ * These are the "repeat MMIO read/write" functions.
+ * Note the "__raw" accesses, since we don't want to
+ * convert to CPU byte order. We write in "IO byte
+ * order" (we also don't have IO barriers).
+ */
+static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
+{
+ while (--count >= 0) {
+ u8 data = __raw_readb(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
+{
+ while (--count >= 0) {
+ u16 data = __raw_readw(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
+{
+ while (--count >= 0) {
+ u32 data = __raw_readl(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writeb(*src, addr);
+ src++;
+ }
+}
+
+static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writew(*src, addr);
+ src++;
+ }
+}
+
+static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writel(*src, addr);
+ src++;
+ }
+}
+
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insb(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread8_rep);
+
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insw(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread16_rep);
+
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insl(addr, dst, count);
+}
+
+EXPORT_SYMBOL(ioread32_rep);
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsb(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite8_rep);
+
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsw(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite16_rep);
+
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsl(addr, src, count);
+}
+
+EXPORT_SYMBOL(iowrite32_rep);
+
+/*
+ * Create a virtual mapping cookie for an IO port range
+ *
+ * This uses the same mapping are as the in/out family which has to be setup
+ * by the platform initialization code.
+ *
+ * Just to make matters somewhat more interesting on MIPS systems with
+ * multiple host bridge each will have it's own ioport address space.
+ */
+static void __iomem *ioport_map_legacy(unsigned long port, unsigned int nr)
+{
+ return (void __iomem *) (mips_io_port_base + port);
+}
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+ if (port > PIO_MASK)
+ return NULL;
+
+ return ioport_map_legacy(port, nr);
+}
+
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+ /* Nothing to do */
+}
+
+EXPORT_SYMBOL(ioport_unmap);
diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h
new file mode 100644
index 00000000..05909d58
--- /dev/null
+++ b/arch/mips/lib/libgcc.h
@@ -0,0 +1,25 @@
+#ifndef __ASM_LIBGCC_H
+#define __ASM_LIBGCC_H
+
+#include <asm/byteorder.h>
+
+typedef int word_type __attribute__ ((mode (__word__)));
+
+#ifdef __BIG_ENDIAN
+struct DWstruct {
+ int high, low;
+};
+#elif defined(__LITTLE_ENDIAN)
+struct DWstruct {
+ int low, high;
+};
+#else
+#error I feel sick.
+#endif
+
+typedef union {
+ struct DWstruct s;
+ long long ll;
+} DWunion;
+
+#endif /* __ASM_LIBGCC_H */
diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c
new file mode 100644
index 00000000..dcf8d681
--- /dev/null
+++ b/arch/mips/lib/lshrdi3.c
@@ -0,0 +1,29 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+long long __lshrdi3(long long u, word_type b)
+{
+ DWunion uu, w;
+ word_type bm;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+ bm = 32 - b;
+
+ if (bm <= 0) {
+ w.s.high = 0;
+ w.s.low = (unsigned int) uu.s.high >> -bm;
+ } else {
+ const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+ w.s.high = (unsigned int) uu.s.high >> b;
+ w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
+
+EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/mips/lib/memcpy-inatomic.S b/arch/mips/lib/memcpy-inatomic.S
new file mode 100644
index 00000000..68853a03
--- /dev/null
+++ b/arch/mips/lib/memcpy-inatomic.S
@@ -0,0 +1,451 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Unified implementation of memcpy, memmove and the __copy_user backend.
+ *
+ * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Broadcom, Inc.
+ * memcpy/copy_user author: Mark Vandevoorde
+ * Copyright (C) 2007 Maciej W. Rozycki
+ *
+ * Mnemonic names for arguments to memcpy/__copy_user
+ */
+
+/*
+ * Hack to resolve longstanding prefetch issue
+ *
+ * Prefetching may be fatal on some systems if we're prefetching beyond the
+ * end of memory on some systems. It's also a seriously bad idea on non
+ * dma-coherent systems.
+ */
+#ifdef CONFIG_DMA_NONCOHERENT
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+#ifdef CONFIG_MIPS_MALTA
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define dst a0
+#define src a1
+#define len a2
+
+/*
+ * Spec
+ *
+ * memcpy copies len bytes from src to dst and sets v0 to dst.
+ * It assumes that
+ * - src and dst don't overlap
+ * - src is readable
+ * - dst is writable
+ * memcpy uses the standard calling convention
+ *
+ * __copy_user copies up to len bytes from src to dst and sets a2 (len) to
+ * the number of uncopied bytes due to an exception caused by a read or write.
+ * __copy_user assumes that src and dst don't overlap, and that the call is
+ * implementing one of the following:
+ * copy_to_user
+ * - src is readable (no exceptions when reading src)
+ * copy_from_user
+ * - dst is writable (no exceptions when writing dst)
+ * __copy_user uses a non-standard calling convention; see
+ * include/asm-mips/uaccess.h
+ *
+ * When an exception happens on a load, the handler must
+ # ensure that all of the destination buffer is overwritten to prevent
+ * leaking information to user mode programs.
+ */
+
+/*
+ * Implementation
+ */
+
+/*
+ * The exception handler for loads requires that:
+ * 1- AT contain the address of the byte just past the end of the source
+ * of the copy,
+ * 2- src_entry <= src < AT, and
+ * 3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores adjust len (if necessary) and return.
+ * These handlers do not need to overwrite any data.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.
+ */
+
+#define EXC(inst_reg,addr,handler) \
+9: inst_reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+/*
+ * Only on the 64-bit kernel we can made use of 64-bit registers.
+ */
+#ifdef CONFIG_64BIT
+#define USE_DOUBLE
+#endif
+
+#ifdef USE_DOUBLE
+
+#define LOAD ld
+#define LOADL ldl
+#define LOADR ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE sd
+#define ADD daddu
+#define SUB dsubu
+#define SRL dsrl
+#define SRA dsra
+#define SLL dsll
+#define SLLV dsllv
+#define SRLV dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+/*
+ * As we are sharing code base with the mips32 tree (which use the o32 ABI
+ * register definitions). We need to redefine the register definitions from
+ * the n64 ABI register naming to the o32 ABI register naming.
+ */
+#undef t0
+#undef t1
+#undef t2
+#undef t3
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+
+#else
+
+#define LOAD lw
+#define LOADL lwl
+#define LOADR lwr
+#define STOREL swl
+#define STORER swr
+#define STORE sw
+#define ADD addu
+#define SUB subu
+#define SRL srl
+#define SLL sll
+#define SRA sra
+#define SLLV sllv
+#define SRLV srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST LOADL
+#define STFIRST STORER
+#define STREST STOREL
+#define SHIFT_DISCARD SLLV
+#else
+#define LDFIRST LOADL
+#define LDREST LOADR
+#define STFIRST STOREL
+#define STREST STORER
+#define SHIFT_DISCARD SRLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit) (FIRST(unit)+NBYTES-1)
+#define UNIT(unit) FIRST(unit)
+
+#define ADDRMASK (NBYTES-1)
+
+ .text
+ .set noreorder
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+ .set noat
+#else
+ .set at=v1
+#endif
+
+/*
+ * A combined memcpy/__copy_user
+ * __copy_user sets len to 0 for success; else to an upper bound of
+ * the number of uncopied bytes.
+ * memcpy sets v0 to dst.
+ */
+ .align 5
+LEAF(__copy_user_inatomic)
+ /*
+ * Note: dst & src may be unaligned, len may be 0
+ * Temps
+ */
+#define rem t8
+
+ /*
+ * The "issue break"s below are very approximate.
+ * Issue delays for dcache fills will perturb the schedule, as will
+ * load queue full replay traps, etc.
+ *
+ * If len < NBYTES use byte operations.
+ */
+ PREF( 0, 0(src) )
+ PREF( 1, 0(dst) )
+ sltu t2, len, NBYTES
+ and t1, dst, ADDRMASK
+ PREF( 0, 1*32(src) )
+ PREF( 1, 1*32(dst) )
+ bnez t2, .Lcopy_bytes_checklen
+ and t0, src, ADDRMASK
+ PREF( 0, 2*32(src) )
+ PREF( 1, 2*32(dst) )
+ bnez t1, .Ldst_unaligned
+ nop
+ bnez t0, .Lsrc_unaligned_dst_aligned
+ /*
+ * use delay slot for fall-through
+ * src and dst are aligned; need to compute rem
+ */
+.Lboth_aligned:
+ SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
+ beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
+ and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
+ PREF( 0, 3*32(src) )
+ PREF( 1, 3*32(dst) )
+ .align 4
+1:
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
+ SUB len, len, 8*NBYTES
+EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
+EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
+ STORE t0, UNIT(0)(dst)
+ STORE t1, UNIT(1)(dst)
+EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
+EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
+ ADD src, src, 8*NBYTES
+ ADD dst, dst, 8*NBYTES
+ STORE t2, UNIT(-6)(dst)
+ STORE t3, UNIT(-5)(dst)
+ STORE t4, UNIT(-4)(dst)
+ STORE t7, UNIT(-3)(dst)
+ STORE t0, UNIT(-2)(dst)
+ STORE t1, UNIT(-1)(dst)
+ PREF( 0, 8*32(src) )
+ PREF( 1, 8*32(dst) )
+ bne len, rem, 1b
+ nop
+
+ /*
+ * len == rem == the number of bytes left to copy < 8*NBYTES
+ */
+.Lcleanup_both_aligned:
+ beqz len, .Ldone
+ sltu t0, len, 4*NBYTES
+ bnez t0, .Lless_than_4units
+ and rem, len, (NBYTES-1) # rem = len % NBYTES
+ /*
+ * len >= 4*NBYTES
+ */
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
+ SUB len, len, 4*NBYTES
+ ADD src, src, 4*NBYTES
+ STORE t0, UNIT(0)(dst)
+ STORE t1, UNIT(1)(dst)
+ STORE t2, UNIT(2)(dst)
+ STORE t3, UNIT(3)(dst)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ beqz len, .Ldone
+ .set noreorder
+.Lless_than_4units:
+ /*
+ * rem = len % NBYTES
+ */
+ beq rem, len, .Lcopy_bytes
+ nop
+1:
+EXC( LOAD t0, 0(src), .Ll_exc)
+ ADD src, src, NBYTES
+ SUB len, len, NBYTES
+ STORE t0, 0(dst)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
+ bne rem, len, 1b
+ .set noreorder
+
+ /*
+ * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
+ * A loop would do only a byte at a time with possible branch
+ * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE
+ * because can't assume read-access to dst. Instead, use
+ * STREST dst, which doesn't require read access to dst.
+ *
+ * This code should perform better than a simple loop on modern,
+ * wide-issue mips processors because the code has fewer branches and
+ * more instruction-level parallelism.
+ */
+#define bits t2
+ beqz len, .Ldone
+ ADD t1, dst, len # t1 is just past last byte of dst
+ li bits, 8*NBYTES
+ SLL rem, len, 3 # rem = number of bits to keep
+EXC( LOAD t0, 0(src), .Ll_exc)
+ SUB bits, bits, rem # bits = number of bits to discard
+ SHIFT_DISCARD t0, t0, bits
+ STREST t0, -1(t1)
+ jr ra
+ move len, zero
+.Ldst_unaligned:
+ /*
+ * dst is unaligned
+ * t0 = src & ADDRMASK
+ * t1 = dst & ADDRMASK; T1 > 0
+ * len >= NBYTES
+ *
+ * Copy enough bytes to align dst
+ * Set match = (src and dst have same alignment)
+ */
+#define match rem
+EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
+ ADD t2, zero, NBYTES
+EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
+ SUB t2, t2, t1 # t2 = number of bytes copied
+ xor match, t0, t1
+ STFIRST t3, FIRST(0)(dst)
+ beq len, t2, .Ldone
+ SUB len, len, t2
+ ADD dst, dst, t2
+ beqz match, .Lboth_aligned
+ ADD src, src, t2
+
+.Lsrc_unaligned_dst_aligned:
+ SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
+ PREF( 0, 3*32(src) )
+ beqz t0, .Lcleanup_src_unaligned
+ and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
+ PREF( 1, 3*32(dst) )
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
+ SUB len, len, 4*NBYTES
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
+EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
+EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
+EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
+EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
+ PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
+ ADD src, src, 4*NBYTES
+#ifdef CONFIG_CPU_SB1
+ nop # improves slotting
+#endif
+ STORE t0, UNIT(0)(dst)
+ STORE t1, UNIT(1)(dst)
+ STORE t2, UNIT(2)(dst)
+ STORE t3, UNIT(3)(dst)
+ PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ bne len, rem, 1b
+ .set noreorder
+
+.Lcleanup_src_unaligned:
+ beqz len, .Ldone
+ and rem, len, NBYTES-1 # rem = len % NBYTES
+ beq rem, len, .Lcopy_bytes
+ nop
+1:
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+ ADD src, src, NBYTES
+ SUB len, len, NBYTES
+ STORE t0, 0(dst)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
+ bne len, rem, 1b
+ .set noreorder
+
+.Lcopy_bytes_checklen:
+ beqz len, .Ldone
+ nop
+.Lcopy_bytes:
+ /* 0 < len < NBYTES */
+#define COPY_BYTE(N) \
+EXC( lb t0, N(src), .Ll_exc); \
+ SUB len, len, 1; \
+ beqz len, .Ldone; \
+ sb t0, N(dst)
+
+ COPY_BYTE(0)
+ COPY_BYTE(1)
+#ifdef USE_DOUBLE
+ COPY_BYTE(2)
+ COPY_BYTE(3)
+ COPY_BYTE(4)
+ COPY_BYTE(5)
+#endif
+EXC( lb t0, NBYTES-2(src), .Ll_exc)
+ SUB len, len, 1
+ jr ra
+ sb t0, NBYTES-2(dst)
+.Ldone:
+ jr ra
+ nop
+ END(__copy_user_inatomic)
+
+.Ll_exc_copy:
+ /*
+ * Copy bytes from src until faulting load address (or until a
+ * lb faults)
+ *
+ * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+ * may be more than a byte beyond the last address.
+ * Hence, the lb below may get an exception.
+ *
+ * Assumes src < THREAD_BUADDR($28)
+ */
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0)
+1:
+EXC( lb t1, 0(src), .Ll_exc)
+ ADD src, src, 1
+ sb t1, 0(dst) # can't fault -- we're copy_from_user
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 1
+ bne src, t0, 1b
+ .set noreorder
+.Ll_exc:
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
+ nop
+ SUB len, AT, t0 # len number of uncopied bytes
+ jr ra
+ nop
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
new file mode 100644
index 00000000..56a1f85a
--- /dev/null
+++ b/arch/mips/lib/memcpy.S
@@ -0,0 +1,566 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Unified implementation of memcpy, memmove and the __copy_user backend.
+ *
+ * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Broadcom, Inc.
+ * memcpy/copy_user author: Mark Vandevoorde
+ * Copyright (C) 2007 Maciej W. Rozycki
+ *
+ * Mnemonic names for arguments to memcpy/__copy_user
+ */
+
+/*
+ * Hack to resolve longstanding prefetch issue
+ *
+ * Prefetching may be fatal on some systems if we're prefetching beyond the
+ * end of memory on some systems. It's also a seriously bad idea on non
+ * dma-coherent systems.
+ */
+#ifdef CONFIG_DMA_NONCOHERENT
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+#ifdef CONFIG_MIPS_MALTA
+#undef CONFIG_CPU_HAS_PREFETCH
+#endif
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define dst a0
+#define src a1
+#define len a2
+
+/*
+ * Spec
+ *
+ * memcpy copies len bytes from src to dst and sets v0 to dst.
+ * It assumes that
+ * - src and dst don't overlap
+ * - src is readable
+ * - dst is writable
+ * memcpy uses the standard calling convention
+ *
+ * __copy_user copies up to len bytes from src to dst and sets a2 (len) to
+ * the number of uncopied bytes due to an exception caused by a read or write.
+ * __copy_user assumes that src and dst don't overlap, and that the call is
+ * implementing one of the following:
+ * copy_to_user
+ * - src is readable (no exceptions when reading src)
+ * copy_from_user
+ * - dst is writable (no exceptions when writing dst)
+ * __copy_user uses a non-standard calling convention; see
+ * include/asm-mips/uaccess.h
+ *
+ * When an exception happens on a load, the handler must
+ # ensure that all of the destination buffer is overwritten to prevent
+ * leaking information to user mode programs.
+ */
+
+/*
+ * Implementation
+ */
+
+/*
+ * The exception handler for loads requires that:
+ * 1- AT contain the address of the byte just past the end of the source
+ * of the copy,
+ * 2- src_entry <= src < AT, and
+ * 3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores adjust len (if necessary) and return.
+ * These handlers do not need to overwrite any data.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.
+ */
+
+#define EXC(inst_reg,addr,handler) \
+9: inst_reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+/*
+ * Only on the 64-bit kernel we can made use of 64-bit registers.
+ */
+#ifdef CONFIG_64BIT
+#define USE_DOUBLE
+#endif
+
+#ifdef USE_DOUBLE
+
+#define LOAD ld
+#define LOADL ldl
+#define LOADR ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE sd
+#define ADD daddu
+#define SUB dsubu
+#define SRL dsrl
+#define SRA dsra
+#define SLL dsll
+#define SLLV dsllv
+#define SRLV dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+/*
+ * As we are sharing code base with the mips32 tree (which use the o32 ABI
+ * register definitions). We need to redefine the register definitions from
+ * the n64 ABI register naming to the o32 ABI register naming.
+ */
+#undef t0
+#undef t1
+#undef t2
+#undef t3
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+
+#else
+
+#define LOAD lw
+#define LOADL lwl
+#define LOADR lwr
+#define STOREL swl
+#define STORER swr
+#define STORE sw
+#define ADD addu
+#define SUB subu
+#define SRL srl
+#define SLL sll
+#define SRA sra
+#define SLLV sllv
+#define SRLV srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST LOADL
+#define STFIRST STORER
+#define STREST STOREL
+#define SHIFT_DISCARD SLLV
+#else
+#define LDFIRST LOADL
+#define LDREST LOADR
+#define STFIRST STOREL
+#define STREST STORER
+#define SHIFT_DISCARD SRLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit) (FIRST(unit)+NBYTES-1)
+#define UNIT(unit) FIRST(unit)
+
+#define ADDRMASK (NBYTES-1)
+
+ .text
+ .set noreorder
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+ .set noat
+#else
+ .set at=v1
+#endif
+
+/*
+ * A combined memcpy/__copy_user
+ * __copy_user sets len to 0 for success; else to an upper bound of
+ * the number of uncopied bytes.
+ * memcpy sets v0 to dst.
+ */
+ .align 5
+LEAF(memcpy) /* a0=dst a1=src a2=len */
+ move v0, dst /* return value */
+.L__memcpy:
+FEXPORT(__copy_user)
+ /*
+ * Note: dst & src may be unaligned, len may be 0
+ * Temps
+ */
+#define rem t8
+
+ R10KCBARRIER(0(ra))
+ /*
+ * The "issue break"s below are very approximate.
+ * Issue delays for dcache fills will perturb the schedule, as will
+ * load queue full replay traps, etc.
+ *
+ * If len < NBYTES use byte operations.
+ */
+ PREF( 0, 0(src) )
+ PREF( 1, 0(dst) )
+ sltu t2, len, NBYTES
+ and t1, dst, ADDRMASK
+ PREF( 0, 1*32(src) )
+ PREF( 1, 1*32(dst) )
+ bnez t2, .Lcopy_bytes_checklen
+ and t0, src, ADDRMASK
+ PREF( 0, 2*32(src) )
+ PREF( 1, 2*32(dst) )
+ bnez t1, .Ldst_unaligned
+ nop
+ bnez t0, .Lsrc_unaligned_dst_aligned
+ /*
+ * use delay slot for fall-through
+ * src and dst are aligned; need to compute rem
+ */
+.Lboth_aligned:
+ SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
+ beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
+ and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
+ PREF( 0, 3*32(src) )
+ PREF( 1, 3*32(dst) )
+ .align 4
+1:
+ R10KCBARRIER(0(ra))
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
+ SUB len, len, 8*NBYTES
+EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
+EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p8u)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p7u)
+EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
+EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
+ ADD src, src, 8*NBYTES
+ ADD dst, dst, 8*NBYTES
+EXC( STORE t2, UNIT(-6)(dst), .Ls_exc_p6u)
+EXC( STORE t3, UNIT(-5)(dst), .Ls_exc_p5u)
+EXC( STORE t4, UNIT(-4)(dst), .Ls_exc_p4u)
+EXC( STORE t7, UNIT(-3)(dst), .Ls_exc_p3u)
+EXC( STORE t0, UNIT(-2)(dst), .Ls_exc_p2u)
+EXC( STORE t1, UNIT(-1)(dst), .Ls_exc_p1u)
+ PREF( 0, 8*32(src) )
+ PREF( 1, 8*32(dst) )
+ bne len, rem, 1b
+ nop
+
+ /*
+ * len == rem == the number of bytes left to copy < 8*NBYTES
+ */
+.Lcleanup_both_aligned:
+ beqz len, .Ldone
+ sltu t0, len, 4*NBYTES
+ bnez t0, .Lless_than_4units
+ and rem, len, (NBYTES-1) # rem = len % NBYTES
+ /*
+ * len >= 4*NBYTES
+ */
+EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
+EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
+ SUB len, len, 4*NBYTES
+ ADD src, src, 4*NBYTES
+ R10KCBARRIER(0(ra))
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p4u)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p3u)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc_p2u)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc_p1u)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ beqz len, .Ldone
+ .set noreorder
+.Lless_than_4units:
+ /*
+ * rem = len % NBYTES
+ */
+ beq rem, len, .Lcopy_bytes
+ nop
+1:
+ R10KCBARRIER(0(ra))
+EXC( LOAD t0, 0(src), .Ll_exc)
+ ADD src, src, NBYTES
+ SUB len, len, NBYTES
+EXC( STORE t0, 0(dst), .Ls_exc_p1u)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
+ bne rem, len, 1b
+ .set noreorder
+
+ /*
+ * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
+ * A loop would do only a byte at a time with possible branch
+ * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE
+ * because can't assume read-access to dst. Instead, use
+ * STREST dst, which doesn't require read access to dst.
+ *
+ * This code should perform better than a simple loop on modern,
+ * wide-issue mips processors because the code has fewer branches and
+ * more instruction-level parallelism.
+ */
+#define bits t2
+ beqz len, .Ldone
+ ADD t1, dst, len # t1 is just past last byte of dst
+ li bits, 8*NBYTES
+ SLL rem, len, 3 # rem = number of bits to keep
+EXC( LOAD t0, 0(src), .Ll_exc)
+ SUB bits, bits, rem # bits = number of bits to discard
+ SHIFT_DISCARD t0, t0, bits
+EXC( STREST t0, -1(t1), .Ls_exc)
+ jr ra
+ move len, zero
+.Ldst_unaligned:
+ /*
+ * dst is unaligned
+ * t0 = src & ADDRMASK
+ * t1 = dst & ADDRMASK; T1 > 0
+ * len >= NBYTES
+ *
+ * Copy enough bytes to align dst
+ * Set match = (src and dst have same alignment)
+ */
+#define match rem
+EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
+ ADD t2, zero, NBYTES
+EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
+ SUB t2, t2, t1 # t2 = number of bytes copied
+ xor match, t0, t1
+ R10KCBARRIER(0(ra))
+EXC( STFIRST t3, FIRST(0)(dst), .Ls_exc)
+ beq len, t2, .Ldone
+ SUB len, len, t2
+ ADD dst, dst, t2
+ beqz match, .Lboth_aligned
+ ADD src, src, t2
+
+.Lsrc_unaligned_dst_aligned:
+ SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
+ PREF( 0, 3*32(src) )
+ beqz t0, .Lcleanup_src_unaligned
+ and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
+ PREF( 1, 3*32(dst) )
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+ R10KCBARRIER(0(ra))
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
+ SUB len, len, 4*NBYTES
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
+EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
+EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
+EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
+EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
+ PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
+ ADD src, src, 4*NBYTES
+#ifdef CONFIG_CPU_SB1
+ nop # improves slotting
+#endif
+EXC( STORE t0, UNIT(0)(dst), .Ls_exc_p4u)
+EXC( STORE t1, UNIT(1)(dst), .Ls_exc_p3u)
+EXC( STORE t2, UNIT(2)(dst), .Ls_exc_p2u)
+EXC( STORE t3, UNIT(3)(dst), .Ls_exc_p1u)
+ PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 4*NBYTES
+ bne len, rem, 1b
+ .set noreorder
+
+.Lcleanup_src_unaligned:
+ beqz len, .Ldone
+ and rem, len, NBYTES-1 # rem = len % NBYTES
+ beq rem, len, .Lcopy_bytes
+ nop
+1:
+ R10KCBARRIER(0(ra))
+EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
+EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
+ ADD src, src, NBYTES
+ SUB len, len, NBYTES
+EXC( STORE t0, 0(dst), .Ls_exc_p1u)
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, NBYTES
+ bne len, rem, 1b
+ .set noreorder
+
+.Lcopy_bytes_checklen:
+ beqz len, .Ldone
+ nop
+.Lcopy_bytes:
+ /* 0 < len < NBYTES */
+ R10KCBARRIER(0(ra))
+#define COPY_BYTE(N) \
+EXC( lb t0, N(src), .Ll_exc); \
+ SUB len, len, 1; \
+ beqz len, .Ldone; \
+EXC( sb t0, N(dst), .Ls_exc_p1)
+
+ COPY_BYTE(0)
+ COPY_BYTE(1)
+#ifdef USE_DOUBLE
+ COPY_BYTE(2)
+ COPY_BYTE(3)
+ COPY_BYTE(4)
+ COPY_BYTE(5)
+#endif
+EXC( lb t0, NBYTES-2(src), .Ll_exc)
+ SUB len, len, 1
+ jr ra
+EXC( sb t0, NBYTES-2(dst), .Ls_exc_p1)
+.Ldone:
+ jr ra
+ nop
+ END(memcpy)
+
+.Ll_exc_copy:
+ /*
+ * Copy bytes from src until faulting load address (or until a
+ * lb faults)
+ *
+ * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+ * may be more than a byte beyond the last address.
+ * Hence, the lb below may get an exception.
+ *
+ * Assumes src < THREAD_BUADDR($28)
+ */
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0)
+1:
+EXC( lb t1, 0(src), .Ll_exc)
+ ADD src, src, 1
+ sb t1, 0(dst) # can't fault -- we're copy_from_user
+ .set reorder /* DADDI_WAR */
+ ADD dst, dst, 1
+ bne src, t0, 1b
+ .set noreorder
+.Ll_exc:
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
+ nop
+ SUB len, AT, t0 # len number of uncopied bytes
+ /*
+ * Here's where we rely on src and dst being incremented in tandem,
+ * See (3) above.
+ * dst += (fault addr - src) to put dst at first byte to clear
+ */
+ ADD dst, t0 # compute start address in a1
+ SUB dst, src
+ /*
+ * Clear len bytes starting at dst. Can't call __bzero because it
+ * might modify len. An inefficient loop for these rare times...
+ */
+ .set reorder /* DADDI_WAR */
+ SUB src, len, 1
+ beqz len, .Ldone
+ .set noreorder
+1: sb zero, 0(dst)
+ ADD dst, dst, 1
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+ bnez src, 1b
+ SUB src, src, 1
+#else
+ .set push
+ .set noat
+ li v1, 1
+ bnez src, 1b
+ SUB src, src, v1
+ .set pop
+#endif
+ jr ra
+ nop
+
+
+#define SEXC(n) \
+ .set reorder; /* DADDI_WAR */ \
+.Ls_exc_p ## n ## u: \
+ ADD len, len, n*NBYTES; \
+ jr ra; \
+ .set noreorder
+
+SEXC(8)
+SEXC(7)
+SEXC(6)
+SEXC(5)
+SEXC(4)
+SEXC(3)
+SEXC(2)
+SEXC(1)
+
+.Ls_exc_p1:
+ .set reorder /* DADDI_WAR */
+ ADD len, len, 1
+ jr ra
+ .set noreorder
+.Ls_exc:
+ jr ra
+ nop
+
+ .align 5
+LEAF(memmove)
+ ADD t0, a0, a2
+ ADD t1, a1, a2
+ sltu t0, a1, t0 # dst + len <= src -> memcpy
+ sltu t1, a0, t1 # dst >= src + len -> memcpy
+ and t0, t1
+ beqz t0, .L__memcpy
+ move v0, a0 /* return value */
+ beqz a2, .Lr_out
+ END(memmove)
+
+ /* fall through to __rmemcpy */
+LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
+ sltu t0, a1, a0
+ beqz t0, .Lr_end_bytes_up # src >= dst
+ nop
+ ADD a0, a2 # dst = dst + len
+ ADD a1, a2 # src = src + len
+
+.Lr_end_bytes:
+ R10KCBARRIER(0(ra))
+ lb t0, -1(a1)
+ SUB a2, a2, 0x1
+ sb t0, -1(a0)
+ SUB a1, a1, 0x1
+ .set reorder /* DADDI_WAR */
+ SUB a0, a0, 0x1
+ bnez a2, .Lr_end_bytes
+ .set noreorder
+
+.Lr_out:
+ jr ra
+ move a2, zero
+
+.Lr_end_bytes_up:
+ R10KCBARRIER(0(ra))
+ lb t0, (a1)
+ SUB a2, a2, 0x1
+ sb t0, (a0)
+ ADD a1, a1, 0x1
+ .set reorder /* DADDI_WAR */
+ ADD a0, a0, 0x1
+ bnez a2, .Lr_end_bytes_up
+ .set noreorder
+
+ jr ra
+ move a2, zero
+ END(__rmemcpy)
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
new file mode 100644
index 00000000..606c8a9e
--- /dev/null
+++ b/arch/mips/lib/memset.S
@@ -0,0 +1,180 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1998, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 2007 Maciej W. Rozycki
+ */
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#if LONGSIZE == 4
+#define LONG_S_L swl
+#define LONG_S_R swr
+#else
+#define LONG_S_L sdl
+#define LONG_S_R sdr
+#endif
+
+#define EX(insn,reg,addr,handler) \
+9: insn reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+ .macro f_fill64 dst, offset, val, fixup
+ EX(LONG_S, \val, (\offset + 0 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 1 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 2 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 3 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 4 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 5 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 6 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 7 * LONGSIZE)(\dst), \fixup)
+#if LONGSIZE == 4
+ EX(LONG_S, \val, (\offset + 8 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 9 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 10 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 11 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 12 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 13 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 14 * LONGSIZE)(\dst), \fixup)
+ EX(LONG_S, \val, (\offset + 15 * LONGSIZE)(\dst), \fixup)
+#endif
+ .endm
+
+/*
+ * memset(void *s, int c, size_t n)
+ *
+ * a0: start of area to clear
+ * a1: char to fill with
+ * a2: size of area to clear
+ */
+ .set noreorder
+ .align 5
+LEAF(memset)
+ beqz a1, 1f
+ move v0, a0 /* result */
+
+ andi a1, 0xff /* spread fillword */
+ LONG_SLL t1, a1, 8
+ or a1, t1
+ LONG_SLL t1, a1, 16
+#if LONGSIZE == 8
+ or a1, t1
+ LONG_SLL t1, a1, 32
+#endif
+ or a1, t1
+1:
+
+FEXPORT(__bzero)
+ sltiu t0, a2, LONGSIZE /* very small region? */
+ bnez t0, .Lsmall_memset
+ andi t0, a0, LONGMASK /* aligned? */
+
+#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
+ beqz t0, 1f
+ PTR_SUBU t0, LONGSIZE /* alignment in bytes */
+#else
+ .set noat
+ li AT, LONGSIZE
+ beqz t0, 1f
+ PTR_SUBU t0, AT /* alignment in bytes */
+ .set at
+#endif
+
+ R10KCBARRIER(0(ra))
+#ifdef __MIPSEB__
+ EX(LONG_S_L, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
+#endif
+#ifdef __MIPSEL__
+ EX(LONG_S_R, a1, (a0), .Lfirst_fixup) /* make word/dword aligned */
+#endif
+ PTR_SUBU a0, t0 /* long align ptr */
+ PTR_ADDU a2, t0 /* correct size */
+
+1: ori t1, a2, 0x3f /* # of full blocks */
+ xori t1, 0x3f
+ beqz t1, .Lmemset_partial /* no block to fill */
+ andi t0, a2, 0x40-LONGSIZE
+
+ PTR_ADDU t1, a0 /* end address */
+ .set reorder
+1: PTR_ADDIU a0, 64
+ R10KCBARRIER(0(ra))
+ f_fill64 a0, -64, a1, .Lfwd_fixup
+ bne t1, a0, 1b
+ .set noreorder
+
+.Lmemset_partial:
+ R10KCBARRIER(0(ra))
+ PTR_LA t1, 2f /* where to start */
+#if LONGSIZE == 4
+ PTR_SUBU t1, t0
+#else
+ .set noat
+ LONG_SRL AT, t0, 1
+ PTR_SUBU t1, AT
+ .set at
+#endif
+ jr t1
+ PTR_ADDU a0, t0 /* dest ptr */
+
+ .set push
+ .set noreorder
+ .set nomacro
+ f_fill64 a0, -64, a1, .Lpartial_fixup /* ... but first do longs ... */
+2: .set pop
+ andi a2, LONGMASK /* At most one long to go */
+
+ beqz a2, 1f
+ PTR_ADDU a0, a2 /* What's left */
+ R10KCBARRIER(0(ra))
+#ifdef __MIPSEB__
+ EX(LONG_S_R, a1, -1(a0), .Llast_fixup)
+#endif
+#ifdef __MIPSEL__
+ EX(LONG_S_L, a1, -1(a0), .Llast_fixup)
+#endif
+1: jr ra
+ move a2, zero
+
+.Lsmall_memset:
+ beqz a2, 2f
+ PTR_ADDU t1, a0, a2
+
+1: PTR_ADDIU a0, 1 /* fill bytewise */
+ R10KCBARRIER(0(ra))
+ bne t1, a0, 1b
+ sb a1, -1(a0)
+
+2: jr ra /* done */
+ move a2, zero
+ END(memset)
+
+.Lfirst_fixup:
+ jr ra
+ nop
+
+.Lfwd_fixup:
+ PTR_L t0, TI_TASK($28)
+ andi a2, 0x3f
+ LONG_L t0, THREAD_BUADDR(t0)
+ LONG_ADDU a2, t1
+ jr ra
+ LONG_SUBU a2, t0
+
+.Lpartial_fixup:
+ PTR_L t0, TI_TASK($28)
+ andi a2, LONGMASK
+ LONG_L t0, THREAD_BUADDR(t0)
+ LONG_ADDU a2, t1
+ jr ra
+ LONG_SUBU a2, t0
+
+.Llast_fixup:
+ jr ra
+ andi v1, a2, LONGMASK
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
new file mode 100644
index 00000000..9cee9079
--- /dev/null
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -0,0 +1,63 @@
+/*
+ * Dump R3000 TLB for debugging purposes.
+ *
+ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ * Copyright (C) 1999 by Harald Koerfgen
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbdebug.h>
+
+extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */
+
+static void dump_tlb(int first, int last)
+{
+ int i;
+ unsigned int asid;
+ unsigned long entryhi, entrylo0;
+
+ asid = read_c0_entryhi() & 0xfc0;
+
+ for (i = first; i <= last; i++) {
+ write_c0_index(i<<8);
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ "tlbr\n\t"
+ "nop\n\t"
+ ".set\treorder");
+ entryhi = read_c0_entryhi();
+ entrylo0 = read_c0_entrylo0();
+
+ /* Unused entries have a virtual address of KSEG0. */
+ if ((entryhi & 0xffffe000) != 0x80000000
+ && (entryhi & 0xfc0) == asid) {
+ /*
+ * Only print entries in use
+ */
+ printk("Index: %2d ", i);
+
+ printk("va=%08lx asid=%08lx"
+ " [pa=%06lx n=%d d=%d v=%d g=%d]",
+ (entryhi & 0xffffe000),
+ entryhi & 0xfc0,
+ entrylo0 & PAGE_MASK,
+ (entrylo0 & (1 << 11)) ? 1 : 0,
+ (entrylo0 & (1 << 10)) ? 1 : 0,
+ (entrylo0 & (1 << 9)) ? 1 : 0,
+ (entrylo0 & (1 << 8)) ? 1 : 0);
+ }
+ }
+ printk("\n");
+
+ write_c0_entryhi(asid);
+}
+
+void dump_tlb_all(void)
+{
+ dump_tlb(0, current_cpu_data.tlbsize - 1);
+}
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
new file mode 100644
index 00000000..fdbb970f
--- /dev/null
+++ b/arch/mips/lib/strlen_user.S
@@ -0,0 +1,39 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1996, 1998, 1999, 2004 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler) \
+9: insn reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+LEAF(__strlen_user_asm)
+ LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
+ and v0, a0
+ bnez v0, .Lfault
+
+FEXPORT(__strlen_user_nocheck_asm)
+ move v0, a0
+1: EX(lb, t0, (v0), .Lfault)
+ PTR_ADDIU v0, 1
+ bnez t0, 1b
+ PTR_SUBU v0, a0
+ jr ra
+ END(__strlen_user_asm)
+
+.Lfault: move v0, zero
+ jr ra
diff --git a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S
new file mode 100644
index 00000000..7201b2ff
--- /dev/null
+++ b/arch/mips/lib/strncpy_user.S
@@ -0,0 +1,59 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1996, 1999 by Ralf Baechle
+ */
+#include <linux/errno.h>
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler) \
+9: insn reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+/*
+ * Returns: -EFAULT if exception before terminator, N if the entire
+ * buffer filled, else strlen.
+ */
+
+/*
+ * Ugly special case have to check: we might get passed a user space
+ * pointer which wraps into the kernel space. We don't deal with that. If
+ * it happens at most some bytes of the exceptions handlers will be copied.
+ */
+
+LEAF(__strncpy_from_user_asm)
+ LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
+ and v0, a1
+ bnez v0, .Lfault
+
+FEXPORT(__strncpy_from_user_nocheck_asm)
+ move v0, zero
+ move v1, a1
+ .set noreorder
+1: EX(lbu, t0, (v1), .Lfault)
+ PTR_ADDIU v1, 1
+ R10KCBARRIER(0(ra))
+ beqz t0, 2f
+ sb t0, (a0)
+ PTR_ADDIU v0, 1
+ .set reorder
+ PTR_ADDIU a0, 1
+ bne v0, a2, 1b
+2: PTR_ADDU t0, a1, v0
+ xor t0, a1
+ bltz t0, .Lfault
+ jr ra # return n
+ END(__strncpy_from_user_asm)
+
+.Lfault: li v0, -EFAULT
+ jr ra
+
+ .section __ex_table,"a"
+ PTR 1b, .Lfault
+ .previous
diff --git a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S
new file mode 100644
index 00000000..64457162
--- /dev/null
+++ b/arch/mips/lib/strnlen_user.S
@@ -0,0 +1,46 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1996, 1998, 1999, 2004 by Ralf Baechle
+ * Copyright (c) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define EX(insn,reg,addr,handler) \
+9: insn reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+/*
+ * Return the size of a string including the ending NUL character up to a
+ * maximum of a1 or 0 in case of error.
+ *
+ * Note: for performance reasons we deliberately accept that a user may
+ * make strlen_user and strnlen_user access the first few KSEG0
+ * bytes. There's nothing secret there. On 64-bit accessing beyond
+ * the maximum is a tad hairier ...
+ */
+LEAF(__strnlen_user_asm)
+ LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
+ and v0, a0
+ bnez v0, .Lfault
+
+FEXPORT(__strnlen_user_nocheck_asm)
+ move v0, a0
+ PTR_ADDU a1, a0 # stop pointer
+1: beq v0, a1, 1f # limit reached?
+ EX(lb, t0, (v0), .Lfault)
+ PTR_ADDU v0, 1
+ bnez t0, 1b
+1: PTR_SUBU v0, a0
+ jr ra
+ END(__strnlen_user_asm)
+
+.Lfault:
+ move v0, zero
+ jr ra
diff --git a/arch/mips/lib/ucmpdi2.c b/arch/mips/lib/ucmpdi2.c
new file mode 100644
index 00000000..bb4cb2f8
--- /dev/null
+++ b/arch/mips/lib/ucmpdi2.c
@@ -0,0 +1,21 @@
+#include <linux/module.h>
+
+#include "libgcc.h"
+
+word_type __ucmpdi2(unsigned long long a, unsigned long long b)
+{
+ const DWunion au = {.ll = a};
+ const DWunion bu = {.ll = b};
+
+ if ((unsigned int) au.s.high < (unsigned int) bu.s.high)
+ return 0;
+ else if ((unsigned int) au.s.high > (unsigned int) bu.s.high)
+ return 2;
+ if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
+ return 0;
+ else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
+ return 2;
+ return 1;
+}
+
+EXPORT_SYMBOL(__ucmpdi2);
diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c
new file mode 100644
index 00000000..a6d1c770
--- /dev/null
+++ b/arch/mips/lib/uncached.c
@@ -0,0 +1,81 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Thiemo Seufer
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ */
+
+#include <linux/init.h>
+
+#include <asm/addrspace.h>
+#include <asm/bug.h>
+#include <asm/cacheflush.h>
+
+#ifndef CKSEG2
+#define CKSEG2 CKSSEG
+#endif
+#ifndef TO_PHYS_MASK
+#define TO_PHYS_MASK -1
+#endif
+
+/*
+ * FUNC is executed in one of the uncached segments, depending on its
+ * original address as follows:
+ *
+ * 1. If the original address is in CKSEG0 or CKSEG1, then the uncached
+ * segment used is CKSEG1.
+ * 2. If the original address is in XKPHYS, then the uncached segment
+ * used is XKPHYS(2).
+ * 3. Otherwise it's a bug.
+ *
+ * The same remapping is done with the stack pointer. Stack handling
+ * works because we don't handle stack arguments or more complex return
+ * values, so we can avoid sharing the same stack area between a cached
+ * and the uncached mode.
+ */
+unsigned long __cpuinit run_uncached(void *func)
+{
+ register long sp __asm__("$sp");
+ register long ret __asm__("$2");
+ long lfunc = (long)func, ufunc;
+ long usp;
+
+ if (sp >= (long)CKSEG0 && sp < (long)CKSEG2)
+ usp = CKSEG1ADDR(sp);
+#ifdef CONFIG_64BIT
+ else if ((long long)sp >= (long long)PHYS_TO_XKPHYS(0, 0) &&
+ (long long)sp < (long long)PHYS_TO_XKPHYS(8, 0))
+ usp = PHYS_TO_XKPHYS(K_CALG_UNCACHED,
+ XKPHYS_TO_PHYS((long long)sp));
+#endif
+ else {
+ BUG();
+ usp = sp;
+ }
+ if (lfunc >= (long)CKSEG0 && lfunc < (long)CKSEG2)
+ ufunc = CKSEG1ADDR(lfunc);
+#ifdef CONFIG_64BIT
+ else if ((long long)lfunc >= (long long)PHYS_TO_XKPHYS(0, 0) &&
+ (long long)lfunc < (long long)PHYS_TO_XKPHYS(8, 0))
+ ufunc = PHYS_TO_XKPHYS(K_CALG_UNCACHED,
+ XKPHYS_TO_PHYS((long long)lfunc));
+#endif
+ else {
+ BUG();
+ ufunc = lfunc;
+ }
+
+ __asm__ __volatile__ (
+ " move $16, $sp\n"
+ " move $sp, %1\n"
+ " jalr %2\n"
+ " move $sp, $16"
+ : "=r" (ret)
+ : "r" (usp), "r" (ufunc)
+ : "$16", "$31");
+
+ return ret;
+}
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
new file mode 100644
index 00000000..aca93eed
--- /dev/null
+++ b/arch/mips/loongson/Kconfig
@@ -0,0 +1,92 @@
+if MACH_LOONGSON
+
+choice
+ prompt "Machine Type"
+
+config LEMOTE_FULOONG2E
+ bool "Lemote Fuloong(2e) mini-PC"
+ select ARCH_SPARSEMEM_ENABLE
+ select CEVT_R4K
+ select CSRC_R4K
+ select SYS_HAS_CPU_LOONGSON2E
+ select DMA_NONCOHERENT
+ select BOOT_ELF32
+ select BOARD_SCACHE
+ select HW_HAS_PCI
+ select I8259
+ select ISA
+ select IRQ_CPU
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_HAS_EARLY_PRINTK
+ select GENERIC_ISA_DMA_SUPPORT_BROKEN
+ select CPU_HAS_WB
+ select LOONGSON_MC146818
+ help
+ Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
+ an FPGA northbridge
+
+ Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
+
+config LEMOTE_MACH2F
+ bool "Lemote Loongson 2F family machines"
+ select ARCH_SPARSEMEM_ENABLE
+ select BOARD_SCACHE
+ select BOOT_ELF32
+ select CEVT_R4K if ! MIPS_EXTERNAL_TIMER
+ select CPU_HAS_WB
+ select CS5536
+ select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
+ select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA_SUPPORT_BROKEN
+ select HW_HAS_PCI
+ select I8259
+ select IRQ_CPU
+ select ISA
+ select SYS_HAS_CPU_LOONGSON2F
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select LOONGSON_MC146818
+ help
+ Lemote Loongson 2F family machines utilize the 2F revision of
+ Loongson processor and the AMD CS5536 south bridge.
+
+ These family machines include fuloong2f mini PC, yeeloong2f notebook,
+ LingLoong allinone PC and so forth.
+endchoice
+
+config CS5536
+ bool
+
+config CS5536_MFGPT
+ bool "CS5536 MFGPT Timer"
+ depends on CS5536
+ select MIPS_EXTERNAL_TIMER
+ help
+ This option enables the mfgpt0 timer of AMD CS5536.
+
+ If you want to enable the Loongson2 CPUFreq Driver, Please enable
+ this option at first, otherwise, You will get wrong system time.
+
+ If unsure, say Yes.
+
+config LOONGSON_SUSPEND
+ bool
+ default y
+ depends on CPU_SUPPORTS_CPUFREQ && SUSPEND
+
+config LOONGSON_UART_BASE
+ bool
+ default y
+ depends on EARLY_PRINTK || SERIAL_8250
+
+config LOONGSON_MC146818
+ bool
+ default n
+
+endif # MACH_LOONGSON
diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile
new file mode 100644
index 00000000..2b76cb0f
--- /dev/null
+++ b/arch/mips/loongson/Makefile
@@ -0,0 +1,17 @@
+#
+# Common code for all Loongson based systems
+#
+
+obj-$(CONFIG_MACH_LOONGSON) += common/
+
+#
+# Lemote Fuloong mini-PC (Loongson 2E-based)
+#
+
+obj-$(CONFIG_LEMOTE_FULOONG2E) += fuloong-2e/
+
+#
+# Lemote loongson2f family machines
+#
+
+obj-$(CONFIG_LEMOTE_MACH2F) += lemote-2f/
diff --git a/arch/mips/loongson/Platform b/arch/mips/loongson/Platform
new file mode 100644
index 00000000..29692e54
--- /dev/null
+++ b/arch/mips/loongson/Platform
@@ -0,0 +1,32 @@
+#
+# Loongson Processors' Support
+#
+
+# Only gcc >= 4.4 have Loongson specific support
+cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2E) += \
+ $(call cc-option,-march=loongson2e,-march=r4600)
+cflags-$(CONFIG_CPU_LOONGSON2F) += \
+ $(call cc-option,-march=loongson2f,-march=r4600)
+# Enable the workarounds for Loongson2f
+ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
+ ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
+ $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
+ else
+ cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
+ endif
+ ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
+ $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
+ else
+ cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
+ endif
+endif
+
+#
+# Loongson Machines' Support
+#
+
+platform-$(CONFIG_MACH_LOONGSON) += loongson/
+cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely
+load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
+load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile
new file mode 100644
index 00000000..e526488d
--- /dev/null
+++ b/arch/mips/loongson/common/Makefile
@@ -0,0 +1,27 @@
+#
+# Makefile for loongson based machines.
+#
+
+obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
+ pci.o bonito-irq.o mem.o machtype.o platform.o
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+
+#
+# Serial port support
+#
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_SERIAL_8250) += serial.o
+obj-$(CONFIG_LOONGSON_UART_BASE) += uart_base.o
+obj-$(CONFIG_LOONGSON_MC146818) += rtc.o
+
+#
+# Enable CS5536 Virtual Support Module(VSM) to virtulize the PCI configure
+# space
+#
+obj-$(CONFIG_CS5536) += cs5536/
+
+#
+# Suspend Support
+#
+
+obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c
new file mode 100644
index 00000000..f27d7ccc
--- /dev/null
+++ b/arch/mips/loongson/common/bonito-irq.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/compiler.h>
+
+#include <loongson.h>
+
+static inline void bonito_irq_enable(struct irq_data *d)
+{
+ LOONGSON_INTENSET = (1 << (d->irq - LOONGSON_IRQ_BASE));
+ mmiowb();
+}
+
+static inline void bonito_irq_disable(struct irq_data *d)
+{
+ LOONGSON_INTENCLR = (1 << (d->irq - LOONGSON_IRQ_BASE));
+ mmiowb();
+}
+
+static struct irq_chip bonito_irq_type = {
+ .name = "bonito_irq",
+ .irq_mask = bonito_irq_disable,
+ .irq_unmask = bonito_irq_enable,
+};
+
+static struct irqaction __maybe_unused dma_timeout_irqaction = {
+ .handler = no_action,
+ .name = "dma_timeout",
+};
+
+void bonito_irq_init(void)
+{
+ u32 i;
+
+ for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++)
+ irq_set_chip_and_handler(i, &bonito_irq_type,
+ handle_level_irq);
+
+#ifdef CONFIG_CPU_LOONGSON2E
+ setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction);
+#endif
+}
diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c
new file mode 100644
index 00000000..353e1d2e
--- /dev/null
+++ b/arch/mips/loongson/common/cmdline.c
@@ -0,0 +1,48 @@
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+void __init prom_init_cmdline(void)
+{
+ int prom_argc;
+ /* pmon passes arguments in 32bit pointers */
+ int *_prom_argv;
+ int i;
+ long l;
+
+ /* firmware arguments are initialized in head.S */
+ prom_argc = fw_arg0;
+ _prom_argv = (int *)fw_arg1;
+
+ /* arg[0] is "g", the rest is boot parameters */
+ arcs_cmdline[0] = '\0';
+ for (i = 1; i < prom_argc; i++) {
+ l = (long)_prom_argv[i];
+ if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
+ >= sizeof(arcs_cmdline))
+ break;
+ strcat(arcs_cmdline, ((char *)l));
+ strcat(arcs_cmdline, " ");
+ }
+
+ prom_init_machtype();
+}
diff --git a/arch/mips/loongson/common/cs5536/Makefile b/arch/mips/loongson/common/cs5536/Makefile
new file mode 100644
index 00000000..f12e6400
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for CS5536 support.
+#
+
+obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \
+ cs5536_isa.o cs5536_ehci.o
+
+#
+# Enable cs5536 mfgpt Timer
+#
+obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o
diff --git a/arch/mips/loongson/common/cs5536/cs5536_acc.c b/arch/mips/loongson/common/cs5536/cs5536_acc.c
new file mode 100644
index 00000000..b3fd5eab
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_acc.c
@@ -0,0 +1,140 @@
+/*
+ * the ACC Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+void pci_acc_write_reg(int reg, u32 value)
+{
+ u32 hi = 0, lo = value;
+
+ switch (reg) {
+ case PCI_COMMAND:
+ _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+ if (value & PCI_COMMAND_MASTER)
+ lo |= (0x03 << 8);
+ else
+ lo &= ~(0x03 << 8);
+ _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
+ break;
+ case PCI_STATUS:
+ if (value & PCI_STATUS_PARITY) {
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_PARE_ERR_FLAG) {
+ lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+ }
+ }
+ break;
+ case PCI_BAR0_REG:
+ if (value == PCI_BAR_RANGE_MASK) {
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ lo |= SOFT_BAR_ACC_FLAG;
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else if (value & 0x01) {
+ value &= 0xfffffffc;
+ hi = 0xA0000000 | ((value & 0x000ff000) >> 12);
+ lo = 0x000fff80 | ((value & 0x00000fff) << 20);
+ _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM1), hi, lo);
+ }
+ break;
+ case PCI_ACC_INT_REG:
+ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+ /* disable all the usb interrupt in PIC */
+ lo &= ~(0xf << PIC_YSEL_LOW_ACC_SHIFT);
+ if (value) /* enable all the acc interrupt in PIC */
+ lo |= (CS5536_ACC_INTR << PIC_YSEL_LOW_ACC_SHIFT);
+ _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+ break;
+ default:
+ break;
+ }
+}
+
+u32 pci_acc_read_reg(int reg)
+{
+ u32 hi, lo;
+ u32 conf_data = 0;
+
+ switch (reg) {
+ case PCI_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID);
+ break;
+ case PCI_COMMAND:
+ _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
+ if (((lo & 0xfff00000) || (hi & 0x000000ff))
+ && ((hi & 0xf0000000) == 0xa0000000))
+ conf_data |= PCI_COMMAND_IO;
+ _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+ if ((lo & 0x300) == 0x300)
+ conf_data |= PCI_COMMAND_MASTER;
+ break;
+ case PCI_STATUS:
+ conf_data |= PCI_STATUS_66MHZ;
+ conf_data |= PCI_STATUS_FAST_BACK;
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_PARE_ERR_FLAG)
+ conf_data |= PCI_STATUS_PARITY;
+ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+ break;
+ case PCI_CLASS_REVISION:
+ _rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);
+ conf_data = lo & 0x000000ff;
+ conf_data |= (CS5536_ACC_CLASS_CODE << 8);
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ conf_data =
+ CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
+ PCI_NORMAL_LATENCY_TIMER);
+ break;
+ case PCI_BAR0_REG:
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ if (lo & SOFT_BAR_ACC_FLAG) {
+ conf_data = CS5536_ACC_RANGE |
+ PCI_BASE_ADDRESS_SPACE_IO;
+ lo &= ~SOFT_BAR_ACC_FLAG;
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else {
+ _rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);
+ conf_data = (hi & 0x000000ff) << 12;
+ conf_data |= (lo & 0xfff00000) >> 20;
+ conf_data |= 0x01;
+ conf_data &= ~0x02;
+ }
+ break;
+ case PCI_CARDBUS_CIS:
+ conf_data = PCI_CARDBUS_CIS_POINTER;
+ break;
+ case PCI_SUBSYSTEM_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID);
+ break;
+ case PCI_ROM_ADDRESS:
+ conf_data = PCI_EXPANSION_ROM_BAR;
+ break;
+ case PCI_CAPABILITY_LIST:
+ conf_data = PCI_CAPLIST_USB_POINTER;
+ break;
+ case PCI_INTERRUPT_LINE:
+ conf_data =
+ CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);
+ break;
+ default:
+ break;
+ }
+
+ return conf_data;
+}
diff --git a/arch/mips/loongson/common/cs5536/cs5536_ehci.c b/arch/mips/loongson/common/cs5536/cs5536_ehci.c
new file mode 100644
index 00000000..5b5cbba6
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_ehci.c
@@ -0,0 +1,160 @@
+/*
+ * the EHCI Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+void pci_ehci_write_reg(int reg, u32 value)
+{
+ u32 hi = 0, lo = value;
+
+ switch (reg) {
+ case PCI_COMMAND:
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ if (value & PCI_COMMAND_MASTER)
+ hi |= PCI_COMMAND_MASTER;
+ else
+ hi &= ~PCI_COMMAND_MASTER;
+
+ if (value & PCI_COMMAND_MEMORY)
+ hi |= PCI_COMMAND_MEMORY;
+ else
+ hi &= ~PCI_COMMAND_MEMORY;
+ _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+ break;
+ case PCI_STATUS:
+ if (value & PCI_STATUS_PARITY) {
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_PARE_ERR_FLAG) {
+ lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+ }
+ }
+ break;
+ case PCI_BAR0_REG:
+ if (value == PCI_BAR_RANGE_MASK) {
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ lo |= SOFT_BAR_EHCI_FLAG;
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else if ((value & 0x01) == 0x00) {
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ lo = value;
+ _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+
+ value &= 0xfffffff0;
+ hi = 0x40000000 | ((value & 0xff000000) >> 24);
+ lo = 0x000fffff | ((value & 0x00fff000) << 8);
+ _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM4), hi, lo);
+ }
+ break;
+ case PCI_EHCI_LEGSMIEN_REG:
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ hi &= 0x003f0000;
+ hi |= (value & 0x3f) << 16;
+ _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+ break;
+ case PCI_EHCI_FLADJ_REG:
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ hi &= ~0x00003f00;
+ hi |= value & 0x00003f00;
+ _wrmsr(USB_MSR_REG(USB_EHCI), hi, lo);
+ break;
+ default:
+ break;
+ }
+}
+
+u32 pci_ehci_read_reg(int reg)
+{
+ u32 conf_data = 0;
+ u32 hi, lo;
+
+ switch (reg) {
+ case PCI_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);
+ break;
+ case PCI_COMMAND:
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ if (hi & PCI_COMMAND_MASTER)
+ conf_data |= PCI_COMMAND_MASTER;
+ if (hi & PCI_COMMAND_MEMORY)
+ conf_data |= PCI_COMMAND_MEMORY;
+ break;
+ case PCI_STATUS:
+ conf_data |= PCI_STATUS_66MHZ;
+ conf_data |= PCI_STATUS_FAST_BACK;
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_PARE_ERR_FLAG)
+ conf_data |= PCI_STATUS_PARITY;
+ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+ break;
+ case PCI_CLASS_REVISION:
+ _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+ conf_data = lo & 0x000000ff;
+ conf_data |= (CS5536_EHCI_CLASS_CODE << 8);
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ conf_data =
+ CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
+ PCI_NORMAL_LATENCY_TIMER);
+ break;
+ case PCI_BAR0_REG:
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ if (lo & SOFT_BAR_EHCI_FLAG) {
+ conf_data = CS5536_EHCI_RANGE |
+ PCI_BASE_ADDRESS_SPACE_MEMORY;
+ lo &= ~SOFT_BAR_EHCI_FLAG;
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else {
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ conf_data = lo & 0xfffff000;
+ }
+ break;
+ case PCI_CARDBUS_CIS:
+ conf_data = PCI_CARDBUS_CIS_POINTER;
+ break;
+ case PCI_SUBSYSTEM_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
+ break;
+ case PCI_ROM_ADDRESS:
+ conf_data = PCI_EXPANSION_ROM_BAR;
+ break;
+ case PCI_CAPABILITY_LIST:
+ conf_data = PCI_CAPLIST_USB_POINTER;
+ break;
+ case PCI_INTERRUPT_LINE:
+ conf_data =
+ CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
+ break;
+ case PCI_EHCI_LEGSMIEN_REG:
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ conf_data = (hi & 0x003f0000) >> 16;
+ break;
+ case PCI_EHCI_LEGSMISTS_REG:
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ conf_data = (hi & 0x3f000000) >> 24;
+ break;
+ case PCI_EHCI_FLADJ_REG:
+ _rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);
+ conf_data = hi & 0x00003f00;
+ break;
+ default:
+ break;
+ }
+
+ return conf_data;
+}
diff --git a/arch/mips/loongson/common/cs5536/cs5536_ide.c b/arch/mips/loongson/common/cs5536/cs5536_ide.c
new file mode 100644
index 00000000..681d1291
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_ide.c
@@ -0,0 +1,192 @@
+/*
+ * the IDE Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+void pci_ide_write_reg(int reg, u32 value)
+{
+ u32 hi = 0, lo = value;
+
+ switch (reg) {
+ case PCI_COMMAND:
+ _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+ if (value & PCI_COMMAND_MASTER)
+ lo |= (0x03 << 4);
+ else
+ lo &= ~(0x03 << 4);
+ _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
+ break;
+ case PCI_STATUS:
+ if (value & PCI_STATUS_PARITY) {
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_PARE_ERR_FLAG) {
+ lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+ }
+ }
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ value &= 0x0000ff00;
+ _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+ hi &= 0xffffff00;
+ hi |= (value >> 8);
+ _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
+ break;
+ case PCI_BAR4_REG:
+ if (value == PCI_BAR_RANGE_MASK) {
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ lo |= SOFT_BAR_IDE_FLAG;
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else if (value & 0x01) {
+ _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+ lo = (value & 0xfffffff0) | 0x1;
+ _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
+
+ value &= 0xfffffffc;
+ hi = 0x60000000 | ((value & 0x000ff000) >> 12);
+ lo = 0x000ffff0 | ((value & 0x00000fff) << 20);
+ _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo);
+ }
+ break;
+ case PCI_IDE_CFG_REG:
+ if (value == CS5536_IDE_FLASH_SIGNATURE) {
+ _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
+ lo |= 0x01;
+ _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
+ } else {
+ _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
+ lo = value;
+ _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
+ }
+ break;
+ case PCI_IDE_DTC_REG:
+ _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
+ lo = value;
+ _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
+ break;
+ case PCI_IDE_CAST_REG:
+ _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
+ lo = value;
+ _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
+ break;
+ case PCI_IDE_ETC_REG:
+ _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
+ lo = value;
+ _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
+ break;
+ case PCI_IDE_PM_REG:
+ _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
+ lo = value;
+ _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
+ break;
+ default:
+ break;
+ }
+}
+
+u32 pci_ide_read_reg(int reg)
+{
+ u32 conf_data = 0;
+ u32 hi, lo;
+
+ switch (reg) {
+ case PCI_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
+ break;
+ case PCI_COMMAND:
+ _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+ if (lo & 0xfffffff0)
+ conf_data |= PCI_COMMAND_IO;
+ _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
+ if ((lo & 0x30) == 0x30)
+ conf_data |= PCI_COMMAND_MASTER;
+ break;
+ case PCI_STATUS:
+ conf_data |= PCI_STATUS_66MHZ;
+ conf_data |= PCI_STATUS_FAST_BACK;
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_PARE_ERR_FLAG)
+ conf_data |= PCI_STATUS_PARITY;
+ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+ break;
+ case PCI_CLASS_REVISION:
+ _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
+ conf_data = lo & 0x000000ff;
+ conf_data |= (CS5536_IDE_CLASS_CODE << 8);
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+ hi &= 0x000000f8;
+ conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
+ break;
+ case PCI_BAR4_REG:
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ if (lo & SOFT_BAR_IDE_FLAG) {
+ conf_data = CS5536_IDE_RANGE |
+ PCI_BASE_ADDRESS_SPACE_IO;
+ lo &= ~SOFT_BAR_IDE_FLAG;
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else {
+ _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
+ conf_data = lo & 0xfffffff0;
+ conf_data |= 0x01;
+ conf_data &= ~0x02;
+ }
+ break;
+ case PCI_CARDBUS_CIS:
+ conf_data = PCI_CARDBUS_CIS_POINTER;
+ break;
+ case PCI_SUBSYSTEM_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
+ break;
+ case PCI_ROM_ADDRESS:
+ conf_data = PCI_EXPANSION_ROM_BAR;
+ break;
+ case PCI_CAPABILITY_LIST:
+ conf_data = PCI_CAPLIST_POINTER;
+ break;
+ case PCI_INTERRUPT_LINE:
+ conf_data =
+ CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
+ break;
+ case PCI_IDE_CFG_REG:
+ _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
+ conf_data = lo;
+ break;
+ case PCI_IDE_DTC_REG:
+ _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
+ conf_data = lo;
+ break;
+ case PCI_IDE_CAST_REG:
+ _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
+ conf_data = lo;
+ break;
+ case PCI_IDE_ETC_REG:
+ _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
+ conf_data = lo;
+ break;
+ case PCI_IDE_PM_REG:
+ _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
+ conf_data = lo;
+ break;
+ default:
+ break;
+ }
+
+ return conf_data;
+}
diff --git a/arch/mips/loongson/common/cs5536/cs5536_isa.c b/arch/mips/loongson/common/cs5536/cs5536_isa.c
new file mode 100644
index 00000000..4d9f65ab
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_isa.c
@@ -0,0 +1,316 @@
+/*
+ * the ISA Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+/* common variables for PCI_ISA_READ/WRITE_BAR */
+static const u32 divil_msr_reg[6] = {
+ DIVIL_MSR_REG(DIVIL_LBAR_SMB), DIVIL_MSR_REG(DIVIL_LBAR_GPIO),
+ DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), DIVIL_MSR_REG(DIVIL_LBAR_IRQ),
+ DIVIL_MSR_REG(DIVIL_LBAR_PMS), DIVIL_MSR_REG(DIVIL_LBAR_ACPI),
+};
+
+static const u32 soft_bar_flag[6] = {
+ SOFT_BAR_SMB_FLAG, SOFT_BAR_GPIO_FLAG, SOFT_BAR_MFGPT_FLAG,
+ SOFT_BAR_IRQ_FLAG, SOFT_BAR_PMS_FLAG, SOFT_BAR_ACPI_FLAG,
+};
+
+static const u32 sb_msr_reg[6] = {
+ SB_MSR_REG(SB_R0), SB_MSR_REG(SB_R1), SB_MSR_REG(SB_R2),
+ SB_MSR_REG(SB_R3), SB_MSR_REG(SB_R4), SB_MSR_REG(SB_R5),
+};
+
+static const u32 bar_space_range[6] = {
+ CS5536_SMB_RANGE, CS5536_GPIO_RANGE, CS5536_MFGPT_RANGE,
+ CS5536_IRQ_RANGE, CS5536_PMS_RANGE, CS5536_ACPI_RANGE,
+};
+
+static const int bar_space_len[6] = {
+ CS5536_SMB_LENGTH, CS5536_GPIO_LENGTH, CS5536_MFGPT_LENGTH,
+ CS5536_IRQ_LENGTH, CS5536_PMS_LENGTH, CS5536_ACPI_LENGTH,
+};
+
+/*
+ * enable the divil module bar space.
+ *
+ * For all the DIVIL module LBAR, you should control the DIVIL LBAR reg
+ * and the RCONFx(0~5) reg to use the modules.
+ */
+static void divil_lbar_enable(void)
+{
+ u32 hi, lo;
+ int offset;
+
+ /*
+ * The DIVIL IRQ is not used yet. and make the RCONF0 reserved.
+ */
+
+ for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
+ _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
+ hi |= 0x01;
+ _wrmsr(DIVIL_MSR_REG(offset), hi, lo);
+ }
+}
+
+/*
+ * disable the divil module bar space.
+ */
+static void divil_lbar_disable(void)
+{
+ u32 hi, lo;
+ int offset;
+
+ for (offset = DIVIL_LBAR_SMB; offset <= DIVIL_LBAR_PMS; offset++) {
+ _rdmsr(DIVIL_MSR_REG(offset), &hi, &lo);
+ hi &= ~0x01;
+ _wrmsr(DIVIL_MSR_REG(offset), hi, lo);
+ }
+}
+
+/*
+ * BAR write: write value to the n BAR
+ */
+
+void pci_isa_write_bar(int n, u32 value)
+{
+ u32 hi = 0, lo = value;
+
+ if (value == PCI_BAR_RANGE_MASK) {
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ lo |= soft_bar_flag[n];
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else if (value & 0x01) {
+ /* NATIVE reg */
+ hi = 0x0000f001;
+ lo &= bar_space_range[n];
+ _wrmsr(divil_msr_reg[n], hi, lo);
+
+ /* RCONFx is 4bytes in units for I/O space */
+ hi = ((value & 0x000ffffc) << 12) |
+ ((bar_space_len[n] - 4) << 12) | 0x01;
+ lo = ((value & 0x000ffffc) << 12) | 0x01;
+ _wrmsr(sb_msr_reg[n], hi, lo);
+ }
+}
+
+/*
+ * BAR read: read the n BAR
+ */
+
+u32 pci_isa_read_bar(int n)
+{
+ u32 conf_data = 0;
+ u32 hi, lo;
+
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ if (lo & soft_bar_flag[n]) {
+ conf_data = bar_space_range[n] | PCI_BASE_ADDRESS_SPACE_IO;
+ lo &= ~soft_bar_flag[n];
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else {
+ _rdmsr(divil_msr_reg[n], &hi, &lo);
+ conf_data = lo & bar_space_range[n];
+ conf_data |= 0x01;
+ conf_data &= ~0x02;
+ }
+ return conf_data;
+}
+
+/*
+ * isa_write: ISA write transfer
+ *
+ * We assume that this is not a bus master transfer.
+ */
+void pci_isa_write_reg(int reg, u32 value)
+{
+ u32 hi = 0, lo = value;
+ u32 temp;
+
+ switch (reg) {
+ case PCI_COMMAND:
+ if (value & PCI_COMMAND_IO)
+ divil_lbar_enable();
+ else
+ divil_lbar_disable();
+ break;
+ case PCI_STATUS:
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ temp = lo & 0x0000ffff;
+ if ((value & PCI_STATUS_SIG_TARGET_ABORT) &&
+ (lo & SB_TAS_ERR_EN))
+ temp |= SB_TAS_ERR_FLAG;
+
+ if ((value & PCI_STATUS_REC_TARGET_ABORT) &&
+ (lo & SB_TAR_ERR_EN))
+ temp |= SB_TAR_ERR_FLAG;
+
+ if ((value & PCI_STATUS_REC_MASTER_ABORT)
+ && (lo & SB_MAR_ERR_EN))
+ temp |= SB_MAR_ERR_FLAG;
+
+ if ((value & PCI_STATUS_DETECTED_PARITY)
+ && (lo & SB_PARE_ERR_EN))
+ temp |= SB_PARE_ERR_FLAG;
+
+ lo = temp;
+ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ value &= 0x0000ff00;
+ _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+ hi &= 0xffffff00;
+ hi |= (value >> 8);
+ _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
+ break;
+ case PCI_BAR0_REG:
+ pci_isa_write_bar(0, value);
+ break;
+ case PCI_BAR1_REG:
+ pci_isa_write_bar(1, value);
+ break;
+ case PCI_BAR2_REG:
+ pci_isa_write_bar(2, value);
+ break;
+ case PCI_BAR3_REG:
+ pci_isa_write_bar(3, value);
+ break;
+ case PCI_BAR4_REG:
+ pci_isa_write_bar(4, value);
+ break;
+ case PCI_BAR5_REG:
+ pci_isa_write_bar(5, value);
+ break;
+ case PCI_UART1_INT_REG:
+ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+ /* disable uart1 interrupt in PIC */
+ lo &= ~(0xf << 24);
+ if (value) /* enable uart1 interrupt in PIC */
+ lo |= (CS5536_UART1_INTR << 24);
+ _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+ break;
+ case PCI_UART2_INT_REG:
+ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), &hi, &lo);
+ /* disable uart2 interrupt in PIC */
+ lo &= ~(0xf << 28);
+ if (value) /* enable uart2 interrupt in PIC */
+ lo |= (CS5536_UART2_INTR << 28);
+ _wrmsr(DIVIL_MSR_REG(PIC_YSEL_HIGH), hi, lo);
+ break;
+ case PCI_ISA_FIXUP_REG:
+ if (value) {
+ /* enable the TARGET ABORT/MASTER ABORT etc. */
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ lo |= 0x00000063;
+ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+ }
+
+ default:
+ /* ALL OTHER PCI CONFIG SPACE HEADER IS NOT IMPLEMENTED. */
+ break;
+ }
+}
+
+/*
+ * isa_read: ISA read transfers
+ *
+ * We assume that this is not a bus master transfer.
+ */
+u32 pci_isa_read_reg(int reg)
+{
+ u32 conf_data = 0;
+ u32 hi, lo;
+
+ switch (reg) {
+ case PCI_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_ISA_DEVICE_ID, CS5536_VENDOR_ID);
+ break;
+ case PCI_COMMAND:
+ /* we just check the first LBAR for the IO enable bit, */
+ /* maybe we should changed later. */
+ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_SMB), &hi, &lo);
+ if (hi & 0x01)
+ conf_data |= PCI_COMMAND_IO;
+ break;
+ case PCI_STATUS:
+ conf_data |= PCI_STATUS_66MHZ;
+ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+ conf_data |= PCI_STATUS_FAST_BACK;
+
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_TAS_ERR_FLAG)
+ conf_data |= PCI_STATUS_SIG_TARGET_ABORT;
+ if (lo & SB_TAR_ERR_FLAG)
+ conf_data |= PCI_STATUS_REC_TARGET_ABORT;
+ if (lo & SB_MAR_ERR_FLAG)
+ conf_data |= PCI_STATUS_REC_MASTER_ABORT;
+ if (lo & SB_PARE_ERR_FLAG)
+ conf_data |= PCI_STATUS_DETECTED_PARITY;
+ break;
+ case PCI_CLASS_REVISION:
+ _rdmsr(GLCP_MSR_REG(GLCP_CHIP_REV_ID), &hi, &lo);
+ conf_data = lo & 0x000000ff;
+ conf_data |= (CS5536_ISA_CLASS_CODE << 8);
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
+ hi &= 0x000000f8;
+ conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_BRIDGE_HEADER_TYPE, hi);
+ break;
+ /*
+ * we only use the LBAR of DIVIL, no RCONF used.
+ * all of them are IO space.
+ */
+ case PCI_BAR0_REG:
+ return pci_isa_read_bar(0);
+ break;
+ case PCI_BAR1_REG:
+ return pci_isa_read_bar(1);
+ break;
+ case PCI_BAR2_REG:
+ return pci_isa_read_bar(2);
+ break;
+ case PCI_BAR3_REG:
+ break;
+ case PCI_BAR4_REG:
+ return pci_isa_read_bar(4);
+ break;
+ case PCI_BAR5_REG:
+ return pci_isa_read_bar(5);
+ break;
+ case PCI_CARDBUS_CIS:
+ conf_data = PCI_CARDBUS_CIS_POINTER;
+ break;
+ case PCI_SUBSYSTEM_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_ISA_SUB_ID, CS5536_SUB_VENDOR_ID);
+ break;
+ case PCI_ROM_ADDRESS:
+ conf_data = PCI_EXPANSION_ROM_BAR;
+ break;
+ case PCI_CAPABILITY_LIST:
+ conf_data = PCI_CAPLIST_POINTER;
+ break;
+ case PCI_INTERRUPT_LINE:
+ /* no interrupt used here */
+ conf_data = CFG_PCI_INTERRUPT_LINE(0x00, 0x00);
+ break;
+ default:
+ break;
+ }
+
+ return conf_data;
+}
diff --git a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
new file mode 100644
index 00000000..0cb1b976
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
@@ -0,0 +1,214 @@
+/*
+ * CS5536 General timer functions
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Yanhua, yanh@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu zhangjin, wuzhangjin@gmail.com
+ *
+ * Reference: AMD Geode(TM) CS5536 Companion Device Data Book
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+
+#include <asm/time.h>
+
+#include <cs5536/cs5536_mfgpt.h>
+
+DEFINE_SPINLOCK(mfgpt_lock);
+EXPORT_SYMBOL(mfgpt_lock);
+
+static u32 mfgpt_base;
+
+/*
+ * Initialize the MFGPT timer.
+ *
+ * This is also called after resume to bring the MFGPT into operation again.
+ */
+
+/* disable counter */
+void disable_mfgpt0_counter(void)
+{
+ outw(inw(MFGPT0_SETUP) & 0x7fff, MFGPT0_SETUP);
+}
+EXPORT_SYMBOL(disable_mfgpt0_counter);
+
+/* enable counter, comparator2 to event mode, 14.318MHz clock */
+void enable_mfgpt0_counter(void)
+{
+ outw(0xe310, MFGPT0_SETUP);
+}
+EXPORT_SYMBOL(enable_mfgpt0_counter);
+
+static void init_mfgpt_timer(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ spin_lock(&mfgpt_lock);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */
+ outw(0, MFGPT0_CNT); /* set counter to 0 */
+ enable_mfgpt0_counter();
+ break;
+
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
+ evt->mode == CLOCK_EVT_MODE_ONESHOT)
+ disable_mfgpt0_counter();
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* The oneshot mode have very high deviation, Not use it! */
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ /* Nothing to do here */
+ break;
+ }
+ spin_unlock(&mfgpt_lock);
+}
+
+static struct clock_event_device mfgpt_clockevent = {
+ .name = "mfgpt",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .set_mode = init_mfgpt_timer,
+ .irq = CS5536_MFGPT_INTR,
+};
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ u32 basehi;
+
+ /*
+ * get MFGPT base address
+ *
+ * NOTE: do not remove me, it's need for the value of mfgpt_base is
+ * variable
+ */
+ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base);
+
+ /* ack */
+ outw(inw(MFGPT0_SETUP) | 0x4000, MFGPT0_SETUP);
+
+ mfgpt_clockevent.event_handler(&mfgpt_clockevent);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq5 = {
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
+ .name = "timer"
+};
+
+/*
+ * Initialize the conversion factor and the min/max deltas of the clock event
+ * structure and register the clock event source with the framework.
+ */
+void __init setup_mfgpt0_timer(void)
+{
+ u32 basehi;
+ struct clock_event_device *cd = &mfgpt_clockevent;
+ unsigned int cpu = smp_processor_id();
+
+ cd->cpumask = cpumask_of(cpu);
+ clockevent_set_clock(cd, MFGPT_TICK_RATE);
+ cd->max_delta_ns = clockevent_delta2ns(0xffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
+
+ /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */
+ _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100);
+
+ /* Enable Interrupt Gate 5 */
+ _wrmsr(DIVIL_MSR_REG(PIC_ZSEL_LOW), 0, 0x50000);
+
+ /* get MFGPT base address */
+ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &basehi, &mfgpt_base);
+
+ clockevents_register_device(cd);
+
+ setup_irq(CS5536_MFGPT_INTR, &irq5);
+}
+
+/*
+ * Since the MFGPT overflows every tick, its not very useful
+ * to just read by itself. So use jiffies to emulate a free
+ * running counter:
+ */
+static cycle_t mfgpt_read(struct clocksource *cs)
+{
+ unsigned long flags;
+ int count;
+ u32 jifs;
+ static int old_count;
+ static u32 old_jifs;
+
+ spin_lock_irqsave(&mfgpt_lock, flags);
+ /*
+ * Although our caller may have the read side of xtime_lock,
+ * this is now a seqlock, and we are cheating in this routine
+ * by having side effects on state that we cannot undo if
+ * there is a collision on the seqlock and our caller has to
+ * retry. (Namely, old_jifs and old_count.) So we must treat
+ * jiffies as volatile despite the lock. We read jiffies
+ * before latching the timer count to guarantee that although
+ * the jiffies value might be older than the count (that is,
+ * the counter may underflow between the last point where
+ * jiffies was incremented and the point where we latch the
+ * count), it cannot be newer.
+ */
+ jifs = jiffies;
+ /* read the count */
+ count = inw(MFGPT0_CNT);
+
+ /*
+ * It's possible for count to appear to go the wrong way for this
+ * reason:
+ *
+ * The timer counter underflows, but we haven't handled the resulting
+ * interrupt and incremented jiffies yet.
+ *
+ * Previous attempts to handle these cases intelligently were buggy, so
+ * we just do the simple thing now.
+ */
+ if (count < old_count && jifs == old_jifs)
+ count = old_count;
+
+ old_count = count;
+ old_jifs = jifs;
+
+ spin_unlock_irqrestore(&mfgpt_lock, flags);
+
+ return (cycle_t) (jifs * COMPARE) + count;
+}
+
+static struct clocksource clocksource_mfgpt = {
+ .name = "mfgpt",
+ .rating = 120, /* Functional for real use, but not desired */
+ .read = mfgpt_read,
+ .mask = CLOCKSOURCE_MASK(32),
+};
+
+int __init init_mfgpt_clocksource(void)
+{
+ if (num_possible_cpus() > 1) /* MFGPT does not scale! */
+ return 0;
+
+ return clocksource_register_hz(&clocksource_mfgpt, MFGPT_TICK_RATE);
+}
+
+arch_initcall(init_mfgpt_clocksource);
diff --git a/arch/mips/loongson/common/cs5536/cs5536_ohci.c b/arch/mips/loongson/common/cs5536/cs5536_ohci.c
new file mode 100644
index 00000000..bdedf512
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_ohci.c
@@ -0,0 +1,149 @@
+/*
+ * the OHCI Virtual Support Module of AMD CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+void pci_ohci_write_reg(int reg, u32 value)
+{
+ u32 hi = 0, lo = value;
+
+ switch (reg) {
+ case PCI_COMMAND:
+ _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+ if (value & PCI_COMMAND_MASTER)
+ hi |= PCI_COMMAND_MASTER;
+ else
+ hi &= ~PCI_COMMAND_MASTER;
+
+ if (value & PCI_COMMAND_MEMORY)
+ hi |= PCI_COMMAND_MEMORY;
+ else
+ hi &= ~PCI_COMMAND_MEMORY;
+ _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+ break;
+ case PCI_STATUS:
+ if (value & PCI_STATUS_PARITY) {
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_PARE_ERR_FLAG) {
+ lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
+ _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
+ }
+ }
+ break;
+ case PCI_BAR0_REG:
+ if (value == PCI_BAR_RANGE_MASK) {
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ lo |= SOFT_BAR_OHCI_FLAG;
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else if ((value & 0x01) == 0x00) {
+ _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+ lo = value;
+ _wrmsr(USB_MSR_REG(USB_OHCI), hi, lo);
+
+ value &= 0xfffffff0;
+ hi = 0x40000000 | ((value & 0xff000000) >> 24);
+ lo = 0x000fffff | ((value & 0x00fff000) << 8);
+ _wrmsr(GLIU_MSR_REG(GLIU_P2D_BM3), hi, lo);
+ }
+ break;
+ case PCI_OHCI_INT_REG:
+ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+ lo &= ~(0xf << PIC_YSEL_LOW_USB_SHIFT);
+ if (value) /* enable all the usb interrupt in PIC */
+ lo |= (CS5536_USB_INTR << PIC_YSEL_LOW_USB_SHIFT);
+ _wrmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), hi, lo);
+ break;
+ default:
+ break;
+ }
+}
+
+u32 pci_ohci_read_reg(int reg)
+{
+ u32 conf_data = 0;
+ u32 hi, lo;
+
+ switch (reg) {
+ case PCI_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);
+ break;
+ case PCI_COMMAND:
+ _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+ if (hi & PCI_COMMAND_MASTER)
+ conf_data |= PCI_COMMAND_MASTER;
+ if (hi & PCI_COMMAND_MEMORY)
+ conf_data |= PCI_COMMAND_MEMORY;
+ break;
+ case PCI_STATUS:
+ conf_data |= PCI_STATUS_66MHZ;
+ conf_data |= PCI_STATUS_FAST_BACK;
+ _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
+ if (lo & SB_PARE_ERR_FLAG)
+ conf_data |= PCI_STATUS_PARITY;
+ conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
+ break;
+ case PCI_CLASS_REVISION:
+ _rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);
+ conf_data = lo & 0x000000ff;
+ conf_data |= (CS5536_OHCI_CLASS_CODE << 8);
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ conf_data =
+ CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,
+ PCI_NORMAL_LATENCY_TIMER);
+ break;
+ case PCI_BAR0_REG:
+ _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
+ if (lo & SOFT_BAR_OHCI_FLAG) {
+ conf_data = CS5536_OHCI_RANGE |
+ PCI_BASE_ADDRESS_SPACE_MEMORY;
+ lo &= ~SOFT_BAR_OHCI_FLAG;
+ _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
+ } else {
+ _rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);
+ conf_data = lo & 0xffffff00;
+ conf_data &= ~0x0000000f; /* 32bit mem */
+ }
+ break;
+ case PCI_CARDBUS_CIS:
+ conf_data = PCI_CARDBUS_CIS_POINTER;
+ break;
+ case PCI_SUBSYSTEM_VENDOR_ID:
+ conf_data =
+ CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);
+ break;
+ case PCI_ROM_ADDRESS:
+ conf_data = PCI_EXPANSION_ROM_BAR;
+ break;
+ case PCI_CAPABILITY_LIST:
+ conf_data = PCI_CAPLIST_USB_POINTER;
+ break;
+ case PCI_INTERRUPT_LINE:
+ conf_data =
+ CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);
+ break;
+ case PCI_OHCI_INT_REG:
+ _rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo);
+ if ((lo & 0x00000f00) == CS5536_USB_INTR)
+ conf_data = 1;
+ break;
+ default:
+ break;
+ }
+
+ return conf_data;
+}
diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c
new file mode 100644
index 00000000..6dfeab11
--- /dev/null
+++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c
@@ -0,0 +1,87 @@
+/*
+ * read/write operation to the PCI config space of CS5536
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author : jlliu, liujl@lemote.com
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * the Virtual Support Module(VSM) for virtulizing the PCI
+ * configure space are defined in cs5536_modulename.c respectively,
+ *
+ * after this virtulizing, user can access the PCI configure space
+ * directly as a normal multi-function PCI device which follows
+ * the PCI-2.2 spec.
+ */
+
+#include <linux/types.h>
+#include <cs5536/cs5536_vsm.h>
+
+enum {
+ CS5536_FUNC_START = -1,
+ CS5536_ISA_FUNC,
+ reserved_func,
+ CS5536_IDE_FUNC,
+ CS5536_ACC_FUNC,
+ CS5536_OHCI_FUNC,
+ CS5536_EHCI_FUNC,
+ CS5536_FUNC_END,
+};
+
+static const cs5536_pci_vsm_write vsm_conf_write[] = {
+ [CS5536_ISA_FUNC] pci_isa_write_reg,
+ [reserved_func] NULL,
+ [CS5536_IDE_FUNC] pci_ide_write_reg,
+ [CS5536_ACC_FUNC] pci_acc_write_reg,
+ [CS5536_OHCI_FUNC] pci_ohci_write_reg,
+ [CS5536_EHCI_FUNC] pci_ehci_write_reg,
+};
+
+static const cs5536_pci_vsm_read vsm_conf_read[] = {
+ [CS5536_ISA_FUNC] pci_isa_read_reg,
+ [reserved_func] NULL,
+ [CS5536_IDE_FUNC] pci_ide_read_reg,
+ [CS5536_ACC_FUNC] pci_acc_read_reg,
+ [CS5536_OHCI_FUNC] pci_ohci_read_reg,
+ [CS5536_EHCI_FUNC] pci_ehci_read_reg,
+};
+
+/*
+ * write to PCI config space and transfer it to MSR write.
+ */
+void cs5536_pci_conf_write4(int function, int reg, u32 value)
+{
+ if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END))
+ return;
+ if ((reg < 0) || (reg > 0x100) || ((reg & 0x03) != 0))
+ return;
+
+ if (vsm_conf_write[function] != NULL)
+ vsm_conf_write[function](reg, value);
+}
+
+/*
+ * read PCI config space and transfer it to MSR access.
+ */
+u32 cs5536_pci_conf_read4(int function, int reg)
+{
+ u32 data = 0;
+
+ if ((function <= CS5536_FUNC_START) || (function >= CS5536_FUNC_END))
+ return 0;
+ if ((reg < 0) || ((reg & 0x03) != 0))
+ return 0;
+ if (reg > 0x100)
+ return 0xffffffff;
+
+ if (vsm_conf_read[function] != NULL)
+ data = vsm_conf_read[function](reg);
+
+ return data;
+}
diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c
new file mode 100644
index 00000000..a71736f0
--- /dev/null
+++ b/arch/mips/loongson/common/early_printk.c
@@ -0,0 +1,41 @@
+/* early printk support
+ *
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ * Copyright (c) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/serial_reg.h>
+
+#include <loongson.h>
+
+#define PORT(base, offset) (u8 *)(base + offset)
+
+static inline unsigned int serial_in(unsigned char *base, int offset)
+{
+ return readb(PORT(base, offset));
+}
+
+static inline void serial_out(unsigned char *base, int offset, int value)
+{
+ writeb(value, PORT(base, offset));
+}
+
+void prom_putchar(char c)
+{
+ int timeout;
+ unsigned char *uart_base;
+
+ uart_base = (unsigned char *)_loongson_uart_base;
+ timeout = 1024;
+
+ while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) &&
+ (timeout-- > 0))
+ ;
+
+ serial_out(uart_base, UART_TX, c);
+}
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
new file mode 100644
index 00000000..d93830ad
--- /dev/null
+++ b/arch/mips/loongson/common/env.c
@@ -0,0 +1,79 @@
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/module.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+unsigned long cpu_clock_freq;
+EXPORT_SYMBOL(cpu_clock_freq);
+unsigned long memsize, highmemsize;
+
+#define parse_even_earlier(res, option, p) \
+do { \
+ unsigned int tmp __maybe_unused; \
+ \
+ if (strncmp(option, (char *)p, strlen(option)) == 0) \
+ tmp = strict_strtol((char *)p + strlen(option"="), 10, &res); \
+} while (0)
+
+void __init prom_init_env(void)
+{
+ /* pmon passes arguments in 32bit pointers */
+ int *_prom_envp;
+ unsigned long bus_clock;
+ unsigned int processor_id;
+ long l;
+
+ /* firmware arguments are initialized in head.S */
+ _prom_envp = (int *)fw_arg2;
+
+ l = (long)*_prom_envp;
+ while (l != 0) {
+ parse_even_earlier(bus_clock, "busclock", l);
+ parse_even_earlier(cpu_clock_freq, "cpuclock", l);
+ parse_even_earlier(memsize, "memsize", l);
+ parse_even_earlier(highmemsize, "highmemsize", l);
+ _prom_envp++;
+ l = (long)*_prom_envp;
+ }
+ if (memsize == 0)
+ memsize = 256;
+ if (bus_clock == 0)
+ bus_clock = 66000000;
+ if (cpu_clock_freq == 0) {
+ processor_id = (&current_cpu_data)->processor_id;
+ switch (processor_id & PRID_REV_MASK) {
+ case PRID_REV_LOONGSON2E:
+ cpu_clock_freq = 533080000;
+ break;
+ case PRID_REV_LOONGSON2F:
+ cpu_clock_freq = 797000000;
+ break;
+ default:
+ cpu_clock_freq = 100000000;
+ break;
+ }
+ }
+
+ pr_info("busclock=%ld, cpuclock=%ld, memsize=%ld, highmemsize=%ld\n",
+ bus_clock, cpu_clock_freq, memsize, highmemsize);
+}
diff --git a/arch/mips/loongson/common/gpio.c b/arch/mips/loongson/common/gpio.c
new file mode 100644
index 00000000..e8a0ffa9
--- /dev/null
+++ b/arch/mips/loongson/common/gpio.c
@@ -0,0 +1,139 @@
+/*
+ * STLS2F GPIO Support
+ *
+ * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
+ * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <asm/types.h>
+#include <loongson.h>
+#include <linux/gpio.h>
+
+#define STLS2F_N_GPIO 4
+#define STLS2F_GPIO_IN_OFFSET 16
+
+static DEFINE_SPINLOCK(gpio_lock);
+
+int gpio_get_value(unsigned gpio)
+{
+ u32 val;
+ u32 mask;
+
+ if (gpio >= STLS2F_N_GPIO)
+ return __gpio_get_value(gpio);
+
+ mask = 1 << (gpio + STLS2F_GPIO_IN_OFFSET);
+ spin_lock(&gpio_lock);
+ val = LOONGSON_GPIODATA;
+ spin_unlock(&gpio_lock);
+
+ return ((val & mask) != 0);
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int state)
+{
+ u32 val;
+ u32 mask;
+
+ if (gpio >= STLS2F_N_GPIO) {
+ __gpio_set_value(gpio, state);
+ return ;
+ }
+
+ mask = 1 << gpio;
+
+ spin_lock(&gpio_lock);
+ val = LOONGSON_GPIODATA;
+ if (state)
+ val |= mask;
+ else
+ val &= (~mask);
+ LOONGSON_GPIODATA = val;
+ spin_unlock(&gpio_lock);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_cansleep(unsigned gpio)
+{
+ if (gpio < STLS2F_N_GPIO)
+ return 0;
+ else
+ return __gpio_cansleep(gpio);
+}
+EXPORT_SYMBOL(gpio_cansleep);
+
+static int ls2f_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ u32 temp;
+ u32 mask;
+
+ if (gpio >= STLS2F_N_GPIO)
+ return -EINVAL;
+
+ spin_lock(&gpio_lock);
+ mask = 1 << gpio;
+ temp = LOONGSON_GPIOIE;
+ temp |= mask;
+ LOONGSON_GPIOIE = temp;
+ spin_unlock(&gpio_lock);
+
+ return 0;
+}
+
+static int ls2f_gpio_direction_output(struct gpio_chip *chip,
+ unsigned gpio, int level)
+{
+ u32 temp;
+ u32 mask;
+
+ if (gpio >= STLS2F_N_GPIO)
+ return -EINVAL;
+
+ gpio_set_value(gpio, level);
+ spin_lock(&gpio_lock);
+ mask = 1 << gpio;
+ temp = LOONGSON_GPIOIE;
+ temp &= (~mask);
+ LOONGSON_GPIOIE = temp;
+ spin_unlock(&gpio_lock);
+
+ return 0;
+}
+
+static int ls2f_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ return gpio_get_value(gpio);
+}
+
+static void ls2f_gpio_set_value(struct gpio_chip *chip,
+ unsigned gpio, int value)
+{
+ gpio_set_value(gpio, value);
+}
+
+static struct gpio_chip ls2f_chip = {
+ .label = "ls2f",
+ .direction_input = ls2f_gpio_direction_input,
+ .get = ls2f_gpio_get_value,
+ .direction_output = ls2f_gpio_direction_output,
+ .set = ls2f_gpio_set_value,
+ .base = 0,
+ .ngpio = STLS2F_N_GPIO,
+};
+
+static int __init ls2f_gpio_setup(void)
+{
+ return gpiochip_add(&ls2f_chip);
+}
+arch_initcall(ls2f_gpio_setup);
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c
new file mode 100644
index 00000000..19d34159
--- /dev/null
+++ b/arch/mips/loongson/common/init.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/bootmem.h>
+
+#include <loongson.h>
+
+/* Loongson CPU address windows config space base address */
+unsigned long __maybe_unused _loongson_addrwincfg_base;
+
+void __init prom_init(void)
+{
+ /* init base address of io space */
+ set_io_port_base((unsigned long)
+ ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE));
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+ _loongson_addrwincfg_base = (unsigned long)
+ ioremap(LOONGSON_ADDRWINCFG_BASE, LOONGSON_ADDRWINCFG_SIZE);
+#endif
+
+ prom_init_cmdline();
+ prom_init_env();
+ prom_init_memory();
+
+ /*init the uart base address */
+ prom_init_uart_base();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c
new file mode 100644
index 00000000..5897471d
--- /dev/null
+++ b/arch/mips/loongson/common/irq.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <loongson.h>
+/*
+ * the first level int-handler will jump here if it is a bonito irq
+ */
+void bonito_irqdispatch(void)
+{
+ u32 int_status;
+ int i;
+
+ /* workaround the IO dma problem: let cpu looping to allow DMA finish */
+ int_status = LOONGSON_INTISR;
+ while (int_status & (1 << 10)) {
+ udelay(1);
+ int_status = LOONGSON_INTISR;
+ }
+
+ /* Get pending sources, masked by current enables */
+ int_status = LOONGSON_INTISR & LOONGSON_INTEN;
+
+ if (int_status) {
+ i = __ffs(int_status);
+ do_IRQ(LOONGSON_IRQ_BASE + i);
+ }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending;
+
+ pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+ /* machine-specific plat_irq_dispatch */
+ mach_irq_dispatch(pending);
+}
+
+void __init arch_init_irq(void)
+{
+ /*
+ * Clear all of the interrupts while we change the able around a bit.
+ * int-handler is not on bootstrap
+ */
+ clear_c0_status(ST0_IM | ST0_BEV);
+
+ /* no steer */
+ LOONGSON_INTSTEER = 0;
+
+ /*
+ * Mask out all interrupt by writing "1" to all bit position in
+ * the interrupt reset reg.
+ */
+ LOONGSON_INTENCLR = ~0;
+
+ /* machine specific irq init */
+ mach_init_irq();
+}
diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c
new file mode 100644
index 00000000..2efd5d9d
--- /dev/null
+++ b/arch/mips/loongson/common/machtype.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/errno.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+/* please ensure the length of the machtype string is less than 50 */
+#define MACHTYPE_LEN 50
+
+static const char *system_types[] = {
+ [MACH_LOONGSON_UNKNOWN] "unknown loongson machine",
+ [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box",
+ [MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box",
+ [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches",
+ [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches",
+ [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f",
+ [MACH_LEMOTE_NAS] "lemote-nas-2f",
+ [MACH_LEMOTE_LL2F] "lemote-lynloong-2f",
+ [MACH_LOONGSON_END] NULL,
+};
+
+const char *get_system_type(void)
+{
+ return system_types[mips_machtype];
+}
+
+void __weak __init mach_prom_init_machtype(void)
+{
+}
+
+void __init prom_init_machtype(void)
+{
+ char *p, str[MACHTYPE_LEN + 1];
+ int machtype = MACH_LEMOTE_FL2E;
+
+ mips_machtype = LOONGSON_MACHTYPE;
+
+ p = strstr(arcs_cmdline, "machtype=");
+ if (!p) {
+ mach_prom_init_machtype();
+ return;
+ }
+ p += strlen("machtype=");
+ strncpy(str, p, MACHTYPE_LEN);
+ str[MACHTYPE_LEN] = '\0';
+ p = strstr(str, " ");
+ if (p)
+ *p = '\0';
+
+ for (; system_types[machtype]; machtype++)
+ if (strstr(system_types[machtype], str)) {
+ mips_machtype = machtype;
+ break;
+ }
+}
diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c
new file mode 100644
index 00000000..30eba600
--- /dev/null
+++ b/arch/mips/loongson/common/mem.c
@@ -0,0 +1,119 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <mem.h>
+#include <pci.h>
+
+void __init prom_init_memory(void)
+{
+ add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+
+ add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
+ 20), BOOT_MEM_RESERVED);
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+ {
+ int bit;
+
+ bit = fls(memsize + highmemsize);
+ if (bit != ffs(memsize + highmemsize))
+ bit += 20;
+ else
+ bit = bit + 20 - 1;
+
+ /* set cpu window3 to map CPU to DDR: 2G -> 2G */
+ LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul,
+ 0x80000000ul, (1 << bit));
+ mmiowb();
+ }
+#endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
+
+#ifdef CONFIG_64BIT
+ if (highmemsize > 0)
+ add_memory_region(LOONGSON_HIGHMEM_START,
+ highmemsize << 20, BOOT_MEM_RAM);
+
+ add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START -
+ LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED);
+
+#endif /* !CONFIG_64BIT */
+}
+
+/* override of arch/mips/mm/cache.c: __uncached_access */
+int __uncached_access(struct file *file, unsigned long addr)
+{
+ if (file->f_flags & O_DSYNC)
+ return 1;
+
+ return addr >= __pa(high_memory) ||
+ ((addr >= LOONGSON_MMIO_MEM_START) &&
+ (addr < LOONGSON_MMIO_MEM_END));
+}
+
+#ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
+
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <asm/current.h>
+
+static unsigned long uca_start, uca_end;
+
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot)
+{
+ unsigned long offset = pfn << PAGE_SHIFT;
+ unsigned long end = offset + size;
+
+ if (__uncached_access(file, offset)) {
+ if (uca_start && (offset >= uca_start) &&
+ (end <= uca_end))
+ return __pgprot((pgprot_val(vma_prot) &
+ ~_CACHE_MASK) |
+ _CACHE_UNCACHED_ACCELERATED);
+ else
+ return pgprot_noncached(vma_prot);
+ }
+ return vma_prot;
+}
+
+static int __init find_vga_mem_init(void)
+{
+ struct pci_dev *dev = 0;
+ struct resource *r;
+ int idx;
+
+ if (uca_start)
+ return 0;
+
+ for_each_pci_dev(dev) {
+ if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
+ r = &dev->resource[idx];
+ if (!r->start && r->end)
+ continue;
+ if (r->flags & IORESOURCE_IO)
+ continue;
+ if (r->flags & IORESOURCE_MEM) {
+ uca_start = r->start;
+ uca_end = r->end;
+ return 0;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+late_initcall(find_vga_mem_init);
+#endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */
diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c
new file mode 100644
index 00000000..31d8c5ec
--- /dev/null
+++ b/arch/mips/loongson/common/pci.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/pci.h>
+
+#include <pci.h>
+#include <loongson.h>
+
+static struct resource loongson_pci_mem_resource = {
+ .name = "pci memory space",
+ .start = LOONGSON_PCI_MEM_START,
+ .end = LOONGSON_PCI_MEM_END,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource loongson_pci_io_resource = {
+ .name = "pci io space",
+ .start = LOONGSON_PCI_IO_START,
+ .end = IO_SPACE_LIMIT,
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller loongson_pci_controller = {
+ .pci_ops = &loongson_pci_ops,
+ .io_resource = &loongson_pci_io_resource,
+ .mem_resource = &loongson_pci_mem_resource,
+ .mem_offset = 0x00000000UL,
+ .io_offset = 0x00000000UL,
+};
+
+static void __init setup_pcimap(void)
+{
+ /*
+ * local to PCI mapping for CPU accessing PCI space
+ * CPU address space [256M,448M] is window for accessing pci space
+ * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M]
+ *
+ * pcimap: PCI_MAP2 PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0
+ * [<2G] [384M,448M] [320M,384M] [0M,64M]
+ */
+ LOONGSON_PCIMAP = LOONGSON_PCIMAP_PCIMAP_2 |
+ LOONGSON_PCIMAP_WIN(2, LOONGSON_PCILO2_BASE) |
+ LOONGSON_PCIMAP_WIN(1, LOONGSON_PCILO1_BASE) |
+ LOONGSON_PCIMAP_WIN(0, 0);
+
+ /*
+ * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M]
+ */
+ LOONGSON_PCIBASE0 = 0x80000000ul; /* base: 2G -> mmap: 0M */
+ /* size: 256M, burst transmission, pre-fetch enable, 64bit */
+ LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul;
+ LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful;
+ LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */
+ LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul;
+ LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */
+ LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul;
+
+ /* avoid deadlock of PCI reading/writing lock operation */
+ LOONGSON_PCI_ISR4C = 0xd2000001ul;
+
+ /* can not change gnt to break pci transfer when device's gnt not
+ deassert for some broken device */
+ LOONGSON_PXARB_CFG = 0x00fe0105ul;
+
+#ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+ /*
+ * set cpu addr window2 to map CPU address space to PCI address space
+ */
+ LOONGSON_ADDRWIN_CPUTOPCI(ADDRWIN_WIN2, LOONGSON_CPU_MEM_SRC,
+ LOONGSON_PCI_MEM_DST, MMAP_CPUTOPCI_SIZE);
+#endif
+}
+
+static int __init pcibios_init(void)
+{
+ setup_pcimap();
+
+ loongson_pci_controller.io_map_base = mips_io_port_base;
+
+ register_pci_controller(&loongson_pci_controller);
+
+ return 0;
+}
+
+arch_initcall(pcibios_init);
diff --git a/arch/mips/loongson/common/platform.c b/arch/mips/loongson/common/platform.c
new file mode 100644
index 00000000..ed007a2e
--- /dev/null
+++ b/arch/mips/loongson/common/platform.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+static struct platform_device loongson2_cpufreq_device = {
+ .name = "loongson2_cpufreq",
+ .id = -1,
+};
+
+static int __init loongson2_cpufreq_init(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ /* Only 2F revision and it's successors support CPUFreq */
+ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F)
+ return platform_device_register(&loongson2_cpufreq_device);
+
+ return -ENODEV;
+}
+
+arch_initcall(loongson2_cpufreq_init);
diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c
new file mode 100644
index 00000000..f55e07ae
--- /dev/null
+++ b/arch/mips/loongson/common/pm.c
@@ -0,0 +1,161 @@
+/*
+ * loongson-specific suspend support
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/suspend.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+
+#include <loongson.h>
+
+static unsigned int __maybe_unused cached_master_mask; /* i8259A */
+static unsigned int __maybe_unused cached_slave_mask;
+static unsigned int __maybe_unused cached_bonito_irq_mask; /* bonito */
+
+void arch_suspend_disable_irqs(void)
+{
+ /* disable all mips events */
+ local_irq_disable();
+
+#ifdef CONFIG_I8259
+ /* disable all events of i8259A */
+ cached_slave_mask = inb(PIC_SLAVE_IMR);
+ cached_master_mask = inb(PIC_MASTER_IMR);
+
+ outb(0xff, PIC_SLAVE_IMR);
+ inb(PIC_SLAVE_IMR);
+ outb(0xff, PIC_MASTER_IMR);
+ inb(PIC_MASTER_IMR);
+#endif
+ /* disable all events of bonito */
+ cached_bonito_irq_mask = LOONGSON_INTEN;
+ LOONGSON_INTENCLR = 0xffff;
+ (void)LOONGSON_INTENCLR;
+}
+
+void arch_suspend_enable_irqs(void)
+{
+ /* enable all mips events */
+ local_irq_enable();
+#ifdef CONFIG_I8259
+ /* only enable the cached events of i8259A */
+ outb(cached_slave_mask, PIC_SLAVE_IMR);
+ outb(cached_master_mask, PIC_MASTER_IMR);
+#endif
+ /* enable all cached events of bonito */
+ LOONGSON_INTENSET = cached_bonito_irq_mask;
+ (void)LOONGSON_INTENSET;
+}
+
+/*
+ * Setup the board-specific events for waking up loongson from wait mode
+ */
+void __weak setup_wakeup_events(void)
+{
+}
+
+/*
+ * Check wakeup events
+ */
+int __weak wakeup_loongson(void)
+{
+ return 1;
+}
+
+/*
+ * If the events are really what we want to wakeup the CPU, wake it up
+ * otherwise put the CPU asleep again.
+ */
+static void wait_for_wakeup_events(void)
+{
+ while (!wakeup_loongson())
+ LOONGSON_CHIPCFG0 &= ~0x7;
+}
+
+/*
+ * Stop all perf counters
+ *
+ * $24 is the control register of Loongson perf counter
+ */
+static inline void stop_perf_counters(void)
+{
+ __write_64bit_c0_register($24, 0, 0);
+}
+
+
+static void loongson_suspend_enter(void)
+{
+ static unsigned int cached_cpu_freq;
+
+ /* setup wakeup events via enabling the IRQs */
+ setup_wakeup_events();
+
+ stop_perf_counters();
+
+ cached_cpu_freq = LOONGSON_CHIPCFG0;
+
+ /* Put CPU into wait mode */
+ LOONGSON_CHIPCFG0 &= ~0x7;
+
+ /* wait for the given events to wakeup cpu from wait mode */
+ wait_for_wakeup_events();
+
+ LOONGSON_CHIPCFG0 = cached_cpu_freq;
+ mmiowb();
+}
+
+void __weak mach_suspend(void)
+{
+}
+
+void __weak mach_resume(void)
+{
+}
+
+static int loongson_pm_enter(suspend_state_t state)
+{
+ mach_suspend();
+
+ /* processor specific suspend */
+ loongson_suspend_enter();
+
+ mach_resume();
+
+ return 0;
+}
+
+static int loongson_pm_valid_state(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_ON:
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+static const struct platform_suspend_ops loongson_pm_ops = {
+ .valid = loongson_pm_valid_state,
+ .enter = loongson_pm_enter,
+};
+
+static int __init loongson_pm_init(void)
+{
+ suspend_set_ops(&loongson_pm_ops);
+
+ return 0;
+}
+arch_initcall(loongson_pm_init);
diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c
new file mode 100644
index 00000000..9e10d622
--- /dev/null
+++ b/arch/mips/loongson/common/reset.c
@@ -0,0 +1,70 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Zhangjin Wu, wuzhangjin@gmail.com
+ */
+#include <linux/init.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+
+#include <loongson.h>
+
+static inline void loongson_reboot(void)
+{
+#ifndef CONFIG_CPU_JUMP_WORKAROUNDS
+ ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
+#else
+ void (*func)(void);
+
+ func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4);
+
+ __asm__ __volatile__(
+ " .set noat \n"
+ " jr %[func] \n"
+ " .set at \n"
+ : /* No outputs */
+ : [func] "r" (func));
+#endif
+}
+
+static void loongson_restart(char *command)
+{
+ /* do preparation for reboot */
+ mach_prepare_reboot();
+
+ /* reboot via jumping to boot base address */
+ loongson_reboot();
+}
+
+static void loongson_poweroff(void)
+{
+ mach_prepare_shutdown();
+ unreachable();
+}
+
+static void loongson_halt(void)
+{
+ pr_notice("\n\n** You can safely turn off the power now **\n\n");
+ while (1) {
+ if (cpu_wait)
+ cpu_wait();
+ }
+}
+
+static int __init mips_reboot_setup(void)
+{
+ _machine_restart = loongson_restart;
+ _machine_halt = loongson_halt;
+ pm_power_off = loongson_poweroff;
+
+ return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c
new file mode 100644
index 00000000..a90d87c0
--- /dev/null
+++ b/arch/mips/loongson/common/rtc.c
@@ -0,0 +1,43 @@
+/*
+ * Lemote Fuloong platform support
+ *
+ * Copyright(c) 2010 Arnaud Patard <apatard@mandriva.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mc146818rtc.h>
+
+struct resource loongson_rtc_resources[] = {
+ {
+ .start = RTC_PORT(0),
+ .end = RTC_PORT(1),
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = RTC_IRQ,
+ .end = RTC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device loongson_rtc_device = {
+ .name = "rtc_cmos",
+ .id = -1,
+ .resource = loongson_rtc_resources,
+ .num_resources = ARRAY_SIZE(loongson_rtc_resources),
+};
+
+
+static int __init loongson_rtc_platform_init(void)
+{
+ platform_device_register(&loongson_rtc_device);
+ return 0;
+}
+
+device_initcall(loongson_rtc_platform_init);
diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c
new file mode 100644
index 00000000..75808731
--- /dev/null
+++ b/arch/mips/loongson/common/serial.c
@@ -0,0 +1,76 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Yan hua (yanhua@lemote.com)
+ * Author: Wu Zhangjin (wuzhangjin@gmail.com)
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+#define PORT(int) \
+{ \
+ .irq = int, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
+ .regshift = 0, \
+}
+
+#define PORT_M(int) \
+{ \
+ .irq = MIPS_CPU_IRQ_BASE + (int), \
+ .uartclk = 3686400, \
+ .iotype = UPIO_MEM, \
+ .membase = (void __iomem *)NULL, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
+ .regshift = 0, \
+}
+
+static struct plat_serial8250_port uart8250_data[][2] = {
+ [MACH_LOONGSON_UNKNOWN] {},
+ [MACH_LEMOTE_FL2E] {PORT(4), {} },
+ [MACH_LEMOTE_FL2F] {PORT(3), {} },
+ [MACH_LEMOTE_ML2F7] {PORT_M(3), {} },
+ [MACH_LEMOTE_YL2F89] {PORT_M(3), {} },
+ [MACH_DEXXON_GDIUM2F10] {PORT_M(3), {} },
+ [MACH_LEMOTE_NAS] {PORT_M(3), {} },
+ [MACH_LEMOTE_LL2F] {PORT(3), {} },
+ [MACH_LOONGSON_END] {},
+};
+
+static struct platform_device uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+};
+
+static int __init serial_init(void)
+{
+ unsigned char iotype;
+
+ iotype = uart8250_data[mips_machtype][0].iotype;
+
+ if (UPIO_MEM == iotype)
+ uart8250_data[mips_machtype][0].membase =
+ (void __iomem *)_loongson_uart_base;
+ else if (UPIO_PORT == iotype)
+ uart8250_data[mips_machtype][0].iobase =
+ loongson_uart_base - LOONGSON_PCIIO_BASE;
+
+ uart8250_device.dev.platform_data = uart8250_data[mips_machtype];
+
+ return platform_device_register(&uart8250_device);
+}
+
+device_initcall(serial_init);
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c
new file mode 100644
index 00000000..27d826bc
--- /dev/null
+++ b/arch/mips/loongson/common/setup.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/module.h>
+
+#include <asm/wbflush.h>
+
+#include <loongson.h>
+
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#include <linux/screen_info.h>
+#endif
+
+void (*__wbflush)(void);
+EXPORT_SYMBOL(__wbflush);
+
+static void wbflush_loongson(void)
+{
+ asm(".set\tpush\n\t"
+ ".set\tnoreorder\n\t"
+ ".set mips3\n\t"
+ "sync\n\t"
+ "nop\n\t"
+ ".set\tpop\n\t"
+ ".set mips0\n\t");
+}
+
+void __init plat_mem_setup(void)
+{
+ __wbflush = wbflush_loongson;
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+ conswitchp = &vga_con;
+
+ screen_info = (struct screen_info) {
+ .orig_x = 0,
+ .orig_y = 25,
+ .orig_video_cols = 80,
+ .orig_video_lines = 25,
+ .orig_video_isVGA = VIDEO_TYPE_VGAC,
+ .orig_video_points = 16,
+ };
+#elif defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+#endif
+}
diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c
new file mode 100644
index 00000000..9fdd01f6
--- /dev/null
+++ b/arch/mips/loongson/common/time.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <asm/mc146818-time.h>
+#include <asm/time.h>
+
+#include <loongson.h>
+#include <cs5536/cs5536_mfgpt.h>
+
+void __init plat_time_init(void)
+{
+ /* setup mips r4k timer */
+ mips_hpt_frequency = cpu_clock_freq / 2;
+
+ setup_mfgpt0_timer();
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+ ts->tv_sec = mc146818_get_cmos_time();
+ ts->tv_nsec = 0;
+}
diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c
new file mode 100644
index 00000000..d69ea54b
--- /dev/null
+++ b/arch/mips/loongson/common/uart_base.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+/* ioremapped */
+unsigned long _loongson_uart_base;
+EXPORT_SYMBOL(_loongson_uart_base);
+/* raw */
+unsigned long loongson_uart_base;
+EXPORT_SYMBOL(loongson_uart_base);
+
+void prom_init_loongson_uart_base(void)
+{
+ switch (mips_machtype) {
+ case MACH_LEMOTE_FL2E:
+ loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8;
+ break;
+ case MACH_LEMOTE_FL2F:
+ case MACH_LEMOTE_LL2F:
+ loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8;
+ break;
+ case MACH_LEMOTE_ML2F7:
+ case MACH_LEMOTE_YL2F89:
+ case MACH_DEXXON_GDIUM2F10:
+ case MACH_LEMOTE_NAS:
+ default:
+ /* The CPU provided serial port */
+ loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8;
+ break;
+ }
+
+ _loongson_uart_base =
+ (unsigned long)ioremap_nocache(loongson_uart_base, 8);
+}
diff --git a/arch/mips/loongson/fuloong-2e/Makefile b/arch/mips/loongson/fuloong-2e/Makefile
new file mode 100644
index 00000000..b7622720
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2e/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for Lemote Fuloong2e mini-PC board.
+#
+
+obj-y += irq.o reset.o
diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c
new file mode 100644
index 00000000..d61a0422
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2e/irq.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/interrupt.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+
+#include <loongson.h>
+
+static void i8259_irqdispatch(void)
+{
+ int irq;
+
+ irq = i8259_irq();
+ if (irq >= 0)
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+}
+
+asmlinkage void mach_irq_dispatch(unsigned int pending)
+{
+ if (pending & CAUSEF_IP7)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+ else if (pending & CAUSEF_IP6) /* perf counter loverflow */
+ do_perfcnt_IRQ();
+ else if (pending & CAUSEF_IP5)
+ i8259_irqdispatch();
+ else if (pending & CAUSEF_IP2)
+ bonito_irqdispatch();
+ else
+ spurious_interrupt();
+}
+
+static struct irqaction cascade_irqaction = {
+ .handler = no_action,
+ .name = "cascade",
+};
+
+void __init mach_init_irq(void)
+{
+ /* init all controller
+ * 0-15 ------> i8259 interrupt
+ * 16-23 ------> mips cpu interrupt
+ * 32-63 ------> bonito irq
+ */
+
+ /* most bonito irq should be level triggered */
+ LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR |
+ LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES;
+
+ /* Sets the first-level interrupt dispatcher. */
+ mips_cpu_irq_init();
+ init_i8259_irqs();
+ bonito_irq_init();
+
+ /* bonito irq at IP2 */
+ setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
+ /* 8259 irq at IP5 */
+ setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
+}
diff --git a/arch/mips/loongson/fuloong-2e/reset.c b/arch/mips/loongson/fuloong-2e/reset.c
new file mode 100644
index 00000000..bc39ec62
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2e/reset.c
@@ -0,0 +1,23 @@
+/* Board-specific reboot/shutdown routines
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <loongson.h>
+
+void mach_prepare_reboot(void)
+{
+ LOONGSON_GENCFG &= ~(1 << 2);
+ LOONGSON_GENCFG |= (1 << 2);
+}
+
+void mach_prepare_shutdown(void)
+{
+}
diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile
new file mode 100644
index 00000000..8699a53f
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for lemote loongson2f family machines
+#
+
+obj-y += machtype.o irq.o reset.o ec_kb3310b.o
+
+#
+# Suspend Support
+#
+
+obj-$(CONFIG_LOONGSON_SUSPEND) += pm.o
diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.c b/arch/mips/loongson/lemote-2f/ec_kb3310b.c
new file mode 100644
index 00000000..64057244
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/ec_kb3310b.c
@@ -0,0 +1,130 @@
+/*
+ * Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook
+ *
+ * Copyright (C) 2008 Lemote Inc.
+ * Author: liujl <liujl@lemote.com>, 2008-04-20
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+
+#include "ec_kb3310b.h"
+
+static DEFINE_SPINLOCK(index_access_lock);
+static DEFINE_SPINLOCK(port_access_lock);
+
+unsigned char ec_read(unsigned short addr)
+{
+ unsigned char value;
+ unsigned long flags;
+
+ spin_lock_irqsave(&index_access_lock, flags);
+ outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
+ outb((addr & 0x00ff), EC_IO_PORT_LOW);
+ value = inb(EC_IO_PORT_DATA);
+ spin_unlock_irqrestore(&index_access_lock, flags);
+
+ return value;
+}
+EXPORT_SYMBOL_GPL(ec_read);
+
+void ec_write(unsigned short addr, unsigned char val)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&index_access_lock, flags);
+ outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
+ outb((addr & 0x00ff), EC_IO_PORT_LOW);
+ outb(val, EC_IO_PORT_DATA);
+ /* flush the write action */
+ inb(EC_IO_PORT_DATA);
+ spin_unlock_irqrestore(&index_access_lock, flags);
+
+ return;
+}
+EXPORT_SYMBOL_GPL(ec_write);
+
+/*
+ * This function is used for EC command writes and corresponding status queries.
+ */
+int ec_query_seq(unsigned char cmd)
+{
+ int timeout;
+ unsigned char status;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&port_access_lock, flags);
+
+ /* make chip goto reset mode */
+ udelay(EC_REG_DELAY);
+ outb(cmd, EC_CMD_PORT);
+ udelay(EC_REG_DELAY);
+
+ /* check if the command is received by ec */
+ timeout = EC_CMD_TIMEOUT;
+ status = inb(EC_STS_PORT);
+ while (timeout-- && (status & (1 << 1))) {
+ status = inb(EC_STS_PORT);
+ udelay(EC_REG_DELAY);
+ }
+
+ spin_unlock_irqrestore(&port_access_lock, flags);
+
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
+ ret = -EINVAL;
+ } else
+ printk(KERN_INFO
+ "(%x/%d)ec issued command %d status : 0x%x\n",
+ timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ec_query_seq);
+
+/*
+ * Send query command to EC to get the proper event number
+ */
+int ec_query_event_num(void)
+{
+ return ec_query_seq(CMD_GET_EVENT_NUM);
+}
+EXPORT_SYMBOL(ec_query_event_num);
+
+/*
+ * Get event number from EC
+ *
+ * NOTE: This routine must follow the query_event_num function in the
+ * interrupt.
+ */
+int ec_get_event_num(void)
+{
+ int timeout = 100;
+ unsigned char value;
+ unsigned char status;
+
+ udelay(EC_REG_DELAY);
+ status = inb(EC_STS_PORT);
+ udelay(EC_REG_DELAY);
+ while (timeout-- && !(status & (1 << 0))) {
+ status = inb(EC_STS_PORT);
+ udelay(EC_REG_DELAY);
+ }
+ if (timeout <= 0) {
+ pr_info("%s: get event number timeout.\n", __func__);
+
+ return -EINVAL;
+ }
+ value = inb(EC_DAT_PORT);
+ udelay(EC_REG_DELAY);
+
+ return value;
+}
+EXPORT_SYMBOL(ec_get_event_num);
diff --git a/arch/mips/loongson/lemote-2f/ec_kb3310b.h b/arch/mips/loongson/lemote-2f/ec_kb3310b.h
new file mode 100644
index 00000000..1595a21b
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/ec_kb3310b.h
@@ -0,0 +1,188 @@
+/*
+ * KB3310B Embedded Controller
+ *
+ * Copyright (C) 2008 Lemote Inc.
+ * Author: liujl <liujl@lemote.com>, 2008-03-14
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _EC_KB3310B_H
+#define _EC_KB3310B_H
+
+extern unsigned char ec_read(unsigned short addr);
+extern void ec_write(unsigned short addr, unsigned char val);
+extern int ec_query_seq(unsigned char cmd);
+extern int ec_query_event_num(void);
+extern int ec_get_event_num(void);
+
+typedef int (*sci_handler) (int status);
+extern sci_handler yeeloong_report_lid_status;
+
+#define SCI_IRQ_NUM 0x0A
+
+/*
+ * The following registers are determined by the EC index configuration.
+ * 1, fill the PORT_HIGH as EC register high part.
+ * 2, fill the PORT_LOW as EC register low part.
+ * 3, fill the PORT_DATA as EC register write data or get the data from it.
+ */
+#define EC_IO_PORT_HIGH 0x0381
+#define EC_IO_PORT_LOW 0x0382
+#define EC_IO_PORT_DATA 0x0383
+
+/*
+ * EC delay time is 500us for register and status access
+ */
+#define EC_REG_DELAY 500 /* unit : us */
+#define EC_CMD_TIMEOUT 0x1000
+
+/*
+ * EC access port for SCI communication
+ */
+#define EC_CMD_PORT 0x66
+#define EC_STS_PORT 0x66
+#define EC_DAT_PORT 0x62
+#define CMD_INIT_IDLE_MODE 0xdd
+#define CMD_EXIT_IDLE_MODE 0xdf
+#define CMD_INIT_RESET_MODE 0xd8
+#define CMD_REBOOT_SYSTEM 0x8c
+#define CMD_GET_EVENT_NUM 0x84
+#define CMD_PROGRAM_PIECE 0xda
+
+/* temperature & fan registers */
+#define REG_TEMPERATURE_VALUE 0xF458
+#define REG_FAN_AUTO_MAN_SWITCH 0xF459
+#define BIT_FAN_AUTO 0
+#define BIT_FAN_MANUAL 1
+#define REG_FAN_CONTROL 0xF4D2
+#define BIT_FAN_CONTROL_ON (1 << 0)
+#define BIT_FAN_CONTROL_OFF (0 << 0)
+#define REG_FAN_STATUS 0xF4DA
+#define BIT_FAN_STATUS_ON (1 << 0)
+#define BIT_FAN_STATUS_OFF (0 << 0)
+#define REG_FAN_SPEED_HIGH 0xFE22
+#define REG_FAN_SPEED_LOW 0xFE23
+#define REG_FAN_SPEED_LEVEL 0xF4CC
+/* fan speed divider */
+#define FAN_SPEED_DIVIDER 480000 /* (60*1000*1000/62.5/2)*/
+
+/* battery registers */
+#define REG_BAT_DESIGN_CAP_HIGH 0xF77D
+#define REG_BAT_DESIGN_CAP_LOW 0xF77E
+#define REG_BAT_FULLCHG_CAP_HIGH 0xF780
+#define REG_BAT_FULLCHG_CAP_LOW 0xF781
+#define REG_BAT_DESIGN_VOL_HIGH 0xF782
+#define REG_BAT_DESIGN_VOL_LOW 0xF783
+#define REG_BAT_CURRENT_HIGH 0xF784
+#define REG_BAT_CURRENT_LOW 0xF785
+#define REG_BAT_VOLTAGE_HIGH 0xF786
+#define REG_BAT_VOLTAGE_LOW 0xF787
+#define REG_BAT_TEMPERATURE_HIGH 0xF788
+#define REG_BAT_TEMPERATURE_LOW 0xF789
+#define REG_BAT_RELATIVE_CAP_HIGH 0xF492
+#define REG_BAT_RELATIVE_CAP_LOW 0xF493
+#define REG_BAT_VENDOR 0xF4C4
+#define FLAG_BAT_VENDOR_SANYO 0x01
+#define FLAG_BAT_VENDOR_SIMPLO 0x02
+#define REG_BAT_CELL_COUNT 0xF4C6
+#define FLAG_BAT_CELL_3S1P 0x03
+#define FLAG_BAT_CELL_3S2P 0x06
+#define REG_BAT_CHARGE 0xF4A2
+#define FLAG_BAT_CHARGE_DISCHARGE 0x01
+#define FLAG_BAT_CHARGE_CHARGE 0x02
+#define FLAG_BAT_CHARGE_ACPOWER 0x00
+#define REG_BAT_STATUS 0xF4B0
+#define BIT_BAT_STATUS_LOW (1 << 5)
+#define BIT_BAT_STATUS_DESTROY (1 << 2)
+#define BIT_BAT_STATUS_FULL (1 << 1)
+#define BIT_BAT_STATUS_IN (1 << 0)
+#define REG_BAT_CHARGE_STATUS 0xF4B1
+#define BIT_BAT_CHARGE_STATUS_OVERTEMP (1 << 2)
+#define BIT_BAT_CHARGE_STATUS_PRECHG (1 << 1)
+#define REG_BAT_STATE 0xF482
+#define BIT_BAT_STATE_CHARGING (1 << 1)
+#define BIT_BAT_STATE_DISCHARGING (1 << 0)
+#define REG_BAT_POWER 0xF440
+#define BIT_BAT_POWER_S3 (1 << 2)
+#define BIT_BAT_POWER_ON (1 << 1)
+#define BIT_BAT_POWER_ACIN (1 << 0)
+
+/* other registers */
+/* Audio: rd/wr */
+#define REG_AUDIO_VOLUME 0xF46C
+#define REG_AUDIO_MUTE 0xF4E7
+#define REG_AUDIO_BEEP 0xF4D0
+/* USB port power or not: rd/wr */
+#define REG_USB0_FLAG 0xF461
+#define REG_USB1_FLAG 0xF462
+#define REG_USB2_FLAG 0xF463
+#define BIT_USB_FLAG_ON 1
+#define BIT_USB_FLAG_OFF 0
+/* LID */
+#define REG_LID_DETECT 0xF4BD
+#define BIT_LID_DETECT_ON 1
+#define BIT_LID_DETECT_OFF 0
+/* CRT */
+#define REG_CRT_DETECT 0xF4AD
+#define BIT_CRT_DETECT_PLUG 1
+#define BIT_CRT_DETECT_UNPLUG 0
+/* LCD backlight brightness adjust: 9 levels */
+#define REG_DISPLAY_BRIGHTNESS 0xF4F5
+/* Black screen Status */
+#define BIT_DISPLAY_LCD_ON 1
+#define BIT_DISPLAY_LCD_OFF 0
+/* LCD backlight control: off/restore */
+#define REG_BACKLIGHT_CTRL 0xF7BD
+#define BIT_BACKLIGHT_ON 1
+#define BIT_BACKLIGHT_OFF 0
+/* Reset the machine auto-clear: rd/wr */
+#define REG_RESET 0xF4EC
+#define BIT_RESET_ON 1
+/* Light the led: rd/wr */
+#define REG_LED 0xF4C8
+#define BIT_LED_RED_POWER (1 << 0)
+#define BIT_LED_ORANGE_POWER (1 << 1)
+#define BIT_LED_GREEN_CHARGE (1 << 2)
+#define BIT_LED_RED_CHARGE (1 << 3)
+#define BIT_LED_NUMLOCK (1 << 4)
+/* Test led mode, all led on/off */
+#define REG_LED_TEST 0xF4C2
+#define BIT_LED_TEST_IN 1
+#define BIT_LED_TEST_OUT 0
+/* Camera on/off */
+#define REG_CAMERA_STATUS 0xF46A
+#define BIT_CAMERA_STATUS_ON 1
+#define BIT_CAMERA_STATUS_OFF 0
+#define REG_CAMERA_CONTROL 0xF7B7
+#define BIT_CAMERA_CONTROL_OFF 0
+#define BIT_CAMERA_CONTROL_ON 1
+/* Wlan Status */
+#define REG_WLAN 0xF4FA
+#define BIT_WLAN_ON 1
+#define BIT_WLAN_OFF 0
+#define REG_DISPLAY_LCD 0xF79F
+
+/* SCI Event Number from EC */
+enum {
+ EVENT_LID = 0x23, /* LID open/close */
+ EVENT_DISPLAY_TOGGLE, /* Fn+F3 for display switch */
+ EVENT_SLEEP, /* Fn+F1 for entering sleep mode */
+ EVENT_OVERTEMP, /* Over-temperature happened */
+ EVENT_CRT_DETECT, /* CRT is connected */
+ EVENT_CAMERA, /* Camera on/off */
+ EVENT_USB_OC2, /* USB2 Over Current occurred */
+ EVENT_USB_OC0, /* USB0 Over Current occurred */
+ EVENT_BLACK_SCREEN, /* Turn on/off backlight */
+ EVENT_AUDIO_MUTE, /* Mute on/off */
+ EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */
+ EVENT_AC_BAT, /* AC & Battery relative issue */
+ EVENT_AUDIO_VOLUME, /* Volume adjust */
+ EVENT_WLAN, /* Wlan on/off */
+ EVENT_END
+};
+
+#endif /* !_EC_KB3310B_H */
diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c
new file mode 100644
index 00000000..081db102
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/irq.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007 Lemote Inc.
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* cpu timer */
+#define LOONGSON_NORTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 6) /* bonito */
+#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 3) /* cpu serial port */
+#define LOONGSON_SOUTH_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 2) /* i8259 */
+
+#define LOONGSON_INT_BIT_INT0 (1 << 11)
+#define LOONGSON_INT_BIT_INT1 (1 << 12)
+
+/*
+ * The generic i8259_irq() make the kernel hang on booting. Since we cannot
+ * get the irq via the IRR directly, we access the ISR instead.
+ */
+int mach_i8259_irq(void)
+{
+ int irq, isr;
+
+ irq = -1;
+
+ if ((LOONGSON_INTISR & LOONGSON_INTEN) & LOONGSON_INT_BIT_INT0) {
+ raw_spin_lock(&i8259A_lock);
+ isr = inb(PIC_MASTER_CMD) &
+ ~inb(PIC_MASTER_IMR) & ~(1 << PIC_CASCADE_IR);
+ if (!isr)
+ isr = (inb(PIC_SLAVE_CMD) & ~inb(PIC_SLAVE_IMR)) << 8;
+ irq = ffs(isr) - 1;
+ if (unlikely(irq == 7)) {
+ /*
+ * This may be a spurious interrupt.
+ *
+ * Read the interrupt status register (ISR). If the most
+ * significant bit is not set then there is no valid
+ * interrupt.
+ */
+ outb(0x0B, PIC_MASTER_ISR); /* ISR register */
+ if (~inb(PIC_MASTER_ISR) & 0x80)
+ irq = -1;
+ }
+ raw_spin_unlock(&i8259A_lock);
+ }
+
+ return irq;
+}
+EXPORT_SYMBOL(mach_i8259_irq);
+
+static void i8259_irqdispatch(void)
+{
+ int irq;
+
+ irq = mach_i8259_irq();
+ if (irq >= 0)
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+}
+
+void mach_irq_dispatch(unsigned int pending)
+{
+ if (pending & CAUSEF_IP7)
+ do_IRQ(LOONGSON_TIMER_IRQ);
+ else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */
+ do_perfcnt_IRQ();
+ bonito_irqdispatch();
+ } else if (pending & CAUSEF_IP3) /* CPU UART */
+ do_IRQ(LOONGSON_UART_IRQ);
+ else if (pending & CAUSEF_IP2) /* South Bridge */
+ i8259_irqdispatch();
+ else
+ spurious_interrupt();
+}
+
+static irqreturn_t ip6_action(int cpl, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+
+struct irqaction ip6_irqaction = {
+ .handler = ip6_action,
+ .name = "cascade",
+ .flags = IRQF_SHARED,
+};
+
+struct irqaction cascade_irqaction = {
+ .handler = no_action,
+ .name = "cascade",
+};
+
+void __init mach_init_irq(void)
+{
+ /* init all controller
+ * 0-15 ------> i8259 interrupt
+ * 16-23 ------> mips cpu interrupt
+ * 32-63 ------> bonito irq
+ */
+
+ /* setup cs5536 as high level trigger */
+ LOONGSON_INTPOL = LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1;
+ LOONGSON_INTEDGE &= ~(LOONGSON_INT_BIT_INT0 | LOONGSON_INT_BIT_INT1);
+
+ /* Sets the first-level interrupt dispatcher. */
+ mips_cpu_irq_init();
+ init_i8259_irqs();
+ bonito_irq_init();
+
+ /* setup north bridge irq (bonito) */
+ setup_irq(LOONGSON_NORTH_BRIDGE_IRQ, &ip6_irqaction);
+ /* setup source bridge irq (i8259) */
+ setup_irq(LOONGSON_SOUTH_BRIDGE_IRQ, &cascade_irqaction);
+}
diff --git a/arch/mips/loongson/lemote-2f/machtype.c b/arch/mips/loongson/lemote-2f/machtype.c
new file mode 100644
index 00000000..e860a270
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/machtype.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+void __init mach_prom_init_machtype(void)
+{
+ /* We share the same kernel image file among Lemote 2F family
+ * of machines, and provide the machtype= kernel command line
+ * to users to indicate their machine, this command line will
+ * be passed by the latest PMON automatically. and fortunately,
+ * up to now, we can get the machine type from the PMON_VER=
+ * commandline directly except the NAS machine, In the old
+ * machines, this will help the users a lot.
+ *
+ * If no "machtype=" passed, get machine type from "PMON_VER=".
+ * PMON_VER=LM8089 Lemote 8.9'' netbook
+ * LM8101 Lemote 10.1'' netbook
+ * (The above two netbooks have the same kernel support)
+ * LM6XXX Lemote FuLoong(2F) box series
+ * LM9XXX Lemote LynLoong PC series
+ */
+ if (strstr(arcs_cmdline, "PMON_VER=LM")) {
+ if (strstr(arcs_cmdline, "PMON_VER=LM8"))
+ mips_machtype = MACH_LEMOTE_YL2F89;
+ else if (strstr(arcs_cmdline, "PMON_VER=LM6"))
+ mips_machtype = MACH_LEMOTE_FL2F;
+ else if (strstr(arcs_cmdline, "PMON_VER=LM9"))
+ mips_machtype = MACH_LEMOTE_LL2F;
+ else
+ mips_machtype = MACH_LEMOTE_NAS;
+
+ strcat(arcs_cmdline, " machtype=");
+ strcat(arcs_cmdline, get_system_type());
+ strcat(arcs_cmdline, " ");
+ }
+}
diff --git a/arch/mips/loongson/lemote-2f/pm.c b/arch/mips/loongson/lemote-2f/pm.c
new file mode 100644
index 00000000..cac4d382
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/pm.c
@@ -0,0 +1,149 @@
+/*
+ * Lemote loongson2f family machines' specific suspend support
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/suspend.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/i8042.h>
+#include <linux/module.h>
+
+#include <asm/i8259.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+#include <cs5536/cs5536_mfgpt.h>
+#include "ec_kb3310b.h"
+
+#define I8042_KBD_IRQ 1
+#define I8042_CTR_KBDINT 0x01
+#define I8042_CTR_KBDDIS 0x10
+
+static unsigned char i8042_ctr;
+
+static int i8042_enable_kbd_port(void)
+{
+ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_RCTR)) {
+ pr_err("i8042.c: Can't read CTR while enabling i8042 kbd port."
+ "\n");
+ return -EIO;
+ }
+
+ i8042_ctr &= ~I8042_CTR_KBDDIS;
+ i8042_ctr |= I8042_CTR_KBDINT;
+
+ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
+ i8042_ctr &= ~I8042_CTR_KBDINT;
+ i8042_ctr |= I8042_CTR_KBDDIS;
+ pr_err("i8042.c: Failed to enable KBD port.\n");
+
+ return -EIO;
+ }
+
+ return 0;
+}
+
+void setup_wakeup_events(void)
+{
+ int irq_mask;
+
+ switch (mips_machtype) {
+ case MACH_LEMOTE_ML2F7:
+ case MACH_LEMOTE_YL2F89:
+ /* open the keyboard irq in i8259A */
+ outb((0xff & ~(1 << I8042_KBD_IRQ)), PIC_MASTER_IMR);
+ irq_mask = inb(PIC_MASTER_IMR);
+
+ /* enable keyboard port */
+ i8042_enable_kbd_port();
+
+ /* Wakeup CPU via SCI lid open event */
+ outb(irq_mask & ~(1 << PIC_CASCADE_IR), PIC_MASTER_IMR);
+ inb(PIC_MASTER_IMR);
+ outb(0xff & ~(1 << (SCI_IRQ_NUM - 8)), PIC_SLAVE_IMR);
+ inb(PIC_SLAVE_IMR);
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+static struct delayed_work lid_task;
+static int initialized;
+/* yeeloong_report_lid_status will be implemented in yeeloong_laptop.c */
+sci_handler yeeloong_report_lid_status;
+EXPORT_SYMBOL(yeeloong_report_lid_status);
+static void yeeloong_lid_update_task(struct work_struct *work)
+{
+ if (yeeloong_report_lid_status)
+ yeeloong_report_lid_status(BIT_LID_DETECT_ON);
+}
+
+int wakeup_loongson(void)
+{
+ int irq;
+
+ /* query the interrupt number */
+ irq = mach_i8259_irq();
+ if (irq < 0)
+ return 0;
+
+ printk(KERN_INFO "%s: irq = %d\n", __func__, irq);
+
+ if (irq == I8042_KBD_IRQ)
+ return 1;
+ else if (irq == SCI_IRQ_NUM) {
+ int ret, sci_event;
+ /* query the event number */
+ ret = ec_query_seq(CMD_GET_EVENT_NUM);
+ if (ret < 0)
+ return 0;
+ sci_event = ec_get_event_num();
+ if (sci_event < 0)
+ return 0;
+ if (sci_event == EVENT_LID) {
+ int lid_status;
+ /* check the LID status */
+ lid_status = ec_read(REG_LID_DETECT);
+ /* wakeup cpu when people open the LID */
+ if (lid_status == BIT_LID_DETECT_ON) {
+ /* If we call it directly here, the WARNING
+ * will be sent out by getnstimeofday
+ * via "WARN_ON(timekeeping_suspended);"
+ * because we can not schedule in suspend mode.
+ */
+ if (initialized == 0) {
+ INIT_DELAYED_WORK(&lid_task,
+ yeeloong_lid_update_task);
+ initialized = 1;
+ }
+ schedule_delayed_work(&lid_task, 1);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void __weak mach_suspend(void)
+{
+ disable_mfgpt0_counter();
+}
+
+void __weak mach_resume(void)
+{
+ enable_mfgpt0_counter();
+}
diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c
new file mode 100644
index 00000000..36020a07
--- /dev/null
+++ b/arch/mips/loongson/lemote-2f/reset.c
@@ -0,0 +1,159 @@
+/* Board-specific reboot/shutdown routines
+ *
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+#include <cs5536/cs5536.h>
+#include "ec_kb3310b.h"
+
+static void reset_cpu(void)
+{
+ /*
+ * reset cpu to full speed, this is needed when enabling cpu frequency
+ * scalling
+ */
+ LOONGSON_CHIPCFG0 |= 0x7;
+}
+
+/* reset support for fuloong2f */
+
+static void fl2f_reboot(void)
+{
+ reset_cpu();
+
+ /* send a reset signal to south bridge.
+ *
+ * NOTE: if enable "Power Management" in kernel, rtl8169 will not reset
+ * normally with this reset operation and it will not work in PMON, but
+ * you can type halt command and then reboot, seems the hardware reset
+ * logic not work normally.
+ */
+ {
+ u32 hi, lo;
+ _rdmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), &hi, &lo);
+ lo |= 0x00000001;
+ _wrmsr(DIVIL_MSR_REG(DIVIL_SOFT_RESET), hi, lo);
+ }
+}
+
+static void fl2f_shutdown(void)
+{
+ u32 hi, lo, val;
+ int gpio_base;
+
+ /* get gpio base */
+ _rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);
+ gpio_base = lo & 0xff00;
+
+ /* make cs5536 gpio13 output enable */
+ val = inl(gpio_base + GPIOL_OUT_EN);
+ val &= ~(1 << (16 + 13));
+ val |= (1 << 13);
+ outl(val, gpio_base + GPIOL_OUT_EN);
+ mmiowb();
+ /* make cs5536 gpio13 output low level voltage. */
+ val = inl(gpio_base + GPIOL_OUT_VAL) & ~(1 << (13));
+ val |= (1 << (16 + 13));
+ outl(val, gpio_base + GPIOL_OUT_VAL);
+ mmiowb();
+}
+
+/* reset support for yeeloong2f and mengloong2f notebook */
+
+void ml2f_reboot(void)
+{
+ reset_cpu();
+
+ /* sending an reset signal to EC(embedded controller) */
+ ec_write(REG_RESET, BIT_RESET_ON);
+}
+
+#define yl2f89_reboot ml2f_reboot
+
+/* menglong(7inches) laptop has different shutdown logic from 8.9inches */
+#define EC_SHUTDOWN_IO_PORT_HIGH 0xff2d
+#define EC_SHUTDOWN_IO_PORT_LOW 0xff2e
+#define EC_SHUTDOWN_IO_PORT_DATA 0xff2f
+#define REG_SHUTDOWN_HIGH 0xFC
+#define REG_SHUTDOWN_LOW 0x29
+#define BIT_SHUTDOWN_ON (1 << 1)
+
+static void ml2f_shutdown(void)
+{
+ u8 val;
+ u64 i;
+
+ outb(REG_SHUTDOWN_HIGH, EC_SHUTDOWN_IO_PORT_HIGH);
+ outb(REG_SHUTDOWN_LOW, EC_SHUTDOWN_IO_PORT_LOW);
+ mmiowb();
+ val = inb(EC_SHUTDOWN_IO_PORT_DATA);
+ outb(val & (~BIT_SHUTDOWN_ON), EC_SHUTDOWN_IO_PORT_DATA);
+ mmiowb();
+ /* need enough wait here... how many microseconds needs? */
+ for (i = 0; i < 0x10000; i++)
+ delay();
+ outb(val | BIT_SHUTDOWN_ON, EC_SHUTDOWN_IO_PORT_DATA);
+ mmiowb();
+}
+
+static void yl2f89_shutdown(void)
+{
+ /* cpu-gpio0 output low */
+ LOONGSON_GPIODATA &= ~0x00000001;
+ /* cpu-gpio0 as output */
+ LOONGSON_GPIOIE &= ~0x00000001;
+}
+
+void mach_prepare_reboot(void)
+{
+ switch (mips_machtype) {
+ case MACH_LEMOTE_FL2F:
+ case MACH_LEMOTE_NAS:
+ case MACH_LEMOTE_LL2F:
+ fl2f_reboot();
+ break;
+ case MACH_LEMOTE_ML2F7:
+ ml2f_reboot();
+ break;
+ case MACH_LEMOTE_YL2F89:
+ yl2f89_reboot();
+ break;
+ default:
+ break;
+ }
+}
+
+void mach_prepare_shutdown(void)
+{
+ switch (mips_machtype) {
+ case MACH_LEMOTE_FL2F:
+ case MACH_LEMOTE_NAS:
+ case MACH_LEMOTE_LL2F:
+ fl2f_shutdown();
+ break;
+ case MACH_LEMOTE_ML2F7:
+ ml2f_shutdown();
+ break;
+ case MACH_LEMOTE_YL2F89:
+ yl2f89_shutdown();
+ break;
+ default:
+ break;
+ }
+}
diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile
new file mode 100644
index 00000000..96607230
--- /dev/null
+++ b/arch/mips/math-emu/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the Linux/MIPS kernel FPU emulation.
+#
+
+obj-y := cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
+ ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
+ dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
+ dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
+ sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
+ sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
+ dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
+
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
new file mode 100644
index 00000000..d32cb050
--- /dev/null
+++ b/arch/mips/math-emu/cp1emu.c
@@ -0,0 +1,1413 @@
+/*
+ * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator
+ *
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * A complete emulator for MIPS coprocessor 1 instructions. This is
+ * required for #float(switch) or #float(trap), where it catches all
+ * COP1 instructions via the "CoProcessor Unusable" exception.
+ *
+ * More surprisingly it is also required for #float(ieee), to help out
+ * the hardware fpu at the boundaries of the IEEE-754 representation
+ * (denormalised values, infinities, underflow, etc). It is made
+ * quite nasty because emulation of some non-COP1 instructions is
+ * required, e.g. in branch delay slots.
+ *
+ * Note if you know that you won't have an fpu, then you'll get much
+ * better performance by compiling with -msoft-float!
+ */
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/perf_event.h>
+
+#include <asm/inst.h>
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/mipsregs.h>
+#include <asm/fpu_emulator.h>
+#include <asm/uaccess.h>
+#include <asm/branch.h>
+
+#include "ieee754.h"
+
+/* Strap kernel emulator for full MIPS IV emulation */
+
+#ifdef __mips
+#undef __mips
+#endif
+#define __mips 4
+
+/* Function which emulates a floating point instruction. */
+
+static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
+ mips_instruction);
+
+#if __mips >= 4 && __mips != 32
+static int fpux_emu(struct pt_regs *,
+ struct mips_fpu_struct *, mips_instruction, void *__user *);
+#endif
+
+/* Further private data for which no space exists in mips_fpu_struct */
+
+#ifdef CONFIG_DEBUG_FS
+DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
+#endif
+
+/* Control registers */
+
+#define FPCREG_RID 0 /* $0 = revision id */
+#define FPCREG_CSR 31 /* $31 = csr */
+
+/* Determine rounding mode from the RM bits of the FCSR */
+#define modeindex(v) ((v) & FPU_CSR_RM)
+
+/* Convert Mips rounding mode (0..3) to IEEE library modes. */
+static const unsigned char ieee_rm[4] = {
+ [FPU_CSR_RN] = IEEE754_RN,
+ [FPU_CSR_RZ] = IEEE754_RZ,
+ [FPU_CSR_RU] = IEEE754_RU,
+ [FPU_CSR_RD] = IEEE754_RD,
+};
+/* Convert IEEE library modes to Mips rounding mode (0..3). */
+static const unsigned char mips_rm[4] = {
+ [IEEE754_RN] = FPU_CSR_RN,
+ [IEEE754_RZ] = FPU_CSR_RZ,
+ [IEEE754_RD] = FPU_CSR_RD,
+ [IEEE754_RU] = FPU_CSR_RU,
+};
+
+#if __mips >= 4
+/* convert condition code register number to csr bit */
+static const unsigned int fpucondbit[8] = {
+ FPU_CSR_COND0,
+ FPU_CSR_COND1,
+ FPU_CSR_COND2,
+ FPU_CSR_COND3,
+ FPU_CSR_COND4,
+ FPU_CSR_COND5,
+ FPU_CSR_COND6,
+ FPU_CSR_COND7
+};
+#endif
+
+
+/*
+ * Redundant with logic already in kernel/branch.c,
+ * embedded in compute_return_epc. At some point,
+ * a single subroutine should be used across both
+ * modules.
+ */
+static int isBranchInstr(mips_instruction * i)
+{
+ switch (MIPSInst_OPCODE(*i)) {
+ case spec_op:
+ switch (MIPSInst_FUNC(*i)) {
+ case jalr_op:
+ case jr_op:
+ return 1;
+ }
+ break;
+
+ case bcond_op:
+ switch (MIPSInst_RT(*i)) {
+ case bltz_op:
+ case bgez_op:
+ case bltzl_op:
+ case bgezl_op:
+ case bltzal_op:
+ case bgezal_op:
+ case bltzall_op:
+ case bgezall_op:
+ return 1;
+ }
+ break;
+
+ case j_op:
+ case jal_op:
+ case jalx_op:
+ case beq_op:
+ case bne_op:
+ case blez_op:
+ case bgtz_op:
+ case beql_op:
+ case bnel_op:
+ case blezl_op:
+ case bgtzl_op:
+ return 1;
+
+ case cop0_op:
+ case cop1_op:
+ case cop2_op:
+ case cop1x_op:
+ if (MIPSInst_RS(*i) == bc_op)
+ return 1;
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * In the Linux kernel, we support selection of FPR format on the
+ * basis of the Status.FR bit. If an FPU is not present, the FR bit
+ * is hardwired to zero, which would imply a 32-bit FPU even for
+ * 64-bit CPUs. For 64-bit kernels with no FPU we use TIF_32BIT_REGS
+ * as a proxy for the FR bit so that a 64-bit FPU is emulated. In any
+ * case, for a 32-bit kernel which uses the O32 MIPS ABI, only the
+ * even FPRs are used (Status.FR = 0).
+ */
+static inline int cop1_64bit(struct pt_regs *xcp)
+{
+ if (cpu_has_fpu)
+ return xcp->cp0_status & ST0_FR;
+#ifdef CONFIG_64BIT
+ return !test_thread_flag(TIF_32BIT_REGS);
+#else
+ return 0;
+#endif
+}
+
+#define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \
+ (int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32))
+
+#define SITOREG(si, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \
+ cop1_64bit(xcp) || !(x & 1) ? \
+ ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
+ ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
+
+#define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
+#define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
+
+#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
+#define SPTOREG(sp, x) SITOREG((sp).bits, x)
+#define DPFROMREG(dp, x) DIFROMREG((dp).bits, x)
+#define DPTOREG(dp, x) DITOREG((dp).bits, x)
+
+/*
+ * Emulate the single floating point instruction pointed at by EPC.
+ * Two instructions if the instruction is in a branch delay slot.
+ */
+
+static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ void *__user *fault_addr)
+{
+ mips_instruction ir;
+ unsigned long emulpc, contpc;
+ unsigned int cond;
+
+ if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGBUS;
+ }
+ if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGSEGV;
+ }
+
+ /* XXX NEC Vr54xx bug workaround */
+ if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
+ xcp->cp0_cause &= ~CAUSEF_BD;
+
+ if (xcp->cp0_cause & CAUSEF_BD) {
+ /*
+ * The instruction to be emulated is in a branch delay slot
+ * which means that we have to emulate the branch instruction
+ * BEFORE we do the cop1 instruction.
+ *
+ * This branch could be a COP1 branch, but in that case we
+ * would have had a trap for that instruction, and would not
+ * come through this route.
+ *
+ * Linux MIPS branch emulator operates on context, updating the
+ * cp0_epc.
+ */
+ emulpc = xcp->cp0_epc + 4; /* Snapshot emulation target */
+
+ if (__compute_return_epc(xcp)) {
+#ifdef CP1DBG
+ printk("failed to emulate branch at %p\n",
+ (void *) (xcp->cp0_epc));
+#endif
+ return SIGILL;
+ }
+ if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)emulpc;
+ return SIGBUS;
+ }
+ if (__get_user(ir, (mips_instruction __user *) emulpc)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)emulpc;
+ return SIGSEGV;
+ }
+ /* __compute_return_epc() will have updated cp0_epc */
+ contpc = xcp->cp0_epc;
+ /* In order not to confuse ptrace() et al, tweak context */
+ xcp->cp0_epc = emulpc - 4;
+ } else {
+ emulpc = xcp->cp0_epc;
+ contpc = xcp->cp0_epc + 4;
+ }
+
+ emul:
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
+ 1, 0, xcp, 0);
+ MIPS_FPU_EMU_INC_STATS(emulated);
+ switch (MIPSInst_OPCODE(ir)) {
+ case ldc1_op:{
+ u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ MIPSInst_SIMM(ir));
+ u64 val;
+
+ MIPS_FPU_EMU_INC_STATS(loads);
+
+ if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGBUS;
+ }
+ if (__get_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
+ DITOREG(val, MIPSInst_RT(ir));
+ break;
+ }
+
+ case sdc1_op:{
+ u64 __user *va = (u64 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ MIPSInst_SIMM(ir));
+ u64 val;
+
+ MIPS_FPU_EMU_INC_STATS(stores);
+ DIFROMREG(val, MIPSInst_RT(ir));
+ if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGBUS;
+ }
+ if (__put_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
+ break;
+ }
+
+ case lwc1_op:{
+ u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ MIPSInst_SIMM(ir));
+ u32 val;
+
+ MIPS_FPU_EMU_INC_STATS(loads);
+ if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGBUS;
+ }
+ if (__get_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
+ SITOREG(val, MIPSInst_RT(ir));
+ break;
+ }
+
+ case swc1_op:{
+ u32 __user *va = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
+ MIPSInst_SIMM(ir));
+ u32 val;
+
+ MIPS_FPU_EMU_INC_STATS(stores);
+ SIFROMREG(val, MIPSInst_RT(ir));
+ if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGBUS;
+ }
+ if (__put_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
+ break;
+ }
+
+ case cop1_op:
+ switch (MIPSInst_RS(ir)) {
+
+#if defined(__mips64)
+ case dmfc_op:
+ /* copregister fs -> gpr[rt] */
+ if (MIPSInst_RT(ir) != 0) {
+ DIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+ MIPSInst_RD(ir));
+ }
+ break;
+
+ case dmtc_op:
+ /* copregister fs <- rt */
+ DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
+ break;
+#endif
+
+ case mfc_op:
+ /* copregister rd -> gpr[rt] */
+ if (MIPSInst_RT(ir) != 0) {
+ SIFROMREG(xcp->regs[MIPSInst_RT(ir)],
+ MIPSInst_RD(ir));
+ }
+ break;
+
+ case mtc_op:
+ /* copregister rd <- rt */
+ SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
+ break;
+
+ case cfc_op:{
+ /* cop control register rd -> gpr[rt] */
+ u32 value;
+
+ if (MIPSInst_RD(ir) == FPCREG_CSR) {
+ value = ctx->fcr31;
+ value = (value & ~FPU_CSR_RM) |
+ mips_rm[modeindex(value)];
+#ifdef CSRTRACE
+ printk("%p gpr[%d]<-csr=%08x\n",
+ (void *) (xcp->cp0_epc),
+ MIPSInst_RT(ir), value);
+#endif
+ }
+ else if (MIPSInst_RD(ir) == FPCREG_RID)
+ value = 0;
+ else
+ value = 0;
+ if (MIPSInst_RT(ir))
+ xcp->regs[MIPSInst_RT(ir)] = value;
+ break;
+ }
+
+ case ctc_op:{
+ /* copregister rd <- rt */
+ u32 value;
+
+ if (MIPSInst_RT(ir) == 0)
+ value = 0;
+ else
+ value = xcp->regs[MIPSInst_RT(ir)];
+
+ /* we only have one writable control reg
+ */
+ if (MIPSInst_RD(ir) == FPCREG_CSR) {
+#ifdef CSRTRACE
+ printk("%p gpr[%d]->csr=%08x\n",
+ (void *) (xcp->cp0_epc),
+ MIPSInst_RT(ir), value);
+#endif
+
+ /*
+ * Don't write reserved bits,
+ * and convert to ieee library modes
+ */
+ ctx->fcr31 = (value &
+ ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
+ ieee_rm[modeindex(value)];
+ }
+ if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+ return SIGFPE;
+ }
+ break;
+ }
+
+ case bc_op:{
+ int likely = 0;
+
+ if (xcp->cp0_cause & CAUSEF_BD)
+ return SIGILL;
+
+#if __mips >= 4
+ cond = ctx->fcr31 & fpucondbit[MIPSInst_RT(ir) >> 2];
+#else
+ cond = ctx->fcr31 & FPU_CSR_COND;
+#endif
+ switch (MIPSInst_RT(ir) & 3) {
+ case bcfl_op:
+ likely = 1;
+ case bcf_op:
+ cond = !cond;
+ break;
+ case bctl_op:
+ likely = 1;
+ case bct_op:
+ break;
+ default:
+ /* thats an illegal instruction */
+ return SIGILL;
+ }
+
+ xcp->cp0_cause |= CAUSEF_BD;
+ if (cond) {
+ /* branch taken: emulate dslot
+ * instruction
+ */
+ xcp->cp0_epc += 4;
+ contpc = (xcp->cp0_epc +
+ (MIPSInst_SIMM(ir) << 2));
+
+ if (!access_ok(VERIFY_READ, xcp->cp0_epc,
+ sizeof(mips_instruction))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGBUS;
+ }
+ if (__get_user(ir,
+ (mips_instruction __user *) xcp->cp0_epc)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGSEGV;
+ }
+
+ switch (MIPSInst_OPCODE(ir)) {
+ case lwc1_op:
+ case swc1_op:
+#if (__mips >= 2 || defined(__mips64))
+ case ldc1_op:
+ case sdc1_op:
+#endif
+ case cop1_op:
+#if __mips >= 4 && __mips != 32
+ case cop1x_op:
+#endif
+ /* its one of ours */
+ goto emul;
+#if __mips >= 4
+ case spec_op:
+ if (MIPSInst_FUNC(ir) == movc_op)
+ goto emul;
+ break;
+#endif
+ }
+
+ /*
+ * Single step the non-cp1
+ * instruction in the dslot
+ */
+ return mips_dsemul(xcp, ir, contpc);
+ }
+ else {
+ /* branch not taken */
+ if (likely) {
+ /*
+ * branch likely nullifies
+ * dslot if not taken
+ */
+ xcp->cp0_epc += 4;
+ contpc += 4;
+ /*
+ * else continue & execute
+ * dslot as normal insn
+ */
+ }
+ }
+ break;
+ }
+
+ default:
+ if (!(MIPSInst_RS(ir) & 0x10))
+ return SIGILL;
+ {
+ int sig;
+
+ /* a real fpu computation instruction */
+ if ((sig = fpu_emu(xcp, ctx, ir)))
+ return sig;
+ }
+ }
+ break;
+
+#if __mips >= 4 && __mips != 32
+ case cop1x_op:{
+ int sig = fpux_emu(xcp, ctx, ir, fault_addr);
+ if (sig)
+ return sig;
+ break;
+ }
+#endif
+
+#if __mips >= 4
+ case spec_op:
+ if (MIPSInst_FUNC(ir) != movc_op)
+ return SIGILL;
+ cond = fpucondbit[MIPSInst_RT(ir) >> 2];
+ if (((ctx->fcr31 & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
+ xcp->regs[MIPSInst_RD(ir)] =
+ xcp->regs[MIPSInst_RS(ir)];
+ break;
+#endif
+
+ default:
+ return SIGILL;
+ }
+
+ /* we did it !! */
+ xcp->cp0_epc = contpc;
+ xcp->cp0_cause &= ~CAUSEF_BD;
+
+ return 0;
+}
+
+/*
+ * Conversion table from MIPS compare ops 48-63
+ * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
+ */
+static const unsigned char cmptab[8] = {
+ 0, /* cmp_0 (sig) cmp_sf */
+ IEEE754_CUN, /* cmp_un (sig) cmp_ngle */
+ IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */
+ IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */
+ IEEE754_CLT, /* cmp_olt (sig) cmp_lt */
+ IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */
+ IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */
+ IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
+};
+
+
+#if __mips >= 4 && __mips != 32
+
+/*
+ * Additional MIPS4 instructions
+ */
+
+#define DEF3OP(name, p, f1, f2, f3) \
+static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \
+ ieee754##p t) \
+{ \
+ struct _ieee754_csr ieee754_csr_save; \
+ s = f1(s, t); \
+ ieee754_csr_save = ieee754_csr; \
+ s = f2(s, r); \
+ ieee754_csr_save.cx |= ieee754_csr.cx; \
+ ieee754_csr_save.sx |= ieee754_csr.sx; \
+ s = f3(s); \
+ ieee754_csr.cx |= ieee754_csr_save.cx; \
+ ieee754_csr.sx |= ieee754_csr_save.sx; \
+ return s; \
+}
+
+static ieee754dp fpemu_dp_recip(ieee754dp d)
+{
+ return ieee754dp_div(ieee754dp_one(0), d);
+}
+
+static ieee754dp fpemu_dp_rsqrt(ieee754dp d)
+{
+ return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d));
+}
+
+static ieee754sp fpemu_sp_recip(ieee754sp s)
+{
+ return ieee754sp_div(ieee754sp_one(0), s);
+}
+
+static ieee754sp fpemu_sp_rsqrt(ieee754sp s)
+{
+ return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s));
+}
+
+DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add, );
+DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub, );
+DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
+DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
+DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add, );
+DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub, );
+DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
+DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
+
+static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ mips_instruction ir, void *__user *fault_addr)
+{
+ unsigned rcsr = 0; /* resulting csr */
+
+ MIPS_FPU_EMU_INC_STATS(cp1xops);
+
+ switch (MIPSInst_FMA_FFMT(ir)) {
+ case s_fmt:{ /* 0 */
+
+ ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp);
+ ieee754sp fd, fr, fs, ft;
+ u32 __user *va;
+ u32 val;
+
+ switch (MIPSInst_FUNC(ir)) {
+ case lwxc1_op:
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ xcp->regs[MIPSInst_FT(ir)]);
+
+ MIPS_FPU_EMU_INC_STATS(loads);
+ if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGBUS;
+ }
+ if (__get_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
+ SITOREG(val, MIPSInst_FD(ir));
+ break;
+
+ case swxc1_op:
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ xcp->regs[MIPSInst_FT(ir)]);
+
+ MIPS_FPU_EMU_INC_STATS(stores);
+
+ SIFROMREG(val, MIPSInst_FS(ir));
+ if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGBUS;
+ }
+ if (put_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
+ break;
+
+ case madd_s_op:
+ handler = fpemu_sp_madd;
+ goto scoptop;
+ case msub_s_op:
+ handler = fpemu_sp_msub;
+ goto scoptop;
+ case nmadd_s_op:
+ handler = fpemu_sp_nmadd;
+ goto scoptop;
+ case nmsub_s_op:
+ handler = fpemu_sp_nmsub;
+ goto scoptop;
+
+ scoptop:
+ SPFROMREG(fr, MIPSInst_FR(ir));
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ SPFROMREG(ft, MIPSInst_FT(ir));
+ fd = (*handler) (fr, fs, ft);
+ SPTOREG(fd, MIPSInst_FD(ir));
+
+ copcsr:
+ if (ieee754_cxtest(IEEE754_INEXACT))
+ rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
+ if (ieee754_cxtest(IEEE754_UNDERFLOW))
+ rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
+ if (ieee754_cxtest(IEEE754_OVERFLOW))
+ rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
+ if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+ rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+
+ ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
+ if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+ /*printk ("SIGFPE: fpu csr = %08x\n",
+ ctx->fcr31); */
+ return SIGFPE;
+ }
+
+ break;
+
+ default:
+ return SIGILL;
+ }
+ break;
+ }
+
+ case d_fmt:{ /* 1 */
+ ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp);
+ ieee754dp fd, fr, fs, ft;
+ u64 __user *va;
+ u64 val;
+
+ switch (MIPSInst_FUNC(ir)) {
+ case ldxc1_op:
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ xcp->regs[MIPSInst_FT(ir)]);
+
+ MIPS_FPU_EMU_INC_STATS(loads);
+ if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGBUS;
+ }
+ if (__get_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
+ DITOREG(val, MIPSInst_FD(ir));
+ break;
+
+ case sdxc1_op:
+ va = (void __user *) (xcp->regs[MIPSInst_FR(ir)] +
+ xcp->regs[MIPSInst_FT(ir)]);
+
+ MIPS_FPU_EMU_INC_STATS(stores);
+ DIFROMREG(val, MIPSInst_FS(ir));
+ if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGBUS;
+ }
+ if (__put_user(val, va)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = va;
+ return SIGSEGV;
+ }
+ break;
+
+ case madd_d_op:
+ handler = fpemu_dp_madd;
+ goto dcoptop;
+ case msub_d_op:
+ handler = fpemu_dp_msub;
+ goto dcoptop;
+ case nmadd_d_op:
+ handler = fpemu_dp_nmadd;
+ goto dcoptop;
+ case nmsub_d_op:
+ handler = fpemu_dp_nmsub;
+ goto dcoptop;
+
+ dcoptop:
+ DPFROMREG(fr, MIPSInst_FR(ir));
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ DPFROMREG(ft, MIPSInst_FT(ir));
+ fd = (*handler) (fr, fs, ft);
+ DPTOREG(fd, MIPSInst_FD(ir));
+ goto copcsr;
+
+ default:
+ return SIGILL;
+ }
+ break;
+ }
+
+ case 0x7: /* 7 */
+ if (MIPSInst_FUNC(ir) != pfetch_op) {
+ return SIGILL;
+ }
+ /* ignore prefx operation */
+ break;
+
+ default:
+ return SIGILL;
+ }
+
+ return 0;
+}
+#endif
+
+
+
+/*
+ * Emulate a single COP1 arithmetic instruction.
+ */
+static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ mips_instruction ir)
+{
+ int rfmt; /* resulting format */
+ unsigned rcsr = 0; /* resulting csr */
+ unsigned cond;
+ union {
+ ieee754dp d;
+ ieee754sp s;
+ int w;
+#ifdef __mips64
+ s64 l;
+#endif
+ } rv; /* resulting value */
+
+ MIPS_FPU_EMU_INC_STATS(cp1ops);
+ switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {
+ case s_fmt:{ /* 0 */
+ union {
+ ieee754sp(*b) (ieee754sp, ieee754sp);
+ ieee754sp(*u) (ieee754sp);
+ } handler;
+
+ switch (MIPSInst_FUNC(ir)) {
+ /* binary ops */
+ case fadd_op:
+ handler.b = ieee754sp_add;
+ goto scopbop;
+ case fsub_op:
+ handler.b = ieee754sp_sub;
+ goto scopbop;
+ case fmul_op:
+ handler.b = ieee754sp_mul;
+ goto scopbop;
+ case fdiv_op:
+ handler.b = ieee754sp_div;
+ goto scopbop;
+
+ /* unary ops */
+#if __mips >= 2 || defined(__mips64)
+ case fsqrt_op:
+ handler.u = ieee754sp_sqrt;
+ goto scopuop;
+#endif
+#if __mips >= 4 && __mips != 32
+ case frsqrt_op:
+ handler.u = fpemu_sp_rsqrt;
+ goto scopuop;
+ case frecip_op:
+ handler.u = fpemu_sp_recip;
+ goto scopuop;
+#endif
+#if __mips >= 4
+ case fmovc_op:
+ cond = fpucondbit[MIPSInst_FT(ir) >> 2];
+ if (((ctx->fcr31 & cond) != 0) !=
+ ((MIPSInst_FT(ir) & 1) != 0))
+ return 0;
+ SPFROMREG(rv.s, MIPSInst_FS(ir));
+ break;
+ case fmovz_op:
+ if (xcp->regs[MIPSInst_FT(ir)] != 0)
+ return 0;
+ SPFROMREG(rv.s, MIPSInst_FS(ir));
+ break;
+ case fmovn_op:
+ if (xcp->regs[MIPSInst_FT(ir)] == 0)
+ return 0;
+ SPFROMREG(rv.s, MIPSInst_FS(ir));
+ break;
+#endif
+ case fabs_op:
+ handler.u = ieee754sp_abs;
+ goto scopuop;
+ case fneg_op:
+ handler.u = ieee754sp_neg;
+ goto scopuop;
+ case fmov_op:
+ /* an easy one */
+ SPFROMREG(rv.s, MIPSInst_FS(ir));
+ goto copcsr;
+
+ /* binary op on handler */
+ scopbop:
+ {
+ ieee754sp fs, ft;
+
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ SPFROMREG(ft, MIPSInst_FT(ir));
+
+ rv.s = (*handler.b) (fs, ft);
+ goto copcsr;
+ }
+ scopuop:
+ {
+ ieee754sp fs;
+
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ rv.s = (*handler.u) (fs);
+ goto copcsr;
+ }
+ copcsr:
+ if (ieee754_cxtest(IEEE754_INEXACT))
+ rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;
+ if (ieee754_cxtest(IEEE754_UNDERFLOW))
+ rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;
+ if (ieee754_cxtest(IEEE754_OVERFLOW))
+ rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;
+ if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
+ rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;
+ if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
+ rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;
+ break;
+
+ /* unary conv ops */
+ case fcvts_op:
+ return SIGILL; /* not defined */
+ case fcvtd_op:{
+ ieee754sp fs;
+
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ rv.d = ieee754dp_fsp(fs);
+ rfmt = d_fmt;
+ goto copcsr;
+ }
+ case fcvtw_op:{
+ ieee754sp fs;
+
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ rv.w = ieee754sp_tint(fs);
+ rfmt = w_fmt;
+ goto copcsr;
+ }
+
+#if __mips >= 2 || defined(__mips64)
+ case fround_op:
+ case ftrunc_op:
+ case fceil_op:
+ case ffloor_op:{
+ unsigned int oldrm = ieee754_csr.rm;
+ ieee754sp fs;
+
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
+ rv.w = ieee754sp_tint(fs);
+ ieee754_csr.rm = oldrm;
+ rfmt = w_fmt;
+ goto copcsr;
+ }
+#endif /* __mips >= 2 */
+
+#if defined(__mips64)
+ case fcvtl_op:{
+ ieee754sp fs;
+
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ rv.l = ieee754sp_tlong(fs);
+ rfmt = l_fmt;
+ goto copcsr;
+ }
+
+ case froundl_op:
+ case ftruncl_op:
+ case fceill_op:
+ case ffloorl_op:{
+ unsigned int oldrm = ieee754_csr.rm;
+ ieee754sp fs;
+
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
+ rv.l = ieee754sp_tlong(fs);
+ ieee754_csr.rm = oldrm;
+ rfmt = l_fmt;
+ goto copcsr;
+ }
+#endif /* defined(__mips64) */
+
+ default:
+ if (MIPSInst_FUNC(ir) >= fcmp_op) {
+ unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
+ ieee754sp fs, ft;
+
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ SPFROMREG(ft, MIPSInst_FT(ir));
+ rv.w = ieee754sp_cmp(fs, ft,
+ cmptab[cmpop & 0x7], cmpop & 0x8);
+ rfmt = -1;
+ if ((cmpop & 0x8) && ieee754_cxtest
+ (IEEE754_INVALID_OPERATION))
+ rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
+ else
+ goto copcsr;
+
+ }
+ else {
+ return SIGILL;
+ }
+ break;
+ }
+ break;
+ }
+
+ case d_fmt:{
+ union {
+ ieee754dp(*b) (ieee754dp, ieee754dp);
+ ieee754dp(*u) (ieee754dp);
+ } handler;
+
+ switch (MIPSInst_FUNC(ir)) {
+ /* binary ops */
+ case fadd_op:
+ handler.b = ieee754dp_add;
+ goto dcopbop;
+ case fsub_op:
+ handler.b = ieee754dp_sub;
+ goto dcopbop;
+ case fmul_op:
+ handler.b = ieee754dp_mul;
+ goto dcopbop;
+ case fdiv_op:
+ handler.b = ieee754dp_div;
+ goto dcopbop;
+
+ /* unary ops */
+#if __mips >= 2 || defined(__mips64)
+ case fsqrt_op:
+ handler.u = ieee754dp_sqrt;
+ goto dcopuop;
+#endif
+#if __mips >= 4 && __mips != 32
+ case frsqrt_op:
+ handler.u = fpemu_dp_rsqrt;
+ goto dcopuop;
+ case frecip_op:
+ handler.u = fpemu_dp_recip;
+ goto dcopuop;
+#endif
+#if __mips >= 4
+ case fmovc_op:
+ cond = fpucondbit[MIPSInst_FT(ir) >> 2];
+ if (((ctx->fcr31 & cond) != 0) !=
+ ((MIPSInst_FT(ir) & 1) != 0))
+ return 0;
+ DPFROMREG(rv.d, MIPSInst_FS(ir));
+ break;
+ case fmovz_op:
+ if (xcp->regs[MIPSInst_FT(ir)] != 0)
+ return 0;
+ DPFROMREG(rv.d, MIPSInst_FS(ir));
+ break;
+ case fmovn_op:
+ if (xcp->regs[MIPSInst_FT(ir)] == 0)
+ return 0;
+ DPFROMREG(rv.d, MIPSInst_FS(ir));
+ break;
+#endif
+ case fabs_op:
+ handler.u = ieee754dp_abs;
+ goto dcopuop;
+
+ case fneg_op:
+ handler.u = ieee754dp_neg;
+ goto dcopuop;
+
+ case fmov_op:
+ /* an easy one */
+ DPFROMREG(rv.d, MIPSInst_FS(ir));
+ goto copcsr;
+
+ /* binary op on handler */
+ dcopbop:{
+ ieee754dp fs, ft;
+
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ DPFROMREG(ft, MIPSInst_FT(ir));
+
+ rv.d = (*handler.b) (fs, ft);
+ goto copcsr;
+ }
+ dcopuop:{
+ ieee754dp fs;
+
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ rv.d = (*handler.u) (fs);
+ goto copcsr;
+ }
+
+ /* unary conv ops */
+ case fcvts_op:{
+ ieee754dp fs;
+
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ rv.s = ieee754sp_fdp(fs);
+ rfmt = s_fmt;
+ goto copcsr;
+ }
+ case fcvtd_op:
+ return SIGILL; /* not defined */
+
+ case fcvtw_op:{
+ ieee754dp fs;
+
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ rv.w = ieee754dp_tint(fs); /* wrong */
+ rfmt = w_fmt;
+ goto copcsr;
+ }
+
+#if __mips >= 2 || defined(__mips64)
+ case fround_op:
+ case ftrunc_op:
+ case fceil_op:
+ case ffloor_op:{
+ unsigned int oldrm = ieee754_csr.rm;
+ ieee754dp fs;
+
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
+ rv.w = ieee754dp_tint(fs);
+ ieee754_csr.rm = oldrm;
+ rfmt = w_fmt;
+ goto copcsr;
+ }
+#endif
+
+#if defined(__mips64)
+ case fcvtl_op:{
+ ieee754dp fs;
+
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ rv.l = ieee754dp_tlong(fs);
+ rfmt = l_fmt;
+ goto copcsr;
+ }
+
+ case froundl_op:
+ case ftruncl_op:
+ case fceill_op:
+ case ffloorl_op:{
+ unsigned int oldrm = ieee754_csr.rm;
+ ieee754dp fs;
+
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ ieee754_csr.rm = ieee_rm[modeindex(MIPSInst_FUNC(ir))];
+ rv.l = ieee754dp_tlong(fs);
+ ieee754_csr.rm = oldrm;
+ rfmt = l_fmt;
+ goto copcsr;
+ }
+#endif /* __mips >= 3 */
+
+ default:
+ if (MIPSInst_FUNC(ir) >= fcmp_op) {
+ unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
+ ieee754dp fs, ft;
+
+ DPFROMREG(fs, MIPSInst_FS(ir));
+ DPFROMREG(ft, MIPSInst_FT(ir));
+ rv.w = ieee754dp_cmp(fs, ft,
+ cmptab[cmpop & 0x7], cmpop & 0x8);
+ rfmt = -1;
+ if ((cmpop & 0x8)
+ &&
+ ieee754_cxtest
+ (IEEE754_INVALID_OPERATION))
+ rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
+ else
+ goto copcsr;
+
+ }
+ else {
+ return SIGILL;
+ }
+ break;
+ }
+ break;
+ }
+
+ case w_fmt:{
+ ieee754sp fs;
+
+ switch (MIPSInst_FUNC(ir)) {
+ case fcvts_op:
+ /* convert word to single precision real */
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ rv.s = ieee754sp_fint(fs.bits);
+ rfmt = s_fmt;
+ goto copcsr;
+ case fcvtd_op:
+ /* convert word to double precision real */
+ SPFROMREG(fs, MIPSInst_FS(ir));
+ rv.d = ieee754dp_fint(fs.bits);
+ rfmt = d_fmt;
+ goto copcsr;
+ default:
+ return SIGILL;
+ }
+ break;
+ }
+
+#if defined(__mips64)
+ case l_fmt:{
+ switch (MIPSInst_FUNC(ir)) {
+ case fcvts_op:
+ /* convert long to single precision real */
+ rv.s = ieee754sp_flong(ctx->fpr[MIPSInst_FS(ir)]);
+ rfmt = s_fmt;
+ goto copcsr;
+ case fcvtd_op:
+ /* convert long to double precision real */
+ rv.d = ieee754dp_flong(ctx->fpr[MIPSInst_FS(ir)]);
+ rfmt = d_fmt;
+ goto copcsr;
+ default:
+ return SIGILL;
+ }
+ break;
+ }
+#endif
+
+ default:
+ return SIGILL;
+ }
+
+ /*
+ * Update the fpu CSR register for this operation.
+ * If an exception is required, generate a tidy SIGFPE exception,
+ * without updating the result register.
+ * Note: cause exception bits do not accumulate, they are rewritten
+ * for each op; only the flag/sticky bits accumulate.
+ */
+ ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;
+ if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
+ /*printk ("SIGFPE: fpu csr = %08x\n",ctx->fcr31); */
+ return SIGFPE;
+ }
+
+ /*
+ * Now we can safely write the result back to the register file.
+ */
+ switch (rfmt) {
+ case -1:{
+#if __mips >= 4
+ cond = fpucondbit[MIPSInst_FD(ir) >> 2];
+#else
+ cond = FPU_CSR_COND;
+#endif
+ if (rv.w)
+ ctx->fcr31 |= cond;
+ else
+ ctx->fcr31 &= ~cond;
+ break;
+ }
+ case d_fmt:
+ DPTOREG(rv.d, MIPSInst_FD(ir));
+ break;
+ case s_fmt:
+ SPTOREG(rv.s, MIPSInst_FD(ir));
+ break;
+ case w_fmt:
+ SITOREG(rv.w, MIPSInst_FD(ir));
+ break;
+#if defined(__mips64)
+ case l_fmt:
+ DITOREG(rv.l, MIPSInst_FD(ir));
+ break;
+#endif
+ default:
+ return SIGILL;
+ }
+
+ return 0;
+}
+
+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ int has_fpu, void *__user *fault_addr)
+{
+ unsigned long oldepc, prevepc;
+ mips_instruction insn;
+ int sig = 0;
+
+ oldepc = xcp->cp0_epc;
+ do {
+ prevepc = xcp->cp0_epc;
+
+ if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGBUS;
+ }
+ if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+ return SIGSEGV;
+ }
+ if (insn == 0)
+ xcp->cp0_epc += 4; /* skip nops */
+ else {
+ /*
+ * The 'ieee754_csr' is an alias of
+ * ctx->fcr31. No need to copy ctx->fcr31 to
+ * ieee754_csr. But ieee754_csr.rm is ieee
+ * library modes. (not mips rounding mode)
+ */
+ /* convert to ieee library modes */
+ ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
+ sig = cop1Emulate(xcp, ctx, fault_addr);
+ /* revert to mips rounding mode */
+ ieee754_csr.rm = mips_rm[ieee754_csr.rm];
+ }
+
+ if (has_fpu)
+ break;
+ if (sig)
+ break;
+
+ cond_resched();
+ } while (xcp->cp0_epc > prevepc);
+
+ /* SIGILL indicates a non-fpu instruction */
+ if (sig == SIGILL && xcp->cp0_epc != oldepc)
+ /* but if epc has advanced, then ignore it */
+ sig = 0;
+
+ return sig;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static int fpuemu_stat_get(void *data, u64 *val)
+{
+ int cpu;
+ unsigned long sum = 0;
+ for_each_online_cpu(cpu) {
+ struct mips_fpu_emulator_stats *ps;
+ local_t *pv;
+ ps = &per_cpu(fpuemustats, cpu);
+ pv = (void *)ps + (unsigned long)data;
+ sum += local_read(pv);
+ }
+ *val = sum;
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n");
+
+extern struct dentry *mips_debugfs_dir;
+static int __init debugfs_fpuemu(void)
+{
+ struct dentry *d, *dir;
+
+ if (!mips_debugfs_dir)
+ return -ENODEV;
+ dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir);
+ if (!dir)
+ return -ENOMEM;
+
+#define FPU_STAT_CREATE(M) \
+ do { \
+ d = debugfs_create_file(#M , S_IRUGO, dir, \
+ (void *)offsetof(struct mips_fpu_emulator_stats, M), \
+ &fops_fpuemu_stat); \
+ if (!d) \
+ return -ENOMEM; \
+ } while (0)
+
+ FPU_STAT_CREATE(emulated);
+ FPU_STAT_CREATE(loads);
+ FPU_STAT_CREATE(stores);
+ FPU_STAT_CREATE(cp1ops);
+ FPU_STAT_CREATE(cp1xops);
+ FPU_STAT_CREATE(errors);
+
+ return 0;
+}
+__initcall(debugfs_fpuemu);
+#endif
diff --git a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c
new file mode 100644
index 00000000..b422fcad
--- /dev/null
+++ b/arch/mips/math-emu/dp_add.c
@@ -0,0 +1,182 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y)
+{
+ COMPXDP;
+ COMPYDP;
+
+ EXPLODEXDP;
+ EXPLODEYDP;
+
+ CLEARCX;
+
+ FLUSHXDP;
+ FLUSHYDP;
+
+ switch (CLPAIR(xc, yc)) {
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "add", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+ return x;
+
+
+ /* Infinity handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ if (xs == ys)
+ return x;
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+ return x;
+
+ /* Zero handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+ if (xs == ys)
+ return x;
+ else
+ return ieee754dp_zero(ieee754_csr.rm ==
+ IEEE754_RD);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+ return x;
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+ DPDNORMX;
+
+ /* FALL THROUGH */
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+ DPDNORMY;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+ DPDNORMX;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+ break;
+ }
+ assert(xm & DP_HIDDEN_BIT);
+ assert(ym & DP_HIDDEN_BIT);
+
+ /* provide guard,round and stick bit space */
+ xm <<= 3;
+ ym <<= 3;
+
+ if (xe > ye) {
+ /* have to shift y fraction right to align
+ */
+ int s = xe - ye;
+ ym = XDPSRS(ym, s);
+ ye += s;
+ } else if (ye > xe) {
+ /* have to shift x fraction right to align
+ */
+ int s = ye - xe;
+ xm = XDPSRS(xm, s);
+ xe += s;
+ }
+ assert(xe == ye);
+ assert(xe <= DP_EMAX);
+
+ if (xs == ys) {
+ /* generate 28 bit result of adding two 27 bit numbers
+ * leaving result in xm,xs,xe
+ */
+ xm = xm + ym;
+ xe = xe;
+ xs = xs;
+
+ if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */
+ xm = XDPSRS1(xm);
+ xe++;
+ }
+ } else {
+ if (xm >= ym) {
+ xm = xm - ym;
+ xe = xe;
+ xs = xs;
+ } else {
+ xm = ym - xm;
+ xe = xe;
+ xs = ys;
+ }
+ if (xm == 0)
+ return ieee754dp_zero(ieee754_csr.rm ==
+ IEEE754_RD);
+
+ /* normalize to rounding precision */
+ while ((xm >> (DP_MBITS + 3)) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+
+ }
+ DPNORMRET2(xs, xe, xm, "add", x, y);
+}
diff --git a/arch/mips/math-emu/dp_cmp.c b/arch/mips/math-emu/dp_cmp.c
new file mode 100644
index 00000000..0f32486b
--- /dev/null
+++ b/arch/mips/math-emu/dp_cmp.c
@@ -0,0 +1,66 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig)
+{
+ COMPXDP;
+ COMPYDP;
+
+ EXPLODEXDP;
+ EXPLODEYDP;
+ FLUSHXDP;
+ FLUSHYDP;
+ CLEARCX; /* Even clear inexact flag here */
+
+ if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
+ if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+ SETCX(IEEE754_INVALID_OPERATION);
+ if (cmp & IEEE754_CUN)
+ return 1;
+ if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
+ if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION))
+ return ieee754si_xcpt(0, "fcmpf", x);
+ }
+ return 0;
+ } else {
+ s64 vx = x.bits;
+ s64 vy = y.bits;
+
+ if (vx < 0)
+ vx = -vx ^ DP_SIGN_BIT;
+ if (vy < 0)
+ vy = -vy ^ DP_SIGN_BIT;
+
+ if (vx < vy)
+ return (cmp & IEEE754_CLT) != 0;
+ else if (vx == vy)
+ return (cmp & IEEE754_CEQ) != 0;
+ else
+ return (cmp & IEEE754_CGT) != 0;
+ }
+}
diff --git a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c
new file mode 100644
index 00000000..a1bce1b7
--- /dev/null
+++ b/arch/mips/math-emu/dp_div.c
@@ -0,0 +1,156 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y)
+{
+ COMPXDP;
+ COMPYDP;
+
+ EXPLODEXDP;
+ EXPLODEYDP;
+
+ CLEARCX;
+
+ FLUSHXDP;
+ FLUSHYDP;
+
+ switch (CLPAIR(xc, yc)) {
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "div", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+ return x;
+
+
+ /* Infinity handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+ return ieee754dp_zero(xs ^ ys);
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+ return ieee754dp_inf(xs ^ ys);
+
+ /* Zero handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+ SETCX(IEEE754_ZERO_DIVIDE);
+ return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+ return ieee754dp_zero(xs == ys ? 0 : 1);
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+ DPDNORMX;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+ DPDNORMY;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+ DPDNORMX;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+ break;
+ }
+ assert(xm & DP_HIDDEN_BIT);
+ assert(ym & DP_HIDDEN_BIT);
+
+ /* provide rounding space */
+ xm <<= 3;
+ ym <<= 3;
+
+ {
+ /* now the dirty work */
+
+ u64 rm = 0;
+ int re = xe - ye;
+ u64 bm;
+
+ for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) {
+ if (xm >= ym) {
+ xm -= ym;
+ rm |= bm;
+ if (xm == 0)
+ break;
+ }
+ xm <<= 1;
+ }
+ rm <<= 1;
+ if (xm)
+ rm |= 1; /* have remainder, set sticky */
+
+ assert(rm);
+
+ /* normalise rm to rounding precision ?
+ */
+ while ((rm >> (DP_MBITS + 3)) == 0) {
+ rm <<= 1;
+ re--;
+ }
+
+ DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
+ }
+}
diff --git a/arch/mips/math-emu/dp_fint.c b/arch/mips/math-emu/dp_fint.c
new file mode 100644
index 00000000..88571288
--- /dev/null
+++ b/arch/mips/math-emu/dp_fint.c
@@ -0,0 +1,79 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_fint(int x)
+{
+ u64 xm;
+ int xe;
+ int xs;
+
+ CLEARCX;
+
+ if (x == 0)
+ return ieee754dp_zero(0);
+ if (x == 1 || x == -1)
+ return ieee754dp_one(x < 0);
+ if (x == 10 || x == -10)
+ return ieee754dp_ten(x < 0);
+
+ xs = (x < 0);
+ if (xs) {
+ if (x == (1 << 31))
+ xm = ((unsigned) 1 << 31); /* max neg can't be safely negated */
+ else
+ xm = -x;
+ } else {
+ xm = x;
+ }
+
+#if 1
+ /* normalize - result can never be inexact or overflow */
+ xe = DP_MBITS;
+ while ((xm >> DP_MBITS) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+#else
+ /* normalize */
+ xe = DP_MBITS + 3;
+ while ((xm >> (DP_MBITS + 3)) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ DPNORMRET1(xs, xe, xm, "fint", x);
+#endif
+}
+
+ieee754dp ieee754dp_funs(unsigned int u)
+{
+ if ((int) u < 0)
+ return ieee754dp_add(ieee754dp_1e31(),
+ ieee754dp_fint(u & ~(1 << 31)));
+ return ieee754dp_fint(u);
+}
diff --git a/arch/mips/math-emu/dp_flong.c b/arch/mips/math-emu/dp_flong.c
new file mode 100644
index 00000000..14fc01ec
--- /dev/null
+++ b/arch/mips/math-emu/dp_flong.c
@@ -0,0 +1,77 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_flong(s64 x)
+{
+ u64 xm;
+ int xe;
+ int xs;
+
+ CLEARCX;
+
+ if (x == 0)
+ return ieee754dp_zero(0);
+ if (x == 1 || x == -1)
+ return ieee754dp_one(x < 0);
+ if (x == 10 || x == -10)
+ return ieee754dp_ten(x < 0);
+
+ xs = (x < 0);
+ if (xs) {
+ if (x == (1ULL << 63))
+ xm = (1ULL << 63); /* max neg can't be safely negated */
+ else
+ xm = -x;
+ } else {
+ xm = x;
+ }
+
+ /* normalize */
+ xe = DP_MBITS + 3;
+ if (xm >> (DP_MBITS + 1 + 3)) {
+ /* shunt out overflow bits */
+ while (xm >> (DP_MBITS + 1 + 3)) {
+ XDPSRSX1();
+ }
+ } else {
+ /* normalize in grs extended double precision */
+ while ((xm >> (DP_MBITS + 3)) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ }
+ DPNORMRET1(xs, xe, xm, "dp_flong", x);
+}
+
+ieee754dp ieee754dp_fulong(u64 u)
+{
+ if ((s64) u < 0)
+ return ieee754dp_add(ieee754dp_1e63(),
+ ieee754dp_flong(u & ~(1ULL << 63)));
+ return ieee754dp_flong(u);
+}
diff --git a/arch/mips/math-emu/dp_frexp.c b/arch/mips/math-emu/dp_frexp.c
new file mode 100644
index 00000000..cb15a5ea
--- /dev/null
+++ b/arch/mips/math-emu/dp_frexp.c
@@ -0,0 +1,52 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+/* close to ieeep754dp_logb
+*/
+ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr)
+{
+ COMPXDP;
+ CLEARCX;
+ EXPLODEXDP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ case IEEE754_CLASS_ZERO:
+ *eptr = 0;
+ return x;
+ case IEEE754_CLASS_DNORM:
+ DPDNORMX;
+ break;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ *eptr = xe + 1;
+ return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+}
diff --git a/arch/mips/math-emu/dp_fsp.c b/arch/mips/math-emu/dp_fsp.c
new file mode 100644
index 00000000..daed6834
--- /dev/null
+++ b/arch/mips/math-emu/dp_fsp.c
@@ -0,0 +1,73 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_fsp(ieee754sp x)
+{
+ COMPXSP;
+
+ EXPLODEXSP;
+
+ CLEARCX;
+
+ FLUSHXSP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "fsp");
+ case IEEE754_CLASS_QNAN:
+ return ieee754dp_nanxcpt(builddp(xs,
+ DP_EMAX + 1 + DP_EBIAS,
+ ((u64) xm
+ << (DP_MBITS -
+ SP_MBITS))), "fsp",
+ x);
+ case IEEE754_CLASS_INF:
+ return ieee754dp_inf(xs);
+ case IEEE754_CLASS_ZERO:
+ return ieee754dp_zero(xs);
+ case IEEE754_CLASS_DNORM:
+ /* normalize */
+ while ((xm >> SP_MBITS) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ break;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+
+ /* CAN'T possibly overflow,underflow, or need rounding
+ */
+
+ /* drop the hidden bit */
+ xm &= ~SP_HIDDEN_BIT;
+
+ return builddp(xs, xe + DP_EBIAS,
+ (u64) xm << (DP_MBITS - SP_MBITS));
+}
diff --git a/arch/mips/math-emu/dp_logb.c b/arch/mips/math-emu/dp_logb.c
new file mode 100644
index 00000000..151127e5
--- /dev/null
+++ b/arch/mips/math-emu/dp_logb.c
@@ -0,0 +1,53 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_logb(ieee754dp x)
+{
+ COMPXDP;
+
+ CLEARCX;
+
+ EXPLODEXDP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ return ieee754dp_nanxcpt(x, "logb", x);
+ case IEEE754_CLASS_QNAN:
+ return x;
+ case IEEE754_CLASS_INF:
+ return ieee754dp_inf(0);
+ case IEEE754_CLASS_ZERO:
+ return ieee754dp_inf(1);
+ case IEEE754_CLASS_DNORM:
+ DPDNORMX;
+ break;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ return ieee754dp_fint(xe);
+}
diff --git a/arch/mips/math-emu/dp_modf.c b/arch/mips/math-emu/dp_modf.c
new file mode 100644
index 00000000..b01f9cf6
--- /dev/null
+++ b/arch/mips/math-emu/dp_modf.c
@@ -0,0 +1,79 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+/* modf function is always exact for a finite number
+*/
+ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp *ip)
+{
+ COMPXDP;
+
+ CLEARCX;
+
+ EXPLODEXDP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ case IEEE754_CLASS_ZERO:
+ *ip = x;
+ return x;
+ case IEEE754_CLASS_DNORM:
+ /* far to small */
+ *ip = ieee754dp_zero(xs);
+ return x;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ if (xe < 0) {
+ *ip = ieee754dp_zero(xs);
+ return x;
+ }
+ if (xe >= DP_MBITS) {
+ *ip = x;
+ return ieee754dp_zero(xs);
+ }
+ /* generate ipart mantissa by clearing bottom bits
+ */
+ *ip = builddp(xs, xe + DP_EBIAS,
+ ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) &
+ ~DP_HIDDEN_BIT);
+
+ /* generate fpart mantissa by clearing top bits
+ * and normalizing (must be able to normalize)
+ */
+ xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe));
+ if (xm == 0)
+ return ieee754dp_zero(xs);
+
+ while ((xm >> DP_MBITS) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+}
diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c
new file mode 100644
index 00000000..09175f46
--- /dev/null
+++ b/arch/mips/math-emu/dp_mul.c
@@ -0,0 +1,176 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y)
+{
+ COMPXDP;
+ COMPYDP;
+
+ EXPLODEXDP;
+ EXPLODEYDP;
+
+ CLEARCX;
+
+ FLUSHXDP;
+ FLUSHYDP;
+
+ switch (CLPAIR(xc, yc)) {
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "mul", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+ return x;
+
+
+ /* Infinity handling */
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ return ieee754dp_inf(xs ^ ys);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+ return ieee754dp_zero(xs ^ ys);
+
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+ DPDNORMX;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+ DPDNORMY;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+ DPDNORMX;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+ break;
+ }
+ /* rm = xm * ym, re = xe+ye basically */
+ assert(xm & DP_HIDDEN_BIT);
+ assert(ym & DP_HIDDEN_BIT);
+ {
+ int re = xe + ye;
+ int rs = xs ^ ys;
+ u64 rm;
+
+ /* shunt to top of word */
+ xm <<= 64 - (DP_MBITS + 1);
+ ym <<= 64 - (DP_MBITS + 1);
+
+ /* multiply 32bits xm,ym to give high 32bits rm with stickness
+ */
+
+ /* 32 * 32 => 64 */
+#define DPXMULT(x, y) ((u64)(x) * (u64)y)
+
+ {
+ unsigned lxm = xm;
+ unsigned hxm = xm >> 32;
+ unsigned lym = ym;
+ unsigned hym = ym >> 32;
+ u64 lrm;
+ u64 hrm;
+
+ lrm = DPXMULT(lxm, lym);
+ hrm = DPXMULT(hxm, hym);
+
+ {
+ u64 t = DPXMULT(lxm, hym);
+ {
+ u64 at =
+ lrm + (t << 32);
+ hrm += at < lrm;
+ lrm = at;
+ }
+ hrm = hrm + (t >> 32);
+ }
+
+ {
+ u64 t = DPXMULT(hxm, lym);
+ {
+ u64 at =
+ lrm + (t << 32);
+ hrm += at < lrm;
+ lrm = at;
+ }
+ hrm = hrm + (t >> 32);
+ }
+ rm = hrm | (lrm != 0);
+ }
+
+ /*
+ * sticky shift down to normal rounding precision
+ */
+ if ((s64) rm < 0) {
+ rm =
+ (rm >> (64 - (DP_MBITS + 1 + 3))) |
+ ((rm << (DP_MBITS + 1 + 3)) != 0);
+ re++;
+ } else {
+ rm =
+ (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) |
+ ((rm << (DP_MBITS + 1 + 3 + 1)) != 0);
+ }
+ assert(rm & (DP_HIDDEN_BIT << 3));
+ DPNORMRET2(rs, re, rm, "mul", x, y);
+ }
+}
diff --git a/arch/mips/math-emu/dp_scalb.c b/arch/mips/math-emu/dp_scalb.c
new file mode 100644
index 00000000..6f5df438
--- /dev/null
+++ b/arch/mips/math-emu/dp_scalb.c
@@ -0,0 +1,57 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_scalb(ieee754dp x, int n)
+{
+ COMPXDP;
+
+ CLEARCX;
+
+ EXPLODEXDP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ return ieee754dp_nanxcpt(x, "scalb", x, n);
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ case IEEE754_CLASS_ZERO:
+ return x;
+ case IEEE754_CLASS_DNORM:
+ DPDNORMX;
+ break;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
+}
+
+
+ieee754dp ieee754dp_ldexp(ieee754dp x, int n)
+{
+ return ieee754dp_scalb(x, n);
+}
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c
new file mode 100644
index 00000000..79ce2673
--- /dev/null
+++ b/arch/mips/math-emu/dp_simple.c
@@ -0,0 +1,85 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+int ieee754dp_finite(ieee754dp x)
+{
+ return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS;
+}
+
+ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y)
+{
+ CLEARCX;
+ DPSIGN(x) = DPSIGN(y);
+ return x;
+}
+
+
+ieee754dp ieee754dp_neg(ieee754dp x)
+{
+ COMPXDP;
+
+ EXPLODEXDP;
+ CLEARCX;
+ FLUSHXDP;
+
+ /*
+ * Invert the sign ALWAYS to prevent an endless recursion on
+ * pow() in libc.
+ */
+ /* quick fix up */
+ DPSIGN(x) ^= 1;
+
+ if (xc == IEEE754_CLASS_SNAN) {
+ ieee754dp y = ieee754dp_indef();
+ SETCX(IEEE754_INVALID_OPERATION);
+ DPSIGN(y) = DPSIGN(x);
+ return ieee754dp_nanxcpt(y, "neg");
+ }
+
+ return x;
+}
+
+
+ieee754dp ieee754dp_abs(ieee754dp x)
+{
+ COMPXDP;
+
+ EXPLODEXDP;
+ CLEARCX;
+ FLUSHXDP;
+
+ /* Clear sign ALWAYS, irrespective of NaN */
+ DPSIGN(x) = 0;
+
+ if (xc == IEEE754_CLASS_SNAN) {
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "abs");
+ }
+
+ return x;
+}
diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
new file mode 100644
index 00000000..a2a51b87
--- /dev/null
+++ b/arch/mips/math-emu/dp_sqrt.c
@@ -0,0 +1,164 @@
+/* IEEE754 floating point arithmetic
+ * double precision square root
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+static const unsigned table[] = {
+ 0, 1204, 3062, 5746, 9193, 13348, 18162, 23592,
+ 29598, 36145, 43202, 50740, 58733, 67158, 75992,
+ 85215, 83599, 71378, 60428, 50647, 41945, 34246,
+ 27478, 21581, 16499, 12183, 8588, 5674, 3403,
+ 1742, 661, 130
+};
+
+ieee754dp ieee754dp_sqrt(ieee754dp x)
+{
+ struct _ieee754_csr oldcsr;
+ ieee754dp y, z, t;
+ unsigned scalx, yh;
+ COMPXDP;
+
+ EXPLODEXDP;
+ CLEARCX;
+ FLUSHXDP;
+
+ /* x == INF or NAN? */
+ switch (xc) {
+ case IEEE754_CLASS_QNAN:
+ /* sqrt(Nan) = Nan */
+ return ieee754dp_nanxcpt(x, "sqrt");
+ case IEEE754_CLASS_SNAN:
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
+ case IEEE754_CLASS_ZERO:
+ /* sqrt(0) = 0 */
+ return x;
+ case IEEE754_CLASS_INF:
+ if (xs) {
+ /* sqrt(-Inf) = Nan */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
+ }
+ /* sqrt(+Inf) = Inf */
+ return x;
+ case IEEE754_CLASS_DNORM:
+ DPDNORMX;
+ /* fall through */
+ case IEEE754_CLASS_NORM:
+ if (xs) {
+ /* sqrt(-x) = Nan */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
+ }
+ break;
+ }
+
+ /* save old csr; switch off INX enable & flag; set RN rounding */
+ oldcsr = ieee754_csr;
+ ieee754_csr.mx &= ~IEEE754_INEXACT;
+ ieee754_csr.sx &= ~IEEE754_INEXACT;
+ ieee754_csr.rm = IEEE754_RN;
+
+ /* adjust exponent to prevent overflow */
+ scalx = 0;
+ if (xe > 512) { /* x > 2**-512? */
+ xe -= 512; /* x = x / 2**512 */
+ scalx += 256;
+ } else if (xe < -512) { /* x < 2**-512? */
+ xe += 512; /* x = x * 2**512 */
+ scalx -= 256;
+ }
+
+ y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+
+ /* magic initial approximation to almost 8 sig. bits */
+ yh = y.bits >> 32;
+ yh = (yh >> 1) + 0x1ff80000;
+ yh = yh - table[(yh >> 15) & 31];
+ y.bits = ((u64) yh << 32) | (y.bits & 0xffffffff);
+
+ /* Heron's rule once with correction to improve to ~18 sig. bits */
+ /* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */
+ t = ieee754dp_div(x, y);
+ y = ieee754dp_add(y, t);
+ y.bits -= 0x0010000600000000LL;
+ y.bits &= 0xffffffff00000000LL;
+
+ /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */
+ /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */
+ z = t = ieee754dp_mul(y, y);
+ t.parts.bexp += 0x001;
+ t = ieee754dp_add(t, z);
+ z = ieee754dp_mul(ieee754dp_sub(x, z), y);
+
+ /* t=z/(t+x) ; pt[n0]+=0x00100000; y+=t; */
+ t = ieee754dp_div(z, ieee754dp_add(t, x));
+ t.parts.bexp += 0x001;
+ y = ieee754dp_add(y, t);
+
+ /* twiddle last bit to force y correctly rounded */
+
+ /* set RZ, clear INEX flag */
+ ieee754_csr.rm = IEEE754_RZ;
+ ieee754_csr.sx &= ~IEEE754_INEXACT;
+
+ /* t=x/y; ...chopped quotient, possibly inexact */
+ t = ieee754dp_div(x, y);
+
+ if (ieee754_csr.sx & IEEE754_INEXACT || t.bits != y.bits) {
+
+ if (!(ieee754_csr.sx & IEEE754_INEXACT))
+ /* t = t-ulp */
+ t.bits -= 1;
+
+ /* add inexact to result status */
+ oldcsr.cx |= IEEE754_INEXACT;
+ oldcsr.sx |= IEEE754_INEXACT;
+
+ switch (oldcsr.rm) {
+ case IEEE754_RP:
+ y.bits += 1;
+ /* drop through */
+ case IEEE754_RN:
+ t.bits += 1;
+ break;
+ }
+
+ /* y=y+t; ...chopped sum */
+ y = ieee754dp_add(y, t);
+
+ /* adjust scalx for correctly rounded sqrt(x) */
+ scalx -= 1;
+ }
+
+ /* py[n0]=py[n0]+scalx; ...scale back y */
+ y.parts.bexp += scalx;
+
+ /* restore rounding mode, possibly set inexact */
+ ieee754_csr = oldcsr;
+
+ return y;
+}
diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
new file mode 100644
index 00000000..0de098cb
--- /dev/null
+++ b/arch/mips/math-emu/dp_sub.c
@@ -0,0 +1,190 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y)
+{
+ COMPXDP;
+ COMPYDP;
+
+ EXPLODEXDP;
+ EXPLODEYDP;
+
+ CLEARCX;
+
+ FLUSHXDP;
+ FLUSHYDP;
+
+ switch (CLPAIR(xc, yc)) {
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_nanxcpt(ieee754dp_indef(), "sub", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+ return x;
+
+
+ /* Infinity handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ if (xs != ys)
+ return x;
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+ return ieee754dp_inf(ys ^ 1);
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+ return x;
+
+ /* Zero handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+ if (xs != ys)
+ return x;
+ else
+ return ieee754dp_zero(ieee754_csr.rm ==
+ IEEE754_RD);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+ return x;
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+ /* quick fix up */
+ DPSIGN(y) ^= 1;
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+ DPDNORMX;
+ /* FALL THROUGH */
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+ /* normalize ym,ye */
+ DPDNORMY;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+ /* normalize xm,xe */
+ DPDNORMX;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+ break;
+ }
+ /* flip sign of y and handle as add */
+ ys ^= 1;
+
+ assert(xm & DP_HIDDEN_BIT);
+ assert(ym & DP_HIDDEN_BIT);
+
+
+ /* provide guard,round and stick bit dpace */
+ xm <<= 3;
+ ym <<= 3;
+
+ if (xe > ye) {
+ /* have to shift y fraction right to align
+ */
+ int s = xe - ye;
+ ym = XDPSRS(ym, s);
+ ye += s;
+ } else if (ye > xe) {
+ /* have to shift x fraction right to align
+ */
+ int s = ye - xe;
+ xm = XDPSRS(xm, s);
+ xe += s;
+ }
+ assert(xe == ye);
+ assert(xe <= DP_EMAX);
+
+ if (xs == ys) {
+ /* generate 28 bit result of adding two 27 bit numbers
+ */
+ xm = xm + ym;
+ xe = xe;
+ xs = xs;
+
+ if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */
+ xm = XDPSRS1(xm); /* shift preserving sticky */
+ xe++;
+ }
+ } else {
+ if (xm >= ym) {
+ xm = xm - ym;
+ xe = xe;
+ xs = xs;
+ } else {
+ xm = ym - xm;
+ xe = xe;
+ xs = ys;
+ }
+ if (xm == 0) {
+ if (ieee754_csr.rm == IEEE754_RD)
+ return ieee754dp_zero(1); /* round negative inf. => sign = -1 */
+ else
+ return ieee754dp_zero(0); /* other round modes => sign = 1 */
+ }
+
+ /* normalize to rounding precision
+ */
+ while ((xm >> (DP_MBITS + 3)) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ }
+ DPNORMRET2(xs, xe, xm, "sub", x, y);
+}
diff --git a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c
new file mode 100644
index 00000000..0ebe8598
--- /dev/null
+++ b/arch/mips/math-emu/dp_tint.c
@@ -0,0 +1,122 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include <linux/kernel.h>
+#include "ieee754dp.h"
+
+int ieee754dp_tint(ieee754dp x)
+{
+ COMPXDP;
+
+ CLEARCX;
+
+ EXPLODEXDP;
+ FLUSHXDP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
+ case IEEE754_CLASS_ZERO:
+ return 0;
+ case IEEE754_CLASS_DNORM:
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ if (xe > 31) {
+ /* Set invalid. We will only use overflow for floating
+ point overflow */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
+ }
+ /* oh gawd */
+ if (xe > DP_MBITS) {
+ xm <<= xe - DP_MBITS;
+ } else if (xe < DP_MBITS) {
+ u64 residue;
+ int round;
+ int sticky;
+ int odd;
+
+ if (xe < -1) {
+ residue = xm;
+ round = 0;
+ sticky = residue != 0;
+ xm = 0;
+ } else {
+ residue = xm << (64 - DP_MBITS + xe);
+ round = (residue >> 63) != 0;
+ sticky = (residue << 1) != 0;
+ xm >>= DP_MBITS - xe;
+ }
+ /* Note: At this point upper 32 bits of xm are guaranteed
+ to be zero */
+ odd = (xm & 0x1) != 0x0;
+ switch (ieee754_csr.rm) {
+ case IEEE754_RN:
+ if (round && (sticky || odd))
+ xm++;
+ break;
+ case IEEE754_RZ:
+ break;
+ case IEEE754_RU: /* toward +Infinity */
+ if ((round || sticky) && !xs)
+ xm++;
+ break;
+ case IEEE754_RD: /* toward -Infinity */
+ if ((round || sticky) && xs)
+ xm++;
+ break;
+ }
+ /* look for valid corner case 0x80000000 */
+ if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
+ /* This can happen after rounding */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
+ }
+ if (round || sticky)
+ SETCX(IEEE754_INEXACT);
+ }
+ if (xs)
+ return -xm;
+ else
+ return xm;
+}
+
+
+unsigned int ieee754dp_tuns(ieee754dp x)
+{
+ ieee754dp hb = ieee754dp_1e31();
+
+ /* what if x < 0 ?? */
+ if (ieee754dp_lt(x, hb))
+ return (unsigned) ieee754dp_tint(x);
+
+ return (unsigned) ieee754dp_tint(ieee754dp_sub(x, hb)) |
+ ((unsigned) 1 << 31);
+}
diff --git a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c
new file mode 100644
index 00000000..133ce2ba
--- /dev/null
+++ b/arch/mips/math-emu/dp_tlong.c
@@ -0,0 +1,125 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+s64 ieee754dp_tlong(ieee754dp x)
+{
+ COMPXDP;
+
+ CLEARCX;
+
+ EXPLODEXDP;
+ FLUSHXDP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
+ case IEEE754_CLASS_ZERO:
+ return 0;
+ case IEEE754_CLASS_DNORM:
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ if (xe >= 63) {
+ /* look for valid corner case */
+ if (xe == 63 && xs && xm == DP_HIDDEN_BIT)
+ return -0x8000000000000000LL;
+ /* Set invalid. We will only use overflow for floating
+ point overflow */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
+ }
+ /* oh gawd */
+ if (xe > DP_MBITS) {
+ xm <<= xe - DP_MBITS;
+ } else if (xe < DP_MBITS) {
+ u64 residue;
+ int round;
+ int sticky;
+ int odd;
+
+ if (xe < -1) {
+ residue = xm;
+ round = 0;
+ sticky = residue != 0;
+ xm = 0;
+ } else {
+ /* Shifting a u64 64 times does not work,
+ * so we do it in two steps. Be aware that xe
+ * may be -1 */
+ residue = xm << (xe + 1);
+ residue <<= 63 - DP_MBITS;
+ round = (residue >> 63) != 0;
+ sticky = (residue << 1) != 0;
+ xm >>= DP_MBITS - xe;
+ }
+ odd = (xm & 0x1) != 0x0;
+ switch (ieee754_csr.rm) {
+ case IEEE754_RN:
+ if (round && (sticky || odd))
+ xm++;
+ break;
+ case IEEE754_RZ:
+ break;
+ case IEEE754_RU: /* toward +Infinity */
+ if ((round || sticky) && !xs)
+ xm++;
+ break;
+ case IEEE754_RD: /* toward -Infinity */
+ if ((round || sticky) && xs)
+ xm++;
+ break;
+ }
+ if ((xm >> 63) != 0) {
+ /* This can happen after rounding */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
+ }
+ if (round || sticky)
+ SETCX(IEEE754_INEXACT);
+ }
+ if (xs)
+ return -xm;
+ else
+ return xm;
+}
+
+
+u64 ieee754dp_tulong(ieee754dp x)
+{
+ ieee754dp hb = ieee754dp_1e63();
+
+ /* what if x < 0 ?? */
+ if (ieee754dp_lt(x, hb))
+ return (u64) ieee754dp_tlong(x);
+
+ return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) |
+ (1ULL << 63);
+}
diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c
new file mode 100644
index 00000000..3c4a8c5b
--- /dev/null
+++ b/arch/mips/math-emu/dsemul.c
@@ -0,0 +1,167 @@
+#include <linux/compiler.h>
+#include <linux/mm.h>
+#include <linux/signal.h>
+#include <linux/smp.h>
+
+#include <asm/asm.h>
+#include <asm/bootinfo.h>
+#include <asm/byteorder.h>
+#include <asm/cpu.h>
+#include <asm/inst.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/branch.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+
+#include <asm/fpu_emulator.h>
+
+#include "ieee754.h"
+
+/* Strap kernel emulator for full MIPS IV emulation */
+
+#ifdef __mips
+#undef __mips
+#endif
+#define __mips 4
+
+/*
+ * Emulate the arbritrary instruction ir at xcp->cp0_epc. Required when
+ * we have to emulate the instruction in a COP1 branch delay slot. Do
+ * not change cp0_epc due to the instruction
+ *
+ * According to the spec:
+ * 1) it shouldn't be a branch :-)
+ * 2) it can be a COP instruction :-(
+ * 3) if we are tring to run a protected memory space we must take
+ * special care on memory access instructions :-(
+ */
+
+/*
+ * "Trampoline" return routine to catch exception following
+ * execution of delay-slot instruction execution.
+ */
+
+struct emuframe {
+ mips_instruction emul;
+ mips_instruction badinst;
+ mips_instruction cookie;
+ unsigned long epc;
+};
+
+int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
+{
+ extern asmlinkage void handle_dsemulret(void);
+ struct emuframe __user *fr;
+ int err;
+
+ if (ir == 0) { /* a nop is easy */
+ regs->cp0_epc = cpc;
+ regs->cp0_cause &= ~CAUSEF_BD;
+ return 0;
+ }
+#ifdef DSEMUL_TRACE
+ printk("dsemul %lx %lx\n", regs->cp0_epc, cpc);
+
+#endif
+
+ /*
+ * The strategy is to push the instruction onto the user stack
+ * and put a trap after it which we can catch and jump to
+ * the required address any alternative apart from full
+ * instruction emulation!!.
+ *
+ * Algorithmics used a system call instruction, and
+ * borrowed that vector. MIPS/Linux version is a bit
+ * more heavyweight in the interests of portability and
+ * multiprocessor support. For Linux we generate a
+ * an unaligned access and force an address error exception.
+ *
+ * For embedded systems (stand-alone) we prefer to use a
+ * non-existing CP1 instruction. This prevents us from emulating
+ * branches, but gives us a cleaner interface to the exception
+ * handler (single entry point).
+ */
+
+ /* Ensure that the two instructions are in the same cache line */
+ fr = (struct emuframe __user *)
+ ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
+
+ /* Verify that the stack pointer is not competely insane */
+ if (unlikely(!access_ok(VERIFY_WRITE, fr, sizeof(struct emuframe))))
+ return SIGBUS;
+
+ err = __put_user(ir, &fr->emul);
+ err |= __put_user((mips_instruction)BREAK_MATH, &fr->badinst);
+ err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie);
+ err |= __put_user(cpc, &fr->epc);
+
+ if (unlikely(err)) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ return SIGBUS;
+ }
+
+ regs->cp0_epc = (unsigned long) &fr->emul;
+
+ flush_cache_sigtramp((unsigned long)&fr->badinst);
+
+ return SIGILL; /* force out of emulation loop */
+}
+
+int do_dsemulret(struct pt_regs *xcp)
+{
+ struct emuframe __user *fr;
+ unsigned long epc;
+ u32 insn, cookie;
+ int err = 0;
+
+ fr = (struct emuframe __user *)
+ (xcp->cp0_epc - sizeof(mips_instruction));
+
+ /*
+ * If we can't even access the area, something is very wrong, but we'll
+ * leave that to the default handling
+ */
+ if (!access_ok(VERIFY_READ, fr, sizeof(struct emuframe)))
+ return 0;
+
+ /*
+ * Do some sanity checking on the stackframe:
+ *
+ * - Is the instruction pointed to by the EPC an BREAK_MATH?
+ * - Is the following memory word the BD_COOKIE?
+ */
+ err = __get_user(insn, &fr->badinst);
+ err |= __get_user(cookie, &fr->cookie);
+
+ if (unlikely(err || (insn != BREAK_MATH) || (cookie != BD_COOKIE))) {
+ MIPS_FPU_EMU_INC_STATS(errors);
+ return 0;
+ }
+
+ /*
+ * At this point, we are satisfied that it's a BD emulation trap. Yes,
+ * a user might have deliberately put two malformed and useless
+ * instructions in a row in his program, in which case he's in for a
+ * nasty surprise - the next instruction will be treated as a
+ * continuation address! Alas, this seems to be the only way that we
+ * can handle signals, recursion, and longjmps() in the context of
+ * emulating the branch delay instruction.
+ */
+
+#ifdef DSEMUL_TRACE
+ printk("dsemulret\n");
+#endif
+ if (__get_user(epc, &fr->epc)) { /* Saved EPC */
+ /* This is not a good situation to be in */
+ force_sig(SIGBUS, current);
+
+ return 0;
+ }
+
+ /* Set EPC to return to post-branch instruction */
+ xcp->cp0_epc = epc;
+
+ return 1;
+}
diff --git a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c
new file mode 100644
index 00000000..30554e1c
--- /dev/null
+++ b/arch/mips/math-emu/ieee754.c
@@ -0,0 +1,127 @@
+/* ieee754 floating point arithmetic
+ * single and double precision
+ *
+ * BUGS
+ * not much dp done
+ * doesn't generate IEEE754_INEXACT
+ *
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754int.h"
+#include "ieee754sp.h"
+#include "ieee754dp.h"
+
+#define DP_EBIAS 1023
+#define DP_EMIN (-1022)
+#define DP_EMAX 1023
+
+#define SP_EBIAS 127
+#define SP_EMIN (-126)
+#define SP_EMAX 127
+
+/* special constants
+*/
+
+
+#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
+#define SPSTR(s, b, m) {m, b, s}
+#define DPSTR(s, b, mh, ml) {ml, mh, b, s}
+#endif
+
+#ifdef __MIPSEB__
+#define SPSTR(s, b, m) {s, b, m}
+#define DPSTR(s, b, mh, ml) {s, b, mh, ml}
+#endif
+
+const struct ieee754dp_konst __ieee754dp_spcvals[] = {
+ DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* + zero */
+ DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* - zero */
+ DPSTR(0, DP_EBIAS, 0, 0), /* + 1.0 */
+ DPSTR(1, DP_EBIAS, 0, 0), /* - 1.0 */
+ DPSTR(0, 3 + DP_EBIAS, 0x40000, 0), /* + 10.0 */
+ DPSTR(1, 3 + DP_EBIAS, 0x40000, 0), /* - 10.0 */
+ DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* + infinity */
+ DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* - infinity */
+ DPSTR(0, DP_EMAX+1+DP_EBIAS, 0x7FFFF, 0xFFFFFFFF), /* + indef quiet Nan */
+ DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* + max */
+ DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* - max */
+ DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0), /* + min normal */
+ DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0), /* - min normal */
+ DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* + min denormal */
+ DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* - min denormal */
+ DPSTR(0, 31 + DP_EBIAS, 0, 0), /* + 1.0e31 */
+ DPSTR(0, 63 + DP_EBIAS, 0, 0), /* + 1.0e63 */
+};
+
+const struct ieee754sp_konst __ieee754sp_spcvals[] = {
+ SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0), /* + zero */
+ SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0), /* - zero */
+ SPSTR(0, SP_EBIAS, 0), /* + 1.0 */
+ SPSTR(1, SP_EBIAS, 0), /* - 1.0 */
+ SPSTR(0, 3 + SP_EBIAS, 0x200000), /* + 10.0 */
+ SPSTR(1, 3 + SP_EBIAS, 0x200000), /* - 10.0 */
+ SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0), /* + infinity */
+ SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0), /* - infinity */
+ SPSTR(0, SP_EMAX+1+SP_EBIAS, 0x3FFFFF), /* + indef quiet Nan */
+ SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* + max normal */
+ SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* - max normal */
+ SPSTR(0, SP_EMIN + SP_EBIAS, 0), /* + min normal */
+ SPSTR(1, SP_EMIN + SP_EBIAS, 0), /* - min normal */
+ SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1), /* + min denormal */
+ SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1), /* - min denormal */
+ SPSTR(0, 31 + SP_EBIAS, 0), /* + 1.0e31 */
+ SPSTR(0, 63 + SP_EBIAS, 0), /* + 1.0e63 */
+};
+
+
+int ieee754si_xcpt(int r, const char *op, ...)
+{
+ struct ieee754xctx ax;
+
+ if (!TSTX())
+ return r;
+ ax.op = op;
+ ax.rt = IEEE754_RT_SI;
+ ax.rv.si = r;
+ va_start(ax.ap, op);
+ ieee754_xcpt(&ax);
+ va_end(ax.ap);
+ return ax.rv.si;
+}
+
+s64 ieee754di_xcpt(s64 r, const char *op, ...)
+{
+ struct ieee754xctx ax;
+
+ if (!TSTX())
+ return r;
+ ax.op = op;
+ ax.rt = IEEE754_RT_DI;
+ ax.rv.di = r;
+ va_start(ax.ap, op);
+ ieee754_xcpt(&ax);
+ va_end(ax.ap);
+ return ax.rv.di;
+}
diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h
new file mode 100644
index 00000000..22796e01
--- /dev/null
+++ b/arch/mips/math-emu/ieee754.h
@@ -0,0 +1,470 @@
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Nov 7, 2000
+ * Modification to allow integration with Linux kernel
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ */
+#ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H
+#define __ARCH_MIPS_MATH_EMU_IEEE754_H
+
+#include <asm/byteorder.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+
+/*
+ * Not very pretty, but the Linux kernel's normal va_list definition
+ * does not allow it to be used as a structure element, as it is here.
+ */
+#ifndef _STDARG_H
+#include <stdarg.h>
+#endif
+
+#ifdef __LITTLE_ENDIAN
+struct ieee754dp_konst {
+ unsigned mantlo:32;
+ unsigned manthi:20;
+ unsigned bexp:11;
+ unsigned sign:1;
+};
+struct ieee754sp_konst {
+ unsigned mant:23;
+ unsigned bexp:8;
+ unsigned sign:1;
+};
+
+typedef union _ieee754dp {
+ struct ieee754dp_konst oparts;
+ struct {
+ u64 mant:52;
+ unsigned int bexp:11;
+ unsigned int sign:1;
+ } parts;
+ u64 bits;
+ double d;
+} ieee754dp;
+
+typedef union _ieee754sp {
+ struct ieee754sp_konst parts;
+ float f;
+ u32 bits;
+} ieee754sp;
+#endif
+
+#ifdef __BIG_ENDIAN
+struct ieee754dp_konst {
+ unsigned sign:1;
+ unsigned bexp:11;
+ unsigned manthi:20;
+ unsigned mantlo:32;
+};
+
+typedef union _ieee754dp {
+ struct ieee754dp_konst oparts;
+ struct {
+ unsigned int sign:1;
+ unsigned int bexp:11;
+ u64 mant:52;
+ } parts;
+ double d;
+ u64 bits;
+} ieee754dp;
+
+struct ieee754sp_konst {
+ unsigned sign:1;
+ unsigned bexp:8;
+ unsigned mant:23;
+};
+
+typedef union _ieee754sp {
+ struct ieee754sp_konst parts;
+ float f;
+ u32 bits;
+} ieee754sp;
+#endif
+
+/*
+ * single precision (often aka float)
+*/
+int ieee754sp_finite(ieee754sp x);
+int ieee754sp_class(ieee754sp x);
+
+ieee754sp ieee754sp_abs(ieee754sp x);
+ieee754sp ieee754sp_neg(ieee754sp x);
+ieee754sp ieee754sp_scalb(ieee754sp x, int);
+ieee754sp ieee754sp_logb(ieee754sp x);
+
+/* x with sign of y */
+ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y);
+
+ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y);
+ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y);
+ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y);
+ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y);
+
+ieee754sp ieee754sp_fint(int x);
+ieee754sp ieee754sp_funs(unsigned x);
+ieee754sp ieee754sp_flong(s64 x);
+ieee754sp ieee754sp_fulong(u64 x);
+ieee754sp ieee754sp_fdp(ieee754dp x);
+
+int ieee754sp_tint(ieee754sp x);
+unsigned int ieee754sp_tuns(ieee754sp x);
+s64 ieee754sp_tlong(ieee754sp x);
+u64 ieee754sp_tulong(ieee754sp x);
+
+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig);
+/*
+ * basic sp math
+ */
+ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip);
+ieee754sp ieee754sp_frexp(ieee754sp x, int *exp);
+ieee754sp ieee754sp_ldexp(ieee754sp x, int exp);
+
+ieee754sp ieee754sp_ceil(ieee754sp x);
+ieee754sp ieee754sp_floor(ieee754sp x);
+ieee754sp ieee754sp_trunc(ieee754sp x);
+
+ieee754sp ieee754sp_sqrt(ieee754sp x);
+
+/*
+ * double precision (often aka double)
+*/
+int ieee754dp_finite(ieee754dp x);
+int ieee754dp_class(ieee754dp x);
+
+/* x with sign of y */
+ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y);
+
+ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y);
+ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y);
+ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y);
+ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y);
+
+ieee754dp ieee754dp_abs(ieee754dp x);
+ieee754dp ieee754dp_neg(ieee754dp x);
+ieee754dp ieee754dp_scalb(ieee754dp x, int);
+
+/* return exponent as integer in floating point format
+ */
+ieee754dp ieee754dp_logb(ieee754dp x);
+
+ieee754dp ieee754dp_fint(int x);
+ieee754dp ieee754dp_funs(unsigned x);
+ieee754dp ieee754dp_flong(s64 x);
+ieee754dp ieee754dp_fulong(u64 x);
+ieee754dp ieee754dp_fsp(ieee754sp x);
+
+ieee754dp ieee754dp_ceil(ieee754dp x);
+ieee754dp ieee754dp_floor(ieee754dp x);
+ieee754dp ieee754dp_trunc(ieee754dp x);
+
+int ieee754dp_tint(ieee754dp x);
+unsigned int ieee754dp_tuns(ieee754dp x);
+s64 ieee754dp_tlong(ieee754dp x);
+u64 ieee754dp_tulong(ieee754dp x);
+
+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig);
+/*
+ * basic sp math
+ */
+ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip);
+ieee754dp ieee754dp_frexp(ieee754dp x, int *exp);
+ieee754dp ieee754dp_ldexp(ieee754dp x, int exp);
+
+ieee754dp ieee754dp_ceil(ieee754dp x);
+ieee754dp ieee754dp_floor(ieee754dp x);
+ieee754dp ieee754dp_trunc(ieee754dp x);
+
+ieee754dp ieee754dp_sqrt(ieee754dp x);
+
+
+
+/* 5 types of floating point number
+*/
+#define IEEE754_CLASS_NORM 0x00
+#define IEEE754_CLASS_ZERO 0x01
+#define IEEE754_CLASS_DNORM 0x02
+#define IEEE754_CLASS_INF 0x03
+#define IEEE754_CLASS_SNAN 0x04
+#define IEEE754_CLASS_QNAN 0x05
+
+/* exception numbers */
+#define IEEE754_INEXACT 0x01
+#define IEEE754_UNDERFLOW 0x02
+#define IEEE754_OVERFLOW 0x04
+#define IEEE754_ZERO_DIVIDE 0x08
+#define IEEE754_INVALID_OPERATION 0x10
+
+/* cmp operators
+*/
+#define IEEE754_CLT 0x01
+#define IEEE754_CEQ 0x02
+#define IEEE754_CGT 0x04
+#define IEEE754_CUN 0x08
+
+/* rounding mode
+*/
+#define IEEE754_RN 0 /* round to nearest */
+#define IEEE754_RZ 1 /* round toward zero */
+#define IEEE754_RD 2 /* round toward -Infinity */
+#define IEEE754_RU 3 /* round toward +Infinity */
+
+/* other naming */
+#define IEEE754_RM IEEE754_RD
+#define IEEE754_RP IEEE754_RU
+
+/* "normal" comparisons
+*/
+static inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
+{
+ return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
+}
+
+static inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
+{
+ return ieee754sp_cmp(x, y,
+ IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
+}
+
+static inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
+{
+ return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
+}
+
+static inline int ieee754sp_le(ieee754sp x, ieee754sp y)
+{
+ return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
+}
+
+static inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
+{
+ return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
+}
+
+
+static inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
+{
+ return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
+}
+
+static inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
+{
+ return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
+}
+
+static inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
+{
+ return ieee754dp_cmp(x, y,
+ IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
+}
+
+static inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
+{
+ return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
+}
+
+static inline int ieee754dp_le(ieee754dp x, ieee754dp y)
+{
+ return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
+}
+
+static inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
+{
+ return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
+}
+
+static inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
+{
+ return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
+}
+
+
+/*
+ * Like strtod
+ */
+ieee754dp ieee754dp_fstr(const char *s, char **endp);
+char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
+
+
+/*
+ * The control status register
+ */
+struct _ieee754_csr {
+#ifdef __BIG_ENDIAN
+ unsigned pad0:7;
+ unsigned nod:1; /* set 1 for no denormalised numbers */
+ unsigned c:1; /* condition */
+ unsigned pad1:5;
+ unsigned cx:6; /* exceptions this operation */
+ unsigned mx:5; /* exception enable mask */
+ unsigned sx:5; /* exceptions total */
+ unsigned rm:2; /* current rounding mode */
+#endif
+#ifdef __LITTLE_ENDIAN
+ unsigned rm:2; /* current rounding mode */
+ unsigned sx:5; /* exceptions total */
+ unsigned mx:5; /* exception enable mask */
+ unsigned cx:6; /* exceptions this operation */
+ unsigned pad1:5;
+ unsigned c:1; /* condition */
+ unsigned nod:1; /* set 1 for no denormalised numbers */
+ unsigned pad0:7;
+#endif
+};
+#define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.fcr31))
+
+static inline unsigned ieee754_getrm(void)
+{
+ return (ieee754_csr.rm);
+}
+static inline unsigned ieee754_setrm(unsigned rm)
+{
+ return (ieee754_csr.rm = rm);
+}
+
+/*
+ * get current exceptions
+ */
+static inline unsigned ieee754_getcx(void)
+{
+ return (ieee754_csr.cx);
+}
+
+/* test for current exception condition
+ */
+static inline int ieee754_cxtest(unsigned n)
+{
+ return (ieee754_csr.cx & n);
+}
+
+/*
+ * get sticky exceptions
+ */
+static inline unsigned ieee754_getsx(void)
+{
+ return (ieee754_csr.sx);
+}
+
+/* clear sticky conditions
+*/
+static inline unsigned ieee754_clrsx(void)
+{
+ return (ieee754_csr.sx = 0);
+}
+
+/* test for sticky exception condition
+ */
+static inline int ieee754_sxtest(unsigned n)
+{
+ return (ieee754_csr.sx & n);
+}
+
+/* debugging */
+ieee754sp ieee754sp_dump(char *s, ieee754sp x);
+ieee754dp ieee754dp_dump(char *s, ieee754dp x);
+
+#define IEEE754_SPCVAL_PZERO 0
+#define IEEE754_SPCVAL_NZERO 1
+#define IEEE754_SPCVAL_PONE 2
+#define IEEE754_SPCVAL_NONE 3
+#define IEEE754_SPCVAL_PTEN 4
+#define IEEE754_SPCVAL_NTEN 5
+#define IEEE754_SPCVAL_PINFINITY 6
+#define IEEE754_SPCVAL_NINFINITY 7
+#define IEEE754_SPCVAL_INDEF 8
+#define IEEE754_SPCVAL_PMAX 9 /* +max norm */
+#define IEEE754_SPCVAL_NMAX 10 /* -max norm */
+#define IEEE754_SPCVAL_PMIN 11 /* +min norm */
+#define IEEE754_SPCVAL_NMIN 12 /* +min norm */
+#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
+#define IEEE754_SPCVAL_NMIND 14 /* +min denorm */
+#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
+#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
+
+extern const struct ieee754dp_konst __ieee754dp_spcvals[];
+extern const struct ieee754sp_konst __ieee754sp_spcvals[];
+#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
+#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
+
+/*
+ * Return infinity with given sign
+ */
+#define ieee754dp_inf(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+#define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+#define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+#define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+#define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+#define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+#define ieee754dp_1e31() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
+#define ieee754dp_1e63() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
+
+#define ieee754sp_inf(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
+#define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
+#define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
+#define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
+#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
+#define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
+#define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
+#define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
+#define ieee754sp_1e31() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
+#define ieee754sp_1e63() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
+
+/*
+ * Indefinite integer value
+ */
+#define ieee754si_indef() INT_MAX
+#ifdef LONG_LONG_MAX
+#define ieee754di_indef() LONG_LONG_MAX
+#else
+#define ieee754di_indef() ((s64)(~0ULL>>1))
+#endif
+
+/* IEEE exception context, passed to handler */
+struct ieee754xctx {
+ const char *op; /* operation name */
+ int rt; /* result type */
+ union {
+ ieee754sp sp; /* single precision */
+ ieee754dp dp; /* double precision */
+#ifdef IEEE854_XP
+ ieee754xp xp; /* extended precision */
+#endif
+ int si; /* standard signed integer (32bits) */
+ s64 di; /* extended signed integer (64bits) */
+ } rv; /* default result format implied by op */
+ va_list ap;
+};
+
+/* result types for xctx.rt */
+#define IEEE754_RT_SP 0
+#define IEEE754_RT_DP 1
+#define IEEE754_RT_XP 2
+#define IEEE754_RT_SI 3
+#define IEEE754_RT_DI 4
+
+extern void ieee754_xcpt(struct ieee754xctx *xcp);
+
+/* compat */
+#define ieee754dp_fix(x) ieee754dp_tint(x)
+#define ieee754sp_fix(x) ieee754sp_tint(x)
+
+#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */
diff --git a/arch/mips/math-emu/ieee754d.c b/arch/mips/math-emu/ieee754d.c
new file mode 100644
index 00000000..9599bdd3
--- /dev/null
+++ b/arch/mips/math-emu/ieee754d.c
@@ -0,0 +1,136 @@
+/*
+ * Some debug functions
+ *
+ * MIPS floating point support
+ *
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Nov 7, 2000
+ * Modified to build and operate in Linux kernel environment.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include "ieee754.h"
+
+#define DP_EBIAS 1023
+#define DP_EMIN (-1022)
+#define DP_EMAX 1023
+#define DP_FBITS 52
+
+#define SP_EBIAS 127
+#define SP_EMIN (-126)
+#define SP_EMAX 127
+#define SP_FBITS 23
+
+#define DP_MBIT(x) ((u64)1 << (x))
+#define DP_HIDDEN_BIT DP_MBIT(DP_FBITS)
+#define DP_SIGN_BIT DP_MBIT(63)
+
+
+#define SP_MBIT(x) ((u32)1 << (x))
+#define SP_HIDDEN_BIT SP_MBIT(SP_FBITS)
+#define SP_SIGN_BIT SP_MBIT(31)
+
+
+#define SPSIGN(sp) (sp.parts.sign)
+#define SPBEXP(sp) (sp.parts.bexp)
+#define SPMANT(sp) (sp.parts.mant)
+
+#define DPSIGN(dp) (dp.parts.sign)
+#define DPBEXP(dp) (dp.parts.bexp)
+#define DPMANT(dp) (dp.parts.mant)
+
+ieee754dp ieee754dp_dump(char *m, ieee754dp x)
+{
+ int i;
+
+ printk("%s", m);
+ printk("<%08x,%08x>\n", (unsigned) (x.bits >> 32),
+ (unsigned) x.bits);
+ printk("\t=");
+ switch (ieee754dp_class(x)) {
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_SNAN:
+ printk("Nan %c", DPSIGN(x) ? '-' : '+');
+ for (i = DP_FBITS - 1; i >= 0; i--)
+ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
+ break;
+ case IEEE754_CLASS_INF:
+ printk("%cInfinity", DPSIGN(x) ? '-' : '+');
+ break;
+ case IEEE754_CLASS_ZERO:
+ printk("%cZero", DPSIGN(x) ? '-' : '+');
+ break;
+ case IEEE754_CLASS_DNORM:
+ printk("%c0.", DPSIGN(x) ? '-' : '+');
+ for (i = DP_FBITS - 1; i >= 0; i--)
+ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
+ printk("e%d", DPBEXP(x) - DP_EBIAS);
+ break;
+ case IEEE754_CLASS_NORM:
+ printk("%c1.", DPSIGN(x) ? '-' : '+');
+ for (i = DP_FBITS - 1; i >= 0; i--)
+ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
+ printk("e%d", DPBEXP(x) - DP_EBIAS);
+ break;
+ default:
+ printk("Illegal/Unknown IEEE754 value class");
+ }
+ printk("\n");
+ return x;
+}
+
+ieee754sp ieee754sp_dump(char *m, ieee754sp x)
+{
+ int i;
+
+ printk("%s=", m);
+ printk("<%08x>\n", (unsigned) x.bits);
+ printk("\t=");
+ switch (ieee754sp_class(x)) {
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_SNAN:
+ printk("Nan %c", SPSIGN(x) ? '-' : '+');
+ for (i = SP_FBITS - 1; i >= 0; i--)
+ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
+ break;
+ case IEEE754_CLASS_INF:
+ printk("%cInfinity", SPSIGN(x) ? '-' : '+');
+ break;
+ case IEEE754_CLASS_ZERO:
+ printk("%cZero", SPSIGN(x) ? '-' : '+');
+ break;
+ case IEEE754_CLASS_DNORM:
+ printk("%c0.", SPSIGN(x) ? '-' : '+');
+ for (i = SP_FBITS - 1; i >= 0; i--)
+ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
+ printk("e%d", SPBEXP(x) - SP_EBIAS);
+ break;
+ case IEEE754_CLASS_NORM:
+ printk("%c1.", SPSIGN(x) ? '-' : '+');
+ for (i = SP_FBITS - 1; i >= 0; i--)
+ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
+ printk("e%d", SPBEXP(x) - SP_EBIAS);
+ break;
+ default:
+ printk("Illegal/Unknown IEEE754 value class");
+ }
+ printk("\n");
+ return x;
+}
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
new file mode 100644
index 00000000..080b5ca0
--- /dev/null
+++ b/arch/mips/math-emu/ieee754dp.c
@@ -0,0 +1,243 @@
+/* IEEE754 floating point arithmetic
+ * double precision: common utilities
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754dp.h"
+
+int ieee754dp_class(ieee754dp x)
+{
+ COMPXDP;
+ EXPLODEXDP;
+ return xc;
+}
+
+int ieee754dp_isnan(ieee754dp x)
+{
+ return ieee754dp_class(x) >= IEEE754_CLASS_SNAN;
+}
+
+int ieee754dp_issnan(ieee754dp x)
+{
+ assert(ieee754dp_isnan(x));
+ return ((DPMANT(x) & DP_MBIT(DP_MBITS-1)) == DP_MBIT(DP_MBITS-1));
+}
+
+
+ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...)
+{
+ struct ieee754xctx ax;
+ if (!TSTX())
+ return r;
+
+ ax.op = op;
+ ax.rt = IEEE754_RT_DP;
+ ax.rv.dp = r;
+ va_start(ax.ap, op);
+ ieee754_xcpt(&ax);
+ va_end(ax.ap);
+ return ax.rv.dp;
+}
+
+ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...)
+{
+ struct ieee754xctx ax;
+
+ assert(ieee754dp_isnan(r));
+
+ if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */
+ return r;
+
+ if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) {
+ /* not enabled convert to a quiet NaN */
+ DPMANT(r) &= (~DP_MBIT(DP_MBITS-1));
+ if (ieee754dp_isnan(r))
+ return r;
+ else
+ return ieee754dp_indef();
+ }
+
+ ax.op = op;
+ ax.rt = 0;
+ ax.rv.dp = r;
+ va_start(ax.ap, op);
+ ieee754_xcpt(&ax);
+ va_end(ax.ap);
+ return ax.rv.dp;
+}
+
+ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y)
+{
+ assert(ieee754dp_isnan(x));
+ assert(ieee754dp_isnan(y));
+
+ if (DPMANT(x) > DPMANT(y))
+ return x;
+ else
+ return y;
+}
+
+
+static u64 get_rounding(int sn, u64 xm)
+{
+ /* inexact must round of 3 bits
+ */
+ if (xm & (DP_MBIT(3) - 1)) {
+ switch (ieee754_csr.rm) {
+ case IEEE754_RZ:
+ break;
+ case IEEE754_RN:
+ xm += 0x3 + ((xm >> 3) & 1);
+ /* xm += (xm&0x8)?0x4:0x3 */
+ break;
+ case IEEE754_RU: /* toward +Infinity */
+ if (!sn) /* ?? */
+ xm += 0x8;
+ break;
+ case IEEE754_RD: /* toward -Infinity */
+ if (sn) /* ?? */
+ xm += 0x8;
+ break;
+ }
+ }
+ return xm;
+}
+
+
+/* generate a normal/denormal number with over,under handling
+ * sn is sign
+ * xe is an unbiased exponent
+ * xm is 3bit extended precision value.
+ */
+ieee754dp ieee754dp_format(int sn, int xe, u64 xm)
+{
+ assert(xm); /* we don't gen exact zeros (probably should) */
+
+ assert((xm >> (DP_MBITS + 1 + 3)) == 0); /* no execess */
+ assert(xm & (DP_HIDDEN_BIT << 3));
+
+ if (xe < DP_EMIN) {
+ /* strip lower bits */
+ int es = DP_EMIN - xe;
+
+ if (ieee754_csr.nod) {
+ SETCX(IEEE754_UNDERFLOW);
+ SETCX(IEEE754_INEXACT);
+
+ switch(ieee754_csr.rm) {
+ case IEEE754_RN:
+ case IEEE754_RZ:
+ return ieee754dp_zero(sn);
+ case IEEE754_RU: /* toward +Infinity */
+ if(sn == 0)
+ return ieee754dp_min(0);
+ else
+ return ieee754dp_zero(1);
+ case IEEE754_RD: /* toward -Infinity */
+ if(sn == 0)
+ return ieee754dp_zero(0);
+ else
+ return ieee754dp_min(1);
+ }
+ }
+
+ if (xe == DP_EMIN - 1
+ && get_rounding(sn, xm) >> (DP_MBITS + 1 + 3))
+ {
+ /* Not tiny after rounding */
+ SETCX(IEEE754_INEXACT);
+ xm = get_rounding(sn, xm);
+ xm >>= 1;
+ /* Clear grs bits */
+ xm &= ~(DP_MBIT(3) - 1);
+ xe++;
+ }
+ else {
+ /* sticky right shift es bits
+ */
+ xm = XDPSRS(xm, es);
+ xe += es;
+ assert((xm & (DP_HIDDEN_BIT << 3)) == 0);
+ assert(xe == DP_EMIN);
+ }
+ }
+ if (xm & (DP_MBIT(3) - 1)) {
+ SETCX(IEEE754_INEXACT);
+ if ((xm & (DP_HIDDEN_BIT << 3)) == 0) {
+ SETCX(IEEE754_UNDERFLOW);
+ }
+
+ /* inexact must round of 3 bits
+ */
+ xm = get_rounding(sn, xm);
+ /* adjust exponent for rounding add overflowing
+ */
+ if (xm >> (DP_MBITS + 3 + 1)) {
+ /* add causes mantissa overflow */
+ xm >>= 1;
+ xe++;
+ }
+ }
+ /* strip grs bits */
+ xm >>= 3;
+
+ assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */
+ assert(xe >= DP_EMIN);
+
+ if (xe > DP_EMAX) {
+ SETCX(IEEE754_OVERFLOW);
+ SETCX(IEEE754_INEXACT);
+ /* -O can be table indexed by (rm,sn) */
+ switch (ieee754_csr.rm) {
+ case IEEE754_RN:
+ return ieee754dp_inf(sn);
+ case IEEE754_RZ:
+ return ieee754dp_max(sn);
+ case IEEE754_RU: /* toward +Infinity */
+ if (sn == 0)
+ return ieee754dp_inf(0);
+ else
+ return ieee754dp_max(1);
+ case IEEE754_RD: /* toward -Infinity */
+ if (sn == 0)
+ return ieee754dp_max(0);
+ else
+ return ieee754dp_inf(1);
+ }
+ }
+ /* gen norm/denorm/zero */
+
+ if ((xm & DP_HIDDEN_BIT) == 0) {
+ /* we underflow (tiny/zero) */
+ assert(xe == DP_EMIN);
+ if (ieee754_csr.mx & IEEE754_UNDERFLOW)
+ SETCX(IEEE754_UNDERFLOW);
+ return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm);
+ } else {
+ assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */
+ assert(xm & DP_HIDDEN_BIT);
+
+ return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+ }
+}
diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h
new file mode 100644
index 00000000..f139c724
--- /dev/null
+++ b/arch/mips/math-emu/ieee754dp.h
@@ -0,0 +1,82 @@
+/*
+ * IEEE754 floating point
+ * double precision internal header file
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754int.h"
+
+#define assert(expr) ((void)0)
+
+/* 3bit extended double precision sticky right shift */
+#define XDPSRS(v,rs) \
+ ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0))
+
+#define XDPSRSX1() \
+ (xe++, (xm = (xm >> 1) | (xm & 1)))
+
+#define XDPSRS1(v) \
+ (((v) >> 1) | ((v) & 1))
+
+/* convert denormal to normalized with extended exponent */
+#define DPDNORMx(m,e) \
+ while( (m >> DP_MBITS) == 0) { m <<= 1; e--; }
+#define DPDNORMX DPDNORMx(xm, xe)
+#define DPDNORMY DPDNORMx(ym, ye)
+
+static inline ieee754dp builddp(int s, int bx, u64 m)
+{
+ ieee754dp r;
+
+ assert((s) == 0 || (s) == 1);
+ assert((bx) >= DP_EMIN - 1 + DP_EBIAS
+ && (bx) <= DP_EMAX + 1 + DP_EBIAS);
+ assert(((m) >> DP_MBITS) == 0);
+
+ r.parts.sign = s;
+ r.parts.bexp = bx;
+ r.parts.mant = m;
+ return r;
+}
+
+extern int ieee754dp_isnan(ieee754dp);
+extern int ieee754dp_issnan(ieee754dp);
+extern int ieee754si_xcpt(int, const char *, ...);
+extern s64 ieee754di_xcpt(s64, const char *, ...);
+extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...);
+extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...);
+extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp);
+extern ieee754dp ieee754dp_format(int, int, u64);
+
+
+#define DPNORMRET2(s, e, m, name, a0, a1) \
+{ \
+ ieee754dp V = ieee754dp_format(s, e, m); \
+ if(TSTX()) \
+ return ieee754dp_xcpt(V, name, a0, a1); \
+ else \
+ return V; \
+}
+
+#define DPNORMRET1(s, e, m, name, a0) DPNORMRET2(s, e, m, name, a0, a0)
diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h
new file mode 100644
index 00000000..2a7d43f4
--- /dev/null
+++ b/arch/mips/math-emu/ieee754int.h
@@ -0,0 +1,164 @@
+/*
+ * IEEE754 floating point
+ * common internal header file
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754.h"
+
+#define DP_EBIAS 1023
+#define DP_EMIN (-1022)
+#define DP_EMAX 1023
+#define DP_MBITS 52
+
+#define SP_EBIAS 127
+#define SP_EMIN (-126)
+#define SP_EMAX 127
+#define SP_MBITS 23
+
+#define DP_MBIT(x) ((u64)1 << (x))
+#define DP_HIDDEN_BIT DP_MBIT(DP_MBITS)
+#define DP_SIGN_BIT DP_MBIT(63)
+
+#define SP_MBIT(x) ((u32)1 << (x))
+#define SP_HIDDEN_BIT SP_MBIT(SP_MBITS)
+#define SP_SIGN_BIT SP_MBIT(31)
+
+
+#define SPSIGN(sp) (sp.parts.sign)
+#define SPBEXP(sp) (sp.parts.bexp)
+#define SPMANT(sp) (sp.parts.mant)
+
+#define DPSIGN(dp) (dp.parts.sign)
+#define DPBEXP(dp) (dp.parts.bexp)
+#define DPMANT(dp) (dp.parts.mant)
+
+#define CLPAIR(x, y) ((x)*6+(y))
+
+#define CLEARCX \
+ (ieee754_csr.cx = 0)
+
+#define SETCX(x) \
+ (ieee754_csr.cx |= (x), ieee754_csr.sx |= (x))
+
+#define SETANDTESTCX(x) \
+ (SETCX(x), ieee754_csr.mx & (x))
+
+#define TSTX() \
+ (ieee754_csr.cx & ieee754_csr.mx)
+
+
+#define COMPXSP \
+ unsigned xm; int xe; int xs __maybe_unused; int xc
+
+#define COMPYSP \
+ unsigned ym; int ye; int ys; int yc
+
+#define EXPLODESP(v, vc, vs, ve, vm) \
+{\
+ vs = SPSIGN(v);\
+ ve = SPBEXP(v);\
+ vm = SPMANT(v);\
+ if(ve == SP_EMAX+1+SP_EBIAS){\
+ if(vm == 0)\
+ vc = IEEE754_CLASS_INF;\
+ else if(vm & SP_MBIT(SP_MBITS-1)) \
+ vc = IEEE754_CLASS_SNAN;\
+ else \
+ vc = IEEE754_CLASS_QNAN;\
+ } else if(ve == SP_EMIN-1+SP_EBIAS) {\
+ if(vm) {\
+ ve = SP_EMIN;\
+ vc = IEEE754_CLASS_DNORM;\
+ } else\
+ vc = IEEE754_CLASS_ZERO;\
+ } else {\
+ ve -= SP_EBIAS;\
+ vm |= SP_HIDDEN_BIT;\
+ vc = IEEE754_CLASS_NORM;\
+ }\
+}
+#define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
+#define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
+
+
+#define COMPXDP \
+u64 xm; int xe; int xs __maybe_unused; int xc
+
+#define COMPYDP \
+u64 ym; int ye; int ys; int yc
+
+#define EXPLODEDP(v, vc, vs, ve, vm) \
+{\
+ vm = DPMANT(v);\
+ vs = DPSIGN(v);\
+ ve = DPBEXP(v);\
+ if(ve == DP_EMAX+1+DP_EBIAS){\
+ if(vm == 0)\
+ vc = IEEE754_CLASS_INF;\
+ else if(vm & DP_MBIT(DP_MBITS-1)) \
+ vc = IEEE754_CLASS_SNAN;\
+ else \
+ vc = IEEE754_CLASS_QNAN;\
+ } else if(ve == DP_EMIN-1+DP_EBIAS) {\
+ if(vm) {\
+ ve = DP_EMIN;\
+ vc = IEEE754_CLASS_DNORM;\
+ } else\
+ vc = IEEE754_CLASS_ZERO;\
+ } else {\
+ ve -= DP_EBIAS;\
+ vm |= DP_HIDDEN_BIT;\
+ vc = IEEE754_CLASS_NORM;\
+ }\
+}
+#define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
+#define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
+
+#define FLUSHDP(v, vc, vs, ve, vm) \
+ if(vc==IEEE754_CLASS_DNORM) {\
+ if(ieee754_csr.nod) {\
+ SETCX(IEEE754_INEXACT);\
+ vc = IEEE754_CLASS_ZERO;\
+ ve = DP_EMIN-1+DP_EBIAS;\
+ vm = 0;\
+ v = ieee754dp_zero(vs);\
+ }\
+ }
+
+#define FLUSHSP(v, vc, vs, ve, vm) \
+ if(vc==IEEE754_CLASS_DNORM) {\
+ if(ieee754_csr.nod) {\
+ SETCX(IEEE754_INEXACT);\
+ vc = IEEE754_CLASS_ZERO;\
+ ve = SP_EMIN-1+SP_EBIAS;\
+ vm = 0;\
+ v = ieee754sp_zero(vs);\
+ }\
+ }
+
+#define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
+#define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
+#define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
+#define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
diff --git a/arch/mips/math-emu/ieee754m.c b/arch/mips/math-emu/ieee754m.c
new file mode 100644
index 00000000..24190f3c
--- /dev/null
+++ b/arch/mips/math-emu/ieee754m.c
@@ -0,0 +1,55 @@
+/*
+ * floor, trunc, ceil
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754.h"
+
+ieee754dp ieee754dp_floor(ieee754dp x)
+{
+ ieee754dp i;
+
+ if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
+ return ieee754dp_sub(i, ieee754dp_one(0));
+ else
+ return i;
+}
+
+ieee754dp ieee754dp_ceil(ieee754dp x)
+{
+ ieee754dp i;
+
+ if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
+ return ieee754dp_add(i, ieee754dp_one(0));
+ else
+ return i;
+}
+
+ieee754dp ieee754dp_trunc(ieee754dp x)
+{
+ ieee754dp i;
+
+ (void) ieee754dp_modf(x, &i);
+ return i;
+}
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
new file mode 100644
index 00000000..271d00d6
--- /dev/null
+++ b/arch/mips/math-emu/ieee754sp.c
@@ -0,0 +1,243 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+int ieee754sp_class(ieee754sp x)
+{
+ COMPXSP;
+ EXPLODEXSP;
+ return xc;
+}
+
+int ieee754sp_isnan(ieee754sp x)
+{
+ return ieee754sp_class(x) >= IEEE754_CLASS_SNAN;
+}
+
+int ieee754sp_issnan(ieee754sp x)
+{
+ assert(ieee754sp_isnan(x));
+ return (SPMANT(x) & SP_MBIT(SP_MBITS-1));
+}
+
+
+ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...)
+{
+ struct ieee754xctx ax;
+
+ if (!TSTX())
+ return r;
+
+ ax.op = op;
+ ax.rt = IEEE754_RT_SP;
+ ax.rv.sp = r;
+ va_start(ax.ap, op);
+ ieee754_xcpt(&ax);
+ va_end(ax.ap);
+ return ax.rv.sp;
+}
+
+ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...)
+{
+ struct ieee754xctx ax;
+
+ assert(ieee754sp_isnan(r));
+
+ if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */
+ return r;
+
+ if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) {
+ /* not enabled convert to a quiet NaN */
+ SPMANT(r) &= (~SP_MBIT(SP_MBITS-1));
+ if (ieee754sp_isnan(r))
+ return r;
+ else
+ return ieee754sp_indef();
+ }
+
+ ax.op = op;
+ ax.rt = 0;
+ ax.rv.sp = r;
+ va_start(ax.ap, op);
+ ieee754_xcpt(&ax);
+ va_end(ax.ap);
+ return ax.rv.sp;
+}
+
+ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y)
+{
+ assert(ieee754sp_isnan(x));
+ assert(ieee754sp_isnan(y));
+
+ if (SPMANT(x) > SPMANT(y))
+ return x;
+ else
+ return y;
+}
+
+
+static unsigned get_rounding(int sn, unsigned xm)
+{
+ /* inexact must round of 3 bits
+ */
+ if (xm & (SP_MBIT(3) - 1)) {
+ switch (ieee754_csr.rm) {
+ case IEEE754_RZ:
+ break;
+ case IEEE754_RN:
+ xm += 0x3 + ((xm >> 3) & 1);
+ /* xm += (xm&0x8)?0x4:0x3 */
+ break;
+ case IEEE754_RU: /* toward +Infinity */
+ if (!sn) /* ?? */
+ xm += 0x8;
+ break;
+ case IEEE754_RD: /* toward -Infinity */
+ if (sn) /* ?? */
+ xm += 0x8;
+ break;
+ }
+ }
+ return xm;
+}
+
+
+/* generate a normal/denormal number with over,under handling
+ * sn is sign
+ * xe is an unbiased exponent
+ * xm is 3bit extended precision value.
+ */
+ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
+{
+ assert(xm); /* we don't gen exact zeros (probably should) */
+
+ assert((xm >> (SP_MBITS + 1 + 3)) == 0); /* no execess */
+ assert(xm & (SP_HIDDEN_BIT << 3));
+
+ if (xe < SP_EMIN) {
+ /* strip lower bits */
+ int es = SP_EMIN - xe;
+
+ if (ieee754_csr.nod) {
+ SETCX(IEEE754_UNDERFLOW);
+ SETCX(IEEE754_INEXACT);
+
+ switch(ieee754_csr.rm) {
+ case IEEE754_RN:
+ case IEEE754_RZ:
+ return ieee754sp_zero(sn);
+ case IEEE754_RU: /* toward +Infinity */
+ if(sn == 0)
+ return ieee754sp_min(0);
+ else
+ return ieee754sp_zero(1);
+ case IEEE754_RD: /* toward -Infinity */
+ if(sn == 0)
+ return ieee754sp_zero(0);
+ else
+ return ieee754sp_min(1);
+ }
+ }
+
+ if (xe == SP_EMIN - 1
+ && get_rounding(sn, xm) >> (SP_MBITS + 1 + 3))
+ {
+ /* Not tiny after rounding */
+ SETCX(IEEE754_INEXACT);
+ xm = get_rounding(sn, xm);
+ xm >>= 1;
+ /* Clear grs bits */
+ xm &= ~(SP_MBIT(3) - 1);
+ xe++;
+ }
+ else {
+ /* sticky right shift es bits
+ */
+ SPXSRSXn(es);
+ assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
+ assert(xe == SP_EMIN);
+ }
+ }
+ if (xm & (SP_MBIT(3) - 1)) {
+ SETCX(IEEE754_INEXACT);
+ if ((xm & (SP_HIDDEN_BIT << 3)) == 0) {
+ SETCX(IEEE754_UNDERFLOW);
+ }
+
+ /* inexact must round of 3 bits
+ */
+ xm = get_rounding(sn, xm);
+ /* adjust exponent for rounding add overflowing
+ */
+ if (xm >> (SP_MBITS + 1 + 3)) {
+ /* add causes mantissa overflow */
+ xm >>= 1;
+ xe++;
+ }
+ }
+ /* strip grs bits */
+ xm >>= 3;
+
+ assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */
+ assert(xe >= SP_EMIN);
+
+ if (xe > SP_EMAX) {
+ SETCX(IEEE754_OVERFLOW);
+ SETCX(IEEE754_INEXACT);
+ /* -O can be table indexed by (rm,sn) */
+ switch (ieee754_csr.rm) {
+ case IEEE754_RN:
+ return ieee754sp_inf(sn);
+ case IEEE754_RZ:
+ return ieee754sp_max(sn);
+ case IEEE754_RU: /* toward +Infinity */
+ if (sn == 0)
+ return ieee754sp_inf(0);
+ else
+ return ieee754sp_max(1);
+ case IEEE754_RD: /* toward -Infinity */
+ if (sn == 0)
+ return ieee754sp_max(0);
+ else
+ return ieee754sp_inf(1);
+ }
+ }
+ /* gen norm/denorm/zero */
+
+ if ((xm & SP_HIDDEN_BIT) == 0) {
+ /* we underflow (tiny/zero) */
+ assert(xe == SP_EMIN);
+ if (ieee754_csr.mx & IEEE754_UNDERFLOW)
+ SETCX(IEEE754_UNDERFLOW);
+ return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm);
+ } else {
+ assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */
+ assert(xm & SP_HIDDEN_BIT);
+
+ return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
+ }
+}
diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h
new file mode 100644
index 00000000..754fd546
--- /dev/null
+++ b/arch/mips/math-emu/ieee754sp.h
@@ -0,0 +1,88 @@
+/*
+ * IEEE754 floating point
+ * double precision internal header file
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754int.h"
+
+#define assert(expr) ((void)0)
+
+/* 3bit extended single precision sticky right shift */
+#define SPXSRSXn(rs) \
+ (xe += rs, \
+ xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
+
+#define SPXSRSX1() \
+ (xe++, (xm = (xm >> 1) | (xm & 1)))
+
+#define SPXSRSYn(rs) \
+ (ye+=rs, \
+ ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
+
+#define SPXSRSY1() \
+ (ye++, (ym = (ym >> 1) | (ym & 1)))
+
+/* convert denormal to normalized with extended exponent */
+#define SPDNORMx(m,e) \
+ while( (m >> SP_MBITS) == 0) { m <<= 1; e--; }
+#define SPDNORMX SPDNORMx(xm, xe)
+#define SPDNORMY SPDNORMx(ym, ye)
+
+static inline ieee754sp buildsp(int s, int bx, unsigned m)
+{
+ ieee754sp r;
+
+ assert((s) == 0 || (s) == 1);
+ assert((bx) >= SP_EMIN - 1 + SP_EBIAS
+ && (bx) <= SP_EMAX + 1 + SP_EBIAS);
+ assert(((m) >> SP_MBITS) == 0);
+
+ r.parts.sign = s;
+ r.parts.bexp = bx;
+ r.parts.mant = m;
+
+ return r;
+}
+
+extern int ieee754sp_isnan(ieee754sp);
+extern int ieee754sp_issnan(ieee754sp);
+extern int ieee754si_xcpt(int, const char *, ...);
+extern s64 ieee754di_xcpt(s64, const char *, ...);
+extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...);
+extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...);
+extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp);
+extern ieee754sp ieee754sp_format(int, int, unsigned);
+
+
+#define SPNORMRET2(s, e, m, name, a0, a1) \
+{ \
+ ieee754sp V = ieee754sp_format(s, e, m); \
+ if(TSTX()) \
+ return ieee754sp_xcpt(V, name, a0, a1); \
+ else \
+ return V; \
+}
+
+#define SPNORMRET1(s, e, m, name, a0) SPNORMRET2(s, e, m, name, a0, a0)
diff --git a/arch/mips/math-emu/ieee754xcpt.c b/arch/mips/math-emu/ieee754xcpt.c
new file mode 100644
index 00000000..b99a693c
--- /dev/null
+++ b/arch/mips/math-emu/ieee754xcpt.c
@@ -0,0 +1,47 @@
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+/**************************************************************************
+ * Nov 7, 2000
+ * Added preprocessor hacks to map to Linux kernel diagnostics.
+ *
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *************************************************************************/
+
+#include <linux/kernel.h>
+#include "ieee754.h"
+
+/*
+ * Very naff exception handler (you can plug in your own and
+ * override this).
+ */
+
+static const char *const rtnames[] = {
+ "sp", "dp", "xp", "si", "di"
+};
+
+void ieee754_xcpt(struct ieee754xctx *xcp)
+{
+ printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n",
+ xcp->op, rtnames[xcp->rt]);
+}
diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c
new file mode 100644
index 00000000..52e6c58c
--- /dev/null
+++ b/arch/mips/math-emu/kernel_linkage.c
@@ -0,0 +1,115 @@
+/*
+ * Kevin D. Kissell, kevink@mips and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines corresponding to Linux kernel FP context
+ * manipulation primitives for the Algorithmics MIPS
+ * FPU Emulator
+ */
+#include <linux/sched.h>
+#include <asm/processor.h>
+#include <asm/signal.h>
+#include <asm/uaccess.h>
+
+#include <asm/fpu.h>
+#include <asm/fpu_emulator.h>
+
+#define SIGNALLING_NAN 0x7ff800007ff80000LL
+
+void fpu_emulator_init_fpu(void)
+{
+ static int first = 1;
+ int i;
+
+ if (first) {
+ first = 0;
+ printk("Algorithmics/MIPS FPU Emulator v1.5\n");
+ }
+
+ current->thread.fpu.fcr31 = 0;
+ for (i = 0; i < 32; i++) {
+ current->thread.fpu.fpr[i] = SIGNALLING_NAN;
+ }
+}
+
+
+/*
+ * Emulator context save/restore to/from a signal context
+ * presumed to be on the user stack, and therefore accessed
+ * with appropriate macros from uaccess.h
+ */
+
+int fpu_emulator_save_context(struct sigcontext __user *sc)
+{
+ int i;
+ int err = 0;
+
+ for (i = 0; i < 32; i++) {
+ err |=
+ __put_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
+ }
+ err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
+
+ return err;
+}
+
+int fpu_emulator_restore_context(struct sigcontext __user *sc)
+{
+ int i;
+ int err = 0;
+
+ for (i = 0; i < 32; i++) {
+ err |=
+ __get_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
+ }
+ err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
+
+ return err;
+}
+
+#ifdef CONFIG_64BIT
+/*
+ * This is the o32 version
+ */
+
+int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
+{
+ int i;
+ int err = 0;
+
+ for (i = 0; i < 32; i+=2) {
+ err |=
+ __put_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
+ }
+ err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
+
+ return err;
+}
+
+int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
+{
+ int i;
+ int err = 0;
+
+ for (i = 0; i < 32; i+=2) {
+ err |=
+ __get_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
+ }
+ err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
+
+ return err;
+}
+#endif
diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c
new file mode 100644
index 00000000..ae1a327c
--- /dev/null
+++ b/arch/mips/math-emu/sp_add.c
@@ -0,0 +1,176 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y)
+{
+ COMPXSP;
+ COMPYSP;
+
+ EXPLODEXSP;
+ EXPLODEYSP;
+
+ CLEARCX;
+
+ FLUSHXSP;
+ FLUSHYSP;
+
+ switch (CLPAIR(xc, yc)) {
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "add", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+ return x;
+
+
+ /* Infinity handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ if (xs == ys)
+ return x;
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+ return x;
+
+ /* Zero handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+ if (xs == ys)
+ return x;
+ else
+ return ieee754sp_zero(ieee754_csr.rm ==
+ IEEE754_RD);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+ return x;
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+ SPDNORMX;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+ SPDNORMY;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+ SPDNORMX;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+ break;
+ }
+ assert(xm & SP_HIDDEN_BIT);
+ assert(ym & SP_HIDDEN_BIT);
+
+ /* provide guard,round and stick bit space */
+ xm <<= 3;
+ ym <<= 3;
+
+ if (xe > ye) {
+ /* have to shift y fraction right to align
+ */
+ int s = xe - ye;
+ SPXSRSYn(s);
+ } else if (ye > xe) {
+ /* have to shift x fraction right to align
+ */
+ int s = ye - xe;
+ SPXSRSXn(s);
+ }
+ assert(xe == ye);
+ assert(xe <= SP_EMAX);
+
+ if (xs == ys) {
+ /* generate 28 bit result of adding two 27 bit numbers
+ * leaving result in xm,xs,xe
+ */
+ xm = xm + ym;
+ xe = xe;
+ xs = xs;
+
+ if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */
+ SPXSRSX1();
+ }
+ } else {
+ if (xm >= ym) {
+ xm = xm - ym;
+ xe = xe;
+ xs = xs;
+ } else {
+ xm = ym - xm;
+ xe = xe;
+ xs = ys;
+ }
+ if (xm == 0)
+ return ieee754sp_zero(ieee754_csr.rm ==
+ IEEE754_RD);
+
+ /* normalize in extended single precision */
+ while ((xm >> (SP_MBITS + 3)) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+
+ }
+ SPNORMRET2(xs, xe, xm, "add", x, y);
+}
diff --git a/arch/mips/math-emu/sp_cmp.c b/arch/mips/math-emu/sp_cmp.c
new file mode 100644
index 00000000..716cf37e
--- /dev/null
+++ b/arch/mips/math-emu/sp_cmp.c
@@ -0,0 +1,66 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig)
+{
+ COMPXSP;
+ COMPYSP;
+
+ EXPLODEXSP;
+ EXPLODEYSP;
+ FLUSHXSP;
+ FLUSHYSP;
+ CLEARCX; /* Even clear inexact flag here */
+
+ if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
+ if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+ SETCX(IEEE754_INVALID_OPERATION);
+ if (cmp & IEEE754_CUN)
+ return 1;
+ if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
+ if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION))
+ return ieee754si_xcpt(0, "fcmpf", x);
+ }
+ return 0;
+ } else {
+ int vx = x.bits;
+ int vy = y.bits;
+
+ if (vx < 0)
+ vx = -vx ^ SP_SIGN_BIT;
+ if (vy < 0)
+ vy = -vy ^ SP_SIGN_BIT;
+
+ if (vx < vy)
+ return (cmp & IEEE754_CLT) != 0;
+ else if (vx == vy)
+ return (cmp & IEEE754_CEQ) != 0;
+ else
+ return (cmp & IEEE754_CGT) != 0;
+ }
+}
diff --git a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c
new file mode 100644
index 00000000..d7747928
--- /dev/null
+++ b/arch/mips/math-emu/sp_div.c
@@ -0,0 +1,156 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y)
+{
+ COMPXSP;
+ COMPYSP;
+
+ EXPLODEXSP;
+ EXPLODEYSP;
+
+ CLEARCX;
+
+ FLUSHXSP;
+ FLUSHYSP;
+
+ switch (CLPAIR(xc, yc)) {
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "div", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+ return x;
+
+
+ /* Infinity handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+ return ieee754sp_zero(xs ^ ys);
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+ return ieee754sp_inf(xs ^ ys);
+
+ /* Zero handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+ SETCX(IEEE754_ZERO_DIVIDE);
+ return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+ return ieee754sp_zero(xs == ys ? 0 : 1);
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+ SPDNORMX;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+ SPDNORMY;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+ SPDNORMX;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+ break;
+ }
+ assert(xm & SP_HIDDEN_BIT);
+ assert(ym & SP_HIDDEN_BIT);
+
+ /* provide rounding space */
+ xm <<= 3;
+ ym <<= 3;
+
+ {
+ /* now the dirty work */
+
+ unsigned rm = 0;
+ int re = xe - ye;
+ unsigned bm;
+
+ for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) {
+ if (xm >= ym) {
+ xm -= ym;
+ rm |= bm;
+ if (xm == 0)
+ break;
+ }
+ xm <<= 1;
+ }
+ rm <<= 1;
+ if (xm)
+ rm |= 1; /* have remainder, set sticky */
+
+ assert(rm);
+
+ /* normalise rm to rounding precision ?
+ */
+ while ((rm >> (SP_MBITS + 3)) == 0) {
+ rm <<= 1;
+ re--;
+ }
+
+ SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
+ }
+}
diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c
new file mode 100644
index 00000000..e1515aae
--- /dev/null
+++ b/arch/mips/math-emu/sp_fdp.c
@@ -0,0 +1,76 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_fdp(ieee754dp x)
+{
+ COMPXDP;
+ ieee754sp nan;
+
+ EXPLODEXDP;
+
+ CLEARCX;
+
+ FLUSHXDP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp");
+ case IEEE754_CLASS_QNAN:
+ nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32)
+ (xm >> (DP_MBITS - SP_MBITS)));
+ if (!ieee754sp_isnan(nan))
+ nan = ieee754sp_indef();
+ return ieee754sp_nanxcpt(nan, "fdp", x);
+ case IEEE754_CLASS_INF:
+ return ieee754sp_inf(xs);
+ case IEEE754_CLASS_ZERO:
+ return ieee754sp_zero(xs);
+ case IEEE754_CLASS_DNORM:
+ /* can't possibly be sp representable */
+ SETCX(IEEE754_UNDERFLOW);
+ SETCX(IEEE754_INEXACT);
+ if ((ieee754_csr.rm == IEEE754_RU && !xs) ||
+ (ieee754_csr.rm == IEEE754_RD && xs))
+ return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x);
+ return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+
+ {
+ u32 rm;
+
+ /* convert from DP_MBITS to SP_MBITS+3 with sticky right shift
+ */
+ rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) |
+ ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0);
+
+ SPNORMRET1(xs, xe, rm, "fdp", x);
+ }
+}
diff --git a/arch/mips/math-emu/sp_fint.c b/arch/mips/math-emu/sp_fint.c
new file mode 100644
index 00000000..9694d6c0
--- /dev/null
+++ b/arch/mips/math-emu/sp_fint.c
@@ -0,0 +1,79 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_fint(int x)
+{
+ unsigned xm;
+ int xe;
+ int xs;
+
+ CLEARCX;
+
+ if (x == 0)
+ return ieee754sp_zero(0);
+ if (x == 1 || x == -1)
+ return ieee754sp_one(x < 0);
+ if (x == 10 || x == -10)
+ return ieee754sp_ten(x < 0);
+
+ xs = (x < 0);
+ if (xs) {
+ if (x == (1 << 31))
+ xm = ((unsigned) 1 << 31); /* max neg can't be safely negated */
+ else
+ xm = -x;
+ } else {
+ xm = x;
+ }
+ xe = SP_MBITS + 3;
+
+ if (xm >> (SP_MBITS + 1 + 3)) {
+ /* shunt out overflow bits
+ */
+ while (xm >> (SP_MBITS + 1 + 3)) {
+ SPXSRSX1();
+ }
+ } else {
+ /* normalize in grs extended single precision
+ */
+ while ((xm >> (SP_MBITS + 3)) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ }
+ SPNORMRET1(xs, xe, xm, "fint", x);
+}
+
+
+ieee754sp ieee754sp_funs(unsigned int u)
+{
+ if ((int) u < 0)
+ return ieee754sp_add(ieee754sp_1e31(),
+ ieee754sp_fint(u & ~(1 << 31)));
+ return ieee754sp_fint(u);
+}
diff --git a/arch/mips/math-emu/sp_flong.c b/arch/mips/math-emu/sp_flong.c
new file mode 100644
index 00000000..16a651f2
--- /dev/null
+++ b/arch/mips/math-emu/sp_flong.c
@@ -0,0 +1,78 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_flong(s64 x)
+{
+ u64 xm; /* <--- need 64-bit mantissa temp */
+ int xe;
+ int xs;
+
+ CLEARCX;
+
+ if (x == 0)
+ return ieee754sp_zero(0);
+ if (x == 1 || x == -1)
+ return ieee754sp_one(x < 0);
+ if (x == 10 || x == -10)
+ return ieee754sp_ten(x < 0);
+
+ xs = (x < 0);
+ if (xs) {
+ if (x == (1ULL << 63))
+ xm = (1ULL << 63); /* max neg can't be safely negated */
+ else
+ xm = -x;
+ } else {
+ xm = x;
+ }
+ xe = SP_MBITS + 3;
+
+ if (xm >> (SP_MBITS + 1 + 3)) {
+ /* shunt out overflow bits
+ */
+ while (xm >> (SP_MBITS + 1 + 3)) {
+ SPXSRSX1();
+ }
+ } else {
+ /* normalize in grs extended single precision */
+ while ((xm >> (SP_MBITS + 3)) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ }
+ SPNORMRET1(xs, xe, xm, "sp_flong", x);
+}
+
+
+ieee754sp ieee754sp_fulong(u64 u)
+{
+ if ((s64) u < 0)
+ return ieee754sp_add(ieee754sp_1e63(),
+ ieee754sp_flong(u & ~(1ULL << 63)));
+ return ieee754sp_flong(u);
+}
diff --git a/arch/mips/math-emu/sp_frexp.c b/arch/mips/math-emu/sp_frexp.c
new file mode 100644
index 00000000..5bc993c3
--- /dev/null
+++ b/arch/mips/math-emu/sp_frexp.c
@@ -0,0 +1,52 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+/* close to ieeep754sp_logb
+*/
+ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr)
+{
+ COMPXSP;
+ CLEARCX;
+ EXPLODEXSP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ case IEEE754_CLASS_ZERO:
+ *eptr = 0;
+ return x;
+ case IEEE754_CLASS_DNORM:
+ SPDNORMX;
+ break;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ *eptr = xe + 1;
+ return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
+}
diff --git a/arch/mips/math-emu/sp_logb.c b/arch/mips/math-emu/sp_logb.c
new file mode 100644
index 00000000..9c14e0c7
--- /dev/null
+++ b/arch/mips/math-emu/sp_logb.c
@@ -0,0 +1,53 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_logb(ieee754sp x)
+{
+ COMPXSP;
+
+ CLEARCX;
+
+ EXPLODEXSP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ return ieee754sp_nanxcpt(x, "logb", x);
+ case IEEE754_CLASS_QNAN:
+ return x;
+ case IEEE754_CLASS_INF:
+ return ieee754sp_inf(0);
+ case IEEE754_CLASS_ZERO:
+ return ieee754sp_inf(1);
+ case IEEE754_CLASS_DNORM:
+ SPDNORMX;
+ break;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ return ieee754sp_fint(xe);
+}
diff --git a/arch/mips/math-emu/sp_modf.c b/arch/mips/math-emu/sp_modf.c
new file mode 100644
index 00000000..25a0fbaa
--- /dev/null
+++ b/arch/mips/math-emu/sp_modf.c
@@ -0,0 +1,79 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+/* modf function is always exact for a finite number
+*/
+ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp *ip)
+{
+ COMPXSP;
+
+ CLEARCX;
+
+ EXPLODEXSP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ case IEEE754_CLASS_ZERO:
+ *ip = x;
+ return x;
+ case IEEE754_CLASS_DNORM:
+ /* far to small */
+ *ip = ieee754sp_zero(xs);
+ return x;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ if (xe < 0) {
+ *ip = ieee754sp_zero(xs);
+ return x;
+ }
+ if (xe >= SP_MBITS) {
+ *ip = x;
+ return ieee754sp_zero(xs);
+ }
+ /* generate ipart mantissa by clearing bottom bits
+ */
+ *ip = buildsp(xs, xe + SP_EBIAS,
+ ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) &
+ ~SP_HIDDEN_BIT);
+
+ /* generate fpart mantissa by clearing top bits
+ * and normalizing (must be able to normalize)
+ */
+ xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe));
+ if (xm == 0)
+ return ieee754sp_zero(xs);
+
+ while ((xm >> SP_MBITS) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
+}
diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c
new file mode 100644
index 00000000..2722a257
--- /dev/null
+++ b/arch/mips/math-emu/sp_mul.c
@@ -0,0 +1,170 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y)
+{
+ COMPXSP;
+ COMPYSP;
+
+ EXPLODEXSP;
+ EXPLODEYSP;
+
+ CLEARCX;
+
+ FLUSHXSP;
+ FLUSHYSP;
+
+ switch (CLPAIR(xc, yc)) {
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "mul", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+ return x;
+
+
+ /* Infinity handling */
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ return ieee754sp_inf(xs ^ ys);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+ return ieee754sp_zero(xs ^ ys);
+
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+ SPDNORMX;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+ SPDNORMY;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+ SPDNORMX;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+ break;
+ }
+ /* rm = xm * ym, re = xe+ye basically */
+ assert(xm & SP_HIDDEN_BIT);
+ assert(ym & SP_HIDDEN_BIT);
+
+ {
+ int re = xe + ye;
+ int rs = xs ^ ys;
+ unsigned rm;
+
+ /* shunt to top of word */
+ xm <<= 32 - (SP_MBITS + 1);
+ ym <<= 32 - (SP_MBITS + 1);
+
+ /* multiply 32bits xm,ym to give high 32bits rm with stickness
+ */
+ {
+ unsigned short lxm = xm & 0xffff;
+ unsigned short hxm = xm >> 16;
+ unsigned short lym = ym & 0xffff;
+ unsigned short hym = ym >> 16;
+ unsigned lrm;
+ unsigned hrm;
+
+ lrm = lxm * lym; /* 16 * 16 => 32 */
+ hrm = hxm * hym; /* 16 * 16 => 32 */
+
+ {
+ unsigned t = lxm * hym; /* 16 * 16 => 32 */
+ {
+ unsigned at = lrm + (t << 16);
+ hrm += at < lrm;
+ lrm = at;
+ }
+ hrm = hrm + (t >> 16);
+ }
+
+ {
+ unsigned t = hxm * lym; /* 16 * 16 => 32 */
+ {
+ unsigned at = lrm + (t << 16);
+ hrm += at < lrm;
+ lrm = at;
+ }
+ hrm = hrm + (t >> 16);
+ }
+ rm = hrm | (lrm != 0);
+ }
+
+ /*
+ * sticky shift down to normal rounding precision
+ */
+ if ((int) rm < 0) {
+ rm = (rm >> (32 - (SP_MBITS + 1 + 3))) |
+ ((rm << (SP_MBITS + 1 + 3)) != 0);
+ re++;
+ } else {
+ rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) |
+ ((rm << (SP_MBITS + 1 + 3 + 1)) != 0);
+ }
+ assert(rm & (SP_HIDDEN_BIT << 3));
+
+ SPNORMRET2(rs, re, rm, "mul", x, y);
+ }
+}
diff --git a/arch/mips/math-emu/sp_scalb.c b/arch/mips/math-emu/sp_scalb.c
new file mode 100644
index 00000000..dd761969
--- /dev/null
+++ b/arch/mips/math-emu/sp_scalb.c
@@ -0,0 +1,57 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_scalb(ieee754sp x, int n)
+{
+ COMPXSP;
+
+ CLEARCX;
+
+ EXPLODEXSP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ return ieee754sp_nanxcpt(x, "scalb", x, n);
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ case IEEE754_CLASS_ZERO:
+ return x;
+ case IEEE754_CLASS_DNORM:
+ SPDNORMX;
+ break;
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
+}
+
+
+ieee754sp ieee754sp_ldexp(ieee754sp x, int n)
+{
+ return ieee754sp_scalb(x, n);
+}
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c
new file mode 100644
index 00000000..ae4fcfaf
--- /dev/null
+++ b/arch/mips/math-emu/sp_simple.c
@@ -0,0 +1,85 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+int ieee754sp_finite(ieee754sp x)
+{
+ return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
+}
+
+ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y)
+{
+ CLEARCX;
+ SPSIGN(x) = SPSIGN(y);
+ return x;
+}
+
+
+ieee754sp ieee754sp_neg(ieee754sp x)
+{
+ COMPXSP;
+
+ EXPLODEXSP;
+ CLEARCX;
+ FLUSHXSP;
+
+ /*
+ * Invert the sign ALWAYS to prevent an endless recursion on
+ * pow() in libc.
+ */
+ /* quick fix up */
+ SPSIGN(x) ^= 1;
+
+ if (xc == IEEE754_CLASS_SNAN) {
+ ieee754sp y = ieee754sp_indef();
+ SETCX(IEEE754_INVALID_OPERATION);
+ SPSIGN(y) = SPSIGN(x);
+ return ieee754sp_nanxcpt(y, "neg");
+ }
+
+ return x;
+}
+
+
+ieee754sp ieee754sp_abs(ieee754sp x)
+{
+ COMPXSP;
+
+ EXPLODEXSP;
+ CLEARCX;
+ FLUSHXSP;
+
+ /* Clear sign ALWAYS, irrespective of NaN */
+ SPSIGN(x) = 0;
+
+ if (xc == IEEE754_CLASS_SNAN) {
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
+ }
+
+ return x;
+}
diff --git a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c
new file mode 100644
index 00000000..fed20175
--- /dev/null
+++ b/arch/mips/math-emu/sp_sqrt.c
@@ -0,0 +1,116 @@
+/* IEEE754 floating point arithmetic
+ * single precision square root
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_sqrt(ieee754sp x)
+{
+ int ix, s, q, m, t, i;
+ unsigned int r;
+ COMPXSP;
+
+ /* take care of Inf and NaN */
+
+ EXPLODEXSP;
+ CLEARCX;
+ FLUSHXSP;
+
+ /* x == INF or NAN? */
+ switch (xc) {
+ case IEEE754_CLASS_QNAN:
+ /* sqrt(Nan) = Nan */
+ return ieee754sp_nanxcpt(x, "sqrt");
+ case IEEE754_CLASS_SNAN:
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
+ case IEEE754_CLASS_ZERO:
+ /* sqrt(0) = 0 */
+ return x;
+ case IEEE754_CLASS_INF:
+ if (xs) {
+ /* sqrt(-Inf) = Nan */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
+ }
+ /* sqrt(+Inf) = Inf */
+ return x;
+ case IEEE754_CLASS_DNORM:
+ case IEEE754_CLASS_NORM:
+ if (xs) {
+ /* sqrt(-x) = Nan */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
+ }
+ break;
+ }
+
+ ix = x.bits;
+
+ /* normalize x */
+ m = (ix >> 23);
+ if (m == 0) { /* subnormal x */
+ for (i = 0; (ix & 0x00800000) == 0; i++)
+ ix <<= 1;
+ m -= i - 1;
+ }
+ m -= 127; /* unbias exponent */
+ ix = (ix & 0x007fffff) | 0x00800000;
+ if (m & 1) /* odd m, double x to make it even */
+ ix += ix;
+ m >>= 1; /* m = [m/2] */
+
+ /* generate sqrt(x) bit by bit */
+ ix += ix;
+ q = s = 0; /* q = sqrt(x) */
+ r = 0x01000000; /* r = moving bit from right to left */
+
+ while (r != 0) {
+ t = s + r;
+ if (t <= ix) {
+ s = t + r;
+ ix -= t;
+ q += r;
+ }
+ ix += ix;
+ r >>= 1;
+ }
+
+ if (ix != 0) {
+ SETCX(IEEE754_INEXACT);
+ switch (ieee754_csr.rm) {
+ case IEEE754_RP:
+ q += 2;
+ break;
+ case IEEE754_RN:
+ q += (q & 1);
+ break;
+ }
+ }
+ ix = (q >> 1) + 0x3f000000;
+ ix += (m << 23);
+ x.bits = ix;
+ return x;
+}
diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c
new file mode 100644
index 00000000..886ed5bc
--- /dev/null
+++ b/arch/mips/math-emu/sp_sub.c
@@ -0,0 +1,183 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y)
+{
+ COMPXSP;
+ COMPYSP;
+
+ EXPLODEXSP;
+ EXPLODEYSP;
+
+ CLEARCX;
+
+ FLUSHXSP;
+ FLUSHYSP;
+
+ switch (CLPAIR(xc, yc)) {
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_nanxcpt(ieee754sp_indef(), "sub", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
+ return x;
+
+
+ /* Infinity handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+ if (xs != ys)
+ return x;
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y);
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+ return ieee754sp_inf(ys ^ 1);
+
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+ return x;
+
+ /* Zero handling
+ */
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+ if (xs != ys)
+ return x;
+ else
+ return ieee754sp_zero(ieee754_csr.rm ==
+ IEEE754_RD);
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+ return x;
+
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+ /* quick fix up */
+ DPSIGN(y) ^= 1;
+ return y;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+ SPDNORMX;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
+ SPDNORMY;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
+ SPDNORMX;
+ break;
+
+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
+ break;
+ }
+ /* flip sign of y and handle as add */
+ ys ^= 1;
+
+ assert(xm & SP_HIDDEN_BIT);
+ assert(ym & SP_HIDDEN_BIT);
+
+
+ /* provide guard,round and stick bit space */
+ xm <<= 3;
+ ym <<= 3;
+
+ if (xe > ye) {
+ /* have to shift y fraction right to align
+ */
+ int s = xe - ye;
+ SPXSRSYn(s);
+ } else if (ye > xe) {
+ /* have to shift x fraction right to align
+ */
+ int s = ye - xe;
+ SPXSRSXn(s);
+ }
+ assert(xe == ye);
+ assert(xe <= SP_EMAX);
+
+ if (xs == ys) {
+ /* generate 28 bit result of adding two 27 bit numbers
+ */
+ xm = xm + ym;
+ xe = xe;
+ xs = xs;
+
+ if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */
+ SPXSRSX1(); /* shift preserving sticky */
+ }
+ } else {
+ if (xm >= ym) {
+ xm = xm - ym;
+ xe = xe;
+ xs = xs;
+ } else {
+ xm = ym - xm;
+ xe = xe;
+ xs = ys;
+ }
+ if (xm == 0) {
+ if (ieee754_csr.rm == IEEE754_RD)
+ return ieee754sp_zero(1); /* round negative inf. => sign = -1 */
+ else
+ return ieee754sp_zero(0); /* other round modes => sign = 1 */
+ }
+ /* normalize to rounding precision
+ */
+ while ((xm >> (SP_MBITS + 3)) == 0) {
+ xm <<= 1;
+ xe--;
+ }
+ }
+ SPNORMRET2(xs, xe, xm, "sub", x, y);
+}
diff --git a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c
new file mode 100644
index 00000000..0fe9acc7
--- /dev/null
+++ b/arch/mips/math-emu/sp_tint.c
@@ -0,0 +1,126 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include <linux/kernel.h>
+#include "ieee754sp.h"
+
+int ieee754sp_tint(ieee754sp x)
+{
+ COMPXSP;
+
+ CLEARCX;
+
+ EXPLODEXSP;
+ FLUSHXSP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
+ case IEEE754_CLASS_ZERO:
+ return 0;
+ case IEEE754_CLASS_DNORM:
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ if (xe >= 31) {
+ /* look for valid corner case */
+ if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
+ return -0x80000000;
+ /* Set invalid. We will only use overflow for floating
+ point overflow */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
+ }
+ /* oh gawd */
+ if (xe > SP_MBITS) {
+ xm <<= xe - SP_MBITS;
+ } else {
+ u32 residue;
+ int round;
+ int sticky;
+ int odd;
+
+ if (xe < -1) {
+ residue = xm;
+ round = 0;
+ sticky = residue != 0;
+ xm = 0;
+ } else {
+ /* Shifting a u32 32 times does not work,
+ * so we do it in two steps. Be aware that xe
+ * may be -1 */
+ residue = xm << (xe + 1);
+ residue <<= 31 - SP_MBITS;
+ round = (residue >> 31) != 0;
+ sticky = (residue << 1) != 0;
+ xm >>= SP_MBITS - xe;
+ }
+ odd = (xm & 0x1) != 0x0;
+ switch (ieee754_csr.rm) {
+ case IEEE754_RN:
+ if (round && (sticky || odd))
+ xm++;
+ break;
+ case IEEE754_RZ:
+ break;
+ case IEEE754_RU: /* toward +Infinity */
+ if ((round || sticky) && !xs)
+ xm++;
+ break;
+ case IEEE754_RD: /* toward -Infinity */
+ if ((round || sticky) && xs)
+ xm++;
+ break;
+ }
+ if ((xm >> 31) != 0) {
+ /* This can happen after rounding */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
+ }
+ if (round || sticky)
+ SETCX(IEEE754_INEXACT);
+ }
+ if (xs)
+ return -xm;
+ else
+ return xm;
+}
+
+
+unsigned int ieee754sp_tuns(ieee754sp x)
+{
+ ieee754sp hb = ieee754sp_1e31();
+
+ /* what if x < 0 ?? */
+ if (ieee754sp_lt(x, hb))
+ return (unsigned) ieee754sp_tint(x);
+
+ return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) |
+ ((unsigned) 1 << 31);
+}
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
new file mode 100644
index 00000000..d0ca6e22
--- /dev/null
+++ b/arch/mips/math-emu/sp_tlong.c
@@ -0,0 +1,121 @@
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+
+#include "ieee754sp.h"
+
+s64 ieee754sp_tlong(ieee754sp x)
+{
+ COMPXDP; /* <-- need 64-bit mantissa tmp */
+
+ CLEARCX;
+
+ EXPLODEXSP;
+ FLUSHXSP;
+
+ switch (xc) {
+ case IEEE754_CLASS_SNAN:
+ case IEEE754_CLASS_QNAN:
+ case IEEE754_CLASS_INF:
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
+ case IEEE754_CLASS_ZERO:
+ return 0;
+ case IEEE754_CLASS_DNORM:
+ case IEEE754_CLASS_NORM:
+ break;
+ }
+ if (xe >= 63) {
+ /* look for valid corner case */
+ if (xe == 63 && xs && xm == SP_HIDDEN_BIT)
+ return -0x8000000000000000LL;
+ /* Set invalid. We will only use overflow for floating
+ point overflow */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
+ }
+ /* oh gawd */
+ if (xe > SP_MBITS) {
+ xm <<= xe - SP_MBITS;
+ } else if (xe < SP_MBITS) {
+ u32 residue;
+ int round;
+ int sticky;
+ int odd;
+
+ if (xe < -1) {
+ residue = xm;
+ round = 0;
+ sticky = residue != 0;
+ xm = 0;
+ } else {
+ residue = xm << (32 - SP_MBITS + xe);
+ round = (residue >> 31) != 0;
+ sticky = (residue << 1) != 0;
+ xm >>= SP_MBITS - xe;
+ }
+ odd = (xm & 0x1) != 0x0;
+ switch (ieee754_csr.rm) {
+ case IEEE754_RN:
+ if (round && (sticky || odd))
+ xm++;
+ break;
+ case IEEE754_RZ:
+ break;
+ case IEEE754_RU: /* toward +Infinity */
+ if ((round || sticky) && !xs)
+ xm++;
+ break;
+ case IEEE754_RD: /* toward -Infinity */
+ if ((round || sticky) && xs)
+ xm++;
+ break;
+ }
+ if ((xm >> 63) != 0) {
+ /* This can happen after rounding */
+ SETCX(IEEE754_INVALID_OPERATION);
+ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
+ }
+ if (round || sticky)
+ SETCX(IEEE754_INEXACT);
+ }
+ if (xs)
+ return -xm;
+ else
+ return xm;
+}
+
+
+u64 ieee754sp_tulong(ieee754sp x)
+{
+ ieee754sp hb = ieee754sp_1e63();
+
+ /* what if x < 0 ?? */
+ if (ieee754sp_lt(x, hb))
+ return (u64) ieee754sp_tlong(x);
+
+ return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) |
+ (1ULL << 63);
+}
diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile
new file mode 100644
index 00000000..01410a3f
--- /dev/null
+++ b/arch/mips/mipssim/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+# Copyright (C) 2007 MIPS Technologies, Inc.
+# written by Ralf Baechle (ralf@linux-mips.org)
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+
+obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o
+
+obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
+obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o
diff --git a/arch/mips/mipssim/Platform b/arch/mips/mipssim/Platform
new file mode 100644
index 00000000..3df60b8a
--- /dev/null
+++ b/arch/mips/mipssim/Platform
@@ -0,0 +1,6 @@
+#
+# MIPS SIM
+#
+platform-$(CONFIG_MIPS_SIM) += mipssim/
+cflags-$(CONFIG_MIPS_SIM) += -I$(srctree)/arch/mips/include/asm/mach-mipssim
+load-$(CONFIG_MIPS_SIM) += 0x80100000
diff --git a/arch/mips/mipssim/sim_console.c b/arch/mips/mipssim/sim_console.c
new file mode 100644
index 00000000..a2f41672
--- /dev/null
+++ b/arch/mips/mipssim/sim_console.c
@@ -0,0 +1,40 @@
+/*
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * written by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serial_reg.h>
+
+static inline unsigned int serial_in(int offset)
+{
+ return inb(0x3f8 + offset);
+}
+
+static inline void serial_out(int offset, int value)
+{
+ outb(value, 0x3f8 + offset);
+}
+
+void __init prom_putchar(char c)
+{
+ while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
+ ;
+
+ serial_out(UART_TX, c);
+}
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c
new file mode 100644
index 00000000..5c779be6
--- /dev/null
+++ b/arch/mips/mipssim/sim_int.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 1999, 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <asm/mips-boards/simint.h>
+#include <asm/irq_cpu.h>
+
+static inline int clz(unsigned long x)
+{
+ __asm__(
+ " .set push \n"
+ " .set mips32 \n"
+ " clz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (x)
+ : "r" (x));
+
+ return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ return -clz(pending) + 31 - CAUSEB_IP;
+#else
+ unsigned int a0 = 7;
+ unsigned int t0;
+
+ t0 = s0 & 0xf000;
+ t0 = t0 < 1;
+ t0 = t0 << 2;
+ a0 = a0 - t0;
+ s0 = s0 << t0;
+
+ t0 = s0 & 0xc000;
+ t0 = t0 < 1;
+ t0 = t0 << 1;
+ a0 = a0 - t0;
+ s0 = s0 << t0;
+
+ t0 = s0 & 0x8000;
+ t0 = t0 < 1;
+ /* t0 = t0 << 2; */
+ a0 = a0 - t0;
+ /* s0 = s0 << t0; */
+
+ return a0;
+#endif
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+ int irq;
+
+ irq = irq_ffs(pending);
+
+ if (irq > 0)
+ do_IRQ(MIPS_CPU_IRQ_BASE + irq);
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+}
diff --git a/arch/mips/mipssim/sim_mem.c b/arch/mips/mipssim/sim_mem.c
new file mode 100644
index 00000000..953d836a
--- /dev/null
+++ b/arch/mips/mipssim/sim_mem.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/pfn.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <asm/mips-boards/prom.h>
+
+/*#define DEBUG*/
+
+enum simmem_memtypes {
+ simmem_reserved = 0,
+ simmem_free,
+};
+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+#ifdef DEBUG
+static char *mtypes[3] = {
+ "SIM reserved memory",
+ "SIM free memory",
+};
+#endif
+
+struct prom_pmemblock * __init prom_getmdesc(void)
+{
+ unsigned int memsize;
+
+ memsize = 0x02000000;
+ pr_info("Setting default memory size 0x%08x\n", memsize);
+
+ memset(mdesc, 0, sizeof(mdesc));
+
+ mdesc[0].type = simmem_reserved;
+ mdesc[0].base = 0x00000000;
+ mdesc[0].size = 0x00001000;
+
+ mdesc[1].type = simmem_free;
+ mdesc[1].base = 0x00001000;
+ mdesc[1].size = 0x000ff000;
+
+ mdesc[2].type = simmem_reserved;
+ mdesc[2].base = 0x00100000;
+ mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
+
+ mdesc[3].type = simmem_free;
+ mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
+ mdesc[3].size = memsize - mdesc[3].base;
+
+ return &mdesc[0];
+}
+
+static int __init prom_memtype_classify(unsigned int type)
+{
+ switch (type) {
+ case simmem_free:
+ return BOOT_MEM_RAM;
+ case simmem_reserved:
+ default:
+ return BOOT_MEM_RESERVED;
+ }
+}
+
+void __init prom_meminit(void)
+{
+ struct prom_pmemblock *p;
+
+ p = prom_getmdesc();
+
+ while (p->size) {
+ long type;
+ unsigned long base, size;
+
+ type = prom_memtype_classify(p->type);
+ base = p->base;
+ size = p->size;
+
+ add_memory_region(base, size, type);
+ p++;
+ }
+}
+
+void __init prom_free_prom_memory(void)
+{
+ int i;
+ unsigned long addr;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ free_init_pages("prom memory",
+ addr, addr + boot_mem_map.map[i].size);
+ }
+}
diff --git a/arch/mips/mipssim/sim_platform.c b/arch/mips/mipssim/sim_platform.c
new file mode 100644
index 00000000..53210a8c
--- /dev/null
+++ b/arch/mips/mipssim/sim_platform.c
@@ -0,0 +1,35 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/init.h>
+#include <linux/if_ether.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+static char mipsnet_string[] = "mipsnet";
+
+static struct platform_device eth1_device = {
+ .name = mipsnet_string,
+ .id = 0,
+};
+
+/*
+ * Create a platform device for the GPI port that receives the
+ * image data from the embedded camera.
+ */
+static int __init mipsnet_devinit(void)
+{
+ int err;
+
+ err = platform_device_register(&eth1_device);
+ if (err)
+ printk(KERN_ERR "%s: registration failed\n", mipsnet_string);
+
+ return err;
+}
+
+device_initcall(mipsnet_devinit);
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
new file mode 100644
index 00000000..55f22a3a
--- /dev/null
+++ b/arch/mips/mipssim/sim_setup.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/ioport.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/time.h>
+#include <asm/mips-boards/sim.h>
+#include <asm/mips-boards/simint.h>
+
+
+static void __init serial_init(void);
+unsigned int _isbonito;
+
+const char *get_system_type(void)
+{
+ return "MIPSsim";
+}
+
+void __init plat_mem_setup(void)
+{
+ set_io_port_base(0xbfd00000);
+
+ serial_init();
+}
+
+extern struct plat_smp_ops ssmtc_smp_ops;
+
+void __init prom_init(void)
+{
+ set_io_port_base(0xbfd00000);
+
+ prom_meminit();
+
+#ifdef CONFIG_MIPS_MT_SMP
+ if (cpu_has_mipsmt)
+ register_smp_ops(&vsmp_smp_ops);
+ else
+ register_smp_ops(&up_smp_ops);
+#endif
+#ifdef CONFIG_MIPS_MT_SMTC
+ if (cpu_has_mipsmt)
+ register_smp_ops(&ssmtc_smp_ops);
+ else
+ register_smp_ops(&up_smp_ops);
+#endif
+}
+
+static void __init serial_init(void)
+{
+#ifdef CONFIG_SERIAL_8250
+ struct uart_port s;
+
+ memset(&s, 0, sizeof(s));
+
+ s.iobase = 0x3f8;
+
+ /* hardware int 4 - the serial int, is CPU int 6
+ but poll for now */
+ s.irq = 0;
+ s.uartclk = 1843200;
+ s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+ s.iotype = UPIO_PORT;
+ s.regshift = 0;
+ s.timeout = 4;
+
+ if (early_serial_setup(&s) != 0) {
+ printk(KERN_ERR "Serial setup failed!\n");
+ }
+
+#endif
+}
diff --git a/arch/mips/mipssim/sim_smtc.c b/arch/mips/mipssim/sim_smtc.c
new file mode 100644
index 00000000..30df4725
--- /dev/null
+++ b/arch/mips/mipssim/sim_smtc.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+/*
+ * Simulator Platform-specific hooks for SMTC operation
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include <asm/atomic.h>
+#include <asm/cpu.h>
+#include <asm/processor.h>
+#include <asm/smtc.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/smtc_ipi.h>
+
+/* VPE/SMP Prototype implements platform interfaces directly */
+
+/*
+ * Cause the specified action to be performed on a targeted "CPU"
+ */
+
+static void ssmtc_send_ipi_single(int cpu, unsigned int action)
+{
+ smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
+ /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
+}
+
+static inline void ssmtc_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ ssmtc_send_ipi_single(i, action);
+}
+
+/*
+ * Post-config but pre-boot cleanup entry point
+ */
+static void __cpuinit ssmtc_init_secondary(void)
+{
+ smtc_init_secondary();
+}
+
+/*
+ * SMP initialization finalization entry point
+ */
+static void __cpuinit ssmtc_smp_finish(void)
+{
+ smtc_smp_finish();
+}
+
+/*
+ * Hook for after all CPUs are online
+ */
+static void ssmtc_cpus_done(void)
+{
+}
+
+/*
+ * Platform "CPU" startup hook
+ */
+static void __cpuinit ssmtc_boot_secondary(int cpu, struct task_struct *idle)
+{
+ smtc_boot_secondary(cpu, idle);
+}
+
+static void __init ssmtc_smp_setup(void)
+{
+ if (read_c0_config3() & (1 << 2))
+ mipsmt_build_cpu_map(0);
+}
+
+/*
+ * Platform SMP pre-initialization
+ */
+static void ssmtc_prepare_cpus(unsigned int max_cpus)
+{
+ /*
+ * As noted above, we can assume a single CPU for now
+ * but it may be multithreaded.
+ */
+
+ if (read_c0_config3() & (1 << 2)) {
+ mipsmt_prepare_cpus();
+ }
+}
+
+struct plat_smp_ops ssmtc_smp_ops = {
+ .send_ipi_single = ssmtc_send_ipi_single,
+ .send_ipi_mask = ssmtc_send_ipi_mask,
+ .init_secondary = ssmtc_init_secondary,
+ .smp_finish = ssmtc_smp_finish,
+ .cpus_done = ssmtc_cpus_done,
+ .boot_secondary = ssmtc_boot_secondary,
+ .smp_setup = ssmtc_smp_setup,
+ .prepare_cpus = ssmtc_prepare_cpus,
+};
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c
new file mode 100644
index 00000000..5492c42f
--- /dev/null
+++ b/arch/mips/mipssim/sim_time.c
@@ -0,0 +1,116 @@
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/smp.h>
+#include <linux/timex.h>
+
+#include <asm/hardirq.h>
+#include <asm/div64.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/mc146818-time.h>
+#include <asm/msc01_ic.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/simint.h>
+
+
+unsigned long cpu_khz;
+
+/*
+ * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
+ */
+static unsigned int __init estimate_cpu_frequency(void)
+{
+ unsigned int prid = read_c0_prid() & 0xffff00;
+ unsigned int count;
+
+#if 1
+ /*
+ * hardwire the board frequency to 12MHz.
+ */
+
+ if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
+ (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ count = 12000000;
+ else
+ count = 6000000;
+#else
+ unsigned int flags;
+
+ local_irq_save(flags);
+
+ /* Start counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ /* Start r4k counter. */
+ write_c0_count(0);
+
+ /* Read counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ count = read_c0_count();
+
+ /* restore interrupts */
+ local_irq_restore(flags);
+#endif
+
+ mips_hpt_frequency = count;
+
+ if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+ (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ count *= 2;
+
+ count += 5000; /* round */
+ count -= count%10000;
+
+ return count;
+}
+
+static int mips_cpu_timer_irq;
+
+static void mips_timer_dispatch(void)
+{
+ do_IRQ(mips_cpu_timer_irq);
+}
+
+
+unsigned __cpuinit get_c0_compare_int(void)
+{
+#ifdef MSC01E_INT_BASE
+ if (cpu_has_veic) {
+ set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
+
+ return mips_cpu_timer_irq;
+ }
+#endif
+ if (cpu_has_vint)
+ set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
+ mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+
+ return mips_cpu_timer_irq;
+}
+
+void __init plat_time_init(void)
+{
+ unsigned int est_freq;
+
+ /* Set Data mode - binary. */
+ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+
+ est_freq = estimate_cpu_frequency();
+
+ printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
+ (est_freq % 1000000) * 100 / 1000000);
+
+ cpu_khz = est_freq / 1000;
+}
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
new file mode 100644
index 00000000..4d8c1623
--- /dev/null
+++ b/arch/mips/mm/Makefile
@@ -0,0 +1,38 @@
+#
+# Makefile for the Linux/MIPS-specific parts of the memory manager.
+#
+
+obj-y += cache.o dma-default.o extable.o fault.o \
+ init.o mmap.o tlbex.o tlbex-fault.o uasm.o \
+ page.o
+
+obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
+obj-$(CONFIG_64BIT) += pgtable-64.o
+obj-$(CONFIG_HIGHMEM) += highmem.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+
+obj-$(CONFIG_CPU_LOONGSON2) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_MIPS32) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_MIPS64) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_NEVADA) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R10000) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o
+obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R5500) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o
+obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
+obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o
+obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o
+obj-$(CONFIG_CPU_XLR) += c-r4k.o tlb-r4k.o cex-gen.o
+
+obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
+obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
+obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o
+obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c
new file mode 100644
index 00000000..16c4d256
--- /dev/null
+++ b/arch/mips/mm/c-octeon.c
@@ -0,0 +1,322 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2007 Cavium Networks
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
+#include <linux/cpu.h>
+#include <linux/io.h>
+
+#include <asm/bcache.h>
+#include <asm/bootinfo.h>
+#include <asm/cacheops.h>
+#include <asm/cpu-features.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/r4kcache.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/war.h>
+
+#include <asm/octeon/octeon.h>
+
+unsigned long long cache_err_dcache[NR_CPUS];
+
+/**
+ * Octeon automatically flushes the dcache on tlb changes, so
+ * from Linux's viewpoint it acts much like a physically
+ * tagged cache. No flushing is needed
+ *
+ */
+static void octeon_flush_data_cache_page(unsigned long addr)
+{
+ /* Nothing to do */
+}
+
+static inline void octeon_local_flush_icache(void)
+{
+ asm volatile ("synci 0($0)");
+}
+
+/*
+ * Flush local I-cache for the specified range.
+ */
+static void local_octeon_flush_icache_range(unsigned long start,
+ unsigned long end)
+{
+ octeon_local_flush_icache();
+}
+
+/**
+ * Flush caches as necessary for all cores affected by a
+ * vma. If no vma is supplied, all cores are flushed.
+ *
+ * @vma: VMA to flush or NULL to flush all icaches.
+ */
+static void octeon_flush_icache_all_cores(struct vm_area_struct *vma)
+{
+ extern void octeon_send_ipi_single(int cpu, unsigned int action);
+#ifdef CONFIG_SMP
+ int cpu;
+ cpumask_t mask;
+#endif
+
+ mb();
+ octeon_local_flush_icache();
+#ifdef CONFIG_SMP
+ preempt_disable();
+ cpu = smp_processor_id();
+
+ /*
+ * If we have a vma structure, we only need to worry about
+ * cores it has been used on
+ */
+ if (vma)
+ mask = *mm_cpumask(vma->vm_mm);
+ else
+ mask = cpu_online_map;
+ cpu_clear(cpu, mask);
+ for_each_cpu_mask(cpu, mask)
+ octeon_send_ipi_single(cpu, SMP_ICACHE_FLUSH);
+
+ preempt_enable();
+#endif
+}
+
+
+/**
+ * Called to flush the icache on all cores
+ */
+static void octeon_flush_icache_all(void)
+{
+ octeon_flush_icache_all_cores(NULL);
+}
+
+
+/**
+ * Called to flush all memory associated with a memory
+ * context.
+ *
+ * @mm: Memory context to flush
+ */
+static void octeon_flush_cache_mm(struct mm_struct *mm)
+{
+ /*
+ * According to the R4K version of this file, CPUs without
+ * dcache aliases don't need to do anything here
+ */
+}
+
+
+/**
+ * Flush a range of kernel addresses out of the icache
+ *
+ */
+static void octeon_flush_icache_range(unsigned long start, unsigned long end)
+{
+ octeon_flush_icache_all_cores(NULL);
+}
+
+
+/**
+ * Flush the icache for a trampoline. These are used for interrupt
+ * and exception hooking.
+ *
+ * @addr: Address to flush
+ */
+static void octeon_flush_cache_sigtramp(unsigned long addr)
+{
+ struct vm_area_struct *vma;
+
+ vma = find_vma(current->mm, addr);
+ octeon_flush_icache_all_cores(vma);
+}
+
+
+/**
+ * Flush a range out of a vma
+ *
+ * @vma: VMA to flush
+ * @start:
+ * @end:
+ */
+static void octeon_flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ if (vma->vm_flags & VM_EXEC)
+ octeon_flush_icache_all_cores(vma);
+}
+
+
+/**
+ * Flush a specific page of a vma
+ *
+ * @vma: VMA to flush page for
+ * @page: Page to flush
+ * @pfn:
+ */
+static void octeon_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long page, unsigned long pfn)
+{
+ if (vma->vm_flags & VM_EXEC)
+ octeon_flush_icache_all_cores(vma);
+}
+
+
+/**
+ * Probe Octeon's caches
+ *
+ */
+static void __cpuinit probe_octeon(void)
+{
+ unsigned long icache_size;
+ unsigned long dcache_size;
+ unsigned int config1;
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ config1 = read_c0_config1();
+ switch (c->cputype) {
+ case CPU_CAVIUM_OCTEON:
+ case CPU_CAVIUM_OCTEON_PLUS:
+ c->icache.linesz = 2 << ((config1 >> 19) & 7);
+ c->icache.sets = 64 << ((config1 >> 22) & 7);
+ c->icache.ways = 1 + ((config1 >> 16) & 7);
+ c->icache.flags |= MIPS_CACHE_VTAG;
+ icache_size =
+ c->icache.sets * c->icache.ways * c->icache.linesz;
+ c->icache.waybit = ffs(icache_size / c->icache.ways) - 1;
+ c->dcache.linesz = 128;
+ if (c->cputype == CPU_CAVIUM_OCTEON_PLUS)
+ c->dcache.sets = 2; /* CN5XXX has two Dcache sets */
+ else
+ c->dcache.sets = 1; /* CN3XXX has one Dcache set */
+ c->dcache.ways = 64;
+ dcache_size =
+ c->dcache.sets * c->dcache.ways * c->dcache.linesz;
+ c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+
+ case CPU_CAVIUM_OCTEON2:
+ c->icache.linesz = 2 << ((config1 >> 19) & 7);
+ c->icache.sets = 8;
+ c->icache.ways = 37;
+ c->icache.flags |= MIPS_CACHE_VTAG;
+ icache_size = c->icache.sets * c->icache.ways * c->icache.linesz;
+
+ c->dcache.linesz = 128;
+ c->dcache.ways = 32;
+ c->dcache.sets = 8;
+ dcache_size = c->dcache.sets * c->dcache.ways * c->dcache.linesz;
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+
+ default:
+ panic("Unsupported Cavium Networks CPU type\n");
+ break;
+ }
+
+ /* compute a couple of other cache variables */
+ c->icache.waysize = icache_size / c->icache.ways;
+ c->dcache.waysize = dcache_size / c->dcache.ways;
+
+ c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways);
+ c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways);
+
+ if (smp_processor_id() == 0) {
+ pr_notice("Primary instruction cache %ldkB, %s, %d way, "
+ "%d sets, linesize %d bytes.\n",
+ icache_size >> 10,
+ cpu_has_vtag_icache ?
+ "virtually tagged" : "physically tagged",
+ c->icache.ways, c->icache.sets, c->icache.linesz);
+
+ pr_notice("Primary data cache %ldkB, %d-way, %d sets, "
+ "linesize %d bytes.\n",
+ dcache_size >> 10, c->dcache.ways,
+ c->dcache.sets, c->dcache.linesz);
+ }
+}
+
+
+/**
+ * Setup the Octeon cache flush routines
+ *
+ */
+void __cpuinit octeon_cache_init(void)
+{
+ extern unsigned long ebase;
+ extern char except_vec2_octeon;
+
+ memcpy((void *)(ebase + 0x100), &except_vec2_octeon, 0x80);
+ octeon_flush_cache_sigtramp(ebase + 0x100);
+
+ probe_octeon();
+
+ shm_align_mask = PAGE_SIZE - 1;
+
+ flush_cache_all = octeon_flush_icache_all;
+ __flush_cache_all = octeon_flush_icache_all;
+ flush_cache_mm = octeon_flush_cache_mm;
+ flush_cache_page = octeon_flush_cache_page;
+ flush_cache_range = octeon_flush_cache_range;
+ flush_cache_sigtramp = octeon_flush_cache_sigtramp;
+ flush_icache_all = octeon_flush_icache_all;
+ flush_data_cache_page = octeon_flush_data_cache_page;
+ flush_icache_range = octeon_flush_icache_range;
+ local_flush_icache_range = local_octeon_flush_icache_range;
+
+ build_clear_page();
+ build_copy_page();
+}
+
+/**
+ * Handle a cache error exception
+ */
+
+static void cache_parity_error_octeon(int non_recoverable)
+{
+ unsigned long coreid = cvmx_get_core_num();
+ uint64_t icache_err = read_octeon_c0_icacheerr();
+
+ pr_err("Cache error exception:\n");
+ pr_err("cp0_errorepc == %lx\n", read_c0_errorepc());
+ if (icache_err & 1) {
+ pr_err("CacheErr (Icache) == %llx\n",
+ (unsigned long long)icache_err);
+ write_octeon_c0_icacheerr(0);
+ }
+ if (cache_err_dcache[coreid] & 1) {
+ pr_err("CacheErr (Dcache) == %llx\n",
+ (unsigned long long)cache_err_dcache[coreid]);
+ cache_err_dcache[coreid] = 0;
+ }
+
+ if (non_recoverable)
+ panic("Can't handle cache error: nested exception");
+}
+
+/**
+ * Called when the the exception is recoverable
+ */
+
+asmlinkage void cache_parity_error_octeon_recoverable(void)
+{
+ cache_parity_error_octeon(0);
+}
+
+/**
+ * Called when the the exception is not recoverable
+ */
+
+asmlinkage void cache_parity_error_octeon_non_recoverable(void)
+{
+ cache_parity_error_octeon(1);
+}
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
new file mode 100644
index 00000000..e6b0efd3
--- /dev/null
+++ b/arch/mips/mm/c-r3k.c
@@ -0,0 +1,341 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ * Copyright (C) 2001, 2004, 2007 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+static unsigned long icache_size, dcache_size; /* Size in bytes */
+static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */
+
+unsigned long __cpuinit r3k_cache_size(unsigned long ca_flags)
+{
+ unsigned long flags, status, dummy, size;
+ volatile unsigned long *p;
+
+ p = (volatile unsigned long *) KSEG0;
+
+ flags = read_c0_status();
+
+ /* isolate cache space */
+ write_c0_status((ca_flags|flags)&~ST0_IEC);
+
+ *p = 0xa5a55a5a;
+ dummy = *p;
+ status = read_c0_status();
+
+ if (dummy != 0xa5a55a5a || (status & ST0_CM)) {
+ size = 0;
+ } else {
+ for (size = 128; size <= 0x40000; size <<= 1)
+ *(p + size) = 0;
+ *p = -1;
+ for (size = 128;
+ (size <= 0x40000) && (*(p + size) == 0);
+ size <<= 1)
+ ;
+ if (size > 0x40000)
+ size = 0;
+ }
+
+ write_c0_status(flags);
+
+ return size * sizeof(*p);
+}
+
+unsigned long __cpuinit r3k_cache_lsize(unsigned long ca_flags)
+{
+ unsigned long flags, status, lsize, i;
+ volatile unsigned long *p;
+
+ p = (volatile unsigned long *) KSEG0;
+
+ flags = read_c0_status();
+
+ /* isolate cache space */
+ write_c0_status((ca_flags|flags)&~ST0_IEC);
+
+ for (i = 0; i < 128; i++)
+ *(p + i) = 0;
+ *(volatile unsigned char *)p = 0;
+ for (lsize = 1; lsize < 128; lsize <<= 1) {
+ *(p + lsize);
+ status = read_c0_status();
+ if (!(status & ST0_CM))
+ break;
+ }
+ for (i = 0; i < 128; i += lsize)
+ *(volatile unsigned char *)(p + i) = 0;
+
+ write_c0_status(flags);
+
+ return lsize * sizeof(*p);
+}
+
+static void __cpuinit r3k_probe_cache(void)
+{
+ dcache_size = r3k_cache_size(ST0_ISC);
+ if (dcache_size)
+ dcache_lsize = r3k_cache_lsize(ST0_ISC);
+
+ icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
+ if (icache_size)
+ icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC);
+}
+
+static void r3k_flush_icache_range(unsigned long start, unsigned long end)
+{
+ unsigned long size, i, flags;
+ volatile unsigned char *p;
+
+ size = end - start;
+ if (size > icache_size || KSEGX(start) != KSEG0) {
+ start = KSEG0;
+ size = icache_size;
+ }
+ p = (char *)start;
+
+ flags = read_c0_status();
+
+ /* isolate cache space */
+ write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
+
+ for (i = 0; i < size; i += 0x080) {
+ asm( "sb\t$0, 0x000(%0)\n\t"
+ "sb\t$0, 0x004(%0)\n\t"
+ "sb\t$0, 0x008(%0)\n\t"
+ "sb\t$0, 0x00c(%0)\n\t"
+ "sb\t$0, 0x010(%0)\n\t"
+ "sb\t$0, 0x014(%0)\n\t"
+ "sb\t$0, 0x018(%0)\n\t"
+ "sb\t$0, 0x01c(%0)\n\t"
+ "sb\t$0, 0x020(%0)\n\t"
+ "sb\t$0, 0x024(%0)\n\t"
+ "sb\t$0, 0x028(%0)\n\t"
+ "sb\t$0, 0x02c(%0)\n\t"
+ "sb\t$0, 0x030(%0)\n\t"
+ "sb\t$0, 0x034(%0)\n\t"
+ "sb\t$0, 0x038(%0)\n\t"
+ "sb\t$0, 0x03c(%0)\n\t"
+ "sb\t$0, 0x040(%0)\n\t"
+ "sb\t$0, 0x044(%0)\n\t"
+ "sb\t$0, 0x048(%0)\n\t"
+ "sb\t$0, 0x04c(%0)\n\t"
+ "sb\t$0, 0x050(%0)\n\t"
+ "sb\t$0, 0x054(%0)\n\t"
+ "sb\t$0, 0x058(%0)\n\t"
+ "sb\t$0, 0x05c(%0)\n\t"
+ "sb\t$0, 0x060(%0)\n\t"
+ "sb\t$0, 0x064(%0)\n\t"
+ "sb\t$0, 0x068(%0)\n\t"
+ "sb\t$0, 0x06c(%0)\n\t"
+ "sb\t$0, 0x070(%0)\n\t"
+ "sb\t$0, 0x074(%0)\n\t"
+ "sb\t$0, 0x078(%0)\n\t"
+ "sb\t$0, 0x07c(%0)\n\t"
+ : : "r" (p) );
+ p += 0x080;
+ }
+
+ write_c0_status(flags);
+}
+
+static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
+{
+ unsigned long size, i, flags;
+ volatile unsigned char *p;
+
+ size = end - start;
+ if (size > dcache_size || KSEGX(start) != KSEG0) {
+ start = KSEG0;
+ size = dcache_size;
+ }
+ p = (char *)start;
+
+ flags = read_c0_status();
+
+ /* isolate cache space */
+ write_c0_status((ST0_ISC|flags)&~ST0_IEC);
+
+ for (i = 0; i < size; i += 0x080) {
+ asm( "sb\t$0, 0x000(%0)\n\t"
+ "sb\t$0, 0x004(%0)\n\t"
+ "sb\t$0, 0x008(%0)\n\t"
+ "sb\t$0, 0x00c(%0)\n\t"
+ "sb\t$0, 0x010(%0)\n\t"
+ "sb\t$0, 0x014(%0)\n\t"
+ "sb\t$0, 0x018(%0)\n\t"
+ "sb\t$0, 0x01c(%0)\n\t"
+ "sb\t$0, 0x020(%0)\n\t"
+ "sb\t$0, 0x024(%0)\n\t"
+ "sb\t$0, 0x028(%0)\n\t"
+ "sb\t$0, 0x02c(%0)\n\t"
+ "sb\t$0, 0x030(%0)\n\t"
+ "sb\t$0, 0x034(%0)\n\t"
+ "sb\t$0, 0x038(%0)\n\t"
+ "sb\t$0, 0x03c(%0)\n\t"
+ "sb\t$0, 0x040(%0)\n\t"
+ "sb\t$0, 0x044(%0)\n\t"
+ "sb\t$0, 0x048(%0)\n\t"
+ "sb\t$0, 0x04c(%0)\n\t"
+ "sb\t$0, 0x050(%0)\n\t"
+ "sb\t$0, 0x054(%0)\n\t"
+ "sb\t$0, 0x058(%0)\n\t"
+ "sb\t$0, 0x05c(%0)\n\t"
+ "sb\t$0, 0x060(%0)\n\t"
+ "sb\t$0, 0x064(%0)\n\t"
+ "sb\t$0, 0x068(%0)\n\t"
+ "sb\t$0, 0x06c(%0)\n\t"
+ "sb\t$0, 0x070(%0)\n\t"
+ "sb\t$0, 0x074(%0)\n\t"
+ "sb\t$0, 0x078(%0)\n\t"
+ "sb\t$0, 0x07c(%0)\n\t"
+ : : "r" (p) );
+ p += 0x080;
+ }
+
+ write_c0_status(flags);
+}
+
+static inline void r3k_flush_cache_all(void)
+{
+}
+
+static inline void r3k___flush_cache_all(void)
+{
+ r3k_flush_dcache_range(KSEG0, KSEG0 + dcache_size);
+ r3k_flush_icache_range(KSEG0, KSEG0 + icache_size);
+}
+
+static void r3k_flush_cache_mm(struct mm_struct *mm)
+{
+}
+
+static void r3k_flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+}
+
+static void r3k_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn)
+{
+ unsigned long kaddr = KSEG0ADDR(pfn << PAGE_SHIFT);
+ int exec = vma->vm_flags & VM_EXEC;
+ struct mm_struct *mm = vma->vm_mm;
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ pr_debug("cpage[%08lx,%08lx]\n",
+ cpu_context(smp_processor_id(), mm), addr);
+
+ /* No ASID => no such page in the cache. */
+ if (cpu_context(smp_processor_id(), mm) == 0)
+ return;
+
+ pgdp = pgd_offset(mm, addr);
+ pudp = pud_offset(pgdp, addr);
+ pmdp = pmd_offset(pudp, addr);
+ ptep = pte_offset(pmdp, addr);
+
+ /* Invalid => no such page in the cache. */
+ if (!(pte_val(*ptep) & _PAGE_PRESENT))
+ return;
+
+ r3k_flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
+ if (exec)
+ r3k_flush_icache_range(kaddr, kaddr + PAGE_SIZE);
+}
+
+static void local_r3k_flush_data_cache_page(void *addr)
+{
+}
+
+static void r3k_flush_data_cache_page(unsigned long addr)
+{
+}
+
+static void r3k_flush_cache_sigtramp(unsigned long addr)
+{
+ unsigned long flags;
+
+ pr_debug("csigtramp[%08lx]\n", addr);
+
+ flags = read_c0_status();
+
+ write_c0_status(flags&~ST0_IEC);
+
+ /* Fill the TLB to avoid an exception with caches isolated. */
+ asm( "lw\t$0, 0x000(%0)\n\t"
+ "lw\t$0, 0x004(%0)\n\t"
+ : : "r" (addr) );
+
+ write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
+
+ asm( "sb\t$0, 0x000(%0)\n\t"
+ "sb\t$0, 0x004(%0)\n\t"
+ : : "r" (addr) );
+
+ write_c0_status(flags);
+}
+
+static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
+{
+ /* Catch bad driver code */
+ BUG_ON(size == 0);
+
+ iob();
+ r3k_flush_dcache_range(start, start + size);
+}
+
+void __cpuinit r3k_cache_init(void)
+{
+ extern void build_clear_page(void);
+ extern void build_copy_page(void);
+
+ r3k_probe_cache();
+
+ flush_cache_all = r3k_flush_cache_all;
+ __flush_cache_all = r3k___flush_cache_all;
+ flush_cache_mm = r3k_flush_cache_mm;
+ flush_cache_range = r3k_flush_cache_range;
+ flush_cache_page = r3k_flush_cache_page;
+ flush_icache_range = r3k_flush_icache_range;
+ local_flush_icache_range = r3k_flush_icache_range;
+
+ flush_cache_sigtramp = r3k_flush_cache_sigtramp;
+ local_flush_data_cache_page = local_r3k_flush_data_cache_page;
+ flush_data_cache_page = r3k_flush_data_cache_page;
+
+ _dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+ _dma_cache_wback = r3k_dma_cache_wback_inv;
+ _dma_cache_inv = r3k_dma_cache_wback_inv;
+
+ printk("Primary instruction cache %ldkB, linesize %ld bytes.\n",
+ icache_size >> 10, icache_lsize);
+ printk("Primary data cache %ldkB, linesize %ld bytes.\n",
+ dcache_size >> 10, dcache_lsize);
+
+ build_clear_page();
+ build_copy_page();
+}
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
new file mode 100644
index 00000000..eeb642e4
--- /dev/null
+++ b/arch/mips/mm/c-r4k.c
@@ -0,0 +1,1427 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/hardirq.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/bitops.h>
+
+#include <asm/bcache.h>
+#include <asm/bootinfo.h>
+#include <asm/cache.h>
+#include <asm/cacheops.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/r4kcache.h>
+#include <asm/sections.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/war.h>
+#include <asm/cacheflush.h> /* for run_uncached() */
+
+
+/*
+ * Special Variant of smp_call_function for use by cache functions:
+ *
+ * o No return value
+ * o collapses to normal function call on UP kernels
+ * o collapses to normal function call on systems with a single shared
+ * primary cache.
+ * o doesn't disable interrupts on the local CPU
+ */
+static inline void r4k_on_each_cpu(void (*func) (void *info), void *info)
+{
+ preempt_disable();
+
+#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
+ smp_call_function(func, info, 1);
+#endif
+ func(info);
+ preempt_enable();
+}
+
+#if defined(CONFIG_MIPS_CMP)
+#define cpu_has_safe_index_cacheops 0
+#else
+#define cpu_has_safe_index_cacheops 1
+#endif
+
+/*
+ * Must die.
+ */
+static unsigned long icache_size __read_mostly;
+static unsigned long dcache_size __read_mostly;
+static unsigned long scache_size __read_mostly;
+
+/*
+ * Dummy cache handling routines for machines without boardcaches
+ */
+static void cache_noop(void) {}
+
+static struct bcache_ops no_sc_ops = {
+ .bc_enable = (void *)cache_noop,
+ .bc_disable = (void *)cache_noop,
+ .bc_wback_inv = (void *)cache_noop,
+ .bc_inv = (void *)cache_noop
+};
+
+struct bcache_ops *bcops = &no_sc_ops;
+
+#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
+#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
+
+#define R4600_HIT_CACHEOP_WAR_IMPL \
+do { \
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) \
+ *(volatile unsigned long *)CKSEG1; \
+ if (R4600_V1_HIT_CACHEOP_WAR) \
+ __asm__ __volatile__("nop;nop;nop;nop"); \
+} while (0)
+
+static void (*r4k_blast_dcache_page)(unsigned long addr);
+
+static inline void r4k_blast_dcache_page_dc32(unsigned long addr)
+{
+ R4600_HIT_CACHEOP_WAR_IMPL;
+ blast_dcache32_page(addr);
+}
+
+static inline void r4k_blast_dcache_page_dc64(unsigned long addr)
+{
+ R4600_HIT_CACHEOP_WAR_IMPL;
+ blast_dcache64_page(addr);
+}
+
+static void __cpuinit r4k_blast_dcache_page_setup(void)
+{
+ unsigned long dc_lsize = cpu_dcache_line_size();
+
+ if (dc_lsize == 0)
+ r4k_blast_dcache_page = (void *)cache_noop;
+ else if (dc_lsize == 16)
+ r4k_blast_dcache_page = blast_dcache16_page;
+ else if (dc_lsize == 32)
+ r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
+ else if (dc_lsize == 64)
+ r4k_blast_dcache_page = r4k_blast_dcache_page_dc64;
+}
+
+static void (* r4k_blast_dcache_page_indexed)(unsigned long addr);
+
+static void __cpuinit r4k_blast_dcache_page_indexed_setup(void)
+{
+ unsigned long dc_lsize = cpu_dcache_line_size();
+
+ if (dc_lsize == 0)
+ r4k_blast_dcache_page_indexed = (void *)cache_noop;
+ else if (dc_lsize == 16)
+ r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed;
+ else if (dc_lsize == 32)
+ r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
+ else if (dc_lsize == 64)
+ r4k_blast_dcache_page_indexed = blast_dcache64_page_indexed;
+}
+
+static void (* r4k_blast_dcache)(void);
+
+static void __cpuinit r4k_blast_dcache_setup(void)
+{
+ unsigned long dc_lsize = cpu_dcache_line_size();
+
+ if (dc_lsize == 0)
+ r4k_blast_dcache = (void *)cache_noop;
+ else if (dc_lsize == 16)
+ r4k_blast_dcache = blast_dcache16;
+ else if (dc_lsize == 32)
+ r4k_blast_dcache = blast_dcache32;
+ else if (dc_lsize == 64)
+ r4k_blast_dcache = blast_dcache64;
+}
+
+/* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */
+#define JUMP_TO_ALIGN(order) \
+ __asm__ __volatile__( \
+ "b\t1f\n\t" \
+ ".align\t" #order "\n\t" \
+ "1:\n\t" \
+ )
+#define CACHE32_UNROLL32_ALIGN JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */
+#define CACHE32_UNROLL32_ALIGN2 JUMP_TO_ALIGN(11)
+
+static inline void blast_r4600_v1_icache32(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ blast_icache32();
+ local_irq_restore(flags);
+}
+
+static inline void tx49_blast_icache32(void)
+{
+ unsigned long start = INDEX_BASE;
+ unsigned long end = start + current_cpu_data.icache.waysize;
+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
+ unsigned long ws_end = current_cpu_data.icache.ways <<
+ current_cpu_data.icache.waybit;
+ unsigned long ws, addr;
+
+ CACHE32_UNROLL32_ALIGN2;
+ /* I'm in even chunk. blast odd chunks */
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+ for (addr = start + 0x400; addr < end; addr += 0x400 * 2)
+ cache32_unroll32(addr|ws, Index_Invalidate_I);
+ CACHE32_UNROLL32_ALIGN;
+ /* I'm in odd chunk. blast even chunks */
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+ for (addr = start; addr < end; addr += 0x400 * 2)
+ cache32_unroll32(addr|ws, Index_Invalidate_I);
+}
+
+static inline void blast_icache32_r4600_v1_page_indexed(unsigned long page)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ blast_icache32_page_indexed(page);
+ local_irq_restore(flags);
+}
+
+static inline void tx49_blast_icache32_page_indexed(unsigned long page)
+{
+ unsigned long indexmask = current_cpu_data.icache.waysize - 1;
+ unsigned long start = INDEX_BASE + (page & indexmask);
+ unsigned long end = start + PAGE_SIZE;
+ unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
+ unsigned long ws_end = current_cpu_data.icache.ways <<
+ current_cpu_data.icache.waybit;
+ unsigned long ws, addr;
+
+ CACHE32_UNROLL32_ALIGN2;
+ /* I'm in even chunk. blast odd chunks */
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+ for (addr = start + 0x400; addr < end; addr += 0x400 * 2)
+ cache32_unroll32(addr|ws, Index_Invalidate_I);
+ CACHE32_UNROLL32_ALIGN;
+ /* I'm in odd chunk. blast even chunks */
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+ for (addr = start; addr < end; addr += 0x400 * 2)
+ cache32_unroll32(addr|ws, Index_Invalidate_I);
+}
+
+static void (* r4k_blast_icache_page)(unsigned long addr);
+
+static void __cpuinit r4k_blast_icache_page_setup(void)
+{
+ unsigned long ic_lsize = cpu_icache_line_size();
+
+ if (ic_lsize == 0)
+ r4k_blast_icache_page = (void *)cache_noop;
+ else if (ic_lsize == 16)
+ r4k_blast_icache_page = blast_icache16_page;
+ else if (ic_lsize == 32)
+ r4k_blast_icache_page = blast_icache32_page;
+ else if (ic_lsize == 64)
+ r4k_blast_icache_page = blast_icache64_page;
+}
+
+
+static void (* r4k_blast_icache_page_indexed)(unsigned long addr);
+
+static void __cpuinit r4k_blast_icache_page_indexed_setup(void)
+{
+ unsigned long ic_lsize = cpu_icache_line_size();
+
+ if (ic_lsize == 0)
+ r4k_blast_icache_page_indexed = (void *)cache_noop;
+ else if (ic_lsize == 16)
+ r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
+ else if (ic_lsize == 32) {
+ if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+ r4k_blast_icache_page_indexed =
+ blast_icache32_r4600_v1_page_indexed;
+ else if (TX49XX_ICACHE_INDEX_INV_WAR)
+ r4k_blast_icache_page_indexed =
+ tx49_blast_icache32_page_indexed;
+ else
+ r4k_blast_icache_page_indexed =
+ blast_icache32_page_indexed;
+ } else if (ic_lsize == 64)
+ r4k_blast_icache_page_indexed = blast_icache64_page_indexed;
+}
+
+static void (* r4k_blast_icache)(void);
+
+static void __cpuinit r4k_blast_icache_setup(void)
+{
+ unsigned long ic_lsize = cpu_icache_line_size();
+
+ if (ic_lsize == 0)
+ r4k_blast_icache = (void *)cache_noop;
+ else if (ic_lsize == 16)
+ r4k_blast_icache = blast_icache16;
+ else if (ic_lsize == 32) {
+ if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+ r4k_blast_icache = blast_r4600_v1_icache32;
+ else if (TX49XX_ICACHE_INDEX_INV_WAR)
+ r4k_blast_icache = tx49_blast_icache32;
+ else
+ r4k_blast_icache = blast_icache32;
+ } else if (ic_lsize == 64)
+ r4k_blast_icache = blast_icache64;
+}
+
+static void (* r4k_blast_scache_page)(unsigned long addr);
+
+static void __cpuinit r4k_blast_scache_page_setup(void)
+{
+ unsigned long sc_lsize = cpu_scache_line_size();
+
+ if (scache_size == 0)
+ r4k_blast_scache_page = (void *)cache_noop;
+ else if (sc_lsize == 16)
+ r4k_blast_scache_page = blast_scache16_page;
+ else if (sc_lsize == 32)
+ r4k_blast_scache_page = blast_scache32_page;
+ else if (sc_lsize == 64)
+ r4k_blast_scache_page = blast_scache64_page;
+ else if (sc_lsize == 128)
+ r4k_blast_scache_page = blast_scache128_page;
+}
+
+static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
+
+static void __cpuinit r4k_blast_scache_page_indexed_setup(void)
+{
+ unsigned long sc_lsize = cpu_scache_line_size();
+
+ if (scache_size == 0)
+ r4k_blast_scache_page_indexed = (void *)cache_noop;
+ else if (sc_lsize == 16)
+ r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
+ else if (sc_lsize == 32)
+ r4k_blast_scache_page_indexed = blast_scache32_page_indexed;
+ else if (sc_lsize == 64)
+ r4k_blast_scache_page_indexed = blast_scache64_page_indexed;
+ else if (sc_lsize == 128)
+ r4k_blast_scache_page_indexed = blast_scache128_page_indexed;
+}
+
+static void (* r4k_blast_scache)(void);
+
+static void __cpuinit r4k_blast_scache_setup(void)
+{
+ unsigned long sc_lsize = cpu_scache_line_size();
+
+ if (scache_size == 0)
+ r4k_blast_scache = (void *)cache_noop;
+ else if (sc_lsize == 16)
+ r4k_blast_scache = blast_scache16;
+ else if (sc_lsize == 32)
+ r4k_blast_scache = blast_scache32;
+ else if (sc_lsize == 64)
+ r4k_blast_scache = blast_scache64;
+ else if (sc_lsize == 128)
+ r4k_blast_scache = blast_scache128;
+}
+
+static inline void local_r4k___flush_cache_all(void * args)
+{
+#if defined(CONFIG_CPU_LOONGSON2)
+ r4k_blast_scache();
+ return;
+#endif
+ r4k_blast_dcache();
+ r4k_blast_icache();
+
+ switch (current_cpu_type()) {
+ case CPU_R4000SC:
+ case CPU_R4000MC:
+ case CPU_R4400SC:
+ case CPU_R4400MC:
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_R14000:
+ r4k_blast_scache();
+ }
+}
+
+static void r4k___flush_cache_all(void)
+{
+ r4k_on_each_cpu(local_r4k___flush_cache_all, NULL);
+}
+
+static inline int has_valid_asid(const struct mm_struct *mm)
+{
+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
+ int i;
+
+ for_each_online_cpu(i)
+ if (cpu_context(i, mm))
+ return 1;
+
+ return 0;
+#else
+ return cpu_context(smp_processor_id(), mm);
+#endif
+}
+
+static void r4k__flush_cache_vmap(void)
+{
+ r4k_blast_dcache();
+}
+
+static void r4k__flush_cache_vunmap(void)
+{
+ r4k_blast_dcache();
+}
+
+static inline void local_r4k_flush_cache_range(void * args)
+{
+ struct vm_area_struct *vma = args;
+ int exec = vma->vm_flags & VM_EXEC;
+
+ if (!(has_valid_asid(vma->vm_mm)))
+ return;
+
+ r4k_blast_dcache();
+ if (exec)
+ r4k_blast_icache();
+}
+
+static void r4k_flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ int exec = vma->vm_flags & VM_EXEC;
+
+ if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
+ r4k_on_each_cpu(local_r4k_flush_cache_range, vma);
+}
+
+static inline void local_r4k_flush_cache_mm(void * args)
+{
+ struct mm_struct *mm = args;
+
+ if (!has_valid_asid(mm))
+ return;
+
+ /*
+ * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we
+ * only flush the primary caches but R10000 and R12000 behave sane ...
+ * R4000SC and R4400SC indexed S-cache ops also invalidate primary
+ * caches, so we can bail out early.
+ */
+ if (current_cpu_type() == CPU_R4000SC ||
+ current_cpu_type() == CPU_R4000MC ||
+ current_cpu_type() == CPU_R4400SC ||
+ current_cpu_type() == CPU_R4400MC) {
+ r4k_blast_scache();
+ return;
+ }
+
+ r4k_blast_dcache();
+}
+
+static void r4k_flush_cache_mm(struct mm_struct *mm)
+{
+ if (!cpu_has_dc_aliases)
+ return;
+
+ r4k_on_each_cpu(local_r4k_flush_cache_mm, mm);
+}
+
+struct flush_cache_page_args {
+ struct vm_area_struct *vma;
+ unsigned long addr;
+ unsigned long pfn;
+};
+
+static inline void local_r4k_flush_cache_page(void *args)
+{
+ struct flush_cache_page_args *fcp_args = args;
+ struct vm_area_struct *vma = fcp_args->vma;
+ unsigned long addr = fcp_args->addr;
+ struct page *page = pfn_to_page(fcp_args->pfn);
+ int exec = vma->vm_flags & VM_EXEC;
+ struct mm_struct *mm = vma->vm_mm;
+ int map_coherent = 0;
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+ void *vaddr;
+
+ /*
+ * If ownes no valid ASID yet, cannot possibly have gotten
+ * this page into the cache.
+ */
+ if (!has_valid_asid(mm))
+ return;
+
+ addr &= PAGE_MASK;
+ pgdp = pgd_offset(mm, addr);
+ pudp = pud_offset(pgdp, addr);
+ pmdp = pmd_offset(pudp, addr);
+ ptep = pte_offset(pmdp, addr);
+
+ /*
+ * If the page isn't marked valid, the page cannot possibly be
+ * in the cache.
+ */
+ if (!(pte_present(*ptep)))
+ return;
+
+ if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID))
+ vaddr = NULL;
+ else {
+ /*
+ * Use kmap_coherent or kmap_atomic to do flushes for
+ * another ASID than the current one.
+ */
+ map_coherent = (cpu_has_dc_aliases &&
+ page_mapped(page) && !Page_dcache_dirty(page));
+ if (map_coherent)
+ vaddr = kmap_coherent(page, addr);
+ else
+ vaddr = kmap_atomic(page, KM_USER0);
+ addr = (unsigned long)vaddr;
+ }
+
+ if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+ r4k_blast_dcache_page(addr);
+ if (exec && !cpu_icache_snoops_remote_store)
+ r4k_blast_scache_page(addr);
+ }
+ if (exec) {
+ if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
+ int cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0)
+ drop_mmu_context(mm, cpu);
+ } else
+ r4k_blast_icache_page(addr);
+ }
+
+ if (vaddr) {
+ if (map_coherent)
+ kunmap_coherent();
+ else
+ kunmap_atomic(vaddr, KM_USER0);
+ }
+}
+
+static void r4k_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long pfn)
+{
+ struct flush_cache_page_args args;
+
+ args.vma = vma;
+ args.addr = addr;
+ args.pfn = pfn;
+
+ r4k_on_each_cpu(local_r4k_flush_cache_page, &args);
+}
+
+static inline void local_r4k_flush_data_cache_page(void * addr)
+{
+ r4k_blast_dcache_page((unsigned long) addr);
+}
+
+static void r4k_flush_data_cache_page(unsigned long addr)
+{
+ if (in_atomic())
+ local_r4k_flush_data_cache_page((void *)addr);
+ else
+ r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr);
+}
+
+struct flush_icache_range_args {
+ unsigned long start;
+ unsigned long end;
+};
+
+static inline void local_r4k_flush_icache_range(unsigned long start, unsigned long end)
+{
+ if (!cpu_has_ic_fills_f_dc) {
+ if (end - start >= dcache_size) {
+ r4k_blast_dcache();
+ } else {
+ R4600_HIT_CACHEOP_WAR_IMPL;
+ protected_blast_dcache_range(start, end);
+ }
+ }
+
+ if (end - start > icache_size)
+ r4k_blast_icache();
+ else
+ protected_blast_icache_range(start, end);
+}
+
+static inline void local_r4k_flush_icache_range_ipi(void *args)
+{
+ struct flush_icache_range_args *fir_args = args;
+ unsigned long start = fir_args->start;
+ unsigned long end = fir_args->end;
+
+ local_r4k_flush_icache_range(start, end);
+}
+
+static void r4k_flush_icache_range(unsigned long start, unsigned long end)
+{
+ struct flush_icache_range_args args;
+
+ args.start = start;
+ args.end = end;
+
+ r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args);
+ instruction_hazard();
+}
+
+#ifdef CONFIG_DMA_NONCOHERENT
+
+static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+ /* Catch bad driver code */
+ BUG_ON(size == 0);
+
+ if (cpu_has_inclusive_pcaches) {
+ if (size >= scache_size)
+ r4k_blast_scache();
+ else
+ blast_scache_range(addr, addr + size);
+ return;
+ }
+
+ /*
+ * Either no secondary cache or the available caches don't have the
+ * subset property so we have to flush the primary caches
+ * explicitly
+ */
+ if (cpu_has_safe_index_cacheops && size >= dcache_size) {
+ r4k_blast_dcache();
+ } else {
+ R4600_HIT_CACHEOP_WAR_IMPL;
+ blast_dcache_range(addr, addr + size);
+ }
+
+ bc_wback_inv(addr, size);
+}
+
+static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+ /* Catch bad driver code */
+ BUG_ON(size == 0);
+
+ if (cpu_has_inclusive_pcaches) {
+ if (size >= scache_size)
+ r4k_blast_scache();
+ else {
+ unsigned long lsize = cpu_scache_line_size();
+ unsigned long almask = ~(lsize - 1);
+
+ /*
+ * There is no clearly documented alignment requirement
+ * for the cache instruction on MIPS processors and
+ * some processors, among them the RM5200 and RM7000
+ * QED processors will throw an address error for cache
+ * hit ops with insufficient alignment. Solved by
+ * aligning the address to cache line size.
+ */
+ cache_op(Hit_Writeback_Inv_SD, addr & almask);
+ cache_op(Hit_Writeback_Inv_SD,
+ (addr + size - 1) & almask);
+ blast_inv_scache_range(addr, addr + size);
+ }
+ return;
+ }
+
+ if (cpu_has_safe_index_cacheops && size >= dcache_size) {
+ r4k_blast_dcache();
+ } else {
+ unsigned long lsize = cpu_dcache_line_size();
+ unsigned long almask = ~(lsize - 1);
+
+ R4600_HIT_CACHEOP_WAR_IMPL;
+ cache_op(Hit_Writeback_Inv_D, addr & almask);
+ cache_op(Hit_Writeback_Inv_D, (addr + size - 1) & almask);
+ blast_inv_dcache_range(addr, addr + size);
+ }
+
+ bc_inv(addr, size);
+}
+#endif /* CONFIG_DMA_NONCOHERENT */
+
+/*
+ * While we're protected against bad userland addresses we don't care
+ * very much about what happens in that case. Usually a segmentation
+ * fault will dump the process later on anyway ...
+ */
+static void local_r4k_flush_cache_sigtramp(void * arg)
+{
+ unsigned long ic_lsize = cpu_icache_line_size();
+ unsigned long dc_lsize = cpu_dcache_line_size();
+ unsigned long sc_lsize = cpu_scache_line_size();
+ unsigned long addr = (unsigned long) arg;
+
+ R4600_HIT_CACHEOP_WAR_IMPL;
+ if (dc_lsize)
+ protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+ if (!cpu_icache_snoops_remote_store && scache_size)
+ protected_writeback_scache_line(addr & ~(sc_lsize - 1));
+ if (ic_lsize)
+ protected_flush_icache_line(addr & ~(ic_lsize - 1));
+ if (MIPS4K_ICACHE_REFILL_WAR) {
+ __asm__ __volatile__ (
+ ".set push\n\t"
+ ".set noat\n\t"
+ ".set mips3\n\t"
+#ifdef CONFIG_32BIT
+ "la $at,1f\n\t"
+#endif
+#ifdef CONFIG_64BIT
+ "dla $at,1f\n\t"
+#endif
+ "cache %0,($at)\n\t"
+ "nop; nop; nop\n"
+ "1:\n\t"
+ ".set pop"
+ :
+ : "i" (Hit_Invalidate_I));
+ }
+ if (MIPS_CACHE_SYNC_WAR)
+ __asm__ __volatile__ ("sync");
+}
+
+static void r4k_flush_cache_sigtramp(unsigned long addr)
+{
+ r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr);
+}
+
+static void r4k_flush_icache_all(void)
+{
+ if (cpu_has_vtag_icache)
+ r4k_blast_icache();
+}
+
+static inline void rm7k_erratum31(void)
+{
+ const unsigned long ic_lsize = 32;
+ unsigned long addr;
+
+ /* RM7000 erratum #31. The icache is screwed at startup. */
+ write_c0_taglo(0);
+ write_c0_taghi(0);
+
+ for (addr = INDEX_BASE; addr <= INDEX_BASE + 4096; addr += ic_lsize) {
+ __asm__ __volatile__ (
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ ".set mips3\n\t"
+ "cache\t%1, 0(%0)\n\t"
+ "cache\t%1, 0x1000(%0)\n\t"
+ "cache\t%1, 0x2000(%0)\n\t"
+ "cache\t%1, 0x3000(%0)\n\t"
+ "cache\t%2, 0(%0)\n\t"
+ "cache\t%2, 0x1000(%0)\n\t"
+ "cache\t%2, 0x2000(%0)\n\t"
+ "cache\t%2, 0x3000(%0)\n\t"
+ "cache\t%1, 0(%0)\n\t"
+ "cache\t%1, 0x1000(%0)\n\t"
+ "cache\t%1, 0x2000(%0)\n\t"
+ "cache\t%1, 0x3000(%0)\n\t"
+ ".set pop\n"
+ :
+ : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill));
+ }
+}
+
+static char *way_string[] __cpuinitdata = { NULL, "direct mapped", "2-way",
+ "3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
+};
+
+static void __cpuinit probe_pcache(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int config = read_c0_config();
+ unsigned int prid = read_c0_prid();
+ unsigned long config1;
+ unsigned int lsize;
+
+ switch (c->cputype) {
+ case CPU_R4600: /* QED style two way caches? */
+ case CPU_R4700:
+ case CPU_R5000:
+ case CPU_NEVADA:
+ icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+ c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+ c->icache.ways = 2;
+ c->icache.waybit = __ffs(icache_size/2);
+
+ dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+ c->dcache.ways = 2;
+ c->dcache.waybit= __ffs(dcache_size/2);
+
+ c->options |= MIPS_CPU_CACHE_CDEX_P;
+ break;
+
+ case CPU_R5432:
+ case CPU_R5500:
+ icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+ c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+ c->icache.ways = 2;
+ c->icache.waybit= 0;
+
+ dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+ c->dcache.ways = 2;
+ c->dcache.waybit = 0;
+
+ c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH;
+ break;
+
+ case CPU_TX49XX:
+ icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+ c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+ c->icache.ways = 4;
+ c->icache.waybit= 0;
+
+ dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+ c->dcache.ways = 4;
+ c->dcache.waybit = 0;
+
+ c->options |= MIPS_CPU_CACHE_CDEX_P;
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+
+ case CPU_R4000PC:
+ case CPU_R4000SC:
+ case CPU_R4000MC:
+ case CPU_R4400PC:
+ case CPU_R4400SC:
+ case CPU_R4400MC:
+ case CPU_R4300:
+ icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+ c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+ c->icache.ways = 1;
+ c->icache.waybit = 0; /* doesn't matter */
+
+ dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+ c->dcache.ways = 1;
+ c->dcache.waybit = 0; /* does not matter */
+
+ c->options |= MIPS_CPU_CACHE_CDEX_P;
+ break;
+
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_R14000:
+ icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29));
+ c->icache.linesz = 64;
+ c->icache.ways = 2;
+ c->icache.waybit = 0;
+
+ dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26));
+ c->dcache.linesz = 32;
+ c->dcache.ways = 2;
+ c->dcache.waybit = 0;
+
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+
+ case CPU_VR4133:
+ write_c0_config(config & ~VR41_CONF_P4K);
+ case CPU_VR4131:
+ /* Workaround for cache instruction bug of VR4131 */
+ if (c->processor_id == 0x0c80U || c->processor_id == 0x0c81U ||
+ c->processor_id == 0x0c82U) {
+ config |= 0x00400000U;
+ if (c->processor_id == 0x0c80U)
+ config |= VR41_CONF_BP;
+ write_c0_config(config);
+ } else
+ c->options |= MIPS_CPU_CACHE_CDEX_P;
+
+ icache_size = 1 << (10 + ((config & CONF_IC) >> 9));
+ c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+ c->icache.ways = 2;
+ c->icache.waybit = __ffs(icache_size/2);
+
+ dcache_size = 1 << (10 + ((config & CONF_DC) >> 6));
+ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+ c->dcache.ways = 2;
+ c->dcache.waybit = __ffs(dcache_size/2);
+ break;
+
+ case CPU_VR41XX:
+ case CPU_VR4111:
+ case CPU_VR4121:
+ case CPU_VR4122:
+ case CPU_VR4181:
+ case CPU_VR4181A:
+ icache_size = 1 << (10 + ((config & CONF_IC) >> 9));
+ c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+ c->icache.ways = 1;
+ c->icache.waybit = 0; /* doesn't matter */
+
+ dcache_size = 1 << (10 + ((config & CONF_DC) >> 6));
+ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+ c->dcache.ways = 1;
+ c->dcache.waybit = 0; /* does not matter */
+
+ c->options |= MIPS_CPU_CACHE_CDEX_P;
+ break;
+
+ case CPU_RM7000:
+ rm7k_erratum31();
+
+ case CPU_RM9000:
+ icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+ c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+ c->icache.ways = 4;
+ c->icache.waybit = __ffs(icache_size / c->icache.ways);
+
+ dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+ c->dcache.ways = 4;
+ c->dcache.waybit = __ffs(dcache_size / c->dcache.ways);
+
+#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)
+ c->options |= MIPS_CPU_CACHE_CDEX_P;
+#endif
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+
+ case CPU_LOONGSON2:
+ icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
+ c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
+ if (prid & 0x3)
+ c->icache.ways = 4;
+ else
+ c->icache.ways = 2;
+ c->icache.waybit = 0;
+
+ dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
+ c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
+ if (prid & 0x3)
+ c->dcache.ways = 4;
+ else
+ c->dcache.ways = 2;
+ c->dcache.waybit = 0;
+ break;
+
+ default:
+ if (!(config & MIPS_CONF_M))
+ panic("Don't know how to probe P-caches on this cpu.");
+
+ /*
+ * So we seem to be a MIPS32 or MIPS64 CPU
+ * So let's probe the I-cache ...
+ */
+ config1 = read_c0_config1();
+
+ if ((lsize = ((config1 >> 19) & 7)))
+ c->icache.linesz = 2 << lsize;
+ else
+ c->icache.linesz = lsize;
+ c->icache.sets = 64 << ((config1 >> 22) & 7);
+ c->icache.ways = 1 + ((config1 >> 16) & 7);
+
+ icache_size = c->icache.sets *
+ c->icache.ways *
+ c->icache.linesz;
+ c->icache.waybit = __ffs(icache_size/c->icache.ways);
+
+ if (config & 0x8) /* VI bit */
+ c->icache.flags |= MIPS_CACHE_VTAG;
+
+ /*
+ * Now probe the MIPS32 / MIPS64 data cache.
+ */
+ c->dcache.flags = 0;
+
+ if ((lsize = ((config1 >> 10) & 7)))
+ c->dcache.linesz = 2 << lsize;
+ else
+ c->dcache.linesz= lsize;
+ c->dcache.sets = 64 << ((config1 >> 13) & 7);
+ c->dcache.ways = 1 + ((config1 >> 7) & 7);
+
+ dcache_size = c->dcache.sets *
+ c->dcache.ways *
+ c->dcache.linesz;
+ c->dcache.waybit = __ffs(dcache_size/c->dcache.ways);
+
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+ }
+
+ /*
+ * Processor configuration sanity check for the R4000SC erratum
+ * #5. With page sizes larger than 32kB there is no possibility
+ * to get a VCE exception anymore so we don't care about this
+ * misconfiguration. The case is rather theoretical anyway;
+ * presumably no vendor is shipping his hardware in the "bad"
+ * configuration.
+ */
+ if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 &&
+ !(config & CONF_SC) && c->icache.linesz != 16 &&
+ PAGE_SIZE <= 0x8000)
+ panic("Improper R4000SC processor configuration detected");
+
+ /* compute a couple of other cache variables */
+ c->icache.waysize = icache_size / c->icache.ways;
+ c->dcache.waysize = dcache_size / c->dcache.ways;
+
+ c->icache.sets = c->icache.linesz ?
+ icache_size / (c->icache.linesz * c->icache.ways) : 0;
+ c->dcache.sets = c->dcache.linesz ?
+ dcache_size / (c->dcache.linesz * c->dcache.ways) : 0;
+
+ /*
+ * R10000 and R12000 P-caches are odd in a positive way. They're 32kB
+ * 2-way virtually indexed so normally would suffer from aliases. So
+ * normally they'd suffer from aliases but magic in the hardware deals
+ * with that for us so we don't need to take care ourselves.
+ */
+ switch (c->cputype) {
+ case CPU_20KC:
+ case CPU_25KF:
+ case CPU_SB1:
+ case CPU_SB1A:
+ case CPU_XLR:
+ c->dcache.flags |= MIPS_CACHE_PINDEX;
+ break;
+
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_R14000:
+ break;
+
+ case CPU_24K:
+ case CPU_34K:
+ case CPU_74K:
+ case CPU_1004K:
+ if ((read_c0_config7() & (1 << 16))) {
+ /* effectively physically indexed dcache,
+ thus no virtual aliases. */
+ c->dcache.flags |= MIPS_CACHE_PINDEX;
+ break;
+ }
+ default:
+ if (c->dcache.waysize > PAGE_SIZE)
+ c->dcache.flags |= MIPS_CACHE_ALIASES;
+ }
+
+ switch (c->cputype) {
+ case CPU_20KC:
+ /*
+ * Some older 20Kc chips doesn't have the 'VI' bit in
+ * the config register.
+ */
+ c->icache.flags |= MIPS_CACHE_VTAG;
+ break;
+
+ case CPU_ALCHEMY:
+ c->icache.flags |= MIPS_CACHE_IC_F_DC;
+ break;
+ }
+
+#ifdef CONFIG_CPU_LOONGSON2
+ /*
+ * LOONGSON2 has 4 way icache, but when using indexed cache op,
+ * one op will act on all 4 ways
+ */
+ c->icache.ways = 1;
+#endif
+
+ printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n",
+ icache_size >> 10,
+ c->icache.flags & MIPS_CACHE_VTAG ? "VIVT" : "VIPT",
+ way_string[c->icache.ways], c->icache.linesz);
+
+ printk("Primary data cache %ldkB, %s, %s, %s, linesize %d bytes\n",
+ dcache_size >> 10, way_string[c->dcache.ways],
+ (c->dcache.flags & MIPS_CACHE_PINDEX) ? "PIPT" : "VIPT",
+ (c->dcache.flags & MIPS_CACHE_ALIASES) ?
+ "cache aliases" : "no aliases",
+ c->dcache.linesz);
+}
+
+/*
+ * If you even _breathe_ on this function, look at the gcc output and make sure
+ * it does not pop things on and off the stack for the cache sizing loop that
+ * executes in KSEG1 space or else you will crash and burn badly. You have
+ * been warned.
+ */
+static int __cpuinit probe_scache(void)
+{
+ unsigned long flags, addr, begin, end, pow2;
+ unsigned int config = read_c0_config();
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ if (config & CONF_SC)
+ return 0;
+
+ begin = (unsigned long) &_stext;
+ begin &= ~((4 * 1024 * 1024) - 1);
+ end = begin + (4 * 1024 * 1024);
+
+ /*
+ * This is such a bitch, you'd think they would make it easy to do
+ * this. Away you daemons of stupidity!
+ */
+ local_irq_save(flags);
+
+ /* Fill each size-multiple cache line with a valid tag. */
+ pow2 = (64 * 1024);
+ for (addr = begin; addr < end; addr = (begin + pow2)) {
+ unsigned long *p = (unsigned long *) addr;
+ __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */
+ pow2 <<= 1;
+ }
+
+ /* Load first line with zero (therefore invalid) tag. */
+ write_c0_taglo(0);
+ write_c0_taghi(0);
+ __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+ cache_op(Index_Store_Tag_I, begin);
+ cache_op(Index_Store_Tag_D, begin);
+ cache_op(Index_Store_Tag_SD, begin);
+
+ /* Now search for the wrap around point. */
+ pow2 = (128 * 1024);
+ for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) {
+ cache_op(Index_Load_Tag_SD, addr);
+ __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+ if (!read_c0_taglo())
+ break;
+ pow2 <<= 1;
+ }
+ local_irq_restore(flags);
+ addr -= begin;
+
+ scache_size = addr;
+ c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22);
+ c->scache.ways = 1;
+ c->dcache.waybit = 0; /* does not matter */
+
+ return 1;
+}
+
+#if defined(CONFIG_CPU_LOONGSON2)
+static void __init loongson2_sc_init(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ scache_size = 512*1024;
+ c->scache.linesz = 32;
+ c->scache.ways = 4;
+ c->scache.waybit = 0;
+ c->scache.waysize = scache_size / (c->scache.ways);
+ c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
+ pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
+ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
+
+ c->options |= MIPS_CPU_INCLUSIVE_CACHES;
+}
+#endif
+
+extern int r5k_sc_init(void);
+extern int rm7k_sc_init(void);
+extern int mips_sc_init(void);
+
+static void __cpuinit setup_scache(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int config = read_c0_config();
+ int sc_present = 0;
+
+ /*
+ * Do the probing thing on R4000SC and R4400SC processors. Other
+ * processors don't have a S-cache that would be relevant to the
+ * Linux memory management.
+ */
+ switch (c->cputype) {
+ case CPU_R4000SC:
+ case CPU_R4000MC:
+ case CPU_R4400SC:
+ case CPU_R4400MC:
+ sc_present = run_uncached(probe_scache);
+ if (sc_present)
+ c->options |= MIPS_CPU_CACHE_CDEX_S;
+ break;
+
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_R14000:
+ scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16);
+ c->scache.linesz = 64 << ((config >> 13) & 1);
+ c->scache.ways = 2;
+ c->scache.waybit= 0;
+ sc_present = 1;
+ break;
+
+ case CPU_R5000:
+ case CPU_NEVADA:
+#ifdef CONFIG_R5000_CPU_SCACHE
+ r5k_sc_init();
+#endif
+ return;
+
+ case CPU_RM7000:
+ case CPU_RM9000:
+#ifdef CONFIG_RM7000_CPU_SCACHE
+ rm7k_sc_init();
+#endif
+ return;
+
+#if defined(CONFIG_CPU_LOONGSON2)
+ case CPU_LOONGSON2:
+ loongson2_sc_init();
+ return;
+#endif
+
+ default:
+ if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
+ c->isa_level == MIPS_CPU_ISA_M32R2 ||
+ c->isa_level == MIPS_CPU_ISA_M64R1 ||
+ c->isa_level == MIPS_CPU_ISA_M64R2) {
+#ifdef CONFIG_MIPS_CPU_SCACHE
+ if (mips_sc_init ()) {
+ scache_size = c->scache.ways * c->scache.sets * c->scache.linesz;
+ printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n",
+ scache_size >> 10,
+ way_string[c->scache.ways], c->scache.linesz);
+ }
+#else
+ if (!(c->scache.flags & MIPS_CACHE_NOT_PRESENT))
+ panic("Dunno how to handle MIPS32 / MIPS64 second level cache");
+#endif
+ return;
+ }
+ sc_present = 0;
+ }
+
+ if (!sc_present)
+ return;
+
+ /* compute a couple of other cache variables */
+ c->scache.waysize = scache_size / c->scache.ways;
+
+ c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
+
+ printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
+ scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
+
+ c->options |= MIPS_CPU_INCLUSIVE_CACHES;
+}
+
+void au1x00_fixup_config_od(void)
+{
+ /*
+ * c0_config.od (bit 19) was write only (and read as 0)
+ * on the early revisions of Alchemy SOCs. It disables the bus
+ * transaction overlapping and needs to be set to fix various errata.
+ */
+ switch (read_c0_prid()) {
+ case 0x00030100: /* Au1000 DA */
+ case 0x00030201: /* Au1000 HA */
+ case 0x00030202: /* Au1000 HB */
+ case 0x01030200: /* Au1500 AB */
+ /*
+ * Au1100 errata actually keeps silence about this bit, so we set it
+ * just in case for those revisions that require it to be set according
+ * to the (now gone) cpu table.
+ */
+ case 0x02030200: /* Au1100 AB */
+ case 0x02030201: /* Au1100 BA */
+ case 0x02030202: /* Au1100 BC */
+ set_c0_config(1 << 19);
+ break;
+ }
+}
+
+/* CP0 hazard avoidance. */
+#define NXP_BARRIER() \
+ __asm__ __volatile__( \
+ ".set noreorder\n\t" \
+ "nop; nop; nop; nop; nop; nop;\n\t" \
+ ".set reorder\n\t")
+
+static void nxp_pr4450_fixup_config(void)
+{
+ unsigned long config0;
+
+ config0 = read_c0_config();
+
+ /* clear all three cache coherency fields */
+ config0 &= ~(0x7 | (7 << 25) | (7 << 28));
+ config0 |= (((_page_cachable_default >> _CACHE_SHIFT) << 0) |
+ ((_page_cachable_default >> _CACHE_SHIFT) << 25) |
+ ((_page_cachable_default >> _CACHE_SHIFT) << 28));
+ write_c0_config(config0);
+ NXP_BARRIER();
+}
+
+static int __cpuinitdata cca = -1;
+
+static int __init cca_setup(char *str)
+{
+ get_option(&str, &cca);
+
+ return 1;
+}
+
+__setup("cca=", cca_setup);
+
+static void __cpuinit coherency_setup(void)
+{
+ if (cca < 0 || cca > 7)
+ cca = read_c0_config() & CONF_CM_CMASK;
+ _page_cachable_default = cca << _CACHE_SHIFT;
+
+ pr_debug("Using cache attribute %d\n", cca);
+ change_c0_config(CONF_CM_CMASK, cca);
+
+ /*
+ * c0_status.cu=0 specifies that updates by the sc instruction use
+ * the coherency mode specified by the TLB; 1 means cachable
+ * coherent update on write will be used. Not all processors have
+ * this bit and; some wire it to zero, others like Toshiba had the
+ * silly idea of putting something else there ...
+ */
+ switch (current_cpu_type()) {
+ case CPU_R4000PC:
+ case CPU_R4000SC:
+ case CPU_R4000MC:
+ case CPU_R4400PC:
+ case CPU_R4400SC:
+ case CPU_R4400MC:
+ clear_c0_config(CONF_CU);
+ break;
+ /*
+ * We need to catch the early Alchemy SOCs with
+ * the write-only co_config.od bit and set it back to one on:
+ * Au1000 rev DA, HA, HB; Au1100 AB, BA, BC, Au1500 AB
+ */
+ case CPU_ALCHEMY:
+ au1x00_fixup_config_od();
+ break;
+
+ case PRID_IMP_PR4450:
+ nxp_pr4450_fixup_config();
+ break;
+ }
+}
+
+#if defined(CONFIG_DMA_NONCOHERENT)
+
+static int __cpuinitdata coherentio;
+
+static int __init setcoherentio(char *str)
+{
+ coherentio = 1;
+
+ return 1;
+}
+
+__setup("coherentio", setcoherentio);
+#endif
+
+void __cpuinit r4k_cache_init(void)
+{
+ extern void build_clear_page(void);
+ extern void build_copy_page(void);
+ extern char __weak except_vec2_generic;
+ extern char __weak except_vec2_sb1;
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ switch (c->cputype) {
+ case CPU_SB1:
+ case CPU_SB1A:
+ set_uncached_handler(0x100, &except_vec2_sb1, 0x80);
+ break;
+
+ default:
+ set_uncached_handler(0x100, &except_vec2_generic, 0x80);
+ break;
+ }
+
+ probe_pcache();
+ setup_scache();
+
+ r4k_blast_dcache_page_setup();
+ r4k_blast_dcache_page_indexed_setup();
+ r4k_blast_dcache_setup();
+ r4k_blast_icache_page_setup();
+ r4k_blast_icache_page_indexed_setup();
+ r4k_blast_icache_setup();
+ r4k_blast_scache_page_setup();
+ r4k_blast_scache_page_indexed_setup();
+ r4k_blast_scache_setup();
+
+ /*
+ * Some MIPS32 and MIPS64 processors have physically indexed caches.
+ * This code supports virtually indexed processors and will be
+ * unnecessarily inefficient on physically indexed processors.
+ */
+ if (c->dcache.linesz)
+ shm_align_mask = max_t( unsigned long,
+ c->dcache.sets * c->dcache.linesz - 1,
+ PAGE_SIZE - 1);
+ else
+ shm_align_mask = PAGE_SIZE-1;
+
+ __flush_cache_vmap = r4k__flush_cache_vmap;
+ __flush_cache_vunmap = r4k__flush_cache_vunmap;
+
+ flush_cache_all = cache_noop;
+ __flush_cache_all = r4k___flush_cache_all;
+ flush_cache_mm = r4k_flush_cache_mm;
+ flush_cache_page = r4k_flush_cache_page;
+ flush_cache_range = r4k_flush_cache_range;
+
+ flush_cache_sigtramp = r4k_flush_cache_sigtramp;
+ flush_icache_all = r4k_flush_icache_all;
+ local_flush_data_cache_page = local_r4k_flush_data_cache_page;
+ flush_data_cache_page = r4k_flush_data_cache_page;
+ flush_icache_range = r4k_flush_icache_range;
+ local_flush_icache_range = local_r4k_flush_icache_range;
+
+#if defined(CONFIG_DMA_NONCOHERENT)
+ if (coherentio) {
+ _dma_cache_wback_inv = (void *)cache_noop;
+ _dma_cache_wback = (void *)cache_noop;
+ _dma_cache_inv = (void *)cache_noop;
+ } else {
+ _dma_cache_wback_inv = r4k_dma_cache_wback_inv;
+ _dma_cache_wback = r4k_dma_cache_wback_inv;
+ _dma_cache_inv = r4k_dma_cache_inv;
+ }
+#endif
+
+ build_clear_page();
+ build_copy_page();
+#if !defined(CONFIG_MIPS_CMP)
+ local_r4k___flush_cache_all(NULL);
+#endif
+ coherency_setup();
+}
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
new file mode 100644
index 00000000..d352fad3
--- /dev/null
+++ b/arch/mips/mm/c-tx39.c
@@ -0,0 +1,434 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+
+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+/* For R3000 cores with R4000 style caches */
+static unsigned long icache_size, dcache_size; /* Size in bytes */
+
+#include <asm/r4kcache.h>
+
+extern int r3k_have_wired_reg; /* in r3k-tlb.c */
+
+/* This sequence is required to ensure icache is disabled immediately */
+#define TX39_STOP_STREAMING() \
+__asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ "b 1f\n\t" \
+ "nop\n\t" \
+ "1:\n\t" \
+ ".set pop" \
+ )
+
+/* TX39H-style cache flush routines. */
+static void tx39h_flush_icache_all(void)
+{
+ unsigned long flags, config;
+
+ /* disable icache (set ICE#) */
+ local_irq_save(flags);
+ config = read_c0_conf();
+ write_c0_conf(config & ~TX39_CONF_ICE);
+ TX39_STOP_STREAMING();
+ blast_icache16();
+ write_c0_conf(config);
+ local_irq_restore(flags);
+}
+
+static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+ /* Catch bad driver code */
+ BUG_ON(size == 0);
+
+ iob();
+ blast_inv_dcache_range(addr, addr + size);
+}
+
+
+/* TX39H2,TX39H3 */
+static inline void tx39_blast_dcache_page(unsigned long addr)
+{
+ if (current_cpu_type() != CPU_TX3912)
+ blast_dcache16_page(addr);
+}
+
+static inline void tx39_blast_dcache_page_indexed(unsigned long addr)
+{
+ blast_dcache16_page_indexed(addr);
+}
+
+static inline void tx39_blast_dcache(void)
+{
+ blast_dcache16();
+}
+
+static inline void tx39_blast_icache_page(unsigned long addr)
+{
+ unsigned long flags, config;
+ /* disable icache (set ICE#) */
+ local_irq_save(flags);
+ config = read_c0_conf();
+ write_c0_conf(config & ~TX39_CONF_ICE);
+ TX39_STOP_STREAMING();
+ blast_icache16_page(addr);
+ write_c0_conf(config);
+ local_irq_restore(flags);
+}
+
+static inline void tx39_blast_icache_page_indexed(unsigned long addr)
+{
+ unsigned long flags, config;
+ /* disable icache (set ICE#) */
+ local_irq_save(flags);
+ config = read_c0_conf();
+ write_c0_conf(config & ~TX39_CONF_ICE);
+ TX39_STOP_STREAMING();
+ blast_icache16_page_indexed(addr);
+ write_c0_conf(config);
+ local_irq_restore(flags);
+}
+
+static inline void tx39_blast_icache(void)
+{
+ unsigned long flags, config;
+ /* disable icache (set ICE#) */
+ local_irq_save(flags);
+ config = read_c0_conf();
+ write_c0_conf(config & ~TX39_CONF_ICE);
+ TX39_STOP_STREAMING();
+ blast_icache16();
+ write_c0_conf(config);
+ local_irq_restore(flags);
+}
+
+static void tx39__flush_cache_vmap(void)
+{
+ tx39_blast_dcache();
+}
+
+static void tx39__flush_cache_vunmap(void)
+{
+ tx39_blast_dcache();
+}
+
+static inline void tx39_flush_cache_all(void)
+{
+ if (!cpu_has_dc_aliases)
+ return;
+
+ tx39_blast_dcache();
+}
+
+static inline void tx39___flush_cache_all(void)
+{
+ tx39_blast_dcache();
+ tx39_blast_icache();
+}
+
+static void tx39_flush_cache_mm(struct mm_struct *mm)
+{
+ if (!cpu_has_dc_aliases)
+ return;
+
+ if (cpu_context(smp_processor_id(), mm) != 0)
+ tx39_blast_dcache();
+}
+
+static void tx39_flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ if (!cpu_has_dc_aliases)
+ return;
+ if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
+ return;
+
+ tx39_blast_dcache();
+}
+
+static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+{
+ int exec = vma->vm_flags & VM_EXEC;
+ struct mm_struct *mm = vma->vm_mm;
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+
+ /*
+ * If ownes no valid ASID yet, cannot possibly have gotten
+ * this page into the cache.
+ */
+ if (cpu_context(smp_processor_id(), mm) == 0)
+ return;
+
+ page &= PAGE_MASK;
+ pgdp = pgd_offset(mm, page);
+ pudp = pud_offset(pgdp, page);
+ pmdp = pmd_offset(pudp, page);
+ ptep = pte_offset(pmdp, page);
+
+ /*
+ * If the page isn't marked valid, the page cannot possibly be
+ * in the cache.
+ */
+ if (!(pte_val(*ptep) & _PAGE_PRESENT))
+ return;
+
+ /*
+ * Doing flushes for another ASID than the current one is
+ * too difficult since stupid R4k caches do a TLB translation
+ * for every cache flush operation. So we do indexed flushes
+ * in that case, which doesn't overly flush the cache too much.
+ */
+ if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+ if (cpu_has_dc_aliases || exec)
+ tx39_blast_dcache_page(page);
+ if (exec)
+ tx39_blast_icache_page(page);
+
+ return;
+ }
+
+ /*
+ * Do indexed flush, too much work to get the (possible) TLB refills
+ * to work correctly.
+ */
+ if (cpu_has_dc_aliases || exec)
+ tx39_blast_dcache_page_indexed(page);
+ if (exec)
+ tx39_blast_icache_page_indexed(page);
+}
+
+static void local_tx39_flush_data_cache_page(void * addr)
+{
+ tx39_blast_dcache_page((unsigned long)addr);
+}
+
+static void tx39_flush_data_cache_page(unsigned long addr)
+{
+ tx39_blast_dcache_page(addr);
+}
+
+static void tx39_flush_icache_range(unsigned long start, unsigned long end)
+{
+ if (end - start > dcache_size)
+ tx39_blast_dcache();
+ else
+ protected_blast_dcache_range(start, end);
+
+ if (end - start > icache_size)
+ tx39_blast_icache();
+ else {
+ unsigned long flags, config;
+ /* disable icache (set ICE#) */
+ local_irq_save(flags);
+ config = read_c0_conf();
+ write_c0_conf(config & ~TX39_CONF_ICE);
+ TX39_STOP_STREAMING();
+ protected_blast_icache_range(start, end);
+ write_c0_conf(config);
+ local_irq_restore(flags);
+ }
+}
+
+static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
+{
+ unsigned long end;
+
+ if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
+ end = addr + size;
+ do {
+ tx39_blast_dcache_page(addr);
+ addr += PAGE_SIZE;
+ } while(addr != end);
+ } else if (size > dcache_size) {
+ tx39_blast_dcache();
+ } else {
+ blast_dcache_range(addr, addr + size);
+ }
+}
+
+static void tx39_dma_cache_inv(unsigned long addr, unsigned long size)
+{
+ unsigned long end;
+
+ if (((size | addr) & (PAGE_SIZE - 1)) == 0) {
+ end = addr + size;
+ do {
+ tx39_blast_dcache_page(addr);
+ addr += PAGE_SIZE;
+ } while(addr != end);
+ } else if (size > dcache_size) {
+ tx39_blast_dcache();
+ } else {
+ blast_inv_dcache_range(addr, addr + size);
+ }
+}
+
+static void tx39_flush_cache_sigtramp(unsigned long addr)
+{
+ unsigned long ic_lsize = current_cpu_data.icache.linesz;
+ unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+ unsigned long config;
+ unsigned long flags;
+
+ protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
+
+ /* disable icache (set ICE#) */
+ local_irq_save(flags);
+ config = read_c0_conf();
+ write_c0_conf(config & ~TX39_CONF_ICE);
+ TX39_STOP_STREAMING();
+ protected_flush_icache_line(addr & ~(ic_lsize - 1));
+ write_c0_conf(config);
+ local_irq_restore(flags);
+}
+
+static __init void tx39_probe_cache(void)
+{
+ unsigned long config;
+
+ config = read_c0_conf();
+
+ icache_size = 1 << (10 + ((config & TX39_CONF_ICS_MASK) >>
+ TX39_CONF_ICS_SHIFT));
+ dcache_size = 1 << (10 + ((config & TX39_CONF_DCS_MASK) >>
+ TX39_CONF_DCS_SHIFT));
+
+ current_cpu_data.icache.linesz = 16;
+ switch (current_cpu_type()) {
+ case CPU_TX3912:
+ current_cpu_data.icache.ways = 1;
+ current_cpu_data.dcache.ways = 1;
+ current_cpu_data.dcache.linesz = 4;
+ break;
+
+ case CPU_TX3927:
+ current_cpu_data.icache.ways = 2;
+ current_cpu_data.dcache.ways = 2;
+ current_cpu_data.dcache.linesz = 16;
+ break;
+
+ case CPU_TX3922:
+ default:
+ current_cpu_data.icache.ways = 1;
+ current_cpu_data.dcache.ways = 1;
+ current_cpu_data.dcache.linesz = 16;
+ break;
+ }
+}
+
+void __cpuinit tx39_cache_init(void)
+{
+ extern void build_clear_page(void);
+ extern void build_copy_page(void);
+ unsigned long config;
+
+ config = read_c0_conf();
+ config &= ~TX39_CONF_WBON;
+ write_c0_conf(config);
+
+ tx39_probe_cache();
+
+ switch (current_cpu_type()) {
+ case CPU_TX3912:
+ /* TX39/H core (writethru direct-map cache) */
+ __flush_cache_vmap = tx39__flush_cache_vmap;
+ __flush_cache_vunmap = tx39__flush_cache_vunmap;
+ flush_cache_all = tx39h_flush_icache_all;
+ __flush_cache_all = tx39h_flush_icache_all;
+ flush_cache_mm = (void *) tx39h_flush_icache_all;
+ flush_cache_range = (void *) tx39h_flush_icache_all;
+ flush_cache_page = (void *) tx39h_flush_icache_all;
+ flush_icache_range = (void *) tx39h_flush_icache_all;
+ local_flush_icache_range = (void *) tx39h_flush_icache_all;
+
+ flush_cache_sigtramp = (void *) tx39h_flush_icache_all;
+ local_flush_data_cache_page = (void *) tx39h_flush_icache_all;
+ flush_data_cache_page = (void *) tx39h_flush_icache_all;
+
+ _dma_cache_wback_inv = tx39h_dma_cache_wback_inv;
+
+ shm_align_mask = PAGE_SIZE - 1;
+
+ break;
+
+ case CPU_TX3922:
+ case CPU_TX3927:
+ default:
+ /* TX39/H2,H3 core (writeback 2way-set-associative cache) */
+ r3k_have_wired_reg = 1;
+ write_c0_wired(0); /* set 8 on reset... */
+ /* board-dependent init code may set WBON */
+
+ __flush_cache_vmap = tx39__flush_cache_vmap;
+ __flush_cache_vunmap = tx39__flush_cache_vunmap;
+
+ flush_cache_all = tx39_flush_cache_all;
+ __flush_cache_all = tx39___flush_cache_all;
+ flush_cache_mm = tx39_flush_cache_mm;
+ flush_cache_range = tx39_flush_cache_range;
+ flush_cache_page = tx39_flush_cache_page;
+ flush_icache_range = tx39_flush_icache_range;
+ local_flush_icache_range = tx39_flush_icache_range;
+
+ flush_cache_sigtramp = tx39_flush_cache_sigtramp;
+ local_flush_data_cache_page = local_tx39_flush_data_cache_page;
+ flush_data_cache_page = tx39_flush_data_cache_page;
+
+ _dma_cache_wback_inv = tx39_dma_cache_wback_inv;
+ _dma_cache_wback = tx39_dma_cache_wback_inv;
+ _dma_cache_inv = tx39_dma_cache_inv;
+
+ shm_align_mask = max_t(unsigned long,
+ (dcache_size / current_cpu_data.dcache.ways) - 1,
+ PAGE_SIZE - 1);
+
+ break;
+ }
+
+ current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways;
+ current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways;
+
+ current_cpu_data.icache.sets =
+ current_cpu_data.icache.waysize / current_cpu_data.icache.linesz;
+ current_cpu_data.dcache.sets =
+ current_cpu_data.dcache.waysize / current_cpu_data.dcache.linesz;
+
+ if (current_cpu_data.dcache.waysize > PAGE_SIZE)
+ current_cpu_data.dcache.flags |= MIPS_CACHE_ALIASES;
+
+ current_cpu_data.icache.waybit = 0;
+ current_cpu_data.dcache.waybit = 0;
+
+ printk("Primary instruction cache %ldkB, linesize %d bytes\n",
+ icache_size >> 10, current_cpu_data.icache.linesz);
+ printk("Primary data cache %ldkB, linesize %d bytes\n",
+ dcache_size >> 10, current_cpu_data.dcache.linesz);
+
+ build_clear_page();
+ build_copy_page();
+ tx39h_flush_icache_all();
+}
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
new file mode 100644
index 00000000..12af7390
--- /dev/null
+++ b/arch/mips/mm/cache.c
@@ -0,0 +1,222 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2003, 06, 07 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ */
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/mm.h>
+
+#include <asm/cacheflush.h>
+#include <asm/processor.h>
+#include <asm/cpu.h>
+#include <asm/cpu-features.h>
+
+/* Cache operations. */
+void (*flush_cache_all)(void);
+void (*__flush_cache_all)(void);
+void (*flush_cache_mm)(struct mm_struct *mm);
+void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end);
+void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
+ unsigned long pfn);
+void (*flush_icache_range)(unsigned long start, unsigned long end);
+void (*local_flush_icache_range)(unsigned long start, unsigned long end);
+
+void (*__flush_cache_vmap)(void);
+void (*__flush_cache_vunmap)(void);
+
+/* MIPS specific cache operations */
+void (*flush_cache_sigtramp)(unsigned long addr);
+void (*local_flush_data_cache_page)(void * addr);
+void (*flush_data_cache_page)(unsigned long addr);
+void (*flush_icache_all)(void);
+
+EXPORT_SYMBOL_GPL(local_flush_data_cache_page);
+EXPORT_SYMBOL(flush_data_cache_page);
+
+#ifdef CONFIG_DMA_NONCOHERENT
+
+/* DMA cache operations. */
+void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
+void (*_dma_cache_wback)(unsigned long start, unsigned long size);
+void (*_dma_cache_inv)(unsigned long start, unsigned long size);
+
+EXPORT_SYMBOL(_dma_cache_wback_inv);
+
+#endif /* CONFIG_DMA_NONCOHERENT */
+
+/*
+ * We could optimize the case where the cache argument is not BCACHE but
+ * that seems very atypical use ...
+ */
+SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,
+ unsigned int, cache)
+{
+ if (bytes == 0)
+ return 0;
+ if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes))
+ return -EFAULT;
+
+ flush_icache_range(addr, addr + bytes);
+
+ return 0;
+}
+
+void __flush_dcache_page(struct page *page)
+{
+ struct address_space *mapping = page_mapping(page);
+ unsigned long addr;
+
+ if (PageHighMem(page))
+ return;
+ if (mapping && !mapping_mapped(mapping)) {
+ SetPageDcacheDirty(page);
+ return;
+ }
+
+ /*
+ * We could delay the flush for the !page_mapping case too. But that
+ * case is for exec env/arg pages and those are %99 certainly going to
+ * get faulted into the tlb (and thus flushed) anyways.
+ */
+ addr = (unsigned long) page_address(page);
+ flush_data_cache_page(addr);
+}
+
+EXPORT_SYMBOL(__flush_dcache_page);
+
+void __flush_anon_page(struct page *page, unsigned long vmaddr)
+{
+ unsigned long addr = (unsigned long) page_address(page);
+
+ if (pages_do_alias(addr, vmaddr)) {
+ if (page_mapped(page) && !Page_dcache_dirty(page)) {
+ void *kaddr;
+
+ kaddr = kmap_coherent(page, vmaddr);
+ flush_data_cache_page((unsigned long)kaddr);
+ kunmap_coherent();
+ } else
+ flush_data_cache_page(addr);
+ }
+}
+
+EXPORT_SYMBOL(__flush_anon_page);
+
+void __update_cache(struct vm_area_struct *vma, unsigned long address,
+ pte_t pte)
+{
+ struct page *page;
+ unsigned long pfn, addr;
+ int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
+
+ pfn = pte_pfn(pte);
+ if (unlikely(!pfn_valid(pfn)))
+ return;
+ page = pfn_to_page(pfn);
+ if (page_mapping(page) && Page_dcache_dirty(page)) {
+ addr = (unsigned long) page_address(page);
+ if (exec || pages_do_alias(addr, address & PAGE_MASK))
+ flush_data_cache_page(addr);
+ ClearPageDcacheDirty(page);
+ }
+}
+
+unsigned long _page_cachable_default;
+EXPORT_SYMBOL(_page_cachable_default);
+
+static inline void setup_protection_map(void)
+{
+ if (kernel_uses_smartmips_rixi) {
+ protection_map[0] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+ protection_map[1] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+ protection_map[2] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+ protection_map[3] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+ protection_map[4] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
+ protection_map[5] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+ protection_map[6] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
+ protection_map[7] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+
+ protection_map[8] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
+ protection_map[9] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
+ protection_map[10] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE | _PAGE_NO_READ);
+ protection_map[11] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_WRITE);
+ protection_map[12] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_READ);
+ protection_map[13] = __pgprot(_page_cachable_default | _PAGE_PRESENT);
+ protection_map[14] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE | _PAGE_NO_READ);
+ protection_map[15] = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_WRITE);
+
+ } else {
+ protection_map[0] = PAGE_NONE;
+ protection_map[1] = PAGE_READONLY;
+ protection_map[2] = PAGE_COPY;
+ protection_map[3] = PAGE_COPY;
+ protection_map[4] = PAGE_READONLY;
+ protection_map[5] = PAGE_READONLY;
+ protection_map[6] = PAGE_COPY;
+ protection_map[7] = PAGE_COPY;
+ protection_map[8] = PAGE_NONE;
+ protection_map[9] = PAGE_READONLY;
+ protection_map[10] = PAGE_SHARED;
+ protection_map[11] = PAGE_SHARED;
+ protection_map[12] = PAGE_READONLY;
+ protection_map[13] = PAGE_READONLY;
+ protection_map[14] = PAGE_SHARED;
+ protection_map[15] = PAGE_SHARED;
+ }
+}
+
+void __cpuinit cpu_cache_init(void)
+{
+ if (cpu_has_3k_cache) {
+ extern void __weak r3k_cache_init(void);
+
+ r3k_cache_init();
+ }
+ if (cpu_has_6k_cache) {
+ extern void __weak r6k_cache_init(void);
+
+ r6k_cache_init();
+ }
+ if (cpu_has_4k_cache) {
+ extern void __weak r4k_cache_init(void);
+
+ r4k_cache_init();
+ }
+ if (cpu_has_8k_cache) {
+ extern void __weak r8k_cache_init(void);
+
+ r8k_cache_init();
+ }
+ if (cpu_has_tx39_cache) {
+ extern void __weak tx39_cache_init(void);
+
+ tx39_cache_init();
+ }
+
+ if (cpu_has_octeon_cache) {
+ extern void __weak octeon_cache_init(void);
+
+ octeon_cache_init();
+ }
+
+ setup_protection_map();
+}
+
+int __weak __uncached_access(struct file *file, unsigned long addr)
+{
+ if (file->f_flags & O_DSYNC)
+ return 1;
+
+ return addr >= __pa(high_memory);
+}
diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
new file mode 100644
index 00000000..3571090b
--- /dev/null
+++ b/arch/mips/mm/cerr-sb1.c
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2001,2002,2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/sched.h>
+#include <asm/mipsregs.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+
+#if !defined(CONFIG_SIBYTE_BUS_WATCHER) || defined(CONFIG_SIBYTE_BW_TRACE)
+#include <asm/io.h>
+#include <asm/sibyte/sb1250_scd.h>
+#endif
+
+/*
+ * We'd like to dump the L2_ECC_TAG register on errors, but errata make
+ * that unsafe... So for now we don't. (BCM1250/BCM112x erratum SOC-48.)
+ */
+#undef DUMP_L2_ECC_TAG_ON_ERROR
+
+/* SB1 definitions */
+
+/* XXX should come from config1 XXX */
+#define SB1_CACHE_INDEX_MASK 0x1fe0
+
+#define CP0_ERRCTL_RECOVERABLE (1 << 31)
+#define CP0_ERRCTL_DCACHE (1 << 30)
+#define CP0_ERRCTL_ICACHE (1 << 29)
+#define CP0_ERRCTL_MULTIBUS (1 << 23)
+#define CP0_ERRCTL_MC_TLB (1 << 15)
+#define CP0_ERRCTL_MC_TIMEOUT (1 << 14)
+
+#define CP0_CERRI_TAG_PARITY (1 << 29)
+#define CP0_CERRI_DATA_PARITY (1 << 28)
+#define CP0_CERRI_EXTERNAL (1 << 26)
+
+#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL))
+#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY)
+
+#define CP0_CERRD_MULTIPLE (1 << 31)
+#define CP0_CERRD_TAG_STATE (1 << 30)
+#define CP0_CERRD_TAG_ADDRESS (1 << 29)
+#define CP0_CERRD_DATA_SBE (1 << 28)
+#define CP0_CERRD_DATA_DBE (1 << 27)
+#define CP0_CERRD_EXTERNAL (1 << 26)
+#define CP0_CERRD_LOAD (1 << 25)
+#define CP0_CERRD_STORE (1 << 24)
+#define CP0_CERRD_FILLWB (1 << 23)
+#define CP0_CERRD_COHERENCY (1 << 22)
+#define CP0_CERRD_DUPTAG (1 << 21)
+
+#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL))
+#define CP0_CERRD_IDX_VALID(c) \
+ (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0)
+#define CP0_CERRD_CAUSES \
+ (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG)
+#define CP0_CERRD_TYPES \
+ (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL)
+#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE)
+
+static uint32_t extract_ic(unsigned short addr, int data);
+static uint32_t extract_dc(unsigned short addr, int data);
+
+static inline void breakout_errctl(unsigned int val)
+{
+ if (val & CP0_ERRCTL_RECOVERABLE)
+ printk(" recoverable");
+ if (val & CP0_ERRCTL_DCACHE)
+ printk(" dcache");
+ if (val & CP0_ERRCTL_ICACHE)
+ printk(" icache");
+ if (val & CP0_ERRCTL_MULTIBUS)
+ printk(" multiple-buserr");
+ printk("\n");
+}
+
+static inline void breakout_cerri(unsigned int val)
+{
+ if (val & CP0_CERRI_TAG_PARITY)
+ printk(" tag-parity");
+ if (val & CP0_CERRI_DATA_PARITY)
+ printk(" data-parity");
+ if (val & CP0_CERRI_EXTERNAL)
+ printk(" external");
+ printk("\n");
+}
+
+static inline void breakout_cerrd(unsigned int val)
+{
+ switch (val & CP0_CERRD_CAUSES) {
+ case CP0_CERRD_LOAD:
+ printk(" load,");
+ break;
+ case CP0_CERRD_STORE:
+ printk(" store,");
+ break;
+ case CP0_CERRD_FILLWB:
+ printk(" fill/wb,");
+ break;
+ case CP0_CERRD_COHERENCY:
+ printk(" coherency,");
+ break;
+ case CP0_CERRD_DUPTAG:
+ printk(" duptags,");
+ break;
+ default:
+ printk(" NO CAUSE,");
+ break;
+ }
+ if (!(val & CP0_CERRD_TYPES))
+ printk(" NO TYPE");
+ else {
+ if (val & CP0_CERRD_MULTIPLE)
+ printk(" multi-err");
+ if (val & CP0_CERRD_TAG_STATE)
+ printk(" tag-state");
+ if (val & CP0_CERRD_TAG_ADDRESS)
+ printk(" tag-address");
+ if (val & CP0_CERRD_DATA_SBE)
+ printk(" data-SBE");
+ if (val & CP0_CERRD_DATA_DBE)
+ printk(" data-DBE");
+ if (val & CP0_CERRD_EXTERNAL)
+ printk(" external");
+ }
+ printk("\n");
+}
+
+#ifndef CONFIG_SIBYTE_BUS_WATCHER
+
+static void check_bus_watcher(void)
+{
+ uint32_t status, l2_err, memio_err;
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ uint64_t l2_tag;
+#endif
+
+ /* Destructive read, clears register and interrupt */
+ status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+ /* Bit 31 is always on, but there's no #define for that */
+ if (status & ~(1UL << 31)) {
+ l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ l2_tag = in64(IOADDR(A_L2_ECC_TAG));
+#endif
+ memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+ printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
+ printk("\nLast recorded signature:\n");
+ printk("Request %02x from %d, answered by %d with Dcode %d\n",
+ (unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
+ (int)(G_SCD_BERR_TID(status) >> 6),
+ (int)G_SCD_BERR_RID(status),
+ (int)G_SCD_BERR_DCODE(status));
+#ifdef DUMP_L2_ECC_TAG_ON_ERROR
+ printk("Last L2 tag w/ bad ECC: %016llx\n", l2_tag);
+#endif
+ } else {
+ printk("Bus watcher indicates no error\n");
+ }
+}
+#else
+extern void check_bus_watcher(void);
+#endif
+
+asmlinkage void sb1_cache_error(void)
+{
+ uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+ unsigned long long cerr_dpa;
+
+#ifdef CONFIG_SIBYTE_BW_TRACE
+ /* Freeze the trace buffer now */
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ csr_out32(M_BCM1480_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
+#else
+ csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
+#endif
+ printk("Trace buffer frozen\n");
+#endif
+
+ printk("Cache error exception on CPU %x:\n",
+ (read_c0_prid() >> 25) & 0x7);
+
+ __asm__ __volatile__ (
+ " .set push\n\t"
+ " .set mips64\n\t"
+ " .set noat\n\t"
+ " mfc0 %0, $26\n\t"
+ " mfc0 %1, $27\n\t"
+ " mfc0 %2, $27, 1\n\t"
+ " dmfc0 $1, $27, 3\n\t"
+ " dsrl32 %3, $1, 0 \n\t"
+ " sll %4, $1, 0 \n\t"
+ " mfc0 %5, $30\n\t"
+ " .set pop"
+ : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d),
+ "=r" (dpahi), "=r" (dpalo), "=r" (eepc));
+
+ cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo;
+ printk(" c0_errorepc == %08x\n", eepc);
+ printk(" c0_errctl == %08x", errctl);
+ breakout_errctl(errctl);
+ if (errctl & CP0_ERRCTL_ICACHE) {
+ printk(" c0_cerr_i == %08x", cerr_i);
+ breakout_cerri(cerr_i);
+ if (CP0_CERRI_IDX_VALID(cerr_i)) {
+ /* Check index of EPC, allowing for delay slot */
+ if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) &&
+ ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4)))
+ printk(" cerr_i idx doesn't match eepc\n");
+ else {
+ res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK,
+ (cerr_i & CP0_CERRI_DATA) != 0);
+ if (!(res & cerr_i))
+ printk("...didn't see indicated icache problem\n");
+ }
+ }
+ }
+ if (errctl & CP0_ERRCTL_DCACHE) {
+ printk(" c0_cerr_d == %08x", cerr_d);
+ breakout_cerrd(cerr_d);
+ if (CP0_CERRD_DPA_VALID(cerr_d)) {
+ printk(" c0_cerr_dpa == %010llx\n", cerr_dpa);
+ if (!CP0_CERRD_IDX_VALID(cerr_d)) {
+ res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK,
+ (cerr_d & CP0_CERRD_DATA) != 0);
+ if (!(res & cerr_d))
+ printk("...didn't see indicated dcache problem\n");
+ } else {
+ if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK))
+ printk(" cerr_d idx doesn't match cerr_dpa\n");
+ else {
+ res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK,
+ (cerr_d & CP0_CERRD_DATA) != 0);
+ if (!(res & cerr_d))
+ printk("...didn't see indicated problem\n");
+ }
+ }
+ }
+ }
+
+ check_bus_watcher();
+
+ /*
+ * Calling panic() when a fatal cache error occurs scrambles the
+ * state of the system (and the cache), making it difficult to
+ * investigate after the fact. However, if you just stall the CPU,
+ * the other CPU may keep on running, which is typically very
+ * undesirable.
+ */
+#ifdef CONFIG_SB1_CERR_STALL
+ while (1)
+ ;
+#else
+ panic("unhandled cache error");
+#endif
+}
+
+
+/* Parity lookup table. */
+static const uint8_t parity[256] = {
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
+};
+
+/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
+static const uint64_t mask_72_64[8] = {
+ 0x0738C808099264FFULL,
+ 0x38C808099264FF07ULL,
+ 0xC808099264FF0738ULL,
+ 0x08099264FF0738C8ULL,
+ 0x099264FF0738C808ULL,
+ 0x9264FF0738C80809ULL,
+ 0x64FF0738C8080992ULL,
+ 0xFF0738C808099264ULL
+};
+
+/* Calculate the parity on a range of bits */
+static char range_parity(uint64_t dword, int max, int min)
+{
+ char parity = 0;
+ int i;
+ dword >>= min;
+ for (i=max-min; i>=0; i--) {
+ if (dword & 0x1)
+ parity = !parity;
+ dword >>= 1;
+ }
+ return parity;
+}
+
+/* Calculate the 4-bit even byte-parity for an instruction */
+static unsigned char inst_parity(uint32_t word)
+{
+ int i, j;
+ char parity = 0;
+ for (j=0; j<4; j++) {
+ char byte_parity = 0;
+ for (i=0; i<8; i++) {
+ if (word & 0x80000000)
+ byte_parity = !byte_parity;
+ word <<= 1;
+ }
+ parity <<= 1;
+ parity |= byte_parity;
+ }
+ return parity;
+}
+
+static uint32_t extract_ic(unsigned short addr, int data)
+{
+ unsigned short way;
+ int valid;
+ uint32_t taghi, taglolo, taglohi;
+ unsigned long long taglo, va;
+ uint64_t tlo_tmp;
+ uint8_t lru;
+ int res = 0;
+
+ printk("Icache index 0x%04x ", addr);
+ for (way = 0; way < 4; way++) {
+ /* Index-load-tag-I */
+ __asm__ __volatile__ (
+ " .set push \n\t"
+ " .set noreorder \n\t"
+ " .set mips64 \n\t"
+ " .set noat \n\t"
+ " cache 4, 0(%3) \n\t"
+ " mfc0 %0, $29 \n\t"
+ " dmfc0 $1, $28 \n\t"
+ " dsrl32 %1, $1, 0 \n\t"
+ " sll %2, $1, 0 \n\t"
+ " .set pop"
+ : "=r" (taghi), "=r" (taglohi), "=r" (taglolo)
+ : "r" ((way << 13) | addr));
+
+ taglo = ((unsigned long long)taglohi << 32) | taglolo;
+ if (way == 0) {
+ lru = (taghi >> 14) & 0xff;
+ printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
+ ((addr >> 5) & 0x3), /* bank */
+ ((addr >> 7) & 0x3f), /* index */
+ (lru & 0x3),
+ ((lru >> 2) & 0x3),
+ ((lru >> 4) & 0x3),
+ ((lru >> 6) & 0x3));
+ }
+ va = (taglo & 0xC0000FFFFFFFE000ULL) | addr;
+ if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
+ va |= 0x3FFFF00000000000ULL;
+ valid = ((taghi >> 29) & 1);
+ if (valid) {
+ tlo_tmp = taglo & 0xfff3ff;
+ if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {
+ printk(" ** bad parity in VTag0/G/ASID\n");
+ res |= CP0_CERRI_TAG_PARITY;
+ }
+ if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {
+ printk(" ** bad parity in R/VTag1\n");
+ res |= CP0_CERRI_TAG_PARITY;
+ }
+ }
+ if (valid ^ ((taghi >> 27) & 1)) {
+ printk(" ** bad parity for valid bit\n");
+ res |= CP0_CERRI_TAG_PARITY;
+ }
+ printk(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n",
+ way, va, valid, taghi, taglo);
+
+ if (data) {
+ uint32_t datahi, insta, instb;
+ uint8_t predecode;
+ int offset;
+
+ /* (hit all banks and ways) */
+ for (offset = 0; offset < 4; offset++) {
+ /* Index-load-data-I */
+ __asm__ __volatile__ (
+ " .set push\n\t"
+ " .set noreorder\n\t"
+ " .set mips64\n\t"
+ " .set noat\n\t"
+ " cache 6, 0(%3) \n\t"
+ " mfc0 %0, $29, 1\n\t"
+ " dmfc0 $1, $28, 1\n\t"
+ " dsrl32 %1, $1, 0 \n\t"
+ " sll %2, $1, 0 \n\t"
+ " .set pop \n"
+ : "=r" (datahi), "=r" (insta), "=r" (instb)
+ : "r" ((way << 13) | addr | (offset << 3)));
+ predecode = (datahi >> 8) & 0xff;
+ if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) {
+ printk(" ** bad parity in predecode\n");
+ res |= CP0_CERRI_DATA_PARITY;
+ }
+ /* XXXKW should/could check predecode bits themselves */
+ if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {
+ printk(" ** bad parity in instruction a\n");
+ res |= CP0_CERRI_DATA_PARITY;
+ }
+ if ((datahi & 0xf) ^ inst_parity(instb)) {
+ printk(" ** bad parity in instruction b\n");
+ res |= CP0_CERRI_DATA_PARITY;
+ }
+ printk(" %05X-%08X%08X", datahi, insta, instb);
+ }
+ printk("\n");
+ }
+ }
+ return res;
+}
+
+/* Compute the ECC for a data doubleword */
+static uint8_t dc_ecc(uint64_t dword)
+{
+ uint64_t t;
+ uint32_t w;
+ uint8_t p;
+ int i;
+
+ p = 0;
+ for (i = 7; i >= 0; i--)
+ {
+ p <<= 1;
+ t = dword & mask_72_64[i];
+ w = (uint32_t)(t >> 32);
+ p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
+ ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+ w = (uint32_t)(t & 0xFFFFFFFF);
+ p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
+ ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+ }
+ return p;
+}
+
+struct dc_state {
+ unsigned char val;
+ char *name;
+};
+
+static struct dc_state dc_states[] = {
+ { 0x00, "INVALID" },
+ { 0x0f, "COH-SHD" },
+ { 0x13, "NCO-E-C" },
+ { 0x19, "NCO-E-D" },
+ { 0x16, "COH-E-C" },
+ { 0x1c, "COH-E-D" },
+ { 0xff, "*ERROR*" }
+};
+
+#define DC_TAG_VALID(state) \
+ (((state) == 0x0) || ((state) == 0xf) || ((state) == 0x13) || \
+ ((state) == 0x19) || ((state) == 0x16) || ((state) == 0x1c))
+
+static char *dc_state_str(unsigned char state)
+{
+ struct dc_state *dsc = dc_states;
+ while (dsc->val != 0xff) {
+ if (dsc->val == state)
+ break;
+ dsc++;
+ }
+ return dsc->name;
+}
+
+static uint32_t extract_dc(unsigned short addr, int data)
+{
+ int valid, way;
+ unsigned char state;
+ uint32_t taghi, taglolo, taglohi;
+ unsigned long long taglo, pa;
+ uint8_t ecc, lru;
+ int res = 0;
+
+ printk("Dcache index 0x%04x ", addr);
+ for (way = 0; way < 4; way++) {
+ __asm__ __volatile__ (
+ " .set push\n\t"
+ " .set noreorder\n\t"
+ " .set mips64\n\t"
+ " .set noat\n\t"
+ " cache 5, 0(%3)\n\t" /* Index-load-tag-D */
+ " mfc0 %0, $29, 2\n\t"
+ " dmfc0 $1, $28, 2\n\t"
+ " dsrl32 %1, $1, 0\n\t"
+ " sll %2, $1, 0\n\t"
+ " .set pop"
+ : "=r" (taghi), "=r" (taglohi), "=r" (taglolo)
+ : "r" ((way << 13) | addr));
+
+ taglo = ((unsigned long long)taglohi << 32) | taglolo;
+ pa = (taglo & 0xFFFFFFE000ULL) | addr;
+ if (way == 0) {
+ lru = (taghi >> 14) & 0xff;
+ printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
+ ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */
+ ((addr >> 6) & 0x3f), /* index */
+ (lru & 0x3),
+ ((lru >> 2) & 0x3),
+ ((lru >> 4) & 0x3),
+ ((lru >> 6) & 0x3));
+ }
+ state = (taghi >> 25) & 0x1f;
+ valid = DC_TAG_VALID(state);
+ printk(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n",
+ way, pa, dc_state_str(state), state, taghi, taglo);
+ if (valid) {
+ if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {
+ printk(" ** bad parity in PTag1\n");
+ res |= CP0_CERRD_TAG_ADDRESS;
+ }
+ if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {
+ printk(" ** bad parity in PTag0\n");
+ res |= CP0_CERRD_TAG_ADDRESS;
+ }
+ } else {
+ res |= CP0_CERRD_TAG_STATE;
+ }
+
+ if (data) {
+ uint32_t datalohi, datalolo, datahi;
+ unsigned long long datalo;
+ int offset;
+ char bad_ecc = 0;
+
+ for (offset = 0; offset < 4; offset++) {
+ /* Index-load-data-D */
+ __asm__ __volatile__ (
+ " .set push\n\t"
+ " .set noreorder\n\t"
+ " .set mips64\n\t"
+ " .set noat\n\t"
+ " cache 7, 0(%3)\n\t" /* Index-load-data-D */
+ " mfc0 %0, $29, 3\n\t"
+ " dmfc0 $1, $28, 3\n\t"
+ " dsrl32 %1, $1, 0 \n\t"
+ " sll %2, $1, 0 \n\t"
+ " .set pop"
+ : "=r" (datahi), "=r" (datalohi), "=r" (datalolo)
+ : "r" ((way << 13) | addr | (offset << 3)));
+ datalo = ((unsigned long long)datalohi << 32) | datalolo;
+ ecc = dc_ecc(datalo);
+ if (ecc != datahi) {
+ int bits;
+ bad_ecc |= 1 << (3-offset);
+ ecc ^= datahi;
+ bits = hweight8(ecc);
+ res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
+ }
+ printk(" %02X-%016llX", datahi, datalo);
+ }
+ printk("\n");
+ if (bad_ecc)
+ printk(" dwords w/ bad ECC: %d %d %d %d\n",
+ !!(bad_ecc & 8), !!(bad_ecc & 4),
+ !!(bad_ecc & 2), !!(bad_ecc & 1));
+ }
+ }
+ return res;
+}
diff --git a/arch/mips/mm/cex-gen.S b/arch/mips/mm/cex-gen.S
new file mode 100644
index 00000000..e743622f
--- /dev/null
+++ b/arch/mips/mm/cex-gen.S
@@ -0,0 +1,42 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 - 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Cache error handler
+ */
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+/*
+ * Game over. Go to the button. Press gently. Swear where allowed by
+ * legislation.
+ */
+ LEAF(except_vec2_generic)
+ .set noreorder
+ .set noat
+ .set mips0
+ /*
+ * This is a very bad place to be. Our cache error
+ * detection has triggered. If we have write-back data
+ * in the cache, we may not be able to recover. As a
+ * first-order desperate measure, turn off KSEG0 cacheing.
+ */
+ mfc0 k0,CP0_CONFIG
+ li k1,~CONF_CM_CMASK
+ and k0,k0,k1
+ ori k0,k0,CONF_CM_UNCACHED
+ mtc0 k0,CP0_CONFIG
+ /* Give it a few cycles to sink in... */
+ nop
+ nop
+ nop
+
+ j cache_parity_error
+ nop
+ END(except_vec2_generic)
diff --git a/arch/mips/mm/cex-oct.S b/arch/mips/mm/cex-oct.S
new file mode 100644
index 00000000..3db8553f
--- /dev/null
+++ b/arch/mips/mm/cex-oct.S
@@ -0,0 +1,70 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Cavium Networks
+ * Cache error handler
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+/*
+ * Handle cache error. Indicate to the second level handler whether
+ * the exception is recoverable.
+ */
+ LEAF(except_vec2_octeon)
+
+ .set push
+ .set mips64r2
+ .set noreorder
+ .set noat
+
+
+ /* due to an errata we need to read the COP0 CacheErr (Dcache)
+ * before any cache/DRAM access */
+
+ rdhwr k0, $0 /* get core_id */
+ PTR_LA k1, cache_err_dcache
+ sll k0, k0, 3
+ PTR_ADDU k1, k0, k1 /* k1 = &cache_err_dcache[core_id] */
+
+ dmfc0 k0, CP0_CACHEERR, 1
+ sd k0, (k1)
+ dmtc0 $0, CP0_CACHEERR, 1
+
+ /* check whether this is a nested exception */
+ mfc0 k1, CP0_STATUS
+ andi k1, k1, ST0_EXL
+ beqz k1, 1f
+ nop
+ j cache_parity_error_octeon_non_recoverable
+ nop
+
+ /* exception is recoverable */
+1: j handle_cache_err
+ nop
+
+ .set pop
+ END(except_vec2_octeon)
+
+ /* We need to jump to handle_cache_err so that the previous handler
+ * can fit within 0x80 bytes. We also move from 0xFFFFFFFFAXXXXXXX
+ * space (uncached) to the 0xFFFFFFFF8XXXXXXX space (cached). */
+ LEAF(handle_cache_err)
+ .set push
+ .set noreorder
+ .set noat
+
+ SAVE_ALL
+ KMODE
+ jal cache_parity_error_octeon_recoverable
+ nop
+ j ret_from_exception
+ nop
+
+ .set pop
+ END(handle_cache_err)
diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S
new file mode 100644
index 00000000..89c412bc
--- /dev/null
+++ b/arch/mips/mm/cex-sb1.S
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2001,2002,2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/cacheops.h>
+#include <asm/sibyte/board.h>
+
+#define C0_ERRCTL $26 /* CP0: Error info */
+#define C0_CERR_I $27 /* CP0: Icache error */
+#define C0_CERR_D $27,1 /* CP0: Dcache error */
+
+ /*
+ * Based on SiByte sample software cache-err/cerr.S
+ * CVS revision 1.8. Only the 'unrecoverable' case
+ * is changed.
+ */
+
+ .set mips64
+ .set noreorder
+ .set noat
+
+ /*
+ * sb1_cerr_vec: code to be copied to the Cache Error
+ * Exception vector. The code must be pushed out to memory
+ * (either by copying to Kseg0 and Kseg1 both, or by flushing
+ * the L1 and L2) since it is fetched as 0xa0000100.
+ *
+ * NOTE: Be sure this handler is at most 28 instructions long
+ * since the final 16 bytes of the exception vector memory
+ * (0x170-0x17f) are used to preserve k0, k1, and ra.
+ */
+
+ __CPUINIT
+
+LEAF(except_vec2_sb1)
+ /*
+ * If this error is recoverable, we need to exit the handler
+ * without having dirtied any registers. To do this,
+ * save/restore k0 and k1 from low memory (Useg is direct
+ * mapped while ERL=1). Note that we can't save to a
+ * CPU-specific location without ruining a register in the
+ * process. This means we are vulnerable to data corruption
+ * whenever the handler is reentered by a second CPU.
+ */
+ sd k0,0x170($0)
+ sd k1,0x178($0)
+
+#ifdef CONFIG_SB1_CEX_ALWAYS_FATAL
+ j handle_vec2_sb1
+ nop
+#else
+ /*
+ * M_ERRCTL_RECOVERABLE is bit 31, which makes it easy to tell
+ * if we can fast-path out of here for a h/w-recovered error.
+ */
+ mfc0 k1,C0_ERRCTL
+ bgtz k1,attempt_recovery
+ sll k0,k1,1
+
+recovered_dcache:
+ /*
+ * Unlock CacheErr-D (which in turn unlocks CacheErr-DPA).
+ * Ought to log the occurrence of this recovered dcache error.
+ */
+ b recovered
+ mtc0 $0,C0_CERR_D
+
+attempt_recovery:
+ /*
+ * k0 has C0_ERRCTL << 1, which puts 'DC' at bit 31. Any
+ * Dcache errors we can recover from will take more extensive
+ * processing. For now, they are considered "unrecoverable".
+ * Note that 'DC' becoming set (outside of ERL mode) will
+ * cause 'IC' to clear; so if there's an Icache error, we'll
+ * only find out about it if we recover from this error and
+ * continue executing.
+ */
+ bltz k0,unrecoverable
+ sll k0,1
+
+ /*
+ * k0 has C0_ERRCTL << 2, which puts 'IC' at bit 31. If an
+ * Icache error isn't indicated, I'm not sure why we got here.
+ * Consider that case "unrecoverable" for now.
+ */
+ bgez k0,unrecoverable
+
+attempt_icache_recovery:
+ /*
+ * External icache errors are due to uncorrectable ECC errors
+ * in the L2 cache or Memory Controller and cannot be
+ * recovered here.
+ */
+ mfc0 k0,C0_CERR_I /* delay slot */
+ li k1,1 << 26 /* ICACHE_EXTERNAL */
+ and k1,k0
+ bnez k1,unrecoverable
+ andi k0,0x1fe0
+
+ /*
+ * Since the error is internal, the 'IDX' field from
+ * CacheErr-I is valid and we can just invalidate all blocks
+ * in that set.
+ */
+ cache Index_Invalidate_I,(0<<13)(k0)
+ cache Index_Invalidate_I,(1<<13)(k0)
+ cache Index_Invalidate_I,(2<<13)(k0)
+ cache Index_Invalidate_I,(3<<13)(k0)
+
+ /* Ought to log this recovered icache error */
+
+recovered:
+ /* Restore the saved registers */
+ ld k0,0x170($0)
+ ld k1,0x178($0)
+ eret
+
+unrecoverable:
+ /* Unrecoverable Icache or Dcache error; log it and/or fail */
+ j handle_vec2_sb1
+ nop
+#endif
+
+END(except_vec2_sb1)
+
+ __FINIT
+
+ LEAF(handle_vec2_sb1)
+ mfc0 k0,CP0_CONFIG
+ li k1,~CONF_CM_CMASK
+ and k0,k0,k1
+ ori k0,k0,CONF_CM_UNCACHED
+ mtc0 k0,CP0_CONFIG
+
+ SSNOP
+ SSNOP
+ SSNOP
+ SSNOP
+ bnezl $0, 1f
+1:
+ mfc0 k0, CP0_STATUS
+ sll k0, k0, 3 # check CU0 (kernel?)
+ bltz k0, 2f
+ nop
+
+ /* Get a valid Kseg0 stack pointer. Any task's stack pointer
+ * will do, although if we ever want to resume execution we
+ * better not have corrupted any state. */
+ get_saved_sp
+ move sp, k1
+
+2:
+ j sb1_cache_error
+ nop
+
+ END(handle_vec2_sb1)
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
new file mode 100644
index 00000000..21ea14ef
--- /dev/null
+++ b/arch/mips/mm/dma-default.c
@@ -0,0 +1,329 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001, 06 Ralf Baechle <ralf@linux-mips.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/string.h>
+#include <linux/gfp.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+
+#include <dma-coherence.h>
+
+static inline unsigned long dma_addr_to_virt(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ unsigned long addr = plat_dma_addr_to_phys(dev, dma_addr);
+
+ return (unsigned long)phys_to_virt(addr);
+}
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+static inline int cpu_is_noncoherent_r10000(struct device *dev)
+{
+ return !plat_device_is_coherent(dev) &&
+ (current_cpu_type() == CPU_R10000 ||
+ current_cpu_type() == CPU_R12000);
+}
+
+static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp)
+{
+ gfp_t dma_flag;
+
+ /* ignore region specifiers */
+ gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+
+#ifdef CONFIG_ISA
+ if (dev == NULL)
+ dma_flag = __GFP_DMA;
+ else
+#endif
+#if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA)
+ if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
+ dma_flag = __GFP_DMA;
+ else if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA32;
+ else
+#endif
+#if defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_ZONE_DMA)
+ if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA32;
+ else
+#endif
+#if defined(CONFIG_ZONE_DMA) && !defined(CONFIG_ZONE_DMA32)
+ if (dev->coherent_dma_mask < DMA_BIT_MASK(64))
+ dma_flag = __GFP_DMA;
+ else
+#endif
+ dma_flag = 0;
+
+ /* Don't invoke OOM killer */
+ gfp |= __GFP_NORETRY;
+
+ return gfp | dma_flag;
+}
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+ dma_addr_t * dma_handle, gfp_t gfp)
+{
+ void *ret;
+
+ gfp = massage_gfp_flags(dev, gfp);
+
+ ret = (void *) __get_free_pages(gfp, get_order(size));
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = plat_map_dma_mem(dev, ret, size);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t * dma_handle, gfp_t gfp)
+{
+ void *ret;
+
+ if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
+ return ret;
+
+ gfp = massage_gfp_flags(dev, gfp);
+
+ ret = (void *) __get_free_pages(gfp, get_order(size));
+
+ if (ret) {
+ memset(ret, 0, size);
+ *dma_handle = plat_map_dma_mem(dev, ret, size);
+
+ if (!plat_device_is_coherent(dev)) {
+ dma_cache_wback_inv((unsigned long) ret, size);
+ ret = UNCAC_ADDR(ret);
+ }
+ }
+
+ return ret;
+}
+
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
+{
+ plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
+ free_pages((unsigned long) vaddr, get_order(size));
+}
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
+{
+ unsigned long addr = (unsigned long) vaddr;
+ int order = get_order(size);
+
+ if (dma_release_from_coherent(dev, order, vaddr))
+ return;
+
+ plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
+
+ if (!plat_device_is_coherent(dev))
+ addr = CAC_ADDR(addr);
+
+ free_pages(addr, get_order(size));
+}
+
+static inline void __dma_sync(unsigned long addr, size_t size,
+ enum dma_data_direction direction)
+{
+ switch (direction) {
+ case DMA_TO_DEVICE:
+ dma_cache_wback(addr, size);
+ break;
+
+ case DMA_FROM_DEVICE:
+ dma_cache_inv(addr, size);
+ break;
+
+ case DMA_BIDIRECTIONAL:
+ dma_cache_wback_inv(addr, size);
+ break;
+
+ default:
+ BUG();
+ }
+}
+
+static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+ if (cpu_is_noncoherent_r10000(dev))
+ __dma_sync(dma_addr_to_virt(dev, dma_addr), size,
+ direction);
+
+ plat_unmap_dma_mem(dev, dma_addr, size, direction);
+}
+
+static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
+{
+ int i;
+
+ for (i = 0; i < nents; i++, sg++) {
+ unsigned long addr;
+
+ addr = (unsigned long) sg_virt(sg);
+ if (!plat_device_is_coherent(dev) && addr)
+ __dma_sync(addr, sg->length, direction);
+ sg->dma_address = plat_map_dma_mem(dev,
+ (void *)addr, sg->length);
+ }
+
+ return nents;
+}
+
+static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ unsigned long addr;
+
+ addr = (unsigned long) page_address(page) + offset;
+
+ if (!plat_device_is_coherent(dev))
+ __dma_sync(addr, size, direction);
+
+ return plat_map_dma_mem(dev, (void *)addr, size);
+}
+
+static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ unsigned long addr;
+ int i;
+
+ for (i = 0; i < nhwentries; i++, sg++) {
+ if (!plat_device_is_coherent(dev) &&
+ direction != DMA_TO_DEVICE) {
+ addr = (unsigned long) sg_virt(sg);
+ if (addr)
+ __dma_sync(addr, sg->length, direction);
+ }
+ plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction);
+ }
+}
+
+static void mips_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+{
+ if (cpu_is_noncoherent_r10000(dev)) {
+ unsigned long addr;
+
+ addr = dma_addr_to_virt(dev, dma_handle);
+ __dma_sync(addr, size, direction);
+ }
+}
+
+static void mips_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
+{
+ plat_extra_sync_for_device(dev);
+ if (!plat_device_is_coherent(dev)) {
+ unsigned long addr;
+
+ addr = dma_addr_to_virt(dev, dma_handle);
+ __dma_sync(addr, size, direction);
+ }
+}
+
+static void mips_dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sg, int nelems, enum dma_data_direction direction)
+{
+ int i;
+
+ /* Make sure that gcc doesn't leave the empty loop body. */
+ for (i = 0; i < nelems; i++, sg++) {
+ if (cpu_is_noncoherent_r10000(dev))
+ __dma_sync((unsigned long)page_address(sg_page(sg)),
+ sg->length, direction);
+ }
+}
+
+static void mips_dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sg, int nelems, enum dma_data_direction direction)
+{
+ int i;
+
+ /* Make sure that gcc doesn't leave the empty loop body. */
+ for (i = 0; i < nelems; i++, sg++) {
+ if (!plat_device_is_coherent(dev))
+ __dma_sync((unsigned long)page_address(sg_page(sg)),
+ sg->length, direction);
+ }
+}
+
+int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return plat_dma_mapping_error(dev, dma_addr);
+}
+
+int mips_dma_supported(struct device *dev, u64 mask)
+{
+ return plat_dma_supported(dev, mask);
+}
+
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+
+ plat_extra_sync_for_device(dev);
+ if (!plat_device_is_coherent(dev))
+ __dma_sync((unsigned long)vaddr, size, direction);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
+
+static struct dma_map_ops mips_default_dma_map_ops = {
+ .alloc_coherent = mips_dma_alloc_coherent,
+ .free_coherent = mips_dma_free_coherent,
+ .map_page = mips_dma_map_page,
+ .unmap_page = mips_dma_unmap_page,
+ .map_sg = mips_dma_map_sg,
+ .unmap_sg = mips_dma_unmap_sg,
+ .sync_single_for_cpu = mips_dma_sync_single_for_cpu,
+ .sync_single_for_device = mips_dma_sync_single_for_device,
+ .sync_sg_for_cpu = mips_dma_sync_sg_for_cpu,
+ .sync_sg_for_device = mips_dma_sync_sg_for_device,
+ .mapping_error = mips_dma_mapping_error,
+ .dma_supported = mips_dma_supported
+};
+
+struct dma_map_ops *mips_dma_map_ops = &mips_default_dma_map_ops;
+EXPORT_SYMBOL(mips_dma_map_ops);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+
+static int __init mips_dma_init(void)
+{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+ return 0;
+}
+fs_initcall(mips_dma_init);
diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c
new file mode 100644
index 00000000..9d25d2ba
--- /dev/null
+++ b/arch/mips/mm/extable.c
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 99, 2001 - 2004 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/branch.h>
+#include <asm/uaccess.h>
+
+int fixup_exception(struct pt_regs *regs)
+{
+ const struct exception_table_entry *fixup;
+
+ fixup = search_exception_tables(exception_epc(regs));
+ if (fixup) {
+ regs->cp0_epc = fixup->nextinsn;
+
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
new file mode 100644
index 00000000..137ee76a
--- /dev/null
+++ b/arch/mips/mm/fault.c
@@ -0,0 +1,294 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 - 2000 by Ralf Baechle
+ */
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/perf_event.h>
+
+#include <asm/branch.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+#include <asm/highmem.h> /* For VMALLOC_END */
+#include <linux/kdebug.h>
+
+/*
+ * This routine handles page faults. It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long write,
+ unsigned long address)
+{
+ struct vm_area_struct * vma = NULL;
+ struct task_struct *tsk = current;
+ struct mm_struct *mm = tsk->mm;
+ const int field = sizeof(unsigned long) * 2;
+ siginfo_t info;
+ int fault;
+
+#if 0
+ printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
+ current->comm, current->pid, field, address, write,
+ field, regs->cp0_epc);
+#endif
+
+#ifdef CONFIG_KPROBES
+ /*
+ * This is to notify the fault handler of the kprobes. The
+ * exception code is redundant as it is also carried in REGS,
+ * but we pass it anyhow.
+ */
+ if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1,
+ (regs->cp0_cause >> 2) & 0x1f, SIGSEGV) == NOTIFY_STOP)
+ return;
+#endif
+
+ info.si_code = SEGV_MAPERR;
+
+ /*
+ * We fault-in kernel-space virtual memory on-demand. The
+ * 'reference' page table is init_mm.pgd.
+ *
+ * NOTE! We MUST NOT take any locks for this case. We may
+ * be in an interrupt or a critical region, and should
+ * only copy the information from the master page table,
+ * nothing more.
+ */
+#ifdef CONFIG_64BIT
+# define VMALLOC_FAULT_TARGET no_context
+#else
+# define VMALLOC_FAULT_TARGET vmalloc_fault
+#endif
+
+ if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
+ goto VMALLOC_FAULT_TARGET;
+#ifdef MODULE_START
+ if (unlikely(address >= MODULE_START && address < MODULE_END))
+ goto VMALLOC_FAULT_TARGET;
+#endif
+
+ /*
+ * If we're in an interrupt or have no user
+ * context, we must not take the fault..
+ */
+ if (in_atomic() || !mm)
+ goto bad_area_nosemaphore;
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, address);
+ if (!vma)
+ goto bad_area;
+ if (vma->vm_start <= address)
+ goto good_area;
+ if (!(vma->vm_flags & VM_GROWSDOWN))
+ goto bad_area;
+ if (expand_stack(vma, address))
+ goto bad_area;
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+good_area:
+ info.si_code = SEGV_ACCERR;
+
+ if (write) {
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;
+ } else {
+ if (kernel_uses_smartmips_rixi) {
+ if (address == regs->cp0_epc && !(vma->vm_flags & VM_EXEC)) {
+#if 0
+ pr_notice("Cpu%d[%s:%d:%0*lx:%ld:%0*lx] XI violation\n",
+ raw_smp_processor_id(),
+ current->comm, current->pid,
+ field, address, write,
+ field, regs->cp0_epc);
+#endif
+ goto bad_area;
+ }
+ if (!(vma->vm_flags & VM_READ)) {
+#if 0
+ pr_notice("Cpu%d[%s:%d:%0*lx:%ld:%0*lx] RI violation\n",
+ raw_smp_processor_id(),
+ current->comm, current->pid,
+ field, address, write,
+ field, regs->cp0_epc);
+#endif
+ goto bad_area;
+ }
+ } else {
+ if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
+ goto bad_area;
+ }
+ }
+
+ /*
+ * If for any reason at all we couldn't handle the fault,
+ * make sure we exit gracefully rather than endlessly redo
+ * the fault.
+ */
+ fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+ if (unlikely(fault & VM_FAULT_ERROR)) {
+ if (fault & VM_FAULT_OOM)
+ goto out_of_memory;
+ else if (fault & VM_FAULT_SIGBUS)
+ goto do_sigbus;
+ BUG();
+ }
+ if (fault & VM_FAULT_MAJOR) {
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
+ 1, 0, regs, address);
+ tsk->maj_flt++;
+ } else {
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+ 1, 0, regs, address);
+ tsk->min_flt++;
+ }
+
+ up_read(&mm->mmap_sem);
+ return;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+bad_area:
+ up_read(&mm->mmap_sem);
+
+bad_area_nosemaphore:
+ /* User mode accesses just cause a SIGSEGV */
+ if (user_mode(regs)) {
+ tsk->thread.cp0_badvaddr = address;
+ tsk->thread.error_code = write;
+#if 0
+ printk("do_page_fault() #2: sending SIGSEGV to %s for "
+ "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n",
+ tsk->comm,
+ write ? "write access to" : "read access from",
+ field, address,
+ field, (unsigned long) regs->cp0_epc,
+ field, (unsigned long) regs->regs[31]);
+#endif
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ /* info.si_code has been set above */
+ info.si_addr = (void __user *) address;
+ force_sig_info(SIGSEGV, &info, tsk);
+ return;
+ }
+
+no_context:
+ /* Are we prepared to handle this kernel fault? */
+ if (fixup_exception(regs)) {
+ current->thread.cp0_baduaddr = address;
+ return;
+ }
+
+ /*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+ bust_spinlocks(1);
+
+ printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
+ "virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
+ raw_smp_processor_id(), field, address, field, regs->cp0_epc,
+ field, regs->regs[31]);
+ die("Oops", regs);
+
+out_of_memory:
+ /*
+ * We ran out of memory, call the OOM killer, and return the userspace
+ * (which will retry the fault, or kill us if we got oom-killed).
+ */
+ up_read(&mm->mmap_sem);
+ pagefault_out_of_memory();
+ return;
+
+do_sigbus:
+ up_read(&mm->mmap_sem);
+
+ /* Kernel mode? Handle exceptions or die */
+ if (!user_mode(regs))
+ goto no_context;
+ else
+ /*
+ * Send a sigbus, regardless of whether we were in kernel
+ * or user mode.
+ */
+#if 0
+ printk("do_page_fault() #3: sending SIGBUS to %s for "
+ "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n",
+ tsk->comm,
+ write ? "write access to" : "read access from",
+ field, address,
+ field, (unsigned long) regs->cp0_epc,
+ field, (unsigned long) regs->regs[31]);
+#endif
+ tsk->thread.cp0_badvaddr = address;
+ info.si_signo = SIGBUS;
+ info.si_errno = 0;
+ info.si_code = BUS_ADRERR;
+ info.si_addr = (void __user *) address;
+ force_sig_info(SIGBUS, &info, tsk);
+
+ return;
+#ifndef CONFIG_64BIT
+vmalloc_fault:
+ {
+ /*
+ * Synchronize this task's top level page-table
+ * with the 'reference' page table.
+ *
+ * Do _not_ use "tsk" here. We might be inside
+ * an interrupt in the middle of a task switch..
+ */
+ int offset = __pgd_offset(address);
+ pgd_t *pgd, *pgd_k;
+ pud_t *pud, *pud_k;
+ pmd_t *pmd, *pmd_k;
+ pte_t *pte_k;
+
+ pgd = (pgd_t *) pgd_current[raw_smp_processor_id()] + offset;
+ pgd_k = init_mm.pgd + offset;
+
+ if (!pgd_present(*pgd_k))
+ goto no_context;
+ set_pgd(pgd, *pgd_k);
+
+ pud = pud_offset(pgd, address);
+ pud_k = pud_offset(pgd_k, address);
+ if (!pud_present(*pud_k))
+ goto no_context;
+
+ pmd = pmd_offset(pud, address);
+ pmd_k = pmd_offset(pud_k, address);
+ if (!pmd_present(*pmd_k))
+ goto no_context;
+ set_pmd(pmd, *pmd_k);
+
+ pte_k = pte_offset_kernel(pmd_k, address);
+ if (!pte_present(*pte_k))
+ goto no_context;
+ return;
+ }
+#endif
+}
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
new file mode 100644
index 00000000..3634c7ea
--- /dev/null
+++ b/arch/mips/mm/highmem.c
@@ -0,0 +1,137 @@
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <asm/fixmap.h>
+#include <asm/tlbflush.h>
+
+static pte_t *kmap_pte;
+
+unsigned long highstart_pfn, highend_pfn;
+
+void *kmap(struct page *page)
+{
+ void *addr;
+
+ might_sleep();
+ if (!PageHighMem(page))
+ return page_address(page);
+ addr = kmap_high(page);
+ flush_tlb_one((unsigned long)addr);
+
+ return addr;
+}
+EXPORT_SYMBOL(kmap);
+
+void kunmap(struct page *page)
+{
+ BUG_ON(in_interrupt());
+ if (!PageHighMem(page))
+ return;
+ kunmap_high(page);
+}
+EXPORT_SYMBOL(kunmap);
+
+/*
+ * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
+ * no global lock is needed and because the kmap code must perform a global TLB
+ * invalidation when the kmap pool wraps.
+ *
+ * However when holding an atomic kmap is is not legal to sleep, so atomic
+ * kmaps are appropriate for short, tight code paths only.
+ */
+
+void *__kmap_atomic(struct page *page)
+{
+ unsigned long vaddr;
+ int idx, type;
+
+ /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+ pagefault_disable();
+ if (!PageHighMem(page))
+ return page_address(page);
+
+ type = kmap_atomic_idx_push();
+ idx = type + KM_TYPE_NR*smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(!pte_none(*(kmap_pte - idx)));
+#endif
+ set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
+ local_flush_tlb_one((unsigned long)vaddr);
+
+ return (void*) vaddr;
+}
+EXPORT_SYMBOL(__kmap_atomic);
+
+void __kunmap_atomic(void *kvaddr)
+{
+ unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+ int type;
+
+ if (vaddr < FIXADDR_START) { // FIXME
+ pagefault_enable();
+ return;
+ }
+
+ type = kmap_atomic_idx();
+#ifdef CONFIG_DEBUG_HIGHMEM
+ {
+ int idx = type + KM_TYPE_NR * smp_processor_id();
+
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+
+ /*
+ * force other mappings to Oops if they'll try to access
+ * this pte without first remap it
+ */
+ pte_clear(&init_mm, vaddr, kmap_pte-idx);
+ local_flush_tlb_one(vaddr);
+ }
+#endif
+ kmap_atomic_idx_pop();
+ pagefault_enable();
+}
+EXPORT_SYMBOL(__kunmap_atomic);
+
+/*
+ * This is the same as kmap_atomic() but can map memory that doesn't
+ * have a struct page associated with it.
+ */
+void *kmap_atomic_pfn(unsigned long pfn)
+{
+ unsigned long vaddr;
+ int idx, type;
+
+ pagefault_disable();
+
+ type = kmap_atomic_idx_push();
+ idx = type + KM_TYPE_NR*smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
+ flush_tlb_one(vaddr);
+
+ return (void*) vaddr;
+}
+
+struct page *kmap_atomic_to_page(void *ptr)
+{
+ unsigned long idx, vaddr = (unsigned long)ptr;
+ pte_t *pte;
+
+ if (vaddr < FIXADDR_START)
+ return virt_to_page(ptr);
+
+ idx = virt_to_fix(vaddr);
+ pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
+ return pte_page(*pte);
+}
+
+void __init kmap_init(void)
+{
+ unsigned long kmap_vstart;
+
+ /* cache the first kmap pte */
+ kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+ kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+}
diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c
new file mode 100644
index 00000000..a7fee0df
--- /dev/null
+++ b/arch/mips/mm/hugetlbpage.c
@@ -0,0 +1,98 @@
+/*
+ * MIPS Huge TLB Page Support for Kernel.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
+ * Copyright 2005, Embedded Alley Solutions, Inc.
+ * Matt Porter <mporter@embeddedalley.com>
+ * Copyright (C) 2008, 2009 Cavium Networks, Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr,
+ unsigned long sz)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pte_t *pte = NULL;
+
+ pgd = pgd_offset(mm, addr);
+ pud = pud_alloc(mm, pgd, addr);
+ if (pud)
+ pte = (pte_t *)pmd_alloc(mm, pud, addr);
+
+ return pte;
+}
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd = NULL;
+
+ pgd = pgd_offset(mm, addr);
+ if (pgd_present(*pgd)) {
+ pud = pud_offset(pgd, addr);
+ if (pud_present(*pud))
+ pmd = pmd_offset(pud, addr);
+ }
+ return (pte_t *) pmd;
+}
+
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+ return 0;
+}
+
+/*
+ * This function checks for proper alignment of input addr and len parameters.
+ */
+int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
+{
+ if (len & ~HPAGE_MASK)
+ return -EINVAL;
+ if (addr & ~HPAGE_MASK)
+ return -EINVAL;
+ return 0;
+}
+
+struct page *
+follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+int pmd_huge(pmd_t pmd)
+{
+ return (pmd_val(pmd) & _PAGE_HUGE) != 0;
+}
+
+int pud_huge(pud_t pud)
+{
+ return (pud_val(pud) & _PAGE_HUGE) != 0;
+}
+
+struct page *
+follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ pmd_t *pmd, int write)
+{
+ struct page *page;
+
+ page = pte_page(*(pte_t *)pmd);
+ if (page)
+ page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
+ return page;
+}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
new file mode 100644
index 00000000..1aadeb42
--- /dev/null
+++ b/arch/mips/mm/init.c
@@ -0,0 +1,482 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/bug.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/pagemap.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
+#include <linux/proc_fs.h>
+#include <linux/pfn.h>
+#include <linux/hardirq.h>
+#include <linux/gfp.h>
+
+#include <asm/asm-offsets.h>
+#include <asm/bootinfo.h>
+#include <asm/cachectl.h>
+#include <asm/cpu.h>
+#include <asm/dma.h>
+#include <asm/kmap_types.h>
+#include <asm/mmu_context.h>
+#include <asm/sections.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+#include <asm/fixmap.h>
+
+/* Atomicity and interruptability */
+#ifdef CONFIG_MIPS_MT_SMTC
+
+#include <asm/mipsmtregs.h>
+
+#define ENTER_CRITICAL(flags) \
+ { \
+ unsigned int mvpflags; \
+ local_irq_save(flags);\
+ mvpflags = dvpe()
+#define EXIT_CRITICAL(flags) \
+ evpe(mvpflags); \
+ local_irq_restore(flags); \
+ }
+#else
+
+#define ENTER_CRITICAL(flags) local_irq_save(flags)
+#define EXIT_CRITICAL(flags) local_irq_restore(flags)
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+/*
+ * We have up to 8 empty zeroed pages so we can map one of the right colour
+ * when needed. This is necessary only on R4000 / R4400 SC and MC versions
+ * where we have to avoid VCED / VECI exceptions for good performance at
+ * any price. Since page is never written to after the initialization we
+ * don't have to care about aliases on other CPUs.
+ */
+unsigned long empty_zero_page, zero_page_mask;
+EXPORT_SYMBOL_GPL(empty_zero_page);
+
+/*
+ * Not static inline because used by IP27 special magic initialization code
+ */
+unsigned long setup_zero_pages(void)
+{
+ unsigned int order;
+ unsigned long size;
+ struct page *page;
+
+ if (cpu_has_vce)
+ order = 3;
+ else
+ order = 0;
+
+ empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
+ if (!empty_zero_page)
+ panic("Oh boy, that early out of memory?");
+
+ page = virt_to_page((void *)empty_zero_page);
+ split_page(page, order);
+ while (page < virt_to_page((void *)(empty_zero_page + (PAGE_SIZE << order)))) {
+ SetPageReserved(page);
+ page++;
+ }
+
+ size = PAGE_SIZE << order;
+ zero_page_mask = (size - 1) & PAGE_MASK;
+
+ return 1UL << order;
+}
+
+#ifdef CONFIG_MIPS_MT_SMTC
+static pte_t *kmap_coherent_pte;
+static void __init kmap_coherent_init(void)
+{
+ unsigned long vaddr;
+
+ /* cache the first coherent kmap pte */
+ vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
+ kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
+}
+#else
+static inline void kmap_coherent_init(void) {}
+#endif
+
+void *kmap_coherent(struct page *page, unsigned long addr)
+{
+ enum fixed_addresses idx;
+ unsigned long vaddr, flags, entrylo;
+ unsigned long old_ctx;
+ pte_t pte;
+ int tlbidx;
+
+ BUG_ON(Page_dcache_dirty(page));
+
+ inc_preempt_count();
+ idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1);
+#ifdef CONFIG_MIPS_MT_SMTC
+ idx += FIX_N_COLOURS * smp_processor_id() +
+ (in_interrupt() ? (FIX_N_COLOURS * NR_CPUS) : 0);
+#else
+ idx += in_interrupt() ? FIX_N_COLOURS : 0;
+#endif
+ vaddr = __fix_to_virt(FIX_CMAP_END - idx);
+ pte = mk_pte(page, PAGE_KERNEL);
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+ entrylo = pte.pte_high;
+#else
+ entrylo = pte_to_entrylo(pte_val(pte));
+#endif
+
+ ENTER_CRITICAL(flags);
+ old_ctx = read_c0_entryhi();
+ write_c0_entryhi(vaddr & (PAGE_MASK << 1));
+ write_c0_entrylo0(entrylo);
+ write_c0_entrylo1(entrylo);
+#ifdef CONFIG_MIPS_MT_SMTC
+ set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
+ /* preload TLB instead of local_flush_tlb_one() */
+ mtc0_tlbw_hazard();
+ tlb_probe();
+ tlb_probe_hazard();
+ tlbidx = read_c0_index();
+ mtc0_tlbw_hazard();
+ if (tlbidx < 0)
+ tlb_write_random();
+ else
+ tlb_write_indexed();
+#else
+ tlbidx = read_c0_wired();
+ write_c0_wired(tlbidx + 1);
+ write_c0_index(tlbidx);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+#endif
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+ EXIT_CRITICAL(flags);
+
+ return (void*) vaddr;
+}
+
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
+void kunmap_coherent(void)
+{
+#ifndef CONFIG_MIPS_MT_SMTC
+ unsigned int wired;
+ unsigned long flags, old_ctx;
+
+ ENTER_CRITICAL(flags);
+ old_ctx = read_c0_entryhi();
+ wired = read_c0_wired() - 1;
+ write_c0_wired(wired);
+ write_c0_index(wired);
+ write_c0_entryhi(UNIQUE_ENTRYHI(wired));
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+ EXIT_CRITICAL(flags);
+#endif
+ dec_preempt_count();
+ preempt_check_resched();
+}
+
+void copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *vfrom, *vto;
+
+ vto = kmap_atomic(to, KM_USER1);
+ if (cpu_has_dc_aliases &&
+ page_mapped(from) && !Page_dcache_dirty(from)) {
+ vfrom = kmap_coherent(from, vaddr);
+ copy_page(vto, vfrom);
+ kunmap_coherent();
+ } else {
+ vfrom = kmap_atomic(from, KM_USER0);
+ copy_page(vto, vfrom);
+ kunmap_atomic(vfrom, KM_USER0);
+ }
+ if ((!cpu_has_ic_fills_f_dc) ||
+ pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
+ flush_data_cache_page((unsigned long)vto);
+ kunmap_atomic(vto, KM_USER1);
+ /* Make sure this page is cleared on other CPU's too before using it */
+ smp_wmb();
+}
+
+void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases &&
+ page_mapped(page) && !Page_dcache_dirty(page)) {
+ void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ memcpy(vto, src, len);
+ kunmap_coherent();
+ } else {
+ memcpy(dst, src, len);
+ if (cpu_has_dc_aliases)
+ SetPageDcacheDirty(page);
+ }
+ if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
+ flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+void copy_from_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ if (cpu_has_dc_aliases &&
+ page_mapped(page) && !Page_dcache_dirty(page)) {
+ void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+ memcpy(dst, vfrom, len);
+ kunmap_coherent();
+ } else {
+ memcpy(dst, src, len);
+ if (cpu_has_dc_aliases)
+ SetPageDcacheDirty(page);
+ }
+}
+
+void __init fixrange_init(unsigned long start, unsigned long end,
+ pgd_t *pgd_base)
+{
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC)
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ int i, j, k;
+ unsigned long vaddr;
+
+ vaddr = start;
+ i = __pgd_offset(vaddr);
+ j = __pud_offset(vaddr);
+ k = __pmd_offset(vaddr);
+ pgd = pgd_base + i;
+
+ for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+ pud = (pud_t *)pgd;
+ for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+ pmd = (pmd_t *)pud;
+ for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
+ if (pmd_none(*pmd)) {
+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ set_pmd(pmd, __pmd((unsigned long)pte));
+ BUG_ON(pte != pte_offset_kernel(pmd, 0));
+ }
+ vaddr += PMD_SIZE;
+ }
+ k = 0;
+ }
+ j = 0;
+ }
+#endif
+}
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+int page_is_ram(unsigned long pagenr)
+{
+ int i;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ unsigned long addr, end;
+
+ if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+ /* not usable memory */
+ continue;
+
+ addr = PFN_UP(boot_mem_map.map[i].addr);
+ end = PFN_DOWN(boot_mem_map.map[i].addr +
+ boot_mem_map.map[i].size);
+
+ if (pagenr >= addr && pagenr < end)
+ return 1;
+ }
+
+ return 0;
+}
+
+void __init paging_init(void)
+{
+ unsigned long max_zone_pfns[MAX_NR_ZONES];
+ unsigned long lastpfn __maybe_unused;
+
+ pagetable_init();
+
+#ifdef CONFIG_HIGHMEM
+ kmap_init();
+#endif
+ kmap_coherent_init();
+
+#ifdef CONFIG_ZONE_DMA
+ max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
+#endif
+#ifdef CONFIG_ZONE_DMA32
+ max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
+#endif
+ max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+ lastpfn = max_low_pfn;
+#ifdef CONFIG_HIGHMEM
+ max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
+ lastpfn = highend_pfn;
+
+ if (cpu_has_dc_aliases && max_low_pfn != highend_pfn) {
+ printk(KERN_WARNING "This processor doesn't support highmem."
+ " %ldk highmem ignored\n",
+ (highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10));
+ max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn;
+ lastpfn = max_low_pfn;
+ }
+#endif
+
+ free_area_init_nodes(max_zone_pfns);
+}
+
+#ifdef CONFIG_64BIT
+static struct kcore_list kcore_kseg0;
+#endif
+
+void __init mem_init(void)
+{
+ unsigned long codesize, reservedpages, datasize, initsize;
+ unsigned long tmp, ram;
+
+#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_DISCONTIGMEM
+#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
+#endif
+ max_mapnr = highend_pfn;
+#else
+ max_mapnr = max_low_pfn;
+#endif
+ high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
+
+ totalram_pages += free_all_bootmem();
+ totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */
+
+ reservedpages = ram = 0;
+ for (tmp = 0; tmp < max_low_pfn; tmp++)
+ if (page_is_ram(tmp)) {
+ ram++;
+ if (PageReserved(pfn_to_page(tmp)))
+ reservedpages++;
+ }
+ num_physpages = ram;
+
+#ifdef CONFIG_HIGHMEM
+ for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
+ struct page *page = pfn_to_page(tmp);
+
+ if (!page_is_ram(tmp)) {
+ SetPageReserved(page);
+ continue;
+ }
+ ClearPageReserved(page);
+ init_page_count(page);
+ __free_page(page);
+ totalhigh_pages++;
+ }
+ totalram_pages += totalhigh_pages;
+ num_physpages += totalhigh_pages;
+#endif
+
+ codesize = (unsigned long) &_etext - (unsigned long) &_text;
+ datasize = (unsigned long) &_edata - (unsigned long) &_etext;
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+#ifdef CONFIG_64BIT
+ if ((unsigned long) &_text > (unsigned long) CKSEG0)
+ /* The -4 is a hack so that user tools don't have to handle
+ the overflow. */
+ kclist_add(&kcore_kseg0, (void *) CKSEG0,
+ 0x80000000 - 4, KCORE_TEXT);
+#endif
+
+ printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
+ "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
+ nr_free_pages() << (PAGE_SHIFT-10),
+ ram << (PAGE_SHIFT-10),
+ codesize >> 10,
+ reservedpages << (PAGE_SHIFT-10),
+ datasize >> 10,
+ initsize >> 10,
+ totalhigh_pages << (PAGE_SHIFT-10));
+}
+#endif /* !CONFIG_NEED_MULTIPLE_NODES */
+
+void free_init_pages(const char *what, unsigned long begin, unsigned long end)
+{
+ unsigned long pfn;
+
+ for (pfn = PFN_UP(begin); pfn < PFN_DOWN(end); pfn++) {
+ struct page *page = pfn_to_page(pfn);
+ void *addr = phys_to_virt(PFN_PHYS(pfn));
+
+ ClearPageReserved(page);
+ init_page_count(page);
+ memset(addr, POISON_FREE_INITMEM, PAGE_SIZE);
+ __free_page(page);
+ totalram_pages++;
+ }
+ printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ free_init_pages("initrd memory",
+ virt_to_phys((void *)start),
+ virt_to_phys((void *)end));
+}
+#endif
+
+void __init_refok free_initmem(void)
+{
+ prom_free_prom_memory();
+ free_init_pages("unused kernel memory",
+ __pa_symbol(&__init_begin),
+ __pa_symbol(&__init_end));
+}
+
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+unsigned long pgd_current[NR_CPUS];
+#endif
+/*
+ * On 64-bit we've got three-level pagetables with a slightly
+ * different layout ...
+ */
+#define __page_aligned(order) __attribute__((__aligned__(PAGE_SIZE<<order)))
+
+/*
+ * gcc 3.3 and older have trouble determining that PTRS_PER_PGD and PGD_ORDER
+ * are constants. So we use the variants from asm-offset.h until that gcc
+ * will officially be retired.
+ */
+pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER);
+#ifndef __PAGETABLE_PMD_FOLDED
+pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER);
+#endif
+pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
new file mode 100644
index 00000000..cacfd31e
--- /dev/null
+++ b/arch/mips/mm/ioremap.c
@@ -0,0 +1,192 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ * (C) Copyright 2001, 2002 Ralf Baechle
+ */
+#include <linux/module.h>
+#include <asm/addrspace.h>
+#include <asm/byteorder.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+ phys_t size, phys_t phys_addr, unsigned long flags)
+{
+ phys_t end;
+ unsigned long pfn;
+ pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+ | __WRITEABLE | flags);
+
+ address &= ~PMD_MASK;
+ end = address + size;
+ if (end > PMD_SIZE)
+ end = PMD_SIZE;
+ BUG_ON(address >= end);
+ pfn = phys_addr >> PAGE_SHIFT;
+ do {
+ if (!pte_none(*pte)) {
+ printk("remap_area_pte: page already exists\n");
+ BUG();
+ }
+ set_pte(pte, pfn_pte(pfn, pgprot));
+ address += PAGE_SIZE;
+ pfn++;
+ pte++;
+ } while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+ phys_t size, phys_t phys_addr, unsigned long flags)
+{
+ phys_t end;
+
+ address &= ~PGDIR_MASK;
+ end = address + size;
+ if (end > PGDIR_SIZE)
+ end = PGDIR_SIZE;
+ phys_addr -= address;
+ BUG_ON(address >= end);
+ do {
+ pte_t * pte = pte_alloc_kernel(pmd, address);
+ if (!pte)
+ return -ENOMEM;
+ remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+ address = (address + PMD_SIZE) & PMD_MASK;
+ pmd++;
+ } while (address && (address < end));
+ return 0;
+}
+
+static int remap_area_pages(unsigned long address, phys_t phys_addr,
+ phys_t size, unsigned long flags)
+{
+ int error;
+ pgd_t * dir;
+ unsigned long end = address + size;
+
+ phys_addr -= address;
+ dir = pgd_offset(&init_mm, address);
+ flush_cache_all();
+ BUG_ON(address >= end);
+ do {
+ pud_t *pud;
+ pmd_t *pmd;
+
+ error = -ENOMEM;
+ pud = pud_alloc(&init_mm, dir, address);
+ if (!pud)
+ break;
+ pmd = pmd_alloc(&init_mm, pud, address);
+ if (!pmd)
+ break;
+ if (remap_area_pmd(pmd, address, end - address,
+ phys_addr + address, flags))
+ break;
+ error = 0;
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ dir++;
+ } while (address && (address < end));
+ flush_tlb_all();
+ return error;
+}
+
+/*
+ * Generic mapping function (not visible outside):
+ */
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+
+#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
+
+void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
+{
+ struct vm_struct * area;
+ unsigned long offset;
+ phys_t last_addr;
+ void * addr;
+
+ phys_addr = fixup_bigphys_addr(phys_addr, size);
+
+ /* Don't allow wraparound or zero size */
+ last_addr = phys_addr + size - 1;
+ if (!size || last_addr < phys_addr)
+ return NULL;
+
+ /*
+ * Map uncached objects in the low 512mb of address space using KSEG1,
+ * otherwise map using page tables.
+ */
+ if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
+ flags == _CACHE_UNCACHED)
+ return (void __iomem *) CKSEG1ADDR(phys_addr);
+
+ /*
+ * Don't allow anybody to remap normal RAM that we're using..
+ */
+ if (phys_addr < virt_to_phys(high_memory)) {
+ char *t_addr, *t_end;
+ struct page *page;
+
+ t_addr = __va(phys_addr);
+ t_end = t_addr + (size - 1);
+
+ for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
+ if(!PageReserved(page))
+ return NULL;
+ }
+
+ /*
+ * Mappings have to be page-aligned
+ */
+ offset = phys_addr & ~PAGE_MASK;
+ phys_addr &= PAGE_MASK;
+ size = PAGE_ALIGN(last_addr + 1) - phys_addr;
+
+ /*
+ * Ok, go for it..
+ */
+ area = get_vm_area(size, VM_IOREMAP);
+ if (!area)
+ return NULL;
+ addr = area->addr;
+ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ vunmap(addr);
+ return NULL;
+ }
+
+ return (void __iomem *) (offset + (char *)addr);
+}
+
+#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
+
+void __iounmap(const volatile void __iomem *addr)
+{
+ struct vm_struct *p;
+
+ if (IS_KSEG1(addr))
+ return;
+
+ p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+ if (!p)
+ printk(KERN_ERR "iounmap: bad address %p\n", addr);
+
+ kfree(p);
+}
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(__iounmap);
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
new file mode 100644
index 00000000..ae3c20a9
--- /dev/null
+++ b/arch/mips/mm/mmap.c
@@ -0,0 +1,122 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2011 Wind River Systems,
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
+
+EXPORT_SYMBOL(shm_align_mask);
+
+#define COLOUR_ALIGN(addr,pgoff) \
+ ((((addr) + shm_align_mask) & ~shm_align_mask) + \
+ (((pgoff) << PAGE_SHIFT) & shm_align_mask))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ struct vm_area_struct * vmm;
+ int do_color_align;
+
+ if (len > TASK_SIZE)
+ return -ENOMEM;
+
+ if (flags & MAP_FIXED) {
+ /* Even MAP_FIXED mappings must reside within TASK_SIZE. */
+ if (TASK_SIZE - len < addr)
+ return -EINVAL;
+
+ /*
+ * We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+ if ((flags & MAP_SHARED) &&
+ ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
+ return -EINVAL;
+ return addr;
+ }
+
+ do_color_align = 0;
+ if (filp || (flags & MAP_SHARED))
+ do_color_align = 1;
+ if (addr) {
+ if (do_color_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+ else
+ addr = PAGE_ALIGN(addr);
+ vmm = find_vma(current->mm, addr);
+ if (TASK_SIZE - len >= addr &&
+ (!vmm || addr + len <= vmm->vm_start))
+ return addr;
+ }
+ addr = current->mm->mmap_base;
+ if (do_color_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+ else
+ addr = PAGE_ALIGN(addr);
+
+ for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
+ /* At this point: (!vmm || addr < vmm->vm_end). */
+ if (TASK_SIZE - len < addr)
+ return -ENOMEM;
+ if (!vmm || addr + len <= vmm->vm_start)
+ return addr;
+ addr = vmm->vm_end;
+ if (do_color_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+ }
+}
+
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+ unsigned long random_factor = 0UL;
+
+ if (current->flags & PF_RANDOMIZE) {
+ random_factor = get_random_int();
+ random_factor = random_factor << PAGE_SHIFT;
+ if (TASK_IS_32BIT_ADDR)
+ random_factor &= 0xfffffful;
+ else
+ random_factor &= 0xffffffful;
+ }
+
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
+ mm->get_unmapped_area = arch_get_unmapped_area;
+ mm->unmap_area = arch_unmap_area;
+}
+
+static inline unsigned long brk_rnd(void)
+{
+ unsigned long rnd = get_random_int();
+
+ rnd = rnd << PAGE_SHIFT;
+ /* 8MB for 32bit, 256MB for 64bit */
+ if (TASK_IS_32BIT_ADDR)
+ rnd = rnd & 0x7ffffful;
+ else
+ rnd = rnd & 0xffffffful;
+
+ return rnd;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+ unsigned long base = mm->brk;
+ unsigned long ret;
+
+ ret = PAGE_ALIGN(base + brk_rnd());
+
+ if (ret < mm->brk)
+ return mm->brk;
+
+ return ret;
+}
diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c
new file mode 100644
index 00000000..36272f7d
--- /dev/null
+++ b/arch/mips/mm/page.c
@@ -0,0 +1,691 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 04, 05 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2007 Maciej W. Rozycki
+ * Copyright (C) 2008 Thiemo Seufer
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+
+#include <asm/bugs.h>
+#include <asm/cacheops.h>
+#include <asm/inst.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/prefetch.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/mmu_context.h>
+#include <asm/cpu.h>
+#include <asm/war.h>
+
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_dma.h>
+#endif
+
+#include <asm/uasm.h>
+
+/* Registers used in the assembled routines. */
+#define ZERO 0
+#define AT 2
+#define A0 4
+#define A1 5
+#define A2 6
+#define T0 8
+#define T1 9
+#define T2 10
+#define T3 11
+#define T9 25
+#define RA 31
+
+/* Handle labels (which must be positive integers). */
+enum label_id {
+ label_clear_nopref = 1,
+ label_clear_pref,
+ label_copy_nopref,
+ label_copy_pref_both,
+ label_copy_pref_store,
+};
+
+UASM_L_LA(_clear_nopref)
+UASM_L_LA(_clear_pref)
+UASM_L_LA(_copy_nopref)
+UASM_L_LA(_copy_pref_both)
+UASM_L_LA(_copy_pref_store)
+
+/* We need one branch and therefore one relocation per target label. */
+static struct uasm_label __cpuinitdata labels[5];
+static struct uasm_reloc __cpuinitdata relocs[5];
+
+#define cpu_is_r4600_v1_x() ((read_c0_prid() & 0xfffffff0) == 0x00002010)
+#define cpu_is_r4600_v2_x() ((read_c0_prid() & 0xfffffff0) == 0x00002020)
+
+/*
+ * Maximum sizes:
+ *
+ * R4000 128 bytes S-cache: 0x058 bytes
+ * R4600 v1.7: 0x05c bytes
+ * R4600 v2.0: 0x060 bytes
+ * With prefetching, 16 word strides 0x120 bytes
+ */
+
+static u32 clear_page_array[0x120 / 4];
+
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+void clear_page_cpu(void *page) __attribute__((alias("clear_page_array")));
+#else
+void clear_page(void *page) __attribute__((alias("clear_page_array")));
+#endif
+
+EXPORT_SYMBOL(clear_page);
+
+/*
+ * Maximum sizes:
+ *
+ * R4000 128 bytes S-cache: 0x11c bytes
+ * R4600 v1.7: 0x080 bytes
+ * R4600 v2.0: 0x07c bytes
+ * With prefetching, 16 word strides 0x540 bytes
+ */
+static u32 copy_page_array[0x540 / 4];
+
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+void
+copy_page_cpu(void *to, void *from) __attribute__((alias("copy_page_array")));
+#else
+void copy_page(void *to, void *from) __attribute__((alias("copy_page_array")));
+#endif
+
+EXPORT_SYMBOL(copy_page);
+
+
+static int pref_bias_clear_store __cpuinitdata;
+static int pref_bias_copy_load __cpuinitdata;
+static int pref_bias_copy_store __cpuinitdata;
+
+static u32 pref_src_mode __cpuinitdata;
+static u32 pref_dst_mode __cpuinitdata;
+
+static int clear_word_size __cpuinitdata;
+static int copy_word_size __cpuinitdata;
+
+static int half_clear_loop_size __cpuinitdata;
+static int half_copy_loop_size __cpuinitdata;
+
+static int cache_line_size __cpuinitdata;
+#define cache_line_mask() (cache_line_size - 1)
+
+static inline void __cpuinit
+pg_addiu(u32 **buf, unsigned int reg1, unsigned int reg2, unsigned int off)
+{
+ if (cpu_has_64bit_gp_regs && DADDI_WAR && r4k_daddiu_bug()) {
+ if (off > 0x7fff) {
+ uasm_i_lui(buf, T9, uasm_rel_hi(off));
+ uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
+ } else
+ uasm_i_addiu(buf, T9, ZERO, off);
+ uasm_i_daddu(buf, reg1, reg2, T9);
+ } else {
+ if (off > 0x7fff) {
+ uasm_i_lui(buf, T9, uasm_rel_hi(off));
+ uasm_i_addiu(buf, T9, T9, uasm_rel_lo(off));
+ UASM_i_ADDU(buf, reg1, reg2, T9);
+ } else
+ UASM_i_ADDIU(buf, reg1, reg2, off);
+ }
+}
+
+static void __cpuinit set_prefetch_parameters(void)
+{
+ if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg)
+ clear_word_size = 8;
+ else
+ clear_word_size = 4;
+
+ if (cpu_has_64bit_gp_regs)
+ copy_word_size = 8;
+ else
+ copy_word_size = 4;
+
+ /*
+ * The pref's used here are using "streaming" hints, which cause the
+ * copied data to be kicked out of the cache sooner. A page copy often
+ * ends up copying a lot more data than is commonly used, so this seems
+ * to make sense in terms of reducing cache pollution, but I've no real
+ * performance data to back this up.
+ */
+ if (cpu_has_prefetch) {
+ /*
+ * XXX: Most prefetch bias values in here are based on
+ * guesswork.
+ */
+ cache_line_size = cpu_dcache_line_size();
+ switch (current_cpu_type()) {
+ case CPU_R5500:
+ case CPU_TX49XX:
+ /* These processors only support the Pref_Load. */
+ pref_bias_copy_load = 256;
+ break;
+
+ case CPU_RM9000:
+ /*
+ * As a workaround for erratum G105 which make the
+ * PrepareForStore hint unusable we fall back to
+ * StoreRetained on the RM9000. Once it is known which
+ * versions of the RM9000 we'll be able to condition-
+ * alize this.
+ */
+
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_R14000:
+ /*
+ * Those values have been experimentally tuned for an
+ * Origin 200.
+ */
+ pref_bias_clear_store = 512;
+ pref_bias_copy_load = 256;
+ pref_bias_copy_store = 256;
+ pref_src_mode = Pref_LoadStreamed;
+ pref_dst_mode = Pref_StoreStreamed;
+ break;
+
+ case CPU_SB1:
+ case CPU_SB1A:
+ pref_bias_clear_store = 128;
+ pref_bias_copy_load = 128;
+ pref_bias_copy_store = 128;
+ /*
+ * SB1 pass1 Pref_LoadStreamed/Pref_StoreStreamed
+ * hints are broken.
+ */
+ if (current_cpu_type() == CPU_SB1 &&
+ (current_cpu_data.processor_id & 0xff) < 0x02) {
+ pref_src_mode = Pref_Load;
+ pref_dst_mode = Pref_Store;
+ } else {
+ pref_src_mode = Pref_LoadStreamed;
+ pref_dst_mode = Pref_StoreStreamed;
+ }
+ break;
+
+ default:
+ pref_bias_clear_store = 128;
+ pref_bias_copy_load = 256;
+ pref_bias_copy_store = 128;
+ pref_src_mode = Pref_LoadStreamed;
+ pref_dst_mode = Pref_PrepareForStore;
+ break;
+ }
+ } else {
+ if (cpu_has_cache_cdex_s)
+ cache_line_size = cpu_scache_line_size();
+ else if (cpu_has_cache_cdex_p)
+ cache_line_size = cpu_dcache_line_size();
+ }
+ /*
+ * Too much unrolling will overflow the available space in
+ * clear_space_array / copy_page_array.
+ */
+ half_clear_loop_size = min(16 * clear_word_size,
+ max(cache_line_size >> 1,
+ 4 * clear_word_size));
+ half_copy_loop_size = min(16 * copy_word_size,
+ max(cache_line_size >> 1,
+ 4 * copy_word_size));
+}
+
+static void __cpuinit build_clear_store(u32 **buf, int off)
+{
+ if (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg) {
+ uasm_i_sd(buf, ZERO, off, A0);
+ } else {
+ uasm_i_sw(buf, ZERO, off, A0);
+ }
+}
+
+static inline void __cpuinit build_clear_pref(u32 **buf, int off)
+{
+ if (off & cache_line_mask())
+ return;
+
+ if (pref_bias_clear_store) {
+ uasm_i_pref(buf, pref_dst_mode, pref_bias_clear_store + off,
+ A0);
+ } else if (cache_line_size == (half_clear_loop_size << 1)) {
+ if (cpu_has_cache_cdex_s) {
+ uasm_i_cache(buf, Create_Dirty_Excl_SD, off, A0);
+ } else if (cpu_has_cache_cdex_p) {
+ if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) {
+ uasm_i_nop(buf);
+ uasm_i_nop(buf);
+ uasm_i_nop(buf);
+ uasm_i_nop(buf);
+ }
+
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
+ uasm_i_lw(buf, ZERO, ZERO, AT);
+
+ uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0);
+ }
+ }
+}
+
+void __cpuinit build_clear_page(void)
+{
+ int off;
+ u32 *buf = (u32 *)&clear_page_array;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+ int i;
+
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ set_prefetch_parameters();
+
+ /*
+ * This algorithm makes the following assumptions:
+ * - The prefetch bias is a multiple of 2 words.
+ * - The prefetch bias is less than one page.
+ */
+ BUG_ON(pref_bias_clear_store % (2 * clear_word_size));
+ BUG_ON(PAGE_SIZE < pref_bias_clear_store);
+
+ off = PAGE_SIZE - pref_bias_clear_store;
+ if (off > 0xffff || !pref_bias_clear_store)
+ pg_addiu(&buf, A2, A0, off);
+ else
+ uasm_i_ori(&buf, A2, A0, off);
+
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
+ uasm_i_lui(&buf, AT, 0xa000);
+
+ off = cache_line_size ? min(8, pref_bias_clear_store / cache_line_size)
+ * cache_line_size : 0;
+ while (off) {
+ build_clear_pref(&buf, -off);
+ off -= cache_line_size;
+ }
+ uasm_l_clear_pref(&l, buf);
+ do {
+ build_clear_pref(&buf, off);
+ build_clear_store(&buf, off);
+ off += clear_word_size;
+ } while (off < half_clear_loop_size);
+ pg_addiu(&buf, A0, A0, 2 * off);
+ off = -off;
+ do {
+ build_clear_pref(&buf, off);
+ if (off == -clear_word_size)
+ uasm_il_bne(&buf, &r, A0, A2, label_clear_pref);
+ build_clear_store(&buf, off);
+ off += clear_word_size;
+ } while (off < 0);
+
+ if (pref_bias_clear_store) {
+ pg_addiu(&buf, A2, A0, pref_bias_clear_store);
+ uasm_l_clear_nopref(&l, buf);
+ off = 0;
+ do {
+ build_clear_store(&buf, off);
+ off += clear_word_size;
+ } while (off < half_clear_loop_size);
+ pg_addiu(&buf, A0, A0, 2 * off);
+ off = -off;
+ do {
+ if (off == -clear_word_size)
+ uasm_il_bne(&buf, &r, A0, A2,
+ label_clear_nopref);
+ build_clear_store(&buf, off);
+ off += clear_word_size;
+ } while (off < 0);
+ }
+
+ uasm_i_jr(&buf, RA);
+ uasm_i_nop(&buf);
+
+ BUG_ON(buf > clear_page_array + ARRAY_SIZE(clear_page_array));
+
+ uasm_resolve_relocs(relocs, labels);
+
+ pr_debug("Synthesized clear page handler (%u instructions).\n",
+ (u32)(buf - clear_page_array));
+
+ pr_debug("\t.set push\n");
+ pr_debug("\t.set noreorder\n");
+ for (i = 0; i < (buf - clear_page_array); i++)
+ pr_debug("\t.word 0x%08x\n", clear_page_array[i]);
+ pr_debug("\t.set pop\n");
+}
+
+static void __cpuinit build_copy_load(u32 **buf, int reg, int off)
+{
+ if (cpu_has_64bit_gp_regs) {
+ uasm_i_ld(buf, reg, off, A1);
+ } else {
+ uasm_i_lw(buf, reg, off, A1);
+ }
+}
+
+static void __cpuinit build_copy_store(u32 **buf, int reg, int off)
+{
+ if (cpu_has_64bit_gp_regs) {
+ uasm_i_sd(buf, reg, off, A0);
+ } else {
+ uasm_i_sw(buf, reg, off, A0);
+ }
+}
+
+static inline void build_copy_load_pref(u32 **buf, int off)
+{
+ if (off & cache_line_mask())
+ return;
+
+ if (pref_bias_copy_load)
+ uasm_i_pref(buf, pref_src_mode, pref_bias_copy_load + off, A1);
+}
+
+static inline void build_copy_store_pref(u32 **buf, int off)
+{
+ if (off & cache_line_mask())
+ return;
+
+ if (pref_bias_copy_store) {
+ uasm_i_pref(buf, pref_dst_mode, pref_bias_copy_store + off,
+ A0);
+ } else if (cache_line_size == (half_copy_loop_size << 1)) {
+ if (cpu_has_cache_cdex_s) {
+ uasm_i_cache(buf, Create_Dirty_Excl_SD, off, A0);
+ } else if (cpu_has_cache_cdex_p) {
+ if (R4600_V1_HIT_CACHEOP_WAR && cpu_is_r4600_v1_x()) {
+ uasm_i_nop(buf);
+ uasm_i_nop(buf);
+ uasm_i_nop(buf);
+ uasm_i_nop(buf);
+ }
+
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
+ uasm_i_lw(buf, ZERO, ZERO, AT);
+
+ uasm_i_cache(buf, Create_Dirty_Excl_D, off, A0);
+ }
+ }
+}
+
+void __cpuinit build_copy_page(void)
+{
+ int off;
+ u32 *buf = (u32 *)&copy_page_array;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+ int i;
+
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ set_prefetch_parameters();
+
+ /*
+ * This algorithm makes the following assumptions:
+ * - All prefetch biases are multiples of 8 words.
+ * - The prefetch biases are less than one page.
+ * - The store prefetch bias isn't greater than the load
+ * prefetch bias.
+ */
+ BUG_ON(pref_bias_copy_load % (8 * copy_word_size));
+ BUG_ON(pref_bias_copy_store % (8 * copy_word_size));
+ BUG_ON(PAGE_SIZE < pref_bias_copy_load);
+ BUG_ON(pref_bias_copy_store > pref_bias_copy_load);
+
+ off = PAGE_SIZE - pref_bias_copy_load;
+ if (off > 0xffff || !pref_bias_copy_load)
+ pg_addiu(&buf, A2, A0, off);
+ else
+ uasm_i_ori(&buf, A2, A0, off);
+
+ if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
+ uasm_i_lui(&buf, AT, 0xa000);
+
+ off = cache_line_size ? min(8, pref_bias_copy_load / cache_line_size) *
+ cache_line_size : 0;
+ while (off) {
+ build_copy_load_pref(&buf, -off);
+ off -= cache_line_size;
+ }
+ off = cache_line_size ? min(8, pref_bias_copy_store / cache_line_size) *
+ cache_line_size : 0;
+ while (off) {
+ build_copy_store_pref(&buf, -off);
+ off -= cache_line_size;
+ }
+ uasm_l_copy_pref_both(&l, buf);
+ do {
+ build_copy_load_pref(&buf, off);
+ build_copy_load(&buf, T0, off);
+ build_copy_load_pref(&buf, off + copy_word_size);
+ build_copy_load(&buf, T1, off + copy_word_size);
+ build_copy_load_pref(&buf, off + 2 * copy_word_size);
+ build_copy_load(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load_pref(&buf, off + 3 * copy_word_size);
+ build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store_pref(&buf, off);
+ build_copy_store(&buf, T0, off);
+ build_copy_store_pref(&buf, off + copy_word_size);
+ build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store_pref(&buf, off + 2 * copy_word_size);
+ build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store_pref(&buf, off + 3 * copy_word_size);
+ build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ off += 4 * copy_word_size;
+ } while (off < half_copy_loop_size);
+ pg_addiu(&buf, A1, A1, 2 * off);
+ pg_addiu(&buf, A0, A0, 2 * off);
+ off = -off;
+ do {
+ build_copy_load_pref(&buf, off);
+ build_copy_load(&buf, T0, off);
+ build_copy_load_pref(&buf, off + copy_word_size);
+ build_copy_load(&buf, T1, off + copy_word_size);
+ build_copy_load_pref(&buf, off + 2 * copy_word_size);
+ build_copy_load(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load_pref(&buf, off + 3 * copy_word_size);
+ build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store_pref(&buf, off);
+ build_copy_store(&buf, T0, off);
+ build_copy_store_pref(&buf, off + copy_word_size);
+ build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store_pref(&buf, off + 2 * copy_word_size);
+ build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store_pref(&buf, off + 3 * copy_word_size);
+ if (off == -(4 * copy_word_size))
+ uasm_il_bne(&buf, &r, A2, A0, label_copy_pref_both);
+ build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ off += 4 * copy_word_size;
+ } while (off < 0);
+
+ if (pref_bias_copy_load - pref_bias_copy_store) {
+ pg_addiu(&buf, A2, A0,
+ pref_bias_copy_load - pref_bias_copy_store);
+ uasm_l_copy_pref_store(&l, buf);
+ off = 0;
+ do {
+ build_copy_load(&buf, T0, off);
+ build_copy_load(&buf, T1, off + copy_word_size);
+ build_copy_load(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store_pref(&buf, off);
+ build_copy_store(&buf, T0, off);
+ build_copy_store_pref(&buf, off + copy_word_size);
+ build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store_pref(&buf, off + 2 * copy_word_size);
+ build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store_pref(&buf, off + 3 * copy_word_size);
+ build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ off += 4 * copy_word_size;
+ } while (off < half_copy_loop_size);
+ pg_addiu(&buf, A1, A1, 2 * off);
+ pg_addiu(&buf, A0, A0, 2 * off);
+ off = -off;
+ do {
+ build_copy_load(&buf, T0, off);
+ build_copy_load(&buf, T1, off + copy_word_size);
+ build_copy_load(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store_pref(&buf, off);
+ build_copy_store(&buf, T0, off);
+ build_copy_store_pref(&buf, off + copy_word_size);
+ build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store_pref(&buf, off + 2 * copy_word_size);
+ build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store_pref(&buf, off + 3 * copy_word_size);
+ if (off == -(4 * copy_word_size))
+ uasm_il_bne(&buf, &r, A2, A0,
+ label_copy_pref_store);
+ build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ off += 4 * copy_word_size;
+ } while (off < 0);
+ }
+
+ if (pref_bias_copy_store) {
+ pg_addiu(&buf, A2, A0, pref_bias_copy_store);
+ uasm_l_copy_nopref(&l, buf);
+ off = 0;
+ do {
+ build_copy_load(&buf, T0, off);
+ build_copy_load(&buf, T1, off + copy_word_size);
+ build_copy_load(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store(&buf, T0, off);
+ build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ off += 4 * copy_word_size;
+ } while (off < half_copy_loop_size);
+ pg_addiu(&buf, A1, A1, 2 * off);
+ pg_addiu(&buf, A0, A0, 2 * off);
+ off = -off;
+ do {
+ build_copy_load(&buf, T0, off);
+ build_copy_load(&buf, T1, off + copy_word_size);
+ build_copy_load(&buf, T2, off + 2 * copy_word_size);
+ build_copy_load(&buf, T3, off + 3 * copy_word_size);
+ build_copy_store(&buf, T0, off);
+ build_copy_store(&buf, T1, off + copy_word_size);
+ build_copy_store(&buf, T2, off + 2 * copy_word_size);
+ if (off == -(4 * copy_word_size))
+ uasm_il_bne(&buf, &r, A2, A0,
+ label_copy_nopref);
+ build_copy_store(&buf, T3, off + 3 * copy_word_size);
+ off += 4 * copy_word_size;
+ } while (off < 0);
+ }
+
+ uasm_i_jr(&buf, RA);
+ uasm_i_nop(&buf);
+
+ BUG_ON(buf > copy_page_array + ARRAY_SIZE(copy_page_array));
+
+ uasm_resolve_relocs(relocs, labels);
+
+ pr_debug("Synthesized copy page handler (%u instructions).\n",
+ (u32)(buf - copy_page_array));
+
+ pr_debug("\t.set push\n");
+ pr_debug("\t.set noreorder\n");
+ for (i = 0; i < (buf - copy_page_array); i++)
+ pr_debug("\t.word 0x%08x\n", copy_page_array[i]);
+ pr_debug("\t.set pop\n");
+}
+
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+
+/*
+ * Pad descriptors to cacheline, since each is exclusively owned by a
+ * particular CPU.
+ */
+struct dmadscr {
+ u64 dscr_a;
+ u64 dscr_b;
+ u64 pad_a;
+ u64 pad_b;
+} ____cacheline_aligned_in_smp page_descr[DM_NUM_CHANNELS];
+
+void sb1_dma_init(void)
+{
+ int i;
+
+ for (i = 0; i < DM_NUM_CHANNELS; i++) {
+ const u64 base_val = CPHYSADDR((unsigned long)&page_descr[i]) |
+ V_DM_DSCR_BASE_RINGSZ(1);
+ void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
+
+ __raw_writeq(base_val, base_reg);
+ __raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg);
+ __raw_writeq(base_val | M_DM_DSCR_BASE_ENABL, base_reg);
+ }
+}
+
+void clear_page(void *page)
+{
+ u64 to_phys = CPHYSADDR((unsigned long)page);
+ unsigned int cpu = smp_processor_id();
+
+ /* if the page is not in KSEG0, use old way */
+ if ((long)KSEGX((unsigned long)page) != (long)CKSEG0)
+ return clear_page_cpu(page);
+
+ page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_ZERO_MEM |
+ M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+ page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+ __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+
+ /*
+ * Don't really want to do it this way, but there's no
+ * reliable way to delay completion detection.
+ */
+ while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
+ & M_DM_DSCR_BASE_INTERRUPT))
+ ;
+ __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+}
+
+void copy_page(void *to, void *from)
+{
+ u64 from_phys = CPHYSADDR((unsigned long)from);
+ u64 to_phys = CPHYSADDR((unsigned long)to);
+ unsigned int cpu = smp_processor_id();
+
+ /* if any page is not in KSEG0, use old way */
+ if ((long)KSEGX((unsigned long)to) != (long)CKSEG0
+ || (long)KSEGX((unsigned long)from) != (long)CKSEG0)
+ return copy_page_cpu(to, from);
+
+ page_descr[cpu].dscr_a = to_phys | M_DM_DSCRA_L2C_DEST |
+ M_DM_DSCRA_INTERRUPT;
+ page_descr[cpu].dscr_b = from_phys | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+ __raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+
+ /*
+ * Don't really want to do it this way, but there's no
+ * reliable way to delay completion detection.
+ */
+ while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)))
+ & M_DM_DSCR_BASE_INTERRUPT))
+ ;
+ __raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+}
+
+#endif /* CONFIG_SIBYTE_DMA_PAGEOPS */
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
new file mode 100644
index 00000000..575e4019
--- /dev/null
+++ b/arch/mips/mm/pgtable-32.c
@@ -0,0 +1,70 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+void pgd_init(unsigned long page)
+{
+ unsigned long *p = (unsigned long *) page;
+ int i;
+
+ for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+ p[i + 0] = (unsigned long) invalid_pte_table;
+ p[i + 1] = (unsigned long) invalid_pte_table;
+ p[i + 2] = (unsigned long) invalid_pte_table;
+ p[i + 3] = (unsigned long) invalid_pte_table;
+ p[i + 4] = (unsigned long) invalid_pte_table;
+ p[i + 5] = (unsigned long) invalid_pte_table;
+ p[i + 6] = (unsigned long) invalid_pte_table;
+ p[i + 7] = (unsigned long) invalid_pte_table;
+ }
+}
+
+void __init pagetable_init(void)
+{
+ unsigned long vaddr;
+ pgd_t *pgd_base;
+#ifdef CONFIG_HIGHMEM
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+#endif
+
+ /* Initialize the entire pgd. */
+ pgd_init((unsigned long)swapper_pg_dir);
+ pgd_init((unsigned long)swapper_pg_dir
+ + sizeof(pgd_t) * USER_PTRS_PER_PGD);
+
+ pgd_base = swapper_pg_dir;
+
+ /*
+ * Fixed mappings:
+ */
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+ fixrange_init(vaddr, 0, pgd_base);
+
+#ifdef CONFIG_HIGHMEM
+ /*
+ * Permanent kmaps:
+ */
+ vaddr = PKMAP_BASE;
+ fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+
+ pgd = swapper_pg_dir + __pgd_offset(vaddr);
+ pud = pud_offset(pgd, vaddr);
+ pmd = pmd_offset(pud, vaddr);
+ pte = pte_offset_kernel(pmd, vaddr);
+ pkmap_page_table = pte;
+#endif
+}
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
new file mode 100644
index 00000000..78eaa4f0
--- /dev/null
+++ b/arch/mips/mm/pgtable-64.c
@@ -0,0 +1,80 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+void pgd_init(unsigned long page)
+{
+ unsigned long *p, *end;
+ unsigned long entry;
+
+#ifdef __PAGETABLE_PMD_FOLDED
+ entry = (unsigned long)invalid_pte_table;
+#else
+ entry = (unsigned long)invalid_pmd_table;
+#endif
+
+ p = (unsigned long *) page;
+ end = p + PTRS_PER_PGD;
+
+ while (p < end) {
+ p[0] = entry;
+ p[1] = entry;
+ p[2] = entry;
+ p[3] = entry;
+ p[4] = entry;
+ p[5] = entry;
+ p[6] = entry;
+ p[7] = entry;
+ p += 8;
+ }
+}
+
+#ifndef __PAGETABLE_PMD_FOLDED
+void pmd_init(unsigned long addr, unsigned long pagetable)
+{
+ unsigned long *p, *end;
+
+ p = (unsigned long *) addr;
+ end = p + PTRS_PER_PMD;
+
+ while (p < end) {
+ p[0] = pagetable;
+ p[1] = pagetable;
+ p[2] = pagetable;
+ p[3] = pagetable;
+ p[4] = pagetable;
+ p[5] = pagetable;
+ p[6] = pagetable;
+ p[7] = pagetable;
+ p += 8;
+ }
+}
+#endif
+
+void __init pagetable_init(void)
+{
+ unsigned long vaddr;
+ pgd_t *pgd_base;
+
+ /* Initialize the entire pgd. */
+ pgd_init((unsigned long)swapper_pg_dir);
+#ifndef __PAGETABLE_PMD_FOLDED
+ pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+#endif
+ pgd_base = swapper_pg_dir;
+ /*
+ * Fixed mappings:
+ */
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+ fixrange_init(vaddr, 0, pgd_base);
+}
diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c
new file mode 100644
index 00000000..a6bd11fb
--- /dev/null
+++ b/arch/mips/mm/sc-ip22.c
@@ -0,0 +1,177 @@
+/*
+ * sc-ip22.c: Indy cache management functions.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (davem@davemloft.net).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/bcache.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/sgi/ip22.h>
+#include <asm/sgi/mc.h>
+
+/* Secondary cache size in bytes, if present. */
+static unsigned long scache_size;
+
+#undef DEBUG_CACHE
+
+#define SC_SIZE 0x00080000
+#define SC_LINE 32
+#define CI_MASK (SC_SIZE - SC_LINE)
+#define SC_INDEX(n) ((n) & CI_MASK)
+
+static inline void indy_sc_wipe(unsigned long first, unsigned long last)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+ ".set\tpush\t\t\t# indy_sc_wipe\n\t"
+ ".set\tnoreorder\n\t"
+ ".set\tmips3\n\t"
+ ".set\tnoat\n\t"
+ "mfc0\t%2, $12\n\t"
+ "li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
+ "mtc0\t$1, $12\n\t"
+
+ "dli\t$1, 0x9000000080000000\n\t"
+ "or\t%0, $1\t\t\t# first line to flush\n\t"
+ "or\t%1, $1\t\t\t# last line to flush\n\t"
+ ".set\tat\n\t"
+
+ "1:\tsw\t$0, 0(%0)\n\t"
+ "bne\t%0, %1, 1b\n\t"
+ " daddu\t%0, 32\n\t"
+
+ "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
+ "nop; nop; nop; nop;\n\t"
+ ".set\tpop"
+ : "=r" (first), "=r" (last), "=&r" (tmp)
+ : "0" (first), "1" (last));
+}
+
+static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size)
+{
+ unsigned long first_line, last_line;
+ unsigned long flags;
+
+#ifdef DEBUG_CACHE
+ printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
+#endif
+
+ /* Catch bad driver code */
+ BUG_ON(size == 0);
+
+ /* Which lines to flush? */
+ first_line = SC_INDEX(addr);
+ last_line = SC_INDEX(addr + size - 1);
+
+ local_irq_save(flags);
+ if (first_line <= last_line) {
+ indy_sc_wipe(first_line, last_line);
+ goto out;
+ }
+
+ indy_sc_wipe(first_line, SC_SIZE - SC_LINE);
+ indy_sc_wipe(0, last_line);
+out:
+ local_irq_restore(flags);
+}
+
+static void indy_sc_enable(void)
+{
+ unsigned long addr, tmp1, tmp2;
+
+ /* This is really cool... */
+#ifdef DEBUG_CACHE
+ printk("Enabling R4600 SCACHE\n");
+#endif
+ __asm__ __volatile__(
+ ".set\tpush\n\t"
+ ".set\tnoreorder\n\t"
+ ".set\tmips3\n\t"
+ "mfc0\t%2, $12\n\t"
+ "nop; nop; nop; nop;\n\t"
+ "li\t%1, 0x80\n\t"
+ "mtc0\t%1, $12\n\t"
+ "nop; nop; nop; nop;\n\t"
+ "li\t%0, 0x1\n\t"
+ "dsll\t%0, 31\n\t"
+ "lui\t%1, 0x9000\n\t"
+ "dsll32\t%1, 0\n\t"
+ "or\t%0, %1, %0\n\t"
+ "sb\t$0, 0(%0)\n\t"
+ "mtc0\t$0, $12\n\t"
+ "nop; nop; nop; nop;\n\t"
+ "mtc0\t%2, $12\n\t"
+ "nop; nop; nop; nop;\n\t"
+ ".set\tpop"
+ : "=r" (tmp1), "=r" (tmp2), "=r" (addr));
+}
+
+static void indy_sc_disable(void)
+{
+ unsigned long tmp1, tmp2, tmp3;
+
+#ifdef DEBUG_CACHE
+ printk("Disabling R4600 SCACHE\n");
+#endif
+ __asm__ __volatile__(
+ ".set\tpush\n\t"
+ ".set\tnoreorder\n\t"
+ ".set\tmips3\n\t"
+ "li\t%0, 0x1\n\t"
+ "dsll\t%0, 31\n\t"
+ "lui\t%1, 0x9000\n\t"
+ "dsll32\t%1, 0\n\t"
+ "or\t%0, %1, %0\n\t"
+ "mfc0\t%2, $12\n\t"
+ "nop; nop; nop; nop\n\t"
+ "li\t%1, 0x80\n\t"
+ "mtc0\t%1, $12\n\t"
+ "nop; nop; nop; nop\n\t"
+ "sh\t$0, 0(%0)\n\t"
+ "mtc0\t$0, $12\n\t"
+ "nop; nop; nop; nop\n\t"
+ "mtc0\t%2, $12\n\t"
+ "nop; nop; nop; nop\n\t"
+ ".set\tpop"
+ : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3));
+}
+
+static inline int __init indy_sc_probe(void)
+{
+ unsigned int size = ip22_eeprom_read(&sgimc->eeprom, 17);
+ if (size == 0)
+ return 0;
+
+ size <<= PAGE_SHIFT;
+ printk(KERN_INFO "R4600/R5000 SCACHE size %dK, linesize 32 bytes.\n",
+ size >> 10);
+ scache_size = size;
+
+ return 1;
+}
+
+/* XXX Check with wje if the Indy caches can differenciate between
+ writeback + invalidate and just invalidate. */
+static struct bcache_ops indy_sc_ops = {
+ .bc_enable = indy_sc_enable,
+ .bc_disable = indy_sc_disable,
+ .bc_wback_inv = indy_sc_wback_invalidate,
+ .bc_inv = indy_sc_wback_invalidate
+};
+
+void __cpuinit indy_sc_init(void)
+{
+ if (indy_sc_probe()) {
+ indy_sc_enable();
+ bcops = &indy_sc_ops;
+ }
+}
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
new file mode 100644
index 00000000..9cca8de0
--- /dev/null
+++ b/arch/mips/mm/sc-mips.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2006 Chris Dearman (chris@mips.com),
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/r4kcache.h>
+
+/*
+ * MIPS32/MIPS64 L2 cache handling
+ */
+
+/*
+ * Writeback and invalidate the secondary cache before DMA.
+ */
+static void mips_sc_wback_inv(unsigned long addr, unsigned long size)
+{
+ blast_scache_range(addr, addr + size);
+}
+
+/*
+ * Invalidate the secondary cache before DMA.
+ */
+static void mips_sc_inv(unsigned long addr, unsigned long size)
+{
+ unsigned long lsize = cpu_scache_line_size();
+ unsigned long almask = ~(lsize - 1);
+
+ cache_op(Hit_Writeback_Inv_SD, addr & almask);
+ cache_op(Hit_Writeback_Inv_SD, (addr + size - 1) & almask);
+ blast_inv_scache_range(addr, addr + size);
+}
+
+static void mips_sc_enable(void)
+{
+ /* L2 cache is permanently enabled */
+}
+
+static void mips_sc_disable(void)
+{
+ /* L2 cache is permanently enabled */
+}
+
+static struct bcache_ops mips_sc_ops = {
+ .bc_enable = mips_sc_enable,
+ .bc_disable = mips_sc_disable,
+ .bc_wback_inv = mips_sc_wback_inv,
+ .bc_inv = mips_sc_inv
+};
+
+/*
+ * Check if the L2 cache controller is activated on a particular platform.
+ * MTI's L2 controller and the L2 cache controller of Broadcom's BMIPS
+ * cores both use c0_config2's bit 12 as "L2 Bypass" bit, that is the
+ * cache being disabled. However there is no guarantee for this to be
+ * true on all platforms. In an act of stupidity the spec defined bits
+ * 12..15 as implementation defined so below function will eventually have
+ * to be replaced by a platform specific probe.
+ */
+static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
+{
+ unsigned int config2 = read_c0_config2();
+ unsigned int tmp;
+
+ /* Check the bypass bit (L2B) */
+ switch (c->cputype) {
+ case CPU_34K:
+ case CPU_74K:
+ case CPU_1004K:
+ case CPU_BMIPS5000:
+ if (config2 & (1 << 12))
+ return 0;
+ }
+
+ tmp = (config2 >> 4) & 0x0f;
+ if (0 < tmp && tmp <= 7)
+ c->scache.linesz = 2 << tmp;
+ else
+ return 0;
+ return 1;
+}
+
+static inline int __init mips_sc_probe(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int config1, config2;
+ unsigned int tmp;
+
+ /* Mark as not present until probe completed */
+ c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
+
+ /* Ignore anything but MIPSxx processors */
+ if (c->isa_level != MIPS_CPU_ISA_M32R1 &&
+ c->isa_level != MIPS_CPU_ISA_M32R2 &&
+ c->isa_level != MIPS_CPU_ISA_M64R1 &&
+ c->isa_level != MIPS_CPU_ISA_M64R2)
+ return 0;
+
+ /* Does this MIPS32/MIPS64 CPU have a config2 register? */
+ config1 = read_c0_config1();
+ if (!(config1 & MIPS_CONF_M))
+ return 0;
+
+ config2 = read_c0_config2();
+
+ if (!mips_sc_is_activated(c))
+ return 0;
+
+ tmp = (config2 >> 8) & 0x0f;
+ if (0 <= tmp && tmp <= 7)
+ c->scache.sets = 64 << tmp;
+ else
+ return 0;
+
+ tmp = (config2 >> 0) & 0x0f;
+ if (0 <= tmp && tmp <= 7)
+ c->scache.ways = tmp + 1;
+ else
+ return 0;
+
+ c->scache.waysize = c->scache.sets * c->scache.linesz;
+ c->scache.waybit = __ffs(c->scache.waysize);
+
+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+
+ return 1;
+}
+
+int __cpuinit mips_sc_init(void)
+{
+ int found = mips_sc_probe();
+ if (found) {
+ mips_sc_enable();
+ bcops = &mips_sc_ops;
+ }
+ return found;
+}
diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c
new file mode 100644
index 00000000..ae1e533a
--- /dev/null
+++ b/arch/mips/mm/sc-r5k.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (davem@davemloft.net).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/cacheops.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/r4kcache.h>
+
+/* Secondary cache size in bytes, if present. */
+static unsigned long scache_size;
+
+#define SC_LINE 32
+#define SC_PAGE (128*SC_LINE)
+
+static inline void blast_r5000_scache(void)
+{
+ unsigned long start = INDEX_BASE;
+ unsigned long end = start + scache_size;
+
+ while(start < end) {
+ cache_op(R5K_Page_Invalidate_S, start);
+ start += SC_PAGE;
+ }
+}
+
+static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size)
+{
+ unsigned long end, a;
+
+ /* Catch bad driver code */
+ BUG_ON(size == 0);
+
+ if (size >= scache_size) {
+ blast_r5000_scache();
+ return;
+ }
+
+ /* On the R5000 secondary cache we cannot
+ * invalidate less than a page at a time.
+ * The secondary cache is physically indexed, write-through.
+ */
+ a = addr & ~(SC_PAGE - 1);
+ end = (addr + size - 1) & ~(SC_PAGE - 1);
+ while (a <= end) {
+ cache_op(R5K_Page_Invalidate_S, a);
+ a += SC_PAGE;
+ }
+}
+
+static void r5k_sc_enable(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ set_c0_config(R5K_CONF_SE);
+ blast_r5000_scache();
+ local_irq_restore(flags);
+}
+
+static void r5k_sc_disable(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ blast_r5000_scache();
+ clear_c0_config(R5K_CONF_SE);
+ local_irq_restore(flags);
+}
+
+static inline int __init r5k_sc_probe(void)
+{
+ unsigned long config = read_c0_config();
+
+ if (config & CONF_SC)
+ return(0);
+
+ scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20);
+
+ printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n",
+ scache_size >> 10);
+
+ return 1;
+}
+
+static struct bcache_ops r5k_sc_ops = {
+ .bc_enable = r5k_sc_enable,
+ .bc_disable = r5k_sc_disable,
+ .bc_wback_inv = r5k_dma_cache_inv_sc,
+ .bc_inv = r5k_dma_cache_inv_sc
+};
+
+void __cpuinit r5k_sc_init(void)
+{
+ if (r5k_sc_probe()) {
+ r5k_sc_enable();
+ bcops = &r5k_sc_ops;
+ }
+}
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
new file mode 100644
index 00000000..274af3be
--- /dev/null
+++ b/arch/mips/mm/sc-rm7k.c
@@ -0,0 +1,270 @@
+/*
+ * sc-rm7k.c: RM7000 cache management functions.
+ *
+ * Copyright (C) 1997, 2001, 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/cacheops.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/cacheflush.h> /* for run_uncached() */
+
+/* Primary cache parameters. */
+#define sc_lsize 32
+#define tc_pagesize (32*128)
+
+/* Secondary cache parameters. */
+#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */
+
+/* Tertiary cache parameters */
+#define tc_lsize 32
+
+extern unsigned long icache_way_size, dcache_way_size;
+static unsigned long tcache_size;
+
+#include <asm/r4kcache.h>
+
+static int rm7k_tcache_init;
+
+/*
+ * Writeback and invalidate the primary cache dcache before DMA.
+ * (XXX These need to be fixed ...)
+ */
+static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size)
+{
+ unsigned long end, a;
+
+ pr_debug("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size);
+
+ /* Catch bad driver code */
+ BUG_ON(size == 0);
+
+ blast_scache_range(addr, addr + size);
+
+ if (!rm7k_tcache_init)
+ return;
+
+ a = addr & ~(tc_pagesize - 1);
+ end = (addr + size - 1) & ~(tc_pagesize - 1);
+ while(1) {
+ invalidate_tcache_page(a); /* Page_Invalidate_T */
+ if (a == end)
+ break;
+ a += tc_pagesize;
+ }
+}
+
+static void rm7k_sc_inv(unsigned long addr, unsigned long size)
+{
+ unsigned long end, a;
+
+ pr_debug("rm7k_sc_inv[%08lx,%08lx]", addr, size);
+
+ /* Catch bad driver code */
+ BUG_ON(size == 0);
+
+ blast_inv_scache_range(addr, addr + size);
+
+ if (!rm7k_tcache_init)
+ return;
+
+ a = addr & ~(tc_pagesize - 1);
+ end = (addr + size - 1) & ~(tc_pagesize - 1);
+ while(1) {
+ invalidate_tcache_page(a); /* Page_Invalidate_T */
+ if (a == end)
+ break;
+ a += tc_pagesize;
+ }
+}
+
+static void blast_rm7k_tcache(void)
+{
+ unsigned long start = CKSEG0ADDR(0);
+ unsigned long end = start + tcache_size;
+
+ write_c0_taglo(0);
+
+ while (start < end) {
+ cache_op(Page_Invalidate_T, start);
+ start += tc_pagesize;
+ }
+}
+
+/*
+ * This function is executed in uncached address space.
+ */
+static __cpuinit void __rm7k_tc_enable(void)
+{
+ int i;
+
+ set_c0_config(RM7K_CONF_TE);
+
+ write_c0_taglo(0);
+ write_c0_taghi(0);
+
+ for (i = 0; i < tcache_size; i += tc_lsize)
+ cache_op(Index_Store_Tag_T, CKSEG0ADDR(i));
+}
+
+static __cpuinit void rm7k_tc_enable(void)
+{
+ if (read_c0_config() & RM7K_CONF_TE)
+ return;
+
+ BUG_ON(tcache_size == 0);
+
+ run_uncached(__rm7k_tc_enable);
+}
+
+/*
+ * This function is executed in uncached address space.
+ */
+static __cpuinit void __rm7k_sc_enable(void)
+{
+ int i;
+
+ set_c0_config(RM7K_CONF_SE);
+
+ write_c0_taglo(0);
+ write_c0_taghi(0);
+
+ for (i = 0; i < scache_size; i += sc_lsize)
+ cache_op(Index_Store_Tag_SD, CKSEG0ADDR(i));
+}
+
+static __cpuinit void rm7k_sc_enable(void)
+{
+ if (read_c0_config() & RM7K_CONF_SE)
+ return;
+
+ pr_info("Enabling secondary cache...\n");
+ run_uncached(__rm7k_sc_enable);
+
+ if (rm7k_tcache_init)
+ rm7k_tc_enable();
+}
+
+static void rm7k_tc_disable(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ blast_rm7k_tcache();
+ clear_c0_config(RM7K_CONF_TE);
+ local_irq_save(flags);
+}
+
+static void rm7k_sc_disable(void)
+{
+ clear_c0_config(RM7K_CONF_SE);
+
+ if (rm7k_tcache_init)
+ rm7k_tc_disable();
+}
+
+static struct bcache_ops rm7k_sc_ops = {
+ .bc_enable = rm7k_sc_enable,
+ .bc_disable = rm7k_sc_disable,
+ .bc_wback_inv = rm7k_sc_wback_inv,
+ .bc_inv = rm7k_sc_inv
+};
+
+/*
+ * This is a probing function like the one found in c-r4k.c, we look for the
+ * wrap around point with different addresses.
+ */
+static __cpuinit void __probe_tcache(void)
+{
+ unsigned long flags, addr, begin, end, pow2;
+
+ begin = (unsigned long) &_stext;
+ begin &= ~((8 * 1024 * 1024) - 1);
+ end = begin + (8 * 1024 * 1024);
+
+ local_irq_save(flags);
+
+ set_c0_config(RM7K_CONF_TE);
+
+ /* Fill size-multiple lines with a valid tag */
+ pow2 = (256 * 1024);
+ for (addr = begin; addr <= end; addr = (begin + pow2)) {
+ unsigned long *p = (unsigned long *) addr;
+ __asm__ __volatile__("nop" : : "r" (*p));
+ pow2 <<= 1;
+ }
+
+ /* Load first line with a 0 tag, to check after */
+ write_c0_taglo(0);
+ write_c0_taghi(0);
+ cache_op(Index_Store_Tag_T, begin);
+
+ /* Look for the wrap-around */
+ pow2 = (512 * 1024);
+ for (addr = begin + (512 * 1024); addr <= end; addr = begin + pow2) {
+ cache_op(Index_Load_Tag_T, addr);
+ if (!read_c0_taglo())
+ break;
+ pow2 <<= 1;
+ }
+
+ addr -= begin;
+ tcache_size = addr;
+
+ clear_c0_config(RM7K_CONF_TE);
+
+ local_irq_restore(flags);
+}
+
+void __cpuinit rm7k_sc_init(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int config = read_c0_config();
+
+ if ((config & RM7K_CONF_SC))
+ return;
+
+ c->scache.linesz = sc_lsize;
+ c->scache.ways = 4;
+ c->scache.waybit= __ffs(scache_size / c->scache.ways);
+ c->scache.waysize = scache_size / c->scache.ways;
+ c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
+ printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
+ (scache_size >> 10), sc_lsize);
+
+ if (!(config & RM7K_CONF_SE))
+ rm7k_sc_enable();
+
+ bcops = &rm7k_sc_ops;
+
+ /*
+ * While we're at it let's deal with the tertiary cache.
+ */
+
+ rm7k_tcache_init = 0;
+ tcache_size = 0;
+
+ if (config & RM7K_CONF_TC)
+ return;
+
+ /*
+ * No efficient way to ask the hardware for the size of the tcache,
+ * so must probe for it.
+ */
+ run_uncached(__probe_tcache);
+ rm7k_tc_enable();
+ rm7k_tcache_init = 1;
+ c->tcache.linesz = tc_lsize;
+ c->tcache.ways = 1;
+ pr_info("Tertiary cache size %ldK.\n", (tcache_size >> 10));
+}
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c
new file mode 100644
index 00000000..40424aff
--- /dev/null
+++ b/arch/mips/mm/tlb-r3k.c
@@ -0,0 +1,284 @@
+/*
+ * r2300.c: R2000 and R3000 specific mmu/cache code.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ *
+ * with a lot of changes to make this thing work for R3000s
+ * Tx39XX R4k style caches added. HK
+ * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
+ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+ * Copyright (C) 2002 Ralf Baechle
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/isadep.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+
+#undef DEBUG_TLB
+
+extern void build_tlb_refill_handler(void);
+
+/* CP0 hazard avoidance. */
+#define BARRIER \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ "nop\n\t" \
+ ".set pop\n\t")
+
+int r3k_have_wired_reg; /* should be in cpu_data? */
+
+/* TLB operations. */
+void local_flush_tlb_all(void)
+{
+ unsigned long flags;
+ unsigned long old_ctx;
+ int entry;
+
+#ifdef DEBUG_TLB
+ printk("[tlball]");
+#endif
+
+ local_irq_save(flags);
+ old_ctx = read_c0_entryhi() & ASID_MASK;
+ write_c0_entrylo0(0);
+ entry = r3k_have_wired_reg ? read_c0_wired() : 8;
+ for (; entry < current_cpu_data.tlbsize; entry++) {
+ write_c0_index(entry << 8);
+ write_c0_entryhi((entry | 0x80000) << 12);
+ BARRIER;
+ tlb_write_indexed();
+ }
+ write_c0_entryhi(old_ctx);
+ local_irq_restore(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+ int cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0) {
+#ifdef DEBUG_TLB
+ printk("[tlbmm<%lu>]", (unsigned long)cpu_context(cpu, mm));
+#endif
+ drop_mmu_context(mm, cpu);
+ }
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ int cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0) {
+ unsigned long size, flags;
+
+#ifdef DEBUG_TLB
+ printk("[tlbrange<%lu,0x%08lx,0x%08lx>]",
+ cpu_context(cpu, mm) & ASID_MASK, start, end);
+#endif
+ local_irq_save(flags);
+ size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ if (size <= current_cpu_data.tlbsize) {
+ int oldpid = read_c0_entryhi() & ASID_MASK;
+ int newpid = cpu_context(cpu, mm) & ASID_MASK;
+
+ start &= PAGE_MASK;
+ end += PAGE_SIZE - 1;
+ end &= PAGE_MASK;
+ while (start < end) {
+ int idx;
+
+ write_c0_entryhi(start | newpid);
+ start += PAGE_SIZE; /* BARRIER */
+ tlb_probe();
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entryhi(KSEG0);
+ if (idx < 0) /* BARRIER */
+ continue;
+ tlb_write_indexed();
+ }
+ write_c0_entryhi(oldpid);
+ } else {
+ drop_mmu_context(mm, cpu);
+ }
+ local_irq_restore(flags);
+ }
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ unsigned long size, flags;
+
+#ifdef DEBUG_TLB
+ printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", start, end);
+#endif
+ local_irq_save(flags);
+ size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ if (size <= current_cpu_data.tlbsize) {
+ int pid = read_c0_entryhi();
+
+ start &= PAGE_MASK;
+ end += PAGE_SIZE - 1;
+ end &= PAGE_MASK;
+
+ while (start < end) {
+ int idx;
+
+ write_c0_entryhi(start);
+ start += PAGE_SIZE; /* BARRIER */
+ tlb_probe();
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entryhi(KSEG0);
+ if (idx < 0) /* BARRIER */
+ continue;
+ tlb_write_indexed();
+ }
+ write_c0_entryhi(pid);
+ } else {
+ local_flush_tlb_all();
+ }
+ local_irq_restore(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+ int cpu = smp_processor_id();
+
+ if (!vma || cpu_context(cpu, vma->vm_mm) != 0) {
+ unsigned long flags;
+ int oldpid, newpid, idx;
+
+#ifdef DEBUG_TLB
+ printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page);
+#endif
+ newpid = cpu_context(cpu, vma->vm_mm) & ASID_MASK;
+ page &= PAGE_MASK;
+ local_irq_save(flags);
+ oldpid = read_c0_entryhi() & ASID_MASK;
+ write_c0_entryhi(page | newpid);
+ BARRIER;
+ tlb_probe();
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entryhi(KSEG0);
+ if (idx < 0) /* BARRIER */
+ goto finish;
+ tlb_write_indexed();
+
+finish:
+ write_c0_entryhi(oldpid);
+ local_irq_restore(flags);
+ }
+}
+
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+ unsigned long flags;
+ int idx, pid;
+
+ /*
+ * Handle debugger faulting in for debugee.
+ */
+ if (current->active_mm != vma->vm_mm)
+ return;
+
+ pid = read_c0_entryhi() & ASID_MASK;
+
+#ifdef DEBUG_TLB
+ if ((pid != (cpu_context(cpu, vma->vm_mm) & ASID_MASK)) || (cpu_context(cpu, vma->vm_mm) == 0)) {
+ printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n",
+ (cpu_context(cpu, vma->vm_mm)), pid);
+ }
+#endif
+
+ local_irq_save(flags);
+ address &= PAGE_MASK;
+ write_c0_entryhi(address | pid);
+ BARRIER;
+ tlb_probe();
+ idx = read_c0_index();
+ write_c0_entrylo0(pte_val(pte));
+ write_c0_entryhi(address | pid);
+ if (idx < 0) { /* BARRIER */
+ tlb_write_random();
+ } else {
+ tlb_write_indexed();
+ }
+ write_c0_entryhi(pid);
+ local_irq_restore(flags);
+}
+
+void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+ unsigned long entryhi, unsigned long pagemask)
+{
+ unsigned long flags;
+ unsigned long old_ctx;
+ static unsigned long wired = 0;
+
+ if (r3k_have_wired_reg) { /* TX39XX */
+ unsigned long old_pagemask;
+ unsigned long w;
+
+#ifdef DEBUG_TLB
+ printk("[tlbwired<entry lo0 %8x, hi %8x\n, pagemask %8x>]\n",
+ entrylo0, entryhi, pagemask);
+#endif
+
+ local_irq_save(flags);
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi() & ASID_MASK;
+ old_pagemask = read_c0_pagemask();
+ w = read_c0_wired();
+ write_c0_wired(w + 1);
+ write_c0_index(w << 8);
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+ BARRIER;
+ tlb_write_indexed();
+
+ write_c0_entryhi(old_ctx);
+ write_c0_pagemask(old_pagemask);
+ local_flush_tlb_all();
+ local_irq_restore(flags);
+
+ } else if (wired < 8) {
+#ifdef DEBUG_TLB
+ printk("[tlbwired<entry lo0 %8x, hi %8x\n>]\n",
+ entrylo0, entryhi);
+#endif
+
+ local_irq_save(flags);
+ old_ctx = read_c0_entryhi() & ASID_MASK;
+ write_c0_entrylo0(entrylo0);
+ write_c0_entryhi(entryhi);
+ write_c0_index(wired);
+ wired++; /* BARRIER */
+ tlb_write_indexed();
+ write_c0_entryhi(old_ctx);
+ local_flush_tlb_all();
+ local_irq_restore(flags);
+ }
+}
+
+void __cpuinit tlb_init(void)
+{
+ local_flush_tlb_all();
+
+ build_tlb_refill_handler();
+}
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
new file mode 100644
index 00000000..ba40325c
--- /dev/null
+++ b/arch/mips/mm/tlb-r4k.c
@@ -0,0 +1,471 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+extern void build_tlb_refill_handler(void);
+
+/*
+ * Make sure all entries differ. If they're not different
+ * MIPS32 will take revenge ...
+ */
+#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+
+/* Atomicity and interruptability */
+#ifdef CONFIG_MIPS_MT_SMTC
+
+#include <asm/smtc.h>
+#include <asm/mipsmtregs.h>
+
+#define ENTER_CRITICAL(flags) \
+ { \
+ unsigned int mvpflags; \
+ local_irq_save(flags);\
+ mvpflags = dvpe()
+#define EXIT_CRITICAL(flags) \
+ evpe(mvpflags); \
+ local_irq_restore(flags); \
+ }
+#else
+
+#define ENTER_CRITICAL(flags) local_irq_save(flags)
+#define EXIT_CRITICAL(flags) local_irq_restore(flags)
+
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+#if defined(CONFIG_CPU_LOONGSON2)
+/*
+ * LOONGSON2 has a 4 entry itlb which is a subset of dtlb,
+ * unfortrunately, itlb is not totally transparent to software.
+ */
+#define FLUSH_ITLB write_c0_diag(4);
+
+#define FLUSH_ITLB_VM(vma) { if ((vma)->vm_flags & VM_EXEC) write_c0_diag(4); }
+
+#else
+
+#define FLUSH_ITLB
+#define FLUSH_ITLB_VM(vma)
+
+#endif
+
+void local_flush_tlb_all(void)
+{
+ unsigned long flags;
+ unsigned long old_ctx;
+ int entry;
+
+ ENTER_CRITICAL(flags);
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+
+ entry = read_c0_wired();
+
+ /* Blast 'em all away. */
+ while (entry < current_cpu_data.tlbsize) {
+ /* Make sure all entries differ. */
+ write_c0_entryhi(UNIQUE_ENTRYHI(entry));
+ write_c0_index(entry);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ entry++;
+ }
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+ FLUSH_ITLB;
+ EXIT_CRITICAL(flags);
+}
+
+/* All entries common to a mm share an asid. To effectively flush
+ these entries, we just bump the asid. */
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+ int cpu;
+
+ preempt_disable();
+
+ cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0) {
+ drop_mmu_context(mm, cpu);
+ }
+
+ preempt_enable();
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ int cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0) {
+ unsigned long size, flags;
+
+ ENTER_CRITICAL(flags);
+ size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ size = (size + 1) >> 1;
+ if (size <= current_cpu_data.tlbsize/2) {
+ int oldpid = read_c0_entryhi();
+ int newpid = cpu_asid(cpu, mm);
+
+ start &= (PAGE_MASK << 1);
+ end += ((PAGE_SIZE << 1) - 1);
+ end &= (PAGE_MASK << 1);
+ while (start < end) {
+ int idx;
+
+ write_c0_entryhi(start | newpid);
+ start += (PAGE_SIZE << 1);
+ mtc0_tlbw_hazard();
+ tlb_probe();
+ tlb_probe_hazard();
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+ if (idx < 0)
+ continue;
+ /* Make sure all entries differ. */
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ }
+ tlbw_use_hazard();
+ write_c0_entryhi(oldpid);
+ } else {
+ drop_mmu_context(mm, cpu);
+ }
+ FLUSH_ITLB;
+ EXIT_CRITICAL(flags);
+ }
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ unsigned long size, flags;
+
+ ENTER_CRITICAL(flags);
+ size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ size = (size + 1) >> 1;
+ if (size <= current_cpu_data.tlbsize / 2) {
+ int pid = read_c0_entryhi();
+
+ start &= (PAGE_MASK << 1);
+ end += ((PAGE_SIZE << 1) - 1);
+ end &= (PAGE_MASK << 1);
+
+ while (start < end) {
+ int idx;
+
+ write_c0_entryhi(start);
+ start += (PAGE_SIZE << 1);
+ mtc0_tlbw_hazard();
+ tlb_probe();
+ tlb_probe_hazard();
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+ if (idx < 0)
+ continue;
+ /* Make sure all entries differ. */
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ }
+ tlbw_use_hazard();
+ write_c0_entryhi(pid);
+ } else {
+ local_flush_tlb_all();
+ }
+ FLUSH_ITLB;
+ EXIT_CRITICAL(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+ int cpu = smp_processor_id();
+
+ if (cpu_context(cpu, vma->vm_mm) != 0) {
+ unsigned long flags;
+ int oldpid, newpid, idx;
+
+ newpid = cpu_asid(cpu, vma->vm_mm);
+ page &= (PAGE_MASK << 1);
+ ENTER_CRITICAL(flags);
+ oldpid = read_c0_entryhi();
+ write_c0_entryhi(page | newpid);
+ mtc0_tlbw_hazard();
+ tlb_probe();
+ tlb_probe_hazard();
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+ if (idx < 0)
+ goto finish;
+ /* Make sure all entries differ. */
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ tlbw_use_hazard();
+
+ finish:
+ write_c0_entryhi(oldpid);
+ FLUSH_ITLB_VM(vma);
+ EXIT_CRITICAL(flags);
+ }
+}
+
+/*
+ * This one is only used for pages with the global bit set so we don't care
+ * much about the ASID.
+ */
+void local_flush_tlb_one(unsigned long page)
+{
+ unsigned long flags;
+ int oldpid, idx;
+
+ ENTER_CRITICAL(flags);
+ oldpid = read_c0_entryhi();
+ page &= (PAGE_MASK << 1);
+ write_c0_entryhi(page);
+ mtc0_tlbw_hazard();
+ tlb_probe();
+ tlb_probe_hazard();
+ idx = read_c0_index();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
+ if (idx >= 0) {
+ /* Make sure all entries differ. */
+ write_c0_entryhi(UNIQUE_ENTRYHI(idx));
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ tlbw_use_hazard();
+ }
+ write_c0_entryhi(oldpid);
+ FLUSH_ITLB;
+ EXIT_CRITICAL(flags);
+}
+
+/*
+ * We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
+{
+ unsigned long flags;
+ pgd_t *pgdp;
+ pud_t *pudp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+ int idx, pid;
+
+ /*
+ * Handle debugger faulting in for debugee.
+ */
+ if (current->active_mm != vma->vm_mm)
+ return;
+
+ ENTER_CRITICAL(flags);
+
+ pid = read_c0_entryhi() & ASID_MASK;
+ address &= (PAGE_MASK << 1);
+ write_c0_entryhi(address | pid);
+ pgdp = pgd_offset(vma->vm_mm, address);
+ mtc0_tlbw_hazard();
+ tlb_probe();
+ tlb_probe_hazard();
+ pudp = pud_offset(pgdp, address);
+ pmdp = pmd_offset(pudp, address);
+ idx = read_c0_index();
+#ifdef CONFIG_HUGETLB_PAGE
+ /* this could be a huge page */
+ if (pmd_huge(*pmdp)) {
+ unsigned long lo;
+ write_c0_pagemask(PM_HUGE_MASK);
+ ptep = (pte_t *)pmdp;
+ lo = pte_to_entrylo(pte_val(*ptep));
+ write_c0_entrylo0(lo);
+ write_c0_entrylo1(lo + (HPAGE_SIZE >> 7));
+
+ mtc0_tlbw_hazard();
+ if (idx < 0)
+ tlb_write_random();
+ else
+ tlb_write_indexed();
+ write_c0_pagemask(PM_DEFAULT_MASK);
+ } else
+#endif
+ {
+ ptep = pte_offset_map(pmdp, address);
+
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+ write_c0_entrylo0(ptep->pte_high);
+ ptep++;
+ write_c0_entrylo1(ptep->pte_high);
+#else
+ write_c0_entrylo0(pte_to_entrylo(pte_val(*ptep++)));
+ write_c0_entrylo1(pte_to_entrylo(pte_val(*ptep)));
+#endif
+ mtc0_tlbw_hazard();
+ if (idx < 0)
+ tlb_write_random();
+ else
+ tlb_write_indexed();
+ }
+ tlbw_use_hazard();
+ FLUSH_ITLB_VM(vma);
+ EXIT_CRITICAL(flags);
+}
+
+void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+ unsigned long entryhi, unsigned long pagemask)
+{
+ unsigned long flags;
+ unsigned long wired;
+ unsigned long old_pagemask;
+ unsigned long old_ctx;
+
+ ENTER_CRITICAL(flags);
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi();
+ old_pagemask = read_c0_pagemask();
+ wired = read_c0_wired();
+ write_c0_wired(wired + 1);
+ write_c0_index(wired);
+ tlbw_use_hazard(); /* What is the hazard here? */
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+ write_c0_entrylo1(entrylo1);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ tlbw_use_hazard();
+
+ write_c0_entryhi(old_ctx);
+ tlbw_use_hazard(); /* What is the hazard here? */
+ write_c0_pagemask(old_pagemask);
+ local_flush_tlb_all();
+ EXIT_CRITICAL(flags);
+}
+
+/*
+ * Used for loading TLB entries before trap_init() has started, when we
+ * don't actually want to add a wired entry which remains throughout the
+ * lifetime of the system
+ */
+
+static int temp_tlb_entry __cpuinitdata;
+
+__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
+ unsigned long entryhi, unsigned long pagemask)
+{
+ int ret = 0;
+ unsigned long flags;
+ unsigned long wired;
+ unsigned long old_pagemask;
+ unsigned long old_ctx;
+
+ ENTER_CRITICAL(flags);
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi();
+ old_pagemask = read_c0_pagemask();
+ wired = read_c0_wired();
+ if (--temp_tlb_entry < wired) {
+ printk(KERN_WARNING
+ "No TLB space left for add_temporary_entry\n");
+ ret = -ENOSPC;
+ goto out;
+ }
+
+ write_c0_index(temp_tlb_entry);
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+ write_c0_entrylo1(entrylo1);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
+ tlbw_use_hazard();
+
+ write_c0_entryhi(old_ctx);
+ write_c0_pagemask(old_pagemask);
+out:
+ EXIT_CRITICAL(flags);
+ return ret;
+}
+
+static int __cpuinitdata ntlb;
+static int __init set_ntlb(char *str)
+{
+ get_option(&str, &ntlb);
+ return 1;
+}
+
+__setup("ntlb=", set_ntlb);
+
+void __cpuinit tlb_init(void)
+{
+ /*
+ * You should never change this register:
+ * - On R4600 1.7 the tlbp never hits for pages smaller than
+ * the value in the c0_pagemask register.
+ * - The entire mm handling assumes the c0_pagemask register to
+ * be set to fixed-size pages.
+ */
+ write_c0_pagemask(PM_DEFAULT_MASK);
+ write_c0_wired(0);
+ if (current_cpu_type() == CPU_R10000 ||
+ current_cpu_type() == CPU_R12000 ||
+ current_cpu_type() == CPU_R14000)
+ write_c0_framemask(0);
+
+ if (kernel_uses_smartmips_rixi) {
+ /*
+ * Enable the no read, no exec bits, and enable large virtual
+ * address.
+ */
+ u32 pg = PG_RIE | PG_XIE;
+#ifdef CONFIG_64BIT
+ pg |= PG_ELPA;
+#endif
+ write_c0_pagegrain(pg);
+ }
+
+ temp_tlb_entry = current_cpu_data.tlbsize - 1;
+
+ /* From this point on the ARC firmware is dead. */
+ local_flush_tlb_all();
+
+ /* Did I tell you that ARC SUCKS? */
+
+ if (ntlb) {
+ if (ntlb > 1 && ntlb <= current_cpu_data.tlbsize) {
+ int wired = current_cpu_data.tlbsize - ntlb;
+ write_c0_wired(wired);
+ write_c0_index(wired-1);
+ printk("Restricting TLB to %d entries\n", ntlb);
+ } else
+ printk("Ignoring invalid argument ntlb=%d\n", ntlb);
+ }
+
+ build_tlb_refill_handler();
+}
diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c
new file mode 100644
index 00000000..3d95f76c
--- /dev/null
+++ b/arch/mips/mm/tlb-r8k.c
@@ -0,0 +1,249 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+extern void build_tlb_refill_handler(void);
+
+#define TFP_TLB_SIZE 384
+#define TFP_TLB_SET_SHIFT 7
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+ "nop; nop; nop; nop; nop; nop;\n\t" \
+ ".set reorder\n\t")
+
+void local_flush_tlb_all(void)
+{
+ unsigned long flags;
+ unsigned long old_ctx;
+ int entry;
+
+ local_irq_save(flags);
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi();
+ write_c0_entrylo(0);
+
+ for (entry = 0; entry < TFP_TLB_SIZE; entry++) {
+ write_c0_tlbset(entry >> TFP_TLB_SET_SHIFT);
+ write_c0_vaddr(entry << PAGE_SHIFT);
+ write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
+ mtc0_tlbw_hazard();
+ tlb_write();
+ }
+ tlbw_use_hazard();
+ write_c0_entryhi(old_ctx);
+ local_irq_restore(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+ int cpu = smp_processor_id();
+
+ if (cpu_context(cpu, mm) != 0)
+ drop_mmu_context(mm, cpu);
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ int cpu = smp_processor_id();
+ unsigned long flags;
+ int oldpid, newpid, size;
+
+ if (!cpu_context(cpu, mm))
+ return;
+
+ size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ size = (size + 1) >> 1;
+
+ local_irq_save(flags);
+
+ if (size > TFP_TLB_SIZE / 2) {
+ drop_mmu_context(mm, cpu);
+ goto out_restore;
+ }
+
+ oldpid = read_c0_entryhi();
+ newpid = cpu_asid(cpu, mm);
+
+ write_c0_entrylo(0);
+
+ start &= PAGE_MASK;
+ end += (PAGE_SIZE - 1);
+ end &= PAGE_MASK;
+ while (start < end) {
+ signed long idx;
+
+ write_c0_vaddr(start);
+ write_c0_entryhi(start);
+ start += PAGE_SIZE;
+ tlb_probe();
+ idx = read_c0_tlbset();
+ if (idx < 0)
+ continue;
+
+ write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ tlb_write();
+ }
+ write_c0_entryhi(oldpid);
+
+out_restore:
+ local_irq_restore(flags);
+}
+
+/* Usable for KV1 addresses only! */
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ unsigned long size, flags;
+
+ size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ size = (size + 1) >> 1;
+
+ if (size > TFP_TLB_SIZE / 2) {
+ local_flush_tlb_all();
+ return;
+ }
+
+ local_irq_save(flags);
+
+ write_c0_entrylo(0);
+
+ start &= PAGE_MASK;
+ end += (PAGE_SIZE - 1);
+ end &= PAGE_MASK;
+ while (start < end) {
+ signed long idx;
+
+ write_c0_vaddr(start);
+ write_c0_entryhi(start);
+ start += PAGE_SIZE;
+ tlb_probe();
+ idx = read_c0_tlbset();
+ if (idx < 0)
+ continue;
+
+ write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ tlb_write();
+ }
+
+ local_irq_restore(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+ int cpu = smp_processor_id();
+ unsigned long flags;
+ int oldpid, newpid;
+ signed long idx;
+
+ if (!cpu_context(cpu, vma->vm_mm))
+ return;
+
+ newpid = cpu_asid(cpu, vma->vm_mm);
+ page &= PAGE_MASK;
+ local_irq_save(flags);
+ oldpid = read_c0_entryhi();
+ write_c0_vaddr(page);
+ write_c0_entryhi(newpid);
+ tlb_probe();
+ idx = read_c0_tlbset();
+ if (idx < 0)
+ goto finish;
+
+ write_c0_entrylo(0);
+ write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1)));
+ tlb_write();
+
+finish:
+ write_c0_entryhi(oldpid);
+ local_irq_restore(flags);
+}
+
+/*
+ * We will need multiple versions of update_mmu_cache(), one that just
+ * updates the TLB with the new pte(s), and another which also checks
+ * for the R4k "end of page" hardware bug and does the needy.
+ */
+void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
+{
+ unsigned long flags;
+ pgd_t *pgdp;
+ pmd_t *pmdp;
+ pte_t *ptep;
+ int pid;
+
+ /*
+ * Handle debugger faulting in for debugee.
+ */
+ if (current->active_mm != vma->vm_mm)
+ return;
+
+ pid = read_c0_entryhi() & ASID_MASK;
+
+ local_irq_save(flags);
+ address &= PAGE_MASK;
+ write_c0_vaddr(address);
+ write_c0_entryhi(pid);
+ pgdp = pgd_offset(vma->vm_mm, address);
+ pmdp = pmd_offset(pgdp, address);
+ ptep = pte_offset_map(pmdp, address);
+ tlb_probe();
+
+ write_c0_entrylo(pte_val(*ptep++) >> 6);
+ tlb_write();
+
+ write_c0_entryhi(pid);
+ local_irq_restore(flags);
+}
+
+static void __cpuinit probe_tlb(unsigned long config)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ c->tlbsize = 3 * 128; /* 3 sets each 128 entries */
+}
+
+void __cpuinit tlb_init(void)
+{
+ unsigned int config = read_c0_config();
+ unsigned long status;
+
+ probe_tlb(config);
+
+ status = read_c0_status();
+ status &= ~(ST0_UPS | ST0_KPS);
+#ifdef CONFIG_PAGE_SIZE_4KB
+ status |= (TFP_PAGESIZE_4K << 32) | (TFP_PAGESIZE_4K << 36);
+#elif defined(CONFIG_PAGE_SIZE_8KB)
+ status |= (TFP_PAGESIZE_8K << 32) | (TFP_PAGESIZE_8K << 36);
+#elif defined(CONFIG_PAGE_SIZE_16KB)
+ status |= (TFP_PAGESIZE_16K << 32) | (TFP_PAGESIZE_16K << 36);
+#elif defined(CONFIG_PAGE_SIZE_64KB)
+ status |= (TFP_PAGESIZE_64K << 32) | (TFP_PAGESIZE_64K << 36);
+#endif
+ write_c0_status(status);
+
+ write_c0_wired(0);
+
+ local_flush_tlb_all();
+
+ build_tlb_refill_handler();
+}
diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S
new file mode 100644
index 00000000..e99eaa1f
--- /dev/null
+++ b/arch/mips/mm/tlbex-fault.S
@@ -0,0 +1,28 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ */
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+ .macro tlb_do_page_fault, write
+ NESTED(tlb_do_page_fault_\write, PT_SIZE, sp)
+ SAVE_ALL
+ MFC0 a2, CP0_BADVADDR
+ KMODE
+ move a0, sp
+ REG_S a2, PT_BVADDR(sp)
+ li a1, \write
+ PTR_LA ra, ret_from_exception
+ j do_page_fault
+ END(tlb_do_page_fault_\write)
+ .endm
+
+ tlb_do_page_fault 0
+ tlb_do_page_fault 1
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
new file mode 100644
index 00000000..424ed4b9
--- /dev/null
+++ b/arch/mips/mm/tlbex.c
@@ -0,0 +1,2063 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Synthesize TLB refill handlers at runtime.
+ *
+ * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
+ * Copyright (C) 2005, 2007, 2008, 2009 Maciej W. Rozycki
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2008, 2009 Cavium Networks, Inc.
+ *
+ * ... and the days got worse and worse and now you see
+ * I've gone completly out of my mind.
+ *
+ * They're coming to take me a away haha
+ * they're coming to take me a away hoho hihi haha
+ * to the funny farm where code is beautiful all the time ...
+ *
+ * (Condolences to Napoleon XIV)
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/smp.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/cache.h>
+
+#include <asm/cacheflush.h>
+#include <asm/pgtable.h>
+#include <asm/war.h>
+#include <asm/uasm.h>
+
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
+
+
+static inline int r45k_bvahwbug(void)
+{
+ /* XXX: We should probe for the presence of this bug, but we don't. */
+ return 0;
+}
+
+static inline int r4k_250MHZhwbug(void)
+{
+ /* XXX: We should probe for the presence of this bug, but we don't. */
+ return 0;
+}
+
+static inline int __maybe_unused bcm1250_m3_war(void)
+{
+ return BCM1250_M3_WAR;
+}
+
+static inline int __maybe_unused r10000_llsc_war(void)
+{
+ return R10000_LLSC_WAR;
+}
+
+static int use_bbit_insns(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_CAVIUM_OCTEON:
+ case CPU_CAVIUM_OCTEON_PLUS:
+ case CPU_CAVIUM_OCTEON2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int use_lwx_insns(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_CAVIUM_OCTEON2:
+ return 1;
+ default:
+ return 0;
+ }
+}
+#if defined(CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE) && \
+ CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
+static bool scratchpad_available(void)
+{
+ return true;
+}
+static int scratchpad_offset(int i)
+{
+ /*
+ * CVMSEG starts at address -32768 and extends for
+ * CAVIUM_OCTEON_CVMSEG_SIZE 128 byte cache lines.
+ */
+ i += 1; /* Kernel use starts at the top and works down. */
+ return CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128 - (8 * i) - 32768;
+}
+#else
+static bool scratchpad_available(void)
+{
+ return false;
+}
+static int scratchpad_offset(int i)
+{
+ BUG();
+ /* Really unreachable, but evidently some GCC want this. */
+ return 0;
+}
+#endif
+/*
+ * Found by experiment: At least some revisions of the 4kc throw under
+ * some circumstances a machine check exception, triggered by invalid
+ * values in the index register. Delaying the tlbp instruction until
+ * after the next branch, plus adding an additional nop in front of
+ * tlbwi/tlbwr avoids the invalid index register values. Nobody knows
+ * why; it's not an issue caused by the core RTL.
+ *
+ */
+static int __cpuinit m4kc_tlbp_war(void)
+{
+ return (current_cpu_data.processor_id & 0xffff00) ==
+ (PRID_COMP_MIPS | PRID_IMP_4KC);
+}
+
+/* Handle labels (which must be positive integers). */
+enum label_id {
+ label_second_part = 1,
+ label_leave,
+ label_vmalloc,
+ label_vmalloc_done,
+ label_tlbw_hazard,
+ label_split,
+ label_tlbl_goaround1,
+ label_tlbl_goaround2,
+ label_nopage_tlbl,
+ label_nopage_tlbs,
+ label_nopage_tlbm,
+ label_smp_pgtable_change,
+ label_r3000_write_probe_fail,
+ label_large_segbits_fault,
+#ifdef CONFIG_HUGETLB_PAGE
+ label_tlb_huge_update,
+#endif
+};
+
+UASM_L_LA(_second_part)
+UASM_L_LA(_leave)
+UASM_L_LA(_vmalloc)
+UASM_L_LA(_vmalloc_done)
+UASM_L_LA(_tlbw_hazard)
+UASM_L_LA(_split)
+UASM_L_LA(_tlbl_goaround1)
+UASM_L_LA(_tlbl_goaround2)
+UASM_L_LA(_nopage_tlbl)
+UASM_L_LA(_nopage_tlbs)
+UASM_L_LA(_nopage_tlbm)
+UASM_L_LA(_smp_pgtable_change)
+UASM_L_LA(_r3000_write_probe_fail)
+UASM_L_LA(_large_segbits_fault)
+#ifdef CONFIG_HUGETLB_PAGE
+UASM_L_LA(_tlb_huge_update)
+#endif
+
+/*
+ * For debug purposes.
+ */
+static inline void dump_handler(const u32 *handler, int count)
+{
+ int i;
+
+ pr_debug("\t.set push\n");
+ pr_debug("\t.set noreorder\n");
+
+ for (i = 0; i < count; i++)
+ pr_debug("\t%p\t.word 0x%08x\n", &handler[i], handler[i]);
+
+ pr_debug("\t.set pop\n");
+}
+
+/* The only general purpose registers allowed in TLB handlers. */
+#define K0 26
+#define K1 27
+
+/* Some CP0 registers */
+#define C0_INDEX 0, 0
+#define C0_ENTRYLO0 2, 0
+#define C0_TCBIND 2, 2
+#define C0_ENTRYLO1 3, 0
+#define C0_CONTEXT 4, 0
+#define C0_PAGEMASK 5, 0
+#define C0_BADVADDR 8, 0
+#define C0_ENTRYHI 10, 0
+#define C0_EPC 14, 0
+#define C0_XCONTEXT 20, 0
+
+#ifdef CONFIG_64BIT
+# define GET_CONTEXT(buf, reg) UASM_i_MFC0(buf, reg, C0_XCONTEXT)
+#else
+# define GET_CONTEXT(buf, reg) UASM_i_MFC0(buf, reg, C0_CONTEXT)
+#endif
+
+/* The worst case length of the handler is around 18 instructions for
+ * R3000-style TLBs and up to 63 instructions for R4000-style TLBs.
+ * Maximum space available is 32 instructions for R3000 and 64
+ * instructions for R4000.
+ *
+ * We deliberately chose a buffer size of 128, so we won't scribble
+ * over anything important on overflow before we panic.
+ */
+static u32 tlb_handler[128] __cpuinitdata;
+
+/* simply assume worst case size for labels and relocs */
+static struct uasm_label labels[128] __cpuinitdata;
+static struct uasm_reloc relocs[128] __cpuinitdata;
+
+#ifdef CONFIG_64BIT
+static int check_for_high_segbits __cpuinitdata;
+#endif
+
+static int check_for_high_segbits __cpuinitdata;
+
+static unsigned int kscratch_used_mask __cpuinitdata;
+
+static int __cpuinit allocate_kscratch(void)
+{
+ int r;
+ unsigned int a = cpu_data[0].kscratch_mask & ~kscratch_used_mask;
+
+ r = ffs(a);
+
+ if (r == 0)
+ return -1;
+
+ r--; /* make it zero based */
+
+ kscratch_used_mask |= (1 << r);
+
+ return r;
+}
+
+static int scratch_reg __cpuinitdata;
+static int pgd_reg __cpuinitdata;
+enum vmalloc64_mode {not_refill, refill_scratch, refill_noscratch};
+
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+
+/*
+ * CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
+ * we cannot do r3000 under these circumstances.
+ *
+ * Declare pgd_current here instead of including mmu_context.h to avoid type
+ * conflicts for tlbmiss_handler_setup_pgd
+ */
+extern unsigned long pgd_current[];
+
+/*
+ * The R3000 TLB handler is simple.
+ */
+static void __cpuinit build_r3000_tlb_refill_handler(void)
+{
+ long pgdc = (long)pgd_current;
+ u32 *p;
+
+ memset(tlb_handler, 0, sizeof(tlb_handler));
+ p = tlb_handler;
+
+ uasm_i_mfc0(&p, K0, C0_BADVADDR);
+ uasm_i_lui(&p, K1, uasm_rel_hi(pgdc)); /* cp0 delay */
+ uasm_i_lw(&p, K1, uasm_rel_lo(pgdc), K1);
+ uasm_i_srl(&p, K0, K0, 22); /* load delay */
+ uasm_i_sll(&p, K0, K0, 2);
+ uasm_i_addu(&p, K1, K1, K0);
+ uasm_i_mfc0(&p, K0, C0_CONTEXT);
+ uasm_i_lw(&p, K1, 0, K1); /* cp0 delay */
+ uasm_i_andi(&p, K0, K0, 0xffc); /* load delay */
+ uasm_i_addu(&p, K1, K1, K0);
+ uasm_i_lw(&p, K0, 0, K1);
+ uasm_i_nop(&p); /* load delay */
+ uasm_i_mtc0(&p, K0, C0_ENTRYLO0);
+ uasm_i_mfc0(&p, K1, C0_EPC); /* cp0 delay */
+ uasm_i_tlbwr(&p); /* cp0 delay */
+ uasm_i_jr(&p, K1);
+ uasm_i_rfe(&p); /* branch delay */
+
+ if (p > tlb_handler + 32)
+ panic("TLB refill handler space exceeded");
+
+ pr_debug("Wrote TLB refill handler (%u instructions).\n",
+ (unsigned int)(p - tlb_handler));
+
+ memcpy((void *)ebase, tlb_handler, 0x80);
+
+ dump_handler((u32 *)ebase, 32);
+}
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
+
+/*
+ * The R4000 TLB handler is much more complicated. We have two
+ * consecutive handler areas with 32 instructions space each.
+ * Since they aren't used at the same time, we can overflow in the
+ * other one.To keep things simple, we first assume linear space,
+ * then we relocate it to the final handler layout as needed.
+ */
+static u32 final_handler[64] __cpuinitdata;
+
+/*
+ * Hazards
+ *
+ * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
+ * 2. A timing hazard exists for the TLBP instruction.
+ *
+ * stalling_instruction
+ * TLBP
+ *
+ * The JTLB is being read for the TLBP throughout the stall generated by the
+ * previous instruction. This is not really correct as the stalling instruction
+ * can modify the address used to access the JTLB. The failure symptom is that
+ * the TLBP instruction will use an address created for the stalling instruction
+ * and not the address held in C0_ENHI and thus report the wrong results.
+ *
+ * The software work-around is to not allow the instruction preceding the TLBP
+ * to stall - make it an NOP or some other instruction guaranteed not to stall.
+ *
+ * Errata 2 will not be fixed. This errata is also on the R5000.
+ *
+ * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
+ */
+static void __cpuinit __maybe_unused build_tlb_probe_entry(u32 **p)
+{
+ switch (current_cpu_type()) {
+ /* Found by experiment: R4600 v2.0/R4700 needs this, too. */
+ case CPU_R4600:
+ case CPU_R4700:
+ case CPU_R5000:
+ case CPU_R5000A:
+ case CPU_NEVADA:
+ uasm_i_nop(p);
+ uasm_i_tlbp(p);
+ break;
+
+ default:
+ uasm_i_tlbp(p);
+ break;
+ }
+}
+
+/*
+ * Write random or indexed TLB entry, and care about the hazards from
+ * the preceding mtc0 and for the following eret.
+ */
+enum tlb_write_entry { tlb_random, tlb_indexed };
+
+static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r,
+ enum tlb_write_entry wmode)
+{
+ void(*tlbw)(u32 **) = NULL;
+
+ switch (wmode) {
+ case tlb_random: tlbw = uasm_i_tlbwr; break;
+ case tlb_indexed: tlbw = uasm_i_tlbwi; break;
+ }
+
+ if (cpu_has_mips_r2) {
+ if (cpu_has_mips_r2_exec_hazard)
+ uasm_i_ehb(p);
+ tlbw(p);
+ return;
+ }
+
+ switch (current_cpu_type()) {
+ case CPU_R4000PC:
+ case CPU_R4000SC:
+ case CPU_R4000MC:
+ case CPU_R4400PC:
+ case CPU_R4400SC:
+ case CPU_R4400MC:
+ /*
+ * This branch uses up a mtc0 hazard nop slot and saves
+ * two nops after the tlbw instruction.
+ */
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
+ tlbw(p);
+ uasm_l_tlbw_hazard(l, *p);
+ uasm_i_nop(p);
+ break;
+
+ case CPU_R4600:
+ case CPU_R4700:
+ case CPU_R5000:
+ case CPU_R5000A:
+ uasm_i_nop(p);
+ tlbw(p);
+ uasm_i_nop(p);
+ break;
+
+ case CPU_R4300:
+ case CPU_5KC:
+ case CPU_TX49XX:
+ case CPU_PR4450:
+ case CPU_XLR:
+ uasm_i_nop(p);
+ tlbw(p);
+ break;
+
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_R14000:
+ case CPU_4KC:
+ case CPU_4KEC:
+ case CPU_SB1:
+ case CPU_SB1A:
+ case CPU_4KSC:
+ case CPU_20KC:
+ case CPU_25KF:
+ case CPU_BMIPS32:
+ case CPU_BMIPS3300:
+ case CPU_BMIPS4350:
+ case CPU_BMIPS4380:
+ case CPU_BMIPS5000:
+ case CPU_LOONGSON2:
+ case CPU_R5500:
+ if (m4kc_tlbp_war())
+ uasm_i_nop(p);
+ case CPU_ALCHEMY:
+ tlbw(p);
+ break;
+
+ case CPU_NEVADA:
+ uasm_i_nop(p); /* QED specifies 2 nops hazard */
+ /*
+ * This branch uses up a mtc0 hazard nop slot and saves
+ * a nop after the tlbw instruction.
+ */
+ uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
+ tlbw(p);
+ uasm_l_tlbw_hazard(l, *p);
+ break;
+
+ case CPU_RM7000:
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ tlbw(p);
+ break;
+
+ case CPU_RM9000:
+ /*
+ * When the JTLB is updated by tlbwi or tlbwr, a subsequent
+ * use of the JTLB for instructions should not occur for 4
+ * cpu cycles and use for data translations should not occur
+ * for 3 cpu cycles.
+ */
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ tlbw(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ uasm_i_ssnop(p);
+ break;
+
+ case CPU_VR4111:
+ case CPU_VR4121:
+ case CPU_VR4122:
+ case CPU_VR4181:
+ case CPU_VR4181A:
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ tlbw(p);
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ break;
+
+ case CPU_VR4131:
+ case CPU_VR4133:
+ case CPU_R5432:
+ uasm_i_nop(p);
+ uasm_i_nop(p);
+ tlbw(p);
+ break;
+
+ case CPU_JZRISC:
+ tlbw(p);
+ uasm_i_nop(p);
+ break;
+
+ default:
+ panic("No TLB refill handler yet (CPU type: %d)",
+ current_cpu_data.cputype);
+ break;
+ }
+}
+
+static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
+ unsigned int reg)
+{
+ if (kernel_uses_smartmips_rixi) {
+ UASM_i_SRL(p, reg, reg, ilog2(_PAGE_NO_EXEC));
+ UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ } else {
+#ifdef CONFIG_64BIT_PHYS_ADDR
+ uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
+#else
+ UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL));
+#endif
+ }
+}
+
+#ifdef CONFIG_HUGETLB_PAGE
+
+static __cpuinit void build_restore_pagemask(u32 **p,
+ struct uasm_reloc **r,
+ unsigned int tmp,
+ enum label_id lid,
+ int restore_scratch)
+{
+ if (restore_scratch) {
+ /* Reset default page size */
+ if (PM_DEFAULT_MASK >> 16) {
+ uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
+ uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ } else if (PM_DEFAULT_MASK) {
+ uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ } else {
+ uasm_i_mtc0(p, 0, C0_PAGEMASK);
+ uasm_il_b(p, r, lid);
+ }
+ if (scratch_reg > 0)
+ UASM_i_MFC0(p, 1, 31, scratch_reg);
+ else
+ UASM_i_LW(p, 1, scratchpad_offset(0), 0);
+ } else {
+ /* Reset default page size */
+ if (PM_DEFAULT_MASK >> 16) {
+ uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
+ uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ } else if (PM_DEFAULT_MASK) {
+ uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+ } else {
+ uasm_il_b(p, r, lid);
+ uasm_i_mtc0(p, 0, C0_PAGEMASK);
+ }
+ }
+}
+
+static __cpuinit void build_huge_tlb_write_entry(u32 **p,
+ struct uasm_label **l,
+ struct uasm_reloc **r,
+ unsigned int tmp,
+ enum tlb_write_entry wmode,
+ int restore_scratch)
+{
+ /* Set huge page tlb entry size */
+ uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16);
+ uasm_i_ori(p, tmp, tmp, PM_HUGE_MASK & 0xffff);
+ uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+
+ build_tlb_write_entry(p, l, r, wmode);
+
+ build_restore_pagemask(p, r, tmp, label_leave, restore_scratch);
+}
+
+/*
+ * Check if Huge PTE is present, if so then jump to LABEL.
+ */
+static void __cpuinit
+build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,
+ unsigned int pmd, int lid)
+{
+ UASM_i_LW(p, tmp, 0, pmd);
+ if (use_bbit_insns()) {
+ uasm_il_bbit1(p, r, tmp, ilog2(_PAGE_HUGE), lid);
+ } else {
+ uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
+ uasm_il_bnez(p, r, tmp, lid);
+ }
+}
+
+static __cpuinit void build_huge_update_entries(u32 **p,
+ unsigned int pte,
+ unsigned int tmp)
+{
+ int small_sequence;
+
+ /*
+ * A huge PTE describes an area the size of the
+ * configured huge page size. This is twice the
+ * of the large TLB entry size we intend to use.
+ * A TLB entry half the size of the configured
+ * huge page size is configured into entrylo0
+ * and entrylo1 to cover the contiguous huge PTE
+ * address space.
+ */
+ small_sequence = (HPAGE_SIZE >> 7) < 0x10000;
+
+ /* We can clobber tmp. It isn't used after this.*/
+ if (!small_sequence)
+ uasm_i_lui(p, tmp, HPAGE_SIZE >> (7 + 16));
+
+ build_convert_pte_to_entrylo(p, pte);
+ UASM_i_MTC0(p, pte, C0_ENTRYLO0); /* load it */
+ /* convert to entrylo1 */
+ if (small_sequence)
+ UASM_i_ADDIU(p, pte, pte, HPAGE_SIZE >> 7);
+ else
+ UASM_i_ADDU(p, pte, pte, tmp);
+
+ UASM_i_MTC0(p, pte, C0_ENTRYLO1); /* load it */
+}
+
+static __cpuinit void build_huge_handler_tail(u32 **p,
+ struct uasm_reloc **r,
+ struct uasm_label **l,
+ unsigned int pte,
+ unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+ UASM_i_SC(p, pte, 0, ptr);
+ uasm_il_beqz(p, r, pte, label_tlb_huge_update);
+ UASM_i_LW(p, pte, 0, ptr); /* Needed because SC killed our PTE */
+#else
+ UASM_i_SW(p, pte, 0, ptr);
+#endif
+ build_huge_update_entries(p, pte, ptr);
+ build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed, 0);
+}
+#endif /* CONFIG_HUGETLB_PAGE */
+
+#ifdef CONFIG_64BIT
+/*
+ * TMP and PTR are scratch.
+ * TMP will be clobbered, PTR will hold the pmd entry.
+ */
+static void __cpuinit
+build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
+ unsigned int tmp, unsigned int ptr)
+{
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+ long pgdc = (long)pgd_current;
+#endif
+ /*
+ * The vmalloc handling is not in the hotpath.
+ */
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR);
+
+ if (check_for_high_segbits) {
+ /*
+ * The kernel currently implicitely assumes that the
+ * MIPS SEGBITS parameter for the processor is
+ * (PGDIR_SHIFT+PGDIR_BITS) or less, and will never
+ * allocate virtual addresses outside the maximum
+ * range for SEGBITS = (PGDIR_SHIFT+PGDIR_BITS). But
+ * that doesn't prevent user code from accessing the
+ * higher xuseg addresses. Here, we make sure that
+ * everything but the lower xuseg addresses goes down
+ * the module_alloc/vmalloc path.
+ */
+ uasm_i_dsrl_safe(p, ptr, tmp, PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+ uasm_il_bnez(p, r, ptr, label_vmalloc);
+ } else {
+ uasm_il_bltz(p, r, tmp, label_vmalloc);
+ }
+ /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
+
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+ if (pgd_reg != -1) {
+ /* pgd is in pgd_reg */
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ } else {
+ /*
+ * &pgd << 11 stored in CONTEXT [23..63].
+ */
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+
+ /* 1 0 1 0 1 << 6 xkphys cached */
+ uasm_i_ori(p, ptr, ptr, 0x540);
+ uasm_i_drotr(p, ptr, ptr, 11);
+ }
+#elif defined(CONFIG_SMP)
+# ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC uses TCBind value as "CPU" index
+ */
+ uasm_i_mfc0(p, ptr, C0_TCBIND);
+ uasm_i_dsrl_safe(p, ptr, ptr, 19);
+# else
+ /*
+ * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
+ * stored in CONTEXT.
+ */
+ uasm_i_dmfc0(p, ptr, C0_CONTEXT);
+ uasm_i_dsrl_safe(p, ptr, ptr, 23);
+# endif
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_daddu(p, ptr, ptr, tmp);
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR);
+ uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
+#else
+ UASM_i_LA_mostly(p, ptr, pgdc);
+ uasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);
+#endif
+
+ uasm_l_vmalloc_done(l, *p);
+
+ /* get pgd offset in bytes */
+ uasm_i_dsrl_safe(p, tmp, tmp, PGDIR_SHIFT - 3);
+
+ uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
+ uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
+#ifndef __PAGETABLE_PMD_FOLDED
+ uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
+ uasm_i_dsrl_safe(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
+ uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
+ uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
+#endif
+}
+
+/*
+ * BVADDR is the faulting address, PTR is scratch.
+ * PTR will hold the pgd for vmalloc.
+ */
+static void __cpuinit
+build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
+ unsigned int bvaddr, unsigned int ptr,
+ enum vmalloc64_mode mode)
+{
+ long swpd = (long)swapper_pg_dir;
+ int single_insn_swpd;
+ int did_vmalloc_branch = 0;
+
+ single_insn_swpd = uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd);
+
+ uasm_l_vmalloc(l, *p);
+
+ if (mode != not_refill && check_for_high_segbits) {
+ if (single_insn_swpd) {
+ uasm_il_bltz(p, r, bvaddr, label_vmalloc_done);
+ uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+ did_vmalloc_branch = 1;
+ /* fall through */
+ } else {
+ uasm_il_bgez(p, r, bvaddr, label_large_segbits_fault);
+ }
+ }
+ if (!did_vmalloc_branch) {
+ if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
+ uasm_il_b(p, r, label_vmalloc_done);
+ uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+ } else {
+ UASM_i_LA_mostly(p, ptr, swpd);
+ uasm_il_b(p, r, label_vmalloc_done);
+ if (uasm_in_compat_space_p(swpd))
+ uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
+ else
+ uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+ }
+ }
+ if (mode != not_refill && check_for_high_segbits) {
+ uasm_l_large_segbits_fault(l, *p);
+ /*
+ * We get here if we are an xsseg address, or if we are
+ * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary.
+ *
+ * Ignoring xsseg (assume disabled so would generate
+ * (address errors?), the only remaining possibility
+ * is the upper xuseg addresses. On processors with
+ * TLB_SEGBITS <= PGDIR_SHIFT+PGDIR_BITS, these
+ * addresses would have taken an address error. We try
+ * to mimic that here by taking a load/istream page
+ * fault.
+ */
+ UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
+ uasm_i_jr(p, ptr);
+
+ if (mode == refill_scratch) {
+ if (scratch_reg > 0)
+ UASM_i_MFC0(p, 1, 31, scratch_reg);
+ else
+ UASM_i_LW(p, 1, scratchpad_offset(0), 0);
+ } else {
+ uasm_i_nop(p);
+ }
+ }
+}
+
+#else /* !CONFIG_64BIT */
+
+/*
+ * TMP and PTR are scratch.
+ * TMP will be clobbered, PTR will hold the pgd entry.
+ */
+static void __cpuinit __maybe_unused
+build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
+{
+ long pgdc = (long)pgd_current;
+
+ /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */
+#ifdef CONFIG_SMP
+#ifdef CONFIG_MIPS_MT_SMTC
+ /*
+ * SMTC uses TCBind value as "CPU" index
+ */
+ uasm_i_mfc0(p, ptr, C0_TCBIND);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_srl(p, ptr, ptr, 19);
+#else
+ /*
+ * smp_processor_id() << 3 is stored in CONTEXT.
+ */
+ uasm_i_mfc0(p, ptr, C0_CONTEXT);
+ UASM_i_LA_mostly(p, tmp, pgdc);
+ uasm_i_srl(p, ptr, ptr, 23);
+#endif
+ uasm_i_addu(p, ptr, tmp, ptr);
+#else
+ UASM_i_LA_mostly(p, ptr, pgdc);
+#endif
+ uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+ uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
+ uasm_i_sll(p, tmp, tmp, PGD_T_LOG2);
+ uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
+}
+
+#endif /* !CONFIG_64BIT */
+
+static void __cpuinit build_adjust_context(u32 **p, unsigned int ctx)
+{
+ unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12;
+ unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
+
+ switch (current_cpu_type()) {
+ case CPU_VR41XX:
+ case CPU_VR4111:
+ case CPU_VR4121:
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4181:
+ case CPU_VR4181A:
+ case CPU_VR4133:
+ shift += 2;
+ break;
+
+ default:
+ break;
+ }
+
+ if (shift)
+ UASM_i_SRL(p, ctx, ctx, shift);
+ uasm_i_andi(p, ctx, ctx, mask);
+}
+
+static void __cpuinit build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
+{
+ /*
+ * Bug workaround for the Nevada. It seems as if under certain
+ * circumstances the move from cp0_context might produce a
+ * bogus result when the mfc0 instruction and its consumer are
+ * in a different cacheline or a load instruction, probably any
+ * memory reference, is between them.
+ */
+ switch (current_cpu_type()) {
+ case CPU_NEVADA:
+ UASM_i_LW(p, ptr, 0, ptr);
+ GET_CONTEXT(p, tmp); /* get context reg */
+ break;
+
+ default:
+ GET_CONTEXT(p, tmp); /* get context reg */
+ UASM_i_LW(p, ptr, 0, ptr);
+ break;
+ }
+
+ build_adjust_context(p, tmp);
+ UASM_i_ADDU(p, ptr, ptr, tmp); /* add in offset */
+}
+
+static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
+ unsigned int ptep)
+{
+ /*
+ * 64bit address support (36bit on a 32bit CPU) in a 32bit
+ * Kernel is a special case. Only a few CPUs use it.
+ */
+#ifdef CONFIG_64BIT_PHYS_ADDR
+ if (cpu_has_64bits) {
+ uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
+ uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+ if (kernel_uses_smartmips_rixi) {
+ UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_NO_EXEC));
+ UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_NO_EXEC));
+ UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+ UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ } else {
+ uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
+ UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+ uasm_i_dsrl_safe(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
+ }
+ UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
+ } else {
+ int pte_off_even = sizeof(pte_t) / 2;
+ int pte_off_odd = pte_off_even + sizeof(pte_t);
+
+ /* The pte entries are pre-shifted */
+ uasm_i_lw(p, tmp, pte_off_even, ptep); /* get even pte */
+ UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+ uasm_i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */
+ UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
+ }
+#else
+ UASM_i_LW(p, tmp, 0, ptep); /* get even pte */
+ UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+ if (r45k_bvahwbug())
+ build_tlb_probe_entry(p);
+ if (kernel_uses_smartmips_rixi) {
+ UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_NO_EXEC));
+ UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_NO_EXEC));
+ UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ if (r4k_250MHZhwbug())
+ UASM_i_MTC0(p, 0, C0_ENTRYLO0);
+ UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+ UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ } else {
+ UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
+ if (r4k_250MHZhwbug())
+ UASM_i_MTC0(p, 0, C0_ENTRYLO0);
+ UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
+ UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
+ if (r45k_bvahwbug())
+ uasm_i_mfc0(p, tmp, C0_INDEX);
+ }
+ if (r4k_250MHZhwbug())
+ UASM_i_MTC0(p, 0, C0_ENTRYLO1);
+ UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
+#endif
+}
+
+struct mips_huge_tlb_info {
+ int huge_pte;
+ int restore_scratch;
+};
+
+static struct mips_huge_tlb_info __cpuinit
+build_fast_tlb_refill_handler (u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int tmp,
+ unsigned int ptr, int c0_scratch)
+{
+ struct mips_huge_tlb_info rv;
+ unsigned int even, odd;
+ int vmalloc_branch_delay_filled = 0;
+ const int scratch = 1; /* Our extra working register */
+
+ rv.huge_pte = scratch;
+ rv.restore_scratch = 0;
+
+ if (check_for_high_segbits) {
+ UASM_i_MFC0(p, tmp, C0_BADVADDR);
+
+ if (pgd_reg != -1)
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ else
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ if (c0_scratch >= 0)
+ UASM_i_MTC0(p, scratch, 31, c0_scratch);
+ else
+ UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
+
+ uasm_i_dsrl_safe(p, scratch, tmp,
+ PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+ uasm_il_bnez(p, r, scratch, label_vmalloc);
+
+ if (pgd_reg == -1) {
+ vmalloc_branch_delay_filled = 1;
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+ }
+ } else {
+ if (pgd_reg != -1)
+ UASM_i_MFC0(p, ptr, 31, pgd_reg);
+ else
+ UASM_i_MFC0(p, ptr, C0_CONTEXT);
+
+ UASM_i_MFC0(p, tmp, C0_BADVADDR);
+
+ if (c0_scratch >= 0)
+ UASM_i_MTC0(p, scratch, 31, c0_scratch);
+ else
+ UASM_i_SW(p, scratch, scratchpad_offset(0), 0);
+
+ if (pgd_reg == -1)
+ /* Clear lower 23 bits of context. */
+ uasm_i_dins(p, ptr, 0, 0, 23);
+
+ uasm_il_bltz(p, r, tmp, label_vmalloc);
+ }
+
+ if (pgd_reg == -1) {
+ vmalloc_branch_delay_filled = 1;
+ /* 1 0 1 0 1 << 6 xkphys cached */
+ uasm_i_ori(p, ptr, ptr, 0x540);
+ uasm_i_drotr(p, ptr, ptr, 11);
+ }
+
+#ifdef __PAGETABLE_PMD_FOLDED
+#define LOC_PTEP scratch
+#else
+#define LOC_PTEP ptr
+#endif
+
+ if (!vmalloc_branch_delay_filled)
+ /* get pgd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PGDIR_SHIFT - 3);
+
+ uasm_l_vmalloc_done(l, *p);
+
+ /*
+ * tmp ptr
+ * fall-through case = badvaddr *pgd_current
+ * vmalloc case = badvaddr swapper_pg_dir
+ */
+
+ if (vmalloc_branch_delay_filled)
+ /* get pgd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PGDIR_SHIFT - 3);
+
+#ifdef __PAGETABLE_PMD_FOLDED
+ GET_CONTEXT(p, tmp); /* get context reg */
+#endif
+ uasm_i_andi(p, scratch, scratch, (PTRS_PER_PGD - 1) << 3);
+
+ if (use_lwx_insns()) {
+ UASM_i_LWX(p, LOC_PTEP, scratch, ptr);
+ } else {
+ uasm_i_daddu(p, ptr, ptr, scratch); /* add in pgd offset */
+ uasm_i_ld(p, LOC_PTEP, 0, ptr); /* get pmd pointer */
+ }
+
+#ifndef __PAGETABLE_PMD_FOLDED
+ /* get pmd offset in bytes */
+ uasm_i_dsrl_safe(p, scratch, tmp, PMD_SHIFT - 3);
+ uasm_i_andi(p, scratch, scratch, (PTRS_PER_PMD - 1) << 3);
+ GET_CONTEXT(p, tmp); /* get context reg */
+
+ if (use_lwx_insns()) {
+ UASM_i_LWX(p, scratch, scratch, ptr);
+ } else {
+ uasm_i_daddu(p, ptr, ptr, scratch); /* add in pmd offset */
+ UASM_i_LW(p, scratch, 0, ptr);
+ }
+#endif
+ /* Adjust the context during the load latency. */
+ build_adjust_context(p, tmp);
+
+#ifdef CONFIG_HUGETLB_PAGE
+ uasm_il_bbit1(p, r, scratch, ilog2(_PAGE_HUGE), label_tlb_huge_update);
+ /*
+ * The in the LWX case we don't want to do the load in the
+ * delay slot. It cannot issue in the same cycle and may be
+ * speculative and unneeded.
+ */
+ if (use_lwx_insns())
+ uasm_i_nop(p);
+#endif /* CONFIG_HUGETLB_PAGE */
+
+
+ /* build_update_entries */
+ if (use_lwx_insns()) {
+ even = ptr;
+ odd = tmp;
+ UASM_i_LWX(p, even, scratch, tmp);
+ UASM_i_ADDIU(p, tmp, tmp, sizeof(pte_t));
+ UASM_i_LWX(p, odd, scratch, tmp);
+ } else {
+ UASM_i_ADDU(p, ptr, scratch, tmp); /* add in offset */
+ even = tmp;
+ odd = ptr;
+ UASM_i_LW(p, even, 0, ptr); /* get even pte */
+ UASM_i_LW(p, odd, sizeof(pte_t), ptr); /* get odd pte */
+ }
+ if (kernel_uses_smartmips_rixi) {
+ uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_NO_EXEC));
+ uasm_i_dsrl_safe(p, odd, odd, ilog2(_PAGE_NO_EXEC));
+ uasm_i_drotr(p, even, even,
+ ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ UASM_i_MTC0(p, even, C0_ENTRYLO0); /* load it */
+ uasm_i_drotr(p, odd, odd,
+ ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
+ } else {
+ uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_GLOBAL));
+ UASM_i_MTC0(p, even, C0_ENTRYLO0); /* load it */
+ uasm_i_dsrl_safe(p, odd, odd, ilog2(_PAGE_GLOBAL));
+ }
+ UASM_i_MTC0(p, odd, C0_ENTRYLO1); /* load it */
+
+ if (c0_scratch >= 0) {
+ UASM_i_MFC0(p, scratch, 31, c0_scratch);
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ rv.restore_scratch = 1;
+ } else if (PAGE_SHIFT == 14 || PAGE_SHIFT == 13) {
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ UASM_i_LW(p, scratch, scratchpad_offset(0), 0);
+ } else {
+ UASM_i_LW(p, scratch, scratchpad_offset(0), 0);
+ build_tlb_write_entry(p, l, r, tlb_random);
+ uasm_l_leave(l, *p);
+ rv.restore_scratch = 1;
+ }
+
+ uasm_i_eret(p); /* return from trap */
+
+ return rv;
+}
+
+/*
+ * For a 64-bit kernel, we are using the 64-bit XTLB refill exception
+ * because EXL == 0. If we wrap, we can also use the 32 instruction
+ * slots before the XTLB refill exception handler which belong to the
+ * unused TLB refill exception.
+ */
+#define MIPS64_REFILL_INSNS 32
+
+static void __cpuinit build_r4000_tlb_refill_handler(void)
+{
+ u32 *p = tlb_handler;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+ u32 *f;
+ unsigned int final_len;
+ struct mips_huge_tlb_info htlb_info __maybe_unused;
+ enum vmalloc64_mode vmalloc_mode __maybe_unused;
+
+ memset(tlb_handler, 0, sizeof(tlb_handler));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+ memset(final_handler, 0, sizeof(final_handler));
+
+ if (scratch_reg == 0)
+ scratch_reg = allocate_kscratch();
+
+ if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) {
+ htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
+ scratch_reg);
+ vmalloc_mode = refill_scratch;
+ } else {
+ htlb_info.huge_pte = K0;
+ htlb_info.restore_scratch = 0;
+ vmalloc_mode = refill_noscratch;
+ /*
+ * create the plain linear handler
+ */
+ if (bcm1250_m3_war()) {
+ unsigned int segbits = 44;
+
+ uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+ uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
+ uasm_i_xor(&p, K0, K0, K1);
+ uasm_i_dsrl_safe(&p, K1, K0, 62);
+ uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+ uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+ uasm_i_or(&p, K0, K0, K1);
+ uasm_il_bnez(&p, &r, K0, label_leave);
+ /* No need for uasm_i_nop */
+ }
+
+#ifdef CONFIG_64BIT
+ build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
+#else
+ build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
+#endif
+
+#ifdef CONFIG_HUGETLB_PAGE
+ build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
+#endif
+
+ build_get_ptep(&p, K0, K1);
+ build_update_entries(&p, K0, K1);
+ build_tlb_write_entry(&p, &l, &r, tlb_random);
+ uasm_l_leave(&l, p);
+ uasm_i_eret(&p); /* return from trap */
+ }
+#ifdef CONFIG_HUGETLB_PAGE
+ uasm_l_tlb_huge_update(&l, p);
+ build_huge_update_entries(&p, htlb_info.huge_pte, K1);
+ build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random,
+ htlb_info.restore_scratch);
+#endif
+
+#ifdef CONFIG_64BIT
+ build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, vmalloc_mode);
+#endif
+
+ /*
+ * Overflow check: For the 64bit handler, we need at least one
+ * free instruction slot for the wrap-around branch. In worst
+ * case, if the intended insertion point is a delay slot, we
+ * need three, with the second nop'ed and the third being
+ * unused.
+ */
+ /* Loongson2 ebase is different than r4k, we have more space */
+#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
+ if ((p - tlb_handler) > 64)
+ panic("TLB refill handler space exceeded");
+#else
+ if (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 1)
+ || (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 3)
+ && uasm_insn_has_bdelay(relocs,
+ tlb_handler + MIPS64_REFILL_INSNS - 3)))
+ panic("TLB refill handler space exceeded");
+#endif
+
+ /*
+ * Now fold the handler in the TLB refill handler space.
+ */
+#if defined(CONFIG_32BIT) || defined(CONFIG_CPU_LOONGSON2)
+ f = final_handler;
+ /* Simplest case, just copy the handler. */
+ uasm_copy_handler(relocs, labels, tlb_handler, p, f);
+ final_len = p - tlb_handler;
+#else /* CONFIG_64BIT */
+ f = final_handler + MIPS64_REFILL_INSNS;
+ if ((p - tlb_handler) <= MIPS64_REFILL_INSNS) {
+ /* Just copy the handler. */
+ uasm_copy_handler(relocs, labels, tlb_handler, p, f);
+ final_len = p - tlb_handler;
+ } else {
+#if defined(CONFIG_HUGETLB_PAGE)
+ const enum label_id ls = label_tlb_huge_update;
+#else
+ const enum label_id ls = label_vmalloc;
+#endif
+ u32 *split;
+ int ov = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(labels) && labels[i].lab != ls; i++)
+ ;
+ BUG_ON(i == ARRAY_SIZE(labels));
+ split = labels[i].addr;
+
+ /*
+ * See if we have overflown one way or the other.
+ */
+ if (split > tlb_handler + MIPS64_REFILL_INSNS ||
+ split < p - MIPS64_REFILL_INSNS)
+ ov = 1;
+
+ if (ov) {
+ /*
+ * Split two instructions before the end. One
+ * for the branch and one for the instruction
+ * in the delay slot.
+ */
+ split = tlb_handler + MIPS64_REFILL_INSNS - 2;
+
+ /*
+ * If the branch would fall in a delay slot,
+ * we must back up an additional instruction
+ * so that it is no longer in a delay slot.
+ */
+ if (uasm_insn_has_bdelay(relocs, split - 1))
+ split--;
+ }
+ /* Copy first part of the handler. */
+ uasm_copy_handler(relocs, labels, tlb_handler, split, f);
+ f += split - tlb_handler;
+
+ if (ov) {
+ /* Insert branch. */
+ uasm_l_split(&l, final_handler);
+ uasm_il_b(&f, &r, label_split);
+ if (uasm_insn_has_bdelay(relocs, split))
+ uasm_i_nop(&f);
+ else {
+ uasm_copy_handler(relocs, labels,
+ split, split + 1, f);
+ uasm_move_labels(labels, f, f + 1, -1);
+ f++;
+ split++;
+ }
+ }
+
+ /* Copy the rest of the handler. */
+ uasm_copy_handler(relocs, labels, split, p, final_handler);
+ final_len = (f - (final_handler + MIPS64_REFILL_INSNS)) +
+ (p - split);
+ }
+#endif /* CONFIG_64BIT */
+
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB refill handler (%u instructions).\n",
+ final_len);
+
+ memcpy((void *)ebase, final_handler, 0x100);
+
+ dump_handler((u32 *)ebase, 64);
+}
+
+/*
+ * 128 instructions for the fastpath handler is generous and should
+ * never be exceeded.
+ */
+#define FASTPATH_SIZE 128
+
+u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned;
+u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned;
+u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+u32 tlbmiss_handler_setup_pgd[16] __cacheline_aligned;
+
+static void __cpuinit build_r4000_setup_pgd(void)
+{
+ const int a0 = 4;
+ const int a1 = 5;
+ u32 *p = tlbmiss_handler_setup_pgd;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(tlbmiss_handler_setup_pgd, 0, sizeof(tlbmiss_handler_setup_pgd));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ pgd_reg = allocate_kscratch();
+
+ if (pgd_reg == -1) {
+ /* PGD << 11 in c0_Context */
+ /*
+ * If it is a ckseg0 address, convert to a physical
+ * address. Shifting right by 29 and adding 4 will
+ * result in zero for these addresses.
+ *
+ */
+ UASM_i_SRA(&p, a1, a0, 29);
+ UASM_i_ADDIU(&p, a1, a1, 4);
+ uasm_il_bnez(&p, &r, a1, label_tlbl_goaround1);
+ uasm_i_nop(&p);
+ uasm_i_dinsm(&p, a0, 0, 29, 64 - 29);
+ uasm_l_tlbl_goaround1(&l, p);
+ UASM_i_SLL(&p, a0, a0, 11);
+ uasm_i_jr(&p, 31);
+ UASM_i_MTC0(&p, a0, C0_CONTEXT);
+ } else {
+ /* PGD in c0_KScratch */
+ uasm_i_jr(&p, 31);
+ UASM_i_MTC0(&p, a0, 31, pgd_reg);
+ }
+ if (p - tlbmiss_handler_setup_pgd > ARRAY_SIZE(tlbmiss_handler_setup_pgd))
+ panic("tlbmiss_handler_setup_pgd space exceeded");
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote tlbmiss_handler_setup_pgd (%u instructions).\n",
+ (unsigned int)(p - tlbmiss_handler_setup_pgd));
+
+ dump_handler(tlbmiss_handler_setup_pgd,
+ ARRAY_SIZE(tlbmiss_handler_setup_pgd));
+}
+#endif
+
+static void __cpuinit
+iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+# ifdef CONFIG_64BIT_PHYS_ADDR
+ if (cpu_has_64bits)
+ uasm_i_lld(p, pte, 0, ptr);
+ else
+# endif
+ UASM_i_LL(p, pte, 0, ptr);
+#else
+# ifdef CONFIG_64BIT_PHYS_ADDR
+ if (cpu_has_64bits)
+ uasm_i_ld(p, pte, 0, ptr);
+ else
+# endif
+ UASM_i_LW(p, pte, 0, ptr);
+#endif
+}
+
+static void __cpuinit
+iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
+ unsigned int mode)
+{
+#ifdef CONFIG_64BIT_PHYS_ADDR
+ unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
+#endif
+
+ uasm_i_ori(p, pte, pte, mode);
+#ifdef CONFIG_SMP
+# ifdef CONFIG_64BIT_PHYS_ADDR
+ if (cpu_has_64bits)
+ uasm_i_scd(p, pte, 0, ptr);
+ else
+# endif
+ UASM_i_SC(p, pte, 0, ptr);
+
+ if (r10000_llsc_war())
+ uasm_il_beqzl(p, r, pte, label_smp_pgtable_change);
+ else
+ uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
+
+# ifdef CONFIG_64BIT_PHYS_ADDR
+ if (!cpu_has_64bits) {
+ /* no uasm_i_nop needed */
+ uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_ori(p, pte, pte, hwmode);
+ uasm_i_sc(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
+ /* no uasm_i_nop needed */
+ uasm_i_lw(p, pte, 0, ptr);
+ } else
+ uasm_i_nop(p);
+# else
+ uasm_i_nop(p);
+# endif
+#else
+# ifdef CONFIG_64BIT_PHYS_ADDR
+ if (cpu_has_64bits)
+ uasm_i_sd(p, pte, 0, ptr);
+ else
+# endif
+ UASM_i_SW(p, pte, 0, ptr);
+
+# ifdef CONFIG_64BIT_PHYS_ADDR
+ if (!cpu_has_64bits) {
+ uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_ori(p, pte, pte, hwmode);
+ uasm_i_sw(p, pte, sizeof(pte_t) / 2, ptr);
+ uasm_i_lw(p, pte, 0, ptr);
+ }
+# endif
+#endif
+}
+
+/*
+ * Check if PTE is present, if not then jump to LABEL. PTR points to
+ * the page table where this PTE is located, PTE will be re-loaded
+ * with it's original value.
+ */
+static void __cpuinit
+build_pte_present(u32 **p, struct uasm_reloc **r,
+ unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+ if (kernel_uses_smartmips_rixi) {
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT);
+ uasm_il_beqz(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+ uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
+ uasm_il_bnez(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
+}
+
+/* Make PTE valid, store result in PTR. */
+static void __cpuinit
+build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte,
+ unsigned int ptr)
+{
+ unsigned int mode = _PAGE_VALID | _PAGE_ACCESSED;
+
+ iPTE_SW(p, r, pte, ptr, mode);
+}
+
+/*
+ * Check if PTE can be written to, if not branch to LABEL. Regardless
+ * restore PTE with value from PTR when done.
+ */
+static void __cpuinit
+build_pte_writable(u32 **p, struct uasm_reloc **r,
+ unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
+ uasm_i_nop(p);
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
+ uasm_il_bnez(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
+}
+
+/* Make PTE writable, update software status bits as well, then store
+ * at PTR.
+ */
+static void __cpuinit
+build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte,
+ unsigned int ptr)
+{
+ unsigned int mode = (_PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID
+ | _PAGE_DIRTY);
+
+ iPTE_SW(p, r, pte, ptr, mode);
+}
+
+/*
+ * Check if PTE can be modified, if not branch to LABEL. Regardless
+ * restore PTE with value from PTR when done.
+ */
+static void __cpuinit
+build_pte_modifiable(u32 **p, struct uasm_reloc **r,
+ unsigned int pte, unsigned int ptr, enum label_id lid)
+{
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(p, r, pte, ilog2(_PAGE_WRITE), lid);
+ uasm_i_nop(p);
+ } else {
+ uasm_i_andi(p, pte, pte, _PAGE_WRITE);
+ uasm_il_beqz(p, r, pte, lid);
+ iPTE_LW(p, pte, ptr);
+ }
+}
+
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+
+
+/*
+ * R3000 style TLB load/store/modify handlers.
+ */
+
+/*
+ * This places the pte into ENTRYLO0 and writes it with tlbwi.
+ * Then it returns.
+ */
+static void __cpuinit
+build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp)
+{
+ uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ uasm_i_mfc0(p, tmp, C0_EPC); /* cp0 delay */
+ uasm_i_tlbwi(p);
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
+}
+
+/*
+ * This places the pte into ENTRYLO0 and writes it with tlbwi
+ * or tlbwr as appropriate. This is because the index register
+ * may have the probe fail bit set as a result of a trap on a
+ * kseg2 access, i.e. without refill. Then it returns.
+ */
+static void __cpuinit
+build_r3000_tlb_reload_write(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int pte,
+ unsigned int tmp)
+{
+ uasm_i_mfc0(p, tmp, C0_INDEX);
+ uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */
+ uasm_il_bltz(p, r, tmp, label_r3000_write_probe_fail); /* cp0 delay */
+ uasm_i_mfc0(p, tmp, C0_EPC); /* branch delay */
+ uasm_i_tlbwi(p); /* cp0 delay */
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
+ uasm_l_r3000_write_probe_fail(l, *p);
+ uasm_i_tlbwr(p); /* cp0 delay */
+ uasm_i_jr(p, tmp);
+ uasm_i_rfe(p); /* branch delay */
+}
+
+static void __cpuinit
+build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
+ unsigned int ptr)
+{
+ long pgdc = (long)pgd_current;
+
+ uasm_i_mfc0(p, pte, C0_BADVADDR);
+ uasm_i_lui(p, ptr, uasm_rel_hi(pgdc)); /* cp0 delay */
+ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+ uasm_i_srl(p, pte, pte, 22); /* load delay */
+ uasm_i_sll(p, pte, pte, 2);
+ uasm_i_addu(p, ptr, ptr, pte);
+ uasm_i_mfc0(p, pte, C0_CONTEXT);
+ uasm_i_lw(p, ptr, 0, ptr); /* cp0 delay */
+ uasm_i_andi(p, pte, pte, 0xffc); /* load delay */
+ uasm_i_addu(p, ptr, ptr, pte);
+ uasm_i_lw(p, pte, 0, ptr);
+ uasm_i_tlbp(p); /* load delay */
+}
+
+static void __cpuinit build_r3000_tlb_load_handler(void)
+{
+ u32 *p = handle_tlbl;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(handle_tlbl, 0, sizeof(handle_tlbl));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ build_r3000_tlbchange_handler_head(&p, K0, K1);
+ build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
+ uasm_i_nop(&p); /* load delay */
+ build_make_valid(&p, &r, K0, K1);
+ build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
+
+ uasm_l_nopage_tlbl(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+ uasm_i_nop(&p);
+
+ if ((p - handle_tlbl) > FASTPATH_SIZE)
+ panic("TLB load handler fastpath space exceeded");
+
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbl));
+
+ dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
+}
+
+static void __cpuinit build_r3000_tlb_store_handler(void)
+{
+ u32 *p = handle_tlbs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(handle_tlbs, 0, sizeof(handle_tlbs));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ build_r3000_tlbchange_handler_head(&p, K0, K1);
+ build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
+ uasm_i_nop(&p); /* load delay */
+ build_make_write(&p, &r, K0, K1);
+ build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
+
+ uasm_l_nopage_tlbs(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
+
+ if ((p - handle_tlbs) > FASTPATH_SIZE)
+ panic("TLB store handler fastpath space exceeded");
+
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbs));
+
+ dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
+}
+
+static void __cpuinit build_r3000_tlb_modify_handler(void)
+{
+ u32 *p = handle_tlbm;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(handle_tlbm, 0, sizeof(handle_tlbm));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ build_r3000_tlbchange_handler_head(&p, K0, K1);
+ build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
+ uasm_i_nop(&p); /* load delay */
+ build_make_write(&p, &r, K0, K1);
+ build_r3000_pte_reload_tlbwi(&p, K0, K1);
+
+ uasm_l_nopage_tlbm(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
+
+ if ((p - handle_tlbm) > FASTPATH_SIZE)
+ panic("TLB modify handler fastpath space exceeded");
+
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbm));
+
+ dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
+}
+#endif /* CONFIG_MIPS_PGD_C0_CONTEXT */
+
+/*
+ * R4000 style TLB load/store/modify handlers.
+ */
+static void __cpuinit
+build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int pte,
+ unsigned int ptr)
+{
+#ifdef CONFIG_64BIT
+ build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */
+#else
+ build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
+#endif
+
+#ifdef CONFIG_HUGETLB_PAGE
+ /*
+ * For huge tlb entries, pmd doesn't contain an address but
+ * instead contains the tlb pte. Check the PAGE_HUGE bit and
+ * see if we need to jump to huge tlb processing.
+ */
+ build_is_huge_pte(p, r, pte, ptr, label_tlb_huge_update);
+#endif
+
+ UASM_i_MFC0(p, pte, C0_BADVADDR);
+ UASM_i_LW(p, ptr, 0, ptr);
+ UASM_i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
+ uasm_i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
+ UASM_i_ADDU(p, ptr, ptr, pte);
+
+#ifdef CONFIG_SMP
+ uasm_l_smp_pgtable_change(l, *p);
+#endif
+ iPTE_LW(p, pte, ptr); /* get even pte */
+ if (!m4kc_tlbp_war())
+ build_tlb_probe_entry(p);
+}
+
+static void __cpuinit
+build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
+ struct uasm_reloc **r, unsigned int tmp,
+ unsigned int ptr)
+{
+ uasm_i_ori(p, ptr, ptr, sizeof(pte_t));
+ uasm_i_xori(p, ptr, ptr, sizeof(pte_t));
+ build_update_entries(p, tmp, ptr);
+ build_tlb_write_entry(p, l, r, tlb_indexed);
+ uasm_l_leave(l, *p);
+ uasm_i_eret(p); /* return from trap */
+
+#ifdef CONFIG_64BIT
+ build_get_pgd_vmalloc64(p, l, r, tmp, ptr, not_refill);
+#endif
+}
+
+static void __cpuinit build_r4000_tlb_load_handler(void)
+{
+ u32 *p = handle_tlbl;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(handle_tlbl, 0, sizeof(handle_tlbl));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ if (bcm1250_m3_war()) {
+ unsigned int segbits = 44;
+
+ uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+ uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
+ uasm_i_xor(&p, K0, K0, K1);
+ uasm_i_dsrl_safe(&p, K1, K0, 62);
+ uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+ uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+ uasm_i_or(&p, K0, K0, K1);
+ uasm_il_bnez(&p, &r, K0, label_leave);
+ /* No need for uasm_i_nop */
+ }
+
+ build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+ build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
+ if (m4kc_tlbp_war())
+ build_tlb_probe_entry(&p);
+
+ if (kernel_uses_smartmips_rixi) {
+ /*
+ * If the page is not _PAGE_VALID, RI or XI could not
+ * have triggered it. Skip the expensive test..
+ */
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID),
+ label_tlbl_goaround1);
+ } else {
+ uasm_i_andi(&p, K0, K0, _PAGE_VALID);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround1);
+ }
+ uasm_i_nop(&p);
+
+ uasm_i_tlbr(&p);
+ /* Examine entrylo 0 or 1 based on ptr. */
+ if (use_bbit_insns()) {
+ uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8);
+ } else {
+ uasm_i_andi(&p, K0, K1, sizeof(pte_t));
+ uasm_i_beqz(&p, K0, 8);
+ }
+
+ UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
+ UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
+ /*
+ * If the entryLo (now in K0) is valid (bit 1), RI or
+ * XI must have triggered it.
+ */
+ if (use_bbit_insns()) {
+ uasm_il_bbit1(&p, &r, K0, 1, label_nopage_tlbl);
+ /* Reload the PTE value */
+ iPTE_LW(&p, K0, K1);
+ uasm_l_tlbl_goaround1(&l, p);
+ } else {
+ uasm_i_andi(&p, K0, K0, 2);
+ uasm_il_bnez(&p, &r, K0, label_nopage_tlbl);
+ uasm_l_tlbl_goaround1(&l, p);
+ /* Reload the PTE value */
+ iPTE_LW(&p, K0, K1);
+ }
+ }
+ build_make_valid(&p, &r, K0, K1);
+ build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+#ifdef CONFIG_HUGETLB_PAGE
+ /*
+ * This is the entry point when build_r4000_tlbchange_handler_head
+ * spots a huge page.
+ */
+ uasm_l_tlb_huge_update(&l, p);
+ iPTE_LW(&p, K0, K1);
+ build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
+ build_tlb_probe_entry(&p);
+
+ if (kernel_uses_smartmips_rixi) {
+ /*
+ * If the page is not _PAGE_VALID, RI or XI could not
+ * have triggered it. Skip the expensive test..
+ */
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, ilog2(_PAGE_VALID),
+ label_tlbl_goaround2);
+ } else {
+ uasm_i_andi(&p, K0, K0, _PAGE_VALID);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ }
+ uasm_i_nop(&p);
+
+ uasm_i_tlbr(&p);
+ /* Examine entrylo 0 or 1 based on ptr. */
+ if (use_bbit_insns()) {
+ uasm_i_bbit0(&p, K1, ilog2(sizeof(pte_t)), 8);
+ } else {
+ uasm_i_andi(&p, K0, K1, sizeof(pte_t));
+ uasm_i_beqz(&p, K0, 8);
+ }
+ UASM_i_MFC0(&p, K0, C0_ENTRYLO0); /* load it in the delay slot*/
+ UASM_i_MFC0(&p, K0, C0_ENTRYLO1); /* load it if ptr is odd */
+ /*
+ * If the entryLo (now in K0) is valid (bit 1), RI or
+ * XI must have triggered it.
+ */
+ if (use_bbit_insns()) {
+ uasm_il_bbit0(&p, &r, K0, 1, label_tlbl_goaround2);
+ } else {
+ uasm_i_andi(&p, K0, K0, 2);
+ uasm_il_beqz(&p, &r, K0, label_tlbl_goaround2);
+ }
+ /* Reload the PTE value */
+ iPTE_LW(&p, K0, K1);
+
+ /*
+ * We clobbered C0_PAGEMASK, restore it. On the other branch
+ * it is restored in build_huge_tlb_write_entry.
+ */
+ build_restore_pagemask(&p, &r, K0, label_nopage_tlbl, 0);
+
+ uasm_l_tlbl_goaround2(&l, p);
+ }
+ uasm_i_ori(&p, K0, K0, (_PAGE_ACCESSED | _PAGE_VALID));
+ build_huge_handler_tail(&p, &r, &l, K0, K1);
+#endif
+
+ uasm_l_nopage_tlbl(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
+ uasm_i_nop(&p);
+
+ if ((p - handle_tlbl) > FASTPATH_SIZE)
+ panic("TLB load handler fastpath space exceeded");
+
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB load handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbl));
+
+ dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl));
+}
+
+static void __cpuinit build_r4000_tlb_store_handler(void)
+{
+ u32 *p = handle_tlbs;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(handle_tlbs, 0, sizeof(handle_tlbs));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+ build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
+ if (m4kc_tlbp_war())
+ build_tlb_probe_entry(&p);
+ build_make_write(&p, &r, K0, K1);
+ build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+#ifdef CONFIG_HUGETLB_PAGE
+ /*
+ * This is the entry point when
+ * build_r4000_tlbchange_handler_head spots a huge page.
+ */
+ uasm_l_tlb_huge_update(&l, p);
+ iPTE_LW(&p, K0, K1);
+ build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
+ build_tlb_probe_entry(&p);
+ uasm_i_ori(&p, K0, K0,
+ _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
+ build_huge_handler_tail(&p, &r, &l, K0, K1);
+#endif
+
+ uasm_l_nopage_tlbs(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
+
+ if ((p - handle_tlbs) > FASTPATH_SIZE)
+ panic("TLB store handler fastpath space exceeded");
+
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB store handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbs));
+
+ dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs));
+}
+
+static void __cpuinit build_r4000_tlb_modify_handler(void)
+{
+ u32 *p = handle_tlbm;
+ struct uasm_label *l = labels;
+ struct uasm_reloc *r = relocs;
+
+ memset(handle_tlbm, 0, sizeof(handle_tlbm));
+ memset(labels, 0, sizeof(labels));
+ memset(relocs, 0, sizeof(relocs));
+
+ build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
+ build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
+ if (m4kc_tlbp_war())
+ build_tlb_probe_entry(&p);
+ /* Present and writable bits set, set accessed and dirty bits. */
+ build_make_write(&p, &r, K0, K1);
+ build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
+
+#ifdef CONFIG_HUGETLB_PAGE
+ /*
+ * This is the entry point when
+ * build_r4000_tlbchange_handler_head spots a huge page.
+ */
+ uasm_l_tlb_huge_update(&l, p);
+ iPTE_LW(&p, K0, K1);
+ build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
+ build_tlb_probe_entry(&p);
+ uasm_i_ori(&p, K0, K0,
+ _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
+ build_huge_handler_tail(&p, &r, &l, K0, K1);
+#endif
+
+ uasm_l_nopage_tlbm(&l, p);
+ uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
+ uasm_i_nop(&p);
+
+ if ((p - handle_tlbm) > FASTPATH_SIZE)
+ panic("TLB modify handler fastpath space exceeded");
+
+ uasm_resolve_relocs(relocs, labels);
+ pr_debug("Wrote TLB modify handler fastpath (%u instructions).\n",
+ (unsigned int)(p - handle_tlbm));
+
+ dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm));
+}
+
+void __cpuinit build_tlb_refill_handler(void)
+{
+ /*
+ * The refill handler is generated per-CPU, multi-node systems
+ * may have local storage for it. The other handlers are only
+ * needed once.
+ */
+ static int run_once = 0;
+
+#ifdef CONFIG_64BIT
+ check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+#endif
+
+ switch (current_cpu_type()) {
+ case CPU_R2000:
+ case CPU_R3000:
+ case CPU_R3000A:
+ case CPU_R3081E:
+ case CPU_TX3912:
+ case CPU_TX3922:
+ case CPU_TX3927:
+#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
+ build_r3000_tlb_refill_handler();
+ if (!run_once) {
+ build_r3000_tlb_load_handler();
+ build_r3000_tlb_store_handler();
+ build_r3000_tlb_modify_handler();
+ run_once++;
+ }
+#else
+ panic("No R3000 TLB refill handler");
+#endif
+ break;
+
+ case CPU_R6000:
+ case CPU_R6000A:
+ panic("No R6000 TLB refill handler yet");
+ break;
+
+ case CPU_R8000:
+ panic("No R8000 TLB refill handler yet");
+ break;
+
+ default:
+ if (!run_once) {
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+ build_r4000_setup_pgd();
+#endif
+ build_r4000_tlb_load_handler();
+ build_r4000_tlb_store_handler();
+ build_r4000_tlb_modify_handler();
+ run_once++;
+ }
+ build_r4000_tlb_refill_handler();
+ }
+}
+
+void __cpuinit flush_tlb_handlers(void)
+{
+ local_flush_icache_range((unsigned long)handle_tlbl,
+ (unsigned long)handle_tlbl + sizeof(handle_tlbl));
+ local_flush_icache_range((unsigned long)handle_tlbs,
+ (unsigned long)handle_tlbs + sizeof(handle_tlbs));
+ local_flush_icache_range((unsigned long)handle_tlbm,
+ (unsigned long)handle_tlbm + sizeof(handle_tlbm));
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
+ local_flush_icache_range((unsigned long)tlbmiss_handler_setup_pgd,
+ (unsigned long)tlbmiss_handler_setup_pgd + sizeof(handle_tlbm));
+#endif
+}
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
new file mode 100644
index 00000000..5fa18515
--- /dev/null
+++ b/arch/mips/mm/uasm.c
@@ -0,0 +1,699 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * A small micro-assembler. It is intentionally kept simple, does only
+ * support a subset of instructions, and does not try to hide pipeline
+ * effects like branch delay slots.
+ *
+ * Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
+ * Copyright (C) 2005, 2007 Maciej W. Rozycki
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/inst.h>
+#include <asm/elf.h>
+#include <asm/bugs.h>
+#include <asm/uasm.h>
+
+enum fields {
+ RS = 0x001,
+ RT = 0x002,
+ RD = 0x004,
+ RE = 0x008,
+ SIMM = 0x010,
+ UIMM = 0x020,
+ BIMM = 0x040,
+ JIMM = 0x080,
+ FUNC = 0x100,
+ SET = 0x200,
+ SCIMM = 0x400
+};
+
+#define OP_MASK 0x3f
+#define OP_SH 26
+#define RS_MASK 0x1f
+#define RS_SH 21
+#define RT_MASK 0x1f
+#define RT_SH 16
+#define RD_MASK 0x1f
+#define RD_SH 11
+#define RE_MASK 0x1f
+#define RE_SH 6
+#define IMM_MASK 0xffff
+#define IMM_SH 0
+#define JIMM_MASK 0x3ffffff
+#define JIMM_SH 0
+#define FUNC_MASK 0x3f
+#define FUNC_SH 0
+#define SET_MASK 0x7
+#define SET_SH 0
+#define SCIMM_MASK 0xfffff
+#define SCIMM_SH 6
+
+enum opcode {
+ insn_invalid,
+ insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
+ insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+ insn_bne, insn_cache, insn_daddu, insn_daddiu, insn_dmfc0,
+ insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
+ insn_dsrl32, insn_drotr, insn_drotr32, insn_dsubu, insn_eret,
+ insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld,
+ insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_or, insn_ori,
+ insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
+ insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, insn_tlbp,
+ insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
+ insn_dins, insn_dinsm, insn_syscall, insn_bbit0, insn_bbit1,
+ insn_lwx, insn_ldx
+};
+
+struct insn {
+ enum opcode opcode;
+ u32 match;
+ enum fields fields;
+};
+
+/* This macro sets the non-variable bits of an instruction. */
+#define M(a, b, c, d, e, f) \
+ ((a) << OP_SH \
+ | (b) << RS_SH \
+ | (c) << RT_SH \
+ | (d) << RD_SH \
+ | (e) << RE_SH \
+ | (f) << FUNC_SH)
+
+static struct insn insn_table[] __uasminitdata = {
+ { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
+ { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
+ { insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM },
+ { insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM },
+ { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
+ { insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
+ { insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
+ { insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE },
+ { insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE },
+ { insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE },
+ { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
+ { insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
+ { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE },
+ { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE },
+ { insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
+ { insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 },
+ { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
+ { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
+ { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
+ { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM },
+ { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
+ { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
+ { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
+ { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE },
+ { insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE },
+ { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE },
+ { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE },
+ { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD },
+ { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 },
+ { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 },
+ { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 },
+ { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 },
+ { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
+ { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+ { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE },
+ { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
+ { insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
+ { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
+ { insn_invalid, 0, 0 }
+};
+
+#undef M
+
+static inline __uasminit u32 build_rs(u32 arg)
+{
+ WARN(arg & ~RS_MASK, KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RS_MASK) << RS_SH;
+}
+
+static inline __uasminit u32 build_rt(u32 arg)
+{
+ WARN(arg & ~RT_MASK, KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RT_MASK) << RT_SH;
+}
+
+static inline __uasminit u32 build_rd(u32 arg)
+{
+ WARN(arg & ~RD_MASK, KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RD_MASK) << RD_SH;
+}
+
+static inline __uasminit u32 build_re(u32 arg)
+{
+ WARN(arg & ~RE_MASK, KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & RE_MASK) << RE_SH;
+}
+
+static inline __uasminit u32 build_simm(s32 arg)
+{
+ WARN(arg > 0x7fff || arg < -0x8000,
+ KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & 0xffff;
+}
+
+static inline __uasminit u32 build_uimm(u32 arg)
+{
+ WARN(arg & ~IMM_MASK, KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & IMM_MASK;
+}
+
+static inline __uasminit u32 build_bimm(s32 arg)
+{
+ WARN(arg > 0x1ffff || arg < -0x20000,
+ KERN_WARNING "Micro-assembler field overflow\n");
+
+ WARN(arg & 0x3, KERN_WARNING "Invalid micro-assembler branch target\n");
+
+ return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff);
+}
+
+static inline __uasminit u32 build_jimm(u32 arg)
+{
+ WARN(arg & ~(JIMM_MASK << 2),
+ KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg >> 2) & JIMM_MASK;
+}
+
+static inline __uasminit u32 build_scimm(u32 arg)
+{
+ WARN(arg & ~SCIMM_MASK,
+ KERN_WARNING "Micro-assembler field overflow\n");
+
+ return (arg & SCIMM_MASK) << SCIMM_SH;
+}
+
+static inline __uasminit u32 build_func(u32 arg)
+{
+ WARN(arg & ~FUNC_MASK, KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & FUNC_MASK;
+}
+
+static inline __uasminit u32 build_set(u32 arg)
+{
+ WARN(arg & ~SET_MASK, KERN_WARNING "Micro-assembler field overflow\n");
+
+ return arg & SET_MASK;
+}
+
+/*
+ * The order of opcode arguments is implicitly left to right,
+ * starting with RS and ending with FUNC or IMM.
+ */
+static void __uasminit build_insn(u32 **buf, enum opcode opc, ...)
+{
+ struct insn *ip = NULL;
+ unsigned int i;
+ va_list ap;
+ u32 op;
+
+ for (i = 0; insn_table[i].opcode != insn_invalid; i++)
+ if (insn_table[i].opcode == opc) {
+ ip = &insn_table[i];
+ break;
+ }
+
+ if (!ip || (opc == insn_daddiu && r4k_daddiu_bug()))
+ panic("Unsupported Micro-assembler instruction %d", opc);
+
+ op = ip->match;
+ va_start(ap, opc);
+ if (ip->fields & RS)
+ op |= build_rs(va_arg(ap, u32));
+ if (ip->fields & RT)
+ op |= build_rt(va_arg(ap, u32));
+ if (ip->fields & RD)
+ op |= build_rd(va_arg(ap, u32));
+ if (ip->fields & RE)
+ op |= build_re(va_arg(ap, u32));
+ if (ip->fields & SIMM)
+ op |= build_simm(va_arg(ap, s32));
+ if (ip->fields & UIMM)
+ op |= build_uimm(va_arg(ap, u32));
+ if (ip->fields & BIMM)
+ op |= build_bimm(va_arg(ap, s32));
+ if (ip->fields & JIMM)
+ op |= build_jimm(va_arg(ap, u32));
+ if (ip->fields & FUNC)
+ op |= build_func(va_arg(ap, u32));
+ if (ip->fields & SET)
+ op |= build_set(va_arg(ap, u32));
+ if (ip->fields & SCIMM)
+ op |= build_scimm(va_arg(ap, u32));
+ va_end(ap);
+
+ **buf = op;
+ (*buf)++;
+}
+
+#define I_u1u2u3(op) \
+Ip_u1u2u3(op) \
+{ \
+ build_insn(buf, insn##op, a, b, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u2u1u3(op) \
+Ip_u2u1u3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u3u1u2(op) \
+Ip_u3u1u2(op) \
+{ \
+ build_insn(buf, insn##op, b, c, a); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u1u2s3(op) \
+Ip_u1u2s3(op) \
+{ \
+ build_insn(buf, insn##op, a, b, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u2s3u1(op) \
+Ip_u2s3u1(op) \
+{ \
+ build_insn(buf, insn##op, c, a, b); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u2u1s3(op) \
+Ip_u2u1s3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u2u1msbu3(op) \
+Ip_u2u1msbu3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c+d-1, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u2u1msb32u3(op) \
+Ip_u2u1msbu3(op) \
+{ \
+ build_insn(buf, insn##op, b, a, c+d-33, c); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u1u2(op) \
+Ip_u1u2(op) \
+{ \
+ build_insn(buf, insn##op, a, b); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u1s2(op) \
+Ip_u1s2(op) \
+{ \
+ build_insn(buf, insn##op, a, b); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_u1(op) \
+Ip_u1(op) \
+{ \
+ build_insn(buf, insn##op, a); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+#define I_0(op) \
+Ip_0(op) \
+{ \
+ build_insn(buf, insn##op); \
+} \
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
+I_u2u1s3(_addiu)
+I_u3u1u2(_addu)
+I_u2u1u3(_andi)
+I_u3u1u2(_and)
+I_u1u2s3(_beq)
+I_u1u2s3(_beql)
+I_u1s2(_bgez)
+I_u1s2(_bgezl)
+I_u1s2(_bltz)
+I_u1s2(_bltzl)
+I_u1u2s3(_bne)
+I_u2s3u1(_cache)
+I_u1u2u3(_dmfc0)
+I_u1u2u3(_dmtc0)
+I_u2u1s3(_daddiu)
+I_u3u1u2(_daddu)
+I_u2u1u3(_dsll)
+I_u2u1u3(_dsll32)
+I_u2u1u3(_dsra)
+I_u2u1u3(_dsrl)
+I_u2u1u3(_dsrl32)
+I_u2u1u3(_drotr)
+I_u2u1u3(_drotr32)
+I_u3u1u2(_dsubu)
+I_0(_eret)
+I_u1(_j)
+I_u1(_jal)
+I_u1(_jr)
+I_u2s3u1(_ld)
+I_u2s3u1(_ll)
+I_u2s3u1(_lld)
+I_u1s2(_lui)
+I_u2s3u1(_lw)
+I_u1u2u3(_mfc0)
+I_u1u2u3(_mtc0)
+I_u2u1u3(_ori)
+I_u3u1u2(_or)
+I_0(_rfe)
+I_u2s3u1(_sc)
+I_u2s3u1(_scd)
+I_u2s3u1(_sd)
+I_u2u1u3(_sll)
+I_u2u1u3(_sra)
+I_u2u1u3(_srl)
+I_u2u1u3(_rotr)
+I_u3u1u2(_subu)
+I_u2s3u1(_sw)
+I_0(_tlbp)
+I_0(_tlbr)
+I_0(_tlbwi)
+I_0(_tlbwr)
+I_u3u1u2(_xor)
+I_u2u1u3(_xori)
+I_u2u1msbu3(_dins);
+I_u2u1msb32u3(_dinsm);
+I_u1(_syscall);
+I_u1u2s3(_bbit0);
+I_u1u2s3(_bbit1);
+I_u3u1u2(_lwx)
+I_u3u1u2(_ldx)
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#include <asm/octeon/octeon.h>
+void __uasminit uasm_i_pref(u32 **buf, unsigned int a, signed int b,
+ unsigned int c)
+{
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) && a <= 24 && a != 5)
+ /*
+ * As per erratum Core-14449, replace prefetches 0-4,
+ * 6-24 with 'pref 28'.
+ */
+ build_insn(buf, insn_pref, c, 28, b);
+ else
+ build_insn(buf, insn_pref, c, a, b);
+}
+UASM_EXPORT_SYMBOL(uasm_i_pref);
+#else
+I_u2s3u1(_pref)
+#endif
+
+/* Handle labels. */
+void __uasminit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
+{
+ (*lab)->addr = addr;
+ (*lab)->lab = lid;
+ (*lab)++;
+}
+UASM_EXPORT_SYMBOL(uasm_build_label);
+
+int __uasminit uasm_in_compat_space_p(long addr)
+{
+ /* Is this address in 32bit compat space? */
+#ifdef CONFIG_64BIT
+ return (((addr) & 0xffffffff00000000L) == 0xffffffff00000000L);
+#else
+ return 1;
+#endif
+}
+UASM_EXPORT_SYMBOL(uasm_in_compat_space_p);
+
+static int __uasminit uasm_rel_highest(long val)
+{
+#ifdef CONFIG_64BIT
+ return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
+#else
+ return 0;
+#endif
+}
+
+static int __uasminit uasm_rel_higher(long val)
+{
+#ifdef CONFIG_64BIT
+ return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
+#else
+ return 0;
+#endif
+}
+
+int __uasminit uasm_rel_hi(long val)
+{
+ return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000;
+}
+UASM_EXPORT_SYMBOL(uasm_rel_hi);
+
+int __uasminit uasm_rel_lo(long val)
+{
+ return ((val & 0xffff) ^ 0x8000) - 0x8000;
+}
+UASM_EXPORT_SYMBOL(uasm_rel_lo);
+
+void __uasminit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr)
+{
+ if (!uasm_in_compat_space_p(addr)) {
+ uasm_i_lui(buf, rs, uasm_rel_highest(addr));
+ if (uasm_rel_higher(addr))
+ uasm_i_daddiu(buf, rs, rs, uasm_rel_higher(addr));
+ if (uasm_rel_hi(addr)) {
+ uasm_i_dsll(buf, rs, rs, 16);
+ uasm_i_daddiu(buf, rs, rs, uasm_rel_hi(addr));
+ uasm_i_dsll(buf, rs, rs, 16);
+ } else
+ uasm_i_dsll32(buf, rs, rs, 0);
+ } else
+ uasm_i_lui(buf, rs, uasm_rel_hi(addr));
+}
+UASM_EXPORT_SYMBOL(UASM_i_LA_mostly);
+
+void __uasminit UASM_i_LA(u32 **buf, unsigned int rs, long addr)
+{
+ UASM_i_LA_mostly(buf, rs, addr);
+ if (uasm_rel_lo(addr)) {
+ if (!uasm_in_compat_space_p(addr))
+ uasm_i_daddiu(buf, rs, rs, uasm_rel_lo(addr));
+ else
+ uasm_i_addiu(buf, rs, rs, uasm_rel_lo(addr));
+ }
+}
+UASM_EXPORT_SYMBOL(UASM_i_LA);
+
+/* Handle relocations. */
+void __uasminit
+uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid)
+{
+ (*rel)->addr = addr;
+ (*rel)->type = R_MIPS_PC16;
+ (*rel)->lab = lid;
+ (*rel)++;
+}
+UASM_EXPORT_SYMBOL(uasm_r_mips_pc16);
+
+static inline void __uasminit
+__resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
+{
+ long laddr = (long)lab->addr;
+ long raddr = (long)rel->addr;
+
+ switch (rel->type) {
+ case R_MIPS_PC16:
+ *rel->addr |= build_bimm(laddr - (raddr + 4));
+ break;
+
+ default:
+ panic("Unsupported Micro-assembler relocation %d",
+ rel->type);
+ }
+}
+
+void __uasminit
+uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab)
+{
+ struct uasm_label *l;
+
+ for (; rel->lab != UASM_LABEL_INVALID; rel++)
+ for (l = lab; l->lab != UASM_LABEL_INVALID; l++)
+ if (rel->lab == l->lab)
+ __resolve_relocs(rel, l);
+}
+UASM_EXPORT_SYMBOL(uasm_resolve_relocs);
+
+void __uasminit
+uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off)
+{
+ for (; rel->lab != UASM_LABEL_INVALID; rel++)
+ if (rel->addr >= first && rel->addr < end)
+ rel->addr += off;
+}
+UASM_EXPORT_SYMBOL(uasm_move_relocs);
+
+void __uasminit
+uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off)
+{
+ for (; lab->lab != UASM_LABEL_INVALID; lab++)
+ if (lab->addr >= first && lab->addr < end)
+ lab->addr += off;
+}
+UASM_EXPORT_SYMBOL(uasm_move_labels);
+
+void __uasminit
+uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first,
+ u32 *end, u32 *target)
+{
+ long off = (long)(target - first);
+
+ memcpy(target, first, (end - first) * sizeof(u32));
+
+ uasm_move_relocs(rel, first, end, off);
+ uasm_move_labels(lab, first, end, off);
+}
+UASM_EXPORT_SYMBOL(uasm_copy_handler);
+
+int __uasminit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr)
+{
+ for (; rel->lab != UASM_LABEL_INVALID; rel++) {
+ if (rel->addr == addr
+ && (rel->type == R_MIPS_PC16
+ || rel->type == R_MIPS_26))
+ return 1;
+ }
+
+ return 0;
+}
+UASM_EXPORT_SYMBOL(uasm_insn_has_bdelay);
+
+/* Convenience functions for labeled branches. */
+void __uasminit
+uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bltz(p, reg, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bltz);
+
+void __uasminit
+uasm_il_b(u32 **p, struct uasm_reloc **r, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_b(p, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_b);
+
+void __uasminit
+uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_beqz(p, reg, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_beqz);
+
+void __uasminit
+uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_beqzl(p, reg, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_beqzl);
+
+void __uasminit
+uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
+ unsigned int reg2, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bne(p, reg1, reg2, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bne);
+
+void __uasminit
+uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bnez(p, reg, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bnez);
+
+void __uasminit
+uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bgezl(p, reg, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bgezl);
+
+void __uasminit
+uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bgez(p, reg, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bgez);
+
+void __uasminit
+uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg,
+ unsigned int bit, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bbit0(p, reg, bit, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bbit0);
+
+void __uasminit
+uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
+ unsigned int bit, int lid)
+{
+ uasm_r_mips_pc16(r, *p, lid);
+ uasm_i_bbit1(p, reg, bit, 0);
+}
+UASM_EXPORT_SYMBOL(uasm_il_bbit1);
diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile
new file mode 100644
index 00000000..6079ef33
--- /dev/null
+++ b/arch/mips/mti-malta/Makefile
@@ -0,0 +1,17 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+#
+# Copyright (C) 2008 Wind River Systems, Inc.
+# written by Ralf Baechle <ralf@linux-mips.org>
+#
+obj-y := malta-amon.o malta-cmdline.o \
+ malta-display.o malta-init.o malta-int.o \
+ malta-memory.o malta-platform.o \
+ malta-reset.o malta-setup.o malta-time.o
+
+obj-$(CONFIG_EARLY_PRINTK) += malta-console.o
+obj-$(CONFIG_PCI) += malta-pci.o
+
+# FIXME FIXME FIXME
+obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o
diff --git a/arch/mips/mti-malta/Platform b/arch/mips/mti-malta/Platform
new file mode 100644
index 00000000..5b548b5a
--- /dev/null
+++ b/arch/mips/mti-malta/Platform
@@ -0,0 +1,7 @@
+#
+# MIPS Malta board
+#
+platform-$(CONFIG_MIPS_MALTA) += mti-malta/
+cflags-$(CONFIG_MIPS_MALTA) += -I$(srctree)/arch/mips/include/asm/mach-malta
+load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
+all-$(CONFIG_MIPS_MALTA) := $(COMPRESSION_FNAME).bin
diff --git a/arch/mips/mti-malta/malta-amon.c b/arch/mips/mti-malta/malta-amon.c
new file mode 100644
index 00000000..469d9b0c
--- /dev/null
+++ b/arch/mips/mti-malta/malta-amon.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * All rights reserved.
+
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Arbitrary Monitor interface
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/addrspace.h>
+#include <asm/mips-boards/launch.h>
+#include <asm/mipsmtregs.h>
+
+int amon_cpu_avail(int cpu)
+{
+ struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
+
+ if (cpu < 0 || cpu >= NCPULAUNCH) {
+ pr_debug("avail: cpu%d is out of range\n", cpu);
+ return 0;
+ }
+
+ launch += cpu;
+ if (!(launch->flags & LAUNCH_FREADY)) {
+ pr_debug("avail: cpu%d is not ready\n", cpu);
+ return 0;
+ }
+ if (launch->flags & (LAUNCH_FGO|LAUNCH_FGONE)) {
+ pr_debug("avail: too late.. cpu%d is already gone\n", cpu);
+ return 0;
+ }
+
+ return 1;
+}
+
+void amon_cpu_start(int cpu,
+ unsigned long pc, unsigned long sp,
+ unsigned long gp, unsigned long a0)
+{
+ volatile struct cpulaunch *launch =
+ (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
+
+ if (!amon_cpu_avail(cpu))
+ return;
+ if (cpu == smp_processor_id()) {
+ pr_debug("launch: I am cpu%d!\n", cpu);
+ return;
+ }
+ launch += cpu;
+
+ pr_debug("launch: starting cpu%d\n", cpu);
+
+ launch->pc = pc;
+ launch->gp = gp;
+ launch->sp = sp;
+ launch->a0 = a0;
+
+ smp_wmb(); /* Target must see parameters before go */
+ launch->flags |= LAUNCH_FGO;
+ smp_wmb(); /* Target must see go before we poll */
+
+ while ((launch->flags & LAUNCH_FGONE) == 0)
+ ;
+ smp_rmb(); /* Target will be updating flags soon */
+ pr_debug("launch: cpu%d gone!\n", cpu);
+}
diff --git a/arch/mips/mti-malta/malta-cmdline.c b/arch/mips/mti-malta/malta-cmdline.c
new file mode 100644
index 00000000..1871c30e
--- /dev/null
+++ b/arch/mips/mti-malta/malta-cmdline.c
@@ -0,0 +1,59 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern int *_prom_argv;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(long)_prom_argv[(index)])
+
+char * __init prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+
+void __init prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while(actr < prom_argc) {
+ strcpy(cp, prom_argv(actr));
+ cp += strlen(prom_argv(actr));
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) {
+ /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+ }
+}
diff --git a/arch/mips/mti-malta/malta-console.c b/arch/mips/mti-malta/malta-console.c
new file mode 100644
index 00000000..43bcfb4f
--- /dev/null
+++ b/arch/mips/mti-malta/malta-console.c
@@ -0,0 +1,47 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Putting things on the screen/serial line using YAMONs facilities.
+ */
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+#include <asm/io.h>
+
+
+#define PORT(offset) (0x3f8 + (offset))
+
+
+static inline unsigned int serial_in(int offset)
+{
+ return inb(PORT(offset));
+}
+
+static inline void serial_out(int offset, int value)
+{
+ outb(value, PORT(offset));
+}
+
+int prom_putchar(char c)
+{
+ while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
+ ;
+
+ serial_out(UART_TX, c);
+
+ return 1;
+}
diff --git a/arch/mips/mti-malta/malta-display.c b/arch/mips/mti-malta/malta-display.c
new file mode 100644
index 00000000..7c8828fc
--- /dev/null
+++ b/arch/mips/mti-malta/malta-display.c
@@ -0,0 +1,64 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Display routines for display messages in MIPS boards ascii display.
+ */
+
+#include <linux/compiler.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+extern const char display_string[];
+static unsigned int display_count;
+static unsigned int max_display_count;
+
+void mips_display_message(const char *str)
+{
+ static unsigned int __iomem *display = NULL;
+ int i;
+
+ if (unlikely(display == NULL))
+ display = ioremap(ASCII_DISPLAY_POS_BASE, 16*sizeof(int));
+
+ for (i = 0; i <= 14; i=i+2) {
+ if (*str)
+ __raw_writel(*str++, display + i);
+ else
+ __raw_writel(' ', display + i);
+ }
+}
+
+static void scroll_display_message(unsigned long data);
+static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0);
+
+static void scroll_display_message(unsigned long data)
+{
+ mips_display_message(&display_string[display_count++]);
+ if (display_count == max_display_count)
+ display_count = 0;
+
+ mod_timer(&mips_scroll_timer, jiffies + HZ);
+}
+
+void mips_scroll_message(void)
+{
+ del_timer_sync(&mips_scroll_timer);
+ max_display_count = strlen(display_string) + 1 - 8;
+ mod_timer(&mips_scroll_timer, jiffies + 1);
+}
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
new file mode 100644
index 00000000..31180c32
--- /dev/null
+++ b/arch/mips/mti-malta/malta-init.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * PROM library initialisation code.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <asm/gt64120.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+
+#include <asm/gcmpregs.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/bonito64.h>
+#include <asm/mips-boards/msc01_pci.h>
+
+#include <asm/mips-boards/malta.h>
+
+int prom_argc;
+int *_prom_argv, *_prom_envp;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension, if running in 64-bit mode.
+ */
+#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
+
+int init_debug;
+
+static int mips_revision_corid;
+int mips_revision_sconid;
+
+/* Bonito64 system controller register base. */
+unsigned long _pcictrl_bonito;
+unsigned long _pcictrl_bonito_pcicfg;
+
+/* GT64120 system controller register base */
+unsigned long _pcictrl_gt64120;
+
+/* MIPS System controller register base */
+unsigned long _pcictrl_msc;
+
+char *prom_getenv(char *envname)
+{
+ /*
+ * Return a pointer to the given environment variable.
+ * In 64-bit mode: we're using 64-bit pointers, but all pointers
+ * in the PROM structures are only 32-bit, so we need some
+ * workarounds, if we are running in 64-bit mode.
+ */
+ int i, index=0;
+
+ i = strlen(envname);
+
+ while (prom_envp(index)) {
+ if(strncmp(envname, prom_envp(index), i) == 0) {
+ return(prom_envp(index+1));
+ }
+ index += 2;
+ }
+
+ return NULL;
+}
+
+static inline unsigned char str2hexnum(unsigned char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if((*str == '.') || (*str == ':'))
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= (str2hexnum(*str++));
+ ea[i] = num;
+ }
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+ char *ethaddr_str;
+
+ ethaddr_str = prom_getenv("ethaddr");
+ if (!ethaddr_str) {
+ printk("ethaddr not set in boot prom\n");
+ return -1;
+ }
+ str2eaddr(ethernet_addr, ethaddr_str);
+
+ if (init_debug > 1) {
+ int i;
+ printk("get_ethernet_addr: ");
+ for (i=0; i<5; i++)
+ printk("%02x:", (unsigned char)*(ethernet_addr+i));
+ printk("%02x\n", *(ethernet_addr+i));
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static void __init console_config(void)
+{
+ char console_string[40];
+ int baud = 0;
+ char parity = '\0', bits = '\0', flow = '\0';
+ char *s;
+
+ if ((strstr(prom_getcmdline(), "console=")) == NULL) {
+ s = prom_getenv("modetty0");
+ if (s) {
+ while (*s >= '0' && *s <= '9')
+ baud = baud*10 + *s++ - '0';
+ if (*s == ',') s++;
+ if (*s) parity = *s++;
+ if (*s == ',') s++;
+ if (*s) bits = *s++;
+ if (*s == ',') s++;
+ if (*s == 'h') flow = 'r';
+ }
+ if (baud == 0)
+ baud = 38400;
+ if (parity != 'n' && parity != 'o' && parity != 'e')
+ parity = 'n';
+ if (bits != '7' && bits != '8')
+ bits = '8';
+ if (flow == '\0')
+ flow = 'r';
+ sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow);
+ strcat(prom_getcmdline(), console_string);
+ pr_info("Config serial console:%s\n", console_string);
+ }
+}
+#endif
+
+static void __init mips_nmi_setup(void)
+{
+ void *base;
+ extern char except_vec_nmi;
+
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa80) :
+ (void *)(CAC_BASE + 0x380);
+ memcpy(base, &except_vec_nmi, 0x80);
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+static void __init mips_ejtag_setup(void)
+{
+ void *base;
+ extern char except_vec_ejtag_debug;
+
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa00) :
+ (void *)(CAC_BASE + 0x300);
+ memcpy(base, &except_vec_ejtag_debug, 0x80);
+ flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+extern struct plat_smp_ops msmtc_smp_ops;
+
+void __init prom_init(void)
+{
+ prom_argc = fw_arg0;
+ _prom_argv = (int *) fw_arg1;
+ _prom_envp = (int *) fw_arg2;
+
+ mips_display_message("LINUX");
+
+ /*
+ * early setup of _pcictrl_bonito so that we can determine
+ * the system controller on a CORE_EMUL board
+ */
+ _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE);
+
+ mips_revision_corid = MIPS_REVISION_CORID;
+
+ if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) {
+ if (BONITO_PCIDID == 0x0001df53 ||
+ BONITO_PCIDID == 0x0003df53)
+ mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON;
+ else
+ mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC;
+ }
+
+ mips_revision_sconid = MIPS_REVISION_SCONID;
+ if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) {
+ switch (mips_revision_corid) {
+ case MIPS_REVISION_CORID_QED_RM5261:
+ case MIPS_REVISION_CORID_CORE_LV:
+ case MIPS_REVISION_CORID_CORE_FPGA:
+ case MIPS_REVISION_CORID_CORE_FPGAR2:
+ mips_revision_sconid = MIPS_REVISION_SCON_GT64120;
+ break;
+ case MIPS_REVISION_CORID_CORE_EMUL_BON:
+ case MIPS_REVISION_CORID_BONITO64:
+ case MIPS_REVISION_CORID_CORE_20K:
+ mips_revision_sconid = MIPS_REVISION_SCON_BONITO;
+ break;
+ case MIPS_REVISION_CORID_CORE_MSC:
+ case MIPS_REVISION_CORID_CORE_FPGA2:
+ case MIPS_REVISION_CORID_CORE_24K:
+ /*
+ * SOCit/ROCit support is essentially identical
+ * but make an attempt to distinguish them
+ */
+ mips_revision_sconid = MIPS_REVISION_SCON_SOCIT;
+ break;
+ case MIPS_REVISION_CORID_CORE_FPGA3:
+ case MIPS_REVISION_CORID_CORE_FPGA4:
+ case MIPS_REVISION_CORID_CORE_FPGA5:
+ case MIPS_REVISION_CORID_CORE_EMUL_MSC:
+ default:
+ /* See above */
+ mips_revision_sconid = MIPS_REVISION_SCON_ROCIT;
+ break;
+ }
+ }
+
+ switch (mips_revision_sconid) {
+ u32 start, map, mask, data;
+
+ case MIPS_REVISION_SCON_GT64120:
+ /*
+ * Setup the North bridge to do Master byte-lane swapping
+ * when running in bigendian.
+ */
+ _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000);
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
+ GT_PCI0_CMD_SBYTESWAP_BIT);
+#else
+ GT_WRITE(GT_PCI0_CMD_OFS, 0);
+#endif
+ /* Fix up PCI I/O mapping if necessary (for Atlas). */
+ start = GT_READ(GT_PCI0IOLD_OFS);
+ map = GT_READ(GT_PCI0IOREMAP_OFS);
+ if ((start & map) != 0) {
+ map &= ~start;
+ GT_WRITE(GT_PCI0IOREMAP_OFS, map);
+ }
+
+ set_io_port_base(MALTA_GT_PORT_BASE);
+ break;
+
+ case MIPS_REVISION_SCON_BONITO:
+ _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE);
+
+ /*
+ * Disable Bonito IOBC.
+ */
+ BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
+ ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
+ BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
+
+ /*
+ * Setup the North bridge to do Master byte-lane swapping
+ * when running in bigendian.
+ */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ BONITO_BONGENCFG = BONITO_BONGENCFG &
+ ~(BONITO_BONGENCFG_MSTRBYTESWAP |
+ BONITO_BONGENCFG_BYTESWAP);
+#else
+ BONITO_BONGENCFG = BONITO_BONGENCFG |
+ BONITO_BONGENCFG_MSTRBYTESWAP |
+ BONITO_BONGENCFG_BYTESWAP;
+#endif
+
+ set_io_port_base(MALTA_BONITO_PORT_BASE);
+ break;
+
+ case MIPS_REVISION_SCON_SOCIT:
+ case MIPS_REVISION_SCON_ROCIT:
+ _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
+ mips_pci_controller:
+ mb();
+ MSC_READ(MSC01_PCI_CFG, data);
+ MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
+ wmb();
+
+ /* Fix up lane swapping. */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
+#else
+ MSC_WRITE(MSC01_PCI_SWAP,
+ MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
+ MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
+ MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
+#endif
+ /* Fix up target memory mapping. */
+ MSC_READ(MSC01_PCI_BAR0, mask);
+ MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK);
+
+ /* Don't handle target retries indefinitely. */
+ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
+ MSC01_PCI_CFG_MAXRTRY_MSK)
+ data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
+ MSC01_PCI_CFG_MAXRTRY_SHF)) |
+ ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
+ MSC01_PCI_CFG_MAXRTRY_SHF);
+
+ wmb();
+ MSC_WRITE(MSC01_PCI_CFG, data);
+ mb();
+
+ set_io_port_base(MALTA_MSC_PORT_BASE);
+ break;
+
+ case MIPS_REVISION_SCON_SOCITSC:
+ case MIPS_REVISION_SCON_SOCITSCP:
+ _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000);
+ goto mips_pci_controller;
+
+ default:
+ /* Unknown system controller */
+ mips_display_message("SC Error");
+ while (1); /* We die here... */
+ }
+ board_nmi_handler_setup = mips_nmi_setup;
+ board_ejtag_handler_setup = mips_ejtag_setup;
+
+ prom_init_cmdline();
+ prom_meminit();
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ console_config();
+#endif
+#ifdef CONFIG_MIPS_CMP
+ /* Early detection of CMP support */
+ if (gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ))
+ register_smp_ops(&cmp_smp_ops);
+ else
+#endif
+#ifdef CONFIG_MIPS_MT_SMP
+ register_smp_ops(&vsmp_smp_ops);
+#endif
+#ifdef CONFIG_MIPS_MT_SMTC
+ register_smp_ops(&msmtc_smp_ops);
+#endif
+}
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
new file mode 100644
index 00000000..1d36c511
--- /dev/null
+++ b/arch/mips/mti-malta/malta-int.c
@@ -0,0 +1,746 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines for generic manipulation of the interrupts found on the MIPS
+ * Malta board.
+ * The interrupt controller is located in the South Bridge a PIIX4 device
+ * with two internal 82C95 interrupt controllers.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel_stat.h>
+#include <linux/kernel.h>
+#include <linux/random.h>
+
+#include <asm/traps.h>
+#include <asm/i8259.h>
+#include <asm/irq_cpu.h>
+#include <asm/irq_regs.h>
+#include <asm/mips-boards/malta.h>
+#include <asm/mips-boards/maltaint.h>
+#include <asm/mips-boards/piix4.h>
+#include <asm/gt64120.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/msc01_pci.h>
+#include <asm/msc01_ic.h>
+#include <asm/gic.h>
+#include <asm/gcmpregs.h>
+
+int gcmp_present = -1;
+int gic_present;
+static unsigned long _msc01_biu_base;
+static unsigned long _gcmp_base;
+static unsigned int ipi_map[NR_CPUS];
+
+static DEFINE_RAW_SPINLOCK(mips_irq_lock);
+
+static inline int mips_pcibios_iack(void)
+{
+ int irq;
+
+ /*
+ * Determine highest priority pending interrupt by performing
+ * a PCI Interrupt Acknowledge cycle.
+ */
+ switch (mips_revision_sconid) {
+ case MIPS_REVISION_SCON_SOCIT:
+ case MIPS_REVISION_SCON_ROCIT:
+ case MIPS_REVISION_SCON_SOCITSC:
+ case MIPS_REVISION_SCON_SOCITSCP:
+ MSC_READ(MSC01_PCI_IACK, irq);
+ irq &= 0xff;
+ break;
+ case MIPS_REVISION_SCON_GT64120:
+ irq = GT_READ(GT_PCI0_IACK_OFS);
+ irq &= 0xff;
+ break;
+ case MIPS_REVISION_SCON_BONITO:
+ /* The following will generate a PCI IACK cycle on the
+ * Bonito controller. It's a little bit kludgy, but it
+ * was the easiest way to implement it in hardware at
+ * the given time.
+ */
+ BONITO_PCIMAP_CFG = 0x20000;
+
+ /* Flush Bonito register block */
+ (void) BONITO_PCIMAP_CFG;
+ iob(); /* sync */
+
+ irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg);
+ iob(); /* sync */
+ irq &= 0xff;
+ BONITO_PCIMAP_CFG = 0;
+ break;
+ default:
+ printk(KERN_WARNING "Unknown system controller.\n");
+ return -1;
+ }
+ return irq;
+}
+
+static inline int get_int(void)
+{
+ unsigned long flags;
+ int irq;
+ raw_spin_lock_irqsave(&mips_irq_lock, flags);
+
+ irq = mips_pcibios_iack();
+
+ /*
+ * The only way we can decide if an interrupt is spurious
+ * is by checking the 8259 registers. This needs a spinlock
+ * on an SMP system, so leave it up to the generic code...
+ */
+
+ raw_spin_unlock_irqrestore(&mips_irq_lock, flags);
+
+ return irq;
+}
+
+static void malta_hw0_irqdispatch(void)
+{
+ int irq;
+
+ irq = get_int();
+ if (irq < 0) {
+ /* interrupt has already been cleared */
+ return;
+ }
+
+ do_IRQ(MALTA_INT_BASE + irq);
+}
+
+static void malta_ipi_irqdispatch(void)
+{
+ int irq;
+
+ irq = gic_get_int();
+ if (irq < 0)
+ return; /* interrupt has already been cleared */
+
+ do_IRQ(MIPS_GIC_IRQ_BASE + irq);
+}
+
+static void corehi_irqdispatch(void)
+{
+ unsigned int intedge, intsteer, pcicmd, pcibadaddr;
+ unsigned int pcimstat, intisr, inten, intpol;
+ unsigned int intrcause, datalo, datahi;
+ struct pt_regs *regs = get_irq_regs();
+
+ printk(KERN_EMERG "CoreHI interrupt, shouldn't happen, we die here!\n");
+ printk(KERN_EMERG "epc : %08lx\nStatus: %08lx\n"
+ "Cause : %08lx\nbadVaddr : %08lx\n",
+ regs->cp0_epc, regs->cp0_status,
+ regs->cp0_cause, regs->cp0_badvaddr);
+
+ /* Read all the registers and then print them as there is a
+ problem with interspersed printk's upsetting the Bonito controller.
+ Do it for the others too.
+ */
+
+ switch (mips_revision_sconid) {
+ case MIPS_REVISION_SCON_SOCIT:
+ case MIPS_REVISION_SCON_ROCIT:
+ case MIPS_REVISION_SCON_SOCITSC:
+ case MIPS_REVISION_SCON_SOCITSCP:
+ ll_msc_irq();
+ break;
+ case MIPS_REVISION_SCON_GT64120:
+ intrcause = GT_READ(GT_INTRCAUSE_OFS);
+ datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
+ datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
+ printk(KERN_EMERG "GT_INTRCAUSE = %08x\n", intrcause);
+ printk(KERN_EMERG "GT_CPUERR_ADDR = %02x%08x\n",
+ datahi, datalo);
+ break;
+ case MIPS_REVISION_SCON_BONITO:
+ pcibadaddr = BONITO_PCIBADADDR;
+ pcimstat = BONITO_PCIMSTAT;
+ intisr = BONITO_INTISR;
+ inten = BONITO_INTEN;
+ intpol = BONITO_INTPOL;
+ intedge = BONITO_INTEDGE;
+ intsteer = BONITO_INTSTEER;
+ pcicmd = BONITO_PCICMD;
+ printk(KERN_EMERG "BONITO_INTISR = %08x\n", intisr);
+ printk(KERN_EMERG "BONITO_INTEN = %08x\n", inten);
+ printk(KERN_EMERG "BONITO_INTPOL = %08x\n", intpol);
+ printk(KERN_EMERG "BONITO_INTEDGE = %08x\n", intedge);
+ printk(KERN_EMERG "BONITO_INTSTEER = %08x\n", intsteer);
+ printk(KERN_EMERG "BONITO_PCICMD = %08x\n", pcicmd);
+ printk(KERN_EMERG "BONITO_PCIBADADDR = %08x\n", pcibadaddr);
+ printk(KERN_EMERG "BONITO_PCIMSTAT = %08x\n", pcimstat);
+ break;
+ }
+
+ die("CoreHi interrupt", regs);
+}
+
+static inline int clz(unsigned long x)
+{
+ __asm__(
+ " .set push \n"
+ " .set mips32 \n"
+ " clz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (x)
+ : "r" (x));
+
+ return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ return -clz(pending) + 31 - CAUSEB_IP;
+#else
+ unsigned int a0 = 7;
+ unsigned int t0;
+
+ t0 = pending & 0xf000;
+ t0 = t0 < 1;
+ t0 = t0 << 2;
+ a0 = a0 - t0;
+ pending = pending << t0;
+
+ t0 = pending & 0xc000;
+ t0 = t0 < 1;
+ t0 = t0 << 1;
+ a0 = a0 - t0;
+ pending = pending << t0;
+
+ t0 = pending & 0x8000;
+ t0 = t0 < 1;
+ /* t0 = t0 << 2; */
+ a0 = a0 - t0;
+ /* pending = pending << t0; */
+
+ return a0;
+#endif
+}
+
+/*
+ * IRQs on the Malta board look basically (barring software IRQs which we
+ * don't use at all and all external interrupt sources are combined together
+ * on hardware interrupt 0 (MIPS IRQ 2)) like:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 Combined hardware interrupt (hw0)
+ * 3 Hardware (ignored)
+ * 4 Hardware (ignored)
+ * 5 Hardware (ignored)
+ * 6 Hardware (ignored)
+ * 7 R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ---- R4k Timer
+ * Lowest ---- Combined hardware interrupt
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+ int irq;
+
+ irq = irq_ffs(pending);
+
+ if (irq == MIPSCPU_INT_I8259A)
+ malta_hw0_irqdispatch();
+ else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
+ malta_ipi_irqdispatch();
+ else if (irq >= 0)
+ do_IRQ(MIPS_CPU_IRQ_BASE + irq);
+ else
+ spurious_interrupt();
+}
+
+#ifdef CONFIG_MIPS_MT_SMP
+
+
+#define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3
+#define GIC_MIPS_CPU_IPI_CALL_IRQ 4
+
+#define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */
+#define C_RESCHED C_SW0
+#define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for resched */
+#define C_CALL C_SW1
+static int cpu_ipi_resched_irq, cpu_ipi_call_irq;
+
+static void ipi_resched_dispatch(void)
+{
+ do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ);
+}
+
+static void ipi_call_dispatch(void)
+{
+ do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
+}
+
+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
+{
+ scheduler_ipi();
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
+{
+ smp_call_function_interrupt();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq_resched = {
+ .handler = ipi_resched_interrupt,
+ .flags = IRQF_DISABLED|IRQF_PERCPU,
+ .name = "IPI_resched"
+};
+
+static struct irqaction irq_call = {
+ .handler = ipi_call_interrupt,
+ .flags = IRQF_DISABLED|IRQF_PERCPU,
+ .name = "IPI_call"
+};
+#endif /* CONFIG_MIPS_MT_SMP */
+
+static int gic_resched_int_base;
+static int gic_call_int_base;
+#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu))
+#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu))
+
+unsigned int plat_ipi_call_int_xlate(unsigned int cpu)
+{
+ return GIC_CALL_INT(cpu);
+}
+
+unsigned int plat_ipi_resched_int_xlate(unsigned int cpu)
+{
+ return GIC_RESCHED_INT(cpu);
+}
+
+static struct irqaction i8259irq = {
+ .handler = no_action,
+ .name = "XT-PIC cascade"
+};
+
+static struct irqaction corehi_irqaction = {
+ .handler = no_action,
+ .name = "CoreHi"
+};
+
+static msc_irqmap_t __initdata msc_irqmap[] = {
+ {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0},
+ {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0},
+};
+static int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap);
+
+static msc_irqmap_t __initdata msc_eicirqmap[] = {
+ {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_I8259A, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_SMI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_COREHI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_CORELO, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0},
+ {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0},
+ {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0}
+};
+
+static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
+
+/*
+ * This GIC specific tabular array defines the association between External
+ * Interrupts and CPUs/Core Interrupts. The nature of the External
+ * Interrupts is also defined here - polarity/trigger.
+ */
+
+#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
+#define X GIC_UNUSED
+
+static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
+ { X, X, X, X, 0 },
+ { X, X, X, X, 0 },
+ { X, X, X, X, 0 },
+ { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { X, X, X, X, 0 },
+ { X, X, X, X, 0 },
+ { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+ { X, X, X, X, 0 },
+ /* The remainder of this table is initialised by fill_ipi_map */
+};
+#undef X
+
+/*
+ * GCMP needs to be detected before any SMP initialisation
+ */
+int __init gcmp_probe(unsigned long addr, unsigned long size)
+{
+ if (mips_revision_sconid != MIPS_REVISION_SCON_ROCIT) {
+ gcmp_present = 0;
+ return gcmp_present;
+ }
+
+ if (gcmp_present >= 0)
+ return gcmp_present;
+
+ _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ);
+ _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ);
+ gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR;
+
+ if (gcmp_present)
+ pr_debug("GCMP present\n");
+ return gcmp_present;
+}
+
+/* Return the number of IOCU's present */
+int __init gcmp_niocu(void)
+{
+ return gcmp_present ?
+ (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF :
+ 0;
+}
+
+/* Set GCMP region attributes */
+void __init gcmp_setregion(int region, unsigned long base,
+ unsigned long mask, int type)
+{
+ GCMPGCBn(CMxBASE, region) = base;
+ GCMPGCBn(CMxMASK, region) = mask | type;
+}
+
+#if defined(CONFIG_MIPS_MT_SMP)
+static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
+{
+ int intr = baseintr + cpu;
+ gic_intr_map[intr].cpunum = cpu;
+ gic_intr_map[intr].pin = cpupin;
+ gic_intr_map[intr].polarity = GIC_POL_POS;
+ gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
+ gic_intr_map[intr].flags = GIC_FLAG_IPI;
+ ipi_map[cpu] |= (1 << (cpupin + 2));
+}
+
+static void __init fill_ipi_map(void)
+{
+ int cpu;
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1);
+ fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2);
+ }
+}
+#endif
+
+void __init arch_init_ipiirq(int irq, struct irqaction *action)
+{
+ setup_irq(irq, action);
+ irq_set_handler(irq, handle_percpu_irq);
+}
+
+void __init arch_init_irq(void)
+{
+ init_i8259_irqs();
+
+ if (!cpu_has_veic)
+ mips_cpu_irq_init();
+
+ if (gcmp_present) {
+ GCMPGCB(GICBA) = GIC_BASE_ADDR | GCMP_GCB_GICBA_EN_MSK;
+ gic_present = 1;
+ } else {
+ if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) {
+ _msc01_biu_base = (unsigned long)
+ ioremap_nocache(MSC01_BIU_REG_BASE,
+ MSC01_BIU_ADDRSPACE_SZ);
+ gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) &
+ MSC01_SC_CFG_GICPRES_MSK) >>
+ MSC01_SC_CFG_GICPRES_SHF;
+ }
+ }
+ if (gic_present)
+ pr_debug("GIC present\n");
+
+ switch (mips_revision_sconid) {
+ case MIPS_REVISION_SCON_SOCIT:
+ case MIPS_REVISION_SCON_ROCIT:
+ if (cpu_has_veic)
+ init_msc_irqs(MIPS_MSC01_IC_REG_BASE,
+ MSC01E_INT_BASE, msc_eicirqmap,
+ msc_nr_eicirqs);
+ else
+ init_msc_irqs(MIPS_MSC01_IC_REG_BASE,
+ MSC01C_INT_BASE, msc_irqmap,
+ msc_nr_irqs);
+ break;
+
+ case MIPS_REVISION_SCON_SOCITSC:
+ case MIPS_REVISION_SCON_SOCITSCP:
+ if (cpu_has_veic)
+ init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE,
+ MSC01E_INT_BASE, msc_eicirqmap,
+ msc_nr_eicirqs);
+ else
+ init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE,
+ MSC01C_INT_BASE, msc_irqmap,
+ msc_nr_irqs);
+ }
+
+ if (cpu_has_veic) {
+ set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch);
+ set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
+ setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
+ setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
+ } else if (cpu_has_vint) {
+ set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
+ set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch);
+#ifdef CONFIG_MIPS_MT_SMTC
+ setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq,
+ (0x100 << MIPSCPU_INT_I8259A));
+ setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
+ &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI));
+ /*
+ * Temporary hack to ensure that the subsidiary device
+ * interrupts coing in via the i8259A, but associated
+ * with low IRQ numbers, will restore the Status.IM
+ * value associated with the i8259A.
+ */
+ {
+ int i;
+
+ for (i = 0; i < 16; i++)
+ irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A);
+ }
+#else /* Not SMTC */
+ setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
+ setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
+ &corehi_irqaction);
+#endif /* CONFIG_MIPS_MT_SMTC */
+ } else {
+ setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
+ setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
+ &corehi_irqaction);
+ }
+
+ if (gic_present) {
+ /* FIXME */
+ int i;
+#if defined(CONFIG_MIPS_MT_SMP)
+ gic_call_int_base = GIC_NUM_INTRS - NR_CPUS;
+ gic_resched_int_base = gic_call_int_base - NR_CPUS;
+ fill_ipi_map();
+#endif
+ gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
+ ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
+ if (!gcmp_present) {
+ /* Enable the GIC */
+ i = REG(_msc01_biu_base, MSC01_SC_CFG);
+ REG(_msc01_biu_base, MSC01_SC_CFG) =
+ (i | (0x1 << MSC01_SC_CFG_GICENA_SHF));
+ pr_debug("GIC Enabled\n");
+ }
+#if defined(CONFIG_MIPS_MT_SMP)
+ /* set up ipi interrupts */
+ if (cpu_has_vint) {
+ set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
+ set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch);
+ }
+ /* Argh.. this really needs sorting out.. */
+ printk("CPU%d: status register was %08x\n", smp_processor_id(), read_c0_status());
+ write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4);
+ printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status());
+ write_c0_status(0x1100dc00);
+ printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
+ for (i = 0; i < NR_CPUS; i++) {
+ arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
+ GIC_RESCHED_INT(i), &irq_resched);
+ arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
+ GIC_CALL_INT(i), &irq_call);
+ }
+#endif
+ } else {
+#if defined(CONFIG_MIPS_MT_SMP)
+ /* set up ipi interrupts */
+ if (cpu_has_veic) {
+ set_vi_handler (MSC01E_INT_SW0, ipi_resched_dispatch);
+ set_vi_handler (MSC01E_INT_SW1, ipi_call_dispatch);
+ cpu_ipi_resched_irq = MSC01E_INT_SW0;
+ cpu_ipi_call_irq = MSC01E_INT_SW1;
+ } else {
+ if (cpu_has_vint) {
+ set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
+ set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
+ }
+ cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
+ cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
+ }
+ arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
+ arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
+#endif
+ }
+}
+
+void malta_be_init(void)
+{
+ if (gcmp_present) {
+ /* Could change CM error mask register */
+ }
+}
+
+
+static char *tr[8] = {
+ "mem", "gcr", "gic", "mmio",
+ "0x04", "0x05", "0x06", "0x07"
+};
+
+static char *mcmd[32] = {
+ [0x00] = "0x00",
+ [0x01] = "Legacy Write",
+ [0x02] = "Legacy Read",
+ [0x03] = "0x03",
+ [0x04] = "0x04",
+ [0x05] = "0x05",
+ [0x06] = "0x06",
+ [0x07] = "0x07",
+ [0x08] = "Coherent Read Own",
+ [0x09] = "Coherent Read Share",
+ [0x0a] = "Coherent Read Discard",
+ [0x0b] = "Coherent Ready Share Always",
+ [0x0c] = "Coherent Upgrade",
+ [0x0d] = "Coherent Writeback",
+ [0x0e] = "0x0e",
+ [0x0f] = "0x0f",
+ [0x10] = "Coherent Copyback",
+ [0x11] = "Coherent Copyback Invalidate",
+ [0x12] = "Coherent Invalidate",
+ [0x13] = "Coherent Write Invalidate",
+ [0x14] = "Coherent Completion Sync",
+ [0x15] = "0x15",
+ [0x16] = "0x16",
+ [0x17] = "0x17",
+ [0x18] = "0x18",
+ [0x19] = "0x19",
+ [0x1a] = "0x1a",
+ [0x1b] = "0x1b",
+ [0x1c] = "0x1c",
+ [0x1d] = "0x1d",
+ [0x1e] = "0x1e",
+ [0x1f] = "0x1f"
+};
+
+static char *core[8] = {
+ "Invalid/OK", "Invalid/Data",
+ "Shared/OK", "Shared/Data",
+ "Modified/OK", "Modified/Data",
+ "Exclusive/OK", "Exclusive/Data"
+};
+
+static char *causes[32] = {
+ "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR",
+ "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07",
+ "0x08", "0x09", "0x0a", "0x0b",
+ "0x0c", "0x0d", "0x0e", "0x0f",
+ "0x10", "0x11", "0x12", "0x13",
+ "0x14", "0x15", "0x16", "INTVN_WR_ERR",
+ "INTVN_RD_ERR", "0x19", "0x1a", "0x1b",
+ "0x1c", "0x1d", "0x1e", "0x1f"
+};
+
+int malta_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ /* This duplicates the handling in do_be which seems wrong */
+ int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
+
+ if (gcmp_present) {
+ unsigned long cm_error = GCMPGCB(GCMEC);
+ unsigned long cm_addr = GCMPGCB(GCMEA);
+ unsigned long cm_other = GCMPGCB(GCMEO);
+ unsigned long cause, ocause;
+ char buf[256];
+
+ cause = (cm_error & GCMP_GCB_GMEC_ERROR_TYPE_MSK);
+ if (cause != 0) {
+ cause >>= GCMP_GCB_GMEC_ERROR_TYPE_SHF;
+ if (cause < 16) {
+ unsigned long cca_bits = (cm_error >> 15) & 7;
+ unsigned long tr_bits = (cm_error >> 12) & 7;
+ unsigned long mcmd_bits = (cm_error >> 7) & 0x1f;
+ unsigned long stag_bits = (cm_error >> 3) & 15;
+ unsigned long sport_bits = (cm_error >> 0) & 7;
+
+ snprintf(buf, sizeof(buf),
+ "CCA=%lu TR=%s MCmd=%s STag=%lu "
+ "SPort=%lu\n",
+ cca_bits, tr[tr_bits], mcmd[mcmd_bits],
+ stag_bits, sport_bits);
+ } else {
+ /* glob state & sresp together */
+ unsigned long c3_bits = (cm_error >> 18) & 7;
+ unsigned long c2_bits = (cm_error >> 15) & 7;
+ unsigned long c1_bits = (cm_error >> 12) & 7;
+ unsigned long c0_bits = (cm_error >> 9) & 7;
+ unsigned long sc_bit = (cm_error >> 8) & 1;
+ unsigned long mcmd_bits = (cm_error >> 3) & 0x1f;
+ unsigned long sport_bits = (cm_error >> 0) & 7;
+ snprintf(buf, sizeof(buf),
+ "C3=%s C2=%s C1=%s C0=%s SC=%s "
+ "MCmd=%s SPort=%lu\n",
+ core[c3_bits], core[c2_bits],
+ core[c1_bits], core[c0_bits],
+ sc_bit ? "True" : "False",
+ mcmd[mcmd_bits], sport_bits);
+ }
+
+ ocause = (cm_other & GCMP_GCB_GMEO_ERROR_2ND_MSK) >>
+ GCMP_GCB_GMEO_ERROR_2ND_SHF;
+
+ printk("CM_ERROR=%08lx %s <%s>\n", cm_error,
+ causes[cause], buf);
+ printk("CM_ADDR =%08lx\n", cm_addr);
+ printk("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]);
+
+ /* reprime cause register */
+ GCMPGCB(GCMEC) = 0;
+ }
+ }
+
+ return retval;
+}
diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
new file mode 100644
index 00000000..a96d281f
--- /dev/null
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -0,0 +1,178 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to
+ * us from the YAMON.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/pfn.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <asm/mips-boards/prom.h>
+
+/*#define DEBUG*/
+
+enum yamon_memtypes {
+ yamon_dontuse,
+ yamon_prom,
+ yamon_free,
+};
+static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+#ifdef DEBUG
+static char *mtypes[3] = {
+ "Dont use memory",
+ "YAMON PROM memory",
+ "Free memory",
+};
+#endif
+
+/* determined physical memory size, not overridden by command line args */
+unsigned long physical_memsize = 0L;
+
+static struct prom_pmemblock * __init prom_getmdesc(void)
+{
+ char *memsize_str;
+ unsigned int memsize;
+ char *ptr;
+ static char cmdline[COMMAND_LINE_SIZE] __initdata;
+
+ /* otherwise look in the environment */
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str) {
+ printk(KERN_WARNING
+ "memsize not set in boot prom, set to default (32Mb)\n");
+ physical_memsize = 0x02000000;
+ } else {
+#ifdef DEBUG
+ pr_debug("prom_memsize = %s\n", memsize_str);
+#endif
+ physical_memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last
+ word of physical memory */
+ physical_memsize -= PAGE_SIZE;
+#endif
+
+ /* Check the command line for a memsize directive that overrides
+ the physical/default amount */
+ strcpy(cmdline, arcs_cmdline);
+ ptr = strstr(cmdline, "memsize=");
+ if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
+ ptr = strstr(ptr, " memsize=");
+
+ if (ptr)
+ memsize = memparse(ptr + 8, &ptr);
+ else
+ memsize = physical_memsize;
+
+ memset(mdesc, 0, sizeof(mdesc));
+
+ mdesc[0].type = yamon_dontuse;
+ mdesc[0].base = 0x00000000;
+ mdesc[0].size = 0x00001000;
+
+ mdesc[1].type = yamon_prom;
+ mdesc[1].base = 0x00001000;
+ mdesc[1].size = 0x000ef000;
+
+ /*
+ * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
+ * south bridge and PCI access always forwarded to the ISA Bus and
+ * BIOSCS# is always generated.
+ * This mean that this area can't be used as DMA memory for PCI
+ * devices.
+ */
+ mdesc[2].type = yamon_dontuse;
+ mdesc[2].base = 0x000f0000;
+ mdesc[2].size = 0x00010000;
+
+ mdesc[3].type = yamon_dontuse;
+ mdesc[3].base = 0x00100000;
+ mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base;
+
+ mdesc[4].type = yamon_free;
+ mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
+ mdesc[4].size = memsize - mdesc[4].base;
+
+ return &mdesc[0];
+}
+
+static int __init prom_memtype_classify(unsigned int type)
+{
+ switch (type) {
+ case yamon_free:
+ return BOOT_MEM_RAM;
+ case yamon_prom:
+ return BOOT_MEM_ROM_DATA;
+ default:
+ return BOOT_MEM_RESERVED;
+ }
+}
+
+void __init prom_meminit(void)
+{
+ struct prom_pmemblock *p;
+
+#ifdef DEBUG
+ pr_debug("YAMON MEMORY DESCRIPTOR dump:\n");
+ p = prom_getmdesc();
+ while (p->size) {
+ int i = 0;
+ pr_debug("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n",
+ i, p, p->base, p->size, mtypes[p->type]);
+ p++;
+ i++;
+ }
+#endif
+ p = prom_getmdesc();
+
+ while (p->size) {
+ long type;
+ unsigned long base, size;
+
+ type = prom_memtype_classify(p->type);
+ base = p->base;
+ size = p->size;
+
+ add_memory_region(base, size, type);
+ p++;
+ }
+}
+
+void __init prom_free_prom_memory(void)
+{
+ unsigned long addr;
+ int i;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ free_init_pages("prom memory",
+ addr, addr + boot_mem_map.map[i].size);
+ }
+}
diff --git a/arch/mips/mti-malta/malta-pci.c b/arch/mips/mti-malta/malta-pci.c
new file mode 100644
index 00000000..bf80921f
--- /dev/null
+++ b/arch/mips/mti-malta/malta-pci.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/gt64120.h>
+#include <asm/gcmpregs.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/bonito64.h>
+#include <asm/mips-boards/msc01_pci.h>
+
+static struct resource bonito64_mem_resource = {
+ .name = "Bonito PCI MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bonito64_io_resource = {
+ .name = "Bonito PCI I/O",
+ .start = 0x00000000UL,
+ .end = 0x000fffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource gt64120_mem_resource = {
+ .name = "GT-64120 PCI MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource gt64120_io_resource = {
+ .name = "GT-64120 PCI I/O",
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource msc_mem_resource = {
+ .name = "MSC PCI MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource msc_io_resource = {
+ .name = "MSC PCI I/O",
+ .flags = IORESOURCE_IO,
+};
+
+extern struct pci_ops bonito64_pci_ops;
+extern struct pci_ops gt64xxx_pci0_ops;
+extern struct pci_ops msc_pci_ops;
+
+static struct pci_controller bonito64_controller = {
+ .pci_ops = &bonito64_pci_ops,
+ .io_resource = &bonito64_io_resource,
+ .mem_resource = &bonito64_mem_resource,
+ .io_offset = 0x00000000UL,
+};
+
+static struct pci_controller gt64120_controller = {
+ .pci_ops = &gt64xxx_pci0_ops,
+ .io_resource = &gt64120_io_resource,
+ .mem_resource = &gt64120_mem_resource,
+};
+
+static struct pci_controller msc_controller = {
+ .pci_ops = &msc_pci_ops,
+ .io_resource = &msc_io_resource,
+ .mem_resource = &msc_mem_resource,
+};
+
+void __init mips_pcibios_init(void)
+{
+ struct pci_controller *controller;
+ resource_size_t start, end, map, start1, end1, map1, map2, map3, mask;
+
+ switch (mips_revision_sconid) {
+ case MIPS_REVISION_SCON_GT64120:
+ /*
+ * Due to a bug in the Galileo system controller, we need
+ * to setup the PCI BAR for the Galileo internal registers.
+ * This should be done in the bios/bootprom and will be
+ * fixed in a later revision of YAMON (the MIPS boards
+ * boot prom).
+ */
+ GT_WRITE(GT_PCI0_CFGADDR_OFS,
+ (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
+ (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
+ (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
+ ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
+ GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+ /* Perform the write */
+ GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+
+ /* Set up resource ranges from the controller's registers. */
+ start = GT_READ(GT_PCI0M0LD_OFS);
+ end = GT_READ(GT_PCI0M0HD_OFS);
+ map = GT_READ(GT_PCI0M0REMAP_OFS);
+ end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+ start1 = GT_READ(GT_PCI0M1LD_OFS);
+ end1 = GT_READ(GT_PCI0M1HD_OFS);
+ map1 = GT_READ(GT_PCI0M1REMAP_OFS);
+ end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
+ /* Cannot support multiple windows, use the wider. */
+ if (end1 - start1 > end - start) {
+ start = start1;
+ end = end1;
+ map = map1;
+ }
+ mask = ~(start ^ end);
+ /* We don't support remapping with a discontiguous mask. */
+ BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+ mask != ~((mask & -mask) - 1));
+ gt64120_mem_resource.start = start;
+ gt64120_mem_resource.end = end;
+ gt64120_controller.mem_offset = (start & mask) - (map & mask);
+ /* Addresses are 36-bit, so do shifts in the destinations. */
+ gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
+ gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
+ gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+ gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
+
+ start = GT_READ(GT_PCI0IOLD_OFS);
+ end = GT_READ(GT_PCI0IOHD_OFS);
+ map = GT_READ(GT_PCI0IOREMAP_OFS);
+ end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+ mask = ~(start ^ end);
+ /* We don't support remapping with a discontiguous mask. */
+ BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+ mask != ~((mask & -mask) - 1));
+ gt64120_io_resource.start = map & mask;
+ gt64120_io_resource.end = (map & mask) | ~mask;
+ gt64120_controller.io_offset = 0;
+ /* Addresses are 36-bit, so do shifts in the destinations. */
+ gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
+ gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
+ gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+
+ controller = &gt64120_controller;
+ break;
+
+ case MIPS_REVISION_SCON_BONITO:
+ /* Set up resource ranges from the controller's registers. */
+ map = BONITO_PCIMAP;
+ map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
+ BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
+ map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
+ BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
+ map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
+ BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
+ /* Combine as many adjacent windows as possible. */
+ map = map1;
+ start = BONITO_PCILO0_BASE;
+ end = 1;
+ if (map3 == map2 + 1) {
+ map = map2;
+ start = BONITO_PCILO1_BASE;
+ end++;
+ }
+ if (map2 == map1 + 1) {
+ map = map1;
+ start = BONITO_PCILO0_BASE;
+ end++;
+ }
+ bonito64_mem_resource.start = start;
+ bonito64_mem_resource.end = start +
+ BONITO_PCIMAP_WINBASE(end) - 1;
+ bonito64_controller.mem_offset = start -
+ BONITO_PCIMAP_WINBASE(map);
+
+ controller = &bonito64_controller;
+ break;
+
+ case MIPS_REVISION_SCON_SOCIT:
+ case MIPS_REVISION_SCON_ROCIT:
+ case MIPS_REVISION_SCON_SOCITSC:
+ case MIPS_REVISION_SCON_SOCITSCP:
+ /* Set up resource ranges from the controller's registers. */
+ MSC_READ(MSC01_PCI_SC2PMBASL, start);
+ MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
+ MSC_READ(MSC01_PCI_SC2PMMAPL, map);
+ msc_mem_resource.start = start & mask;
+ msc_mem_resource.end = (start & mask) | ~mask;
+ msc_controller.mem_offset = (start & mask) - (map & mask);
+#ifdef CONFIG_MIPS_CMP
+ if (gcmp_niocu())
+ gcmp_setregion(0, start, mask,
+ GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
+#endif
+ MSC_READ(MSC01_PCI_SC2PIOBASL, start);
+ MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
+ MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
+ msc_io_resource.start = map & mask;
+ msc_io_resource.end = (map & mask) | ~mask;
+ msc_controller.io_offset = 0;
+ ioport_resource.end = ~mask;
+#ifdef CONFIG_MIPS_CMP
+ if (gcmp_niocu())
+ gcmp_setregion(1, start, mask,
+ GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
+#endif
+ /* If ranges overlap I/O takes precedence. */
+ start = start & mask;
+ end = start | ~mask;
+ if ((start >= msc_mem_resource.start &&
+ start <= msc_mem_resource.end) ||
+ (end >= msc_mem_resource.start &&
+ end <= msc_mem_resource.end)) {
+ /* Use the larger space. */
+ start = max(start, msc_mem_resource.start);
+ end = min(end, msc_mem_resource.end);
+ if (start - msc_mem_resource.start >=
+ msc_mem_resource.end - end)
+ msc_mem_resource.end = start - 1;
+ else
+ msc_mem_resource.start = end + 1;
+ }
+
+ controller = &msc_controller;
+ break;
+ default:
+ return;
+ }
+
+ if (controller->io_resource->start < 0x00001000UL) /* FIXME */
+ controller->io_resource->start = 0x00001000UL;
+
+ iomem_resource.end &= 0xfffffffffULL; /* 64 GB */
+ ioport_resource.end = controller->io_resource->end;
+
+ controller->io_map_base = mips_io_port_base;
+
+ register_pci_controller(controller);
+}
+
+/* Enable PCI 2.1 compatibility in PIIX4 */
+static void __init quirk_dlcsetup(struct pci_dev *dev)
+{
+ u8 odlc, ndlc;
+ (void) pci_read_config_byte(dev, 0x82, &odlc);
+ /* Enable passive releases and delayed transaction */
+ ndlc = odlc | 7;
+ (void) pci_write_config_byte(dev, 0x82, ndlc);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
+ quirk_dlcsetup);
diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c
new file mode 100644
index 00000000..4c353017
--- /dev/null
+++ b/arch/mips/mti-malta/malta-platform.c
@@ -0,0 +1,149 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006, 07 MIPS Technologies, Inc.
+ * written by Ralf Baechle (ralf@linux-mips.org)
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ *
+ * Copyright (C) 2008 Wind River Systems, Inc.
+ * updated by Tiejun Chen <tiejun.chen@windriver.com>
+ *
+ * 1. Probe driver for the Malta's UART ports:
+ *
+ * o 2 ports in the SMC SuperIO
+ * o 1 port in the CBUS UART, a discrete 16550 which normally is only used
+ * for bringups.
+ *
+ * We don't use 8250_platform.c on Malta as it would result in the CBUS
+ * UART becoming ttyS0.
+ *
+ * 2. Register RTC-CMOS platform device on Malta.
+ */
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+#include <linux/mc146818rtc.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <mtd/mtd-abi.h>
+
+#define SMC_PORT(base, int) \
+{ \
+ .iobase = base, \
+ .irq = int, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
+ .regshift = 0, \
+}
+
+#define CBUS_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+
+static struct plat_serial8250_port uart8250_data[] = {
+ SMC_PORT(0x3F8, 4),
+ SMC_PORT(0x2F8, 3),
+ {
+ .mapbase = 0x1f000900, /* The CBUS UART */
+ .irq = MIPS_CPU_IRQ_BASE + 2,
+ .uartclk = 3686400, /* Twice the usual clk! */
+ .iotype = UPIO_MEM32,
+ .flags = CBUS_UART_FLAGS,
+ .regshift = 3,
+ },
+ { },
+};
+
+static struct platform_device malta_uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = uart8250_data,
+ },
+};
+
+struct resource malta_rtc_resources[] = {
+ {
+ .start = RTC_PORT(0),
+ .end = RTC_PORT(7),
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = RTC_IRQ,
+ .end = RTC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device malta_rtc_device = {
+ .name = "rtc_cmos",
+ .id = -1,
+ .resource = malta_rtc_resources,
+ .num_resources = ARRAY_SIZE(malta_rtc_resources),
+};
+
+static struct mtd_partition malta_mtd_partitions[] = {
+ {
+ .name = "YAMON",
+ .offset = 0x0,
+ .size = 0x100000,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "User FS",
+ .offset = 0x100000,
+ .size = 0x2e0000
+ }, {
+ .name = "Board Config",
+ .offset = 0x3e0000,
+ .size = 0x020000,
+ .mask_flags = MTD_WRITEABLE
+ }
+};
+
+static struct physmap_flash_data malta_flash_data = {
+ .width = 4,
+ .nr_parts = ARRAY_SIZE(malta_mtd_partitions),
+ .parts = malta_mtd_partitions
+};
+
+static struct resource malta_flash_resource = {
+ .start = 0x1e000000,
+ .end = 0x1e3fffff,
+ .flags = IORESOURCE_MEM
+};
+
+static struct platform_device malta_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &malta_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &malta_flash_resource,
+};
+
+static struct platform_device *malta_devices[] __initdata = {
+ &malta_uart8250_device,
+ &malta_rtc_device,
+ &malta_flash_device,
+};
+
+static int __init malta_add_devices(void)
+{
+ int err;
+
+ err = platform_add_devices(malta_devices, ARRAY_SIZE(malta_devices));
+ if (err)
+ return err;
+
+ /*
+ * Set RTC to BCD mode to support current alarm code.
+ */
+ CMOS_WRITE(CMOS_READ(RTC_CONTROL) & ~RTC_DM_BINARY, RTC_CONTROL);
+
+ return 0;
+}
+
+device_initcall(malta_add_devices);
diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c
new file mode 100644
index 00000000..32942053
--- /dev/null
+++ b/arch/mips/mti-malta/malta-reset.c
@@ -0,0 +1,58 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Reset the MIPS boards.
+ *
+ */
+#include <linux/init.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/mips-boards/generic.h>
+
+static void mips_machine_restart(char *command)
+{
+ unsigned int __iomem *softres_reg =
+ ioremap(SOFTRES_REG, sizeof(unsigned int));
+
+ __raw_writel(GORESET, softres_reg);
+}
+
+static void mips_machine_halt(void)
+{
+ unsigned int __iomem *softres_reg =
+ ioremap(SOFTRES_REG, sizeof(unsigned int));
+
+ __raw_writel(GORESET, softres_reg);
+}
+
+
+static int __init mips_reboot_setup(void)
+{
+ _machine_restart = mips_machine_restart;
+ _machine_halt = mips_machine_halt;
+ pm_power_off = mips_machine_halt;
+
+ return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
new file mode 100644
index 00000000..b7f37d49
--- /dev/null
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -0,0 +1,224 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ * Copyright (C) 2008 Dmitri Vorobiev
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/cpu.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/screen_info.h>
+#include <linux/time.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/malta.h>
+#include <asm/mips-boards/maltaint.h>
+#include <asm/dma.h>
+#include <asm/traps.h>
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#endif
+
+extern void malta_be_init(void);
+extern int malta_be_handler(struct pt_regs *regs, int is_fixup);
+
+static struct resource standard_io_resources[] = {
+ {
+ .name = "dma1",
+ .start = 0x00,
+ .end = 0x1f,
+ .flags = IORESOURCE_BUSY
+ },
+ {
+ .name = "timer",
+ .start = 0x40,
+ .end = 0x5f,
+ .flags = IORESOURCE_BUSY
+ },
+ {
+ .name = "keyboard",
+ .start = 0x60,
+ .end = 0x6f,
+ .flags = IORESOURCE_BUSY
+ },
+ {
+ .name = "dma page reg",
+ .start = 0x80,
+ .end = 0x8f,
+ .flags = IORESOURCE_BUSY
+ },
+ {
+ .name = "dma2",
+ .start = 0xc0,
+ .end = 0xdf,
+ .flags = IORESOURCE_BUSY
+ },
+};
+
+const char *get_system_type(void)
+{
+ return "MIPS Malta";
+}
+
+#if defined(CONFIG_MIPS_MT_SMTC)
+const char display_string[] = " SMTC LINUX ON MALTA ";
+#else
+const char display_string[] = " LINUX ON MALTA ";
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+#ifdef CONFIG_BLK_DEV_FD
+static void __init fd_activate(void)
+{
+ /*
+ * Activate Floppy Controller in the SMSC FDC37M817 Super I/O
+ * Controller.
+ * Done by YAMON 2.00 onwards
+ */
+ /* Entering config state. */
+ SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG);
+
+ /* Activate floppy controller. */
+ SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG);
+ SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG);
+ SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG);
+ SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG);
+
+ /* Exit config state. */
+ SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG);
+}
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+static void __init pci_clock_check(void)
+{
+ unsigned int __iomem *jmpr_p =
+ (unsigned int *) ioremap(MALTA_JMPRS_REG, sizeof(unsigned int));
+ int jmpr = (__raw_readl(jmpr_p) >> 2) & 0x07;
+ static const int pciclocks[] __initdata = {
+ 33, 20, 25, 30, 12, 16, 37, 10
+ };
+ int pciclock = pciclocks[jmpr];
+ char *argptr = prom_getcmdline();
+
+ if (pciclock != 33 && !strstr(argptr, "idebus=")) {
+ printk(KERN_WARNING "WARNING: PCI clock is %dMHz, "
+ "setting idebus\n", pciclock);
+ argptr += strlen(argptr);
+ sprintf(argptr, " idebus=%d", pciclock);
+ if (pciclock < 20 || pciclock > 66)
+ printk(KERN_WARNING "WARNING: IDE timing "
+ "calculations will be incorrect\n");
+ }
+}
+#endif
+
+#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
+static void __init screen_info_setup(void)
+{
+ screen_info = (struct screen_info) {
+ .orig_x = 0,
+ .orig_y = 25,
+ .ext_mem_k = 0,
+ .orig_video_page = 0,
+ .orig_video_mode = 0,
+ .orig_video_cols = 80,
+ .unused2 = 0,
+ .orig_video_ega_bx = 0,
+ .unused3 = 0,
+ .orig_video_lines = 25,
+ .orig_video_isVGA = VIDEO_TYPE_VGAC,
+ .orig_video_points = 16
+ };
+}
+#endif
+
+static void __init bonito_quirks_setup(void)
+{
+ char *argptr;
+
+ argptr = prom_getcmdline();
+ if (strstr(argptr, "debug")) {
+ BONITO_BONGENCFG |= BONITO_BONGENCFG_DEBUGMODE;
+ printk(KERN_INFO "Enabled Bonito debug mode\n");
+ } else
+ BONITO_BONGENCFG &= ~BONITO_BONGENCFG_DEBUGMODE;
+
+#ifdef CONFIG_DMA_COHERENT
+ if (BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CPUCOH_PRES) {
+ BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_CPUCOH_EN;
+ printk(KERN_INFO "Enabled Bonito CPU coherency\n");
+
+ argptr = prom_getcmdline();
+ if (strstr(argptr, "iobcuncached")) {
+ BONITO_PCICACHECTRL &= ~BONITO_PCICACHECTRL_IOBCCOH_EN;
+ BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
+ ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
+ BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
+ printk(KERN_INFO "Disabled Bonito IOBC coherency\n");
+ } else {
+ BONITO_PCICACHECTRL |= BONITO_PCICACHECTRL_IOBCCOH_EN;
+ BONITO_PCIMEMBASECFG |=
+ (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
+ BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
+ printk(KERN_INFO "Enabled Bonito IOBC coherency\n");
+ }
+ } else
+ panic("Hardware DMA cache coherency not supported");
+#endif
+}
+
+void __init plat_mem_setup(void)
+{
+ unsigned int i;
+
+ mips_pcibios_init();
+
+ /* Request I/O space for devices used on the Malta board. */
+ for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
+ request_resource(&ioport_resource, standard_io_resources+i);
+
+ /*
+ * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge.
+ */
+ enable_dma(4);
+
+#ifdef CONFIG_DMA_COHERENT
+ if (mips_revision_sconid != MIPS_REVISION_SCON_BONITO)
+ panic("Hardware DMA cache coherency not supported");
+#endif
+
+ if (mips_revision_sconid == MIPS_REVISION_SCON_BONITO)
+ bonito_quirks_setup();
+
+#ifdef CONFIG_BLK_DEV_IDE
+ pci_clock_check();
+#endif
+
+#ifdef CONFIG_BLK_DEV_FD
+ fd_activate();
+#endif
+
+#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
+ screen_info_setup();
+#endif
+
+ board_be_init = malta_be_init;
+ board_be_handler = malta_be_handler;
+}
diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c
new file mode 100644
index 00000000..49a38b09
--- /dev/null
+++ b/arch/mips/mti-malta/malta-smtc.c
@@ -0,0 +1,162 @@
+/*
+ * Malta Platform-specific hooks for SMP operation
+ */
+#include <linux/irq.h>
+#include <linux/init.h>
+
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/smtc.h>
+#include <asm/smtc_ipi.h>
+
+/* VPE/SMP Prototype implements platform interfaces directly */
+
+/*
+ * Cause the specified action to be performed on a targeted "CPU"
+ */
+
+static void msmtc_send_ipi_single(int cpu, unsigned int action)
+{
+ /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
+ smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
+}
+
+static void msmtc_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ msmtc_send_ipi_single(i, action);
+}
+
+/*
+ * Post-config but pre-boot cleanup entry point
+ */
+static void __cpuinit msmtc_init_secondary(void)
+{
+ int myvpe;
+
+ /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
+ myvpe = read_c0_tcbind() & TCBIND_CURVPE;
+ if (myvpe != 0) {
+ /* Ideally, this should be done only once per VPE, but... */
+ clear_c0_status(ST0_IM);
+ set_c0_status((0x100 << cp0_compare_irq)
+ | (0x100 << MIPS_CPU_IPI_IRQ));
+ if (cp0_perfcount_irq >= 0)
+ set_c0_status(0x100 << cp0_perfcount_irq);
+ }
+
+ smtc_init_secondary();
+}
+
+/*
+ * Platform "CPU" startup hook
+ */
+static void __cpuinit msmtc_boot_secondary(int cpu, struct task_struct *idle)
+{
+ smtc_boot_secondary(cpu, idle);
+}
+
+/*
+ * SMP initialization finalization entry point
+ */
+static void __cpuinit msmtc_smp_finish(void)
+{
+ smtc_smp_finish();
+}
+
+/*
+ * Hook for after all CPUs are online
+ */
+
+static void msmtc_cpus_done(void)
+{
+}
+
+/*
+ * Platform SMP pre-initialization
+ *
+ * As noted above, we can assume a single CPU for now
+ * but it may be multithreaded.
+ */
+
+static void __init msmtc_smp_setup(void)
+{
+ /*
+ * we won't get the definitive value until
+ * we've run smtc_prepare_cpus later, but
+ * we would appear to need an upper bound now.
+ */
+ smp_num_siblings = smtc_build_cpu_map(0);
+}
+
+static void __init msmtc_prepare_cpus(unsigned int max_cpus)
+{
+ smtc_prepare_cpus(max_cpus);
+}
+
+struct plat_smp_ops msmtc_smp_ops = {
+ .send_ipi_single = msmtc_send_ipi_single,
+ .send_ipi_mask = msmtc_send_ipi_mask,
+ .init_secondary = msmtc_init_secondary,
+ .smp_finish = msmtc_smp_finish,
+ .cpus_done = msmtc_cpus_done,
+ .boot_secondary = msmtc_boot_secondary,
+ .smp_setup = msmtc_smp_setup,
+ .prepare_cpus = msmtc_prepare_cpus,
+};
+
+#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
+/*
+ * IRQ affinity hook
+ */
+
+
+int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity,
+ bool force)
+{
+ cpumask_t tmask;
+ int cpu = 0;
+ void smtc_set_irq_affinity(unsigned int irq, cpumask_t aff);
+
+ /*
+ * On the legacy Malta development board, all I/O interrupts
+ * are routed through the 8259 and combined in a single signal
+ * to the CPU daughterboard, and on the CoreFPGA2/3 34K models,
+ * that signal is brought to IP2 of both VPEs. To avoid racing
+ * concurrent interrupt service events, IP2 is enabled only on
+ * one VPE, by convention VPE0. So long as no bits are ever
+ * cleared in the affinity mask, there will never be any
+ * interrupt forwarding. But as soon as a program or operator
+ * sets affinity for one of the related IRQs, we need to make
+ * sure that we don't ever try to forward across the VPE boundary,
+ * at least not until we engineer a system where the interrupt
+ * _ack() or _end() function can somehow know that it corresponds
+ * to an interrupt taken on another VPE, and perform the appropriate
+ * restoration of Status.IM state using MFTR/MTTR instead of the
+ * normal local behavior. We also ensure that no attempt will
+ * be made to forward to an offline "CPU".
+ */
+
+ cpumask_copy(&tmask, affinity);
+ for_each_cpu(cpu, affinity) {
+ if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu))
+ cpu_clear(cpu, tmask);
+ }
+ cpumask_copy(d->affinity, &tmask);
+
+ if (cpus_empty(tmask))
+ /*
+ * We could restore a default mask here, but the
+ * runtime code can anyway deal with the null set
+ */
+ printk(KERN_WARNING
+ "IRQ affinity leaves no legal CPU for IRQ %d\n", irq);
+
+ /* Do any generic SMTC IRQ affinity setup */
+ smtc_set_irq_affinity(d->irq, tmask);
+
+ return IRQ_SET_MASK_OK_NOCOPY;
+}
+#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
new file mode 100644
index 00000000..1620b83c
--- /dev/null
+++ b/arch/mips/mti-malta/malta-time.c
@@ -0,0 +1,164 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/hardirq.h>
+#include <asm/i8253.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/mc146818-time.h>
+#include <asm/msc01_ic.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+#include <asm/mips-boards/maltaint.h>
+
+unsigned long cpu_khz;
+
+static int mips_cpu_timer_irq;
+static int mips_cpu_perf_irq;
+extern int cp0_perfcount_irq;
+
+static void mips_timer_dispatch(void)
+{
+ do_IRQ(mips_cpu_timer_irq);
+}
+
+static void mips_perf_dispatch(void)
+{
+ do_IRQ(mips_cpu_perf_irq);
+}
+
+/*
+ * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
+ */
+static unsigned int __init estimate_cpu_frequency(void)
+{
+ unsigned int prid = read_c0_prid() & 0xffff00;
+ unsigned int count;
+
+ unsigned long flags;
+ unsigned int start;
+
+ local_irq_save(flags);
+
+ /* Start counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ /* Start r4k counter. */
+ start = read_c0_count();
+
+ /* Read counter exactly on falling edge of update flag */
+ while (CMOS_READ(RTC_REG_A) & RTC_UIP);
+ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
+
+ count = read_c0_count() - start;
+
+ /* restore interrupts */
+ local_irq_restore(flags);
+
+ mips_hpt_frequency = count;
+ if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+ (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+ count *= 2;
+
+ count += 5000; /* round */
+ count -= count%10000;
+
+ return count;
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+ ts->tv_sec = mc146818_get_cmos_time();
+ ts->tv_nsec = 0;
+}
+
+static void __init plat_perf_setup(void)
+{
+#ifdef MSC01E_INT_BASE
+ if (cpu_has_veic) {
+ set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
+ mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
+ } else
+#endif
+ if (cp0_perfcount_irq >= 0) {
+ if (cpu_has_vint)
+ set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
+ mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
+#ifdef CONFIG_SMP
+ irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq);
+#endif
+ }
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+#ifdef MSC01E_INT_BASE
+ if (cpu_has_veic) {
+ set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
+ mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
+ } else
+#endif
+ {
+ if (cpu_has_vint)
+ set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
+ mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+ }
+
+ return mips_cpu_timer_irq;
+}
+
+void __init plat_time_init(void)
+{
+ unsigned int est_freq;
+
+ /* Set Data mode - binary. */
+ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+
+ est_freq = estimate_cpu_frequency();
+
+ printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+ (est_freq%1000000)*100/1000000);
+
+ cpu_khz = est_freq / 1000;
+
+ mips_scroll_message();
+#ifdef CONFIG_I8253 /* Only Malta has a PIT */
+ setup_pit_timer();
+#endif
+
+ plat_perf_setup();
+}
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig
new file mode 100644
index 00000000..a5ca7436
--- /dev/null
+++ b/arch/mips/netlogic/Kconfig
@@ -0,0 +1,5 @@
+config NLM_COMMON
+ bool
+
+config NLM_XLR
+ bool
diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile
new file mode 100644
index 00000000..9bd3f731
--- /dev/null
+++ b/arch/mips/netlogic/xlr/Makefile
@@ -0,0 +1,5 @@
+obj-y += setup.o platform.o irq.o setup.o time.o
+obj-$(CONFIG_SMP) += smp.o smpboot.o
+obj-$(CONFIG_EARLY_PRINTK) += xlr_console.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/netlogic/xlr/irq.c b/arch/mips/netlogic/xlr/irq.c
new file mode 100644
index 00000000..1446d58e
--- /dev/null
+++ b/arch/mips/netlogic/xlr/irq.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/mips-extns.h>
+
+static u64 nlm_irq_mask;
+static DEFINE_SPINLOCK(nlm_pic_lock);
+
+static void xlr_pic_enable(struct irq_data *d)
+{
+ nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+ unsigned long flags;
+ nlm_reg_t reg;
+ int irq = d->irq;
+
+ WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
+
+ spin_lock_irqsave(&nlm_pic_lock, flags);
+ reg = netlogic_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE);
+ netlogic_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE,
+ reg | (1 << 6) | (1 << 30) | (1 << 31));
+ spin_unlock_irqrestore(&nlm_pic_lock, flags);
+}
+
+static void xlr_pic_mask(struct irq_data *d)
+{
+ nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+ unsigned long flags;
+ nlm_reg_t reg;
+ int irq = d->irq;
+
+ WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
+
+ spin_lock_irqsave(&nlm_pic_lock, flags);
+ reg = netlogic_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE);
+ netlogic_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE,
+ reg | (1 << 6) | (1 << 30) | (0 << 31));
+ spin_unlock_irqrestore(&nlm_pic_lock, flags);
+}
+
+#ifdef CONFIG_PCI
+/* Extra ACK needed for XLR on chip PCI controller */
+static void xlr_pci_ack(struct irq_data *d)
+{
+ nlm_reg_t *pci_mmio = netlogic_io_mmio(NETLOGIC_IO_PCIX_OFFSET);
+
+ netlogic_read_reg(pci_mmio, (0x140 >> 2));
+}
+
+/* Extra ACK needed for XLS on chip PCIe controller */
+static void xls_pcie_ack(struct irq_data *d)
+{
+ nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET);
+
+ switch (d->irq) {
+ case PIC_PCIE_LINK0_IRQ:
+ netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_LINK1_IRQ:
+ netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_LINK2_IRQ:
+ netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_LINK3_IRQ:
+ netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff);
+ break;
+ }
+}
+
+/* For XLS B silicon, the 3,4 PCI interrupts are different */
+static void xls_pcie_ack_b(struct irq_data *d)
+{
+ nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET);
+
+ switch (d->irq) {
+ case PIC_PCIE_LINK0_IRQ:
+ netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_LINK1_IRQ:
+ netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_XLSB0_LINK2_IRQ:
+ netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_XLSB0_LINK3_IRQ:
+ netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff);
+ break;
+ }
+}
+#endif
+
+static void xlr_pic_ack(struct irq_data *d)
+{
+ unsigned long flags;
+ nlm_reg_t *mmio;
+ int irq = d->irq;
+ void *hd = irq_data_get_irq_handler_data(d);
+
+ WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
+
+ if (hd) {
+ void (*extra_ack)(void *) = hd;
+ extra_ack(d);
+ }
+ mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+ spin_lock_irqsave(&nlm_pic_lock, flags);
+ netlogic_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
+ spin_unlock_irqrestore(&nlm_pic_lock, flags);
+}
+
+/*
+ * This chip definition handles interrupts routed thru the XLR
+ * hardware PIC, currently IRQs 8-39 are mapped to hardware intr
+ * 0-31 wired the XLR PIC
+ */
+static struct irq_chip xlr_pic = {
+ .name = "XLR-PIC",
+ .irq_enable = xlr_pic_enable,
+ .irq_mask = xlr_pic_mask,
+ .irq_ack = xlr_pic_ack,
+};
+
+static void rsvd_irq_handler(struct irq_data *d)
+{
+ WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq);
+}
+
+/*
+ * Chip definition for CPU originated interrupts(timer, msg) and
+ * IPIs
+ */
+struct irq_chip nlm_cpu_intr = {
+ .name = "XLR-CPU-INTR",
+ .irq_enable = rsvd_irq_handler,
+ .irq_mask = rsvd_irq_handler,
+ .irq_ack = rsvd_irq_handler,
+};
+
+void __init init_xlr_irqs(void)
+{
+ nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+ uint32_t thread_mask = 1;
+ int level, i;
+
+ pr_info("Interrupt thread mask [%x]\n", thread_mask);
+ for (i = 0; i < PIC_NUM_IRTS; i++) {
+ level = PIC_IRQ_IS_EDGE_TRIGGERED(i);
+
+ /* Bind all PIC irqs to boot cpu */
+ netlogic_write_reg(mmio, PIC_IRT_0_BASE + i, thread_mask);
+
+ /*
+ * Use local scheduling and high polarity for all IRTs
+ * Invalidate all IRTs, by default
+ */
+ netlogic_write_reg(mmio, PIC_IRT_1_BASE + i,
+ (level << 30) | (1 << 6) | (PIC_IRQ_BASE + i));
+ }
+
+ /* Make all IRQs as level triggered by default */
+ for (i = 0; i < NR_IRQS; i++) {
+ if (PIC_IRQ_IS_IRT(i))
+ irq_set_chip_and_handler(i, &xlr_pic, handle_level_irq);
+ else
+ irq_set_chip_and_handler(i, &nlm_cpu_intr,
+ handle_level_irq);
+ }
+#ifdef CONFIG_SMP
+ irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr,
+ nlm_smp_function_ipi_handler);
+ irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,
+ nlm_smp_resched_ipi_handler);
+ nlm_irq_mask |=
+ ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));
+#endif
+
+#ifdef CONFIG_PCI
+ /*
+ * For PCI interrupts, we need to ack the PIC controller too, overload
+ * irq handler data to do this
+ */
+ if (nlm_chip_is_xls()) {
+ if (nlm_chip_is_xls_b()) {
+ irq_set_handler_data(PIC_PCIE_LINK0_IRQ,
+ xls_pcie_ack_b);
+ irq_set_handler_data(PIC_PCIE_LINK1_IRQ,
+ xls_pcie_ack_b);
+ irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ,
+ xls_pcie_ack_b);
+ irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ,
+ xls_pcie_ack_b);
+ } else {
+ irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack);
+ irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack);
+ irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack);
+ irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack);
+ }
+ } else {
+ /* XLR PCI controller ACK */
+ irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack);
+ }
+#endif
+ /* unmask all PIC related interrupts. If no handler is installed by the
+ * drivers, it'll just ack the interrupt and return
+ */
+ for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++)
+ nlm_irq_mask |= (1ULL << i);
+
+ nlm_irq_mask |= (1ULL << IRQ_TIMER);
+}
+
+void __init arch_init_irq(void)
+{
+ /* Initialize the irq descriptors */
+ init_xlr_irqs();
+ write_c0_eimr(nlm_irq_mask);
+}
+
+void __cpuinit nlm_smp_irq_init(void)
+{
+ /* set interrupt mask for non-zero cpus */
+ write_c0_eimr(nlm_irq_mask);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ uint64_t eirr;
+ int i;
+
+ eirr = read_c0_eirr() & read_c0_eimr();
+ if (!eirr)
+ return;
+
+ /* no need of EIRR here, writing compare clears interrupt */
+ if (eirr & (1 << IRQ_TIMER)) {
+ do_IRQ(IRQ_TIMER);
+ return;
+ }
+
+ /* use dcltz: optimize below code */
+ for (i = 63; i != -1; i--) {
+ if (eirr & (1ULL << i))
+ break;
+ }
+ if (i == -1) {
+ pr_err("no interrupt !!\n");
+ return;
+ }
+
+ /* Ack eirr */
+ write_c0_eirr(1ULL << i);
+
+ do_IRQ(i);
+}
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c
new file mode 100644
index 00000000..609ec253
--- /dev/null
+++ b/arch/mips/netlogic/xlr/platform.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2011, Netlogic Microsystems.
+ * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
+{
+ nlm_reg_t *mmio;
+ unsigned int value;
+
+ /* XLR uart does not need any mapping of regs */
+ mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift));
+ value = netlogic_read_reg(mmio, 0);
+
+ /* See XLR/XLS errata */
+ if (offset == UART_MSR)
+ value ^= 0xF0;
+ else if (offset == UART_MCR)
+ value ^= 0x3;
+
+ return value;
+}
+
+void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
+{
+ nlm_reg_t *mmio;
+
+ /* XLR uart does not need any mapping of regs */
+ mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift));
+
+ /* See XLR/XLS errata */
+ if (offset == UART_MSR)
+ value ^= 0xF0;
+ else if (offset == UART_MCR)
+ value ^= 0x3;
+
+ netlogic_write_reg(mmio, 0, value);
+}
+
+#define PORT(_irq) \
+ { \
+ .irq = _irq, \
+ .regshift = 2, \
+ .iotype = UPIO_MEM32, \
+ .flags = (UPF_SKIP_TEST | \
+ UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
+ .uartclk = PIC_CLKS_PER_SEC, \
+ .type = PORT_16550A, \
+ .serial_in = nlm_xlr_uart_in, \
+ .serial_out = nlm_xlr_uart_out, \
+ }
+
+static struct plat_serial8250_port xlr_uart_data[] = {
+ PORT(PIC_UART_0_IRQ),
+ PORT(PIC_UART_1_IRQ),
+ {},
+};
+
+static struct platform_device uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = xlr_uart_data,
+ },
+};
+
+static int __init nlm_uart_init(void)
+{
+ nlm_reg_t *mmio;
+
+ mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
+ xlr_uart_data[0].membase = (void __iomem *)mmio;
+ xlr_uart_data[0].mapbase = CPHYSADDR((unsigned long)mmio);
+
+ mmio = netlogic_io_mmio(NETLOGIC_IO_UART_1_OFFSET);
+ xlr_uart_data[1].membase = (void __iomem *)mmio;
+ xlr_uart_data[1].mapbase = CPHYSADDR((unsigned long)mmio);
+
+ return platform_device_register(&uart_device);
+}
+
+arch_initcall(nlm_uart_init);
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c
new file mode 100644
index 00000000..48280256
--- /dev/null
+++ b/arch/mips/netlogic/xlr/setup.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial_8250.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/smp-ops.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/psb-bootinfo.h>
+
+#include <asm/netlogic/xlr/xlr.h>
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/gpio.h>
+
+unsigned long netlogic_io_base = (unsigned long)(DEFAULT_NETLOGIC_IO_BASE);
+unsigned long nlm_common_ebase = 0x0;
+struct psb_info nlm_prom_info;
+
+static void nlm_early_serial_setup(void)
+{
+ struct uart_port s;
+ nlm_reg_t *uart_base;
+
+ uart_base = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
+ memset(&s, 0, sizeof(s));
+ s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+ s.iotype = UPIO_MEM32;
+ s.regshift = 2;
+ s.irq = PIC_UART_0_IRQ;
+ s.uartclk = PIC_CLKS_PER_SEC;
+ s.serial_in = nlm_xlr_uart_in;
+ s.serial_out = nlm_xlr_uart_out;
+ s.mapbase = (unsigned long)uart_base;
+ s.membase = (unsigned char __iomem *)uart_base;
+ early_serial_setup(&s);
+}
+
+static void nlm_linux_exit(void)
+{
+ nlm_reg_t *mmio;
+
+ mmio = netlogic_io_mmio(NETLOGIC_IO_GPIO_OFFSET);
+ /* trigger a chip reset by writing 1 to GPIO_SWRESET_REG */
+ netlogic_write_reg(mmio, NETLOGIC_GPIO_SWRESET_REG, 1);
+ for ( ; ; )
+ cpu_wait();
+}
+
+void __init plat_mem_setup(void)
+{
+ panic_timeout = 5;
+ _machine_restart = (void (*)(char *))nlm_linux_exit;
+ _machine_halt = nlm_linux_exit;
+ pm_power_off = nlm_linux_exit;
+}
+
+const char *get_system_type(void)
+{
+ return "Netlogic XLR/XLS Series";
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* Nothing yet */
+}
+
+static void build_arcs_cmdline(int *argv)
+{
+ int i, remain, len;
+ char *arg;
+
+ remain = sizeof(arcs_cmdline) - 1;
+ arcs_cmdline[0] = '\0';
+ for (i = 0; argv[i] != 0; i++) {
+ arg = (char *)(long)argv[i];
+ len = strlen(arg);
+ if (len + 1 > remain)
+ break;
+ strcat(arcs_cmdline, arg);
+ strcat(arcs_cmdline, " ");
+ remain -= len + 1;
+ }
+
+ /* Add the default options here */
+ if ((strstr(arcs_cmdline, "console=")) == NULL) {
+ arg = "console=ttyS0,38400 ";
+ len = strlen(arg);
+ if (len > remain)
+ goto fail;
+ strcat(arcs_cmdline, arg);
+ remain -= len;
+ }
+#ifdef CONFIG_BLK_DEV_INITRD
+ if ((strstr(arcs_cmdline, "rdinit=")) == NULL) {
+ arg = "rdinit=/sbin/init ";
+ len = strlen(arg);
+ if (len > remain)
+ goto fail;
+ strcat(arcs_cmdline, arg);
+ remain -= len;
+ }
+#endif
+ return;
+fail:
+ panic("Cannot add %s, command line too big!", arg);
+}
+
+static void prom_add_memory(void)
+{
+ struct nlm_boot_mem_map *bootm;
+ u64 start, size;
+ u64 pref_backup = 512; /* avoid pref walking beyond end */
+ int i;
+
+ bootm = (void *)(long)nlm_prom_info.psb_mem_map;
+ for (i = 0; i < bootm->nr_map; i++) {
+ if (bootm->map[i].type != BOOT_MEM_RAM)
+ continue;
+ start = bootm->map[i].addr;
+ size = bootm->map[i].size;
+
+ /* Work around for using bootloader mem */
+ if (i == 0 && start == 0 && size == 0x0c000000)
+ size = 0x0ff00000;
+
+ add_memory_region(start, size - pref_backup, BOOT_MEM_RAM);
+ }
+}
+
+void __init prom_init(void)
+{
+ int *argv, *envp; /* passed as 32 bit ptrs */
+ struct psb_info *prom_infop;
+
+ /* truncate to 32 bit and sign extend all args */
+ argv = (int *)(long)(int)fw_arg1;
+ envp = (int *)(long)(int)fw_arg2;
+ prom_infop = (struct psb_info *)(long)(int)fw_arg3;
+
+ nlm_prom_info = *prom_infop;
+
+ nlm_early_serial_setup();
+ build_arcs_cmdline(argv);
+ nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
+ prom_add_memory();
+
+#ifdef CONFIG_SMP
+ nlm_wakeup_secondary_cpus(nlm_prom_info.online_cpu_map);
+ register_smp_ops(&nlm_smp_ops);
+#endif
+}
diff --git a/arch/mips/netlogic/xlr/smp.c b/arch/mips/netlogic/xlr/smp.c
new file mode 100644
index 00000000..b495a7f1
--- /dev/null
+++ b/arch/mips/netlogic/xlr/smp.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+
+#include <asm/mmu_context.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/mips-extns.h>
+
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+void core_send_ipi(int logical_cpu, unsigned int action)
+{
+ int cpu = cpu_logical_map(logical_cpu);
+ u32 tid = cpu & 0x3;
+ u32 pid = (cpu >> 2) & 0x07;
+ u32 ipi = (tid << 16) | (pid << 20);
+
+ if (action & SMP_CALL_FUNCTION)
+ ipi |= IRQ_IPI_SMP_FUNCTION;
+ else if (action & SMP_RESCHEDULE_YOURSELF)
+ ipi |= IRQ_IPI_SMP_RESCHEDULE;
+ else
+ return;
+
+ pic_send_ipi(ipi);
+}
+
+void nlm_send_ipi_single(int cpu, unsigned int action)
+{
+ core_send_ipi(cpu, action);
+}
+
+void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ int cpu;
+
+ for_each_cpu(cpu, mask) {
+ core_send_ipi(cpu, action);
+ }
+}
+
+/* IRQ_IPI_SMP_FUNCTION Handler */
+void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc)
+{
+ smp_call_function_interrupt();
+}
+
+/* IRQ_IPI_SMP_RESCHEDULE handler */
+void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc)
+{
+ set_need_resched();
+}
+
+void nlm_common_ipi_handler(int irq, struct pt_regs *regs)
+{
+ if (irq == IRQ_IPI_SMP_FUNCTION) {
+ smp_call_function_interrupt();
+ } else {
+ /* Announce that we are for reschduling */
+ set_need_resched();
+ }
+}
+
+/*
+ * Called before going into mips code, early cpu init
+ */
+void nlm_early_init_secondary(void)
+{
+ write_c0_ebase((uint32_t)nlm_common_ebase);
+ /* TLB partition here later */
+}
+
+/*
+ * Code to run on secondary just after probing the CPU
+ */
+static void __cpuinit nlm_init_secondary(void)
+{
+ nlm_smp_irq_init();
+}
+
+void nlm_smp_finish(void)
+{
+#ifdef notyet
+ nlm_common_msgring_cpu_init();
+#endif
+}
+
+void nlm_cpus_done(void)
+{
+}
+
+/*
+ * Boot all other cpus in the system, initialize them, and bring them into
+ * the boot function
+ */
+int nlm_cpu_unblock[NR_CPUS];
+int nlm_cpu_ready[NR_CPUS];
+unsigned long nlm_next_gp;
+unsigned long nlm_next_sp;
+cpumask_t phys_cpu_present_map;
+
+void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
+{
+ unsigned long gp = (unsigned long)task_thread_info(idle);
+ unsigned long sp = (unsigned long)__KSTK_TOS(idle);
+ int cpu = cpu_logical_map(logical_cpu);
+
+ nlm_next_sp = sp;
+ nlm_next_gp = gp;
+
+ /* barrier */
+ __sync();
+ nlm_cpu_unblock[cpu] = 1;
+}
+
+void __init nlm_smp_setup(void)
+{
+ unsigned int boot_cpu;
+ int num_cpus, i;
+
+ boot_cpu = hard_smp_processor_id();
+ cpus_clear(phys_cpu_present_map);
+
+ cpu_set(boot_cpu, phys_cpu_present_map);
+ __cpu_number_map[boot_cpu] = 0;
+ __cpu_logical_map[0] = boot_cpu;
+ cpu_set(0, cpu_possible_map);
+
+ num_cpus = 1;
+ for (i = 0; i < NR_CPUS; i++) {
+ if (nlm_cpu_ready[i]) {
+ cpu_set(i, phys_cpu_present_map);
+ __cpu_number_map[i] = num_cpus;
+ __cpu_logical_map[num_cpus] = i;
+ cpu_set(num_cpus, cpu_possible_map);
+ ++num_cpus;
+ }
+ }
+
+ pr_info("Phys CPU present map: %lx, possible map %lx\n",
+ (unsigned long)phys_cpu_present_map.bits[0],
+ (unsigned long)cpu_possible_map.bits[0]);
+
+ pr_info("Detected %i Slave CPU(s)\n", num_cpus);
+}
+
+void nlm_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+struct plat_smp_ops nlm_smp_ops = {
+ .send_ipi_single = nlm_send_ipi_single,
+ .send_ipi_mask = nlm_send_ipi_mask,
+ .init_secondary = nlm_init_secondary,
+ .smp_finish = nlm_smp_finish,
+ .cpus_done = nlm_cpus_done,
+ .boot_secondary = nlm_boot_secondary,
+ .smp_setup = nlm_smp_setup,
+ .prepare_cpus = nlm_prepare_cpus,
+};
+
+unsigned long secondary_entry_point;
+
+int nlm_wakeup_secondary_cpus(u32 wakeup_mask)
+{
+ unsigned int tid, pid, ipi, i, boot_cpu;
+ void *reset_vec;
+
+ secondary_entry_point = (unsigned long)prom_pre_boot_secondary_cpus;
+ reset_vec = (void *)CKSEG1ADDR(0x1fc00000);
+ memcpy(reset_vec, nlm_boot_smp_nmi, 0x80);
+ boot_cpu = hard_smp_processor_id();
+
+ for (i = 0; i < NR_CPUS; i++) {
+ if (i == boot_cpu)
+ continue;
+ if (wakeup_mask & (1u << i)) {
+ tid = i & 0x3;
+ pid = (i >> 2) & 0x7;
+ ipi = (tid << 16) | (pid << 20) | (1 << 8);
+ pic_send_ipi(ipi);
+ }
+ }
+
+ return 0;
+}
diff --git a/arch/mips/netlogic/xlr/smpboot.S b/arch/mips/netlogic/xlr/smpboot.S
new file mode 100644
index 00000000..b8e07440
--- /dev/null
+++ b/arch/mips/netlogic/xlr/smpboot.S
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+
+/* Don't jump to linux function from Bootloader stack. Change it
+ * here. Kernel might allocate bootloader memory before all the CPUs are
+ * brought up (eg: Inode cache region) and we better don't overwrite this
+ * memory
+ */
+NESTED(prom_pre_boot_secondary_cpus, 16, sp)
+ .set mips64
+ mfc0 t0, $15, 1 # read ebase
+ andi t0, 0x1f # t0 has the processor_id()
+ sll t0, 2 # offset in cpu array
+
+ PTR_LA t1, nlm_cpu_ready # mark CPU ready
+ PTR_ADDU t1, t0
+ li t2, 1
+ sw t2, 0(t1)
+
+ PTR_LA t1, nlm_cpu_unblock
+ PTR_ADDU t1, t0
+1: lw t2, 0(t1) # wait till unblocked
+ beqz t2, 1b
+ nop
+
+ PTR_LA t1, nlm_next_sp
+ PTR_L sp, 0(t1)
+ PTR_LA t1, nlm_next_gp
+ PTR_L gp, 0(t1)
+
+ PTR_LA t0, nlm_early_init_secondary
+ jalr t0
+ nop
+
+ PTR_LA t0, smp_bootstrap
+ jr t0
+ nop
+END(prom_pre_boot_secondary_cpus)
+
+NESTED(nlm_boot_smp_nmi, 0, sp)
+ .set push
+ .set noat
+ .set mips64
+ .set noreorder
+
+ /* Clear the NMI and BEV bits */
+ MFC0 k0, CP0_STATUS
+ li k1, 0xffb7ffff
+ and k0, k0, k1
+ MTC0 k0, CP0_STATUS
+
+ PTR_LA k1, secondary_entry_point
+ PTR_L k0, 0(k1)
+ jr k0
+ nop
+ .set pop
+END(nlm_boot_smp_nmi)
diff --git a/arch/mips/netlogic/xlr/time.c b/arch/mips/netlogic/xlr/time.c
new file mode 100644
index 00000000..0d81b262
--- /dev/null
+++ b/arch/mips/netlogic/xlr/time.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/init.h>
+
+#include <asm/time.h>
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/psb-bootinfo.h>
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ return IRQ_TIMER;
+}
+
+void __init plat_time_init(void)
+{
+ mips_hpt_frequency = nlm_prom_info.cpu_frequency;
+ pr_info("MIPS counter frequency [%ld]\n",
+ (unsigned long)mips_hpt_frequency);
+}
diff --git a/arch/mips/netlogic/xlr/xlr_console.c b/arch/mips/netlogic/xlr/xlr_console.c
new file mode 100644
index 00000000..759df069
--- /dev/null
+++ b/arch/mips/netlogic/xlr/xlr_console.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <asm/netlogic/xlr/iomap.h>
+
+void prom_putchar(char c)
+{
+ nlm_reg_t *mmio;
+
+ mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
+ while (netlogic_read_reg(mmio, 0x5) == 0)
+ ;
+ netlogic_write_reg(mmio, 0x0, c);
+}
diff --git a/arch/mips/nxp/pnx8550/common/pci.c b/arch/mips/nxp/pnx8550/common/pci.c
new file mode 100644
index 00000000..98e86ddb
--- /dev/null
+++ b/arch/mips/nxp/pnx8550/common/pci.c
@@ -0,0 +1,134 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <pci.h>
+#include <glb.h>
+#include <nand.h>
+
+static struct resource pci_io_resource = {
+ .start = PNX8550_PCIIO + 0x1000, /* reserve regacy I/O space */
+ .end = PNX8550_PCIIO + PNX8550_PCIIO_SIZE,
+ .name = "pci IO space",
+ .flags = IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+ .start = PNX8550_PCIMEM,
+ .end = PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1,
+ .name = "pci memory space",
+ .flags = IORESOURCE_MEM
+};
+
+extern struct pci_ops pnx8550_pci_ops;
+
+static struct pci_controller pnx8550_controller = {
+ .pci_ops = &pnx8550_pci_ops,
+ .io_map_base = PNX8550_PORT_BASE,
+ .io_resource = &pci_io_resource,
+ .mem_resource = &pci_mem_resource,
+};
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+static inline unsigned long get_system_mem_size(void)
+{
+ /* Read IP2031_RANK0_ADDR_LO */
+ unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+ /* Read IP2031_RANK1_ADDR_HI */
+ unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+ return dram_r1_hi - dram_r0_lo + 1;
+}
+
+static int __init pnx8550_pci_setup(void)
+{
+ int pci_mem_code;
+ int mem_size = get_system_mem_size() >> 20;
+
+ /* Clear the Global 2 Register, PCI Inta Output Enable Registers
+ Bit 1:Enable DAC Powerdown
+ -> 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+ Bit 0:Enable of PCI inta output
+ -> 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+ */
+ PNX8550_GLB2_ENAB_INTA_O = 0;
+
+ /* Calc the PCI mem size code */
+ if (mem_size >= 128)
+ pci_mem_code = SIZE_128M;
+ else if (mem_size >= 64)
+ pci_mem_code = SIZE_64M;
+ else if (mem_size >= 32)
+ pci_mem_code = SIZE_32M;
+ else
+ pci_mem_code = SIZE_16M;
+
+ /* Set PCI_XIO registers */
+ outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
+ outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
+ outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
+ outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
+
+ /* Send memory transaction via PCI_BASE2 */
+ outl(0x00000001, PCI_BASE | PCI_IO);
+
+ /* Unlock the setup register */
+ outl(0xca, PCI_BASE | PCI_UNLOCKREG);
+
+ /*
+ * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
+ * to work, and in order for bus_to_baddr to work without any
+ * hacks.
+ */
+ outl(0x00000000, PCI_BASE | PCI_BASE10);
+
+ /*
+ *These two bars are set by default or the boot code.
+ * However, it's safer to set them here so we're not boot
+ * code dependent.
+ */
+ outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */
+ outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */
+
+ outl(PCI_EN_TA |
+ PCI_EN_PCI2MMI |
+ PCI_EN_XIO |
+ PCI_SETUP_BASE18_SIZE(SIZE_32M) |
+ PCI_SETUP_BASE18_EN |
+ PCI_SETUP_BASE14_EN |
+ PCI_SETUP_BASE10_PREF |
+ PCI_SETUP_BASE10_SIZE(pci_mem_code) |
+ PCI_SETUP_CFGMANAGE_EN |
+ PCI_SETUP_PCIARB_EN,
+ PCI_BASE |
+ PCI_SETUP); /* PCI_SETUP */
+ outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */
+
+ register_pci_controller(&pnx8550_controller);
+
+ return 0;
+}
+
+arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c
new file mode 100644
index 00000000..64246c9c
--- /dev/null
+++ b/arch/mips/nxp/pnx8550/common/setup.c
@@ -0,0 +1,145 @@
+/*
+ *
+ * 2.6 port, Embedded Alley Solutions, Inc
+ *
+ * Based on Per Hallsmark, per.hallsmark@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/serial_pnx8xxx.h>
+#include <linux/pm.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+
+#include <glb.h>
+#include <int.h>
+#include <pci.h>
+#include <uart.h>
+#include <nand.h>
+
+extern void __init board_setup(void);
+extern void pnx8550_machine_restart(char *);
+extern void pnx8550_machine_halt(void);
+extern void pnx8550_machine_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+extern char *prom_getcmdline(void);
+
+struct resource standard_io_resources[] = {
+ {
+ .start = 0x00,
+ .end = 0x1f,
+ .name = "dma1",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x40,
+ .end = 0x5f,
+ .name = "timer",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x80,
+ .end = 0x8f,
+ .name = "dma page reg",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0xc0,
+ .end = 0xdf,
+ .name = "dma2",
+ .flags = IORESOURCE_BUSY
+ },
+};
+
+#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
+
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+unsigned long get_system_mem_size(void)
+{
+ /* Read IP2031_RANK0_ADDR_LO */
+ unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+ /* Read IP2031_RANK1_ADDR_HI */
+ unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+ return dram_r1_hi - dram_r0_lo + 1;
+}
+
+int pnx8550_console_port = -1;
+
+void __init plat_mem_setup(void)
+{
+ int i;
+ char* argptr;
+
+ board_setup(); /* board specific setup */
+
+ _machine_restart = pnx8550_machine_restart;
+ _machine_halt = pnx8550_machine_halt;
+ pm_power_off = pnx8550_machine_power_off;
+
+ /* Clear the Global 2 Register, PCI Inta Output Enable Registers
+ Bit 1:Enable DAC Powerdown
+ -> 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+ Bit 0:Enable of PCI inta output
+ -> 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+ */
+ PNX8550_GLB2_ENAB_INTA_O = 0;
+
+ /* IO/MEM resources. */
+ set_io_port_base(PNX8550_PORT_BASE);
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+ iomem_resource.start = 0;
+ iomem_resource.end = ~0;
+
+ /* Request I/O space for devices on this board */
+ for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+ request_resource(&ioport_resource, standard_io_resources + i);
+
+ /* Place the Mode Control bit for GPIO pin 16 in primary function */
+ /* Pin 16 is used by UART1, UA1_TX */
+ outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
+ (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
+ PNX8550_GPIO_MC1);
+
+ argptr = prom_getcmdline();
+ if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
+ argptr += strlen("console=ttyS");
+ pnx8550_console_port = *argptr == '0' ? 0 : 1;
+
+ /* We must initialize the UART (console) before early printk */
+ /* Set LCR to 8-bit and BAUD to 38400 (no 5) */
+ ip3106_lcr(UART_BASE, pnx8550_console_port) =
+ PNX8XXX_UART_LCR_8BIT;
+ ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
+ }
+
+ return;
+}
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
new file mode 100644
index 00000000..4b9d7044
--- /dev/null
+++ b/arch/mips/oprofile/Makefile
@@ -0,0 +1,18 @@
+ccflags-y := -Werror
+
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+ oprof.o cpu_buffer.o buffer_sync.o \
+ event_buffer.o oprofile_files.o \
+ oprofilefs.o oprofile_stats.o \
+ timer_int.o )
+
+oprofile-y := $(DRIVER_OBJS) common.o
+
+oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o
+oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
new file mode 100644
index 00000000..f9eb1aba
--- /dev/null
+++ b/arch/mips/oprofile/common.c
@@ -0,0 +1,129 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004, 2005 Ralf Baechle
+ * Copyright (C) 2005 MIPS Technologies, Inc.
+ */
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/smp.h>
+#include <asm/cpu-info.h>
+
+#include "op_impl.h"
+
+extern struct op_mips_model op_model_mipsxx_ops __weak;
+extern struct op_mips_model op_model_rm9000_ops __weak;
+extern struct op_mips_model op_model_loongson2_ops __weak;
+
+static struct op_mips_model *model;
+
+static struct op_counter_config ctr[20];
+
+static int op_mips_setup(void)
+{
+ /* Pre-compute the values to stuff in the hardware registers. */
+ model->reg_setup(ctr);
+
+ /* Configure the registers on all cpus. */
+ on_each_cpu(model->cpu_setup, NULL, 1);
+
+ return 0;
+}
+
+static int op_mips_create_files(struct super_block *sb, struct dentry *root)
+{
+ int i;
+
+ for (i = 0; i < model->num_counters; ++i) {
+ struct dentry *dir;
+ char buf[4];
+
+ snprintf(buf, sizeof buf, "%d", i);
+ dir = oprofilefs_mkdir(sb, root, buf);
+
+ oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+ oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+ oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+ oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+ oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+ oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
+ /* Dummy. */
+ oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+ }
+
+ return 0;
+}
+
+static int op_mips_start(void)
+{
+ on_each_cpu(model->cpu_start, NULL, 1);
+
+ return 0;
+}
+
+static void op_mips_stop(void)
+{
+ /* Disable performance monitoring for all counters. */
+ on_each_cpu(model->cpu_stop, NULL, 1);
+}
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+ struct op_mips_model *lmodel = NULL;
+ int res;
+
+ switch (current_cpu_type()) {
+ case CPU_5KC:
+ case CPU_20KC:
+ case CPU_24K:
+ case CPU_25KF:
+ case CPU_34K:
+ case CPU_1004K:
+ case CPU_74K:
+ case CPU_SB1:
+ case CPU_SB1A:
+ case CPU_R10000:
+ case CPU_R12000:
+ case CPU_R14000:
+ lmodel = &op_model_mipsxx_ops;
+ break;
+
+ case CPU_RM9000:
+ lmodel = &op_model_rm9000_ops;
+ break;
+ case CPU_LOONGSON2:
+ lmodel = &op_model_loongson2_ops;
+ break;
+ };
+
+ if (!lmodel)
+ return -ENODEV;
+
+ res = lmodel->init();
+ if (res)
+ return res;
+
+ model = lmodel;
+
+ ops->create_files = op_mips_create_files;
+ ops->setup = op_mips_setup;
+ //ops->shutdown = op_mips_shutdown;
+ ops->start = op_mips_start;
+ ops->stop = op_mips_stop;
+ ops->cpu_type = lmodel->cpu_type;
+
+ printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+ lmodel->cpu_type);
+
+ return 0;
+}
+
+void oprofile_arch_exit(void)
+{
+ if (model)
+ model->exit();
+}
diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h
new file mode 100644
index 00000000..f04b54fb
--- /dev/null
+++ b/arch/mips/oprofile/op_impl.h
@@ -0,0 +1,39 @@
+/**
+ * @file arch/alpha/oprofile/op_impl.h
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Richard Henderson <rth@twiddle.net>
+ */
+
+#ifndef OP_IMPL_H
+#define OP_IMPL_H 1
+
+extern int (*perf_irq)(void);
+
+/* Per-counter configuration as set via oprofilefs. */
+struct op_counter_config {
+ unsigned long enabled;
+ unsigned long event;
+ unsigned long count;
+ /* Dummies because I am too lazy to hack the userspace tools. */
+ unsigned long kernel;
+ unsigned long user;
+ unsigned long exl;
+ unsigned long unit_mask;
+};
+
+/* Per-architecture configury and hooks. */
+struct op_mips_model {
+ void (*reg_setup) (struct op_counter_config *);
+ void (*cpu_setup) (void *dummy);
+ int (*init)(void);
+ void (*exit)(void);
+ void (*cpu_start)(void *args);
+ void (*cpu_stop)(void *args);
+ char *cpu_type;
+ unsigned char num_counters;
+};
+
+#endif
diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c
new file mode 100644
index 00000000..60d3ea60
--- /dev/null
+++ b/arch/mips/oprofile/op_model_loongson2.c
@@ -0,0 +1,161 @@
+/*
+ * Loongson2 performance counter driver for oprofile
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Yanhua <yanh@lemote.com>
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+
+#include <loongson.h> /* LOONGSON2_PERFCNT_IRQ */
+#include "op_impl.h"
+
+#define LOONGSON2_CPU_TYPE "mips/loongson2"
+
+#define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31)
+
+#define LOONGSON2_PERFCTRL_EXL (1UL << 0)
+#define LOONGSON2_PERFCTRL_KERNEL (1UL << 1)
+#define LOONGSON2_PERFCTRL_SUPERVISOR (1UL << 2)
+#define LOONGSON2_PERFCTRL_USER (1UL << 3)
+#define LOONGSON2_PERFCTRL_ENABLE (1UL << 4)
+#define LOONGSON2_PERFCTRL_EVENT(idx, event) \
+ (((event) & 0x0f) << ((idx) ? 9 : 5))
+
+#define read_c0_perfctrl() __read_64bit_c0_register($24, 0)
+#define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val)
+#define read_c0_perfcnt() __read_64bit_c0_register($25, 0)
+#define write_c0_perfcnt(val) __write_64bit_c0_register($25, 0, val)
+
+static struct loongson2_register_config {
+ unsigned int ctrl;
+ unsigned long long reset_counter1;
+ unsigned long long reset_counter2;
+ int cnt1_enabled, cnt2_enabled;
+} reg;
+
+static char *oprofid = "LoongsonPerf";
+static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id);
+
+static void reset_counters(void *arg)
+{
+ write_c0_perfctrl(0);
+ write_c0_perfcnt(0);
+}
+
+static void loongson2_reg_setup(struct op_counter_config *cfg)
+{
+ unsigned int ctrl = 0;
+
+ reg.reset_counter1 = 0;
+ reg.reset_counter2 = 0;
+
+ /*
+ * Compute the performance counter ctrl word.
+ * For now, count kernel and user mode.
+ */
+ if (cfg[0].enabled) {
+ ctrl |= LOONGSON2_PERFCTRL_EVENT(0, cfg[0].event);
+ reg.reset_counter1 = 0x80000000ULL - cfg[0].count;
+ }
+
+ if (cfg[1].enabled) {
+ ctrl |= LOONGSON2_PERFCTRL_EVENT(1, cfg[1].event);
+ reg.reset_counter2 = 0x80000000ULL - cfg[1].count;
+ }
+
+ if (cfg[0].enabled || cfg[1].enabled) {
+ ctrl |= LOONGSON2_PERFCTRL_EXL | LOONGSON2_PERFCTRL_ENABLE;
+ if (cfg[0].kernel || cfg[1].kernel)
+ ctrl |= LOONGSON2_PERFCTRL_KERNEL;
+ if (cfg[0].user || cfg[1].user)
+ ctrl |= LOONGSON2_PERFCTRL_USER;
+ }
+
+ reg.ctrl = ctrl;
+
+ reg.cnt1_enabled = cfg[0].enabled;
+ reg.cnt2_enabled = cfg[1].enabled;
+}
+
+static void loongson2_cpu_setup(void *args)
+{
+ write_c0_perfcnt((reg.reset_counter2 << 32) | reg.reset_counter1);
+}
+
+static void loongson2_cpu_start(void *args)
+{
+ /* Start all counters on current CPU */
+ if (reg.cnt1_enabled || reg.cnt2_enabled)
+ write_c0_perfctrl(reg.ctrl);
+}
+
+static void loongson2_cpu_stop(void *args)
+{
+ /* Stop all counters on current CPU */
+ write_c0_perfctrl(0);
+ memset(&reg, 0, sizeof(reg));
+}
+
+static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
+{
+ uint64_t counter, counter1, counter2;
+ struct pt_regs *regs = get_irq_regs();
+ int enabled;
+
+ /* Check whether the irq belongs to me */
+ enabled = read_c0_perfctrl() & LOONGSON2_PERFCTRL_ENABLE;
+ if (!enabled)
+ return IRQ_NONE;
+ enabled = reg.cnt1_enabled | reg.cnt2_enabled;
+ if (!enabled)
+ return IRQ_NONE;
+
+ counter = read_c0_perfcnt();
+ counter1 = counter & 0xffffffff;
+ counter2 = counter >> 32;
+
+ if (counter1 & LOONGSON2_PERFCNT_OVERFLOW) {
+ if (reg.cnt1_enabled)
+ oprofile_add_sample(regs, 0);
+ counter1 = reg.reset_counter1;
+ }
+ if (counter2 & LOONGSON2_PERFCNT_OVERFLOW) {
+ if (reg.cnt2_enabled)
+ oprofile_add_sample(regs, 1);
+ counter2 = reg.reset_counter2;
+ }
+
+ write_c0_perfcnt((counter2 << 32) | counter1);
+
+ return IRQ_HANDLED;
+}
+
+static int __init loongson2_init(void)
+{
+ return request_irq(LOONGSON2_PERFCNT_IRQ, loongson2_perfcount_handler,
+ IRQF_SHARED, "Perfcounter", oprofid);
+}
+
+static void loongson2_exit(void)
+{
+ reset_counters(NULL);
+ free_irq(LOONGSON2_PERFCNT_IRQ, oprofid);
+}
+
+struct op_mips_model op_model_loongson2_ops = {
+ .reg_setup = loongson2_reg_setup,
+ .cpu_setup = loongson2_cpu_setup,
+ .init = loongson2_init,
+ .exit = loongson2_exit,
+ .cpu_start = loongson2_cpu_start,
+ .cpu_stop = loongson2_cpu_stop,
+ .cpu_type = LOONGSON2_CPU_TYPE,
+ .num_counters = 2
+};
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
new file mode 100644
index 00000000..54759f16
--- /dev/null
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -0,0 +1,397 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004, 05, 06 by Ralf Baechle
+ * Copyright (C) 2005 by MIPS Technologies, Inc.
+ */
+#include <linux/cpumask.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <asm/irq_regs.h>
+
+#include "op_impl.h"
+
+#define M_PERFCTL_EXL (1UL << 0)
+#define M_PERFCTL_KERNEL (1UL << 1)
+#define M_PERFCTL_SUPERVISOR (1UL << 2)
+#define M_PERFCTL_USER (1UL << 3)
+#define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4)
+#define M_PERFCTL_EVENT(event) (((event) & 0x3ff) << 5)
+#define M_PERFCTL_VPEID(vpe) ((vpe) << 16)
+#define M_PERFCTL_MT_EN(filter) ((filter) << 20)
+#define M_TC_EN_ALL M_PERFCTL_MT_EN(0)
+#define M_TC_EN_VPE M_PERFCTL_MT_EN(1)
+#define M_TC_EN_TC M_PERFCTL_MT_EN(2)
+#define M_PERFCTL_TCID(tcid) ((tcid) << 22)
+#define M_PERFCTL_WIDE (1UL << 30)
+#define M_PERFCTL_MORE (1UL << 31)
+
+#define M_COUNTER_OVERFLOW (1UL << 31)
+
+static int (*save_perf_irq)(void);
+
+#ifdef CONFIG_MIPS_MT_SMP
+static int cpu_has_mipsmt_pertccounters;
+#define WHAT (M_TC_EN_VPE | \
+ M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id))
+#define vpe_id() (cpu_has_mipsmt_pertccounters ? \
+ 0 : cpu_data[smp_processor_id()].vpe_id)
+
+/*
+ * The number of bits to shift to convert between counters per core and
+ * counters per VPE. There is no reasonable interface atm to obtain the
+ * number of VPEs used by Linux and in the 34K this number is fixed to two
+ * anyways so we hardcore a few things here for the moment. The way it's
+ * done here will ensure that oprofile VSMP kernel will run right on a lesser
+ * core like a 24K also or with maxcpus=1.
+ */
+static inline unsigned int vpe_shift(void)
+{
+ if (num_possible_cpus() > 1)
+ return 1;
+
+ return 0;
+}
+
+#else
+
+#define WHAT 0
+#define vpe_id() 0
+
+static inline unsigned int vpe_shift(void)
+{
+ return 0;
+}
+
+#endif
+
+static inline unsigned int counters_total_to_per_cpu(unsigned int counters)
+{
+ return counters >> vpe_shift();
+}
+
+static inline unsigned int counters_per_cpu_to_total(unsigned int counters)
+{
+ return counters << vpe_shift();
+}
+
+#define __define_perf_accessors(r, n, np) \
+ \
+static inline unsigned int r_c0_ ## r ## n(void) \
+{ \
+ unsigned int cpu = vpe_id(); \
+ \
+ switch (cpu) { \
+ case 0: \
+ return read_c0_ ## r ## n(); \
+ case 1: \
+ return read_c0_ ## r ## np(); \
+ default: \
+ BUG(); \
+ } \
+ return 0; \
+} \
+ \
+static inline void w_c0_ ## r ## n(unsigned int value) \
+{ \
+ unsigned int cpu = vpe_id(); \
+ \
+ switch (cpu) { \
+ case 0: \
+ write_c0_ ## r ## n(value); \
+ return; \
+ case 1: \
+ write_c0_ ## r ## np(value); \
+ return; \
+ default: \
+ BUG(); \
+ } \
+ return; \
+} \
+
+__define_perf_accessors(perfcntr, 0, 2)
+__define_perf_accessors(perfcntr, 1, 3)
+__define_perf_accessors(perfcntr, 2, 0)
+__define_perf_accessors(perfcntr, 3, 1)
+
+__define_perf_accessors(perfctrl, 0, 2)
+__define_perf_accessors(perfctrl, 1, 3)
+__define_perf_accessors(perfctrl, 2, 0)
+__define_perf_accessors(perfctrl, 3, 1)
+
+struct op_mips_model op_model_mipsxx_ops;
+
+static struct mipsxx_register_config {
+ unsigned int control[4];
+ unsigned int counter[4];
+} reg;
+
+/* Compute all of the registers in preparation for enabling profiling. */
+
+static void mipsxx_reg_setup(struct op_counter_config *ctr)
+{
+ unsigned int counters = op_model_mipsxx_ops.num_counters;
+ int i;
+
+ /* Compute the performance counter control word. */
+ for (i = 0; i < counters; i++) {
+ reg.control[i] = 0;
+ reg.counter[i] = 0;
+
+ if (!ctr[i].enabled)
+ continue;
+
+ reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) |
+ M_PERFCTL_INTERRUPT_ENABLE;
+ if (ctr[i].kernel)
+ reg.control[i] |= M_PERFCTL_KERNEL;
+ if (ctr[i].user)
+ reg.control[i] |= M_PERFCTL_USER;
+ if (ctr[i].exl)
+ reg.control[i] |= M_PERFCTL_EXL;
+ reg.counter[i] = 0x80000000 - ctr[i].count;
+ }
+}
+
+/* Program all of the registers in preparation for enabling profiling. */
+
+static void mipsxx_cpu_setup(void *args)
+{
+ unsigned int counters = op_model_mipsxx_ops.num_counters;
+
+ switch (counters) {
+ case 4:
+ w_c0_perfctrl3(0);
+ w_c0_perfcntr3(reg.counter[3]);
+ case 3:
+ w_c0_perfctrl2(0);
+ w_c0_perfcntr2(reg.counter[2]);
+ case 2:
+ w_c0_perfctrl1(0);
+ w_c0_perfcntr1(reg.counter[1]);
+ case 1:
+ w_c0_perfctrl0(0);
+ w_c0_perfcntr0(reg.counter[0]);
+ }
+}
+
+/* Start all counters on current CPU */
+static void mipsxx_cpu_start(void *args)
+{
+ unsigned int counters = op_model_mipsxx_ops.num_counters;
+
+ switch (counters) {
+ case 4:
+ w_c0_perfctrl3(WHAT | reg.control[3]);
+ case 3:
+ w_c0_perfctrl2(WHAT | reg.control[2]);
+ case 2:
+ w_c0_perfctrl1(WHAT | reg.control[1]);
+ case 1:
+ w_c0_perfctrl0(WHAT | reg.control[0]);
+ }
+}
+
+/* Stop all counters on current CPU */
+static void mipsxx_cpu_stop(void *args)
+{
+ unsigned int counters = op_model_mipsxx_ops.num_counters;
+
+ switch (counters) {
+ case 4:
+ w_c0_perfctrl3(0);
+ case 3:
+ w_c0_perfctrl2(0);
+ case 2:
+ w_c0_perfctrl1(0);
+ case 1:
+ w_c0_perfctrl0(0);
+ }
+}
+
+static int mipsxx_perfcount_handler(void)
+{
+ unsigned int counters = op_model_mipsxx_ops.num_counters;
+ unsigned int control;
+ unsigned int counter;
+ int handled = IRQ_NONE;
+
+ if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26)))
+ return handled;
+
+ switch (counters) {
+#define HANDLE_COUNTER(n) \
+ case n + 1: \
+ control = r_c0_perfctrl ## n(); \
+ counter = r_c0_perfcntr ## n(); \
+ if ((control & M_PERFCTL_INTERRUPT_ENABLE) && \
+ (counter & M_COUNTER_OVERFLOW)) { \
+ oprofile_add_sample(get_irq_regs(), n); \
+ w_c0_perfcntr ## n(reg.counter[n]); \
+ handled = IRQ_HANDLED; \
+ }
+ HANDLE_COUNTER(3)
+ HANDLE_COUNTER(2)
+ HANDLE_COUNTER(1)
+ HANDLE_COUNTER(0)
+ }
+
+ return handled;
+}
+
+#define M_CONFIG1_PC (1 << 4)
+
+static inline int __n_counters(void)
+{
+ if (!(read_c0_config1() & M_CONFIG1_PC))
+ return 0;
+ if (!(read_c0_perfctrl0() & M_PERFCTL_MORE))
+ return 1;
+ if (!(read_c0_perfctrl1() & M_PERFCTL_MORE))
+ return 2;
+ if (!(read_c0_perfctrl2() & M_PERFCTL_MORE))
+ return 3;
+
+ return 4;
+}
+
+static inline int n_counters(void)
+{
+ int counters;
+
+ switch (current_cpu_type()) {
+ case CPU_R10000:
+ counters = 2;
+ break;
+
+ case CPU_R12000:
+ case CPU_R14000:
+ counters = 4;
+ break;
+
+ default:
+ counters = __n_counters();
+ }
+
+ return counters;
+}
+
+static void reset_counters(void *arg)
+{
+ int counters = (int)(long)arg;
+ switch (counters) {
+ case 4:
+ w_c0_perfctrl3(0);
+ w_c0_perfcntr3(0);
+ case 3:
+ w_c0_perfctrl2(0);
+ w_c0_perfcntr2(0);
+ case 2:
+ w_c0_perfctrl1(0);
+ w_c0_perfcntr1(0);
+ case 1:
+ w_c0_perfctrl0(0);
+ w_c0_perfcntr0(0);
+ }
+}
+
+static int __init mipsxx_init(void)
+{
+ int counters;
+
+ counters = n_counters();
+ if (counters == 0) {
+ printk(KERN_ERR "Oprofile: CPU has no performance counters\n");
+ return -ENODEV;
+ }
+
+#ifdef CONFIG_MIPS_MT_SMP
+ cpu_has_mipsmt_pertccounters = read_c0_config7() & (1<<19);
+ if (!cpu_has_mipsmt_pertccounters)
+ counters = counters_total_to_per_cpu(counters);
+#endif
+ on_each_cpu(reset_counters, (void *)(long)counters, 1);
+
+ op_model_mipsxx_ops.num_counters = counters;
+ switch (current_cpu_type()) {
+ case CPU_20KC:
+ op_model_mipsxx_ops.cpu_type = "mips/20K";
+ break;
+
+ case CPU_24K:
+ op_model_mipsxx_ops.cpu_type = "mips/24K";
+ break;
+
+ case CPU_25KF:
+ op_model_mipsxx_ops.cpu_type = "mips/25K";
+ break;
+
+ case CPU_1004K:
+#if 0
+ /* FIXME: report as 34K for now */
+ op_model_mipsxx_ops.cpu_type = "mips/1004K";
+ break;
+#endif
+
+ case CPU_34K:
+ op_model_mipsxx_ops.cpu_type = "mips/34K";
+ break;
+
+ case CPU_74K:
+ op_model_mipsxx_ops.cpu_type = "mips/74K";
+ break;
+
+ case CPU_5KC:
+ op_model_mipsxx_ops.cpu_type = "mips/5K";
+ break;
+
+ case CPU_R10000:
+ if ((current_cpu_data.processor_id & 0xff) == 0x20)
+ op_model_mipsxx_ops.cpu_type = "mips/r10000-v2.x";
+ else
+ op_model_mipsxx_ops.cpu_type = "mips/r10000";
+ break;
+
+ case CPU_R12000:
+ case CPU_R14000:
+ op_model_mipsxx_ops.cpu_type = "mips/r12000";
+ break;
+
+ case CPU_SB1:
+ case CPU_SB1A:
+ op_model_mipsxx_ops.cpu_type = "mips/sb1";
+ break;
+
+ default:
+ printk(KERN_ERR "Profiling unsupported for this CPU\n");
+
+ return -ENODEV;
+ }
+
+ save_perf_irq = perf_irq;
+ perf_irq = mipsxx_perfcount_handler;
+
+ return 0;
+}
+
+static void mipsxx_exit(void)
+{
+ int counters = op_model_mipsxx_ops.num_counters;
+
+ counters = counters_per_cpu_to_total(counters);
+ on_each_cpu(reset_counters, (void *)(long)counters, 1);
+
+ perf_irq = save_perf_irq;
+}
+
+struct op_mips_model op_model_mipsxx_ops = {
+ .reg_setup = mipsxx_reg_setup,
+ .cpu_setup = mipsxx_cpu_setup,
+ .init = mipsxx_init,
+ .exit = mipsxx_exit,
+ .cpu_start = mipsxx_cpu_start,
+ .cpu_stop = mipsxx_cpu_stop,
+};
diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c
new file mode 100644
index 00000000..3aa81384
--- /dev/null
+++ b/arch/mips/oprofile/op_model_rm9000.c
@@ -0,0 +1,138 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 by Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include "op_impl.h"
+
+#define RM9K_COUNTER1_EVENT(event) ((event) << 0)
+#define RM9K_COUNTER1_SUPERVISOR (1ULL << 7)
+#define RM9K_COUNTER1_KERNEL (1ULL << 8)
+#define RM9K_COUNTER1_USER (1ULL << 9)
+#define RM9K_COUNTER1_ENABLE (1ULL << 10)
+#define RM9K_COUNTER1_OVERFLOW (1ULL << 15)
+
+#define RM9K_COUNTER2_EVENT(event) ((event) << 16)
+#define RM9K_COUNTER2_SUPERVISOR (1ULL << 23)
+#define RM9K_COUNTER2_KERNEL (1ULL << 24)
+#define RM9K_COUNTER2_USER (1ULL << 25)
+#define RM9K_COUNTER2_ENABLE (1ULL << 26)
+#define RM9K_COUNTER2_OVERFLOW (1ULL << 31)
+
+extern unsigned int rm9000_perfcount_irq;
+
+static struct rm9k_register_config {
+ unsigned int control;
+ unsigned int reset_counter1;
+ unsigned int reset_counter2;
+} reg;
+
+/* Compute all of the registers in preparation for enabling profiling. */
+
+static void rm9000_reg_setup(struct op_counter_config *ctr)
+{
+ unsigned int control = 0;
+
+ /* Compute the performance counter control word. */
+ /* For now count kernel and user mode */
+ if (ctr[0].enabled)
+ control |= RM9K_COUNTER1_EVENT(ctr[0].event) |
+ RM9K_COUNTER1_KERNEL |
+ RM9K_COUNTER1_USER |
+ RM9K_COUNTER1_ENABLE;
+ if (ctr[1].enabled)
+ control |= RM9K_COUNTER2_EVENT(ctr[1].event) |
+ RM9K_COUNTER2_KERNEL |
+ RM9K_COUNTER2_USER |
+ RM9K_COUNTER2_ENABLE;
+ reg.control = control;
+
+ reg.reset_counter1 = 0x80000000 - ctr[0].count;
+ reg.reset_counter2 = 0x80000000 - ctr[1].count;
+}
+
+/* Program all of the registers in preparation for enabling profiling. */
+
+static void rm9000_cpu_setup(void *args)
+{
+ uint64_t perfcount;
+
+ perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1;
+ write_c0_perfcount(perfcount);
+}
+
+static void rm9000_cpu_start(void *args)
+{
+ /* Start all counters on current CPU */
+ write_c0_perfcontrol(reg.control);
+}
+
+static void rm9000_cpu_stop(void *args)
+{
+ /* Stop all counters on current CPU */
+ write_c0_perfcontrol(0);
+}
+
+static irqreturn_t rm9000_perfcount_handler(int irq, void *dev_id)
+{
+ unsigned int control = read_c0_perfcontrol();
+ struct pt_regs *regs = get_irq_regs();
+ uint32_t counter1, counter2;
+ uint64_t counters;
+
+ /*
+ * RM9000 combines two 32-bit performance counters into a single
+ * 64-bit coprocessor zero register. To avoid a race updating the
+ * registers we need to stop the counters while we're messing with
+ * them ...
+ */
+ write_c0_perfcontrol(0);
+
+ counters = read_c0_perfcount();
+ counter1 = counters;
+ counter2 = counters >> 32;
+
+ if (control & RM9K_COUNTER1_OVERFLOW) {
+ oprofile_add_sample(regs, 0);
+ counter1 = reg.reset_counter1;
+ }
+ if (control & RM9K_COUNTER2_OVERFLOW) {
+ oprofile_add_sample(regs, 1);
+ counter2 = reg.reset_counter2;
+ }
+
+ counters = ((uint64_t)counter2 << 32) | counter1;
+ write_c0_perfcount(counters);
+ write_c0_perfcontrol(reg.control);
+
+ return IRQ_HANDLED;
+}
+
+static int __init rm9000_init(void)
+{
+ return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
+ 0, "Perfcounter", NULL);
+}
+
+static void rm9000_exit(void)
+{
+ free_irq(rm9000_perfcount_irq, NULL);
+}
+
+struct op_mips_model op_model_rm9000_ops = {
+ .reg_setup = rm9000_reg_setup,
+ .cpu_setup = rm9000_cpu_setup,
+ .init = rm9000_init,
+ .exit = rm9000_exit,
+ .cpu_start = rm9000_cpu_start,
+ .cpu_stop = rm9000_cpu_stop,
+ .cpu_type = "mips/rm9000",
+ .num_counters = 2
+};
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
new file mode 100644
index 00000000..4df87993
--- /dev/null
+++ b/arch/mips/pci/Makefile
@@ -0,0 +1,63 @@
+#
+# Makefile for the PCI specific kernel interface routines under Linux.
+#
+
+obj-y += pci.o
+
+#
+# PCI bus host bridge specific code
+#
+obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o
+obj-$(CONFIG_PCI_GT64XXX_PCI0) += ops-gt64xxx_pci0.o
+obj-$(CONFIG_MIPS_MSC) += ops-msc.o
+obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o
+obj-$(CONFIG_SOC_TX3927) += ops-tx3927.o
+obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o
+obj-$(CONFIG_NEC_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
+obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o
+obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
+obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
+ ops-bcm63xx.o
+
+#
+# These are still pretty much in the old state, watch, go blind.
+#
+obj-$(CONFIG_LASAT) += pci-lasat.o
+obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
+obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
+obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
+obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o
+obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o
+obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o
+obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o
+obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o
+obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o
+obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o
+obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \
+ pci-yosemite.o
+obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o
+obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o
+obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
+obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o
+obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
+obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
+obj-$(CONFIG_SOC_XWAY) += pci-lantiq.o ops-lantiq.o
+obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
+obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
+obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
+obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o
+obj-$(CONFIG_SOC_TX4927) += pci-tx4927.o
+obj-$(CONFIG_SOC_TX4938) += pci-tx4938.o
+obj-$(CONFIG_SOC_TX4939) += pci-tx4939.o
+obj-$(CONFIG_TOSHIBA_RBTX4927) += fixup-rbtx4927.o
+obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o
+obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
+obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
+obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o
+obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o
+obj-$(CONFIG_NLM_XLR) += pci-xlr.o
+
+ifdef CONFIG_PCI_MSI
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o
+endif
diff --git a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c
new file mode 100644
index 00000000..e2ddfc49
--- /dev/null
+++ b/arch/mips/pci/fixup-au1000.c
@@ -0,0 +1,43 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Board specific PCI fixups.
+ *
+ * Copyright 2001-2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+
+extern char irq_tab_alchemy[][5];
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irq_tab_alchemy[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-bcm63xx.c b/arch/mips/pci/fixup-bcm63xx.c
new file mode 100644
index 00000000..34086300
--- /dev/null
+++ b/arch/mips/pci/fixup-bcm63xx.c
@@ -0,0 +1,21 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <bcm63xx_cpu.h>
+
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return bcm63xx_get_irq_number(IRQ_PCI);
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c
new file mode 100644
index 00000000..1c02f573
--- /dev/null
+++ b/arch/mips/pci/fixup-capcella.c
@@ -0,0 +1,50 @@
+/*
+ * fixup-cappcela.c, The ZAO Networks Capcella specific PCI fixups.
+ *
+ * Copyright (C) 2002,2004 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/capcella.h>
+
+/*
+ * Shortcuts
+ */
+#define INT1 RTL8139_1_IRQ
+#define INT2 RTL8139_2_IRQ
+#define INTA PC104PLUS_INTA_IRQ
+#define INTB PC104PLUS_INTB_IRQ
+#define INTC PC104PLUS_INTC_IRQ
+#define INTD PC104PLUS_INTD_IRQ
+
+static char irq_tab_capcella[][5] __initdata = {
+ [11] = { -1, INT1, INT1, INT1, INT1 },
+ [12] = { -1, INT2, INT2, INT2, INT2 },
+ [14] = { -1, INTA, INTB, INTC, INTD }
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irq_tab_capcella[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
new file mode 100644
index 00000000..acacd140
--- /dev/null
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -0,0 +1,254 @@
+/*
+ * Cobalt Qube/Raq PCI support
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 2002, 2003 by Ralf Baechle
+ * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/gt64120.h>
+
+#include <cobalt.h>
+#include <irq.h>
+
+/*
+ * PCI slot numbers
+ */
+#define COBALT_PCICONF_CPU 0x06
+#define COBALT_PCICONF_ETH0 0x07
+#define COBALT_PCICONF_RAQSCSI 0x08
+#define COBALT_PCICONF_VIA 0x09
+#define COBALT_PCICONF_PCISLOT 0x0A
+#define COBALT_PCICONF_ETH1 0x0C
+
+/*
+ * The Cobalt board ID information. The boards have an ID number wired
+ * into the VIA that is available in the high nibble of register 94.
+ */
+#define VIA_COBALT_BRD_ID_REG 0x94
+#define VIA_COBALT_BRD_REG_to_ID(reg) ((unsigned char)(reg) >> 4)
+
+static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
+{
+ if (dev->devfn == PCI_DEVFN(0, 0) &&
+ (dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) {
+
+ dev->class = (PCI_CLASS_BRIDGE_HOST << 8) | (dev->class & 0xff);
+
+ printk(KERN_INFO "Galileo: fixed bridge class\n");
+ }
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
+ qube_raq_galileo_early_fixup);
+
+static void __devinit cobalt_legacy_ide_resource_fixup(struct pci_dev *dev,
+ struct resource *res)
+{
+ struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
+ unsigned long offset = hose->io_offset;
+ struct resource orig = *res;
+
+ if (!(res->flags & IORESOURCE_IO) ||
+ !(res->flags & IORESOURCE_PCI_FIXED))
+ return;
+
+ res->start -= offset;
+ res->end -= offset;
+ dev_printk(KERN_DEBUG, &dev->dev, "converted legacy %pR to bus %pR\n",
+ &orig, res);
+}
+
+static void __devinit cobalt_legacy_ide_fixup(struct pci_dev *dev)
+{
+ u32 class;
+ u8 progif;
+
+ /*
+ * If the IDE controller is in legacy mode, pci_setup_device() fills in
+ * the resources with the legacy addresses that normally appear on the
+ * PCI bus, just as if we had read them from a BAR.
+ *
+ * However, with the GT-64111, those legacy addresses, e.g., 0x1f0,
+ * will never appear on the PCI bus because it converts memory accesses
+ * in the PCI I/O region (which is never at address zero) into I/O port
+ * accesses with no address translation.
+ *
+ * For example, if GT_DEF_PCI0_IO_BASE is 0x10000000, a load or store
+ * to physical address 0x100001f0 will become a PCI access to I/O port
+ * 0x100001f0. There's no way to generate an access to I/O port 0x1f0,
+ * but the VT82C586 IDE controller does respond at 0x100001f0 because
+ * it only decodes the low 24 bits of the address.
+ *
+ * When this quirk runs, the pci_dev resources should contain bus
+ * addresses, not Linux I/O port numbers, so convert legacy addresses
+ * like 0x1f0 to bus addresses like 0x100001f0. Later, we'll convert
+ * them back with pcibios_fixup_bus() or pcibios_bus_to_resource().
+ */
+ class = dev->class >> 8;
+ if (class != PCI_CLASS_STORAGE_IDE)
+ return;
+
+ pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
+ if ((progif & 1) == 0) {
+ cobalt_legacy_ide_resource_fixup(dev, &dev->resource[0]);
+ cobalt_legacy_ide_resource_fixup(dev, &dev->resource[1]);
+ }
+ if ((progif & 4) == 0) {
+ cobalt_legacy_ide_resource_fixup(dev, &dev->resource[2]);
+ cobalt_legacy_ide_resource_fixup(dev, &dev->resource[3]);
+ }
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
+ cobalt_legacy_ide_fixup);
+
+static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
+{
+ unsigned short cfgword;
+ unsigned char lt;
+
+ /* Enable Bus Mastering and fast back to back. */
+ pci_read_config_word(dev, PCI_COMMAND, &cfgword);
+ cfgword |= (PCI_COMMAND_FAST_BACK | PCI_COMMAND_MASTER);
+ pci_write_config_word(dev, PCI_COMMAND, cfgword);
+
+ /* Enable both ide interfaces. ROM only enables primary one. */
+ pci_write_config_byte(dev, 0x40, 0xb);
+
+ /* Set latency timer to reasonable value. */
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lt);
+ if (lt < 64)
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
+ qube_raq_via_bmIDE_fixup);
+
+static void qube_raq_galileo_fixup(struct pci_dev *dev)
+{
+ if (dev->devfn != PCI_DEVFN(0, 0))
+ return;
+
+ /* Fix PCI latency-timer and cache-line-size values in Galileo
+ * host bridge.
+ */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+
+ /*
+ * The code described by the comment below has been removed
+ * as it causes bus mastering by the Ethernet controllers
+ * to break under any kind of network load. We always set
+ * the retry timeouts to their maximum.
+ *
+ * --x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--
+ *
+ * On all machines prior to Q2, we had the STOP line disconnected
+ * from Galileo to VIA on PCI. The new Galileo does not function
+ * correctly unless we have it connected.
+ *
+ * Therefore we must set the disconnect/retry cycle values to
+ * something sensible when using the new Galileo.
+ */
+
+ printk(KERN_INFO "Galileo: revision %u\n", dev->revision);
+
+#if 0
+ if (dev->revision >= 0x10) {
+ /* New Galileo, assumes PCI stop line to VIA is connected. */
+ GT_WRITE(GT_PCI0_TOR_OFS, 0x4020);
+ } else if (dev->revision == 0x1 || dev->revision == 0x2)
+#endif
+ {
+ signed int timeo;
+ /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
+ timeo = GT_READ(GT_PCI0_TOR_OFS);
+ /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
+ GT_WRITE(GT_PCI0_TOR_OFS,
+ (0xff << 16) | /* retry count */
+ (0xff << 8) | /* timeout 1 */
+ 0xff); /* timeout 0 */
+
+ /* enable PCI retry exceeded interrupt */
+ GT_WRITE(GT_INTRMASK_OFS, GT_INTR_RETRYCTR0_MSK | GT_READ(GT_INTRMASK_OFS));
+ }
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
+ qube_raq_galileo_fixup);
+
+int cobalt_board_id;
+
+static void qube_raq_via_board_id_fixup(struct pci_dev *dev)
+{
+ u8 id;
+ int retval;
+
+ retval = pci_read_config_byte(dev, VIA_COBALT_BRD_ID_REG, &id);
+ if (retval) {
+ panic("Cannot read board ID");
+ return;
+ }
+
+ cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(id);
+
+ printk(KERN_INFO "Cobalt board ID: %d\n", cobalt_board_id);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0,
+ qube_raq_via_board_id_fixup);
+
+static char irq_tab_qube1[] __initdata = {
+ [COBALT_PCICONF_CPU] = 0,
+ [COBALT_PCICONF_ETH0] = QUBE1_ETH0_IRQ,
+ [COBALT_PCICONF_RAQSCSI] = SCSI_IRQ,
+ [COBALT_PCICONF_VIA] = 0,
+ [COBALT_PCICONF_PCISLOT] = PCISLOT_IRQ,
+ [COBALT_PCICONF_ETH1] = 0
+};
+
+static char irq_tab_cobalt[] __initdata = {
+ [COBALT_PCICONF_CPU] = 0,
+ [COBALT_PCICONF_ETH0] = ETH0_IRQ,
+ [COBALT_PCICONF_RAQSCSI] = SCSI_IRQ,
+ [COBALT_PCICONF_VIA] = 0,
+ [COBALT_PCICONF_PCISLOT] = PCISLOT_IRQ,
+ [COBALT_PCICONF_ETH1] = ETH1_IRQ
+};
+
+static char irq_tab_raq2[] __initdata = {
+ [COBALT_PCICONF_CPU] = 0,
+ [COBALT_PCICONF_ETH0] = ETH0_IRQ,
+ [COBALT_PCICONF_RAQSCSI] = RAQ2_SCSI_IRQ,
+ [COBALT_PCICONF_VIA] = 0,
+ [COBALT_PCICONF_PCISLOT] = PCISLOT_IRQ,
+ [COBALT_PCICONF_ETH1] = ETH1_IRQ
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (cobalt_board_id <= COBALT_BRD_ID_QUBE1)
+ return irq_tab_qube1[slot];
+
+ if (cobalt_board_id == COBALT_BRD_ID_RAQ2)
+ return irq_tab_raq2[slot];
+
+ return irq_tab_cobalt[slot];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c
new file mode 100644
index 00000000..0d9ccf4d
--- /dev/null
+++ b/arch/mips/pci/fixup-emma2rh.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ * This file is based on the arch/mips/ddb5xxx/ddb5477/pci.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/bootinfo.h>
+
+#include <asm/emma/emma2rh.h>
+
+#define EMMA2RH_PCI_HOST_SLOT 0x09
+#define EMMA2RH_USB_SLOT 0x03
+#define PCI_DEVICE_ID_NEC_EMMA2RH 0x014b /* EMMA2RH PCI Host */
+
+/*
+ * we fix up irqs based on the slot number.
+ * The first entry is at AD:11.
+ * Fortunately this works because, although we have two pci buses,
+ * they all have different slot numbers (except for rockhopper slot 20
+ * which is handled below).
+ *
+ */
+
+#define MAX_SLOT_NUM 10
+static unsigned char irq_map[][5] __initdata = {
+ [3] = {0, MARKEINS_PCI_IRQ_INTB, MARKEINS_PCI_IRQ_INTC,
+ MARKEINS_PCI_IRQ_INTD, 0,},
+ [4] = {0, MARKEINS_PCI_IRQ_INTA, 0, 0, 0,},
+ [5] = {0, 0, 0, 0, 0,},
+ [6] = {0, MARKEINS_PCI_IRQ_INTC, MARKEINS_PCI_IRQ_INTD,
+ MARKEINS_PCI_IRQ_INTA, MARKEINS_PCI_IRQ_INTB,},
+};
+
+static void __devinit nec_usb_controller_fixup(struct pci_dev *dev)
+{
+ if (PCI_SLOT(dev->devfn) == EMMA2RH_USB_SLOT)
+ /* on board USB controller configuration */
+ pci_write_config_dword(dev, 0xe4, 1 << 5);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ nec_usb_controller_fixup);
+
+/*
+ * Prevent the PCI layer from seeing the resources allocated to this device
+ * if it is the host bridge by marking it as such. These resources are of
+ * no consequence to the PCI layer (they are handled elsewhere).
+ */
+static void __devinit emma2rh_pci_host_fixup(struct pci_dev *dev)
+{
+ int i;
+
+ if (PCI_SLOT(dev->devfn) == EMMA2RH_PCI_HOST_SLOT) {
+ dev->class &= 0xff;
+ dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH,
+ emma2rh_pci_host_fixup);
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irq_map[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c
new file mode 100644
index 00000000..d5d4c018
--- /dev/null
+++ b/arch/mips/pci/fixup-fuloong2e.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2004 ICT CAS
+ * Author: Li xiaoyu, ICT CAS
+ * lixy@ict.ac.cn
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <loongson.h>
+
+/* South bridge slot number is set by the pci probe process */
+static u8 sb_slot = 5;
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq = 0;
+
+ if (slot == sb_slot) {
+ switch (PCI_FUNC(dev->devfn)) {
+ case 2:
+ irq = 10;
+ break;
+ case 3:
+ irq = 11;
+ break;
+ case 5:
+ irq = 9;
+ break;
+ }
+ } else {
+ irq = LOONGSON_IRQ_BASE + 25 + pin;
+ }
+ return irq;
+
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+static void __init loongson2e_nec_fixup(struct pci_dev *pdev)
+{
+ unsigned int val;
+
+ /* Configures port 1, 2, 3, 4 to be validate*/
+ pci_read_config_dword(pdev, 0xe0, &val);
+ pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
+
+ /* System clock is 48-MHz Oscillator. */
+ pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+
+static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev)
+{
+ unsigned char c;
+
+ sb_slot = PCI_SLOT(pdev->devfn);
+
+ printk(KERN_INFO "via686b fix: ISA bridge\n");
+
+ /* Enable I/O Recovery time */
+ pci_write_config_byte(pdev, 0x40, 0x08);
+
+ /* Enable ISA refresh */
+ pci_write_config_byte(pdev, 0x41, 0x01);
+
+ /* disable ISA line buffer */
+ pci_write_config_byte(pdev, 0x45, 0x00);
+
+ /* Gate INTR, and flush line buffer */
+ pci_write_config_byte(pdev, 0x46, 0xe0);
+
+ /* Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */
+ /* pci_write_config_byte(pdev, 0x47, 0x20); */
+
+ /*
+ * enable PCI Delay Transaction, Enable EISA ports 4D0/4D1.
+ * enable time-out timer
+ */
+ pci_write_config_byte(pdev, 0x47, 0xe6);
+
+ /*
+ * enable level trigger on pci irqs: 9,10,11,13
+ * important! without this PCI interrupts won't work
+ */
+ outb(0x2e, 0x4d1);
+
+ /* 512 K PCI Decode */
+ pci_write_config_byte(pdev, 0x48, 0x01);
+
+ /* Wait for PGNT before grant to ISA Master/DMA */
+ pci_write_config_byte(pdev, 0x4a, 0x84);
+
+ /*
+ * Plug'n'Play
+ *
+ * Parallel DRQ 3, Floppy DRQ 2 (default)
+ */
+ pci_write_config_byte(pdev, 0x50, 0x0e);
+
+ /*
+ * IRQ Routing for Floppy and Parallel port
+ *
+ * IRQ 6 for floppy, IRQ 7 for parallel port
+ */
+ pci_write_config_byte(pdev, 0x51, 0x76);
+
+ /* IRQ Routing for serial ports (take IRQ 3 and 4) */
+ pci_write_config_byte(pdev, 0x52, 0x34);
+
+ /* All IRQ's level triggered. */
+ pci_write_config_byte(pdev, 0x54, 0x00);
+
+ /* route PIRQA-D irq */
+ pci_write_config_byte(pdev, 0x55, 0x90); /* bit 7-4, PIRQA */
+ pci_write_config_byte(pdev, 0x56, 0xba); /* bit 7-4, PIRQC; */
+ /* 3-0, PIRQB */
+ pci_write_config_byte(pdev, 0x57, 0xd0); /* bit 7-4, PIRQD */
+
+ /* enable function 5/6, audio/modem */
+ pci_read_config_byte(pdev, 0x85, &c);
+ c &= ~(0x3 << 2);
+ pci_write_config_byte(pdev, 0x85, c);
+
+ printk(KERN_INFO"via686b fix: ISA bridge done\n");
+}
+
+static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev)
+{
+ printk(KERN_INFO"via686b fix: IDE\n");
+
+ /* Modify IDE controller setup */
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48);
+ pci_write_config_byte(pdev, PCI_COMMAND,
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER);
+ pci_write_config_byte(pdev, 0x40, 0x0b);
+ /* legacy mode */
+ pci_write_config_byte(pdev, 0x42, 0x09);
+
+#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */
+ /* disable read prefetch/write post buffers */
+ pci_write_config_byte(pdev, 0x41, 0x02);
+
+ /* use 3/4 as fifo thresh hold */
+ pci_write_config_byte(pdev, 0x43, 0x0a);
+ pci_write_config_byte(pdev, 0x44, 0x00);
+
+ pci_write_config_byte(pdev, 0x45, 0x00);
+#else
+ pci_write_config_byte(pdev, 0x41, 0xc2);
+ pci_write_config_byte(pdev, 0x43, 0x35);
+ pci_write_config_byte(pdev, 0x44, 0x1c);
+
+ pci_write_config_byte(pdev, 0x45, 0x10);
+#endif
+
+ printk(KERN_INFO"via686b fix: IDE done\n");
+}
+
+static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev)
+{
+ /* irq routing */
+ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);
+}
+
+static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev)
+{
+ /* irq routing */
+ pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);
+}
+
+static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev)
+{
+ unsigned int val;
+ unsigned char c;
+
+ /* enable IO */
+ pci_write_config_byte(pdev, PCI_COMMAND,
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER);
+ pci_read_config_dword(pdev, 0x4, &val);
+ pci_write_config_dword(pdev, 0x4, val | 1);
+
+ /* route ac97 IRQ */
+ pci_write_config_byte(pdev, 0x3c, 9);
+
+ pci_read_config_byte(pdev, 0x8, &c);
+
+ /* link control: enable link & SGD PCM output */
+ pci_write_config_byte(pdev, 0x41, 0xcc);
+
+ /* disable game port, FM, midi, sb, enable write to reg2c-2f */
+ pci_write_config_byte(pdev, 0x42, 0x20);
+
+ /* we are using Avance logic codec */
+ pci_write_config_word(pdev, 0x2c, 0x1005);
+ pci_write_config_word(pdev, 0x2e, 0x4710);
+ pci_read_config_dword(pdev, 0x2c, &val);
+
+ pci_write_config_byte(pdev, 0x42, 0x0);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
+ loongson2e_686b_func0_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
+ loongson2e_686b_func1_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2,
+ loongson2e_686b_func2_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3,
+ loongson2e_686b_func3_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
+ loongson2e_686b_func5_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ loongson2e_nec_fixup);
diff --git a/arch/mips/pci/fixup-ip32.c b/arch/mips/pci/fixup-ip32.c
new file mode 100644
index 00000000..190fffd0
--- /dev/null
+++ b/arch/mips/pci/fixup-ip32.c
@@ -0,0 +1,51 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/ip32/ip32_ints.h>
+/*
+ * O2 has up to 5 PCI devices connected into the MACE bridge. The device
+ * map looks like this:
+ *
+ * 0 aic7xxx 0
+ * 1 aic7xxx 1
+ * 2 expansion slot
+ * 3 N/C
+ * 4 N/C
+ */
+
+#define SCSI0 MACEPCI_SCSI0_IRQ
+#define SCSI1 MACEPCI_SCSI1_IRQ
+#define INTA0 MACEPCI_SLOT0_IRQ
+#define INTA1 MACEPCI_SLOT1_IRQ
+#define INTA2 MACEPCI_SLOT2_IRQ
+#define INTB MACEPCI_SHARED0_IRQ
+#define INTC MACEPCI_SHARED1_IRQ
+#define INTD MACEPCI_SHARED2_IRQ
+static char irq_tab_mace[][5] __initdata = {
+ /* Dummy INT#A INT#B INT#C INT#D */
+ {0, 0, 0, 0, 0}, /* This is placeholder row - never used */
+ {0, SCSI0, SCSI0, SCSI0, SCSI0},
+ {0, SCSI1, SCSI1, SCSI1, SCSI1},
+ {0, INTA0, INTB, INTC, INTD},
+ {0, INTA1, INTC, INTD, INTB},
+ {0, INTA2, INTD, INTB, INTC},
+};
+
+
+/*
+ * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
+ * the device (1-4 => A-D), tell what irq to use. Note that we don't
+ * in theory have slots 4 and 5, and we never normally use the shared
+ * irqs. I suppose a device without a pin A will thank us for doing it
+ * right if there exists such a broken piece of crap.
+ */
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irq_tab_mace[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c
new file mode 100644
index 00000000..0f106952
--- /dev/null
+++ b/arch/mips/pci/fixup-jmr3927.c
@@ -0,0 +1,79 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Board specific pci fixups.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/jmr3927.h>
+
+int __init jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char irq = pin;
+
+ /* IRQ rotation (PICMG) */
+ irq--; /* 0-3 */
+ if (slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) {
+ /* PCI CardSlot (IDSEL=A23, DevNu=12) */
+ /* PCIA => PCIC (IDSEL=A23) */
+ /* NOTE: JMR3927 JP1 must be set to OPEN */
+ irq = (irq + 2) % 4;
+ } else if (slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) {
+ /* PCI CardSlot (IDSEL=A22, DevNu=11) */
+ /* PCIA => PCIA (IDSEL=A22) */
+ /* NOTE: JMR3927 JP1 must be set to OPEN */
+ irq = (irq + 0) % 4;
+ } else {
+ /* PCI Backplane */
+ if (txx9_pci_option & TXX9_PCI_OPT_PICMG)
+ irq = (irq + 33 - slot) % 4;
+ else
+ irq = (irq + 3 + slot) % 4;
+ }
+ irq++; /* 1-4 */
+
+ switch (irq) {
+ case 1:
+ irq = JMR3927_IRQ_IOC_PCIA;
+ break;
+ case 2:
+ irq = JMR3927_IRQ_IOC_PCIB;
+ break;
+ case 3:
+ irq = JMR3927_IRQ_IOC_PCIC;
+ break;
+ case 4:
+ irq = JMR3927_IRQ_IOC_PCID;
+ break;
+ }
+
+ /* Check OnBoard Ethernet (IDSEL=A24, DevNu=13) */
+ if (dev->bus->parent == NULL &&
+ slot == TX3927_PCIC_IDSEL_AD_TO_SLOT(24))
+ irq = JMR3927_IRQ_ETHER0;
+ return irq;
+}
diff --git a/arch/mips/pci/fixup-lemote2f.c b/arch/mips/pci/fixup-lemote2f.c
new file mode 100644
index 00000000..4b9768d5
--- /dev/null
+++ b/arch/mips/pci/fixup-lemote2f.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2008 Lemote Technology
+ * Copyright (C) 2004 ICT CAS
+ * Author: Li xiaoyu, lixy@ict.ac.cn
+ *
+ * Copyright (C) 2007 Lemote, Inc.
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <loongson.h>
+#include <cs5536/cs5536.h>
+#include <cs5536/cs5536_pci.h>
+
+/* PCI interrupt pins
+ *
+ * These should not be changed, or you should consider loongson2f interrupt
+ * register and your pci card dispatch
+ */
+
+#define PCIA 4
+#define PCIB 5
+#define PCIC 6
+#define PCID 7
+
+/* all the pci device has the PCIA pin, check the datasheet. */
+static char irq_tab[][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ {0, 0, 0, 0, 0}, /* 11: Unused */
+ {0, 0, 0, 0, 0}, /* 12: Unused */
+ {0, 0, 0, 0, 0}, /* 13: Unused */
+ {0, 0, 0, 0, 0}, /* 14: Unused */
+ {0, 0, 0, 0, 0}, /* 15: Unused */
+ {0, 0, 0, 0, 0}, /* 16: Unused */
+ {0, PCIA, 0, 0, 0}, /* 17: RTL8110-0 */
+ {0, PCIB, 0, 0, 0}, /* 18: RTL8110-1 */
+ {0, PCIC, 0, 0, 0}, /* 19: SiI3114 */
+ {0, PCID, 0, 0, 0}, /* 20: 3-ports nec usb */
+ {0, PCIA, PCIB, PCIC, PCID}, /* 21: PCI-SLOT */
+ {0, 0, 0, 0, 0}, /* 22: Unused */
+ {0, 0, 0, 0, 0}, /* 23: Unused */
+ {0, 0, 0, 0, 0}, /* 24: Unused */
+ {0, 0, 0, 0, 0}, /* 25: Unused */
+ {0, 0, 0, 0, 0}, /* 26: Unused */
+ {0, 0, 0, 0, 0}, /* 27: Unused */
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int virq;
+
+ if ((PCI_SLOT(dev->devfn) != PCI_IDSEL_CS5536)
+ && (PCI_SLOT(dev->devfn) < 32)) {
+ virq = irq_tab[slot][pin];
+ printk(KERN_INFO "slot: %d, pin: %d, irq: %d\n", slot, pin,
+ virq + LOONGSON_IRQ_BASE);
+ if (virq != 0)
+ return LOONGSON_IRQ_BASE + virq;
+ else
+ return 0;
+ } else if (PCI_SLOT(dev->devfn) == PCI_IDSEL_CS5536) { /* cs5536 */
+ switch (PCI_FUNC(dev->devfn)) {
+ case 2:
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+ CS5536_IDE_INTR);
+ return CS5536_IDE_INTR; /* for IDE */
+ case 3:
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+ CS5536_ACC_INTR);
+ return CS5536_ACC_INTR; /* for AUDIO */
+ case 4: /* for OHCI */
+ case 5: /* for EHCI */
+ case 6: /* for UDC */
+ case 7: /* for OTG */
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+ CS5536_USB_INTR);
+ return CS5536_USB_INTR;
+ }
+ return dev->irq;
+ } else {
+ printk(KERN_INFO " strange pci slot number.\n");
+ return 0;
+ }
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+/* CS5536 SPEC. fixup */
+static void __init loongson_cs5536_isa_fixup(struct pci_dev *pdev)
+{
+ /* the uart1 and uart2 interrupt in PIC is enabled as default */
+ pci_write_config_dword(pdev, PCI_UART1_INT_REG, 1);
+ pci_write_config_dword(pdev, PCI_UART2_INT_REG, 1);
+}
+
+static void __init loongson_cs5536_ide_fixup(struct pci_dev *pdev)
+{
+ /* setting the mutex pin as IDE function */
+ pci_write_config_dword(pdev, PCI_IDE_CFG_REG,
+ CS5536_IDE_FLASH_SIGNATURE);
+}
+
+static void __init loongson_cs5536_acc_fixup(struct pci_dev *pdev)
+{
+ /* enable the AUDIO interrupt in PIC */
+ pci_write_config_dword(pdev, PCI_ACC_INT_REG, 1);
+
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xc0);
+}
+
+static void __init loongson_cs5536_ohci_fixup(struct pci_dev *pdev)
+{
+ /* enable the OHCI interrupt in PIC */
+ /* THE OHCI, EHCI, UDC, OTG are shared with interrupt in PIC */
+ pci_write_config_dword(pdev, PCI_OHCI_INT_REG, 1);
+}
+
+static void __init loongson_cs5536_ehci_fixup(struct pci_dev *pdev)
+{
+ u32 hi, lo;
+
+ /* Serial short detect enable */
+ _rdmsr(USB_MSR_REG(USB_CONFIG), &hi, &lo);
+ _wrmsr(USB_MSR_REG(USB_CONFIG), (1 << 1) | (1 << 3), lo);
+
+ /* setting the USB2.0 micro frame length */
+ pci_write_config_dword(pdev, PCI_EHCI_FLADJ_REG, 0x2000);
+}
+
+static void __init loongson_nec_fixup(struct pci_dev *pdev)
+{
+ unsigned int val;
+
+ pci_read_config_dword(pdev, 0xe0, &val);
+ /* Only 2 port be used */
+ pci_write_config_dword(pdev, 0xe0, (val & ~3) | 0x2);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA,
+ loongson_cs5536_isa_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_OHC,
+ loongson_cs5536_ohci_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_EHC,
+ loongson_cs5536_ehci_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
+ loongson_cs5536_acc_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE,
+ loongson_cs5536_ide_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ loongson_nec_fixup);
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c
new file mode 100644
index 00000000..0f48498b
--- /dev/null
+++ b/arch/mips/pci/fixup-malta.c
@@ -0,0 +1,103 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+
+/* PCI interrupt pins */
+#define PCIA 1
+#define PCIB 2
+#define PCIC 3
+#define PCID 4
+
+/* This table is filled in by interrogating the PIIX4 chip */
+static char pci_irq[5] __initdata;
+
+static char irq_tab[][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ {0, 0, 0, 0, 0 }, /* 0: GT64120 PCI bridge */
+ {0, 0, 0, 0, 0 }, /* 1: Unused */
+ {0, 0, 0, 0, 0 }, /* 2: Unused */
+ {0, 0, 0, 0, 0 }, /* 3: Unused */
+ {0, 0, 0, 0, 0 }, /* 4: Unused */
+ {0, 0, 0, 0, 0 }, /* 5: Unused */
+ {0, 0, 0, 0, 0 }, /* 6: Unused */
+ {0, 0, 0, 0, 0 }, /* 7: Unused */
+ {0, 0, 0, 0, 0 }, /* 8: Unused */
+ {0, 0, 0, 0, 0 }, /* 9: Unused */
+ {0, 0, 0, 0, PCID }, /* 10: PIIX4 USB */
+ {0, PCIB, 0, 0, 0 }, /* 11: AMD 79C973 Ethernet */
+ {0, PCIC, 0, 0, 0 }, /* 12: Crystal 4281 Sound */
+ {0, 0, 0, 0, 0 }, /* 13: Unused */
+ {0, 0, 0, 0, 0 }, /* 14: Unused */
+ {0, 0, 0, 0, 0 }, /* 15: Unused */
+ {0, 0, 0, 0, 0 }, /* 16: Unused */
+ {0, 0, 0, 0, 0 }, /* 17: Bonito/SOC-it PCI Bridge*/
+ {0, PCIA, PCIB, PCIC, PCID }, /* 18: PCI Slot 1 */
+ {0, PCIB, PCIC, PCID, PCIA }, /* 19: PCI Slot 2 */
+ {0, PCIC, PCID, PCIA, PCIB }, /* 20: PCI Slot 3 */
+ {0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int virq;
+ virq = irq_tab[slot][pin];
+ return pci_irq[virq];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+static void __init malta_piix_func0_fixup(struct pci_dev *pdev)
+{
+ unsigned char reg_val;
+ static int piixirqmap[16] __initdata = { /* PIIX PIRQC[A:D] irq mappings */
+ 0, 0, 0, 3,
+ 4, 5, 6, 7,
+ 0, 9, 10, 11,
+ 12, 0, 14, 15
+ };
+ int i;
+
+ /* Interrogate PIIX4 to get PCI IRQ mapping */
+ for (i = 0; i <= 3; i++) {
+ pci_read_config_byte(pdev, 0x60+i, &reg_val);
+ if (reg_val & 0x80)
+ pci_irq[PCIA+i] = 0; /* Disabled */
+ else
+ pci_irq[PCIA+i] = piixirqmap[reg_val & 15];
+ }
+
+ /* Done by YAMON 2.00 onwards */
+ if (PCI_SLOT(pdev->devfn) == 10) {
+ /*
+ * Set top of main memory accessible by ISA or DMA
+ * devices to 16 Mb.
+ */
+ pci_read_config_byte(pdev, 0x69, &reg_val);
+ pci_write_config_byte(pdev, 0x69, reg_val | 0xf0);
+ }
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
+ malta_piix_func0_fixup);
+
+static void __init malta_piix_func1_fixup(struct pci_dev *pdev)
+{
+ unsigned char reg_val;
+
+ /* Done by YAMON 2.02 onwards */
+ if (PCI_SLOT(pdev->devfn) == 10) {
+ /*
+ * IDE Decode enable.
+ */
+ pci_read_config_byte(pdev, 0x41, &reg_val);
+ pci_write_config_byte(pdev, 0x41, reg_val|0x80);
+ pci_read_config_byte(pdev, 0x43, &reg_val);
+ pci_write_config_byte(pdev, 0x43, reg_val|0x80);
+ }
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
+ malta_piix_func1_fixup);
diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c
new file mode 100644
index 00000000..e08f49cb
--- /dev/null
+++ b/arch/mips/pci/fixup-mpc30x.c
@@ -0,0 +1,49 @@
+/*
+ * fixup-mpc30x.c, The Victor MP-C303/304 specific PCI fixups.
+ *
+ * Copyright (C) 2002,2004 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/mpc30x.h>
+
+static const int internal_func_irqs[] __initdata = {
+ VRC4173_CASCADE_IRQ,
+ VRC4173_AC97_IRQ,
+ VRC4173_USB_IRQ,
+};
+
+static const int irq_tab_mpc30x[] __initdata = {
+ [12] = VRC4173_PCMCIA1_IRQ,
+ [13] = VRC4173_PCMCIA2_IRQ,
+ [29] = MQ200_IRQ,
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (slot == 30)
+ return internal_func_irqs[PCI_FUNC(dev->devfn)];
+
+ return irq_tab_mpc30x[slot];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c
new file mode 100644
index 00000000..65735b1b
--- /dev/null
+++ b/arch/mips/pci/fixup-pmcmsp.c
@@ -0,0 +1,216 @@
+/*
+ * PMC-Sierra MSP board specific pci fixups.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2005-2007 PMC-Sierra, Inc
+ *
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef CONFIG_PCI
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/byteorder.h>
+
+#include <msp_pci.h>
+#include <msp_cic_int.h>
+
+/* PCI interrupt pins */
+#define IRQ4 MSP_INT_EXT4
+#define IRQ5 MSP_INT_EXT5
+#define IRQ6 MSP_INT_EXT6
+
+#if defined(CONFIG_PMC_MSP7120_GW)
+/* Garibaldi Board IRQ wiring to PCI slots */
+static char irq_tab[][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */
+ {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */
+ {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */
+ {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */
+ {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */
+ {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */
+ {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */
+ {0, 0, 0, 0, 0 }, /* 6 (AD[16]): Unused */
+ {0, 0, 0, 0, 0 }, /* 7 (AD[17]): Unused */
+ {0, 0, 0, 0, 0 }, /* 8 (AD[18]): Unused */
+ {0, 0, 0, 0, 0 }, /* 9 (AD[19]): Unused */
+ {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */
+ {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */
+ {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */
+ {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */
+ {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */
+ {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */
+ {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */
+ {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */
+ {0, IRQ4, IRQ4, 0, 0 }, /* 18 (AD[28]): slot 0 */
+ {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */
+ {0, IRQ5, IRQ5, 0, 0 }, /* 20 (AD[30]): slot 1 */
+ {0, IRQ6, IRQ6, 0, 0 } /* 21 (AD[31]): slot 2 */
+};
+
+#elif defined(CONFIG_PMC_MSP7120_EVAL)
+
+/* MSP7120 Eval Board IRQ wiring to PCI slots */
+static char irq_tab[][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */
+ {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */
+ {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */
+ {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */
+ {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */
+ {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */
+ {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */
+ {0, IRQ6, IRQ6, 0, 0 }, /* 6 (AD[16]): slot 3 (mini) */
+ {0, IRQ5, IRQ5, 0, 0 }, /* 7 (AD[17]): slot 2 (mini) */
+ {0, IRQ4, IRQ4, IRQ4, IRQ4}, /* 8 (AD[18]): slot 0 (PCI) */
+ {0, IRQ5, IRQ5, IRQ5, IRQ5}, /* 9 (AD[19]): slot 1 (PCI) */
+ {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */
+ {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */
+ {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */
+ {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */
+ {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */
+ {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */
+ {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */
+ {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */
+ {0, 0, 0, 0, 0 }, /* 18 (AD[28]): Unused */
+ {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */
+ {0, 0, 0, 0, 0 }, /* 20 (AD[30]): Unused */
+ {0, 0, 0, 0, 0 } /* 21 (AD[31]): Unused */
+};
+
+#else
+
+/* Unknown board -- don't assign any IRQs */
+static char irq_tab[][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[2]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[3]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[4]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[5]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[6]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[7]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[8]): Unused */
+ {0, 0, 0, 0, 0 }, /* (AD[9]): Unused */
+ {0, 0, 0, 0, 0 }, /* 0 (AD[10]): Unused */
+ {0, 0, 0, 0, 0 }, /* 1 (AD[11]): Unused */
+ {0, 0, 0, 0, 0 }, /* 2 (AD[12]): Unused */
+ {0, 0, 0, 0, 0 }, /* 3 (AD[13]): Unused */
+ {0, 0, 0, 0, 0 }, /* 4 (AD[14]): Unused */
+ {0, 0, 0, 0, 0 }, /* 5 (AD[15]): Unused */
+ {0, 0, 0, 0, 0 }, /* 6 (AD[16]): Unused */
+ {0, 0, 0, 0, 0 }, /* 7 (AD[17]): Unused */
+ {0, 0, 0, 0, 0 }, /* 8 (AD[18]): Unused */
+ {0, 0, 0, 0, 0 }, /* 9 (AD[19]): Unused */
+ {0, 0, 0, 0, 0 }, /* 10 (AD[20]): Unused */
+ {0, 0, 0, 0, 0 }, /* 11 (AD[21]): Unused */
+ {0, 0, 0, 0, 0 }, /* 12 (AD[22]): Unused */
+ {0, 0, 0, 0, 0 }, /* 13 (AD[23]): Unused */
+ {0, 0, 0, 0, 0 }, /* 14 (AD[24]): Unused */
+ {0, 0, 0, 0, 0 }, /* 15 (AD[25]): Unused */
+ {0, 0, 0, 0, 0 }, /* 16 (AD[26]): Unused */
+ {0, 0, 0, 0, 0 }, /* 17 (AD[27]): Unused */
+ {0, 0, 0, 0, 0 }, /* 18 (AD[28]): Unused */
+ {0, 0, 0, 0, 0 }, /* 19 (AD[29]): Unused */
+ {0, 0, 0, 0, 0 }, /* 20 (AD[30]): Unused */
+ {0, 0, 0, 0, 0 } /* 21 (AD[31]): Unused */
+};
+#endif
+
+/*****************************************************************************
+ *
+ * FUNCTION: pcibios_plat_dev_init
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Perform platform specific device initialization at
+ * pci_enable_device() time.
+ * None are needed for the MSP7120 PCI Controller.
+ *
+ * INPUTS: dev - structure describing the PCI device
+ *
+ * OUTPUTS: none
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL
+ *
+ ****************************************************************************/
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: pcibios_map_irq
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Perform board supplied PCI IRQ mapping routine.
+ *
+ * INPUTS: dev - unused
+ * slot - PCI slot. Identified by which bit of the AD[] bus
+ * drives the IDSEL line. AD[10] is 0, AD[31] is
+ * slot 21.
+ * pin - numbered using the scheme of the PCI_INTERRUPT_PIN
+ * field of the config header.
+ *
+ * OUTPUTS: none
+ *
+ * RETURNS: IRQ number
+ *
+ ****************************************************************************/
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+#if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL)
+ printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n");
+#endif
+ printk(KERN_WARNING "PCI: irq_tab returned %d for slot=%d pin=%d\n",
+ irq_tab[slot][pin], slot, pin);
+
+ return irq_tab[slot][pin];
+}
+
+#endif /* CONFIG_PCI */
diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c
new file mode 100644
index 00000000..96857ac6
--- /dev/null
+++ b/arch/mips/pci/fixup-pnx8550.c
@@ -0,0 +1,57 @@
+/*
+ * Philips PNX8550 pci fixups.
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddealley.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach-pnx8550/pci.h>
+#include <asm/mach-pnx8550/int.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+extern char pnx8550_irq_tab[][5];
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+ /* no need to fixup IO resources */
+}
+
+void __init pcibios_fixup(void)
+{
+ /* nothing to do here */
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return pnx8550_irq_tab[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c
new file mode 100644
index 00000000..321db265
--- /dev/null
+++ b/arch/mips/pci/fixup-rbtx4927.c
@@ -0,0 +1,73 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Board specific pci fixups for the Toshiba rbtx4927
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani (mlachwani@mvista.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/rbtx4927.h>
+
+int __init rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char irq = pin;
+
+ /* IRQ rotation */
+ irq--; /* 0-3 */
+ if (slot == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) {
+ /* PCI CardSlot (IDSEL=A23) */
+ /* PCIA => PCIA */
+ irq = (irq + 0 + slot) % 4;
+ } else {
+ /* PCI Backplane */
+ if (txx9_pci_option & TXX9_PCI_OPT_PICMG)
+ irq = (irq + 33 - slot) % 4;
+ else
+ irq = (irq + 3 + slot) % 4;
+ }
+ irq++; /* 1-4 */
+
+ switch (irq) {
+ case 1:
+ irq = RBTX4927_IRQ_IOC_PCIA;
+ break;
+ case 2:
+ irq = RBTX4927_IRQ_IOC_PCIB;
+ break;
+ case 3:
+ irq = RBTX4927_IRQ_IOC_PCIC;
+ break;
+ case 4:
+ irq = RBTX4927_IRQ_IOC_PCID;
+ break;
+ }
+ return irq;
+}
diff --git a/arch/mips/pci/fixup-rbtx4938.c b/arch/mips/pci/fixup-rbtx4938.c
new file mode 100644
index 00000000..a80579af
--- /dev/null
+++ b/arch/mips/pci/fixup-rbtx4938.c
@@ -0,0 +1,53 @@
+/*
+ * Toshiba rbtx4938 pci routines
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/types.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/rbtx4938.h>
+
+int __init rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq = tx4938_pcic1_map_irq(dev, slot);
+
+ if (irq >= 0)
+ return irq;
+ irq = pin;
+ /* IRQ rotation */
+ irq--; /* 0-3 */
+ if (slot == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) {
+ /* PCI CardSlot (IDSEL=A23) */
+ /* PCIA => PCIA (IDSEL=A23) */
+ irq = (irq + 0 + slot) % 4;
+ } else {
+ /* PCI Backplane */
+ if (txx9_pci_option & TXX9_PCI_OPT_PICMG)
+ irq = (irq + 33 - slot) % 4;
+ else
+ irq = (irq + 3 + slot) % 4;
+ }
+ irq++; /* 1-4 */
+
+ switch (irq) {
+ case 1:
+ irq = RBTX4938_IRQ_IOC_PCIA;
+ break;
+ case 2:
+ irq = RBTX4938_IRQ_IOC_PCIB;
+ break;
+ case 3:
+ irq = RBTX4938_IRQ_IOC_PCIC;
+ break;
+ case 4:
+ irq = RBTX4938_IRQ_IOC_PCID;
+ break;
+ }
+ return irq;
+}
diff --git a/arch/mips/pci/fixup-rc32434.c b/arch/mips/pci/fixup-rc32434.c
new file mode 100644
index 00000000..3d86823d
--- /dev/null
+++ b/arch/mips/pci/fixup-rc32434.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * stevel@mvista.com or source@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach-rc32434/rc32434.h>
+#include <asm/mach-rc32434/irq.h>
+
+static int __devinitdata irq_map[2][12] = {
+ {0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1},
+ {0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3}
+};
+
+int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq = 0;
+
+ if (dev->bus->number < 2 && PCI_SLOT(dev->devfn) < 12)
+ irq = irq_map[dev->bus->number][PCI_SLOT(dev->devfn)];
+
+ return irq + GROUP4_IRQ_BASE + 4;
+}
+
+static void rc32434_pci_early_fixup(struct pci_dev *dev)
+{
+ if (PCI_SLOT(dev->devfn) == 6 && dev->bus->number == 0) {
+ /* disable prefetched memory range */
+ pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0);
+ pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x10);
+
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4);
+ }
+}
+
+/*
+ * The fixup applies to both the IDT and VIA devices present on the board
+ */
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, rc32434_pci_early_fixup);
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-sb1250.c b/arch/mips/pci/fixup-sb1250.c
new file mode 100644
index 00000000..f0bb9146
--- /dev/null
+++ b/arch/mips/pci/fixup-sb1250.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2004, 2006 MIPS Technologies, Inc. All rights reserved.
+ * Author: Maciej W. Rozycki <macro@mips.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+
+/*
+ * Set the BCM1250, etc. PCI host bridge's TRDY timeout
+ * to the finite max.
+ */
+static void __init quirk_sb1250_pci(struct pci_dev *dev)
+{
+ pci_write_config_byte(dev, 0x40, 0xff);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_PCI,
+ quirk_sb1250_pci);
+
+/*
+ * The BCM1250, etc. PCI/HT bridge reports as a host bridge.
+ */
+static void __init quirk_sb1250_ht(struct pci_dev *dev)
+{
+ dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,
+ quirk_sb1250_ht);
+
+/*
+ * Set the SP1011 HT/PCI bridge's TRDY timeout to the finite max.
+ */
+static void __init quirk_sp1011(struct pci_dev *dev)
+{
+ pci_write_config_byte(dev, 0x64, 0xff);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIPACKETS, PCI_DEVICE_ID_SP1011,
+ quirk_sp1011);
diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c
new file mode 100644
index 00000000..5c8a79bb
--- /dev/null
+++ b/arch/mips/pci/fixup-sni.c
@@ -0,0 +1,170 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SNI specific PCI support for RM200/RM300.
+ *
+ * Copyright (C) 1997 - 2000, 2003, 04 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/mipsregs.h>
+#include <asm/sni.h>
+
+#include <irq.h>
+
+/*
+ * PCIMT Shortcuts ...
+ */
+#define SCSI PCIMT_IRQ_SCSI
+#define ETH PCIMT_IRQ_ETHERNET
+#define INTA PCIMT_IRQ_INTA
+#define INTB PCIMT_IRQ_INTB
+#define INTC PCIMT_IRQ_INTC
+#define INTD PCIMT_IRQ_INTD
+
+/*
+ * Device 0: PCI EISA Bridge (directly routed)
+ * Device 1: NCR53c810 SCSI (directly routed)
+ * Device 2: PCnet32 Ethernet (directly routed)
+ * Device 3: VGA (routed to INTB)
+ * Device 4: Unused
+ * Device 5: Slot 2
+ * Device 6: Slot 3
+ * Device 7: Slot 4
+ *
+ * Documentation says the VGA is device 5 and device 3 is unused but that
+ * seem to be a documentation error. At least on my RM200C the Cirrus
+ * Logic CL-GD5434 VGA is device 3.
+ */
+static char irq_tab_rm200[8][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ { 0, 0, 0, 0, 0 }, /* EISA bridge */
+ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */
+ { ETH, ETH, ETH, ETH, ETH }, /* Ethernet */
+ { INTB, INTB, INTB, INTB, INTB }, /* VGA */
+ { 0, 0, 0, 0, 0 }, /* Unused */
+ { 0, INTB, INTC, INTD, INTA }, /* Slot 2 */
+ { 0, INTC, INTD, INTA, INTB }, /* Slot 3 */
+ { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */
+};
+
+/*
+ * In Revision D of the RM300 Device 2 has become a normal purpose Slot 1
+ *
+ * The VGA card is optional for RM300 systems.
+ */
+static char irq_tab_rm300d[8][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ { 0, 0, 0, 0, 0 }, /* EISA bridge */
+ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */
+ { 0, INTC, INTD, INTA, INTB }, /* Slot 1 */
+ { INTB, INTB, INTB, INTB, INTB }, /* VGA */
+ { 0, 0, 0, 0, 0 }, /* Unused */
+ { 0, INTB, INTC, INTD, INTA }, /* Slot 2 */
+ { 0, INTC, INTD, INTA, INTB }, /* Slot 3 */
+ { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */
+};
+
+static char irq_tab_rm300e[5][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ { 0, 0, 0, 0, 0 }, /* HOST bridge */
+ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */
+ { 0, INTC, INTD, INTA, INTB }, /* Bridge/i960 */
+ { 0, INTD, INTA, INTB, INTC }, /* Slot 1 */
+ { 0, INTA, INTB, INTC, INTD }, /* Slot 2 */
+};
+#undef SCSI
+#undef ETH
+#undef INTA
+#undef INTB
+#undef INTC
+#undef INTD
+
+
+/*
+ * PCIT Shortcuts ...
+ */
+#define SCSI0 PCIT_IRQ_SCSI0
+#define SCSI1 PCIT_IRQ_SCSI1
+#define ETH PCIT_IRQ_ETHERNET
+#define INTA PCIT_IRQ_INTA
+#define INTB PCIT_IRQ_INTB
+#define INTC PCIT_IRQ_INTC
+#define INTD PCIT_IRQ_INTD
+
+static char irq_tab_pcit[13][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ { 0, 0, 0, 0, 0 }, /* HOST bridge */
+ { SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 }, /* SCSI */
+ { SCSI1, SCSI1, SCSI1, SCSI1, SCSI1 }, /* SCSI */
+ { ETH, ETH, ETH, ETH, ETH }, /* Ethernet */
+ { 0, INTA, INTB, INTC, INTD }, /* PCI-PCI bridge */
+ { 0, 0, 0, 0, 0 }, /* Unused */
+ { 0, 0, 0, 0, 0 }, /* Unused */
+ { 0, 0, 0, 0, 0 }, /* Unused */
+ { 0, INTA, INTB, INTC, INTD }, /* Slot 1 */
+ { 0, INTB, INTC, INTD, INTA }, /* Slot 2 */
+ { 0, INTC, INTD, INTA, INTB }, /* Slot 3 */
+ { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */
+ { 0, INTA, INTB, INTC, INTD }, /* Slot 5 */
+};
+
+static char irq_tab_pcit_cplus[13][5] __initdata = {
+ /* INTA INTB INTC INTD */
+ { 0, 0, 0, 0, 0 }, /* HOST bridge */
+ { 0, INTB, INTC, INTD, INTA }, /* PCI Slot 9 */
+ { 0, 0, 0, 0, 0 }, /* PCI-EISA */
+ { 0, 0, 0, 0, 0 }, /* Unused */
+ { 0, INTA, INTB, INTC, INTD }, /* PCI-PCI bridge */
+ { 0, INTB, INTC, INTD, INTA }, /* fixup */
+};
+
+static inline int is_rm300_revd(void)
+{
+ unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
+
+ return (csmsr & 0xa0) == 0x20;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ switch (sni_brd_type) {
+ case SNI_BRD_PCI_TOWER_CPLUS:
+ if (slot == 4) {
+ /*
+ * SNI messed up interrupt wiring for onboard
+ * PCI bus 1; we need to fix this up here
+ */
+ while (dev && dev->bus->number != 1)
+ dev = dev->bus->self;
+ if (dev && dev->devfn >= PCI_DEVFN(4, 0))
+ slot = 5;
+ }
+ return irq_tab_pcit_cplus[slot][pin];
+ case SNI_BRD_PCI_TOWER:
+ return irq_tab_pcit[slot][pin];
+
+ case SNI_BRD_PCI_MTOWER:
+ if (is_rm300_revd())
+ return irq_tab_rm300d[slot][pin];
+ /* fall through */
+
+ case SNI_BRD_PCI_DESKTOP:
+ return irq_tab_rm200[slot][pin];
+
+ case SNI_BRD_PCI_MTOWER_CPLUS:
+ return irq_tab_rm300e[slot][pin];
+ }
+
+ return 0;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c
new file mode 100644
index 00000000..8084b17d
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0219.c
@@ -0,0 +1,51 @@
+/*
+ * fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups.
+ *
+ * Copyright (C) 2003 Megasolution Inc. <matsu@megasolution.jp>
+ * Copyright (C) 2004-2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/tb0219.h>
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq = -1;
+
+ switch (slot) {
+ case 12:
+ irq = TB0219_PCI_SLOT1_IRQ;
+ break;
+ case 13:
+ irq = TB0219_PCI_SLOT2_IRQ;
+ break;
+ case 14:
+ irq = TB0219_PCI_SLOT3_IRQ;
+ break;
+ default:
+ break;
+ }
+
+ return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c
new file mode 100644
index 00000000..4196ccf3
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0226.c
@@ -0,0 +1,86 @@
+/*
+ * fixup-tb0226.c, The TANBAC TB0226 specific PCI fixups.
+ *
+ * Copyright (C) 2002-2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/giu.h>
+#include <asm/vr41xx/tb0226.h>
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq = -1;
+
+ switch (slot) {
+ case 12:
+ vr41xx_set_irq_trigger(GD82559_1_PIN,
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(GD82559_1_PIN, IRQ_LEVEL_LOW);
+ irq = GD82559_1_IRQ;
+ break;
+ case 13:
+ vr41xx_set_irq_trigger(GD82559_2_PIN,
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(GD82559_2_PIN, IRQ_LEVEL_LOW);
+ irq = GD82559_2_IRQ;
+ break;
+ case 14:
+ switch (pin) {
+ case 1:
+ vr41xx_set_irq_trigger(UPD720100_INTA_PIN,
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(UPD720100_INTA_PIN,
+ IRQ_LEVEL_LOW);
+ irq = UPD720100_INTA_IRQ;
+ break;
+ case 2:
+ vr41xx_set_irq_trigger(UPD720100_INTB_PIN,
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(UPD720100_INTB_PIN,
+ IRQ_LEVEL_LOW);
+ irq = UPD720100_INTB_IRQ;
+ break;
+ case 3:
+ vr41xx_set_irq_trigger(UPD720100_INTC_PIN,
+ IRQ_TRIGGER_LEVEL,
+ IRQ_SIGNAL_THROUGH);
+ vr41xx_set_irq_level(UPD720100_INTC_PIN,
+ IRQ_LEVEL_LOW);
+ irq = UPD720100_INTC_IRQ;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-tb0287.c b/arch/mips/pci/fixup-tb0287.c
new file mode 100644
index 00000000..2fe29db4
--- /dev/null
+++ b/arch/mips/pci/fixup-tb0287.c
@@ -0,0 +1,65 @@
+/*
+ * fixup-tb0287.c, The TANBAC TB0287 specific PCI fixups.
+ *
+ * Copyright (C) 2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/vr41xx/tb0287.h>
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char bus;
+ int irq = -1;
+
+ bus = dev->bus->number;
+ if (bus == 0) {
+ switch (slot) {
+ case 16:
+ irq = TB0287_SM501_IRQ;
+ break;
+ case 17:
+ irq = TB0287_SIL680A_IRQ;
+ break;
+ default:
+ break;
+ }
+ } else if (bus == 1) {
+ switch (PCI_SLOT(dev->devfn)) {
+ case 0:
+ irq = TB0287_PCI_SLOT_IRQ;
+ break;
+ case 2:
+ case 3:
+ irq = TB0287_RTL8110_IRQ;
+ break;
+ default:
+ break;
+ }
+ } else if (bus > 1) {
+ irq = TB0287_PCI_SLOT_IRQ;
+ }
+
+ return irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-wrppmc.c b/arch/mips/pci/fixup-wrppmc.c
new file mode 100644
index 00000000..3d277549
--- /dev/null
+++ b/arch/mips/pci/fixup-wrppmc.c
@@ -0,0 +1,37 @@
+/*
+ * fixup-wrppmc.c: PPMC board specific PCI fixup
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006, Wind River Inc. Rongkai.zhan (rongkai.zhan@windriver.com)
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/gt64120.h>
+
+/* PCI interrupt pins */
+#define PCI_INTA 1
+#define PCI_INTB 2
+#define PCI_INTC 3
+#define PCI_INTD 4
+
+#define PCI_SLOT_MAXNR 32 /* Each PCI bus has 32 physical slots */
+
+static char pci_irq_tab[PCI_SLOT_MAXNR][5] __initdata = {
+ /* 0 INTA INTB INTC INTD */
+ [0] = {0, 0, 0, 0, 0}, /* Slot 0: GT64120 PCI bridge */
+ [6] = {0, WRPPMC_PCI_INTA_IRQ, 0, 0, 0},
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return pci_irq_tab[slot][pin];
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/fixup-yosemite.c b/arch/mips/pci/fixup-yosemite.c
new file mode 100644
index 00000000..fdafb13a
--- /dev/null
+++ b/arch/mips/pci/fixup-yosemite.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (pin == 0)
+ return -1;
+
+ return 3; /* Everything goes to one irq bit */
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
new file mode 100644
index 00000000..5d530f89
--- /dev/null
+++ b/arch/mips/pci/msi-octeon.c
@@ -0,0 +1,431 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2009, 2010 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/msi.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
+#include <asm/octeon/cvmx-npei-defs.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+#include <asm/octeon/pci-octeon.h>
+
+/*
+ * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
+ * in use.
+ */
+static u64 msi_free_irq_bitmask[4];
+
+/*
+ * Each bit in msi_multiple_irq_bitmask tells that the device using
+ * this bit in msi_free_irq_bitmask is also using the next bit. This
+ * is used so we can disable all of the MSI interrupts when a device
+ * uses multiple.
+ */
+static u64 msi_multiple_irq_bitmask[4];
+
+/*
+ * This lock controls updates to msi_free_irq_bitmask and
+ * msi_multiple_irq_bitmask.
+ */
+static DEFINE_SPINLOCK(msi_free_irq_bitmask_lock);
+
+/*
+ * Number of MSI IRQs used. This variable is set up in
+ * the module init time.
+ */
+static int msi_irq_size;
+
+/**
+ * Called when a driver request MSI interrupts instead of the
+ * legacy INT A-D. This routine will allocate multiple interrupts
+ * for MSI devices that support them. A device can override this by
+ * programming the MSI control bits [6:4] before calling
+ * pci_enable_msi().
+ *
+ * @dev: Device requesting MSI interrupts
+ * @desc: MSI descriptor
+ *
+ * Returns 0 on success.
+ */
+int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+{
+ struct msi_msg msg;
+ u16 control;
+ int configured_private_bits;
+ int request_private_bits;
+ int irq = 0;
+ int irq_step;
+ u64 search_mask;
+ int index;
+
+ /*
+ * Read the MSI config to figure out how many IRQs this device
+ * wants. Most devices only want 1, which will give
+ * configured_private_bits and request_private_bits equal 0.
+ */
+ pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
+ &control);
+
+ /*
+ * If the number of private bits has been configured then use
+ * that value instead of the requested number. This gives the
+ * driver the chance to override the number of interrupts
+ * before calling pci_enable_msi().
+ */
+ configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
+ if (configured_private_bits == 0) {
+ /* Nothing is configured, so use the hardware requested size */
+ request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
+ } else {
+ /*
+ * Use the number of configured bits, assuming the
+ * driver wanted to override the hardware request
+ * value.
+ */
+ request_private_bits = configured_private_bits;
+ }
+
+ /*
+ * The PCI 2.3 spec mandates that there are at most 32
+ * interrupts. If this device asks for more, only give it one.
+ */
+ if (request_private_bits > 5)
+ request_private_bits = 0;
+
+try_only_one:
+ /*
+ * The IRQs have to be aligned on a power of two based on the
+ * number being requested.
+ */
+ irq_step = 1 << request_private_bits;
+
+ /* Mask with one bit for each IRQ */
+ search_mask = (1 << irq_step) - 1;
+
+ /*
+ * We're going to search msi_free_irq_bitmask_lock for zero
+ * bits. This represents an MSI interrupt number that isn't in
+ * use.
+ */
+ spin_lock(&msi_free_irq_bitmask_lock);
+ for (index = 0; index < msi_irq_size/64; index++) {
+ for (irq = 0; irq < 64; irq += irq_step) {
+ if ((msi_free_irq_bitmask[index] & (search_mask << irq)) == 0) {
+ msi_free_irq_bitmask[index] |= search_mask << irq;
+ msi_multiple_irq_bitmask[index] |= (search_mask >> 1) << irq;
+ goto msi_irq_allocated;
+ }
+ }
+ }
+msi_irq_allocated:
+ spin_unlock(&msi_free_irq_bitmask_lock);
+
+ /* Make sure the search for available interrupts didn't fail */
+ if (irq >= 64) {
+ if (request_private_bits) {
+ pr_err("arch_setup_msi_irq: Unable to find %d free interrupts, trying just one",
+ 1 << request_private_bits);
+ request_private_bits = 0;
+ goto try_only_one;
+ } else
+ panic("arch_setup_msi_irq: Unable to find a free MSI interrupt");
+ }
+
+ /* MSI interrupts start at logical IRQ OCTEON_IRQ_MSI_BIT0 */
+ irq += index*64;
+ irq += OCTEON_IRQ_MSI_BIT0;
+
+ switch (octeon_dma_bar_type) {
+ case OCTEON_DMA_BAR_TYPE_SMALL:
+ /* When not using big bar, Bar 0 is based at 128MB */
+ msg.address_lo =
+ ((128ul << 20) + CVMX_PCI_MSI_RCV) & 0xffffffff;
+ msg.address_hi = ((128ul << 20) + CVMX_PCI_MSI_RCV) >> 32;
+ case OCTEON_DMA_BAR_TYPE_BIG:
+ /* When using big bar, Bar 0 is based at 0 */
+ msg.address_lo = (0 + CVMX_PCI_MSI_RCV) & 0xffffffff;
+ msg.address_hi = (0 + CVMX_PCI_MSI_RCV) >> 32;
+ break;
+ case OCTEON_DMA_BAR_TYPE_PCIE:
+ /* When using PCIe, Bar 0 is based at 0 */
+ /* FIXME CVMX_NPEI_MSI_RCV* other than 0? */
+ msg.address_lo = (0 + CVMX_NPEI_PCIE_MSI_RCV) & 0xffffffff;
+ msg.address_hi = (0 + CVMX_NPEI_PCIE_MSI_RCV) >> 32;
+ break;
+ default:
+ panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type\n");
+ }
+ msg.data = irq - OCTEON_IRQ_MSI_BIT0;
+
+ /* Update the number of IRQs the device has available to it */
+ control &= ~PCI_MSI_FLAGS_QSIZE;
+ control |= request_private_bits << 4;
+ pci_write_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
+ control);
+
+ irq_set_msi_desc(irq, desc);
+ write_msi_msg(irq, &msg);
+ return 0;
+}
+
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+ struct msi_desc *entry;
+ int ret;
+
+ /*
+ * MSI-X is not supported.
+ */
+ if (type == PCI_CAP_ID_MSIX)
+ return -EINVAL;
+
+ /*
+ * If an architecture wants to support multiple MSI, it needs to
+ * override arch_setup_msi_irqs()
+ */
+ if (type == PCI_CAP_ID_MSI && nvec > 1)
+ return 1;
+
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ ret = arch_setup_msi_irq(dev, entry);
+ if (ret < 0)
+ return ret;
+ if (ret > 0)
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+/**
+ * Called when a device no longer needs its MSI interrupts. All
+ * MSI interrupts for the device are freed.
+ *
+ * @irq: The devices first irq number. There may be multple in sequence.
+ */
+void arch_teardown_msi_irq(unsigned int irq)
+{
+ int number_irqs;
+ u64 bitmask;
+ int index = 0;
+ int irq0;
+
+ if ((irq < OCTEON_IRQ_MSI_BIT0)
+ || (irq > msi_irq_size + OCTEON_IRQ_MSI_BIT0))
+ panic("arch_teardown_msi_irq: Attempted to teardown illegal "
+ "MSI interrupt (%d)", irq);
+
+ irq -= OCTEON_IRQ_MSI_BIT0;
+ index = irq / 64;
+ irq0 = irq % 64;
+
+ /*
+ * Count the number of IRQs we need to free by looking at the
+ * msi_multiple_irq_bitmask. Each bit set means that the next
+ * IRQ is also owned by this device.
+ */
+ number_irqs = 0;
+ while ((irq0 + number_irqs < 64) &&
+ (msi_multiple_irq_bitmask[index]
+ & (1ull << (irq0 + number_irqs))))
+ number_irqs++;
+ number_irqs++;
+ /* Mask with one bit for each IRQ */
+ bitmask = (1 << number_irqs) - 1;
+ /* Shift the mask to the correct bit location */
+ bitmask <<= irq0;
+ if ((msi_free_irq_bitmask[index] & bitmask) != bitmask)
+ panic("arch_teardown_msi_irq: Attempted to teardown MSI "
+ "interrupt (%d) not in use", irq);
+
+ /* Checks are done, update the in use bitmask */
+ spin_lock(&msi_free_irq_bitmask_lock);
+ msi_free_irq_bitmask[index] &= ~bitmask;
+ msi_multiple_irq_bitmask[index] &= ~bitmask;
+ spin_unlock(&msi_free_irq_bitmask_lock);
+}
+
+static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
+
+static u64 msi_rcv_reg[4];
+static u64 mis_ena_reg[4];
+
+static void octeon_irq_msi_enable_pcie(struct irq_data *data)
+{
+ u64 en;
+ unsigned long flags;
+ int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0;
+ int irq_index = msi_number >> 6;
+ int irq_bit = msi_number & 0x3f;
+
+ raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
+ en = cvmx_read_csr(mis_ena_reg[irq_index]);
+ en |= 1ull << irq_bit;
+ cvmx_write_csr(mis_ena_reg[irq_index], en);
+ cvmx_read_csr(mis_ena_reg[irq_index]);
+ raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
+}
+
+static void octeon_irq_msi_disable_pcie(struct irq_data *data)
+{
+ u64 en;
+ unsigned long flags;
+ int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0;
+ int irq_index = msi_number >> 6;
+ int irq_bit = msi_number & 0x3f;
+
+ raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
+ en = cvmx_read_csr(mis_ena_reg[irq_index]);
+ en &= ~(1ull << irq_bit);
+ cvmx_write_csr(mis_ena_reg[irq_index], en);
+ cvmx_read_csr(mis_ena_reg[irq_index]);
+ raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
+}
+
+static struct irq_chip octeon_irq_chip_msi_pcie = {
+ .name = "MSI",
+ .irq_enable = octeon_irq_msi_enable_pcie,
+ .irq_disable = octeon_irq_msi_disable_pcie,
+};
+
+static void octeon_irq_msi_enable_pci(struct irq_data *data)
+{
+ /*
+ * Octeon PCI doesn't have the ability to mask/unmask MSI
+ * interrupts individually. Instead of masking/unmasking them
+ * in groups of 16, we simple assume MSI devices are well
+ * behaved. MSI interrupts are always enable and the ACK is
+ * assumed to be enough
+ */
+}
+
+static void octeon_irq_msi_disable_pci(struct irq_data *data)
+{
+ /* See comment in enable */
+}
+
+static struct irq_chip octeon_irq_chip_msi_pci = {
+ .name = "MSI",
+ .irq_enable = octeon_irq_msi_enable_pci,
+ .irq_disable = octeon_irq_msi_disable_pci,
+};
+
+/*
+ * Called by the interrupt handling code when an MSI interrupt
+ * occurs.
+ */
+static irqreturn_t __octeon_msi_do_interrupt(int index, u64 msi_bits)
+{
+ int irq;
+ int bit;
+
+ bit = fls64(msi_bits);
+ if (bit) {
+ bit--;
+ /* Acknowledge it first. */
+ cvmx_write_csr(msi_rcv_reg[index], 1ull << bit);
+
+ irq = bit + OCTEON_IRQ_MSI_BIT0 + 64 * index;
+ do_IRQ(irq);
+ return IRQ_HANDLED;
+ }
+ return IRQ_NONE;
+}
+
+#define OCTEON_MSI_INT_HANDLER_X(x) \
+static irqreturn_t octeon_msi_interrupt##x(int cpl, void *dev_id) \
+{ \
+ u64 msi_bits = cvmx_read_csr(msi_rcv_reg[(x)]); \
+ return __octeon_msi_do_interrupt((x), msi_bits); \
+}
+
+/*
+ * Create octeon_msi_interrupt{0-3} function body
+ */
+OCTEON_MSI_INT_HANDLER_X(0);
+OCTEON_MSI_INT_HANDLER_X(1);
+OCTEON_MSI_INT_HANDLER_X(2);
+OCTEON_MSI_INT_HANDLER_X(3);
+
+/*
+ * Initializes the MSI interrupt handling code
+ */
+int __init octeon_msi_initialize(void)
+{
+ int irq;
+ struct irq_chip *msi;
+
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE) {
+ msi_rcv_reg[0] = CVMX_PEXP_NPEI_MSI_RCV0;
+ msi_rcv_reg[1] = CVMX_PEXP_NPEI_MSI_RCV1;
+ msi_rcv_reg[2] = CVMX_PEXP_NPEI_MSI_RCV2;
+ msi_rcv_reg[3] = CVMX_PEXP_NPEI_MSI_RCV3;
+ mis_ena_reg[0] = CVMX_PEXP_NPEI_MSI_ENB0;
+ mis_ena_reg[1] = CVMX_PEXP_NPEI_MSI_ENB1;
+ mis_ena_reg[2] = CVMX_PEXP_NPEI_MSI_ENB2;
+ mis_ena_reg[3] = CVMX_PEXP_NPEI_MSI_ENB3;
+ msi = &octeon_irq_chip_msi_pcie;
+ } else {
+ msi_rcv_reg[0] = CVMX_NPI_NPI_MSI_RCV;
+#define INVALID_GENERATE_ADE 0x8700000000000000ULL;
+ msi_rcv_reg[1] = INVALID_GENERATE_ADE;
+ msi_rcv_reg[2] = INVALID_GENERATE_ADE;
+ msi_rcv_reg[3] = INVALID_GENERATE_ADE;
+ mis_ena_reg[0] = INVALID_GENERATE_ADE;
+ mis_ena_reg[1] = INVALID_GENERATE_ADE;
+ mis_ena_reg[2] = INVALID_GENERATE_ADE;
+ mis_ena_reg[3] = INVALID_GENERATE_ADE;
+ msi = &octeon_irq_chip_msi_pci;
+ }
+
+ for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_LAST; irq++)
+ irq_set_chip_and_handler(irq, msi, handle_simple_irq);
+
+ if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
+ if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0,
+ 0, "MSI[0:63]", octeon_msi_interrupt0))
+ panic("request_irq(OCTEON_IRQ_PCI_MSI0) failed");
+
+ if (request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt1,
+ 0, "MSI[64:127]", octeon_msi_interrupt1))
+ panic("request_irq(OCTEON_IRQ_PCI_MSI1) failed");
+
+ if (request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt2,
+ 0, "MSI[127:191]", octeon_msi_interrupt2))
+ panic("request_irq(OCTEON_IRQ_PCI_MSI2) failed");
+
+ if (request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt3,
+ 0, "MSI[192:255]", octeon_msi_interrupt3))
+ panic("request_irq(OCTEON_IRQ_PCI_MSI3) failed");
+
+ msi_irq_size = 256;
+ } else if (octeon_is_pci_host()) {
+ if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0,
+ 0, "MSI[0:15]", octeon_msi_interrupt0))
+ panic("request_irq(OCTEON_IRQ_PCI_MSI0) failed");
+
+ if (request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt0,
+ 0, "MSI[16:31]", octeon_msi_interrupt0))
+ panic("request_irq(OCTEON_IRQ_PCI_MSI1) failed");
+
+ if (request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt0,
+ 0, "MSI[32:47]", octeon_msi_interrupt0))
+ panic("request_irq(OCTEON_IRQ_PCI_MSI2) failed");
+
+ if (request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt0,
+ 0, "MSI[48:63]", octeon_msi_interrupt0))
+ panic("request_irq(OCTEON_IRQ_PCI_MSI3) failed");
+ msi_irq_size = 64;
+ }
+ return 0;
+}
+subsys_initcall(octeon_msi_initialize);
diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c
new file mode 100644
index 00000000..9a57c5ab
--- /dev/null
+++ b/arch/mips/pci/ops-au1000.c
@@ -0,0 +1,308 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Alchemy/AMD Au1xx0 PCI support.
+ *
+ * Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Support for all devices (greater than 16) added by David Gathright.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+
+#include <asm/mach-au1x00/au1000.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...)
+#endif
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+int (*board_pci_idsel)(unsigned int devsel, int assert);
+
+void mod_wired_entry(int entry, unsigned long entrylo0,
+ unsigned long entrylo1, unsigned long entryhi,
+ unsigned long pagemask)
+{
+ unsigned long old_pagemask;
+ unsigned long old_ctx;
+
+ /* Save old context and create impossible VPN2 value */
+ old_ctx = read_c0_entryhi() & 0xff;
+ old_pagemask = read_c0_pagemask();
+ write_c0_index(entry);
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+ write_c0_entrylo1(entrylo1);
+ tlb_write_indexed();
+ write_c0_entryhi(old_ctx);
+ write_c0_pagemask(old_pagemask);
+}
+
+static struct vm_struct *pci_cfg_vm;
+static int pci_cfg_wired_entry;
+static unsigned long last_entryLo0, last_entryLo1;
+
+/*
+ * We can't ioremap the entire pci config space because it's too large.
+ * Nor can we call ioremap dynamically because some device drivers use
+ * the PCI config routines from within interrupt handlers and that
+ * becomes a problem in get_vm_area(). We use one wired TLB to handle
+ * all config accesses for all busses.
+ */
+void __init au1x_pci_cfg_init(void)
+{
+ /* Reserve a wired entry for PCI config accesses */
+ pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP);
+ if (!pci_cfg_vm)
+ panic(KERN_ERR "PCI unable to get vm area\n");
+ pci_cfg_wired_entry = read_c0_wired();
+ add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, PM_4K);
+ last_entryLo0 = last_entryLo1 = 0xffffffff;
+}
+
+static int config_access(unsigned char access_type, struct pci_bus *bus,
+ unsigned int dev_fn, unsigned char where, u32 *data)
+{
+#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
+ unsigned int device = PCI_SLOT(dev_fn);
+ unsigned int function = PCI_FUNC(dev_fn);
+ unsigned long offset, status;
+ unsigned long cfg_base;
+ unsigned long flags;
+ int error = PCIBIOS_SUCCESSFUL;
+ unsigned long entryLo0, entryLo1;
+
+ if (device > 19) {
+ *data = 0xffffffff;
+ return -1;
+ }
+
+ local_irq_save(flags);
+ au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
+ Au1500_PCI_STATCMD);
+ au_sync_udelay(1);
+
+ /*
+ * Allow board vendors to implement their own off-chip IDSEL.
+ * If it doesn't succeed, may as well bail out at this point.
+ */
+ if (board_pci_idsel && board_pci_idsel(device, 1) == 0) {
+ *data = 0xffffffff;
+ local_irq_restore(flags);
+ return -1;
+ }
+
+ /* Setup the config window */
+ if (bus->number == 0)
+ cfg_base = (1 << device) << 11;
+ else
+ cfg_base = 0x80000000 | (bus->number << 16) | (device << 11);
+
+ /* Setup the lower bits of the 36-bit address */
+ offset = (function << 8) | (where & ~0x3);
+ /* Pick up any address that falls below the page mask */
+ offset |= cfg_base & ~PAGE_MASK;
+
+ /* Page boundary */
+ cfg_base = cfg_base & PAGE_MASK;
+
+ /*
+ * To improve performance, if the current device is the same as
+ * the last device accessed, we don't touch the TLB.
+ */
+ entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7;
+ entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
+ if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
+ mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1,
+ (unsigned long)pci_cfg_vm->addr, PM_4K);
+ last_entryLo0 = entryLo0;
+ last_entryLo1 = entryLo1;
+ }
+
+ if (access_type == PCI_ACCESS_WRITE)
+ au_writel(*data, (int)(pci_cfg_vm->addr + offset));
+ else
+ *data = au_readl((int)(pci_cfg_vm->addr + offset));
+
+ au_sync_udelay(2);
+
+ DBG("cfg_access %d bus->number %u dev %u at %x *data %x conf %lx\n",
+ access_type, bus->number, device, where, *data, offset);
+
+ /* Check master abort */
+ status = au_readl(Au1500_PCI_STATCMD);
+
+ if (status & (1 << 29)) {
+ *data = 0xffffffff;
+ error = -1;
+ DBG("Au1x Master Abort\n");
+ } else if ((status >> 28) & 0xf) {
+ DBG("PCI ERR detected: device %u, status %lx\n",
+ device, (status >> 28) & 0xf);
+
+ /* Clear errors */
+ au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD);
+
+ *data = 0xffffffff;
+ error = -1;
+ }
+
+ /* Take away the IDSEL. */
+ if (board_pci_idsel)
+ (void)board_pci_idsel(device, 0);
+
+ local_irq_restore(flags);
+ return error;
+#endif
+}
+
+static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
+ int where, u8 *val)
+{
+ u32 data;
+ int ret;
+
+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
+ if (where & 1)
+ data >>= 8;
+ if (where & 2)
+ data >>= 16;
+ *val = data & 0xff;
+ return ret;
+}
+
+static int read_config_word(struct pci_bus *bus, unsigned int devfn,
+ int where, u16 *val)
+{
+ u32 data;
+ int ret;
+
+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
+ if (where & 2)
+ data >>= 16;
+ *val = data & 0xffff;
+ return ret;
+}
+
+static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
+ int where, u32 *val)
+{
+ int ret;
+
+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
+ return ret;
+}
+
+static int write_config_byte(struct pci_bus *bus, unsigned int devfn,
+ int where, u8 val)
+{
+ u32 data = 0;
+
+ if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+ return -1;
+
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+
+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_word(struct pci_bus *bus, unsigned int devfn,
+ int where, u16 val)
+{
+ u32 data = 0;
+
+ if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+ return -1;
+
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+
+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int write_config_dword(struct pci_bus *bus, unsigned int devfn,
+ int where, u32 val)
+{
+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int config_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ switch (size) {
+ case 1: {
+ u8 _val;
+ int rc = read_config_byte(bus, devfn, where, &_val);
+
+ *val = _val;
+ return rc;
+ }
+ case 2: {
+ u16 _val;
+ int rc = read_config_word(bus, devfn, where, &_val);
+
+ *val = _val;
+ return rc;
+ }
+ default:
+ return read_config_dword(bus, devfn, where, val);
+ }
+}
+
+static int config_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ switch (size) {
+ case 1:
+ return write_config_byte(bus, devfn, where, (u8) val);
+ case 2:
+ return write_config_word(bus, devfn, where, (u16) val);
+ default:
+ return write_config_dword(bus, devfn, where, val);
+ }
+}
+
+struct pci_ops au1x_pci_ops = {
+ config_read,
+ config_write
+};
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c
new file mode 100644
index 00000000..822ae179
--- /dev/null
+++ b/arch/mips/pci/ops-bcm63xx.c
@@ -0,0 +1,467 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "pci-bcm63xx.h"
+
+/*
+ * swizzle 32bits data to return only the needed part
+ */
+static int postprocess_read(u32 data, int where, unsigned int size)
+{
+ u32 ret;
+
+ ret = 0;
+ switch (size) {
+ case 1:
+ ret = (data >> ((where & 3) << 3)) & 0xff;
+ break;
+ case 2:
+ ret = (data >> ((where & 3) << 3)) & 0xffff;
+ break;
+ case 4:
+ ret = data;
+ break;
+ }
+ return ret;
+}
+
+static int preprocess_write(u32 orig_data, u32 val, int where,
+ unsigned int size)
+{
+ u32 ret;
+
+ ret = 0;
+ switch (size) {
+ case 1:
+ ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ break;
+ case 2:
+ ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ break;
+ case 4:
+ ret = val;
+ break;
+ }
+ return ret;
+}
+
+/*
+ * setup hardware for a configuration cycle with given parameters
+ */
+static int bcm63xx_setup_cfg_access(int type, unsigned int busn,
+ unsigned int devfn, int where)
+{
+ unsigned int slot, func, reg;
+ u32 val;
+
+ slot = PCI_SLOT(devfn);
+ func = PCI_FUNC(devfn);
+ reg = where >> 2;
+
+ /* sanity check */
+ if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT))
+ return 1;
+
+ if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT))
+ return 1;
+
+ if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT))
+ return 1;
+
+ /* ok, setup config access */
+ val = (reg << MPI_L2PCFG_REG_SHIFT);
+ val |= (func << MPI_L2PCFG_FUNC_SHIFT);
+ val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT);
+ val |= MPI_L2PCFG_CFG_USEREG_MASK;
+ val |= MPI_L2PCFG_CFG_SEL_MASK;
+ /* type 0 cycle for local bus, type 1 cycle for anything else */
+ if (type != 0) {
+ /* FIXME: how to specify bus ??? */
+ val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT);
+ }
+ bcm_mpi_writel(val, MPI_L2PCFG_REG);
+
+ return 0;
+}
+
+static int bcm63xx_do_cfg_read(int type, unsigned int busn,
+ unsigned int devfn, int where, int size,
+ u32 *val)
+{
+ u32 data;
+
+ /* two phase cycle, first we write address, then read data at
+ * another location, caller already has a spinlock so no need
+ * to add one here */
+ if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ iob();
+ data = le32_to_cpu(__raw_readl(pci_iospace_start));
+ /* restore IO space normal behaviour */
+ bcm_mpi_writel(0, MPI_L2PCFG_REG);
+
+ *val = postprocess_read(data, where, size);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_do_cfg_write(int type, unsigned int busn,
+ unsigned int devfn, int where, int size,
+ u32 val)
+{
+ u32 data;
+
+ /* two phase cycle, first we write address, then write data to
+ * another location, caller already has a spinlock so no need
+ * to add one here */
+ if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ iob();
+
+ data = le32_to_cpu(__raw_readl(pci_iospace_start));
+ data = preprocess_write(data, val, where, size);
+
+ __raw_writel(cpu_to_le32(data), pci_iospace_start);
+ wmb();
+ /* no way to know the access is done, we have to wait */
+ udelay(500);
+ /* restore IO space normal behaviour */
+ bcm_mpi_writel(0, MPI_L2PCFG_REG);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_pci_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ int type;
+
+ type = bus->parent ? 1 : 0;
+
+ if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return bcm63xx_do_cfg_read(type, bus->number, devfn,
+ where, size, val);
+}
+
+static int bcm63xx_pci_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ int type;
+
+ type = bus->parent ? 1 : 0;
+
+ if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return bcm63xx_do_cfg_write(type, bus->number, devfn,
+ where, size, val);
+}
+
+struct pci_ops bcm63xx_pci_ops = {
+ .read = bcm63xx_pci_read,
+ .write = bcm63xx_pci_write
+};
+
+#ifdef CONFIG_CARDBUS
+/*
+ * emulate configuration read access on a cardbus bridge
+ */
+#define FAKE_CB_BRIDGE_SLOT 0x1e
+
+static int fake_cb_bridge_bus_number = -1;
+
+static struct {
+ u16 pci_command;
+ u8 cb_latency;
+ u8 subordinate_busn;
+ u8 cardbus_busn;
+ u8 pci_busn;
+ int bus_assigned;
+ u16 bridge_control;
+
+ u32 mem_base0;
+ u32 mem_limit0;
+ u32 mem_base1;
+ u32 mem_limit1;
+
+ u32 io_base0;
+ u32 io_limit0;
+ u32 io_base1;
+ u32 io_limit1;
+} fake_cb_bridge_regs;
+
+static int fake_cb_bridge_read(int where, int size, u32 *val)
+{
+ unsigned int reg;
+ u32 data;
+
+ data = 0;
+ reg = where >> 2;
+ switch (reg) {
+ case (PCI_VENDOR_ID >> 2):
+ case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2):
+ /* create dummy vendor/device id from our cpu id */
+ data = (bcm63xx_get_cpu_id() << 16) | PCI_VENDOR_ID_BROADCOM;
+ break;
+
+ case (PCI_COMMAND >> 2):
+ data = (PCI_STATUS_DEVSEL_SLOW << 16);
+ data |= fake_cb_bridge_regs.pci_command;
+ break;
+
+ case (PCI_CLASS_REVISION >> 2):
+ data = (PCI_CLASS_BRIDGE_CARDBUS << 16);
+ break;
+
+ case (PCI_CACHE_LINE_SIZE >> 2):
+ data = (PCI_HEADER_TYPE_CARDBUS << 16);
+ break;
+
+ case (PCI_INTERRUPT_LINE >> 2):
+ /* bridge control */
+ data = (fake_cb_bridge_regs.bridge_control << 16);
+ /* pin:intA line:0xff */
+ data |= (0x1 << 8) | 0xff;
+ break;
+
+ case (PCI_CB_PRIMARY_BUS >> 2):
+ data = (fake_cb_bridge_regs.cb_latency << 24);
+ data |= (fake_cb_bridge_regs.subordinate_busn << 16);
+ data |= (fake_cb_bridge_regs.cardbus_busn << 8);
+ data |= fake_cb_bridge_regs.pci_busn;
+ break;
+
+ case (PCI_CB_MEMORY_BASE_0 >> 2):
+ data = fake_cb_bridge_regs.mem_base0;
+ break;
+
+ case (PCI_CB_MEMORY_LIMIT_0 >> 2):
+ data = fake_cb_bridge_regs.mem_limit0;
+ break;
+
+ case (PCI_CB_MEMORY_BASE_1 >> 2):
+ data = fake_cb_bridge_regs.mem_base1;
+ break;
+
+ case (PCI_CB_MEMORY_LIMIT_1 >> 2):
+ data = fake_cb_bridge_regs.mem_limit1;
+ break;
+
+ case (PCI_CB_IO_BASE_0 >> 2):
+ /* | 1 for 32bits io support */
+ data = fake_cb_bridge_regs.io_base0 | 0x1;
+ break;
+
+ case (PCI_CB_IO_LIMIT_0 >> 2):
+ data = fake_cb_bridge_regs.io_limit0;
+ break;
+
+ case (PCI_CB_IO_BASE_1 >> 2):
+ /* | 1 for 32bits io support */
+ data = fake_cb_bridge_regs.io_base1 | 0x1;
+ break;
+
+ case (PCI_CB_IO_LIMIT_1 >> 2):
+ data = fake_cb_bridge_regs.io_limit1;
+ break;
+ }
+
+ *val = postprocess_read(data, where, size);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * emulate configuration write access on a cardbus bridge
+ */
+static int fake_cb_bridge_write(int where, int size, u32 val)
+{
+ unsigned int reg;
+ u32 data, tmp;
+ int ret;
+
+ ret = fake_cb_bridge_read((where & ~0x3), 4, &data);
+ if (ret != PCIBIOS_SUCCESSFUL)
+ return ret;
+
+ data = preprocess_write(data, val, where, size);
+
+ reg = where >> 2;
+ switch (reg) {
+ case (PCI_COMMAND >> 2):
+ fake_cb_bridge_regs.pci_command = (data & 0xffff);
+ break;
+
+ case (PCI_CB_PRIMARY_BUS >> 2):
+ fake_cb_bridge_regs.cb_latency = (data >> 24) & 0xff;
+ fake_cb_bridge_regs.subordinate_busn = (data >> 16) & 0xff;
+ fake_cb_bridge_regs.cardbus_busn = (data >> 8) & 0xff;
+ fake_cb_bridge_regs.pci_busn = data & 0xff;
+ if (fake_cb_bridge_regs.cardbus_busn)
+ fake_cb_bridge_regs.bus_assigned = 1;
+ break;
+
+ case (PCI_INTERRUPT_LINE >> 2):
+ tmp = (data >> 16) & 0xffff;
+ /* disable memory prefetch support */
+ tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
+ tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1;
+ fake_cb_bridge_regs.bridge_control = tmp;
+ break;
+
+ case (PCI_CB_MEMORY_BASE_0 >> 2):
+ fake_cb_bridge_regs.mem_base0 = data;
+ break;
+
+ case (PCI_CB_MEMORY_LIMIT_0 >> 2):
+ fake_cb_bridge_regs.mem_limit0 = data;
+ break;
+
+ case (PCI_CB_MEMORY_BASE_1 >> 2):
+ fake_cb_bridge_regs.mem_base1 = data;
+ break;
+
+ case (PCI_CB_MEMORY_LIMIT_1 >> 2):
+ fake_cb_bridge_regs.mem_limit1 = data;
+ break;
+
+ case (PCI_CB_IO_BASE_0 >> 2):
+ fake_cb_bridge_regs.io_base0 = data;
+ break;
+
+ case (PCI_CB_IO_LIMIT_0 >> 2):
+ fake_cb_bridge_regs.io_limit0 = data;
+ break;
+
+ case (PCI_CB_IO_BASE_1 >> 2):
+ fake_cb_bridge_regs.io_base1 = data;
+ break;
+
+ case (PCI_CB_IO_LIMIT_1 >> 2):
+ fake_cb_bridge_regs.io_limit1 = data;
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_cb_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ /* snoop access to slot 0x1e on root bus, we fake a cardbus
+ * bridge at this location */
+ if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
+ fake_cb_bridge_bus_number = bus->number;
+ return fake_cb_bridge_read(where, size, val);
+ }
+
+ /* a configuration cycle for the device behind the cardbus
+ * bridge is actually done as a type 0 cycle on the primary
+ * bus. This means that only one device can be on the cardbus
+ * bus */
+ if (fake_cb_bridge_regs.bus_assigned &&
+ bus->number == fake_cb_bridge_regs.cardbus_busn &&
+ PCI_SLOT(devfn) == 0)
+ return bcm63xx_do_cfg_read(0, 0,
+ PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
+ where, size, val);
+
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int bcm63xx_cb_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
+ fake_cb_bridge_bus_number = bus->number;
+ return fake_cb_bridge_write(where, size, val);
+ }
+
+ if (fake_cb_bridge_regs.bus_assigned &&
+ bus->number == fake_cb_bridge_regs.cardbus_busn &&
+ PCI_SLOT(devfn) == 0)
+ return bcm63xx_do_cfg_write(0, 0,
+ PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
+ where, size, val);
+
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+struct pci_ops bcm63xx_cb_ops = {
+ .read = bcm63xx_cb_read,
+ .write = bcm63xx_cb_write,
+};
+
+/*
+ * only one IO window, so it cannot be shared by PCI and cardbus, use
+ * fixup to choose and detect unhandled configuration
+ */
+static void bcm63xx_fixup(struct pci_dev *dev)
+{
+ static int io_window = -1;
+ int i, found, new_io_window;
+ u32 val;
+
+ /* look for any io resource */
+ found = 0;
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ return;
+
+ /* skip our fake bus with only cardbus bridge on it */
+ if (dev->bus->number == fake_cb_bridge_bus_number)
+ return;
+
+ /* find on which bus the device is */
+ if (fake_cb_bridge_regs.bus_assigned &&
+ dev->bus->number == fake_cb_bridge_regs.cardbus_busn &&
+ PCI_SLOT(dev->devfn) == 0)
+ new_io_window = 1;
+ else
+ new_io_window = 0;
+
+ if (new_io_window == io_window)
+ return;
+
+ if (io_window != -1) {
+ printk(KERN_ERR "bcm63xx: both PCI and cardbus devices "
+ "need IO, which hardware cannot do\n");
+ return;
+ }
+
+ printk(KERN_INFO "bcm63xx: PCI IO window assigned to %s\n",
+ (new_io_window == 0) ? "PCI" : "cardbus");
+
+ val = bcm_mpi_readl(MPI_L2PIOREMAP_REG);
+ if (io_window)
+ val |= MPI_L2PREMAP_IS_CARDBUS_MASK;
+ else
+ val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK;
+ bcm_mpi_writel(val, MPI_L2PIOREMAP_REG);
+
+ io_window = new_io_window;
+}
+
+DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
+#endif
diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
new file mode 100644
index 00000000..1b3e03f2
--- /dev/null
+++ b/arch/mips/pci/ops-bonito64.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mips-boards/bonito64.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+#define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset))
+#define ID_SEL_BEGIN 10
+#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
+
+
+static int bonito64_pcibios_config_access(unsigned char access_type,
+ struct pci_bus *bus,
+ unsigned int devfn, int where,
+ u32 * data)
+{
+ u32 busnum = bus->number;
+ u32 addr, type;
+ u32 dummy;
+ void *addrp;
+ int device = PCI_SLOT(devfn);
+ int function = PCI_FUNC(devfn);
+ int reg = where & ~3;
+
+ if (busnum == 0) {
+ /* Type 0 configuration for onboard PCI bus */
+ if (device > MAX_DEV_NUM)
+ return -1;
+
+ addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
+ type = 0;
+ } else {
+ /* Type 1 configuration for offboard PCI bus */
+ addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
+ type = 0x10000;
+ }
+
+ /* Clear aborts */
+ BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR;
+
+ BONITO_PCIMAP_CFG = (addr >> 16) | type;
+
+ /* Flush Bonito register block */
+ dummy = BONITO_PCIMAP_CFG;
+ mmiowb();
+
+ addrp = CFG_SPACE_REG(addr & 0xffff);
+ if (access_type == PCI_ACCESS_WRITE) {
+ writel(cpu_to_le32(*data), addrp);
+ /* Wait till done */
+ while (BONITO_PCIMSTAT & 0xF);
+ } else {
+ *data = le32_to_cpu(readl(addrp));
+ }
+
+ /* Detect Master/Target abort */
+ if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR |
+ BONITO_PCICMD_MTABORT_CLR)) {
+ /* Error occurred */
+
+ /* Clear bits */
+ BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
+ BONITO_PCICMD_MTABORT_CLR);
+
+ return -1;
+ }
+
+ return 0;
+
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int bonito64_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+ &data))
+ return -1;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bonito64_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (size == 4)
+ data = val;
+ else {
+ if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data))
+ return -1;
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ }
+
+ if (bonito64_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
+ &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops bonito64_pci_ops = {
+ .read = bonito64_pcibios_read,
+ .write = bonito64_pcibios_write
+};
diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c
new file mode 100644
index 00000000..b46b3e21
--- /dev/null
+++ b/arch/mips/pci/ops-bridge.c
@@ -0,0 +1,322 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000, 04, 06 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/pci.h>
+#include <asm/paccess.h>
+#include <asm/pci/bridge.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * Most of the IOC3 PCI config register aren't present
+ * we emulate what is needed for a normal PCI enumeration
+ */
+static u32 emulate_ioc3_cfg(int where, int size)
+{
+ if (size == 1 && where == 0x3d)
+ return 0x01;
+ else if (size == 2 && where == 0x3c)
+ return 0x0100;
+ else if (size == 4 && where == 0x3c)
+ return 0x00000100;
+
+ return 0;
+}
+
+/*
+ * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
+ * not really documented, so right now I can't write code which uses it.
+ * Therefore we use type 0 accesses for now even though they won't work
+ * correcly for PCI-to-PCI bridges.
+ *
+ * The function is complicated by the ultimate brokeness of the IOC3 chip
+ * which is used in SGI systems. The IOC3 can only handle 32-bit PCI
+ * accesses and does only decode parts of it's address space.
+ */
+
+static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * value)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+ bridge_t *bridge = bc->base;
+ int slot = PCI_SLOT(devfn);
+ int fn = PCI_FUNC(devfn);
+ volatile void *addr;
+ u32 cf, shift, mask;
+ int res;
+
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
+ if (get_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't even give the
+ * generic PCI code a chance to look at it for real ...
+ */
+ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+ goto oh_my_gawd;
+
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
+
+ if (size == 1)
+ res = get_dbe(*value, (u8 *) addr);
+ else if (size == 2)
+ res = get_dbe(*value, (u16 *) addr);
+ else
+ res = get_dbe(*value, (u32 *) addr);
+
+ return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't even give the
+ * generic PCI code a chance to look at the wrong register.
+ */
+ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
+ *value = emulate_ioc3_cfg(where, size);
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't try to access
+ * anything but 32-bit words ...
+ */
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+ if (get_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ shift = ((where & 3) << 3);
+ mask = (0xffffffffU >> ((4 - size) << 3));
+ *value = (cf >> shift) & mask;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * value)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+ bridge_t *bridge = bc->base;
+ int busno = bus->number;
+ int slot = PCI_SLOT(devfn);
+ int fn = PCI_FUNC(devfn);
+ volatile void *addr;
+ u32 cf, shift, mask;
+ int res;
+
+ bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+ addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
+ if (get_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't even give the
+ * generic PCI code a chance to look at it for real ...
+ */
+ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+ goto oh_my_gawd;
+
+ bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+ addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
+
+ if (size == 1)
+ res = get_dbe(*value, (u8 *) addr);
+ else if (size == 2)
+ res = get_dbe(*value, (u16 *) addr);
+ else
+ res = get_dbe(*value, (u32 *) addr);
+
+ return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't even give the
+ * generic PCI code a chance to look at the wrong register.
+ */
+ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
+ *value = emulate_ioc3_cfg(where, size);
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't try to access
+ * anything but 32-bit words ...
+ */
+ bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+ addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
+
+ if (get_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ shift = ((where & 3) << 3);
+ mask = (0xffffffffU >> ((4 - size) << 3));
+ *value = (cf >> shift) & mask;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * value)
+{
+ if (bus->number > 0)
+ return pci_conf1_read_config(bus, devfn, where, size, value);
+
+ return pci_conf0_read_config(bus, devfn, where, size, value);
+}
+
+static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+ bridge_t *bridge = bc->base;
+ int slot = PCI_SLOT(devfn);
+ int fn = PCI_FUNC(devfn);
+ volatile void *addr;
+ u32 cf, shift, mask, smask;
+ int res;
+
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
+ if (get_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't even give the
+ * generic PCI code a chance to look at it for real ...
+ */
+ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+ goto oh_my_gawd;
+
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
+
+ if (size == 1) {
+ res = put_dbe(value, (u8 *) addr);
+ } else if (size == 2) {
+ res = put_dbe(value, (u16 *) addr);
+ } else {
+ res = put_dbe(value, (u32 *) addr);
+ }
+
+ if (res)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't even give the
+ * generic PCI code a chance to touch the wrong register.
+ */
+ if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
+ return PCIBIOS_SUCCESSFUL;
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't try to access
+ * anything but 32-bit words ...
+ */
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+ if (get_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ shift = ((where & 3) << 3);
+ mask = (0xffffffffU >> ((4 - size) << 3));
+ smask = mask << shift;
+
+ cf = (cf & ~smask) | ((value & mask) << shift);
+ if (put_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+ bridge_t *bridge = bc->base;
+ int slot = PCI_SLOT(devfn);
+ int fn = PCI_FUNC(devfn);
+ int busno = bus->number;
+ volatile void *addr;
+ u32 cf, shift, mask, smask;
+ int res;
+
+ bridge->b_pci_cfg = (busno << 16) | (slot << 11);
+ addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
+ if (get_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't even give the
+ * generic PCI code a chance to look at it for real ...
+ */
+ if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
+ goto oh_my_gawd;
+
+ addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
+
+ if (size == 1) {
+ res = put_dbe(value, (u8 *) addr);
+ } else if (size == 2) {
+ res = put_dbe(value, (u16 *) addr);
+ } else {
+ res = put_dbe(value, (u32 *) addr);
+ }
+
+ if (res)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+
+oh_my_gawd:
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't even give the
+ * generic PCI code a chance to touch the wrong register.
+ */
+ if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
+ return PCIBIOS_SUCCESSFUL;
+
+ /*
+ * IOC3 is fucked fucked beyond believe ... Don't try to access
+ * anything but 32-bit words ...
+ */
+ addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
+
+ if (get_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ shift = ((where & 3) << 3);
+ mask = (0xffffffffU >> ((4 - size) << 3));
+ smask = mask << shift;
+
+ cf = (cf & ~smask) | ((value & mask) << shift);
+ if (put_dbe(cf, (u32 *) addr))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ if (bus->number > 0)
+ return pci_conf1_write_config(bus, devfn, where, size, value);
+
+ return pci_conf0_write_config(bus, devfn, where, size, value);
+}
+
+struct pci_ops bridge_pci_ops = {
+ .read = pci_read_config,
+ .write = pci_write_config,
+};
diff --git a/arch/mips/pci/ops-emma2rh.c b/arch/mips/pci/ops-emma2rh.c
new file mode 100644
index 00000000..710aef5c
--- /dev/null
+++ b/arch/mips/pci/ops-emma2rh.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ * This file is based on the arch/mips/pci/ops-vr41xx.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#include <asm/addrspace.h>
+#include <asm/debug.h>
+
+#include <asm/emma/emma2rh.h>
+
+#define RTABORT (0x1<<9)
+#define RMABORT (0x1<<10)
+#define EMMA2RH_PCI_SLOT_NUM 9 /* 0000:09.0 is final PCI device */
+
+/*
+ * access config space
+ */
+
+static int check_args(struct pci_bus *bus, u32 devfn, u32 * bus_num)
+{
+ /* check if the bus is top-level */
+ if (bus->parent != NULL) {
+ *bus_num = bus->number;
+ db_assert(bus_num != NULL);
+ } else
+ *bus_num = 0;
+
+ if (*bus_num == 0) {
+ /* Type 0 */
+ if (PCI_SLOT(devfn) >= 10)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ } else {
+ /* Type 1 */
+ if ((*bus_num >= 64) || (PCI_SLOT(devfn) >= 16))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ return 0;
+}
+
+static inline int set_pci_configuration_address(unsigned char bus_num,
+ unsigned int devfn, int where)
+{
+ u32 config_win0;
+
+ emma2rh_out32(EMMA2RH_PCI_INT, ~RMABORT);
+ if (bus_num == 0)
+ /*
+ * Type 0 configuration
+ */
+ config_win0 = (1 << (22 + PCI_SLOT(devfn))) | (5 << 9);
+ else
+ /*
+ * Type 1 configuration
+ */
+ config_win0 = (bus_num << 26) | (PCI_SLOT(devfn) << 22) |
+ (1 << 15) | (5 << 9);
+
+ emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, config_win0);
+
+ return 0;
+}
+
+static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, uint32_t * val)
+{
+ u32 bus_num;
+ u32 base = KSEG1ADDR(EMMA2RH_PCI_CONFIG_BASE);
+ u32 backup_win0;
+ u32 data;
+
+ *val = 0xffffffffU;
+
+ if (check_args(bus, devfn, &bus_num) == PCIBIOS_DEVICE_NOT_FOUND)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ backup_win0 = emma2rh_in32(EMMA2RH_PCI_IWIN0_CTR);
+
+ if (set_pci_configuration_address(bus_num, devfn, where) < 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ data =
+ *(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) +
+ (where & 0xfffffffc));
+
+ switch (size) {
+ case 1:
+ *val = (data >> ((where & 3) << 3)) & 0xffU;
+ break;
+ case 2:
+ *val = (data >> ((where & 2) << 3)) & 0xffffU;
+ break;
+ case 4:
+ *val = data;
+ break;
+ default:
+ emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0);
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ }
+
+ emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0);
+
+ if (emma2rh_in32(EMMA2RH_PCI_INT) & RMABORT)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ u32 bus_num;
+ u32 base = KSEG1ADDR(EMMA2RH_PCI_CONFIG_BASE);
+ u32 backup_win0;
+ u32 data;
+ int shift;
+
+ if (check_args(bus, devfn, &bus_num) == PCIBIOS_DEVICE_NOT_FOUND)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ backup_win0 = emma2rh_in32(EMMA2RH_PCI_IWIN0_CTR);
+
+ if (set_pci_configuration_address(bus_num, devfn, where) < 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /* read modify write */
+ data =
+ *(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) +
+ (where & 0xfffffffc));
+
+ switch (size) {
+ case 1:
+ shift = (where & 3) << 3;
+ data &= ~(0xffU << shift);
+ data |= ((val & 0xffU) << shift);
+ break;
+ case 2:
+ shift = (where & 2) << 3;
+ data &= ~(0xffffU << shift);
+ data |= ((val & 0xffffU) << shift);
+ break;
+ case 4:
+ data = val;
+ break;
+ default:
+ emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0);
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ }
+ *(volatile u32 *)(base + (PCI_FUNC(devfn) << 8) +
+ (where & 0xfffffffc)) = data;
+
+ emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0);
+ if (emma2rh_in32(EMMA2RH_PCI_INT) & RMABORT)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops emma2rh_pci_ops = {
+ .read = pci_config_read,
+ .write = pci_config_write,
+};
diff --git a/arch/mips/pci/ops-gt64xxx_pci0.c b/arch/mips/pci/ops-gt64xxx_pci0.c
new file mode 100644
index 00000000..3d896c5f
--- /dev/null
+++ b/arch/mips/pci/ops-gt64xxx_pci0.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+
+#include <asm/gt64120.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+/*
+ * PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF 0
+#define PCI_CFG_TYPE0_FUNC_SHF 8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF 0
+#define PCI_CFG_TYPE1_FUNC_SHF 8
+#define PCI_CFG_TYPE1_DEV_SHF 11
+#define PCI_CFG_TYPE1_BUS_SHF 16
+
+static int gt64xxx_pci0_pcibios_config_access(unsigned char access_type,
+ struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
+{
+ unsigned char busnum = bus->number;
+ u32 intr;
+
+ if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
+ return -1; /* Because of a bug in the galileo (for slot 31). */
+
+ /* Clear cause register bits */
+ GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+ GT_INTRCAUSE_TARABORT0_BIT));
+
+ /* Setup address */
+ GT_WRITE(GT_PCI0_CFGADDR_OFS,
+ (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+ (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+ ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+ GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+ if (access_type == PCI_ACCESS_WRITE) {
+ if (busnum == 0 && PCI_SLOT(devfn) == 0) {
+ /*
+ * The Galileo system controller is acting
+ * differently than other devices.
+ */
+ GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+ } else
+ __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+ } else {
+ if (busnum == 0 && PCI_SLOT(devfn) == 0) {
+ /*
+ * The Galileo system controller is acting
+ * differently than other devices.
+ */
+ *data = GT_READ(GT_PCI0_CFGDATA_OFS);
+ } else
+ *data = __GT_READ(GT_PCI0_CFGDATA_OFS);
+ }
+
+ /* Check for master or target abort */
+ intr = GT_READ(GT_INTRCAUSE_OFS);
+
+ if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
+ /* Error occurred */
+
+ /* Clear bits */
+ GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+ GT_INTRCAUSE_TARABORT0_BIT));
+
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int gt64xxx_pci0_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int gt64xxx_pci0_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data = 0;
+
+ if (size == 4)
+ data = val;
+ else {
+ if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus,
+ devfn, where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ }
+
+ if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+ where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops gt64xxx_pci0_ops = {
+ .read = gt64xxx_pci0_pcibios_read,
+ .write = gt64xxx_pci0_pcibios_write
+};
diff --git a/arch/mips/pci/ops-lantiq.c b/arch/mips/pci/ops-lantiq.c
new file mode 100644
index 00000000..1f2afb55
--- /dev/null
+++ b/arch/mips/pci/ops-lantiq.c
@@ -0,0 +1,116 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <asm/addrspace.h>
+#include <linux/vmalloc.h>
+
+#include <lantiq_soc.h>
+
+#include "pci-lantiq.h"
+
+#define LTQ_PCI_CFG_BUSNUM_SHF 16
+#define LTQ_PCI_CFG_DEVNUM_SHF 11
+#define LTQ_PCI_CFG_FUNNUM_SHF 8
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+static int ltq_pci_config_access(unsigned char access_type, struct pci_bus *bus,
+ unsigned int devfn, unsigned int where, u32 *data)
+{
+ unsigned long cfg_base;
+ unsigned long flags;
+ u32 temp;
+
+ /* we support slot from 0 to 15 dev_fn & 0x68 (AD29) is the
+ SoC itself */
+ if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
+ || ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
+ return 1;
+
+ spin_lock_irqsave(&ebu_lock, flags);
+
+ cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+ cfg_base |= (bus->number << LTQ_PCI_CFG_BUSNUM_SHF) | (devfn <<
+ LTQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
+
+ /* Perform access */
+ if (access_type == PCI_ACCESS_WRITE) {
+ ltq_w32(swab32(*data), ((u32 *)cfg_base));
+ } else {
+ *data = ltq_r32(((u32 *)(cfg_base)));
+ *data = swab32(*data);
+ }
+ wmb();
+
+ /* clean possible Master abort */
+ cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+ cfg_base |= (0x0 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
+ temp = ltq_r32(((u32 *)(cfg_base)));
+ temp = swab32(temp);
+ cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+ cfg_base |= (0x68 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
+ ltq_w32(temp, ((u32 *)cfg_base));
+
+ spin_unlock_irqrestore(&ebu_lock, flags);
+
+ if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
+ return 1;
+
+ return 0;
+}
+
+int ltq_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 data = 0;
+
+ if (ltq_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int ltq_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data = 0;
+
+ if (size == 4) {
+ data = val;
+ } else {
+ if (ltq_pci_config_access(PCI_ACCESS_READ, bus,
+ devfn, where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ }
+
+ if (ltq_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
diff --git a/arch/mips/pci/ops-loongson2.c b/arch/mips/pci/ops-loongson2.c
new file mode 100644
index 00000000..d657ee0b
--- /dev/null
+++ b/arch/mips/pci/ops-loongson2.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 1999, 2000, 2004 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Wu Zhangjin <wuzhangjin@gmail.com>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <loongson.h>
+
+#ifdef CONFIG_CS5536
+#include <cs5536/cs5536_pci.h>
+#include <cs5536/cs5536.h>
+#endif
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+#define CFG_SPACE_REG(offset) \
+ (void *)CKSEG1ADDR(LOONGSON_PCICFG_BASE | (offset))
+#define ID_SEL_BEGIN 11
+#define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
+
+
+static int loongson_pcibios_config_access(unsigned char access_type,
+ struct pci_bus *bus,
+ unsigned int devfn, int where,
+ u32 *data)
+{
+ u32 busnum = bus->number;
+ u32 addr, type;
+ u32 dummy;
+ void *addrp;
+ int device = PCI_SLOT(devfn);
+ int function = PCI_FUNC(devfn);
+ int reg = where & ~3;
+
+ if (busnum == 0) {
+ /* board-specific part,currently,only fuloong2f,yeeloong2f
+ * use CS5536, fuloong2e use via686b, gdium has no
+ * south bridge
+ */
+#ifdef CONFIG_CS5536
+ /* cs5536_pci_conf_read4/write4() will call _rdmsr/_wrmsr() to
+ * access the regsters PCI_MSR_ADDR, PCI_MSR_DATA_LO,
+ * PCI_MSR_DATA_HI, which is bigger than PCI_MSR_CTRL, so, it
+ * will not go this branch, but the others. so, no calling dead
+ * loop here.
+ */
+ if ((PCI_IDSEL_CS5536 == device) && (reg < PCI_MSR_CTRL)) {
+ switch (access_type) {
+ case PCI_ACCESS_READ:
+ *data = cs5536_pci_conf_read4(function, reg);
+ break;
+ case PCI_ACCESS_WRITE:
+ cs5536_pci_conf_write4(function, reg, *data);
+ break;
+ }
+ return 0;
+ }
+#endif
+ /* Type 0 configuration for onboard PCI bus */
+ if (device > MAX_DEV_NUM)
+ return -1;
+
+ addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
+ type = 0;
+ } else {
+ /* Type 1 configuration for offboard PCI bus */
+ addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
+ type = 0x10000;
+ }
+
+ /* Clear aborts */
+ LOONGSON_PCICMD |= LOONGSON_PCICMD_MABORT_CLR | \
+ LOONGSON_PCICMD_MTABORT_CLR;
+
+ LOONGSON_PCIMAP_CFG = (addr >> 16) | type;
+
+ /* Flush Bonito register block */
+ dummy = LOONGSON_PCIMAP_CFG;
+ mmiowb();
+
+ addrp = CFG_SPACE_REG(addr & 0xffff);
+ if (access_type == PCI_ACCESS_WRITE)
+ writel(cpu_to_le32(*data), addrp);
+ else
+ *data = le32_to_cpu(readl(addrp));
+
+ /* Detect Master/Target abort */
+ if (LOONGSON_PCICMD & (LOONGSON_PCICMD_MABORT_CLR |
+ LOONGSON_PCICMD_MTABORT_CLR)) {
+ /* Error occurred */
+
+ /* Clear bits */
+ LOONGSON_PCICMD |= (LOONGSON_PCICMD_MABORT_CLR |
+ LOONGSON_PCICMD_MTABORT_CLR);
+
+ return -1;
+ }
+
+ return 0;
+
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int loongson_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+ &data))
+ return -1;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int loongson_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (size == 4)
+ data = val;
+ else {
+ if (loongson_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data))
+ return -1;
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ }
+
+ if (loongson_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
+ &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops loongson_pci_ops = {
+ .read = loongson_pcibios_read,
+ .write = loongson_pcibios_write
+};
+
+#ifdef CONFIG_CS5536
+DEFINE_RAW_SPINLOCK(msr_lock);
+
+void _rdmsr(u32 msr, u32 *hi, u32 *lo)
+{
+ struct pci_bus bus = {
+ .number = PCI_BUS_CS5536
+ };
+ u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&msr_lock, flags);
+ loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
+ loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
+ loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+ raw_spin_unlock_irqrestore(&msr_lock, flags);
+}
+EXPORT_SYMBOL(_rdmsr);
+
+void _wrmsr(u32 msr, u32 hi, u32 lo)
+{
+ struct pci_bus bus = {
+ .number = PCI_BUS_CS5536
+ };
+ u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&msr_lock, flags);
+ loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
+ loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
+ loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+ raw_spin_unlock_irqrestore(&msr_lock, flags);
+}
+EXPORT_SYMBOL(_wrmsr);
+#endif
diff --git a/arch/mips/pci/ops-mace.c b/arch/mips/pci/ops-mace.c
new file mode 100644
index 00000000..1cfb5588
--- /dev/null
+++ b/arch/mips/pci/ops-mace.c
@@ -0,0 +1,102 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 2001 Keith M Wesolowski
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/pci.h>
+#include <asm/ip32/mace.h>
+
+#if 0
+# define DPRINTK(args...) printk(args);
+#else
+# define DPRINTK(args...)
+#endif
+
+/*
+ * O2 has up to 5 PCI devices connected into the MACE bridge. The device
+ * map looks like this:
+ *
+ * 0 aic7xxx 0
+ * 1 aic7xxx 1
+ * 2 expansion slot
+ * 3 N/C
+ * 4 N/C
+ */
+
+static inline int mkaddr(struct pci_bus *bus, unsigned int devfn,
+ unsigned int reg)
+{
+ return ((bus->number & 0xff) << 16) |
+ ((devfn & 0xff) << 8) |
+ (reg & 0xfc);
+}
+
+
+static int
+mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ u32 control = mace->pci.control;
+
+ /* disable master aborts interrupts during config read */
+ mace->pci.control = control & ~MACEPCI_CONTROL_MAR_INT;
+ mace->pci.config_addr = mkaddr(bus, devfn, reg);
+ switch (size) {
+ case 1:
+ *val = mace->pci.config_data.b[(reg & 3) ^ 3];
+ break;
+ case 2:
+ *val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1];
+ break;
+ case 4:
+ *val = mace->pci.config_data.l;
+ break;
+ }
+ /* ack possible master abort */
+ mace->pci.error &= ~MACEPCI_ERROR_MASTER_ABORT;
+ mace->pci.control = control;
+ /*
+ * someone forgot to set the ultra bit for the onboard
+ * scsi chips; we fake it here
+ */
+ if (bus->number == 0 && reg == 0x40 && size == 4 &&
+ (devfn == (1 << 3) || devfn == (2 << 3)))
+ *val |= 0x1000;
+
+ DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ mace->pci.config_addr = mkaddr(bus, devfn, reg);
+ switch (size) {
+ case 1:
+ mace->pci.config_data.b[(reg & 3) ^ 3] = val;
+ break;
+ case 2:
+ mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val;
+ break;
+ case 4:
+ mace->pci.config_data.l = val;
+ break;
+ }
+
+ DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops mace_pci_ops = {
+ .read = mace_pci_read_config,
+ .write = mace_pci_write_config,
+};
diff --git a/arch/mips/pci/ops-msc.c b/arch/mips/pci/ops-msc.c
new file mode 100644
index 00000000..5d9fbb0f
--- /dev/null
+++ b/arch/mips/pci/ops-msc.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * MIPS boards specific PCI support.
+ *
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mips-boards/msc01_pci.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+/*
+ * PCI configuration cycle AD bus definition
+ */
+/* Type 0 */
+#define PCI_CFG_TYPE0_REG_SHF 0
+#define PCI_CFG_TYPE0_FUNC_SHF 8
+
+/* Type 1 */
+#define PCI_CFG_TYPE1_REG_SHF 0
+#define PCI_CFG_TYPE1_FUNC_SHF 8
+#define PCI_CFG_TYPE1_DEV_SHF 11
+#define PCI_CFG_TYPE1_BUS_SHF 16
+
+static int msc_pcibios_config_access(unsigned char access_type,
+ struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
+{
+ unsigned char busnum = bus->number;
+ u32 intr;
+
+ /* Clear status register bits. */
+ MSC_WRITE(MSC01_PCI_INTSTAT,
+ (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
+
+ MSC_WRITE(MSC01_PCI_CFGADDR,
+ ((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) |
+ (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF) |
+ (PCI_FUNC(devfn) << MSC01_PCI_CFGADDR_FNUM_SHF) |
+ ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF)));
+
+ /* Perform access */
+ if (access_type == PCI_ACCESS_WRITE)
+ MSC_WRITE(MSC01_PCI_CFGDATA, *data);
+ else
+ MSC_READ(MSC01_PCI_CFGDATA, *data);
+
+ /* Detect Master/Target abort */
+ MSC_READ(MSC01_PCI_INTSTAT, intr);
+ if (intr & (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT)) {
+ /* Error occurred */
+
+ /* Clear bits */
+ MSC_WRITE(MSC01_PCI_INTSTAT,
+ (MSC01_PCI_INTCFG_MA_BIT | MSC01_PCI_INTCFG_TA_BIT));
+
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int msc_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (msc_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+ &data))
+ return -1;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int msc_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (size == 4)
+ data = val;
+ else {
+ if (msc_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data))
+ return -1;
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ }
+
+ if (msc_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
+ &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops msc_pci_ops = {
+ .read = msc_pcibios_read,
+ .write = msc_pcibios_write
+};
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
new file mode 100644
index 00000000..b7f0fb02
--- /dev/null
+++ b/arch/mips/pci/ops-nile4.c
@@ -0,0 +1,147 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/bootinfo.h>
+
+#include <asm/lasat/lasat.h>
+#include <asm/gt64120.h>
+#include <asm/nile4.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+#define LO(reg) (reg / 4)
+#define HI(reg) (reg / 4 + 1)
+
+volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
+
+static DEFINE_SPINLOCK(nile4_pci_lock);
+
+static int nile4_pcibios_config_access(unsigned char access_type,
+ struct pci_bus *bus, unsigned int devfn, int where, u32 *val)
+{
+ unsigned char busnum = bus->number;
+ u32 adr, mask, err;
+
+ if ((busnum == 0) && (PCI_SLOT(devfn) > 8))
+ /* The addressing scheme chosen leaves room for just
+ * 8 devices on the first busnum (besides the PCI
+ * controller itself) */
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) {
+ /* Access controller registers directly */
+ if (access_type == PCI_ACCESS_WRITE) {
+ vrc_pciregs[(0x200 + where) >> 2] = *val;
+ } else {
+ *val = vrc_pciregs[(0x200 + where) >> 2];
+ }
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ /* Temporarily map PCI Window 1 to config space */
+ mask = vrc_pciregs[LO(NILE4_PCIINIT1)];
+ vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0);
+
+ /* Clear PCI Error register. This also clears the Error Type
+ * bits in the Control register */
+ vrc_pciregs[LO(NILE4_PCIERR)] = 0;
+ vrc_pciregs[HI(NILE4_PCIERR)] = 0;
+
+ /* Setup address */
+ if (busnum == 0)
+ adr =
+ KSEG1ADDR(PCI_WINDOW1) +
+ ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8)
+ | (where & ~3));
+ else
+ adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) |
+ (where & ~3);
+
+ if (access_type == PCI_ACCESS_WRITE)
+ *(u32 *) adr = *val;
+ else
+ *val = *(u32 *) adr;
+
+ /* Check for master or target abort */
+ err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7;
+
+ /* Restore PCI Window 1 */
+ vrc_pciregs[LO(NILE4_PCIINIT1)] = mask;
+
+ if (err)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ unsigned long flags;
+ u32 data = 0;
+ int err;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ spin_lock_irqsave(&nile4_pci_lock, flags);
+ err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+ &data);
+ spin_unlock_irqrestore(&nile4_pci_lock, flags);
+
+ if (err)
+ return err;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ unsigned long flags;
+ u32 data = 0;
+ int err;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ spin_lock_irqsave(&nile4_pci_lock, flags);
+ err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
+ &data);
+ spin_unlock_irqrestore(&nile4_pci_lock, flags);
+
+ if (err)
+ return err;
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ if (nile4_pcibios_config_access
+ (PCI_ACCESS_WRITE, bus, devfn, where, &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops nile4_pci_ops = {
+ .read = nile4_pcibios_read,
+ .write = nile4_pcibios_write,
+};
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
new file mode 100644
index 00000000..8fbfbf2b
--- /dev/null
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -0,0 +1,998 @@
+/*
+ * PMC-Sierra MSP board specific pci_ops
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Copyright 2005-2007 PMC-Sierra, Inc
+ *
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * Much of the code is derived from the original DDB5074 port by
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#define PCI_COUNTERS 1
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+
+#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/byteorder.h>
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+#include <asm/mipsmtregs.h>
+#endif
+
+#include <msp_prom.h>
+#include <msp_cic_int.h>
+#include <msp_pci.h>
+#include <msp_regs.h>
+#include <msp_regops.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
+static char proc_init;
+extern struct proc_dir_entry *proc_bus_pci_dir;
+unsigned int pci_int_count[32];
+
+static void pci_proc_init(void);
+
+/*****************************************************************************
+ *
+ * FUNCTION: read_msp_pci_counts
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Prints the count of how many times each PCI
+ * interrupt has asserted. Can be invoked by the
+ * /proc filesystem.
+ *
+ * INPUTS: page - part of STDOUT calculation
+ * off - part of STDOUT calculation
+ * count - part of STDOUT calculation
+ * data - unused
+ *
+ * OUTPUTS: start - new start location
+ * eof - end of file pointer
+ *
+ * RETURNS: len - STDOUT length
+ *
+ ****************************************************************************/
+static int read_msp_pci_counts(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int i;
+ int len = 0;
+ unsigned int intcount, total = 0;
+
+ for (i = 0; i < 32; ++i) {
+ intcount = pci_int_count[i];
+ if (intcount != 0) {
+ len += sprintf(page + len, "[%d] = %u\n", i, intcount);
+ total += intcount;
+ }
+ }
+
+ len += sprintf(page + len, "total = %u\n", total);
+ if (len <= off+count)
+ *eof = 1;
+
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+
+ return len;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: gen_pci_cfg_wr
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Generates a configuration write cycle for debug purposes.
+ * The IDSEL line asserted and location and data written are
+ * immaterial. Just want to be able to prove that a
+ * configuration write can be correctly generated on the
+ * PCI bus. Intent is that this function by invocable from
+ * the /proc filesystem.
+ *
+ * INPUTS: page - part of STDOUT calculation
+ * off - part of STDOUT calculation
+ * count - part of STDOUT calculation
+ * data - unused
+ *
+ * OUTPUTS: start - new start location
+ * eof - end of file pointer
+ *
+ * RETURNS: len - STDOUT length
+ *
+ ****************************************************************************/
+static int gen_pci_cfg_wr(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ unsigned char where = 0; /* Write to static Device/Vendor ID */
+ unsigned char bus_num = 0; /* Bus 0 */
+ unsigned char dev_fn = 0xF; /* Arbitrary device number */
+ u32 wr_data = 0xFF00AA00; /* Arbitrary data */
+ struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
+ int len = 0;
+ unsigned long value;
+ int intr;
+
+ len += sprintf(page + len, "PMC MSP PCI: Beginning\n");
+
+ if (proc_init == 0) {
+ pci_proc_init();
+ proc_init = ~0;
+ }
+
+ len += sprintf(page + len, "PMC MSP PCI: Before Cfg Wr\n");
+
+ /*
+ * Generate PCI Configuration Write Cycle
+ */
+
+ /* Clear cause register bits */
+ preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
+
+ /* Setup address that is to appear on PCI bus */
+ preg->config_addr = BPCI_CFGADDR_ENABLE |
+ (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
+ (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
+ (where & 0xFC);
+
+ value = cpu_to_le32(wr_data);
+
+ /* Launch the PCI configuration write cycle */
+ *PCI_CONFIG_SPACE_REG = value;
+
+ /*
+ * Check if the PCI configuration cycle (rd or wr) succeeded, by
+ * checking the status bits for errors like master or target abort.
+ */
+ intr = preg->if_status;
+
+ len += sprintf(page + len, "PMC MSP PCI: After Cfg Wr\n");
+
+ /* Handle STDOUT calculations */
+ if (len <= off+count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+
+ return len;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: pci_proc_init
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Create entries in the /proc filesystem for debug access.
+ *
+ * INPUTS: none
+ *
+ * OUTPUTS: none
+ *
+ * RETURNS: none
+ *
+ ****************************************************************************/
+static void pci_proc_init(void)
+{
+ create_proc_read_entry("pmc_msp_pci_rd_cnt", 0, NULL,
+ read_msp_pci_counts, NULL);
+ create_proc_read_entry("pmc_msp_pci_cfg_wr", 0, NULL,
+ gen_pci_cfg_wr, NULL);
+}
+#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
+
+static DEFINE_SPINLOCK(bpci_lock);
+
+/*****************************************************************************
+ *
+ * STRUCT: pci_io_resource
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Defines the address range that pciauto() will use to
+ * assign to the I/O BARs of PCI devices.
+ *
+ * Use the start and end addresses of the MSP7120 PCI Host
+ * Controller I/O space, in the form that they appear on the
+ * PCI bus AFTER MSP7120 has performed address translation.
+ *
+ * For I/O accesses, MSP7120 ignores OATRAN and maps I/O
+ * accesses into the bottom 0xFFF region of address space,
+ * so that is the range to put into the pci_io_resource
+ * struct.
+ *
+ * In MSP4200, the start address was 0x04 instead of the
+ * expected 0x00. Will just assume there was a good reason
+ * for this!
+ *
+ * NOTES: Linux, by default, will assign I/O space to the lowest
+ * region of address space. Since MSP7120 and Linux,
+ * by default, have no offset in between how they map, the
+ * io_offset element of pci_controller struct should be set
+ * to zero.
+ * ELEMENTS:
+ * name - String used for a meaningful name.
+ *
+ * start - Start address of MSP7120's I/O space, as MSP7120 presents
+ * the address on the PCI bus.
+ *
+ * end - End address of MSP7120's I/O space, as MSP7120 presents
+ * the address on the PCI bus.
+ *
+ * flags - Attributes indicating the type of resource. In this case,
+ * indicate I/O space.
+ *
+ ****************************************************************************/
+static struct resource pci_io_resource = {
+ .name = "pci IO space",
+ .start = 0x04,
+ .end = 0x0FFF,
+ .flags = IORESOURCE_IO /* I/O space */
+};
+
+/*****************************************************************************
+ *
+ * STRUCT: pci_mem_resource
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Defines the address range that pciauto() will use to
+ * assign to the memory BARs of PCI devices.
+ *
+ * The .start and .end values are dependent upon how address
+ * translation is performed by the OATRAN regiser.
+ *
+ * The values to use for .start and .end are the values
+ * in the form they appear on the PCI bus AFTER MSP7120 has
+ * performed OATRAN address translation.
+ *
+ * ELEMENTS:
+ * name - String used for a meaningful name.
+ *
+ * start - Start address of MSP7120's memory space, as MSP7120 presents
+ * the address on the PCI bus.
+ *
+ * end - End address of MSP7120's memory space, as MSP7120 presents
+ * the address on the PCI bus.
+ *
+ * flags - Attributes indicating the type of resource. In this case,
+ * indicate memory space.
+ *
+ ****************************************************************************/
+static struct resource pci_mem_resource = {
+ .name = "pci memory space",
+ .start = MSP_PCI_SPACE_BASE,
+ .end = MSP_PCI_SPACE_END,
+ .flags = IORESOURCE_MEM /* memory space */
+};
+
+/*****************************************************************************
+ *
+ * FUNCTION: bpci_interrupt
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: PCI status interrupt handler. Updates the count of how
+ * many times each status bit has been set, then clears
+ * the status bits. If the appropriate macros are defined,
+ * these counts can be viewed via the /proc filesystem.
+ *
+ * INPUTS: irq - unused
+ * dev_id - unused
+ * pt_regs - unused
+ *
+ * OUTPUTS: none
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ *
+ ****************************************************************************/
+static irqreturn_t bpci_interrupt(int irq, void *dev_id)
+{
+ struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
+ unsigned int stat = preg->if_status;
+
+#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
+ int i;
+ for (i = 0; i < 32; ++i) {
+ if ((1 << i) & stat)
+ ++pci_int_count[i];
+ }
+#endif /* PROC_FS && PCI_COUNTERS */
+
+ /* printk("PCI ISR: Status=%08X\n", stat); */
+
+ /* write to clear all asserted interrupts */
+ preg->if_status = stat;
+
+ return IRQ_HANDLED;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_config_access
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Performs a PCI configuration access (rd or wr), then
+ * checks that the access succeeded by querying MSP7120's
+ * PCI status bits.
+ *
+ * INPUTS:
+ * access_type - kind of PCI configuration cycle to perform
+ * (read or write). Legal values are
+ * PCI_ACCESS_WRITE and PCI_ACCESS_READ.
+ *
+ * bus - pointer to the bus number of the device to
+ * be targeted for the configuration cycle.
+ * The only element of the pci_bus structure
+ * used is bus->number. This argument determines
+ * if the configuration access will be Type 0 or
+ * Type 1. Since MSP7120 assumes itself to be the
+ * PCI Host, any non-zero bus->number generates
+ * a Type 1 access.
+ *
+ * devfn - this is an 8-bit field. The lower three bits
+ * specify the function number of the device to
+ * be targeted for the configuration cycle, with
+ * all three-bit combinations being legal. The
+ * upper five bits specify the device number,
+ * with legal values being 10 to 31.
+ *
+ * where - address within the Configuration Header
+ * space to access.
+ *
+ * data - for write accesses, contains the data to
+ * write.
+ *
+ * OUTPUTS:
+ * data - for read accesses, contains the value read.
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * -1 - access failure
+ *
+ ****************************************************************************/
+int msp_pcibios_config_access(unsigned char access_type,
+ struct pci_bus *bus,
+ unsigned int devfn,
+ unsigned char where,
+ u32 *data)
+{
+ struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
+ unsigned char bus_num = bus->number;
+ unsigned char dev_fn = (unsigned char)devfn;
+ unsigned long flags;
+ unsigned long intr;
+ unsigned long value;
+ static char pciirqflag;
+ int ret;
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+ unsigned int vpe_status;
+#endif
+
+#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
+ if (proc_init == 0) {
+ pci_proc_init();
+ proc_init = ~0;
+ }
+#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
+
+ /*
+ * Just the first time this function invokes, allocate
+ * an interrupt line for PCI host status interrupts. The
+ * allocation assigns an interrupt handler to the interrupt.
+ */
+ if (pciirqflag == 0) {
+ ret = request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
+ bpci_interrupt,
+ IRQF_SHARED | IRQF_DISABLED,
+ "PMC MSP PCI Host",
+ preg);
+ if (ret != 0)
+ return ret;
+ pciirqflag = ~0;
+ }
+
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+ local_irq_save(flags);
+ vpe_status = dvpe();
+#else
+ spin_lock_irqsave(&bpci_lock, flags);
+#endif
+
+ /*
+ * Clear PCI cause register bits.
+ *
+ * In Polo, the PCI Host had a dedicated DMA called the
+ * Block Copy (not to be confused with the general purpose Block
+ * Copy Engine block). There appear to have been special interrupts
+ * for this Block Copy, called Block Copy 0 Fault (BC0F) and
+ * Block Copy 1 Fault (BC1F). MSP4200 and MSP7120 don't have this
+ * dedicated Block Copy block, so these two interrupts are now
+ * marked reserved. In case the Block Copy is resurrected in a
+ * future design, maintain the code that treats these two interrupts
+ * specially.
+ *
+ * Write to clear all interrupts in the PCI status register, aside
+ * from BC0F and BC1F.
+ */
+ preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
+
+ /* Setup address that is to appear on PCI bus */
+ preg->config_addr = BPCI_CFGADDR_ENABLE |
+ (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
+ (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
+ (where & 0xFC);
+
+ /* IF access is a PCI configuration write */
+ if (access_type == PCI_ACCESS_WRITE) {
+ value = cpu_to_le32(*data);
+ *PCI_CONFIG_SPACE_REG = value;
+ } else {
+ /* ELSE access is a PCI configuration read */
+ value = le32_to_cpu(*PCI_CONFIG_SPACE_REG);
+ *data = value;
+ }
+
+ /*
+ * Check if the PCI configuration cycle (rd or wr) succeeded, by
+ * checking the status bits for errors like master or target abort.
+ */
+ intr = preg->if_status;
+
+ /* Clear config access */
+ preg->config_addr = 0;
+
+ /* IF error occurred */
+ if (intr & ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F)) {
+ /* Clear status bits */
+ preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
+
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+ evpe(vpe_status);
+ local_irq_restore(flags);
+#else
+ spin_unlock_irqrestore(&bpci_lock, flags);
+#endif
+
+ return -1;
+ }
+
+#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
+ evpe(vpe_status);
+ local_irq_restore(flags);
+#else
+ spin_unlock_irqrestore(&bpci_lock, flags);
+#endif
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_read_config_byte
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Read a byte from PCI configuration address spac
+ * Since the hardware can't address 8 bit chunks
+ * directly, read a 32-bit chunk, then mask off extraneous
+ * bits.
+ *
+ * INPUTS bus - structure containing attributes for the PCI bus
+ * that the read is destined for.
+ * devfn - device/function combination that the read is
+ * destined for.
+ * where - register within the Configuration Header space
+ * to access.
+ *
+ * OUTPUTS val - read data
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * -1 - read access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_read_config_byte(struct pci_bus *bus,
+ unsigned int devfn,
+ int where,
+ u32 *val)
+{
+ u32 data = 0;
+
+ /*
+ * If the config access did not complete normally (e.g., underwent
+ * master abort) do the PCI compliant thing, which is to supply an
+ * all ones value.
+ */
+ if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data)) {
+ *val = 0xFFFFFFFF;
+ return -1;
+ }
+
+ *val = (data >> ((where & 3) << 3)) & 0x0ff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_read_config_word
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Read a word (16 bits) from PCI configuration address space.
+ * Since the hardware can't address 16 bit chunks
+ * directly, read a 32-bit chunk, then mask off extraneous
+ * bits.
+ *
+ * INPUTS bus - structure containing attributes for the PCI bus
+ * that the read is destined for.
+ * devfn - device/function combination that the read is
+ * destined for.
+ * where - register within the Configuration Header space
+ * to access.
+ *
+ * OUTPUTS val - read data
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
+ * -1 - read access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_read_config_word(struct pci_bus *bus,
+ unsigned int devfn,
+ int where,
+ u32 *val)
+{
+ u32 data = 0;
+
+ /* if (where & 1) */ /* Commented out non-compliant code.
+ * Should allow word access to configuration
+ * registers, with only exception being when
+ * the word access would wrap around into
+ * the next dword.
+ */
+ if ((where & 3) == 3) {
+ *val = 0xFFFFFFFF;
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
+ /*
+ * If the config access did not complete normally (e.g., underwent
+ * master abort) do the PCI compliant thing, which is to supply an
+ * all ones value.
+ */
+ if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data)) {
+ *val = 0xFFFFFFFF;
+ return -1;
+ }
+
+ *val = (data >> ((where & 3) << 3)) & 0x0ffff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_read_config_dword
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Read a double word (32 bits) from PCI configuration
+ * address space.
+ *
+ * INPUTS bus - structure containing attributes for the PCI bus
+ * that the read is destined for.
+ * devfn - device/function combination that the read is
+ * destined for.
+ * where - register within the Configuration Header space
+ * to access.
+ *
+ * OUTPUTS val - read data
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
+ * -1 - read access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_read_config_dword(struct pci_bus *bus,
+ unsigned int devfn,
+ int where,
+ u32 *val)
+{
+ u32 data = 0;
+
+ /* Address must be dword aligned. */
+ if (where & 3) {
+ *val = 0xFFFFFFFF;
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
+ /*
+ * If the config access did not complete normally (e.g., underwent
+ * master abort) do the PCI compliant thing, which is to supply an
+ * all ones value.
+ */
+ if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data)) {
+ *val = 0xFFFFFFFF;
+ return -1;
+ }
+
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_write_config_byte
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Write a byte to PCI configuration address space.
+ * Since the hardware can't address 8 bit chunks
+ * directly, a read-modify-write is performed.
+ *
+ * INPUTS bus - structure containing attributes for the PCI bus
+ * that the write is destined for.
+ * devfn - device/function combination that the write is
+ * destined for.
+ * where - register within the Configuration Header space
+ * to access.
+ * val - value to write
+ *
+ * OUTPUTS none
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * -1 - write access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_write_config_byte(struct pci_bus *bus,
+ unsigned int devfn,
+ int where,
+ u8 val)
+{
+ u32 data = 0;
+
+ /* read config space */
+ if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data))
+ return -1;
+
+ /* modify the byte within the dword */
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+
+ /* write back the full dword */
+ if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+ where, &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_write_config_word
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Write a word (16-bits) to PCI configuration address space.
+ * Since the hardware can't address 16 bit chunks
+ * directly, a read-modify-write is performed.
+ *
+ * INPUTS bus - structure containing attributes for the PCI bus
+ * that the write is destined for.
+ * devfn - device/function combination that the write is
+ * destined for.
+ * where - register within the Configuration Header space
+ * to access.
+ * val - value to write
+ *
+ * OUTPUTS none
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
+ * -1 - write access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_write_config_word(struct pci_bus *bus,
+ unsigned int devfn,
+ int where,
+ u16 val)
+{
+ u32 data = 0;
+
+ /* Fixed non-compliance: if (where & 1) */
+ if ((where & 3) == 3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ /* read config space */
+ if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data))
+ return -1;
+
+ /* modify the word within the dword */
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+
+ /* write back the full dword */
+ if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+ where, &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_write_config_dword
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Write a double word (32-bits) to PCI configuration address
+ * space.
+ *
+ * INPUTS bus - structure containing attributes for the PCI bus
+ * that the write is destined for.
+ * devfn - device/function combination that the write is
+ * destined for.
+ * where - register within the Configuration Header space
+ * to access.
+ * val - value to write
+ *
+ * OUTPUTS none
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * PCIBIOS_BAD_REGISTER_NUMBER - bad register address
+ * -1 - write access failure
+ *
+ ****************************************************************************/
+static int
+msp_pcibios_write_config_dword(struct pci_bus *bus,
+ unsigned int devfn,
+ int where,
+ u32 val)
+{
+ /* check that address is dword aligned */
+ if (where & 3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ /* perform write */
+ if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+ where, &val))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_read_config
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Interface the PCI configuration read request with
+ * the appropriate function, based on how many bytes
+ * the read request is.
+ *
+ * INPUTS bus - structure containing attributes for the PCI bus
+ * that the write is destined for.
+ * devfn - device/function combination that the write is
+ * destined for.
+ * where - register within the Configuration Header space
+ * to access.
+ * size - in units of bytes, should be 1, 2, or 4.
+ *
+ * OUTPUTS val - value read, with any extraneous bytes masked
+ * to zero.
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * -1 - failure
+ *
+ ****************************************************************************/
+int
+msp_pcibios_read_config(struct pci_bus *bus,
+ unsigned int devfn,
+ int where,
+ int size,
+ u32 *val)
+{
+ if (size == 1) {
+ if (msp_pcibios_read_config_byte(bus, devfn, where, val)) {
+ return -1;
+ }
+ } else if (size == 2) {
+ if (msp_pcibios_read_config_word(bus, devfn, where, val)) {
+ return -1;
+ }
+ } else if (size == 4) {
+ if (msp_pcibios_read_config_dword(bus, devfn, where, val)) {
+ return -1;
+ }
+ } else {
+ *val = 0xFFFFFFFF;
+ return -1;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pcibios_write_config
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Interface the PCI configuration write request with
+ * the appropriate function, based on how many bytes
+ * the read request is.
+ *
+ * INPUTS bus - structure containing attributes for the PCI bus
+ * that the write is destined for.
+ * devfn - device/function combination that the write is
+ * destined for.
+ * where - register within the Configuration Header space
+ * to access.
+ * size - in units of bytes, should be 1, 2, or 4.
+ * val - value to write
+ *
+ * OUTPUTS: none
+ *
+ * RETURNS: PCIBIOS_SUCCESSFUL - success
+ * -1 - failure
+ *
+ ****************************************************************************/
+int
+msp_pcibios_write_config(struct pci_bus *bus,
+ unsigned int devfn,
+ int where,
+ int size,
+ u32 val)
+{
+ if (size == 1) {
+ if (msp_pcibios_write_config_byte(bus, devfn,
+ where, (u8)(0xFF & val))) {
+ return -1;
+ }
+ } else if (size == 2) {
+ if (msp_pcibios_write_config_word(bus, devfn,
+ where, (u16)(0xFFFF & val))) {
+ return -1;
+ }
+ } else if (size == 4) {
+ if (msp_pcibios_write_config_dword(bus, devfn, where, val)) {
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*****************************************************************************
+ *
+ * STRUCTURE: msp_pci_ops
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: structure to abstract the hardware specific PCI
+ * configuration accesses.
+ *
+ * ELEMENTS:
+ * read - function for Linux to generate PCI Configuration reads.
+ * write - function for Linux to generate PCI Configuration writes.
+ *
+ ****************************************************************************/
+struct pci_ops msp_pci_ops = {
+ .read = msp_pcibios_read_config,
+ .write = msp_pcibios_write_config
+};
+
+/*****************************************************************************
+ *
+ * STRUCTURE: msp_pci_controller
+ * _________________________________________________________________________
+ *
+ * Describes the attributes of the MSP7120 PCI Host Controller
+ *
+ * ELEMENTS:
+ * pci_ops - abstracts the hardware specific PCI configuration
+ * accesses.
+ *
+ * mem_resource - address range pciauto() uses to assign to PCI device
+ * memory BARs.
+ *
+ * mem_offset - offset between how MSP7120 outbound PCI memory
+ * transaction addresses appear on the PCI bus and how Linux
+ * wants to configure memory BARs of the PCI devices.
+ * MSP7120 does nothing funky, so just set to zero.
+ *
+ * io_resource - address range pciauto() uses to assign to PCI device
+ * I/O BARs.
+ *
+ * io_offset - offset between how MSP7120 outbound PCI I/O
+ * transaction addresses appear on the PCI bus and how
+ * Linux defaults to configure I/O BARs of the PCI devices.
+ * MSP7120 maps outbound I/O accesses into the bottom
+ * bottom 4K of PCI address space (and ignores OATRAN).
+ * Since the Linux default is to configure I/O BARs to the
+ * bottom 4K, no special offset is needed. Just set to zero.
+ *
+ ****************************************************************************/
+static struct pci_controller msp_pci_controller = {
+ .pci_ops = &msp_pci_ops,
+ .mem_resource = &pci_mem_resource,
+ .mem_offset = 0,
+ .io_map_base = MSP_PCI_IOSPACE_BASE,
+ .io_resource = &pci_io_resource,
+ .io_offset = 0
+};
+
+/*****************************************************************************
+ *
+ * FUNCTION: msp_pci_init
+ * _________________________________________________________________________
+ *
+ * DESCRIPTION: Initialize the PCI Host Controller and register it with
+ * Linux so Linux can seize control of the PCI bus.
+ *
+ ****************************************************************************/
+void __init msp_pci_init(void)
+{
+ struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
+ u32 id;
+
+ /* Extract Device ID */
+ id = read_reg32(PCI_JTAG_DEVID_REG, 0xFFFF) >> 12;
+
+ /* Check if JTAG ID identifies MSP7120 */
+ if (!MSP_HAS_PCI(id)) {
+ printk(KERN_WARNING "PCI: No PCI; id reads as %x\n", id);
+ goto no_pci;
+ }
+
+ /*
+ * Enable flushing of the PCI-SDRAM queue upon a read
+ * of the SDRAM's Memory Configuration Register.
+ */
+ *(unsigned long *)QFLUSH_REG_1 = 3;
+
+ /* Configure PCI Host Controller. */
+ preg->if_status = ~0; /* Clear cause register bits */
+ preg->config_addr = 0; /* Clear config access */
+ preg->oatran = MSP_PCI_OATRAN; /* PCI outbound addr translation */
+ preg->if_mask = 0xF8BF87C0; /* Enable all PCI status interrupts */
+
+ /* configure so inb(), outb(), and family are functional */
+ set_io_port_base(MSP_PCI_IOSPACE_BASE);
+
+ /* Tell Linux the details of the MSP7120 PCI Host Controller */
+ register_pci_controller(&msp_pci_controller);
+
+ return;
+
+no_pci:
+ /* Disable PCI channel */
+ printk(KERN_WARNING "PCI: no host PCI bus detected\n");
+}
diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c
new file mode 100644
index 00000000..1e6213fa
--- /dev/null
+++ b/arch/mips/pci/ops-pnx8550.c
@@ -0,0 +1,282 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * 2.6 port, Embedded Alley Solutions, Inc
+ *
+ * Based on:
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+
+#include <asm/mach-pnx8550/pci.h>
+#include <asm/mach-pnx8550/glb.h>
+
+static inline void clear_status(void)
+{
+ unsigned long pci_stat;
+
+ pci_stat = inl(PCI_BASE | PCI_GPPM_STATUS);
+ outl(pci_stat, PCI_BASE | PCI_GPPM_ICLR);
+}
+
+static inline unsigned int
+calc_cfg_addr(struct pci_bus *bus, unsigned int devfn, int where)
+{
+ unsigned int addr;
+
+ addr = ((bus->number > 0) ? (((bus->number & 0xff) << PCI_CFG_BUS_SHIFT) | 1) : 0);
+ addr |= ((devfn & 0xff) << PCI_CFG_FUNC_SHIFT) | (where & 0xfc);
+
+ return addr;
+}
+
+static int
+config_access(unsigned int pci_cmd, struct pci_bus *bus, unsigned int devfn, int where, unsigned int pci_mode, unsigned int *val)
+{
+ unsigned int flags;
+ unsigned long loops = 0;
+ unsigned long ioaddr = calc_cfg_addr(bus, devfn, where);
+
+ local_irq_save(flags);
+ /*Clear pending interrupt status */
+ if (inl(PCI_BASE | PCI_GPPM_STATUS)) {
+ clear_status();
+ while (!(inl(PCI_BASE | PCI_GPPM_STATUS) == 0)) ;
+ }
+
+ outl(ioaddr, PCI_BASE | PCI_GPPM_ADDR);
+
+ if ((pci_cmd == PCI_CMD_IOW) || (pci_cmd == PCI_CMD_CONFIG_WRITE))
+ outl(*val, PCI_BASE | PCI_GPPM_WDAT);
+
+ outl(INIT_PCI_CYCLE | pci_cmd | (pci_mode & PCI_BYTE_ENABLE_MASK),
+ PCI_BASE | PCI_GPPM_CTRL);
+
+ loops =
+ ((loops_per_jiffy *
+ PCI_IO_JIFFIES_TIMEOUT) >> (PCI_IO_JIFFIES_SHIFT));
+ while (1) {
+ if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_DONE) {
+ if ((pci_cmd == PCI_CMD_IOR) ||
+ (pci_cmd == PCI_CMD_CONFIG_READ))
+ *val = inl(PCI_BASE | PCI_GPPM_RDAT);
+ clear_status();
+ local_irq_restore(flags);
+ return PCIBIOS_SUCCESSFUL;
+ } else if (inl(PCI_BASE | PCI_GPPM_STATUS) & GPPM_R_MABORT) {
+ break;
+ }
+
+ loops--;
+ if (loops == 0) {
+ printk("%s : Arbiter Locked.\n", __func__);
+ }
+ }
+
+ clear_status();
+ if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_IOW)) {
+ printk("%s timeout (GPPM_CTRL=%X) ioaddr %lX pci_cmd %X\n",
+ __func__, inl(PCI_BASE | PCI_GPPM_CTRL), ioaddr,
+ pci_cmd);
+ }
+
+ if ((pci_cmd == PCI_CMD_IOR) || (pci_cmd == PCI_CMD_CONFIG_READ))
+ *val = 0xffffffff;
+ local_irq_restore(flags);
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int
+read_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 * val)
+{
+ unsigned int data = 0;
+ int err;
+
+ if (bus == NULL)
+ return -1;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
+ switch (where & 0x03) {
+ case 0:
+ *val = (unsigned char)(data & 0x000000ff);
+ break;
+ case 1:
+ *val = (unsigned char)((data & 0x0000ff00) >> 8);
+ break;
+ case 2:
+ *val = (unsigned char)((data & 0x00ff0000) >> 16);
+ break;
+ case 3:
+ *val = (unsigned char)((data & 0xff000000) >> 24);
+ break;
+ }
+
+ return err;
+}
+
+static int
+read_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 * val)
+{
+ unsigned int data = 0;
+ int err;
+
+ if (bus == NULL)
+ return -1;
+
+ if (where & 0x01)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(3 << (where & 3)), &data);
+ switch (where & 0x02) {
+ case 0:
+ *val = (unsigned short)(data & 0x0000ffff);
+ break;
+ case 2:
+ *val = (unsigned short)((data & 0xffff0000) >> 16);
+ break;
+ }
+
+ return err;
+}
+
+static int
+read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 * val)
+{
+ int err;
+ if (bus == NULL)
+ return -1;
+
+ if (where & 0x03)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, 0, val);
+
+ return err;
+}
+
+static int
+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
+{
+ unsigned int data = (unsigned int)val;
+ int err;
+
+ if (bus == NULL)
+ return -1;
+
+ switch (where & 0x03) {
+ case 1:
+ data = (data << 8);
+ break;
+ case 2:
+ data = (data << 16);
+ break;
+ case 3:
+ data = (data << 24);
+ break;
+ default:
+ break;
+ }
+
+ err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(1 << (where & 3)), &data);
+
+ return err;
+}
+
+static int
+write_config_word(struct pci_bus *bus, unsigned int devfn, int where, u16 val)
+{
+ unsigned int data = (unsigned int)val;
+ int err;
+
+ if (bus == NULL)
+ return -1;
+
+ if (where & 0x01)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ switch (where & 0x02) {
+ case 2:
+ data = (data << 16);
+ break;
+ default:
+ break;
+ }
+ err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(3 << (where & 3)), &data);
+
+ return err;
+}
+
+static int
+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val)
+{
+ int err;
+ if (bus == NULL)
+ return -1;
+
+ if (where & 0x03)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, 0, &val);
+
+ return err;
+}
+
+static int config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val)
+{
+ switch (size) {
+ case 1: {
+ u8 _val;
+ int rc = read_config_byte(bus, devfn, where, &_val);
+ *val = _val;
+ return rc;
+ }
+ case 2: {
+ u16 _val;
+ int rc = read_config_word(bus, devfn, where, &_val);
+ *val = _val;
+ return rc;
+ }
+ default:
+ return read_config_dword(bus, devfn, where, val);
+ }
+}
+
+static int config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
+{
+ switch (size) {
+ case 1:
+ return write_config_byte(bus, devfn, where, (u8) val);
+ case 2:
+ return write_config_word(bus, devfn, where, (u16) val);
+ default:
+ return write_config_dword(bus, devfn, where, val);
+ }
+}
+
+struct pci_ops pnx8550_pci_ops = {
+ config_read,
+ config_write
+};
diff --git a/arch/mips/pci/ops-rc32434.c b/arch/mips/pci/ops-rc32434.c
new file mode 100644
index 00000000..d1f8fa21
--- /dev/null
+++ b/arch/mips/pci/ops-rc32434.c
@@ -0,0 +1,207 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * pci_ops for IDT EB434 board
+ *
+ * Copyright 2004 IDT Inc. (rischelp@idt.com)
+ * Copyright 2006 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/mach-rc32434/rc32434.h>
+#include <asm/mach-rc32434/pci.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+
+#define PCI_CFG_SET(bus, slot, func, off) \
+ (rc32434_pci->pcicfga = (0x80000000 | \
+ ((bus) << 16) | ((slot)<<11) | \
+ ((func)<<8) | (off)))
+
+static inline int config_access(unsigned char access_type,
+ struct pci_bus *bus, unsigned int devfn,
+ unsigned char where, u32 *data)
+{
+ unsigned int slot = PCI_SLOT(devfn);
+ u8 func = PCI_FUNC(devfn);
+
+ /* Setup address */
+ PCI_CFG_SET(bus->number, slot, func, where);
+ rc32434_sync();
+
+ if (access_type == PCI_ACCESS_WRITE)
+ rc32434_pci->pcicfgd = *data;
+ else
+ *data = rc32434_pci->pcicfgd;
+
+ rc32434_sync();
+
+ return 0;
+}
+
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
+ int where, u8 *val)
+{
+ u32 data;
+ int ret;
+
+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ return ret;
+}
+
+static int read_config_word(struct pci_bus *bus, unsigned int devfn,
+ int where, u16 *val)
+{
+ u32 data;
+ int ret;
+
+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ return ret;
+}
+
+static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
+ int where, u32 *val)
+{
+ int ret;
+ int delay = 1;
+
+ /*
+ * Don't scan too far, else there will be errors with plugged in
+ * daughterboard (rb564).
+ */
+ if (bus->number == 0 && PCI_SLOT(devfn) > 21)
+ return 0;
+
+retry:
+ ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
+
+ /*
+ * Certain devices react delayed at device scan time, this
+ * gives them time to settle
+ */
+ if (where == PCI_VENDOR_ID) {
+ if (ret == 0xffffffff || ret == 0x00000000 ||
+ ret == 0x0000ffff || ret == 0xffff0000) {
+ if (delay > 4)
+ return 0;
+ delay *= 2;
+ msleep(delay);
+ goto retry;
+ }
+ }
+
+ return ret;
+}
+
+static int
+write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
+ u8 val)
+{
+ u32 data = 0;
+
+ if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+ return -1;
+
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+
+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
+ u16 val)
+{
+ u32 data = 0;
+
+ if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+ return -1;
+
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+
+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+ return -1;
+
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int
+write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
+ u32 val)
+{
+ if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
+ return -1;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_config_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ switch (size) {
+ case 1:
+ return read_config_byte(bus, devfn, where, (u8 *) val);
+ case 2:
+ return read_config_word(bus, devfn, where, (u16 *) val);
+ default:
+ return read_config_dword(bus, devfn, where, val);
+ }
+}
+
+static int pci_config_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ switch (size) {
+ case 1:
+ return write_config_byte(bus, devfn, where, (u8) val);
+ case 2:
+ return write_config_word(bus, devfn, where, (u16) val);
+ default:
+ return write_config_dword(bus, devfn, where, val);
+ }
+}
+
+struct pci_ops rc32434_pci_ops = {
+ .read = pci_config_read,
+ .write = pci_config_write,
+};
diff --git a/arch/mips/pci/ops-sni.c b/arch/mips/pci/ops-sni.c
new file mode 100644
index 00000000..97ed25b9
--- /dev/null
+++ b/arch/mips/pci/ops-sni.c
@@ -0,0 +1,164 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SNI specific PCI support for RM200/RM300.
+ *
+ * Copyright (C) 1997 - 2000, 2003 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/sni.h>
+
+/*
+ * It seems that on the RM200 only lower 3 bits of the 5 bit PCI device
+ * address are decoded. We therefore manually have to reject attempts at
+ * reading outside this range. Being on the paranoid side we only do this
+ * test for bus 0 and hope forwarding and decoding work properly for any
+ * subordinated busses.
+ *
+ * ASIC PCI only supports type 1 config cycles.
+ */
+static int set_config_address(unsigned int busno, unsigned int devfn, int reg)
+{
+ if ((devfn > 255) || (reg > 255))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (busno == 0 && devfn >= PCI_DEVFN(8, 0))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *(volatile u32 *)PCIMT_CONFIG_ADDRESS =
+ ((busno & 0xff) << 16) |
+ ((devfn & 0xff) << 8) |
+ (reg & 0xfc);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pcimt_read(struct pci_bus *bus, unsigned int devfn, int reg,
+ int size, u32 * val)
+{
+ int res;
+
+ if ((res = set_config_address(bus->number, devfn, reg)))
+ return res;
+
+ switch (size) {
+ case 1:
+ *val = inb(PCIMT_CONFIG_DATA + (reg & 3));
+ break;
+ case 2:
+ *val = inw(PCIMT_CONFIG_DATA + (reg & 2));
+ break;
+ case 4:
+ *val = inl(PCIMT_CONFIG_DATA);
+ break;
+ }
+
+ return 0;
+}
+
+static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int reg,
+ int size, u32 val)
+{
+ int res;
+
+ if ((res = set_config_address(bus->number, devfn, reg)))
+ return res;
+
+ switch (size) {
+ case 1:
+ outb(val, PCIMT_CONFIG_DATA + (reg & 3));
+ break;
+ case 2:
+ outw(val, PCIMT_CONFIG_DATA + (reg & 2));
+ break;
+ case 4:
+ outl(val, PCIMT_CONFIG_DATA);
+ break;
+ }
+
+ return 0;
+}
+
+struct pci_ops sni_pcimt_ops = {
+ .read = pcimt_read,
+ .write = pcimt_write,
+};
+
+static int pcit_set_config_address(unsigned int busno, unsigned int devfn, int reg)
+{
+ if ((devfn > 255) || (reg > 255) || (busno > 255))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ outl((1 << 31) | ((busno & 0xff) << 16) | ((devfn & 0xff) << 8) | (reg & 0xfc), 0xcf8);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pcit_read(struct pci_bus *bus, unsigned int devfn, int reg,
+ int size, u32 * val)
+{
+ int res;
+
+ /*
+ * on bus 0 we need to check, whether there is a device answering
+ * for the devfn by doing a config write and checking the result. If
+ * we don't do it, we will get a data bus error
+ */
+ if (bus->number == 0) {
+ pcit_set_config_address(0, 0, 0x68);
+ outl(inl(0xcfc) | 0xc0000000, 0xcfc);
+ if ((res = pcit_set_config_address(0, devfn, 0)))
+ return res;
+ outl(0xffffffff, 0xcfc);
+ pcit_set_config_address(0, 0, 0x68);
+ if (inl(0xcfc) & 0x100000)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ if ((res = pcit_set_config_address(bus->number, devfn, reg)))
+ return res;
+
+ switch (size) {
+ case 1:
+ *val = inb(PCIMT_CONFIG_DATA + (reg & 3));
+ break;
+ case 2:
+ *val = inw(PCIMT_CONFIG_DATA + (reg & 2));
+ break;
+ case 4:
+ *val = inl(PCIMT_CONFIG_DATA);
+ break;
+ }
+ return 0;
+}
+
+static int pcit_write(struct pci_bus *bus, unsigned int devfn, int reg,
+ int size, u32 val)
+{
+ int res;
+
+ if ((res = pcit_set_config_address(bus->number, devfn, reg)))
+ return res;
+
+ switch (size) {
+ case 1:
+ outb(val, PCIMT_CONFIG_DATA + (reg & 3));
+ break;
+ case 2:
+ outw(val, PCIMT_CONFIG_DATA + (reg & 2));
+ break;
+ case 4:
+ outl(val, PCIMT_CONFIG_DATA);
+ break;
+ }
+
+ return 0;
+}
+
+
+struct pci_ops sni_pcit_ops = {
+ .read = pcit_read,
+ .write = pcit_write,
+};
diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c
new file mode 100644
index 00000000..57d54adc
--- /dev/null
+++ b/arch/mips/pci/ops-titan-ht.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include <asm/titan_dep.h>
+
+static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
+ int offset, u32 *val)
+{
+ volatile uint32_t address;
+ int busno;
+
+ busno = bus->number;
+
+ address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
+ if (busno != 0)
+ address |= 1;
+
+ /*
+ * RM9000 HT Errata: Issue back to back HT config
+ * transcations. Issue a BIU sync before and
+ * after the HT cycle
+ */
+
+ *(volatile int32_t *) 0xfb0000f0 |= 0x2;
+
+ udelay(30);
+
+ *(volatile int32_t *) 0xfb0006f8 = address;
+ *(val) = *(volatile int32_t *) 0xfb0006fc;
+
+ udelay(30);
+
+ * (volatile int32_t *) 0xfb0000f0 |= 0x2;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn,
+ int offset, int size, u32 *val)
+{
+ uint32_t dword;
+
+ titan_ht_config_read_dword(bus, devfn, offset, &dword);
+
+ dword >>= ((offset & 3) << 3);
+ dword &= (0xffffffffU >> ((4 - size) << 8));
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static inline int titan_ht_config_write_dword(struct pci_bus *bus,
+ unsigned int devfn, int offset, u32 val)
+{
+ volatile uint32_t address;
+ int busno;
+
+ busno = bus->number;
+
+ address = (busno << 16) | (devfn << 8) | (offset & 0xfc) | 0x80000000;
+ if (busno != 0)
+ address |= 1;
+
+ *(volatile int32_t *) 0xfb0000f0 |= 0x2;
+
+ udelay(30);
+
+ *(volatile int32_t *) 0xfb0006f8 = address;
+ *(volatile int32_t *) 0xfb0006fc = val;
+
+ udelay(30);
+
+ *(volatile int32_t *) 0xfb0000f0 |= 0x2;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write(struct pci_bus *bus, unsigned int devfn,
+ int offset, int size, u32 val)
+{
+ uint32_t val1, val2, mask;
+
+ titan_ht_config_read_dword(bus, devfn, offset, &val2);
+
+ val1 = val << ((offset & 3) << 3);
+ mask = ~(0xffffffffU >> ((4 - size) << 8));
+ val2 &= ~(mask << ((offset & 3) << 8));
+
+ titan_ht_config_write_dword(bus, devfn, offset, val1 | val2);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops titan_ht_pci_ops = {
+ .read = titan_ht_config_read,
+ .write = titan_ht_config_write,
+};
diff --git a/arch/mips/pci/ops-titan.c b/arch/mips/pci/ops-titan.c
new file mode 100644
index 00000000..ebf8fc40
--- /dev/null
+++ b/arch/mips/pci/ops-titan.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/rm9k-ocd.h>
+
+/*
+ * PCI specific defines
+ */
+#define TITAN_PCI_0_CONFIG_ADDRESS 0x780
+#define TITAN_PCI_0_CONFIG_DATA 0x784
+
+/*
+ * Titan PCI Config Read Byte
+ */
+static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
+ int size, u32 * val)
+{
+ uint32_t address, tmp;
+ int dev, busno, func;
+
+ busno = bus->number;
+ dev = PCI_SLOT(devfn);
+ func = PCI_FUNC(devfn);
+
+ address = (busno << 16) | (dev << 11) | (func << 8) |
+ (reg & 0xfc) | 0x80000000;
+
+
+ /* start the configuration cycle */
+ ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS);
+ tmp = ocd_readl(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3);
+
+ switch (size) {
+ case 1:
+ tmp &= 0xff;
+ case 2:
+ tmp &= 0xffff;
+ }
+ *val = tmp;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
+ int size, u32 val)
+{
+ uint32_t address;
+ int dev, busno, func;
+
+ busno = bus->number;
+ dev = PCI_SLOT(devfn);
+ func = PCI_FUNC(devfn);
+
+ address = (busno << 16) | (dev << 11) | (func << 8) |
+ (reg & 0xfc) | 0x80000000;
+
+ /* start the configuration cycle */
+ ocd_writel(address, TITAN_PCI_0_CONFIG_ADDRESS);
+
+ /* write the data */
+ switch (size) {
+ case 1:
+ ocd_writeb(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3));
+ break;
+
+ case 2:
+ ocd_writew(val, TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2));
+ break;
+
+ case 4:
+ ocd_writel(val, TITAN_PCI_0_CONFIG_DATA);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Titan PCI structure
+ */
+struct pci_ops titan_pci_ops = {
+ titan_read_config,
+ titan_write_config,
+};
diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c
new file mode 100644
index 00000000..6a3bdb5f
--- /dev/null
+++ b/arch/mips/pci/ops-tx3927.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ahennessy@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
+ *
+ * Define the pci_ops for TX3927.
+ *
+ * Much of the code is derived from the original DDB5074 port by
+ * Geert Uytterhoeven <geert@sonycom.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/addrspace.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/tx3927.h>
+
+static int mkaddr(struct pci_bus *bus, unsigned char devfn, unsigned char where)
+{
+ if (bus->parent == NULL &&
+ devfn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
+ return -1;
+ tx3927_pcicptr->ica =
+ ((bus->number & 0xff) << 0x10) |
+ ((devfn & 0xff) << 0x08) |
+ (where & 0xfc) | (bus->parent ? 1 : 0);
+
+ /* clear M_ABORT and Disable M_ABORT Int. */
+ tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
+ tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;
+ return 0;
+}
+
+static inline int check_abort(void)
+{
+ if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) {
+ tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
+ tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
+ /* flush write buffer */
+ iob();
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int tx3927_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ if (mkaddr(bus, devfn, where)) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ switch (size) {
+ case 1:
+ *val = *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3));
+ break;
+
+ case 2:
+ *val = le16_to_cpu(*(volatile u16 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)));
+ break;
+
+ case 4:
+ *val = le32_to_cpu(tx3927_pcicptr->icd);
+ break;
+ }
+
+ return check_abort();
+}
+
+static int tx3927_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ if (mkaddr(bus, devfn, where))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ switch (size) {
+ case 1:
+ *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)) = val;
+ break;
+
+ case 2:
+ *(volatile u16 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 2)) =
+ cpu_to_le16(val);
+ break;
+
+ case 4:
+ tx3927_pcicptr->icd = cpu_to_le32(val);
+ }
+
+ return check_abort();
+}
+
+static struct pci_ops tx3927_pci_ops = {
+ .read = tx3927_pci_read_config,
+ .write = tx3927_pci_write_config,
+};
+
+void __init tx3927_pcic_setup(struct pci_controller *channel,
+ unsigned long sdram_size, int extarb)
+{
+ unsigned long flags;
+ unsigned long io_base =
+ channel->io_resource->start + mips_io_port_base - IO_BASE;
+ unsigned long io_size =
+ channel->io_resource->end - channel->io_resource->start;
+ unsigned long io_pciaddr =
+ channel->io_resource->start - channel->io_offset;
+ unsigned long mem_base =
+ channel->mem_resource->start;
+ unsigned long mem_size =
+ channel->mem_resource->end - channel->mem_resource->start;
+ unsigned long mem_pciaddr =
+ channel->mem_resource->start - channel->mem_offset;
+
+ printk(KERN_INFO "TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s",
+ tx3927_pcicptr->did, tx3927_pcicptr->vid,
+ tx3927_pcicptr->rid,
+ extarb ? "External" : "Internal");
+ channel->pci_ops = &tx3927_pci_ops;
+
+ local_irq_save(flags);
+ /* Disable External PCI Config. Access */
+ tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD;
+#ifdef __BIG_ENDIAN
+ tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE |
+ TX3927_PCIC_LBC_TIBSE |
+ TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE;
+#endif
+ /* LB->PCI mappings */
+ tx3927_pcicptr->iomas = ~(io_size - 1);
+ tx3927_pcicptr->ilbioma = io_base;
+ tx3927_pcicptr->ipbioma = io_pciaddr;
+ tx3927_pcicptr->mmas = ~(mem_size - 1);
+ tx3927_pcicptr->ilbmma = mem_base;
+ tx3927_pcicptr->ipbmma = mem_pciaddr;
+ /* PCI->LB mappings */
+ tx3927_pcicptr->iobas = 0xffffffff;
+ tx3927_pcicptr->ioba = 0;
+ tx3927_pcicptr->tlbioma = 0;
+ tx3927_pcicptr->mbas = ~(sdram_size - 1);
+ tx3927_pcicptr->mba = 0;
+ tx3927_pcicptr->tlbmma = 0;
+ /* Enable Direct mapping Address Space Decoder */
+ tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE;
+
+ /* Clear All Local Bus Status */
+ tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL;
+ /* Enable All Local Bus Interrupts */
+ tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL;
+ /* Clear All PCI Status Error */
+ tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL;
+ /* Enable All PCI Status Error Interrupts */
+ tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL;
+
+ /* PCIC Int => IRC IRQ10 */
+ tx3927_pcicptr->il = TX3927_IR_PCI;
+ /* Target Control (per errata) */
+ tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E;
+
+ /* Enable Bus Arbiter */
+ if (!extarb)
+ tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN;
+
+ tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER |
+ PCI_COMMAND_MEMORY |
+ PCI_COMMAND_IO |
+ PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ local_irq_restore(flags);
+}
+
+static irqreturn_t tx3927_pcierr_interrupt(int irq, void *dev_id)
+{
+ struct pt_regs *regs = get_irq_regs();
+
+ if (txx9_pci_err_action != TXX9_PCI_ERR_IGNORE) {
+ printk(KERN_WARNING "PCI error interrupt at 0x%08lx.\n",
+ regs->cp0_epc);
+ printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
+ tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
+ }
+ if (txx9_pci_err_action != TXX9_PCI_ERR_PANIC) {
+ /* clear all pci errors */
+ tx3927_pcicptr->pcistat |= TX3927_PCIC_PCISTATIM_ALL;
+ tx3927_pcicptr->istat = TX3927_PCIC_IIM_ALL;
+ tx3927_pcicptr->tstat = TX3927_PCIC_TIM_ALL;
+ tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL;
+ return IRQ_HANDLED;
+ }
+ console_verbose();
+ panic("PCI error.");
+}
+
+void __init tx3927_setup_pcierr_irq(void)
+{
+ if (request_irq(TXX9_IRQ_BASE + TX3927_IR_PCI,
+ tx3927_pcierr_interrupt,
+ IRQF_DISABLED, "PCI error",
+ (void *)TX3927_PCIC_REG))
+ printk(KERN_WARNING "Failed to request irq for PCIERR\n");
+}
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c
new file mode 100644
index 00000000..a1e7e6d8
--- /dev/null
+++ b/arch/mips/pci/ops-tx4927.c
@@ -0,0 +1,527 @@
+/*
+ * Define the pci_ops for the PCIC on Toshiba TX4927, TX4938, etc.
+ *
+ * Based on linux/arch/mips/pci/ops-tx4938.c,
+ * linux/arch/mips/pci/fixup-rbtx4938.c,
+ * linux/arch/mips/txx9/rbtx4938/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * 2003-2005 (c) MontaVista Software, Inc.
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/tx4927pcic.h>
+
+static struct {
+ struct pci_controller *channel;
+ struct tx4927_pcic_reg __iomem *pcicptr;
+} pcicptrs[2]; /* TX4938 has 2 pcic */
+
+static void __init set_tx4927_pcicptr(struct pci_controller *channel,
+ struct tx4927_pcic_reg __iomem *pcicptr)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) {
+ if (pcicptrs[i].channel == channel) {
+ pcicptrs[i].pcicptr = pcicptr;
+ return;
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) {
+ if (!pcicptrs[i].channel) {
+ pcicptrs[i].channel = channel;
+ pcicptrs[i].pcicptr = pcicptr;
+ return;
+ }
+ }
+ BUG();
+}
+
+struct tx4927_pcic_reg __iomem *get_tx4927_pcicptr(
+ struct pci_controller *channel)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) {
+ if (pcicptrs[i].channel == channel)
+ return pcicptrs[i].pcicptr;
+ }
+ return NULL;
+}
+
+static int mkaddr(struct pci_bus *bus, unsigned int devfn, int where,
+ struct tx4927_pcic_reg __iomem *pcicptr)
+{
+ if (bus->parent == NULL &&
+ devfn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0))
+ return -1;
+ __raw_writel(((bus->number & 0xff) << 0x10)
+ | ((devfn & 0xff) << 0x08) | (where & 0xfc)
+ | (bus->parent ? 1 : 0),
+ &pcicptr->g2pcfgadrs);
+ /* clear M_ABORT and Disable M_ABORT Int. */
+ __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff)
+ | (PCI_STATUS_REC_MASTER_ABORT << 16),
+ &pcicptr->pcistatus);
+ return 0;
+}
+
+static int check_abort(struct tx4927_pcic_reg __iomem *pcicptr)
+{
+ int code = PCIBIOS_SUCCESSFUL;
+
+ /* wait write cycle completion before checking error status */
+ while (__raw_readl(&pcicptr->pcicstatus) & TX4927_PCIC_PCICSTATUS_IWB)
+ ;
+ if (__raw_readl(&pcicptr->pcistatus)
+ & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+ __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff)
+ | (PCI_STATUS_REC_MASTER_ABORT << 16),
+ &pcicptr->pcistatus);
+ /* flush write buffer */
+ iob();
+ code = PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ return code;
+}
+
+static u8 icd_readb(int offset, struct tx4927_pcic_reg __iomem *pcicptr)
+{
+#ifdef __BIG_ENDIAN
+ offset ^= 3;
+#endif
+ return __raw_readb((void __iomem *)&pcicptr->g2pcfgdata + offset);
+}
+static u16 icd_readw(int offset, struct tx4927_pcic_reg __iomem *pcicptr)
+{
+#ifdef __BIG_ENDIAN
+ offset ^= 2;
+#endif
+ return __raw_readw((void __iomem *)&pcicptr->g2pcfgdata + offset);
+}
+static u32 icd_readl(struct tx4927_pcic_reg __iomem *pcicptr)
+{
+ return __raw_readl(&pcicptr->g2pcfgdata);
+}
+static void icd_writeb(u8 val, int offset,
+ struct tx4927_pcic_reg __iomem *pcicptr)
+{
+#ifdef __BIG_ENDIAN
+ offset ^= 3;
+#endif
+ __raw_writeb(val, (void __iomem *)&pcicptr->g2pcfgdata + offset);
+}
+static void icd_writew(u16 val, int offset,
+ struct tx4927_pcic_reg __iomem *pcicptr)
+{
+#ifdef __BIG_ENDIAN
+ offset ^= 2;
+#endif
+ __raw_writew(val, (void __iomem *)&pcicptr->g2pcfgdata + offset);
+}
+static void icd_writel(u32 val, struct tx4927_pcic_reg __iomem *pcicptr)
+{
+ __raw_writel(val, &pcicptr->g2pcfgdata);
+}
+
+static struct tx4927_pcic_reg __iomem *pci_bus_to_pcicptr(struct pci_bus *bus)
+{
+ struct pci_controller *channel = bus->sysdata;
+ return get_tx4927_pcicptr(channel);
+}
+
+static int tx4927_pci_config_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(bus);
+
+ if (mkaddr(bus, devfn, where, pcicptr)) {
+ *val = 0xffffffff;
+ return -1;
+ }
+ switch (size) {
+ case 1:
+ *val = icd_readb(where & 3, pcicptr);
+ break;
+ case 2:
+ *val = icd_readw(where & 3, pcicptr);
+ break;
+ default:
+ *val = icd_readl(pcicptr);
+ }
+ return check_abort(pcicptr);
+}
+
+static int tx4927_pci_config_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(bus);
+
+ if (mkaddr(bus, devfn, where, pcicptr))
+ return -1;
+ switch (size) {
+ case 1:
+ icd_writeb(val, where & 3, pcicptr);
+ break;
+ case 2:
+ icd_writew(val, where & 3, pcicptr);
+ break;
+ default:
+ icd_writel(val, pcicptr);
+ }
+ return check_abort(pcicptr);
+}
+
+static struct pci_ops tx4927_pci_ops = {
+ .read = tx4927_pci_config_read,
+ .write = tx4927_pci_config_write,
+};
+
+static struct {
+ u8 trdyto;
+ u8 retryto;
+ u16 gbwc;
+} tx4927_pci_opts __devinitdata = {
+ .trdyto = 0,
+ .retryto = 0,
+ .gbwc = 0xfe0, /* 4064 GBUSCLK for CCFG.GTOT=0b11 */
+};
+
+char *__devinit tx4927_pcibios_setup(char *str)
+{
+ unsigned long val;
+
+ if (!strncmp(str, "trdyto=", 7)) {
+ if (strict_strtoul(str + 7, 0, &val) == 0)
+ tx4927_pci_opts.trdyto = val;
+ return NULL;
+ }
+ if (!strncmp(str, "retryto=", 8)) {
+ if (strict_strtoul(str + 8, 0, &val) == 0)
+ tx4927_pci_opts.retryto = val;
+ return NULL;
+ }
+ if (!strncmp(str, "gbwc=", 5)) {
+ if (strict_strtoul(str + 5, 0, &val) == 0)
+ tx4927_pci_opts.gbwc = val;
+ return NULL;
+ }
+ return str;
+}
+
+void __init tx4927_pcic_setup(struct tx4927_pcic_reg __iomem *pcicptr,
+ struct pci_controller *channel, int extarb)
+{
+ int i;
+ unsigned long flags;
+
+ set_tx4927_pcicptr(channel, pcicptr);
+
+ if (!channel->pci_ops)
+ printk(KERN_INFO
+ "PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n",
+ __raw_readl(&pcicptr->pciid) >> 16,
+ __raw_readl(&pcicptr->pciid) & 0xffff,
+ __raw_readl(&pcicptr->pciccrev) & 0xff,
+ extarb ? "External" : "Internal");
+ channel->pci_ops = &tx4927_pci_ops;
+
+ local_irq_save(flags);
+
+ /* Disable All Initiator Space */
+ __raw_writel(__raw_readl(&pcicptr->pciccfg)
+ & ~(TX4927_PCIC_PCICCFG_G2PMEN(0)
+ | TX4927_PCIC_PCICCFG_G2PMEN(1)
+ | TX4927_PCIC_PCICCFG_G2PMEN(2)
+ | TX4927_PCIC_PCICCFG_G2PIOEN),
+ &pcicptr->pciccfg);
+
+ /* GB->PCI mappings */
+ __raw_writel((channel->io_resource->end - channel->io_resource->start)
+ >> 4,
+ &pcicptr->g2piomask);
+ ____raw_writeq((channel->io_resource->start +
+ channel->io_map_base - IO_BASE) |
+#ifdef __BIG_ENDIAN
+ TX4927_PCIC_G2PIOGBASE_ECHG
+#else
+ TX4927_PCIC_G2PIOGBASE_BSDIS
+#endif
+ , &pcicptr->g2piogbase);
+ ____raw_writeq(channel->io_resource->start - channel->io_offset,
+ &pcicptr->g2piopbase);
+ for (i = 0; i < 3; i++) {
+ __raw_writel(0, &pcicptr->g2pmmask[i]);
+ ____raw_writeq(0, &pcicptr->g2pmgbase[i]);
+ ____raw_writeq(0, &pcicptr->g2pmpbase[i]);
+ }
+ if (channel->mem_resource->end) {
+ __raw_writel((channel->mem_resource->end
+ - channel->mem_resource->start) >> 4,
+ &pcicptr->g2pmmask[0]);
+ ____raw_writeq(channel->mem_resource->start |
+#ifdef __BIG_ENDIAN
+ TX4927_PCIC_G2PMnGBASE_ECHG
+#else
+ TX4927_PCIC_G2PMnGBASE_BSDIS
+#endif
+ , &pcicptr->g2pmgbase[0]);
+ ____raw_writeq(channel->mem_resource->start -
+ channel->mem_offset,
+ &pcicptr->g2pmpbase[0]);
+ }
+ /* PCI->GB mappings (I/O 256B) */
+ __raw_writel(0, &pcicptr->p2giopbase); /* 256B */
+ ____raw_writeq(0, &pcicptr->p2giogbase);
+ /* PCI->GB mappings (MEM 512MB (64MB on R1.x)) */
+ __raw_writel(0, &pcicptr->p2gm0plbase);
+ __raw_writel(0, &pcicptr->p2gm0pubase);
+ ____raw_writeq(TX4927_PCIC_P2GMnGBASE_TMEMEN |
+#ifdef __BIG_ENDIAN
+ TX4927_PCIC_P2GMnGBASE_TECHG
+#else
+ TX4927_PCIC_P2GMnGBASE_TBSDIS
+#endif
+ , &pcicptr->p2gmgbase[0]);
+ /* PCI->GB mappings (MEM 16MB) */
+ __raw_writel(0xffffffff, &pcicptr->p2gm1plbase);
+ __raw_writel(0xffffffff, &pcicptr->p2gm1pubase);
+ ____raw_writeq(0, &pcicptr->p2gmgbase[1]);
+ /* PCI->GB mappings (MEM 1MB) */
+ __raw_writel(0xffffffff, &pcicptr->p2gm2pbase); /* 1MB */
+ ____raw_writeq(0, &pcicptr->p2gmgbase[2]);
+
+ /* Clear all (including IRBER) except for GBWC */
+ __raw_writel((tx4927_pci_opts.gbwc << 16)
+ & TX4927_PCIC_PCICCFG_GBWC_MASK,
+ &pcicptr->pciccfg);
+ /* Enable Initiator Memory Space */
+ if (channel->mem_resource->end)
+ __raw_writel(__raw_readl(&pcicptr->pciccfg)
+ | TX4927_PCIC_PCICCFG_G2PMEN(0),
+ &pcicptr->pciccfg);
+ /* Enable Initiator I/O Space */
+ if (channel->io_resource->end)
+ __raw_writel(__raw_readl(&pcicptr->pciccfg)
+ | TX4927_PCIC_PCICCFG_G2PIOEN,
+ &pcicptr->pciccfg);
+ /* Enable Initiator Config */
+ __raw_writel(__raw_readl(&pcicptr->pciccfg)
+ | TX4927_PCIC_PCICCFG_ICAEN | TX4927_PCIC_PCICCFG_TCAR,
+ &pcicptr->pciccfg);
+
+ /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */
+ __raw_writel(0, &pcicptr->pcicfg1);
+
+ __raw_writel((__raw_readl(&pcicptr->g2ptocnt) & ~0xffff)
+ | (tx4927_pci_opts.trdyto & 0xff)
+ | ((tx4927_pci_opts.retryto & 0xff) << 8),
+ &pcicptr->g2ptocnt);
+
+ /* Clear All Local Bus Status */
+ __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicstatus);
+ /* Enable All Local Bus Interrupts */
+ __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicmask);
+ /* Clear All Initiator Status */
+ __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pstatus);
+ /* Enable All Initiator Interrupts */
+ __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pmask);
+ /* Clear All PCI Status Error */
+ __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff)
+ | (TX4927_PCIC_PCISTATUS_ALL << 16),
+ &pcicptr->pcistatus);
+ /* Enable All PCI Status Error Interrupts */
+ __raw_writel(TX4927_PCIC_PCISTATUS_ALL, &pcicptr->pcimask);
+
+ if (!extarb) {
+ /* Reset Bus Arbiter */
+ __raw_writel(TX4927_PCIC_PBACFG_RPBA, &pcicptr->pbacfg);
+ __raw_writel(0, &pcicptr->pbabm);
+ /* Enable Bus Arbiter */
+ __raw_writel(TX4927_PCIC_PBACFG_PBAEN, &pcicptr->pbacfg);
+ }
+
+ __raw_writel(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
+ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR,
+ &pcicptr->pcistatus);
+ local_irq_restore(flags);
+
+ printk(KERN_DEBUG
+ "PCI: COMMAND=%04x,PCIMASK=%04x,"
+ "TRDYTO=%02x,RETRYTO=%02x,GBWC=%03x\n",
+ __raw_readl(&pcicptr->pcistatus) & 0xffff,
+ __raw_readl(&pcicptr->pcimask) & 0xffff,
+ __raw_readl(&pcicptr->g2ptocnt) & 0xff,
+ (__raw_readl(&pcicptr->g2ptocnt) & 0xff00) >> 8,
+ (__raw_readl(&pcicptr->pciccfg) >> 16) & 0xfff);
+}
+
+static void tx4927_report_pcic_status1(struct tx4927_pcic_reg __iomem *pcicptr)
+{
+ __u16 pcistatus = (__u16)(__raw_readl(&pcicptr->pcistatus) >> 16);
+ __u32 g2pstatus = __raw_readl(&pcicptr->g2pstatus);
+ __u32 pcicstatus = __raw_readl(&pcicptr->pcicstatus);
+ static struct {
+ __u32 flag;
+ const char *str;
+ } pcistat_tbl[] = {
+ { PCI_STATUS_DETECTED_PARITY, "DetectedParityError" },
+ { PCI_STATUS_SIG_SYSTEM_ERROR, "SignaledSystemError" },
+ { PCI_STATUS_REC_MASTER_ABORT, "ReceivedMasterAbort" },
+ { PCI_STATUS_REC_TARGET_ABORT, "ReceivedTargetAbort" },
+ { PCI_STATUS_SIG_TARGET_ABORT, "SignaledTargetAbort" },
+ { PCI_STATUS_PARITY, "MasterParityError" },
+ }, g2pstat_tbl[] = {
+ { TX4927_PCIC_G2PSTATUS_TTOE, "TIOE" },
+ { TX4927_PCIC_G2PSTATUS_RTOE, "RTOE" },
+ }, pcicstat_tbl[] = {
+ { TX4927_PCIC_PCICSTATUS_PME, "PME" },
+ { TX4927_PCIC_PCICSTATUS_TLB, "TLB" },
+ { TX4927_PCIC_PCICSTATUS_NIB, "NIB" },
+ { TX4927_PCIC_PCICSTATUS_ZIB, "ZIB" },
+ { TX4927_PCIC_PCICSTATUS_PERR, "PERR" },
+ { TX4927_PCIC_PCICSTATUS_SERR, "SERR" },
+ { TX4927_PCIC_PCICSTATUS_GBE, "GBE" },
+ { TX4927_PCIC_PCICSTATUS_IWB, "IWB" },
+ };
+ int i, cont;
+
+ printk(KERN_ERR "");
+ if (pcistatus & TX4927_PCIC_PCISTATUS_ALL) {
+ printk(KERN_CONT "pcistat:%04x(", pcistatus);
+ for (i = 0, cont = 0; i < ARRAY_SIZE(pcistat_tbl); i++)
+ if (pcistatus & pcistat_tbl[i].flag)
+ printk(KERN_CONT "%s%s",
+ cont++ ? " " : "", pcistat_tbl[i].str);
+ printk(KERN_CONT ") ");
+ }
+ if (g2pstatus & TX4927_PCIC_G2PSTATUS_ALL) {
+ printk(KERN_CONT "g2pstatus:%08x(", g2pstatus);
+ for (i = 0, cont = 0; i < ARRAY_SIZE(g2pstat_tbl); i++)
+ if (g2pstatus & g2pstat_tbl[i].flag)
+ printk(KERN_CONT "%s%s",
+ cont++ ? " " : "", g2pstat_tbl[i].str);
+ printk(KERN_CONT ") ");
+ }
+ if (pcicstatus & TX4927_PCIC_PCICSTATUS_ALL) {
+ printk(KERN_CONT "pcicstatus:%08x(", pcicstatus);
+ for (i = 0, cont = 0; i < ARRAY_SIZE(pcicstat_tbl); i++)
+ if (pcicstatus & pcicstat_tbl[i].flag)
+ printk(KERN_CONT "%s%s",
+ cont++ ? " " : "", pcicstat_tbl[i].str);
+ printk(KERN_CONT ")");
+ }
+ printk(KERN_CONT "\n");
+}
+
+void tx4927_report_pcic_status(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) {
+ if (pcicptrs[i].pcicptr)
+ tx4927_report_pcic_status1(pcicptrs[i].pcicptr);
+ }
+}
+
+static void tx4927_dump_pcic_settings1(struct tx4927_pcic_reg __iomem *pcicptr)
+{
+ int i;
+ __u32 __iomem *preg = (__u32 __iomem *)pcicptr;
+
+ printk(KERN_INFO "tx4927 pcic (0x%p) settings:", pcicptr);
+ for (i = 0; i < sizeof(struct tx4927_pcic_reg); i += 4, preg++) {
+ if (i % 32 == 0) {
+ printk(KERN_CONT "\n");
+ printk(KERN_INFO "%04x:", i);
+ }
+ /* skip registers with side-effects */
+ if (i == offsetof(struct tx4927_pcic_reg, g2pintack)
+ || i == offsetof(struct tx4927_pcic_reg, g2pspc)
+ || i == offsetof(struct tx4927_pcic_reg, g2pcfgadrs)
+ || i == offsetof(struct tx4927_pcic_reg, g2pcfgdata)) {
+ printk(KERN_CONT " XXXXXXXX");
+ continue;
+ }
+ printk(KERN_CONT " %08x", __raw_readl(preg));
+ }
+ printk(KERN_CONT "\n");
+}
+
+void tx4927_dump_pcic_settings(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pcicptrs); i++) {
+ if (pcicptrs[i].pcicptr)
+ tx4927_dump_pcic_settings1(pcicptrs[i].pcicptr);
+ }
+}
+
+irqreturn_t tx4927_pcierr_interrupt(int irq, void *dev_id)
+{
+ struct pt_regs *regs = get_irq_regs();
+ struct tx4927_pcic_reg __iomem *pcicptr =
+ (struct tx4927_pcic_reg __iomem *)(unsigned long)dev_id;
+
+ if (txx9_pci_err_action != TXX9_PCI_ERR_IGNORE) {
+ printk(KERN_WARNING "PCIERR interrupt at 0x%0*lx\n",
+ (int)(2 * sizeof(unsigned long)), regs->cp0_epc);
+ tx4927_report_pcic_status1(pcicptr);
+ }
+ if (txx9_pci_err_action != TXX9_PCI_ERR_PANIC) {
+ /* clear all pci errors */
+ __raw_writel((__raw_readl(&pcicptr->pcistatus) & 0x0000ffff)
+ | (TX4927_PCIC_PCISTATUS_ALL << 16),
+ &pcicptr->pcistatus);
+ __raw_writel(TX4927_PCIC_G2PSTATUS_ALL, &pcicptr->g2pstatus);
+ __raw_writel(TX4927_PCIC_PBASTATUS_ALL, &pcicptr->pbastatus);
+ __raw_writel(TX4927_PCIC_PCICSTATUS_ALL, &pcicptr->pcicstatus);
+ return IRQ_HANDLED;
+ }
+ console_verbose();
+ tx4927_dump_pcic_settings1(pcicptr);
+ panic("PCI error.");
+}
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static void __init tx4927_quirk_slc90e66_bridge(struct pci_dev *dev)
+{
+ struct tx4927_pcic_reg __iomem *pcicptr = pci_bus_to_pcicptr(dev->bus);
+
+ if (!pcicptr)
+ return;
+ if (__raw_readl(&pcicptr->pbacfg) & TX4927_PCIC_PBACFG_PBAEN) {
+ /* Reset Bus Arbiter */
+ __raw_writel(TX4927_PCIC_PBACFG_RPBA, &pcicptr->pbacfg);
+ /*
+ * swap reqBP and reqXP (raise priority of SLC90E66).
+ * SLC90E66(PCI-ISA bridge) is connected to REQ2 on
+ * PCI Backplane board.
+ */
+ __raw_writel(0x72543610, &pcicptr->pbareqport);
+ __raw_writel(0, &pcicptr->pbabm);
+ /* Use Fixed ParkMaster (required by SLC90E66) */
+ __raw_writel(TX4927_PCIC_PBACFG_FIXPA, &pcicptr->pbacfg);
+ /* Enable Bus Arbiter */
+ __raw_writel(TX4927_PCIC_PBACFG_FIXPA |
+ TX4927_PCIC_PBACFG_PBAEN,
+ &pcicptr->pbacfg);
+ printk(KERN_INFO "PCI: Use Fixed Park Master (REQPORT %08x)\n",
+ __raw_readl(&pcicptr->pbareqport));
+ }
+}
+#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0,
+ tx4927_quirk_slc90e66_bridge);
+#endif
diff --git a/arch/mips/pci/ops-vr41xx.c b/arch/mips/pci/ops-vr41xx.c
new file mode 100644
index 00000000..28962a7c
--- /dev/null
+++ b/arch/mips/pci/ops-vr41xx.c
@@ -0,0 +1,126 @@
+/*
+ * ops-vr41xx.c, PCI configuration routines for the PCIU of NEC VR4100 series.
+ *
+ * Copyright (C) 2001-2003 MontaVista Software Inc.
+ * Author: Yoichi Yuasa <source@mvista.com>
+ * Copyright (C) 2004-2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * Changes:
+ * MontaVista Software Inc. <source@mvista.com>
+ * - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+
+#define PCICONFDREG (void __iomem *)KSEG1ADDR(0x0f000c14)
+#define PCICONFAREG (void __iomem *)KSEG1ADDR(0x0f000c18)
+
+static inline int set_pci_configuration_address(unsigned char number,
+ unsigned int devfn, int where)
+{
+ if (number == 0) {
+ /*
+ * Type 0 configuration
+ */
+ if (PCI_SLOT(devfn) < 11 || where > 0xff)
+ return -EINVAL;
+
+ writel((1U << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) |
+ (where & 0xfc), PCICONFAREG);
+ } else {
+ /*
+ * Type 1 configuration
+ */
+ if (where > 0xff)
+ return -EINVAL;
+
+ writel(((uint32_t)number << 16) | ((devfn & 0xff) << 8) |
+ (where & 0xfc) | 1U, PCICONFAREG);
+ }
+
+ return 0;
+}
+
+static int pci_config_read(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, uint32_t *val)
+{
+ uint32_t data;
+
+ *val = 0xffffffffU;
+ if (set_pci_configuration_address(bus->number, devfn, where) < 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ data = readl(PCICONFDREG);
+
+ switch (size) {
+ case 1:
+ *val = (data >> ((where & 3) << 3)) & 0xffU;
+ break;
+ case 2:
+ *val = (data >> ((where & 2) << 3)) & 0xffffU;
+ break;
+ case 4:
+ *val = data;
+ break;
+ default:
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pci_config_write(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, uint32_t val)
+{
+ uint32_t data;
+ int shift;
+
+ if (set_pci_configuration_address(bus->number, devfn, where) < 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ data = readl(PCICONFDREG);
+
+ switch (size) {
+ case 1:
+ shift = (where & 3) << 3;
+ data &= ~(0xffU << shift);
+ data |= ((val & 0xffU) << shift);
+ break;
+ case 2:
+ shift = (where & 2) << 3;
+ data &= ~(0xffffU << shift);
+ data |= ((val & 0xffffU) << shift);
+ break;
+ case 4:
+ data = val;
+ break;
+ default:
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ }
+
+ writel(data, PCICONFDREG);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops vr41xx_pci_ops = {
+ .read = pci_config_read,
+ .write = pci_config_write,
+};
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
new file mode 100644
index 00000000..af8c3199
--- /dev/null
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2001,2002,2005 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * BCM1x80/1x55-specific PCI support
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware. We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ *
+ * To access configuration space, we use ioremap. In the 32-bit
+ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
+ * kernel mapped memory. Hopefully neither of these should be a huge
+ * problem.
+ *
+ * XXX: AT THIS TIME, ONLY the NATIVE PCI-X INTERFACE IS SUPPORTED.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/board.h>
+#include <asm/io.h>
+
+/*
+ * Macros for calculating offsets into config space given a device
+ * structure or dev/fun/reg
+ */
+#define CFGOFFSET(bus, devfn, where) (((bus)<<16)+((devfn)<<8)+(where))
+#define CFGADDR(bus, devfn, where) CFGOFFSET((bus)->number, (devfn), where)
+
+static void *cfg_space;
+
+#define PCI_BUS_ENABLED 1
+#define PCI_DEVICE_MODE 2
+
+static int bcm1480_bus_status;
+
+#define PCI_BRIDGE_DEVICE 0
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+static inline u32 READCFG32(u32 addr)
+{
+ return *(u32 *)(cfg_space + (addr&~3));
+}
+
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+ *(u32 *)(cfg_space + (addr & ~3)) = data;
+}
+
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (pin == 0)
+ return -1;
+
+ return K_BCM1480_INT_PCI_INTA - 1 + pin;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+/*
+ * Some checks before doing config cycles:
+ * In PCI Device Mode, hide everything on bus 0 except the LDT host
+ * bridge. Otherwise, access is controlled by bridge MasterEn bits.
+ */
+static int bcm1480_pci_can_access(struct pci_bus *bus, int devfn)
+{
+ u32 devno;
+
+ if (!(bcm1480_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
+ return 0;
+
+ if (bus->number == 0) {
+ devno = PCI_SLOT(devfn);
+ if (bcm1480_bus_status & PCI_DEVICE_MODE)
+ return 0;
+ else
+ return 1;
+ } else
+ return 1;
+}
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space. Return all 1's for disallowed accesses
+ * for a kludgy but adequate simulation of master aborts.
+ */
+
+static int bcm1480_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (bcm1480_pci_can_access(bus, devfn))
+ data = READCFG32(CFGADDR(bus, devfn, where));
+ else
+ data = 0xFFFFFFFF;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 cfgaddr = CFGADDR(bus, devfn, where);
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (!bcm1480_pci_can_access(bus, devfn))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = READCFG32(cfgaddr);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ WRITECFG32(cfgaddr, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops bcm1480_pci_ops = {
+ bcm1480_pcibios_read,
+ bcm1480_pcibios_write,
+};
+
+static struct resource bcm1480_mem_resource = {
+ .name = "BCM1480 PCI MEM",
+ .start = A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES,
+ .end = A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES + 0xfffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bcm1480_io_resource = {
+ .name = "BCM1480 PCI I/O",
+ .start = A_BCM1480_PHYS_PCI_IO_MATCH_BYTES,
+ .end = A_BCM1480_PHYS_PCI_IO_MATCH_BYTES + 0x1ffffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller bcm1480_controller = {
+ .pci_ops = &bcm1480_pci_ops,
+ .mem_resource = &bcm1480_mem_resource,
+ .io_resource = &bcm1480_io_resource,
+ .io_offset = A_BCM1480_PHYS_PCI_IO_MATCH_BYTES,
+};
+
+
+static int __init bcm1480_pcibios_init(void)
+{
+ uint32_t cmdreg;
+ uint64_t reg;
+
+ /* CFE will assign PCI resources */
+ pci_probe_only = 1;
+
+ /* Avoid ISA compat ranges. */
+ PCIBIOS_MIN_IO = 0x00008000UL;
+ PCIBIOS_MIN_MEM = 0x01000000UL;
+
+ /* Set I/O resource limits. - unlimited for now to accommodate HT */
+ ioport_resource.end = 0xffffffffUL;
+ iomem_resource.end = 0xffffffffUL;
+
+ cfg_space = ioremap(A_BCM1480_PHYS_PCI_CFG_MATCH_BITS, 16*1024*1024);
+
+ /*
+ * See if the PCI bus has been configured by the firmware.
+ */
+ reg = __raw_readq(IOADDR(A_SCD_SYSTEM_CFG));
+ if (!(reg & M_BCM1480_SYS_PCI_HOST)) {
+ bcm1480_bus_status |= PCI_DEVICE_MODE;
+ } else {
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
+ PCI_COMMAND));
+ if (!(cmdreg & PCI_COMMAND_MASTER)) {
+ printk
+ ("PCI: Skipping PCI probe. Bus is not initialized.\n");
+ iounmap(cfg_space);
+ return 1; /* XXX */
+ }
+ bcm1480_bus_status |= PCI_BUS_ENABLED;
+ }
+
+ /* turn on ExpMemEn */
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
+ WRITECFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40),
+ cmdreg | 0x10);
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40));
+
+ /*
+ * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
+ * space. Use "match bytes" policy to make everything look
+ * little-endian. So, you need to also set
+ * CONFIG_SWAP_IO_SPACE, but this is the combination that
+ * works correctly with most of Linux's drivers.
+ * XXX ehs: Should this happen in PCI Device mode?
+ */
+
+ bcm1480_controller.io_map_base = (unsigned long)
+ ioremap(A_BCM1480_PHYS_PCI_IO_MATCH_BYTES, 65536);
+ bcm1480_controller.io_map_base -= bcm1480_controller.io_offset;
+ set_io_port_base(bcm1480_controller.io_map_base);
+
+ register_pci_controller(&bcm1480_controller);
+
+#ifdef CONFIG_VGA_CONSOLE
+ take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1);
+#endif
+ return 0;
+}
+
+arch_initcall(bcm1480_pcibios_init);
diff --git a/arch/mips/pci/pci-bcm1480ht.c b/arch/mips/pci/pci-bcm1480ht.c
new file mode 100644
index 00000000..50cc6e9e
--- /dev/null
+++ b/arch/mips/pci/pci-bcm1480ht.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2001,2002,2005 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * BCM1480/1455-specific HT support (looking like PCI)
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware. We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ *
+ * To access configuration space, we use ioremap. In the 32-bit
+ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
+ * kernel mapped memory. Hopefully neither of these should be a huge
+ * problem.
+ *
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/board.h>
+#include <asm/io.h>
+
+/*
+ * Macros for calculating offsets into config space given a device
+ * structure or dev/fun/reg
+ */
+#define CFGOFFSET(bus, devfn, where) (((bus)<<16)+((devfn)<<8)+(where))
+#define CFGADDR(bus, devfn, where) CFGOFFSET((bus)->number, (devfn), where)
+
+static void *ht_cfg_space;
+
+#define PCI_BUS_ENABLED 1
+#define PCI_DEVICE_MODE 2
+
+static int bcm1480ht_bus_status;
+
+#define PCI_BRIDGE_DEVICE 0
+#define HT_BRIDGE_DEVICE 1
+
+/*
+ * HT's level-sensitive interrupts require EOI, which is generated
+ * through a 4MB memory-mapped region
+ */
+unsigned long ht_eoi_space;
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+static inline u32 READCFG32(u32 addr)
+{
+ return *(u32 *)(ht_cfg_space + (addr&~3));
+}
+
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+ *(u32 *)(ht_cfg_space + (addr & ~3)) = data;
+}
+
+/*
+ * Some checks before doing config cycles:
+ * In PCI Device Mode, hide everything on bus 0 except the LDT host
+ * bridge. Otherwise, access is controlled by bridge MasterEn bits.
+ */
+static int bcm1480ht_can_access(struct pci_bus *bus, int devfn)
+{
+ u32 devno;
+
+ if (!(bcm1480ht_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
+ return 0;
+
+ if (bus->number == 0) {
+ devno = PCI_SLOT(devfn);
+ if (bcm1480ht_bus_status & PCI_DEVICE_MODE)
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space. Return all 1's for disallowed accesses
+ * for a kludgy but adequate simulation of master aborts.
+ */
+
+static int bcm1480ht_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (bcm1480ht_can_access(bus, devfn))
+ data = READCFG32(CFGADDR(bus, devfn, where));
+ else
+ data = 0xFFFFFFFF;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480ht_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 cfgaddr = CFGADDR(bus, devfn, where);
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (!bcm1480ht_can_access(bus, devfn))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = READCFG32(cfgaddr);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ WRITECFG32(cfgaddr, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm1480ht_pcibios_get_busno(void)
+{
+ return 0;
+}
+
+struct pci_ops bcm1480ht_pci_ops = {
+ .read = bcm1480ht_pcibios_read,
+ .write = bcm1480ht_pcibios_write,
+};
+
+static struct resource bcm1480ht_mem_resource = {
+ .name = "BCM1480 HT MEM",
+ .start = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES,
+ .end = A_BCM1480_PHYS_HT_MEM_MATCH_BYTES + 0x1fffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bcm1480ht_io_resource = {
+ .name = "BCM1480 HT I/O",
+ .start = A_BCM1480_PHYS_HT_IO_MATCH_BYTES,
+ .end = A_BCM1480_PHYS_HT_IO_MATCH_BYTES + 0x01ffffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller bcm1480ht_controller = {
+ .pci_ops = &bcm1480ht_pci_ops,
+ .mem_resource = &bcm1480ht_mem_resource,
+ .io_resource = &bcm1480ht_io_resource,
+ .index = 1,
+ .get_busno = bcm1480ht_pcibios_get_busno,
+ .io_offset = A_BCM1480_PHYS_HT_IO_MATCH_BYTES,
+};
+
+static int __init bcm1480ht_pcibios_init(void)
+{
+ ht_cfg_space = ioremap(A_BCM1480_PHYS_HT_CFG_MATCH_BITS, 16*1024*1024);
+
+ /* CFE doesn't always init all HT paths, so we always scan */
+ bcm1480ht_bus_status |= PCI_BUS_ENABLED;
+
+ ht_eoi_space = (unsigned long)
+ ioremap(A_BCM1480_PHYS_HT_SPECIAL_MATCH_BYTES,
+ 4 * 1024 * 1024);
+ bcm1480ht_controller.io_map_base = (unsigned long)
+ ioremap(A_BCM1480_PHYS_HT_IO_MATCH_BYTES, 65536);
+ bcm1480ht_controller.io_map_base -= bcm1480ht_controller.io_offset;
+
+ register_pci_controller(&bcm1480ht_controller);
+
+ return 0;
+}
+
+arch_initcall(bcm1480ht_pcibios_init);
diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c
new file mode 100644
index 00000000..455f8e50
--- /dev/null
+++ b/arch/mips/pci/pci-bcm47xx.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Aurelien Jarno <aurelien@aurel32.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ssb/ssb.h>
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return 0;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ int res;
+ u8 slot, pin;
+
+ res = ssb_pcibios_plat_dev_init(dev);
+ if (res < 0) {
+ printk(KERN_ALERT "PCI: Failed to init device %s\n",
+ pci_name(dev));
+ return res;
+ }
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+ slot = PCI_SLOT(dev->devfn);
+ res = ssb_pcibios_map_irq(dev, slot, pin);
+
+ /* IRQ-0 and IRQ-1 are software interrupts. */
+ if (res < 2) {
+ printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n",
+ pci_name(dev));
+ return res;
+ }
+
+ dev->irq = res;
+ return 0;
+}
diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c
new file mode 100644
index 00000000..82e0fde1
--- /dev/null
+++ b/arch/mips/pci/pci-bcm63xx.c
@@ -0,0 +1,224 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+
+#include "pci-bcm63xx.h"
+
+/*
+ * Allow PCI to be disabled at runtime depending on board nvram
+ * configuration
+ */
+int bcm63xx_pci_enabled;
+
+static struct resource bcm_pci_mem_resource = {
+ .name = "bcm63xx PCI memory space",
+ .start = BCM_PCI_MEM_BASE_PA,
+ .end = BCM_PCI_MEM_END_PA,
+ .flags = IORESOURCE_MEM
+};
+
+static struct resource bcm_pci_io_resource = {
+ .name = "bcm63xx PCI IO space",
+ .start = BCM_PCI_IO_BASE_PA,
+#ifdef CONFIG_CARDBUS
+ .end = BCM_PCI_IO_HALF_PA,
+#else
+ .end = BCM_PCI_IO_END_PA,
+#endif
+ .flags = IORESOURCE_IO
+};
+
+struct pci_controller bcm63xx_controller = {
+ .pci_ops = &bcm63xx_pci_ops,
+ .io_resource = &bcm_pci_io_resource,
+ .mem_resource = &bcm_pci_mem_resource,
+};
+
+/*
+ * We handle cardbus via a fake Cardbus bridge, memory and io spaces
+ * have to be clearly separated from PCI one since we have different
+ * memory decoder.
+ */
+#ifdef CONFIG_CARDBUS
+static struct resource bcm_cb_mem_resource = {
+ .name = "bcm63xx Cardbus memory space",
+ .start = BCM_CB_MEM_BASE_PA,
+ .end = BCM_CB_MEM_END_PA,
+ .flags = IORESOURCE_MEM
+};
+
+static struct resource bcm_cb_io_resource = {
+ .name = "bcm63xx Cardbus IO space",
+ .start = BCM_PCI_IO_HALF_PA + 1,
+ .end = BCM_PCI_IO_END_PA,
+ .flags = IORESOURCE_IO
+};
+
+struct pci_controller bcm63xx_cb_controller = {
+ .pci_ops = &bcm63xx_cb_ops,
+ .io_resource = &bcm_cb_io_resource,
+ .mem_resource = &bcm_cb_mem_resource,
+};
+#endif
+
+static u32 bcm63xx_int_cfg_readl(u32 reg)
+{
+ u32 tmp;
+
+ tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK;
+ tmp |= MPI_PCICFGCTL_WRITEEN_MASK;
+ bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG);
+ iob();
+ return bcm_mpi_readl(MPI_PCICFGDATA_REG);
+}
+
+static void bcm63xx_int_cfg_writel(u32 val, u32 reg)
+{
+ u32 tmp;
+
+ tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK;
+ tmp |= MPI_PCICFGCTL_WRITEEN_MASK;
+ bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG);
+ bcm_mpi_writel(val, MPI_PCICFGDATA_REG);
+}
+
+void __iomem *pci_iospace_start;
+
+static int __init bcm63xx_pci_init(void)
+{
+ unsigned int mem_size;
+ u32 val;
+
+ if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
+ return -ENODEV;
+
+ if (!bcm63xx_pci_enabled)
+ return -ENODEV;
+
+ /*
+ * configuration access are done through IO space, remap 4
+ * first bytes to access it from CPU.
+ *
+ * this means that no io access from CPU should happen while
+ * we do a configuration cycle, but there's no way we can add
+ * a spinlock for each io access, so this is currently kind of
+ * broken on SMP.
+ */
+ pci_iospace_start = ioremap_nocache(BCM_PCI_IO_BASE_PA, 4);
+ if (!pci_iospace_start)
+ return -ENOMEM;
+
+ /* setup local bus to PCI access (PCI memory) */
+ val = BCM_PCI_MEM_BASE_PA & MPI_L2P_BASE_MASK;
+ bcm_mpi_writel(val, MPI_L2PMEMBASE1_REG);
+ bcm_mpi_writel(~(BCM_PCI_MEM_SIZE - 1), MPI_L2PMEMRANGE1_REG);
+ bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PMEMREMAP1_REG);
+
+ /* set Cardbus IDSEL (type 0 cfg access on primary bus for
+ * this IDSEL will be done on Cardbus instead) */
+ val = bcm_pcmcia_readl(PCMCIA_C1_REG);
+ val &= ~PCMCIA_C1_CBIDSEL_MASK;
+ val |= (CARDBUS_PCI_IDSEL << PCMCIA_C1_CBIDSEL_SHIFT);
+ bcm_pcmcia_writel(val, PCMCIA_C1_REG);
+
+#ifdef CONFIG_CARDBUS
+ /* setup local bus to PCI access (Cardbus memory) */
+ val = BCM_CB_MEM_BASE_PA & MPI_L2P_BASE_MASK;
+ bcm_mpi_writel(val, MPI_L2PMEMBASE2_REG);
+ bcm_mpi_writel(~(BCM_CB_MEM_SIZE - 1), MPI_L2PMEMRANGE2_REG);
+ val |= MPI_L2PREMAP_ENABLED_MASK | MPI_L2PREMAP_IS_CARDBUS_MASK;
+ bcm_mpi_writel(val, MPI_L2PMEMREMAP2_REG);
+#else
+ /* disable second access windows */
+ bcm_mpi_writel(0, MPI_L2PMEMREMAP2_REG);
+#endif
+
+ /* setup local bus to PCI access (IO memory), we have only 1
+ * IO window for both PCI and cardbus, but it cannot handle
+ * both at the same time, assume standard PCI for now, if
+ * cardbus card has IO zone, PCI fixup will change window to
+ * cardbus */
+ val = BCM_PCI_IO_BASE_PA & MPI_L2P_BASE_MASK;
+ bcm_mpi_writel(val, MPI_L2PIOBASE_REG);
+ bcm_mpi_writel(~(BCM_PCI_IO_SIZE - 1), MPI_L2PIORANGE_REG);
+ bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PIOREMAP_REG);
+
+ /* enable PCI related GPIO pins */
+ bcm_mpi_writel(MPI_LOCBUSCTL_EN_PCI_GPIO_MASK, MPI_LOCBUSCTL_REG);
+
+ /* setup PCI to local bus access, used by PCI device to target
+ * local RAM while bus mastering */
+ bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3);
+ if (BCMCPU_IS_6358())
+ val = MPI_SP0_REMAP_ENABLE_MASK;
+ else
+ val = 0;
+ bcm_mpi_writel(val, MPI_SP0_REMAP_REG);
+
+ bcm63xx_int_cfg_writel(0x0, PCI_BASE_ADDRESS_4);
+ bcm_mpi_writel(0, MPI_SP1_REMAP_REG);
+
+ mem_size = bcm63xx_get_memory_size();
+
+ /* 6348 before rev b0 exposes only 16 MB of RAM memory through
+ * PCI, throw a warning if we have more memory */
+ if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() & 0xf0) == 0xa0) {
+ if (mem_size > (16 * 1024 * 1024))
+ printk(KERN_WARNING "bcm63xx: this CPU "
+ "revision cannot handle more than 16MB "
+ "of RAM for PCI bus mastering\n");
+ } else {
+ /* setup sp0 range to local RAM size */
+ bcm_mpi_writel(~(mem_size - 1), MPI_SP0_RANGE_REG);
+ bcm_mpi_writel(0, MPI_SP1_RANGE_REG);
+ }
+
+ /* change host bridge retry counter to infinite number of
+ * retry, needed for some broadcom wifi cards with Silicon
+ * Backplane bus where access to srom seems very slow */
+ val = bcm63xx_int_cfg_readl(BCMPCI_REG_TIMERS);
+ val &= ~REG_TIMER_RETRY_MASK;
+ bcm63xx_int_cfg_writel(val, BCMPCI_REG_TIMERS);
+
+ /* enable memory decoder and bus mastering */
+ val = bcm63xx_int_cfg_readl(PCI_COMMAND);
+ val |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ bcm63xx_int_cfg_writel(val, PCI_COMMAND);
+
+ /* enable read prefetching & disable byte swapping for bus
+ * mastering transfers */
+ val = bcm_mpi_readl(MPI_PCIMODESEL_REG);
+ val &= ~MPI_PCIMODESEL_BAR1_NOSWAP_MASK;
+ val &= ~MPI_PCIMODESEL_BAR2_NOSWAP_MASK;
+ val &= ~MPI_PCIMODESEL_PREFETCH_MASK;
+ val |= (8 << MPI_PCIMODESEL_PREFETCH_SHIFT);
+ bcm_mpi_writel(val, MPI_PCIMODESEL_REG);
+
+ /* enable pci interrupt */
+ val = bcm_mpi_readl(MPI_LOCINT_REG);
+ val |= MPI_LOCINT_MASK(MPI_LOCINT_EXT_PCI_INT);
+ bcm_mpi_writel(val, MPI_LOCINT_REG);
+
+ register_pci_controller(&bcm63xx_controller);
+
+#ifdef CONFIG_CARDBUS
+ register_pci_controller(&bcm63xx_cb_controller);
+#endif
+
+ /* mark memory space used for IO mapping as reserved */
+ request_mem_region(BCM_PCI_IO_BASE_PA, BCM_PCI_IO_SIZE,
+ "bcm63xx PCI IO space");
+ return 0;
+}
+
+arch_initcall(bcm63xx_pci_init);
diff --git a/arch/mips/pci/pci-bcm63xx.h b/arch/mips/pci/pci-bcm63xx.h
new file mode 100644
index 00000000..a6e594ef
--- /dev/null
+++ b/arch/mips/pci/pci-bcm63xx.h
@@ -0,0 +1,27 @@
+#ifndef PCI_BCM63XX_H_
+#define PCI_BCM63XX_H_
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_dev_pci.h>
+
+/*
+ * Cardbus shares the PCI bus, but has no IDSEL, so a special id is
+ * reserved for it. If you have a standard PCI device at this id, you
+ * need to change the following definition.
+ */
+#define CARDBUS_PCI_IDSEL 0x8
+
+/*
+ * defined in ops-bcm63xx.c
+ */
+extern struct pci_ops bcm63xx_pci_ops;
+extern struct pci_ops bcm63xx_cb_ops;
+
+/*
+ * defined in pci-bcm63xx.c
+ */
+extern void __iomem *pci_iospace_start;
+
+#endif /* ! PCI_BCM63XX_H_ */
diff --git a/arch/mips/pci/pci-emma2rh.c b/arch/mips/pci/pci-emma2rh.c
new file mode 100644
index 00000000..773e34ff
--- /dev/null
+++ b/arch/mips/pci/pci-emma2rh.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) NEC Electronics Corporation 2004-2006
+ *
+ * This file is based on the arch/mips/ddb5xxx/ddb5477/pci.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/bootinfo.h>
+
+#include <asm/emma/emma2rh.h>
+
+static struct resource pci_io_resource = {
+ .name = "pci IO space",
+ .start = EMMA2RH_PCI_IO_BASE,
+ .end = EMMA2RH_PCI_IO_BASE + EMMA2RH_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource pci_mem_resource = {
+ .name = "pci memory space",
+ .start = EMMA2RH_PCI_MEM_BASE,
+ .end = EMMA2RH_PCI_MEM_BASE + EMMA2RH_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+extern struct pci_ops emma2rh_pci_ops;
+
+static struct pci_controller emma2rh_pci_controller = {
+ .pci_ops = &emma2rh_pci_ops,
+ .mem_resource = &pci_mem_resource,
+ .io_resource = &pci_io_resource,
+ .mem_offset = -0x04000000,
+ .io_offset = 0,
+};
+
+static void __init emma2rh_pci_init(void)
+{
+ /* setup PCI interface */
+ emma2rh_out32(EMMA2RH_PCI_ARBIT_CTR, 0x70f);
+
+ emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, 0x80000a18);
+ emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_COMMAND,
+ PCI_STATUS_DEVSEL_MEDIUM | PCI_STATUS_CAP_LIST |
+ PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+ emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_BASE_ADDRESS_0, 0x10000000);
+ emma2rh_out32(EMMA2RH_PCI_CONFIG_BASE + PCI_BASE_ADDRESS_1, 0x00000000);
+
+ emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, 0x12000000 | 0x218);
+ emma2rh_out32(EMMA2RH_PCI_IWIN1_CTR, 0x18000000 | 0x600);
+ emma2rh_out32(EMMA2RH_PCI_INIT_ESWP, 0x00000200);
+
+ emma2rh_out32(EMMA2RH_PCI_TWIN_CTR, 0x00009200);
+ emma2rh_out32(EMMA2RH_PCI_TWIN_BADR, 0x00000000);
+ emma2rh_out32(EMMA2RH_PCI_TWIN0_DADR, 0x00000000);
+ emma2rh_out32(EMMA2RH_PCI_TWIN1_DADR, 0x00000000);
+}
+
+static int __init emma2rh_pci_setup(void)
+{
+ emma2rh_pci_init();
+ register_pci_controller(&emma2rh_pci_controller);
+ return 0;
+}
+
+arch_initcall(emma2rh_pci_setup);
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
new file mode 100644
index 00000000..a0e726eb
--- /dev/null
+++ b/arch/mips/pci/pci-ip27.c
@@ -0,0 +1,228 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Christoph Hellwig (hch@lst.de)
+ * Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/smp.h>
+#include <asm/sn/arch.h>
+#include <asm/pci/bridge.h>
+#include <asm/paccess.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/sn0/hub.h>
+
+/*
+ * Max #PCI busses we can handle; ie, max #PCI bridges.
+ */
+#define MAX_PCI_BUSSES 40
+
+/*
+ * Max #PCI devices (like scsi controllers) we handle on a bus.
+ */
+#define MAX_DEVICES_PER_PCIBUS 8
+
+/*
+ * XXX: No kmalloc available when we do our crosstalk scan,
+ * we should try to move it later in the boot process.
+ */
+static struct bridge_controller bridges[MAX_PCI_BUSSES];
+
+/*
+ * Translate from irq to software PCI bus number and PCI slot.
+ */
+struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
+int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
+
+extern struct pci_ops bridge_pci_ops;
+
+int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid)
+{
+ unsigned long offset = NODE_OFFSET(nasid);
+ struct bridge_controller *bc;
+ static int num_bridges = 0;
+ bridge_t *bridge;
+ int slot;
+
+ pci_probe_only = 1;
+
+ printk("a bridge\n");
+
+ /* XXX: kludge alert.. */
+ if (!num_bridges)
+ ioport_resource.end = ~0UL;
+
+ bc = &bridges[num_bridges];
+
+ bc->pc.pci_ops = &bridge_pci_ops;
+ bc->pc.mem_resource = &bc->mem;
+ bc->pc.io_resource = &bc->io;
+
+ bc->pc.index = num_bridges;
+
+ bc->mem.name = "Bridge PCI MEM";
+ bc->pc.mem_offset = offset;
+ bc->mem.start = 0;
+ bc->mem.end = ~0UL;
+ bc->mem.flags = IORESOURCE_MEM;
+
+ bc->io.name = "Bridge IO MEM";
+ bc->pc.io_offset = offset;
+ bc->io.start = 0UL;
+ bc->io.end = ~0UL;
+ bc->io.flags = IORESOURCE_IO;
+
+ bc->irq_cpu = smp_processor_id();
+ bc->widget_id = widget_id;
+ bc->nasid = nasid;
+
+ bc->baddr = (u64)masterwid << 60 | PCI64_ATTR_BAR;
+
+ /*
+ * point to this bridge
+ */
+ bridge = (bridge_t *) RAW_NODE_SWIN_BASE(nasid, widget_id);
+
+ /*
+ * Clear all pending interrupts.
+ */
+ bridge->b_int_rst_stat = BRIDGE_IRR_ALL_CLR;
+
+ /*
+ * Until otherwise set up, assume all interrupts are from slot 0
+ */
+ bridge->b_int_device = 0x0;
+
+ /*
+ * swap pio's to pci mem and io space (big windows)
+ */
+ bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP |
+ BRIDGE_CTRL_MEM_SWAP;
+#ifdef CONFIG_PAGE_SIZE_4KB
+ bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE;
+#else /* 16kB or larger */
+ bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE;
+#endif
+
+ /*
+ * Hmm... IRIX sets additional bits in the address which
+ * are documented as reserved in the bridge docs.
+ */
+ bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
+ bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/
+ bridge->b_dir_map = (masterwid << 20); /* DMA */
+ bridge->b_int_enable = 0;
+
+ for (slot = 0; slot < 8; slot ++) {
+ bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
+ bc->pci_int[slot] = -1;
+ }
+ bridge->b_wid_tflush; /* wait until Bridge PIO complete */
+
+ bc->base = bridge;
+
+ register_pci_controller(&bc->pc);
+
+ num_bridges++;
+
+ return 0;
+}
+
+/*
+ * All observed requests have pin == 1. We could have a global here, that
+ * gets incremented and returned every time - unfortunately, pci_map_irq
+ * may be called on the same device over and over, and need to return the
+ * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7].
+ *
+ * A given PCI device, in general, should be able to intr any of the cpus
+ * on any one of the hubs connected to its xbow.
+ */
+int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return 0;
+}
+
+static inline struct pci_dev *bridge_root_dev(struct pci_dev *dev)
+{
+ while (dev->bus->parent) {
+ /* Move up the chain of bridges. */
+ dev = dev->bus->self;
+ }
+
+ return dev;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
+ struct pci_dev *rdev = bridge_root_dev(dev);
+ int slot = PCI_SLOT(rdev->devfn);
+ int irq;
+
+ irq = bc->pci_int[slot];
+ if (irq == -1) {
+ irq = request_bridge_irq(bc);
+ if (irq < 0)
+ return irq;
+
+ bc->pci_int[slot] = irq;
+ }
+
+ irq_to_bridge[irq] = bc;
+ irq_to_slot[irq] = slot;
+
+ dev->irq = irq;
+
+ return 0;
+}
+
+/*
+ * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses
+ * to find the slot number in sense of the bridge device register.
+ * XXX This also means multiple devices might rely on conflicting bridge
+ * settings.
+ */
+
+static inline void pci_disable_swapping(struct pci_dev *dev)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
+ bridge_t *bridge = bc->base;
+ int slot = PCI_SLOT(dev->devfn);
+
+ /* Turn off byte swapping */
+ bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
+ bridge->b_widget.w_tflush; /* Flush */
+}
+
+static inline void pci_enable_swapping(struct pci_dev *dev)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
+ bridge_t *bridge = bc->base;
+ int slot = PCI_SLOT(dev->devfn);
+
+ /* Turn on byte swapping */
+ bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR;
+ bridge->b_widget.w_tflush; /* Flush */
+}
+
+static void __init pci_fixup_ioc3(struct pci_dev *d)
+{
+ pci_disable_swapping(d);
+}
+
+int pcibus_to_node(struct pci_bus *bus)
+{
+ struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
+
+ return bc->nasid;
+}
+EXPORT_SYMBOL(pcibus_to_node);
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+ pci_fixup_ioc3);
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
new file mode 100644
index 00000000..532b561b
--- /dev/null
+++ b/arch/mips/pci/pci-ip32.c
@@ -0,0 +1,148 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 2001 Keith M Wesolowski
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+#undef DEBUG_MACE_PCI
+
+/*
+ * Handle errors from the bridge. This includes master and target aborts,
+ * various command and address errors, and the interrupt test. This gets
+ * registered on the bridge error irq. It's conceivable that some of these
+ * conditions warrant a panic. Anybody care to say which ones?
+ */
+static irqreturn_t macepci_error(int irq, void *dev)
+{
+ char s;
+ unsigned int flags = mace->pci.error;
+ unsigned int addr = mace->pci.error_addr;
+
+ if (flags & MACEPCI_ERROR_MEMORY_ADDR)
+ s = 'M';
+ else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
+ s = 'C';
+ else
+ s = 'X';
+
+ if (flags & MACEPCI_ERROR_MASTER_ABORT) {
+ printk("MACEPCI: Master abort at 0x%08x (%c)\n", addr, s);
+ flags &= ~MACEPCI_ERROR_MASTER_ABORT;
+ }
+ if (flags & MACEPCI_ERROR_TARGET_ABORT) {
+ printk("MACEPCI: Target abort at 0x%08x (%c)\n", addr, s);
+ flags &= ~MACEPCI_ERROR_TARGET_ABORT;
+ }
+ if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
+ printk("MACEPCI: Data parity error at 0x%08x (%c)\n", addr, s);
+ flags &= ~MACEPCI_ERROR_DATA_PARITY_ERR;
+ }
+ if (flags & MACEPCI_ERROR_RETRY_ERR) {
+ printk("MACEPCI: Retry error at 0x%08x (%c)\n", addr, s);
+ flags &= ~MACEPCI_ERROR_RETRY_ERR;
+ }
+ if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
+ printk("MACEPCI: Illegal command at 0x%08x (%c)\n", addr, s);
+ flags &= ~MACEPCI_ERROR_ILLEGAL_CMD;
+ }
+ if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
+ printk("MACEPCI: System error at 0x%08x (%c)\n", addr, s);
+ flags &= ~MACEPCI_ERROR_SYSTEM_ERR;
+ }
+ if (flags & MACEPCI_ERROR_PARITY_ERR) {
+ printk("MACEPCI: Parity error at 0x%08x (%c)\n", addr, s);
+ flags &= ~MACEPCI_ERROR_PARITY_ERR;
+ }
+ if (flags & MACEPCI_ERROR_OVERRUN) {
+ printk("MACEPCI: Overrun error at 0x%08x (%c)\n", addr, s);
+ flags &= ~MACEPCI_ERROR_OVERRUN;
+ }
+ if (flags & MACEPCI_ERROR_SIG_TABORT) {
+ printk("MACEPCI: Signaled target abort (clearing)\n");
+ flags &= ~MACEPCI_ERROR_SIG_TABORT;
+ }
+ if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
+ printk("MACEPCI: Interrupt test triggered (clearing)\n");
+ flags &= ~MACEPCI_ERROR_INTERRUPT_TEST;
+ }
+
+ mace->pci.error = flags;
+
+ return IRQ_HANDLED;
+}
+
+
+extern struct pci_ops mace_pci_ops;
+#ifdef CONFIG_64BIT
+static struct resource mace_pci_mem_resource = {
+ .name = "SGI O2 PCI MEM",
+ .start = MACEPCI_HI_MEMORY,
+ .end = 0x2FFFFFFFFUL,
+ .flags = IORESOURCE_MEM,
+};
+static struct resource mace_pci_io_resource = {
+ .name = "SGI O2 PCI IO",
+ .start = 0x00000000UL,
+ .end = 0xffffffffUL,
+ .flags = IORESOURCE_IO,
+};
+#define MACE_PCI_MEM_OFFSET 0x200000000
+#else
+static struct resource mace_pci_mem_resource = {
+ .name = "SGI O2 PCI MEM",
+ .start = MACEPCI_LOW_MEMORY,
+ .end = MACEPCI_LOW_MEMORY + 0x2000000 - 1,
+ .flags = IORESOURCE_MEM,
+};
+static struct resource mace_pci_io_resource = {
+ .name = "SGI O2 PCI IO",
+ .start = 0x00000000,
+ .end = 0xFFFFFFFF,
+ .flags = IORESOURCE_IO,
+};
+#define MACE_PCI_MEM_OFFSET (MACEPCI_LOW_MEMORY - 0x80000000)
+#endif
+static struct pci_controller mace_pci_controller = {
+ .pci_ops = &mace_pci_ops,
+ .mem_resource = &mace_pci_mem_resource,
+ .io_resource = &mace_pci_io_resource,
+ .iommu = 0,
+ .mem_offset = MACE_PCI_MEM_OFFSET,
+ .io_offset = 0,
+ .io_map_base = CKSEG1ADDR(MACEPCI_LOW_IO),
+};
+
+static int __init mace_init(void)
+{
+ PCIBIOS_MIN_IO = 0x1000;
+
+ /* Clear any outstanding errors and enable interrupts */
+ mace->pci.error_addr = 0;
+ mace->pci.error = 0;
+ mace->pci.control = 0xff008500;
+
+ printk("MACE PCI rev %d\n", mace->pci.rev);
+
+ BUG_ON(request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
+ "MACE PCI error", NULL));
+
+ /* extend memory resources */
+ iomem_resource.end = mace_pci_mem_resource.end;
+ ioport_resource = mace_pci_io_resource;
+
+ register_pci_controller(&mace_pci_controller);
+
+ return 0;
+}
+
+arch_initcall(mace_init);
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c
new file mode 100644
index 00000000..603d7493
--- /dev/null
+++ b/arch/mips/pci/pci-lantiq.c
@@ -0,0 +1,297 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/platform_device.h>
+
+#include <asm/pci.h>
+#include <asm/gpio.h>
+#include <asm/addrspace.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_irq.h>
+#include <lantiq_platform.h>
+
+#include "pci-lantiq.h"
+
+#define LTQ_PCI_CFG_BASE 0x17000000
+#define LTQ_PCI_CFG_SIZE 0x00008000
+#define LTQ_PCI_MEM_BASE 0x18000000
+#define LTQ_PCI_MEM_SIZE 0x02000000
+#define LTQ_PCI_IO_BASE 0x1AE00000
+#define LTQ_PCI_IO_SIZE 0x00200000
+
+#define PCI_CR_FCI_ADDR_MAP0 0x00C0
+#define PCI_CR_FCI_ADDR_MAP1 0x00C4
+#define PCI_CR_FCI_ADDR_MAP2 0x00C8
+#define PCI_CR_FCI_ADDR_MAP3 0x00CC
+#define PCI_CR_FCI_ADDR_MAP4 0x00D0
+#define PCI_CR_FCI_ADDR_MAP5 0x00D4
+#define PCI_CR_FCI_ADDR_MAP6 0x00D8
+#define PCI_CR_FCI_ADDR_MAP7 0x00DC
+#define PCI_CR_CLK_CTRL 0x0000
+#define PCI_CR_PCI_MOD 0x0030
+#define PCI_CR_PC_ARB 0x0080
+#define PCI_CR_FCI_ADDR_MAP11hg 0x00E4
+#define PCI_CR_BAR11MASK 0x0044
+#define PCI_CR_BAR12MASK 0x0048
+#define PCI_CR_BAR13MASK 0x004C
+#define PCI_CS_BASE_ADDR1 0x0010
+#define PCI_CR_PCI_ADDR_MAP11 0x0064
+#define PCI_CR_FCI_BURST_LENGTH 0x00E8
+#define PCI_CR_PCI_EOI 0x002C
+#define PCI_CS_STS_CMD 0x0004
+
+#define PCI_MASTER0_REQ_MASK_2BITS 8
+#define PCI_MASTER1_REQ_MASK_2BITS 10
+#define PCI_MASTER2_REQ_MASK_2BITS 12
+#define INTERNAL_ARB_ENABLE_BIT 0
+
+#define LTQ_CGU_IFCCR 0x0018
+#define LTQ_CGU_PCICR 0x0034
+
+#define ltq_pci_w32(x, y) ltq_w32((x), ltq_pci_membase + (y))
+#define ltq_pci_r32(x) ltq_r32(ltq_pci_membase + (x))
+
+#define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y))
+#define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x))
+
+struct ltq_pci_gpio_map {
+ int pin;
+ int alt0;
+ int alt1;
+ int dir;
+ char *name;
+};
+
+/* the pci core can make use of the following gpios */
+static struct ltq_pci_gpio_map ltq_pci_gpio_map[] = {
+ { 0, 1, 0, 0, "pci-exin0" },
+ { 1, 1, 0, 0, "pci-exin1" },
+ { 2, 1, 0, 0, "pci-exin2" },
+ { 39, 1, 0, 0, "pci-exin3" },
+ { 10, 1, 0, 0, "pci-exin4" },
+ { 9, 1, 0, 0, "pci-exin5" },
+ { 30, 1, 0, 1, "pci-gnt1" },
+ { 23, 1, 0, 1, "pci-gnt2" },
+ { 19, 1, 0, 1, "pci-gnt3" },
+ { 38, 1, 0, 1, "pci-gnt4" },
+ { 29, 1, 0, 0, "pci-req1" },
+ { 31, 1, 0, 0, "pci-req2" },
+ { 3, 1, 0, 0, "pci-req3" },
+ { 37, 1, 0, 0, "pci-req4" },
+};
+
+__iomem void *ltq_pci_mapped_cfg;
+static __iomem void *ltq_pci_membase;
+
+int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL;
+
+/* Since the PCI REQ pins can be reused for other functionality, make it
+ possible to exclude those from interpretation by the PCI controller */
+static int ltq_pci_req_mask = 0xf;
+
+static int *ltq_pci_irq_map;
+
+struct pci_ops ltq_pci_ops = {
+ .read = ltq_pci_read_config_dword,
+ .write = ltq_pci_write_config_dword
+};
+
+static struct resource pci_io_resource = {
+ .name = "pci io space",
+ .start = LTQ_PCI_IO_BASE,
+ .end = LTQ_PCI_IO_BASE + LTQ_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+ .name = "pci memory space",
+ .start = LTQ_PCI_MEM_BASE,
+ .end = LTQ_PCI_MEM_BASE + LTQ_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM
+};
+
+static struct pci_controller ltq_pci_controller = {
+ .pci_ops = &ltq_pci_ops,
+ .mem_resource = &pci_mem_resource,
+ .mem_offset = 0x00000000UL,
+ .io_resource = &pci_io_resource,
+ .io_offset = 0x00000000UL,
+};
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ if (ltqpci_plat_dev_init)
+ return ltqpci_plat_dev_init(dev);
+
+ return 0;
+}
+
+static u32 ltq_calc_bar11mask(void)
+{
+ u32 mem, bar11mask;
+
+ /* BAR11MASK value depends on available memory on system. */
+ mem = num_physpages * PAGE_SIZE;
+ bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8;
+
+ return bar11mask;
+}
+
+static void ltq_pci_setup_gpio(int gpio)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) {
+ if (gpio & (1 << i)) {
+ ltq_gpio_request(ltq_pci_gpio_map[i].pin,
+ ltq_pci_gpio_map[i].alt0,
+ ltq_pci_gpio_map[i].alt1,
+ ltq_pci_gpio_map[i].dir,
+ ltq_pci_gpio_map[i].name);
+ }
+ }
+ ltq_gpio_request(21, 0, 0, 1, "pci-reset");
+ ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
+}
+
+static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
+{
+ u32 temp_buffer;
+
+ /* set clock to 33Mhz */
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
+
+ /* external or internal clock ? */
+ if (conf->clock) {
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~(1 << 16),
+ LTQ_CGU_IFCCR);
+ ltq_cgu_w32((1 << 30), LTQ_CGU_PCICR);
+ } else {
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | (1 << 16),
+ LTQ_CGU_IFCCR);
+ ltq_cgu_w32((1 << 31) | (1 << 30), LTQ_CGU_PCICR);
+ }
+
+ /* setup pci clock and gpis used by pci */
+ ltq_pci_setup_gpio(conf->gpio);
+
+ /* enable auto-switching between PCI and EBU */
+ ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
+
+ /* busy, i.e. configuration is not done, PCI access has to be retried */
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD);
+ wmb();
+ /* BUS Master/IO/MEM access */
+ ltq_pci_cfg_w32(ltq_pci_cfg_r32(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD);
+
+ /* enable external 2 PCI masters */
+ temp_buffer = ltq_pci_r32(PCI_CR_PC_ARB);
+ temp_buffer &= (~(ltq_pci_req_mask << 16));
+ /* enable internal arbiter */
+ temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
+ /* enable internal PCI master reqest */
+ temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS));
+
+ /* enable EBU request */
+ temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS));
+
+ /* enable all external masters request */
+ temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS));
+ ltq_pci_w32(temp_buffer, PCI_CR_PC_ARB);
+ wmb();
+
+ /* setup BAR memory regions */
+ ltq_pci_w32(0x18000000, PCI_CR_FCI_ADDR_MAP0);
+ ltq_pci_w32(0x18400000, PCI_CR_FCI_ADDR_MAP1);
+ ltq_pci_w32(0x18800000, PCI_CR_FCI_ADDR_MAP2);
+ ltq_pci_w32(0x18c00000, PCI_CR_FCI_ADDR_MAP3);
+ ltq_pci_w32(0x19000000, PCI_CR_FCI_ADDR_MAP4);
+ ltq_pci_w32(0x19400000, PCI_CR_FCI_ADDR_MAP5);
+ ltq_pci_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6);
+ ltq_pci_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
+ ltq_pci_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
+ ltq_pci_w32(ltq_calc_bar11mask(), PCI_CR_BAR11MASK);
+ ltq_pci_w32(0, PCI_CR_PCI_ADDR_MAP11);
+ ltq_pci_w32(0, PCI_CS_BASE_ADDR1);
+ /* both TX and RX endian swap are enabled */
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI);
+ wmb();
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_BAR12MASK) | 0x80000000,
+ PCI_CR_BAR12MASK);
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_BAR13MASK) | 0x80000000,
+ PCI_CR_BAR13MASK);
+ /*use 8 dw burst length */
+ ltq_pci_w32(0x303, PCI_CR_FCI_BURST_LENGTH);
+ ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD);
+ wmb();
+
+ /* setup irq line */
+ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_CON) | 0xc, LTQ_EBU_PCC_CON);
+ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN);
+
+ /* toggle reset pin */
+ __gpio_set_value(21, 0);
+ wmb();
+ mdelay(1);
+ __gpio_set_value(21, 1);
+ return 0;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (ltq_pci_irq_map[slot])
+ return ltq_pci_irq_map[slot];
+ printk(KERN_ERR "lq_pci: trying to map irq for unknown slot %d\n",
+ slot);
+
+ return 0;
+}
+
+static int __devinit ltq_pci_probe(struct platform_device *pdev)
+{
+ struct ltq_pci_data *ltq_pci_data =
+ (struct ltq_pci_data *) pdev->dev.platform_data;
+ pci_probe_only = 0;
+ ltq_pci_irq_map = ltq_pci_data->irq;
+ ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE);
+ ltq_pci_mapped_cfg =
+ ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE);
+ ltq_pci_controller.io_map_base =
+ (unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1);
+ ltq_pci_startup(ltq_pci_data);
+ register_pci_controller(&ltq_pci_controller);
+
+ return 0;
+}
+
+static struct platform_driver
+ltq_pci_driver = {
+ .probe = ltq_pci_probe,
+ .driver = {
+ .name = "ltq_pci",
+ .owner = THIS_MODULE,
+ },
+};
+
+int __init pcibios_init(void)
+{
+ int ret = platform_driver_register(&ltq_pci_driver);
+ if (ret)
+ printk(KERN_INFO "ltq_pci: Error registering platfom driver!");
+ return ret;
+}
+
+arch_initcall(pcibios_init);
diff --git a/arch/mips/pci/pci-lantiq.h b/arch/mips/pci/pci-lantiq.h
new file mode 100644
index 00000000..66bf6cd6
--- /dev/null
+++ b/arch/mips/pci/pci-lantiq.h
@@ -0,0 +1,18 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_PCI_H__
+#define _LTQ_PCI_H__
+
+extern __iomem void *ltq_pci_mapped_cfg;
+extern int ltq_pci_read_config_dword(struct pci_bus *bus,
+ unsigned int devfn, int where, int size, u32 *val);
+extern int ltq_pci_write_config_dword(struct pci_bus *bus,
+ unsigned int devfn, int where, int size, u32 val);
+
+#endif
diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c
new file mode 100644
index 00000000..a98e543a
--- /dev/null
+++ b/arch/mips/pci/pci-lasat.c
@@ -0,0 +1,88 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 2001, 04 Keith M Wesolowski
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include <asm/lasat/lasat.h>
+
+#include <irq.h>
+
+extern struct pci_ops nile4_pci_ops;
+extern struct pci_ops gt64xxx_pci0_ops;
+static struct resource lasat_pci_mem_resource = {
+ .name = "LASAT PCI MEM",
+ .start = 0x18000000,
+ .end = 0x19ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource lasat_pci_io_resource = {
+ .name = "LASAT PCI IO",
+ .start = 0x1a000000,
+ .end = 0x1bffffff,
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller lasat_pci_controller = {
+ .mem_resource = &lasat_pci_mem_resource,
+ .io_resource = &lasat_pci_io_resource,
+};
+
+static int __init lasat_pci_setup(void)
+{
+ printk(KERN_DEBUG "PCI: starting\n");
+
+ if (IS_LASAT_200())
+ lasat_pci_controller.pci_ops = &nile4_pci_ops;
+ else
+ lasat_pci_controller.pci_ops = &gt64xxx_pci0_ops;
+
+ register_pci_controller(&lasat_pci_controller);
+
+ return 0;
+}
+
+arch_initcall(lasat_pci_setup);
+
+#define LASAT_IRQ_ETH1 (LASAT_IRQ_BASE + 0)
+#define LASAT_IRQ_ETH0 (LASAT_IRQ_BASE + 1)
+#define LASAT_IRQ_HDC (LASAT_IRQ_BASE + 2)
+#define LASAT_IRQ_COMP (LASAT_IRQ_BASE + 3)
+#define LASAT_IRQ_HDLC (LASAT_IRQ_BASE + 4)
+#define LASAT_IRQ_PCIA (LASAT_IRQ_BASE + 5)
+#define LASAT_IRQ_PCIB (LASAT_IRQ_BASE + 6)
+#define LASAT_IRQ_PCIC (LASAT_IRQ_BASE + 7)
+#define LASAT_IRQ_PCID (LASAT_IRQ_BASE + 8)
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ switch (slot) {
+ case 1:
+ case 2:
+ case 3:
+ return LASAT_IRQ_PCIA + (((slot-1) + (pin-1)) % 4);
+ case 4:
+ return LASAT_IRQ_ETH1; /* Ethernet 1 (LAN 2) */
+ case 5:
+ return LASAT_IRQ_ETH0; /* Ethernet 0 (LAN 1) */
+ case 6:
+ return LASAT_IRQ_HDC; /* IDE controller */
+ default:
+ return 0xff; /* Illegal */
+ }
+
+ return -1;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
new file mode 100644
index 00000000..ed1c5428
--- /dev/null
+++ b/arch/mips/pci/pci-octeon.c
@@ -0,0 +1,721 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2009 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/swiotlb.h>
+
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
+#include <asm/octeon/pci-octeon.h>
+
+#include <dma-coherence.h>
+
+#define USE_OCTEON_INTERNAL_ARBITER
+
+/*
+ * Octeon's PCI controller uses did=3, subdid=2 for PCI IO
+ * addresses. Use PCI endian swapping 1 so no address swapping is
+ * necessary. The Linux io routines will endian swap the data.
+ */
+#define OCTEON_PCI_IOSPACE_BASE 0x80011a0400000000ull
+#define OCTEON_PCI_IOSPACE_SIZE (1ull<<32)
+
+/* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */
+#define OCTEON_PCI_MEMSPACE_OFFSET (0x00011b0000000000ull)
+
+u64 octeon_bar1_pci_phys;
+
+/**
+ * This is the bit decoding used for the Octeon PCI controller addresses
+ */
+union octeon_pci_address {
+ uint64_t u64;
+ struct {
+ uint64_t upper:2;
+ uint64_t reserved:13;
+ uint64_t io:1;
+ uint64_t did:5;
+ uint64_t subdid:3;
+ uint64_t reserved2:4;
+ uint64_t endian_swap:2;
+ uint64_t reserved3:10;
+ uint64_t bus:8;
+ uint64_t dev:5;
+ uint64_t func:3;
+ uint64_t reg:8;
+ } s;
+};
+
+int __initdata (*octeon_pcibios_map_irq)(const struct pci_dev *dev,
+ u8 slot, u8 pin);
+enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID;
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @dev: The Linux PCI device structure for the device to map
+ * @slot: The slot number for this device on __BUS 0__. Linux
+ * enumerates through all the bridges and figures out the
+ * slot on Bus 0 where this device eventually hooks to.
+ * @pin: The PCI interrupt pin read from the device, then swizzled
+ * as it goes through each bridge.
+ * Returns Interrupt number for the device
+ */
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (octeon_pcibios_map_irq)
+ return octeon_pcibios_map_irq(dev, slot, pin);
+ else
+ panic("octeon_pcibios_map_irq not set.");
+}
+
+
+/*
+ * Called to perform platform specific PCI setup
+ */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ uint16_t config;
+ uint32_t dconfig;
+ int pos;
+ /*
+ * Force the Cache line setting to 64 bytes. The standard
+ * Linux bus scan doesn't seem to set it. Octeon really has
+ * 128 byte lines, but Intel bridges get really upset if you
+ * try and set values above 64 bytes. Value is specified in
+ * 32bit words.
+ */
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4);
+ /* Set latency timers for all devices */
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48);
+
+ /* Enable reporting System errors and parity errors on all devices */
+ /* Enable parity checking and error reporting */
+ pci_read_config_word(dev, PCI_COMMAND, &config);
+ config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ pci_write_config_word(dev, PCI_COMMAND, config);
+
+ if (dev->subordinate) {
+ /* Set latency timers on sub bridges */
+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48);
+ /* More bridge error detection */
+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
+ config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
+ }
+
+ /* Enable the PCIe normal error reporting */
+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ if (pos) {
+ /* Update Device Control */
+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
+ /* Correctable Error Reporting */
+ config |= PCI_EXP_DEVCTL_CERE;
+ /* Non-Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_NFERE;
+ /* Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_FERE;
+ /* Unsupported Request */
+ config |= PCI_EXP_DEVCTL_URRE;
+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
+ }
+
+ /* Find the Advanced Error Reporting capability */
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ if (pos) {
+ /* Clear Uncorrectable Error Status */
+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
+ &dconfig);
+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
+ dconfig);
+ /* Enable reporting of all uncorrectable errors */
+ /* Uncorrectable Error Mask - turned on bits disable errors */
+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
+ /*
+ * Leave severity at HW default. This only controls if
+ * errors are reported as uncorrectable or
+ * correctable, not if the error is reported.
+ */
+ /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
+ /* Clear Correctable Error Status */
+ pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
+ pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
+ /* Enable reporting of all correctable errors */
+ /* Correctable Error Mask - turned on bits disable errors */
+ pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
+ /* Advanced Error Capabilities */
+ pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
+ /* ECRC Generation Enable */
+ if (config & PCI_ERR_CAP_ECRC_GENC)
+ config |= PCI_ERR_CAP_ECRC_GENE;
+ /* ECRC Check Enable */
+ if (config & PCI_ERR_CAP_ECRC_CHKC)
+ config |= PCI_ERR_CAP_ECRC_CHKE;
+ pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
+ /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
+ /* Report all errors to the root complex */
+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
+ PCI_ERR_ROOT_CMD_COR_EN |
+ PCI_ERR_ROOT_CMD_NONFATAL_EN |
+ PCI_ERR_ROOT_CMD_FATAL_EN);
+ /* Clear the Root status register */
+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
+ }
+
+ dev->dev.archdata.dma_ops = octeon_pci_dma_map_ops;
+
+ return 0;
+}
+
+/**
+ * Return the mapping of PCI device number to IRQ line. Each
+ * character in the return string represents the interrupt
+ * line for the device at that position. Device 1 maps to the
+ * first character, etc. The characters A-D are used for PCI
+ * interrupts.
+ *
+ * Returns PCI interrupt mapping
+ */
+const char *octeon_get_pci_interrupts(void)
+{
+ /*
+ * Returning an empty string causes the interrupts to be
+ * routed based on the PCI specification. From the PCI spec:
+ *
+ * INTA# of Device Number 0 is connected to IRQW on the system
+ * board. (Device Number has no significance regarding being
+ * located on the system board or in a connector.) INTA# of
+ * Device Number 1 is connected to IRQX on the system
+ * board. INTA# of Device Number 2 is connected to IRQY on the
+ * system board. INTA# of Device Number 3 is connected to IRQZ
+ * on the system board. The table below describes how each
+ * agent's INTx# lines are connected to the system board
+ * interrupt lines. The following equation can be used to
+ * determine to which INTx# signal on the system board a given
+ * device's INTx# line(s) is connected.
+ *
+ * MB = (D + I) MOD 4 MB = System board Interrupt (IRQW = 0,
+ * IRQX = 1, IRQY = 2, and IRQZ = 3) D = Device Number I =
+ * Interrupt Number (INTA# = 0, INTB# = 1, INTC# = 2, and
+ * INTD# = 3)
+ */
+ switch (octeon_bootinfo->board_type) {
+ case CVMX_BOARD_TYPE_NAO38:
+ /* This is really the NAC38 */
+ return "AAAAADABAAAAAAAAAAAAAAAAAAAAAAAA";
+ case CVMX_BOARD_TYPE_EBH3100:
+ case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
+ case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+ return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+ case CVMX_BOARD_TYPE_BBGW_REF:
+ return "AABCD";
+ case CVMX_BOARD_TYPE_THUNDER:
+ case CVMX_BOARD_TYPE_EBH3000:
+ default:
+ return "";
+ }
+}
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @dev: The Linux PCI device structure for the device to map
+ * @slot: The slot number for this device on __BUS 0__. Linux
+ * enumerates through all the bridges and figures out the
+ * slot on Bus 0 where this device eventually hooks to.
+ * @pin: The PCI interrupt pin read from the device, then swizzled
+ * as it goes through each bridge.
+ * Returns Interrupt number for the device
+ */
+int __init octeon_pci_pcibios_map_irq(const struct pci_dev *dev,
+ u8 slot, u8 pin)
+{
+ int irq_num;
+ const char *interrupts;
+ int dev_num;
+
+ /* Get the board specific interrupt mapping */
+ interrupts = octeon_get_pci_interrupts();
+
+ dev_num = dev->devfn >> 3;
+ if (dev_num < strlen(interrupts))
+ irq_num = ((interrupts[dev_num] - 'A' + pin - 1) & 3) +
+ OCTEON_IRQ_PCI_INT0;
+ else
+ irq_num = ((slot + pin - 3) & 3) + OCTEON_IRQ_PCI_INT0;
+ return irq_num;
+}
+
+
+/*
+ * Read a value from configuration space
+ */
+static int octeon_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ union octeon_pci_address pci_addr;
+
+ pci_addr.u64 = 0;
+ pci_addr.s.upper = 2;
+ pci_addr.s.io = 1;
+ pci_addr.s.did = 3;
+ pci_addr.s.subdid = 1;
+ pci_addr.s.endian_swap = 1;
+ pci_addr.s.bus = bus->number;
+ pci_addr.s.dev = devfn >> 3;
+ pci_addr.s.func = devfn & 0x7;
+ pci_addr.s.reg = reg;
+
+#if PCI_CONFIG_SPACE_DELAY
+ udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+ switch (size) {
+ case 4:
+ *val = le32_to_cpu(cvmx_read64_uint32(pci_addr.u64));
+ return PCIBIOS_SUCCESSFUL;
+ case 2:
+ *val = le16_to_cpu(cvmx_read64_uint16(pci_addr.u64));
+ return PCIBIOS_SUCCESSFUL;
+ case 1:
+ *val = cvmx_read64_uint8(pci_addr.u64);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+
+/*
+ * Write a value to PCI configuration space
+ */
+static int octeon_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ union octeon_pci_address pci_addr;
+
+ pci_addr.u64 = 0;
+ pci_addr.s.upper = 2;
+ pci_addr.s.io = 1;
+ pci_addr.s.did = 3;
+ pci_addr.s.subdid = 1;
+ pci_addr.s.endian_swap = 1;
+ pci_addr.s.bus = bus->number;
+ pci_addr.s.dev = devfn >> 3;
+ pci_addr.s.func = devfn & 0x7;
+ pci_addr.s.reg = reg;
+
+#if PCI_CONFIG_SPACE_DELAY
+ udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+ switch (size) {
+ case 4:
+ cvmx_write64_uint32(pci_addr.u64, cpu_to_le32(val));
+ return PCIBIOS_SUCCESSFUL;
+ case 2:
+ cvmx_write64_uint16(pci_addr.u64, cpu_to_le16(val));
+ return PCIBIOS_SUCCESSFUL;
+ case 1:
+ cvmx_write64_uint8(pci_addr.u64, val);
+ return PCIBIOS_SUCCESSFUL;
+ }
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+
+static struct pci_ops octeon_pci_ops = {
+ octeon_read_config,
+ octeon_write_config,
+};
+
+static struct resource octeon_pci_mem_resource = {
+ .start = 0,
+ .end = 0,
+ .name = "Octeon PCI MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ * PCI ports must be above 16KB so the ISA bus filtering in the PCI-X to PCI
+ * bridge
+ */
+static struct resource octeon_pci_io_resource = {
+ .start = 0x4000,
+ .end = OCTEON_PCI_IOSPACE_SIZE - 1,
+ .name = "Octeon PCI IO",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pci_controller = {
+ .pci_ops = &octeon_pci_ops,
+ .mem_resource = &octeon_pci_mem_resource,
+ .mem_offset = OCTEON_PCI_MEMSPACE_OFFSET,
+ .io_resource = &octeon_pci_io_resource,
+ .io_offset = 0,
+ .io_map_base = OCTEON_PCI_IOSPACE_BASE,
+};
+
+
+/*
+ * Low level initialize the Octeon PCI controller
+ */
+static void octeon_pci_initialize(void)
+{
+ union cvmx_pci_cfg01 cfg01;
+ union cvmx_npi_ctl_status ctl_status;
+ union cvmx_pci_ctl_status_2 ctl_status_2;
+ union cvmx_pci_cfg19 cfg19;
+ union cvmx_pci_cfg16 cfg16;
+ union cvmx_pci_cfg22 cfg22;
+ union cvmx_pci_cfg56 cfg56;
+
+ /* Reset the PCI Bus */
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x1);
+ cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+
+ udelay(2000); /* Hold PCI reset for 2 ms */
+
+ ctl_status.u64 = 0; /* cvmx_read_csr(CVMX_NPI_CTL_STATUS); */
+ ctl_status.s.max_word = 1;
+ ctl_status.s.timer = 1;
+ cvmx_write_csr(CVMX_NPI_CTL_STATUS, ctl_status.u64);
+
+ /* Deassert PCI reset and advertize PCX Host Mode Device Capability
+ (64b) */
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x4);
+ cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+
+ udelay(2000); /* Wait 2 ms after deasserting PCI reset */
+
+ ctl_status_2.u32 = 0;
+ ctl_status_2.s.tsr_hwm = 1; /* Initializes to 0. Must be set
+ before any PCI reads. */
+ ctl_status_2.s.bar2pres = 1; /* Enable BAR2 */
+ ctl_status_2.s.bar2_enb = 1;
+ ctl_status_2.s.bar2_cax = 1; /* Don't use L2 */
+ ctl_status_2.s.bar2_esx = 1;
+ ctl_status_2.s.pmo_amod = 1; /* Round robin priority */
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) {
+ /* BAR1 hole */
+ ctl_status_2.s.bb1_hole = OCTEON_PCI_BAR1_HOLE_BITS;
+ ctl_status_2.s.bb1_siz = 1; /* BAR1 is 2GB */
+ ctl_status_2.s.bb_ca = 1; /* Don't use L2 with big bars */
+ ctl_status_2.s.bb_es = 1; /* Big bar in byte swap mode */
+ ctl_status_2.s.bb1 = 1; /* BAR1 is big */
+ ctl_status_2.s.bb0 = 1; /* BAR0 is big */
+ }
+
+ octeon_npi_write32(CVMX_NPI_PCI_CTL_STATUS_2, ctl_status_2.u32);
+ udelay(2000); /* Wait 2 ms before doing PCI reads */
+
+ ctl_status_2.u32 = octeon_npi_read32(CVMX_NPI_PCI_CTL_STATUS_2);
+ pr_notice("PCI Status: %s %s-bit\n",
+ ctl_status_2.s.ap_pcix ? "PCI-X" : "PCI",
+ ctl_status_2.s.ap_64ad ? "64" : "32");
+
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+ union cvmx_pci_cnt_reg cnt_reg_start;
+ union cvmx_pci_cnt_reg cnt_reg_end;
+ unsigned long cycles, pci_clock;
+
+ cnt_reg_start.u64 = cvmx_read_csr(CVMX_NPI_PCI_CNT_REG);
+ cycles = read_c0_cvmcount();
+ udelay(1000);
+ cnt_reg_end.u64 = cvmx_read_csr(CVMX_NPI_PCI_CNT_REG);
+ cycles = read_c0_cvmcount() - cycles;
+ pci_clock = (cnt_reg_end.s.pcicnt - cnt_reg_start.s.pcicnt) /
+ (cycles / (mips_hpt_frequency / 1000000));
+ pr_notice("PCI Clock: %lu MHz\n", pci_clock);
+ }
+
+ /*
+ * TDOMC must be set to one in PCI mode. TDOMC should be set to 4
+ * in PCI-X mode to allow four outstanding splits. Otherwise,
+ * should not change from its reset value. Don't write PCI_CFG19
+ * in PCI mode (0x82000001 reset value), write it to 0x82000004
+ * after PCI-X mode is known. MRBCI,MDWE,MDRE -> must be zero.
+ * MRBCM -> must be one.
+ */
+ if (ctl_status_2.s.ap_pcix) {
+ cfg19.u32 = 0;
+ /*
+ * Target Delayed/Split request outstanding maximum
+ * count. [1..31] and 0=32. NOTE: If the user
+ * programs these bits beyond the Designed Maximum
+ * outstanding count, then the designed maximum table
+ * depth will be used instead. No additional
+ * Deferred/Split transactions will be accepted if
+ * this outstanding maximum count is
+ * reached. Furthermore, no additional deferred/split
+ * transactions will be accepted if the I/O delay/ I/O
+ * Split Request outstanding maximum is reached.
+ */
+ cfg19.s.tdomc = 4;
+ /*
+ * Master Deferred Read Request Outstanding Max Count
+ * (PCI only). CR4C[26:24] Max SAC cycles MAX DAC
+ * cycles 000 8 4 001 1 0 010 2 1 011 3 1 100 4 2 101
+ * 5 2 110 6 3 111 7 3 For example, if these bits are
+ * programmed to 100, the core can support 2 DAC
+ * cycles, 4 SAC cycles or a combination of 1 DAC and
+ * 2 SAC cycles. NOTE: For the PCI-X maximum
+ * outstanding split transactions, refer to
+ * CRE0[22:20].
+ */
+ cfg19.s.mdrrmc = 2;
+ /*
+ * Master Request (Memory Read) Byte Count/Byte Enable
+ * select. 0 = Byte Enables valid. In PCI mode, a
+ * burst transaction cannot be performed using Memory
+ * Read command=4?h6. 1 = DWORD Byte Count valid
+ * (default). In PCI Mode, the memory read byte
+ * enables are automatically generated by the
+ * core. Note: N3 Master Request transaction sizes are
+ * always determined through the
+ * am_attr[<35:32>|<7:0>] field.
+ */
+ cfg19.s.mrbcm = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_CFG19, cfg19.u32);
+ }
+
+
+ cfg01.u32 = 0;
+ cfg01.s.msae = 1; /* Memory Space Access Enable */
+ cfg01.s.me = 1; /* Master Enable */
+ cfg01.s.pee = 1; /* PERR# Enable */
+ cfg01.s.see = 1; /* System Error Enable */
+ cfg01.s.fbbe = 1; /* Fast Back to Back Transaction Enable */
+
+ octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+
+#ifdef USE_OCTEON_INTERNAL_ARBITER
+ /*
+ * When OCTEON is a PCI host, most systems will use OCTEON's
+ * internal arbiter, so must enable it before any PCI/PCI-X
+ * traffic can occur.
+ */
+ {
+ union cvmx_npi_pci_int_arb_cfg pci_int_arb_cfg;
+
+ pci_int_arb_cfg.u64 = 0;
+ pci_int_arb_cfg.s.en = 1; /* Internal arbiter enable */
+ cvmx_write_csr(CVMX_NPI_PCI_INT_ARB_CFG, pci_int_arb_cfg.u64);
+ }
+#endif /* USE_OCTEON_INTERNAL_ARBITER */
+
+ /*
+ * Preferably written to 1 to set MLTD. [RDSATI,TRTAE,
+ * TWTAE,TMAE,DPPMR -> must be zero. TILT -> must not be set to
+ * 1..7.
+ */
+ cfg16.u32 = 0;
+ cfg16.s.mltd = 1; /* Master Latency Timer Disable */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG16, cfg16.u32);
+
+ /*
+ * Should be written to 0x4ff00. MTTV -> must be zero.
+ * FLUSH -> must be 1. MRV -> should be 0xFF.
+ */
+ cfg22.u32 = 0;
+ /* Master Retry Value [1..255] and 0=infinite */
+ cfg22.s.mrv = 0xff;
+ /*
+ * AM_DO_FLUSH_I control NOTE: This bit MUST BE ONE for proper
+ * N3K operation.
+ */
+ cfg22.s.flush = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_CFG22, cfg22.u32);
+
+ /*
+ * MOST Indicates the maximum number of outstanding splits (in -1
+ * notation) when OCTEON is in PCI-X mode. PCI-X performance is
+ * affected by the MOST selection. Should generally be written
+ * with one of 0x3be807, 0x2be807, 0x1be807, or 0x0be807,
+ * depending on the desired MOST of 3, 2, 1, or 0, respectively.
+ */
+ cfg56.u32 = 0;
+ cfg56.s.pxcid = 7; /* RO - PCI-X Capability ID */
+ cfg56.s.ncp = 0xe8; /* RO - Next Capability Pointer */
+ cfg56.s.dpere = 1; /* Data Parity Error Recovery Enable */
+ cfg56.s.roe = 1; /* Relaxed Ordering Enable */
+ cfg56.s.mmbc = 1; /* Maximum Memory Byte Count
+ [0=512B,1=1024B,2=2048B,3=4096B] */
+ cfg56.s.most = 3; /* Maximum outstanding Split transactions [0=1
+ .. 7=32] */
+
+ octeon_npi_write32(CVMX_NPI_PCI_CFG56, cfg56.u32);
+
+ /*
+ * Affects PCI performance when OCTEON services reads to its
+ * BAR1/BAR2. Refer to Section 10.6.1. The recommended values are
+ * 0x22, 0x33, and 0x33 for PCI_READ_CMD_6, PCI_READ_CMD_C, and
+ * PCI_READ_CMD_E, respectively. Unfortunately due to errata DDR-700,
+ * these values need to be changed so they won't possibly prefetch off
+ * of the end of memory if PCI is DMAing a buffer at the end of
+ * memory. Note that these values differ from their reset values.
+ */
+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_6, 0x21);
+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_C, 0x31);
+ octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_E, 0x31);
+}
+
+
+/*
+ * Initialize the Octeon PCI controller
+ */
+static int __init octeon_pci_setup(void)
+{
+ union cvmx_npi_mem_access_subidx mem_access;
+ int index;
+
+ /* Only these chips have PCI */
+ if (octeon_has_feature(OCTEON_FEATURE_PCIE))
+ return 0;
+
+ /* Point pcibios_map_irq() to the PCI version of it */
+ octeon_pcibios_map_irq = octeon_pci_pcibios_map_irq;
+
+ /* Only use the big bars on chips that support it */
+ if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) ||
+ OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_SMALL;
+ else
+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_BIG;
+
+ /* PCI I/O and PCI MEM values */
+ set_io_port_base(OCTEON_PCI_IOSPACE_BASE);
+ ioport_resource.start = 0;
+ ioport_resource.end = OCTEON_PCI_IOSPACE_SIZE - 1;
+ if (!octeon_is_pci_host()) {
+ pr_notice("Not in host mode, PCI Controller not initialized\n");
+ return 0;
+ }
+
+ pr_notice("%s Octeon big bar support\n",
+ (octeon_dma_bar_type ==
+ OCTEON_DMA_BAR_TYPE_BIG) ? "Enabling" : "Disabling");
+
+ octeon_pci_initialize();
+
+ mem_access.u64 = 0;
+ mem_access.s.esr = 1; /* Endian-Swap on read. */
+ mem_access.s.esw = 1; /* Endian-Swap on write. */
+ mem_access.s.nsr = 0; /* No-Snoop on read. */
+ mem_access.s.nsw = 0; /* No-Snoop on write. */
+ mem_access.s.ror = 0; /* Relax Read on read. */
+ mem_access.s.row = 0; /* Relax Order on write. */
+ mem_access.s.ba = 0; /* PCI Address bits [63:36]. */
+ cvmx_write_csr(CVMX_NPI_MEM_ACCESS_SUBID3, mem_access.u64);
+
+ /*
+ * Remap the Octeon BAR 2 above all 32 bit devices
+ * (0x8000000000ul). This is done here so it is remapped
+ * before the readl()'s below. We don't want BAR2 overlapping
+ * with BAR0/BAR1 during these reads.
+ */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG08,
+ (u32)(OCTEON_BAR2_PCI_ADDRESS & 0xffffffffull));
+ octeon_npi_write32(CVMX_NPI_PCI_CFG09,
+ (u32)(OCTEON_BAR2_PCI_ADDRESS >> 32));
+
+ if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) {
+ /* Remap the Octeon BAR 0 to 0-2GB */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG04, 0);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG05, 0);
+
+ /*
+ * Remap the Octeon BAR 1 to map 2GB-4GB (minus the
+ * BAR 1 hole).
+ */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
+
+ /* BAR1 movable mappings set for identity mapping */
+ octeon_bar1_pci_phys = 0x80000000ull;
+ for (index = 0; index < 32; index++) {
+ union cvmx_pci_bar1_indexx bar1_index;
+
+ bar1_index.u32 = 0;
+ /* Address bits[35:22] sent to L2C */
+ bar1_index.s.addr_idx =
+ (octeon_bar1_pci_phys >> 22) + index;
+ /* Don't put PCI accesses in L2. */
+ bar1_index.s.ca = 1;
+ /* Endian Swap Mode */
+ bar1_index.s.end_swp = 1;
+ /* Set '1' when the selected address range is valid. */
+ bar1_index.s.addr_v = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
+ bar1_index.u32);
+ }
+
+ /* Devices go after BAR1 */
+ octeon_pci_mem_resource.start =
+ OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) -
+ (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+ octeon_pci_mem_resource.end =
+ octeon_pci_mem_resource.start + (1ul << 30);
+ } else {
+ /* Remap the Octeon BAR 0 to map 128MB-(128MB+4KB) */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG04, 128ul << 20);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG05, 0);
+
+ /* Remap the Octeon BAR 1 to map 0-128MB */
+ octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0);
+ octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
+
+ /* BAR1 movable regions contiguous to cover the swiotlb */
+ octeon_bar1_pci_phys =
+ virt_to_phys(octeon_swiotlb) & ~((1ull << 22) - 1);
+
+ for (index = 0; index < 32; index++) {
+ union cvmx_pci_bar1_indexx bar1_index;
+
+ bar1_index.u32 = 0;
+ /* Address bits[35:22] sent to L2C */
+ bar1_index.s.addr_idx =
+ (octeon_bar1_pci_phys >> 22) + index;
+ /* Don't put PCI accesses in L2. */
+ bar1_index.s.ca = 1;
+ /* Endian Swap Mode */
+ bar1_index.s.end_swp = 1;
+ /* Set '1' when the selected address range is valid. */
+ bar1_index.s.addr_v = 1;
+ octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
+ bar1_index.u32);
+ }
+
+ /* Devices go after BAR0 */
+ octeon_pci_mem_resource.start =
+ OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) +
+ (4ul << 10);
+ octeon_pci_mem_resource.end =
+ octeon_pci_mem_resource.start + (1ul << 30);
+ }
+
+ register_pci_controller(&octeon_pci_controller);
+
+ /*
+ * Clear any errors that might be pending from before the bus
+ * was setup properly.
+ */
+ cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1);
+
+ octeon_pci_dma_init();
+
+ return 0;
+}
+
+arch_initcall(octeon_pci_setup);
diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c
new file mode 100644
index 00000000..f31218e1
--- /dev/null
+++ b/arch/mips/pci/pci-rc32434.c
@@ -0,0 +1,232 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * PCI initialization for IDT EB434 board
+ *
+ * Copyright 2004 IDT Inc. (rischelp@idt.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach-rc32434/rc32434.h>
+#include <asm/mach-rc32434/pci.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+/* define an unsigned array for the PCI registers */
+static unsigned int korina_cnfg_regs[25] = {
+ KORINA_CNFG1, KORINA_CNFG2, KORINA_CNFG3, KORINA_CNFG4,
+ KORINA_CNFG5, KORINA_CNFG6, KORINA_CNFG7, KORINA_CNFG8,
+ KORINA_CNFG9, KORINA_CNFG10, KORINA_CNFG11, KORINA_CNFG12,
+ KORINA_CNFG13, KORINA_CNFG14, KORINA_CNFG15, KORINA_CNFG16,
+ KORINA_CNFG17, KORINA_CNFG18, KORINA_CNFG19, KORINA_CNFG20,
+ KORINA_CNFG21, KORINA_CNFG22, KORINA_CNFG23, KORINA_CNFG24
+};
+static struct resource rc32434_res_pci_mem1;
+static struct resource rc32434_res_pci_mem2;
+
+static struct resource rc32434_res_pci_mem1 = {
+ .name = "PCI MEM1",
+ .start = 0x50000000,
+ .end = 0x5FFFFFFF,
+ .flags = IORESOURCE_MEM,
+ .parent = &rc32434_res_pci_mem1,
+ .sibling = NULL,
+ .child = &rc32434_res_pci_mem2
+};
+
+static struct resource rc32434_res_pci_mem2 = {
+ .name = "PCI Mem2",
+ .start = 0x60000000,
+ .end = 0x6FFFFFFF,
+ .flags = IORESOURCE_MEM,
+ .parent = &rc32434_res_pci_mem1,
+ .sibling = NULL,
+ .child = NULL
+};
+
+static struct resource rc32434_res_pci_io1 = {
+ .name = "PCI I/O1",
+ .start = 0x18800000,
+ .end = 0x188FFFFF,
+ .flags = IORESOURCE_IO,
+};
+
+extern struct pci_ops rc32434_pci_ops;
+
+#define PCI_MEM1_START PCI_ADDR_START
+#define PCI_MEM1_END (PCI_ADDR_START + CPUTOPCI_MEM_WIN - 1)
+#define PCI_MEM2_START (PCI_ADDR_START + CPUTOPCI_MEM_WIN)
+#define PCI_MEM2_END (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) - 1)
+#define PCI_IO1_START (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN))
+#define PCI_IO1_END \
+ (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + CPUTOPCI_IO_WIN - 1)
+#define PCI_IO2_START \
+ (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + CPUTOPCI_IO_WIN)
+#define PCI_IO2_END \
+ (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + (2 * CPUTOPCI_IO_WIN) - 1)
+
+struct pci_controller rc32434_controller2;
+
+struct pci_controller rc32434_controller = {
+ .pci_ops = &rc32434_pci_ops,
+ .mem_resource = &rc32434_res_pci_mem1,
+ .io_resource = &rc32434_res_pci_io1,
+ .mem_offset = 0,
+ .io_offset = 0,
+
+};
+
+#ifdef __MIPSEB__
+#define PCI_ENDIAN_FLAG PCILBAC_sb_m
+#else
+#define PCI_ENDIAN_FLAG 0
+#endif
+
+static int __init rc32434_pcibridge_init(void)
+{
+ unsigned int pcicvalue, pcicdata = 0;
+ unsigned int dummyread, pcicntlval;
+ int loopCount;
+ unsigned int pci_config_addr;
+
+ pcicvalue = rc32434_pci->pcic;
+ pcicvalue = (pcicvalue >> PCIM_SHFT) & PCIM_BIT_LEN;
+ if (!((pcicvalue == PCIM_H_EA) ||
+ (pcicvalue == PCIM_H_IA_FIX) ||
+ (pcicvalue == PCIM_H_IA_RR))) {
+ pr_err("PCI init error!!!\n");
+ /* Not in Host Mode, return ERROR */
+ return -1;
+ }
+ /* Enables the Idle Grant mode, Arbiter Parking */
+ pcicdata |= (PCI_CTL_IGM | PCI_CTL_EAP | PCI_CTL_EN);
+ rc32434_pci->pcic = pcicdata; /* Enable the PCI bus Interface */
+ /* Zero out the PCI status & PCI Status Mask */
+ for (;;) {
+ pcicdata = rc32434_pci->pcis;
+ if (!(pcicdata & PCI_STAT_RIP))
+ break;
+ }
+
+ rc32434_pci->pcis = 0;
+ rc32434_pci->pcism = 0xFFFFFFFF;
+ /* Zero out the PCI decoupled registers */
+ rc32434_pci->pcidac = 0; /*
+ * disable PCI decoupled accesses at
+ * initialization
+ */
+ rc32434_pci->pcidas = 0; /* clear the status */
+ rc32434_pci->pcidasm = 0x0000007F; /* Mask all the interrupts */
+ /* Mask PCI Messaging Interrupts */
+ rc32434_pci_msg->pciiic = 0;
+ rc32434_pci_msg->pciiim = 0xFFFFFFFF;
+ rc32434_pci_msg->pciioic = 0;
+ rc32434_pci_msg->pciioim = 0;
+
+
+ /* Setup PCILB0 as Memory Window */
+ rc32434_pci->pcilba[0].address = (unsigned int) (PCI_ADDR_START);
+
+ /* setup the PCI map address as same as the local address */
+
+ rc32434_pci->pcilba[0].mapping = (unsigned int) (PCI_ADDR_START);
+
+
+ /* Setup PCILBA1 as MEM */
+ rc32434_pci->pcilba[0].control =
+ (((SIZE_256MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG);
+ dummyread = rc32434_pci->pcilba[0].control; /* flush the CPU write Buffers */
+ rc32434_pci->pcilba[1].address = 0x60000000;
+ rc32434_pci->pcilba[1].mapping = 0x60000000;
+
+ /* setup PCILBA2 as IO Window */
+ rc32434_pci->pcilba[1].control =
+ (((SIZE_256MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG);
+ dummyread = rc32434_pci->pcilba[1].control; /* flush the CPU write Buffers */
+ rc32434_pci->pcilba[2].address = 0x18C00000;
+ rc32434_pci->pcilba[2].mapping = 0x18FFFFFF;
+
+ /* setup PCILBA2 as IO Window */
+ rc32434_pci->pcilba[2].control =
+ (((SIZE_4MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG);
+ dummyread = rc32434_pci->pcilba[2].control; /* flush the CPU write Buffers */
+
+ /* Setup PCILBA3 as IO Window */
+ rc32434_pci->pcilba[3].address = 0x18800000;
+ rc32434_pci->pcilba[3].mapping = 0x18800000;
+ rc32434_pci->pcilba[3].control =
+ ((((SIZE_1MB & 0x1ff) << PCI_LBAC_SIZE_BIT) | PCI_LBAC_MSI) |
+ PCI_ENDIAN_FLAG);
+ dummyread = rc32434_pci->pcilba[3].control; /* flush the CPU write Buffers */
+
+ pci_config_addr = (unsigned int) (0x80000004);
+ for (loopCount = 0; loopCount < 24; loopCount++) {
+ rc32434_pci->pcicfga = pci_config_addr;
+ dummyread = rc32434_pci->pcicfga;
+ rc32434_pci->pcicfgd = korina_cnfg_regs[loopCount];
+ dummyread = rc32434_pci->pcicfgd;
+ pci_config_addr += 4;
+ }
+ rc32434_pci->pcitc =
+ (unsigned int) ((PCITC_RTIMER_VAL & 0xff) << PCI_TC_RTIMER_BIT) |
+ ((PCITC_DTIMER_VAL & 0xff) << PCI_TC_DTIMER_BIT);
+
+ pcicntlval = rc32434_pci->pcic;
+ pcicntlval &= ~PCI_CTL_TNR;
+ rc32434_pci->pcic = pcicntlval;
+ pcicntlval = rc32434_pci->pcic;
+
+ return 0;
+}
+
+static int __init rc32434_pci_init(void)
+{
+ void __iomem *io_map_base;
+
+ pr_info("PCI: Initializing PCI\n");
+
+ ioport_resource.start = rc32434_res_pci_io1.start;
+ ioport_resource.end = rc32434_res_pci_io1.end;
+
+ rc32434_pcibridge_init();
+
+ io_map_base = ioremap(rc32434_res_pci_io1.start,
+ rc32434_res_pci_io1.end - rc32434_res_pci_io1.start + 1);
+
+ if (!io_map_base)
+ return -ENOMEM;
+
+ rc32434_controller.io_map_base =
+ (unsigned long)io_map_base - rc32434_res_pci_io1.start;
+
+ register_pci_controller(&rc32434_controller);
+ rc32434_sync();
+
+ return 0;
+}
+
+arch_initcall(rc32434_pci_init);
diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c
new file mode 100644
index 00000000..1711e8e1
--- /dev/null
+++ b/arch/mips/pci/pci-sb1250.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2001,2002,2003 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * BCM1250-specific PCI support
+ *
+ * This module provides the glue between Linux's PCI subsystem
+ * and the hardware. We basically provide glue for accessing
+ * configuration space, and set up the translation for I/O
+ * space accesses.
+ *
+ * To access configuration space, we use ioremap. In the 32-bit
+ * kernel, this consumes either 4 or 8 page table pages, and 16MB of
+ * kernel mapped memory. Hopefully neither of these should be a huge
+ * problem.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/vt.h>
+
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250_defs.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/board.h>
+
+/*
+ * Macros for calculating offsets into config space given a device
+ * structure or dev/fun/reg
+ */
+#define CFGOFFSET(bus, devfn, where) (((bus)<<16) + ((devfn)<<8) + (where))
+#define CFGADDR(bus, devfn, where) CFGOFFSET((bus)->number, (devfn), where)
+
+static void *cfg_space;
+
+#define PCI_BUS_ENABLED 1
+#define LDT_BUS_ENABLED 2
+#define PCI_DEVICE_MODE 4
+
+static int sb1250_bus_status;
+
+#define PCI_BRIDGE_DEVICE 0
+#define LDT_BRIDGE_DEVICE 1
+
+#ifdef CONFIG_SIBYTE_HAS_LDT
+/*
+ * HT's level-sensitive interrupts require EOI, which is generated
+ * through a 4MB memory-mapped region
+ */
+unsigned long ldt_eoi_space;
+#endif
+
+/*
+ * Read/write 32-bit values in config space.
+ */
+static inline u32 READCFG32(u32 addr)
+{
+ return *(u32 *) (cfg_space + (addr & ~3));
+}
+
+static inline void WRITECFG32(u32 addr, u32 data)
+{
+ *(u32 *) (cfg_space + (addr & ~3)) = data;
+}
+
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return dev->irq;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+/*
+ * Some checks before doing config cycles:
+ * In PCI Device Mode, hide everything on bus 0 except the LDT host
+ * bridge. Otherwise, access is controlled by bridge MasterEn bits.
+ */
+static int sb1250_pci_can_access(struct pci_bus *bus, int devfn)
+{
+ u32 devno;
+
+ if (!(sb1250_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
+ return 0;
+
+ if (bus->number == 0) {
+ devno = PCI_SLOT(devfn);
+ if (devno == LDT_BRIDGE_DEVICE)
+ return (sb1250_bus_status & LDT_BUS_ENABLED) != 0;
+ else if (sb1250_bus_status & PCI_DEVICE_MODE)
+ return 0;
+ else
+ return 1;
+ } else
+ return 1;
+}
+
+/*
+ * Read/write access functions for various sizes of values
+ * in config space. Return all 1's for disallowed accesses
+ * for a kludgy but adequate simulation of master aborts.
+ */
+
+static int sb1250_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 * val)
+{
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (sb1250_pci_can_access(bus, devfn))
+ data = READCFG32(CFGADDR(bus, devfn, where));
+ else
+ data = 0xFFFFFFFF;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int sb1250_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 cfgaddr = CFGADDR(bus, devfn, where);
+ u32 data = 0;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (!sb1250_pci_can_access(bus, devfn))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = READCFG32(cfgaddr);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ WRITECFG32(cfgaddr, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops sb1250_pci_ops = {
+ .read = sb1250_pcibios_read,
+ .write = sb1250_pcibios_write,
+};
+
+static struct resource sb1250_mem_resource = {
+ .name = "SB1250 PCI MEM",
+ .start = 0x40000000UL,
+ .end = 0x5fffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource sb1250_io_resource = {
+ .name = "SB1250 PCI I/O",
+ .start = 0x00000000UL,
+ .end = 0x01ffffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller sb1250_controller = {
+ .pci_ops = &sb1250_pci_ops,
+ .mem_resource = &sb1250_mem_resource,
+ .io_resource = &sb1250_io_resource,
+};
+
+static int __init sb1250_pcibios_init(void)
+{
+ void __iomem *io_map_base;
+ uint32_t cmdreg;
+ uint64_t reg;
+
+ /* CFE will assign PCI resources */
+ pci_probe_only = 1;
+
+ /* Avoid ISA compat ranges. */
+ PCIBIOS_MIN_IO = 0x00008000UL;
+ PCIBIOS_MIN_MEM = 0x01000000UL;
+
+ /* Set I/O resource limits. */
+ ioport_resource.end = 0x01ffffffUL; /* 32MB accessible by sb1250 */
+ iomem_resource.end = 0xffffffffUL; /* no HT support yet */
+
+ cfg_space =
+ ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16 * 1024 * 1024);
+
+ /*
+ * See if the PCI bus has been configured by the firmware.
+ */
+ reg = __raw_readq(IOADDR(A_SCD_SYSTEM_CFG));
+ if (!(reg & M_SYS_PCI_HOST)) {
+ sb1250_bus_status |= PCI_DEVICE_MODE;
+ } else {
+ cmdreg =
+ READCFG32(CFGOFFSET
+ (0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
+ PCI_COMMAND));
+ if (!(cmdreg & PCI_COMMAND_MASTER)) {
+ printk
+ ("PCI: Skipping PCI probe. Bus is not initialized.\n");
+ iounmap(cfg_space);
+ return 0;
+ }
+ sb1250_bus_status |= PCI_BUS_ENABLED;
+ }
+
+ /*
+ * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
+ * space. Use "match bytes" policy to make everything look
+ * little-endian. So, you need to also set
+ * CONFIG_SWAP_IO_SPACE, but this is the combination that
+ * works correctly with most of Linux's drivers.
+ * XXX ehs: Should this happen in PCI Device mode?
+ */
+ io_map_base = ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 1024 * 1024);
+ sb1250_controller.io_map_base = (unsigned long)io_map_base;
+ set_io_port_base((unsigned long)io_map_base);
+
+#ifdef CONFIG_SIBYTE_HAS_LDT
+ /*
+ * Also check the LDT bridge's enable, just in case we didn't
+ * initialize that one.
+ */
+
+ cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(LDT_BRIDGE_DEVICE, 0),
+ PCI_COMMAND));
+ if (cmdreg & PCI_COMMAND_MASTER) {
+ sb1250_bus_status |= LDT_BUS_ENABLED;
+
+ /*
+ * Need bits 23:16 to convey vector number. Note that
+ * this consumes 4MB of kernel-mapped memory
+ * (Kseg2/Kseg3) for 32-bit kernel.
+ */
+ ldt_eoi_space = (unsigned long)
+ ioremap(A_PHYS_LDT_SPECIAL_MATCH_BYTES,
+ 4 * 1024 * 1024);
+ }
+#endif
+
+ register_pci_controller(&sb1250_controller);
+
+#ifdef CONFIG_VGA_CONSOLE
+ take_over_console(&vga_con, 0, MAX_NR_CONSOLES - 1, 1);
+#endif
+ return 0;
+}
+arch_initcall(sb1250_pcibios_init);
diff --git a/arch/mips/pci/pci-tx4927.c b/arch/mips/pci/pci-tx4927.c
new file mode 100644
index 00000000..a5807406
--- /dev/null
+++ b/arch/mips/pci/pci-tx4927.c
@@ -0,0 +1,91 @@
+/*
+ * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * Copyright 2001, 2003-2005 MontaVista Software Inc.
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/tx4927.h>
+
+int __init tx4927_report_pciclk(void)
+{
+ int pciclk = 0;
+
+ printk(KERN_INFO "PCIC --%s PCICLK:",
+ (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66) ?
+ " PCI66" : "");
+ if (__raw_readq(&tx4927_ccfgptr->pcfg) & TX4927_PCFG_PCICLKEN_ALL) {
+ u64 ccfg = __raw_readq(&tx4927_ccfgptr->ccfg);
+ switch ((unsigned long)ccfg &
+ TX4927_CCFG_PCIDIVMODE_MASK) {
+ case TX4927_CCFG_PCIDIVMODE_2_5:
+ pciclk = txx9_cpu_clock * 2 / 5; break;
+ case TX4927_CCFG_PCIDIVMODE_3:
+ pciclk = txx9_cpu_clock / 3; break;
+ case TX4927_CCFG_PCIDIVMODE_5:
+ pciclk = txx9_cpu_clock / 5; break;
+ case TX4927_CCFG_PCIDIVMODE_6:
+ pciclk = txx9_cpu_clock / 6; break;
+ }
+ printk("Internal(%u.%uMHz)",
+ (pciclk + 50000) / 1000000,
+ ((pciclk + 50000) / 100000) % 10);
+ } else {
+ printk("External");
+ pciclk = -1;
+ }
+ printk("\n");
+ return pciclk;
+}
+
+int __init tx4927_pciclk66_setup(void)
+{
+ int pciclk;
+
+ /* Assert M66EN */
+ tx4927_ccfg_set(TX4927_CCFG_PCI66);
+ /* Double PCICLK (if possible) */
+ if (__raw_readq(&tx4927_ccfgptr->pcfg) & TX4927_PCFG_PCICLKEN_ALL) {
+ unsigned int pcidivmode = 0;
+ u64 ccfg = __raw_readq(&tx4927_ccfgptr->ccfg);
+ pcidivmode = (unsigned long)ccfg &
+ TX4927_CCFG_PCIDIVMODE_MASK;
+ switch (pcidivmode) {
+ case TX4927_CCFG_PCIDIVMODE_5:
+ case TX4927_CCFG_PCIDIVMODE_2_5:
+ pcidivmode = TX4927_CCFG_PCIDIVMODE_2_5;
+ pciclk = txx9_cpu_clock * 2 / 5;
+ break;
+ case TX4927_CCFG_PCIDIVMODE_6:
+ case TX4927_CCFG_PCIDIVMODE_3:
+ default:
+ pcidivmode = TX4927_CCFG_PCIDIVMODE_3;
+ pciclk = txx9_cpu_clock / 3;
+ }
+ tx4927_ccfg_change(TX4927_CCFG_PCIDIVMODE_MASK,
+ pcidivmode);
+ printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n",
+ (unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg));
+ } else
+ pciclk = -1;
+ return pciclk;
+}
+
+void __init tx4927_setup_pcierr_irq(void)
+{
+ if (request_irq(TXX9_IRQ_BASE + TX4927_IR_PCIERR,
+ tx4927_pcierr_interrupt,
+ IRQF_DISABLED, "PCI error",
+ (void *)TX4927_PCIC_REG))
+ printk(KERN_WARNING "Failed to request irq for PCIERR\n");
+}
diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c
new file mode 100644
index 00000000..20e45f30
--- /dev/null
+++ b/arch/mips/pci/pci-tx4938.c
@@ -0,0 +1,142 @@
+/*
+ * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * Copyright 2001, 2003-2005 MontaVista Software Inc.
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/tx4938.h>
+
+int __init tx4938_report_pciclk(void)
+{
+ int pciclk = 0;
+
+ printk(KERN_INFO "PCIC --%s PCICLK:",
+ (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66) ?
+ " PCI66" : "");
+ if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) {
+ u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg);
+ switch ((unsigned long)ccfg &
+ TX4938_CCFG_PCIDIVMODE_MASK) {
+ case TX4938_CCFG_PCIDIVMODE_4:
+ pciclk = txx9_cpu_clock / 4; break;
+ case TX4938_CCFG_PCIDIVMODE_4_5:
+ pciclk = txx9_cpu_clock * 2 / 9; break;
+ case TX4938_CCFG_PCIDIVMODE_5:
+ pciclk = txx9_cpu_clock / 5; break;
+ case TX4938_CCFG_PCIDIVMODE_5_5:
+ pciclk = txx9_cpu_clock * 2 / 11; break;
+ case TX4938_CCFG_PCIDIVMODE_8:
+ pciclk = txx9_cpu_clock / 8; break;
+ case TX4938_CCFG_PCIDIVMODE_9:
+ pciclk = txx9_cpu_clock / 9; break;
+ case TX4938_CCFG_PCIDIVMODE_10:
+ pciclk = txx9_cpu_clock / 10; break;
+ case TX4938_CCFG_PCIDIVMODE_11:
+ pciclk = txx9_cpu_clock / 11; break;
+ }
+ printk("Internal(%u.%uMHz)",
+ (pciclk + 50000) / 1000000,
+ ((pciclk + 50000) / 100000) % 10);
+ } else {
+ printk("External");
+ pciclk = -1;
+ }
+ printk("\n");
+ return pciclk;
+}
+
+void __init tx4938_report_pci1clk(void)
+{
+ __u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg);
+ unsigned int pciclk =
+ txx9_gbus_clock / ((ccfg & TX4938_CCFG_PCI1DMD) ? 4 : 2);
+
+ printk(KERN_INFO "PCIC1 -- %sPCICLK:%u.%uMHz\n",
+ (ccfg & TX4938_CCFG_PCI1_66) ? "PCI66 " : "",
+ (pciclk + 50000) / 1000000,
+ ((pciclk + 50000) / 100000) % 10);
+}
+
+int __init tx4938_pciclk66_setup(void)
+{
+ int pciclk;
+
+ /* Assert M66EN */
+ tx4938_ccfg_set(TX4938_CCFG_PCI66);
+ /* Double PCICLK (if possible) */
+ if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_PCICLKEN_ALL) {
+ unsigned int pcidivmode = 0;
+ u64 ccfg = __raw_readq(&tx4938_ccfgptr->ccfg);
+ pcidivmode = (unsigned long)ccfg &
+ TX4938_CCFG_PCIDIVMODE_MASK;
+ switch (pcidivmode) {
+ case TX4938_CCFG_PCIDIVMODE_8:
+ case TX4938_CCFG_PCIDIVMODE_4:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_4;
+ pciclk = txx9_cpu_clock / 4;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_9:
+ case TX4938_CCFG_PCIDIVMODE_4_5:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_4_5;
+ pciclk = txx9_cpu_clock * 2 / 9;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_10:
+ case TX4938_CCFG_PCIDIVMODE_5:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_5;
+ pciclk = txx9_cpu_clock / 5;
+ break;
+ case TX4938_CCFG_PCIDIVMODE_11:
+ case TX4938_CCFG_PCIDIVMODE_5_5:
+ default:
+ pcidivmode = TX4938_CCFG_PCIDIVMODE_5_5;
+ pciclk = txx9_cpu_clock * 2 / 11;
+ break;
+ }
+ tx4938_ccfg_change(TX4938_CCFG_PCIDIVMODE_MASK,
+ pcidivmode);
+ printk(KERN_DEBUG "PCICLK: ccfg:%08lx\n",
+ (unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg));
+ } else
+ pciclk = -1;
+ return pciclk;
+}
+
+int __init tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot)
+{
+ if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) {
+ switch (slot) {
+ case TX4927_PCIC_IDSEL_AD_TO_SLOT(31):
+ if (__raw_readq(&tx4938_ccfgptr->pcfg) &
+ TX4938_PCFG_ETH0_SEL)
+ return TXX9_IRQ_BASE + TX4938_IR_ETH0;
+ break;
+ case TX4927_PCIC_IDSEL_AD_TO_SLOT(30):
+ if (__raw_readq(&tx4938_ccfgptr->pcfg) &
+ TX4938_PCFG_ETH1_SEL)
+ return TXX9_IRQ_BASE + TX4938_IR_ETH1;
+ break;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+void __init tx4938_setup_pcierr_irq(void)
+{
+ if (request_irq(TXX9_IRQ_BASE + TX4938_IR_PCIERR,
+ tx4927_pcierr_interrupt,
+ IRQF_DISABLED, "PCI error",
+ (void *)TX4927_PCIC_REG))
+ printk(KERN_WARNING "Failed to request irq for PCIERR\n");
+}
diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c
new file mode 100644
index 00000000..9ef84069
--- /dev/null
+++ b/arch/mips/pci/pci-tx4939.c
@@ -0,0 +1,107 @@
+/*
+ * Based on linux/arch/mips/txx9/rbtx4939/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * Copyright 2001, 2003-2005 MontaVista Software Inc.
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/tx4939.h>
+
+int __init tx4939_report_pciclk(void)
+{
+ int pciclk = 0;
+
+ pr_info("PCIC --%s PCICLK:",
+ (__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCI66) ?
+ " PCI66" : "");
+ if (__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_PCICLKEN_ALL) {
+ pciclk = txx9_master_clock * 20 / 6;
+ if (!(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCI66))
+ pciclk /= 2;
+ printk(KERN_CONT "Internal(%u.%uMHz)",
+ (pciclk + 50000) / 1000000,
+ ((pciclk + 50000) / 100000) % 10);
+ } else {
+ printk(KERN_CONT "External");
+ pciclk = -1;
+ }
+ printk(KERN_CONT "\n");
+ return pciclk;
+}
+
+void __init tx4939_report_pci1clk(void)
+{
+ unsigned int pciclk = txx9_master_clock * 20 / 6;
+
+ pr_info("PCIC1 -- PCICLK:%u.%uMHz\n",
+ (pciclk + 50000) / 1000000,
+ ((pciclk + 50000) / 100000) % 10);
+}
+
+int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot)
+{
+ if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4939_pcic1ptr) {
+ switch (slot) {
+ case TX4927_PCIC_IDSEL_AD_TO_SLOT(31):
+ if (__raw_readq(&tx4939_ccfgptr->pcfg) &
+ TX4939_PCFG_ET0MODE)
+ return TXX9_IRQ_BASE + TX4939_IR_ETH(0);
+ break;
+ case TX4927_PCIC_IDSEL_AD_TO_SLOT(30):
+ if (__raw_readq(&tx4939_ccfgptr->pcfg) &
+ TX4939_PCFG_ET1MODE)
+ return TXX9_IRQ_BASE + TX4939_IR_ETH(1);
+ break;
+ }
+ return 0;
+ }
+ return -1;
+}
+
+int __init tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq = tx4939_pcic1_map_irq(dev, slot);
+
+ if (irq >= 0)
+ return irq;
+ irq = pin;
+ /* IRQ rotation */
+ irq--; /* 0-3 */
+ irq = (irq + 33 - slot) % 4;
+ irq++; /* 1-4 */
+
+ switch (irq) {
+ case 1:
+ irq = TXX9_IRQ_BASE + TX4939_IR_INTA;
+ break;
+ case 2:
+ irq = TXX9_IRQ_BASE + TX4939_IR_INTB;
+ break;
+ case 3:
+ irq = TXX9_IRQ_BASE + TX4939_IR_INTC;
+ break;
+ case 4:
+ irq = TXX9_IRQ_BASE + TX4939_IR_INTD;
+ break;
+ }
+ return irq;
+}
+
+void __init tx4939_setup_pcierr_irq(void)
+{
+ if (request_irq(TXX9_IRQ_BASE + TX4939_IR_PCIERR,
+ tx4927_pcierr_interrupt,
+ IRQF_DISABLED, "PCI error",
+ (void *)TX4939_PCIC_REG))
+ pr_warning("Failed to request irq for PCIERR\n");
+}
diff --git a/arch/mips/pci/pci-vr41xx.c b/arch/mips/pci/pci-vr41xx.c
new file mode 100644
index 00000000..56525711
--- /dev/null
+++ b/arch/mips/pci/pci-vr41xx.c
@@ -0,0 +1,320 @@
+/*
+ * pci-vr41xx.c, PCI Control Unit routines for the NEC VR4100 series.
+ *
+ * Copyright (C) 2001-2003 MontaVista Software Inc.
+ * Author: Yoichi Yuasa <source@mvista.com>
+ * Copyright (C) 2004-2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * Changes:
+ * MontaVista Software Inc. <source@mvista.com>
+ * - New creation, NEC VR4122 and VR4131 are supported.
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/pci.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#include "pci-vr41xx.h"
+
+extern struct pci_ops vr41xx_pci_ops;
+
+static void __iomem *pciu_base;
+
+#define pciu_read(offset) readl(pciu_base + (offset))
+#define pciu_write(offset, value) writel((value), pciu_base + (offset))
+
+static struct pci_master_address_conversion pci_master_memory1 = {
+ .bus_base_address = PCI_MASTER_MEM1_BUS_BASE_ADDRESS,
+ .address_mask = PCI_MASTER_MEM1_ADDRESS_MASK,
+ .pci_base_address = PCI_MASTER_MEM1_PCI_BASE_ADDRESS,
+};
+
+static struct pci_target_address_conversion pci_target_memory1 = {
+ .address_mask = PCI_TARGET_MEM1_ADDRESS_MASK,
+ .bus_base_address = PCI_TARGET_MEM1_BUS_BASE_ADDRESS,
+};
+
+static struct pci_master_address_conversion pci_master_io = {
+ .bus_base_address = PCI_MASTER_IO_BUS_BASE_ADDRESS,
+ .address_mask = PCI_MASTER_IO_ADDRESS_MASK,
+ .pci_base_address = PCI_MASTER_IO_PCI_BASE_ADDRESS,
+};
+
+static struct pci_mailbox_address pci_mailbox = {
+ .base_address = PCI_MAILBOX_BASE_ADDRESS,
+};
+
+static struct pci_target_address_window pci_target_window1 = {
+ .base_address = PCI_TARGET_WINDOW1_BASE_ADDRESS,
+};
+
+static struct resource pci_mem_resource = {
+ .name = "PCI Memory resources",
+ .start = PCI_MEM_RESOURCE_START,
+ .end = PCI_MEM_RESOURCE_END,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource pci_io_resource = {
+ .name = "PCI I/O resources",
+ .start = PCI_IO_RESOURCE_START,
+ .end = PCI_IO_RESOURCE_END,
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller_unit_setup vr41xx_pci_controller_unit_setup = {
+ .master_memory1 = &pci_master_memory1,
+ .target_memory1 = &pci_target_memory1,
+ .master_io = &pci_master_io,
+ .exclusive_access = CANNOT_LOCK_FROM_DEVICE,
+ .wait_time_limit_from_irdy_to_trdy = 0,
+ .mailbox = &pci_mailbox,
+ .target_window1 = &pci_target_window1,
+ .master_latency_timer = 0x80,
+ .retry_limit = 0,
+ .arbiter_priority_control = PCI_ARBITRATION_MODE_FAIR,
+ .take_away_gnt_mode = PCI_TAKE_AWAY_GNT_DISABLE,
+};
+
+static struct pci_controller vr41xx_pci_controller = {
+ .pci_ops = &vr41xx_pci_ops,
+ .mem_resource = &pci_mem_resource,
+ .io_resource = &pci_io_resource,
+};
+
+void __init vr41xx_pciu_setup(struct pci_controller_unit_setup *setup)
+{
+ vr41xx_pci_controller_unit_setup = *setup;
+}
+
+static int __init vr41xx_pciu_init(void)
+{
+ struct pci_controller_unit_setup *setup;
+ struct pci_master_address_conversion *master;
+ struct pci_target_address_conversion *target;
+ struct pci_mailbox_address *mailbox;
+ struct pci_target_address_window *window;
+ unsigned long vtclock, pci_clock_max;
+ uint32_t val;
+
+ setup = &vr41xx_pci_controller_unit_setup;
+
+ if (request_mem_region(PCIU_BASE, PCIU_SIZE, "PCIU") == NULL)
+ return -EBUSY;
+
+ pciu_base = ioremap(PCIU_BASE, PCIU_SIZE);
+ if (pciu_base == NULL) {
+ release_mem_region(PCIU_BASE, PCIU_SIZE);
+ return -EBUSY;
+ }
+
+ /* Disable PCI interrupt */
+ vr41xx_disable_pciint();
+
+ /* Supply VTClock to PCIU */
+ vr41xx_supply_clock(PCIU_CLOCK);
+
+ /* Dummy write, waiting for supply of VTClock. */
+ vr41xx_disable_pciint();
+
+ /* Select PCI clock */
+ if (setup->pci_clock_max != 0)
+ pci_clock_max = setup->pci_clock_max;
+ else
+ pci_clock_max = PCI_CLOCK_MAX;
+ vtclock = vr41xx_get_vtclock_frequency();
+ if (vtclock < pci_clock_max)
+ pciu_write(PCICLKSELREG, EQUAL_VTCLOCK);
+ else if ((vtclock / 2) < pci_clock_max)
+ pciu_write(PCICLKSELREG, HALF_VTCLOCK);
+ else if (current_cpu_data.processor_id >= PRID_VR4131_REV2_1 &&
+ (vtclock / 3) < pci_clock_max)
+ pciu_write(PCICLKSELREG, ONE_THIRD_VTCLOCK);
+ else if ((vtclock / 4) < pci_clock_max)
+ pciu_write(PCICLKSELREG, QUARTER_VTCLOCK);
+ else {
+ printk(KERN_ERR "PCI Clock is over 33MHz.\n");
+ iounmap(pciu_base);
+ return -EINVAL;
+ }
+
+ /* Supply PCI clock by PCI bus */
+ vr41xx_supply_clock(PCI_CLOCK);
+
+ if (setup->master_memory1 != NULL) {
+ master = setup->master_memory1;
+ val = IBA(master->bus_base_address) |
+ MASTER_MSK(master->address_mask) |
+ WINEN |
+ PCIA(master->pci_base_address);
+ pciu_write(PCIMMAW1REG, val);
+ } else {
+ val = pciu_read(PCIMMAW1REG);
+ val &= ~WINEN;
+ pciu_write(PCIMMAW1REG, val);
+ }
+
+ if (setup->master_memory2 != NULL) {
+ master = setup->master_memory2;
+ val = IBA(master->bus_base_address) |
+ MASTER_MSK(master->address_mask) |
+ WINEN |
+ PCIA(master->pci_base_address);
+ pciu_write(PCIMMAW2REG, val);
+ } else {
+ val = pciu_read(PCIMMAW2REG);
+ val &= ~WINEN;
+ pciu_write(PCIMMAW2REG, val);
+ }
+
+ if (setup->target_memory1 != NULL) {
+ target = setup->target_memory1;
+ val = TARGET_MSK(target->address_mask) |
+ WINEN |
+ ITA(target->bus_base_address);
+ pciu_write(PCITAW1REG, val);
+ } else {
+ val = pciu_read(PCITAW1REG);
+ val &= ~WINEN;
+ pciu_write(PCITAW1REG, val);
+ }
+
+ if (setup->target_memory2 != NULL) {
+ target = setup->target_memory2;
+ val = TARGET_MSK(target->address_mask) |
+ WINEN |
+ ITA(target->bus_base_address);
+ pciu_write(PCITAW2REG, val);
+ } else {
+ val = pciu_read(PCITAW2REG);
+ val &= ~WINEN;
+ pciu_write(PCITAW2REG, val);
+ }
+
+ if (setup->master_io != NULL) {
+ master = setup->master_io;
+ val = IBA(master->bus_base_address) |
+ MASTER_MSK(master->address_mask) |
+ WINEN |
+ PCIIA(master->pci_base_address);
+ pciu_write(PCIMIOAWREG, val);
+ } else {
+ val = pciu_read(PCIMIOAWREG);
+ val &= ~WINEN;
+ pciu_write(PCIMIOAWREG, val);
+ }
+
+ if (setup->exclusive_access == CANNOT_LOCK_FROM_DEVICE)
+ pciu_write(PCIEXACCREG, UNLOCK);
+ else
+ pciu_write(PCIEXACCREG, 0);
+
+ if (current_cpu_type() == CPU_VR4122)
+ pciu_write(PCITRDYVREG, TRDYV(setup->wait_time_limit_from_irdy_to_trdy));
+
+ pciu_write(LATTIMEREG, MLTIM(setup->master_latency_timer));
+
+ if (setup->mailbox != NULL) {
+ mailbox = setup->mailbox;
+ val = MBADD(mailbox->base_address) | TYPE_32BITSPACE |
+ MSI_MEMORY | PREF_APPROVAL;
+ pciu_write(MAILBAREG, val);
+ }
+
+ if (setup->target_window1) {
+ window = setup->target_window1;
+ val = PMBA(window->base_address) | TYPE_32BITSPACE |
+ MSI_MEMORY | PREF_APPROVAL;
+ pciu_write(PCIMBA1REG, val);
+ }
+
+ if (setup->target_window2) {
+ window = setup->target_window2;
+ val = PMBA(window->base_address) | TYPE_32BITSPACE |
+ MSI_MEMORY | PREF_APPROVAL;
+ pciu_write(PCIMBA2REG, val);
+ }
+
+ val = pciu_read(RETVALREG);
+ val &= ~RTYVAL_MASK;
+ val |= RTYVAL(setup->retry_limit);
+ pciu_write(RETVALREG, val);
+
+ val = pciu_read(PCIAPCNTREG);
+ val &= ~(TKYGNT | PAPC);
+
+ switch (setup->arbiter_priority_control) {
+ case PCI_ARBITRATION_MODE_ALTERNATE_0:
+ val |= PAPC_ALTERNATE_0;
+ break;
+ case PCI_ARBITRATION_MODE_ALTERNATE_B:
+ val |= PAPC_ALTERNATE_B;
+ break;
+ default:
+ val |= PAPC_FAIR;
+ break;
+ }
+
+ if (setup->take_away_gnt_mode == PCI_TAKE_AWAY_GNT_ENABLE)
+ val |= TKYGNT_ENABLE;
+
+ pciu_write(PCIAPCNTREG, val);
+
+ pciu_write(COMMANDREG, PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_PARITY |
+ PCI_COMMAND_SERR);
+
+ /* Clear bus error */
+ pciu_read(BUSERRADREG);
+
+ pciu_write(PCIENREG, PCIU_CONFIG_DONE);
+
+ if (setup->mem_resource != NULL)
+ vr41xx_pci_controller.mem_resource = setup->mem_resource;
+
+ if (setup->io_resource != NULL) {
+ vr41xx_pci_controller.io_resource = setup->io_resource;
+ } else {
+ set_io_port_base(IO_PORT_BASE);
+ ioport_resource.start = IO_PORT_RESOURCE_START;
+ ioport_resource.end = IO_PORT_RESOURCE_END;
+ }
+
+ if (setup->master_io) {
+ void __iomem *io_map_base;
+ struct resource *res = vr41xx_pci_controller.io_resource;
+ master = setup->master_io;
+ io_map_base = ioremap(master->bus_base_address,
+ res->end - res->start + 1);
+ if (!io_map_base)
+ return -EBUSY;
+
+ vr41xx_pci_controller.io_map_base = (unsigned long)io_map_base;
+ }
+
+ register_pci_controller(&vr41xx_pci_controller);
+
+ return 0;
+}
+
+arch_initcall(vr41xx_pciu_init);
diff --git a/arch/mips/pci/pci-vr41xx.h b/arch/mips/pci/pci-vr41xx.h
new file mode 100644
index 00000000..6b1ae2eb
--- /dev/null
+++ b/arch/mips/pci/pci-vr41xx.h
@@ -0,0 +1,154 @@
+/*
+ * pci-vr41xx.h, Include file for PCI Control Unit of the NEC VR4100 series.
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ * Author: Yoichi Yuasa <source@mvista.com>
+ * Copyright (C) 2004-2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __PCI_VR41XX_H
+#define __PCI_VR41XX_H
+
+#define PCIU_BASE 0x0f000c00UL
+#define PCIU_SIZE 0x200UL
+
+#define PCIMMAW1REG 0x00
+#define PCIMMAW2REG 0x04
+#define PCITAW1REG 0x08
+#define PCITAW2REG 0x0c
+#define PCIMIOAWREG 0x10
+ #define IBA(addr) ((addr) & 0xff000000U)
+ #define MASTER_MSK(mask) (((mask) >> 11) & 0x000fe000U)
+ #define PCIA(addr) (((addr) >> 24) & 0x000000ffU)
+ #define TARGET_MSK(mask) (((mask) >> 8) & 0x000fe000U)
+ #define ITA(addr) (((addr) >> 24) & 0x000000ffU)
+ #define PCIIA(addr) (((addr) >> 24) & 0x000000ffU)
+ #define WINEN 0x1000U
+#define PCICONFDREG 0x14
+#define PCICONFAREG 0x18
+#define PCIMAILREG 0x1c
+#define BUSERRADREG 0x24
+ #define EA(reg) ((reg) &0xfffffffc)
+
+#define INTCNTSTAREG 0x28
+ #define MABTCLR 0x80000000U
+ #define TRDYCLR 0x40000000U
+ #define PARCLR 0x20000000U
+ #define MBCLR 0x10000000U
+ #define SERRCLR 0x08000000U
+ #define RTYCLR 0x04000000U
+ #define MABCLR 0x02000000U
+ #define TABCLR 0x01000000U
+ /* RFU */
+ #define MABTMSK 0x00008000U
+ #define TRDYMSK 0x00004000U
+ #define PARMSK 0x00002000U
+ #define MBMSK 0x00001000U
+ #define SERRMSK 0x00000800U
+ #define RTYMSK 0x00000400U
+ #define MABMSK 0x00000200U
+ #define TABMSK 0x00000100U
+ #define IBAMABT 0x00000080U
+ #define TRDYRCH 0x00000040U
+ #define PAR 0x00000020U
+ #define MB 0x00000010U
+ #define PCISERR 0x00000008U
+ #define RTYRCH 0x00000004U
+ #define MABORT 0x00000002U
+ #define TABORT 0x00000001U
+
+#define PCIEXACCREG 0x2c
+ #define UNLOCK 0x2U
+ #define EAREQ 0x1U
+#define PCIRECONTREG 0x30
+ #define RTRYCNT(reg) ((reg) & 0x000000ffU)
+#define PCIENREG 0x34
+ #define PCIU_CONFIG_DONE 0x4U
+#define PCICLKSELREG 0x38
+ #define EQUAL_VTCLOCK 0x2U
+ #define HALF_VTCLOCK 0x0U
+ #define ONE_THIRD_VTCLOCK 0x3U
+ #define QUARTER_VTCLOCK 0x1U
+#define PCITRDYVREG 0x3c
+ #define TRDYV(val) ((uint32_t)(val) & 0xffU)
+#define PCICLKRUNREG 0x60
+
+#define VENDORIDREG 0x100
+#define DEVICEIDREG 0x100
+#define COMMANDREG 0x104
+#define STATUSREG 0x104
+#define REVIDREG 0x108
+#define CLASSREG 0x108
+#define CACHELSREG 0x10c
+#define LATTIMEREG 0x10c
+ #define MLTIM(val) (((uint32_t)(val) << 7) & 0xff00U)
+#define MAILBAREG 0x110
+#define PCIMBA1REG 0x114
+#define PCIMBA2REG 0x118
+ #define MBADD(base) ((base) & 0xfffff800U)
+ #define PMBA(base) ((base) & 0xffe00000U)
+ #define PREF 0x8U
+ #define PREF_APPROVAL 0x8U
+ #define PREF_DISAPPROVAL 0x0U
+ #define TYPE 0x6U
+ #define TYPE_32BITSPACE 0x0U
+ #define MSI 0x1U
+ #define MSI_MEMORY 0x0U
+#define INTLINEREG 0x13c
+#define INTPINREG 0x13c
+#define RETVALREG 0x140
+#define PCIAPCNTREG 0x140
+ #define TKYGNT 0x04000000U
+ #define TKYGNT_ENABLE 0x04000000U
+ #define TKYGNT_DISABLE 0x00000000U
+ #define PAPC 0x03000000U
+ #define PAPC_ALTERNATE_B 0x02000000U
+ #define PAPC_ALTERNATE_0 0x01000000U
+ #define PAPC_FAIR 0x00000000U
+ #define RTYVAL(val) (((uint32_t)(val) << 7) & 0xff00U)
+ #define RTYVAL_MASK 0xff00U
+
+#define PCI_CLOCK_MAX 33333333U
+
+/*
+ * Default setup
+ */
+#define PCI_MASTER_MEM1_BUS_BASE_ADDRESS 0x10000000U
+#define PCI_MASTER_MEM1_ADDRESS_MASK 0x7c000000U
+#define PCI_MASTER_MEM1_PCI_BASE_ADDRESS 0x10000000U
+
+#define PCI_TARGET_MEM1_ADDRESS_MASK 0x08000000U
+#define PCI_TARGET_MEM1_BUS_BASE_ADDRESS 0x00000000U
+
+#define PCI_MASTER_IO_BUS_BASE_ADDRESS 0x16000000U
+#define PCI_MASTER_IO_ADDRESS_MASK 0x7e000000U
+#define PCI_MASTER_IO_PCI_BASE_ADDRESS 0x00000000U
+
+#define PCI_MAILBOX_BASE_ADDRESS 0x00000000U
+
+#define PCI_TARGET_WINDOW1_BASE_ADDRESS 0x00000000U
+
+#define IO_PORT_BASE KSEG1ADDR(PCI_MASTER_IO_BUS_BASE_ADDRESS)
+#define IO_PORT_RESOURCE_START PCI_MASTER_IO_PCI_BASE_ADDRESS
+#define IO_PORT_RESOURCE_END (~PCI_MASTER_IO_ADDRESS_MASK & PCI_MASTER_ADDRESS_MASK)
+
+#define PCI_IO_RESOURCE_START 0x01000000UL
+#define PCI_IO_RESOURCE_END 0x01ffffffUL
+
+#define PCI_MEM_RESOURCE_START 0x11000000UL
+#define PCI_MEM_RESOURCE_END 0x13ffffffUL
+
+#endif /* __PCI_VR41XX_H */
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
new file mode 100644
index 00000000..38fece16
--- /dev/null
+++ b/arch/mips/pci/pci-xlr.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+
+#include <asm/io.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+static void *pci_config_base;
+
+#define pci_cfg_addr(bus, devfn, off) (((bus) << 16) | ((devfn) << 8) | (off))
+
+/* PCI ops */
+static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn,
+ int where)
+{
+ u32 data;
+ u32 *cfgaddr;
+
+ cfgaddr = (u32 *)(pci_config_base +
+ pci_cfg_addr(bus->number, devfn, where & ~3));
+ data = *cfgaddr;
+ return cpu_to_le32(data);
+}
+
+static inline void pci_cfg_write_32bit(struct pci_bus *bus, unsigned int devfn,
+ int where, u32 data)
+{
+ u32 *cfgaddr;
+
+ cfgaddr = (u32 *)(pci_config_base +
+ pci_cfg_addr(bus->number, devfn, where & ~3));
+ *cfgaddr = cpu_to_le32(data);
+}
+
+static int nlm_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 data;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = pci_cfg_read_32bit(bus, devfn, where);
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int nlm_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = pci_cfg_read_32bit(bus, devfn, where);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ pci_cfg_write_32bit(bus, devfn, where, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops nlm_pci_ops = {
+ .read = nlm_pcibios_read,
+ .write = nlm_pcibios_write
+};
+
+static struct resource nlm_pci_mem_resource = {
+ .name = "XLR PCI MEM",
+ .start = 0xd0000000UL, /* 256MB PCI mem @ 0xd000_0000 */
+ .end = 0xdfffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource nlm_pci_io_resource = {
+ .name = "XLR IO MEM",
+ .start = 0x10000000UL, /* 16MB PCI IO @ 0x1000_0000 */
+ .end = 0x100fffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller nlm_pci_controller = {
+ .index = 0,
+ .pci_ops = &nlm_pci_ops,
+ .mem_resource = &nlm_pci_mem_resource,
+ .mem_offset = 0x00000000UL,
+ .io_resource = &nlm_pci_io_resource,
+ .io_offset = 0x00000000UL,
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (!nlm_chip_is_xls())
+ return PIC_PCIX_IRQ; /* for XLR just one IRQ*/
+
+ /*
+ * For XLS PCIe, there is an IRQ per Link, find out which
+ * link the device is on to assign interrupts
+ */
+ if (dev->bus->self == NULL)
+ return 0;
+
+ switch (dev->bus->self->devfn) {
+ case 0x0:
+ return PIC_PCIE_LINK0_IRQ;
+ case 0x8:
+ return PIC_PCIE_LINK1_IRQ;
+ case 0x10:
+ if (nlm_chip_is_xls_b())
+ return PIC_PCIE_XLSB0_LINK2_IRQ;
+ else
+ return PIC_PCIE_LINK2_IRQ;
+ case 0x18:
+ if (nlm_chip_is_xls_b())
+ return PIC_PCIE_XLSB0_LINK3_IRQ;
+ else
+ return PIC_PCIE_LINK3_IRQ;
+ }
+ WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
+ return 0;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+static int __init pcibios_init(void)
+{
+ /* PSB assigns PCI resources */
+ pci_probe_only = 1;
+ pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20);
+
+ /* Extend IO port for memory mapped io */
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+
+ set_io_port_base(CKSEG1);
+ nlm_pci_controller.io_map_base = CKSEG1;
+
+ pr_info("Registering XLR/XLS PCIX/PCIE Controller.\n");
+ register_pci_controller(&nlm_pci_controller);
+
+ return 0;
+}
+
+arch_initcall(pcibios_init);
+
+struct pci_fixup pcibios_fixups[] = {
+ {0}
+};
diff --git a/arch/mips/pci/pci-yosemite.c b/arch/mips/pci/pci-yosemite.c
new file mode 100644
index 00000000..cf5e1a25
--- /dev/null
+++ b/arch/mips/pci/pci-yosemite.c
@@ -0,0 +1,67 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/titan_dep.h>
+
+extern struct pci_ops titan_pci_ops;
+
+static struct resource py_mem_resource = {
+ .start = 0xe0000000UL,
+ .end = 0xe3ffffffUL,
+ .name = "Titan PCI MEM",
+ .flags = IORESOURCE_MEM
+};
+
+/*
+ * PMON really reserves 16MB of I/O port space but that's stupid, nothing
+ * needs that much since allocations are limited to 256 bytes per device
+ * anyway. So we just claim 64kB here.
+ */
+#define TITAN_IO_SIZE 0x0000ffffUL
+#define TITAN_IO_BASE 0xe8000000UL
+
+static struct resource py_io_resource = {
+ .start = 0x00001000UL,
+ .end = TITAN_IO_SIZE - 1,
+ .name = "Titan IO MEM",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller py_controller = {
+ .pci_ops = &titan_pci_ops,
+ .mem_resource = &py_mem_resource,
+ .mem_offset = 0x00000000UL,
+ .io_resource = &py_io_resource,
+ .io_offset = 0x00000000UL
+};
+
+static char ioremap_failed[] __initdata = "Could not ioremap I/O port range";
+
+static int __init pmc_yosemite_setup(void)
+{
+ unsigned long io_v_base;
+
+ io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE);
+ if (!io_v_base)
+ panic(ioremap_failed);
+
+ set_io_port_base(io_v_base);
+ py_controller.io_map_base = io_v_base;
+ TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
+
+ ioport_resource.end = TITAN_IO_SIZE - 1;
+
+ register_pci_controller(&py_controller);
+
+ return 0;
+}
+
+arch_initcall(pmc_yosemite_setup);
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
new file mode 100644
index 00000000..33bba7bf
--- /dev/null
+++ b/arch/mips/pci/pci.c
@@ -0,0 +1,364 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+/*
+ * Indicate whether we respect the PCI setup left by the firmware.
+ *
+ * Make this long-lived so that we know when shutting down
+ * whether we probed only or not.
+ */
+int pci_probe_only;
+
+#define PCI_ASSIGN_ALL_BUSSES 1
+
+unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES;
+
+/*
+ * The PCI controller list.
+ */
+
+static struct pci_controller *hose_head, **hose_tail = &hose_head;
+
+unsigned long PCIBIOS_MIN_IO;
+unsigned long PCIBIOS_MIN_MEM;
+
+static int pci_initialized;
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+resource_size_t
+pcibios_align_resource(void *data, const struct resource *res,
+ resource_size_t size, resource_size_t align)
+{
+ struct pci_dev *dev = data;
+ struct pci_controller *hose = dev->sysdata;
+ resource_size_t start = res->start;
+
+ if (res->flags & IORESOURCE_IO) {
+ /* Make sure we start at our min on all hoses */
+ if (start < PCIBIOS_MIN_IO + hose->io_resource->start)
+ start = PCIBIOS_MIN_IO + hose->io_resource->start;
+
+ /*
+ * Put everything into 0x00-0xff region modulo 0x400
+ */
+ if (start & 0x300)
+ start = (start + 0x3ff) & ~0x3ff;
+ } else if (res->flags & IORESOURCE_MEM) {
+ /* Make sure we start at our min on all hoses */
+ if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start)
+ start = PCIBIOS_MIN_MEM + hose->mem_resource->start;
+ }
+
+ return start;
+}
+
+static void __devinit pcibios_scanbus(struct pci_controller *hose)
+{
+ static int next_busno;
+ static int need_domain_info;
+ struct pci_bus *bus;
+
+ if (!hose->iommu)
+ PCI_DMA_BUS_IS_PHYS = 1;
+
+ if (hose->get_busno && pci_probe_only)
+ next_busno = (*hose->get_busno)();
+
+ bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
+ hose->bus = bus;
+
+ need_domain_info = need_domain_info || hose->index;
+ hose->need_domain_info = need_domain_info;
+ if (bus) {
+ next_busno = bus->subordinate + 1;
+ /* Don't allow 8-bit bus number overflow inside the hose -
+ reserve some space for bridges. */
+ if (next_busno > 224) {
+ next_busno = 0;
+ need_domain_info = 1;
+ }
+
+ if (!pci_probe_only) {
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+ pci_enable_bridges(bus);
+ }
+ }
+}
+
+static DEFINE_MUTEX(pci_scan_mutex);
+
+void __devinit register_pci_controller(struct pci_controller *hose)
+{
+ if (request_resource(&iomem_resource, hose->mem_resource) < 0)
+ goto out;
+ if (request_resource(&ioport_resource, hose->io_resource) < 0) {
+ release_resource(hose->mem_resource);
+ goto out;
+ }
+
+ *hose_tail = hose;
+ hose_tail = &hose->next;
+
+ /*
+ * Do not panic here but later - this might happen before console init.
+ */
+ if (!hose->io_map_base) {
+ printk(KERN_WARNING
+ "registering PCI controller with io_map_base unset\n");
+ }
+
+ /*
+ * Scan the bus if it is register after the PCI subsystem
+ * initialization.
+ */
+ if (pci_initialized) {
+ mutex_lock(&pci_scan_mutex);
+ pcibios_scanbus(hose);
+ mutex_unlock(&pci_scan_mutex);
+ }
+
+ return;
+
+out:
+ printk(KERN_WARNING
+ "Skipping PCI bus scan due to resource conflict\n");
+}
+
+static int __init pcibios_init(void)
+{
+ struct pci_controller *hose;
+
+ /* Scan all of the recorded PCI controllers. */
+ for (hose = hose_head; hose; hose = hose->next)
+ pcibios_scanbus(hose);
+
+ pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq);
+
+ pci_initialized = 1;
+
+ return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+static int pcibios_enable_resources(struct pci_dev *dev, int mask)
+{
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
+ /* Only set up the requested stuff */
+ if (!(mask & (1<<idx)))
+ continue;
+
+ r = &dev->resource[idx];
+ if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
+ continue;
+ if ((idx == PCI_ROM_RESOURCE) &&
+ (!(r->flags & IORESOURCE_ROM_ENABLE)))
+ continue;
+ if (!r->start && r->end) {
+ printk(KERN_ERR "PCI: Device %s not available "
+ "because of resource collisions\n",
+ pci_name(dev));
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (cmd != old_cmd) {
+ printk("PCI: Enabling device %s (%04x -> %04x)\n",
+ pci_name(dev), old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+}
+
+/*
+ * If we set up a device for bus mastering, we need to check the latency
+ * timer as certain crappy BIOSes forget to set it properly.
+ */
+static unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+ u8 lat;
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+ if (lat < 16)
+ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+ else if (lat > pcibios_max_latency)
+ lat = pcibios_max_latency;
+ else
+ return;
+ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
+ pci_name(dev), lat);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+ return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+ int err;
+
+ if ((err = pcibios_enable_resources(dev, mask)) < 0)
+ return err;
+
+ return pcibios_plat_dev_init(dev);
+}
+
+static void pcibios_fixup_device_resources(struct pci_dev *dev,
+ struct pci_bus *bus)
+{
+ /* Update device resources. */
+ struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
+ unsigned long offset = 0;
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ if (!dev->resource[i].start)
+ continue;
+ if (dev->resource[i].flags & IORESOURCE_IO)
+ offset = hose->io_offset;
+ else if (dev->resource[i].flags & IORESOURCE_MEM)
+ offset = hose->mem_offset;
+
+ dev->resource[i].start += offset;
+ dev->resource[i].end += offset;
+ }
+}
+
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+ /* Propagate hose info into the subordinate devices. */
+
+ struct pci_controller *hose = bus->sysdata;
+ struct list_head *ln;
+ struct pci_dev *dev = bus->self;
+
+ if (!dev) {
+ bus->resource[0] = hose->io_resource;
+ bus->resource[1] = hose->mem_resource;
+ } else if (pci_probe_only &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ pci_read_bridge_bases(bus);
+ pcibios_fixup_device_resources(dev, bus);
+ }
+
+ for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
+ dev = pci_dev_b(ln);
+
+ if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ pcibios_fixup_device_resources(dev, bus);
+ }
+}
+
+void __init
+pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+ struct resource *res)
+{
+ struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
+ unsigned long offset = 0;
+
+ if (res->flags & IORESOURCE_IO)
+ offset = hose->io_offset;
+ else if (res->flags & IORESOURCE_MEM)
+ offset = hose->mem_offset;
+
+ region->start = res->start - offset;
+ region->end = res->end - offset;
+}
+
+void __devinit
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region)
+{
+ struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
+ unsigned long offset = 0;
+
+ if (res->flags & IORESOURCE_IO)
+ offset = hose->io_offset;
+ else if (res->flags & IORESOURCE_MEM)
+ offset = hose->mem_offset;
+
+ res->start = region->start + offset;
+ res->end = region->end + offset;
+}
+
+#ifdef CONFIG_HOTPLUG
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+EXPORT_SYMBOL(PCIBIOS_MIN_IO);
+EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
+#endif
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine)
+{
+ unsigned long prot;
+
+ /*
+ * I/O space can be accessed via normal processor loads and stores on
+ * this platform but for now we elect not to do this and portable
+ * drivers should not do this anyway.
+ */
+ if (mmap_state == pci_mmap_io)
+ return -EINVAL;
+
+ /*
+ * Ignore write-combine; for now only return uncached mappings.
+ */
+ prot = pgprot_val(vma->vm_page_prot);
+ prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
+ vma->vm_page_prot = __pgprot(prot);
+
+ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
+char * (*pcibios_plat_setup)(char *str) __devinitdata;
+
+char *__devinit pcibios_setup(char *str)
+{
+ if (pcibios_plat_setup)
+ return pcibios_plat_setup(str);
+ return str;
+}
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c
new file mode 100644
index 00000000..0583c463
--- /dev/null
+++ b/arch/mips/pci/pcie-octeon.c
@@ -0,0 +1,1402 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007, 2008 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npei-defs.h>
+#include <asm/octeon/cvmx-pciercx-defs.h>
+#include <asm/octeon/cvmx-pescx-defs.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+#include <asm/octeon/cvmx-helper-errata.h>
+#include <asm/octeon/pci-octeon.h>
+
+union cvmx_pcie_address {
+ uint64_t u64;
+ struct {
+ uint64_t upper:2; /* Normally 2 for XKPHYS */
+ uint64_t reserved_49_61:13; /* Must be zero */
+ uint64_t io:1; /* 1 for IO space access */
+ uint64_t did:5; /* PCIe DID = 3 */
+ uint64_t subdid:3; /* PCIe SubDID = 1 */
+ uint64_t reserved_36_39:4; /* Must be zero */
+ uint64_t es:2; /* Endian swap = 1 */
+ uint64_t port:2; /* PCIe port 0,1 */
+ uint64_t reserved_29_31:3; /* Must be zero */
+ /*
+ * Selects the type of the configuration request (0 = type 0,
+ * 1 = type 1).
+ */
+ uint64_t ty:1;
+ /* Target bus number sent in the ID in the request. */
+ uint64_t bus:8;
+ /*
+ * Target device number sent in the ID in the
+ * request. Note that Dev must be zero for type 0
+ * configuration requests.
+ */
+ uint64_t dev:5;
+ /* Target function number sent in the ID in the request. */
+ uint64_t func:3;
+ /*
+ * Selects a register in the configuration space of
+ * the target.
+ */
+ uint64_t reg:12;
+ } config;
+ struct {
+ uint64_t upper:2; /* Normally 2 for XKPHYS */
+ uint64_t reserved_49_61:13; /* Must be zero */
+ uint64_t io:1; /* 1 for IO space access */
+ uint64_t did:5; /* PCIe DID = 3 */
+ uint64_t subdid:3; /* PCIe SubDID = 2 */
+ uint64_t reserved_36_39:4; /* Must be zero */
+ uint64_t es:2; /* Endian swap = 1 */
+ uint64_t port:2; /* PCIe port 0,1 */
+ uint64_t address:32; /* PCIe IO address */
+ } io;
+ struct {
+ uint64_t upper:2; /* Normally 2 for XKPHYS */
+ uint64_t reserved_49_61:13; /* Must be zero */
+ uint64_t io:1; /* 1 for IO space access */
+ uint64_t did:5; /* PCIe DID = 3 */
+ uint64_t subdid:3; /* PCIe SubDID = 3-6 */
+ uint64_t reserved_36_39:4; /* Must be zero */
+ uint64_t address:36; /* PCIe Mem address */
+ } mem;
+};
+
+#include <dma-coherence.h>
+
+/**
+ * Return the Core virtual base address for PCIe IO access. IOs are
+ * read/written as an offset from this address.
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns 64bit Octeon IO base address for read/write
+ */
+static inline uint64_t cvmx_pcie_get_io_base_address(int pcie_port)
+{
+ union cvmx_pcie_address pcie_addr;
+ pcie_addr.u64 = 0;
+ pcie_addr.io.upper = 0;
+ pcie_addr.io.io = 1;
+ pcie_addr.io.did = 3;
+ pcie_addr.io.subdid = 2;
+ pcie_addr.io.es = 1;
+ pcie_addr.io.port = pcie_port;
+ return pcie_addr.u64;
+}
+
+/**
+ * Size of the IO address region returned at address
+ * cvmx_pcie_get_io_base_address()
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns Size of the IO window
+ */
+static inline uint64_t cvmx_pcie_get_io_size(int pcie_port)
+{
+ return 1ull << 32;
+}
+
+/**
+ * Return the Core virtual base address for PCIe MEM access. Memory is
+ * read/written as an offset from this address.
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns 64bit Octeon IO base address for read/write
+ */
+static inline uint64_t cvmx_pcie_get_mem_base_address(int pcie_port)
+{
+ union cvmx_pcie_address pcie_addr;
+ pcie_addr.u64 = 0;
+ pcie_addr.mem.upper = 0;
+ pcie_addr.mem.io = 1;
+ pcie_addr.mem.did = 3;
+ pcie_addr.mem.subdid = 3 + pcie_port;
+ return pcie_addr.u64;
+}
+
+/**
+ * Size of the Mem address region returned at address
+ * cvmx_pcie_get_mem_base_address()
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns Size of the Mem window
+ */
+static inline uint64_t cvmx_pcie_get_mem_size(int pcie_port)
+{
+ return 1ull << 36;
+}
+
+/**
+ * Read a PCIe config space register indirectly. This is used for
+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
+ *
+ * @pcie_port: PCIe port to read from
+ * @cfg_offset: Address to read
+ *
+ * Returns Value read
+ */
+static uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset)
+{
+ union cvmx_pescx_cfg_rd pescx_cfg_rd;
+ pescx_cfg_rd.u64 = 0;
+ pescx_cfg_rd.s.addr = cfg_offset;
+ cvmx_write_csr(CVMX_PESCX_CFG_RD(pcie_port), pescx_cfg_rd.u64);
+ pescx_cfg_rd.u64 = cvmx_read_csr(CVMX_PESCX_CFG_RD(pcie_port));
+ return pescx_cfg_rd.s.data;
+}
+
+/**
+ * Write a PCIe config space register indirectly. This is used for
+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
+ *
+ * @pcie_port: PCIe port to write to
+ * @cfg_offset: Address to write
+ * @val: Value to write
+ */
+static void cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset,
+ uint32_t val)
+{
+ union cvmx_pescx_cfg_wr pescx_cfg_wr;
+ pescx_cfg_wr.u64 = 0;
+ pescx_cfg_wr.s.addr = cfg_offset;
+ pescx_cfg_wr.s.data = val;
+ cvmx_write_csr(CVMX_PESCX_CFG_WR(pcie_port), pescx_cfg_wr.u64);
+}
+
+/**
+ * Build a PCIe config space request address for a device
+ *
+ * @pcie_port: PCIe port to access
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ *
+ * Returns 64bit Octeon IO address
+ */
+static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus,
+ int dev, int fn, int reg)
+{
+ union cvmx_pcie_address pcie_addr;
+ union cvmx_pciercx_cfg006 pciercx_cfg006;
+
+ pciercx_cfg006.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port));
+ if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0))
+ return 0;
+
+ pcie_addr.u64 = 0;
+ pcie_addr.config.upper = 2;
+ pcie_addr.config.io = 1;
+ pcie_addr.config.did = 3;
+ pcie_addr.config.subdid = 1;
+ pcie_addr.config.es = 1;
+ pcie_addr.config.port = pcie_port;
+ pcie_addr.config.ty = (bus > pciercx_cfg006.s.pbnum);
+ pcie_addr.config.bus = bus;
+ pcie_addr.config.dev = dev;
+ pcie_addr.config.func = fn;
+ pcie_addr.config.reg = reg;
+ return pcie_addr.u64;
+}
+
+/**
+ * Read 8bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ *
+ * Returns Result of the read
+ */
+static uint8_t cvmx_pcie_config_read8(int pcie_port, int bus, int dev,
+ int fn, int reg)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ return cvmx_read64_uint8(address);
+ else
+ return 0xff;
+}
+
+/**
+ * Read 16bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ *
+ * Returns Result of the read
+ */
+static uint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev,
+ int fn, int reg)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ return le16_to_cpu(cvmx_read64_uint16(address));
+ else
+ return 0xffff;
+}
+
+/**
+ * Read 32bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ *
+ * Returns Result of the read
+ */
+static uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev,
+ int fn, int reg)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ return le32_to_cpu(cvmx_read64_uint32(address));
+ else
+ return 0xffffffff;
+}
+
+/**
+ * Write 8bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ * @val: Value to write
+ */
+static void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn,
+ int reg, uint8_t val)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ cvmx_write64_uint8(address, val);
+}
+
+/**
+ * Write 16bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ * @val: Value to write
+ */
+static void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn,
+ int reg, uint16_t val)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ cvmx_write64_uint16(address, cpu_to_le16(val));
+}
+
+/**
+ * Write 32bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus: Sub bus
+ * @dev: Device ID
+ * @fn: Device sub function
+ * @reg: Register to access
+ * @val: Value to write
+ */
+static void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn,
+ int reg, uint32_t val)
+{
+ uint64_t address =
+ __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+ if (address)
+ cvmx_write64_uint32(address, cpu_to_le32(val));
+}
+
+/**
+ * Initialize the RC config space CSRs
+ *
+ * @pcie_port: PCIe port to initialize
+ */
+static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
+{
+ union cvmx_pciercx_cfg030 pciercx_cfg030;
+ union cvmx_npei_ctl_status2 npei_ctl_status2;
+ union cvmx_pciercx_cfg070 pciercx_cfg070;
+ union cvmx_pciercx_cfg001 pciercx_cfg001;
+ union cvmx_pciercx_cfg032 pciercx_cfg032;
+ union cvmx_pciercx_cfg006 pciercx_cfg006;
+ union cvmx_pciercx_cfg008 pciercx_cfg008;
+ union cvmx_pciercx_cfg009 pciercx_cfg009;
+ union cvmx_pciercx_cfg010 pciercx_cfg010;
+ union cvmx_pciercx_cfg011 pciercx_cfg011;
+ union cvmx_pciercx_cfg035 pciercx_cfg035;
+ union cvmx_pciercx_cfg075 pciercx_cfg075;
+ union cvmx_pciercx_cfg034 pciercx_cfg034;
+
+ /* Max Payload Size (PCIE*_CFG030[MPS]) */
+ /* Max Read Request Size (PCIE*_CFG030[MRRS]) */
+ /* Relaxed-order, no-snoop enables (PCIE*_CFG030[RO_EN,NS_EN] */
+ /* Error Message Enables (PCIE*_CFG030[CE_EN,NFE_EN,FE_EN,UR_EN]) */
+ pciercx_cfg030.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG030(pcie_port));
+ /*
+ * Max payload size = 128 bytes for best Octeon DMA
+ * performance.
+ */
+ pciercx_cfg030.s.mps = 0;
+ /*
+ * Max read request size = 128 bytes for best Octeon DMA
+ * performance.
+ */
+ pciercx_cfg030.s.mrrs = 0;
+ /* Enable relaxed ordering. */
+ pciercx_cfg030.s.ro_en = 1;
+ /* Enable no snoop. */
+ pciercx_cfg030.s.ns_en = 1;
+ /* Correctable error reporting enable. */
+ pciercx_cfg030.s.ce_en = 1;
+ /* Non-fatal error reporting enable. */
+ pciercx_cfg030.s.nfe_en = 1;
+ /* Fatal error reporting enable. */
+ pciercx_cfg030.s.fe_en = 1;
+ /* Unsupported request reporting enable. */
+ pciercx_cfg030.s.ur_en = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG030(pcie_port),
+ pciercx_cfg030.u32);
+
+ /*
+ * Max Payload Size (NPEI_CTL_STATUS2[MPS]) must match
+ * PCIE*_CFG030[MPS]
+ *
+ * Max Read Request Size (NPEI_CTL_STATUS2[MRRS]) must not
+ * exceed PCIE*_CFG030[MRRS].
+ */
+ npei_ctl_status2.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS2);
+ /* Max payload size = 128 bytes for best Octeon DMA performance */
+ npei_ctl_status2.s.mps = 0;
+ /* Max read request size = 128 bytes for best Octeon DMA performance */
+ npei_ctl_status2.s.mrrs = 0;
+ if (pcie_port)
+ npei_ctl_status2.s.c1_b1_s = 3; /* Port1 BAR1 Size 256MB */
+ else
+ npei_ctl_status2.s.c0_b1_s = 3; /* Port0 BAR1 Size 256MB */
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64);
+
+ /* ECRC Generation (PCIE*_CFG070[GE,CE]) */
+ pciercx_cfg070.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG070(pcie_port));
+ pciercx_cfg070.s.ge = 1; /* ECRC generation enable. */
+ pciercx_cfg070.s.ce = 1; /* ECRC check enable. */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG070(pcie_port),
+ pciercx_cfg070.u32);
+
+ /*
+ * Access Enables (PCIE*_CFG001[MSAE,ME]) ME and MSAE should
+ * always be set.
+ *
+ * Interrupt Disable (PCIE*_CFG001[I_DIS]) System Error
+ * Message Enable (PCIE*_CFG001[SEE])
+ */
+ pciercx_cfg001.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG001(pcie_port));
+ pciercx_cfg001.s.msae = 1; /* Memory space enable. */
+ pciercx_cfg001.s.me = 1; /* Bus master enable. */
+ pciercx_cfg001.s.i_dis = 1; /* INTx assertion disable. */
+ pciercx_cfg001.s.see = 1; /* SERR# enable */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG001(pcie_port),
+ pciercx_cfg001.u32);
+
+ /* Advanced Error Recovery Message Enables */
+ /* (PCIE*_CFG066,PCIE*_CFG067,PCIE*_CFG069) */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG066(pcie_port), 0);
+ /* Use CVMX_PCIERCX_CFG067 hardware default */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG069(pcie_port), 0);
+
+ /* Active State Power Management (PCIE*_CFG032[ASLPC]) */
+ pciercx_cfg032.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ pciercx_cfg032.s.aslpc = 0; /* Active state Link PM control. */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG032(pcie_port),
+ pciercx_cfg032.u32);
+
+ /* Entrance Latencies (PCIE*_CFG451[L0EL,L1EL]) */
+
+ /*
+ * Link Width Mode (PCIERCn_CFG452[LME]) - Set during
+ * cvmx_pcie_rc_initialize_link()
+ *
+ * Primary Bus Number (PCIERCn_CFG006[PBNUM])
+ *
+ * We set the primary bus number to 1 so IDT bridges are
+ * happy. They don't like zero.
+ */
+ pciercx_cfg006.u32 = 0;
+ pciercx_cfg006.s.pbnum = 1;
+ pciercx_cfg006.s.sbnum = 1;
+ pciercx_cfg006.s.subbnum = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG006(pcie_port),
+ pciercx_cfg006.u32);
+
+ /*
+ * Memory-mapped I/O BAR (PCIERCn_CFG008)
+ * Most applications should disable the memory-mapped I/O BAR by
+ * setting PCIERCn_CFG008[ML_ADDR] < PCIERCn_CFG008[MB_ADDR]
+ */
+ pciercx_cfg008.u32 = 0;
+ pciercx_cfg008.s.mb_addr = 0x100;
+ pciercx_cfg008.s.ml_addr = 0;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG008(pcie_port),
+ pciercx_cfg008.u32);
+
+ /*
+ * Prefetchable BAR (PCIERCn_CFG009,PCIERCn_CFG010,PCIERCn_CFG011)
+ * Most applications should disable the prefetchable BAR by setting
+ * PCIERCn_CFG011[UMEM_LIMIT],PCIERCn_CFG009[LMEM_LIMIT] <
+ * PCIERCn_CFG010[UMEM_BASE],PCIERCn_CFG009[LMEM_BASE]
+ */
+ pciercx_cfg009.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG009(pcie_port));
+ pciercx_cfg010.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG010(pcie_port));
+ pciercx_cfg011.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG011(pcie_port));
+ pciercx_cfg009.s.lmem_base = 0x100;
+ pciercx_cfg009.s.lmem_limit = 0;
+ pciercx_cfg010.s.umem_base = 0x100;
+ pciercx_cfg011.s.umem_limit = 0;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG009(pcie_port),
+ pciercx_cfg009.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG010(pcie_port),
+ pciercx_cfg010.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG011(pcie_port),
+ pciercx_cfg011.u32);
+
+ /*
+ * System Error Interrupt Enables (PCIERCn_CFG035[SECEE,SEFEE,SENFEE])
+ * PME Interrupt Enables (PCIERCn_CFG035[PMEIE])
+ */
+ pciercx_cfg035.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG035(pcie_port));
+ /* System error on correctable error enable. */
+ pciercx_cfg035.s.secee = 1;
+ /* System error on fatal error enable. */
+ pciercx_cfg035.s.sefee = 1;
+ /* System error on non-fatal error enable. */
+ pciercx_cfg035.s.senfee = 1;
+ /* PME interrupt enable. */
+ pciercx_cfg035.s.pmeie = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG035(pcie_port),
+ pciercx_cfg035.u32);
+
+ /*
+ * Advanced Error Recovery Interrupt Enables
+ * (PCIERCn_CFG075[CERE,NFERE,FERE])
+ */
+ pciercx_cfg075.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG075(pcie_port));
+ /* Correctable error reporting enable. */
+ pciercx_cfg075.s.cere = 1;
+ /* Non-fatal error reporting enable. */
+ pciercx_cfg075.s.nfere = 1;
+ /* Fatal error reporting enable. */
+ pciercx_cfg075.s.fere = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG075(pcie_port),
+ pciercx_cfg075.u32);
+
+ /* HP Interrupt Enables (PCIERCn_CFG034[HPINT_EN],
+ * PCIERCn_CFG034[DLLS_EN,CCINT_EN])
+ */
+ pciercx_cfg034.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG034(pcie_port));
+ /* Hot-plug interrupt enable. */
+ pciercx_cfg034.s.hpint_en = 1;
+ /* Data Link Layer state changed enable */
+ pciercx_cfg034.s.dlls_en = 1;
+ /* Command completed interrupt enable. */
+ pciercx_cfg034.s.ccint_en = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG034(pcie_port),
+ pciercx_cfg034.u32);
+}
+
+/**
+ * Initialize a host mode PCIe link. This function takes a PCIe
+ * port from reset to a link up state. Software can then begin
+ * configuring the rest of the link.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Returns Zero on success
+ */
+static int __cvmx_pcie_rc_initialize_link(int pcie_port)
+{
+ uint64_t start_cycle;
+ union cvmx_pescx_ctl_status pescx_ctl_status;
+ union cvmx_pciercx_cfg452 pciercx_cfg452;
+ union cvmx_pciercx_cfg032 pciercx_cfg032;
+ union cvmx_pciercx_cfg448 pciercx_cfg448;
+
+ /* Set the lane width */
+ pciercx_cfg452.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG452(pcie_port));
+ pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
+ if (pescx_ctl_status.s.qlm_cfg == 0) {
+ /* We're in 8 lane (56XX) or 4 lane (54XX) mode */
+ pciercx_cfg452.s.lme = 0xf;
+ } else {
+ /* We're in 4 lane (56XX) or 2 lane (52XX) mode */
+ pciercx_cfg452.s.lme = 0x7;
+ }
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG452(pcie_port),
+ pciercx_cfg452.u32);
+
+ /*
+ * CN52XX pass 1.x has an errata where length mismatches on UR
+ * responses can cause bus errors on 64bit memory
+ * reads. Turning off length error checking fixes this.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ union cvmx_pciercx_cfg455 pciercx_cfg455;
+ pciercx_cfg455.u32 =
+ cvmx_pcie_cfgx_read(pcie_port,
+ CVMX_PCIERCX_CFG455(pcie_port));
+ pciercx_cfg455.s.m_cpl_len_err = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG455(pcie_port),
+ pciercx_cfg455.u32);
+ }
+
+ /* Lane swap needs to be manually enabled for CN52XX */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) && (pcie_port == 1)) {
+ pescx_ctl_status.s.lane_swp = 1;
+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port),
+ pescx_ctl_status.u64);
+ }
+
+ /* Bring up the link */
+ pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
+ pescx_ctl_status.s.lnk_enb = 1;
+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port), pescx_ctl_status.u64);
+
+ /*
+ * CN52XX pass 1.0: Due to a bug in 2nd order CDR, it needs to
+ * be disabled.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
+ __cvmx_helper_errata_qlm_disable_2nd_order_cdr(0);
+
+ /* Wait for the link to come up */
+ cvmx_dprintf("PCIe: Waiting for port %d link\n", pcie_port);
+ start_cycle = cvmx_get_cycle();
+ do {
+ if (cvmx_get_cycle() - start_cycle >
+ 2 * cvmx_sysinfo_get()->cpu_clock_hz) {
+ cvmx_dprintf("PCIe: Port %d link timeout\n",
+ pcie_port);
+ return -1;
+ }
+ cvmx_wait(10000);
+ pciercx_cfg032.u32 =
+ cvmx_pcie_cfgx_read(pcie_port,
+ CVMX_PCIERCX_CFG032(pcie_port));
+ } while (pciercx_cfg032.s.dlla == 0);
+
+ /* Display the link status */
+ cvmx_dprintf("PCIe: Port %d link active, %d lanes\n", pcie_port,
+ pciercx_cfg032.s.nlw);
+
+ /*
+ * Update the Replay Time Limit. Empirically, some PCIe
+ * devices take a little longer to respond than expected under
+ * load. As a workaround for this we configure the Replay Time
+ * Limit to the value expected for a 512 byte MPS instead of
+ * our actual 256 byte MPS. The numbers below are directly
+ * from the PCIe spec table 3-4.
+ */
+ pciercx_cfg448.u32 =
+ cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port));
+ switch (pciercx_cfg032.s.nlw) {
+ case 1: /* 1 lane */
+ pciercx_cfg448.s.rtl = 1677;
+ break;
+ case 2: /* 2 lanes */
+ pciercx_cfg448.s.rtl = 867;
+ break;
+ case 4: /* 4 lanes */
+ pciercx_cfg448.s.rtl = 462;
+ break;
+ case 8: /* 8 lanes */
+ pciercx_cfg448.s.rtl = 258;
+ break;
+ }
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port),
+ pciercx_cfg448.u32);
+
+ return 0;
+}
+
+/**
+ * Initialize a PCIe port for use in host(RC) mode. It doesn't
+ * enumerate the bus.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Returns Zero on success
+ */
+static int cvmx_pcie_rc_initialize(int pcie_port)
+{
+ int i;
+ int base;
+ u64 addr_swizzle;
+ union cvmx_ciu_soft_prst ciu_soft_prst;
+ union cvmx_pescx_bist_status pescx_bist_status;
+ union cvmx_pescx_bist_status2 pescx_bist_status2;
+ union cvmx_npei_ctl_status npei_ctl_status;
+ union cvmx_npei_mem_access_ctl npei_mem_access_ctl;
+ union cvmx_npei_mem_access_subidx mem_access_subid;
+ union cvmx_npei_dbg_data npei_dbg_data;
+ union cvmx_pescx_ctl_status2 pescx_ctl_status2;
+ union cvmx_npei_bar1_indexx bar1_index;
+
+ /*
+ * Make sure we aren't trying to setup a target mode interface
+ * in host mode.
+ */
+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+ if ((pcie_port == 0) && !npei_ctl_status.s.host_mode) {
+ cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() called "
+ "on port0, but port0 is not in host mode\n");
+ return -1;
+ }
+
+ /*
+ * Make sure a CN52XX isn't trying to bring up port 1 when it
+ * is disabled.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+ npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+ if ((pcie_port == 1) && npei_dbg_data.cn52xx.qlm0_link_width) {
+ cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() "
+ "called on port1, but port1 is "
+ "disabled\n");
+ return -1;
+ }
+ }
+
+ /*
+ * PCIe switch arbitration mode. '0' == fixed priority NPEI,
+ * PCIe0, then PCIe1. '1' == round robin.
+ */
+ npei_ctl_status.s.arb = 1;
+ /* Allow up to 0x20 config retries */
+ npei_ctl_status.s.cfg_rtry = 0x20;
+ /*
+ * CN52XX pass1.x has an errata where P0_NTAGS and P1_NTAGS
+ * don't reset.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ npei_ctl_status.s.p0_ntags = 0x20;
+ npei_ctl_status.s.p1_ntags = 0x20;
+ }
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS, npei_ctl_status.u64);
+
+ /* Bring the PCIe out of reset */
+ if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBH5200) {
+ /*
+ * The EBH5200 board swapped the PCIe reset lines on
+ * the board. As a workaround for this bug, we bring
+ * both PCIe ports out of reset at the same time
+ * instead of on separate calls. So for port 0, we
+ * bring both out of reset and do nothing on port 1.
+ */
+ if (pcie_port == 0) {
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ /*
+ * After a chip reset the PCIe will also be in
+ * reset. If it isn't, most likely someone is
+ * trying to init it again without a proper
+ * PCIe reset.
+ */
+ if (ciu_soft_prst.s.soft_prst == 0) {
+ /* Reset the ports */
+ ciu_soft_prst.s.soft_prst = 1;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST,
+ ciu_soft_prst.u64);
+ ciu_soft_prst.u64 =
+ cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ ciu_soft_prst.s.soft_prst = 1;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1,
+ ciu_soft_prst.u64);
+ /* Wait until pcie resets the ports. */
+ udelay(2000);
+ }
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+ }
+ } else {
+ /*
+ * The normal case: The PCIe ports are completely
+ * separate and can be brought out of reset
+ * independently.
+ */
+ if (pcie_port)
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ else
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ /*
+ * After a chip reset the PCIe will also be in
+ * reset. If it isn't, most likely someone is trying
+ * to init it again without a proper PCIe reset.
+ */
+ if (ciu_soft_prst.s.soft_prst == 0) {
+ /* Reset the port */
+ ciu_soft_prst.s.soft_prst = 1;
+ if (pcie_port)
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1,
+ ciu_soft_prst.u64);
+ else
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST,
+ ciu_soft_prst.u64);
+ /* Wait until pcie resets the ports. */
+ udelay(2000);
+ }
+ if (pcie_port) {
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
+ } else {
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+ }
+ }
+
+ /*
+ * Wait for PCIe reset to complete. Due to errata PCIE-700, we
+ * don't poll PESCX_CTL_STATUS2[PCIERST], but simply wait a
+ * fixed number of cycles.
+ */
+ cvmx_wait(400000);
+
+ /* PESCX_BIST_STATUS2[PCLK_RUN] was missing on pass 1 of CN56XX and
+ CN52XX, so we only probe it on newer chips */
+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+ && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ /* Clear PCLK_RUN so we can check if the clock is running */
+ pescx_ctl_status2.u64 =
+ cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
+ pescx_ctl_status2.s.pclk_run = 1;
+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS2(pcie_port),
+ pescx_ctl_status2.u64);
+ /*
+ * Now that we cleared PCLK_RUN, wait for it to be set
+ * again telling us the clock is running.
+ */
+ if (CVMX_WAIT_FOR_FIELD64(CVMX_PESCX_CTL_STATUS2(pcie_port),
+ union cvmx_pescx_ctl_status2,
+ pclk_run, ==, 1, 10000)) {
+ cvmx_dprintf("PCIe: Port %d isn't clocked, skipping.\n",
+ pcie_port);
+ return -1;
+ }
+ }
+
+ /*
+ * Check and make sure PCIe came out of reset. If it doesn't
+ * the board probably hasn't wired the clocks up and the
+ * interface should be skipped.
+ */
+ pescx_ctl_status2.u64 =
+ cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
+ if (pescx_ctl_status2.s.pcierst) {
+ cvmx_dprintf("PCIe: Port %d stuck in reset, skipping.\n",
+ pcie_port);
+ return -1;
+ }
+
+ /*
+ * Check BIST2 status. If any bits are set skip this interface. This
+ * is an attempt to catch PCIE-813 on pass 1 parts.
+ */
+ pescx_bist_status2.u64 =
+ cvmx_read_csr(CVMX_PESCX_BIST_STATUS2(pcie_port));
+ if (pescx_bist_status2.u64) {
+ cvmx_dprintf("PCIe: Port %d BIST2 failed. Most likely this "
+ "port isn't hooked up, skipping.\n",
+ pcie_port);
+ return -1;
+ }
+
+ /* Check BIST status */
+ pescx_bist_status.u64 =
+ cvmx_read_csr(CVMX_PESCX_BIST_STATUS(pcie_port));
+ if (pescx_bist_status.u64)
+ cvmx_dprintf("PCIe: BIST FAILED for port %d (0x%016llx)\n",
+ pcie_port, CAST64(pescx_bist_status.u64));
+
+ /* Initialize the config space CSRs */
+ __cvmx_pcie_rc_initialize_config_space(pcie_port);
+
+ /* Bring the link up */
+ if (__cvmx_pcie_rc_initialize_link(pcie_port)) {
+ cvmx_dprintf
+ ("PCIe: ERROR: cvmx_pcie_rc_initialize_link() failed\n");
+ return -1;
+ }
+
+ /* Store merge control (NPEI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */
+ npei_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL);
+ /* Allow 16 words to combine */
+ npei_mem_access_ctl.s.max_word = 0;
+ /* Wait up to 127 cycles for more data */
+ npei_mem_access_ctl.s.timer = 127;
+ cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL, npei_mem_access_ctl.u64);
+
+ /* Setup Mem access SubDIDs */
+ mem_access_subid.u64 = 0;
+ /* Port the request is sent to. */
+ mem_access_subid.s.port = pcie_port;
+ /* Due to an errata on pass 1 chips, no merging is allowed. */
+ mem_access_subid.s.nmerge = 1;
+ /* Endian-swap for Reads. */
+ mem_access_subid.s.esr = 1;
+ /* Endian-swap for Writes. */
+ mem_access_subid.s.esw = 1;
+ /* No Snoop for Reads. */
+ mem_access_subid.s.nsr = 1;
+ /* No Snoop for Writes. */
+ mem_access_subid.s.nsw = 1;
+ /* Disable Relaxed Ordering for Reads. */
+ mem_access_subid.s.ror = 0;
+ /* Disable Relaxed Ordering for Writes. */
+ mem_access_subid.s.row = 0;
+ /* PCIe Address Bits <63:34>. */
+ mem_access_subid.s.ba = 0;
+
+ /*
+ * Setup mem access 12-15 for port 0, 16-19 for port 1,
+ * supplying 36 bits of address space.
+ */
+ for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) {
+ cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(i),
+ mem_access_subid.u64);
+ /* Set each SUBID to extend the addressable range */
+ mem_access_subid.s.ba += 1;
+ }
+
+ /*
+ * Disable the peer to peer forwarding register. This must be
+ * setup by the OS after it enumerates the bus and assigns
+ * addresses to the PCIe busses.
+ */
+ for (i = 0; i < 4; i++) {
+ cvmx_write_csr(CVMX_PESCX_P2P_BARX_START(i, pcie_port), -1);
+ cvmx_write_csr(CVMX_PESCX_P2P_BARX_END(i, pcie_port), -1);
+ }
+
+ /* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
+ cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0);
+
+ /* BAR1 follows BAR2 with a gap. */
+ cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), CVMX_PCIE_BAR1_RC_BASE);
+
+ bar1_index.u32 = 0;
+ bar1_index.s.addr_idx = (CVMX_PCIE_BAR1_PHYS_BASE >> 22);
+ bar1_index.s.ca = 1; /* Not Cached */
+ bar1_index.s.end_swp = 1; /* Endian Swap mode */
+ bar1_index.s.addr_v = 1; /* Valid entry */
+
+ base = pcie_port ? 16 : 0;
+
+ /* Big endian swizzle for 32-bit PEXP_NCB register. */
+#ifdef __MIPSEB__
+ addr_swizzle = 4;
+#else
+ addr_swizzle = 0;
+#endif
+ for (i = 0; i < 16; i++) {
+ cvmx_write64_uint32((CVMX_PEXP_NPEI_BAR1_INDEXX(base) ^ addr_swizzle),
+ bar1_index.u32);
+ base++;
+ /* 256MB / 16 >> 22 == 4 */
+ bar1_index.s.addr_idx += (((1ull << 28) / 16ull) >> 22);
+ }
+
+ /*
+ * Set Octeon's BAR2 to decode 0-2^39. Bar0 and Bar1 take
+ * precedence where they overlap. It also overlaps with the
+ * device addresses, so make sure the peer to peer forwarding
+ * is set right.
+ */
+ cvmx_write_csr(CVMX_PESCX_P2N_BAR2_START(pcie_port), 0);
+
+ /*
+ * Setup BAR2 attributes
+ *
+ * Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM])
+ * - PTLP_RO,CTLP_RO should normally be set (except for debug).
+ * - WAIT_COM=0 will likely work for all applications.
+ *
+ * Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM]).
+ */
+ if (pcie_port) {
+ union cvmx_npei_ctl_port1 npei_ctl_port;
+ npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT1);
+ npei_ctl_port.s.bar2_enb = 1;
+ npei_ctl_port.s.bar2_esx = 1;
+ npei_ctl_port.s.bar2_cax = 0;
+ npei_ctl_port.s.ptlp_ro = 1;
+ npei_ctl_port.s.ctlp_ro = 1;
+ npei_ctl_port.s.wait_com = 0;
+ npei_ctl_port.s.waitl_com = 0;
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT1, npei_ctl_port.u64);
+ } else {
+ union cvmx_npei_ctl_port0 npei_ctl_port;
+ npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT0);
+ npei_ctl_port.s.bar2_enb = 1;
+ npei_ctl_port.s.bar2_esx = 1;
+ npei_ctl_port.s.bar2_cax = 0;
+ npei_ctl_port.s.ptlp_ro = 1;
+ npei_ctl_port.s.ctlp_ro = 1;
+ npei_ctl_port.s.wait_com = 0;
+ npei_ctl_port.s.waitl_com = 0;
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT0, npei_ctl_port.u64);
+ }
+ return 0;
+}
+
+
+/* Above was cvmx-pcie.c, below original pcie.c */
+
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @dev: The Linux PCI device structure for the device to map
+ * @slot: The slot number for this device on __BUS 0__. Linux
+ * enumerates through all the bridges and figures out the
+ * slot on Bus 0 where this device eventually hooks to.
+ * @pin: The PCI interrupt pin read from the device, then swizzled
+ * as it goes through each bridge.
+ * Returns Interrupt number for the device
+ */
+int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev,
+ u8 slot, u8 pin)
+{
+ /*
+ * The EBH5600 board with the PCI to PCIe bridge mistakenly
+ * wires the first slot for both device id 2 and interrupt
+ * A. According to the PCI spec, device id 2 should be C. The
+ * following kludge attempts to fix this.
+ */
+ if (strstr(octeon_board_type_string(), "EBH5600") &&
+ dev->bus && dev->bus->parent) {
+ /*
+ * Iterate all the way up the device chain and find
+ * the root bus.
+ */
+ while (dev->bus && dev->bus->parent)
+ dev = to_pci_dev(dev->bus->bridge);
+ /* If the root bus is number 0 and the PEX 8114 is the
+ * root, assume we are behind the miswired bus. We
+ * need to correct the swizzle level by two. Yuck.
+ */
+ if ((dev->bus->number == 0) &&
+ (dev->vendor == 0x10b5) && (dev->device == 0x8114)) {
+ /*
+ * The pin field is one based, not zero. We
+ * need to swizzle it by minus two.
+ */
+ pin = ((pin - 3) & 3) + 1;
+ }
+ }
+ /*
+ * The -1 is because pin starts with one, not zero. It might
+ * be that this equation needs to include the slot number, but
+ * I don't have hardware to check that against.
+ */
+ return pin - 1 + OCTEON_IRQ_PCI_INT0;
+}
+
+/**
+ * Read a value from configuration space
+ *
+ * @bus:
+ * @devfn:
+ * @reg:
+ * @size:
+ * @val:
+ * Returns
+ */
+static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus,
+ unsigned int devfn, int reg, int size,
+ u32 *val)
+{
+ union octeon_cvmemctl cvmmemctl;
+ union octeon_cvmemctl cvmmemctl_save;
+ int bus_number = bus->number;
+
+ /*
+ * For the top level bus make sure our hardware bus number
+ * matches the software one.
+ */
+ if (bus->parent == NULL) {
+ union cvmx_pciercx_cfg006 pciercx_cfg006;
+ pciercx_cfg006.u32 = cvmx_pcie_cfgx_read(pcie_port,
+ CVMX_PCIERCX_CFG006(pcie_port));
+ if (pciercx_cfg006.s.pbnum != bus_number) {
+ pciercx_cfg006.s.pbnum = bus_number;
+ pciercx_cfg006.s.sbnum = bus_number;
+ pciercx_cfg006.s.subbnum = bus_number;
+ cvmx_pcie_cfgx_write(pcie_port,
+ CVMX_PCIERCX_CFG006(pcie_port),
+ pciercx_cfg006.u32);
+ }
+ }
+
+ /*
+ * PCIe only has a single device connected to Octeon. It is
+ * always device ID 0. Don't bother doing reads for other
+ * device IDs on the first segment.
+ */
+ if ((bus->parent == NULL) && (devfn >> 3 != 0))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+
+ /*
+ * The following is a workaround for the CN57XX, CN56XX,
+ * CN55XX, and CN54XX errata with PCIe config reads from non
+ * existent devices. These chips will hang the PCIe link if a
+ * config read is performed that causes a UR response.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1)) {
+ /*
+ * For our EBH5600 board, port 0 has a bridge with two
+ * PCI-X slots. We need a new special checks to make
+ * sure we only probe valid stuff. The PCIe->PCI-X
+ * bridge only respondes to device ID 0, function
+ * 0-1
+ */
+ if ((bus->parent == NULL) && (devfn >= 2))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ /*
+ * The PCI-X slots are device ID 2,3. Choose one of
+ * the below "if" blocks based on what is plugged into
+ * the board.
+ */
+#if 1
+ /* Use this option if you aren't using either slot */
+ if (bus_number == 1)
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+ /*
+ * Use this option if you are using the first slot but
+ * not the second.
+ */
+ if ((bus_number == 1) && (devfn >> 3 != 2))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+ /*
+ * Use this option if you are using the second slot
+ * but not the first.
+ */
+ if ((bus_number == 1) && (devfn >> 3 != 3))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+ /* Use this opion if you are using both slots */
+ if ((bus_number == 1) &&
+ !((devfn == (2 << 3)) || (devfn == (3 << 3))))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#endif
+
+ /*
+ * Shorten the DID timeout so bus errors for PCIe
+ * config reads from non existent devices happen
+ * faster. This allows us to continue booting even if
+ * the above "if" checks are wrong. Once one of these
+ * errors happens, the PCIe port is dead.
+ */
+ cvmmemctl_save.u64 = __read_64bit_c0_register($11, 7);
+ cvmmemctl.u64 = cvmmemctl_save.u64;
+ cvmmemctl.s.didtto = 2;
+ __write_64bit_c0_register($11, 7, cvmmemctl.u64);
+ }
+
+ switch (size) {
+ case 4:
+ *val = cvmx_pcie_config_read32(pcie_port, bus_number,
+ devfn >> 3, devfn & 0x7, reg);
+ break;
+ case 2:
+ *val = cvmx_pcie_config_read16(pcie_port, bus_number,
+ devfn >> 3, devfn & 0x7, reg);
+ break;
+ case 1:
+ *val = cvmx_pcie_config_read8(pcie_port, bus_number, devfn >> 3,
+ devfn & 0x7, reg);
+ break;
+ default:
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ }
+
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1))
+ __write_64bit_c0_register($11, 7, cvmmemctl_save.u64);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int octeon_pcie0_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ return octeon_pcie_read_config(0, bus, devfn, reg, size, val);
+}
+
+static int octeon_pcie1_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ return octeon_pcie_read_config(1, bus, devfn, reg, size, val);
+}
+
+
+
+/**
+ * Write a value to PCI configuration space
+ *
+ * @bus:
+ * @devfn:
+ * @reg:
+ * @size:
+ * @val:
+ * Returns
+ */
+static inline int octeon_pcie_write_config(int pcie_port, struct pci_bus *bus,
+ unsigned int devfn, int reg,
+ int size, u32 val)
+{
+ int bus_number = bus->number;
+
+ switch (size) {
+ case 4:
+ cvmx_pcie_config_write32(pcie_port, bus_number, devfn >> 3,
+ devfn & 0x7, reg, val);
+ return PCIBIOS_SUCCESSFUL;
+ case 2:
+ cvmx_pcie_config_write16(pcie_port, bus_number, devfn >> 3,
+ devfn & 0x7, reg, val);
+ return PCIBIOS_SUCCESSFUL;
+ case 1:
+ cvmx_pcie_config_write8(pcie_port, bus_number, devfn >> 3,
+ devfn & 0x7, reg, val);
+ return PCIBIOS_SUCCESSFUL;
+ }
+#if PCI_CONFIG_SPACE_DELAY
+ udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+static int octeon_pcie0_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ return octeon_pcie_write_config(0, bus, devfn, reg, size, val);
+}
+
+static int octeon_pcie1_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ return octeon_pcie_write_config(1, bus, devfn, reg, size, val);
+}
+
+static struct pci_ops octeon_pcie0_ops = {
+ octeon_pcie0_read_config,
+ octeon_pcie0_write_config,
+};
+
+static struct resource octeon_pcie0_mem_resource = {
+ .name = "Octeon PCIe0 MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource octeon_pcie0_io_resource = {
+ .name = "Octeon PCIe0 IO",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pcie0_controller = {
+ .pci_ops = &octeon_pcie0_ops,
+ .mem_resource = &octeon_pcie0_mem_resource,
+ .io_resource = &octeon_pcie0_io_resource,
+};
+
+static struct pci_ops octeon_pcie1_ops = {
+ octeon_pcie1_read_config,
+ octeon_pcie1_write_config,
+};
+
+static struct resource octeon_pcie1_mem_resource = {
+ .name = "Octeon PCIe1 MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource octeon_pcie1_io_resource = {
+ .name = "Octeon PCIe1 IO",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pcie1_controller = {
+ .pci_ops = &octeon_pcie1_ops,
+ .mem_resource = &octeon_pcie1_mem_resource,
+ .io_resource = &octeon_pcie1_io_resource,
+};
+
+
+/**
+ * Initialize the Octeon PCIe controllers
+ *
+ * Returns
+ */
+static int __init octeon_pcie_setup(void)
+{
+ union cvmx_npei_ctl_status npei_ctl_status;
+ int result;
+
+ /* These chips don't have PCIe */
+ if (!octeon_has_feature(OCTEON_FEATURE_PCIE))
+ return 0;
+
+ /* Point pcibios_map_irq() to the PCIe version of it */
+ octeon_pcibios_map_irq = octeon_pcie_pcibios_map_irq;
+
+ /* Use the PCIe based DMA mappings */
+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE;
+
+ /*
+ * PCIe I/O range. It is based on port 0 but includes up until
+ * port 1's end.
+ */
+ set_io_port_base(CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(0)));
+ ioport_resource.start = 0;
+ ioport_resource.end =
+ cvmx_pcie_get_io_base_address(1) -
+ cvmx_pcie_get_io_base_address(0) + cvmx_pcie_get_io_size(1) - 1;
+
+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+ if (npei_ctl_status.s.host_mode) {
+ pr_notice("PCIe: Initializing port 0\n");
+ result = cvmx_pcie_rc_initialize(0);
+ if (result == 0) {
+ /* Memory offsets are physical addresses */
+ octeon_pcie0_controller.mem_offset =
+ cvmx_pcie_get_mem_base_address(0);
+ /* IO offsets are Mips virtual addresses */
+ octeon_pcie0_controller.io_map_base =
+ CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address
+ (0));
+ octeon_pcie0_controller.io_offset = 0;
+ /*
+ * To keep things similar to PCI, we start
+ * device addresses at the same place as PCI
+ * uisng big bar support. This normally
+ * translates to 4GB-256MB, which is the same
+ * as most x86 PCs.
+ */
+ octeon_pcie0_controller.mem_resource->start =
+ cvmx_pcie_get_mem_base_address(0) +
+ (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+ octeon_pcie0_controller.mem_resource->end =
+ cvmx_pcie_get_mem_base_address(0) +
+ cvmx_pcie_get_mem_size(0) - 1;
+ /*
+ * Ports must be above 16KB for the ISA bus
+ * filtering in the PCI-X to PCI bridge.
+ */
+ octeon_pcie0_controller.io_resource->start = 4 << 10;
+ octeon_pcie0_controller.io_resource->end =
+ cvmx_pcie_get_io_size(0) - 1;
+ register_pci_controller(&octeon_pcie0_controller);
+ }
+ } else {
+ pr_notice("PCIe: Port 0 in endpoint mode, skipping.\n");
+ }
+
+ /* Skip the 2nd port on CN52XX if port 0 is in 4 lane mode */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+ union cvmx_npei_dbg_data npei_dbg_data;
+ npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+ if (npei_dbg_data.cn52xx.qlm0_link_width)
+ return 0;
+ }
+
+ pr_notice("PCIe: Initializing port 1\n");
+ result = cvmx_pcie_rc_initialize(1);
+ if (result == 0) {
+ /* Memory offsets are physical addresses */
+ octeon_pcie1_controller.mem_offset =
+ cvmx_pcie_get_mem_base_address(1);
+ /* IO offsets are Mips virtual addresses */
+ octeon_pcie1_controller.io_map_base =
+ CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(1));
+ octeon_pcie1_controller.io_offset =
+ cvmx_pcie_get_io_base_address(1) -
+ cvmx_pcie_get_io_base_address(0);
+ /*
+ * To keep things similar to PCI, we start device
+ * addresses at the same place as PCI uisng big bar
+ * support. This normally translates to 4GB-256MB,
+ * which is the same as most x86 PCs.
+ */
+ octeon_pcie1_controller.mem_resource->start =
+ cvmx_pcie_get_mem_base_address(1) + (4ul << 30) -
+ (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+ octeon_pcie1_controller.mem_resource->end =
+ cvmx_pcie_get_mem_base_address(1) +
+ cvmx_pcie_get_mem_size(1) - 1;
+ /*
+ * Ports must be above 16KB for the ISA bus filtering
+ * in the PCI-X to PCI bridge.
+ */
+ octeon_pcie1_controller.io_resource->start =
+ cvmx_pcie_get_io_base_address(1) -
+ cvmx_pcie_get_io_base_address(0);
+ octeon_pcie1_controller.io_resource->end =
+ octeon_pcie1_controller.io_resource->start +
+ cvmx_pcie_get_io_size(1) - 1;
+ register_pci_controller(&octeon_pcie1_controller);
+ }
+
+ octeon_pci_dma_init();
+
+ return 0;
+}
+
+arch_initcall(octeon_pcie_setup);
diff --git a/arch/mips/pmc-sierra/Kconfig b/arch/mips/pmc-sierra/Kconfig
new file mode 100644
index 00000000..bbd76082
--- /dev/null
+++ b/arch/mips/pmc-sierra/Kconfig
@@ -0,0 +1,52 @@
+choice
+ prompt "PMC-Sierra MSP SOC type"
+ depends on PMC_MSP
+
+config PMC_MSP4200_EVAL
+ bool "PMC-Sierra MSP4200 Eval Board"
+ select IRQ_MSP_SLP
+ select HW_HAS_PCI
+
+config PMC_MSP4200_GW
+ bool "PMC-Sierra MSP4200 VoIP Gateway"
+ select IRQ_MSP_SLP
+ select HW_HAS_PCI
+
+config PMC_MSP7120_EVAL
+ bool "PMC-Sierra MSP7120 Eval Board"
+ select SYS_SUPPORTS_MULTITHREADING
+ select IRQ_MSP_CIC
+ select HW_HAS_PCI
+
+config PMC_MSP7120_GW
+ bool "PMC-Sierra MSP7120 Residential Gateway"
+ select SYS_SUPPORTS_MULTITHREADING
+ select IRQ_MSP_CIC
+ select HW_HAS_PCI
+ select MSP_HAS_USB
+ select MSP_ETH
+
+config PMC_MSP7120_FPGA
+ bool "PMC-Sierra MSP7120 FPGA"
+ select SYS_SUPPORTS_MULTITHREADING
+ select IRQ_MSP_CIC
+ select HW_HAS_PCI
+
+endchoice
+
+config HYPERTRANSPORT
+ bool "Hypertransport Support for PMC-Sierra Yosemite"
+ depends on PMC_YOSEMITE
+
+config MSP_HAS_USB
+ boolean
+ depends on PMC_MSP
+
+config MSP_ETH
+ boolean
+ select MSP_HAS_MAC
+ depends on PMC_MSP
+
+config MSP_HAS_MAC
+ boolean
+ depends on PMC_MSP
diff --git a/arch/mips/pmc-sierra/Platform b/arch/mips/pmc-sierra/Platform
new file mode 100644
index 00000000..f092f252
--- /dev/null
+++ b/arch/mips/pmc-sierra/Platform
@@ -0,0 +1,14 @@
+#
+# PMC-Sierra MSP SOCs
+#
+platform-$(CONFIG_PMC_MSP) += pmc-sierra/msp71xx/
+cflags-$(CONFIG_PMC_MSP) += -I$(srctree)/arch/mips/include/asm/pmc-sierra/msp71xx \
+ -mno-branch-likely
+load-$(CONFIG_PMC_MSP) += 0xffffffff80100000
+
+#
+# PMC-Sierra Yosemite
+#
+platform-$(CONFIG_PMC_YOSEMITE) += pmc-sierra/yosemite/
+cflags-$(CONFIG_PMC_YOSEMITE) += -I$(srctree)/arch/mips/include/asm/mach-yosemite
+load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000
diff --git a/arch/mips/pmc-sierra/msp71xx/Makefile b/arch/mips/pmc-sierra/msp71xx/Makefile
new file mode 100644
index 00000000..cefba773
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the PMC-Sierra MSP SOCs
+#
+obj-y += msp_prom.o msp_setup.o msp_irq.o \
+ msp_time.o msp_serial.o msp_elb.o
+obj-$(CONFIG_HAVE_GPIO_LIB) += gpio.o gpio_extended.o
+obj-$(CONFIG_PMC_MSP7120_GW) += msp_hwbutton.o
+obj-$(CONFIG_IRQ_MSP_SLP) += msp_irq_slp.o
+obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o
+obj-$(CONFIG_PCI) += msp_pci.o
+obj-$(CONFIG_MSP_HAS_MAC) += msp_eth.o
+obj-$(CONFIG_MSP_HAS_USB) += msp_usb.o
+obj-$(CONFIG_MIPS_MT_SMP) += msp_smp.o
+obj-$(CONFIG_MIPS_MT_SMTC) += msp_smtc.o
diff --git a/arch/mips/pmc-sierra/msp71xx/gpio.c b/arch/mips/pmc-sierra/msp71xx/gpio.c
new file mode 100644
index 00000000..aaccbe52
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/gpio.c
@@ -0,0 +1,216 @@
+/*
+ * Generic PMC MSP71xx GPIO handling. These base gpio are controlled by two
+ * types of registers. The data register sets the output level when in output
+ * mode and when in input mode will contain the value at the input. The config
+ * register sets the various modes for each gpio.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * @author Patrick Glass <patrickglass@gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#define MSP71XX_CFG_OFFSET(gpio) (4 * (gpio))
+#define CONF_MASK 0x0F
+#define MSP71XX_GPIO_INPUT 0x01
+#define MSP71XX_GPIO_OUTPUT 0x08
+
+#define MSP71XX_GPIO_BASE 0x0B8400000L
+
+#define to_msp71xx_gpio_chip(c) container_of(c, struct msp71xx_gpio_chip, chip)
+
+static spinlock_t gpio_lock;
+
+/*
+ * struct msp71xx_gpio_chip - container for gpio chip and registers
+ * @chip: chip structure for the specified gpio bank
+ * @data_reg: register for reading and writing the gpio pin value
+ * @config_reg: register to set the mode for the gpio pin bank
+ * @out_drive_reg: register to set the output drive mode for the gpio pin bank
+ */
+struct msp71xx_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *data_reg;
+ void __iomem *config_reg;
+ void __iomem *out_drive_reg;
+};
+
+/*
+ * msp71xx_gpio_get() - return the chip's gpio value
+ * @chip: chip structure which controls the specified gpio
+ * @offset: gpio whose value will be returned
+ *
+ * It will return 0 if gpio value is low and other if high.
+ */
+static int msp71xx_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
+
+ return __raw_readl(msp_chip->data_reg) & (1 << offset);
+}
+
+/*
+ * msp71xx_gpio_set() - set the output value for the gpio
+ * @chip: chip structure who controls the specified gpio
+ * @offset: gpio whose value will be assigned
+ * @value: logic level to assign to the gpio initially
+ *
+ * This will set the gpio bit specified to the desired value. It will set the
+ * gpio pin low if value is 0 otherwise it will be high.
+ */
+static void msp71xx_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
+ unsigned long flags;
+ u32 data;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ data = __raw_readl(msp_chip->data_reg);
+ if (value)
+ data |= (1 << offset);
+ else
+ data &= ~(1 << offset);
+ __raw_writel(data, msp_chip->data_reg);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+}
+
+/*
+ * msp71xx_set_gpio_mode() - declare the mode for a gpio
+ * @chip: chip structure which controls the specified gpio
+ * @offset: gpio whose value will be assigned
+ * @mode: desired configuration for the gpio (see datasheet)
+ *
+ * It will set the gpio pin config to the @mode value passed in.
+ */
+static int msp71xx_set_gpio_mode(struct gpio_chip *chip,
+ unsigned offset, int mode)
+{
+ struct msp71xx_gpio_chip *msp_chip = to_msp71xx_gpio_chip(chip);
+ const unsigned bit_offset = MSP71XX_CFG_OFFSET(offset);
+ unsigned long flags;
+ u32 cfg;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ cfg = __raw_readl(msp_chip->config_reg);
+ cfg &= ~(CONF_MASK << bit_offset);
+ cfg |= (mode << bit_offset);
+ __raw_writel(cfg, msp_chip->config_reg);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+
+ return 0;
+}
+
+/*
+ * msp71xx_direction_output() - declare the direction mode for a gpio
+ * @chip: chip structure which controls the specified gpio
+ * @offset: gpio whose value will be assigned
+ * @value: logic level to assign to the gpio initially
+ *
+ * This call will set the mode for the @gpio to output. It will set the
+ * gpio pin low if value is 0 otherwise it will be high.
+ */
+static int msp71xx_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ msp71xx_gpio_set(chip, offset, value);
+
+ return msp71xx_set_gpio_mode(chip, offset, MSP71XX_GPIO_OUTPUT);
+}
+
+/*
+ * msp71xx_direction_input() - declare the direction mode for a gpio
+ * @chip: chip structure which controls the specified gpio
+ * @offset: gpio whose to which the value will be assigned
+ *
+ * This call will set the mode for the @gpio to input.
+ */
+static int msp71xx_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ return msp71xx_set_gpio_mode(chip, offset, MSP71XX_GPIO_INPUT);
+}
+
+/*
+ * msp71xx_set_output_drive() - declare the output drive for the gpio line
+ * @gpio: gpio pin whose output drive you wish to modify
+ * @value: zero for active drain 1 for open drain drive
+ *
+ * This call will set the output drive mode for the @gpio to output.
+ */
+int msp71xx_set_output_drive(unsigned gpio, int value)
+{
+ unsigned long flags;
+ u32 data;
+
+ if (gpio > 15 || gpio < 0)
+ return -EINVAL;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ data = __raw_readl((void __iomem *)(MSP71XX_GPIO_BASE + 0x190));
+ if (value)
+ data |= (1 << gpio);
+ else
+ data &= ~(1 << gpio);
+ __raw_writel(data, (void __iomem *)(MSP71XX_GPIO_BASE + 0x190));
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(msp71xx_set_output_drive);
+
+#define MSP71XX_GPIO_BANK(name, dr, cr, base_gpio, num_gpio) \
+{ \
+ .chip = { \
+ .label = name, \
+ .direction_input = msp71xx_direction_input, \
+ .direction_output = msp71xx_direction_output, \
+ .get = msp71xx_gpio_get, \
+ .set = msp71xx_gpio_set, \
+ .base = base_gpio, \
+ .ngpio = num_gpio \
+ }, \
+ .data_reg = (void __iomem *)(MSP71XX_GPIO_BASE + dr), \
+ .config_reg = (void __iomem *)(MSP71XX_GPIO_BASE + cr), \
+ .out_drive_reg = (void __iomem *)(MSP71XX_GPIO_BASE + 0x190), \
+}
+
+/*
+ * struct msp71xx_gpio_banks[] - container array of gpio banks
+ * @chip: chip structure for the specified gpio bank
+ * @data_reg: register for reading and writing the gpio pin value
+ * @config_reg: register to set the mode for the gpio pin bank
+ *
+ * This array structure defines the gpio banks for the PMC MIPS Processor.
+ * We specify the bank name, the data register, the config register, base
+ * starting gpio number, and the number of gpios exposed by the bank.
+ */
+static struct msp71xx_gpio_chip msp71xx_gpio_banks[] = {
+
+ MSP71XX_GPIO_BANK("GPIO_1_0", 0x170, 0x180, 0, 2),
+ MSP71XX_GPIO_BANK("GPIO_5_2", 0x174, 0x184, 2, 4),
+ MSP71XX_GPIO_BANK("GPIO_9_6", 0x178, 0x188, 6, 4),
+ MSP71XX_GPIO_BANK("GPIO_15_10", 0x17C, 0x18C, 10, 6),
+};
+
+void __init msp71xx_init_gpio(void)
+{
+ int i;
+
+ spin_lock_init(&gpio_lock);
+
+ for (i = 0; i < ARRAY_SIZE(msp71xx_gpio_banks); i++)
+ gpiochip_add(&msp71xx_gpio_banks[i].chip);
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/gpio_extended.c b/arch/mips/pmc-sierra/msp71xx/gpio_extended.c
new file mode 100644
index 00000000..2a99f360
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/gpio_extended.c
@@ -0,0 +1,146 @@
+/*
+ * Generic PMC MSP71xx EXTENDED (EXD) GPIO handling. The extended gpio is
+ * a set of hardware registers that have no need for explicit locking as
+ * it is handled by unique method of writing individual set/clr bits.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * @author Patrick Glass <patrickglass@gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#define MSP71XX_DATA_OFFSET(gpio) (2 * (gpio))
+#define MSP71XX_READ_OFFSET(gpio) (MSP71XX_DATA_OFFSET(gpio) + 1)
+#define MSP71XX_CFG_OUT_OFFSET(gpio) (MSP71XX_DATA_OFFSET(gpio) + 16)
+#define MSP71XX_CFG_IN_OFFSET(gpio) (MSP71XX_CFG_OUT_OFFSET(gpio) + 1)
+
+#define MSP71XX_EXD_GPIO_BASE 0x0BC000000L
+
+#define to_msp71xx_exd_gpio_chip(c) \
+ container_of(c, struct msp71xx_exd_gpio_chip, chip)
+
+/*
+ * struct msp71xx_exd_gpio_chip - container for gpio chip and registers
+ * @chip: chip structure for the specified gpio bank
+ * @reg: register for control and data of gpio pin
+ */
+struct msp71xx_exd_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *reg;
+};
+
+/*
+ * msp71xx_exd_gpio_get() - return the chip's gpio value
+ * @chip: chip structure which controls the specified gpio
+ * @offset: gpio whose value will be returned
+ *
+ * It will return 0 if gpio value is low and other if high.
+ */
+static int msp71xx_exd_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct msp71xx_exd_gpio_chip *msp71xx_chip =
+ to_msp71xx_exd_gpio_chip(chip);
+ const unsigned bit = MSP71XX_READ_OFFSET(offset);
+
+ return __raw_readl(msp71xx_chip->reg) & (1 << bit);
+}
+
+/*
+ * msp71xx_exd_gpio_set() - set the output value for the gpio
+ * @chip: chip structure who controls the specified gpio
+ * @offset: gpio whose value will be assigned
+ * @value: logic level to assign to the gpio initially
+ *
+ * This will set the gpio bit specified to the desired value. It will set the
+ * gpio pin low if value is 0 otherwise it will be high.
+ */
+static void msp71xx_exd_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct msp71xx_exd_gpio_chip *msp71xx_chip =
+ to_msp71xx_exd_gpio_chip(chip);
+ const unsigned bit = MSP71XX_DATA_OFFSET(offset);
+
+ __raw_writel(1 << (bit + (value ? 1 : 0)), msp71xx_chip->reg);
+}
+
+/*
+ * msp71xx_exd_direction_output() - declare the direction mode for a gpio
+ * @chip: chip structure which controls the specified gpio
+ * @offset: gpio whose value will be assigned
+ * @value: logic level to assign to the gpio initially
+ *
+ * This call will set the mode for the @gpio to output. It will set the
+ * gpio pin low if value is 0 otherwise it will be high.
+ */
+static int msp71xx_exd_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct msp71xx_exd_gpio_chip *msp71xx_chip =
+ to_msp71xx_exd_gpio_chip(chip);
+
+ msp71xx_exd_gpio_set(chip, offset, value);
+ __raw_writel(1 << MSP71XX_CFG_OUT_OFFSET(offset), msp71xx_chip->reg);
+ return 0;
+}
+
+/*
+ * msp71xx_exd_direction_input() - declare the direction mode for a gpio
+ * @chip: chip structure which controls the specified gpio
+ * @offset: gpio whose to which the value will be assigned
+ *
+ * This call will set the mode for the @gpio to input.
+ */
+static int msp71xx_exd_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct msp71xx_exd_gpio_chip *msp71xx_chip =
+ to_msp71xx_exd_gpio_chip(chip);
+
+ __raw_writel(1 << MSP71XX_CFG_IN_OFFSET(offset), msp71xx_chip->reg);
+ return 0;
+}
+
+#define MSP71XX_EXD_GPIO_BANK(name, exd_reg, base_gpio, num_gpio) \
+{ \
+ .chip = { \
+ .label = name, \
+ .direction_input = msp71xx_exd_direction_input, \
+ .direction_output = msp71xx_exd_direction_output, \
+ .get = msp71xx_exd_gpio_get, \
+ .set = msp71xx_exd_gpio_set, \
+ .base = base_gpio, \
+ .ngpio = num_gpio, \
+ }, \
+ .reg = (void __iomem *)(MSP71XX_EXD_GPIO_BASE + exd_reg), \
+}
+
+/*
+ * struct msp71xx_exd_gpio_banks[] - container array of gpio banks
+ * @chip: chip structure for the specified gpio bank
+ * @reg: register for reading and writing the gpio pin value
+ *
+ * This array structure defines the extended gpio banks for the
+ * PMC MIPS Processor. We specify the bank name, the data/config
+ * register,the base starting gpio number, and the number of
+ * gpios exposed by the bank of gpios.
+ */
+static struct msp71xx_exd_gpio_chip msp71xx_exd_gpio_banks[] = {
+
+ MSP71XX_EXD_GPIO_BANK("GPIO_23_16", 0x188, 16, 8),
+ MSP71XX_EXD_GPIO_BANK("GPIO_27_24", 0x18C, 24, 4),
+};
+
+void __init msp71xx_init_gpio_extended(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(msp71xx_exd_gpio_banks); i++)
+ gpiochip_add(&msp71xx_exd_gpio_banks[i].chip);
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_elb.c b/arch/mips/pmc-sierra/msp71xx/msp_elb.c
new file mode 100644
index 00000000..3e964100
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_elb.c
@@ -0,0 +1,46 @@
+/*
+ * Sets up the proper Chip Select configuration registers. It is assumed that
+ * PMON sets up the ADDR and MASK registers properly.
+ *
+ * Copyright 2005-2006 PMC-Sierra, Inc.
+ * Author: Marc St-Jean, Marc_St-Jean@pmc-sierra.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <msp_regs.h>
+
+static int __init msp_elb_setup(void)
+{
+#if defined(CONFIG_PMC_MSP7120_GW) \
+ || defined(CONFIG_PMC_MSP7120_EVAL)
+ /*
+ * Force all CNFG to be identical and equal to CS0,
+ * according to OPS doc
+ */
+ *CS1_CNFG_REG = *CS2_CNFG_REG = *CS3_CNFG_REG = *CS0_CNFG_REG;
+#endif
+ return 0;
+}
+
+subsys_initcall(msp_elb_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_eth.c b/arch/mips/pmc-sierra/msp71xx/msp_eth.c
new file mode 100644
index 00000000..c584df39
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_eth.c
@@ -0,0 +1,187 @@
+/*
+ * The setup file for ethernet related hardware on PMC-Sierra MSP processors.
+ *
+ * Copyright 2010 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <msp_regs.h>
+#include <msp_int.h>
+#include <msp_gpio_macros.h>
+
+
+#define MSP_ETHERNET_GPIO0 14
+#define MSP_ETHERNET_GPIO1 15
+#define MSP_ETHERNET_GPIO2 16
+
+#ifdef CONFIG_MSP_HAS_TSMAC
+#define MSP_TSMAC_SIZE 0x10020
+#define MSP_TSMAC_ID "pmc_tsmac"
+
+static struct resource msp_tsmac0_resources[] = {
+ [0] = {
+ .start = MSP_MAC0_BASE,
+ .end = MSP_MAC0_BASE + MSP_TSMAC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_MAC0,
+ .end = MSP_INT_MAC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msp_tsmac1_resources[] = {
+ [0] = {
+ .start = MSP_MAC1_BASE,
+ .end = MSP_MAC1_BASE + MSP_TSMAC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_MAC1,
+ .end = MSP_INT_MAC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct resource msp_tsmac2_resources[] = {
+ [0] = {
+ .start = MSP_MAC2_BASE,
+ .end = MSP_MAC2_BASE + MSP_TSMAC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_SAR,
+ .end = MSP_INT_SAR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static struct platform_device tsmac_device[] = {
+ [0] = {
+ .name = MSP_TSMAC_ID,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(msp_tsmac0_resources),
+ .resource = msp_tsmac0_resources,
+ },
+ [1] = {
+ .name = MSP_TSMAC_ID,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(msp_tsmac1_resources),
+ .resource = msp_tsmac1_resources,
+ },
+ [2] = {
+ .name = MSP_TSMAC_ID,
+ .id = 2,
+ .num_resources = ARRAY_SIZE(msp_tsmac2_resources),
+ .resource = msp_tsmac2_resources,
+ },
+};
+#define msp_eth_devs tsmac_device
+
+#else
+/* If it is not TSMAC assume MSP_ETH (100Mbps) */
+#define MSP_ETH_ID "pmc_mspeth"
+#define MSP_ETH_SIZE 0xE0
+static struct resource msp_eth0_resources[] = {
+ [0] = {
+ .start = MSP_MAC0_BASE,
+ .end = MSP_MAC0_BASE + MSP_ETH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_MAC0,
+ .end = MSP_INT_MAC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msp_eth1_resources[] = {
+ [0] = {
+ .start = MSP_MAC1_BASE,
+ .end = MSP_MAC1_BASE + MSP_ETH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_MAC1,
+ .end = MSP_INT_MAC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+
+static struct platform_device mspeth_device[] = {
+ [0] = {
+ .name = MSP_ETH_ID,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(msp_eth0_resources),
+ .resource = msp_eth0_resources,
+ },
+ [1] = {
+ .name = MSP_ETH_ID,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(msp_eth1_resources),
+ .resource = msp_eth1_resources,
+ },
+
+};
+#define msp_eth_devs mspeth_device
+
+#endif
+int __init msp_eth_setup(void)
+{
+ int i, ret = 0;
+
+ /* Configure the GPIO and take the ethernet PHY out of reset */
+ msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO0);
+ msp_gpio_pin_hi(MSP_ETHERNET_GPIO0);
+
+#ifdef CONFIG_MSP_HAS_TSMAC
+ /* 3 phys on boards with TSMAC */
+ msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO1);
+ msp_gpio_pin_hi(MSP_ETHERNET_GPIO1);
+
+ msp_gpio_pin_mode(MSP_GPIO_OUTPUT, MSP_ETHERNET_GPIO2);
+ msp_gpio_pin_hi(MSP_ETHERNET_GPIO2);
+#endif
+ for (i = 0; i < ARRAY_SIZE(msp_eth_devs); i++) {
+ ret = platform_device_register(&msp_eth_devs[i]);
+ printk(KERN_INFO "device: %d, return value = %d\n", i, ret);
+ if (ret) {
+ platform_device_unregister(&msp_eth_devs[i]);
+ break;
+ }
+ }
+
+ if (ret)
+ printk(KERN_WARNING "Could not initialize "
+ "MSPETH device structures.\n");
+
+ return ret;
+}
+subsys_initcall(msp_eth_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
new file mode 100644
index 00000000..c841f083
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
@@ -0,0 +1,165 @@
+/*
+ * Sets up interrupt handlers for various hardware switches which are
+ * connected to interrupt lines.
+ *
+ * Copyright 2005-2207 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <msp_int.h>
+#include <msp_regs.h>
+#include <msp_regops.h>
+
+/* For hwbutton_interrupt->initial_state */
+#define HWBUTTON_HI 0x1
+#define HWBUTTON_LO 0x2
+
+/*
+ * This struct describes a hardware button
+ */
+struct hwbutton_interrupt {
+ char *name; /* Name of button */
+ int irq; /* Actual LINUX IRQ */
+ int eirq; /* Extended IRQ number (0-7) */
+ int initial_state; /* The "normal" state of the switch */
+ void (*handle_hi)(void *); /* Handler: switch input has gone HI */
+ void (*handle_lo)(void *); /* Handler: switch input has gone LO */
+ void *data; /* Optional data to pass to handler */
+};
+
+#ifdef CONFIG_PMC_MSP7120_GW
+extern void msp_restart(char *);
+
+static void softreset_push(void *data)
+{
+ printk(KERN_WARNING "SOFTRESET switch was pushed\n");
+
+ /*
+ * In the future you could move this to the release handler,
+ * timing the difference between the 'push' and 'release', and only
+ * doing this ungraceful restart if the button has been down for
+ * a certain amount of time; otherwise doing a graceful restart.
+ */
+
+ msp_restart(NULL);
+}
+
+static void softreset_release(void *data)
+{
+ printk(KERN_WARNING "SOFTRESET switch was released\n");
+
+ /* Do nothing */
+}
+
+static void standby_on(void *data)
+{
+ printk(KERN_WARNING "STANDBY switch was set to ON (not implemented)\n");
+
+ /* TODO: Put board in standby mode */
+}
+
+static void standby_off(void *data)
+{
+ printk(KERN_WARNING
+ "STANDBY switch was set to OFF (not implemented)\n");
+
+ /* TODO: Take out of standby mode */
+}
+
+static struct hwbutton_interrupt softreset_sw = {
+ .name = "Softreset button",
+ .irq = MSP_INT_EXT0,
+ .eirq = 0,
+ .initial_state = HWBUTTON_HI,
+ .handle_hi = softreset_release,
+ .handle_lo = softreset_push,
+ .data = NULL,
+};
+
+static struct hwbutton_interrupt standby_sw = {
+ .name = "Standby switch",
+ .irq = MSP_INT_EXT1,
+ .eirq = 1,
+ .initial_state = HWBUTTON_HI,
+ .handle_hi = standby_off,
+ .handle_lo = standby_on,
+ .data = NULL,
+};
+#endif /* CONFIG_PMC_MSP7120_GW */
+
+static irqreturn_t hwbutton_handler(int irq, void *data)
+{
+ struct hwbutton_interrupt *hirq = data;
+ unsigned long cic_ext = *CIC_EXT_CFG_REG;
+
+ if (CIC_EXT_IS_ACTIVE_HI(cic_ext, hirq->eirq)) {
+ /* Interrupt: pin is now HI */
+ CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
+ hirq->handle_hi(hirq->data);
+ } else {
+ /* Interrupt: pin is now LO */
+ CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
+ hirq->handle_lo(hirq->data);
+ }
+
+ /*
+ * Invert the POLARITY of this level interrupt to ack the interrupt
+ * Thus next state change will invoke the opposite message
+ */
+ *CIC_EXT_CFG_REG = cic_ext;
+
+ return IRQ_HANDLED;
+}
+
+static int msp_hwbutton_register(struct hwbutton_interrupt *hirq)
+{
+ unsigned long cic_ext;
+
+ if (hirq->handle_hi == NULL || hirq->handle_lo == NULL)
+ return -EINVAL;
+
+ cic_ext = *CIC_EXT_CFG_REG;
+ CIC_EXT_SET_TRIGGER_LEVEL(cic_ext, hirq->eirq);
+ if (hirq->initial_state == HWBUTTON_HI)
+ CIC_EXT_SET_ACTIVE_LO(cic_ext, hirq->eirq);
+ else
+ CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
+ *CIC_EXT_CFG_REG = cic_ext;
+
+ return request_irq(hirq->irq, hwbutton_handler, IRQF_DISABLED,
+ hirq->name, hirq);
+}
+
+static int __init msp_hwbutton_setup(void)
+{
+#ifdef CONFIG_PMC_MSP7120_GW
+ msp_hwbutton_register(&softreset_sw);
+ msp_hwbutton_register(&standby_sw);
+#endif
+ return 0;
+}
+
+subsys_initcall(msp_hwbutton_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c
new file mode 100644
index 00000000..4531c4a5
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c
@@ -0,0 +1,162 @@
+/*
+ * IRQ vector handles
+ *
+ * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/time.h>
+
+#include <asm/irq_cpu.h>
+
+#include <msp_int.h>
+
+/* SLP bases systems */
+extern void msp_slp_irq_init(void);
+extern void msp_slp_irq_dispatch(void);
+
+/* CIC based systems */
+extern void msp_cic_irq_init(void);
+extern void msp_cic_irq_dispatch(void);
+
+/* VSMP support init */
+extern void msp_vsmp_int_init(void);
+
+/* vectored interrupt implementation */
+
+/* SW0/1 interrupts are used for SMP/SMTC */
+static inline void mac0_int_dispatch(void) { do_IRQ(MSP_INT_MAC0); }
+static inline void mac1_int_dispatch(void) { do_IRQ(MSP_INT_MAC1); }
+static inline void mac2_int_dispatch(void) { do_IRQ(MSP_INT_SAR); }
+static inline void usb_int_dispatch(void) { do_IRQ(MSP_INT_USB); }
+static inline void sec_int_dispatch(void) { do_IRQ(MSP_INT_SEC); }
+
+/*
+ * The PMC-Sierra MSP interrupts are arranged in a 3 level cascaded
+ * hierarchical system. The first level are the direct MIPS interrupts
+ * and are assigned the interrupt range 0-7. The second level is the SLM
+ * interrupt controller and is assigned the range 8-39. The third level
+ * comprises the Peripherial block, the PCI block, the PCI MSI block and
+ * the SLP. The PCI interrupts and the SLP errors are handled by the
+ * relevant subsystems so the core interrupt code needs only concern
+ * itself with the Peripheral block. These are assigned interrupts in
+ * the range 40-71.
+ */
+
+asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
+{
+ u32 pending;
+
+ pending = read_c0_status() & read_c0_cause();
+
+ /*
+ * jump to the correct interrupt routine
+ * These are arranged in priority order and the timer
+ * comes first!
+ */
+
+#ifdef CONFIG_IRQ_MSP_CIC /* break out the CIC stuff for now */
+ if (pending & C_IRQ4) /* do the peripherals first, that's the timer */
+ msp_cic_irq_dispatch();
+
+ else if (pending & C_IRQ0)
+ do_IRQ(MSP_INT_MAC0);
+
+ else if (pending & C_IRQ1)
+ do_IRQ(MSP_INT_MAC1);
+
+ else if (pending & C_IRQ2)
+ do_IRQ(MSP_INT_USB);
+
+ else if (pending & C_IRQ3)
+ do_IRQ(MSP_INT_SAR);
+
+ else if (pending & C_IRQ5)
+ do_IRQ(MSP_INT_SEC);
+
+#else
+ if (pending & C_IRQ5)
+ do_IRQ(MSP_INT_TIMER);
+
+ else if (pending & C_IRQ0)
+ do_IRQ(MSP_INT_MAC0);
+
+ else if (pending & C_IRQ1)
+ do_IRQ(MSP_INT_MAC1);
+
+ else if (pending & C_IRQ3)
+ do_IRQ(MSP_INT_VE);
+
+ else if (pending & C_IRQ4)
+ msp_slp_irq_dispatch();
+#endif
+
+ else if (pending & C_SW0) /* do software after hardware */
+ do_IRQ(MSP_INT_SW0);
+
+ else if (pending & C_SW1)
+ do_IRQ(MSP_INT_SW1);
+}
+
+static struct irqaction cic_cascade_msp = {
+ .handler = no_action,
+ .name = "MSP CIC cascade"
+};
+
+static struct irqaction per_cascade_msp = {
+ .handler = no_action,
+ .name = "MSP PER cascade"
+};
+
+void __init arch_init_irq(void)
+{
+ /* assume we'll be using vectored interrupt mode except in UP mode*/
+#ifdef CONFIG_MIPS_MT
+ BUG_ON(!cpu_has_vint);
+#endif
+ /* initialize the 1st-level CPU based interrupt controller */
+ mips_cpu_irq_init();
+
+#ifdef CONFIG_IRQ_MSP_CIC
+ msp_cic_irq_init();
+#ifdef CONFIG_MIPS_MT
+ set_vi_handler(MSP_INT_CIC, msp_cic_irq_dispatch);
+ set_vi_handler(MSP_INT_MAC0, mac0_int_dispatch);
+ set_vi_handler(MSP_INT_MAC1, mac1_int_dispatch);
+ set_vi_handler(MSP_INT_SAR, mac2_int_dispatch);
+ set_vi_handler(MSP_INT_USB, usb_int_dispatch);
+ set_vi_handler(MSP_INT_SEC, sec_int_dispatch);
+#ifdef CONFIG_MIPS_MT_SMP
+ msp_vsmp_int_init();
+#elif defined CONFIG_MIPS_MT_SMTC
+ /*Set hwmask for all platform devices */
+ irq_hwmask[MSP_INT_MAC0] = C_IRQ0;
+ irq_hwmask[MSP_INT_MAC1] = C_IRQ1;
+ irq_hwmask[MSP_INT_USB] = C_IRQ2;
+ irq_hwmask[MSP_INT_SAR] = C_IRQ3;
+ irq_hwmask[MSP_INT_SEC] = C_IRQ5;
+
+#endif /* CONFIG_MIPS_MT_SMP */
+#endif /* CONFIG_MIPS_MT */
+ /* setup the cascaded interrupts */
+ setup_irq(MSP_INT_CIC, &cic_cascade_msp);
+ setup_irq(MSP_INT_PER, &per_cascade_msp);
+
+#else
+ /* setup the 2nd-level SLP register based interrupt controller */
+ /* VSMP /SMTC support support is not enabled for SLP */
+ msp_slp_irq_init();
+
+ /* setup the cascaded SLP/PER interrupts */
+ setup_irq(MSP_INT_SLP, &cic_cascade_msp);
+ setup_irq(MSP_INT_PER, &per_cascade_msp);
+#endif
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
new file mode 100644
index 00000000..c4fa2d77
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c
+ *
+ * This file define the irq handler for MSP CIC subsystem interrupts.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/irq.h>
+
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <msp_cic_int.h>
+#include <msp_regs.h>
+
+/*
+ * External API
+ */
+extern void msp_per_irq_init(void);
+extern void msp_per_irq_dispatch(void);
+
+
+/*
+ * Convenience Macro. Should be somewhere generic.
+ */
+#define get_current_vpe() \
+ ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
+
+#ifdef CONFIG_SMP
+
+#define LOCK_VPE(flags, mtflags) \
+do { \
+ local_irq_save(flags); \
+ mtflags = dmt(); \
+} while (0)
+
+#define UNLOCK_VPE(flags, mtflags) \
+do { \
+ emt(mtflags); \
+ local_irq_restore(flags);\
+} while (0)
+
+#define LOCK_CORE(flags, mtflags) \
+do { \
+ local_irq_save(flags); \
+ mtflags = dvpe(); \
+} while (0)
+
+#define UNLOCK_CORE(flags, mtflags) \
+do { \
+ evpe(mtflags); \
+ local_irq_restore(flags);\
+} while (0)
+
+#else
+
+#define LOCK_VPE(flags, mtflags)
+#define UNLOCK_VPE(flags, mtflags)
+#endif
+
+/* ensure writes to cic are completed */
+static inline void cic_wmb(void)
+{
+ const volatile void __iomem *cic_mem = CIC_VPE0_MSK_REG;
+ volatile u32 dummy_read;
+
+ wmb();
+ dummy_read = __raw_readl(cic_mem);
+ dummy_read++;
+}
+
+static void unmask_cic_irq(struct irq_data *d)
+{
+ volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG;
+ int vpe;
+#ifdef CONFIG_SMP
+ unsigned int mtflags;
+ unsigned long flags;
+
+ /*
+ * Make sure we have IRQ affinity. It may have changed while
+ * we were processing the IRQ.
+ */
+ if (!cpumask_test_cpu(smp_processor_id(), d->affinity))
+ return;
+#endif
+
+ vpe = get_current_vpe();
+ LOCK_VPE(flags, mtflags);
+ cic_msk_reg[vpe] |= (1 << (d->irq - MSP_CIC_INTBASE));
+ UNLOCK_VPE(flags, mtflags);
+ cic_wmb();
+}
+
+static void mask_cic_irq(struct irq_data *d)
+{
+ volatile u32 *cic_msk_reg = CIC_VPE0_MSK_REG;
+ int vpe = get_current_vpe();
+#ifdef CONFIG_SMP
+ unsigned long flags, mtflags;
+#endif
+ LOCK_VPE(flags, mtflags);
+ cic_msk_reg[vpe] &= ~(1 << (d->irq - MSP_CIC_INTBASE));
+ UNLOCK_VPE(flags, mtflags);
+ cic_wmb();
+}
+static void msp_cic_irq_ack(struct irq_data *d)
+{
+ mask_cic_irq(d);
+ /*
+ * Only really necessary for 18, 16-14 and sometimes 3:0
+ * (since these can be edge sensitive) but it doesn't
+ * hurt for the others
+ */
+ *CIC_STS_REG = (1 << (d->irq - MSP_CIC_INTBASE));
+ smtc_im_ack_irq(d->irq);
+}
+
+/*Note: Limiting to VSMP . Not tested in SMTC */
+
+#ifdef CONFIG_MIPS_MT_SMP
+static int msp_cic_irq_set_affinity(struct irq_data *d,
+ const struct cpumask *cpumask, bool force)
+{
+ int cpu;
+ unsigned long flags;
+ unsigned int mtflags;
+ unsigned long imask = (1 << (irq - MSP_CIC_INTBASE));
+ volatile u32 *cic_mask = (volatile u32 *)CIC_VPE0_MSK_REG;
+
+ /* timer balancing should be disabled in kernel code */
+ BUG_ON(irq == MSP_INT_VPE0_TIMER || irq == MSP_INT_VPE1_TIMER);
+
+ LOCK_CORE(flags, mtflags);
+ /* enable if any of each VPE's TCs require this IRQ */
+ for_each_online_cpu(cpu) {
+ if (cpumask_test_cpu(cpu, cpumask))
+ cic_mask[cpu] |= imask;
+ else
+ cic_mask[cpu] &= ~imask;
+
+ }
+
+ UNLOCK_CORE(flags, mtflags);
+ return 0;
+
+}
+#endif
+
+static struct irq_chip msp_cic_irq_controller = {
+ .name = "MSP_CIC",
+ .irq_mask = mask_cic_irq,
+ .irq_mask_ack = msp_cic_irq_ack,
+ .irq_unmask = unmask_cic_irq,
+ .irq_ack = msp_cic_irq_ack,
+#ifdef CONFIG_MIPS_MT_SMP
+ .irq_set_affinity = msp_cic_irq_set_affinity,
+#endif
+};
+
+void __init msp_cic_irq_init(void)
+{
+ int i;
+ /* Mask/clear interrupts. */
+ *CIC_VPE0_MSK_REG = 0x00000000;
+ *CIC_VPE1_MSK_REG = 0x00000000;
+ *CIC_STS_REG = 0xFFFFFFFF;
+ /*
+ * The MSP7120 RG and EVBD boards use IRQ[6:4] for PCI.
+ * These inputs map to EXT_INT_POL[6:4] inside the CIC.
+ * They are to be active low, level sensitive.
+ */
+ *CIC_EXT_CFG_REG &= 0xFFFF8F8F;
+
+ /* initialize all the IRQ descriptors */
+ for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) {
+ irq_set_chip_and_handler(i, &msp_cic_irq_controller,
+ handle_level_irq);
+#ifdef CONFIG_MIPS_MT_SMTC
+ /* Mask of CIC interrupt */
+ irq_hwmask[i] = C_IRQ4;
+#endif
+ }
+
+ /* Initialize the PER interrupt sub-system */
+ msp_per_irq_init();
+}
+
+/* CIC masked by CIC vector processing before dispatch called */
+void msp_cic_irq_dispatch(void)
+{
+ volatile u32 *cic_msk_reg = (volatile u32 *)CIC_VPE0_MSK_REG;
+ u32 cic_mask;
+ u32 pending;
+ int cic_status = *CIC_STS_REG;
+ cic_mask = cic_msk_reg[get_current_vpe()];
+ pending = cic_status & cic_mask;
+ if (pending & (1 << (MSP_INT_VPE0_TIMER - MSP_CIC_INTBASE))) {
+ do_IRQ(MSP_INT_VPE0_TIMER);
+ } else if (pending & (1 << (MSP_INT_VPE1_TIMER - MSP_CIC_INTBASE))) {
+ do_IRQ(MSP_INT_VPE1_TIMER);
+ } else if (pending & (1 << (MSP_INT_PER - MSP_CIC_INTBASE))) {
+ msp_per_irq_dispatch();
+ } else if (pending) {
+ do_IRQ(ffs(pending) + MSP_CIC_INTBASE - 1);
+ } else{
+ spurious_interrupt();
+ }
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c
new file mode 100644
index 00000000..98fd0099
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_per.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2010 PMC-Sierra, Inc, derived from irq_cpu.c
+ *
+ * This file define the irq handler for MSP PER subsystem interrupts.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <msp_cic_int.h>
+#include <msp_regs.h>
+
+
+/*
+ * Convenience Macro. Should be somewhere generic.
+ */
+#define get_current_vpe() \
+ ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
+
+#ifdef CONFIG_SMP
+/*
+ * The PER registers must be protected from concurrent access.
+ */
+
+static DEFINE_SPINLOCK(per_lock);
+#endif
+
+/* ensure writes to per are completed */
+
+static inline void per_wmb(void)
+{
+ const volatile void __iomem *per_mem = PER_INT_MSK_REG;
+ volatile u32 dummy_read;
+
+ wmb();
+ dummy_read = __raw_readl(per_mem);
+ dummy_read++;
+}
+
+static inline void unmask_per_irq(struct irq_data *d)
+{
+#ifdef CONFIG_SMP
+ unsigned long flags;
+ spin_lock_irqsave(&per_lock, flags);
+ *PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE));
+ spin_unlock_irqrestore(&per_lock, flags);
+#else
+ *PER_INT_MSK_REG |= (1 << (d->irq - MSP_PER_INTBASE));
+#endif
+ per_wmb();
+}
+
+static inline void mask_per_irq(struct irq_data *d)
+{
+#ifdef CONFIG_SMP
+ unsigned long flags;
+ spin_lock_irqsave(&per_lock, flags);
+ *PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE));
+ spin_unlock_irqrestore(&per_lock, flags);
+#else
+ *PER_INT_MSK_REG &= ~(1 << (d->irq - MSP_PER_INTBASE));
+#endif
+ per_wmb();
+}
+
+static inline void msp_per_irq_ack(struct irq_data *d)
+{
+ mask_per_irq(d);
+ /*
+ * In the PER interrupt controller, only bits 11 and 10
+ * are write-to-clear, (SPI TX complete, SPI RX complete).
+ * It does nothing for any others.
+ */
+ *PER_INT_STS_REG = (1 << (d->irq - MSP_PER_INTBASE));
+}
+
+#ifdef CONFIG_SMP
+static int msp_per_irq_set_affinity(struct irq_data *d,
+ const struct cpumask *affinity, bool force)
+{
+ /* WTF is this doing ????? */
+ unmask_per_irq(d);
+ return 0;
+}
+#endif
+
+static struct irq_chip msp_per_irq_controller = {
+ .name = "MSP_PER",
+ .irq_enable = unmask_per_irq,
+ .irq_disable = mask_per_irq,
+ .irq_ack = msp_per_irq_ack,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = msp_per_irq_set_affinity,
+#endif
+};
+
+void __init msp_per_irq_init(void)
+{
+ int i;
+ /* Mask/clear interrupts. */
+ *PER_INT_MSK_REG = 0x00000000;
+ *PER_INT_STS_REG = 0xFFFFFFFF;
+ /* initialize all the IRQ descriptors */
+ for (i = MSP_PER_INTBASE; i < MSP_PER_INTBASE + 32; i++) {
+ irq_set_chip(i, &msp_per_irq_controller);
+#ifdef CONFIG_MIPS_MT_SMTC
+ irq_hwmask[i] = C_IRQ4;
+#endif
+ }
+}
+
+void msp_per_irq_dispatch(void)
+{
+ u32 per_mask = *PER_INT_MSK_REG;
+ u32 per_status = *PER_INT_STS_REG;
+ u32 pending;
+
+ pending = per_status & per_mask;
+ if (pending) {
+ do_IRQ(ffs(pending) + MSP_PER_INTBASE - 1);
+ } else {
+ spurious_interrupt();
+ }
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
new file mode 100644
index 00000000..5bbcc47d
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
@@ -0,0 +1,107 @@
+/*
+ * This file define the irq handler for MSP SLM subsystem interrupts.
+ *
+ * Copyright 2005-2006 PMC-Sierra, Inc, derived from irq_cpu.c
+ * Author: Andrew Hughes, Andrew_Hughes@pmc-sierra.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <msp_slp_int.h>
+#include <msp_regs.h>
+
+static inline void unmask_msp_slp_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ /* check for PER interrupt range */
+ if (irq < MSP_PER_INTBASE)
+ *SLP_INT_MSK_REG |= (1 << (irq - MSP_SLP_INTBASE));
+ else
+ *PER_INT_MSK_REG |= (1 << (irq - MSP_PER_INTBASE));
+}
+
+static inline void mask_msp_slp_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ /* check for PER interrupt range */
+ if (irq < MSP_PER_INTBASE)
+ *SLP_INT_MSK_REG &= ~(1 << (irq - MSP_SLP_INTBASE));
+ else
+ *PER_INT_MSK_REG &= ~(1 << (irq - MSP_PER_INTBASE));
+}
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues. Same for msp_slp_irq_end.
+ */
+static inline void ack_msp_slp_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ /* check for PER interrupt range */
+ if (irq < MSP_PER_INTBASE)
+ *SLP_INT_STS_REG = (1 << (irq - MSP_SLP_INTBASE));
+ else
+ *PER_INT_STS_REG = (1 << (irq - MSP_PER_INTBASE));
+}
+
+static struct irq_chip msp_slp_irq_controller = {
+ .name = "MSP_SLP",
+ .irq_ack = ack_msp_slp_irq,
+ .irq_mask = mask_msp_slp_irq,
+ .irq_unmask = unmask_msp_slp_irq,
+};
+
+void __init msp_slp_irq_init(void)
+{
+ int i;
+
+ /* Mask/clear interrupts. */
+ *SLP_INT_MSK_REG = 0x00000000;
+ *PER_INT_MSK_REG = 0x00000000;
+ *SLP_INT_STS_REG = 0xFFFFFFFF;
+ *PER_INT_STS_REG = 0xFFFFFFFF;
+
+ /* initialize all the IRQ descriptors */
+ for (i = MSP_SLP_INTBASE; i < MSP_PER_INTBASE + 32; i++)
+ irq_set_chip_and_handler(i, &msp_slp_irq_controller,
+ handle_level_irq);
+}
+
+void msp_slp_irq_dispatch(void)
+{
+ u32 pending;
+ int intbase;
+
+ intbase = MSP_SLP_INTBASE;
+ pending = *SLP_INT_STS_REG & *SLP_INT_MSK_REG;
+
+ /* check for PER interrupt */
+ if (pending == (1 << (MSP_INT_PER - MSP_SLP_INTBASE))) {
+ intbase = MSP_PER_INTBASE;
+ pending = *PER_INT_STS_REG & *PER_INT_MSK_REG;
+ }
+
+ /* check for spurious interrupt */
+ if (pending == 0x00000000) {
+ printk(KERN_ERR "Spurious %s interrupt?\n",
+ (intbase == MSP_SLP_INTBASE) ? "SLP" : "PER");
+ return;
+ }
+
+ /* dispatch the irq */
+ do_IRQ(ffs(pending) + intbase - 1);
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_pci.c b/arch/mips/pmc-sierra/msp71xx/msp_pci.c
new file mode 100644
index 00000000..f764fe77
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_pci.c
@@ -0,0 +1,50 @@
+/*
+ * The setup file for PCI related hardware on PMC-Sierra MSP processors.
+ *
+ * Copyright 2005-2006 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+
+#include <msp_prom.h>
+#include <msp_regs.h>
+
+extern void msp_pci_init(void);
+
+static int __init msp_pci_setup(void)
+{
+#if 0 /* Linux 2.6 initialization code to be completed */
+ if (getdeviceid() & DEV_ID_SINGLE_PC) {
+ /* If single card mode */
+ slmRegs *sreg = (slmRegs *) SREG_BASE;
+
+ sreg->single_pc_enable = SINGLE_PCCARD;
+ }
+#endif
+
+ msp_pci_init();
+
+ return 0;
+}
+
+subsys_initcall(msp_pci_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_prom.c b/arch/mips/pmc-sierra/msp71xx/msp_prom.c
new file mode 100644
index 00000000..db00deb5
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_prom.c
@@ -0,0 +1,503 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * PROM library initialisation code, assuming a version of
+ * pmon is the boot code.
+ *
+ * Copyright 2000,2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ppopov@mvista.com or source@mvista.com
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <asm-generic/sections.h>
+#include <asm/page.h>
+
+#include <msp_prom.h>
+#include <msp_regs.h>
+
+/* global PROM environment variables and pointers */
+int prom_argc;
+char **prom_argv, **prom_envp;
+int *prom_vec;
+
+/* debug flag */
+int init_debug = 1;
+
+/* memory blocks */
+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+/* default feature sets */
+static char msp_default_features[] =
+#if defined(CONFIG_PMC_MSP4200_EVAL) \
+ || defined(CONFIG_PMC_MSP4200_GW)
+ "ERER";
+#elif defined(CONFIG_PMC_MSP7120_EVAL) \
+ || defined(CONFIG_PMC_MSP7120_GW)
+ "EMEMSP";
+#elif defined(CONFIG_PMC_MSP7120_FPGA)
+ "EMEM";
+#endif
+
+/* conversion functions */
+static inline unsigned char str2hexnum(unsigned char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ return 0; /* foo */
+}
+
+static inline int str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int index = 0;
+ unsigned char num = 0;
+
+ while (*str != '\0') {
+ if ((*str == '.') || (*str == ':')) {
+ ea[index++] = num;
+ num = 0;
+ str++;
+ } else {
+ num = num << 4;
+ num |= str2hexnum(*str++);
+ }
+ }
+
+ if (index == 5) {
+ ea[index++] = num;
+ return 0;
+ } else
+ return -1;
+}
+EXPORT_SYMBOL(str2eaddr);
+
+static inline unsigned long str2hex(unsigned char *str)
+{
+ int value = 0;
+
+ while (*str) {
+ value = value << 4;
+ value |= str2hexnum(*str++);
+ }
+
+ return value;
+}
+
+/* function to query the system information */
+const char *get_system_type(void)
+{
+#if defined(CONFIG_PMC_MSP4200_EVAL)
+ return "PMC-Sierra MSP4200 Eval Board";
+#elif defined(CONFIG_PMC_MSP4200_GW)
+ return "PMC-Sierra MSP4200 VoIP Gateway";
+#elif defined(CONFIG_PMC_MSP7120_EVAL)
+ return "PMC-Sierra MSP7120 Eval Board";
+#elif defined(CONFIG_PMC_MSP7120_GW)
+ return "PMC-Sierra MSP7120 Residential Gateway";
+#elif defined(CONFIG_PMC_MSP7120_FPGA)
+ return "PMC-Sierra MSP7120 FPGA";
+#else
+ #error "What is the type of *your* MSP?"
+#endif
+}
+
+int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr)
+{
+ char *ethaddr_str;
+
+ ethaddr_str = prom_getenv(ethaddr_name);
+ if (!ethaddr_str) {
+ printk(KERN_WARNING "%s not set in boot prom\n", ethaddr_name);
+ return -1;
+ }
+
+ if (str2eaddr(ethernet_addr, ethaddr_str) == -1) {
+ printk(KERN_WARNING "%s badly formatted-<%s>\n",
+ ethaddr_name, ethaddr_str);
+ return -1;
+ }
+
+ if (init_debug > 1) {
+ int i;
+ printk(KERN_DEBUG "get_ethernet_addr: for %s ", ethaddr_name);
+ for (i = 0; i < 5; i++)
+ printk(KERN_DEBUG "%02x:",
+ (unsigned char)*(ethernet_addr+i));
+ printk(KERN_DEBUG "%02x\n", *(ethernet_addr+i));
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(get_ethernet_addr);
+
+static char *get_features(void)
+{
+ char *feature = prom_getenv(FEATURES);
+
+ if (feature == NULL) {
+ /* default features based on MACHINE_TYPE */
+ feature = msp_default_features;
+ }
+
+ return feature;
+}
+
+static char test_feature(char c)
+{
+ char *feature = get_features();
+
+ while (*feature) {
+ if (*feature++ == c)
+ return *feature;
+ feature++;
+ }
+
+ return FEATURE_NOEXIST;
+}
+
+unsigned long get_deviceid(void)
+{
+ char *deviceid = prom_getenv(DEVICEID);
+
+ if (deviceid == NULL)
+ return *DEV_ID_REG;
+ else
+ return str2hex(deviceid);
+}
+
+char identify_pci(void)
+{
+ return test_feature(PCI_KEY);
+}
+EXPORT_SYMBOL(identify_pci);
+
+char identify_pcimux(void)
+{
+ return test_feature(PCIMUX_KEY);
+}
+
+char identify_sec(void)
+{
+ return test_feature(SEC_KEY);
+}
+EXPORT_SYMBOL(identify_sec);
+
+char identify_spad(void)
+{
+ return test_feature(SPAD_KEY);
+}
+EXPORT_SYMBOL(identify_spad);
+
+char identify_tdm(void)
+{
+ return test_feature(TDM_KEY);
+}
+EXPORT_SYMBOL(identify_tdm);
+
+char identify_zsp(void)
+{
+ return test_feature(ZSP_KEY);
+}
+EXPORT_SYMBOL(identify_zsp);
+
+static char identify_enetfeature(char key, unsigned long interface_num)
+{
+ char *feature = get_features();
+
+ while (*feature) {
+ if (*feature++ == key && interface_num-- == 0)
+ return *feature;
+ feature++;
+ }
+
+ return FEATURE_NOEXIST;
+}
+
+char identify_enet(unsigned long interface_num)
+{
+ return identify_enetfeature(ENET_KEY, interface_num);
+}
+EXPORT_SYMBOL(identify_enet);
+
+char identify_enetTxD(unsigned long interface_num)
+{
+ return identify_enetfeature(ENETTXD_KEY, interface_num);
+}
+EXPORT_SYMBOL(identify_enetTxD);
+
+unsigned long identify_family(void)
+{
+ unsigned long deviceid;
+
+ deviceid = get_deviceid();
+
+ return deviceid & CPU_DEVID_FAMILY;
+}
+EXPORT_SYMBOL(identify_family);
+
+unsigned long identify_revision(void)
+{
+ unsigned long deviceid;
+
+ deviceid = get_deviceid();
+
+ return deviceid & CPU_DEVID_REVISION;
+}
+EXPORT_SYMBOL(identify_revision);
+
+/* PROM environment functions */
+char *prom_getenv(char *env_name)
+{
+ /*
+ * Return a pointer to the given environment variable. prom_envp
+ * points to a null terminated array of pointers to variables.
+ * Environment variables are stored in the form of "memsize=64"
+ */
+
+ char **var = prom_envp;
+ int i = strlen(env_name);
+
+ while (*var) {
+ if (strncmp(env_name, *var, i) == 0) {
+ return (*var + strlen(env_name) + 1);
+ }
+ var++;
+ }
+
+ return NULL;
+}
+
+/* PROM commandline functions */
+void __init prom_init_cmdline(void)
+{
+ char *cp;
+ int actr;
+
+ actr = 1; /* Always ignore argv[0] */
+
+ cp = &(arcs_cmdline[0]);
+ while (actr < prom_argc) {
+ strcpy(cp, prom_argv[actr]);
+ cp += strlen(prom_argv[actr]);
+ *cp++ = ' ';
+ actr++;
+ }
+ if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
+ --cp;
+ *cp = '\0';
+}
+
+/* memory allocation functions */
+static int __init prom_memtype_classify(unsigned int type)
+{
+ switch (type) {
+ case yamon_free:
+ return BOOT_MEM_RAM;
+ case yamon_prom:
+ return BOOT_MEM_ROM_DATA;
+ default:
+ return BOOT_MEM_RESERVED;
+ }
+}
+
+void __init prom_meminit(void)
+{
+ struct prom_pmemblock *p;
+
+ p = prom_getmdesc();
+
+ while (p->size) {
+ long type;
+ unsigned long base, size;
+
+ type = prom_memtype_classify(p->type);
+ base = p->base;
+ size = p->size;
+
+ add_memory_region(base, size, type);
+ p++;
+ }
+}
+
+void __init prom_free_prom_memory(void)
+{
+ int argc;
+ char **argv;
+ char **envp;
+ char *ptr;
+ int len = 0;
+ int i;
+ unsigned long addr;
+
+ /*
+ * preserve environment variables and command line from pmon/bbload
+ * first preserve the command line
+ */
+ for (argc = 0; argc < prom_argc; argc++) {
+ len += sizeof(char *); /* length of pointer */
+ len += strlen(prom_argv[argc]) + 1; /* length of string */
+ }
+ len += sizeof(char *); /* plus length of null pointer */
+
+ argv = kmalloc(len, GFP_KERNEL);
+ ptr = (char *) &argv[prom_argc + 1]; /* strings follow array */
+
+ for (argc = 0; argc < prom_argc; argc++) {
+ argv[argc] = ptr;
+ strcpy(ptr, prom_argv[argc]);
+ ptr += strlen(prom_argv[argc]) + 1;
+ }
+ argv[prom_argc] = NULL; /* end array with null pointer */
+ prom_argv = argv;
+
+ /* next preserve the environment variables */
+ len = 0;
+ i = 0;
+ for (envp = prom_envp; *envp != NULL; envp++) {
+ i++; /* count number of environment variables */
+ len += sizeof(char *); /* length of pointer */
+ len += strlen(*envp) + 1; /* length of string */
+ }
+ len += sizeof(char *); /* plus length of null pointer */
+
+ envp = kmalloc(len, GFP_KERNEL);
+ ptr = (char *) &envp[i+1];
+
+ for (argc = 0; argc < i; argc++) {
+ envp[argc] = ptr;
+ strcpy(ptr, prom_envp[argc]);
+ ptr += strlen(prom_envp[argc]) + 1;
+ }
+ envp[i] = NULL; /* end array with null pointer */
+ prom_envp = envp;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ free_init_pages("prom memory",
+ addr, addr + boot_mem_map.map[i].size);
+ }
+}
+
+struct prom_pmemblock *__init prom_getmdesc(void)
+{
+ static char memsz_env[] __initdata = "memsize";
+ static char heaptop_env[] __initdata = "heaptop";
+ char *str;
+ unsigned int memsize;
+ unsigned int heaptop;
+ int i;
+
+ str = prom_getenv(memsz_env);
+ if (!str) {
+ ppfinit("memsize not set in boot prom, "
+ "set to default (32Mb)\n");
+ memsize = 0x02000000;
+ } else {
+ memsize = simple_strtol(str, NULL, 0);
+
+ if (memsize == 0) {
+ /* if memsize is a bad size, use reasonable default */
+ memsize = 0x02000000;
+ }
+
+ /* convert to physical address (removing caching bits, etc) */
+ memsize = CPHYSADDR(memsize);
+ }
+
+ str = prom_getenv(heaptop_env);
+ if (!str) {
+ heaptop = CPHYSADDR((u32)&_text);
+ ppfinit("heaptop not set in boot prom, "
+ "set to default 0x%08x\n", heaptop);
+ } else {
+ heaptop = simple_strtol(str, NULL, 16);
+ if (heaptop == 0) {
+ /* heaptop conversion bad, might have 0xValue */
+ heaptop = simple_strtol(str, NULL, 0);
+
+ if (heaptop == 0) {
+ /* heaptop still bad, use reasonable default */
+ heaptop = CPHYSADDR((u32)&_text);
+ }
+ }
+
+ /* convert to physical address (removing caching bits, etc) */
+ heaptop = CPHYSADDR((u32)heaptop);
+ }
+
+ /* the base region */
+ i = 0;
+ mdesc[i].type = BOOT_MEM_RESERVED;
+ mdesc[i].base = 0x00000000;
+ mdesc[i].size = PAGE_ALIGN(0x300 + 0x80);
+ /* jtag interrupt vector + sizeof vector */
+
+ /* PMON data */
+ if (heaptop > mdesc[i].base + mdesc[i].size) {
+ i++; /* 1 */
+ mdesc[i].type = BOOT_MEM_ROM_DATA;
+ mdesc[i].base = mdesc[i-1].base + mdesc[i-1].size;
+ mdesc[i].size = heaptop - mdesc[i].base;
+ }
+
+ /* end of PMON data to start of kernel -- probably zero .. */
+ if (heaptop != CPHYSADDR((u32)_text)) {
+ i++; /* 2 */
+ mdesc[i].type = BOOT_MEM_RAM;
+ mdesc[i].base = heaptop;
+ mdesc[i].size = CPHYSADDR((u32)_text) - mdesc[i].base;
+ }
+
+ /* kernel proper */
+ i++; /* 3 */
+ mdesc[i].type = BOOT_MEM_RESERVED;
+ mdesc[i].base = CPHYSADDR((u32)_text);
+ mdesc[i].size = CPHYSADDR(PAGE_ALIGN((u32)_end)) - mdesc[i].base;
+
+ /* Remainder of RAM -- under memsize */
+ i++; /* 5 */
+ mdesc[i].type = yamon_free;
+ mdesc[i].base = mdesc[i-1].base + mdesc[i-1].size;
+ mdesc[i].size = memsize - mdesc[i].base;
+
+ return &mdesc[0];
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_serial.c b/arch/mips/pmc-sierra/msp71xx/msp_serial.c
new file mode 100644
index 00000000..f7261628
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_serial.c
@@ -0,0 +1,93 @@
+/*
+ * The setup file for serial related hardware on PMC-Sierra MSP processors.
+ *
+ * Copyright 2005 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/serial.h>
+#include <linux/serial_8250.h>
+
+#include <msp_prom.h>
+#include <msp_int.h>
+#include <msp_regs.h>
+
+void __init msp_serial_setup(void)
+{
+ char *s;
+ char *endp;
+ struct uart_port up;
+ unsigned int uartclk;
+
+ memset(&up, 0, sizeof(up));
+
+ /* Check if clock was specified in environment */
+ s = prom_getenv("uartfreqhz");
+ if(!(s && *s && (uartclk = simple_strtoul(s, &endp, 10)) && *endp == 0))
+ uartclk = MSP_BASE_BAUD;
+ ppfinit("UART clock set to %d\n", uartclk);
+
+ /* Initialize first serial port */
+ up.mapbase = MSP_UART0_BASE;
+ up.membase = ioremap_nocache(up.mapbase, MSP_UART_REG_LEN);
+ up.irq = MSP_INT_UART0;
+ up.uartclk = uartclk;
+ up.regshift = 2;
+ up.iotype = UPIO_DWAPB; /* UPIO_MEM like */
+ up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+ up.type = PORT_16550A;
+ up.line = 0;
+ up.private_data = (void*)UART0_STATUS_REG;
+ if (early_serial_setup(&up))
+ printk(KERN_ERR "Early serial init of port 0 failed\n");
+
+ /* Initialize the second serial port, if one exists */
+ switch (mips_machtype) {
+ case MACH_MSP4200_EVAL:
+ case MACH_MSP4200_GW:
+ case MACH_MSP4200_FPGA:
+ case MACH_MSP7120_EVAL:
+ case MACH_MSP7120_GW:
+ case MACH_MSP7120_FPGA:
+ /* Enable UART1 on MSP4200 and MSP7120 */
+ *GPIO_CFG2_REG = 0x00002299;
+ break;
+
+ default:
+ return; /* No second serial port, good-bye. */
+ }
+
+ up.mapbase = MSP_UART1_BASE;
+ up.membase = ioremap_nocache(up.mapbase, MSP_UART_REG_LEN);
+ up.irq = MSP_INT_UART1;
+ up.line = 1;
+ up.private_data = (void*)UART1_STATUS_REG;
+ if (early_serial_setup(&up))
+ printk(KERN_ERR "Early serial init of port 1 failed\n");
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c
new file mode 100644
index 00000000..2413ea67
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c
@@ -0,0 +1,246 @@
+/*
+ * The generic setup file for PMC-Sierra MSP processors
+ *
+ * Copyright 2005-2007 PMC-Sierra, Inc,
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/bootinfo.h>
+#include <asm/cacheflush.h>
+#include <asm/r4kcache.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+
+#include <msp_prom.h>
+#include <msp_regs.h>
+
+#if defined(CONFIG_PMC_MSP7120_GW)
+#include <msp_regops.h>
+#define MSP_BOARD_RESET_GPIO 9
+#endif
+
+extern void msp_serial_setup(void);
+extern void pmctwiled_setup(void);
+
+#if defined(CONFIG_PMC_MSP7120_EVAL) || \
+ defined(CONFIG_PMC_MSP7120_GW) || \
+ defined(CONFIG_PMC_MSP7120_FPGA)
+/*
+ * Performs the reset for MSP7120-based boards
+ */
+void msp7120_reset(void)
+{
+ void *start, *end, *iptr;
+ register int i;
+
+ /* Diasble all interrupts */
+ local_irq_disable();
+#ifdef CONFIG_SYS_SUPPORTS_MULTITHREADING
+ dvpe();
+#endif
+
+ /* Cache the reset code of this function */
+ __asm__ __volatile__ (
+ " .set push \n"
+ " .set mips3 \n"
+ " la %0,startpoint \n"
+ " la %1,endpoint \n"
+ " .set pop \n"
+ : "=r" (start), "=r" (end)
+ :
+ );
+
+ for (iptr = (void *)((unsigned int)start & ~(L1_CACHE_BYTES - 1));
+ iptr < end; iptr += L1_CACHE_BYTES)
+ cache_op(Fill, iptr);
+
+ __asm__ __volatile__ (
+ "startpoint: \n"
+ );
+
+ /* Put the DDRC into self-refresh mode */
+ DDRC_INDIRECT_WRITE(DDRC_CTL(10), 0xb, 1 << 16);
+
+ /*
+ * IMPORTANT!
+ * DO NOT do anything from here on out that might even
+ * think about fetching from RAM - i.e., don't call any
+ * non-inlined functions, and be VERY sure that any inline
+ * functions you do call do NOT access any sort of RAM
+ * anywhere!
+ */
+
+ /* Wait a bit for the DDRC to settle */
+ for (i = 0; i < 100000000; i++);
+
+#if defined(CONFIG_PMC_MSP7120_GW)
+ /*
+ * Set GPIO 9 HI, (tied to board reset logic)
+ * GPIO 9 is the 4th GPIO of register 3
+ *
+ * NOTE: We cannot use the higher-level msp_gpio_mode()/out()
+ * as GPIO char driver may not be enabled and it would look up
+ * data inRAM!
+ */
+ set_value_reg32(GPIO_CFG3_REG, 0xf000, 0x8000);
+ set_reg32(GPIO_DATA3_REG, 8);
+
+ /*
+ * In case GPIO9 doesn't reset the board (jumper configurable!)
+ * fallback to device reset below.
+ */
+#endif
+ /* Set bit 1 of the MSP7120 reset register */
+ *RST_SET_REG = 0x00000001;
+
+ __asm__ __volatile__ (
+ "endpoint: \n"
+ );
+}
+#endif
+
+void msp_restart(char *command)
+{
+ printk(KERN_WARNING "Now rebooting .......\n");
+
+#if defined(CONFIG_PMC_MSP7120_EVAL) || \
+ defined(CONFIG_PMC_MSP7120_GW) || \
+ defined(CONFIG_PMC_MSP7120_FPGA)
+ msp7120_reset();
+#else
+ /* No chip-specific reset code, just jump to the ROM reset vector */
+ set_c0_status(ST0_BEV | ST0_ERL);
+ change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+ flush_cache_all();
+ write_c0_wired(0);
+
+ __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+#endif
+}
+
+void msp_halt(void)
+{
+ printk(KERN_WARNING "\n** You can safely turn off the power\n");
+ while (1)
+ /* If possible call official function to get CPU WARs */
+ if (cpu_wait)
+ (*cpu_wait)();
+ else
+ __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
+}
+
+void msp_power_off(void)
+{
+ msp_halt();
+}
+
+void __init plat_mem_setup(void)
+{
+ _machine_restart = msp_restart;
+ _machine_halt = msp_halt;
+ pm_power_off = msp_power_off;
+}
+
+extern struct plat_smp_ops msp_smtc_smp_ops;
+
+void __init prom_init(void)
+{
+ unsigned long family;
+ unsigned long revision;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ /*
+ * Someday we can use this with PMON2000 to get a
+ * platform call prom routines for output etc. without
+ * having to use grody hacks. For now it's unused.
+ *
+ * struct callvectors *cv = (struct callvectors *) fw_arg3;
+ */
+ family = identify_family();
+ revision = identify_revision();
+
+ switch (family) {
+ case FAMILY_FPGA:
+ if (FPGA_IS_MSP4200(revision)) {
+ /* Old-style revision ID */
+ mips_machtype = MACH_MSP4200_FPGA;
+ } else {
+ mips_machtype = MACH_MSP_OTHER;
+ }
+ break;
+
+ case FAMILY_MSP4200:
+#if defined(CONFIG_PMC_MSP4200_EVAL)
+ mips_machtype = MACH_MSP4200_EVAL;
+#elif defined(CONFIG_PMC_MSP4200_GW)
+ mips_machtype = MACH_MSP4200_GW;
+#else
+ mips_machtype = MACH_MSP_OTHER;
+#endif
+ break;
+
+ case FAMILY_MSP4200_FPGA:
+ mips_machtype = MACH_MSP4200_FPGA;
+ break;
+
+ case FAMILY_MSP7100:
+#if defined(CONFIG_PMC_MSP7120_EVAL)
+ mips_machtype = MACH_MSP7120_EVAL;
+#elif defined(CONFIG_PMC_MSP7120_GW)
+ mips_machtype = MACH_MSP7120_GW;
+#else
+ mips_machtype = MACH_MSP_OTHER;
+#endif
+ break;
+
+ case FAMILY_MSP7100_FPGA:
+ mips_machtype = MACH_MSP7120_FPGA;
+ break;
+
+ default:
+ /* we don't recognize the machine */
+ mips_machtype = MACH_UNKNOWN;
+ panic("***Bogosity factor five***, exiting\n");
+ break;
+ }
+
+ prom_init_cmdline();
+
+ prom_meminit();
+
+ /*
+ * Sub-system setup follows.
+ * Setup functions can either be called here or using the
+ * subsys_initcall mechanism (i.e. see msp_pci_setup). The
+ * order in which they are called can be changed by using the
+ * link order in arch/mips/pmc-sierra/msp71xx/Makefile.
+ *
+ * NOTE: Please keep sub-system specific initialization code
+ * in separate specific files.
+ */
+ msp_serial_setup();
+
+#ifdef CONFIG_MIPS_MT_SMP
+ register_smp_ops(&vsmp_smp_ops);
+#endif
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ register_smp_ops(&msp_smtc_smp_ops);
+#endif
+
+#ifdef CONFIG_PMCTWILED
+ /*
+ * Setup LED states before the subsys_initcall loads other
+ * dependent drivers/modules.
+ */
+ pmctwiled_setup();
+#endif
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smp.c b/arch/mips/pmc-sierra/msp71xx/msp_smp.c
new file mode 100644
index 00000000..bec17901
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_smp.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ * Copyright (C) 2010 PMC-Sierra, Inc.
+ *
+ * VSMP support for MSP platforms . Derived from malta vsmp support.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+
+#ifdef CONFIG_MIPS_MT_SMP
+#define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */
+#define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for call */
+
+
+static void ipi_resched_dispatch(void)
+{
+ do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ);
+}
+
+static void ipi_call_dispatch(void)
+{
+ do_IRQ(MIPS_CPU_IPI_CALL_IRQ);
+}
+
+static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
+{
+ smp_call_function_interrupt();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction irq_resched = {
+ .handler = ipi_resched_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .name = "IPI_resched"
+};
+
+static struct irqaction irq_call = {
+ .handler = ipi_call_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .name = "IPI_call"
+};
+
+void __init arch_init_ipiirq(int irq, struct irqaction *action)
+{
+ setup_irq(irq, action);
+ irq_set_handler(irq, handle_percpu_irq);
+}
+
+void __init msp_vsmp_int_init(void)
+{
+ set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
+ set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
+ arch_init_ipiirq(MIPS_CPU_IPI_RESCHED_IRQ, &irq_resched);
+ arch_init_ipiirq(MIPS_CPU_IPI_CALL_IRQ, &irq_call);
+}
+#endif /* CONFIG_MIPS_MT_SMP */
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smtc.c b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c
new file mode 100644
index 00000000..c8dcc1c0
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c
@@ -0,0 +1,105 @@
+/*
+ * MSP71xx Platform-specific hooks for SMP operation
+ */
+#include <linux/irq.h>
+#include <linux/init.h>
+
+#include <asm/mipsmtregs.h>
+#include <asm/mipsregs.h>
+#include <asm/smtc.h>
+#include <asm/smtc_ipi.h>
+
+/* VPE/SMP Prototype implements platform interfaces directly */
+
+/*
+ * Cause the specified action to be performed on a targeted "CPU"
+ */
+
+static void msp_smtc_send_ipi_single(int cpu, unsigned int action)
+{
+ /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
+ smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
+}
+
+static void msp_smtc_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ msp_smtc_send_ipi_single(i, action);
+}
+
+/*
+ * Post-config but pre-boot cleanup entry point
+ */
+static void __cpuinit msp_smtc_init_secondary(void)
+{
+ int myvpe;
+
+ /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
+ myvpe = read_c0_tcbind() & TCBIND_CURVPE;
+ if (myvpe > 0)
+ change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
+ STATUSF_IP6 | STATUSF_IP7);
+ smtc_init_secondary();
+}
+
+/*
+ * Platform "CPU" startup hook
+ */
+static void __cpuinit msp_smtc_boot_secondary(int cpu,
+ struct task_struct *idle)
+{
+ smtc_boot_secondary(cpu, idle);
+}
+
+/*
+ * SMP initialization finalization entry point
+ */
+static void __cpuinit msp_smtc_smp_finish(void)
+{
+ smtc_smp_finish();
+}
+
+/*
+ * Hook for after all CPUs are online
+ */
+
+static void msp_smtc_cpus_done(void)
+{
+}
+
+/*
+ * Platform SMP pre-initialization
+ *
+ * As noted above, we can assume a single CPU for now
+ * but it may be multithreaded.
+ */
+
+static void __init msp_smtc_smp_setup(void)
+{
+ /*
+ * we won't get the definitive value until
+ * we've run smtc_prepare_cpus later, but
+ */
+
+ if (read_c0_config3() & (1 << 2))
+ smp_num_siblings = smtc_build_cpu_map(0);
+}
+
+static void __init msp_smtc_prepare_cpus(unsigned int max_cpus)
+{
+ smtc_prepare_cpus(max_cpus);
+}
+
+struct plat_smp_ops msp_smtc_smp_ops = {
+ .send_ipi_single = msp_smtc_send_ipi_single,
+ .send_ipi_mask = msp_smtc_send_ipi_mask,
+ .init_secondary = msp_smtc_init_secondary,
+ .smp_finish = msp_smtc_smp_finish,
+ .cpus_done = msp_smtc_cpus_done,
+ .boot_secondary = msp_smtc_boot_secondary,
+ .smp_setup = msp_smtc_smp_setup,
+ .prepare_cpus = msp_smtc_prepare_cpus,
+};
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c
new file mode 100644
index 00000000..8b42f307
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_time.c
@@ -0,0 +1,101 @@
+/*
+ * Setting up the clock on MSP SOCs. No RTC typically.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ */
+
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/ptrace.h>
+
+#include <asm/cevt-r4k.h>
+#include <asm/mipsregs.h>
+#include <asm/time.h>
+
+#include <msp_prom.h>
+#include <msp_int.h>
+#include <msp_regs.h>
+
+#define get_current_vpe() \
+ ((read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE)
+
+static struct irqaction timer_vpe1;
+static int tim_installed;
+
+void __init plat_time_init(void)
+{
+ char *endp, *s;
+ unsigned long cpu_rate = 0;
+
+ if (cpu_rate == 0) {
+ s = prom_getenv("clkfreqhz");
+ cpu_rate = simple_strtoul(s, &endp, 10);
+ if (endp != NULL && *endp != 0) {
+ printk(KERN_ERR
+ "Clock rate in Hz parse error: %s\n", s);
+ cpu_rate = 0;
+ }
+ }
+
+ if (cpu_rate == 0) {
+ s = prom_getenv("clkfreq");
+ cpu_rate = 1000 * simple_strtoul(s, &endp, 10);
+ if (endp != NULL && *endp != 0) {
+ printk(KERN_ERR
+ "Clock rate in MHz parse error: %s\n", s);
+ cpu_rate = 0;
+ }
+ }
+
+ if (cpu_rate == 0) {
+#if defined(CONFIG_PMC_MSP7120_EVAL) \
+ || defined(CONFIG_PMC_MSP7120_GW)
+ cpu_rate = 400000000;
+#elif defined(CONFIG_PMC_MSP7120_FPGA)
+ cpu_rate = 25000000;
+#else
+ cpu_rate = 150000000;
+#endif
+ printk(KERN_ERR
+ "Failed to determine CPU clock rate, "
+ "assuming %ld hz ...\n", cpu_rate);
+ }
+
+ printk(KERN_WARNING "Clock rate set to %ld\n", cpu_rate);
+
+ /* timer frequency is 1/2 clock rate */
+ mips_hpt_frequency = cpu_rate/2;
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ /* MIPS_MT modes may want timer for second VPE */
+ if ((get_current_vpe()) && !tim_installed) {
+ memcpy(&timer_vpe1, &c0_compare_irqaction, sizeof(timer_vpe1));
+ setup_irq(MSP_INT_VPE1_TIMER, &timer_vpe1);
+ tim_installed++;
+ }
+
+ return get_current_vpe() ? MSP_INT_VPE1_TIMER : MSP_INT_VPE0_TIMER;
+}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_usb.c b/arch/mips/pmc-sierra/msp71xx/msp_usb.c
new file mode 100644
index 00000000..9a1aef89
--- /dev/null
+++ b/arch/mips/pmc-sierra/msp71xx/msp_usb.c
@@ -0,0 +1,263 @@
+/*
+ * The setup file for USB related hardware on PMC-Sierra MSP processors.
+ *
+ * Copyright 2006 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_GADGET)
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/mipsregs.h>
+
+#include <msp_regs.h>
+#include <msp_int.h>
+#include <msp_prom.h>
+#include <msp_usb.h>
+
+
+#if defined(CONFIG_USB_EHCI_HCD)
+static struct resource msp_usbhost0_resources[] = {
+ [0] = { /* EHCI-HS operational and capabilities registers */
+ .start = MSP_USB0_HS_START,
+ .end = MSP_USB0_HS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_USB,
+ .end = MSP_INT_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = { /* MSBus-to-AMBA bridge register space */
+ .start = MSP_USB0_MAB_START,
+ .end = MSP_USB0_MAB_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = { /* Identification and general hardware parameters */
+ .start = MSP_USB0_ID_START,
+ .end = MSP_USB0_ID_END,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static u64 msp_usbhost0_dma_mask = 0xffffffffUL;
+
+static struct mspusb_device msp_usbhost0_device = {
+ .dev = {
+ .name = "pmcmsp-ehci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &msp_usbhost0_dma_mask,
+ .coherent_dma_mask = 0xffffffffUL,
+ },
+ .num_resources = ARRAY_SIZE(msp_usbhost0_resources),
+ .resource = msp_usbhost0_resources,
+ },
+};
+
+/* MSP7140/MSP82XX has two USB2 hosts. */
+#ifdef CONFIG_MSP_HAS_DUAL_USB
+static u64 msp_usbhost1_dma_mask = 0xffffffffUL;
+
+static struct resource msp_usbhost1_resources[] = {
+ [0] = { /* EHCI-HS operational and capabilities registers */
+ .start = MSP_USB1_HS_START,
+ .end = MSP_USB1_HS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_USB,
+ .end = MSP_INT_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = { /* MSBus-to-AMBA bridge register space */
+ .start = MSP_USB1_MAB_START,
+ .end = MSP_USB1_MAB_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = { /* Identification and general hardware parameters */
+ .start = MSP_USB1_ID_START,
+ .end = MSP_USB1_ID_END,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mspusb_device msp_usbhost1_device = {
+ .dev = {
+ .name = "pmcmsp-ehci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &msp_usbhost1_dma_mask,
+ .coherent_dma_mask = 0xffffffffUL,
+ },
+ .num_resources = ARRAY_SIZE(msp_usbhost1_resources),
+ .resource = msp_usbhost1_resources,
+ },
+};
+#endif /* CONFIG_MSP_HAS_DUAL_USB */
+#endif /* CONFIG_USB_EHCI_HCD */
+
+#if defined(CONFIG_USB_GADGET)
+static struct resource msp_usbdev0_resources[] = {
+ [0] = { /* EHCI-HS operational and capabilities registers */
+ .start = MSP_USB0_HS_START,
+ .end = MSP_USB0_HS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_USB,
+ .end = MSP_INT_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = { /* MSBus-to-AMBA bridge register space */
+ .start = MSP_USB0_MAB_START,
+ .end = MSP_USB0_MAB_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = { /* Identification and general hardware parameters */
+ .start = MSP_USB0_ID_START,
+ .end = MSP_USB0_ID_END,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static u64 msp_usbdev_dma_mask = 0xffffffffUL;
+
+/* This may need to be converted to a mspusb_device, too. */
+static struct mspusb_device msp_usbdev0_device = {
+ .dev = {
+ .name = "msp71xx_udc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &msp_usbdev_dma_mask,
+ .coherent_dma_mask = 0xffffffffUL,
+ },
+ .num_resources = ARRAY_SIZE(msp_usbdev0_resources),
+ .resource = msp_usbdev0_resources,
+ },
+};
+
+#ifdef CONFIG_MSP_HAS_DUAL_USB
+static struct resource msp_usbdev1_resources[] = {
+ [0] = { /* EHCI-HS operational and capabilities registers */
+ .start = MSP_USB1_HS_START,
+ .end = MSP_USB1_HS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSP_INT_USB,
+ .end = MSP_INT_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = { /* MSBus-to-AMBA bridge register space */
+ .start = MSP_USB1_MAB_START,
+ .end = MSP_USB1_MAB_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = { /* Identification and general hardware parameters */
+ .start = MSP_USB1_ID_START,
+ .end = MSP_USB1_ID_END,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/* This may need to be converted to a mspusb_device, too. */
+static struct mspusb_device msp_usbdev1_device = {
+ .dev = {
+ .name = "msp71xx_udc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &msp_usbdev_dma_mask,
+ .coherent_dma_mask = 0xffffffffUL,
+ },
+ .num_resources = ARRAY_SIZE(msp_usbdev1_resources),
+ .resource = msp_usbdev1_resources,
+ },
+};
+
+#endif /* CONFIG_MSP_HAS_DUAL_USB */
+#endif /* CONFIG_USB_GADGET */
+
+static int __init msp_usb_setup(void)
+{
+ char *strp;
+ char envstr[32];
+ struct platform_device *msp_devs[NUM_USB_DEVS];
+ unsigned int val;
+
+ /* construct environment name usbmode */
+ /* set usbmode <host/device> as pmon environment var */
+ /*
+ * Could this perhaps be integrated into the "features" env var?
+ * Use the features key "U", and follow with "H" for host-mode,
+ * "D" for device-mode. If it works for Ethernet, why not USB...
+ * -- hammtrev, 2007/03/22
+ */
+ snprintf((char *)&envstr[0], sizeof(envstr), "usbmode");
+
+ /* set default host mode */
+ val = 1;
+
+ /* get environment string */
+ strp = prom_getenv((char *)&envstr[0]);
+ if (strp) {
+ /* compare string */
+ if (!strcmp(strp, "device"))
+ val = 0;
+ }
+
+ if (val) {
+#if defined(CONFIG_USB_EHCI_HCD)
+ msp_devs[0] = &msp_usbhost0_device.dev;
+ ppfinit("platform add USB HOST done %s.\n", msp_devs[0]->name);
+#ifdef CONFIG_MSP_HAS_DUAL_USB
+ msp_devs[1] = &msp_usbhost1_device.dev;
+ ppfinit("platform add USB HOST done %s.\n", msp_devs[1]->name);
+#endif
+#else
+ ppfinit("%s: echi_hcd not supported\n", __FILE__);
+#endif /* CONFIG_USB_EHCI_HCD */
+ } else {
+#if defined(CONFIG_USB_GADGET)
+ /* get device mode structure */
+ msp_devs[0] = &msp_usbdev0_device.dev;
+ ppfinit("platform add USB DEVICE done %s.\n"
+ , msp_devs[0]->name);
+#ifdef CONFIG_MSP_HAS_DUAL_USB
+ msp_devs[1] = &msp_usbdev1_device.dev;
+ ppfinit("platform add USB DEVICE done %s.\n"
+ , msp_devs[1]->name);
+#endif
+#else
+ ppfinit("%s: usb_gadget not supported\n", __FILE__);
+#endif /* CONFIG_USB_GADGET */
+ }
+ /* add device */
+ platform_add_devices(msp_devs, ARRAY_SIZE(msp_devs));
+
+ return 0;
+}
+
+subsys_initcall(msp_usb_setup);
+#endif /* CONFIG_USB_EHCI_HCD || CONFIG_USB_GADGET */
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile
new file mode 100644
index 00000000..02f5fb94
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the PMC-Sierra Titan
+#
+
+obj-y += irq.o prom.o py-console.o setup.o
+
+obj-$(CONFIG_SMP) += smp.o
+
+ccflags-y := -Werror
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
new file mode 100644
index 00000000..d6f8bdff
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Description:
+ *
+ * This code reads the ATMEL 24CXX EEPROM. The PMC-Sierra Yosemite board uses the ATMEL
+ * 24C32/24C64 which uses two byte addressing as compared to 24C16. Note that this program
+ * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are
+ * expected to have a connectivity from the EEPROM to the serial port. This program does
+ * __not__ communicate using the I2C protocol
+ */
+
+#include "atmel_read_eeprom.h"
+
+static void delay(int delay)
+{
+ while (delay--);
+}
+
+static void send_bit(unsigned char bit)
+{
+ scl_lo;
+ delay(TXX);
+ if (bit)
+ sda_hi;
+ else
+ sda_lo;
+
+ delay(TXX);
+ scl_hi;
+ delay(TXX);
+}
+
+static void send_ack(void)
+{
+ send_bit(0);
+}
+
+static void send_byte(unsigned char byte)
+{
+ int i = 0;
+
+ for (i = 7; i >= 0; i--)
+ send_bit((byte >> i) & 0x01);
+}
+
+static void send_start(void)
+{
+ sda_hi;
+ delay(TXX);
+ scl_hi;
+ delay(TXX);
+ sda_lo;
+ delay(TXX);
+}
+
+static void send_stop(void)
+{
+ sda_lo;
+ delay(TXX);
+ scl_hi;
+ delay(TXX);
+ sda_hi;
+ delay(TXX);
+}
+
+static void do_idle(void)
+{
+ sda_hi;
+ scl_hi;
+ vcc_off;
+}
+
+static int recv_bit(void)
+{
+ int status;
+
+ scl_lo;
+ delay(TXX);
+ sda_hi;
+ delay(TXX);
+ scl_hi;
+ delay(TXX);
+
+ return 1;
+}
+
+static unsigned char recv_byte(void) {
+ int i;
+ unsigned char byte=0;
+
+ for (i=7;i>=0;i--)
+ byte |= (recv_bit() << i);
+
+ return byte;
+}
+
+static int recv_ack(void)
+{
+ unsigned int ack;
+
+ ack = (unsigned int)recv_bit();
+ scl_lo;
+
+ if (ack) {
+ do_idle();
+ printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM\n");
+ return -1;
+ }
+
+ return ack;
+}
+
+/*
+ * This function does the actual read of the EEPROM. It needs the buffer into which the
+ * read data is copied, the size of the EEPROM being read and the buffer size
+ */
+int read_eeprom(char *buffer, int eeprom_size, int size)
+{
+ int i = 0, err;
+
+ send_start();
+ send_byte(W_HEADER);
+ recv_ack();
+
+ /* EEPROM with size of more than 2K need two byte addressing */
+ if (eeprom_size > 2048) {
+ send_byte(0x00);
+ recv_ack();
+ }
+
+ send_start();
+ send_byte(R_HEADER);
+ err = recv_ack();
+ if (err == -1)
+ return err;
+
+ for (i = 0; i < size; i++) {
+ *buffer++ = recv_byte();
+ send_ack();
+ }
+
+ /* Note : We should do some check if the buffer contains correct information */
+
+ send_stop();
+}
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
new file mode 100644
index 00000000..d6c7ec46
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
@@ -0,0 +1,67 @@
+/*
+ * arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
+ *
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Header file for atmel_read_eeprom.c
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <linux/init.h>
+#include <asm/termios.h>
+#include <asm/ioctls.h>
+#include <linux/ioctl.h>
+#include <linux/fcntl.h>
+
+#define DEFAULT_PORT "/dev/ttyS0" /* Port to open */
+#define TXX 0 /* Dummy loop for spinning */
+
+#define BLOCK_SEL 0x00
+#define SLAVE_ADDR 0xa0
+#define READ_BIT 0x01
+#define WRITE_BIT 0x00
+#define R_HEADER SLAVE_ADDR + BLOCK_SEL + READ_BIT
+#define W_HEADER SLAVE_ADDR + BLOCK_SEL + WRITE_BIT
+
+/*
+ * Clock, Voltages and Data
+ */
+#define vcc_off (ioctl(fd, TIOCSBRK, 0))
+#define vcc_on (ioctl(fd, TIOCCBRK, 0))
+#define sda_hi (ioctl(fd, TIOCMBIS, &dtr))
+#define sda_lo (ioctl(fd, TIOCMBIC, &dtr))
+#define scl_lo (ioctl(fd, TIOCMBIC, &rts))
+#define scl_hi (ioctl(fd, TIOCMBIS, &rts))
+
+const char rts = TIOCM_RTS;
+const char dtr = TIOCM_DTR;
+int fd;
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
new file mode 100644
index 00000000..86b98e98
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+/*
+ * HT Bus fixup for the Titan
+ * XXX IRQ values need to change based on the board layout
+ */
+void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
+{
+ struct pci_bus *current_bus = bus;
+ struct pci_dev *devices;
+ struct list_head *devices_link;
+
+ list_for_each(devices_link, &(current_bus->devices)) {
+ devices = pci_dev_b(devices_link);
+ if (devices == NULL)
+ continue;
+ }
+
+ /*
+ * PLX and SPKT related changes go here
+ */
+}
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c
new file mode 100644
index 00000000..63be40e4
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/ht.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+
+#include <linux/init.h>
+#include <asm/titan_dep.h>
+
+#ifdef CONFIG_HYPERTRANSPORT
+
+
+/*
+ * This function check if the Hypertransport Link Initialization completed. If
+ * it did, then proceed further with scanning bus #2
+ */
+static __inline__ int check_titan_htlink(void)
+{
+ u32 val;
+
+ val = *(volatile uint32_t *)(RM9000x2_HTLINK_REG);
+ if (val & 0x00000020)
+ /* HT Link Initialization completed */
+ return 1;
+ else
+ return 0;
+}
+
+static int titan_ht_config_read_dword(struct pci_dev *device,
+ int offset, u32* val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ RM9K_WRITE(address_reg, address);
+ RM9K_READ(data_reg, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int titan_ht_config_read_word(struct pci_dev *device,
+ int offset, u16* val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ if ((offset & 0x3) == 0)
+ offset = 0x2;
+ else
+ offset = 0x0;
+
+ RM9K_WRITE(address_reg, address);
+ RM9K_READ_16(data_reg + offset, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+u32 longswap(unsigned long l)
+{
+ unsigned char b1, b2, b3, b4;
+
+ b1 = l&255;
+ b2 = (l>>8)&255;
+ b3 = (l>>16)&255;
+ b4 = (l>>24)&255;
+
+ return ((b1<<24) + (b2<<16) + (b3<<8) + b4);
+}
+
+
+static int titan_ht_config_read_byte(struct pci_dev *device,
+ int offset, u8* val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+ int offset1;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ RM9K_WRITE(address_reg, address);
+
+ if ((offset & 0x3) == 0) {
+ offset1 = 0x3;
+ }
+ if ((offset & 0x3) == 1) {
+ offset1 = 0x2;
+ }
+ if ((offset & 0x3) == 2) {
+ offset1 = 0x1;
+ }
+ if ((offset & 0x3) == 3) {
+ offset1 = 0x0;
+ }
+ RM9K_READ_8(data_reg + offset1, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int titan_ht_config_write_dword(struct pci_dev *device,
+ int offset, u8 val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ RM9K_WRITE(address_reg, address);
+ RM9K_WRITE(data_reg, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write_word(struct pci_dev *device,
+ int offset, u8 val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ if ((offset & 0x3) == 0)
+ offset = 0x2;
+ else
+ offset = 0x0;
+
+ RM9K_WRITE(address_reg, address);
+ RM9K_WRITE_16(data_reg + offset, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write_byte(struct pci_dev *device,
+ int offset, u8 val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+ int offset1;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ RM9K_WRITE(address_reg, address);
+
+ if ((offset & 0x3) == 0) {
+ offset1 = 0x3;
+ }
+ if ((offset & 0x3) == 1) {
+ offset1 = 0x2;
+ }
+ if ((offset & 0x3) == 2) {
+ offset1 = 0x1;
+ }
+ if ((offset & 0x3) == 3) {
+ offset1 = 0x0;
+ }
+
+ RM9K_WRITE_8(data_reg + offset1, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static void titan_pcibios_set_master(struct pci_dev *dev)
+{
+ u16 cmd;
+ int bus = dev->bus->number;
+
+ if (check_titan_htlink())
+ titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
+
+ cmd |= PCI_COMMAND_MASTER;
+
+ if (check_titan_htlink())
+ titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
+}
+
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+ u16 cmd, old_cmd;
+ u8 tmp1;
+ int idx;
+ struct resource *r;
+ int bus = dev->bus->number;
+
+ if (check_titan_htlink())
+ titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
+
+ old_cmd = cmd;
+ for (idx = 0; idx < 6; idx++) {
+ r = &dev->resource[idx];
+ if (!r->start && r->end) {
+ printk(KERN_ERR
+ "PCI: Device %s not available because of "
+ "resource collisions\n", pci_name(dev));
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (cmd != old_cmd) {
+ if (check_titan_htlink())
+ titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
+ }
+
+ if (check_titan_htlink())
+ titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+
+ if (tmp1 != 8) {
+ printk(KERN_WARNING "PCI setting cache line size to 8 from "
+ "%d\n", tmp1);
+ }
+
+ if (check_titan_htlink())
+ titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+
+ if (check_titan_htlink())
+ titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+
+ if (tmp1 < 32 || tmp1 == 0xff) {
+ printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
+ tmp1);
+ }
+
+ if (check_titan_htlink())
+ titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32);
+
+ return 0;
+}
+
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+ return pcibios_enable_resources(dev);
+}
+
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+ resource_size_t size, resource_size_t align)
+{
+ struct pci_dev *dev = data;
+ resource_size_t start = res->start;
+
+ if (res->flags & IORESOURCE_IO) {
+ /* We need to avoid collisions with `mirrored' VGA ports
+ and other strange ISA hardware, so we always want the
+ addresses kilobyte aligned. */
+ if (size > 0x100) {
+ printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+ " (%ld bytes)\n", pci_name(dev),
+ dev->resource - res, size);
+ }
+
+ start = (start + 1024 - 1) & ~(1024 - 1);
+ }
+
+ return start;
+}
+
+struct pci_ops titan_pci_ops = {
+ titan_ht_config_read_byte,
+ titan_ht_config_read_word,
+ titan_ht_config_read_dword,
+ titan_ht_config_write_byte,
+ titan_ht_config_write_word,
+ titan_ht_config_write_dword
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+ titan_ht_pcibios_fixup_bus(c);
+}
+
+void __init pcibios_init(void)
+{
+
+ /* Reset PCI I/O and PCI MEM values */
+ /* XXX Need to add the proper values here */
+ ioport_resource.start = 0xe0000000;
+ ioport_resource.end = 0xe0000000 + 0x20000000 - 1;
+ iomem_resource.start = 0xc0000000;
+ iomem_resource.end = 0xc0000000 + 0x20000000 - 1;
+
+ /* XXX Need to add bus values */
+ pci_scan_bus(2, &titan_pci_ops, NULL);
+ pci_scan_bus(3, &titan_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+ printk(KERN_INFO "rr: pcibios_setup\n");
+ /* Nothing to do for now. */
+
+ return str;
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+ /* We want to use the PCI bus detection done by PMON */
+ return 0;
+}
+
+#endif /* CONFIG_HYPERTRANSPORT */
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c
new file mode 100644
index 00000000..25bbbf42
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/irq.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/timex.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/titan_dep.h>
+
+/* Hypertransport specific */
+#define IRQ_ACK_BITS 0x00000000 /* Ack bits */
+
+#define HYPERTRANSPORT_INTA 0x78 /* INTA# */
+#define HYPERTRANSPORT_INTB 0x79 /* INTB# */
+#define HYPERTRANSPORT_INTC 0x7a /* INTC# */
+#define HYPERTRANSPORT_INTD 0x7b /* INTD# */
+
+extern void titan_mailbox_irq(void);
+
+#ifdef CONFIG_HYPERTRANSPORT
+/*
+ * Handle hypertransport & SMP interrupts. The interrupt lines are scarce.
+ * For interprocessor interrupts, the best thing to do is to use the INTMSG
+ * register. We use the same external interrupt line, i.e. INTB3 and monitor
+ * another status bit
+ */
+static void ll_ht_smp_irq_handler(int irq)
+{
+ u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
+
+ /* Ack all the bits that correspond to the interrupt sources */
+ if (status != 0)
+ OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
+
+ status = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
+ if (status != 0)
+ OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
+
+#ifdef CONFIG_HT_LEVEL_TRIGGER
+ /*
+ * Level Trigger Mode only. Send the HT EOI message back to the source.
+ */
+ switch (status) {
+ case 0x1000000:
+ OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA);
+ break;
+ case 0x2000000:
+ OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB);
+ break;
+ case 0x4000000:
+ OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC);
+ break;
+ case 0x8000000:
+ OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD);
+ break;
+ case 0x0000001:
+ /* PLX */
+ OCD_WRITE(RM9000x2_OCD_HTEOI, 0x20);
+ OCD_WRITE(IRQ_CLEAR_REG, IRQ_ACK_BITS);
+ break;
+ case 0xf000000:
+ OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTA);
+ OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTB);
+ OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTC);
+ OCD_WRITE(RM9000x2_OCD_HTEOI, HYPERTRANSPORT_INTD);
+ break;
+ }
+#endif /* CONFIG_HT_LEVEL_TRIGGER */
+
+ do_IRQ(irq);
+}
+#endif
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int cause = read_c0_cause();
+ unsigned int status = read_c0_status();
+ unsigned int pending = cause & status;
+
+ if (pending & STATUSF_IP7) {
+ do_IRQ(7);
+ } else if (pending & STATUSF_IP2) {
+#ifdef CONFIG_HYPERTRANSPORT
+ ll_ht_smp_irq_handler(2);
+#else
+ do_IRQ(2);
+#endif
+ } else if (pending & STATUSF_IP3) {
+ do_IRQ(3);
+ } else if (pending & STATUSF_IP4) {
+ do_IRQ(4);
+ } else if (pending & STATUSF_IP5) {
+#ifdef CONFIG_SMP
+ titan_mailbox_irq();
+#else
+ do_IRQ(5);
+#endif
+ } else if (pending & STATUSF_IP6) {
+ do_IRQ(4);
+ }
+}
+
+/*
+ * Initialize the next level interrupt handler
+ */
+void __init arch_init_irq(void)
+{
+ clear_c0_status(ST0_IM);
+
+ mips_cpu_irq_init();
+ rm7k_cpu_irq_init();
+ rm9k_cpu_irq_init();
+}
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c
new file mode 100644
index 00000000..cf4c8687
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/prom.c
@@ -0,0 +1,143 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2003, 2004 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ * Copyright (C) 2004 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/smp.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/smp-ops.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/pmon.h>
+
+#ifdef CONFIG_SMP
+extern void prom_grab_secondary(void);
+#else
+#define prom_grab_secondary() do { } while (0)
+#endif
+
+#include "setup.h"
+
+struct callvectors *debug_vectors;
+
+extern unsigned long yosemite_base;
+extern unsigned long cpu_clock_freq;
+
+const char *get_system_type(void)
+{
+ return "PMC-Sierra Yosemite";
+}
+
+static void prom_cpu0_exit(void *arg)
+{
+ void *nvram = (void *) YOSEMITE_RTC_BASE;
+
+ /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+ writeb(0x84, nvram + 0xff7);
+
+ /* wait for the watchdog to go off */
+ mdelay(100 + (1000 / 16));
+
+ /* if the watchdog fails for some reason, let people know */
+ printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+/*
+ * Reset the NVRAM over the local bus
+ */
+static void prom_exit(void)
+{
+#ifdef CONFIG_SMP
+ if (smp_processor_id())
+ /* CPU 1 */
+ smp_call_function(prom_cpu0_exit, NULL, 1);
+#endif
+ prom_cpu0_exit(NULL);
+}
+
+/*
+ * Halt the system
+ */
+static void prom_halt(void)
+{
+ printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+ while (1)
+ __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
+}
+
+extern struct plat_smp_ops yos_smp_ops;
+
+/*
+ * Init routine which accepts the variables from PMON
+ */
+void __init prom_init(void)
+{
+ int argc = fw_arg0;
+ char **arg = (char **) fw_arg1;
+ char **env = (char **) fw_arg2;
+ struct callvectors *cv = (struct callvectors *) fw_arg3;
+ int i = 0;
+
+ /* Callbacks for halt, restart */
+ _machine_restart = (void (*)(char *)) prom_exit;
+ _machine_halt = prom_halt;
+ pm_power_off = prom_halt;
+
+ debug_vectors = cv;
+ arcs_cmdline[0] = '\0';
+
+ /* Get the boot parameters */
+ for (i = 1; i < argc; i++) {
+ if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >=
+ sizeof(arcs_cmdline))
+ break;
+
+ strcat(arcs_cmdline, arg[i]);
+ strcat(arcs_cmdline, " ");
+ }
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ if ((strstr(arcs_cmdline, "console=ttyS")) == NULL)
+ strcat(arcs_cmdline, "console=ttyS0,115200");
+#endif
+
+ while (*env) {
+ if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0)
+ yosemite_base =
+ simple_strtol(*env + strlen("ocd_base="), NULL,
+ 16);
+
+ if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0)
+ cpu_clock_freq =
+ simple_strtol(*env + strlen("cpuclock="), NULL,
+ 10);
+
+ env++;
+ }
+
+ prom_grab_secondary();
+
+ register_smp_ops(&yos_smp_ops);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c
new file mode 100644
index 00000000..434d7b1a
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/py-console.c
@@ -0,0 +1,117 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001, 2002, 2004 Ralf Baechle
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/termios.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+
+/* SUPERIO uart register map */
+struct yo_uartregs {
+ union {
+ volatile u8 rbr; /* read only, DLAB == 0 */
+ volatile u8 thr; /* write only, DLAB == 0 */
+ volatile u8 dll; /* DLAB == 1 */
+ } u1;
+ union {
+ volatile u8 ier; /* DLAB == 0 */
+ volatile u8 dlm; /* DLAB == 1 */
+ } u2;
+ union {
+ volatile u8 iir; /* read only */
+ volatile u8 fcr; /* write only */
+ } u3;
+ volatile u8 iu_lcr;
+ volatile u8 iu_mcr;
+ volatile u8 iu_lsr;
+ volatile u8 iu_msr;
+ volatile u8 iu_scr;
+} yo_uregs_t;
+
+#define iu_rbr u1.rbr
+#define iu_thr u1.thr
+#define iu_dll u1.dll
+#define iu_ier u2.ier
+#define iu_dlm u2.dlm
+#define iu_iir u3.iir
+#define iu_fcr u3.fcr
+
+#define ssnop() __asm__ __volatile__("sll $0, $0, 1\n");
+#define ssnop_4() do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0)
+
+#define IO_BASE_64 0x9000000000000000ULL
+
+static unsigned char readb_outer_space(unsigned long long phys)
+{
+ unsigned long long vaddr = IO_BASE_64 | phys;
+ unsigned char res;
+ unsigned int sr;
+
+ sr = read_c0_status();
+ write_c0_status((sr | ST0_KX) & ~ ST0_IE);
+ ssnop_4();
+
+ __asm__ __volatile__ (
+ " .set mips3 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set nomacro \n"
+ " ld %0, %1 \n"
+ " .set pop \n"
+ " lbu %0, (%0) \n"
+ " .set mips0 \n"
+ : "=r" (res)
+ : "R" (vaddr));
+
+ write_c0_status(sr);
+ ssnop_4();
+
+ return res;
+}
+
+static void writeb_outer_space(unsigned long long phys, unsigned char c)
+{
+ unsigned long long vaddr = IO_BASE_64 | phys;
+ unsigned long tmp;
+ unsigned int sr;
+
+ sr = read_c0_status();
+ write_c0_status((sr | ST0_KX) & ~ ST0_IE);
+ ssnop_4();
+
+ __asm__ __volatile__ (
+ " .set mips3 \n"
+ " .set push \n"
+ " .set noreorder \n"
+ " .set nomacro \n"
+ " ld %0, %1 \n"
+ " .set pop \n"
+ " sb %2, (%0) \n"
+ " .set mips0 \n"
+ : "=&r" (tmp)
+ : "R" (vaddr), "r" (c));
+
+ write_c0_status(sr);
+ ssnop_4();
+}
+
+void prom_putchar(char c)
+{
+ unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr);
+ unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr);
+
+ while ((readb_outer_space(lsr) & 0x20) == 0);
+ writeb_outer_space(thr, c);
+}
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
new file mode 100644
index 00000000..3498ac9c
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/termios.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/serial.h>
+#include <asm/titan_dep.h>
+#include <asm/m48t37.h>
+
+#include "setup.h"
+
+unsigned char titan_ge_mac_addr_base[6] = {
+ // 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
+ 0x00, 0xe0, 0x04, 0x00, 0x00, 0x21
+};
+
+unsigned long cpu_clock_freq;
+unsigned long yosemite_base;
+
+static struct m48t37_rtc *m48t37_base;
+
+void __init bus_error_init(void)
+{
+ /* Do nothing */
+}
+
+
+void read_persistent_clock(struct timespec *ts)
+{
+ unsigned int year, month, day, hour, min, sec;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ /* Stop the update to the time */
+ m48t37_base->control = 0x40;
+
+ year = bcd2bin(m48t37_base->year);
+ year += bcd2bin(m48t37_base->century) * 100;
+
+ month = bcd2bin(m48t37_base->month);
+ day = bcd2bin(m48t37_base->date);
+ hour = bcd2bin(m48t37_base->hour);
+ min = bcd2bin(m48t37_base->min);
+ sec = bcd2bin(m48t37_base->sec);
+
+ /* Start the update to the time again */
+ m48t37_base->control = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ ts->tv_sec = mktime(year, month, day, hour, min, sec);
+ ts->tv_nsec = 0;
+}
+
+int rtc_mips_set_time(unsigned long tim)
+{
+ struct rtc_time tm;
+ unsigned long flags;
+
+ /*
+ * Convert to a more useful format -- note months count from 0
+ * and years from 1900
+ */
+ rtc_time_to_tm(tim, &tm);
+ tm.tm_year += 1900;
+ tm.tm_mon += 1;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ /* enable writing */
+ m48t37_base->control = 0x80;
+
+ /* year */
+ m48t37_base->year = bin2bcd(tm.tm_year % 100);
+ m48t37_base->century = bin2bcd(tm.tm_year / 100);
+
+ /* month */
+ m48t37_base->month = bin2bcd(tm.tm_mon);
+
+ /* day */
+ m48t37_base->date = bin2bcd(tm.tm_mday);
+
+ /* hour/min/sec */
+ m48t37_base->hour = bin2bcd(tm.tm_hour);
+ m48t37_base->min = bin2bcd(tm.tm_min);
+ m48t37_base->sec = bin2bcd(tm.tm_sec);
+
+ /* day of week -- not really used, but let's keep it up-to-date */
+ m48t37_base->day = bin2bcd(tm.tm_wday + 1);
+
+ /* disable writing */
+ m48t37_base->control = 0x00;
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ return 0;
+}
+
+void __init plat_time_init(void)
+{
+ mips_hpt_frequency = cpu_clock_freq / 2;
+mips_hpt_frequency = 33000000 * 3 * 5;
+}
+
+unsigned long ocd_base;
+
+EXPORT_SYMBOL(ocd_base);
+
+/*
+ * Common setup before any secondaries are started
+ */
+
+#define TITAN_UART_CLK 3686400
+#define TITAN_SERIAL_BASE_BAUD (TITAN_UART_CLK / 16)
+#define TITAN_SERIAL_IRQ 4
+#define TITAN_SERIAL_BASE 0xfd000008UL
+
+static void __init py_map_ocd(void)
+{
+ ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE);
+ if (!ocd_base)
+ panic("Mapping OCD failed - game over. Your score is 0.");
+
+ /* Kludge for PMON bug ... */
+ OCD_WRITE(0x0710, 0x0ffff029);
+}
+
+static void __init py_uart_setup(void)
+{
+#ifdef CONFIG_SERIAL_8250
+ struct uart_port up;
+
+ /*
+ * Register to interrupt zero because we share the interrupt with
+ * the serial driver which we don't properly support yet.
+ */
+ memset(&up, 0, sizeof(up));
+ up.membase = (unsigned char *) ioremap(TITAN_SERIAL_BASE, 8);
+ up.irq = TITAN_SERIAL_IRQ;
+ up.uartclk = TITAN_UART_CLK;
+ up.regshift = 0;
+ up.iotype = UPIO_MEM;
+ up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+ up.line = 0;
+
+ if (early_serial_setup(&up))
+ printk(KERN_ERR "Early serial init of port 0 failed\n");
+#endif /* CONFIG_SERIAL_8250 */
+}
+
+static void __init py_rtc_setup(void)
+{
+ m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE);
+ if (!m48t37_base)
+ printk(KERN_ERR "Mapping the RTC failed\n");
+}
+
+/* Not only time init but that's what the hook it's called through is named */
+static void __init py_late_time_init(void)
+{
+ py_map_ocd();
+ py_uart_setup();
+ py_rtc_setup();
+}
+
+void __init plat_mem_setup(void)
+{
+ late_time_init = py_late_time_init;
+
+ /* Add memory regions */
+ add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM);
+
+#if 0 /* XXX Crash ... */
+ OCD_WRITE(RM9000x2_OCD_HTSC,
+ OCD_READ(RM9000x2_OCD_HTSC) | HYPERTRANSPORT_ENABLE);
+
+ /* Set the BAR. Shifted mode */
+ OCD_WRITE(RM9000x2_OCD_HTBAR0, HYPERTRANSPORT_BAR0_ADDR);
+ OCD_WRITE(RM9000x2_OCD_HTMASK0, HYPERTRANSPORT_SIZE0);
+#endif
+}
diff --git a/arch/mips/pmc-sierra/yosemite/setup.h b/arch/mips/pmc-sierra/yosemite/setup.h
new file mode 100644
index 00000000..1a01abfc
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/setup.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2003, 04 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ * Copyright 2004 Ralf Baechle <ralf@linux-mips.org>
+ *
+ * Board specific definititions for the PMC-Sierra Yosemite
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#ifndef __SETUP_H__
+#define __SETUP_H__
+
+/* M48T37 RTC + NVRAM */
+#define YOSEMITE_RTC_BASE 0xfc800000
+#define YOSEMITE_RTC_SIZE 0x00800000
+
+#define HYPERTRANSPORT_BAR0_ADDR 0x00000006
+#define HYPERTRANSPORT_SIZE0 0x0fffffff
+#define HYPERTRANSPORT_BAR0_ATTR 0x00002000
+
+#define HYPERTRANSPORT_ENABLE 0x6
+
+/*
+ * EEPROM Size
+ */
+#define TITAN_ATMEL_24C32_SIZE 32768
+#define TITAN_ATMEL_24C64_SIZE 65536
+
+#endif /* __SETUP_H__ */
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
new file mode 100644
index 00000000..26087528
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -0,0 +1,185 @@
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+
+#include <asm/pmon.h>
+#include <asm/titan_dep.h>
+#include <asm/time.h>
+
+#define LAUNCHSTACK_SIZE 256
+
+static __cpuinitdata arch_spinlock_t launch_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+
+static unsigned long secondary_sp __cpuinitdata;
+static unsigned long secondary_gp __cpuinitdata;
+
+static unsigned char launchstack[LAUNCHSTACK_SIZE] __initdata
+ __attribute__((aligned(2 * sizeof(long))));
+
+static void __init prom_smp_bootstrap(void)
+{
+ local_irq_disable();
+
+ while (arch_spin_is_locked(&launch_lock));
+
+ __asm__ __volatile__(
+ " move $sp, %0 \n"
+ " move $gp, %1 \n"
+ " j smp_bootstrap \n"
+ :
+ : "r" (secondary_sp), "r" (secondary_gp));
+}
+
+/*
+ * PMON is a fragile beast. It'll blow up once the mappings it's littering
+ * right into the middle of KSEG3 are blown away so we have to grab the slave
+ * core early and keep it in a waiting loop.
+ */
+void __init prom_grab_secondary(void)
+{
+ arch_spin_lock(&launch_lock);
+
+ pmon_cpustart(1, &prom_smp_bootstrap,
+ launchstack + LAUNCHSTACK_SIZE, 0);
+}
+
+void titan_mailbox_irq(void)
+{
+ int cpu = smp_processor_id();
+ unsigned long status;
+
+ switch (cpu) {
+ case 0:
+ status = OCD_READ(RM9000x2_OCD_INTP0STATUS3);
+ OCD_WRITE(RM9000x2_OCD_INTP0CLEAR3, status);
+
+ if (status & 0x2)
+ smp_call_function_interrupt();
+ if (status & 0x4)
+ scheduler_ipi();
+ break;
+
+ case 1:
+ status = OCD_READ(RM9000x2_OCD_INTP1STATUS3);
+ OCD_WRITE(RM9000x2_OCD_INTP1CLEAR3, status);
+
+ if (status & 0x2)
+ smp_call_function_interrupt();
+ if (status & 0x4)
+ scheduler_ipi();
+ break;
+ }
+}
+
+/*
+ * Send inter-processor interrupt
+ */
+static void yos_send_ipi_single(int cpu, unsigned int action)
+{
+ /*
+ * Generate an INTMSG so that it can be sent over to the
+ * destination CPU. The INTMSG will put the STATUS bits
+ * based on the action desired. An alternative strategy
+ * is to write to the Interrupt Set register, read the
+ * Interrupt Status register and clear the Interrupt
+ * Clear register. The latter is preffered.
+ */
+ switch (action) {
+ case SMP_RESCHEDULE_YOURSELF:
+ if (cpu == 1)
+ OCD_WRITE(RM9000x2_OCD_INTP1SET3, 4);
+ else
+ OCD_WRITE(RM9000x2_OCD_INTP0SET3, 4);
+ break;
+
+ case SMP_CALL_FUNCTION:
+ if (cpu == 1)
+ OCD_WRITE(RM9000x2_OCD_INTP1SET3, 2);
+ else
+ OCD_WRITE(RM9000x2_OCD_INTP0SET3, 2);
+ break;
+ }
+}
+
+static void yos_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ yos_send_ipi_single(i, action);
+}
+
+/*
+ * After we've done initial boot, this function is called to allow the
+ * board code to clean up state, if needed
+ */
+static void __cpuinit yos_init_secondary(void)
+{
+ set_c0_status(ST0_CO | ST0_IE | ST0_IM);
+}
+
+static void __cpuinit yos_smp_finish(void)
+{
+}
+
+/* Hook for after all CPUs are online */
+static void yos_cpus_done(void)
+{
+}
+
+/*
+ * Firmware CPU startup hook
+ * Complicated by PMON's weird interface which tries to minimic the UNIX fork.
+ * It launches the next * available CPU and copies some information on the
+ * stack so the first thing we do is throw away that stuff and load useful
+ * values into the registers ...
+ */
+static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle)
+{
+ unsigned long gp = (unsigned long) task_thread_info(idle);
+ unsigned long sp = __KSTK_TOS(idle);
+
+ secondary_sp = sp;
+ secondary_gp = gp;
+
+ arch_spin_unlock(&launch_lock);
+}
+
+/*
+ * Detect available CPUs, populate cpu_possible_map before smp_init
+ *
+ * We don't want to start the secondary CPU yet nor do we have a nice probing
+ * feature in PMON so we just assume presence of the secondary core.
+ */
+static void __init yos_smp_setup(void)
+{
+ int i;
+
+ cpus_clear(cpu_possible_map);
+
+ for (i = 0; i < 2; i++) {
+ cpu_set(i, cpu_possible_map);
+ __cpu_number_map[i] = i;
+ __cpu_logical_map[i] = i;
+ }
+}
+
+static void __init yos_prepare_cpus(unsigned int max_cpus)
+{
+ /*
+ * Be paranoid. Enable the IPI only if we're really about to go SMP.
+ */
+ if (cpus_weight(cpu_possible_map))
+ set_c0_status(STATUSF_IP5);
+}
+
+struct plat_smp_ops yos_smp_ops = {
+ .send_ipi_single = yos_send_ipi_single,
+ .send_ipi_mask = yos_send_ipi_mask,
+ .init_secondary = yos_init_secondary,
+ .smp_finish = yos_smp_finish,
+ .cpus_done = yos_cpus_done,
+ .boot_secondary = yos_boot_secondary,
+ .smp_setup = yos_smp_setup,
+ .prepare_cpus = yos_prepare_cpus,
+};
diff --git a/arch/mips/pnx833x/Makefile b/arch/mips/pnx833x/Makefile
new file mode 100644
index 00000000..02c4698c
--- /dev/null
+++ b/arch/mips/pnx833x/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SOC_PNX833X) += common/
+obj-$(CONFIG_NXP_STB220) += stb22x/
+obj-$(CONFIG_NXP_STB225) += stb22x/
diff --git a/arch/mips/pnx833x/Platform b/arch/mips/pnx833x/Platform
new file mode 100644
index 00000000..7e6ec4db
--- /dev/null
+++ b/arch/mips/pnx833x/Platform
@@ -0,0 +1,5 @@
+# NXP STB225
+platform-$(CONFIG_SOC_PNX833X) += pnx833x/
+cflags-$(CONFIG_SOC_PNX833X) += -Iarch/mips/include/asm/mach-pnx833x
+load-$(CONFIG_NXP_STB220) += 0xffffffff80001000
+load-$(CONFIG_NXP_STB225) += 0xffffffff80001000
diff --git a/arch/mips/pnx833x/common/Makefile b/arch/mips/pnx833x/common/Makefile
new file mode 100644
index 00000000..1a46dd29
--- /dev/null
+++ b/arch/mips/pnx833x/common/Makefile
@@ -0,0 +1 @@
+obj-y := interrupts.o platform.o prom.o setup.o reset.o
diff --git a/arch/mips/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c
new file mode 100644
index 00000000..adc171c8
--- /dev/null
+++ b/arch/mips/pnx833x/common/interrupts.c
@@ -0,0 +1,315 @@
+/*
+ * interrupts.c: Interrupt mappings for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
+#include <asm/mipsregs.h>
+#include <asm/irq_cpu.h>
+#include <irq.h>
+#include <irq-mapping.h>
+#include <gpio.h>
+
+static int mips_cpu_timer_irq;
+
+static const unsigned int irq_prio[PNX833X_PIC_NUM_IRQ] =
+{
+ 0, /* unused */
+ 4, /* PNX833X_PIC_I2C0_INT 1 */
+ 4, /* PNX833X_PIC_I2C1_INT 2 */
+ 1, /* PNX833X_PIC_UART0_INT 3 */
+ 1, /* PNX833X_PIC_UART1_INT 4 */
+ 6, /* PNX833X_PIC_TS_IN0_DV_INT 5 */
+ 6, /* PNX833X_PIC_TS_IN0_DMA_INT 6 */
+ 7, /* PNX833X_PIC_GPIO_INT 7 */
+ 4, /* PNX833X_PIC_AUDIO_DEC_INT 8 */
+ 5, /* PNX833X_PIC_VIDEO_DEC_INT 9 */
+ 4, /* PNX833X_PIC_CONFIG_INT 10 */
+ 4, /* PNX833X_PIC_AOI_INT 11 */
+ 9, /* PNX833X_PIC_SYNC_INT 12 */
+ 9, /* PNX8335_PIC_SATA_INT 13 */
+ 4, /* PNX833X_PIC_OSD_INT 14 */
+ 9, /* PNX833X_PIC_DISP1_INT 15 */
+ 4, /* PNX833X_PIC_DEINTERLACER_INT 16 */
+ 9, /* PNX833X_PIC_DISPLAY2_INT 17 */
+ 4, /* PNX833X_PIC_VC_INT 18 */
+ 4, /* PNX833X_PIC_SC_INT 19 */
+ 9, /* PNX833X_PIC_IDE_INT 20 */
+ 9, /* PNX833X_PIC_IDE_DMA_INT 21 */
+ 6, /* PNX833X_PIC_TS_IN1_DV_INT 22 */
+ 6, /* PNX833X_PIC_TS_IN1_DMA_INT 23 */
+ 4, /* PNX833X_PIC_SGDX_DMA_INT 24 */
+ 4, /* PNX833X_PIC_TS_OUT_INT 25 */
+ 4, /* PNX833X_PIC_IR_INT 26 */
+ 3, /* PNX833X_PIC_VMSP1_INT 27 */
+ 3, /* PNX833X_PIC_VMSP2_INT 28 */
+ 4, /* PNX833X_PIC_PIBC_INT 29 */
+ 4, /* PNX833X_PIC_TS_IN0_TRD_INT 30 */
+ 4, /* PNX833X_PIC_SGDX_TPD_INT 31 */
+ 5, /* PNX833X_PIC_USB_INT 32 */
+ 4, /* PNX833X_PIC_TS_IN1_TRD_INT 33 */
+ 4, /* PNX833X_PIC_CLOCK_INT 34 */
+ 4, /* PNX833X_PIC_SGDX_PARSER_INT 35 */
+ 4, /* PNX833X_PIC_VMSP_DMA_INT 36 */
+#if defined(CONFIG_SOC_PNX8335)
+ 4, /* PNX8335_PIC_MIU_INT 37 */
+ 4, /* PNX8335_PIC_AVCHIP_IRQ_INT 38 */
+ 9, /* PNX8335_PIC_SYNC_HD_INT 39 */
+ 9, /* PNX8335_PIC_DISP_HD_INT 40 */
+ 9, /* PNX8335_PIC_DISP_SCALER_INT 41 */
+ 4, /* PNX8335_PIC_OSD_HD1_INT 42 */
+ 4, /* PNX8335_PIC_DTL_WRITER_Y_INT 43 */
+ 4, /* PNX8335_PIC_DTL_WRITER_C_INT 44 */
+ 4, /* PNX8335_PIC_DTL_EMULATOR_Y_IR_INT 45 */
+ 4, /* PNX8335_PIC_DTL_EMULATOR_C_IR_INT 46 */
+ 4, /* PNX8335_PIC_DENC_TTX_INT 47 */
+ 4, /* PNX8335_PIC_MMI_SIF0_INT 48 */
+ 4, /* PNX8335_PIC_MMI_SIF1_INT 49 */
+ 4, /* PNX8335_PIC_MMI_CDMMU_INT 50 */
+ 4, /* PNX8335_PIC_PIBCS_INT 51 */
+ 12, /* PNX8335_PIC_ETHERNET_INT 52 */
+ 3, /* PNX8335_PIC_VMSP1_0_INT 53 */
+ 3, /* PNX8335_PIC_VMSP1_1_INT 54 */
+ 4, /* PNX8335_PIC_VMSP1_DMA_INT 55 */
+ 4, /* PNX8335_PIC_TDGR_DE_INT 56 */
+ 4, /* PNX8335_PIC_IR1_IRQ_INT 57 */
+#endif
+};
+
+static void pnx833x_timer_dispatch(void)
+{
+ do_IRQ(mips_cpu_timer_irq);
+}
+
+static void pic_dispatch(void)
+{
+ unsigned int irq = PNX833X_REGFIELD(PIC_INT_SRC, INT_SRC);
+
+ if ((irq >= 1) && (irq < (PNX833X_PIC_NUM_IRQ))) {
+ unsigned long priority = PNX833X_PIC_INT_PRIORITY;
+ PNX833X_PIC_INT_PRIORITY = irq_prio[irq];
+
+ if (irq == PNX833X_PIC_GPIO_INT) {
+ unsigned long mask = PNX833X_PIO_INT_STATUS & PNX833X_PIO_INT_ENABLE;
+ int pin;
+ while ((pin = ffs(mask & 0xffff))) {
+ pin -= 1;
+ do_IRQ(PNX833X_GPIO_IRQ_BASE + pin);
+ mask &= ~(1 << pin);
+ }
+ } else {
+ do_IRQ(irq + PNX833X_PIC_IRQ_BASE);
+ }
+
+ PNX833X_PIC_INT_PRIORITY = priority;
+ } else {
+ printk(KERN_ERR "plat_irq_dispatch: unexpected irq %u\n", irq);
+ }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause();
+
+ if (pending & STATUSF_IP4)
+ pic_dispatch();
+ else if (pending & STATUSF_IP7)
+ do_IRQ(PNX833X_TIMER_IRQ);
+ else
+ spurious_interrupt();
+}
+
+static inline void pnx833x_hard_enable_pic_irq(unsigned int irq)
+{
+ /* Currently we do this by setting IRQ priority to 1.
+ If priority support is being implemented, 1 should be repalced
+ by a better value. */
+ PNX833X_PIC_INT_REG(irq) = irq_prio[irq];
+}
+
+static inline void pnx833x_hard_disable_pic_irq(unsigned int irq)
+{
+ /* Disable IRQ by writing setting it's priority to 0 */
+ PNX833X_PIC_INT_REG(irq) = 0;
+}
+
+static DEFINE_RAW_SPINLOCK(pnx833x_irq_lock);
+
+static unsigned int pnx833x_startup_pic_irq(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE;
+
+ raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
+ pnx833x_hard_enable_pic_irq(pic_irq);
+ raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+ return 0;
+}
+
+static void pnx833x_enable_pic_irq(struct irq_data *d)
+{
+ unsigned long flags;
+ unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE;
+
+ raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
+ pnx833x_hard_enable_pic_irq(pic_irq);
+ raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+}
+
+static void pnx833x_disable_pic_irq(struct irq_data *d)
+{
+ unsigned long flags;
+ unsigned int pic_irq = d->irq - PNX833X_PIC_IRQ_BASE;
+
+ raw_spin_lock_irqsave(&pnx833x_irq_lock, flags);
+ pnx833x_hard_disable_pic_irq(pic_irq);
+ raw_spin_unlock_irqrestore(&pnx833x_irq_lock, flags);
+}
+
+static DEFINE_RAW_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock);
+
+static void pnx833x_enable_gpio_irq(struct irq_data *d)
+{
+ int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
+ unsigned long flags;
+ raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+ pnx833x_gpio_enable_irq(pin);
+ raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+}
+
+static void pnx833x_disable_gpio_irq(struct irq_data *d)
+{
+ int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
+ unsigned long flags;
+ raw_spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags);
+ pnx833x_gpio_disable_irq(pin);
+ raw_spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags);
+}
+
+static int pnx833x_set_type_gpio_irq(struct irq_data *d, unsigned int flow_type)
+{
+ int pin = d->irq - PNX833X_GPIO_IRQ_BASE;
+ int gpio_mode;
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_RISING:
+ gpio_mode = GPIO_INT_EDGE_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ gpio_mode = GPIO_INT_EDGE_FALLING;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ gpio_mode = GPIO_INT_EDGE_BOTH;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ gpio_mode = GPIO_INT_LEVEL_HIGH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ gpio_mode = GPIO_INT_LEVEL_LOW;
+ break;
+ default:
+ gpio_mode = GPIO_INT_NONE;
+ break;
+ }
+
+ pnx833x_gpio_setup_irq(gpio_mode, pin);
+
+ return 0;
+}
+
+static struct irq_chip pnx833x_pic_irq_type = {
+ .name = "PNX-PIC",
+ .irq_enable = pnx833x_enable_pic_irq,
+ .irq_disable = pnx833x_disable_pic_irq,
+};
+
+static struct irq_chip pnx833x_gpio_irq_type = {
+ .name = "PNX-GPIO",
+ .irq_enable = pnx833x_enable_gpio_irq,
+ .irq_disable = pnx833x_disable_gpio_irq,
+ .irq_set_type = pnx833x_set_type_gpio_irq,
+};
+
+void __init arch_init_irq(void)
+{
+ unsigned int irq;
+
+ /* setup standard internal cpu irqs */
+ mips_cpu_irq_init();
+
+ /* Set IRQ information in irq_desc */
+ for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) {
+ pnx833x_hard_disable_pic_irq(irq);
+ irq_set_chip_and_handler(irq, &pnx833x_pic_irq_type,
+ handle_simple_irq);
+ }
+
+ for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++)
+ irq_set_chip_and_handler(irq, &pnx833x_gpio_irq_type,
+ handle_simple_irq);
+
+ /* Set PIC priority limiter register to 0 */
+ PNX833X_PIC_INT_PRIORITY = 0;
+
+ /* Setup GPIO IRQ dispatching */
+ pnx833x_startup_pic_irq(PNX833X_PIC_GPIO_INT);
+
+ /* Enable PIC IRQs (HWIRQ2) */
+ if (cpu_has_vint)
+ set_vi_handler(4, pic_dispatch);
+
+ write_c0_status(read_c0_status() | IE_IRQ2);
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ if (cpu_has_vint)
+ set_vi_handler(cp0_compare_irq, pnx833x_timer_dispatch);
+
+ mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+ return mips_cpu_timer_irq;
+}
+
+void __init plat_time_init(void)
+{
+ /* calculate mips_hpt_frequency based on PNX833X_CLOCK_CPUCP_CTL reg */
+
+ extern unsigned long mips_hpt_frequency;
+ unsigned long reg = PNX833X_CLOCK_CPUCP_CTL;
+
+ if (!(PNX833X_BIT(reg, CLOCK_CPUCP_CTL, EXIT_RESET))) {
+ /* Functional clock is disabled so use crystal frequency */
+ mips_hpt_frequency = 25;
+ } else {
+#if defined(CONFIG_SOC_PNX8335)
+ /* Functional clock is enabled, so get clock multiplier */
+ mips_hpt_frequency = 90 + (10 * PNX8335_REGFIELD(CLOCK_PLL_CPU_CTL, FREQ));
+#else
+ static const unsigned long int freq[4] = {240, 160, 120, 80};
+ mips_hpt_frequency = freq[PNX833X_FIELD(reg, CLOCK_CPUCP_CTL, DIV_CLOCK)];
+#endif
+ }
+
+ printk(KERN_INFO "CPU clock is %ld MHz\n", mips_hpt_frequency);
+
+ mips_hpt_frequency *= 500000;
+}
diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c
new file mode 100644
index 00000000..87167dcc
--- /dev/null
+++ b/arch/mips/pnx833x/common/platform.c
@@ -0,0 +1,320 @@
+/*
+ * platform.c: platform support for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial.h>
+#include <linux/serial_pnx8xxx.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#ifdef CONFIG_I2C_PNX0105
+/* Until i2c driver available in kernel.*/
+#include <linux/i2c-pnx0105.h>
+#endif
+
+#include <irq.h>
+#include <irq-mapping.h>
+#include <pnx833x.h>
+
+static u64 uart_dmamask = DMA_BIT_MASK(32);
+
+static struct resource pnx833x_uart_resources[] = {
+ [0] = {
+ .start = PNX833X_UART0_PORTS_START,
+ .end = PNX833X_UART0_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX833X_PIC_UART0_INT,
+ .end = PNX833X_PIC_UART0_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = PNX833X_UART1_PORTS_START,
+ .end = PNX833X_UART1_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = PNX833X_PIC_UART1_INT,
+ .end = PNX833X_PIC_UART1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct pnx8xxx_port pnx8xxx_ports[] = {
+ [0] = {
+ .port = {
+ .type = PORT_PNX8XXX,
+ .iotype = UPIO_MEM,
+ .membase = (void __iomem *)PNX833X_UART0_PORTS_START,
+ .mapbase = PNX833X_UART0_PORTS_START,
+ .irq = PNX833X_PIC_UART0_INT,
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ },
+ [1] = {
+ .port = {
+ .type = PORT_PNX8XXX,
+ .iotype = UPIO_MEM,
+ .membase = (void __iomem *)PNX833X_UART1_PORTS_START,
+ .mapbase = PNX833X_UART1_PORTS_START,
+ .irq = PNX833X_PIC_UART1_INT,
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ },
+};
+
+static struct platform_device pnx833x_uart_device = {
+ .name = "pnx8xxx-uart",
+ .id = -1,
+ .dev = {
+ .dma_mask = &uart_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = pnx8xxx_ports,
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_uart_resources),
+ .resource = pnx833x_uart_resources,
+};
+
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+
+static struct resource pnx833x_usb_ehci_resources[] = {
+ [0] = {
+ .start = PNX833X_USB_PORTS_START,
+ .end = PNX833X_USB_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX833X_PIC_USB_INT,
+ .end = PNX833X_PIC_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pnx833x_usb_ehci_device = {
+ .name = "pnx833x-ehci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_usb_ehci_resources),
+ .resource = pnx833x_usb_ehci_resources,
+};
+
+#ifdef CONFIG_I2C_PNX0105
+static struct resource pnx833x_i2c0_resources[] = {
+ {
+ .start = PNX833X_I2C0_PORTS_START,
+ .end = PNX833X_I2C0_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = PNX833X_PIC_I2C0_INT,
+ .end = PNX833X_PIC_I2C0_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pnx833x_i2c1_resources[] = {
+ {
+ .start = PNX833X_I2C1_PORTS_START,
+ .end = PNX833X_I2C1_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = PNX833X_PIC_I2C1_INT,
+ .end = PNX833X_PIC_I2C1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct i2c_pnx0105_dev pnx833x_i2c_dev[] = {
+ {
+ .base = PNX833X_I2C0_PORTS_START,
+ .irq = -1, /* should be PNX833X_PIC_I2C0_INT but polling is faster */
+ .clock = 6, /* 0 == 400 kHz, 4 == 100 kHz(Maximum HDMI), 6 = 50kHz(Preferred HDCP) */
+ .bus_addr = 0, /* no slave support */
+ },
+ {
+ .base = PNX833X_I2C1_PORTS_START,
+ .irq = -1, /* on high freq, polling is faster */
+ /*.irq = PNX833X_PIC_I2C1_INT,*/
+ .clock = 4, /* 0 == 400 kHz, 4 == 100 kHz. 100 kHz seems a safe default for now */
+ .bus_addr = 0, /* no slave support */
+ },
+};
+
+static struct platform_device pnx833x_i2c0_device = {
+ .name = "i2c-pnx0105",
+ .id = 0,
+ .dev = {
+ .platform_data = &pnx833x_i2c_dev[0],
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_i2c0_resources),
+ .resource = pnx833x_i2c0_resources,
+};
+
+static struct platform_device pnx833x_i2c1_device = {
+ .name = "i2c-pnx0105",
+ .id = 1,
+ .dev = {
+ .platform_data = &pnx833x_i2c_dev[1],
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_i2c1_resources),
+ .resource = pnx833x_i2c1_resources,
+};
+#endif
+
+static u64 ethernet_dmamask = DMA_BIT_MASK(32);
+
+static struct resource pnx833x_ethernet_resources[] = {
+ [0] = {
+ .start = PNX8335_IP3902_PORTS_START,
+ .end = PNX8335_IP3902_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8335_PIC_ETHERNET_INT,
+ .end = PNX8335_PIC_ETHERNET_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pnx833x_ethernet_device = {
+ .name = "ip3902-eth",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ethernet_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(pnx833x_ethernet_resources),
+ .resource = pnx833x_ethernet_resources,
+};
+
+static struct resource pnx833x_sata_resources[] = {
+ [0] = {
+ .start = PNX8335_SATA_PORTS_START,
+ .end = PNX8335_SATA_PORTS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8335_PIC_SATA_INT,
+ .end = PNX8335_PIC_SATA_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pnx833x_sata_device = {
+ .name = "pnx833x-sata",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pnx833x_sata_resources),
+ .resource = pnx833x_sata_resources,
+};
+
+static const char *part_probes[] = {
+ "cmdlinepart",
+ NULL
+};
+
+static void
+pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_CLE_MASK));
+ else
+ writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_ALE_MASK));
+}
+
+static struct platform_nand_data pnx833x_flash_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_delay = 25,
+ .part_probe_types = part_probes,
+ },
+ .ctrl = {
+ .cmd_ctrl = pnx833x_flash_nand_cmd_ctrl
+ }
+};
+
+/*
+ * Set start to be the correct address (PNX8335_NAND_BASE with no 0xb!!),
+ * 12 bytes more seems to be the standard that allows for NAND access.
+ */
+static struct resource pnx833x_flash_nand_resource = {
+ .start = PNX8335_NAND_BASE,
+ .end = PNX8335_NAND_BASE + 12,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pnx833x_flash_nand = {
+ .name = "gen_nand",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &pnx833x_flash_nand_resource,
+ .dev = {
+ .platform_data = &pnx833x_flash_nand_data,
+ },
+};
+
+static struct platform_device *pnx833x_platform_devices[] __initdata = {
+ &pnx833x_uart_device,
+ &pnx833x_usb_ehci_device,
+#ifdef CONFIG_I2C_PNX0105
+ &pnx833x_i2c0_device,
+ &pnx833x_i2c1_device,
+#endif
+ &pnx833x_ethernet_device,
+ &pnx833x_sata_device,
+ &pnx833x_flash_nand,
+};
+
+static int __init pnx833x_platform_init(void)
+{
+ int res;
+
+ res = platform_add_devices(pnx833x_platform_devices,
+ ARRAY_SIZE(pnx833x_platform_devices));
+
+ return res;
+}
+
+arch_initcall(pnx833x_platform_init);
diff --git a/arch/mips/pnx833x/common/prom.c b/arch/mips/pnx833x/common/prom.c
new file mode 100644
index 00000000..29969f90
--- /dev/null
+++ b/arch/mips/pnx833x/common/prom.c
@@ -0,0 +1,64 @@
+/*
+ * prom.c:
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+
+void __init prom_init_cmdline(void)
+{
+ int argc = fw_arg0;
+ char **argv = (char **)fw_arg1;
+ char *c = &(arcs_cmdline[0]);
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ strcpy(c, argv[i]);
+ c += strlen(argv[i]);
+ if (i < argc-1)
+ *c++ = ' ';
+ }
+ *c = 0;
+}
+
+char __init *prom_getenv(char *envname)
+{
+ extern char **prom_envp;
+ char **env = prom_envp;
+ int i;
+
+ i = strlen(envname);
+
+ while (*env) {
+ if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=')
+ return *env + i + 1;
+ env++;
+ }
+
+ return 0;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/pnx833x/common/reset.c b/arch/mips/pnx833x/common/reset.c
new file mode 100644
index 00000000..e0ea96d2
--- /dev/null
+++ b/arch/mips/pnx833x/common/reset.c
@@ -0,0 +1,44 @@
+/*
+ * reset.c: reset support for PNX833X.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/reboot.h>
+#include <pnx833x.h>
+
+void pnx833x_machine_restart(char *command)
+{
+ PNX833X_RESET_CONTROL_2 = 0;
+ PNX833X_RESET_CONTROL = 0;
+}
+
+void pnx833x_machine_halt(void)
+{
+ while (1)
+ __asm__ __volatile__ ("wait");
+
+}
+
+void pnx833x_machine_power_off(void)
+{
+ pnx833x_machine_halt();
+}
diff --git a/arch/mips/pnx833x/common/setup.c b/arch/mips/pnx833x/common/setup.c
new file mode 100644
index 00000000..e51fbc4b
--- /dev/null
+++ b/arch/mips/pnx833x/common/setup.c
@@ -0,0 +1,64 @@
+/*
+ * setup.c: Setup PNX833X Soc.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+#include <asm/reboot.h>
+#include <pnx833x.h>
+#include <gpio.h>
+
+extern void pnx833x_board_setup(void);
+extern void pnx833x_machine_restart(char *);
+extern void pnx833x_machine_halt(void);
+extern void pnx833x_machine_power_off(void);
+
+int __init plat_mem_setup(void)
+{
+ /* fake pci bus to avoid bounce buffers */
+ PCI_DMA_BUS_IS_PHYS = 1;
+
+ /* set mips clock to 320MHz */
+#if defined(CONFIG_SOC_PNX8335)
+ PNX8335_WRITEFIELD(0x17, CLOCK_PLL_CPU_CTL, FREQ);
+#endif
+ pnx833x_gpio_init(); /* so it will be ready in board_setup() */
+
+ pnx833x_board_setup();
+
+ _machine_restart = pnx833x_machine_restart;
+ _machine_halt = pnx833x_machine_halt;
+ pm_power_off = pnx833x_machine_power_off;
+
+ /* IO/MEM resources. */
+ set_io_port_base(KSEG1);
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+ iomem_resource.start = 0;
+ iomem_resource.end = ~0;
+
+ return 0;
+}
diff --git a/arch/mips/pnx833x/stb22x/Makefile b/arch/mips/pnx833x/stb22x/Makefile
new file mode 100644
index 00000000..7b580060
--- /dev/null
+++ b/arch/mips/pnx833x/stb22x/Makefile
@@ -0,0 +1 @@
+obj-y := board.o
diff --git a/arch/mips/pnx833x/stb22x/board.c b/arch/mips/pnx833x/stb22x/board.c
new file mode 100644
index 00000000..644eb7c3
--- /dev/null
+++ b/arch/mips/pnx833x/stb22x/board.c
@@ -0,0 +1,133 @@
+/*
+ * board.c: STB225 board support.
+ *
+ * Copyright 2008 NXP Semiconductors
+ * Chris Steel <chris.steel@nxp.com>
+ * Daniel Laird <daniel.j.laird@nxp.com>
+ *
+ * Based on software written by:
+ * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+#include <linux/mm.h>
+#include <pnx833x.h>
+#include <gpio.h>
+
+/* endianess twiddlers */
+#define PNX8335_DEBUG0 0x4400
+#define PNX8335_DEBUG1 0x4404
+#define PNX8335_DEBUG2 0x4408
+#define PNX8335_DEBUG3 0x440c
+#define PNX8335_DEBUG4 0x4410
+#define PNX8335_DEBUG5 0x4414
+#define PNX8335_DEBUG6 0x4418
+#define PNX8335_DEBUG7 0x441c
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+
+extern void prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+ return "NXP STB22x";
+}
+
+static inline unsigned long env_or_default(char *env, unsigned long dfl)
+{
+ char *str = prom_getenv(env);
+ return str ? simple_strtol(str, 0, 0) : dfl;
+}
+
+void __init prom_init(void)
+{
+ unsigned long memsize;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize = env_or_default("memsize", 0x02000000);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void __init pnx833x_board_setup(void)
+{
+ pnx833x_gpio_select_function_alt(4);
+ pnx833x_gpio_select_output(4);
+ pnx833x_gpio_select_function_alt(5);
+ pnx833x_gpio_select_input(5);
+ pnx833x_gpio_select_function_alt(6);
+ pnx833x_gpio_select_input(6);
+ pnx833x_gpio_select_function_alt(7);
+ pnx833x_gpio_select_output(7);
+
+ pnx833x_gpio_select_function_alt(25);
+ pnx833x_gpio_select_function_alt(26);
+
+ pnx833x_gpio_select_function_alt(27);
+ pnx833x_gpio_select_function_alt(28);
+ pnx833x_gpio_select_function_alt(29);
+ pnx833x_gpio_select_function_alt(30);
+ pnx833x_gpio_select_function_alt(31);
+ pnx833x_gpio_select_function_alt(32);
+ pnx833x_gpio_select_function_alt(33);
+
+#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+ /* Setup MIU for NAND access on CS0...
+ *
+ * (it seems that we must also configure CS1 for reliable operation,
+ * otherwise the first read ID command will fail if it's read as 4 bytes
+ * but pass if it's read as 1 word.)
+ */
+
+ /* Setup MIU CS0 & CS1 timing */
+ PNX833X_MIU_SEL0 = 0;
+ PNX833X_MIU_SEL1 = 0;
+ PNX833X_MIU_SEL0_TIMING = 0x50003081;
+ PNX833X_MIU_SEL1_TIMING = 0x50003081;
+
+ /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */
+ pnx833x_gpio_select_function_alt(0);
+
+ /* Setup GPIO 04 to input NAND read/busy signal */
+ pnx833x_gpio_select_function_io(4);
+ pnx833x_gpio_select_input(4);
+
+ /* Setup GPIO 05 to disable NAND write protect */
+ pnx833x_gpio_select_function_io(5);
+ pnx833x_gpio_select_output(5);
+ pnx833x_gpio_write(1, 5);
+
+#elif defined(CONFIG_MTD_CFI) || defined(CONFIG_MTD_CFI_MODULE)
+
+ /* Set up MIU for 16-bit NOR access on CS0 and CS1... */
+
+ /* Setup MIU CS0 & CS1 timing */
+ PNX833X_MIU_SEL0 = 1;
+ PNX833X_MIU_SEL1 = 1;
+ PNX833X_MIU_SEL0_TIMING = 0x6A08D082;
+ PNX833X_MIU_SEL1_TIMING = 0x6A08D082;
+
+ /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */
+ pnx833x_gpio_select_function_alt(0);
+#endif
+}
diff --git a/arch/mips/pnx8550/Makefile b/arch/mips/pnx8550/Makefile
new file mode 100644
index 00000000..3f7e8561
--- /dev/null
+++ b/arch/mips/pnx8550/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SOC_PNX8550) += common/
+obj-$(CONFIG_PNX8550_JBS) += jbs/
+obj-$(CONFIG_PNX8550_STB810) += stb810/
diff --git a/arch/mips/pnx8550/Platform b/arch/mips/pnx8550/Platform
new file mode 100644
index 00000000..0e7fbde7
--- /dev/null
+++ b/arch/mips/pnx8550/Platform
@@ -0,0 +1,7 @@
+platform-$(CONFIG_SOC_PNX8550) += pnx8550/
+
+cflags-$(CONFIG_SOC_PNX8550) += \
+ -I$(srctree)/arch/mips/include/asm/mach-pnx8550
+
+load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000
+load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000
diff --git a/arch/mips/pnx8550/common/Makefile b/arch/mips/pnx8550/common/Makefile
new file mode 100644
index 00000000..f8ce695d
--- /dev/null
+++ b/arch/mips/pnx8550/common/Makefile
@@ -0,0 +1,26 @@
+#
+# Per Hallsmark, per.hallsmark@mvista.com
+#
+# ########################################################################
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# #######################################################################
+#
+# Makefile for the PNX8550 specific kernel interface routines
+# under Linux.
+#
+
+obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o
+obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/mips/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c
new file mode 100644
index 00000000..6b93c817
--- /dev/null
+++ b/arch/mips/pnx8550/common/int.c
@@ -0,0 +1,236 @@
+/*
+ *
+ * Copyright (C) 2005 Embedded Alley Solutions, Inc
+ * Ported to 2.6.
+ *
+ * Per Hallsmark, per.hallsmark@mvista.com
+ * Copyright (C) 2000, 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ *
+ * Cleaned up and bug fixing: Pete Popov, ppopov@embeddedalley.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ */
+#include <linux/compiler.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/random.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <int.h>
+#include <uart.h>
+
+/* default prio for interrupts */
+/* first one is a no-no so therefore always prio 0 (disabled) */
+static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
+ 0, 1, 1, 1, 1, 15, 1, 1, 1, 1, // 0 - 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 10 - 19
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 20 - 29
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 30 - 39
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 40 - 49
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, // 50 - 59
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 60 - 69
+ 1 // 70
+};
+
+static void hw0_irqdispatch(int irq)
+{
+ /* find out which interrupt */
+ irq = PNX8550_GIC_VECTOR_0 >> 3;
+
+ if (irq == 0) {
+ printk("hw0_irqdispatch: irq 0, spurious interrupt?\n");
+ return;
+ }
+ do_IRQ(PNX8550_INT_GIC_MIN + irq);
+}
+
+
+static void timer_irqdispatch(int irq)
+{
+ irq = (0x01c0 & read_c0_config7()) >> 6;
+
+ if (unlikely(irq == 0)) {
+ printk("timer_irqdispatch: irq 0, spurious interrupt?\n");
+ return;
+ }
+
+ if (irq & 0x1)
+ do_IRQ(PNX8550_INT_TIMER1);
+ if (irq & 0x2)
+ do_IRQ(PNX8550_INT_TIMER2);
+ if (irq & 0x4)
+ do_IRQ(PNX8550_INT_TIMER3);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP2)
+ hw0_irqdispatch(2);
+ else if (pending & STATUSF_IP7) {
+ if (read_c0_config7() & 0x01c0)
+ timer_irqdispatch(7);
+ } else
+ spurious_interrupt();
+}
+
+static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
+{
+ unsigned long status = read_c0_status();
+
+ status &= ~((clr_mask & 0xFF) << 8);
+ status |= (set_mask & 0xFF) << 8;
+
+ write_c0_status(status);
+}
+
+static inline void mask_gic_int(unsigned int irq_nr)
+{
+ /* interrupt disabled, bit 26(WE_ENABLE)=1 and bit 16(enable)=0 */
+ PNX8550_GIC_REQ(irq_nr) = 1<<28; /* set priority to 0 */
+}
+
+static inline void unmask_gic_int(unsigned int irq_nr)
+{
+ /* set prio mask to lower four bits and enable interrupt */
+ PNX8550_GIC_REQ(irq_nr) = (1<<26 | 1<<16) | (1<<28) | gic_prio[irq_nr];
+}
+
+static inline void mask_irq(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq;
+
+ if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
+ modify_cp0_intmask(1 << irq_nr, 0);
+ } else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_GIC_MAX)) {
+ mask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
+ } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_TIMER_MAX)) {
+ modify_cp0_intmask(1 << 7, 0);
+ } else {
+ printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
+ }
+}
+
+static inline void unmask_irq(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq;
+
+ if ((PNX8550_INT_CP0_MIN <= irq_nr) && (irq_nr <= PNX8550_INT_CP0_MAX)) {
+ modify_cp0_intmask(0, 1 << irq_nr);
+ } else if ((PNX8550_INT_GIC_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_GIC_MAX)) {
+ unmask_gic_int(irq_nr - PNX8550_INT_GIC_MIN);
+ } else if ((PNX8550_INT_TIMER_MIN <= irq_nr) &&
+ (irq_nr <= PNX8550_INT_TIMER_MAX)) {
+ modify_cp0_intmask(0, 1 << 7);
+ } else {
+ printk("mask_irq: irq %d doesn't exist!\n", irq_nr);
+ }
+}
+
+int pnx8550_set_gic_priority(int irq, int priority)
+{
+ int gic_irq = irq-PNX8550_INT_GIC_MIN;
+ int prev_priority = PNX8550_GIC_REQ(gic_irq) & 0xf;
+
+ gic_prio[gic_irq] = priority;
+ PNX8550_GIC_REQ(gic_irq) |= (0x10000000 | gic_prio[gic_irq]);
+
+ return prev_priority;
+}
+
+static struct irq_chip level_irq_type = {
+ .name = "PNX Level IRQ",
+ .irq_mask = mask_irq,
+ .irq_unmask = unmask_irq,
+};
+
+static struct irqaction gic_action = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED,
+ .name = "GIC",
+};
+
+static struct irqaction timer_action = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "Timer",
+};
+
+void __init arch_init_irq(void)
+{
+ int i;
+ int configPR;
+
+ for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++)
+ irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq);
+
+ /* init of GIC/IPC interrupts */
+ /* should be done before cp0 since cp0 init enables the GIC int */
+ for (i = PNX8550_INT_GIC_MIN; i <= PNX8550_INT_GIC_MAX; i++) {
+ int gic_int_line = i - PNX8550_INT_GIC_MIN;
+ if (gic_int_line == 0 )
+ continue; // don't fiddle with int 0
+ /*
+ * enable change of TARGET, ENABLE and ACTIVE_LOW bits
+ * set TARGET 0 to route through hw0 interrupt
+ * set ACTIVE_LOW 0 active high (correct?)
+ *
+ * We really should setup an interrupt description table
+ * to do this nicely.
+ * Note, PCI INTA is active low on the bus, but inverted
+ * in the GIC, so to us it's active high.
+ */
+ PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000;
+
+ /* mask/priority is still 0 so we will not get any
+ * interrupts until it is unmasked */
+
+ irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq);
+ }
+
+ /* Priority level 0 */
+ PNX8550_GIC_PRIMASK_0 = PNX8550_GIC_PRIMASK_1 = 0;
+
+ /* Set int vector table address */
+ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0;
+
+ irq_set_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type,
+ handle_level_irq);
+ setup_irq(MIPS_CPU_GIC_IRQ, &gic_action);
+
+ /* init of Timer interrupts */
+ for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++)
+ irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq);
+
+ /* Stop Timer 1-3 */
+ configPR = read_c0_config7();
+ configPR |= 0x00000038;
+ write_c0_config7(configPR);
+
+ irq_set_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type,
+ handle_level_irq);
+ setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action);
+}
+
+EXPORT_SYMBOL(pnx8550_set_gic_priority);
diff --git a/arch/mips/pnx8550/common/pci.c b/arch/mips/pnx8550/common/pci.c
new file mode 100644
index 00000000..98e86ddb
--- /dev/null
+++ b/arch/mips/pnx8550/common/pci.c
@@ -0,0 +1,134 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *
+ * Author: source@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <pci.h>
+#include <glb.h>
+#include <nand.h>
+
+static struct resource pci_io_resource = {
+ .start = PNX8550_PCIIO + 0x1000, /* reserve regacy I/O space */
+ .end = PNX8550_PCIIO + PNX8550_PCIIO_SIZE,
+ .name = "pci IO space",
+ .flags = IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+ .start = PNX8550_PCIMEM,
+ .end = PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1,
+ .name = "pci memory space",
+ .flags = IORESOURCE_MEM
+};
+
+extern struct pci_ops pnx8550_pci_ops;
+
+static struct pci_controller pnx8550_controller = {
+ .pci_ops = &pnx8550_pci_ops,
+ .io_map_base = PNX8550_PORT_BASE,
+ .io_resource = &pci_io_resource,
+ .mem_resource = &pci_mem_resource,
+};
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+static inline unsigned long get_system_mem_size(void)
+{
+ /* Read IP2031_RANK0_ADDR_LO */
+ unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+ /* Read IP2031_RANK1_ADDR_HI */
+ unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+ return dram_r1_hi - dram_r0_lo + 1;
+}
+
+static int __init pnx8550_pci_setup(void)
+{
+ int pci_mem_code;
+ int mem_size = get_system_mem_size() >> 20;
+
+ /* Clear the Global 2 Register, PCI Inta Output Enable Registers
+ Bit 1:Enable DAC Powerdown
+ -> 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+ Bit 0:Enable of PCI inta output
+ -> 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+ */
+ PNX8550_GLB2_ENAB_INTA_O = 0;
+
+ /* Calc the PCI mem size code */
+ if (mem_size >= 128)
+ pci_mem_code = SIZE_128M;
+ else if (mem_size >= 64)
+ pci_mem_code = SIZE_64M;
+ else if (mem_size >= 32)
+ pci_mem_code = SIZE_32M;
+ else
+ pci_mem_code = SIZE_16M;
+
+ /* Set PCI_XIO registers */
+ outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO);
+ outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI);
+ outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO);
+ outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI);
+
+ /* Send memory transaction via PCI_BASE2 */
+ outl(0x00000001, PCI_BASE | PCI_IO);
+
+ /* Unlock the setup register */
+ outl(0xca, PCI_BASE | PCI_UNLOCKREG);
+
+ /*
+ * BAR0 of PNX8550 (pci base 10) must be zero in order for ide
+ * to work, and in order for bus_to_baddr to work without any
+ * hacks.
+ */
+ outl(0x00000000, PCI_BASE | PCI_BASE10);
+
+ /*
+ *These two bars are set by default or the boot code.
+ * However, it's safer to set them here so we're not boot
+ * code dependent.
+ */
+ outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */
+ outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */
+
+ outl(PCI_EN_TA |
+ PCI_EN_PCI2MMI |
+ PCI_EN_XIO |
+ PCI_SETUP_BASE18_SIZE(SIZE_32M) |
+ PCI_SETUP_BASE18_EN |
+ PCI_SETUP_BASE14_EN |
+ PCI_SETUP_BASE10_PREF |
+ PCI_SETUP_BASE10_SIZE(pci_mem_code) |
+ PCI_SETUP_CFGMANAGE_EN |
+ PCI_SETUP_PCIARB_EN,
+ PCI_BASE |
+ PCI_SETUP); /* PCI_SETUP */
+ outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */
+
+ register_pci_controller(&pnx8550_controller);
+
+ return 0;
+}
+
+arch_initcall(pnx8550_pci_setup);
diff --git a/arch/mips/pnx8550/common/platform.c b/arch/mips/pnx8550/common/platform.c
new file mode 100644
index 00000000..5264cc09
--- /dev/null
+++ b/arch/mips/pnx8550/common/platform.c
@@ -0,0 +1,133 @@
+/*
+ * Platform device support for NXP PNX8550 SoCs
+ *
+ * Copyright 2005, Embedded Alley Solutions, Inc
+ *
+ * Based on arch/mips/au1000/common/platform.c
+ * Platform device support for Au1x00 SoCs.
+ *
+ * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial.h>
+#include <linux/serial_pnx8xxx.h>
+#include <linux/platform_device.h>
+
+#include <int.h>
+#include <usb.h>
+#include <uart.h>
+
+static struct resource pnx8550_usb_ohci_resources[] = {
+ [0] = {
+ .start = PNX8550_USB_OHCI_OP_BASE,
+ .end = PNX8550_USB_OHCI_OP_BASE +
+ PNX8550_USB_OHCI_OP_LEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8550_INT_USB,
+ .end = PNX8550_INT_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pnx8550_uart_resources[] = {
+ [0] = {
+ .start = PNX8550_UART_PORT0,
+ .end = PNX8550_UART_PORT0 + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PNX8550_UART_INT(0),
+ .end = PNX8550_UART_INT(0),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = PNX8550_UART_PORT1,
+ .end = PNX8550_UART_PORT1 + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = PNX8550_UART_INT(1),
+ .end = PNX8550_UART_INT(1),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct pnx8xxx_port pnx8xxx_ports[] = {
+ [0] = {
+ .port = {
+ .type = PORT_PNX8XXX,
+ .iotype = UPIO_MEM,
+ .membase = (void __iomem *)PNX8550_UART_PORT0,
+ .mapbase = PNX8550_UART_PORT0,
+ .irq = PNX8550_UART_INT(0),
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ },
+ [1] = {
+ .port = {
+ .type = PORT_PNX8XXX,
+ .iotype = UPIO_MEM,
+ .membase = (void __iomem *)PNX8550_UART_PORT1,
+ .mapbase = PNX8550_UART_PORT1,
+ .irq = PNX8550_UART_INT(1),
+ .uartclk = 3692300,
+ .fifosize = 16,
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ },
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+
+static u64 uart_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device pnx8550_usb_ohci_device = {
+ .name = "pnx8550-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources),
+ .resource = pnx8550_usb_ohci_resources,
+};
+
+static struct platform_device pnx8550_uart_device = {
+ .name = "pnx8xxx-uart",
+ .id = -1,
+ .dev = {
+ .dma_mask = &uart_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = pnx8xxx_ports,
+ },
+ .num_resources = ARRAY_SIZE(pnx8550_uart_resources),
+ .resource = pnx8550_uart_resources,
+};
+
+static struct platform_device *pnx8550_platform_devices[] __initdata = {
+ &pnx8550_usb_ohci_device,
+ &pnx8550_uart_device,
+};
+
+static int __init pnx8550_platform_init(void)
+{
+ return platform_add_devices(pnx8550_platform_devices,
+ ARRAY_SIZE(pnx8550_platform_devices));
+}
+
+arch_initcall(pnx8550_platform_init);
diff --git a/arch/mips/pnx8550/common/proc.c b/arch/mips/pnx8550/common/proc.c
new file mode 100644
index 00000000..3bba5ec8
--- /dev/null
+++ b/arch/mips/pnx8550/common/proc.c
@@ -0,0 +1,110 @@
+/*
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/random.h>
+
+#include <asm/io.h>
+#include <int.h>
+#include <uart.h>
+
+
+static int pnx8550_timers_read(char* page, char** start, off_t offset, int count, int* eof, void* data)
+{
+ int len = 0;
+ int configPR = read_c0_config7();
+
+ if (offset==0) {
+ len += sprintf(&page[len], "Timer: count, compare, tc, status\n");
+ len += sprintf(&page[len], " 1: %11i, %8i, %1i, %s\n",
+ read_c0_count(), read_c0_compare(),
+ (configPR>>6)&0x1, ((configPR>>3)&0x1)? "off":"on");
+ len += sprintf(&page[len], " 2: %11i, %8i, %1i, %s\n",
+ read_c0_count2(), read_c0_compare2(),
+ (configPR>>7)&0x1, ((configPR>>4)&0x1)? "off":"on");
+ len += sprintf(&page[len], " 3: %11i, %8i, %1i, %s\n",
+ read_c0_count3(), read_c0_compare3(),
+ (configPR>>8)&0x1, ((configPR>>5)&0x1)? "off":"on");
+ }
+
+ return len;
+}
+
+static int pnx8550_registers_read(char* page, char** start, off_t offset, int count, int* eof, void* data)
+{
+ int len = 0;
+
+ if (offset==0) {
+ len += sprintf(&page[len], "config1: %#10.8x\n", read_c0_config1());
+ len += sprintf(&page[len], "config2: %#10.8x\n", read_c0_config2());
+ len += sprintf(&page[len], "config3: %#10.8x\n", read_c0_config3());
+ len += sprintf(&page[len], "configPR: %#10.8x\n", read_c0_config7());
+ len += sprintf(&page[len], "status: %#10.8x\n", read_c0_status());
+ len += sprintf(&page[len], "cause: %#10.8x\n", read_c0_cause());
+ len += sprintf(&page[len], "count: %#10.8x\n", read_c0_count());
+ len += sprintf(&page[len], "count_2: %#10.8x\n", read_c0_count2());
+ len += sprintf(&page[len], "count_3: %#10.8x\n", read_c0_count3());
+ len += sprintf(&page[len], "compare: %#10.8x\n", read_c0_compare());
+ len += sprintf(&page[len], "compare_2: %#10.8x\n", read_c0_compare2());
+ len += sprintf(&page[len], "compare_3: %#10.8x\n", read_c0_compare3());
+ }
+
+ return len;
+}
+
+static struct proc_dir_entry* pnx8550_dir;
+static struct proc_dir_entry* pnx8550_timers;
+static struct proc_dir_entry* pnx8550_registers;
+
+static int pnx8550_proc_init( void )
+{
+
+ // Create /proc/pnx8550
+ pnx8550_dir = proc_mkdir("pnx8550", NULL);
+ if (!pnx8550_dir) {
+ printk(KERN_ERR "Can't create pnx8550 proc dir\n");
+ return -1;
+ }
+
+ // Create /proc/pnx8550/timers
+ pnx8550_timers = create_proc_read_entry(
+ "timers",
+ 0,
+ pnx8550_dir,
+ pnx8550_timers_read,
+ NULL);
+
+ if (!pnx8550_timers)
+ printk(KERN_ERR "Can't create pnx8550 timers proc file\n");
+
+ // Create /proc/pnx8550/registers
+ pnx8550_registers = create_proc_read_entry(
+ "registers",
+ 0,
+ pnx8550_dir,
+ pnx8550_registers_read,
+ NULL);
+
+ if (!pnx8550_registers)
+ printk(KERN_ERR "Can't create pnx8550 registers proc file\n");
+
+ return 0;
+}
+
+__initcall(pnx8550_proc_init);
diff --git a/arch/mips/pnx8550/common/prom.c b/arch/mips/pnx8550/common/prom.c
new file mode 100644
index 00000000..32f70097
--- /dev/null
+++ b/arch/mips/pnx8550/common/prom.c
@@ -0,0 +1,128 @@
+/*
+ *
+ * Per Hallsmark, per.hallsmark@mvista.com
+ *
+ * Based on jmr3927/common/prom.c
+ *
+ * 2004 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/serial_pnx8xxx.h>
+
+#include <asm/bootinfo.h>
+#include <uart.h>
+
+/* #define DEBUG_CMDLINE */
+
+extern int prom_argc;
+extern char **prom_argv, **prom_envp;
+
+typedef struct
+{
+ char *name;
+/* char *val; */
+}t_env_var;
+
+
+char * prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+void __init prom_init_cmdline(void)
+{
+ int i;
+
+ arcs_cmdline[0] = '\0';
+ for (i = 0; i < prom_argc; i++) {
+ strcat(arcs_cmdline, prom_argv[i]);
+ strcat(arcs_cmdline, " ");
+ }
+}
+
+char *prom_getenv(char *envname)
+{
+ /*
+ * Return a pointer to the given environment variable.
+ * Environment variables are stored in the form of "memsize=64".
+ */
+
+ t_env_var *env = (t_env_var *)prom_envp;
+ int i;
+
+ i = strlen(envname);
+
+ while(env->name) {
+ if(strncmp(envname, env->name, i) == 0) {
+ return(env->name + strlen(envname) + 1);
+ }
+ env++;
+ }
+ return(NULL);
+}
+
+inline unsigned char str2hexnum(unsigned char c)
+{
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ if(c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if(c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return 0; /* foo */
+}
+
+inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for(i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if((*str == '.') || (*str == ':'))
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= (str2hexnum(*str++));
+ ea[i] = num;
+ }
+}
+
+int get_ethernet_addr(char *ethernet_addr)
+{
+ char *ethaddr_str;
+
+ ethaddr_str = prom_getenv("ethaddr");
+ if (!ethaddr_str) {
+ printk("ethaddr not set in boot prom\n");
+ return -1;
+ }
+ str2eaddr(ethernet_addr, ethaddr_str);
+ return 0;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+extern int pnx8550_console_port;
+
+/* used by early printk */
+void prom_putchar(char c)
+{
+ if (pnx8550_console_port != -1) {
+ /* Wait until FIFO not full */
+ while( ((ip3106_fifo(UART_BASE, pnx8550_console_port) & PNX8XXX_UART_FIFO_TXFIFO) >> 16) >= 16)
+ ;
+ /* Send one char */
+ ip3106_fifo(UART_BASE, pnx8550_console_port) = c;
+ }
+}
+
+EXPORT_SYMBOL(get_ethernet_addr);
+EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/pnx8550/common/reset.c b/arch/mips/pnx8550/common/reset.c
new file mode 100644
index 00000000..e7a12ff3
--- /dev/null
+++ b/arch/mips/pnx8550/common/reset.c
@@ -0,0 +1,40 @@
+/*.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * Reset the PNX8550 board.
+ *
+ */
+#include <linux/kernel.h>
+
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <glb.h>
+
+void pnx8550_machine_restart(char *command)
+{
+ PNX8550_RST_CTL = PNX8550_RST_DO_SW_RST;
+}
+
+void pnx8550_machine_halt(void)
+{
+ while (1) {
+ if (cpu_wait)
+ cpu_wait();
+ }
+}
diff --git a/arch/mips/pnx8550/common/setup.c b/arch/mips/pnx8550/common/setup.c
new file mode 100644
index 00000000..43cb3945
--- /dev/null
+++ b/arch/mips/pnx8550/common/setup.c
@@ -0,0 +1,144 @@
+/*
+ *
+ * 2.6 port, Embedded Alley Solutions, Inc
+ *
+ * Based on Per Hallsmark, per.hallsmark@mvista.com
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/serial_pnx8xxx.h>
+#include <linux/pm.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+
+#include <glb.h>
+#include <int.h>
+#include <pci.h>
+#include <uart.h>
+#include <nand.h>
+
+extern void __init board_setup(void);
+extern void pnx8550_machine_restart(char *);
+extern void pnx8550_machine_halt(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
+extern char *prom_getcmdline(void);
+
+struct resource standard_io_resources[] = {
+ {
+ .start = 0x00,
+ .end = 0x1f,
+ .name = "dma1",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x40,
+ .end = 0x5f,
+ .name = "timer",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x80,
+ .end = 0x8f,
+ .name = "dma page reg",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0xc0,
+ .end = 0xdf,
+ .name = "dma2",
+ .flags = IORESOURCE_BUSY
+ },
+};
+
+#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources)
+
+extern struct resource pci_io_resource;
+extern struct resource pci_mem_resource;
+
+/* Return the total size of DRAM-memory, (RANK0 + RANK1) */
+unsigned long get_system_mem_size(void)
+{
+ /* Read IP2031_RANK0_ADDR_LO */
+ unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010);
+ /* Read IP2031_RANK1_ADDR_HI */
+ unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018);
+
+ return dram_r1_hi - dram_r0_lo + 1;
+}
+
+int pnx8550_console_port = -1;
+
+void __init plat_mem_setup(void)
+{
+ int i;
+ char* argptr;
+
+ board_setup(); /* board specific setup */
+
+ _machine_restart = pnx8550_machine_restart;
+ _machine_halt = pnx8550_machine_halt;
+ pm_power_off = pnx8550_machine_halt;
+
+ /* Clear the Global 2 Register, PCI Inta Output Enable Registers
+ Bit 1:Enable DAC Powerdown
+ -> 0:DACs are enabled and are working normally
+ 1:DACs are powerdown
+ Bit 0:Enable of PCI inta output
+ -> 0 = Disable PCI inta output
+ 1 = Enable PCI inta output
+ */
+ PNX8550_GLB2_ENAB_INTA_O = 0;
+
+ /* IO/MEM resources. */
+ set_io_port_base(PNX8550_PORT_BASE);
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+ iomem_resource.start = 0;
+ iomem_resource.end = ~0;
+
+ /* Request I/O space for devices on this board */
+ for (i = 0; i < STANDARD_IO_RESOURCES; i++)
+ request_resource(&ioport_resource, standard_io_resources + i);
+
+ /* Place the Mode Control bit for GPIO pin 16 in primary function */
+ /* Pin 16 is used by UART1, UA1_TX */
+ outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) |
+ (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT),
+ PNX8550_GPIO_MC1);
+
+ argptr = prom_getcmdline();
+ if ((argptr = strstr(argptr, "console=ttyS")) != NULL) {
+ argptr += strlen("console=ttyS");
+ pnx8550_console_port = *argptr == '0' ? 0 : 1;
+
+ /* We must initialize the UART (console) before early printk */
+ /* Set LCR to 8-bit and BAUD to 38400 (no 5) */
+ ip3106_lcr(UART_BASE, pnx8550_console_port) =
+ PNX8XXX_UART_LCR_8BIT;
+ ip3106_baud(UART_BASE, pnx8550_console_port) = 5;
+ }
+
+ return;
+}
diff --git a/arch/mips/pnx8550/common/time.c b/arch/mips/pnx8550/common/time.c
new file mode 100644
index 00000000..8836c620
--- /dev/null
+++ b/arch/mips/pnx8550/common/time.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2001, 2002, 2003 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * Common time service routines for MIPS machines. See
+ * Documents/MIPS/README.txt.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include <asm/time.h>
+#include <asm/hardirq.h>
+#include <asm/div64.h>
+#include <asm/debug.h>
+
+#include <int.h>
+#include <cm.h>
+
+static unsigned long cpj;
+
+static cycle_t hpt_read(struct clocksource *cs)
+{
+ return read_c0_count2();
+}
+
+static struct clocksource pnx_clocksource = {
+ .name = "pnx8xxx",
+ .rating = 200,
+ .read = hpt_read,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *c = dev_id;
+
+ /* clear MATCH, signal the event */
+ c->event_handler(c);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction pnx8xxx_timer_irq = {
+ .handler = pnx8xxx_timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "pnx8xxx_timer",
+};
+
+static irqreturn_t monotonic_interrupt(int irq, void *dev_id)
+{
+ /* Timer 2 clear interrupt */
+ write_c0_compare2(-1);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction monotonic_irqaction = {
+ .handler = monotonic_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "Monotonic timer",
+};
+
+static int pnx8xxx_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ write_c0_compare(delta);
+ return 0;
+}
+
+static struct clock_event_device pnx8xxx_clockevent = {
+ .name = "pnx8xxx_clockevent",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = pnx8xxx_set_next_event,
+};
+
+static inline void timer_ack(void)
+{
+ write_c0_compare(cpj);
+}
+
+__init void plat_time_init(void)
+{
+ unsigned int configPR;
+ unsigned int n;
+ unsigned int m;
+ unsigned int p;
+ unsigned int pow2p;
+
+ pnx8xxx_clockevent.cpumask = cpu_none_mask;
+ clockevents_register_device(&pnx8xxx_clockevent);
+ clocksource_register(&pnx_clocksource);
+
+ /* Timer 1 start */
+ configPR = read_c0_config7();
+ configPR &= ~0x00000008;
+ write_c0_config7(configPR);
+
+ /* Timer 2 start */
+ configPR = read_c0_config7();
+ configPR &= ~0x00000010;
+ write_c0_config7(configPR);
+
+ /* Timer 3 stop */
+ configPR = read_c0_config7();
+ configPR |= 0x00000020;
+ write_c0_config7(configPR);
+
+
+ /* PLL0 sets MIPS clock (PLL1 <=> TM1, PLL6 <=> TM2, PLL5 <=> mem) */
+ /* (but only if CLK_MIPS_CTL select value [bits 3:1] is 1: FIXME) */
+
+ n = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_N_MASK) >> 16;
+ m = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_M_MASK) >> 8;
+ p = (PNX8550_CM_PLL0_CTL & PNX8550_CM_PLL_P_MASK) >> 2;
+ pow2p = (1 << p);
+
+ db_assert(m != 0 && pow2p != 0);
+
+ /*
+ * Compute the frequency as in the PNX8550 User Manual 1.0, p.186
+ * (a.k.a. 8-10). Divide by HZ for a timer offset that results in
+ * HZ timer interrupts per second.
+ */
+ mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p));
+ cpj = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ);
+ write_c0_count(0);
+ timer_ack();
+
+ /* Setup Timer 2 */
+ write_c0_count2(0);
+ write_c0_compare2(0xffffffff);
+
+ setup_irq(PNX8550_INT_TIMER1, &pnx8xxx_timer_irq);
+ setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction);
+}
diff --git a/arch/mips/pnx8550/jbs/Makefile b/arch/mips/pnx8550/jbs/Makefile
new file mode 100644
index 00000000..c4dc3d53
--- /dev/null
+++ b/arch/mips/pnx8550/jbs/Makefile
@@ -0,0 +1,4 @@
+
+# Makefile for the NXP JBS Board.
+
+obj-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/pnx8550/jbs/board_setup.c b/arch/mips/pnx8550/jbs/board_setup.c
new file mode 100644
index 00000000..57dd903c
--- /dev/null
+++ b/arch/mips/pnx8550/jbs/board_setup.c
@@ -0,0 +1,56 @@
+/*
+ * JBS Specific board startup routines.
+ *
+ * Copyright 2005, Embedded Alley Solutions, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+
+#include <glb.h>
+
+/* CP0 hazard avoidance. */
+#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
+ "nop; nop; nop; nop; nop; nop;\n\t" \
+ ".set reorder\n\t")
+
+void __init board_setup(void)
+{
+ unsigned long configpr;
+
+ configpr = read_c0_config7();
+ configpr |= (1<<19); /* enable tlb */
+ write_c0_config7(configpr);
+ BARRIER;
+}
diff --git a/arch/mips/pnx8550/jbs/init.c b/arch/mips/pnx8550/jbs/init.c
new file mode 100644
index 00000000..d59b4a4e
--- /dev/null
+++ b/arch/mips/pnx8550/jbs/init.c
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddedalley.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+ return "NXP PNX8550/JBS";
+}
+
+void __init prom_init(void)
+{
+ unsigned long memsize;
+
+ //memsize = 0x02800000; /* Trimedia uses memory above */
+ memsize = 0x08000000; /* Trimedia uses memory above */
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/pnx8550/jbs/irqmap.c b/arch/mips/pnx8550/jbs/irqmap.c
new file mode 100644
index 00000000..7fc89842
--- /dev/null
+++ b/arch/mips/pnx8550/jbs/irqmap.c
@@ -0,0 +1,35 @@
+/*
+ * NXP JBS board irqmap.
+ *
+ * Copyright 2005 Embedded Alley Solutions, Inc
+ * source@embeddealley.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <int.h>
+
+char pnx8550_irq_tab[][5] __initdata = {
+ [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+ [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+ [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+};
diff --git a/arch/mips/pnx8550/stb810/Makefile b/arch/mips/pnx8550/stb810/Makefile
new file mode 100644
index 00000000..cb4ff022
--- /dev/null
+++ b/arch/mips/pnx8550/stb810/Makefile
@@ -0,0 +1,4 @@
+
+# Makefile for the NXP STB810 Board.
+
+obj-y := prom_init.o board_setup.o irqmap.o
diff --git a/arch/mips/pnx8550/stb810/board_setup.c b/arch/mips/pnx8550/stb810/board_setup.c
new file mode 100644
index 00000000..af2a55e0
--- /dev/null
+++ b/arch/mips/pnx8550/stb810/board_setup.c
@@ -0,0 +1,41 @@
+/*
+ * STB810 specific board startup routines.
+ *
+ * Based on the arch/mips/nxp/pnx8550/jbs/board_setup.c
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2005 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+
+#include <asm/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/pgtable.h>
+
+#include <glb.h>
+
+void __init board_setup(void)
+{
+ unsigned long configpr;
+
+ configpr = read_c0_config7();
+ configpr |= (1<<19); /* enable tlb */
+ write_c0_config7(configpr);
+}
diff --git a/arch/mips/pnx8550/stb810/irqmap.c b/arch/mips/pnx8550/stb810/irqmap.c
new file mode 100644
index 00000000..8c034963
--- /dev/null
+++ b/arch/mips/pnx8550/stb810/irqmap.c
@@ -0,0 +1,22 @@
+/*
+ * NXP STB810 board irqmap.
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2005 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <int.h>
+
+char pnx8550_irq_tab[][5] __initdata = {
+ [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+ [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+ [10] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff},
+};
diff --git a/arch/mips/pnx8550/stb810/prom_init.c b/arch/mips/pnx8550/stb810/prom_init.c
new file mode 100644
index 00000000..ca7f4ada
--- /dev/null
+++ b/arch/mips/pnx8550/stb810/prom_init.c
@@ -0,0 +1,46 @@
+/*
+ * STB810 specific prom routines
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2005 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+extern void __init prom_init_cmdline(void);
+extern char *prom_getenv(char *envname);
+
+const char *get_system_type(void)
+{
+ return "NXP PNX8950/STB810";
+}
+
+void __init prom_init(void)
+{
+ unsigned long memsize;
+
+ prom_argc = (int) fw_arg0;
+ prom_argv = (char **) fw_arg1;
+ prom_envp = (char **) fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize = 0x08000000; /* Trimedia uses memory above */
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/power/Makefile b/arch/mips/power/Makefile
new file mode 100644
index 00000000..73d56b87
--- /dev/null
+++ b/arch/mips/power/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_HIBERNATION) += cpu.o hibernate.o
diff --git a/arch/mips/power/cpu.c b/arch/mips/power/cpu.c
new file mode 100644
index 00000000..26a6ef19
--- /dev/null
+++ b/arch/mips/power/cpu.c
@@ -0,0 +1,43 @@
+/*
+ * Suspend support specific for mips.
+ *
+ * Licensed under the GPLv2
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Hu Hongbing <huhb@lemote.com>
+ * Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+#include <asm/suspend.h>
+#include <asm/fpu.h>
+#include <asm/dsp.h>
+
+static u32 saved_status;
+struct pt_regs saved_regs;
+
+void save_processor_state(void)
+{
+ saved_status = read_c0_status();
+
+ if (is_fpu_owner())
+ save_fp(current);
+ if (cpu_has_dsp)
+ save_dsp(current);
+}
+
+void restore_processor_state(void)
+{
+ write_c0_status(saved_status);
+
+ if (is_fpu_owner())
+ restore_fp(current);
+ if (cpu_has_dsp)
+ restore_dsp(current);
+}
+
+int pfn_is_nosave(unsigned long pfn)
+{
+ unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
+ unsigned long nosave_end_pfn = PFN_UP(__pa(&__nosave_end));
+
+ return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+}
diff --git a/arch/mips/power/hibernate.S b/arch/mips/power/hibernate.S
new file mode 100644
index 00000000..f8a751c0
--- /dev/null
+++ b/arch/mips/power/hibernate.S
@@ -0,0 +1,62 @@
+/*
+ * Hibernation support specific for mips - temporary page tables
+ *
+ * Licensed under the GPLv2
+ *
+ * Copyright (C) 2009 Lemote Inc.
+ * Author: Hu Hongbing <huhb@lemote.com>
+ * Wu Zhangjin <wuzhangjin@gmail.com>
+ */
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+.text
+LEAF(swsusp_arch_suspend)
+ PTR_LA t0, saved_regs
+ PTR_S ra, PT_R31(t0)
+ PTR_S sp, PT_R29(t0)
+ PTR_S fp, PT_R30(t0)
+ PTR_S gp, PT_R28(t0)
+ PTR_S s0, PT_R16(t0)
+ PTR_S s1, PT_R17(t0)
+ PTR_S s2, PT_R18(t0)
+ PTR_S s3, PT_R19(t0)
+ PTR_S s4, PT_R20(t0)
+ PTR_S s5, PT_R21(t0)
+ PTR_S s6, PT_R22(t0)
+ PTR_S s7, PT_R23(t0)
+ j swsusp_save
+END(swsusp_arch_suspend)
+
+LEAF(swsusp_arch_resume)
+ PTR_L t0, restore_pblist
+0:
+ PTR_L t1, PBE_ADDRESS(t0) /* source */
+ PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */
+ PTR_ADDU t3, t1, PAGE_SIZE
+1:
+ REG_L t8, (t1)
+ REG_S t8, (t2)
+ PTR_ADDIU t1, t1, SZREG
+ PTR_ADDIU t2, t2, SZREG
+ bne t1, t3, 1b
+ PTR_L t0, PBE_NEXT(t0)
+ bnez t0, 0b
+ PTR_LA t0, saved_regs
+ PTR_L ra, PT_R31(t0)
+ PTR_L sp, PT_R29(t0)
+ PTR_L fp, PT_R30(t0)
+ PTR_L gp, PT_R28(t0)
+ PTR_L s0, PT_R16(t0)
+ PTR_L s1, PT_R17(t0)
+ PTR_L s2, PT_R18(t0)
+ PTR_L s3, PT_R19(t0)
+ PTR_L s4, PT_R20(t0)
+ PTR_L s5, PT_R21(t0)
+ PTR_L s6, PT_R22(t0)
+ PTR_L s7, PT_R23(t0)
+ PTR_LI v0, 0x0
+ jr ra
+END(swsusp_arch_resume)
diff --git a/arch/mips/powertv/Kconfig b/arch/mips/powertv/Kconfig
new file mode 100644
index 00000000..ff0e7e3e
--- /dev/null
+++ b/arch/mips/powertv/Kconfig
@@ -0,0 +1,21 @@
+source "arch/mips/powertv/asic/Kconfig"
+
+config BOOTLOADER_DRIVER
+ bool "PowerTV Bootloader Driver Support"
+ default n
+ depends on POWERTV
+ help
+ Use this option if you want to load bootloader driver.
+
+config BOOTLOADER_FAMILY
+ string "POWERTV Bootloader Family string"
+ default "85"
+ depends on POWERTV && !BOOTLOADER_DRIVER
+ help
+ This value should be specified when the bootloader driver is disabled
+ and must be exactly two characters long. Families supported are:
+ R1 - RNG-100 R2 - RNG-200
+ A1 - Class A B1 - Class B
+ E1 - Class E F1 - Class F
+ 44 - 45xx 46 - 46xx
+ 85 - 85xx 86 - 86xx
diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile
new file mode 100644
index 00000000..348d2e85
--- /dev/null
+++ b/arch/mips/powertv/Makefile
@@ -0,0 +1,31 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+# Portions copyright (C) 2009 Cisco Systems, Inc.
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Makefile for the Cisco PowerTV-specific kernel interface routines
+# under Linux.
+#
+
+obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \
+ asic/ pci/
+
+obj-$(CONFIG_USB) += powertv-usb.o
+
+ccflags-y := -Wall
diff --git a/arch/mips/powertv/Platform b/arch/mips/powertv/Platform
new file mode 100644
index 00000000..4eb5af1d
--- /dev/null
+++ b/arch/mips/powertv/Platform
@@ -0,0 +1,7 @@
+#
+# Cisco PowerTV Platform
+#
+platform-$(CONFIG_POWERTV) += powertv/
+cflags-$(CONFIG_POWERTV) += \
+ -I$(srctree)/arch/mips/include/asm/mach-powertv
+load-$(CONFIG_POWERTV) += 0xffffffff90800000
diff --git a/arch/mips/powertv/asic/Kconfig b/arch/mips/powertv/asic/Kconfig
new file mode 100644
index 00000000..2016bfe9
--- /dev/null
+++ b/arch/mips/powertv/asic/Kconfig
@@ -0,0 +1,28 @@
+config MIN_RUNTIME_RESOURCES
+ bool "Support for minimum runtime resources"
+ default n
+ depends on POWERTV
+ help
+ Enables support for minimizing the number of (SA asic) runtime
+ resources that are preallocated by the kernel.
+
+config MIN_RUNTIME_DOCSIS
+ bool "Support for minimum DOCSIS resource"
+ default y
+ depends on MIN_RUNTIME_RESOURCES
+ help
+ Enables support for the preallocated DOCSIS resource.
+
+config MIN_RUNTIME_PMEM
+ bool "Support for minimum PMEM resource"
+ default y
+ depends on MIN_RUNTIME_RESOURCES
+ help
+ Enables support for the preallocated Memory resource.
+
+config MIN_RUNTIME_TFTP
+ bool "Support for minimum TFTP resource"
+ default y
+ depends on MIN_RUNTIME_RESOURCES
+ help
+ Enables support for the preallocated TFTP resource.
diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile
new file mode 100644
index 00000000..d810a331
--- /dev/null
+++ b/arch/mips/powertv/asic/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2009 Scientific-Atlanta, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \
+ asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \
+ prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o
+
+ccflags-y := -Wall -Werror
diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c
new file mode 100644
index 00000000..0a170e0f
--- /dev/null
+++ b/arch/mips/powertv/asic/asic-calliope.c
@@ -0,0 +1,101 @@
+/*
+ * Locations of devices in the Calliope ASIC.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ken Eppinett
+ * David Schleef <ds@schleef.org>
+ *
+ * Description: Defines the platform resources for the SA settop.
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+#define CALLIOPE_ADDR(x) (CALLIOPE_IO_BASE + (x))
+
+const struct register_map calliope_register_map __initdata = {
+ .eic_slow0_strt_add = {.phys = CALLIOPE_ADDR(0x800000)},
+ .eic_cfg_bits = {.phys = CALLIOPE_ADDR(0x800038)},
+ .eic_ready_status = {.phys = CALLIOPE_ADDR(0x80004c)},
+
+ .chipver3 = {.phys = CALLIOPE_ADDR(0xA00800)},
+ .chipver2 = {.phys = CALLIOPE_ADDR(0xA00804)},
+ .chipver1 = {.phys = CALLIOPE_ADDR(0xA00808)},
+ .chipver0 = {.phys = CALLIOPE_ADDR(0xA0080c)},
+
+ /* The registers of IRBlaster */
+ .uart1_intstat = {.phys = CALLIOPE_ADDR(0xA01800)},
+ .uart1_inten = {.phys = CALLIOPE_ADDR(0xA01804)},
+ .uart1_config1 = {.phys = CALLIOPE_ADDR(0xA01808)},
+ .uart1_config2 = {.phys = CALLIOPE_ADDR(0xA0180C)},
+ .uart1_divisorhi = {.phys = CALLIOPE_ADDR(0xA01810)},
+ .uart1_divisorlo = {.phys = CALLIOPE_ADDR(0xA01814)},
+ .uart1_data = {.phys = CALLIOPE_ADDR(0xA01818)},
+ .uart1_status = {.phys = CALLIOPE_ADDR(0xA0181C)},
+
+ .int_stat_3 = {.phys = CALLIOPE_ADDR(0xA02800)},
+ .int_stat_2 = {.phys = CALLIOPE_ADDR(0xA02804)},
+ .int_stat_1 = {.phys = CALLIOPE_ADDR(0xA02808)},
+ .int_stat_0 = {.phys = CALLIOPE_ADDR(0xA0280c)},
+ .int_config = {.phys = CALLIOPE_ADDR(0xA02810)},
+ .int_int_scan = {.phys = CALLIOPE_ADDR(0xA02818)},
+ .ien_int_3 = {.phys = CALLIOPE_ADDR(0xA02830)},
+ .ien_int_2 = {.phys = CALLIOPE_ADDR(0xA02834)},
+ .ien_int_1 = {.phys = CALLIOPE_ADDR(0xA02838)},
+ .ien_int_0 = {.phys = CALLIOPE_ADDR(0xA0283c)},
+ .int_level_3_3 = {.phys = CALLIOPE_ADDR(0xA02880)},
+ .int_level_3_2 = {.phys = CALLIOPE_ADDR(0xA02884)},
+ .int_level_3_1 = {.phys = CALLIOPE_ADDR(0xA02888)},
+ .int_level_3_0 = {.phys = CALLIOPE_ADDR(0xA0288c)},
+ .int_level_2_3 = {.phys = CALLIOPE_ADDR(0xA02890)},
+ .int_level_2_2 = {.phys = CALLIOPE_ADDR(0xA02894)},
+ .int_level_2_1 = {.phys = CALLIOPE_ADDR(0xA02898)},
+ .int_level_2_0 = {.phys = CALLIOPE_ADDR(0xA0289c)},
+ .int_level_1_3 = {.phys = CALLIOPE_ADDR(0xA028a0)},
+ .int_level_1_2 = {.phys = CALLIOPE_ADDR(0xA028a4)},
+ .int_level_1_1 = {.phys = CALLIOPE_ADDR(0xA028a8)},
+ .int_level_1_0 = {.phys = CALLIOPE_ADDR(0xA028ac)},
+ .int_level_0_3 = {.phys = CALLIOPE_ADDR(0xA028b0)},
+ .int_level_0_2 = {.phys = CALLIOPE_ADDR(0xA028b4)},
+ .int_level_0_1 = {.phys = CALLIOPE_ADDR(0xA028b8)},
+ .int_level_0_0 = {.phys = CALLIOPE_ADDR(0xA028bc)},
+ .int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)},
+
+ .mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)},
+ .fs432x4b4_usb_ctl = {.phys = CALLIOPE_ADDR(0x980030)},
+ .test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)},
+ .crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)},
+ .usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)},
+ .usb2_strap = {.phys = CALLIOPE_ADDR(0x9A0014)},
+ .ehci_hcapbase = {.phys = CALLIOPE_ADDR(0x9BFE00)},
+ .ohci_hc_revision = {.phys = CALLIOPE_ADDR(0x9BFC00)},
+ .bcm1_bs_lmi_steer = {.phys = CALLIOPE_ADDR(0x9E0004)},
+ .usb2_control = {.phys = CALLIOPE_ADDR(0x9E0054)},
+ .usb2_stbus_obc = {.phys = CALLIOPE_ADDR(0x9BFF00)},
+ .usb2_stbus_mess_size = {.phys = CALLIOPE_ADDR(0x9BFF04)},
+ .usb2_stbus_chunk_size = {.phys = CALLIOPE_ADDR(0x9BFF08)},
+
+ .pcie_regs = {.phys = 0x000000}, /* -doesn't exist- */
+ .tim_ch = {.phys = CALLIOPE_ADDR(0xA02C10)},
+ .tim_cl = {.phys = CALLIOPE_ADDR(0xA02C14)},
+ .gpio_dout = {.phys = CALLIOPE_ADDR(0xA02c20)},
+ .gpio_din = {.phys = CALLIOPE_ADDR(0xA02c24)},
+ .gpio_dir = {.phys = CALLIOPE_ADDR(0xA02c2C)},
+ .watchdog = {.phys = CALLIOPE_ADDR(0xA02c30)},
+ .front_panel = {.phys = 0x000000}, /* -not used- */
+};
diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c
new file mode 100644
index 00000000..bbc0c122
--- /dev/null
+++ b/arch/mips/powertv/asic/asic-cronus.c
@@ -0,0 +1,101 @@
+/*
+ * Locations of devices in the Cronus ASIC
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ken Eppinett
+ * David Schleef <ds@schleef.org>
+ *
+ * Description: Defines the platform resources for the SA settop.
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+#define CRONUS_ADDR(x) (CRONUS_IO_BASE + (x))
+
+const struct register_map cronus_register_map __initdata = {
+ .eic_slow0_strt_add = {.phys = CRONUS_ADDR(0x000000)},
+ .eic_cfg_bits = {.phys = CRONUS_ADDR(0x000038)},
+ .eic_ready_status = {.phys = CRONUS_ADDR(0x00004C)},
+
+ .chipver3 = {.phys = CRONUS_ADDR(0x2A0800)},
+ .chipver2 = {.phys = CRONUS_ADDR(0x2A0804)},
+ .chipver1 = {.phys = CRONUS_ADDR(0x2A0808)},
+ .chipver0 = {.phys = CRONUS_ADDR(0x2A080C)},
+
+ /* The registers of IRBlaster */
+ .uart1_intstat = {.phys = CRONUS_ADDR(0x2A1800)},
+ .uart1_inten = {.phys = CRONUS_ADDR(0x2A1804)},
+ .uart1_config1 = {.phys = CRONUS_ADDR(0x2A1808)},
+ .uart1_config2 = {.phys = CRONUS_ADDR(0x2A180C)},
+ .uart1_divisorhi = {.phys = CRONUS_ADDR(0x2A1810)},
+ .uart1_divisorlo = {.phys = CRONUS_ADDR(0x2A1814)},
+ .uart1_data = {.phys = CRONUS_ADDR(0x2A1818)},
+ .uart1_status = {.phys = CRONUS_ADDR(0x2A181C)},
+
+ .int_stat_3 = {.phys = CRONUS_ADDR(0x2A2800)},
+ .int_stat_2 = {.phys = CRONUS_ADDR(0x2A2804)},
+ .int_stat_1 = {.phys = CRONUS_ADDR(0x2A2808)},
+ .int_stat_0 = {.phys = CRONUS_ADDR(0x2A280C)},
+ .int_config = {.phys = CRONUS_ADDR(0x2A2810)},
+ .int_int_scan = {.phys = CRONUS_ADDR(0x2A2818)},
+ .ien_int_3 = {.phys = CRONUS_ADDR(0x2A2830)},
+ .ien_int_2 = {.phys = CRONUS_ADDR(0x2A2834)},
+ .ien_int_1 = {.phys = CRONUS_ADDR(0x2A2838)},
+ .ien_int_0 = {.phys = CRONUS_ADDR(0x2A283C)},
+ .int_level_3_3 = {.phys = CRONUS_ADDR(0x2A2880)},
+ .int_level_3_2 = {.phys = CRONUS_ADDR(0x2A2884)},
+ .int_level_3_1 = {.phys = CRONUS_ADDR(0x2A2888)},
+ .int_level_3_0 = {.phys = CRONUS_ADDR(0x2A288C)},
+ .int_level_2_3 = {.phys = CRONUS_ADDR(0x2A2890)},
+ .int_level_2_2 = {.phys = CRONUS_ADDR(0x2A2894)},
+ .int_level_2_1 = {.phys = CRONUS_ADDR(0x2A2898)},
+ .int_level_2_0 = {.phys = CRONUS_ADDR(0x2A289C)},
+ .int_level_1_3 = {.phys = CRONUS_ADDR(0x2A28A0)},
+ .int_level_1_2 = {.phys = CRONUS_ADDR(0x2A28A4)},
+ .int_level_1_1 = {.phys = CRONUS_ADDR(0x2A28A8)},
+ .int_level_1_0 = {.phys = CRONUS_ADDR(0x2A28AC)},
+ .int_level_0_3 = {.phys = CRONUS_ADDR(0x2A28B0)},
+ .int_level_0_2 = {.phys = CRONUS_ADDR(0x2A28B4)},
+ .int_level_0_1 = {.phys = CRONUS_ADDR(0x2A28B8)},
+ .int_level_0_0 = {.phys = CRONUS_ADDR(0x2A28BC)},
+ .int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)},
+
+ .mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)},
+ .fs432x4b4_usb_ctl = {.phys = CRONUS_ADDR(0x1C0028)},
+ .test_bus = {.phys = CRONUS_ADDR(0x1C00CC)},
+ .crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)},
+ .usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)},
+ .usb2_strap = {.phys = CRONUS_ADDR(0x200014)},
+ .ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)},
+ .ohci_hc_revision = {.phys = CRONUS_ADDR(0x21fc00)},
+ .bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)},
+ .usb2_control = {.phys = CRONUS_ADDR(0x2E004C)},
+ .usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)},
+ .usb2_stbus_mess_size = {.phys = CRONUS_ADDR(0x21FF04)},
+ .usb2_stbus_chunk_size = {.phys = CRONUS_ADDR(0x21FF08)},
+
+ .pcie_regs = {.phys = CRONUS_ADDR(0x220000)},
+ .tim_ch = {.phys = CRONUS_ADDR(0x2A2C10)},
+ .tim_cl = {.phys = CRONUS_ADDR(0x2A2C14)},
+ .gpio_dout = {.phys = CRONUS_ADDR(0x2A2C20)},
+ .gpio_din = {.phys = CRONUS_ADDR(0x2A2C24)},
+ .gpio_dir = {.phys = CRONUS_ADDR(0x2A2C2C)},
+ .watchdog = {.phys = CRONUS_ADDR(0x2A2C30)},
+ .front_panel = {.phys = CRONUS_ADDR(0x2A3800)},
+};
diff --git a/arch/mips/powertv/asic/asic-gaia.c b/arch/mips/powertv/asic/asic-gaia.c
new file mode 100644
index 00000000..91dda682
--- /dev/null
+++ b/arch/mips/powertv/asic/asic-gaia.c
@@ -0,0 +1,96 @@
+/*
+ * Locations of devices in the Gaia ASIC
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: David VomLehn
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+const struct register_map gaia_register_map __initdata = {
+ .eic_slow0_strt_add = {.phys = GAIA_IO_BASE + 0x000000},
+ .eic_cfg_bits = {.phys = GAIA_IO_BASE + 0x000038},
+ .eic_ready_status = {.phys = GAIA_IO_BASE + 0x00004C},
+
+ .chipver3 = {.phys = GAIA_IO_BASE + 0x2A0800},
+ .chipver2 = {.phys = GAIA_IO_BASE + 0x2A0804},
+ .chipver1 = {.phys = GAIA_IO_BASE + 0x2A0808},
+ .chipver0 = {.phys = GAIA_IO_BASE + 0x2A080C},
+
+ /* The registers of IRBlaster */
+ .uart1_intstat = {.phys = GAIA_IO_BASE + 0x2A1800},
+ .uart1_inten = {.phys = GAIA_IO_BASE + 0x2A1804},
+ .uart1_config1 = {.phys = GAIA_IO_BASE + 0x2A1808},
+ .uart1_config2 = {.phys = GAIA_IO_BASE + 0x2A180C},
+ .uart1_divisorhi = {.phys = GAIA_IO_BASE + 0x2A1810},
+ .uart1_divisorlo = {.phys = GAIA_IO_BASE + 0x2A1814},
+ .uart1_data = {.phys = GAIA_IO_BASE + 0x2A1818},
+ .uart1_status = {.phys = GAIA_IO_BASE + 0x2A181C},
+
+ .int_stat_3 = {.phys = GAIA_IO_BASE + 0x2A2800},
+ .int_stat_2 = {.phys = GAIA_IO_BASE + 0x2A2804},
+ .int_stat_1 = {.phys = GAIA_IO_BASE + 0x2A2808},
+ .int_stat_0 = {.phys = GAIA_IO_BASE + 0x2A280C},
+ .int_config = {.phys = GAIA_IO_BASE + 0x2A2810},
+ .int_int_scan = {.phys = GAIA_IO_BASE + 0x2A2818},
+ .ien_int_3 = {.phys = GAIA_IO_BASE + 0x2A2830},
+ .ien_int_2 = {.phys = GAIA_IO_BASE + 0x2A2834},
+ .ien_int_1 = {.phys = GAIA_IO_BASE + 0x2A2838},
+ .ien_int_0 = {.phys = GAIA_IO_BASE + 0x2A283C},
+ .int_level_3_3 = {.phys = GAIA_IO_BASE + 0x2A2880},
+ .int_level_3_2 = {.phys = GAIA_IO_BASE + 0x2A2884},
+ .int_level_3_1 = {.phys = GAIA_IO_BASE + 0x2A2888},
+ .int_level_3_0 = {.phys = GAIA_IO_BASE + 0x2A288C},
+ .int_level_2_3 = {.phys = GAIA_IO_BASE + 0x2A2890},
+ .int_level_2_2 = {.phys = GAIA_IO_BASE + 0x2A2894},
+ .int_level_2_1 = {.phys = GAIA_IO_BASE + 0x2A2898},
+ .int_level_2_0 = {.phys = GAIA_IO_BASE + 0x2A289C},
+ .int_level_1_3 = {.phys = GAIA_IO_BASE + 0x2A28A0},
+ .int_level_1_2 = {.phys = GAIA_IO_BASE + 0x2A28A4},
+ .int_level_1_1 = {.phys = GAIA_IO_BASE + 0x2A28A8},
+ .int_level_1_0 = {.phys = GAIA_IO_BASE + 0x2A28AC},
+ .int_level_0_3 = {.phys = GAIA_IO_BASE + 0x2A28B0},
+ .int_level_0_2 = {.phys = GAIA_IO_BASE + 0x2A28B4},
+ .int_level_0_1 = {.phys = GAIA_IO_BASE + 0x2A28B8},
+ .int_level_0_0 = {.phys = GAIA_IO_BASE + 0x2A28BC},
+ .int_docsis_en = {.phys = GAIA_IO_BASE + 0x2A28F4},
+
+ .mips_pll_setup = {.phys = GAIA_IO_BASE + 0x1C0000},
+ .fs432x4b4_usb_ctl = {.phys = GAIA_IO_BASE + 0x1C0024},
+ .test_bus = {.phys = GAIA_IO_BASE + 0x1C00CC},
+ .crt_spare = {.phys = GAIA_IO_BASE + 0x1c0108},
+ .usb2_ohci_int_mask = {.phys = GAIA_IO_BASE + 0x20000C},
+ .usb2_strap = {.phys = GAIA_IO_BASE + 0x200014},
+ .ehci_hcapbase = {.phys = GAIA_IO_BASE + 0x21FE00},
+ .ohci_hc_revision = {.phys = GAIA_IO_BASE + 0x21fc00},
+ .bcm1_bs_lmi_steer = {.phys = GAIA_IO_BASE + 0x2E0004},
+ .usb2_control = {.phys = GAIA_IO_BASE + 0x2E004C},
+ .usb2_stbus_obc = {.phys = GAIA_IO_BASE + 0x21FF00},
+ .usb2_stbus_mess_size = {.phys = GAIA_IO_BASE + 0x21FF04},
+ .usb2_stbus_chunk_size = {.phys = GAIA_IO_BASE + 0x21FF08},
+
+ .pcie_regs = {.phys = GAIA_IO_BASE + 0x220000},
+ .tim_ch = {.phys = GAIA_IO_BASE + 0x2A2C10},
+ .tim_cl = {.phys = GAIA_IO_BASE + 0x2A2C14},
+ .gpio_dout = {.phys = GAIA_IO_BASE + 0x2A2C20},
+ .gpio_din = {.phys = GAIA_IO_BASE + 0x2A2C24},
+ .gpio_dir = {.phys = GAIA_IO_BASE + 0x2A2C2C},
+ .watchdog = {.phys = GAIA_IO_BASE + 0x2A2C30},
+ .front_panel = {.phys = GAIA_IO_BASE + 0x2A3800},
+};
diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c
new file mode 100644
index 00000000..4a05bb09
--- /dev/null
+++ b/arch/mips/powertv/asic/asic-zeus.c
@@ -0,0 +1,101 @@
+/*
+ * Locations of devices in the Zeus ASIC
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ken Eppinett
+ * David Schleef <ds@schleef.org>
+ *
+ * Description: Defines the platform resources for the SA settop.
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+#define ZEUS_ADDR(x) (ZEUS_IO_BASE + (x))
+
+const struct register_map zeus_register_map __initdata = {
+ .eic_slow0_strt_add = {.phys = ZEUS_ADDR(0x000000)},
+ .eic_cfg_bits = {.phys = ZEUS_ADDR(0x000038)},
+ .eic_ready_status = {.phys = ZEUS_ADDR(0x00004c)},
+
+ .chipver3 = {.phys = ZEUS_ADDR(0x280800)},
+ .chipver2 = {.phys = ZEUS_ADDR(0x280804)},
+ .chipver1 = {.phys = ZEUS_ADDR(0x280808)},
+ .chipver0 = {.phys = ZEUS_ADDR(0x28080c)},
+
+ /* The registers of IRBlaster */
+ .uart1_intstat = {.phys = ZEUS_ADDR(0x281800)},
+ .uart1_inten = {.phys = ZEUS_ADDR(0x281804)},
+ .uart1_config1 = {.phys = ZEUS_ADDR(0x281808)},
+ .uart1_config2 = {.phys = ZEUS_ADDR(0x28180C)},
+ .uart1_divisorhi = {.phys = ZEUS_ADDR(0x281810)},
+ .uart1_divisorlo = {.phys = ZEUS_ADDR(0x281814)},
+ .uart1_data = {.phys = ZEUS_ADDR(0x281818)},
+ .uart1_status = {.phys = ZEUS_ADDR(0x28181C)},
+
+ .int_stat_3 = {.phys = ZEUS_ADDR(0x282800)},
+ .int_stat_2 = {.phys = ZEUS_ADDR(0x282804)},
+ .int_stat_1 = {.phys = ZEUS_ADDR(0x282808)},
+ .int_stat_0 = {.phys = ZEUS_ADDR(0x28280c)},
+ .int_config = {.phys = ZEUS_ADDR(0x282810)},
+ .int_int_scan = {.phys = ZEUS_ADDR(0x282818)},
+ .ien_int_3 = {.phys = ZEUS_ADDR(0x282830)},
+ .ien_int_2 = {.phys = ZEUS_ADDR(0x282834)},
+ .ien_int_1 = {.phys = ZEUS_ADDR(0x282838)},
+ .ien_int_0 = {.phys = ZEUS_ADDR(0x28283c)},
+ .int_level_3_3 = {.phys = ZEUS_ADDR(0x282880)},
+ .int_level_3_2 = {.phys = ZEUS_ADDR(0x282884)},
+ .int_level_3_1 = {.phys = ZEUS_ADDR(0x282888)},
+ .int_level_3_0 = {.phys = ZEUS_ADDR(0x28288c)},
+ .int_level_2_3 = {.phys = ZEUS_ADDR(0x282890)},
+ .int_level_2_2 = {.phys = ZEUS_ADDR(0x282894)},
+ .int_level_2_1 = {.phys = ZEUS_ADDR(0x282898)},
+ .int_level_2_0 = {.phys = ZEUS_ADDR(0x28289c)},
+ .int_level_1_3 = {.phys = ZEUS_ADDR(0x2828a0)},
+ .int_level_1_2 = {.phys = ZEUS_ADDR(0x2828a4)},
+ .int_level_1_1 = {.phys = ZEUS_ADDR(0x2828a8)},
+ .int_level_1_0 = {.phys = ZEUS_ADDR(0x2828ac)},
+ .int_level_0_3 = {.phys = ZEUS_ADDR(0x2828b0)},
+ .int_level_0_2 = {.phys = ZEUS_ADDR(0x2828b4)},
+ .int_level_0_1 = {.phys = ZEUS_ADDR(0x2828b8)},
+ .int_level_0_0 = {.phys = ZEUS_ADDR(0x2828bc)},
+ .int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)},
+
+ .mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)},
+ .fs432x4b4_usb_ctl = {.phys = ZEUS_ADDR(0x1a0018)},
+ .test_bus = {.phys = ZEUS_ADDR(0x1a0238)},
+ .crt_spare = {.phys = ZEUS_ADDR(0x1a0090)},
+ .usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)},
+ .usb2_strap = {.phys = ZEUS_ADDR(0x1e0014)},
+ .ehci_hcapbase = {.phys = ZEUS_ADDR(0x1FFE00)},
+ .ohci_hc_revision = {.phys = ZEUS_ADDR(0x1FFC00)},
+ .bcm1_bs_lmi_steer = {.phys = ZEUS_ADDR(0x2C0008)},
+ .usb2_control = {.phys = ZEUS_ADDR(0x2c01a0)},
+ .usb2_stbus_obc = {.phys = ZEUS_ADDR(0x1FFF00)},
+ .usb2_stbus_mess_size = {.phys = ZEUS_ADDR(0x1FFF04)},
+ .usb2_stbus_chunk_size = {.phys = ZEUS_ADDR(0x1FFF08)},
+
+ .pcie_regs = {.phys = ZEUS_ADDR(0x200000)},
+ .tim_ch = {.phys = ZEUS_ADDR(0x282C10)},
+ .tim_cl = {.phys = ZEUS_ADDR(0x282C14)},
+ .gpio_dout = {.phys = ZEUS_ADDR(0x282c20)},
+ .gpio_din = {.phys = ZEUS_ADDR(0x282c24)},
+ .gpio_dir = {.phys = ZEUS_ADDR(0x282c2C)},
+ .watchdog = {.phys = ZEUS_ADDR(0x282c30)},
+ .front_panel = {.phys = ZEUS_ADDR(0x283800)},
+};
diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c
new file mode 100644
index 00000000..e56fa61b
--- /dev/null
+++ b/arch/mips/powertv/asic/asic_devices.c
@@ -0,0 +1,571 @@
+/*
+ *
+ * Description: Defines the platform resources for Gaia-based settops.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: The bootloader allocates persistent memory at an address which is
+ * 16 MiB below the end of the highest address in KSEG0. All fixed
+ * address memory reservations must avoid this region.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial_reg.h>
+#include <linux/io.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <asm/page.h>
+#include <linux/swap.h>
+#include <linux/highmem.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/asic_regs.h>
+#include <asm/mach-powertv/interrupts.h>
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+#include <asm/mach-powertv/kbldr.h>
+#endif
+#include <asm/bootinfo.h>
+
+#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0))
+
+/*
+ * Forward Prototypes
+ */
+static void pmem_setup_resource(void);
+
+/*
+ * Global Variables
+ */
+enum asic_type asic;
+
+unsigned int platform_features;
+unsigned int platform_family;
+struct register_map _asic_register_map;
+EXPORT_SYMBOL(_asic_register_map); /* Exported for testing */
+unsigned long asic_phy_base;
+unsigned long asic_base;
+EXPORT_SYMBOL(asic_base); /* Exported for testing */
+struct resource *gp_resources;
+
+/*
+ * Don't recommend to use it directly, it is usually used by kernel internally.
+ * Portable code should be using interfaces such as ioremp, dma_map_single, etc.
+ */
+unsigned long phys_to_dma_offset;
+EXPORT_SYMBOL(phys_to_dma_offset);
+
+/*
+ *
+ * IO Resource Definition
+ *
+ */
+
+struct resource asic_resource = {
+ .name = "ASIC Resource",
+ .start = 0,
+ .end = ASIC_IO_SIZE,
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ * Allow override of bootloader-specified model
+ * Returns zero on success, a negative errno value on failure. This parameter
+ * allows overriding of the bootloader-specified model.
+ */
+static char __initdata cmdline[COMMAND_LINE_SIZE];
+
+#define FORCEFAMILY_PARAM "forcefamily"
+
+/*
+ * check_forcefamily - check for, and parse, forcefamily command line parameter
+ * @forced_family: Pointer to two-character array in which to store the
+ * value of the forcedfamily parameter, if any.
+ */
+static __init int check_forcefamily(unsigned char forced_family[2])
+{
+ const char *p;
+
+ forced_family[0] = '\0';
+ forced_family[1] = '\0';
+
+ /* Check the command line for a forcefamily directive */
+ strncpy(cmdline, arcs_cmdline, COMMAND_LINE_SIZE - 1);
+ p = strstr(cmdline, FORCEFAMILY_PARAM);
+ if (p && (p != cmdline) && (*(p - 1) != ' '))
+ p = strstr(p, " " FORCEFAMILY_PARAM "=");
+
+ if (p) {
+ p += strlen(FORCEFAMILY_PARAM "=");
+
+ if (*p == '\0' || *(p + 1) == '\0' ||
+ (*(p + 2) != '\0' && *(p + 2) != ' '))
+ pr_err(FORCEFAMILY_PARAM " must be exactly two "
+ "characters long, ignoring value\n");
+
+ else {
+ forced_family[0] = *p;
+ forced_family[1] = *(p + 1);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * platform_set_family - determine major platform family type.
+ *
+ * Returns family type; -1 if none
+ * Returns the family type; -1 if none
+ *
+ */
+static __init noinline void platform_set_family(void)
+{
+ unsigned char forced_family[2];
+ unsigned short bootldr_family;
+
+ if (check_forcefamily(forced_family) == 0)
+ bootldr_family = BOOTLDRFAMILY(forced_family[0],
+ forced_family[1]);
+ else {
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+ bootldr_family = (unsigned short) kbldr_GetSWFamily();
+#else
+#if defined(CONFIG_BOOTLOADER_FAMILY)
+ bootldr_family = (unsigned short) BOOTLDRFAMILY(
+ CONFIG_BOOTLOADER_FAMILY[0],
+ CONFIG_BOOTLOADER_FAMILY[1]);
+#else
+#error "Unknown Bootloader Family"
+#endif
+#endif
+ }
+
+ pr_info("Bootloader Family = 0x%04X\n", bootldr_family);
+
+ switch (bootldr_family) {
+ case BOOTLDRFAMILY('R', '1'):
+ platform_family = FAMILY_1500;
+ break;
+ case BOOTLDRFAMILY('4', '4'):
+ platform_family = FAMILY_4500;
+ break;
+ case BOOTLDRFAMILY('4', '6'):
+ platform_family = FAMILY_4600;
+ break;
+ case BOOTLDRFAMILY('A', '1'):
+ platform_family = FAMILY_4600VZA;
+ break;
+ case BOOTLDRFAMILY('8', '5'):
+ platform_family = FAMILY_8500;
+ break;
+ case BOOTLDRFAMILY('R', '2'):
+ platform_family = FAMILY_8500RNG;
+ break;
+ case BOOTLDRFAMILY('8', '6'):
+ platform_family = FAMILY_8600;
+ break;
+ case BOOTLDRFAMILY('B', '1'):
+ platform_family = FAMILY_8600VZB;
+ break;
+ case BOOTLDRFAMILY('E', '1'):
+ platform_family = FAMILY_1500VZE;
+ break;
+ case BOOTLDRFAMILY('F', '1'):
+ platform_family = FAMILY_1500VZF;
+ break;
+ case BOOTLDRFAMILY('8', '7'):
+ platform_family = FAMILY_8700;
+ break;
+ default:
+ platform_family = -1;
+ }
+}
+
+unsigned int platform_get_family(void)
+{
+ return platform_family;
+}
+EXPORT_SYMBOL(platform_get_family);
+
+/*
+ * platform_get_asic - determine the ASIC type.
+ *
+ * Returns the ASIC type, or ASIC_UNKNOWN if unknown
+ *
+ */
+enum asic_type platform_get_asic(void)
+{
+ return asic;
+}
+EXPORT_SYMBOL(platform_get_asic);
+
+/*
+ * set_register_map - set ASIC register configuration
+ * @phys_base: Physical address of the base of the ASIC registers
+ * @map: Description of key ASIC registers
+ */
+static void __init set_register_map(unsigned long phys_base,
+ const struct register_map *map)
+{
+ asic_phy_base = phys_base;
+ _asic_register_map = *map;
+ register_map_virtualize(&_asic_register_map);
+ asic_base = (unsigned long)ioremap_nocache(phys_base, ASIC_IO_SIZE);
+}
+
+/**
+ * configure_platform - configuration based on platform type.
+ */
+void __init configure_platform(void)
+{
+ platform_set_family();
+
+ switch (platform_family) {
+ case FAMILY_1500:
+ case FAMILY_1500VZE:
+ case FAMILY_1500VZF:
+ platform_features = FFS_CAPABLE;
+ asic = ASIC_CALLIOPE;
+ set_register_map(CALLIOPE_IO_BASE, &calliope_register_map);
+
+ if (platform_family == FAMILY_1500VZE) {
+ gp_resources = non_dvr_vze_calliope_resources;
+ pr_info("Platform: 1500/Vz Class E - "
+ "CALLIOPE, NON_DVR_CAPABLE\n");
+ } else if (platform_family == FAMILY_1500VZF) {
+ gp_resources = non_dvr_vzf_calliope_resources;
+ pr_info("Platform: 1500/Vz Class F - "
+ "CALLIOPE, NON_DVR_CAPABLE\n");
+ } else {
+ gp_resources = non_dvr_calliope_resources;
+ pr_info("Platform: 1500/RNG100 - CALLIOPE, "
+ "NON_DVR_CAPABLE\n");
+ }
+ break;
+
+ case FAMILY_4500:
+ platform_features = FFS_CAPABLE | PCIE_CAPABLE |
+ DISPLAY_CAPABLE;
+ asic = ASIC_ZEUS;
+ set_register_map(ZEUS_IO_BASE, &zeus_register_map);
+ gp_resources = non_dvr_zeus_resources;
+
+ pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n");
+ break;
+
+ case FAMILY_4600:
+ {
+ unsigned int chipversion = 0;
+
+ /* The settop has PCIE but it isn't used, so don't advertise
+ * it*/
+ platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
+
+ /* Cronus and Cronus Lite have the same register map */
+ set_register_map(CRONUS_IO_BASE, &cronus_register_map);
+
+ /* ASIC version will determine if this is a real CronusLite or
+ * Castrati(Cronus) */
+ chipversion = asic_read(chipver3) << 24;
+ chipversion |= asic_read(chipver2) << 16;
+ chipversion |= asic_read(chipver1) << 8;
+ chipversion |= asic_read(chipver0);
+
+ if ((chipversion == CRONUS_10) || (chipversion == CRONUS_11))
+ asic = ASIC_CRONUS;
+ else
+ asic = ASIC_CRONUSLITE;
+
+ gp_resources = non_dvr_cronuslite_resources;
+ pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, "
+ "chipversion=0x%08X\n",
+ (asic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE",
+ chipversion);
+ break;
+ }
+ case FAMILY_4600VZA:
+ platform_features = FFS_CAPABLE | DISPLAY_CAPABLE;
+ asic = ASIC_CRONUS;
+ set_register_map(CRONUS_IO_BASE, &cronus_register_map);
+ gp_resources = non_dvr_cronus_resources;
+
+ pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n");
+ break;
+
+ case FAMILY_8500:
+ case FAMILY_8500RNG:
+ platform_features = DVR_CAPABLE | PCIE_CAPABLE |
+ DISPLAY_CAPABLE;
+ asic = ASIC_ZEUS;
+ set_register_map(ZEUS_IO_BASE, &zeus_register_map);
+ gp_resources = dvr_zeus_resources;
+
+ pr_info("Platform: 8500/RNG200 - ZEUS, DVR_CAPABLE\n");
+ break;
+
+ case FAMILY_8600:
+ case FAMILY_8600VZB:
+ platform_features = DVR_CAPABLE | PCIE_CAPABLE |
+ DISPLAY_CAPABLE;
+ asic = ASIC_CRONUS;
+ set_register_map(CRONUS_IO_BASE, &cronus_register_map);
+ gp_resources = dvr_cronus_resources;
+
+ pr_info("Platform: 8600/Vz Class B - CRONUS, "
+ "DVR_CAPABLE\n");
+ break;
+
+ case FAMILY_8700:
+ platform_features = FFS_CAPABLE | PCIE_CAPABLE;
+ asic = ASIC_GAIA;
+ set_register_map(GAIA_IO_BASE, &gaia_register_map);
+ gp_resources = dvr_gaia_resources;
+
+ pr_info("Platform: 8700 - GAIA, DVR_CAPABLE\n");
+ break;
+
+ default:
+ pr_crit("Platform: UNKNOWN PLATFORM\n");
+ break;
+ }
+
+ switch (asic) {
+ case ASIC_ZEUS:
+ phys_to_dma_offset = 0x30000000;
+ break;
+ case ASIC_CALLIOPE:
+ phys_to_dma_offset = 0x10000000;
+ break;
+ case ASIC_CRONUSLITE:
+ /* Fall through */
+ case ASIC_CRONUS:
+ /*
+ * TODO: We suppose 0x10000000 aliases into 0x20000000-
+ * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000-
+ * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000.
+ */
+ phys_to_dma_offset = 0x10000000;
+ break;
+ default:
+ phys_to_dma_offset = 0x00000000;
+ break;
+ }
+}
+
+/*
+ * RESOURCE ALLOCATION
+ *
+ */
+/*
+ * Allocates/reserves the Platform memory resources early in the boot process.
+ * This ignores any resources that are designated IORESOURCE_IO
+ */
+void __init platform_alloc_bootmem(void)
+{
+ int i;
+ int total = 0;
+
+ /* Get persistent memory data from command line before allocating
+ * resources. This need to happen before normal command line parsing
+ * has been done */
+ pmem_setup_resource();
+
+ /* Loop through looking for resources that want a particular address */
+ for (i = 0; gp_resources[i].flags != 0; i++) {
+ int size = gp_resources[i].end - gp_resources[i].start + 1;
+ if ((gp_resources[i].start != 0) &&
+ ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
+ reserve_bootmem(dma_to_phys(gp_resources[i].start),
+ size, 0);
+ total += gp_resources[i].end -
+ gp_resources[i].start + 1;
+ pr_info("reserve resource %s at %08x (%u bytes)\n",
+ gp_resources[i].name, gp_resources[i].start,
+ gp_resources[i].end -
+ gp_resources[i].start + 1);
+ }
+ }
+
+ /* Loop through assigning addresses for those that are left */
+ for (i = 0; gp_resources[i].flags != 0; i++) {
+ int size = gp_resources[i].end - gp_resources[i].start + 1;
+ if ((gp_resources[i].start == 0) &&
+ ((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
+ void *mem = alloc_bootmem_pages(size);
+
+ if (mem == NULL)
+ pr_err("Unable to allocate bootmem pages "
+ "for %s\n", gp_resources[i].name);
+
+ else {
+ gp_resources[i].start =
+ phys_to_dma(virt_to_phys(mem));
+ gp_resources[i].end =
+ gp_resources[i].start + size - 1;
+ total += size;
+ pr_info("allocate resource %s at %08x "
+ "(%u bytes)\n",
+ gp_resources[i].name,
+ gp_resources[i].start, size);
+ }
+ }
+ }
+
+ pr_info("Total Platform driver memory allocation: 0x%08x\n", total);
+
+ /* indicate resources that are platform I/O related */
+ for (i = 0; gp_resources[i].flags != 0; i++) {
+ if ((gp_resources[i].start != 0) &&
+ ((gp_resources[i].flags & IORESOURCE_IO) != 0)) {
+ pr_info("reserved platform resource %s at %08x\n",
+ gp_resources[i].name, gp_resources[i].start);
+ }
+ }
+}
+
+/*
+ *
+ * PERSISTENT MEMORY (PMEM) CONFIGURATION
+ *
+ */
+static unsigned long pmemaddr __initdata;
+
+static int __init early_param_pmemaddr(char *p)
+{
+ pmemaddr = (unsigned long)simple_strtoul(p, NULL, 0);
+ return 0;
+}
+early_param("pmemaddr", early_param_pmemaddr);
+
+static long pmemlen __initdata;
+
+static int __init early_param_pmemlen(char *p)
+{
+/* TODO: we can use this code when and if the bootloader ever changes this */
+#if 0
+ pmemlen = (unsigned long)simple_strtoul(p, NULL, 0);
+#else
+ pmemlen = 0x20000;
+#endif
+ return 0;
+}
+early_param("pmemlen", early_param_pmemlen);
+
+/*
+ * Set up persistent memory. If we were given values, we patch the array of
+ * resources. Otherwise, persistent memory may be allocated anywhere at all.
+ */
+static void __init pmem_setup_resource(void)
+{
+ struct resource *resource;
+ resource = asic_resource_get("DiagPersistentMemory");
+
+ if (resource && pmemaddr && pmemlen) {
+ /* The address provided by bootloader is in kseg0. Convert to
+ * a bus address. */
+ resource->start = phys_to_dma(pmemaddr - 0x80000000);
+ resource->end = resource->start + pmemlen - 1;
+
+ pr_info("persistent memory: start=0x%x end=0x%x\n",
+ resource->start, resource->end);
+ }
+}
+
+/*
+ *
+ * RESOURCE ACCESS FUNCTIONS
+ *
+ */
+
+/**
+ * asic_resource_get - retrieves parameters for a platform resource.
+ * @name: string to match resource
+ *
+ * Returns a pointer to a struct resource corresponding to the given name.
+ *
+ * CANNOT BE NAMED platform_resource_get, which would be the obvious choice,
+ * as this function name is already declared
+ */
+struct resource *asic_resource_get(const char *name)
+{
+ int i;
+
+ for (i = 0; gp_resources[i].flags != 0; i++) {
+ if (strcmp(gp_resources[i].name, name) == 0)
+ return &gp_resources[i];
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(asic_resource_get);
+
+/**
+ * platform_release_memory - release pre-allocated memory
+ * @ptr: pointer to memory to release
+ * @size: size of resource
+ *
+ * This must only be called for memory allocated or reserved via the boot
+ * memory allocator.
+ */
+void platform_release_memory(void *ptr, int size)
+{
+ unsigned long addr;
+ unsigned long end;
+
+ addr = ((unsigned long)ptr + (PAGE_SIZE - 1)) & PAGE_MASK;
+ end = ((unsigned long)ptr + size) & PAGE_MASK;
+
+ for (; addr < end; addr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(__va(addr)));
+ init_page_count(virt_to_page(__va(addr)));
+ free_page((unsigned long)__va(addr));
+ }
+}
+EXPORT_SYMBOL(platform_release_memory);
+
+/*
+ *
+ * FEATURE AVAILABILITY FUNCTIONS
+ *
+ */
+int platform_supports_dvr(void)
+{
+ return (platform_features & DVR_CAPABLE) != 0;
+}
+
+int platform_supports_ffs(void)
+{
+ return (platform_features & FFS_CAPABLE) != 0;
+}
+
+int platform_supports_pcie(void)
+{
+ return (platform_features & PCIE_CAPABLE) != 0;
+}
+
+int platform_supports_display(void)
+{
+ return (platform_features & DISPLAY_CAPABLE) != 0;
+}
diff --git a/arch/mips/powertv/asic/asic_int.c b/arch/mips/powertv/asic/asic_int.c
new file mode 100644
index 00000000..529c44a5
--- /dev/null
+++ b/arch/mips/powertv/asic/asic_int.c
@@ -0,0 +1,124 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Routines for generic manipulation of the interrupts found on the PowerTV
+ * platform.
+ *
+ * The interrupt controller is located in the South Bridge a PIIX4 device
+ * with two internal 82C95 interrupt controllers.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/kernel.h>
+#include <linux/random.h>
+
+#include <asm/irq_cpu.h>
+#include <linux/io.h>
+#include <asm/irq_regs.h>
+#include <asm/mips-boards/generic.h>
+
+#include <asm/mach-powertv/asic_regs.h>
+
+static DEFINE_RAW_SPINLOCK(asic_irq_lock);
+
+static inline int get_int(void)
+{
+ unsigned long flags;
+ int irq;
+
+ raw_spin_lock_irqsave(&asic_irq_lock, flags);
+
+ irq = (asic_read(int_int_scan) >> 4) - 1;
+
+ if (irq == 0 || irq >= NR_IRQS)
+ irq = -1;
+
+ raw_spin_unlock_irqrestore(&asic_irq_lock, flags);
+
+ return irq;
+}
+
+static void asic_irqdispatch(void)
+{
+ int irq;
+
+ irq = get_int();
+ if (irq < 0)
+ return; /* interrupt has already been cleared */
+
+ do_IRQ(irq);
+}
+
+static inline int clz(unsigned long x)
+{
+ __asm__(
+ " .set push \n"
+ " .set mips32 \n"
+ " clz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (x)
+ : "r" (x));
+
+ return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+ return fls(pending) - 1 + CAUSEB_IP;
+}
+
+/*
+ * TODO: check how it works under EIC mode.
+ */
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+ int irq;
+
+ irq = irq_ffs(pending);
+
+ if (irq == CAUSEF_IP3)
+ asic_irqdispatch();
+ else if (irq >= 0)
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ asic_irq_init();
+
+ /*
+ * Initialize interrupt exception vectors.
+ */
+ if (cpu_has_veic || cpu_has_vint) {
+ int nvec = cpu_has_veic ? 64 : 8;
+ for (i = 0; i < nvec; i++)
+ set_vi_handler(i, asic_irqdispatch);
+ }
+}
diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c
new file mode 100644
index 00000000..7fb97fb0
--- /dev/null
+++ b/arch/mips/powertv/asic/irq_asic.c
@@ -0,0 +1,116 @@
+/*
+ * Portions copyright (C) 2005-2009 Scientific Atlanta
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * Modified from arch/mips/kernel/irq-rm7000.c:
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/mach-powertv/asic_regs.h>
+
+static inline void unmask_asic_irq(struct irq_data *d)
+{
+ unsigned long enable_bit;
+ unsigned int irq = d->irq;
+
+ enable_bit = (1 << (irq & 0x1f));
+
+ switch (irq >> 5) {
+ case 0:
+ asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
+ break;
+ case 1:
+ asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
+ break;
+ case 2:
+ asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
+ break;
+ case 3:
+ asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static inline void mask_asic_irq(struct irq_data *d)
+{
+ unsigned long disable_mask;
+ unsigned int irq = d->irq;
+
+ disable_mask = ~(1 << (irq & 0x1f));
+
+ switch (irq >> 5) {
+ case 0:
+ asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
+ break;
+ case 1:
+ asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
+ break;
+ case 2:
+ asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
+ break;
+ case 3:
+ asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static struct irq_chip asic_irq_chip = {
+ .name = "ASIC Level",
+ .irq_mask = mask_asic_irq,
+ .irq_unmask = unmask_asic_irq,
+};
+
+void __init asic_irq_init(void)
+{
+ int i;
+
+ /* set priority to 0 */
+ write_c0_status(read_c0_status() & ~(0x0000fc00));
+
+ asic_write(0, ien_int_0);
+ asic_write(0, ien_int_1);
+ asic_write(0, ien_int_2);
+ asic_write(0, ien_int_3);
+
+ asic_write(0x0fffffff, int_level_3_3);
+ asic_write(0xffffffff, int_level_3_2);
+ asic_write(0xffffffff, int_level_3_1);
+ asic_write(0xffffffff, int_level_3_0);
+ asic_write(0xffffffff, int_level_2_3);
+ asic_write(0xffffffff, int_level_2_2);
+ asic_write(0xffffffff, int_level_2_1);
+ asic_write(0xffffffff, int_level_2_0);
+ asic_write(0xffffffff, int_level_1_3);
+ asic_write(0xffffffff, int_level_1_2);
+ asic_write(0xffffffff, int_level_1_1);
+ asic_write(0xffffffff, int_level_1_0);
+ asic_write(0xffffffff, int_level_0_3);
+ asic_write(0xffffffff, int_level_0_2);
+ asic_write(0xffffffff, int_level_0_1);
+ asic_write(0xffffffff, int_level_0_0);
+
+ asic_write(0xf, int_int_scan);
+
+ /*
+ * Initialize interrupt handlers.
+ */
+ for (i = 0; i < NR_IRQS; i++)
+ irq_set_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
+}
diff --git a/arch/mips/powertv/asic/prealloc-calliope.c b/arch/mips/powertv/asic/prealloc-calliope.c
new file mode 100644
index 00000000..3fc5d466
--- /dev/null
+++ b/arch/mips/powertv/asic/prealloc-calliope.c
@@ -0,0 +1,385 @@
+/*
+ * Memory pre-allocations for Calliope boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ken Eppinett
+ * David Schleef <ds@schleef.org>
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/mach-powertv/asic.h>
+#include "prealloc.h"
+
+/*
+ * NON_DVR_CAPABLE CALLIOPE RESOURCES
+ */
+struct resource non_dvr_calliope_resources[] __initdata =
+{
+ /*
+ * VIDEO / LX1
+ */
+ /* Delta-Mu 1 image (2MiB) */
+ PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 RAM (~36.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26700000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Sysaudio Driver
+ */
+ /* DSP code and data images (1MiB) */
+ PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC CPU PCM buffer (40KiB) */
+ PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC AUX buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC Main buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * STAVEM driver/STAPI
+ */
+ /* 6MiB */
+ PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * DOCSIS Subsystem
+ */
+ /* 7MiB */
+ PREALLOC_DOCSIS("Docsis", 0x27500000, 0x27c00000-1, IORESOURCE_MEM)
+
+ /*
+ * GHW HAL Driver
+ */
+ /* PowerTV Graphics Heap (14MiB) */
+ PREALLOC_NORMAL("GraphicsHeap", 0x26700000, 0x26700000+(14*1048576)-1,
+ IORESOURCE_MEM)
+
+ /*
+ * multi com buffer area
+ */
+ /* 128KiB */
+ PREALLOC_NORMAL("MulticomSHM", 0x23700000, 0x23720000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DMA Ring buffer (don't need recording buffers)
+ */
+ /* 680KiB */
+ PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit0
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * AVFS: player HAL memory
+ */
+ /* 945K * 3 for playback */
+ PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * PMEM
+ */
+ /* Persistent memory for diagnostics (64KiB) */
+ PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Smartcard
+ */
+ /* Read and write buffers for Internal/External cards (10KiB) */
+ PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * NAND Flash
+ */
+ /* 10KiB */
+ PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Synopsys GMAC Memory Region
+ */
+ /* 64KiB */
+ PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * TFTPBuffer
+ *
+ * This buffer is used in some minimal configurations (e.g. two-way
+ * loader) for storing software images
+ */
+ PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Add other resources here
+ */
+
+ /*
+ * End of Resource marker
+ */
+ {
+ .flags = 0,
+ },
+};
+
+
+struct resource non_dvr_vze_calliope_resources[] __initdata =
+{
+ /*
+ * VIDEO / LX1
+ */
+ /* Delta-Mu 1 image (2MiB) */
+ PREALLOC_NORMAL("ST231aImage", 0x22000000, 0x22200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231aMonitor", 0x22200000, 0x22202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 RAM (10.12MiB) */
+ PREALLOC_NORMAL("MediaMemory1", 0x22202000, 0x22C20B85-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Sysaudio Driver
+ */
+ /* DSP code and data images (1MiB) */
+ PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC CPU PCM buffer (40KiB) */
+ PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC AUX buffer (16KiB) */
+ PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC Main buffer (16KiB) */
+ PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * STAVEM driver/STAPI
+ */
+ /* 3.125MiB */
+ PREALLOC_NORMAL("AVMEMPartition0", 0x20396000, 0x206B6000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * GHW HAL Driver
+ */
+ /* PowerTV Graphics Heap (2.59MiB) */
+ PREALLOC_NORMAL("GraphicsHeap", 0x20100000, 0x20396000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * multi com buffer area
+ */
+ /* 128KiB */
+ PREALLOC_NORMAL("MulticomSHM", 0x206B6000, 0x206D6000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DMA Ring buffer (don't need recording buffers)
+ */
+ /* 680KiB */
+ PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit0
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * PMEM
+ */
+ /* Persistent memory for diagnostics (64KiB) */
+ PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Smartcard
+ */
+ /* Read and write buffers for Internal/External cards (10KiB) */
+ PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * NAND Flash
+ */
+ /* 10KiB */
+ PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Synopsys GMAC Memory Region
+ */
+ /* 64KiB */
+ PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Add other resources here
+ */
+
+ /*
+ * End of Resource marker
+ */
+ {
+ .flags = 0,
+ },
+};
+
+struct resource non_dvr_vzf_calliope_resources[] __initdata =
+{
+ /*
+ * VIDEO / LX1
+ */
+ /* Delta-Mu 1 image (2MiB) */
+ PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 RAM (~19.4 (21.5MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x25580000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Sysaudio Driver
+ */
+ /* DSP code and data images (1MiB) */
+ PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC CPU PCM buffer (40KiB) */
+ PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC AUX buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC Main buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * STAVEM driver/STAPI
+ */
+ /* 4.5MiB */
+ PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00480000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * GHW HAL Driver
+ */
+ /* PowerTV Graphics Heap (14MiB) */
+ PREALLOC_NORMAL("GraphicsHeap", 0x25600000, 0x25600000+(14*1048576)-1,
+ IORESOURCE_MEM)
+
+ /*
+ * multi com buffer area
+ */
+ /* 128KiB */
+ PREALLOC_NORMAL("MulticomSHM", 0x23700000, 0x23720000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DMA Ring buffer (don't need recording buffers)
+ */
+ /* 680KiB */
+ PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit0
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit1
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * AVFS: player HAL memory
+ */
+ /* 945K * 3 for playback */
+ PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * PMEM
+ */
+ /* Persistent memory for diagnostics (64KiB) */
+ PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Smartcard
+ */
+ /* Read and write buffers for Internal/External cards (10KiB) */
+ PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * NAND Flash
+ */
+ /* 10KiB */
+ PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Synopsys GMAC Memory Region
+ */
+ /* 64KiB */
+ PREALLOC_NORMAL("GMAC", 0x00000000, 0x00010000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Add other resources here
+ */
+
+ /*
+ * End of Resource marker
+ */
+ {
+ .flags = 0,
+ },
+};
diff --git a/arch/mips/powertv/asic/prealloc-cronus.c b/arch/mips/powertv/asic/prealloc-cronus.c
new file mode 100644
index 00000000..c532b505
--- /dev/null
+++ b/arch/mips/powertv/asic/prealloc-cronus.c
@@ -0,0 +1,340 @@
+/*
+ * Memory pre-allocations for Cronus boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ken Eppinett
+ * David Schleef <ds@schleef.org>
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/mach-powertv/asic.h>
+#include "prealloc.h"
+
+/*
+ * DVR_CAPABLE CRONUS RESOURCES
+ */
+struct resource dvr_cronus_resources[] __initdata =
+{
+ /*
+ * VIDEO1 / LX1
+ */
+ /* Delta-Mu 1 image (2MiB) */
+ PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26000000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * VIDEO2 / LX2
+ */
+ /* Delta-Mu 2 image (2MiB) */
+ PREALLOC_NORMAL("ST231bImage", 0x60000000, 0x60200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 2 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231bMonitor", 0x60200000, 0x60202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory2", 0x60202000, 0x62000000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Sysaudio Driver
+ */
+ /* DSP code and data images (1MiB) */
+ PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC CPU PCM buffer (40KiB) */
+ PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC AUX buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC Main buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * STAVEM driver/STAPI
+ *
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ */
+ /* 12MiB */
+ PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DOCSIS Subsystem
+ */
+ /* 7MiB */
+ PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM)
+
+ /*
+ * GHW HAL Driver
+ */
+ /* PowerTV Graphics Heap (14MiB) */
+ PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * multi com buffer area
+ */
+ /* 128KiB */
+ PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DMA Ring buffer
+ */
+ PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x002EA000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit0
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit1
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * ITFS
+ */
+ /* 815,104 bytes each for 2 ITFS partitions. */
+ PREALLOC_NORMAL("ITFS", 0x00000000, 0x0018E000-1, IORESOURCE_MEM)
+
+ /*
+ * AVFS
+ */
+ /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */
+ PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x007c2000-1,
+ IORESOURCE_MEM)
+
+ /* 4KiB */
+ PREALLOC_NORMAL("AvfsFileSys", 0x00000000, 0x00001000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * PMEM
+ */
+ /* Persistent memory for diagnostics (64KiB) */
+ PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Smartcard
+ */
+ /* Read and write buffers for Internal/External cards (10KiB) */
+ PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
+ IORESOURCE_MEM)
+
+ /*
+ * KAVNET
+ */
+ /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */
+ PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1,
+ IORESOURCE_MEM)
+ /* NP Image - must be video bank 1 (320KiB) */
+ PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM)
+ /* NP IPC - must be video bank 2 (512KiB) */
+ PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM)
+
+ /*
+ * TFTPBuffer
+ *
+ * This buffer is used in some minimal configurations (e.g. two-way
+ * loader) for storing software images
+ */
+ PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Add other resources here
+ */
+
+ /*
+ * End of Resource marker
+ */
+ {
+ .flags = 0,
+ },
+};
+
+/*
+ * NON_DVR_CAPABLE CRONUS RESOURCES
+ */
+struct resource non_dvr_cronus_resources[] __initdata =
+{
+ /*
+ * VIDEO1 / LX1
+ */
+ /* Delta-Mu 1 image (2MiB) */
+ PREALLOC_NORMAL("ST231aImage", 0x24000000, 0x24200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231aMonitor", 0x24200000, 0x24202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory1", 0x24202000, 0x26000000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * VIDEO2 / LX2
+ */
+ /* Delta-Mu 2 image (2MiB) */
+ PREALLOC_NORMAL("ST231bImage", 0x60000000, 0x60200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 2 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231bMonitor", 0x60200000, 0x60202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory2", 0x60202000, 0x62000000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Sysaudio Driver
+ */
+ /* DSP code and data images (1MiB) */
+ PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC CPU PCM buffer (40KiB) */
+ PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC AUX buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC Main buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * STAVEM driver/STAPI
+ *
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ */
+ /* 12MiB */
+ PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DOCSIS Subsystem
+ */
+ /* 7MiB */
+ PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM)
+
+ /*
+ * GHW HAL Driver
+ */
+ /* PowerTV Graphics Heap (14MiB) */
+ PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * multi com buffer area
+ */
+ /* 128KiB */
+ PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DMA Ring buffer (don't need recording buffers)
+ */
+ /* 680KiB */
+ PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit0
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit1
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * AVFS: player HAL memory
+ */
+ /* 945K * 3 for playback */
+ PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1, IORESOURCE_MEM)
+
+ /*
+ * PMEM
+ */
+ /* Persistent memory for diagnostics (64KiB) */
+ PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Smartcard
+ */
+ /* Read and write buffers for Internal/External cards (10KiB) */
+ PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, IORESOURCE_MEM)
+
+ /*
+ * KAVNET
+ */
+ /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */
+ PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1,
+ IORESOURCE_MEM)
+ /* NP Image - must be video bank 1 (320KiB) */
+ PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM)
+ /* NP IPC - must be video bank 2 (512KiB) */
+ PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM)
+
+ /*
+ * NAND Flash
+ */
+ /* 10KiB */
+ PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Add other resources here
+ */
+
+ /*
+ * End of Resource marker
+ */
+ {
+ .flags = 0,
+ },
+};
diff --git a/arch/mips/powertv/asic/prealloc-cronuslite.c b/arch/mips/powertv/asic/prealloc-cronuslite.c
new file mode 100644
index 00000000..b5537e49
--- /dev/null
+++ b/arch/mips/powertv/asic/prealloc-cronuslite.c
@@ -0,0 +1,174 @@
+/*
+ * Memory pre-allocations for Cronus Lite boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ken Eppinett
+ * David Schleef <ds@schleef.org>
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/mach-powertv/asic.h>
+#include "prealloc.h"
+
+/*
+ * NON_DVR_CAPABLE CRONUSLITE RESOURCES
+ */
+struct resource non_dvr_cronuslite_resources[] __initdata =
+{
+ /*
+ * VIDEO2 / LX2
+ */
+ /* Delta-Mu 1 image (2MiB) */
+ PREALLOC_NORMAL("ST231aImage", 0x60000000, 0x60200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231aMonitor", 0x60200000, 0x60202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory1", 0x60202000, 0x62000000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Sysaudio Driver
+ */
+ /* DSP code and data images (1MiB) */
+ PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC CPU PCM buffer (40KiB) */
+ PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC AUX buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC Main buffer (128KiB) */
+ PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00020000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * STAVEM driver/STAPI
+ *
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ */
+ /* 6MiB */
+ PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DOCSIS Subsystem
+ */
+ /* 7MiB */
+ PREALLOC_DOCSIS("Docsis", 0x67500000, 0x67c00000-1, IORESOURCE_MEM)
+
+ /*
+ * GHW HAL Driver
+ */
+ /* PowerTV Graphics Heap (14MiB) */
+ PREALLOC_NORMAL("GraphicsHeap", 0x62700000, 0x63500000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * multi com buffer area
+ */
+ /* 128KiB */
+ PREALLOC_NORMAL("MulticomSHM", 0x26000000, 0x26020000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DMA Ring buffer (don't need recording buffers)
+ */
+ /* 680KiB */
+ PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x000AA000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit0
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit1
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * AVFS: player HAL memory
+ */
+ /* 945K * 3 for playback */
+ PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * PMEM
+ */
+ /* Persistent memory for diagnostics (64KiB) */
+ PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Smartcard
+ */
+ /* Read and write buffers for Internal/External cards (10KiB) */
+ PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1, IORESOURCE_MEM)
+
+ /*
+ * KAVNET
+ */
+ /* NP Reset Vector - must be of the form xxCxxxxx (4KiB) */
+ PREALLOC_NORMAL("NP_Reset_Vector", 0x27c00000, 0x27c01000-1,
+ IORESOURCE_MEM)
+ /* NP Image - must be video bank 1 (320KiB) */
+ PREALLOC_NORMAL("NP_Image", 0x27020000, 0x27070000-1, IORESOURCE_MEM)
+ /* NP IPC - must be video bank 2 (512KiB) */
+ PREALLOC_NORMAL("NP_IPC", 0x63500000, 0x63580000-1, IORESOURCE_MEM)
+
+ /*
+ * NAND Flash
+ */
+ /* 10KiB */
+ PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
+ IORESOURCE_MEM)
+
+ /*
+ * TFTPBuffer
+ *
+ * This buffer is used in some minimal configurations (e.g. two-way
+ * loader) for storing software images
+ */
+ PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Add other resources here
+ */
+
+ /*
+ * End of Resource marker
+ */
+ {
+ .flags = 0,
+ },
+};
diff --git a/arch/mips/powertv/asic/prealloc-gaia.c b/arch/mips/powertv/asic/prealloc-gaia.c
new file mode 100644
index 00000000..8ac8c7ae
--- /dev/null
+++ b/arch/mips/powertv/asic/prealloc-gaia.c
@@ -0,0 +1,589 @@
+/*
+ * Memory pre-allocations for Gaia boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: David VomLehn
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/asic.h>
+
+/*
+ * DVR_CAPABLE GAIA RESOURCES
+ */
+struct resource dvr_gaia_resources[] __initdata = {
+ /*
+ *
+ * VIDEO1 / LX1
+ *
+ */
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x24000000,
+ .end = 0x241FFFFF, /* 2MiB */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
+ .start = 0x24200000,
+ .end = 0x24201FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x24202000,
+ .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * VIDEO2 / LX2
+ *
+ */
+ {
+ .name = "ST231bImage", /* Delta-Mu 2 image and ram */
+ .start = 0x60000000,
+ .end = 0x601FFFFF, /* 2MiB */
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "ST231bMonitor", /* 8KiB block ST231b monitor */
+ .start = 0x60200000,
+ .end = 0x60201FFF,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "MediaMemory2",
+ .start = 0x60202000,
+ .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * Sysaudio Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * DSP_Image_Buff - DSP code and data images (1MB)
+ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+ * ADSC_Main_Buff - ADSC Main buffer (16KB)
+ *
+ */
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * STAVEM driver/STAPI
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ *
+ */
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x63580000,
+ .end = 0x64180000 - 1, /* 12 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * DOCSIS Subsystem
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ */
+ {
+ .name = "Docsis",
+ .start = 0x62000000,
+ .end = 0x62700000 - 1, /* 7 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * GHW HAL Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * GraphicsHeap - PowerTV Graphics Heap
+ *
+ */
+ {
+ .name = "GraphicsHeap",
+ .start = 0x62700000,
+ .end = 0x63500000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * multi com buffer area
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ */
+ {
+ .name = "MulticomSHM",
+ .start = 0x26000000,
+ .end = 0x26020000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * DMA Ring buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ */
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x00280000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * Display bins buffer for unit0
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit0
+ *
+ */
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * Display bins buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit1
+ *
+ */
+ {
+ .name = "DisplayBins1",
+ .start = 0x64AD4000,
+ .end = 0x64AD5000 - 1, /* 4 KB total */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * ITFS
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ */
+ {
+ .name = "ITFS",
+ .start = 0x64180000,
+ /* 815,104 bytes each for 2 ITFS partitions. */
+ .end = 0x6430DFFF,
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * AVFS
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ */
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x6430E000,
+ /* (945K * 8) = (128K *3) 5 playbacks / 3 server */
+ .end = 0x64AD0000 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "AvfsFileSys",
+ .start = 0x64AD0000,
+ .end = 0x64AD1000 - 1, /* 4K */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * Smartcard
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Read and write buffers for Internal/External cards
+ *
+ */
+ {
+ .name = "SmartCardInfo",
+ .start = 0x64AD1000,
+ .end = 0x64AD3800 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * KAVNET
+ * NP Reset Vector - must be of the form xxCxxxxx
+ * NP Image - must be video bank 1
+ * NP IPC - must be video bank 2
+ */
+ {
+ .name = "NP_Reset_Vector",
+ .start = 0x27c00000,
+ .end = 0x27c01000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_Image",
+ .start = 0x27020000,
+ .end = 0x27060000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_IPC",
+ .start = 0x63500000,
+ .end = 0x63580000 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ * Add other resources here
+ */
+ { },
+};
+
+/*
+ * NON_DVR_CAPABLE GAIA RESOURCES
+ */
+struct resource non_dvr_gaia_resources[] __initdata = {
+ /*
+ *
+ * VIDEO1 / LX1
+ *
+ */
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x24000000,
+ .end = 0x241FFFFF, /* 2MiB */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
+ .start = 0x24200000,
+ .end = 0x24201FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x24202000,
+ .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * VIDEO2 / LX2
+ *
+ */
+ {
+ .name = "ST231bImage", /* Delta-Mu 2 image and ram */
+ .start = 0x60000000,
+ .end = 0x601FFFFF, /* 2MiB */
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "ST231bMonitor", /* 8KiB block ST231b monitor */
+ .start = 0x60200000,
+ .end = 0x60201FFF,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "MediaMemory2",
+ .start = 0x60202000,
+ .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * Sysaudio Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * DSP_Image_Buff - DSP code and data images (1MB)
+ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+ * ADSC_Main_Buff - ADSC Main buffer (16KB)
+ *
+ */
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * STAVEM driver/STAPI
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ *
+ */
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x63580000,
+ .end = 0x64180000 - 1, /* 12 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * DOCSIS Subsystem
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ */
+ {
+ .name = "Docsis",
+ .start = 0x62000000,
+ .end = 0x62700000 - 1, /* 7 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * GHW HAL Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * GraphicsHeap - PowerTV Graphics Heap
+ *
+ */
+ {
+ .name = "GraphicsHeap",
+ .start = 0x62700000,
+ .end = 0x63500000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * multi com buffer area
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ */
+ {
+ .name = "MulticomSHM",
+ .start = 0x26000000,
+ .end = 0x26020000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * DMA Ring buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ */
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x000AA000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * Display bins buffer for unit0
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit0
+ *
+ */
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * Display bins buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit1
+ *
+ */
+ {
+ .name = "DisplayBins1",
+ .start = 0x64AD4000,
+ .end = 0x64AD5000 - 1, /* 4 KB total */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * AVFS: player HAL memory
+ *
+ *
+ */
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x6430E000,
+ .end = 0x645D2C00 - 1, /* 945K * 3 for playback */
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * PMEM
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Persistent memory for diagnostics.
+ *
+ */
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ *
+ * Smartcard
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Read and write buffers for Internal/External cards
+ *
+ */
+ {
+ .name = "SmartCardInfo",
+ .start = 0x64AD1000,
+ .end = 0x64AD3800 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /*
+ *
+ * KAVNET
+ * NP Reset Vector - must be of the form xxCxxxxx
+ * NP Image - must be video bank 1
+ * NP IPC - must be video bank 2
+ */
+ {
+ .name = "NP_Reset_Vector",
+ .start = 0x27c00000,
+ .end = 0x27c01000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_Image",
+ .start = 0x27020000,
+ .end = 0x27060000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_IPC",
+ .start = 0x63500000,
+ .end = 0x63580000 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ { },
+};
diff --git a/arch/mips/powertv/asic/prealloc-zeus.c b/arch/mips/powertv/asic/prealloc-zeus.c
new file mode 100644
index 00000000..96480a23
--- /dev/null
+++ b/arch/mips/powertv/asic/prealloc-zeus.c
@@ -0,0 +1,304 @@
+/*
+ * Memory pre-allocations for Zeus boxes.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ken Eppinett
+ * David Schleef <ds@schleef.org>
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/mach-powertv/asic.h>
+#include "prealloc.h"
+
+/*
+ * DVR_CAPABLE RESOURCES
+ */
+struct resource dvr_zeus_resources[] __initdata =
+{
+ /*
+ * VIDEO1 / LX1
+ */
+ /* Delta-Mu 1 image (2MiB) */
+ PREALLOC_NORMAL("ST231aImage", 0x20000000, 0x20200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231aMonitor", 0x20200000, 0x20202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory1", 0x20202000, 0x22000000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * VIDEO2 / LX2
+ */
+ /* Delta-Mu 2 image (2MiB) */
+ PREALLOC_NORMAL("ST231bImage", 0x30000000, 0x30200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 2 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231bMonitor", 0x30200000, 0x30202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 2 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory2", 0x30202000, 0x32000000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Sysaudio Driver
+ */
+ /* DSP code and data images (1MiB) */
+ PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC CPU PCM buffer (40KiB) */
+ PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC AUX buffer (16KiB) */
+ PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC Main buffer (16KiB) */
+ PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * STAVEM driver/STAPI
+ *
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ */
+ /* 12MiB */
+ PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00c00000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * DOCSIS Subsystem
+ */
+ /* 7MiB */
+ PREALLOC_DOCSIS("Docsis", 0x40100000, 0x40800000-1, IORESOURCE_MEM)
+
+ /*
+ * GHW HAL Driver
+ */
+ /* PowerTV Graphics Heap (14MiB) */
+ PREALLOC_NORMAL("GraphicsHeap", 0x46900000, 0x47700000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * multi com buffer area
+ */
+ /* 128KiB */
+ PREALLOC_NORMAL("MulticomSHM", 0x47900000, 0x47920000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DMA Ring buffer
+ */
+ /* 2.5MiB */
+ PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x00280000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit0
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit1
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins1", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * ITFS
+ */
+ /* 815,104 bytes each for 2 ITFS partitions. */
+ PREALLOC_NORMAL("ITFS", 0x00000000, 0x0018E000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * AVFS
+ */
+ /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */
+ PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x007c2000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* 4KiB */
+ PREALLOC_NORMAL("AvfsFileSys", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * PMEM
+ */
+ /* Persistent memory for diagnostics (64KiB) */
+ PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Smartcard
+ */
+ /* Read and write buffers for Internal/External cards (10KiB) */
+ PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * TFTPBuffer
+ *
+ * This buffer is used in some minimal configurations (e.g. two-way
+ * loader) for storing software images
+ */
+ PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Add other resources here
+ */
+
+ /*
+ * End of Resource marker
+ */
+ {
+ .flags = 0,
+ },
+};
+
+/*
+ * NON_DVR_CAPABLE ZEUS RESOURCES
+ */
+struct resource non_dvr_zeus_resources[] __initdata =
+{
+ /*
+ * VIDEO1 / LX1
+ */
+ /* Delta-Mu 1 image (2MiB) */
+ PREALLOC_NORMAL("ST231aImage", 0x20000000, 0x20200000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 monitor (8KiB) */
+ PREALLOC_NORMAL("ST231aMonitor", 0x20200000, 0x20202000-1,
+ IORESOURCE_MEM)
+ /* Delta-Mu 1 RAM (~29.9MiB (32MiB - (2MiB + 8KiB))) */
+ PREALLOC_NORMAL("MediaMemory1", 0x20202000, 0x22000000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * Sysaudio Driver
+ */
+ /* DSP code and data images (1MiB) */
+ PREALLOC_NORMAL("DSP_Image_Buff", 0x00000000, 0x00100000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC CPU PCM buffer (40KiB) */
+ PREALLOC_NORMAL("ADSC_CPU_PCM_Buff", 0x00000000, 0x0000A000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC AUX buffer (16KiB) */
+ PREALLOC_NORMAL("ADSC_AUX_Buff", 0x00000000, 0x00004000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+ /* ADSC Main buffer (16KiB) */
+ PREALLOC_NORMAL("ADSC_Main_Buff", 0x00000000, 0x00004000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * STAVEM driver/STAPI
+ */
+ /* 6MiB */
+ PREALLOC_NORMAL("AVMEMPartition0", 0x00000000, 0x00600000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * DOCSIS Subsystem
+ */
+ /* 7MiB */
+ PREALLOC_DOCSIS("Docsis", 0x40100000, 0x40800000-1, IORESOURCE_MEM)
+
+ /*
+ * GHW HAL Driver
+ */
+ /* PowerTV Graphics Heap (14MiB) */
+ PREALLOC_NORMAL("GraphicsHeap", 0x46900000, 0x47700000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * multi com buffer area
+ */
+ /* 128KiB */
+ PREALLOC_NORMAL("MulticomSHM", 0x47900000, 0x47920000-1,
+ IORESOURCE_MEM)
+
+ /*
+ * DMA Ring buffer
+ */
+ /* 2.5MiB */
+ PREALLOC_NORMAL("BMM_Buffer", 0x00000000, 0x00280000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Display bins buffer for unit0
+ */
+ /* 4KiB */
+ PREALLOC_NORMAL("DisplayBins0", 0x00000000, 0x00001000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * AVFS: player HAL memory
+ */
+ /* 945K * 3 for playback */
+ PREALLOC_NORMAL("AvfsDmaMem", 0x00000000, 0x002c4c00-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * PMEM
+ */
+ /* Persistent memory for diagnostics (64KiB) */
+ PREALLOC_PMEM("DiagPersistentMemory", 0x00000000, 0x10000-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Smartcard
+ */
+ /* Read and write buffers for Internal/External cards (10KiB) */
+ PREALLOC_NORMAL("SmartCardInfo", 0x00000000, 0x2800-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * NAND Flash
+ */
+ /* 10KiB */
+ PREALLOC_NORMAL("NandFlash", NAND_FLASH_BASE, NAND_FLASH_BASE+0x400-1,
+ IORESOURCE_MEM)
+
+ /*
+ * TFTPBuffer
+ *
+ * This buffer is used in some minimal configurations (e.g. two-way
+ * loader) for storing software images
+ */
+ PREALLOC_TFTP("TFTPBuffer", 0x00000000, MEBIBYTE(80)-1,
+ (IORESOURCE_MEM|IORESOURCE_PTV_RES_LOEXT))
+
+ /*
+ * Add other resources here
+ */
+
+ /*
+ * End of Resource marker
+ */
+ {
+ .flags = 0,
+ },
+};
diff --git a/arch/mips/powertv/asic/prealloc.h b/arch/mips/powertv/asic/prealloc.h
new file mode 100644
index 00000000..8e682df1
--- /dev/null
+++ b/arch/mips/powertv/asic/prealloc.h
@@ -0,0 +1,70 @@
+/*
+ * Definitions for memory preallocations
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ARCH_MIPS_POWERTV_ASIC_PREALLOC_H
+#define _ARCH_MIPS_POWERTV_ASIC_PREALLOC_H
+
+#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */
+#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */
+
+/* "struct resource" array element definition */
+#define PREALLOC(NAME, START, END, FLAGS) { \
+ .name = (NAME), \
+ .start = (START), \
+ .end = (END), \
+ .flags = (FLAGS) \
+ },
+
+/* Individual resources in the preallocated resource arrays are defined using
+ * macros. These macros are conditionally defined based on their
+ * corresponding kernel configuration flag:
+ * - CONFIG_PREALLOC_NORMAL: preallocate resources for a normal settop box
+ * - CONFIG_PREALLOC_TFTP: preallocate the TFTP download resource
+ * - CONFIG_PREALLOC_DOCSIS: preallocate the DOCSIS resource
+ * - CONFIG_PREALLOC_PMEM: reserve space for persistent memory
+ */
+#ifdef CONFIG_PREALLOC_NORMAL
+#define PREALLOC_NORMAL(name, start, end, flags) \
+ PREALLOC(name, start, end, flags)
+#else
+#define PREALLOC_NORMAL(name, start, end, flags)
+#endif
+
+#ifdef CONFIG_PREALLOC_TFTP
+#define PREALLOC_TFTP(name, start, end, flags) \
+ PREALLOC(name, start, end, flags)
+#else
+#define PREALLOC_TFTP(name, start, end, flags)
+#endif
+
+#ifdef CONFIG_PREALLOC_DOCSIS
+#define PREALLOC_DOCSIS(name, start, end, flags) \
+ PREALLOC(name, start, end, flags)
+#else
+#define PREALLOC_DOCSIS(name, start, end, flags)
+#endif
+
+#ifdef CONFIG_PREALLOC_PMEM
+#define PREALLOC_PMEM(name, start, end, flags) \
+ PREALLOC(name, start, end, flags)
+#else
+#define PREALLOC_PMEM(name, start, end, flags)
+#endif
+#endif
diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c
new file mode 100644
index 00000000..83552288
--- /dev/null
+++ b/arch/mips/powertv/init.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <carstenl@mips.com>
+ * Maciej W. Rozycki <macro@mips.com>
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * PROM library initialisation code.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mach-powertv/asic.h>
+
+static int *_prom_envp;
+unsigned long _prom_memsize;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension, if running in 64-bit mode.
+ */
+#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
+
+char *prom_getenv(char *envname)
+{
+ char *result = NULL;
+
+ if (_prom_envp != NULL) {
+ /*
+ * Return a pointer to the given environment variable.
+ * In 64-bit mode: we're using 64-bit pointers, but all pointers
+ * in the PROM structures are only 32-bit, so we need some
+ * workarounds, if we are running in 64-bit mode.
+ */
+ int i, index = 0;
+
+ i = strlen(envname);
+
+ while (prom_envp(index)) {
+ if (strncmp(envname, prom_envp(index), i) == 0) {
+ result = prom_envp(index + 1);
+ break;
+ }
+ index += 2;
+ }
+ }
+
+ return result;
+}
+
+/* TODO: Verify on linux-mips mailing list that the following two */
+/* functions are correct */
+/* TODO: Copy NMI and EJTAG exception vectors to memory from the */
+/* BootROM exception vectors. Flush their cache entries. test it. */
+
+static void __init mips_nmi_setup(void)
+{
+ void *base;
+#if defined(CONFIG_CPU_MIPS32_R1)
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa80) :
+ (void *)(CAC_BASE + 0x380);
+#elif defined(CONFIG_CPU_MIPS32_R2)
+ base = (void *)0xbfc00000;
+#else
+#error NMI exception handler address not defined
+#endif
+}
+
+static void __init mips_ejtag_setup(void)
+{
+ void *base;
+
+#if defined(CONFIG_CPU_MIPS32_R1)
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa00) :
+ (void *)(CAC_BASE + 0x300);
+#elif defined(CONFIG_CPU_MIPS32_R2)
+ base = (void *)0xbfc00480;
+#else
+#error EJTAG exception handler address not defined
+#endif
+}
+
+void __init prom_init(void)
+{
+ int prom_argc;
+ char *prom_argv;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char *) fw_arg1;
+ _prom_envp = (int *) fw_arg2;
+ _prom_memsize = (unsigned long) fw_arg3;
+
+ board_nmi_handler_setup = mips_nmi_setup;
+ board_ejtag_handler_setup = mips_ejtag_setup;
+
+ if (prom_argc == 1) {
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+ strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE);
+ }
+
+ configure_platform();
+ prom_meminit();
+
+#ifndef CONFIG_BOOTLOADER_DRIVER
+ pr_info("\nBootloader driver isn't loaded...\n");
+#endif
+}
diff --git a/arch/mips/powertv/init.h b/arch/mips/powertv/init.h
new file mode 100644
index 00000000..b194c34c
--- /dev/null
+++ b/arch/mips/powertv/init.h
@@ -0,0 +1,26 @@
+/*
+ * Definitions from powertv init.c file
+ *
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: David VomLehn
+ */
+
+#ifndef _POWERTV_INIT_H
+#define _POWERTV_INIT_H
+extern unsigned long _prom_memsize;
+#endif
diff --git a/arch/mips/powertv/ioremap.c b/arch/mips/powertv/ioremap.c
new file mode 100644
index 00000000..a77c6f62
--- /dev/null
+++ b/arch/mips/powertv/ioremap.c
@@ -0,0 +1,136 @@
+/*
+ * ioremap.c
+ *
+ * Support for mapping between dma_addr_t values a phys_addr_t values.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: David VomLehn <dvomlehn@cisco.com>
+ *
+ * Description: Defines the platform resources for the SA settop.
+ *
+ * NOTE: The bootloader allocates persistent memory at an address which is
+ * 16 MiB below the end of the highest address in KSEG0. All fixed
+ * address memory reservations must avoid this region.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/mach-powertv/ioremap.h>
+
+/*
+ * Define the sizes of and masks for grains in physical and DMA space. The
+ * values are the same but the types are not.
+ */
+#define IOR_PHYS_GRAIN ((phys_addr_t) 1 << IOR_LSBITS)
+#define IOR_PHYS_GRAIN_MASK (IOR_PHYS_GRAIN - 1)
+
+#define IOR_DMA_GRAIN ((dma_addr_t) 1 << IOR_LSBITS)
+#define IOR_DMA_GRAIN_MASK (IOR_DMA_GRAIN - 1)
+
+/*
+ * Values that, when accessed by an index derived from a phys_addr_t and
+ * added to phys_addr_t value, yield a DMA address
+ */
+struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
+EXPORT_SYMBOL(_ior_phys_to_dma);
+
+/*
+ * Values that, when accessed by an index derived from a dma_addr_t and
+ * added to that dma_addr_t value, yield a physical address
+ */
+struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
+EXPORT_SYMBOL(_ior_dma_to_phys);
+
+/**
+ * setup_dma_to_phys - set up conversion from DMA to physical addresses
+ * @dma_idx: Top IOR_LSBITS bits of the DMA address, i.e. an index
+ * into the array _dma_to_phys.
+ * @delta: Value that, when added to the DMA address, will yield the
+ * physical address
+ * @s: Number of bytes in the section of memory with the given delta
+ * between DMA and physical addresses.
+ */
+static void setup_dma_to_phys(dma_addr_t dma, phys_addr_t delta, dma_addr_t s)
+{
+ int dma_idx, first_idx, last_idx;
+ phys_addr_t first, last;
+
+ /*
+ * Calculate the first and last indices, rounding the first up and
+ * the second down.
+ */
+ first = dma & ~IOR_DMA_GRAIN_MASK;
+ last = (dma + s - 1) & ~IOR_DMA_GRAIN_MASK;
+ first_idx = first >> IOR_LSBITS; /* Convert to indices */
+ last_idx = last >> IOR_LSBITS;
+
+ for (dma_idx = first_idx; dma_idx <= last_idx; dma_idx++)
+ _ior_dma_to_phys[dma_idx].offset = delta >> IOR_DMA_SHIFT;
+}
+
+/**
+ * setup_phys_to_dma - set up conversion from DMA to physical addresses
+ * @phys_idx: Top IOR_LSBITS bits of the DMA address, i.e. an index
+ * into the array _phys_to_dma.
+ * @delta: Value that, when added to the DMA address, will yield the
+ * physical address
+ * @s: Number of bytes in the section of memory with the given delta
+ * between DMA and physical addresses.
+ */
+static void setup_phys_to_dma(phys_addr_t phys, dma_addr_t delta, phys_addr_t s)
+{
+ int phys_idx, first_idx, last_idx;
+ phys_addr_t first, last;
+
+ /*
+ * Calculate the first and last indices, rounding the first up and
+ * the second down.
+ */
+ first = phys & ~IOR_PHYS_GRAIN_MASK;
+ last = (phys + s - 1) & ~IOR_PHYS_GRAIN_MASK;
+ first_idx = first >> IOR_LSBITS; /* Convert to indices */
+ last_idx = last >> IOR_LSBITS;
+
+ for (phys_idx = first_idx; phys_idx <= last_idx; phys_idx++)
+ _ior_phys_to_dma[phys_idx].offset = delta >> IOR_PHYS_SHIFT;
+}
+
+/**
+ * ioremap_add_map - add to the physical and DMA address conversion arrays
+ * @phys: Process's view of the address of the start of the memory chunk
+ * @dma: DMA address of the start of the memory chunk
+ * @size: Size, in bytes, of the chunk of memory
+ *
+ * NOTE: It might be obvious, but the assumption is that all @size bytes have
+ * the same offset between the physical address and the DMA address.
+ */
+void ioremap_add_map(phys_addr_t phys, phys_addr_t dma, phys_addr_t size)
+{
+ if (size == 0)
+ return;
+
+ if ((dma & IOR_DMA_GRAIN_MASK) != 0 ||
+ (phys & IOR_PHYS_GRAIN_MASK) != 0 ||
+ (size & IOR_PHYS_GRAIN_MASK) != 0)
+ pr_crit("Memory allocation must be in chunks of 0x%x bytes\n",
+ IOR_PHYS_GRAIN);
+
+ setup_dma_to_phys(dma, phys - dma, size);
+ setup_phys_to_dma(phys, dma - phys, size);
+}
diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c
new file mode 100644
index 00000000..fb3d2966
--- /dev/null
+++ b/arch/mips/powertv/memory.c
@@ -0,0 +1,354 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Apparently originally from arch/mips/malta-memory.c. Modified to work
+ * with the PowerTV bootloader.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/pfn.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <asm/mips-boards/prom.h>
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/ioremap.h>
+
+#include "init.h"
+
+/* Memory constants */
+#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */
+#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */
+#define DEFAULT_MEMSIZE MEBIBYTE(128) /* If no memsize provided */
+
+#define BLDR_SIZE KIBIBYTE(256) /* Memory reserved for bldr */
+#define RV_SIZE MEBIBYTE(4) /* Size of reset vector */
+
+#define LOW_MEM_END 0x20000000 /* Highest low memory address */
+#define BLDR_ALIAS 0x10000000 /* Bootloader address */
+#define RV_PHYS 0x1fc00000 /* Reset vector address */
+#define LOW_RAM_END RV_PHYS /* End of real RAM in low mem */
+
+/*
+ * Very low-level conversion from processor physical address to device
+ * DMA address for the first bank of memory.
+ */
+#define PHYS_TO_DMA(paddr) ((paddr) + (CONFIG_LOW_RAM_DMA - LOW_RAM_ALIAS))
+
+unsigned long ptv_memsize;
+
+/*
+ * struct low_mem_reserved - Items in low memory that are reserved
+ * @start: Physical address of item
+ * @size: Size, in bytes, of this item
+ * @is_aliased: True if this is RAM aliased from another location. If false,
+ * it is something other than aliased RAM and the RAM in the
+ * unaliased address is still visible outside of low memory.
+ */
+struct low_mem_reserved {
+ phys_addr_t start;
+ phys_addr_t size;
+ bool is_aliased;
+};
+
+/*
+ * Must be in ascending address order
+ */
+struct low_mem_reserved low_mem_reserved[] = {
+ {BLDR_ALIAS, BLDR_SIZE, true}, /* Bootloader RAM */
+ {RV_PHYS, RV_SIZE, false}, /* Reset vector */
+};
+
+/*
+ * struct mem_layout - layout of a piece of the system RAM
+ * @phys: Physical address of the start of this piece of RAM. This is the
+ * address at which both the processor and I/O devices see the
+ * RAM.
+ * @alias: Alias of this piece of memory in order to make it appear in
+ * the low memory part of the processor's address space. I/O
+ * devices don't see anything here.
+ * @size: Size, in bytes, of this piece of RAM
+ */
+struct mem_layout {
+ phys_addr_t phys;
+ phys_addr_t alias;
+ phys_addr_t size;
+};
+
+/*
+ * struct mem_layout_list - list descriptor for layouts of system RAM pieces
+ * @family: Specifies the family being described
+ * @n: Number of &struct mem_layout elements
+ * @layout: Pointer to the list of &mem_layout structures
+ */
+struct mem_layout_list {
+ enum family_type family;
+ size_t n;
+ struct mem_layout *layout;
+};
+
+static struct mem_layout f1500_layout[] = {
+ {0x20000000, 0x10000000, MEBIBYTE(256)},
+};
+
+static struct mem_layout f4500_layout[] = {
+ {0x40000000, 0x10000000, MEBIBYTE(256)},
+ {0x20000000, 0x20000000, MEBIBYTE(32)},
+};
+
+static struct mem_layout f8500_layout[] = {
+ {0x40000000, 0x10000000, MEBIBYTE(256)},
+ {0x20000000, 0x20000000, MEBIBYTE(32)},
+ {0x30000000, 0x30000000, MEBIBYTE(32)},
+};
+
+static struct mem_layout fx600_layout[] = {
+ {0x20000000, 0x10000000, MEBIBYTE(256)},
+ {0x60000000, 0x60000000, MEBIBYTE(128)},
+};
+
+static struct mem_layout_list layout_list[] = {
+ {FAMILY_1500, ARRAY_SIZE(f1500_layout), f1500_layout},
+ {FAMILY_1500VZE, ARRAY_SIZE(f1500_layout), f1500_layout},
+ {FAMILY_1500VZF, ARRAY_SIZE(f1500_layout), f1500_layout},
+ {FAMILY_4500, ARRAY_SIZE(f4500_layout), f4500_layout},
+ {FAMILY_8500, ARRAY_SIZE(f8500_layout), f8500_layout},
+ {FAMILY_8500RNG, ARRAY_SIZE(f8500_layout), f8500_layout},
+ {FAMILY_4600, ARRAY_SIZE(fx600_layout), fx600_layout},
+ {FAMILY_4600VZA, ARRAY_SIZE(fx600_layout), fx600_layout},
+ {FAMILY_8600, ARRAY_SIZE(fx600_layout), fx600_layout},
+ {FAMILY_8600VZB, ARRAY_SIZE(fx600_layout), fx600_layout},
+};
+
+/* If we can't determine the layout, use this */
+static struct mem_layout default_layout[] = {
+ {0x20000000, 0x10000000, MEBIBYTE(128)},
+};
+
+/**
+ * register_non_ram - register low memory not available for RAM usage
+ */
+static __init void register_non_ram(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(low_mem_reserved); i++)
+ add_memory_region(low_mem_reserved[i].start,
+ low_mem_reserved[i].size, BOOT_MEM_RESERVED);
+}
+
+/**
+ * get_memsize - get the size of memory as a single bank
+ */
+static phys_addr_t get_memsize(void)
+{
+ static char cmdline[COMMAND_LINE_SIZE] __initdata;
+ phys_addr_t memsize = 0;
+ char *memsize_str;
+ char *ptr;
+
+ /* Check the command line first for a memsize directive */
+ strcpy(cmdline, arcs_cmdline);
+ ptr = strstr(cmdline, "memsize=");
+ if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
+ ptr = strstr(ptr, " memsize=");
+
+ if (ptr) {
+ memsize = memparse(ptr + 8, &ptr);
+ } else {
+ /* otherwise look in the environment */
+ memsize_str = prom_getenv("memsize");
+
+ if (memsize_str != NULL) {
+ pr_info("prom memsize = %s\n", memsize_str);
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+
+ if (memsize == 0) {
+ if (_prom_memsize != 0) {
+ memsize = _prom_memsize;
+ pr_info("_prom_memsize = 0x%x\n", memsize);
+ /* add in memory that the bootloader doesn't
+ * report */
+ memsize += BLDR_SIZE;
+ } else {
+ memsize = DEFAULT_MEMSIZE;
+ pr_info("Memsize not passed by bootloader, "
+ "defaulting to 0x%x\n", memsize);
+ }
+ }
+ }
+
+ return memsize;
+}
+
+/**
+ * register_low_ram - register an aliased section of RAM
+ * @p: Alias address of memory
+ * @n: Number of bytes in this section of memory
+ *
+ * Returns the number of bytes registered
+ *
+ */
+static __init phys_addr_t register_low_ram(phys_addr_t p, phys_addr_t n)
+{
+ phys_addr_t s;
+ int i;
+ phys_addr_t orig_n;
+
+ orig_n = n;
+
+ BUG_ON(p + n > RV_PHYS);
+
+ for (i = 0; n != 0 && i < ARRAY_SIZE(low_mem_reserved); i++) {
+ phys_addr_t start;
+ phys_addr_t size;
+
+ start = low_mem_reserved[i].start;
+ size = low_mem_reserved[i].size;
+
+ /* Handle memory before this low memory section */
+ if (p < start) {
+ phys_addr_t s;
+ s = min(n, start - p);
+ add_memory_region(p, s, BOOT_MEM_RAM);
+ p += s;
+ n -= s;
+ }
+
+ /* Handle the low memory section itself. If it's aliased,
+ * we reduce the number of byes left, but if not, the RAM
+ * is available elsewhere and we don't reduce the number of
+ * bytes remaining. */
+ if (p == start) {
+ if (low_mem_reserved[i].is_aliased) {
+ s = min(n, size);
+ n -= s;
+ p += s;
+ } else
+ p += n;
+ }
+ }
+
+ return orig_n - n;
+}
+
+/*
+ * register_ram - register real RAM
+ * @p: Address of memory as seen by devices
+ * @alias: If the memory is seen at an additional address by the processor,
+ * this will be the address, otherwise it is the same as @p.
+ * @n: Number of bytes in this section of memory
+ */
+static __init void register_ram(phys_addr_t p, phys_addr_t alias,
+ phys_addr_t n)
+{
+ /*
+ * If some or all of this memory has an alias, break it into the
+ * aliased and non-aliased portion.
+ */
+ if (p != alias) {
+ phys_addr_t alias_size;
+ phys_addr_t registered;
+
+ alias_size = min(n, LOW_RAM_END - alias);
+ registered = register_low_ram(alias, alias_size);
+ ioremap_add_map(alias, p, n);
+ n -= registered;
+ p += registered;
+ }
+
+#ifdef CONFIG_HIGHMEM
+ if (n != 0) {
+ add_memory_region(p, n, BOOT_MEM_RAM);
+ ioremap_add_map(p, p, n);
+ }
+#endif
+}
+
+/**
+ * register_address_space - register things in the address space
+ * @memsize: Number of bytes of RAM installed
+ *
+ * Takes the given number of bytes of RAM and registers as many of the regions,
+ * or partial regions, as it can. So, the default configuration might have
+ * two regions with 256 MiB each. If the memsize passed in on the command line
+ * is 384 MiB, it will register the first region with 256 MiB and the second
+ * with 128 MiB.
+ */
+static __init void register_address_space(phys_addr_t memsize)
+{
+ int i;
+ phys_addr_t size;
+ size_t n;
+ struct mem_layout *layout;
+ enum family_type family;
+
+ /*
+ * Register all of the things that aren't available to the kernel as
+ * memory.
+ */
+ register_non_ram();
+
+ /* Find the appropriate memory description */
+ family = platform_get_family();
+
+ for (i = 0; i < ARRAY_SIZE(layout_list); i++) {
+ if (layout_list[i].family == family)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(layout_list)) {
+ n = ARRAY_SIZE(default_layout);
+ layout = default_layout;
+ } else {
+ n = layout_list[i].n;
+ layout = layout_list[i].layout;
+ }
+
+ for (i = 0; memsize != 0 && i < n; i++) {
+ size = min(memsize, layout[i].size);
+ register_ram(layout[i].phys, layout[i].alias, size);
+ memsize -= size;
+ }
+}
+
+void __init prom_meminit(void)
+{
+ ptv_memsize = get_memsize();
+ register_address_space(ptv_memsize);
+}
+
+void __init prom_free_prom_memory(void)
+{
+ unsigned long addr;
+ int i;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ free_init_pages("prom memory",
+ addr, addr + boot_mem_map.map[i].size);
+ }
+}
diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile
new file mode 100644
index 00000000..5783201c
--- /dev/null
+++ b/arch/mips/powertv/pci/Makefile
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2009 Scientific-Atlanta, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+obj-$(CONFIG_PCI) += fixup-powertv.o
+
+ccflags-y := -Wall -Werror
diff --git a/arch/mips/powertv/pci/fixup-powertv.c b/arch/mips/powertv/pci/fixup-powertv.c
new file mode 100644
index 00000000..726bc2e8
--- /dev/null
+++ b/arch/mips/powertv/pci/fixup-powertv.c
@@ -0,0 +1,36 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/mach-powertv/interrupts.h>
+#include "powertv-pci.h"
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return asic_pcie_map_irq(dev, slot, pin);
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+/*
+ * asic_pcie_map_irq
+ *
+ * Parameters:
+ * *dev - pointer to a pci_dev structure (not used)
+ * slot - slot number (not used)
+ * pin - pin number (not used)
+ *
+ * Return Value:
+ * Returns: IRQ number (always the PCI Express IRQ number)
+ *
+ * Description:
+ * asic_pcie_map_irq will return the IRQ number of the PCI Express interrupt.
+ *
+ */
+int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irq_pciexp;
+}
+EXPORT_SYMBOL(asic_pcie_map_irq);
diff --git a/arch/mips/powertv/pci/powertv-pci.h b/arch/mips/powertv/pci/powertv-pci.h
new file mode 100644
index 00000000..1b5886bb
--- /dev/null
+++ b/arch/mips/powertv/pci/powertv-pci.h
@@ -0,0 +1,31 @@
+/*
+ * powertv-pci.c
+ *
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+/*
+ * Local definitions for the powertv PCI code
+ */
+
+#ifndef _POWERTV_PCI_POWERTV_PCI_H_
+#define _POWERTV_PCI_POWERTV_PCI_H_
+extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+extern int asic_pcie_init(void);
+extern int asic_pcie_init(void);
+
+extern int log_level;
+#endif
diff --git a/arch/mips/powertv/powertv-clock.h b/arch/mips/powertv/powertv-clock.h
new file mode 100644
index 00000000..d94c5431
--- /dev/null
+++ b/arch/mips/powertv/powertv-clock.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: David VomLehn
+ */
+
+#ifndef _POWERTV_POWERTV_CLOCK_H
+#define _POWERTV_POWERTV_CLOCK_H
+extern int powertv_clockevent_init(void);
+extern void powertv_clocksource_init(void);
+extern unsigned int mips_get_pll_freq(void);
+#endif
diff --git a/arch/mips/powertv/powertv-usb.c b/arch/mips/powertv/powertv-usb.c
new file mode 100644
index 00000000..6ac85cf7
--- /dev/null
+++ b/arch/mips/powertv/powertv-usb.c
@@ -0,0 +1,403 @@
+/*
+ * powertv-usb.c
+ *
+ * Description: ASIC-specific USB device setup and shutdown
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: Ken Eppinett
+ * David Schleef <ds@schleef.org>
+ *
+ * NOTE: The bootloader allocates persistent memory at an address which is
+ * 16 MiB below the end of the highest address in KSEG0. All fixed
+ * address memory reservations must avoid this region.
+ */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/interrupts.h>
+
+/* misc_clk_ctl1 values */
+#define MCC1_30MHZ_POWERUP_SELECT (1 << 14)
+#define MCC1_DIV9 (1 << 13)
+#define MCC1_ETHMIPS_POWERUP_SELECT (1 << 11)
+#define MCC1_USB_POWERUP_SELECT (1 << 1)
+#define MCC1_CLOCK108_POWERUP_SELECT (1 << 0)
+
+/* Possible values for clock select */
+#define MCC1_USB_CLOCK_HIGH_Z (0 << 4)
+#define MCC1_USB_CLOCK_48MHZ (1 << 4)
+#define MCC1_USB_CLOCK_24MHZ (2 << 4)
+#define MCC1_USB_CLOCK_6MHZ (3 << 4)
+
+#define MCC1_CONFIG (MCC1_30MHZ_POWERUP_SELECT | \
+ MCC1_DIV9 | \
+ MCC1_ETHMIPS_POWERUP_SELECT | \
+ MCC1_USB_POWERUP_SELECT | \
+ MCC1_CLOCK108_POWERUP_SELECT)
+
+/* misc_clk_ctl2 values */
+#define MCC2_GMII_GCLK_TO_PAD (1 << 31)
+#define MCC2_ETHER125_0_CLOCK_SELECT (1 << 29)
+#define MCC2_RMII_0_CLOCK_SELECT (1 << 28)
+#define MCC2_GMII_TX0_CLOCK_SELECT (1 << 27)
+#define MCC2_GMII_RX0_CLOCK_SELECT (1 << 26)
+#define MCC2_ETHER125_1_CLOCK_SELECT (1 << 24)
+#define MCC2_RMII_1_CLOCK_SELECT (1 << 23)
+#define MCC2_GMII_TX1_CLOCK_SELECT (1 << 22)
+#define MCC2_GMII_RX1_CLOCK_SELECT (1 << 21)
+#define MCC2_ETHER125_2_CLOCK_SELECT (1 << 19)
+#define MCC2_RMII_2_CLOCK_SELECT (1 << 18)
+#define MCC2_GMII_TX2_CLOCK_SELECT (1 << 17)
+#define MCC2_GMII_RX2_CLOCK_SELECT (1 << 16)
+
+#define ETHER_CLK_CONFIG (MCC2_GMII_GCLK_TO_PAD | \
+ MCC2_ETHER125_0_CLOCK_SELECT | \
+ MCC2_RMII_0_CLOCK_SELECT | \
+ MCC2_GMII_TX0_CLOCK_SELECT | \
+ MCC2_GMII_RX0_CLOCK_SELECT | \
+ MCC2_ETHER125_1_CLOCK_SELECT | \
+ MCC2_RMII_1_CLOCK_SELECT | \
+ MCC2_GMII_TX1_CLOCK_SELECT | \
+ MCC2_GMII_RX1_CLOCK_SELECT | \
+ MCC2_ETHER125_2_CLOCK_SELECT | \
+ MCC2_RMII_2_CLOCK_SELECT | \
+ MCC2_GMII_TX2_CLOCK_SELECT | \
+ MCC2_GMII_RX2_CLOCK_SELECT)
+
+/* misc_clk_ctl2 definitions for Gaia */
+#define FSX4A_REF_SELECT (1 << 16)
+#define FSX4B_REF_SELECT (1 << 17)
+#define FSX4C_REF_SELECT (1 << 18)
+#define DDR_PLL_REF_SELECT (1 << 19)
+#define MIPS_PLL_REF_SELECT (1 << 20)
+
+/* Definitions for the QAM frequency select register FS432X4A4_QAM_CTL */
+#define QAM_FS_SDIV_SHIFT 29
+#define QAM_FS_MD_SHIFT 24
+#define QAM_FS_MD_MASK 0x1f /* Cut down to 5 bits */
+#define QAM_FS_PE_SHIFT 8
+
+#define QAM_FS_DISABLE_DIVIDE_BY_3 (1 << 5)
+#define QAM_FS_ENABLE_PROGRAM (1 << 4)
+#define QAM_FS_ENABLE_OUTPUT (1 << 3)
+#define QAM_FS_SELECT_TEST_BYPASS (1 << 2)
+#define QAM_FS_DISABLE_DIGITAL_STANDBY (1 << 1)
+#define QAM_FS_CHOOSE_FS (1 << 0)
+
+/* Definitions for fs432x4a_ctl register */
+#define QAM_FS_NSDIV_54MHZ (1 << 2)
+
+/* Definitions for bcm1_usb2_ctl register */
+#define BCM1_USB2_CTL_BISTOK (1 << 11)
+#define BCM1_USB2_CTL_PORT2_SHIFT_JK (1 << 7)
+#define BCM1_USB2_CTL_PORT1_SHIFT_JK (1 << 6)
+#define BCM1_USB2_CTL_PORT2_FAST_EDGE (1 << 5)
+#define BCM1_USB2_CTL_PORT1_FAST_EDGE (1 << 4)
+#define BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH (1 << 1)
+#define BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH (1 << 0)
+
+/* Definitions for crt_spare register */
+#define CRT_SPARE_PORT2_SHIFT_JK (1 << 21)
+#define CRT_SPARE_PORT1_SHIFT_JK (1 << 20)
+#define CRT_SPARE_PORT2_FAST_EDGE (1 << 19)
+#define CRT_SPARE_PORT1_FAST_EDGE (1 << 18)
+#define CRT_SPARE_DIVIDE_BY_9_FROM_432 (1 << 17)
+#define CRT_SPARE_USB_DIVIDE_BY_9 (1 << 16)
+
+/* Definitions for usb2_stbus_obc register */
+#define USB_STBUS_OBC_STORE32_LOAD32 0x3
+
+/* Definitions for usb2_stbus_mess_size register */
+#define USB2_STBUS_MESS_SIZE_2 0x1 /* 2 packets */
+
+/* Definitions for usb2_stbus_chunk_size register */
+#define USB2_STBUS_CHUNK_SIZE_2 0x1 /* 2 packets */
+
+/* Definitions for usb2_strap register */
+#define USB2_STRAP_HFREQ_SELECT 0x1
+
+/*
+ * USB Host Resource Definition
+ */
+
+static struct resource ehci_resources[] = {
+ {
+ .parent = &asic_resource,
+ .start = 0,
+ .end = 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = irq_usbehci,
+ .end = irq_usbehci,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ehci_dmamask = 0xffffffffULL;
+
+static struct platform_device ehci_device = {
+ .name = "powertv-ehci",
+ .id = 0,
+ .num_resources = 2,
+ .resource = ehci_resources,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct resource ohci_resources[] = {
+ {
+ .parent = &asic_resource,
+ .start = 0,
+ .end = 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = irq_usbohci,
+ .end = irq_usbohci,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ohci_dmamask = 0xffffffffULL;
+
+static struct platform_device ohci_device = {
+ .name = "powertv-ohci",
+ .id = 0,
+ .num_resources = 2,
+ .resource = ohci_resources,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static unsigned usb_users;
+static DEFINE_SPINLOCK(usb_regs_lock);
+
+/*
+ *
+ * fs_update - set frequency synthesizer for USB
+ * @pe_bits Phase tap setting
+ * @md_bits Coarse selector bus for algorithm of phase tap
+ * @sdiv_bits Output divider setting
+ * @disable_div_by_3 Either QAM_FS_DISABLE_DIVIDE_BY_3 or zero
+ * @standby Either QAM_FS_DISABLE_DIGITAL_STANDBY or zero
+ *
+ * QAM frequency selection code, which affects the frequency at which USB
+ * runs. The frequency is calculated as:
+ * 2^15 * ndiv * Fin
+ * Fout = ------------------------------------------------------------
+ * (sdiv * (ipe * (1 + md/32) - (ipe - 2^15)*(1 + (md + 1)/32)))
+ * where:
+ * Fin 54 MHz
+ * ndiv QAM_FS_NSDIV_54MHZ ? 8 : 16
+ * sdiv 1 << (sdiv_bits + 1)
+ * ipe Same as pe_bits
+ * md A five-bit, two's-complement integer (range [-16, 15]), which
+ * is the lower 5 bits of md_bits.
+ */
+static void fs_update(u32 pe_bits, int md_bits, u32 sdiv_bits,
+ u32 disable_div_by_3, u32 standby)
+{
+ u32 val;
+
+ val = ((sdiv_bits << QAM_FS_SDIV_SHIFT) |
+ ((md_bits & QAM_FS_MD_MASK) << QAM_FS_MD_SHIFT) |
+ (pe_bits << QAM_FS_PE_SHIFT) |
+ QAM_FS_ENABLE_OUTPUT |
+ standby |
+ disable_div_by_3);
+ asic_write(val, fs432x4b4_usb_ctl);
+ asic_write(val | QAM_FS_ENABLE_PROGRAM, fs432x4b4_usb_ctl);
+ asic_write(val | QAM_FS_ENABLE_PROGRAM | QAM_FS_CHOOSE_FS,
+ fs432x4b4_usb_ctl);
+}
+
+/*
+ * usb_eye_configure - for optimizing the shape USB eye waveform
+ * @set: Bits to set in the register
+ * @clear: Bits to clear in the register; each bit with a one will
+ * be set in the register, zero bits will not be modified
+ */
+static void usb_eye_configure(u32 set, u32 clear)
+{
+ u32 old;
+
+ old = asic_read(crt_spare);
+ old |= set;
+ old &= ~clear;
+ asic_write(old, crt_spare);
+}
+
+/*
+ * platform_configure_usb - usb configuration based on platform type.
+ */
+static void platform_configure_usb(void)
+{
+ u32 bcm1_usb2_ctl_value;
+ enum asic_type asic_type;
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_regs_lock, flags);
+ usb_users++;
+
+ if (usb_users != 1) {
+ spin_unlock_irqrestore(&usb_regs_lock, flags);
+ return;
+ }
+
+ asic_type = platform_get_asic();
+
+ switch (asic_type) {
+ case ASIC_ZEUS:
+ fs_update(0x0000, -15, 0x02, 0, 0);
+ bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
+ BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
+ break;
+
+ case ASIC_CRONUS:
+ case ASIC_CRONUSLITE:
+ usb_eye_configure(0, CRT_SPARE_USB_DIVIDE_BY_9);
+ fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3,
+ QAM_FS_DISABLE_DIGITAL_STANDBY);
+ bcm1_usb2_ctl_value = BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
+ BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
+ break;
+
+ case ASIC_CALLIOPE:
+ fs_update(0x0000, -15, 0x02, QAM_FS_DISABLE_DIVIDE_BY_3,
+ QAM_FS_DISABLE_DIGITAL_STANDBY);
+
+ switch (platform_get_family()) {
+ case FAMILY_1500VZE:
+ break;
+
+ case FAMILY_1500VZF:
+ usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK |
+ CRT_SPARE_PORT1_SHIFT_JK |
+ CRT_SPARE_PORT2_FAST_EDGE |
+ CRT_SPARE_PORT1_FAST_EDGE, 0);
+ break;
+
+ default:
+ usb_eye_configure(CRT_SPARE_PORT2_SHIFT_JK |
+ CRT_SPARE_PORT1_SHIFT_JK, 0);
+ break;
+ }
+
+ bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK |
+ BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
+ BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
+ break;
+
+ case ASIC_GAIA:
+ fs_update(0x8000, -14, 0x03, QAM_FS_DISABLE_DIVIDE_BY_3,
+ QAM_FS_DISABLE_DIGITAL_STANDBY);
+ bcm1_usb2_ctl_value = BCM1_USB2_CTL_BISTOK |
+ BCM1_USB2_CTL_EHCI_PRT_PWR_ACTIVE_HIGH |
+ BCM1_USB2_CTL_APP_PRT_OVRCUR_IN_ACTIVE_HIGH;
+ break;
+
+ default:
+ pr_err("Unknown ASIC type: %d\n", asic_type);
+ bcm1_usb2_ctl_value = 0;
+ break;
+ }
+
+ /* turn on USB power */
+ asic_write(0, usb2_strap);
+ /* Enable all OHCI interrupts */
+ asic_write(bcm1_usb2_ctl_value, usb2_control);
+ /* usb2_stbus_obc store32/load32 */
+ asic_write(USB_STBUS_OBC_STORE32_LOAD32, usb2_stbus_obc);
+ /* usb2_stbus_mess_size 2 packets */
+ asic_write(USB2_STBUS_MESS_SIZE_2, usb2_stbus_mess_size);
+ /* usb2_stbus_chunk_size 2 packets */
+ asic_write(USB2_STBUS_CHUNK_SIZE_2, usb2_stbus_chunk_size);
+ spin_unlock_irqrestore(&usb_regs_lock, flags);
+}
+
+static void platform_unconfigure_usb(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_regs_lock, flags);
+ usb_users--;
+ if (usb_users == 0)
+ asic_write(USB2_STRAP_HFREQ_SELECT, usb2_strap);
+ spin_unlock_irqrestore(&usb_regs_lock, flags);
+}
+
+/*
+ * Set up the USB EHCI interface
+ */
+void platform_configure_usb_ehci()
+{
+ platform_configure_usb();
+}
+EXPORT_SYMBOL(platform_configure_usb_ehci);
+
+/*
+ * Set up the USB OHCI interface
+ */
+void platform_configure_usb_ohci()
+{
+ platform_configure_usb();
+}
+EXPORT_SYMBOL(platform_configure_usb_ohci);
+
+/*
+ * Shut the USB EHCI interface down
+ */
+void platform_unconfigure_usb_ehci()
+{
+ platform_unconfigure_usb();
+}
+EXPORT_SYMBOL(platform_unconfigure_usb_ehci);
+
+/*
+ * Shut the USB OHCI interface down
+ */
+void platform_unconfigure_usb_ohci()
+{
+ platform_unconfigure_usb();
+}
+EXPORT_SYMBOL(platform_unconfigure_usb_ohci);
+
+/**
+ * platform_devices_init - sets up USB device resourse.
+ */
+int __init platform_usb_devices_init(struct platform_device **ehci_dev,
+ struct platform_device **ohci_dev)
+{
+ *ehci_dev = &ehci_device;
+ ehci_resources[0].start = asic_reg_phys_addr(ehci_hcapbase);
+ ehci_resources[0].end += ehci_resources[0].start;
+
+ *ohci_dev = &ohci_device;
+ ohci_resources[0].start = asic_reg_phys_addr(ohci_hc_revision);
+ ohci_resources[0].end += ohci_resources[0].start;
+
+ return 0;
+}
diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c
new file mode 100644
index 00000000..3933c373
--- /dev/null
+++ b/arch/mips/powertv/powertv_setup.c
@@ -0,0 +1,320 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/screen_info.h>
+#include <linux/notifier.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <linux/ctype.h>
+#include <linux/cpu.h>
+#include <linux/time.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/dma.h>
+#include <asm/asm.h>
+#include <asm/traps.h>
+#include <asm/asm-offsets.h>
+#include "reset.h"
+
+#define VAL(n) STR(n)
+
+/*
+ * Macros for loading addresses and storing registers:
+ * LONG_L_ Stringified version of LONG_L for use in asm() statement
+ * LONG_S_ Stringified version of LONG_S for use in asm() statement
+ * PTR_LA_ Stringified version of PTR_LA for use in asm() statement
+ * REG_SIZE Number of 8-bit bytes in a full width register
+ */
+#define LONG_L_ VAL(LONG_L) " "
+#define LONG_S_ VAL(LONG_S) " "
+#define PTR_LA_ VAL(PTR_LA) " "
+
+#ifdef CONFIG_64BIT
+#warning TODO: 64-bit code needs to be verified
+#define REG_SIZE "8" /* In bytes */
+#endif
+
+#ifdef CONFIG_32BIT
+#define REG_SIZE "4" /* In bytes */
+#endif
+
+static void register_panic_notifier(void);
+static int panic_handler(struct notifier_block *notifier_block,
+ unsigned long event, void *cause_string);
+
+const char *get_system_type(void)
+{
+ return "PowerTV";
+}
+
+void __init plat_mem_setup(void)
+{
+ panic_on_oops = 1;
+ register_panic_notifier();
+
+#if 0
+ mips_pcibios_init();
+#endif
+ mips_reboot_setup();
+}
+
+/*
+ * Install a panic notifier for platform-specific diagnostics
+ */
+static void register_panic_notifier()
+{
+ static struct notifier_block panic_notifier = {
+ .notifier_call = panic_handler,
+ .next = NULL,
+ .priority = INT_MAX
+ };
+ atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier);
+}
+
+static int panic_handler(struct notifier_block *notifier_block,
+ unsigned long event, void *cause_string)
+{
+ struct pt_regs my_regs;
+
+ /* Save all of the registers */
+ {
+ unsigned long at, v0, v1; /* Must be on the stack */
+
+ /* Start by saving $at and v0 on the stack. We use $at
+ * ourselves, but it looks like the compiler may use v0 or v1
+ * to load the address of the pt_regs structure. We'll come
+ * back later to store the registers in the pt_regs
+ * structure. */
+ __asm__ __volatile__ (
+ ".set noat\n"
+ LONG_S_ "$at, %[at]\n"
+ LONG_S_ "$2, %[v0]\n"
+ LONG_S_ "$3, %[v1]\n"
+ :
+ [at] "=m" (at),
+ [v0] "=m" (v0),
+ [v1] "=m" (v1)
+ :
+ : "at"
+ );
+
+ __asm__ __volatile__ (
+ ".set noat\n"
+ "move $at, %[pt_regs]\n"
+
+ /* Argument registers */
+ LONG_S_ "$4, " VAL(PT_R4) "($at)\n"
+ LONG_S_ "$5, " VAL(PT_R5) "($at)\n"
+ LONG_S_ "$6, " VAL(PT_R6) "($at)\n"
+ LONG_S_ "$7, " VAL(PT_R7) "($at)\n"
+
+ /* Temporary regs */
+ LONG_S_ "$8, " VAL(PT_R8) "($at)\n"
+ LONG_S_ "$9, " VAL(PT_R9) "($at)\n"
+ LONG_S_ "$10, " VAL(PT_R10) "($at)\n"
+ LONG_S_ "$11, " VAL(PT_R11) "($at)\n"
+ LONG_S_ "$12, " VAL(PT_R12) "($at)\n"
+ LONG_S_ "$13, " VAL(PT_R13) "($at)\n"
+ LONG_S_ "$14, " VAL(PT_R14) "($at)\n"
+ LONG_S_ "$15, " VAL(PT_R15) "($at)\n"
+
+ /* "Saved" registers */
+ LONG_S_ "$16, " VAL(PT_R16) "($at)\n"
+ LONG_S_ "$17, " VAL(PT_R17) "($at)\n"
+ LONG_S_ "$18, " VAL(PT_R18) "($at)\n"
+ LONG_S_ "$19, " VAL(PT_R19) "($at)\n"
+ LONG_S_ "$20, " VAL(PT_R20) "($at)\n"
+ LONG_S_ "$21, " VAL(PT_R21) "($at)\n"
+ LONG_S_ "$22, " VAL(PT_R22) "($at)\n"
+ LONG_S_ "$23, " VAL(PT_R23) "($at)\n"
+
+ /* Add'l temp regs */
+ LONG_S_ "$24, " VAL(PT_R24) "($at)\n"
+ LONG_S_ "$25, " VAL(PT_R25) "($at)\n"
+
+ /* Kernel temp regs */
+ LONG_S_ "$26, " VAL(PT_R26) "($at)\n"
+ LONG_S_ "$27, " VAL(PT_R27) "($at)\n"
+
+ /* Global pointer, stack pointer, frame pointer and
+ * return address */
+ LONG_S_ "$gp, " VAL(PT_R28) "($at)\n"
+ LONG_S_ "$sp, " VAL(PT_R29) "($at)\n"
+ LONG_S_ "$fp, " VAL(PT_R30) "($at)\n"
+ LONG_S_ "$ra, " VAL(PT_R31) "($at)\n"
+
+ /* Now we can get the $at and v0 registers back and
+ * store them */
+ LONG_L_ "$8, %[at]\n"
+ LONG_S_ "$8, " VAL(PT_R1) "($at)\n"
+ LONG_L_ "$8, %[v0]\n"
+ LONG_S_ "$8, " VAL(PT_R2) "($at)\n"
+ LONG_L_ "$8, %[v1]\n"
+ LONG_S_ "$8, " VAL(PT_R3) "($at)\n"
+ :
+ :
+ [at] "m" (at),
+ [v0] "m" (v0),
+ [v1] "m" (v1),
+ [pt_regs] "r" (&my_regs)
+ : "at", "t0"
+ );
+
+ /* Set the current EPC value to be the current location in this
+ * function */
+ __asm__ __volatile__ (
+ ".set noat\n"
+ "1:\n"
+ PTR_LA_ "$at, 1b\n"
+ LONG_S_ "$at, %[cp0_epc]\n"
+ :
+ [cp0_epc] "=m" (my_regs.cp0_epc)
+ :
+ : "at"
+ );
+
+ my_regs.cp0_cause = read_c0_cause();
+ my_regs.cp0_status = read_c0_status();
+ }
+
+ pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... "
+ "zzzz... \n");
+
+ return NOTIFY_DONE;
+}
+
+/* Information about the RF MAC address, if one was supplied on the
+ * command line. */
+static bool have_rfmac;
+static u8 rfmac[ETH_ALEN];
+
+static int rfmac_param(char *p)
+{
+ u8 *q;
+ bool is_high_nibble;
+ int c;
+
+ /* Skip a leading "0x", if present */
+ if (*p == '0' && *(p+1) == 'x')
+ p += 2;
+
+ q = rfmac;
+ is_high_nibble = true;
+
+ for (c = (unsigned char) *p++;
+ isxdigit(c) && q - rfmac < ETH_ALEN;
+ c = (unsigned char) *p++) {
+ int nibble;
+
+ nibble = (isdigit(c) ? (c - '0') :
+ (isupper(c) ? c - 'A' + 10 : c - 'a' + 10));
+
+ if (is_high_nibble)
+ *q = nibble << 4;
+ else
+ *q++ |= nibble;
+
+ is_high_nibble = !is_high_nibble;
+ }
+
+ /* If we parsed all the way to the end of the parameter value and
+ * parsed all ETH_ALEN bytes, we have a usable RF MAC address */
+ have_rfmac = (c == '\0' && q - rfmac == ETH_ALEN);
+
+ return 0;
+}
+
+early_param("rfmac", rfmac_param);
+
+/*
+ * Generate an Ethernet MAC address that has a good chance of being unique.
+ * @addr: Pointer to six-byte array containing the Ethernet address
+ * Generates an Ethernet MAC address that is highly likely to be unique for
+ * this particular system on a network with other systems of the same type.
+ *
+ * The problem we are solving is that, when random_ether_addr() is used to
+ * generate MAC addresses at startup, there isn't much entropy for the random
+ * number generator to use and the addresses it produces are fairly likely to
+ * be the same as those of other identical systems on the same local network.
+ * This is true even for relatively small numbers of systems (for the reason
+ * why, see the Wikipedia entry for "Birthday problem" at:
+ * http://en.wikipedia.org/wiki/Birthday_problem
+ *
+ * The good news is that we already have a MAC address known to be unique, the
+ * RF MAC address. The bad news is that this address is already in use on the
+ * RF interface. Worse, the obvious trick, taking the RF MAC address and
+ * turning on the locally managed bit, has already been used for other devices.
+ * Still, this does give us something to work with.
+ *
+ * The approach we take is:
+ * 1. If we can't get the RF MAC Address, just call random_ether_addr.
+ * 2. Use the 24-bit NIC-specific bits of the RF MAC address as the last 24
+ * bits of the new address. This is very likely to be unique, except for
+ * the current box.
+ * 3. To avoid using addresses already on the current box, we set the top
+ * six bits of the address with a value different from any currently
+ * registered Scientific Atlanta organizationally unique identifyer
+ * (OUI). This avoids duplication with any addresses on the system that
+ * were generated from valid Scientific Atlanta-registered address by
+ * simply flipping the locally managed bit.
+ * 4. We aren't generating a multicast address, so we leave the multicast
+ * bit off. Since we aren't using a registered address, we have to set
+ * the locally managed bit.
+ * 5. We then randomly generate the remaining 16-bits. This does two
+ * things:
+ * a. It allows us to call this function for more than one device
+ * in this system
+ * b. It ensures that things will probably still work even if
+ * some device on the device network has a locally managed
+ * address that matches the top six bits from step 2.
+ */
+void platform_random_ether_addr(u8 addr[ETH_ALEN])
+{
+ const int num_random_bytes = 2;
+ const unsigned char non_sciatl_oui_bits = 0xc0u;
+ const unsigned char mac_addr_locally_managed = (1 << 1);
+
+ if (!have_rfmac) {
+ pr_warning("rfmac not available on command line; "
+ "generating random MAC address\n");
+ random_ether_addr(addr);
+ }
+
+ else {
+ int i;
+
+ /* Set the first byte to something that won't match a Scientific
+ * Atlanta OUI, is locally managed, and isn't a multicast
+ * address */
+ addr[0] = non_sciatl_oui_bits | mac_addr_locally_managed;
+
+ /* Get some bytes of random address information */
+ get_random_bytes(&addr[1], num_random_bytes);
+
+ /* Copy over the NIC-specific bits of the RF MAC address */
+ for (i = 1 + num_random_bytes; i < ETH_ALEN; i++)
+ addr[i] = rfmac[i];
+ }
+}
diff --git a/arch/mips/powertv/reset.c b/arch/mips/powertv/reset.c
new file mode 100644
index 00000000..0007652c
--- /dev/null
+++ b/arch/mips/powertv/reset.c
@@ -0,0 +1,47 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+#include <linux/pm.h>
+
+#include <linux/io.h>
+#include <asm/reboot.h> /* Not included by linux/reboot.h */
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+#include <asm/mach-powertv/kbldr.h>
+#endif
+
+#include <asm/mach-powertv/asic_regs.h>
+#include "reset.h"
+
+static void mips_machine_restart(char *command)
+{
+#ifdef CONFIG_BOOTLOADER_DRIVER
+ /*
+ * Call the bootloader's reset function to ensure
+ * that persistent data is flushed before hard reset
+ */
+ kbldr_SetCauseAndReset();
+#else
+ writel(0x1, asic_reg_addr(watchdog));
+#endif
+}
+
+void mips_reboot_setup(void)
+{
+ _machine_restart = mips_machine_restart;
+}
diff --git a/arch/mips/powertv/reset.h b/arch/mips/powertv/reset.h
new file mode 100644
index 00000000..888fd09e
--- /dev/null
+++ b/arch/mips/powertv/reset.h
@@ -0,0 +1,26 @@
+/*
+ * Definitions from powertv reset.c file
+ *
+ * Copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: David VomLehn
+ */
+
+#ifndef _POWERTV_POWERTV_RESET_H
+#define _POWERTV_POWERTV_RESET_H
+extern void mips_reboot_setup(void);
+#endif
diff --git a/arch/mips/powertv/time.c b/arch/mips/powertv/time.c
new file mode 100644
index 00000000..9fd7b67f
--- /dev/null
+++ b/arch/mips/powertv/time.c
@@ -0,0 +1,36 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ * Portions copyright (C) 2009 Cisco Systems, Inc.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+
+#include <linux/init.h>
+#include <asm/mach-powertv/interrupts.h>
+#include <asm/time.h>
+
+#include "powertv-clock.h"
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ return irq_mips_timer;
+}
+
+void __init plat_time_init(void)
+{
+ powertv_clocksource_init();
+}
diff --git a/arch/mips/rb532/Makefile b/arch/mips/rb532/Makefile
new file mode 100644
index 00000000..efdecdb6
--- /dev/null
+++ b/arch/mips/rb532/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the RB532 board specific parts of the kernel
+#
+
+obj-y += irq.o time.o setup.o serial.o prom.o gpio.o devices.o
diff --git a/arch/mips/rb532/Platform b/arch/mips/rb532/Platform
new file mode 100644
index 00000000..aeec45a7
--- /dev/null
+++ b/arch/mips/rb532/Platform
@@ -0,0 +1,7 @@
+#
+# Routerboard 532
+#
+platform-$(CONFIG_MIKROTIK_RB532) += rb532/
+cflags-$(CONFIG_MIKROTIK_RB532) += \
+ -I$(srctree)/arch/mips/include/asm/mach-rc32434
+load-$(CONFIG_MIKROTIK_RB532) += 0xffffffff80101000
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
new file mode 100644
index 00000000..041fc1af
--- /dev/null
+++ b/arch/mips/rb532/devices.c
@@ -0,0 +1,348 @@
+/*
+ * RouterBoard 500 Platform devices
+ *
+ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/serial_8250.h>
+
+#include <asm/bootinfo.h>
+
+#include <asm/mach-rc32434/rc32434.h>
+#include <asm/mach-rc32434/dma.h>
+#include <asm/mach-rc32434/dma_v.h>
+#include <asm/mach-rc32434/eth.h>
+#include <asm/mach-rc32434/rb.h>
+#include <asm/mach-rc32434/integ.h>
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/irq.h>
+
+#define ETH0_RX_DMA_ADDR (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET)
+#define ETH0_TX_DMA_ADDR (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET)
+
+extern unsigned int idt_cpu_freq;
+
+static struct mpmc_device dev3;
+
+void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev3.lock, flags);
+
+ dev3.state = (dev3.state | or_mask) & ~nand_mask;
+ writeb(dev3.state, dev3.base);
+
+ spin_unlock_irqrestore(&dev3.lock, flags);
+}
+EXPORT_SYMBOL(set_latch_u5);
+
+unsigned char get_latch_u5(void)
+{
+ return dev3.state;
+}
+EXPORT_SYMBOL(get_latch_u5);
+
+static struct resource korina_dev0_res[] = {
+ {
+ .name = "korina_regs",
+ .start = ETH0_BASE_ADDR,
+ .end = ETH0_BASE_ADDR + sizeof(struct eth_regs),
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "korina_rx",
+ .start = ETH0_DMA_RX_IRQ,
+ .end = ETH0_DMA_RX_IRQ,
+ .flags = IORESOURCE_IRQ
+ }, {
+ .name = "korina_tx",
+ .start = ETH0_DMA_TX_IRQ,
+ .end = ETH0_DMA_TX_IRQ,
+ .flags = IORESOURCE_IRQ
+ }, {
+ .name = "korina_ovr",
+ .start = ETH0_RX_OVR_IRQ,
+ .end = ETH0_RX_OVR_IRQ,
+ .flags = IORESOURCE_IRQ
+ }, {
+ .name = "korina_und",
+ .start = ETH0_TX_UND_IRQ,
+ .end = ETH0_TX_UND_IRQ,
+ .flags = IORESOURCE_IRQ
+ }, {
+ .name = "korina_dma_rx",
+ .start = ETH0_RX_DMA_ADDR,
+ .end = ETH0_RX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "korina_dma_tx",
+ .start = ETH0_TX_DMA_ADDR,
+ .end = ETH0_TX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct korina_device korina_dev0_data = {
+ .name = "korina0",
+ .mac = {0xde, 0xca, 0xff, 0xc0, 0xff, 0xee}
+};
+
+static struct platform_device korina_dev0 = {
+ .id = -1,
+ .name = "korina",
+ .resource = korina_dev0_res,
+ .num_resources = ARRAY_SIZE(korina_dev0_res),
+};
+
+static struct resource cf_slot0_res[] = {
+ {
+ .name = "cf_membase",
+ .flags = IORESOURCE_MEM
+ }, {
+ .name = "cf_irq",
+ .start = (8 + 4 * 32 + CF_GPIO_NUM), /* 149 */
+ .end = (8 + 4 * 32 + CF_GPIO_NUM),
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct cf_device cf_slot0_data = {
+ .gpio_pin = CF_GPIO_NUM
+};
+
+static struct platform_device cf_slot0 = {
+ .id = -1,
+ .name = "pata-rb532-cf",
+ .dev.platform_data = &cf_slot0_data,
+ .resource = cf_slot0_res,
+ .num_resources = ARRAY_SIZE(cf_slot0_res),
+};
+
+/* Resources and device for NAND */
+static int rb532_dev_ready(struct mtd_info *mtd)
+{
+ return gpio_get_value(GPIO_RDY);
+}
+
+static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *chip = mtd->priv;
+ unsigned char orbits, nandbits;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ orbits = (ctrl & NAND_CLE) << 1;
+ orbits |= (ctrl & NAND_ALE) >> 1;
+
+ nandbits = (~ctrl & NAND_CLE) << 1;
+ nandbits |= (~ctrl & NAND_ALE) >> 1;
+
+ set_latch_u5(orbits, nandbits);
+ }
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, chip->IO_ADDR_W);
+}
+
+static struct resource nand_slot0_res[] = {
+ [0] = {
+ .name = "nand_membase",
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct platform_nand_data rb532_nand_data = {
+ .ctrl.dev_ready = rb532_dev_ready,
+ .ctrl.cmd_ctrl = rb532_cmd_ctrl,
+};
+
+static struct platform_device nand_slot0 = {
+ .name = "gen_nand",
+ .id = -1,
+ .resource = nand_slot0_res,
+ .num_resources = ARRAY_SIZE(nand_slot0_res),
+ .dev.platform_data = &rb532_nand_data,
+};
+
+static struct mtd_partition rb532_partition_info[] = {
+ {
+ .name = "Routerboard NAND boot",
+ .offset = 0,
+ .size = 4 * 1024 * 1024,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct platform_device rb532_led = {
+ .name = "rb532-led",
+ .id = -1,
+};
+
+static struct platform_device rb532_button = {
+ .name = "rb532-button",
+ .id = -1,
+};
+
+static struct resource rb532_wdt_res[] = {
+ {
+ .name = "rb532_wdt_res",
+ .start = INTEG0_BASE_ADDR,
+ .end = INTEG0_BASE_ADDR + sizeof(struct integ),
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device rb532_wdt = {
+ .name = "rc32434_wdt",
+ .id = -1,
+ .resource = rb532_wdt_res,
+ .num_resources = ARRAY_SIZE(rb532_wdt_res),
+};
+
+static struct plat_serial8250_port rb532_uart_res[] = {
+ {
+ .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE),
+ .irq = UART0_IRQ,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF,
+ },
+ {
+ .flags = 0,
+ }
+};
+
+static struct platform_device rb532_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = &rb532_uart_res,
+};
+
+static struct platform_device *rb532_devs[] = {
+ &korina_dev0,
+ &nand_slot0,
+ &cf_slot0,
+ &rb532_led,
+ &rb532_button,
+ &rb532_uart,
+ &rb532_wdt
+};
+
+static void __init parse_mac_addr(char *macstr)
+{
+ int i, j;
+ unsigned char result, value;
+
+ for (i = 0; i < 6; i++) {
+ result = 0;
+
+ if (i != 5 && *(macstr + 2) != ':')
+ return;
+
+ for (j = 0; j < 2; j++) {
+ if (isxdigit(*macstr)
+ && (value =
+ isdigit(*macstr) ? *macstr -
+ '0' : toupper(*macstr) - 'A' + 10) < 16) {
+ result = result * 16 + value;
+ macstr++;
+ } else
+ return;
+ }
+
+ macstr++;
+ korina_dev0_data.mac[i] = result;
+ }
+}
+
+
+/* NAND definitions */
+#define NAND_CHIP_DELAY 25
+
+static void __init rb532_nand_setup(void)
+{
+ switch (mips_machtype) {
+ case MACH_MIKROTIK_RB532A:
+ set_latch_u5(LO_FOFF | LO_CEX,
+ LO_ULED | LO_ALE | LO_CLE | LO_WPX);
+ break;
+ default:
+ set_latch_u5(LO_WPX | LO_FOFF | LO_CEX,
+ LO_ULED | LO_ALE | LO_CLE);
+ break;
+ }
+
+ /* Setup NAND specific settings */
+ rb532_nand_data.chip.nr_chips = 1;
+ rb532_nand_data.chip.nr_partitions = ARRAY_SIZE(rb532_partition_info);
+ rb532_nand_data.chip.partitions = rb532_partition_info;
+ rb532_nand_data.chip.chip_delay = NAND_CHIP_DELAY;
+ rb532_nand_data.chip.options = NAND_NO_AUTOINCR;
+}
+
+
+static int __init plat_setup_devices(void)
+{
+ /* Look for the CF card reader */
+ if (!readl(IDT434_REG_BASE + DEV1MASK))
+ rb532_devs[2] = NULL; /* disable cf_slot0 at index 2 */
+ else {
+ cf_slot0_res[0].start =
+ readl(IDT434_REG_BASE + DEV1BASE);
+ cf_slot0_res[0].end = cf_slot0_res[0].start + 0x1000;
+ }
+
+ /* Read the NAND resources from the device controller */
+ nand_slot0_res[0].start = readl(IDT434_REG_BASE + DEV2BASE);
+ nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000;
+
+ /* Read and map device controller 3 */
+ dev3.base = ioremap_nocache(readl(IDT434_REG_BASE + DEV3BASE), 1);
+
+ if (!dev3.base) {
+ printk(KERN_ERR "rb532: cannot remap device controller 3\n");
+ return -ENXIO;
+ }
+
+ /* Initialise the NAND device */
+ rb532_nand_setup();
+
+ /* set the uart clock to the current cpu frequency */
+ rb532_uart_res[0].uartclk = idt_cpu_freq;
+
+ dev_set_drvdata(&korina_dev0.dev, &korina_dev0_data);
+
+ return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
+}
+
+static int __init setup_kmac(char *s)
+{
+ printk(KERN_INFO "korina mac = %s\n", s);
+ parse_mac_addr(s);
+ return 0;
+}
+
+__setup("kmac=", setup_kmac);
+
+arch_initcall(plat_setup_devices);
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
new file mode 100644
index 00000000..6c47dfeb
--- /dev/null
+++ b/arch/mips/rb532/gpio.c
@@ -0,0 +1,200 @@
+/*
+ * Miscellaneous functions for IDT EB434 board
+ *
+ * Copyright 2004 IDT Inc. (rischelp@idt.com)
+ * Copyright 2006 Phil Sutter <n0-1@freewrt.org>
+ * Copyright 2007 Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-rc32434/rb.h>
+#include <asm/mach-rc32434/gpio.h>
+
+struct rb532_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *regbase;
+};
+
+static struct resource rb532_gpio_reg0_res[] = {
+ {
+ .name = "gpio_reg0",
+ .start = REGBASE + GPIOBASE,
+ .end = REGBASE + GPIOBASE + sizeof(struct rb532_gpio_reg) - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+/* rb532_set_bit - sanely set a bit
+ *
+ * bitval: new value for the bit
+ * offset: bit index in the 4 byte address range
+ * ioaddr: 4 byte aligned address being altered
+ */
+static inline void rb532_set_bit(unsigned bitval,
+ unsigned offset, void __iomem *ioaddr)
+{
+ unsigned long flags;
+ u32 val;
+
+ local_irq_save(flags);
+
+ val = readl(ioaddr);
+ val &= ~(!bitval << offset); /* unset bit if bitval == 0 */
+ val |= (!!bitval << offset); /* set bit if bitval == 1 */
+ writel(val, ioaddr);
+
+ local_irq_restore(flags);
+}
+
+/* rb532_get_bit - read a bit
+ *
+ * returns the boolean state of the bit, which may be > 1
+ */
+static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr)
+{
+ return (readl(ioaddr) & (1 << offset));
+}
+
+/*
+ * Return GPIO level */
+static int rb532_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct rb532_gpio_chip *gpch;
+
+ gpch = container_of(chip, struct rb532_gpio_chip, chip);
+ return rb532_get_bit(offset, gpch->regbase + GPIOD);
+}
+
+/*
+ * Set output GPIO level
+ */
+static void rb532_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct rb532_gpio_chip *gpch;
+
+ gpch = container_of(chip, struct rb532_gpio_chip, chip);
+ rb532_set_bit(value, offset, gpch->regbase + GPIOD);
+}
+
+/*
+ * Set GPIO direction to input
+ */
+static int rb532_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct rb532_gpio_chip *gpch;
+
+ gpch = container_of(chip, struct rb532_gpio_chip, chip);
+
+ /* disable alternate function in case it's set */
+ rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC);
+
+ rb532_set_bit(0, offset, gpch->regbase + GPIOCFG);
+ return 0;
+}
+
+/*
+ * Set GPIO direction to output
+ */
+static int rb532_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct rb532_gpio_chip *gpch;
+
+ gpch = container_of(chip, struct rb532_gpio_chip, chip);
+
+ /* disable alternate function in case it's set */
+ rb532_set_bit(0, offset, gpch->regbase + GPIOFUNC);
+
+ /* set the initial output value */
+ rb532_set_bit(value, offset, gpch->regbase + GPIOD);
+
+ rb532_set_bit(1, offset, gpch->regbase + GPIOCFG);
+ return 0;
+}
+
+static struct rb532_gpio_chip rb532_gpio_chip[] = {
+ [0] = {
+ .chip = {
+ .label = "gpio0",
+ .direction_input = rb532_gpio_direction_input,
+ .direction_output = rb532_gpio_direction_output,
+ .get = rb532_gpio_get,
+ .set = rb532_gpio_set,
+ .base = 0,
+ .ngpio = 32,
+ },
+ },
+};
+
+/*
+ * Set GPIO interrupt level
+ */
+void rb532_gpio_set_ilevel(int bit, unsigned gpio)
+{
+ rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOILEVEL);
+}
+EXPORT_SYMBOL(rb532_gpio_set_ilevel);
+
+/*
+ * Set GPIO interrupt status
+ */
+void rb532_gpio_set_istat(int bit, unsigned gpio)
+{
+ rb532_set_bit(bit, gpio, rb532_gpio_chip->regbase + GPIOISTAT);
+}
+EXPORT_SYMBOL(rb532_gpio_set_istat);
+
+/*
+ * Configure GPIO alternate function
+ */
+void rb532_gpio_set_func(unsigned gpio)
+{
+ rb532_set_bit(1, gpio, rb532_gpio_chip->regbase + GPIOFUNC);
+}
+EXPORT_SYMBOL(rb532_gpio_set_func);
+
+int __init rb532_gpio_init(void)
+{
+ struct resource *r;
+
+ r = rb532_gpio_reg0_res;
+ rb532_gpio_chip->regbase = ioremap_nocache(r->start, resource_size(r));
+
+ if (!rb532_gpio_chip->regbase) {
+ printk(KERN_ERR "rb532: cannot remap GPIO register 0\n");
+ return -ENXIO;
+ }
+
+ /* Register our GPIO chip */
+ gpiochip_add(&rb532_gpio_chip->chip);
+
+ return 0;
+}
+arch_initcall(rb532_gpio_init);
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c
new file mode 100644
index 00000000..7c6db74e
--- /dev/null
+++ b/arch/mips/rb532/irq.c
@@ -0,0 +1,236 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * stevel@mvista.com or source@mvista.com
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/mach-rc32434/irq.h>
+#include <asm/mach-rc32434/gpio.h>
+
+struct intr_group {
+ u32 mask; /* mask of valid bits in pending/mask registers */
+ volatile u32 *base_addr;
+};
+
+#define RC32434_NR_IRQS (GROUP4_IRQ_BASE + 32)
+
+#if (NR_IRQS < RC32434_NR_IRQS)
+#error Too little irqs defined. Did you override <asm/irq.h> ?
+#endif
+
+static const struct intr_group intr_group[NUM_INTR_GROUPS] = {
+ {
+ .mask = 0x0000efff,
+ .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0 * IC_GROUP_OFFSET)},
+ {
+ .mask = 0x00001fff,
+ .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 1 * IC_GROUP_OFFSET)},
+ {
+ .mask = 0x00000007,
+ .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 2 * IC_GROUP_OFFSET)},
+ {
+ .mask = 0x0003ffff,
+ .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 3 * IC_GROUP_OFFSET)},
+ {
+ .mask = 0xffffffff,
+ .base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 4 * IC_GROUP_OFFSET)}
+};
+
+#define READ_PEND(base) (*(base))
+#define READ_MASK(base) (*(base + 2))
+#define WRITE_MASK(base, val) (*(base + 2) = (val))
+
+static inline int irq_to_group(unsigned int irq_nr)
+{
+ return (irq_nr - GROUP0_IRQ_BASE) >> 5;
+}
+
+static inline int group_to_ip(unsigned int group)
+{
+ return group + 2;
+}
+
+static inline void enable_local_irq(unsigned int ip)
+{
+ int ipnum = 0x100 << ip;
+
+ set_c0_status(ipnum);
+}
+
+static inline void disable_local_irq(unsigned int ip)
+{
+ int ipnum = 0x100 << ip;
+
+ clear_c0_status(ipnum);
+}
+
+static inline void ack_local_irq(unsigned int ip)
+{
+ int ipnum = 0x100 << ip;
+
+ clear_c0_cause(ipnum);
+}
+
+static void rb532_enable_irq(struct irq_data *d)
+{
+ unsigned int group, intr_bit, irq_nr = d->irq;
+ int ip = irq_nr - GROUP0_IRQ_BASE;
+ volatile unsigned int *addr;
+
+ if (ip < 0)
+ enable_local_irq(irq_nr);
+ else {
+ group = ip >> 5;
+
+ ip &= (1 << 5) - 1;
+ intr_bit = 1 << ip;
+
+ enable_local_irq(group_to_ip(group));
+
+ addr = intr_group[group].base_addr;
+ WRITE_MASK(addr, READ_MASK(addr) & ~intr_bit);
+ }
+}
+
+static void rb532_disable_irq(struct irq_data *d)
+{
+ unsigned int group, intr_bit, mask, irq_nr = d->irq;
+ int ip = irq_nr - GROUP0_IRQ_BASE;
+ volatile unsigned int *addr;
+
+ if (ip < 0) {
+ disable_local_irq(irq_nr);
+ } else {
+ group = ip >> 5;
+
+ ip &= (1 << 5) - 1;
+ intr_bit = 1 << ip;
+ addr = intr_group[group].base_addr;
+ mask = READ_MASK(addr);
+ mask |= intr_bit;
+ WRITE_MASK(addr, mask);
+
+ /* There is a maximum of 14 GPIO interrupts */
+ if (group == GPIO_MAPPED_IRQ_GROUP && irq_nr <= (GROUP4_IRQ_BASE + 13))
+ rb532_gpio_set_istat(0, irq_nr - GPIO_MAPPED_IRQ_BASE);
+
+ /*
+ * if there are no more interrupts enabled in this
+ * group, disable corresponding IP
+ */
+ if (mask == intr_group[group].mask)
+ disable_local_irq(group_to_ip(group));
+ }
+}
+
+static void rb532_mask_and_ack_irq(struct irq_data *d)
+{
+ rb532_disable_irq(d);
+ ack_local_irq(group_to_ip(irq_to_group(d->irq)));
+}
+
+static int rb532_set_type(struct irq_data *d, unsigned type)
+{
+ int gpio = d->irq - GPIO_MAPPED_IRQ_BASE;
+ int group = irq_to_group(d->irq);
+
+ if (group != GPIO_MAPPED_IRQ_GROUP || d->irq > (GROUP4_IRQ_BASE + 13))
+ return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL;
+
+ switch (type) {
+ case IRQ_TYPE_LEVEL_HIGH:
+ rb532_gpio_set_ilevel(1, gpio);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ rb532_gpio_set_ilevel(0, gpio);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct irq_chip rc32434_irq_type = {
+ .name = "RB532",
+ .irq_ack = rb532_disable_irq,
+ .irq_mask = rb532_disable_irq,
+ .irq_mask_ack = rb532_mask_and_ack_irq,
+ .irq_unmask = rb532_enable_irq,
+ .irq_set_type = rb532_set_type,
+};
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ pr_info("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS);
+
+ for (i = 0; i < RC32434_NR_IRQS; i++)
+ irq_set_chip_and_handler(i, &rc32434_irq_type,
+ handle_level_irq);
+}
+
+/* Main Interrupt dispatcher */
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int ip, pend, group;
+ volatile unsigned int *addr;
+ unsigned int cp0_cause = read_c0_cause() & read_c0_status();
+
+ if (cp0_cause & CAUSEF_IP7) {
+ do_IRQ(7);
+ } else {
+ ip = (cp0_cause & 0x7c00);
+ if (ip) {
+ group = 21 + (fls(ip) - 32);
+
+ addr = intr_group[group].base_addr;
+
+ pend = READ_PEND(addr);
+ pend &= ~READ_MASK(addr); /* only unmasked interrupts */
+ pend = 39 + (fls(pend) - 32);
+ do_IRQ((group << 5) + pend);
+ }
+ }
+}
diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c
new file mode 100644
index 00000000..d7c26d00
--- /dev/null
+++ b/arch/mips/rb532/prom.c
@@ -0,0 +1,146 @@
+/*
+ * RouterBoard 500 specific prom routines
+ *
+ * Copyright (C) 2003, Peter Sadik <peter.sadik@idt.com>
+ * Copyright (C) 2005-2006, P.Christeas <p_christ@hol.gr>
+ * Copyright (C) 2007, Gabor Juhos <juhosg@openwrt.org>
+ * Felix Fietkau <nbd@openwrt.org>
+ * Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/console.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mach-rc32434/ddr.h>
+#include <asm/mach-rc32434/prom.h>
+
+unsigned int idt_cpu_freq = 132000000;
+EXPORT_SYMBOL(idt_cpu_freq);
+
+static struct resource ddr_reg[] = {
+ {
+ .name = "ddr-reg",
+ .start = DDR0_PHYS_ADDR,
+ .end = DDR0_PHYS_ADDR + sizeof(struct ddr_ram),
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+void __init prom_free_prom_memory(void)
+{
+ /* No prom memory to free */
+}
+
+static inline int match_tag(char *arg, const char *tag)
+{
+ return strncmp(arg, tag, strlen(tag)) == 0;
+}
+
+static inline unsigned long tag2ul(char *arg, const char *tag)
+{
+ char *num;
+
+ num = arg + strlen(tag);
+ return simple_strtoul(num, 0, 10);
+}
+
+void __init prom_setup_cmdline(void)
+{
+ static char cmd_line[COMMAND_LINE_SIZE] __initdata;
+ char *cp, *board;
+ int prom_argc;
+ char **prom_argv, **prom_envp;
+ int i;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **) fw_arg1;
+ prom_envp = (char **) fw_arg2;
+
+ cp = cmd_line;
+ /* Note: it is common that parameters start
+ * at argv[1] and not argv[0],
+ * however, our elf loader starts at [0] */
+ for (i = 0; i < prom_argc; i++) {
+ if (match_tag(prom_argv[i], FREQ_TAG)) {
+ idt_cpu_freq = tag2ul(prom_argv[i], FREQ_TAG);
+ continue;
+ }
+#ifdef IGNORE_CMDLINE_MEM
+ /* parses out the "mem=xx" arg */
+ if (match_tag(prom_argv[i], MEM_TAG))
+ continue;
+#endif
+ if (i > 0)
+ *(cp++) = ' ';
+ if (match_tag(prom_argv[i], BOARD_TAG)) {
+ board = prom_argv[i] + strlen(BOARD_TAG);
+
+ if (match_tag(board, BOARD_RB532A))
+ mips_machtype = MACH_MIKROTIK_RB532A;
+ else
+ mips_machtype = MACH_MIKROTIK_RB532;
+ }
+
+ strcpy(cp, prom_argv[i]);
+ cp += strlen(prom_argv[i]);
+ }
+ *(cp++) = ' ';
+
+ i = strlen(arcs_cmdline);
+ if (i > 0) {
+ *(cp++) = ' ';
+ strcpy(cp, arcs_cmdline);
+ cp += strlen(arcs_cmdline);
+ }
+ cmd_line[COMMAND_LINE_SIZE - 1] = '\0';
+
+ strcpy(arcs_cmdline, cmd_line);
+}
+
+void __init prom_init(void)
+{
+ struct ddr_ram __iomem *ddr;
+ phys_t memsize;
+ phys_t ddrbase;
+
+ ddr = ioremap_nocache(ddr_reg[0].start,
+ ddr_reg[0].end - ddr_reg[0].start);
+
+ if (!ddr) {
+ printk(KERN_ERR "Unable to remap DDR register\n");
+ return;
+ }
+
+ ddrbase = (phys_t)&ddr->ddrbase;
+ memsize = (phys_t)&ddr->ddrmask;
+ memsize = 0 - memsize;
+
+ prom_setup_cmdline();
+
+ /* give all RAM to boot allocator,
+ * except for the first 0x400 and the last 0x200 bytes */
+ add_memory_region(ddrbase + 0x400, memsize - 0x600, BOOT_MEM_RAM);
+}
diff --git a/arch/mips/rb532/serial.c b/arch/mips/rb532/serial.c
new file mode 100644
index 00000000..70482540
--- /dev/null
+++ b/arch/mips/rb532/serial.c
@@ -0,0 +1,54 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * Serial port initialisation.
+ *
+ * Copyright 2004 IDT Inc. (rischelp@idt.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/irq.h>
+
+#include <asm/serial.h>
+#include <asm/mach-rc32434/rb.h>
+
+extern unsigned int idt_cpu_freq;
+
+static struct uart_port rb532_uart = {
+ .flags = UPF_BOOT_AUTOCONF,
+ .line = 0,
+ .irq = UART0_IRQ,
+ .iotype = UPIO_MEM,
+ .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE),
+ .regshift = 2
+};
+
+int __init setup_serial_port(void)
+{
+ rb532_uart.uartclk = idt_cpu_freq;
+
+ return early_serial_setup(&rb532_uart);
+}
+arch_initcall(setup_serial_port);
diff --git a/arch/mips/rb532/setup.c b/arch/mips/rb532/setup.c
new file mode 100644
index 00000000..50f530f5
--- /dev/null
+++ b/arch/mips/rb532/setup.c
@@ -0,0 +1,79 @@
+/*
+ * setup.c - boot time setup code
+ */
+
+#include <linux/init.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <linux/ioport.h>
+
+#include <asm/mach-rc32434/rb.h>
+#include <asm/mach-rc32434/pci.h>
+
+struct pci_reg __iomem *pci_reg;
+EXPORT_SYMBOL(pci_reg);
+
+static struct resource pci0_res[] = {
+ {
+ .name = "pci_reg0",
+ .start = PCI0_BASE_ADDR,
+ .end = PCI0_BASE_ADDR + sizeof(struct pci_reg),
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static void rb_machine_restart(char *command)
+{
+ /* just jump to the reset vector */
+ writel(0x80000001, IDT434_REG_BASE + RST);
+ ((void (*)(void)) KSEG1ADDR(0x1FC00000u))();
+}
+
+static void rb_machine_halt(void)
+{
+ for (;;)
+ continue;
+}
+
+void __init plat_mem_setup(void)
+{
+ u32 val;
+
+ _machine_restart = rb_machine_restart;
+ _machine_halt = rb_machine_halt;
+ pm_power_off = rb_machine_halt;
+
+ set_io_port_base(KSEG1);
+
+ pci_reg = ioremap_nocache(pci0_res[0].start,
+ pci0_res[0].end - pci0_res[0].start);
+ if (!pci_reg) {
+ printk(KERN_ERR "Could not remap PCI registers\n");
+ return;
+ }
+
+ val = __raw_readl(&pci_reg->pcic);
+ val &= 0xFFFFFF7;
+ __raw_writel(val, (void *)&pci_reg->pcic);
+
+#ifdef CONFIG_PCI
+ /* Enable PCI interrupts in EPLD Mask register */
+ *epld_mask = 0x0;
+ *(epld_mask + 1) = 0x0;
+#endif
+ write_c0_wired(0);
+}
+
+const char *get_system_type(void)
+{
+ switch (mips_machtype) {
+ case MACH_MIKROTIK_RB532A:
+ return "Mikrotik RB532A";
+ break;
+ default:
+ return "Mikrotik RB532";
+ break;
+ }
+}
diff --git a/arch/mips/rb532/time.c b/arch/mips/rb532/time.c
new file mode 100644
index 00000000..1377d599
--- /dev/null
+++ b/arch/mips/rb532/time.c
@@ -0,0 +1,66 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/mc146818rtc.h>
+#include <linux/irq.h>
+#include <linux/timex.h>
+
+#include <asm/mipsregs.h>
+#include <asm/time.h>
+#include <asm/mach-rc32434/rc32434.h>
+
+extern unsigned int idt_cpu_freq;
+
+/*
+ * Figure out the r4k offset, the amount to increment the compare
+ * register for each time tick. There is no RTC available.
+ *
+ * The RC32434 counts at half the CPU *core* speed.
+ */
+static unsigned long __init cal_r4koff(void)
+{
+ mips_hpt_frequency = idt_cpu_freq * IDT_CLOCK_MULT / 2;
+
+ return mips_hpt_frequency / HZ;
+}
+
+void __init plat_time_init(void)
+{
+ unsigned int est_freq;
+ unsigned long flags, r4k_offset;
+
+ local_irq_save(flags);
+
+ printk(KERN_INFO "calculating r4koff... ");
+ r4k_offset = cal_r4koff();
+ printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
+
+ est_freq = 2 * r4k_offset * HZ;
+ est_freq += 5000; /* round */
+ est_freq -= est_freq % 10000;
+ printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
+ (est_freq % 1000000) * 100 / 1000000);
+ local_irq_restore(flags);
+}
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
new file mode 100644
index 00000000..cc538493
--- /dev/null
+++ b/arch/mips/sgi-ip22/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the SGI specific kernel interface routines
+# under Linux.
+#
+
+obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-time.o ip22-nvram.o \
+ ip22-platform.o ip22-reset.o ip22-setup.o
+
+obj-$(CONFIG_SGI_IP22) += ip22-berr.o
+obj-$(CONFIG_SGI_IP28) += ip28-berr.o
+obj-$(CONFIG_EISA) += ip22-eisa.o
diff --git a/arch/mips/sgi-ip22/Platform b/arch/mips/sgi-ip22/Platform
new file mode 100644
index 00000000..b7a4b7e0
--- /dev/null
+++ b/arch/mips/sgi-ip22/Platform
@@ -0,0 +1,34 @@
+#
+# SGI IP22 (Indy/Indigo2)
+#
+# Set the load address to >= 0xffffffff88069000 if you want to leave space for
+# symmon, 0xffffffff80002000 for production kernels. Note that the value must
+# be aligned to a multiple of the kernel stack size or the handling of the
+# current variable will break so for 64-bit kernels we have to raise the start
+# address by 8kb.
+#
+platform-$(CONFIG_SGI_IP22) += sgi-ip22/
+cflags-$(CONFIG_SGI_IP22) += -I$(srctree)/arch/mips/include/asm/mach-ip22
+ifdef CONFIG_32BIT
+load-$(CONFIG_SGI_IP22) += 0xffffffff88002000
+endif
+ifdef CONFIG_64BIT
+load-$(CONFIG_SGI_IP22) += 0xffffffff88004000
+endif
+
+#
+# SGI IP28 (Indigo2 R10k)
+#
+# Set the load address to >= 0xa800000020080000 if you want to leave space for
+# symmon, 0xa800000020004000 for production kernels ? Note that the value must
+# be 16kb aligned or the handling of the current variable will break.
+# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
+#
+ifdef CONFIG_SGI_IP28
+ ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
+ $(error gcc doesn't support needed option -mr10k-cache-barrier=store)
+ endif
+endif
+platform-$(CONFIG_SGI_IP28) += sgi-ip22/
+cflags-$(CONFIG_SGI_IP28) += -mr10k-cache-barrier=store -I$(srctree)/arch/mips/include/asm/mach-ip28
+load-$(CONFIG_SGI_IP28) += 0xa800000020004000
diff --git a/arch/mips/sgi-ip22/ip22-berr.c b/arch/mips/sgi-ip22/ip22-berr.c
new file mode 100644
index 00000000..911d3999
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-berr.c
@@ -0,0 +1,116 @@
+/*
+ * ip22-berr.c: Bus error handling.
+ *
+ * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/branch.h>
+#include <asm/irq_regs.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/ip22.h>
+
+
+static unsigned int cpu_err_stat; /* Status reg for CPU */
+static unsigned int gio_err_stat; /* Status reg for GIO */
+static unsigned int cpu_err_addr; /* Error address reg for CPU */
+static unsigned int gio_err_addr; /* Error address reg for GIO */
+static unsigned int extio_stat;
+static unsigned int hpc3_berr_stat; /* Bus error interrupt status */
+
+static void save_and_clear_buserr(void)
+{
+ /* save status registers */
+ cpu_err_addr = sgimc->cerr;
+ cpu_err_stat = sgimc->cstat;
+ gio_err_addr = sgimc->gerr;
+ gio_err_stat = sgimc->gstat;
+ extio_stat = ip22_is_fullhouse() ? sgioc->extio : (sgint->errstat << 4);
+ hpc3_berr_stat = hpc3c0->bestat;
+
+ sgimc->cstat = sgimc->gstat = 0;
+}
+
+#define GIO_ERRMASK 0xff00
+#define CPU_ERRMASK 0x3f00
+
+static void print_buserr(void)
+{
+ if (extio_stat & EXTIO_MC_BUSERR)
+ printk(KERN_ERR "MC Bus Error\n");
+ if (extio_stat & EXTIO_HPC3_BUSERR)
+ printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
+ hpc3_berr_stat,
+ (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
+ HPC3_BESTAT_PIDSHIFT,
+ (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
+ hpc3_berr_stat & HPC3_BESTAT_BLMASK);
+ if (extio_stat & EXTIO_EISA_BUSERR)
+ printk(KERN_ERR "EISA Bus Error\n");
+ if (cpu_err_stat & CPU_ERRMASK)
+ printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
+ cpu_err_stat,
+ cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
+ cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
+ cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
+ cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
+ cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
+ cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
+ cpu_err_addr);
+ if (gio_err_stat & GIO_ERRMASK)
+ printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
+ gio_err_stat,
+ gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
+ gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
+ gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
+ gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
+ gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
+ gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
+ gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
+ gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
+ gio_err_addr);
+}
+
+/*
+ * MC sends an interrupt whenever bus or parity errors occur. In addition,
+ * if the error happened during a CPU read, it also asserts the bus error
+ * pin on the R4K. Code in bus error handler save the MC bus error registers
+ * and then clear the interrupt when this happens.
+ */
+
+void ip22_be_interrupt(int irq)
+{
+ const int field = 2 * sizeof(unsigned long);
+ struct pt_regs *regs = get_irq_regs();
+
+ save_and_clear_buserr();
+ print_buserr();
+ printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
+ (regs->cp0_cause & 4) ? "Data" : "Instruction",
+ field, regs->cp0_epc, field, regs->regs[31]);
+ /* Assume it would be too dangerous to continue ... */
+ die_if_kernel("Oops", regs);
+ force_sig(SIGBUS, current);
+}
+
+static int ip22_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ save_and_clear_buserr();
+ if (is_fixup)
+ return MIPS_BE_FIXUP;
+ print_buserr();
+ return MIPS_BE_FATAL;
+}
+
+void __init ip22_be_init(void)
+{
+ board_be_handler = ip22_be_handler;
+}
diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c
new file mode 100644
index 00000000..da44ccb2
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-eisa.c
@@ -0,0 +1,147 @@
+/*
+ * Basic EISA bus support for the SGI Indigo-2.
+ *
+ * (C) 2002 Pascal Dameme <netinet@freesurf.fr>
+ * and Marc Zyngier <mzyngier@freesurf.fr>
+ *
+ * This code is released under both the GPL version 2 and BSD
+ * licenses. Either license may be used.
+ *
+ * This code offers a very basic support for this EISA bus present in
+ * the SGI Indigo-2. It currently only supports PIO (forget about DMA
+ * for the time being). This is enough for a low-end ethernet card,
+ * but forget about your favorite SCSI card...
+ *
+ * TODO :
+ * - Fix bugs...
+ * - Add ISA support
+ * - Add DMA (yeah, right...).
+ * - Fix more bugs.
+ */
+
+#include <linux/eisa.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/processor.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/ip22.h>
+#include <asm/i8259.h>
+
+/* I2 has four EISA slots. */
+#define IP22_EISA_MAX_SLOTS 4
+#define EISA_MAX_IRQ 16
+
+#define EIU_MODE_REG 0x0001ffc0
+#define EIU_STAT_REG 0x0001ffc4
+#define EIU_PREMPT_REG 0x0001ffc8
+#define EIU_QUIET_REG 0x0001ffcc
+#define EIU_INTRPT_ACK 0x00010004
+
+static char __init *decode_eisa_sig(unsigned long addr)
+{
+ static char sig_str[EISA_SIG_LEN] __initdata;
+ u8 sig[4];
+ u16 rev;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ sig[i] = inb(addr + i);
+
+ if (!i && (sig[0] & 0x80))
+ return NULL;
+ }
+
+ sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
+ sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
+ sig_str[2] = (sig[1] & 0x1f) + ('A' - 1);
+ rev = (sig[2] << 8) | sig[3];
+ sprintf(sig_str + 3, "%04X", rev);
+
+ return sig_str;
+}
+
+static irqreturn_t ip22_eisa_intr(int irq, void *dev_id)
+{
+ u8 eisa_irq;
+ u8 dma1, dma2;
+
+ eisa_irq = inb(EIU_INTRPT_ACK);
+ dma1 = inb(EISA_DMA1_STATUS);
+ dma2 = inb(EISA_DMA2_STATUS);
+
+ if (eisa_irq < EISA_MAX_IRQ) {
+ do_IRQ(eisa_irq);
+ return IRQ_HANDLED;
+ }
+
+ /* Oops, Bad Stuff Happened... */
+ printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
+
+ outb(0x20, EISA_INT2_CTRL);
+ outb(0x20, EISA_INT1_CTRL);
+
+ return IRQ_NONE;
+}
+
+static struct irqaction eisa_action = {
+ .handler = ip22_eisa_intr,
+ .name = "EISA",
+};
+
+int __init ip22_eisa_init(void)
+{
+ int i, c;
+ char *str;
+
+ if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
+ printk(KERN_INFO "EISA: bus not present.\n");
+ return 1;
+ }
+
+ printk(KERN_INFO "EISA: Probing bus...\n");
+ for (c = 0, i = 1; i <= IP22_EISA_MAX_SLOTS; i++) {
+ if ((str = decode_eisa_sig(0x1000 * i + EISA_VENDOR_ID_OFFSET))) {
+ printk(KERN_INFO "EISA: slot %d : %s detected.\n",
+ i, str);
+ c++;
+ }
+ }
+ printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s");
+#ifdef CONFIG_ISA
+ printk(KERN_INFO "ISA support compiled in.\n");
+#endif
+
+ /* Warning : BlackMagicAhead(tm).
+ Please wave your favorite dead chicken over the busses */
+
+ /* First say hello to the EIU */
+ outl(0x0000FFFF, EIU_PREMPT_REG);
+ outl(1, EIU_QUIET_REG);
+ outl(0x40f3c07F, EIU_MODE_REG);
+
+ /* Now be nice to the EISA chipset */
+ outb(1, EISA_EXT_NMI_RESET_CTRL);
+ udelay(50); /* Wait long enough for the dust to settle */
+ outb(0, EISA_EXT_NMI_RESET_CTRL);
+ outb(0, EISA_DMA2_WRITE_SINGLE);
+
+ init_i8259_irqs();
+
+ /* Cannot use request_irq because of kmalloc not being ready at such
+ * an early stage. Yes, I've been bitten... */
+ setup_irq(SGI_EISA_IRQ, &eisa_action);
+
+ EISA_bus = 1;
+ return 0;
+}
diff --git a/arch/mips/sgi-ip22/ip22-hpc.c b/arch/mips/sgi-ip22/ip22-hpc.c
new file mode 100644
index 00000000..bb70589b
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-hpc.c
@@ -0,0 +1,63 @@
+/*
+ * ip22-hpc.c: Routines for generic manipulation of the HPC controllers.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1998 Ralf Baechle
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/ip22.h>
+
+struct hpc3_regs *hpc3c0, *hpc3c1;
+
+EXPORT_SYMBOL(hpc3c0);
+EXPORT_SYMBOL(hpc3c1);
+
+struct sgioc_regs *sgioc;
+
+EXPORT_SYMBOL(sgioc);
+
+/* We need software copies of these because they are write only. */
+u8 sgi_ioc_reset, sgi_ioc_write;
+
+extern char *system_type;
+
+void __init sgihpc_init(void)
+{
+ /* ioremap can't fail */
+ hpc3c0 = (struct hpc3_regs *)
+ ioremap(HPC3_CHIP0_BASE, sizeof(struct hpc3_regs));
+ hpc3c1 = (struct hpc3_regs *)
+ ioremap(HPC3_CHIP1_BASE, sizeof(struct hpc3_regs));
+ /* IOC lives in PBUS PIO channel 6 */
+ sgioc = (struct sgioc_regs *)hpc3c0->pbus_extregs[6];
+
+ hpc3c0->pbus_piocfg[6][0] |= HPC3_PIOCFG_DS16;
+ if (ip22_is_fullhouse()) {
+ /* Full House comes with INT2 which lives in PBUS PIO
+ * channel 4 */
+ sgint = (struct sgint_regs *)hpc3c0->pbus_extregs[4];
+ system_type = "SGI Indigo2";
+ } else {
+ /* Guiness comes with INT3 which is part of IOC */
+ sgint = &sgioc->int3;
+ system_type = "SGI Indy";
+ }
+
+ sgi_ioc_reset = (SGIOC_RESET_PPORT | SGIOC_RESET_KBDMOUSE |
+ SGIOC_RESET_EISA | SGIOC_RESET_ISDN |
+ SGIOC_RESET_LC0OFF);
+
+ sgi_ioc_write = (SGIOC_WRITE_EASEL | SGIOC_WRITE_NTHRESH |
+ SGIOC_WRITE_TPSPEED | SGIOC_WRITE_EPSEL |
+ SGIOC_WRITE_U0AMODE | SGIOC_WRITE_U1AMODE);
+
+ sgioc->reset = sgi_ioc_reset;
+ sgioc->write = sgi_ioc_write;
+}
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
new file mode 100644
index 00000000..b4d08e4d
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -0,0 +1,333 @@
+/*
+ * ip22-int.c: Routines for generic manipulation of the INT[23] ASIC
+ * found on INDY and Indigo2 workstations.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
+ * - Indigo2 changes
+ * - Interrupt handling fixes
+ * Copyright (C) 2001, 2003 Ladislav Michl (ladis@linux-mips.org)
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
+#include <linux/ftrace.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+/* So far nothing hangs here */
+#undef USE_LIO3_IRQ
+
+struct sgint_regs *sgint;
+
+static char lc0msk_to_irqnr[256];
+static char lc1msk_to_irqnr[256];
+static char lc2msk_to_irqnr[256];
+static char lc3msk_to_irqnr[256];
+
+extern int ip22_eisa_init(void);
+
+static void enable_local0_irq(struct irq_data *d)
+{
+ /* don't allow mappable interrupt to be enabled from setup_irq,
+ * we have our own way to do so */
+ if (d->irq != SGI_MAP_0_IRQ)
+ sgint->imask0 |= (1 << (d->irq - SGINT_LOCAL0));
+}
+
+static void disable_local0_irq(struct irq_data *d)
+{
+ sgint->imask0 &= ~(1 << (d->irq - SGINT_LOCAL0));
+}
+
+static struct irq_chip ip22_local0_irq_type = {
+ .name = "IP22 local 0",
+ .irq_mask = disable_local0_irq,
+ .irq_unmask = enable_local0_irq,
+};
+
+static void enable_local1_irq(struct irq_data *d)
+{
+ /* don't allow mappable interrupt to be enabled from setup_irq,
+ * we have our own way to do so */
+ if (d->irq != SGI_MAP_1_IRQ)
+ sgint->imask1 |= (1 << (d->irq - SGINT_LOCAL1));
+}
+
+static void disable_local1_irq(struct irq_data *d)
+{
+ sgint->imask1 &= ~(1 << (d->irq - SGINT_LOCAL1));
+}
+
+static struct irq_chip ip22_local1_irq_type = {
+ .name = "IP22 local 1",
+ .irq_mask = disable_local1_irq,
+ .irq_unmask = enable_local1_irq,
+};
+
+static void enable_local2_irq(struct irq_data *d)
+{
+ sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
+ sgint->cmeimask0 |= (1 << (d->irq - SGINT_LOCAL2));
+}
+
+static void disable_local2_irq(struct irq_data *d)
+{
+ sgint->cmeimask0 &= ~(1 << (d->irq - SGINT_LOCAL2));
+ if (!sgint->cmeimask0)
+ sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
+}
+
+static struct irq_chip ip22_local2_irq_type = {
+ .name = "IP22 local 2",
+ .irq_mask = disable_local2_irq,
+ .irq_unmask = enable_local2_irq,
+};
+
+static void enable_local3_irq(struct irq_data *d)
+{
+ sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+ sgint->cmeimask1 |= (1 << (d->irq - SGINT_LOCAL3));
+}
+
+static void disable_local3_irq(struct irq_data *d)
+{
+ sgint->cmeimask1 &= ~(1 << (d->irq - SGINT_LOCAL3));
+ if (!sgint->cmeimask1)
+ sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+}
+
+static struct irq_chip ip22_local3_irq_type = {
+ .name = "IP22 local 3",
+ .irq_mask = disable_local3_irq,
+ .irq_unmask = enable_local3_irq,
+};
+
+static void indy_local0_irqdispatch(void)
+{
+ u8 mask = sgint->istat0 & sgint->imask0;
+ u8 mask2;
+ int irq;
+
+ if (mask & SGINT_ISTAT0_LIO2) {
+ mask2 = sgint->vmeistat & sgint->cmeimask0;
+ irq = lc2msk_to_irqnr[mask2];
+ } else
+ irq = lc0msk_to_irqnr[mask];
+
+ /* if irq == 0, then the interrupt has already been cleared */
+ if (irq)
+ do_IRQ(irq);
+}
+
+static void indy_local1_irqdispatch(void)
+{
+ u8 mask = sgint->istat1 & sgint->imask1;
+ u8 mask2;
+ int irq;
+
+ if (mask & SGINT_ISTAT1_LIO3) {
+ mask2 = sgint->vmeistat & sgint->cmeimask1;
+ irq = lc3msk_to_irqnr[mask2];
+ } else
+ irq = lc1msk_to_irqnr[mask];
+
+ /* if irq == 0, then the interrupt has already been cleared */
+ if (irq)
+ do_IRQ(irq);
+}
+
+extern void ip22_be_interrupt(int irq);
+
+static void __irq_entry indy_buserror_irq(void)
+{
+ int irq = SGI_BUSERR_IRQ;
+
+ irq_enter();
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+ ip22_be_interrupt(irq);
+ irq_exit();
+}
+
+static struct irqaction local0_cascade = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED,
+ .name = "local0 cascade",
+};
+
+static struct irqaction local1_cascade = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED,
+ .name = "local1 cascade",
+};
+
+static struct irqaction buserr = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED,
+ .name = "Bus Error",
+};
+
+static struct irqaction map0_cascade = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED,
+ .name = "mapable0 cascade",
+};
+
+#ifdef USE_LIO3_IRQ
+static struct irqaction map1_cascade = {
+ .handler = no_action,
+ .flags = IRQF_DISABLED,
+ .name = "mapable1 cascade",
+};
+#define SGI_INTERRUPTS SGINT_END
+#else
+#define SGI_INTERRUPTS SGINT_LOCAL3
+#endif
+
+extern void indy_8254timer_irq(void);
+
+/*
+ * IRQs on the INDY look basically (barring software IRQs which we don't use
+ * at all) like:
+ *
+ * MIPS IRQ Source
+ * -------- ------
+ * 0 Software (ignored)
+ * 1 Software (ignored)
+ * 2 Local IRQ level zero
+ * 3 Local IRQ level one
+ * 4 8254 Timer zero
+ * 5 8254 Timer one
+ * 6 Bus Error
+ * 7 R4k timer (what we use)
+ *
+ * We handle the IRQ according to _our_ priority which is:
+ *
+ * Highest ---- R4k Timer
+ * Local IRQ zero
+ * Local IRQ one
+ * Bus Error
+ * 8254 Timer zero
+ * Lowest ---- 8254 Timer one
+ *
+ * then we just return, if multiple IRQs are pending then we will just take
+ * another exception, big deal.
+ */
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause();
+
+ /*
+ * First we check for r4k counter/timer IRQ.
+ */
+ if (pending & CAUSEF_IP7)
+ do_IRQ(SGI_TIMER_IRQ);
+ else if (pending & CAUSEF_IP2)
+ indy_local0_irqdispatch();
+ else if (pending & CAUSEF_IP3)
+ indy_local1_irqdispatch();
+ else if (pending & CAUSEF_IP6)
+ indy_buserror_irq();
+ else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
+ indy_8254timer_irq();
+}
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ /* Init local mask --> irq tables. */
+ for (i = 0; i < 256; i++) {
+ if (i & 0x80) {
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7;
+ } else if (i & 0x40) {
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6;
+ } else if (i & 0x20) {
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5;
+ } else if (i & 0x10) {
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4;
+ } else if (i & 0x08) {
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3;
+ } else if (i & 0x04) {
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2;
+ } else if (i & 0x02) {
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1;
+ } else if (i & 0x01) {
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0;
+ } else {
+ lc0msk_to_irqnr[i] = 0;
+ lc1msk_to_irqnr[i] = 0;
+ lc2msk_to_irqnr[i] = 0;
+ lc3msk_to_irqnr[i] = 0;
+ }
+ }
+
+ /* Mask out all interrupts. */
+ sgint->imask0 = 0;
+ sgint->imask1 = 0;
+ sgint->cmeimask0 = 0;
+ sgint->cmeimask1 = 0;
+
+ /* init CPU irqs */
+ mips_cpu_irq_init();
+
+ for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) {
+ struct irq_chip *handler;
+
+ if (i < SGINT_LOCAL1)
+ handler = &ip22_local0_irq_type;
+ else if (i < SGINT_LOCAL2)
+ handler = &ip22_local1_irq_type;
+ else if (i < SGINT_LOCAL3)
+ handler = &ip22_local2_irq_type;
+ else
+ handler = &ip22_local3_irq_type;
+
+ irq_set_chip_and_handler(i, handler, handle_level_irq);
+ }
+
+ /* vector handler. this register the IRQ as non-sharable */
+ setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade);
+ setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade);
+ setup_irq(SGI_BUSERR_IRQ, &buserr);
+
+ /* cascade in cascade. i love Indy ;-) */
+ setup_irq(SGI_MAP_0_IRQ, &map0_cascade);
+#ifdef USE_LIO3_IRQ
+ setup_irq(SGI_MAP_1_IRQ, &map1_cascade);
+#endif
+
+#ifdef CONFIG_EISA
+ if (ip22_is_fullhouse()) /* Only Indigo-2 has EISA stuff */
+ ip22_eisa_init();
+#endif
+}
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
new file mode 100644
index 00000000..d22262ee
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -0,0 +1,237 @@
+/*
+ * ip22-mc.c: Routines for manipulating SGI Memory Controller.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
+ * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org)
+ * Copyright (C) 2004 Peter Fuerst (pf@net.alphadv.de) - IP28
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+struct sgimc_regs *sgimc;
+
+EXPORT_SYMBOL(sgimc);
+
+static inline unsigned long get_bank_addr(unsigned int memconfig)
+{
+ return ((memconfig & SGIMC_MCONFIG_BASEADDR) <<
+ ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22));
+}
+
+static inline unsigned long get_bank_size(unsigned int memconfig)
+{
+ return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) <<
+ ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
+}
+
+static inline unsigned int get_bank_config(int bank)
+{
+ unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0;
+ return bank % 2 ? res & 0xffff : res >> 16;
+}
+
+struct mem {
+ unsigned long addr;
+ unsigned long size;
+};
+
+/*
+ * Detect installed memory, do some sanity checks and notify kernel about it
+ */
+static void __init probe_memory(void)
+{
+ int i, j, found, cnt = 0;
+ struct mem bank[4];
+ struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}};
+
+ printk(KERN_INFO "MC: Probing memory configuration:\n");
+ for (i = 0; i < ARRAY_SIZE(bank); i++) {
+ unsigned int tmp = get_bank_config(i);
+ if (!(tmp & SGIMC_MCONFIG_BVALID))
+ continue;
+
+ bank[cnt].size = get_bank_size(tmp);
+ bank[cnt].addr = get_bank_addr(tmp);
+ printk(KERN_INFO " bank%d: %3ldM @ %08lx\n",
+ i, bank[cnt].size / 1024 / 1024, bank[cnt].addr);
+ cnt++;
+ }
+
+ /* And you thought bubble sort is dead algorithm... */
+ do {
+ unsigned long addr, size;
+
+ found = 0;
+ for (i = 1; i < cnt; i++)
+ if (bank[i-1].addr > bank[i].addr) {
+ addr = bank[i].addr;
+ size = bank[i].size;
+ bank[i].addr = bank[i-1].addr;
+ bank[i].size = bank[i-1].size;
+ bank[i-1].addr = addr;
+ bank[i-1].size = size;
+ found = 1;
+ }
+ } while (found);
+
+ /* Figure out how are memory banks mapped into spaces */
+ for (i = 0; i < cnt; i++) {
+ found = 0;
+ for (j = 0; j < ARRAY_SIZE(space) && !found; j++)
+ if (space[j].addr + space[j].size == bank[i].addr) {
+ space[j].size += bank[i].size;
+ found = 1;
+ }
+ /* There is either hole or overlapping memory */
+ if (!found)
+ printk(KERN_CRIT "MC: Memory configuration mismatch "
+ "(%08lx), expect Bus Error soon\n",
+ bank[i].addr);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(space); i++)
+ if (space[i].size)
+ add_memory_region(space[i].addr, space[i].size,
+ BOOT_MEM_RAM);
+}
+
+void __init sgimc_init(void)
+{
+ u32 tmp;
+
+ /* ioremap can't fail */
+ sgimc = (struct sgimc_regs *)
+ ioremap(SGIMC_BASE, sizeof(struct sgimc_regs));
+
+ printk(KERN_INFO "MC: SGI memory controller Revision %d\n",
+ (int) sgimc->systemid & SGIMC_SYSID_MASKREV);
+
+ /* Place the MC into a known state. This must be done before
+ * interrupts are first enabled etc.
+ */
+
+ /* Step 0: Make sure we turn off the watchdog in case it's
+ * still running (which might be the case after a
+ * soft reboot).
+ */
+ tmp = sgimc->cpuctrl0;
+ tmp &= ~SGIMC_CCTRL0_WDOG;
+ sgimc->cpuctrl0 = tmp;
+
+ /* Step 1: The CPU/GIO error status registers will not latch
+ * up a new error status until the register has been
+ * cleared by the cpu. These status registers are
+ * cleared by writing any value to them.
+ */
+ sgimc->cstat = sgimc->gstat = 0;
+
+ /* Step 2: Enable all parity checking in cpu control register
+ * zero.
+ */
+ /* don't touch parity settings for IP28 */
+#ifndef CONFIG_SGI_IP28
+ tmp = sgimc->cpuctrl0;
+ tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
+ SGIMC_CCTRL0_R4KNOCHKPARR);
+#endif
+ sgimc->cpuctrl0 = tmp;
+
+ /* Step 3: Setup the MC write buffer depth, this is controlled
+ * in cpu control register 1 in the lower 4 bits.
+ */
+ tmp = sgimc->cpuctrl1;
+ tmp &= ~0xf;
+ tmp |= 0xd;
+ sgimc->cpuctrl1 = tmp;
+
+ /* Step 4: Initialize the RPSS divider register to run as fast
+ * as it can correctly operate. The register is laid
+ * out as follows:
+ *
+ * ----------------------------------------
+ * | RESERVED | INCREMENT | DIVIDER |
+ * ----------------------------------------
+ * 31 16 15 8 7 0
+ *
+ * DIVIDER determines how often a 'tick' happens,
+ * INCREMENT determines by how the RPSS increment
+ * registers value increases at each 'tick'. Thus,
+ * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
+ */
+ sgimc->divider = 0x101;
+
+ /* Step 5: Initialize GIO64 arbitrator configuration register.
+ *
+ * NOTE: HPC init code in sgihpc_init() must run before us because
+ * we need to know Guiness vs. FullHouse and the board
+ * revision on this machine. You have been warned.
+ */
+
+ /* First the basic invariants across all GIO64 implementations. */
+ tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */
+ tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */
+
+ if (ip22_is_fullhouse()) {
+ /* Fullhouse specific settings. */
+ if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) {
+ tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */
+ tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */
+ tmp |= SGIMC_GIOPAR_MASTEREXP1; /* exp1 masters */
+ tmp |= SGIMC_GIOPAR_RTIMEEXP0; /* exp0 is realtime */
+ } else {
+ tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC 64bits */
+ tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */
+ tmp |= SGIMC_GIOPAR_PLINEEXP1;
+ tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */
+ tmp |= SGIMC_GIOPAR_GFX64; /* GFX at 64 bits */
+ }
+ } else {
+ /* Guiness specific settings. */
+ tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */
+ tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */
+ }
+ sgimc->giopar = tmp; /* poof */
+
+ probe_memory();
+}
+
+void __init prom_meminit(void) {}
+void __init prom_free_prom_memory(void)
+{
+#ifdef CONFIG_SGI_IP28
+ u32 mconfig1;
+ unsigned long flags;
+ spinlock_t lock;
+
+ /*
+ * because ARCS accesses memory uncached we wait until ARCS
+ * isn't needed any longer, before we switch from slow to
+ * normal mode
+ */
+ spin_lock_irqsave(&lock, flags);
+ mconfig1 = sgimc->mconfig1;
+ /* map ECC register */
+ sgimc->mconfig1 = (mconfig1 & 0xffff0000) | 0x2060;
+ iob();
+ /* switch to normal mode */
+ *(unsigned long *)PHYS_TO_XKSEG_UNCACHED(0x60000000) = 0;
+ iob();
+ /* reduce WR_COL */
+ sgimc->cmacc = (sgimc->cmacc & ~0xf) | 4;
+ iob();
+ /* restore old config */
+ sgimc->mconfig1 = mconfig1;
+ iob();
+ spin_unlock_irqrestore(&lock, flags);
+#endif
+}
diff --git a/arch/mips/sgi-ip22/ip22-nvram.c b/arch/mips/sgi-ip22/ip22-nvram.c
new file mode 100644
index 00000000..01775664
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-nvram.c
@@ -0,0 +1,121 @@
+/*
+ * ip22-nvram.c: NVRAM and serial EEPROM handling.
+ *
+ * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org)
+ */
+#include <linux/module.h>
+
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+/* Control opcode for serial eeprom */
+#define EEPROM_READ 0xc000 /* serial memory read */
+#define EEPROM_WEN 0x9800 /* write enable before prog modes */
+#define EEPROM_WRITE 0xa000 /* serial memory write */
+#define EEPROM_WRALL 0x8800 /* write all registers */
+#define EEPROM_WDS 0x8000 /* disable all programming */
+#define EEPROM_PRREAD 0xc000 /* read protect register */
+#define EEPROM_PREN 0x9800 /* enable protect register mode */
+#define EEPROM_PRCLEAR 0xffff /* clear protect register */
+#define EEPROM_PRWRITE 0xa000 /* write protect register */
+#define EEPROM_PRDS 0x8000 /* disable protect register, forever */
+
+#define EEPROM_EPROT 0x01 /* Protect register enable */
+#define EEPROM_CSEL 0x02 /* Chip select */
+#define EEPROM_ECLK 0x04 /* EEPROM clock */
+#define EEPROM_DATO 0x08 /* Data out */
+#define EEPROM_DATI 0x10 /* Data in */
+
+/* We need to use these functions early... */
+#define delay() ({ \
+ int x; \
+ for (x=0; x<100000; x++) __asm__ __volatile__(""); })
+
+#define eeprom_cs_on(ptr) ({ \
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_DATO, ptr); \
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_ECLK, ptr); \
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_EPROT, ptr); \
+ delay(); \
+ __raw_writel(__raw_readl(ptr) | EEPROM_CSEL, ptr); \
+ __raw_writel(__raw_readl(ptr) | EEPROM_ECLK, ptr); })
+
+
+#define eeprom_cs_off(ptr) ({ \
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_ECLK, ptr); \
+ __raw_writel(__raw_readl(ptr) & ~EEPROM_CSEL, ptr); \
+ __raw_writel(__raw_readl(ptr) | EEPROM_EPROT, ptr); \
+ __raw_writel(__raw_readl(ptr) | EEPROM_ECLK, ptr); })
+
+#define BITS_IN_COMMAND 11
+/*
+ * clock in the nvram command and the register number. For the
+ * national semiconductor nv ram chip the op code is 3 bits and
+ * the address is 6/8 bits.
+ */
+static inline void eeprom_cmd(unsigned int *ctrl, unsigned cmd, unsigned reg)
+{
+ unsigned short ser_cmd;
+ int i;
+
+ ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND));
+ for (i = 0; i < BITS_IN_COMMAND; i++) {
+ if (ser_cmd & (1<<15)) /* if high order bit set */
+ __raw_writel(__raw_readl(ctrl) | EEPROM_DATO, ctrl);
+ else
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_DATO, ctrl);
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_ECLK, ctrl);
+ delay();
+ __raw_writel(__raw_readl(ctrl) | EEPROM_ECLK, ctrl);
+ delay();
+ ser_cmd <<= 1;
+ }
+ /* see data sheet timing diagram */
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_DATO, ctrl);
+}
+
+unsigned short ip22_eeprom_read(unsigned int *ctrl, int reg)
+{
+ unsigned short res = 0;
+ int i;
+
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_EPROT, ctrl);
+ eeprom_cs_on(ctrl);
+ eeprom_cmd(ctrl, EEPROM_READ, reg);
+
+ /* clock the data ouf of serial mem */
+ for (i = 0; i < 16; i++) {
+ __raw_writel(__raw_readl(ctrl) & ~EEPROM_ECLK, ctrl);
+ delay();
+ __raw_writel(__raw_readl(ctrl) | EEPROM_ECLK, ctrl);
+ delay();
+ res <<= 1;
+ if (__raw_readl(ctrl) & EEPROM_DATI)
+ res |= 1;
+ }
+
+ eeprom_cs_off(ctrl);
+
+ return res;
+}
+
+EXPORT_SYMBOL(ip22_eeprom_read);
+
+/*
+ * Read specified register from main NVRAM
+ */
+unsigned short ip22_nvram_read(int reg)
+{
+ if (ip22_is_fullhouse())
+ /* IP22 (Indigo2 aka FullHouse) stores env variables into
+ * 93CS56 Microwire Bus EEPROM 2048 Bit (128x16) */
+ return ip22_eeprom_read(&hpc3c0->eeprom, reg);
+ else {
+ unsigned short tmp;
+ /* IP24 (Indy aka Guiness) uses DS1386 8K version */
+ reg <<= 1;
+ tmp = hpc3c0->bbram[reg++] & 0xff;
+ return (tmp << 8) | (hpc3c0->bbram[reg] & 0xff);
+ }
+}
+
+EXPORT_SYMBOL(ip22_nvram_read);
diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c
new file mode 100644
index 00000000..698904da
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-platform.c
@@ -0,0 +1,209 @@
+#include <linux/init.h>
+#include <linux/if_ether.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/paccess.h>
+#include <asm/sgi/ip22.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/seeq.h>
+#include <asm/sgi/wd.h>
+
+static struct resource sgiwd93_0_resources[] = {
+ {
+ .name = "eth0 irq",
+ .start = SGI_WD93_0_IRQ,
+ .end = SGI_WD93_0_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct sgiwd93_platform_data sgiwd93_0_pd = {
+ .unit = 0,
+ .irq = SGI_WD93_0_IRQ,
+};
+
+static struct platform_device sgiwd93_0_device = {
+ .name = "sgiwd93",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sgiwd93_0_resources),
+ .resource = sgiwd93_0_resources,
+ .dev = {
+ .platform_data = &sgiwd93_0_pd,
+ },
+};
+
+static struct resource sgiwd93_1_resources[] = {
+ {
+ .name = "eth0 irq",
+ .start = SGI_WD93_1_IRQ,
+ .end = SGI_WD93_1_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct sgiwd93_platform_data sgiwd93_1_pd = {
+ .unit = 1,
+ .irq = SGI_WD93_1_IRQ,
+};
+
+static struct platform_device sgiwd93_1_device = {
+ .name = "sgiwd93",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sgiwd93_1_resources),
+ .resource = sgiwd93_1_resources,
+ .dev = {
+ .platform_data = &sgiwd93_1_pd,
+ },
+};
+
+/*
+ * Create a platform device for the GPI port that receives the
+ * image data from the embedded camera.
+ */
+static int __init sgiwd93_devinit(void)
+{
+ int res;
+
+ sgiwd93_0_pd.hregs = &hpc3c0->scsi_chan0;
+ sgiwd93_0_pd.wdregs = (unsigned char *) hpc3c0->scsi0_ext;
+
+ res = platform_device_register(&sgiwd93_0_device);
+ if (res)
+ return res;
+
+ if (!ip22_is_fullhouse())
+ return 0;
+
+ sgiwd93_1_pd.hregs = &hpc3c0->scsi_chan1;
+ sgiwd93_1_pd.wdregs = (unsigned char *) hpc3c0->scsi1_ext;
+
+ return platform_device_register(&sgiwd93_1_device);
+}
+
+device_initcall(sgiwd93_devinit);
+
+static struct resource sgiseeq_0_resources[] = {
+ {
+ .name = "eth0 irq",
+ .start = SGI_ENET_IRQ,
+ .end = SGI_ENET_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct sgiseeq_platform_data eth0_pd;
+
+static struct platform_device eth0_device = {
+ .name = "sgiseeq",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sgiseeq_0_resources),
+ .resource = sgiseeq_0_resources,
+ .dev = {
+ .platform_data = &eth0_pd,
+ },
+};
+
+static struct resource sgiseeq_1_resources[] = {
+ {
+ .name = "eth1 irq",
+ .start = SGI_GIO_0_IRQ,
+ .end = SGI_GIO_0_IRQ,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct sgiseeq_platform_data eth1_pd;
+
+static struct platform_device eth1_device = {
+ .name = "sgiseeq",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sgiseeq_1_resources),
+ .resource = sgiseeq_1_resources,
+ .dev = {
+ .platform_data = &eth1_pd,
+ },
+};
+
+/*
+ * Create a platform device for the GPI port that receives the
+ * image data from the embedded camera.
+ */
+static int __init sgiseeq_devinit(void)
+{
+ unsigned int pbdma __maybe_unused;
+ int res, i;
+
+ eth0_pd.hpc = hpc3c0;
+ eth0_pd.irq = SGI_ENET_IRQ;
+#define EADDR_NVOFS 250
+ for (i = 0; i < 3; i++) {
+ unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i);
+
+ eth0_pd.mac[2 * i] = tmp >> 8;
+ eth0_pd.mac[2 * i + 1] = tmp & 0xff;
+ }
+
+ res = platform_device_register(&eth0_device);
+ if (res)
+ return res;
+
+ /* Second HPC is missing? */
+ if (ip22_is_fullhouse() ||
+ get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1]))
+ return 0;
+
+ sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | SGIMC_GIOPAR_EXP164 |
+ SGIMC_GIOPAR_HPC264;
+ hpc3c1->pbus_piocfg[0][0] = 0x3ffff;
+ /* interrupt/config register on Challenge S Mezz board */
+ hpc3c1->pbus_extregs[0][0] = 0x30;
+
+ eth1_pd.hpc = hpc3c1;
+ eth1_pd.irq = SGI_GIO_0_IRQ;
+#define EADDR_NVOFS 250
+ for (i = 0; i < 3; i++) {
+ unsigned short tmp = ip22_eeprom_read(&hpc3c1->eeprom,
+ EADDR_NVOFS / 2 + i);
+
+ eth1_pd.mac[2 * i] = tmp >> 8;
+ eth1_pd.mac[2 * i + 1] = tmp & 0xff;
+ }
+
+ return platform_device_register(&eth1_device);
+}
+
+device_initcall(sgiseeq_devinit);
+
+static int __init sgi_hal2_devinit(void)
+{
+ return IS_ERR(platform_device_register_simple("sgihal2", 0, NULL, 0));
+}
+
+device_initcall(sgi_hal2_devinit);
+
+static int __init sgi_button_devinit(void)
+{
+ if (ip22_is_fullhouse())
+ return 0; /* full house has no volume buttons */
+
+ return IS_ERR(platform_device_register_simple("sgibtns", -1, NULL, 0));
+}
+
+device_initcall(sgi_button_devinit);
+
+static int __init sgi_ds1286_devinit(void)
+{
+ struct resource res;
+
+ memset(&res, 0, sizeof(res));
+ res.start = HPC3_CHIP0_BASE + offsetof(struct hpc3_regs, rtcregs);
+ res.end = res.start + sizeof(hpc3c0->rtcregs) - 1;
+ res.flags = IORESOURCE_MEM;
+
+ return IS_ERR(platform_device_register_simple("rtc-ds1286", -1,
+ &res, 1));
+}
+
+device_initcall(sgi_ds1286_devinit);
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c
new file mode 100644
index 00000000..45b6694c
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-reset.c
@@ -0,0 +1,207 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997, 1998, 2001, 03, 05, 06 by Ralf Baechle
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/ds1286.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/pm.h>
+#include <linux/timer.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/reboot.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/ip22.h>
+
+/*
+ * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds.
+ * I'm not sure if this feature is a good idea, for now it's here just to
+ * make the power button make behave just like under IRIX.
+ */
+#define POWERDOWN_TIMEOUT 120
+
+/*
+ * Blink frequency during reboot grace period and when panicked.
+ */
+#define POWERDOWN_FREQ (HZ / 4)
+#define PANIC_FREQ (HZ / 8)
+
+static struct timer_list power_timer, blink_timer, debounce_timer;
+
+#define MACHINE_PANICED 1
+#define MACHINE_SHUTTING_DOWN 2
+
+static int machine_state;
+
+static void __noreturn sgi_machine_power_off(void)
+{
+ unsigned int tmp;
+
+ local_irq_disable();
+
+ /* Disable watchdog */
+ tmp = hpc3c0->rtcregs[RTC_CMD] & 0xff;
+ hpc3c0->rtcregs[RTC_CMD] = tmp | RTC_WAM;
+ hpc3c0->rtcregs[RTC_WSEC] = 0;
+ hpc3c0->rtcregs[RTC_WHSEC] = 0;
+
+ while (1) {
+ sgioc->panel = ~SGIOC_PANEL_POWERON;
+ /* Good bye cruel world ... */
+
+ /* If we're still running, we probably got sent an alarm
+ interrupt. Read the flag to clear it. */
+ tmp = hpc3c0->rtcregs[RTC_HOURS_ALARM];
+ }
+}
+
+static void __noreturn sgi_machine_restart(char *command)
+{
+ if (machine_state & MACHINE_SHUTTING_DOWN)
+ sgi_machine_power_off();
+ sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT;
+ while (1);
+}
+
+static void __noreturn sgi_machine_halt(void)
+{
+ if (machine_state & MACHINE_SHUTTING_DOWN)
+ sgi_machine_power_off();
+ ArcEnterInteractiveMode();
+}
+
+static void power_timeout(unsigned long data)
+{
+ sgi_machine_power_off();
+}
+
+static void blink_timeout(unsigned long data)
+{
+ /* XXX fix this for fullhouse */
+ sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF);
+ sgioc->reset = sgi_ioc_reset;
+
+ mod_timer(&blink_timer, jiffies + data);
+}
+
+static void debounce(unsigned long data)
+{
+ del_timer(&debounce_timer);
+ if (sgint->istat1 & SGINT_ISTAT1_PWR) {
+ /* Interrupt still being sent. */
+ debounce_timer.expires = jiffies + (HZ / 20); /* 0.05s */
+ add_timer(&debounce_timer);
+
+ sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR |
+ SGIOC_PANEL_VOLDNINTR | SGIOC_PANEL_VOLDNHOLD |
+ SGIOC_PANEL_VOLUPINTR | SGIOC_PANEL_VOLUPHOLD;
+
+ return;
+ }
+
+ if (machine_state & MACHINE_PANICED)
+ sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT;
+
+ enable_irq(SGI_PANEL_IRQ);
+}
+
+static inline void power_button(void)
+{
+ if (machine_state & MACHINE_PANICED)
+ return;
+
+ if ((machine_state & MACHINE_SHUTTING_DOWN) ||
+ kill_cad_pid(SIGINT, 1)) {
+ /* No init process or button pressed twice. */
+ sgi_machine_power_off();
+ }
+
+ machine_state |= MACHINE_SHUTTING_DOWN;
+ blink_timer.data = POWERDOWN_FREQ;
+ blink_timeout(POWERDOWN_FREQ);
+
+ init_timer(&power_timer);
+ power_timer.function = power_timeout;
+ power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
+ add_timer(&power_timer);
+}
+
+static irqreturn_t panel_int(int irq, void *dev_id)
+{
+ unsigned int buttons;
+
+ buttons = sgioc->panel;
+ sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR;
+
+ if (sgint->istat1 & SGINT_ISTAT1_PWR) {
+ /* Wait until interrupt goes away */
+ disable_irq_nosync(SGI_PANEL_IRQ);
+ init_timer(&debounce_timer);
+ debounce_timer.function = debounce;
+ debounce_timer.expires = jiffies + 5;
+ add_timer(&debounce_timer);
+ }
+
+ /* Power button was pressed
+ * ioc.ps page 22: "The Panel Register is called Power Control by Full
+ * House. Only lowest 2 bits are used. Guiness uses upper four bits
+ * for volume control". This is not true, all bits are pulled high
+ * on fullhouse */
+ if (!(buttons & SGIOC_PANEL_POWERINTR))
+ power_button();
+
+ return IRQ_HANDLED;
+}
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
+{
+ if (machine_state & MACHINE_PANICED)
+ return NOTIFY_DONE;
+ machine_state |= MACHINE_PANICED;
+
+ blink_timer.data = PANIC_FREQ;
+ blink_timeout(PANIC_FREQ);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+ .notifier_call = panic_event,
+};
+
+static int __init reboot_setup(void)
+{
+ int res;
+
+ _machine_restart = sgi_machine_restart;
+ _machine_halt = sgi_machine_halt;
+ pm_power_off = sgi_machine_power_off;
+
+ res = request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL);
+ if (res) {
+ printk(KERN_ERR "Allocation of front panel IRQ failed\n");
+ return res;
+ }
+
+ init_timer(&blink_timer);
+ blink_timer.function = blink_timeout;
+ atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+
+ return 0;
+}
+
+subsys_initcall(reboot_setup);
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
new file mode 100644
index 00000000..5e662134
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -0,0 +1,99 @@
+/*
+ * ip22-setup.c: SGI specific setup, including init of the feature struct.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+
+#include <asm/addrspace.h>
+#include <asm/bcache.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/traps.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+unsigned long sgi_gfxaddr;
+EXPORT_SYMBOL_GPL(sgi_gfxaddr);
+
+extern void ip22_be_init(void) __init;
+
+void __init plat_mem_setup(void)
+{
+ char *ctype;
+ char *cserial;
+
+ board_be_init = ip22_be_init;
+
+ /* Init the INDY HPC I/O controller. Need to call this before
+ * fucking with the memory controller because it needs to know the
+ * boardID and whether this is a Guiness or a FullHouse machine.
+ */
+ sgihpc_init();
+
+ /* Init INDY memory controller. */
+ sgimc_init();
+
+#ifdef CONFIG_BOARD_SCACHE
+ /* Now enable boardcaches, if any. */
+ indy_sc_init();
+#endif
+
+ /* Set EISA IO port base for Indigo2
+ * ioremap cannot fail */
+ set_io_port_base((unsigned long)ioremap(0x00080000,
+ 0x1fffffff - 0x00080000));
+ /* ARCS console environment variable is set to "g?" for
+ * graphics console, it is set to "d" for the first serial
+ * line and "d2" for the second serial line.
+ *
+ * Need to check if the case is 'g' but no keyboard:
+ * (ConsoleIn/Out = serial)
+ */
+ ctype = ArcGetEnvironmentVariable("console");
+ cserial = ArcGetEnvironmentVariable("ConsoleOut");
+
+ if ((ctype && *ctype == 'd') || (cserial && *cserial == 's')) {
+ static char options[8] __initdata;
+ char *baud = ArcGetEnvironmentVariable("dbaud");
+ if (baud)
+ strcpy(options, baud);
+ add_preferred_console("ttyS", *(ctype + 1) == '2' ? 1 : 0,
+ baud ? options : NULL);
+ } else if (!ctype || *ctype != 'g') {
+ /* Use ARC if we don't want serial ('d') or graphics ('g'). */
+ prom_flags |= PROM_FLAG_USE_AS_CONSOLE;
+ add_preferred_console("arc", 0, NULL);
+ }
+
+#if defined(CONFIG_VT) && defined(CONFIG_SGI_NEWPORT_CONSOLE)
+ {
+ ULONG *gfxinfo;
+ ULONG * (*__vec)(void) = (void *) (long)
+ *((_PULONG *)(long)((PROMBLOCK)->pvector + 0x20));
+
+ gfxinfo = __vec();
+ sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000
+ && gfxinfo[1] <= 0xc0000000)
+ ? gfxinfo[1] - 0xa0000000 : 0);
+
+ /* newport addresses? */
+ if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) {
+ conswitchp = &newport_con;
+ }
+ }
+#endif
+}
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
new file mode 100644
index 00000000..1a94c989
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -0,0 +1,131 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Time operations for IP22 machines. Original code may come from
+ * Ralf Baechle or David S. Miller (sorry guys, i'm really not sure)
+ *
+ * Copyright (C) 2001 by Ladislav Michl
+ * Copyright (C) 2003, 06 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/time.h>
+#include <linux/ftrace.h>
+
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/i8253.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/time.h>
+#include <asm/sgialib.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
+
+static unsigned long dosample(void)
+{
+ u32 ct0, ct1;
+ u8 msb;
+
+ /* Start the counter. */
+ sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL |
+ SGINT_TCWORD_MRGEN);
+ sgint->tcnt2 = SGINT_TCSAMP_COUNTER & 0xff;
+ sgint->tcnt2 = SGINT_TCSAMP_COUNTER >> 8;
+
+ /* Get initial counter invariant */
+ ct0 = read_c0_count();
+
+ /* Latch and spin until top byte of counter2 is zero */
+ do {
+ writeb(SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT, &sgint->tcword);
+ (void) readb(&sgint->tcnt2);
+ msb = readb(&sgint->tcnt2);
+ ct1 = read_c0_count();
+ } while (msb);
+
+ /* Stop the counter. */
+ writeb(SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST,
+ &sgint->tcword);
+ /*
+ * Return the difference, this is how far the r4k counter increments
+ * for every 1/HZ seconds. We round off the nearest 1 MHz of master
+ * clock (= 1000000 / HZ / 2).
+ */
+
+ return (ct1 - ct0) / (500000/HZ) * (500000/HZ);
+}
+
+/*
+ * Here we need to calibrate the cycle counter to at least be close.
+ */
+__init void plat_time_init(void)
+{
+ unsigned long r4k_ticks[3];
+ unsigned long r4k_tick;
+
+ /*
+ * Figure out the r4k offset, the algorithm is very simple and works in
+ * _all_ cases as long as the 8254 counter register itself works ok (as
+ * an interrupt driving timer it does not because of bug, this is why
+ * we are using the onchip r4k counter/compare register to serve this
+ * purpose, but for r4k_offset calculation it will work ok for us).
+ * There are other very complicated ways of performing this calculation
+ * but this one works just fine so I am not going to futz around. ;-)
+ */
+ printk(KERN_INFO "Calibrating system timer... ");
+ dosample(); /* Prime cache. */
+ dosample(); /* Prime cache. */
+ /* Zero is NOT an option. */
+ do {
+ r4k_ticks[0] = dosample();
+ } while (!r4k_ticks[0]);
+ do {
+ r4k_ticks[1] = dosample();
+ } while (!r4k_ticks[1]);
+
+ if (r4k_ticks[0] != r4k_ticks[1]) {
+ printk("warning: timer counts differ, retrying... ");
+ r4k_ticks[2] = dosample();
+ if (r4k_ticks[2] == r4k_ticks[0]
+ || r4k_ticks[2] == r4k_ticks[1])
+ r4k_tick = r4k_ticks[2];
+ else {
+ printk("disagreement, using average... ");
+ r4k_tick = (r4k_ticks[0] + r4k_ticks[1]
+ + r4k_ticks[2]) / 3;
+ }
+ } else
+ r4k_tick = r4k_ticks[0];
+
+ printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick,
+ (int) (r4k_tick / (500000 / HZ)),
+ (int) (r4k_tick % (500000 / HZ)));
+
+ mips_hpt_frequency = r4k_tick * HZ;
+
+ if (ip22_is_fullhouse())
+ setup_pit_timer();
+}
+
+/* Generic SGI handler for (spurious) 8254 interrupts */
+void __irq_entry indy_8254timer_irq(void)
+{
+ int irq = SGI_8254_0_IRQ;
+ ULONG cnt;
+ char c;
+
+ irq_enter();
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+ printk(KERN_ALERT "Oops, got 8254 interrupt.\n");
+ ArcRead(0, &c, 1, &cnt);
+ ArcEnterInteractiveMode();
+ irq_exit();
+}
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
new file mode 100644
index 00000000..88c684e0
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -0,0 +1,502 @@
+/*
+ * ip28-berr.c: Bus error handling.
+ *
+ * Copyright (C) 2002, 2003 Ladislav Michl (ladis@linux-mips.org)
+ * Copyright (C) 2005 Peter Fuerst (pf@net.alphadv.de) - IP28
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+
+#include <asm/addrspace.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/branch.h>
+#include <asm/irq_regs.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/ip22.h>
+#include <asm/r4kcache.h>
+#include <asm/uaccess.h>
+#include <asm/bootinfo.h>
+
+static unsigned int count_be_is_fixup;
+static unsigned int count_be_handler;
+static unsigned int count_be_interrupt;
+static int debug_be_interrupt;
+
+static unsigned int cpu_err_stat; /* Status reg for CPU */
+static unsigned int gio_err_stat; /* Status reg for GIO */
+static unsigned int cpu_err_addr; /* Error address reg for CPU */
+static unsigned int gio_err_addr; /* Error address reg for GIO */
+static unsigned int extio_stat;
+static unsigned int hpc3_berr_stat; /* Bus error interrupt status */
+
+struct hpc3_stat {
+ unsigned long addr;
+ unsigned int ctrl;
+ unsigned int cbp;
+ unsigned int ndptr;
+};
+
+static struct {
+ struct hpc3_stat pbdma[8];
+ struct hpc3_stat scsi[2];
+ struct hpc3_stat ethrx, ethtx;
+} hpc3;
+
+static struct {
+ unsigned long err_addr;
+ struct {
+ u32 lo;
+ u32 hi;
+ } tags[1][2], tagd[4][2], tagi[4][2]; /* Way 0/1 */
+} cache_tags;
+
+static inline void save_cache_tags(unsigned busaddr)
+{
+ unsigned long addr = CAC_BASE | busaddr;
+ int i;
+ cache_tags.err_addr = addr;
+
+ /*
+ * Starting with a bus-address, save secondary cache (indexed by
+ * PA[23..18:7..6]) tags first.
+ */
+ addr &= ~1L;
+#define tag cache_tags.tags[0]
+ cache_op(Index_Load_Tag_S, addr);
+ tag[0].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */
+ tag[0].hi = read_c0_taghi(); /* PA[39:36] */
+ cache_op(Index_Load_Tag_S, addr | 1L);
+ tag[1].lo = read_c0_taglo(); /* PA[35:18], VA[13:12] */
+ tag[1].hi = read_c0_taghi(); /* PA[39:36] */
+#undef tag
+
+ /*
+ * Save all primary data cache (indexed by VA[13:5]) tags which
+ * might fit to this bus-address, knowing that VA[11:0] == PA[11:0].
+ * Saving all tags and evaluating them later is easier and safer
+ * than relying on VA[13:12] from the secondary cache tags to pick
+ * matching primary tags here already.
+ */
+ addr &= (0xffL << 56) | ((1 << 12) - 1);
+#define tag cache_tags.tagd[i]
+ for (i = 0; i < 4; ++i, addr += (1 << 12)) {
+ cache_op(Index_Load_Tag_D, addr);
+ tag[0].lo = read_c0_taglo(); /* PA[35:12] */
+ tag[0].hi = read_c0_taghi(); /* PA[39:36] */
+ cache_op(Index_Load_Tag_D, addr | 1L);
+ tag[1].lo = read_c0_taglo(); /* PA[35:12] */
+ tag[1].hi = read_c0_taghi(); /* PA[39:36] */
+ }
+#undef tag
+
+ /*
+ * Save primary instruction cache (indexed by VA[13:6]) tags
+ * the same way.
+ */
+ addr &= (0xffL << 56) | ((1 << 12) - 1);
+#define tag cache_tags.tagi[i]
+ for (i = 0; i < 4; ++i, addr += (1 << 12)) {
+ cache_op(Index_Load_Tag_I, addr);
+ tag[0].lo = read_c0_taglo(); /* PA[35:12] */
+ tag[0].hi = read_c0_taghi(); /* PA[39:36] */
+ cache_op(Index_Load_Tag_I, addr | 1L);
+ tag[1].lo = read_c0_taglo(); /* PA[35:12] */
+ tag[1].hi = read_c0_taghi(); /* PA[39:36] */
+ }
+#undef tag
+}
+
+#define GIO_ERRMASK 0xff00
+#define CPU_ERRMASK 0x3f00
+
+static void save_and_clear_buserr(void)
+{
+ int i;
+
+ /* save status registers */
+ cpu_err_addr = sgimc->cerr;
+ cpu_err_stat = sgimc->cstat;
+ gio_err_addr = sgimc->gerr;
+ gio_err_stat = sgimc->gstat;
+ extio_stat = sgioc->extio;
+ hpc3_berr_stat = hpc3c0->bestat;
+
+ hpc3.scsi[0].addr = (unsigned long)&hpc3c0->scsi_chan0;
+ hpc3.scsi[0].ctrl = hpc3c0->scsi_chan0.ctrl; /* HPC3_SCTRL_ACTIVE ? */
+ hpc3.scsi[0].cbp = hpc3c0->scsi_chan0.cbptr;
+ hpc3.scsi[0].ndptr = hpc3c0->scsi_chan0.ndptr;
+
+ hpc3.scsi[1].addr = (unsigned long)&hpc3c0->scsi_chan1;
+ hpc3.scsi[1].ctrl = hpc3c0->scsi_chan1.ctrl; /* HPC3_SCTRL_ACTIVE ? */
+ hpc3.scsi[1].cbp = hpc3c0->scsi_chan1.cbptr;
+ hpc3.scsi[1].ndptr = hpc3c0->scsi_chan1.ndptr;
+
+ hpc3.ethrx.addr = (unsigned long)&hpc3c0->ethregs.rx_cbptr;
+ hpc3.ethrx.ctrl = hpc3c0->ethregs.rx_ctrl; /* HPC3_ERXCTRL_ACTIVE ? */
+ hpc3.ethrx.cbp = hpc3c0->ethregs.rx_cbptr;
+ hpc3.ethrx.ndptr = hpc3c0->ethregs.rx_ndptr;
+
+ hpc3.ethtx.addr = (unsigned long)&hpc3c0->ethregs.tx_cbptr;
+ hpc3.ethtx.ctrl = hpc3c0->ethregs.tx_ctrl; /* HPC3_ETXCTRL_ACTIVE ? */
+ hpc3.ethtx.cbp = hpc3c0->ethregs.tx_cbptr;
+ hpc3.ethtx.ndptr = hpc3c0->ethregs.tx_ndptr;
+
+ for (i = 0; i < 8; ++i) {
+ /* HPC3_PDMACTRL_ISACT ? */
+ hpc3.pbdma[i].addr = (unsigned long)&hpc3c0->pbdma[i];
+ hpc3.pbdma[i].ctrl = hpc3c0->pbdma[i].pbdma_ctrl;
+ hpc3.pbdma[i].cbp = hpc3c0->pbdma[i].pbdma_bptr;
+ hpc3.pbdma[i].ndptr = hpc3c0->pbdma[i].pbdma_dptr;
+ }
+ i = 0;
+ if (gio_err_stat & CPU_ERRMASK)
+ i = gio_err_addr;
+ if (cpu_err_stat & CPU_ERRMASK)
+ i = cpu_err_addr;
+ save_cache_tags(i);
+
+ sgimc->cstat = sgimc->gstat = 0;
+}
+
+static void print_cache_tags(void)
+{
+ u32 scb, scw;
+ int i;
+
+ printk(KERN_ERR "Cache tags @ %08x:\n", (unsigned)cache_tags.err_addr);
+
+ /* PA[31:12] shifted to PTag0 (PA[35:12]) format */
+ scw = (cache_tags.err_addr >> 4) & 0x0fffff00;
+
+ scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 5) - 1);
+ for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
+ if ((cache_tags.tagd[i][0].lo & 0x0fffff00) != scw &&
+ (cache_tags.tagd[i][1].lo & 0x0fffff00) != scw)
+ continue;
+ printk(KERN_ERR
+ "D: 0: %08x %08x, 1: %08x %08x (VA[13:5] %04x)\n",
+ cache_tags.tagd[i][0].hi, cache_tags.tagd[i][0].lo,
+ cache_tags.tagd[i][1].hi, cache_tags.tagd[i][1].lo,
+ scb | (1 << 12)*i);
+ }
+ scb = cache_tags.err_addr & ((1 << 12) - 1) & ~((1 << 6) - 1);
+ for (i = 0; i < 4; ++i) { /* for each possible VA[13:12] value */
+ if ((cache_tags.tagi[i][0].lo & 0x0fffff00) != scw &&
+ (cache_tags.tagi[i][1].lo & 0x0fffff00) != scw)
+ continue;
+ printk(KERN_ERR
+ "I: 0: %08x %08x, 1: %08x %08x (VA[13:6] %04x)\n",
+ cache_tags.tagi[i][0].hi, cache_tags.tagi[i][0].lo,
+ cache_tags.tagi[i][1].hi, cache_tags.tagi[i][1].lo,
+ scb | (1 << 12)*i);
+ }
+ i = read_c0_config();
+ scb = i & (1 << 13) ? 7:6; /* scblksize = 2^[7..6] */
+ scw = ((i >> 16) & 7) + 19 - 1; /* scwaysize = 2^[24..19] / 2 */
+
+ i = ((1 << scw) - 1) & ~((1 << scb) - 1);
+ printk(KERN_ERR "S: 0: %08x %08x, 1: %08x %08x (PA[%u:%u] %05x)\n",
+ cache_tags.tags[0][0].hi, cache_tags.tags[0][0].lo,
+ cache_tags.tags[0][1].hi, cache_tags.tags[0][1].lo,
+ scw-1, scb, i & (unsigned)cache_tags.err_addr);
+}
+
+static inline const char *cause_excode_text(int cause)
+{
+ static const char *txt[32] =
+ { "Interrupt",
+ "TLB modification",
+ "TLB (load or instruction fetch)",
+ "TLB (store)",
+ "Address error (load or instruction fetch)",
+ "Address error (store)",
+ "Bus error (instruction fetch)",
+ "Bus error (data: load or store)",
+ "Syscall",
+ "Breakpoint",
+ "Reserved instruction",
+ "Coprocessor unusable",
+ "Arithmetic Overflow",
+ "Trap",
+ "14",
+ "Floating-Point",
+ "16", "17", "18", "19", "20", "21", "22",
+ "Watch Hi/Lo",
+ "24", "25", "26", "27", "28", "29", "30", "31",
+ };
+ return txt[(cause & 0x7c) >> 2];
+}
+
+static void print_buserr(const struct pt_regs *regs)
+{
+ const int field = 2 * sizeof(unsigned long);
+ int error = 0;
+
+ if (extio_stat & EXTIO_MC_BUSERR) {
+ printk(KERN_ERR "MC Bus Error\n");
+ error |= 1;
+ }
+ if (extio_stat & EXTIO_HPC3_BUSERR) {
+ printk(KERN_ERR "HPC3 Bus Error 0x%x:<id=0x%x,%s,lane=0x%x>\n",
+ hpc3_berr_stat,
+ (hpc3_berr_stat & HPC3_BESTAT_PIDMASK) >>
+ HPC3_BESTAT_PIDSHIFT,
+ (hpc3_berr_stat & HPC3_BESTAT_CTYPE) ? "PIO" : "DMA",
+ hpc3_berr_stat & HPC3_BESTAT_BLMASK);
+ error |= 2;
+ }
+ if (extio_stat & EXTIO_EISA_BUSERR) {
+ printk(KERN_ERR "EISA Bus Error\n");
+ error |= 4;
+ }
+ if (cpu_err_stat & CPU_ERRMASK) {
+ printk(KERN_ERR "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n",
+ cpu_err_stat,
+ cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "",
+ cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "",
+ cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "",
+ cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "",
+ cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "",
+ cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "",
+ cpu_err_addr);
+ error |= 8;
+ }
+ if (gio_err_stat & GIO_ERRMASK) {
+ printk(KERN_ERR "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x%08x\n",
+ gio_err_stat,
+ gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "",
+ gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "",
+ gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "",
+ gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "",
+ gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "",
+ gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "",
+ gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "",
+ gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "",
+ gio_err_addr);
+ error |= 16;
+ }
+ if (!error)
+ printk(KERN_ERR "MC: Hmm, didn't find any error condition.\n");
+ else {
+ printk(KERN_ERR "CP0: config %08x, "
+ "MC: cpuctrl0/1: %08x/%05x, giopar: %04x\n"
+ "MC: cpu/gio_memacc: %08x/%05x, memcfg0/1: %08x/%08x\n",
+ read_c0_config(),
+ sgimc->cpuctrl0, sgimc->cpuctrl0, sgimc->giopar,
+ sgimc->cmacc, sgimc->gmacc,
+ sgimc->mconfig0, sgimc->mconfig1);
+ print_cache_tags();
+ }
+ printk(KERN_ALERT "%s, epc == %0*lx, ra == %0*lx\n",
+ cause_excode_text(regs->cp0_cause),
+ field, regs->cp0_epc, field, regs->regs[31]);
+}
+
+/*
+ * Check, whether MC's (virtual) DMA address caused the bus error.
+ * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
+ */
+
+static int addr_is_ram(unsigned long addr, unsigned sz)
+{
+ int i;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ unsigned long a = boot_mem_map.map[i].addr;
+ if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size)
+ return 1;
+ }
+ return 0;
+}
+
+static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
+{
+ /* This is likely rather similar to correct code ;-) */
+
+ vaddr &= 0x7fffffff; /* Doc. states that top bit is ignored */
+
+ /* If tlb-entry is valid and VPN-high (bits [30:21] ?) matches... */
+ if ((lo & 2) && (vaddr >> 21) == ((hi<<1) >> 22)) {
+ u32 ctl = sgimc->dma_ctrl;
+ if (ctl & 1) {
+ unsigned int pgsz = (ctl & 2) ? 14:12; /* 16k:4k */
+ /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
+ unsigned long pte = (lo >> 6) << 12; /* PTEBase */
+ pte += 8*((vaddr >> pgsz) & 0x1ff);
+ if (addr_is_ram(pte, 8)) {
+ /*
+ * Note: Since DMA hardware does look up
+ * translation on its own, this PTE *must*
+ * match the TLB/EntryLo-register format !
+ */
+ unsigned long a = *(unsigned long *)
+ PHYS_TO_XKSEG_UNCACHED(pte);
+ a = (a & 0x3f) << 6; /* PFN */
+ a += vaddr & ((1 << pgsz) - 1);
+ return (cpu_err_addr == a);
+ }
+ }
+ }
+ return 0;
+}
+
+static int check_vdma_memaddr(void)
+{
+ if (cpu_err_stat & CPU_ERRMASK) {
+ u32 a = sgimc->maddronly;
+
+ if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */
+ return (cpu_err_addr == a);
+
+ if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
+ check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
+ check_microtlb(sgimc->dtlb_hi2, sgimc->dtlb_lo2, a) ||
+ check_microtlb(sgimc->dtlb_hi3, sgimc->dtlb_lo3, a))
+ return 1;
+ }
+ return 0;
+}
+
+static int check_vdma_gioaddr(void)
+{
+ if (gio_err_stat & GIO_ERRMASK) {
+ u32 a = sgimc->gio_dma_trans;
+ a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
+ return (gio_err_addr == a);
+ }
+ return 0;
+}
+
+/*
+ * MC sends an interrupt whenever bus or parity errors occur. In addition,
+ * if the error happened during a CPU read, it also asserts the bus error
+ * pin on the R4K. Code in bus error handler save the MC bus error registers
+ * and then clear the interrupt when this happens.
+ */
+
+static int ip28_be_interrupt(const struct pt_regs *regs)
+{
+ int i;
+
+ save_and_clear_buserr();
+ /*
+ * Try to find out, whether we got here by a mispredicted speculative
+ * load/store operation. If so, it's not fatal, we can go on.
+ */
+ /* Any cause other than "Interrupt" (ExcCode 0) is fatal. */
+ if (regs->cp0_cause & CAUSEF_EXCCODE)
+ goto mips_be_fatal;
+
+ /* Any cause other than "Bus error interrupt" (IP6) is weird. */
+ if ((regs->cp0_cause & CAUSEF_IP6) != CAUSEF_IP6)
+ goto mips_be_fatal;
+
+ if (extio_stat & (EXTIO_HPC3_BUSERR | EXTIO_EISA_BUSERR))
+ goto mips_be_fatal;
+
+ /* Any state other than "Memory bus error" is fatal. */
+ if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
+ goto mips_be_fatal;
+
+ /* GIO errors other than timeouts are fatal */
+ if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
+ goto mips_be_fatal;
+
+ /*
+ * Now we have an asynchronous bus error, speculatively or DMA caused.
+ * Need to search all DMA descriptors for the error address.
+ */
+ for (i = 0; i < sizeof(hpc3)/sizeof(struct hpc3_stat); ++i) {
+ struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
+ if ((cpu_err_stat & CPU_ERRMASK) &&
+ (cpu_err_addr == hp->ndptr || cpu_err_addr == hp->cbp))
+ break;
+ if ((gio_err_stat & GIO_ERRMASK) &&
+ (gio_err_addr == hp->ndptr || gio_err_addr == hp->cbp))
+ break;
+ }
+ if (i < sizeof(hpc3)/sizeof(struct hpc3_stat)) {
+ struct hpc3_stat *hp = (struct hpc3_stat *)&hpc3 + i;
+ printk(KERN_ERR "at DMA addresses: HPC3 @ %08lx:"
+ " ctl %08x, ndp %08x, cbp %08x\n",
+ CPHYSADDR(hp->addr), hp->ctrl, hp->ndptr, hp->cbp);
+ goto mips_be_fatal;
+ }
+ /* Check MC's virtual DMA stuff. */
+ if (check_vdma_memaddr()) {
+ printk(KERN_ERR "at GIO DMA: mem address 0x%08x.\n",
+ sgimc->maddronly);
+ goto mips_be_fatal;
+ }
+ if (check_vdma_gioaddr()) {
+ printk(KERN_ERR "at GIO DMA: gio address 0x%08x.\n",
+ sgimc->gmaddronly);
+ goto mips_be_fatal;
+ }
+ /* A speculative bus error... */
+ if (debug_be_interrupt) {
+ print_buserr(regs);
+ printk(KERN_ERR "discarded!\n");
+ }
+ return MIPS_BE_DISCARD;
+
+mips_be_fatal:
+ print_buserr(regs);
+ return MIPS_BE_FATAL;
+}
+
+void ip22_be_interrupt(int irq)
+{
+ struct pt_regs *regs = get_irq_regs();
+
+ count_be_interrupt++;
+
+ if (ip28_be_interrupt(regs) != MIPS_BE_DISCARD) {
+ /* Assume it would be too dangerous to continue ... */
+ die_if_kernel("Oops", regs);
+ force_sig(SIGBUS, current);
+ } else if (debug_be_interrupt)
+ show_regs((struct pt_regs *)regs);
+}
+
+static int ip28_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ /*
+ * We arrive here only in the unusual case of do_be() invocation,
+ * i.e. by a bus error exception without a bus error interrupt.
+ */
+ if (is_fixup) {
+ count_be_is_fixup++;
+ save_and_clear_buserr();
+ return MIPS_BE_FIXUP;
+ }
+ count_be_handler++;
+ return ip28_be_interrupt(regs);
+}
+
+void __init ip22_be_init(void)
+{
+ board_be_handler = ip28_be_handler;
+}
+
+int ip28_show_be_info(struct seq_file *m)
+{
+ seq_printf(m, "IP28 be fixups\t\t: %u\n", count_be_is_fixup);
+ seq_printf(m, "IP28 be interrupts\t: %u\n", count_be_interrupt);
+ seq_printf(m, "IP28 be handler\t\t: %u\n", count_be_handler);
+
+ return 0;
+}
+
+static int __init debug_be_setup(char *str)
+{
+ debug_be_interrupt++;
+ return 1;
+}
+__setup("ip28_debug_be", debug_be_setup);
diff --git a/arch/mips/sgi-ip27/Kconfig b/arch/mips/sgi-ip27/Kconfig
new file mode 100644
index 00000000..bc5e9769
--- /dev/null
+++ b/arch/mips/sgi-ip27/Kconfig
@@ -0,0 +1,53 @@
+#config SGI_SN0_XXL
+# bool "IP27 XXL"
+# depends on SGI_IP27
+# This options adds support for userspace processes up to 16TB size.
+# Normally the limit is just .5TB.
+
+choice
+ prompt "Node addressing mode"
+ depends on SGI_IP27
+ default SGI_SN_M_MODE
+
+config SGI_SN_M_MODE
+ bool "IP27 M-Mode"
+ help
+ The nodes of Origin, Onyx, Fuel and Tezro systems can be configured
+ in either N-Modes which allows for more nodes or M-Mode which allows
+ for more memory. Your hardware is almost certainly running in
+ M-Mode, so choose M-mode here.
+
+config SGI_SN_N_MODE
+ bool "IP27 N-Mode"
+ depends on EXPERIMENTAL
+ help
+ The nodes of Origin, Onyx, Fuel and Tezro systems can be configured
+ in either N-Modes which allows for more nodes or M-Mode which allows
+ for more memory. Your hardware is almost certainly running in
+ M-Mode, so choose M-mode here.
+
+endchoice
+
+config MAPPED_KERNEL
+ bool "Mapped kernel support"
+ depends on SGI_IP27
+ help
+ Change the way a Linux kernel is loaded into memory on a MIPS64
+ machine. This is required in order to support text replication on
+ NUMA. If you need to understand it, read the source code.
+
+config REPLICATE_KTEXT
+ bool "Kernel text replication support"
+ depends on SGI_IP27
+ select MAPPED_KERNEL
+ help
+ Say Y here to enable replicating the kernel text across multiple
+ nodes in a NUMA cluster. This trades memory for speed.
+
+config REPLICATE_EXHANDLERS
+ bool "Exception handler replication support"
+ depends on SGI_IP27
+ help
+ Say Y here to enable replicating the kernel exception handlers
+ across multiple nodes in a NUMA cluster. This trades memory for
+ speed.
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile
new file mode 100644
index 00000000..1f29e761
--- /dev/null
+++ b/arch/mips/sgi-ip27/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the IP27 specific kernel interface routines under Linux.
+#
+
+obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o ip27-klnuma.o \
+ ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o ip27-hubio.o \
+ ip27-xtalk.o
+
+obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o
+obj-$(CONFIG_SMP) += ip27-smp.o
diff --git a/arch/mips/sgi-ip27/Platform b/arch/mips/sgi-ip27/Platform
new file mode 100644
index 00000000..1fb9c2ea
--- /dev/null
+++ b/arch/mips/sgi-ip27/Platform
@@ -0,0 +1,19 @@
+#
+# SGI-IP27 (Origin200/2000)
+#
+# Set the load address to >= 0xc000000000300000 if you want to leave space for
+# symmon, 0xc00000000001c000 for production kernels. Note that the value must
+# be 16kb aligned or the handling of the current variable will break.
+#
+ifdef CONFIG_SGI_IP27
+platform-$(CONFIG_SGI_IP27) += sgi-ip27/
+cflags-$(CONFIG_SGI_IP27) += -I$(srctree)/arch/mips/include/asm/mach-ip27
+ifdef CONFIG_MAPPED_KERNEL
+load-$(CONFIG_SGI_IP27) += 0xc00000004001c000
+OBJCOPYFLAGS := --change-addresses=0x3fffffff80000000
+dataoffset-$(CONFIG_SGI_IP27) += 0x01000000
+else
+load-$(CONFIG_SGI_IP27) += 0xa80000000001c000
+OBJCOPYFLAGS := --change-addresses=0x57ffffff80000000
+endif
+endif
diff --git a/arch/mips/sgi-ip27/TODO b/arch/mips/sgi-ip27/TODO
new file mode 100644
index 00000000..160857ff
--- /dev/null
+++ b/arch/mips/sgi-ip27/TODO
@@ -0,0 +1,19 @@
+1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay
+not to write to the IOC3 ever.
+2. Need to figure out RRB allocation in bridge_startup().
+3. Need to figure out why address swaizzling is needed in inw/outw for
+Qlogic scsi controllers.
+4. Need to integrate ip27-klconfig.c:find_lboard and
+ip27-init.c:find_lbaord_real. DONE
+5. Is it okay to set calias space on all nodes as 0, instead of 8k as
+in irix?
+6. Investigate why things do not work without the setup_test() call
+being invoked on all nodes in ip27-memory.c.
+8. Too many do_page_faults invoked - investigate.
+9. start_thread must turn off UX64 ... and define tlb_refill_debug.
+10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
+does not agree with pgd_bad/pmd_bad.
+11. All intrs (ip27_do_irq handlers) are targeted at cpu A on the node.
+This might need to change later. Only the timer intr is set up to be
+received on both Cpu A and B. (ip27_do_irq()/bridge_startup())
+13. Cache flushing (specially the SMP version) has to be investigated.
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
new file mode 100644
index 00000000..04cebadc
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-berr.c
@@ -0,0 +1,93 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/signal.h> /* for SIGBUS */
+#include <linux/sched.h> /* schow_regs(), force_sig() */
+
+#include <asm/module.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/tlbdebug.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+static void dump_hub_information(unsigned long errst0, unsigned long errst1)
+{
+ static char *err_type[2][8] = {
+ { NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout",
+ NULL, NULL, NULL, NULL },
+ { "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
+ NULL, NULL, NULL, NULL }
+ };
+ int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK;
+
+ if (!(errst0 & PI_ERR_ST0_VALID_MASK)) {
+ printk("Hub does not contain valid error information\n");
+ return;
+ }
+
+
+ printk("Hub has valid error information:\n");
+ if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
+ printk("Overrun is set. Error stack may contain additional "
+ "information.\n");
+ printk("Hub error address is %08lx\n",
+ (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3));
+ printk("Incoming message command 0x%lx\n",
+ (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT);
+ printk("Supplemental field of incoming message is 0x%lx\n",
+ (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT);
+ printk("T5 Rn (for RRB only) is 0x%lx\n",
+ (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT);
+ printk("Error type is %s\n", err_type[wrb]
+ [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT]
+ ? : "invalid");
+}
+
+int ip27_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ unsigned long errst0, errst1;
+ int data = regs->cp0_cause & 4;
+ int cpu = LOCAL_HUB_L(PI_CPU_NUM);
+
+ if (is_fixup)
+ return MIPS_BE_FIXUP;
+
+ printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
+ regs->cp0_epc);
+ printk("Hub information:\n");
+ printk("ERR_INT_PEND = 0x%06llx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
+ errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
+ errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
+ dump_hub_information(errst0, errst1);
+ show_regs(regs);
+ dump_tlb_all();
+ while(1);
+ force_sig(SIGBUS, current);
+}
+
+void __init ip27_be_init(void)
+{
+ /* XXX Initialize all the Hub & Bridge error handling here. */
+ int cpu = LOCAL_HUB_L(PI_CPU_NUM);
+ int cpuoff = cpu << 8;
+
+ board_be_handler = ip27_be_handler;
+
+ LOCAL_HUB_S(PI_ERR_INT_PEND,
+ cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A);
+ LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0);
+ LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0);
+ LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0); /* Disable error stack */
+ LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL);
+}
diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c
new file mode 100644
index 00000000..984e561f
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-console.c
@@ -0,0 +1,40 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001, 2002 Ralf Baechle
+ */
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/hub.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/sn_private.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#define IOC3_CLK (22000000 / 3)
+#define IOC3_FLAGS (0)
+
+static inline struct ioc3_uartregs *console_uart(void)
+{
+ struct ioc3 *ioc3;
+ nasid_t nasid;
+
+ nasid = (master_nasid == INVALID_NASID) ? get_nasid() : master_nasid;
+ ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(nasid)->memory_base;
+
+ return &ioc3->sregs.uarta;
+}
+
+void __init prom_putchar(char c)
+{
+ struct ioc3_uartregs *uart = console_uart();
+
+ while ((uart->iu_lsr & 0x20) == 0);
+ uart->iu_thr = c;
+}
diff --git a/arch/mips/sgi-ip27/ip27-hubio.c b/arch/mips/sgi-ip27/ip27-hubio.c
new file mode 100644
index 00000000..cd0d5b06
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-hubio.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.
+ * Copyright (C) 2004 Christoph Hellwig.
+ * Released under GPL v2.
+ *
+ * Support functions for the HUB ASIC - mostly PIO mapping related.
+ */
+
+#include <linux/bitops.h>
+#include <linux/string.h>
+#include <linux/mmzone.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/hub.h>
+
+
+static int force_fire_and_forget = 1;
+
+/**
+ * hub_pio_map - establish a HUB PIO mapping
+ *
+ * @hub: hub to perform PIO mapping on
+ * @widget: widget ID to perform PIO mapping for
+ * @xtalk_addr: xtalk_address that needs to be mapped
+ * @size: size of the PIO mapping
+ *
+ **/
+unsigned long hub_pio_map(cnodeid_t cnode, xwidgetnum_t widget,
+ unsigned long xtalk_addr, size_t size)
+{
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+ unsigned i;
+
+ /* use small-window mapping if possible */
+ if ((xtalk_addr % SWIN_SIZE) + size <= SWIN_SIZE)
+ return NODE_SWIN_BASE(nasid, widget) + (xtalk_addr % SWIN_SIZE);
+
+ if ((xtalk_addr % BWIN_SIZE) + size > BWIN_SIZE) {
+ printk(KERN_WARNING "PIO mapping at hub %d widget %d addr 0x%lx"
+ " too big (%ld)\n",
+ nasid, widget, xtalk_addr, size);
+ return 0;
+ }
+
+ xtalk_addr &= ~(BWIN_SIZE-1);
+ for (i = 0; i < HUB_NUM_BIG_WINDOW; i++) {
+ if (test_and_set_bit(i, hub_data(cnode)->h_bigwin_used))
+ continue;
+
+ /*
+ * The code below does a PIO write to setup an ITTE entry.
+ *
+ * We need to prevent other CPUs from seeing our updated
+ * memory shadow of the ITTE (in the piomap) until the ITTE
+ * entry is actually set up; otherwise, another CPU might
+ * attempt a PIO prematurely.
+ *
+ * Also, the only way we can know that an entry has been
+ * received by the hub and can be used by future PIO reads/
+ * writes is by reading back the ITTE entry after writing it.
+ *
+ * For these two reasons, we PIO read back the ITTE entry
+ * after we write it.
+ */
+ IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr);
+ (void) HUB_L(IIO_ITTE_GET(nasid, i));
+
+ return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE);
+ }
+
+ printk(KERN_WARNING "unable to establish PIO mapping for at"
+ " hub %d widget %d addr 0x%lx\n",
+ nasid, widget, xtalk_addr);
+ return 0;
+}
+
+
+/*
+ * hub_setup_prb(nasid, prbnum, credits, conveyor)
+ *
+ * Put a PRB into fire-and-forget mode if conveyor isn't set. Otherwise,
+ * put it into conveyor belt mode with the specified number of credits.
+ */
+static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
+{
+ iprb_t prb;
+ int prb_offset;
+
+ /*
+ * Get the current register value.
+ */
+ prb_offset = IIO_IOPRB(prbnum);
+ prb.iprb_regval = REMOTE_HUB_L(nasid, prb_offset);
+
+ /*
+ * Clear out some fields.
+ */
+ prb.iprb_ovflow = 1;
+ prb.iprb_bnakctr = 0;
+ prb.iprb_anakctr = 0;
+
+ /*
+ * Enable or disable fire-and-forget mode.
+ */
+ prb.iprb_ff = force_fire_and_forget ? 1 : 0;
+
+ /*
+ * Set the appropriate number of PIO cresits for the widget.
+ */
+ prb.iprb_xtalkctr = credits;
+
+ /*
+ * Store the new value to the register.
+ */
+ REMOTE_HUB_S(nasid, prb_offset, prb.iprb_regval);
+}
+
+/**
+ * hub_set_piomode - set pio mode for a given hub
+ *
+ * @nasid: physical node ID for the hub in question
+ *
+ * Put the hub into either "PIO conveyor belt" mode or "fire-and-forget" mode.
+ * To do this, we have to make absolutely sure that no PIOs are in progress
+ * so we turn off access to all widgets for the duration of the function.
+ *
+ * XXX - This code should really check what kind of widget we're talking
+ * to. Bridges can only handle three requests, but XG will do more.
+ * How many can crossbow handle to widget 0? We're assuming 1.
+ *
+ * XXX - There is a bug in the crossbow that link reset PIOs do not
+ * return write responses. The easiest solution to this problem is to
+ * leave widget 0 (xbow) in fire-and-forget mode at all times. This
+ * only affects pio's to xbow registers, which should be rare.
+ **/
+static void hub_set_piomode(nasid_t nasid)
+{
+ hubreg_t ii_iowa;
+ hubii_wcr_t ii_wcr;
+ unsigned i;
+
+ ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
+ REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0);
+
+ ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid, IIO_WCR);
+
+ if (ii_wcr.iwcr_dir_con) {
+ /*
+ * Assume a bridge here.
+ */
+ hub_setup_prb(nasid, 0, 3);
+ } else {
+ /*
+ * Assume a crossbow here.
+ */
+ hub_setup_prb(nasid, 0, 1);
+ }
+
+ /*
+ * XXX - Here's where we should take the widget type into
+ * when account assigning credits.
+ */
+ for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++)
+ hub_setup_prb(nasid, i, 3);
+
+ REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
+}
+
+/*
+ * hub_pio_init - PIO-related hub initialization
+ *
+ * @hub: hubinfo structure for our hub
+ */
+void hub_pio_init(cnodeid_t cnode)
+{
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+ unsigned i;
+
+ /* initialize big window piomaps for this hub */
+ bitmap_zero(hub_data(cnode)->h_bigwin_used, HUB_NUM_BIG_WINDOW);
+ for (i = 0; i < HUB_NUM_BIG_WINDOW; i++)
+ IIO_ITTE_DISABLE(nasid, i);
+
+ hub_set_piomode(nasid);
+}
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
new file mode 100644
index 00000000..923c080f
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -0,0 +1,221 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/cpumask.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/time.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/ioc3.h>
+#include <asm/mipsregs.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/intr.h>
+#include <asm/current.h>
+#include <asm/processor.h>
+#include <asm/mmu_context.h>
+#include <asm/thread_info.h>
+#include <asm/sn/launch.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/mapped_kernel.h>
+
+#define CPU_NONE (cpuid_t)-1
+
+static DECLARE_BITMAP(hub_init_mask, MAX_COMPACT_NODES);
+nasid_t master_nasid = INVALID_NASID;
+
+cnodeid_t nasid_to_compact_node[MAX_NASIDS];
+nasid_t compact_to_nasid_node[MAX_COMPACT_NODES];
+cnodeid_t cpuid_to_compact_node[MAXCPUS];
+
+EXPORT_SYMBOL(nasid_to_compact_node);
+
+struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
+EXPORT_SYMBOL_GPL(sn_cpu_info);
+
+extern void pcibr_setup(cnodeid_t);
+
+extern void xtalk_probe_node(cnodeid_t nid);
+
+static void __cpuinit per_hub_init(cnodeid_t cnode)
+{
+ struct hub_data *hub = hub_data(cnode);
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+ int i;
+
+ cpu_set(smp_processor_id(), hub->h_cpus);
+
+ if (test_and_set_bit(cnode, hub_init_mask))
+ return;
+ /*
+ * Set CRB timeout at 5ms, (< PI timeout of 10ms)
+ */
+ REMOTE_HUB_S(nasid, IIO_ICTP, 0x800);
+ REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+
+ hub_rtc_init(cnode);
+ xtalk_probe_node(cnode);
+
+#ifdef CONFIG_REPLICATE_EXHANDLERS
+ /*
+ * If this is not a headless node initialization,
+ * copy over the caliased exception handlers.
+ */
+ if (get_compact_nodeid() == cnode) {
+ extern char except_vec2_generic, except_vec3_generic;
+ extern void build_tlb_refill_handler(void);
+
+ memcpy((void *)(CKSEG0 + 0x100), &except_vec2_generic, 0x80);
+ memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x80);
+ build_tlb_refill_handler();
+ memcpy((void *)(CKSEG0 + 0x100), (void *) CKSEG0, 0x80);
+ memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x100);
+ __flush_cache_all();
+ }
+#endif
+
+ /*
+ * Some interrupts are reserved by hardware or by software convention.
+ * Mark these as reserved right away so they won't be used accidentally
+ * later.
+ */
+ for (i = 0; i <= BASE_PCI_IRQ; i++) {
+ __set_bit(i, hub->irq_alloc_mask);
+ LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
+ }
+
+ __set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
+ LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
+
+ for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
+ __set_bit(i, hub->irq_alloc_mask);
+ LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
+ }
+}
+
+void __cpuinit per_cpu_init(void)
+{
+ int cpu = smp_processor_id();
+ int slice = LOCAL_HUB_L(PI_CPU_NUM);
+ cnodeid_t cnode = get_compact_nodeid();
+ struct hub_data *hub = hub_data(cnode);
+ struct slice_data *si = hub->slice + slice;
+ int i;
+
+ if (test_and_set_bit(slice, &hub->slice_map))
+ return;
+
+ clear_c0_status(ST0_IM);
+
+ per_hub_init(cnode);
+
+ for (i = 0; i < LEVELS_PER_SLICE; i++)
+ si->level_to_irq[i] = -1;
+
+ /*
+ * We use this so we can find the local hub's data as fast as only
+ * possible.
+ */
+ cpu_data[cpu].data = si;
+
+ cpu_time_init();
+ install_ipi();
+
+ /* Install our NMI handler if symmon hasn't installed one. */
+ install_cpu_nmi_handler(cputoslice(cpu));
+
+ set_c0_status(SRB_DEV0 | SRB_DEV1);
+}
+
+/*
+ * get_nasid() returns the physical node id number of the caller.
+ */
+nasid_t
+get_nasid(void)
+{
+ return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
+ >> NSRI_NODEID_SHFT);
+}
+
+/*
+ * Map the physical node id to a virtual node id (virtual node ids are contiguous).
+ */
+cnodeid_t get_compact_nodeid(void)
+{
+ return NASID_TO_COMPACT_NODEID(get_nasid());
+}
+
+static inline void ioc3_eth_init(void)
+{
+ struct ioc3 *ioc3;
+ nasid_t nid;
+
+ nid = get_nasid();
+ ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
+
+ ioc3->eier = 0;
+}
+
+extern void ip27_reboot_setup(void);
+
+void __init plat_mem_setup(void)
+{
+ hubreg_t p, e, n_mode;
+ nasid_t nid;
+
+ ip27_reboot_setup();
+
+ /*
+ * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
+ */
+ nid = get_nasid();
+ printk("IP27: Running on node %d.\n", nid);
+
+ p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
+ e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
+ printk("Node %d has %s primary CPU%s.\n", nid,
+ p ? "a" : "no",
+ e ? ", CPU is running" : "");
+
+ p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
+ e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
+ printk("Node %d has %s secondary CPU%s.\n", nid,
+ p ? "a" : "no",
+ e ? ", CPU is running" : "");
+
+ /*
+ * Try to catch kernel missconfigurations and give user an
+ * indication what option to select.
+ */
+ n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
+ printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
+#ifdef CONFIG_SGI_SN_N_MODE
+ if (!n_mode)
+ panic("Kernel compiled for M mode.");
+#else
+ if (n_mode)
+ panic("Kernel compiled for N mode.");
+#endif
+
+ ioc3_eth_init();
+ per_cpu_init();
+
+ set_io_port_base(IO_BASE);
+}
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
new file mode 100644
index 00000000..b18b04e4
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -0,0 +1,423 @@
+/*
+ * ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
+ *
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1999 - 2001 Kanoj Sarcar
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/smp.h>
+#include <linux/random.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/processor.h>
+#include <asm/pci/bridge.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/agent.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/intr.h>
+
+/*
+ * Linux has a controller-independent x86 interrupt architecture.
+ * every controller has a 'controller-template', that is used
+ * by the main code to do the right thing. Each driver-visible
+ * interrupt source is transparently wired to the appropriate
+ * controller. Thus drivers need not be aware of the
+ * interrupt-controller.
+ *
+ * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
+ * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
+ * (IO-APICs assumed to be messaging to Pentium local-APICs)
+ *
+ * the code is designed to be easily extended with new/different
+ * interrupt controllers, without having to do assembly magic.
+ */
+
+extern asmlinkage void ip27_irq(void);
+
+extern struct bridge_controller *irq_to_bridge[];
+extern int irq_to_slot[];
+
+/*
+ * use these macros to get the encoded nasid and widget id
+ * from the irq value
+ */
+#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)]
+#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i]
+
+static inline int alloc_level(int cpu, int irq)
+{
+ struct hub_data *hub = hub_data(cpu_to_node(cpu));
+ struct slice_data *si = cpu_data[cpu].data;
+ int level;
+
+ level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
+ if (level >= LEVELS_PER_SLICE)
+ panic("Cpu %d flooded with devices\n", cpu);
+
+ __set_bit(level, hub->irq_alloc_mask);
+ si->level_to_irq[level] = irq;
+
+ return level;
+}
+
+static inline int find_level(cpuid_t *cpunum, int irq)
+{
+ int cpu, i;
+
+ for_each_online_cpu(cpu) {
+ struct slice_data *si = cpu_data[cpu].data;
+
+ for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
+ if (si->level_to_irq[i] == irq) {
+ *cpunum = cpu;
+
+ return i;
+ }
+ }
+
+ panic("Could not identify cpu/level for irq %d\n", irq);
+}
+
+/*
+ * Find first bit set
+ */
+static int ms1bit(unsigned long x)
+{
+ int b = 0, s;
+
+ s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s;
+ s = 8; if (x >> 8 == 0) s = 0; b += s; x >>= s;
+ s = 4; if (x >> 4 == 0) s = 0; b += s; x >>= s;
+ s = 2; if (x >> 2 == 0) s = 0; b += s; x >>= s;
+ s = 1; if (x >> 1 == 0) s = 0; b += s;
+
+ return b;
+}
+
+/*
+ * This code is unnecessarily complex, because we do IRQF_DISABLED
+ * intr enabling. Basically, once we grab the set of intrs we need
+ * to service, we must mask _all_ these interrupts; firstly, to make
+ * sure the same intr does not intr again, causing recursion that
+ * can lead to stack overflow. Secondly, we can not just mask the
+ * one intr we are do_IRQing, because the non-masked intrs in the
+ * first set might intr again, causing multiple servicings of the
+ * same intr. This effect is mostly seen for intercpu intrs.
+ * Kanoj 05.13.00
+ */
+
+static void ip27_do_irq_mask0(void)
+{
+ int irq, swlevel;
+ hubreg_t pend0, mask0;
+ cpuid_t cpu = smp_processor_id();
+ int pi_int_mask0 =
+ (cputoslice(cpu) == 0) ? PI_INT_MASK0_A : PI_INT_MASK0_B;
+
+ /* copied from Irix intpend0() */
+ pend0 = LOCAL_HUB_L(PI_INT_PEND0);
+ mask0 = LOCAL_HUB_L(pi_int_mask0);
+
+ pend0 &= mask0; /* Pick intrs we should look at */
+ if (!pend0)
+ return;
+
+ swlevel = ms1bit(pend0);
+#ifdef CONFIG_SMP
+ if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) {
+ LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
+ scheduler_ipi();
+ } else if (pend0 & (1UL << CPU_RESCHED_B_IRQ)) {
+ LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ);
+ scheduler_ipi();
+ } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) {
+ LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
+ smp_call_function_interrupt();
+ } else if (pend0 & (1UL << CPU_CALL_B_IRQ)) {
+ LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ);
+ smp_call_function_interrupt();
+ } else
+#endif
+ {
+ /* "map" swlevel to irq */
+ struct slice_data *si = cpu_data[cpu].data;
+
+ irq = si->level_to_irq[swlevel];
+ do_IRQ(irq);
+ }
+
+ LOCAL_HUB_L(PI_INT_PEND0);
+}
+
+static void ip27_do_irq_mask1(void)
+{
+ int irq, swlevel;
+ hubreg_t pend1, mask1;
+ cpuid_t cpu = smp_processor_id();
+ int pi_int_mask1 = (cputoslice(cpu) == 0) ? PI_INT_MASK1_A : PI_INT_MASK1_B;
+ struct slice_data *si = cpu_data[cpu].data;
+
+ /* copied from Irix intpend0() */
+ pend1 = LOCAL_HUB_L(PI_INT_PEND1);
+ mask1 = LOCAL_HUB_L(pi_int_mask1);
+
+ pend1 &= mask1; /* Pick intrs we should look at */
+ if (!pend1)
+ return;
+
+ swlevel = ms1bit(pend1);
+ /* "map" swlevel to irq */
+ irq = si->level_to_irq[swlevel];
+ LOCAL_HUB_CLR_INTR(swlevel);
+ do_IRQ(irq);
+
+ LOCAL_HUB_L(PI_INT_PEND1);
+}
+
+static void ip27_prof_timer(void)
+{
+ panic("CPU %d got a profiling interrupt", smp_processor_id());
+}
+
+static void ip27_hub_error(void)
+{
+ panic("CPU %d got a hub error interrupt", smp_processor_id());
+}
+
+static int intr_connect_level(int cpu, int bit)
+{
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+ struct slice_data *si = cpu_data[cpu].data;
+
+ set_bit(bit, si->irq_enable_mask);
+
+ if (!cputoslice(cpu)) {
+ REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
+ REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
+ } else {
+ REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
+ REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
+ }
+
+ return 0;
+}
+
+static int intr_disconnect_level(int cpu, int bit)
+{
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+ struct slice_data *si = cpu_data[cpu].data;
+
+ clear_bit(bit, si->irq_enable_mask);
+
+ if (!cputoslice(cpu)) {
+ REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]);
+ REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]);
+ } else {
+ REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]);
+ REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]);
+ }
+
+ return 0;
+}
+
+/* Startup one of the (PCI ...) IRQs routes over a bridge. */
+static unsigned int startup_bridge_irq(struct irq_data *d)
+{
+ struct bridge_controller *bc;
+ bridgereg_t device;
+ bridge_t *bridge;
+ int pin, swlevel;
+ cpuid_t cpu;
+
+ pin = SLOT_FROM_PCI_IRQ(d->irq);
+ bc = IRQ_TO_BRIDGE(d->irq);
+ bridge = bc->base;
+
+ pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin);
+ /*
+ * "map" irq to a swlevel greater than 6 since the first 6 bits
+ * of INT_PEND0 are taken
+ */
+ swlevel = find_level(&cpu, d->irq);
+ bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8));
+ bridge->b_int_enable |= (1 << pin);
+ bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */
+
+ /*
+ * Enable sending of an interrupt clear packt to the hub on a high to
+ * low transition of the interrupt pin.
+ *
+ * IRIX sets additional bits in the address which are documented as
+ * reserved in the bridge docs.
+ */
+ bridge->b_int_mode |= (1UL << pin);
+
+ /*
+ * We assume the bridge to have a 1:1 mapping between devices
+ * (slots) and intr pins.
+ */
+ device = bridge->b_int_device;
+ device &= ~(7 << (pin*3));
+ device |= (pin << (pin*3));
+ bridge->b_int_device = device;
+
+ bridge->b_wid_tflush;
+
+ intr_connect_level(cpu, swlevel);
+
+ return 0; /* Never anything pending. */
+}
+
+/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */
+static void shutdown_bridge_irq(struct irq_data *d)
+{
+ struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq);
+ bridge_t *bridge = bc->base;
+ int pin, swlevel;
+ cpuid_t cpu;
+
+ pr_debug("bridge_shutdown: irq 0x%x\n", d->irq);
+ pin = SLOT_FROM_PCI_IRQ(d->irq);
+
+ /*
+ * map irq to a swlevel greater than 6 since the first 6 bits
+ * of INT_PEND0 are taken
+ */
+ swlevel = find_level(&cpu, d->irq);
+ intr_disconnect_level(cpu, swlevel);
+
+ bridge->b_int_enable &= ~(1 << pin);
+ bridge->b_wid_tflush;
+}
+
+static inline void enable_bridge_irq(struct irq_data *d)
+{
+ cpuid_t cpu;
+ int swlevel;
+
+ swlevel = find_level(&cpu, d->irq); /* Criminal offence */
+ intr_connect_level(cpu, swlevel);
+}
+
+static inline void disable_bridge_irq(struct irq_data *d)
+{
+ cpuid_t cpu;
+ int swlevel;
+
+ swlevel = find_level(&cpu, d->irq); /* Criminal offence */
+ intr_disconnect_level(cpu, swlevel);
+}
+
+static struct irq_chip bridge_irq_type = {
+ .name = "bridge",
+ .irq_startup = startup_bridge_irq,
+ .irq_shutdown = shutdown_bridge_irq,
+ .irq_mask = disable_bridge_irq,
+ .irq_unmask = enable_bridge_irq,
+};
+
+void __devinit register_bridge_irq(unsigned int irq)
+{
+ irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
+}
+
+int __devinit request_bridge_irq(struct bridge_controller *bc)
+{
+ int irq = allocate_irqno();
+ int swlevel, cpu;
+ nasid_t nasid;
+
+ if (irq < 0)
+ return irq;
+
+ /*
+ * "map" irq to a swlevel greater than 6 since the first 6 bits
+ * of INT_PEND0 are taken
+ */
+ cpu = bc->irq_cpu;
+ swlevel = alloc_level(cpu, irq);
+ if (unlikely(swlevel < 0)) {
+ free_irqno(irq);
+
+ return -EAGAIN;
+ }
+
+ /* Make sure it's not already pending when we connect it. */
+ nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu));
+ REMOTE_HUB_CLR_INTR(nasid, swlevel);
+
+ intr_connect_level(cpu, swlevel);
+
+ register_bridge_irq(irq);
+
+ return irq;
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long pending = read_c0_cause() & read_c0_status();
+ extern unsigned int rt_timer_irq;
+
+ if (pending & CAUSEF_IP4)
+ do_IRQ(rt_timer_irq);
+ else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */
+ ip27_do_irq_mask0();
+ else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */
+ ip27_do_irq_mask1();
+ else if (pending & CAUSEF_IP5)
+ ip27_prof_timer();
+ else if (pending & CAUSEF_IP6)
+ ip27_hub_error();
+}
+
+void __init arch_init_irq(void)
+{
+}
+
+void install_ipi(void)
+{
+ int slice = LOCAL_HUB_L(PI_CPU_NUM);
+ int cpu = smp_processor_id();
+ struct slice_data *si = cpu_data[cpu].data;
+ struct hub_data *hub = hub_data(cpu_to_node(cpu));
+ int resched, call;
+
+ resched = CPU_RESCHED_A_IRQ + slice;
+ __set_bit(resched, hub->irq_alloc_mask);
+ __set_bit(resched, si->irq_enable_mask);
+ LOCAL_HUB_CLR_INTR(resched);
+
+ call = CPU_CALL_A_IRQ + slice;
+ __set_bit(call, hub->irq_alloc_mask);
+ __set_bit(call, si->irq_enable_mask);
+ LOCAL_HUB_CLR_INTR(call);
+
+ if (slice == 0) {
+ LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]);
+ LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]);
+ } else {
+ LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]);
+ LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]);
+ }
+}
diff --git a/arch/mips/sgi-ip27/ip27-klconfig.c b/arch/mips/sgi-ip27/ip27-klconfig.c
new file mode 100644
index 00000000..7afe1468
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-klconfig.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+
+klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
+{
+ int index, j;
+
+ if (kli == (klinfo_t *)NULL) {
+ index = 0;
+ } else {
+ for (j = 0; j < KLCF_NUM_COMPS(brd); j++)
+ if (kli == KLCF_COMP(brd, j))
+ break;
+ index = j;
+ if (index == KLCF_NUM_COMPS(brd)) {
+ printk("find_component: Bad pointer: 0x%p\n", kli);
+ return (klinfo_t *)NULL;
+ }
+ index++; /* next component */
+ }
+
+ for (; index < KLCF_NUM_COMPS(brd); index++) {
+ kli = KLCF_COMP(brd, index);
+ if (KLCF_COMP_TYPE(kli) == struct_type)
+ return kli;
+ }
+
+ /* Didn't find it. */
+ return (klinfo_t *)NULL;
+}
+
+klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
+{
+ return find_component(brd, (klinfo_t *)NULL, struct_type);
+}
+
+lboard_t *find_lboard(lboard_t *start, unsigned char brd_type)
+{
+ /* Search all boards stored on this node. */
+ while (start) {
+ if (start->brd_type == brd_type)
+ return start;
+ start = KLCF_NEXT(start);
+ }
+ /* Didn't find it. */
+ return (lboard_t *)NULL;
+}
+
+lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_type)
+{
+ /* Search all boards stored on this node. */
+ while (start) {
+ if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
+ return start;
+ start = KLCF_NEXT(start);
+ }
+
+ /* Didn't find it. */
+ return (lboard_t *)NULL;
+}
+
+cnodeid_t get_cpu_cnode(cpuid_t cpu)
+{
+ return CPUID_TO_COMPACT_NODEID(cpu);
+}
+
+klcpu_t *nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
+{
+ lboard_t *brd;
+ klcpu_t *acpu;
+
+ if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
+ return (klcpu_t *)NULL;
+
+ if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
+ return (klcpu_t *)NULL;
+
+ do {
+ if ((acpu->cpu_info.physid) == slice)
+ return acpu;
+ } while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
+ KLSTRUCT_CPU)));
+ return (klcpu_t *)NULL;
+}
+
+klcpu_t *sn_get_cpuinfo(cpuid_t cpu)
+{
+ nasid_t nasid;
+ int slice;
+ klcpu_t *acpu;
+ gda_t *gdap = GDA;
+ cnodeid_t cnode;
+
+ if (!(cpu < MAXCPUS)) {
+ printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu);
+ return NULL;
+ }
+
+ cnode = get_cpu_cnode(cpu);
+ if (cnode == INVALID_CNODEID)
+ return NULL;
+
+ if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID)
+ return NULL;
+
+ for (slice = 0; slice < CPUS_PER_NODE; slice++) {
+ acpu = nasid_slice_to_cpuinfo(nasid, slice);
+ if (acpu && acpu->cpu_info.virtid == cpu)
+ return acpu;
+ }
+ return NULL;
+}
+
+int get_cpu_slice(cpuid_t cpu)
+{
+ klcpu_t *acpu;
+
+ if ((acpu = sn_get_cpuinfo(cpu)) == NULL)
+ return -1;
+ return acpu->cpu_info.physid;
+}
diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c
new file mode 100644
index 00000000..1d1919a4
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-klnuma.c
@@ -0,0 +1,132 @@
+/*
+ * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
+ * Copyright 2000 - 2001 Silicon Graphics, Inc.
+ * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com)
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/kernel.h>
+#include <linux/nodemask.h>
+#include <linux/string.h>
+
+#include <asm/page.h>
+#include <asm/sections.h>
+#include <asm/sn/types.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn_private.h>
+
+static cpumask_t ktext_repmask;
+
+/*
+ * XXX - This needs to be much smarter about where it puts copies of the
+ * kernel. For example, we should never put a copy on a headless node,
+ * and we should respect the topology of the machine.
+ */
+void __init setup_replication_mask(void)
+{
+ /* Set only the master cnode's bit. The master cnode is always 0. */
+ cpus_clear(ktext_repmask);
+ cpu_set(0, ktext_repmask);
+
+#ifdef CONFIG_REPLICATE_KTEXT
+#ifndef CONFIG_MAPPED_KERNEL
+#error Kernel replication works with mapped kernel support. No calias support.
+#endif
+ {
+ cnodeid_t cnode;
+
+ for_each_online_node(cnode) {
+ if (cnode == 0)
+ continue;
+ /* Advertise that we have a copy of the kernel */
+ cpu_set(cnode, ktext_repmask);
+ }
+ }
+#endif
+ /* Set up a GDA pointer to the replication mask. */
+ GDA->g_ktext_repmask = &ktext_repmask;
+}
+
+
+static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
+{
+ kern_vars_t *kvp;
+
+ kvp = &hub_data(client_nasid)->kern_vars;
+
+ KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp;
+
+ kvp->kv_magic = KV_MAGIC;
+ kvp->kv_ro_nasid = server_nasid;
+ kvp->kv_rw_nasid = master_nasid;
+ kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid);
+ kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid);
+ printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d\n", client_nasid, server_nasid, master_nasid);
+}
+
+/* XXX - When the BTE works, we should use it instead of this. */
+static __init void copy_kernel(nasid_t dest_nasid)
+{
+ unsigned long dest_kern_start, source_start, source_end, kern_size;
+
+ source_start = (unsigned long) _stext;
+ source_end = (unsigned long) _etext;
+ kern_size = source_end - source_start;
+
+ dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start),
+ dest_nasid);
+ memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
+}
+
+void __init replicate_kernel_text()
+{
+ cnodeid_t cnode;
+ nasid_t client_nasid;
+ nasid_t server_nasid;
+
+ server_nasid = master_nasid;
+
+ /* Record where the master node should get its kernel text */
+ set_ktext_source(master_nasid, master_nasid);
+
+ for_each_online_node(cnode) {
+ if (cnode == 0)
+ continue;
+ client_nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+ /* Check if this node should get a copy of the kernel */
+ if (cpu_isset(cnode, ktext_repmask)) {
+ server_nasid = client_nasid;
+ copy_kernel(server_nasid);
+ }
+
+ /* Record where this node should get its kernel text */
+ set_ktext_source(client_nasid, server_nasid);
+ }
+}
+
+/*
+ * Return pfn of first free page of memory on a node. PROM may allocate
+ * data structures on the first couple of pages of the first slot of each
+ * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
+ */
+pfn_t node_getfirstfree(cnodeid_t cnode)
+{
+ unsigned long loadbase = REP_BASE;
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+ unsigned long offset;
+
+#ifdef CONFIG_MAPPED_KERNEL
+ loadbase += 16777216;
+#endif
+ offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
+ if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask)))
+ return (TO_NODE(nasid, offset) >> PAGE_SHIFT);
+ else
+ return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >>
+ PAGE_SHIFT);
+}
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
new file mode 100644
index 00000000..bc129710
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -0,0 +1,509 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000, 05 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2000 by Silicon Graphics, Inc.
+ * Copyright (C) 2004 by Christoph Hellwig
+ *
+ * On SGI IP27 the ARC memory configuration data is completly bogus but
+ * alternate easier to use mechanisms are available.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#include <linux/pfn.h>
+#include <linux/highmem.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/sections.h>
+
+#include <asm/sn/arch.h>
+#include <asm/sn/hub.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_private.h>
+
+
+#define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT)
+#define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT)
+
+struct node_data *__node_data[MAX_COMPACT_NODES];
+
+EXPORT_SYMBOL(__node_data);
+
+static int fine_mode;
+
+static int is_fine_dirmode(void)
+{
+ return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
+ >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
+}
+
+static hubreg_t get_region(cnodeid_t cnode)
+{
+ if (fine_mode)
+ return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT;
+ else
+ return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT;
+}
+
+static hubreg_t region_mask;
+
+static void gen_region_mask(hubreg_t *region_mask)
+{
+ cnodeid_t cnode;
+
+ (*region_mask) = 0;
+ for_each_online_node(cnode) {
+ (*region_mask) |= 1ULL << get_region(cnode);
+ }
+}
+
+#define rou_rflag rou_flags
+
+static int router_distance;
+
+static void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth)
+{
+ klrou_t *router;
+ lboard_t *brd;
+ int port;
+
+ if (router_a->rou_rflag == 1)
+ return;
+
+ if (depth >= router_distance)
+ return;
+
+ router_a->rou_rflag = 1;
+
+ for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+ if (router_a->rou_port[port].port_nasid == INVALID_NASID)
+ continue;
+
+ brd = (lboard_t *)NODE_OFFSET_TO_K0(
+ router_a->rou_port[port].port_nasid,
+ router_a->rou_port[port].port_offset);
+
+ if (brd->brd_type == KLTYPE_ROUTER) {
+ router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+ if (router == router_b) {
+ if (depth < router_distance)
+ router_distance = depth;
+ }
+ else
+ router_recurse(router, router_b, depth + 1);
+ }
+ }
+
+ router_a->rou_rflag = 0;
+}
+
+unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
+
+static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
+{
+ klrou_t *router, *router_a = NULL, *router_b = NULL;
+ lboard_t *brd, *dest_brd;
+ cnodeid_t cnode;
+ nasid_t nasid;
+ int port;
+
+ /* Figure out which routers nodes in question are connected to */
+ for_each_online_node(cnode) {
+ nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+ if (nasid == -1) continue;
+
+ brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+ KLTYPE_ROUTER);
+
+ if (!brd)
+ continue;
+
+ do {
+ if (brd->brd_flags & DUPLICATE_BOARD)
+ continue;
+
+ router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+ router->rou_rflag = 0;
+
+ for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+ if (router->rou_port[port].port_nasid == INVALID_NASID)
+ continue;
+
+ dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+ router->rou_port[port].port_nasid,
+ router->rou_port[port].port_offset);
+
+ if (dest_brd->brd_type == KLTYPE_IP27) {
+ if (dest_brd->brd_nasid == nasid_a)
+ router_a = router;
+ if (dest_brd->brd_nasid == nasid_b)
+ router_b = router;
+ }
+ }
+
+ } while ((brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)));
+ }
+
+ if (router_a == NULL) {
+ printk("node_distance: router_a NULL\n");
+ return -1;
+ }
+ if (router_b == NULL) {
+ printk("node_distance: router_b NULL\n");
+ return -1;
+ }
+
+ if (nasid_a == nasid_b)
+ return 0;
+
+ if (router_a == router_b)
+ return 1;
+
+ router_distance = 100;
+ router_recurse(router_a, router_b, 2);
+
+ return router_distance;
+}
+
+static void __init init_topology_matrix(void)
+{
+ nasid_t nasid, nasid2;
+ cnodeid_t row, col;
+
+ for (row = 0; row < MAX_COMPACT_NODES; row++)
+ for (col = 0; col < MAX_COMPACT_NODES; col++)
+ __node_distances[row][col] = -1;
+
+ for_each_online_node(row) {
+ nasid = COMPACT_TO_NASID_NODEID(row);
+ for_each_online_node(col) {
+ nasid2 = COMPACT_TO_NASID_NODEID(col);
+ __node_distances[row][col] =
+ compute_node_distance(nasid, nasid2);
+ }
+ }
+}
+
+static void __init dump_topology(void)
+{
+ nasid_t nasid;
+ cnodeid_t cnode;
+ lboard_t *brd, *dest_brd;
+ int port;
+ int router_num = 0;
+ klrou_t *router;
+ cnodeid_t row, col;
+
+ printk("************** Topology ********************\n");
+
+ printk(" ");
+ for_each_online_node(col)
+ printk("%02d ", col);
+ printk("\n");
+ for_each_online_node(row) {
+ printk("%02d ", row);
+ for_each_online_node(col)
+ printk("%2d ", node_distance(row, col));
+ printk("\n");
+ }
+
+ for_each_online_node(cnode) {
+ nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+ if (nasid == -1) continue;
+
+ brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
+ KLTYPE_ROUTER);
+
+ if (!brd)
+ continue;
+
+ do {
+ if (brd->brd_flags & DUPLICATE_BOARD)
+ continue;
+ printk("Router %d:", router_num);
+ router_num++;
+
+ router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]);
+
+ for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
+ if (router->rou_port[port].port_nasid == INVALID_NASID)
+ continue;
+
+ dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
+ router->rou_port[port].port_nasid,
+ router->rou_port[port].port_offset);
+
+ if (dest_brd->brd_type == KLTYPE_IP27)
+ printk(" %d", dest_brd->brd_nasid);
+ if (dest_brd->brd_type == KLTYPE_ROUTER)
+ printk(" r");
+ }
+ printk("\n");
+
+ } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
+ }
+}
+
+static pfn_t __init slot_getbasepfn(cnodeid_t cnode, int slot)
+{
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+ return ((pfn_t)nasid << PFN_NASIDSHFT) | (slot << SLOT_PFNSHIFT);
+}
+
+static pfn_t __init slot_psize_compute(cnodeid_t node, int slot)
+{
+ nasid_t nasid;
+ lboard_t *brd;
+ klmembnk_t *banks;
+ unsigned long size;
+
+ nasid = COMPACT_TO_NASID_NODEID(node);
+ /* Find the node board */
+ brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+ if (!brd)
+ return 0;
+
+ /* Get the memory bank structure */
+ banks = (klmembnk_t *) find_first_component(brd, KLSTRUCT_MEMBNK);
+ if (!banks)
+ return 0;
+
+ /* Size in _Megabytes_ */
+ size = (unsigned long)banks->membnk_bnksz[slot/4];
+
+ /* hack for 128 dimm banks */
+ if (size <= 128) {
+ if (slot % 4 == 0) {
+ size <<= 20; /* size in bytes */
+ return(size >> PAGE_SHIFT);
+ } else
+ return 0;
+ } else {
+ size /= 4;
+ size <<= 20;
+ return size >> PAGE_SHIFT;
+ }
+}
+
+static void __init mlreset(void)
+{
+ int i;
+
+ master_nasid = get_nasid();
+ fine_mode = is_fine_dirmode();
+
+ /*
+ * Probe for all CPUs - this creates the cpumask and sets up the
+ * mapping tables. We need to do this as early as possible.
+ */
+#ifdef CONFIG_SMP
+ cpu_node_probe();
+#endif
+
+ init_topology_matrix();
+ dump_topology();
+
+ gen_region_mask(&region_mask);
+
+ setup_replication_mask();
+
+ /*
+ * Set all nodes' calias sizes to 8k
+ */
+ for_each_online_node(i) {
+ nasid_t nasid;
+
+ nasid = COMPACT_TO_NASID_NODEID(i);
+
+ /*
+ * Always have node 0 in the region mask, otherwise
+ * CALIAS accesses get exceptions since the hub
+ * thinks it is a node 0 address.
+ */
+ REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1));
+#ifdef CONFIG_REPLICATE_EXHANDLERS
+ REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K);
+#else
+ REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0);
+#endif
+
+#ifdef LATER
+ /*
+ * Set up all hubs to have a big window pointing at
+ * widget 0. Memory mode, widget 0, offset 0
+ */
+ REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN),
+ ((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) |
+ (0 << IIO_ITTE_WIDGET_SHIFT)));
+#endif
+ }
+}
+
+static void __init szmem(void)
+{
+ pfn_t slot_psize, slot0sz = 0, nodebytes; /* Hack to detect problem configs */
+ int slot;
+ cnodeid_t node;
+
+ num_physpages = 0;
+
+ for_each_online_node(node) {
+ nodebytes = 0;
+ for (slot = 0; slot < MAX_MEM_SLOTS; slot++) {
+ slot_psize = slot_psize_compute(node, slot);
+ if (slot == 0)
+ slot0sz = slot_psize;
+ /*
+ * We need to refine the hack when we have replicated
+ * kernel text.
+ */
+ nodebytes += (1LL << SLOT_SHIFT);
+
+ if (!slot_psize)
+ continue;
+
+ if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) >
+ (slot0sz << PAGE_SHIFT)) {
+ printk("Ignoring slot %d onwards on node %d\n",
+ slot, node);
+ slot = MAX_MEM_SLOTS;
+ continue;
+ }
+ num_physpages += slot_psize;
+ add_active_range(node, slot_getbasepfn(node, slot),
+ slot_getbasepfn(node, slot) + slot_psize);
+ }
+ }
+}
+
+static void __init node_mem_init(cnodeid_t node)
+{
+ pfn_t slot_firstpfn = slot_getbasepfn(node, 0);
+ pfn_t slot_freepfn = node_getfirstfree(node);
+ unsigned long bootmap_size;
+ pfn_t start_pfn, end_pfn;
+
+ get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
+
+ /*
+ * Allocate the node data structures on the node first.
+ */
+ __node_data[node] = __va(slot_freepfn << PAGE_SHIFT);
+
+ NODE_DATA(node)->bdata = &bootmem_node_data[node];
+ NODE_DATA(node)->node_start_pfn = start_pfn;
+ NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn;
+
+ cpus_clear(hub_data(node)->h_cpus);
+
+ slot_freepfn += PFN_UP(sizeof(struct pglist_data) +
+ sizeof(struct hub_data));
+
+ bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn,
+ start_pfn, end_pfn);
+ free_bootmem_with_active_regions(node, end_pfn);
+ reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT,
+ ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size,
+ BOOTMEM_DEFAULT);
+ sparse_memory_present_with_active_regions(node);
+}
+
+/*
+ * A node with nothing. We use it to avoid any special casing in
+ * cpumask_of_node
+ */
+static struct node_data null_node = {
+ .hub = {
+ .h_cpus = CPU_MASK_NONE
+ }
+};
+
+/*
+ * Currently, the intranode memory hole support assumes that each slot
+ * contains at least 32 MBytes of memory. We assume all bootmem data
+ * fits on the first slot.
+ */
+void __init prom_meminit(void)
+{
+ cnodeid_t node;
+
+ mlreset();
+ szmem();
+
+ for (node = 0; node < MAX_COMPACT_NODES; node++) {
+ if (node_online(node)) {
+ node_mem_init(node);
+ continue;
+ }
+ __node_data[node] = &null_node;
+ }
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* We got nothing to free here ... */
+}
+
+extern unsigned long setup_zero_pages(void);
+
+void __init paging_init(void)
+{
+ unsigned long zones_size[MAX_NR_ZONES] = {0, };
+ unsigned node;
+
+ pagetable_init();
+
+ for_each_online_node(node) {
+ pfn_t start_pfn, end_pfn;
+
+ get_pfn_range_for_nid(node, &start_pfn, &end_pfn);
+
+ if (end_pfn > max_low_pfn)
+ max_low_pfn = end_pfn;
+ }
+ zones_size[ZONE_NORMAL] = max_low_pfn;
+ free_area_init_nodes(zones_size);
+}
+
+void __init mem_init(void)
+{
+ unsigned long codesize, datasize, initsize, tmp;
+ unsigned node;
+
+ high_memory = (void *) __va(num_physpages << PAGE_SHIFT);
+
+ for_each_online_node(node) {
+ /*
+ * This will free up the bootmem, ie, slot 0 memory.
+ */
+ totalram_pages += free_all_bootmem_node(NODE_DATA(node));
+ }
+
+ totalram_pages -= setup_zero_pages(); /* This comes from node 0 */
+
+ codesize = (unsigned long) &_etext - (unsigned long) &_text;
+ datasize = (unsigned long) &_edata - (unsigned long) &_etext;
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+ tmp = nr_free_pages();
+ printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
+ "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
+ tmp << (PAGE_SHIFT-10),
+ num_physpages << (PAGE_SHIFT-10),
+ codesize >> 10,
+ (num_physpages - tmp) << (PAGE_SHIFT-10),
+ datasize >> 10,
+ initsize >> 10,
+ totalhigh_pages << (PAGE_SHIFT-10));
+}
diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
new file mode 100644
index 00000000..bc4fa8dd
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-nmi.c
@@ -0,0 +1,244 @@
+#include <linux/kernel.h>
+#include <linux/mmzone.h>
+#include <linux/nodemask.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <asm/atomic.h>
+#include <asm/sn/types.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/nmi.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/sn0/hub.h>
+
+#if 0
+#define NODE_NUM_CPUS(n) CNODE_NUM_CPUS(n)
+#else
+#define NODE_NUM_CPUS(n) CPUS_PER_NODE
+#endif
+
+#define CNODEID_NONE (cnodeid_t)-1
+
+typedef unsigned long machreg_t;
+
+static arch_spinlock_t nmi_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+
+/*
+ * Lets see what else we need to do here. Set up sp, gp?
+ */
+void nmi_dump(void)
+{
+ void cont_nmi_dump(void);
+
+ cont_nmi_dump();
+}
+
+void install_cpu_nmi_handler(int slice)
+{
+ nmi_t *nmi_addr;
+
+ nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice);
+ if (nmi_addr->call_addr)
+ return;
+ nmi_addr->magic = NMI_MAGIC;
+ nmi_addr->call_addr = (void *)nmi_dump;
+ nmi_addr->call_addr_c =
+ (void *)(~((unsigned long)(nmi_addr->call_addr)));
+ nmi_addr->call_parm = 0;
+}
+
+/*
+ * Copy the cpu registers which have been saved in the IP27prom format
+ * into the eframe format for the node under consideration.
+ */
+
+void nmi_cpu_eframe_save(nasid_t nasid, int slice)
+{
+ struct reg_struct *nr;
+ int i;
+
+ /* Get the pointer to the current cpu's register set. */
+ nr = (struct reg_struct *)
+ (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) +
+ slice * IP27_NMI_KREGS_CPU_SIZE);
+
+ printk("NMI nasid %d: slice %d\n", nasid, slice);
+
+ /*
+ * Saved main processor registers
+ */
+ for (i = 0; i < 32; ) {
+ if ((i % 4) == 0)
+ printk("$%2d :", i);
+ printk(" %016lx", nr->gpr[i]);
+
+ i++;
+ if ((i % 4) == 0)
+ printk("\n");
+ }
+
+ printk("Hi : (value lost)\n");
+ printk("Lo : (value lost)\n");
+
+ /*
+ * Saved cp0 registers
+ */
+ printk("epc : %016lx %pS\n", nr->epc, (void *) nr->epc);
+ printk("%s\n", print_tainted());
+ printk("ErrEPC: %016lx %pS\n", nr->error_epc, (void *) nr->error_epc);
+ printk("ra : %016lx %pS\n", nr->gpr[31], (void *) nr->gpr[31]);
+ printk("Status: %08lx ", nr->sr);
+
+ if (nr->sr & ST0_KX)
+ printk("KX ");
+ if (nr->sr & ST0_SX)
+ printk("SX ");
+ if (nr->sr & ST0_UX)
+ printk("UX ");
+
+ switch (nr->sr & ST0_KSU) {
+ case KSU_USER:
+ printk("USER ");
+ break;
+ case KSU_SUPERVISOR:
+ printk("SUPERVISOR ");
+ break;
+ case KSU_KERNEL:
+ printk("KERNEL ");
+ break;
+ default:
+ printk("BAD_MODE ");
+ break;
+ }
+
+ if (nr->sr & ST0_ERL)
+ printk("ERL ");
+ if (nr->sr & ST0_EXL)
+ printk("EXL ");
+ if (nr->sr & ST0_IE)
+ printk("IE ");
+ printk("\n");
+
+ printk("Cause : %08lx\n", nr->cause);
+ printk("PrId : %08x\n", read_c0_prid());
+ printk("BadVA : %016lx\n", nr->badva);
+ printk("CErr : %016lx\n", nr->cache_err);
+ printk("NMI_SR: %016lx\n", nr->nmi_sr);
+
+ printk("\n");
+}
+
+void nmi_dump_hub_irq(nasid_t nasid, int slice)
+{
+ hubreg_t mask0, mask1, pend0, pend1;
+
+ if (slice == 0) { /* Slice A */
+ mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A);
+ mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_A);
+ } else { /* Slice B */
+ mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_B);
+ mask1 = REMOTE_HUB_L(nasid, PI_INT_MASK1_B);
+ }
+
+ pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);
+ pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);
+
+ printk("PI_INT_MASK0: %16Lx PI_INT_MASK1: %16Lx\n", mask0, mask1);
+ printk("PI_INT_PEND0: %16Lx PI_INT_PEND1: %16Lx\n", pend0, pend1);
+ printk("\n\n");
+}
+
+/*
+ * Copy the cpu registers which have been saved in the IP27prom format
+ * into the eframe format for the node under consideration.
+ */
+void nmi_node_eframe_save(cnodeid_t cnode)
+{
+ nasid_t nasid;
+ int slice;
+
+ /* Make sure that we have a valid node */
+ if (cnode == CNODEID_NONE)
+ return;
+
+ nasid = COMPACT_TO_NASID_NODEID(cnode);
+ if (nasid == INVALID_NASID)
+ return;
+
+ /* Save the registers into eframe for each cpu */
+ for (slice = 0; slice < NODE_NUM_CPUS(slice); slice++) {
+ nmi_cpu_eframe_save(nasid, slice);
+ nmi_dump_hub_irq(nasid, slice);
+ }
+}
+
+/*
+ * Save the nmi cpu registers for all cpus in the system.
+ */
+void
+nmi_eframes_save(void)
+{
+ cnodeid_t cnode;
+
+ for_each_online_node(cnode)
+ nmi_node_eframe_save(cnode);
+}
+
+void
+cont_nmi_dump(void)
+{
+#ifndef REAL_NMI_SIGNAL
+ static atomic_t nmied_cpus = ATOMIC_INIT(0);
+
+ atomic_inc(&nmied_cpus);
+#endif
+ /*
+ * Only allow 1 cpu to proceed
+ */
+ arch_spin_lock(&nmi_lock);
+
+#ifdef REAL_NMI_SIGNAL
+ /*
+ * Wait up to 15 seconds for the other cpus to respond to the NMI.
+ * If a cpu has not responded after 10 sec, send it 1 additional NMI.
+ * This is for 2 reasons:
+ * - sometimes a MMSC fail to NMI all cpus.
+ * - on 512p SN0 system, the MMSC will only send NMIs to
+ * half the cpus. Unfortunately, we don't know which cpus may be
+ * NMIed - it depends on how the site chooses to configure.
+ *
+ * Note: it has been measure that it takes the MMSC up to 2.3 secs to
+ * send NMIs to all cpus on a 256p system.
+ */
+ for (i=0; i < 1500; i++) {
+ for_each_online_node(node)
+ if (NODEPDA(node)->dump_count == 0)
+ break;
+ if (node == MAX_NUMNODES)
+ break;
+ if (i == 1000) {
+ for_each_online_node(node)
+ if (NODEPDA(node)->dump_count == 0) {
+ cpu = cpumask_first(cpumask_of_node(node));
+ for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
+ CPUMASK_SETB(nmied_cpus, cpu);
+ /*
+ * cputonasid, cputoslice
+ * needs kernel cpuid
+ */
+ SEND_NMI((cputonasid(cpu)), (cputoslice(cpu)));
+ }
+ }
+
+ }
+ udelay(10000);
+ }
+#else
+ while (atomic_read(&nmied_cpus) != num_online_cpus());
+#endif
+
+ /*
+ * Save the nmi cpu registers for all cpu in the eframe format.
+ */
+ nmi_eframes_save();
+ LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+}
diff --git a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c
new file mode 100644
index 00000000..c1707610
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-reset.c
@@ -0,0 +1,81 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Reset an IP27.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 06 by Ralf Baechle
+ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/smp.h>
+#include <linux/mmzone.h>
+#include <linux/nodemask.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/sgialib.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/sn0/hub.h>
+
+void machine_restart(char *command) __attribute__((noreturn));
+void machine_halt(void) __attribute__((noreturn));
+void machine_power_off(void) __attribute__((noreturn));
+
+#define noreturn while(1); /* Silence gcc. */
+
+/* XXX How to pass the reboot command to the firmware??? */
+static void ip27_machine_restart(char *command)
+{
+#if 0
+ int i;
+#endif
+
+ printk("Reboot started from CPU %d\n", smp_processor_id());
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+#if 0
+ for_each_online_node(i)
+ REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
+ PROMOP_REBOOT);
+#else
+ LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+#endif
+ noreturn;
+}
+
+static void ip27_machine_halt(void)
+{
+ int i;
+
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+ for_each_online_node(i)
+ REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG,
+ PROMOP_RESTART);
+ LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
+ noreturn;
+}
+
+static void ip27_machine_power_off(void)
+{
+ /* To do ... */
+ noreturn;
+}
+
+void ip27_reboot_setup(void)
+{
+ _machine_restart = ip27_machine_restart;
+ _machine_halt = ip27_machine_halt;
+ pm_power_off = ip27_machine_power_off;
+}
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
new file mode 100644
index 00000000..c6851df9
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -0,0 +1,243 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/nodemask.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/gda.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/launch.h>
+#include <asm/sn/mapped_kernel.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/hubpi.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/sn0/ip27.h>
+
+/*
+ * Takes as first input the PROM assigned cpu id, and the kernel
+ * assigned cpu id as the second.
+ */
+static void alloc_cpupda(cpuid_t cpu, int cpunum)
+{
+ cnodeid_t node = get_cpu_cnode(cpu);
+ nasid_t nasid = COMPACT_TO_NASID_NODEID(node);
+
+ cputonasid(cpunum) = nasid;
+ sn_cpu_info[cpunum].p_nodeid = node;
+ cputoslice(cpunum) = get_cpu_slice(cpu);
+}
+
+static nasid_t get_actual_nasid(lboard_t *brd)
+{
+ klhub_t *hub;
+
+ if (!brd)
+ return INVALID_NASID;
+
+ /* find out if we are a completely disabled brd. */
+ hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
+ if (!hub)
+ return INVALID_NASID;
+ if (!(hub->hub_info.flags & KLINFO_ENABLE)) /* disabled node brd */
+ return hub->hub_info.physid;
+ else
+ return brd->brd_nasid;
+}
+
+static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest)
+{
+ static int tot_cpus_found = 0;
+ lboard_t *brd;
+ klcpu_t *acpu;
+ int cpus_found = 0;
+ cpuid_t cpuid;
+
+ brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
+
+ do {
+ acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
+ while (acpu) {
+ cpuid = acpu->cpu_info.virtid;
+ /* cnode is not valid for completely disabled brds */
+ if (get_actual_nasid(brd) == brd->brd_nasid)
+ cpuid_to_compact_node[cpuid] = cnode;
+ if (cpuid > highest)
+ highest = cpuid;
+ /* Only let it join in if it's marked enabled */
+ if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
+ (tot_cpus_found != NR_CPUS)) {
+ cpu_set(cpuid, cpu_possible_map);
+ alloc_cpupda(cpuid, tot_cpus_found);
+ cpus_found++;
+ tot_cpus_found++;
+ }
+ acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
+ KLSTRUCT_CPU);
+ }
+ brd = KLCF_NEXT(brd);
+ if (!brd)
+ break;
+
+ brd = find_lboard(brd, KLTYPE_IP27);
+ } while (brd);
+
+ return highest;
+}
+
+void cpu_node_probe(void)
+{
+ int i, highest = 0;
+ gda_t *gdap = GDA;
+
+ /*
+ * Initialize the arrays to invalid nodeid (-1)
+ */
+ for (i = 0; i < MAX_COMPACT_NODES; i++)
+ compact_to_nasid_node[i] = INVALID_NASID;
+ for (i = 0; i < MAX_NASIDS; i++)
+ nasid_to_compact_node[i] = INVALID_CNODEID;
+ for (i = 0; i < MAXCPUS; i++)
+ cpuid_to_compact_node[i] = INVALID_CNODEID;
+
+ /*
+ * MCD - this whole "compact node" stuff can probably be dropped,
+ * as we can handle sparse numbering now
+ */
+ nodes_clear(node_online_map);
+ for (i = 0; i < MAX_COMPACT_NODES; i++) {
+ nasid_t nasid = gdap->g_nasidtable[i];
+ if (nasid == INVALID_NASID)
+ break;
+ compact_to_nasid_node[i] = nasid;
+ nasid_to_compact_node[nasid] = i;
+ node_set_online(num_online_nodes());
+ highest = do_cpumask(i, nasid, highest);
+ }
+
+ printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
+}
+
+static __init void intr_clear_all(nasid_t nasid)
+{
+ int i;
+
+ REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0);
+ REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0);
+ REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0);
+ REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0);
+
+ for (i = 0; i < 128; i++)
+ REMOTE_HUB_CLR_INTR(nasid, i);
+}
+
+static void ip27_send_ipi_single(int destid, unsigned int action)
+{
+ int irq;
+
+ switch (action) {
+ case SMP_RESCHEDULE_YOURSELF:
+ irq = CPU_RESCHED_A_IRQ;
+ break;
+ case SMP_CALL_FUNCTION:
+ irq = CPU_CALL_A_IRQ;
+ break;
+ default:
+ panic("sendintr");
+ }
+
+ irq += cputoslice(destid);
+
+ /*
+ * Convert the compact hub number to the NASID to get the correct
+ * part of the address space. Then set the interrupt bit associated
+ * with the CPU we want to send the interrupt to.
+ */
+ REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq);
+}
+
+static void ip27_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ ip27_send_ipi_single(i, action);
+}
+
+static void __cpuinit ip27_init_secondary(void)
+{
+ per_cpu_init();
+}
+
+static void __cpuinit ip27_smp_finish(void)
+{
+ extern void hub_rt_clock_event_init(void);
+
+ hub_rt_clock_event_init();
+ local_irq_enable();
+}
+
+static void __init ip27_cpus_done(void)
+{
+}
+
+/*
+ * Launch a slave into smp_bootstrap(). It doesn't take an argument, and we
+ * set sp to the kernel stack of the newly created idle process, gp to the proc
+ * struct so that current_thread_info() will work.
+ */
+static void __cpuinit ip27_boot_secondary(int cpu, struct task_struct *idle)
+{
+ unsigned long gp = (unsigned long)task_thread_info(idle);
+ unsigned long sp = __KSTK_TOS(idle);
+
+ LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu),
+ (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap),
+ 0, (void *) sp, (void *) gp);
+}
+
+static void __init ip27_smp_setup(void)
+{
+ cnodeid_t cnode;
+
+ for_each_online_node(cnode) {
+ if (cnode == 0)
+ continue;
+ intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
+ }
+
+ replicate_kernel_text();
+
+ /*
+ * Assumption to be fixed: we're always booted on logical / physical
+ * processor 0. While we're always running on logical processor 0
+ * this still means this is physical processor zero; it might for
+ * example be disabled in the firmware.
+ */
+ alloc_cpupda(0, 0);
+}
+
+static void __init ip27_prepare_cpus(unsigned int max_cpus)
+{
+ /* We already did everything necessary earlier */
+}
+
+struct plat_smp_ops ip27_smp_ops = {
+ .send_ipi_single = ip27_send_ipi_single,
+ .send_ipi_mask = ip27_send_ipi_mask,
+ .init_secondary = ip27_init_secondary,
+ .smp_finish = ip27_smp_finish,
+ .cpus_done = ip27_cpus_done,
+ .boot_secondary = ip27_boot_secondary,
+ .smp_setup = ip27_smp_setup,
+ .prepare_cpus = ip27_prepare_cpus,
+};
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
new file mode 100644
index 00000000..ef74f326
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -0,0 +1,234 @@
+/*
+ * Copytight (C) 1999, 2000, 05, 06 Ralf Baechle (ralf@linux-mips.org)
+ * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
+ */
+#include <linux/bcd.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/smp.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+
+#include <asm/time.h>
+#include <asm/pgtable.h>
+#include <asm/sgialib.h>
+#include <asm/sn/ioc3.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+#define TICK_SIZE (tick_nsec / 1000)
+
+/* Includes for ioc3_init(). */
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/pci/bridge.h>
+
+static void enable_rt_irq(struct irq_data *d)
+{
+}
+
+static void disable_rt_irq(struct irq_data *d)
+{
+}
+
+static struct irq_chip rt_irq_type = {
+ .name = "SN HUB RT timer",
+ .irq_mask = disable_rt_irq,
+ .irq_unmask = enable_rt_irq,
+};
+
+static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
+{
+ unsigned int cpu = smp_processor_id();
+ int slice = cputoslice(cpu);
+ unsigned long cnt;
+
+ cnt = LOCAL_HUB_L(PI_RT_COUNT);
+ cnt += delta;
+ LOCAL_HUB_S(PI_RT_COMPARE_A + PI_COUNT_OFFSET * slice, cnt);
+
+ return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
+}
+
+static void rt_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Nothing to do ... */
+}
+
+int rt_timer_irq;
+
+static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
+static DEFINE_PER_CPU(char [11], hub_rt_name);
+
+static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
+ int slice = cputoslice(cpu);
+
+ /*
+ * Ack
+ */
+ LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, 0);
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+struct irqaction hub_rt_irqaction = {
+ .handler = hub_rt_counter_handler,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "hub-rt",
+};
+
+/*
+ * This is a hack; we really need to figure these values out dynamically
+ *
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE 800
+#define CYCLES_PER_SEC (NSEC_PER_SEC / NSEC_PER_CYCLE)
+
+void __cpuinit hub_rt_clock_event_init(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
+ unsigned char *name = per_cpu(hub_rt_name, cpu);
+ int irq = rt_timer_irq;
+
+ sprintf(name, "hub-rt %d", cpu);
+ cd->name = name;
+ cd->features = CLOCK_EVT_FEAT_ONESHOT;
+ clockevent_set_clock(cd, CYCLES_PER_SEC);
+ cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+ cd->rating = 200;
+ cd->irq = irq;
+ cd->cpumask = cpumask_of(cpu);
+ cd->set_next_event = rt_next_event;
+ cd->set_mode = rt_set_mode;
+ clockevents_register_device(cd);
+}
+
+static void __init hub_rt_clock_event_global_init(void)
+{
+ int irq;
+
+ do {
+ smp_wmb();
+ irq = rt_timer_irq;
+ if (irq)
+ break;
+
+ irq = allocate_irqno();
+ if (irq < 0)
+ panic("Allocation of irq number for timer failed");
+ } while (xchg(&rt_timer_irq, irq));
+
+ irq_set_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
+ setup_irq(irq, &hub_rt_irqaction);
+}
+
+static cycle_t hub_rt_read(struct clocksource *cs)
+{
+ return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
+}
+
+struct clocksource hub_rt_clocksource = {
+ .name = "HUB-RT",
+ .rating = 200,
+ .read = hub_rt_read,
+ .mask = CLOCKSOURCE_MASK(52),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init hub_rt_clocksource_init(void)
+{
+ struct clocksource *cs = &hub_rt_clocksource;
+
+ clocksource_register_hz(cs, CYCLES_PER_SEC);
+}
+
+void __init plat_time_init(void)
+{
+ hub_rt_clocksource_init();
+ hub_rt_clock_event_global_init();
+ hub_rt_clock_event_init();
+}
+
+void __cpuinit cpu_time_init(void)
+{
+ lboard_t *board;
+ klcpu_t *cpu;
+ int cpuid;
+
+ /* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */
+ board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
+ if (!board)
+ panic("Can't find board info for myself.");
+
+ cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
+ cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
+ if (!cpu)
+ panic("No information about myself?");
+
+ printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
+
+ set_c0_status(SRB_TIMOCLK);
+}
+
+void __cpuinit hub_rtc_init(cnodeid_t cnode)
+{
+
+ /*
+ * We only need to initialize the current node.
+ * If this is not the current node then it is a cpuless
+ * node and timeouts will not happen there.
+ */
+ if (get_compact_nodeid() == cnode) {
+ LOCAL_HUB_S(PI_RT_EN_A, 1);
+ LOCAL_HUB_S(PI_RT_EN_B, 1);
+ LOCAL_HUB_S(PI_PROF_EN_A, 0);
+ LOCAL_HUB_S(PI_PROF_EN_B, 0);
+ LOCAL_HUB_S(PI_RT_COUNT, 0);
+ LOCAL_HUB_S(PI_RT_PEND_A, 0);
+ LOCAL_HUB_S(PI_RT_PEND_B, 0);
+ }
+}
+
+static int __init sgi_ip27_rtc_devinit(void)
+{
+ struct resource res;
+
+ memset(&res, 0, sizeof(res));
+ res.start = XPHYSADDR(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base +
+ IOC3_BYTEBUS_DEV0);
+ res.end = res.start + 32767;
+ res.flags = IORESOURCE_MEM;
+
+ return IS_ERR(platform_device_register_simple("rtc-m48t35", -1,
+ &res, 1));
+}
+
+/*
+ * kludge make this a device_initcall after ioc3 resource conflicts
+ * are resolved
+ */
+late_initcall(sgi_ip27_rtc_devinit);
diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
new file mode 100644
index 00000000..5e871e75
--- /dev/null
+++ b/arch/mips/sgi-ip27/ip27-xtalk.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
+ * Copyright (C) 2004 Christoph Hellwig.
+ * Released under GPL v2.
+ *
+ * Generic XTALK initialization code
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <asm/sn/types.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/hub.h>
+#include <asm/pci/bridge.h>
+#include <asm/xtalk/xtalk.h>
+
+
+#define XBOW_WIDGET_PART_NUM 0x0
+#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */
+#define BASE_XBOW_PORT 8 /* Lowest external port */
+
+extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
+
+static int __cpuinit probe_one_port(nasid_t nasid, int widget, int masterwid)
+{
+ widgetreg_t widget_id;
+ xwidget_part_num_t partnum;
+
+ widget_id = *(volatile widgetreg_t *)
+ (RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID);
+ partnum = XWIDGET_PART_NUM(widget_id);
+
+ printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ",
+ smp_processor_id(), nasid, widget, partnum);
+
+ switch (partnum) {
+ case BRIDGE_WIDGET_PART_NUM:
+ case XBRIDGE_WIDGET_PART_NUM:
+ bridge_probe(nasid, widget, masterwid);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int __cpuinit xbow_probe(nasid_t nasid)
+{
+ lboard_t *brd;
+ klxbow_t *xbow_p;
+ unsigned masterwid, i;
+
+ printk("is xbow\n");
+
+ /*
+ * found xbow, so may have multiple bridges
+ * need to probe xbow
+ */
+ brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8);
+ if (!brd)
+ return -ENODEV;
+
+ xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW);
+ if (!xbow_p)
+ return -ENODEV;
+
+ /*
+ * Okay, here's a xbow. Lets arbitrate and find
+ * out if we should initialize it. Set enabled
+ * hub connected at highest or lowest widget as
+ * master.
+ */
+#ifdef WIDGET_A
+ i = HUB_WIDGET_ID_MAX + 1;
+ do {
+ i--;
+ } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
+ (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
+#else
+ i = HUB_WIDGET_ID_MIN - 1;
+ do {
+ i++;
+ } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
+ (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
+#endif
+
+ masterwid = i;
+ if (nasid != XBOW_PORT_NASID(xbow_p, i))
+ return 1;
+
+ for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) {
+ if (XBOW_PORT_IS_ENABLED(xbow_p, i) &&
+ XBOW_PORT_TYPE_IO(xbow_p, i))
+ probe_one_port(nasid, i, masterwid);
+ }
+
+ return 0;
+}
+
+void __cpuinit xtalk_probe_node(cnodeid_t nid)
+{
+ volatile u64 hubreg;
+ nasid_t nasid;
+ xwidget_part_num_t partnum;
+ widgetreg_t widget_id;
+
+ nasid = COMPACT_TO_NASID_NODEID(nid);
+ hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+
+ /* check whether the link is up */
+ if (!(hubreg & IIO_LLP_CSR_IS_UP))
+ return;
+
+ widget_id = *(volatile widgetreg_t *)
+ (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
+ partnum = XWIDGET_PART_NUM(widget_id);
+
+ printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ",
+ smp_processor_id(), nasid, partnum);
+
+ switch (partnum) {
+ case BRIDGE_WIDGET_PART_NUM:
+ bridge_probe(nasid, 0x8, 0xa);
+ break;
+ case XBOW_WIDGET_PART_NUM:
+ case XXBOW_WIDGET_PART_NUM:
+ xbow_probe(nasid);
+ break;
+ default:
+ printk(" unknown widget??\n");
+ break;
+ }
+}
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
new file mode 100644
index 00000000..60f02274
--- /dev/null
+++ b/arch/mips/sgi-ip32/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the SGI specific kernel interface routines
+# under Linux.
+#
+
+obj-y += ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \
+ crime.o ip32-memory.o
diff --git a/arch/mips/sgi-ip32/Platform b/arch/mips/sgi-ip32/Platform
new file mode 100644
index 00000000..0fea556f
--- /dev/null
+++ b/arch/mips/sgi-ip32/Platform
@@ -0,0 +1,11 @@
+#
+# SGI-IP32 (O2)
+#
+# Set the load address to >= 80069000 if you want to leave space for symmon,
+# 0xffffffff80004000 for production kernels. Note that the value must be aligned to
+# a multiple of the kernel stack size or the handling of the current variable
+# will break.
+#
+platform-$(CONFIG_SGI_IP32) += sgi-ip32/
+cflags-$(CONFIG_SGI_IP32) += -I$(srctree)/arch/mips/include/asm/mach-ip32
+load-$(CONFIG_SGI_IP32) += 0xffffffff80004000
diff --git a/arch/mips/sgi-ip32/crime.c b/arch/mips/sgi-ip32/crime.c
new file mode 100644
index 00000000..563c614a
--- /dev/null
+++ b/arch/mips/sgi-ip32/crime.c
@@ -0,0 +1,103 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001, 2003 Keith M Wesolowski
+ * Copyright (C) 2005 Ilya A. Volynets <ilya@total-knowledge.com>
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+
+struct sgi_crime __iomem *crime;
+struct sgi_mace __iomem *mace;
+
+EXPORT_SYMBOL_GPL(mace);
+
+void __init crime_init(void)
+{
+ unsigned int id, rev;
+ const int field = 2 * sizeof(unsigned long);
+
+ set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
+ crime = ioremap(CRIME_BASE, sizeof(struct sgi_crime));
+ mace = ioremap(MACE_BASE, sizeof(struct sgi_mace));
+
+ id = crime->id;
+ rev = id & CRIME_ID_REV;
+ id = (id & CRIME_ID_IDBITS) >> 4;
+ printk(KERN_INFO "CRIME id %1x rev %d at 0x%0*lx\n",
+ id, rev, field, (unsigned long) CRIME_BASE);
+}
+
+irqreturn_t crime_memerr_intr(unsigned int irq, void *dev_id)
+{
+ unsigned long stat, addr;
+ int fatal = 0;
+
+ stat = crime->mem_error_stat & CRIME_MEM_ERROR_STAT_MASK;
+ addr = crime->mem_error_addr & CRIME_MEM_ERROR_ADDR_MASK;
+
+ printk("CRIME memory error at 0x%08lx ST 0x%08lx<", addr, stat);
+
+ if (stat & CRIME_MEM_ERROR_INV)
+ printk("INV,");
+ if (stat & CRIME_MEM_ERROR_ECC) {
+ unsigned long ecc_syn =
+ crime->mem_ecc_syn & CRIME_MEM_ERROR_ECC_SYN_MASK;
+ unsigned long ecc_gen =
+ crime->mem_ecc_chk & CRIME_MEM_ERROR_ECC_CHK_MASK;
+ printk("ECC,SYN=0x%08lx,GEN=0x%08lx,", ecc_syn, ecc_gen);
+ }
+ if (stat & CRIME_MEM_ERROR_MULTIPLE) {
+ fatal = 1;
+ printk("MULTIPLE,");
+ }
+ if (stat & CRIME_MEM_ERROR_HARD_ERR) {
+ fatal = 1;
+ printk("HARD,");
+ }
+ if (stat & CRIME_MEM_ERROR_SOFT_ERR)
+ printk("SOFT,");
+ if (stat & CRIME_MEM_ERROR_CPU_ACCESS)
+ printk("CPU,");
+ if (stat & CRIME_MEM_ERROR_VICE_ACCESS)
+ printk("VICE,");
+ if (stat & CRIME_MEM_ERROR_GBE_ACCESS)
+ printk("GBE,");
+ if (stat & CRIME_MEM_ERROR_RE_ACCESS)
+ printk("RE,REID=0x%02lx,", (stat & CRIME_MEM_ERROR_RE_ID)>>8);
+ if (stat & CRIME_MEM_ERROR_MACE_ACCESS)
+ printk("MACE,MACEID=0x%02lx,", stat & CRIME_MEM_ERROR_MACE_ID);
+
+ crime->mem_error_stat = 0;
+
+ if (fatal) {
+ printk("FATAL>\n");
+ panic("Fatal memory error.");
+ } else
+ printk("NONFATAL>\n");
+
+ return IRQ_HANDLED;
+}
+
+irqreturn_t crime_cpuerr_intr(unsigned int irq, void *dev_id)
+{
+ unsigned long stat = crime->cpu_error_stat & CRIME_CPU_ERROR_MASK;
+ unsigned long addr = crime->cpu_error_addr & CRIME_CPU_ERROR_ADDR_MASK;
+
+ addr <<= 2;
+ printk("CRIME CPU error at 0x%09lx status 0x%08lx\n", addr, stat);
+ crime->cpu_error_stat = 0;
+
+ return IRQ_HANDLED;
+}
diff --git a/arch/mips/sgi-ip32/ip32-berr.c b/arch/mips/sgi-ip32/ip32-berr.c
new file mode 100644
index 00000000..afc1cadb
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-berr.c
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1999, 2000 by Ralf Baechle
+ * Copyright (C) 1999, 2000 by Silicon Graphics
+ * Copyright (C) 2002 Maciej W. Rozycki
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+#include <asm/ptrace.h>
+#include <asm/tlbdebug.h>
+
+static int ip32_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ int data = regs->cp0_cause & 4;
+
+ if (is_fixup)
+ return MIPS_BE_FIXUP;
+
+ printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc);
+ show_regs(regs);
+ dump_tlb_all();
+ while(1);
+ force_sig(SIGBUS, current);
+}
+
+void __init ip32_be_init(void)
+{
+ board_be_handler = ip32_be_handler;
+}
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
new file mode 100644
index 00000000..c65ea76d
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -0,0 +1,507 @@
+/*
+ * Code to handle IP32 IRQs
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Harald Koerfgen
+ * Copyright (C) 2001 Keith M Wesolowski
+ */
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+/* issue a PIO read to make sure no PIO writes are pending */
+static void inline flush_crime_bus(void)
+{
+ crime->control;
+}
+
+static void inline flush_mace_bus(void)
+{
+ mace->perif.ctrl.misc;
+}
+
+/*
+ * O2 irq map
+ *
+ * IP0 -> software (ignored)
+ * IP1 -> software (ignored)
+ * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ???
+ * IP3 -> (irq1) X unknown
+ * IP4 -> (irq2) X unknown
+ * IP5 -> (irq3) X unknown
+ * IP6 -> (irq4) X unknown
+ * IP7 -> (irq5) 7 CPU count/compare timer (system timer)
+ *
+ * crime: (C)
+ *
+ * CRIME_INT_STAT 31:0:
+ *
+ * 0 -> 8 Video in 1
+ * 1 -> 9 Video in 2
+ * 2 -> 10 Video out
+ * 3 -> 11 Mace ethernet
+ * 4 -> S SuperIO sub-interrupt
+ * 5 -> M Miscellaneous sub-interrupt
+ * 6 -> A Audio sub-interrupt
+ * 7 -> 15 PCI bridge errors
+ * 8 -> 16 PCI SCSI aic7xxx 0
+ * 9 -> 17 PCI SCSI aic7xxx 1
+ * 10 -> 18 PCI slot 0
+ * 11 -> 19 unused (PCI slot 1)
+ * 12 -> 20 unused (PCI slot 2)
+ * 13 -> 21 unused (PCI shared 0)
+ * 14 -> 22 unused (PCI shared 1)
+ * 15 -> 23 unused (PCI shared 2)
+ * 16 -> 24 GBE0 (E)
+ * 17 -> 25 GBE1 (E)
+ * 18 -> 26 GBE2 (E)
+ * 19 -> 27 GBE3 (E)
+ * 20 -> 28 CPU errors
+ * 21 -> 29 Memory errors
+ * 22 -> 30 RE empty edge (E)
+ * 23 -> 31 RE full edge (E)
+ * 24 -> 32 RE idle edge (E)
+ * 25 -> 33 RE empty level
+ * 26 -> 34 RE full level
+ * 27 -> 35 RE idle level
+ * 28 -> 36 unused (software 0) (E)
+ * 29 -> 37 unused (software 1) (E)
+ * 30 -> 38 unused (software 2) - crime 1.5 CPU SysCorError (E)
+ * 31 -> 39 VICE
+ *
+ * S, M, A: Use the MACE ISA interrupt register
+ * MACE_ISA_INT_STAT 31:0
+ *
+ * 0-7 -> 40-47 Audio
+ * 8 -> 48 RTC
+ * 9 -> 49 Keyboard
+ * 10 -> X Keyboard polled
+ * 11 -> 51 Mouse
+ * 12 -> X Mouse polled
+ * 13-15 -> 53-55 Count/compare timers
+ * 16-19 -> 56-59 Parallel (16 E)
+ * 20-25 -> 60-62 Serial 1 (22 E)
+ * 26-31 -> 66-71 Serial 2 (28 E)
+ *
+ * Note that this means IRQs 12-14, 50, and 52 do not exist. This is a
+ * different IRQ map than IRIX uses, but that's OK as Linux irq handling
+ * is quite different anyway.
+ */
+
+/* Some initial interrupts to set up */
+extern irqreturn_t crime_memerr_intr(int irq, void *dev_id);
+extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
+
+static struct irqaction memerr_irq = {
+ .handler = crime_memerr_intr,
+ .flags = IRQF_DISABLED,
+ .name = "CRIME memory error",
+};
+
+static struct irqaction cpuerr_irq = {
+ .handler = crime_cpuerr_intr,
+ .flags = IRQF_DISABLED,
+ .name = "CRIME CPU error",
+};
+
+/*
+ * This is for pure CRIME interrupts - ie not MACE. The advantage?
+ * We get to split the register in half and do faster lookups.
+ */
+
+static uint64_t crime_mask;
+
+static inline void crime_enable_irq(struct irq_data *d)
+{
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+
+ crime_mask |= 1 << bit;
+ crime->imask = crime_mask;
+}
+
+static inline void crime_disable_irq(struct irq_data *d)
+{
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+
+ crime_mask &= ~(1 << bit);
+ crime->imask = crime_mask;
+ flush_crime_bus();
+}
+
+static struct irq_chip crime_level_interrupt = {
+ .name = "IP32 CRIME",
+ .irq_mask = crime_disable_irq,
+ .irq_unmask = crime_enable_irq,
+};
+
+static void crime_edge_mask_and_ack_irq(struct irq_data *d)
+{
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+ uint64_t crime_int;
+
+ /* Edge triggered interrupts must be cleared. */
+ crime_int = crime->hard_int;
+ crime_int &= ~(1 << bit);
+ crime->hard_int = crime_int;
+
+ crime_disable_irq(d);
+}
+
+static struct irq_chip crime_edge_interrupt = {
+ .name = "IP32 CRIME",
+ .irq_ack = crime_edge_mask_and_ack_irq,
+ .irq_mask = crime_disable_irq,
+ .irq_mask_ack = crime_edge_mask_and_ack_irq,
+ .irq_unmask = crime_enable_irq,
+};
+
+/*
+ * This is for MACE PCI interrupts. We can decrease bus traffic by masking
+ * as close to the source as possible. This also means we can take the
+ * next chunk of the CRIME register in one piece.
+ */
+
+static unsigned long macepci_mask;
+
+static void enable_macepci_irq(struct irq_data *d)
+{
+ macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
+ mace->pci.control = macepci_mask;
+ crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
+ crime->imask = crime_mask;
+}
+
+static void disable_macepci_irq(struct irq_data *d)
+{
+ crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
+ crime->imask = crime_mask;
+ flush_crime_bus();
+ macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
+ mace->pci.control = macepci_mask;
+ flush_mace_bus();
+}
+
+static struct irq_chip ip32_macepci_interrupt = {
+ .name = "IP32 MACE PCI",
+ .irq_mask = disable_macepci_irq,
+ .irq_unmask = enable_macepci_irq,
+};
+
+/* This is used for MACE ISA interrupts. That means bits 4-6 in the
+ * CRIME register.
+ */
+
+#define MACEISA_AUDIO_INT (MACEISA_AUDIO_SW_INT | \
+ MACEISA_AUDIO_SC_INT | \
+ MACEISA_AUDIO1_DMAT_INT | \
+ MACEISA_AUDIO1_OF_INT | \
+ MACEISA_AUDIO2_DMAT_INT | \
+ MACEISA_AUDIO2_MERR_INT | \
+ MACEISA_AUDIO3_DMAT_INT | \
+ MACEISA_AUDIO3_MERR_INT)
+#define MACEISA_MISC_INT (MACEISA_RTC_INT | \
+ MACEISA_KEYB_INT | \
+ MACEISA_KEYB_POLL_INT | \
+ MACEISA_MOUSE_INT | \
+ MACEISA_MOUSE_POLL_INT | \
+ MACEISA_TIMER0_INT | \
+ MACEISA_TIMER1_INT | \
+ MACEISA_TIMER2_INT)
+#define MACEISA_SUPERIO_INT (MACEISA_PARALLEL_INT | \
+ MACEISA_PAR_CTXA_INT | \
+ MACEISA_PAR_CTXB_INT | \
+ MACEISA_PAR_MERR_INT | \
+ MACEISA_SERIAL1_INT | \
+ MACEISA_SERIAL1_TDMAT_INT | \
+ MACEISA_SERIAL1_TDMAPR_INT | \
+ MACEISA_SERIAL1_TDMAME_INT | \
+ MACEISA_SERIAL1_RDMAT_INT | \
+ MACEISA_SERIAL1_RDMAOR_INT | \
+ MACEISA_SERIAL2_INT | \
+ MACEISA_SERIAL2_TDMAT_INT | \
+ MACEISA_SERIAL2_TDMAPR_INT | \
+ MACEISA_SERIAL2_TDMAME_INT | \
+ MACEISA_SERIAL2_RDMAT_INT | \
+ MACEISA_SERIAL2_RDMAOR_INT)
+
+static unsigned long maceisa_mask;
+
+static void enable_maceisa_irq(struct irq_data *d)
+{
+ unsigned int crime_int = 0;
+
+ pr_debug("maceisa enable: %u\n", d->irq);
+
+ switch (d->irq) {
+ case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
+ crime_int = MACE_AUDIO_INT;
+ break;
+ case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ:
+ crime_int = MACE_MISC_INT;
+ break;
+ case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ:
+ crime_int = MACE_SUPERIO_INT;
+ break;
+ }
+ pr_debug("crime_int %08x enabled\n", crime_int);
+ crime_mask |= crime_int;
+ crime->imask = crime_mask;
+ maceisa_mask |= 1 << (d->irq - MACEISA_AUDIO_SW_IRQ);
+ mace->perif.ctrl.imask = maceisa_mask;
+}
+
+static void disable_maceisa_irq(struct irq_data *d)
+{
+ unsigned int crime_int = 0;
+
+ maceisa_mask &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
+ if (!(maceisa_mask & MACEISA_AUDIO_INT))
+ crime_int |= MACE_AUDIO_INT;
+ if (!(maceisa_mask & MACEISA_MISC_INT))
+ crime_int |= MACE_MISC_INT;
+ if (!(maceisa_mask & MACEISA_SUPERIO_INT))
+ crime_int |= MACE_SUPERIO_INT;
+ crime_mask &= ~crime_int;
+ crime->imask = crime_mask;
+ flush_crime_bus();
+ mace->perif.ctrl.imask = maceisa_mask;
+ flush_mace_bus();
+}
+
+static void mask_and_ack_maceisa_irq(struct irq_data *d)
+{
+ unsigned long mace_int;
+
+ /* edge triggered */
+ mace_int = mace->perif.ctrl.istat;
+ mace_int &= ~(1 << (d->irq - MACEISA_AUDIO_SW_IRQ));
+ mace->perif.ctrl.istat = mace_int;
+
+ disable_maceisa_irq(d);
+}
+
+static struct irq_chip ip32_maceisa_level_interrupt = {
+ .name = "IP32 MACE ISA",
+ .irq_mask = disable_maceisa_irq,
+ .irq_unmask = enable_maceisa_irq,
+};
+
+static struct irq_chip ip32_maceisa_edge_interrupt = {
+ .name = "IP32 MACE ISA",
+ .irq_ack = mask_and_ack_maceisa_irq,
+ .irq_mask = disable_maceisa_irq,
+ .irq_mask_ack = mask_and_ack_maceisa_irq,
+ .irq_unmask = enable_maceisa_irq,
+};
+
+/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
+ * bits 0-3 and 7 in the CRIME register.
+ */
+
+static void enable_mace_irq(struct irq_data *d)
+{
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+
+ crime_mask |= (1 << bit);
+ crime->imask = crime_mask;
+}
+
+static void disable_mace_irq(struct irq_data *d)
+{
+ unsigned int bit = d->irq - CRIME_IRQ_BASE;
+
+ crime_mask &= ~(1 << bit);
+ crime->imask = crime_mask;
+ flush_crime_bus();
+}
+
+static struct irq_chip ip32_mace_interrupt = {
+ .name = "IP32 MACE",
+ .irq_mask = disable_mace_irq,
+ .irq_unmask = enable_mace_irq,
+};
+
+static void ip32_unknown_interrupt(void)
+{
+ printk("Unknown interrupt occurred!\n");
+ printk("cp0_status: %08x\n", read_c0_status());
+ printk("cp0_cause: %08x\n", read_c0_cause());
+ printk("CRIME intr mask: %016lx\n", crime->imask);
+ printk("CRIME intr status: %016lx\n", crime->istat);
+ printk("CRIME hardware intr register: %016lx\n", crime->hard_int);
+ printk("MACE ISA intr mask: %08lx\n", mace->perif.ctrl.imask);
+ printk("MACE ISA intr status: %08lx\n", mace->perif.ctrl.istat);
+ printk("MACE PCI control register: %08x\n", mace->pci.control);
+
+ printk("Register dump:\n");
+ show_regs(get_irq_regs());
+
+ printk("Please mail this report to linux-mips@linux-mips.org\n");
+ printk("Spinning...");
+ while(1) ;
+}
+
+/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
+/* change this to loop over all edge-triggered irqs, exception masked out ones */
+static void ip32_irq0(void)
+{
+ uint64_t crime_int;
+ int irq = 0;
+
+ /*
+ * Sanity check interrupt numbering enum.
+ * MACE got 32 interrupts and there are 32 MACE ISA interrupts daisy
+ * chained.
+ */
+ BUILD_BUG_ON(CRIME_VICE_IRQ - MACE_VID_IN1_IRQ != 31);
+ BUILD_BUG_ON(MACEISA_SERIAL2_RDMAOR_IRQ - MACEISA_AUDIO_SW_IRQ != 31);
+
+ crime_int = crime->istat & crime_mask;
+
+ /* crime sometime delivers spurious interrupts, ignore them */
+ if (unlikely(crime_int == 0))
+ return;
+
+ irq = MACE_VID_IN1_IRQ + __ffs(crime_int);
+
+ if (crime_int & CRIME_MACEISA_INT_MASK) {
+ unsigned long mace_int = mace->perif.ctrl.istat;
+ irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
+ }
+
+ pr_debug("*irq %u*\n", irq);
+ do_IRQ(irq);
+}
+
+static void ip32_irq1(void)
+{
+ ip32_unknown_interrupt();
+}
+
+static void ip32_irq2(void)
+{
+ ip32_unknown_interrupt();
+}
+
+static void ip32_irq3(void)
+{
+ ip32_unknown_interrupt();
+}
+
+static void ip32_irq4(void)
+{
+ ip32_unknown_interrupt();
+}
+
+static void ip32_irq5(void)
+{
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause();
+
+ if (likely(pending & IE_IRQ0))
+ ip32_irq0();
+ else if (unlikely(pending & IE_IRQ1))
+ ip32_irq1();
+ else if (unlikely(pending & IE_IRQ2))
+ ip32_irq2();
+ else if (unlikely(pending & IE_IRQ3))
+ ip32_irq3();
+ else if (unlikely(pending & IE_IRQ4))
+ ip32_irq4();
+ else if (likely(pending & IE_IRQ5))
+ ip32_irq5();
+}
+
+void __init arch_init_irq(void)
+{
+ unsigned int irq;
+
+ /* Install our interrupt handler, then clear and disable all
+ * CRIME and MACE interrupts. */
+ crime->imask = 0;
+ crime->hard_int = 0;
+ crime->soft_int = 0;
+ mace->perif.ctrl.istat = 0;
+ mace->perif.ctrl.imask = 0;
+
+ mips_cpu_irq_init();
+ for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
+ switch (irq) {
+ case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &ip32_mace_interrupt,
+ handle_level_irq,
+ "level");
+ break;
+
+ case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &ip32_macepci_interrupt,
+ handle_level_irq,
+ "level");
+ break;
+
+ case CRIME_CPUERR_IRQ:
+ case CRIME_MEMERR_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &crime_level_interrupt,
+ handle_level_irq,
+ "level");
+ break;
+
+ case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
+ case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
+ case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
+ case CRIME_VICE_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &crime_edge_interrupt,
+ handle_edge_irq,
+ "edge");
+ break;
+
+ case MACEISA_PARALLEL_IRQ:
+ case MACEISA_SERIAL1_TDMAPR_IRQ:
+ case MACEISA_SERIAL2_TDMAPR_IRQ:
+ irq_set_chip_and_handler_name(irq,
+ &ip32_maceisa_edge_interrupt,
+ handle_edge_irq,
+ "edge");
+ break;
+
+ default:
+ irq_set_chip_and_handler_name(irq,
+ &ip32_maceisa_level_interrupt,
+ handle_level_irq,
+ "level");
+ break;
+ }
+ }
+ setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
+ setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
+ change_c0_status(ST0_IM, ALLINTS);
+}
diff --git a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c
new file mode 100644
index 00000000..828ce131
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-memory.c
@@ -0,0 +1,48 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Keith M Wesolowski
+ * Copyright (C) 2005 Ilya A. Volynets (Total Knowledge)
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/ip32/crime.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+extern void crime_init(void);
+
+void __init prom_meminit(void)
+{
+ u64 base, size;
+ int bank;
+
+ crime_init();
+
+ for (bank=0; bank < CRIME_MAXBANKS; bank++) {
+ u64 bankctl = crime->bank_ctrl[bank];
+ base = (bankctl & CRIME_MEM_BANK_CONTROL_ADDR) << 25;
+ if (bank != 0 && base == 0)
+ continue;
+ size = (bankctl & CRIME_MEM_BANK_CONTROL_SDRAM_SIZE) ? 128 : 32;
+ size <<= 20;
+ if (base + size > (256 << 20))
+ base += CRIME_HI_MEM_BASE;
+
+ printk("CRIME MC: bank %u base 0x%016Lx size %LuMiB\n",
+ bank, base, size >> 20);
+ add_memory_region(base, size, BOOT_MEM_RAM);
+ }
+}
+
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c
new file mode 100644
index 00000000..511e9ff2
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-platform.c
@@ -0,0 +1,111 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+#define MACEISA_SERIAL1_OFFS offsetof(struct sgi_mace, isa.serial1)
+#define MACEISA_SERIAL2_OFFS offsetof(struct sgi_mace, isa.serial2)
+
+#define MACE_PORT(offset,_irq) \
+{ \
+ .mapbase = MACE_BASE + offset, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_MEM, \
+ .flags = UPF_SKIP_TEST|UPF_IOREMAP, \
+ .regshift = 8, \
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+ MACE_PORT(MACEISA_SERIAL1_OFFS, MACEISA_SERIAL1_IRQ),
+ MACE_PORT(MACEISA_SERIAL2_OFFS, MACEISA_SERIAL2_IRQ),
+ { },
+};
+
+static struct platform_device uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = uart8250_data,
+ },
+};
+
+static int __init uart8250_init(void)
+{
+ return platform_device_register(&uart8250_device);
+}
+
+device_initcall(uart8250_init);
+
+static __init int meth_devinit(void)
+{
+ struct platform_device *pd;
+ int ret;
+
+ pd = platform_device_alloc("meth", -1);
+ if (!pd)
+ return -ENOMEM;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ platform_device_put(pd);
+
+ return ret;
+}
+
+device_initcall(meth_devinit);
+
+static __init int sgio2audio_devinit(void)
+{
+ struct platform_device *pd;
+ int ret;
+
+ pd = platform_device_alloc("sgio2audio", -1);
+ if (!pd)
+ return -ENOMEM;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ platform_device_put(pd);
+
+ return ret;
+}
+
+device_initcall(sgio2audio_devinit);
+
+static __init int sgio2btns_devinit(void)
+{
+ return IS_ERR(platform_device_register_simple("sgibtns", -1, NULL, 0));
+}
+
+device_initcall(sgio2btns_devinit);
+
+static struct resource sgio2_cmos_rsrc[] = {
+ {
+ .start = 0x70,
+ .end = 0x71,
+ .flags = IORESOURCE_IO
+ }
+};
+
+static __init int sgio2_cmos_devinit(void)
+{
+ return IS_ERR(platform_device_register_simple("rtc_cmos", -1,
+ sgio2_cmos_rsrc, 1));
+}
+
+device_initcall(sgio2_cmos_devinit);
+
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2");
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c
new file mode 100644
index 00000000..9b95d80e
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-reset.c
@@ -0,0 +1,205 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Keith M Wesolowski
+ * Copyright (C) 2001 Paul Mundt
+ * Copyright (C) 2003 Guido Guenther <agx@sigxcpu.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/delay.h>
+#include <linux/ds17287rtc.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+
+#include <asm/addrspace.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/wbflush.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/ip32_ints.h>
+
+#define POWERDOWN_TIMEOUT 120
+/*
+ * Blink frequency during reboot grace period and when panicked.
+ */
+#define POWERDOWN_FREQ (HZ / 4)
+#define PANIC_FREQ (HZ / 8)
+
+static struct timer_list power_timer, blink_timer, debounce_timer;
+static int has_panicked, shuting_down;
+
+static void ip32_machine_restart(char *command) __attribute__((noreturn));
+static void ip32_machine_halt(void) __attribute__((noreturn));
+static void ip32_machine_power_off(void) __attribute__((noreturn));
+
+static void ip32_machine_restart(char *cmd)
+{
+ crime->control = CRIME_CONTROL_HARD_RESET;
+ while (1);
+}
+
+static inline void ip32_machine_halt(void)
+{
+ ip32_machine_power_off();
+}
+
+static void ip32_machine_power_off(void)
+{
+ unsigned char reg_a, xctrl_a, xctrl_b;
+
+ disable_irq(MACEISA_RTC_IRQ);
+ reg_a = CMOS_READ(RTC_REG_A);
+
+ /* setup for kickstart & wake-up (DS12287 Ref. Man. p. 19) */
+ reg_a &= ~DS_REGA_DV2;
+ reg_a |= DS_REGA_DV1;
+
+ CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
+ wbflush();
+ xctrl_b = CMOS_READ(DS_B1_XCTRL4B)
+ | DS_XCTRL4B_ABE | DS_XCTRL4B_KFE;
+ CMOS_WRITE(xctrl_b, DS_B1_XCTRL4B);
+ xctrl_a = CMOS_READ(DS_B1_XCTRL4A) & ~DS_XCTRL4A_IFS;
+ CMOS_WRITE(xctrl_a, DS_B1_XCTRL4A);
+ wbflush();
+ /* adios amigos... */
+ CMOS_WRITE(xctrl_a | DS_XCTRL4A_PAB, DS_B1_XCTRL4A);
+ CMOS_WRITE(reg_a, RTC_REG_A);
+ wbflush();
+ while (1);
+}
+
+static void power_timeout(unsigned long data)
+{
+ ip32_machine_power_off();
+}
+
+static void blink_timeout(unsigned long data)
+{
+ unsigned long led = mace->perif.ctrl.misc ^ MACEISA_LED_RED;
+ mace->perif.ctrl.misc = led;
+ mod_timer(&blink_timer, jiffies + data);
+}
+
+static void debounce(unsigned long data)
+{
+ unsigned char reg_a, reg_c, xctrl_a;
+
+ reg_c = CMOS_READ(RTC_INTR_FLAGS);
+ reg_a = CMOS_READ(RTC_REG_A);
+ CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
+ wbflush();
+ xctrl_a = CMOS_READ(DS_B1_XCTRL4A);
+ if ((xctrl_a & DS_XCTRL4A_IFS) || (reg_c & RTC_IRQF )) {
+ /* Interrupt still being sent. */
+ debounce_timer.expires = jiffies + 50;
+ add_timer(&debounce_timer);
+
+ /* clear interrupt source */
+ CMOS_WRITE(xctrl_a & ~DS_XCTRL4A_IFS, DS_B1_XCTRL4A);
+ CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
+ return;
+ }
+ CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
+
+ if (has_panicked)
+ ip32_machine_restart(NULL);
+
+ enable_irq(MACEISA_RTC_IRQ);
+}
+
+static inline void ip32_power_button(void)
+{
+ if (has_panicked)
+ return;
+
+ if (shuting_down || kill_cad_pid(SIGINT, 1)) {
+ /* No init process or button pressed twice. */
+ ip32_machine_power_off();
+ }
+
+ shuting_down = 1;
+ blink_timer.data = POWERDOWN_FREQ;
+ blink_timeout(POWERDOWN_FREQ);
+
+ init_timer(&power_timer);
+ power_timer.function = power_timeout;
+ power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ;
+ add_timer(&power_timer);
+}
+
+static irqreturn_t ip32_rtc_int(int irq, void *dev_id)
+{
+ unsigned char reg_c;
+
+ reg_c = CMOS_READ(RTC_INTR_FLAGS);
+ if (!(reg_c & RTC_IRQF)) {
+ printk(KERN_WARNING
+ "%s: RTC IRQ without RTC_IRQF\n", __func__);
+ }
+ /* Wait until interrupt goes away */
+ disable_irq_nosync(MACEISA_RTC_IRQ);
+ init_timer(&debounce_timer);
+ debounce_timer.function = debounce;
+ debounce_timer.expires = jiffies + 50;
+ add_timer(&debounce_timer);
+
+ printk(KERN_DEBUG "Power button pressed\n");
+ ip32_power_button();
+ return IRQ_HANDLED;
+}
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
+{
+ unsigned long led;
+
+ if (has_panicked)
+ return NOTIFY_DONE;
+ has_panicked = 1;
+
+ /* turn off the green LED */
+ led = mace->perif.ctrl.misc | MACEISA_LED_GREEN;
+ mace->perif.ctrl.misc = led;
+
+ blink_timer.data = PANIC_FREQ;
+ blink_timeout(PANIC_FREQ);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+ .notifier_call = panic_event,
+};
+
+static __init int ip32_reboot_setup(void)
+{
+ /* turn on the green led only */
+ unsigned long led = mace->perif.ctrl.misc;
+ led |= MACEISA_LED_RED;
+ led &= ~MACEISA_LED_GREEN;
+ mace->perif.ctrl.misc = led;
+
+ _machine_restart = ip32_machine_restart;
+ _machine_halt = ip32_machine_halt;
+ pm_power_off = ip32_machine_power_off;
+
+ init_timer(&blink_timer);
+ blink_timer.function = blink_timeout;
+ atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+
+ if (request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL))
+ panic("Can't allocate MACEISA RTC IRQ");
+
+ return 0;
+}
+
+subsys_initcall(ip32_reboot_setup);
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c
new file mode 100644
index 00000000..3abd1465
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-setup.c
@@ -0,0 +1,102 @@
+/*
+ * IP32 basic setup
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000 Harald Koerfgen
+ * Copyright (C) 2002, 2003, 2005 Ilya A. Volynets
+ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/param.h>
+#include <linux/sched.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mc146818-time.h>
+#include <asm/mipsregs.h>
+#include <asm/mmu_context.h>
+#include <asm/sgialib.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+#include <asm/io.h>
+#include <asm/ip32/crime.h>
+#include <asm/ip32/mace.h>
+#include <asm/ip32/ip32_ints.h>
+
+extern void ip32_be_init(void);
+extern void crime_init(void);
+
+#ifdef CONFIG_SGI_O2MACE_ETH
+/*
+ * This is taken care of in here 'cause they say using Arc later on is
+ * problematic
+ */
+extern char o2meth_eaddr[8];
+static inline unsigned char str2hexnum(unsigned char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ return 0; /* foo */
+}
+
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
+{
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ unsigned char num;
+
+ if(*str == ':')
+ str++;
+ num = str2hexnum(*str++) << 4;
+ num |= (str2hexnum(*str++));
+ ea[i] = num;
+ }
+}
+#endif
+
+/* An arbitrary time; this can be decreased if reliability looks good */
+#define WAIT_MS 10
+
+void __init plat_time_init(void)
+{
+ printk(KERN_INFO "Calibrating system timer... ");
+ write_c0_count(0);
+ crime->timer = 0;
+ while (crime->timer < CRIME_MASTER_FREQ * WAIT_MS / 1000) ;
+ mips_hpt_frequency = read_c0_count() * 1000 / WAIT_MS;
+ printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000);
+}
+
+void __init plat_mem_setup(void)
+{
+ board_be_init = ip32_be_init;
+
+#ifdef CONFIG_SGI_O2MACE_ETH
+ {
+ char *mac = ArcGetEnvironmentVariable("eaddr");
+ str2eaddr(o2meth_eaddr, mac);
+ }
+#endif
+
+#if defined(CONFIG_SERIAL_CORE_CONSOLE)
+ {
+ char* con = ArcGetEnvironmentVariable("console");
+ if (con && *con == 'd') {
+ static char options[8] __initdata;
+ char *baud = ArcGetEnvironmentVariable("dbaud");
+ if (baud)
+ strcpy(options, baud);
+ add_preferred_console("ttyS", *(con + 1) == '2' ? 1 : 0,
+ baud ? options : NULL);
+ }
+ }
+#endif
+}
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
new file mode 100644
index 00000000..3e639bda
--- /dev/null
+++ b/arch/mips/sibyte/Kconfig
@@ -0,0 +1,171 @@
+config SIBYTE_SB1250
+ bool
+ select CEVT_SB1250
+ select CSRC_SB1250
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SIBYTE_ENABLE_LDT_IF_PCI
+ select SIBYTE_HAS_ZBUS_PROFILING
+ select SIBYTE_SB1xxx_SOC
+ select SYS_SUPPORTS_SMP
+
+config SIBYTE_BCM1120
+ bool
+ select CEVT_SB1250
+ select CSRC_SB1250
+ select IRQ_CPU
+ select SIBYTE_BCM112X
+ select SIBYTE_HAS_ZBUS_PROFILING
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1125
+ bool
+ select CEVT_SB1250
+ select CSRC_SB1250
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SIBYTE_BCM112X
+ select SIBYTE_HAS_ZBUS_PROFILING
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM1125H
+ bool
+ select CEVT_SB1250
+ select CSRC_SB1250
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SIBYTE_BCM112X
+ select SIBYTE_ENABLE_LDT_IF_PCI
+ select SIBYTE_HAS_ZBUS_PROFILING
+ select SIBYTE_SB1xxx_SOC
+
+config SIBYTE_BCM112X
+ bool
+ select CEVT_SB1250
+ select CSRC_SB1250
+ select IRQ_CPU
+ select SIBYTE_SB1xxx_SOC
+ select SIBYTE_HAS_ZBUS_PROFILING
+
+config SIBYTE_BCM1x80
+ bool
+ select CEVT_BCM1480
+ select CSRC_BCM1480
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SIBYTE_HAS_ZBUS_PROFILING
+ select SIBYTE_SB1xxx_SOC
+ select SYS_SUPPORTS_SMP
+
+config SIBYTE_BCM1x55
+ bool
+ select CEVT_BCM1480
+ select CSRC_BCM1480
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select SIBYTE_SB1xxx_SOC
+ select SIBYTE_HAS_ZBUS_PROFILING
+ select SYS_SUPPORTS_SMP
+
+config SIBYTE_SB1xxx_SOC
+ bool
+ select DMA_COHERENT
+ select IRQ_CPU
+ select SIBYTE_CFE
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select CFE
+ select SYS_HAS_EARLY_PRINTK
+
+choice
+ prompt "SiByte SOC Stepping"
+ depends on SIBYTE_SB1xxx_SOC
+
+config CPU_SB1_PASS_1
+ bool "1250 Pass1"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+
+config CPU_SB1_PASS_2_1250
+ bool "1250 An"
+ depends on SIBYTE_SB1250
+ select CPU_SB1_PASS_2
+ help
+ Also called BCM1250 Pass 2
+
+config CPU_SB1_PASS_2_2
+ bool "1250 Bn"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+ help
+ Also called BCM1250 Pass 2.2
+
+config CPU_SB1_PASS_4
+ bool "1250 Cn"
+ depends on SIBYTE_SB1250
+ select CPU_HAS_PREFETCH
+ help
+ Also called BCM1250 Pass 3
+
+config CPU_SB1_PASS_2_112x
+ bool "112x Hybrid"
+ depends on SIBYTE_BCM112X
+ select CPU_SB1_PASS_2
+
+config CPU_SB1_PASS_3
+ bool "112x An"
+ depends on SIBYTE_BCM112X
+ select CPU_HAS_PREFETCH
+
+endchoice
+
+config CPU_SB1_PASS_2
+ bool
+
+config SIBYTE_HAS_LDT
+ bool
+
+config SIBYTE_ENABLE_LDT_IF_PCI
+ bool
+ select SIBYTE_HAS_LDT if PCI
+
+config SB1_CEX_ALWAYS_FATAL
+ bool "All cache exceptions considered fatal (no recovery attempted)"
+ depends on SIBYTE_SB1xxx_SOC
+
+config SB1_CERR_STALL
+ bool "Stall (rather than panic) on fatal cache error"
+ depends on SIBYTE_SB1xxx_SOC
+
+config SIBYTE_CFE_CONSOLE
+ bool "Use firmware console"
+ depends on SIBYTE_SB1xxx_SOC
+ help
+ Use the CFE API's console write routines during boot. Other console
+ options (VT console, sb1250 duart console, etc.) should not be
+ configured.
+
+config SIBYTE_BUS_WATCHER
+ bool "Support for Bus Watcher statistics"
+ depends on SIBYTE_SB1xxx_SOC
+ help
+ Handle and keep statistics on the bus error interrupts (COR_ECC,
+ BAD_ECC, IO_BUS).
+
+config SIBYTE_BW_TRACE
+ bool "Capture bus trace before bus error"
+ depends on SIBYTE_BUS_WATCHER
+ help
+ Run a continuous bus trace, dumping the raw data as soon as
+ a ZBbus error is detected. Cannot work if ZBbus profiling
+ is turned on, and also will interfere with JTAG-based trace
+ buffer activity. Raw buffer data is dumped to console, and
+ must be processed off-line.
+
+config SIBYTE_TBPROF
+ tristate "Support for ZBbus profiling"
+ depends on SIBYTE_HAS_ZBUS_PROFILING
+
+config SIBYTE_HAS_ZBUS_PROFILING
+ bool
diff --git a/arch/mips/sibyte/Makefile b/arch/mips/sibyte/Makefile
new file mode 100644
index 00000000..c8ed2c80
--- /dev/null
+++ b/arch/mips/sibyte/Makefile
@@ -0,0 +1,27 @@
+#
+# Sibyte SB1250 / BCM1480 family of SOCs
+#
+obj-$(CONFIG_SIBYTE_BCM112X) += sb1250/
+obj-$(CONFIG_SIBYTE_BCM112X) += common/
+obj-$(CONFIG_SIBYTE_SB1250) += sb1250/
+obj-$(CONFIG_SIBYTE_SB1250) += common/
+obj-$(CONFIG_SIBYTE_BCM1x55) += bcm1480/
+obj-$(CONFIG_SIBYTE_BCM1x55) += common/
+obj-$(CONFIG_SIBYTE_BCM1x80) += bcm1480/
+obj-$(CONFIG_SIBYTE_BCM1x80) += common/
+
+#
+# Sibyte BCM91120x (Carmel) board
+# Sibyte BCM91120C (CRhine) board
+# Sibyte BCM91125C (CRhone) board
+# Sibyte BCM91125E (Rhone) board
+# Sibyte SWARM board
+# Sibyte BCM91x80 (BigSur) board
+#
+obj-$(CONFIG_SIBYTE_CARMEL) += swarm/
+obj-$(CONFIG_SIBYTE_CRHINE) += swarm/
+obj-$(CONFIG_SIBYTE_CRHONE) += swarm/
+obj-$(CONFIG_SIBYTE_RHONE) += swarm/
+obj-$(CONFIG_SIBYTE_SENTOSA) += swarm/
+obj-$(CONFIG_SIBYTE_SWARM) += swarm/
+obj-$(CONFIG_SIBYTE_BIGSUR) += swarm/
diff --git a/arch/mips/sibyte/Platform b/arch/mips/sibyte/Platform
new file mode 100644
index 00000000..911dfe39
--- /dev/null
+++ b/arch/mips/sibyte/Platform
@@ -0,0 +1,43 @@
+#
+# These are all rather similar so we consider them a single platform
+#
+platform-$(CONFIG_SIBYTE_BCM112X) += sibyte/
+platform-$(CONFIG_SIBYTE_SB1250) += sibyte/
+platform-$(CONFIG_SIBYTE_BCM1x55) += sibyte/
+platform-$(CONFIG_SIBYTE_BCM1x80) += sibyte/
+
+#
+# Sibyte SB1250 / BCM1480 family of SOCs
+#
+cflags-$(CONFIG_SIBYTE_BCM112X) += \
+ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+
+platform-$(CONFIG_SIBYTE_SB1250) += sibyte/
+cflags-$(CONFIG_SIBYTE_SB1250) += \
+ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+
+cflags-$(CONFIG_SIBYTE_BCM1x55) += \
+ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+
+cflags-$(CONFIG_SIBYTE_BCM1x80) += \
+ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+
+#
+# Sibyte BCM91120x (Carmel) board
+# Sibyte BCM91120C (CRhine) board
+# Sibyte BCM91125C (CRhone) board
+# Sibyte BCM91125E (Rhone) board
+# Sibyte SWARM board
+# Sibyte BCM91x80 (BigSur) board
+#
+load-$(CONFIG_SIBYTE_CARMEL) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_CRHINE) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_CRHONE) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_RHONE) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_SENTOSA) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_SWARM) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile
new file mode 100644
index 00000000..cdc4c56c
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/Makefile
@@ -0,0 +1,3 @@
+obj-y := setup.o irq.o time.o
+
+obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
new file mode 100644
index 00000000..09740d60
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/errno.h>
+#include <asm/irq_regs.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+#include <asm/sibyte/bcm1480_scd.h>
+
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250.h>
+
+/*
+ * These are the routines that handle all the low level interrupt stuff.
+ * Actions handled here are: initialization of the interrupt map, requesting of
+ * interrupt lines by handlers, dispatching if interrupts to handlers, probing
+ * for interrupt lines
+ */
+
+#ifdef CONFIG_PCI
+extern unsigned long ht_eoi_space;
+#endif
+
+/* Store the CPU id (not the logical number) */
+int bcm1480_irq_owner[BCM1480_NR_IRQS];
+
+static DEFINE_RAW_SPINLOCK(bcm1480_imr_lock);
+
+void bcm1480_mask_irq(int cpu, int irq)
+{
+ unsigned long flags, hl_spacing;
+ u64 cur_ints;
+
+ raw_spin_lock_irqsave(&bcm1480_imr_lock, flags);
+ hl_spacing = 0;
+ if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
+ hl_spacing = BCM1480_IMR_HL_SPACING;
+ irq -= BCM1480_NR_IRQS_HALF;
+ }
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ cur_ints |= (((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ raw_spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+}
+
+void bcm1480_unmask_irq(int cpu, int irq)
+{
+ unsigned long flags, hl_spacing;
+ u64 cur_ints;
+
+ raw_spin_lock_irqsave(&bcm1480_imr_lock, flags);
+ hl_spacing = 0;
+ if ((irq >= BCM1480_NR_IRQS_HALF) && (irq <= BCM1480_NR_IRQS)) {
+ hl_spacing = BCM1480_IMR_HL_SPACING;
+ irq -= BCM1480_NR_IRQS_HALF;
+ }
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ cur_ints &= ~(((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + hl_spacing));
+ raw_spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static int bcm1480_set_affinity(struct irq_data *d, const struct cpumask *mask,
+ bool force)
+{
+ unsigned int irq_dirty, irq = d->irq;
+ int i = 0, old_cpu, cpu, int_on, k;
+ u64 cur_ints;
+ unsigned long flags;
+
+ i = cpumask_first(mask);
+
+ /* Convert logical CPU to physical CPU */
+ cpu = cpu_logical_map(i);
+
+ /* Protect against other affinity changers and IMR manipulation */
+ raw_spin_lock_irqsave(&bcm1480_imr_lock, flags);
+
+ /* Swizzle each CPU's IMR (but leave the IP selection alone) */
+ old_cpu = bcm1480_irq_owner[irq];
+ irq_dirty = irq;
+ if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
+ irq_dirty -= BCM1480_NR_IRQS_HALF;
+ }
+
+ for (k=0; k<2; k++) { /* Loop through high and low interrupt mask register */
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ int_on = !(cur_ints & (((u64) 1) << irq_dirty));
+ if (int_on) {
+ /* If it was on, mask it */
+ cur_ints |= (((u64) 1) << irq_dirty);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(old_cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ }
+ bcm1480_irq_owner[irq] = cpu;
+ if (int_on) {
+ /* unmask for the new CPU */
+ cur_ints = ____raw_readq(IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ cur_ints &= ~(((u64) 1) << irq_dirty);
+ ____raw_writeq(cur_ints, IOADDR(A_BCM1480_IMR_MAPPER(cpu) + R_BCM1480_IMR_INTERRUPT_MASK_H + (k*BCM1480_IMR_HL_SPACING)));
+ }
+ }
+ raw_spin_unlock_irqrestore(&bcm1480_imr_lock, flags);
+
+ return 0;
+}
+#endif
+
+
+/*****************************************************************************/
+
+static void disable_bcm1480_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+static void enable_bcm1480_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+
+static void ack_bcm1480_irq(struct irq_data *d)
+{
+ unsigned int irq_dirty, irq = d->irq;
+ u64 pending;
+ int k;
+
+ /*
+ * If the interrupt was an HT interrupt, now is the time to
+ * clear it. NOTE: we assume the HT bridge was set up to
+ * deliver the interrupts to all CPUs (which makes affinity
+ * changing easier for us)
+ */
+ irq_dirty = irq;
+ if ((irq_dirty >= BCM1480_NR_IRQS_HALF) && (irq_dirty <= BCM1480_NR_IRQS)) {
+ irq_dirty -= BCM1480_NR_IRQS_HALF;
+ }
+ for (k=0; k<2; k++) { /* Loop through high and low LDT interrupts */
+ pending = __raw_readq(IOADDR(A_BCM1480_IMR_REGISTER(bcm1480_irq_owner[irq],
+ R_BCM1480_IMR_LDT_INTERRUPT_H + (k*BCM1480_IMR_HL_SPACING))));
+ pending &= ((u64)1 << (irq_dirty));
+ if (pending) {
+#ifdef CONFIG_SMP
+ int i;
+ for (i=0; i<NR_CPUS; i++) {
+ /*
+ * Clear for all CPUs so an affinity switch
+ * doesn't find an old status
+ */
+ __raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(cpu_logical_map(i),
+ R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING))));
+ }
+#else
+ __raw_writeq(pending, IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_LDT_INTERRUPT_CLR_H + (k*BCM1480_IMR_HL_SPACING))));
+#endif
+
+ /*
+ * Generate EOI. For Pass 1 parts, EOI is a nop. For
+ * Pass 2, the LDT world may be edge-triggered, but
+ * this EOI shouldn't hurt. If they are
+ * level-sensitive, the EOI is required.
+ */
+#ifdef CONFIG_PCI
+ if (ht_eoi_space)
+ *(uint32_t *)(ht_eoi_space+(irq<<16)+(7<<2)) = 0;
+#endif
+ }
+ }
+ bcm1480_mask_irq(bcm1480_irq_owner[irq], irq);
+}
+
+static struct irq_chip bcm1480_irq_type = {
+ .name = "BCM1480-IMR",
+ .irq_mask_ack = ack_bcm1480_irq,
+ .irq_mask = disable_bcm1480_irq,
+ .irq_unmask = enable_bcm1480_irq,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = bcm1480_set_affinity
+#endif
+};
+
+void __init init_bcm1480_irqs(void)
+{
+ int i;
+
+ for (i = 0; i < BCM1480_NR_IRQS; i++) {
+ irq_set_chip_and_handler(i, &bcm1480_irq_type,
+ handle_level_irq);
+ bcm1480_irq_owner[i] = 0;
+ }
+}
+
+/*
+ * init_IRQ is called early in the boot sequence from init/main.c. It
+ * is responsible for setting up the interrupt mapper and installing the
+ * handler that will be responsible for dispatching interrupts to the
+ * "right" place.
+ */
+/*
+ * For now, map all interrupts to IP[2]. We could save
+ * some cycles by parceling out system interrupts to different
+ * IP lines, but keep it simple for bringup. We'll also direct
+ * all interrupts to a single CPU; we should probably route
+ * PCI and LDT to one cpu and everything else to the other
+ * to balance the load a bit.
+ *
+ * On the second cpu, everything is set to IP5, which is
+ * ignored, EXCEPT the mailbox interrupt. That one is
+ * set to IP[2] so it is handled. This is needed so we
+ * can do cross-cpu function calls, as required by SMP
+ */
+
+#define IMR_IP2_VAL K_BCM1480_INT_MAP_I0
+#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
+#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
+#define IMR_IP5_VAL K_BCM1480_INT_MAP_I3
+#define IMR_IP6_VAL K_BCM1480_INT_MAP_I4
+
+void __init arch_init_irq(void)
+{
+ unsigned int i, cpu;
+ u64 tmp;
+ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+ STATUSF_IP1 | STATUSF_IP0;
+
+ /* Default everything to IP2 */
+ /* Start with _high registers which has no bit 0 interrupt source */
+ for (i = 1; i < BCM1480_NR_IRQS_HALF; i++) { /* was I0 */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+ R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (i << 3)));
+ }
+ }
+
+ /* Now do _low registers */
+ for (i = 0; i < BCM1480_NR_IRQS_HALF; i++) {
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+ R_BCM1480_IMR_INTERRUPT_MAP_BASE_L) + (i << 3)));
+ }
+ }
+
+ init_bcm1480_irqs();
+
+ /*
+ * Map the high 16 bits of mailbox_0 registers to IP[3], for
+ * inter-cpu messages
+ */
+ /* Was I1 */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(IMR_IP3_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
+ (K_BCM1480_INT_MBOX_0_0 << 3)));
+ }
+
+
+ /* Clear the mailboxes. The firmware may leave them dirty */
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_0_CLR_CPU)));
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_MAILBOX_1_CLR_CPU)));
+ }
+
+
+ /* Mask everything except the high 16 bit of mailbox_0 registers for all cpus */
+ tmp = ~((u64) 0) ^ ( (((u64) 1) << K_BCM1480_INT_MBOX_0_0));
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_H)));
+ }
+ tmp = ~((u64) 0);
+ for (cpu = 0; cpu < 4; cpu++) {
+ __raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L)));
+ }
+
+ /*
+ * Note that the timer interrupts are also mapped, but this is
+ * done in bcm1480_time_init(). Also, the profiling driver
+ * does its own management of IP7.
+ */
+
+ /* Enable necessary IPs, disable the rest */
+ change_c0_status(ST0_IM, imask);
+}
+
+extern void bcm1480_mailbox_interrupt(void);
+
+static inline void dispatch_ip2(void)
+{
+ unsigned long long mask_h, mask_l;
+ unsigned int cpu = smp_processor_id();
+ unsigned long base;
+
+ /*
+ * Default...we've hit an IP[2] interrupt, which means we've got to
+ * check the 1480 interrupt registers to figure out what to do. Need
+ * to detect which CPU we're on, now that smp_affinity is supported.
+ */
+ base = A_BCM1480_IMR_MAPPER(cpu);
+ mask_h = __raw_readq(
+ IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
+ mask_l = __raw_readq(
+ IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
+
+ if (mask_h) {
+ if (mask_h ^ 1)
+ do_IRQ(fls64(mask_h) - 1);
+ else if (mask_l)
+ do_IRQ(63 + fls64(mask_l));
+ }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned int pending;
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+ /* Set compare to count to silence count/compare timer interrupts */
+ write_c0_compare(read_c0_count());
+#endif
+
+ pending = read_c0_cause() & read_c0_status();
+
+#ifdef CONFIG_SIBYTE_BCM1480_PROF
+ if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
+ sbprof_cpu_intr();
+ else
+#endif
+
+ if (pending & CAUSEF_IP4)
+ do_IRQ(K_BCM1480_INT_TIMER_0 + cpu);
+#ifdef CONFIG_SMP
+ else if (pending & CAUSEF_IP3)
+ bcm1480_mailbox_interrupt();
+#endif
+
+ else if (pending & CAUSEF_IP2)
+ dispatch_ip2();
+}
diff --git a/arch/mips/sibyte/bcm1480/setup.c b/arch/mips/sibyte/bcm1480/setup.c
new file mode 100644
index 00000000..05ed92c9
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/setup.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+unsigned int sb1_pass;
+unsigned int soc_pass;
+unsigned int soc_type;
+EXPORT_SYMBOL(soc_type);
+unsigned int periph_rev;
+unsigned int zbbus_mhz;
+EXPORT_SYMBOL(zbbus_mhz);
+
+static unsigned int part_type;
+
+static char *soc_str;
+static char *pass_str;
+
+static int __init setup_bcm1x80_bcm1x55(void)
+{
+ int ret = 0;
+
+ switch (soc_pass) {
+ case K_SYS_REVISION_BCM1480_S0:
+ periph_rev = 1;
+ pass_str = "S0 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A1:
+ periph_rev = 1;
+ pass_str = "A1 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A2:
+ periph_rev = 1;
+ pass_str = "A2 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_A3:
+ periph_rev = 1;
+ pass_str = "A3 (pass1)";
+ break;
+ case K_SYS_REVISION_BCM1480_B0:
+ periph_rev = 1;
+ pass_str = "B0 (pass2)";
+ break;
+ default:
+ printk("Unknown %s rev %x\n", soc_str, soc_pass);
+ periph_rev = 1;
+ pass_str = "Unknown Revision";
+ break;
+ }
+
+ return ret;
+}
+
+/* Setup code likely to be common to all SiByte platforms */
+
+static int __init sys_rev_decode(void)
+{
+ int ret = 0;
+
+ switch (soc_type) {
+ case K_SYS_SOC_TYPE_BCM1x80:
+ if (part_type == K_SYS_PART_BCM1480)
+ soc_str = "BCM1480";
+ else if (part_type == K_SYS_PART_BCM1280)
+ soc_str = "BCM1280";
+ else
+ soc_str = "BCM1x80";
+ ret = setup_bcm1x80_bcm1x55();
+ break;
+
+ case K_SYS_SOC_TYPE_BCM1x55:
+ if (part_type == K_SYS_PART_BCM1455)
+ soc_str = "BCM1455";
+ else if (part_type == K_SYS_PART_BCM1255)
+ soc_str = "BCM1255";
+ else
+ soc_str = "BCM1x55";
+ ret = setup_bcm1x80_bcm1x55();
+ break;
+
+ default:
+ printk("Unknown part type %x\n", part_type);
+ ret = 1;
+ break;
+ }
+
+ return ret;
+}
+
+void __init bcm1480_setup(void)
+{
+ uint64_t sys_rev;
+ int plldiv;
+
+ sb1_pass = read_c0_prid() & 0xff;
+ sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+ soc_type = SYS_SOC_TYPE(sys_rev);
+ part_type = G_SYS_PART(sys_rev);
+ soc_pass = G_SYS_REVISION(sys_rev);
+
+ if (sys_rev_decode()) {
+ printk("Restart after failure to identify SiByte chip\n");
+ machine_restart(NULL);
+ }
+
+ plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
+
+ printk("Broadcom SiByte %s %s @ %d MHz (SB-1A rev %d)\n",
+ soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
+ printk("Board type: %s\n", get_system_type());
+}
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
new file mode 100644
index 00000000..d667875b
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2001,2002,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/fw/cfe/cfe_api.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_int.h>
+
+extern void smp_call_function_interrupt(void);
+
+/*
+ * These are routines for dealing with the bcm1480 smp capabilities
+ * independent of board/firmware
+ */
+
+static void *mailbox_0_set_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU),
+};
+
+static void *mailbox_0_clear_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU),
+};
+
+static void *mailbox_0_regs[] = {
+ IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+ IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CPU),
+};
+
+/*
+ * SMP init and finish on secondary CPUs
+ */
+void __cpuinit bcm1480_smp_init(void)
+{
+ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+ STATUSF_IP1 | STATUSF_IP0;
+
+ /* Set interrupt mask, but don't enable */
+ change_c0_status(ST0_IM, imask);
+}
+
+/*
+ * These are routines for dealing with the sb1250 smp capabilities
+ * independent of board/firmware
+ */
+
+/*
+ * Simple enough; everything is set up, so just poke the appropriate mailbox
+ * register, and we should be set
+ */
+static void bcm1480_send_ipi_single(int cpu, unsigned int action)
+{
+ __raw_writeq((((u64)action)<< 48), mailbox_0_set_regs[cpu]);
+}
+
+static void bcm1480_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ bcm1480_send_ipi_single(i, action);
+}
+
+/*
+ * Code to run on secondary just after probing the CPU
+ */
+static void __cpuinit bcm1480_init_secondary(void)
+{
+ extern void bcm1480_smp_init(void);
+
+ bcm1480_smp_init();
+}
+
+/*
+ * Do any tidying up before marking online and running the idle
+ * loop
+ */
+static void __cpuinit bcm1480_smp_finish(void)
+{
+ extern void sb1480_clockevent_init(void);
+
+ sb1480_clockevent_init();
+ local_irq_enable();
+}
+
+/*
+ * Final cleanup after all secondaries booted
+ */
+static void bcm1480_cpus_done(void)
+{
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ */
+static void __cpuinit bcm1480_boot_secondary(int cpu, struct task_struct *idle)
+{
+ int retval;
+
+ retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
+ __KSTK_TOS(idle),
+ (unsigned long)task_thread_info(idle), 0);
+ if (retval != 0)
+ printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+}
+
+/*
+ * Use CFE to find out how many CPUs are available, setting up
+ * cpu_possible_map and the logical/physical mappings.
+ * XXXKW will the boot CPU ever not be physical 0?
+ *
+ * Common setup before any secondaries are started
+ */
+static void __init bcm1480_smp_setup(void)
+{
+ int i, num;
+
+ cpus_clear(cpu_possible_map);
+ cpu_set(0, cpu_possible_map);
+ __cpu_number_map[0] = 0;
+ __cpu_logical_map[0] = 0;
+
+ for (i = 1, num = 0; i < NR_CPUS; i++) {
+ if (cfe_cpu_stop(i) == 0) {
+ cpu_set(i, cpu_possible_map);
+ __cpu_number_map[i] = ++num;
+ __cpu_logical_map[num] = i;
+ }
+ }
+ printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
+}
+
+static void __init bcm1480_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+struct plat_smp_ops bcm1480_smp_ops = {
+ .send_ipi_single = bcm1480_send_ipi_single,
+ .send_ipi_mask = bcm1480_send_ipi_mask,
+ .init_secondary = bcm1480_init_secondary,
+ .smp_finish = bcm1480_smp_finish,
+ .cpus_done = bcm1480_cpus_done,
+ .boot_secondary = bcm1480_boot_secondary,
+ .smp_setup = bcm1480_smp_setup,
+ .prepare_cpus = bcm1480_prepare_cpus,
+};
+
+void bcm1480_mailbox_interrupt(void)
+{
+ int cpu = smp_processor_id();
+ int irq = K_BCM1480_INT_MBOX_0_0;
+ unsigned int action;
+
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+ /* Load the mailbox register to figure out what we're supposed to do */
+ action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff;
+
+ /* Clear the mailbox to clear the interrupt */
+ __raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
+
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
+
+ if (action & SMP_CALL_FUNCTION)
+ smp_call_function_interrupt();
+}
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
new file mode 100644
index 00000000..1680a689
--- /dev/null
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2000,2001,2004 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+
+extern void sb1480_clockevent_init(void);
+extern void sb1480_clocksource_init(void);
+
+void __init plat_time_init(void)
+{
+ sb1480_clocksource_init();
+ sb1480_clockevent_init();
+}
diff --git a/arch/mips/sibyte/common/Makefile b/arch/mips/sibyte/common/Makefile
new file mode 100644
index 00000000..36aa700c
--- /dev/null
+++ b/arch/mips/sibyte/common/Makefile
@@ -0,0 +1,3 @@
+obj-y := cfe.o
+obj-$(CONFIG_SIBYTE_CFE_CONSOLE) += cfe_console.o
+obj-$(CONFIG_SIBYTE_TBPROF) += sb_tbprof.o
diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c
new file mode 100644
index 00000000..6343011e
--- /dev/null
+++ b/arch/mips/sibyte/common/cfe.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/blkdev.h>
+#include <linux/bootmem.h>
+#include <linux/pm.h>
+#include <linux/smp.h>
+
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/sibyte/board.h>
+#include <asm/smp-ops.h>
+
+#include <asm/fw/cfe/cfe_api.h>
+#include <asm/fw/cfe/cfe_error.h>
+
+/* Max ram addressable in 32-bit segments */
+#ifdef CONFIG_64BIT
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_64BIT_PHYS_ADDR
+#define MAX_RAM_SIZE (~0ULL)
+#else
+#define MAX_RAM_SIZE (0xffffffffULL)
+#endif
+#else
+#define MAX_RAM_SIZE (0x1fffffffULL)
+#endif
+#endif
+
+#define SIBYTE_MAX_MEM_REGIONS 8
+phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS];
+phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS];
+unsigned int board_mem_region_count;
+
+int cfe_cons_handle;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+#endif
+
+static void __noreturn cfe_linux_exit(void *arg)
+{
+ int warm = *(int *)arg;
+
+ if (smp_processor_id()) {
+ static int reboot_smp;
+
+ /* Don't repeat the process from another CPU */
+ if (!reboot_smp) {
+ /* Get CPU 0 to do the cfe_exit */
+ reboot_smp = 1;
+ smp_call_function(cfe_linux_exit, arg, 0);
+ }
+ } else {
+ printk("Passing control back to CFE...\n");
+ cfe_exit(warm, 0);
+ printk("cfe_exit returned??\n");
+ }
+ while (1);
+}
+
+static void __noreturn cfe_linux_restart(char *command)
+{
+ static const int zero;
+
+ cfe_linux_exit((void *)&zero);
+}
+
+static void __noreturn cfe_linux_halt(void)
+{
+ static const int one = 1;
+
+ cfe_linux_exit((void *)&one);
+}
+
+static __init void prom_meminit(void)
+{
+ u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */
+ int mem_flags = 0;
+ unsigned int idx;
+ int rd_flag;
+#ifdef CONFIG_BLK_DEV_INITRD
+ unsigned long initrd_pstart;
+ unsigned long initrd_pend;
+
+ initrd_pstart = CPHYSADDR(initrd_start);
+ initrd_pend = CPHYSADDR(initrd_end);
+ if (initrd_start &&
+ ((initrd_pstart > MAX_RAM_SIZE)
+ || (initrd_pend > MAX_RAM_SIZE))) {
+ panic("initrd out of addressable memory");
+ }
+
+#endif /* INITRD */
+
+ for (idx = 0; cfe_enummem(idx, mem_flags, &addr, &size, &type) != CFE_ERR_NOMORE;
+ idx++) {
+ rd_flag = 0;
+ if (type == CFE_MI_AVAILABLE) {
+ /*
+ * See if this block contains (any portion of) the
+ * ramdisk
+ */
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start) {
+ if ((initrd_pstart > addr) &&
+ (initrd_pstart < (addr + size))) {
+ add_memory_region(addr,
+ initrd_pstart - addr,
+ BOOT_MEM_RAM);
+ rd_flag = 1;
+ }
+ if ((initrd_pend > addr) &&
+ (initrd_pend < (addr + size))) {
+ add_memory_region(initrd_pend,
+ (addr + size) - initrd_pend,
+ BOOT_MEM_RAM);
+ rd_flag = 1;
+ }
+ }
+#endif
+ if (!rd_flag) {
+ if (addr > MAX_RAM_SIZE)
+ continue;
+ if (addr+size > MAX_RAM_SIZE)
+ size = MAX_RAM_SIZE - (addr+size) + 1;
+ /*
+ * memcpy/__copy_user prefetch, which
+ * will cause a bus error for
+ * KSEG/KUSEG addrs not backed by RAM.
+ * Hence, reserve some padding for the
+ * prefetch distance.
+ */
+ if (size > 512)
+ size -= 512;
+ add_memory_region(addr, size, BOOT_MEM_RAM);
+ }
+ board_mem_region_addrs[board_mem_region_count] = addr;
+ board_mem_region_sizes[board_mem_region_count] = size;
+ board_mem_region_count++;
+ if (board_mem_region_count ==
+ SIBYTE_MAX_MEM_REGIONS) {
+ /*
+ * Too many regions. Need to configure more
+ */
+ while(1);
+ }
+ }
+ }
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start) {
+ add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
+ BOOT_MEM_RESERVED);
+ }
+#endif
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+static int __init initrd_setup(char *str)
+{
+ char rdarg[64];
+ int idx;
+ char *tmp, *endptr;
+ unsigned long initrd_size;
+
+ /* Make a copy of the initrd argument so we can smash it up here */
+ for (idx = 0; idx < sizeof(rdarg)-1; idx++) {
+ if (!str[idx] || (str[idx] == ' ')) break;
+ rdarg[idx] = str[idx];
+ }
+
+ rdarg[idx] = 0;
+ str = rdarg;
+
+ /*
+ *Initrd location comes in the form "<hex size of ramdisk in bytes>@<location in memory>"
+ * e.g. initrd=3abfd@80010000. This is set up by the loader.
+ */
+ for (tmp = str; *tmp != '@'; tmp++) {
+ if (!*tmp) {
+ goto fail;
+ }
+ }
+ *tmp = 0;
+ tmp++;
+ if (!*tmp) {
+ goto fail;
+ }
+ initrd_size = simple_strtoul(str, &endptr, 16);
+ if (*endptr) {
+ *(tmp-1) = '@';
+ goto fail;
+ }
+ *(tmp-1) = '@';
+ initrd_start = simple_strtoul(tmp, &endptr, 16);
+ if (*endptr) {
+ goto fail;
+ }
+ initrd_end = initrd_start + initrd_size;
+ printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start);
+ return 1;
+ fail:
+ printk("Bad initrd argument. Disabling initrd\n");
+ initrd_start = 0;
+ initrd_end = 0;
+ return 1;
+}
+
+#endif
+
+extern struct plat_smp_ops sb_smp_ops;
+extern struct plat_smp_ops bcm1480_smp_ops;
+
+/*
+ * prom_init is called just after the cpu type is determined, from setup_arch()
+ */
+void __init prom_init(void)
+{
+ uint64_t cfe_ept, cfe_handle;
+ unsigned int cfe_eptseal;
+ int argc = fw_arg0;
+ char **envp = (char **) fw_arg2;
+ int *prom_vec = (int *) fw_arg3;
+
+ _machine_restart = cfe_linux_restart;
+ _machine_halt = cfe_linux_halt;
+ pm_power_off = cfe_linux_halt;
+
+ /*
+ * Check if a loader was used; if NOT, the 4 arguments are
+ * what CFE gives us (handle, 0, EPT and EPTSEAL)
+ */
+ if (argc < 0) {
+ cfe_handle = (uint64_t)(long)argc;
+ cfe_ept = (long)envp;
+ cfe_eptseal = (uint32_t)(unsigned long)prom_vec;
+ } else {
+ if ((int32_t)(long)prom_vec < 0) {
+ /*
+ * Old loader; all it gives us is the handle,
+ * so use the "known" entrypoint and assume
+ * the seal.
+ */
+ cfe_handle = (uint64_t)(long)prom_vec;
+ cfe_ept = (uint64_t)((int32_t)0x9fc00500);
+ cfe_eptseal = CFE_EPTSEAL;
+ } else {
+ /*
+ * Newer loaders bundle the handle/ept/eptseal
+ * Note: prom_vec is in the loader's useg
+ * which is still alive in the TLB.
+ */
+ cfe_handle = (uint64_t)((int32_t *)prom_vec)[0];
+ cfe_ept = (uint64_t)((int32_t *)prom_vec)[2];
+ cfe_eptseal = (unsigned int)((uint32_t *)prom_vec)[3];
+ }
+ }
+ if (cfe_eptseal != CFE_EPTSEAL) {
+ /* too early for panic to do any good */
+ printk("CFE's entrypoint seal doesn't match. Spinning.");
+ while (1) ;
+ }
+ cfe_init(cfe_handle, cfe_ept);
+ /*
+ * Get the handle for (at least) prom_putchar, possibly for
+ * boot console
+ */
+ cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
+ if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, COMMAND_LINE_SIZE) < 0) {
+ if (argc >= 0) {
+ /* The loader should have set the command line */
+ /* too early for panic to do any good */
+ printk("LINUX_CMDLINE not defined in cfe.");
+ while (1) ;
+ }
+ }
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ {
+ char *ptr;
+ /* Need to find out early whether we've got an initrd. So scan
+ the list looking now */
+ for (ptr = arcs_cmdline; *ptr; ptr++) {
+ while (*ptr == ' ') {
+ ptr++;
+ }
+ if (!strncmp(ptr, "initrd=", 7)) {
+ initrd_setup(ptr+7);
+ break;
+ } else {
+ while (*ptr && (*ptr != ' ')) {
+ ptr++;
+ }
+ }
+ }
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+ /* Not sure this is needed, but it's the safe way. */
+ arcs_cmdline[COMMAND_LINE_SIZE-1] = 0;
+
+ prom_meminit();
+
+#if defined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250)
+ register_smp_ops(&sb_smp_ops);
+#endif
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ register_smp_ops(&bcm1480_smp_ops);
+#endif
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* Not sure what I'm supposed to do here. Nothing, I think */
+}
+
+void prom_putchar(char c)
+{
+ int ret;
+
+ while ((ret = cfe_write(cfe_cons_handle, &c, 1)) == 0)
+ ;
+}
diff --git a/arch/mips/sibyte/common/cfe_console.c b/arch/mips/sibyte/common/cfe_console.c
new file mode 100644
index 00000000..1ad2da10
--- /dev/null
+++ b/arch/mips/sibyte/common/cfe_console.c
@@ -0,0 +1,80 @@
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/console.h>
+
+#include <asm/sibyte/board.h>
+
+#include <asm/fw/cfe/cfe_api.h>
+#include <asm/fw/cfe/cfe_error.h>
+
+extern int cfe_cons_handle;
+
+static void cfe_console_write(struct console *cons, const char *str,
+ unsigned int count)
+{
+ int i, last, written;
+
+ for (i=0, last=0; i<count; i++) {
+ if (!str[i])
+ /* XXXKW can/should this ever happen? */
+ return;
+ if (str[i] == '\n') {
+ do {
+ written = cfe_write(cfe_cons_handle, &str[last], i-last);
+ if (written < 0)
+ ;
+ last += written;
+ } while (last < i);
+ while (cfe_write(cfe_cons_handle, "\r", 1) <= 0)
+ ;
+ }
+ }
+ if (last != count) {
+ do {
+ written = cfe_write(cfe_cons_handle, &str[last], count-last);
+ if (written < 0)
+ ;
+ last += written;
+ } while (last < count);
+ }
+
+}
+
+static int cfe_console_setup(struct console *cons, char *str)
+{
+ char consdev[32];
+ /* XXXKW think about interaction with 'console=' cmdline arg */
+ /* If none of the console options are configured, the build will break. */
+ if (cfe_getenv("BOOT_CONSOLE", consdev, 32) >= 0) {
+#ifdef CONFIG_SERIAL_SB1250_DUART
+ if (!strcmp(consdev, "uart0")) {
+ setleds("u0cn");
+ } else if (!strcmp(consdev, "uart1")) {
+ setleds("u1cn");
+ } else
+#endif
+#ifdef CONFIG_VGA_CONSOLE
+ if (!strcmp(consdev, "pcconsole0")) {
+ setleds("pccn");
+ } else
+#endif
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static struct console sb1250_cfe_cons = {
+ .name = "cfe",
+ .write = cfe_console_write,
+ .setup = cfe_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+static int __init sb1250_cfe_console_init(void)
+{
+ register_console(&sb1250_cfe_cons);
+ return 0;
+}
+
+console_initcall(sb1250_cfe_console_init);
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
new file mode 100644
index 00000000..48853ab5
--- /dev/null
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -0,0 +1,607 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ */
+
+#undef DEBUG
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+#include <asm/sibyte/bcm1480_regs.h>
+#include <asm/sibyte/bcm1480_scd.h>
+#include <asm/sibyte/bcm1480_int.h>
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/sb1250_int.h>
+#else
+#error invalid SiByte UART configuration
+#endif
+
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+#undef K_INT_TRACE_FREEZE
+#define K_INT_TRACE_FREEZE K_BCM1480_INT_TRACE_FREEZE
+#undef K_INT_PERF_CNT
+#define K_INT_PERF_CNT K_BCM1480_INT_PERF_CNT
+#endif
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#define SBPROF_TB_MAJOR 240
+
+typedef u64 tb_sample_t[6*256];
+
+enum open_status {
+ SB_CLOSED,
+ SB_OPENING,
+ SB_OPEN
+};
+
+struct sbprof_tb {
+ wait_queue_head_t tb_sync;
+ wait_queue_head_t tb_read;
+ struct mutex lock;
+ enum open_status open;
+ tb_sample_t *sbprof_tbbuf;
+ int next_tb_sample;
+
+ volatile int tb_enable;
+ volatile int tb_armed;
+
+};
+
+static struct sbprof_tb sbp;
+
+#define MAX_SAMPLE_BYTES (24*1024*1024)
+#define MAX_TBSAMPLE_BYTES (12*1024*1024)
+
+#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t))
+#define TB_SAMPLE_SIZE (sizeof(tb_sample_t))
+#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE)
+
+/* ioctls */
+#define SBPROF_ZBSTART _IOW('s', 0, int)
+#define SBPROF_ZBSTOP _IOW('s', 1, int)
+#define SBPROF_ZBWAITFULL _IOW('s', 2, int)
+
+/*
+ * Routines for using 40-bit SCD cycle counter
+ *
+ * Client responsible for either handling interrupts or making sure
+ * the cycles counter never saturates, e.g., by doing
+ * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs.
+ */
+
+/*
+ * Configures SCD counter 0 to count ZCLKs starting from val;
+ * Configures SCD counters1,2,3 to count nothing.
+ * Must not be called while gathering ZBbus profiles.
+ */
+
+#define zclk_timer_init(val) \
+ __asm__ __volatile__ (".set push;" \
+ ".set mips64;" \
+ "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
+ "sd %0, 0x10($8);" /* write val to counter0 */ \
+ "sd %1, 0($8);" /* config counter0 for zclks*/ \
+ ".set pop" \
+ : /* no outputs */ \
+ /* enable, counter0 */ \
+ : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \
+ : /* modifies */ "$8" )
+
+
+/* Reads SCD counter 0 and puts result in value
+ unsigned long long val; */
+#define zclk_get(val) \
+ __asm__ __volatile__ (".set push;" \
+ ".set mips64;" \
+ "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \
+ "ld %0, 0x10($8);" /* write val to counter0 */ \
+ ".set pop" \
+ : /* outputs */ "=r"(val) \
+ : /* inputs */ \
+ : /* modifies */ "$8" )
+
+#define DEVNAME "sb_tbprof"
+
+#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES)
+
+/*
+ * Support for ZBbus sampling using the trace buffer
+ *
+ * We use the SCD performance counter interrupt, caused by a Zclk counter
+ * overflow, to trigger the start of tracing.
+ *
+ * We set the trace buffer to sample everything and freeze on
+ * overflow.
+ *
+ * We map the interrupt for trace_buffer_freeze to handle it on CPU 0.
+ *
+ */
+
+static u64 tb_period;
+
+static void arm_tb(void)
+{
+ u64 scdperfcnt;
+ u64 next = (1ULL << 40) - tb_period;
+ u64 tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
+
+ /*
+ * Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
+ * trigger start of trace. XXX vary sampling period
+ */
+ __raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
+ scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+
+ /*
+ * Unfortunately, in Pass 2 we must clear all counters to knock down
+ * a previous interrupt request. This means that bus profiling
+ * requires ALL of the SCD perf counters.
+ */
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) |
+ /* keep counters 0,2,3,4,5,6,7 as is */
+ V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */
+ IOADDR(A_BCM1480_SCD_PERF_CNT_CFG0));
+ __raw_writeq(
+ M_SPC_CFG_ENABLE | /* enable counting */
+ M_SPC_CFG_CLEAR | /* clear all counters */
+ V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */
+ IOADDR(A_BCM1480_SCD_PERF_CNT_CFG1));
+#else
+ __raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) |
+ /* keep counters 0,2,3 as is */
+ M_SPC_CFG_ENABLE | /* enable counting */
+ M_SPC_CFG_CLEAR | /* clear all counters */
+ V_SPC_CFG_SRC1(1), /* counter 1 counts cycles */
+ IOADDR(A_SCD_PERF_CNT_CFG));
+#endif
+ __raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+ /* Reset the trace buffer */
+ __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
+ /* XXXKW may want to expose control to the data-collector */
+ tb_options |= M_SCD_TRACE_CFG_FORCECNT;
+#endif
+ __raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
+ sbp.tb_armed = 1;
+}
+
+static irqreturn_t sbprof_tb_intr(int irq, void *dev_id)
+{
+ int i;
+
+ pr_debug(DEVNAME ": tb_intr\n");
+
+ if (sbp.next_tb_sample < MAX_TB_SAMPLES) {
+ /* XXX should use XKPHYS to make writes bypass L2 */
+ u64 *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
+ /* Read out trace */
+ __raw_writeq(M_SCD_TRACE_CFG_START_READ,
+ IOADDR(A_SCD_TRACE_CFG));
+ __asm__ __volatile__ ("sync" : : : "memory");
+ /* Loop runs backwards because bundles are read out in reverse order */
+ for (i = 256 * 6; i > 0; i -= 6) {
+ /* Subscripts decrease to put bundle in the order */
+ /* t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi */
+ p[i - 1] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ /* read t2 hi */
+ p[i - 2] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ /* read t2 lo */
+ p[i - 3] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ /* read t1 hi */
+ p[i - 4] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ /* read t1 lo */
+ p[i - 5] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ /* read t0 hi */
+ p[i - 6] = __raw_readq(IOADDR(A_SCD_TRACE_READ));
+ /* read t0 lo */
+ }
+ if (!sbp.tb_enable) {
+ pr_debug(DEVNAME ": tb_intr shutdown\n");
+ __raw_writeq(M_SCD_TRACE_CFG_RESET,
+ IOADDR(A_SCD_TRACE_CFG));
+ sbp.tb_armed = 0;
+ wake_up_interruptible(&sbp.tb_sync);
+ } else {
+ /* knock down current interrupt and get another one later */
+ arm_tb();
+ }
+ } else {
+ /* No more trace buffer samples */
+ pr_debug(DEVNAME ": tb_intr full\n");
+ __raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ sbp.tb_armed = 0;
+ if (!sbp.tb_enable)
+ wake_up_interruptible(&sbp.tb_sync);
+ wake_up_interruptible(&sbp.tb_read);
+ }
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sbprof_pc_intr(int irq, void *dev_id)
+{
+ printk(DEVNAME ": unexpected pc_intr");
+ return IRQ_NONE;
+}
+
+/*
+ * Requires: Already called zclk_timer_init with a value that won't
+ * saturate 40 bits. No subsequent use of SCD performance counters
+ * or trace buffer.
+ */
+
+static int sbprof_zbprof_start(struct file *filp)
+{
+ u64 scdperfcnt;
+ int err;
+
+ if (xchg(&sbp.tb_enable, 1))
+ return -EBUSY;
+
+ pr_debug(DEVNAME ": starting\n");
+
+ sbp.next_tb_sample = 0;
+ filp->f_pos = 0;
+
+ err = request_irq(K_INT_TRACE_FREEZE, sbprof_tb_intr, 0,
+ DEVNAME " trace freeze", &sbp);
+ if (err)
+ return -EBUSY;
+
+ /* Make sure there isn't a perf-cnt interrupt waiting */
+ scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ /* Disable and clear counters, override SRC_1 */
+ __raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
+ M_SPC_CFG_ENABLE | M_SPC_CFG_CLEAR | V_SPC_CFG_SRC1(1),
+ IOADDR(A_SCD_PERF_CNT_CFG));
+
+ /*
+ * We grab this interrupt to prevent others from trying to use
+ * it, even though we don't want to service the interrupts
+ * (they only feed into the trace-on-interrupt mechanism)
+ */
+ if (request_irq(K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) {
+ free_irq(K_INT_TRACE_FREEZE, &sbp);
+ return -EBUSY;
+ }
+
+ /*
+ * I need the core to mask these, but the interrupt mapper to
+ * pass them through. I am exploiting my knowledge that
+ * cp0_status masks out IP[5]. krw
+ */
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ __raw_writeq(K_BCM1480_INT_MAP_I3,
+ IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_L) +
+ ((K_BCM1480_INT_PERF_CNT & 0x3f) << 3)));
+#else
+ __raw_writeq(K_INT_MAP_I3,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_PERF_CNT << 3)));
+#endif
+
+ /* Initialize address traps */
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
+
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
+
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
+ __raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
+
+ /* Initialize Trace Event 0-7 */
+ /* when interrupt */
+ __raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
+
+ /* Initialize Trace Sequence 0-7 */
+ /* Start on event 0 (interrupt) */
+ __raw_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
+ IOADDR(A_SCD_TRACE_SEQUENCE_0));
+ /* dsamp when d used | asamp when a used */
+ __raw_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+ K_SCD_TRSEQ_TRIGGER_ALL,
+ IOADDR(A_SCD_TRACE_SEQUENCE_1));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
+ __raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
+
+ /* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ __raw_writeq(1ULL << (K_BCM1480_INT_PERF_CNT & 0x3f),
+ IOADDR(A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_TRACE_L)));
+#else
+ __raw_writeq(1ULL << K_INT_PERF_CNT,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
+#endif
+ arm_tb();
+
+ pr_debug(DEVNAME ": done starting\n");
+
+ return 0;
+}
+
+static int sbprof_zbprof_stop(void)
+{
+ int err = 0;
+
+ pr_debug(DEVNAME ": stopping\n");
+
+ if (sbp.tb_enable) {
+ /*
+ * XXXKW there is a window here where the intr handler may run,
+ * see the disable, and do the wake_up before this sleep
+ * happens.
+ */
+ pr_debug(DEVNAME ": wait for disarm\n");
+ err = wait_event_interruptible(sbp.tb_sync, !sbp.tb_armed);
+ pr_debug(DEVNAME ": disarm complete, stat %d\n", err);
+
+ if (err)
+ return err;
+
+ sbp.tb_enable = 0;
+ free_irq(K_INT_TRACE_FREEZE, &sbp);
+ free_irq(K_INT_PERF_CNT, &sbp);
+ }
+
+ pr_debug(DEVNAME ": done stopping\n");
+
+ return err;
+}
+
+static int sbprof_tb_open(struct inode *inode, struct file *filp)
+{
+ int minor;
+
+ minor = iminor(inode);
+ if (minor != 0)
+ return -ENODEV;
+
+ if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED)
+ return -EBUSY;
+
+ memset(&sbp, 0, sizeof(struct sbprof_tb));
+ sbp.sbprof_tbbuf = vzalloc(MAX_TBSAMPLE_BYTES);
+ if (!sbp.sbprof_tbbuf) {
+ sbp.open = SB_CLOSED;
+ wmb();
+ return -ENOMEM;
+ }
+
+ init_waitqueue_head(&sbp.tb_sync);
+ init_waitqueue_head(&sbp.tb_read);
+ mutex_init(&sbp.lock);
+
+ sbp.open = SB_OPEN;
+ wmb();
+
+ return 0;
+}
+
+static int sbprof_tb_release(struct inode *inode, struct file *filp)
+{
+ int minor;
+
+ minor = iminor(inode);
+ if (minor != 0 || sbp.open != SB_CLOSED)
+ return -ENODEV;
+
+ mutex_lock(&sbp.lock);
+
+ if (sbp.tb_armed || sbp.tb_enable)
+ sbprof_zbprof_stop();
+
+ vfree(sbp.sbprof_tbbuf);
+ sbp.open = SB_CLOSED;
+ wmb();
+
+ mutex_unlock(&sbp.lock);
+
+ return 0;
+}
+
+static ssize_t sbprof_tb_read(struct file *filp, char *buf,
+ size_t size, loff_t *offp)
+{
+ int cur_sample, sample_off, cur_count, sample_left;
+ char *src;
+ int count = 0;
+ char *dest = buf;
+ long cur_off = *offp;
+
+ if (!access_ok(VERIFY_WRITE, buf, size))
+ return -EFAULT;
+
+ mutex_lock(&sbp.lock);
+
+ count = 0;
+ cur_sample = cur_off / TB_SAMPLE_SIZE;
+ sample_off = cur_off % TB_SAMPLE_SIZE;
+ sample_left = TB_SAMPLE_SIZE - sample_off;
+
+ while (size && (cur_sample < sbp.next_tb_sample)) {
+ int err;
+
+ cur_count = size < sample_left ? size : sample_left;
+ src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off);
+ err = __copy_to_user(dest, src, cur_count);
+ if (err) {
+ *offp = cur_off + cur_count - err;
+ mutex_unlock(&sbp.lock);
+ return err;
+ }
+ pr_debug(DEVNAME ": read from sample %d, %d bytes\n",
+ cur_sample, cur_count);
+ size -= cur_count;
+ sample_left -= cur_count;
+ if (!sample_left) {
+ cur_sample++;
+ sample_off = 0;
+ sample_left = TB_SAMPLE_SIZE;
+ } else {
+ sample_off += cur_count;
+ }
+ cur_off += cur_count;
+ dest += cur_count;
+ count += cur_count;
+ }
+ *offp = cur_off;
+ mutex_unlock(&sbp.lock);
+
+ return count;
+}
+
+static long sbprof_tb_ioctl(struct file *filp,
+ unsigned int command,
+ unsigned long arg)
+{
+ int err = 0;
+
+ switch (command) {
+ case SBPROF_ZBSTART:
+ mutex_lock(&sbp.lock);
+ err = sbprof_zbprof_start(filp);
+ mutex_unlock(&sbp.lock);
+ break;
+
+ case SBPROF_ZBSTOP:
+ mutex_lock(&sbp.lock);
+ err = sbprof_zbprof_stop();
+ mutex_unlock(&sbp.lock);
+ break;
+
+ case SBPROF_ZBWAITFULL: {
+ err = wait_event_interruptible(sbp.tb_read, TB_FULL);
+ if (err)
+ break;
+
+ err = put_user(TB_FULL, (int *) arg);
+ break;
+ }
+
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+static const struct file_operations sbprof_tb_fops = {
+ .owner = THIS_MODULE,
+ .open = sbprof_tb_open,
+ .release = sbprof_tb_release,
+ .read = sbprof_tb_read,
+ .unlocked_ioctl = sbprof_tb_ioctl,
+ .compat_ioctl = sbprof_tb_ioctl,
+ .mmap = NULL,
+ .llseek = default_llseek,
+};
+
+static struct class *tb_class;
+static struct device *tb_dev;
+
+static int __init sbprof_tb_init(void)
+{
+ struct device *dev;
+ struct class *tbc;
+ int err;
+
+ if (register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) {
+ printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n",
+ SBPROF_TB_MAJOR);
+ return -EIO;
+ }
+
+ tbc = class_create(THIS_MODULE, "sb_tracebuffer");
+ if (IS_ERR(tbc)) {
+ err = PTR_ERR(tbc);
+ goto out_chrdev;
+ }
+
+ tb_class = tbc;
+
+ dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), NULL, "tb");
+ if (IS_ERR(dev)) {
+ err = PTR_ERR(dev);
+ goto out_class;
+ }
+ tb_dev = dev;
+
+ sbp.open = SB_CLOSED;
+ wmb();
+ tb_period = zbbus_mhz * 10000LL;
+ pr_info(DEVNAME ": initialized - tb_period = %lld\n",
+ (long long) tb_period);
+ return 0;
+
+out_class:
+ class_destroy(tb_class);
+out_chrdev:
+ unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
+
+ return err;
+}
+
+static void __exit sbprof_tb_cleanup(void)
+{
+ device_destroy(tb_class, MKDEV(SBPROF_TB_MAJOR, 0));
+ unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME);
+ class_destroy(tb_class);
+}
+
+module_init(sbprof_tb_init);
+module_exit(sbprof_tb_cleanup);
+
+MODULE_ALIAS_CHARDEV_MAJOR(SBPROF_TB_MAJOR);
+MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile
new file mode 100644
index 00000000..d3d969de
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/Makefile
@@ -0,0 +1,4 @@
+obj-y := setup.o irq.o time.o
+
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o
diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c
new file mode 100644
index 00000000..45274bd3
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/bus_watcher.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2002,2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * The Bus Watcher monitors internal bus transactions and maintains
+ * counts of transactions with error status, logging details and
+ * causing one of several interrupts. This driver provides a handler
+ * for those interrupts which aggregates the counts (to avoid
+ * saturating the 8-bit counters) and provides a presence in
+ * /proc/bus_watcher if PROC_FS is on.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+
+struct bw_stats_struct {
+ uint64_t status;
+ uint32_t l2_err;
+ uint32_t memio_err;
+ int status_printed;
+ unsigned long l2_cor_d;
+ unsigned long l2_bad_d;
+ unsigned long l2_cor_t;
+ unsigned long l2_bad_t;
+ unsigned long mem_cor_d;
+ unsigned long mem_bad_d;
+ unsigned long bus_error;
+} bw_stats;
+
+
+static void print_summary(uint32_t status, uint32_t l2_err,
+ uint32_t memio_err)
+{
+ printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
+ printk("\nLast recorded signature:\n");
+ printk("Request %02x from %d, answered by %d with Dcode %d\n",
+ (unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
+ (int)(G_SCD_BERR_TID(status) >> 6),
+ (int)G_SCD_BERR_RID(status),
+ (int)G_SCD_BERR_DCODE(status));
+}
+
+/*
+ * check_bus_watcher is exported for use in situations where we want
+ * to see the most recent status of the bus watcher, which might have
+ * already been destructively read out of the registers.
+ *
+ * notes: this is currently used by the cache error handler
+ * should provide locking against the interrupt handler
+ */
+void check_bus_watcher(void)
+{
+ u32 status, l2_err, memio_err;
+
+#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+ /* Destructive read, clears register and interrupt */
+ status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+#else
+ /* Use non-destructive register */
+ status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS_DEBUG));
+#endif
+ if (!(status & 0x7fffffff)) {
+ printk("Using last values reaped by bus watcher driver\n");
+ status = bw_stats.status;
+ l2_err = bw_stats.l2_err;
+ memio_err = bw_stats.memio_err;
+ } else {
+ l2_err = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+ memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+ }
+ if (status & ~(1UL << 31))
+ print_summary(status, l2_err, memio_err);
+ else
+ printk("Bus watcher indicates no error\n");
+}
+
+static int bw_print_buffer(char *page, struct bw_stats_struct *stats)
+{
+ int len;
+
+ len = sprintf(page, "SiByte Bus Watcher statistics\n");
+ len += sprintf(page+len, "-----------------------------\n");
+ len += sprintf(page+len, "L2-d-cor %8ld\nL2-d-bad %8ld\n",
+ stats->l2_cor_d, stats->l2_bad_d);
+ len += sprintf(page+len, "L2-t-cor %8ld\nL2-t-bad %8ld\n",
+ stats->l2_cor_t, stats->l2_bad_t);
+ len += sprintf(page+len, "MC-d-cor %8ld\nMC-d-bad %8ld\n",
+ stats->mem_cor_d, stats->mem_bad_d);
+ len += sprintf(page+len, "IO-err %8ld\n", stats->bus_error);
+ len += sprintf(page+len, "\nLast recorded signature:\n");
+ len += sprintf(page+len, "Request %02x from %d, answered by %d with Dcode %d\n",
+ (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f),
+ (int)(G_SCD_BERR_TID(stats->status) >> 6),
+ (int)G_SCD_BERR_RID(stats->status),
+ (int)G_SCD_BERR_DCODE(stats->status));
+ /* XXXKW indicate multiple errors between printings, or stats
+ collection (or both)? */
+ if (stats->status & M_SCD_BERR_MULTERRS)
+ len += sprintf(page+len, "Multiple errors observed since last check.\n");
+ if (stats->status_printed) {
+ len += sprintf(page+len, "(no change since last printing)\n");
+ } else {
+ stats->status_printed = 1;
+ }
+
+ return len;
+}
+
+#ifdef CONFIG_PROC_FS
+
+/* For simplicity, I want to assume a single read is required each
+ time */
+static int bw_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len;
+
+ if (off == 0) {
+ len = bw_print_buffer(page, data);
+ *start = page;
+ } else {
+ len = 0;
+ *eof = 1;
+ }
+ return len;
+}
+
+static void create_proc_decoder(struct bw_stats_struct *stats)
+{
+ struct proc_dir_entry *ent;
+
+ ent = create_proc_read_entry("bus_watcher", S_IWUSR | S_IRUGO, NULL,
+ bw_read_proc, stats);
+ if (!ent) {
+ printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n");
+ return;
+ }
+}
+
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * sibyte_bw_int - handle bus watcher interrupts and accumulate counts
+ *
+ * notes: possible re-entry due to multiple sources
+ * should check/indicate saturation
+ */
+static irqreturn_t sibyte_bw_int(int irq, void *data)
+{
+ struct bw_stats_struct *stats = data;
+ unsigned long cntr;
+#ifdef CONFIG_SIBYTE_BW_TRACE
+ int i;
+#endif
+#ifndef CONFIG_PROC_FS
+ char bw_buf[1024];
+#endif
+
+#ifdef CONFIG_SIBYTE_BW_TRACE
+ csr_out32(M_SCD_TRACE_CFG_FREEZE, IOADDR(A_SCD_TRACE_CFG));
+ csr_out32(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+
+ for (i=0; i<256*6; i++)
+ printk("%016llx\n",
+ (long long)__raw_readq(IOADDR(A_SCD_TRACE_READ)));
+
+ csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
+#endif
+
+ /* Destructive read, clears register and interrupt */
+ stats->status = csr_in32(IOADDR(A_SCD_BUS_ERR_STATUS));
+ stats->status_printed = 0;
+
+ stats->l2_err = cntr = csr_in32(IOADDR(A_BUS_L2_ERRORS));
+ stats->l2_cor_d += G_SCD_L2ECC_CORR_D(cntr);
+ stats->l2_bad_d += G_SCD_L2ECC_BAD_D(cntr);
+ stats->l2_cor_t += G_SCD_L2ECC_CORR_T(cntr);
+ stats->l2_bad_t += G_SCD_L2ECC_BAD_T(cntr);
+ csr_out32(0, IOADDR(A_BUS_L2_ERRORS));
+
+ stats->memio_err = cntr = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
+ stats->mem_cor_d += G_SCD_MEM_ECC_CORR(cntr);
+ stats->mem_bad_d += G_SCD_MEM_ECC_BAD(cntr);
+ stats->bus_error += G_SCD_MEM_BUSERR(cntr);
+ csr_out32(0, IOADDR(A_BUS_MEM_IO_ERRORS));
+
+#ifndef CONFIG_PROC_FS
+ bw_print_buffer(bw_buf, stats);
+ printk(bw_buf);
+#endif
+
+ return IRQ_HANDLED;
+}
+
+int __init sibyte_bus_watcher(void)
+{
+ memset(&bw_stats, 0, sizeof(struct bw_stats_struct));
+ bw_stats.status_printed = 1;
+
+ if (request_irq(K_INT_BAD_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+ printk("Failed to register bus watcher BAD_ECC irq\n");
+ return -1;
+ }
+ if (request_irq(K_INT_COR_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+ free_irq(K_INT_BAD_ECC, &bw_stats);
+ printk("Failed to register bus watcher COR_ECC irq\n");
+ return -1;
+ }
+ if (request_irq(K_INT_IO_BUS, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) {
+ free_irq(K_INT_BAD_ECC, &bw_stats);
+ free_irq(K_INT_COR_ECC, &bw_stats);
+ printk("Failed to register bus watcher IO_BUS irq\n");
+ return -1;
+ }
+
+#ifdef CONFIG_PROC_FS
+ create_proc_decoder(&bw_stats);
+#endif
+
+#ifdef CONFIG_SIBYTE_BW_TRACE
+ csr_out32((M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
+ K_SCD_TRSEQ_TRIGGER_ALL),
+ IOADDR(A_SCD_TRACE_SEQUENCE_0));
+ csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
+#endif
+
+ return 0;
+}
+
+__initcall(sibyte_bus_watcher);
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
new file mode 100644
index 00000000..be4460a5
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/errno.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+#include <asm/sibyte/sb1250_uart.h>
+#include <asm/sibyte/sb1250_scd.h>
+#include <asm/sibyte/sb1250.h>
+
+/*
+ * These are the routines that handle all the low level interrupt stuff.
+ * Actions handled here are: initialization of the interrupt map, requesting of
+ * interrupt lines by handlers, dispatching if interrupts to handlers, probing
+ * for interrupt lines
+ */
+
+#ifdef CONFIG_SIBYTE_HAS_LDT
+extern unsigned long ldt_eoi_space;
+#endif
+
+/* Store the CPU id (not the logical number) */
+int sb1250_irq_owner[SB1250_NR_IRQS];
+
+static DEFINE_RAW_SPINLOCK(sb1250_imr_lock);
+
+void sb1250_mask_irq(int cpu, int irq)
+{
+ unsigned long flags;
+ u64 cur_ints;
+
+ raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
+ cur_ints |= (((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
+ raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+}
+
+void sb1250_unmask_irq(int cpu, int irq)
+{
+ unsigned long flags;
+ u64 cur_ints;
+
+ raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
+ cur_ints &= ~(((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
+ raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static int sb1250_set_affinity(struct irq_data *d, const struct cpumask *mask,
+ bool force)
+{
+ int i = 0, old_cpu, cpu, int_on;
+ unsigned int irq = d->irq;
+ u64 cur_ints;
+ unsigned long flags;
+
+ i = cpumask_first(mask);
+
+ /* Convert logical CPU to physical CPU */
+ cpu = cpu_logical_map(i);
+
+ /* Protect against other affinity changers and IMR manipulation */
+ raw_spin_lock_irqsave(&sb1250_imr_lock, flags);
+
+ /* Swizzle each CPU's IMR (but leave the IP selection alone) */
+ old_cpu = sb1250_irq_owner[irq];
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
+ R_IMR_INTERRUPT_MASK));
+ int_on = !(cur_ints & (((u64) 1) << irq));
+ if (int_on) {
+ /* If it was on, mask it */
+ cur_ints |= (((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
+ R_IMR_INTERRUPT_MASK));
+ }
+ sb1250_irq_owner[irq] = cpu;
+ if (int_on) {
+ /* unmask for the new CPU */
+ cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
+ cur_ints &= ~(((u64) 1) << irq);
+ ____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
+ R_IMR_INTERRUPT_MASK));
+ }
+ raw_spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+
+ return 0;
+}
+#endif
+
+static void enable_sb1250_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ sb1250_unmask_irq(sb1250_irq_owner[irq], irq);
+}
+
+
+static void ack_sb1250_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+#ifdef CONFIG_SIBYTE_HAS_LDT
+ u64 pending;
+
+ /*
+ * If the interrupt was an HT interrupt, now is the time to
+ * clear it. NOTE: we assume the HT bridge was set up to
+ * deliver the interrupts to all CPUs (which makes affinity
+ * changing easier for us)
+ */
+ pending = __raw_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
+ R_IMR_LDT_INTERRUPT)));
+ pending &= ((u64)1 << (irq));
+ if (pending) {
+ int i;
+ for (i=0; i<NR_CPUS; i++) {
+ int cpu;
+#ifdef CONFIG_SMP
+ cpu = cpu_logical_map(i);
+#else
+ cpu = i;
+#endif
+ /*
+ * Clear for all CPUs so an affinity switch
+ * doesn't find an old status
+ */
+ __raw_writeq(pending,
+ IOADDR(A_IMR_REGISTER(cpu,
+ R_IMR_LDT_INTERRUPT_CLR)));
+ }
+
+ /*
+ * Generate EOI. For Pass 1 parts, EOI is a nop. For
+ * Pass 2, the LDT world may be edge-triggered, but
+ * this EOI shouldn't hurt. If they are
+ * level-sensitive, the EOI is required.
+ */
+ *(uint32_t *)(ldt_eoi_space+(irq<<16)+(7<<2)) = 0;
+ }
+#endif
+ sb1250_mask_irq(sb1250_irq_owner[irq], irq);
+}
+
+static struct irq_chip sb1250_irq_type = {
+ .name = "SB1250-IMR",
+ .irq_mask_ack = ack_sb1250_irq,
+ .irq_unmask = enable_sb1250_irq,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = sb1250_set_affinity
+#endif
+};
+
+void __init init_sb1250_irqs(void)
+{
+ int i;
+
+ for (i = 0; i < SB1250_NR_IRQS; i++) {
+ irq_set_chip_and_handler(i, &sb1250_irq_type,
+ handle_level_irq);
+ sb1250_irq_owner[i] = 0;
+ }
+}
+
+
+/*
+ * arch_init_irq is called early in the boot sequence from init/main.c via
+ * init_IRQ. It is responsible for setting up the interrupt mapper and
+ * installing the handler that will be responsible for dispatching interrupts
+ * to the "right" place.
+ */
+/*
+ * For now, map all interrupts to IP[2]. We could save
+ * some cycles by parceling out system interrupts to different
+ * IP lines, but keep it simple for bringup. We'll also direct
+ * all interrupts to a single CPU; we should probably route
+ * PCI and LDT to one cpu and everything else to the other
+ * to balance the load a bit.
+ *
+ * On the second cpu, everything is set to IP5, which is
+ * ignored, EXCEPT the mailbox interrupt. That one is
+ * set to IP[2] so it is handled. This is needed so we
+ * can do cross-cpu function calls, as required by SMP
+ */
+
+#define IMR_IP2_VAL K_INT_MAP_I0
+#define IMR_IP3_VAL K_INT_MAP_I1
+#define IMR_IP4_VAL K_INT_MAP_I2
+#define IMR_IP5_VAL K_INT_MAP_I3
+#define IMR_IP6_VAL K_INT_MAP_I4
+
+void __init arch_init_irq(void)
+{
+
+ unsigned int i;
+ u64 tmp;
+ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+ STATUSF_IP1 | STATUSF_IP0;
+
+ /* Default everything to IP2 */
+ for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_IMR_REGISTER(0,
+ R_IMR_INTERRUPT_MAP_BASE) +
+ (i << 3)));
+ __raw_writeq(IMR_IP2_VAL,
+ IOADDR(A_IMR_REGISTER(1,
+ R_IMR_INTERRUPT_MAP_BASE) +
+ (i << 3)));
+ }
+
+ init_sb1250_irqs();
+
+ /*
+ * Map the high 16 bits of the mailbox registers to IP[3], for
+ * inter-cpu messages
+ */
+ /* Was I1 */
+ __raw_writeq(IMR_IP3_VAL,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_MBOX_0 << 3)));
+ __raw_writeq(IMR_IP3_VAL,
+ IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+ (K_INT_MBOX_0 << 3)));
+
+ /* Clear the mailboxes. The firmware may leave them dirty */
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
+ __raw_writeq(0xffffffffffffffffULL,
+ IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
+
+ /* Mask everything except the mailbox registers for both cpus */
+ tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
+ __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
+ __raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
+
+ /*
+ * Note that the timer interrupts are also mapped, but this is
+ * done in sb1250_time_init(). Also, the profiling driver
+ * does its own management of IP7.
+ */
+
+ /* Enable necessary IPs, disable the rest */
+ change_c0_status(ST0_IM, imask);
+}
+
+extern void sb1250_mailbox_interrupt(void);
+
+static inline void dispatch_ip2(void)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned long long mask;
+
+ /*
+ * Default...we've hit an IP[2] interrupt, which means we've got to
+ * check the 1250 interrupt registers to figure out what to do. Need
+ * to detect which CPU we're on, now that smp_affinity is supported.
+ */
+ mask = __raw_readq(IOADDR(A_IMR_REGISTER(cpu,
+ R_IMR_INTERRUPT_STATUS_BASE)));
+ if (mask)
+ do_IRQ(fls64(mask) - 1);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned int pending;
+
+ /*
+ * What a pain. We have to be really careful saving the upper 32 bits
+ * of any * register across function calls if we don't want them
+ * trashed--since were running in -o32, the calling routing never saves
+ * the full 64 bits of a register across a function call. Being the
+ * interrupt handler, we're guaranteed that interrupts are disabled
+ * during this code so we don't have to worry about random interrupts
+ * blasting the high 32 bits.
+ */
+
+ pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+ if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+ else if (pending & CAUSEF_IP4)
+ do_IRQ(K_INT_TIMER_0 + cpu); /* sb1250_timer_interrupt() */
+
+#ifdef CONFIG_SMP
+ else if (pending & CAUSEF_IP3)
+ sb1250_mailbox_interrupt();
+#endif
+
+ else if (pending & CAUSEF_IP2)
+ dispatch_ip2();
+ else
+ spurious_interrupt();
+}
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c
new file mode 100644
index 00000000..92da3155
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/setup.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/io.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_scd.h>
+
+unsigned int sb1_pass;
+unsigned int soc_pass;
+unsigned int soc_type;
+EXPORT_SYMBOL(soc_type);
+unsigned int periph_rev;
+unsigned int zbbus_mhz;
+EXPORT_SYMBOL(zbbus_mhz);
+
+static char *soc_str;
+static char *pass_str;
+static unsigned int war_pass; /* XXXKW don't overload PASS defines? */
+
+static int __init setup_bcm1250(void)
+{
+ int ret = 0;
+
+ switch (soc_pass) {
+ case K_SYS_REVISION_BCM1250_PASS1:
+ periph_rev = 1;
+ pass_str = "Pass 1";
+ break;
+ case K_SYS_REVISION_BCM1250_A10:
+ periph_rev = 2;
+ pass_str = "A8/A10";
+ /* XXXKW different war_pass? */
+ war_pass = K_SYS_REVISION_BCM1250_PASS2;
+ break;
+ case K_SYS_REVISION_BCM1250_PASS2_2:
+ periph_rev = 2;
+ pass_str = "B1";
+ break;
+ case K_SYS_REVISION_BCM1250_B2:
+ periph_rev = 2;
+ pass_str = "B2";
+ war_pass = K_SYS_REVISION_BCM1250_PASS2_2;
+ break;
+ case K_SYS_REVISION_BCM1250_PASS3:
+ periph_rev = 3;
+ pass_str = "C0";
+ break;
+ case K_SYS_REVISION_BCM1250_C1:
+ periph_rev = 3;
+ pass_str = "C1";
+ break;
+ default:
+ if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) {
+ periph_rev = 2;
+ pass_str = "A0-A6";
+ war_pass = K_SYS_REVISION_BCM1250_PASS2;
+ } else {
+ printk("Unknown BCM1250 rev %x\n", soc_pass);
+ ret = 1;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+int sb1250_m3_workaround_needed(void)
+{
+ switch (soc_type) {
+ case K_SYS_SOC_TYPE_BCM1250:
+ case K_SYS_SOC_TYPE_BCM1250_ALT:
+ case K_SYS_SOC_TYPE_BCM1250_ALT2:
+ case K_SYS_SOC_TYPE_BCM1125:
+ case K_SYS_SOC_TYPE_BCM1125H:
+ return soc_pass < K_SYS_REVISION_BCM1250_C0;
+
+ default:
+ return 0;
+ }
+}
+
+static int __init setup_bcm112x(void)
+{
+ int ret = 0;
+
+ switch (soc_pass) {
+ case 0:
+ /* Early build didn't have revid set */
+ periph_rev = 3;
+ pass_str = "A1";
+ war_pass = K_SYS_REVISION_BCM112x_A1;
+ break;
+ case K_SYS_REVISION_BCM112x_A1:
+ periph_rev = 3;
+ pass_str = "A1";
+ break;
+ case K_SYS_REVISION_BCM112x_A2:
+ periph_rev = 3;
+ pass_str = "A2";
+ break;
+ case K_SYS_REVISION_BCM112x_A3:
+ periph_rev = 3;
+ pass_str = "A3";
+ break;
+ case K_SYS_REVISION_BCM112x_A4:
+ periph_rev = 3;
+ pass_str = "A4";
+ break;
+ case K_SYS_REVISION_BCM112x_B0:
+ periph_rev = 3;
+ pass_str = "B0";
+ break;
+ default:
+ printk("Unknown %s rev %x\n", soc_str, soc_pass);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/* Setup code likely to be common to all SiByte platforms */
+
+static int __init sys_rev_decode(void)
+{
+ int ret = 0;
+
+ war_pass = soc_pass;
+ switch (soc_type) {
+ case K_SYS_SOC_TYPE_BCM1250:
+ case K_SYS_SOC_TYPE_BCM1250_ALT:
+ case K_SYS_SOC_TYPE_BCM1250_ALT2:
+ soc_str = "BCM1250";
+ ret = setup_bcm1250();
+ break;
+ case K_SYS_SOC_TYPE_BCM1120:
+ soc_str = "BCM1120";
+ ret = setup_bcm112x();
+ break;
+ case K_SYS_SOC_TYPE_BCM1125:
+ soc_str = "BCM1125";
+ ret = setup_bcm112x();
+ break;
+ case K_SYS_SOC_TYPE_BCM1125H:
+ soc_str = "BCM1125H";
+ ret = setup_bcm112x();
+ break;
+ default:
+ printk("Unknown SOC type %x\n", soc_type);
+ ret = 1;
+ break;
+ }
+
+ return ret;
+}
+
+void __init sb1250_setup(void)
+{
+ uint64_t sys_rev;
+ int plldiv;
+ int bad_config = 0;
+
+ sb1_pass = read_c0_prid() & 0xff;
+ sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+ soc_type = SYS_SOC_TYPE(sys_rev);
+ soc_pass = G_SYS_REVISION(sys_rev);
+
+ if (sys_rev_decode()) {
+ printk("Restart after failure to identify SiByte chip\n");
+ machine_restart(NULL);
+ }
+
+ plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
+
+ printk("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
+ soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
+ printk("Board type: %s\n", get_system_type());
+
+ switch (war_pass) {
+ case K_SYS_REVISION_BCM1250_PASS1:
+#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
+ printk("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, "
+ "and the kernel doesn't have the proper "
+ "workarounds compiled in. @@@@\n");
+ bad_config = 1;
+#endif
+ break;
+ case K_SYS_REVISION_BCM1250_PASS2:
+ /* Pass 2 - easiest as default for now - so many numbers */
+#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \
+ !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
+ printk("@@@@ This is a BCM1250 A3-A10 board, and the "
+ "kernel doesn't have the proper workarounds "
+ "compiled in. @@@@\n");
+ bad_config = 1;
+#endif
+#ifdef CONFIG_CPU_HAS_PREFETCH
+ printk("@@@@ Prefetches may be enabled in this kernel, "
+ "but are buggy on this board. @@@@\n");
+ bad_config = 1;
+#endif
+ break;
+ case K_SYS_REVISION_BCM1250_PASS2_2:
+#ifndef CONFIG_SB1_PASS_2_WORKAROUNDS
+ printk("@@@@ This is a BCM1250 B1/B2. board, and the "
+ "kernel doesn't have the proper workarounds "
+ "compiled in. @@@@\n");
+ bad_config = 1;
+#endif
+#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \
+ !defined(CONFIG_CPU_HAS_PREFETCH)
+ printk("@@@@ This is a BCM1250 B1/B2, but the kernel is "
+ "conservatively configured for an 'A' stepping. "
+ "@@@@\n");
+#endif
+ break;
+ default:
+ break;
+ }
+ if (bad_config) {
+ printk("Invalid configuration for this chip.\n");
+ machine_restart(NULL);
+ }
+}
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
new file mode 100644
index 00000000..38e7f6bd
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/fw/cfe/cfe_api.h>
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_int.h>
+
+static void *mailbox_set_regs[] = {
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU)
+};
+
+static void *mailbox_clear_regs[] = {
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU)
+};
+
+static void *mailbox_regs[] = {
+ IOADDR(A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU),
+ IOADDR(A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU)
+};
+
+/*
+ * SMP init and finish on secondary CPUs
+ */
+void __cpuinit sb1250_smp_init(void)
+{
+ unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
+ STATUSF_IP1 | STATUSF_IP0;
+
+ /* Set interrupt mask, but don't enable */
+ change_c0_status(ST0_IM, imask);
+}
+
+/*
+ * These are routines for dealing with the sb1250 smp capabilities
+ * independent of board/firmware
+ */
+
+/*
+ * Simple enough; everything is set up, so just poke the appropriate mailbox
+ * register, and we should be set
+ */
+static void sb1250_send_ipi_single(int cpu, unsigned int action)
+{
+ __raw_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
+}
+
+static inline void sb1250_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ sb1250_send_ipi_single(i, action);
+}
+
+/*
+ * Code to run on secondary just after probing the CPU
+ */
+static void __cpuinit sb1250_init_secondary(void)
+{
+ extern void sb1250_smp_init(void);
+
+ sb1250_smp_init();
+}
+
+/*
+ * Do any tidying up before marking online and running the idle
+ * loop
+ */
+static void __cpuinit sb1250_smp_finish(void)
+{
+ extern void sb1250_clockevent_init(void);
+
+ sb1250_clockevent_init();
+ local_irq_enable();
+}
+
+/*
+ * Final cleanup after all secondaries booted
+ */
+static void sb1250_cpus_done(void)
+{
+}
+
+/*
+ * Setup the PC, SP, and GP of a secondary processor and start it
+ * running!
+ */
+static void __cpuinit sb1250_boot_secondary(int cpu, struct task_struct *idle)
+{
+ int retval;
+
+ retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap,
+ __KSTK_TOS(idle),
+ (unsigned long)task_thread_info(idle), 0);
+ if (retval != 0)
+ printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
+}
+
+/*
+ * Use CFE to find out how many CPUs are available, setting up
+ * cpu_possible_map and the logical/physical mappings.
+ * XXXKW will the boot CPU ever not be physical 0?
+ *
+ * Common setup before any secondaries are started
+ */
+static void __init sb1250_smp_setup(void)
+{
+ int i, num;
+
+ cpus_clear(cpu_possible_map);
+ cpu_set(0, cpu_possible_map);
+ __cpu_number_map[0] = 0;
+ __cpu_logical_map[0] = 0;
+
+ for (i = 1, num = 0; i < NR_CPUS; i++) {
+ if (cfe_cpu_stop(i) == 0) {
+ cpu_set(i, cpu_possible_map);
+ __cpu_number_map[i] = ++num;
+ __cpu_logical_map[num] = i;
+ }
+ }
+ printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
+}
+
+static void __init sb1250_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+struct plat_smp_ops sb_smp_ops = {
+ .send_ipi_single = sb1250_send_ipi_single,
+ .send_ipi_mask = sb1250_send_ipi_mask,
+ .init_secondary = sb1250_init_secondary,
+ .smp_finish = sb1250_smp_finish,
+ .cpus_done = sb1250_cpus_done,
+ .boot_secondary = sb1250_boot_secondary,
+ .smp_setup = sb1250_smp_setup,
+ .prepare_cpus = sb1250_prepare_cpus,
+};
+
+void sb1250_mailbox_interrupt(void)
+{
+ int cpu = smp_processor_id();
+ int irq = K_INT_MBOX_0;
+ unsigned int action;
+
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
+ /* Load the mailbox register to figure out what we're supposed to do */
+ action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
+
+ /* Clear the mailbox to clear the interrupt */
+ ____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
+
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
+
+ if (action & SMP_CALL_FUNCTION)
+ smp_call_function_interrupt();
+}
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
new file mode 100644
index 00000000..68337bf7
--- /dev/null
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+
+extern void sb1250_clocksource_init(void);
+extern void sb1250_clockevent_init(void);
+
+void __init plat_time_init(void)
+{
+ sb1250_clocksource_init();
+ sb1250_clockevent_init();
+}
diff --git a/arch/mips/sibyte/swarm/Makefile b/arch/mips/sibyte/swarm/Makefile
new file mode 100644
index 00000000..7b45f199
--- /dev/null
+++ b/arch/mips/sibyte/swarm/Makefile
@@ -0,0 +1,4 @@
+obj-y := platform.o setup.o rtc_xicor1241.o \
+ rtc_m41t81.o
+
+obj-$(CONFIG_I2C_BOARDINFO) += swarm-i2c.o
diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c
new file mode 100644
index 00000000..09733526
--- /dev/null
+++ b/arch/mips/sibyte/swarm/platform.c
@@ -0,0 +1,139 @@
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+
+#include <asm/sibyte/board.h>
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/sb1250_regs.h>
+
+#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR)
+
+#define DRV_NAME "pata-swarm"
+
+#define SWARM_IDE_SHIFT 5
+#define SWARM_IDE_BASE 0x1f0
+#define SWARM_IDE_CTRL 0x3f6
+
+static struct resource swarm_pata_resource[] = {
+ {
+ .name = "Swarm GenBus IDE",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "Swarm GenBus IDE",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "Swarm GenBus IDE",
+ .flags = IORESOURCE_IRQ,
+ .start = K_INT_GB_IDE,
+ .end = K_INT_GB_IDE,
+ },
+};
+
+static struct pata_platform_info pata_platform_data = {
+ .ioport_shift = SWARM_IDE_SHIFT,
+};
+
+static struct platform_device swarm_pata_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .resource = swarm_pata_resource,
+ .num_resources = ARRAY_SIZE(swarm_pata_resource),
+ .dev = {
+ .platform_data = &pata_platform_data,
+ .coherent_dma_mask = ~0, /* grumble */
+ },
+};
+
+static int __init swarm_pata_init(void)
+{
+ u8 __iomem *base;
+ phys_t offset, size;
+ struct resource *r;
+
+ if (!SIBYTE_HAVE_IDE)
+ return -ENODEV;
+
+ base = ioremap(A_IO_EXT_BASE, 0x800);
+ offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
+ size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
+ iounmap(base);
+
+ offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE;
+ size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE;
+ if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) {
+ pr_info(DRV_NAME ": PATA interface at GenBus disabled\n");
+
+ return -EBUSY;
+ }
+
+ pr_info(DRV_NAME ": PATA interface at GenBus slot %i\n", IDE_CS);
+
+ r = swarm_pata_resource;
+ r[0].start = offset + (SWARM_IDE_BASE << SWARM_IDE_SHIFT);
+ r[0].end = offset + ((SWARM_IDE_BASE + 8) << SWARM_IDE_SHIFT) - 1;
+ r[1].start = offset + (SWARM_IDE_CTRL << SWARM_IDE_SHIFT);
+ r[1].end = offset + ((SWARM_IDE_CTRL + 1) << SWARM_IDE_SHIFT) - 1;
+
+ return platform_device_register(&swarm_pata_device);
+}
+
+device_initcall(swarm_pata_init);
+
+#endif /* defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_LITTLESUR) */
+
+#define sb1250_dev_struct(num) \
+ static struct resource sb1250_res##num = { \
+ .name = "SB1250 MAC " __stringify(num), \
+ .flags = IORESOURCE_MEM, \
+ .start = A_MAC_CHANNEL_BASE(num), \
+ .end = A_MAC_CHANNEL_BASE(num + 1) -1, \
+ };\
+ static struct platform_device sb1250_dev##num = { \
+ .name = "sb1250-mac", \
+ .id = num, \
+ .resource = &sb1250_res##num, \
+ .num_resources = 1, \
+ }
+
+sb1250_dev_struct(0);
+sb1250_dev_struct(1);
+sb1250_dev_struct(2);
+sb1250_dev_struct(3);
+
+static struct platform_device *sb1250_devs[] __initdata = {
+ &sb1250_dev0,
+ &sb1250_dev1,
+ &sb1250_dev2,
+ &sb1250_dev3,
+};
+
+static int __init sb1250_device_init(void)
+{
+ int ret;
+
+ /* Set the number of available units based on the SOC type. */
+ switch (soc_type) {
+ case K_SYS_SOC_TYPE_BCM1250:
+ case K_SYS_SOC_TYPE_BCM1250_ALT:
+ ret = platform_add_devices(sb1250_devs, 3);
+ break;
+ case K_SYS_SOC_TYPE_BCM1120:
+ case K_SYS_SOC_TYPE_BCM1125:
+ case K_SYS_SOC_TYPE_BCM1125H:
+ case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */
+ ret = platform_add_devices(sb1250_devs, 2);
+ break;
+ case K_SYS_SOC_TYPE_BCM1x55:
+ case K_SYS_SOC_TYPE_BCM1x80:
+ ret = platform_add_devices(sb1250_devs, 4);
+ break;
+ default:
+ ret = -ENODEV;
+ break;
+ }
+ return ret;
+}
+device_initcall(sb1250_device_init);
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
new file mode 100644
index 00000000..b732600b
--- /dev/null
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/bcd.h>
+#include <linux/types.h>
+#include <linux/time.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_smbus.h>
+
+
+/* M41T81 definitions */
+
+/*
+ * Register bits
+ */
+
+#define M41T81REG_SC_ST 0x80 /* stop bit */
+#define M41T81REG_HR_CB 0x40 /* century bit */
+#define M41T81REG_HR_CEB 0x80 /* century enable bit */
+#define M41T81REG_CTL_S 0x20 /* sign bit */
+#define M41T81REG_CTL_FT 0x40 /* frequency test bit */
+#define M41T81REG_CTL_OUT 0x80 /* output level */
+#define M41T81REG_WD_RB0 0x01 /* watchdog resolution bit 0 */
+#define M41T81REG_WD_RB1 0x02 /* watchdog resolution bit 1 */
+#define M41T81REG_WD_BMB0 0x04 /* watchdog multiplier bit 0 */
+#define M41T81REG_WD_BMB1 0x08 /* watchdog multiplier bit 1 */
+#define M41T81REG_WD_BMB2 0x10 /* watchdog multiplier bit 2 */
+#define M41T81REG_WD_BMB3 0x20 /* watchdog multiplier bit 3 */
+#define M41T81REG_WD_BMB4 0x40 /* watchdog multiplier bit 4 */
+#define M41T81REG_AMO_ABE 0x20 /* alarm in "battery back-up mode" enable bit */
+#define M41T81REG_AMO_SQWE 0x40 /* square wave enable */
+#define M41T81REG_AMO_AFE 0x80 /* alarm flag enable flag */
+#define M41T81REG_ADT_RPT5 0x40 /* alarm repeat mode bit 5 */
+#define M41T81REG_ADT_RPT4 0x80 /* alarm repeat mode bit 4 */
+#define M41T81REG_AHR_RPT3 0x80 /* alarm repeat mode bit 3 */
+#define M41T81REG_AHR_HT 0x40 /* halt update bit */
+#define M41T81REG_AMN_RPT2 0x80 /* alarm repeat mode bit 2 */
+#define M41T81REG_ASC_RPT1 0x80 /* alarm repeat mode bit 1 */
+#define M41T81REG_FLG_AF 0x40 /* alarm flag (read only) */
+#define M41T81REG_FLG_WDF 0x80 /* watchdog flag (read only) */
+#define M41T81REG_SQW_RS0 0x10 /* sqw frequency bit 0 */
+#define M41T81REG_SQW_RS1 0x20 /* sqw frequency bit 1 */
+#define M41T81REG_SQW_RS2 0x40 /* sqw frequency bit 2 */
+#define M41T81REG_SQW_RS3 0x80 /* sqw frequency bit 3 */
+
+
+/*
+ * Register numbers
+ */
+
+#define M41T81REG_TSC 0x00 /* tenths/hundredths of second */
+#define M41T81REG_SC 0x01 /* seconds */
+#define M41T81REG_MN 0x02 /* minute */
+#define M41T81REG_HR 0x03 /* hour/century */
+#define M41T81REG_DY 0x04 /* day of week */
+#define M41T81REG_DT 0x05 /* date of month */
+#define M41T81REG_MO 0x06 /* month */
+#define M41T81REG_YR 0x07 /* year */
+#define M41T81REG_CTL 0x08 /* control */
+#define M41T81REG_WD 0x09 /* watchdog */
+#define M41T81REG_AMO 0x0A /* alarm: month */
+#define M41T81REG_ADT 0x0B /* alarm: date */
+#define M41T81REG_AHR 0x0C /* alarm: hour */
+#define M41T81REG_AMN 0x0D /* alarm: minute */
+#define M41T81REG_ASC 0x0E /* alarm: second */
+#define M41T81REG_FLG 0x0F /* flags */
+#define M41T81REG_SQW 0x13 /* square wave register */
+
+#define M41T81_CCR_ADDRESS 0x68
+
+#define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg))
+
+static int m41t81_read(uint8_t addr)
+{
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE,
+ SMB_CSR(R_SMB_START));
+
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
+
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ /* Clear error bit by writing a 1 */
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ return -1;
+ }
+
+ return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+}
+
+static int m41t81_write(uint8_t addr, int b)
+{
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(b & 0xff, SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+ SMB_CSR(R_SMB_START));
+
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ /* Clear error bit by writing a 1 */
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ return -1;
+ }
+
+ /* read the same byte again to make sure it is written */
+ __raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
+
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ return 0;
+}
+
+int m41t81_set_time(unsigned long t)
+{
+ struct rtc_time tm;
+ unsigned long flags;
+
+ /* Note we don't care about the century */
+ rtc_time_to_tm(t, &tm);
+
+ /*
+ * Note the write order matters as it ensures the correctness.
+ * When we write sec, 10th sec is clear. It is reasonable to
+ * believe we should finish writing min within a second.
+ */
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ tm.tm_sec = bin2bcd(tm.tm_sec);
+ m41t81_write(M41T81REG_SC, tm.tm_sec);
+
+ tm.tm_min = bin2bcd(tm.tm_min);
+ m41t81_write(M41T81REG_MN, tm.tm_min);
+
+ tm.tm_hour = bin2bcd(tm.tm_hour);
+ tm.tm_hour = (tm.tm_hour & 0x3f) | (m41t81_read(M41T81REG_HR) & 0xc0);
+ m41t81_write(M41T81REG_HR, tm.tm_hour);
+
+ /* tm_wday starts from 0 to 6 */
+ if (tm.tm_wday == 0) tm.tm_wday = 7;
+ tm.tm_wday = bin2bcd(tm.tm_wday);
+ m41t81_write(M41T81REG_DY, tm.tm_wday);
+
+ tm.tm_mday = bin2bcd(tm.tm_mday);
+ m41t81_write(M41T81REG_DT, tm.tm_mday);
+
+ /* tm_mon starts from 0, *ick* */
+ tm.tm_mon ++;
+ tm.tm_mon = bin2bcd(tm.tm_mon);
+ m41t81_write(M41T81REG_MO, tm.tm_mon);
+
+ /* we don't do century, everything is beyond 2000 */
+ tm.tm_year %= 100;
+ tm.tm_year = bin2bcd(tm.tm_year);
+ m41t81_write(M41T81REG_YR, tm.tm_year);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ return 0;
+}
+
+unsigned long m41t81_get_time(void)
+{
+ unsigned int year, mon, day, hour, min, sec;
+ unsigned long flags;
+
+ /*
+ * min is valid if two reads of sec are the same.
+ */
+ for (;;) {
+ spin_lock_irqsave(&rtc_lock, flags);
+ sec = m41t81_read(M41T81REG_SC);
+ min = m41t81_read(M41T81REG_MN);
+ if (sec == m41t81_read(M41T81REG_SC)) break;
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ }
+ hour = m41t81_read(M41T81REG_HR) & 0x3f;
+ day = m41t81_read(M41T81REG_DT);
+ mon = m41t81_read(M41T81REG_MO);
+ year = m41t81_read(M41T81REG_YR);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
+
+ year += 2000;
+
+ return mktime(year, mon, day, hour, min, sec);
+}
+
+int m41t81_probe(void)
+{
+ unsigned int tmp;
+
+ /* enable chip if it is not enabled yet */
+ tmp = m41t81_read(M41T81REG_SC);
+ m41t81_write(M41T81REG_SC, tmp & 0x7f);
+
+ return (m41t81_read(M41T81REG_SC) != -1);
+}
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
new file mode 100644
index 00000000..4438b219
--- /dev/null
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2000, 2001 Broadcom Corporation
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/bcd.h>
+#include <linux/types.h>
+#include <linux/time.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#include <asm/sibyte/sb1250.h>
+#include <asm/sibyte/sb1250_regs.h>
+#include <asm/sibyte/sb1250_smbus.h>
+
+
+/* Xicor 1241 definitions */
+
+/*
+ * Register bits
+ */
+
+#define X1241REG_SR_BAT 0x80 /* currently on battery power */
+#define X1241REG_SR_RWEL 0x04 /* r/w latch is enabled, can write RTC */
+#define X1241REG_SR_WEL 0x02 /* r/w latch is unlocked, can enable r/w now */
+#define X1241REG_SR_RTCF 0x01 /* clock failed */
+#define X1241REG_BL_BP2 0x80 /* block protect 2 */
+#define X1241REG_BL_BP1 0x40 /* block protect 1 */
+#define X1241REG_BL_BP0 0x20 /* block protect 0 */
+#define X1241REG_BL_WD1 0x10
+#define X1241REG_BL_WD0 0x08
+#define X1241REG_HR_MIL 0x80 /* military time format */
+
+/*
+ * Register numbers
+ */
+
+#define X1241REG_BL 0x10 /* block protect bits */
+#define X1241REG_INT 0x11 /* */
+#define X1241REG_SC 0x30 /* Seconds */
+#define X1241REG_MN 0x31 /* Minutes */
+#define X1241REG_HR 0x32 /* Hours */
+#define X1241REG_DT 0x33 /* Day of month */
+#define X1241REG_MO 0x34 /* Month */
+#define X1241REG_YR 0x35 /* Year */
+#define X1241REG_DW 0x36 /* Day of Week */
+#define X1241REG_Y2K 0x37 /* Year 2K */
+#define X1241REG_SR 0x3F /* Status register */
+
+#define X1241_CCR_ADDRESS 0x6F
+
+#define SMB_CSR(reg) IOADDR(A_SMB_REGISTER(1, reg))
+
+static int xicor_read(uint8_t addr)
+{
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ __raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+ __raw_writeq(addr & 0xff, SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+ SMB_CSR(R_SMB_START));
+
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+ SMB_CSR(R_SMB_START));
+
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ /* Clear error bit by writing a 1 */
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ return -1;
+ }
+
+ return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+}
+
+static int xicor_write(uint8_t addr, int b)
+{
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ __raw_writeq(addr, SMB_CSR(R_SMB_CMD));
+ __raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+ __raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+ SMB_CSR(R_SMB_START));
+
+ while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ ;
+
+ if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ /* Clear error bit by writing a 1 */
+ __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+int xicor_set_time(unsigned long t)
+{
+ struct rtc_time tm;
+ int tmp;
+ unsigned long flags;
+
+ rtc_time_to_tm(t, &tm);
+ tm.tm_year += 1900;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ /* unlock writes to the CCR */
+ xicor_write(X1241REG_SR, X1241REG_SR_WEL);
+ xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
+
+ /* trivial ones */
+ tm.tm_sec = bin2bcd(tm.tm_sec);
+ xicor_write(X1241REG_SC, tm.tm_sec);
+
+ tm.tm_min = bin2bcd(tm.tm_min);
+ xicor_write(X1241REG_MN, tm.tm_min);
+
+ tm.tm_mday = bin2bcd(tm.tm_mday);
+ xicor_write(X1241REG_DT, tm.tm_mday);
+
+ /* tm_mon starts from 0, *ick* */
+ tm.tm_mon ++;
+ tm.tm_mon = bin2bcd(tm.tm_mon);
+ xicor_write(X1241REG_MO, tm.tm_mon);
+
+ /* year is split */
+ tmp = tm.tm_year / 100;
+ tm.tm_year %= 100;
+ xicor_write(X1241REG_YR, tm.tm_year);
+ xicor_write(X1241REG_Y2K, tmp);
+
+ /* hour is the most tricky one */
+ tmp = xicor_read(X1241REG_HR);
+ if (tmp & X1241REG_HR_MIL) {
+ /* 24 hour format */
+ tm.tm_hour = bin2bcd(tm.tm_hour);
+ tmp = (tmp & ~0x3f) | (tm.tm_hour & 0x3f);
+ } else {
+ /* 12 hour format, with 0x2 for pm */
+ tmp = tmp & ~0x3f;
+ if (tm.tm_hour >= 12) {
+ tmp |= 0x20;
+ tm.tm_hour -= 12;
+ }
+ tm.tm_hour = bin2bcd(tm.tm_hour);
+ tmp |= tm.tm_hour;
+ }
+ xicor_write(X1241REG_HR, tmp);
+
+ xicor_write(X1241REG_SR, 0);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ return 0;
+}
+
+unsigned long xicor_get_time(void)
+{
+ unsigned int year, mon, day, hour, min, sec, y2k;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ sec = xicor_read(X1241REG_SC);
+ min = xicor_read(X1241REG_MN);
+ hour = xicor_read(X1241REG_HR);
+
+ if (hour & X1241REG_HR_MIL) {
+ hour &= 0x3f;
+ } else {
+ if (hour & 0x20)
+ hour = (hour & 0xf) + 0x12;
+ }
+
+ day = xicor_read(X1241REG_DT);
+ mon = xicor_read(X1241REG_MO);
+ year = xicor_read(X1241REG_YR);
+ y2k = xicor_read(X1241REG_Y2K);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
+ y2k = bcd2bin(y2k);
+
+ year += (y2k * 100);
+
+ return mktime(year, mon, day, hour, min, sec);
+}
+
+int xicor_probe(void)
+{
+ return (xicor_read(X1241REG_SC) != -1);
+}
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
new file mode 100644
index 00000000..41707a24
--- /dev/null
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2000, 2001, 2002, 2003, 2004 Broadcom Corporation
+ * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Setup code for the SWARM board
+ */
+
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/blkdev.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/screen_info.h>
+#include <linux/initrd.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+#include <asm/sibyte/sb1250.h>
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+#include <asm/sibyte/bcm1480_regs.h>
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+#include <asm/sibyte/sb1250_regs.h>
+#else
+#error invalid SiByte board configuration
+#endif
+#include <asm/sibyte/sb1250_genbus.h>
+#include <asm/sibyte/board.h>
+
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+extern void bcm1480_setup(void);
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+extern void sb1250_setup(void);
+#else
+#error invalid SiByte board configuration
+#endif
+
+extern int xicor_probe(void);
+extern int xicor_set_time(unsigned long);
+extern unsigned long xicor_get_time(void);
+
+extern int m41t81_probe(void);
+extern int m41t81_set_time(unsigned long);
+extern unsigned long m41t81_get_time(void);
+
+const char *get_system_type(void)
+{
+ return "SiByte " SIBYTE_BOARD_NAME;
+}
+
+int swarm_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ if (!is_fixup && (regs->cp0_cause & 4)) {
+ /* Data bus error - print PA */
+ printk("DBE physical address: %010Lx\n",
+ __read_64bit_c0_register($26, 1));
+ }
+ return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL);
+}
+
+enum swarm_rtc_type {
+ RTC_NONE,
+ RTC_XICOR,
+ RTC_M41T81,
+};
+
+enum swarm_rtc_type swarm_rtc_type;
+
+void read_persistent_clock(struct timespec *ts)
+{
+ unsigned long sec;
+
+ switch (swarm_rtc_type) {
+ case RTC_XICOR:
+ sec = xicor_get_time();
+ break;
+
+ case RTC_M41T81:
+ sec = m41t81_get_time();
+ break;
+
+ case RTC_NONE:
+ default:
+ sec = mktime(2000, 1, 1, 0, 0, 0);
+ break;
+ }
+ ts->tv_sec = sec;
+ ts->tv_nsec = 0;
+}
+
+int rtc_mips_set_time(unsigned long sec)
+{
+ switch (swarm_rtc_type) {
+ case RTC_XICOR:
+ return xicor_set_time(sec);
+
+ case RTC_M41T81:
+ return m41t81_set_time(sec);
+
+ case RTC_NONE:
+ default:
+ return -1;
+ }
+}
+
+void __init plat_mem_setup(void)
+{
+#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
+ bcm1480_setup();
+#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
+ sb1250_setup();
+#else
+#error invalid SiByte board configuration
+#endif
+
+ panic_timeout = 5; /* For debug. */
+
+ board_be_handler = swarm_be_handler;
+
+ if (xicor_probe())
+ swarm_rtc_type = RTC_XICOR;
+ if (m41t81_probe())
+ swarm_rtc_type = RTC_M41T81;
+
+#ifdef CONFIG_VT
+ screen_info = (struct screen_info) {
+ .orig_video_page = 52,
+ .orig_video_mode = 3,
+ .orig_video_cols = 80,
+ .flags = 12,
+ .orig_video_ega_bx = 3,
+ .orig_video_lines = 25,
+ .orig_video_isVGA = 0x22,
+ .orig_video_points = 16,
+ };
+ /* XXXKW for CFE, get lines/cols from environment */
+#endif
+}
+
+#ifdef LEDS_PHYS
+
+#ifdef CONFIG_SIBYTE_CARMEL
+/* XXXKW need to detect Monterey/LittleSur/etc */
+#undef LEDS_PHYS
+#define LEDS_PHYS MLEDS_PHYS
+#endif
+
+void setleds(char *str)
+{
+ void *reg;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ reg = IOADDR(LEDS_PHYS) + 0x20 + ((3 - i) << 3);
+
+ if (!str[i])
+ writeb(' ', reg);
+ else
+ writeb(str[i], reg);
+ }
+}
+
+#endif /* LEDS_PHYS */
diff --git a/arch/mips/sibyte/swarm/swarm-i2c.c b/arch/mips/sibyte/swarm/swarm-i2c.c
new file mode 100644
index 00000000..06250505
--- /dev/null
+++ b/arch/mips/sibyte/swarm/swarm-i2c.c
@@ -0,0 +1,35 @@
+/*
+ * Broadcom BCM91250A (SWARM), etc. I2C platform setup.
+ *
+ * Copyright (c) 2008 Maciej W. Rozycki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+
+static struct i2c_board_info swarm_i2c_info1[] __initdata = {
+ {
+ I2C_BOARD_INFO("m41t81", 0x68),
+ },
+};
+
+static int __init swarm_i2c_init(void)
+{
+ int err;
+
+ err = i2c_register_board_info(1, swarm_i2c_info1,
+ ARRAY_SIZE(swarm_i2c_info1));
+ if (err < 0)
+ printk(KERN_ERR
+ "swarm-i2c: cannot register board I2C devices\n");
+ return err;
+}
+
+arch_initcall(swarm_i2c_init);
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
new file mode 100644
index 00000000..9d3bad32
--- /dev/null
+++ b/arch/mips/sni/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the SNI specific part of the kernel
+#
+
+obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o
+obj-$(CONFIG_EISA) += eisa.o
diff --git a/arch/mips/sni/Platform b/arch/mips/sni/Platform
new file mode 100644
index 00000000..2644a9d6
--- /dev/null
+++ b/arch/mips/sni/Platform
@@ -0,0 +1,11 @@
+#
+# SNI RM
+#
+platform-$(CONFIG_SNI_RM) += sni/
+cflags-$(CONFIG_SNI_RM) += -I$(srctree)/arch/mips/include/asm/mach-rm
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+load-$(CONFIG_SNI_RM) += 0xffffffff80600000
+else
+load-$(CONFIG_SNI_RM) += 0xffffffff80030000
+endif
+all-$(CONFIG_SNI_RM) := $(COMPRESSION_FNAME).ecoff
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
new file mode 100644
index 00000000..c48194c3
--- /dev/null
+++ b/arch/mips/sni/a20r.c
@@ -0,0 +1,239 @@
+/*
+ * A20R specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/sni.h>
+#include <asm/time.h>
+
+#define PORT(_base,_irq) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ }
+
+static struct plat_serial8250_port a20r_data[] = {
+ PORT(0x3f8, 4),
+ PORT(0x2f8, 3),
+ { },
+};
+
+static struct platform_device a20r_serial8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = a20r_data,
+ },
+};
+
+static struct resource a20r_ds1216_rsrc[] = {
+ {
+ .start = 0x1c081ffc,
+ .end = 0x1c081fff,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct platform_device a20r_ds1216_device = {
+ .name = "rtc-ds1216",
+ .num_resources = ARRAY_SIZE(a20r_ds1216_rsrc),
+ .resource = a20r_ds1216_rsrc
+};
+
+static struct resource snirm_82596_rsrc[] = {
+ {
+ .start = 0x18000000,
+ .end = 0x18000004,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 0x18010000,
+ .end = 0x18010004,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 0x1ff00000,
+ .end = 0x1ff00020,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 22,
+ .end = 22,
+ .flags = IORESOURCE_IRQ
+ },
+ {
+ .flags = 0x01 /* 16bit mpu port access */
+ }
+};
+
+static struct platform_device snirm_82596_pdev = {
+ .name = "snirm_82596",
+ .num_resources = ARRAY_SIZE(snirm_82596_rsrc),
+ .resource = snirm_82596_rsrc
+};
+
+static struct resource snirm_53c710_rsrc[] = {
+ {
+ .start = 0x19000000,
+ .end = 0x190fffff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 19,
+ .end = 19,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device snirm_53c710_pdev = {
+ .name = "snirm_53c710",
+ .num_resources = ARRAY_SIZE(snirm_53c710_rsrc),
+ .resource = snirm_53c710_rsrc
+};
+
+static struct resource sc26xx_rsrc[] = {
+ {
+ .start = 0x1c070000,
+ .end = 0x1c0700ff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 20,
+ .end = 20,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static unsigned int sc26xx_data[2] = {
+ /* DTR | RTS | DSR | CTS | DCD | RI */
+ (8 << 0) | (4 << 4) | (6 << 8) | (0 << 12) | (6 << 16) | (0 << 20),
+ (3 << 0) | (2 << 4) | (1 << 8) | (2 << 12) | (3 << 16) | (4 << 20)
+};
+
+static struct platform_device sc26xx_pdev = {
+ .name = "SC26xx",
+ .num_resources = ARRAY_SIZE(sc26xx_rsrc),
+ .resource = sc26xx_rsrc,
+ .dev = {
+ .platform_data = sc26xx_data,
+ }
+};
+
+static u32 a20r_ack_hwint(void)
+{
+ u32 status = read_c0_status();
+
+ write_c0_status(status | 0x00010000);
+ asm volatile(
+ " .set push \n"
+ " .set noat \n"
+ " .set noreorder \n"
+ " lw $1, 0(%0) \n"
+ " sb $0, 0(%1) \n"
+ " sync \n"
+ " lb %1, 0(%1) \n"
+ " b 1f \n"
+ " ori %1, $1, 2 \n"
+ " .align 8 \n"
+ "1: \n"
+ " nop \n"
+ " sw %1, 0(%0) \n"
+ " sync \n"
+ " li %1, 0x20 \n"
+ "2: \n"
+ " nop \n"
+ " bnez %1,2b \n"
+ " addiu %1, -1 \n"
+ " sw $1, 0(%0) \n"
+ " sync \n"
+ ".set pop \n"
+ :
+ : "Jr" (PCIMT_UCONF), "Jr" (0xbc000000));
+ write_c0_status(status);
+
+ return status;
+}
+
+static inline void unmask_a20r_irq(struct irq_data *d)
+{
+ set_c0_status(0x100 << (d->irq - SNI_A20R_IRQ_BASE));
+ irq_enable_hazard();
+}
+
+static inline void mask_a20r_irq(struct irq_data *d)
+{
+ clear_c0_status(0x100 << (d->irq - SNI_A20R_IRQ_BASE));
+ irq_disable_hazard();
+}
+
+static struct irq_chip a20r_irq_type = {
+ .name = "A20R",
+ .irq_mask = mask_a20r_irq,
+ .irq_unmask = unmask_a20r_irq,
+};
+
+/*
+ * hwint 0 receive all interrupts
+ */
+static void a20r_hwint(void)
+{
+ u32 cause, status;
+ int irq;
+
+ clear_c0_status(IE_IRQ0);
+ status = a20r_ack_hwint();
+ cause = read_c0_cause();
+
+ irq = ffs(((cause & status) >> 8) & 0xf8);
+ if (likely(irq > 0))
+ do_IRQ(SNI_A20R_IRQ_BASE + irq - 1);
+ set_c0_status(IE_IRQ0);
+}
+
+void __init sni_a20r_irq_init(void)
+{
+ int i;
+
+ for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++)
+ irq_set_chip_and_handler(i, &a20r_irq_type, handle_level_irq);
+ sni_hwint = a20r_hwint;
+ change_c0_status(ST0_IM, IE_IRQ0);
+ setup_irq(SNI_A20R_IRQ_BASE + 3, &sni_isa_irq);
+}
+
+void sni_a20r_init(void)
+{
+ /* FIXME, remove if not needed */
+}
+
+static int __init snirm_a20r_setup_devinit(void)
+{
+ switch (sni_brd_type) {
+ case SNI_BRD_TOWER_OASIC:
+ case SNI_BRD_MINITOWER:
+ platform_device_register(&snirm_82596_pdev);
+ platform_device_register(&snirm_53c710_pdev);
+ platform_device_register(&sc26xx_pdev);
+ platform_device_register(&a20r_serial8250_device);
+ platform_device_register(&a20r_ds1216_device);
+ sni_eisa_root_init();
+ break;
+ }
+ return 0;
+}
+
+device_initcall(snirm_a20r_setup_devinit);
diff --git a/arch/mips/sni/eisa.c b/arch/mips/sni/eisa.c
new file mode 100644
index 00000000..6827feb4
--- /dev/null
+++ b/arch/mips/sni/eisa.c
@@ -0,0 +1,50 @@
+/*
+ * Virtual EISA root driver.
+ * Acts as a placeholder if we don't have a proper EISA bridge.
+ *
+ * (C) 2003 Marc Zyngier <maz@wild-wind.fr.eu.org>
+ * modified for SNI usage by Thomas Bogendoerfer
+ *
+ * This code is released under the GPL version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/eisa.h>
+#include <linux/init.h>
+
+/* The default EISA device parent (virtual root device).
+ * Now use a platform device, since that's the obvious choice. */
+
+static struct platform_device eisa_root_dev = {
+ .name = "eisa",
+ .id = 0,
+};
+
+static struct eisa_root_device eisa_bus_root = {
+ .dev = &eisa_root_dev.dev,
+ .bus_base_addr = 0,
+ .res = &ioport_resource,
+ .slots = EISA_MAX_SLOTS,
+ .dma_mask = 0xffffffff,
+ .force_probe = 1,
+};
+
+int __init sni_eisa_root_init(void)
+{
+ int r;
+
+ r = platform_device_register(&eisa_root_dev);
+ if (!r)
+ return r;
+
+ dev_set_drvdata(&eisa_root_dev.dev, &eisa_bus_root);
+
+ if (eisa_root_register(&eisa_bus_root)) {
+ /* A real bridge may have been registered before
+ * us. So quietly unregister. */
+ platform_device_unregister(&eisa_root_dev);
+ return -1;
+ }
+ return 0;
+}
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
new file mode 100644
index 00000000..e8e72bb3
--- /dev/null
+++ b/arch/mips/sni/irq.c
@@ -0,0 +1,82 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Copyright (C) 1994 - 2000 Ralf Baechle
+ * Copyright (C) 2006 Thomas Bogendoerfer
+ */
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+
+#include <asm/i8259.h>
+#include <asm/io.h>
+#include <asm/sni.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+
+void (*sni_hwint)(void);
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ sni_hwint();
+}
+
+/* ISA irq handler */
+static irqreturn_t sni_isa_irq_handler(int dummy, void *p)
+{
+ int irq;
+
+ irq = i8259_irq();
+ if (unlikely(irq < 0))
+ return IRQ_NONE;
+
+ generic_handle_irq(irq);
+ return IRQ_HANDLED;
+}
+
+struct irqaction sni_isa_irq = {
+ .handler = sni_isa_irq_handler,
+ .name = "ISA",
+ .flags = IRQF_SHARED | IRQF_DISABLED
+};
+
+/*
+ * On systems with i8259-style interrupt controllers we assume for
+ * driver compatibility reasons interrupts 0 - 15 to be the i8295
+ * interrupts even if the hardware uses a different interrupt numbering.
+ */
+void __init arch_init_irq(void)
+{
+ init_i8259_irqs(); /* Integrated i8259 */
+ switch (sni_brd_type) {
+ case SNI_BRD_10:
+ case SNI_BRD_10NEW:
+ case SNI_BRD_TOWER_OASIC:
+ case SNI_BRD_MINITOWER:
+ sni_a20r_irq_init();
+ break;
+
+ case SNI_BRD_PCI_TOWER:
+ sni_pcit_irq_init();
+ break;
+
+ case SNI_BRD_PCI_TOWER_CPLUS:
+ sni_pcit_cplus_irq_init();
+ break;
+
+ case SNI_BRD_RM200:
+ sni_rm200_irq_init();
+ break;
+
+ case SNI_BRD_PCI_MTOWER:
+ case SNI_BRD_PCI_DESKTOP:
+ case SNI_BRD_PCI_MTOWER_CPLUS:
+ sni_pcimt_irq_init();
+ break;
+ }
+}
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
new file mode 100644
index 00000000..ed3b3d31
--- /dev/null
+++ b/arch/mips/sni/pcimt.c
@@ -0,0 +1,330 @@
+/*
+ * PCIMT specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm/i8259.h>
+#include <asm/irq_cpu.h>
+
+#define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF)
+#define invspace (*(volatile unsigned int *)PCIMT_INVSPACE)
+
+static void __init sni_pcimt_sc_init(void)
+{
+ unsigned int scsiz, sc_size;
+
+ scsiz = cacheconf & 7;
+ if (scsiz == 0) {
+ printk("Second level cache is deactived.\n");
+ return;
+ }
+ if (scsiz >= 6) {
+ printk("Invalid second level cache size configured, "
+ "deactivating second level cache.\n");
+ cacheconf = 0;
+ return;
+ }
+
+ sc_size = 128 << scsiz;
+ printk("%dkb second level cache detected, deactivating.\n", sc_size);
+ cacheconf = 0;
+}
+
+
+/*
+ * A bit more gossip about the iron we're running on ...
+ */
+static inline void sni_pcimt_detect(void)
+{
+ char boardtype[80];
+ unsigned char csmsr;
+ char *p = boardtype;
+ unsigned int asic;
+
+ csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
+
+ p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
+ if ((csmsr & 0x80) == 0)
+ p += sprintf(p, ", board revision %s",
+ (csmsr & 0x20) ? "D" : "C");
+ asic = csmsr & 0x80;
+ asic = (csmsr & 0x08) ? asic : !asic;
+ p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
+ printk("%s.\n", boardtype);
+}
+
+#define PORT(_base,_irq) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ }
+
+static struct plat_serial8250_port pcimt_data[] = {
+ PORT(0x3f8, 4),
+ PORT(0x2f8, 3),
+ { },
+};
+
+static struct platform_device pcimt_serial8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = pcimt_data,
+ },
+};
+
+static struct resource pcimt_cmos_rsrc[] = {
+ {
+ .start = 0x70,
+ .end = 0x71,
+ .flags = IORESOURCE_IO
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device pcimt_cmos_device = {
+ .name = "rtc_cmos",
+ .num_resources = ARRAY_SIZE(pcimt_cmos_rsrc),
+ .resource = pcimt_cmos_rsrc
+};
+
+
+static struct resource sni_io_resource = {
+ .start = 0x00000000UL,
+ .end = 0x03bfffffUL,
+ .name = "PCIMT IO MEM",
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource pcimt_io_resources[] = {
+ {
+ .start = 0x00,
+ .end = 0x1f,
+ .name = "dma1",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x40,
+ .end = 0x5f,
+ .name = "timer",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x60,
+ .end = 0x6f,
+ .name = "keyboard",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x80,
+ .end = 0x8f,
+ .name = "dma page reg",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0xc0,
+ .end = 0xdf,
+ .name = "dma2",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0xcfc,
+ .end = 0xcff,
+ .name = "PCI config data",
+ .flags = IORESOURCE_BUSY
+ }
+};
+
+static struct resource pcimt_mem_resources[] = {
+ {
+ /*
+ * this region should only be 4 bytes long,
+ * but it's 16MB on all RM300C I've checked
+ */
+ .start = 0x1a000000,
+ .end = 0x1affffff,
+ .name = "PCI INT ACK",
+ .flags = IORESOURCE_BUSY
+ }
+};
+
+static struct resource sni_mem_resource = {
+ .start = 0x18000000UL,
+ .end = 0x1fbfffffUL,
+ .name = "PCIMT PCI MEM",
+ .flags = IORESOURCE_MEM
+};
+
+static void __init sni_pcimt_resource_init(void)
+{
+ int i;
+
+ /* request I/O space for devices used on all i[345]86 PCs */
+ for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
+ request_resource(&sni_io_resource, pcimt_io_resources + i);
+ /* request MEM space for devices used on all i[345]86 PCs */
+ for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
+ request_resource(&sni_mem_resource, pcimt_mem_resources + i);
+}
+
+extern struct pci_ops sni_pcimt_ops;
+
+static struct pci_controller sni_controller = {
+ .pci_ops = &sni_pcimt_ops,
+ .mem_resource = &sni_mem_resource,
+ .mem_offset = 0x00000000UL,
+ .io_resource = &sni_io_resource,
+ .io_offset = 0x00000000UL,
+ .io_map_base = SNI_PORT_BASE
+};
+
+static void enable_pcimt_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq - PCIMT_IRQ_INT2);
+
+ *(volatile u8 *) PCIMT_IRQSEL |= mask;
+}
+
+void disable_pcimt_irq(struct irq_data *d)
+{
+ unsigned int mask = ~(1 << (d->irq - PCIMT_IRQ_INT2));
+
+ *(volatile u8 *) PCIMT_IRQSEL &= mask;
+}
+
+static struct irq_chip pcimt_irq_type = {
+ .name = "PCIMT",
+ .irq_mask = disable_pcimt_irq,
+ .irq_unmask = enable_pcimt_irq,
+};
+
+/*
+ * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
+ * button interrupts. Later ...
+ */
+static void pcimt_hwint0(void)
+{
+ panic("Received int0 but no handler yet ...");
+}
+
+/*
+ * hwint 1 deals with EISA and SCSI interrupts,
+ *
+ * The EISA_INT bit in CSITPEND is high active, all others are low active.
+ */
+static void pcimt_hwint1(void)
+{
+ u8 pend = *(volatile char *)PCIMT_CSITPEND;
+ unsigned long flags;
+
+ if (pend & IT_EISA) {
+ int irq;
+ /*
+ * Note: ASIC PCI's builtin interrupt acknowledge feature is
+ * broken. Using it may result in loss of some or all i8259
+ * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
+ */
+ irq = i8259_irq();
+ if (unlikely(irq < 0))
+ return;
+
+ do_IRQ(irq);
+ }
+
+ if (!(pend & IT_SCSI)) {
+ flags = read_c0_status();
+ clear_c0_status(ST0_IM);
+ do_IRQ(PCIMT_IRQ_SCSI);
+ write_c0_status(flags);
+ }
+}
+
+/*
+ * hwint 3 should deal with the PCI A - D interrupts,
+ */
+static void pcimt_hwint3(void)
+{
+ u8 pend = *(volatile char *)PCIMT_CSITPEND;
+ int irq;
+
+ pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
+ pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
+ clear_c0_status(IE_IRQ3);
+ irq = PCIMT_IRQ_INT2 + ffs(pend) - 1;
+ do_IRQ(irq);
+ set_c0_status(IE_IRQ3);
+}
+
+static void sni_pcimt_hwint(void)
+{
+ u32 pending = read_c0_cause() & read_c0_status();
+
+ if (pending & C_IRQ5)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+ else if (pending & C_IRQ4)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 6);
+ else if (pending & C_IRQ3)
+ pcimt_hwint3();
+ else if (pending & C_IRQ1)
+ pcimt_hwint1();
+ else if (pending & C_IRQ0) {
+ pcimt_hwint0();
+ }
+}
+
+void __init sni_pcimt_irq_init(void)
+{
+ int i;
+
+ *(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA;
+ mips_cpu_irq_init();
+ /* Actually we've got more interrupts to handle ... */
+ for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
+ irq_set_chip_and_handler(i, &pcimt_irq_type, handle_level_irq);
+ sni_hwint = sni_pcimt_hwint;
+ change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
+}
+
+void __init sni_pcimt_init(void)
+{
+ sni_pcimt_detect();
+ sni_pcimt_sc_init();
+ ioport_resource.end = sni_io_resource.end;
+#ifdef CONFIG_PCI
+ PCIBIOS_MIN_IO = 0x9000;
+ register_pci_controller(&sni_controller);
+#endif
+ sni_pcimt_resource_init();
+}
+
+static int __init snirm_pcimt_setup_devinit(void)
+{
+ switch (sni_brd_type) {
+ case SNI_BRD_PCI_MTOWER:
+ case SNI_BRD_PCI_DESKTOP:
+ case SNI_BRD_PCI_MTOWER_CPLUS:
+ platform_device_register(&pcimt_serial8250_device);
+ platform_device_register(&pcimt_cmos_device);
+ break;
+ }
+
+ return 0;
+}
+
+device_initcall(snirm_pcimt_setup_devinit);
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
new file mode 100644
index 00000000..b5246373
--- /dev/null
+++ b/arch/mips/sni/pcit.c
@@ -0,0 +1,289 @@
+/*
+ * PCI Tower specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm/irq_cpu.h>
+
+
+#define PORT(_base,_irq) \
+ { \
+ .iobase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_PORT, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ }
+
+static struct plat_serial8250_port pcit_data[] = {
+ PORT(0x3f8, 0),
+ PORT(0x2f8, 3),
+ { },
+};
+
+static struct platform_device pcit_serial8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = pcit_data,
+ },
+};
+
+static struct plat_serial8250_port pcit_cplus_data[] = {
+ PORT(0x3f8, 0),
+ PORT(0x2f8, 3),
+ PORT(0x3e8, 4),
+ PORT(0x2e8, 3),
+ { },
+};
+
+static struct platform_device pcit_cplus_serial8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = pcit_cplus_data,
+ },
+};
+
+static struct resource pcit_cmos_rsrc[] = {
+ {
+ .start = 0x70,
+ .end = 0x71,
+ .flags = IORESOURCE_IO
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device pcit_cmos_device = {
+ .name = "rtc_cmos",
+ .num_resources = ARRAY_SIZE(pcit_cmos_rsrc),
+ .resource = pcit_cmos_rsrc
+};
+
+static struct platform_device pcit_pcspeaker_pdev = {
+ .name = "pcspkr",
+ .id = -1,
+};
+
+static struct resource sni_io_resource = {
+ .start = 0x00000000UL,
+ .end = 0x03bfffffUL,
+ .name = "PCIT IO",
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource pcit_io_resources[] = {
+ {
+ .start = 0x00,
+ .end = 0x1f,
+ .name = "dma1",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x40,
+ .end = 0x5f,
+ .name = "timer",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x60,
+ .end = 0x6f,
+ .name = "keyboard",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0x80,
+ .end = 0x8f,
+ .name = "dma page reg",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0xc0,
+ .end = 0xdf,
+ .name = "dma2",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0xcf8,
+ .end = 0xcfb,
+ .name = "PCI config addr",
+ .flags = IORESOURCE_BUSY
+ }, {
+ .start = 0xcfc,
+ .end = 0xcff,
+ .name = "PCI config data",
+ .flags = IORESOURCE_BUSY
+ }
+};
+
+static struct resource sni_mem_resource = {
+ .start = 0x18000000UL,
+ .end = 0x1fbfffffUL,
+ .name = "PCIT PCI MEM",
+ .flags = IORESOURCE_MEM
+};
+
+static void __init sni_pcit_resource_init(void)
+{
+ int i;
+
+ /* request I/O space for devices used on all i[345]86 PCs */
+ for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++)
+ request_resource(&sni_io_resource, pcit_io_resources + i);
+}
+
+
+extern struct pci_ops sni_pcit_ops;
+
+static struct pci_controller sni_pcit_controller = {
+ .pci_ops = &sni_pcit_ops,
+ .mem_resource = &sni_mem_resource,
+ .mem_offset = 0x00000000UL,
+ .io_resource = &sni_io_resource,
+ .io_offset = 0x00000000UL,
+ .io_map_base = SNI_PORT_BASE
+};
+
+static void enable_pcit_irq(struct irq_data *d)
+{
+ u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);
+
+ *(volatile u32 *)SNI_PCIT_INT_REG |= mask;
+}
+
+void disable_pcit_irq(struct irq_data *d)
+{
+ u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);
+
+ *(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
+}
+
+static struct irq_chip pcit_irq_type = {
+ .name = "PCIT",
+ .irq_mask = disable_pcit_irq,
+ .irq_unmask = enable_pcit_irq,
+};
+
+static void pcit_hwint1(void)
+{
+ u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
+ int irq;
+
+ clear_c0_status(IE_IRQ1);
+ irq = ffs((pending >> 16) & 0x7f);
+
+ if (likely(irq > 0))
+ do_IRQ(irq + SNI_PCIT_INT_START - 1);
+ set_c0_status(IE_IRQ1);
+}
+
+static void pcit_hwint0(void)
+{
+ u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
+ int irq;
+
+ clear_c0_status(IE_IRQ0);
+ irq = ffs((pending >> 16) & 0x3f);
+
+ if (likely(irq > 0))
+ do_IRQ(irq + SNI_PCIT_INT_START - 1);
+ set_c0_status(IE_IRQ0);
+}
+
+static void sni_pcit_hwint(void)
+{
+ u32 pending = read_c0_cause() & read_c0_status();
+
+ if (pending & C_IRQ1)
+ pcit_hwint1();
+ else if (pending & C_IRQ2)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 4);
+ else if (pending & C_IRQ3)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 5);
+ else if (pending & C_IRQ5)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+}
+
+static void sni_pcit_hwint_cplus(void)
+{
+ u32 pending = read_c0_cause() & read_c0_status();
+
+ if (pending & C_IRQ0)
+ pcit_hwint0();
+ else if (pending & C_IRQ1)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 3);
+ else if (pending & C_IRQ2)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 4);
+ else if (pending & C_IRQ3)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 5);
+ else if (pending & C_IRQ5)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+}
+
+void __init sni_pcit_irq_init(void)
+{
+ int i;
+
+ mips_cpu_irq_init();
+ for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
+ irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
+ *(volatile u32 *)SNI_PCIT_INT_REG = 0;
+ sni_hwint = sni_pcit_hwint;
+ change_c0_status(ST0_IM, IE_IRQ1);
+ setup_irq(SNI_PCIT_INT_START + 6, &sni_isa_irq);
+}
+
+void __init sni_pcit_cplus_irq_init(void)
+{
+ int i;
+
+ mips_cpu_irq_init();
+ for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
+ irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
+ *(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000;
+ sni_hwint = sni_pcit_hwint_cplus;
+ change_c0_status(ST0_IM, IE_IRQ0);
+ setup_irq(MIPS_CPU_IRQ_BASE + 3, &sni_isa_irq);
+}
+
+void __init sni_pcit_init(void)
+{
+ ioport_resource.end = sni_io_resource.end;
+#ifdef CONFIG_PCI
+ PCIBIOS_MIN_IO = 0x9000;
+ register_pci_controller(&sni_pcit_controller);
+#endif
+ sni_pcit_resource_init();
+}
+
+static int __init snirm_pcit_setup_devinit(void)
+{
+ switch (sni_brd_type) {
+ case SNI_BRD_PCI_TOWER:
+ platform_device_register(&pcit_serial8250_device);
+ platform_device_register(&pcit_cmos_device);
+ platform_device_register(&pcit_pcspeaker_pdev);
+ break;
+
+ case SNI_BRD_PCI_TOWER_CPLUS:
+ platform_device_register(&pcit_cplus_serial8250_device);
+ platform_device_register(&pcit_cmos_device);
+ platform_device_register(&pcit_pcspeaker_pdev);
+ break;
+ }
+ return 0;
+}
+
+device_initcall(snirm_pcit_setup_devinit);
diff --git a/arch/mips/sni/reset.c b/arch/mips/sni/reset.c
new file mode 100644
index 00000000..79f8d70f
--- /dev/null
+++ b/arch/mips/sni/reset.c
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/mips/sni/process.c
+ *
+ * Reset a SNI machine.
+ */
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <asm/sni.h>
+
+/*
+ * This routine reboots the machine by asking the keyboard
+ * controller to pulse the reset-line low. We try that for a while,
+ * and if it doesn't work, we do some other stupid things.
+ */
+static inline void kb_wait(void)
+{
+ int i;
+
+ for (i = 0; i < 0x10000; i++)
+ if ((inb_p(0x64) & 0x02) == 0)
+ break;
+}
+
+/* XXX This ends up at the ARC firmware prompt ... */
+void sni_machine_restart(char *command)
+{
+ int i, j;
+
+ /* This does a normal via the keyboard controller like a PC.
+ We can do that easier ... */
+ local_irq_disable();
+ for (;;) {
+ for (i = 0; i < 100; i++) {
+ kb_wait();
+ for (j = 0; j < 100000 ; j++)
+ /* nothing */;
+ outb_p(0xfe, 0x64); /* pulse reset low */
+ }
+ }
+}
+
+void sni_machine_power_off(void)
+{
+ *(volatile unsigned char *)PCIMT_CSWCSM = 0xfd;
+}
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
new file mode 100644
index 00000000..a7e5a6d9
--- /dev/null
+++ b/arch/mips/sni/rm200.c
@@ -0,0 +1,489 @@
+/*
+ * RM200 specific code
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ *
+ * i8259 parts ripped out of arch/mips/kernel/i8259.c
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/io.h>
+
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm/irq_cpu.h>
+
+#define RM200_I8259A_IRQ_BASE 32
+
+#define MEMPORT(_base,_irq) \
+ { \
+ .mapbase = _base, \
+ .irq = _irq, \
+ .uartclk = 1843200, \
+ .iotype = UPIO_MEM, \
+ .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP, \
+ }
+
+static struct plat_serial8250_port rm200_data[] = {
+ MEMPORT(0x160003f8, RM200_I8259A_IRQ_BASE + 4),
+ MEMPORT(0x160002f8, RM200_I8259A_IRQ_BASE + 3),
+ { },
+};
+
+static struct platform_device rm200_serial8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = rm200_data,
+ },
+};
+
+static struct resource rm200_ds1216_rsrc[] = {
+ {
+ .start = 0x1cd41ffc,
+ .end = 0x1cd41fff,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct platform_device rm200_ds1216_device = {
+ .name = "rtc-ds1216",
+ .num_resources = ARRAY_SIZE(rm200_ds1216_rsrc),
+ .resource = rm200_ds1216_rsrc
+};
+
+static struct resource snirm_82596_rm200_rsrc[] = {
+ {
+ .start = 0x18000000,
+ .end = 0x180fffff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 0x1b000000,
+ .end = 0x1b000004,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 0x1ff00000,
+ .end = 0x1ff00020,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 27,
+ .end = 27,
+ .flags = IORESOURCE_IRQ
+ },
+ {
+ .flags = 0x00
+ }
+};
+
+static struct platform_device snirm_82596_rm200_pdev = {
+ .name = "snirm_82596",
+ .num_resources = ARRAY_SIZE(snirm_82596_rm200_rsrc),
+ .resource = snirm_82596_rm200_rsrc
+};
+
+static struct resource snirm_53c710_rm200_rsrc[] = {
+ {
+ .start = 0x19000000,
+ .end = 0x190fffff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = 26,
+ .end = 26,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device snirm_53c710_rm200_pdev = {
+ .name = "snirm_53c710",
+ .num_resources = ARRAY_SIZE(snirm_53c710_rm200_rsrc),
+ .resource = snirm_53c710_rm200_rsrc
+};
+
+static int __init snirm_setup_devinit(void)
+{
+ if (sni_brd_type == SNI_BRD_RM200) {
+ platform_device_register(&rm200_serial8250_device);
+ platform_device_register(&rm200_ds1216_device);
+ platform_device_register(&snirm_82596_rm200_pdev);
+ platform_device_register(&snirm_53c710_rm200_pdev);
+ sni_eisa_root_init();
+ }
+ return 0;
+}
+
+device_initcall(snirm_setup_devinit);
+
+/*
+ * RM200 has an ISA and an EISA bus. The iSA bus is only used
+ * for onboard devices and also has twi i8259 PICs. Since these
+ * PICs are no accessible via inb/outb the following code uses
+ * readb/writeb to access them
+ */
+
+static DEFINE_RAW_SPINLOCK(sni_rm200_i8259A_lock);
+#define PIC_CMD 0x00
+#define PIC_IMR 0x01
+#define PIC_ISR PIC_CMD
+#define PIC_POLL PIC_ISR
+#define PIC_OCW3 PIC_ISR
+
+/* i8259A PIC related value */
+#define PIC_CASCADE_IR 2
+#define MASTER_ICW4_DEFAULT 0x01
+#define SLAVE_ICW4_DEFAULT 0x01
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static unsigned int rm200_cached_irq_mask = 0xffff;
+static __iomem u8 *rm200_pic_master;
+static __iomem u8 *rm200_pic_slave;
+
+#define cached_master_mask (rm200_cached_irq_mask)
+#define cached_slave_mask (rm200_cached_irq_mask >> 8)
+
+static void sni_rm200_disable_8259A_irq(struct irq_data *d)
+{
+ unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE;
+ unsigned long flags;
+
+ mask = 1 << irq;
+ raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
+ rm200_cached_irq_mask |= mask;
+ if (irq & 8)
+ writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
+ else
+ writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
+ raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
+}
+
+static void sni_rm200_enable_8259A_irq(struct irq_data *d)
+{
+ unsigned int mask, irq = d->irq - RM200_I8259A_IRQ_BASE;
+ unsigned long flags;
+
+ mask = ~(1 << irq);
+ raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
+ rm200_cached_irq_mask &= mask;
+ if (irq & 8)
+ writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
+ else
+ writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
+ raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
+}
+
+static inline int sni_rm200_i8259A_irq_real(unsigned int irq)
+{
+ int value;
+ int irqmask = 1 << irq;
+
+ if (irq < 8) {
+ writeb(0x0B, rm200_pic_master + PIC_CMD);
+ value = readb(rm200_pic_master + PIC_CMD) & irqmask;
+ writeb(0x0A, rm200_pic_master + PIC_CMD);
+ return value;
+ }
+ writeb(0x0B, rm200_pic_slave + PIC_CMD); /* ISR register */
+ value = readb(rm200_pic_slave + PIC_CMD) & (irqmask >> 8);
+ writeb(0x0A, rm200_pic_slave + PIC_CMD);
+ return value;
+}
+
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+void sni_rm200_mask_and_ack_8259A(struct irq_data *d)
+{
+ unsigned int irqmask, irq = d->irq - RM200_I8259A_IRQ_BASE;
+ unsigned long flags;
+
+ irqmask = 1 << irq;
+ raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
+ /*
+ * Lightweight spurious IRQ detection. We do not want
+ * to overdo spurious IRQ handling - it's usually a sign
+ * of hardware problems, so we only do the checks we can
+ * do without slowing down good hardware unnecessarily.
+ *
+ * Note that IRQ7 and IRQ15 (the two spurious IRQs
+ * usually resulting from the 8259A-1|2 PICs) occur
+ * even if the IRQ is masked in the 8259A. Thus we
+ * can check spurious 8259A IRQs without doing the
+ * quite slow i8259A_irq_real() call for every IRQ.
+ * This does not cover 100% of spurious interrupts,
+ * but should be enough to warn the user that there
+ * is something bad going on ...
+ */
+ if (rm200_cached_irq_mask & irqmask)
+ goto spurious_8259A_irq;
+ rm200_cached_irq_mask |= irqmask;
+
+handle_real_irq:
+ if (irq & 8) {
+ readb(rm200_pic_slave + PIC_IMR);
+ writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
+ writeb(0x60+(irq & 7), rm200_pic_slave + PIC_CMD);
+ writeb(0x60+PIC_CASCADE_IR, rm200_pic_master + PIC_CMD);
+ } else {
+ readb(rm200_pic_master + PIC_IMR);
+ writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
+ writeb(0x60+irq, rm200_pic_master + PIC_CMD);
+ }
+ raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
+ return;
+
+spurious_8259A_irq:
+ /*
+ * this is the slow path - should happen rarely.
+ */
+ if (sni_rm200_i8259A_irq_real(irq))
+ /*
+ * oops, the IRQ _is_ in service according to the
+ * 8259A - not spurious, go handle it.
+ */
+ goto handle_real_irq;
+
+ {
+ static int spurious_irq_mask;
+ /*
+ * At this point we can be sure the IRQ is spurious,
+ * lets ACK and report it. [once per IRQ]
+ */
+ if (!(spurious_irq_mask & irqmask)) {
+ printk(KERN_DEBUG
+ "spurious RM200 8259A interrupt: IRQ%d.\n", irq);
+ spurious_irq_mask |= irqmask;
+ }
+ atomic_inc(&irq_err_count);
+ /*
+ * Theoretically we do not have to handle this IRQ,
+ * but in Linux this does not cause problems and is
+ * simpler for us.
+ */
+ goto handle_real_irq;
+ }
+}
+
+static struct irq_chip sni_rm200_i8259A_chip = {
+ .name = "RM200-XT-PIC",
+ .irq_mask = sni_rm200_disable_8259A_irq,
+ .irq_unmask = sni_rm200_enable_8259A_irq,
+ .irq_mask_ack = sni_rm200_mask_and_ack_8259A,
+};
+
+/*
+ * Do the traditional i8259 interrupt polling thing. This is for the few
+ * cases where no better interrupt acknowledge method is available and we
+ * absolutely must touch the i8259.
+ */
+static inline int sni_rm200_i8259_irq(void)
+{
+ int irq;
+
+ raw_spin_lock(&sni_rm200_i8259A_lock);
+
+ /* Perform an interrupt acknowledge cycle on controller 1. */
+ writeb(0x0C, rm200_pic_master + PIC_CMD); /* prepare for poll */
+ irq = readb(rm200_pic_master + PIC_CMD) & 7;
+ if (irq == PIC_CASCADE_IR) {
+ /*
+ * Interrupt is cascaded so perform interrupt
+ * acknowledge on controller 2.
+ */
+ writeb(0x0C, rm200_pic_slave + PIC_CMD); /* prepare for poll */
+ irq = (readb(rm200_pic_slave + PIC_CMD) & 7) + 8;
+ }
+
+ if (unlikely(irq == 7)) {
+ /*
+ * This may be a spurious interrupt.
+ *
+ * Read the interrupt status register (ISR). If the most
+ * significant bit is not set then there is no valid
+ * interrupt.
+ */
+ writeb(0x0B, rm200_pic_master + PIC_ISR); /* ISR register */
+ if (~readb(rm200_pic_master + PIC_ISR) & 0x80)
+ irq = -1;
+ }
+
+ raw_spin_unlock(&sni_rm200_i8259A_lock);
+
+ return likely(irq >= 0) ? irq + RM200_I8259A_IRQ_BASE : irq;
+}
+
+void sni_rm200_init_8259A(void)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&sni_rm200_i8259A_lock, flags);
+
+ writeb(0xff, rm200_pic_master + PIC_IMR);
+ writeb(0xff, rm200_pic_slave + PIC_IMR);
+
+ writeb(0x11, rm200_pic_master + PIC_CMD);
+ writeb(0, rm200_pic_master + PIC_IMR);
+ writeb(1U << PIC_CASCADE_IR, rm200_pic_master + PIC_IMR);
+ writeb(MASTER_ICW4_DEFAULT, rm200_pic_master + PIC_IMR);
+ writeb(0x11, rm200_pic_slave + PIC_CMD);
+ writeb(8, rm200_pic_slave + PIC_IMR);
+ writeb(PIC_CASCADE_IR, rm200_pic_slave + PIC_IMR);
+ writeb(SLAVE_ICW4_DEFAULT, rm200_pic_slave + PIC_IMR);
+ udelay(100); /* wait for 8259A to initialize */
+
+ writeb(cached_master_mask, rm200_pic_master + PIC_IMR);
+ writeb(cached_slave_mask, rm200_pic_slave + PIC_IMR);
+
+ raw_spin_unlock_irqrestore(&sni_rm200_i8259A_lock, flags);
+}
+
+/*
+ * IRQ2 is cascade interrupt to second interrupt controller
+ */
+static struct irqaction sni_rm200_irq2 = {
+ .handler = no_action,
+ .name = "cascade",
+};
+
+static struct resource sni_rm200_pic1_resource = {
+ .name = "onboard ISA pic1",
+ .start = 0x16000020,
+ .end = 0x16000023,
+ .flags = IORESOURCE_BUSY
+};
+
+static struct resource sni_rm200_pic2_resource = {
+ .name = "onboard ISA pic2",
+ .start = 0x160000a0,
+ .end = 0x160000a3,
+ .flags = IORESOURCE_BUSY
+};
+
+/* ISA irq handler */
+static irqreturn_t sni_rm200_i8259A_irq_handler(int dummy, void *p)
+{
+ int irq;
+
+ irq = sni_rm200_i8259_irq();
+ if (unlikely(irq < 0))
+ return IRQ_NONE;
+
+ do_IRQ(irq);
+ return IRQ_HANDLED;
+}
+
+struct irqaction sni_rm200_i8259A_irq = {
+ .handler = sni_rm200_i8259A_irq_handler,
+ .name = "onboard ISA",
+ .flags = IRQF_SHARED
+};
+
+void __init sni_rm200_i8259_irqs(void)
+{
+ int i;
+
+ rm200_pic_master = ioremap_nocache(0x16000020, 4);
+ if (!rm200_pic_master)
+ return;
+ rm200_pic_slave = ioremap_nocache(0x160000a0, 4);
+ if (!rm200_pic_slave) {
+ iounmap(rm200_pic_master);
+ return;
+ }
+
+ insert_resource(&iomem_resource, &sni_rm200_pic1_resource);
+ insert_resource(&iomem_resource, &sni_rm200_pic2_resource);
+
+ sni_rm200_init_8259A();
+
+ for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++)
+ irq_set_chip_and_handler(i, &sni_rm200_i8259A_chip,
+ handle_level_irq);
+
+ setup_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, &sni_rm200_irq2);
+}
+
+
+#define SNI_RM200_INT_STAT_REG CKSEG1ADDR(0xbc000000)
+#define SNI_RM200_INT_ENA_REG CKSEG1ADDR(0xbc080000)
+
+#define SNI_RM200_INT_START 24
+#define SNI_RM200_INT_END 28
+
+static void enable_rm200_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START);
+
+ *(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask;
+}
+
+void disable_rm200_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq - SNI_RM200_INT_START);
+
+ *(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask;
+}
+
+static struct irq_chip rm200_irq_type = {
+ .name = "RM200",
+ .irq_mask = disable_rm200_irq,
+ .irq_unmask = enable_rm200_irq,
+};
+
+static void sni_rm200_hwint(void)
+{
+ u32 pending = read_c0_cause() & read_c0_status();
+ u8 mask;
+ u8 stat;
+ int irq;
+
+ if (pending & C_IRQ5)
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+ else if (pending & C_IRQ0) {
+ clear_c0_status(IE_IRQ0);
+ mask = *(volatile u8 *)SNI_RM200_INT_ENA_REG ^ 0x1f;
+ stat = *(volatile u8 *)SNI_RM200_INT_STAT_REG ^ 0x14;
+ irq = ffs(stat & mask & 0x1f);
+
+ if (likely(irq > 0))
+ do_IRQ(irq + SNI_RM200_INT_START - 1);
+ set_c0_status(IE_IRQ0);
+ }
+}
+
+void __init sni_rm200_irq_init(void)
+{
+ int i;
+
+ * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f;
+
+ sni_rm200_i8259_irqs();
+ mips_cpu_irq_init();
+ /* Actually we've got more interrupts to handle ... */
+ for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
+ irq_set_chip_and_handler(i, &rm200_irq_type, handle_level_irq);
+ sni_hwint = sni_rm200_hwint;
+ change_c0_status(ST0_IM, IE_IRQ0);
+ setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq);
+ setup_irq(SNI_RM200_INT_START + 1, &sni_isa_irq);
+}
+
+void __init sni_rm200_init(void)
+{
+}
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c
new file mode 100644
index 00000000..d16b4621
--- /dev/null
+++ b/arch/mips/sni/setup.c
@@ -0,0 +1,261 @@
+/*
+ * Setup pointers to hardware-dependent routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ */
+#include <linux/eisa.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fb.h>
+#include <linux/screen_info.h>
+
+#ifdef CONFIG_ARC
+#include <asm/fw/arc/types.h>
+#include <asm/sgialib.h>
+#endif
+
+#ifdef CONFIG_SNIPROM
+#include <asm/mipsprom.h>
+#endif
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/sni.h>
+
+unsigned int sni_brd_type;
+EXPORT_SYMBOL(sni_brd_type);
+
+extern void sni_machine_restart(char *command);
+extern void sni_machine_power_off(void);
+
+static void __init sni_display_setup(void)
+{
+#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_ARC)
+ struct screen_info *si = &screen_info;
+ DISPLAY_STATUS *di;
+
+ di = ArcGetDisplayStatus(1);
+
+ if (di) {
+ si->orig_x = di->CursorXPosition;
+ si->orig_y = di->CursorYPosition;
+ si->orig_video_cols = di->CursorMaxXPosition;
+ si->orig_video_lines = di->CursorMaxYPosition;
+ si->orig_video_isVGA = VIDEO_TYPE_VGAC;
+ si->orig_video_points = 16;
+ }
+#endif
+}
+
+static void __init sni_console_setup(void)
+{
+#ifndef CONFIG_ARC
+ char *ctype;
+ char *cdev;
+ char *baud;
+ int port;
+ static char options[8] __initdata;
+
+ cdev = prom_getenv("console_dev");
+ if (strncmp(cdev, "tty", 3) == 0) {
+ ctype = prom_getenv("console");
+ switch (*ctype) {
+ default:
+ case 'l':
+ port = 0;
+ baud = prom_getenv("lbaud");
+ break;
+ case 'r':
+ port = 1;
+ baud = prom_getenv("rbaud");
+ break;
+ }
+ if (baud)
+ strcpy(options, baud);
+ if (strncmp(cdev, "tty552", 6) == 0)
+ add_preferred_console("ttyS", port,
+ baud ? options : NULL);
+ else
+ add_preferred_console("ttySC", port,
+ baud ? options : NULL);
+ }
+#endif
+}
+
+#ifdef DEBUG
+static void __init sni_idprom_dump(void)
+{
+ int i;
+
+ pr_debug("SNI IDProm dump:\n");
+ for (i = 0; i < 256; i++) {
+ if (i%16 == 0)
+ pr_debug("%04x ", i);
+
+ printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));
+
+ if (i % 16 == 15)
+ printk("\n");
+ }
+}
+#endif
+
+void __init plat_mem_setup(void)
+{
+ int cputype;
+
+ set_io_port_base(SNI_PORT_BASE);
+// ioport_resource.end = sni_io_resource.end;
+
+ /*
+ * Setup (E)ISA I/O memory access stuff
+ */
+#ifdef CONFIG_EISA
+ EISA_bus = 1;
+#endif
+
+ sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
+ cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
+ switch (sni_brd_type) {
+ case SNI_BRD_TOWER_OASIC:
+ switch (cputype) {
+ case SNI_CPU_M8030:
+ system_type = "RM400-330";
+ break;
+ case SNI_CPU_M8031:
+ system_type = "RM400-430";
+ break;
+ case SNI_CPU_M8037:
+ system_type = "RM400-530";
+ break;
+ case SNI_CPU_M8034:
+ system_type = "RM400-730";
+ break;
+ default:
+ system_type = "RM400-xxx";
+ break;
+ }
+ break;
+ case SNI_BRD_MINITOWER:
+ switch (cputype) {
+ case SNI_CPU_M8021:
+ case SNI_CPU_M8043:
+ system_type = "RM400-120";
+ break;
+ case SNI_CPU_M8040:
+ system_type = "RM400-220";
+ break;
+ case SNI_CPU_M8053:
+ system_type = "RM400-225";
+ break;
+ case SNI_CPU_M8050:
+ system_type = "RM400-420";
+ break;
+ default:
+ system_type = "RM400-xxx";
+ break;
+ }
+ break;
+ case SNI_BRD_PCI_TOWER:
+ system_type = "RM400-Cxx";
+ break;
+ case SNI_BRD_RM200:
+ system_type = "RM200-xxx";
+ break;
+ case SNI_BRD_PCI_MTOWER:
+ system_type = "RM300-Cxx";
+ break;
+ case SNI_BRD_PCI_DESKTOP:
+ switch (read_c0_prid() & 0xff00) {
+ case PRID_IMP_R4600:
+ case PRID_IMP_R4700:
+ system_type = "RM200-C20";
+ break;
+ case PRID_IMP_R5000:
+ system_type = "RM200-C40";
+ break;
+ default:
+ system_type = "RM200-Cxx";
+ break;
+ }
+ break;
+ case SNI_BRD_PCI_TOWER_CPLUS:
+ system_type = "RM400-Exx";
+ break;
+ case SNI_BRD_PCI_MTOWER_CPLUS:
+ system_type = "RM300-Exx";
+ break;
+ }
+ pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type, system_type);
+
+#ifdef DEBUG
+ sni_idprom_dump();
+#endif
+
+ switch (sni_brd_type) {
+ case SNI_BRD_10:
+ case SNI_BRD_10NEW:
+ case SNI_BRD_TOWER_OASIC:
+ case SNI_BRD_MINITOWER:
+ sni_a20r_init();
+ break;
+
+ case SNI_BRD_PCI_TOWER:
+ case SNI_BRD_PCI_TOWER_CPLUS:
+ sni_pcit_init();
+ break;
+
+ case SNI_BRD_RM200:
+ sni_rm200_init();
+ break;
+
+ case SNI_BRD_PCI_MTOWER:
+ case SNI_BRD_PCI_DESKTOP:
+ case SNI_BRD_PCI_MTOWER_CPLUS:
+ sni_pcimt_init();
+ break;
+ }
+
+ _machine_restart = sni_machine_restart;
+ pm_power_off = sni_machine_power_off;
+
+ sni_display_setup();
+ sni_console_setup();
+}
+
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+#include <video/vga.h>
+#include <video/cirrus.h>
+
+static void __devinit quirk_cirrus_ram_size(struct pci_dev *dev)
+{
+ u16 cmd;
+
+ /*
+ * firmware doesn't set the ram size correct, so we
+ * need to do it here, otherwise we get screen corruption
+ * on older Cirrus chips
+ */
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ if ((cmd & (PCI_COMMAND_IO|PCI_COMMAND_MEMORY))
+ == (PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) {
+ vga_wseq(NULL, CL_SEQR6, 0x12); /* unlock all extension registers */
+ vga_wseq(NULL, CL_SEQRF, 0x18);
+ }
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5434_8,
+ quirk_cirrus_ram_size);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5436,
+ quirk_cirrus_ram_size);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446,
+ quirk_cirrus_ram_size);
+#endif
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
new file mode 100644
index 00000000..0904d4d3
--- /dev/null
+++ b/arch/mips/sni/time.c
@@ -0,0 +1,190 @@
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/smp.h>
+#include <linux/time.h>
+#include <linux/clockchips.h>
+
+#include <asm/i8253.h>
+#include <asm/sni.h>
+#include <asm/time.h>
+#include <asm-generic/rtc.h>
+
+#define SNI_CLOCK_TICK_RATE 3686400
+#define SNI_COUNTER2_DIV 64
+#define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ)
+
+static void a20r_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34;
+ wmb();
+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV;
+ wmb();
+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8;
+ wmb();
+
+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4;
+ wmb();
+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV;
+ wmb();
+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8;
+ wmb();
+
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device a20r_clockevent_device = {
+ .name = "a20r-timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+
+ /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
+
+ .rating = 300,
+ .irq = SNI_A20R_IRQ_TIMER,
+ .set_mode = a20r_set_mode,
+};
+
+static irqreturn_t a20r_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = dev_id;
+
+ *(volatile u8 *)A20R_PT_TIM0_ACK = 0;
+ wmb();
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction a20r_irqaction = {
+ .handler = a20r_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .name = "a20r-timer",
+};
+
+/*
+ * a20r platform uses 2 counters to divide the input frequency.
+ * Counter 2 output is connected to Counter 0 & 1 input.
+ */
+static void __init sni_a20r_timer_setup(void)
+{
+ struct clock_event_device *cd = &a20r_clockevent_device;
+ struct irqaction *action = &a20r_irqaction;
+ unsigned int cpu = smp_processor_id();
+
+ cd->cpumask = cpumask_of(cpu);
+ clockevents_register_device(cd);
+ action->dev_id = cd;
+ setup_irq(SNI_A20R_IRQ_TIMER, &a20r_irqaction);
+}
+
+#define SNI_8254_TICK_RATE 1193182UL
+
+#define SNI_8254_TCSAMP_COUNTER ((SNI_8254_TICK_RATE / HZ) + 255)
+
+static __init unsigned long dosample(void)
+{
+ u32 ct0, ct1;
+ volatile u8 msb;
+
+ /* Start the counter. */
+ outb_p(0x34, 0x43);
+ outb_p(SNI_8254_TCSAMP_COUNTER & 0xff, 0x40);
+ outb(SNI_8254_TCSAMP_COUNTER >> 8, 0x40);
+
+ /* Get initial counter invariant */
+ ct0 = read_c0_count();
+
+ /* Latch and spin until top byte of counter0 is zero */
+ do {
+ outb(0x00, 0x43);
+ (void) inb(0x40);
+ msb = inb(0x40);
+ ct1 = read_c0_count();
+ } while (msb);
+
+ /* Stop the counter. */
+ outb(0x38, 0x43);
+ /*
+ * Return the difference, this is how far the r4k counter increments
+ * for every 1/HZ seconds. We round off the nearest 1 MHz of master
+ * clock (= 1000000 / HZ / 2).
+ */
+ /*return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ);*/
+ return (ct1 - ct0) / (500000/HZ) * (500000/HZ);
+}
+
+/*
+ * Here we need to calibrate the cycle counter to at least be close.
+ */
+void __init plat_time_init(void)
+{
+ unsigned long r4k_ticks[3];
+ unsigned long r4k_tick;
+
+ /*
+ * Figure out the r4k offset, the algorithm is very simple and works in
+ * _all_ cases as long as the 8254 counter register itself works ok (as
+ * an interrupt driving timer it does not because of bug, this is why
+ * we are using the onchip r4k counter/compare register to serve this
+ * purpose, but for r4k_offset calculation it will work ok for us).
+ * There are other very complicated ways of performing this calculation
+ * but this one works just fine so I am not going to futz around. ;-)
+ */
+ printk(KERN_INFO "Calibrating system timer... ");
+ dosample(); /* Prime cache. */
+ dosample(); /* Prime cache. */
+ /* Zero is NOT an option. */
+ do {
+ r4k_ticks[0] = dosample();
+ } while (!r4k_ticks[0]);
+ do {
+ r4k_ticks[1] = dosample();
+ } while (!r4k_ticks[1]);
+
+ if (r4k_ticks[0] != r4k_ticks[1]) {
+ printk("warning: timer counts differ, retrying... ");
+ r4k_ticks[2] = dosample();
+ if (r4k_ticks[2] == r4k_ticks[0]
+ || r4k_ticks[2] == r4k_ticks[1])
+ r4k_tick = r4k_ticks[2];
+ else {
+ printk("disagreement, using average... ");
+ r4k_tick = (r4k_ticks[0] + r4k_ticks[1]
+ + r4k_ticks[2]) / 3;
+ }
+ } else
+ r4k_tick = r4k_ticks[0];
+
+ printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick,
+ (int) (r4k_tick / (500000 / HZ)),
+ (int) (r4k_tick % (500000 / HZ)));
+
+ mips_hpt_frequency = r4k_tick * HZ;
+
+ switch (sni_brd_type) {
+ case SNI_BRD_10:
+ case SNI_BRD_10NEW:
+ case SNI_BRD_TOWER_OASIC:
+ case SNI_BRD_MINITOWER:
+ sni_a20r_timer_setup();
+ break;
+ }
+ setup_pit_timer();
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+ ts->tv_sec = -1;
+ ts->tv_nsec = 0;
+}
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
new file mode 100644
index 00000000..852ae4bb
--- /dev/null
+++ b/arch/mips/txx9/Kconfig
@@ -0,0 +1,126 @@
+config MACH_TX39XX
+ bool
+ select MACH_TXX9
+ select SYS_HAS_CPU_TX39XX
+
+config MACH_TX49XX
+ bool
+ select MACH_TXX9
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select SYS_HAS_CPU_TX49XX
+ select SYS_SUPPORTS_64BIT_KERNEL
+
+config MACH_TXX9
+ bool
+ select DMA_NONCOHERENT
+ select SWAP_IO_SPACE
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_BIG_ENDIAN
+
+config TOSHIBA_JMR3927
+ bool "Toshiba JMR-TX3927 board"
+ depends on MACH_TX39XX
+ select SOC_TX3927
+
+config TOSHIBA_RBTX4927
+ bool "Toshiba RBTX49[23]7 board"
+ depends on MACH_TX49XX
+ select SOC_TX4927
+ # TX4937 is subset of TX4938
+ select SOC_TX4938
+ help
+ This Toshiba board is based on the TX4927 processor. Say Y here to
+ support this machine type
+
+config TOSHIBA_RBTX4938
+ bool "Toshiba RBTX4938 board"
+ depends on MACH_TX49XX
+ select SOC_TX4938
+ help
+ This Toshiba board is based on the TX4938 processor. Say Y here to
+ support this machine type
+
+config TOSHIBA_RBTX4939
+ bool "Toshiba RBTX4939 board"
+ depends on MACH_TX49XX
+ select SOC_TX4939
+ select TXX9_7SEGLED
+ help
+ This Toshiba board is based on the TX4939 processor. Say Y here to
+ support this machine type
+
+config SOC_TX3927
+ bool
+ select CEVT_TXX9
+ select HAS_TXX9_SERIAL
+ select HW_HAS_PCI
+ select IRQ_TXX9
+ select GPIO_TXX9
+
+config SOC_TX4927
+ bool
+ select CEVT_TXX9
+ select HAS_TXX9_SERIAL
+ select HW_HAS_PCI
+ select IRQ_TXX9
+ select PCI_TX4927
+ select GPIO_TXX9
+ select HAS_TXX9_ACLC
+
+config SOC_TX4938
+ bool
+ select CEVT_TXX9
+ select HAS_TXX9_SERIAL
+ select HW_HAS_PCI
+ select IRQ_TXX9
+ select PCI_TX4927
+ select GPIO_TXX9
+ select HAS_TXX9_ACLC
+
+config SOC_TX4939
+ bool
+ select CEVT_TXX9
+ select HAS_TXX9_SERIAL
+ select HW_HAS_PCI
+ select PCI_TX4927
+ select HAS_TXX9_ACLC
+
+config TXX9_7SEGLED
+ bool
+
+config TOSHIBA_FPCIB0
+ bool "FPCIB0 Backplane Support"
+ depends on PCI && MACH_TXX9
+ select I8259
+
+config PICMG_PCI_BACKPLANE_DEFAULT
+ bool "Support for PICMG PCI Backplane"
+ depends on PCI && MACH_TXX9
+ default y if !TOSHIBA_FPCIB0
+
+if TOSHIBA_RBTX4938
+
+comment "Multiplex Pin Select"
+choice
+ prompt "PIO[58:61]"
+ default TOSHIBA_RBTX4938_MPLEX_PIO58_61
+
+config TOSHIBA_RBTX4938_MPLEX_PIO58_61
+ bool "PIO"
+config TOSHIBA_RBTX4938_MPLEX_NAND
+ bool "NAND"
+config TOSHIBA_RBTX4938_MPLEX_ATA
+ bool "ATA"
+config TOSHIBA_RBTX4938_MPLEX_KEEP
+ bool "Keep firmware settings"
+
+endchoice
+
+endif
+
+config PCI_TX4927
+ bool
diff --git a/arch/mips/txx9/Makefile b/arch/mips/txx9/Makefile
new file mode 100644
index 00000000..34787dab
--- /dev/null
+++ b/arch/mips/txx9/Makefile
@@ -0,0 +1,17 @@
+#
+# Common TXx9
+#
+obj-$(CONFIG_MACH_TX39XX) += generic/
+obj-$(CONFIG_MACH_TX49XX) += generic/
+
+#
+# Toshiba JMR-TX3927 board
+#
+obj-$(CONFIG_TOSHIBA_JMR3927) += jmr3927/
+
+#
+# Toshiba RBTX49XX boards
+#
+obj-$(CONFIG_TOSHIBA_RBTX4927) += rbtx4927/
+obj-$(CONFIG_TOSHIBA_RBTX4938) += rbtx4938/
+obj-$(CONFIG_TOSHIBA_RBTX4939) += rbtx4939/
diff --git a/arch/mips/txx9/Platform b/arch/mips/txx9/Platform
new file mode 100644
index 00000000..a801abbe
--- /dev/null
+++ b/arch/mips/txx9/Platform
@@ -0,0 +1,10 @@
+platform-$(CONFIG_MACH_TX39XX) += txx9/
+platform-$(CONFIG_MACH_TX49XX) += txx9/
+
+cflags-$(CONFIG_MACH_TX39XX) += \
+ -I$(srctree)/arch/mips/include/asm/mach-tx39xx
+cflags-$(CONFIG_MACH_TX49XX) += \
+ -I$(srctree)/arch/mips/include/asm/mach-tx49xx
+
+load-$(CONFIG_MACH_TX39XX) += 0xffffffff80050000
+load-$(CONFIG_MACH_TX49XX) += 0xffffffff80100000
diff --git a/arch/mips/txx9/generic/7segled.c b/arch/mips/txx9/generic/7segled.c
new file mode 100644
index 00000000..7f8416f8
--- /dev/null
+++ b/arch/mips/txx9/generic/7segled.c
@@ -0,0 +1,115 @@
+/*
+ * 7 Segment LED routines
+ * Based on RBTX49xx patch from CELF patch archive.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2005-2007
+ * All Rights Reserved.
+ */
+#include <linux/sysdev.h>
+#include <linux/slab.h>
+#include <linux/map_to_7segment.h>
+#include <asm/txx9/generic.h>
+
+static unsigned int tx_7segled_num;
+static void (*tx_7segled_putc)(unsigned int pos, unsigned char val);
+
+void __init txx9_7segled_init(unsigned int num,
+ void (*putc)(unsigned int pos, unsigned char val))
+{
+ tx_7segled_num = num;
+ tx_7segled_putc = putc;
+}
+
+static SEG7_CONVERSION_MAP(txx9_seg7map, MAP_ASCII7SEG_ALPHANUM_LC);
+
+int txx9_7segled_putc(unsigned int pos, char c)
+{
+ if (pos >= tx_7segled_num)
+ return -EINVAL;
+ c = map_to_seg7(&txx9_seg7map, c);
+ if (c < 0)
+ return c;
+ tx_7segled_putc(pos, c);
+ return 0;
+}
+
+static ssize_t ascii_store(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned int ch = dev->id;
+ txx9_7segled_putc(ch, buf[0]);
+ return size;
+}
+
+static ssize_t raw_store(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ unsigned int ch = dev->id;
+ tx_7segled_putc(ch, buf[0]);
+ return size;
+}
+
+static SYSDEV_ATTR(ascii, 0200, NULL, ascii_store);
+static SYSDEV_ATTR(raw, 0200, NULL, raw_store);
+
+static ssize_t map_seg7_show(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ char *buf)
+{
+ memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map));
+ return sizeof(txx9_seg7map);
+}
+
+static ssize_t map_seg7_store(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (size != sizeof(txx9_seg7map))
+ return -EINVAL;
+ memcpy(&txx9_seg7map, buf, size);
+ return size;
+}
+
+static SYSDEV_CLASS_ATTR(map_seg7, 0600, map_seg7_show, map_seg7_store);
+
+static struct sysdev_class tx_7segled_sysdev_class = {
+ .name = "7segled",
+};
+
+static int __init tx_7segled_init_sysfs(void)
+{
+ int error, i;
+ if (!tx_7segled_num)
+ return -ENODEV;
+ error = sysdev_class_register(&tx_7segled_sysdev_class);
+ if (error)
+ return error;
+ error = sysdev_class_create_file(&tx_7segled_sysdev_class,
+ &attr_map_seg7);
+ if (error)
+ return error;
+ for (i = 0; i < tx_7segled_num; i++) {
+ struct sys_device *dev;
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ error = -ENODEV;
+ break;
+ }
+ dev->id = i;
+ dev->cls = &tx_7segled_sysdev_class;
+ error = sysdev_register(dev);
+ if (!error) {
+ sysdev_create_file(dev, &attr_ascii);
+ sysdev_create_file(dev, &attr_raw);
+ }
+ }
+ return error;
+}
+
+device_initcall(tx_7segled_init_sysfs);
diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile
new file mode 100644
index 00000000..1863c167
--- /dev/null
+++ b/arch/mips/txx9/generic/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for common code for TXx9 based systems
+#
+
+obj-y += setup.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_SOC_TX3927) += setup_tx3927.o irq_tx3927.o
+obj-$(CONFIG_SOC_TX4927) += mem_tx4927.o setup_tx4927.o irq_tx4927.o
+obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o setup_tx4938.o irq_tx4938.o
+obj-$(CONFIG_SOC_TX4939) += setup_tx4939.o irq_tx4939.o
+obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
+obj-$(CONFIG_SPI) += spi_eeprom.o
+obj-$(CONFIG_TXX9_7SEGLED) += 7segled.o
diff --git a/arch/mips/txx9/generic/irq_tx3927.c b/arch/mips/txx9/generic/irq_tx3927.c
new file mode 100644
index 00000000..c683f593
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx3927.c
@@ -0,0 +1,25 @@
+/*
+ * Common tx3927 irq handler
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ */
+#include <linux/init.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9/tx3927.h>
+
+void __init tx3927_irq_init(void)
+{
+ int i;
+
+ txx9_irq_init(TX3927_IRC_REG);
+ /* raise priority for timers, sio */
+ for (i = 0; i < TX3927_NR_TMR; i++)
+ txx9_irq_set_pri(TX3927_IR_TMR(i), 6);
+ for (i = 0; i < TX3927_NR_SIO; i++)
+ txx9_irq_set_pri(TX3927_IR_SIO(i), 7);
+}
diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c
new file mode 100644
index 00000000..7e3ac578
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4927.c
@@ -0,0 +1,49 @@
+/*
+ * Common tx4927 irq handler
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/txx9/tx4927.h>
+
+void __init tx4927_irq_init(void)
+{
+ int i;
+
+ mips_cpu_irq_init();
+ txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT,
+ handle_simple_irq);
+ /* raise priority for errors, timers, SIO */
+ txx9_irq_set_pri(TX4927_IR_ECCERR, 7);
+ txx9_irq_set_pri(TX4927_IR_WTOERR, 7);
+ txx9_irq_set_pri(TX4927_IR_PCIERR, 7);
+ txx9_irq_set_pri(TX4927_IR_PCIPME, 7);
+ for (i = 0; i < TX4927_NUM_IR_TMR; i++)
+ txx9_irq_set_pri(TX4927_IR_TMR(i), 6);
+ for (i = 0; i < TX4927_NUM_IR_SIO; i++)
+ txx9_irq_set_pri(TX4927_IR_SIO(i), 5);
+}
diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c
new file mode 100644
index 00000000..aace8565
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4938.c
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/mips/tx4938/common/irq.c
+ *
+ * Common tx4938 irq handler
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/txx9/tx4938.h>
+
+void __init tx4938_irq_init(void)
+{
+ int i;
+
+ mips_cpu_irq_init();
+ txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT,
+ handle_simple_irq);
+ /* raise priority for errors, timers, SIO */
+ txx9_irq_set_pri(TX4938_IR_ECCERR, 7);
+ txx9_irq_set_pri(TX4938_IR_WTOERR, 7);
+ txx9_irq_set_pri(TX4938_IR_PCIERR, 7);
+ txx9_irq_set_pri(TX4938_IR_PCIPME, 7);
+ for (i = 0; i < TX4938_NUM_IR_TMR; i++)
+ txx9_irq_set_pri(TX4938_IR_TMR(i), 6);
+ for (i = 0; i < TX4938_NUM_IR_SIO; i++)
+ txx9_irq_set_pri(TX4938_IR_SIO(i), 5);
+}
diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c
new file mode 100644
index 00000000..6b067dbd
--- /dev/null
+++ b/arch/mips/txx9/generic/irq_tx4939.c
@@ -0,0 +1,216 @@
+/*
+ * TX4939 irq routines
+ * Based on linux/arch/mips/kernel/irq_txx9.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * Copyright 2001, 2003-2005 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ahennessy@mvista.com
+ * source@mvista.com
+ * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+/*
+ * TX4939 defines 64 IRQs.
+ * Similer to irq_txx9.c but different register layouts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+#include <asm/irq_cpu.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9/tx4939.h>
+
+/* IRCER : Int. Control Enable */
+#define TXx9_IRCER_ICE 0x00000001
+
+/* IRCR : Int. Control */
+#define TXx9_IRCR_LOW 0x00000000
+#define TXx9_IRCR_HIGH 0x00000001
+#define TXx9_IRCR_DOWN 0x00000002
+#define TXx9_IRCR_UP 0x00000003
+#define TXx9_IRCR_EDGE(cr) ((cr) & 0x00000002)
+
+/* IRSCR : Int. Status Control */
+#define TXx9_IRSCR_EIClrE 0x00000100
+#define TXx9_IRSCR_EIClr_MASK 0x0000000f
+
+/* IRCSR : Int. Current Status */
+#define TXx9_IRCSR_IF 0x00010000
+
+#define irc_dlevel 0
+#define irc_elevel 1
+
+static struct {
+ unsigned char level;
+ unsigned char mode;
+} tx4939irq[TX4939_NUM_IR] __read_mostly;
+
+static void tx4939_irq_unmask(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
+ u32 __iomem *lvlp;
+ int ofs;
+ if (irq_nr < 32) {
+ irq_nr--;
+ lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r;
+ } else {
+ irq_nr -= 32;
+ lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r;
+ }
+ ofs = (irq_nr & 16) + (irq_nr & 1) * 8;
+ __raw_writel((__raw_readl(lvlp) & ~(0xff << ofs))
+ | (tx4939irq[irq_nr].level << ofs),
+ lvlp);
+}
+
+static inline void tx4939_irq_mask(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
+ u32 __iomem *lvlp;
+ int ofs;
+ if (irq_nr < 32) {
+ irq_nr--;
+ lvlp = &tx4939_ircptr->lvl[(irq_nr % 16) / 2].r;
+ } else {
+ irq_nr -= 32;
+ lvlp = &tx4939_ircptr->lvl[8 + (irq_nr % 16) / 2].r;
+ }
+ ofs = (irq_nr & 16) + (irq_nr & 1) * 8;
+ __raw_writel((__raw_readl(lvlp) & ~(0xff << ofs))
+ | (irc_dlevel << ofs),
+ lvlp);
+ mmiowb();
+}
+
+static void tx4939_irq_mask_ack(struct irq_data *d)
+{
+ unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
+
+ tx4939_irq_mask(d);
+ if (TXx9_IRCR_EDGE(tx4939irq[irq_nr].mode)) {
+ irq_nr--;
+ /* clear edge detection */
+ __raw_writel((TXx9_IRSCR_EIClrE | (irq_nr & 0xf))
+ << (irq_nr & 0x10),
+ &tx4939_ircptr->edc.r);
+ }
+}
+
+static int tx4939_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ unsigned int irq_nr = d->irq - TXX9_IRQ_BASE;
+ u32 cr;
+ u32 __iomem *crp;
+ int ofs;
+ int mode;
+
+ if (flow_type & IRQF_TRIGGER_PROBE)
+ return 0;
+ switch (flow_type & IRQF_TRIGGER_MASK) {
+ case IRQF_TRIGGER_RISING:
+ mode = TXx9_IRCR_UP;
+ break;
+ case IRQF_TRIGGER_FALLING:
+ mode = TXx9_IRCR_DOWN;
+ break;
+ case IRQF_TRIGGER_HIGH:
+ mode = TXx9_IRCR_HIGH;
+ break;
+ case IRQF_TRIGGER_LOW:
+ mode = TXx9_IRCR_LOW;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (irq_nr < 32) {
+ irq_nr--;
+ crp = &tx4939_ircptr->dm[(irq_nr & 8) >> 3].r;
+ } else {
+ irq_nr -= 32;
+ crp = &tx4939_ircptr->dm2[((irq_nr & 8) >> 3)].r;
+ }
+ ofs = (((irq_nr & 16) >> 1) | (irq_nr & (8 - 1))) * 2;
+ cr = __raw_readl(crp);
+ cr &= ~(0x3 << ofs);
+ cr |= (mode & 0x3) << ofs;
+ __raw_writel(cr, crp);
+ tx4939irq[irq_nr].mode = mode;
+ return 0;
+}
+
+static struct irq_chip tx4939_irq_chip = {
+ .name = "TX4939",
+ .irq_ack = tx4939_irq_mask_ack,
+ .irq_mask = tx4939_irq_mask,
+ .irq_mask_ack = tx4939_irq_mask_ack,
+ .irq_unmask = tx4939_irq_unmask,
+ .irq_set_type = tx4939_irq_set_type,
+};
+
+static int tx4939_irq_set_pri(int irc_irq, int new_pri)
+{
+ int old_pri;
+
+ if ((unsigned int)irc_irq >= TX4939_NUM_IR)
+ return 0;
+ old_pri = tx4939irq[irc_irq].level;
+ tx4939irq[irc_irq].level = new_pri;
+ return old_pri;
+}
+
+void __init tx4939_irq_init(void)
+{
+ int i;
+
+ mips_cpu_irq_init();
+ /* disable interrupt control */
+ __raw_writel(0, &tx4939_ircptr->den.r);
+ __raw_writel(0, &tx4939_ircptr->maskint.r);
+ __raw_writel(0, &tx4939_ircptr->maskext.r);
+ /* irq_base + 0 is not used */
+ for (i = 1; i < TX4939_NUM_IR; i++) {
+ tx4939irq[i].level = 4; /* middle level */
+ tx4939irq[i].mode = TXx9_IRCR_LOW;
+ irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &tx4939_irq_chip,
+ handle_level_irq);
+ }
+
+ /* mask all IRC interrupts */
+ __raw_writel(0, &tx4939_ircptr->msk.r);
+ for (i = 0; i < 16; i++)
+ __raw_writel(0, &tx4939_ircptr->lvl[i].r);
+ /* setup IRC interrupt mode (Low Active) */
+ for (i = 0; i < 2; i++)
+ __raw_writel(0, &tx4939_ircptr->dm[i].r);
+ for (i = 0; i < 2; i++)
+ __raw_writel(0, &tx4939_ircptr->dm2[i].r);
+ /* enable interrupt control */
+ __raw_writel(TXx9_IRCER_ICE, &tx4939_ircptr->den.r);
+ __raw_writel(irc_elevel, &tx4939_ircptr->msk.r);
+
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT,
+ handle_simple_irq);
+
+ /* raise priority for errors, timers, sio */
+ tx4939_irq_set_pri(TX4939_IR_WTOERR, 7);
+ tx4939_irq_set_pri(TX4939_IR_PCIERR, 7);
+ tx4939_irq_set_pri(TX4939_IR_PCIPME, 7);
+ for (i = 0; i < TX4939_NUM_IR_TMR; i++)
+ tx4939_irq_set_pri(TX4939_IR_TMR(i), 6);
+ for (i = 0; i < TX4939_NUM_IR_SIO; i++)
+ tx4939_irq_set_pri(TX4939_IR_SIO(i), 5);
+}
+
+int tx4939_irq(void)
+{
+ u32 csr = __raw_readl(&tx4939_ircptr->cs.r);
+
+ if (likely(!(csr & TXx9_IRCSR_IF)))
+ return TXX9_IRQ_BASE + (csr & (TX4939_NUM_IR - 1));
+ return -1;
+}
diff --git a/arch/mips/txx9/generic/mem_tx4927.c b/arch/mips/txx9/generic/mem_tx4927.c
new file mode 100644
index 00000000..70f9626f
--- /dev/null
+++ b/arch/mips/txx9/generic/mem_tx4927.c
@@ -0,0 +1,75 @@
+/*
+ * common tx4927 memory interface
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <asm/txx9/tx4927.h>
+
+static unsigned int __init tx4927_process_sdccr(u64 __iomem *addr)
+{
+ u64 val;
+ unsigned int sdccr_ce;
+ unsigned int sdccr_bs;
+ unsigned int sdccr_rs;
+ unsigned int sdccr_cs;
+ unsigned int sdccr_mw;
+ unsigned int bs = 0;
+ unsigned int rs = 0;
+ unsigned int cs = 0;
+ unsigned int mw = 0;
+
+ val = __raw_readq(addr);
+
+ /* MVMCP -- need #defs for these bits masks */
+ sdccr_ce = ((val & (1 << 10)) >> 10);
+ sdccr_bs = ((val & (1 << 8)) >> 8);
+ sdccr_rs = ((val & (3 << 5)) >> 5);
+ sdccr_cs = ((val & (7 << 2)) >> 2);
+ sdccr_mw = ((val & (1 << 0)) >> 0);
+
+ if (sdccr_ce) {
+ bs = 2 << sdccr_bs;
+ rs = 2048 << sdccr_rs;
+ cs = 256 << sdccr_cs;
+ mw = 8 >> sdccr_mw;
+ }
+
+ return rs * cs * mw * bs;
+}
+
+unsigned int __init tx4927_get_mem_size(void)
+{
+ unsigned int total = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tx4927_sdramcptr->cr); i++)
+ total += tx4927_process_sdccr(&tx4927_sdramcptr->cr[i]);
+ return total;
+}
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
new file mode 100644
index 00000000..85a87de1
--- /dev/null
+++ b/arch/mips/txx9/generic/pci.c
@@ -0,0 +1,435 @@
+/*
+ * linux/arch/mips/txx9/pci.c
+ *
+ * Based on linux/arch/mips/txx9/rbtx4927/setup.c,
+ * linux/arch/mips/txx9/rbtx4938/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * Copyright 2001-2005 MontaVista Software Inc.
+ * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org)
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/io.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/pci.h>
+#ifdef CONFIG_TOSHIBA_FPCIB0
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <asm/i8259.h>
+#include <asm/txx9/smsc_fdc37m81x.h>
+#endif
+
+static int __init
+early_read_config_word(struct pci_controller *hose,
+ int top_bus, int bus, int devfn, int offset, u16 *value)
+{
+ struct pci_dev fake_dev;
+ struct pci_bus fake_bus;
+
+ fake_dev.bus = &fake_bus;
+ fake_dev.sysdata = hose;
+ fake_dev.devfn = devfn;
+ fake_bus.number = bus;
+ fake_bus.sysdata = hose;
+ fake_bus.ops = hose->pci_ops;
+
+ if (bus != top_bus)
+ /* Fake a parent bus structure. */
+ fake_bus.parent = &fake_bus;
+ else
+ fake_bus.parent = NULL;
+
+ return pci_read_config_word(&fake_dev, offset, value);
+}
+
+int __init txx9_pci66_check(struct pci_controller *hose, int top_bus,
+ int current_bus)
+{
+ u32 pci_devfn;
+ unsigned short vid;
+ int cap66 = -1;
+ u16 stat;
+
+ /* It seems SLC90E66 needs some time after PCI reset... */
+ mdelay(80);
+
+ printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n");
+
+ for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
+ if (PCI_FUNC(pci_devfn))
+ continue;
+ if (early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_VENDOR_ID, &vid) !=
+ PCIBIOS_SUCCESSFUL)
+ continue;
+ if (vid == 0xffff)
+ continue;
+
+ /* check 66MHz capability */
+ if (cap66 < 0)
+ cap66 = 1;
+ if (cap66) {
+ early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_STATUS, &stat);
+ if (!(stat & PCI_STATUS_66MHZ)) {
+ printk(KERN_DEBUG
+ "PCI: %02x:%02x not 66MHz capable.\n",
+ current_bus, pci_devfn);
+ cap66 = 0;
+ break;
+ }
+ }
+ }
+ return cap66 > 0;
+}
+
+static struct resource primary_pci_mem_res[2] = {
+ { .name = "PCI MEM" },
+ { .name = "PCI MMIO" },
+};
+static struct resource primary_pci_io_res = { .name = "PCI IO" };
+struct pci_controller txx9_primary_pcic = {
+ .mem_resource = &primary_pci_mem_res[0],
+ .io_resource = &primary_pci_io_res,
+};
+
+#ifdef CONFIG_64BIT
+int txx9_pci_mem_high __initdata = 1;
+#else
+int txx9_pci_mem_high __initdata;
+#endif
+
+/*
+ * allocate pci_controller and resources.
+ * mem_base, io_base: physical address. 0 for auto assignment.
+ * mem_size and io_size means max size on auto assignment.
+ * pcic must be &txx9_primary_pcic or NULL.
+ */
+struct pci_controller *__init
+txx9_alloc_pci_controller(struct pci_controller *pcic,
+ unsigned long mem_base, unsigned long mem_size,
+ unsigned long io_base, unsigned long io_size)
+{
+ struct pcic {
+ struct pci_controller c;
+ struct resource r_mem[2];
+ struct resource r_io;
+ } *new = NULL;
+ int min_size = 0x10000;
+
+ if (!pcic) {
+ new = kzalloc(sizeof(*new), GFP_KERNEL);
+ if (!new)
+ return NULL;
+ new->r_mem[0].name = "PCI mem";
+ new->r_mem[1].name = "PCI mmio";
+ new->r_io.name = "PCI io";
+ new->c.mem_resource = new->r_mem;
+ new->c.io_resource = &new->r_io;
+ pcic = &new->c;
+ } else
+ BUG_ON(pcic != &txx9_primary_pcic);
+ pcic->io_resource->flags = IORESOURCE_IO;
+
+ /*
+ * for auto assignment, first search a (big) region for PCI
+ * MEM, then search a region for PCI IO.
+ */
+ if (mem_base) {
+ pcic->mem_resource[0].start = mem_base;
+ pcic->mem_resource[0].end = mem_base + mem_size - 1;
+ if (request_resource(&iomem_resource, &pcic->mem_resource[0]))
+ goto free_and_exit;
+ } else {
+ unsigned long min = 0, max = 0x20000000; /* low 512MB */
+ if (!mem_size) {
+ /* default size for auto assignment */
+ if (txx9_pci_mem_high)
+ mem_size = 0x20000000; /* mem:512M(max) */
+ else
+ mem_size = 0x08000000; /* mem:128M(max) */
+ }
+ if (txx9_pci_mem_high) {
+ min = 0x20000000;
+ max = 0xe0000000;
+ }
+ /* search free region for PCI MEM */
+ for (; mem_size >= min_size; mem_size /= 2) {
+ if (allocate_resource(&iomem_resource,
+ &pcic->mem_resource[0],
+ mem_size, min, max,
+ mem_size, NULL, NULL) == 0)
+ break;
+ }
+ if (mem_size < min_size)
+ goto free_and_exit;
+ }
+
+ pcic->mem_resource[1].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ if (io_base) {
+ pcic->mem_resource[1].start = io_base;
+ pcic->mem_resource[1].end = io_base + io_size - 1;
+ if (request_resource(&iomem_resource, &pcic->mem_resource[1]))
+ goto release_and_exit;
+ } else {
+ if (!io_size)
+ /* default size for auto assignment */
+ io_size = 0x01000000; /* io:16M(max) */
+ /* search free region for PCI IO in low 512MB */
+ for (; io_size >= min_size; io_size /= 2) {
+ if (allocate_resource(&iomem_resource,
+ &pcic->mem_resource[1],
+ io_size, 0, 0x20000000,
+ io_size, NULL, NULL) == 0)
+ break;
+ }
+ if (io_size < min_size)
+ goto release_and_exit;
+ io_base = pcic->mem_resource[1].start;
+ }
+
+ pcic->mem_resource[0].flags = IORESOURCE_MEM;
+ if (pcic == &txx9_primary_pcic &&
+ mips_io_port_base == (unsigned long)-1) {
+ /* map ioport 0 to PCI I/O space address 0 */
+ set_io_port_base(IO_BASE + pcic->mem_resource[1].start);
+ pcic->io_resource->start = 0;
+ pcic->io_offset = 0; /* busaddr == ioaddr */
+ pcic->io_map_base = IO_BASE + pcic->mem_resource[1].start;
+ } else {
+ /* physaddr to ioaddr */
+ pcic->io_resource->start =
+ io_base - (mips_io_port_base - IO_BASE);
+ pcic->io_offset = io_base - (mips_io_port_base - IO_BASE);
+ pcic->io_map_base = mips_io_port_base;
+ }
+ pcic->io_resource->end = pcic->io_resource->start + io_size - 1;
+
+ pcic->mem_offset = 0; /* busaddr == physaddr */
+
+ printk(KERN_INFO "PCI: IO %pR MEM %pR\n",
+ &pcic->mem_resource[1], &pcic->mem_resource[0]);
+
+ /* register_pci_controller() will request MEM resource */
+ release_resource(&pcic->mem_resource[0]);
+ return pcic;
+ release_and_exit:
+ release_resource(&pcic->mem_resource[0]);
+ free_and_exit:
+ kfree(new);
+ printk(KERN_ERR "PCI: Failed to allocate resources.\n");
+ return NULL;
+}
+
+static int __init
+txx9_arch_pci_init(void)
+{
+ PCIBIOS_MIN_IO = 0x8000; /* reseve legacy I/O space */
+ return 0;
+}
+arch_initcall(txx9_arch_pci_init);
+
+/* IRQ/IDSEL mapping */
+int txx9_pci_option =
+#ifdef CONFIG_PICMG_PCI_BACKPLANE_DEFAULT
+ TXX9_PCI_OPT_PICMG |
+#endif
+ TXX9_PCI_OPT_CLK_AUTO;
+
+enum txx9_pci_err_action txx9_pci_err_action = TXX9_PCI_ERR_REPORT;
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+static irqreturn_t i8259_interrupt(int irq, void *dev_id)
+{
+ int isairq;
+
+ isairq = i8259_irq();
+ if (unlikely(isairq <= I8259A_IRQ_BASE))
+ return IRQ_NONE;
+ generic_handle_irq(isairq);
+ return IRQ_HANDLED;
+}
+
+static int __init
+txx9_i8259_irq_setup(int irq)
+{
+ int err;
+
+ init_i8259_irqs();
+ err = request_irq(irq, &i8259_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ "cascade(i8259)", (void *)(long)irq);
+ if (!err)
+ printk(KERN_INFO "PCI-ISA bridge PIC (irq %d)\n", irq);
+ return err;
+}
+
+static void __init quirk_slc90e66_bridge(struct pci_dev *dev)
+{
+ int irq; /* PCI/ISA Bridge interrupt */
+ u8 reg_64;
+ u32 reg_b0;
+ u8 reg_e1;
+ irq = pcibios_map_irq(dev, PCI_SLOT(dev->devfn), 1); /* INTA */
+ if (!irq)
+ return;
+ txx9_i8259_irq_setup(irq);
+ pci_read_config_byte(dev, 0x64, &reg_64);
+ pci_read_config_dword(dev, 0xb0, &reg_b0);
+ pci_read_config_byte(dev, 0xe1, &reg_e1);
+ /* serial irq control */
+ reg_64 = 0xd0;
+ /* serial irq pin */
+ reg_b0 |= 0x00010000;
+ /* ide irq on isa14 */
+ reg_e1 &= 0xf0;
+ reg_e1 |= 0x0d;
+ pci_write_config_byte(dev, 0x64, reg_64);
+ pci_write_config_dword(dev, 0xb0, reg_b0);
+ pci_write_config_byte(dev, 0xe1, reg_e1);
+
+ smsc_fdc37m81x_init(0x3f0);
+ smsc_fdc37m81x_config_beg();
+ smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM,
+ SMSC_FDC37M81X_KBD);
+ smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1);
+ smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12);
+ smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE,
+ 1);
+ smsc_fdc37m81x_config_end();
+}
+
+static void quirk_slc90e66_ide(struct pci_dev *dev)
+{
+ unsigned char dat;
+ int regs[2] = {0x41, 0x43};
+ int i;
+
+ /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14);
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &dat);
+ printk(KERN_INFO "PCI: %s: IRQ %02x", pci_name(dev), dat);
+ /* enable SMSC SLC90E66 IDE */
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ pci_read_config_byte(dev, regs[i], &dat);
+ pci_write_config_byte(dev, regs[i], dat | 0x80);
+ pci_read_config_byte(dev, regs[i], &dat);
+ printk(KERN_CONT " IDETIM%d %02x", i, dat);
+ }
+ pci_read_config_byte(dev, 0x5c, &dat);
+ /*
+ * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
+ *
+ * This line of code is intended to provide the user with a work
+ * around solution to the anomalies cited in SMSC's anomaly sheet
+ * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"".
+ *
+ * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
+ */
+ dat |= 0x01;
+ pci_write_config_byte(dev, regs[i], dat);
+ pci_read_config_byte(dev, 0x5c, &dat);
+ printk(KERN_CONT " REG5C %02x", dat);
+ printk(KERN_CONT "\n");
+}
+#endif /* CONFIG_TOSHIBA_FPCIB0 */
+
+static void tc35815_fixup(struct pci_dev *dev)
+{
+ /* This device may have PM registers but not they are not suported. */
+ if (dev->pm_cap) {
+ dev_info(&dev->dev, "PM disabled\n");
+ dev->pm_cap = 0;
+ }
+}
+
+static void final_fixup(struct pci_dev *dev)
+{
+ unsigned char bist;
+
+ /* Do build-in self test */
+ if (pci_read_config_byte(dev, PCI_BIST, &bist) == PCIBIOS_SUCCESSFUL &&
+ (bist & PCI_BIST_CAPABLE)) {
+ unsigned long timeout;
+ pci_set_power_state(dev, PCI_D0);
+ printk(KERN_INFO "PCI: %s BIST...", pci_name(dev));
+ pci_write_config_byte(dev, PCI_BIST, PCI_BIST_START);
+ timeout = jiffies + HZ * 2; /* timeout after 2 sec */
+ do {
+ pci_read_config_byte(dev, PCI_BIST, &bist);
+ if (time_after(jiffies, timeout))
+ break;
+ } while (bist & PCI_BIST_START);
+ if (bist & (PCI_BIST_CODE_MASK | PCI_BIST_START))
+ printk(KERN_CONT "failed. (0x%x)\n", bist);
+ else
+ printk(KERN_CONT "OK.\n");
+ }
+}
+
+#ifdef CONFIG_TOSHIBA_FPCIB0
+#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0,
+ quirk_slc90e66_bridge);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
+ quirk_slc90e66_ide);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
+ quirk_slc90e66_ide);
+#endif
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
+ PCI_DEVICE_ID_TOSHIBA_TC35815_NWU, tc35815_fixup);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
+ PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939, tc35815_fixup);
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
+DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return txx9_board_vec->pci_map_irq(dev, slot, pin);
+}
+
+char * (*txx9_board_pcibios_setup)(char *str) __devinitdata;
+
+char *__devinit txx9_pcibios_setup(char *str)
+{
+ if (txx9_board_pcibios_setup && !txx9_board_pcibios_setup(str))
+ return NULL;
+ if (!strcmp(str, "picmg")) {
+ /* PICMG compliant backplane (TOSHIBA JMB-PICMG-ATX
+ (5V or 3.3V), JMB-PICMG-L2 (5V only), etc.) */
+ txx9_pci_option |= TXX9_PCI_OPT_PICMG;
+ return NULL;
+ } else if (!strcmp(str, "nopicmg")) {
+ /* non-PICMG compliant backplane (TOSHIBA
+ RBHBK4100,RBHBK4200, Interface PCM-PCM05, etc.) */
+ txx9_pci_option &= ~TXX9_PCI_OPT_PICMG;
+ return NULL;
+ } else if (!strncmp(str, "clk=", 4)) {
+ char *val = str + 4;
+ txx9_pci_option &= ~TXX9_PCI_OPT_CLK_MASK;
+ if (strcmp(val, "33") == 0)
+ txx9_pci_option |= TXX9_PCI_OPT_CLK_33;
+ else if (strcmp(val, "66") == 0)
+ txx9_pci_option |= TXX9_PCI_OPT_CLK_66;
+ else /* "auto" */
+ txx9_pci_option |= TXX9_PCI_OPT_CLK_AUTO;
+ return NULL;
+ } else if (!strncmp(str, "err=", 4)) {
+ if (!strcmp(str + 4, "panic"))
+ txx9_pci_err_action = TXX9_PCI_ERR_PANIC;
+ else if (!strcmp(str + 4, "ignore"))
+ txx9_pci_err_action = TXX9_PCI_ERR_IGNORE;
+ return NULL;
+ }
+ return str;
+}
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
new file mode 100644
index 00000000..ec38e00b
--- /dev/null
+++ b/arch/mips/txx9/generic/setup.c
@@ -0,0 +1,982 @@
+/*
+ * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * 2003-2005 (c) MontaVista Software, Inc.
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/mtd/physmap.h>
+#include <linux/leds.h>
+#include <linux/sysdev.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/reboot.h>
+#include <asm/r4kcache.h>
+#include <asm/sections.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9tmr.h>
+#include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
+#ifdef CONFIG_CPU_TX49XX
+#include <asm/txx9/tx4938.h>
+#endif
+
+/* EBUSC settings of TX4927, etc. */
+struct resource txx9_ce_res[8];
+static char txx9_ce_res_name[8][4]; /* "CEn" */
+
+/* pcode, internal register */
+unsigned int txx9_pcode;
+char txx9_pcode_str[8];
+static struct resource txx9_reg_res = {
+ .name = txx9_pcode_str,
+ .flags = IORESOURCE_MEM,
+};
+void __init
+txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(txx9_ce_res); i++) {
+ sprintf(txx9_ce_res_name[i], "CE%d", i);
+ txx9_ce_res[i].flags = IORESOURCE_MEM;
+ txx9_ce_res[i].name = txx9_ce_res_name[i];
+ }
+
+ txx9_pcode = pcode;
+ sprintf(txx9_pcode_str, "TX%x", pcode);
+ if (base) {
+ txx9_reg_res.start = base & 0xfffffffffULL;
+ txx9_reg_res.end = (base & 0xfffffffffULL) + (size - 1);
+ request_resource(&iomem_resource, &txx9_reg_res);
+ }
+}
+
+/* clocks */
+unsigned int txx9_master_clock;
+unsigned int txx9_cpu_clock;
+unsigned int txx9_gbus_clock;
+
+#ifdef CONFIG_CPU_TX39XX
+/* don't enable by default - see errata */
+int txx9_ccfg_toeon __initdata;
+#else
+int txx9_ccfg_toeon __initdata = 1;
+#endif
+
+/* Minimum CLK support */
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ if (!strcmp(id, "spi-baseclk"))
+ return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 2);
+ if (!strcmp(id, "imbus_clk"))
+ return (struct clk *)((unsigned long)txx9_gbus_clock / 2);
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return (unsigned long)clk;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+/* GPIO support */
+
+#ifdef CONFIG_GENERIC_GPIO
+int gpio_to_irq(unsigned gpio)
+{
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned irq)
+{
+ return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
+#endif
+
+#define BOARD_VEC(board) extern struct txx9_board_vec board;
+#include <asm/txx9/boards.h>
+#undef BOARD_VEC
+
+struct txx9_board_vec *txx9_board_vec __initdata;
+static char txx9_system_type[32];
+
+static struct txx9_board_vec *board_vecs[] __initdata = {
+#define BOARD_VEC(board) &board,
+#include <asm/txx9/boards.h>
+#undef BOARD_VEC
+};
+
+static struct txx9_board_vec *__init find_board_byname(const char *name)
+{
+ int i;
+
+ /* search board_vecs table */
+ for (i = 0; i < ARRAY_SIZE(board_vecs); i++) {
+ if (strstr(board_vecs[i]->system, name))
+ return board_vecs[i];
+ }
+ return NULL;
+}
+
+static void __init prom_init_cmdline(void)
+{
+ int argc;
+ int *argv32;
+ int i; /* Always ignore the "-c" at argv[0] */
+
+ if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) {
+ /*
+ * argc is not a valid number, or argv32 is not a valid
+ * pointer
+ */
+ argc = 0;
+ argv32 = NULL;
+ } else {
+ argc = (int)fw_arg0;
+ argv32 = (int *)fw_arg1;
+ }
+
+ arcs_cmdline[0] = '\0';
+
+ for (i = 1; i < argc; i++) {
+ char *str = (char *)(long)argv32[i];
+ if (i != 1)
+ strcat(arcs_cmdline, " ");
+ if (strchr(str, ' ')) {
+ strcat(arcs_cmdline, "\"");
+ strcat(arcs_cmdline, str);
+ strcat(arcs_cmdline, "\"");
+ } else
+ strcat(arcs_cmdline, str);
+ }
+}
+
+static int txx9_ic_disable __initdata;
+static int txx9_dc_disable __initdata;
+
+#if defined(CONFIG_CPU_TX49XX)
+/* flush all cache on very early stage (before 4k_cache_init) */
+static void __init early_flush_dcache(void)
+{
+ unsigned int conf = read_c0_config();
+ unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6));
+ unsigned int linesz = 32;
+ unsigned long addr, end;
+
+ end = INDEX_BASE + dc_size / 4;
+ /* 4way, waybit=0 */
+ for (addr = INDEX_BASE; addr < end; addr += linesz) {
+ cache_op(Index_Writeback_Inv_D, addr | 0);
+ cache_op(Index_Writeback_Inv_D, addr | 1);
+ cache_op(Index_Writeback_Inv_D, addr | 2);
+ cache_op(Index_Writeback_Inv_D, addr | 3);
+ }
+}
+
+static void __init txx9_cache_fixup(void)
+{
+ unsigned int conf;
+
+ conf = read_c0_config();
+ /* flush and disable */
+ if (txx9_ic_disable) {
+ conf |= TX49_CONF_IC;
+ write_c0_config(conf);
+ }
+ if (txx9_dc_disable) {
+ early_flush_dcache();
+ conf |= TX49_CONF_DC;
+ write_c0_config(conf);
+ }
+
+ /* enable cache */
+ conf = read_c0_config();
+ if (!txx9_ic_disable)
+ conf &= ~TX49_CONF_IC;
+ if (!txx9_dc_disable)
+ conf &= ~TX49_CONF_DC;
+ write_c0_config(conf);
+
+ if (conf & TX49_CONF_IC)
+ pr_info("TX49XX I-Cache disabled.\n");
+ if (conf & TX49_CONF_DC)
+ pr_info("TX49XX D-Cache disabled.\n");
+}
+#elif defined(CONFIG_CPU_TX39XX)
+/* flush all cache on very early stage (before tx39_cache_init) */
+static void __init early_flush_dcache(void)
+{
+ unsigned int conf = read_c0_config();
+ unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >>
+ TX39_CONF_DCS_SHIFT));
+ unsigned int linesz = 16;
+ unsigned long addr, end;
+
+ end = INDEX_BASE + dc_size / 2;
+ /* 2way, waybit=0 */
+ for (addr = INDEX_BASE; addr < end; addr += linesz) {
+ cache_op(Index_Writeback_Inv_D, addr | 0);
+ cache_op(Index_Writeback_Inv_D, addr | 1);
+ }
+}
+
+static void __init txx9_cache_fixup(void)
+{
+ unsigned int conf;
+
+ conf = read_c0_config();
+ /* flush and disable */
+ if (txx9_ic_disable) {
+ conf &= ~TX39_CONF_ICE;
+ write_c0_config(conf);
+ }
+ if (txx9_dc_disable) {
+ early_flush_dcache();
+ conf &= ~TX39_CONF_DCE;
+ write_c0_config(conf);
+ }
+
+ /* enable cache */
+ conf = read_c0_config();
+ if (!txx9_ic_disable)
+ conf |= TX39_CONF_ICE;
+ if (!txx9_dc_disable)
+ conf |= TX39_CONF_DCE;
+ write_c0_config(conf);
+
+ if (!(conf & TX39_CONF_ICE))
+ pr_info("TX39XX I-Cache disabled.\n");
+ if (!(conf & TX39_CONF_DCE))
+ pr_info("TX39XX D-Cache disabled.\n");
+}
+#else
+static inline void txx9_cache_fixup(void)
+{
+}
+#endif
+
+static void __init preprocess_cmdline(void)
+{
+ static char cmdline[COMMAND_LINE_SIZE] __initdata;
+ char *s;
+
+ strcpy(cmdline, arcs_cmdline);
+ s = cmdline;
+ arcs_cmdline[0] = '\0';
+ while (s && *s) {
+ char *str = strsep(&s, " ");
+ if (strncmp(str, "board=", 6) == 0) {
+ txx9_board_vec = find_board_byname(str + 6);
+ continue;
+ } else if (strncmp(str, "masterclk=", 10) == 0) {
+ unsigned long val;
+ if (strict_strtoul(str + 10, 10, &val) == 0)
+ txx9_master_clock = val;
+ continue;
+ } else if (strcmp(str, "icdisable") == 0) {
+ txx9_ic_disable = 1;
+ continue;
+ } else if (strcmp(str, "dcdisable") == 0) {
+ txx9_dc_disable = 1;
+ continue;
+ } else if (strcmp(str, "toeoff") == 0) {
+ txx9_ccfg_toeon = 0;
+ continue;
+ } else if (strcmp(str, "toeon") == 0) {
+ txx9_ccfg_toeon = 1;
+ continue;
+ }
+ if (arcs_cmdline[0])
+ strcat(arcs_cmdline, " ");
+ strcat(arcs_cmdline, str);
+ }
+
+ txx9_cache_fixup();
+}
+
+static void __init select_board(void)
+{
+ const char *envstr;
+
+ /* first, determine by "board=" argument in preprocess_cmdline() */
+ if (txx9_board_vec)
+ return;
+ /* next, determine by "board" envvar */
+ envstr = prom_getenv("board");
+ if (envstr) {
+ txx9_board_vec = find_board_byname(envstr);
+ if (txx9_board_vec)
+ return;
+ }
+
+ /* select "default" board */
+#ifdef CONFIG_CPU_TX39XX
+ txx9_board_vec = &jmr3927_vec;
+#endif
+#ifdef CONFIG_CPU_TX49XX
+ switch (TX4938_REV_PCODE()) {
+#ifdef CONFIG_TOSHIBA_RBTX4927
+ case 0x4927:
+ txx9_board_vec = &rbtx4927_vec;
+ break;
+ case 0x4937:
+ txx9_board_vec = &rbtx4937_vec;
+ break;
+#endif
+#ifdef CONFIG_TOSHIBA_RBTX4938
+ case 0x4938:
+ txx9_board_vec = &rbtx4938_vec;
+ break;
+#endif
+#ifdef CONFIG_TOSHIBA_RBTX4939
+ case 0x4939:
+ txx9_board_vec = &rbtx4939_vec;
+ break;
+#endif
+ }
+#endif
+}
+
+void __init prom_init(void)
+{
+ prom_init_cmdline();
+ preprocess_cmdline();
+ select_board();
+
+ strcpy(txx9_system_type, txx9_board_vec->system);
+
+ txx9_board_vec->prom_init();
+}
+
+void __init prom_free_prom_memory(void)
+{
+ unsigned long saddr = PAGE_SIZE;
+ unsigned long eaddr = __pa_symbol(&_text);
+
+ if (saddr < eaddr)
+ free_init_pages("prom memory", saddr, eaddr);
+}
+
+const char *get_system_type(void)
+{
+ return txx9_system_type;
+}
+
+const char *__init prom_getenv(const char *name)
+{
+ const s32 *str;
+
+ if (fw_arg2 < CKSEG0)
+ return NULL;
+
+ str = (const s32 *)fw_arg2;
+ /* YAMON style ("name", "value" pairs) */
+ while (str[0] && str[1]) {
+ if (!strcmp((const char *)(unsigned long)str[0], name))
+ return (const char *)(unsigned long)str[1];
+ str += 2;
+ }
+ return NULL;
+}
+
+static void __noreturn txx9_machine_halt(void)
+{
+ local_irq_disable();
+ clear_c0_status(ST0_IM);
+ while (1) {
+ if (cpu_wait) {
+ (*cpu_wait)();
+ if (cpu_has_counter) {
+ /*
+ * Clear counter interrupt while it
+ * breaks WAIT instruction even if
+ * masked.
+ */
+ write_c0_compare(0);
+ }
+ }
+ }
+}
+
+/* Watchdog support */
+void __init txx9_wdt_init(unsigned long base)
+{
+ struct resource res = {
+ .start = base,
+ .end = base + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ platform_device_register_simple("txx9wdt", -1, &res, 1);
+}
+
+void txx9_wdt_now(unsigned long base)
+{
+ struct txx9_tmr_reg __iomem *tmrptr =
+ ioremap(base, sizeof(struct txx9_tmr_reg));
+ /* disable watch dog timer */
+ __raw_writel(TXx9_TMWTMR_WDIS | TXx9_TMWTMR_TWC, &tmrptr->wtmr);
+ __raw_writel(0, &tmrptr->tcr);
+ /* kick watchdog */
+ __raw_writel(TXx9_TMWTMR_TWIE, &tmrptr->wtmr);
+ __raw_writel(1, &tmrptr->cpra); /* immediate */
+ __raw_writel(TXx9_TMTCR_TCE | TXx9_TMTCR_CCDE | TXx9_TMTCR_TMODE_WDOG,
+ &tmrptr->tcr);
+}
+
+/* SPI support */
+void __init txx9_spi_init(int busid, unsigned long base, int irq)
+{
+ struct resource res[] = {
+ {
+ .start = base,
+ .end = base + 0x20 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ platform_device_register_simple("spi_txx9", busid,
+ res, ARRAY_SIZE(res));
+}
+
+void __init txx9_ethaddr_init(unsigned int id, unsigned char *ethaddr)
+{
+ struct platform_device *pdev =
+ platform_device_alloc("tc35815-mac", id);
+ if (!pdev ||
+ platform_device_add_data(pdev, ethaddr, 6) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+}
+
+void __init txx9_sio_init(unsigned long baseaddr, int irq,
+ unsigned int line, unsigned int sclk, int nocts)
+{
+#ifdef CONFIG_SERIAL_TXX9
+ struct uart_port req;
+
+ memset(&req, 0, sizeof(req));
+ req.line = line;
+ req.iotype = UPIO_MEM;
+ req.membase = ioremap(baseaddr, 0x24);
+ req.mapbase = baseaddr;
+ req.irq = irq;
+ if (!nocts)
+ req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
+ if (sclk) {
+ req.flags |= UPF_MAGIC_MULTIPLIER /*USE_SCLK*/;
+ req.uartclk = sclk;
+ } else
+ req.uartclk = TXX9_IMCLK;
+ early_serial_txx9_setup(&req);
+#endif /* CONFIG_SERIAL_TXX9 */
+}
+
+#ifdef CONFIG_EARLY_PRINTK
+static void __init null_prom_putchar(char c)
+{
+}
+void (*txx9_prom_putchar)(char c) __initdata = null_prom_putchar;
+
+void __init prom_putchar(char c)
+{
+ txx9_prom_putchar(c);
+}
+
+static void __iomem *early_txx9_sio_port;
+
+static void __init early_txx9_sio_putchar(char c)
+{
+#define TXX9_SICISR 0x0c
+#define TXX9_SITFIFO 0x1c
+#define TXX9_SICISR_TXALS 0x00000002
+ while (!(__raw_readl(early_txx9_sio_port + TXX9_SICISR) &
+ TXX9_SICISR_TXALS))
+ ;
+ __raw_writel(c, early_txx9_sio_port + TXX9_SITFIFO);
+}
+
+void __init txx9_sio_putchar_init(unsigned long baseaddr)
+{
+ early_txx9_sio_port = ioremap(baseaddr, 0x24);
+ txx9_prom_putchar = early_txx9_sio_putchar;
+}
+#endif /* CONFIG_EARLY_PRINTK */
+
+/* wrappers */
+void __init plat_mem_setup(void)
+{
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0UL; /* no limit */
+ iomem_resource.start = 0;
+ iomem_resource.end = ~0UL; /* no limit */
+
+ /* fallback restart/halt routines */
+ _machine_restart = (void (*)(char *))txx9_machine_halt;
+ _machine_halt = txx9_machine_halt;
+ pm_power_off = txx9_machine_halt;
+
+#ifdef CONFIG_PCI
+ pcibios_plat_setup = txx9_pcibios_setup;
+#endif
+ txx9_board_vec->mem_setup();
+}
+
+void __init arch_init_irq(void)
+{
+ txx9_board_vec->irq_setup();
+}
+
+void __init plat_time_init(void)
+{
+#ifdef CONFIG_CPU_TX49XX
+ mips_hpt_frequency = txx9_cpu_clock / 2;
+#endif
+ txx9_board_vec->time_init();
+}
+
+static int __init _txx9_arch_init(void)
+{
+ if (txx9_board_vec->arch_init)
+ txx9_board_vec->arch_init();
+ return 0;
+}
+arch_initcall(_txx9_arch_init);
+
+static int __init _txx9_device_init(void)
+{
+ if (txx9_board_vec->device_init)
+ txx9_board_vec->device_init();
+ return 0;
+}
+device_initcall(_txx9_device_init);
+
+int (*txx9_irq_dispatch)(int pending);
+asmlinkage void plat_irq_dispatch(void)
+{
+ int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+ int irq = txx9_irq_dispatch(pending);
+
+ if (likely(irq >= 0))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+}
+
+/* see include/asm-mips/mach-tx39xx/mangle-port.h, for example. */
+#ifdef NEEDS_TXX9_SWIZZLE_ADDR_B
+static unsigned long __swizzle_addr_none(unsigned long port)
+{
+ return port;
+}
+unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none;
+EXPORT_SYMBOL(__swizzle_addr_b);
+#endif
+
+#ifdef NEEDS_TXX9_IOSWABW
+static u16 ioswabw_default(volatile u16 *a, u16 x)
+{
+ return le16_to_cpu(x);
+}
+static u16 __mem_ioswabw_default(volatile u16 *a, u16 x)
+{
+ return x;
+}
+u16 (*ioswabw)(volatile u16 *a, u16 x) = ioswabw_default;
+EXPORT_SYMBOL(ioswabw);
+u16 (*__mem_ioswabw)(volatile u16 *a, u16 x) = __mem_ioswabw_default;
+EXPORT_SYMBOL(__mem_ioswabw);
+#endif
+
+void __init txx9_physmap_flash_init(int no, unsigned long addr,
+ unsigned long size,
+ const struct physmap_flash_data *pdata)
+{
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+ struct resource res = {
+ .start = addr,
+ .end = addr + size - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ struct platform_device *pdev;
+ static struct mtd_partition parts[2];
+ struct physmap_flash_data pdata_part;
+
+ /* If this area contained boot area, make separate partition */
+ if (pdata->nr_parts == 0 && !pdata->parts &&
+ addr < 0x1fc00000 && addr + size > 0x1fc00000 &&
+ !parts[0].name) {
+ parts[0].name = "boot";
+ parts[0].offset = 0x1fc00000 - addr;
+ parts[0].size = addr + size - 0x1fc00000;
+ parts[1].name = "user";
+ parts[1].offset = 0;
+ parts[1].size = 0x1fc00000 - addr;
+ pdata_part = *pdata;
+ pdata_part.nr_parts = ARRAY_SIZE(parts);
+ pdata_part.parts = parts;
+ pdata = &pdata_part;
+ }
+
+ pdev = platform_device_alloc("physmap-flash", no);
+ if (!pdev ||
+ platform_device_add_resources(pdev, &res, 1) ||
+ platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+#endif
+}
+
+void __init txx9_ndfmc_init(unsigned long baseaddr,
+ const struct txx9ndfmc_platform_data *pdata)
+{
+#if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \
+ defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE)
+ struct resource res = {
+ .start = baseaddr,
+ .end = baseaddr + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1);
+
+ if (!pdev ||
+ platform_device_add_resources(pdev, &res, 1) ||
+ platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+#endif
+}
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static DEFINE_SPINLOCK(txx9_iocled_lock);
+
+#define TXX9_IOCLED_MAXLEDS 8
+
+struct txx9_iocled_data {
+ struct gpio_chip chip;
+ u8 cur_val;
+ void __iomem *mmioaddr;
+ struct gpio_led_platform_data pdata;
+ struct gpio_led leds[TXX9_IOCLED_MAXLEDS];
+ char names[TXX9_IOCLED_MAXLEDS][32];
+};
+
+static int txx9_iocled_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct txx9_iocled_data *data =
+ container_of(chip, struct txx9_iocled_data, chip);
+ return data->cur_val & (1 << offset);
+}
+
+static void txx9_iocled_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ struct txx9_iocled_data *data =
+ container_of(chip, struct txx9_iocled_data, chip);
+ unsigned long flags;
+ spin_lock_irqsave(&txx9_iocled_lock, flags);
+ if (value)
+ data->cur_val |= 1 << offset;
+ else
+ data->cur_val &= ~(1 << offset);
+ writeb(data->cur_val, data->mmioaddr);
+ mmiowb();
+ spin_unlock_irqrestore(&txx9_iocled_lock, flags);
+}
+
+static int txx9_iocled_dir_in(struct gpio_chip *chip, unsigned int offset)
+{
+ return 0;
+}
+
+static int txx9_iocled_dir_out(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ txx9_iocled_set(chip, offset, value);
+ return 0;
+}
+
+void __init txx9_iocled_init(unsigned long baseaddr,
+ int basenum, unsigned int num, int lowactive,
+ const char *color, char **deftriggers)
+{
+ struct txx9_iocled_data *iocled;
+ struct platform_device *pdev;
+ int i;
+ static char *default_triggers[] __initdata = {
+ "heartbeat",
+ "ide-disk",
+ "nand-disk",
+ NULL,
+ };
+
+ if (!deftriggers)
+ deftriggers = default_triggers;
+ iocled = kzalloc(sizeof(*iocled), GFP_KERNEL);
+ if (!iocled)
+ return;
+ iocled->mmioaddr = ioremap(baseaddr, 1);
+ if (!iocled->mmioaddr)
+ goto out_free;
+ iocled->chip.get = txx9_iocled_get;
+ iocled->chip.set = txx9_iocled_set;
+ iocled->chip.direction_input = txx9_iocled_dir_in;
+ iocled->chip.direction_output = txx9_iocled_dir_out;
+ iocled->chip.label = "iocled";
+ iocled->chip.base = basenum;
+ iocled->chip.ngpio = num;
+ if (gpiochip_add(&iocled->chip))
+ goto out_unmap;
+ if (basenum < 0)
+ basenum = iocled->chip.base;
+
+ pdev = platform_device_alloc("leds-gpio", basenum);
+ if (!pdev)
+ goto out_gpio;
+ iocled->pdata.num_leds = num;
+ iocled->pdata.leds = iocled->leds;
+ for (i = 0; i < num; i++) {
+ struct gpio_led *led = &iocled->leds[i];
+ snprintf(iocled->names[i], sizeof(iocled->names[i]),
+ "iocled:%s:%u", color, i);
+ led->name = iocled->names[i];
+ led->gpio = basenum + i;
+ led->active_low = lowactive;
+ if (deftriggers && *deftriggers)
+ led->default_trigger = *deftriggers++;
+ }
+ pdev->dev.platform_data = &iocled->pdata;
+ if (platform_device_add(pdev))
+ goto out_pdev;
+ return;
+out_pdev:
+ platform_device_put(pdev);
+out_gpio:
+ if (gpiochip_remove(&iocled->chip))
+ return;
+out_unmap:
+ iounmap(iocled->mmioaddr);
+out_free:
+ kfree(iocled);
+}
+#else /* CONFIG_LEDS_GPIO */
+void __init txx9_iocled_init(unsigned long baseaddr,
+ int basenum, unsigned int num, int lowactive,
+ const char *color, char **deftriggers)
+{
+}
+#endif /* CONFIG_LEDS_GPIO */
+
+void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq,
+ const struct txx9dmac_platform_data *pdata)
+{
+#if defined(CONFIG_TXX9_DMAC) || defined(CONFIG_TXX9_DMAC_MODULE)
+ struct resource res[] = {
+ {
+ .start = baseaddr,
+ .end = baseaddr + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+#ifndef CONFIG_MACH_TX49XX
+ }, {
+ .start = irq,
+ .flags = IORESOURCE_IRQ,
+#endif
+ }
+ };
+#ifdef CONFIG_MACH_TX49XX
+ struct resource chan_res[] = {
+ {
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+#endif
+ struct platform_device *pdev = platform_device_alloc("txx9dmac", id);
+ struct txx9dmac_chan_platform_data cpdata;
+ int i;
+
+ if (!pdev ||
+ platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
+ platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+ platform_device_add(pdev)) {
+ platform_device_put(pdev);
+ return;
+ }
+ memset(&cpdata, 0, sizeof(cpdata));
+ cpdata.dmac_dev = pdev;
+ for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) {
+#ifdef CONFIG_MACH_TX49XX
+ chan_res[0].start = irq + i;
+#endif
+ pdev = platform_device_alloc("txx9dmac-chan",
+ id * TXX9_DMA_MAX_NR_CHANNELS + i);
+ if (!pdev ||
+#ifdef CONFIG_MACH_TX49XX
+ platform_device_add_resources(pdev, chan_res,
+ ARRAY_SIZE(chan_res)) ||
+#endif
+ platform_device_add_data(pdev, &cpdata, sizeof(cpdata)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+ }
+#endif
+}
+
+void __init txx9_aclc_init(unsigned long baseaddr, int irq,
+ unsigned int dmac_id,
+ unsigned int dma_chan_out,
+ unsigned int dma_chan_in)
+{
+#if defined(CONFIG_SND_SOC_TXX9ACLC) || \
+ defined(CONFIG_SND_SOC_TXX9ACLC_MODULE)
+ unsigned int dma_base = dmac_id * TXX9_DMA_MAX_NR_CHANNELS;
+ struct resource res[] = {
+ {
+ .start = baseaddr,
+ .end = baseaddr + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "txx9dmac-chan",
+ .start = dma_base + dma_chan_out,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .name = "txx9dmac-chan",
+ .start = dma_base + dma_chan_in,
+ .flags = IORESOURCE_DMA,
+ }
+ };
+ struct platform_device *pdev =
+ platform_device_alloc("txx9aclc-ac97", -1);
+
+ if (!pdev ||
+ platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+#endif
+}
+
+static struct sysdev_class txx9_sramc_sysdev_class;
+
+struct txx9_sramc_sysdev {
+ struct sys_device dev;
+ struct bin_attribute bindata_attr;
+ void __iomem *base;
+};
+
+static ssize_t txx9_sram_read(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t pos, size_t size)
+{
+ struct txx9_sramc_sysdev *dev = bin_attr->private;
+ size_t ramsize = bin_attr->size;
+
+ if (pos >= ramsize)
+ return 0;
+ if (pos + size > ramsize)
+ size = ramsize - pos;
+ memcpy_fromio(buf, dev->base + pos, size);
+ return size;
+}
+
+static ssize_t txx9_sram_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t pos, size_t size)
+{
+ struct txx9_sramc_sysdev *dev = bin_attr->private;
+ size_t ramsize = bin_attr->size;
+
+ if (pos >= ramsize)
+ return 0;
+ if (pos + size > ramsize)
+ size = ramsize - pos;
+ memcpy_toio(dev->base + pos, buf, size);
+ return size;
+}
+
+void __init txx9_sramc_init(struct resource *r)
+{
+ struct txx9_sramc_sysdev *dev;
+ size_t size;
+ int err;
+
+ if (!txx9_sramc_sysdev_class.name) {
+ txx9_sramc_sysdev_class.name = "txx9_sram";
+ err = sysdev_class_register(&txx9_sramc_sysdev_class);
+ if (err) {
+ txx9_sramc_sysdev_class.name = NULL;
+ return;
+ }
+ }
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return;
+ size = resource_size(r);
+ dev->base = ioremap(r->start, size);
+ if (!dev->base)
+ goto exit;
+ dev->dev.cls = &txx9_sramc_sysdev_class;
+ sysfs_bin_attr_init(&dev->bindata_attr);
+ dev->bindata_attr.attr.name = "bindata";
+ dev->bindata_attr.attr.mode = S_IRUSR | S_IWUSR;
+ dev->bindata_attr.read = txx9_sram_read;
+ dev->bindata_attr.write = txx9_sram_write;
+ dev->bindata_attr.size = size;
+ dev->bindata_attr.private = dev;
+ err = sysdev_register(&dev->dev);
+ if (err)
+ goto exit;
+ err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr);
+ if (err) {
+ sysdev_unregister(&dev->dev);
+ goto exit;
+ }
+ return;
+exit:
+ if (dev) {
+ if (dev->base)
+ iounmap(dev->base);
+ kfree(dev);
+ }
+}
diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c
new file mode 100644
index 00000000..9505d584
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx3927.c
@@ -0,0 +1,137 @@
+/*
+ * TX3927 setup routines
+ * Based on linux/arch/mips/txx9/jmr3927/setup.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/param.h>
+#include <linux/io.h>
+#include <linux/mtd/physmap.h>
+#include <asm/mipsregs.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9tmr.h>
+#include <asm/txx9pio.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/tx3927.h>
+
+void __init tx3927_wdt_init(void)
+{
+ txx9_wdt_init(TX3927_TMR_REG(2));
+}
+
+void __init tx3927_setup(void)
+{
+ int i;
+ unsigned int conf;
+
+ txx9_reg_res_init(TX3927_REV_PCODE(), TX3927_REG_BASE,
+ TX3927_REG_SIZE);
+
+ /* SDRAMC,ROMC are configured by PROM */
+ for (i = 0; i < 8; i++) {
+ if (!(tx3927_romcptr->cr[i] & 0x8))
+ continue; /* disabled */
+ txx9_ce_res[i].start = (unsigned long)TX3927_ROMC_BA(i);
+ txx9_ce_res[i].end =
+ txx9_ce_res[i].start + TX3927_ROMC_SIZE(i) - 1;
+ request_resource(&iomem_resource, &txx9_ce_res[i]);
+ }
+
+ /* clocks */
+ txx9_gbus_clock = txx9_cpu_clock / 2;
+ /* change default value to udelay/mdelay take reasonable time */
+ loops_per_jiffy = txx9_cpu_clock / HZ / 2;
+
+ /* CCFG */
+ /* enable Timeout BusError */
+ if (txx9_ccfg_toeon)
+ tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE;
+
+ /* clear BusErrorOnWrite flag */
+ tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW;
+ if (read_c0_conf() & TX39_CONF_WBON)
+ /* Disable PCI snoop */
+ tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP;
+ else
+ /* Enable PCI SNOOP - with write through only */
+ tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP;
+ /* do reset on watchdog */
+ tx3927_ccfgptr->ccfg |= TX3927_CCFG_WR;
+
+ printk(KERN_INFO "TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n",
+ tx3927_ccfgptr->crir,
+ tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg);
+
+ /* TMR */
+ for (i = 0; i < TX3927_NR_TMR; i++)
+ txx9_tmr_init(TX3927_TMR_REG(i));
+
+ /* DMA */
+ tx3927_dmaptr->mcr = 0;
+ for (i = 0; i < ARRAY_SIZE(tx3927_dmaptr->ch); i++) {
+ /* reset channel */
+ tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST;
+ tx3927_dmaptr->ch[i].ccr = 0;
+ }
+ /* enable DMA */
+#ifdef __BIG_ENDIAN
+ tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN;
+#else
+ tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE;
+#endif
+
+ /* PIO */
+ __raw_writel(0, &tx3927_pioptr->maskcpu);
+ __raw_writel(0, &tx3927_pioptr->maskext);
+ txx9_gpio_init(TX3927_PIO_REG, 0, 16);
+
+ conf = read_c0_conf();
+ if (conf & TX39_CONF_DCE) {
+ if (!(conf & TX39_CONF_WBON))
+ pr_info("TX3927 D-Cache WriteThrough.\n");
+ else if (!(conf & TX39_CONF_CWFON))
+ pr_info("TX3927 D-Cache WriteBack.\n");
+ else
+ pr_info("TX3927 D-Cache WriteBack (CWF) .\n");
+ }
+}
+
+void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr)
+{
+ txx9_clockevent_init(TX3927_TMR_REG(evt_tmrnr),
+ TXX9_IRQ_BASE + TX3927_IR_TMR(evt_tmrnr),
+ TXX9_IMCLK);
+ txx9_clocksource_init(TX3927_TMR_REG(src_tmrnr), TXX9_IMCLK);
+}
+
+void __init tx3927_sio_init(unsigned int sclk, unsigned int cts_mask)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ txx9_sio_init(TX3927_SIO_REG(i),
+ TXX9_IRQ_BASE + TX3927_IR_SIO(i),
+ i, sclk, (1 << i) & cts_mask);
+}
+
+void __init tx3927_mtd_init(int ch)
+{
+ struct physmap_flash_data pdata = {
+ .width = TX3927_ROMC_WIDTH(ch) / 8,
+ };
+ unsigned long start = txx9_ce_res[ch].start;
+ unsigned long size = txx9_ce_res[ch].end - start + 1;
+
+ if (!(tx3927_romcptr->cr[ch] & 0x8))
+ return; /* disabled */
+ txx9_physmap_flash_init(ch, start, size, &pdata);
+}
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c
new file mode 100644
index 00000000..3418b2a9
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx4927.c
@@ -0,0 +1,340 @@
+/*
+ * TX4927 setup routines
+ * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * 2003-2005 (c) MontaVista Software, Inc.
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/param.h>
+#include <linux/ptrace.h>
+#include <linux/mtd/physmap.h>
+#include <asm/reboot.h>
+#include <asm/traps.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9tmr.h>
+#include <asm/txx9pio.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/dmac.h>
+#include <asm/txx9/tx4927.h>
+
+static void __init tx4927_wdr_init(void)
+{
+ /* report watchdog reset status */
+ if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST)
+ pr_warning("Watchdog reset detected at 0x%lx\n",
+ read_c0_errorepc());
+ /* clear WatchDogReset (W1C) */
+ tx4927_ccfg_set(TX4927_CCFG_WDRST);
+ /* do reset on watchdog */
+ tx4927_ccfg_set(TX4927_CCFG_WR);
+}
+
+void __init tx4927_wdt_init(void)
+{
+ txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL);
+}
+
+static void tx4927_machine_restart(char *command)
+{
+ local_irq_disable();
+ pr_emerg("Rebooting (with %s watchdog reset)...\n",
+ (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) ?
+ "external" : "internal");
+ /* clear watchdog status */
+ tx4927_ccfg_set(TX4927_CCFG_WDRST); /* W1C */
+ txx9_wdt_now(TX4927_TMR_REG(2) & 0xfffffffffULL);
+ while (!(____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST))
+ ;
+ mdelay(10);
+ if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDREXEN) {
+ pr_emerg("Rebooting (with internal watchdog reset)...\n");
+ /* External WDRST failed. Do internal watchdog reset */
+ tx4927_ccfg_clear(TX4927_CCFG_WDREXEN);
+ }
+ /* fallback */
+ (*_machine_halt)();
+}
+
+void show_registers(struct pt_regs *regs);
+static int tx4927_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ int data = regs->cp0_cause & 4;
+ console_verbose();
+ pr_err("%cBE exception at %#lx\n", data ? 'D' : 'I', regs->cp0_epc);
+ pr_err("ccfg:%llx, toea:%llx\n",
+ (unsigned long long)____raw_readq(&tx4927_ccfgptr->ccfg),
+ (unsigned long long)____raw_readq(&tx4927_ccfgptr->toea));
+#ifdef CONFIG_PCI
+ tx4927_report_pcic_status();
+#endif
+ show_registers(regs);
+ panic("BusError!");
+}
+static void __init tx4927_be_init(void)
+{
+ board_be_handler = tx4927_be_handler;
+}
+
+static struct resource tx4927_sdram_resource[4];
+
+void __init tx4927_setup(void)
+{
+ int i;
+ __u32 divmode;
+ unsigned int cpuclk = 0;
+ u64 ccfg;
+
+ txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE,
+ TX4927_REG_SIZE);
+ set_c0_config(TX49_CONF_CWFON);
+
+ /* SDRAMC,EBUSC are configured by PROM */
+ for (i = 0; i < 8; i++) {
+ if (!(TX4927_EBUSC_CR(i) & 0x8))
+ continue; /* disabled */
+ txx9_ce_res[i].start = (unsigned long)TX4927_EBUSC_BA(i);
+ txx9_ce_res[i].end =
+ txx9_ce_res[i].start + TX4927_EBUSC_SIZE(i) - 1;
+ request_resource(&iomem_resource, &txx9_ce_res[i]);
+ }
+
+ /* clocks */
+ ccfg = ____raw_readq(&tx4927_ccfgptr->ccfg);
+ if (txx9_master_clock) {
+ /* calculate gbus_clock and cpu_clock from master_clock */
+ divmode = (__u32)ccfg & TX4927_CCFG_DIVMODE_MASK;
+ switch (divmode) {
+ case TX4927_CCFG_DIVMODE_8:
+ case TX4927_CCFG_DIVMODE_10:
+ case TX4927_CCFG_DIVMODE_12:
+ case TX4927_CCFG_DIVMODE_16:
+ txx9_gbus_clock = txx9_master_clock * 4; break;
+ default:
+ txx9_gbus_clock = txx9_master_clock;
+ }
+ switch (divmode) {
+ case TX4927_CCFG_DIVMODE_2:
+ case TX4927_CCFG_DIVMODE_8:
+ cpuclk = txx9_gbus_clock * 2; break;
+ case TX4927_CCFG_DIVMODE_2_5:
+ case TX4927_CCFG_DIVMODE_10:
+ cpuclk = txx9_gbus_clock * 5 / 2; break;
+ case TX4927_CCFG_DIVMODE_3:
+ case TX4927_CCFG_DIVMODE_12:
+ cpuclk = txx9_gbus_clock * 3; break;
+ case TX4927_CCFG_DIVMODE_4:
+ case TX4927_CCFG_DIVMODE_16:
+ cpuclk = txx9_gbus_clock * 4; break;
+ }
+ txx9_cpu_clock = cpuclk;
+ } else {
+ if (txx9_cpu_clock == 0)
+ txx9_cpu_clock = 200000000; /* 200MHz */
+ /* calculate gbus_clock and master_clock from cpu_clock */
+ cpuclk = txx9_cpu_clock;
+ divmode = (__u32)ccfg & TX4927_CCFG_DIVMODE_MASK;
+ switch (divmode) {
+ case TX4927_CCFG_DIVMODE_2:
+ case TX4927_CCFG_DIVMODE_8:
+ txx9_gbus_clock = cpuclk / 2; break;
+ case TX4927_CCFG_DIVMODE_2_5:
+ case TX4927_CCFG_DIVMODE_10:
+ txx9_gbus_clock = cpuclk * 2 / 5; break;
+ case TX4927_CCFG_DIVMODE_3:
+ case TX4927_CCFG_DIVMODE_12:
+ txx9_gbus_clock = cpuclk / 3; break;
+ case TX4927_CCFG_DIVMODE_4:
+ case TX4927_CCFG_DIVMODE_16:
+ txx9_gbus_clock = cpuclk / 4; break;
+ }
+ switch (divmode) {
+ case TX4927_CCFG_DIVMODE_8:
+ case TX4927_CCFG_DIVMODE_10:
+ case TX4927_CCFG_DIVMODE_12:
+ case TX4927_CCFG_DIVMODE_16:
+ txx9_master_clock = txx9_gbus_clock / 4; break;
+ default:
+ txx9_master_clock = txx9_gbus_clock;
+ }
+ }
+ /* change default value to udelay/mdelay take reasonable time */
+ loops_per_jiffy = txx9_cpu_clock / HZ / 2;
+
+ /* CCFG */
+ tx4927_wdr_init();
+ /* clear BusErrorOnWrite flag (W1C) */
+ tx4927_ccfg_set(TX4927_CCFG_BEOW);
+ /* enable Timeout BusError */
+ if (txx9_ccfg_toeon)
+ tx4927_ccfg_set(TX4927_CCFG_TOE);
+
+ /* DMA selection */
+ txx9_clear64(&tx4927_ccfgptr->pcfg, TX4927_PCFG_DMASEL_ALL);
+
+ /* Use external clock for external arbiter */
+ if (!(____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB))
+ txx9_clear64(&tx4927_ccfgptr->pcfg, TX4927_PCFG_PCICLKEN_ALL);
+
+ printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
+ txx9_pcode_str,
+ (cpuclk + 500000) / 1000000,
+ (txx9_master_clock + 500000) / 1000000,
+ (__u32)____raw_readq(&tx4927_ccfgptr->crir),
+ (unsigned long long)____raw_readq(&tx4927_ccfgptr->ccfg),
+ (unsigned long long)____raw_readq(&tx4927_ccfgptr->pcfg));
+
+ printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str);
+ for (i = 0; i < 4; i++) {
+ __u64 cr = TX4927_SDRAMC_CR(i);
+ unsigned long base, size;
+ if (!((__u32)cr & 0x00000400))
+ continue; /* disabled */
+ base = (unsigned long)(cr >> 49) << 21;
+ size = (((unsigned long)(cr >> 33) & 0x7fff) + 1) << 21;
+ printk(" CR%d:%016llx", i, (unsigned long long)cr);
+ tx4927_sdram_resource[i].name = "SDRAM";
+ tx4927_sdram_resource[i].start = base;
+ tx4927_sdram_resource[i].end = base + size - 1;
+ tx4927_sdram_resource[i].flags = IORESOURCE_MEM;
+ request_resource(&iomem_resource, &tx4927_sdram_resource[i]);
+ }
+ printk(" TR:%09llx\n",
+ (unsigned long long)____raw_readq(&tx4927_sdramcptr->tr));
+
+ /* TMR */
+ /* disable all timers */
+ for (i = 0; i < TX4927_NR_TMR; i++)
+ txx9_tmr_init(TX4927_TMR_REG(i) & 0xfffffffffULL);
+
+ /* PIO */
+ txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO);
+ __raw_writel(0, &tx4927_pioptr->maskcpu);
+ __raw_writel(0, &tx4927_pioptr->maskext);
+
+ _machine_restart = tx4927_machine_restart;
+ board_be_init = tx4927_be_init;
+}
+
+void __init tx4927_time_init(unsigned int tmrnr)
+{
+ if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS)
+ txx9_clockevent_init(TX4927_TMR_REG(tmrnr) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4927_IR_TMR(tmrnr),
+ TXX9_IMCLK);
+}
+
+void __init tx4927_sio_init(unsigned int sclk, unsigned int cts_mask)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ txx9_sio_init(TX4927_SIO_REG(i) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4927_IR_SIO(i),
+ i, sclk, (1 << i) & cts_mask);
+}
+
+void __init tx4927_mtd_init(int ch)
+{
+ struct physmap_flash_data pdata = {
+ .width = TX4927_EBUSC_WIDTH(ch) / 8,
+ };
+ unsigned long start = txx9_ce_res[ch].start;
+ unsigned long size = txx9_ce_res[ch].end - start + 1;
+
+ if (!(TX4927_EBUSC_CR(ch) & 0x8))
+ return; /* disabled */
+ txx9_physmap_flash_init(ch, start, size, &pdata);
+}
+
+void __init tx4927_dmac_init(int memcpy_chan)
+{
+ struct txx9dmac_platform_data plat_data = {
+ .memcpy_chan = memcpy_chan,
+ .have_64bit_regs = true,
+ };
+
+ txx9_dmac_init(0, TX4927_DMA_REG & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4927_IR_DMA(0), &plat_data);
+}
+
+void __init tx4927_aclc_init(unsigned int dma_chan_out,
+ unsigned int dma_chan_in)
+{
+ u64 pcfg = __raw_readq(&tx4927_ccfgptr->pcfg);
+ __u64 dmasel_mask = 0, dmasel = 0;
+ unsigned long flags;
+
+ if (!(pcfg & TX4927_PCFG_SEL2))
+ return;
+ /* setup DMASEL (playback:ACLC ch0, capture:ACLC ch1) */
+ switch (dma_chan_out) {
+ case 0:
+ dmasel_mask |= TX4927_PCFG_DMASEL0_MASK;
+ dmasel |= TX4927_PCFG_DMASEL0_ACL0;
+ break;
+ case 2:
+ dmasel_mask |= TX4927_PCFG_DMASEL2_MASK;
+ dmasel |= TX4927_PCFG_DMASEL2_ACL0;
+ break;
+ default:
+ return;
+ }
+ switch (dma_chan_in) {
+ case 1:
+ dmasel_mask |= TX4927_PCFG_DMASEL1_MASK;
+ dmasel |= TX4927_PCFG_DMASEL1_ACL1;
+ break;
+ case 3:
+ dmasel_mask |= TX4927_PCFG_DMASEL3_MASK;
+ dmasel |= TX4927_PCFG_DMASEL3_ACL1;
+ break;
+ default:
+ return;
+ }
+ local_irq_save(flags);
+ txx9_clear64(&tx4927_ccfgptr->pcfg, dmasel_mask);
+ txx9_set64(&tx4927_ccfgptr->pcfg, dmasel);
+ local_irq_restore(flags);
+ txx9_aclc_init(TX4927_ACLC_REG & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4927_IR_ACLC,
+ 0, dma_chan_out, dma_chan_in);
+}
+
+static void __init tx4927_stop_unused_modules(void)
+{
+ __u64 pcfg, rst = 0, ckd = 0;
+ char buf[128];
+
+ buf[0] = '\0';
+ local_irq_disable();
+ pcfg = ____raw_readq(&tx4927_ccfgptr->pcfg);
+ if (!(pcfg & TX4927_PCFG_SEL2)) {
+ rst |= TX4927_CLKCTR_ACLRST;
+ ckd |= TX4927_CLKCTR_ACLCKD;
+ strcat(buf, " ACLC");
+ }
+ if (rst | ckd) {
+ txx9_set64(&tx4927_ccfgptr->clkctr, rst);
+ txx9_set64(&tx4927_ccfgptr->clkctr, ckd);
+ }
+ local_irq_enable();
+ if (buf[0])
+ pr_info("%s: stop%s\n", txx9_pcode_str, buf);
+}
+
+static int __init tx4927_late_init(void)
+{
+ if (txx9_pcode != 0x4927)
+ return -ENODEV;
+ tx4927_stop_unused_modules();
+ return 0;
+}
+late_initcall(tx4927_late_init);
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
new file mode 100644
index 00000000..eb208011
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -0,0 +1,488 @@
+/*
+ * TX4938/4937 setup routines
+ * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * 2003-2005 (c) MontaVista Software, Inc.
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/param.h>
+#include <linux/ptrace.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/reboot.h>
+#include <asm/traps.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9tmr.h>
+#include <asm/txx9pio.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
+#include <asm/txx9/tx4938.h>
+
+static void __init tx4938_wdr_init(void)
+{
+ /* report watchdog reset status */
+ if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST)
+ pr_warning("Watchdog reset detected at 0x%lx\n",
+ read_c0_errorepc());
+ /* clear WatchDogReset (W1C) */
+ tx4938_ccfg_set(TX4938_CCFG_WDRST);
+ /* do reset on watchdog */
+ tx4938_ccfg_set(TX4938_CCFG_WR);
+}
+
+void __init tx4938_wdt_init(void)
+{
+ txx9_wdt_init(TX4938_TMR_REG(2) & 0xfffffffffULL);
+}
+
+static void tx4938_machine_restart(char *command)
+{
+ local_irq_disable();
+ pr_emerg("Rebooting (with %s watchdog reset)...\n",
+ (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) ?
+ "external" : "internal");
+ /* clear watchdog status */
+ tx4938_ccfg_set(TX4938_CCFG_WDRST); /* W1C */
+ txx9_wdt_now(TX4938_TMR_REG(2) & 0xfffffffffULL);
+ while (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST))
+ ;
+ mdelay(10);
+ if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDREXEN) {
+ pr_emerg("Rebooting (with internal watchdog reset)...\n");
+ /* External WDRST failed. Do internal watchdog reset */
+ tx4938_ccfg_clear(TX4938_CCFG_WDREXEN);
+ }
+ /* fallback */
+ (*_machine_halt)();
+}
+
+void show_registers(struct pt_regs *regs);
+static int tx4938_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ int data = regs->cp0_cause & 4;
+ console_verbose();
+ pr_err("%cBE exception at %#lx\n", data ? 'D' : 'I', regs->cp0_epc);
+ pr_err("ccfg:%llx, toea:%llx\n",
+ (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg),
+ (unsigned long long)____raw_readq(&tx4938_ccfgptr->toea));
+#ifdef CONFIG_PCI
+ tx4927_report_pcic_status();
+#endif
+ show_registers(regs);
+ panic("BusError!");
+}
+static void __init tx4938_be_init(void)
+{
+ board_be_handler = tx4938_be_handler;
+}
+
+static struct resource tx4938_sdram_resource[4];
+static struct resource tx4938_sram_resource;
+
+#define TX4938_SRAM_SIZE 0x800
+
+void __init tx4938_setup(void)
+{
+ int i;
+ __u32 divmode;
+ unsigned int cpuclk = 0;
+ u64 ccfg;
+
+ txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE,
+ TX4938_REG_SIZE);
+ set_c0_config(TX49_CONF_CWFON);
+
+ /* SDRAMC,EBUSC are configured by PROM */
+ for (i = 0; i < 8; i++) {
+ if (!(TX4938_EBUSC_CR(i) & 0x8))
+ continue; /* disabled */
+ txx9_ce_res[i].start = (unsigned long)TX4938_EBUSC_BA(i);
+ txx9_ce_res[i].end =
+ txx9_ce_res[i].start + TX4938_EBUSC_SIZE(i) - 1;
+ request_resource(&iomem_resource, &txx9_ce_res[i]);
+ }
+
+ /* clocks */
+ ccfg = ____raw_readq(&tx4938_ccfgptr->ccfg);
+ if (txx9_master_clock) {
+ /* calculate gbus_clock and cpu_clock from master_clock */
+ divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK;
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_8:
+ case TX4938_CCFG_DIVMODE_10:
+ case TX4938_CCFG_DIVMODE_12:
+ case TX4938_CCFG_DIVMODE_16:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_gbus_clock = txx9_master_clock * 4; break;
+ default:
+ txx9_gbus_clock = txx9_master_clock;
+ }
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_2:
+ case TX4938_CCFG_DIVMODE_8:
+ cpuclk = txx9_gbus_clock * 2; break;
+ case TX4938_CCFG_DIVMODE_2_5:
+ case TX4938_CCFG_DIVMODE_10:
+ cpuclk = txx9_gbus_clock * 5 / 2; break;
+ case TX4938_CCFG_DIVMODE_3:
+ case TX4938_CCFG_DIVMODE_12:
+ cpuclk = txx9_gbus_clock * 3; break;
+ case TX4938_CCFG_DIVMODE_4:
+ case TX4938_CCFG_DIVMODE_16:
+ cpuclk = txx9_gbus_clock * 4; break;
+ case TX4938_CCFG_DIVMODE_4_5:
+ case TX4938_CCFG_DIVMODE_18:
+ cpuclk = txx9_gbus_clock * 9 / 2; break;
+ }
+ txx9_cpu_clock = cpuclk;
+ } else {
+ if (txx9_cpu_clock == 0)
+ txx9_cpu_clock = 300000000; /* 300MHz */
+ /* calculate gbus_clock and master_clock from cpu_clock */
+ cpuclk = txx9_cpu_clock;
+ divmode = (__u32)ccfg & TX4938_CCFG_DIVMODE_MASK;
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_2:
+ case TX4938_CCFG_DIVMODE_8:
+ txx9_gbus_clock = cpuclk / 2; break;
+ case TX4938_CCFG_DIVMODE_2_5:
+ case TX4938_CCFG_DIVMODE_10:
+ txx9_gbus_clock = cpuclk * 2 / 5; break;
+ case TX4938_CCFG_DIVMODE_3:
+ case TX4938_CCFG_DIVMODE_12:
+ txx9_gbus_clock = cpuclk / 3; break;
+ case TX4938_CCFG_DIVMODE_4:
+ case TX4938_CCFG_DIVMODE_16:
+ txx9_gbus_clock = cpuclk / 4; break;
+ case TX4938_CCFG_DIVMODE_4_5:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_gbus_clock = cpuclk * 2 / 9; break;
+ }
+ switch (divmode) {
+ case TX4938_CCFG_DIVMODE_8:
+ case TX4938_CCFG_DIVMODE_10:
+ case TX4938_CCFG_DIVMODE_12:
+ case TX4938_CCFG_DIVMODE_16:
+ case TX4938_CCFG_DIVMODE_18:
+ txx9_master_clock = txx9_gbus_clock / 4; break;
+ default:
+ txx9_master_clock = txx9_gbus_clock;
+ }
+ }
+ /* change default value to udelay/mdelay take reasonable time */
+ loops_per_jiffy = txx9_cpu_clock / HZ / 2;
+
+ /* CCFG */
+ tx4938_wdr_init();
+ /* clear BusErrorOnWrite flag (W1C) */
+ tx4938_ccfg_set(TX4938_CCFG_BEOW);
+ /* enable Timeout BusError */
+ if (txx9_ccfg_toeon)
+ tx4938_ccfg_set(TX4938_CCFG_TOE);
+
+ /* DMA selection */
+ txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_DMASEL_ALL);
+
+ /* Use external clock for external arbiter */
+ if (!(____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB))
+ txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_PCICLKEN_ALL);
+
+ printk(KERN_INFO "%s -- %dMHz(M%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
+ txx9_pcode_str,
+ (cpuclk + 500000) / 1000000,
+ (txx9_master_clock + 500000) / 1000000,
+ (__u32)____raw_readq(&tx4938_ccfgptr->crir),
+ (unsigned long long)____raw_readq(&tx4938_ccfgptr->ccfg),
+ (unsigned long long)____raw_readq(&tx4938_ccfgptr->pcfg));
+
+ printk(KERN_INFO "%s SDRAMC --", txx9_pcode_str);
+ for (i = 0; i < 4; i++) {
+ __u64 cr = TX4938_SDRAMC_CR(i);
+ unsigned long base, size;
+ if (!((__u32)cr & 0x00000400))
+ continue; /* disabled */
+ base = (unsigned long)(cr >> 49) << 21;
+ size = (((unsigned long)(cr >> 33) & 0x7fff) + 1) << 21;
+ printk(" CR%d:%016llx", i, (unsigned long long)cr);
+ tx4938_sdram_resource[i].name = "SDRAM";
+ tx4938_sdram_resource[i].start = base;
+ tx4938_sdram_resource[i].end = base + size - 1;
+ tx4938_sdram_resource[i].flags = IORESOURCE_MEM;
+ request_resource(&iomem_resource, &tx4938_sdram_resource[i]);
+ }
+ printk(" TR:%09llx\n",
+ (unsigned long long)____raw_readq(&tx4938_sdramcptr->tr));
+
+ /* SRAM */
+ if (txx9_pcode == 0x4938 && ____raw_readq(&tx4938_sramcptr->cr) & 1) {
+ unsigned int size = TX4938_SRAM_SIZE;
+ tx4938_sram_resource.name = "SRAM";
+ tx4938_sram_resource.start =
+ (____raw_readq(&tx4938_sramcptr->cr) >> (39-11))
+ & ~(size - 1);
+ tx4938_sram_resource.end =
+ tx4938_sram_resource.start + TX4938_SRAM_SIZE - 1;
+ tx4938_sram_resource.flags = IORESOURCE_MEM;
+ request_resource(&iomem_resource, &tx4938_sram_resource);
+ }
+
+ /* TMR */
+ /* disable all timers */
+ for (i = 0; i < TX4938_NR_TMR; i++)
+ txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
+
+ /* PIO */
+ txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO);
+ __raw_writel(0, &tx4938_pioptr->maskcpu);
+ __raw_writel(0, &tx4938_pioptr->maskext);
+
+ if (txx9_pcode == 0x4938) {
+ __u64 pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg);
+ /* set PCIC1 reset */
+ txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
+ if (pcfg & (TX4938_PCFG_ETH0_SEL | TX4938_PCFG_ETH1_SEL)) {
+ mdelay(1); /* at least 128 cpu clock */
+ /* clear PCIC1 reset */
+ txx9_clear64(&tx4938_ccfgptr->clkctr,
+ TX4938_CLKCTR_PCIC1RST);
+ } else {
+ printk(KERN_INFO "%s: stop PCIC1\n", txx9_pcode_str);
+ /* stop PCIC1 */
+ txx9_set64(&tx4938_ccfgptr->clkctr,
+ TX4938_CLKCTR_PCIC1CKD);
+ }
+ if (!(pcfg & TX4938_PCFG_ETH0_SEL)) {
+ printk(KERN_INFO "%s: stop ETH0\n", txx9_pcode_str);
+ txx9_set64(&tx4938_ccfgptr->clkctr,
+ TX4938_CLKCTR_ETH0RST);
+ txx9_set64(&tx4938_ccfgptr->clkctr,
+ TX4938_CLKCTR_ETH0CKD);
+ }
+ if (!(pcfg & TX4938_PCFG_ETH1_SEL)) {
+ printk(KERN_INFO "%s: stop ETH1\n", txx9_pcode_str);
+ txx9_set64(&tx4938_ccfgptr->clkctr,
+ TX4938_CLKCTR_ETH1RST);
+ txx9_set64(&tx4938_ccfgptr->clkctr,
+ TX4938_CLKCTR_ETH1CKD);
+ }
+ }
+
+ _machine_restart = tx4938_machine_restart;
+ board_be_init = tx4938_be_init;
+}
+
+void __init tx4938_time_init(unsigned int tmrnr)
+{
+ if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_TINTDIS)
+ txx9_clockevent_init(TX4938_TMR_REG(tmrnr) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4938_IR_TMR(tmrnr),
+ TXX9_IMCLK);
+}
+
+void __init tx4938_sio_init(unsigned int sclk, unsigned int cts_mask)
+{
+ int i;
+ unsigned int ch_mask = 0;
+
+ if (__raw_readq(&tx4938_ccfgptr->pcfg) & TX4938_PCFG_ETH0_SEL)
+ ch_mask |= 1 << 1; /* disable SIO1 by PCFG setting */
+ for (i = 0; i < 2; i++) {
+ if ((1 << i) & ch_mask)
+ continue;
+ txx9_sio_init(TX4938_SIO_REG(i) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4938_IR_SIO(i),
+ i, sclk, (1 << i) & cts_mask);
+ }
+}
+
+void __init tx4938_spi_init(int busid)
+{
+ txx9_spi_init(busid, TX4938_SPI_REG & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4938_IR_SPI);
+}
+
+void __init tx4938_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
+{
+ u64 pcfg = __raw_readq(&tx4938_ccfgptr->pcfg);
+
+ if (addr0 && (pcfg & TX4938_PCFG_ETH0_SEL))
+ txx9_ethaddr_init(TXX9_IRQ_BASE + TX4938_IR_ETH0, addr0);
+ if (addr1 && (pcfg & TX4938_PCFG_ETH1_SEL))
+ txx9_ethaddr_init(TXX9_IRQ_BASE + TX4938_IR_ETH1, addr1);
+}
+
+void __init tx4938_mtd_init(int ch)
+{
+ struct physmap_flash_data pdata = {
+ .width = TX4938_EBUSC_WIDTH(ch) / 8,
+ };
+ unsigned long start = txx9_ce_res[ch].start;
+ unsigned long size = txx9_ce_res[ch].end - start + 1;
+
+ if (!(TX4938_EBUSC_CR(ch) & 0x8))
+ return; /* disabled */
+ txx9_physmap_flash_init(ch, start, size, &pdata);
+}
+
+void __init tx4938_ata_init(unsigned int irq, unsigned int shift, int tune)
+{
+ struct platform_device *pdev;
+ struct resource res[] = {
+ {
+ /* .start and .end are filled in later */
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ struct tx4938ide_platform_info pdata = {
+ .ioport_shift = shift,
+ /*
+ * The IDE driver should not change bus timings if other ISA
+ * devices existed.
+ */
+ .gbus_clock = tune ? txx9_gbus_clock : 0,
+ };
+ u64 ebccr;
+ int i;
+
+ if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
+ (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL))
+ != TX4938_PCFG_ATA_SEL)
+ return;
+ for (i = 0; i < 8; i++) {
+ /* check EBCCRn.ISA, EBCCRn.BSZ, EBCCRn.ME */
+ ebccr = __raw_readq(&tx4938_ebuscptr->cr[i]);
+ if ((ebccr & 0x00f00008) == 0x00e00008)
+ break;
+ }
+ if (i == 8)
+ return;
+ pdata.ebus_ch = i;
+ res[0].start = ((ebccr >> 48) << 20) + 0x10000;
+ res[0].end = res[0].start + 0x20000 - 1;
+ pdev = platform_device_alloc("tx4938ide", -1);
+ if (!pdev ||
+ platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
+ platform_device_add_data(pdev, &pdata, sizeof(pdata)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+}
+
+void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
+{
+ struct txx9ndfmc_platform_data plat_data = {
+ .shift = 1,
+ .gbus_clock = txx9_gbus_clock,
+ .hold = hold,
+ .spw = spw,
+ .ch_mask = 1,
+ };
+ unsigned long baseaddr = TX4938_NDFMC_REG & 0xfffffffffULL;
+
+#ifdef __BIG_ENDIAN
+ baseaddr += 4;
+#endif
+ if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
+ (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_NDF_SEL)
+ txx9_ndfmc_init(baseaddr, &plat_data);
+}
+
+void __init tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1)
+{
+ struct txx9dmac_platform_data plat_data = {
+ .have_64bit_regs = true,
+ };
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
+ txx9_dmac_init(i, TX4938_DMA_REG(i) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4938_IR_DMA(i, 0),
+ &plat_data);
+ }
+}
+
+void __init tx4938_aclc_init(void)
+{
+ u64 pcfg = __raw_readq(&tx4938_ccfgptr->pcfg);
+
+ if ((pcfg & TX4938_PCFG_SEL2) &&
+ !(pcfg & TX4938_PCFG_ETH0_SEL))
+ txx9_aclc_init(TX4938_ACLC_REG & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4938_IR_ACLC,
+ 1, 0, 1);
+}
+
+void __init tx4938_sramc_init(void)
+{
+ if (tx4938_sram_resource.start)
+ txx9_sramc_init(&tx4938_sram_resource);
+}
+
+static void __init tx4938_stop_unused_modules(void)
+{
+ __u64 pcfg, rst = 0, ckd = 0;
+ char buf[128];
+
+ buf[0] = '\0';
+ local_irq_disable();
+ pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg);
+ switch (txx9_pcode) {
+ case 0x4937:
+ if (!(pcfg & TX4938_PCFG_SEL2)) {
+ rst |= TX4938_CLKCTR_ACLRST;
+ ckd |= TX4938_CLKCTR_ACLCKD;
+ strcat(buf, " ACLC");
+ }
+ break;
+ case 0x4938:
+ if (!(pcfg & TX4938_PCFG_SEL2) ||
+ (pcfg & TX4938_PCFG_ETH0_SEL)) {
+ rst |= TX4938_CLKCTR_ACLRST;
+ ckd |= TX4938_CLKCTR_ACLCKD;
+ strcat(buf, " ACLC");
+ }
+ if ((pcfg &
+ (TX4938_PCFG_ATA_SEL | TX4938_PCFG_ISA_SEL |
+ TX4938_PCFG_NDF_SEL))
+ != TX4938_PCFG_NDF_SEL) {
+ rst |= TX4938_CLKCTR_NDFRST;
+ ckd |= TX4938_CLKCTR_NDFCKD;
+ strcat(buf, " NDFMC");
+ }
+ if (!(pcfg & TX4938_PCFG_SPI_SEL)) {
+ rst |= TX4938_CLKCTR_SPIRST;
+ ckd |= TX4938_CLKCTR_SPICKD;
+ strcat(buf, " SPI");
+ }
+ break;
+ }
+ if (rst | ckd) {
+ txx9_set64(&tx4938_ccfgptr->clkctr, rst);
+ txx9_set64(&tx4938_ccfgptr->clkctr, ckd);
+ }
+ local_irq_enable();
+ if (buf[0])
+ pr_info("%s: stop%s\n", txx9_pcode_str, buf);
+}
+
+static int __init tx4938_late_init(void)
+{
+ if (txx9_pcode != 0x4937 && txx9_pcode != 0x4938)
+ return -ENODEV;
+ tx4938_stop_unused_modules();
+ return 0;
+}
+late_initcall(tx4938_late_init);
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
new file mode 100644
index 00000000..e9f95dcd
--- /dev/null
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -0,0 +1,583 @@
+/*
+ * TX4939 setup routines
+ * Based on linux/arch/mips/txx9/generic/setup_tx4938.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * 2003-2005 (c) MontaVista Software, Inc.
+ * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/notifier.h>
+#include <linux/sysdev.h>
+#include <linux/ethtool.h>
+#include <linux/param.h>
+#include <linux/ptrace.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/traps.h>
+#include <asm/txx9irq.h>
+#include <asm/txx9tmr.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
+#include <asm/txx9/tx4939.h>
+
+static void __init tx4939_wdr_init(void)
+{
+ /* report watchdog reset status */
+ if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST)
+ pr_warning("Watchdog reset detected at 0x%lx\n",
+ read_c0_errorepc());
+ /* clear WatchDogReset (W1C) */
+ tx4939_ccfg_set(TX4939_CCFG_WDRST);
+ /* do reset on watchdog */
+ tx4939_ccfg_set(TX4939_CCFG_WR);
+}
+
+void __init tx4939_wdt_init(void)
+{
+ txx9_wdt_init(TX4939_TMR_REG(2) & 0xfffffffffULL);
+}
+
+static void tx4939_machine_restart(char *command)
+{
+ local_irq_disable();
+ pr_emerg("Rebooting (with %s watchdog reset)...\n",
+ (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) ?
+ "external" : "internal");
+ /* clear watchdog status */
+ tx4939_ccfg_set(TX4939_CCFG_WDRST); /* W1C */
+ txx9_wdt_now(TX4939_TMR_REG(2) & 0xfffffffffULL);
+ while (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST))
+ ;
+ mdelay(10);
+ if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDREXEN) {
+ pr_emerg("Rebooting (with internal watchdog reset)...\n");
+ /* External WDRST failed. Do internal watchdog reset */
+ tx4939_ccfg_clear(TX4939_CCFG_WDREXEN);
+ }
+ /* fallback */
+ (*_machine_halt)();
+}
+
+void show_registers(struct pt_regs *regs);
+static int tx4939_be_handler(struct pt_regs *regs, int is_fixup)
+{
+ int data = regs->cp0_cause & 4;
+ console_verbose();
+ pr_err("%cBE exception at %#lx\n",
+ data ? 'D' : 'I', regs->cp0_epc);
+ pr_err("ccfg:%llx, toea:%llx\n",
+ (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg),
+ (unsigned long long)____raw_readq(&tx4939_ccfgptr->toea));
+#ifdef CONFIG_PCI
+ tx4927_report_pcic_status();
+#endif
+ show_registers(regs);
+ panic("BusError!");
+}
+static void __init tx4939_be_init(void)
+{
+ board_be_handler = tx4939_be_handler;
+}
+
+static struct resource tx4939_sdram_resource[4];
+static struct resource tx4939_sram_resource;
+#define TX4939_SRAM_SIZE 0x800
+
+void __init tx4939_add_memory_regions(void)
+{
+ int i;
+ unsigned long start, size;
+ u64 win;
+
+ for (i = 0; i < 4; i++) {
+ if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i)))
+ continue;
+ win = ____raw_readq(&tx4939_ddrcptr->win[i]);
+ start = (unsigned long)(win >> 48);
+ size = (((unsigned long)(win >> 32) & 0xffff) + 1) - start;
+ add_memory_region(start << 20, size << 20, BOOT_MEM_RAM);
+ }
+}
+
+void __init tx4939_setup(void)
+{
+ int i;
+ __u32 divmode;
+ __u64 pcfg;
+ unsigned int cpuclk = 0;
+
+ txx9_reg_res_init(TX4939_REV_PCODE(), TX4939_REG_BASE,
+ TX4939_REG_SIZE);
+ set_c0_config(TX49_CONF_CWFON);
+
+ /* SDRAMC,EBUSC are configured by PROM */
+ for (i = 0; i < 4; i++) {
+ if (!(TX4939_EBUSC_CR(i) & 0x8))
+ continue; /* disabled */
+ txx9_ce_res[i].start = (unsigned long)TX4939_EBUSC_BA(i);
+ txx9_ce_res[i].end =
+ txx9_ce_res[i].start + TX4939_EBUSC_SIZE(i) - 1;
+ request_resource(&iomem_resource, &txx9_ce_res[i]);
+ }
+
+ /* clocks */
+ if (txx9_master_clock) {
+ /* calculate cpu_clock from master_clock */
+ divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
+ TX4939_CCFG_MULCLK_MASK;
+ cpuclk = txx9_master_clock * 20 / 2;
+ switch (divmode) {
+ case TX4939_CCFG_MULCLK_8:
+ cpuclk = cpuclk / 3 * 4 /* / 6 * 8 */; break;
+ case TX4939_CCFG_MULCLK_9:
+ cpuclk = cpuclk / 2 * 3 /* / 6 * 9 */; break;
+ case TX4939_CCFG_MULCLK_10:
+ cpuclk = cpuclk / 3 * 5 /* / 6 * 10 */; break;
+ case TX4939_CCFG_MULCLK_11:
+ cpuclk = cpuclk / 6 * 11; break;
+ case TX4939_CCFG_MULCLK_12:
+ cpuclk = cpuclk * 2 /* / 6 * 12 */; break;
+ case TX4939_CCFG_MULCLK_13:
+ cpuclk = cpuclk / 6 * 13; break;
+ case TX4939_CCFG_MULCLK_14:
+ cpuclk = cpuclk / 3 * 7 /* / 6 * 14 */; break;
+ case TX4939_CCFG_MULCLK_15:
+ cpuclk = cpuclk / 2 * 5 /* / 6 * 15 */; break;
+ }
+ txx9_cpu_clock = cpuclk;
+ } else {
+ if (txx9_cpu_clock == 0)
+ txx9_cpu_clock = 400000000; /* 400MHz */
+ /* calculate master_clock from cpu_clock */
+ cpuclk = txx9_cpu_clock;
+ divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
+ TX4939_CCFG_MULCLK_MASK;
+ switch (divmode) {
+ case TX4939_CCFG_MULCLK_8:
+ txx9_master_clock = cpuclk * 6 / 8; break;
+ case TX4939_CCFG_MULCLK_9:
+ txx9_master_clock = cpuclk * 6 / 9; break;
+ case TX4939_CCFG_MULCLK_10:
+ txx9_master_clock = cpuclk * 6 / 10; break;
+ case TX4939_CCFG_MULCLK_11:
+ txx9_master_clock = cpuclk * 6 / 11; break;
+ case TX4939_CCFG_MULCLK_12:
+ txx9_master_clock = cpuclk * 6 / 12; break;
+ case TX4939_CCFG_MULCLK_13:
+ txx9_master_clock = cpuclk * 6 / 13; break;
+ case TX4939_CCFG_MULCLK_14:
+ txx9_master_clock = cpuclk * 6 / 14; break;
+ case TX4939_CCFG_MULCLK_15:
+ txx9_master_clock = cpuclk * 6 / 15; break;
+ }
+ txx9_master_clock /= 10; /* * 2 / 20 */
+ }
+ /* calculate gbus_clock from cpu_clock */
+ divmode = (__u32)____raw_readq(&tx4939_ccfgptr->ccfg) &
+ TX4939_CCFG_YDIVMODE_MASK;
+ txx9_gbus_clock = txx9_cpu_clock;
+ switch (divmode) {
+ case TX4939_CCFG_YDIVMODE_2:
+ txx9_gbus_clock /= 2; break;
+ case TX4939_CCFG_YDIVMODE_3:
+ txx9_gbus_clock /= 3; break;
+ case TX4939_CCFG_YDIVMODE_5:
+ txx9_gbus_clock /= 5; break;
+ case TX4939_CCFG_YDIVMODE_6:
+ txx9_gbus_clock /= 6; break;
+ }
+ /* change default value to udelay/mdelay take reasonable time */
+ loops_per_jiffy = txx9_cpu_clock / HZ / 2;
+
+ /* CCFG */
+ tx4939_wdr_init();
+ /* clear BusErrorOnWrite flag (W1C) */
+ tx4939_ccfg_set(TX4939_CCFG_WDRST | TX4939_CCFG_BEOW);
+ /* enable Timeout BusError */
+ if (txx9_ccfg_toeon)
+ tx4939_ccfg_set(TX4939_CCFG_TOE);
+
+ /* DMA selection */
+ txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_DMASEL_ALL);
+
+ /* Use external clock for external arbiter */
+ if (!(____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB))
+ txx9_clear64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_PCICLKEN_ALL);
+
+ pr_info("%s -- %dMHz(M%dMHz,G%dMHz) CRIR:%08x CCFG:%llx PCFG:%llx\n",
+ txx9_pcode_str,
+ (cpuclk + 500000) / 1000000,
+ (txx9_master_clock + 500000) / 1000000,
+ (txx9_gbus_clock + 500000) / 1000000,
+ (__u32)____raw_readq(&tx4939_ccfgptr->crir),
+ (unsigned long long)____raw_readq(&tx4939_ccfgptr->ccfg),
+ (unsigned long long)____raw_readq(&tx4939_ccfgptr->pcfg));
+
+ pr_info("%s DDRC -- EN:%08x", txx9_pcode_str,
+ (__u32)____raw_readq(&tx4939_ddrcptr->winen));
+ for (i = 0; i < 4; i++) {
+ __u64 win = ____raw_readq(&tx4939_ddrcptr->win[i]);
+ if (!((__u32)____raw_readq(&tx4939_ddrcptr->winen) & (1 << i)))
+ continue; /* disabled */
+ printk(KERN_CONT " #%d:%016llx", i, (unsigned long long)win);
+ tx4939_sdram_resource[i].name = "DDR SDRAM";
+ tx4939_sdram_resource[i].start =
+ (unsigned long)(win >> 48) << 20;
+ tx4939_sdram_resource[i].end =
+ ((((unsigned long)(win >> 32) & 0xffff) + 1) <<
+ 20) - 1;
+ tx4939_sdram_resource[i].flags = IORESOURCE_MEM;
+ request_resource(&iomem_resource, &tx4939_sdram_resource[i]);
+ }
+ printk(KERN_CONT "\n");
+
+ /* SRAM */
+ if (____raw_readq(&tx4939_sramcptr->cr) & 1) {
+ unsigned int size = TX4939_SRAM_SIZE;
+ tx4939_sram_resource.name = "SRAM";
+ tx4939_sram_resource.start =
+ (____raw_readq(&tx4939_sramcptr->cr) >> (39-11))
+ & ~(size - 1);
+ tx4939_sram_resource.end =
+ tx4939_sram_resource.start + TX4939_SRAM_SIZE - 1;
+ tx4939_sram_resource.flags = IORESOURCE_MEM;
+ request_resource(&iomem_resource, &tx4939_sram_resource);
+ }
+
+ /* TMR */
+ /* disable all timers */
+ for (i = 0; i < TX4939_NR_TMR; i++)
+ txx9_tmr_init(TX4939_TMR_REG(i) & 0xfffffffffULL);
+
+ /* set PCIC1 reset (required to prevent hangup on BIST) */
+ txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
+ pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
+ if (pcfg & (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE)) {
+ mdelay(1); /* at least 128 cpu clock */
+ /* clear PCIC1 reset */
+ txx9_clear64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
+ } else {
+ pr_info("%s: stop PCIC1\n", txx9_pcode_str);
+ /* stop PCIC1 */
+ txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1CKD);
+ }
+ if (!(pcfg & TX4939_PCFG_ET0MODE)) {
+ pr_info("%s: stop ETH0\n", txx9_pcode_str);
+ txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0RST);
+ txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH0CKD);
+ }
+ if (!(pcfg & TX4939_PCFG_ET1MODE)) {
+ pr_info("%s: stop ETH1\n", txx9_pcode_str);
+ txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1RST);
+ txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_ETH1CKD);
+ }
+
+ _machine_restart = tx4939_machine_restart;
+ board_be_init = tx4939_be_init;
+}
+
+void __init tx4939_time_init(unsigned int tmrnr)
+{
+ if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_TINTDIS)
+ txx9_clockevent_init(TX4939_TMR_REG(tmrnr) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4939_IR_TMR(tmrnr),
+ TXX9_IMCLK);
+}
+
+void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
+{
+ int i;
+ unsigned int ch_mask = 0;
+ __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
+
+ cts_mask |= ~1; /* only SIO0 have RTS/CTS */
+ if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO0)
+ cts_mask |= 1 << 0; /* disable SIO0 RTS/CTS by PCFG setting */
+ if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2)
+ ch_mask |= 1 << 2; /* disable SIO2 by PCFG setting */
+ if (pcfg & TX4939_PCFG_SIO3MODE)
+ ch_mask |= 1 << 3; /* disable SIO3 by PCFG setting */
+ for (i = 0; i < 4; i++) {
+ if ((1 << i) & ch_mask)
+ continue;
+ txx9_sio_init(TX4939_SIO_REG(i) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4939_IR_SIO(i),
+ i, sclk, (1 << i) & cts_mask);
+ }
+}
+
+#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
+static u32 tx4939_get_eth_speed(struct net_device *dev)
+{
+ struct ethtool_cmd cmd;
+ if (dev_ethtool_get_settings(dev, &cmd))
+ return 100; /* default 100Mbps */
+
+ return ethtool_cmd_speed(&cmd);
+}
+
+static int tx4939_netdev_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+ struct net_device *dev = ptr;
+ if (event == NETDEV_CHANGE && netif_carrier_ok(dev)) {
+ __u64 bit = 0;
+ if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(0))
+ bit = TX4939_PCFG_SPEED0;
+ else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1))
+ bit = TX4939_PCFG_SPEED1;
+ if (bit) {
+ if (tx4939_get_eth_speed(dev) == 100)
+ txx9_set64(&tx4939_ccfgptr->pcfg, bit);
+ else
+ txx9_clear64(&tx4939_ccfgptr->pcfg, bit);
+ }
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block tx4939_netdev_notifier = {
+ .notifier_call = tx4939_netdev_event,
+ .priority = 1,
+};
+
+void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
+{
+ u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
+
+ if (addr0 && (pcfg & TX4939_PCFG_ET0MODE))
+ txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(0), addr0);
+ if (addr1 && (pcfg & TX4939_PCFG_ET1MODE))
+ txx9_ethaddr_init(TXX9_IRQ_BASE + TX4939_IR_ETH(1), addr1);
+ register_netdevice_notifier(&tx4939_netdev_notifier);
+}
+#else
+void __init tx4939_ethaddr_init(unsigned char *addr0, unsigned char *addr1)
+{
+}
+#endif
+
+void __init tx4939_mtd_init(int ch)
+{
+ struct physmap_flash_data pdata = {
+ .width = TX4939_EBUSC_WIDTH(ch) / 8,
+ };
+ unsigned long start = txx9_ce_res[ch].start;
+ unsigned long size = txx9_ce_res[ch].end - start + 1;
+
+ if (!(TX4939_EBUSC_CR(ch) & 0x8))
+ return; /* disabled */
+ txx9_physmap_flash_init(ch, start, size, &pdata);
+}
+
+#define TX4939_ATA_REG_PHYS(ch) (TX4939_ATA_REG(ch) & 0xfffffffffULL)
+void __init tx4939_ata_init(void)
+{
+ static struct resource ata0_res[] = {
+ {
+ .start = TX4939_ATA_REG_PHYS(0),
+ .end = TX4939_ATA_REG_PHYS(0) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = TXX9_IRQ_BASE + TX4939_IR_ATA(0),
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ static struct resource ata1_res[] = {
+ {
+ .start = TX4939_ATA_REG_PHYS(1),
+ .end = TX4939_ATA_REG_PHYS(1) + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = TXX9_IRQ_BASE + TX4939_IR_ATA(1),
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ static struct platform_device ata0_dev = {
+ .name = "tx4939ide",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ata0_res),
+ .resource = ata0_res,
+ };
+ static struct platform_device ata1_dev = {
+ .name = "tx4939ide",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(ata1_res),
+ .resource = ata1_res,
+ };
+ __u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
+
+ if (pcfg & TX4939_PCFG_ATA0MODE)
+ platform_device_register(&ata0_dev);
+ if ((pcfg & (TX4939_PCFG_ATA1MODE |
+ TX4939_PCFG_ET1MODE |
+ TX4939_PCFG_ET0MODE)) == TX4939_PCFG_ATA1MODE)
+ platform_device_register(&ata1_dev);
+}
+
+void __init tx4939_rtc_init(void)
+{
+ static struct resource res[] = {
+ {
+ .start = TX4939_RTC_REG & 0xfffffffffULL,
+ .end = (TX4939_RTC_REG & 0xfffffffffULL) + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = TXX9_IRQ_BASE + TX4939_IR_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ static struct platform_device rtc_dev = {
+ .name = "tx4939rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(res),
+ .resource = res,
+ };
+
+ platform_device_register(&rtc_dev);
+}
+
+void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
+ unsigned char ch_mask, unsigned char wide_mask)
+{
+ struct txx9ndfmc_platform_data plat_data = {
+ .shift = 1,
+ .gbus_clock = txx9_gbus_clock,
+ .hold = hold,
+ .spw = spw,
+ .flags = NDFMC_PLAT_FLAG_NO_RSTR | NDFMC_PLAT_FLAG_HOLDADD |
+ NDFMC_PLAT_FLAG_DUMMYWRITE,
+ .ch_mask = ch_mask,
+ .wide_mask = wide_mask,
+ };
+ txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
+}
+
+void __init tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1)
+{
+ struct txx9dmac_platform_data plat_data = {
+ .have_64bit_regs = true,
+ };
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
+ txx9_dmac_init(i, TX4939_DMA_REG(i) & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4939_IR_DMA(i, 0),
+ &plat_data);
+ }
+}
+
+void __init tx4939_aclc_init(void)
+{
+ u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
+
+ if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_ACLC)
+ txx9_aclc_init(TX4939_ACLC_REG & 0xfffffffffULL,
+ TXX9_IRQ_BASE + TX4939_IR_ACLC, 1, 0, 1);
+}
+
+void __init tx4939_sramc_init(void)
+{
+ if (tx4939_sram_resource.start)
+ txx9_sramc_init(&tx4939_sram_resource);
+}
+
+void __init tx4939_rng_init(void)
+{
+ static struct resource res = {
+ .start = TX4939_RNG_REG & 0xfffffffffULL,
+ .end = (TX4939_RNG_REG & 0xfffffffffULL) + 0x30 - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ static struct platform_device pdev = {
+ .name = "tx4939-rng",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &res,
+ };
+
+ platform_device_register(&pdev);
+}
+
+static void __init tx4939_stop_unused_modules(void)
+{
+ __u64 pcfg, rst = 0, ckd = 0;
+ char buf[128];
+
+ buf[0] = '\0';
+ local_irq_disable();
+ pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
+ if ((pcfg & TX4939_PCFG_I2SMODE_MASK) !=
+ TX4939_PCFG_I2SMODE_ACLC) {
+ rst |= TX4939_CLKCTR_ACLRST;
+ ckd |= TX4939_CLKCTR_ACLCKD;
+ strcat(buf, " ACLC");
+ }
+ if ((pcfg & TX4939_PCFG_I2SMODE_MASK) !=
+ TX4939_PCFG_I2SMODE_I2S &&
+ (pcfg & TX4939_PCFG_I2SMODE_MASK) !=
+ TX4939_PCFG_I2SMODE_I2S_ALT) {
+ rst |= TX4939_CLKCTR_I2SRST;
+ ckd |= TX4939_CLKCTR_I2SCKD;
+ strcat(buf, " I2S");
+ }
+ if (!(pcfg & TX4939_PCFG_ATA0MODE)) {
+ rst |= TX4939_CLKCTR_ATA0RST;
+ ckd |= TX4939_CLKCTR_ATA0CKD;
+ strcat(buf, " ATA0");
+ }
+ if (!(pcfg & TX4939_PCFG_ATA1MODE)) {
+ rst |= TX4939_CLKCTR_ATA1RST;
+ ckd |= TX4939_CLKCTR_ATA1CKD;
+ strcat(buf, " ATA1");
+ }
+ if (pcfg & TX4939_PCFG_SPIMODE) {
+ rst |= TX4939_CLKCTR_SPIRST;
+ ckd |= TX4939_CLKCTR_SPICKD;
+ strcat(buf, " SPI");
+ }
+ if (!(pcfg & (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE))) {
+ rst |= TX4939_CLKCTR_VPCRST;
+ ckd |= TX4939_CLKCTR_VPCCKD;
+ strcat(buf, " VPC");
+ }
+ if ((pcfg & TX4939_PCFG_SIO2MODE_MASK) != TX4939_PCFG_SIO2MODE_SIO2) {
+ rst |= TX4939_CLKCTR_SIO2RST;
+ ckd |= TX4939_CLKCTR_SIO2CKD;
+ strcat(buf, " SIO2");
+ }
+ if (pcfg & TX4939_PCFG_SIO3MODE) {
+ rst |= TX4939_CLKCTR_SIO3RST;
+ ckd |= TX4939_CLKCTR_SIO3CKD;
+ strcat(buf, " SIO3");
+ }
+ if (rst | ckd) {
+ txx9_set64(&tx4939_ccfgptr->clkctr, rst);
+ txx9_set64(&tx4939_ccfgptr->clkctr, ckd);
+ }
+ local_irq_enable();
+ if (buf[0])
+ pr_info("%s: stop%s\n", txx9_pcode_str, buf);
+}
+
+static int __init tx4939_late_init(void)
+{
+ if (txx9_pcode != 0x4939)
+ return -ENODEV;
+ tx4939_stop_unused_modules();
+ return 0;
+}
+late_initcall(tx4939_late_init);
diff --git a/arch/mips/txx9/generic/smsc_fdc37m81x.c b/arch/mips/txx9/generic/smsc_fdc37m81x.c
new file mode 100644
index 00000000..8ebc3848
--- /dev/null
+++ b/arch/mips/txx9/generic/smsc_fdc37m81x.c
@@ -0,0 +1,172 @@
+/*
+ * Interface for smsc fdc48m81x Super IO chip
+ *
+ * Author: MontaVista Software, Inc. source@mvista.com
+ *
+ * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Copyright 2004 (c) MontaVista Software, Inc.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/txx9/smsc_fdc37m81x.h>
+
+/* Common Registers */
+#define SMSC_FDC37M81X_CONFIG_INDEX 0x00
+#define SMSC_FDC37M81X_CONFIG_DATA 0x01
+#define SMSC_FDC37M81X_CONF 0x02
+#define SMSC_FDC37M81X_INDEX 0x03
+#define SMSC_FDC37M81X_DNUM 0x07
+#define SMSC_FDC37M81X_DID 0x20
+#define SMSC_FDC37M81X_DREV 0x21
+#define SMSC_FDC37M81X_PCNT 0x22
+#define SMSC_FDC37M81X_PMGT 0x23
+#define SMSC_FDC37M81X_OSC 0x24
+#define SMSC_FDC37M81X_CONFPA0 0x26
+#define SMSC_FDC37M81X_CONFPA1 0x27
+#define SMSC_FDC37M81X_TEST4 0x2B
+#define SMSC_FDC37M81X_TEST5 0x2C
+#define SMSC_FDC37M81X_TEST1 0x2D
+#define SMSC_FDC37M81X_TEST2 0x2E
+#define SMSC_FDC37M81X_TEST3 0x2F
+
+/* Logical device numbers */
+#define SMSC_FDC37M81X_FDD 0x00
+#define SMSC_FDC37M81X_SERIAL1 0x04
+#define SMSC_FDC37M81X_SERIAL2 0x05
+#define SMSC_FDC37M81X_KBD 0x07
+
+/* Logical device Config Registers */
+#define SMSC_FDC37M81X_ACTIVE 0x30
+#define SMSC_FDC37M81X_BASEADDR0 0x60
+#define SMSC_FDC37M81X_BASEADDR1 0x61
+#define SMSC_FDC37M81X_INT 0x70
+#define SMSC_FDC37M81X_INT2 0x72
+#define SMSC_FDC37M81X_MODE 0xF0
+
+/* Chip Config Values */
+#define SMSC_FDC37M81X_CONFIG_ENTER 0x55
+#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa
+#define SMSC_FDC37M81X_CHIP_ID 0x4d
+
+static unsigned long g_smsc_fdc37m81x_base;
+
+static inline unsigned char smsc_fdc37m81x_rd(unsigned char index)
+{
+ outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+
+ return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
+}
+
+static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data)
+{
+ outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+ outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
+}
+
+void smsc_fdc37m81x_config_beg(void)
+{
+ if (g_smsc_fdc37m81x_base) {
+ outb(SMSC_FDC37M81X_CONFIG_ENTER,
+ g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+ }
+}
+
+void smsc_fdc37m81x_config_end(void)
+{
+ if (g_smsc_fdc37m81x_base)
+ outb(SMSC_FDC37M81X_CONFIG_EXIT,
+ g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+}
+
+u8 smsc_fdc37m81x_config_get(u8 reg)
+{
+ u8 val = 0;
+
+ if (g_smsc_fdc37m81x_base)
+ val = smsc_fdc37m81x_rd(reg);
+
+ return val;
+}
+
+void smsc_fdc37m81x_config_set(u8 reg, u8 val)
+{
+ if (g_smsc_fdc37m81x_base)
+ smsc_dc37m81x_wr(reg, val);
+}
+
+unsigned long __init smsc_fdc37m81x_init(unsigned long port)
+{
+ const int field = sizeof(unsigned long) * 2;
+ u8 chip_id;
+
+ if (g_smsc_fdc37m81x_base)
+ printk(KERN_WARNING "%s: stepping on old base=0x%0*lx\n",
+ __func__,
+ field, g_smsc_fdc37m81x_base);
+
+ g_smsc_fdc37m81x_base = port;
+
+ smsc_fdc37m81x_config_beg();
+
+ chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
+ if (chip_id == SMSC_FDC37M81X_CHIP_ID)
+ smsc_fdc37m81x_config_end();
+ else {
+ printk(KERN_WARNING "%s: unknown chip id 0x%02x\n", __func__,
+ chip_id);
+ g_smsc_fdc37m81x_base = 0;
+ }
+
+ return g_smsc_fdc37m81x_base;
+}
+
+#ifdef DEBUG
+static void smsc_fdc37m81x_config_dump_one(const char *key, u8 dev, u8 reg)
+{
+ printk(KERN_INFO "%s: dev=0x%02x reg=0x%02x val=0x%02x\n",
+ key, dev, reg,
+ smsc_fdc37m81x_rd(reg));
+}
+
+void smsc_fdc37m81x_config_dump(void)
+{
+ u8 orig;
+ const char *fname = __func__;
+
+ smsc_fdc37m81x_config_beg();
+
+ orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
+
+ printk(KERN_INFO "%s: common\n", fname);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+ SMSC_FDC37M81X_DNUM);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+ SMSC_FDC37M81X_DID);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+ SMSC_FDC37M81X_DREV);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+ SMSC_FDC37M81X_PCNT);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+ SMSC_FDC37M81X_PMGT);
+
+ printk(KERN_INFO "%s: keyboard\n", fname);
+ smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+ SMSC_FDC37M81X_ACTIVE);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+ SMSC_FDC37M81X_INT);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+ SMSC_FDC37M81X_INT2);
+ smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+ SMSC_FDC37M81X_LDCR_F0);
+
+ smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
+
+ smsc_fdc37m81x_config_end();
+}
+#endif
diff --git a/arch/mips/txx9/generic/spi_eeprom.c b/arch/mips/txx9/generic/spi_eeprom.c
new file mode 100644
index 00000000..103abc13
--- /dev/null
+++ b/arch/mips/txx9/generic/spi_eeprom.c
@@ -0,0 +1,104 @@
+/*
+ * spi_eeprom.c
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+#include <asm/txx9/spi.h>
+
+#define AT250X0_PAGE_SIZE 8
+
+/* register board information for at25 driver */
+int __init spi_eeprom_register(int busid, int chipid, int size)
+{
+ struct spi_board_info info = {
+ .modalias = "at25",
+ .max_speed_hz = 1500000, /* 1.5Mbps */
+ .bus_num = busid,
+ .chip_select = chipid,
+ /* Mode 0: High-Active, Sample-Then-Shift */
+ };
+ struct spi_eeprom *eeprom;
+ eeprom = kzalloc(sizeof(*eeprom), GFP_KERNEL);
+ if (!eeprom)
+ return -ENOMEM;
+ strcpy(eeprom->name, "at250x0");
+ eeprom->byte_len = size;
+ eeprom->page_size = AT250X0_PAGE_SIZE;
+ eeprom->flags = EE_ADDR1;
+ info.platform_data = eeprom;
+ return spi_register_board_info(&info, 1);
+}
+
+/* simple temporary spi driver to provide early access to seeprom. */
+
+static struct read_param {
+ int busid;
+ int chipid;
+ int address;
+ unsigned char *buf;
+ int len;
+} *read_param;
+
+static int __init early_seeprom_probe(struct spi_device *spi)
+{
+ int stat = 0;
+ u8 cmd[2];
+ int len = read_param->len;
+ char *buf = read_param->buf;
+ int address = read_param->address;
+
+ dev_info(&spi->dev, "spiclk %u KHz.\n",
+ (spi->max_speed_hz + 500) / 1000);
+ if (read_param->busid != spi->master->bus_num ||
+ read_param->chipid != spi->chip_select)
+ return -ENODEV;
+ while (len > 0) {
+ /* spi_write_then_read can only work with small chunk */
+ int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE;
+ cmd[0] = 0x03; /* AT25_READ */
+ cmd[1] = address;
+ stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c);
+ buf += c;
+ len -= c;
+ address += c;
+ }
+ return stat;
+}
+
+static struct spi_driver early_seeprom_driver __initdata = {
+ .driver = {
+ .name = "at25",
+ .owner = THIS_MODULE,
+ },
+ .probe = early_seeprom_probe,
+};
+
+int __init spi_eeprom_read(int busid, int chipid, int address,
+ unsigned char *buf, int len)
+{
+ int ret;
+ struct read_param param = {
+ .busid = busid,
+ .chipid = chipid,
+ .address = address,
+ .buf = buf,
+ .len = len
+ };
+
+ read_param = &param;
+ ret = spi_register_driver(&early_seeprom_driver);
+ if (!ret)
+ spi_unregister_driver(&early_seeprom_driver);
+ return ret;
+}
diff --git a/arch/mips/txx9/jmr3927/Makefile b/arch/mips/txx9/jmr3927/Makefile
new file mode 100644
index 00000000..9f5d5b62
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for TOSHIBA JMR-TX3927 board
+#
+
+obj-y += prom.o irq.o setup.o
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
new file mode 100644
index 00000000..c22c859a
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ahennessy@mvista.com
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/jmr3927.h>
+
+#if JMR3927_IRQ_END > NR_IRQS
+#error JMR3927_IRQ_END > NR_IRQS
+#endif
+
+/*
+ * CP0_STATUS is a thread's resource (saved/restored on context switch).
+ * So disable_irq/enable_irq MUST handle IOC/IRC registers.
+ */
+static void mask_irq_ioc(struct irq_data *d)
+{
+ /* 0: mask */
+ unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC;
+ unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
+ unsigned int bit = 1 << irq_nr;
+ jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR);
+ /* flush write buffer */
+ (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+static void unmask_irq_ioc(struct irq_data *d)
+{
+ /* 0: mask */
+ unsigned int irq_nr = d->irq - JMR3927_IRQ_IOC;
+ unsigned char imask = jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR);
+ unsigned int bit = 1 << irq_nr;
+ jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR);
+ /* flush write buffer */
+ (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR);
+}
+
+static int jmr3927_ioc_irqroute(void)
+{
+ unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);
+ int i;
+
+ for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) {
+ if (istat & (1 << i))
+ return JMR3927_IRQ_IOC + i;
+ }
+ return -1;
+}
+
+static int jmr3927_irq_dispatch(int pending)
+{
+ int irq;
+
+ if ((pending & CAUSEF_IP7) == 0)
+ return -1;
+ irq = (pending >> CAUSEB_IP2) & 0x0f;
+ irq += JMR3927_IRQ_IRC;
+ if (irq == JMR3927_IRQ_IOCINT)
+ irq = jmr3927_ioc_irqroute();
+ return irq;
+}
+
+static struct irq_chip jmr3927_irq_ioc = {
+ .name = "jmr3927_ioc",
+ .irq_mask = mask_irq_ioc,
+ .irq_unmask = unmask_irq_ioc,
+};
+
+void __init jmr3927_irq_setup(void)
+{
+ int i;
+
+ txx9_irq_dispatch = jmr3927_irq_dispatch;
+ /* Now, interrupt control disabled, */
+ /* all IRC interrupts are masked, */
+ /* all IRC interrupt mode are Low Active. */
+
+ /* mask all IOC interrupts */
+ jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR);
+ /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */
+ jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR);
+
+ /* clear PCI Soft interrupts */
+ jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR);
+ /* clear PCI Reset interrupts */
+ jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+
+ tx3927_irq_init();
+ for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++)
+ irq_set_chip_and_handler(i, &jmr3927_irq_ioc,
+ handle_level_irq);
+
+ /* setup IOC interrupt 1 (PCI, MODEM) */
+ irq_set_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq);
+}
diff --git a/arch/mips/txx9/jmr3927/prom.c b/arch/mips/txx9/jmr3927/prom.c
new file mode 100644
index 00000000..c899c0c0
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/prom.c
@@ -0,0 +1,52 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * PROM library initialisation code, assuming a version of
+ * pmon is the boot code.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ahennessy@mvista.com
+ *
+ * Based on arch/mips/au1000/common/prom.c
+ *
+ * This file was derived from Carsten Langgaard's
+ * arch/mips/mips-boards/xx files.
+ *
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/bootinfo.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/jmr3927.h>
+
+void __init jmr3927_prom_init(void)
+{
+ /* CCFG */
+ if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0)
+ printk(KERN_ERR "TX3927 TLB off\n");
+
+ add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM);
+ txx9_sio_putchar_init(TX3927_SIO_REG(1));
+}
diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c
new file mode 100644
index 00000000..3206f76f
--- /dev/null
+++ b/arch/mips/txx9/jmr3927/setup.c
@@ -0,0 +1,217 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * ahennessy@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <asm/reboot.h>
+#include <asm/txx9pio.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/jmr3927.h>
+#include <asm/mipsregs.h>
+
+static void jmr3927_machine_restart(char *command)
+{
+ local_irq_disable();
+#if 1 /* Resetting PCI bus */
+ jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+ jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR);
+ (void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR); /* flush WB */
+ mdelay(1);
+ jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+#endif
+ jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR);
+ /* fallback */
+ (*_machine_halt)();
+}
+
+static void __init jmr3927_time_init(void)
+{
+ tx3927_time_init(0, 1);
+}
+
+#define DO_WRITE_THROUGH
+
+static void jmr3927_board_init(void);
+
+static void __init jmr3927_mem_setup(void)
+{
+ set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO);
+
+ _machine_restart = jmr3927_machine_restart;
+
+ /* cache setup */
+ {
+ unsigned int conf;
+#ifdef DO_WRITE_THROUGH
+ int mips_config_cwfon = 0;
+ int mips_config_wbon = 0;
+#else
+ int mips_config_cwfon = 1;
+ int mips_config_wbon = 1;
+#endif
+
+ conf = read_c0_conf();
+ conf &= ~(TX39_CONF_WBON | TX39_CONF_CWFON);
+ conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
+ conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;
+
+ write_c0_conf(conf);
+ write_c0_cache(0);
+ }
+
+ /* initialize board */
+ jmr3927_board_init();
+
+ tx3927_sio_init(0, 1 << 1); /* ch1: noCTS */
+}
+
+static void __init jmr3927_pci_setup(void)
+{
+#ifdef CONFIG_PCI
+ int extarb = !(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB);
+ struct pci_controller *c;
+
+ c = txx9_alloc_pci_controller(&txx9_primary_pcic,
+ JMR3927_PCIMEM, JMR3927_PCIMEM_SIZE,
+ JMR3927_PCIIO, JMR3927_PCIIO_SIZE);
+ register_pci_controller(c);
+ if (!extarb) {
+ /* Reset PCI Bus */
+ jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+ udelay(100);
+ jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI,
+ JMR3927_IOC_RESET_ADDR);
+ udelay(100);
+ jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR);
+ }
+ tx3927_pcic_setup(c, JMR3927_SDRAM_SIZE, extarb);
+ tx3927_setup_pcierr_irq();
+#endif /* CONFIG_PCI */
+}
+
+static void __init jmr3927_board_init(void)
+{
+ txx9_cpu_clock = JMR3927_CORECLK;
+ /* SDRAMC are configured by PROM */
+
+ /* ROMC */
+ tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048;
+ tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8;
+ tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698;
+ tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218;
+
+ /* Pin selection */
+ tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL;
+ tx3927_ccfgptr->pcfg |=
+ TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL |
+ (TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1));
+
+ tx3927_setup();
+
+ /* PIO[15:12] connected to LEDs */
+ __raw_writel(0x0000f000, &tx3927_pioptr->dir);
+ gpio_request(11, "dipsw1");
+ gpio_request(10, "dipsw2");
+
+ jmr3927_pci_setup();
+
+ /* SIO0 DTR on */
+ jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR);
+
+ jmr3927_led_set(0);
+
+ printk(KERN_INFO
+ "JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n",
+ jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK,
+ jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK,
+ jmr3927_dipsw1(), jmr3927_dipsw2(),
+ jmr3927_dipsw3(), jmr3927_dipsw4());
+}
+
+/* This trick makes rtc-ds1742 driver usable as is. */
+static unsigned long jmr3927_swizzle_addr_b(unsigned long port)
+{
+ if ((port & 0xffff0000) != JMR3927_IOC_NVRAMB_ADDR)
+ return port;
+ port = (port & 0xffff0000) | (port & 0x7fff << 1);
+#ifdef __BIG_ENDIAN
+ return port;
+#else
+ return port | 1;
+#endif
+}
+
+static void __init jmr3927_rtc_init(void)
+{
+ static struct resource __initdata res = {
+ .start = JMR3927_IOC_NVRAMB_ADDR - IO_BASE,
+ .end = JMR3927_IOC_NVRAMB_ADDR - IO_BASE + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ platform_device_register_simple("rtc-ds1742", -1, &res, 1);
+}
+
+static void __init jmr3927_mtd_init(void)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ tx3927_mtd_init(i);
+}
+
+static void __init jmr3927_device_init(void)
+{
+ unsigned long iocled_base = JMR3927_IOC_LED_ADDR - IO_BASE;
+#ifdef __LITTLE_ENDIAN
+ iocled_base |= 1;
+#endif
+ __swizzle_addr_b = jmr3927_swizzle_addr_b;
+ jmr3927_rtc_init();
+ tx3927_wdt_init();
+ jmr3927_mtd_init();
+ txx9_iocled_init(iocled_base, -1, 8, 1, "green", NULL);
+}
+
+struct txx9_board_vec jmr3927_vec __initdata = {
+ .system = "Toshiba JMR_TX3927",
+ .prom_init = jmr3927_prom_init,
+ .mem_setup = jmr3927_mem_setup,
+ .irq_setup = jmr3927_irq_setup,
+ .time_init = jmr3927_time_init,
+ .device_init = jmr3927_device_init,
+#ifdef CONFIG_PCI
+ .pci_map_irq = jmr3927_pci_map_irq,
+#endif
+};
diff --git a/arch/mips/txx9/rbtx4927/Makefile b/arch/mips/txx9/rbtx4927/Makefile
new file mode 100644
index 00000000..60b24c8f
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/Makefile
@@ -0,0 +1 @@
+obj-y += prom.o setup.o irq.o
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c
new file mode 100644
index 00000000..6c22c496
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -0,0 +1,198 @@
+/*
+ * Toshiba RBTX4927 specific interrupt handlers
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * I8259A_IRQ_BASE+00
+ * I8259A_IRQ_BASE+01 PS2/Keyboard
+ * I8259A_IRQ_BASE+02 Cascade RBTX4927-ISA (irqs 8-15)
+ * I8259A_IRQ_BASE+03
+ * I8259A_IRQ_BASE+04
+ * I8259A_IRQ_BASE+05
+ * I8259A_IRQ_BASE+06
+ * I8259A_IRQ_BASE+07
+ * I8259A_IRQ_BASE+08
+ * I8259A_IRQ_BASE+09
+ * I8259A_IRQ_BASE+10
+ * I8259A_IRQ_BASE+11
+ * I8259A_IRQ_BASE+12 PS2/Mouse (not supported at this time)
+ * I8259A_IRQ_BASE+13
+ * I8259A_IRQ_BASE+14 IDE
+ * I8259A_IRQ_BASE+15
+ *
+ * MIPS_CPU_IRQ_BASE+00 Software 0
+ * MIPS_CPU_IRQ_BASE+01 Software 1
+ * MIPS_CPU_IRQ_BASE+02 Cascade TX4927-CP0
+ * MIPS_CPU_IRQ_BASE+03 Multiplexed -- do not use
+ * MIPS_CPU_IRQ_BASE+04 Multiplexed -- do not use
+ * MIPS_CPU_IRQ_BASE+05 Multiplexed -- do not use
+ * MIPS_CPU_IRQ_BASE+06 Multiplexed -- do not use
+ * MIPS_CPU_IRQ_BASE+07 CPU TIMER
+ *
+ * TXX9_IRQ_BASE+00
+ * TXX9_IRQ_BASE+01
+ * TXX9_IRQ_BASE+02
+ * TXX9_IRQ_BASE+03 Cascade RBTX4927-IOC
+ * TXX9_IRQ_BASE+04
+ * TXX9_IRQ_BASE+05 RBTX4927 RTL-8019AS ethernet
+ * TXX9_IRQ_BASE+06
+ * TXX9_IRQ_BASE+07
+ * TXX9_IRQ_BASE+08 TX4927 SerialIO Channel 0
+ * TXX9_IRQ_BASE+09 TX4927 SerialIO Channel 1
+ * TXX9_IRQ_BASE+10
+ * TXX9_IRQ_BASE+11
+ * TXX9_IRQ_BASE+12
+ * TXX9_IRQ_BASE+13
+ * TXX9_IRQ_BASE+14
+ * TXX9_IRQ_BASE+15
+ * TXX9_IRQ_BASE+16 TX4927 PCI PCI-C
+ * TXX9_IRQ_BASE+17
+ * TXX9_IRQ_BASE+18
+ * TXX9_IRQ_BASE+19
+ * TXX9_IRQ_BASE+20
+ * TXX9_IRQ_BASE+21
+ * TXX9_IRQ_BASE+22 TX4927 PCI PCI-ERR
+ * TXX9_IRQ_BASE+23 TX4927 PCI PCI-PMA (not used)
+ * TXX9_IRQ_BASE+24
+ * TXX9_IRQ_BASE+25
+ * TXX9_IRQ_BASE+26
+ * TXX9_IRQ_BASE+27
+ * TXX9_IRQ_BASE+28
+ * TXX9_IRQ_BASE+29
+ * TXX9_IRQ_BASE+30
+ * TXX9_IRQ_BASE+31
+ *
+ * RBTX4927_IRQ_IOC+00 FPCIB0 PCI-D (SouthBridge)
+ * RBTX4927_IRQ_IOC+01 FPCIB0 PCI-C (SouthBridge)
+ * RBTX4927_IRQ_IOC+02 FPCIB0 PCI-B (SouthBridge/IDE/pin=1,INTR)
+ * RBTX4927_IRQ_IOC+03 FPCIB0 PCI-A (SouthBridge/USB/pin=4)
+ * RBTX4927_IRQ_IOC+04
+ * RBTX4927_IRQ_IOC+05
+ * RBTX4927_IRQ_IOC+06
+ * RBTX4927_IRQ_IOC+07
+ *
+ * NOTES:
+ * SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58
+ * SouthBridge/ISA/pin=0 no pci irq used by this device
+ * SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR
+ * via ISA IRQ14
+ * SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59
+ * SouthBridge/PMC/pin=0 no pci irq used by this device
+ * SuperIO/PS2/Keyboard, using INTR via ISA IRQ1
+ * SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported)
+ * JP7 is not bus master -- do NOT use -- only 4 pci bus master's
+ * allowed -- SouthBridge, JP4, JP5, JP6
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/rbtx4927.h>
+
+static int toshiba_rbtx4927_irq_nested(int sw_irq)
+{
+ u8 level3;
+
+ level3 = readb(rbtx4927_imstat_addr) & 0x1f;
+ if (unlikely(!level3))
+ return -1;
+ return RBTX4927_IRQ_IOC + __fls8(level3);
+}
+
+static void toshiba_rbtx4927_irq_ioc_enable(struct irq_data *d)
+{
+ unsigned char v;
+
+ v = readb(rbtx4927_imask_addr);
+ v |= (1 << (d->irq - RBTX4927_IRQ_IOC));
+ writeb(v, rbtx4927_imask_addr);
+}
+
+static void toshiba_rbtx4927_irq_ioc_disable(struct irq_data *d)
+{
+ unsigned char v;
+
+ v = readb(rbtx4927_imask_addr);
+ v &= ~(1 << (d->irq - RBTX4927_IRQ_IOC));
+ writeb(v, rbtx4927_imask_addr);
+ mmiowb();
+}
+
+#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC"
+static struct irq_chip toshiba_rbtx4927_irq_ioc_type = {
+ .name = TOSHIBA_RBTX4927_IOC_NAME,
+ .irq_mask = toshiba_rbtx4927_irq_ioc_disable,
+ .irq_unmask = toshiba_rbtx4927_irq_ioc_enable,
+};
+
+static void __init toshiba_rbtx4927_irq_ioc_init(void)
+{
+ int i;
+
+ /* mask all IOC interrupts */
+ writeb(0, rbtx4927_imask_addr);
+ /* clear SoftInt interrupts */
+ writeb(0, rbtx4927_softint_addr);
+
+ for (i = RBTX4927_IRQ_IOC;
+ i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++)
+ irq_set_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type,
+ handle_level_irq);
+ irq_set_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
+}
+
+static int rbtx4927_irq_dispatch(int pending)
+{
+ int irq;
+
+ if (pending & STATUSF_IP7) /* cpu timer */
+ irq = MIPS_CPU_IRQ_BASE + 7;
+ else if (pending & STATUSF_IP2) { /* tx4927 pic */
+ irq = txx9_irq();
+ if (irq == RBTX4927_IRQ_IOCINT)
+ irq = toshiba_rbtx4927_irq_nested(irq);
+ } else if (pending & STATUSF_IP0) /* user line 0 */
+ irq = MIPS_CPU_IRQ_BASE + 0;
+ else if (pending & STATUSF_IP1) /* user line 1 */
+ irq = MIPS_CPU_IRQ_BASE + 1;
+ else
+ irq = -1;
+ return irq;
+}
+
+void __init rbtx4927_irq_setup(void)
+{
+ txx9_irq_dispatch = rbtx4927_irq_dispatch;
+ tx4927_irq_init();
+ toshiba_rbtx4927_irq_ioc_init();
+ /* Onboard 10M Ether: High Active */
+ irq_set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH);
+}
diff --git a/arch/mips/txx9/rbtx4927/prom.c b/arch/mips/txx9/rbtx4927/prom.c
new file mode 100644
index 00000000..cc97c6a6
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/prom.c
@@ -0,0 +1,41 @@
+/*
+ * rbtx4927 specific prom routines
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/rbtx4927.h>
+
+void __init rbtx4927_prom_init(void)
+{
+ add_memory_region(0, tx4927_get_mem_size(), BOOT_MEM_RAM);
+ txx9_sio_putchar_init(TX4927_SIO_REG(0) & 0xfffffffffULL);
+}
diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c
new file mode 100644
index 00000000..b15adfc2
--- /dev/null
+++ b/arch/mips/txx9/rbtx4927/setup.c
@@ -0,0 +1,368 @@
+/*
+ * Toshiba rbtx4927 specific setup
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * Copyright (C) 1996, 97, 2001, 04 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: Michael Pruznick, michael_pruznick@mvista.com
+ *
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * Copyright (C) 2004 MontaVista Software Inc.
+ * Author: Manish Lachwani, mlachwani@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/rbtx4927.h>
+#include <asm/txx9/tx4938.h> /* for TX4937 */
+
+#ifdef CONFIG_PCI
+static void __init tx4927_pci_setup(void)
+{
+ int extarb = !(__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB);
+ struct pci_controller *c = &txx9_primary_pcic;
+
+ register_pci_controller(c);
+
+ if (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66)
+ txx9_pci_option =
+ (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
+ TXX9_PCI_OPT_CLK_66; /* already configured */
+
+ /* Reset PCI Bus */
+ writeb(1, rbtx4927_pcireset_addr);
+ /* Reset PCIC */
+ txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
+ if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
+ TXX9_PCI_OPT_CLK_66)
+ tx4927_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
+ writeb(0, rbtx4927_pcireset_addr);
+ iob();
+
+ tx4927_report_pciclk();
+ tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
+ if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
+ TXX9_PCI_OPT_CLK_AUTO &&
+ txx9_pci66_check(c, 0, 0)) {
+ /* Reset PCI Bus */
+ writeb(1, rbtx4927_pcireset_addr);
+ /* Reset PCIC */
+ txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
+ tx4927_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
+ writeb(0, rbtx4927_pcireset_addr);
+ iob();
+ /* Reinitialize PCIC */
+ tx4927_report_pciclk();
+ tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
+ }
+ tx4927_setup_pcierr_irq();
+}
+
+static void __init tx4937_pci_setup(void)
+{
+ int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB);
+ struct pci_controller *c = &txx9_primary_pcic;
+
+ register_pci_controller(c);
+
+ if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66)
+ txx9_pci_option =
+ (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
+ TXX9_PCI_OPT_CLK_66; /* already configured */
+
+ /* Reset PCI Bus */
+ writeb(1, rbtx4927_pcireset_addr);
+ /* Reset PCIC */
+ txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
+ if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
+ TXX9_PCI_OPT_CLK_66)
+ tx4938_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
+ writeb(0, rbtx4927_pcireset_addr);
+ iob();
+
+ tx4938_report_pciclk();
+ tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
+ if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
+ TXX9_PCI_OPT_CLK_AUTO &&
+ txx9_pci66_check(c, 0, 0)) {
+ /* Reset PCI Bus */
+ writeb(1, rbtx4927_pcireset_addr);
+ /* Reset PCIC */
+ txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
+ tx4938_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
+ writeb(0, rbtx4927_pcireset_addr);
+ iob();
+ /* Reinitialize PCIC */
+ tx4938_report_pciclk();
+ tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
+ }
+ tx4938_setup_pcierr_irq();
+}
+
+static void __init rbtx4927_arch_init(void)
+{
+ tx4927_pci_setup();
+}
+
+static void __init rbtx4937_arch_init(void)
+{
+ tx4937_pci_setup();
+}
+#else
+#define rbtx4927_arch_init NULL
+#define rbtx4937_arch_init NULL
+#endif /* CONFIG_PCI */
+
+static void toshiba_rbtx4927_restart(char *command)
+{
+ /* enable the s/w reset register */
+ writeb(1, rbtx4927_softresetlock_addr);
+
+ /* wait for enable to be seen */
+ while (!(readb(rbtx4927_softresetlock_addr) & 1))
+ ;
+
+ /* do a s/w reset */
+ writeb(1, rbtx4927_softreset_addr);
+
+ /* fallback */
+ (*_machine_halt)();
+}
+
+static void __init rbtx4927_clock_init(void);
+static void __init rbtx4937_clock_init(void);
+
+static void __init rbtx4927_mem_setup(void)
+{
+ if (TX4927_REV_PCODE() == 0x4927) {
+ rbtx4927_clock_init();
+ tx4927_setup();
+ } else {
+ rbtx4937_clock_init();
+ tx4938_setup();
+ }
+
+ _machine_restart = toshiba_rbtx4927_restart;
+
+#ifdef CONFIG_PCI
+ txx9_alloc_pci_controller(&txx9_primary_pcic,
+ RBTX4927_PCIMEM, RBTX4927_PCIMEM_SIZE,
+ RBTX4927_PCIIO, RBTX4927_PCIIO_SIZE);
+ txx9_board_pcibios_setup = tx4927_pcibios_setup;
+#else
+ set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET);
+#endif
+
+ /* TX4927-SIO DTR on (PIO[15]) */
+ gpio_request(15, "sio-dtr");
+ gpio_direction_output(15, 1);
+
+ tx4927_sio_init(0, 0);
+}
+
+static void __init rbtx4927_clock_init(void)
+{
+ /*
+ * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
+ *
+ * For TX4927:
+ * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1).
+ * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5)
+ * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3)
+ * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5)
+ * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6)
+ * i.e. S9[3]: ON (83MHz), OFF (100MHz)
+ */
+ switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) &
+ TX4927_CCFG_PCIDIVMODE_MASK) {
+ case TX4927_CCFG_PCIDIVMODE_2_5:
+ case TX4927_CCFG_PCIDIVMODE_5:
+ txx9_cpu_clock = 166666666; /* 166MHz */
+ break;
+ default:
+ txx9_cpu_clock = 200000000; /* 200MHz */
+ }
+}
+
+static void __init rbtx4937_clock_init(void)
+{
+ /*
+ * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
+ *
+ * For TX4937:
+ * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1)
+ * PCIDIVMODE[10] is 0.
+ * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8)
+ * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4)
+ * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9)
+ * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5)
+ * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10)
+ * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5)
+ */
+ switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) &
+ TX4938_CCFG_PCIDIVMODE_MASK) {
+ case TX4938_CCFG_PCIDIVMODE_8:
+ case TX4938_CCFG_PCIDIVMODE_4:
+ txx9_cpu_clock = 266666666; /* 266MHz */
+ break;
+ case TX4938_CCFG_PCIDIVMODE_9:
+ case TX4938_CCFG_PCIDIVMODE_4_5:
+ txx9_cpu_clock = 300000000; /* 300MHz */
+ break;
+ default:
+ txx9_cpu_clock = 333333333; /* 333MHz */
+ }
+}
+
+static void __init rbtx4927_time_init(void)
+{
+ tx4927_time_init(0);
+}
+
+static void __init toshiba_rbtx4927_rtc_init(void)
+{
+ struct resource res = {
+ .start = RBTX4927_BRAMRTC_BASE - IO_BASE,
+ .end = RBTX4927_BRAMRTC_BASE - IO_BASE + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ platform_device_register_simple("rtc-ds1742", -1, &res, 1);
+}
+
+static void __init rbtx4927_ne_init(void)
+{
+ struct resource res[] = {
+ {
+ .start = RBTX4927_RTL_8019_BASE,
+ .end = RBTX4927_RTL_8019_BASE + 0x20 - 1,
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = RBTX4927_RTL_8019_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+ platform_device_register_simple("ne", -1, res, ARRAY_SIZE(res));
+}
+
+static void __init rbtx4927_mtd_init(void)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ tx4927_mtd_init(i);
+}
+
+static void __init rbtx4927_gpioled_init(void)
+{
+ static struct gpio_led leds[] = {
+ { .name = "gpioled:green:0", .gpio = 0, .active_low = 1, },
+ { .name = "gpioled:green:1", .gpio = 1, .active_low = 1, },
+ };
+ static struct gpio_led_platform_data pdata = {
+ .num_leds = ARRAY_SIZE(leds),
+ .leds = leds,
+ };
+ struct platform_device *pdev = platform_device_alloc("leds-gpio", 0);
+
+ if (!pdev)
+ return;
+ pdev->dev.platform_data = &pdata;
+ if (platform_device_add(pdev))
+ platform_device_put(pdev);
+}
+
+static void __init rbtx4927_device_init(void)
+{
+ toshiba_rbtx4927_rtc_init();
+ rbtx4927_ne_init();
+ tx4927_wdt_init();
+ rbtx4927_mtd_init();
+ if (TX4927_REV_PCODE() == 0x4927) {
+ tx4927_dmac_init(2);
+ tx4927_aclc_init(0, 1);
+ } else {
+ tx4938_dmac_init(0, 2);
+ tx4938_aclc_init();
+ }
+ platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
+ txx9_iocled_init(RBTX4927_LED_ADDR - IO_BASE, -1, 3, 1, "green", NULL);
+ rbtx4927_gpioled_init();
+}
+
+struct txx9_board_vec rbtx4927_vec __initdata = {
+ .system = "Toshiba RBTX4927",
+ .prom_init = rbtx4927_prom_init,
+ .mem_setup = rbtx4927_mem_setup,
+ .irq_setup = rbtx4927_irq_setup,
+ .time_init = rbtx4927_time_init,
+ .device_init = rbtx4927_device_init,
+ .arch_init = rbtx4927_arch_init,
+#ifdef CONFIG_PCI
+ .pci_map_irq = rbtx4927_pci_map_irq,
+#endif
+};
+struct txx9_board_vec rbtx4937_vec __initdata = {
+ .system = "Toshiba RBTX4937",
+ .prom_init = rbtx4927_prom_init,
+ .mem_setup = rbtx4927_mem_setup,
+ .irq_setup = rbtx4927_irq_setup,
+ .time_init = rbtx4927_time_init,
+ .device_init = rbtx4927_device_init,
+ .arch_init = rbtx4937_arch_init,
+#ifdef CONFIG_PCI
+ .pci_map_irq = rbtx4927_pci_map_irq,
+#endif
+};
diff --git a/arch/mips/txx9/rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile
new file mode 100644
index 00000000..60b24c8f
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/Makefile
@@ -0,0 +1 @@
+obj-y += prom.o setup.o irq.o
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c
new file mode 100644
index 00000000..58cd7a92
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -0,0 +1,157 @@
+/*
+ * Toshiba RBTX4938 specific interrupt handlers
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+/*
+ * MIPS_CPU_IRQ_BASE+00 Software 0
+ * MIPS_CPU_IRQ_BASE+01 Software 1
+ * MIPS_CPU_IRQ_BASE+02 Cascade TX4938-CP0
+ * MIPS_CPU_IRQ_BASE+03 Multiplexed -- do not use
+ * MIPS_CPU_IRQ_BASE+04 Multiplexed -- do not use
+ * MIPS_CPU_IRQ_BASE+05 Multiplexed -- do not use
+ * MIPS_CPU_IRQ_BASE+06 Multiplexed -- do not use
+ * MIPS_CPU_IRQ_BASE+07 CPU TIMER
+ *
+ * TXX9_IRQ_BASE+00
+ * TXX9_IRQ_BASE+01
+ * TXX9_IRQ_BASE+02 Cascade RBTX4938-IOC
+ * TXX9_IRQ_BASE+03 RBTX4938 RTL-8019AS Ethernet
+ * TXX9_IRQ_BASE+04
+ * TXX9_IRQ_BASE+05 TX4938 ETH1
+ * TXX9_IRQ_BASE+06 TX4938 ETH0
+ * TXX9_IRQ_BASE+07
+ * TXX9_IRQ_BASE+08 TX4938 SIO 0
+ * TXX9_IRQ_BASE+09 TX4938 SIO 1
+ * TXX9_IRQ_BASE+10 TX4938 DMA0
+ * TXX9_IRQ_BASE+11 TX4938 DMA1
+ * TXX9_IRQ_BASE+12 TX4938 DMA2
+ * TXX9_IRQ_BASE+13 TX4938 DMA3
+ * TXX9_IRQ_BASE+14
+ * TXX9_IRQ_BASE+15
+ * TXX9_IRQ_BASE+16 TX4938 PCIC
+ * TXX9_IRQ_BASE+17 TX4938 TMR0
+ * TXX9_IRQ_BASE+18 TX4938 TMR1
+ * TXX9_IRQ_BASE+19 TX4938 TMR2
+ * TXX9_IRQ_BASE+20
+ * TXX9_IRQ_BASE+21
+ * TXX9_IRQ_BASE+22 TX4938 PCIERR
+ * TXX9_IRQ_BASE+23
+ * TXX9_IRQ_BASE+24
+ * TXX9_IRQ_BASE+25
+ * TXX9_IRQ_BASE+26
+ * TXX9_IRQ_BASE+27
+ * TXX9_IRQ_BASE+28
+ * TXX9_IRQ_BASE+29
+ * TXX9_IRQ_BASE+30
+ * TXX9_IRQ_BASE+31 TX4938 SPI
+ *
+ * RBTX4938_IRQ_IOC+00 PCI-D
+ * RBTX4938_IRQ_IOC+01 PCI-C
+ * RBTX4938_IRQ_IOC+02 PCI-B
+ * RBTX4938_IRQ_IOC+03 PCI-A
+ * RBTX4938_IRQ_IOC+04 RTC
+ * RBTX4938_IRQ_IOC+05 ATA
+ * RBTX4938_IRQ_IOC+06 MODEM
+ * RBTX4938_IRQ_IOC+07 SWINT
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/rbtx4938.h>
+
+static int toshiba_rbtx4938_irq_nested(int sw_irq)
+{
+ u8 level3;
+
+ level3 = readb(rbtx4938_imstat_addr);
+ if (unlikely(!level3))
+ return -1;
+ /* must use fls so onboard ATA has priority */
+ return RBTX4938_IRQ_IOC + __fls8(level3);
+}
+
+static void toshiba_rbtx4938_irq_ioc_enable(struct irq_data *d)
+{
+ unsigned char v;
+
+ v = readb(rbtx4938_imask_addr);
+ v |= (1 << (d->irq - RBTX4938_IRQ_IOC));
+ writeb(v, rbtx4938_imask_addr);
+ mmiowb();
+}
+
+static void toshiba_rbtx4938_irq_ioc_disable(struct irq_data *d)
+{
+ unsigned char v;
+
+ v = readb(rbtx4938_imask_addr);
+ v &= ~(1 << (d->irq - RBTX4938_IRQ_IOC));
+ writeb(v, rbtx4938_imask_addr);
+ mmiowb();
+}
+
+#define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC"
+static struct irq_chip toshiba_rbtx4938_irq_ioc_type = {
+ .name = TOSHIBA_RBTX4938_IOC_NAME,
+ .irq_mask = toshiba_rbtx4938_irq_ioc_disable,
+ .irq_unmask = toshiba_rbtx4938_irq_ioc_enable,
+};
+
+static int rbtx4938_irq_dispatch(int pending)
+{
+ int irq;
+
+ if (pending & STATUSF_IP7)
+ irq = MIPS_CPU_IRQ_BASE + 7;
+ else if (pending & STATUSF_IP2) {
+ irq = txx9_irq();
+ if (irq == RBTX4938_IRQ_IOCINT)
+ irq = toshiba_rbtx4938_irq_nested(irq);
+ } else if (pending & STATUSF_IP1)
+ irq = MIPS_CPU_IRQ_BASE + 0;
+ else if (pending & STATUSF_IP0)
+ irq = MIPS_CPU_IRQ_BASE + 1;
+ else
+ irq = -1;
+ return irq;
+}
+
+static void __init toshiba_rbtx4938_irq_ioc_init(void)
+{
+ int i;
+
+ for (i = RBTX4938_IRQ_IOC;
+ i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++)
+ irq_set_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
+ handle_level_irq);
+
+ irq_set_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq);
+}
+
+void __init rbtx4938_irq_setup(void)
+{
+ txx9_irq_dispatch = rbtx4938_irq_dispatch;
+ /* Now, interrupt control disabled, */
+ /* all IRC interrupts are masked, */
+ /* all IRC interrupt mode are Low Active. */
+
+ /* mask all IOC interrupts */
+ writeb(0, rbtx4938_imask_addr);
+
+ /* clear SoftInt interrupts */
+ writeb(0, rbtx4938_softint_addr);
+ tx4938_irq_init();
+ toshiba_rbtx4938_irq_ioc_init();
+ /* Onboard 10M Ether: High Active */
+ irq_set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
+}
diff --git a/arch/mips/txx9/rbtx4938/prom.c b/arch/mips/txx9/rbtx4938/prom.c
new file mode 100644
index 00000000..bcb46924
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/prom.c
@@ -0,0 +1,23 @@
+/*
+ * rbtx4938 specific prom routines
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <asm/bootinfo.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/rbtx4938.h>
+
+void __init rbtx4938_prom_init(void)
+{
+ add_memory_region(0, tx4938_get_mem_size(), BOOT_MEM_RAM);
+ txx9_sio_putchar_init(TX4938_SIO_REG(0) & 0xfffffffffULL);
+}
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
new file mode 100644
index 00000000..d6e70dab
--- /dev/null
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -0,0 +1,370 @@
+/*
+ * Setup pointers to hardware-dependent routines.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ *
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/reboot.h>
+#include <asm/io.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/rbtx4938.h>
+#include <linux/spi/spi.h>
+#include <asm/txx9/spi.h>
+#include <asm/txx9pio.h>
+
+static void rbtx4938_machine_restart(char *command)
+{
+ local_irq_disable();
+ writeb(1, rbtx4938_softresetlock_addr);
+ writeb(1, rbtx4938_sfvol_addr);
+ writeb(1, rbtx4938_softreset_addr);
+ /* fallback */
+ (*_machine_halt)();
+}
+
+static void __init rbtx4938_pci_setup(void)
+{
+#ifdef CONFIG_PCI
+ int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB);
+ struct pci_controller *c = &txx9_primary_pcic;
+
+ register_pci_controller(c);
+
+ if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66)
+ txx9_pci_option =
+ (txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
+ TXX9_PCI_OPT_CLK_66; /* already configured */
+
+ /* Reset PCI Bus */
+ writeb(0, rbtx4938_pcireset_addr);
+ /* Reset PCIC */
+ txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
+ if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
+ TXX9_PCI_OPT_CLK_66)
+ tx4938_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
+ writeb(1, rbtx4938_pcireset_addr);
+ iob();
+
+ tx4938_report_pciclk();
+ tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
+ if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
+ TXX9_PCI_OPT_CLK_AUTO &&
+ txx9_pci66_check(c, 0, 0)) {
+ /* Reset PCI Bus */
+ writeb(0, rbtx4938_pcireset_addr);
+ /* Reset PCIC */
+ txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
+ tx4938_pciclk66_setup();
+ mdelay(10);
+ /* clear PCIC reset */
+ txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
+ writeb(1, rbtx4938_pcireset_addr);
+ iob();
+ /* Reinitialize PCIC */
+ tx4938_report_pciclk();
+ tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
+ }
+
+ if (__raw_readq(&tx4938_ccfgptr->pcfg) &
+ (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL)) {
+ /* Reset PCIC1 */
+ txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
+ /* PCI1DMD==0 => PCI1CLK==GBUSCLK/2 => PCI66 */
+ if (!(__raw_readq(&tx4938_ccfgptr->ccfg)
+ & TX4938_CCFG_PCI1DMD))
+ tx4938_ccfg_set(TX4938_CCFG_PCI1_66);
+ mdelay(10);
+ /* clear PCIC1 reset */
+ txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIC1RST);
+ tx4938_report_pci1clk();
+
+ /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */
+ c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000);
+ register_pci_controller(c);
+ tx4927_pcic_setup(tx4938_pcic1ptr, c, 0);
+ }
+ tx4938_setup_pcierr_irq();
+#endif /* CONFIG_PCI */
+}
+
+/* SPI support */
+
+/* chip select for SPI devices */
+#define SEEPROM1_CS 7 /* PIO7 */
+#define SEEPROM2_CS 0 /* IOC */
+#define SEEPROM3_CS 1 /* IOC */
+#define SRTC_CS 2 /* IOC */
+#define SPI_BUSNO 0
+
+static int __init rbtx4938_ethaddr_init(void)
+{
+#ifdef CONFIG_PCI
+ unsigned char dat[17];
+ unsigned char sum;
+ int i;
+
+ /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
+ if (spi_eeprom_read(SPI_BUSNO, SEEPROM1_CS, 0, dat, sizeof(dat))) {
+ printk(KERN_ERR "seeprom: read error.\n");
+ return -ENODEV;
+ } else {
+ if (strcmp(dat, "MAC") != 0)
+ printk(KERN_WARNING "seeprom: bad signature.\n");
+ for (i = 0, sum = 0; i < sizeof(dat); i++)
+ sum += dat[i];
+ if (sum)
+ printk(KERN_WARNING "seeprom: bad checksum.\n");
+ }
+ tx4938_ethaddr_init(&dat[4], &dat[4 + 6]);
+#endif /* CONFIG_PCI */
+ return 0;
+}
+
+static void __init rbtx4938_spi_setup(void)
+{
+ /* set SPI_SEL */
+ txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_SPI_SEL);
+}
+
+static struct resource rbtx4938_fpga_resource;
+
+static void __init rbtx4938_time_init(void)
+{
+ tx4938_time_init(0);
+}
+
+static void __init rbtx4938_mem_setup(void)
+{
+ unsigned long long pcfg;
+
+ if (txx9_master_clock == 0)
+ txx9_master_clock = 25000000; /* 25MHz */
+
+ tx4938_setup();
+
+#ifdef CONFIG_PCI
+ txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0);
+ txx9_board_pcibios_setup = tx4927_pcibios_setup;
+#else
+ set_io_port_base(RBTX4938_ETHER_BASE);
+#endif
+
+ tx4938_sio_init(7372800, 0);
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_PIO58_61
+ pr_info("PIOSEL: disabling both ATA and NAND selection\n");
+ txx9_clear64(&tx4938_ccfgptr->pcfg,
+ TX4938_PCFG_NDF_SEL | TX4938_PCFG_ATA_SEL);
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
+ pr_info("PIOSEL: enabling NAND selection\n");
+ txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL);
+ txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL);
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_ATA
+ pr_info("PIOSEL: enabling ATA selection\n");
+ txx9_set64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_ATA_SEL);
+ txx9_clear64(&tx4938_ccfgptr->pcfg, TX4938_PCFG_NDF_SEL);
+#endif
+
+#ifdef CONFIG_TOSHIBA_RBTX4938_MPLEX_KEEP
+ pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg);
+ pr_info("PIOSEL: NAND %s, ATA %s\n",
+ (pcfg & TX4938_PCFG_NDF_SEL) ? "enabled" : "disabled",
+ (pcfg & TX4938_PCFG_ATA_SEL) ? "enabled" : "disabled");
+#endif
+
+ rbtx4938_spi_setup();
+ pcfg = ____raw_readq(&tx4938_ccfgptr->pcfg); /* updated */
+ /* fixup piosel */
+ if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_ATA_SEL)
+ writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x04,
+ rbtx4938_piosel_addr);
+ else if ((pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_NDF_SEL)
+ writeb((readb(rbtx4938_piosel_addr) & 0x03) | 0x08,
+ rbtx4938_piosel_addr);
+ else
+ writeb(readb(rbtx4938_piosel_addr) & ~(0x08 | 0x04),
+ rbtx4938_piosel_addr);
+
+ rbtx4938_fpga_resource.name = "FPGA Registers";
+ rbtx4938_fpga_resource.start = CPHYSADDR(RBTX4938_FPGA_REG_ADDR);
+ rbtx4938_fpga_resource.end = CPHYSADDR(RBTX4938_FPGA_REG_ADDR) + 0xffff;
+ rbtx4938_fpga_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ if (request_resource(&txx9_ce_res[2], &rbtx4938_fpga_resource))
+ printk(KERN_ERR "request resource for fpga failed\n");
+
+ _machine_restart = rbtx4938_machine_restart;
+
+ writeb(0xff, rbtx4938_led_addr);
+ printk(KERN_INFO "RBTX4938 --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
+ readb(rbtx4938_fpga_rev_addr),
+ readb(rbtx4938_dipsw_addr), readb(rbtx4938_bdipsw_addr));
+}
+
+static void __init rbtx4938_ne_init(void)
+{
+ struct resource res[] = {
+ {
+ .start = RBTX4938_RTL_8019_BASE,
+ .end = RBTX4938_RTL_8019_BASE + 0x20 - 1,
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = RBTX4938_RTL_8019_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+ platform_device_register_simple("ne", -1, res, ARRAY_SIZE(res));
+}
+
+static DEFINE_SPINLOCK(rbtx4938_spi_gpio_lock);
+
+static void rbtx4938_spi_gpio_set(struct gpio_chip *chip, unsigned int offset,
+ int value)
+{
+ u8 val;
+ unsigned long flags;
+ spin_lock_irqsave(&rbtx4938_spi_gpio_lock, flags);
+ val = readb(rbtx4938_spics_addr);
+ if (value)
+ val |= 1 << offset;
+ else
+ val &= ~(1 << offset);
+ writeb(val, rbtx4938_spics_addr);
+ mmiowb();
+ spin_unlock_irqrestore(&rbtx4938_spi_gpio_lock, flags);
+}
+
+static int rbtx4938_spi_gpio_dir_out(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ rbtx4938_spi_gpio_set(chip, offset, value);
+ return 0;
+}
+
+static struct gpio_chip rbtx4938_spi_gpio_chip = {
+ .set = rbtx4938_spi_gpio_set,
+ .direction_output = rbtx4938_spi_gpio_dir_out,
+ .label = "RBTX4938-SPICS",
+ .base = 16,
+ .ngpio = 3,
+};
+
+static int __init rbtx4938_spi_init(void)
+{
+ struct spi_board_info srtc_info = {
+ .modalias = "rtc-rs5c348",
+ .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */
+ .bus_num = 0,
+ .chip_select = 16 + SRTC_CS,
+ /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */
+ .mode = SPI_MODE_1 | SPI_CS_HIGH,
+ };
+ spi_register_board_info(&srtc_info, 1);
+ spi_eeprom_register(SPI_BUSNO, SEEPROM1_CS, 128);
+ spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM2_CS, 128);
+ spi_eeprom_register(SPI_BUSNO, 16 + SEEPROM3_CS, 128);
+ gpio_request(16 + SRTC_CS, "rtc-rs5c348");
+ gpio_direction_output(16 + SRTC_CS, 0);
+ gpio_request(SEEPROM1_CS, "seeprom1");
+ gpio_direction_output(SEEPROM1_CS, 1);
+ gpio_request(16 + SEEPROM2_CS, "seeprom2");
+ gpio_direction_output(16 + SEEPROM2_CS, 1);
+ gpio_request(16 + SEEPROM3_CS, "seeprom3");
+ gpio_direction_output(16 + SEEPROM3_CS, 1);
+ tx4938_spi_init(SPI_BUSNO);
+ return 0;
+}
+
+static void __init rbtx4938_mtd_init(void)
+{
+ struct physmap_flash_data pdata = {
+ .width = 4,
+ };
+
+ switch (readb(rbtx4938_bdipsw_addr) & 7) {
+ case 0:
+ /* Boot */
+ txx9_physmap_flash_init(0, 0x1fc00000, 0x400000, &pdata);
+ /* System */
+ txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata);
+ break;
+ case 1:
+ /* System */
+ txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata);
+ /* Boot */
+ txx9_physmap_flash_init(1, 0x1ec00000, 0x400000, &pdata);
+ break;
+ case 2:
+ /* Ext */
+ txx9_physmap_flash_init(0, 0x1f000000, 0x1000000, &pdata);
+ /* System */
+ txx9_physmap_flash_init(1, 0x1e000000, 0x1000000, &pdata);
+ /* Boot */
+ txx9_physmap_flash_init(2, 0x1dc00000, 0x400000, &pdata);
+ break;
+ case 3:
+ /* Boot */
+ txx9_physmap_flash_init(1, 0x1bc00000, 0x400000, &pdata);
+ /* System */
+ txx9_physmap_flash_init(2, 0x1a000000, 0x1000000, &pdata);
+ break;
+ }
+}
+
+static void __init rbtx4938_arch_init(void)
+{
+ gpiochip_add(&rbtx4938_spi_gpio_chip);
+ rbtx4938_pci_setup();
+ rbtx4938_spi_init();
+}
+
+static void __init rbtx4938_device_init(void)
+{
+ rbtx4938_ethaddr_init();
+ rbtx4938_ne_init();
+ tx4938_wdt_init();
+ rbtx4938_mtd_init();
+ /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
+ tx4938_ndfmc_init(10, 35);
+ tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
+ tx4938_dmac_init(0, 2);
+ tx4938_aclc_init();
+ platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
+ tx4938_sramc_init();
+ txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
+}
+
+struct txx9_board_vec rbtx4938_vec __initdata = {
+ .system = "Toshiba RBTX4938",
+ .prom_init = rbtx4938_prom_init,
+ .mem_setup = rbtx4938_mem_setup,
+ .irq_setup = rbtx4938_irq_setup,
+ .time_init = rbtx4938_time_init,
+ .device_init = rbtx4938_device_init,
+ .arch_init = rbtx4938_arch_init,
+#ifdef CONFIG_PCI
+ .pci_map_irq = rbtx4938_pci_map_irq,
+#endif
+};
diff --git a/arch/mips/txx9/rbtx4939/Makefile b/arch/mips/txx9/rbtx4939/Makefile
new file mode 100644
index 00000000..5c84625a
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/Makefile
@@ -0,0 +1 @@
+obj-y += irq.o setup.o prom.o
diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c
new file mode 100644
index 00000000..69a80616
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/irq.c
@@ -0,0 +1,95 @@
+/*
+ * Toshiba RBTX4939 interrupt routines
+ * Based on linux/arch/mips/txx9/rbtx4938/irq.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * Copyright (C) 2000-2001,2005-2006 Toshiba Corporation
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/txx9/rbtx4939.h>
+
+/*
+ * RBTX4939 IOC controller definition
+ */
+
+static void rbtx4939_ioc_irq_unmask(struct irq_data *d)
+{
+ int ioc_nr = d->irq - RBTX4939_IRQ_IOC;
+
+ writeb(readb(rbtx4939_ien_addr) | (1 << ioc_nr), rbtx4939_ien_addr);
+}
+
+static void rbtx4939_ioc_irq_mask(struct irq_data *d)
+{
+ int ioc_nr = d->irq - RBTX4939_IRQ_IOC;
+
+ writeb(readb(rbtx4939_ien_addr) & ~(1 << ioc_nr), rbtx4939_ien_addr);
+ mmiowb();
+}
+
+static struct irq_chip rbtx4939_ioc_irq_chip = {
+ .name = "IOC",
+ .irq_mask = rbtx4939_ioc_irq_mask,
+ .irq_unmask = rbtx4939_ioc_irq_unmask,
+};
+
+
+static inline int rbtx4939_ioc_irqroute(void)
+{
+ unsigned char istat = readb(rbtx4939_ifac2_addr);
+
+ if (unlikely(istat == 0))
+ return -1;
+ return RBTX4939_IRQ_IOC + __fls8(istat);
+}
+
+static int rbtx4939_irq_dispatch(int pending)
+{
+ int irq;
+
+ if (pending & CAUSEF_IP7)
+ return MIPS_CPU_IRQ_BASE + 7;
+ irq = tx4939_irq();
+ if (likely(irq >= 0)) {
+ /* redirect IOC interrupts */
+ switch (irq) {
+ case RBTX4939_IRQ_IOCINT:
+ irq = rbtx4939_ioc_irqroute();
+ break;
+ }
+ } else if (pending & CAUSEF_IP0)
+ irq = MIPS_CPU_IRQ_BASE + 0;
+ else if (pending & CAUSEF_IP1)
+ irq = MIPS_CPU_IRQ_BASE + 1;
+ else
+ irq = -1;
+ return irq;
+}
+
+void __init rbtx4939_irq_setup(void)
+{
+ int i;
+
+ /* mask all IOC interrupts */
+ writeb(0, rbtx4939_ien_addr);
+
+ /* clear SoftInt interrupts */
+ writeb(0, rbtx4939_softint_addr);
+
+ txx9_irq_dispatch = rbtx4939_irq_dispatch;
+
+ tx4939_irq_init();
+ for (i = RBTX4939_IRQ_IOC;
+ i < RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC; i++)
+ irq_set_chip_and_handler(i, &rbtx4939_ioc_irq_chip,
+ handle_level_irq);
+
+ irq_set_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq);
+}
diff --git a/arch/mips/txx9/rbtx4939/prom.c b/arch/mips/txx9/rbtx4939/prom.c
new file mode 100644
index 00000000..bd277ecb
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/prom.c
@@ -0,0 +1,17 @@
+/*
+ * rbtx4939 specific prom routines
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/rbtx4939.h>
+
+void __init rbtx4939_prom_init(void)
+{
+ tx4939_add_memory_regions();
+ txx9_sio_putchar_init(TX4939_SIO_REG(0) & 0xfffffffffULL);
+}
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
new file mode 100644
index 00000000..7dc0fafb
--- /dev/null
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -0,0 +1,555 @@
+/*
+ * Toshiba RBTX4939 setup routines.
+ * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
+ * and RBTX49xx patch from CELF patch archive.
+ *
+ * Copyright (C) 2000-2001,2005-2007 Toshiba Corporation
+ * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/interrupt.h>
+#include <linux/smc91x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
+#include <asm/reboot.h>
+#include <asm/txx9/generic.h>
+#include <asm/txx9/pci.h>
+#include <asm/txx9/rbtx4939.h>
+
+static void rbtx4939_machine_restart(char *command)
+{
+ local_irq_disable();
+ writeb(1, rbtx4939_reseten_addr);
+ writeb(1, rbtx4939_softreset_addr);
+ while (1)
+ ;
+}
+
+static void __init rbtx4939_time_init(void)
+{
+ tx4939_time_init(0);
+}
+
+#if defined(__BIG_ENDIAN) && \
+ (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE))
+#define HAVE_RBTX4939_IOSWAB
+#define IS_CE1_ADDR(addr) \
+ ((((unsigned long)(addr) - IO_BASE) & 0xfff00000) == TXX9_CE(1))
+static u16 rbtx4939_ioswabw(volatile u16 *a, u16 x)
+{
+ return IS_CE1_ADDR(a) ? x : le16_to_cpu(x);
+}
+static u16 rbtx4939_mem_ioswabw(volatile u16 *a, u16 x)
+{
+ return !IS_CE1_ADDR(a) ? x : le16_to_cpu(x);
+}
+#endif /* __BIG_ENDIAN && CONFIG_SMC91X */
+
+static void __init rbtx4939_pci_setup(void)
+{
+#ifdef CONFIG_PCI
+ int extarb = !(__raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_PCIARB);
+ struct pci_controller *c = &txx9_primary_pcic;
+
+ register_pci_controller(c);
+
+ tx4939_report_pciclk();
+ tx4927_pcic_setup(tx4939_pcicptr, c, extarb);
+ if (!(__raw_readq(&tx4939_ccfgptr->pcfg) & TX4939_PCFG_ATA1MODE) &&
+ (__raw_readq(&tx4939_ccfgptr->pcfg) &
+ (TX4939_PCFG_ET0MODE | TX4939_PCFG_ET1MODE))) {
+ tx4939_report_pci1clk();
+
+ /* mem:64K(max), io:64K(max) (enough for ETH0,ETH1) */
+ c = txx9_alloc_pci_controller(NULL, 0, 0x10000, 0, 0x10000);
+ register_pci_controller(c);
+ tx4927_pcic_setup(tx4939_pcic1ptr, c, 0);
+ }
+
+ tx4939_setup_pcierr_irq();
+#endif /* CONFIG_PCI */
+}
+
+static unsigned long long default_ebccr[] __initdata = {
+ 0x01c0000000007608ULL, /* 64M ROM */
+ 0x017f000000007049ULL, /* 1M IOC */
+ 0x0180000000408608ULL, /* ISA */
+ 0,
+};
+
+static void __init rbtx4939_ebusc_setup(void)
+{
+ int i;
+ unsigned int sp;
+
+ /* use user-configured speed */
+ sp = TX4939_EBUSC_CR(0) & 0x30;
+ default_ebccr[0] |= sp;
+ default_ebccr[1] |= sp;
+ default_ebccr[2] |= sp;
+ /* initialise by myself */
+ for (i = 0; i < ARRAY_SIZE(default_ebccr); i++) {
+ if (default_ebccr[i])
+ ____raw_writeq(default_ebccr[i],
+ &tx4939_ebuscptr->cr[i]);
+ else
+ ____raw_writeq(____raw_readq(&tx4939_ebuscptr->cr[i])
+ & ~8,
+ &tx4939_ebuscptr->cr[i]);
+ }
+}
+
+static void __init rbtx4939_update_ioc_pen(void)
+{
+ __u64 pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
+ __u64 ccfg = ____raw_readq(&tx4939_ccfgptr->ccfg);
+ __u8 pe1 = readb(rbtx4939_pe1_addr);
+ __u8 pe2 = readb(rbtx4939_pe2_addr);
+ __u8 pe3 = readb(rbtx4939_pe3_addr);
+ if (pcfg & TX4939_PCFG_ATA0MODE)
+ pe1 |= RBTX4939_PE1_ATA(0);
+ else
+ pe1 &= ~RBTX4939_PE1_ATA(0);
+ if (pcfg & TX4939_PCFG_ATA1MODE) {
+ pe1 |= RBTX4939_PE1_ATA(1);
+ pe1 &= ~(RBTX4939_PE1_RMII(0) | RBTX4939_PE1_RMII(1));
+ } else {
+ pe1 &= ~RBTX4939_PE1_ATA(1);
+ if (pcfg & TX4939_PCFG_ET0MODE)
+ pe1 |= RBTX4939_PE1_RMII(0);
+ else
+ pe1 &= ~RBTX4939_PE1_RMII(0);
+ if (pcfg & TX4939_PCFG_ET1MODE)
+ pe1 |= RBTX4939_PE1_RMII(1);
+ else
+ pe1 &= ~RBTX4939_PE1_RMII(1);
+ }
+ if (ccfg & TX4939_CCFG_PTSEL)
+ pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P |
+ RBTX4939_PE3_VP_S);
+ else {
+ __u64 vmode = pcfg &
+ (TX4939_PCFG_VSSMODE | TX4939_PCFG_VPSMODE);
+ if (vmode == 0)
+ pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_P |
+ RBTX4939_PE3_VP_S);
+ else if (vmode == TX4939_PCFG_VPSMODE) {
+ pe3 |= RBTX4939_PE3_VP_P;
+ pe3 &= ~(RBTX4939_PE3_VP | RBTX4939_PE3_VP_S);
+ } else if (vmode == TX4939_PCFG_VSSMODE) {
+ pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_S;
+ pe3 &= ~RBTX4939_PE3_VP_P;
+ } else {
+ pe3 |= RBTX4939_PE3_VP | RBTX4939_PE3_VP_P;
+ pe3 &= ~RBTX4939_PE3_VP_S;
+ }
+ }
+ if (pcfg & TX4939_PCFG_SPIMODE) {
+ if (pcfg & TX4939_PCFG_SIO2MODE_GPIO)
+ pe2 &= ~(RBTX4939_PE2_SIO2 | RBTX4939_PE2_SIO0);
+ else {
+ if (pcfg & TX4939_PCFG_SIO2MODE_SIO2) {
+ pe2 |= RBTX4939_PE2_SIO2;
+ pe2 &= ~RBTX4939_PE2_SIO0;
+ } else {
+ pe2 |= RBTX4939_PE2_SIO0;
+ pe2 &= ~RBTX4939_PE2_SIO2;
+ }
+ }
+ if (pcfg & TX4939_PCFG_SIO3MODE)
+ pe2 |= RBTX4939_PE2_SIO3;
+ else
+ pe2 &= ~RBTX4939_PE2_SIO3;
+ pe2 &= ~RBTX4939_PE2_SPI;
+ } else {
+ pe2 |= RBTX4939_PE2_SPI;
+ pe2 &= ~(RBTX4939_PE2_SIO3 | RBTX4939_PE2_SIO2 |
+ RBTX4939_PE2_SIO0);
+ }
+ if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_GPIO)
+ pe2 |= RBTX4939_PE2_GPIO;
+ else
+ pe2 &= ~RBTX4939_PE2_GPIO;
+ writeb(pe1, rbtx4939_pe1_addr);
+ writeb(pe2, rbtx4939_pe2_addr);
+ writeb(pe3, rbtx4939_pe3_addr);
+}
+
+#define RBTX4939_MAX_7SEGLEDS 8
+
+#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
+static u8 led_val[RBTX4939_MAX_7SEGLEDS];
+struct rbtx4939_led_data {
+ struct led_classdev cdev;
+ char name[32];
+ unsigned int num;
+};
+
+/* Use "dot" in 7seg LEDs */
+static void rbtx4939_led_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct rbtx4939_led_data *led_dat =
+ container_of(led_cdev, struct rbtx4939_led_data, cdev);
+ unsigned int num = led_dat->num;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ led_val[num] = (led_val[num] & 0x7f) | (value ? 0x80 : 0);
+ writeb(led_val[num], rbtx4939_7seg_addr(num / 4, num % 4));
+ local_irq_restore(flags);
+}
+
+static int __init rbtx4939_led_probe(struct platform_device *pdev)
+{
+ struct rbtx4939_led_data *leds_data;
+ int i;
+ static char *default_triggers[] __initdata = {
+ "heartbeat",
+ "ide-disk",
+ "nand-disk",
+ };
+
+ leds_data = kzalloc(sizeof(*leds_data) * RBTX4939_MAX_7SEGLEDS,
+ GFP_KERNEL);
+ if (!leds_data)
+ return -ENOMEM;
+ for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++) {
+ int rc;
+ struct rbtx4939_led_data *led_dat = &leds_data[i];
+
+ led_dat->num = i;
+ led_dat->cdev.brightness_set = rbtx4939_led_brightness_set;
+ sprintf(led_dat->name, "rbtx4939:amber:%u", i);
+ led_dat->cdev.name = led_dat->name;
+ if (i < ARRAY_SIZE(default_triggers))
+ led_dat->cdev.default_trigger = default_triggers[i];
+ rc = led_classdev_register(&pdev->dev, &led_dat->cdev);
+ if (rc < 0)
+ return rc;
+ led_dat->cdev.brightness_set(&led_dat->cdev, 0);
+ }
+ return 0;
+
+}
+
+static struct platform_driver rbtx4939_led_driver = {
+ .driver = {
+ .name = "rbtx4939-led",
+ .owner = THIS_MODULE,
+ },
+};
+
+static void __init rbtx4939_led_setup(void)
+{
+ platform_device_register_simple("rbtx4939-led", -1, NULL, 0);
+ platform_driver_probe(&rbtx4939_led_driver, rbtx4939_led_probe);
+}
+#else
+static inline void rbtx4939_led_setup(void)
+{
+}
+#endif
+
+static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
+{
+#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
+ unsigned long flags;
+ local_irq_save(flags);
+ /* bit7: reserved for LED class */
+ led_val[pos] = (led_val[pos] & 0x80) | (val & 0x7f);
+ val = led_val[pos];
+ local_irq_restore(flags);
+#endif
+ writeb(val, rbtx4939_7seg_addr(pos / 4, pos % 4));
+}
+
+static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
+{
+ /* convert from map_to_seg7() notation */
+ val = (val & 0x88) |
+ ((val & 0x40) >> 6) |
+ ((val & 0x20) >> 4) |
+ ((val & 0x10) >> 2) |
+ ((val & 0x04) << 2) |
+ ((val & 0x02) << 4) |
+ ((val & 0x01) << 6);
+ __rbtx4939_7segled_putc(pos, val);
+}
+
+#if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE)
+/* special mapping for boot rom */
+static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
+{
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+ unsigned char shift;
+
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ shift = bdipsw & 3;
+ /* rotate A[23:22] */
+ return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22);
+ }
+#ifdef __BIG_ENDIAN
+ if (bdipsw == 0)
+ /* BOOT Mode: Monitor ROM */
+ ofs ^= 0x400000; /* swap A[22] */
+#endif
+ return ofs;
+}
+
+static map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs)
+{
+ map_word r;
+
+ ofs = rbtx4939_flash_fixup_ofs(ofs);
+ r.x[0] = __raw_readw(map->virt + ofs);
+ return r;
+}
+
+static void rbtx4939_flash_write16(struct map_info *map, const map_word datum,
+ unsigned long ofs)
+{
+ ofs = rbtx4939_flash_fixup_ofs(ofs);
+ __raw_writew(datum.x[0], map->virt + ofs);
+ mb(); /* see inline_map_write() in mtd/map.h */
+}
+
+static void rbtx4939_flash_copy_from(struct map_info *map, void *to,
+ unsigned long from, ssize_t len)
+{
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+ unsigned char shift;
+ ssize_t curlen;
+
+ from += (unsigned long)map->virt;
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ shift = bdipsw & 3;
+ while (len) {
+ curlen = min_t(unsigned long, len,
+ 0x400000 - (from & (0x400000 - 1)));
+ memcpy(to,
+ (void *)((from & ~0xc00000) |
+ ((((from >> 22) + shift) & 3) << 22)),
+ curlen);
+ len -= curlen;
+ from += curlen;
+ to += curlen;
+ }
+ return;
+ }
+#ifdef __BIG_ENDIAN
+ if (bdipsw == 0) {
+ /* BOOT Mode: Monitor ROM */
+ while (len) {
+ curlen = min_t(unsigned long, len,
+ 0x400000 - (from & (0x400000 - 1)));
+ memcpy(to, (void *)(from ^ 0x400000), curlen);
+ len -= curlen;
+ from += curlen;
+ to += curlen;
+ }
+ return;
+ }
+#endif
+ memcpy(to, (void *)from, len);
+}
+
+static void rbtx4939_flash_map_init(struct map_info *map)
+{
+ map->read = rbtx4939_flash_read16;
+ map->write = rbtx4939_flash_write16;
+ map->copy_from = rbtx4939_flash_copy_from;
+}
+
+static void __init rbtx4939_mtd_init(void)
+{
+ static struct {
+ struct platform_device dev;
+ struct resource res;
+ struct rbtx4939_flash_data data;
+ } pdevs[4];
+ int i;
+ static char names[4][8];
+ static struct mtd_partition parts[4];
+ struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data;
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ boot_pdata->nr_parts = 4;
+ for (i = 0; i < boot_pdata->nr_parts; i++) {
+ sprintf(names[i], "img%d", 4 - i);
+ parts[i].name = names[i];
+ parts[i].size = 0x400000;
+ parts[i].offset = MTDPART_OFS_NXTBLK;
+ }
+ } else if (bdipsw == 0) {
+ /* BOOT Mode: Monitor ROM */
+ boot_pdata->nr_parts = 2;
+ strcpy(names[0], "big");
+ strcpy(names[1], "little");
+ for (i = 0; i < boot_pdata->nr_parts; i++) {
+ parts[i].name = names[i];
+ parts[i].size = 0x400000;
+ parts[i].offset = MTDPART_OFS_NXTBLK;
+ }
+ } else {
+ /* BOOT Mode: ROM Emulator */
+ boot_pdata->nr_parts = 2;
+ parts[0].name = "boot";
+ parts[0].offset = 0xc00000;
+ parts[0].size = 0x400000;
+ parts[1].name = "user";
+ parts[1].offset = 0;
+ parts[1].size = 0xc00000;
+ }
+ boot_pdata->parts = parts;
+ boot_pdata->map_init = rbtx4939_flash_map_init;
+
+ for (i = 0; i < ARRAY_SIZE(pdevs); i++) {
+ struct resource *r = &pdevs[i].res;
+ struct platform_device *dev = &pdevs[i].dev;
+
+ r->start = 0x1f000000 - i * 0x1000000;
+ r->end = r->start + 0x1000000 - 1;
+ r->flags = IORESOURCE_MEM;
+ pdevs[i].data.width = 2;
+ dev->num_resources = 1;
+ dev->resource = r;
+ dev->id = i;
+ dev->name = "rbtx4939-flash";
+ dev->dev.platform_data = &pdevs[i].data;
+ platform_device_register(dev);
+ }
+}
+#else
+static void __init rbtx4939_mtd_init(void)
+{
+}
+#endif
+
+static void __init rbtx4939_arch_init(void)
+{
+ rbtx4939_pci_setup();
+}
+
+static void __init rbtx4939_device_init(void)
+{
+ unsigned long smc_addr = RBTX4939_ETHER_ADDR - IO_BASE;
+ struct resource smc_res[] = {
+ {
+ .start = smc_addr,
+ .end = smc_addr + 0x10 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = RBTX4939_IRQ_ETHER,
+ /* override default irq flag defined in smc91x.h */
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+ };
+ struct smc91x_platdata smc_pdata = {
+ .flags = SMC91X_USE_16BIT,
+ };
+ struct platform_device *pdev;
+#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
+ int i, j;
+ unsigned char ethaddr[2][6];
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+
+ for (i = 0; i < 2; i++) {
+ unsigned long area = CKSEG1 + 0x1fff0000 + (i * 0x10);
+ if (bdipsw == 0)
+ memcpy(ethaddr[i], (void *)area, 6);
+ else {
+ u16 buf[3];
+ if (bdipsw & 8)
+ area -= 0x03000000;
+ else
+ area -= 0x01000000;
+ for (j = 0; j < 3; j++)
+ buf[j] = le16_to_cpup((u16 *)(area + j * 2));
+ memcpy(ethaddr[i], buf, 6);
+ }
+ }
+ tx4939_ethaddr_init(ethaddr[0], ethaddr[1]);
+#endif
+ pdev = platform_device_alloc("smc91x", -1);
+ if (!pdev ||
+ platform_device_add_resources(pdev, smc_res, ARRAY_SIZE(smc_res)) ||
+ platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+ rbtx4939_mtd_init();
+ /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
+ tx4939_ndfmc_init(10, 35,
+ (1 << 1) | (1 << 2),
+ (1 << 2)); /* ch1:8bit, ch2:16bit */
+ rbtx4939_led_setup();
+ tx4939_wdt_init();
+ tx4939_ata_init();
+ tx4939_rtc_init();
+ tx4939_dmac_init(0, 2);
+ tx4939_aclc_init();
+ platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
+ tx4939_sramc_init();
+ tx4939_rng_init();
+}
+
+static void __init rbtx4939_setup(void)
+{
+ int i;
+
+ rbtx4939_ebusc_setup();
+ /* always enable ATA0 */
+ txx9_set64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_ATA0MODE);
+ if (txx9_master_clock == 0)
+ txx9_master_clock = 20000000;
+ tx4939_setup();
+ rbtx4939_update_ioc_pen();
+#ifdef HAVE_RBTX4939_IOSWAB
+ ioswabw = rbtx4939_ioswabw;
+ __mem_ioswabw = rbtx4939_mem_ioswabw;
+#endif
+
+ _machine_restart = rbtx4939_machine_restart;
+
+ txx9_7segled_init(RBTX4939_MAX_7SEGLEDS, rbtx4939_7segled_putc);
+ for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++)
+ txx9_7segled_putc(i, '-');
+ pr_info("RBTX4939 (Rev %02x) --- FPGA(Rev %02x) DIPSW:%02x,%02x\n",
+ readb(rbtx4939_board_rev_addr), readb(rbtx4939_ioc_rev_addr),
+ readb(rbtx4939_udipsw_addr), readb(rbtx4939_bdipsw_addr));
+
+#ifdef CONFIG_PCI
+ txx9_alloc_pci_controller(&txx9_primary_pcic, 0, 0, 0, 0);
+ txx9_board_pcibios_setup = tx4927_pcibios_setup;
+#else
+ set_io_port_base(RBTX4939_ETHER_BASE);
+#endif
+
+ tx4939_sio_init(TX4939_SCLK0(txx9_master_clock), 0);
+}
+
+struct txx9_board_vec rbtx4939_vec __initdata = {
+ .system = "Toshiba RBTX4939",
+ .prom_init = rbtx4939_prom_init,
+ .mem_setup = rbtx4939_setup,
+ .irq_setup = rbtx4939_irq_setup,
+ .time_init = rbtx4939_time_init,
+ .device_init = rbtx4939_device_init,
+ .arch_init = rbtx4939_arch_init,
+#ifdef CONFIG_PCI
+ .pci_map_irq = tx4939_pci_map_irq,
+#endif
+};
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig
new file mode 100644
index 00000000..c1be6b37
--- /dev/null
+++ b/arch/mips/vr41xx/Kconfig
@@ -0,0 +1,103 @@
+choice
+ prompt "Machine type"
+ depends on MACH_VR41XX
+ default TANBAC_TB022X
+
+config CASIO_E55
+ bool "CASIO CASSIOPEIA E-10/15/55/65"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ISA
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config IBM_WORKPAD
+ bool "IBM WorkPad z50"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select ISA
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config TANBAC_TB022X
+ bool "TANBAC VR4131 multichip module and TANBAC VR4131DIMM"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select HW_HAS_PCI
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ help
+ The TANBAC VR4131 multichip module(TB0225) and
+ the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/>
+ about VR4131 multichip module and VR4131DIMM.
+
+config VICTOR_MPC30X
+ bool "Victor MP-C303/304"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select HW_HAS_PCI
+ select PCI_VR41XX
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+config ZAO_CAPCELLA
+ bool "ZAO Networks Capcella"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select HW_HAS_PCI
+ select PCI_VR41XX
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+
+endchoice
+
+choice
+ prompt "Base board type"
+ depends on TANBAC_TB022X
+ default TANBAC_TB0287
+
+config TANBAC_TB0219
+ bool "TANBAC DIMM Evaluation Kit(TB0219)"
+ select GPIO_VR41XX
+ select PCI_VR41XX
+ help
+ The TANBAC DIMM Evaluation Kit(TB0219) is a MIPS-based platform
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/> about DIMM Evaluation Kit.
+
+config TANBAC_TB0226
+ bool "TANBAC Mbase(TB0226)"
+ select GPIO_VR41XX
+ select PCI_VR41XX
+ help
+ The TANBAC Mbase(TB0226) is a MIPS-based platform
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/> about Mbase.
+
+config TANBAC_TB0287
+ bool "TANBAC Mini-ITX DIMM base(TB0287)"
+ select PCI_VR41XX
+ help
+ The TANBAC Mini-ITX DIMM base(TB0287) is a MIPS-based platform
+ manufactured by TANBAC.
+ Please refer to <http://www.tanbac.co.jp/> about Mini-ITX DIMM base.
+
+endchoice
+
+config PCI_VR41XX
+ bool "Add PCI control unit support of NEC VR4100 series"
+ depends on MACH_VR41XX && HW_HAS_PCI
+ default y
+ select PCI
diff --git a/arch/mips/vr41xx/Platform b/arch/mips/vr41xx/Platform
new file mode 100644
index 00000000..b6c8d5c0
--- /dev/null
+++ b/arch/mips/vr41xx/Platform
@@ -0,0 +1,32 @@
+#
+# NEC VR4100 series based machines
+#
+platform-$(CONFIG_MACH_VR41XX) += vr41xx/common/
+cflags-$(CONFIG_MACH_VR41XX) += -I$(srctree)/arch/mips/include/asm/mach-vr41xx
+
+#
+# CASIO CASSIPEIA E-55/65 (VR4111)
+#
+platform-$(CONFIG_CASIO_E55) += vr41xx/casio-e55/
+load-$(CONFIG_CASIO_E55) += 0xffffffff80004000
+
+#
+# IBM WorkPad z50 (VR4121)
+#
+platform-$(CONFIG_IBM_WORKPAD) += vr41xx/ibm-workpad/
+load-$(CONFIG_IBM_WORKPAD) += 0xffffffff80004000
+
+#
+# TANBAC VR4131 multichip module(TB0225) and TANBAC VR4131DIMM(TB0229) (VR4131)
+#
+load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000
+
+#
+# Victor MP-C303/304 (VR4122)
+#
+load-$(CONFIG_VICTOR_MPC30X) += 0xffffffff80001000
+
+#
+# ZAO Networks Capcella (VR4131)
+#
+load-$(CONFIG_ZAO_CAPCELLA) += 0xffffffff80000000
diff --git a/arch/mips/vr41xx/casio-e55/Makefile b/arch/mips/vr41xx/casio-e55/Makefile
new file mode 100644
index 00000000..d4c03cc8
--- /dev/null
+++ b/arch/mips/vr41xx/casio-e55/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the CASIO CASSIOPEIA E-55/65 specific parts of the kernel
+#
+
+obj-y += setup.o
diff --git a/arch/mips/vr41xx/casio-e55/setup.c b/arch/mips/vr41xx/casio-e55/setup.c
new file mode 100644
index 00000000..719f4a5b
--- /dev/null
+++ b/arch/mips/vr41xx/casio-e55/setup.c
@@ -0,0 +1,40 @@
+/*
+ * setup.c, Setup for the CASIO CASSIOPEIA E-11/15/55/65.
+ *
+ * Copyright (C) 2002-2006 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+
+#define E55_ISA_IO_BASE 0x1400c000
+#define E55_ISA_IO_SIZE 0x03ff4000
+#define E55_ISA_IO_START 0
+#define E55_ISA_IO_END (E55_ISA_IO_SIZE - 1)
+#define E55_IO_PORT_BASE KSEG1ADDR(E55_ISA_IO_BASE)
+
+static int __init casio_e55_setup(void)
+{
+ set_io_port_base(E55_IO_PORT_BASE);
+ ioport_resource.start = E55_ISA_IO_START;
+ ioport_resource.end = E55_ISA_IO_END;
+
+ return 0;
+}
+
+arch_initcall(casio_e55_setup);
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile
new file mode 100644
index 00000000..d0d84ec8
--- /dev/null
+++ b/arch/mips/vr41xx/common/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for common code of the NEC VR4100 series.
+#
+
+obj-y += bcu.o cmu.o giu.o icu.o init.o irq.o pmu.o rtc.o siu.o type.o
diff --git a/arch/mips/vr41xx/common/bcu.c b/arch/mips/vr41xx/common/bcu.c
new file mode 100644
index 00000000..6346c59c
--- /dev/null
+++ b/arch/mips/vr41xx/common/bcu.c
@@ -0,0 +1,222 @@
+/*
+ * bcu.c, Bus Control Unit routines for the NEC VR4100 series.
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ * Author: Yoichi Yuasa <source@mvista.com>
+ * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * Changes:
+ * MontaVista Software Inc. <source@mvista.com>
+ * - New creation, NEC VR4122 and VR4131 are supported.
+ * - Added support for NEC VR4111 and VR4121.
+ *
+ * Yoichi Yuasa <yuasa@linux-mips.org>
+ * - Added support for NEC VR4133.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+
+#define CLKSPEEDREG_TYPE1 (void __iomem *)KSEG1ADDR(0x0b000014)
+#define CLKSPEEDREG_TYPE2 (void __iomem *)KSEG1ADDR(0x0f000014)
+ #define CLKSP(x) ((x) & 0x001f)
+ #define CLKSP_VR4133(x) ((x) & 0x0007)
+
+ #define DIV2B 0x8000
+ #define DIV3B 0x4000
+ #define DIV4B 0x2000
+
+ #define DIVT(x) (((x) & 0xf000) >> 12)
+ #define DIVVT(x) (((x) & 0x0f00) >> 8)
+
+ #define TDIVMODE(x) (2 << (((x) & 0x1000) >> 12))
+ #define VTDIVMODE(x) (((x) & 0x0700) >> 8)
+
+static unsigned long vr41xx_vtclock;
+static unsigned long vr41xx_tclock;
+
+unsigned long vr41xx_get_vtclock_frequency(void)
+{
+ return vr41xx_vtclock;
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_get_vtclock_frequency);
+
+unsigned long vr41xx_get_tclock_frequency(void)
+{
+ return vr41xx_tclock;
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_get_tclock_frequency);
+
+static inline uint16_t read_clkspeed(void)
+{
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121: return readw(CLKSPEEDREG_TYPE1);
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133: return readw(CLKSPEEDREG_TYPE2);
+ default:
+ printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+ break;
+ }
+
+ return 0;
+}
+
+static inline unsigned long calculate_pclock(uint16_t clkspeed)
+{
+ unsigned long pclock = 0;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ pclock = 18432000 * 64;
+ pclock /= CLKSP(clkspeed);
+ break;
+ case CPU_VR4122:
+ pclock = 18432000 * 98;
+ pclock /= CLKSP(clkspeed);
+ break;
+ case CPU_VR4131:
+ pclock = 18432000 * 108;
+ pclock /= CLKSP(clkspeed);
+ break;
+ case CPU_VR4133:
+ switch (CLKSP_VR4133(clkspeed)) {
+ case 0:
+ pclock = 133000000;
+ break;
+ case 1:
+ pclock = 149000000;
+ break;
+ case 2:
+ pclock = 165900000;
+ break;
+ case 3:
+ pclock = 199100000;
+ break;
+ case 4:
+ pclock = 265900000;
+ break;
+ default:
+ printk(KERN_INFO "Unknown PClock speed for NEC VR4133\n");
+ break;
+ }
+ break;
+ default:
+ printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+ break;
+ }
+
+ printk(KERN_INFO "PClock: %ldHz\n", pclock);
+
+ return pclock;
+}
+
+static inline unsigned long calculate_vtclock(uint16_t clkspeed, unsigned long pclock)
+{
+ unsigned long vtclock = 0;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ /* The NEC VR4111 doesn't have the VTClock. */
+ break;
+ case CPU_VR4121:
+ vtclock = pclock;
+ /* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */
+ if (DIVVT(clkspeed) == 9)
+ vtclock = pclock * 6;
+ /* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */
+ else if (DIVVT(clkspeed) == 10)
+ vtclock = pclock * 4;
+ vtclock /= DIVVT(clkspeed);
+ printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
+ break;
+ case CPU_VR4122:
+ if(VTDIVMODE(clkspeed) == 7)
+ vtclock = pclock / 1;
+ else if(VTDIVMODE(clkspeed) == 1)
+ vtclock = pclock / 2;
+ else
+ vtclock = pclock / VTDIVMODE(clkspeed);
+ printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
+ break;
+ case CPU_VR4131:
+ case CPU_VR4133:
+ vtclock = pclock / VTDIVMODE(clkspeed);
+ printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
+ break;
+ default:
+ printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+ break;
+ }
+
+ return vtclock;
+}
+
+static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pclock,
+ unsigned long vtclock)
+{
+ unsigned long tclock = 0;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ if (!(clkspeed & DIV2B))
+ tclock = pclock / 2;
+ else if (!(clkspeed & DIV3B))
+ tclock = pclock / 3;
+ else if (!(clkspeed & DIV4B))
+ tclock = pclock / 4;
+ break;
+ case CPU_VR4121:
+ tclock = pclock / DIVT(clkspeed);
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133:
+ tclock = vtclock / TDIVMODE(clkspeed);
+ break;
+ default:
+ printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
+ break;
+ }
+
+ printk(KERN_INFO "TClock: %ldHz\n", tclock);
+
+ return tclock;
+}
+
+void vr41xx_calculate_clock_frequency(void)
+{
+ unsigned long pclock;
+ uint16_t clkspeed;
+
+ clkspeed = read_clkspeed();
+
+ pclock = calculate_pclock(clkspeed);
+ vr41xx_vtclock = calculate_vtclock(clkspeed, pclock);
+ vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock);
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_calculate_clock_frequency);
diff --git a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c
new file mode 100644
index 00000000..8ba7d04a
--- /dev/null
+++ b/arch/mips/vr41xx/common/cmu.c
@@ -0,0 +1,257 @@
+/*
+ * cmu.c, Clock Mask Unit routines for the NEC VR4100 series.
+ *
+ * Copyright (C) 2001-2002 MontaVista Software Inc.
+ * Author: Yoichi Yuasa <source@mvista.com>
+ * Copuright (C) 2003-2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * Changes:
+ * MontaVista Software Inc. <source@mvista.com>
+ * - New creation, NEC VR4122 and VR4131 are supported.
+ * - Added support for NEC VR4111 and VR4121.
+ *
+ * Yoichi Yuasa <yuasa@linux-mips.org>
+ * - Added support for NEC VR4133.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define CMU_TYPE1_BASE 0x0b000060UL
+#define CMU_TYPE1_SIZE 0x4
+
+#define CMU_TYPE2_BASE 0x0f000060UL
+#define CMU_TYPE2_SIZE 0x4
+
+#define CMU_TYPE3_BASE 0x0f000060UL
+#define CMU_TYPE3_SIZE 0x8
+
+#define CMUCLKMSK 0x0
+ #define MSKPIU 0x0001
+ #define MSKSIU 0x0002
+ #define MSKAIU 0x0004
+ #define MSKKIU 0x0008
+ #define MSKFIR 0x0010
+ #define MSKDSIU 0x0820
+ #define MSKCSI 0x0040
+ #define MSKPCIU 0x0080
+ #define MSKSSIU 0x0100
+ #define MSKSHSP 0x0200
+ #define MSKFFIR 0x0400
+ #define MSKSCSI 0x1000
+ #define MSKPPCIU 0x2000
+#define CMUCLKMSK2 0x4
+ #define MSKCEU 0x0001
+ #define MSKMAC0 0x0002
+ #define MSKMAC1 0x0004
+
+static void __iomem *cmu_base;
+static uint16_t cmuclkmsk, cmuclkmsk2;
+static DEFINE_SPINLOCK(cmu_lock);
+
+#define cmu_read(offset) readw(cmu_base + (offset))
+#define cmu_write(offset, value) writew((value), cmu_base + (offset))
+
+void vr41xx_supply_clock(vr41xx_clock_t clock)
+{
+ spin_lock_irq(&cmu_lock);
+
+ switch (clock) {
+ case PIU_CLOCK:
+ cmuclkmsk |= MSKPIU;
+ break;
+ case SIU_CLOCK:
+ cmuclkmsk |= MSKSIU | MSKSSIU;
+ break;
+ case AIU_CLOCK:
+ cmuclkmsk |= MSKAIU;
+ break;
+ case KIU_CLOCK:
+ cmuclkmsk |= MSKKIU;
+ break;
+ case FIR_CLOCK:
+ cmuclkmsk |= MSKFIR | MSKFFIR;
+ break;
+ case DSIU_CLOCK:
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121)
+ cmuclkmsk |= MSKDSIU;
+ else
+ cmuclkmsk |= MSKSIU | MSKDSIU;
+ break;
+ case CSI_CLOCK:
+ cmuclkmsk |= MSKCSI | MSKSCSI;
+ break;
+ case PCIU_CLOCK:
+ cmuclkmsk |= MSKPCIU;
+ break;
+ case HSP_CLOCK:
+ cmuclkmsk |= MSKSHSP;
+ break;
+ case PCI_CLOCK:
+ cmuclkmsk |= MSKPPCIU;
+ break;
+ case CEU_CLOCK:
+ cmuclkmsk2 |= MSKCEU;
+ break;
+ case ETHER0_CLOCK:
+ cmuclkmsk2 |= MSKMAC0;
+ break;
+ case ETHER1_CLOCK:
+ cmuclkmsk2 |= MSKMAC1;
+ break;
+ default:
+ break;
+ }
+
+ if (clock == CEU_CLOCK || clock == ETHER0_CLOCK ||
+ clock == ETHER1_CLOCK)
+ cmu_write(CMUCLKMSK2, cmuclkmsk2);
+ else
+ cmu_write(CMUCLKMSK, cmuclkmsk);
+
+ spin_unlock_irq(&cmu_lock);
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_supply_clock);
+
+void vr41xx_mask_clock(vr41xx_clock_t clock)
+{
+ spin_lock_irq(&cmu_lock);
+
+ switch (clock) {
+ case PIU_CLOCK:
+ cmuclkmsk &= ~MSKPIU;
+ break;
+ case SIU_CLOCK:
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121) {
+ cmuclkmsk &= ~(MSKSIU | MSKSSIU);
+ } else {
+ if (cmuclkmsk & MSKDSIU)
+ cmuclkmsk &= ~MSKSSIU;
+ else
+ cmuclkmsk &= ~(MSKSIU | MSKSSIU);
+ }
+ break;
+ case AIU_CLOCK:
+ cmuclkmsk &= ~MSKAIU;
+ break;
+ case KIU_CLOCK:
+ cmuclkmsk &= ~MSKKIU;
+ break;
+ case FIR_CLOCK:
+ cmuclkmsk &= ~(MSKFIR | MSKFFIR);
+ break;
+ case DSIU_CLOCK:
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121) {
+ cmuclkmsk &= ~MSKDSIU;
+ } else {
+ if (cmuclkmsk & MSKSSIU)
+ cmuclkmsk &= ~MSKDSIU;
+ else
+ cmuclkmsk &= ~(MSKSIU | MSKDSIU);
+ }
+ break;
+ case CSI_CLOCK:
+ cmuclkmsk &= ~(MSKCSI | MSKSCSI);
+ break;
+ case PCIU_CLOCK:
+ cmuclkmsk &= ~MSKPCIU;
+ break;
+ case HSP_CLOCK:
+ cmuclkmsk &= ~MSKSHSP;
+ break;
+ case PCI_CLOCK:
+ cmuclkmsk &= ~MSKPPCIU;
+ break;
+ case CEU_CLOCK:
+ cmuclkmsk2 &= ~MSKCEU;
+ break;
+ case ETHER0_CLOCK:
+ cmuclkmsk2 &= ~MSKMAC0;
+ break;
+ case ETHER1_CLOCK:
+ cmuclkmsk2 &= ~MSKMAC1;
+ break;
+ default:
+ break;
+ }
+
+ if (clock == CEU_CLOCK || clock == ETHER0_CLOCK ||
+ clock == ETHER1_CLOCK)
+ cmu_write(CMUCLKMSK2, cmuclkmsk2);
+ else
+ cmu_write(CMUCLKMSK, cmuclkmsk);
+
+ spin_unlock_irq(&cmu_lock);
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_mask_clock);
+
+static int __init vr41xx_cmu_init(void)
+{
+ unsigned long start, size;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ start = CMU_TYPE1_BASE;
+ size = CMU_TYPE1_SIZE;
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ start = CMU_TYPE2_BASE;
+ size = CMU_TYPE2_SIZE;
+ break;
+ case CPU_VR4133:
+ start = CMU_TYPE3_BASE;
+ size = CMU_TYPE3_SIZE;
+ break;
+ default:
+ panic("Unexpected CPU of NEC VR4100 series");
+ break;
+ }
+
+ if (request_mem_region(start, size, "CMU") == NULL)
+ return -EBUSY;
+
+ cmu_base = ioremap(start, size);
+ if (cmu_base == NULL) {
+ release_mem_region(start, size);
+ return -EBUSY;
+ }
+
+ cmuclkmsk = cmu_read(CMUCLKMSK);
+ if (current_cpu_type() == CPU_VR4133)
+ cmuclkmsk2 = cmu_read(CMUCLKMSK2);
+
+ spin_lock_init(&cmu_lock);
+
+ return 0;
+}
+
+core_initcall(vr41xx_cmu_init);
diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c
new file mode 100644
index 00000000..22cc6f21
--- /dev/null
+++ b/arch/mips/vr41xx/common/giu.c
@@ -0,0 +1,122 @@
+/*
+ * NEC VR4100 series GIU platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/giu.h>
+#include <asm/vr41xx/irq.h>
+
+static struct resource giu_50pins_pullupdown_resource[] __initdata = {
+ {
+ .start = 0x0b000100,
+ .end = 0x0b00011f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x0b0002e0,
+ .end = 0x0b0002e3,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = GIUINT_IRQ,
+ .end = GIUINT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource giu_36pins_resource[] __initdata = {
+ {
+ .start = 0x0f000140,
+ .end = 0x0f00015f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = GIUINT_IRQ,
+ .end = GIUINT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource giu_48pins_resource[] __initdata = {
+ {
+ .start = 0x0f000140,
+ .end = 0x0f000167,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = GIUINT_IRQ,
+ .end = GIUINT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int __init vr41xx_giu_add(void)
+{
+ struct platform_device *pdev;
+ struct resource *res;
+ unsigned int num;
+ int retval;
+
+ pdev = platform_device_alloc("GIU", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ pdev->id = GPIO_50PINS_PULLUPDOWN;
+ res = giu_50pins_pullupdown_resource;
+ num = ARRAY_SIZE(giu_50pins_pullupdown_resource);
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ pdev->id = GPIO_36PINS;
+ res = giu_36pins_resource;
+ num = ARRAY_SIZE(giu_36pins_resource);
+ break;
+ case CPU_VR4133:
+ pdev->id = GPIO_48PINS_EDGE_SELECT;
+ res = giu_48pins_resource;
+ num = ARRAY_SIZE(giu_48pins_resource);
+ break;
+ default:
+ retval = -ENODEV;
+ goto err_free_device;
+ }
+
+ retval = platform_device_add_resources(pdev, res, num);
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(vr41xx_giu_add);
diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c
new file mode 100644
index 00000000..a39ef320
--- /dev/null
+++ b/arch/mips/vr41xx/common/icu.c
@@ -0,0 +1,729 @@
+/*
+ * icu.c, Interrupt Control Unit routines for the NEC VR4100 series.
+ *
+ * Copyright (C) 2001-2002 MontaVista Software Inc.
+ * Author: Yoichi Yuasa <source@mvista.com>
+ * Copyright (C) 2003-2006 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * Changes:
+ * MontaVista Software Inc. <source@mvista.com>
+ * - New creation, NEC VR4122 and VR4131 are supported.
+ * - Added support for NEC VR4111 and VR4121.
+ *
+ * Yoichi Yuasa <yuasa@linux-mips.org>
+ * - Coped with INTASSIGN of NEC VR4133.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/irq.h>
+#include <asm/vr41xx/vr41xx.h>
+
+static void __iomem *icu1_base;
+static void __iomem *icu2_base;
+
+static unsigned char sysint1_assign[16] = {
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char sysint2_assign[16] = {
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#define ICU1_TYPE1_BASE 0x0b000080UL
+#define ICU2_TYPE1_BASE 0x0b000200UL
+
+#define ICU1_TYPE2_BASE 0x0f000080UL
+#define ICU2_TYPE2_BASE 0x0f0000a0UL
+
+#define ICU1_SIZE 0x20
+#define ICU2_SIZE 0x1c
+
+#define SYSINT1REG 0x00
+#define PIUINTREG 0x02
+#define INTASSIGN0 0x04
+#define INTASSIGN1 0x06
+#define GIUINTLREG 0x08
+#define DSIUINTREG 0x0a
+#define MSYSINT1REG 0x0c
+#define MPIUINTREG 0x0e
+#define MAIUINTREG 0x10
+#define MKIUINTREG 0x12
+#define MMACINTREG 0x12
+#define MGIUINTLREG 0x14
+#define MDSIUINTREG 0x16
+#define NMIREG 0x18
+#define SOFTREG 0x1a
+#define INTASSIGN2 0x1c
+#define INTASSIGN3 0x1e
+
+#define SYSINT2REG 0x00
+#define GIUINTHREG 0x02
+#define FIRINTREG 0x04
+#define MSYSINT2REG 0x06
+#define MGIUINTHREG 0x08
+#define MFIRINTREG 0x0a
+#define PCIINTREG 0x0c
+ #define PCIINT0 0x0001
+#define SCUINTREG 0x0e
+ #define SCUINT0 0x0001
+#define CSIINTREG 0x10
+#define MPCIINTREG 0x12
+#define MSCUINTREG 0x14
+#define MCSIINTREG 0x16
+#define BCUINTREG 0x18
+ #define BCUINTR 0x0001
+#define MBCUINTREG 0x1a
+
+#define SYSINT1_IRQ_TO_PIN(x) ((x) - SYSINT1_IRQ_BASE) /* Pin 0-15 */
+#define SYSINT2_IRQ_TO_PIN(x) ((x) - SYSINT2_IRQ_BASE) /* Pin 0-15 */
+
+#define INT_TO_IRQ(x) ((x) + 2) /* Int0-4 -> IRQ2-6 */
+
+#define icu1_read(offset) readw(icu1_base + (offset))
+#define icu1_write(offset, value) writew((value), icu1_base + (offset))
+
+#define icu2_read(offset) readw(icu2_base + (offset))
+#define icu2_write(offset, value) writew((value), icu2_base + (offset))
+
+#define INTASSIGN_MAX 4
+#define INTASSIGN_MASK 0x0007
+
+static inline uint16_t icu1_set(uint8_t offset, uint16_t set)
+{
+ uint16_t data;
+
+ data = icu1_read(offset);
+ data |= set;
+ icu1_write(offset, data);
+
+ return data;
+}
+
+static inline uint16_t icu1_clear(uint8_t offset, uint16_t clear)
+{
+ uint16_t data;
+
+ data = icu1_read(offset);
+ data &= ~clear;
+ icu1_write(offset, data);
+
+ return data;
+}
+
+static inline uint16_t icu2_set(uint8_t offset, uint16_t set)
+{
+ uint16_t data;
+
+ data = icu2_read(offset);
+ data |= set;
+ icu2_write(offset, data);
+
+ return data;
+}
+
+static inline uint16_t icu2_clear(uint8_t offset, uint16_t clear)
+{
+ uint16_t data;
+
+ data = icu2_read(offset);
+ data &= ~clear;
+ icu2_write(offset, data);
+
+ return data;
+}
+
+void vr41xx_enable_piuint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(PIU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_set(MPIUINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_enable_piuint);
+
+void vr41xx_disable_piuint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(PIU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_clear(MPIUINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_disable_piuint);
+
+void vr41xx_enable_aiuint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(AIU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_set(MAIUINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_enable_aiuint);
+
+void vr41xx_disable_aiuint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(AIU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_clear(MAIUINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_disable_aiuint);
+
+void vr41xx_enable_kiuint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(KIU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_set(MKIUINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_enable_kiuint);
+
+void vr41xx_disable_kiuint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(KIU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4111 ||
+ current_cpu_type() == CPU_VR4121) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_clear(MKIUINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_disable_kiuint);
+
+void vr41xx_enable_macint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_set(MMACINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_enable_macint);
+
+void vr41xx_disable_macint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(ETHERNET_IRQ);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_clear(MMACINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_disable_macint);
+
+void vr41xx_enable_dsiuint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(DSIU_IRQ);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_set(MDSIUINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_enable_dsiuint);
+
+void vr41xx_disable_dsiuint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(DSIU_IRQ);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu1_clear(MDSIUINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_disable_dsiuint);
+
+void vr41xx_enable_firint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(FIR_IRQ);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_set(MFIRINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_enable_firint);
+
+void vr41xx_disable_firint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(FIR_IRQ);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_clear(MFIRINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+}
+
+EXPORT_SYMBOL(vr41xx_disable_firint);
+
+void vr41xx_enable_pciint(void)
+{
+ struct irq_desc *desc = irq_to_desc(PCI_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4122 ||
+ current_cpu_type() == CPU_VR4131 ||
+ current_cpu_type() == CPU_VR4133) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_write(MPCIINTREG, PCIINT0);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_enable_pciint);
+
+void vr41xx_disable_pciint(void)
+{
+ struct irq_desc *desc = irq_to_desc(PCI_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4122 ||
+ current_cpu_type() == CPU_VR4131 ||
+ current_cpu_type() == CPU_VR4133) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_write(MPCIINTREG, 0);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_disable_pciint);
+
+void vr41xx_enable_scuint(void)
+{
+ struct irq_desc *desc = irq_to_desc(SCU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4122 ||
+ current_cpu_type() == CPU_VR4131 ||
+ current_cpu_type() == CPU_VR4133) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_write(MSCUINTREG, SCUINT0);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_enable_scuint);
+
+void vr41xx_disable_scuint(void)
+{
+ struct irq_desc *desc = irq_to_desc(SCU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4122 ||
+ current_cpu_type() == CPU_VR4131 ||
+ current_cpu_type() == CPU_VR4133) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_write(MSCUINTREG, 0);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_disable_scuint);
+
+void vr41xx_enable_csiint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(CSI_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4122 ||
+ current_cpu_type() == CPU_VR4131 ||
+ current_cpu_type() == CPU_VR4133) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_set(MCSIINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_enable_csiint);
+
+void vr41xx_disable_csiint(uint16_t mask)
+{
+ struct irq_desc *desc = irq_to_desc(CSI_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4122 ||
+ current_cpu_type() == CPU_VR4131 ||
+ current_cpu_type() == CPU_VR4133) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_clear(MCSIINTREG, mask);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_disable_csiint);
+
+void vr41xx_enable_bcuint(void)
+{
+ struct irq_desc *desc = irq_to_desc(BCU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4122 ||
+ current_cpu_type() == CPU_VR4131 ||
+ current_cpu_type() == CPU_VR4133) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_write(MBCUINTREG, BCUINTR);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_enable_bcuint);
+
+void vr41xx_disable_bcuint(void)
+{
+ struct irq_desc *desc = irq_to_desc(BCU_IRQ);
+ unsigned long flags;
+
+ if (current_cpu_type() == CPU_VR4122 ||
+ current_cpu_type() == CPU_VR4131 ||
+ current_cpu_type() == CPU_VR4133) {
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ icu2_write(MBCUINTREG, 0);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+EXPORT_SYMBOL(vr41xx_disable_bcuint);
+
+static void disable_sysint1_irq(struct irq_data *d)
+{
+ icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq));
+}
+
+static void enable_sysint1_irq(struct irq_data *d)
+{
+ icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(d->irq));
+}
+
+static struct irq_chip sysint1_irq_type = {
+ .name = "SYSINT1",
+ .irq_mask = disable_sysint1_irq,
+ .irq_unmask = enable_sysint1_irq,
+};
+
+static void disable_sysint2_irq(struct irq_data *d)
+{
+ icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq));
+}
+
+static void enable_sysint2_irq(struct irq_data *d)
+{
+ icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(d->irq));
+}
+
+static struct irq_chip sysint2_irq_type = {
+ .name = "SYSINT2",
+ .irq_mask = disable_sysint2_irq,
+ .irq_unmask = enable_sysint2_irq,
+};
+
+static inline int set_sysint1_assign(unsigned int irq, unsigned char assign)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ uint16_t intassign0, intassign1;
+ unsigned int pin;
+
+ pin = SYSINT1_IRQ_TO_PIN(irq);
+
+ raw_spin_lock_irq(&desc->lock);
+
+ intassign0 = icu1_read(INTASSIGN0);
+ intassign1 = icu1_read(INTASSIGN1);
+
+ switch (pin) {
+ case 0:
+ intassign0 &= ~INTASSIGN_MASK;
+ intassign0 |= (uint16_t)assign;
+ break;
+ case 1:
+ intassign0 &= ~(INTASSIGN_MASK << 3);
+ intassign0 |= (uint16_t)assign << 3;
+ break;
+ case 2:
+ intassign0 &= ~(INTASSIGN_MASK << 6);
+ intassign0 |= (uint16_t)assign << 6;
+ break;
+ case 3:
+ intassign0 &= ~(INTASSIGN_MASK << 9);
+ intassign0 |= (uint16_t)assign << 9;
+ break;
+ case 8:
+ intassign0 &= ~(INTASSIGN_MASK << 12);
+ intassign0 |= (uint16_t)assign << 12;
+ break;
+ case 9:
+ intassign1 &= ~INTASSIGN_MASK;
+ intassign1 |= (uint16_t)assign;
+ break;
+ case 11:
+ intassign1 &= ~(INTASSIGN_MASK << 6);
+ intassign1 |= (uint16_t)assign << 6;
+ break;
+ case 12:
+ intassign1 &= ~(INTASSIGN_MASK << 9);
+ intassign1 |= (uint16_t)assign << 9;
+ break;
+ default:
+ raw_spin_unlock_irq(&desc->lock);
+ return -EINVAL;
+ }
+
+ sysint1_assign[pin] = assign;
+ icu1_write(INTASSIGN0, intassign0);
+ icu1_write(INTASSIGN1, intassign1);
+
+ raw_spin_unlock_irq(&desc->lock);
+
+ return 0;
+}
+
+static inline int set_sysint2_assign(unsigned int irq, unsigned char assign)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ uint16_t intassign2, intassign3;
+ unsigned int pin;
+
+ pin = SYSINT2_IRQ_TO_PIN(irq);
+
+ raw_spin_lock_irq(&desc->lock);
+
+ intassign2 = icu1_read(INTASSIGN2);
+ intassign3 = icu1_read(INTASSIGN3);
+
+ switch (pin) {
+ case 0:
+ intassign2 &= ~INTASSIGN_MASK;
+ intassign2 |= (uint16_t)assign;
+ break;
+ case 1:
+ intassign2 &= ~(INTASSIGN_MASK << 3);
+ intassign2 |= (uint16_t)assign << 3;
+ break;
+ case 3:
+ intassign2 &= ~(INTASSIGN_MASK << 6);
+ intassign2 |= (uint16_t)assign << 6;
+ break;
+ case 4:
+ intassign2 &= ~(INTASSIGN_MASK << 9);
+ intassign2 |= (uint16_t)assign << 9;
+ break;
+ case 5:
+ intassign2 &= ~(INTASSIGN_MASK << 12);
+ intassign2 |= (uint16_t)assign << 12;
+ break;
+ case 6:
+ intassign3 &= ~INTASSIGN_MASK;
+ intassign3 |= (uint16_t)assign;
+ break;
+ case 7:
+ intassign3 &= ~(INTASSIGN_MASK << 3);
+ intassign3 |= (uint16_t)assign << 3;
+ break;
+ case 8:
+ intassign3 &= ~(INTASSIGN_MASK << 6);
+ intassign3 |= (uint16_t)assign << 6;
+ break;
+ case 9:
+ intassign3 &= ~(INTASSIGN_MASK << 9);
+ intassign3 |= (uint16_t)assign << 9;
+ break;
+ case 10:
+ intassign3 &= ~(INTASSIGN_MASK << 12);
+ intassign3 |= (uint16_t)assign << 12;
+ break;
+ default:
+ raw_spin_unlock_irq(&desc->lock);
+ return -EINVAL;
+ }
+
+ sysint2_assign[pin] = assign;
+ icu1_write(INTASSIGN2, intassign2);
+ icu1_write(INTASSIGN3, intassign3);
+
+ raw_spin_unlock_irq(&desc->lock);
+
+ return 0;
+}
+
+int vr41xx_set_intassign(unsigned int irq, unsigned char intassign)
+{
+ int retval = -EINVAL;
+
+ if (current_cpu_type() != CPU_VR4133)
+ return -EINVAL;
+
+ if (intassign > INTASSIGN_MAX)
+ return -EINVAL;
+
+ if (irq >= SYSINT1_IRQ_BASE && irq <= SYSINT1_IRQ_LAST)
+ retval = set_sysint1_assign(irq, intassign);
+ else if (irq >= SYSINT2_IRQ_BASE && irq <= SYSINT2_IRQ_LAST)
+ retval = set_sysint2_assign(irq, intassign);
+
+ return retval;
+}
+
+EXPORT_SYMBOL(vr41xx_set_intassign);
+
+static int icu_get_irq(unsigned int irq)
+{
+ uint16_t pend1, pend2;
+ uint16_t mask1, mask2;
+ int i;
+
+ pend1 = icu1_read(SYSINT1REG);
+ mask1 = icu1_read(MSYSINT1REG);
+
+ pend2 = icu2_read(SYSINT2REG);
+ mask2 = icu2_read(MSYSINT2REG);
+
+ mask1 &= pend1;
+ mask2 &= pend2;
+
+ if (mask1) {
+ for (i = 0; i < 16; i++) {
+ if (irq == INT_TO_IRQ(sysint1_assign[i]) && (mask1 & (1 << i)))
+ return SYSINT1_IRQ(i);
+ }
+ }
+
+ if (mask2) {
+ for (i = 0; i < 16; i++) {
+ if (irq == INT_TO_IRQ(sysint2_assign[i]) && (mask2 & (1 << i)))
+ return SYSINT2_IRQ(i);
+ }
+ }
+
+ printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2);
+
+ atomic_inc(&irq_err_count);
+
+ return -1;
+}
+
+static int __init vr41xx_icu_init(void)
+{
+ unsigned long icu1_start, icu2_start;
+ int i;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ icu1_start = ICU1_TYPE1_BASE;
+ icu2_start = ICU2_TYPE1_BASE;
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133:
+ icu1_start = ICU1_TYPE2_BASE;
+ icu2_start = ICU2_TYPE2_BASE;
+ break;
+ default:
+ printk(KERN_ERR "ICU: Unexpected CPU of NEC VR4100 series\n");
+ return -ENODEV;
+ }
+
+ if (request_mem_region(icu1_start, ICU1_SIZE, "ICU") == NULL)
+ return -EBUSY;
+
+ if (request_mem_region(icu2_start, ICU2_SIZE, "ICU") == NULL) {
+ release_mem_region(icu1_start, ICU1_SIZE);
+ return -EBUSY;
+ }
+
+ icu1_base = ioremap(icu1_start, ICU1_SIZE);
+ if (icu1_base == NULL) {
+ release_mem_region(icu1_start, ICU1_SIZE);
+ release_mem_region(icu2_start, ICU2_SIZE);
+ return -ENOMEM;
+ }
+
+ icu2_base = ioremap(icu2_start, ICU2_SIZE);
+ if (icu2_base == NULL) {
+ iounmap(icu1_base);
+ release_mem_region(icu1_start, ICU1_SIZE);
+ release_mem_region(icu2_start, ICU2_SIZE);
+ return -ENOMEM;
+ }
+
+ icu1_write(MSYSINT1REG, 0);
+ icu1_write(MGIUINTLREG, 0xffff);
+
+ icu2_write(MSYSINT2REG, 0);
+ icu2_write(MGIUINTHREG, 0xffff);
+
+ for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++)
+ irq_set_chip_and_handler(i, &sysint1_irq_type,
+ handle_level_irq);
+
+ for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++)
+ irq_set_chip_and_handler(i, &sysint2_irq_type,
+ handle_level_irq);
+
+ cascade_irq(INT0_IRQ, icu_get_irq);
+ cascade_irq(INT1_IRQ, icu_get_irq);
+ cascade_irq(INT2_IRQ, icu_get_irq);
+ cascade_irq(INT3_IRQ, icu_get_irq);
+ cascade_irq(INT4_IRQ, icu_get_irq);
+
+ return 0;
+}
+
+core_initcall(vr41xx_icu_init);
diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
new file mode 100644
index 00000000..23916321
--- /dev/null
+++ b/arch/mips/vr41xx/common/init.c
@@ -0,0 +1,77 @@
+/*
+ * init.c, Common initialization routines for NEC VR4100 series.
+ *
+ * Copyright (C) 2003-2009 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/vr41xx/irq.h>
+#include <asm/vr41xx/vr41xx.h>
+
+#define IO_MEM_RESOURCE_START 0UL
+#define IO_MEM_RESOURCE_END 0x1fffffffUL
+
+static void __init iomem_resource_init(void)
+{
+ iomem_resource.start = IO_MEM_RESOURCE_START;
+ iomem_resource.end = IO_MEM_RESOURCE_END;
+}
+
+void __init plat_time_init(void)
+{
+ unsigned long tclock;
+
+ vr41xx_calculate_clock_frequency();
+
+ tclock = vr41xx_get_tclock_frequency();
+ if (current_cpu_data.processor_id == PRID_VR4131_REV2_0 ||
+ current_cpu_data.processor_id == PRID_VR4131_REV2_1)
+ mips_hpt_frequency = tclock / 2;
+ else
+ mips_hpt_frequency = tclock / 4;
+}
+
+void __init plat_mem_setup(void)
+{
+ iomem_resource_init();
+
+ vr41xx_siu_setup();
+}
+
+void __init prom_init(void)
+{
+ int argc, i;
+ char **argv;
+
+ argc = fw_arg0;
+ argv = (char **)fw_arg1;
+
+ for (i = 1; i < argc; i++) {
+ strlcat(arcs_cmdline, argv[i], COMMAND_LINE_SIZE);
+ if (i < (argc - 1))
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
+ }
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
new file mode 100644
index 00000000..70a3b85f
--- /dev/null
+++ b/arch/mips/vr41xx/common/irq.c
@@ -0,0 +1,124 @@
+/*
+ * Interrupt handing routines for NEC VR4100 series.
+ *
+ * Copyright (C) 2005-2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/system.h>
+#include <asm/vr41xx/irq.h>
+
+typedef struct irq_cascade {
+ int (*get_irq)(unsigned int);
+} irq_cascade_t;
+
+static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned;
+
+static struct irqaction cascade_irqaction = {
+ .handler = no_action,
+ .name = "cascade",
+};
+
+int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int))
+{
+ int retval = 0;
+
+ if (irq >= NR_IRQS)
+ return -EINVAL;
+
+ if (irq_cascade[irq].get_irq != NULL)
+ free_irq(irq, NULL);
+
+ irq_cascade[irq].get_irq = get_irq;
+
+ if (get_irq != NULL) {
+ retval = setup_irq(irq, &cascade_irqaction);
+ if (retval < 0)
+ irq_cascade[irq].get_irq = NULL;
+ }
+
+ return retval;
+}
+
+EXPORT_SYMBOL_GPL(cascade_irq);
+
+static void irq_dispatch(unsigned int irq)
+{
+ irq_cascade_t *cascade;
+
+ if (irq >= NR_IRQS) {
+ atomic_inc(&irq_err_count);
+ return;
+ }
+
+ cascade = irq_cascade + irq;
+ if (cascade->get_irq != NULL) {
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_data *idata = irq_desc_get_irq_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ int ret;
+
+ if (chip->irq_mask_ack)
+ chip->irq_mask_ack(idata);
+ else {
+ chip->irq_mask(idata);
+ chip->irq_ack(idata);
+ }
+ ret = cascade->get_irq(irq);
+ irq = ret;
+ if (ret < 0)
+ atomic_inc(&irq_err_count);
+ else
+ irq_dispatch(irq);
+ if (!irqd_irq_disabled(idata) && chip->irq_unmask)
+ chip->irq_unmask(idata);
+ } else
+ do_IRQ(irq);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+ if (pending & CAUSEF_IP7)
+ do_IRQ(TIMER_IRQ);
+ else if (pending & 0x7800) {
+ if (pending & CAUSEF_IP3)
+ irq_dispatch(INT1_IRQ);
+ else if (pending & CAUSEF_IP4)
+ irq_dispatch(INT2_IRQ);
+ else if (pending & CAUSEF_IP5)
+ irq_dispatch(INT3_IRQ);
+ else if (pending & CAUSEF_IP6)
+ irq_dispatch(INT4_IRQ);
+ } else if (pending & CAUSEF_IP2)
+ irq_dispatch(INT0_IRQ);
+ else if (pending & CAUSEF_IP0)
+ do_IRQ(MIPS_SOFTINT0_IRQ);
+ else if (pending & CAUSEF_IP1)
+ do_IRQ(MIPS_SOFTINT1_IRQ);
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+}
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c
new file mode 100644
index 00000000..692b4e85
--- /dev/null
+++ b/arch/mips/vr41xx/common/pmu.c
@@ -0,0 +1,135 @@
+/*
+ * pmu.c, Power Management Unit routines for NEC VR4100 series.
+ *
+ * Copyright (C) 2003-2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+#define PMU_TYPE1_BASE 0x0b0000a0UL
+#define PMU_TYPE1_SIZE 0x0eUL
+
+#define PMU_TYPE2_BASE 0x0f0000c0UL
+#define PMU_TYPE2_SIZE 0x10UL
+
+#define PMUCNT2REG 0x06
+ #define SOFTRST 0x0010
+
+static void __iomem *pmu_base;
+
+#define pmu_read(offset) readw(pmu_base + (offset))
+#define pmu_write(offset, value) writew((value), pmu_base + (offset))
+
+static void vr41xx_cpu_wait(void)
+{
+ local_irq_disable();
+ if (!need_resched())
+ /*
+ * "standby" sets IE bit of the CP0_STATUS to 1.
+ */
+ __asm__("standby;\n");
+ else
+ local_irq_enable();
+}
+
+static inline void software_reset(void)
+{
+ uint16_t pmucnt2;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133:
+ pmucnt2 = pmu_read(PMUCNT2REG);
+ pmucnt2 |= SOFTRST;
+ pmu_write(PMUCNT2REG, pmucnt2);
+ break;
+ default:
+ set_c0_status(ST0_BEV | ST0_ERL);
+ change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+ flush_cache_all();
+ write_c0_wired(0);
+ __asm__("jr %0"::"r"(0xbfc00000));
+ break;
+ }
+}
+
+static void vr41xx_restart(char *command)
+{
+ local_irq_disable();
+ software_reset();
+ while (1) ;
+}
+
+static void vr41xx_halt(void)
+{
+ local_irq_disable();
+ printk(KERN_NOTICE "\nYou can turn off the power supply\n");
+ __asm__("hibernate;\n");
+}
+
+static int __init vr41xx_pmu_init(void)
+{
+ unsigned long start, size;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ start = PMU_TYPE1_BASE;
+ size = PMU_TYPE1_SIZE;
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133:
+ start = PMU_TYPE2_BASE;
+ size = PMU_TYPE2_SIZE;
+ break;
+ default:
+ printk("Unexpected CPU of NEC VR4100 series\n");
+ return -ENODEV;
+ }
+
+ if (request_mem_region(start, size, "PMU") == NULL)
+ return -EBUSY;
+
+ pmu_base = ioremap(start, size);
+ if (pmu_base == NULL) {
+ release_mem_region(start, size);
+ return -EBUSY;
+ }
+
+ cpu_wait = vr41xx_cpu_wait;
+ _machine_restart = vr41xx_restart;
+ _machine_halt = vr41xx_halt;
+ pm_power_off = vr41xx_halt;
+
+ return 0;
+}
+
+core_initcall(vr41xx_pmu_init);
diff --git a/arch/mips/vr41xx/common/rtc.c b/arch/mips/vr41xx/common/rtc.c
new file mode 100644
index 00000000..ebc5dcf0
--- /dev/null
+++ b/arch/mips/vr41xx/common/rtc.c
@@ -0,0 +1,117 @@
+/*
+ * NEC VR4100 series RTC platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/irq.h>
+
+static struct resource rtc_type1_resource[] __initdata = {
+ {
+ .start = 0x0b0000c0,
+ .end = 0x0b0000df,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x0b0001c0,
+ .end = 0x0b0001df,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = ELAPSEDTIME_IRQ,
+ .end = ELAPSEDTIME_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = RTCLONG1_IRQ,
+ .end = RTCLONG1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource rtc_type2_resource[] __initdata = {
+ {
+ .start = 0x0f000100,
+ .end = 0x0f00011f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x0f000120,
+ .end = 0x0f00013f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = ELAPSEDTIME_IRQ,
+ .end = ELAPSEDTIME_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = RTCLONG1_IRQ,
+ .end = RTCLONG1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int __init vr41xx_rtc_add(void)
+{
+ struct platform_device *pdev;
+ struct resource *res;
+ unsigned int num;
+ int retval;
+
+ pdev = platform_device_alloc("RTC", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ res = rtc_type1_resource;
+ num = ARRAY_SIZE(rtc_type1_resource);
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133:
+ res = rtc_type2_resource;
+ num = ARRAY_SIZE(rtc_type2_resource);
+ break;
+ default:
+ retval = -ENODEV;
+ goto err_free_device;
+ }
+
+ retval = platform_device_add_resources(pdev, res, num);
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(vr41xx_rtc_add);
diff --git a/arch/mips/vr41xx/common/siu.c b/arch/mips/vr41xx/common/siu.c
new file mode 100644
index 00000000..bbd45d25
--- /dev/null
+++ b/arch/mips/vr41xx/common/siu.c
@@ -0,0 +1,155 @@
+/*
+ * NEC VR4100 series SIU platform device.
+ *
+ * Copyright (C) 2007-2008 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/irq.h>
+
+#include <asm/cpu.h>
+#include <asm/vr41xx/siu.h>
+
+static unsigned int siu_type1_ports[SIU_PORTS_MAX] __initdata = {
+ PORT_VR41XX_SIU,
+ PORT_UNKNOWN,
+};
+
+static struct resource siu_type1_resource[] __initdata = {
+ {
+ .start = 0x0c000000,
+ .end = 0x0c00000a,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = SIU_IRQ,
+ .end = SIU_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static unsigned int siu_type2_ports[SIU_PORTS_MAX] __initdata = {
+ PORT_VR41XX_SIU,
+ PORT_VR41XX_DSIU,
+};
+
+static struct resource siu_type2_resource[] __initdata = {
+ {
+ .start = 0x0f000800,
+ .end = 0x0f00080a,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x0f000820,
+ .end = 0x0f000829,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = SIU_IRQ,
+ .end = SIU_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = DSIU_IRQ,
+ .end = DSIU_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int __init vr41xx_siu_add(void)
+{
+ struct platform_device *pdev;
+ struct resource *res;
+ unsigned int num;
+ int retval;
+
+ pdev = platform_device_alloc("SIU", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ pdev->dev.platform_data = siu_type1_ports;
+ res = siu_type1_resource;
+ num = ARRAY_SIZE(siu_type1_resource);
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133:
+ pdev->dev.platform_data = siu_type2_ports;
+ res = siu_type2_resource;
+ num = ARRAY_SIZE(siu_type2_resource);
+ break;
+ default:
+ retval = -ENODEV;
+ goto err_free_device;
+ }
+
+ retval = platform_device_add_resources(pdev, res, num);
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(vr41xx_siu_add);
+
+void __init vr41xx_siu_setup(void)
+{
+ struct uart_port port;
+ struct resource *res;
+ unsigned int *type;
+ int i;
+
+ switch (current_cpu_type()) {
+ case CPU_VR4111:
+ case CPU_VR4121:
+ type = siu_type1_ports;
+ res = siu_type1_resource;
+ break;
+ case CPU_VR4122:
+ case CPU_VR4131:
+ case CPU_VR4133:
+ type = siu_type2_ports;
+ res = siu_type2_resource;
+ break;
+ default:
+ return;
+ }
+
+ for (i = 0; i < SIU_PORTS_MAX; i++) {
+ port.line = i;
+ port.type = type[i];
+ if (port.type == PORT_UNKNOWN)
+ break;
+ port.mapbase = res[i].start;
+ port.membase = (unsigned char __iomem *)KSEG1ADDR(res[i].start);
+ vr41xx_siu_early_setup(&port);
+ }
+}
diff --git a/arch/mips/vr41xx/common/type.c b/arch/mips/vr41xx/common/type.c
new file mode 100644
index 00000000..ff841422
--- /dev/null
+++ b/arch/mips/vr41xx/common/type.c
@@ -0,0 +1,24 @@
+/*
+ * type.c, System type for NEC VR4100 series.
+ *
+ * Copyright (C) 2005 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+const char *get_system_type(void)
+{
+ return "NEC VR4100 series";
+}
diff --git a/arch/mips/vr41xx/ibm-workpad/Makefile b/arch/mips/vr41xx/ibm-workpad/Makefile
new file mode 100644
index 00000000..5ffaff0f
--- /dev/null
+++ b/arch/mips/vr41xx/ibm-workpad/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the IBM WorkPad z50 specific parts of the kernel
+#
+
+obj-y += setup.o
diff --git a/arch/mips/vr41xx/ibm-workpad/setup.c b/arch/mips/vr41xx/ibm-workpad/setup.c
new file mode 100644
index 00000000..3982f378
--- /dev/null
+++ b/arch/mips/vr41xx/ibm-workpad/setup.c
@@ -0,0 +1,40 @@
+/*
+ * setup.c, Setup for the IBM WorkPad z50.
+ *
+ * Copyright (C) 2002-2006 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+
+#define WORKPAD_ISA_IO_BASE 0x15000000
+#define WORKPAD_ISA_IO_SIZE 0x03000000
+#define WORKPAD_ISA_IO_START 0
+#define WORKPAD_ISA_IO_END (WORKPAD_ISA_IO_SIZE - 1)
+#define WORKPAD_IO_PORT_BASE KSEG1ADDR(WORKPAD_ISA_IO_BASE)
+
+static int __init ibm_workpad_setup(void)
+{
+ set_io_port_base(WORKPAD_IO_PORT_BASE);
+ ioport_resource.start = WORKPAD_ISA_IO_START;
+ ioport_resource.end = WORKPAD_ISA_IO_END;
+
+ return 0;
+}
+
+arch_initcall(ibm_workpad_setup);
diff --git a/arch/mips/wrppmc/Makefile b/arch/mips/wrppmc/Makefile
new file mode 100644
index 00000000..307cc692
--- /dev/null
+++ b/arch/mips/wrppmc/Makefile
@@ -0,0 +1,12 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright 2006 Wind River System, Inc.
+# Author: Rongkai.Zhan <rongkai.zhan@windriver.com>
+#
+# Makefile for the Wind River MIPS 4Kc PPMC Eval Board
+#
+
+obj-y += irq.o pci.o reset.o serial.o setup.o time.o
diff --git a/arch/mips/wrppmc/Platform b/arch/mips/wrppmc/Platform
new file mode 100644
index 00000000..e758645e
--- /dev/null
+++ b/arch/mips/wrppmc/Platform
@@ -0,0 +1,7 @@
+#
+# Wind River PPMC Board (4KC + GT64120)
+#
+platform-$(CONFIG_WR_PPMC) += wrppmc/
+cflags-$(CONFIG_WR_PPMC) += \
+ -I$(srctree)/arch/mips/include/asm/mach-wrppmc
+load-$(CONFIG_WR_PPMC) += 0xffffffff80100000
diff --git a/arch/mips/wrppmc/irq.c b/arch/mips/wrppmc/irq.c
new file mode 100644
index 00000000..c6e70627
--- /dev/null
+++ b/arch/mips/wrppmc/irq.c
@@ -0,0 +1,56 @@
+/*
+ * irq.c: GT64120 Interrupt Controller
+ *
+ * Copyright (C) 2006, Wind River System Inc.
+ * Author: Rongkai.Zhan, <rongkai.zhan@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/hardirq.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/gt64120.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP7)
+ do_IRQ(WRPPMC_MIPS_TIMER_IRQ); /* CPU Compare/Count internal timer */
+ else if (pending & STATUSF_IP6)
+ do_IRQ(WRPPMC_UART16550_IRQ); /* UART 16550 port */
+ else if (pending & STATUSF_IP3)
+ do_IRQ(WRPPMC_PCI_INTA_IRQ); /* PCI INT_A */
+ else
+ spurious_interrupt();
+}
+
+/**
+ * Initialize GT64120 Interrupt Controller
+ */
+void gt64120_init_pic(void)
+{
+ /* clear CPU Interrupt Cause Registers */
+ GT_WRITE(GT_INTRCAUSE_OFS, (0x1F << 21));
+ GT_WRITE(GT_HINTRCAUSE_OFS, 0x00);
+
+ /* Disable all interrupts from GT64120 bridge chip */
+ GT_WRITE(GT_INTRMASK_OFS, 0x00);
+ GT_WRITE(GT_HINTRMASK_OFS, 0x00);
+ GT_WRITE(GT_PCI0_ICMASK_OFS, 0x00);
+ GT_WRITE(GT_PCI0_HICMASK_OFS, 0x00);
+}
+
+void __init arch_init_irq(void)
+{
+ /* IRQ 0 - 7 are for MIPS common irq_cpu controller */
+ mips_cpu_irq_init();
+
+ gt64120_init_pic();
+}
diff --git a/arch/mips/wrppmc/pci.c b/arch/mips/wrppmc/pci.c
new file mode 100644
index 00000000..d06192fa
--- /dev/null
+++ b/arch/mips/wrppmc/pci.c
@@ -0,0 +1,54 @@
+/*
+ * pci.c: GT64120 PCI support.
+ *
+ * Copyright (C) 2006, Wind River System Inc. Rongkai.Zhan <rongkai.zhan@windriver.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/gt64120.h>
+
+extern struct pci_ops gt64xxx_pci0_ops;
+
+static struct resource pci0_io_resource = {
+ .name = "pci_0 io",
+ .start = GT_PCI_IO_BASE,
+ .end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource pci0_mem_resource = {
+ .name = "pci_0 memory",
+ .start = GT_PCI_MEM_BASE,
+ .end = GT_PCI_MEM_BASE + GT_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct pci_controller hose_0 = {
+ .pci_ops = &gt64xxx_pci0_ops,
+ .io_resource = &pci0_io_resource,
+ .mem_resource = &pci0_mem_resource,
+};
+
+static int __init gt64120_pci_init(void)
+{
+ u32 tmp;
+
+ tmp = GT_READ(GT_PCI0_CMD_OFS); /* Huh??? -- Ralf */
+ tmp = GT_READ(GT_PCI0_BARE_OFS);
+
+ /* reset the whole PCI I/O space range */
+ ioport_resource.start = GT_PCI_IO_BASE;
+ ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1;
+
+ register_pci_controller(&hose_0);
+ return 0;
+}
+
+arch_initcall(gt64120_pci_init);
diff --git a/arch/mips/wrppmc/reset.c b/arch/mips/wrppmc/reset.c
new file mode 100644
index 00000000..cc5474b2
--- /dev/null
+++ b/arch/mips/wrppmc/reset.c
@@ -0,0 +1,40 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1997 Ralf Baechle
+ */
+#include <linux/irqflags.h>
+#include <linux/kernel.h>
+
+#include <asm/cacheflush.h>
+#include <asm/mipsregs.h>
+#include <asm/processor.h>
+
+void wrppmc_machine_restart(char *command)
+{
+ /*
+ * Ouch, we're still alive ... This time we take the silver bullet ...
+ * ... and find that we leave the hardware in a state in which the
+ * kernel in the flush locks up somewhen during of after the PCI
+ * detection stuff.
+ */
+ local_irq_disable();
+ set_c0_status(ST0_BEV | ST0_ERL);
+ change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+ flush_cache_all();
+ write_c0_wired(0);
+ __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+void wrppmc_machine_halt(void)
+{
+ local_irq_disable();
+
+ printk(KERN_NOTICE "You can safely turn off the power\n");
+ while (1) {
+ if (cpu_wait)
+ cpu_wait();
+ }
+}
diff --git a/arch/mips/wrppmc/serial.c b/arch/mips/wrppmc/serial.c
new file mode 100644
index 00000000..6f9d0858
--- /dev/null
+++ b/arch/mips/wrppmc/serial.c
@@ -0,0 +1,80 @@
+/*
+ * Registration of WRPPMC UART platform device.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/gt64120.h>
+
+static struct resource wrppmc_uart_resource[] __initdata = {
+ {
+ .start = WRPPMC_UART16550_BASE,
+ .end = WRPPMC_UART16550_BASE + 7,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = WRPPMC_UART16550_IRQ,
+ .end = WRPPMC_UART16550_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct plat_serial8250_port wrppmc_serial8250_port[] = {
+ {
+ .irq = WRPPMC_UART16550_IRQ,
+ .uartclk = WRPPMC_UART16550_CLOCK,
+ .iotype = UPIO_MEM,
+ .flags = UPF_IOREMAP | UPF_SKIP_TEST,
+ .mapbase = WRPPMC_UART16550_BASE,
+ },
+ {},
+};
+
+static __init int wrppmc_uart_add(void)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ pdev = platform_device_alloc("serial8250", -1);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->id = PLAT8250_DEV_PLATFORM;
+ pdev->dev.platform_data = wrppmc_serial8250_port;
+
+ retval = platform_device_add_resources(pdev, wrppmc_uart_resource,
+ ARRAY_SIZE(wrppmc_uart_resource));
+ if (retval)
+ goto err_free_device;
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto err_free_device;
+
+ return 0;
+
+err_free_device:
+ platform_device_put(pdev);
+
+ return retval;
+}
+device_initcall(wrppmc_uart_add);
diff --git a/arch/mips/wrppmc/setup.c b/arch/mips/wrppmc/setup.c
new file mode 100644
index 00000000..ca65c840
--- /dev/null
+++ b/arch/mips/wrppmc/setup.c
@@ -0,0 +1,128 @@
+/*
+ * setup.c: Setup pointers to hardware dependent routines.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006, Wind River System Inc. Rongkai.zhan <rongkai.zhan@windriver.com>
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/gt64120.h>
+
+unsigned long gt64120_base = KSEG1ADDR(0x14000000);
+
+#ifdef WRPPMC_EARLY_DEBUG
+
+static volatile unsigned char * wrppmc_led = \
+ (volatile unsigned char *)KSEG1ADDR(WRPPMC_LED_BASE);
+
+/*
+ * PPMC LED control register:
+ * -) bit[0] controls DS1 LED (1 - OFF, 0 - ON)
+ * -) bit[1] controls DS2 LED (1 - OFF, 0 - ON)
+ * -) bit[2] controls DS4 LED (1 - OFF, 0 - ON)
+ */
+void wrppmc_led_on(int mask)
+{
+ unsigned char value = *wrppmc_led;
+
+ value &= (0xF8 | mask);
+ *wrppmc_led = value;
+}
+
+/* If mask = 0, turn off all LEDs */
+void wrppmc_led_off(int mask)
+{
+ unsigned char value = *wrppmc_led;
+
+ value |= (0x7 & mask);
+ *wrppmc_led = value;
+}
+
+/*
+ * We assume that bootloader has initialized UART16550 correctly
+ */
+void __init wrppmc_early_putc(char ch)
+{
+ static volatile unsigned char *wrppmc_uart = \
+ (volatile unsigned char *)KSEG1ADDR(WRPPMC_UART16550_BASE);
+ unsigned char value;
+
+ /* Wait until Transmit-Holding-Register is empty */
+ while (1) {
+ value = *(wrppmc_uart + 5);
+ if (value & 0x20)
+ break;
+ }
+
+ *wrppmc_uart = ch;
+}
+
+void __init wrppmc_early_printk(const char *fmt, ...)
+{
+ static char pbuf[256] = {'\0', };
+ char *ch = pbuf;
+ va_list args;
+ unsigned int i;
+
+ memset(pbuf, 0, 256);
+ va_start(args, fmt);
+ i = vsprintf(pbuf, fmt, args);
+ va_end(args);
+
+ /* Print the string */
+ while (*ch != '\0') {
+ wrppmc_early_putc(*ch);
+ /* if print '\n', also print '\r' */
+ if (*ch++ == '\n')
+ wrppmc_early_putc('\r');
+ }
+}
+#endif /* WRPPMC_EARLY_DEBUG */
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init plat_mem_setup(void)
+{
+ extern void wrppmc_machine_restart(char *command);
+ extern void wrppmc_machine_halt(void);
+
+ _machine_restart = wrppmc_machine_restart;
+ _machine_halt = wrppmc_machine_halt;
+ pm_power_off = wrppmc_machine_halt;
+
+ /* This makes the operations of 'in/out[bwl]' to the
+ * physical address ( < KSEG0) can work via KSEG1
+ */
+ set_io_port_base(KSEG1);
+}
+
+const char *get_system_type(void)
+{
+ return "Wind River PPMC (GT64120)";
+}
+
+/*
+ * Initializes basic routines and structures pointers, memory size (as
+ * given by the bios and saves the command line.
+ */
+void __init prom_init(void)
+{
+ add_memory_region(WRPPMC_SDRAM_SCS0_BASE, WRPPMC_SDRAM_SCS0_SIZE, BOOT_MEM_RAM);
+ add_memory_region(WRPPMC_BOOTROM_BASE, WRPPMC_BOOTROM_SIZE, BOOT_MEM_ROM_DATA);
+
+ wrppmc_early_printk("prom_init: GT64120 SDRAM Bank 0: 0x%x - 0x%08lx\n",
+ WRPPMC_SDRAM_SCS0_BASE, (WRPPMC_SDRAM_SCS0_BASE + WRPPMC_SDRAM_SCS0_SIZE));
+}
diff --git a/arch/mips/wrppmc/time.c b/arch/mips/wrppmc/time.c
new file mode 100644
index 00000000..668dbd5f
--- /dev/null
+++ b/arch/mips/wrppmc/time.c
@@ -0,0 +1,39 @@
+/*
+ * time.c: MIPS CPU Count/Compare timer hookup
+ *
+ * Author: Mark.Zhan, <rongkai.zhan@windriver.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2006, Wind River System Inc.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/gt64120.h>
+#include <asm/time.h>
+
+#define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */
+
+/*
+ * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect
+ *
+ * NOTE: We disable all GT64120 timers, and use MIPS processor internal
+ * timer as the source of kernel clock tick.
+ */
+void __init plat_time_init(void)
+{
+ /* Disable GT64120 timers */
+ GT_WRITE(GT_TC_CONTROL_OFS, 0x00);
+ GT_WRITE(GT_TC0_OFS, 0x00);
+ GT_WRITE(GT_TC1_OFS, 0x00);
+ GT_WRITE(GT_TC2_OFS, 0x00);
+ GT_WRITE(GT_TC3_OFS, 0x00);
+
+ /* Use MIPS compare/count internal timer */
+ mips_hpt_frequency = WRPPMC_CPU_CLK_FREQ;
+}