aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 20:56:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-11 20:56:37 -0500
commitc0222ac086669a631814bbf857f8c8023452a4d7 (patch)
treebb1d9908031fcf69016eeefa7b35a4f68f414333 /arch/mips
parent140cd7fb04a4a2bc09a30980bc8104cc89e09330 (diff)
parente2965cd0003f222bd49f67907c2bc6ed691c6d20 (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle: "This is an unusually large pull request for MIPS - in parts because lots of patches missed the 3.18 deadline but primarily because some folks opened the flood gates. - Retire the MIPS-specific phys_t with the generic phys_addr_t. - Improvments for the backtrace code used by oprofile. - Better backtraces on SMP systems. - Cleanups for the Octeon platform code. - Cleanups and fixes for the Loongson platform code. - Cleanups and fixes to the firmware library. - Switch ATH79 platform to use the firmware library. - Grand overhault to the SEAD3 and Malta interrupt code. - Move the GIC interrupt code to drivers/irqchip - Lots of GIC cleanups and updates to the GIC code to use modern IRQ infrastructures and features of the kernel. - OF documentation updates for the GIC bindings - Move GIC clocksource driver to drivers/clocksource - Merge GIC clocksource driver with clockevent driver. - Further updates to bring the GIC clocksource driver up to date. - R3000 TLB code cleanups - Improvments to the Loongson 3 platform code. - Convert pr_warning to pr_warn. - Merge a bunch of small lantiq and ralink fixes that have been staged/lingering inside the openwrt tree for a while. - Update archhelp for IP22/IP32 - Fix a number of issues for Loongson 1B. - New clocksource and clockevent driver for Loongson 1B. - Further work on clk handling for Loongson 1B. - Platform work for Broadcom BMIPS. - Error handling cleanups for TurboChannel. - Fixes and optimization to the microMIPS support. - Option to disable the FTLB. - Dump more relevant information on machine check exception - Change binfmt to allow arch to examine PT_*PROC headers - Support for new style FPU register model in O32 - VDSO randomization. - BCM47xx cleanups - BCM47xx reimplement the way the kernel accesses NVRAM information. - Random cleanups - Add support for ATH25 platforms - Remove pointless locking code in some PCI platforms. - Some improvments to EVA support - Minor Alchemy cleanup" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (185 commits) MIPS: Add MFHC0 and MTHC0 instructions to uasm. MIPS: Cosmetic cleanups of page table headers. MIPS: Add CP0 macros for extended EntryLo registers MIPS: Remove now unused definition of phys_t. MIPS: Replace use of phys_t with phys_addr_t. MIPS: Replace MIPS-specific 64BIT_PHYS_ADDR with generic PHYS_ADDR_T_64BIT PCMCIA: Alchemy Don't select 64BIT_PHYS_ADDR in Kconfig. MIPS: lib: memset: Clean up some MIPS{EL,EB} ifdefery MIPS: iomap: Use __mem_{read,write}{b,w,l} for MMIO MIPS: <asm/types.h> fix indentation. MAINTAINERS: Add entry for BMIPS multiplatform kernel MIPS: Enable VDSO randomization MIPS: Remove a temporary hack for debugging cache flushes in SMTC configuration MIPS: Remove declaration of obsolete arch_init_clk_ops() MIPS: atomic.h: Reformat to fit in 79 columns MIPS: Apply `.insn' to fixup labels throughout MIPS: Fix microMIPS LL/SC immediate offsets MIPS: Kconfig: Only allow 32-bit microMIPS builds MIPS: signal.c: Fix an invalid cast in ISA mode bit handling MIPS: mm: Only build one microassembler that is suitable ...
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Kbuild.platforms2
-rw-r--r--arch/mips/Kconfig98
-rw-r--r--arch/mips/Kconfig.debug13
-rw-r--r--arch/mips/Makefile1
-rw-r--r--arch/mips/alchemy/common/clock.c7
-rw-r--r--arch/mips/alchemy/common/setup.c6
-rw-r--r--arch/mips/ar7/platform.c24
-rw-r--r--arch/mips/ath25/Kconfig16
-rw-r--r--arch/mips/ath25/Makefile16
-rw-r--r--arch/mips/ath25/Platform6
-rw-r--r--arch/mips/ath25/ar2315.c364
-rw-r--r--arch/mips/ath25/ar2315.h22
-rw-r--r--arch/mips/ath25/ar2315_regs.h410
-rw-r--r--arch/mips/ath25/ar5312.c393
-rw-r--r--arch/mips/ath25/ar5312.h22
-rw-r--r--arch/mips/ath25/ar5312_regs.h224
-rw-r--r--arch/mips/ath25/board.c234
-rw-r--r--arch/mips/ath25/devices.c125
-rw-r--r--arch/mips/ath25/devices.h43
-rw-r--r--arch/mips/ath25/early_printk.c44
-rw-r--r--arch/mips/ath25/prom.c26
-rw-r--r--arch/mips/ath79/irq.c1
-rw-r--r--arch/mips/ath79/prom.c38
-rw-r--r--arch/mips/ath79/setup.c5
-rw-r--r--arch/mips/bcm3384/Makefile1
-rw-r--r--arch/mips/bcm3384/Platform7
-rw-r--r--arch/mips/bcm3384/dma.c81
-rw-r--r--arch/mips/bcm3384/irq.c193
-rw-r--r--arch/mips/bcm3384/setup.c97
-rw-r--r--arch/mips/bcm47xx/bcm47xx_private.h6
-rw-r--r--arch/mips/bcm47xx/irq.c8
-rw-r--r--arch/mips/bcm47xx/nvram.c155
-rw-r--r--arch/mips/bcm47xx/setup.c91
-rw-r--r--arch/mips/bcm47xx/sprom.c82
-rw-r--r--arch/mips/bcm63xx/cpu.c2
-rw-r--r--arch/mips/boot/dts/Makefile1
-rw-r--r--arch/mips/boot/dts/bcm3384.dtsi109
-rw-r--r--arch/mips/boot/dts/bcm93384wvg.dts32
-rw-r--r--arch/mips/cavium-octeon/dma-octeon.c4
-rw-r--r--arch/mips/cavium-octeon/executive/octeon-model.c49
-rw-r--r--arch/mips/configs/bcm3384_defconfig78
-rw-r--r--arch/mips/fw/lib/cmdline.c8
-rw-r--r--arch/mips/include/asm/atomic.h374
-rw-r--r--arch/mips/include/asm/bitops.h35
-rw-r--r--arch/mips/include/asm/bmips.h1
-rw-r--r--arch/mips/include/asm/bootinfo.h13
-rw-r--r--arch/mips/include/asm/clock.h3
-rw-r--r--arch/mips/include/asm/cmpxchg.h27
-rw-r--r--arch/mips/include/asm/compiler.h8
-rw-r--r--arch/mips/include/asm/cpu-features.h4
-rw-r--r--arch/mips/include/asm/cpu.h2
-rw-r--r--arch/mips/include/asm/edac.h6
-rw-r--r--arch/mips/include/asm/elf.h74
-rw-r--r--arch/mips/include/asm/fpu.h49
-rw-r--r--arch/mips/include/asm/futex.h27
-rw-r--r--arch/mips/include/asm/gic.h384
-rw-r--r--arch/mips/include/asm/hpet.h73
-rw-r--r--arch/mips/include/asm/io.h8
-rw-r--r--arch/mips/include/asm/irq.h3
-rw-r--r--arch/mips/include/asm/irq_cpu.h4
-rw-r--r--arch/mips/include/asm/mach-ath25/ath25_platform.h73
-rw-r--r--arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h64
-rw-r--r--arch/mips/include/asm/mach-ath25/dma-coherence.h82
-rw-r--r--arch/mips/include/asm/mach-ath25/gpio.h16
-rw-r--r--arch/mips/include/asm/mach-ath25/war.h25
-rw-r--r--arch/mips/include/asm/mach-au1x00/ioremap.h10
-rw-r--r--arch/mips/include/asm/mach-bcm3384/dma-coherence.h48
-rw-r--r--arch/mips/include/asm/mach-bcm3384/war.h24
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h36
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/ioremap.h6
-rw-r--r--arch/mips/include/asm/mach-generic/ioremap.h4
-rw-r--r--arch/mips/include/asm/mach-generic/irq.h6
-rw-r--r--arch/mips/include/asm/mach-lantiq/lantiq.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/boot_param.h49
-rw-r--r--arch/mips/include/asm/mach-loongson/dma-coherence.h6
-rw-r--r--arch/mips/include/asm/mach-loongson/irq.h3
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson_hwmon.h55
-rw-r--r--arch/mips/include/asm/mach-loongson/machine.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/topology.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/workarounds.h7
-rw-r--r--arch/mips/include/asm/mach-loongson1/cpufreq.h23
-rw-r--r--arch/mips/include/asm/mach-loongson1/loongson1.h8
-rw-r--r--arch/mips/include/asm/mach-loongson1/platform.h10
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-clk.h23
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-mux.h67
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-pwm.h29
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-wdt.h11
-rw-r--r--arch/mips/include/asm/mach-malta/irq.h1
-rw-r--r--arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h25
-rw-r--r--arch/mips/include/asm/mach-ralink/mt7620.h64
-rw-r--r--arch/mips/include/asm/mach-ralink/pinmux.h55
-rw-r--r--arch/mips/include/asm/mach-ralink/ralink_regs.h7
-rw-r--r--arch/mips/include/asm/mach-ralink/rt305x.h35
-rw-r--r--arch/mips/include/asm/mach-ralink/rt3883.h16
-rw-r--r--arch/mips/include/asm/mach-sead3/irq.h1
-rw-r--r--arch/mips/include/asm/mach-tx39xx/ioremap.h4
-rw-r--r--arch/mips/include/asm/mach-tx49xx/ioremap.h4
-rw-r--r--arch/mips/include/asm/mips-boards/maltaint.h24
-rw-r--r--arch/mips/include/asm/mips-boards/sead3int.h15
-rw-r--r--arch/mips/include/asm/mips-cm.h2
-rw-r--r--arch/mips/include/asm/mips-cpc.h4
-rw-r--r--arch/mips/include/asm/mipsregs.h43
-rw-r--r--arch/mips/include/asm/octeon/cvmx-cmd-queue.h4
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pow.h69
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h63
-rw-r--r--arch/mips/include/asm/octeon/octeon-feature.h52
-rw-r--r--arch/mips/include/asm/octeon/octeon-model.h3
-rw-r--r--arch/mips/include/asm/paccess.h2
-rw-r--r--arch/mips/include/asm/page.h2
-rw-r--r--arch/mips/include/asm/pci.h2
-rw-r--r--arch/mips/include/asm/pgtable-32.h104
-rw-r--r--arch/mips/include/asm/pgtable-bits.h36
-rw-r--r--arch/mips/include/asm/pgtable.h18
-rw-r--r--arch/mips/include/asm/prom.h1
-rw-r--r--arch/mips/include/asm/r4kcache.h59
-rw-r--r--arch/mips/include/asm/spinlock.h50
-rw-r--r--arch/mips/include/asm/thread_info.h2
-rw-r--r--arch/mips/include/asm/time.h6
-rw-r--r--arch/mips/include/asm/types.h18
-rw-r--r--arch/mips/include/asm/uaccess.h27
-rw-r--r--arch/mips/include/asm/uasm.h2
-rw-r--r--arch/mips/include/uapi/asm/inst.h7
-rw-r--r--arch/mips/jz4740/setup.c2
-rw-r--r--arch/mips/kernel/Makefile10
-rw-r--r--arch/mips/kernel/cevt-gic.c105
-rw-r--r--arch/mips/kernel/cevt-r4k.c6
-rw-r--r--arch/mips/kernel/cpu-probe.c71
-rw-r--r--arch/mips/kernel/crash_dump.c4
-rw-r--r--arch/mips/kernel/csrc-gic.c40
-rw-r--r--arch/mips/kernel/elf.c191
-rw-r--r--arch/mips/kernel/i8259.c24
-rw-r--r--arch/mips/kernel/irq-gic.c402
-rw-r--r--arch/mips/kernel/irq_cpu.c48
-rw-r--r--arch/mips/kernel/mips-cm.c12
-rw-r--r--arch/mips/kernel/mips-cpc.c4
-rw-r--r--arch/mips/kernel/mips_ksyms.c4
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c30
-rw-r--r--arch/mips/kernel/process.c54
-rw-r--r--arch/mips/kernel/prom.c18
-rw-r--r--arch/mips/kernel/setup.c12
-rw-r--r--arch/mips/kernel/signal.c2
-rw-r--r--arch/mips/kernel/smp-bmips.c114
-rw-r--r--arch/mips/kernel/smp-cmp.c2
-rw-r--r--arch/mips/kernel/smp-cps.c6
-rw-r--r--arch/mips/kernel/smp-gic.c2
-rw-r--r--arch/mips/kernel/smp-mt.c6
-rw-r--r--arch/mips/kernel/syscall.c2
-rw-r--r--arch/mips/kernel/traps.c66
-rw-r--r--arch/mips/kernel/vdso.c15
-rw-r--r--arch/mips/lantiq/falcon/sysctrl.c11
-rw-r--r--arch/mips/lantiq/irq.c56
-rw-r--r--arch/mips/lantiq/prom.c18
-rw-r--r--arch/mips/lantiq/xway/Makefile2
-rw-r--r--arch/mips/lantiq/xway/reset.c70
-rw-r--r--arch/mips/lantiq/xway/vmmc.c69
-rw-r--r--arch/mips/lantiq/xway/xrx200_phy_fw.c23
-rw-r--r--arch/mips/lib/iomap.c18
-rw-r--r--arch/mips/lib/memset.S6
-rw-r--r--arch/mips/lib/mips-atomic.c20
-rw-r--r--arch/mips/lib/r3k_dump_tlb.c11
-rw-r--r--arch/mips/lib/strlen_user.S3
-rw-r--r--arch/mips/loongson/Kconfig17
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_pci.c25
-rw-r--r--arch/mips/loongson/common/dma-swiotlb.c14
-rw-r--r--arch/mips/loongson/common/early_printk.c2
-rw-r--r--arch/mips/loongson/common/env.c28
-rw-r--r--arch/mips/loongson/common/gpio.c2
-rw-r--r--arch/mips/loongson/common/init.c1
-rw-r--r--arch/mips/loongson/common/machtype.c23
-rw-r--r--arch/mips/loongson/common/rtc.c2
-rw-r--r--arch/mips/loongson/common/serial.c66
-rw-r--r--arch/mips/loongson/common/setup.c1
-rw-r--r--arch/mips/loongson/common/time.c5
-rw-r--r--arch/mips/loongson/common/uart_base.c30
-rw-r--r--arch/mips/loongson/lemote-2f/irq.c4
-rw-r--r--arch/mips/loongson/lemote-2f/reset.c2
-rw-r--r--arch/mips/loongson/loongson-3/Makefile4
-rw-r--r--arch/mips/loongson/loongson-3/hpet.c257
-rw-r--r--arch/mips/loongson/loongson-3/irq.c16
-rw-r--r--arch/mips/loongson/loongson-3/numa.c12
-rw-r--r--arch/mips/loongson/loongson-3/platform.c43
-rw-r--r--arch/mips/loongson/loongson-3/smp.c70
-rw-r--r--arch/mips/loongson1/Kconfig42
-rw-r--r--arch/mips/loongson1/common/Makefile2
-rw-r--r--arch/mips/loongson1/common/clock.c28
-rw-r--r--arch/mips/loongson1/common/platform.c141
-rw-r--r--arch/mips/loongson1/common/prom.c30
-rw-r--r--arch/mips/loongson1/common/reset.c20
-rw-r--r--arch/mips/loongson1/common/time.c226
-rw-r--r--arch/mips/loongson1/ls1b/board.c12
-rw-r--r--arch/mips/math-emu/cp1emu.c9
-rw-r--r--arch/mips/math-emu/ieee754dp.c2
-rw-r--r--arch/mips/math-emu/ieee754sp.c2
-rw-r--r--arch/mips/mm/Makefile10
-rw-r--r--arch/mips/mm/c-r4k.c43
-rw-r--r--arch/mips/mm/dma-default.c5
-rw-r--r--arch/mips/mm/gup.c2
-rw-r--r--arch/mips/mm/init.c2
-rw-r--r--arch/mips/mm/ioremap.c18
-rw-r--r--arch/mips/mm/sc-r5k.c2
-rw-r--r--arch/mips/mm/tlb-r4k.c2
-rw-r--r--arch/mips/mm/tlbex.c18
-rw-r--r--arch/mips/mm/uasm-mips.c2
-rw-r--r--arch/mips/mm/uasm.c14
-rw-r--r--arch/mips/mti-malta/malta-init.c2
-rw-r--r--arch/mips/mti-malta/malta-int.c327
-rw-r--r--arch/mips/mti-malta/malta-time.c51
-rw-r--r--arch/mips/mti-sead3/sead3-ehci.c8
-rw-r--r--arch/mips/mti-sead3/sead3-int.c131
-rw-r--r--arch/mips/mti-sead3/sead3-net.c14
-rw-r--r--arch/mips/mti-sead3/sead3-platform.c18
-rw-r--r--arch/mips/mti-sead3/sead3-serial.c45
-rw-r--r--arch/mips/mti-sead3/sead3-time.c35
-rw-r--r--arch/mips/oprofile/Makefile1
-rw-r--r--arch/mips/oprofile/backtrace.c5
-rw-r--r--arch/mips/oprofile/common.c11
-rw-r--r--arch/mips/oprofile/op_model_loongson3.c220
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c18
-rw-r--r--arch/mips/pci/Makefile2
-rw-r--r--arch/mips/pci/ops-bcm63xx.c2
-rw-r--r--arch/mips/pci/ops-nile4.c12
-rw-r--r--arch/mips/pci/ops-pmcmsp.c12
-rw-r--r--arch/mips/pci/pci-ar2315.c511
-rw-r--r--arch/mips/pci/pci-ar71xx.c13
-rw-r--r--arch/mips/pci/pci-ar724x.c23
-rw-r--r--arch/mips/pci/pci-rt2880.c285
-rw-r--r--arch/mips/pci/pci-rt3883.c9
-rw-r--r--arch/mips/pci/pci-tx4939.c2
-rw-r--r--arch/mips/pmcs-msp71xx/msp_prom.c2
-rw-r--r--arch/mips/ralink/Kconfig3
-rw-r--r--arch/mips/ralink/Makefile4
-rw-r--r--arch/mips/ralink/bootrom.c48
-rw-r--r--arch/mips/ralink/clk.c6
-rw-r--r--arch/mips/ralink/common.h19
-rw-r--r--arch/mips/ralink/early_printk.c45
-rw-r--r--arch/mips/ralink/ill_acc.c87
-rw-r--r--arch/mips/ralink/irq.c45
-rw-r--r--arch/mips/ralink/mt7620.c465
-rw-r--r--arch/mips/ralink/of.c32
-rw-r--r--arch/mips/ralink/prom.c1
-rw-r--r--arch/mips/ralink/rt288x.c65
-rw-r--r--arch/mips/ralink/rt305x.c153
-rw-r--r--arch/mips/ralink/rt3883.c174
-rw-r--r--arch/mips/rb532/gpio.c2
-rw-r--r--arch/mips/rb532/prom.c8
-rw-r--r--arch/mips/sgi-ip22/ip22-mc.c6
-rw-r--r--arch/mips/sgi-ip22/ip28-berr.c6
-rw-r--r--arch/mips/sgi-ip27/ip27-klnuma.c5
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c5
-rw-r--r--arch/mips/sibyte/common/cfe.c8
-rw-r--r--arch/mips/sibyte/swarm/platform.c2
-rw-r--r--arch/mips/sibyte/swarm/rtc_m41t81.c4
-rw-r--r--arch/mips/sibyte/swarm/rtc_xicor1241.c4
-rw-r--r--arch/mips/sibyte/swarm/setup.c2
-rw-r--r--arch/mips/txx9/generic/setup_tx4927.c4
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c4
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c4
258 files changed, 8039 insertions, 3505 deletions
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index f5e18bf3275e..e5fc463b36d0 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -2,7 +2,9 @@
2 2
3platforms += alchemy 3platforms += alchemy
4platforms += ar7 4platforms += ar7
5platforms += ath25
5platforms += ath79 6platforms += ath79
7platforms += bcm3384
6platforms += bcm47xx 8platforms += bcm47xx
7platforms += bcm63xx 9platforms += bcm63xx
8platforms += cavium-octeon 10platforms += cavium-octeon
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9536ef912f59..3289969ee423 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -53,6 +53,7 @@ config MIPS
53 select HAVE_CC_STACKPROTECTOR 53 select HAVE_CC_STACKPROTECTOR
54 select CPU_PM if CPU_IDLE 54 select CPU_PM if CPU_IDLE
55 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST 55 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
56 select ARCH_BINFMT_ELF_STATE
56 57
57menu "Machine selection" 58menu "Machine selection"
58 59
@@ -62,7 +63,7 @@ choice
62 63
63config MIPS_ALCHEMY 64config MIPS_ALCHEMY
64 bool "Alchemy processor based machines" 65 bool "Alchemy processor based machines"
65 select 64BIT_PHYS_ADDR 66 select ARCH_PHYS_ADDR_T_64BIT
66 select CEVT_R4K 67 select CEVT_R4K
67 select CSRC_R4K 68 select CSRC_R4K
68 select IRQ_CPU 69 select IRQ_CPU
@@ -96,6 +97,20 @@ config AR7
96 Support for the Texas Instruments AR7 System-on-a-Chip 97 Support for the Texas Instruments AR7 System-on-a-Chip
97 family: TNETD7100, 7200 and 7300. 98 family: TNETD7100, 7200 and 7300.
98 99
100config ATH25
101 bool "Atheros AR231x/AR531x SoC support"
102 select CEVT_R4K
103 select CSRC_R4K
104 select DMA_NONCOHERENT
105 select IRQ_CPU
106 select IRQ_DOMAIN
107 select SYS_HAS_CPU_MIPS32_R1
108 select SYS_SUPPORTS_BIG_ENDIAN
109 select SYS_SUPPORTS_32BIT_KERNEL
110 select SYS_HAS_EARLY_PRINTK
111 help
112 Support for Atheros AR231x and Atheros AR531x based boards
113
99config ATH79 114config ATH79
100 bool "Atheros AR71XX/AR724X/AR913X based boards" 115 bool "Atheros AR71XX/AR724X/AR913X based boards"
101 select ARCH_REQUIRE_GPIOLIB 116 select ARCH_REQUIRE_GPIOLIB
@@ -115,6 +130,32 @@ config ATH79
115 help 130 help
116 Support for the Atheros AR71XX/AR724X/AR913X SoCs. 131 Support for the Atheros AR71XX/AR724X/AR913X SoCs.
117 132
133config BCM3384
134 bool "Broadcom BCM3384 based boards"
135 select BOOT_RAW
136 select NO_EXCEPT_FILL
137 select USE_OF
138 select CEVT_R4K
139 select CSRC_R4K
140 select SYNC_R4K
141 select COMMON_CLK
142 select DMA_NONCOHERENT
143 select IRQ_CPU
144 select SYS_SUPPORTS_32BIT_KERNEL
145 select SYS_SUPPORTS_BIG_ENDIAN
146 select SYS_SUPPORTS_HIGHMEM
147 select SYS_HAS_CPU_BMIPS5000
148 select SWAP_IO_SPACE
149 select USB_EHCI_BIG_ENDIAN_DESC
150 select USB_EHCI_BIG_ENDIAN_MMIO
151 select USB_OHCI_BIG_ENDIAN_DESC
152 select USB_OHCI_BIG_ENDIAN_MMIO
153 help
154 Support for BCM3384 based boards. BCM3384/BCM33843 is a cable modem
155 chipset with a Linux application processor that is often used to
156 provide Samba services, a CUPS print server, and/or advanced routing
157 features.
158
118config BCM47XX 159config BCM47XX
119 bool "Broadcom BCM47XX based boards" 160 bool "Broadcom BCM47XX based boards"
120 select ARCH_WANT_OPTIONAL_GPIOLIB 161 select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -269,6 +310,8 @@ config LANTIQ
269 select USE_OF 310 select USE_OF
270 select PINCTRL 311 select PINCTRL
271 select PINCTRL_LANTIQ 312 select PINCTRL_LANTIQ
313 select ARCH_HAS_RESET_CONTROLLER
314 select RESET_CONTROLLER
272 315
273config LASAT 316config LASAT
274 bool "LASAT Networks platforms" 317 bool "LASAT Networks platforms"
@@ -315,17 +358,18 @@ config MIPS_MALTA
315 select BOOT_RAW 358 select BOOT_RAW
316 select CEVT_R4K 359 select CEVT_R4K
317 select CSRC_R4K 360 select CSRC_R4K
318 select CSRC_GIC 361 select CLKSRC_MIPS_GIC
319 select DMA_MAYBE_COHERENT 362 select DMA_MAYBE_COHERENT
320 select GENERIC_ISA_DMA 363 select GENERIC_ISA_DMA
321 select HAVE_PCSPKR_PLATFORM 364 select HAVE_PCSPKR_PLATFORM
322 select IRQ_CPU 365 select IRQ_CPU
323 select IRQ_GIC 366 select MIPS_GIC
324 select HW_HAS_PCI 367 select HW_HAS_PCI
325 select I8253 368 select I8253
326 select I8259 369 select I8259
327 select MIPS_BONITO64 370 select MIPS_BONITO64
328 select MIPS_CPU_SCACHE 371 select MIPS_CPU_SCACHE
372 select MIPS_L1_CACHE_SHIFT_6
329 select PCI_GT64XXX_PCI0 373 select PCI_GT64XXX_PCI0
330 select MIPS_MSC 374 select MIPS_MSC
331 select SWAP_IO_SPACE 375 select SWAP_IO_SPACE
@@ -340,6 +384,7 @@ config MIPS_MALTA
340 select SYS_SUPPORTS_64BIT_KERNEL 384 select SYS_SUPPORTS_64BIT_KERNEL
341 select SYS_SUPPORTS_BIG_ENDIAN 385 select SYS_SUPPORTS_BIG_ENDIAN
342 select SYS_SUPPORTS_LITTLE_ENDIAN 386 select SYS_SUPPORTS_LITTLE_ENDIAN
387 select SYS_SUPPORTS_MICROMIPS
343 select SYS_SUPPORTS_MIPS_CMP 388 select SYS_SUPPORTS_MIPS_CMP
344 select SYS_SUPPORTS_MIPS_CPS 389 select SYS_SUPPORTS_MIPS_CPS
345 select SYS_SUPPORTS_MIPS16 390 select SYS_SUPPORTS_MIPS16
@@ -357,12 +402,12 @@ config MIPS_SEAD3
357 select BUILTIN_DTB 402 select BUILTIN_DTB
358 select CEVT_R4K 403 select CEVT_R4K
359 select CSRC_R4K 404 select CSRC_R4K
360 select CSRC_GIC 405 select CLKSRC_MIPS_GIC
361 select CPU_MIPSR2_IRQ_VI 406 select CPU_MIPSR2_IRQ_VI
362 select CPU_MIPSR2_IRQ_EI 407 select CPU_MIPSR2_IRQ_EI
363 select DMA_NONCOHERENT 408 select DMA_NONCOHERENT
364 select IRQ_CPU 409 select IRQ_CPU
365 select IRQ_GIC 410 select MIPS_GIC
366 select LIBFDT 411 select LIBFDT
367 select MIPS_MSC 412 select MIPS_MSC
368 select SYS_HAS_CPU_MIPS32_R1 413 select SYS_HAS_CPU_MIPS32_R1
@@ -726,7 +771,7 @@ config MIKROTIK_RB532
726config CAVIUM_OCTEON_SOC 771config CAVIUM_OCTEON_SOC
727 bool "Cavium Networks Octeon SoC based boards" 772 bool "Cavium Networks Octeon SoC based boards"
728 select CEVT_R4K 773 select CEVT_R4K
729 select 64BIT_PHYS_ADDR 774 select ARCH_PHYS_ADDR_T_64BIT
730 select DMA_COHERENT 775 select DMA_COHERENT
731 select SYS_SUPPORTS_64BIT_KERNEL 776 select SYS_SUPPORTS_64BIT_KERNEL
732 select SYS_SUPPORTS_BIG_ENDIAN 777 select SYS_SUPPORTS_BIG_ENDIAN
@@ -768,7 +813,7 @@ config NLM_XLR_BOARD
768 select SWAP_IO_SPACE 813 select SWAP_IO_SPACE
769 select SYS_SUPPORTS_32BIT_KERNEL 814 select SYS_SUPPORTS_32BIT_KERNEL
770 select SYS_SUPPORTS_64BIT_KERNEL 815 select SYS_SUPPORTS_64BIT_KERNEL
771 select 64BIT_PHYS_ADDR 816 select ARCH_PHYS_ADDR_T_64BIT
772 select SYS_SUPPORTS_BIG_ENDIAN 817 select SYS_SUPPORTS_BIG_ENDIAN
773 select SYS_SUPPORTS_HIGHMEM 818 select SYS_SUPPORTS_HIGHMEM
774 select DMA_COHERENT 819 select DMA_COHERENT
@@ -794,7 +839,7 @@ config NLM_XLP_BOARD
794 select HW_HAS_PCI 839 select HW_HAS_PCI
795 select SYS_SUPPORTS_32BIT_KERNEL 840 select SYS_SUPPORTS_32BIT_KERNEL
796 select SYS_SUPPORTS_64BIT_KERNEL 841 select SYS_SUPPORTS_64BIT_KERNEL
797 select 64BIT_PHYS_ADDR 842 select ARCH_PHYS_ADDR_T_64BIT
798 select SYS_SUPPORTS_BIG_ENDIAN 843 select SYS_SUPPORTS_BIG_ENDIAN
799 select SYS_SUPPORTS_LITTLE_ENDIAN 844 select SYS_SUPPORTS_LITTLE_ENDIAN
800 select SYS_SUPPORTS_HIGHMEM 845 select SYS_SUPPORTS_HIGHMEM
@@ -835,6 +880,7 @@ config MIPS_PARAVIRT
835endchoice 880endchoice
836 881
837source "arch/mips/alchemy/Kconfig" 882source "arch/mips/alchemy/Kconfig"
883source "arch/mips/ath25/Kconfig"
838source "arch/mips/ath79/Kconfig" 884source "arch/mips/ath79/Kconfig"
839source "arch/mips/bcm47xx/Kconfig" 885source "arch/mips/bcm47xx/Kconfig"
840source "arch/mips/bcm63xx/Kconfig" 886source "arch/mips/bcm63xx/Kconfig"
@@ -907,10 +953,6 @@ config CEVT_GT641XX
907config CEVT_R4K 953config CEVT_R4K
908 bool 954 bool
909 955
910config CEVT_GIC
911 select MIPS_CM
912 bool
913
914config CEVT_SB1250 956config CEVT_SB1250
915 bool 957 bool
916 958
@@ -926,10 +968,6 @@ config CSRC_IOASIC
926config CSRC_R4K 968config CSRC_R4K
927 bool 969 bool
928 970
929config CSRC_GIC
930 select MIPS_CM
931 bool
932
933config CSRC_SB1250 971config CSRC_SB1250
934 bool 972 bool
935 973
@@ -941,7 +979,7 @@ config FW_CFE
941 bool 979 bool
942 980
943config ARCH_DMA_ADDR_T_64BIT 981config ARCH_DMA_ADDR_T_64BIT
944 def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT 982 def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT
945 983
946config DMA_MAYBE_COHERENT 984config DMA_MAYBE_COHERENT
947 select DMA_NONCOHERENT 985 select DMA_NONCOHERENT
@@ -975,6 +1013,7 @@ config SYS_SUPPORTS_HOTPLUG_CPU
975 1013
976config I8259 1014config I8259
977 bool 1015 bool
1016 select IRQ_DOMAIN
978 1017
979config MIPS_BONITO64 1018config MIPS_BONITO64
980 bool 1019 bool
@@ -1055,6 +1094,7 @@ config MIPS_HUGE_TLB_SUPPORT
1055 1094
1056config IRQ_CPU 1095config IRQ_CPU
1057 bool 1096 bool
1097 select IRQ_DOMAIN
1058 1098
1059config IRQ_CPU_RM7K 1099config IRQ_CPU_RM7K
1060 bool 1100 bool
@@ -1071,10 +1111,6 @@ config IRQ_TXX9
1071config IRQ_GT641XX 1111config IRQ_GT641XX
1072 bool 1112 bool
1073 1113
1074config IRQ_GIC
1075 select MIPS_CM
1076 bool
1077
1078config PCI_GT64XXX_PCI0 1114config PCI_GT64XXX_PCI0
1079 bool 1115 bool
1080 1116
@@ -1574,6 +1610,7 @@ config CPU_LOONGSON1
1574 select CPU_HAS_PREFETCH 1610 select CPU_HAS_PREFETCH
1575 select CPU_SUPPORTS_32BIT_KERNEL 1611 select CPU_SUPPORTS_32BIT_KERNEL
1576 select CPU_SUPPORTS_HIGHMEM 1612 select CPU_SUPPORTS_HIGHMEM
1613 select CPU_SUPPORTS_CPUFREQ
1577 1614
1578config CPU_BMIPS32_3300 1615config CPU_BMIPS32_3300
1579 select SMP_UP if SMP 1616 select SMP_UP if SMP
@@ -1586,12 +1623,14 @@ config CPU_BMIPS4350
1586 1623
1587config CPU_BMIPS4380 1624config CPU_BMIPS4380
1588 bool 1625 bool
1626 select MIPS_L1_CACHE_SHIFT_6
1589 select SYS_SUPPORTS_SMP 1627 select SYS_SUPPORTS_SMP
1590 select SYS_SUPPORTS_HOTPLUG_CPU 1628 select SYS_SUPPORTS_HOTPLUG_CPU
1591 1629
1592config CPU_BMIPS5000 1630config CPU_BMIPS5000
1593 bool 1631 bool
1594 select MIPS_CPU_SCACHE 1632 select MIPS_CPU_SCACHE
1633 select MIPS_L1_CACHE_SHIFT_7
1595 select SYS_SUPPORTS_SMP 1634 select SYS_SUPPORTS_SMP
1596 select SYS_SUPPORTS_HOTPLUG_CPU 1635 select SYS_SUPPORTS_HOTPLUG_CPU
1597 1636
@@ -1886,15 +1925,6 @@ config FORCE_MAX_ZONEORDER
1886 The page size is not necessarily 4KB. Keep this in mind 1925 The page size is not necessarily 4KB. Keep this in mind
1887 when choosing a value for this option. 1926 when choosing a value for this option.
1888 1927
1889config CEVT_GIC
1890 bool "Use GIC global counter for clock events"
1891 depends on IRQ_GIC && !MIPS_SEAD3
1892 help
1893 Use the GIC global counter for the clock events. The R4K clock
1894 event driver is always present, so if the platform ends up not
1895 detecting a GIC, it will fall back to the R4K timer for the
1896 generation of clock events.
1897
1898config BOARD_SCACHE 1928config BOARD_SCACHE
1899 bool 1929 bool
1900 1930
@@ -1908,7 +1938,6 @@ config IP22_CPU_SCACHE
1908config MIPS_CPU_SCACHE 1938config MIPS_CPU_SCACHE
1909 bool 1939 bool
1910 select BOARD_SCACHE 1940 select BOARD_SCACHE
1911 select MIPS_L1_CACHE_SHIFT_6
1912 1941
1913config R5000_CPU_SCACHE 1942config R5000_CPU_SCACHE
1914 bool 1943 bool
@@ -2095,11 +2124,8 @@ config SB1_PASS_2_1_WORKAROUNDS
2095 default y 2124 default y
2096 2125
2097 2126
2098config 64BIT_PHYS_ADDR
2099 bool
2100
2101config ARCH_PHYS_ADDR_T_64BIT 2127config ARCH_PHYS_ADDR_T_64BIT
2102 def_bool 64BIT_PHYS_ADDR 2128 bool
2103 2129
2104choice 2130choice
2105 prompt "SmartMIPS or microMIPS ASE support" 2131 prompt "SmartMIPS or microMIPS ASE support"
@@ -2122,7 +2148,7 @@ config CPU_HAS_SMARTMIPS
2122 here. 2148 here.
2123 2149
2124config CPU_MICROMIPS 2150config CPU_MICROMIPS
2125 depends on SYS_SUPPORTS_MICROMIPS 2151 depends on 32BIT && SYS_SUPPORTS_MICROMIPS
2126 bool "microMIPS" 2152 bool "microMIPS"
2127 help 2153 help
2128 When this option is enabled the kernel will be built using the 2154 When this option is enabled the kernel will be built using the
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index 3a2b775e8458..88a9f433f6fc 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -122,4 +122,17 @@ config SPINLOCK_TEST
122 help 122 help
123 Add several files to the debugfs to test spinlock speed. 123 Add several files to the debugfs to test spinlock speed.
124 124
125config FP32XX_HYBRID_FPRS
126 bool "Run FP32 & FPXX code with hybrid FPRs"
127 depends on MIPS_O32_FP64_SUPPORT
128 help
129 The hybrid FPR scheme is normally used only when a program needs to
130 execute a mix of FP32 & FP64A code, since the trapping & emulation
131 that it entails is expensive. When enabled, this option will lead
132 to the kernel running programs which use the FP32 & FPXX FP ABIs
133 using the hybrid FPR scheme, which can be useful for debugging
134 purposes.
135
136 If unsure, say N.
137
125endmenu 138endmenu
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 58076472bdd8..2563a088d3b8 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -380,6 +380,7 @@ define archhelp
380 echo ' vmlinux.ecoff - ECOFF boot image' 380 echo ' vmlinux.ecoff - ECOFF boot image'
381 echo ' vmlinux.bin - Raw binary boot image' 381 echo ' vmlinux.bin - Raw binary boot image'
382 echo ' vmlinux.srec - SREC boot image' 382 echo ' vmlinux.srec - SREC boot image'
383 echo ' vmlinux.32 - 64-bit boot image wrapped in 32bits (IP22/IP32)'
383 echo ' vmlinuz - Compressed boot(zboot) image' 384 echo ' vmlinuz - Compressed boot(zboot) image'
384 echo ' vmlinuz.ecoff - ECOFF zboot image' 385 echo ' vmlinuz.ecoff - ECOFF zboot image'
385 echo ' vmlinuz.bin - Raw binary zboot image' 386 echo ' vmlinuz.bin - Raw binary zboot image'
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c
index d7557cde271a..203e4403c366 100644
--- a/arch/mips/alchemy/common/clock.c
+++ b/arch/mips/alchemy/common/clock.c
@@ -37,7 +37,6 @@
37#include <linux/io.h> 37#include <linux/io.h>
38#include <linux/clk-provider.h> 38#include <linux/clk-provider.h>
39#include <linux/clkdev.h> 39#include <linux/clkdev.h>
40#include <linux/clk-private.h>
41#include <linux/slab.h> 40#include <linux/slab.h>
42#include <linux/spinlock.h> 41#include <linux/spinlock.h>
43#include <linux/types.h> 42#include <linux/types.h>
@@ -397,10 +396,10 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate,
397 break; 396 break;
398 397
399 /* if this parent is currently unused, remember it. 398 /* if this parent is currently unused, remember it.
400 * XXX: I know it's a layering violation, but it works 399 * XXX: we would actually want clk_has_active_children()
401 * so well.. (if (!clk_has_active_children(pc)) ) 400 * but this is a good-enough approximation for now.
402 */ 401 */
403 if (pc->prepare_count == 0) { 402 if (!__clk_is_prepared(pc)) {
404 if (!free) 403 if (!free)
405 free = pc; 404 free = pc;
406 } 405 }
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c
index ea8f41869e56..4e72daf12c32 100644
--- a/arch/mips/alchemy/common/setup.c
+++ b/arch/mips/alchemy/common/setup.c
@@ -70,9 +70,9 @@ void __init plat_mem_setup(void)
70 iomem_resource.end = IOMEM_RESOURCE_END; 70 iomem_resource.end = IOMEM_RESOURCE_END;
71} 71}
72 72
73#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) 73#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI)
74/* This routine should be valid for all Au1x based boards */ 74/* This routine should be valid for all Au1x based boards */
75phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) 75phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
76{ 76{
77 unsigned long start = ALCHEMY_PCI_MEMWIN_START; 77 unsigned long start = ALCHEMY_PCI_MEMWIN_START;
78 unsigned long end = ALCHEMY_PCI_MEMWIN_END; 78 unsigned long end = ALCHEMY_PCI_MEMWIN_END;
@@ -83,7 +83,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
83 83
84 /* Check for PCI memory window */ 84 /* Check for PCI memory window */
85 if (phys_addr >= start && (phys_addr + size - 1) <= end) 85 if (phys_addr >= start && (phys_addr + size - 1) <= end)
86 return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); 86 return (phys_addr_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr);
87 87
88 /* default nop */ 88 /* default nop */
89 return phys_addr; 89 return phys_addr;
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 7e2356fd5fd6..af2441dbfc12 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -311,8 +311,7 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
311 &dev_addr[0], &dev_addr[1], 311 &dev_addr[0], &dev_addr[1],
312 &dev_addr[2], &dev_addr[3], 312 &dev_addr[2], &dev_addr[3],
313 &dev_addr[4], &dev_addr[5]) != 6) { 313 &dev_addr[4], &dev_addr[5]) != 6) {
314 pr_warning("cannot parse mac address, " 314 pr_warn("cannot parse mac address, using random address\n");
315 "using random address\n");
316 eth_random_addr(dev_addr); 315 eth_random_addr(dev_addr);
317 } 316 }
318 } else 317 } else
@@ -665,7 +664,7 @@ static int __init ar7_register_devices(void)
665 664
666 res = platform_device_register(&physmap_flash); 665 res = platform_device_register(&physmap_flash);
667 if (res) 666 if (res)
668 pr_warning("unable to register physmap-flash: %d\n", res); 667 pr_warn("unable to register physmap-flash: %d\n", res);
669 668
670 if (ar7_is_titan()) 669 if (ar7_is_titan())
671 titan_fixup_devices(); 670 titan_fixup_devices();
@@ -673,13 +672,13 @@ static int __init ar7_register_devices(void)
673 ar7_device_disable(vlynq_low_data.reset_bit); 672 ar7_device_disable(vlynq_low_data.reset_bit);
674 res = platform_device_register(&vlynq_low); 673 res = platform_device_register(&vlynq_low);
675 if (res) 674 if (res)
676 pr_warning("unable to register vlynq-low: %d\n", res); 675 pr_warn("unable to register vlynq-low: %d\n", res);
677 676
678 if (ar7_has_high_vlynq()) { 677 if (ar7_has_high_vlynq()) {
679 ar7_device_disable(vlynq_high_data.reset_bit); 678 ar7_device_disable(vlynq_high_data.reset_bit);
680 res = platform_device_register(&vlynq_high); 679 res = platform_device_register(&vlynq_high);
681 if (res) 680 if (res)
682 pr_warning("unable to register vlynq-high: %d\n", res); 681 pr_warn("unable to register vlynq-high: %d\n", res);
683 } 682 }
684 683
685 if (ar7_has_high_cpmac()) { 684 if (ar7_has_high_cpmac()) {
@@ -689,9 +688,10 @@ static int __init ar7_register_devices(void)
689 688
690 res = platform_device_register(&cpmac_high); 689 res = platform_device_register(&cpmac_high);
691 if (res) 690 if (res)
692 pr_warning("unable to register cpmac-high: %d\n", res); 691 pr_warn("unable to register cpmac-high: %d\n",
692 res);
693 } else 693 } else
694 pr_warning("unable to add cpmac-high phy: %d\n", res); 694 pr_warn("unable to add cpmac-high phy: %d\n", res);
695 } else 695 } else
696 cpmac_low_data.phy_mask = 0xffffffff; 696 cpmac_low_data.phy_mask = 0xffffffff;
697 697
@@ -700,18 +700,18 @@ static int __init ar7_register_devices(void)
700 cpmac_get_mac(0, cpmac_low_data.dev_addr); 700 cpmac_get_mac(0, cpmac_low_data.dev_addr);
701 res = platform_device_register(&cpmac_low); 701 res = platform_device_register(&cpmac_low);
702 if (res) 702 if (res)
703 pr_warning("unable to register cpmac-low: %d\n", res); 703 pr_warn("unable to register cpmac-low: %d\n", res);
704 } else 704 } else
705 pr_warning("unable to add cpmac-low phy: %d\n", res); 705 pr_warn("unable to add cpmac-low phy: %d\n", res);
706 706
707 detect_leds(); 707 detect_leds();
708 res = platform_device_register(&ar7_gpio_leds); 708 res = platform_device_register(&ar7_gpio_leds);
709 if (res) 709 if (res)
710 pr_warning("unable to register leds: %d\n", res); 710 pr_warn("unable to register leds: %d\n", res);
711 711
712 res = platform_device_register(&ar7_udc); 712 res = platform_device_register(&ar7_udc);
713 if (res) 713 if (res)
714 pr_warning("unable to register usb slave: %d\n", res); 714 pr_warn("unable to register usb slave: %d\n", res);
715 715
716 /* Register watchdog only if enabled in hardware */ 716 /* Register watchdog only if enabled in hardware */
717 bootcr = ioremap_nocache(AR7_REGS_DCL, 4); 717 bootcr = ioremap_nocache(AR7_REGS_DCL, 4);
@@ -726,7 +726,7 @@ static int __init ar7_register_devices(void)
726 ar7_wdt_res.end = ar7_wdt_res.start + 0x20; 726 ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
727 res = platform_device_register(&ar7_wdt); 727 res = platform_device_register(&ar7_wdt);
728 if (res) 728 if (res)
729 pr_warning("unable to register watchdog: %d\n", res); 729 pr_warn("unable to register watchdog: %d\n", res);
730 } 730 }
731 731
732 return 0; 732 return 0;
diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig
new file mode 100644
index 000000000000..fc19dd57e42d
--- /dev/null
+++ b/arch/mips/ath25/Kconfig
@@ -0,0 +1,16 @@
1config SOC_AR5312
2 bool "Atheros AR5312/AR2312+ SoC support"
3 depends on ATH25
4 default y
5
6config SOC_AR2315
7 bool "Atheros AR2315+ SoC support"
8 depends on ATH25
9 default y
10
11config PCI_AR2315
12 bool "Atheros AR2315 PCI controller support"
13 depends on SOC_AR2315
14 select HW_HAS_PCI
15 select PCI
16 default y
diff --git a/arch/mips/ath25/Makefile b/arch/mips/ath25/Makefile
new file mode 100644
index 000000000000..eabad7da446a
--- /dev/null
+++ b/arch/mips/ath25/Makefile
@@ -0,0 +1,16 @@
1#
2# This file is subject to the terms and conditions of the GNU General Public
3# License. See the file "COPYING" in the main directory of this archive
4# for more details.
5#
6# Copyright (C) 2006 FON Technology, SL.
7# Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
8# Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
9#
10
11obj-y += board.o prom.o devices.o
12
13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
14
15obj-$(CONFIG_SOC_AR5312) += ar5312.o
16obj-$(CONFIG_SOC_AR2315) += ar2315.o
diff --git a/arch/mips/ath25/Platform b/arch/mips/ath25/Platform
new file mode 100644
index 000000000000..ef3f81fa080b
--- /dev/null
+++ b/arch/mips/ath25/Platform
@@ -0,0 +1,6 @@
1#
2# Atheros AR531X/AR231X WiSoC
3#
4platform-$(CONFIG_ATH25) += ath25/
5cflags-$(CONFIG_ATH25) += -I$(srctree)/arch/mips/include/asm/mach-ath25
6load-$(CONFIG_ATH25) += 0xffffffff80041000
diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c
new file mode 100644
index 000000000000..2befa7d766a6
--- /dev/null
+++ b/arch/mips/ath25/ar2315.c
@@ -0,0 +1,364 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 FON Technology, SL.
8 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
9 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
10 * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
11 */
12
13/*
14 * Platform devices for Atheros AR2315 SoCs
15 */
16
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/bitops.h>
20#include <linux/irqdomain.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/reboot.h>
24#include <asm/bootinfo.h>
25#include <asm/reboot.h>
26#include <asm/time.h>
27
28#include <ath25_platform.h>
29
30#include "devices.h"
31#include "ar2315.h"
32#include "ar2315_regs.h"
33
34static void __iomem *ar2315_rst_base;
35static struct irq_domain *ar2315_misc_irq_domain;
36
37static inline u32 ar2315_rst_reg_read(u32 reg)
38{
39 return __raw_readl(ar2315_rst_base + reg);
40}
41
42static inline void ar2315_rst_reg_write(u32 reg, u32 val)
43{
44 __raw_writel(val, ar2315_rst_base + reg);
45}
46
47static inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val)
48{
49 u32 ret = ar2315_rst_reg_read(reg);
50
51 ret &= ~mask;
52 ret |= val;
53 ar2315_rst_reg_write(reg, ret);
54}
55
56static irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id)
57{
58 ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET);
59 ar2315_rst_reg_read(AR2315_AHB_ERR1);
60
61 pr_emerg("AHB fatal error\n");
62 machine_restart("AHB error"); /* Catastrophic failure */
63
64 return IRQ_HANDLED;
65}
66
67static struct irqaction ar2315_ahb_err_interrupt = {
68 .handler = ar2315_ahb_err_handler,
69 .name = "ar2315-ahb-error",
70};
71
72static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc)
73{
74 u32 pending = ar2315_rst_reg_read(AR2315_ISR) &
75 ar2315_rst_reg_read(AR2315_IMR);
76 unsigned nr, misc_irq = 0;
77
78 if (pending) {
79 struct irq_domain *domain = irq_get_handler_data(irq);
80
81 nr = __ffs(pending);
82 misc_irq = irq_find_mapping(domain, nr);
83 }
84
85 if (misc_irq) {
86 if (nr == AR2315_MISC_IRQ_GPIO)
87 ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO);
88 else if (nr == AR2315_MISC_IRQ_WATCHDOG)
89 ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD);
90 generic_handle_irq(misc_irq);
91 } else {
92 spurious_interrupt();
93 }
94}
95
96static void ar2315_misc_irq_unmask(struct irq_data *d)
97{
98 ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq));
99}
100
101static void ar2315_misc_irq_mask(struct irq_data *d)
102{
103 ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0);
104}
105
106static struct irq_chip ar2315_misc_irq_chip = {
107 .name = "ar2315-misc",
108 .irq_unmask = ar2315_misc_irq_unmask,
109 .irq_mask = ar2315_misc_irq_mask,
110};
111
112static int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq,
113 irq_hw_number_t hw)
114{
115 irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq);
116 return 0;
117}
118
119static struct irq_domain_ops ar2315_misc_irq_domain_ops = {
120 .map = ar2315_misc_irq_map,
121};
122
123/*
124 * Called when an interrupt is received, this function
125 * determines exactly which interrupt it was, and it
126 * invokes the appropriate handler.
127 *
128 * Implicitly, we also define interrupt priority by
129 * choosing which to dispatch first.
130 */
131static void ar2315_irq_dispatch(void)
132{
133 u32 pending = read_c0_status() & read_c0_cause();
134
135 if (pending & CAUSEF_IP3)
136 do_IRQ(AR2315_IRQ_WLAN0);
137#ifdef CONFIG_PCI_AR2315
138 else if (pending & CAUSEF_IP5)
139 do_IRQ(AR2315_IRQ_LCBUS_PCI);
140#endif
141 else if (pending & CAUSEF_IP2)
142 do_IRQ(AR2315_IRQ_MISC);
143 else if (pending & CAUSEF_IP7)
144 do_IRQ(ATH25_IRQ_CPU_CLOCK);
145 else
146 spurious_interrupt();
147}
148
149void __init ar2315_arch_init_irq(void)
150{
151 struct irq_domain *domain;
152 unsigned irq;
153
154 ath25_irq_dispatch = ar2315_irq_dispatch;
155
156 domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT,
157 &ar2315_misc_irq_domain_ops, NULL);
158 if (!domain)
159 panic("Failed to add IRQ domain");
160
161 irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB);
162 setup_irq(irq, &ar2315_ahb_err_interrupt);
163
164 irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler);
165 irq_set_handler_data(AR2315_IRQ_MISC, domain);
166
167 ar2315_misc_irq_domain = domain;
168}
169
170void __init ar2315_init_devices(void)
171{
172 /* Find board configuration */
173 ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE);
174
175 ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0);
176}
177
178static void ar2315_restart(char *command)
179{
180 void (*mips_reset_vec)(void) = (void *)0xbfc00000;
181
182 local_irq_disable();
183
184 /* try reset the system via reset control */
185 ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM);
186
187 /* Cold reset does not work on the AR2315/6, use the GPIO reset bits
188 * a workaround. Give it some time to attempt a gpio based hardware
189 * reset (atheros reference design workaround) */
190
191 /* TODO: implement the GPIO reset workaround */
192
193 /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic
194 * workaround. Attempt to jump to the mips reset location -
195 * the boot loader itself might be able to recover the system */
196 mips_reset_vec();
197}
198
199/*
200 * This table is indexed by bits 5..4 of the CLOCKCTL1 register
201 * to determine the predevisor value.
202 */
203static int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 };
204static int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 };
205
206static unsigned __init ar2315_sys_clk(u32 clock_ctl)
207{
208 unsigned int pllc_ctrl, cpu_div;
209 unsigned int pllc_out, refdiv, fdiv, divby2;
210 unsigned int clk_div;
211
212 pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL);
213 refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV);
214 refdiv = clockctl1_predivide_table[refdiv];
215 fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV);
216 divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1;
217 pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv;
218
219 /* clkm input selected */
220 switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) {
221 case 0:
222 case 1:
223 clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV);
224 clk_div = pllc_divide_table[clk_div];
225 break;
226 case 2:
227 clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV);
228 clk_div = pllc_divide_table[clk_div];
229 break;
230 default:
231 pllc_out = 40000000;
232 clk_div = 1;
233 break;
234 }
235
236 cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV);
237 cpu_div = cpu_div * 2 ?: 1;
238
239 return pllc_out / (clk_div * cpu_div);
240}
241
242static inline unsigned ar2315_cpu_frequency(void)
243{
244 return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK));
245}
246
247static inline unsigned ar2315_apb_frequency(void)
248{
249 return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK));
250}
251
252void __init ar2315_plat_time_init(void)
253{
254 mips_hpt_frequency = ar2315_cpu_frequency() / 2;
255}
256
257void __init ar2315_plat_mem_setup(void)
258{
259 void __iomem *sdram_base;
260 u32 memsize, memcfg;
261 u32 devid;
262 u32 config;
263
264 /* Detect memory size */
265 sdram_base = ioremap_nocache(AR2315_SDRAMCTL_BASE,
266 AR2315_SDRAMCTL_SIZE);
267 memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG);
268 memsize = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH);
269 memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH);
270 memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH);
271 memsize <<= 3;
272 add_memory_region(0, memsize, BOOT_MEM_RAM);
273 iounmap(sdram_base);
274
275 ar2315_rst_base = ioremap_nocache(AR2315_RST_BASE, AR2315_RST_SIZE);
276
277 /* Detect the hardware based on the device ID */
278 devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP;
279 switch (devid) {
280 case 0x91: /* Need to check */
281 ath25_soc = ATH25_SOC_AR2318;
282 break;
283 case 0x90:
284 ath25_soc = ATH25_SOC_AR2317;
285 break;
286 case 0x87:
287 ath25_soc = ATH25_SOC_AR2316;
288 break;
289 case 0x86:
290 default:
291 ath25_soc = ATH25_SOC_AR2315;
292 break;
293 }
294 ath25_board.devid = devid;
295
296 /* Clear any lingering AHB errors */
297 config = read_c0_config();
298 write_c0_config(config & ~0x3);
299 ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET);
300 ar2315_rst_reg_read(AR2315_AHB_ERR1);
301 ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE);
302
303 _machine_restart = ar2315_restart;
304}
305
306#ifdef CONFIG_PCI_AR2315
307static struct resource ar2315_pci_res[] = {
308 {
309 .name = "ar2315-pci-ctrl",
310 .flags = IORESOURCE_MEM,
311 .start = AR2315_PCI_BASE,
312 .end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1,
313 },
314 {
315 .name = "ar2315-pci-ext",
316 .flags = IORESOURCE_MEM,
317 .start = AR2315_PCI_EXT_BASE,
318 .end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1,
319 },
320 {
321 .name = "ar2315-pci",
322 .flags = IORESOURCE_IRQ,
323 .start = AR2315_IRQ_LCBUS_PCI,
324 .end = AR2315_IRQ_LCBUS_PCI,
325 },
326};
327#endif
328
329void __init ar2315_arch_init(void)
330{
331 unsigned irq = irq_create_mapping(ar2315_misc_irq_domain,
332 AR2315_MISC_IRQ_UART0);
333
334 ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency());
335
336#ifdef CONFIG_PCI_AR2315
337 if (ath25_soc == ATH25_SOC_AR2315) {
338 /* Reset PCI DMA logic */
339 ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA);
340 msleep(20);
341 ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0);
342 msleep(20);
343
344 /* Configure endians */
345 ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB |
346 AR2315_CONFIG_PCIAHB_BRIDGE);
347
348 /* Configure as PCI host with DMA */
349 ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM |
350 (AR2315_PCICLK_IN_FREQ_DIV_6 <<
351 AR2315_PCICLK_DIV_S));
352 ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI);
353 ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK |
354 AR2315_IF_MASK, AR2315_IF_PCI |
355 AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR |
356 (AR2315_IF_PCI_CLK_OUTPUT_CLK <<
357 AR2315_IF_PCI_CLK_SHIFT));
358
359 platform_device_register_simple("ar2315-pci", -1,
360 ar2315_pci_res,
361 ARRAY_SIZE(ar2315_pci_res));
362 }
363#endif
364}
diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h
new file mode 100644
index 000000000000..877afe63eed5
--- /dev/null
+++ b/arch/mips/ath25/ar2315.h
@@ -0,0 +1,22 @@
1#ifndef __AR2315_H
2#define __AR2315_H
3
4#ifdef CONFIG_SOC_AR2315
5
6void ar2315_arch_init_irq(void);
7void ar2315_init_devices(void);
8void ar2315_plat_time_init(void);
9void ar2315_plat_mem_setup(void);
10void ar2315_arch_init(void);
11
12#else
13
14static inline void ar2315_arch_init_irq(void) {}
15static inline void ar2315_init_devices(void) {}
16static inline void ar2315_plat_time_init(void) {}
17static inline void ar2315_plat_mem_setup(void) {}
18static inline void ar2315_arch_init(void) {}
19
20#endif
21
22#endif /* __AR2315_H */
diff --git a/arch/mips/ath25/ar2315_regs.h b/arch/mips/ath25/ar2315_regs.h
new file mode 100644
index 000000000000..16e86149cb74
--- /dev/null
+++ b/arch/mips/ath25/ar2315_regs.h
@@ -0,0 +1,410 @@
1/*
2 * Register definitions for AR2315+
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
9 * Copyright (C) 2006 FON Technology, SL.
10 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
11 * Copyright (C) 2006-2008 Felix Fietkau <nbd@openwrt.org>
12 */
13
14#ifndef __ASM_MACH_ATH25_AR2315_REGS_H
15#define __ASM_MACH_ATH25_AR2315_REGS_H
16
17/*
18 * IRQs
19 */
20#define AR2315_IRQ_MISC (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */
21#define AR2315_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */
22#define AR2315_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */
23#define AR2315_IRQ_LCBUS_PCI (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */
24#define AR2315_IRQ_WLAN0_POLL (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */
25
26/*
27 * Miscellaneous interrupts, which share IP2.
28 */
29#define AR2315_MISC_IRQ_UART0 0
30#define AR2315_MISC_IRQ_I2C_RSVD 1
31#define AR2315_MISC_IRQ_SPI 2
32#define AR2315_MISC_IRQ_AHB 3
33#define AR2315_MISC_IRQ_APB 4
34#define AR2315_MISC_IRQ_TIMER 5
35#define AR2315_MISC_IRQ_GPIO 6
36#define AR2315_MISC_IRQ_WATCHDOG 7
37#define AR2315_MISC_IRQ_IR_RSVD 8
38#define AR2315_MISC_IRQ_COUNT 9
39
40/*
41 * Address map
42 */
43#define AR2315_SPI_READ_BASE 0x08000000 /* SPI flash */
44#define AR2315_SPI_READ_SIZE 0x01000000
45#define AR2315_WLAN0_BASE 0x10000000 /* Wireless MMR */
46#define AR2315_PCI_BASE 0x10100000 /* PCI MMR */
47#define AR2315_PCI_SIZE 0x00001000
48#define AR2315_SDRAMCTL_BASE 0x10300000 /* SDRAM MMR */
49#define AR2315_SDRAMCTL_SIZE 0x00000020
50#define AR2315_LOCAL_BASE 0x10400000 /* Local bus MMR */
51#define AR2315_ENET0_BASE 0x10500000 /* Ethernet MMR */
52#define AR2315_RST_BASE 0x11000000 /* Reset control MMR */
53#define AR2315_RST_SIZE 0x00000100
54#define AR2315_UART0_BASE 0x11100000 /* UART MMR */
55#define AR2315_SPI_MMR_BASE 0x11300000 /* SPI flash MMR */
56#define AR2315_SPI_MMR_SIZE 0x00000010
57#define AR2315_PCI_EXT_BASE 0x80000000 /* PCI external */
58#define AR2315_PCI_EXT_SIZE 0x40000000
59
60/*
61 * Configuration registers
62 */
63
64/* Cold reset register */
65#define AR2315_COLD_RESET 0x0000
66
67#define AR2315_RESET_COLD_AHB 0x00000001
68#define AR2315_RESET_COLD_APB 0x00000002
69#define AR2315_RESET_COLD_CPU 0x00000004
70#define AR2315_RESET_COLD_CPUWARM 0x00000008
71#define AR2315_RESET_SYSTEM (RESET_COLD_CPU |\
72 RESET_COLD_APB |\
73 RESET_COLD_AHB) /* full system */
74#define AR2317_RESET_SYSTEM 0x00000010
75
76/* Reset register */
77#define AR2315_RESET 0x0004
78
79#define AR2315_RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */
80#define AR2315_RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BB */
81#define AR2315_RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */
82#define AR2315_RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */
83#define AR2315_RESET_MEMCTL 0x00000010 /* warm reset mem control */
84#define AR2315_RESET_LOCAL 0x00000020 /* warm reset local bus */
85#define AR2315_RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */
86#define AR2315_RESET_SPI 0x00000080 /* warm reset SPI iface */
87#define AR2315_RESET_UART0 0x00000100 /* warm reset UART0 */
88#define AR2315_RESET_IR_RSVD 0x00000200 /* warm reset IR iface */
89#define AR2315_RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */
90#define AR2315_RESET_ENET0 0x00000800 /* cold reset ENET0 MAC */
91
92/* AHB master arbitration control */
93#define AR2315_AHB_ARB_CTL 0x0008
94
95#define AR2315_ARB_CPU 0x00000001 /* CPU, default */
96#define AR2315_ARB_WLAN 0x00000002 /* WLAN */
97#define AR2315_ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */
98#define AR2315_ARB_LOCAL 0x00000008 /* Local bus */
99#define AR2315_ARB_PCI 0x00000010 /* PCI bus */
100#define AR2315_ARB_ETHERNET 0x00000020 /* Ethernet */
101#define AR2315_ARB_RETRY 0x00000100 /* Retry policy (debug) */
102
103/* Config Register */
104#define AR2315_ENDIAN_CTL 0x000c
105
106#define AR2315_CONFIG_AHB 0x00000001 /* EC-AHB bridge endian */
107#define AR2315_CONFIG_WLAN 0x00000002 /* WLAN byteswap */
108#define AR2315_CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */
109#define AR2315_CONFIG_PCI 0x00000008 /* PCI byteswap */
110#define AR2315_CONFIG_MEMCTL 0x00000010 /* Mem controller endian */
111#define AR2315_CONFIG_LOCAL 0x00000020 /* Local bus byteswap */
112#define AR2315_CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */
113#define AR2315_CONFIG_MERGE 0x00000200 /* CPU write buffer merge */
114#define AR2315_CONFIG_CPU 0x00000400 /* CPU big endian */
115#define AR2315_CONFIG_BIG 0x00000400
116#define AR2315_CONFIG_PCIAHB 0x00000800
117#define AR2315_CONFIG_PCIAHB_BRIDGE 0x00001000
118#define AR2315_CONFIG_SPI 0x00008000 /* SPI byteswap */
119#define AR2315_CONFIG_CPU_DRAM 0x00010000
120#define AR2315_CONFIG_CPU_PCI 0x00020000
121#define AR2315_CONFIG_CPU_MMR 0x00040000
122
123/* NMI control */
124#define AR2315_NMI_CTL 0x0010
125
126#define AR2315_NMI_EN 1
127
128/* Revision Register - Initial value is 0x3010 (WMAC 3.0, AR231X 1.0). */
129#define AR2315_SREV 0x0014
130
131#define AR2315_REV_MAJ 0x000000f0
132#define AR2315_REV_MAJ_S 4
133#define AR2315_REV_MIN 0x0000000f
134#define AR2315_REV_MIN_S 0
135#define AR2315_REV_CHIP (AR2315_REV_MAJ | AR2315_REV_MIN)
136
137/* Interface Enable */
138#define AR2315_IF_CTL 0x0018
139
140#define AR2315_IF_MASK 0x00000007
141#define AR2315_IF_DISABLED 0 /* Disable all */
142#define AR2315_IF_PCI 1 /* PCI */
143#define AR2315_IF_TS_LOCAL 2 /* Local bus */
144#define AR2315_IF_ALL 3 /* Emulation only */
145#define AR2315_IF_LOCAL_HOST 0x00000008
146#define AR2315_IF_PCI_HOST 0x00000010
147#define AR2315_IF_PCI_INTR 0x00000020
148#define AR2315_IF_PCI_CLK_MASK 0x00030000
149#define AR2315_IF_PCI_CLK_INPUT 0
150#define AR2315_IF_PCI_CLK_OUTPUT_LOW 1
151#define AR2315_IF_PCI_CLK_OUTPUT_CLK 2
152#define AR2315_IF_PCI_CLK_OUTPUT_HIGH 3
153#define AR2315_IF_PCI_CLK_SHIFT 16
154
155/* APB Interrupt control */
156#define AR2315_ISR 0x0020
157#define AR2315_IMR 0x0024
158#define AR2315_GISR 0x0028
159
160#define AR2315_ISR_UART0 0x00000001 /* high speed UART */
161#define AR2315_ISR_I2C_RSVD 0x00000002 /* I2C bus */
162#define AR2315_ISR_SPI 0x00000004 /* SPI bus */
163#define AR2315_ISR_AHB 0x00000008 /* AHB error */
164#define AR2315_ISR_APB 0x00000010 /* APB error */
165#define AR2315_ISR_TIMER 0x00000020 /* Timer */
166#define AR2315_ISR_GPIO 0x00000040 /* GPIO */
167#define AR2315_ISR_WD 0x00000080 /* Watchdog */
168#define AR2315_ISR_IR_RSVD 0x00000100 /* IR */
169
170#define AR2315_GISR_MISC 0x00000001 /* Misc */
171#define AR2315_GISR_WLAN0 0x00000002 /* WLAN0 */
172#define AR2315_GISR_MPEGTS_RSVD 0x00000004 /* MPEG-TS */
173#define AR2315_GISR_LOCALPCI 0x00000008 /* Local/PCI bus */
174#define AR2315_GISR_WMACPOLL 0x00000010
175#define AR2315_GISR_TIMER 0x00000020
176#define AR2315_GISR_ETHERNET 0x00000040 /* Ethernet */
177
178/* Generic timer */
179#define AR2315_TIMER 0x0030
180#define AR2315_RELOAD 0x0034
181
182/* Watchdog timer */
183#define AR2315_WDT_TIMER 0x0038
184#define AR2315_WDT_CTRL 0x003c
185
186#define AR2315_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */
187#define AR2315_WDT_CTRL_NMI 0x00000001 /* NMI on watchdog */
188#define AR2315_WDT_CTRL_RESET 0x00000002 /* reset on watchdog */
189
190/* CPU Performance Counters */
191#define AR2315_PERFCNT0 0x0048
192#define AR2315_PERFCNT1 0x004c
193
194#define AR2315_PERF0_DATAHIT 0x00000001 /* Count Data Cache Hits */
195#define AR2315_PERF0_DATAMISS 0x00000002 /* Count Data Cache Misses */
196#define AR2315_PERF0_INSTHIT 0x00000004 /* Count Instruction Cache Hits */
197#define AR2315_PERF0_INSTMISS 0x00000008 /* Count Instruction Cache Misses */
198#define AR2315_PERF0_ACTIVE 0x00000010 /* Count Active Processor Cycles */
199#define AR2315_PERF0_WBHIT 0x00000020 /* Count CPU Write Buffer Hits */
200#define AR2315_PERF0_WBMISS 0x00000040 /* Count CPU Write Buffer Misses */
201
202#define AR2315_PERF1_EB_ARDY 0x00000001 /* Count EB_ARdy signal */
203#define AR2315_PERF1_EB_AVALID 0x00000002 /* Count EB_AValid signal */
204#define AR2315_PERF1_EB_WDRDY 0x00000004 /* Count EB_WDRdy signal */
205#define AR2315_PERF1_EB_RDVAL 0x00000008 /* Count EB_RdVal signal */
206#define AR2315_PERF1_VRADDR 0x00000010 /* Count valid read address cycles*/
207#define AR2315_PERF1_VWADDR 0x00000020 /* Count valid write address cycl.*/
208#define AR2315_PERF1_VWDATA 0x00000040 /* Count valid write data cycles */
209
210/* AHB Error Reporting */
211#define AR2315_AHB_ERR0 0x0050 /* error */
212#define AR2315_AHB_ERR1 0x0054 /* haddr */
213#define AR2315_AHB_ERR2 0x0058 /* hwdata */
214#define AR2315_AHB_ERR3 0x005c /* hrdata */
215#define AR2315_AHB_ERR4 0x0060 /* status */
216
217#define AR2315_AHB_ERROR_DET 1 /* AHB Error has been detected, */
218 /* write 1 to clear all bits in ERR0 */
219#define AR2315_AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */
220#define AR2315_AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */
221
222#define AR2315_PROCERR_HMAST 0x0000000f
223#define AR2315_PROCERR_HMAST_DFLT 0
224#define AR2315_PROCERR_HMAST_WMAC 1
225#define AR2315_PROCERR_HMAST_ENET 2
226#define AR2315_PROCERR_HMAST_PCIENDPT 3
227#define AR2315_PROCERR_HMAST_LOCAL 4
228#define AR2315_PROCERR_HMAST_CPU 5
229#define AR2315_PROCERR_HMAST_PCITGT 6
230#define AR2315_PROCERR_HMAST_S 0
231#define AR2315_PROCERR_HWRITE 0x00000010
232#define AR2315_PROCERR_HSIZE 0x00000060
233#define AR2315_PROCERR_HSIZE_S 5
234#define AR2315_PROCERR_HTRANS 0x00000180
235#define AR2315_PROCERR_HTRANS_S 7
236#define AR2315_PROCERR_HBURST 0x00000e00
237#define AR2315_PROCERR_HBURST_S 9
238
239/* Clock Control */
240#define AR2315_PLLC_CTL 0x0064
241#define AR2315_PLLV_CTL 0x0068
242#define AR2315_CPUCLK 0x006c
243#define AR2315_AMBACLK 0x0070
244#define AR2315_SYNCCLK 0x0074
245#define AR2315_DSL_SLEEP_CTL 0x0080
246#define AR2315_DSL_SLEEP_DUR 0x0084
247
248/* PLLc Control fields */
249#define AR2315_PLLC_REF_DIV_M 0x00000003
250#define AR2315_PLLC_REF_DIV_S 0
251#define AR2315_PLLC_FDBACK_DIV_M 0x0000007c
252#define AR2315_PLLC_FDBACK_DIV_S 2
253#define AR2315_PLLC_ADD_FDBACK_DIV_M 0x00000080
254#define AR2315_PLLC_ADD_FDBACK_DIV_S 7
255#define AR2315_PLLC_CLKC_DIV_M 0x0001c000
256#define AR2315_PLLC_CLKC_DIV_S 14
257#define AR2315_PLLC_CLKM_DIV_M 0x00700000
258#define AR2315_PLLC_CLKM_DIV_S 20
259
260/* CPU CLK Control fields */
261#define AR2315_CPUCLK_CLK_SEL_M 0x00000003
262#define AR2315_CPUCLK_CLK_SEL_S 0
263#define AR2315_CPUCLK_CLK_DIV_M 0x0000000c
264#define AR2315_CPUCLK_CLK_DIV_S 2
265
266/* AMBA CLK Control fields */
267#define AR2315_AMBACLK_CLK_SEL_M 0x00000003
268#define AR2315_AMBACLK_CLK_SEL_S 0
269#define AR2315_AMBACLK_CLK_DIV_M 0x0000000c
270#define AR2315_AMBACLK_CLK_DIV_S 2
271
272/* PCI Clock Control */
273#define AR2315_PCICLK 0x00a4
274
275#define AR2315_PCICLK_INPUT_M 0x00000003
276#define AR2315_PCICLK_INPUT_S 0
277#define AR2315_PCICLK_PLLC_CLKM 0
278#define AR2315_PCICLK_PLLC_CLKM1 1
279#define AR2315_PCICLK_PLLC_CLKC 2
280#define AR2315_PCICLK_REF_CLK 3
281#define AR2315_PCICLK_DIV_M 0x0000000c
282#define AR2315_PCICLK_DIV_S 2
283#define AR2315_PCICLK_IN_FREQ 0
284#define AR2315_PCICLK_IN_FREQ_DIV_6 1
285#define AR2315_PCICLK_IN_FREQ_DIV_8 2
286#define AR2315_PCICLK_IN_FREQ_DIV_10 3
287
288/* Observation Control Register */
289#define AR2315_OCR 0x00b0
290
291#define AR2315_OCR_GPIO0_IRIN 0x00000040
292#define AR2315_OCR_GPIO1_IROUT 0x00000080
293#define AR2315_OCR_GPIO3_RXCLR 0x00000200
294
295/* General Clock Control */
296#define AR2315_MISCCLK 0x00b4
297
298#define AR2315_MISCCLK_PLLBYPASS_EN 0x00000001
299#define AR2315_MISCCLK_PROCREFCLK 0x00000002
300
301/*
302 * SDRAM Controller
303 * - No read or write buffers are included.
304 */
305#define AR2315_MEM_CFG 0x0000
306#define AR2315_MEM_CTRL 0x000c
307#define AR2315_MEM_REF 0x0010
308
309#define AR2315_MEM_CFG_DATA_WIDTH_M 0x00006000
310#define AR2315_MEM_CFG_DATA_WIDTH_S 13
311#define AR2315_MEM_CFG_COL_WIDTH_M 0x00001e00
312#define AR2315_MEM_CFG_COL_WIDTH_S 9
313#define AR2315_MEM_CFG_ROW_WIDTH_M 0x000001e0
314#define AR2315_MEM_CFG_ROW_WIDTH_S 5
315#define AR2315_MEM_CFG_BANKADDR_BITS_M 0x00000018
316#define AR2315_MEM_CFG_BANKADDR_BITS_S 3
317
318/*
319 * Local Bus Interface Registers
320 */
321#define AR2315_LB_CONFIG 0x0000
322
323#define AR2315_LBCONF_OE 0x00000001 /* =1 OE is low-true */
324#define AR2315_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */
325#define AR2315_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */
326#define AR2315_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */
327#define AR2315_LBCONF_WE 0x00000010 /* =1 Write En is low-true */
328#define AR2315_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */
329#define AR2315_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */
330#define AR2315_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */
331#define AR2315_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */
332#define AR2315_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */
333#define AR2315_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */
334#define AR2315_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */
335#define AR2315_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */
336#define AR2315_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */
337#define AR2315_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */
338#define AR2315_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */
339#define AR2315_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */
340#define AR2315_LBCONF_INT 0x00020000 /* =1 Intr is low true */
341#define AR2315_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */
342#define AR2315_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */
343#define AR2315_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */
344#define AR2315_LBCONF_INT_CTR3 0x000c0000 /* GND drive, Vdd drive */
345#define AR2315_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */
346#define AR2315_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */
347#define AR2315_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */
348
349#define AR2315_LB_CLKSEL 0x0004
350
351#define AR2315_LBCLK_EXT 0x00000001 /* use external clk for lb */
352
353#define AR2315_LB_1MS 0x0008
354
355#define AR2315_LB1MS_MASK 0x0003ffff /* # of AHB clk cycles in 1ms */
356
357#define AR2315_LB_MISCCFG 0x000c
358
359#define AR2315_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */
360#define AR2315_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */
361#define AR2315_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */
362#define AR2315_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */
363#define AR2315_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */
364#define AR2315_LBM_TIMEOUT_M 0x00ffff80
365#define AR2315_LBM_TIMEOUT_S 7
366#define AR2315_LBM_PORTMUX 0x07000000
367
368#define AR2315_LB_RXTSOFF 0x0010
369
370#define AR2315_LB_TX_CHAIN_EN 0x0100
371
372#define AR2315_LB_TXEN_0 0x00000001
373#define AR2315_LB_TXEN_1 0x00000002
374#define AR2315_LB_TXEN_2 0x00000004
375#define AR2315_LB_TXEN_3 0x00000008
376
377#define AR2315_LB_TX_CHAIN_DIS 0x0104
378#define AR2315_LB_TX_DESC_PTR 0x0200
379
380#define AR2315_LB_RX_CHAIN_EN 0x0400
381
382#define AR2315_LB_RXEN 0x00000001
383
384#define AR2315_LB_RX_CHAIN_DIS 0x0404
385#define AR2315_LB_RX_DESC_PTR 0x0408
386
387#define AR2315_LB_INT_STATUS 0x0500
388
389#define AR2315_LB_INT_TX_DESC 0x00000001
390#define AR2315_LB_INT_TX_OK 0x00000002
391#define AR2315_LB_INT_TX_ERR 0x00000004
392#define AR2315_LB_INT_TX_EOF 0x00000008
393#define AR2315_LB_INT_RX_DESC 0x00000010
394#define AR2315_LB_INT_RX_OK 0x00000020
395#define AR2315_LB_INT_RX_ERR 0x00000040
396#define AR2315_LB_INT_RX_EOF 0x00000080
397#define AR2315_LB_INT_TX_TRUNC 0x00000100
398#define AR2315_LB_INT_TX_STARVE 0x00000200
399#define AR2315_LB_INT_LB_TIMEOUT 0x00000400
400#define AR2315_LB_INT_LB_ERR 0x00000800
401#define AR2315_LB_INT_MBOX_WR 0x00001000
402#define AR2315_LB_INT_MBOX_RD 0x00002000
403
404/* Bit definitions for INT MASK are the same as INT_STATUS */
405#define AR2315_LB_INT_MASK 0x0504
406
407#define AR2315_LB_INT_EN 0x0508
408#define AR2315_LB_MBOX 0x0600
409
410#endif /* __ASM_MACH_ATH25_AR2315_REGS_H */
diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c
new file mode 100644
index 000000000000..b6887f75144c
--- /dev/null
+++ b/arch/mips/ath25/ar5312.c
@@ -0,0 +1,393 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 FON Technology, SL.
8 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
9 * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
10 * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com>
11 */
12
13/*
14 * Platform devices for Atheros AR5312 SoCs
15 */
16
17#include <linux/init.h>
18#include <linux/kernel.h>
19#include <linux/bitops.h>
20#include <linux/irqdomain.h>
21#include <linux/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/mtd/physmap.h>
24#include <linux/reboot.h>
25#include <asm/bootinfo.h>
26#include <asm/reboot.h>
27#include <asm/time.h>
28
29#include <ath25_platform.h>
30
31#include "devices.h"
32#include "ar5312.h"
33#include "ar5312_regs.h"
34
35static void __iomem *ar5312_rst_base;
36static struct irq_domain *ar5312_misc_irq_domain;
37
38static inline u32 ar5312_rst_reg_read(u32 reg)
39{
40 return __raw_readl(ar5312_rst_base + reg);
41}
42
43static inline void ar5312_rst_reg_write(u32 reg, u32 val)
44{
45 __raw_writel(val, ar5312_rst_base + reg);
46}
47
48static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val)
49{
50 u32 ret = ar5312_rst_reg_read(reg);
51
52 ret &= ~mask;
53 ret |= val;
54 ar5312_rst_reg_write(reg, ret);
55}
56
57static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id)
58{
59 u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1);
60 u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */
61 u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1);
62 u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR); /* clears error */
63
64 pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n",
65 proc_addr, proc1, dma_addr, dma1);
66
67 machine_restart("AHB error"); /* Catastrophic failure */
68 return IRQ_HANDLED;
69}
70
71static struct irqaction ar5312_ahb_err_interrupt = {
72 .handler = ar5312_ahb_err_handler,
73 .name = "ar5312-ahb-error",
74};
75
76static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc)
77{
78 u32 pending = ar5312_rst_reg_read(AR5312_ISR) &
79 ar5312_rst_reg_read(AR5312_IMR);
80 unsigned nr, misc_irq = 0;
81
82 if (pending) {
83 struct irq_domain *domain = irq_get_handler_data(irq);
84
85 nr = __ffs(pending);
86 misc_irq = irq_find_mapping(domain, nr);
87 }
88
89 if (misc_irq) {
90 generic_handle_irq(misc_irq);
91 if (nr == AR5312_MISC_IRQ_TIMER)
92 ar5312_rst_reg_read(AR5312_TIMER);
93 } else {
94 spurious_interrupt();
95 }
96}
97
98/* Enable the specified AR5312_MISC_IRQ interrupt */
99static void ar5312_misc_irq_unmask(struct irq_data *d)
100{
101 ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq));
102}
103
104/* Disable the specified AR5312_MISC_IRQ interrupt */
105static void ar5312_misc_irq_mask(struct irq_data *d)
106{
107 ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0);
108 ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */
109}
110
111static struct irq_chip ar5312_misc_irq_chip = {
112 .name = "ar5312-misc",
113 .irq_unmask = ar5312_misc_irq_unmask,
114 .irq_mask = ar5312_misc_irq_mask,
115};
116
117static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq,
118 irq_hw_number_t hw)
119{
120 irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq);
121 return 0;
122}
123
124static struct irq_domain_ops ar5312_misc_irq_domain_ops = {
125 .map = ar5312_misc_irq_map,
126};
127
128static void ar5312_irq_dispatch(void)
129{
130 u32 pending = read_c0_status() & read_c0_cause();
131
132 if (pending & CAUSEF_IP2)
133 do_IRQ(AR5312_IRQ_WLAN0);
134 else if (pending & CAUSEF_IP5)
135 do_IRQ(AR5312_IRQ_WLAN1);
136 else if (pending & CAUSEF_IP6)
137 do_IRQ(AR5312_IRQ_MISC);
138 else if (pending & CAUSEF_IP7)
139 do_IRQ(ATH25_IRQ_CPU_CLOCK);
140 else
141 spurious_interrupt();
142}
143
144void __init ar5312_arch_init_irq(void)
145{
146 struct irq_domain *domain;
147 unsigned irq;
148
149 ath25_irq_dispatch = ar5312_irq_dispatch;
150
151 domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT,
152 &ar5312_misc_irq_domain_ops, NULL);
153 if (!domain)
154 panic("Failed to add IRQ domain");
155
156 irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC);
157 setup_irq(irq, &ar5312_ahb_err_interrupt);
158
159 irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler);
160 irq_set_handler_data(AR5312_IRQ_MISC, domain);
161
162 ar5312_misc_irq_domain = domain;
163}
164
165static struct physmap_flash_data ar5312_flash_data = {
166 .width = 2,
167};
168
169static struct resource ar5312_flash_resource = {
170 .start = AR5312_FLASH_BASE,
171 .end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1,
172 .flags = IORESOURCE_MEM,
173};
174
175static struct platform_device ar5312_physmap_flash = {
176 .name = "physmap-flash",
177 .id = 0,
178 .dev.platform_data = &ar5312_flash_data,
179 .resource = &ar5312_flash_resource,
180 .num_resources = 1,
181};
182
183static void __init ar5312_flash_init(void)
184{
185 void __iomem *flashctl_base;
186 u32 ctl;
187
188 flashctl_base = ioremap_nocache(AR5312_FLASHCTL_BASE,
189 AR5312_FLASHCTL_SIZE);
190
191 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0);
192 ctl &= AR5312_FLASHCTL_MW;
193
194 /* fixup flash width */
195 switch (ctl) {
196 case AR5312_FLASHCTL_MW16:
197 ar5312_flash_data.width = 2;
198 break;
199 case AR5312_FLASHCTL_MW8:
200 default:
201 ar5312_flash_data.width = 1;
202 break;
203 }
204
205 /*
206 * Configure flash bank 0.
207 * Assume 8M window size. Flash will be aliased if it's smaller
208 */
209 ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE;
210 ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S;
211 ctl |= 0x07 << AR5312_FLASHCTL_WST1_S;
212 ctl |= 0x07 << AR5312_FLASHCTL_WST2_S;
213 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0);
214
215 /* Disable other flash banks */
216 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1);
217 ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
218 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1);
219 ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2);
220 ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC);
221 __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2);
222
223 iounmap(flashctl_base);
224}
225
226void __init ar5312_init_devices(void)
227{
228 struct ath25_boarddata *config;
229
230 ar5312_flash_init();
231
232 /* Locate board/radio config data */
233 ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE);
234 config = ath25_board.config;
235
236 /* AR2313 has CPU minor rev. 10 */
237 if ((current_cpu_data.processor_id & 0xff) == 0x0a)
238 ath25_soc = ATH25_SOC_AR2313;
239
240 /* AR2312 shares the same Silicon ID as AR5312 */
241 else if (config->flags & BD_ISCASPER)
242 ath25_soc = ATH25_SOC_AR2312;
243
244 /* Everything else is probably AR5312 or compatible */
245 else
246 ath25_soc = ATH25_SOC_AR5312;
247
248 platform_device_register(&ar5312_physmap_flash);
249
250 switch (ath25_soc) {
251 case ATH25_SOC_AR5312:
252 if (!ath25_board.radio)
253 return;
254
255 if (!(config->flags & BD_WLAN0))
256 break;
257
258 ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0);
259 break;
260 case ATH25_SOC_AR2312:
261 case ATH25_SOC_AR2313:
262 if (!ath25_board.radio)
263 return;
264 break;
265 default:
266 break;
267 }
268
269 if (config->flags & BD_WLAN1)
270 ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1);
271}
272
273static void ar5312_restart(char *command)
274{
275 /* reset the system */
276 local_irq_disable();
277 while (1)
278 ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM);
279}
280
281/*
282 * This table is indexed by bits 5..4 of the CLOCKCTL1 register
283 * to determine the predevisor value.
284 */
285static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 };
286
287static unsigned __init ar5312_cpu_frequency(void)
288{
289 u32 scratch, devid, clock_ctl1;
290 u32 predivide_mask, multiplier_mask, doubler_mask;
291 unsigned predivide_shift, multiplier_shift;
292 unsigned predivide_select, predivisor, multiplier;
293
294 /* Trust the bootrom's idea of cpu frequency. */
295 scratch = ar5312_rst_reg_read(AR5312_SCRATCH);
296 if (scratch)
297 return scratch;
298
299 devid = ar5312_rst_reg_read(AR5312_REV);
300 devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S;
301 if (devid == AR5312_REV_MAJ_AR2313) {
302 predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;
303 predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;
304 multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;
305 multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;
306 doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;
307 } else { /* AR5312 and AR2312 */
308 predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK;
309 predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT;
310 multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK;
311 multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT;
312 doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK;
313 }
314
315 /*
316 * Clocking is derived from a fixed 40MHz input clock.
317 *
318 * cpu_freq = input_clock * MULT (where MULT is PLL multiplier)
319 * sys_freq = cpu_freq / 4 (used for APB clock, serial,
320 * flash, Timer, Watchdog Timer)
321 *
322 * cnt_freq = cpu_freq / 2 (use for CPU count/compare)
323 *
324 * So, for example, with a PLL multiplier of 5, we have
325 *
326 * cpu_freq = 200MHz
327 * sys_freq = 50MHz
328 * cnt_freq = 100MHz
329 *
330 * We compute the CPU frequency, based on PLL settings.
331 */
332
333 clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1);
334 predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift;
335 predivisor = clockctl1_predivide_table[predivide_select];
336 multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift;
337
338 if (clock_ctl1 & doubler_mask)
339 multiplier <<= 1;
340
341 return (40000000 / predivisor) * multiplier;
342}
343
344static inline unsigned ar5312_sys_frequency(void)
345{
346 return ar5312_cpu_frequency() / 4;
347}
348
349void __init ar5312_plat_time_init(void)
350{
351 mips_hpt_frequency = ar5312_cpu_frequency() / 2;
352}
353
354void __init ar5312_plat_mem_setup(void)
355{
356 void __iomem *sdram_base;
357 u32 memsize, memcfg, bank0_ac, bank1_ac;
358 u32 devid;
359
360 /* Detect memory size */
361 sdram_base = ioremap_nocache(AR5312_SDRAMCTL_BASE,
362 AR5312_SDRAMCTL_SIZE);
363 memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1);
364 bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0);
365 bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1);
366 memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) +
367 (bank1_ac ? (1 << (bank1_ac + 1)) : 0);
368 memsize <<= 20;
369 add_memory_region(0, memsize, BOOT_MEM_RAM);
370 iounmap(sdram_base);
371
372 ar5312_rst_base = ioremap_nocache(AR5312_RST_BASE, AR5312_RST_SIZE);
373
374 devid = ar5312_rst_reg_read(AR5312_REV);
375 devid >>= AR5312_REV_WMAC_MIN_S;
376 devid &= AR5312_REV_CHIP;
377 ath25_board.devid = (u16)devid;
378
379 /* Clear any lingering AHB errors */
380 ar5312_rst_reg_read(AR5312_PROCADDR);
381 ar5312_rst_reg_read(AR5312_DMAADDR);
382 ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE);
383
384 _machine_restart = ar5312_restart;
385}
386
387void __init ar5312_arch_init(void)
388{
389 unsigned irq = irq_create_mapping(ar5312_misc_irq_domain,
390 AR5312_MISC_IRQ_UART0);
391
392 ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency());
393}
diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h
new file mode 100644
index 000000000000..470abb0052bd
--- /dev/null
+++ b/arch/mips/ath25/ar5312.h
@@ -0,0 +1,22 @@
1#ifndef __AR5312_H
2#define __AR5312_H
3
4#ifdef CONFIG_SOC_AR5312
5
6void ar5312_arch_init_irq(void);
7void ar5312_init_devices(void);
8void ar5312_plat_time_init(void);
9void ar5312_plat_mem_setup(void);
10void ar5312_arch_init(void);
11
12#else
13
14static inline void ar5312_arch_init_irq(void) {}
15static inline void ar5312_init_devices(void) {}
16static inline void ar5312_plat_time_init(void) {}
17static inline void ar5312_plat_mem_setup(void) {}
18static inline void ar5312_arch_init(void) {}
19
20#endif
21
22#endif /* __AR5312_H */
diff --git a/arch/mips/ath25/ar5312_regs.h b/arch/mips/ath25/ar5312_regs.h
new file mode 100644
index 000000000000..4b947f967439
--- /dev/null
+++ b/arch/mips/ath25/ar5312_regs.h
@@ -0,0 +1,224 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
8 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
9 */
10
11#ifndef __ASM_MACH_ATH25_AR5312_REGS_H
12#define __ASM_MACH_ATH25_AR5312_REGS_H
13
14/*
15 * IRQs
16 */
17#define AR5312_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */
18#define AR5312_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */
19#define AR5312_IRQ_ENET1 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */
20#define AR5312_IRQ_WLAN1 (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */
21#define AR5312_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */
22
23/*
24 * Miscellaneous interrupts, which share IP6.
25 */
26#define AR5312_MISC_IRQ_TIMER 0
27#define AR5312_MISC_IRQ_AHB_PROC 1
28#define AR5312_MISC_IRQ_AHB_DMA 2
29#define AR5312_MISC_IRQ_GPIO 3
30#define AR5312_MISC_IRQ_UART0 4
31#define AR5312_MISC_IRQ_UART0_DMA 5
32#define AR5312_MISC_IRQ_WATCHDOG 6
33#define AR5312_MISC_IRQ_LOCAL 7
34#define AR5312_MISC_IRQ_SPI 8
35#define AR5312_MISC_IRQ_COUNT 9
36
37/*
38 * Address Map
39 *
40 * The AR5312 supports 2 enet MACS, even though many reference boards only
41 * actually use 1 of them (i.e. Only MAC 0 is actually connected to an enet
42 * PHY or PHY switch. The AR2312 supports 1 enet MAC.
43 */
44#define AR5312_WLAN0_BASE 0x18000000
45#define AR5312_ENET0_BASE 0x18100000
46#define AR5312_ENET1_BASE 0x18200000
47#define AR5312_SDRAMCTL_BASE 0x18300000
48#define AR5312_SDRAMCTL_SIZE 0x00000010
49#define AR5312_FLASHCTL_BASE 0x18400000
50#define AR5312_FLASHCTL_SIZE 0x00000010
51#define AR5312_WLAN1_BASE 0x18500000
52#define AR5312_UART0_BASE 0x1c000000 /* UART MMR */
53#define AR5312_GPIO_BASE 0x1c002000
54#define AR5312_GPIO_SIZE 0x00000010
55#define AR5312_RST_BASE 0x1c003000
56#define AR5312_RST_SIZE 0x00000100
57#define AR5312_FLASH_BASE 0x1e000000
58#define AR5312_FLASH_SIZE 0x00800000
59
60/*
61 * Need these defines to determine true number of ethernet MACs
62 */
63#define AR5312_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */
64#define AR5312_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */
65#define AR5312_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */
66
67/* Reset/Timer Block Address Map */
68#define AR5312_TIMER 0x0000 /* countdown timer */
69#define AR5312_RELOAD 0x0004 /* timer reload value */
70#define AR5312_WDT_CTRL 0x0008 /* watchdog cntrl */
71#define AR5312_WDT_TIMER 0x000c /* watchdog timer */
72#define AR5312_ISR 0x0010 /* Intr Status Reg */
73#define AR5312_IMR 0x0014 /* Intr Mask Reg */
74#define AR5312_RESET 0x0020
75#define AR5312_CLOCKCTL1 0x0064
76#define AR5312_SCRATCH 0x006c
77#define AR5312_PROCADDR 0x0070
78#define AR5312_PROC1 0x0074
79#define AR5312_DMAADDR 0x0078
80#define AR5312_DMA1 0x007c
81#define AR5312_ENABLE 0x0080 /* interface enb */
82#define AR5312_REV 0x0090 /* revision */
83
84/* AR5312_WDT_CTRL register bit field definitions */
85#define AR5312_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */
86#define AR5312_WDT_CTRL_NMI 0x00000001
87#define AR5312_WDT_CTRL_RESET 0x00000002
88
89/* AR5312_ISR register bit field definitions */
90#define AR5312_ISR_TIMER 0x00000001
91#define AR5312_ISR_AHBPROC 0x00000002
92#define AR5312_ISR_AHBDMA 0x00000004
93#define AR5312_ISR_GPIO 0x00000008
94#define AR5312_ISR_UART0 0x00000010
95#define AR5312_ISR_UART0DMA 0x00000020
96#define AR5312_ISR_WD 0x00000040
97#define AR5312_ISR_LOCAL 0x00000080
98
99/* AR5312_RESET register bit field definitions */
100#define AR5312_RESET_SYSTEM 0x00000001 /* cold reset full system */
101#define AR5312_RESET_PROC 0x00000002 /* cold reset MIPS core */
102#define AR5312_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC/BB */
103#define AR5312_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */
104#define AR5312_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */
105#define AR5312_RESET_ENET0 0x00000020 /* cold reset ENET0 MAC */
106#define AR5312_RESET_ENET1 0x00000040 /* cold reset ENET1 MAC */
107#define AR5312_RESET_UART0 0x00000100 /* cold reset UART0 */
108#define AR5312_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */
109#define AR5312_RESET_APB 0x00000400 /* cold reset APB ar5312 */
110#define AR5312_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */
111#define AR5312_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */
112#define AR5312_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BB */
113#define AR5312_RESET_NMI 0x00010000 /* send an NMI to the CPU */
114#define AR5312_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 MAC */
115#define AR5312_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 BB */
116#define AR5312_RESET_LOCAL_BUS 0x00080000 /* reset local bus */
117#define AR5312_RESET_WDOG 0x00100000 /* last reset was a wdt */
118
119#define AR5312_RESET_WMAC0_BITS (AR5312_RESET_WLAN0 |\
120 AR5312_RESET_WARM_WLAN0_MAC |\
121 AR5312_RESET_WARM_WLAN0_BB)
122
123#define AR5312_RESET_WMAC1_BITS (AR5312_RESET_WLAN1 |\
124 AR5312_RESET_WARM_WLAN1_MAC |\
125 AR5312_RESET_WARM_WLAN1_BB)
126
127/* AR5312_CLOCKCTL1 register bit field definitions */
128#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030
129#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4
130#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00
131#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8
132#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000
133
134/* Valid for AR5312 and AR2312 */
135#define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030
136#define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4
137#define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00
138#define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8
139#define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000
140
141/* Valid for AR2313 */
142#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000
143#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12
144#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000
145#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16
146#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000
147
148/* AR5312_ENABLE register bit field definitions */
149#define AR5312_ENABLE_WLAN0 0x00000001
150#define AR5312_ENABLE_ENET0 0x00000002
151#define AR5312_ENABLE_ENET1 0x00000004
152#define AR5312_ENABLE_UART_AND_WLAN1_PIO 0x00000008/* UART & WLAN1 PIO */
153#define AR5312_ENABLE_WLAN1_DMA 0x00000010/* WLAN1 DMAs */
154#define AR5312_ENABLE_WLAN1 (AR5312_ENABLE_UART_AND_WLAN1_PIO |\
155 AR5312_ENABLE_WLAN1_DMA)
156
157/* AR5312_REV register bit field definitions */
158#define AR5312_REV_WMAC_MAJ 0x0000f000
159#define AR5312_REV_WMAC_MAJ_S 12
160#define AR5312_REV_WMAC_MIN 0x00000f00
161#define AR5312_REV_WMAC_MIN_S 8
162#define AR5312_REV_MAJ 0x000000f0
163#define AR5312_REV_MAJ_S 4
164#define AR5312_REV_MIN 0x0000000f
165#define AR5312_REV_MIN_S 0
166#define AR5312_REV_CHIP (AR5312_REV_MAJ|AR5312_REV_MIN)
167
168/* Major revision numbers, bits 7..4 of Revision ID register */
169#define AR5312_REV_MAJ_AR5312 0x4
170#define AR5312_REV_MAJ_AR2313 0x5
171
172/* Minor revision numbers, bits 3..0 of Revision ID register */
173#define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */
174#define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */
175
176/*
177 * ARM Flash Controller -- 3 flash banks with either x8 or x16 devices
178 */
179#define AR5312_FLASHCTL0 0x0000
180#define AR5312_FLASHCTL1 0x0004
181#define AR5312_FLASHCTL2 0x0008
182
183/* AR5312_FLASHCTL register bit field definitions */
184#define AR5312_FLASHCTL_IDCY 0x0000000f /* Idle cycle turnaround time */
185#define AR5312_FLASHCTL_IDCY_S 0
186#define AR5312_FLASHCTL_WST1 0x000003e0 /* Wait state 1 */
187#define AR5312_FLASHCTL_WST1_S 5
188#define AR5312_FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */
189#define AR5312_FLASHCTL_WST2 0x0000f800 /* Wait state 2 */
190#define AR5312_FLASHCTL_WST2_S 11
191#define AR5312_FLASHCTL_AC 0x00070000 /* Flash addr check (added) */
192#define AR5312_FLASHCTL_AC_S 16
193#define AR5312_FLASHCTL_AC_128K 0x00000000
194#define AR5312_FLASHCTL_AC_256K 0x00010000
195#define AR5312_FLASHCTL_AC_512K 0x00020000
196#define AR5312_FLASHCTL_AC_1M 0x00030000
197#define AR5312_FLASHCTL_AC_2M 0x00040000
198#define AR5312_FLASHCTL_AC_4M 0x00050000
199#define AR5312_FLASHCTL_AC_8M 0x00060000
200#define AR5312_FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */
201#define AR5312_FLASHCTL_E 0x00080000 /* Flash bank enable (added) */
202#define AR5312_FLASHCTL_BUSERR 0x01000000 /* Bus transfer error flag */
203#define AR5312_FLASHCTL_WPERR 0x02000000 /* Write protect error flag */
204#define AR5312_FLASHCTL_WP 0x04000000 /* Write protect */
205#define AR5312_FLASHCTL_BM 0x08000000 /* Burst mode */
206#define AR5312_FLASHCTL_MW 0x30000000 /* Mem width */
207#define AR5312_FLASHCTL_MW8 0x00000000 /* Mem width x8 */
208#define AR5312_FLASHCTL_MW16 0x10000000 /* Mem width x16 */
209#define AR5312_FLASHCTL_MW32 0x20000000 /* Mem width x32 (not supp) */
210#define AR5312_FLASHCTL_ATNR 0x00000000 /* Access == no retry */
211#define AR5312_FLASHCTL_ATR 0x80000000 /* Access == retry every */
212#define AR5312_FLASHCTL_ATR4 0xc0000000 /* Access == retry every 4 */
213
214/*
215 * ARM SDRAM Controller -- just enough to determine memory size
216 */
217#define AR5312_MEM_CFG1 0x0004
218
219#define AR5312_MEM_CFG1_AC0_M 0x00000700 /* bank 0: SDRAM addr check */
220#define AR5312_MEM_CFG1_AC0_S 8
221#define AR5312_MEM_CFG1_AC1_M 0x00007000 /* bank 1: SDRAM addr check */
222#define AR5312_MEM_CFG1_AC1_S 12
223
224#endif /* __ASM_MACH_ATH25_AR5312_REGS_H */
diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c
new file mode 100644
index 000000000000..b8bb78282d6a
--- /dev/null
+++ b/arch/mips/ath25/board.c
@@ -0,0 +1,234 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
7 * Copyright (C) 2006 FON Technology, SL.
8 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
9 * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
10 */
11
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <asm/irq_cpu.h>
15#include <asm/reboot.h>
16#include <asm/bootinfo.h>
17#include <asm/time.h>
18
19#include <ath25_platform.h>
20#include "devices.h"
21#include "ar5312.h"
22#include "ar2315.h"
23
24void (*ath25_irq_dispatch)(void);
25
26static inline bool check_radio_magic(const void __iomem *addr)
27{
28 addr += 0x7a; /* offset for flash magic */
29 return (__raw_readb(addr) == 0x5a) && (__raw_readb(addr + 1) == 0xa5);
30}
31
32static inline bool check_notempty(const void __iomem *addr)
33{
34 return __raw_readl(addr) != 0xffffffff;
35}
36
37static inline bool check_board_data(const void __iomem *addr, bool broken)
38{
39 /* config magic found */
40 if (__raw_readl(addr) == ATH25_BD_MAGIC)
41 return true;
42
43 if (!broken)
44 return false;
45
46 /* broken board data detected, use radio data to find the
47 * offset, user will fix this */
48
49 if (check_radio_magic(addr + 0x1000))
50 return true;
51 if (check_radio_magic(addr + 0xf8))
52 return true;
53
54 return false;
55}
56
57static const void __iomem * __init find_board_config(const void __iomem *limit,
58 const bool broken)
59{
60 const void __iomem *addr;
61 const void __iomem *begin = limit - 0x1000;
62 const void __iomem *end = limit - 0x30000;
63
64 for (addr = begin; addr >= end; addr -= 0x1000)
65 if (check_board_data(addr, broken))
66 return addr;
67
68 return NULL;
69}
70
71static const void __iomem * __init find_radio_config(const void __iomem *limit,
72 const void __iomem *bcfg)
73{
74 const void __iomem *rcfg, *begin, *end;
75
76 /*
77 * Now find the start of Radio Configuration data, using heuristics:
78 * Search forward from Board Configuration data by 0x1000 bytes
79 * at a time until we find non-0xffffffff.
80 */
81 begin = bcfg + 0x1000;
82 end = limit;
83 for (rcfg = begin; rcfg < end; rcfg += 0x1000)
84 if (check_notempty(rcfg) && check_radio_magic(rcfg))
85 return rcfg;
86
87 /* AR2316 relocates radio config to new location */
88 begin = bcfg + 0xf8;
89 end = limit - 0x1000 + 0xf8;
90 for (rcfg = begin; rcfg < end; rcfg += 0x1000)
91 if (check_notempty(rcfg) && check_radio_magic(rcfg))
92 return rcfg;
93
94 return NULL;
95}
96
97/*
98 * NB: Search region size could be larger than the actual flash size,
99 * but this shouldn't be a problem here, because the flash
100 * will simply be mapped multiple times.
101 */
102int __init ath25_find_config(phys_addr_t base, unsigned long size)
103{
104 const void __iomem *flash_base, *flash_limit;
105 struct ath25_boarddata *config;
106 unsigned int rcfg_size;
107 int broken_boarddata = 0;
108 const void __iomem *bcfg, *rcfg;
109 u8 *board_data;
110 u8 *radio_data;
111 u8 *mac_addr;
112 u32 offset;
113
114 flash_base = ioremap_nocache(base, size);
115 flash_limit = flash_base + size;
116
117 ath25_board.config = NULL;
118 ath25_board.radio = NULL;
119
120 /* Copy the board and radio data to RAM, because accessing the mapped
121 * memory of the flash directly after booting is not safe */
122
123 /* Try to find valid board and radio data */
124 bcfg = find_board_config(flash_limit, false);
125
126 /* If that fails, try to at least find valid radio data */
127 if (!bcfg) {
128 bcfg = find_board_config(flash_limit, true);
129 broken_boarddata = 1;
130 }
131
132 if (!bcfg) {
133 pr_warn("WARNING: No board configuration data found!\n");
134 goto error;
135 }
136
137 board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL);
138 ath25_board.config = (struct ath25_boarddata *)board_data;
139 memcpy_fromio(board_data, bcfg, 0x100);
140 if (broken_boarddata) {
141 pr_warn("WARNING: broken board data detected\n");
142 config = ath25_board.config;
143 if (is_zero_ether_addr(config->enet0_mac)) {
144 pr_info("Fixing up empty mac addresses\n");
145 config->reset_config_gpio = 0xffff;
146 config->sys_led_gpio = 0xffff;
147 random_ether_addr(config->wlan0_mac);
148 config->wlan0_mac[0] &= ~0x06;
149 random_ether_addr(config->enet0_mac);
150 random_ether_addr(config->enet1_mac);
151 }
152 }
153
154 /* Radio config starts 0x100 bytes after board config, regardless
155 * of what the physical layout on the flash chip looks like */
156
157 rcfg = find_radio_config(flash_limit, bcfg);
158 if (!rcfg) {
159 pr_warn("WARNING: Could not find Radio Configuration data\n");
160 goto error;
161 }
162
163 radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff);
164 ath25_board.radio = radio_data;
165 offset = radio_data - board_data;
166 pr_info("Radio config found at offset 0x%x (0x%x)\n", rcfg - bcfg,
167 offset);
168 rcfg_size = BOARD_CONFIG_BUFSZ - offset;
169 memcpy_fromio(radio_data, rcfg, rcfg_size);
170
171 mac_addr = &radio_data[0x1d * 2];
172 if (is_broadcast_ether_addr(mac_addr)) {
173 pr_info("Radio MAC is blank; using board-data\n");
174 ether_addr_copy(mac_addr, ath25_board.config->wlan0_mac);
175 }
176
177 iounmap(flash_base);
178
179 return 0;
180
181error:
182 iounmap(flash_base);
183 return -ENODEV;
184}
185
186static void ath25_halt(void)
187{
188 local_irq_disable();
189 unreachable();
190}
191
192void __init plat_mem_setup(void)
193{
194 _machine_halt = ath25_halt;
195 pm_power_off = ath25_halt;
196
197 if (is_ar5312())
198 ar5312_plat_mem_setup();
199 else
200 ar2315_plat_mem_setup();
201
202 /* Disable data watchpoints */
203 write_c0_watchlo0(0);
204}
205
206asmlinkage void plat_irq_dispatch(void)
207{
208 ath25_irq_dispatch();
209}
210
211void __init plat_time_init(void)
212{
213 if (is_ar5312())
214 ar5312_plat_time_init();
215 else
216 ar2315_plat_time_init();
217}
218
219unsigned int __cpuinit get_c0_compare_int(void)
220{
221 return CP0_LEGACY_COMPARE_IRQ;
222}
223
224void __init arch_init_irq(void)
225{
226 clear_c0_status(ST0_IM);
227 mips_cpu_irq_init();
228
229 /* Initialize interrupt controllers */
230 if (is_ar5312())
231 ar5312_arch_init_irq();
232 else
233 ar2315_arch_init_irq();
234}
diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c
new file mode 100644
index 000000000000..7a64567d1ac3
--- /dev/null
+++ b/arch/mips/ath25/devices.c
@@ -0,0 +1,125 @@
1#include <linux/kernel.h>
2#include <linux/init.h>
3#include <linux/serial_8250.h>
4#include <linux/platform_device.h>
5#include <asm/bootinfo.h>
6
7#include <ath25_platform.h>
8#include "devices.h"
9#include "ar5312.h"
10#include "ar2315.h"
11
12struct ar231x_board_config ath25_board;
13enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN;
14
15static struct resource ath25_wmac0_res[] = {
16 {
17 .name = "wmac0_membase",
18 .flags = IORESOURCE_MEM,
19 },
20 {
21 .name = "wmac0_irq",
22 .flags = IORESOURCE_IRQ,
23 }
24};
25
26static struct resource ath25_wmac1_res[] = {
27 {
28 .name = "wmac1_membase",
29 .flags = IORESOURCE_MEM,
30 },
31 {
32 .name = "wmac1_irq",
33 .flags = IORESOURCE_IRQ,
34 }
35};
36
37static struct platform_device ath25_wmac[] = {
38 {
39 .id = 0,
40 .name = "ar231x-wmac",
41 .resource = ath25_wmac0_res,
42 .num_resources = ARRAY_SIZE(ath25_wmac0_res),
43 .dev.platform_data = &ath25_board,
44 },
45 {
46 .id = 1,
47 .name = "ar231x-wmac",
48 .resource = ath25_wmac1_res,
49 .num_resources = ARRAY_SIZE(ath25_wmac1_res),
50 .dev.platform_data = &ath25_board,
51 },
52};
53
54static const char * const soc_type_strings[] = {
55 [ATH25_SOC_AR5312] = "Atheros AR5312",
56 [ATH25_SOC_AR2312] = "Atheros AR2312",
57 [ATH25_SOC_AR2313] = "Atheros AR2313",
58 [ATH25_SOC_AR2315] = "Atheros AR2315",
59 [ATH25_SOC_AR2316] = "Atheros AR2316",
60 [ATH25_SOC_AR2317] = "Atheros AR2317",
61 [ATH25_SOC_AR2318] = "Atheros AR2318",
62 [ATH25_SOC_UNKNOWN] = "Atheros (unknown)",
63};
64
65const char *get_system_type(void)
66{
67 if ((ath25_soc >= ARRAY_SIZE(soc_type_strings)) ||
68 !soc_type_strings[ath25_soc])
69 return soc_type_strings[ATH25_SOC_UNKNOWN];
70 return soc_type_strings[ath25_soc];
71}
72
73void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk)
74{
75 struct uart_port s;
76
77 memset(&s, 0, sizeof(s));
78
79 s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP;
80 s.iotype = UPIO_MEM32;
81 s.irq = irq;
82 s.regshift = 2;
83 s.mapbase = mapbase;
84 s.uartclk = uartclk;
85
86 early_serial_setup(&s);
87}
88
89int __init ath25_add_wmac(int nr, u32 base, int irq)
90{
91 struct resource *res;
92
93 ath25_wmac[nr].dev.platform_data = &ath25_board;
94 res = &ath25_wmac[nr].resource[0];
95 res->start = base;
96 res->end = base + 0x10000 - 1;
97 res++;
98 res->start = irq;
99 res->end = irq;
100 return platform_device_register(&ath25_wmac[nr]);
101}
102
103static int __init ath25_register_devices(void)
104{
105 if (is_ar5312())
106 ar5312_init_devices();
107 else
108 ar2315_init_devices();
109
110 return 0;
111}
112
113device_initcall(ath25_register_devices);
114
115static int __init ath25_arch_init(void)
116{
117 if (is_ar5312())
118 ar5312_arch_init();
119 else
120 ar2315_arch_init();
121
122 return 0;
123}
124
125arch_initcall(ath25_arch_init);
diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h
new file mode 100644
index 000000000000..04d414115356
--- /dev/null
+++ b/arch/mips/ath25/devices.h
@@ -0,0 +1,43 @@
1#ifndef __ATH25_DEVICES_H
2#define __ATH25_DEVICES_H
3
4#include <linux/cpu.h>
5
6#define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S)
7
8#define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */
9
10enum ath25_soc_type {
11 /* handled by ar5312.c */
12 ATH25_SOC_AR2312,
13 ATH25_SOC_AR2313,
14 ATH25_SOC_AR5312,
15
16 /* handled by ar2315.c */
17 ATH25_SOC_AR2315,
18 ATH25_SOC_AR2316,
19 ATH25_SOC_AR2317,
20 ATH25_SOC_AR2318,
21
22 ATH25_SOC_UNKNOWN
23};
24
25extern enum ath25_soc_type ath25_soc;
26extern struct ar231x_board_config ath25_board;
27extern void (*ath25_irq_dispatch)(void);
28
29int ath25_find_config(phys_addr_t offset, unsigned long size);
30void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk);
31int ath25_add_wmac(int nr, u32 base, int irq);
32
33static inline bool is_ar2315(void)
34{
35 return (current_cpu_data.cputype == CPU_4KEC);
36}
37
38static inline bool is_ar5312(void)
39{
40 return !is_ar2315();
41}
42
43#endif
diff --git a/arch/mips/ath25/early_printk.c b/arch/mips/ath25/early_printk.c
new file mode 100644
index 000000000000..36035b628161
--- /dev/null
+++ b/arch/mips/ath25/early_printk.c
@@ -0,0 +1,44 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
7 */
8
9#include <linux/mm.h>
10#include <linux/io.h>
11#include <linux/serial_reg.h>
12
13#include "devices.h"
14#include "ar2315_regs.h"
15#include "ar5312_regs.h"
16
17static inline void prom_uart_wr(void __iomem *base, unsigned reg,
18 unsigned char ch)
19{
20 __raw_writel(ch, base + 4 * reg);
21}
22
23static inline unsigned char prom_uart_rr(void __iomem *base, unsigned reg)
24{
25 return __raw_readl(base + 4 * reg);
26}
27
28void prom_putchar(unsigned char ch)
29{
30 static void __iomem *base;
31
32 if (unlikely(base == NULL)) {
33 if (is_ar2315())
34 base = (void __iomem *)(KSEG1ADDR(AR2315_UART0_BASE));
35 else
36 base = (void __iomem *)(KSEG1ADDR(AR5312_UART0_BASE));
37 }
38
39 while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0)
40 ;
41 prom_uart_wr(base, UART_TX, ch);
42 while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0)
43 ;
44}
diff --git a/arch/mips/ath25/prom.c b/arch/mips/ath25/prom.c
new file mode 100644
index 000000000000..edf82be8870d
--- /dev/null
+++ b/arch/mips/ath25/prom.c
@@ -0,0 +1,26 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright MontaVista Software Inc
7 * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
8 * Copyright (C) 2006 FON Technology, SL.
9 * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
10 * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
11 */
12
13/*
14 * Prom setup file for AR5312/AR231x SoCs
15 */
16
17#include <linux/init.h>
18#include <asm/bootinfo.h>
19
20void __init prom_init(void)
21{
22}
23
24void __init prom_free_prom_memory(void)
25{
26}
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index 9c0e1761773f..6adae366f11a 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -359,7 +359,6 @@ void __init arch_init_irq(void)
359 BUG(); 359 BUG();
360 } 360 }
361 361
362 cp0_perfcount_irq = ATH79_MISC_IRQ(5);
363 mips_cpu_irq_init(); 362 mips_cpu_irq_init();
364 ath79_misc_irq_init(); 363 ath79_misc_irq_init();
365 364
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c
index e9cbd7c2918f..e1fe63051136 100644
--- a/arch/mips/ath79/prom.c
+++ b/arch/mips/ath79/prom.c
@@ -13,42 +13,24 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/initrd.h>
16 17
17#include <asm/bootinfo.h> 18#include <asm/bootinfo.h>
18#include <asm/addrspace.h> 19#include <asm/addrspace.h>
20#include <asm/fw/fw.h>
19 21
20#include "common.h" 22#include "common.h"
21 23
22static inline int is_valid_ram_addr(void *addr)
23{
24 if (((u32) addr > KSEG0) &&
25 ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX)))
26 return 1;
27
28 if (((u32) addr > KSEG1) &&
29 ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX)))
30 return 1;
31
32 return 0;
33}
34
35static __init void ath79_prom_init_cmdline(int argc, char **argv)
36{
37 int i;
38
39 if (!is_valid_ram_addr(argv))
40 return;
41
42 for (i = 0; i < argc; i++)
43 if (is_valid_ram_addr(argv[i])) {
44 strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
45 strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
46 }
47}
48
49void __init prom_init(void) 24void __init prom_init(void)
50{ 25{
51 ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); 26 fw_init_cmdline();
27
28 /* Read the initrd address from the firmware environment */
29 initrd_start = fw_getenvl("initrd_start");
30 if (initrd_start) {
31 initrd_start = KSEG0ADDR(initrd_start);
32 initrd_end = initrd_start + fw_getenvl("initrd_size");
33 }
52} 34}
53 35
54void __init prom_free_prom_memory(void) 36void __init prom_free_prom_memory(void)
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 64807a4809d0..a73c93c3d44a 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -182,6 +182,11 @@ const char *get_system_type(void)
182 return ath79_sys_type; 182 return ath79_sys_type;
183} 183}
184 184
185int get_c0_perfcount_int(void)
186{
187 return ATH79_MISC_IRQ(5);
188}
189
185unsigned int get_c0_compare_int(void) 190unsigned int get_c0_compare_int(void)
186{ 191{
187 return CP0_LEGACY_COMPARE_IRQ; 192 return CP0_LEGACY_COMPARE_IRQ;
diff --git a/arch/mips/bcm3384/Makefile b/arch/mips/bcm3384/Makefile
new file mode 100644
index 000000000000..a393955cba08
--- /dev/null
+++ b/arch/mips/bcm3384/Makefile
@@ -0,0 +1 @@
obj-y += setup.o irq.o dma.o
diff --git a/arch/mips/bcm3384/Platform b/arch/mips/bcm3384/Platform
new file mode 100644
index 000000000000..8e1ca0819e1b
--- /dev/null
+++ b/arch/mips/bcm3384/Platform
@@ -0,0 +1,7 @@
1#
2# Broadcom BCM3384 boards
3#
4platform-$(CONFIG_BCM3384) += bcm3384/
5cflags-$(CONFIG_BCM3384) += \
6 -I$(srctree)/arch/mips/include/asm/mach-bcm3384/
7load-$(CONFIG_BCM3384) := 0xffffffff80010000
diff --git a/arch/mips/bcm3384/dma.c b/arch/mips/bcm3384/dma.c
new file mode 100644
index 000000000000..ea42012fd4f5
--- /dev/null
+++ b/arch/mips/bcm3384/dma.c
@@ -0,0 +1,81 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
7 */
8
9#include <linux/device.h>
10#include <linux/dma-direction.h>
11#include <linux/dma-mapping.h>
12#include <linux/init.h>
13#include <linux/mm.h>
14#include <linux/of.h>
15#include <linux/pci.h>
16#include <linux/types.h>
17#include <dma-coherence.h>
18
19/*
20 * BCM3384 has configurable address translation windows which allow the
21 * peripherals' DMA addresses to be different from the Zephyr-visible
22 * physical addresses. e.g. usb_dma_addr = zephyr_pa ^ 0x08000000
23 *
24 * If our DT "memory" node has a "dma-xor-mask" property we will enable this
25 * translation using the provided offset.
26 */
27static u32 bcm3384_dma_xor_mask;
28static u32 bcm3384_dma_xor_limit = 0xffffffff;
29
30/*
31 * PCI collapses the memory hole at 0x10000000 - 0x1fffffff.
32 * On systems with a dma-xor-mask, this range is guaranteed to live above
33 * the dma-xor-limit.
34 */
35#define BCM3384_MEM_HOLE_PA 0x10000000
36#define BCM3384_MEM_HOLE_SIZE 0x10000000
37
38static dma_addr_t bcm3384_phys_to_dma(struct device *dev, phys_addr_t pa)
39{
40 if (dev && dev_is_pci(dev) &&
41 pa >= (BCM3384_MEM_HOLE_PA + BCM3384_MEM_HOLE_SIZE))
42 return pa - BCM3384_MEM_HOLE_SIZE;
43 if (pa <= bcm3384_dma_xor_limit)
44 return pa ^ bcm3384_dma_xor_mask;
45 return pa;
46}
47
48dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
49{
50 return bcm3384_phys_to_dma(dev, virt_to_phys(addr));
51}
52
53dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
54{
55 return bcm3384_phys_to_dma(dev, page_to_phys(page));
56}
57
58unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
59{
60 if (dev && dev_is_pci(dev) &&
61 dma_addr >= BCM3384_MEM_HOLE_PA)
62 return dma_addr + BCM3384_MEM_HOLE_SIZE;
63 if ((dma_addr ^ bcm3384_dma_xor_mask) <= bcm3384_dma_xor_limit)
64 return dma_addr ^ bcm3384_dma_xor_mask;
65 return dma_addr;
66}
67
68static int __init bcm3384_init_dma_xor(void)
69{
70 struct device_node *np = of_find_node_by_type(NULL, "memory");
71
72 if (!np)
73 return 0;
74
75 of_property_read_u32(np, "dma-xor-mask", &bcm3384_dma_xor_mask);
76 of_property_read_u32(np, "dma-xor-limit", &bcm3384_dma_xor_limit);
77
78 of_node_put(np);
79 return 0;
80}
81arch_initcall(bcm3384_init_dma_xor);
diff --git a/arch/mips/bcm3384/irq.c b/arch/mips/bcm3384/irq.c
new file mode 100644
index 000000000000..0fb5134fb832
--- /dev/null
+++ b/arch/mips/bcm3384/irq.c
@@ -0,0 +1,193 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Partially based on arch/mips/ralink/irq.c
7 *
8 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
9 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
10 * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
11 */
12
13#include <linux/io.h>
14#include <linux/bitops.h>
15#include <linux/of_platform.h>
16#include <linux/of_address.h>
17#include <linux/of_irq.h>
18#include <linux/irqdomain.h>
19#include <linux/interrupt.h>
20#include <linux/slab.h>
21#include <linux/spinlock.h>
22
23#include <asm/bmips.h>
24#include <asm/irq_cpu.h>
25#include <asm/mipsregs.h>
26
27/* INTC register offsets */
28#define INTC_REG_ENABLE 0x00
29#define INTC_REG_STATUS 0x04
30
31#define MAX_WORDS 2
32#define IRQS_PER_WORD 32
33
34struct bcm3384_intc {
35 int n_words;
36 void __iomem *reg[MAX_WORDS];
37 u32 enable[MAX_WORDS];
38 spinlock_t lock;
39};
40
41static void bcm3384_intc_irq_unmask(struct irq_data *d)
42{
43 struct bcm3384_intc *priv = d->domain->host_data;
44 unsigned long flags;
45 int idx = d->hwirq / IRQS_PER_WORD;
46 int bit = d->hwirq % IRQS_PER_WORD;
47
48 spin_lock_irqsave(&priv->lock, flags);
49 priv->enable[idx] |= BIT(bit);
50 __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE);
51 spin_unlock_irqrestore(&priv->lock, flags);
52}
53
54static void bcm3384_intc_irq_mask(struct irq_data *d)
55{
56 struct bcm3384_intc *priv = d->domain->host_data;
57 unsigned long flags;
58 int idx = d->hwirq / IRQS_PER_WORD;
59 int bit = d->hwirq % IRQS_PER_WORD;
60
61 spin_lock_irqsave(&priv->lock, flags);
62 priv->enable[idx] &= ~BIT(bit);
63 __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE);
64 spin_unlock_irqrestore(&priv->lock, flags);
65}
66
67static struct irq_chip bcm3384_intc_irq_chip = {
68 .name = "INTC",
69 .irq_unmask = bcm3384_intc_irq_unmask,
70 .irq_mask = bcm3384_intc_irq_mask,
71 .irq_mask_ack = bcm3384_intc_irq_mask,
72};
73
74unsigned int get_c0_compare_int(void)
75{
76 return CP0_LEGACY_COMPARE_IRQ;
77}
78
79static void bcm3384_intc_irq_handler(unsigned int irq, struct irq_desc *desc)
80{
81 struct irq_domain *domain = irq_get_handler_data(irq);
82 struct bcm3384_intc *priv = domain->host_data;
83 unsigned long flags;
84 unsigned int idx;
85
86 for (idx = 0; idx < priv->n_words; idx++) {
87 unsigned long pending;
88 int hwirq;
89
90 spin_lock_irqsave(&priv->lock, flags);
91 pending = __raw_readl(priv->reg[idx] + INTC_REG_STATUS) &
92 priv->enable[idx];
93 spin_unlock_irqrestore(&priv->lock, flags);
94
95 for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
96 generic_handle_irq(irq_find_mapping(domain,
97 hwirq + idx * IRQS_PER_WORD));
98 }
99 }
100}
101
102asmlinkage void plat_irq_dispatch(void)
103{
104 unsigned long pending =
105 (read_c0_status() & read_c0_cause() & ST0_IM) >> STATUSB_IP0;
106 int bit;
107
108 for_each_set_bit(bit, &pending, 8)
109 do_IRQ(MIPS_CPU_IRQ_BASE + bit);
110}
111
112static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
113{
114 irq_set_chip_and_handler(irq, &bcm3384_intc_irq_chip, handle_level_irq);
115 return 0;
116}
117
118static const struct irq_domain_ops irq_domain_ops = {
119 .xlate = irq_domain_xlate_onecell,
120 .map = intc_map,
121};
122
123static int __init ioremap_one_pair(struct bcm3384_intc *priv,
124 struct device_node *node,
125 int idx)
126{
127 struct resource res;
128
129 if (of_address_to_resource(node, idx, &res))
130 return 0;
131
132 if (request_mem_region(res.start, resource_size(&res),
133 res.name) < 0)
134 pr_err("Failed to request INTC register region\n");
135
136 priv->reg[idx] = ioremap_nocache(res.start, resource_size(&res));
137 if (!priv->reg[idx])
138 panic("Failed to ioremap INTC register range");
139
140 /* start up with everything masked before we hook the parent IRQ */
141 __raw_writel(0, priv->reg[idx] + INTC_REG_ENABLE);
142 priv->enable[idx] = 0;
143
144 return IRQS_PER_WORD;
145}
146
147static int __init intc_of_init(struct device_node *node,
148 struct device_node *parent)
149{
150 struct irq_domain *domain;
151 unsigned int parent_irq, n_irqs = 0;
152 struct bcm3384_intc *priv;
153
154 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
155 if (!priv)
156 panic("Failed to allocate bcm3384_intc struct");
157
158 spin_lock_init(&priv->lock);
159
160 parent_irq = irq_of_parse_and_map(node, 0);
161 if (!parent_irq)
162 panic("Failed to get INTC IRQ");
163
164 n_irqs += ioremap_one_pair(priv, node, 0);
165 n_irqs += ioremap_one_pair(priv, node, 1);
166
167 if (!n_irqs)
168 panic("Failed to map INTC registers");
169
170 priv->n_words = n_irqs / IRQS_PER_WORD;
171 domain = irq_domain_add_linear(node, n_irqs, &irq_domain_ops, priv);
172 if (!domain)
173 panic("Failed to add irqdomain");
174
175 irq_set_chained_handler(parent_irq, bcm3384_intc_irq_handler);
176 irq_set_handler_data(parent_irq, domain);
177
178 return 0;
179}
180
181static struct of_device_id of_irq_ids[] __initdata = {
182 { .compatible = "mti,cpu-interrupt-controller",
183 .data = mips_cpu_intc_init },
184 { .compatible = "brcm,bcm3384-intc",
185 .data = intc_of_init },
186 {},
187};
188
189void __init arch_init_irq(void)
190{
191 bmips_tp1_irqs = 0;
192 of_irq_init(of_irq_ids);
193}
diff --git a/arch/mips/bcm3384/setup.c b/arch/mips/bcm3384/setup.c
new file mode 100644
index 000000000000..d84b8400b874
--- /dev/null
+++ b/arch/mips/bcm3384/setup.c
@@ -0,0 +1,97 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
8 */
9
10#include <linux/init.h>
11#include <linux/bootmem.h>
12#include <linux/clk-provider.h>
13#include <linux/ioport.h>
14#include <linux/of.h>
15#include <linux/of_fdt.h>
16#include <linux/of_platform.h>
17#include <linux/smp.h>
18#include <asm/addrspace.h>
19#include <asm/bmips.h>
20#include <asm/bootinfo.h>
21#include <asm/prom.h>
22#include <asm/smp-ops.h>
23#include <asm/time.h>
24
25void __init prom_init(void)
26{
27 register_bmips_smp_ops();
28}
29
30void __init prom_free_prom_memory(void)
31{
32}
33
34const char *get_system_type(void)
35{
36 return "BCM3384";
37}
38
39void __init plat_time_init(void)
40{
41 struct device_node *np;
42 u32 freq;
43
44 np = of_find_node_by_name(NULL, "cpus");
45 if (!np)
46 panic("missing 'cpus' DT node");
47 if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
48 panic("missing 'mips-hpt-frequency' property");
49 of_node_put(np);
50
51 mips_hpt_frequency = freq;
52}
53
54void __init plat_mem_setup(void)
55{
56 void *dtb = __dtb_start;
57
58 set_io_port_base(0);
59 ioport_resource.start = 0;
60 ioport_resource.end = ~0;
61
62 /* intended to somewhat resemble ARM; see Documentation/arm/Booting */
63 if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
64 dtb = phys_to_virt(fw_arg2);
65
66 __dt_setup_arch(dtb);
67
68 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
69}
70
71void __init device_tree_init(void)
72{
73 struct device_node *np;
74
75 unflatten_and_copy_device_tree();
76
77 /* Disable SMP boot unless both CPUs are listed in DT and !disabled */
78 np = of_find_node_by_name(NULL, "cpus");
79 if (np && of_get_available_child_count(np) <= 1)
80 bmips_smp_enabled = 0;
81 of_node_put(np);
82}
83
84int __init plat_of_setup(void)
85{
86 return __dt_register_buses("brcm,bcm3384", "simple-bus");
87}
88
89arch_initcall(plat_of_setup);
90
91static int __init plat_dev_init(void)
92{
93 of_clk_init(NULL);
94 return 0;
95}
96
97device_initcall(plat_dev_init);
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h
index f1cc9d0495d8..ea909a56a3ee 100644
--- a/arch/mips/bcm47xx/bcm47xx_private.h
+++ b/arch/mips/bcm47xx/bcm47xx_private.h
@@ -6,12 +6,18 @@
6/* prom.c */ 6/* prom.c */
7void __init bcm47xx_prom_highmem_init(void); 7void __init bcm47xx_prom_highmem_init(void);
8 8
9/* sprom.c */
10void bcm47xx_sprom_register_fallbacks(void);
11
9/* buttons.c */ 12/* buttons.c */
10int __init bcm47xx_buttons_register(void); 13int __init bcm47xx_buttons_register(void);
11 14
12/* leds.c */ 15/* leds.c */
13void __init bcm47xx_leds_register(void); 16void __init bcm47xx_leds_register(void);
14 17
18/* setup.c */
19void __init bcm47xx_bus_setup(void);
20
15/* workarounds.c */ 21/* workarounds.c */
16void __init bcm47xx_workarounds(void); 22void __init bcm47xx_workarounds(void);
17 23
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c
index e0585b76ec19..21b4497f09be 100644
--- a/arch/mips/bcm47xx/irq.c
+++ b/arch/mips/bcm47xx/irq.c
@@ -22,6 +22,8 @@
22 * 675 Mass Ave, Cambridge, MA 02139, USA. 22 * 675 Mass Ave, Cambridge, MA 02139, USA.
23 */ 23 */
24 24
25#include "bcm47xx_private.h"
26
25#include <linux/types.h> 27#include <linux/types.h>
26#include <linux/interrupt.h> 28#include <linux/interrupt.h>
27#include <linux/irq.h> 29#include <linux/irq.h>
@@ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7)
65 67
66void __init arch_init_irq(void) 68void __init arch_init_irq(void)
67{ 69{
70 /*
71 * This is the first arch callback after mm_init (we can use kmalloc),
72 * so let's finish bus initialization now.
73 */
74 bcm47xx_bus_setup();
75
68#ifdef CONFIG_BCM47XX_BCMA 76#ifdef CONFIG_BCM47XX_BCMA
69 if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { 77 if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
70 bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, 78 bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core,
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index 2bed73a684ae..c5c381c43f17 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -13,24 +13,35 @@
13 13
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/ssb/ssb.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/string.h> 17#include <linux/string.h>
19#include <asm/addrspace.h> 18#include <linux/mtd/mtd.h>
20#include <bcm47xx_nvram.h> 19#include <bcm47xx_nvram.h>
21#include <asm/mach-bcm47xx/bcm47xx.h> 20
21#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
22#define NVRAM_SPACE 0x8000
23
24#define FLASH_MIN 0x00020000 /* Minimum flash size */
25
26struct nvram_header {
27 u32 magic;
28 u32 len;
29 u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
30 u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
31 u32 config_ncdl; /* ncdl values for memc */
32};
22 33
23static char nvram_buf[NVRAM_SPACE]; 34static char nvram_buf[NVRAM_SPACE];
24static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; 35static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
25 36
26static u32 find_nvram_size(u32 end) 37static u32 find_nvram_size(void __iomem *end)
27{ 38{
28 struct nvram_header *header; 39 struct nvram_header __iomem *header;
29 int i; 40 int i;
30 41
31 for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { 42 for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
32 header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); 43 header = (struct nvram_header *)(end - nvram_sizes[i]);
33 if (header->magic == NVRAM_HEADER) 44 if (header->magic == NVRAM_MAGIC)
34 return nvram_sizes[i]; 45 return nvram_sizes[i];
35 } 46 }
36 47
@@ -38,36 +49,40 @@ static u32 find_nvram_size(u32 end)
38} 49}
39 50
40/* Probe for NVRAM header */ 51/* Probe for NVRAM header */
41static int nvram_find_and_copy(u32 base, u32 lim) 52static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
42{ 53{
43 struct nvram_header *header; 54 struct nvram_header __iomem *header;
44 int i; 55 int i;
45 u32 off; 56 u32 off;
46 u32 *src, *dst; 57 u32 *src, *dst;
47 u32 size; 58 u32 size;
48 59
60 if (nvram_buf[0]) {
61 pr_warn("nvram already initialized\n");
62 return -EEXIST;
63 }
64
49 /* TODO: when nvram is on nand flash check for bad blocks first. */ 65 /* TODO: when nvram is on nand flash check for bad blocks first. */
50 off = FLASH_MIN; 66 off = FLASH_MIN;
51 while (off <= lim) { 67 while (off <= lim) {
52 /* Windowed flash access */ 68 /* Windowed flash access */
53 size = find_nvram_size(base + off); 69 size = find_nvram_size(iobase + off);
54 if (size) { 70 if (size) {
55 header = (struct nvram_header *)KSEG1ADDR(base + off - 71 header = (struct nvram_header *)(iobase + off - size);
56 size);
57 goto found; 72 goto found;
58 } 73 }
59 off <<= 1; 74 off <<= 1;
60 } 75 }
61 76
62 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ 77 /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
63 header = (struct nvram_header *) KSEG1ADDR(base + 4096); 78 header = (struct nvram_header *)(iobase + 4096);
64 if (header->magic == NVRAM_HEADER) { 79 if (header->magic == NVRAM_MAGIC) {
65 size = NVRAM_SPACE; 80 size = NVRAM_SPACE;
66 goto found; 81 goto found;
67 } 82 }
68 83
69 header = (struct nvram_header *) KSEG1ADDR(base + 1024); 84 header = (struct nvram_header *)(iobase + 1024);
70 if (header->magic == NVRAM_HEADER) { 85 if (header->magic == NVRAM_MAGIC) {
71 size = NVRAM_SPACE; 86 size = NVRAM_SPACE;
72 goto found; 87 goto found;
73 } 88 }
@@ -94,71 +109,73 @@ found:
94 return 0; 109 return 0;
95} 110}
96 111
97#ifdef CONFIG_BCM47XX_SSB 112/*
98static int nvram_init_ssb(void) 113 * On bcm47xx we need access to the NVRAM very early, so we can't use mtd
114 * subsystem to access flash. We can't even use platform device / driver to
115 * store memory offset.
116 * To handle this we provide following symbol. It's supposed to be called as
117 * soon as we get info about flash device, before any NVRAM entry is needed.
118 */
119int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
99{ 120{
100 struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; 121 void __iomem *iobase;
101 u32 base; 122 int err;
102 u32 lim;
103
104 if (mcore->pflash.present) {
105 base = mcore->pflash.window;
106 lim = mcore->pflash.window_size;
107 } else {
108 pr_err("Couldn't find supported flash memory\n");
109 return -ENXIO;
110 }
111 123
112 return nvram_find_and_copy(base, lim); 124 iobase = ioremap_nocache(base, lim);
113} 125 if (!iobase)
114#endif 126 return -ENOMEM;
115 127
116#ifdef CONFIG_BCM47XX_BCMA 128 err = nvram_find_and_copy(iobase, lim);
117static int nvram_init_bcma(void) 129
118{ 130 iounmap(iobase);
119 struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc;
120 u32 base;
121 u32 lim;
122
123#ifdef CONFIG_BCMA_NFLASH
124 if (cc->nflash.boot) {
125 base = BCMA_SOC_FLASH1;
126 lim = BCMA_SOC_FLASH1_SZ;
127 } else
128#endif
129 if (cc->pflash.present) {
130 base = cc->pflash.window;
131 lim = cc->pflash.window_size;
132#ifdef CONFIG_BCMA_SFLASH
133 } else if (cc->sflash.present) {
134 base = cc->sflash.window;
135 lim = cc->sflash.size;
136#endif
137 } else {
138 pr_err("Couldn't find supported flash memory\n");
139 return -ENXIO;
140 }
141 131
142 return nvram_find_and_copy(base, lim); 132 return err;
143} 133}
144#endif
145 134
146static int nvram_init(void) 135static int nvram_init(void)
147{ 136{
148 switch (bcm47xx_bus_type) { 137#ifdef CONFIG_MTD
149#ifdef CONFIG_BCM47XX_SSB 138 struct mtd_info *mtd;
150 case BCM47XX_BUS_TYPE_SSB: 139 struct nvram_header header;
151 return nvram_init_ssb(); 140 size_t bytes_read;
152#endif 141 int err, i;
153#ifdef CONFIG_BCM47XX_BCMA 142
154 case BCM47XX_BUS_TYPE_BCMA: 143 mtd = get_mtd_device_nm("nvram");
155 return nvram_init_bcma(); 144 if (IS_ERR(mtd))
156#endif 145 return -ENODEV;
146
147 for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
148 loff_t from = mtd->size - nvram_sizes[i];
149
150 if (from < 0)
151 continue;
152
153 err = mtd_read(mtd, from, sizeof(header), &bytes_read,
154 (uint8_t *)&header);
155 if (!err && header.magic == NVRAM_MAGIC) {
156 u8 *dst = (uint8_t *)nvram_buf;
157 size_t len = header.len;
158
159 if (header.len > NVRAM_SPACE) {
160 pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
161 header.len, NVRAM_SPACE);
162 len = NVRAM_SPACE;
163 }
164
165 err = mtd_read(mtd, from, len, &bytes_read, dst);
166 if (err)
167 return err;
168 memset(dst + bytes_read, 0x0, NVRAM_SPACE - bytes_read);
169
170 return 0;
171 }
157 } 172 }
173#endif
174
158 return -ENXIO; 175 return -ENXIO;
159} 176}
160 177
161int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len) 178int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
162{ 179{
163 char *var, *value, *end, *eq; 180 char *var, *value, *end, *eq;
164 int err; 181 int err;
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index c00585d915bc..e43b5046cb30 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void)
102} 102}
103 103
104#ifdef CONFIG_BCM47XX_SSB 104#ifdef CONFIG_BCM47XX_SSB
105static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
106{
107 char prefix[10];
108
109 if (bus->bustype == SSB_BUSTYPE_PCI) {
110 memset(out, 0, sizeof(struct ssb_sprom));
111 snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
112 bus->host_pci->bus->number + 1,
113 PCI_SLOT(bus->host_pci->devfn));
114 bcm47xx_fill_sprom(out, prefix, false);
115 return 0;
116 } else {
117 printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n");
118 return -EINVAL;
119 }
120}
121
122static int bcm47xx_get_invariants(struct ssb_bus *bus, 105static int bcm47xx_get_invariants(struct ssb_bus *bus,
123 struct ssb_init_invariants *iv) 106 struct ssb_init_invariants *iv)
124{ 107{
@@ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void)
144 char buf[100]; 127 char buf[100];
145 struct ssb_mipscore *mcore; 128 struct ssb_mipscore *mcore;
146 129
147 err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb);
148 if (err)
149 printk(KERN_WARNING "bcm47xx: someone else already registered"
150 " a ssb SPROM callback handler (err %d)\n", err);
151
152 err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, 130 err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
153 bcm47xx_get_invariants); 131 bcm47xx_get_invariants);
154 if (err) 132 if (err)
@@ -171,56 +149,21 @@ static void __init bcm47xx_register_ssb(void)
171#endif 149#endif
172 150
173#ifdef CONFIG_BCM47XX_BCMA 151#ifdef CONFIG_BCM47XX_BCMA
174static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
175{
176 char prefix[10];
177 struct bcma_device *core;
178
179 switch (bus->hosttype) {
180 case BCMA_HOSTTYPE_PCI:
181 memset(out, 0, sizeof(struct ssb_sprom));
182 snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
183 bus->host_pci->bus->number + 1,
184 PCI_SLOT(bus->host_pci->devfn));
185 bcm47xx_fill_sprom(out, prefix, false);
186 return 0;
187 case BCMA_HOSTTYPE_SOC:
188 memset(out, 0, sizeof(struct ssb_sprom));
189 core = bcma_find_core(bus, BCMA_CORE_80211);
190 if (core) {
191 snprintf(prefix, sizeof(prefix), "sb/%u/",
192 core->core_index);
193 bcm47xx_fill_sprom(out, prefix, true);
194 } else {
195 bcm47xx_fill_sprom(out, NULL, false);
196 }
197 return 0;
198 default:
199 pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
200 return -EINVAL;
201 }
202}
203
204static void __init bcm47xx_register_bcma(void) 152static void __init bcm47xx_register_bcma(void)
205{ 153{
206 int err; 154 int err;
207 155
208 err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma);
209 if (err)
210 pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err);
211
212 err = bcma_host_soc_register(&bcm47xx_bus.bcma); 156 err = bcma_host_soc_register(&bcm47xx_bus.bcma);
213 if (err) 157 if (err)
214 panic("Failed to register BCMA bus (err %d)", err); 158 panic("Failed to register BCMA bus (err %d)", err);
215
216 err = bcma_host_soc_init(&bcm47xx_bus.bcma);
217 if (err)
218 panic("Failed to initialize BCMA bus (err %d)", err);
219
220 bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL);
221} 159}
222#endif 160#endif
223 161
162/*
163 * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed
164 * to detect memory and record it with add_memory_region.
165 * Any extra initializaion performed here must not use kmalloc or bootmem.
166 */
224void __init plat_mem_setup(void) 167void __init plat_mem_setup(void)
225{ 168{
226 struct cpuinfo_mips *c = &current_cpu_data; 169 struct cpuinfo_mips *c = &current_cpu_data;
@@ -229,6 +172,7 @@ void __init plat_mem_setup(void)
229 printk(KERN_INFO "bcm47xx: using bcma bus\n"); 172 printk(KERN_INFO "bcm47xx: using bcma bus\n");
230#ifdef CONFIG_BCM47XX_BCMA 173#ifdef CONFIG_BCM47XX_BCMA
231 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; 174 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
175 bcm47xx_sprom_register_fallbacks();
232 bcm47xx_register_bcma(); 176 bcm47xx_register_bcma();
233 bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); 177 bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
234#ifdef CONFIG_HIGHMEM 178#ifdef CONFIG_HIGHMEM
@@ -239,6 +183,7 @@ void __init plat_mem_setup(void)
239 printk(KERN_INFO "bcm47xx: using ssb bus\n"); 183 printk(KERN_INFO "bcm47xx: using ssb bus\n");
240#ifdef CONFIG_BCM47XX_SSB 184#ifdef CONFIG_BCM47XX_SSB
241 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; 185 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
186 bcm47xx_sprom_register_fallbacks();
242 bcm47xx_register_ssb(); 187 bcm47xx_register_ssb();
243 bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); 188 bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id);
244#endif 189#endif
@@ -247,6 +192,28 @@ void __init plat_mem_setup(void)
247 _machine_restart = bcm47xx_machine_restart; 192 _machine_restart = bcm47xx_machine_restart;
248 _machine_halt = bcm47xx_machine_halt; 193 _machine_halt = bcm47xx_machine_halt;
249 pm_power_off = bcm47xx_machine_halt; 194 pm_power_off = bcm47xx_machine_halt;
195}
196
197/*
198 * This finishes bus initialization doing things that were not possible without
199 * kmalloc. Make sure to call it late enough (after mm_init).
200 */
201void __init bcm47xx_bus_setup(void)
202{
203#ifdef CONFIG_BCM47XX_BCMA
204 if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
205 int err;
206
207 err = bcma_host_soc_init(&bcm47xx_bus.bcma);
208 if (err)
209 panic("Failed to initialize BCMA bus (err %d)", err);
210
211 bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo,
212 NULL);
213 }
214#endif
215
216 /* With bus initialized we can access NVRAM and detect the board */
250 bcm47xx_board_detect(); 217 bcm47xx_board_detect();
251 mips_set_machine_name(bcm47xx_board_get_name()); 218 mips_set_machine_name(bcm47xx_board_get_name());
252} 219}
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
index 41226b68de3d..2eff7fe99c6b 100644
--- a/arch/mips/bcm47xx/sprom.c
+++ b/arch/mips/bcm47xx/sprom.c
@@ -136,6 +136,20 @@ static void nvram_read_leddc(const char *prefix, const char *name,
136 *leddc_off_time = (val >> 16) & 0xff; 136 *leddc_off_time = (val >> 16) & 0xff;
137} 137}
138 138
139static void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
140{
141 if (strchr(buf, ':'))
142 sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
143 &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
144 &macaddr[5]);
145 else if (strchr(buf, '-'))
146 sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
147 &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
148 &macaddr[5]);
149 else
150 pr_warn("Can not parse mac address: %s\n", buf);
151}
152
139static void nvram_read_macaddr(const char *prefix, const char *name, 153static void nvram_read_macaddr(const char *prefix, const char *name,
140 u8 val[6], bool fallback) 154 u8 val[6], bool fallback)
141{ 155{
@@ -801,3 +815,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
801 nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); 815 nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
802} 816}
803#endif 817#endif
818
819#if defined(CONFIG_BCM47XX_SSB)
820static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
821{
822 char prefix[10];
823
824 if (bus->bustype == SSB_BUSTYPE_PCI) {
825 memset(out, 0, sizeof(struct ssb_sprom));
826 snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
827 bus->host_pci->bus->number + 1,
828 PCI_SLOT(bus->host_pci->devfn));
829 bcm47xx_fill_sprom(out, prefix, false);
830 return 0;
831 } else {
832 pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
833 return -EINVAL;
834 }
835}
836#endif
837
838#if defined(CONFIG_BCM47XX_BCMA)
839static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
840{
841 char prefix[10];
842 struct bcma_device *core;
843
844 switch (bus->hosttype) {
845 case BCMA_HOSTTYPE_PCI:
846 memset(out, 0, sizeof(struct ssb_sprom));
847 snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
848 bus->host_pci->bus->number + 1,
849 PCI_SLOT(bus->host_pci->devfn));
850 bcm47xx_fill_sprom(out, prefix, false);
851 return 0;
852 case BCMA_HOSTTYPE_SOC:
853 memset(out, 0, sizeof(struct ssb_sprom));
854 core = bcma_find_core(bus, BCMA_CORE_80211);
855 if (core) {
856 snprintf(prefix, sizeof(prefix), "sb/%u/",
857 core->core_index);
858 bcm47xx_fill_sprom(out, prefix, true);
859 } else {
860 bcm47xx_fill_sprom(out, NULL, false);
861 }
862 return 0;
863 default:
864 pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
865 return -EINVAL;
866 }
867}
868#endif
869
870/*
871 * On bcm47xx we need to register SPROM fallback handler very early, so we can't
872 * use anything like platform device / driver for this.
873 */
874void bcm47xx_sprom_register_fallbacks(void)
875{
876#if defined(CONFIG_BCM47XX_SSB)
877 if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb))
878 pr_warn("Failed to registered ssb SPROM handler\n");
879#endif
880
881#if defined(CONFIG_BCM47XX_BCMA)
882 if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma))
883 pr_warn("Failed to registered bcma SPROM handler\n");
884#endif
885}
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 536f64443031..307ec8b8e41c 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -263,7 +263,7 @@ static unsigned int detect_memory_size(void)
263 263
264 if (BCMCPU_IS_6345()) { 264 if (BCMCPU_IS_6345()) {
265 val = bcm_sdram_readl(SDRAM_MBASE_REG); 265 val = bcm_sdram_readl(SDRAM_MBASE_REG);
266 return (val * 8 * 1024 * 1024); 266 return val * 8 * 1024 * 1024;
267 } 267 }
268 268
269 if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { 269 if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index ca9c90e2cabf..4f49fa477f14 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -1,3 +1,4 @@
1dtb-$(CONFIG_BCM3384) += bcm93384wvg.dtb
1dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb 2dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb
2dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb 3dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb
3dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb 4dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb
diff --git a/arch/mips/boot/dts/bcm3384.dtsi b/arch/mips/boot/dts/bcm3384.dtsi
new file mode 100644
index 000000000000..21b074a99c94
--- /dev/null
+++ b/arch/mips/boot/dts/bcm3384.dtsi
@@ -0,0 +1,109 @@
1/ {
2 #address-cells = <1>;
3 #size-cells = <1>;
4 compatible = "brcm,bcm3384", "brcm,bcm33843";
5
6 cpus {
7 #address-cells = <1>;
8 #size-cells = <0>;
9
10 /* On BMIPS5000 this is 1/8th of the CPU core clock */
11 mips-hpt-frequency = <100000000>;
12
13 cpu@0 {
14 compatible = "brcm,bmips5000";
15 device_type = "cpu";
16 reg = <0>;
17 };
18
19 cpu@1 {
20 compatible = "brcm,bmips5000";
21 device_type = "cpu";
22 reg = <1>;
23 };
24 };
25
26 clocks {
27 #address-cells = <1>;
28 #size-cells = <0>;
29
30 periph_clk: periph_clk@0 {
31 compatible = "fixed-clock";
32 #clock-cells = <0>;
33 clock-frequency = <54000000>;
34 };
35 };
36
37 aliases {
38 uart0 = &uart0;
39 };
40
41 cpu_intc: cpu_intc@0 {
42 #address-cells = <0>;
43 compatible = "mti,cpu-interrupt-controller";
44
45 interrupt-controller;
46 #interrupt-cells = <1>;
47 };
48
49 periph_intc: periph_intc@14e00038 {
50 compatible = "brcm,bcm3384-intc";
51 reg = <0x14e00038 0x8 0x14e00340 0x8>;
52
53 interrupt-controller;
54 #interrupt-cells = <1>;
55
56 interrupt-parent = <&cpu_intc>;
57 interrupts = <4>;
58 };
59
60 zmips_intc: zmips_intc@104b0060 {
61 compatible = "brcm,bcm3384-intc";
62 reg = <0x104b0060 0x8>;
63
64 interrupt-controller;
65 #interrupt-cells = <1>;
66
67 interrupt-parent = <&periph_intc>;
68 interrupts = <29>;
69 };
70
71 iop_intc: iop_intc@14e00058 {
72 compatible = "brcm,bcm3384-intc";
73 reg = <0x14e00058 0x8>;
74
75 interrupt-controller;
76 #interrupt-cells = <1>;
77
78 interrupt-parent = <&cpu_intc>;
79 interrupts = <6>;
80 };
81
82 uart0: serial@14e00520 {
83 compatible = "brcm,bcm6345-uart";
84 reg = <0x14e00520 0x18>;
85 interrupt-parent = <&periph_intc>;
86 interrupts = <2>;
87 clocks = <&periph_clk>;
88 status = "disabled";
89 };
90
91 ehci0: usb@15400300 {
92 compatible = "brcm,bcm3384-ehci", "generic-ehci";
93 reg = <0x15400300 0x100>;
94 big-endian;
95 interrupt-parent = <&periph_intc>;
96 interrupts = <41>;
97 status = "disabled";
98 };
99
100 ohci0: usb@15400400 {
101 compatible = "brcm,bcm3384-ohci", "generic-ohci";
102 reg = <0x15400400 0x100>;
103 big-endian;
104 no-big-frame-no;
105 interrupt-parent = <&periph_intc>;
106 interrupts = <40>;
107 status = "disabled";
108 };
109};
diff --git a/arch/mips/boot/dts/bcm93384wvg.dts b/arch/mips/boot/dts/bcm93384wvg.dts
new file mode 100644
index 000000000000..831741179212
--- /dev/null
+++ b/arch/mips/boot/dts/bcm93384wvg.dts
@@ -0,0 +1,32 @@
1/dts-v1/;
2
3/include/ "bcm3384.dtsi"
4
5/ {
6 compatible = "brcm,bcm93384wvg", "brcm,bcm3384";
7 model = "Broadcom BCM93384WVG";
8
9 chosen {
10 bootargs = "console=ttyS0,115200";
11 stdout-path = &uart0;
12 };
13
14 memory@0 {
15 device_type = "memory";
16 reg = <0x0 0x04000000>;
17 dma-xor-mask = <0x08000000>;
18 dma-xor-limit = <0x0fffffff>;
19 };
20};
21
22&uart0 {
23 status = "okay";
24};
25
26&ehci0 {
27 status = "okay";
28};
29
30&ohci0 {
31 status = "okay";
32};
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 02f244475207..3778655c4a37 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -262,8 +262,8 @@ char *octeon_swiotlb;
262void __init plat_swiotlb_setup(void) 262void __init plat_swiotlb_setup(void)
263{ 263{
264 int i; 264 int i;
265 phys_t max_addr; 265 phys_addr_t max_addr;
266 phys_t addr_size; 266 phys_addr_t addr_size;
267 size_t swiotlbsize; 267 size_t swiotlbsize;
268 unsigned long swiotlb_nslabs; 268 unsigned long swiotlb_nslabs;
269 269
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c
index f4c1b36fdf65..e15b049b3bd7 100644
--- a/arch/mips/cavium-octeon/executive/octeon-model.c
+++ b/arch/mips/cavium-octeon/executive/octeon-model.c
@@ -28,22 +28,23 @@
28#include <asm/octeon/octeon.h> 28#include <asm/octeon/octeon.h>
29 29
30/** 30/**
31 * Given the chip processor ID from COP0, this function returns a 31 * Read a byte of fuse data
32 * string representing the chip model number. The string is of the 32 * @byte_addr: address to read
33 * form CNXXXXpX.X-FREQ-SUFFIX.
34 * - XXXX = The chip model number
35 * - X.X = Chip pass number
36 * - FREQ = Current frequency in Mhz
37 * - SUFFIX = NSP, EXP, SCP, SSP, or CP
38 *
39 * @chip_id: Chip ID
40 * 33 *
41 * Returns Model string 34 * Returns fuse value: 0 or 1
42 */ 35 */
43const char *octeon_model_get_string(uint32_t chip_id) 36static uint8_t __init cvmx_fuse_read_byte(int byte_addr)
44{ 37{
45 static char buffer[32]; 38 union cvmx_mio_fus_rcmd read_cmd;
46 return octeon_model_get_string_buffer(chip_id, buffer); 39
40 read_cmd.u64 = 0;
41 read_cmd.s.addr = byte_addr;
42 read_cmd.s.pend = 1;
43 cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
44 while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
45 && read_cmd.s.pend)
46 ;
47 return read_cmd.s.dat;
47} 48}
48 49
49/* 50/*
@@ -51,7 +52,8 @@ const char *octeon_model_get_string(uint32_t chip_id)
51 * as running early in u-boot static/global variables don't work when 52 * as running early in u-boot static/global variables don't work when
52 * running from flash. 53 * running from flash.
53 */ 54 */
54const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) 55static const char *__init octeon_model_get_string_buffer(uint32_t chip_id,
56 char *buffer)
55{ 57{
56 const char *family; 58 const char *family;
57 const char *core_model; 59 const char *core_model;
@@ -407,3 +409,22 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
407 sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); 409 sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix);
408 return buffer; 410 return buffer;
409} 411}
412
413/**
414 * Given the chip processor ID from COP0, this function returns a
415 * string representing the chip model number. The string is of the
416 * form CNXXXXpX.X-FREQ-SUFFIX.
417 * - XXXX = The chip model number
418 * - X.X = Chip pass number
419 * - FREQ = Current frequency in Mhz
420 * - SUFFIX = NSP, EXP, SCP, SSP, or CP
421 *
422 * @chip_id: Chip ID
423 *
424 * Returns Model string
425 */
426const char *__init octeon_model_get_string(uint32_t chip_id)
427{
428 static char buffer[32];
429 return octeon_model_get_string_buffer(chip_id, buffer);
430}
diff --git a/arch/mips/configs/bcm3384_defconfig b/arch/mips/configs/bcm3384_defconfig
new file mode 100644
index 000000000000..88711c28ff32
--- /dev/null
+++ b/arch/mips/configs/bcm3384_defconfig
@@ -0,0 +1,78 @@
1CONFIG_BCM3384=y
2CONFIG_HIGHMEM=y
3CONFIG_SMP=y
4CONFIG_NR_CPUS=4
5# CONFIG_SECCOMP is not set
6CONFIG_MIPS_O32_FP64_SUPPORT=y
7# CONFIG_LOCALVERSION_AUTO is not set
8# CONFIG_SWAP is not set
9CONFIG_NO_HZ=y
10CONFIG_BLK_DEV_INITRD=y
11# CONFIG_RD_GZIP is not set
12CONFIG_EXPERT=y
13# CONFIG_VM_EVENT_COUNTERS is not set
14# CONFIG_SLUB_DEBUG is not set
15# CONFIG_BLK_DEV_BSG is not set
16# CONFIG_IOSCHED_DEADLINE is not set
17# CONFIG_IOSCHED_CFQ is not set
18CONFIG_NET=y
19CONFIG_PACKET=y
20CONFIG_PACKET_DIAG=y
21CONFIG_UNIX=y
22CONFIG_INET=y
23# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
24# CONFIG_INET_XFRM_MODE_TUNNEL is not set
25# CONFIG_INET_XFRM_MODE_BEET is not set
26# CONFIG_INET_LRO is not set
27# CONFIG_INET_DIAG is not set
28CONFIG_CFG80211=y
29CONFIG_NL80211_TESTMODE=y
30CONFIG_MAC80211=y
31CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
32CONFIG_DEVTMPFS=y
33CONFIG_DEVTMPFS_MOUNT=y
34# CONFIG_STANDALONE is not set
35# CONFIG_PREVENT_FIRMWARE_BUILD is not set
36CONFIG_MTD=y
37CONFIG_MTD_CFI=y
38CONFIG_MTD_CFI_INTELEXT=y
39CONFIG_MTD_CFI_AMDSTD=y
40CONFIG_MTD_PHYSMAP=y
41# CONFIG_BLK_DEV is not set
42CONFIG_SCSI=y
43CONFIG_BLK_DEV_SD=y
44# CONFIG_SCSI_LOWLEVEL is not set
45CONFIG_NETDEVICES=y
46CONFIG_USB_USBNET=y
47# CONFIG_INPUT is not set
48# CONFIG_SERIO is not set
49# CONFIG_VT is not set
50# CONFIG_DEVKMEM is not set
51CONFIG_SERIAL_EARLYCON_FORCE=y
52CONFIG_SERIAL_BCM63XX=y
53CONFIG_SERIAL_BCM63XX_CONSOLE=y
54# CONFIG_HW_RANDOM is not set
55# CONFIG_HWMON is not set
56CONFIG_USB=y
57CONFIG_USB_EHCI_HCD=y
58# CONFIG_USB_EHCI_TT_NEWSCHED is not set
59CONFIG_USB_EHCI_HCD_PLATFORM=y
60CONFIG_USB_OHCI_HCD=y
61CONFIG_USB_OHCI_HCD_PLATFORM=y
62CONFIG_USB_STORAGE=y
63CONFIG_EXT4_FS=y
64CONFIG_EXT4_FS_POSIX_ACL=y
65CONFIG_EXT4_FS_SECURITY=y
66# CONFIG_DNOTIFY is not set
67CONFIG_FUSE_FS=y
68CONFIG_VFAT_FS=y
69CONFIG_PROC_KCORE=y
70CONFIG_TMPFS=y
71CONFIG_NFS_FS=y
72CONFIG_CIFS=y
73CONFIG_NLS_CODEPAGE_437=y
74CONFIG_NLS_ASCII=y
75CONFIG_NLS_ISO8859_1=y
76CONFIG_DEBUG_FS=y
77CONFIG_MAGIC_SYSRQ=y
78# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c
index ffd0345780ae..6ecda64ad184 100644
--- a/arch/mips/fw/lib/cmdline.c
+++ b/arch/mips/fw/lib/cmdline.c
@@ -68,7 +68,7 @@ char *fw_getenv(char *envname)
68 result = fw_envp(index + 1); 68 result = fw_envp(index + 1);
69 break; 69 break;
70 } else if (fw_envp(index)[i] == '=') { 70 } else if (fw_envp(index)[i] == '=') {
71 result = (fw_envp(index + 1) + i); 71 result = fw_envp(index) + i + 1;
72 break; 72 break;
73 } 73 }
74 } 74 }
@@ -88,13 +88,13 @@ unsigned long fw_getenvl(char *envname)
88{ 88{
89 unsigned long envl = 0UL; 89 unsigned long envl = 0UL;
90 char *str; 90 char *str;
91 long val;
92 int tmp; 91 int tmp;
93 92
94 str = fw_getenv(envname); 93 str = fw_getenv(envname);
95 if (str) { 94 if (str) {
96 tmp = kstrtol(str, 0, &val); 95 tmp = kstrtoul(str, 0, &envl);
97 envl = (unsigned long)val; 96 if (tmp)
97 envl = 0;
98 } 98 }
99 99
100 return envl; 100 return envl;
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 6dd6bfc607e9..857da84cfc92 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -17,6 +17,7 @@
17#include <linux/irqflags.h> 17#include <linux/irqflags.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <asm/barrier.h> 19#include <asm/barrier.h>
20#include <asm/compiler.h>
20#include <asm/cpu-features.h> 21#include <asm/cpu-features.h>
21#include <asm/cmpxchg.h> 22#include <asm/cmpxchg.h>
22#include <asm/war.h> 23#include <asm/war.h>
@@ -40,95 +41,97 @@
40 */ 41 */
41#define atomic_set(v, i) ((v)->counter = (i)) 42#define atomic_set(v, i) ((v)->counter = (i))
42 43
43#define ATOMIC_OP(op, c_op, asm_op) \ 44#define ATOMIC_OP(op, c_op, asm_op) \
44static __inline__ void atomic_##op(int i, atomic_t * v) \ 45static __inline__ void atomic_##op(int i, atomic_t * v) \
45{ \ 46{ \
46 if (kernel_uses_llsc && R10000_LLSC_WAR) { \ 47 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
47 int temp; \ 48 int temp; \
48 \ 49 \
49 __asm__ __volatile__( \ 50 __asm__ __volatile__( \
50 " .set arch=r4000 \n" \ 51 " .set arch=r4000 \n" \
51 "1: ll %0, %1 # atomic_" #op " \n" \ 52 "1: ll %0, %1 # atomic_" #op " \n" \
52 " " #asm_op " %0, %2 \n" \ 53 " " #asm_op " %0, %2 \n" \
53 " sc %0, %1 \n" \ 54 " sc %0, %1 \n" \
54 " beqzl %0, 1b \n" \ 55 " beqzl %0, 1b \n" \
55 " .set mips0 \n" \ 56 " .set mips0 \n" \
56 : "=&r" (temp), "+m" (v->counter) \ 57 : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
57 : "Ir" (i)); \ 58 : "Ir" (i)); \
58 } else if (kernel_uses_llsc) { \ 59 } else if (kernel_uses_llsc) { \
59 int temp; \ 60 int temp; \
60 \ 61 \
61 do { \ 62 do { \
62 __asm__ __volatile__( \ 63 __asm__ __volatile__( \
63 " .set arch=r4000 \n" \ 64 " .set arch=r4000 \n" \
64 " ll %0, %1 # atomic_" #op "\n" \ 65 " ll %0, %1 # atomic_" #op "\n" \
65 " " #asm_op " %0, %2 \n" \ 66 " " #asm_op " %0, %2 \n" \
66 " sc %0, %1 \n" \ 67 " sc %0, %1 \n" \
67 " .set mips0 \n" \ 68 " .set mips0 \n" \
68 : "=&r" (temp), "+m" (v->counter) \ 69 : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
69 : "Ir" (i)); \ 70 : "Ir" (i)); \
70 } while (unlikely(!temp)); \ 71 } while (unlikely(!temp)); \
71 } else { \ 72 } else { \
72 unsigned long flags; \ 73 unsigned long flags; \
73 \ 74 \
74 raw_local_irq_save(flags); \ 75 raw_local_irq_save(flags); \
75 v->counter c_op i; \ 76 v->counter c_op i; \
76 raw_local_irq_restore(flags); \ 77 raw_local_irq_restore(flags); \
77 } \ 78 } \
78} \
79
80#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
81static __inline__ int atomic_##op##_return(int i, atomic_t * v) \
82{ \
83 int result; \
84 \
85 smp_mb__before_llsc(); \
86 \
87 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
88 int temp; \
89 \
90 __asm__ __volatile__( \
91 " .set arch=r4000 \n" \
92 "1: ll %1, %2 # atomic_" #op "_return \n" \
93 " " #asm_op " %0, %1, %3 \n" \
94 " sc %0, %2 \n" \
95 " beqzl %0, 1b \n" \
96 " " #asm_op " %0, %1, %3 \n" \
97 " .set mips0 \n" \
98 : "=&r" (result), "=&r" (temp), "+m" (v->counter) \
99 : "Ir" (i)); \
100 } else if (kernel_uses_llsc) { \
101 int temp; \
102 \
103 do { \
104 __asm__ __volatile__( \
105 " .set arch=r4000 \n" \
106 " ll %1, %2 # atomic_" #op "_return \n" \
107 " " #asm_op " %0, %1, %3 \n" \
108 " sc %0, %2 \n" \
109 " .set mips0 \n" \
110 : "=&r" (result), "=&r" (temp), "+m" (v->counter) \
111 : "Ir" (i)); \
112 } while (unlikely(!result)); \
113 \
114 result = temp; result c_op i; \
115 } else { \
116 unsigned long flags; \
117 \
118 raw_local_irq_save(flags); \
119 result = v->counter; \
120 result c_op i; \
121 v->counter = result; \
122 raw_local_irq_restore(flags); \
123 } \
124 \
125 smp_llsc_mb(); \
126 \
127 return result; \
128} 79}
129 80
130#define ATOMIC_OPS(op, c_op, asm_op) \ 81#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
131 ATOMIC_OP(op, c_op, asm_op) \ 82static __inline__ int atomic_##op##_return(int i, atomic_t * v) \
83{ \
84 int result; \
85 \
86 smp_mb__before_llsc(); \
87 \
88 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
89 int temp; \
90 \
91 __asm__ __volatile__( \
92 " .set arch=r4000 \n" \
93 "1: ll %1, %2 # atomic_" #op "_return \n" \
94 " " #asm_op " %0, %1, %3 \n" \
95 " sc %0, %2 \n" \
96 " beqzl %0, 1b \n" \
97 " " #asm_op " %0, %1, %3 \n" \
98 " .set mips0 \n" \
99 : "=&r" (result), "=&r" (temp), \
100 "+" GCC_OFF12_ASM() (v->counter) \
101 : "Ir" (i)); \
102 } else if (kernel_uses_llsc) { \
103 int temp; \
104 \
105 do { \
106 __asm__ __volatile__( \
107 " .set arch=r4000 \n" \
108 " ll %1, %2 # atomic_" #op "_return \n" \
109 " " #asm_op " %0, %1, %3 \n" \
110 " sc %0, %2 \n" \
111 " .set mips0 \n" \
112 : "=&r" (result), "=&r" (temp), \
113 "+" GCC_OFF12_ASM() (v->counter) \
114 : "Ir" (i)); \
115 } while (unlikely(!result)); \
116 \
117 result = temp; result c_op i; \
118 } else { \
119 unsigned long flags; \
120 \
121 raw_local_irq_save(flags); \
122 result = v->counter; \
123 result c_op i; \
124 v->counter = result; \
125 raw_local_irq_restore(flags); \
126 } \
127 \
128 smp_llsc_mb(); \
129 \
130 return result; \
131}
132
133#define ATOMIC_OPS(op, c_op, asm_op) \
134 ATOMIC_OP(op, c_op, asm_op) \
132 ATOMIC_OP_RETURN(op, c_op, asm_op) 135 ATOMIC_OP_RETURN(op, c_op, asm_op)
133 136
134ATOMIC_OPS(add, +=, addu) 137ATOMIC_OPS(add, +=, addu)
@@ -167,8 +170,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
167 " .set reorder \n" 170 " .set reorder \n"
168 "1: \n" 171 "1: \n"
169 " .set mips0 \n" 172 " .set mips0 \n"
170 : "=&r" (result), "=&r" (temp), "+m" (v->counter) 173 : "=&r" (result), "=&r" (temp),
171 : "Ir" (i), "m" (v->counter) 174 "+" GCC_OFF12_ASM() (v->counter)
175 : "Ir" (i), GCC_OFF12_ASM() (v->counter)
172 : "memory"); 176 : "memory");
173 } else if (kernel_uses_llsc) { 177 } else if (kernel_uses_llsc) {
174 int temp; 178 int temp;
@@ -185,7 +189,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
185 " .set reorder \n" 189 " .set reorder \n"
186 "1: \n" 190 "1: \n"
187 " .set mips0 \n" 191 " .set mips0 \n"
188 : "=&r" (result), "=&r" (temp), "+m" (v->counter) 192 : "=&r" (result), "=&r" (temp),
193 "+" GCC_OFF12_ASM() (v->counter)
189 : "Ir" (i)); 194 : "Ir" (i));
190 } else { 195 } else {
191 unsigned long flags; 196 unsigned long flags;
@@ -315,96 +320,98 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
315 */ 320 */
316#define atomic64_set(v, i) ((v)->counter = (i)) 321#define atomic64_set(v, i) ((v)->counter = (i))
317 322
318#define ATOMIC64_OP(op, c_op, asm_op) \ 323#define ATOMIC64_OP(op, c_op, asm_op) \
319static __inline__ void atomic64_##op(long i, atomic64_t * v) \ 324static __inline__ void atomic64_##op(long i, atomic64_t * v) \
320{ \ 325{ \
321 if (kernel_uses_llsc && R10000_LLSC_WAR) { \ 326 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
322 long temp; \ 327 long temp; \
323 \ 328 \
324 __asm__ __volatile__( \ 329 __asm__ __volatile__( \
325 " .set arch=r4000 \n" \ 330 " .set arch=r4000 \n" \
326 "1: lld %0, %1 # atomic64_" #op " \n" \ 331 "1: lld %0, %1 # atomic64_" #op " \n" \
327 " " #asm_op " %0, %2 \n" \ 332 " " #asm_op " %0, %2 \n" \
328 " scd %0, %1 \n" \ 333 " scd %0, %1 \n" \
329 " beqzl %0, 1b \n" \ 334 " beqzl %0, 1b \n" \
330 " .set mips0 \n" \ 335 " .set mips0 \n" \
331 : "=&r" (temp), "+m" (v->counter) \ 336 : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
332 : "Ir" (i)); \ 337 : "Ir" (i)); \
333 } else if (kernel_uses_llsc) { \ 338 } else if (kernel_uses_llsc) { \
334 long temp; \ 339 long temp; \
335 \ 340 \
336 do { \ 341 do { \
337 __asm__ __volatile__( \ 342 __asm__ __volatile__( \
338 " .set arch=r4000 \n" \ 343 " .set arch=r4000 \n" \
339 " lld %0, %1 # atomic64_" #op "\n" \ 344 " lld %0, %1 # atomic64_" #op "\n" \
340 " " #asm_op " %0, %2 \n" \ 345 " " #asm_op " %0, %2 \n" \
341 " scd %0, %1 \n" \ 346 " scd %0, %1 \n" \
342 " .set mips0 \n" \ 347 " .set mips0 \n" \
343 : "=&r" (temp), "+m" (v->counter) \ 348 : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \
344 : "Ir" (i)); \ 349 : "Ir" (i)); \
345 } while (unlikely(!temp)); \ 350 } while (unlikely(!temp)); \
346 } else { \ 351 } else { \
347 unsigned long flags; \ 352 unsigned long flags; \
348 \ 353 \
349 raw_local_irq_save(flags); \ 354 raw_local_irq_save(flags); \
350 v->counter c_op i; \ 355 v->counter c_op i; \
351 raw_local_irq_restore(flags); \ 356 raw_local_irq_restore(flags); \
352 } \ 357 } \
353} \ 358}
354 359
355#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \ 360#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \
356static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ 361static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \
357{ \ 362{ \
358 long result; \ 363 long result; \
359 \ 364 \
360 smp_mb__before_llsc(); \ 365 smp_mb__before_llsc(); \
361 \ 366 \
362 if (kernel_uses_llsc && R10000_LLSC_WAR) { \ 367 if (kernel_uses_llsc && R10000_LLSC_WAR) { \
363 long temp; \ 368 long temp; \
364 \ 369 \
365 __asm__ __volatile__( \ 370 __asm__ __volatile__( \
366 " .set arch=r4000 \n" \ 371 " .set arch=r4000 \n" \
367 "1: lld %1, %2 # atomic64_" #op "_return\n" \ 372 "1: lld %1, %2 # atomic64_" #op "_return\n" \
368 " " #asm_op " %0, %1, %3 \n" \ 373 " " #asm_op " %0, %1, %3 \n" \
369 " scd %0, %2 \n" \ 374 " scd %0, %2 \n" \
370 " beqzl %0, 1b \n" \ 375 " beqzl %0, 1b \n" \
371 " " #asm_op " %0, %1, %3 \n" \ 376 " " #asm_op " %0, %1, %3 \n" \
372 " .set mips0 \n" \ 377 " .set mips0 \n" \
373 : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ 378 : "=&r" (result), "=&r" (temp), \
374 : "Ir" (i)); \ 379 "+" GCC_OFF12_ASM() (v->counter) \
375 } else if (kernel_uses_llsc) { \ 380 : "Ir" (i)); \
376 long temp; \ 381 } else if (kernel_uses_llsc) { \
377 \ 382 long temp; \
378 do { \ 383 \
379 __asm__ __volatile__( \ 384 do { \
380 " .set arch=r4000 \n" \ 385 __asm__ __volatile__( \
381 " lld %1, %2 # atomic64_" #op "_return\n" \ 386 " .set arch=r4000 \n" \
382 " " #asm_op " %0, %1, %3 \n" \ 387 " lld %1, %2 # atomic64_" #op "_return\n" \
383 " scd %0, %2 \n" \ 388 " " #asm_op " %0, %1, %3 \n" \
384 " .set mips0 \n" \ 389 " scd %0, %2 \n" \
385 : "=&r" (result), "=&r" (temp), "=m" (v->counter) \ 390 " .set mips0 \n" \
386 : "Ir" (i), "m" (v->counter) \ 391 : "=&r" (result), "=&r" (temp), \
387 : "memory"); \ 392 "=" GCC_OFF12_ASM() (v->counter) \
388 } while (unlikely(!result)); \ 393 : "Ir" (i), GCC_OFF12_ASM() (v->counter) \
389 \ 394 : "memory"); \
390 result = temp; result c_op i; \ 395 } while (unlikely(!result)); \
391 } else { \ 396 \
392 unsigned long flags; \ 397 result = temp; result c_op i; \
393 \ 398 } else { \
394 raw_local_irq_save(flags); \ 399 unsigned long flags; \
395 result = v->counter; \ 400 \
396 result c_op i; \ 401 raw_local_irq_save(flags); \
397 v->counter = result; \ 402 result = v->counter; \
398 raw_local_irq_restore(flags); \ 403 result c_op i; \
399 } \ 404 v->counter = result; \
400 \ 405 raw_local_irq_restore(flags); \
401 smp_llsc_mb(); \ 406 } \
402 \ 407 \
403 return result; \ 408 smp_llsc_mb(); \
409 \
410 return result; \
404} 411}
405 412
406#define ATOMIC64_OPS(op, c_op, asm_op) \ 413#define ATOMIC64_OPS(op, c_op, asm_op) \
407 ATOMIC64_OP(op, c_op, asm_op) \ 414 ATOMIC64_OP(op, c_op, asm_op) \
408 ATOMIC64_OP_RETURN(op, c_op, asm_op) 415 ATOMIC64_OP_RETURN(op, c_op, asm_op)
409 416
410ATOMIC64_OPS(add, +=, daddu) 417ATOMIC64_OPS(add, +=, daddu)
@@ -415,7 +422,8 @@ ATOMIC64_OPS(sub, -=, dsubu)
415#undef ATOMIC64_OP 422#undef ATOMIC64_OP
416 423
417/* 424/*
418 * atomic64_sub_if_positive - conditionally subtract integer from atomic variable 425 * atomic64_sub_if_positive - conditionally subtract integer from atomic
426 * variable
419 * @i: integer value to subtract 427 * @i: integer value to subtract
420 * @v: pointer of type atomic64_t 428 * @v: pointer of type atomic64_t
421 * 429 *
@@ -443,8 +451,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
443 " .set reorder \n" 451 " .set reorder \n"
444 "1: \n" 452 "1: \n"
445 " .set mips0 \n" 453 " .set mips0 \n"
446 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 454 : "=&r" (result), "=&r" (temp),
447 : "Ir" (i), "m" (v->counter) 455 "=" GCC_OFF12_ASM() (v->counter)
456 : "Ir" (i), GCC_OFF12_ASM() (v->counter)
448 : "memory"); 457 : "memory");
449 } else if (kernel_uses_llsc) { 458 } else if (kernel_uses_llsc) {
450 long temp; 459 long temp;
@@ -461,7 +470,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
461 " .set reorder \n" 470 " .set reorder \n"
462 "1: \n" 471 "1: \n"
463 " .set mips0 \n" 472 " .set mips0 \n"
464 : "=&r" (result), "=&r" (temp), "+m" (v->counter) 473 : "=&r" (result), "=&r" (temp),
474 "+" GCC_OFF12_ASM() (v->counter)
465 : "Ir" (i)); 475 : "Ir" (i));
466 } else { 476 } else {
467 unsigned long flags; 477 unsigned long flags;
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index bae6b0fa8ab5..6663bcca9d0c 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -17,6 +17,7 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <asm/barrier.h> 18#include <asm/barrier.h>
19#include <asm/byteorder.h> /* sigh ... */ 19#include <asm/byteorder.h> /* sigh ... */
20#include <asm/compiler.h>
20#include <asm/cpu-features.h> 21#include <asm/cpu-features.h>
21#include <asm/sgidefs.h> 22#include <asm/sgidefs.h>
22#include <asm/war.h> 23#include <asm/war.h>
@@ -78,8 +79,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
78 " " __SC "%0, %1 \n" 79 " " __SC "%0, %1 \n"
79 " beqzl %0, 1b \n" 80 " beqzl %0, 1b \n"
80 " .set mips0 \n" 81 " .set mips0 \n"
81 : "=&r" (temp), "=m" (*m) 82 : "=&r" (temp), "=" GCC_OFF12_ASM() (*m)
82 : "ir" (1UL << bit), "m" (*m)); 83 : "ir" (1UL << bit), GCC_OFF12_ASM() (*m));
83#ifdef CONFIG_CPU_MIPSR2 84#ifdef CONFIG_CPU_MIPSR2
84 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { 85 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
85 do { 86 do {
@@ -87,7 +88,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
87 " " __LL "%0, %1 # set_bit \n" 88 " " __LL "%0, %1 # set_bit \n"
88 " " __INS "%0, %3, %2, 1 \n" 89 " " __INS "%0, %3, %2, 1 \n"
89 " " __SC "%0, %1 \n" 90 " " __SC "%0, %1 \n"
90 : "=&r" (temp), "+m" (*m) 91 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
91 : "ir" (bit), "r" (~0)); 92 : "ir" (bit), "r" (~0));
92 } while (unlikely(!temp)); 93 } while (unlikely(!temp));
93#endif /* CONFIG_CPU_MIPSR2 */ 94#endif /* CONFIG_CPU_MIPSR2 */
@@ -99,7 +100,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
99 " or %0, %2 \n" 100 " or %0, %2 \n"
100 " " __SC "%0, %1 \n" 101 " " __SC "%0, %1 \n"
101 " .set mips0 \n" 102 " .set mips0 \n"
102 : "=&r" (temp), "+m" (*m) 103 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
103 : "ir" (1UL << bit)); 104 : "ir" (1UL << bit));
104 } while (unlikely(!temp)); 105 } while (unlikely(!temp));
105 } else 106 } else
@@ -130,7 +131,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
130 " " __SC "%0, %1 \n" 131 " " __SC "%0, %1 \n"
131 " beqzl %0, 1b \n" 132 " beqzl %0, 1b \n"
132 " .set mips0 \n" 133 " .set mips0 \n"
133 : "=&r" (temp), "+m" (*m) 134 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
134 : "ir" (~(1UL << bit))); 135 : "ir" (~(1UL << bit)));
135#ifdef CONFIG_CPU_MIPSR2 136#ifdef CONFIG_CPU_MIPSR2
136 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { 137 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
@@ -139,7 +140,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
139 " " __LL "%0, %1 # clear_bit \n" 140 " " __LL "%0, %1 # clear_bit \n"
140 " " __INS "%0, $0, %2, 1 \n" 141 " " __INS "%0, $0, %2, 1 \n"
141 " " __SC "%0, %1 \n" 142 " " __SC "%0, %1 \n"
142 : "=&r" (temp), "+m" (*m) 143 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
143 : "ir" (bit)); 144 : "ir" (bit));
144 } while (unlikely(!temp)); 145 } while (unlikely(!temp));
145#endif /* CONFIG_CPU_MIPSR2 */ 146#endif /* CONFIG_CPU_MIPSR2 */
@@ -151,7 +152,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
151 " and %0, %2 \n" 152 " and %0, %2 \n"
152 " " __SC "%0, %1 \n" 153 " " __SC "%0, %1 \n"
153 " .set mips0 \n" 154 " .set mips0 \n"
154 : "=&r" (temp), "+m" (*m) 155 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
155 : "ir" (~(1UL << bit))); 156 : "ir" (~(1UL << bit)));
156 } while (unlikely(!temp)); 157 } while (unlikely(!temp));
157 } else 158 } else
@@ -196,7 +197,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
196 " " __SC "%0, %1 \n" 197 " " __SC "%0, %1 \n"
197 " beqzl %0, 1b \n" 198 " beqzl %0, 1b \n"
198 " .set mips0 \n" 199 " .set mips0 \n"
199 : "=&r" (temp), "+m" (*m) 200 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
200 : "ir" (1UL << bit)); 201 : "ir" (1UL << bit));
201 } else if (kernel_uses_llsc) { 202 } else if (kernel_uses_llsc) {
202 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 203 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
@@ -209,7 +210,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
209 " xor %0, %2 \n" 210 " xor %0, %2 \n"
210 " " __SC "%0, %1 \n" 211 " " __SC "%0, %1 \n"
211 " .set mips0 \n" 212 " .set mips0 \n"
212 : "=&r" (temp), "+m" (*m) 213 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m)
213 : "ir" (1UL << bit)); 214 : "ir" (1UL << bit));
214 } while (unlikely(!temp)); 215 } while (unlikely(!temp));
215 } else 216 } else
@@ -244,7 +245,7 @@ static inline int test_and_set_bit(unsigned long nr,
244 " beqzl %2, 1b \n" 245 " beqzl %2, 1b \n"
245 " and %2, %0, %3 \n" 246 " and %2, %0, %3 \n"
246 " .set mips0 \n" 247 " .set mips0 \n"
247 : "=&r" (temp), "+m" (*m), "=&r" (res) 248 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
248 : "r" (1UL << bit) 249 : "r" (1UL << bit)
249 : "memory"); 250 : "memory");
250 } else if (kernel_uses_llsc) { 251 } else if (kernel_uses_llsc) {
@@ -258,7 +259,7 @@ static inline int test_and_set_bit(unsigned long nr,
258 " or %2, %0, %3 \n" 259 " or %2, %0, %3 \n"
259 " " __SC "%2, %1 \n" 260 " " __SC "%2, %1 \n"
260 " .set mips0 \n" 261 " .set mips0 \n"
261 : "=&r" (temp), "+m" (*m), "=&r" (res) 262 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
262 : "r" (1UL << bit) 263 : "r" (1UL << bit)
263 : "memory"); 264 : "memory");
264 } while (unlikely(!res)); 265 } while (unlikely(!res));
@@ -312,7 +313,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
312 " or %2, %0, %3 \n" 313 " or %2, %0, %3 \n"
313 " " __SC "%2, %1 \n" 314 " " __SC "%2, %1 \n"
314 " .set mips0 \n" 315 " .set mips0 \n"
315 : "=&r" (temp), "+m" (*m), "=&r" (res) 316 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
316 : "r" (1UL << bit) 317 : "r" (1UL << bit)
317 : "memory"); 318 : "memory");
318 } while (unlikely(!res)); 319 } while (unlikely(!res));
@@ -354,7 +355,7 @@ static inline int test_and_clear_bit(unsigned long nr,
354 " beqzl %2, 1b \n" 355 " beqzl %2, 1b \n"
355 " and %2, %0, %3 \n" 356 " and %2, %0, %3 \n"
356 " .set mips0 \n" 357 " .set mips0 \n"
357 : "=&r" (temp), "+m" (*m), "=&r" (res) 358 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
358 : "r" (1UL << bit) 359 : "r" (1UL << bit)
359 : "memory"); 360 : "memory");
360#ifdef CONFIG_CPU_MIPSR2 361#ifdef CONFIG_CPU_MIPSR2
@@ -368,7 +369,7 @@ static inline int test_and_clear_bit(unsigned long nr,
368 " " __EXT "%2, %0, %3, 1 \n" 369 " " __EXT "%2, %0, %3, 1 \n"
369 " " __INS "%0, $0, %3, 1 \n" 370 " " __INS "%0, $0, %3, 1 \n"
370 " " __SC "%0, %1 \n" 371 " " __SC "%0, %1 \n"
371 : "=&r" (temp), "+m" (*m), "=&r" (res) 372 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
372 : "ir" (bit) 373 : "ir" (bit)
373 : "memory"); 374 : "memory");
374 } while (unlikely(!temp)); 375 } while (unlikely(!temp));
@@ -385,7 +386,7 @@ static inline int test_and_clear_bit(unsigned long nr,
385 " xor %2, %3 \n" 386 " xor %2, %3 \n"
386 " " __SC "%2, %1 \n" 387 " " __SC "%2, %1 \n"
387 " .set mips0 \n" 388 " .set mips0 \n"
388 : "=&r" (temp), "+m" (*m), "=&r" (res) 389 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
389 : "r" (1UL << bit) 390 : "r" (1UL << bit)
390 : "memory"); 391 : "memory");
391 } while (unlikely(!res)); 392 } while (unlikely(!res));
@@ -427,7 +428,7 @@ static inline int test_and_change_bit(unsigned long nr,
427 " beqzl %2, 1b \n" 428 " beqzl %2, 1b \n"
428 " and %2, %0, %3 \n" 429 " and %2, %0, %3 \n"
429 " .set mips0 \n" 430 " .set mips0 \n"
430 : "=&r" (temp), "+m" (*m), "=&r" (res) 431 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
431 : "r" (1UL << bit) 432 : "r" (1UL << bit)
432 : "memory"); 433 : "memory");
433 } else if (kernel_uses_llsc) { 434 } else if (kernel_uses_llsc) {
@@ -441,7 +442,7 @@ static inline int test_and_change_bit(unsigned long nr,
441 " xor %2, %0, %3 \n" 442 " xor %2, %0, %3 \n"
442 " " __SC "\t%2, %1 \n" 443 " " __SC "\t%2, %1 \n"
443 " .set mips0 \n" 444 " .set mips0 \n"
444 : "=&r" (temp), "+m" (*m), "=&r" (res) 445 : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res)
445 : "r" (1UL << bit) 446 : "r" (1UL << bit)
446 : "memory"); 447 : "memory");
447 } while (unlikely(!res)); 448 } while (unlikely(!res));
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h
index cbaccebf5065..30939b02e3ff 100644
--- a/arch/mips/include/asm/bmips.h
+++ b/arch/mips/include/asm/bmips.h
@@ -84,6 +84,7 @@ extern char bmips_smp_int_vec_end;
84extern int bmips_smp_enabled; 84extern int bmips_smp_enabled;
85extern int bmips_cpu_offset; 85extern int bmips_cpu_offset;
86extern cpumask_t bmips_booted_mask; 86extern cpumask_t bmips_booted_mask;
87extern unsigned long bmips_tp1_irqs;
87 88
88extern void bmips_ebase_setup(void); 89extern void bmips_ebase_setup(void);
89extern asmlinkage void plat_wired_tlb_setup(void); 90extern asmlinkage void plat_wired_tlb_setup(void);
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 1f7ca8b00404..b603804caac5 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -70,10 +70,7 @@ enum loongson_machine_type {
70 MACH_DEXXON_GDIUM2F10, 70 MACH_DEXXON_GDIUM2F10,
71 MACH_LEMOTE_NAS, 71 MACH_LEMOTE_NAS,
72 MACH_LEMOTE_LL2F, 72 MACH_LEMOTE_LL2F,
73 MACH_LEMOTE_A1004, 73 MACH_LOONGSON_GENERIC,
74 MACH_LEMOTE_A1101,
75 MACH_LEMOTE_A1201,
76 MACH_LEMOTE_A1205,
77 MACH_LOONGSON_END 74 MACH_LOONGSON_END
78}; 75};
79 76
@@ -101,16 +98,16 @@ extern unsigned long mips_machtype;
101struct boot_mem_map { 98struct boot_mem_map {
102 int nr_map; 99 int nr_map;
103 struct boot_mem_map_entry { 100 struct boot_mem_map_entry {
104 phys_t addr; /* start of memory segment */ 101 phys_addr_t addr; /* start of memory segment */
105 phys_t size; /* size of memory segment */ 102 phys_addr_t size; /* size of memory segment */
106 long type; /* type of memory segment */ 103 long type; /* type of memory segment */
107 } map[BOOT_MEM_MAP_MAX]; 104 } map[BOOT_MEM_MAP_MAX];
108}; 105};
109 106
110extern struct boot_mem_map boot_mem_map; 107extern struct boot_mem_map boot_mem_map;
111 108
112extern void add_memory_region(phys_t start, phys_t size, long type); 109extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
113extern void detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max); 110extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max);
114 111
115extern void prom_init(void); 112extern void prom_init(void);
116extern void prom_free_prom_memory(void); 113extern void prom_free_prom_memory(void);
diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h
index 778e32d817bc..4809c29a4890 100644
--- a/arch/mips/include/asm/clock.h
+++ b/arch/mips/include/asm/clock.h
@@ -35,9 +35,6 @@ struct clk {
35#define CLK_ALWAYS_ENABLED (1 << 0) 35#define CLK_ALWAYS_ENABLED (1 << 0)
36#define CLK_RATE_PROPAGATES (1 << 1) 36#define CLK_RATE_PROPAGATES (1 << 1)
37 37
38/* Should be defined by processor-specific code */
39void arch_init_clk_ops(struct clk_ops **, int type);
40
41int clk_init(void); 38int clk_init(void);
42 39
43int __clk_enable(struct clk *); 40int __clk_enable(struct clk *);
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
index eefcaa363a87..28b1edf19501 100644
--- a/arch/mips/include/asm/cmpxchg.h
+++ b/arch/mips/include/asm/cmpxchg.h
@@ -10,6 +10,7 @@
10 10
11#include <linux/bug.h> 11#include <linux/bug.h>
12#include <linux/irqflags.h> 12#include <linux/irqflags.h>
13#include <asm/compiler.h>
13#include <asm/war.h> 14#include <asm/war.h>
14 15
15static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) 16static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
@@ -30,8 +31,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
30 " sc %2, %1 \n" 31 " sc %2, %1 \n"
31 " beqzl %2, 1b \n" 32 " beqzl %2, 1b \n"
32 " .set mips0 \n" 33 " .set mips0 \n"
33 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 34 : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy)
34 : "R" (*m), "Jr" (val) 35 : GCC_OFF12_ASM() (*m), "Jr" (val)
35 : "memory"); 36 : "memory");
36 } else if (kernel_uses_llsc) { 37 } else if (kernel_uses_llsc) {
37 unsigned long dummy; 38 unsigned long dummy;
@@ -45,8 +46,9 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
45 " .set arch=r4000 \n" 46 " .set arch=r4000 \n"
46 " sc %2, %1 \n" 47 " sc %2, %1 \n"
47 " .set mips0 \n" 48 " .set mips0 \n"
48 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 49 : "=&r" (retval), "=" GCC_OFF12_ASM() (*m),
49 : "R" (*m), "Jr" (val) 50 "=&r" (dummy)
51 : GCC_OFF12_ASM() (*m), "Jr" (val)
50 : "memory"); 52 : "memory");
51 } while (unlikely(!dummy)); 53 } while (unlikely(!dummy));
52 } else { 54 } else {
@@ -80,8 +82,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
80 " scd %2, %1 \n" 82 " scd %2, %1 \n"
81 " beqzl %2, 1b \n" 83 " beqzl %2, 1b \n"
82 " .set mips0 \n" 84 " .set mips0 \n"
83 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 85 : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy)
84 : "R" (*m), "Jr" (val) 86 : GCC_OFF12_ASM() (*m), "Jr" (val)
85 : "memory"); 87 : "memory");
86 } else if (kernel_uses_llsc) { 88 } else if (kernel_uses_llsc) {
87 unsigned long dummy; 89 unsigned long dummy;
@@ -93,8 +95,9 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
93 " move %2, %z4 \n" 95 " move %2, %z4 \n"
94 " scd %2, %1 \n" 96 " scd %2, %1 \n"
95 " .set mips0 \n" 97 " .set mips0 \n"
96 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 98 : "=&r" (retval), "=" GCC_OFF12_ASM() (*m),
97 : "R" (*m), "Jr" (val) 99 "=&r" (dummy)
100 : GCC_OFF12_ASM() (*m), "Jr" (val)
98 : "memory"); 101 : "memory");
99 } while (unlikely(!dummy)); 102 } while (unlikely(!dummy));
100 } else { 103 } else {
@@ -155,8 +158,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
155 " beqzl $1, 1b \n" \ 158 " beqzl $1, 1b \n" \
156 "2: \n" \ 159 "2: \n" \
157 " .set pop \n" \ 160 " .set pop \n" \
158 : "=&r" (__ret), "=R" (*m) \ 161 : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \
159 : "R" (*m), "Jr" (old), "Jr" (new) \ 162 : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \
160 : "memory"); \ 163 : "memory"); \
161 } else if (kernel_uses_llsc) { \ 164 } else if (kernel_uses_llsc) { \
162 __asm__ __volatile__( \ 165 __asm__ __volatile__( \
@@ -172,8 +175,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
172 " beqz $1, 1b \n" \ 175 " beqz $1, 1b \n" \
173 " .set pop \n" \ 176 " .set pop \n" \
174 "2: \n" \ 177 "2: \n" \
175 : "=&r" (__ret), "=R" (*m) \ 178 : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \
176 : "R" (*m), "Jr" (old), "Jr" (new) \ 179 : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \
177 : "memory"); \ 180 : "memory"); \
178 } else { \ 181 } else { \
179 unsigned long __flags; \ 182 unsigned long __flags; \
diff --git a/arch/mips/include/asm/compiler.h b/arch/mips/include/asm/compiler.h
index 71f5c5cfc58a..c73815e0123a 100644
--- a/arch/mips/include/asm/compiler.h
+++ b/arch/mips/include/asm/compiler.h
@@ -16,4 +16,12 @@
16#define GCC_REG_ACCUM "accum" 16#define GCC_REG_ACCUM "accum"
17#endif 17#endif
18 18
19#ifndef CONFIG_CPU_MICROMIPS
20#define GCC_OFF12_ASM() "R"
21#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
22#define GCC_OFF12_ASM() "ZC"
23#else
24#error "microMIPS compilation unsupported with GCC older than 4.9"
25#endif
26
19#endif /* _ASM_COMPILER_H */ 27#endif /* _ASM_COMPILER_H */
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 3325f3eb248c..2897cfafcaf0 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -344,4 +344,8 @@
344# define cpu_has_msa 0 344# define cpu_has_msa 0
345#endif 345#endif
346 346
347#ifndef cpu_has_fre
348# define cpu_has_fre (cpu_data[0].options & MIPS_CPU_FRE)
349#endif
350
347#endif /* __ASM_CPU_FEATURES_H */ 351#endif /* __ASM_CPU_FEATURES_H */
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index dfdc77ed1839..33866fce4d63 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -142,6 +142,7 @@
142#define PRID_IMP_BMIPS3300_BUG 0x0000 142#define PRID_IMP_BMIPS3300_BUG 0x0000
143#define PRID_IMP_BMIPS43XX 0xa000 143#define PRID_IMP_BMIPS43XX 0xa000
144#define PRID_IMP_BMIPS5000 0x5a00 144#define PRID_IMP_BMIPS5000 0x5a00
145#define PRID_IMP_BMIPS5200 0x5b00
145 146
146#define PRID_REV_BMIPS4380_LO 0x0040 147#define PRID_REV_BMIPS4380_LO 0x0040
147#define PRID_REV_BMIPS4380_HI 0x006f 148#define PRID_REV_BMIPS4380_HI 0x006f
@@ -368,6 +369,7 @@ enum cpu_type_enum {
368#define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ 369#define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */
369#define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ 370#define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */
370#define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ 371#define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */
372#define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */
371 373
372/* 374/*
373 * CPU ASE encodings 375 * CPU ASE encodings
diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h
index 4da0c1fe30d9..ae6fedcb0060 100644
--- a/arch/mips/include/asm/edac.h
+++ b/arch/mips/include/asm/edac.h
@@ -1,6 +1,8 @@
1#ifndef ASM_EDAC_H 1#ifndef ASM_EDAC_H
2#define ASM_EDAC_H 2#define ASM_EDAC_H
3 3
4#include <asm/compiler.h>
5
4/* ECC atomic, DMA, SMP and interrupt safe scrub function */ 6/* ECC atomic, DMA, SMP and interrupt safe scrub function */
5 7
6static inline void atomic_scrub(void *va, u32 size) 8static inline void atomic_scrub(void *va, u32 size)
@@ -24,8 +26,8 @@ static inline void atomic_scrub(void *va, u32 size)
24 " sc %0, %1 \n" 26 " sc %0, %1 \n"
25 " beqz %0, 1b \n" 27 " beqz %0, 1b \n"
26 " .set mips0 \n" 28 " .set mips0 \n"
27 : "=&r" (temp), "=m" (*virt_addr) 29 : "=&r" (temp), "=" GCC_OFF12_ASM() (*virt_addr)
28 : "m" (*virt_addr)); 30 : GCC_OFF12_ASM() (*virt_addr));
29 31
30 virt_addr++; 32 virt_addr++;
31 } 33 }
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index 1d38fe0edd2d..eb4d95de619c 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -8,6 +8,8 @@
8#ifndef _ASM_ELF_H 8#ifndef _ASM_ELF_H
9#define _ASM_ELF_H 9#define _ASM_ELF_H
10 10
11#include <linux/fs.h>
12#include <uapi/linux/elf.h>
11 13
12/* ELF header e_flags defines. */ 14/* ELF header e_flags defines. */
13/* MIPS architecture level. */ 15/* MIPS architecture level. */
@@ -28,6 +30,7 @@
28#define PT_MIPS_REGINFO 0x70000000 30#define PT_MIPS_REGINFO 0x70000000
29#define PT_MIPS_RTPROC 0x70000001 31#define PT_MIPS_RTPROC 0x70000001
30#define PT_MIPS_OPTIONS 0x70000002 32#define PT_MIPS_OPTIONS 0x70000002
33#define PT_MIPS_ABIFLAGS 0x70000003
31 34
32/* Flags in the e_flags field of the header */ 35/* Flags in the e_flags field of the header */
33#define EF_MIPS_NOREORDER 0x00000001 36#define EF_MIPS_NOREORDER 0x00000001
@@ -174,6 +177,30 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
174typedef double elf_fpreg_t; 177typedef double elf_fpreg_t;
175typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; 178typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
176 179
180struct mips_elf_abiflags_v0 {
181 uint16_t version; /* Version of flags structure */
182 uint8_t isa_level; /* The level of the ISA: 1-5, 32, 64 */
183 uint8_t isa_rev; /* The revision of ISA: 0 for MIPS V and below,
184 1-n otherwise */
185 uint8_t gpr_size; /* The size of general purpose registers */
186 uint8_t cpr1_size; /* The size of co-processor 1 registers */
187 uint8_t cpr2_size; /* The size of co-processor 2 registers */
188 uint8_t fp_abi; /* The floating-point ABI */
189 uint32_t isa_ext; /* Mask of processor-specific extensions */
190 uint32_t ases; /* Mask of ASEs used */
191 uint32_t flags1; /* Mask of general flags */
192 uint32_t flags2;
193};
194
195#define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */
196#define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */
197#define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */
198#define MIPS_ABI_FP_SOFT 3 /* -msoft-float */
199#define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */
200#define MIPS_ABI_FP_XX 5 /* -mfpxx */
201#define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */
202#define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */
203
177#ifdef CONFIG_32BIT 204#ifdef CONFIG_32BIT
178 205
179/* 206/*
@@ -262,16 +289,13 @@ extern struct mips_abi mips_abi_n32;
262 289
263#ifdef CONFIG_32BIT 290#ifdef CONFIG_32BIT
264 291
265#define SET_PERSONALITY(ex) \ 292#define SET_PERSONALITY2(ex, state) \
266do { \ 293do { \
267 if ((ex).e_flags & EF_MIPS_FP64) \
268 clear_thread_flag(TIF_32BIT_FPREGS); \
269 else \
270 set_thread_flag(TIF_32BIT_FPREGS); \
271 \
272 if (personality(current->personality) != PER_LINUX) \ 294 if (personality(current->personality) != PER_LINUX) \
273 set_personality(PER_LINUX); \ 295 set_personality(PER_LINUX); \
274 \ 296 \
297 mips_set_personality_fp(state); \
298 \
275 current->thread.abi = &mips_abi; \ 299 current->thread.abi = &mips_abi; \
276} while (0) 300} while (0)
277 301
@@ -291,44 +315,44 @@ do { \
291#endif 315#endif
292 316
293#ifdef CONFIG_MIPS32_O32 317#ifdef CONFIG_MIPS32_O32
294#define __SET_PERSONALITY32_O32(ex) \ 318#define __SET_PERSONALITY32_O32(ex, state) \
295 do { \ 319 do { \
296 set_thread_flag(TIF_32BIT_REGS); \ 320 set_thread_flag(TIF_32BIT_REGS); \
297 set_thread_flag(TIF_32BIT_ADDR); \ 321 set_thread_flag(TIF_32BIT_ADDR); \
298 \ 322 \
299 if (!((ex).e_flags & EF_MIPS_FP64)) \ 323 mips_set_personality_fp(state); \
300 set_thread_flag(TIF_32BIT_FPREGS); \
301 \ 324 \
302 current->thread.abi = &mips_abi_32; \ 325 current->thread.abi = &mips_abi_32; \
303 } while (0) 326 } while (0)
304#else 327#else
305#define __SET_PERSONALITY32_O32(ex) \ 328#define __SET_PERSONALITY32_O32(ex, state) \
306 do { } while (0) 329 do { } while (0)
307#endif 330#endif
308 331
309#ifdef CONFIG_MIPS32_COMPAT 332#ifdef CONFIG_MIPS32_COMPAT
310#define __SET_PERSONALITY32(ex) \ 333#define __SET_PERSONALITY32(ex, state) \
311do { \ 334do { \
312 if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ 335 if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \
313 ((ex).e_flags & EF_MIPS_ABI) == 0) \ 336 ((ex).e_flags & EF_MIPS_ABI) == 0) \
314 __SET_PERSONALITY32_N32(); \ 337 __SET_PERSONALITY32_N32(); \
315 else \ 338 else \
316 __SET_PERSONALITY32_O32(ex); \ 339 __SET_PERSONALITY32_O32(ex, state); \
317} while (0) 340} while (0)
318#else 341#else
319#define __SET_PERSONALITY32(ex) do { } while (0) 342#define __SET_PERSONALITY32(ex, state) do { } while (0)
320#endif 343#endif
321 344
322#define SET_PERSONALITY(ex) \ 345#define SET_PERSONALITY2(ex, state) \
323do { \ 346do { \
324 unsigned int p; \ 347 unsigned int p; \
325 \ 348 \
326 clear_thread_flag(TIF_32BIT_REGS); \ 349 clear_thread_flag(TIF_32BIT_REGS); \
327 clear_thread_flag(TIF_32BIT_FPREGS); \ 350 clear_thread_flag(TIF_32BIT_FPREGS); \
351 clear_thread_flag(TIF_HYBRID_FPREGS); \
328 clear_thread_flag(TIF_32BIT_ADDR); \ 352 clear_thread_flag(TIF_32BIT_ADDR); \
329 \ 353 \
330 if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ 354 if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
331 __SET_PERSONALITY32(ex); \ 355 __SET_PERSONALITY32(ex, state); \
332 else \ 356 else \
333 current->thread.abi = &mips_abi; \ 357 current->thread.abi = &mips_abi; \
334 \ 358 \
@@ -390,4 +414,24 @@ struct mm_struct;
390extern unsigned long arch_randomize_brk(struct mm_struct *mm); 414extern unsigned long arch_randomize_brk(struct mm_struct *mm);
391#define arch_randomize_brk arch_randomize_brk 415#define arch_randomize_brk arch_randomize_brk
392 416
417struct arch_elf_state {
418 int fp_abi;
419 int interp_fp_abi;
420 int overall_abi;
421};
422
423#define INIT_ARCH_ELF_STATE { \
424 .fp_abi = -1, \
425 .interp_fp_abi = -1, \
426 .overall_abi = -1, \
427}
428
429extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
430 bool is_interp, struct arch_elf_state *state);
431
432extern int arch_check_elf(void *ehdr, bool has_interpreter,
433 struct arch_elf_state *state);
434
435extern void mips_set_personality_fp(struct arch_elf_state *state);
436
393#endif /* _ASM_ELF_H */ 437#endif /* _ASM_ELF_H */
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index dd562414cd5e..994d21939676 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -36,14 +36,16 @@ extern void _restore_fp(struct task_struct *);
36 36
37/* 37/*
38 * This enum specifies a mode in which we want the FPU to operate, for cores 38 * This enum specifies a mode in which we want the FPU to operate, for cores
39 * which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT 39 * which implement the Status.FR bit. Note that the bottom bit of the value
40 * purposefully have the values 0 & 1 respectively, so that an integer value 40 * purposefully matches the desired value of the Status.FR bit.
41 * of Status.FR can be trivially casted to the corresponding enum fpu_mode.
42 */ 41 */
43enum fpu_mode { 42enum fpu_mode {
44 FPU_32BIT = 0, /* FR = 0 */ 43 FPU_32BIT = 0, /* FR = 0 */
45 FPU_64BIT, /* FR = 1 */ 44 FPU_64BIT, /* FR = 1, FRE = 0 */
46 FPU_AS_IS, 45 FPU_AS_IS,
46 FPU_HYBRID, /* FR = 1, FRE = 1 */
47
48#define FPU_FR_MASK 0x1
47}; 49};
48 50
49static inline int __enable_fpu(enum fpu_mode mode) 51static inline int __enable_fpu(enum fpu_mode mode)
@@ -57,6 +59,14 @@ static inline int __enable_fpu(enum fpu_mode mode)
57 enable_fpu_hazard(); 59 enable_fpu_hazard();
58 return 0; 60 return 0;
59 61
62 case FPU_HYBRID:
63 if (!cpu_has_fre)
64 return SIGFPE;
65
66 /* set FRE */
67 write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE);
68 goto fr_common;
69
60 case FPU_64BIT: 70 case FPU_64BIT:
61#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) 71#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT))
62 /* we only have a 32-bit FPU */ 72 /* we only have a 32-bit FPU */
@@ -64,8 +74,11 @@ static inline int __enable_fpu(enum fpu_mode mode)
64#endif 74#endif
65 /* fall through */ 75 /* fall through */
66 case FPU_32BIT: 76 case FPU_32BIT:
77 /* clear FRE */
78 write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE);
79fr_common:
67 /* set CU1 & change FR appropriately */ 80 /* set CU1 & change FR appropriately */
68 fr = (int)mode; 81 fr = (int)mode & FPU_FR_MASK;
69 change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0)); 82 change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0));
70 enable_fpu_hazard(); 83 enable_fpu_hazard();
71 84
@@ -102,13 +115,17 @@ static inline int __own_fpu(void)
102 enum fpu_mode mode; 115 enum fpu_mode mode;
103 int ret; 116 int ret;
104 117
105 mode = !test_thread_flag(TIF_32BIT_FPREGS); 118 if (test_thread_flag(TIF_HYBRID_FPREGS))
119 mode = FPU_HYBRID;
120 else
121 mode = !test_thread_flag(TIF_32BIT_FPREGS);
122
106 ret = __enable_fpu(mode); 123 ret = __enable_fpu(mode);
107 if (ret) 124 if (ret)
108 return ret; 125 return ret;
109 126
110 KSTK_STATUS(current) |= ST0_CU1; 127 KSTK_STATUS(current) |= ST0_CU1;
111 if (mode == FPU_64BIT) 128 if (mode == FPU_64BIT || mode == FPU_HYBRID)
112 KSTK_STATUS(current) |= ST0_FR; 129 KSTK_STATUS(current) |= ST0_FR;
113 else /* mode == FPU_32BIT */ 130 else /* mode == FPU_32BIT */
114 KSTK_STATUS(current) &= ~ST0_FR; 131 KSTK_STATUS(current) &= ~ST0_FR;
@@ -166,8 +183,24 @@ static inline int init_fpu(void)
166 183
167 if (cpu_has_fpu) { 184 if (cpu_has_fpu) {
168 ret = __own_fpu(); 185 ret = __own_fpu();
169 if (!ret) 186 if (!ret) {
187 unsigned int config5 = read_c0_config5();
188
189 /*
190 * Ensure FRE is clear whilst running _init_fpu, since
191 * single precision FP instructions are used. If FRE
192 * was set then we'll just end up initialising all 32
193 * 64b registers.
194 */
195 write_c0_config5(config5 & ~MIPS_CONF5_FRE);
196 enable_fpu_hazard();
197
170 _init_fpu(); 198 _init_fpu();
199
200 /* Restore FRE */
201 write_c0_config5(config5);
202 enable_fpu_hazard();
203 }
171 } else 204 } else
172 fpu_emulator_init_fpu(); 205 fpu_emulator_init_fpu();
173 206
diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h
index 194cda0396a3..ef9987a61d88 100644
--- a/arch/mips/include/asm/futex.h
+++ b/arch/mips/include/asm/futex.h
@@ -14,6 +14,7 @@
14#include <linux/uaccess.h> 14#include <linux/uaccess.h>
15#include <asm/asm-eva.h> 15#include <asm/asm-eva.h>
16#include <asm/barrier.h> 16#include <asm/barrier.h>
17#include <asm/compiler.h>
17#include <asm/errno.h> 18#include <asm/errno.h>
18#include <asm/war.h> 19#include <asm/war.h>
19 20
@@ -32,6 +33,7 @@
32 " beqzl $1, 1b \n" \ 33 " beqzl $1, 1b \n" \
33 __WEAK_LLSC_MB \ 34 __WEAK_LLSC_MB \
34 "3: \n" \ 35 "3: \n" \
36 " .insn \n" \
35 " .set pop \n" \ 37 " .set pop \n" \
36 " .set mips0 \n" \ 38 " .set mips0 \n" \
37 " .section .fixup,\"ax\" \n" \ 39 " .section .fixup,\"ax\" \n" \
@@ -42,8 +44,10 @@
42 " "__UA_ADDR "\t1b, 4b \n" \ 44 " "__UA_ADDR "\t1b, 4b \n" \
43 " "__UA_ADDR "\t2b, 4b \n" \ 45 " "__UA_ADDR "\t2b, 4b \n" \
44 " .previous \n" \ 46 " .previous \n" \
45 : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ 47 : "=r" (ret), "=&r" (oldval), \
46 : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ 48 "=" GCC_OFF12_ASM() (*uaddr) \
49 : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \
50 "i" (-EFAULT) \
47 : "memory"); \ 51 : "memory"); \
48 } else if (cpu_has_llsc) { \ 52 } else if (cpu_has_llsc) { \
49 __asm__ __volatile__( \ 53 __asm__ __volatile__( \
@@ -58,6 +62,7 @@
58 " beqz $1, 1b \n" \ 62 " beqz $1, 1b \n" \
59 __WEAK_LLSC_MB \ 63 __WEAK_LLSC_MB \
60 "3: \n" \ 64 "3: \n" \
65 " .insn \n" \
61 " .set pop \n" \ 66 " .set pop \n" \
62 " .set mips0 \n" \ 67 " .set mips0 \n" \
63 " .section .fixup,\"ax\" \n" \ 68 " .section .fixup,\"ax\" \n" \
@@ -68,8 +73,10 @@
68 " "__UA_ADDR "\t1b, 4b \n" \ 73 " "__UA_ADDR "\t1b, 4b \n" \
69 " "__UA_ADDR "\t2b, 4b \n" \ 74 " "__UA_ADDR "\t2b, 4b \n" \
70 " .previous \n" \ 75 " .previous \n" \
71 : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ 76 : "=r" (ret), "=&r" (oldval), \
72 : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ 77 "=" GCC_OFF12_ASM() (*uaddr) \
78 : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \
79 "i" (-EFAULT) \
73 : "memory"); \ 80 : "memory"); \
74 } else \ 81 } else \
75 ret = -ENOSYS; \ 82 ret = -ENOSYS; \
@@ -157,6 +164,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
157 " beqzl $1, 1b \n" 164 " beqzl $1, 1b \n"
158 __WEAK_LLSC_MB 165 __WEAK_LLSC_MB
159 "3: \n" 166 "3: \n"
167 " .insn \n"
160 " .set pop \n" 168 " .set pop \n"
161 " .section .fixup,\"ax\" \n" 169 " .section .fixup,\"ax\" \n"
162 "4: li %0, %6 \n" 170 "4: li %0, %6 \n"
@@ -166,8 +174,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
166 " "__UA_ADDR "\t1b, 4b \n" 174 " "__UA_ADDR "\t1b, 4b \n"
167 " "__UA_ADDR "\t2b, 4b \n" 175 " "__UA_ADDR "\t2b, 4b \n"
168 " .previous \n" 176 " .previous \n"
169 : "+r" (ret), "=&r" (val), "=R" (*uaddr) 177 : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr)
170 : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) 178 : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
179 "i" (-EFAULT)
171 : "memory"); 180 : "memory");
172 } else if (cpu_has_llsc) { 181 } else if (cpu_has_llsc) {
173 __asm__ __volatile__( 182 __asm__ __volatile__(
@@ -184,6 +193,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
184 " beqz $1, 1b \n" 193 " beqz $1, 1b \n"
185 __WEAK_LLSC_MB 194 __WEAK_LLSC_MB
186 "3: \n" 195 "3: \n"
196 " .insn \n"
187 " .set pop \n" 197 " .set pop \n"
188 " .section .fixup,\"ax\" \n" 198 " .section .fixup,\"ax\" \n"
189 "4: li %0, %6 \n" 199 "4: li %0, %6 \n"
@@ -193,8 +203,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
193 " "__UA_ADDR "\t1b, 4b \n" 203 " "__UA_ADDR "\t1b, 4b \n"
194 " "__UA_ADDR "\t2b, 4b \n" 204 " "__UA_ADDR "\t2b, 4b \n"
195 " .previous \n" 205 " .previous \n"
196 : "+r" (ret), "=&r" (val), "=R" (*uaddr) 206 : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr)
197 : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) 207 : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
208 "i" (-EFAULT)
198 : "memory"); 209 : "memory");
199 } else 210 } else
200 return -ENOSYS; 211 return -ENOSYS;
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
deleted file mode 100644
index d7699cf7e135..000000000000
--- a/arch/mips/include/asm/gic.h
+++ /dev/null
@@ -1,384 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2000, 07 MIPS Technologies, Inc.
7 *
8 * GIC Register Definitions
9 *
10 */
11#ifndef _ASM_GICREGS_H
12#define _ASM_GICREGS_H
13
14#include <linux/bitmap.h>
15#include <linux/threads.h>
16
17#include <irq.h>
18
19#undef GICISBYTELITTLEENDIAN
20
21/* Constants */
22#define GIC_POL_POS 1
23#define GIC_POL_NEG 0
24#define GIC_TRIG_EDGE 1
25#define GIC_TRIG_LEVEL 0
26
27#define MSK(n) ((1 << (n)) - 1)
28#define REG32(addr) (*(volatile unsigned int *) (addr))
29#define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS)
30#define REGP(base, phys) REG32((unsigned long)(base) + (phys))
31
32/* Accessors */
33#define GIC_REG(segment, offset) \
34 REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
35#define GIC_REG_ADDR(segment, offset) \
36 REG32(_gic_base + segment##_##SECTION_OFS + offset)
37
38#define GIC_ABS_REG(segment, offset) \
39 (_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
40#define GIC_REG_ABS_ADDR(segment, offset) \
41 (_gic_base + segment##_##SECTION_OFS + offset)
42
43#ifdef GICISBYTELITTLEENDIAN
44#define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data))
45#define GICWRITE(reg, data) ((reg) = cpu_to_le32(data))
46#else
47#define GICREAD(reg, data) ((data) = (reg))
48#define GICWRITE(reg, data) ((reg) = (data))
49#endif
50#define GICBIS(reg, mask, bits) \
51 do { u32 data; \
52 GICREAD(reg, data); \
53 data &= ~(mask); \
54 data |= ((bits) & (mask)); \
55 GICWRITE((reg), data); \
56 } while (0)
57
58
59/* GIC Address Space */
60#define SHARED_SECTION_OFS 0x0000
61#define SHARED_SECTION_SIZE 0x8000
62#define VPE_LOCAL_SECTION_OFS 0x8000
63#define VPE_LOCAL_SECTION_SIZE 0x4000
64#define VPE_OTHER_SECTION_OFS 0xc000
65#define VPE_OTHER_SECTION_SIZE 0x4000
66#define USM_VISIBLE_SECTION_OFS 0x10000
67#define USM_VISIBLE_SECTION_SIZE 0x10000
68
69/* Register Map for Shared Section */
70
71#define GIC_SH_CONFIG_OFS 0x0000
72
73/* Shared Global Counter */
74#define GIC_SH_COUNTER_31_00_OFS 0x0010
75#define GIC_SH_COUNTER_63_32_OFS 0x0014
76#define GIC_SH_REVISIONID_OFS 0x0020
77
78/* Interrupt Polarity */
79#define GIC_SH_POL_31_0_OFS 0x0100
80#define GIC_SH_POL_63_32_OFS 0x0104
81#define GIC_SH_POL_95_64_OFS 0x0108
82#define GIC_SH_POL_127_96_OFS 0x010c
83#define GIC_SH_POL_159_128_OFS 0x0110
84#define GIC_SH_POL_191_160_OFS 0x0114
85#define GIC_SH_POL_223_192_OFS 0x0118
86#define GIC_SH_POL_255_224_OFS 0x011c
87
88/* Edge/Level Triggering */
89#define GIC_SH_TRIG_31_0_OFS 0x0180
90#define GIC_SH_TRIG_63_32_OFS 0x0184
91#define GIC_SH_TRIG_95_64_OFS 0x0188
92#define GIC_SH_TRIG_127_96_OFS 0x018c
93#define GIC_SH_TRIG_159_128_OFS 0x0190
94#define GIC_SH_TRIG_191_160_OFS 0x0194
95#define GIC_SH_TRIG_223_192_OFS 0x0198
96#define GIC_SH_TRIG_255_224_OFS 0x019c
97
98/* Dual Edge Triggering */
99#define GIC_SH_DUAL_31_0_OFS 0x0200
100#define GIC_SH_DUAL_63_32_OFS 0x0204
101#define GIC_SH_DUAL_95_64_OFS 0x0208
102#define GIC_SH_DUAL_127_96_OFS 0x020c
103#define GIC_SH_DUAL_159_128_OFS 0x0210
104#define GIC_SH_DUAL_191_160_OFS 0x0214
105#define GIC_SH_DUAL_223_192_OFS 0x0218
106#define GIC_SH_DUAL_255_224_OFS 0x021c
107
108/* Set/Clear corresponding bit in Edge Detect Register */
109#define GIC_SH_WEDGE_OFS 0x0280
110
111/* Reset Mask - Disables Interrupt */
112#define GIC_SH_RMASK_31_0_OFS 0x0300
113#define GIC_SH_RMASK_63_32_OFS 0x0304
114#define GIC_SH_RMASK_95_64_OFS 0x0308
115#define GIC_SH_RMASK_127_96_OFS 0x030c
116#define GIC_SH_RMASK_159_128_OFS 0x0310
117#define GIC_SH_RMASK_191_160_OFS 0x0314
118#define GIC_SH_RMASK_223_192_OFS 0x0318
119#define GIC_SH_RMASK_255_224_OFS 0x031c
120
121/* Set Mask (WO) - Enables Interrupt */
122#define GIC_SH_SMASK_31_0_OFS 0x0380
123#define GIC_SH_SMASK_63_32_OFS 0x0384
124#define GIC_SH_SMASK_95_64_OFS 0x0388
125#define GIC_SH_SMASK_127_96_OFS 0x038c
126#define GIC_SH_SMASK_159_128_OFS 0x0390
127#define GIC_SH_SMASK_191_160_OFS 0x0394
128#define GIC_SH_SMASK_223_192_OFS 0x0398
129#define GIC_SH_SMASK_255_224_OFS 0x039c
130
131/* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */
132#define GIC_SH_MASK_31_0_OFS 0x0400
133#define GIC_SH_MASK_63_32_OFS 0x0404
134#define GIC_SH_MASK_95_64_OFS 0x0408
135#define GIC_SH_MASK_127_96_OFS 0x040c
136#define GIC_SH_MASK_159_128_OFS 0x0410
137#define GIC_SH_MASK_191_160_OFS 0x0414
138#define GIC_SH_MASK_223_192_OFS 0x0418
139#define GIC_SH_MASK_255_224_OFS 0x041c
140
141/* Pending Global Interrupts (RO) */
142#define GIC_SH_PEND_31_0_OFS 0x0480
143#define GIC_SH_PEND_63_32_OFS 0x0484
144#define GIC_SH_PEND_95_64_OFS 0x0488
145#define GIC_SH_PEND_127_96_OFS 0x048c
146#define GIC_SH_PEND_159_128_OFS 0x0490
147#define GIC_SH_PEND_191_160_OFS 0x0494
148#define GIC_SH_PEND_223_192_OFS 0x0498
149#define GIC_SH_PEND_255_224_OFS 0x049c
150
151#define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500
152
153/* Maps Interrupt X to a Pin */
154#define GIC_SH_MAP_TO_PIN(intr) \
155 (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr))
156
157#define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000
158
159/* Maps Interrupt X to a VPE */
160#define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \
161 (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4))
162#define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32))
163
164/* Convert an interrupt number to a byte offset/bit for multi-word registers */
165#define GIC_INTR_OFS(intr) (((intr) / 32)*4)
166#define GIC_INTR_BIT(intr) ((intr) % 32)
167
168/* Polarity : Reset Value is always 0 */
169#define GIC_SH_SET_POLARITY_OFS 0x0100
170#define GIC_SET_POLARITY(intr, pol) \
171 GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \
172 GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
173 (pol) << GIC_INTR_BIT(intr))
174
175/* Triggering : Reset Value is always 0 */
176#define GIC_SH_SET_TRIGGER_OFS 0x0180
177#define GIC_SET_TRIGGER(intr, trig) \
178 GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \
179 GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \
180 (trig) << GIC_INTR_BIT(intr))
181
182/* Mask manipulation */
183#define GIC_SH_SMASK_OFS 0x0380
184#define GIC_SET_INTR_MASK(intr) \
185 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \
186 GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
187#define GIC_SH_RMASK_OFS 0x0300
188#define GIC_CLR_INTR_MASK(intr) \
189 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \
190 GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr))
191
192/* Register Map for Local Section */
193#define GIC_VPE_CTL_OFS 0x0000
194#define GIC_VPE_PEND_OFS 0x0004
195#define GIC_VPE_MASK_OFS 0x0008
196#define GIC_VPE_RMASK_OFS 0x000c
197#define GIC_VPE_SMASK_OFS 0x0010
198#define GIC_VPE_WD_MAP_OFS 0x0040
199#define GIC_VPE_COMPARE_MAP_OFS 0x0044
200#define GIC_VPE_TIMER_MAP_OFS 0x0048
201#define GIC_VPE_PERFCTR_MAP_OFS 0x0050
202#define GIC_VPE_SWINT0_MAP_OFS 0x0054
203#define GIC_VPE_SWINT1_MAP_OFS 0x0058
204#define GIC_VPE_OTHER_ADDR_OFS 0x0080
205#define GIC_VPE_WD_CONFIG0_OFS 0x0090
206#define GIC_VPE_WD_COUNT0_OFS 0x0094
207#define GIC_VPE_WD_INITIAL0_OFS 0x0098
208#define GIC_VPE_COMPARE_LO_OFS 0x00a0
209#define GIC_VPE_COMPARE_HI_OFS 0x00a4
210
211#define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100
212#define GIC_VPE_EIC_SS(intr) \
213 (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr))
214
215#define GIC_VPE_EIC_VEC_BASE 0x0800
216#define GIC_VPE_EIC_VEC(intr) \
217 (GIC_VPE_EIC_VEC_BASE + (4 * intr))
218
219#define GIC_VPE_TENABLE_NMI_OFS 0x1000
220#define GIC_VPE_TENABLE_YQ_OFS 0x1004
221#define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080
222#define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084
223
224/* User Mode Visible Section Register Map */
225#define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000
226#define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004
227
228/* Masks */
229#define GIC_SH_CONFIG_COUNTSTOP_SHF 28
230#define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF)
231
232#define GIC_SH_CONFIG_COUNTBITS_SHF 24
233#define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF)
234
235#define GIC_SH_CONFIG_NUMINTRS_SHF 16
236#define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF)
237
238#define GIC_SH_CONFIG_NUMVPES_SHF 0
239#define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF)
240
241#define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31))
242#define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31))
243
244#define GIC_MAP_TO_PIN_SHF 31
245#define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF)
246#define GIC_MAP_TO_NMI_SHF 30
247#define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF)
248#define GIC_MAP_TO_YQ_SHF 29
249#define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF)
250#define GIC_MAP_SHF 0
251#define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF)
252
253/* GIC_VPE_CTL Masks */
254#define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2
255#define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF)
256#define GIC_VPE_CTL_TIMER_RTBL_SHF 1
257#define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF)
258#define GIC_VPE_CTL_EIC_MODE_SHF 0
259#define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF)
260
261/* GIC_VPE_PEND Masks */
262#define GIC_VPE_PEND_WD_SHF 0
263#define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF)
264#define GIC_VPE_PEND_CMP_SHF 1
265#define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF)
266#define GIC_VPE_PEND_TIMER_SHF 2
267#define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF)
268#define GIC_VPE_PEND_PERFCOUNT_SHF 3
269#define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF)
270#define GIC_VPE_PEND_SWINT0_SHF 4
271#define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF)
272#define GIC_VPE_PEND_SWINT1_SHF 5
273#define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF)
274
275/* GIC_VPE_RMASK Masks */
276#define GIC_VPE_RMASK_WD_SHF 0
277#define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF)
278#define GIC_VPE_RMASK_CMP_SHF 1
279#define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF)
280#define GIC_VPE_RMASK_TIMER_SHF 2
281#define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF)
282#define GIC_VPE_RMASK_PERFCNT_SHF 3
283#define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF)
284#define GIC_VPE_RMASK_SWINT0_SHF 4
285#define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF)
286#define GIC_VPE_RMASK_SWINT1_SHF 5
287#define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF)
288
289/* GIC_VPE_SMASK Masks */
290#define GIC_VPE_SMASK_WD_SHF 0
291#define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF)
292#define GIC_VPE_SMASK_CMP_SHF 1
293#define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF)
294#define GIC_VPE_SMASK_TIMER_SHF 2
295#define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF)
296#define GIC_VPE_SMASK_PERFCNT_SHF 3
297#define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF)
298#define GIC_VPE_SMASK_SWINT0_SHF 4
299#define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF)
300#define GIC_VPE_SMASK_SWINT1_SHF 5
301#define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF)
302
303/*
304 * Set the Mapping of Interrupt X to a VPE.
305 */
306#define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \
307 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \
308 GIC_SH_MAP_TO_VPE_REG_BIT(vpe))
309
310/*
311 * Interrupt Meta-data specification. The ipiflag helps
312 * in building ipi_map.
313 */
314struct gic_intr_map {
315 unsigned int cpunum; /* Directed to this CPU */
316#define GIC_UNUSED 0xdead /* Dummy data */
317 unsigned int pin; /* Directed to this Pin */
318 unsigned int polarity; /* Polarity : +/- */
319 unsigned int trigtype; /* Trigger : Edge/Levl */
320 unsigned int flags; /* Misc flags */
321#define GIC_FLAG_TRANSPARENT 0x01
322};
323
324/*
325 * This is only used in EIC mode. This helps to figure out which
326 * shared interrupts we need to process when we get a vector interrupt.
327 */
328#define GIC_MAX_SHARED_INTR 0x5
329struct gic_shared_intr_map {
330 unsigned int num_shared_intr;
331 unsigned int intr_list[GIC_MAX_SHARED_INTR];
332 unsigned int local_intr_mask;
333};
334
335/* GIC nomenclature for Core Interrupt Pins. */
336#define GIC_CPU_INT0 0 /* Core Interrupt 2 */
337#define GIC_CPU_INT1 1 /* . */
338#define GIC_CPU_INT2 2 /* . */
339#define GIC_CPU_INT3 3 /* . */
340#define GIC_CPU_INT4 4 /* . */
341#define GIC_CPU_INT5 5 /* Core Interrupt 7 */
342
343/* Local GIC interrupts. */
344#define GIC_INT_TMR (GIC_CPU_INT5)
345#define GIC_INT_PERFCTR (GIC_CPU_INT5)
346
347/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */
348#define GIC_CPU_TO_VEC_OFFSET (2)
349
350/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
351#define GIC_PIN_TO_VEC_OFFSET (1)
352
353#include <linux/clocksource.h>
354#include <linux/irq.h>
355
356extern unsigned int gic_present;
357extern unsigned int gic_frequency;
358extern unsigned long _gic_base;
359extern unsigned int gic_irq_base;
360extern unsigned int gic_irq_flags[];
361extern struct gic_shared_intr_map gic_shared_intr_map[];
362
363extern void gic_init(unsigned long gic_base_addr,
364 unsigned long gic_addrspace_size, struct gic_intr_map *intrmap,
365 unsigned int intrmap_size, unsigned int irqbase);
366extern void gic_clocksource_init(unsigned int);
367extern unsigned int gic_compare_int (void);
368extern cycle_t gic_read_count(void);
369extern cycle_t gic_read_compare(void);
370extern void gic_write_compare(cycle_t cnt);
371extern void gic_write_cpu_compare(cycle_t cnt, int cpu);
372extern void gic_send_ipi(unsigned int intr);
373extern unsigned int plat_ipi_call_int_xlate(unsigned int);
374extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
375extern void gic_bind_eic_interrupt(int irq, int set);
376extern unsigned int gic_get_timer_pending(void);
377extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src);
378extern unsigned int gic_get_int(void);
379extern void gic_enable_interrupt(int irq_vec);
380extern void gic_disable_interrupt(int irq_vec);
381extern void gic_irq_ack(struct irq_data *d);
382extern void gic_finish_irq(struct irq_data *d);
383extern void gic_platform_init(int irqs, struct irq_chip *irq_controller);
384#endif /* _ASM_GICREGS_H */
diff --git a/arch/mips/include/asm/hpet.h b/arch/mips/include/asm/hpet.h
new file mode 100644
index 000000000000..18a8f778bfaa
--- /dev/null
+++ b/arch/mips/include/asm/hpet.h
@@ -0,0 +1,73 @@
1#ifndef _ASM_HPET_H
2#define _ASM_HPET_H
3
4#ifdef CONFIG_RS780_HPET
5
6#define HPET_MMAP_SIZE 1024
7
8#define HPET_ID 0x000
9#define HPET_PERIOD 0x004
10#define HPET_CFG 0x010
11#define HPET_STATUS 0x020
12#define HPET_COUNTER 0x0f0
13
14#define HPET_Tn_CFG(n) (0x100 + 0x20 * n)
15#define HPET_Tn_CMP(n) (0x108 + 0x20 * n)
16#define HPET_Tn_ROUTE(n) (0x110 + 0x20 * n)
17
18#define HPET_T0_IRS 0x001
19#define HPET_T1_IRS 0x002
20#define HPET_T3_IRS 0x004
21
22#define HPET_T0_CFG 0x100
23#define HPET_T0_CMP 0x108
24#define HPET_T0_ROUTE 0x110
25#define HPET_T1_CFG 0x120
26#define HPET_T1_CMP 0x128
27#define HPET_T1_ROUTE 0x130
28#define HPET_T2_CFG 0x140
29#define HPET_T2_CMP 0x148
30#define HPET_T2_ROUTE 0x150
31
32#define HPET_ID_REV 0x000000ff
33#define HPET_ID_NUMBER 0x00001f00
34#define HPET_ID_64BIT 0x00002000
35#define HPET_ID_LEGSUP 0x00008000
36#define HPET_ID_VENDOR 0xffff0000
37#define HPET_ID_NUMBER_SHIFT 8
38#define HPET_ID_VENDOR_SHIFT 16
39
40#define HPET_CFG_ENABLE 0x001
41#define HPET_CFG_LEGACY 0x002
42#define HPET_LEGACY_8254 2
43#define HPET_LEGACY_RTC 8
44
45#define HPET_TN_LEVEL 0x0002
46#define HPET_TN_ENABLE 0x0004
47#define HPET_TN_PERIODIC 0x0008
48#define HPET_TN_PERIODIC_CAP 0x0010
49#define HPET_TN_64BIT_CAP 0x0020
50#define HPET_TN_SETVAL 0x0040
51#define HPET_TN_32BIT 0x0100
52#define HPET_TN_ROUTE 0x3e00
53#define HPET_TN_FSB 0x4000
54#define HPET_TN_FSB_CAP 0x8000
55#define HPET_TN_ROUTE_SHIFT 9
56
57/* Max HPET Period is 10^8 femto sec as in HPET spec */
58#define HPET_MAX_PERIOD 100000000UL
59/*
60 * Min HPET period is 10^5 femto sec just for safety. If it is less than this,
61 * then 32 bit HPET counter wrapsaround in less than 0.5 sec.
62 */
63#define HPET_MIN_PERIOD 100000UL
64
65#define HPET_ADDR 0x20000
66#define HPET_MMIO_ADDR 0x90000e0000020000
67#define HPET_FREQ 14318780
68#define HPET_COMPARE_VAL ((HPET_FREQ + HZ / 2) / HZ)
69#define HPET_T0_IRQ 0
70
71extern void __init setup_hpet_timer(void);
72#endif /* CONFIG_RS780_HPET */
73#endif /* _ASM_HPET_H */
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 933b50e125a0..9e777cd42b67 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -167,7 +167,7 @@ static inline void * isa_bus_to_virt(unsigned long address)
167 */ 167 */
168#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) 168#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
169 169
170extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); 170extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags);
171extern void __iounmap(const volatile void __iomem *addr); 171extern void __iounmap(const volatile void __iomem *addr);
172 172
173#ifndef CONFIG_PCI 173#ifndef CONFIG_PCI
@@ -175,7 +175,7 @@ struct pci_dev;
175static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} 175static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
176#endif 176#endif
177 177
178static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, 178static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size,
179 unsigned long flags) 179 unsigned long flags)
180{ 180{
181 void __iomem *addr = plat_ioremap(offset, size, flags); 181 void __iomem *addr = plat_ioremap(offset, size, flags);
@@ -183,7 +183,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
183 if (addr) 183 if (addr)
184 return addr; 184 return addr;
185 185
186#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) 186#define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
187 187
188 if (cpu_has_64bit_addresses) { 188 if (cpu_has_64bit_addresses) {
189 u64 base = UNCAC_BASE; 189 u64 base = UNCAC_BASE;
@@ -197,7 +197,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
197 return (void __iomem *) (unsigned long) (base + offset); 197 return (void __iomem *) (unsigned long) (base + offset);
198 } else if (__builtin_constant_p(offset) && 198 } else if (__builtin_constant_p(offset) &&
199 __builtin_constant_p(size) && __builtin_constant_p(flags)) { 199 __builtin_constant_p(size) && __builtin_constant_p(flags)) {
200 phys_t phys_addr, last_addr; 200 phys_addr_t phys_addr, last_addr;
201 201
202 phys_addr = fixup_bigphys_addr(offset, size); 202 phys_addr = fixup_bigphys_addr(offset, size);
203 203
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index 39f07aec640c..5a4e1bb8fb1b 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -48,4 +48,7 @@ extern int cp0_compare_irq;
48extern int cp0_compare_irq_shift; 48extern int cp0_compare_irq_shift;
49extern int cp0_perfcount_irq; 49extern int cp0_perfcount_irq;
50 50
51void arch_trigger_all_cpu_backtrace(bool);
52#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
53
51#endif /* _ASM_IRQ_H */ 54#endif /* _ASM_IRQ_H */
diff --git a/arch/mips/include/asm/irq_cpu.h b/arch/mips/include/asm/irq_cpu.h
index 3f11fdb3ed8c..39a160bb41dc 100644
--- a/arch/mips/include/asm/irq_cpu.h
+++ b/arch/mips/include/asm/irq_cpu.h
@@ -19,8 +19,8 @@ extern void rm9k_cpu_irq_init(void);
19 19
20#ifdef CONFIG_IRQ_DOMAIN 20#ifdef CONFIG_IRQ_DOMAIN
21struct device_node; 21struct device_node;
22extern int mips_cpu_intc_init(struct device_node *of_node, 22extern int mips_cpu_irq_of_init(struct device_node *of_node,
23 struct device_node *parent); 23 struct device_node *parent);
24#endif 24#endif
25 25
26#endif /* _ASM_IRQ_CPU_H */ 26#endif /* _ASM_IRQ_CPU_H */
diff --git a/arch/mips/include/asm/mach-ath25/ath25_platform.h b/arch/mips/include/asm/mach-ath25/ath25_platform.h
new file mode 100644
index 000000000000..4f4ee4f9e5ec
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/ath25_platform.h
@@ -0,0 +1,73 @@
1#ifndef __ASM_MACH_ATH25_PLATFORM_H
2#define __ASM_MACH_ATH25_PLATFORM_H
3
4#include <linux/etherdevice.h>
5
6/*
7 * This is board-specific data that is stored in a "fixed" location in flash.
8 * It is shared across operating systems, so it should not be changed lightly.
9 * The main reason we need it is in order to extract the ethernet MAC
10 * address(es).
11 */
12struct ath25_boarddata {
13 u32 magic; /* board data is valid */
14#define ATH25_BD_MAGIC 0x35333131 /* "5311", for all 531x/231x platforms */
15 u16 cksum; /* checksum (starting with BD_REV 2) */
16 u16 rev; /* revision of this struct */
17#define BD_REV 4
18 char board_name[64]; /* Name of board */
19 u16 major; /* Board major number */
20 u16 minor; /* Board minor number */
21 u32 flags; /* Board configuration */
22#define BD_ENET0 0x00000001 /* ENET0 is stuffed */
23#define BD_ENET1 0x00000002 /* ENET1 is stuffed */
24#define BD_UART1 0x00000004 /* UART1 is stuffed */
25#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */
26#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */
27#define BD_SYSLED 0x00000020 /* System LED stuffed */
28#define BD_EXTUARTCLK 0x00000040 /* External UART clock */
29#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */
30#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */
31#define BD_WLAN0 0x00000200 /* Enable WLAN0 */
32#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ mem_cap for testing */
33#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */
34#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */
35#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */
36#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */
37#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */
38#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */
39#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */
40 u16 reset_config_gpio; /* Reset factory GPIO pin */
41 u16 sys_led_gpio; /* System LED GPIO pin */
42
43 u32 cpu_freq; /* CPU core frequency in Hz */
44 u32 sys_freq; /* System frequency in Hz */
45 u32 cnt_freq; /* Calculated C0_COUNT frequency */
46
47 u8 wlan0_mac[ETH_ALEN];
48 u8 enet0_mac[ETH_ALEN];
49 u8 enet1_mac[ETH_ALEN];
50
51 u16 pci_id; /* Pseudo PCIID for common code */
52 u16 mem_cap; /* cap bank1 in MB */
53
54 /* version 3 */
55 u8 wlan1_mac[ETH_ALEN]; /* (ar5212) */
56};
57
58#define BOARD_CONFIG_BUFSZ 0x1000
59
60/*
61 * Platform device information for the Wireless MAC
62 */
63struct ar231x_board_config {
64 u16 devid;
65
66 /* board config data */
67 struct ath25_boarddata *config;
68
69 /* radio calibration data */
70 const char *radio;
71};
72
73#endif /* __ASM_MACH_ATH25_PLATFORM_H */
diff --git a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
new file mode 100644
index 000000000000..ade0356df257
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h
@@ -0,0 +1,64 @@
1/*
2 * Atheros AR231x/AR531x SoC specific CPU feature overrides
3 *
4 * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
5 *
6 * This file was derived from: include/asm-mips/cpu-features.h
7 * Copyright (C) 2003, 2004 Ralf Baechle
8 * Copyright (C) 2004 Maciej W. Rozycki
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 *
14 */
15#ifndef __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H
16#define __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H
17
18/*
19 * The Atheros AR531x/AR231x SoCs have MIPS 4Kc/4KEc core.
20 */
21#define cpu_has_tlb 1
22#define cpu_has_4kex 1
23#define cpu_has_3k_cache 0
24#define cpu_has_4k_cache 1
25#define cpu_has_tx39_cache 0
26#define cpu_has_sb1_cache 0
27#define cpu_has_fpu 0
28#define cpu_has_32fpr 0
29#define cpu_has_counter 1
30#define cpu_has_ejtag 1
31
32#if !defined(CONFIG_SOC_AR5312)
33# define cpu_has_llsc 1
34#else
35/*
36 * The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the
37 * ll/sc instructions.
38 */
39# define cpu_has_llsc 0
40#endif
41
42#define cpu_has_mips16 0
43#define cpu_has_mdmx 0
44#define cpu_has_mips3d 0
45#define cpu_has_smartmips 0
46
47#define cpu_has_mips32r1 1
48
49#if !defined(CONFIG_SOC_AR5312)
50# define cpu_has_mips32r2 1
51#endif
52
53#define cpu_has_mips64r1 0
54#define cpu_has_mips64r2 0
55
56#define cpu_has_dsp 0
57#define cpu_has_mipsmt 0
58
59#define cpu_has_64bits 0
60#define cpu_has_64bit_zero_reg 0
61#define cpu_has_64bit_gp_regs 0
62#define cpu_has_64bit_addresses 0
63
64#endif /* __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h b/arch/mips/include/asm/mach-ath25/dma-coherence.h
new file mode 100644
index 000000000000..d8009c93a465
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/dma-coherence.h
@@ -0,0 +1,82 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
7 * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
8 *
9 */
10#ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H
11#define __ASM_MACH_ATH25_DMA_COHERENCE_H
12
13#include <linux/device.h>
14
15/*
16 * We need some arbitrary non-zero value to be programmed to the BAR1 register
17 * of PCI host controller to enable DMA. The same value should be used as the
18 * offset to calculate the physical address of DMA buffer for PCI devices.
19 */
20#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x20000000
21
22static inline dma_addr_t ath25_dev_offset(struct device *dev)
23{
24#ifdef CONFIG_PCI
25 extern struct bus_type pci_bus_type;
26
27 if (dev && dev->bus == &pci_bus_type)
28 return AR2315_PCI_HOST_SDRAM_BASEADDR;
29#endif
30 return 0;
31}
32
33static inline dma_addr_t
34plat_map_dma_mem(struct device *dev, void *addr, size_t size)
35{
36 return virt_to_phys(addr) + ath25_dev_offset(dev);
37}
38
39static inline dma_addr_t
40plat_map_dma_mem_page(struct device *dev, struct page *page)
41{
42 return page_to_phys(page) + ath25_dev_offset(dev);
43}
44
45static inline unsigned long
46plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
47{
48 return dma_addr - ath25_dev_offset(dev);
49}
50
51static inline void
52plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size,
53 enum dma_data_direction direction)
54{
55}
56
57static inline int plat_dma_supported(struct device *dev, u64 mask)
58{
59 return 1;
60}
61
62static inline void plat_extra_sync_for_device(struct device *dev)
63{
64}
65
66static inline int plat_dma_mapping_error(struct device *dev,
67 dma_addr_t dma_addr)
68{
69 return 0;
70}
71
72static inline int plat_device_is_coherent(struct device *dev)
73{
74#ifdef CONFIG_DMA_COHERENT
75 return 1;
76#endif
77#ifdef CONFIG_DMA_NONCOHERENT
78 return 0;
79#endif
80}
81
82#endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-ath25/gpio.h b/arch/mips/include/asm/mach-ath25/gpio.h
new file mode 100644
index 000000000000..713564b8e8ef
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/gpio.h
@@ -0,0 +1,16 @@
1#ifndef __ASM_MACH_ATH25_GPIO_H
2#define __ASM_MACH_ATH25_GPIO_H
3
4#include <asm-generic/gpio.h>
5
6#define gpio_get_value __gpio_get_value
7#define gpio_set_value __gpio_set_value
8#define gpio_cansleep __gpio_cansleep
9#define gpio_to_irq __gpio_to_irq
10
11static inline int irq_to_gpio(unsigned irq)
12{
13 return -EINVAL;
14}
15
16#endif /* __ASM_MACH_ATH25_GPIO_H */
diff --git a/arch/mips/include/asm/mach-ath25/war.h b/arch/mips/include/asm/mach-ath25/war.h
new file mode 100644
index 000000000000..e3a5250ebd67
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath25/war.h
@@ -0,0 +1,25 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
7 */
8#ifndef __ASM_MACH_ATH25_WAR_H
9#define __ASM_MACH_ATH25_WAR_H
10
11#define R4600_V1_INDEX_ICACHEOP_WAR 0
12#define R4600_V1_HIT_CACHEOP_WAR 0
13#define R4600_V2_HIT_CACHEOP_WAR 0
14#define R5432_CP0_INTERRUPT_WAR 0
15#define BCM1250_M3_WAR 0
16#define SIBYTE_1956_WAR 0
17#define MIPS4K_ICACHE_REFILL_WAR 0
18#define MIPS_CACHE_SYNC_WAR 0
19#define TX49XX_ICACHE_INDEX_INV_WAR 0
20#define RM9000_CDEX_SMP_WAR 0
21#define ICACHE_REFILLS_WORKAROUND_WAR 0
22#define R10000_LLSC_WAR 0
23#define MIPS34K_MISSED_ITLB_WAR 0
24
25#endif /* __ASM_MACH_ATH25_WAR_H */
diff --git a/arch/mips/include/asm/mach-au1x00/ioremap.h b/arch/mips/include/asm/mach-au1x00/ioremap.h
index 75a94ad3ac91..99fea1fbb4f5 100644
--- a/arch/mips/include/asm/mach-au1x00/ioremap.h
+++ b/arch/mips/include/asm/mach-au1x00/ioremap.h
@@ -11,10 +11,10 @@
11 11
12#include <linux/types.h> 12#include <linux/types.h>
13 13
14#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) 14#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI)
15extern phys_t __fixup_bigphys_addr(phys_t, phys_t); 15extern phys_addr_t __fixup_bigphys_addr(phys_addr_t, phys_addr_t);
16#else 16#else
17static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) 17static inline phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
18{ 18{
19 return phys_addr; 19 return phys_addr;
20} 20}
@@ -23,12 +23,12 @@ static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
23/* 23/*
24 * Allow physical addresses to be fixed up to help 36-bit peripherals. 24 * Allow physical addresses to be fixed up to help 36-bit peripherals.
25 */ 25 */
26static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 26static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
27{ 27{
28 return __fixup_bigphys_addr(phys_addr, size); 28 return __fixup_bigphys_addr(phys_addr, size);
29} 29}
30 30
31static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 31static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
32 unsigned long flags) 32 unsigned long flags)
33{ 33{
34 return NULL; 34 return NULL;
diff --git a/arch/mips/include/asm/mach-bcm3384/dma-coherence.h b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h
new file mode 100644
index 000000000000..a3be8e50e1f0
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
3 * Copyright (C) 2009 Broadcom Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef __ASM_MACH_BCM3384_DMA_COHERENCE_H
16#define __ASM_MACH_BCM3384_DMA_COHERENCE_H
17
18struct device;
19
20extern dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size);
21extern dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page);
22extern unsigned long plat_dma_addr_to_phys(struct device *dev,
23 dma_addr_t dma_addr);
24
25static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
26 size_t size, enum dma_data_direction direction)
27{
28}
29
30static inline int plat_dma_supported(struct device *dev, u64 mask)
31{
32 /*
33 * we fall back to GFP_DMA when the mask isn't all 1s,
34 * so we can't guarantee allocations that must be
35 * within a tighter range than GFP_DMA..
36 */
37 if (mask < DMA_BIT_MASK(24))
38 return 0;
39
40 return 1;
41}
42
43static inline int plat_device_is_coherent(struct device *dev)
44{
45 return 0;
46}
47
48#endif /* __ASM_MACH_BCM3384_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-bcm3384/war.h b/arch/mips/include/asm/mach-bcm3384/war.h
new file mode 100644
index 000000000000..59d7599059b0
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm3384/war.h
@@ -0,0 +1,24 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
7 */
8#ifndef __ASM_MIPS_MACH_BCM3384_WAR_H
9#define __ASM_MIPS_MACH_BCM3384_WAR_H
10
11#define R4600_V1_INDEX_ICACHEOP_WAR 0
12#define R4600_V1_HIT_CACHEOP_WAR 0
13#define R4600_V2_HIT_CACHEOP_WAR 0
14#define R5432_CP0_INTERRUPT_WAR 0
15#define BCM1250_M3_WAR 0
16#define SIBYTE_1956_WAR 0
17#define MIPS4K_ICACHE_REFILL_WAR 0
18#define MIPS_CACHE_SYNC_WAR 0
19#define TX49XX_ICACHE_INDEX_INV_WAR 0
20#define ICACHE_REFILLS_WORKAROUND_WAR 0
21#define R10000_LLSC_WAR 0
22#define MIPS34K_MISSED_ITLB_WAR 0
23
24#endif /* __ASM_MIPS_MACH_BCM3384_WAR_H */
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
index 36a3fc1aa3ae..ee59ffe99922 100644
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
@@ -14,40 +14,8 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16 16
17struct nvram_header { 17int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
18 u32 magic; 18int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
19 u32 len;
20 u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
21 u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
22 u32 config_ncdl; /* ncdl values for memc */
23};
24
25#define NVRAM_HEADER 0x48534C46 /* 'FLSH' */
26#define NVRAM_VERSION 1
27#define NVRAM_HEADER_SIZE 20
28#define NVRAM_SPACE 0x8000
29
30#define FLASH_MIN 0x00020000 /* Minimum flash size */
31
32#define NVRAM_MAX_VALUE_LEN 255
33#define NVRAM_MAX_PARAM_LEN 64
34
35extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len);
36
37static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6])
38{
39 if (strchr(buf, ':'))
40 sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
41 &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
42 &macaddr[5]);
43 else if (strchr(buf, '-'))
44 sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
45 &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
46 &macaddr[5]);
47 else
48 printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
49}
50
51int bcm47xx_nvram_gpio_pin(const char *name); 19int bcm47xx_nvram_gpio_pin(const char *name);
52 20
53#endif /* __BCM47XX_NVRAM_H */ 21#endif /* __BCM47XX_NVRAM_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
index ff15e3b14e7a..aea6e64b828f 100644
--- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h
+++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
@@ -3,12 +3,12 @@
3 3
4#include <bcm63xx_cpu.h> 4#include <bcm63xx_cpu.h>
5 5
6static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 6static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
7{ 7{
8 return phys_addr; 8 return phys_addr;
9} 9}
10 10
11static inline int is_bcm63xx_internal_registers(phys_t offset) 11static inline int is_bcm63xx_internal_registers(phys_addr_t offset)
12{ 12{
13 switch (bcm63xx_get_cpu_id()) { 13 switch (bcm63xx_get_cpu_id()) {
14 case BCM3368_CPU_ID: 14 case BCM3368_CPU_ID:
@@ -32,7 +32,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset)
32 return 0; 32 return 0;
33} 33}
34 34
35static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 35static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
36 unsigned long flags) 36 unsigned long flags)
37{ 37{
38 if (is_bcm63xx_internal_registers(offset)) 38 if (is_bcm63xx_internal_registers(offset))
diff --git a/arch/mips/include/asm/mach-generic/ioremap.h b/arch/mips/include/asm/mach-generic/ioremap.h
index b379938d47f0..513371f7c39c 100644
--- a/arch/mips/include/asm/mach-generic/ioremap.h
+++ b/arch/mips/include/asm/mach-generic/ioremap.h
@@ -15,12 +15,12 @@
15 * Allow physical addresses to be fixed up to help peripherals located 15 * Allow physical addresses to be fixed up to help peripherals located
16 * outside the low 32-bit range -- generic pass-through version. 16 * outside the low 32-bit range -- generic pass-through version.
17 */ 17 */
18static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 18static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
19{ 19{
20 return phys_addr; 20 return phys_addr;
21} 21}
22 22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 23static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
24 unsigned long flags) 24 unsigned long flags)
25{ 25{
26 return NULL; 26 return NULL;
diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h
index 139cd200e79d..050e18bb1a04 100644
--- a/arch/mips/include/asm/mach-generic/irq.h
+++ b/arch/mips/include/asm/mach-generic/irq.h
@@ -36,4 +36,10 @@
36 36
37#endif /* CONFIG_IRQ_CPU */ 37#endif /* CONFIG_IRQ_CPU */
38 38
39#ifdef CONFIG_MIPS_GIC
40#ifndef MIPS_GIC_IRQ_BASE
41#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
42#endif
43#endif /* CONFIG_MIPS_GIC */
44
39#endif /* __ASM_MACH_GENERIC_IRQ_H */ 45#endif /* __ASM_MACH_GENERIC_IRQ_H */
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h
index f196cceb7322..4e5ae6523cb4 100644
--- a/arch/mips/include/asm/mach-lantiq/lantiq.h
+++ b/arch/mips/include/asm/mach-lantiq/lantiq.h
@@ -48,6 +48,8 @@ extern struct clk *clk_get_ppe(void);
48extern unsigned char ltq_boot_select(void); 48extern unsigned char ltq_boot_select(void);
49/* find out what caused the last cpu reset */ 49/* find out what caused the last cpu reset */
50extern int ltq_reset_cause(void); 50extern int ltq_reset_cause(void);
51/* find out the soc type */
52extern int ltq_soc_type(void);
51 53
52#define IOPORT_RESOURCE_START 0x10000000 54#define IOPORT_RESOURCE_START 0x10000000
53#define IOPORT_RESOURCE_END 0xffffffff 55#define IOPORT_RESOURCE_END 0xffffffff
diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h
index 3388fc53599e..fa802926523f 100644
--- a/arch/mips/include/asm/mach-loongson/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson/boot_param.h
@@ -10,7 +10,8 @@
10#define VIDEO_ROM 7 10#define VIDEO_ROM 7
11#define ADAPTER_ROM 8 11#define ADAPTER_ROM 8
12#define ACPI_TABLE 9 12#define ACPI_TABLE 9
13#define MAX_MEMORY_TYPE 10 13#define SMBIOS_TABLE 10
14#define MAX_MEMORY_TYPE 11
14 15
15#define LOONGSON3_BOOT_MEM_MAP_MAX 128 16#define LOONGSON3_BOOT_MEM_MAP_MAX 128
16struct efi_memory_map_loongson { 17struct efi_memory_map_loongson {
@@ -42,15 +43,49 @@ struct efi_cpuinfo_loongson {
42 u32 processor_id; /* PRID, e.g. 6305, 6306 */ 43 u32 processor_id; /* PRID, e.g. 6305, 6306 */
43 u32 cputype; /* Loongson_3A/3B, etc. */ 44 u32 cputype; /* Loongson_3A/3B, etc. */
44 u32 total_node; /* num of total numa nodes */ 45 u32 total_node; /* num of total numa nodes */
45 u32 cpu_startup_core_id; /* Core id */ 46 u16 cpu_startup_core_id; /* Boot core id */
47 u16 reserved_cores_mask;
46 u32 cpu_clock_freq; /* cpu_clock */ 48 u32 cpu_clock_freq; /* cpu_clock */
47 u32 nr_cpus; 49 u32 nr_cpus;
48} __packed; 50} __packed;
49 51
52#define MAX_UARTS 64
53struct uart_device {
54 u32 iotype; /* see include/linux/serial_core.h */
55 u32 uartclk;
56 u32 int_offset;
57 u64 uart_base;
58} __packed;
59
60#define MAX_SENSORS 64
61#define SENSOR_TEMPER 0x00000001
62#define SENSOR_VOLTAGE 0x00000002
63#define SENSOR_FAN 0x00000004
64struct sensor_device {
65 char name[32]; /* a formal name */
66 char label[64]; /* a flexible description */
67 u32 type; /* SENSOR_* */
68 u32 id; /* instance id of a sensor-class */
69 u32 fan_policy; /* see loongson_hwmon.h */
70 u32 fan_percent;/* only for constant speed policy */
71 u64 base_addr; /* base address of device registers */
72} __packed;
73
50struct system_loongson { 74struct system_loongson {
51 u16 vers; /* version of system_loongson */ 75 u16 vers; /* version of system_loongson */
52 u32 ccnuma_smp; /* 0: no numa; 1: has numa */ 76 u32 ccnuma_smp; /* 0: no numa; 1: has numa */
53 u32 sing_double_channel; /* 1:single; 2:double */ 77 u32 sing_double_channel; /* 1:single; 2:double */
78 u32 nr_uarts;
79 struct uart_device uarts[MAX_UARTS];
80 u32 nr_sensors;
81 struct sensor_device sensors[MAX_SENSORS];
82 char has_ec;
83 char ec_name[32];
84 u64 ec_base_addr;
85 char has_tcm;
86 char tcm_name[32];
87 u64 tcm_base_addr;
88 u64 workarounds; /* see workarounds.h */
54} __packed; 89} __packed;
55 90
56struct irq_source_routing_table { 91struct irq_source_routing_table {
@@ -149,6 +184,8 @@ struct loongson_system_configuration {
149 u32 nr_nodes; 184 u32 nr_nodes;
150 int cores_per_node; 185 int cores_per_node;
151 int cores_per_package; 186 int cores_per_package;
187 u16 boot_cpu_id;
188 u16 reserved_cpus_mask;
152 enum loongson_cpu_type cputype; 189 enum loongson_cpu_type cputype;
153 u64 ht_control_base; 190 u64 ht_control_base;
154 u64 pci_mem_start_addr; 191 u64 pci_mem_start_addr;
@@ -159,9 +196,15 @@ struct loongson_system_configuration {
159 u64 suspend_addr; 196 u64 suspend_addr;
160 u64 vgabios_addr; 197 u64 vgabios_addr;
161 u32 dma_mask_bits; 198 u32 dma_mask_bits;
199 char ecname[32];
200 u32 nr_uarts;
201 struct uart_device uarts[MAX_UARTS];
202 u32 nr_sensors;
203 struct sensor_device sensors[MAX_SENSORS];
204 u64 workarounds;
162}; 205};
163 206
164extern struct efi_memory_map_loongson *loongson_memmap; 207extern struct efi_memory_map_loongson *loongson_memmap;
165extern struct loongson_system_configuration loongson_sysconf; 208extern struct loongson_system_configuration loongson_sysconf;
166extern int cpuhotplug_workaround; 209
167#endif 210#endif
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
index 6a902751cc7f..a90534161bd2 100644
--- a/arch/mips/include/asm/mach-loongson/dma-coherence.h
+++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h
@@ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
23 size_t size) 23 size_t size)
24{ 24{
25#ifdef CONFIG_CPU_LOONGSON3 25#ifdef CONFIG_CPU_LOONGSON3
26 return virt_to_phys(addr); 26 return phys_to_dma(dev, virt_to_phys(addr));
27#else 27#else
28 return virt_to_phys(addr) | 0x80000000; 28 return virt_to_phys(addr) | 0x80000000;
29#endif 29#endif
@@ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
33 struct page *page) 33 struct page *page)
34{ 34{
35#ifdef CONFIG_CPU_LOONGSON3 35#ifdef CONFIG_CPU_LOONGSON3
36 return page_to_phys(page); 36 return phys_to_dma(dev, page_to_phys(page));
37#else 37#else
38 return page_to_phys(page) | 0x80000000; 38 return page_to_phys(page) | 0x80000000;
39#endif 39#endif
@@ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
43 dma_addr_t dma_addr) 43 dma_addr_t dma_addr)
44{ 44{
45#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) 45#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT)
46 return dma_addr; 46 return dma_to_phys(dev, dma_addr);
47#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) 47#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT)
48 return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); 48 return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff);
49#else 49#else
diff --git a/arch/mips/include/asm/mach-loongson/irq.h b/arch/mips/include/asm/mach-loongson/irq.h
index 34560bda6626..a281cca5f2fb 100644
--- a/arch/mips/include/asm/mach-loongson/irq.h
+++ b/arch/mips/include/asm/mach-loongson/irq.h
@@ -32,8 +32,7 @@
32#define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a) 32#define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a)
33#define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18) 33#define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18)
34 34
35#define LOONGSON_INT_CORE0_INT0 0x11 /* route to int 0 of core 0 */ 35#define LOONGSON_INT_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */
36#define LOONGSON_INT_CORE0_INT1 0x21 /* route to int 1 of core 0 */
37 36
38#endif 37#endif
39 38
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
index 92bf76c21441..5459ac09679f 100644
--- a/arch/mips/include/asm/mach-loongson/loongson.h
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -35,7 +35,7 @@ extern void __init prom_init_cmdline(void);
35extern void __init prom_init_machtype(void); 35extern void __init prom_init_machtype(void);
36extern void __init prom_init_env(void); 36extern void __init prom_init_env(void);
37#ifdef CONFIG_LOONGSON_UART_BASE 37#ifdef CONFIG_LOONGSON_UART_BASE
38extern unsigned long _loongson_uart_base, loongson_uart_base; 38extern unsigned long _loongson_uart_base[], loongson_uart_base[];
39extern void prom_init_loongson_uart_base(void); 39extern void prom_init_loongson_uart_base(void);
40#endif 40#endif
41 41
diff --git a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h
new file mode 100644
index 000000000000..4431fc54a36c
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h
@@ -0,0 +1,55 @@
1#ifndef __LOONGSON_HWMON_H_
2#define __LOONGSON_HWMON_H_
3
4#include <linux/types.h>
5
6#define MIN_TEMP 0
7#define MAX_TEMP 255
8#define NOT_VALID_TEMP 999
9
10typedef int (*get_temp_fun)(int);
11extern int loongson3_cpu_temp(int);
12
13/* 0:Max speed, 1:Manual, 2:Auto */
14enum fan_control_mode {
15 FAN_FULL_MODE = 0,
16 FAN_MANUAL_MODE = 1,
17 FAN_AUTO_MODE = 2,
18 FAN_MODE_END
19};
20
21struct temp_range {
22 u8 low;
23 u8 high;
24 u8 level;
25};
26
27#define CONSTANT_SPEED_POLICY 0 /* at constent speed */
28#define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */
29#define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */
30
31#define MAX_STEP_NUM 16
32#define MAX_FAN_LEVEL 255
33
34/* loongson_fan_policy works when fan work at FAN_AUTO_MODE */
35struct loongson_fan_policy {
36 u8 type;
37
38 /* percent only used when type is CONSTANT_SPEED_POLICY */
39 u8 percent;
40
41 /* period between two check. (Unit: S) */
42 u8 adjust_period;
43
44 /* fan adjust usually depend on a temprature input */
45 get_temp_fun depend_temp;
46
47 /* up_step/down_step used when type is STEP_SPEED_POLICY */
48 u8 up_step_num;
49 u8 down_step_num;
50 struct temp_range up_step[MAX_STEP_NUM];
51 struct temp_range down_step[MAX_STEP_NUM];
52 struct delayed_work work;
53};
54
55#endif /* __LOONGSON_HWMON_H_*/
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h
index 228e37847a36..cb2b60249cd2 100644
--- a/arch/mips/include/asm/mach-loongson/machine.h
+++ b/arch/mips/include/asm/mach-loongson/machine.h
@@ -26,7 +26,7 @@
26 26
27#ifdef CONFIG_LOONGSON_MACH3X 27#ifdef CONFIG_LOONGSON_MACH3X
28 28
29#define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 29#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC
30 30
31#endif /* CONFIG_LOONGSON_MACH3X */ 31#endif /* CONFIG_LOONGSON_MACH3X */
32 32
diff --git a/arch/mips/include/asm/mach-loongson/topology.h b/arch/mips/include/asm/mach-loongson/topology.h
index 5598ba77d2ef..0d8f3b55bdbc 100644
--- a/arch/mips/include/asm/mach-loongson/topology.h
+++ b/arch/mips/include/asm/mach-loongson/topology.h
@@ -3,7 +3,7 @@
3 3
4#ifdef CONFIG_NUMA 4#ifdef CONFIG_NUMA
5 5
6#define cpu_to_node(cpu) ((cpu) >> 2) 6#define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2)
7#define parent_node(node) (node) 7#define parent_node(node) (node)
8#define cpumask_of_node(node) (&__node_data[(node)]->cpumask) 8#define cpumask_of_node(node) (&__node_data[(node)]->cpumask)
9 9
diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h
new file mode 100644
index 000000000000..e180c1422eae
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/workarounds.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_
2#define __ASM_MACH_LOONGSON_WORKAROUNDS_H_
3
4#define WORKAROUND_CPUFREQ 0x00000001
5#define WORKAROUND_CPUHOTPLUG 0x00000002
6
7#endif
diff --git a/arch/mips/include/asm/mach-loongson1/cpufreq.h b/arch/mips/include/asm/mach-loongson1/cpufreq.h
new file mode 100644
index 000000000000..e7765ce30bcf
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/cpufreq.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * Loongson 1 CPUFreq platform support.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12
13#ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H
14#define __ASM_MACH_LOONGSON1_CPUFREQ_H
15
16struct plat_ls1x_cpufreq {
17 const char *clk_name; /* CPU clk */
18 const char *osc_clk_name; /* OSC clk */
19 unsigned int max_freq; /* in kHz */
20 unsigned int min_freq; /* in kHz */
21};
22
23#endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */
diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h
index 5c437c2ba6b3..20e0c2b155dd 100644
--- a/arch/mips/include/asm/mach-loongson1/loongson1.h
+++ b/arch/mips/include/asm/mach-loongson1/loongson1.h
@@ -16,6 +16,7 @@
16#define DEFAULT_MEMSIZE 256 /* If no memsize provided */ 16#define DEFAULT_MEMSIZE 256 /* If no memsize provided */
17 17
18/* Loongson 1 Register Bases */ 18/* Loongson 1 Register Bases */
19#define LS1X_MUX_BASE 0x1fd00420
19#define LS1X_INTC_BASE 0x1fd01040 20#define LS1X_INTC_BASE 0x1fd01040
20#define LS1X_EHCI_BASE 0x1fe00000 21#define LS1X_EHCI_BASE 0x1fe00000
21#define LS1X_OHCI_BASE 0x1fe08000 22#define LS1X_OHCI_BASE 0x1fe08000
@@ -31,7 +32,10 @@
31#define LS1X_I2C0_BASE 0x1fe58000 32#define LS1X_I2C0_BASE 0x1fe58000
32#define LS1X_I2C1_BASE 0x1fe68000 33#define LS1X_I2C1_BASE 0x1fe68000
33#define LS1X_I2C2_BASE 0x1fe70000 34#define LS1X_I2C2_BASE 0x1fe70000
34#define LS1X_PWM_BASE 0x1fe5c000 35#define LS1X_PWM0_BASE 0x1fe5c000
36#define LS1X_PWM1_BASE 0x1fe5c010
37#define LS1X_PWM2_BASE 0x1fe5c020
38#define LS1X_PWM3_BASE 0x1fe5c030
35#define LS1X_WDT_BASE 0x1fe5c060 39#define LS1X_WDT_BASE 0x1fe5c060
36#define LS1X_RTC_BASE 0x1fe64000 40#define LS1X_RTC_BASE 0x1fe64000
37#define LS1X_AC97_BASE 0x1fe74000 41#define LS1X_AC97_BASE 0x1fe74000
@@ -39,6 +43,8 @@
39#define LS1X_CLK_BASE 0x1fe78030 43#define LS1X_CLK_BASE 0x1fe78030
40 44
41#include <regs-clk.h> 45#include <regs-clk.h>
46#include <regs-mux.h>
47#include <regs-pwm.h>
42#include <regs-wdt.h> 48#include <regs-wdt.h>
43 49
44#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ 50#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */
diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h
index 30c13e508fff..47de55e0c835 100644
--- a/arch/mips/include/asm/mach-loongson1/platform.h
+++ b/arch/mips/include/asm/mach-loongson1/platform.h
@@ -13,10 +13,12 @@
13 13
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15 15
16extern struct platform_device ls1x_uart_device; 16extern struct platform_device ls1x_uart_pdev;
17extern struct platform_device ls1x_eth0_device; 17extern struct platform_device ls1x_cpufreq_pdev;
18extern struct platform_device ls1x_ehci_device; 18extern struct platform_device ls1x_eth0_pdev;
19extern struct platform_device ls1x_rtc_device; 19extern struct platform_device ls1x_eth1_pdev;
20extern struct platform_device ls1x_ehci_pdev;
21extern struct platform_device ls1x_rtc_pdev;
20 22
21extern void __init ls1x_clk_init(void); 23extern void __init ls1x_clk_init(void);
22extern void __init ls1x_serial_setup(struct platform_device *pdev); 24extern void __init ls1x_serial_setup(struct platform_device *pdev);
diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h
index fb6a3ff9318f..ee2445b10fc3 100644
--- a/arch/mips/include/asm/mach-loongson1/regs-clk.h
+++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h
@@ -20,15 +20,32 @@
20 20
21/* Clock PLL Divisor Register Bits */ 21/* Clock PLL Divisor Register Bits */
22#define DIV_DC_EN (0x1 << 31) 22#define DIV_DC_EN (0x1 << 31)
23#define DIV_DC_RST (0x1 << 30)
23#define DIV_CPU_EN (0x1 << 25) 24#define DIV_CPU_EN (0x1 << 25)
25#define DIV_CPU_RST (0x1 << 24)
24#define DIV_DDR_EN (0x1 << 19) 26#define DIV_DDR_EN (0x1 << 19)
27#define DIV_DDR_RST (0x1 << 18)
28#define RST_DC_EN (0x1 << 5)
29#define RST_DC (0x1 << 4)
30#define RST_DDR_EN (0x1 << 3)
31#define RST_DDR (0x1 << 2)
32#define RST_CPU_EN (0x1 << 1)
33#define RST_CPU 0x1
25 34
26#define DIV_DC_SHIFT 26 35#define DIV_DC_SHIFT 26
27#define DIV_CPU_SHIFT 20 36#define DIV_CPU_SHIFT 20
28#define DIV_DDR_SHIFT 14 37#define DIV_DDR_SHIFT 14
29 38
30#define DIV_DC_WIDTH 5 39#define DIV_DC_WIDTH 4
31#define DIV_CPU_WIDTH 5 40#define DIV_CPU_WIDTH 4
32#define DIV_DDR_WIDTH 5 41#define DIV_DDR_WIDTH 4
42
43#define BYPASS_DC_SHIFT 12
44#define BYPASS_DDR_SHIFT 10
45#define BYPASS_CPU_SHIFT 8
46
47#define BYPASS_DC_WIDTH 1
48#define BYPASS_DDR_WIDTH 1
49#define BYPASS_CPU_WIDTH 1
33 50
34#endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ 51#endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-mux.h b/arch/mips/include/asm/mach-loongson1/regs-mux.h
new file mode 100644
index 000000000000..fb1e36efaa19
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/regs-mux.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * Loongson 1 MUX Register Definitions.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H
13#define __ASM_MACH_LOONGSON1_REGS_MUX_H
14
15#define LS1X_MUX_REG(x) \
16 ((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x)))
17
18#define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0)
19#define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4)
20
21/* MUX CTRL0 Register Bits */
22#define UART0_USE_PWM23 (0x1 << 28)
23#define UART0_USE_PWM01 (0x1 << 27)
24#define UART1_USE_LCD0_5_6_11 (0x1 << 26)
25#define I2C2_USE_CAN1 (0x1 << 25)
26#define I2C1_USE_CAN0 (0x1 << 24)
27#define NAND3_USE_UART5 (0x1 << 23)
28#define NAND3_USE_UART4 (0x1 << 22)
29#define NAND3_USE_UART1_DAT (0x1 << 21)
30#define NAND3_USE_UART1_CTS (0x1 << 20)
31#define NAND3_USE_PWM23 (0x1 << 19)
32#define NAND3_USE_PWM01 (0x1 << 18)
33#define NAND2_USE_UART5 (0x1 << 17)
34#define NAND2_USE_UART4 (0x1 << 16)
35#define NAND2_USE_UART1_DAT (0x1 << 15)
36#define NAND2_USE_UART1_CTS (0x1 << 14)
37#define NAND2_USE_PWM23 (0x1 << 13)
38#define NAND2_USE_PWM01 (0x1 << 12)
39#define NAND1_USE_UART5 (0x1 << 11)
40#define NAND1_USE_UART4 (0x1 << 10)
41#define NAND1_USE_UART1_DAT (0x1 << 9)
42#define NAND1_USE_UART1_CTS (0x1 << 8)
43#define NAND1_USE_PWM23 (0x1 << 7)
44#define NAND1_USE_PWM01 (0x1 << 6)
45#define GMAC1_USE_UART1 (0x1 << 4)
46#define GMAC1_USE_UART0 (0x1 << 3)
47#define LCD_USE_UART0_DAT (0x1 << 2)
48#define LCD_USE_UART15 (0x1 << 1)
49#define LCD_USE_UART0 0x1
50
51/* MUX CTRL1 Register Bits */
52#define USB_RESET (0x1 << 31)
53#define SPI1_CS_USE_PWM01 (0x1 << 24)
54#define SPI1_USE_CAN (0x1 << 23)
55#define DISABLE_DDR_CONFSPACE (0x1 << 20)
56#define DDR32TO16EN (0x1 << 16)
57#define GMAC1_SHUT (0x1 << 13)
58#define GMAC0_SHUT (0x1 << 12)
59#define USB_SHUT (0x1 << 11)
60#define UART1_3_USE_CAN1 (0x1 << 5)
61#define UART1_2_USE_CAN0 (0x1 << 4)
62#define GMAC1_USE_TXCLK (0x1 << 3)
63#define GMAC0_USE_TXCLK (0x1 << 2)
64#define GMAC1_USE_PWM23 (0x1 << 1)
65#define GMAC0_USE_PWM01 0x1
66
67#endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-pwm.h b/arch/mips/include/asm/mach-loongson1/regs-pwm.h
new file mode 100644
index 000000000000..99f2bcc586f0
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/regs-pwm.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * Loongson 1 PWM Register Definitions.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H
13#define __ASM_MACH_LOONGSON1_REGS_PWM_H
14
15/* Loongson 1 PWM Timer Register Definitions */
16#define PWM_CNT 0x0
17#define PWM_HRC 0x4
18#define PWM_LRC 0x8
19#define PWM_CTRL 0xc
20
21/* PWM Control Register Bits */
22#define CNT_RST (0x1 << 7)
23#define INT_SR (0x1 << 6)
24#define INT_EN (0x1 << 5)
25#define PWM_SINGLE (0x1 << 4)
26#define PWM_OE (0x1 << 3)
27#define CNT_EN 0x1
28
29#endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h
index 6574568c2084..c39ee982ad3b 100644
--- a/arch/mips/include/asm/mach-loongson1/regs-wdt.h
+++ b/arch/mips/include/asm/mach-loongson1/regs-wdt.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> 2 * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
3 * 3 *
4 * Loongson 1 watchdog register definitions. 4 * Loongson 1 Watchdog Register Definitions.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
@@ -12,11 +12,8 @@
12#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H 12#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H
13#define __ASM_MACH_LOONGSON1_REGS_WDT_H 13#define __ASM_MACH_LOONGSON1_REGS_WDT_H
14 14
15#define LS1X_WDT_REG(x) \ 15#define WDT_EN 0x0
16 ((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x))) 16#define WDT_TIMER 0x4
17 17#define WDT_SET 0x8
18#define LS1X_WDT_EN LS1X_WDT_REG(0x0)
19#define LS1X_WDT_SET LS1X_WDT_REG(0x4)
20#define LS1X_WDT_TIMER LS1X_WDT_REG(0x8)
21 18
22#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ 19#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */
diff --git a/arch/mips/include/asm/mach-malta/irq.h b/arch/mips/include/asm/mach-malta/irq.h
index f2c13d211abb..47cfe64efbb0 100644
--- a/arch/mips/include/asm/mach-malta/irq.h
+++ b/arch/mips/include/asm/mach-malta/irq.h
@@ -2,7 +2,6 @@
2#define __ASM_MACH_MIPS_IRQ_H 2#define __ASM_MACH_MIPS_IRQ_H
3 3
4 4
5#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
6#define NR_IRQS 256 5#define NR_IRQS 256
7 6
8#include_next <irq.h> 7#include_next <irq.h>
diff --git a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h
index fc946c835995..2e54b4bff5cf 100644
--- a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h
+++ b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h
@@ -49,6 +49,7 @@
49 49
50#include <linux/types.h> 50#include <linux/types.h>
51 51
52#include <asm/compiler.h>
52#include <asm/war.h> 53#include <asm/war.h>
53 54
54#ifndef R10000_LLSC_WAR 55#ifndef R10000_LLSC_WAR
@@ -84,8 +85,8 @@ static inline void set_value_reg32(volatile u32 *const addr,
84 " "__beqz"%0, 1b \n" 85 " "__beqz"%0, 1b \n"
85 " nop \n" 86 " nop \n"
86 " .set pop \n" 87 " .set pop \n"
87 : "=&r" (temp), "=m" (*addr) 88 : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
88 : "ir" (~mask), "ir" (value), "m" (*addr)); 89 : "ir" (~mask), "ir" (value), GCC_OFF12_ASM() (*addr));
89} 90}
90 91
91/* 92/*
@@ -105,8 +106,8 @@ static inline void set_reg32(volatile u32 *const addr,
105 " "__beqz"%0, 1b \n" 106 " "__beqz"%0, 1b \n"
106 " nop \n" 107 " nop \n"
107 " .set pop \n" 108 " .set pop \n"
108 : "=&r" (temp), "=m" (*addr) 109 : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
109 : "ir" (mask), "m" (*addr)); 110 : "ir" (mask), GCC_OFF12_ASM() (*addr));
110} 111}
111 112
112/* 113/*
@@ -126,8 +127,8 @@ static inline void clear_reg32(volatile u32 *const addr,
126 " "__beqz"%0, 1b \n" 127 " "__beqz"%0, 1b \n"
127 " nop \n" 128 " nop \n"
128 " .set pop \n" 129 " .set pop \n"
129 : "=&r" (temp), "=m" (*addr) 130 : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
130 : "ir" (~mask), "m" (*addr)); 131 : "ir" (~mask), GCC_OFF12_ASM() (*addr));
131} 132}
132 133
133/* 134/*
@@ -147,8 +148,8 @@ static inline void toggle_reg32(volatile u32 *const addr,
147 " "__beqz"%0, 1b \n" 148 " "__beqz"%0, 1b \n"
148 " nop \n" 149 " nop \n"
149 " .set pop \n" 150 " .set pop \n"
150 : "=&r" (temp), "=m" (*addr) 151 : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr)
151 : "ir" (mask), "m" (*addr)); 152 : "ir" (mask), GCC_OFF12_ASM() (*addr));
152} 153}
153 154
154/* 155/*
@@ -219,8 +220,8 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr)
219 " .set arch=r4000 \n" \ 220 " .set arch=r4000 \n" \
220 "1: ll %0, %1 #custom_read_reg32 \n" \ 221 "1: ll %0, %1 #custom_read_reg32 \n" \
221 " .set pop \n" \ 222 " .set pop \n" \
222 : "=r" (tmp), "=m" (*address) \ 223 : "=r" (tmp), "=" GCC_OFF12_ASM() (*address) \
223 : "m" (*address)) 224 : GCC_OFF12_ASM() (*address))
224 225
225#define custom_write_reg32(address, tmp) \ 226#define custom_write_reg32(address, tmp) \
226 __asm__ __volatile__( \ 227 __asm__ __volatile__( \
@@ -230,7 +231,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr)
230 " "__beqz"%0, 1b \n" \ 231 " "__beqz"%0, 1b \n" \
231 " nop \n" \ 232 " nop \n" \
232 " .set pop \n" \ 233 " .set pop \n" \
233 : "=&r" (tmp), "=m" (*address) \ 234 : "=&r" (tmp), "=" GCC_OFF12_ASM() (*address) \
234 : "0" (tmp), "m" (*address)) 235 : "0" (tmp), GCC_OFF12_ASM() (*address))
235 236
236#endif /* __ASM_REGOPS_H__ */ 237#endif /* __ASM_REGOPS_H__ */
diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h
index 6f9b24f51157..1976fb815fd1 100644
--- a/arch/mips/include/asm/mach-ralink/mt7620.h
+++ b/arch/mips/include/asm/mach-ralink/mt7620.h
@@ -13,6 +13,13 @@
13#ifndef _MT7620_REGS_H_ 13#ifndef _MT7620_REGS_H_
14#define _MT7620_REGS_H_ 14#define _MT7620_REGS_H_
15 15
16enum mt762x_soc_type {
17 MT762X_SOC_UNKNOWN = 0,
18 MT762X_SOC_MT7620A,
19 MT762X_SOC_MT7620N,
20 MT762X_SOC_MT7628AN,
21};
22
16#define MT7620_SYSC_BASE 0x10000000 23#define MT7620_SYSC_BASE 0x10000000
17 24
18#define SYSC_REG_CHIP_NAME0 0x00 25#define SYSC_REG_CHIP_NAME0 0x00
@@ -25,11 +32,9 @@
25#define SYSC_REG_CPLL_CONFIG0 0x54 32#define SYSC_REG_CPLL_CONFIG0 0x54
26#define SYSC_REG_CPLL_CONFIG1 0x58 33#define SYSC_REG_CPLL_CONFIG1 0x58
27 34
28#define MT7620N_CHIP_NAME0 0x33365452 35#define MT7620_CHIP_NAME0 0x3637544d
29#define MT7620N_CHIP_NAME1 0x20203235 36#define MT7620_CHIP_NAME1 0x20203032
30 37#define MT7628_CHIP_NAME1 0x20203832
31#define MT7620A_CHIP_NAME0 0x3637544d
32#define MT7620A_CHIP_NAME1 0x20203032
33 38
34#define SYSCFG0_XTAL_FREQ_SEL BIT(6) 39#define SYSCFG0_XTAL_FREQ_SEL BIT(6)
35 40
@@ -74,6 +79,9 @@
74#define SYSCFG0_DRAM_TYPE_DDR1 1 79#define SYSCFG0_DRAM_TYPE_DDR1 1
75#define SYSCFG0_DRAM_TYPE_DDR2 2 80#define SYSCFG0_DRAM_TYPE_DDR2 2
76 81
82#define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0
83#define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1
84
77#define MT7620_DRAM_BASE 0x0 85#define MT7620_DRAM_BASE 0x0
78#define MT7620_SDRAM_SIZE_MIN 2 86#define MT7620_SDRAM_SIZE_MIN 2
79#define MT7620_SDRAM_SIZE_MAX 64 87#define MT7620_SDRAM_SIZE_MAX 64
@@ -82,7 +90,6 @@
82#define MT7620_DDR2_SIZE_MIN 32 90#define MT7620_DDR2_SIZE_MIN 32
83#define MT7620_DDR2_SIZE_MAX 256 91#define MT7620_DDR2_SIZE_MAX 256
84 92
85#define MT7620_GPIO_MODE_I2C BIT(0)
86#define MT7620_GPIO_MODE_UART0_SHIFT 2 93#define MT7620_GPIO_MODE_UART0_SHIFT 2
87#define MT7620_GPIO_MODE_UART0_MASK 0x7 94#define MT7620_GPIO_MODE_UART0_MASK 0x7
88#define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) 95#define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT)
@@ -94,15 +101,40 @@
94#define MT7620_GPIO_MODE_GPIO_UARTF 0x5 101#define MT7620_GPIO_MODE_GPIO_UARTF 0x5
95#define MT7620_GPIO_MODE_GPIO_I2S 0x6 102#define MT7620_GPIO_MODE_GPIO_I2S 0x6
96#define MT7620_GPIO_MODE_GPIO 0x7 103#define MT7620_GPIO_MODE_GPIO 0x7
97#define MT7620_GPIO_MODE_UART1 BIT(5) 104
98#define MT7620_GPIO_MODE_MDIO BIT(8) 105#define MT7620_GPIO_MODE_NAND 0
99#define MT7620_GPIO_MODE_RGMII1 BIT(9) 106#define MT7620_GPIO_MODE_SD 1
100#define MT7620_GPIO_MODE_RGMII2 BIT(10) 107#define MT7620_GPIO_MODE_ND_SD_GPIO 2
101#define MT7620_GPIO_MODE_SPI BIT(11) 108#define MT7620_GPIO_MODE_ND_SD_MASK 0x3
102#define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12) 109#define MT7620_GPIO_MODE_ND_SD_SHIFT 18
103#define MT7620_GPIO_MODE_WLED BIT(13) 110
104#define MT7620_GPIO_MODE_JTAG BIT(15) 111#define MT7620_GPIO_MODE_PCIE_RST 0
105#define MT7620_GPIO_MODE_EPHY BIT(15) 112#define MT7620_GPIO_MODE_PCIE_REF 1
106#define MT7620_GPIO_MODE_WDT BIT(22) 113#define MT7620_GPIO_MODE_PCIE_GPIO 2
114#define MT7620_GPIO_MODE_PCIE_MASK 0x3
115#define MT7620_GPIO_MODE_PCIE_SHIFT 16
116
117#define MT7620_GPIO_MODE_WDT_RST 0
118#define MT7620_GPIO_MODE_WDT_REF 1
119#define MT7620_GPIO_MODE_WDT_GPIO 2
120#define MT7620_GPIO_MODE_WDT_MASK 0x3
121#define MT7620_GPIO_MODE_WDT_SHIFT 21
122
123#define MT7620_GPIO_MODE_I2C 0
124#define MT7620_GPIO_MODE_UART1 5
125#define MT7620_GPIO_MODE_MDIO 8
126#define MT7620_GPIO_MODE_RGMII1 9
127#define MT7620_GPIO_MODE_RGMII2 10
128#define MT7620_GPIO_MODE_SPI 11
129#define MT7620_GPIO_MODE_SPI_REF_CLK 12
130#define MT7620_GPIO_MODE_WLED 13
131#define MT7620_GPIO_MODE_JTAG 15
132#define MT7620_GPIO_MODE_EPHY 15
133#define MT7620_GPIO_MODE_PA 20
134
135static inline int mt7620_get_eco(void)
136{
137 return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK;
138}
107 139
108#endif 140#endif
diff --git a/arch/mips/include/asm/mach-ralink/pinmux.h b/arch/mips/include/asm/mach-ralink/pinmux.h
new file mode 100644
index 000000000000..be106cb2e26d
--- /dev/null
+++ b/arch/mips/include/asm/mach-ralink/pinmux.h
@@ -0,0 +1,55 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * publishhed by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
7 */
8
9#ifndef _RT288X_PINMUX_H__
10#define _RT288X_PINMUX_H__
11
12#define FUNC(name, value, pin_first, pin_count) \
13 { name, value, pin_first, pin_count }
14
15#define GRP(_name, _func, _mask, _shift) \
16 { .name = _name, .mask = _mask, .shift = _shift, \
17 .func = _func, .gpio = _mask, \
18 .func_count = ARRAY_SIZE(_func) }
19
20#define GRP_G(_name, _func, _mask, _gpio, _shift) \
21 { .name = _name, .mask = _mask, .shift = _shift, \
22 .func = _func, .gpio = _gpio, \
23 .func_count = ARRAY_SIZE(_func) }
24
25struct rt2880_pmx_group;
26
27struct rt2880_pmx_func {
28 const char *name;
29 const char value;
30
31 int pin_first;
32 int pin_count;
33 int *pins;
34
35 int *groups;
36 int group_count;
37
38 int enabled;
39};
40
41struct rt2880_pmx_group {
42 const char *name;
43 int enabled;
44
45 const u32 shift;
46 const char mask;
47 const char gpio;
48
49 struct rt2880_pmx_func *func;
50 int func_count;
51};
52
53extern struct rt2880_pmx_group *rt2880_pinmux_data;
54
55#endif
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h
index 5a508f9f9432..bd93014490df 100644
--- a/arch/mips/include/asm/mach-ralink/ralink_regs.h
+++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h
@@ -26,6 +26,13 @@ static inline u32 rt_sysc_r32(unsigned reg)
26 return __raw_readl(rt_sysc_membase + reg); 26 return __raw_readl(rt_sysc_membase + reg);
27} 27}
28 28
29static inline void rt_sysc_m32(u32 clr, u32 set, unsigned reg)
30{
31 u32 val = rt_sysc_r32(reg) & ~clr;
32
33 __raw_writel(val | set, rt_sysc_membase + reg);
34}
35
29static inline void rt_memc_w32(u32 val, unsigned reg) 36static inline void rt_memc_w32(u32 val, unsigned reg)
30{ 37{
31 __raw_writel(val, rt_memc_membase + reg); 38 __raw_writel(val, rt_memc_membase + reg);
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h
index 069bf37a6010..96f731bac79a 100644
--- a/arch/mips/include/asm/mach-ralink/rt305x.h
+++ b/arch/mips/include/asm/mach-ralink/rt305x.h
@@ -125,24 +125,29 @@ static inline int soc_is_rt5350(void)
125#define RT305X_GPIO_GE0_TXD0 40 125#define RT305X_GPIO_GE0_TXD0 40
126#define RT305X_GPIO_GE0_RXCLK 51 126#define RT305X_GPIO_GE0_RXCLK 51
127 127
128#define RT305X_GPIO_MODE_I2C BIT(0)
129#define RT305X_GPIO_MODE_SPI BIT(1)
130#define RT305X_GPIO_MODE_UART0_SHIFT 2 128#define RT305X_GPIO_MODE_UART0_SHIFT 2
131#define RT305X_GPIO_MODE_UART0_MASK 0x7 129#define RT305X_GPIO_MODE_UART0_MASK 0x7
132#define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT) 130#define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT)
133#define RT305X_GPIO_MODE_UARTF 0x0 131#define RT305X_GPIO_MODE_UARTF 0
134#define RT305X_GPIO_MODE_PCM_UARTF 0x1 132#define RT305X_GPIO_MODE_PCM_UARTF 1
135#define RT305X_GPIO_MODE_PCM_I2S 0x2 133#define RT305X_GPIO_MODE_PCM_I2S 2
136#define RT305X_GPIO_MODE_I2S_UARTF 0x3 134#define RT305X_GPIO_MODE_I2S_UARTF 3
137#define RT305X_GPIO_MODE_PCM_GPIO 0x4 135#define RT305X_GPIO_MODE_PCM_GPIO 4
138#define RT305X_GPIO_MODE_GPIO_UARTF 0x5 136#define RT305X_GPIO_MODE_GPIO_UARTF 5
139#define RT305X_GPIO_MODE_GPIO_I2S 0x6 137#define RT305X_GPIO_MODE_GPIO_I2S 6
140#define RT305X_GPIO_MODE_GPIO 0x7 138#define RT305X_GPIO_MODE_GPIO 7
141#define RT305X_GPIO_MODE_UART1 BIT(5) 139
142#define RT305X_GPIO_MODE_JTAG BIT(6) 140#define RT305X_GPIO_MODE_I2C 0
143#define RT305X_GPIO_MODE_MDIO BIT(7) 141#define RT305X_GPIO_MODE_SPI 1
144#define RT305X_GPIO_MODE_SDRAM BIT(8) 142#define RT305X_GPIO_MODE_UART1 5
145#define RT305X_GPIO_MODE_RGMII BIT(9) 143#define RT305X_GPIO_MODE_JTAG 6
144#define RT305X_GPIO_MODE_MDIO 7
145#define RT305X_GPIO_MODE_SDRAM 8
146#define RT305X_GPIO_MODE_RGMII 9
147#define RT5350_GPIO_MODE_PHY_LED 14
148#define RT5350_GPIO_MODE_SPI_CS1 21
149#define RT3352_GPIO_MODE_LNA 18
150#define RT3352_GPIO_MODE_PA 20
146 151
147#define RT3352_SYSC_REG_SYSCFG0 0x010 152#define RT3352_SYSC_REG_SYSCFG0 0x010
148#define RT3352_SYSC_REG_SYSCFG1 0x014 153#define RT3352_SYSC_REG_SYSCFG1 0x014
diff --git a/arch/mips/include/asm/mach-ralink/rt3883.h b/arch/mips/include/asm/mach-ralink/rt3883.h
index 058382f37f92..0fbe6f9257cd 100644
--- a/arch/mips/include/asm/mach-ralink/rt3883.h
+++ b/arch/mips/include/asm/mach-ralink/rt3883.h
@@ -112,8 +112,6 @@
112#define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) 112#define RT3883_CLKCFG1_PCI_CLK_EN BIT(19)
113#define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) 113#define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18)
114 114
115#define RT3883_GPIO_MODE_I2C BIT(0)
116#define RT3883_GPIO_MODE_SPI BIT(1)
117#define RT3883_GPIO_MODE_UART0_SHIFT 2 115#define RT3883_GPIO_MODE_UART0_SHIFT 2
118#define RT3883_GPIO_MODE_UART0_MASK 0x7 116#define RT3883_GPIO_MODE_UART0_MASK 0x7
119#define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) 117#define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT)
@@ -125,11 +123,15 @@
125#define RT3883_GPIO_MODE_GPIO_UARTF 0x5 123#define RT3883_GPIO_MODE_GPIO_UARTF 0x5
126#define RT3883_GPIO_MODE_GPIO_I2S 0x6 124#define RT3883_GPIO_MODE_GPIO_I2S 0x6
127#define RT3883_GPIO_MODE_GPIO 0x7 125#define RT3883_GPIO_MODE_GPIO 0x7
128#define RT3883_GPIO_MODE_UART1 BIT(5) 126
129#define RT3883_GPIO_MODE_JTAG BIT(6) 127#define RT3883_GPIO_MODE_I2C 0
130#define RT3883_GPIO_MODE_MDIO BIT(7) 128#define RT3883_GPIO_MODE_SPI 1
131#define RT3883_GPIO_MODE_GE1 BIT(9) 129#define RT3883_GPIO_MODE_UART1 5
132#define RT3883_GPIO_MODE_GE2 BIT(10) 130#define RT3883_GPIO_MODE_JTAG 6
131#define RT3883_GPIO_MODE_MDIO 7
132#define RT3883_GPIO_MODE_GE1 9
133#define RT3883_GPIO_MODE_GE2 10
134
133#define RT3883_GPIO_MODE_PCI_SHIFT 11 135#define RT3883_GPIO_MODE_PCI_SHIFT 11
134#define RT3883_GPIO_MODE_PCI_MASK 0x7 136#define RT3883_GPIO_MODE_PCI_MASK 0x7
135#define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) 137#define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT)
diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h
index d8106f75b9af..5d154cfbcf4c 100644
--- a/arch/mips/include/asm/mach-sead3/irq.h
+++ b/arch/mips/include/asm/mach-sead3/irq.h
@@ -1,7 +1,6 @@
1#ifndef __ASM_MACH_MIPS_IRQ_H 1#ifndef __ASM_MACH_MIPS_IRQ_H
2#define __ASM_MACH_MIPS_IRQ_H 2#define __ASM_MACH_MIPS_IRQ_H
3 3
4#define GIC_NUM_INTRS (24 + NR_CPUS * 2)
5#define NR_IRQS 256 4#define NR_IRQS 256
6 5
7 6
diff --git a/arch/mips/include/asm/mach-tx39xx/ioremap.h b/arch/mips/include/asm/mach-tx39xx/ioremap.h
index 93c6c04ffda3..0874cd2b06d7 100644
--- a/arch/mips/include/asm/mach-tx39xx/ioremap.h
+++ b/arch/mips/include/asm/mach-tx39xx/ioremap.h
@@ -15,12 +15,12 @@
15 * Allow physical addresses to be fixed up to help peripherals located 15 * Allow physical addresses to be fixed up to help peripherals located
16 * outside the low 32-bit range -- generic pass-through version. 16 * outside the low 32-bit range -- generic pass-through version.
17 */ 17 */
18static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 18static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
19{ 19{
20 return phys_addr; 20 return phys_addr;
21} 21}
22 22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 23static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
24 unsigned long flags) 24 unsigned long flags)
25{ 25{
26#define TXX9_DIRECTMAP_BASE 0xff000000ul 26#define TXX9_DIRECTMAP_BASE 0xff000000ul
diff --git a/arch/mips/include/asm/mach-tx49xx/ioremap.h b/arch/mips/include/asm/mach-tx49xx/ioremap.h
index 1e7beae72229..4b6a8441b25f 100644
--- a/arch/mips/include/asm/mach-tx49xx/ioremap.h
+++ b/arch/mips/include/asm/mach-tx49xx/ioremap.h
@@ -15,12 +15,12 @@
15 * Allow physical addresses to be fixed up to help peripherals located 15 * Allow physical addresses to be fixed up to help peripherals located
16 * outside the low 32-bit range -- generic pass-through version. 16 * outside the low 32-bit range -- generic pass-through version.
17 */ 17 */
18static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) 18static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size)
19{ 19{
20 return phys_addr; 20 return phys_addr;
21} 21}
22 22
23static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, 23static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size,
24 unsigned long flags) 24 unsigned long flags)
25{ 25{
26#ifdef CONFIG_64BIT 26#ifdef CONFIG_64BIT
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index e330732ddf98..987ff580466b 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -10,7 +10,7 @@
10#ifndef _MIPS_MALTAINT_H 10#ifndef _MIPS_MALTAINT_H
11#define _MIPS_MALTAINT_H 11#define _MIPS_MALTAINT_H
12 12
13#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) 13#include <linux/irqchip/mips-gic.h>
14 14
15/* 15/*
16 * Interrupts 0..15 are used for Malta ISA compatible interrupts 16 * Interrupts 0..15 are used for Malta ISA compatible interrupts
@@ -22,29 +22,28 @@
22#define MIPSCPU_INT_SW1 1 22#define MIPSCPU_INT_SW1 1
23#define MIPSCPU_INT_MB0 2 23#define MIPSCPU_INT_MB0 2
24#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 24#define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0
25#define MIPSCPU_INT_GIC MIPSCPU_INT_MB0 /* GIC chained interrupt */
25#define MIPSCPU_INT_MB1 3 26#define MIPSCPU_INT_MB1 3
26#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 27#define MIPSCPU_INT_SMI MIPSCPU_INT_MB1
27#define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */
28#define MIPSCPU_INT_MB2 4 28#define MIPSCPU_INT_MB2 4
29#define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */
30#define MIPSCPU_INT_MB3 5 29#define MIPSCPU_INT_MB3 5
31#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 30#define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3
32#define MIPSCPU_INT_MB4 6 31#define MIPSCPU_INT_MB4 6
33#define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 32#define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4
34 33
35/* 34/*
36 * Interrupts 64..127 are used for Soc-it Classic interrupts 35 * Interrupts 96..127 are used for Soc-it Classic interrupts
37 */ 36 */
38#define MSC01C_INT_BASE 64 37#define MSC01C_INT_BASE 96
39 38
40/* SOC-it Classic interrupt offsets */ 39/* SOC-it Classic interrupt offsets */
41#define MSC01C_INT_TMR 0 40#define MSC01C_INT_TMR 0
42#define MSC01C_INT_PCI 1 41#define MSC01C_INT_PCI 1
43 42
44/* 43/*
45 * Interrupts 64..127 are used for Soc-it EIC interrupts 44 * Interrupts 96..127 are used for Soc-it EIC interrupts
46 */ 45 */
47#define MSC01E_INT_BASE 64 46#define MSC01E_INT_BASE 96
48 47
49/* SOC-it EIC interrupt offsets */ 48/* SOC-it EIC interrupt offsets */
50#define MSC01E_INT_SW0 1 49#define MSC01E_INT_SW0 1
@@ -63,14 +62,7 @@
63#define MSC01E_INT_PERFCTR 10 62#define MSC01E_INT_PERFCTR 10
64#define MSC01E_INT_CPUCTR 11 63#define MSC01E_INT_CPUCTR 11
65 64
66/* External Interrupts used for IPI */ 65/* GIC external interrupts */
67#define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 66#define GIC_INT_I8259A GIC_SHARED_TO_HWIRQ(3)
68#define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17
69#define GIC_IPI_EXT_INTR_RESCHED_VPE1 18
70#define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19
71#define GIC_IPI_EXT_INTR_RESCHED_VPE2 20
72#define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21
73#define GIC_IPI_EXT_INTR_RESCHED_VPE3 22
74#define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23
75 67
76#endif /* !(_MIPS_MALTAINT_H) */ 68#endif /* !(_MIPS_MALTAINT_H) */
diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h
index 6b17aaf7d901..8932c7de0419 100644
--- a/arch/mips/include/asm/mips-boards/sead3int.h
+++ b/arch/mips/include/asm/mips-boards/sead3int.h
@@ -10,10 +10,23 @@
10#ifndef _MIPS_SEAD3INT_H 10#ifndef _MIPS_SEAD3INT_H
11#define _MIPS_SEAD3INT_H 11#define _MIPS_SEAD3INT_H
12 12
13#include <linux/irqchip/mips-gic.h>
14
13/* SEAD-3 GIC address space definitions. */ 15/* SEAD-3 GIC address space definitions. */
14#define GIC_BASE_ADDR 0x1b1c0000 16#define GIC_BASE_ADDR 0x1b1c0000
15#define GIC_ADDRSPACE_SZ (128 * 1024) 17#define GIC_ADDRSPACE_SZ (128 * 1024)
16 18
17#define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 0) 19/* CPU interrupt offsets */
20#define CPU_INT_GIC 2
21#define CPU_INT_EHCI 2
22#define CPU_INT_UART0 4
23#define CPU_INT_UART1 4
24#define CPU_INT_NET 6
25
26/* GIC interrupt offsets */
27#define GIC_INT_NET GIC_SHARED_TO_HWIRQ(0)
28#define GIC_INT_UART1 GIC_SHARED_TO_HWIRQ(2)
29#define GIC_INT_UART0 GIC_SHARED_TO_HWIRQ(3)
30#define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5)
18 31
19#endif /* !(_MIPS_SEAD3INT_H) */ 32#endif /* !(_MIPS_SEAD3INT_H) */
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
index 6a9d2dd005ca..b95a827d763e 100644
--- a/arch/mips/include/asm/mips-cm.h
+++ b/arch/mips/include/asm/mips-cm.h
@@ -30,7 +30,7 @@ extern void __iomem *mips_cm_l2sync_base;
30 * different way by defining a function with the same prototype except for the 30 * different way by defining a function with the same prototype except for the
31 * name mips_cm_phys_base (without underscores). 31 * name mips_cm_phys_base (without underscores).
32 */ 32 */
33extern phys_t __mips_cm_phys_base(void); 33extern phys_addr_t __mips_cm_phys_base(void);
34 34
35/** 35/**
36 * mips_cm_probe - probe for a Coherence Manager 36 * mips_cm_probe - probe for a Coherence Manager
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h
index e139a534e0fd..1cebe8c79051 100644
--- a/arch/mips/include/asm/mips-cpc.h
+++ b/arch/mips/include/asm/mips-cpc.h
@@ -25,7 +25,7 @@ extern void __iomem *mips_cpc_base;
25 * memory mapped registers. This is platform dependant & must therefore be 25 * memory mapped registers. This is platform dependant & must therefore be
26 * implemented per-platform. 26 * implemented per-platform.
27 */ 27 */
28extern phys_t mips_cpc_default_phys_base(void); 28extern phys_addr_t mips_cpc_default_phys_base(void);
29 29
30/** 30/**
31 * mips_cpc_phys_base - retrieve the physical base address of the CPC 31 * mips_cpc_phys_base - retrieve the physical base address of the CPC
@@ -35,7 +35,7 @@ extern phys_t mips_cpc_default_phys_base(void);
35 * is present. It may be overriden by individual platforms which determine 35 * is present. It may be overriden by individual platforms which determine
36 * this address in a different way. 36 * this address in a different way.
37 */ 37 */
38extern phys_t __weak mips_cpc_phys_base(void); 38extern phys_addr_t __weak mips_cpc_phys_base(void);
39 39
40/** 40/**
41 * mips_cpc_probe - probe for a Cluster Power Controller 41 * mips_cpc_probe - probe for a Cluster Power Controller
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 22a135ac91de..5e4aef304b02 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -653,6 +653,9 @@
653#define MIPS_CONF5_NF (_ULCAST_(1) << 0) 653#define MIPS_CONF5_NF (_ULCAST_(1) << 0)
654#define MIPS_CONF5_UFR (_ULCAST_(1) << 2) 654#define MIPS_CONF5_UFR (_ULCAST_(1) << 2)
655#define MIPS_CONF5_MRP (_ULCAST_(1) << 3) 655#define MIPS_CONF5_MRP (_ULCAST_(1) << 3)
656#define MIPS_CONF5_MVH (_ULCAST_(1) << 5)
657#define MIPS_CONF5_FRE (_ULCAST_(1) << 8)
658#define MIPS_CONF5_UFE (_ULCAST_(1) << 9)
656#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) 659#define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27)
657#define MIPS_CONF5_EVA (_ULCAST_(1) << 28) 660#define MIPS_CONF5_EVA (_ULCAST_(1) << 28)
658#define MIPS_CONF5_CV (_ULCAST_(1) << 29) 661#define MIPS_CONF5_CV (_ULCAST_(1) << 29)
@@ -694,6 +697,7 @@
694#define MIPS_FPIR_W (_ULCAST_(1) << 20) 697#define MIPS_FPIR_W (_ULCAST_(1) << 20)
695#define MIPS_FPIR_L (_ULCAST_(1) << 21) 698#define MIPS_FPIR_L (_ULCAST_(1) << 21)
696#define MIPS_FPIR_F64 (_ULCAST_(1) << 22) 699#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
700#define MIPS_FPIR_FREP (_ULCAST_(1) << 29)
697 701
698/* 702/*
699 * Bits in the MIPS32 Memory Segmentation registers. 703 * Bits in the MIPS32 Memory Segmentation registers.
@@ -994,6 +998,39 @@ do { \
994 local_irq_restore(__flags); \ 998 local_irq_restore(__flags); \
995} while (0) 999} while (0)
996 1000
1001#define __readx_32bit_c0_register(source) \
1002({ \
1003 unsigned int __res; \
1004 \
1005 __asm__ __volatile__( \
1006 " .set push \n" \
1007 " .set noat \n" \
1008 " .set mips32r2 \n" \
1009 " .insn \n" \
1010 " # mfhc0 $1, %1 \n" \
1011 " .word (0x40410000 | ((%1 & 0x1f) << 11)) \n" \
1012 " move %0, $1 \n" \
1013 " .set pop \n" \
1014 : "=r" (__res) \
1015 : "i" (source)); \
1016 __res; \
1017})
1018
1019#define __writex_32bit_c0_register(register, value) \
1020do { \
1021 __asm__ __volatile__( \
1022 " .set push \n" \
1023 " .set noat \n" \
1024 " .set mips32r2 \n" \
1025 " move $1, %0 \n" \
1026 " # mthc0 $1, %1 \n" \
1027 " .insn \n" \
1028 " .word (0x40c10000 | ((%1 & 0x1f) << 11)) \n" \
1029 " .set pop \n" \
1030 : \
1031 : "r" (value), "i" (register)); \
1032} while (0)
1033
997#define read_c0_index() __read_32bit_c0_register($0, 0) 1034#define read_c0_index() __read_32bit_c0_register($0, 0)
998#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) 1035#define write_c0_index(val) __write_32bit_c0_register($0, 0, val)
999 1036
@@ -1003,9 +1040,15 @@ do { \
1003#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) 1040#define read_c0_entrylo0() __read_ulong_c0_register($2, 0)
1004#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) 1041#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val)
1005 1042
1043#define readx_c0_entrylo0() __readx_32bit_c0_register(2)
1044#define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val)
1045
1006#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) 1046#define read_c0_entrylo1() __read_ulong_c0_register($3, 0)
1007#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) 1047#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val)
1008 1048
1049#define readx_c0_entrylo1() __readx_32bit_c0_register(3)
1050#define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val)
1051
1009#define read_c0_conf() __read_32bit_c0_register($3, 0) 1052#define read_c0_conf() __read_32bit_c0_register($3, 0)
1010#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) 1053#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val)
1011 1054
diff --git a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
index 024a71b2bff9..75739c83f07e 100644
--- a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
+++ b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
@@ -76,6 +76,8 @@
76 76
77#include <linux/prefetch.h> 77#include <linux/prefetch.h>
78 78
79#include <asm/compiler.h>
80
79#include <asm/octeon/cvmx-fpa.h> 81#include <asm/octeon/cvmx-fpa.h>
80/** 82/**
81 * By default we disable the max depth support. Most programs 83 * By default we disable the max depth support. Most programs
@@ -273,7 +275,7 @@ static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id,
273 " lbu %[ticket], %[now_serving]\n" 275 " lbu %[ticket], %[now_serving]\n"
274 "4:\n" 276 "4:\n"
275 ".set pop\n" : 277 ".set pop\n" :
276 [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), 278 [ticket_ptr] "=" GCC_OFF12_ASM()(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]),
277 [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp), 279 [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp),
278 [my_ticket] "=r"(my_ticket) 280 [my_ticket] "=r"(my_ticket)
279 ); 281 );
diff --git a/arch/mips/include/asm/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h
index 4b4d0ecfd9eb..2188e65afb86 100644
--- a/arch/mips/include/asm/octeon/cvmx-pow.h
+++ b/arch/mips/include/asm/octeon/cvmx-pow.h
@@ -1066,7 +1066,7 @@ static inline void __cvmx_pow_warn_if_pending_switch(const char *function)
1066 uint64_t switch_complete; 1066 uint64_t switch_complete;
1067 CVMX_MF_CHORD(switch_complete); 1067 CVMX_MF_CHORD(switch_complete);
1068 if (!switch_complete) 1068 if (!switch_complete)
1069 pr_warning("%s called with tag switch in progress\n", function); 1069 pr_warn("%s called with tag switch in progress\n", function);
1070} 1070}
1071 1071
1072/** 1072/**
@@ -1084,8 +1084,7 @@ static inline void cvmx_pow_tag_sw_wait(void)
1084 if (unlikely(switch_complete)) 1084 if (unlikely(switch_complete))
1085 break; 1085 break;
1086 if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { 1086 if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) {
1087 pr_warning("Tag switch is taking a long time, " 1087 pr_warn("Tag switch is taking a long time, possible deadlock\n");
1088 "possible deadlock\n");
1089 start_cycle = -MAX_CYCLES - 1; 1088 start_cycle = -MAX_CYCLES - 1;
1090 } 1089 }
1091 } 1090 }
@@ -1296,19 +1295,16 @@ static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag,
1296 __cvmx_pow_warn_if_pending_switch(__func__); 1295 __cvmx_pow_warn_if_pending_switch(__func__);
1297 current_tag = cvmx_pow_get_current_tag(); 1296 current_tag = cvmx_pow_get_current_tag();
1298 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1297 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1299 pr_warning("%s called with NULL_NULL tag\n", 1298 pr_warn("%s called with NULL_NULL tag\n", __func__);
1300 __func__);
1301 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1299 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
1302 pr_warning("%s called with NULL tag\n", __func__); 1300 pr_warn("%s called with NULL tag\n", __func__);
1303 if ((current_tag.s.type == tag_type) 1301 if ((current_tag.s.type == tag_type)
1304 && (current_tag.s.tag == tag)) 1302 && (current_tag.s.tag == tag))
1305 pr_warning("%s called to perform a tag switch to the " 1303 pr_warn("%s called to perform a tag switch to the same tag\n",
1306 "same tag\n", 1304 __func__);
1307 __func__);
1308 if (tag_type == CVMX_POW_TAG_TYPE_NULL) 1305 if (tag_type == CVMX_POW_TAG_TYPE_NULL)
1309 pr_warning("%s called to perform a tag switch to " 1306 pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n",
1310 "NULL. Use cvmx_pow_tag_sw_null() instead\n", 1307 __func__);
1311 __func__);
1312 } 1308 }
1313 1309
1314 /* 1310 /*
@@ -1407,23 +1403,19 @@ static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag,
1407 __cvmx_pow_warn_if_pending_switch(__func__); 1403 __cvmx_pow_warn_if_pending_switch(__func__);
1408 current_tag = cvmx_pow_get_current_tag(); 1404 current_tag = cvmx_pow_get_current_tag();
1409 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1405 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1410 pr_warning("%s called with NULL_NULL tag\n", 1406 pr_warn("%s called with NULL_NULL tag\n", __func__);
1411 __func__);
1412 if ((current_tag.s.type == tag_type) 1407 if ((current_tag.s.type == tag_type)
1413 && (current_tag.s.tag == tag)) 1408 && (current_tag.s.tag == tag))
1414 pr_warning("%s called to perform a tag switch to " 1409 pr_warn("%s called to perform a tag switch to the same tag\n",
1415 "the same tag\n", 1410 __func__);
1416 __func__);
1417 if (tag_type == CVMX_POW_TAG_TYPE_NULL) 1411 if (tag_type == CVMX_POW_TAG_TYPE_NULL)
1418 pr_warning("%s called to perform a tag switch to " 1412 pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n",
1419 "NULL. Use cvmx_pow_tag_sw_null() instead\n", 1413 __func__);
1420 __func__);
1421 if (wqp != cvmx_phys_to_ptr(0x80)) 1414 if (wqp != cvmx_phys_to_ptr(0x80))
1422 if (wqp != cvmx_pow_get_current_wqp()) 1415 if (wqp != cvmx_pow_get_current_wqp())
1423 pr_warning("%s passed WQE(%p) doesn't match " 1416 pr_warn("%s passed WQE(%p) doesn't match the address in the POW(%p)\n",
1424 "the address in the POW(%p)\n", 1417 __func__, wqp,
1425 __func__, wqp, 1418 cvmx_pow_get_current_wqp());
1426 cvmx_pow_get_current_wqp());
1427 } 1419 }
1428 1420
1429 /* 1421 /*
@@ -1507,12 +1499,10 @@ static inline void cvmx_pow_tag_sw_null_nocheck(void)
1507 __cvmx_pow_warn_if_pending_switch(__func__); 1499 __cvmx_pow_warn_if_pending_switch(__func__);
1508 current_tag = cvmx_pow_get_current_tag(); 1500 current_tag = cvmx_pow_get_current_tag();
1509 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1501 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1510 pr_warning("%s called with NULL_NULL tag\n", 1502 pr_warn("%s called with NULL_NULL tag\n", __func__);
1511 __func__);
1512 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1503 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
1513 pr_warning("%s called when we already have a " 1504 pr_warn("%s called when we already have a NULL tag\n",
1514 "NULL tag\n", 1505 __func__);
1515 __func__);
1516 } 1506 }
1517 1507
1518 tag_req.u64 = 0; 1508 tag_req.u64 = 0;
@@ -1725,17 +1715,14 @@ static inline void cvmx_pow_tag_sw_desched_nocheck(
1725 __cvmx_pow_warn_if_pending_switch(__func__); 1715 __cvmx_pow_warn_if_pending_switch(__func__);
1726 current_tag = cvmx_pow_get_current_tag(); 1716 current_tag = cvmx_pow_get_current_tag();
1727 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1717 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1728 pr_warning("%s called with NULL_NULL tag\n", 1718 pr_warn("%s called with NULL_NULL tag\n", __func__);
1729 __func__);
1730 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1719 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
1731 pr_warning("%s called with NULL tag. Deschedule not " 1720 pr_warn("%s called with NULL tag. Deschedule not allowed from NULL state\n",
1732 "allowed from NULL state\n", 1721 __func__);
1733 __func__);
1734 if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) 1722 if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC)
1735 && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) 1723 && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC))
1736 pr_warning("%s called where neither the before or " 1724 pr_warn("%s called where neither the before or after tag is ATOMIC\n",
1737 "after tag is ATOMIC\n", 1725 __func__);
1738 __func__);
1739 } 1726 }
1740 1727
1741 tag_req.u64 = 0; 1728 tag_req.u64 = 0;
@@ -1832,12 +1819,10 @@ static inline void cvmx_pow_desched(uint64_t no_sched)
1832 __cvmx_pow_warn_if_pending_switch(__func__); 1819 __cvmx_pow_warn_if_pending_switch(__func__);
1833 current_tag = cvmx_pow_get_current_tag(); 1820 current_tag = cvmx_pow_get_current_tag();
1834 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) 1821 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
1835 pr_warning("%s called with NULL_NULL tag\n", 1822 pr_warn("%s called with NULL_NULL tag\n", __func__);
1836 __func__);
1837 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) 1823 if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
1838 pr_warning("%s called with NULL tag. Deschedule not " 1824 pr_warn("%s called with NULL tag. Deschedule not expected from NULL state\n",
1839 "expected from NULL state\n", 1825 __func__);
1840 __func__);
1841 } 1826 }
1842 1827
1843 /* Need to make sure any writes to the work queue entry are complete */ 1828 /* Need to make sure any writes to the work queue entry are complete */
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index f991e7701d3d..33db1c806b01 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -451,67 +451,4 @@ static inline uint32_t cvmx_octeon_num_cores(void)
451 return cvmx_pop(ciu_fuse); 451 return cvmx_pop(ciu_fuse);
452} 452}
453 453
454/**
455 * Read a byte of fuse data
456 * @byte_addr: address to read
457 *
458 * Returns fuse value: 0 or 1
459 */
460static uint8_t cvmx_fuse_read_byte(int byte_addr)
461{
462 union cvmx_mio_fus_rcmd read_cmd;
463
464 read_cmd.u64 = 0;
465 read_cmd.s.addr = byte_addr;
466 read_cmd.s.pend = 1;
467 cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
468 while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
469 && read_cmd.s.pend)
470 ;
471 return read_cmd.s.dat;
472}
473
474/**
475 * Read a single fuse bit
476 *
477 * @fuse: Fuse number (0-1024)
478 *
479 * Returns fuse value: 0 or 1
480 */
481static inline int cvmx_fuse_read(int fuse)
482{
483 return (cvmx_fuse_read_byte(fuse >> 3) >> (fuse & 0x7)) & 1;
484}
485
486static inline int cvmx_octeon_model_CN36XX(void)
487{
488 return OCTEON_IS_MODEL(OCTEON_CN38XX)
489 && !cvmx_octeon_is_pass1()
490 && cvmx_fuse_read(264);
491}
492
493static inline int cvmx_octeon_zip_present(void)
494{
495 return octeon_has_feature(OCTEON_FEATURE_ZIP);
496}
497
498static inline int cvmx_octeon_dfa_present(void)
499{
500 if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
501 && !OCTEON_IS_MODEL(OCTEON_CN31XX)
502 && !OCTEON_IS_MODEL(OCTEON_CN58XX))
503 return 0;
504 else if (OCTEON_IS_MODEL(OCTEON_CN3020))
505 return 0;
506 else if (cvmx_octeon_is_pass1())
507 return 1;
508 else
509 return !cvmx_fuse_read(120);
510}
511
512static inline int cvmx_octeon_crypto_present(void)
513{
514 return octeon_has_feature(OCTEON_FEATURE_CRYPTO);
515}
516
517#endif /* __CVMX_H__ */ 454#endif /* __CVMX_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h
index 90e05a8d4b15..c4fe81f47f53 100644
--- a/arch/mips/include/asm/octeon/octeon-feature.h
+++ b/arch/mips/include/asm/octeon/octeon-feature.h
@@ -86,8 +86,6 @@ enum octeon_feature {
86 OCTEON_MAX_FEATURE 86 OCTEON_MAX_FEATURE
87}; 87};
88 88
89static inline int cvmx_fuse_read(int fuse);
90
91/** 89/**
92 * Determine if the current Octeon supports a specific feature. These 90 * Determine if the current Octeon supports a specific feature. These
93 * checks have been optimized to be fairly quick, but they should still 91 * checks have been optimized to be fairly quick, but they should still
@@ -105,33 +103,6 @@ static inline int octeon_has_feature(enum octeon_feature feature)
105 case OCTEON_FEATURE_SAAD: 103 case OCTEON_FEATURE_SAAD:
106 return !OCTEON_IS_MODEL(OCTEON_CN3XXX); 104 return !OCTEON_IS_MODEL(OCTEON_CN3XXX);
107 105
108 case OCTEON_FEATURE_ZIP:
109 if (OCTEON_IS_MODEL(OCTEON_CN30XX)
110 || OCTEON_IS_MODEL(OCTEON_CN50XX)
111 || OCTEON_IS_MODEL(OCTEON_CN52XX))
112 return 0;
113 else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
114 return 1;
115 else
116 return !cvmx_fuse_read(121);
117
118 case OCTEON_FEATURE_CRYPTO:
119 if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
120 union cvmx_mio_fus_dat2 fus_2;
121 fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
122 if (fus_2.s.nocrypto || fus_2.s.nomul) {
123 return 0;
124 } else if (!fus_2.s.dorm_crypto) {
125 return 1;
126 } else {
127 union cvmx_rnm_ctl_status st;
128 st.u64 = cvmx_read_csr(CVMX_RNM_CTL_STATUS);
129 return st.s.eer_val;
130 }
131 } else {
132 return !cvmx_fuse_read(90);
133 }
134
135 case OCTEON_FEATURE_DORM_CRYPTO: 106 case OCTEON_FEATURE_DORM_CRYPTO:
136 if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { 107 if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
137 union cvmx_mio_fus_dat2 fus_2; 108 union cvmx_mio_fus_dat2 fus_2;
@@ -188,29 +159,6 @@ static inline int octeon_has_feature(enum octeon_feature feature)
188 && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) 159 && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
189 && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X); 160 && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X);
190 161
191 case OCTEON_FEATURE_DFA:
192 if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
193 && !OCTEON_IS_MODEL(OCTEON_CN31XX)
194 && !OCTEON_IS_MODEL(OCTEON_CN58XX))
195 return 0;
196 else if (OCTEON_IS_MODEL(OCTEON_CN3020))
197 return 0;
198 else
199 return !cvmx_fuse_read(120);
200
201 case OCTEON_FEATURE_HFA:
202 if (!OCTEON_IS_MODEL(OCTEON_CN6XXX))
203 return 0;
204 else
205 return !cvmx_fuse_read(90);
206
207 case OCTEON_FEATURE_DFM:
208 if (!(OCTEON_IS_MODEL(OCTEON_CN63XX)
209 || OCTEON_IS_MODEL(OCTEON_CN66XX)))
210 return 0;
211 else
212 return !cvmx_fuse_read(90);
213
214 case OCTEON_FEATURE_MDIO_CLAUSE_45: 162 case OCTEON_FEATURE_MDIO_CLAUSE_45:
215 return !(OCTEON_IS_MODEL(OCTEON_CN3XXX) 163 return !(OCTEON_IS_MODEL(OCTEON_CN3XXX)
216 || OCTEON_IS_MODEL(OCTEON_CN58XX) 164 || OCTEON_IS_MODEL(OCTEON_CN58XX)
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
index e2c122c6a657..e8a1c2fd52cd 100644
--- a/arch/mips/include/asm/octeon/octeon-model.h
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -326,8 +326,7 @@ static inline int __octeon_is_model_runtime__(uint32_t model)
326#define OCTEON_IS_COMMON_BINARY() 1 326#define OCTEON_IS_COMMON_BINARY() 1
327#undef OCTEON_MODEL 327#undef OCTEON_MODEL
328 328
329const char *octeon_model_get_string(uint32_t chip_id); 329const char *__init octeon_model_get_string(uint32_t chip_id);
330const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer);
331 330
332/* 331/*
333 * Return the octeon family, i.e., ProcessorID of the PrID register. 332 * Return the octeon family, i.e., ProcessorID of the PrID register.
diff --git a/arch/mips/include/asm/paccess.h b/arch/mips/include/asm/paccess.h
index 2474fc5d1751..af81ab0da55f 100644
--- a/arch/mips/include/asm/paccess.h
+++ b/arch/mips/include/asm/paccess.h
@@ -56,6 +56,7 @@ struct __large_pstruct { unsigned long buf[100]; };
56 "1:\t" insn "\t%1,%2\n\t" \ 56 "1:\t" insn "\t%1,%2\n\t" \
57 "move\t%0,$0\n" \ 57 "move\t%0,$0\n" \
58 "2:\n\t" \ 58 "2:\n\t" \
59 ".insn\n\t" \
59 ".section\t.fixup,\"ax\"\n" \ 60 ".section\t.fixup,\"ax\"\n" \
60 "3:\tli\t%0,%3\n\t" \ 61 "3:\tli\t%0,%3\n\t" \
61 "move\t%1,$0\n\t" \ 62 "move\t%1,$0\n\t" \
@@ -94,6 +95,7 @@ extern void __get_dbe_unknown(void);
94 "1:\t" insn "\t%1,%2\n\t" \ 95 "1:\t" insn "\t%1,%2\n\t" \
95 "move\t%0,$0\n" \ 96 "move\t%0,$0\n" \
96 "2:\n\t" \ 97 "2:\n\t" \
98 ".insn\n\t" \
97 ".section\t.fixup,\"ax\"\n" \ 99 ".section\t.fixup,\"ax\"\n" \
98 "3:\tli\t%0,%3\n\t" \ 100 "3:\tli\t%0,%3\n\t" \
99 "j\t2b\n\t" \ 101 "j\t2b\n\t" \
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index 3be81803595d..154b70a10483 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -116,7 +116,7 @@ extern void copy_user_highpage(struct page *to, struct page *from,
116/* 116/*
117 * These are used to make use of C type-checking.. 117 * These are used to make use of C type-checking..
118 */ 118 */
119#ifdef CONFIG_64BIT_PHYS_ADDR 119#ifdef CONFIG_PHYS_ADDR_T_64BIT
120 #ifdef CONFIG_CPU_MIPS32 120 #ifdef CONFIG_CPU_MIPS32
121 typedef struct { unsigned long pte_low, pte_high; } pte_t; 121 typedef struct { unsigned long pte_low, pte_high; } pte_t;
122 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) 122 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 974b0e308963..69529624a005 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -84,7 +84,7 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
84 const struct resource *rsrc, resource_size_t *start, 84 const struct resource *rsrc, resource_size_t *start,
85 resource_size_t *end) 85 resource_size_t *end)
86{ 86{
87 phys_t size = resource_size(rsrc); 87 phys_addr_t size = resource_size(rsrc);
88 88
89 *start = fixup_bigphys_addr(rsrc->start, size); 89 *start = fixup_bigphys_addr(rsrc->start, size);
90 *end = rsrc->start + size; 90 *end = rsrc->start + size;
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index cd7d6064bcbe..68984b612f9d 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -69,7 +69,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
69# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) 69# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
70#endif 70#endif
71 71
72#ifdef CONFIG_64BIT_PHYS_ADDR 72#ifdef CONFIG_PHYS_ADDR_T_64BIT
73#define pte_ERROR(e) \ 73#define pte_ERROR(e) \
74 printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) 74 printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e))
75#else 75#else
@@ -103,7 +103,7 @@ static inline void pmd_clear(pmd_t *pmdp)
103 pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); 103 pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
104} 104}
105 105
106#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 106#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
107#define pte_page(x) pfn_to_page(pte_pfn(x)) 107#define pte_page(x) pfn_to_page(pte_pfn(x))
108#define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) 108#define pte_pfn(x) ((unsigned long)((x).pte_high >> 6))
109static inline pte_t 109static inline pte_t
@@ -126,7 +126,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
126#define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) 126#define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT))
127#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) 127#define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot))
128#endif 128#endif
129#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ 129#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
130 130
131#define __pgd_offset(address) pgd_index(address) 131#define __pgd_offset(address) pgd_index(address)
132#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) 132#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
@@ -155,73 +155,75 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
155#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 155#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
156 156
157/* Swap entries must have VALID bit cleared. */ 157/* Swap entries must have VALID bit cleared. */
158#define __swp_type(x) (((x).val >> 10) & 0x1f) 158#define __swp_type(x) (((x).val >> 10) & 0x1f)
159#define __swp_offset(x) ((x).val >> 15) 159#define __swp_offset(x) ((x).val >> 15)
160#define __swp_entry(type,offset) \ 160#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 10) | ((offset) << 15) })
161 ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) 161#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
162#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
162 163
163/* 164/*
164 * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: 165 * Encode and decode a nonlinear file mapping entry
165 */ 166 */
166#define PTE_FILE_MAX_BITS 28 167#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \
167 168 (((_pte).pte >> 2 ) & 0x38) | \
168#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ 169 (((_pte).pte >> 10) << 6 ))
169 (((_pte).pte >> 2 ) & 0x38) | \
170 (((_pte).pte >> 10) << 6 ))
171 170
172#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ 171#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \
173 (((off) & 0x38) << 2 ) | \ 172 (((off) & 0x38) << 2 ) | \
174 (((off) >> 6 ) << 10) | \ 173 (((off) >> 6 ) << 10) | \
175 _PAGE_FILE }) 174 _PAGE_FILE })
176 175
176/*
177 * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range:
178 */
179#define PTE_FILE_MAX_BITS 28
177#else 180#else
178 181
182#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
183
179/* Swap entries must have VALID and GLOBAL bits cleared. */ 184/* Swap entries must have VALID and GLOBAL bits cleared. */
180#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 185#define __swp_type(x) (((x).val >> 2) & 0x1f)
181#define __swp_type(x) (((x).val >> 2) & 0x1f) 186#define __swp_offset(x) ((x).val >> 7)
182#define __swp_offset(x) ((x).val >> 7) 187#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 7) })
183#define __swp_entry(type,offset) \ 188#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
184 ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) 189#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
185#else
186#define __swp_type(x) (((x).val >> 8) & 0x1f)
187#define __swp_offset(x) ((x).val >> 13)
188#define __swp_entry(type,offset) \
189 ((swp_entry_t) { ((type) << 8) | ((offset) << 13) })
190#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */
191 190
192#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
193/* 191/*
194 * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... 192 * Bits 0 and 1 of pte_high are taken, use the rest for the page offset...
195 */ 193 */
196#define PTE_FILE_MAX_BITS 30 194#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2)
197 195#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 })
198#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2)
199#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 })
200 196
197#define PTE_FILE_MAX_BITS 30
201#else 198#else
202/* 199/*
203 * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range: 200 * Constraints:
201 * _PAGE_PRESENT at bit 0
202 * _PAGE_MODIFIED at bit 4
203 * _PAGE_GLOBAL at bit 6
204 * _PAGE_VALID at bit 7
204 */ 205 */
205#define PTE_FILE_MAX_BITS 28 206#define __swp_type(x) (((x).val >> 8) & 0x1f)
207#define __swp_offset(x) ((x).val >> 13)
208#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 8) | ((offset) << 13) })
209#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
210#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
206 211
207#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ 212/*
208 (((_pte).pte >> 2) & 0x8) | \ 213 * Encode and decode a nonlinear file mapping entry
209 (((_pte).pte >> 8) << 4)) 214 */
215#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \
216 (((_pte).pte >> 2) & 0x8) | \
217 (((_pte).pte >> 8) << 4))
210 218
211#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ 219#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \
212 (((off) & 0x8) << 2) | \ 220 (((off) & 0x8) << 2) | \
213 (((off) >> 4) << 8) | \ 221 (((off) >> 4) << 8) | \
214 _PAGE_FILE }) 222 _PAGE_FILE })
215#endif
216 223
217#endif 224#define PTE_FILE_MAX_BITS 28
225#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */
218 226
219#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 227#endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */
220#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high })
221#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val })
222#else
223#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
224#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
225#endif
226 228
227#endif /* _ASM_PGTABLE_32_H */ 229#endif /* _ASM_PGTABLE_32_H */
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index e747bfa0be7e..ca11f14f40a3 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -32,39 +32,41 @@
32 * unpredictable things. The code (when it is written) to deal with 32 * unpredictable things. The code (when it is written) to deal with
33 * this problem will be in the update_mmu_cache() code for the r4k. 33 * this problem will be in the update_mmu_cache() code for the r4k.
34 */ 34 */
35#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 35#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
36 36
37/* 37/*
38 * The following bits are directly used by the TLB hardware 38 * The following bits are directly used by the TLB hardware
39 */ 39 */
40#define _PAGE_R4KBUG (1 << 0) /* workaround for r4k bug */ 40#define _PAGE_GLOBAL_SHIFT 0
41#define _PAGE_GLOBAL (1 << 0) 41#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
42#define _PAGE_VALID_SHIFT 1 42#define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1)
43#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) 43#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
44#define _PAGE_SILENT_READ (1 << 1) /* synonym */ 44#define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1)
45#define _PAGE_DIRTY_SHIFT 2 45#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT)
46#define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) /* The MIPS dirty bit */ 46#define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1)
47#define _PAGE_SILENT_WRITE (1 << 2) 47#define _CACHE_MASK (7 << _CACHE_SHIFT)
48#define _CACHE_SHIFT 3
49#define _CACHE_MASK (7 << 3)
50 48
51/* 49/*
52 * The following bits are implemented in software 50 * The following bits are implemented in software
53 * 51 *
54 * _PAGE_FILE semantics: set:pagecache unset:swap 52 * _PAGE_FILE semantics: set:pagecache unset:swap
55 */ 53 */
56#define _PAGE_PRESENT_SHIFT 6 54#define _PAGE_PRESENT_SHIFT (_CACHE_SHIFT + 3)
57#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) 55#define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT)
58#define _PAGE_READ_SHIFT 7 56#define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1)
59#define _PAGE_READ (1 << _PAGE_READ_SHIFT) 57#define _PAGE_READ (1 << _PAGE_READ_SHIFT)
60#define _PAGE_WRITE_SHIFT 8 58#define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1)
61#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) 59#define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT)
62#define _PAGE_ACCESSED_SHIFT 9 60#define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1)
63#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) 61#define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT)
64#define _PAGE_MODIFIED_SHIFT 10 62#define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1)
65#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) 63#define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT)
66 64
67#define _PAGE_FILE (1 << 10) 65#define _PAGE_SILENT_READ _PAGE_VALID
66#define _PAGE_SILENT_WRITE _PAGE_DIRTY
67#define _PAGE_FILE _PAGE_MODIFIED
68
69#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
68 70
69#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 71#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
70 72
@@ -172,7 +174,7 @@
172 174
173#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) 175#define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
174 176
175#endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */ 177#endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */
176 178
177#ifndef _PFN_SHIFT 179#ifndef _PFN_SHIFT
178#define _PFN_SHIFT PAGE_SHIFT 180#define _PFN_SHIFT PAGE_SHIFT
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index d6d1928539b1..62a6ba383d4f 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -125,7 +125,7 @@ do { \
125extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, 125extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
126 pte_t pteval); 126 pte_t pteval);
127 127
128#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 128#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
129 129
130#define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) 130#define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
131#define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) 131#define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT)
@@ -227,7 +227,7 @@ extern pgd_t swapper_pg_dir[];
227 * The following only work if pte_present() is true. 227 * The following only work if pte_present() is true.
228 * Undefined behaviour if not.. 228 * Undefined behaviour if not..
229 */ 229 */
230#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 230#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
231static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } 231static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; }
232static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } 232static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; }
233static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } 233static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; }
@@ -297,13 +297,13 @@ static inline pte_t pte_wrprotect(pte_t pte)
297 297
298static inline pte_t pte_mkclean(pte_t pte) 298static inline pte_t pte_mkclean(pte_t pte)
299{ 299{
300 pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); 300 pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
301 return pte; 301 return pte;
302} 302}
303 303
304static inline pte_t pte_mkold(pte_t pte) 304static inline pte_t pte_mkold(pte_t pte)
305{ 305{
306 pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); 306 pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
307 return pte; 307 return pte;
308} 308}
309 309
@@ -382,13 +382,13 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
382 */ 382 */
383#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) 383#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
384 384
385#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 385#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
386static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 386static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
387{ 387{
388 pte.pte_low &= _PAGE_CHG_MASK; 388 pte.pte_low &= _PAGE_CHG_MASK;
389 pte.pte_high &= ~0x3f; 389 pte.pte_high &= (_PFN_MASK | _CACHE_MASK);
390 pte.pte_low |= pgprot_val(newprot); 390 pte.pte_low |= pgprot_val(newprot);
391 pte.pte_high |= pgprot_val(newprot) & 0x3f; 391 pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK);
392 return pte; 392 return pte;
393} 393}
394#else 394#else
@@ -419,7 +419,7 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
419 419
420#define kern_addr_valid(addr) (1) 420#define kern_addr_valid(addr) (1)
421 421
422#ifdef CONFIG_64BIT_PHYS_ADDR 422#ifdef CONFIG_PHYS_ADDR_T_64BIT
423extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); 423extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot);
424 424
425static inline int io_remap_pfn_range(struct vm_area_struct *vma, 425static inline int io_remap_pfn_range(struct vm_area_struct *vma,
@@ -428,7 +428,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
428 unsigned long size, 428 unsigned long size,
429 pgprot_t prot) 429 pgprot_t prot)
430{ 430{
431 phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); 431 phys_addr_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
432 return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot); 432 return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
433} 433}
434#define io_remap_pfn_range io_remap_pfn_range 434#define io_remap_pfn_range io_remap_pfn_range
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h
index a9494c0141fb..eaa26270a5e5 100644
--- a/arch/mips/include/asm/prom.h
+++ b/arch/mips/include/asm/prom.h
@@ -22,6 +22,7 @@ extern void device_tree_init(void);
22struct boot_param_header; 22struct boot_param_header;
23 23
24extern void __dt_setup_arch(void *bph); 24extern void __dt_setup_arch(void *bph);
25extern int __dt_register_buses(const char *bus0, const char *bus1);
25 26
26#define dt_setup_arch(sym) \ 27#define dt_setup_arch(sym) \
27({ \ 28({ \
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
index cd6e0afc6833..e293a8d89a6d 100644
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -47,79 +47,20 @@ extern void (*r4k_blast_icache)(void);
47 47
48#ifdef CONFIG_MIPS_MT 48#ifdef CONFIG_MIPS_MT
49 49
50/*
51 * Optionally force single-threaded execution during I-cache flushes.
52 */
53#define PROTECT_CACHE_FLUSHES 1
54
55#ifdef PROTECT_CACHE_FLUSHES
56
57extern int mt_protiflush;
58extern int mt_protdflush;
59extern void mt_cflush_lockdown(void);
60extern void mt_cflush_release(void);
61
62#define BEGIN_MT_IPROT \
63 unsigned long flags = 0; \
64 unsigned long mtflags = 0; \
65 if(mt_protiflush) { \
66 local_irq_save(flags); \
67 ehb(); \
68 mtflags = dvpe(); \
69 mt_cflush_lockdown(); \
70 }
71
72#define END_MT_IPROT \
73 if(mt_protiflush) { \
74 mt_cflush_release(); \
75 evpe(mtflags); \
76 local_irq_restore(flags); \
77 }
78
79#define BEGIN_MT_DPROT \
80 unsigned long flags = 0; \
81 unsigned long mtflags = 0; \
82 if(mt_protdflush) { \
83 local_irq_save(flags); \
84 ehb(); \
85 mtflags = dvpe(); \
86 mt_cflush_lockdown(); \
87 }
88
89#define END_MT_DPROT \
90 if(mt_protdflush) { \
91 mt_cflush_release(); \
92 evpe(mtflags); \
93 local_irq_restore(flags); \
94 }
95
96#else
97
98#define BEGIN_MT_IPROT
99#define BEGIN_MT_DPROT
100#define END_MT_IPROT
101#define END_MT_DPROT
102
103#endif /* PROTECT_CACHE_FLUSHES */
104
105#define __iflush_prologue \ 50#define __iflush_prologue \
106 unsigned long redundance; \ 51 unsigned long redundance; \
107 extern int mt_n_iflushes; \ 52 extern int mt_n_iflushes; \
108 BEGIN_MT_IPROT \
109 for (redundance = 0; redundance < mt_n_iflushes; redundance++) { 53 for (redundance = 0; redundance < mt_n_iflushes; redundance++) {
110 54
111#define __iflush_epilogue \ 55#define __iflush_epilogue \
112 END_MT_IPROT \
113 } 56 }
114 57
115#define __dflush_prologue \ 58#define __dflush_prologue \
116 unsigned long redundance; \ 59 unsigned long redundance; \
117 extern int mt_n_dflushes; \ 60 extern int mt_n_dflushes; \
118 BEGIN_MT_DPROT \
119 for (redundance = 0; redundance < mt_n_dflushes; redundance++) { 61 for (redundance = 0; redundance < mt_n_dflushes; redundance++) {
120 62
121#define __dflush_epilogue \ 63#define __dflush_epilogue \
122 END_MT_DPROT \
123 } 64 }
124 65
125#define __inv_dflush_prologue __dflush_prologue 66#define __inv_dflush_prologue __dflush_prologue
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h
index 78d201fb6c87..c6d06d383ef9 100644
--- a/arch/mips/include/asm/spinlock.h
+++ b/arch/mips/include/asm/spinlock.h
@@ -12,6 +12,7 @@
12#include <linux/compiler.h> 12#include <linux/compiler.h>
13 13
14#include <asm/barrier.h> 14#include <asm/barrier.h>
15#include <asm/compiler.h>
15#include <asm/war.h> 16#include <asm/war.h>
16 17
17/* 18/*
@@ -88,7 +89,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
88 " subu %[ticket], %[ticket], 1 \n" 89 " subu %[ticket], %[ticket], 1 \n"
89 " .previous \n" 90 " .previous \n"
90 " .set pop \n" 91 " .set pop \n"
91 : [ticket_ptr] "+m" (lock->lock), 92 : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock),
92 [serving_now_ptr] "+m" (lock->h.serving_now), 93 [serving_now_ptr] "+m" (lock->h.serving_now),
93 [ticket] "=&r" (tmp), 94 [ticket] "=&r" (tmp),
94 [my_ticket] "=&r" (my_ticket) 95 [my_ticket] "=&r" (my_ticket)
@@ -121,7 +122,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
121 " subu %[ticket], %[ticket], 1 \n" 122 " subu %[ticket], %[ticket], 1 \n"
122 " .previous \n" 123 " .previous \n"
123 " .set pop \n" 124 " .set pop \n"
124 : [ticket_ptr] "+m" (lock->lock), 125 : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock),
125 [serving_now_ptr] "+m" (lock->h.serving_now), 126 [serving_now_ptr] "+m" (lock->h.serving_now),
126 [ticket] "=&r" (tmp), 127 [ticket] "=&r" (tmp),
127 [my_ticket] "=&r" (my_ticket) 128 [my_ticket] "=&r" (my_ticket)
@@ -163,7 +164,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock)
163 " li %[ticket], 0 \n" 164 " li %[ticket], 0 \n"
164 " .previous \n" 165 " .previous \n"
165 " .set pop \n" 166 " .set pop \n"
166 : [ticket_ptr] "+m" (lock->lock), 167 : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock),
167 [ticket] "=&r" (tmp), 168 [ticket] "=&r" (tmp),
168 [my_ticket] "=&r" (tmp2), 169 [my_ticket] "=&r" (tmp2),
169 [now_serving] "=&r" (tmp3) 170 [now_serving] "=&r" (tmp3)
@@ -187,7 +188,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock)
187 " li %[ticket], 0 \n" 188 " li %[ticket], 0 \n"
188 " .previous \n" 189 " .previous \n"
189 " .set pop \n" 190 " .set pop \n"
190 : [ticket_ptr] "+m" (lock->lock), 191 : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock),
191 [ticket] "=&r" (tmp), 192 [ticket] "=&r" (tmp),
192 [my_ticket] "=&r" (tmp2), 193 [my_ticket] "=&r" (tmp2),
193 [now_serving] "=&r" (tmp3) 194 [now_serving] "=&r" (tmp3)
@@ -234,8 +235,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
234 " beqzl %1, 1b \n" 235 " beqzl %1, 1b \n"
235 " nop \n" 236 " nop \n"
236 " .set reorder \n" 237 " .set reorder \n"
237 : "=m" (rw->lock), "=&r" (tmp) 238 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
238 : "m" (rw->lock) 239 : GCC_OFF12_ASM() (rw->lock)
239 : "memory"); 240 : "memory");
240 } else { 241 } else {
241 do { 242 do {
@@ -244,8 +245,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
244 " bltz %1, 1b \n" 245 " bltz %1, 1b \n"
245 " addu %1, 1 \n" 246 " addu %1, 1 \n"
246 "2: sc %1, %0 \n" 247 "2: sc %1, %0 \n"
247 : "=m" (rw->lock), "=&r" (tmp) 248 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
248 : "m" (rw->lock) 249 : GCC_OFF12_ASM() (rw->lock)
249 : "memory"); 250 : "memory");
250 } while (unlikely(!tmp)); 251 } while (unlikely(!tmp));
251 } 252 }
@@ -268,8 +269,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
268 " sub %1, 1 \n" 269 " sub %1, 1 \n"
269 " sc %1, %0 \n" 270 " sc %1, %0 \n"
270 " beqzl %1, 1b \n" 271 " beqzl %1, 1b \n"
271 : "=m" (rw->lock), "=&r" (tmp) 272 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
272 : "m" (rw->lock) 273 : GCC_OFF12_ASM() (rw->lock)
273 : "memory"); 274 : "memory");
274 } else { 275 } else {
275 do { 276 do {
@@ -277,8 +278,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
277 "1: ll %1, %2 # arch_read_unlock \n" 278 "1: ll %1, %2 # arch_read_unlock \n"
278 " sub %1, 1 \n" 279 " sub %1, 1 \n"
279 " sc %1, %0 \n" 280 " sc %1, %0 \n"
280 : "=m" (rw->lock), "=&r" (tmp) 281 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
281 : "m" (rw->lock) 282 : GCC_OFF12_ASM() (rw->lock)
282 : "memory"); 283 : "memory");
283 } while (unlikely(!tmp)); 284 } while (unlikely(!tmp));
284 } 285 }
@@ -298,8 +299,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
298 " beqzl %1, 1b \n" 299 " beqzl %1, 1b \n"
299 " nop \n" 300 " nop \n"
300 " .set reorder \n" 301 " .set reorder \n"
301 : "=m" (rw->lock), "=&r" (tmp) 302 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
302 : "m" (rw->lock) 303 : GCC_OFF12_ASM() (rw->lock)
303 : "memory"); 304 : "memory");
304 } else { 305 } else {
305 do { 306 do {
@@ -308,8 +309,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
308 " bnez %1, 1b \n" 309 " bnez %1, 1b \n"
309 " lui %1, 0x8000 \n" 310 " lui %1, 0x8000 \n"
310 "2: sc %1, %0 \n" 311 "2: sc %1, %0 \n"
311 : "=m" (rw->lock), "=&r" (tmp) 312 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp)
312 : "m" (rw->lock) 313 : GCC_OFF12_ASM() (rw->lock)
313 : "memory"); 314 : "memory");
314 } while (unlikely(!tmp)); 315 } while (unlikely(!tmp));
315 } 316 }
@@ -348,8 +349,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
348 __WEAK_LLSC_MB 349 __WEAK_LLSC_MB
349 " li %2, 1 \n" 350 " li %2, 1 \n"
350 "2: \n" 351 "2: \n"
351 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 352 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret)
352 : "m" (rw->lock) 353 : GCC_OFF12_ASM() (rw->lock)
353 : "memory"); 354 : "memory");
354 } else { 355 } else {
355 __asm__ __volatile__( 356 __asm__ __volatile__(
@@ -365,8 +366,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
365 __WEAK_LLSC_MB 366 __WEAK_LLSC_MB
366 " li %2, 1 \n" 367 " li %2, 1 \n"
367 "2: \n" 368 "2: \n"
368 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 369 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret)
369 : "m" (rw->lock) 370 : GCC_OFF12_ASM() (rw->lock)
370 : "memory"); 371 : "memory");
371 } 372 }
372 373
@@ -392,8 +393,8 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
392 " li %2, 1 \n" 393 " li %2, 1 \n"
393 " .set reorder \n" 394 " .set reorder \n"
394 "2: \n" 395 "2: \n"
395 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 396 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret)
396 : "m" (rw->lock) 397 : GCC_OFF12_ASM() (rw->lock)
397 : "memory"); 398 : "memory");
398 } else { 399 } else {
399 do { 400 do {
@@ -405,8 +406,9 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
405 " sc %1, %0 \n" 406 " sc %1, %0 \n"
406 " li %2, 1 \n" 407 " li %2, 1 \n"
407 "2: \n" 408 "2: \n"
408 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 409 : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp),
409 : "m" (rw->lock) 410 "=&r" (ret)
411 : GCC_OFF12_ASM() (rw->lock)
410 : "memory"); 412 : "memory");
411 } while (unlikely(!tmp)); 413 } while (unlikely(!tmp));
412 414
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index 7de865805deb..99eea59604e9 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -116,6 +116,7 @@ static inline struct thread_info *current_thread_info(void)
116#define TIF_LOAD_WATCH 25 /* If set, load watch registers */ 116#define TIF_LOAD_WATCH 25 /* If set, load watch registers */
117#define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */ 117#define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */
118#define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */ 118#define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */
119#define TIF_HYBRID_FPREGS 28 /* 64b FP registers, odd singles in bits 63:32 of even doubles */
119#define TIF_USEDMSA 29 /* MSA has been used this quantum */ 120#define TIF_USEDMSA 29 /* MSA has been used this quantum */
120#define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */ 121#define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */
121#define TIF_SYSCALL_TRACE 31 /* syscall trace active */ 122#define TIF_SYSCALL_TRACE 31 /* syscall trace active */
@@ -135,6 +136,7 @@ static inline struct thread_info *current_thread_info(void)
135#define _TIF_FPUBOUND (1<<TIF_FPUBOUND) 136#define _TIF_FPUBOUND (1<<TIF_FPUBOUND)
136#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) 137#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH)
137#define _TIF_32BIT_FPREGS (1<<TIF_32BIT_FPREGS) 138#define _TIF_32BIT_FPREGS (1<<TIF_32BIT_FPREGS)
139#define _TIF_HYBRID_FPREGS (1<<TIF_HYBRID_FPREGS)
138#define _TIF_USEDMSA (1<<TIF_USEDMSA) 140#define _TIF_USEDMSA (1<<TIF_USEDMSA)
139#define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE) 141#define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE)
140#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) 142#define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index 8f3047d611ee..8ab2874225c4 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -46,19 +46,17 @@ extern unsigned int mips_hpt_frequency;
46 * so it lives here. 46 * so it lives here.
47 */ 47 */
48extern int (*perf_irq)(void); 48extern int (*perf_irq)(void);
49extern int __weak get_c0_perfcount_int(void);
49 50
50/* 51/*
51 * Initialize the calling CPU's compare interrupt as clockevent device 52 * Initialize the calling CPU's compare interrupt as clockevent device
52 */ 53 */
53extern unsigned int __weak get_c0_compare_int(void); 54extern unsigned int __weak get_c0_compare_int(void);
54extern int r4k_clockevent_init(void); 55extern int r4k_clockevent_init(void);
55extern int gic_clockevent_init(void);
56 56
57static inline int mips_clockevent_init(void) 57static inline int mips_clockevent_init(void)
58{ 58{
59#if defined(CONFIG_CEVT_GIC) 59#ifdef CONFIG_CEVT_R4K
60 return (gic_clockevent_init() | r4k_clockevent_init());
61#elif defined(CONFIG_CEVT_R4K)
62 return r4k_clockevent_init(); 60 return r4k_clockevent_init();
63#else 61#else
64 return -ENXIO; 62 return -ENXIO;
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h
index a845aafedee4..148d42a17f30 100644
--- a/arch/mips/include/asm/types.h
+++ b/arch/mips/include/asm/types.h
@@ -11,23 +11,7 @@
11#ifndef _ASM_TYPES_H 11#ifndef _ASM_TYPES_H
12#define _ASM_TYPES_H 12#define _ASM_TYPES_H
13 13
14# include <asm-generic/int-ll64.h> 14#include <asm-generic/int-ll64.h>
15#include <uapi/asm/types.h> 15#include <uapi/asm/types.h>
16 16
17/*
18 * These aren't exported outside the kernel to avoid name space clashes
19 */
20#ifndef __ASSEMBLY__
21
22/*
23 * Don't use phys_t. You've been warned.
24 */
25#ifdef CONFIG_64BIT_PHYS_ADDR
26typedef unsigned long long phys_t;
27#else
28typedef unsigned long phys_t;
29#endif
30
31#endif /* __ASSEMBLY__ */
32
33#endif /* _ASM_TYPES_H */ 17#endif /* _ASM_TYPES_H */
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index 22a5624e2fd2..bf8b32450ef6 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -1325,33 +1325,6 @@ strncpy_from_user(char *__to, const char __user *__from, long __len)
1325 return res; 1325 return res;
1326} 1326}
1327 1327
1328/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
1329static inline long __strlen_user(const char __user *s)
1330{
1331 long res;
1332
1333 if (segment_eq(get_fs(), get_ds())) {
1334 __asm__ __volatile__(
1335 "move\t$4, %1\n\t"
1336 __MODULE_JAL(__strlen_kernel_nocheck_asm)
1337 "move\t%0, $2"
1338 : "=r" (res)
1339 : "r" (s)
1340 : "$2", "$4", __UA_t0, "$31");
1341 } else {
1342 might_fault();
1343 __asm__ __volatile__(
1344 "move\t$4, %1\n\t"
1345 __MODULE_JAL(__strlen_user_nocheck_asm)
1346 "move\t%0, $2"
1347 : "=r" (res)
1348 : "r" (s)
1349 : "$2", "$4", __UA_t0, "$31");
1350 }
1351
1352 return res;
1353}
1354
1355/* 1328/*
1356 * strlen_user: - Get the size of a string in user space. 1329 * strlen_user: - Get the size of a string in user space.
1357 * @str: The string to measure. 1330 * @str: The string to measure.
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 708c5d414905..fc1cdd25fcda 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -136,9 +136,11 @@ Ip_u1s2(_lui);
136Ip_u2s3u1(_lw); 136Ip_u2s3u1(_lw);
137Ip_u3u1u2(_lwx); 137Ip_u3u1u2(_lwx);
138Ip_u1u2u3(_mfc0); 138Ip_u1u2u3(_mfc0);
139Ip_u1u2u3(_mfhc0);
139Ip_u1(_mfhi); 140Ip_u1(_mfhi);
140Ip_u1(_mflo); 141Ip_u1(_mflo);
141Ip_u1u2u3(_mtc0); 142Ip_u1u2u3(_mtc0);
143Ip_u1u2u3(_mthc0);
142Ip_u3u1u2(_mul); 144Ip_u3u1u2(_mul);
143Ip_u3u1u2(_or); 145Ip_u3u1u2(_or);
144Ip_u2u1u3(_ori); 146Ip_u2u1u3(_ori);
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h
index 4bfdb9d4c186..89c22433b1c6 100644
--- a/arch/mips/include/uapi/asm/inst.h
+++ b/arch/mips/include/uapi/asm/inst.h
@@ -108,9 +108,10 @@ enum rt_op {
108 */ 108 */
109enum cop_op { 109enum cop_op {
110 mfc_op = 0x00, dmfc_op = 0x01, 110 mfc_op = 0x00, dmfc_op = 0x01,
111 cfc_op = 0x02, mfhc_op = 0x03, 111 cfc_op = 0x02, mfhc0_op = 0x02,
112 mtc_op = 0x04, dmtc_op = 0x05, 112 mfhc_op = 0x03, mtc_op = 0x04,
113 ctc_op = 0x06, mthc_op = 0x07, 113 dmtc_op = 0x05, ctc_op = 0x06,
114 mthc0_op = 0x06, mthc_op = 0x07,
114 bc_op = 0x08, cop_op = 0x10, 115 bc_op = 0x08, cop_op = 0x10,
115 copm_op = 0x18 116 copm_op = 0x18
116}; 117};
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 76eafcb79c89..ef796f97b996 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -32,7 +32,7 @@ static void __init jz4740_detect_mem(void)
32{ 32{
33 void __iomem *jz_emc_base; 33 void __iomem *jz_emc_base;
34 u32 ctrl, bus, bank, rows, cols; 34 u32 ctrl, bus, bank, rows, cols;
35 phys_t size; 35 phys_addr_t size;
36 36
37 jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100); 37 jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100);
38 ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL); 38 ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL);
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 008a2fed0584..92987d1bbe5f 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -4,9 +4,10 @@
4 4
5extra-y := head.o vmlinux.lds 5extra-y := head.o vmlinux.lds
6 6
7obj-y += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \ 7obj-y += cpu-probe.o branch.o elf.o entry.o genex.o idle.o irq.o \
8 prom.o ptrace.o reset.o setup.o signal.o syscall.o \ 8 process.o prom.o ptrace.o reset.o setup.o signal.o \
9 time.o topology.o traps.o unaligned.o watch.o vdso.o 9 syscall.o time.o topology.o traps.o unaligned.o watch.o \
10 vdso.o
10 11
11ifdef CONFIG_FUNCTION_TRACER 12ifdef CONFIG_FUNCTION_TRACER
12CFLAGS_REMOVE_ftrace.o = -pg 13CFLAGS_REMOVE_ftrace.o = -pg
@@ -18,12 +19,10 @@ endif
18obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o 19obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
19obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o 20obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
20obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o 21obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
21obj-$(CONFIG_CEVT_GIC) += cevt-gic.o
22obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o 22obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
23obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o 23obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
24obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o 24obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
25obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o 25obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
26obj-$(CONFIG_CSRC_GIC) += csrc-gic.o
27obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o 26obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
28obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o 27obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
29obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o 28obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
@@ -68,7 +67,6 @@ obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o
68obj-$(CONFIG_MIPS_MSC) += irq-msc01.o 67obj-$(CONFIG_MIPS_MSC) += irq-msc01.o
69obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o 68obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o
70obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o 69obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o
71obj-$(CONFIG_IRQ_GIC) += irq-gic.o
72 70
73obj-$(CONFIG_KPROBES) += kprobes.o 71obj-$(CONFIG_KPROBES) += kprobes.o
74obj-$(CONFIG_32BIT) += scall32-o32.o 72obj-$(CONFIG_32BIT) += scall32-o32.o
diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c
deleted file mode 100644
index 6093716980b9..000000000000
--- a/arch/mips/kernel/cevt-gic.c
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2013 Imagination Technologies Ltd.
7 */
8#include <linux/clockchips.h>
9#include <linux/interrupt.h>
10#include <linux/percpu.h>
11#include <linux/smp.h>
12#include <linux/irq.h>
13
14#include <asm/time.h>
15#include <asm/gic.h>
16#include <asm/mips-boards/maltaint.h>
17
18DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
19int gic_timer_irq_installed;
20
21
22static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
23{
24 u64 cnt;
25 int res;
26
27 cnt = gic_read_count();
28 cnt += (u64)delta;
29 gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
30 res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
31 return res;
32}
33
34void gic_set_clock_mode(enum clock_event_mode mode,
35 struct clock_event_device *evt)
36{
37 /* Nothing to do ... */
38}
39
40irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
41{
42 struct clock_event_device *cd;
43 int cpu = smp_processor_id();
44
45 gic_write_compare(gic_read_compare());
46 cd = &per_cpu(gic_clockevent_device, cpu);
47 cd->event_handler(cd);
48 return IRQ_HANDLED;
49}
50
51struct irqaction gic_compare_irqaction = {
52 .handler = gic_compare_interrupt,
53 .flags = IRQF_PERCPU | IRQF_TIMER,
54 .name = "timer",
55};
56
57
58void gic_event_handler(struct clock_event_device *dev)
59{
60}
61
62int gic_clockevent_init(void)
63{
64 unsigned int cpu = smp_processor_id();
65 struct clock_event_device *cd;
66 unsigned int irq;
67
68 if (!cpu_has_counter || !gic_frequency)
69 return -ENXIO;
70
71 irq = MIPS_GIC_IRQ_BASE;
72
73 cd = &per_cpu(gic_clockevent_device, cpu);
74
75 cd->name = "MIPS GIC";
76 cd->features = CLOCK_EVT_FEAT_ONESHOT |
77 CLOCK_EVT_FEAT_C3STOP;
78
79 clockevent_set_clock(cd, gic_frequency);
80
81 /* Calculate the min / max delta */
82 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
83 cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
84
85 cd->rating = 300;
86 cd->irq = irq;
87 cd->cpumask = cpumask_of(cpu);
88 cd->set_next_event = gic_next_event;
89 cd->set_mode = gic_set_clock_mode;
90 cd->event_handler = gic_event_handler;
91
92 clockevents_register_device(cd);
93
94 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002);
95 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK);
96
97 if (gic_timer_irq_installed)
98 return 0;
99
100 gic_timer_irq_installed = 1;
101
102 setup_irq(irq, &gic_compare_irqaction);
103 irq_set_handler(irq, handle_percpu_irq);
104 return 0;
105}
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index bc127e22fdab..6acaad0480af 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -11,10 +11,10 @@
11#include <linux/percpu.h> 11#include <linux/percpu.h>
12#include <linux/smp.h> 12#include <linux/smp.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/irqchip/mips-gic.h>
14 15
15#include <asm/time.h> 16#include <asm/time.h>
16#include <asm/cevt-r4k.h> 17#include <asm/cevt-r4k.h>
17#include <asm/gic.h>
18 18
19static int mips_next_event(unsigned long delta, 19static int mips_next_event(unsigned long delta,
20 struct clock_event_device *evt) 20 struct clock_event_device *evt)
@@ -85,8 +85,8 @@ void mips_event_handler(struct clock_event_device *dev)
85 */ 85 */
86static int c0_compare_int_pending(void) 86static int c0_compare_int_pending(void)
87{ 87{
88#ifdef CONFIG_IRQ_GIC 88#ifdef CONFIG_MIPS_GIC
89 if (cpu_has_veic) 89 if (gic_present)
90 return gic_get_timer_pending(); 90 return gic_get_timer_pending();
91#endif 91#endif
92 return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP); 92 return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP);
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index dc49cf30c2db..5342674842f5 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -69,6 +69,63 @@ static int __init htw_disable(char *s)
69 69
70__setup("nohtw", htw_disable); 70__setup("nohtw", htw_disable);
71 71
72static int mips_ftlb_disabled;
73static int mips_has_ftlb_configured;
74
75static void set_ftlb_enable(struct cpuinfo_mips *c, int enable);
76
77static int __init ftlb_disable(char *s)
78{
79 unsigned int config4, mmuextdef;
80
81 /*
82 * If the core hasn't done any FTLB configuration, there is nothing
83 * for us to do here.
84 */
85 if (!mips_has_ftlb_configured)
86 return 1;
87
88 /* Disable it in the boot cpu */
89 set_ftlb_enable(&cpu_data[0], 0);
90
91 back_to_back_c0_hazard();
92
93 config4 = read_c0_config4();
94
95 /* Check that FTLB has been disabled */
96 mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
97 /* MMUSIZEEXT == VTLB ON, FTLB OFF */
98 if (mmuextdef == MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT) {
99 /* This should never happen */
100 pr_warn("FTLB could not be disabled!\n");
101 return 1;
102 }
103
104 mips_ftlb_disabled = 1;
105 mips_has_ftlb_configured = 0;
106
107 /*
108 * noftlb is mainly used for debug purposes so print
109 * an informative message instead of using pr_debug()
110 */
111 pr_info("FTLB has been disabled\n");
112
113 /*
114 * Some of these bits are duplicated in the decode_config4.
115 * MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT is the only possible case
116 * once FTLB has been disabled so undo what decode_config4 did.
117 */
118 cpu_data[0].tlbsize -= cpu_data[0].tlbsizeftlbways *
119 cpu_data[0].tlbsizeftlbsets;
120 cpu_data[0].tlbsizeftlbsets = 0;
121 cpu_data[0].tlbsizeftlbways = 0;
122
123 return 1;
124}
125
126__setup("noftlb", ftlb_disable);
127
128
72static inline void check_errata(void) 129static inline void check_errata(void)
73{ 130{
74 struct cpuinfo_mips *c = &current_cpu_data; 131 struct cpuinfo_mips *c = &current_cpu_data;
@@ -140,7 +197,7 @@ static inline unsigned long cpu_get_fpu_id(void)
140 */ 197 */
141static inline int __cpu_has_fpu(void) 198static inline int __cpu_has_fpu(void)
142{ 199{
143 return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE); 200 return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
144} 201}
145 202
146static inline unsigned long cpu_get_msa_id(void) 203static inline unsigned long cpu_get_msa_id(void)
@@ -399,6 +456,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
399 ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; 456 ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
400 /* fall through */ 457 /* fall through */
401 case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: 458 case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
459 if (mips_ftlb_disabled)
460 break;
402 newcf4 = (config4 & ~ftlb_page) | 461 newcf4 = (config4 & ~ftlb_page) |
403 (page_size_ftlb(mmuextdef) << 462 (page_size_ftlb(mmuextdef) <<
404 MIPS_CONF4_FTLBPAGESIZE_SHIFT); 463 MIPS_CONF4_FTLBPAGESIZE_SHIFT);
@@ -418,6 +477,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)
418 c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> 477 c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
419 MIPS_CONF4_FTLBWAYS_SHIFT) + 2; 478 MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
420 c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; 479 c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
480 mips_has_ftlb_configured = 1;
421 break; 481 break;
422 } 482 }
423 } 483 }
@@ -432,7 +492,7 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
432 unsigned int config5; 492 unsigned int config5;
433 493
434 config5 = read_c0_config5(); 494 config5 = read_c0_config5();
435 config5 &= ~MIPS_CONF5_UFR; 495 config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
436 write_c0_config5(config5); 496 write_c0_config5(config5);
437 497
438 if (config5 & MIPS_CONF5_EVA) 498 if (config5 & MIPS_CONF5_EVA)
@@ -453,8 +513,8 @@ static void decode_configs(struct cpuinfo_mips *c)
453 513
454 c->scache.flags = MIPS_CACHE_NOT_PRESENT; 514 c->scache.flags = MIPS_CACHE_NOT_PRESENT;
455 515
456 /* Enable FTLB if present */ 516 /* Enable FTLB if present and not disabled */
457 set_ftlb_enable(c, 1); 517 set_ftlb_enable(c, !mips_ftlb_disabled);
458 518
459 ok = decode_config0(c); /* Read Config registers. */ 519 ok = decode_config0(c); /* Read Config registers. */
460 BUG_ON(!ok); /* Arch spec violation! */ 520 BUG_ON(!ok); /* Arch spec violation! */
@@ -1058,6 +1118,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
1058 break; 1118 break;
1059 } 1119 }
1060 case PRID_IMP_BMIPS5000: 1120 case PRID_IMP_BMIPS5000:
1121 case PRID_IMP_BMIPS5200:
1061 c->cputype = CPU_BMIPS5000; 1122 c->cputype = CPU_BMIPS5000;
1062 __cpu_name[cpu] = "Broadcom BMIPS5000"; 1123 __cpu_name[cpu] = "Broadcom BMIPS5000";
1063 set_elf_platform(cpu, "bmips5000"); 1124 set_elf_platform(cpu, "bmips5000");
@@ -1288,6 +1349,8 @@ void cpu_probe(void)
1288 MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { 1349 MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) {
1289 if (c->fpu_id & MIPS_FPIR_3D) 1350 if (c->fpu_id & MIPS_FPIR_3D)
1290 c->ases |= MIPS_ASE_MIPS3D; 1351 c->ases |= MIPS_ASE_MIPS3D;
1352 if (c->fpu_id & MIPS_FPIR_FREP)
1353 c->options |= MIPS_CPU_FRE;
1291 } 1354 }
1292 } 1355 }
1293 1356
diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c
index f291cf99b03a..6fe7790e5868 100644
--- a/arch/mips/kernel/crash_dump.c
+++ b/arch/mips/kernel/crash_dump.c
@@ -38,7 +38,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
38 kunmap_atomic(vaddr); 38 kunmap_atomic(vaddr);
39 } else { 39 } else {
40 if (!kdump_buf_page) { 40 if (!kdump_buf_page) {
41 pr_warning("Kdump: Kdump buffer page not allocated\n"); 41 pr_warn("Kdump: Kdump buffer page not allocated\n");
42 42
43 return -EFAULT; 43 return -EFAULT;
44 } 44 }
@@ -57,7 +57,7 @@ static int __init kdump_buf_page_init(void)
57 57
58 kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL); 58 kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
59 if (!kdump_buf_page) { 59 if (!kdump_buf_page) {
60 pr_warning("Kdump: Failed to allocate kdump buffer page\n"); 60 pr_warn("Kdump: Failed to allocate kdump buffer page\n");
61 ret = -ENOMEM; 61 ret = -ENOMEM;
62 } 62 }
63 63
diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c
deleted file mode 100644
index e02620901117..000000000000
--- a/arch/mips/kernel/csrc-gic.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */
8#include <linux/init.h>
9#include <linux/time.h>
10
11#include <asm/gic.h>
12
13static cycle_t gic_hpt_read(struct clocksource *cs)
14{
15 return gic_read_count();
16}
17
18static struct clocksource gic_clocksource = {
19 .name = "GIC",
20 .read = gic_hpt_read,
21 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
22};
23
24void __init gic_clocksource_init(unsigned int frequency)
25{
26 unsigned int config, bits;
27
28 /* Calculate the clocksource mask. */
29 GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config);
30 bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
31 (GIC_SH_CONFIG_COUNTBITS_SHF - 2));
32
33 /* Set clocksource mask. */
34 gic_clocksource.mask = CLOCKSOURCE_MASK(bits);
35
36 /* Calculate a somewhat reasonable rating value. */
37 gic_clocksource.rating = 200 + frequency / 10000000;
38
39 clocksource_register_hz(&gic_clocksource, frequency);
40}
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
new file mode 100644
index 000000000000..c92b15df6893
--- /dev/null
+++ b/arch/mips/kernel/elf.c
@@ -0,0 +1,191 @@
1/*
2 * Copyright (C) 2014 Imagination Technologies
3 * Author: Paul Burton <paul.burton@imgtec.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#include <linux/elf.h>
12#include <linux/sched.h>
13
14enum {
15 FP_ERROR = -1,
16 FP_DOUBLE_64A = -2,
17};
18
19int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
20 bool is_interp, struct arch_elf_state *state)
21{
22 struct elfhdr *ehdr = _ehdr;
23 struct elf_phdr *phdr = _phdr;
24 struct mips_elf_abiflags_v0 abiflags;
25 int ret;
26
27 if (config_enabled(CONFIG_64BIT) &&
28 (ehdr->e_ident[EI_CLASS] != ELFCLASS32))
29 return 0;
30 if (phdr->p_type != PT_MIPS_ABIFLAGS)
31 return 0;
32 if (phdr->p_filesz < sizeof(abiflags))
33 return -EINVAL;
34
35 ret = kernel_read(elf, phdr->p_offset, (char *)&abiflags,
36 sizeof(abiflags));
37 if (ret < 0)
38 return ret;
39 if (ret != sizeof(abiflags))
40 return -EIO;
41
42 /* Record the required FP ABIs for use by mips_check_elf */
43 if (is_interp)
44 state->interp_fp_abi = abiflags.fp_abi;
45 else
46 state->fp_abi = abiflags.fp_abi;
47
48 return 0;
49}
50
51static inline unsigned get_fp_abi(struct elfhdr *ehdr, int in_abi)
52{
53 /* If the ABI requirement is provided, simply return that */
54 if (in_abi != -1)
55 return in_abi;
56
57 /* If the EF_MIPS_FP64 flag was set, return MIPS_ABI_FP_64 */
58 if (ehdr->e_flags & EF_MIPS_FP64)
59 return MIPS_ABI_FP_64;
60
61 /* Default to MIPS_ABI_FP_DOUBLE */
62 return MIPS_ABI_FP_DOUBLE;
63}
64
65int arch_check_elf(void *_ehdr, bool has_interpreter,
66 struct arch_elf_state *state)
67{
68 struct elfhdr *ehdr = _ehdr;
69 unsigned fp_abi, interp_fp_abi, abi0, abi1;
70
71 /* Ignore non-O32 binaries */
72 if (config_enabled(CONFIG_64BIT) &&
73 (ehdr->e_ident[EI_CLASS] != ELFCLASS32))
74 return 0;
75
76 fp_abi = get_fp_abi(ehdr, state->fp_abi);
77
78 if (has_interpreter) {
79 interp_fp_abi = get_fp_abi(ehdr, state->interp_fp_abi);
80
81 abi0 = min(fp_abi, interp_fp_abi);
82 abi1 = max(fp_abi, interp_fp_abi);
83 } else {
84 abi0 = abi1 = fp_abi;
85 }
86
87 state->overall_abi = FP_ERROR;
88
89 if (abi0 == abi1) {
90 state->overall_abi = abi0;
91 } else if (abi0 == MIPS_ABI_FP_ANY) {
92 state->overall_abi = abi1;
93 } else if (abi0 == MIPS_ABI_FP_DOUBLE) {
94 switch (abi1) {
95 case MIPS_ABI_FP_XX:
96 state->overall_abi = MIPS_ABI_FP_DOUBLE;
97 break;
98
99 case MIPS_ABI_FP_64A:
100 state->overall_abi = FP_DOUBLE_64A;
101 break;
102 }
103 } else if (abi0 == MIPS_ABI_FP_SINGLE ||
104 abi0 == MIPS_ABI_FP_SOFT) {
105 /* Cannot link with other ABIs */
106 } else if (abi0 == MIPS_ABI_FP_OLD_64) {
107 switch (abi1) {
108 case MIPS_ABI_FP_XX:
109 case MIPS_ABI_FP_64:
110 case MIPS_ABI_FP_64A:
111 state->overall_abi = MIPS_ABI_FP_64;
112 break;
113 }
114 } else if (abi0 == MIPS_ABI_FP_XX ||
115 abi0 == MIPS_ABI_FP_64 ||
116 abi0 == MIPS_ABI_FP_64A) {
117 state->overall_abi = MIPS_ABI_FP_64;
118 }
119
120 switch (state->overall_abi) {
121 case MIPS_ABI_FP_64:
122 case MIPS_ABI_FP_64A:
123 case FP_DOUBLE_64A:
124 if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
125 return -ELIBBAD;
126 break;
127
128 case FP_ERROR:
129 return -ELIBBAD;
130 }
131
132 return 0;
133}
134
135void mips_set_personality_fp(struct arch_elf_state *state)
136{
137 if (config_enabled(CONFIG_FP32XX_HYBRID_FPRS)) {
138 /*
139 * Use hybrid FPRs for all code which can correctly execute
140 * with that mode.
141 */
142 switch (state->overall_abi) {
143 case MIPS_ABI_FP_DOUBLE:
144 case MIPS_ABI_FP_SINGLE:
145 case MIPS_ABI_FP_SOFT:
146 case MIPS_ABI_FP_XX:
147 case MIPS_ABI_FP_ANY:
148 /* FR=1, FRE=1 */
149 clear_thread_flag(TIF_32BIT_FPREGS);
150 set_thread_flag(TIF_HYBRID_FPREGS);
151 return;
152 }
153 }
154
155 switch (state->overall_abi) {
156 case MIPS_ABI_FP_DOUBLE:
157 case MIPS_ABI_FP_SINGLE:
158 case MIPS_ABI_FP_SOFT:
159 /* FR=0 */
160 set_thread_flag(TIF_32BIT_FPREGS);
161 clear_thread_flag(TIF_HYBRID_FPREGS);
162 break;
163
164 case FP_DOUBLE_64A:
165 /* FR=1, FRE=1 */
166 clear_thread_flag(TIF_32BIT_FPREGS);
167 set_thread_flag(TIF_HYBRID_FPREGS);
168 break;
169
170 case MIPS_ABI_FP_64:
171 case MIPS_ABI_FP_64A:
172 /* FR=1, FRE=0 */
173 clear_thread_flag(TIF_32BIT_FPREGS);
174 clear_thread_flag(TIF_HYBRID_FPREGS);
175 break;
176
177 case MIPS_ABI_FP_XX:
178 case MIPS_ABI_FP_ANY:
179 if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
180 set_thread_flag(TIF_32BIT_FPREGS);
181 else
182 clear_thread_flag(TIF_32BIT_FPREGS);
183
184 clear_thread_flag(TIF_HYBRID_FPREGS);
185 break;
186
187 default:
188 case FP_ERROR:
189 BUG();
190 }
191}
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 50b364897dda..a74ec3ae557c 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/ioport.h> 13#include <linux/ioport.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/irqdomain.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/spinlock.h> 17#include <linux/spinlock.h>
17#include <linux/syscore_ops.h> 18#include <linux/syscore_ops.h>
@@ -308,6 +309,19 @@ static struct resource pic2_io_resource = {
308 .flags = IORESOURCE_BUSY 309 .flags = IORESOURCE_BUSY
309}; 310};
310 311
312static int i8259A_irq_domain_map(struct irq_domain *d, unsigned int virq,
313 irq_hw_number_t hw)
314{
315 irq_set_chip_and_handler(virq, &i8259A_chip, handle_level_irq);
316 irq_set_probe(virq);
317 return 0;
318}
319
320static struct irq_domain_ops i8259A_ops = {
321 .map = i8259A_irq_domain_map,
322 .xlate = irq_domain_xlate_onecell,
323};
324
311/* 325/*
312 * On systems with i8259-style interrupt controllers we assume for 326 * On systems with i8259-style interrupt controllers we assume for
313 * driver compatibility reasons interrupts 0 - 15 to be the i8259 327 * driver compatibility reasons interrupts 0 - 15 to be the i8259
@@ -315,17 +329,17 @@ static struct resource pic2_io_resource = {
315 */ 329 */
316void __init init_i8259_irqs(void) 330void __init init_i8259_irqs(void)
317{ 331{
318 int i; 332 struct irq_domain *domain;
319 333
320 insert_resource(&ioport_resource, &pic1_io_resource); 334 insert_resource(&ioport_resource, &pic1_io_resource);
321 insert_resource(&ioport_resource, &pic2_io_resource); 335 insert_resource(&ioport_resource, &pic2_io_resource);
322 336
323 init_8259A(0); 337 init_8259A(0);
324 338
325 for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { 339 domain = irq_domain_add_legacy(NULL, 16, I8259A_IRQ_BASE, 0,
326 irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq); 340 &i8259A_ops, NULL);
327 irq_set_probe(i); 341 if (!domain)
328 } 342 panic("Failed to add i8259 IRQ domain");
329 343
330 setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); 344 setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);
331} 345}
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
deleted file mode 100644
index 9e9d8b9a5b97..000000000000
--- a/arch/mips/kernel/irq-gic.c
+++ /dev/null
@@ -1,402 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
8 */
9#include <linux/bitmap.h>
10#include <linux/init.h>
11#include <linux/smp.h>
12#include <linux/irq.h>
13#include <linux/clocksource.h>
14
15#include <asm/io.h>
16#include <asm/gic.h>
17#include <asm/setup.h>
18#include <asm/traps.h>
19#include <linux/hardirq.h>
20#include <asm-generic/bitops/find.h>
21
22unsigned int gic_frequency;
23unsigned int gic_present;
24unsigned long _gic_base;
25unsigned int gic_irq_base;
26unsigned int gic_irq_flags[GIC_NUM_INTRS];
27
28/* The index into this array is the vector # of the interrupt. */
29struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS];
30
31struct gic_pcpu_mask {
32 DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
33};
34
35struct gic_pending_regs {
36 DECLARE_BITMAP(pending, GIC_NUM_INTRS);
37};
38
39struct gic_intrmask_regs {
40 DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
41};
42
43static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
44static struct gic_pending_regs pending_regs[NR_CPUS];
45static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
46
47#if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC)
48cycle_t gic_read_count(void)
49{
50 unsigned int hi, hi2, lo;
51
52 do {
53 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
54 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
55 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
56 } while (hi2 != hi);
57
58 return (((cycle_t) hi) << 32) + lo;
59}
60
61void gic_write_compare(cycle_t cnt)
62{
63 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
64 (int)(cnt >> 32));
65 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
66 (int)(cnt & 0xffffffff));
67}
68
69void gic_write_cpu_compare(cycle_t cnt, int cpu)
70{
71 unsigned long flags;
72
73 local_irq_save(flags);
74
75 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
76 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
77 (int)(cnt >> 32));
78 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
79 (int)(cnt & 0xffffffff));
80
81 local_irq_restore(flags);
82}
83
84cycle_t gic_read_compare(void)
85{
86 unsigned int hi, lo;
87
88 GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), hi);
89 GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), lo);
90
91 return (((cycle_t) hi) << 32) + lo;
92}
93#endif
94
95unsigned int gic_get_timer_pending(void)
96{
97 unsigned int vpe_pending;
98
99 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
100 GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_PEND), vpe_pending);
101 return (vpe_pending & GIC_VPE_PEND_TIMER_MSK);
102}
103
104void gic_bind_eic_interrupt(int irq, int set)
105{
106 /* Convert irq vector # to hw int # */
107 irq -= GIC_PIN_TO_VEC_OFFSET;
108
109 /* Set irq to use shadow set */
110 GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), set);
111}
112
113void gic_send_ipi(unsigned int intr)
114{
115 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
116}
117
118static void gic_eic_irq_dispatch(void)
119{
120 unsigned int cause = read_c0_cause();
121 int irq;
122
123 irq = (cause & ST0_IM) >> STATUSB_IP2;
124 if (irq == 0)
125 irq = -1;
126
127 if (irq >= 0)
128 do_IRQ(gic_irq_base + irq);
129 else
130 spurious_interrupt();
131}
132
133static void __init vpe_local_setup(unsigned int numvpes)
134{
135 unsigned long timer_intr = GIC_INT_TMR;
136 unsigned long perf_intr = GIC_INT_PERFCTR;
137 unsigned int vpe_ctl;
138 int i;
139
140 if (cpu_has_veic) {
141 /*
142 * GIC timer interrupt -> CPU HW Int X (vector X+2) ->
143 * map to pin X+2-1 (since GIC adds 1)
144 */
145 timer_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
146 /*
147 * GIC perfcnt interrupt -> CPU HW Int X (vector X+2) ->
148 * map to pin X+2-1 (since GIC adds 1)
149 */
150 perf_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
151 }
152
153 /*
154 * Setup the default performance counter timer interrupts
155 * for all VPEs
156 */
157 for (i = 0; i < numvpes; i++) {
158 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
159
160 /* Are Interrupts locally routable? */
161 GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl);
162 if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK)
163 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
164 GIC_MAP_TO_PIN_MSK | timer_intr);
165 if (cpu_has_veic) {
166 set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET,
167 gic_eic_irq_dispatch);
168 gic_shared_intr_map[timer_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK;
169 }
170
171 if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK)
172 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
173 GIC_MAP_TO_PIN_MSK | perf_intr);
174 if (cpu_has_veic) {
175 set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, gic_eic_irq_dispatch);
176 gic_shared_intr_map[perf_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK;
177 }
178 }
179}
180
181unsigned int gic_compare_int(void)
182{
183 unsigned int pending;
184
185 GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending);
186 if (pending & GIC_VPE_PEND_CMP_MSK)
187 return 1;
188 else
189 return 0;
190}
191
192void gic_get_int_mask(unsigned long *dst, const unsigned long *src)
193{
194 unsigned int i;
195 unsigned long *pending, *intrmask, *pcpu_mask;
196 unsigned long *pending_abs, *intrmask_abs;
197
198 /* Get per-cpu bitmaps */
199 pending = pending_regs[smp_processor_id()].pending;
200 intrmask = intrmask_regs[smp_processor_id()].intrmask;
201 pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask;
202
203 pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
204 GIC_SH_PEND_31_0_OFS);
205 intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED,
206 GIC_SH_MASK_31_0_OFS);
207
208 for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) {
209 GICREAD(*pending_abs, pending[i]);
210 GICREAD(*intrmask_abs, intrmask[i]);
211 pending_abs++;
212 intrmask_abs++;
213 }
214
215 bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS);
216 bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS);
217 bitmap_and(dst, src, pending, GIC_NUM_INTRS);
218}
219
220unsigned int gic_get_int(void)
221{
222 DECLARE_BITMAP(interrupts, GIC_NUM_INTRS);
223
224 bitmap_fill(interrupts, GIC_NUM_INTRS);
225 gic_get_int_mask(interrupts, interrupts);
226
227 return find_first_bit(interrupts, GIC_NUM_INTRS);
228}
229
230static void gic_mask_irq(struct irq_data *d)
231{
232 GIC_CLR_INTR_MASK(d->irq - gic_irq_base);
233}
234
235static void gic_unmask_irq(struct irq_data *d)
236{
237 GIC_SET_INTR_MASK(d->irq - gic_irq_base);
238}
239
240#ifdef CONFIG_SMP
241static DEFINE_SPINLOCK(gic_lock);
242
243static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
244 bool force)
245{
246 unsigned int irq = (d->irq - gic_irq_base);
247 cpumask_t tmp = CPU_MASK_NONE;
248 unsigned long flags;
249 int i;
250
251 cpumask_and(&tmp, cpumask, cpu_online_mask);
252 if (cpus_empty(tmp))
253 return -1;
254
255 /* Assumption : cpumask refers to a single CPU */
256 spin_lock_irqsave(&gic_lock, flags);
257
258 /* Re-route this IRQ */
259 GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp));
260
261 /* Update the pcpu_masks */
262 for (i = 0; i < NR_CPUS; i++)
263 clear_bit(irq, pcpu_masks[i].pcpu_mask);
264 set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
265
266 cpumask_copy(d->affinity, cpumask);
267 spin_unlock_irqrestore(&gic_lock, flags);
268
269 return IRQ_SET_MASK_OK_NOCOPY;
270}
271#endif
272
273static struct irq_chip gic_irq_controller = {
274 .name = "MIPS GIC",
275 .irq_ack = gic_irq_ack,
276 .irq_mask = gic_mask_irq,
277 .irq_mask_ack = gic_mask_irq,
278 .irq_unmask = gic_unmask_irq,
279 .irq_eoi = gic_finish_irq,
280#ifdef CONFIG_SMP
281 .irq_set_affinity = gic_set_affinity,
282#endif
283};
284
285static void __init gic_setup_intr(unsigned int intr, unsigned int cpu,
286 unsigned int pin, unsigned int polarity, unsigned int trigtype,
287 unsigned int flags)
288{
289 struct gic_shared_intr_map *map_ptr;
290
291 /* Setup Intr to Pin mapping */
292 if (pin & GIC_MAP_TO_NMI_MSK) {
293 int i;
294
295 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
296 /* FIXME: hack to route NMI to all cpu's */
297 for (i = 0; i < NR_CPUS; i += 32) {
298 GICWRITE(GIC_REG_ADDR(SHARED,
299 GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)),
300 0xffffffff);
301 }
302 } else {
303 GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)),
304 GIC_MAP_TO_PIN_MSK | pin);
305 /* Setup Intr to CPU mapping */
306 GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
307 if (cpu_has_veic) {
308 set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET,
309 gic_eic_irq_dispatch);
310 map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET];
311 if (map_ptr->num_shared_intr >= GIC_MAX_SHARED_INTR)
312 BUG();
313 map_ptr->intr_list[map_ptr->num_shared_intr++] = intr;
314 }
315 }
316
317 /* Setup Intr Polarity */
318 GIC_SET_POLARITY(intr, polarity);
319
320 /* Setup Intr Trigger Type */
321 GIC_SET_TRIGGER(intr, trigtype);
322
323 /* Init Intr Masks */
324 GIC_CLR_INTR_MASK(intr);
325
326 /* Initialise per-cpu Interrupt software masks */
327 set_bit(intr, pcpu_masks[cpu].pcpu_mask);
328
329 if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0))
330 GIC_SET_INTR_MASK(intr);
331 if (trigtype == GIC_TRIG_EDGE)
332 gic_irq_flags[intr] |= GIC_TRIG_EDGE;
333}
334
335static void __init gic_basic_init(int numintrs, int numvpes,
336 struct gic_intr_map *intrmap, int mapsize)
337{
338 unsigned int i, cpu;
339 unsigned int pin_offset = 0;
340
341 board_bind_eic_interrupt = &gic_bind_eic_interrupt;
342
343 /* Setup defaults */
344 for (i = 0; i < numintrs; i++) {
345 GIC_SET_POLARITY(i, GIC_POL_POS);
346 GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
347 GIC_CLR_INTR_MASK(i);
348 if (i < GIC_NUM_INTRS) {
349 gic_irq_flags[i] = 0;
350 gic_shared_intr_map[i].num_shared_intr = 0;
351 gic_shared_intr_map[i].local_intr_mask = 0;
352 }
353 }
354
355 /*
356 * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract
357 * one because the GIC will add one (since 0=no intr).
358 */
359 if (cpu_has_veic)
360 pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
361
362 /* Setup specifics */
363 for (i = 0; i < mapsize; i++) {
364 cpu = intrmap[i].cpunum;
365 if (cpu == GIC_UNUSED)
366 continue;
367 gic_setup_intr(i,
368 intrmap[i].cpunum,
369 intrmap[i].pin + pin_offset,
370 intrmap[i].polarity,
371 intrmap[i].trigtype,
372 intrmap[i].flags);
373 }
374
375 vpe_local_setup(numvpes);
376}
377
378void __init gic_init(unsigned long gic_base_addr,
379 unsigned long gic_addrspace_size,
380 struct gic_intr_map *intr_map, unsigned int intr_map_size,
381 unsigned int irqbase)
382{
383 unsigned int gicconfig;
384 int numvpes, numintrs;
385
386 _gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
387 gic_addrspace_size);
388 gic_irq_base = irqbase;
389
390 GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
391 numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
392 GIC_SH_CONFIG_NUMINTRS_SHF;
393 numintrs = ((numintrs + 1) * 8);
394
395 numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
396 GIC_SH_CONFIG_NUMVPES_SHF;
397 numvpes = numvpes + 1;
398
399 gic_basic_init(numintrs, numvpes, intr_map, intr_map_size);
400
401 gic_platform_init(numintrs, &gic_irq_controller);
402}
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index e498f2b3646a..590c2c980fd3 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -36,6 +36,7 @@
36#include <asm/irq_cpu.h> 36#include <asm/irq_cpu.h>
37#include <asm/mipsregs.h> 37#include <asm/mipsregs.h>
38#include <asm/mipsmtregs.h> 38#include <asm/mipsmtregs.h>
39#include <asm/setup.h>
39 40
40static inline void unmask_mips_irq(struct irq_data *d) 41static inline void unmask_mips_irq(struct irq_data *d)
41{ 42{
@@ -94,28 +95,24 @@ static struct irq_chip mips_mt_cpu_irq_controller = {
94 .irq_eoi = unmask_mips_irq, 95 .irq_eoi = unmask_mips_irq,
95}; 96};
96 97
97void __init mips_cpu_irq_init(void) 98asmlinkage void __weak plat_irq_dispatch(void)
98{ 99{
99 int irq_base = MIPS_CPU_IRQ_BASE; 100 unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM;
100 int i; 101 int irq;
101 102
102 /* Mask interrupts. */ 103 if (!pending) {
103 clear_c0_status(ST0_IM); 104 spurious_interrupt();
104 clear_c0_cause(CAUSEF_IP); 105 return;
105 106 }
106 /* Software interrupts are used for MT/CMT IPI */
107 for (i = irq_base; i < irq_base + 2; i++)
108 irq_set_chip_and_handler(i, cpu_has_mipsmt ?
109 &mips_mt_cpu_irq_controller :
110 &mips_cpu_irq_controller,
111 handle_percpu_irq);
112 107
113 for (i = irq_base + 2; i < irq_base + 8; i++) 108 pending >>= CAUSEB_IP;
114 irq_set_chip_and_handler(i, &mips_cpu_irq_controller, 109 while (pending) {
115 handle_percpu_irq); 110 irq = fls(pending) - 1;
111 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
112 pending &= ~BIT(irq);
113 }
116} 114}
117 115
118#ifdef CONFIG_IRQ_DOMAIN
119static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, 116static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
120 irq_hw_number_t hw) 117 irq_hw_number_t hw)
121{ 118{
@@ -128,6 +125,9 @@ static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq,
128 chip = &mips_cpu_irq_controller; 125 chip = &mips_cpu_irq_controller;
129 } 126 }
130 127
128 if (cpu_has_vint)
129 set_vi_handler(hw, plat_irq_dispatch);
130
131 irq_set_chip_and_handler(irq, chip, handle_percpu_irq); 131 irq_set_chip_and_handler(irq, chip, handle_percpu_irq);
132 132
133 return 0; 133 return 0;
@@ -138,8 +138,7 @@ static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = {
138 .xlate = irq_domain_xlate_onecell, 138 .xlate = irq_domain_xlate_onecell,
139}; 139};
140 140
141int __init mips_cpu_intc_init(struct device_node *of_node, 141static void __init __mips_cpu_irq_init(struct device_node *of_node)
142 struct device_node *parent)
143{ 142{
144 struct irq_domain *domain; 143 struct irq_domain *domain;
145 144
@@ -151,7 +150,16 @@ int __init mips_cpu_intc_init(struct device_node *of_node,
151 &mips_cpu_intc_irq_domain_ops, NULL); 150 &mips_cpu_intc_irq_domain_ops, NULL);
152 if (!domain) 151 if (!domain)
153 panic("Failed to add irqdomain for MIPS CPU"); 152 panic("Failed to add irqdomain for MIPS CPU");
153}
154 154
155void __init mips_cpu_irq_init(void)
156{
157 __mips_cpu_irq_init(NULL);
158}
159
160int __init mips_cpu_irq_of_init(struct device_node *of_node,
161 struct device_node *parent)
162{
163 __mips_cpu_irq_init(of_node);
155 return 0; 164 return 0;
156} 165}
157#endif /* CONFIG_IRQ_DOMAIN */
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c
index f76f7a08412d..85bbe9b96759 100644
--- a/arch/mips/kernel/mips-cm.c
+++ b/arch/mips/kernel/mips-cm.c
@@ -16,7 +16,7 @@
16void __iomem *mips_cm_base; 16void __iomem *mips_cm_base;
17void __iomem *mips_cm_l2sync_base; 17void __iomem *mips_cm_l2sync_base;
18 18
19phys_t __mips_cm_phys_base(void) 19phys_addr_t __mips_cm_phys_base(void)
20{ 20{
21 u32 config3 = read_c0_config3(); 21 u32 config3 = read_c0_config3();
22 u32 cmgcr; 22 u32 cmgcr;
@@ -30,10 +30,10 @@ phys_t __mips_cm_phys_base(void)
30 return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32); 30 return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32);
31} 31}
32 32
33phys_t mips_cm_phys_base(void) 33phys_addr_t mips_cm_phys_base(void)
34 __attribute__((weak, alias("__mips_cm_phys_base"))); 34 __attribute__((weak, alias("__mips_cm_phys_base")));
35 35
36phys_t __mips_cm_l2sync_phys_base(void) 36phys_addr_t __mips_cm_l2sync_phys_base(void)
37{ 37{
38 u32 base_reg; 38 u32 base_reg;
39 39
@@ -49,13 +49,13 @@ phys_t __mips_cm_l2sync_phys_base(void)
49 return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; 49 return mips_cm_phys_base() + MIPS_CM_GCR_SIZE;
50} 50}
51 51
52phys_t mips_cm_l2sync_phys_base(void) 52phys_addr_t mips_cm_l2sync_phys_base(void)
53 __attribute__((weak, alias("__mips_cm_l2sync_phys_base"))); 53 __attribute__((weak, alias("__mips_cm_l2sync_phys_base")));
54 54
55static void mips_cm_probe_l2sync(void) 55static void mips_cm_probe_l2sync(void)
56{ 56{
57 unsigned major_rev; 57 unsigned major_rev;
58 phys_t addr; 58 phys_addr_t addr;
59 59
60 /* L2-only sync was introduced with CM major revision 6 */ 60 /* L2-only sync was introduced with CM major revision 6 */
61 major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> 61 major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >>
@@ -78,7 +78,7 @@ static void mips_cm_probe_l2sync(void)
78 78
79int mips_cm_probe(void) 79int mips_cm_probe(void)
80{ 80{
81 phys_t addr; 81 phys_addr_t addr;
82 u32 base_reg; 82 u32 base_reg;
83 83
84 addr = mips_cm_phys_base(); 84 addr = mips_cm_phys_base();
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c
index ba473608a347..11964501c4b0 100644
--- a/arch/mips/kernel/mips-cpc.c
+++ b/arch/mips/kernel/mips-cpc.c
@@ -21,7 +21,7 @@ static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock);
21 21
22static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); 22static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);
23 23
24phys_t __weak mips_cpc_phys_base(void) 24phys_addr_t __weak mips_cpc_phys_base(void)
25{ 25{
26 u32 cpc_base; 26 u32 cpc_base;
27 27
@@ -44,7 +44,7 @@ phys_t __weak mips_cpc_phys_base(void)
44 44
45int mips_cpc_probe(void) 45int mips_cpc_probe(void)
46{ 46{
47 phys_t addr; 47 phys_addr_t addr;
48 unsigned cpu; 48 unsigned cpu;
49 49
50 for_each_possible_cpu(cpu) 50 for_each_possible_cpu(cpu)
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 2607c3a4ff7e..17eaf0cf760c 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -24,9 +24,7 @@ extern long __strncpy_from_user_nocheck_asm(char *__to,
24 const char *__from, long __len); 24 const char *__from, long __len);
25extern long __strncpy_from_user_asm(char *__to, const char *__from, 25extern long __strncpy_from_user_asm(char *__to, const char *__from,
26 long __len); 26 long __len);
27extern long __strlen_kernel_nocheck_asm(const char *s);
28extern long __strlen_kernel_asm(const char *s); 27extern long __strlen_kernel_asm(const char *s);
29extern long __strlen_user_nocheck_asm(const char *s);
30extern long __strlen_user_asm(const char *s); 28extern long __strlen_user_asm(const char *s);
31extern long __strnlen_kernel_nocheck_asm(const char *s); 29extern long __strnlen_kernel_nocheck_asm(const char *s);
32extern long __strnlen_kernel_asm(const char *s); 30extern long __strnlen_kernel_asm(const char *s);
@@ -62,9 +60,7 @@ EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm);
62EXPORT_SYMBOL(__strncpy_from_kernel_asm); 60EXPORT_SYMBOL(__strncpy_from_kernel_asm);
63EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); 61EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm);
64EXPORT_SYMBOL(__strncpy_from_user_asm); 62EXPORT_SYMBOL(__strncpy_from_user_asm);
65EXPORT_SYMBOL(__strlen_kernel_nocheck_asm);
66EXPORT_SYMBOL(__strlen_kernel_asm); 63EXPORT_SYMBOL(__strlen_kernel_asm);
67EXPORT_SYMBOL(__strlen_user_nocheck_asm);
68EXPORT_SYMBOL(__strlen_user_asm); 64EXPORT_SYMBOL(__strlen_user_asm);
69EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm); 65EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm);
70EXPORT_SYMBOL(__strnlen_kernel_asm); 66EXPORT_SYMBOL(__strnlen_kernel_asm);
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index a8f9cdc6f8b0..9466184d0039 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -561,8 +561,8 @@ static int mipspmu_get_irq(void)
561 IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD, 561 IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD,
562 "mips_perf_pmu", NULL); 562 "mips_perf_pmu", NULL);
563 if (err) { 563 if (err) {
564 pr_warning("Unable to request IRQ%d for MIPS " 564 pr_warn("Unable to request IRQ%d for MIPS performance counters!\n",
565 "performance counters!\n", mipspmu.irq); 565 mipspmu.irq);
566 } 566 }
567 } else if (cp0_perfcount_irq < 0) { 567 } else if (cp0_perfcount_irq < 0) {
568 /* 568 /*
@@ -572,8 +572,7 @@ static int mipspmu_get_irq(void)
572 perf_irq = mipsxx_pmu_handle_shared_irq; 572 perf_irq = mipsxx_pmu_handle_shared_irq;
573 err = 0; 573 err = 0;
574 } else { 574 } else {
575 pr_warning("The platform hasn't properly defined its " 575 pr_warn("The platform hasn't properly defined its interrupt controller\n");
576 "interrupt controller.\n");
577 err = -ENOENT; 576 err = -ENOENT;
578 } 577 }
579 578
@@ -1614,22 +1613,13 @@ init_hw_perf_events(void)
1614 counters = counters_total_to_per_cpu(counters); 1613 counters = counters_total_to_per_cpu(counters);
1615#endif 1614#endif
1616 1615
1617#ifdef MSC01E_INT_BASE 1616 if (get_c0_perfcount_int)
1618 if (cpu_has_veic) { 1617 irq = get_c0_perfcount_int();
1619 /* 1618 else if ((cp0_perfcount_irq >= 0) &&
1620 * Using platform specific interrupt controller defines. 1619 (cp0_compare_irq != cp0_perfcount_irq))
1621 */ 1620 irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
1622 irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; 1621 else
1623 } else { 1622 irq = -1;
1624#endif
1625 if ((cp0_perfcount_irq >= 0) &&
1626 (cp0_compare_irq != cp0_perfcount_irq))
1627 irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
1628 else
1629 irq = -1;
1630#ifdef MSC01E_INT_BASE
1631 }
1632#endif
1633 1623
1634 mipspmu.map_raw_event = mipsxx_pmu_map_raw_event; 1624 mipspmu.map_raw_event = mipsxx_pmu_map_raw_event;
1635 1625
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 636b0745d7c7..eb76434828e8 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -42,6 +42,7 @@
42#include <asm/isadep.h> 42#include <asm/isadep.h>
43#include <asm/inst.h> 43#include <asm/inst.h>
44#include <asm/stacktrace.h> 44#include <asm/stacktrace.h>
45#include <asm/irq_regs.h>
45 46
46#ifdef CONFIG_HOTPLUG_CPU 47#ifdef CONFIG_HOTPLUG_CPU
47void arch_cpu_idle_dead(void) 48void arch_cpu_idle_dead(void)
@@ -187,21 +188,21 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
187 */ 188 */
188 if (mm_insn_16bit(ip->halfword[0])) { 189 if (mm_insn_16bit(ip->halfword[0])) {
189 mmi.word = (ip->halfword[0] << 16); 190 mmi.word = (ip->halfword[0] << 16);
190 return ((mmi.mm16_r5_format.opcode == mm_swsp16_op && 191 return (mmi.mm16_r5_format.opcode == mm_swsp16_op &&
191 mmi.mm16_r5_format.rt == 31) || 192 mmi.mm16_r5_format.rt == 31) ||
192 (mmi.mm16_m_format.opcode == mm_pool16c_op && 193 (mmi.mm16_m_format.opcode == mm_pool16c_op &&
193 mmi.mm16_m_format.func == mm_swm16_op)); 194 mmi.mm16_m_format.func == mm_swm16_op);
194 } 195 }
195 else { 196 else {
196 mmi.halfword[0] = ip->halfword[1]; 197 mmi.halfword[0] = ip->halfword[1];
197 mmi.halfword[1] = ip->halfword[0]; 198 mmi.halfword[1] = ip->halfword[0];
198 return ((mmi.mm_m_format.opcode == mm_pool32b_op && 199 return (mmi.mm_m_format.opcode == mm_pool32b_op &&
199 mmi.mm_m_format.rd > 9 && 200 mmi.mm_m_format.rd > 9 &&
200 mmi.mm_m_format.base == 29 && 201 mmi.mm_m_format.base == 29 &&
201 mmi.mm_m_format.func == mm_swm32_func) || 202 mmi.mm_m_format.func == mm_swm32_func) ||
202 (mmi.i_format.opcode == mm_sw32_op && 203 (mmi.i_format.opcode == mm_sw32_op &&
203 mmi.i_format.rs == 29 && 204 mmi.i_format.rs == 29 &&
204 mmi.i_format.rt == 31)); 205 mmi.i_format.rt == 31);
205 } 206 }
206#else 207#else
207 /* sw / sd $ra, offset($sp) */ 208 /* sw / sd $ra, offset($sp) */
@@ -233,7 +234,7 @@ static inline int is_jump_ins(union mips_instruction *ip)
233 if (ip->r_format.opcode != mm_pool32a_op || 234 if (ip->r_format.opcode != mm_pool32a_op ||
234 ip->r_format.func != mm_pool32axf_op) 235 ip->r_format.func != mm_pool32axf_op)
235 return 0; 236 return 0;
236 return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); 237 return ((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op;
237#else 238#else
238 if (ip->j_format.opcode == j_op) 239 if (ip->j_format.opcode == j_op)
239 return 1; 240 return 1;
@@ -260,13 +261,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
260 union mips_instruction mmi; 261 union mips_instruction mmi;
261 262
262 mmi.word = (ip->halfword[0] << 16); 263 mmi.word = (ip->halfword[0] << 16);
263 return ((mmi.mm16_r3_format.opcode == mm_pool16d_op && 264 return (mmi.mm16_r3_format.opcode == mm_pool16d_op &&
264 mmi.mm16_r3_format.simmediate && mm_addiusp_func) || 265 mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
265 (mmi.mm16_r5_format.opcode == mm_pool16d_op && 266 (mmi.mm16_r5_format.opcode == mm_pool16d_op &&
266 mmi.mm16_r5_format.rt == 29)); 267 mmi.mm16_r5_format.rt == 29);
267 } 268 }
268 return (ip->mm_i_format.opcode == mm_addiu32_op && 269 return ip->mm_i_format.opcode == mm_addiu32_op &&
269 ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29); 270 ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29;
270#else 271#else
271 /* addiu/daddiu sp,sp,-imm */ 272 /* addiu/daddiu sp,sp,-imm */
272 if (ip->i_format.rs != 29 || ip->i_format.rt != 29) 273 if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
@@ -532,3 +533,20 @@ unsigned long arch_align_stack(unsigned long sp)
532 533
533 return sp & ALMASK; 534 return sp & ALMASK;
534} 535}
536
537static void arch_dump_stack(void *info)
538{
539 struct pt_regs *regs;
540
541 regs = get_irq_regs();
542
543 if (regs)
544 show_regs(regs);
545
546 dump_stack();
547}
548
549void arch_trigger_all_cpu_backtrace(bool include_self)
550{
551 smp_call_function(arch_dump_stack, NULL, 1);
552}
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 5d39bb85bf35..452d4350ce42 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -16,6 +16,7 @@
16#include <linux/debugfs.h> 16#include <linux/debugfs.h>
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/of_fdt.h> 18#include <linux/of_fdt.h>
19#include <linux/of_platform.h>
19 20
20#include <asm/page.h> 21#include <asm/page.h>
21#include <asm/prom.h> 22#include <asm/prom.h>
@@ -54,4 +55,21 @@ void __init __dt_setup_arch(void *bph)
54 55
55 mips_set_machine_name(of_flat_dt_get_machine_name()); 56 mips_set_machine_name(of_flat_dt_get_machine_name());
56} 57}
58
59int __init __dt_register_buses(const char *bus0, const char *bus1)
60{
61 static struct of_device_id of_ids[3];
62
63 if (!of_have_populated_dt())
64 panic("device tree not present");
65
66 strlcpy(of_ids[0].compatible, bus0, sizeof(of_ids[0].compatible));
67 strlcpy(of_ids[1].compatible, bus1, sizeof(of_ids[1].compatible));
68
69 if (of_platform_populate(NULL, of_ids, NULL, NULL))
70 panic("failed to populate DT");
71
72 return 0;
73}
74
57#endif 75#endif
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f3b635f86c39..a8c20afeb813 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -82,14 +82,14 @@ static struct resource data_resource = { .name = "Kernel data", };
82 82
83static void *detect_magic __initdata = detect_memory_region; 83static void *detect_magic __initdata = detect_memory_region;
84 84
85void __init add_memory_region(phys_t start, phys_t size, long type) 85void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
86{ 86{
87 int x = boot_mem_map.nr_map; 87 int x = boot_mem_map.nr_map;
88 int i; 88 int i;
89 89
90 /* Sanity check */ 90 /* Sanity check */
91 if (start + size < start) { 91 if (start + size < start) {
92 pr_warning("Trying to add an invalid memory region, skipped\n"); 92 pr_warn("Trying to add an invalid memory region, skipped\n");
93 return; 93 return;
94 } 94 }
95 95
@@ -127,10 +127,10 @@ void __init add_memory_region(phys_t start, phys_t size, long type)
127 boot_mem_map.nr_map++; 127 boot_mem_map.nr_map++;
128} 128}
129 129
130void __init detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max) 130void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max)
131{ 131{
132 void *dm = &detect_magic; 132 void *dm = &detect_magic;
133 phys_t size; 133 phys_addr_t size;
134 134
135 for (size = sz_min; size < sz_max; size <<= 1) { 135 for (size = sz_min; size < sz_max; size <<= 1) {
136 if (!memcmp(dm, dm + size, sizeof(detect_magic))) 136 if (!memcmp(dm, dm + size, sizeof(detect_magic)))
@@ -545,9 +545,9 @@ static int __init early_parse_elfcorehdr(char *p)
545early_param("elfcorehdr", early_parse_elfcorehdr); 545early_param("elfcorehdr", early_parse_elfcorehdr);
546#endif 546#endif
547 547
548static void __init arch_mem_addpart(phys_t mem, phys_t end, int type) 548static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type)
549{ 549{
550 phys_t size; 550 phys_addr_t size;
551 int i; 551 int i;
552 552
553 size = end - mem; 553 size = end - mem;
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 16f1e4f2bf3c..545bf11bd2ed 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -530,7 +530,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
530 struct mips_abi *abi = current->thread.abi; 530 struct mips_abi *abi = current->thread.abi;
531#ifdef CONFIG_CPU_MICROMIPS 531#ifdef CONFIG_CPU_MICROMIPS
532 void *vdso; 532 void *vdso;
533 unsigned int tmp = (unsigned int)current->mm->context.vdso; 533 unsigned long tmp = (unsigned long)current->mm->context.vdso;
534 534
535 set_isa16_mode(tmp); 535 set_isa16_mode(tmp);
536 vdso = (void *)tmp; 536 vdso = (void *)tmp;
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 06bb5ed6d80a..b8bd9340c9c7 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -35,6 +35,7 @@
35#include <asm/bmips.h> 35#include <asm/bmips.h>
36#include <asm/traps.h> 36#include <asm/traps.h>
37#include <asm/barrier.h> 37#include <asm/barrier.h>
38#include <asm/cpu-features.h>
38 39
39static int __maybe_unused max_cpus = 1; 40static int __maybe_unused max_cpus = 1;
40 41
@@ -42,6 +43,12 @@ static int __maybe_unused max_cpus = 1;
42int bmips_smp_enabled = 1; 43int bmips_smp_enabled = 1;
43int bmips_cpu_offset; 44int bmips_cpu_offset;
44cpumask_t bmips_booted_mask; 45cpumask_t bmips_booted_mask;
46unsigned long bmips_tp1_irqs = IE_IRQ1;
47
48#define RESET_FROM_KSEG0 0x80080800
49#define RESET_FROM_KSEG1 0xa0080800
50
51static void bmips_set_reset_vec(int cpu, u32 val);
45 52
46#ifdef CONFIG_SMP 53#ifdef CONFIG_SMP
47 54
@@ -194,6 +201,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
194 pr_info("SMP: Booting CPU%d...\n", cpu); 201 pr_info("SMP: Booting CPU%d...\n", cpu);
195 202
196 if (cpumask_test_cpu(cpu, &bmips_booted_mask)) { 203 if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
204 /* kseg1 might not exist if this CPU enabled XKS01 */
205 bmips_set_reset_vec(cpu, RESET_FROM_KSEG0);
206
197 switch (current_cpu_type()) { 207 switch (current_cpu_type()) {
198 case CPU_BMIPS4350: 208 case CPU_BMIPS4350:
199 case CPU_BMIPS4380: 209 case CPU_BMIPS4380:
@@ -203,8 +213,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
203 bmips5000_send_ipi_single(cpu, 0); 213 bmips5000_send_ipi_single(cpu, 0);
204 break; 214 break;
205 } 215 }
206 } 216 } else {
207 else { 217 bmips_set_reset_vec(cpu, RESET_FROM_KSEG1);
218
208 switch (current_cpu_type()) { 219 switch (current_cpu_type()) {
209 case CPU_BMIPS4350: 220 case CPU_BMIPS4350:
210 case CPU_BMIPS4380: 221 case CPU_BMIPS4380:
@@ -213,17 +224,7 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
213 set_c0_brcm_cmt_ctrl(0x01); 224 set_c0_brcm_cmt_ctrl(0x01);
214 break; 225 break;
215 case CPU_BMIPS5000: 226 case CPU_BMIPS5000:
216 if (cpu & 0x01) 227 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
217 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
218 else {
219 /*
220 * core N thread 0 was already booted; just
221 * pulse the NMI line
222 */
223 bmips_write_zscm_reg(0x210, 0xc0000000);
224 udelay(10);
225 bmips_write_zscm_reg(0x210, 0x00);
226 }
227 break; 228 break;
228 } 229 }
229 cpumask_set_cpu(cpu, &bmips_booted_mask); 230 cpumask_set_cpu(cpu, &bmips_booted_mask);
@@ -235,31 +236,12 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
235 */ 236 */
236static void bmips_init_secondary(void) 237static void bmips_init_secondary(void)
237{ 238{
238 /* move NMI vector to kseg0, in case XKS01 is enabled */
239
240 void __iomem *cbr;
241 unsigned long old_vec;
242 unsigned long relo_vector;
243 int boot_cpu;
244
245 switch (current_cpu_type()) { 239 switch (current_cpu_type()) {
246 case CPU_BMIPS4350: 240 case CPU_BMIPS4350:
247 case CPU_BMIPS4380: 241 case CPU_BMIPS4380:
248 cbr = BMIPS_GET_CBR();
249
250 boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
251 relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
252 BMIPS_RELO_VECTOR_CONTROL_1;
253
254 old_vec = __raw_readl(cbr + relo_vector);
255 __raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
256
257 clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); 242 clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
258 break; 243 break;
259 case CPU_BMIPS5000: 244 case CPU_BMIPS5000:
260 write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
261 (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
262
263 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); 245 write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
264 break; 246 break;
265 } 247 }
@@ -276,7 +258,7 @@ static void bmips_smp_finish(void)
276 write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); 258 write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
277 259
278 irq_enable_hazard(); 260 irq_enable_hazard();
279 set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); 261 set_c0_status(IE_SW0 | IE_SW1 | bmips_tp1_irqs | IE_IRQ5 | ST0_IE);
280 irq_enable_hazard(); 262 irq_enable_hazard();
281} 263}
282 264
@@ -381,6 +363,7 @@ static int bmips_cpu_disable(void)
381 363
382 set_cpu_online(cpu, false); 364 set_cpu_online(cpu, false);
383 cpu_clear(cpu, cpu_callin_map); 365 cpu_clear(cpu, cpu_callin_map);
366 clear_c0_status(IE_IRQ5);
384 367
385 local_flush_tlb_all(); 368 local_flush_tlb_all();
386 local_flush_icache_range(0, ~0); 369 local_flush_icache_range(0, ~0);
@@ -405,7 +388,8 @@ void __ref play_dead(void)
405 * IRQ handlers; this clears ST0_IE and returns immediately. 388 * IRQ handlers; this clears ST0_IE and returns immediately.
406 */ 389 */
407 clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1); 390 clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1);
408 change_c0_status(IE_IRQ5 | IE_IRQ1 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, 391 change_c0_status(
392 IE_IRQ5 | bmips_tp1_irqs | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV,
409 IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV); 393 IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV);
410 irq_disable_hazard(); 394 irq_disable_hazard();
411 395
@@ -473,10 +457,61 @@ static inline void bmips_nmi_handler_setup(void)
473 &bmips_smp_int_vec_end); 457 &bmips_smp_int_vec_end);
474} 458}
475 459
460struct reset_vec_info {
461 int cpu;
462 u32 val;
463};
464
465static void bmips_set_reset_vec_remote(void *vinfo)
466{
467 struct reset_vec_info *info = vinfo;
468 int shift = info->cpu & 0x01 ? 16 : 0;
469 u32 mask = ~(0xffff << shift), val = info->val >> 16;
470
471 preempt_disable();
472 if (smp_processor_id() > 0) {
473 smp_call_function_single(0, &bmips_set_reset_vec_remote,
474 info, 1);
475 } else {
476 if (info->cpu & 0x02) {
477 /* BMIPS5200 "should" use mask/shift, but it's buggy */
478 bmips_write_zscm_reg(0xa0, (val << 16) | val);
479 bmips_read_zscm_reg(0xa0);
480 } else {
481 write_c0_brcm_bootvec((read_c0_brcm_bootvec() & mask) |
482 (val << shift));
483 }
484 }
485 preempt_enable();
486}
487
488static void bmips_set_reset_vec(int cpu, u32 val)
489{
490 struct reset_vec_info info;
491
492 if (current_cpu_type() == CPU_BMIPS5000) {
493 /* this needs to run from CPU0 (which is always online) */
494 info.cpu = cpu;
495 info.val = val;
496 bmips_set_reset_vec_remote(&info);
497 } else {
498 void __iomem *cbr = BMIPS_GET_CBR();
499
500 if (cpu == 0)
501 __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
502 else {
503 if (current_cpu_type() != CPU_BMIPS4380)
504 return;
505 __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
506 }
507 }
508 __sync();
509 back_to_back_c0_hazard();
510}
511
476void bmips_ebase_setup(void) 512void bmips_ebase_setup(void)
477{ 513{
478 unsigned long new_ebase = ebase; 514 unsigned long new_ebase = ebase;
479 void __iomem __maybe_unused *cbr;
480 515
481 BUG_ON(ebase != CKSEG0); 516 BUG_ON(ebase != CKSEG0);
482 517
@@ -496,15 +531,14 @@ void bmips_ebase_setup(void)
496 &bmips_smp_int_vec, 0x80); 531 &bmips_smp_int_vec, 0x80);
497 __sync(); 532 __sync();
498 return; 533 return;
534 case CPU_BMIPS3300:
499 case CPU_BMIPS4380: 535 case CPU_BMIPS4380:
500 /* 536 /*
501 * 0x8000_0000: reset/NMI (initially in kseg1) 537 * 0x8000_0000: reset/NMI (initially in kseg1)
502 * 0x8000_0400: normal vectors 538 * 0x8000_0400: normal vectors
503 */ 539 */
504 new_ebase = 0x80000400; 540 new_ebase = 0x80000400;
505 cbr = BMIPS_GET_CBR(); 541 bmips_set_reset_vec(0, RESET_FROM_KSEG0);
506 __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
507 __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
508 break; 542 break;
509 case CPU_BMIPS5000: 543 case CPU_BMIPS5000:
510 /* 544 /*
@@ -512,10 +546,8 @@ void bmips_ebase_setup(void)
512 * 0x8000_1000: normal vectors 546 * 0x8000_1000: normal vectors
513 */ 547 */
514 new_ebase = 0x80001000; 548 new_ebase = 0x80001000;
515 write_c0_brcm_bootvec(0xa0088008); 549 bmips_set_reset_vec(0, RESET_FROM_KSEG0);
516 write_c0_ebase(new_ebase); 550 write_c0_ebase(new_ebase);
517 if (max_cpus > 2)
518 bmips_write_zscm_reg(0xa0, 0xa008a008);
519 break; 551 break;
520 default: 552 default:
521 return; 553 return;
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c
index fc8a51553426..1e0a93c5a3e7 100644
--- a/arch/mips/kernel/smp-cmp.c
+++ b/arch/mips/kernel/smp-cmp.c
@@ -24,6 +24,7 @@
24#include <linux/cpumask.h> 24#include <linux/cpumask.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/compiler.h> 26#include <linux/compiler.h>
27#include <linux/irqchip/mips-gic.h>
27 28
28#include <linux/atomic.h> 29#include <linux/atomic.h>
29#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
@@ -37,7 +38,6 @@
37#include <asm/mipsmtregs.h> 38#include <asm/mipsmtregs.h>
38#include <asm/mips_mt.h> 39#include <asm/mips_mt.h>
39#include <asm/amon.h> 40#include <asm/amon.h>
40#include <asm/gic.h>
41 41
42static void cmp_init_secondary(void) 42static void cmp_init_secondary(void)
43{ 43{
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index e6e16a1d4add..bed7590e475f 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -9,13 +9,13 @@
9 */ 9 */
10 10
11#include <linux/io.h> 11#include <linux/io.h>
12#include <linux/irqchip/mips-gic.h>
12#include <linux/sched.h> 13#include <linux/sched.h>
13#include <linux/slab.h> 14#include <linux/slab.h>
14#include <linux/smp.h> 15#include <linux/smp.h>
15#include <linux/types.h> 16#include <linux/types.h>
16 17
17#include <asm/bcache.h> 18#include <asm/bcache.h>
18#include <asm/gic.h>
19#include <asm/mips-cm.h> 19#include <asm/mips-cm.h>
20#include <asm/mips-cpc.h> 20#include <asm/mips-cpc.h>
21#include <asm/mips_mt.h> 21#include <asm/mips_mt.h>
@@ -273,8 +273,8 @@ static void cps_init_secondary(void)
273 if (cpu_has_mipsmt) 273 if (cpu_has_mipsmt)
274 dmt(); 274 dmt();
275 275
276 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | 276 change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 |
277 STATUSF_IP6 | STATUSF_IP7); 277 STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7);
278} 278}
279 279
280static void cps_smp_finish(void) 280static void cps_smp_finish(void)
diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c
index 3b21a96d1ccb..5f0ab5bcd01e 100644
--- a/arch/mips/kernel/smp-gic.c
+++ b/arch/mips/kernel/smp-gic.c
@@ -12,9 +12,9 @@
12 * option) any later version. 12 * option) any later version.
13 */ 13 */
14 14
15#include <linux/irqchip/mips-gic.h>
15#include <linux/printk.h> 16#include <linux/printk.h>
16 17
17#include <asm/gic.h>
18#include <asm/mips-cpc.h> 18#include <asm/mips-cpc.h>
19#include <asm/smp-ops.h> 19#include <asm/smp-ops.h>
20 20
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 21f23add04f4..ad86951b73bd 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -21,6 +21,7 @@
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/cpumask.h> 22#include <linux/cpumask.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/irqchip/mips-gic.h>
24#include <linux/compiler.h> 25#include <linux/compiler.h>
25#include <linux/smp.h> 26#include <linux/smp.h>
26 27
@@ -34,7 +35,6 @@
34#include <asm/mipsregs.h> 35#include <asm/mipsregs.h>
35#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
36#include <asm/mips_mt.h> 37#include <asm/mips_mt.h>
37#include <asm/gic.h>
38 38
39static void __init smvp_copy_vpe_config(void) 39static void __init smvp_copy_vpe_config(void)
40{ 40{
@@ -119,7 +119,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action)
119 unsigned long flags; 119 unsigned long flags;
120 int vpflags; 120 int vpflags;
121 121
122#ifdef CONFIG_IRQ_GIC 122#ifdef CONFIG_MIPS_GIC
123 if (gic_present) { 123 if (gic_present) {
124 gic_send_ipi_single(cpu, action); 124 gic_send_ipi_single(cpu, action);
125 return; 125 return;
@@ -158,7 +158,7 @@ static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
158 158
159static void vsmp_init_secondary(void) 159static void vsmp_init_secondary(void)
160{ 160{
161#ifdef CONFIG_IRQ_GIC 161#ifdef CONFIG_MIPS_GIC
162 /* This is Malta specific: IPI,performance and timer interrupts */ 162 /* This is Malta specific: IPI,performance and timer interrupts */
163 if (gic_present) 163 if (gic_present)
164 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | 164 change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 4a4f9dda5658..604b558809c4 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -117,6 +117,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
117 "2: sc %[tmp], (%[addr]) \n" 117 "2: sc %[tmp], (%[addr]) \n"
118 " beqzl %[tmp], 1b \n" 118 " beqzl %[tmp], 1b \n"
119 "3: \n" 119 "3: \n"
120 " .insn \n"
120 " .section .fixup,\"ax\" \n" 121 " .section .fixup,\"ax\" \n"
121 "4: li %[err], %[efault] \n" 122 "4: li %[err], %[efault] \n"
122 " j 3b \n" 123 " j 3b \n"
@@ -142,6 +143,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
142 "2: sc %[tmp], (%[addr]) \n" 143 "2: sc %[tmp], (%[addr]) \n"
143 " bnez %[tmp], 4f \n" 144 " bnez %[tmp], 4f \n"
144 "3: \n" 145 "3: \n"
146 " .insn \n"
145 " .subsection 2 \n" 147 " .subsection 2 \n"
146 "4: b 1b \n" 148 "4: b 1b \n"
147 " .previous \n" 149 " .previous \n"
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 22b19c275044..ad3d2031c327 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -724,6 +724,50 @@ int process_fpemu_return(int sig, void __user *fault_addr)
724 } 724 }
725} 725}
726 726
727static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
728 unsigned long old_epc, unsigned long old_ra)
729{
730 union mips_instruction inst = { .word = opcode };
731 void __user *fault_addr = NULL;
732 int sig;
733
734 /* If it's obviously not an FP instruction, skip it */
735 switch (inst.i_format.opcode) {
736 case cop1_op:
737 case cop1x_op:
738 case lwc1_op:
739 case ldc1_op:
740 case swc1_op:
741 case sdc1_op:
742 break;
743
744 default:
745 return -1;
746 }
747
748 /*
749 * do_ri skipped over the instruction via compute_return_epc, undo
750 * that for the FPU emulator.
751 */
752 regs->cp0_epc = old_epc;
753 regs->regs[31] = old_ra;
754
755 /* Save the FP context to struct thread_struct */
756 lose_fpu(1);
757
758 /* Run the emulator */
759 sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
760 &fault_addr);
761
762 /* If something went wrong, signal */
763 process_fpemu_return(sig, fault_addr);
764
765 /* Restore the hardware register state */
766 own_fpu(1);
767
768 return 0;
769}
770
727/* 771/*
728 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX 772 * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
729 */ 773 */
@@ -1016,6 +1060,9 @@ asmlinkage void do_ri(struct pt_regs *regs)
1016 1060
1017 if (status < 0) 1061 if (status < 0)
1018 status = simulate_sync(regs, opcode); 1062 status = simulate_sync(regs, opcode);
1063
1064 if (status < 0)
1065 status = simulate_fp(regs, opcode, old_epc, old31);
1019 } 1066 }
1020 1067
1021 if (status < 0) 1068 if (status < 0)
@@ -1380,12 +1427,19 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
1380 show_regs(regs); 1427 show_regs(regs);
1381 1428
1382 if (multi_match) { 1429 if (multi_match) {
1383 printk("Index : %0x\n", read_c0_index()); 1430 pr_err("Index : %0x\n", read_c0_index());
1384 printk("Pagemask: %0x\n", read_c0_pagemask()); 1431 pr_err("Pagemask: %0x\n", read_c0_pagemask());
1385 printk("EntryHi : %0*lx\n", field, read_c0_entryhi()); 1432 pr_err("EntryHi : %0*lx\n", field, read_c0_entryhi());
1386 printk("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); 1433 pr_err("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
1387 printk("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); 1434 pr_err("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
1388 printk("\n"); 1435 pr_err("Wired : %0x\n", read_c0_wired());
1436 pr_err("Pagegrain: %0x\n", read_c0_pagegrain());
1437 if (cpu_has_htw) {
1438 pr_err("PWField : %0*lx\n", field, read_c0_pwfield());
1439 pr_err("PWSize : %0*lx\n", field, read_c0_pwsize());
1440 pr_err("PWCtl : %0x\n", read_c0_pwctl());
1441 }
1442 pr_err("\n");
1389 dump_tlb_all(); 1443 dump_tlb_all();
1390 } 1444 }
1391 1445
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 0f1af58b036a..ed2a278722a9 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -16,9 +16,11 @@
16#include <linux/elf.h> 16#include <linux/elf.h>
17#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
18#include <linux/unistd.h> 18#include <linux/unistd.h>
19#include <linux/random.h>
19 20
20#include <asm/vdso.h> 21#include <asm/vdso.h>
21#include <asm/uasm.h> 22#include <asm/uasm.h>
23#include <asm/processor.h>
22 24
23/* 25/*
24 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... 26 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
@@ -67,7 +69,18 @@ subsys_initcall(init_vdso);
67 69
68static unsigned long vdso_addr(unsigned long start) 70static unsigned long vdso_addr(unsigned long start)
69{ 71{
70 return STACK_TOP; 72 unsigned long offset = 0UL;
73
74 if (current->flags & PF_RANDOMIZE) {
75 offset = get_random_int();
76 offset <<= PAGE_SHIFT;
77 if (TASK_IS_32BIT_ADDR)
78 offset &= 0xfffffful;
79 else
80 offset &= 0xffffffful;
81 }
82
83 return STACK_TOP + offset;
71} 84}
72 85
73int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) 86int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c
index 468ffa043607..7edcd4946fc1 100644
--- a/arch/mips/lantiq/falcon/sysctrl.c
+++ b/arch/mips/lantiq/falcon/sysctrl.c
@@ -49,6 +49,7 @@
49 49
50/* Activation Status Register */ 50/* Activation Status Register */
51#define ACTS_ASC0_ACT 0x00001000 51#define ACTS_ASC0_ACT 0x00001000
52#define ACTS_SSC0 0x00002000
52#define ACTS_ASC1_ACT 0x00000800 53#define ACTS_ASC1_ACT 0x00000800
53#define ACTS_I2C_ACT 0x00004000 54#define ACTS_I2C_ACT 0x00004000
54#define ACTS_P0 0x00010000 55#define ACTS_P0 0x00010000
@@ -147,12 +148,11 @@ static void falcon_gpe_enable(void)
147 if (status & (1 << (GPPC_OFFSET + 1))) 148 if (status & (1 << (GPPC_OFFSET + 1)))
148 return; 149 return;
149 150
150 if (status_r32(STATUS_CONFIG) == 0) 151 freq = (status_r32(STATUS_CONFIG) &
152 GPEFREQ_MASK) >>
153 GPEFREQ_OFFSET;
154 if (freq == 0)
151 freq = 1; /* use 625MHz on unfused chip */ 155 freq = 1; /* use 625MHz on unfused chip */
152 else
153 freq = (status_r32(STATUS_CONFIG) &
154 GPEFREQ_MASK) >>
155 GPEFREQ_OFFSET;
156 156
157 /* apply new frequency */ 157 /* apply new frequency */
158 sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), 158 sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1),
@@ -260,5 +260,6 @@ void __init ltq_soc_init(void)
260 clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); 260 clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4);
261 clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); 261 clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT);
262 clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT); 262 clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT);
263 clkdev_add_sys("1e100d00.spi", SYSCTL_SYS1, ACTS_SSC0);
263 clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); 264 clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT);
264} 265}
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 030568a70ac4..6ab10573490d 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -70,6 +70,7 @@ static struct resource ltq_eiu_irq[MAX_EIU];
70static void __iomem *ltq_icu_membase[MAX_IM]; 70static void __iomem *ltq_icu_membase[MAX_IM];
71static void __iomem *ltq_eiu_membase; 71static void __iomem *ltq_eiu_membase;
72static struct irq_domain *ltq_domain; 72static struct irq_domain *ltq_domain;
73static int ltq_perfcount_irq;
73 74
74int ltq_eiu_get_irq(int exin) 75int ltq_eiu_get_irq(int exin)
75{ 76{
@@ -378,30 +379,6 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
378 panic("Failed to remap icu memory"); 379 panic("Failed to remap icu memory");
379 } 380 }
380 381
381 /* the external interrupts are optional and xway only */
382 eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
383 if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
384 /* find out how many external irq sources we have */
385 exin_avail = of_irq_count(eiu_node);
386
387 if (exin_avail > MAX_EIU)
388 exin_avail = MAX_EIU;
389
390 ret = of_irq_to_resource_table(eiu_node,
391 ltq_eiu_irq, exin_avail);
392 if (ret != exin_avail)
393 panic("failed to load external irq resources");
394
395 if (request_mem_region(res.start, resource_size(&res),
396 res.name) < 0)
397 pr_err("Failed to request eiu memory");
398
399 ltq_eiu_membase = ioremap_nocache(res.start,
400 resource_size(&res));
401 if (!ltq_eiu_membase)
402 panic("Failed to remap eiu memory");
403 }
404
405 /* turn off all irqs by default */ 382 /* turn off all irqs by default */
406 for (i = 0; i < MAX_IM; i++) { 383 for (i = 0; i < MAX_IM; i++) {
407 /* make sure all irqs are turned off by default */ 384 /* make sure all irqs are turned off by default */
@@ -449,7 +426,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
449#endif 426#endif
450 427
451 /* tell oprofile which irq to use */ 428 /* tell oprofile which irq to use */
452 cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); 429 ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ);
453 430
454 /* 431 /*
455 * if the timer irq is not one of the mips irqs we need to 432 * if the timer irq is not one of the mips irqs we need to
@@ -458,9 +435,38 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
458 if (MIPS_CPU_TIMER_IRQ != 7) 435 if (MIPS_CPU_TIMER_IRQ != 7)
459 irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); 436 irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);
460 437
438 /* the external interrupts are optional and xway only */
439 eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway");
440 if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
441 /* find out how many external irq sources we have */
442 exin_avail = of_irq_count(eiu_node);
443
444 if (exin_avail > MAX_EIU)
445 exin_avail = MAX_EIU;
446
447 ret = of_irq_to_resource_table(eiu_node,
448 ltq_eiu_irq, exin_avail);
449 if (ret != exin_avail)
450 panic("failed to load external irq resources");
451
452 if (request_mem_region(res.start, resource_size(&res),
453 res.name) < 0)
454 pr_err("Failed to request eiu memory");
455
456 ltq_eiu_membase = ioremap_nocache(res.start,
457 resource_size(&res));
458 if (!ltq_eiu_membase)
459 panic("Failed to remap eiu memory");
460 }
461
461 return 0; 462 return 0;
462} 463}
463 464
465int get_c0_perfcount_int(void)
466{
467 return ltq_perfcount_irq;
468}
469
464unsigned int get_c0_compare_int(void) 470unsigned int get_c0_compare_int(void)
465{ 471{
466 return MIPS_CPU_TIMER_IRQ; 472 return MIPS_CPU_TIMER_IRQ;
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index 7447d322d14e..39ab3e786e59 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -36,6 +36,11 @@ const char *get_system_type(void)
36 return soc_info.sys_type; 36 return soc_info.sys_type;
37} 37}
38 38
39int ltq_soc_type(void)
40{
41 return soc_info.type;
42}
43
39void prom_free_prom_memory(void) 44void prom_free_prom_memory(void)
40{ 45{
41} 46}
@@ -72,6 +77,8 @@ void __init plat_mem_setup(void)
72 * parsed resulting in our memory appearing 77 * parsed resulting in our memory appearing
73 */ 78 */
74 __dt_setup_arch(__dtb_start); 79 __dt_setup_arch(__dtb_start);
80
81 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
75} 82}
76 83
77void __init device_tree_init(void) 84void __init device_tree_init(void)
@@ -97,16 +104,7 @@ void __init prom_init(void)
97 104
98int __init plat_of_setup(void) 105int __init plat_of_setup(void)
99{ 106{
100 static struct of_device_id of_ids[3]; 107 return __dt_register_buses(soc_info.compatible, "simple-bus");
101
102 if (!of_have_populated_dt())
103 panic("device tree not present");
104
105 strlcpy(of_ids[0].compatible, soc_info.compatible,
106 sizeof(of_ids[0].compatible));
107 strncpy(of_ids[1].compatible, "simple-bus",
108 sizeof(of_ids[1].compatible));
109 return of_platform_populate(NULL, of_ids, NULL, NULL);
110} 108}
111 109
112arch_initcall(plat_of_setup); 110arch_initcall(plat_of_setup);
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index 087497d97357..a2edc538f477 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1,3 +1,5 @@
1obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o 1obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o
2 2
3obj-y += vmmc.o
4
3obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o 5obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 1fa0f175357e..fe68f9ae47c1 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -14,6 +14,7 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/of_address.h> 15#include <linux/of_address.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#include <linux/reset-controller.h>
17 18
18#include <asm/reboot.h> 19#include <asm/reboot.h>
19 20
@@ -113,10 +114,77 @@ void ltq_reset_once(unsigned int module, ulong u)
113 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); 114 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ);
114} 115}
115 116
117static int ltq_assert_device(struct reset_controller_dev *rcdev,
118 unsigned long id)
119{
120 u32 val;
121
122 if (id < 8)
123 return -1;
124
125 val = ltq_rcu_r32(RCU_RST_REQ);
126 val |= BIT(id);
127 ltq_rcu_w32(val, RCU_RST_REQ);
128
129 return 0;
130}
131
132static int ltq_deassert_device(struct reset_controller_dev *rcdev,
133 unsigned long id)
134{
135 u32 val;
136
137 if (id < 8)
138 return -1;
139
140 val = ltq_rcu_r32(RCU_RST_REQ);
141 val &= ~BIT(id);
142 ltq_rcu_w32(val, RCU_RST_REQ);
143
144 return 0;
145}
146
147static int ltq_reset_device(struct reset_controller_dev *rcdev,
148 unsigned long id)
149{
150 ltq_assert_device(rcdev, id);
151 return ltq_deassert_device(rcdev, id);
152}
153
154static struct reset_control_ops reset_ops = {
155 .reset = ltq_reset_device,
156 .assert = ltq_assert_device,
157 .deassert = ltq_deassert_device,
158};
159
160static struct reset_controller_dev reset_dev = {
161 .ops = &reset_ops,
162 .owner = THIS_MODULE,
163 .nr_resets = 32,
164 .of_reset_n_cells = 1,
165};
166
167void ltq_rst_init(void)
168{
169 reset_dev.of_node = of_find_compatible_node(NULL, NULL,
170 "lantiq,xway-reset");
171 if (!reset_dev.of_node)
172 pr_err("Failed to find reset controller node");
173 else
174 reset_controller_register(&reset_dev);
175}
176
116static void ltq_machine_restart(char *command) 177static void ltq_machine_restart(char *command)
117{ 178{
179 u32 val = ltq_rcu_r32(RCU_RST_REQ);
180
181 if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200"))
182 val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200;
183
184 val |= RCU_RD_SRST;
185
118 local_irq_disable(); 186 local_irq_disable();
119 ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ); 187 ltq_rcu_w32(val, RCU_RST_REQ);
120 unreachable(); 188 unreachable();
121} 189}
122 190
diff --git a/arch/mips/lantiq/xway/vmmc.c b/arch/mips/lantiq/xway/vmmc.c
new file mode 100644
index 000000000000..696cd57f6f13
--- /dev/null
+++ b/arch/mips/lantiq/xway/vmmc.c
@@ -0,0 +1,69 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/module.h>
10#include <linux/of_platform.h>
11#include <linux/of_gpio.h>
12#include <linux/dma-mapping.h>
13
14#include <lantiq_soc.h>
15
16static unsigned int *cp1_base;
17
18unsigned int *ltq_get_cp1_base(void)
19{
20 if (!cp1_base)
21 panic("no cp1 base was set\n");
22
23 return cp1_base;
24}
25EXPORT_SYMBOL(ltq_get_cp1_base);
26
27static int vmmc_probe(struct platform_device *pdev)
28{
29#define CP1_SIZE (1 << 20)
30 int gpio_count;
31 dma_addr_t dma;
32
33 cp1_base =
34 (void *) CPHYSADDR(dma_alloc_coherent(NULL, CP1_SIZE,
35 &dma, GFP_ATOMIC));
36
37 gpio_count = of_gpio_count(pdev->dev.of_node);
38 while (gpio_count > 0) {
39 enum of_gpio_flags flags;
40 int gpio = of_get_gpio_flags(pdev->dev.of_node,
41 --gpio_count, &flags);
42 if (gpio_request(gpio, "vmmc-relay"))
43 continue;
44 dev_info(&pdev->dev, "requested GPIO %d\n", gpio);
45 gpio_direction_output(gpio,
46 (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1));
47 }
48
49 dev_info(&pdev->dev, "reserved %dMB at 0x%p", CP1_SIZE >> 20, cp1_base);
50
51 return 0;
52}
53
54static const struct of_device_id vmmc_match[] = {
55 { .compatible = "lantiq,vmmc-xway" },
56 {},
57};
58MODULE_DEVICE_TABLE(of, vmmc_match);
59
60static struct platform_driver vmmc_driver = {
61 .probe = vmmc_probe,
62 .driver = {
63 .name = "lantiq,vmmc",
64 .owner = THIS_MODULE,
65 .of_match_table = vmmc_match,
66 },
67};
68
69module_platform_driver(vmmc_driver);
diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c
index d4d9d31f152e..7c1e54c6a36c 100644
--- a/arch/mips/lantiq/xway/xrx200_phy_fw.c
+++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c
@@ -24,7 +24,28 @@ static dma_addr_t xway_gphy_load(struct platform_device *pdev)
24 void *fw_addr; 24 void *fw_addr;
25 size_t size; 25 size_t size;
26 26
27 if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) { 27 if (of_get_property(pdev->dev.of_node, "firmware1", NULL) ||
28 of_get_property(pdev->dev.of_node, "firmware2", NULL)) {
29 switch (ltq_soc_type()) {
30 case SOC_TYPE_VR9:
31 if (of_property_read_string(pdev->dev.of_node,
32 "firmware1", &fw_name)) {
33 dev_err(&pdev->dev,
34 "failed to load firmware filename\n");
35 return 0;
36 }
37 break;
38 case SOC_TYPE_VR9_2:
39 if (of_property_read_string(pdev->dev.of_node,
40 "firmware2", &fw_name)) {
41 dev_err(&pdev->dev,
42 "failed to load firmware filename\n");
43 return 0;
44 }
45 break;
46 }
47 } else if (of_property_read_string(pdev->dev.of_node,
48 "firmware", &fw_name)) {
28 dev_err(&pdev->dev, "failed to load firmware filename\n"); 49 dev_err(&pdev->dev, "failed to load firmware filename\n");
29 return 0; 50 return 0;
30 } 51 }
diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c
index e3acb2dad33a..8e7e378ce51c 100644
--- a/arch/mips/lib/iomap.c
+++ b/arch/mips/lib/iomap.c
@@ -97,14 +97,14 @@ EXPORT_SYMBOL(iowrite32be);
97 97
98/* 98/*
99 * These are the "repeat MMIO read/write" functions. 99 * These are the "repeat MMIO read/write" functions.
100 * Note the "__raw" accesses, since we don't want to 100 * Note the "__mem" accesses, since we want to convert
101 * convert to CPU byte order. We write in "IO byte 101 * to CPU byte order if the host bus happens to not match the
102 * order" (we also don't have IO barriers). 102 * endianness of PCI/ISA (see mach-generic/mangle-port.h).
103 */ 103 */
104static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) 104static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
105{ 105{
106 while (--count >= 0) { 106 while (--count >= 0) {
107 u8 data = __raw_readb(addr); 107 u8 data = __mem_readb(addr);
108 *dst = data; 108 *dst = data;
109 dst++; 109 dst++;
110 } 110 }
@@ -113,7 +113,7 @@ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
113static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) 113static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
114{ 114{
115 while (--count >= 0) { 115 while (--count >= 0) {
116 u16 data = __raw_readw(addr); 116 u16 data = __mem_readw(addr);
117 *dst = data; 117 *dst = data;
118 dst++; 118 dst++;
119 } 119 }
@@ -122,7 +122,7 @@ static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
122static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) 122static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
123{ 123{
124 while (--count >= 0) { 124 while (--count >= 0) {
125 u32 data = __raw_readl(addr); 125 u32 data = __mem_readl(addr);
126 *dst = data; 126 *dst = data;
127 dst++; 127 dst++;
128 } 128 }
@@ -131,7 +131,7 @@ static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
131static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) 131static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
132{ 132{
133 while (--count >= 0) { 133 while (--count >= 0) {
134 __raw_writeb(*src, addr); 134 __mem_writeb(*src, addr);
135 src++; 135 src++;
136 } 136 }
137} 137}
@@ -139,7 +139,7 @@ static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
139static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) 139static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
140{ 140{
141 while (--count >= 0) { 141 while (--count >= 0) {
142 __raw_writew(*src, addr); 142 __mem_writew(*src, addr);
143 src++; 143 src++;
144 } 144 }
145} 145}
@@ -147,7 +147,7 @@ static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
147static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) 147static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
148{ 148{
149 while (--count >= 0) { 149 while (--count >= 0) {
150 __raw_writel(*src, addr); 150 __mem_writel(*src, addr);
151 src++; 151 src++;
152 } 152 }
153} 153}
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S
index 7b0e5462ca51..c8fe6b1968fb 100644
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -114,8 +114,7 @@
114 R10KCBARRIER(0(ra)) 114 R10KCBARRIER(0(ra))
115#ifdef __MIPSEB__ 115#ifdef __MIPSEB__
116 EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ 116 EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */
117#endif 117#else
118#ifdef __MIPSEL__
119 EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ 118 EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */
120#endif 119#endif
121 PTR_SUBU a0, t0 /* long align ptr */ 120 PTR_SUBU a0, t0 /* long align ptr */
@@ -164,8 +163,7 @@
164 R10KCBARRIER(0(ra)) 163 R10KCBARRIER(0(ra))
165#ifdef __MIPSEB__ 164#ifdef __MIPSEB__
166 EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@) 165 EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@)
167#endif 166#else
168#ifdef __MIPSEL__
169 EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@) 167 EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@)
170#endif 168#endif
1711: jr ra 1691: jr ra
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c
index 57bcdaf1f1c8..be777d9a3f85 100644
--- a/arch/mips/lib/mips-atomic.c
+++ b/arch/mips/lib/mips-atomic.c
@@ -42,15 +42,11 @@ notrace void arch_local_irq_disable(void)
42 __asm__ __volatile__( 42 __asm__ __volatile__(
43 " .set push \n" 43 " .set push \n"
44 " .set noat \n" 44 " .set noat \n"
45#if defined(CONFIG_CPU_MIPSR2)
46 /* see irqflags.h for inline function */
47#else
48 " mfc0 $1,$12 \n" 45 " mfc0 $1,$12 \n"
49 " ori $1,0x1f \n" 46 " ori $1,0x1f \n"
50 " xori $1,0x1f \n" 47 " xori $1,0x1f \n"
51 " .set noreorder \n" 48 " .set noreorder \n"
52 " mtc0 $1,$12 \n" 49 " mtc0 $1,$12 \n"
53#endif
54 " " __stringify(__irq_disable_hazard) " \n" 50 " " __stringify(__irq_disable_hazard) " \n"
55 " .set pop \n" 51 " .set pop \n"
56 : /* no outputs */ 52 : /* no outputs */
@@ -72,15 +68,11 @@ notrace unsigned long arch_local_irq_save(void)
72 " .set push \n" 68 " .set push \n"
73 " .set reorder \n" 69 " .set reorder \n"
74 " .set noat \n" 70 " .set noat \n"
75#if defined(CONFIG_CPU_MIPSR2)
76 /* see irqflags.h for inline function */
77#else
78 " mfc0 %[flags], $12 \n" 71 " mfc0 %[flags], $12 \n"
79 " ori $1, %[flags], 0x1f \n" 72 " ori $1, %[flags], 0x1f \n"
80 " xori $1, 0x1f \n" 73 " xori $1, 0x1f \n"
81 " .set noreorder \n" 74 " .set noreorder \n"
82 " mtc0 $1, $12 \n" 75 " mtc0 $1, $12 \n"
83#endif
84 " " __stringify(__irq_disable_hazard) " \n" 76 " " __stringify(__irq_disable_hazard) " \n"
85 " .set pop \n" 77 " .set pop \n"
86 : [flags] "=r" (flags) 78 : [flags] "=r" (flags)
@@ -103,18 +95,12 @@ notrace void arch_local_irq_restore(unsigned long flags)
103 " .set push \n" 95 " .set push \n"
104 " .set noreorder \n" 96 " .set noreorder \n"
105 " .set noat \n" 97 " .set noat \n"
106#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
107 /* see irqflags.h for inline function */
108#elif defined(CONFIG_CPU_MIPSR2)
109 /* see irqflags.h for inline function */
110#else
111 " mfc0 $1, $12 \n" 98 " mfc0 $1, $12 \n"
112 " andi %[flags], 1 \n" 99 " andi %[flags], 1 \n"
113 " ori $1, 0x1f \n" 100 " ori $1, 0x1f \n"
114 " xori $1, 0x1f \n" 101 " xori $1, 0x1f \n"
115 " or %[flags], $1 \n" 102 " or %[flags], $1 \n"
116 " mtc0 %[flags], $12 \n" 103 " mtc0 %[flags], $12 \n"
117#endif
118 " " __stringify(__irq_disable_hazard) " \n" 104 " " __stringify(__irq_disable_hazard) " \n"
119 " .set pop \n" 105 " .set pop \n"
120 : [flags] "=r" (__tmp1) 106 : [flags] "=r" (__tmp1)
@@ -136,18 +122,12 @@ notrace void __arch_local_irq_restore(unsigned long flags)
136 " .set push \n" 122 " .set push \n"
137 " .set noreorder \n" 123 " .set noreorder \n"
138 " .set noat \n" 124 " .set noat \n"
139#if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU)
140 /* see irqflags.h for inline function */
141#elif defined(CONFIG_CPU_MIPSR2)
142 /* see irqflags.h for inline function */
143#else
144 " mfc0 $1, $12 \n" 125 " mfc0 $1, $12 \n"
145 " andi %[flags], 1 \n" 126 " andi %[flags], 1 \n"
146 " ori $1, 0x1f \n" 127 " ori $1, 0x1f \n"
147 " xori $1, 0x1f \n" 128 " xori $1, 0x1f \n"
148 " or %[flags], $1 \n" 129 " or %[flags], $1 \n"
149 " mtc0 %[flags], $12 \n" 130 " mtc0 %[flags], $12 \n"
150#endif
151 " " __stringify(__irq_disable_hazard) " \n" 131 " " __stringify(__irq_disable_hazard) " \n"
152 " .set pop \n" 132 " .set pop \n"
153 : [flags] "=r" (__tmp1) 133 : [flags] "=r" (__tmp1)
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c
index 1ef365ab3cd3..975a13855116 100644
--- a/arch/mips/lib/r3k_dump_tlb.c
+++ b/arch/mips/lib/r3k_dump_tlb.c
@@ -9,6 +9,7 @@
9#include <linux/mm.h> 9#include <linux/mm.h>
10 10
11#include <asm/mipsregs.h> 11#include <asm/mipsregs.h>
12#include <asm/mmu_context.h>
12#include <asm/page.h> 13#include <asm/page.h>
13#include <asm/pgtable.h> 14#include <asm/pgtable.h>
14#include <asm/tlbdebug.h> 15#include <asm/tlbdebug.h>
@@ -21,7 +22,7 @@ static void dump_tlb(int first, int last)
21 unsigned int asid; 22 unsigned int asid;
22 unsigned long entryhi, entrylo0; 23 unsigned long entryhi, entrylo0;
23 24
24 asid = read_c0_entryhi() & 0xfc0; 25 asid = read_c0_entryhi() & ASID_MASK;
25 26
26 for (i = first; i <= last; i++) { 27 for (i = first; i <= last; i++) {
27 write_c0_index(i<<8); 28 write_c0_index(i<<8);
@@ -34,8 +35,8 @@ static void dump_tlb(int first, int last)
34 entrylo0 = read_c0_entrylo0(); 35 entrylo0 = read_c0_entrylo0();
35 36
36 /* Unused entries have a virtual address of KSEG0. */ 37 /* Unused entries have a virtual address of KSEG0. */
37 if ((entryhi & 0xfffff000) != 0x80000000 38 if ((entryhi & PAGE_MASK) != KSEG0
38 && (entryhi & 0xfc0) == asid) { 39 && (entryhi & ASID_MASK) == asid) {
39 /* 40 /*
40 * Only print entries in use 41 * Only print entries in use
41 */ 42 */
@@ -43,8 +44,8 @@ static void dump_tlb(int first, int last)
43 44
44 printk("va=%08lx asid=%08lx" 45 printk("va=%08lx asid=%08lx"
45 " [pa=%06lx n=%d d=%d v=%d g=%d]", 46 " [pa=%06lx n=%d d=%d v=%d g=%d]",
46 (entryhi & 0xfffff000), 47 entryhi & PAGE_MASK,
47 entryhi & 0xfc0, 48 entryhi & ASID_MASK,
48 entrylo0 & PAGE_MASK, 49 entrylo0 & PAGE_MASK,
49 (entrylo0 & (1 << 11)) ? 1 : 0, 50 (entrylo0 & (1 << 11)) ? 1 : 0,
50 (entrylo0 & (1 << 10)) ? 1 : 0, 51 (entrylo0 & (1 << 10)) ? 1 : 0,
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S
index bef65c98df59..929bbacd697e 100644
--- a/arch/mips/lib/strlen_user.S
+++ b/arch/mips/lib/strlen_user.S
@@ -28,7 +28,6 @@ LEAF(__strlen_\func\()_asm)
28 and v0, a0 28 and v0, a0
29 bnez v0, .Lfault\@ 29 bnez v0, .Lfault\@
30 30
31FEXPORT(__strlen_\func\()_nocheck_asm)
32 move v0, a0 31 move v0, a0
33.ifeqs "\func", "kernel" 32.ifeqs "\func", "kernel"
341: EX(lbu, v1, (v0), .Lfault\@) 331: EX(lbu, v1, (v0), .Lfault\@)
@@ -48,9 +47,7 @@ FEXPORT(__strlen_\func\()_nocheck_asm)
48#ifndef CONFIG_EVA 47#ifndef CONFIG_EVA
49 /* Set aliases */ 48 /* Set aliases */
50 .global __strlen_user_asm 49 .global __strlen_user_asm
51 .global __strlen_user_nocheck_asm
52 .set __strlen_user_asm, __strlen_kernel_asm 50 .set __strlen_user_asm, __strlen_kernel_asm
53 .set __strlen_user_nocheck_asm, __strlen_kernel_nocheck_asm
54#endif 51#endif
55 52
56__BUILD_STRLEN_ASM kernel 53__BUILD_STRLEN_ASM kernel
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
index 1b91fc6a921b..156de85b82cd 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -86,6 +86,7 @@ config LOONGSON_MACH3X
86 select LOONGSON_MC146818 86 select LOONGSON_MC146818
87 select ZONE_DMA32 87 select ZONE_DMA32
88 select LEFI_FIRMWARE_INTERFACE 88 select LEFI_FIRMWARE_INTERFACE
89 select PHYS48_TO_HT40
89 help 90 help
90 Generic Loongson 3 family machines utilize the 3A/3B revision 91 Generic Loongson 3 family machines utilize the 3A/3B revision
91 of Loongson processor and RS780/SBX00 chipset. 92 of Loongson processor and RS780/SBX00 chipset.
@@ -107,6 +108,18 @@ config CS5536_MFGPT
107 108
108 If unsure, say Yes. 109 If unsure, say Yes.
109 110
111config RS780_HPET
112 bool "RS780/SBX00 HPET Timer"
113 depends on LOONGSON_MACH3X
114 select MIPS_EXTERNAL_TIMER
115 help
116 This option enables the hpet timer of AMD RS780/SBX00.
117
118 If you want to enable the Loongson3 CPUFreq Driver, Please enable
119 this option at first, otherwise, You will get wrong system time.
120
121 If unsure, say Yes.
122
110config LOONGSON_SUSPEND 123config LOONGSON_SUSPEND
111 bool 124 bool
112 default y 125 default y
@@ -131,6 +144,10 @@ config SWIOTLB
131 select NEED_SG_DMA_LENGTH 144 select NEED_SG_DMA_LENGTH
132 select NEED_DMA_MAP_STATE 145 select NEED_DMA_MAP_STATE
133 146
147config PHYS48_TO_HT40
148 bool
149 default y if CPU_LOONGSON3
150
134config LOONGSON_MC146818 151config LOONGSON_MC146818
135 bool 152 bool
136 default n 153 default n
diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c
index 81bed9d18061..b739723205f8 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_pci.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/types.h> 23#include <linux/types.h>
24#include <cs5536/cs5536_pci.h>
24#include <cs5536/cs5536_vsm.h> 25#include <cs5536/cs5536_vsm.h>
25 26
26enum { 27enum {
@@ -35,21 +36,21 @@ enum {
35}; 36};
36 37
37static const cs5536_pci_vsm_write vsm_conf_write[] = { 38static const cs5536_pci_vsm_write vsm_conf_write[] = {
38 [CS5536_ISA_FUNC] pci_isa_write_reg, 39 [CS5536_ISA_FUNC] = pci_isa_write_reg,
39 [reserved_func] NULL, 40 [reserved_func] = NULL,
40 [CS5536_IDE_FUNC] pci_ide_write_reg, 41 [CS5536_IDE_FUNC] = pci_ide_write_reg,
41 [CS5536_ACC_FUNC] pci_acc_write_reg, 42 [CS5536_ACC_FUNC] = pci_acc_write_reg,
42 [CS5536_OHCI_FUNC] pci_ohci_write_reg, 43 [CS5536_OHCI_FUNC] = pci_ohci_write_reg,
43 [CS5536_EHCI_FUNC] pci_ehci_write_reg, 44 [CS5536_EHCI_FUNC] = pci_ehci_write_reg,
44}; 45};
45 46
46static const cs5536_pci_vsm_read vsm_conf_read[] = { 47static const cs5536_pci_vsm_read vsm_conf_read[] = {
47 [CS5536_ISA_FUNC] pci_isa_read_reg, 48 [CS5536_ISA_FUNC] = pci_isa_read_reg,
48 [reserved_func] NULL, 49 [reserved_func] = NULL,
49 [CS5536_IDE_FUNC] pci_ide_read_reg, 50 [CS5536_IDE_FUNC] = pci_ide_read_reg,
50 [CS5536_ACC_FUNC] pci_acc_read_reg, 51 [CS5536_ACC_FUNC] = pci_acc_read_reg,
51 [CS5536_OHCI_FUNC] pci_ohci_read_reg, 52 [CS5536_OHCI_FUNC] = pci_ohci_read_reg,
52 [CS5536_EHCI_FUNC] pci_ehci_read_reg, 53 [CS5536_EHCI_FUNC] = pci_ehci_read_reg,
53}; 54};
54 55
55/* 56/*
diff --git a/arch/mips/loongson/common/dma-swiotlb.c b/arch/mips/loongson/common/dma-swiotlb.c
index c2be01f91575..2c6b989c1bc4 100644
--- a/arch/mips/loongson/common/dma-swiotlb.c
+++ b/arch/mips/loongson/common/dma-swiotlb.c
@@ -105,11 +105,25 @@ static int loongson_dma_set_mask(struct device *dev, u64 mask)
105 105
106dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) 106dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
107{ 107{
108 long nid;
109#ifdef CONFIG_PHYS48_TO_HT40
110 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
111 * Loongson-3's 48bit address space and embed it into 40bit */
112 nid = (paddr >> 44) & 0x3;
113 paddr = ((nid << 44) ^ paddr) | (nid << 37);
114#endif
108 return paddr; 115 return paddr;
109} 116}
110 117
111phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) 118phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
112{ 119{
120 long nid;
121#ifdef CONFIG_PHYS48_TO_HT40
122 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from
123 * Loongson-3's 48bit address space and embed it into 40bit */
124 nid = (daddr >> 37) & 0x3;
125 daddr = ((nid << 37) ^ daddr) | (nid << 44);
126#endif
113 return daddr; 127 return daddr;
114} 128}
115 129
diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c
index ced461b39069..6ca632e529dc 100644
--- a/arch/mips/loongson/common/early_printk.c
+++ b/arch/mips/loongson/common/early_printk.c
@@ -30,7 +30,7 @@ void prom_putchar(char c)
30 int timeout; 30 int timeout;
31 unsigned char *uart_base; 31 unsigned char *uart_base;
32 32
33 uart_base = (unsigned char *)_loongson_uart_base; 33 uart_base = (unsigned char *)_loongson_uart_base[0];
34 timeout = 1024; 34 timeout = 1024;
35 35
36 while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && 36 while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) &&
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
index f15228550a22..045ea3d47c87 100644
--- a/arch/mips/loongson/common/env.c
+++ b/arch/mips/loongson/common/env.c
@@ -21,6 +21,7 @@
21#include <asm/bootinfo.h> 21#include <asm/bootinfo.h>
22#include <loongson.h> 22#include <loongson.h>
23#include <boot_param.h> 23#include <boot_param.h>
24#include <workarounds.h>
24 25
25u32 cpu_clock_freq; 26u32 cpu_clock_freq;
26EXPORT_SYMBOL(cpu_clock_freq); 27EXPORT_SYMBOL(cpu_clock_freq);
@@ -31,7 +32,6 @@ u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180};
31u64 loongson_freqctrl[MAX_PACKAGES]; 32u64 loongson_freqctrl[MAX_PACKAGES];
32 33
33unsigned long long smp_group[4]; 34unsigned long long smp_group[4];
34int cpuhotplug_workaround = 0;
35 35
36#define parse_even_earlier(res, option, p) \ 36#define parse_even_earlier(res, option, p) \
37do { \ 37do { \
@@ -67,6 +67,7 @@ void __init prom_init_env(void)
67#else 67#else
68 struct boot_params *boot_p; 68 struct boot_params *boot_p;
69 struct loongson_params *loongson_p; 69 struct loongson_params *loongson_p;
70 struct system_loongson *esys;
70 struct efi_cpuinfo_loongson *ecpu; 71 struct efi_cpuinfo_loongson *ecpu;
71 struct irq_source_routing_table *eirq_source; 72 struct irq_source_routing_table *eirq_source;
72 73
@@ -74,6 +75,8 @@ void __init prom_init_env(void)
74 boot_p = (struct boot_params *)fw_arg2; 75 boot_p = (struct boot_params *)fw_arg2;
75 loongson_p = &(boot_p->efi.smbios.lp); 76 loongson_p = &(boot_p->efi.smbios.lp);
76 77
78 esys = (struct system_loongson *)
79 ((u64)loongson_p + loongson_p->system_offset);
77 ecpu = (struct efi_cpuinfo_loongson *) 80 ecpu = (struct efi_cpuinfo_loongson *)
78 ((u64)loongson_p + loongson_p->cpu_offset); 81 ((u64)loongson_p + loongson_p->cpu_offset);
79 eirq_source = (struct irq_source_routing_table *) 82 eirq_source = (struct irq_source_routing_table *)
@@ -95,6 +98,7 @@ void __init prom_init_env(void)
95 loongson_chipcfg[2] = 0x900020001fe00180; 98 loongson_chipcfg[2] = 0x900020001fe00180;
96 loongson_chipcfg[3] = 0x900030001fe00180; 99 loongson_chipcfg[3] = 0x900030001fe00180;
97 loongson_sysconf.ht_control_base = 0x90000EFDFB000000; 100 loongson_sysconf.ht_control_base = 0x90000EFDFB000000;
101 loongson_sysconf.workarounds = WORKAROUND_CPUFREQ;
98 } else if (ecpu->cputype == Loongson_3B) { 102 } else if (ecpu->cputype == Loongson_3B) {
99 loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ 103 loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */
100 loongson_sysconf.cores_per_package = 8; 104 loongson_sysconf.cores_per_package = 8;
@@ -111,7 +115,7 @@ void __init prom_init_env(void)
111 loongson_freqctrl[2] = 0x900040001fe001d0; 115 loongson_freqctrl[2] = 0x900040001fe001d0;
112 loongson_freqctrl[3] = 0x900060001fe001d0; 116 loongson_freqctrl[3] = 0x900060001fe001d0;
113 loongson_sysconf.ht_control_base = 0x90001EFDFB000000; 117 loongson_sysconf.ht_control_base = 0x90001EFDFB000000;
114 cpuhotplug_workaround = 1; 118 loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG;
115 } else { 119 } else {
116 loongson_sysconf.cores_per_node = 1; 120 loongson_sysconf.cores_per_node = 1;
117 loongson_sysconf.cores_per_package = 1; 121 loongson_sysconf.cores_per_package = 1;
@@ -119,6 +123,8 @@ void __init prom_init_env(void)
119 } 123 }
120 124
121 loongson_sysconf.nr_cpus = ecpu->nr_cpus; 125 loongson_sysconf.nr_cpus = ecpu->nr_cpus;
126 loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id;
127 loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask;
122 if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) 128 if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0)
123 loongson_sysconf.nr_cpus = NR_CPUS; 129 loongson_sysconf.nr_cpus = NR_CPUS;
124 loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + 130 loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
@@ -141,6 +147,24 @@ void __init prom_init_env(void)
141 pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", 147 pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n",
142 loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, 148 loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr,
143 loongson_sysconf.vgabios_addr); 149 loongson_sysconf.vgabios_addr);
150
151 memset(loongson_sysconf.ecname, 0, 32);
152 if (esys->has_ec)
153 memcpy(loongson_sysconf.ecname, esys->ec_name, 32);
154 loongson_sysconf.workarounds |= esys->workarounds;
155
156 loongson_sysconf.nr_uarts = esys->nr_uarts;
157 if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS)
158 loongson_sysconf.nr_uarts = 1;
159 memcpy(loongson_sysconf.uarts, esys->uarts,
160 sizeof(struct uart_device) * loongson_sysconf.nr_uarts);
161
162 loongson_sysconf.nr_sensors = esys->nr_sensors;
163 if (loongson_sysconf.nr_sensors > MAX_SENSORS)
164 loongson_sysconf.nr_sensors = 0;
165 if (loongson_sysconf.nr_sensors)
166 memcpy(loongson_sysconf.sensors, esys->sensors,
167 sizeof(struct sensor_device) * loongson_sysconf.nr_sensors);
144#endif 168#endif
145 if (cpu_clock_freq == 0) { 169 if (cpu_clock_freq == 0) {
146 processor_id = (&current_cpu_data)->processor_id; 170 processor_id = (&current_cpu_data)->processor_id;
diff --git a/arch/mips/loongson/common/gpio.c b/arch/mips/loongson/common/gpio.c
index 21869908aaa4..29dbaa253061 100644
--- a/arch/mips/loongson/common/gpio.c
+++ b/arch/mips/loongson/common/gpio.c
@@ -37,7 +37,7 @@ int gpio_get_value(unsigned gpio)
37 val = LOONGSON_GPIODATA; 37 val = LOONGSON_GPIODATA;
38 spin_unlock(&gpio_lock); 38 spin_unlock(&gpio_lock);
39 39
40 return ((val & mask) != 0); 40 return (val & mask) != 0;
41} 41}
42EXPORT_SYMBOL(gpio_get_value); 42EXPORT_SYMBOL(gpio_get_value);
43 43
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c
index f6af3aba4c86..9b987fe98b5b 100644
--- a/arch/mips/loongson/common/init.c
+++ b/arch/mips/loongson/common/init.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/bootmem.h> 11#include <linux/bootmem.h>
12#include <asm/bootinfo.h>
12#include <asm/smp-ops.h> 13#include <asm/smp-ops.h>
13 14
14#include <loongson.h> 15#include <loongson.h>
diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c
index 1a4797984b8d..f2807bc662a3 100644
--- a/arch/mips/loongson/common/machtype.c
+++ b/arch/mips/loongson/common/machtype.c
@@ -19,19 +19,16 @@
19#define MACHTYPE_LEN 50 19#define MACHTYPE_LEN 50
20 20
21static const char *system_types[] = { 21static const char *system_types[] = {
22 [MACH_LOONGSON_UNKNOWN] "unknown loongson machine", 22 [MACH_LOONGSON_UNKNOWN] = "unknown loongson machine",
23 [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box", 23 [MACH_LEMOTE_FL2E] = "lemote-fuloong-2e-box",
24 [MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box", 24 [MACH_LEMOTE_FL2F] = "lemote-fuloong-2f-box",
25 [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches", 25 [MACH_LEMOTE_ML2F7] = "lemote-mengloong-2f-7inches",
26 [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", 26 [MACH_LEMOTE_YL2F89] = "lemote-yeeloong-2f-8.9inches",
27 [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f", 27 [MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f",
28 [MACH_LEMOTE_NAS] "lemote-nas-2f", 28 [MACH_LEMOTE_NAS] = "lemote-nas-2f",
29 [MACH_LEMOTE_LL2F] "lemote-lynloong-2f", 29 [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f",
30 [MACH_LEMOTE_A1004] "lemote-3a-notebook-a1004", 30 [MACH_LOONGSON_GENERIC] = "generic-loongson-machine",
31 [MACH_LEMOTE_A1101] "lemote-3a-itx-a1101", 31 [MACH_LOONGSON_END] = NULL,
32 [MACH_LEMOTE_A1201] "lemote-2gq-notebook-a1201",
33 [MACH_LEMOTE_A1205] "lemote-2gq-aio-a1205",
34 [MACH_LOONGSON_END] NULL,
35}; 32};
36 33
37const char *get_system_type(void) 34const char *get_system_type(void)
diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c
index a90d87c01555..b5709af09f7f 100644
--- a/arch/mips/loongson/common/rtc.c
+++ b/arch/mips/loongson/common/rtc.c
@@ -14,7 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/mc146818rtc.h> 15#include <linux/mc146818rtc.h>
16 16
17struct resource loongson_rtc_resources[] = { 17static struct resource loongson_rtc_resources[] = {
18 { 18 {
19 .start = RTC_PORT(0), 19 .start = RTC_PORT(0),
20 .end = RTC_PORT(1), 20 .end = RTC_PORT(1),
diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c
index bd2b7095b6dc..c23fa1373729 100644
--- a/arch/mips/loongson/common/serial.c
+++ b/arch/mips/loongson/common/serial.c
@@ -38,20 +38,17 @@
38 .regshift = 0, \ 38 .regshift = 0, \
39} 39}
40 40
41static struct plat_serial8250_port uart8250_data[][2] = { 41static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = {
42 [MACH_LOONGSON_UNKNOWN] {}, 42 [MACH_LOONGSON_UNKNOWN] = {},
43 [MACH_LEMOTE_FL2E] {PORT(4, 1843200), {} }, 43 [MACH_LEMOTE_FL2E] = {PORT(4, 1843200), {} },
44 [MACH_LEMOTE_FL2F] {PORT(3, 1843200), {} }, 44 [MACH_LEMOTE_FL2F] = {PORT(3, 1843200), {} },
45 [MACH_LEMOTE_ML2F7] {PORT_M(3, 3686400), {} }, 45 [MACH_LEMOTE_ML2F7] = {PORT_M(3, 3686400), {} },
46 [MACH_LEMOTE_YL2F89] {PORT_M(3, 3686400), {} }, 46 [MACH_LEMOTE_YL2F89] = {PORT_M(3, 3686400), {} },
47 [MACH_DEXXON_GDIUM2F10] {PORT_M(3, 3686400), {} }, 47 [MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} },
48 [MACH_LEMOTE_NAS] {PORT_M(3, 3686400), {} }, 48 [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} },
49 [MACH_LEMOTE_LL2F] {PORT(3, 1843200), {} }, 49 [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} },
50 [MACH_LEMOTE_A1004] {PORT_M(2, 33177600), {} }, 50 [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} },
51 [MACH_LEMOTE_A1101] {PORT_M(2, 25000000), {} }, 51 [MACH_LOONGSON_END] = {},
52 [MACH_LEMOTE_A1201] {PORT_M(2, 25000000), {} },
53 [MACH_LEMOTE_A1205] {PORT_M(2, 25000000), {} },
54 [MACH_LOONGSON_END] {},
55}; 52};
56 53
57static struct platform_device uart8250_device = { 54static struct platform_device uart8250_device = {
@@ -61,17 +58,52 @@ static struct platform_device uart8250_device = {
61 58
62static int __init serial_init(void) 59static int __init serial_init(void)
63{ 60{
61 int i;
64 unsigned char iotype; 62 unsigned char iotype;
65 63
66 iotype = uart8250_data[mips_machtype][0].iotype; 64 iotype = uart8250_data[mips_machtype][0].iotype;
67 65
68 if (UPIO_MEM == iotype) 66 if (UPIO_MEM == iotype) {
67 uart8250_data[mips_machtype][0].mapbase =
68 loongson_uart_base[0];
69 uart8250_data[mips_machtype][0].membase = 69 uart8250_data[mips_machtype][0].membase =
70 (void __iomem *)_loongson_uart_base; 70 (void __iomem *)_loongson_uart_base[0];
71 }
71 else if (UPIO_PORT == iotype) 72 else if (UPIO_PORT == iotype)
72 uart8250_data[mips_machtype][0].iobase = 73 uart8250_data[mips_machtype][0].iobase =
73 loongson_uart_base - LOONGSON_PCIIO_BASE; 74 loongson_uart_base[0] - LOONGSON_PCIIO_BASE;
74 75
76 if (loongson_sysconf.uarts[0].uartclk)
77 uart8250_data[mips_machtype][0].uartclk =
78 loongson_sysconf.uarts[0].uartclk;
79
80 for (i = 1; i < loongson_sysconf.nr_uarts; i++) {
81 iotype = loongson_sysconf.uarts[i].iotype;
82 uart8250_data[mips_machtype][i].iotype = iotype;
83 loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base;
84
85 if (UPIO_MEM == iotype) {
86 uart8250_data[mips_machtype][i].irq =
87 MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset;
88 uart8250_data[mips_machtype][i].mapbase =
89 loongson_uart_base[i];
90 uart8250_data[mips_machtype][i].membase =
91 ioremap_nocache(loongson_uart_base[i], 8);
92 } else if (UPIO_PORT == iotype) {
93 uart8250_data[mips_machtype][i].irq =
94 loongson_sysconf.uarts[i].int_offset;
95 uart8250_data[mips_machtype][i].iobase =
96 loongson_uart_base[i] - LOONGSON_PCIIO_BASE;
97 }
98
99 uart8250_data[mips_machtype][i].uartclk =
100 loongson_sysconf.uarts[i].uartclk;
101 uart8250_data[mips_machtype][i].flags =
102 UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
103 }
104
105 memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts],
106 0, sizeof(struct plat_serial8250_port));
75 uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; 107 uart8250_device.dev.platform_data = uart8250_data[mips_machtype];
76 108
77 return platform_device_register(&uart8250_device); 109 return platform_device_register(&uart8250_device);
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c
index bb4ac922e47a..d477dd6bb326 100644
--- a/arch/mips/loongson/common/setup.c
+++ b/arch/mips/loongson/common/setup.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11 11
12#include <asm/wbflush.h> 12#include <asm/wbflush.h>
13#include <asm/bootinfo.h>
13 14
14#include <loongson.h> 15#include <loongson.h>
15 16
diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c
index 262a1f65b05e..e1a5382ad47e 100644
--- a/arch/mips/loongson/common/time.c
+++ b/arch/mips/loongson/common/time.c
@@ -12,6 +12,7 @@
12 */ 12 */
13#include <asm/mc146818-time.h> 13#include <asm/mc146818-time.h>
14#include <asm/time.h> 14#include <asm/time.h>
15#include <asm/hpet.h>
15 16
16#include <loongson.h> 17#include <loongson.h>
17#include <cs5536/cs5536_mfgpt.h> 18#include <cs5536/cs5536_mfgpt.h>
@@ -21,7 +22,11 @@ void __init plat_time_init(void)
21 /* setup mips r4k timer */ 22 /* setup mips r4k timer */
22 mips_hpt_frequency = cpu_clock_freq / 2; 23 mips_hpt_frequency = cpu_clock_freq / 2;
23 24
25#ifdef CONFIG_RS780_HPET
26 setup_hpet_timer();
27#else
24 setup_mfgpt0_timer(); 28 setup_mfgpt0_timer();
29#endif
25} 30}
26 31
27void read_persistent_clock(struct timespec *ts) 32void read_persistent_clock(struct timespec *ts)
diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c
index 1e1eeea73fde..9de559d58e1f 100644
--- a/arch/mips/loongson/common/uart_base.c
+++ b/arch/mips/loongson/common/uart_base.c
@@ -13,22 +13,27 @@
13 13
14#include <loongson.h> 14#include <loongson.h>
15 15
16/* ioremapped */
17unsigned long _loongson_uart_base;
18EXPORT_SYMBOL(_loongson_uart_base);
19/* raw */ 16/* raw */
20unsigned long loongson_uart_base; 17unsigned long loongson_uart_base[MAX_UARTS] = {};
18/* ioremapped */
19unsigned long _loongson_uart_base[MAX_UARTS] = {};
20
21EXPORT_SYMBOL(loongson_uart_base); 21EXPORT_SYMBOL(loongson_uart_base);
22EXPORT_SYMBOL(_loongson_uart_base);
22 23
23void prom_init_loongson_uart_base(void) 24void prom_init_loongson_uart_base(void)
24{ 25{
25 switch (mips_machtype) { 26 switch (mips_machtype) {
27 case MACH_LOONGSON_GENERIC:
28 /* The CPU provided serial port (CPU) */
29 loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0;
30 break;
26 case MACH_LEMOTE_FL2E: 31 case MACH_LEMOTE_FL2E:
27 loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8; 32 loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8;
28 break; 33 break;
29 case MACH_LEMOTE_FL2F: 34 case MACH_LEMOTE_FL2F:
30 case MACH_LEMOTE_LL2F: 35 case MACH_LEMOTE_LL2F:
31 loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8; 36 loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8;
32 break; 37 break;
33 case MACH_LEMOTE_ML2F7: 38 case MACH_LEMOTE_ML2F7:
34 case MACH_LEMOTE_YL2F89: 39 case MACH_LEMOTE_YL2F89:
@@ -36,17 +41,10 @@ void prom_init_loongson_uart_base(void)
36 case MACH_LEMOTE_NAS: 41 case MACH_LEMOTE_NAS:
37 default: 42 default:
38 /* The CPU provided serial port (LPC) */ 43 /* The CPU provided serial port (LPC) */
39 loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8; 44 loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8;
40 break;
41 case MACH_LEMOTE_A1004:
42 case MACH_LEMOTE_A1101:
43 case MACH_LEMOTE_A1201:
44 case MACH_LEMOTE_A1205:
45 /* The CPU provided serial port (CPU) */
46 loongson_uart_base = LOONGSON_REG_BASE + 0x1e0;
47 break; 45 break;
48 } 46 }
49 47
50 _loongson_uart_base = 48 _loongson_uart_base[0] =
51 (unsigned long)ioremap_nocache(loongson_uart_base, 8); 49 (unsigned long)ioremap_nocache(loongson_uart_base[0], 8);
52} 50}
diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c
index 6f8682e44483..cab5f43e0e29 100644
--- a/arch/mips/loongson/lemote-2f/irq.c
+++ b/arch/mips/loongson/lemote-2f/irq.c
@@ -93,13 +93,13 @@ static irqreturn_t ip6_action(int cpl, void *dev_id)
93 return IRQ_HANDLED; 93 return IRQ_HANDLED;
94} 94}
95 95
96struct irqaction ip6_irqaction = { 96static struct irqaction ip6_irqaction = {
97 .handler = ip6_action, 97 .handler = ip6_action,
98 .name = "cascade", 98 .name = "cascade",
99 .flags = IRQF_SHARED | IRQF_NO_THREAD, 99 .flags = IRQF_SHARED | IRQF_NO_THREAD,
100}; 100};
101 101
102struct irqaction cascade_irqaction = { 102static struct irqaction cascade_irqaction = {
103 .handler = no_action, 103 .handler = no_action,
104 .name = "cascade", 104 .name = "cascade",
105 .flags = IRQF_NO_THREAD, 105 .flags = IRQF_NO_THREAD,
diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c
index 79ac694fe744..a26ca7fcd7e0 100644
--- a/arch/mips/loongson/lemote-2f/reset.c
+++ b/arch/mips/loongson/lemote-2f/reset.c
@@ -76,7 +76,7 @@ static void fl2f_shutdown(void)
76 76
77/* reset support for yeeloong2f and mengloong2f notebook */ 77/* reset support for yeeloong2f and mengloong2f notebook */
78 78
79void ml2f_reboot(void) 79static void ml2f_reboot(void)
80{ 80{
81 reset_cpu(); 81 reset_cpu();
82 82
diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile
index b4df775b9f30..622fead5ebc9 100644
--- a/arch/mips/loongson/loongson-3/Makefile
+++ b/arch/mips/loongson/loongson-3/Makefile
@@ -1,8 +1,10 @@
1# 1#
2# Makefile for Loongson-3 family machines 2# Makefile for Loongson-3 family machines
3# 3#
4obj-y += irq.o cop2-ex.o 4obj-y += irq.o cop2-ex.o platform.o
5 5
6obj-$(CONFIG_SMP) += smp.o 6obj-$(CONFIG_SMP) += smp.o
7 7
8obj-$(CONFIG_NUMA) += numa.o 8obj-$(CONFIG_NUMA) += numa.o
9
10obj-$(CONFIG_RS780_HPET) += hpet.o
diff --git a/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c
new file mode 100644
index 000000000000..e898d68668a9
--- /dev/null
+++ b/arch/mips/loongson/loongson-3/hpet.c
@@ -0,0 +1,257 @@
1#include <linux/init.h>
2#include <linux/pci.h>
3#include <linux/percpu.h>
4#include <linux/delay.h>
5#include <linux/spinlock.h>
6#include <linux/interrupt.h>
7
8#include <asm/hpet.h>
9#include <asm/time.h>
10
11#define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000)
12#define SMBUS_PCI_REG40 0x40
13#define SMBUS_PCI_REG64 0x64
14#define SMBUS_PCI_REGB4 0xb4
15
16static DEFINE_SPINLOCK(hpet_lock);
17DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device);
18
19static unsigned int smbus_read(int offset)
20{
21 return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset);
22}
23
24static void smbus_write(int offset, int data)
25{
26 *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data;
27}
28
29static void smbus_enable(int offset, int bit)
30{
31 unsigned int cfg = smbus_read(offset);
32
33 cfg |= bit;
34 smbus_write(offset, cfg);
35}
36
37static int hpet_read(int offset)
38{
39 return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset);
40}
41
42static void hpet_write(int offset, int data)
43{
44 *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data;
45}
46
47static void hpet_start_counter(void)
48{
49 unsigned int cfg = hpet_read(HPET_CFG);
50
51 cfg |= HPET_CFG_ENABLE;
52 hpet_write(HPET_CFG, cfg);
53}
54
55static void hpet_stop_counter(void)
56{
57 unsigned int cfg = hpet_read(HPET_CFG);
58
59 cfg &= ~HPET_CFG_ENABLE;
60 hpet_write(HPET_CFG, cfg);
61}
62
63static void hpet_reset_counter(void)
64{
65 hpet_write(HPET_COUNTER, 0);
66 hpet_write(HPET_COUNTER + 4, 0);
67}
68
69static void hpet_restart_counter(void)
70{
71 hpet_stop_counter();
72 hpet_reset_counter();
73 hpet_start_counter();
74}
75
76static void hpet_enable_legacy_int(void)
77{
78 /* Do nothing on Loongson-3 */
79}
80
81static void hpet_set_mode(enum clock_event_mode mode,
82 struct clock_event_device *evt)
83{
84 int cfg = 0;
85
86 spin_lock(&hpet_lock);
87 switch (mode) {
88 case CLOCK_EVT_MODE_PERIODIC:
89 pr_info("set clock event to periodic mode!\n");
90 /* stop counter */
91 hpet_stop_counter();
92
93 /* enables the timer0 to generate a periodic interrupt */
94 cfg = hpet_read(HPET_T0_CFG);
95 cfg &= ~HPET_TN_LEVEL;
96 cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
97 HPET_TN_SETVAL | HPET_TN_32BIT;
98 hpet_write(HPET_T0_CFG, cfg);
99
100 /* set the comparator */
101 hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
102 udelay(1);
103 hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
104
105 /* start counter */
106 hpet_start_counter();
107 break;
108 case CLOCK_EVT_MODE_SHUTDOWN:
109 case CLOCK_EVT_MODE_UNUSED:
110 cfg = hpet_read(HPET_T0_CFG);
111 cfg &= ~HPET_TN_ENABLE;
112 hpet_write(HPET_T0_CFG, cfg);
113 break;
114 case CLOCK_EVT_MODE_ONESHOT:
115 pr_info("set clock event to one shot mode!\n");
116 cfg = hpet_read(HPET_T0_CFG);
117 /* set timer0 type
118 * 1 : periodic interrupt
119 * 0 : non-periodic(oneshot) interrupt
120 */
121 cfg &= ~HPET_TN_PERIODIC;
122 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
123 hpet_write(HPET_T0_CFG, cfg);
124 break;
125 case CLOCK_EVT_MODE_RESUME:
126 hpet_enable_legacy_int();
127 break;
128 }
129 spin_unlock(&hpet_lock);
130}
131
132static int hpet_next_event(unsigned long delta,
133 struct clock_event_device *evt)
134{
135 unsigned int cnt;
136 int res;
137
138 cnt = hpet_read(HPET_COUNTER);
139 cnt += delta;
140 hpet_write(HPET_T0_CMP, cnt);
141
142 res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0;
143 return res;
144}
145
146static irqreturn_t hpet_irq_handler(int irq, void *data)
147{
148 int is_irq;
149 struct clock_event_device *cd;
150 unsigned int cpu = smp_processor_id();
151
152 is_irq = hpet_read(HPET_STATUS);
153 if (is_irq & HPET_T0_IRS) {
154 /* clear the TIMER0 irq status register */
155 hpet_write(HPET_STATUS, HPET_T0_IRS);
156 cd = &per_cpu(hpet_clockevent_device, cpu);
157 cd->event_handler(cd);
158 return IRQ_HANDLED;
159 }
160 return IRQ_NONE;
161}
162
163static struct irqaction hpet_irq = {
164 .handler = hpet_irq_handler,
165 .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
166 .name = "hpet",
167};
168
169/*
170 * hpet address assignation and irq setting should be done in bios.
171 * but pmon don't do this, we just setup here directly.
172 * The operation under is normal. unfortunately, hpet_setup process
173 * is before pci initialize.
174 *
175 * {
176 * struct pci_dev *pdev;
177 *
178 * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL);
179 * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR);
180 *
181 * ...
182 * }
183 */
184static void hpet_setup(void)
185{
186 /* set hpet base address */
187 smbus_write(SMBUS_PCI_REGB4, HPET_ADDR);
188
189 /* enable decodeing of access to HPET MMIO*/
190 smbus_enable(SMBUS_PCI_REG40, (1 << 28));
191
192 /* HPET irq enable */
193 smbus_enable(SMBUS_PCI_REG64, (1 << 10));
194
195 hpet_enable_legacy_int();
196}
197
198void __init setup_hpet_timer(void)
199{
200 unsigned int cpu = smp_processor_id();
201 struct clock_event_device *cd;
202
203 hpet_setup();
204
205 cd = &per_cpu(hpet_clockevent_device, cpu);
206 cd->name = "hpet";
207 cd->rating = 320;
208 cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
209 cd->set_mode = hpet_set_mode;
210 cd->set_next_event = hpet_next_event;
211 cd->irq = HPET_T0_IRQ;
212 cd->cpumask = cpumask_of(cpu);
213 clockevent_set_clock(cd, HPET_FREQ);
214 cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
215 cd->min_delta_ns = 5000;
216
217 clockevents_register_device(cd);
218 setup_irq(HPET_T0_IRQ, &hpet_irq);
219 pr_info("hpet clock event device register\n");
220}
221
222static cycle_t hpet_read_counter(struct clocksource *cs)
223{
224 return (cycle_t)hpet_read(HPET_COUNTER);
225}
226
227static void hpet_suspend(struct clocksource *cs)
228{
229}
230
231static void hpet_resume(struct clocksource *cs)
232{
233 hpet_setup();
234 hpet_restart_counter();
235}
236
237static struct clocksource csrc_hpet = {
238 .name = "hpet",
239 /* mips clocksource rating is less than 300, so hpet is better. */
240 .rating = 300,
241 .read = hpet_read_counter,
242 .mask = CLOCKSOURCE_MASK(32),
243 /* oneshot mode work normal with this flag */
244 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
245 .suspend = hpet_suspend,
246 .resume = hpet_resume,
247 .mult = 0,
248 .shift = 10,
249};
250
251int __init init_hpet_clocksource(void)
252{
253 csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift);
254 return clocksource_register_hz(&csrc_hpet, HPET_FREQ);
255}
256
257arch_initcall(init_hpet_clocksource);
diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c
index ca1c62af5188..21221edda7a9 100644
--- a/arch/mips/loongson/loongson-3/irq.c
+++ b/arch/mips/loongson/loongson-3/irq.c
@@ -9,7 +9,7 @@
9 9
10#include "smp.h" 10#include "smp.h"
11 11
12unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; 12unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15};
13 13
14static void ht_irqdispatch(void) 14static void ht_irqdispatch(void)
15{ 15{
@@ -55,8 +55,8 @@ static inline void mask_loongson_irq(struct irq_data *d)
55 /* Workaround: UART IRQ may deliver to any core */ 55 /* Workaround: UART IRQ may deliver to any core */
56 if (d->irq == LOONGSON_UART_IRQ) { 56 if (d->irq == LOONGSON_UART_IRQ) {
57 int cpu = smp_processor_id(); 57 int cpu = smp_processor_id();
58 int node_id = cpu / loongson_sysconf.cores_per_node; 58 int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
59 int core_id = cpu % loongson_sysconf.cores_per_node; 59 int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
60 u64 intenclr_addr = smp_group[node_id] | 60 u64 intenclr_addr = smp_group[node_id] |
61 (u64)(&LOONGSON_INT_ROUTER_INTENCLR); 61 (u64)(&LOONGSON_INT_ROUTER_INTENCLR);
62 u64 introuter_lpc_addr = smp_group[node_id] | 62 u64 introuter_lpc_addr = smp_group[node_id] |
@@ -72,8 +72,8 @@ static inline void unmask_loongson_irq(struct irq_data *d)
72 /* Workaround: UART IRQ may deliver to any core */ 72 /* Workaround: UART IRQ may deliver to any core */
73 if (d->irq == LOONGSON_UART_IRQ) { 73 if (d->irq == LOONGSON_UART_IRQ) {
74 int cpu = smp_processor_id(); 74 int cpu = smp_processor_id();
75 int node_id = cpu / loongson_sysconf.cores_per_node; 75 int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
76 int core_id = cpu % loongson_sysconf.cores_per_node; 76 int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
77 u64 intenset_addr = smp_group[node_id] | 77 u64 intenset_addr = smp_group[node_id] |
78 (u64)(&LOONGSON_INT_ROUTER_INTENSET); 78 (u64)(&LOONGSON_INT_ROUTER_INTENSET);
79 u64 introuter_lpc_addr = smp_group[node_id] | 79 u64 introuter_lpc_addr = smp_group[node_id] |
@@ -102,10 +102,12 @@ void irq_router_init(void)
102 int i; 102 int i;
103 103
104 /* route LPC int to cpu core0 int 0 */ 104 /* route LPC int to cpu core0 int 0 */
105 LOONGSON_INT_ROUTER_LPC = LOONGSON_INT_CORE0_INT0; 105 LOONGSON_INT_ROUTER_LPC =
106 LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0);
106 /* route HT1 int0 ~ int7 to cpu core0 INT1*/ 107 /* route HT1 int0 ~ int7 to cpu core0 INT1*/
107 for (i = 0; i < 8; i++) 108 for (i = 0; i < 8; i++)
108 LOONGSON_INT_ROUTER_HT1(i) = LOONGSON_INT_CORE0_INT1; 109 LOONGSON_INT_ROUTER_HT1(i) =
110 LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1);
109 /* enable HT1 interrupt */ 111 /* enable HT1 interrupt */
110 LOONGSON_HT1_INTN_EN(0) = 0xffffffff; 112 LOONGSON_HT1_INTN_EN(0) = 0xffffffff;
111 /* enable router interrupt intenset */ 113 /* enable router interrupt intenset */
diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c
index 42323bcc5d28..6cae0e75de27 100644
--- a/arch/mips/loongson/loongson-3/numa.c
+++ b/arch/mips/loongson/loongson-3/numa.c
@@ -224,7 +224,7 @@ static void __init node_mem_init(unsigned int node)
224 224
225static __init void prom_meminit(void) 225static __init void prom_meminit(void)
226{ 226{
227 unsigned int node, cpu; 227 unsigned int node, cpu, active_cpu = 0;
228 228
229 cpu_node_probe(); 229 cpu_node_probe();
230 init_topology_matrix(); 230 init_topology_matrix();
@@ -240,8 +240,14 @@ static __init void prom_meminit(void)
240 node = cpu / loongson_sysconf.cores_per_node; 240 node = cpu / loongson_sysconf.cores_per_node;
241 if (node >= num_online_nodes()) 241 if (node >= num_online_nodes())
242 node = 0; 242 node = 0;
243 pr_info("NUMA: set cpumask cpu %d on node %d\n", cpu, node); 243
244 cpu_set(cpu, __node_data[(node)]->cpumask); 244 if (loongson_sysconf.reserved_cpus_mask & (1<<cpu))
245 continue;
246
247 cpu_set(active_cpu, __node_data[(node)]->cpumask);
248 pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node);
249
250 active_cpu++;
245 } 251 }
246} 252}
247 253
diff --git a/arch/mips/loongson/loongson-3/platform.c b/arch/mips/loongson/loongson-3/platform.c
new file mode 100644
index 000000000000..25a97cc0ee33
--- /dev/null
+++ b/arch/mips/loongson/loongson-3/platform.c
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2009 Lemote Inc.
3 * Author: Wu Zhangjin, wuzhangjin@gmail.com
4 * Xiang Yu, xiangy@lemote.com
5 * Chen Huacai, chenhc@lemote.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/err.h>
14#include <linux/slab.h>
15#include <linux/platform_device.h>
16#include <asm/bootinfo.h>
17#include <boot_param.h>
18#include <loongson_hwmon.h>
19#include <workarounds.h>
20
21static int __init loongson3_platform_init(void)
22{
23 int i;
24 struct platform_device *pdev;
25
26 if (loongson_sysconf.ecname[0] != '\0')
27 platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0);
28
29 for (i = 0; i < loongson_sysconf.nr_sensors; i++) {
30 if (loongson_sysconf.sensors[i].type > SENSOR_FAN)
31 continue;
32
33 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
34 pdev->name = loongson_sysconf.sensors[i].name;
35 pdev->id = loongson_sysconf.sensors[i].id;
36 pdev->dev.platform_data = &loongson_sysconf.sensors[i];
37 platform_device_register(pdev);
38 }
39
40 return 0;
41}
42
43arch_initcall(loongson3_platform_init);
diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c
index d8c63af6c7cc..e2eb688b5434 100644
--- a/arch/mips/loongson/loongson-3/smp.c
+++ b/arch/mips/loongson/loongson-3/smp.c
@@ -25,6 +25,7 @@
25#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
26#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
27#include <loongson.h> 27#include <loongson.h>
28#include <workarounds.h>
28 29
29#include "smp.h" 30#include "smp.h"
30 31
@@ -239,7 +240,7 @@ static void ipi_mailbox_buf_init(void)
239 */ 240 */
240static void loongson3_send_ipi_single(int cpu, unsigned int action) 241static void loongson3_send_ipi_single(int cpu, unsigned int action)
241{ 242{
242 loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu]); 243 loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]);
243} 244}
244 245
245static void 246static void
@@ -248,7 +249,7 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
248 unsigned int i; 249 unsigned int i;
249 250
250 for_each_cpu(i, mask) 251 for_each_cpu(i, mask)
251 loongson3_ipi_write32((u32)action, ipi_set0_regs[i]); 252 loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]);
252} 253}
253 254
254void loongson3_ipi_interrupt(struct pt_regs *regs) 255void loongson3_ipi_interrupt(struct pt_regs *regs)
@@ -257,10 +258,10 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
257 unsigned int action, c0count; 258 unsigned int action, c0count;
258 259
259 /* Load the ipi register to figure out what we're supposed to do */ 260 /* Load the ipi register to figure out what we're supposed to do */
260 action = loongson3_ipi_read32(ipi_status0_regs[cpu]); 261 action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]);
261 262
262 /* Clear the ipi register to clear the interrupt */ 263 /* Clear the ipi register to clear the interrupt */
263 loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu]); 264 loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]);
264 265
265 if (action & SMP_RESCHEDULE_YOURSELF) 266 if (action & SMP_RESCHEDULE_YOURSELF)
266 scheduler_ipi(); 267 scheduler_ipi();
@@ -291,12 +292,14 @@ static void loongson3_init_secondary(void)
291 /* Set interrupt mask, but don't enable */ 292 /* Set interrupt mask, but don't enable */
292 change_c0_status(ST0_IM, imask); 293 change_c0_status(ST0_IM, imask);
293 294
294 for (i = 0; i < loongson_sysconf.nr_cpus; i++) 295 for (i = 0; i < num_possible_cpus(); i++)
295 loongson3_ipi_write32(0xffffffff, ipi_en0_regs[i]); 296 loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]);
296 297
297 cpu_data[cpu].package = cpu / loongson_sysconf.cores_per_package;
298 cpu_data[cpu].core = cpu % loongson_sysconf.cores_per_package;
299 per_cpu(cpu_state, cpu) = CPU_ONLINE; 298 per_cpu(cpu_state, cpu) = CPU_ONLINE;
299 cpu_data[cpu].core =
300 cpu_logical_map(cpu) % loongson_sysconf.cores_per_package;
301 cpu_data[cpu].package =
302 cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
300 303
301 i = 0; 304 i = 0;
302 __this_cpu_write(core0_c0count, 0); 305 __this_cpu_write(core0_c0count, 0);
@@ -314,37 +317,50 @@ static void loongson3_init_secondary(void)
314 317
315static void loongson3_smp_finish(void) 318static void loongson3_smp_finish(void)
316{ 319{
320 int cpu = smp_processor_id();
321
317 write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); 322 write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
318 local_irq_enable(); 323 local_irq_enable();
319 loongson3_ipi_write64(0, 324 loongson3_ipi_write64(0,
320 (void *)(ipi_mailbox_buf[smp_processor_id()]+0x0)); 325 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
321 pr_info("CPU#%d finished, CP0_ST=%x\n", 326 pr_info("CPU#%d finished, CP0_ST=%x\n",
322 smp_processor_id(), read_c0_status()); 327 smp_processor_id(), read_c0_status());
323} 328}
324 329
325static void __init loongson3_smp_setup(void) 330static void __init loongson3_smp_setup(void)
326{ 331{
327 int i, num; 332 int i = 0, num = 0; /* i: physical id, num: logical id */
328 333
329 init_cpu_possible(cpu_none_mask); 334 init_cpu_possible(cpu_none_mask);
330 set_cpu_possible(0, true);
331
332 __cpu_number_map[0] = 0;
333 __cpu_logical_map[0] = 0;
334 335
335 /* For unified kernel, NR_CPUS is the maximum possible value, 336 /* For unified kernel, NR_CPUS is the maximum possible value,
336 * loongson_sysconf.nr_cpus is the really present value */ 337 * loongson_sysconf.nr_cpus is the really present value */
337 for (i = 1, num = 0; i < loongson_sysconf.nr_cpus; i++) { 338 while (i < loongson_sysconf.nr_cpus) {
338 set_cpu_possible(i, true); 339 if (loongson_sysconf.reserved_cpus_mask & (1<<i)) {
339 __cpu_number_map[i] = ++num; 340 /* Reserved physical CPU cores */
340 __cpu_logical_map[num] = i; 341 __cpu_number_map[i] = -1;
342 } else {
343 __cpu_number_map[i] = num;
344 __cpu_logical_map[num] = i;
345 set_cpu_possible(num, true);
346 num++;
347 }
348 i++;
341 } 349 }
350 pr_info("Detected %i available CPU(s)\n", num);
351
352 while (num < loongson_sysconf.nr_cpus) {
353 __cpu_logical_map[num] = -1;
354 num++;
355 }
356
342 ipi_set0_regs_init(); 357 ipi_set0_regs_init();
343 ipi_clear0_regs_init(); 358 ipi_clear0_regs_init();
344 ipi_status0_regs_init(); 359 ipi_status0_regs_init();
345 ipi_en0_regs_init(); 360 ipi_en0_regs_init();
346 ipi_mailbox_buf_init(); 361 ipi_mailbox_buf_init();
347 pr_info("Detected %i available secondary CPU(s)\n", num); 362 cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
363 cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
348} 364}
349 365
350static void __init loongson3_prepare_cpus(unsigned int max_cpus) 366static void __init loongson3_prepare_cpus(unsigned int max_cpus)
@@ -371,10 +387,14 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle)
371 pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n", 387 pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n",
372 cpu, startargs[0], startargs[1], startargs[2]); 388 cpu, startargs[0], startargs[1], startargs[2]);
373 389
374 loongson3_ipi_write64(startargs[3], (void *)(ipi_mailbox_buf[cpu]+0x18)); 390 loongson3_ipi_write64(startargs[3],
375 loongson3_ipi_write64(startargs[2], (void *)(ipi_mailbox_buf[cpu]+0x10)); 391 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x18));
376 loongson3_ipi_write64(startargs[1], (void *)(ipi_mailbox_buf[cpu]+0x8)); 392 loongson3_ipi_write64(startargs[2],
377 loongson3_ipi_write64(startargs[0], (void *)(ipi_mailbox_buf[cpu]+0x0)); 393 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x10));
394 loongson3_ipi_write64(startargs[1],
395 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8));
396 loongson3_ipi_write64(startargs[0],
397 (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
378} 398}
379 399
380#ifdef CONFIG_HOTPLUG_CPU 400#ifdef CONFIG_HOTPLUG_CPU
@@ -568,7 +588,7 @@ void loongson3_disable_clock(int cpu)
568 if (loongson_sysconf.cputype == Loongson_3A) { 588 if (loongson_sysconf.cputype == Loongson_3A) {
569 LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); 589 LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
570 } else if (loongson_sysconf.cputype == Loongson_3B) { 590 } else if (loongson_sysconf.cputype == Loongson_3B) {
571 if (!cpuhotplug_workaround) 591 if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
572 LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); 592 LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
573 } 593 }
574} 594}
@@ -581,7 +601,7 @@ void loongson3_enable_clock(int cpu)
581 if (loongson_sysconf.cputype == Loongson_3A) { 601 if (loongson_sysconf.cputype == Loongson_3A) {
582 LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); 602 LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
583 } else if (loongson_sysconf.cputype == Loongson_3B) { 603 } else if (loongson_sysconf.cputype == Loongson_3B) {
584 if (!cpuhotplug_workaround) 604 if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
585 LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); 605 LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
586 } 606 }
587} 607}
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig
index e23c25d09963..a2b796eaf3c3 100644
--- a/arch/mips/loongson1/Kconfig
+++ b/arch/mips/loongson1/Kconfig
@@ -5,8 +5,8 @@ choice
5 5
6config LOONGSON1_LS1B 6config LOONGSON1_LS1B
7 bool "Loongson LS1B board" 7 bool "Loongson LS1B board"
8 select CEVT_R4K 8 select CEVT_R4K if !MIPS_EXTERNAL_TIMER
9 select CSRC_R4K 9 select CSRC_R4K if !MIPS_EXTERNAL_TIMER
10 select SYS_HAS_CPU_LOONGSON1B 10 select SYS_HAS_CPU_LOONGSON1B
11 select DMA_NONCOHERENT 11 select DMA_NONCOHERENT
12 select BOOT_ELF32 12 select BOOT_ELF32
@@ -16,8 +16,46 @@ config LOONGSON1_LS1B
16 select SYS_SUPPORTS_HIGHMEM 16 select SYS_SUPPORTS_HIGHMEM
17 select SYS_SUPPORTS_MIPS16 17 select SYS_SUPPORTS_MIPS16
18 select SYS_HAS_EARLY_PRINTK 18 select SYS_HAS_EARLY_PRINTK
19 select USE_GENERIC_EARLY_PRINTK_8250
19 select COMMON_CLK 20 select COMMON_CLK
20 21
21endchoice 22endchoice
22 23
24menuconfig CEVT_CSRC_LS1X
25 bool "Use PWM Timer for clockevent/clocksource"
26 select MIPS_EXTERNAL_TIMER
27 depends on CPU_LOONGSON1
28 help
29 This option changes the default clockevent/clocksource to PWM Timer,
30 and is required by Loongson1 CPUFreq support.
31
32 If unsure, say N.
33
34choice
35 prompt "Select clockevent/clocksource"
36 depends on CEVT_CSRC_LS1X
37 default TIMER_USE_PWM0
38
39config TIMER_USE_PWM0
40 bool "Use PWM Timer 0"
41 help
42 Use PWM Timer 0 as the default clockevent/clocksourcer.
43
44config TIMER_USE_PWM1
45 bool "Use PWM Timer 1"
46 help
47 Use PWM Timer 1 as the default clockevent/clocksourcer.
48
49config TIMER_USE_PWM2
50 bool "Use PWM Timer 2"
51 help
52 Use PWM Timer 2 as the default clockevent/clocksourcer.
53
54config TIMER_USE_PWM3
55 bool "Use PWM Timer 3"
56 help
57 Use PWM Timer 3 as the default clockevent/clocksourcer.
58
59endchoice
60
23endif # MACH_LOONGSON1 61endif # MACH_LOONGSON1
diff --git a/arch/mips/loongson1/common/Makefile b/arch/mips/loongson1/common/Makefile
index b2797709ef5b..723b4ce3b8f0 100644
--- a/arch/mips/loongson1/common/Makefile
+++ b/arch/mips/loongson1/common/Makefile
@@ -2,4 +2,4 @@
2# Makefile for common code of loongson1 based machines. 2# Makefile for common code of loongson1 based machines.
3# 3#
4 4
5obj-y += clock.o irq.o platform.o prom.o reset.o setup.o 5obj-y += time.o irq.o platform.o prom.o reset.o setup.o
diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c
deleted file mode 100644
index b4437f19c3d9..000000000000
--- a/arch/mips/loongson1/common/clock.c
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clk.h>
11#include <linux/err.h>
12#include <asm/time.h>
13#include <platform.h>
14
15void __init plat_time_init(void)
16{
17 struct clk *clk;
18
19 /* Initialize LS1X clocks */
20 ls1x_clk_init();
21
22 /* setup mips r4k timer */
23 clk = clk_get(NULL, "cpu");
24 if (IS_ERR(clk))
25 panic("unable to get cpu clock, err=%ld", PTR_ERR(clk));
26
27 mips_hpt_frequency = clk_get_rate(clk) / 2;
28}
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c
index fdf8cb5987a4..ddf1d4cbf31e 100644
--- a/arch/mips/loongson1/common/platform.c
+++ b/arch/mips/loongson1/common/platform.c
@@ -16,8 +16,10 @@
16#include <linux/usb/ehci_pdriver.h> 16#include <linux/usb/ehci_pdriver.h>
17#include <asm-generic/sizes.h> 17#include <asm-generic/sizes.h>
18 18
19#include <cpufreq.h>
19#include <loongson1.h> 20#include <loongson1.h>
20 21
22/* 8250/16550 compatible UART */
21#define LS1X_UART(_id) \ 23#define LS1X_UART(_id) \
22 { \ 24 { \
23 .mapbase = LS1X_UART ## _id ## _BASE, \ 25 .mapbase = LS1X_UART ## _id ## _BASE, \
@@ -27,7 +29,7 @@
27 .type = PORT_16550A, \ 29 .type = PORT_16550A, \
28 } 30 }
29 31
30static struct plat_serial8250_port ls1x_serial8250_port[] = { 32static struct plat_serial8250_port ls1x_serial8250_pdata[] = {
31 LS1X_UART(0), 33 LS1X_UART(0),
32 LS1X_UART(1), 34 LS1X_UART(1),
33 LS1X_UART(2), 35 LS1X_UART(2),
@@ -35,11 +37,11 @@ static struct plat_serial8250_port ls1x_serial8250_port[] = {
35 {}, 37 {},
36}; 38};
37 39
38struct platform_device ls1x_uart_device = { 40struct platform_device ls1x_uart_pdev = {
39 .name = "serial8250", 41 .name = "serial8250",
40 .id = PLAT8250_DEV_PLATFORM, 42 .id = PLAT8250_DEV_PLATFORM,
41 .dev = { 43 .dev = {
42 .platform_data = ls1x_serial8250_port, 44 .platform_data = ls1x_serial8250_pdata,
43 }, 45 },
44}; 46};
45 47
@@ -48,16 +50,97 @@ void __init ls1x_serial_setup(struct platform_device *pdev)
48 struct clk *clk; 50 struct clk *clk;
49 struct plat_serial8250_port *p; 51 struct plat_serial8250_port *p;
50 52
51 clk = clk_get(NULL, pdev->name); 53 clk = clk_get(&pdev->dev, pdev->name);
52 if (IS_ERR(clk)) 54 if (IS_ERR(clk)) {
53 panic("unable to get %s clock, err=%ld", 55 pr_err("unable to get %s clock, err=%ld",
54 pdev->name, PTR_ERR(clk)); 56 pdev->name, PTR_ERR(clk));
57 return;
58 }
59 clk_prepare_enable(clk);
55 60
56 for (p = pdev->dev.platform_data; p->flags != 0; ++p) 61 for (p = pdev->dev.platform_data; p->flags != 0; ++p)
57 p->uartclk = clk_get_rate(clk); 62 p->uartclk = clk_get_rate(clk);
58} 63}
59 64
65/* CPUFreq */
66static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = {
67 .clk_name = "cpu_clk",
68 .osc_clk_name = "osc_33m_clk",
69 .max_freq = 266 * 1000,
70 .min_freq = 33 * 1000,
71};
72
73struct platform_device ls1x_cpufreq_pdev = {
74 .name = "ls1x-cpufreq",
75 .dev = {
76 .platform_data = &ls1x_cpufreq_pdata,
77 },
78};
79
60/* Synopsys Ethernet GMAC */ 80/* Synopsys Ethernet GMAC */
81static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
82 .phy_mask = 0,
83};
84
85static struct stmmac_dma_cfg ls1x_eth_dma_cfg = {
86 .pbl = 1,
87};
88
89int ls1x_eth_mux_init(struct platform_device *pdev, void *priv)
90{
91 struct plat_stmmacenet_data *plat_dat = NULL;
92 u32 val;
93
94 val = __raw_readl(LS1X_MUX_CTRL1);
95
96 plat_dat = dev_get_platdata(&pdev->dev);
97 if (plat_dat->bus_id) {
98 __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 |
99 GMAC1_USE_UART0, LS1X_MUX_CTRL0);
100 switch (plat_dat->interface) {
101 case PHY_INTERFACE_MODE_RGMII:
102 val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
103 break;
104 case PHY_INTERFACE_MODE_MII:
105 val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
106 break;
107 default:
108 pr_err("unsupported mii mode %d\n",
109 plat_dat->interface);
110 return -ENOTSUPP;
111 }
112 val &= ~GMAC1_SHUT;
113 } else {
114 switch (plat_dat->interface) {
115 case PHY_INTERFACE_MODE_RGMII:
116 val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
117 break;
118 case PHY_INTERFACE_MODE_MII:
119 val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
120 break;
121 default:
122 pr_err("unsupported mii mode %d\n",
123 plat_dat->interface);
124 return -ENOTSUPP;
125 }
126 val &= ~GMAC0_SHUT;
127 }
128 __raw_writel(val, LS1X_MUX_CTRL1);
129
130 return 0;
131}
132
133static struct plat_stmmacenet_data ls1x_eth0_pdata = {
134 .bus_id = 0,
135 .phy_addr = -1,
136 .interface = PHY_INTERFACE_MODE_MII,
137 .mdio_bus_data = &ls1x_mdio_bus_data,
138 .dma_cfg = &ls1x_eth_dma_cfg,
139 .has_gmac = 1,
140 .tx_coe = 1,
141 .init = ls1x_eth_mux_init,
142};
143
61static struct resource ls1x_eth0_resources[] = { 144static struct resource ls1x_eth0_resources[] = {
62 [0] = { 145 [0] = {
63 .start = LS1X_GMAC0_BASE, 146 .start = LS1X_GMAC0_BASE,
@@ -71,25 +154,47 @@ static struct resource ls1x_eth0_resources[] = {
71 }, 154 },
72}; 155};
73 156
74static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { 157struct platform_device ls1x_eth0_pdev = {
75 .phy_mask = 0, 158 .name = "stmmaceth",
159 .id = 0,
160 .num_resources = ARRAY_SIZE(ls1x_eth0_resources),
161 .resource = ls1x_eth0_resources,
162 .dev = {
163 .platform_data = &ls1x_eth0_pdata,
164 },
76}; 165};
77 166
78static struct plat_stmmacenet_data ls1x_eth_data = { 167static struct plat_stmmacenet_data ls1x_eth1_pdata = {
79 .bus_id = 0, 168 .bus_id = 1,
80 .phy_addr = -1, 169 .phy_addr = -1,
170 .interface = PHY_INTERFACE_MODE_MII,
81 .mdio_bus_data = &ls1x_mdio_bus_data, 171 .mdio_bus_data = &ls1x_mdio_bus_data,
172 .dma_cfg = &ls1x_eth_dma_cfg,
82 .has_gmac = 1, 173 .has_gmac = 1,
83 .tx_coe = 1, 174 .tx_coe = 1,
175 .init = ls1x_eth_mux_init,
84}; 176};
85 177
86struct platform_device ls1x_eth0_device = { 178static struct resource ls1x_eth1_resources[] = {
179 [0] = {
180 .start = LS1X_GMAC1_BASE,
181 .end = LS1X_GMAC1_BASE + SZ_64K - 1,
182 .flags = IORESOURCE_MEM,
183 },
184 [1] = {
185 .name = "macirq",
186 .start = LS1X_GMAC1_IRQ,
187 .flags = IORESOURCE_IRQ,
188 },
189};
190
191struct platform_device ls1x_eth1_pdev = {
87 .name = "stmmaceth", 192 .name = "stmmaceth",
88 .id = 0, 193 .id = 1,
89 .num_resources = ARRAY_SIZE(ls1x_eth0_resources), 194 .num_resources = ARRAY_SIZE(ls1x_eth1_resources),
90 .resource = ls1x_eth0_resources, 195 .resource = ls1x_eth1_resources,
91 .dev = { 196 .dev = {
92 .platform_data = &ls1x_eth_data, 197 .platform_data = &ls1x_eth1_pdata,
93 }, 198 },
94}; 199};
95 200
@@ -111,7 +216,7 @@ static struct resource ls1x_ehci_resources[] = {
111static struct usb_ehci_pdata ls1x_ehci_pdata = { 216static struct usb_ehci_pdata ls1x_ehci_pdata = {
112}; 217};
113 218
114struct platform_device ls1x_ehci_device = { 219struct platform_device ls1x_ehci_pdev = {
115 .name = "ehci-platform", 220 .name = "ehci-platform",
116 .id = -1, 221 .id = -1,
117 .num_resources = ARRAY_SIZE(ls1x_ehci_resources), 222 .num_resources = ARRAY_SIZE(ls1x_ehci_resources),
@@ -123,7 +228,7 @@ struct platform_device ls1x_ehci_device = {
123}; 228};
124 229
125/* Real Time Clock */ 230/* Real Time Clock */
126struct platform_device ls1x_rtc_device = { 231struct platform_device ls1x_rtc_pdev = {
127 .name = "ls1x-rtc", 232 .name = "ls1x-rtc",
128 .id = -1, 233 .id = -1,
129}; 234};
diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c
index 2a47af5a55c3..68600980ea49 100644
--- a/arch/mips/loongson1/common/prom.c
+++ b/arch/mips/loongson1/common/prom.c
@@ -27,7 +27,7 @@ char *prom_getenv(char *envname)
27 i = strlen(envname); 27 i = strlen(envname);
28 28
29 while (*env) { 29 while (*env) {
30 if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=') 30 if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=')
31 return *env + i + 1; 31 return *env + i + 1;
32 env++; 32 env++;
33 } 33 }
@@ -49,7 +49,7 @@ void __init prom_init_cmdline(void)
49 for (i = 1; i < prom_argc; i++) { 49 for (i = 1; i < prom_argc; i++) {
50 strcpy(c, prom_argv[i]); 50 strcpy(c, prom_argv[i]);
51 c += strlen(prom_argv[i]); 51 c += strlen(prom_argv[i]);
52 if (i < prom_argc-1) 52 if (i < prom_argc - 1)
53 *c++ = ' '; 53 *c++ = ' ';
54 } 54 }
55 *c = 0; 55 *c = 0;
@@ -57,6 +57,7 @@ void __init prom_init_cmdline(void)
57 57
58void __init prom_init(void) 58void __init prom_init(void)
59{ 59{
60 void __iomem *uart_base;
60 prom_argc = fw_arg0; 61 prom_argc = fw_arg0;
61 prom_argv = (char **)fw_arg1; 62 prom_argv = (char **)fw_arg1;
62 prom_envp = (char **)fw_arg2; 63 prom_envp = (char **)fw_arg2;
@@ -65,23 +66,18 @@ void __init prom_init(void)
65 66
66 memsize = env_or_default("memsize", DEFAULT_MEMSIZE); 67 memsize = env_or_default("memsize", DEFAULT_MEMSIZE);
67 highmemsize = env_or_default("highmemsize", 0x0); 68 highmemsize = env_or_default("highmemsize", 0x0);
68}
69 69
70void __init prom_free_prom_memory(void) 70 if (strstr(arcs_cmdline, "console=ttyS3"))
71{ 71 uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f);
72 else if (strstr(arcs_cmdline, "console=ttyS2"))
73 uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f);
74 else if (strstr(arcs_cmdline, "console=ttyS1"))
75 uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f);
76 else
77 uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f);
78 setup_8250_early_printk_port((unsigned long)uart_base, 0, 0);
72} 79}
73 80
74#define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset)) 81void __init prom_free_prom_memory(void)
75
76void prom_putchar(char c)
77{ 82{
78 int timeout;
79
80 timeout = 1024;
81
82 while (((readb(PORT(UART_LSR)) & UART_LSR_THRE) == 0)
83 && (timeout-- > 0))
84 ;
85
86 writeb(c, PORT(UART_TX));
87} 83}
diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c
index 547f34b69e4c..c41e4ca56ab4 100644
--- a/arch/mips/loongson1/common/reset.c
+++ b/arch/mips/loongson1/common/reset.c
@@ -14,12 +14,7 @@
14 14
15#include <loongson1.h> 15#include <loongson1.h>
16 16
17static void ls1x_restart(char *command) 17static void __iomem *wdt_base;
18{
19 __raw_writel(0x1, LS1X_WDT_EN);
20 __raw_writel(0x5000000, LS1X_WDT_TIMER);
21 __raw_writel(0x1, LS1X_WDT_SET);
22}
23 18
24static void ls1x_halt(void) 19static void ls1x_halt(void)
25{ 20{
@@ -29,6 +24,15 @@ static void ls1x_halt(void)
29 } 24 }
30} 25}
31 26
27static void ls1x_restart(char *command)
28{
29 __raw_writel(0x1, wdt_base + WDT_EN);
30 __raw_writel(0x1, wdt_base + WDT_TIMER);
31 __raw_writel(0x1, wdt_base + WDT_SET);
32
33 ls1x_halt();
34}
35
32static void ls1x_power_off(void) 36static void ls1x_power_off(void)
33{ 37{
34 ls1x_halt(); 38 ls1x_halt();
@@ -36,6 +40,10 @@ static void ls1x_power_off(void)
36 40
37static int __init ls1x_reboot_setup(void) 41static int __init ls1x_reboot_setup(void)
38{ 42{
43 wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f);
44 if (!wdt_base)
45 panic("Failed to remap watchdog registers");
46
39 _machine_restart = ls1x_restart; 47 _machine_restart = ls1x_restart;
40 _machine_halt = ls1x_halt; 48 _machine_halt = ls1x_halt;
41 pm_power_off = ls1x_power_off; 49 pm_power_off = ls1x_power_off;
diff --git a/arch/mips/loongson1/common/time.c b/arch/mips/loongson1/common/time.c
new file mode 100644
index 000000000000..df0f850d6a5f
--- /dev/null
+++ b/arch/mips/loongson1/common/time.c
@@ -0,0 +1,226 @@
1/*
2 * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include <linux/clk.h>
11#include <linux/interrupt.h>
12#include <asm/time.h>
13
14#include <loongson1.h>
15#include <platform.h>
16
17#ifdef CONFIG_CEVT_CSRC_LS1X
18
19#if defined(CONFIG_TIMER_USE_PWM1)
20#define LS1X_TIMER_BASE LS1X_PWM1_BASE
21#define LS1X_TIMER_IRQ LS1X_PWM1_IRQ
22
23#elif defined(CONFIG_TIMER_USE_PWM2)
24#define LS1X_TIMER_BASE LS1X_PWM2_BASE
25#define LS1X_TIMER_IRQ LS1X_PWM2_IRQ
26
27#elif defined(CONFIG_TIMER_USE_PWM3)
28#define LS1X_TIMER_BASE LS1X_PWM3_BASE
29#define LS1X_TIMER_IRQ LS1X_PWM3_IRQ
30
31#else
32#define LS1X_TIMER_BASE LS1X_PWM0_BASE
33#define LS1X_TIMER_IRQ LS1X_PWM0_IRQ
34#endif
35
36DEFINE_RAW_SPINLOCK(ls1x_timer_lock);
37
38static void __iomem *timer_base;
39static uint32_t ls1x_jiffies_per_tick;
40
41static inline void ls1x_pwmtimer_set_period(uint32_t period)
42{
43 __raw_writel(period, timer_base + PWM_HRC);
44 __raw_writel(period, timer_base + PWM_LRC);
45}
46
47static inline void ls1x_pwmtimer_restart(void)
48{
49 __raw_writel(0x0, timer_base + PWM_CNT);
50 __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
51}
52
53void __init ls1x_pwmtimer_init(void)
54{
55 timer_base = ioremap(LS1X_TIMER_BASE, 0xf);
56 if (!timer_base)
57 panic("Failed to remap timer registers");
58
59 ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ);
60
61 ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
62 ls1x_pwmtimer_restart();
63}
64
65static cycle_t ls1x_clocksource_read(struct clocksource *cs)
66{
67 unsigned long flags;
68 int count;
69 u32 jifs;
70 static int old_count;
71 static u32 old_jifs;
72
73 raw_spin_lock_irqsave(&ls1x_timer_lock, flags);
74 /*
75 * Although our caller may have the read side of xtime_lock,
76 * this is now a seqlock, and we are cheating in this routine
77 * by having side effects on state that we cannot undo if
78 * there is a collision on the seqlock and our caller has to
79 * retry. (Namely, old_jifs and old_count.) So we must treat
80 * jiffies as volatile despite the lock. We read jiffies
81 * before latching the timer count to guarantee that although
82 * the jiffies value might be older than the count (that is,
83 * the counter may underflow between the last point where
84 * jiffies was incremented and the point where we latch the
85 * count), it cannot be newer.
86 */
87 jifs = jiffies;
88 /* read the count */
89 count = __raw_readl(timer_base + PWM_CNT);
90
91 /*
92 * It's possible for count to appear to go the wrong way for this
93 * reason:
94 *
95 * The timer counter underflows, but we haven't handled the resulting
96 * interrupt and incremented jiffies yet.
97 *
98 * Previous attempts to handle these cases intelligently were buggy, so
99 * we just do the simple thing now.
100 */
101 if (count < old_count && jifs == old_jifs)
102 count = old_count;
103
104 old_count = count;
105 old_jifs = jifs;
106
107 raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags);
108
109 return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count;
110}
111
112static struct clocksource ls1x_clocksource = {
113 .name = "ls1x-pwmtimer",
114 .read = ls1x_clocksource_read,
115 .mask = CLOCKSOURCE_MASK(24),
116 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
117};
118
119static irqreturn_t ls1x_clockevent_isr(int irq, void *devid)
120{
121 struct clock_event_device *cd = devid;
122
123 ls1x_pwmtimer_restart();
124 cd->event_handler(cd);
125
126 return IRQ_HANDLED;
127}
128
129static void ls1x_clockevent_set_mode(enum clock_event_mode mode,
130 struct clock_event_device *cd)
131{
132 raw_spin_lock(&ls1x_timer_lock);
133 switch (mode) {
134 case CLOCK_EVT_MODE_PERIODIC:
135 ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
136 ls1x_pwmtimer_restart();
137 case CLOCK_EVT_MODE_RESUME:
138 __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
139 break;
140 case CLOCK_EVT_MODE_ONESHOT:
141 case CLOCK_EVT_MODE_SHUTDOWN:
142 __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN,
143 timer_base + PWM_CTRL);
144 break;
145 default:
146 break;
147 }
148 raw_spin_unlock(&ls1x_timer_lock);
149}
150
151static int ls1x_clockevent_set_next(unsigned long evt,
152 struct clock_event_device *cd)
153{
154 raw_spin_lock(&ls1x_timer_lock);
155 ls1x_pwmtimer_set_period(evt);
156 ls1x_pwmtimer_restart();
157 raw_spin_unlock(&ls1x_timer_lock);
158
159 return 0;
160}
161
162static struct clock_event_device ls1x_clockevent = {
163 .name = "ls1x-pwmtimer",
164 .features = CLOCK_EVT_FEAT_PERIODIC,
165 .rating = 300,
166 .irq = LS1X_TIMER_IRQ,
167 .set_next_event = ls1x_clockevent_set_next,
168 .set_mode = ls1x_clockevent_set_mode,
169};
170
171static struct irqaction ls1x_pwmtimer_irqaction = {
172 .name = "ls1x-pwmtimer",
173 .handler = ls1x_clockevent_isr,
174 .dev_id = &ls1x_clockevent,
175 .flags = IRQF_PERCPU | IRQF_TIMER,
176};
177
178static void __init ls1x_time_init(void)
179{
180 struct clock_event_device *cd = &ls1x_clockevent;
181 int ret;
182
183 if (!mips_hpt_frequency)
184 panic("Invalid timer clock rate");
185
186 ls1x_pwmtimer_init();
187
188 clockevent_set_clock(cd, mips_hpt_frequency);
189 cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd);
190 cd->min_delta_ns = clockevent_delta2ns(0x000300, cd);
191 cd->cpumask = cpumask_of(smp_processor_id());
192 clockevents_register_device(cd);
193
194 ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000;
195 ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency);
196 if (ret)
197 panic(KERN_ERR "Failed to register clocksource: %d\n", ret);
198
199 setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction);
200}
201#endif /* CONFIG_CEVT_CSRC_LS1X */
202
203void __init plat_time_init(void)
204{
205 struct clk *clk = NULL;
206
207 /* initialize LS1X clocks */
208 ls1x_clk_init();
209
210#ifdef CONFIG_CEVT_CSRC_LS1X
211 /* setup LS1X PWM timer */
212 clk = clk_get(NULL, "ls1x_pwmtimer");
213 if (IS_ERR(clk))
214 panic("unable to get timer clock, err=%ld", PTR_ERR(clk));
215
216 mips_hpt_frequency = clk_get_rate(clk);
217 ls1x_time_init();
218#else
219 /* setup mips r4k timer */
220 clk = clk_get(NULL, "cpu_clk");
221 if (IS_ERR(clk))
222 panic("unable to get cpu clock, err=%ld", PTR_ERR(clk));
223
224 mips_hpt_frequency = clk_get_rate(clk) / 2;
225#endif /* CONFIG_CEVT_CSRC_LS1X */
226}
diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c
index b26b10dac70a..58daeea25739 100644
--- a/arch/mips/loongson1/ls1b/board.c
+++ b/arch/mips/loongson1/ls1b/board.c
@@ -10,17 +10,19 @@
10#include <platform.h> 10#include <platform.h>
11 11
12static struct platform_device *ls1b_platform_devices[] __initdata = { 12static struct platform_device *ls1b_platform_devices[] __initdata = {
13 &ls1x_uart_device, 13 &ls1x_uart_pdev,
14 &ls1x_eth0_device, 14 &ls1x_cpufreq_pdev,
15 &ls1x_ehci_device, 15 &ls1x_eth0_pdev,
16 &ls1x_rtc_device, 16 &ls1x_eth1_pdev,
17 &ls1x_ehci_pdev,
18 &ls1x_rtc_pdev,
17}; 19};
18 20
19static int __init ls1b_platform_init(void) 21static int __init ls1b_platform_init(void)
20{ 22{
21 int err; 23 int err;
22 24
23 ls1x_serial_setup(&ls1x_uart_device); 25 ls1x_serial_setup(&ls1x_uart_pdev);
24 26
25 err = platform_add_devices(ls1b_platform_devices, 27 err = platform_add_devices(ls1b_platform_devices,
26 ARRAY_SIZE(ls1b_platform_devices)); 28 ARRAY_SIZE(ls1b_platform_devices));
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index cac529a405b8..9dfcd7fc1bc3 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -643,9 +643,14 @@ static inline int cop1_64bit(struct pt_regs *xcp)
643 return !test_thread_flag(TIF_32BIT_FPREGS); 643 return !test_thread_flag(TIF_32BIT_FPREGS);
644} 644}
645 645
646static inline bool hybrid_fprs(void)
647{
648 return test_thread_flag(TIF_HYBRID_FPREGS);
649}
650
646#define SIFROMREG(si, x) \ 651#define SIFROMREG(si, x) \
647do { \ 652do { \
648 if (cop1_64bit(xcp)) \ 653 if (cop1_64bit(xcp) && !hybrid_fprs()) \
649 (si) = (int)get_fpr32(&ctx->fpr[x], 0); \ 654 (si) = (int)get_fpr32(&ctx->fpr[x], 0); \
650 else \ 655 else \
651 (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \ 656 (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \
@@ -653,7 +658,7 @@ do { \
653 658
654#define SITOREG(si, x) \ 659#define SITOREG(si, x) \
655do { \ 660do { \
656 if (cop1_64bit(xcp)) { \ 661 if (cop1_64bit(xcp) && !hybrid_fprs()) { \
657 unsigned i; \ 662 unsigned i; \
658 set_fpr32(&ctx->fpr[x], 0, si); \ 663 set_fpr32(&ctx->fpr[x], 0, si); \
659 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \ 664 for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c
index fd134675fc2e..068f45a415fc 100644
--- a/arch/mips/math-emu/ieee754dp.c
+++ b/arch/mips/math-emu/ieee754dp.c
@@ -38,7 +38,7 @@ int ieee754dp_isnan(union ieee754dp x)
38static inline int ieee754dp_issnan(union ieee754dp x) 38static inline int ieee754dp_issnan(union ieee754dp x)
39{ 39{
40 assert(ieee754dp_isnan(x)); 40 assert(ieee754dp_isnan(x));
41 return ((DPMANT(x) & DP_MBIT(DP_FBITS-1)) == DP_MBIT(DP_FBITS-1)); 41 return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1);
42} 42}
43 43
44 44
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c
index d348efe91445..ba88301579c2 100644
--- a/arch/mips/math-emu/ieee754sp.c
+++ b/arch/mips/math-emu/ieee754sp.c
@@ -38,7 +38,7 @@ int ieee754sp_isnan(union ieee754sp x)
38static inline int ieee754sp_issnan(union ieee754sp x) 38static inline int ieee754sp_issnan(union ieee754sp x)
39{ 39{
40 assert(ieee754sp_isnan(x)); 40 assert(ieee754sp_isnan(x));
41 return (SPMANT(x) & SP_MBIT(SP_FBITS-1)); 41 return SPMANT(x) & SP_MBIT(SP_FBITS - 1);
42} 42}
43 43
44 44
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 7f4f93ab22b7..67ede4ef9b8d 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -4,7 +4,13 @@
4 4
5obj-y += cache.o dma-default.o extable.o fault.o \ 5obj-y += cache.o dma-default.o extable.o fault.o \
6 gup.o init.o mmap.o page.o page-funcs.o \ 6 gup.o init.o mmap.o page.o page-funcs.o \
7 tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o 7 tlbex.o tlbex-fault.o tlb-funcs.o
8
9ifdef CONFIG_CPU_MICROMIPS
10obj-y += uasm-micromips.o
11else
12obj-y += uasm-mips.o
13endif
8 14
9obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o 15obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
10obj-$(CONFIG_64BIT) += pgtable-64.o 16obj-$(CONFIG_64BIT) += pgtable-64.o
@@ -22,5 +28,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
22obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o 28obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
23obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o 29obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o
24obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o 30obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o
25
26obj-$(CONFIG_SYS_SUPPORTS_MICROMIPS) += uasm-micromips.o
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index fbcd8674ff1d..dd261df005c2 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -917,6 +917,18 @@ static inline void alias_74k_erratum(struct cpuinfo_mips *c)
917 } 917 }
918} 918}
919 919
920static void b5k_instruction_hazard(void)
921{
922 __sync();
923 __sync();
924 __asm__ __volatile__(
925 " nop; nop; nop; nop; nop; nop; nop; nop\n"
926 " nop; nop; nop; nop; nop; nop; nop; nop\n"
927 " nop; nop; nop; nop; nop; nop; nop; nop\n"
928 " nop; nop; nop; nop; nop; nop; nop; nop\n"
929 : : : "memory");
930}
931
920static char *way_string[] = { NULL, "direct mapped", "2-way", 932static char *way_string[] = { NULL, "direct mapped", "2-way",
921 "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" 933 "3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
922}; 934};
@@ -1683,6 +1695,37 @@ void r4k_cache_init(void)
1683 1695
1684 coherency_setup(); 1696 coherency_setup();
1685 board_cache_error_setup = r4k_cache_error_setup; 1697 board_cache_error_setup = r4k_cache_error_setup;
1698
1699 /*
1700 * Per-CPU overrides
1701 */
1702 switch (current_cpu_type()) {
1703 case CPU_BMIPS4350:
1704 case CPU_BMIPS4380:
1705 /* No IPI is needed because all CPUs share the same D$ */
1706 flush_data_cache_page = r4k_blast_dcache_page;
1707 break;
1708 case CPU_BMIPS5000:
1709 /* We lose our superpowers if L2 is disabled */
1710 if (c->scache.flags & MIPS_CACHE_NOT_PRESENT)
1711 break;
1712
1713 /* I$ fills from D$ just by emptying the write buffers */
1714 flush_cache_page = (void *)b5k_instruction_hazard;
1715 flush_cache_range = (void *)b5k_instruction_hazard;
1716 flush_cache_sigtramp = (void *)b5k_instruction_hazard;
1717 local_flush_data_cache_page = (void *)b5k_instruction_hazard;
1718 flush_data_cache_page = (void *)b5k_instruction_hazard;
1719 flush_icache_range = (void *)b5k_instruction_hazard;
1720 local_flush_icache_range = (void *)b5k_instruction_hazard;
1721
1722 /* Cache aliases are handled in hardware; allow HIGHMEM */
1723 current_cpu_data.dcache.flags &= ~MIPS_CACHE_ALIASES;
1724
1725 /* Optimization: an L2 flush implicitly flushes the L1 */
1726 current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES;
1727 break;
1728 }
1686} 1729}
1687 1730
1688static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd, 1731static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd,
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 33ba3c558fe4..af5f046e627e 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -61,6 +61,11 @@ static inline struct page *dma_addr_to_page(struct device *dev,
61 * Warning on the terminology - Linux calls an uncached area coherent; 61 * Warning on the terminology - Linux calls an uncached area coherent;
62 * MIPS terminology calls memory areas with hardware maintained coherency 62 * MIPS terminology calls memory areas with hardware maintained coherency
63 * coherent. 63 * coherent.
64 *
65 * Note that the R14000 and R16000 should also be checked for in this
66 * condition. However this function is only called on non-I/O-coherent
67 * systems and only the R10000 and R12000 are used in such systems, the
68 * SGI IP28 Indigo² rsp. SGI IP32 aka O2.
64 */ 69 */
65static inline int cpu_needs_post_dma_flush(struct device *dev) 70static inline int cpu_needs_post_dma_flush(struct device *dev)
66{ 71{
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
index 06ce17c2a905..7cba480568c8 100644
--- a/arch/mips/mm/gup.c
+++ b/arch/mips/mm/gup.c
@@ -17,7 +17,7 @@
17 17
18static inline pte_t gup_get_pte(pte_t *ptep) 18static inline pte_t gup_get_pte(pte_t *ptep)
19{ 19{
20#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 20#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
21 pte_t pte; 21 pte_t pte;
22 22
23retry: 23retry:
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index f42e35e42790..448cde372af0 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -95,7 +95,7 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
95 idx += in_interrupt() ? FIX_N_COLOURS : 0; 95 idx += in_interrupt() ? FIX_N_COLOURS : 0;
96 vaddr = __fix_to_virt(FIX_CMAP_END - idx); 96 vaddr = __fix_to_virt(FIX_CMAP_END - idx);
97 pte = mk_pte(page, prot); 97 pte = mk_pte(page, prot);
98#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 98#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
99 entrylo = pte.pte_high; 99 entrylo = pte.pte_high;
100#else 100#else
101 entrylo = pte_to_entrylo(pte_val(pte)); 101 entrylo = pte_to_entrylo(pte_val(pte));
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index 7f840bc08abf..8d5008cbdc0f 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -17,9 +17,9 @@
17#include <asm/tlbflush.h> 17#include <asm/tlbflush.h>
18 18
19static inline void remap_area_pte(pte_t * pte, unsigned long address, 19static inline void remap_area_pte(pte_t * pte, unsigned long address,
20 phys_t size, phys_t phys_addr, unsigned long flags) 20 phys_addr_t size, phys_addr_t phys_addr, unsigned long flags)
21{ 21{
22 phys_t end; 22 phys_addr_t end;
23 unsigned long pfn; 23 unsigned long pfn;
24 pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE 24 pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
25 | __WRITEABLE | flags); 25 | __WRITEABLE | flags);
@@ -43,9 +43,9 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address,
43} 43}
44 44
45static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, 45static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
46 phys_t size, phys_t phys_addr, unsigned long flags) 46 phys_addr_t size, phys_addr_t phys_addr, unsigned long flags)
47{ 47{
48 phys_t end; 48 phys_addr_t end;
49 49
50 address &= ~PGDIR_MASK; 50 address &= ~PGDIR_MASK;
51 end = address + size; 51 end = address + size;
@@ -64,8 +64,8 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
64 return 0; 64 return 0;
65} 65}
66 66
67static int remap_area_pages(unsigned long address, phys_t phys_addr, 67static int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
68 phys_t size, unsigned long flags) 68 phys_addr_t size, unsigned long flags)
69{ 69{
70 int error; 70 int error;
71 pgd_t * dir; 71 pgd_t * dir;
@@ -111,13 +111,13 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr,
111 * caller shouldn't need to know that small detail. 111 * caller shouldn't need to know that small detail.
112 */ 112 */
113 113
114#define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) 114#define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL))
115 115
116void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) 116void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags)
117{ 117{
118 struct vm_struct * area; 118 struct vm_struct * area;
119 unsigned long offset; 119 unsigned long offset;
120 phys_t last_addr; 120 phys_addr_t last_addr;
121 void * addr; 121 void * addr;
122 122
123 phys_addr = fixup_bigphys_addr(phys_addr, size); 123 phys_addr = fixup_bigphys_addr(phys_addr, size);
diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c
index 0216ed6eaa2a..751b5cd18bf2 100644
--- a/arch/mips/mm/sc-r5k.c
+++ b/arch/mips/mm/sc-r5k.c
@@ -81,7 +81,7 @@ static inline int __init r5k_sc_probe(void)
81 unsigned long config = read_c0_config(); 81 unsigned long config = read_c0_config();
82 82
83 if (config & CONF_SC) 83 if (config & CONF_SC)
84 return(0); 84 return 0;
85 85
86 scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); 86 scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20);
87 87
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index c3917e251f59..e90b2e899291 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -332,7 +332,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
332 { 332 {
333 ptep = pte_offset_map(pmdp, address); 333 ptep = pte_offset_map(pmdp, address);
334 334
335#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) 335#if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
336 write_c0_entrylo0(ptep->pte_high); 336 write_c0_entrylo0(ptep->pte_high);
337 ptep++; 337 ptep++;
338 write_c0_entrylo1(ptep->pte_high); 338 write_c0_entrylo1(ptep->pte_high);
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index e3328a96e809..3978a3d81366 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -637,7 +637,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
637 if (cpu_has_rixi) { 637 if (cpu_has_rixi) {
638 UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); 638 UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL));
639 } else { 639 } else {
640#ifdef CONFIG_64BIT_PHYS_ADDR 640#ifdef CONFIG_PHYS_ADDR_T_64BIT
641 uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL)); 641 uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
642#else 642#else
643 UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL)); 643 UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL));
@@ -1009,7 +1009,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
1009 * 64bit address support (36bit on a 32bit CPU) in a 32bit 1009 * 64bit address support (36bit on a 32bit CPU) in a 32bit
1010 * Kernel is a special case. Only a few CPUs use it. 1010 * Kernel is a special case. Only a few CPUs use it.
1011 */ 1011 */
1012#ifdef CONFIG_64BIT_PHYS_ADDR 1012#ifdef CONFIG_PHYS_ADDR_T_64BIT
1013 if (cpu_has_64bits) { 1013 if (cpu_has_64bits) {
1014 uasm_i_ld(p, tmp, 0, ptep); /* get even pte */ 1014 uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
1015 uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ 1015 uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
@@ -1510,14 +1510,14 @@ static void
1510iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) 1510iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
1511{ 1511{
1512#ifdef CONFIG_SMP 1512#ifdef CONFIG_SMP
1513# ifdef CONFIG_64BIT_PHYS_ADDR 1513# ifdef CONFIG_PHYS_ADDR_T_64BIT
1514 if (cpu_has_64bits) 1514 if (cpu_has_64bits)
1515 uasm_i_lld(p, pte, 0, ptr); 1515 uasm_i_lld(p, pte, 0, ptr);
1516 else 1516 else
1517# endif 1517# endif
1518 UASM_i_LL(p, pte, 0, ptr); 1518 UASM_i_LL(p, pte, 0, ptr);
1519#else 1519#else
1520# ifdef CONFIG_64BIT_PHYS_ADDR 1520# ifdef CONFIG_PHYS_ADDR_T_64BIT
1521 if (cpu_has_64bits) 1521 if (cpu_has_64bits)
1522 uasm_i_ld(p, pte, 0, ptr); 1522 uasm_i_ld(p, pte, 0, ptr);
1523 else 1523 else
@@ -1530,13 +1530,13 @@ static void
1530iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, 1530iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
1531 unsigned int mode) 1531 unsigned int mode)
1532{ 1532{
1533#ifdef CONFIG_64BIT_PHYS_ADDR 1533#ifdef CONFIG_PHYS_ADDR_T_64BIT
1534 unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); 1534 unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
1535#endif 1535#endif
1536 1536
1537 uasm_i_ori(p, pte, pte, mode); 1537 uasm_i_ori(p, pte, pte, mode);
1538#ifdef CONFIG_SMP 1538#ifdef CONFIG_SMP
1539# ifdef CONFIG_64BIT_PHYS_ADDR 1539# ifdef CONFIG_PHYS_ADDR_T_64BIT
1540 if (cpu_has_64bits) 1540 if (cpu_has_64bits)
1541 uasm_i_scd(p, pte, 0, ptr); 1541 uasm_i_scd(p, pte, 0, ptr);
1542 else 1542 else
@@ -1548,7 +1548,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
1548 else 1548 else
1549 uasm_il_beqz(p, r, pte, label_smp_pgtable_change); 1549 uasm_il_beqz(p, r, pte, label_smp_pgtable_change);
1550 1550
1551# ifdef CONFIG_64BIT_PHYS_ADDR 1551# ifdef CONFIG_PHYS_ADDR_T_64BIT
1552 if (!cpu_has_64bits) { 1552 if (!cpu_has_64bits) {
1553 /* no uasm_i_nop needed */ 1553 /* no uasm_i_nop needed */
1554 uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); 1554 uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr);
@@ -1563,14 +1563,14 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
1563 uasm_i_nop(p); 1563 uasm_i_nop(p);
1564# endif 1564# endif
1565#else 1565#else
1566# ifdef CONFIG_64BIT_PHYS_ADDR 1566# ifdef CONFIG_PHYS_ADDR_T_64BIT
1567 if (cpu_has_64bits) 1567 if (cpu_has_64bits)
1568 uasm_i_sd(p, pte, 0, ptr); 1568 uasm_i_sd(p, pte, 0, ptr);
1569 else 1569 else
1570# endif 1570# endif
1571 UASM_i_SW(p, pte, 0, ptr); 1571 UASM_i_SW(p, pte, 0, ptr);
1572 1572
1573# ifdef CONFIG_64BIT_PHYS_ADDR 1573# ifdef CONFIG_PHYS_ADDR_T_64BIT
1574 if (!cpu_has_64bits) { 1574 if (!cpu_has_64bits) {
1575 uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); 1575 uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr);
1576 uasm_i_ori(p, pte, pte, hwmode); 1576 uasm_i_ori(p, pte, pte, hwmode);
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c
index 6708a2dbf934..8e02291cfc0c 100644
--- a/arch/mips/mm/uasm-mips.c
+++ b/arch/mips/mm/uasm-mips.c
@@ -96,9 +96,11 @@ static struct insn insn_table[] = {
96 { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, 96 { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
97 { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, 97 { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
98 { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, 98 { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
99 { insn_mfhc0, M(cop0_op, mfhc0_op, 0, 0, 0, 0), RT | RD | SET},
99 { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD }, 100 { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD },
100 { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD }, 101 { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD },
101 { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, 102 { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
103 { insn_mthc0, M(cop0_op, mthc0_op, 0, 0, 0, 0), RT | RD | SET},
102 { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, 104 { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD},
103 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, 105 { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
104 { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, 106 { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index a01b0d6cedd2..4adf30284813 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -51,12 +51,12 @@ enum opcode {
51 insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, 51 insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret,
52 insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, 52 insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb,
53 insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw, 53 insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw,
54 insn_lwx, insn_mfc0, insn_mfhi, insn_mflo, insn_mtc0, insn_mul, 54 insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi, insn_mflo, insn_mtc0,
55 insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, 55 insn_mthc0, insn_mul, insn_or, insn_ori, insn_pref, insn_rfe,
56 insn_sd, insn_sll, insn_sllv, insn_slt, insn_sltiu, insn_sltu, insn_sra, 56 insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll, insn_sllv, insn_slt,
57 insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall, 57 insn_sltiu, insn_sltu, insn_sra, insn_srl, insn_srlv, insn_subu,
58 insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh, 58 insn_sw, insn_sync, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi,
59 insn_xor, insn_xori, insn_yield, 59 insn_tlbwr, insn_wait, insn_wsbh, insn_xor, insn_xori, insn_yield,
60}; 60};
61 61
62struct insn { 62struct insn {
@@ -284,9 +284,11 @@ I_u2s3u1(_lld)
284I_u1s2(_lui) 284I_u1s2(_lui)
285I_u2s3u1(_lw) 285I_u2s3u1(_lw)
286I_u1u2u3(_mfc0) 286I_u1u2u3(_mfc0)
287I_u1u2u3(_mfhc0)
287I_u1(_mfhi) 288I_u1(_mfhi)
288I_u1(_mflo) 289I_u1(_mflo)
289I_u1u2u3(_mtc0) 290I_u1u2u3(_mtc0)
291I_u1u2u3(_mthc0)
290I_u3u1u2(_mul) 292I_u3u1u2(_mul)
291I_u2u1u3(_ori) 293I_u2u1u3(_ori)
292I_u3u1u2(_or) 294I_u3u1u2(_or)
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 0f60256d3784..6849f533154f 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -111,7 +111,7 @@ static void __init mips_ejtag_setup(void)
111 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); 111 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
112} 112}
113 113
114phys_t mips_cpc_default_phys_base(void) 114phys_addr_t mips_cpc_default_phys_base(void)
115{ 115{
116 return CPC_BASE_ADDR; 116 return CPC_BASE_ADDR;
117} 117}
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index e4f43baa8f67..d1392f8f5811 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -18,6 +18,7 @@
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/irqchip/mips-gic.h>
21#include <linux/kernel_stat.h> 22#include <linux/kernel_stat.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/random.h> 24#include <linux/random.h>
@@ -33,19 +34,13 @@
33#include <asm/mips-boards/generic.h> 34#include <asm/mips-boards/generic.h>
34#include <asm/mips-boards/msc01_pci.h> 35#include <asm/mips-boards/msc01_pci.h>
35#include <asm/msc01_ic.h> 36#include <asm/msc01_ic.h>
36#include <asm/gic.h>
37#include <asm/setup.h> 37#include <asm/setup.h>
38#include <asm/rtlx.h> 38#include <asm/rtlx.h>
39 39
40static unsigned long _msc01_biu_base; 40static void __iomem *_msc01_biu_base;
41static unsigned int ipi_map[NR_CPUS];
42 41
43static DEFINE_RAW_SPINLOCK(mips_irq_lock); 42static DEFINE_RAW_SPINLOCK(mips_irq_lock);
44 43
45#ifdef CONFIG_MIPS_GIC_IPI
46DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS);
47#endif
48
49static inline int mips_pcibios_iack(void) 44static inline int mips_pcibios_iack(void)
50{ 45{
51 int irq; 46 int irq;
@@ -127,24 +122,10 @@ static void malta_hw0_irqdispatch(void)
127#endif 122#endif
128} 123}
129 124
130static void malta_ipi_irqdispatch(void) 125static irqreturn_t i8259_handler(int irq, void *dev_id)
131{ 126{
132#ifdef CONFIG_MIPS_GIC_IPI 127 malta_hw0_irqdispatch();
133 unsigned long irq; 128 return IRQ_HANDLED;
134 DECLARE_BITMAP(pending, GIC_NUM_INTRS);
135
136 gic_get_int_mask(pending, ipi_ints);
137
138 irq = find_first_bit(pending, GIC_NUM_INTRS);
139
140 while (irq < GIC_NUM_INTRS) {
141 do_IRQ(MIPS_GIC_IRQ_BASE + irq);
142
143 irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1);
144 }
145#endif
146 if (gic_compare_int())
147 do_IRQ(MIPS_GIC_IRQ_BASE);
148} 129}
149 130
150static void corehi_irqdispatch(void) 131static void corehi_irqdispatch(void)
@@ -203,95 +184,10 @@ static void corehi_irqdispatch(void)
203 die("CoreHi interrupt", regs); 184 die("CoreHi interrupt", regs);
204} 185}
205 186
206static inline int clz(unsigned long x) 187static irqreturn_t corehi_handler(int irq, void *dev_id)
207{
208 __asm__(
209 " .set push \n"
210 " .set mips32 \n"
211 " clz %0, %1 \n"
212 " .set pop \n"
213 : "=r" (x)
214 : "r" (x));
215
216 return x;
217}
218
219/*
220 * Version of ffs that only looks at bits 12..15.
221 */
222static inline unsigned int irq_ffs(unsigned int pending)
223{
224#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
225 return -clz(pending) + 31 - CAUSEB_IP;
226#else
227 unsigned int a0 = 7;
228 unsigned int t0;
229
230 t0 = pending & 0xf000;
231 t0 = t0 < 1;
232 t0 = t0 << 2;
233 a0 = a0 - t0;
234 pending = pending << t0;
235
236 t0 = pending & 0xc000;
237 t0 = t0 < 1;
238 t0 = t0 << 1;
239 a0 = a0 - t0;
240 pending = pending << t0;
241
242 t0 = pending & 0x8000;
243 t0 = t0 < 1;
244 /* t0 = t0 << 2; */
245 a0 = a0 - t0;
246 /* pending = pending << t0; */
247
248 return a0;
249#endif
250}
251
252/*
253 * IRQs on the Malta board look basically (barring software IRQs which we
254 * don't use at all and all external interrupt sources are combined together
255 * on hardware interrupt 0 (MIPS IRQ 2)) like:
256 *
257 * MIPS IRQ Source
258 * -------- ------
259 * 0 Software (ignored)
260 * 1 Software (ignored)
261 * 2 Combined hardware interrupt (hw0)
262 * 3 Hardware (ignored)
263 * 4 Hardware (ignored)
264 * 5 Hardware (ignored)
265 * 6 Hardware (ignored)
266 * 7 R4k timer (what we use)
267 *
268 * We handle the IRQ according to _our_ priority which is:
269 *
270 * Highest ---- R4k Timer
271 * Lowest ---- Combined hardware interrupt
272 *
273 * then we just return, if multiple IRQs are pending then we will just take
274 * another exception, big deal.
275 */
276
277asmlinkage void plat_irq_dispatch(void)
278{ 188{
279 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; 189 corehi_irqdispatch();
280 int irq; 190 return IRQ_HANDLED;
281
282 if (unlikely(!pending)) {
283 spurious_interrupt();
284 return;
285 }
286
287 irq = irq_ffs(pending);
288
289 if (irq == MIPSCPU_INT_I8259A)
290 malta_hw0_irqdispatch();
291 else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
292 malta_ipi_irqdispatch();
293 else
294 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
295} 191}
296 192
297#ifdef CONFIG_MIPS_MT_SMP 193#ifdef CONFIG_MIPS_MT_SMP
@@ -312,13 +208,6 @@ static void ipi_call_dispatch(void)
312 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); 208 do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ);
313} 209}
314 210
315#endif /* CONFIG_MIPS_MT_SMP */
316
317#ifdef CONFIG_MIPS_GIC_IPI
318
319#define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3
320#define GIC_MIPS_CPU_IPI_CALL_IRQ 4
321
322static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) 211static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
323{ 212{
324#ifdef CONFIG_MIPS_VPE_APSP_API_CMP 213#ifdef CONFIG_MIPS_VPE_APSP_API_CMP
@@ -349,31 +238,16 @@ static struct irqaction irq_call = {
349 .flags = IRQF_PERCPU, 238 .flags = IRQF_PERCPU,
350 .name = "IPI_call" 239 .name = "IPI_call"
351}; 240};
352#endif /* CONFIG_MIPS_GIC_IPI */ 241#endif /* CONFIG_MIPS_MT_SMP */
353
354static int gic_resched_int_base;
355static int gic_call_int_base;
356#define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu))
357#define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu))
358
359unsigned int plat_ipi_call_int_xlate(unsigned int cpu)
360{
361 return GIC_CALL_INT(cpu);
362}
363
364unsigned int plat_ipi_resched_int_xlate(unsigned int cpu)
365{
366 return GIC_RESCHED_INT(cpu);
367}
368 242
369static struct irqaction i8259irq = { 243static struct irqaction i8259irq = {
370 .handler = no_action, 244 .handler = i8259_handler,
371 .name = "XT-PIC cascade", 245 .name = "XT-PIC cascade",
372 .flags = IRQF_NO_THREAD, 246 .flags = IRQF_NO_THREAD,
373}; 247};
374 248
375static struct irqaction corehi_irqaction = { 249static struct irqaction corehi_irqaction = {
376 .handler = no_action, 250 .handler = corehi_handler,
377 .name = "CoreHi", 251 .name = "CoreHi",
378 .flags = IRQF_NO_THREAD, 252 .flags = IRQF_NO_THREAD,
379}; 253};
@@ -399,60 +273,6 @@ static msc_irqmap_t msc_eicirqmap[] __initdata = {
399 273
400static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); 274static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap);
401 275
402/*
403 * This GIC specific tabular array defines the association between External
404 * Interrupts and CPUs/Core Interrupts. The nature of the External
405 * Interrupts is also defined here - polarity/trigger.
406 */
407
408#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
409#define X GIC_UNUSED
410
411static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
412 { X, X, X, X, 0 },
413 { X, X, X, X, 0 },
414 { X, X, X, X, 0 },
415 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
416 { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
417 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
418 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
419 { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
420 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
421 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
422 { X, X, X, X, 0 },
423 { X, X, X, X, 0 },
424 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
425 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
426 { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
427 { X, X, X, X, 0 },
428 /* The remainder of this table is initialised by fill_ipi_map */
429};
430#undef X
431
432#ifdef CONFIG_MIPS_GIC_IPI
433static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin)
434{
435 int intr = baseintr + cpu;
436 gic_intr_map[intr].cpunum = cpu;
437 gic_intr_map[intr].pin = cpupin;
438 gic_intr_map[intr].polarity = GIC_POL_POS;
439 gic_intr_map[intr].trigtype = GIC_TRIG_EDGE;
440 gic_intr_map[intr].flags = 0;
441 ipi_map[cpu] |= (1 << (cpupin + 2));
442 bitmap_set(ipi_ints, intr, 1);
443}
444
445static void __init fill_ipi_map(void)
446{
447 int cpu;
448
449 for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
450 fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1);
451 fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2);
452 }
453}
454#endif
455
456void __init arch_init_ipiirq(int irq, struct irqaction *action) 276void __init arch_init_ipiirq(int irq, struct irqaction *action)
457{ 277{
458 setup_irq(irq, action); 278 setup_irq(irq, action);
@@ -461,6 +281,8 @@ void __init arch_init_ipiirq(int irq, struct irqaction *action)
461 281
462void __init arch_init_irq(void) 282void __init arch_init_irq(void)
463{ 283{
284 int corehi_irq, i8259_irq;
285
464 init_i8259_irqs(); 286 init_i8259_irqs();
465 287
466 if (!cpu_has_veic) 288 if (!cpu_has_veic)
@@ -471,12 +293,12 @@ void __init arch_init_irq(void)
471 gic_present = 1; 293 gic_present = 1;
472 } else { 294 } else {
473 if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { 295 if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) {
474 _msc01_biu_base = (unsigned long) 296 _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE,
475 ioremap_nocache(MSC01_BIU_REG_BASE,
476 MSC01_BIU_ADDRSPACE_SZ); 297 MSC01_BIU_ADDRSPACE_SZ);
477 gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & 298 gic_present =
478 MSC01_SC_CFG_GICPRES_MSK) >> 299 (__raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS) &
479 MSC01_SC_CFG_GICPRES_SHF; 300 MSC01_SC_CFG_GICPRES_MSK) >>
301 MSC01_SC_CFG_GICPRES_SHF;
480 } 302 }
481 } 303 }
482 if (gic_present) 304 if (gic_present)
@@ -507,63 +329,20 @@ void __init arch_init_irq(void)
507 msc_nr_irqs); 329 msc_nr_irqs);
508 } 330 }
509 331
510 if (cpu_has_veic) {
511 set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch);
512 set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
513 setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq);
514 setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction);
515 } else if (cpu_has_vint) {
516 set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
517 set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch);
518 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
519 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
520 &corehi_irqaction);
521 } else {
522 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
523 setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
524 &corehi_irqaction);
525 }
526
527 if (gic_present) { 332 if (gic_present) {
528 /* FIXME */
529 int i; 333 int i;
530#if defined(CONFIG_MIPS_GIC_IPI) 334
531 gic_call_int_base = GIC_NUM_INTRS - 335 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC,
532 (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; 336 MIPS_GIC_IRQ_BASE);
533 gic_resched_int_base = gic_call_int_base - nr_cpu_ids;
534 fill_ipi_map();
535#endif
536 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
537 ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
538 if (!mips_cm_present()) { 337 if (!mips_cm_present()) {
539 /* Enable the GIC */ 338 /* Enable the GIC */
540 i = REG(_msc01_biu_base, MSC01_SC_CFG); 339 i = __raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS);
541 REG(_msc01_biu_base, MSC01_SC_CFG) = 340 __raw_writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF),
542 (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); 341 _msc01_biu_base + MSC01_SC_CFG_OFS);
543 pr_debug("GIC Enabled\n"); 342 pr_debug("GIC Enabled\n");
544 } 343 }
545#if defined(CONFIG_MIPS_GIC_IPI) 344 i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A;
546 /* set up ipi interrupts */ 345 corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
547 if (cpu_has_vint) {
548 set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch);
549 set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch);
550 }
551 /* Argh.. this really needs sorting out.. */
552 pr_info("CPU%d: status register was %08x\n",
553 smp_processor_id(), read_c0_status());
554 write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4);
555 pr_info("CPU%d: status register now %08x\n",
556 smp_processor_id(), read_c0_status());
557 write_c0_status(0x1100dc00);
558 pr_info("CPU%d: status register frc %08x\n",
559 smp_processor_id(), read_c0_status());
560 for (i = 0; i < nr_cpu_ids; i++) {
561 arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
562 GIC_RESCHED_INT(i), &irq_resched);
563 arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
564 GIC_CALL_INT(i), &irq_call);
565 }
566#endif
567 } else { 346 } else {
568#if defined(CONFIG_MIPS_MT_SMP) 347#if defined(CONFIG_MIPS_MT_SMP)
569 /* set up ipi interrupts */ 348 /* set up ipi interrupts */
@@ -573,12 +352,6 @@ void __init arch_init_irq(void)
573 cpu_ipi_resched_irq = MSC01E_INT_SW0; 352 cpu_ipi_resched_irq = MSC01E_INT_SW0;
574 cpu_ipi_call_irq = MSC01E_INT_SW1; 353 cpu_ipi_call_irq = MSC01E_INT_SW1;
575 } else { 354 } else {
576 if (cpu_has_vint) {
577 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ,
578 ipi_resched_dispatch);
579 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ,
580 ipi_call_dispatch);
581 }
582 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + 355 cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE +
583 MIPS_CPU_IPI_RESCHED_IRQ; 356 MIPS_CPU_IPI_RESCHED_IRQ;
584 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + 357 cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE +
@@ -587,7 +360,21 @@ void __init arch_init_irq(void)
587 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); 360 arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
588 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); 361 arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
589#endif 362#endif
363 if (cpu_has_veic) {
364 set_vi_handler(MSC01E_INT_I8259A,
365 malta_hw0_irqdispatch);
366 set_vi_handler(MSC01E_INT_COREHI,
367 corehi_irqdispatch);
368 i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A;
369 corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI;
370 } else {
371 i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A;
372 corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
373 }
590 } 374 }
375
376 setup_irq(i8259_irq, &i8259irq);
377 setup_irq(corehi_irq, &corehi_irqaction);
591} 378}
592 379
593void malta_be_init(void) 380void malta_be_init(void)
@@ -714,37 +501,3 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup)
714 501
715 return retval; 502 return retval;
716} 503}
717
718void gic_enable_interrupt(int irq_vec)
719{
720 GIC_SET_INTR_MASK(irq_vec);
721}
722
723void gic_disable_interrupt(int irq_vec)
724{
725 GIC_CLR_INTR_MASK(irq_vec);
726}
727
728void gic_irq_ack(struct irq_data *d)
729{
730 int irq = (d->irq - gic_irq_base);
731
732 GIC_CLR_INTR_MASK(irq);
733
734 if (gic_irq_flags[irq] & GIC_TRIG_EDGE)
735 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
736}
737
738void gic_finish_irq(struct irq_data *d)
739{
740 /* Enable interrupts. */
741 GIC_SET_INTR_MASK(d->irq - gic_irq_base);
742}
743
744void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
745{
746 int i;
747
748 for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
749 irq_set_chip(i, irq_controller);
750}
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 3778a359f3ad..ce02dbdedc62 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -24,6 +24,7 @@
24#include <linux/sched.h> 24#include <linux/sched.h>
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/irqchip/mips-gic.h>
27#include <linux/timex.h> 28#include <linux/timex.h>
28#include <linux/mc146818rtc.h> 29#include <linux/mc146818rtc.h>
29 30
@@ -37,7 +38,6 @@
37#include <asm/time.h> 38#include <asm/time.h>
38#include <asm/mc146818-time.h> 39#include <asm/mc146818-time.h>
39#include <asm/msc01_ic.h> 40#include <asm/msc01_ic.h>
40#include <asm/gic.h>
41 41
42#include <asm/mips-boards/generic.h> 42#include <asm/mips-boards/generic.h>
43#include <asm/mips-boards/maltaint.h> 43#include <asm/mips-boards/maltaint.h>
@@ -46,6 +46,8 @@ static int mips_cpu_timer_irq;
46static int mips_cpu_perf_irq; 46static int mips_cpu_perf_irq;
47extern int cp0_perfcount_irq; 47extern int cp0_perfcount_irq;
48 48
49static unsigned int gic_frequency;
50
49static void mips_timer_dispatch(void) 51static void mips_timer_dispatch(void)
50{ 52{
51 do_IRQ(mips_cpu_timer_irq); 53 do_IRQ(mips_cpu_timer_irq);
@@ -70,9 +72,7 @@ static void __init estimate_frequencies(void)
70{ 72{
71 unsigned long flags; 73 unsigned long flags;
72 unsigned int count, start; 74 unsigned int count, start;
73#ifdef CONFIG_IRQ_GIC 75 cycle_t giccount = 0, gicstart = 0;
74 unsigned int giccount = 0, gicstart = 0;
75#endif
76 76
77#if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ 77#if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ
78 mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; 78 mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000;
@@ -87,32 +87,26 @@ static void __init estimate_frequencies(void)
87 87
88 /* Initialize counters. */ 88 /* Initialize counters. */
89 start = read_c0_count(); 89 start = read_c0_count();
90#ifdef CONFIG_IRQ_GIC
91 if (gic_present) 90 if (gic_present)
92 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); 91 gicstart = gic_read_count();
93#endif
94 92
95 /* Read counter exactly on falling edge of update flag. */ 93 /* Read counter exactly on falling edge of update flag. */
96 while (CMOS_READ(RTC_REG_A) & RTC_UIP); 94 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
97 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); 95 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
98 96
99 count = read_c0_count(); 97 count = read_c0_count();
100#ifdef CONFIG_IRQ_GIC
101 if (gic_present) 98 if (gic_present)
102 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); 99 giccount = gic_read_count();
103#endif
104 100
105 local_irq_restore(flags); 101 local_irq_restore(flags);
106 102
107 count -= start; 103 count -= start;
108 mips_hpt_frequency = count; 104 mips_hpt_frequency = count;
109 105
110#ifdef CONFIG_IRQ_GIC
111 if (gic_present) { 106 if (gic_present) {
112 giccount -= gicstart; 107 giccount -= gicstart;
113 gic_frequency = giccount; 108 gic_frequency = giccount;
114 } 109 }
115#endif
116} 110}
117 111
118void read_persistent_clock(struct timespec *ts) 112void read_persistent_clock(struct timespec *ts)
@@ -121,35 +115,30 @@ void read_persistent_clock(struct timespec *ts)
121 ts->tv_nsec = 0; 115 ts->tv_nsec = 0;
122} 116}
123 117
124static void __init plat_perf_setup(void) 118int get_c0_perfcount_int(void)
125{ 119{
126#ifdef MSC01E_INT_BASE
127 if (cpu_has_veic) { 120 if (cpu_has_veic) {
128 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); 121 set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch);
129 mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; 122 mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR;
130 } else 123 } else if (gic_present) {
131#endif 124 mips_cpu_perf_irq = gic_get_c0_perfcount_int();
132 if (cp0_perfcount_irq >= 0) { 125 } else if (cp0_perfcount_irq >= 0) {
133 if (cpu_has_vint)
134 set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
135 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 126 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
136#ifdef CONFIG_SMP 127 } else {
137 irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq); 128 mips_cpu_perf_irq = -1;
138#endif
139 } 129 }
130
131 return mips_cpu_perf_irq;
140} 132}
141 133
142unsigned int get_c0_compare_int(void) 134unsigned int get_c0_compare_int(void)
143{ 135{
144#ifdef MSC01E_INT_BASE
145 if (cpu_has_veic) { 136 if (cpu_has_veic) {
146 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); 137 set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
147 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; 138 mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
148 } else 139 } else if (gic_present) {
149#endif 140 mips_cpu_timer_irq = gic_get_c0_compare_int();
150 { 141 } else {
151 if (cpu_has_vint)
152 set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
153 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 142 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
154 } 143 }
155 144
@@ -191,16 +180,14 @@ void __init plat_time_init(void)
191 setup_pit_timer(); 180 setup_pit_timer();
192#endif 181#endif
193 182
194#ifdef CONFIG_IRQ_GIC 183#ifdef CONFIG_MIPS_GIC
195 if (gic_present) { 184 if (gic_present) {
196 freq = freqround(gic_frequency, 5000); 185 freq = freqround(gic_frequency, 5000);
197 printk("GIC frequency %d.%02d MHz\n", freq/1000000, 186 printk("GIC frequency %d.%02d MHz\n", freq/1000000,
198 (freq%1000000)*100/1000000); 187 (freq%1000000)*100/1000000);
199#ifdef CONFIG_CSRC_GIC 188#ifdef CONFIG_CLKSRC_MIPS_GIC
200 gic_clocksource_init(gic_frequency); 189 gic_clocksource_init(gic_frequency);
201#endif 190#endif
202 } 191 }
203#endif 192#endif
204
205 plat_perf_setup();
206} 193}
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c
index 772fc056a92d..014dd7ba4d68 100644
--- a/arch/mips/mti-sead3/sead3-ehci.c
+++ b/arch/mips/mti-sead3/sead3-ehci.c
@@ -9,6 +9,9 @@
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/dma-mapping.h> 10#include <linux/dma-mapping.h>
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12#include <linux/irqchip/mips-gic.h>
13
14#include <asm/mips-boards/sead3int.h>
12 15
13struct resource ehci_resources[] = { 16struct resource ehci_resources[] = {
14 { 17 {
@@ -17,7 +20,6 @@ struct resource ehci_resources[] = {
17 .flags = IORESOURCE_MEM 20 .flags = IORESOURCE_MEM
18 }, 21 },
19 { 22 {
20 .start = MIPS_CPU_IRQ_BASE + 2,
21 .flags = IORESOURCE_IRQ 23 .flags = IORESOURCE_IRQ
22 } 24 }
23}; 25};
@@ -37,6 +39,10 @@ static struct platform_device ehci_device = {
37 39
38static int __init ehci_init(void) 40static int __init ehci_init(void)
39{ 41{
42 if (gic_present)
43 ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI;
44 else
45 ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI;
40 return platform_device_register(&ehci_device); 46 return platform_device_register(&ehci_device);
41} 47}
42 48
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c
index 6a560ac03def..e31e17f81eef 100644
--- a/arch/mips/mti-sead3/sead3-int.c
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -7,9 +7,9 @@
7 */ 7 */
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/irqchip/mips-gic.h>
10#include <linux/io.h> 11#include <linux/io.h>
11 12
12#include <asm/gic.h>
13#include <asm/irq_cpu.h> 13#include <asm/irq_cpu.h>
14#include <asm/setup.h> 14#include <asm/setup.h>
15 15
@@ -20,138 +20,23 @@
20#define SEAD_CONFIG_BASE 0x1b100110 20#define SEAD_CONFIG_BASE 0x1b100110
21#define SEAD_CONFIG_SIZE 4 21#define SEAD_CONFIG_SIZE 4
22 22
23static unsigned long sead3_config_reg; 23static void __iomem *sead3_config_reg;
24
25/*
26 * This table defines the setup for each external GIC interrupt. It is
27 * indexed by interrupt number.
28 */
29#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
30static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
31 { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
32 { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
33 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
34 { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
35 { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
36 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
37 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
38 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
39 { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
40 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
41 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
42 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
43 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
44 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
45 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
46 { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
47};
48
49asmlinkage void plat_irq_dispatch(void)
50{
51 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
52 int irq;
53
54 irq = (fls(pending) - CAUSEB_IP - 1);
55 if (irq >= 0)
56 do_IRQ(MIPS_CPU_IRQ_BASE + irq);
57 else
58 spurious_interrupt();
59}
60 24
61void __init arch_init_irq(void) 25void __init arch_init_irq(void)
62{ 26{
63 int i; 27 if (!cpu_has_veic)
64
65 if (!cpu_has_veic) {
66 mips_cpu_irq_init(); 28 mips_cpu_irq_init();
67 29
68 if (cpu_has_vint) { 30 sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE);
69 /* install generic handler */ 31 gic_present = (__raw_readl(sead3_config_reg) &
70 for (i = 0; i < 8; i++) 32 SEAD_CONFIG_GIC_PRESENT_MSK) >>
71 set_vi_handler(i, plat_irq_dispatch);
72 }
73 }
74
75 sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE,
76 SEAD_CONFIG_SIZE);
77 gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >>
78 SEAD_CONFIG_GIC_PRESENT_SHF; 33 SEAD_CONFIG_GIC_PRESENT_SHF;
79 pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); 34 pr_info("GIC: %spresent\n", (gic_present) ? "" : "not ");
80 pr_info("EIC: %s\n", 35 pr_info("EIC: %s\n",
81 (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); 36 (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off");
82 37
83 if (gic_present) 38 if (gic_present)
84 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, 39 gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, CPU_INT_GIC,
85 ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); 40 MIPS_GIC_IRQ_BASE);
86}
87
88void gic_enable_interrupt(int irq_vec)
89{
90 unsigned int i, irq_source;
91
92 /* enable all the interrupts associated with this vector */
93 for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) {
94 irq_source = gic_shared_intr_map[irq_vec].intr_list[i];
95 GIC_SET_INTR_MASK(irq_source);
96 }
97 /* enable all local interrupts associated with this vector */
98 if (gic_shared_intr_map[irq_vec].local_intr_mask) {
99 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
100 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK),
101 gic_shared_intr_map[irq_vec].local_intr_mask);
102 }
103} 41}
104 42
105void gic_disable_interrupt(int irq_vec)
106{
107 unsigned int i, irq_source;
108
109 /* disable all the interrupts associated with this vector */
110 for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) {
111 irq_source = gic_shared_intr_map[irq_vec].intr_list[i];
112 GIC_CLR_INTR_MASK(irq_source);
113 }
114 /* disable all local interrupts associated with this vector */
115 if (gic_shared_intr_map[irq_vec].local_intr_mask) {
116 GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
117 GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK),
118 gic_shared_intr_map[irq_vec].local_intr_mask);
119 }
120}
121
122void gic_irq_ack(struct irq_data *d)
123{
124 GIC_CLR_INTR_MASK(d->irq - gic_irq_base);
125}
126
127void gic_finish_irq(struct irq_data *d)
128{
129 unsigned int irq = (d->irq - gic_irq_base);
130 unsigned int i, irq_source;
131
132 /* Clear edge detectors. */
133 for (i = 0; i < gic_shared_intr_map[irq].num_shared_intr; i++) {
134 irq_source = gic_shared_intr_map[irq].intr_list[i];
135 if (gic_irq_flags[irq_source] & GIC_TRIG_EDGE)
136 GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq_source);
137 }
138
139 /* Enable interrupts. */
140 GIC_SET_INTR_MASK(irq);
141}
142
143void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
144{
145 int i;
146
147 /*
148 * For non-EIC mode, we want to setup the GIC in pass-through
149 * mode, as if the GIC didn't exist. Do not map any interrupts
150 * for an external interrupt controller.
151 */
152 if (!cpu_has_veic)
153 return;
154
155 for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
156 irq_set_chip_and_handler(i, irq_controller, handle_percpu_irq);
157}
diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c
index dd11e7eb771c..46176b804576 100644
--- a/arch/mips/mti-sead3/sead3-net.c
+++ b/arch/mips/mti-sead3/sead3-net.c
@@ -7,9 +7,12 @@
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/irqchip/mips-gic.h>
10#include <linux/platform_device.h> 11#include <linux/platform_device.h>
11#include <linux/smsc911x.h> 12#include <linux/smsc911x.h>
12 13
14#include <asm/mips-boards/sead3int.h>
15
13static struct smsc911x_platform_config sead3_smsc911x_data = { 16static struct smsc911x_platform_config sead3_smsc911x_data = {
14 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, 17 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
15 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, 18 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
@@ -17,14 +20,13 @@ static struct smsc911x_platform_config sead3_smsc911x_data = {
17 .phy_interface = PHY_INTERFACE_MODE_MII, 20 .phy_interface = PHY_INTERFACE_MODE_MII,
18}; 21};
19 22
20struct resource sead3_net_resourcess[] = { 23struct resource sead3_net_resources[] = {
21 { 24 {
22 .start = 0x1f010000, 25 .start = 0x1f010000,
23 .end = 0x1f01ffff, 26 .end = 0x1f01ffff,
24 .flags = IORESOURCE_MEM 27 .flags = IORESOURCE_MEM
25 }, 28 },
26 { 29 {
27 .start = MIPS_CPU_IRQ_BASE + 6,
28 .flags = IORESOURCE_IRQ 30 .flags = IORESOURCE_IRQ
29 } 31 }
30}; 32};
@@ -35,12 +37,16 @@ static struct platform_device sead3_net_device = {
35 .dev = { 37 .dev = {
36 .platform_data = &sead3_smsc911x_data, 38 .platform_data = &sead3_smsc911x_data,
37 }, 39 },
38 .num_resources = ARRAY_SIZE(sead3_net_resourcess), 40 .num_resources = ARRAY_SIZE(sead3_net_resources),
39 .resource = sead3_net_resourcess 41 .resource = sead3_net_resources
40}; 42};
41 43
42static int __init sead3_net_init(void) 44static int __init sead3_net_init(void)
43{ 45{
46 if (gic_present)
47 sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET;
48 else
49 sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET;
44 return platform_device_register(&sead3_net_device); 50 return platform_device_register(&sead3_net_device);
45} 51}
46 52
diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c
index 6c3b33dbed18..53ee6f1f018d 100644
--- a/arch/mips/mti-sead3/sead3-platform.c
+++ b/arch/mips/mti-sead3/sead3-platform.c
@@ -7,12 +7,15 @@
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/irqchip/mips-gic.h>
10#include <linux/serial_8250.h> 11#include <linux/serial_8250.h>
11 12
12#define UART(base, int) \ 13#include <asm/mips-boards/sead3int.h>
14
15#define UART(base) \
13{ \ 16{ \
14 .mapbase = base, \ 17 .mapbase = base, \
15 .irq = int, \ 18 .irq = -1, \
16 .uartclk = 14745600, \ 19 .uartclk = 14745600, \
17 .iotype = UPIO_MEM32, \ 20 .iotype = UPIO_MEM32, \
18 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ 21 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
@@ -20,8 +23,8 @@
20} 23}
21 24
22static struct plat_serial8250_port uart8250_data[] = { 25static struct plat_serial8250_port uart8250_data[] = {
23 UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ 26 UART(0x1f000900), /* ttyS0 = USB */
24 UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ 27 UART(0x1f000800), /* ttyS1 = RS232 */
25 { }, 28 { },
26}; 29};
27 30
@@ -35,6 +38,13 @@ static struct platform_device uart8250_device = {
35 38
36static int __init uart8250_init(void) 39static int __init uart8250_init(void)
37{ 40{
41 if (gic_present) {
42 uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0;
43 uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1;
44 } else {
45 uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0;
46 uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1;
47 }
38 return platform_device_register(&uart8250_device); 48 return platform_device_register(&uart8250_device);
39} 49}
40 50
diff --git a/arch/mips/mti-sead3/sead3-serial.c b/arch/mips/mti-sead3/sead3-serial.c
deleted file mode 100644
index bc52705bbee4..000000000000
--- a/arch/mips/mti-sead3/sead3-serial.c
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/serial_8250.h>
11
12#define UART(base, int) \
13{ \
14 .mapbase = base, \
15 .irq = int, \
16 .uartclk = 14745600, \
17 .iotype = UPIO_MEM32, \
18 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
19 .regshift = 2, \
20}
21
22static struct plat_serial8250_port uart8250_data[] = {
23 UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */
24 UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */
25 { },
26};
27
28static struct platform_device uart8250_device = {
29 .name = "serial8250",
30 .id = PLAT8250_DEV_PLATFORM,
31 .dev = {
32 .platform_data = uart8250_data,
33 },
34};
35
36static int __init uart8250_init(void)
37{
38 return platform_device_register(&uart8250_device);
39}
40
41module_init(uart8250_init);
42
43MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
44MODULE_LICENSE("GPL");
45MODULE_DESCRIPTION("8250 UART probe driver for the SEAD-3 platform");
diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c
index 678d03d53c60..ec1dd2491f96 100644
--- a/arch/mips/mti-sead3/sead3-time.c
+++ b/arch/mips/mti-sead3/sead3-time.c
@@ -6,6 +6,7 @@
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. 6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
7 */ 7 */
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/irqchip/mips-gic.h>
9 10
10#include <asm/cpu.h> 11#include <asm/cpu.h>
11#include <asm/setup.h> 12#include <asm/setup.h>
@@ -13,19 +14,6 @@
13#include <asm/irq.h> 14#include <asm/irq.h>
14#include <asm/mips-boards/generic.h> 15#include <asm/mips-boards/generic.h>
15 16
16static int mips_cpu_timer_irq;
17static int mips_cpu_perf_irq;
18
19static void mips_timer_dispatch(void)
20{
21 do_IRQ(mips_cpu_timer_irq);
22}
23
24static void mips_perf_dispatch(void)
25{
26 do_IRQ(mips_cpu_perf_irq);
27}
28
29static void __iomem *status_reg = (void __iomem *)0xbf000410; 17static void __iomem *status_reg = (void __iomem *)0xbf000410;
30 18
31/* 19/*
@@ -81,21 +69,20 @@ void read_persistent_clock(struct timespec *ts)
81 ts->tv_nsec = 0; 69 ts->tv_nsec = 0;
82} 70}
83 71
84static void __init plat_perf_setup(void) 72int get_c0_perfcount_int(void)
85{ 73{
86 if (cp0_perfcount_irq >= 0) { 74 if (gic_present)
87 if (cpu_has_vint) 75 return gic_get_c0_compare_int();
88 set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); 76 if (cp0_perfcount_irq >= 0)
89 mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; 77 return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
90 } 78 return -1;
91} 79}
92 80
93unsigned int get_c0_compare_int(void) 81unsigned int get_c0_compare_int(void)
94{ 82{
95 if (cpu_has_vint) 83 if (gic_present)
96 set_vi_handler(cp0_compare_irq, mips_timer_dispatch); 84 return gic_get_c0_compare_int();
97 mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 85 return MIPS_CPU_IRQ_BASE + cp0_compare_irq;
98 return mips_cpu_timer_irq;
99} 86}
100 87
101void __init plat_time_init(void) 88void __init plat_time_init(void)
@@ -108,6 +95,4 @@ void __init plat_time_init(void)
108 (est_freq % 1000000) * 100 / 1000000); 95 (est_freq % 1000000) * 100 / 1000000);
109 96
110 mips_scroll_message(); 97 mips_scroll_message();
111
112 plat_perf_setup();
113} 98}
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
index 9c0a6782c091..070afdb297df 100644
--- a/arch/mips/oprofile/Makefile
+++ b/arch/mips/oprofile/Makefile
@@ -14,3 +14,4 @@ oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o
14oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o 14oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o
15oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o 15oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o
16oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o 16oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o
17oprofile-$(CONFIG_CPU_LOONGSON3) += op_model_loongson3.o
diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c
index 83a1dfd8f0e3..5e645c9a3162 100644
--- a/arch/mips/oprofile/backtrace.c
+++ b/arch/mips/oprofile/backtrace.c
@@ -65,7 +65,7 @@ static inline int is_end_of_function_marker(union mips_instruction *ip)
65 * - handle cases where the stack is adjusted inside a function 65 * - handle cases where the stack is adjusted inside a function
66 * (generally doesn't happen) 66 * (generally doesn't happen)
67 * - find optimal value for max_instr_check 67 * - find optimal value for max_instr_check
68 * - try to find a way to handle leaf functions 68 * - try to find a better way to handle leaf functions
69 */ 69 */
70 70
71static inline int unwind_user_frame(struct stackframe *old_frame, 71static inline int unwind_user_frame(struct stackframe *old_frame,
@@ -104,7 +104,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
104 } 104 }
105 105
106 if (!ra_offset || !stack_size) 106 if (!ra_offset || !stack_size)
107 return -1; 107 goto done;
108 108
109 if (ra_offset) { 109 if (ra_offset) {
110 new_frame.ra = old_frame->sp + ra_offset; 110 new_frame.ra = old_frame->sp + ra_offset;
@@ -121,6 +121,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
121 if (new_frame.sp > old_frame->sp) 121 if (new_frame.sp > old_frame->sp)
122 return -2; 122 return -2;
123 123
124done:
124 new_frame.pc = old_frame->ra; 125 new_frame.pc = old_frame->ra;
125 *old_frame = new_frame; 126 *old_frame = new_frame;
126 127
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index e74732449478..a26cbe372e06 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -18,6 +18,7 @@
18 18
19extern struct op_mips_model op_model_mipsxx_ops __weak; 19extern struct op_mips_model op_model_mipsxx_ops __weak;
20extern struct op_mips_model op_model_loongson2_ops __weak; 20extern struct op_mips_model op_model_loongson2_ops __weak;
21extern struct op_mips_model op_model_loongson3_ops __weak;
21 22
22static struct op_mips_model *model; 23static struct op_mips_model *model;
23 24
@@ -104,8 +105,17 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
104 case CPU_LOONGSON2: 105 case CPU_LOONGSON2:
105 lmodel = &op_model_loongson2_ops; 106 lmodel = &op_model_loongson2_ops;
106 break; 107 break;
108 case CPU_LOONGSON3:
109 lmodel = &op_model_loongson3_ops;
110 break;
107 }; 111 };
108 112
113 /*
114 * Always set the backtrace. This allows unsupported CPU types to still
115 * use timer-based oprofile.
116 */
117 ops->backtrace = op_mips_backtrace;
118
109 if (!lmodel) 119 if (!lmodel)
110 return -ENODEV; 120 return -ENODEV;
111 121
@@ -121,7 +131,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
121 ops->start = op_mips_start; 131 ops->start = op_mips_start;
122 ops->stop = op_mips_stop; 132 ops->stop = op_mips_stop;
123 ops->cpu_type = lmodel->cpu_type; 133 ops->cpu_type = lmodel->cpu_type;
124 ops->backtrace = op_mips_backtrace;
125 134
126 printk(KERN_INFO "oprofile: using %s performance monitoring.\n", 135 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
127 lmodel->cpu_type); 136 lmodel->cpu_type);
diff --git a/arch/mips/oprofile/op_model_loongson3.c b/arch/mips/oprofile/op_model_loongson3.c
new file mode 100644
index 000000000000..8bcf7fc40f0d
--- /dev/null
+++ b/arch/mips/oprofile/op_model_loongson3.c
@@ -0,0 +1,220 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 */
7#include <linux/init.h>
8#include <linux/cpu.h>
9#include <linux/smp.h>
10#include <linux/proc_fs.h>
11#include <linux/oprofile.h>
12#include <linux/spinlock.h>
13#include <linux/interrupt.h>
14#include <asm/uaccess.h>
15#include <irq.h>
16#include <loongson.h>
17#include "op_impl.h"
18
19#define LOONGSON3_PERFCNT_OVERFLOW (1ULL << 63)
20
21#define LOONGSON3_PERFCTRL_EXL (1UL << 0)
22#define LOONGSON3_PERFCTRL_KERNEL (1UL << 1)
23#define LOONGSON3_PERFCTRL_SUPERVISOR (1UL << 2)
24#define LOONGSON3_PERFCTRL_USER (1UL << 3)
25#define LOONGSON3_PERFCTRL_ENABLE (1UL << 4)
26#define LOONGSON3_PERFCTRL_W (1UL << 30)
27#define LOONGSON3_PERFCTRL_M (1UL << 31)
28#define LOONGSON3_PERFCTRL_EVENT(idx, event) \
29 (((event) & (idx ? 0x0f : 0x3f)) << 5)
30
31/* Loongson-3 PerfCount performance counter1 register */
32#define read_c0_perflo1() __read_64bit_c0_register($25, 0)
33#define write_c0_perflo1(val) __write_64bit_c0_register($25, 0, val)
34#define read_c0_perfhi1() __read_64bit_c0_register($25, 1)
35#define write_c0_perfhi1(val) __write_64bit_c0_register($25, 1, val)
36
37/* Loongson-3 PerfCount performance counter2 register */
38#define read_c0_perflo2() __read_64bit_c0_register($25, 2)
39#define write_c0_perflo2(val) __write_64bit_c0_register($25, 2, val)
40#define read_c0_perfhi2() __read_64bit_c0_register($25, 3)
41#define write_c0_perfhi2(val) __write_64bit_c0_register($25, 3, val)
42
43static int (*save_perf_irq)(void);
44
45static struct loongson3_register_config {
46 unsigned int control1;
47 unsigned int control2;
48 unsigned long long reset_counter1;
49 unsigned long long reset_counter2;
50 int ctr1_enable, ctr2_enable;
51} reg;
52
53static void reset_counters(void *arg)
54{
55 write_c0_perfhi1(0);
56 write_c0_perfhi2(0);
57 write_c0_perflo1(0xc0000000);
58 write_c0_perflo2(0x40000000);
59}
60
61/* Compute all of the registers in preparation for enabling profiling. */
62static void loongson3_reg_setup(struct op_counter_config *ctr)
63{
64 unsigned int control1 = 0;
65 unsigned int control2 = 0;
66
67 reg.reset_counter1 = 0;
68 reg.reset_counter2 = 0;
69 /* Compute the performance counter control word. */
70 /* For now count kernel and user mode */
71 if (ctr[0].enabled) {
72 control1 |= LOONGSON3_PERFCTRL_EVENT(0, ctr[0].event) |
73 LOONGSON3_PERFCTRL_ENABLE;
74 if (ctr[0].kernel)
75 control1 |= LOONGSON3_PERFCTRL_KERNEL;
76 if (ctr[0].user)
77 control1 |= LOONGSON3_PERFCTRL_USER;
78 reg.reset_counter1 = 0x8000000000000000ULL - ctr[0].count;
79 }
80
81 if (ctr[1].enabled) {
82 control2 |= LOONGSON3_PERFCTRL_EVENT(1, ctr[1].event) |
83 LOONGSON3_PERFCTRL_ENABLE;
84 if (ctr[1].kernel)
85 control2 |= LOONGSON3_PERFCTRL_KERNEL;
86 if (ctr[1].user)
87 control2 |= LOONGSON3_PERFCTRL_USER;
88 reg.reset_counter2 = 0x8000000000000000ULL - ctr[1].count;
89 }
90
91 if (ctr[0].enabled)
92 control1 |= LOONGSON3_PERFCTRL_EXL;
93 if (ctr[1].enabled)
94 control2 |= LOONGSON3_PERFCTRL_EXL;
95
96 reg.control1 = control1;
97 reg.control2 = control2;
98 reg.ctr1_enable = ctr[0].enabled;
99 reg.ctr2_enable = ctr[1].enabled;
100}
101
102/* Program all of the registers in preparation for enabling profiling. */
103static void loongson3_cpu_setup(void *args)
104{
105 uint64_t perfcount1, perfcount2;
106
107 perfcount1 = reg.reset_counter1;
108 perfcount2 = reg.reset_counter2;
109 write_c0_perfhi1(perfcount1);
110 write_c0_perfhi2(perfcount2);
111}
112
113static void loongson3_cpu_start(void *args)
114{
115 /* Start all counters on current CPU */
116 reg.control1 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M);
117 reg.control2 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M);
118
119 if (reg.ctr1_enable)
120 write_c0_perflo1(reg.control1);
121 if (reg.ctr2_enable)
122 write_c0_perflo2(reg.control2);
123}
124
125static void loongson3_cpu_stop(void *args)
126{
127 /* Stop all counters on current CPU */
128 write_c0_perflo1(0xc0000000);
129 write_c0_perflo2(0x40000000);
130 memset(&reg, 0, sizeof(reg));
131}
132
133static int loongson3_perfcount_handler(void)
134{
135 unsigned long flags;
136 uint64_t counter1, counter2;
137 uint32_t cause, handled = IRQ_NONE;
138 struct pt_regs *regs = get_irq_regs();
139
140 cause = read_c0_cause();
141 if (!(cause & CAUSEF_PCI))
142 return handled;
143
144 counter1 = read_c0_perfhi1();
145 counter2 = read_c0_perfhi2();
146
147 local_irq_save(flags);
148
149 if (counter1 & LOONGSON3_PERFCNT_OVERFLOW) {
150 if (reg.ctr1_enable)
151 oprofile_add_sample(regs, 0);
152 counter1 = reg.reset_counter1;
153 }
154 if (counter2 & LOONGSON3_PERFCNT_OVERFLOW) {
155 if (reg.ctr2_enable)
156 oprofile_add_sample(regs, 1);
157 counter2 = reg.reset_counter2;
158 }
159
160 local_irq_restore(flags);
161
162 write_c0_perfhi1(counter1);
163 write_c0_perfhi2(counter2);
164
165 if (!(cause & CAUSEF_TI))
166 handled = IRQ_HANDLED;
167
168 return handled;
169}
170
171static int loongson3_cpu_callback(struct notifier_block *nfb,
172 unsigned long action, void *hcpu)
173{
174 switch (action) {
175 case CPU_STARTING:
176 case CPU_STARTING_FROZEN:
177 write_c0_perflo1(reg.control1);
178 write_c0_perflo2(reg.control2);
179 break;
180 case CPU_DYING:
181 case CPU_DYING_FROZEN:
182 write_c0_perflo1(0xc0000000);
183 write_c0_perflo2(0x40000000);
184 break;
185 }
186
187 return NOTIFY_OK;
188}
189
190static struct notifier_block loongson3_notifier_block = {
191 .notifier_call = loongson3_cpu_callback
192};
193
194static int __init loongson3_init(void)
195{
196 on_each_cpu(reset_counters, NULL, 1);
197 register_hotcpu_notifier(&loongson3_notifier_block);
198 save_perf_irq = perf_irq;
199 perf_irq = loongson3_perfcount_handler;
200
201 return 0;
202}
203
204static void loongson3_exit(void)
205{
206 on_each_cpu(reset_counters, NULL, 1);
207 unregister_hotcpu_notifier(&loongson3_notifier_block);
208 perf_irq = save_perf_irq;
209}
210
211struct op_mips_model op_model_loongson3_ops = {
212 .reg_setup = loongson3_reg_setup,
213 .cpu_setup = loongson3_cpu_setup,
214 .init = loongson3_init,
215 .exit = loongson3_exit,
216 .cpu_start = loongson3_cpu_start,
217 .cpu_stop = loongson3_cpu_stop,
218 .cpu_type = "mips/loongson3",
219 .num_counters = 2
220};
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 42821ae2d77e..01f721a85c5b 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -11,6 +11,7 @@
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/smp.h> 12#include <linux/smp.h>
13#include <asm/irq_regs.h> 13#include <asm/irq_regs.h>
14#include <asm/time.h>
14 15
15#include "op_impl.h" 16#include "op_impl.h"
16 17
@@ -35,6 +36,7 @@
35#define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) 36#define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13)
36 37
37static int (*save_perf_irq)(void); 38static int (*save_perf_irq)(void);
39static int perfcount_irq;
38 40
39/* 41/*
40 * XLR has only one set of counters per core. Designate the 42 * XLR has only one set of counters per core. Designate the
@@ -431,8 +433,16 @@ static int __init mipsxx_init(void)
431 save_perf_irq = perf_irq; 433 save_perf_irq = perf_irq;
432 perf_irq = mipsxx_perfcount_handler; 434 perf_irq = mipsxx_perfcount_handler;
433 435
434 if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) 436 if (get_c0_perfcount_int)
435 return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int, 437 perfcount_irq = get_c0_perfcount_int();
438 else if ((cp0_perfcount_irq >= 0) &&
439 (cp0_compare_irq != cp0_perfcount_irq))
440 perfcount_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
441 else
442 perfcount_irq = -1;
443
444 if (perfcount_irq >= 0)
445 return request_irq(perfcount_irq, mipsxx_perfcount_int,
436 0, "Perfcounter", save_perf_irq); 446 0, "Perfcounter", save_perf_irq);
437 447
438 return 0; 448 return 0;
@@ -442,8 +452,8 @@ static void mipsxx_exit(void)
442{ 452{
443 int counters = op_model_mipsxx_ops.num_counters; 453 int counters = op_model_mipsxx_ops.num_counters;
444 454
445 if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) 455 if (perfcount_irq >= 0)
446 free_irq(cp0_perfcount_irq, save_perf_irq); 456 free_irq(perfcount_irq, save_perf_irq);
447 457
448 counters = counters_per_cpu_to_total(counters); 458 counters = counters_per_cpu_to_total(counters);
449 on_each_cpu(reset_counters, (void *)(long)counters, 1); 459 on_each_cpu(reset_counters, (void *)(long)counters, 1);
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 6523d558ff5a..300591c6278d 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
19obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ 19obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
20 ops-bcm63xx.o 20 ops-bcm63xx.o
21obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o 21obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
22obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o
22obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o 23obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
23obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o 24obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
24obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o 25obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
42obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o 43obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
43obj-$(CONFIG_LANTIQ) += fixup-lantiq.o 44obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
44obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o 45obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
46obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o
45obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o 47obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
46obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o 48obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
47obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o 49obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c
index 13eea696bbe7..d02eb9d16b55 100644
--- a/arch/mips/pci/ops-bcm63xx.c
+++ b/arch/mips/pci/ops-bcm63xx.c
@@ -469,7 +469,7 @@ static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
469{ 469{
470 switch (bus->number) { 470 switch (bus->number) {
471 case PCIE_BUS_BRIDGE: 471 case PCIE_BUS_BRIDGE:
472 return (PCI_SLOT(devfn) == 0); 472 return PCI_SLOT(devfn) == 0;
473 case PCIE_BUS_DEVICE: 473 case PCIE_BUS_DEVICE:
474 if (PCI_SLOT(devfn) == 0) 474 if (PCI_SLOT(devfn) == 0)
475 return bcm_pcie_readl(PCIE_DLSTATUS_REG) 475 return bcm_pcie_readl(PCIE_DLSTATUS_REG)
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c
index a1a7c9f4096e..b9d1fd0ff7e2 100644
--- a/arch/mips/pci/ops-nile4.c
+++ b/arch/mips/pci/ops-nile4.c
@@ -13,8 +13,6 @@
13 13
14volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; 14volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE;
15 15
16static DEFINE_SPINLOCK(nile4_pci_lock);
17
18static int nile4_pcibios_config_access(unsigned char access_type, 16static int nile4_pcibios_config_access(unsigned char access_type,
19 struct pci_bus *bus, unsigned int devfn, int where, u32 *val) 17 struct pci_bus *bus, unsigned int devfn, int where, u32 *val)
20{ 18{
@@ -76,7 +74,6 @@ static int nile4_pcibios_config_access(unsigned char access_type,
76static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, 74static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
77 int where, int size, u32 *val) 75 int where, int size, u32 *val)
78{ 76{
79 unsigned long flags;
80 u32 data = 0; 77 u32 data = 0;
81 int err; 78 int err;
82 79
@@ -85,11 +82,8 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
85 else if ((size == 4) && (where & 3)) 82 else if ((size == 4) && (where & 3))
86 return PCIBIOS_BAD_REGISTER_NUMBER; 83 return PCIBIOS_BAD_REGISTER_NUMBER;
87 84
88 spin_lock_irqsave(&nile4_pci_lock, flags);
89 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, 85 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
90 &data); 86 &data);
91 spin_unlock_irqrestore(&nile4_pci_lock, flags);
92
93 if (err) 87 if (err)
94 return err; 88 return err;
95 89
@@ -106,7 +100,6 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn,
106static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, 100static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
107 int where, int size, u32 val) 101 int where, int size, u32 val)
108{ 102{
109 unsigned long flags;
110 u32 data = 0; 103 u32 data = 0;
111 int err; 104 int err;
112 105
@@ -115,11 +108,8 @@ static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn,
115 else if ((size == 4) && (where & 3)) 108 else if ((size == 4) && (where & 3))
116 return PCIBIOS_BAD_REGISTER_NUMBER; 109 return PCIBIOS_BAD_REGISTER_NUMBER;
117 110
118 spin_lock_irqsave(&nile4_pci_lock, flags);
119 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, 111 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
120 &data); 112 &data);
121 spin_unlock_irqrestore(&nile4_pci_lock, flags);
122
123 if (err) 113 if (err)
124 return err; 114 return err;
125 115
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
index 50034f985be1..dd2d9f7e9412 100644
--- a/arch/mips/pci/ops-pmcmsp.c
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -193,8 +193,6 @@ static void pci_proc_init(void)
193} 193}
194#endif /* CONFIG_PROC_FS && PCI_COUNTERS */ 194#endif /* CONFIG_PROC_FS && PCI_COUNTERS */
195 195
196static DEFINE_SPINLOCK(bpci_lock);
197
198/***************************************************************************** 196/*****************************************************************************
199 * 197 *
200 * STRUCT: pci_io_resource 198 * STRUCT: pci_io_resource
@@ -368,7 +366,6 @@ int msp_pcibios_config_access(unsigned char access_type,
368 struct msp_pci_regs *preg = (void *)PCI_BASE_REG; 366 struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
369 unsigned char bus_num = bus->number; 367 unsigned char bus_num = bus->number;
370 unsigned char dev_fn = (unsigned char)devfn; 368 unsigned char dev_fn = (unsigned char)devfn;
371 unsigned long flags;
372 unsigned long intr; 369 unsigned long intr;
373 unsigned long value; 370 unsigned long value;
374 static char pciirqflag; 371 static char pciirqflag;
@@ -401,10 +398,7 @@ int msp_pcibios_config_access(unsigned char access_type,
401 } 398 }
402 399
403#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) 400#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
404 local_irq_save(flags);
405 vpe_status = dvpe(); 401 vpe_status = dvpe();
406#else
407 spin_lock_irqsave(&bpci_lock, flags);
408#endif 402#endif
409 403
410 /* 404 /*
@@ -457,9 +451,6 @@ int msp_pcibios_config_access(unsigned char access_type,
457 451
458#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) 452#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
459 evpe(vpe_status); 453 evpe(vpe_status);
460 local_irq_restore(flags);
461#else
462 spin_unlock_irqrestore(&bpci_lock, flags);
463#endif 454#endif
464 455
465 return -1; 456 return -1;
@@ -467,9 +458,6 @@ int msp_pcibios_config_access(unsigned char access_type,
467 458
468#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) 459#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
469 evpe(vpe_status); 460 evpe(vpe_status);
470 local_irq_restore(flags);
471#else
472 spin_unlock_irqrestore(&bpci_lock, flags);
473#endif 461#endif
474 462
475 return PCIBIOS_SUCCESSFUL; 463 return PCIBIOS_SUCCESSFUL;
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
new file mode 100644
index 000000000000..bd2b3b60da83
--- /dev/null
+++ b/arch/mips/pci/pci-ar2315.c
@@ -0,0 +1,511 @@
1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, see <http://www.gnu.org/licenses/>.
14 */
15
16/**
17 * Both AR2315 and AR2316 chips have PCI interface unit, which supports DMA
18 * and interrupt. PCI interface supports MMIO access method, but does not
19 * seem to support I/O ports.
20 *
21 * Read/write operation in the region 0x80000000-0xBFFFFFFF causes
22 * a memory read/write command on the PCI bus. 30 LSBs of address on
23 * the bus are taken from memory read/write request and 2 MSBs are
24 * determined by PCI unit configuration.
25 *
26 * To work with the configuration space instead of memory is necessary set
27 * the CFG_SEL bit in the PCI_MISC_CONFIG register.
28 *
29 * Devices on the bus can perform DMA requests via chip BAR1. PCI host
30 * controller BARs are programmend as if an external device is programmed.
31 * Which means that during configuration, IDSEL pin of the chip should be
32 * asserted.
33 *
34 * We know (and support) only one board that uses the PCI interface -
35 * Fonera 2.0g (FON2202). It has a USB EHCI controller connected to the
36 * AR2315 PCI bus. IDSEL pin of USB controller is connected to AD[13] line
37 * and IDSEL pin of AR2315 is connected to AD[16] line.
38 */
39
40#include <linux/types.h>
41#include <linux/pci.h>
42#include <linux/platform_device.h>
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/mm.h>
46#include <linux/delay.h>
47#include <linux/bitops.h>
48#include <linux/irq.h>
49#include <linux/irqdomain.h>
50#include <linux/io.h>
51#include <asm/paccess.h>
52
53/*
54 * PCI Bus Interface Registers
55 */
56#define AR2315_PCI_1MS_REG 0x0008
57
58#define AR2315_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */
59
60#define AR2315_PCI_MISC_CONFIG 0x000c
61
62#define AR2315_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */
63#define AR2315_PCIMISC_CFG_SEL 0x00000002 /* Mem or Config cycles */
64#define AR2315_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */
65#define AR2315_PCIMISC_RST_MODE 0x00000030
66#define AR2315_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */
67#define AR2315_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */
68#define AR2315_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */
69#define AR2315_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */
70#define AR2315_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */
71#define AR2315_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */
72#define AR2315_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */
73#define AR2315_PCICACHE_DIS 0x00001000 /* PCI external access cache
74 * disable */
75
76#define AR2315_PCI_OUT_TSTAMP 0x0010
77
78#define AR2315_PCI_UNCACHE_CFG 0x0014
79
80#define AR2315_PCI_IN_EN 0x0100
81
82#define AR2315_PCI_IN_EN0 0x01 /* Enable chain 0 */
83#define AR2315_PCI_IN_EN1 0x02 /* Enable chain 1 */
84#define AR2315_PCI_IN_EN2 0x04 /* Enable chain 2 */
85#define AR2315_PCI_IN_EN3 0x08 /* Enable chain 3 */
86
87#define AR2315_PCI_IN_DIS 0x0104
88
89#define AR2315_PCI_IN_DIS0 0x01 /* Disable chain 0 */
90#define AR2315_PCI_IN_DIS1 0x02 /* Disable chain 1 */
91#define AR2315_PCI_IN_DIS2 0x04 /* Disable chain 2 */
92#define AR2315_PCI_IN_DIS3 0x08 /* Disable chain 3 */
93
94#define AR2315_PCI_IN_PTR 0x0200
95
96#define AR2315_PCI_OUT_EN 0x0400
97
98#define AR2315_PCI_OUT_EN0 0x01 /* Enable chain 0 */
99
100#define AR2315_PCI_OUT_DIS 0x0404
101
102#define AR2315_PCI_OUT_DIS0 0x01 /* Disable chain 0 */
103
104#define AR2315_PCI_OUT_PTR 0x0408
105
106/* PCI interrupt status (write one to clear) */
107#define AR2315_PCI_ISR 0x0500
108
109#define AR2315_PCI_INT_TX 0x00000001 /* Desc In Completed */
110#define AR2315_PCI_INT_TXOK 0x00000002 /* Desc In OK */
111#define AR2315_PCI_INT_TXERR 0x00000004 /* Desc In ERR */
112#define AR2315_PCI_INT_TXEOL 0x00000008 /* Desc In End-of-List */
113#define AR2315_PCI_INT_RX 0x00000010 /* Desc Out Completed */
114#define AR2315_PCI_INT_RXOK 0x00000020 /* Desc Out OK */
115#define AR2315_PCI_INT_RXERR 0x00000040 /* Desc Out ERR */
116#define AR2315_PCI_INT_RXEOL 0x00000080 /* Desc Out EOL */
117#define AR2315_PCI_INT_TXOOD 0x00000200 /* Desc In Out-of-Desc */
118#define AR2315_PCI_INT_DESCMASK 0x0000FFFF /* Desc Mask */
119#define AR2315_PCI_INT_EXT 0x02000000 /* Extern PCI INTA */
120#define AR2315_PCI_INT_ABORT 0x04000000 /* PCI bus abort event */
121
122/* PCI interrupt mask */
123#define AR2315_PCI_IMR 0x0504
124
125/* Global PCI interrupt enable */
126#define AR2315_PCI_IER 0x0508
127
128#define AR2315_PCI_IER_DISABLE 0x00 /* disable pci interrupts */
129#define AR2315_PCI_IER_ENABLE 0x01 /* enable pci interrupts */
130
131#define AR2315_PCI_HOST_IN_EN 0x0800
132#define AR2315_PCI_HOST_IN_DIS 0x0804
133#define AR2315_PCI_HOST_IN_PTR 0x0810
134#define AR2315_PCI_HOST_OUT_EN 0x0900
135#define AR2315_PCI_HOST_OUT_DIS 0x0904
136#define AR2315_PCI_HOST_OUT_PTR 0x0908
137
138/*
139 * PCI interrupts, which share IP5
140 * Keep ordered according to AR2315_PCI_INT_XXX bits
141 */
142#define AR2315_PCI_IRQ_EXT 25
143#define AR2315_PCI_IRQ_ABORT 26
144#define AR2315_PCI_IRQ_COUNT 27
145
146/* Arbitrary size of memory region to access the configuration space */
147#define AR2315_PCI_CFG_SIZE 0x00100000
148
149#define AR2315_PCI_HOST_SLOT 3
150#define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS)
151
152/* ??? access BAR */
153#define AR2315_PCI_HOST_MBAR0 0x10000000
154/* RAM access BAR */
155#define AR2315_PCI_HOST_MBAR1 AR2315_PCI_HOST_SDRAM_BASEADDR
156/* ??? access BAR */
157#define AR2315_PCI_HOST_MBAR2 0x30000000
158
159struct ar2315_pci_ctrl {
160 void __iomem *cfg_mem;
161 void __iomem *mmr_mem;
162 unsigned irq;
163 unsigned irq_ext;
164 struct irq_domain *domain;
165 struct pci_controller pci_ctrl;
166 struct resource mem_res;
167 struct resource io_res;
168};
169
170static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus)
171{
172 struct pci_controller *hose = bus->sysdata;
173
174 return container_of(hose, struct ar2315_pci_ctrl, pci_ctrl);
175}
176
177static inline u32 ar2315_pci_reg_read(struct ar2315_pci_ctrl *apc, u32 reg)
178{
179 return __raw_readl(apc->mmr_mem + reg);
180}
181
182static inline void ar2315_pci_reg_write(struct ar2315_pci_ctrl *apc, u32 reg,
183 u32 val)
184{
185 __raw_writel(val, apc->mmr_mem + reg);
186}
187
188static inline void ar2315_pci_reg_mask(struct ar2315_pci_ctrl *apc, u32 reg,
189 u32 mask, u32 val)
190{
191 u32 ret = ar2315_pci_reg_read(apc, reg);
192
193 ret &= ~mask;
194 ret |= val;
195 ar2315_pci_reg_write(apc, reg, ret);
196}
197
198static int ar2315_pci_cfg_access(struct ar2315_pci_ctrl *apc, unsigned devfn,
199 int where, int size, u32 *ptr, bool write)
200{
201 int func = PCI_FUNC(devfn);
202 int dev = PCI_SLOT(devfn);
203 u32 addr = (1 << (13 + dev)) | (func << 8) | (where & ~3);
204 u32 mask = 0xffffffff >> 8 * (4 - size);
205 u32 sh = (where & 3) * 8;
206 u32 value, isr;
207
208 /* Prevent access past the remapped area */
209 if (addr >= AR2315_PCI_CFG_SIZE || dev > 18)
210 return PCIBIOS_DEVICE_NOT_FOUND;
211
212 /* Clear pending errors */
213 ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT);
214 /* Select Configuration access */
215 ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, 0,
216 AR2315_PCIMISC_CFG_SEL);
217
218 mb(); /* PCI must see space change before we begin */
219
220 value = __raw_readl(apc->cfg_mem + addr);
221
222 isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR);
223
224 if (isr & AR2315_PCI_INT_ABORT)
225 goto exit_err;
226
227 if (write) {
228 value = (value & ~(mask << sh)) | *ptr << sh;
229 __raw_writel(value, apc->cfg_mem + addr);
230 isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR);
231 if (isr & AR2315_PCI_INT_ABORT)
232 goto exit_err;
233 } else {
234 *ptr = (value >> sh) & mask;
235 }
236
237 goto exit;
238
239exit_err:
240 ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT);
241 if (!write)
242 *ptr = 0xffffffff;
243
244exit:
245 /* Select Memory access */
246 ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL,
247 0);
248
249 return isr & AR2315_PCI_INT_ABORT ? PCIBIOS_DEVICE_NOT_FOUND :
250 PCIBIOS_SUCCESSFUL;
251}
252
253static inline int ar2315_pci_local_cfg_rd(struct ar2315_pci_ctrl *apc,
254 unsigned devfn, int where, u32 *val)
255{
256 return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), val,
257 false);
258}
259
260static inline int ar2315_pci_local_cfg_wr(struct ar2315_pci_ctrl *apc,
261 unsigned devfn, int where, u32 val)
262{
263 return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), &val,
264 true);
265}
266
267static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned devfn, int where,
268 int size, u32 *value)
269{
270 struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus);
271
272 if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT)
273 return PCIBIOS_DEVICE_NOT_FOUND;
274
275 return ar2315_pci_cfg_access(apc, devfn, where, size, value, false);
276}
277
278static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned devfn, int where,
279 int size, u32 value)
280{
281 struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus);
282
283 if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT)
284 return PCIBIOS_DEVICE_NOT_FOUND;
285
286 return ar2315_pci_cfg_access(apc, devfn, where, size, &value, true);
287}
288
289static struct pci_ops ar2315_pci_ops = {
290 .read = ar2315_pci_cfg_read,
291 .write = ar2315_pci_cfg_write,
292};
293
294static int ar2315_pci_host_setup(struct ar2315_pci_ctrl *apc)
295{
296 unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0);
297 int res;
298 u32 id;
299
300 res = ar2315_pci_local_cfg_rd(apc, devfn, PCI_VENDOR_ID, &id);
301 if (res != PCIBIOS_SUCCESSFUL || id != AR2315_PCI_HOST_DEVID)
302 return -ENODEV;
303
304 /* Program MBARs */
305 ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_0,
306 AR2315_PCI_HOST_MBAR0);
307 ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_1,
308 AR2315_PCI_HOST_MBAR1);
309 ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_2,
310 AR2315_PCI_HOST_MBAR2);
311
312 /* Run */
313 ar2315_pci_local_cfg_wr(apc, devfn, PCI_COMMAND, PCI_COMMAND_MEMORY |
314 PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL |
315 PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
316 PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK);
317
318 return 0;
319}
320
321static void ar2315_pci_irq_handler(unsigned irq, struct irq_desc *desc)
322{
323 struct ar2315_pci_ctrl *apc = irq_get_handler_data(irq);
324 u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) &
325 ar2315_pci_reg_read(apc, AR2315_PCI_IMR);
326 unsigned pci_irq = 0;
327
328 if (pending)
329 pci_irq = irq_find_mapping(apc->domain, __ffs(pending));
330
331 if (pci_irq)
332 generic_handle_irq(pci_irq);
333 else
334 spurious_interrupt();
335}
336
337static void ar2315_pci_irq_mask(struct irq_data *d)
338{
339 struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d);
340
341 ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, BIT(d->hwirq), 0);
342}
343
344static void ar2315_pci_irq_mask_ack(struct irq_data *d)
345{
346 struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d);
347 u32 m = BIT(d->hwirq);
348
349 ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, m, 0);
350 ar2315_pci_reg_write(apc, AR2315_PCI_ISR, m);
351}
352
353static void ar2315_pci_irq_unmask(struct irq_data *d)
354{
355 struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d);
356
357 ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, 0, BIT(d->hwirq));
358}
359
360static struct irq_chip ar2315_pci_irq_chip = {
361 .name = "AR2315-PCI",
362 .irq_mask = ar2315_pci_irq_mask,
363 .irq_mask_ack = ar2315_pci_irq_mask_ack,
364 .irq_unmask = ar2315_pci_irq_unmask,
365};
366
367static int ar2315_pci_irq_map(struct irq_domain *d, unsigned irq,
368 irq_hw_number_t hw)
369{
370 irq_set_chip_and_handler(irq, &ar2315_pci_irq_chip, handle_level_irq);
371 irq_set_chip_data(irq, d->host_data);
372 return 0;
373}
374
375static struct irq_domain_ops ar2315_pci_irq_domain_ops = {
376 .map = ar2315_pci_irq_map,
377};
378
379static void ar2315_pci_irq_init(struct ar2315_pci_ctrl *apc)
380{
381 ar2315_pci_reg_mask(apc, AR2315_PCI_IER, AR2315_PCI_IER_ENABLE, 0);
382 ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, (AR2315_PCI_INT_ABORT |
383 AR2315_PCI_INT_EXT), 0);
384
385 apc->irq_ext = irq_create_mapping(apc->domain, AR2315_PCI_IRQ_EXT);
386
387 irq_set_chained_handler(apc->irq, ar2315_pci_irq_handler);
388 irq_set_handler_data(apc->irq, apc);
389
390 /* Clear any pending Abort or external Interrupts
391 * and enable interrupt processing */
392 ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT |
393 AR2315_PCI_INT_EXT);
394 ar2315_pci_reg_mask(apc, AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE);
395}
396
397static int ar2315_pci_probe(struct platform_device *pdev)
398{
399 struct ar2315_pci_ctrl *apc;
400 struct device *dev = &pdev->dev;
401 struct resource *res;
402 int irq, err;
403
404 apc = devm_kzalloc(dev, sizeof(*apc), GFP_KERNEL);
405 if (!apc)
406 return -ENOMEM;
407
408 irq = platform_get_irq(pdev, 0);
409 if (irq < 0)
410 return -EINVAL;
411 apc->irq = irq;
412
413 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
414 "ar2315-pci-ctrl");
415 apc->mmr_mem = devm_ioremap_resource(dev, res);
416 if (IS_ERR(apc->mmr_mem))
417 return PTR_ERR(apc->mmr_mem);
418
419 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
420 "ar2315-pci-ext");
421 if (!res)
422 return -EINVAL;
423
424 apc->mem_res.name = "AR2315 PCI mem space";
425 apc->mem_res.parent = res;
426 apc->mem_res.start = res->start;
427 apc->mem_res.end = res->end;
428 apc->mem_res.flags = IORESOURCE_MEM;
429
430 /* Remap PCI config space */
431 apc->cfg_mem = devm_ioremap_nocache(dev, res->start,
432 AR2315_PCI_CFG_SIZE);
433 if (!apc->cfg_mem) {
434 dev_err(dev, "failed to remap PCI config space\n");
435 return -ENOMEM;
436 }
437
438 /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */
439 ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG,
440 AR2315_PCIMISC_RST_MODE,
441 AR2315_PCIRST_LOW);
442 msleep(100);
443
444 /* Bring the PCI out of reset */
445 ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG,
446 AR2315_PCIMISC_RST_MODE,
447 AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8);
448
449 ar2315_pci_reg_write(apc, AR2315_PCI_UNCACHE_CFG,
450 0x1E | /* 1GB uncached */
451 (1 << 5) | /* Enable uncached */
452 (0x2 << 30) /* Base: 0x80000000 */);
453 ar2315_pci_reg_read(apc, AR2315_PCI_UNCACHE_CFG);
454
455 msleep(500);
456
457 err = ar2315_pci_host_setup(apc);
458 if (err)
459 return err;
460
461 apc->domain = irq_domain_add_linear(NULL, AR2315_PCI_IRQ_COUNT,
462 &ar2315_pci_irq_domain_ops, apc);
463 if (!apc->domain) {
464 dev_err(dev, "failed to add IRQ domain\n");
465 return -ENOMEM;
466 }
467
468 ar2315_pci_irq_init(apc);
469
470 /* PCI controller does not support I/O ports */
471 apc->io_res.name = "AR2315 IO space";
472 apc->io_res.start = 0;
473 apc->io_res.end = 0;
474 apc->io_res.flags = IORESOURCE_IO,
475
476 apc->pci_ctrl.pci_ops = &ar2315_pci_ops;
477 apc->pci_ctrl.mem_resource = &apc->mem_res,
478 apc->pci_ctrl.io_resource = &apc->io_res,
479
480 register_pci_controller(&apc->pci_ctrl);
481
482 dev_info(dev, "register PCI controller\n");
483
484 return 0;
485}
486
487static struct platform_driver ar2315_pci_driver = {
488 .probe = ar2315_pci_probe,
489 .driver = {
490 .name = "ar2315-pci",
491 .owner = THIS_MODULE,
492 },
493};
494
495static int __init ar2315_pci_init(void)
496{
497 return platform_driver_register(&ar2315_pci_driver);
498}
499arch_initcall(ar2315_pci_init);
500
501int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
502{
503 struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(dev->bus);
504
505 return slot ? 0 : apc->irq_ext;
506}
507
508int pcibios_plat_dev_init(struct pci_dev *dev)
509{
510 return 0;
511}
diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c
index d471a26dd5f8..2b534aea20e4 100644
--- a/arch/mips/pci/pci-ar71xx.c
+++ b/arch/mips/pci/pci-ar71xx.c
@@ -50,7 +50,6 @@
50 50
51struct ar71xx_pci_controller { 51struct ar71xx_pci_controller {
52 void __iomem *cfg_base; 52 void __iomem *cfg_base;
53 spinlock_t lock;
54 int irq; 53 int irq;
55 int irq_base; 54 int irq_base;
56 struct pci_controller pci_ctrl; 55 struct pci_controller pci_ctrl;
@@ -182,7 +181,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
182{ 181{
183 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); 182 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
184 void __iomem *base = apc->cfg_base; 183 void __iomem *base = apc->cfg_base;
185 unsigned long flags;
186 u32 data; 184 u32 data;
187 int err; 185 int err;
188 int ret; 186 int ret;
@@ -190,8 +188,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
190 ret = PCIBIOS_SUCCESSFUL; 188 ret = PCIBIOS_SUCCESSFUL;
191 data = ~0; 189 data = ~0;
192 190
193 spin_lock_irqsave(&apc->lock, flags);
194
195 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, 191 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
196 AR71XX_PCI_CFG_CMD_READ); 192 AR71XX_PCI_CFG_CMD_READ);
197 if (err) 193 if (err)
@@ -199,8 +195,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
199 else 195 else
200 data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); 196 data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA);
201 197
202 spin_unlock_irqrestore(&apc->lock, flags);
203
204 *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; 198 *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7];
205 199
206 return ret; 200 return ret;
@@ -211,15 +205,12 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
211{ 205{
212 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); 206 struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus);
213 void __iomem *base = apc->cfg_base; 207 void __iomem *base = apc->cfg_base;
214 unsigned long flags;
215 int err; 208 int err;
216 int ret; 209 int ret;
217 210
218 value = value << (8 * (where & 3)); 211 value = value << (8 * (where & 3));
219 ret = PCIBIOS_SUCCESSFUL; 212 ret = PCIBIOS_SUCCESSFUL;
220 213
221 spin_lock_irqsave(&apc->lock, flags);
222
223 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, 214 err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
224 AR71XX_PCI_CFG_CMD_WRITE); 215 AR71XX_PCI_CFG_CMD_WRITE);
225 if (err) 216 if (err)
@@ -227,8 +218,6 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
227 else 218 else
228 __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); 219 __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA);
229 220
230 spin_unlock_irqrestore(&apc->lock, flags);
231
232 return ret; 221 return ret;
233} 222}
234 223
@@ -360,8 +349,6 @@ static int ar71xx_pci_probe(struct platform_device *pdev)
360 if (!apc) 349 if (!apc)
361 return -ENOMEM; 350 return -ENOMEM;
362 351
363 spin_lock_init(&apc->lock);
364
365 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); 352 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base");
366 apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); 353 apc->cfg_base = devm_ioremap_resource(&pdev->dev, res);
367 if (IS_ERR(apc->cfg_base)) 354 if (IS_ERR(apc->cfg_base))
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
index 785b2659b519..b7a6fcbb8852 100644
--- a/arch/mips/pci/pci-ar724x.c
+++ b/arch/mips/pci/pci-ar724x.c
@@ -9,7 +9,6 @@
9 * by the Free Software Foundation. 9 * by the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/spinlock.h>
13#include <linux/irq.h> 12#include <linux/irq.h>
14#include <linux/pci.h> 13#include <linux/pci.h>
15#include <linux/module.h> 14#include <linux/module.h>
@@ -48,8 +47,6 @@ struct ar724x_pci_controller {
48 bool bar0_is_cached; 47 bool bar0_is_cached;
49 u32 bar0_value; 48 u32 bar0_value;
50 49
51 spinlock_t lock;
52
53 struct pci_controller pci_controller; 50 struct pci_controller pci_controller;
54 struct resource io_res; 51 struct resource io_res;
55 struct resource mem_res; 52 struct resource mem_res;
@@ -75,7 +72,6 @@ pci_bus_to_ar724x_controller(struct pci_bus *bus)
75static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, 72static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
76 int where, int size, u32 value) 73 int where, int size, u32 value)
77{ 74{
78 unsigned long flags;
79 void __iomem *base; 75 void __iomem *base;
80 u32 data; 76 u32 data;
81 int s; 77 int s;
@@ -86,8 +82,6 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
86 return PCIBIOS_DEVICE_NOT_FOUND; 82 return PCIBIOS_DEVICE_NOT_FOUND;
87 83
88 base = apc->crp_base; 84 base = apc->crp_base;
89
90 spin_lock_irqsave(&apc->lock, flags);
91 data = __raw_readl(base + (where & ~3)); 85 data = __raw_readl(base + (where & ~3));
92 86
93 switch (size) { 87 switch (size) {
@@ -105,14 +99,12 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc,
105 data = value; 99 data = value;
106 break; 100 break;
107 default: 101 default:
108 spin_unlock_irqrestore(&apc->lock, flags);
109 return PCIBIOS_BAD_REGISTER_NUMBER; 102 return PCIBIOS_BAD_REGISTER_NUMBER;
110 } 103 }
111 104
112 __raw_writel(data, base + (where & ~3)); 105 __raw_writel(data, base + (where & ~3));
113 /* flush write */ 106 /* flush write */
114 __raw_readl(base + (where & ~3)); 107 __raw_readl(base + (where & ~3));
115 spin_unlock_irqrestore(&apc->lock, flags);
116 108
117 return PCIBIOS_SUCCESSFUL; 109 return PCIBIOS_SUCCESSFUL;
118} 110}
@@ -121,7 +113,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
121 int size, uint32_t *value) 113 int size, uint32_t *value)
122{ 114{
123 struct ar724x_pci_controller *apc; 115 struct ar724x_pci_controller *apc;
124 unsigned long flags;
125 void __iomem *base; 116 void __iomem *base;
126 u32 data; 117 u32 data;
127 118
@@ -133,8 +124,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
133 return PCIBIOS_DEVICE_NOT_FOUND; 124 return PCIBIOS_DEVICE_NOT_FOUND;
134 125
135 base = apc->devcfg_base; 126 base = apc->devcfg_base;
136
137 spin_lock_irqsave(&apc->lock, flags);
138 data = __raw_readl(base + (where & ~3)); 127 data = __raw_readl(base + (where & ~3));
139 128
140 switch (size) { 129 switch (size) {
@@ -153,13 +142,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
153 case 4: 142 case 4:
154 break; 143 break;
155 default: 144 default:
156 spin_unlock_irqrestore(&apc->lock, flags);
157
158 return PCIBIOS_BAD_REGISTER_NUMBER; 145 return PCIBIOS_BAD_REGISTER_NUMBER;
159 } 146 }
160 147
161 spin_unlock_irqrestore(&apc->lock, flags);
162
163 if (where == PCI_BASE_ADDRESS_0 && size == 4 && 148 if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
164 apc->bar0_is_cached) { 149 apc->bar0_is_cached) {
165 /* use the cached value */ 150 /* use the cached value */
@@ -175,7 +160,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
175 int size, uint32_t value) 160 int size, uint32_t value)
176{ 161{
177 struct ar724x_pci_controller *apc; 162 struct ar724x_pci_controller *apc;
178 unsigned long flags;
179 void __iomem *base; 163 void __iomem *base;
180 u32 data; 164 u32 data;
181 int s; 165 int s;
@@ -209,8 +193,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
209 } 193 }
210 194
211 base = apc->devcfg_base; 195 base = apc->devcfg_base;
212
213 spin_lock_irqsave(&apc->lock, flags);
214 data = __raw_readl(base + (where & ~3)); 196 data = __raw_readl(base + (where & ~3));
215 197
216 switch (size) { 198 switch (size) {
@@ -228,15 +210,12 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
228 data = value; 210 data = value;
229 break; 211 break;
230 default: 212 default:
231 spin_unlock_irqrestore(&apc->lock, flags);
232
233 return PCIBIOS_BAD_REGISTER_NUMBER; 213 return PCIBIOS_BAD_REGISTER_NUMBER;
234 } 214 }
235 215
236 __raw_writel(data, base + (where & ~3)); 216 __raw_writel(data, base + (where & ~3));
237 /* flush write */ 217 /* flush write */
238 __raw_readl(base + (where & ~3)); 218 __raw_readl(base + (where & ~3));
239 spin_unlock_irqrestore(&apc->lock, flags);
240 219
241 return PCIBIOS_SUCCESSFUL; 220 return PCIBIOS_SUCCESSFUL;
242} 221}
@@ -380,8 +359,6 @@ static int ar724x_pci_probe(struct platform_device *pdev)
380 if (apc->irq < 0) 359 if (apc->irq < 0)
381 return -EINVAL; 360 return -EINVAL;
382 361
383 spin_lock_init(&apc->lock);
384
385 res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); 362 res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base");
386 if (!res) 363 if (!res)
387 return -EINVAL; 364 return -EINVAL;
diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c
new file mode 100644
index 000000000000..a4574947e698
--- /dev/null
+++ b/arch/mips/pci/pci-rt2880.c
@@ -0,0 +1,285 @@
1/*
2 * Ralink RT288x SoC PCI register definitions
3 *
4 * Copyright (C) 2009 John Crispin <blogic@openwrt.org>
5 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
6 *
7 * Parts of this file are based on Ralink's 2.6.21 BSP
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <linux/types.h>
15#include <linux/pci.h>
16#include <linux/io.h>
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/of_platform.h>
20#include <linux/of_irq.h>
21#include <linux/of_pci.h>
22
23#include <asm/mach-ralink/rt288x.h>
24
25#define RT2880_PCI_BASE 0x00440000
26#define RT288X_CPU_IRQ_PCI 4
27
28#define RT2880_PCI_MEM_BASE 0x20000000
29#define RT2880_PCI_MEM_SIZE 0x10000000
30#define RT2880_PCI_IO_BASE 0x00460000
31#define RT2880_PCI_IO_SIZE 0x00010000
32
33#define RT2880_PCI_REG_PCICFG_ADDR 0x00
34#define RT2880_PCI_REG_PCIMSK_ADDR 0x0c
35#define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10
36#define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18
37#define RT2880_PCI_REG_CONFIG_ADDR 0x20
38#define RT2880_PCI_REG_CONFIG_DATA 0x24
39#define RT2880_PCI_REG_MEMBASE 0x28
40#define RT2880_PCI_REG_IOBASE 0x2c
41#define RT2880_PCI_REG_ID 0x30
42#define RT2880_PCI_REG_CLASS 0x34
43#define RT2880_PCI_REG_SUBID 0x38
44#define RT2880_PCI_REG_ARBCTL 0x80
45
46static void __iomem *rt2880_pci_base;
47static DEFINE_SPINLOCK(rt2880_pci_lock);
48
49static u32 rt2880_pci_reg_read(u32 reg)
50{
51 return readl(rt2880_pci_base + reg);
52}
53
54static void rt2880_pci_reg_write(u32 val, u32 reg)
55{
56 writel(val, rt2880_pci_base + reg);
57}
58
59static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot,
60 unsigned int func, unsigned int where)
61{
62 return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) |
63 0x80000000);
64}
65
66static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn,
67 int where, int size, u32 *val)
68{
69 unsigned long flags;
70 u32 address;
71 u32 data;
72
73 address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
74 PCI_FUNC(devfn), where);
75
76 spin_lock_irqsave(&rt2880_pci_lock, flags);
77 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
78 data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
79 spin_unlock_irqrestore(&rt2880_pci_lock, flags);
80
81 switch (size) {
82 case 1:
83 *val = (data >> ((where & 3) << 3)) & 0xff;
84 break;
85 case 2:
86 *val = (data >> ((where & 3) << 3)) & 0xffff;
87 break;
88 case 4:
89 *val = data;
90 break;
91 }
92
93 return PCIBIOS_SUCCESSFUL;
94}
95
96static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn,
97 int where, int size, u32 val)
98{
99 unsigned long flags;
100 u32 address;
101 u32 data;
102
103 address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
104 PCI_FUNC(devfn), where);
105
106 spin_lock_irqsave(&rt2880_pci_lock, flags);
107 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
108 data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
109
110 switch (size) {
111 case 1:
112 data = (data & ~(0xff << ((where & 3) << 3))) |
113 (val << ((where & 3) << 3));
114 break;
115 case 2:
116 data = (data & ~(0xffff << ((where & 3) << 3))) |
117 (val << ((where & 3) << 3));
118 break;
119 case 4:
120 data = val;
121 break;
122 }
123
124 rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA);
125 spin_unlock_irqrestore(&rt2880_pci_lock, flags);
126
127 return PCIBIOS_SUCCESSFUL;
128}
129
130static struct pci_ops rt2880_pci_ops = {
131 .read = rt2880_pci_config_read,
132 .write = rt2880_pci_config_write,
133};
134
135static struct resource rt2880_pci_mem_resource = {
136 .name = "PCI MEM space",
137 .start = RT2880_PCI_MEM_BASE,
138 .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1,
139 .flags = IORESOURCE_MEM,
140};
141
142static struct resource rt2880_pci_io_resource = {
143 .name = "PCI IO space",
144 .start = RT2880_PCI_IO_BASE,
145 .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1,
146 .flags = IORESOURCE_IO,
147};
148
149static struct pci_controller rt2880_pci_controller = {
150 .pci_ops = &rt2880_pci_ops,
151 .mem_resource = &rt2880_pci_mem_resource,
152 .io_resource = &rt2880_pci_io_resource,
153};
154
155static inline u32 rt2880_pci_read_u32(unsigned long reg)
156{
157 unsigned long flags;
158 u32 address;
159 u32 ret;
160
161 address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
162
163 spin_lock_irqsave(&rt2880_pci_lock, flags);
164 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
165 ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA);
166 spin_unlock_irqrestore(&rt2880_pci_lock, flags);
167
168 return ret;
169}
170
171static inline void rt2880_pci_write_u32(unsigned long reg, u32 val)
172{
173 unsigned long flags;
174 u32 address;
175
176 address = rt2880_pci_get_cfgaddr(0, 0, 0, reg);
177
178 spin_lock_irqsave(&rt2880_pci_lock, flags);
179 rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR);
180 rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA);
181 spin_unlock_irqrestore(&rt2880_pci_lock, flags);
182}
183
184int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
185{
186 u16 cmd;
187 int irq = -1;
188
189 if (dev->bus->number != 0)
190 return irq;
191
192 switch (PCI_SLOT(dev->devfn)) {
193 case 0x00:
194 rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
195 (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
196 break;
197 case 0x11:
198 irq = RT288X_CPU_IRQ_PCI;
199 break;
200 default:
201 pr_err("%s:%s[%d] trying to alloc unknown pci irq\n",
202 __FILE__, __func__, __LINE__);
203 BUG();
204 break;
205 }
206
207 pci_write_config_byte((struct pci_dev *) dev,
208 PCI_CACHE_LINE_SIZE, 0x14);
209 pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF);
210 pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd);
211 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
212 PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK |
213 PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY;
214 pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd);
215 pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE,
216 dev->irq);
217 return irq;
218}
219
220static int rt288x_pci_probe(struct platform_device *pdev)
221{
222 void __iomem *io_map_base;
223 int i;
224
225 rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE);
226
227 io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE);
228 rt2880_pci_controller.io_map_base = (unsigned long) io_map_base;
229 set_io_port_base((unsigned long) io_map_base);
230
231 ioport_resource.start = RT2880_PCI_IO_BASE;
232 ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1;
233
234 rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR);
235 for (i = 0; i < 0xfffff; i++)
236 ;
237
238 rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL);
239 rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR);
240 rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE);
241 rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE);
242 rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR);
243 rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID);
244 rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS);
245 rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID);
246 rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR);
247
248 rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000);
249 (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0);
250
251 register_pci_controller(&rt2880_pci_controller);
252 return 0;
253}
254
255int pcibios_plat_dev_init(struct pci_dev *dev)
256{
257 return 0;
258}
259
260static const struct of_device_id rt288x_pci_match[] = {
261 { .compatible = "ralink,rt288x-pci" },
262 {},
263};
264MODULE_DEVICE_TABLE(of, rt288x_pci_match);
265
266static struct platform_driver rt288x_pci_driver = {
267 .probe = rt288x_pci_probe,
268 .driver = {
269 .name = "rt288x-pci",
270 .owner = THIS_MODULE,
271 .of_match_table = rt288x_pci_match,
272 },
273};
274
275int __init pcibios_init(void)
276{
277 int ret = platform_driver_register(&rt288x_pci_driver);
278
279 if (ret)
280 pr_info("rt288x-pci: Error registering platform driver!");
281
282 return ret;
283}
284
285arch_initcall(pcibios_init);
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index 72919aeef42b..0bcc0b1cfddc 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -61,7 +61,6 @@
61 61
62struct rt3883_pci_controller { 62struct rt3883_pci_controller {
63 void __iomem *base; 63 void __iomem *base;
64 spinlock_t lock;
65 64
66 struct device_node *intc_of_node; 65 struct device_node *intc_of_node;
67 struct irq_domain *irq_domain; 66 struct irq_domain *irq_domain;
@@ -111,10 +110,8 @@ static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc,
111 110
112 address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); 111 address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);
113 112
114 spin_lock_irqsave(&rpc->lock, flags);
115 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 113 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
116 ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 114 ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
117 spin_unlock_irqrestore(&rpc->lock, flags);
118 115
119 return ret; 116 return ret;
120} 117}
@@ -128,10 +125,8 @@ static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc,
128 125
129 address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); 126 address = rt3883_pci_get_cfgaddr(bus, slot, func, reg);
130 127
131 spin_lock_irqsave(&rpc->lock, flags);
132 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 128 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
133 rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); 129 rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA);
134 spin_unlock_irqrestore(&rpc->lock, flags);
135} 130}
136 131
137static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) 132static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
@@ -252,10 +247,8 @@ static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn,
252 address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), 247 address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
253 PCI_FUNC(devfn), where); 248 PCI_FUNC(devfn), where);
254 249
255 spin_lock_irqsave(&rpc->lock, flags);
256 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 250 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
257 data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 251 data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
258 spin_unlock_irqrestore(&rpc->lock, flags);
259 252
260 switch (size) { 253 switch (size) {
261 case 1: 254 case 1:
@@ -288,7 +281,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn,
288 address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), 281 address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn),
289 PCI_FUNC(devfn), where); 282 PCI_FUNC(devfn), where);
290 283
291 spin_lock_irqsave(&rpc->lock, flags);
292 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); 284 rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR);
293 data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); 285 data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA);
294 286
@@ -307,7 +299,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn,
307 } 299 }
308 300
309 rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); 301 rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA);
310 spin_unlock_irqrestore(&rpc->lock, flags);
311 302
312 return PCIBIOS_SUCCESSFUL; 303 return PCIBIOS_SUCCESSFUL;
313} 304}
diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c
index c10fbf2a19dc..cd8ed09c4f53 100644
--- a/arch/mips/pci/pci-tx4939.c
+++ b/arch/mips/pci/pci-tx4939.c
@@ -103,5 +103,5 @@ void __init tx4939_setup_pcierr_irq(void)
103 tx4927_pcierr_interrupt, 103 tx4927_pcierr_interrupt,
104 0, "PCI error", 104 0, "PCI error",
105 (void *)TX4939_PCIC_REG)) 105 (void *)TX4939_PCIC_REG))
106 pr_warning("Failed to request irq for PCIERR\n"); 106 pr_warn("Failed to request irq for PCIERR\n");
107} 107}
diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c
index 1c9897531660..ef620a4c82a5 100644
--- a/arch/mips/pmcs-msp71xx/msp_prom.c
+++ b/arch/mips/pmcs-msp71xx/msp_prom.c
@@ -295,7 +295,7 @@ char *prom_getenv(char *env_name)
295 295
296 while (*var) { 296 while (*var) {
297 if (strncmp(env_name, *var, i) == 0) { 297 if (strncmp(env_name, *var, i) == 0) {
298 return (*var + strlen(env_name) + 1); 298 return *var + strlen(env_name) + 1;
299 } 299 }
300 var++; 300 var++;
301 } 301 }
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig
index 77e8a9620e18..b1c52ca580f9 100644
--- a/arch/mips/ralink/Kconfig
+++ b/arch/mips/ralink/Kconfig
@@ -16,6 +16,7 @@ choice
16 config SOC_RT288X 16 config SOC_RT288X
17 bool "RT288x" 17 bool "RT288x"
18 select MIPS_L1_CACHE_SHIFT_4 18 select MIPS_L1_CACHE_SHIFT_4
19 select HW_HAS_PCI
19 20
20 config SOC_RT305X 21 config SOC_RT305X
21 bool "RT305x" 22 bool "RT305x"
@@ -26,7 +27,7 @@ choice
26 select HW_HAS_PCI 27 select HW_HAS_PCI
27 28
28 config SOC_MT7620 29 config SOC_MT7620
29 bool "MT7620" 30 bool "MT7620/8"
30 31
31endchoice 32endchoice
32 33
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile
index 2c09c8aa0ae2..a6c9d0061326 100644
--- a/arch/mips/ralink/Makefile
+++ b/arch/mips/ralink/Makefile
@@ -10,9 +10,13 @@ obj-y := prom.o of.o reset.o clk.o irq.o timer.o
10 10
11obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o 11obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
12 12
13obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
14
13obj-$(CONFIG_SOC_RT288X) += rt288x.o 15obj-$(CONFIG_SOC_RT288X) += rt288x.o
14obj-$(CONFIG_SOC_RT305X) += rt305x.o 16obj-$(CONFIG_SOC_RT305X) += rt305x.o
15obj-$(CONFIG_SOC_RT3883) += rt3883.o 17obj-$(CONFIG_SOC_RT3883) += rt3883.o
16obj-$(CONFIG_SOC_MT7620) += mt7620.o 18obj-$(CONFIG_SOC_MT7620) += mt7620.o
17 19
18obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 20obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
21
22obj-$(CONFIG_DEBUG_FS) += bootrom.o
diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c
new file mode 100644
index 000000000000..5403468394fb
--- /dev/null
+++ b/arch/mips/ralink/bootrom.c
@@ -0,0 +1,48 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/debugfs.h>
10#include <linux/seq_file.h>
11
12#define BOOTROM_OFFSET 0x10118000
13#define BOOTROM_SIZE 0x8000
14
15static void __iomem *membase = (void __iomem *) KSEG1ADDR(BOOTROM_OFFSET);
16
17static int bootrom_show(struct seq_file *s, void *unused)
18{
19 seq_write(s, membase, BOOTROM_SIZE);
20
21 return 0;
22}
23
24static int bootrom_open(struct inode *inode, struct file *file)
25{
26 return single_open(file, bootrom_show, NULL);
27}
28
29static const struct file_operations bootrom_file_ops = {
30 .open = bootrom_open,
31 .read = seq_read,
32 .llseek = seq_lseek,
33 .release = single_release,
34};
35
36static int bootrom_setup(void)
37{
38 if (!debugfs_create_file("bootrom", 0444,
39 NULL, NULL, &bootrom_file_ops)) {
40 pr_err("Failed to create bootrom debugfs file\n");
41
42 return -EINVAL;
43 }
44
45 return 0;
46}
47
48postcore_initcall(bootrom_setup);
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c
index 5d0983d47161..feb5a9bf98b4 100644
--- a/arch/mips/ralink/clk.c
+++ b/arch/mips/ralink/clk.c
@@ -56,6 +56,12 @@ unsigned long clk_get_rate(struct clk *clk)
56} 56}
57EXPORT_SYMBOL_GPL(clk_get_rate); 57EXPORT_SYMBOL_GPL(clk_get_rate);
58 58
59int clk_set_rate(struct clk *clk, unsigned long rate)
60{
61 return -1;
62}
63EXPORT_SYMBOL_GPL(clk_set_rate);
64
59void __init plat_time_init(void) 65void __init plat_time_init(void)
60{ 66{
61 struct clk *clk; 67 struct clk *clk;
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h
index 42dfd6100a2d..8e7d8e618fb9 100644
--- a/arch/mips/ralink/common.h
+++ b/arch/mips/ralink/common.h
@@ -11,25 +11,6 @@
11 11
12#define RAMIPS_SYS_TYPE_LEN 32 12#define RAMIPS_SYS_TYPE_LEN 32
13 13
14struct ralink_pinmux_grp {
15 const char *name;
16 u32 mask;
17 int gpio_first;
18 int gpio_last;
19};
20
21struct ralink_pinmux {
22 struct ralink_pinmux_grp *mode;
23 struct ralink_pinmux_grp *uart;
24 int uart_shift;
25 u32 uart_mask;
26 void (*wdt_reset)(void);
27 struct ralink_pinmux_grp *pci;
28 int pci_shift;
29 u32 pci_mask;
30};
31extern struct ralink_pinmux rt_gpio_pinmux;
32
33struct ralink_soc_info { 14struct ralink_soc_info {
34 unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; 15 unsigned char sys_type[RAMIPS_SYS_TYPE_LEN];
35 unsigned char *compatible; 16 unsigned char *compatible;
diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c
index b46d0419d09b..255d695ec8c6 100644
--- a/arch/mips/ralink/early_printk.c
+++ b/arch/mips/ralink/early_printk.c
@@ -12,21 +12,24 @@
12#include <asm/addrspace.h> 12#include <asm/addrspace.h>
13 13
14#ifdef CONFIG_SOC_RT288X 14#ifdef CONFIG_SOC_RT288X
15#define EARLY_UART_BASE 0x300c00 15#define EARLY_UART_BASE 0x300c00
16#define CHIPID_BASE 0x300004
17#elif defined(CONFIG_SOC_MT7621)
18#define EARLY_UART_BASE 0x1E000c00
19#define CHIPID_BASE 0x1E000004
16#else 20#else
17#define EARLY_UART_BASE 0x10000c00 21#define EARLY_UART_BASE 0x10000c00
22#define CHIPID_BASE 0x10000004
18#endif 23#endif
19 24
20#define UART_REG_RX 0x00 25#define MT7628_CHIP_NAME1 0x20203832
21#define UART_REG_TX 0x04 26
22#define UART_REG_IER 0x08 27#define UART_REG_TX 0x04
23#define UART_REG_IIR 0x0c 28#define UART_REG_LSR 0x14
24#define UART_REG_FCR 0x10 29#define UART_REG_LSR_RT2880 0x1c
25#define UART_REG_LCR 0x14
26#define UART_REG_MCR 0x18
27#define UART_REG_LSR 0x1c
28 30
29static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); 31static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE);
32static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE);
30 33
31static inline void uart_w32(u32 val, unsigned reg) 34static inline void uart_w32(u32 val, unsigned reg)
32{ 35{
@@ -38,11 +41,23 @@ static inline u32 uart_r32(unsigned reg)
38 return __raw_readl(uart_membase + reg); 41 return __raw_readl(uart_membase + reg);
39} 42}
40 43
44static inline int soc_is_mt7628(void)
45{
46 return IS_ENABLED(CONFIG_SOC_MT7620) &&
47 (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1);
48}
49
41void prom_putchar(unsigned char ch) 50void prom_putchar(unsigned char ch)
42{ 51{
43 while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) 52 if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) {
44 ; 53 uart_w32(ch, UART_TX);
45 uart_w32(ch, UART_REG_TX); 54 while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0)
46 while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) 55 ;
47 ; 56 } else {
57 while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0)
58 ;
59 uart_w32(ch, UART_REG_TX);
60 while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0)
61 ;
62 }
48} 63}
diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c
new file mode 100644
index 000000000000..e20b02e3ae28
--- /dev/null
+++ b/arch/mips/ralink/ill_acc.c
@@ -0,0 +1,87 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License version 2 as published
4 * by the Free Software Foundation.
5 *
6 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
7 */
8
9#include <linux/interrupt.h>
10#include <linux/of_platform.h>
11#include <linux/of_irq.h>
12
13#include <asm/mach-ralink/ralink_regs.h>
14
15#define REG_ILL_ACC_ADDR 0x10
16#define REG_ILL_ACC_TYPE 0x14
17
18#define ILL_INT_STATUS BIT(31)
19#define ILL_ACC_WRITE BIT(30)
20#define ILL_ACC_LEN_M 0xff
21#define ILL_ACC_OFF_M 0xf
22#define ILL_ACC_OFF_S 16
23#define ILL_ACC_ID_M 0x7
24#define ILL_ACC_ID_S 8
25
26#define DRV_NAME "ill_acc"
27
28static const char * const ill_acc_ids[] = {
29 "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb",
30};
31
32static irqreturn_t ill_acc_irq_handler(int irq, void *_priv)
33{
34 struct device *dev = (struct device *) _priv;
35 u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR);
36 u32 type = rt_memc_r32(REG_ILL_ACC_TYPE);
37
38 dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n",
39 (type & ILL_ACC_WRITE) ? ("write") : ("read"),
40 ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M],
41 addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M,
42 type & ILL_ACC_LEN_M);
43
44 rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE);
45
46 return IRQ_HANDLED;
47}
48
49static int __init ill_acc_of_setup(void)
50{
51 struct platform_device *pdev;
52 struct device_node *np;
53 int irq;
54
55 /* somehow this driver breaks on RT5350 */
56 if (of_machine_is_compatible("ralink,rt5350-soc"))
57 return -EINVAL;
58
59 np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc");
60 if (!np)
61 return -EINVAL;
62
63 pdev = of_find_device_by_node(np);
64 if (!pdev) {
65 pr_err("%s: failed to lookup pdev\n", np->name);
66 return -EINVAL;
67 }
68
69 irq = irq_of_parse_and_map(np, 0);
70 if (!irq) {
71 dev_err(&pdev->dev, "failed to get irq\n");
72 return -EINVAL;
73 }
74
75 if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) {
76 dev_err(&pdev->dev, "failed to request irq\n");
77 return -EINVAL;
78 }
79
80 rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
81
82 dev_info(&pdev->dev, "irq registered\n");
83
84 return 0;
85}
86
87arch_initcall(ill_acc_of_setup);
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
index 781b3d14a489..7cf91b92e9d1 100644
--- a/arch/mips/ralink/irq.c
+++ b/arch/mips/ralink/irq.c
@@ -20,14 +20,6 @@
20 20
21#include "common.h" 21#include "common.h"
22 22
23/* INTC register offsets */
24#define INTC_REG_STATUS0 0x00
25#define INTC_REG_STATUS1 0x04
26#define INTC_REG_TYPE 0x20
27#define INTC_REG_RAW_STATUS 0x30
28#define INTC_REG_ENABLE 0x34
29#define INTC_REG_DISABLE 0x38
30
31#define INTC_INT_GLOBAL BIT(31) 23#define INTC_INT_GLOBAL BIT(31)
32 24
33#define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) 25#define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2)
@@ -44,16 +36,36 @@
44 36
45#define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) 37#define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9)
46 38
39enum rt_intc_regs_enum {
40 INTC_REG_STATUS0 = 0,
41 INTC_REG_STATUS1,
42 INTC_REG_TYPE,
43 INTC_REG_RAW_STATUS,
44 INTC_REG_ENABLE,
45 INTC_REG_DISABLE,
46};
47
48static u32 rt_intc_regs[] = {
49 [INTC_REG_STATUS0] = 0x00,
50 [INTC_REG_STATUS1] = 0x04,
51 [INTC_REG_TYPE] = 0x20,
52 [INTC_REG_RAW_STATUS] = 0x30,
53 [INTC_REG_ENABLE] = 0x34,
54 [INTC_REG_DISABLE] = 0x38,
55};
56
47static void __iomem *rt_intc_membase; 57static void __iomem *rt_intc_membase;
48 58
59static int rt_perfcount_irq;
60
49static inline void rt_intc_w32(u32 val, unsigned reg) 61static inline void rt_intc_w32(u32 val, unsigned reg)
50{ 62{
51 __raw_writel(val, rt_intc_membase + reg); 63 __raw_writel(val, rt_intc_membase + rt_intc_regs[reg]);
52} 64}
53 65
54static inline u32 rt_intc_r32(unsigned reg) 66static inline u32 rt_intc_r32(unsigned reg)
55{ 67{
56 return __raw_readl(rt_intc_membase + reg); 68 return __raw_readl(rt_intc_membase + rt_intc_regs[reg]);
57} 69}
58 70
59static void ralink_intc_irq_unmask(struct irq_data *d) 71static void ralink_intc_irq_unmask(struct irq_data *d)
@@ -73,6 +85,11 @@ static struct irq_chip ralink_intc_irq_chip = {
73 .irq_mask_ack = ralink_intc_irq_mask, 85 .irq_mask_ack = ralink_intc_irq_mask,
74}; 86};
75 87
88int get_c0_perfcount_int(void)
89{
90 return rt_perfcount_irq;
91}
92
76unsigned int get_c0_compare_int(void) 93unsigned int get_c0_compare_int(void)
77{ 94{
78 return CP0_LEGACY_COMPARE_IRQ; 95 return CP0_LEGACY_COMPARE_IRQ;
@@ -134,6 +151,10 @@ static int __init intc_of_init(struct device_node *node,
134 struct irq_domain *domain; 151 struct irq_domain *domain;
135 int irq; 152 int irq;
136 153
154 if (!of_property_read_u32_array(node, "ralink,intc-registers",
155 rt_intc_regs, 6))
156 pr_info("intc: using register map from devicetree\n");
157
137 irq = irq_of_parse_and_map(node, 0); 158 irq = irq_of_parse_and_map(node, 0);
138 if (!irq) 159 if (!irq)
139 panic("Failed to get INTC IRQ"); 160 panic("Failed to get INTC IRQ");
@@ -167,13 +188,13 @@ static int __init intc_of_init(struct device_node *node,
167 irq_set_handler_data(irq, domain); 188 irq_set_handler_data(irq, domain);
168 189
169 /* tell the kernel which irq is used for performance monitoring */ 190 /* tell the kernel which irq is used for performance monitoring */
170 cp0_perfcount_irq = irq_create_mapping(domain, 9); 191 rt_perfcount_irq = irq_create_mapping(domain, 9);
171 192
172 return 0; 193 return 0;
173} 194}
174 195
175static struct of_device_id __initdata of_irq_ids[] = { 196static struct of_device_id __initdata of_irq_ids[] = {
176 { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, 197 { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
177 { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, 198 { .compatible = "ralink,rt2880-intc", .data = intc_of_init },
178 {}, 199 {},
179}; 200};
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c
index a3ad56c2372d..2ea5ff6dc22e 100644
--- a/arch/mips/ralink/mt7620.c
+++ b/arch/mips/ralink/mt7620.c
@@ -17,124 +17,214 @@
17#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h> 18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/mt7620.h> 19#include <asm/mach-ralink/mt7620.h>
20#include <asm/mach-ralink/pinmux.h>
20 21
21#include "common.h" 22#include "common.h"
22 23
24/* analog */
25#define PMU0_CFG 0x88
26#define PMU_SW_SET BIT(28)
27#define A_DCDC_EN BIT(24)
28#define A_SSC_PERI BIT(19)
29#define A_SSC_GEN BIT(18)
30#define A_SSC_M 0x3
31#define A_SSC_S 16
32#define A_DLY_M 0x7
33#define A_DLY_S 8
34#define A_VTUNE_M 0xff
35
36/* digital */
37#define PMU1_CFG 0x8C
38#define DIG_SW_SEL BIT(25)
39
40/* is this a MT7620 or a MT7628 */
41enum mt762x_soc_type mt762x_soc;
42
23/* does the board have sdram or ddram */ 43/* does the board have sdram or ddram */
24static int dram_type; 44static int dram_type;
25 45
26static struct ralink_pinmux_grp mode_mux[] = { 46static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) };
27 { 47static struct rt2880_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) };
28 .name = "i2c", 48static struct rt2880_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) };
29 .mask = MT7620_GPIO_MODE_I2C, 49static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 22, 2) };
30 .gpio_first = 1, 50static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) };
31 .gpio_last = 2, 51static struct rt2880_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) };
32 }, { 52static struct rt2880_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) };
33 .name = "spi", 53static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) };
34 .mask = MT7620_GPIO_MODE_SPI, 54static struct rt2880_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) };
35 .gpio_first = 3, 55static struct rt2880_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) };
36 .gpio_last = 6, 56static struct rt2880_pmx_func uartf_grp[] = {
37 }, { 57 FUNC("uartf", MT7620_GPIO_MODE_UARTF, 7, 8),
38 .name = "uartlite", 58 FUNC("pcm uartf", MT7620_GPIO_MODE_PCM_UARTF, 7, 8),
39 .mask = MT7620_GPIO_MODE_UART1, 59 FUNC("pcm i2s", MT7620_GPIO_MODE_PCM_I2S, 7, 8),
40 .gpio_first = 15, 60 FUNC("i2s uartf", MT7620_GPIO_MODE_I2S_UARTF, 7, 8),
41 .gpio_last = 16, 61 FUNC("pcm gpio", MT7620_GPIO_MODE_PCM_GPIO, 11, 4),
42 }, { 62 FUNC("gpio uartf", MT7620_GPIO_MODE_GPIO_UARTF, 7, 4),
43 .name = "wdt", 63 FUNC("gpio i2s", MT7620_GPIO_MODE_GPIO_I2S, 7, 4),
44 .mask = MT7620_GPIO_MODE_WDT, 64};
45 .gpio_first = 17, 65static struct rt2880_pmx_func wdt_grp[] = {
46 .gpio_last = 17, 66 FUNC("wdt rst", 0, 17, 1),
47 }, { 67 FUNC("wdt refclk", 0, 17, 1),
48 .name = "mdio", 68 };
49 .mask = MT7620_GPIO_MODE_MDIO, 69static struct rt2880_pmx_func pcie_rst_grp[] = {
50 .gpio_first = 22, 70 FUNC("pcie rst", MT7620_GPIO_MODE_PCIE_RST, 36, 1),
51 .gpio_last = 23, 71 FUNC("pcie refclk", MT7620_GPIO_MODE_PCIE_REF, 36, 1)
52 }, { 72};
53 .name = "rgmii1", 73static struct rt2880_pmx_func nd_sd_grp[] = {
54 .mask = MT7620_GPIO_MODE_RGMII1, 74 FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15),
55 .gpio_first = 24, 75 FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15)
56 .gpio_last = 35, 76};
57 }, { 77
58 .name = "spi refclk", 78static struct rt2880_pmx_group mt7620a_pinmux_data[] = {
59 .mask = MT7620_GPIO_MODE_SPI_REF_CLK, 79 GRP("i2c", i2c_grp, 1, MT7620_GPIO_MODE_I2C),
60 .gpio_first = 37, 80 GRP("uartf", uartf_grp, MT7620_GPIO_MODE_UART0_MASK,
61 .gpio_last = 39, 81 MT7620_GPIO_MODE_UART0_SHIFT),
62 }, { 82 GRP("spi", spi_grp, 1, MT7620_GPIO_MODE_SPI),
63 .name = "jtag", 83 GRP("uartlite", uartlite_grp, 1, MT7620_GPIO_MODE_UART1),
64 .mask = MT7620_GPIO_MODE_JTAG, 84 GRP_G("wdt", wdt_grp, MT7620_GPIO_MODE_WDT_MASK,
65 .gpio_first = 40, 85 MT7620_GPIO_MODE_WDT_GPIO, MT7620_GPIO_MODE_WDT_SHIFT),
66 .gpio_last = 44, 86 GRP("mdio", mdio_grp, 1, MT7620_GPIO_MODE_MDIO),
67 }, { 87 GRP("rgmii1", rgmii1_grp, 1, MT7620_GPIO_MODE_RGMII1),
68 /* shared lines with jtag */ 88 GRP("spi refclk", refclk_grp, 1, MT7620_GPIO_MODE_SPI_REF_CLK),
69 .name = "ephy", 89 GRP_G("pcie", pcie_rst_grp, MT7620_GPIO_MODE_PCIE_MASK,
70 .mask = MT7620_GPIO_MODE_EPHY, 90 MT7620_GPIO_MODE_PCIE_GPIO, MT7620_GPIO_MODE_PCIE_SHIFT),
71 .gpio_first = 40, 91 GRP_G("nd_sd", nd_sd_grp, MT7620_GPIO_MODE_ND_SD_MASK,
72 .gpio_last = 44, 92 MT7620_GPIO_MODE_ND_SD_GPIO, MT7620_GPIO_MODE_ND_SD_SHIFT),
73 }, { 93 GRP("rgmii2", rgmii2_grp, 1, MT7620_GPIO_MODE_RGMII2),
74 .name = "nand", 94 GRP("wled", wled_grp, 1, MT7620_GPIO_MODE_WLED),
75 .mask = MT7620_GPIO_MODE_JTAG, 95 GRP("ephy", ephy_grp, 1, MT7620_GPIO_MODE_EPHY),
76 .gpio_first = 45, 96 GRP("pa", pa_grp, 1, MT7620_GPIO_MODE_PA),
77 .gpio_last = 59, 97 { 0 }
78 }, { 98};
79 .name = "rgmii2", 99
80 .mask = MT7620_GPIO_MODE_RGMII2, 100static struct rt2880_pmx_func pwm1_grp_mt7628[] = {
81 .gpio_first = 60, 101 FUNC("sdcx", 3, 19, 1),
82 .gpio_last = 71, 102 FUNC("utif", 2, 19, 1),
83 }, { 103 FUNC("gpio", 1, 19, 1),
84 .name = "wled", 104 FUNC("pwm", 0, 19, 1),
85 .mask = MT7620_GPIO_MODE_WLED, 105};
86 .gpio_first = 72, 106
87 .gpio_last = 72, 107static struct rt2880_pmx_func pwm0_grp_mt7628[] = {
88 }, {0} 108 FUNC("sdcx", 3, 18, 1),
109 FUNC("utif", 2, 18, 1),
110 FUNC("gpio", 1, 18, 1),
111 FUNC("pwm", 0, 18, 1),
112};
113
114static struct rt2880_pmx_func uart2_grp_mt7628[] = {
115 FUNC("sdcx", 3, 20, 2),
116 FUNC("pwm", 2, 20, 2),
117 FUNC("gpio", 1, 20, 2),
118 FUNC("uart", 0, 20, 2),
119};
120
121static struct rt2880_pmx_func uart1_grp_mt7628[] = {
122 FUNC("sdcx", 3, 45, 2),
123 FUNC("pwm", 2, 45, 2),
124 FUNC("gpio", 1, 45, 2),
125 FUNC("uart", 0, 45, 2),
126};
127
128static struct rt2880_pmx_func i2c_grp_mt7628[] = {
129 FUNC("-", 3, 4, 2),
130 FUNC("debug", 2, 4, 2),
131 FUNC("gpio", 1, 4, 2),
132 FUNC("i2c", 0, 4, 2),
133};
134
135static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) };
136static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) };
137static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) };
138static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) };
139
140static struct rt2880_pmx_func sd_mode_grp_mt7628[] = {
141 FUNC("jtag", 3, 22, 8),
142 FUNC("utif", 2, 22, 8),
143 FUNC("gpio", 1, 22, 8),
144 FUNC("sdcx", 0, 22, 8),
145};
146
147static struct rt2880_pmx_func uart0_grp_mt7628[] = {
148 FUNC("-", 3, 12, 2),
149 FUNC("-", 2, 12, 2),
150 FUNC("gpio", 1, 12, 2),
151 FUNC("uart", 0, 12, 2),
152};
153
154static struct rt2880_pmx_func i2s_grp_mt7628[] = {
155 FUNC("antenna", 3, 0, 4),
156 FUNC("pcm", 2, 0, 4),
157 FUNC("gpio", 1, 0, 4),
158 FUNC("i2s", 0, 0, 4),
159};
160
161static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = {
162 FUNC("-", 3, 6, 1),
163 FUNC("refclk", 2, 6, 1),
164 FUNC("gpio", 1, 6, 1),
165 FUNC("spi", 0, 6, 1),
166};
167
168static struct rt2880_pmx_func spis_grp_mt7628[] = {
169 FUNC("pwm", 3, 14, 4),
170 FUNC("util", 2, 14, 4),
171 FUNC("gpio", 1, 14, 4),
172 FUNC("spis", 0, 14, 4),
89}; 173};
90 174
91static struct ralink_pinmux_grp uart_mux[] = { 175static struct rt2880_pmx_func gpio_grp_mt7628[] = {
92 { 176 FUNC("pcie", 3, 11, 1),
93 .name = "uartf", 177 FUNC("refclk", 2, 11, 1),
94 .mask = MT7620_GPIO_MODE_UARTF, 178 FUNC("gpio", 1, 11, 1),
95 .gpio_first = 7, 179 FUNC("gpio", 0, 11, 1),
96 .gpio_last = 14,
97 }, {
98 .name = "pcm uartf",
99 .mask = MT7620_GPIO_MODE_PCM_UARTF,
100 .gpio_first = 7,
101 .gpio_last = 14,
102 }, {
103 .name = "pcm i2s",
104 .mask = MT7620_GPIO_MODE_PCM_I2S,
105 .gpio_first = 7,
106 .gpio_last = 14,
107 }, {
108 .name = "i2s uartf",
109 .mask = MT7620_GPIO_MODE_I2S_UARTF,
110 .gpio_first = 7,
111 .gpio_last = 14,
112 }, {
113 .name = "pcm gpio",
114 .mask = MT7620_GPIO_MODE_PCM_GPIO,
115 .gpio_first = 11,
116 .gpio_last = 14,
117 }, {
118 .name = "gpio uartf",
119 .mask = MT7620_GPIO_MODE_GPIO_UARTF,
120 .gpio_first = 7,
121 .gpio_last = 10,
122 }, {
123 .name = "gpio i2s",
124 .mask = MT7620_GPIO_MODE_GPIO_I2S,
125 .gpio_first = 7,
126 .gpio_last = 10,
127 }, {
128 .name = "gpio",
129 .mask = MT7620_GPIO_MODE_GPIO,
130 }, {0}
131}; 180};
132 181
133struct ralink_pinmux rt_gpio_pinmux = { 182#define MT7628_GPIO_MODE_MASK 0x3
134 .mode = mode_mux, 183
135 .uart = uart_mux, 184#define MT7628_GPIO_MODE_PWM1 30
136 .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT, 185#define MT7628_GPIO_MODE_PWM0 28
137 .uart_mask = MT7620_GPIO_MODE_UART0_MASK, 186#define MT7628_GPIO_MODE_UART2 26
187#define MT7628_GPIO_MODE_UART1 24
188#define MT7628_GPIO_MODE_I2C 20
189#define MT7628_GPIO_MODE_REFCLK 18
190#define MT7628_GPIO_MODE_PERST 16
191#define MT7628_GPIO_MODE_WDT 14
192#define MT7628_GPIO_MODE_SPI 12
193#define MT7628_GPIO_MODE_SDMODE 10
194#define MT7628_GPIO_MODE_UART0 8
195#define MT7628_GPIO_MODE_I2S 6
196#define MT7628_GPIO_MODE_CS1 4
197#define MT7628_GPIO_MODE_SPIS 2
198#define MT7628_GPIO_MODE_GPIO 0
199
200static struct rt2880_pmx_group mt7628an_pinmux_data[] = {
201 GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK,
202 1, MT7628_GPIO_MODE_PWM1),
203 GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK,
204 1, MT7628_GPIO_MODE_PWM0),
205 GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK,
206 1, MT7628_GPIO_MODE_UART2),
207 GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK,
208 1, MT7628_GPIO_MODE_UART1),
209 GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK,
210 1, MT7628_GPIO_MODE_I2C),
211 GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK),
212 GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST),
213 GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT),
214 GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI),
215 GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK,
216 1, MT7628_GPIO_MODE_SDMODE),
217 GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK,
218 1, MT7628_GPIO_MODE_UART0),
219 GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK,
220 1, MT7628_GPIO_MODE_I2S),
221 GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK,
222 1, MT7628_GPIO_MODE_CS1),
223 GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK,
224 1, MT7628_GPIO_MODE_SPIS),
225 GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK,
226 1, MT7628_GPIO_MODE_GPIO),
227 { 0 }
138}; 228};
139 229
140static __init u32 230static __init u32
@@ -287,29 +377,42 @@ void __init ralink_clk_init(void)
287 377
288 xtal_rate = mt7620_get_xtal_rate(); 378 xtal_rate = mt7620_get_xtal_rate();
289 379
290 cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
291 pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
292
293 cpu_rate = mt7620_get_cpu_rate(pll_rate);
294 dram_rate = mt7620_get_dram_rate(pll_rate);
295 sys_rate = mt7620_get_sys_rate(cpu_rate);
296 periph_rate = mt7620_get_periph_rate(xtal_rate);
297
298#define RFMT(label) label ":%lu.%03luMHz " 380#define RFMT(label) label ":%lu.%03luMHz "
299#define RINT(x) ((x) / 1000000) 381#define RINT(x) ((x) / 1000000)
300#define RFRAC(x) (((x) / 1000) % 1000) 382#define RFRAC(x) (((x) / 1000) % 1000)
301 383
302 pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), 384 if (mt762x_soc == MT762X_SOC_MT7628AN) {
303 RINT(xtal_rate), RFRAC(xtal_rate), 385 if (xtal_rate == MHZ(40))
304 RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), 386 cpu_rate = MHZ(580);
305 RINT(pll_rate), RFRAC(pll_rate)); 387 else
388 cpu_rate = MHZ(575);
389 dram_rate = sys_rate = cpu_rate / 3;
390 periph_rate = MHZ(40);
391
392 ralink_clk_add("10000d00.uartlite", periph_rate);
393 ralink_clk_add("10000e00.uartlite", periph_rate);
394 } else {
395 cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate);
396 pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate);
397
398 cpu_rate = mt7620_get_cpu_rate(pll_rate);
399 dram_rate = mt7620_get_dram_rate(pll_rate);
400 sys_rate = mt7620_get_sys_rate(cpu_rate);
401 periph_rate = mt7620_get_periph_rate(xtal_rate);
402
403 pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"),
404 RINT(xtal_rate), RFRAC(xtal_rate),
405 RINT(cpu_pll_rate), RFRAC(cpu_pll_rate),
406 RINT(pll_rate), RFRAC(pll_rate));
407
408 ralink_clk_add("10000500.uart", periph_rate);
409 }
306 410
307 pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"), 411 pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"),
308 RINT(cpu_rate), RFRAC(cpu_rate), 412 RINT(cpu_rate), RFRAC(cpu_rate),
309 RINT(dram_rate), RFRAC(dram_rate), 413 RINT(dram_rate), RFRAC(dram_rate),
310 RINT(sys_rate), RFRAC(sys_rate), 414 RINT(sys_rate), RFRAC(sys_rate),
311 RINT(periph_rate), RFRAC(periph_rate)); 415 RINT(periph_rate), RFRAC(periph_rate));
312
313#undef RFRAC 416#undef RFRAC
314#undef RINT 417#undef RINT
315#undef RFMT 418#undef RFMT
@@ -317,9 +420,9 @@ void __init ralink_clk_init(void)
317 ralink_clk_add("cpu", cpu_rate); 420 ralink_clk_add("cpu", cpu_rate);
318 ralink_clk_add("10000100.timer", periph_rate); 421 ralink_clk_add("10000100.timer", periph_rate);
319 ralink_clk_add("10000120.watchdog", periph_rate); 422 ralink_clk_add("10000120.watchdog", periph_rate);
320 ralink_clk_add("10000500.uart", periph_rate);
321 ralink_clk_add("10000b00.spi", sys_rate); 423 ralink_clk_add("10000b00.spi", sys_rate);
322 ralink_clk_add("10000c00.uartlite", periph_rate); 424 ralink_clk_add("10000c00.uartlite", periph_rate);
425 ralink_clk_add("10180000.wmac", xtal_rate);
323} 426}
324 427
325void __init ralink_of_remap(void) 428void __init ralink_of_remap(void)
@@ -331,6 +434,52 @@ void __init ralink_of_remap(void)
331 panic("Failed to remap core resources"); 434 panic("Failed to remap core resources");
332} 435}
333 436
437static __init void
438mt7620_dram_init(struct ralink_soc_info *soc_info)
439{
440 switch (dram_type) {
441 case SYSCFG0_DRAM_TYPE_SDRAM:
442 pr_info("Board has SDRAM\n");
443 soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN;
444 soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX;
445 break;
446
447 case SYSCFG0_DRAM_TYPE_DDR1:
448 pr_info("Board has DDR1\n");
449 soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
450 soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
451 break;
452
453 case SYSCFG0_DRAM_TYPE_DDR2:
454 pr_info("Board has DDR2\n");
455 soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
456 soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
457 break;
458 default:
459 BUG();
460 }
461}
462
463static __init void
464mt7628_dram_init(struct ralink_soc_info *soc_info)
465{
466 switch (dram_type) {
467 case SYSCFG0_DRAM_TYPE_DDR1_MT7628:
468 pr_info("Board has DDR1\n");
469 soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
470 soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
471 break;
472
473 case SYSCFG0_DRAM_TYPE_DDR2_MT7628:
474 pr_info("Board has DDR2\n");
475 soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
476 soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
477 break;
478 default:
479 BUG();
480 }
481}
482
334void prom_soc_init(struct ralink_soc_info *soc_info) 483void prom_soc_init(struct ralink_soc_info *soc_info)
335{ 484{
336 void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE); 485 void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE);
@@ -339,22 +488,36 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
339 u32 n1; 488 u32 n1;
340 u32 rev; 489 u32 rev;
341 u32 cfg0; 490 u32 cfg0;
491 u32 pmu0;
492 u32 pmu1;
493 u32 bga;
342 494
343 n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); 495 n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
344 n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); 496 n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
345 497 rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
346 if (n0 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) { 498 bga = (rev >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK;
347 name = "MT7620N"; 499
348 soc_info->compatible = "ralink,mt7620n-soc"; 500 if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) {
349 } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) { 501 if (bga) {
350 name = "MT7620A"; 502 mt762x_soc = MT762X_SOC_MT7620A;
351 soc_info->compatible = "ralink,mt7620a-soc"; 503 name = "MT7620A";
504 soc_info->compatible = "ralink,mt7620a-soc";
505 } else {
506 mt762x_soc = MT762X_SOC_MT7620N;
507 name = "MT7620N";
508 soc_info->compatible = "ralink,mt7620n-soc";
509#ifdef CONFIG_PCI
510 panic("mt7620n is only supported for non pci kernels");
511#endif
512 }
513 } else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) {
514 mt762x_soc = MT762X_SOC_MT7628AN;
515 name = "MT7628AN";
516 soc_info->compatible = "ralink,mt7628an-soc";
352 } else { 517 } else {
353 panic("mt7620: unknown SoC, n0:%08x n1:%08x", n0, n1); 518 panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
354 } 519 }
355 520
356 rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
357
358 snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, 521 snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
359 "Ralink %s ver:%u eco:%u", 522 "Ralink %s ver:%u eco:%u",
360 name, 523 name,
@@ -364,26 +527,22 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
364 cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); 527 cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0);
365 dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; 528 dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK;
366 529
367 switch (dram_type) {
368 case SYSCFG0_DRAM_TYPE_SDRAM:
369 pr_info("Board has SDRAM\n");
370 soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN;
371 soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX;
372 break;
373
374 case SYSCFG0_DRAM_TYPE_DDR1:
375 pr_info("Board has DDR1\n");
376 soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN;
377 soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX;
378 break;
379
380 case SYSCFG0_DRAM_TYPE_DDR2:
381 pr_info("Board has DDR2\n");
382 soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN;
383 soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX;
384 break;
385 default:
386 BUG();
387 }
388 soc_info->mem_base = MT7620_DRAM_BASE; 530 soc_info->mem_base = MT7620_DRAM_BASE;
531 if (mt762x_soc == MT762X_SOC_MT7628AN)
532 mt7628_dram_init(soc_info);
533 else
534 mt7620_dram_init(soc_info);
535
536 pmu0 = __raw_readl(sysc + PMU0_CFG);
537 pmu1 = __raw_readl(sysc + PMU1_CFG);
538
539 pr_info("Analog PMU set to %s control\n",
540 (pmu0 & PMU_SW_SET) ? ("sw") : ("hw"));
541 pr_info("Digital PMU set to %s control\n",
542 (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw"));
543
544 if (mt762x_soc == MT762X_SOC_MT7628AN)
545 rt2880_pinmux_data = mt7628an_pinmux_data;
546 else
547 rt2880_pinmux_data = mt7620a_pinmux_data;
389} 548}
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
index 7c4598cb6de8..0d30dcd63246 100644
--- a/arch/mips/ralink/of.c
+++ b/arch/mips/ralink/of.c
@@ -53,6 +53,17 @@ void __init device_tree_init(void)
53 unflatten_and_copy_device_tree(); 53 unflatten_and_copy_device_tree();
54} 54}
55 55
56static int memory_dtb;
57
58static int __init early_init_dt_find_memory(unsigned long node,
59 const char *uname, int depth, void *data)
60{
61 if (depth == 1 && !strcmp(uname, "memory@0"))
62 memory_dtb = 1;
63
64 return 0;
65}
66
56void __init plat_mem_setup(void) 67void __init plat_mem_setup(void)
57{ 68{
58 set_io_port_base(KSEG1); 69 set_io_port_base(KSEG1);
@@ -63,7 +74,12 @@ void __init plat_mem_setup(void)
63 */ 74 */
64 __dt_setup_arch(__dtb_start); 75 __dt_setup_arch(__dtb_start);
65 76
66 if (soc_info.mem_size) 77 strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
78
79 of_scan_flat_dt(early_init_dt_find_memory, NULL);
80 if (memory_dtb)
81 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
82 else if (soc_info.mem_size)
67 add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, 83 add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M,
68 BOOT_MEM_RAM); 84 BOOT_MEM_RAM);
69 else 85 else
@@ -74,19 +90,9 @@ void __init plat_mem_setup(void)
74 90
75static int __init plat_of_setup(void) 91static int __init plat_of_setup(void)
76{ 92{
77 static struct of_device_id of_ids[3]; 93 __dt_register_buses(soc_info.compatible, "palmbus");
78 int len = sizeof(of_ids[0].compatible);
79
80 if (!of_have_populated_dt())
81 panic("device tree not present");
82
83 strlcpy(of_ids[0].compatible, soc_info.compatible, len);
84 strlcpy(of_ids[1].compatible, "palmbus", len);
85
86 if (of_platform_populate(NULL, of_ids, NULL, NULL))
87 panic("failed to populate DT");
88 94
89 /* make sure ithat the reset controller is setup early */ 95 /* make sure that the reset controller is setup early */
90 ralink_rst_init(); 96 ralink_rst_init();
91 97
92 return 0; 98 return 0;
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c
index 9c64f029d047..09419f67da39 100644
--- a/arch/mips/ralink/prom.c
+++ b/arch/mips/ralink/prom.c
@@ -18,6 +18,7 @@
18#include "common.h" 18#include "common.h"
19 19
20struct ralink_soc_info soc_info; 20struct ralink_soc_info soc_info;
21struct rt2880_pmx_group *rt2880_pinmux_data = NULL;
21 22
22const char *get_system_type(void) 23const char *get_system_type(void)
23{ 24{
diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c
index f87de1ab2198..738cec865f41 100644
--- a/arch/mips/ralink/rt288x.c
+++ b/arch/mips/ralink/rt288x.c
@@ -17,46 +17,27 @@
17#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h> 18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/rt288x.h> 19#include <asm/mach-ralink/rt288x.h>
20#include <asm/mach-ralink/pinmux.h>
20 21
21#include "common.h" 22#include "common.h"
22 23
23static struct ralink_pinmux_grp mode_mux[] = { 24static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
24 { 25static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
25 .name = "i2c", 26static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) };
26 .mask = RT2880_GPIO_MODE_I2C, 27static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
27 .gpio_first = 1, 28static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
28 .gpio_last = 2, 29static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
29 }, { 30static struct rt2880_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) };
30 .name = "spi", 31
31 .mask = RT2880_GPIO_MODE_SPI, 32static struct rt2880_pmx_group rt2880_pinmux_data_act[] = {
32 .gpio_first = 3, 33 GRP("i2c", i2c_func, 1, RT2880_GPIO_MODE_I2C),
33 .gpio_last = 6, 34 GRP("spi", spi_func, 1, RT2880_GPIO_MODE_SPI),
34 }, { 35 GRP("uartlite", uartlite_func, 1, RT2880_GPIO_MODE_UART0),
35 .name = "uartlite", 36 GRP("jtag", jtag_func, 1, RT2880_GPIO_MODE_JTAG),
36 .mask = RT2880_GPIO_MODE_UART0, 37 GRP("mdio", mdio_func, 1, RT2880_GPIO_MODE_MDIO),
37 .gpio_first = 7, 38 GRP("sdram", sdram_func, 1, RT2880_GPIO_MODE_SDRAM),
38 .gpio_last = 14, 39 GRP("pci", pci_func, 1, RT2880_GPIO_MODE_PCI),
39 }, { 40 { 0 }
40 .name = "jtag",
41 .mask = RT2880_GPIO_MODE_JTAG,
42 .gpio_first = 17,
43 .gpio_last = 21,
44 }, {
45 .name = "mdio",
46 .mask = RT2880_GPIO_MODE_MDIO,
47 .gpio_first = 22,
48 .gpio_last = 23,
49 }, {
50 .name = "sdram",
51 .mask = RT2880_GPIO_MODE_SDRAM,
52 .gpio_first = 24,
53 .gpio_last = 39,
54 }, {
55 .name = "pci",
56 .mask = RT2880_GPIO_MODE_PCI,
57 .gpio_first = 40,
58 .gpio_last = 71,
59 }, {0}
60}; 41};
61 42
62static void rt288x_wdt_reset(void) 43static void rt288x_wdt_reset(void)
@@ -69,14 +50,9 @@ static void rt288x_wdt_reset(void)
69 rt_sysc_w32(t, SYSC_REG_CLKCFG); 50 rt_sysc_w32(t, SYSC_REG_CLKCFG);
70} 51}
71 52
72struct ralink_pinmux rt_gpio_pinmux = {
73 .mode = mode_mux,
74 .wdt_reset = rt288x_wdt_reset,
75};
76
77void __init ralink_clk_init(void) 53void __init ralink_clk_init(void)
78{ 54{
79 unsigned long cpu_rate; 55 unsigned long cpu_rate, wmac_rate = 40000000;
80 u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); 56 u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG);
81 t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); 57 t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK);
82 58
@@ -101,6 +77,7 @@ void __init ralink_clk_init(void)
101 ralink_clk_add("300500.uart", cpu_rate / 2); 77 ralink_clk_add("300500.uart", cpu_rate / 2);
102 ralink_clk_add("300c00.uartlite", cpu_rate / 2); 78 ralink_clk_add("300c00.uartlite", cpu_rate / 2);
103 ralink_clk_add("400000.ethernet", cpu_rate / 2); 79 ralink_clk_add("400000.ethernet", cpu_rate / 2);
80 ralink_clk_add("480000.wmac", wmac_rate);
104} 81}
105 82
106void __init ralink_of_remap(void) 83void __init ralink_of_remap(void)
@@ -140,4 +117,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
140 soc_info->mem_base = RT2880_SDRAM_BASE; 117 soc_info->mem_base = RT2880_SDRAM_BASE;
141 soc_info->mem_size_min = RT2880_MEM_SIZE_MIN; 118 soc_info->mem_size_min = RT2880_MEM_SIZE_MIN;
142 soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; 119 soc_info->mem_size_max = RT2880_MEM_SIZE_MAX;
120
121 rt2880_pinmux_data = rt2880_pinmux_data_act;
143} 122}
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c
index bb82a82da9e7..c40776ab67db 100644
--- a/arch/mips/ralink/rt305x.c
+++ b/arch/mips/ralink/rt305x.c
@@ -17,90 +17,78 @@
17#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h> 18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/rt305x.h> 19#include <asm/mach-ralink/rt305x.h>
20#include <asm/mach-ralink/pinmux.h>
20 21
21#include "common.h" 22#include "common.h"
22 23
23enum rt305x_soc_type rt305x_soc; 24enum rt305x_soc_type rt305x_soc;
24 25
25static struct ralink_pinmux_grp mode_mux[] = { 26static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
26 { 27static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
27 .name = "i2c", 28static struct rt2880_pmx_func uartf_func[] = {
28 .mask = RT305X_GPIO_MODE_I2C, 29 FUNC("uartf", RT305X_GPIO_MODE_UARTF, 7, 8),
29 .gpio_first = RT305X_GPIO_I2C_SD, 30 FUNC("pcm uartf", RT305X_GPIO_MODE_PCM_UARTF, 7, 8),
30 .gpio_last = RT305X_GPIO_I2C_SCLK, 31 FUNC("pcm i2s", RT305X_GPIO_MODE_PCM_I2S, 7, 8),
31 }, { 32 FUNC("i2s uartf", RT305X_GPIO_MODE_I2S_UARTF, 7, 8),
32 .name = "spi", 33 FUNC("pcm gpio", RT305X_GPIO_MODE_PCM_GPIO, 11, 4),
33 .mask = RT305X_GPIO_MODE_SPI, 34 FUNC("gpio uartf", RT305X_GPIO_MODE_GPIO_UARTF, 7, 4),
34 .gpio_first = RT305X_GPIO_SPI_EN, 35 FUNC("gpio i2s", RT305X_GPIO_MODE_GPIO_I2S, 7, 4),
35 .gpio_last = RT305X_GPIO_SPI_CLK, 36};
36 }, { 37static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
37 .name = "uartlite", 38static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
38 .mask = RT305X_GPIO_MODE_UART1, 39static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
39 .gpio_first = RT305X_GPIO_UART1_TXD, 40static struct rt2880_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) };
40 .gpio_last = RT305X_GPIO_UART1_RXD, 41static struct rt2880_pmx_func rt5350_cs1_func[] = {
41 }, { 42 FUNC("spi_cs1", 0, 27, 1),
42 .name = "jtag", 43 FUNC("wdg_cs1", 1, 27, 1),
43 .mask = RT305X_GPIO_MODE_JTAG, 44};
44 .gpio_first = RT305X_GPIO_JTAG_TDO, 45static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) };
45 .gpio_last = RT305X_GPIO_JTAG_TDI, 46static struct rt2880_pmx_func rt3352_rgmii_func[] = {
46 }, { 47 FUNC("rgmii", 0, 24, 12)
47 .name = "mdio", 48};
48 .mask = RT305X_GPIO_MODE_MDIO, 49static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) };
49 .gpio_first = RT305X_GPIO_MDIO_MDC, 50static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) };
50 .gpio_last = RT305X_GPIO_MDIO_MDIO, 51static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) };
51 }, { 52static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) };
52 .name = "sdram", 53
53 .mask = RT305X_GPIO_MODE_SDRAM, 54static struct rt2880_pmx_group rt3050_pinmux_data[] = {
54 .gpio_first = RT305X_GPIO_SDRAM_MD16, 55 GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
55 .gpio_last = RT305X_GPIO_SDRAM_MD31, 56 GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
56 }, { 57 GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
57 .name = "rgmii", 58 RT305X_GPIO_MODE_UART0_SHIFT),
58 .mask = RT305X_GPIO_MODE_RGMII, 59 GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
59 .gpio_first = RT305X_GPIO_GE0_TXD0, 60 GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
60 .gpio_last = RT305X_GPIO_GE0_RXCLK, 61 GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO),
61 }, {0} 62 GRP("rgmii", rgmii_func, 1, RT305X_GPIO_MODE_RGMII),
63 GRP("sdram", sdram_func, 1, RT305X_GPIO_MODE_SDRAM),
64 { 0 }
62}; 65};
63 66
64static struct ralink_pinmux_grp uart_mux[] = { 67static struct rt2880_pmx_group rt3352_pinmux_data[] = {
65 { 68 GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
66 .name = "uartf", 69 GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
67 .mask = RT305X_GPIO_MODE_UARTF, 70 GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
68 .gpio_first = RT305X_GPIO_7, 71 RT305X_GPIO_MODE_UART0_SHIFT),
69 .gpio_last = RT305X_GPIO_14, 72 GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
70 }, { 73 GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
71 .name = "pcm uartf", 74 GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO),
72 .mask = RT305X_GPIO_MODE_PCM_UARTF, 75 GRP("rgmii", rt3352_rgmii_func, 1, RT305X_GPIO_MODE_RGMII),
73 .gpio_first = RT305X_GPIO_7, 76 GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA),
74 .gpio_last = RT305X_GPIO_14, 77 GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA),
75 }, { 78 GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
76 .name = "pcm i2s", 79 { 0 }
77 .mask = RT305X_GPIO_MODE_PCM_I2S, 80};
78 .gpio_first = RT305X_GPIO_7, 81
79 .gpio_last = RT305X_GPIO_14, 82static struct rt2880_pmx_group rt5350_pinmux_data[] = {
80 }, { 83 GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C),
81 .name = "i2s uartf", 84 GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI),
82 .mask = RT305X_GPIO_MODE_I2S_UARTF, 85 GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK,
83 .gpio_first = RT305X_GPIO_7, 86 RT305X_GPIO_MODE_UART0_SHIFT),
84 .gpio_last = RT305X_GPIO_14, 87 GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1),
85 }, { 88 GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG),
86 .name = "pcm gpio", 89 GRP("led", rt5350_led_func, 1, RT5350_GPIO_MODE_PHY_LED),
87 .mask = RT305X_GPIO_MODE_PCM_GPIO, 90 GRP("spi_cs1", rt5350_cs1_func, 2, RT5350_GPIO_MODE_SPI_CS1),
88 .gpio_first = RT305X_GPIO_10, 91 { 0 }
89 .gpio_last = RT305X_GPIO_14,
90 }, {
91 .name = "gpio uartf",
92 .mask = RT305X_GPIO_MODE_GPIO_UARTF,
93 .gpio_first = RT305X_GPIO_7,
94 .gpio_last = RT305X_GPIO_10,
95 }, {
96 .name = "gpio i2s",
97 .mask = RT305X_GPIO_MODE_GPIO_I2S,
98 .gpio_first = RT305X_GPIO_7,
99 .gpio_last = RT305X_GPIO_10,
100 }, {
101 .name = "gpio",
102 .mask = RT305X_GPIO_MODE_GPIO,
103 }, {0}
104}; 92};
105 93
106static void rt305x_wdt_reset(void) 94static void rt305x_wdt_reset(void)
@@ -114,14 +102,6 @@ static void rt305x_wdt_reset(void)
114 rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); 102 rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG);
115} 103}
116 104
117struct ralink_pinmux rt_gpio_pinmux = {
118 .mode = mode_mux,
119 .uart = uart_mux,
120 .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT,
121 .uart_mask = RT305X_GPIO_MODE_UART0_MASK,
122 .wdt_reset = rt305x_wdt_reset,
123};
124
125static unsigned long rt5350_get_mem_size(void) 105static unsigned long rt5350_get_mem_size(void)
126{ 106{
127 void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); 107 void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE);
@@ -290,11 +270,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
290 soc_info->mem_base = RT305X_SDRAM_BASE; 270 soc_info->mem_base = RT305X_SDRAM_BASE;
291 if (soc_is_rt5350()) { 271 if (soc_is_rt5350()) {
292 soc_info->mem_size = rt5350_get_mem_size(); 272 soc_info->mem_size = rt5350_get_mem_size();
273 rt2880_pinmux_data = rt5350_pinmux_data;
293 } else if (soc_is_rt305x() || soc_is_rt3350()) { 274 } else if (soc_is_rt305x() || soc_is_rt3350()) {
294 soc_info->mem_size_min = RT305X_MEM_SIZE_MIN; 275 soc_info->mem_size_min = RT305X_MEM_SIZE_MIN;
295 soc_info->mem_size_max = RT305X_MEM_SIZE_MAX; 276 soc_info->mem_size_max = RT305X_MEM_SIZE_MAX;
277 rt2880_pinmux_data = rt3050_pinmux_data;
296 } else if (soc_is_rt3352()) { 278 } else if (soc_is_rt3352()) {
297 soc_info->mem_size_min = RT3352_MEM_SIZE_MIN; 279 soc_info->mem_size_min = RT3352_MEM_SIZE_MIN;
298 soc_info->mem_size_max = RT3352_MEM_SIZE_MAX; 280 soc_info->mem_size_max = RT3352_MEM_SIZE_MAX;
281 rt2880_pinmux_data = rt3352_pinmux_data;
299 } 282 }
300} 283}
diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c
index b474ac284b83..86a535c770d8 100644
--- a/arch/mips/ralink/rt3883.c
+++ b/arch/mips/ralink/rt3883.c
@@ -17,132 +17,50 @@
17#include <asm/mipsregs.h> 17#include <asm/mipsregs.h>
18#include <asm/mach-ralink/ralink_regs.h> 18#include <asm/mach-ralink/ralink_regs.h>
19#include <asm/mach-ralink/rt3883.h> 19#include <asm/mach-ralink/rt3883.h>
20#include <asm/mach-ralink/pinmux.h>
20 21
21#include "common.h" 22#include "common.h"
22 23
23static struct ralink_pinmux_grp mode_mux[] = { 24static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) };
24 { 25static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) };
25 .name = "i2c", 26static struct rt2880_pmx_func uartf_func[] = {
26 .mask = RT3883_GPIO_MODE_I2C, 27 FUNC("uartf", RT3883_GPIO_MODE_UARTF, 7, 8),
27 .gpio_first = RT3883_GPIO_I2C_SD, 28 FUNC("pcm uartf", RT3883_GPIO_MODE_PCM_UARTF, 7, 8),
28 .gpio_last = RT3883_GPIO_I2C_SCLK, 29 FUNC("pcm i2s", RT3883_GPIO_MODE_PCM_I2S, 7, 8),
29 }, { 30 FUNC("i2s uartf", RT3883_GPIO_MODE_I2S_UARTF, 7, 8),
30 .name = "spi", 31 FUNC("pcm gpio", RT3883_GPIO_MODE_PCM_GPIO, 11, 4),
31 .mask = RT3883_GPIO_MODE_SPI, 32 FUNC("gpio uartf", RT3883_GPIO_MODE_GPIO_UARTF, 7, 4),
32 .gpio_first = RT3883_GPIO_SPI_CS0, 33 FUNC("gpio i2s", RT3883_GPIO_MODE_GPIO_I2S, 7, 4),
33 .gpio_last = RT3883_GPIO_SPI_MISO,
34 }, {
35 .name = "uartlite",
36 .mask = RT3883_GPIO_MODE_UART1,
37 .gpio_first = RT3883_GPIO_UART1_TXD,
38 .gpio_last = RT3883_GPIO_UART1_RXD,
39 }, {
40 .name = "jtag",
41 .mask = RT3883_GPIO_MODE_JTAG,
42 .gpio_first = RT3883_GPIO_JTAG_TDO,
43 .gpio_last = RT3883_GPIO_JTAG_TCLK,
44 }, {
45 .name = "mdio",
46 .mask = RT3883_GPIO_MODE_MDIO,
47 .gpio_first = RT3883_GPIO_MDIO_MDC,
48 .gpio_last = RT3883_GPIO_MDIO_MDIO,
49 }, {
50 .name = "ge1",
51 .mask = RT3883_GPIO_MODE_GE1,
52 .gpio_first = RT3883_GPIO_GE1_TXD0,
53 .gpio_last = RT3883_GPIO_GE1_RXCLK,
54 }, {
55 .name = "ge2",
56 .mask = RT3883_GPIO_MODE_GE2,
57 .gpio_first = RT3883_GPIO_GE2_TXD0,
58 .gpio_last = RT3883_GPIO_GE2_RXCLK,
59 }, {
60 .name = "pci",
61 .mask = RT3883_GPIO_MODE_PCI,
62 .gpio_first = RT3883_GPIO_PCI_AD0,
63 .gpio_last = RT3883_GPIO_PCI_AD31,
64 }, {
65 .name = "lna a",
66 .mask = RT3883_GPIO_MODE_LNA_A,
67 .gpio_first = RT3883_GPIO_LNA_PE_A0,
68 .gpio_last = RT3883_GPIO_LNA_PE_A2,
69 }, {
70 .name = "lna g",
71 .mask = RT3883_GPIO_MODE_LNA_G,
72 .gpio_first = RT3883_GPIO_LNA_PE_G0,
73 .gpio_last = RT3883_GPIO_LNA_PE_G2,
74 }, {0}
75}; 34};
76 35static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) };
77static struct ralink_pinmux_grp uart_mux[] = { 36static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) };
78 { 37static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) };
79 .name = "uartf", 38static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) };
80 .mask = RT3883_GPIO_MODE_UARTF, 39static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) };
81 .gpio_first = RT3883_GPIO_7, 40static struct rt2880_pmx_func pci_func[] = {
82 .gpio_last = RT3883_GPIO_14, 41 FUNC("pci-dev", 0, 40, 32),
83 }, { 42 FUNC("pci-host2", 1, 40, 32),
84 .name = "pcm uartf", 43 FUNC("pci-host1", 2, 40, 32),
85 .mask = RT3883_GPIO_MODE_PCM_UARTF, 44 FUNC("pci-fnc", 3, 40, 32)
86 .gpio_first = RT3883_GPIO_7,
87 .gpio_last = RT3883_GPIO_14,
88 }, {
89 .name = "pcm i2s",
90 .mask = RT3883_GPIO_MODE_PCM_I2S,
91 .gpio_first = RT3883_GPIO_7,
92 .gpio_last = RT3883_GPIO_14,
93 }, {
94 .name = "i2s uartf",
95 .mask = RT3883_GPIO_MODE_I2S_UARTF,
96 .gpio_first = RT3883_GPIO_7,
97 .gpio_last = RT3883_GPIO_14,
98 }, {
99 .name = "pcm gpio",
100 .mask = RT3883_GPIO_MODE_PCM_GPIO,
101 .gpio_first = RT3883_GPIO_11,
102 .gpio_last = RT3883_GPIO_14,
103 }, {
104 .name = "gpio uartf",
105 .mask = RT3883_GPIO_MODE_GPIO_UARTF,
106 .gpio_first = RT3883_GPIO_7,
107 .gpio_last = RT3883_GPIO_10,
108 }, {
109 .name = "gpio i2s",
110 .mask = RT3883_GPIO_MODE_GPIO_I2S,
111 .gpio_first = RT3883_GPIO_7,
112 .gpio_last = RT3883_GPIO_10,
113 }, {
114 .name = "gpio",
115 .mask = RT3883_GPIO_MODE_GPIO,
116 }, {0}
117}; 45};
118 46static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) };
119static struct ralink_pinmux_grp pci_mux[] = { 47static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) };
120 { 48
121 .name = "pci-dev", 49static struct rt2880_pmx_group rt3883_pinmux_data[] = {
122 .mask = 0, 50 GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C),
123 .gpio_first = RT3883_GPIO_PCI_AD0, 51 GRP("spi", spi_func, 1, RT3883_GPIO_MODE_SPI),
124 .gpio_last = RT3883_GPIO_PCI_AD31, 52 GRP("uartf", uartf_func, RT3883_GPIO_MODE_UART0_MASK,
125 }, { 53 RT3883_GPIO_MODE_UART0_SHIFT),
126 .name = "pci-host2", 54 GRP("uartlite", uartlite_func, 1, RT3883_GPIO_MODE_UART1),
127 .mask = 1, 55 GRP("jtag", jtag_func, 1, RT3883_GPIO_MODE_JTAG),
128 .gpio_first = RT3883_GPIO_PCI_AD0, 56 GRP("mdio", mdio_func, 1, RT3883_GPIO_MODE_MDIO),
129 .gpio_last = RT3883_GPIO_PCI_AD31, 57 GRP("lna a", lna_a_func, 1, RT3883_GPIO_MODE_LNA_A),
130 }, { 58 GRP("lna g", lna_g_func, 1, RT3883_GPIO_MODE_LNA_G),
131 .name = "pci-host1", 59 GRP("pci", pci_func, RT3883_GPIO_MODE_PCI_MASK,
132 .mask = 2, 60 RT3883_GPIO_MODE_PCI_SHIFT),
133 .gpio_first = RT3883_GPIO_PCI_AD0, 61 GRP("ge1", ge1_func, 1, RT3883_GPIO_MODE_GE1),
134 .gpio_last = RT3883_GPIO_PCI_AD31, 62 GRP("ge2", ge2_func, 1, RT3883_GPIO_MODE_GE2),
135 }, { 63 { 0 }
136 .name = "pci-fnc",
137 .mask = 3,
138 .gpio_first = RT3883_GPIO_PCI_AD0,
139 .gpio_last = RT3883_GPIO_PCI_AD31,
140 }, {
141 .name = "pci-gpio",
142 .mask = 7,
143 .gpio_first = RT3883_GPIO_PCI_AD0,
144 .gpio_last = RT3883_GPIO_PCI_AD31,
145 }, {0}
146}; 64};
147 65
148static void rt3883_wdt_reset(void) 66static void rt3883_wdt_reset(void)
@@ -155,17 +73,6 @@ static void rt3883_wdt_reset(void)
155 rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); 73 rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1);
156} 74}
157 75
158struct ralink_pinmux rt_gpio_pinmux = {
159 .mode = mode_mux,
160 .uart = uart_mux,
161 .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT,
162 .uart_mask = RT3883_GPIO_MODE_UART0_MASK,
163 .wdt_reset = rt3883_wdt_reset,
164 .pci = pci_mux,
165 .pci_shift = RT3883_GPIO_MODE_PCI_SHIFT,
166 .pci_mask = RT3883_GPIO_MODE_PCI_MASK,
167};
168
169void __init ralink_clk_init(void) 76void __init ralink_clk_init(void)
170{ 77{
171 unsigned long cpu_rate, sys_rate; 78 unsigned long cpu_rate, sys_rate;
@@ -204,6 +111,7 @@ void __init ralink_clk_init(void)
204 ralink_clk_add("10000b00.spi", sys_rate); 111 ralink_clk_add("10000b00.spi", sys_rate);
205 ralink_clk_add("10000c00.uartlite", 40000000); 112 ralink_clk_add("10000c00.uartlite", 40000000);
206 ralink_clk_add("10100000.ethernet", sys_rate); 113 ralink_clk_add("10100000.ethernet", sys_rate);
114 ralink_clk_add("10180000.wmac", 40000000);
207} 115}
208 116
209void __init ralink_of_remap(void) 117void __init ralink_of_remap(void)
@@ -243,4 +151,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info)
243 soc_info->mem_base = RT3883_SDRAM_BASE; 151 soc_info->mem_base = RT3883_SDRAM_BASE;
244 soc_info->mem_size_min = RT3883_MEM_SIZE_MIN; 152 soc_info->mem_size_min = RT3883_MEM_SIZE_MIN;
245 soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; 153 soc_info->mem_size_max = RT3883_MEM_SIZE_MAX;
154
155 rt2880_pinmux_data = rt3883_pinmux_data;
246} 156}
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
index a18007613c30..5aa3df853082 100644
--- a/arch/mips/rb532/gpio.c
+++ b/arch/mips/rb532/gpio.c
@@ -79,7 +79,7 @@ static inline void rb532_set_bit(unsigned bitval,
79 */ 79 */
80static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) 80static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr)
81{ 81{
82 return (readl(ioaddr) & (1 << offset)); 82 return readl(ioaddr) & (1 << offset);
83} 83}
84 84
85/* 85/*
diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c
index a757ded437cd..657210e767c2 100644
--- a/arch/mips/rb532/prom.c
+++ b/arch/mips/rb532/prom.c
@@ -122,8 +122,8 @@ void __init prom_setup_cmdline(void)
122void __init prom_init(void) 122void __init prom_init(void)
123{ 123{
124 struct ddr_ram __iomem *ddr; 124 struct ddr_ram __iomem *ddr;
125 phys_t memsize; 125 phys_addr_t memsize;
126 phys_t ddrbase; 126 phys_addr_t ddrbase;
127 127
128 ddr = ioremap_nocache(ddr_reg[0].start, 128 ddr = ioremap_nocache(ddr_reg[0].start,
129 ddr_reg[0].end - ddr_reg[0].start); 129 ddr_reg[0].end - ddr_reg[0].start);
@@ -133,8 +133,8 @@ void __init prom_init(void)
133 return; 133 return;
134 } 134 }
135 135
136 ddrbase = (phys_t)&ddr->ddrbase; 136 ddrbase = (phys_addr_t)&ddr->ddrbase;
137 memsize = (phys_t)&ddr->ddrmask; 137 memsize = (phys_addr_t)&ddr->ddrmask;
138 memsize = 0 - memsize; 138 memsize = 0 - memsize;
139 139
140 prom_setup_cmdline(); 140 prom_setup_cmdline();
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
index 7cec0a4e527d..6b009c45abed 100644
--- a/arch/mips/sgi-ip22/ip22-mc.c
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -24,14 +24,12 @@ EXPORT_SYMBOL(sgimc);
24 24
25static inline unsigned long get_bank_addr(unsigned int memconfig) 25static inline unsigned long get_bank_addr(unsigned int memconfig)
26{ 26{
27 return ((memconfig & SGIMC_MCONFIG_BASEADDR) << 27 return (memconfig & SGIMC_MCONFIG_BASEADDR) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22);
28 ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22));
29} 28}
30 29
31static inline unsigned long get_bank_size(unsigned int memconfig) 30static inline unsigned long get_bank_size(unsigned int memconfig)
32{ 31{
33 return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << 32 return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
34 ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
35} 33}
36 34
37static inline unsigned int get_bank_config(int bank) 35static inline unsigned int get_bank_config(int bank)
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
index 3f47346608d7..712cc0f6a58d 100644
--- a/arch/mips/sgi-ip22/ip28-berr.c
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -338,7 +338,7 @@ static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
338 PHYS_TO_XKSEG_UNCACHED(pte); 338 PHYS_TO_XKSEG_UNCACHED(pte);
339 a = (a & 0x3f) << 6; /* PFN */ 339 a = (a & 0x3f) << 6; /* PFN */
340 a += vaddr & ((1 << pgsz) - 1); 340 a += vaddr & ((1 << pgsz) - 1);
341 return (cpu_err_addr == a); 341 return cpu_err_addr == a;
342 } 342 }
343 } 343 }
344 } 344 }
@@ -351,7 +351,7 @@ static int check_vdma_memaddr(void)
351 u32 a = sgimc->maddronly; 351 u32 a = sgimc->maddronly;
352 352
353 if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */ 353 if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */
354 return (cpu_err_addr == a); 354 return cpu_err_addr == a;
355 355
356 if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) || 356 if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) ||
357 check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) || 357 check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) ||
@@ -367,7 +367,7 @@ static int check_vdma_gioaddr(void)
367 if (gio_err_stat & GIO_ERRMASK) { 367 if (gio_err_stat & GIO_ERRMASK) {
368 u32 a = sgimc->gio_dma_trans; 368 u32 a = sgimc->gio_dma_trans;
369 a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a); 369 a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a);
370 return (gio_err_addr == a); 370 return gio_err_addr == a;
371 } 371 }
372 return 0; 372 return 0;
373} 373}
diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c
index 7a53b1e28a93..ecbb62f339c5 100644
--- a/arch/mips/sgi-ip27/ip27-klnuma.c
+++ b/arch/mips/sgi-ip27/ip27-klnuma.c
@@ -125,8 +125,7 @@ unsigned long node_getfirstfree(cnodeid_t cnode)
125#endif 125#endif
126 offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; 126 offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
127 if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask))) 127 if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask)))
128 return (TO_NODE(nasid, offset) >> PAGE_SHIFT); 128 return TO_NODE(nasid, offset) >> PAGE_SHIFT;
129 else 129 else
130 return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> 130 return KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> PAGE_SHIFT;
131 PAGE_SHIFT);
132} 131}
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index a304bcc37e4f..0b68469e063f 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -42,8 +42,7 @@ static int fine_mode;
42 42
43static int is_fine_dirmode(void) 43static int is_fine_dirmode(void)
44{ 44{
45 return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) 45 return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE;
46 >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE);
47} 46}
48 47
49static hubreg_t get_region(cnodeid_t cnode) 48static hubreg_t get_region(cnodeid_t cnode)
@@ -288,7 +287,7 @@ static unsigned long __init slot_psize_compute(cnodeid_t node, int slot)
288 if (size <= 128) { 287 if (size <= 128) {
289 if (slot % 4 == 0) { 288 if (slot % 4 == 0) {
290 size <<= 20; /* size in bytes */ 289 size <<= 20; /* size in bytes */
291 return(size >> PAGE_SHIFT); 290 return size >> PAGE_SHIFT;
292 } else 291 } else
293 return 0; 292 return 0;
294 } else { 293 } else {
diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c
index 588e1806a1a3..c1a11a11db7f 100644
--- a/arch/mips/sibyte/common/cfe.c
+++ b/arch/mips/sibyte/common/cfe.c
@@ -38,7 +38,7 @@
38#define MAX_RAM_SIZE (~0ULL) 38#define MAX_RAM_SIZE (~0ULL)
39#else 39#else
40#ifdef CONFIG_HIGHMEM 40#ifdef CONFIG_HIGHMEM
41#ifdef CONFIG_64BIT_PHYS_ADDR 41#ifdef CONFIG_PHYS_ADDR_T_64BIT
42#define MAX_RAM_SIZE (~0ULL) 42#define MAX_RAM_SIZE (~0ULL)
43#else 43#else
44#define MAX_RAM_SIZE (0xffffffffULL) 44#define MAX_RAM_SIZE (0xffffffffULL)
@@ -49,8 +49,8 @@
49#endif 49#endif
50 50
51#define SIBYTE_MAX_MEM_REGIONS 8 51#define SIBYTE_MAX_MEM_REGIONS 8
52phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; 52phys_addr_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS];
53phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; 53phys_addr_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS];
54unsigned int board_mem_region_count; 54unsigned int board_mem_region_count;
55 55
56int cfe_cons_handle; 56int cfe_cons_handle;
@@ -96,7 +96,7 @@ static void __noreturn cfe_linux_halt(void)
96 96
97static __init void prom_meminit(void) 97static __init void prom_meminit(void)
98{ 98{
99 u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */ 99 u64 addr, size, type; /* regardless of PHYS_ADDR_T_64BIT */
100 int mem_flags = 0; 100 int mem_flags = 0;
101 unsigned int idx; 101 unsigned int idx;
102 int rd_flag; 102 int rd_flag;
diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c
index 9480c14ec66a..1cecdcf85cf1 100644
--- a/arch/mips/sibyte/swarm/platform.c
+++ b/arch/mips/sibyte/swarm/platform.c
@@ -50,7 +50,7 @@ static struct platform_device swarm_pata_device = {
50static int __init swarm_pata_init(void) 50static int __init swarm_pata_init(void)
51{ 51{
52 u8 __iomem *base; 52 u8 __iomem *base;
53 phys_t offset, size; 53 phys_addr_t offset, size;
54 struct resource *r; 54 struct resource *r;
55 55
56 if (!SIBYTE_HAVE_IDE) 56 if (!SIBYTE_HAVE_IDE)
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
index b732600b47f5..e62466445f08 100644
--- a/arch/mips/sibyte/swarm/rtc_m41t81.c
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -109,7 +109,7 @@ static int m41t81_read(uint8_t addr)
109 return -1; 109 return -1;
110 } 110 }
111 111
112 return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); 112 return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff;
113} 113}
114 114
115static int m41t81_write(uint8_t addr, int b) 115static int m41t81_write(uint8_t addr, int b)
@@ -229,5 +229,5 @@ int m41t81_probe(void)
229 tmp = m41t81_read(M41T81REG_SC); 229 tmp = m41t81_read(M41T81REG_SC);
230 m41t81_write(M41T81REG_SC, tmp & 0x7f); 230 m41t81_write(M41T81REG_SC, tmp & 0x7f);
231 231
232 return (m41t81_read(M41T81REG_SC) != -1); 232 return m41t81_read(M41T81REG_SC) != -1;
233} 233}
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
index 178a824b28d4..50a82c495427 100644
--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -84,7 +84,7 @@ static int xicor_read(uint8_t addr)
84 return -1; 84 return -1;
85 } 85 }
86 86
87 return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); 87 return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff;
88} 88}
89 89
90static int xicor_write(uint8_t addr, int b) 90static int xicor_write(uint8_t addr, int b)
@@ -206,5 +206,5 @@ unsigned long xicor_get_time(void)
206 206
207int xicor_probe(void) 207int xicor_probe(void)
208{ 208{
209 return (xicor_read(X1241REG_SC) != -1); 209 return xicor_read(X1241REG_SC) != -1;
210} 210}
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 3462c831d0ea..494fb0a475ac 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -76,7 +76,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup)
76 printk("DBE physical address: %010Lx\n", 76 printk("DBE physical address: %010Lx\n",
77 __read_64bit_c0_register($26, 1)); 77 __read_64bit_c0_register($26, 1));
78 } 78 }
79 return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); 79 return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
80} 80}
81 81
82enum swarm_rtc_type { 82enum swarm_rtc_type {
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c
index e714d6ce9a82..a4664cb6c1e1 100644
--- a/arch/mips/txx9/generic/setup_tx4927.c
+++ b/arch/mips/txx9/generic/setup_tx4927.c
@@ -29,8 +29,8 @@ static void __init tx4927_wdr_init(void)
29{ 29{
30 /* report watchdog reset status */ 30 /* report watchdog reset status */
31 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) 31 if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST)
32 pr_warning("Watchdog reset detected at 0x%lx\n", 32 pr_warn("Watchdog reset detected at 0x%lx\n",
33 read_c0_errorepc()); 33 read_c0_errorepc());
34 /* clear WatchDogReset (W1C) */ 34 /* clear WatchDogReset (W1C) */
35 tx4927_ccfg_set(TX4927_CCFG_WDRST); 35 tx4927_ccfg_set(TX4927_CCFG_WDRST);
36 /* do reset on watchdog */ 36 /* do reset on watchdog */
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
index 0a3bf2dfaba1..58cdb2aba5e1 100644
--- a/arch/mips/txx9/generic/setup_tx4938.c
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -31,8 +31,8 @@ static void __init tx4938_wdr_init(void)
31{ 31{
32 /* report watchdog reset status */ 32 /* report watchdog reset status */
33 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) 33 if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST)
34 pr_warning("Watchdog reset detected at 0x%lx\n", 34 pr_warn("Watchdog reset detected at 0x%lx\n",
35 read_c0_errorepc()); 35 read_c0_errorepc());
36 /* clear WatchDogReset (W1C) */ 36 /* clear WatchDogReset (W1C) */
37 tx4938_ccfg_set(TX4938_CCFG_WDRST); 37 tx4938_ccfg_set(TX4938_CCFG_WDRST);
38 /* do reset on watchdog */ 38 /* do reset on watchdog */
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index b7eccbd17bf7..e3733cde50d6 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -35,8 +35,8 @@ static void __init tx4939_wdr_init(void)
35{ 35{
36 /* report watchdog reset status */ 36 /* report watchdog reset status */
37 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST) 37 if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST)
38 pr_warning("Watchdog reset detected at 0x%lx\n", 38 pr_warn("Watchdog reset detected at 0x%lx\n",
39 read_c0_errorepc()); 39 read_c0_errorepc());
40 /* clear WatchDogReset (W1C) */ 40 /* clear WatchDogReset (W1C) */
41 tx4939_ccfg_set(TX4939_CCFG_WDRST); 41 tx4939_ccfg_set(TX4939_CCFG_WDRST);
42 /* do reset on watchdog */ 42 /* do reset on watchdog */