Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Apr 2015 19:50:54 +0000 (15:50 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Apr 2015 19:50:54 +0000 (15:50 -0400)
Pull MIPS updates from Ralf Baechle:
 "This is the main pull request for MIPS for Linux 4.1.  Most
  noteworthy:

   - Add more Octeon-optimized crypto functions
   - Octeon crypto preemption and locking fixes
   - Little endian support for Octeon
   - Use correct CSR to soft reset Octeons
   - Support LEDs on the Octeon-based DSR-1000N
   - Fix PCI interrupt mapping for the Octeon-based DSR-1000N
   - Mark prom_free_prom_memory() as __init for a number of systems
   - Support for Imagination's Pistachio SOC.  This includes arch and
     CLK bits.  I'd like to merge pinctrl bits later
   - Improve parallelism of csum_partial for certain pipelines
   - Organize DTB files in subdirs like other architectures
   - Implement read_sched_clock for all MIPS platforms other than
     Octeon
   - Massive series of 38 fixes and cleanups for the FPU emulator /
     kernel
   - Further FPU remulator work to support new features.  This sits on a
     separate branch which also has been pulled into the 4.1 KVM branch
   - Clean up and fixes for the SEAD3 eval board; remove unused file
   - Various updates for Netlogic platforms
   - A number of small updates for Loongson 3 platforms
   - Increase the memory limit for ATH79 platforms to 256MB
   - A fair number of fixes and updates for BCM47xx platforms
   - Finish the implementation of XPA support
   - MIPS FDC support.  No, not floppy controller but Fast Debug Channel :)
   - Detect the R16000 used in SGI legacy platforms
   - Fix Kconfig dependencies for the SSB bus support"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (265 commits)
  MIPS: Makefile: Fix MIPS ASE detection code
  MIPS: asm: elf: Set O32 default FPU flags
  MIPS: BCM47XX: Fix detecting Microsoft MN-700 & Asus WL500G
  MIPS: Kconfig: Disable SMP/CPS for 64-bit
  MIPS: Hibernate: flush TLB entries earlier
  MIPS: smp-cps: cpu_set FPU mask if FPU present
  MIPS: lose_fpu(): Disable FPU when MSA enabled
  MIPS: ralink: add missing symbol for RALINK_ILL_ACC
  MIPS: ralink: Fix bad config symbol in PCI makefile.
  SSB: fix Kconfig dependencies
  MIPS: Malta: Detect and fix bad memsize values
  Revert "MIPS: Avoid pipeline stalls on some MIPS32R2 cores."
  MIPS: Octeon: Delete override of cpu_has_mips_r2_exec_hazard.
  MIPS: Fix cpu_has_mips_r2_exec_hazard.
  MIPS: kernel: entry.S: Set correct ISA level for mips_ihb
  MIPS: asm: spinlock: Fix addiu instruction for R10000_LLSC_WAR case
  MIPS: r4kcache: Use correct base register for MIPS R6 cache flushes
  MIPS: Kconfig: Fix typo for the r2-to-r6 emulator kernel parameter
  MIPS: unaligned: Fix regular load/store instruction emulation for EVA
  MIPS: unaligned: Surround load/store macros in do {} while statements
  ...

352 files changed:
Documentation/IRQ-domain.txt
Documentation/devicetree/bindings/clock/pistachio-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/brcm,bcm3380-l2-intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7120-l2-intc.txt
Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt
Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt [deleted file]
Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt [deleted file]
Documentation/devicetree/bindings/mips/brcm/soc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mips/img/pistachio.txt [new file with mode: 0644]
Documentation/devicetree/booting-without-of.txt
Documentation/kernel-parameters.txt
arch/mips/Kbuild.platforms
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/ar7/platform.c
arch/mips/ath79/common.h
arch/mips/bcm3384/Platform [deleted file]
arch/mips/bcm3384/dma.c [deleted file]
arch/mips/bcm3384/irq.c [deleted file]
arch/mips/bcm3384/setup.c [deleted file]
arch/mips/bcm47xx/bcm47xx_private.h
arch/mips/bcm47xx/board.c
arch/mips/bcm47xx/buttons.c
arch/mips/bcm47xx/leds.c
arch/mips/bcm47xx/nvram.c
arch/mips/bcm47xx/prom.c
arch/mips/bcm47xx/serial.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/sprom.c
arch/mips/bcm47xx/time.c
arch/mips/bcm63xx/prom.c
arch/mips/bcm63xx/setup.c
arch/mips/bmips/Kconfig [new file with mode: 0644]
arch/mips/bmips/Makefile [moved from arch/mips/bcm3384/Makefile with 100% similarity]
arch/mips/bmips/Platform [new file with mode: 0644]
arch/mips/bmips/dma.c [new file with mode: 0644]
arch/mips/bmips/irq.c [new file with mode: 0644]
arch/mips/bmips/setup.c [new file with mode: 0644]
arch/mips/boot/compressed/Makefile
arch/mips/boot/compressed/decompress.c
arch/mips/boot/dts/Makefile
arch/mips/boot/dts/bcm3384.dtsi [deleted file]
arch/mips/boot/dts/brcm/Makefile [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm3384_viper.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm3384_zephyr.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm6328.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm6368.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm7125.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm7346.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm7358.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm7360.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm7362.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm7420.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm7425.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm93384wvg.dts [moved from arch/mips/boot/dts/bcm93384wvg.dts with 63% similarity]
arch/mips/boot/dts/brcm/bcm93384wvg_viper.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm96368mvwg.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm97125cbmb.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm97346dbsmb.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm97358svmb.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm97360svmb.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm97362svmb.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm97420c.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm97425svmb.dts [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm9ejtagprb.dts [new file with mode: 0644]
arch/mips/boot/dts/cavium-octeon/Makefile [new file with mode: 0644]
arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts [moved from arch/mips/boot/dts/octeon_3xxx.dts with 98% similarity]
arch/mips/boot/dts/cavium-octeon/octeon_68xx.dts [moved from arch/mips/boot/dts/octeon_68xx.dts with 100% similarity]
arch/mips/boot/dts/lantiq/Makefile [new file with mode: 0644]
arch/mips/boot/dts/lantiq/danube.dtsi [moved from arch/mips/boot/dts/danube.dtsi with 100% similarity]
arch/mips/boot/dts/lantiq/easy50712.dts [moved from arch/mips/boot/dts/easy50712.dts with 100% similarity]
arch/mips/boot/dts/mti/Makefile [new file with mode: 0644]
arch/mips/boot/dts/mti/sead3.dts [moved from arch/mips/boot/dts/sead3.dts with 100% similarity]
arch/mips/boot/dts/netlogic/Makefile [new file with mode: 0644]
arch/mips/boot/dts/netlogic/xlp_evp.dts [moved from arch/mips/boot/dts/xlp_evp.dts with 100% similarity]
arch/mips/boot/dts/netlogic/xlp_fvp.dts [moved from arch/mips/boot/dts/xlp_fvp.dts with 100% similarity]
arch/mips/boot/dts/netlogic/xlp_gvp.dts [moved from arch/mips/boot/dts/xlp_gvp.dts with 100% similarity]
arch/mips/boot/dts/netlogic/xlp_rvp.dts [new file with mode: 0644]
arch/mips/boot/dts/netlogic/xlp_svp.dts [moved from arch/mips/boot/dts/xlp_svp.dts with 100% similarity]
arch/mips/boot/dts/ralink/Makefile [new file with mode: 0644]
arch/mips/boot/dts/ralink/mt7620a.dtsi [moved from arch/mips/boot/dts/mt7620a.dtsi with 100% similarity]
arch/mips/boot/dts/ralink/mt7620a_eval.dts [moved from arch/mips/boot/dts/mt7620a_eval.dts with 100% similarity]
arch/mips/boot/dts/ralink/rt2880.dtsi [moved from arch/mips/boot/dts/rt2880.dtsi with 100% similarity]
arch/mips/boot/dts/ralink/rt2880_eval.dts [moved from arch/mips/boot/dts/rt2880_eval.dts with 100% similarity]
arch/mips/boot/dts/ralink/rt3050.dtsi [moved from arch/mips/boot/dts/rt3050.dtsi with 100% similarity]
arch/mips/boot/dts/ralink/rt3052_eval.dts [moved from arch/mips/boot/dts/rt3052_eval.dts with 100% similarity]
arch/mips/boot/dts/ralink/rt3883.dtsi [moved from arch/mips/boot/dts/rt3883.dtsi with 100% similarity]
arch/mips/boot/dts/ralink/rt3883_eval.dts [moved from arch/mips/boot/dts/rt3883_eval.dts with 100% similarity]
arch/mips/cavium-octeon/crypto/octeon-crypto.h
arch/mips/cavium-octeon/dma-octeon.c
arch/mips/cavium-octeon/executive/cvmx-l2c.c
arch/mips/cavium-octeon/flash_setup.c
arch/mips/cavium-octeon/octeon-platform.c
arch/mips/cavium-octeon/octeon_boot.h
arch/mips/cavium-octeon/setup.c
arch/mips/configs/bmips_be_defconfig [moved from arch/mips/configs/bcm3384_defconfig with 89% similarity]
arch/mips/configs/bmips_stb_defconfig [new file with mode: 0644]
arch/mips/configs/maltaup_xpa_defconfig [new file with mode: 0644]
arch/mips/configs/pistachio_defconfig [new file with mode: 0644]
arch/mips/dec/int-handler.S
arch/mips/dec/setup.c
arch/mips/include/asm/asm-eva.h
arch/mips/include/asm/asmmacro-32.h
arch/mips/include/asm/bitops.h
arch/mips/include/asm/bmips.h
arch/mips/include/asm/cacheflush.h
arch/mips/include/asm/cdmm.h [new file with mode: 0644]
arch/mips/include/asm/cevt-r4k.h
arch/mips/include/asm/checksum.h
arch/mips/include/asm/cmpxchg.h
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/cpu-info.h
arch/mips/include/asm/cpu-type.h
arch/mips/include/asm/cpu.h
arch/mips/include/asm/dma-mapping.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/fpu.h
arch/mips/include/asm/fpu_emulator.h
arch/mips/include/asm/irq.h
arch/mips/include/asm/mach-ar7/war.h [deleted file]
arch/mips/include/asm/mach-ath25/dma-coherence.h
arch/mips/include/asm/mach-ath25/war.h [deleted file]
arch/mips/include/asm/mach-ath79/war.h [deleted file]
arch/mips/include/asm/mach-au1x00/war.h [deleted file]
arch/mips/include/asm/mach-bcm3384/war.h [deleted file]
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
arch/mips/include/asm/mach-bcm47xx/war.h [deleted file]
arch/mips/include/asm/mach-bcm63xx/dma-coherence.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/war.h [deleted file]
arch/mips/include/asm/mach-bmips/dma-coherence.h [moved from arch/mips/include/asm/mach-bcm3384/dma-coherence.h with 83% similarity]
arch/mips/include/asm/mach-bmips/spaces.h [new file with mode: 0644]
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
arch/mips/include/asm/mach-cavium-octeon/mangle-port.h [new file with mode: 0644]
arch/mips/include/asm/mach-cobalt/cpu-feature-overrides.h
arch/mips/include/asm/mach-cobalt/war.h [deleted file]
arch/mips/include/asm/mach-dec/cpu-feature-overrides.h
arch/mips/include/asm/mach-dec/war.h [deleted file]
arch/mips/include/asm/mach-emma2rh/war.h [deleted file]
arch/mips/include/asm/mach-generic/dma-coherence.h
arch/mips/include/asm/mach-generic/war.h [moved from arch/mips/include/asm/mach-ralink/war.h with 86% similarity]
arch/mips/include/asm/mach-ip22/cpu-feature-overrides.h
arch/mips/include/asm/mach-ip27/dma-coherence.h
arch/mips/include/asm/mach-ip32/cpu-feature-overrides.h
arch/mips/include/asm/mach-ip32/dma-coherence.h
arch/mips/include/asm/mach-jazz/dma-coherence.h
arch/mips/include/asm/mach-jazz/war.h [deleted file]
arch/mips/include/asm/mach-jz4740/war.h [deleted file]
arch/mips/include/asm/mach-lantiq/war.h [deleted file]
arch/mips/include/asm/mach-lasat/war.h [deleted file]
arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
arch/mips/include/asm/mach-loongson/dma-coherence.h
arch/mips/include/asm/mach-loongson/loongson.h
arch/mips/include/asm/mach-loongson/war.h [deleted file]
arch/mips/include/asm/mach-loongson1/war.h [deleted file]
arch/mips/include/asm/mach-netlogic/multi-node.h
arch/mips/include/asm/mach-netlogic/topology.h [deleted file]
arch/mips/include/asm/mach-netlogic/war.h [deleted file]
arch/mips/include/asm/mach-paravirt/war.h [deleted file]
arch/mips/include/asm/mach-pistachio/gpio.h [new file with mode: 0644]
arch/mips/include/asm/mach-pistachio/irq.h [new file with mode: 0644]
arch/mips/include/asm/mach-pnx833x/war.h [deleted file]
arch/mips/include/asm/mach-rm/cpu-feature-overrides.h
arch/mips/include/asm/mach-tx39xx/war.h [deleted file]
arch/mips/include/asm/mach-vr41xx/war.h [deleted file]
arch/mips/include/asm/mips-boards/sead3-addr.h [new file with mode: 0644]
arch/mips/include/asm/mips-r2-to-r6-emul.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/netlogic/common.h
arch/mips/include/asm/netlogic/mips-extns.h
arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
arch/mips/include/asm/netlogic/xlp-hal/sys.h
arch/mips/include/asm/netlogic/xlp-hal/xlp.h
arch/mips/include/asm/octeon/cvmx-address.h
arch/mips/include/asm/octeon/cvmx-bootinfo.h
arch/mips/include/asm/octeon/cvmx-bootmem.h
arch/mips/include/asm/octeon/cvmx-fau.h
arch/mips/include/asm/octeon/cvmx-fpa.h
arch/mips/include/asm/octeon/cvmx-l2c.h
arch/mips/include/asm/octeon/cvmx-packet.h
arch/mips/include/asm/octeon/cvmx-pko.h
arch/mips/include/asm/octeon/cvmx-pow.h
arch/mips/include/asm/octeon/cvmx-wqe.h
arch/mips/include/asm/octeon/cvmx.h
arch/mips/include/asm/octeon/octeon.h
arch/mips/include/asm/octeon/pci-octeon.h
arch/mips/include/asm/page.h
arch/mips/include/asm/pci.h
arch/mips/include/asm/pci/bridge.h
arch/mips/include/asm/pgtable-32.h
arch/mips/include/asm/pgtable-64.h
arch/mips/include/asm/pgtable-bits.h
arch/mips/include/asm/pgtable.h
arch/mips/include/asm/r4kcache.h
arch/mips/include/asm/sgi/sgi.h
arch/mips/include/asm/spinlock.h
arch/mips/include/asm/thread_info.h
arch/mips/jz4740/Platform
arch/mips/jz4740/time.c
arch/mips/kernel/branch.c
arch/mips/kernel/cevt-r4k.c
arch/mips/kernel/cevt-txx9.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/csrc-bcm1480.c
arch/mips/kernel/csrc-ioasic.c
arch/mips/kernel/csrc-r4k.c
arch/mips/kernel/csrc-sb1250.c
arch/mips/kernel/elf.c
arch/mips/kernel/entry.S
arch/mips/kernel/idle.c
arch/mips/kernel/mips-r2-to-r6-emul.c
arch/mips/kernel/perf_event_mipsxx.c
arch/mips/kernel/proc.c
arch/mips/kernel/process.c
arch/mips/kernel/prom.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/r2300_switch.S
arch/mips/kernel/r4k_switch.S
arch/mips/kernel/reset.c
arch/mips/kernel/setup.c
arch/mips/kernel/smp-cps.c
arch/mips/kernel/smp.c
arch/mips/kernel/traps.c
arch/mips/kernel/unaligned.c
arch/mips/lantiq/prom.c
arch/mips/lantiq/xway/vmmc.c
arch/mips/lasat/sysctl.c
arch/mips/lib/csum_partial.S
arch/mips/loongson/common/env.c
arch/mips/loongson/common/pci.c
arch/mips/loongson/loongson-3/cop2-ex.c
arch/mips/loongson/loongson-3/irq.c
arch/mips/math-emu/Makefile
arch/mips/math-emu/cp1emu.c
arch/mips/math-emu/dp_add.c
arch/mips/math-emu/dp_cmp.c
arch/mips/math-emu/dp_div.c
arch/mips/math-emu/dp_fsp.c
arch/mips/math-emu/dp_mul.c
arch/mips/math-emu/dp_simple.c
arch/mips/math-emu/dp_sqrt.c
arch/mips/math-emu/dp_sub.c
arch/mips/math-emu/dsemul.c
arch/mips/math-emu/ieee754.h
arch/mips/math-emu/ieee754dp.c
arch/mips/math-emu/ieee754dp.h
arch/mips/math-emu/ieee754int.h
arch/mips/math-emu/ieee754sp.c
arch/mips/math-emu/ieee754sp.h
arch/mips/math-emu/me-debugfs.c
arch/mips/math-emu/sp_add.c
arch/mips/math-emu/sp_cmp.c
arch/mips/math-emu/sp_div.c
arch/mips/math-emu/sp_fdp.c
arch/mips/math-emu/sp_mul.c
arch/mips/math-emu/sp_simple.c
arch/mips/math-emu/sp_sqrt.c
arch/mips/math-emu/sp_sub.c
arch/mips/mm/c-r4k.c
arch/mips/mm/cache.c
arch/mips/mm/dma-default.c
arch/mips/mm/init.c
arch/mips/mm/page.c
arch/mips/mm/tlb-r4k.c
arch/mips/mm/tlbex.c
arch/mips/mti-malta/malta-memory.c
arch/mips/mti-malta/malta-time.c
arch/mips/mti-sead3/Makefile
arch/mips/mti-sead3/leds-sead3.c
arch/mips/mti-sead3/sead3-ehci.c [deleted file]
arch/mips/mti-sead3/sead3-i2c-dev.c [deleted file]
arch/mips/mti-sead3/sead3-i2c-drv.c [deleted file]
arch/mips/mti-sead3/sead3-i2c.c [deleted file]
arch/mips/mti-sead3/sead3-init.c
arch/mips/mti-sead3/sead3-leds.c [deleted file]
arch/mips/mti-sead3/sead3-mtd.c [deleted file]
arch/mips/mti-sead3/sead3-net.c [deleted file]
arch/mips/mti-sead3/sead3-platform.c
arch/mips/netlogic/Kconfig
arch/mips/netlogic/common/irq.c
arch/mips/netlogic/common/reset.S
arch/mips/netlogic/common/smp.c
arch/mips/netlogic/common/time.c
arch/mips/netlogic/xlp/ahci-init-xlp2.c
arch/mips/netlogic/xlp/ahci-init.c
arch/mips/netlogic/xlp/dt.c
arch/mips/netlogic/xlp/nlm_hal.c
arch/mips/netlogic/xlp/setup.c
arch/mips/netlogic/xlp/usb-init-xlp2.c
arch/mips/netlogic/xlp/wakeup.c
arch/mips/oprofile/common.c
arch/mips/oprofile/op_model_mipsxx.c
arch/mips/pci/Makefile
arch/mips/pci/msi-xlp.c
arch/mips/pci/pci-ar2315.c
arch/mips/pci/pci-octeon.c
arch/mips/pci/pci-rt2880.c
arch/mips/pci/pci.c
arch/mips/pci/pcie-octeon.c
arch/mips/pistachio/Makefile [new file with mode: 0644]
arch/mips/pistachio/Platform [new file with mode: 0644]
arch/mips/pistachio/init.c [new file with mode: 0644]
arch/mips/pistachio/irq.c [new file with mode: 0644]
arch/mips/pistachio/time.c [new file with mode: 0644]
arch/mips/power/Makefile
arch/mips/power/hibernate.c [new file with mode: 0644]
arch/mips/power/hibernate_asm.S [moved from arch/mips/power/hibernate.S with 91% similarity]
arch/mips/ralink/Kconfig
arch/mips/sgi-ip27/ip27-timer.c
arch/mips/sgi-ip32/ip32-platform.c
drivers/bcma/driver_mips.c
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/mips_cdmm.c [new file with mode: 0644]
drivers/clk/Makefile
drivers/clk/pistachio/Makefile [new file with mode: 0644]
drivers/clk/pistachio/clk-pistachio.c [new file with mode: 0644]
drivers/clk/pistachio/clk-pll.c [new file with mode: 0644]
drivers/clk/pistachio/clk.c [new file with mode: 0644]
drivers/clk/pistachio/clk.h [new file with mode: 0644]
drivers/clocksource/Kconfig
drivers/clocksource/mips-gic-timer.c
drivers/irqchip/Kconfig
drivers/irqchip/Makefile
drivers/irqchip/irq-bcm7038-l1.c [new file with mode: 0644]
drivers/irqchip/irq-bcm7120-l2.c
drivers/irqchip/irq-brcmstb-l2.c
drivers/irqchip/irq-mips-gic.c
drivers/net/ethernet/broadcom/b44.c
drivers/net/ethernet/broadcom/bgmac.c
drivers/platform/Kconfig
drivers/platform/Makefile
drivers/platform/mips/Kconfig [new file with mode: 0644]
drivers/platform/mips/Makefile [new file with mode: 0644]
drivers/platform/mips/acpi_init.c [new file with mode: 0644]
drivers/platform/mips/cpu_hwmon.c [new file with mode: 0644]
drivers/ssb/Kconfig
drivers/ssb/driver_chipcommon_pmu.c
drivers/ssb/driver_mipscore.c
drivers/staging/octeon/ethernet-tx.c
drivers/staging/octeon/ethernet.c
drivers/tty/Kconfig
drivers/tty/Makefile
drivers/tty/mips_ejtag_fdc.c [new file with mode: 0644]
include/dt-bindings/clock/pistachio-clk.h [new file with mode: 0644]
include/linux/bcm47xx_nvram.h [moved from arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h with 63% similarity]
include/linux/irqchip/mips-gic.h
include/linux/mod_devicetable.h
scripts/mod/devicetable-offsets.c
scripts/mod/file2alias.c

index 39cfa72..3a8e15c 100644 (file)
@@ -95,8 +95,7 @@ since it doesn't need to allocate a table as large as the largest
 hwirq number.  The disadvantage is that hwirq to IRQ number lookup is
 dependent on how many entries are in the table.
 
-Very few drivers should need this mapping.  At the moment, powerpc
-iseries is the only user.
+Very few drivers should need this mapping.
 
 ==== No Map ===-
 irq_domain_add_nomap()
diff --git a/Documentation/devicetree/bindings/clock/pistachio-clock.txt b/Documentation/devicetree/bindings/clock/pistachio-clock.txt
new file mode 100644 (file)
index 0000000..868db49
--- /dev/null
@@ -0,0 +1,123 @@
+Imagination Technologies Pistachio SoC clock controllers
+========================================================
+
+Pistachio has four clock controllers (core clock, peripheral clock, peripheral
+general control, and top general control) which are instantiated individually
+from the device-tree.
+
+External clocks:
+----------------
+
+There are three external inputs to the clock controllers which should be
+defined with the following clock-output-names:
+- "xtal": External 52Mhz oscillator (required)
+- "audio_clk_in": Alternate audio reference clock (optional)
+- "enet_clk_in": Alternate ethernet PHY clock (optional)
+
+Core clock controller:
+----------------------
+
+The core clock controller generates clocks for the CPU, RPU (WiFi + BT
+co-processor), audio, and several peripherals.
+
+Required properties:
+- compatible: Must be "img,pistachio-clk".
+- reg: Must contain the base address and length of the core clock controller.
+- #clock-cells: Must be 1.  The single cell is the clock identifier.
+  See dt-bindings/clock/pistachio-clk.h for the list of valid identifiers.
+- clocks: Must contain an entry for each clock in clock-names.
+- clock-names: Must include "xtal" (see "External clocks") and
+  "audio_clk_in_gate", "enet_clk_in_gate" which are generated by the
+  top-level general control.
+
+Example:
+       clk_core: clock-controller@18144000 {
+               compatible = "img,pistachio-clk";
+               reg = <0x18144000 0x800>;
+               clocks = <&xtal>, <&cr_top EXT_CLK_AUDIO_IN>,
+                        <&cr_top EXT_CLK_ENET_IN>;
+               clock-names = "xtal", "audio_clk_in_gate", "enet_clk_in_gate";
+
+               #clock-cells = <1>;
+       };
+
+Peripheral clock controller:
+----------------------------
+
+The peripheral clock controller generates clocks for the DDR, ROM, and other
+peripherals.  The peripheral system clock ("periph_sys") generated by the core
+clock controller is the input clock to the peripheral clock controller.
+
+Required properties:
+- compatible: Must be "img,pistachio-periph-clk".
+- reg: Must contain the base address and length of the peripheral clock
+  controller.
+- #clock-cells: Must be 1.  The single cell is the clock identifier.
+  See dt-bindings/clock/pistachio-clk.h for the list of valid identifiers.
+- clocks: Must contain an entry for each clock in clock-names.
+- clock-names: Must include "periph_sys", the peripheral system clock generated
+  by the core clock controller.
+
+Example:
+       clk_periph: clock-controller@18144800 {
+               compatible = "img,pistachio-clk-periph";
+               reg = <0x18144800 0x800>;
+               clocks = <&clk_core CLK_PERIPH_SYS>;
+               clock-names = "periph_sys";
+
+               #clock-cells = <1>;
+       };
+
+Peripheral general control:
+---------------------------
+
+The peripheral general control block generates system interface clocks and
+resets for various peripherals.  It also contains miscellaneous peripheral
+control registers.  The system clock ("sys") generated by the peripheral clock
+controller is the input clock to the system clock controller.
+
+Required properties:
+- compatible: Must include "img,pistachio-periph-cr" and "syscon".
+- reg: Must contain the base address and length of the peripheral general
+  control registers.
+- #clock-cells: Must be 1.  The single cell is the clock identifier.
+  See dt-bindings/clock/pistachio-clk.h for the list of valid identifiers.
+- clocks: Must contain an entry for each clock in clock-names.
+- clock-names: Must include "sys", the system clock generated by the peripheral
+  clock controller.
+
+Example:
+       cr_periph: syscon@18144800 {
+               compatible = "img,pistachio-cr-periph", "syscon";
+               reg = <0x18148000 0x1000>;
+               clocks = <&clock_periph PERIPH_CLK_PERIPH_SYS>;
+               clock-names = "sys";
+
+               #clock-cells = <1>;
+       };
+
+Top-level general control:
+--------------------------
+
+The top-level general control block contains miscellaneous control registers and
+gates for the external clocks "audio_clk_in" and "enet_clk_in".
+
+Required properties:
+- compatible: Must include "img,pistachio-cr-top" and "syscon".
+- reg: Must contain the base address and length of the top-level
+  control registers.
+- clocks: Must contain an entry for each clock in clock-names.
+- clock-names: Two optional clocks, "audio_clk_in" and "enet_clk_in" (see
+  "External clocks").
+- #clock-cells: Must be 1.  The single cell is the clock identifier.
+  See dt-bindings/clock/pistachio-clk.h for the list of valid identifiers.
+
+Example:
+       cr_top: syscon@18144800 {
+               compatible = "img,pistachio-cr-top", "syscon";
+               reg = <0x18149000 0x200>;
+               clocks = <&audio_refclk>, <&ext_enet_in>;
+               clock-names = "audio_clk_in", "enet_clk_in";
+
+               #clock-cells = <1>;
+       };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm3380-l2-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm3380-l2-intc.txt
new file mode 100644 (file)
index 0000000..8f48aad
--- /dev/null
@@ -0,0 +1,41 @@
+Broadcom BCM3380-style Level 1 / Level 2 interrupt controller
+
+This interrupt controller shows up in various forms on many BCM338x/BCM63xx
+chipsets.  It has the following properties:
+
+- outputs a single interrupt signal to its interrupt controller parent
+
+- contains one or more enable/status word pairs, which often appear at
+  different offsets in different blocks
+
+- no atomic set/clear operations
+
+Required properties:
+
+- compatible: should be "brcm,bcm3380-l2-intc"
+- reg: specifies one or more enable/status pairs, in the following format:
+  <enable_reg 0x4 status_reg 0x4>...
+- interrupt-controller: identifies the node as an interrupt controller
+- #interrupt-cells: specifies the number of cells needed to encode an interrupt
+  source, should be 1.
+- interrupt-parent: specifies the phandle to the parent interrupt controller
+  this one is cascaded from
+- interrupts: specifies the interrupt line in the interrupt-parent controller
+  node, valid values depend on the type of parent interrupt controller
+
+Optional properties:
+
+- brcm,irq-can-wake: if present, this means the L2 controller can be used as a
+  wakeup source for system suspend/resume.
+
+Example:
+
+irq0_intc: interrupt-controller@10000020 {
+       compatible = "brcm,bcm3380-l2-intc";
+       reg = <0x10000024 0x4 0x1000002c 0x4>,
+             <0x10000020 0x4 0x10000028 0x4>;
+       interrupt-controller;
+       #interrupt-cells = <1>;
+       interrupt-parent = <&cpu_intc>;
+       interrupts = <2>;
+};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm7038-l1-intc.txt
new file mode 100644 (file)
index 0000000..cc217b2
--- /dev/null
@@ -0,0 +1,52 @@
+Broadcom BCM7038-style Level 1 interrupt controller
+
+This block is a first level interrupt controller that is typically connected
+directly to one of the HW INT lines on each CPU.  Every BCM7xxx set-top chip
+since BCM7038 has contained this hardware.
+
+Key elements of the hardware design include:
+
+- 64, 96, 128, or 160 incoming level IRQ lines
+
+- Most onchip peripherals are wired directly to an L1 input
+
+- A separate instance of the register set for each CPU, allowing individual
+  peripheral IRQs to be routed to any CPU
+
+- Atomic mask/unmask operations
+
+- No polarity/level/edge settings
+
+- No FIFO or priority encoder logic; software is expected to read all
+  2-5 status words to determine which IRQs are pending
+
+Required properties:
+
+- compatible: should be "brcm,bcm7038-l1-intc"
+- reg: specifies the base physical address and size of the registers;
+  the number of supported IRQs is inferred from the size argument
+- interrupt-controller: identifies the node as an interrupt controller
+- #interrupt-cells: specifies the number of cells needed to encode an interrupt
+  source, should be 1.
+- interrupt-parent: specifies the phandle to the parent interrupt controller(s)
+  this one is cascaded from
+- interrupts: specifies the interrupt line(s) in the interrupt-parent controller
+  node; valid values depend on the type of parent interrupt controller
+
+If multiple reg ranges and interrupt-parent entries are present on an SMP
+system, the driver will allow IRQ SMP affinity to be set up through the
+/proc/irq/ interface.  In the simplest possible configuration, only one
+reg range and one interrupt-parent is needed.
+
+Example:
+
+periph_intc: periph_intc@1041a400 {
+        compatible = "brcm,bcm7038-l1-intc";
+        reg = <0x1041a400 0x30 0x1041a600 0x30>;
+
+        interrupt-controller;
+        #interrupt-cells = <1>;
+
+        interrupt-parent = <&cpu_intc>;
+        interrupts = <2>, <3>;
+};
index bae1f21..44a9bb1 100644 (file)
@@ -13,8 +13,7 @@ Such an interrupt controller has the following hardware design:
   or if they will output an interrupt signal at this 2nd level interrupt
   controller, in particular for UARTs
 
-- typically has one 32-bit enable word and one 32-bit status word, but on
-  some hardware may have more than one enable/status pair
+- has one 32-bit enable word and one 32-bit status word
 
 - no atomic set/clear operations
 
@@ -53,9 +52,7 @@ The typical hardware layout for this controller is represented below:
 Required properties:
 
 - compatible: should be "brcm,bcm7120-l2-intc"
-- reg: specifies the base physical address and size of the registers;
-  multiple pairs may be specified, with the first pair handling IRQ offsets
-  0..31 and the second pair handling 32..63
+- reg: specifies the base physical address and size of the registers
 - interrupt-controller: identifies the node as an interrupt controller
 - #interrupt-cells: specifies the number of cells needed to encode an interrupt
   source, should be 1.
@@ -66,10 +63,7 @@ Required properties:
 - brcm,int-map-mask: 32-bits bit mask describing how many and which interrupts
   are wired to this 2nd level interrupt controller, and how they match their
   respective interrupt parents. Should match exactly the number of interrupts
-  specified in the 'interrupts' property, multiplied by the number of
-  enable/status register pairs implemented by this controller.  For
-  multiple parent IRQs with multiple enable/status words, this looks like:
-  <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
+  specified in the 'interrupts' property.
 
 Optional properties:
 
index 5a65478..aae4c38 100644 (file)
@@ -27,8 +27,13 @@ Optional properties:
 Required properties for timer sub-node:
 - compatible : Should be "mti,gic-timer".
 - interrupts : Interrupt for the GIC local timer.
+
+Optional properties for timer sub-node:
+- clocks : GIC timer operating clock.
 - clock-frequency : Clock frequency at which the GIC timers operate.
 
+Note that one of clocks or clock-frequency must be specified.
+
 Example:
 
        gic: interrupt-controller@1bdc0000 {
diff --git a/Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt b/Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt
deleted file mode 100644 (file)
index d4e0141..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-* Interrupt Controller
-
-Properties:
-- compatible: "brcm,bcm3384-intc"
-
-  Compatibility with BCM3384 and possibly other BCM33xx/BCM63xx SoCs.
-
-- reg: Address/length pairs for each mask/status register set.  Length must
-  be 8.  If multiple register sets are specified, the first set will
-  handle IRQ offsets 0..31, the second set 32..63, and so on.
-
-- interrupt-controller: This is an interrupt controller.
-
-- #interrupt-cells: Must be <1>.  Just a simple IRQ offset; no level/edge
-  or polarity configuration is possible with this controller.
-
-- interrupt-parent: This controller is cascaded from a MIPS CPU HW IRQ, or
-  from another INTC.
-
-- interrupts: The IRQ on the parent controller.
-
-Example:
-       periph_intc: periph_intc@14e00038 {
-               compatible = "brcm,bcm3384-intc";
-
-               /*
-                * IRQs 0..31:  mask reg 0x14e00038, status reg 0x14e0003c
-                * IRQs 32..63: mask reg 0x14e00340, status reg 0x14e00344
-                */
-               reg = <0x14e00038 0x8 0x14e00340 0x8>;
-
-               interrupt-controller;
-               #interrupt-cells = <1>;
-
-               interrupt-parent = <&cpu_intc>;
-               interrupts = <4>;
-       };
diff --git a/Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt b/Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt
deleted file mode 100644 (file)
index 8a139cb..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-* Broadcom cable/DSL platforms
-
-SoCs:
-
-Required properties:
-- compatible: "brcm,bcm3384", "brcm,bcm33843"
-
-Boards:
-
-Required properties:
-- compatible: "brcm,bcm93384wvg"
diff --git a/Documentation/devicetree/bindings/mips/brcm/soc.txt b/Documentation/devicetree/bindings/mips/brcm/soc.txt
new file mode 100644 (file)
index 0000000..7bab90c
--- /dev/null
@@ -0,0 +1,12 @@
+* Broadcom cable/DSL/settop platforms
+
+Required properties:
+
+- compatible: "brcm,bcm3384", "brcm,bcm33843"
+              "brcm,bcm3384-viper", "brcm,bcm33843-viper"
+              "brcm,bcm6328", "brcm,bcm6368",
+              "brcm,bcm7125", "brcm,bcm7346", "brcm,bcm7358", "brcm,bcm7360",
+              "brcm,bcm7362", "brcm,bcm7420", "brcm,bcm7425"
+
+The experimental -viper variants are for running Linux on the 3384's
+BMIPS4355 cable modem CPU instead of the BMIPS5000 application processor.
diff --git a/Documentation/devicetree/bindings/mips/img/pistachio.txt b/Documentation/devicetree/bindings/mips/img/pistachio.txt
new file mode 100644 (file)
index 0000000..a736d88
--- /dev/null
@@ -0,0 +1,42 @@
+Imagination Pistachio SoC
+=========================
+
+Required properties:
+--------------------
+ - compatible: Must include "img,pistachio".
+
+CPU nodes:
+----------
+A "cpus" node is required.  Required properties:
+ - #address-cells: Must be 1.
+ - #size-cells: Must be 0.
+A CPU sub-node is also required for at least CPU 0.  Since the topology may
+be probed via CPS, it is not necessary to specify secondary CPUs.  Required
+propertis:
+ - device_type: Must be "cpu".
+ - compatible: Must be "mti,interaptiv".
+ - reg: CPU number.
+ - clocks: Must include the CPU clock.  See ../../clock/clock-bindings.txt for
+   details on clock bindings.
+Example:
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mti,interaptiv";
+                       reg = <0>;
+                       clocks = <&clk_core CLK_MIPS>;
+               };
+       };
+
+
+Boot protocol:
+--------------
+In accordance with the MIPS UHI specification[1], the bootloader must pass the
+following arguments to the kernel:
+ - $a0: -2.
+ - $a1: KSEG0 address of the flattened device-tree blob.
+
+[1] http://prplfoundation.org/wiki/MIPS_documentation
index 7768518..e49e423 100644 (file)
@@ -15,6 +15,7 @@ Table of Contents
     1) Entry point for arch/arm
     2) Entry point for arch/powerpc
     3) Entry point for arch/x86
+    4) Entry point for arch/mips/bmips
 
   II - The DT block format
     1) Header
@@ -288,6 +289,33 @@ it with special cases.
   or initrd address. It simply holds information which can not be retrieved
   otherwise like interrupt routing or a list of devices behind an I2C bus.
 
+4) Entry point for arch/mips/bmips
+----------------------------------
+
+  Some bootloaders only support a single entry point, at the start of the
+  kernel image.  Other bootloaders will jump to the ELF start address.
+  Both schemes are supported; CONFIG_BOOT_RAW=y and CONFIG_NO_EXCEPT_FILL=y,
+  so the first instruction immediately jumps to kernel_entry().
+
+  Similar to the arch/arm case (b), a DT-aware bootloader is expected to
+  set up the following registers:
+
+         a0 : 0
+
+         a1 : 0xffffffff
+
+         a2 : Physical pointer to the device tree block (defined in chapter
+         II) in RAM.  The device tree can be located anywhere in the first
+         512MB of the physical address space (0x00000000 - 0x1fffffff),
+         aligned on a 64 bit boundary.
+
+  Legacy bootloaders do not use this convention, and they do not pass in a
+  DT block.  In this case, Linux will look for a builtin DTB, selected via
+  CONFIG_DT_*.
+
+  This convention is defined for 32-bit systems only, as there are not
+  currently any 64-bit BMIPS implementations.
+
 II - The DT block format
 ========================
 
index 491bbd1..11a76df 100644 (file)
@@ -2317,7 +2317,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        noexec32=off: disable non-executable mappings
                                read implies executable mappings
 
-       nofpu           [SH] Disable hardware FPU at boot time.
+       nofpu           [MIPS,SH] Disable hardware FPU at boot time.
 
        nofxsr          [BUGS=X86-32] Disables x86 floating point extended
                        register save and restore. The kernel will only save
index e5fc463..39cf40d 100644 (file)
@@ -4,9 +4,9 @@ platforms += alchemy
 platforms += ar7
 platforms += ath25
 platforms += ath79
-platforms += bcm3384
 platforms += bcm47xx
 platforms += bcm63xx
+platforms += bmips
 platforms += cavium-octeon
 platforms += cobalt
 platforms += dec
@@ -21,6 +21,7 @@ platforms += mti-malta
 platforms += mti-sead3
 platforms += netlogic
 platforms += paravirt
+platforms += pistachio
 platforms += pmcs-msp71xx
 platforms += pnx833x
 platforms += ralink
index a326c4c..2198837 100644 (file)
@@ -43,6 +43,7 @@ config MIPS
        select GENERIC_SMP_IDLE_THREAD
        select BUILDTIME_EXTABLE_SORT
        select GENERIC_CLOCKEVENTS
+       select GENERIC_SCHED_CLOCK if !CAVIUM_OCTEON_SOC
        select GENERIC_CMOS_UPDATE
        select HAVE_MOD_ARCH_SPECIFIC
        select VIRT_TO_BUS
@@ -55,6 +56,8 @@ config MIPS
        select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
        select ARCH_BINFMT_ELF_STATE
        select SYSCTL_EXCEPTION_TRACE
+       select HAVE_VIRT_CPU_ACCOUNTING_GEN
+       select HAVE_IRQ_TIME_ACCOUNTING
 
 menu "Machine selection"
 
@@ -131,8 +134,8 @@ config ATH79
        help
          Support for the Atheros AR71XX/AR724X/AR913X SoCs.
 
-config BCM3384
-       bool "Broadcom BCM3384 based boards"
+config BMIPS_GENERIC
+       bool "Broadcom Generic BMIPS kernel"
        select BOOT_RAW
        select NO_EXCEPT_FILL
        select USE_OF
@@ -140,22 +143,30 @@ config BCM3384
        select CSRC_R4K
        select SYNC_R4K
        select COMMON_CLK
-       select DMA_NONCOHERENT
+       select BCM7038_L1_IRQ
+       select BCM7120_L2_IRQ
+       select BRCMSTB_L2_IRQ
        select IRQ_CPU
+       select RAW_IRQ_ACCESSORS
+       select DMA_NONCOHERENT
        select SYS_SUPPORTS_32BIT_KERNEL
+       select SYS_SUPPORTS_LITTLE_ENDIAN
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_HIGHMEM
+       select SYS_HAS_CPU_BMIPS32_3300
+       select SYS_HAS_CPU_BMIPS4350
+       select SYS_HAS_CPU_BMIPS4380
        select SYS_HAS_CPU_BMIPS5000
        select SWAP_IO_SPACE
-       select USB_EHCI_BIG_ENDIAN_DESC
-       select USB_EHCI_BIG_ENDIAN_MMIO
-       select USB_OHCI_BIG_ENDIAN_DESC
-       select USB_OHCI_BIG_ENDIAN_MMIO
+       select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+       select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+       select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+       select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
        help
-         Support for BCM3384 based boards.  BCM3384/BCM33843 is a cable modem
-         chipset with a Linux application processor that is often used to
-         provide Samba services, a CUPS print server, and/or advanced routing
-         features.
+         Build a generic DT-based kernel image that boots on select
+         BCM33xx cable modem chips, BCM63xx DSL chips, and BCM7xxx set-top
+         box chips.  Note that CONFIG_CPU_BIG_ENDIAN/CONFIG_CPU_LITTLE_ENDIAN
+         must be set appropriately for your board.
 
 config BCM47XX
        bool "Broadcom BCM47XX based boards"
@@ -352,6 +363,33 @@ config MACH_LOONGSON1
          the ICT (Institute of Computing Technology) and the Chinese Academy
          of Sciences.
 
+config MACH_PISTACHIO
+       bool "IMG Pistachio SoC based boards"
+       select ARCH_REQUIRE_GPIOLIB
+       select BOOT_ELF32
+       select BOOT_RAW
+       select CEVT_R4K
+       select CLKSRC_MIPS_GIC
+       select COMMON_CLK
+       select CSRC_R4K
+       select DMA_MAYBE_COHERENT
+       select IRQ_CPU
+       select LIBFDT
+       select MFD_SYSCON
+       select MIPS_CPU_SCACHE
+       select MIPS_GIC
+       select PINCTRL
+       select REGULATOR
+       select SYS_HAS_CPU_MIPS32_R2
+       select SYS_SUPPORTS_32BIT_KERNEL
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_SUPPORTS_MIPS_CPS
+       select SYS_SUPPORTS_MULTITHREADING
+       select SYS_SUPPORTS_ZBOOT
+       select USE_OF
+       help
+         This enables support for the IMG Pistachio SoC platform.
+
 config MIPS_MALTA
        bool "MIPS Malta board"
        select ARCH_MAY_HAVE_PC_FDC
@@ -377,6 +415,7 @@ config MIPS_MALTA
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_HAS_CPU_MIPS32_R2
        select SYS_HAS_CPU_MIPS32_R3_5
+       select SYS_HAS_CPU_MIPS32_R5
        select SYS_HAS_CPU_MIPS32_R6
        select SYS_HAS_CPU_MIPS64_R1
        select SYS_HAS_CPU_MIPS64_R2
@@ -386,6 +425,7 @@ config MIPS_MALTA
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
+       select SYS_SUPPORTS_HIGHMEM
        select SYS_SUPPORTS_LITTLE_ENDIAN
        select SYS_SUPPORTS_MICROMIPS
        select SYS_SUPPORTS_MIPS_CMP
@@ -779,7 +819,8 @@ config CAVIUM_OCTEON_SOC
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        select EDAC_SUPPORT
-       select SYS_SUPPORTS_HOTPLUG_CPU
+       select SYS_SUPPORTS_LITTLE_ENDIAN
+       select SYS_SUPPORTS_HOTPLUG_CPU if CPU_BIG_ENDIAN
        select SYS_HAS_EARLY_PRINTK
        select SYS_HAS_CPU_CAVIUM_OCTEON
        select SWAP_IO_SPACE
@@ -793,6 +834,7 @@ config CAVIUM_OCTEON_SOC
        select SYS_SUPPORTS_SMP
        select NR_CPUS_DEFAULT_16
        select BUILTIN_DTB
+       select MTD_COMPLEX_MAPPINGS
        help
          This option supports all of the Octeon reference boards from Cavium
          Networks. It builds a kernel that dynamically determines the Octeon
@@ -887,6 +929,7 @@ source "arch/mips/ath25/Kconfig"
 source "arch/mips/ath79/Kconfig"
 source "arch/mips/bcm47xx/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
+source "arch/mips/bmips/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
 source "arch/mips/lantiq/Kconfig"
@@ -1202,10 +1245,10 @@ config MIPS_L1_CACHE_SHIFT_7
 
 config MIPS_L1_CACHE_SHIFT
        int
-       default "4" if MIPS_L1_CACHE_SHIFT_4
-       default "5" if MIPS_L1_CACHE_SHIFT_5
-       default "6" if MIPS_L1_CACHE_SHIFT_6
        default "7" if MIPS_L1_CACHE_SHIFT_7
+       default "6" if MIPS_L1_CACHE_SHIFT_6
+       default "5" if MIPS_L1_CACHE_SHIFT_5
+       default "4" if MIPS_L1_CACHE_SHIFT_4
        default "5"
 
 config HAVE_STD_PC_SERIAL_PORT
@@ -1572,6 +1615,7 @@ config CPU_XLP
        select WEAK_REORDERING_BEYOND_LLSC
        select CPU_HAS_PREFETCH
        select CPU_MIPSR2
+       select CPU_SUPPORTS_HUGEPAGES
        help
          Netlogic Microsystems XLP processors.
 endchoice
@@ -1596,6 +1640,33 @@ config CPU_MIPS32_3_5_EVA
          One of its primary benefits is an increase in the maximum size
          of lowmem (up to 3GB). If unsure, say 'N' here.
 
+config CPU_MIPS32_R5_FEATURES
+       bool "MIPS32 Release 5 Features"
+       depends on SYS_HAS_CPU_MIPS32_R5
+       depends on CPU_MIPS32_R2
+       help
+         Choose this option to build a kernel for release 2 or later of the
+         MIPS32 architecture including features from release 5 such as
+         support for Extended Physical Addressing (XPA).
+
+config CPU_MIPS32_R5_XPA
+       bool "Extended Physical Addressing (XPA)"
+       depends on CPU_MIPS32_R5_FEATURES
+       depends on !EVA
+       depends on !PAGE_SIZE_4KB
+       depends on SYS_SUPPORTS_HIGHMEM
+       select XPA
+       select HIGHMEM
+       select ARCH_PHYS_ADDR_T_64BIT
+       default n
+       help
+         Choose this option if you want to enable the Extended Physical
+         Addressing (XPA) on your MIPS32 core (such as P5600 series). The
+         benefit is to increase physical addressing equal to or greater
+         than 40 bits. Note that this has the side effect of turning on
+         64-bit addressing which in turn makes the PTEs 64-bit in size.
+         If unsure, say 'N' here.
+
 if CPU_LOONGSON2F
 config CPU_NOP_WORKAROUNDS
        bool
@@ -1699,6 +1770,9 @@ config SYS_HAS_CPU_MIPS32_R2
 config SYS_HAS_CPU_MIPS32_R3_5
        bool
 
+config SYS_HAS_CPU_MIPS32_R5
+       bool
+
 config SYS_HAS_CPU_MIPS32_R6
        bool
 
@@ -1836,6 +1910,9 @@ config CPU_MIPSR6
 config EVA
        bool
 
+config XPA
+       bool
+
 config SYS_SUPPORTS_32BIT_KERNEL
        bool
 config SYS_SUPPORTS_64BIT_KERNEL
@@ -2072,7 +2149,7 @@ config MIPSR2_TO_R6_EMULATOR
        help
          Choose this option if you want to run non-R6 MIPS userland code.
          Even if you say 'Y' here, the emulator will still be disabled by
-         default. You can enable it using the 'mipsr2emul' kernel option.
+         default. You can enable it using the 'mipsr2emu' kernel option.
          The only reason this is a build-time option is to save ~14K from the
          final kernel image.
 comment "MIPS R2-to-R6 emulator is only available for UP kernels"
@@ -2142,7 +2219,7 @@ config MIPS_CMP
 
 config MIPS_CPS
        bool "MIPS Coherent Processing System support"
-       depends on SYS_SUPPORTS_MIPS_CPS
+       depends on SYS_SUPPORTS_MIPS_CPS && !64BIT
        select MIPS_CM
        select MIPS_CPC
        select MIPS_CPS_PM if HOTPLUG_CPU
@@ -2348,7 +2425,7 @@ config NODES_SHIFT
 
 config HW_PERF_EVENTS
        bool "Enable hardware performance counter support for perf events"
-       depends on PERF_EVENTS && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP)
+       depends on PERF_EVENTS && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON3)
        default y
        help
          Enable hardware performance counter support for perf events. If
@@ -2500,6 +2577,9 @@ config HZ
        default 1000 if HZ_1000
        default 1024 if HZ_1024
 
+config SCHED_HRTICK
+       def_bool HIGH_RES_TIMERS
+
 source "kernel/Kconfig.preempt"
 
 config KEXEC
index d152dfb..5200f64 100644 (file)
@@ -197,11 +197,17 @@ endif
 # Warning: the 64-bit MIPS architecture does not support the `smartmips' extension
 # Pass -Wa,--no-warn to disable all assembler warnings until the kernel code has
 # been fixed properly.
-mips-cflags                            := "$(cflags-y)"
-cflags-$(CONFIG_CPU_HAS_SMARTMIPS)     += $(call cc-option,$(mips-cflags),-msmartmips) -Wa,--no-warn
-cflags-$(CONFIG_CPU_MICROMIPS)         += $(call cc-option,$(mips-cflags),-mmicromips)
+mips-cflags                            := $(cflags-y)
+ifeq ($(CONFIG_CPU_HAS_SMARTMIPS),y)
+smartmips-ase                          := $(call cc-option-yn,$(mips-cflags) -msmartmips)
+cflags-$(smartmips-ase)                        += -msmartmips -Wa,--no-warn
+endif
+ifeq ($(CONFIG_CPU_MICROMIPS),y)
+micromips-ase                          := $(call cc-option-yn,$(mips-cflags) -mmicromips)
+cflags-$(micromips-ase)                        += -mmicromips
+endif
 ifeq ($(CONFIG_CPU_HAS_MSA),y)
-toolchain-msa                          := $(call cc-option-yn,-$(mips-cflags),mhard-float -mfp64 -Wa$(comma)-mmsa)
+toolchain-msa                          := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$(comma)-mmsa)
 cflags-$(toolchain-msa)                        += -DTOOLCHAIN_SUPPORTS_MSA
 endif
 
@@ -365,7 +371,11 @@ core-$(CONFIG_BUILTIN_DTB) += arch/mips/boot/dts/
 
 PHONY += dtbs
 dtbs: scripts
-       $(Q)$(MAKE) $(build)=arch/mips/boot/dts dtbs
+       $(Q)$(MAKE) $(build)=arch/mips/boot/dts
+
+PHONY += dtbs_install
+dtbs_install:
+       $(Q)$(MAKE) $(dtbinst)=arch/mips/boot/dts
 
 archprepare:
 ifdef CONFIG_MIPS32_N32
@@ -407,6 +417,7 @@ define archhelp
        echo '  uImage.lzma          - U-Boot image (lzma)'
        echo '  uImage.lzo           - U-Boot image (lzo)'
        echo '  dtbs                 - Device-tree blobs for enabled boards'
+       echo '  dtbs_install         - Install dtbs to $(INSTALL_DTBS_PATH)'
        echo
        echo '  These will be default as appropriate for a configured platform.'
 endef
index af2441d..be9ff16 100644 (file)
@@ -307,10 +307,7 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
        }
 
        if (mac) {
-               if (sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-                                       &dev_addr[0], &dev_addr[1],
-                                       &dev_addr[2], &dev_addr[3],
-                                       &dev_addr[4], &dev_addr[5]) != 6) {
+               if (!mac_pton(mac, dev_addr)) {
                        pr_warn("cannot parse mac address, using random address\n");
                        eth_random_addr(dev_addr);
                }
index a312071..c39de61 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/types.h>
 
 #define ATH79_MEM_SIZE_MIN     (2 * 1024 * 1024)
-#define ATH79_MEM_SIZE_MAX     (128 * 1024 * 1024)
+#define ATH79_MEM_SIZE_MAX     (256 * 1024 * 1024)
 
 void ath79_clocks_init(void);
 unsigned long ath79_get_sys_clk_rate(const char *id);
diff --git a/arch/mips/bcm3384/Platform b/arch/mips/bcm3384/Platform
deleted file mode 100644 (file)
index 8e1ca08..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Broadcom BCM3384 boards
-#
-platform-$(CONFIG_BCM3384)     += bcm3384/
-cflags-$(CONFIG_BCM3384)       +=                                      \
-               -I$(srctree)/arch/mips/include/asm/mach-bcm3384/
-load-$(CONFIG_BCM3384)         := 0xffffffff80010000
diff --git a/arch/mips/bcm3384/dma.c b/arch/mips/bcm3384/dma.c
deleted file mode 100644 (file)
index ea42012..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
- */
-
-#include <linux/device.h>
-#include <linux/dma-direction.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/of.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <dma-coherence.h>
-
-/*
- * BCM3384 has configurable address translation windows which allow the
- * peripherals' DMA addresses to be different from the Zephyr-visible
- * physical addresses.  e.g. usb_dma_addr = zephyr_pa ^ 0x08000000
- *
- * If our DT "memory" node has a "dma-xor-mask" property we will enable this
- * translation using the provided offset.
- */
-static u32 bcm3384_dma_xor_mask;
-static u32 bcm3384_dma_xor_limit = 0xffffffff;
-
-/*
- * PCI collapses the memory hole at 0x10000000 - 0x1fffffff.
- * On systems with a dma-xor-mask, this range is guaranteed to live above
- * the dma-xor-limit.
- */
-#define BCM3384_MEM_HOLE_PA    0x10000000
-#define BCM3384_MEM_HOLE_SIZE  0x10000000
-
-static dma_addr_t bcm3384_phys_to_dma(struct device *dev, phys_addr_t pa)
-{
-       if (dev && dev_is_pci(dev) &&
-           pa >= (BCM3384_MEM_HOLE_PA + BCM3384_MEM_HOLE_SIZE))
-               return pa - BCM3384_MEM_HOLE_SIZE;
-       if (pa <= bcm3384_dma_xor_limit)
-               return pa ^ bcm3384_dma_xor_mask;
-       return pa;
-}
-
-dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
-{
-       return bcm3384_phys_to_dma(dev, virt_to_phys(addr));
-}
-
-dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
-{
-       return bcm3384_phys_to_dma(dev, page_to_phys(page));
-}
-
-unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
-{
-       if (dev && dev_is_pci(dev) &&
-           dma_addr >= BCM3384_MEM_HOLE_PA)
-               return dma_addr + BCM3384_MEM_HOLE_SIZE;
-       if ((dma_addr ^ bcm3384_dma_xor_mask) <= bcm3384_dma_xor_limit)
-               return dma_addr ^ bcm3384_dma_xor_mask;
-       return dma_addr;
-}
-
-static int __init bcm3384_init_dma_xor(void)
-{
-       struct device_node *np = of_find_node_by_type(NULL, "memory");
-
-       if (!np)
-               return 0;
-
-       of_property_read_u32(np, "dma-xor-mask", &bcm3384_dma_xor_mask);
-       of_property_read_u32(np, "dma-xor-limit", &bcm3384_dma_xor_limit);
-
-       of_node_put(np);
-       return 0;
-}
-arch_initcall(bcm3384_init_dma_xor);
diff --git a/arch/mips/bcm3384/irq.c b/arch/mips/bcm3384/irq.c
deleted file mode 100644 (file)
index fd94fe8..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * Partially based on arch/mips/ralink/irq.c
- *
- * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
- */
-
-#include <linux/io.h>
-#include <linux/bitops.h>
-#include <linux/of_platform.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/irqdomain.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-
-#include <asm/bmips.h>
-#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
-
-/* INTC register offsets */
-#define INTC_REG_ENABLE                0x00
-#define INTC_REG_STATUS                0x04
-
-#define MAX_WORDS              2
-#define IRQS_PER_WORD          32
-
-struct bcm3384_intc {
-       int                     n_words;
-       void __iomem            *reg[MAX_WORDS];
-       u32                     enable[MAX_WORDS];
-       spinlock_t              lock;
-};
-
-static void bcm3384_intc_irq_unmask(struct irq_data *d)
-{
-       struct bcm3384_intc *priv = d->domain->host_data;
-       unsigned long flags;
-       int idx = d->hwirq / IRQS_PER_WORD;
-       int bit = d->hwirq % IRQS_PER_WORD;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->enable[idx] |= BIT(bit);
-       __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE);
-       spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static void bcm3384_intc_irq_mask(struct irq_data *d)
-{
-       struct bcm3384_intc *priv = d->domain->host_data;
-       unsigned long flags;
-       int idx = d->hwirq / IRQS_PER_WORD;
-       int bit = d->hwirq % IRQS_PER_WORD;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->enable[idx] &= ~BIT(bit);
-       __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE);
-       spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static struct irq_chip bcm3384_intc_irq_chip = {
-       .name           = "INTC",
-       .irq_unmask     = bcm3384_intc_irq_unmask,
-       .irq_mask       = bcm3384_intc_irq_mask,
-       .irq_mask_ack   = bcm3384_intc_irq_mask,
-};
-
-unsigned int get_c0_compare_int(void)
-{
-       return CP0_LEGACY_COMPARE_IRQ;
-}
-
-static void bcm3384_intc_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       struct irq_domain *domain = irq_get_handler_data(irq);
-       struct bcm3384_intc *priv = domain->host_data;
-       unsigned long flags;
-       unsigned int idx;
-
-       for (idx = 0; idx < priv->n_words; idx++) {
-               unsigned long pending;
-               int hwirq;
-
-               spin_lock_irqsave(&priv->lock, flags);
-               pending = __raw_readl(priv->reg[idx] + INTC_REG_STATUS) &
-                         priv->enable[idx];
-               spin_unlock_irqrestore(&priv->lock, flags);
-
-               for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
-                       generic_handle_irq(irq_find_mapping(domain,
-                                          hwirq + idx * IRQS_PER_WORD));
-               }
-       }
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned long pending =
-               (read_c0_status() & read_c0_cause() & ST0_IM) >> STATUSB_IP0;
-       int bit;
-
-       for_each_set_bit(bit, &pending, 8)
-               do_IRQ(MIPS_CPU_IRQ_BASE + bit);
-}
-
-static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
-{
-       irq_set_chip_and_handler(irq, &bcm3384_intc_irq_chip, handle_level_irq);
-       return 0;
-}
-
-static const struct irq_domain_ops irq_domain_ops = {
-       .xlate = irq_domain_xlate_onecell,
-       .map = intc_map,
-};
-
-static int __init ioremap_one_pair(struct bcm3384_intc *priv,
-                                  struct device_node *node,
-                                  int idx)
-{
-       struct resource res;
-
-       if (of_address_to_resource(node, idx, &res))
-               return 0;
-
-       if (request_mem_region(res.start, resource_size(&res),
-                              res.name) < 0)
-               pr_err("Failed to request INTC register region\n");
-
-       priv->reg[idx] = ioremap_nocache(res.start, resource_size(&res));
-       if (!priv->reg[idx])
-               panic("Failed to ioremap INTC register range");
-
-       /* start up with everything masked before we hook the parent IRQ */
-       __raw_writel(0, priv->reg[idx] + INTC_REG_ENABLE);
-       priv->enable[idx] = 0;
-
-       return IRQS_PER_WORD;
-}
-
-static int __init intc_of_init(struct device_node *node,
-                              struct device_node *parent)
-{
-       struct irq_domain *domain;
-       unsigned int parent_irq, n_irqs = 0;
-       struct bcm3384_intc *priv;
-
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv)
-               panic("Failed to allocate bcm3384_intc struct");
-
-       spin_lock_init(&priv->lock);
-
-       parent_irq = irq_of_parse_and_map(node, 0);
-       if (!parent_irq)
-               panic("Failed to get INTC IRQ");
-
-       n_irqs += ioremap_one_pair(priv, node, 0);
-       n_irqs += ioremap_one_pair(priv, node, 1);
-
-       if (!n_irqs)
-               panic("Failed to map INTC registers");
-
-       priv->n_words = n_irqs / IRQS_PER_WORD;
-       domain = irq_domain_add_linear(node, n_irqs, &irq_domain_ops, priv);
-       if (!domain)
-               panic("Failed to add irqdomain");
-
-       irq_set_chained_handler(parent_irq, bcm3384_intc_irq_handler);
-       irq_set_handler_data(parent_irq, domain);
-
-       return 0;
-}
-
-static struct of_device_id of_irq_ids[] __initdata = {
-       { .compatible = "mti,cpu-interrupt-controller",
-         .data = mips_cpu_irq_of_init },
-       { .compatible = "brcm,bcm3384-intc",
-         .data = intc_of_init },
-       {},
-};
-
-void __init arch_init_irq(void)
-{
-       bmips_tp1_irqs = 0;
-       of_irq_init(of_irq_ids);
-}
diff --git a/arch/mips/bcm3384/setup.c b/arch/mips/bcm3384/setup.c
deleted file mode 100644 (file)
index d84b840..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
- * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
- */
-
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/clk-provider.h>
-#include <linux/ioport.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
-#include <linux/of_platform.h>
-#include <linux/smp.h>
-#include <asm/addrspace.h>
-#include <asm/bmips.h>
-#include <asm/bootinfo.h>
-#include <asm/prom.h>
-#include <asm/smp-ops.h>
-#include <asm/time.h>
-
-void __init prom_init(void)
-{
-       register_bmips_smp_ops();
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-const char *get_system_type(void)
-{
-       return "BCM3384";
-}
-
-void __init plat_time_init(void)
-{
-       struct device_node *np;
-       u32 freq;
-
-       np = of_find_node_by_name(NULL, "cpus");
-       if (!np)
-               panic("missing 'cpus' DT node");
-       if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
-               panic("missing 'mips-hpt-frequency' property");
-       of_node_put(np);
-
-       mips_hpt_frequency = freq;
-}
-
-void __init plat_mem_setup(void)
-{
-       void *dtb = __dtb_start;
-
-       set_io_port_base(0);
-       ioport_resource.start = 0;
-       ioport_resource.end = ~0;
-
-       /* intended to somewhat resemble ARM; see Documentation/arm/Booting */
-       if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
-               dtb = phys_to_virt(fw_arg2);
-
-       __dt_setup_arch(dtb);
-
-       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
-}
-
-void __init device_tree_init(void)
-{
-       struct device_node *np;
-
-       unflatten_and_copy_device_tree();
-
-       /* Disable SMP boot unless both CPUs are listed in DT and !disabled */
-       np = of_find_node_by_name(NULL, "cpus");
-       if (np && of_get_available_child_count(np) <= 1)
-               bmips_smp_enabled = 0;
-       of_node_put(np);
-}
-
-int __init plat_of_setup(void)
-{
-       return __dt_register_buses("brcm,bcm3384", "simple-bus");
-}
-
-arch_initcall(plat_of_setup);
-
-static int __init plat_dev_init(void)
-{
-       of_clk_init(NULL);
-       return 0;
-}
-
-device_initcall(plat_dev_init);
index ea909a5..41796be 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef LINUX_BCM47XX_PRIVATE_H_
 #define LINUX_BCM47XX_PRIVATE_H_
 
+#ifndef pr_fmt
+#define pr_fmt(fmt)            "bcm47xx: " fmt
+#endif
+
 #include <linux/kernel.h>
 
 /* prom.c */
index b3ae068..bd56415 100644 (file)
@@ -1,8 +1,8 @@
 #include <linux/errno.h>
 #include <linux/export.h>
 #include <linux/string.h>
+#include <bcm47xx.h>
 #include <bcm47xx_board.h>
-#include <bcm47xx_nvram.h>
 
 struct bcm47xx_board_type {
        const enum bcm47xx_board board;
@@ -40,20 +40,6 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_model_name[] __initconst = {
        { {0}, NULL},
 };
 
-/* model_no */
-static const
-struct bcm47xx_board_type_list1 bcm47xx_board_list_model_no[] __initconst = {
-       {{BCM47XX_BOARD_ASUS_WL700GE, "Asus WL700"}, "WL700"},
-       { {0}, NULL},
-};
-
-/* machine_name */
-static const
-struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst = {
-       {{BCM47XX_BOARD_LINKSYS_WRTSL54GS, "Linksys WRTSL54GS"}, "WRTSL54GS"},
-       { {0}, NULL},
-};
-
 /* hardware_version */
 static const
 struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = {
@@ -165,9 +151,11 @@ static const
 struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = {
        {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WNDR3300, "Netgear WNDR3300"}, "U12H093T00_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WNDR3400V1, "Netgear WNDR3400 V1"}, "U12H155T00_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WNDR3400V2, "Netgear WNDR3400 V2"}, "U12H187T00_NETGEAR"},
+       {{BCM47XX_BOARD_NETGEAR_WNDR3400_V3, "Netgear WNDR3400 V3"}, "U12H208T00_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WNDR3400VCNA, "Netgear WNDR3400 Vcna"}, "U12H155T01_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WNDR3700V3, "Netgear WNDR3700 V3"}, "U12H194T00_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WNDR4000, "Netgear WNDR4000"}, "U12H181T00_NETGEAR"},
@@ -202,6 +190,20 @@ struct bcm47xx_board_type_list2 bcm47xx_board_list_board_type_rev[] __initconst
        { {0}, NULL},
 };
 
+/*
+ * Some devices don't use any common NVRAM entry for identification and they
+ * have only one model specific variable.
+ * They don't deserve own arrays, let's group them there using key-value array.
+ */
+static const
+struct bcm47xx_board_type_list2 bcm47xx_board_list_key_value[] __initconst = {
+       {{BCM47XX_BOARD_ASUS_WL700GE, "Asus WL700"}, "model_no", "WL700"},
+       {{BCM47XX_BOARD_LINKSYS_WRT300N_V1, "Linksys WRT300N V1"}, "router_name", "WRT300N"},
+       {{BCM47XX_BOARD_LINKSYS_WRT600N_V11, "Linksys WRT600N V1.1"}, "Model_Name", "WRT600N"},
+       {{BCM47XX_BOARD_LINKSYS_WRTSL54GS, "Linksys WRTSL54GS"}, "machine_name", "WRTSL54GS"},
+       { {0}, NULL},
+};
+
 static const
 struct bcm47xx_board_type bcm47xx_board_unknown[] __initconst = {
        {BCM47XX_BOARD_UNKNOWN, "Unknown Board"},
@@ -225,20 +227,6 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
                }
        }
 
-       if (bcm47xx_nvram_getenv("model_no", buf1, sizeof(buf1)) >= 0) {
-               for (e1 = bcm47xx_board_list_model_no; e1->value1; e1++) {
-                       if (strstarts(buf1, e1->value1))
-                               return &e1->board;
-               }
-       }
-
-       if (bcm47xx_nvram_getenv("machine_name", buf1, sizeof(buf1)) >= 0) {
-               for (e1 = bcm47xx_board_list_machine_name; e1->value1; e1++) {
-                       if (strstarts(buf1, e1->value1))
-                               return &e1->board;
-               }
-       }
-
        if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0) {
                for (e1 = bcm47xx_board_list_hardware_version; e1->value1; e1++) {
                        if (strstarts(buf1, e1->value1))
@@ -247,8 +235,8 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
        }
 
        if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 &&
-           bcm47xx_nvram_getenv("boardtype", buf2, sizeof(buf2)) >= 0) {
-               for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) {
+           bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0) {
+               for (e2 = bcm47xx_board_list_hw_version_num; e2->value1; e2++) {
                        if (!strstarts(buf1, e2->value1) &&
                            !strcmp(buf2, e2->value2))
                                return &e2->board;
@@ -314,6 +302,14 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
                                return &e2->board;
                }
        }
+
+       for (e2 = bcm47xx_board_list_key_value; e2->value1; e2++) {
+               if (bcm47xx_nvram_getenv(e2->value1, buf1, sizeof(buf1)) >= 0) {
+                       if (!strcmp(buf1, e2->value2))
+                               return &e2->board;
+               }
+       }
+
        return bcm47xx_board_unknown;
 }
 
@@ -330,9 +326,8 @@ void __init bcm47xx_board_detect(void)
        err = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
 
        /* init of nvram failed, probably too early now */
-       if (err == -ENXIO) {
+       if (err == -ENXIO)
                return;
-       }
 
        board_detected = bcm47xx_board_get_nvram();
        bcm47xx_board.board = board_detected->board;
index 913182b..276276a 100644 (file)
@@ -252,6 +252,12 @@ bcm47xx_buttons_linksys_wrt160nv3[] __initconst = {
 };
 
 static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt300n_v1[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
 bcm47xx_buttons_linksys_wrt300nv11[] __initconst = {
        BCM47XX_GPIO_KEY(4, KEY_UNKNOWN),
        BCM47XX_GPIO_KEY(6, KEY_RESTART),
@@ -327,6 +333,12 @@ bcm47xx_buttons_netgear_wndr3400v1[] __initconst = {
 };
 
 static const struct gpio_keys_button
+bcm47xx_buttons_netgear_wndr3400_v3[] __initconst = {
+       BCM47XX_GPIO_KEY(12, KEY_RESTART),
+       BCM47XX_GPIO_KEY(23, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
 bcm47xx_buttons_netgear_wndr3700v3[] __initconst = {
        BCM47XX_GPIO_KEY(2, KEY_RFKILL),
        BCM47XX_GPIO_KEY(3, KEY_RESTART),
@@ -516,6 +528,9 @@ int __init bcm47xx_buttons_register(void)
        case BCM47XX_BOARD_LINKSYS_WRT160NV3:
                err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv3);
                break;
+       case BCM47XX_BOARD_LINKSYS_WRT300N_V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt300n_v1);
+               break;
        case BCM47XX_BOARD_LINKSYS_WRT300NV11:
                err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt300nv11);
                break;
@@ -557,6 +572,9 @@ int __init bcm47xx_buttons_register(void)
        case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
                err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1);
                break;
+       case BCM47XX_BOARD_NETGEAR_WNDR3400_V3:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400_v3);
+               break;
        case BCM47XX_BOARD_NETGEAR_WNDR3700V3:
                err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3700v3);
                break;
index 903a656..0e4ade3 100644 (file)
@@ -292,6 +292,13 @@ bcm47xx_leds_linksys_wrt160nv3[] __initconst = {
 };
 
 static const struct gpio_led
+bcm47xx_leds_linksys_wrt300n_v1[] __initconst = {
+       BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
 bcm47xx_leds_linksys_wrt300nv11[] __initconst = {
        BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
        BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
@@ -585,6 +592,9 @@ void __init bcm47xx_leds_register(void)
        case BCM47XX_BOARD_LINKSYS_WRT160NV3:
                bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv3);
                break;
+       case BCM47XX_BOARD_LINKSYS_WRT300N_V1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt300n_v1);
+               break;
        case BCM47XX_BOARD_LINKSYS_WRT300NV11:
                bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt300nv11);
                break;
index c5c381c..ba632ff 100644 (file)
  * option) any later version.
  */
 
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/mtd/mtd.h>
-#include <bcm47xx_nvram.h>
+#include <linux/bcm47xx_nvram.h>
 
-#define NVRAM_MAGIC            0x48534C46      /* 'FLSH' */
-#define NVRAM_SPACE            0x8000
+#define NVRAM_MAGIC                    0x48534C46      /* 'FLSH' */
+#define NVRAM_SPACE                    0x10000
+#define NVRAM_MAX_GPIO_ENTRIES         32
+#define NVRAM_MAX_GPIO_VALUE_LEN       30
 
 #define FLASH_MIN              0x00020000      /* Minimum flash size */
 
@@ -91,20 +94,18 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
        return -ENXIO;
 
 found:
-
        if (header->len > size)
                pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n");
        if (header->len > NVRAM_SPACE)
                pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
                       header->len, NVRAM_SPACE);
 
-       src = (u32 *) header;
-       dst = (u32 *) nvram_buf;
+       src = (u32 *)header;
+       dst = (u32 *)nvram_buf;
        for (i = 0; i < sizeof(struct nvram_header); i += 4)
-               *dst++ = *src++;
+               *dst++ = __raw_readl(src++);
        for (; i < header->len && i < NVRAM_SPACE && i < size; i += 4)
-               *dst++ = le32_to_cpu(*src++);
-       memset(dst, 0x0, NVRAM_SPACE - i);
+               *dst++ = readl(src++);
 
        return 0;
 }
@@ -138,37 +139,28 @@ static int nvram_init(void)
        struct mtd_info *mtd;
        struct nvram_header header;
        size_t bytes_read;
-       int err, i;
+       int err;
 
        mtd = get_mtd_device_nm("nvram");
        if (IS_ERR(mtd))
                return -ENODEV;
 
-       for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
-               loff_t from = mtd->size - nvram_sizes[i];
+       err = mtd_read(mtd, 0, sizeof(header), &bytes_read, (uint8_t *)&header);
+       if (!err && header.magic == NVRAM_MAGIC) {
+               u8 *dst = (uint8_t *)nvram_buf;
+               size_t len = header.len;
 
-               if (from < 0)
-                       continue;
-
-               err = mtd_read(mtd, from, sizeof(header), &bytes_read,
-                              (uint8_t *)&header);
-               if (!err && header.magic == NVRAM_MAGIC) {
-                       u8 *dst = (uint8_t *)nvram_buf;
-                       size_t len = header.len;
-
-                       if (header.len > NVRAM_SPACE) {
-                               pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
-                                      header.len, NVRAM_SPACE);
-                               len = NVRAM_SPACE;
-                       }
+               if (header.len > NVRAM_SPACE) {
+                       pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
+                               header.len, NVRAM_SPACE);
+                       len = NVRAM_SPACE;
+               }
 
-                       err = mtd_read(mtd, from, len, &bytes_read, dst);
-                       if (err)
-                               return err;
-                       memset(dst + bytes_read, 0x0, NVRAM_SPACE - bytes_read);
+               err = mtd_read(mtd, 0, len, &bytes_read, dst);
+               if (err)
+                       return err;
 
-                       return 0;
-               }
+               return 0;
        }
 #endif
 
@@ -178,7 +170,7 @@ static int nvram_init(void)
 int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
 {
        char *var, *value, *end, *eq;
-       int err;
+       int data_left, err;
 
        if (!name)
                return -EINVAL;
@@ -192,16 +184,18 @@ int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
        /* Look for name=value and return value */
        var = &nvram_buf[sizeof(struct nvram_header)];
        end = nvram_buf + sizeof(nvram_buf) - 2;
-       end[0] = end[1] = '\0';
+       end[0] = '\0';
+       end[1] = '\0';
        for (; *var; var = value + strlen(value) + 1) {
-               eq = strchr(var, '=');
+               data_left = end - var;
+
+               eq = strnchr(var, data_left, '=');
                if (!eq)
                        break;
                value = eq + 1;
-               if ((eq - var) == strlen(name) &&
-                       strncmp(var, name, (eq - var)) == 0) {
+               if (eq - var == strlen(name) &&
+                   strncmp(var, name, eq - var) == 0)
                        return snprintf(val, val_len, "%s", value);
-               }
        }
        return -ENOENT;
 }
@@ -210,10 +204,11 @@ EXPORT_SYMBOL(bcm47xx_nvram_getenv);
 int bcm47xx_nvram_gpio_pin(const char *name)
 {
        int i, err;
-       char nvram_var[10];
-       char buf[30];
+       char nvram_var[] = "gpioXX";
+       char buf[NVRAM_MAX_GPIO_VALUE_LEN];
 
-       for (i = 0; i < 32; i++) {
+       /* TODO: Optimize it to don't call getenv so many times */
+       for (i = 0; i < NVRAM_MAX_GPIO_ENTRIES; i++) {
                err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
                if (err <= 0)
                        continue;
index 1b170bf..ab698ba 100644 (file)
@@ -35,7 +35,6 @@
 #include <bcm47xx.h>
 #include <bcm47xx_board.h>
 
-
 static char bcm47xx_system_type[20] = "Broadcom BCM47XX";
 
 const char *get_system_type(void)
@@ -83,7 +82,7 @@ static __init void prom_init_mem(void)
                /* Loop condition may be not enough, off may be over 1 MiB */
                if (off + mem >= max) {
                        mem = max;
-                       printk(KERN_DEBUG "assume 128MB RAM\n");
+                       pr_debug("Assume 128MB RAM\n");
                        break;
                }
                if (!memcmp(prom_init, prom_init + mem, 32))
index 2f5bbd6..df761d3 100644 (file)
@@ -36,8 +36,8 @@ static int __init uart8250_init_ssb(void)
                struct plat_serial8250_port *p = &(uart8250_data[i]);
                struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]);
 
-               p->mapbase = (unsigned int) ssb_port->regs;
-               p->membase = (void *) ssb_port->regs;
+               p->mapbase = (unsigned int)ssb_port->regs;
+               p->membase = (void *)ssb_port->regs;
                p->irq = ssb_port->irq + 2;
                p->uartclk = ssb_port->baud_base;
                p->regshift = ssb_port->reg_shift;
@@ -62,8 +62,8 @@ static int __init uart8250_init_bcma(void)
                struct bcma_serial_port *bcma_port;
                bcma_port = &(cc->serial_ports[i]);
 
-               p->mapbase = (unsigned int) bcma_port->regs;
-               p->membase = (void *) bcma_port->regs;
+               p->mapbase = (unsigned int)bcma_port->regs;
+               p->membase = (void *)bcma_port->regs;
                p->irq = bcma_port->irq;
                p->uartclk = bcma_port->baud_base;
                p->regshift = bcma_port->reg_shift;
index e43b504..82ff9fd 100644 (file)
@@ -42,7 +42,6 @@
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <bcm47xx.h>
-#include <bcm47xx_nvram.h>
 #include <bcm47xx_board.h>
 
 union bcm47xx_bus bcm47xx_bus;
@@ -53,7 +52,7 @@ EXPORT_SYMBOL(bcm47xx_bus_type);
 
 static void bcm47xx_machine_restart(char *command)
 {
-       printk(KERN_ALERT "Please stand by while rebooting the system...\n");
+       pr_alert("Please stand by while rebooting the system...\n");
        local_irq_disable();
        /* Set the watchdog timer to reset immediately */
        switch (bcm47xx_bus_type) {
@@ -108,7 +107,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
        char buf[20];
 
        /* Fill boardinfo structure */
-       memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
+       memset(&iv->boardinfo, 0 , sizeof(struct ssb_boardinfo));
 
        bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL);
 
@@ -127,7 +126,7 @@ static void __init bcm47xx_register_ssb(void)
        char buf[100];
        struct ssb_mipscore *mcore;
 
-       err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
+       err = ssb_bus_ssbbus_register(&bcm47xx_bus.ssb, SSB_ENUM_BASE,
                                      bcm47xx_get_invariants);
        if (err)
                panic("Failed to initialize SSB bus (err %d)", err);
@@ -137,7 +136,7 @@ static void __init bcm47xx_register_ssb(void)
                if (strstr(buf, "console=ttyS1")) {
                        struct ssb_serial_port port;
 
-                       printk(KERN_DEBUG "Swapping serial ports!\n");
+                       pr_debug("Swapping serial ports!\n");
                        /* swap serial ports */
                        memcpy(&port, &mcore->serial_ports[0], sizeof(port));
                        memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
@@ -169,7 +168,7 @@ void __init plat_mem_setup(void)
        struct cpuinfo_mips *c = &current_cpu_data;
 
        if ((c->cputype == CPU_74K) || (c->cputype == CPU_1074K)) {
-               printk(KERN_INFO "bcm47xx: using bcma bus\n");
+               pr_info("Using bcma bus\n");
 #ifdef CONFIG_BCM47XX_BCMA
                bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
                bcm47xx_sprom_register_fallbacks();
@@ -180,7 +179,7 @@ void __init plat_mem_setup(void)
 #endif
 #endif
        } else {
-               printk(KERN_INFO "bcm47xx: using ssb bus\n");
+               pr_info("Using ssb bus\n");
 #ifdef CONFIG_BCM47XX_SSB
                bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
                bcm47xx_sprom_register_fallbacks();
index 2eff7fe..68ebf23 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 #include <bcm47xx.h>
-#include <bcm47xx_nvram.h>
 #include <linux/if_ether.h>
 #include <linux/etherdevice.h>
 
@@ -181,94 +180,245 @@ static void nvram_read_alpha2(const char *prefix, const char *name,
        memcpy(val, buf, 2);
 }
 
+/* This is one-function-only macro, it uses local "sprom" variable! */
+#define ENTRY(_revmask, _type, _prefix, _name, _val, _allset, _fallback) \
+       if (_revmask & BIT(sprom->revision)) \
+               nvram_read_ ## _type(_prefix, NULL, _name, &sprom->_val, \
+                                    _allset, _fallback)
+/*
+ * Special version of filling function that can be safely called for any SPROM
+ * revision. For every NVRAM to SPROM mapping it contains bitmask of revisions
+ * for which the mapping is valid.
+ * It obviously requires some hexadecimal/bitmasks knowledge, but allows
+ * writing cleaner code (easy revisions handling).
+ * Note that while SPROM revision 0 was never used, we still keep BIT(0)
+ * reserved for it, just to keep numbering sane.
+ */
+static void bcm47xx_sprom_fill_auto(struct ssb_sprom *sprom,
+                                   const char *prefix, bool fallback)
+{
+       const char *pre = prefix;
+       bool fb = fallback;
+
+       ENTRY(0xfffffffe, u16, pre, "boardrev", board_rev, 0, true);
+       ENTRY(0x00000002, u16, pre, "boardflags", boardflags_lo, 0, fb);
+       ENTRY(0xfffffffc, u16, pre, "boardtype", board_type, 0, true);
+       ENTRY(0xfffffffe, u16, pre, "boardnum", board_num, 0, fb);
+       ENTRY(0x00000002, u8, pre, "cc", country_code, 0, fb);
+       ENTRY(0xfffffff8, u8, pre, "regrev", regrev, 0, fb);
+
+       ENTRY(0xfffffffe, u8, pre, "ledbh0", gpio0, 0xff, fb);
+       ENTRY(0xfffffffe, u8, pre, "ledbh1", gpio1, 0xff, fb);
+       ENTRY(0xfffffffe, u8, pre, "ledbh2", gpio2, 0xff, fb);
+       ENTRY(0xfffffffe, u8, pre, "ledbh3", gpio3, 0xff, fb);
+
+       ENTRY(0x0000070e, u16, pre, "pa0b0", pa0b0, 0, fb);
+       ENTRY(0x0000070e, u16, pre, "pa0b1", pa0b1, 0, fb);
+       ENTRY(0x0000070e, u16, pre, "pa0b2", pa0b2, 0, fb);
+       ENTRY(0x0000070e, u8, pre, "pa0itssit", itssi_bg, 0, fb);
+       ENTRY(0x0000070e, u8, pre, "pa0maxpwr", maxpwr_bg, 0, fb);
+
+       ENTRY(0x0000070c, u8, pre, "opo", opo, 0, fb);
+       ENTRY(0xfffffffe, u8, pre, "aa2g", ant_available_bg, 0, fb);
+       ENTRY(0xfffffffe, u8, pre, "aa5g", ant_available_a, 0, fb);
+       ENTRY(0x000007fe, s8, pre, "ag0", antenna_gain.a0, 0, fb);
+       ENTRY(0x000007fe, s8, pre, "ag1", antenna_gain.a1, 0, fb);
+       ENTRY(0x000007f0, s8, pre, "ag2", antenna_gain.a2, 0, fb);
+       ENTRY(0x000007f0, s8, pre, "ag3", antenna_gain.a3, 0, fb);
+
+       ENTRY(0x0000070e, u16, pre, "pa1b0", pa1b0, 0, fb);
+       ENTRY(0x0000070e, u16, pre, "pa1b1", pa1b1, 0, fb);
+       ENTRY(0x0000070e, u16, pre, "pa1b2", pa1b2, 0, fb);
+       ENTRY(0x0000070c, u16, pre, "pa1lob0", pa1lob0, 0, fb);
+       ENTRY(0x0000070c, u16, pre, "pa1lob1", pa1lob1, 0, fb);
+       ENTRY(0x0000070c, u16, pre, "pa1lob2", pa1lob2, 0, fb);
+       ENTRY(0x0000070c, u16, pre, "pa1hib0", pa1hib0, 0, fb);
+       ENTRY(0x0000070c, u16, pre, "pa1hib1", pa1hib1, 0, fb);
+       ENTRY(0x0000070c, u16, pre, "pa1hib2", pa1hib2, 0, fb);
+       ENTRY(0x0000070e, u8, pre, "pa1itssit", itssi_a, 0, fb);
+       ENTRY(0x0000070e, u8, pre, "pa1maxpwr", maxpwr_a, 0, fb);
+       ENTRY(0x0000070c, u8, pre, "pa1lomaxpwr", maxpwr_al, 0, fb);
+       ENTRY(0x0000070c, u8, pre, "pa1himaxpwr", maxpwr_ah, 0, fb);
+
+       ENTRY(0x00000708, u8, pre, "bxa2g", bxa2g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "rssisav2g", rssisav2g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "rssismc2g", rssismc2g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "rssismf2g", rssismf2g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "bxa5g", bxa5g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "rssisav5g", rssisav5g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "rssismc5g", rssismc5g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "rssismf5g", rssismf5g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "tri2g", tri2g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "tri5g", tri5g, 0, fb);
+       ENTRY(0x00000708, u8, pre, "tri5gl", tri5gl, 0, fb);
+       ENTRY(0x00000708, u8, pre, "tri5gh", tri5gh, 0, fb);
+       ENTRY(0x00000708, s8, pre, "rxpo2g", rxpo2g, 0, fb);
+       ENTRY(0x00000708, s8, pre, "rxpo5g", rxpo5g, 0, fb);
+       ENTRY(0xfffffff0, u8, pre, "txchain", txchain, 0xf, fb);
+       ENTRY(0xfffffff0, u8, pre, "rxchain", rxchain, 0xf, fb);
+       ENTRY(0xfffffff0, u8, pre, "antswitch", antswitch, 0xff, fb);
+       ENTRY(0x00000700, u8, pre, "tssipos2g", fem.ghz2.tssipos, 0, fb);
+       ENTRY(0x00000700, u8, pre, "extpagain2g", fem.ghz2.extpa_gain, 0, fb);
+       ENTRY(0x00000700, u8, pre, "pdetrange2g", fem.ghz2.pdet_range, 0, fb);
+       ENTRY(0x00000700, u8, pre, "triso2g", fem.ghz2.tr_iso, 0, fb);
+       ENTRY(0x00000700, u8, pre, "antswctl2g", fem.ghz2.antswlut, 0, fb);
+       ENTRY(0x00000700, u8, pre, "tssipos5g", fem.ghz5.tssipos, 0, fb);
+       ENTRY(0x00000700, u8, pre, "extpagain5g", fem.ghz5.extpa_gain, 0, fb);
+       ENTRY(0x00000700, u8, pre, "pdetrange5g", fem.ghz5.pdet_range, 0, fb);
+       ENTRY(0x00000700, u8, pre, "triso5g", fem.ghz5.tr_iso, 0, fb);
+       ENTRY(0x00000700, u8, pre, "antswctl5g", fem.ghz5.antswlut, 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid2ga0", txpid2g[0], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid2ga1", txpid2g[1], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid2ga2", txpid2g[2], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid2ga3", txpid2g[3], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5ga0", txpid5g[0], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5ga1", txpid5g[1], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5ga2", txpid5g[2], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5ga3", txpid5g[3], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5gla0", txpid5gl[0], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5gla1", txpid5gl[1], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5gla2", txpid5gl[2], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5gla3", txpid5gl[3], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5gha0", txpid5gh[0], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5gha1", txpid5gh[1], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5gha2", txpid5gh[2], 0, fb);
+       ENTRY(0x000000f0, u8, pre, "txpid5gha3", txpid5gh[3], 0, fb);
+
+       ENTRY(0xffffff00, u8, pre, "tempthresh", tempthresh, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "tempoffset", tempoffset, 0, fb);
+       ENTRY(0xffffff00, u16, pre, "rawtempsense", rawtempsense, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "measpower", measpower, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "tempsense_slope", tempsense_slope, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "tempcorrx", tempcorrx, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "tempsense_option", tempsense_option, 0, fb);
+       ENTRY(0x00000700, u8, pre, "freqoffset_corr", freqoffset_corr, 0, fb);
+       ENTRY(0x00000700, u8, pre, "iqcal_swp_dis", iqcal_swp_dis, 0, fb);
+       ENTRY(0x00000700, u8, pre, "hw_iqcal_en", hw_iqcal_en, 0, fb);
+       ENTRY(0x00000700, u8, pre, "elna2g", elna2g, 0, fb);
+       ENTRY(0x00000700, u8, pre, "elna5g", elna5g, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "phycal_tempdelta", phycal_tempdelta, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "temps_period", temps_period, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "temps_hysteresis", temps_hysteresis, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "measpower1", measpower1, 0, fb);
+       ENTRY(0xffffff00, u8, pre, "measpower2", measpower2, 0, fb);
+
+       ENTRY(0x000001f0, u16, pre, "cck2gpo", cck2gpo, 0, fb);
+       ENTRY(0x000001f0, u32, pre, "ofdm2gpo", ofdm2gpo, 0, fb);
+       ENTRY(0x000001f0, u32, pre, "ofdm5gpo", ofdm5gpo, 0, fb);
+       ENTRY(0x000001f0, u32, pre, "ofdm5glpo", ofdm5glpo, 0, fb);
+       ENTRY(0x000001f0, u32, pre, "ofdm5ghpo", ofdm5ghpo, 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs2gpo0", mcs2gpo[0], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs2gpo1", mcs2gpo[1], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs2gpo2", mcs2gpo[2], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs2gpo3", mcs2gpo[3], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs2gpo4", mcs2gpo[4], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs2gpo5", mcs2gpo[5], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs2gpo6", mcs2gpo[6], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs2gpo7", mcs2gpo[7], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5gpo0", mcs5gpo[0], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5gpo1", mcs5gpo[1], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5gpo2", mcs5gpo[2], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5gpo3", mcs5gpo[3], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5gpo4", mcs5gpo[4], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5gpo5", mcs5gpo[5], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5gpo6", mcs5gpo[6], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5gpo7", mcs5gpo[7], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5glpo0", mcs5glpo[0], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5glpo1", mcs5glpo[1], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5glpo2", mcs5glpo[2], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5glpo3", mcs5glpo[3], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5glpo4", mcs5glpo[4], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5glpo5", mcs5glpo[5], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5glpo6", mcs5glpo[6], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5glpo7", mcs5glpo[7], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5ghpo0", mcs5ghpo[0], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5ghpo1", mcs5ghpo[1], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5ghpo2", mcs5ghpo[2], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5ghpo3", mcs5ghpo[3], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5ghpo4", mcs5ghpo[4], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5ghpo5", mcs5ghpo[5], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5ghpo6", mcs5ghpo[6], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "mcs5ghpo7", mcs5ghpo[7], 0, fb);
+       ENTRY(0x000001f0, u16, pre, "cddpo", cddpo, 0, fb);
+       ENTRY(0x000001f0, u16, pre, "stbcpo", stbcpo, 0, fb);
+       ENTRY(0x000001f0, u16, pre, "bw40po", bw40po, 0, fb);
+       ENTRY(0x000001f0, u16, pre, "bwduppo", bwduppo, 0, fb);
+
+       ENTRY(0xfffffe00, u16, pre, "cckbw202gpo", cckbw202gpo, 0, fb);
+       ENTRY(0xfffffe00, u16, pre, "cckbw20ul2gpo", cckbw20ul2gpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "legofdmbw202gpo", legofdmbw202gpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "legofdmbw20ul2gpo", legofdmbw20ul2gpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "legofdmbw205glpo", legofdmbw205glpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "legofdmbw20ul5glpo", legofdmbw20ul5glpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "legofdmbw205gmpo", legofdmbw205gmpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "legofdmbw20ul5gmpo", legofdmbw20ul5gmpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "legofdmbw205ghpo", legofdmbw205ghpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "legofdmbw20ul5ghpo", legofdmbw20ul5ghpo, 0, fb);
+       ENTRY(0xfffffe00, u32, pre, "mcsbw202gpo", mcsbw202gpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "mcsbw20ul2gpo", mcsbw20ul2gpo, 0, fb);
+       ENTRY(0xfffffe00, u32, pre, "mcsbw402gpo", mcsbw402gpo, 0, fb);
+       ENTRY(0xfffffe00, u32, pre, "mcsbw205glpo", mcsbw205glpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "mcsbw20ul5glpo", mcsbw20ul5glpo, 0, fb);
+       ENTRY(0xfffffe00, u32, pre, "mcsbw405glpo", mcsbw405glpo, 0, fb);
+       ENTRY(0xfffffe00, u32, pre, "mcsbw205gmpo", mcsbw205gmpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "mcsbw20ul5gmpo", mcsbw20ul5gmpo, 0, fb);
+       ENTRY(0xfffffe00, u32, pre, "mcsbw405gmpo", mcsbw405gmpo, 0, fb);
+       ENTRY(0xfffffe00, u32, pre, "mcsbw205ghpo", mcsbw205ghpo, 0, fb);
+       ENTRY(0x00000600, u32, pre, "mcsbw20ul5ghpo", mcsbw20ul5ghpo, 0, fb);
+       ENTRY(0xfffffe00, u32, pre, "mcsbw405ghpo", mcsbw405ghpo, 0, fb);
+       ENTRY(0x00000600, u16, pre, "mcs32po", mcs32po, 0, fb);
+       ENTRY(0x00000600, u16, pre, "legofdm40duppo", legofdm40duppo, 0, fb);
+       ENTRY(0x00000700, u8, pre, "pcieingress_war", pcieingress_war, 0, fb);
+
+       /* TODO: rev 11 support */
+       ENTRY(0x00000700, u8, pre, "rxgainerr2ga0", rxgainerr2ga[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr2ga1", rxgainerr2ga[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr2ga2", rxgainerr2ga[2], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gla0", rxgainerr5gla[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gla1", rxgainerr5gla[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gla2", rxgainerr5gla[2], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gma0", rxgainerr5gma[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gma1", rxgainerr5gma[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gma2", rxgainerr5gma[2], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gha0", rxgainerr5gha[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gha1", rxgainerr5gha[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gha2", rxgainerr5gha[2], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gua0", rxgainerr5gua[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gua1", rxgainerr5gua[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "rxgainerr5gua2", rxgainerr5gua[2], 0, fb);
+
+       ENTRY(0xfffffe00, u8, pre, "sar2g", sar2g, 0, fb);
+       ENTRY(0xfffffe00, u8, pre, "sar5g", sar5g, 0, fb);
+
+       /* TODO: rev 11 support */
+       ENTRY(0x00000700, u8, pre, "noiselvl2ga0", noiselvl2ga[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl2ga1", noiselvl2ga[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl2ga2", noiselvl2ga[2], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gla0", noiselvl5gla[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gla1", noiselvl5gla[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gla2", noiselvl5gla[2], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gma0", noiselvl5gma[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gma1", noiselvl5gma[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gma2", noiselvl5gma[2], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gha0", noiselvl5gha[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gha1", noiselvl5gha[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gha2", noiselvl5gha[2], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gua0", noiselvl5gua[0], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gua1", noiselvl5gua[1], 0, fb);
+       ENTRY(0x00000700, u8, pre, "noiselvl5gua2", noiselvl5gua[2], 0, fb);
+}
+#undef ENTRY /* It's specififc, uses local variable, don't use it (again). */
+
 static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
                                        const char *prefix, bool fallback)
 {
        nvram_read_u16(prefix, NULL, "devid", &sprom->dev_id, 0, fallback);
-       nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff, fallback);
-       nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff, fallback);
-       nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff, fallback);
-       nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff, fallback);
-       nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0,
-                     fallback);
-       nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0,
-                     fallback);
-       nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0,
-                     fallback);
        nvram_read_alpha2(prefix, "ccode", sprom->alpha2, fallback);
 }
 
-static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom,
-                                     const char *prefix, bool fallback)
-{
-       nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0, fallback);
-       nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0, fallback);
-       nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0,
-                     fallback);
-       nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0, fallback);
-       nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0, fallback);
-       nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0, fallback);
-}
-
-static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix,
-                                 bool fallback)
-{
-       nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0,
-                      fallback);
-       nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0, fallback);
-}
-
-static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom,
-                                    const char *prefix, bool fallback)
-{
-       nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0, fallback);
-       nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0, fallback);
-       nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0,
-                     fallback);
-}
-
-static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix,
-                                   bool fallback)
-{
-       nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0, fallback);
-       nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0, fallback);
-       nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0, fallback);
-       nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0, fallback);
-       nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0, fallback);
-       nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0, fallback);
-       nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0, fallback);
-       nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0, fallback);
-}
-
 static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix,
                                  bool fallback)
 {
-       nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback);
        nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
                         &sprom->leddc_off_time, fallback);
 }
@@ -276,309 +426,10 @@ static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix,
 static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom,
                                     const char *prefix, bool fallback)
 {
-       nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback);
-       nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0,
-                     fallback);
-       nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf, fallback);
-       nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf, fallback);
-       nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff,
-                     fallback);
        nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
                         &sprom->leddc_off_time, fallback);
 }
 
-static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix,
-                                   bool fallback)
-{
-       nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0, fallback);
-       nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0, fallback);
-       nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0, fallback);
-       nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0, fallback);
-       nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0,
-                      fallback);
-}
-
-static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix,
-                                  bool fallback)
-{
-       nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0,
-                     fallback);
-}
-
-static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix,
-                                  bool fallback)
-{
-       nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "extpagain2g",
-                     &sprom->fem.ghz2.extpa_gain, 0, fallback);
-       nvram_read_u8(prefix, NULL, "pdetrange2g",
-                     &sprom->fem.ghz2.pdet_range, 0, fallback);
-       nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "extpagain5g",
-                     &sprom->fem.ghz5.extpa_gain, 0, fallback);
-       nvram_read_u8(prefix, NULL, "pdetrange5g",
-                     &sprom->fem.ghz5.pdet_range, 0, fallback);
-       nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0,
-                     fallback);
-       nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0,
-                      fallback);
-       nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "tempsense_slope",
-                     &sprom->tempsense_slope, 0, fallback);
-       nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0,
-                      fallback);
-       nvram_read_u8(prefix, NULL, "tempsense_option",
-                     &sprom->tempsense_option, 0, fallback);
-       nvram_read_u8(prefix, NULL, "freqoffset_corr",
-                     &sprom->freqoffset_corr, 0, fallback);
-       nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0, fallback);
-       nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0, fallback);
-       nvram_read_u8(prefix, NULL, "phycal_tempdelta",
-                     &sprom->phycal_tempdelta, 0, fallback);
-       nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "temps_hysteresis",
-                     &sprom->temps_hysteresis, 0, fallback);
-       nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr2ga0",
-                     &sprom->rxgainerr2ga[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr2ga1",
-                     &sprom->rxgainerr2ga[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr2ga2",
-                     &sprom->rxgainerr2ga[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gla0",
-                     &sprom->rxgainerr5gla[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gla1",
-                     &sprom->rxgainerr5gla[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gla2",
-                     &sprom->rxgainerr5gla[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gma0",
-                     &sprom->rxgainerr5gma[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gma1",
-                     &sprom->rxgainerr5gma[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gma2",
-                     &sprom->rxgainerr5gma[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gha0",
-                     &sprom->rxgainerr5gha[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gha1",
-                     &sprom->rxgainerr5gha[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gha2",
-                     &sprom->rxgainerr5gha[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gua0",
-                     &sprom->rxgainerr5gua[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gua1",
-                     &sprom->rxgainerr5gua[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "rxgainerr5gua2",
-                     &sprom->rxgainerr5gua[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0,
-                     fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gla0",
-                     &sprom->noiselvl5gla[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gla1",
-                     &sprom->noiselvl5gla[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gla2",
-                     &sprom->noiselvl5gla[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gma0",
-                     &sprom->noiselvl5gma[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gma1",
-                     &sprom->noiselvl5gma[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gma2",
-                     &sprom->noiselvl5gma[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gha0",
-                     &sprom->noiselvl5gha[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gha1",
-                     &sprom->noiselvl5gha[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gha2",
-                     &sprom->noiselvl5gha[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gua0",
-                     &sprom->noiselvl5gua[0], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gua1",
-                     &sprom->noiselvl5gua[1], 0, fallback);
-       nvram_read_u8(prefix, NULL, "noiselvl5gua2",
-                     &sprom->noiselvl5gua[2], 0, fallback);
-       nvram_read_u8(prefix, NULL, "pcieingress_war",
-                     &sprom->pcieingress_war, 0, fallback);
-}
-
-static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix,
-                                 bool fallback)
-{
-       nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "legofdmbw202gpo",
-                      &sprom->legofdmbw202gpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo",
-                      &sprom->legofdmbw20ul2gpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "legofdmbw205glpo",
-                      &sprom->legofdmbw205glpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo",
-                      &sprom->legofdmbw20ul5glpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "legofdmbw205gmpo",
-                      &sprom->legofdmbw205gmpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo",
-                      &sprom->legofdmbw20ul5gmpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "legofdmbw205ghpo",
-                      &sprom->legofdmbw205ghpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo",
-                      &sprom->legofdmbw20ul5ghpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo",
-                      &sprom->mcsbw20ul5glpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo",
-                      &sprom->mcsbw20ul5gmpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0,
-                      fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo",
-                      &sprom->mcsbw20ul5ghpo, 0, fallback);
-       nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0, fallback);
-       nvram_read_u16(prefix, NULL, "legofdm40duppo",
-                      &sprom->legofdm40duppo, 0, fallback);
-       nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0, fallback);
-       nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0, fallback);
-}
-
 static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
                                          const char *prefix, bool fallback)
 {
@@ -715,10 +566,6 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
 static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,
                                    bool fallback)
 {
-       nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0, true);
-       nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0,
-                      fallback);
-       nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0, true);
        nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
                         &sprom->boardflags_hi, fallback);
        nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo,
@@ -736,58 +583,39 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
        switch (sprom->revision) {
        case 1:
                bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r1(sprom, prefix, fallback);
                break;
        case 2:
                bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
                break;
        case 3:
                bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
                bcm47xx_fill_sprom_r3(sprom, prefix, fallback);
                break;
        case 4:
        case 5:
                bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
                bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r458(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r45(sprom, prefix, fallback);
                bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
                bcm47xx_fill_sprom_path_r45(sprom, prefix, fallback);
                break;
        case 8:
                bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
                bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r458(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r89(sprom, prefix, fallback);
                bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
                break;
        case 9:
                bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
                bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r89(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r9(sprom, prefix, fallback);
                bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
                break;
        default:
-               pr_warn("Unsupported SPROM revision %d detected. Will extract"
-                       " v1\n", sprom->revision);
+               pr_warn("Unsupported SPROM revision %d detected. Will extract v1\n",
+                       sprom->revision);
                sprom->revision = 1;
                bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r1(sprom, prefix, fallback);
        }
+
+       bcm47xx_sprom_fill_auto(sprom, prefix, fallback);
 }
 
 #ifdef CONFIG_BCM47XX_SSB
@@ -829,13 +657,45 @@ static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
                bcm47xx_fill_sprom(out, prefix, false);
                return 0;
        } else {
-               pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
+               pr_warn("Unable to fill SPROM for given bustype.\n");
                return -EINVAL;
        }
 }
 #endif
 
 #if defined(CONFIG_BCM47XX_BCMA)
+/*
+ * Having many NVRAM entries for PCI devices led to repeating prefixes like
+ * pci/1/1/ all the time and wasting flash space. So at some point Broadcom
+ * decided to introduce prefixes like 0: 1: 2: etc.
+ * If we find e.g. devpath0=pci/2/1 or devpath0=pci/2/1/ we should use 0:
+ * instead of pci/2/1/.
+ */
+static void bcm47xx_sprom_apply_prefix_alias(char *prefix, size_t prefix_size)
+{
+       size_t prefix_len = strlen(prefix);
+       size_t short_len = prefix_len - 1;
+       char nvram_var[10];
+       char buf[20];
+       int i;
+
+       /* Passed prefix has to end with a slash */
+       if (prefix_len <= 0 || prefix[prefix_len - 1] != '/')
+               return;
+
+       for (i = 0; i < 3; i++) {
+               if (snprintf(nvram_var, sizeof(nvram_var), "devpath%d", i) <= 0)
+                       continue;
+               if (bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf)) < 0)
+                       continue;
+               if (!strcmp(buf, prefix) ||
+                   (short_len && strlen(buf) == short_len && !strncmp(buf, prefix, short_len))) {
+                       snprintf(prefix, prefix_size, "%d:", i);
+                       return;
+               }
+       }
+}
+
 static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
 {
        char prefix[10];
@@ -847,6 +707,7 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
                snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
                         bus->host_pci->bus->number + 1,
                         PCI_SLOT(bus->host_pci->devfn));
+               bcm47xx_sprom_apply_prefix_alias(prefix, sizeof(prefix));
                bcm47xx_fill_sprom(out, prefix, false);
                return 0;
        case BCMA_HOSTTYPE_SOC:
@@ -861,7 +722,7 @@ static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
                }
                return 0;
        default:
-               pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
+               pr_warn("Unable to fill SPROM for given bustype.\n");
                return -EINVAL;
        }
 }
index 2c85d92..74224cf 100644 (file)
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 #include <linux/init.h>
 #include <linux/ssb/ssb.h>
 #include <asm/time.h>
 #include <bcm47xx.h>
-#include <bcm47xx_nvram.h>
 #include <bcm47xx_board.h>
 
 void __init plat_time_init(void)
index e1f27d6..7019e29 100644 (file)
@@ -17,7 +17,6 @@
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_regs.h>
-#include <bcm63xx_gpio.h>
 
 void __init prom_init(void)
 {
@@ -53,9 +52,6 @@ void __init prom_init(void)
        reg &= ~mask;
        bcm_perf_writel(reg, PERF_CKCTL_REG);
 
-       /* register gpiochip */
-       bcm63xx_gpio_init();
-
        /* do low level board init */
        board_prom_init();
 
index 6660c7d..240fb4f 100644 (file)
@@ -20,6 +20,7 @@
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
+#include <bcm63xx_gpio.h>
 
 void bcm63xx_machine_halt(void)
 {
@@ -160,6 +161,9 @@ void __init plat_mem_setup(void)
 
 int __init bcm63xx_register_devices(void)
 {
+       /* register gpiochip */
+       bcm63xx_gpio_init();
+
        return board_register_devices();
 }
 
diff --git a/arch/mips/bmips/Kconfig b/arch/mips/bmips/Kconfig
new file mode 100644 (file)
index 0000000..f35c84c
--- /dev/null
@@ -0,0 +1,62 @@
+if BMIPS_GENERIC
+
+choice
+       prompt "Built-in device tree"
+       help
+         Legacy bootloaders do not pass a DTB pointer to the kernel, so
+         if a "wrapper" is not being used, the kernel will need to include
+         a device tree that matches the target board.
+
+         The builtin DTB will only be used if the firmware does not supply
+         a valid DTB.
+
+config DT_NONE
+       bool "None"
+
+config DT_BCM93384WVG
+       bool "BCM93384WVG Zephyr CPU"
+       select BUILTIN_DTB
+
+config DT_BCM93384WVG_VIPER
+       bool "BCM93384WVG Viper CPU (EXPERIMENTAL)"
+       select BUILTIN_DTB
+
+config DT_BCM96368MVWG
+       bool "BCM96368MVWG"
+       select BUILTIN_DTB
+
+config DT_BCM9EJTAGPRB
+       bool "BCM9EJTAGPRB"
+       select BUILTIN_DTB
+
+config DT_BCM97125CBMB
+       bool "BCM97125CBMB"
+       select BUILTIN_DTB
+
+config DT_BCM97346DBSMB
+       bool "BCM97346DBSMB"
+       select BUILTIN_DTB
+
+config DT_BCM97358SVMB
+       bool "BCM97358SVMB"
+       select BUILTIN_DTB
+
+config DT_BCM97360SVMB
+       bool "BCM97360SVMB"
+       select BUILTIN_DTB
+
+config DT_BCM97362SVMB
+       bool "BCM97362SVMB"
+       select BUILTIN_DTB
+
+config DT_BCM97420C
+       bool "BCM97420C"
+       select BUILTIN_DTB
+
+config DT_BCM97425SVMB
+       bool "BCM97425SVMB"
+       select BUILTIN_DTB
+
+endchoice
+
+endif
diff --git a/arch/mips/bmips/Platform b/arch/mips/bmips/Platform
new file mode 100644 (file)
index 0000000..5f127fd
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Broadcom Generic BMIPS kernel
+#
+platform-$(CONFIG_BMIPS_GENERIC)       += bmips/
+cflags-$(CONFIG_BMIPS_GENERIC)         +=                              \
+               -I$(srctree)/arch/mips/include/asm/mach-bmips/
+load-$(CONFIG_BMIPS_GENERIC)           := 0xffffffff80010000
diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c
new file mode 100644 (file)
index 0000000..04790f4
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
+ */
+
+#define pr_fmt(fmt)            "bmips-dma: " fmt
+
+#include <linux/device.h>
+#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <dma-coherence.h>
+
+/*
+ * BCM338x has configurable address translation windows which allow the
+ * peripherals' DMA addresses to be different from the Zephyr-visible
+ * physical addresses.  e.g. usb_dma_addr = zephyr_pa ^ 0x08000000
+ *
+ * If the "brcm,ubus" node has a "dma-ranges" property we will enable this
+ * translation globally using the provided information.  This implements a
+ * very limited subset of "dma-ranges" support and it will probably be
+ * replaced by a more generic version later.
+ */
+
+struct bmips_dma_range {
+       u32                     child_addr;
+       u32                     parent_addr;
+       u32                     size;
+};
+
+static struct bmips_dma_range *bmips_dma_ranges;
+
+#define FLUSH_RAC              0x100
+
+static dma_addr_t bmips_phys_to_dma(struct device *dev, phys_addr_t pa)
+{
+       struct bmips_dma_range *r;
+
+       for (r = bmips_dma_ranges; r && r->size; r++) {
+               if (pa >= r->child_addr &&
+                   pa < (r->child_addr + r->size))
+                       return pa - r->child_addr + r->parent_addr;
+       }
+       return pa;
+}
+
+dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+{
+       return bmips_phys_to_dma(dev, virt_to_phys(addr));
+}
+
+dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+{
+       return bmips_phys_to_dma(dev, page_to_phys(page));
+}
+
+unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr)
+{
+       struct bmips_dma_range *r;
+
+       for (r = bmips_dma_ranges; r && r->size; r++) {
+               if (dma_addr >= r->parent_addr &&
+                   dma_addr < (r->parent_addr + r->size))
+                       return dma_addr - r->parent_addr + r->child_addr;
+       }
+       return dma_addr;
+}
+
+static int __init bmips_init_dma_ranges(void)
+{
+       struct device_node *np =
+               of_find_compatible_node(NULL, NULL, "brcm,ubus");
+       const __be32 *data;
+       struct bmips_dma_range *r;
+       int len;
+
+       if (!np)
+               return 0;
+
+       data = of_get_property(np, "dma-ranges", &len);
+       if (!data)
+               goto out_good;
+
+       len /= sizeof(*data) * 3;
+       if (!len)
+               goto out_bad;
+
+       /* add a dummy (zero) entry at the end as a sentinel */
+       bmips_dma_ranges = kzalloc(sizeof(struct bmips_dma_range) * (len + 1),
+                                  GFP_KERNEL);
+       if (!bmips_dma_ranges)
+               goto out_bad;
+
+       for (r = bmips_dma_ranges; len; len--, r++) {
+               r->child_addr = be32_to_cpup(data++);
+               r->parent_addr = be32_to_cpup(data++);
+               r->size = be32_to_cpup(data++);
+       }
+
+out_good:
+       of_node_put(np);
+       return 0;
+
+out_bad:
+       pr_err("error parsing dma-ranges property\n");
+       of_node_put(np);
+       return -EINVAL;
+}
+arch_initcall(bmips_init_dma_ranges);
diff --git a/arch/mips/bmips/irq.c b/arch/mips/bmips/irq.c
new file mode 100644 (file)
index 0000000..14552e5
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Copyright (C) 2014 Broadcom Corporation
+ * Author: Kevin Cernekee <cernekee@gmail.com>
+ */
+
+#include <linux/of.h>
+#include <linux/irqchip.h>
+
+#include <asm/bmips.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
+#include <asm/time.h>
+
+unsigned int get_c0_compare_int(void)
+{
+       return CP0_LEGACY_COMPARE_IRQ;
+}
+
+void __init arch_init_irq(void)
+{
+       struct device_node *dn;
+
+       /* Only the STB (bcm7038) controller supports SMP IRQ affinity */
+       dn = of_find_compatible_node(NULL, NULL, "brcm,bcm7038-l1-intc");
+       if (dn)
+               of_node_put(dn);
+       else
+               bmips_tp1_irqs = 0;
+
+       irqchip_init();
+}
+
+OF_DECLARE_2(irqchip, mips_cpu_intc, "mti,cpu-interrupt-controller",
+            mips_cpu_irq_of_init);
diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c
new file mode 100644 (file)
index 0000000..fae800e
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/bootmem.h>
+#include <linux/clk-provider.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/smp.h>
+#include <asm/addrspace.h>
+#include <asm/bmips.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu-type.h>
+#include <asm/mipsregs.h>
+#include <asm/prom.h>
+#include <asm/smp-ops.h>
+#include <asm/time.h>
+#include <asm/traps.h>
+
+#define RELO_NORMAL_VEC                BIT(18)
+
+#define REG_BCM6328_OTP                ((void __iomem *)CKSEG1ADDR(0x1000062c))
+#define BCM6328_TP1_DISABLED   BIT(9)
+
+static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000;
+
+struct bmips_quirk {
+       const char              *compatible;
+       void                    (*quirk_fn)(void);
+};
+
+static void kbase_setup(void)
+{
+       __raw_writel(kbase | RELO_NORMAL_VEC,
+                    BMIPS_GET_CBR() + BMIPS_RELO_VECTOR_CONTROL_1);
+       ebase = kbase;
+}
+
+static void bcm3384_viper_quirks(void)
+{
+       /*
+        * Some experimental CM boxes are set up to let CM own the Viper TP0
+        * and let Linux own TP1.  This requires moving the kernel
+        * load address to a non-conflicting region (e.g. via
+        * CONFIG_PHYSICAL_START) and supplying an alternate DTB.
+        * If we detect this condition, we need to move the MIPS exception
+        * vectors up to an area that we own.
+        *
+        * This is distinct from the OTHER special case mentioned in
+        * smp-bmips.c (boot on TP1, but enable SMP, then TP0 becomes our
+        * logical CPU#1).  For the Viper TP1 case, SMP is off limits.
+        *
+        * Also note that many BMIPS435x CPUs do not have a
+        * BMIPS_RELO_VECTOR_CONTROL_1 register, so it isn't safe to just
+        * write VMLINUX_LOAD_ADDRESS into that register on every SoC.
+        */
+       board_ebase_setup = &kbase_setup;
+       bmips_smp_enabled = 0;
+}
+
+static void bcm63xx_fixup_cpu1(void)
+{
+       /*
+        * The bootloader has set up the CPU1 reset vector at
+        * 0xa000_0200.
+        * This conflicts with the special interrupt vector (IV).
+        * The bootloader has also set up CPU1 to respond to the wrong
+        * IPI interrupt.
+        * Here we will start up CPU1 in the background and ask it to
+        * reconfigure itself then go back to sleep.
+        */
+       memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
+       __sync();
+       set_c0_cause(C_SW0);
+       cpumask_set_cpu(1, &bmips_booted_mask);
+}
+
+static void bcm6328_quirks(void)
+{
+       /* Check CPU1 status in OTP (it is usually disabled) */
+       if (__raw_readl(REG_BCM6328_OTP) & BCM6328_TP1_DISABLED)
+               bmips_smp_enabled = 0;
+       else
+               bcm63xx_fixup_cpu1();
+}
+
+static void bcm6368_quirks(void)
+{
+       bcm63xx_fixup_cpu1();
+}
+
+static const struct bmips_quirk bmips_quirk_list[] = {
+       { "brcm,bcm3384-viper",         &bcm3384_viper_quirks           },
+       { "brcm,bcm33843-viper",        &bcm3384_viper_quirks           },
+       { "brcm,bcm6328",               &bcm6328_quirks                 },
+       { "brcm,bcm6368",               &bcm6368_quirks                 },
+       { },
+};
+
+void __init prom_init(void)
+{
+       register_bmips_smp_ops();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+const char *get_system_type(void)
+{
+       return "Generic BMIPS kernel";
+}
+
+void __init plat_time_init(void)
+{
+       struct device_node *np;
+       u32 freq;
+
+       np = of_find_node_by_name(NULL, "cpus");
+       if (!np)
+               panic("missing 'cpus' DT node");
+       if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0)
+               panic("missing 'mips-hpt-frequency' property");
+       of_node_put(np);
+
+       mips_hpt_frequency = freq;
+}
+
+void __init plat_mem_setup(void)
+{
+       void *dtb;
+       const struct bmips_quirk *q;
+
+       set_io_port_base(0);
+       ioport_resource.start = 0;
+       ioport_resource.end = ~0;
+
+       /* intended to somewhat resemble ARM; see Documentation/arm/Booting */
+       if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
+               dtb = phys_to_virt(fw_arg2);
+       else if (__dtb_start != __dtb_end)
+               dtb = (void *)__dtb_start;
+       else
+               panic("no dtb found");
+
+       __dt_setup_arch(dtb);
+       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+
+       for (q = bmips_quirk_list; q->quirk_fn; q++) {
+               if (of_flat_dt_is_compatible(of_get_flat_dt_root(),
+                                            q->compatible)) {
+                       q->quirk_fn();
+               }
+       }
+}
+
+void __init device_tree_init(void)
+{
+       struct device_node *np;
+
+       unflatten_and_copy_device_tree();
+
+       /* Disable SMP boot unless both CPUs are listed in DT and !disabled */
+       np = of_find_node_by_name(NULL, "cpus");
+       if (np && of_get_available_child_count(np) <= 1)
+               bmips_smp_enabled = 0;
+       of_node_put(np);
+}
+
+int __init plat_of_setup(void)
+{
+       return __dt_register_buses("simple-bus", NULL);
+}
+
+arch_initcall(plat_of_setup);
+
+static int __init plat_dev_init(void)
+{
+       of_clk_init(NULL);
+       return 0;
+}
+
+device_initcall(plat_dev_init);
index 61af6b6..dc91bde 100644 (file)
@@ -12,6 +12,8 @@
 # Author: Wu Zhangjin <wuzhangjin@gmail.com>
 #
 
+include $(srctree)/arch/mips/Kbuild.platforms
+
 # set the default size of the mallocing area for decompressing
 BOOT_HEAP_SIZE := 0x400000
 
@@ -30,9 +32,10 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
 targets := head.o decompress.o string.o dbg.o uart-16550.o uart-alchemy.o
 
 # decompressor objects (linked with vmlinuz)
-vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o $(obj)/dbg.o
+vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o
 
 ifdef CONFIG_DEBUG_ZBOOT
+vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT)                 += $(obj)/dbg.o
 vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
 vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY)                += $(obj)/uart-alchemy.o
 endif
@@ -66,8 +69,8 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
 # Calculate the load address of the compressed kernel image
 hostprogs-y := calc_vmlinuz_load_addr
 
-ifeq ($(CONFIG_MACH_JZ4740),y)
-VMLINUZ_LOAD_ADDRESS := 0x80600000
+ifneq ($(zload-y),)
+VMLINUZ_LOAD_ADDRESS := $(zload-y)
 else
 VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
                $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
index 31903cf..5483106 100644 (file)
@@ -28,8 +28,13 @@ unsigned long free_mem_end_ptr;
 extern unsigned char __image_begin, __image_end;
 
 /* debug interfaces  */
+#ifdef CONFIG_DEBUG_ZBOOT
 extern void puts(const char *s);
 extern void puthex(unsigned long long val);
+#else
+#define puts(s) do {} while (0)
+#define puthex(val) do {} while (0)
+#endif
 
 void error(char *x)
 {
index 4f49fa4..5d95e4b 100644 (file)
@@ -1,21 +1,12 @@
-dtb-$(CONFIG_BCM3384)                  += bcm93384wvg.dtb
-dtb-$(CONFIG_CAVIUM_OCTEON_SOC)                += octeon_3xxx.dtb octeon_68xx.dtb
-dtb-$(CONFIG_DT_EASY50712)             += easy50712.dtb
-dtb-$(CONFIG_DT_XLP_EVP)               += xlp_evp.dtb
-dtb-$(CONFIG_DT_XLP_SVP)               += xlp_svp.dtb
-dtb-$(CONFIG_DT_XLP_FVP)               += xlp_fvp.dtb
-dtb-$(CONFIG_DT_XLP_GVP)               += xlp_gvp.dtb
-dtb-$(CONFIG_DTB_RT2880_EVAL)          += rt2880_eval.dtb
-dtb-$(CONFIG_DTB_RT305X_EVAL)          += rt3052_eval.dtb
-dtb-$(CONFIG_DTB_RT3883_EVAL)          += rt3883_eval.dtb
-dtb-$(CONFIG_DTB_MT7620A_EVAL)         += mt7620a_eval.dtb
-dtb-$(CONFIG_MIPS_SEAD3)               += sead3.dtb
-
-obj-y          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
-
-targets                += dtbs
-targets                += $(dtb-y)
-
-dtbs: $(addprefix $(obj)/, $(dtb-y))
-
-clean-files    += *.dtb *.dtb.S
+dts-dirs       += brcm
+dts-dirs       += cavium-octeon
+dts-dirs       += lantiq
+dts-dirs       += mti
+dts-dirs       += netlogic
+dts-dirs       += ralink
+
+obj-y          := $(addsuffix /, $(dts-dirs))
+
+always         := $(dtb-y)
+subdir-y       := $(dts-dirs)
+clean-files    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/bcm3384.dtsi b/arch/mips/boot/dts/bcm3384.dtsi
deleted file mode 100644 (file)
index 21b074a..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/ {
-       #address-cells = <1>;
-       #size-cells = <1>;
-       compatible = "brcm,bcm3384", "brcm,bcm33843";
-
-       cpus {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               /* On BMIPS5000 this is 1/8th of the CPU core clock */
-               mips-hpt-frequency = <100000000>;
-
-               cpu@0 {
-                       compatible = "brcm,bmips5000";
-                       device_type = "cpu";
-                       reg = <0>;
-               };
-
-               cpu@1 {
-                       compatible = "brcm,bmips5000";
-                       device_type = "cpu";
-                       reg = <1>;
-               };
-       };
-
-       clocks {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               periph_clk: periph_clk@0 {
-                       compatible = "fixed-clock";
-                       #clock-cells = <0>;
-                       clock-frequency = <54000000>;
-               };
-       };
-
-       aliases {
-               uart0 = &uart0;
-       };
-
-       cpu_intc: cpu_intc@0 {
-               #address-cells = <0>;
-               compatible = "mti,cpu-interrupt-controller";
-
-               interrupt-controller;
-               #interrupt-cells = <1>;
-       };
-
-       periph_intc: periph_intc@14e00038 {
-               compatible = "brcm,bcm3384-intc";
-               reg = <0x14e00038 0x8 0x14e00340 0x8>;
-
-               interrupt-controller;
-               #interrupt-cells = <1>;
-
-               interrupt-parent = <&cpu_intc>;
-               interrupts = <4>;
-       };
-
-       zmips_intc: zmips_intc@104b0060 {
-               compatible = "brcm,bcm3384-intc";
-               reg = <0x104b0060 0x8>;
-
-               interrupt-controller;
-               #interrupt-cells = <1>;
-
-               interrupt-parent = <&periph_intc>;
-               interrupts = <29>;
-       };
-
-       iop_intc: iop_intc@14e00058 {
-               compatible = "brcm,bcm3384-intc";
-               reg = <0x14e00058 0x8>;
-
-               interrupt-controller;
-               #interrupt-cells = <1>;
-
-               interrupt-parent = <&cpu_intc>;
-               interrupts = <6>;
-       };
-
-       uart0: serial@14e00520 {
-               compatible = "brcm,bcm6345-uart";
-               reg = <0x14e00520 0x18>;
-               interrupt-parent = <&periph_intc>;
-               interrupts = <2>;
-               clocks = <&periph_clk>;
-               status = "disabled";
-       };
-
-       ehci0: usb@15400300 {
-               compatible = "brcm,bcm3384-ehci", "generic-ehci";
-               reg = <0x15400300 0x100>;
-               big-endian;
-               interrupt-parent = <&periph_intc>;
-               interrupts = <41>;
-               status = "disabled";
-       };
-
-       ohci0: usb@15400400 {
-               compatible = "brcm,bcm3384-ohci", "generic-ohci";
-               reg = <0x15400400 0x100>;
-               big-endian;
-               no-big-frame-no;
-               interrupt-parent = <&periph_intc>;
-               interrupts = <40>;
-               status = "disabled";
-       };
-};
diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile
new file mode 100644 (file)
index 0000000..1c8353b
--- /dev/null
@@ -0,0 +1,19 @@
+dtb-$(CONFIG_DT_BCM93384WVG)           += bcm93384wvg.dtb
+dtb-$(CONFIG_DT_BCM93384WVG_VIPER)     += bcm93384wvg_viper.dtb
+dtb-$(CONFIG_DT_BCM96368MVWG)          += bcm96368mvwg.dtb
+dtb-$(CONFIG_DT_BCM9EJTAGPRB)          += bcm9ejtagprb.dtb
+dtb-$(CONFIG_DT_BCM97125CBMB)          += bcm97125cbmb.dtb
+dtb-$(CONFIG_DT_BCM97346DBSMB)         += bcm97346dbsmb.dtb
+dtb-$(CONFIG_DT_BCM97358SVMB)          += bcm97358svmb.dtb
+dtb-$(CONFIG_DT_BCM97360SVMB)          += bcm97360svmb.dtb
+dtb-$(CONFIG_DT_BCM97362SVMB)          += bcm97362svmb.dtb
+dtb-$(CONFIG_DT_BCM97420C)             += bcm97420c.dtb
+dtb-$(CONFIG_DT_BCM97425SVMB)          += bcm97425svmb.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/brcm/bcm3384_viper.dtsi b/arch/mips/boot/dts/brcm/bcm3384_viper.dtsi
new file mode 100644 (file)
index 0000000..aa406b4
--- /dev/null
@@ -0,0 +1,108 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm3384-viper", "brcm,bcm33843-viper";
+
+       memory@0 {
+               device_type = "memory";
+
+               /* Typical ranges.  The bootloader should fill these in. */
+               reg = <0x06000000 0x02000000>,
+                     <0x0e000000 0x02000000>;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* 1/2 of the CPU core clock (standard MIPS behavior) */
+               mips-hpt-frequency = <300000000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips4350";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               periph_clk: periph_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <54000000>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       ubus {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "brcm,ubus", "simple-bus";
+               ranges;
+               /* No dma-ranges on Viper. */
+
+               periph_intc: periph_intc@14e00048 {
+                       compatible = "brcm,bcm3380-l2-intc";
+                       reg = <0x14e00048 0x4 0x14e0004c 0x4>,
+                             <0x14e00350 0x4 0x14e00354 0x4>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <4>;
+               };
+
+               cmips_intc: cmips_intc@151f8048 {
+                       compatible = "brcm,bcm3380-l2-intc";
+                       reg = <0x151f8048 0x4 0x151f804c 0x4>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <30>;
+                       brcm,int-map-mask = <0xffffffff>;
+               };
+
+               uart0: serial@14e00520 {
+                       compatible = "brcm,bcm6345-uart";
+                       reg = <0x14e00520 0x18>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <2>;
+                       clocks = <&periph_clk>;
+                       status = "disabled";
+               };
+
+               ehci0: usb@15400300 {
+                       compatible = "brcm,bcm3384-ehci", "generic-ehci";
+                       reg = <0x15400300 0x100>;
+                       big-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <41>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@15400400 {
+                       compatible = "brcm,bcm3384-ohci", "generic-ohci";
+                       reg = <0x15400400 0x100>;
+                       big-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <40>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm3384_zephyr.dtsi b/arch/mips/boot/dts/brcm/bcm3384_zephyr.dtsi
new file mode 100644 (file)
index 0000000..a7bd856
--- /dev/null
@@ -0,0 +1,126 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm3384", "brcm,bcm33843";
+
+       memory@0 {
+               device_type = "memory";
+
+               /* Typical range.  The bootloader should fill this in. */
+               reg = <0x0 0x08000000>;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* On BMIPS5000 this is 1/8th of the CPU core clock */
+               mips-hpt-frequency = <100000000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips5000";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips5000";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               periph_clk: periph_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <54000000>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       ubus {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "brcm,ubus", "simple-bus";
+               ranges;
+               dma-ranges = <0x00000000 0x08000000 0x08000000>,
+                            <0x08000000 0x00000000 0x08000000>;
+
+               periph_intc: periph_intc@14e00038 {
+                       compatible = "brcm,bcm3380-l2-intc";
+                       reg = <0x14e00038 0x4 0x14e0003c 0x4>,
+                             <0x14e00340 0x4 0x14e00344 0x4>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <4>;
+               };
+
+               zmips_intc: zmips_intc@104b0060 {
+                       compatible = "brcm,bcm3380-l2-intc";
+                       reg = <0x104b0060 0x4 0x104b0064 0x4>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <29>;
+                       brcm,int-map-mask = <0xffffffff>;
+               };
+
+               iop_intc: iop_intc@14e00058 {
+                       compatible = "brcm,bcm3380-l2-intc";
+                       reg = <0x14e00058 0x4 0x14e0005c 0x4>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <6>;
+                       brcm,int-map-mask = <0xffffffff>;
+               };
+
+               uart0: serial@14e00520 {
+                       compatible = "brcm,bcm6345-uart";
+                       reg = <0x14e00520 0x18>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <2>;
+                       clocks = <&periph_clk>;
+                       status = "disabled";
+               };
+
+               ehci0: usb@15400300 {
+                       compatible = "brcm,bcm3384-ehci", "generic-ehci";
+                       reg = <0x15400300 0x100>;
+                       big-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <41>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@15400400 {
+                       compatible = "brcm,bcm3384-ohci", "generic-ohci";
+                       reg = <0x15400400 0x100>;
+                       big-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <40>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi
new file mode 100644 (file)
index 0000000..41891c1
--- /dev/null
@@ -0,0 +1,86 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm6328";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <160000000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips4350";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips4350";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       clocks {
+               periph_clk: periph_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <50000000>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       ubus {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges;
+
+               periph_intc: periph_intc@10000020 {
+                       compatible = "brcm,bcm3380-l2-intc";
+                       reg = <0x10000024 0x4 0x1000002c 0x4>,
+                             <0x10000020 0x4 0x10000028 0x4>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>;
+               };
+
+               uart0: serial@10000100 {
+                       compatible = "brcm,bcm6345-uart";
+                       reg = <0x10000100 0x18>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <28>;
+                       clocks = <&periph_clk>;
+                       status = "disabled";
+               };
+
+               timer: timer@10000040 {
+                       compatible = "syscon";
+                       reg = <0x10000040 0x2c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "syscon-reboot";
+                       regmap = <&timer>;
+                       offset = <0x28>;
+                       mask = <0x1>;
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm6368.dtsi b/arch/mips/boot/dts/brcm/bcm6368.dtsi
new file mode 100644 (file)
index 0000000..45152bc
--- /dev/null
@@ -0,0 +1,93 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm6368";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <200000000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips4350";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips4350";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+
+       };
+
+       clocks {
+               periph_clk: periph_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <50000000>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       ubus {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges;
+
+               periph_intc: periph_intc@10000020 {
+                       compatible = "brcm,bcm3380-l2-intc";
+                       reg = <0x10000024 0x4 0x1000002c 0x4>,
+                             <0x10000020 0x4 0x10000028 0x4>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>;
+               };
+
+               uart0: serial@10000100 {
+                       compatible = "brcm,bcm6345-uart";
+                       reg = <0x10000100 0x18>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <2>;
+                       clocks = <&periph_clk>;
+                       status = "disabled";
+               };
+
+               ehci0: usb@10001500 {
+                       compatible = "brcm,bcm6368-ehci", "generic-ehci";
+                       reg = <0x10001500 0x100>;
+                       big-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <7>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@10001600 {
+                       compatible = "brcm,bcm6368-ohci", "generic-ohci";
+                       reg = <0x10001600 0x100>;
+                       big-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <5>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi
new file mode 100644 (file)
index 0000000..1a7efa8
--- /dev/null
@@ -0,0 +1,139 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm7125";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <202500000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips4380";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips4380";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <81000000>;
+               };
+       };
+
+       rdb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges = <0 0x10000000 0x01000000>;
+
+               periph_intc: periph_intc@441400 {
+                       compatible = "brcm,bcm7038-l1-intc";
+                       reg = <0x441400 0x30>, <0x441600 0x30>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>, <3>;
+               };
+
+               sun_l2_intc: sun_l2_intc@401800 {
+                       compatible = "brcm,l2-intc";
+                       reg = <0x401800 0x30>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <23>;
+               };
+
+               gisb-arb@400000 {
+                       compatible = "brcm,bcm7400-gisb-arb";
+                       reg = <0x400000 0xdc>;
+                       native-endian;
+                       interrupt-parent = <&sun_l2_intc>;
+                       interrupts = <0>, <2>;
+                       brcm,gisb-arb-master-mask = <0x2f7>;
+                       brcm,gisb-arb-master-names = "ssp_0", "cpu_0", "pci_0",
+                                                    "bsp_0", "rdc_0", "rptd_0",
+                                                    "avd_0", "jtag_0";
+               };
+
+               upg_irq0_intc: upg_irq0_intc@406780 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x406780 0x8>;
+
+                       brcm,int-map-mask = <0x44>;
+                       brcm,int-fwd-mask = <0x70000>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <18>;
+               };
+
+               sun_top_ctrl: syscon@404000 {
+                       compatible = "brcm,bcm7125-sun-top-ctrl", "syscon";
+                       reg = <0x404000 0x60c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "brcm,bcm7038-reboot";
+                       syscon = <&sun_top_ctrl 0x8 0x14>;
+               };
+
+               uart0: serial@406b00 {
+                       compatible = "ns16550a";
+                       reg = <0x406b00 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <21>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               ehci0: usb@488300 {
+                       compatible = "brcm,bcm7125-ehci", "generic-ehci";
+                       reg = <0x488300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <60>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@488400 {
+                       compatible = "brcm,bcm7125-ohci", "generic-ohci";
+                       reg = <0x488400 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <61>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi
new file mode 100644 (file)
index 0000000..1f30728
--- /dev/null
@@ -0,0 +1,224 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm7346";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <163125000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips5000";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips5000";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <81000000>;
+               };
+       };
+
+       rdb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges = <0 0x10000000 0x01000000>;
+
+               periph_intc: periph_intc@411400 {
+                       compatible = "brcm,bcm7038-l1-intc";
+                       reg = <0x411400 0x30>, <0x411600 0x30>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>, <3>;
+               };
+
+               sun_l2_intc: sun_l2_intc@403000 {
+                       compatible = "brcm,l2-intc";
+                       reg = <0x403000 0x30>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <51>;
+               };
+
+               gisb-arb@400000 {
+                       compatible = "brcm,bcm7400-gisb-arb";
+                       reg = <0x400000 0xdc>;
+                       native-endian;
+                       interrupt-parent = <&sun_l2_intc>;
+                       interrupts = <0>, <2>;
+                       brcm,gisb-arb-master-mask = <0x673>;
+                       brcm,gisb-arb-master-names = "ssp_0", "cpu_0", "bsp_0",
+                                                    "rdc_0", "raaga_0",
+                                                    "jtag_0", "svd_0";
+               };
+
+               upg_irq0_intc: upg_irq0_intc@406780 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x406780 0x8>;
+
+                       brcm,int-map-mask = <0x44>;
+                       brcm,int-fwd-mask = <0x70000>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <59>;
+               };
+
+               sun_top_ctrl: syscon@404000 {
+                       compatible = "brcm,bcm7346-sun-top-ctrl", "syscon";
+                       reg = <0x404000 0x51c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "brcm,brcmstb-reboot";
+                       syscon = <&sun_top_ctrl 0x304 0x308>;
+               };
+
+               uart0: serial@406900 {
+                       compatible = "ns16550a";
+                       reg = <0x406900 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <64>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               enet0: ethernet@430000 {
+                       phy-mode = "internal";
+                       phy-handle = <&phy1>;
+                       mac-address = [ 00 10 18 36 23 1a ];
+                       compatible = "brcm,genet-v2";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       reg = <0x430000 0x4c8c>;
+                       interrupts = <24>, <25>;
+                       interrupt-parent = <&periph_intc>;
+                       status = "disabled";
+
+                       mdio@e14 {
+                               compatible = "brcm,genet-mdio-v2";
+                               #address-cells = <0x1>;
+                               #size-cells = <0x0>;
+                               reg = <0xe14 0x8>;
+
+                               phy1: ethernet-phy@1 {
+                                       max-speed = <100>;
+                                       reg = <0x1>;
+                                       compatible = "brcm,40nm-ephy",
+                                               "ethernet-phy-ieee802.3-c22";
+                               };
+                       };
+               };
+
+               ehci0: usb@480300 {
+                       compatible = "brcm,bcm7346-ehci", "generic-ehci";
+                       reg = <0x480300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <68>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@480400 {
+                       compatible = "brcm,bcm7346-ohci", "generic-ohci";
+                       reg = <0x480400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <70>;
+                       status = "disabled";
+               };
+
+               ehci1: usb@480500 {
+                       compatible = "brcm,bcm7346-ehci", "generic-ehci";
+                       reg = <0x480500 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <69>;
+                       status = "disabled";
+               };
+
+               ohci1: usb@480600 {
+                       compatible = "brcm,bcm7346-ohci", "generic-ohci";
+                       reg = <0x480600 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <71>;
+                       status = "disabled";
+               };
+
+               ehci2: usb@490300 {
+                       compatible = "brcm,bcm7346-ehci", "generic-ehci";
+                       reg = <0x490300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <73>;
+                       status = "disabled";
+               };
+
+               ohci2: usb@490400 {
+                       compatible = "brcm,bcm7346-ohci", "generic-ohci";
+                       reg = <0x490400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <75>;
+                       status = "disabled";
+               };
+
+               ehci3: usb@490500 {
+                       compatible = "brcm,bcm7346-ehci", "generic-ehci";
+                       reg = <0x490500 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <74>;
+                       status = "disabled";
+               };
+
+               ohci3: usb@490600 {
+                       compatible = "brcm,bcm7346-ohci", "generic-ohci";
+                       reg = <0x490600 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <76>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi
new file mode 100644 (file)
index 0000000..2c2aa93
--- /dev/null
@@ -0,0 +1,161 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm7358";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <375000000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips3300";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <81000000>;
+               };
+       };
+
+       rdb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges = <0 0x10000000 0x01000000>;
+
+               periph_intc: periph_intc@411400 {
+                       compatible = "brcm,bcm7038-l1-intc";
+                       reg = <0x411400 0x30>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>;
+               };
+
+               sun_l2_intc: sun_l2_intc@403000 {
+                       compatible = "brcm,l2-intc";
+                       reg = <0x403000 0x30>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <48>;
+               };
+
+               gisb-arb@400000 {
+                       compatible = "brcm,bcm7400-gisb-arb";
+                       reg = <0x400000 0xdc>;
+                       native-endian;
+                       interrupt-parent = <&sun_l2_intc>;
+                       interrupts = <0>, <2>;
+                       brcm,gisb-arb-master-mask = <0x2f3>;
+                       brcm,gisb-arb-master-names = "ssp_0", "cpu_0", "bsp_0",
+                                                    "rdc_0", "raaga_0",
+                                                    "avd_0", "jtag_0";
+               };
+
+               upg_irq0_intc: upg_irq0_intc@406600 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x406600 0x8>;
+
+                       brcm,int-map-mask = <0x44>;
+                       brcm,int-fwd-mask = <0x70000>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <56>;
+               };
+
+               sun_top_ctrl: syscon@404000 {
+                       compatible = "brcm,bcm7358-sun-top-ctrl", "syscon";
+                       reg = <0x404000 0x51c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "brcm,brcmstb-reboot";
+                       syscon = <&sun_top_ctrl 0x304 0x308>;
+               };
+
+               uart0: serial@406800 {
+                       compatible = "ns16550a";
+                       reg = <0x406800 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <61>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               enet0: ethernet@430000 {
+                       phy-mode = "internal";
+                       phy-handle = <&phy1>;
+                       mac-address = [ 00 10 18 36 23 1a ];
+                       compatible = "brcm,genet-v2";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       reg = <0x430000 0x4c8c>;
+                       interrupts = <24>, <25>;
+                       interrupt-parent = <&periph_intc>;
+                       status = "disabled";
+
+                       mdio@e14 {
+                               compatible = "brcm,genet-mdio-v2";
+                               #address-cells = <0x1>;
+                               #size-cells = <0x0>;
+                               reg = <0xe14 0x8>;
+
+                               phy1: ethernet-phy@1 {
+                                       max-speed = <100>;
+                                       reg = <0x1>;
+                                       compatible = "brcm,40nm-ephy",
+                                               "ethernet-phy-ieee802.3-c22";
+                               };
+                       };
+               };
+
+               ehci0: usb@480300 {
+                       compatible = "brcm,bcm7358-ehci", "generic-ehci";
+                       reg = <0x480300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <65>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@480400 {
+                       compatible = "brcm,bcm7358-ohci", "generic-ohci";
+                       reg = <0x480400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <66>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi
new file mode 100644 (file)
index 0000000..f23b0ae
--- /dev/null
@@ -0,0 +1,161 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm7360";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <375000000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips3300";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <81000000>;
+               };
+       };
+
+       rdb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges = <0 0x10000000 0x01000000>;
+
+               periph_intc: periph_intc@411400 {
+                       compatible = "brcm,bcm7038-l1-intc";
+                       reg = <0x411400 0x30>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>;
+               };
+
+               sun_l2_intc: sun_l2_intc@403000 {
+                       compatible = "brcm,l2-intc";
+                       reg = <0x403000 0x30>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <48>;
+               };
+
+               gisb-arb@400000 {
+                       compatible = "brcm,bcm7400-gisb-arb";
+                       reg = <0x400000 0xdc>;
+                       native-endian;
+                       interrupt-parent = <&sun_l2_intc>;
+                       interrupts = <0>, <2>;
+                       brcm,gisb-arb-master-mask = <0x2f3>;
+                       brcm,gisb-arb-master-names = "ssp_0", "cpu_0", "bsp_0",
+                                                    "rdc_0", "raaga_0",
+                                                    "avd_0", "jtag_0";
+               };
+
+               upg_irq0_intc: upg_irq0_intc@406600 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x406600 0x8>;
+
+                       brcm,int-map-mask = <0x44>;
+                       brcm,int-fwd-mask = <0x70000>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <56>;
+               };
+
+               sun_top_ctrl: syscon@404000 {
+                       compatible = "brcm,bcm7360-sun-top-ctrl", "syscon";
+                       reg = <0x404000 0x51c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "brcm,brcmstb-reboot";
+                       syscon = <&sun_top_ctrl 0x304 0x308>;
+               };
+
+               uart0: serial@406800 {
+                       compatible = "ns16550a";
+                       reg = <0x406800 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <61>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               enet0: ethernet@430000 {
+                       phy-mode = "internal";
+                       phy-handle = <&phy1>;
+                       mac-address = [ 00 10 18 36 23 1a ];
+                       compatible = "brcm,genet-v2";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       reg = <0x430000 0x4c8c>;
+                       interrupts = <24>, <25>;
+                       interrupt-parent = <&periph_intc>;
+                       status = "disabled";
+
+                       mdio@e14 {
+                               compatible = "brcm,genet-mdio-v2";
+                               #address-cells = <0x1>;
+                               #size-cells = <0x0>;
+                               reg = <0xe14 0x8>;
+
+                               phy1: ethernet-phy@1 {
+                                       max-speed = <100>;
+                                       reg = <0x1>;
+                                       compatible = "brcm,40nm-ephy",
+                                               "ethernet-phy-ieee802.3-c22";
+                               };
+                       };
+               };
+
+               ehci0: usb@480300 {
+                       compatible = "brcm,bcm7360-ehci", "generic-ehci";
+                       reg = <0x480300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <65>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@480400 {
+                       compatible = "brcm,bcm7360-ohci", "generic-ohci";
+                       reg = <0x480400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <66>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi
new file mode 100644 (file)
index 0000000..da99db6
--- /dev/null
@@ -0,0 +1,167 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm7362";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <375000000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips4380";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips4380";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <81000000>;
+               };
+       };
+
+       rdb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges = <0 0x10000000 0x01000000>;
+
+               periph_intc: periph_intc@411400 {
+                       compatible = "brcm,bcm7038-l1-intc";
+                       reg = <0x411400 0x30>, <0x411600 0x30>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>, <3>;
+               };
+
+               sun_l2_intc: sun_l2_intc@403000 {
+                       compatible = "brcm,l2-intc";
+                       reg = <0x403000 0x30>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <48>;
+               };
+
+               gisb-arb@400000 {
+                       compatible = "brcm,bcm7400-gisb-arb";
+                       reg = <0x400000 0xdc>;
+                       native-endian;
+                       interrupt-parent = <&sun_l2_intc>;
+                       interrupts = <0>, <2>;
+                       brcm,gisb-arb-master-mask = <0x2f3>;
+                       brcm,gisb-arb-master-names = "ssp_0", "cpu_0", "bsp_0",
+                                                    "rdc_0", "raaga_0",
+                                                    "avd_0", "jtag_0";
+               };
+
+               upg_irq0_intc: upg_irq0_intc@406600 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x406600 0x8>;
+
+                       brcm,int-map-mask = <0x44>;
+                       brcm,int-fwd-mask = <0x70000>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <56>;
+               };
+
+               sun_top_ctrl: syscon@404000 {
+                       compatible = "brcm,bcm7362-sun-top-ctrl", "syscon";
+                       reg = <0x404000 0x51c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "brcm,brcmstb-reboot";
+                       syscon = <&sun_top_ctrl 0x304 0x308>;
+               };
+
+               uart0: serial@406800 {
+                       compatible = "ns16550a";
+                       reg = <0x406800 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <61>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               enet0: ethernet@430000 {
+                       phy-mode = "internal";
+                       phy-handle = <&phy1>;
+                       mac-address = [ 00 10 18 36 23 1a ];
+                       compatible = "brcm,genet-v2";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       reg = <0x430000 0x4c8c>;
+                       interrupts = <24>, <25>;
+                       interrupt-parent = <&periph_intc>;
+                       status = "disabled";
+
+                       mdio@e14 {
+                               compatible = "brcm,genet-mdio-v2";
+                               #address-cells = <0x1>;
+                               #size-cells = <0x0>;
+                               reg = <0xe14 0x8>;
+
+                               phy1: ethernet-phy@1 {
+                                       max-speed = <100>;
+                                       reg = <0x1>;
+                                       compatible = "brcm,40nm-ephy",
+                                               "ethernet-phy-ieee802.3-c22";
+                               };
+                       };
+               };
+
+               ehci0: usb@480300 {
+                       compatible = "brcm,bcm7362-ehci", "generic-ehci";
+                       reg = <0x480300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <65>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@480400 {
+                       compatible = "brcm,bcm7362-ohci", "generic-ohci";
+                       reg = <0x480400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <66>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi
new file mode 100644 (file)
index 0000000..5f55d0a
--- /dev/null
@@ -0,0 +1,184 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm7420";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <93750000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips5000";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips5000";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <81000000>;
+               };
+       };
+
+       rdb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges = <0 0x10000000 0x01000000>;
+
+               periph_intc: periph_intc@441400 {
+                       compatible = "brcm,bcm7038-l1-intc";
+                       reg = <0x441400 0x30>, <0x441600 0x30>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>, <3>;
+               };
+
+               sun_l2_intc: sun_l2_intc@401800 {
+                       compatible = "brcm,l2-intc";
+                       reg = <0x401800 0x30>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <23>;
+               };
+
+               gisb-arb@400000 {
+                       compatible = "brcm,bcm7400-gisb-arb";
+                       reg = <0x400000 0xdc>;
+                       native-endian;
+                       interrupt-parent = <&sun_l2_intc>;
+                       interrupts = <0>, <2>;
+                       brcm,gisb-arb-master-mask = <0x3ff>;
+                       brcm,gisb-arb-master-names = "ssp_0", "cpu_0", "pci_0",
+                                                    "pcie_0", "bsp_0", "rdc_0",
+                                                    "rptd_0", "avd_0", "avd_1",
+                                                    "jtag_0";
+               };
+
+               upg_irq0_intc: upg_irq0_intc@406780 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x406780 0x8>;
+
+                       brcm,int-map-mask = <0x44>;
+                       brcm,int-fwd-mask = <0x70000>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <18>;
+               };
+
+               sun_top_ctrl: syscon@404000 {
+                       compatible = "brcm,bcm7420-sun-top-ctrl", "syscon";
+                       reg = <0x404000 0x60c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "brcm,bcm7038-reboot";
+                       syscon = <&sun_top_ctrl 0x8 0x14>;
+               };
+
+               uart0: serial@406b00 {
+                       compatible = "ns16550a";
+                       reg = <0x406b00 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <21>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               enet0: ethernet@468000 {
+                       phy-mode = "internal";
+                       phy-handle = <&phy1>;
+                       mac-address = [ 00 10 18 36 23 1a ];
+                       compatible = "brcm,genet-v1";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       reg = <0x468000 0x3c8c>;
+                       interrupts = <69>, <79>;
+                       interrupt-parent = <&periph_intc>;
+                       status = "disabled";
+
+                       mdio@e14 {
+                               compatible = "brcm,genet-mdio-v1";
+                               #address-cells = <0x1>;
+                               #size-cells = <0x0>;
+                               reg = <0xe14 0x8>;
+
+                               phy1: ethernet-phy@1 {
+                                       max-speed = <100>;
+                                       reg = <0x1>;
+                                       compatible = "brcm,65nm-ephy",
+                                               "ethernet-phy-ieee802.3-c22";
+                               };
+                       };
+               };
+
+               ehci0: usb@488300 {
+                       compatible = "brcm,bcm7420-ehci", "generic-ehci";
+                       reg = <0x488300 0x100>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <60>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@488400 {
+                       compatible = "brcm,bcm7420-ohci", "generic-ohci";
+                       reg = <0x488400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <61>;
+                       status = "disabled";
+               };
+
+               ehci1: usb@488500 {
+                       compatible = "brcm,bcm7420-ehci", "generic-ehci";
+                       reg = <0x488500 0x100>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <55>;
+                       status = "disabled";
+               };
+
+               ohci1: usb@488600 {
+                       compatible = "brcm,bcm7420-ohci", "generic-ohci";
+                       reg = <0x488600 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <62>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi
new file mode 100644 (file)
index 0000000..5b660b6
--- /dev/null
@@ -0,0 +1,225 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm7425";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <163125000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips5000";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips5000";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <81000000>;
+               };
+       };
+
+       rdb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges = <0 0x10000000 0x01000000>;
+
+               periph_intc: periph_intc@41a400 {
+                       compatible = "brcm,bcm7038-l1-intc";
+                       reg = <0x41a400 0x30>, <0x41a600 0x30>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>, <3>;
+               };
+
+               sun_l2_intc: sun_l2_intc@403000 {
+                       compatible = "brcm,l2-intc";
+                       reg = <0x403000 0x30>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <47>;
+               };
+
+               gisb-arb@400000 {
+                       compatible = "brcm,bcm7400-gisb-arb";
+                       reg = <0x400000 0xdc>;
+                       native-endian;
+                       interrupt-parent = <&sun_l2_intc>;
+                       interrupts = <0>, <2>;
+                       brcm,gisb-arb-master-mask = <0x177b>;
+                       brcm,gisb-arb-master-names = "ssp_0", "cpu_0", "pcie_0",
+                                                    "bsp_0", "rdc_0",
+                                                    "raaga_0", "avd_1",
+                                                    "jtag_0", "svd_0",
+                                                    "vice_0";
+               };
+
+               upg_irq0_intc: upg_irq0_intc@406780 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x406780 0x8>;
+
+                       brcm,int-map-mask = <0x44>;
+                       brcm,int-fwd-mask = <0x70000>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <55>;
+               };
+
+               sun_top_ctrl: syscon@404000 {
+                       compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
+                       reg = <0x404000 0x51c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "brcm,brcmstb-reboot";
+                       syscon = <&sun_top_ctrl 0x304 0x308>;
+               };
+
+               uart0: serial@406b00 {
+                       compatible = "ns16550a";
+                       reg = <0x406b00 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <61>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               enet0: ethernet@b80000 {
+                       phy-mode = "internal";
+                       phy-handle = <&phy1>;
+                       mac-address = [ 00 10 18 36 23 1a ];
+                       compatible = "brcm,genet-v3";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       reg = <0xb80000 0x11c88>;
+                       interrupts = <17>, <18>;
+                       interrupt-parent = <&periph_intc>;
+                       status = "disabled";
+
+                       mdio@e14 {
+                               compatible = "brcm,genet-mdio-v3";
+                               #address-cells = <0x1>;
+                               #size-cells = <0x0>;
+                               reg = <0xe14 0x8>;
+
+                               phy1: ethernet-phy@1 {
+                                       max-speed = <100>;
+                                       reg = <0x1>;
+                                       compatible = "brcm,40nm-ephy",
+                                               "ethernet-phy-ieee802.3-c22";
+                               };
+                       };
+               };
+
+               ehci0: usb@480300 {
+                       compatible = "brcm,bcm7425-ehci", "generic-ehci";
+                       reg = <0x480300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <65>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@480400 {
+                       compatible = "brcm,bcm7425-ohci", "generic-ohci";
+                       reg = <0x480400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <67>;
+                       status = "disabled";
+               };
+
+               ehci1: usb@480500 {
+                       compatible = "brcm,bcm7425-ehci", "generic-ehci";
+                       reg = <0x480500 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <66>;
+                       status = "disabled";
+               };
+
+               ohci1: usb@480600 {
+                       compatible = "brcm,bcm7425-ohci", "generic-ohci";
+                       reg = <0x480600 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <68>;
+                       status = "disabled";
+               };
+
+               ehci2: usb@490300 {
+                       compatible = "brcm,bcm7425-ehci", "generic-ehci";
+                       reg = <0x490300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <70>;
+                       status = "disabled";
+               };
+
+               ohci2: usb@490400 {
+                       compatible = "brcm,bcm7425-ohci", "generic-ohci";
+                       reg = <0x490400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <72>;
+                       status = "disabled";
+               };
+
+               ehci3: usb@490500 {
+                       compatible = "brcm,bcm7425-ehci", "generic-ehci";
+                       reg = <0x490500 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <71>;
+                       status = "disabled";
+               };
+
+               ohci3: usb@490600 {
+                       compatible = "brcm,bcm7425-ohci", "generic-ohci";
+                       reg = <0x490600 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <73>;
+                       status = "disabled";
+               };
+       };
+};
similarity index 63%
rename from arch/mips/boot/dts/bcm93384wvg.dts
rename to arch/mips/boot/dts/brcm/bcm93384wvg.dts
index 8317411..d1e44a1 100644 (file)
@@ -1,6 +1,6 @@
 /dts-v1/;
 
-/include/ "bcm3384.dtsi"
+/include/ "bcm3384_zephyr.dtsi"
 
 / {
        compatible = "brcm,bcm93384wvg", "brcm,bcm3384";
                bootargs = "console=ttyS0,115200";
                stdout-path = &uart0;
        };
-
-       memory@0 {
-               device_type = "memory";
-               reg = <0x0 0x04000000>;
-               dma-xor-mask = <0x08000000>;
-               dma-xor-limit = <0x0fffffff>;
-       };
 };
 
 &uart0 {
diff --git a/arch/mips/boot/dts/brcm/bcm93384wvg_viper.dts b/arch/mips/boot/dts/brcm/bcm93384wvg_viper.dts
new file mode 100644 (file)
index 0000000..1ecb269
--- /dev/null
@@ -0,0 +1,25 @@
+/dts-v1/;
+
+/include/ "bcm3384_viper.dtsi"
+
+/ {
+       compatible = "brcm,bcm93384wvg-viper", "brcm,bcm3384-viper";
+       model = "Broadcom BCM93384WVG-viper";
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm96368mvwg.dts b/arch/mips/boot/dts/brcm/bcm96368mvwg.dts
new file mode 100644 (file)
index 0000000..0e890c2
--- /dev/null
@@ -0,0 +1,31 @@
+/dts-v1/;
+
+/include/ "bcm6368.dtsi"
+
+/ {
+       compatible = "brcm,bcm96368mvwg", "brcm,bcm6368";
+       model = "Broadcom BCM96368MVWG";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x04000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+/* FIXME: need to set up USB_CTRL registers first */
+&ehci0 {
+       status = "disabled";
+};
+
+&ohci0 {
+       status = "disabled";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts
new file mode 100644 (file)
index 0000000..e046b11
--- /dev/null
@@ -0,0 +1,31 @@
+/dts-v1/;
+
+/include/ "bcm7125.dtsi"
+
+/ {
+       compatible = "brcm,bcm97125cbmb", "brcm,bcm7125";
+       model = "Broadcom BCM97125CBMB";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+/* FIXME: USB is wonky; disable it for now */
+&ehci0 {
+       status = "disabled";
+};
+
+&ohci0 {
+       status = "disabled";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts
new file mode 100644 (file)
index 0000000..70f196d
--- /dev/null
@@ -0,0 +1,58 @@
+/dts-v1/;
+
+/include/ "bcm7346.dtsi"
+
+/ {
+       compatible = "brcm,bcm97346dbsmb", "brcm,bcm7346";
+       model = "Broadcom BCM97346DBSMB";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>, <0x20000000 0x30000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&enet0 {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+&ehci2 {
+       status = "okay";
+};
+
+&ohci2 {
+       status = "okay";
+};
+
+&ehci3 {
+       status = "okay";
+};
+
+&ohci3 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm97358svmb.dts b/arch/mips/boot/dts/brcm/bcm97358svmb.dts
new file mode 100644 (file)
index 0000000..d18e6d9
--- /dev/null
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+/include/ "bcm7358.dtsi"
+
+/ {
+       compatible = "brcm,bcm97358svmb", "brcm,bcm7358";
+       model = "Broadcom BCM97358SVMB";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&enet0 {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm97360svmb.dts b/arch/mips/boot/dts/brcm/bcm97360svmb.dts
new file mode 100644 (file)
index 0000000..4fe5155
--- /dev/null
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+/include/ "bcm7360.dtsi"
+
+/ {
+       compatible = "brcm,bcm97360svmb", "brcm,bcm7360";
+       model = "Broadcom BCM97360SVMB";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&enet0 {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm97362svmb.dts b/arch/mips/boot/dts/brcm/bcm97362svmb.dts
new file mode 100644 (file)
index 0000000..b7b88e5
--- /dev/null
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+/include/ "bcm7362.dtsi"
+
+/ {
+       compatible = "brcm,bcm97362svmb", "brcm,bcm7362";
+       model = "Broadcom BCM97362SVMB";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>, <0x20000000 0x30000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&enet0 {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm97420c.dts b/arch/mips/boot/dts/brcm/bcm97420c.dts
new file mode 100644 (file)
index 0000000..67fe1f3
--- /dev/null
@@ -0,0 +1,45 @@
+/dts-v1/;
+
+/include/ "bcm7420.dtsi"
+
+/ {
+       compatible = "brcm,bcm97420c", "brcm,bcm7420";
+       model = "Broadcom BCM97420C";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>,
+                     <0x20000000 0x30000000>,
+                     <0x60000000 0x10000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+/* FIXME: MAC driver comes up but cannot attach to PHY */
+&enet0 {
+       status = "disabled";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm97425svmb.dts b/arch/mips/boot/dts/brcm/bcm97425svmb.dts
new file mode 100644 (file)
index 0000000..689c68a
--- /dev/null
@@ -0,0 +1,60 @@
+/dts-v1/;
+
+/include/ "bcm7425.dtsi"
+
+/ {
+       compatible = "brcm,bcm97425svmb", "brcm,bcm7425";
+       model = "Broadcom BCM97425SVMB";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>,
+                     <0x20000000 0x30000000>,
+                     <0x90000000 0x40000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&enet0 {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+&ehci2 {
+       status = "okay";
+};
+
+&ohci2 {
+       status = "okay";
+};
+
+&ehci3 {
+       status = "okay";
+};
+
+&ohci3 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/brcm/bcm9ejtagprb.dts b/arch/mips/boot/dts/brcm/bcm9ejtagprb.dts
new file mode 100644 (file)
index 0000000..1da4608
--- /dev/null
@@ -0,0 +1,22 @@
+/dts-v1/;
+
+/include/ "bcm6328.dtsi"
+
+/ {
+       compatible = "brcm,bcm9ejtagprb", "brcm,bcm6328";
+       model = "Broadcom BCM9EJTAGPRB";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x08000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/cavium-octeon/Makefile b/arch/mips/boot/dts/cavium-octeon/Makefile
new file mode 100644 (file)
index 0000000..5b99c40
--- /dev/null
@@ -0,0 +1,9 @@
+dtb-$(CONFIG_CAVIUM_OCTEON_SOC)        += octeon_3xxx.dtb octeon_68xx.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
similarity index 98%
rename from arch/mips/boot/dts/octeon_3xxx.dts
rename to arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts
index fa33115..9c48e05 100644 (file)
                usbn = &usbn;
                led0 = &led0;
        };
+
+       dsr1000n-leds {
+               compatible = "gpio-leds";
+               usb1 {
+                       label = "usb1";
+                       gpios = <&gpio 9 1>; /* Active low */
+               };
+               usb2 {
+                       label = "usb2";
+                       gpios = <&gpio 10 1>; /* Active low */
+               };
+       };
  };
diff --git a/arch/mips/boot/dts/lantiq/Makefile b/arch/mips/boot/dts/lantiq/Makefile
new file mode 100644 (file)
index 0000000..0906c62
--- /dev/null
@@ -0,0 +1,9 @@
+dtb-$(CONFIG_DT_EASY50712)     += easy50712.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/mti/Makefile b/arch/mips/boot/dts/mti/Makefile
new file mode 100644 (file)
index 0000000..ef1f3db
--- /dev/null
@@ -0,0 +1,9 @@
+dtb-$(CONFIG_MIPS_SEAD3)       += sead3.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/netlogic/Makefile b/arch/mips/boot/dts/netlogic/Makefile
new file mode 100644 (file)
index 0000000..9868057
--- /dev/null
@@ -0,0 +1,13 @@
+dtb-$(CONFIG_DT_XLP_EVP)       += xlp_evp.dtb
+dtb-$(CONFIG_DT_XLP_SVP)       += xlp_svp.dtb
+dtb-$(CONFIG_DT_XLP_FVP)       += xlp_fvp.dtb
+dtb-$(CONFIG_DT_XLP_GVP)       += xlp_gvp.dtb
+dtb-$(CONFIG_DT_XLP_RVP)       += xlp_rvp.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/netlogic/xlp_rvp.dts b/arch/mips/boot/dts/netlogic/xlp_rvp.dts
new file mode 100644 (file)
index 0000000..7188aed
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * XLP5XX Device Tree Source for RVP boards
+ */
+
+/dts-v1/;
+/ {
+       model = "netlogic,XLP-RVP";
+       compatible = "netlogic,xlp";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       soc {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               ranges = <0 0  0 0x18000000  0x04000000   // PCIe CFG
+                         1 0  0 0x16000000  0x02000000>; // GBU chipselects
+
+               serial0: serial@30000 {
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0 0x112100 0xa00>;
+                       reg-shift = <2>;
+                       reg-io-width = <4>;
+                       clock-frequency = <125000000>;
+                       interrupt-parent = <&pic>;
+                       interrupts = <17>;
+               };
+               pic: pic@110000 {
+                       compatible = "netlogic,xlp-pic";
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+                       reg = <0 0x110000 0x200>;
+                       interrupt-controller;
+               };
+
+               nor_flash@1,0 {
+                       compatible = "cfi-flash";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       bank-width = <2>;
+                       reg = <1 0 0x1000000>;
+
+                       partition@0 {
+                               label = "x-loader";
+                               reg = <0x0 0x100000>; /* 1M */
+                               read-only;
+                       };
+
+                       partition@100000 {
+                               label = "u-boot";
+                               reg = <0x100000 0x100000>; /* 1M */
+                       };
+
+                       partition@200000 {
+                               label = "kernel";
+                               reg = <0x200000 0x500000>; /* 5M */
+                       };
+
+                       partition@700000 {
+                               label = "rootfs";
+                               reg = <0x700000 0x800000>; /* 8M */
+                       };
+
+                       partition@f00000 {
+                               label = "env";
+                               reg = <0xf00000 0x100000>; /* 1M */
+                               read-only;
+                       };
+               };
+
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200 rdinit=/sbin/init";
+       };
+};
diff --git a/arch/mips/boot/dts/ralink/Makefile b/arch/mips/boot/dts/ralink/Makefile
new file mode 100644 (file)
index 0000000..2a72259
--- /dev/null
@@ -0,0 +1,12 @@
+dtb-$(CONFIG_DTB_RT2880_EVAL)  += rt2880_eval.dtb
+dtb-$(CONFIG_DTB_RT305X_EVAL)  += rt3052_eval.dtb
+dtb-$(CONFIG_DTB_RT3883_EVAL)  += rt3883_eval.dtb
+dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
index 3550725..7315cc3 100644 (file)
@@ -33,7 +33,7 @@ do {                                                  \
        __asm__ __volatile__ (                          \
        "dmtc2 %[rt],0x0048+" STR(index)                \
        :                                               \
-       : [rt] "d" (value));                            \
+       : [rt] "d" (cpu_to_be64(value)));               \
 } while (0)
 
 /*
@@ -48,7 +48,7 @@ do {                                                  \
        : [rt] "=d" (__value)                           \
        : );                                            \
                                                        \
-       __value;                                        \
+       be64_to_cpu(__value);                           \
 })
 
 /*
@@ -59,7 +59,7 @@ do {                                                  \
        __asm__ __volatile__ (                          \
        "dmtc2 %[rt],0x0040+" STR(index)                \
        :                                               \
-       : [rt] "d" (value));                            \
+       : [rt] "d" (cpu_to_be64(value)));               \
 } while (0)
 
 /*
@@ -70,6 +70,80 @@ do {                                                 \
        __asm__ __volatile__ (                          \
        "dmtc2 %[rt],0x4047"                            \
        :                                               \
+       : [rt] "d" (cpu_to_be64(value)));               \
+} while (0)
+
+/*
+ * The value is the final block dword (64-bit).
+ */
+#define octeon_sha1_start(value)                       \
+do {                                                   \
+       __asm__ __volatile__ (                          \
+       "dmtc2 %[rt],0x4057"                            \
+       :                                               \
+       : [rt] "d" (value));                            \
+} while (0)
+
+/*
+ * The value is the final block dword (64-bit).
+ */
+#define octeon_sha256_start(value)                     \
+do {                                                   \
+       __asm__ __volatile__ (                          \
+       "dmtc2 %[rt],0x404f"                            \
+       :                                               \
+       : [rt] "d" (value));                            \
+} while (0)
+
+/*
+ * Macros needed to implement SHA512:
+ */
+
+/*
+ * The index can be 0-7.
+ */
+#define write_octeon_64bit_hash_sha512(value, index)   \
+do {                                                   \
+       __asm__ __volatile__ (                          \
+       "dmtc2 %[rt],0x0250+" STR(index)                \
+       :                                               \
+       : [rt] "d" (value));                            \
+} while (0)
+
+/*
+ * The index can be 0-7.
+ */
+#define read_octeon_64bit_hash_sha512(index)           \
+({                                                     \
+       u64 __value;                                    \
+                                                       \
+       __asm__ __volatile__ (                          \
+       "dmfc2 %[rt],0x0250+" STR(index)                \
+       : [rt] "=d" (__value)                           \
+       : );                                            \
+                                                       \
+       __value;                                        \
+})
+
+/*
+ * The index can be 0-14.
+ */
+#define write_octeon_64bit_block_sha512(value, index)  \
+do {                                                   \
+       __asm__ __volatile__ (                          \
+       "dmtc2 %[rt],0x0240+" STR(index)                \
+       :                                               \
+       : [rt] "d" (value));                            \
+} while (0)
+
+/*
+ * The value is the final block word (64-bit).
+ */
+#define octeon_sha512_start(value)                     \
+do {                                                   \
+       __asm__ __volatile__ (                          \
+       "dmtc2 %[rt],0x424f"                            \
+       :                                               \
        : [rt] "d" (value));                            \
 } while (0)
 
index 7d89878..d8960d4 100644 (file)
@@ -306,7 +306,7 @@ void __init plat_swiotlb_setup(void)
                swiotlbsize = 64 * (1<<20);
        }
 #endif
-#ifdef CONFIG_USB_OCTEON_OHCI
+#ifdef CONFIG_USB_OHCI_HCD_PLATFORM
        /* OCTEON II ohci is only 32-bit. */
        if (OCTEON_IS_OCTEON2() && max_addr >= 0x100000000ul)
                swiotlbsize = 64 * (1<<20);
index 42e38c3..89b5273 100644 (file)
@@ -519,44 +519,89 @@ int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len)
 union __cvmx_l2c_tag {
        uint64_t u64;
        struct cvmx_l2c_tag_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved:40;
                uint64_t V:1;           /* Line valid */
                uint64_t D:1;           /* Line dirty */
                uint64_t L:1;           /* Line locked */
                uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:20;       /* Phys mem addr (33..14) */
+#else
+               uint64_t addr:20;       /* Phys mem addr (33..14) */
+               uint64_t U:1;           /* Use, LRU eviction */
+               uint64_t L:1;           /* Line locked */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t V:1;           /* Line valid */
+               uint64_t reserved:40;
+#endif
        } cn50xx;
        struct cvmx_l2c_tag_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved:41;
                uint64_t V:1;           /* Line valid */
                uint64_t D:1;           /* Line dirty */
                uint64_t L:1;           /* Line locked */
                uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:19;       /* Phys mem addr (33..15) */
+#else
+               uint64_t addr:19;       /* Phys mem addr (33..15) */
+               uint64_t U:1;           /* Use, LRU eviction */
+               uint64_t L:1;           /* Line locked */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t V:1;           /* Line valid */
+               uint64_t reserved:41;
+#endif
        } cn30xx;
        struct cvmx_l2c_tag_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved:42;
                uint64_t V:1;           /* Line valid */
                uint64_t D:1;           /* Line dirty */
                uint64_t L:1;           /* Line locked */
                uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:18;       /* Phys mem addr (33..16) */
+#else
+               uint64_t addr:18;       /* Phys mem addr (33..16) */
+               uint64_t U:1;           /* Use, LRU eviction */
+               uint64_t L:1;           /* Line locked */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t V:1;           /* Line valid */
+               uint64_t reserved:42;
+#endif
        } cn31xx;
        struct cvmx_l2c_tag_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved:43;
                uint64_t V:1;           /* Line valid */
                uint64_t D:1;           /* Line dirty */
                uint64_t L:1;           /* Line locked */
                uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:17;       /* Phys mem addr (33..17) */
+#else
+               uint64_t addr:17;       /* Phys mem addr (33..17) */
+               uint64_t U:1;           /* Use, LRU eviction */
+               uint64_t L:1;           /* Line locked */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t V:1;           /* Line valid */
+               uint64_t reserved:43;
+#endif
        } cn38xx;
        struct cvmx_l2c_tag_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved:44;
                uint64_t V:1;           /* Line valid */
                uint64_t D:1;           /* Line dirty */
                uint64_t L:1;           /* Line locked */
                uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:16;       /* Phys mem addr (33..18) */
+#else
+               uint64_t addr:16;       /* Phys mem addr (33..18) */
+               uint64_t U:1;           /* Use, LRU eviction */
+               uint64_t L:1;           /* Line locked */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t V:1;           /* Line valid */
+               uint64_t reserved:44;
+#endif
        } cn58xx;
        struct cvmx_l2c_tag_cn58xx cn56xx;      /* 2048 sets */
        struct cvmx_l2c_tag_cn31xx cn52xx;      /* 512 sets */
index 237e5b1..a5e8f4a 100644 (file)
@@ -8,9 +8,11 @@
  * Copyright (C) 2007, 2008 Cavium Networks
  */
 #include <linux/kernel.h>
-#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/semaphore.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
+#include <linux/of_platform.h>
 #include <linux/mtd/partitions.h>
 
 #include <asm/octeon/octeon.h>
@@ -25,19 +27,62 @@ static const char *part_probe_types[] = {
        NULL
 };
 
+static map_word octeon_flash_map_read(struct map_info *map, unsigned long ofs)
+{
+       map_word r;
+
+       down(&octeon_bootbus_sem);
+       r = inline_map_read(map, ofs);
+       up(&octeon_bootbus_sem);
+
+       return r;
+}
+
+static void octeon_flash_map_write(struct map_info *map, const map_word datum,
+                                  unsigned long ofs)
+{
+       down(&octeon_bootbus_sem);
+       inline_map_write(map, datum, ofs);
+       up(&octeon_bootbus_sem);
+}
+
+static void octeon_flash_map_copy_from(struct map_info *map, void *to,
+                                      unsigned long from, ssize_t len)
+{
+       down(&octeon_bootbus_sem);
+       inline_map_copy_from(map, to, from, len);
+       up(&octeon_bootbus_sem);
+}
+
+static void octeon_flash_map_copy_to(struct map_info *map, unsigned long to,
+                                    const void *from, ssize_t len)
+{
+       down(&octeon_bootbus_sem);
+       inline_map_copy_to(map, to, from, len);
+       up(&octeon_bootbus_sem);
+}
+
 /**
  * Module/ driver initialization.
  *
  * Returns Zero on success
  */
-static int __init flash_init(void)
+static int octeon_flash_probe(struct platform_device *pdev)
 {
+       union cvmx_mio_boot_reg_cfgx region_cfg;
+       u32 cs;
+       int r;
+       struct device_node *np = pdev->dev.of_node;
+
+       r = of_property_read_u32(np, "reg", &cs);
+       if (r)
+               return r;
+
        /*
         * Read the bootbus region 0 setup to determine the base
         * address of the flash.
         */
-       union cvmx_mio_boot_reg_cfgx region_cfg;
-       region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0));
+       region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
        if (region_cfg.s.en) {
                /*
                 * The bootloader always takes the flash and sets its
@@ -56,7 +101,11 @@ static int __init flash_init(void)
                flash_map.virt = ioremap(flash_map.phys, flash_map.size);
                pr_notice("Bootbus flash: Setting flash for %luMB flash at "
                          "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
-               simple_map_init(&flash_map);
+               WARN_ON(!map_bankwidth_supported(flash_map.bankwidth));
+               flash_map.read = octeon_flash_map_read;
+               flash_map.write = octeon_flash_map_write;
+               flash_map.copy_from = octeon_flash_map_copy_from;
+               flash_map.copy_to = octeon_flash_map_copy_to;
                mymtd = do_map_probe("cfi_probe", &flash_map);
                if (mymtd) {
                        mymtd->owner = THIS_MODULE;
@@ -69,4 +118,26 @@ static int __init flash_init(void)
        return 0;
 }
 
-late_initcall(flash_init);
+static const struct of_device_id of_flash_match[] = {
+       {
+               .compatible     = "cfi-flash",
+       },
+       { },
+};
+MODULE_DEVICE_TABLE(of, of_flash_match);
+
+static struct platform_driver of_flash_driver = {
+       .driver = {
+               .name = "octeon-of-flash",
+               .of_match_table = of_flash_match,
+       },
+       .probe          = octeon_flash_probe,
+};
+
+static int octeon_flash_init(void)
+{
+       return platform_driver_register(&of_flash_driver);
+}
+late_initcall(octeon_flash_init);
+
+MODULE_LICENSE("GPL");
index 12410a2..d113c8d 100644 (file)
@@ -325,8 +325,14 @@ static void __init octeon_ehci_hw_start(struct device *dev)
        /* Use 64-bit addressing. */
        ehci_ctl.s.ehci_64b_addr_en = 1;
        ehci_ctl.s.l2c_addr_msb = 0;
+#ifdef __BIG_ENDIAN
        ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
        ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
+#else
+       ehci_ctl.s.l2c_buff_emod = 0; /* not swapped. */
+       ehci_ctl.s.l2c_desc_emod = 0; /* not swapped. */
+       ehci_ctl.s.inv_reg_a2 = 1;
+#endif
        cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64);
 
        octeon2_usb_clocks_stop();
@@ -381,8 +387,14 @@ static void __init octeon_ohci_hw_start(struct device *dev)
 
        ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
        ohci_ctl.s.l2c_addr_msb = 0;
+#ifdef __BIG_ENDIAN
        ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
        ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
+#else
+       ohci_ctl.s.l2c_buff_emod = 0; /* not swapped. */
+       ohci_ctl.s.l2c_desc_emod = 0; /* not swapped. */
+       ohci_ctl.s.inv_reg_a2 = 1;
+#endif
        cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64);
 
        octeon2_usb_clocks_stop();
@@ -958,6 +970,13 @@ end_led:
                }
        }
 
+       if (octeon_bootinfo->board_type != CVMX_BOARD_TYPE_CUST_DSR1000N) {
+               int dsr1000n_leds = fdt_path_offset(initial_boot_params,
+                                                   "/dsr1000n-leds");
+               if (dsr1000n_leds >= 0)
+                       fdt_nop_node(initial_boot_params, dsr1000n_leds);
+       }
+
        return 0;
 }
 
index 7b066bb..a6ce7c4 100644 (file)
@@ -37,11 +37,13 @@ struct boot_init_vector {
 
 /* similar to bootloader's linux_app_boot_info but without global data */
 struct linux_app_boot_info {
+#ifdef __BIG_ENDIAN_BITFIELD
        uint32_t labi_signature;
        uint32_t start_core0_addr;
        uint32_t avail_coremask;
        uint32_t pci_console_active;
        uint32_t icache_prefetch_disable;
+       uint32_t padding;
        uint64_t InitTLBStart_addr;
        uint32_t start_app_addr;
        uint32_t cur_exception_base;
@@ -49,6 +51,27 @@ struct linux_app_boot_info {
        uint32_t compact_flash_common_base_addr;
        uint32_t compact_flash_attribute_base_addr;
        uint32_t led_display_base_addr;
+#else
+       uint32_t start_core0_addr;
+       uint32_t labi_signature;
+
+       uint32_t pci_console_active;
+       uint32_t avail_coremask;
+
+       uint32_t padding;
+       uint32_t icache_prefetch_disable;
+
+       uint64_t InitTLBStart_addr;
+
+       uint32_t cur_exception_base;
+       uint32_t start_app_addr;
+
+       uint32_t compact_flash_common_base_addr;
+       uint32_t no_mark_private_data;
+
+       uint32_t led_display_base_addr;
+       uint32_t compact_flash_attribute_base_addr;
+#endif
 };
 
 /* If not to copy a lot of bootloader's structures
index a42110e..89a6284 100644 (file)
@@ -51,6 +51,9 @@ extern void pci_console_init(const char *arg);
 
 static unsigned long long MAX_MEMORY = 512ull << 20;
 
+DEFINE_SEMAPHORE(octeon_bootbus_sem);
+EXPORT_SYMBOL(octeon_bootbus_sem);
+
 struct octeon_boot_descriptor *octeon_boot_desc_ptr;
 
 struct cvmx_bootinfo *octeon_bootinfo;
@@ -413,7 +416,10 @@ static void octeon_restart(char *command)
 
        mb();
        while (1)
-               cvmx_write_csr(CVMX_CIU_SOFT_RST, 1);
+               if (OCTEON_IS_OCTEON3())
+                       cvmx_write_csr(CVMX_RST_SOFT_RST, 1);
+               else
+                       cvmx_write_csr(CVMX_CIU_SOFT_RST, 1);
 }
 
 
@@ -1043,7 +1049,7 @@ int prom_putchar(char c)
 }
 EXPORT_SYMBOL(prom_putchar);
 
-void prom_free_prom_memory(void)
+void __init prom_free_prom_memory(void)
 {
        if (CAVIUM_OCTEON_DCACHE_PREFETCH_WAR) {
                /* Check for presence of Core-14449 fix.  */
similarity index 89%
rename from arch/mips/configs/bcm3384_defconfig
rename to arch/mips/configs/bmips_be_defconfig
index 88711c2..f5585c8 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_BCM3384=y
+CONFIG_BMIPS_GENERIC=y
 CONFIG_HIGHMEM=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=4
@@ -33,6 +33,7 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BRCMSTB_GISB_ARB=y
 CONFIG_MTD=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
@@ -43,15 +44,19 @@ CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
+CONFIG_BCMGENET=y
 CONFIG_USB_USBNET=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
 # CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_EARLYCON_FORCE=y
 CONFIG_SERIAL_BCM63XX=y
 CONFIG_SERIAL_BCM63XX_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_BRCMSTB=y
+CONFIG_POWER_RESET_SYSCON=y
 # CONFIG_HWMON is not set
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
@@ -75,4 +80,6 @@ CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_DEBUG_FS=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="earlycon"
 # CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/configs/bmips_stb_defconfig b/arch/mips/configs/bmips_stb_defconfig
new file mode 100644 (file)
index 0000000..400a47e
--- /dev/null
@@ -0,0 +1,88 @@
+CONFIG_BMIPS_GENERIC=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_HIGHMEM=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+# CONFIG_SECCOMP is not set
+CONFIG_MIPS_O32_FP64_SUPPORT=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_NO_HZ=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+CONFIG_EXPERT=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_BRCMSTB_GISB_ARB=y
+CONFIG_MTD=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_BLK_DEV is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_BCMGENET=y
+CONFIG_USB_USBNET=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_BRCMSTB=y
+CONFIG_POWER_RESET_SYSCON=y
+# CONFIG_HWMON is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_CIFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="earlycon"
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig
new file mode 100644 (file)
index 0000000..c388bff
--- /dev/null
@@ -0,0 +1,439 @@
+CONFIG_MIPS_MALTA=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPS32_R5_FEATURES=y
+CONFIG_CPU_MIPS32_R5_XPA=y
+CONFIG_PAGE_SIZE_16KB=y
+CONFIG_HZ_100=y
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_NAMESPACES=y
+CONFIG_RELAY=y
+CONFIG_EXPERT=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MROUTE=y
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_IP_SCTP=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_PHONET=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_CLS_IND=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_RFKILL=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_OOPS=m
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_UBI=m
+CONFIG_MTD_UBI_GLUEBI=m
+CONFIG_BLK_DEV_FD=m
+CONFIG_BLK_DEV_UMEM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_ATA_OVER_ETH=m
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_PIIX=y
+CONFIG_BLK_DEV_IT8213=m
+CONFIG_BLK_DEV_TC86C001=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_ISCSI_TCP=m
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+CONFIG_SCSI_3W_9XXX=m
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_EQUALIZER=m
+CONFIG_IFB=m
+CONFIG_MACVLAN=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_PCNET32=y
+CONFIG_CHELSIO_T3=m
+CONFIG_AX88796=m
+CONFIG_NETXEN_NIC=m
+CONFIG_TC35815=m
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_ICPLUS_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_ATMEL=m
+CONFIG_PCI_ATMEL=m
+CONFIG_PRISM54=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_PLX=m
+CONFIG_HOSTAP_PCI=m
+CONFIG_IPW2100=m
+CONFIG_IPW2100_MONITOR=y
+CONFIG_LIBERTAS=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_CIRRUS=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_HID=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_CMOS=y
+CONFIG_UIO=m
+CONFIG_UIO_CIF=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V2=y
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC16=m
diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig
new file mode 100644 (file)
index 0000000..f22e92e
--- /dev/null
@@ -0,0 +1,336 @@
+CONFIG_MACH_PISTACHIO=y
+CONFIG_MIPS_MT_SMP=y
+CONFIG_MIPS_CPS=y
+# CONFIG_COMPACTION is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
+CONFIG_ZSMALLOC=y
+CONFIG_NR_CPUS=4
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_DEFAULT_HOSTNAME="localhost"
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=m
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_ADVANCED_DEBUG=y
+CONFIG_CPU_IDLE=y
+# CONFIG_MIPS_CPS_CPUIDLE is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_DIAG is not set
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_WESTWOOD is not set
+# CONFIG_TCP_CONG_HTCP is not set
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_IPV6_SIT=m
+CONFIG_NETWORK_SECMARK=y
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_DSCP=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_NAT_IPV4=m
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_NF_NAT_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_CFG80211=m
+CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_LEDS=y
+CONFIG_MAC80211_DEBUGFS=y
+CONFIG_MAC80211_DEBUG_MENU=y
+CONFIG_MAC80211_VERBOSE_DEBUG=y
+CONFIG_RFKILL=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_DEBUG_DEVRES=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_ZRAM=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_VERITY=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_VETH=m
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_NET_VENDOR_VIA is not set
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_SMSC75XX=m
+CONFIG_USB_NET_SMSC95XX=m
+CONFIG_USB_NET_MCS7830=m
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_LIBERTAS_THINFIRM=m
+CONFIG_USB_NET_RNDIS_WLAN=m
+CONFIG_MAC80211_HWSIM=m
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_RT2X00=m
+CONFIG_RT2800USB=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_HW_RANDOM=y
+CONFIG_TCG_TPM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_IMG=y
+CONFIG_I2C_STUB=m
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=m
+CONFIG_SPI_IMG_SPFI=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_CORE=y
+CONFIG_IMGPDC_WDT=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_RC_SUPPORT=y
+# CONFIG_RC_DECODERS is not set
+CONFIG_RC_DEVICES=y
+CONFIG_IR_IMG=y
+CONFIG_IR_IMG_NEC=y
+CONFIG_IR_IMG_JVC=y
+CONFIG_IR_IMG_SONY=y
+CONFIG_IR_IMG_SHARP=y
+CONFIG_IR_IMG_SANYO=y
+CONFIG_IR_IMG_RC5=y
+CONFIG_IR_IMG_RC6=y
+# CONFIG_DVB_TUNER_DIB0070 is not set
+# CONFIG_DVB_TUNER_DIB0090 is not set
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_HRTIMER=m
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+# CONFIG_USB_DEFAULT_PERSIST is not set
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OTI6858=m
+CONFIG_USB_SERIAL_QUALCOMM=m
+CONFIG_USB_SERIAL_SIERRAWIRELESS=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=16
+CONFIG_MMC_TEST=m
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_IMG_MDC_DMA=y
+CONFIG_STAGING=y
+CONFIG_ASHMEM=y
+# CONFIG_ANDROID_TIMED_OUTPUT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_MEMORY=y
+CONFIG_IIO=y
+CONFIG_CC10001_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_IMG=y
+CONFIG_ANDROID=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ECRYPT_FS=y
+CONFIG_HFSPLUS_FS=m
+CONFIG_UBIFS_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_RAM=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_CREDENTIALS=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_LKDTM=y
+CONFIG_TEST_UDELAY=m
+CONFIG_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_YAMA=y
+CONFIG_SECURITY_YAMA_STACKED=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+# CONFIG_XZ_DEC_X86 is not set
index 41a2fa1..8c6f508 100644 (file)
@@ -267,8 +267,13 @@ handle_it:
 
 #ifdef CONFIG_32BIT
 fpu:
+               lw      t0,fpu_kstat_irq
+               nop
+               lw      t1,(t0)
+               nop
+               addu    t1,1
                j       handle_fpe_int
-                nop
+                sw     t1,(t0)
 #endif
 
 spurious:
index 41bbffd..a0b8943 100644 (file)
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/irqnr.h>
 #include <linux/module.h>
 #include <linux/param.h>
+#include <linux/percpu-defs.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/pm.h>
-#include <linux/irq.h>
 
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
@@ -98,6 +100,7 @@ int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2] = {
        { { .i = ~0 }, { .p = asic_intr_unimplemented } },
 };
 int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU);
+int *fpu_kstat_irq;
 
 static struct irqaction ioirq = {
        .handler = no_action,
@@ -755,8 +758,15 @@ void __init arch_init_irq(void)
                dec_interrupt[DEC_IRQ_HALT] = -1;
 
        /* Register board interrupts: FPU and cascade. */
-       if (dec_interrupt[DEC_IRQ_FPU] >= 0)
-               setup_irq(dec_interrupt[DEC_IRQ_FPU], &fpuirq);
+       if (dec_interrupt[DEC_IRQ_FPU] >= 0 && cpu_has_fpu) {
+               struct irq_desc *desc_fpu;
+               int irq_fpu;
+
+               irq_fpu = dec_interrupt[DEC_IRQ_FPU];
+               setup_irq(irq_fpu, &fpuirq);
+               desc_fpu = irq_to_desc(irq_fpu);
+               fpu_kstat_irq = this_cpu_ptr(desc_fpu->kstat_irqs);
+       }
        if (dec_interrupt[DEC_IRQ_CASCADE] >= 0)
                setup_irq(dec_interrupt[DEC_IRQ_CASCADE], &ioirq);
 
index e41c56e..1e38f0e 100644 (file)
 #define __ASM_ASM_EVA_H
 
 #ifndef __ASSEMBLY__
+
+/* Kernel variants */
+
+#define kernel_cache(op, base)         "cache " op ", " base "\n"
+#define kernel_ll(reg, addr)           "ll " reg ", " addr "\n"
+#define kernel_sc(reg, addr)           "sc " reg ", " addr "\n"
+#define kernel_lw(reg, addr)           "lw " reg ", " addr "\n"
+#define kernel_lwl(reg, addr)          "lwl " reg ", " addr "\n"
+#define kernel_lwr(reg, addr)          "lwr " reg ", " addr "\n"
+#define kernel_lh(reg, addr)           "lh " reg ", " addr "\n"
+#define kernel_lb(reg, addr)           "lb " reg ", " addr "\n"
+#define kernel_lbu(reg, addr)          "lbu " reg ", " addr "\n"
+#define kernel_sw(reg, addr)           "sw " reg ", " addr "\n"
+#define kernel_swl(reg, addr)          "swl " reg ", " addr "\n"
+#define kernel_swr(reg, addr)          "swr " reg ", " addr "\n"
+#define kernel_sh(reg, addr)           "sh " reg ", " addr "\n"
+#define kernel_sb(reg, addr)           "sb " reg ", " addr "\n"
+
+#ifdef CONFIG_32BIT
+/*
+ * No 'sd' or 'ld' instructions in 32-bit but the code will
+ * do the correct thing
+ */
+#define kernel_sd(reg, addr)           user_sw(reg, addr)
+#define kernel_ld(reg, addr)           user_lw(reg, addr)
+#else
+#define kernel_sd(reg, addr)           "sd " reg", " addr "\n"
+#define kernel_ld(reg, addr)           "ld " reg", " addr "\n"
+#endif /* CONFIG_32BIT */
+
 #ifdef CONFIG_EVA
 
 #define __BUILD_EVA_INSN(insn, reg, addr)                              \
 
 #else
 
-#define user_cache(op, base)           "cache " op ", " base "\n"
-#define user_ll(reg, addr)             "ll " reg ", " addr "\n"
-#define user_sc(reg, addr)             "sc " reg ", " addr "\n"
-#define user_lw(reg, addr)             "lw " reg ", " addr "\n"
-#define user_lwl(reg, addr)            "lwl " reg ", " addr "\n"
-#define user_lwr(reg, addr)            "lwr " reg ", " addr "\n"
-#define user_lh(reg, addr)             "lh " reg ", " addr "\n"
-#define user_lb(reg, addr)             "lb " reg ", " addr "\n"
-#define user_lbu(reg, addr)            "lbu " reg ", " addr "\n"
-#define user_sw(reg, addr)             "sw " reg ", " addr "\n"
-#define user_swl(reg, addr)            "swl " reg ", " addr "\n"
-#define user_swr(reg, addr)            "swr " reg ", " addr "\n"
-#define user_sh(reg, addr)             "sh " reg ", " addr "\n"
-#define user_sb(reg, addr)             "sb " reg ", " addr "\n"
+#define user_cache(op, base)           kernel_cache(op, base)
+#define user_ll(reg, addr)             kernel_ll(reg, addr)
+#define user_sc(reg, addr)             kernel_sc(reg, addr)
+#define user_lw(reg, addr)             kernel_lw(reg, addr)
+#define user_lwl(reg, addr)            kernel_lwl(reg, addr)
+#define user_lwr(reg, addr)            kernel_lwr(reg, addr)
+#define user_lh(reg, addr)             kernel_lh(reg, addr)
+#define user_lb(reg, addr)             kernel_lb(reg, addr)
+#define user_lbu(reg, addr)            kernel_lbu(reg, addr)
+#define user_sw(reg, addr)             kernel_sw(reg, addr)
+#define user_swl(reg, addr)            kernel_swl(reg, addr)
+#define user_swr(reg, addr)            kernel_swr(reg, addr)
+#define user_sh(reg, addr)             kernel_sh(reg, addr)
+#define user_sb(reg, addr)             kernel_sb(reg, addr)
 
 #ifdef CONFIG_32BIT
-/*
- * No 'sd' or 'ld' instructions in 32-bit but the code will
- * do the correct thing
- */
-#define user_sd(reg, addr)             user_sw(reg, addr)
-#define user_ld(reg, addr)             user_lw(reg, addr)
+#define user_sd(reg, addr)             kernel_sw(reg, addr)
+#define user_ld(reg, addr)             kernel_lw(reg, addr)
 #else
-#define user_sd(reg, addr)             "sd " reg", " addr "\n"
-#define user_ld(reg, addr)             "ld " reg", " addr "\n"
+#define user_sd(reg, addr)             kernel_sd(reg, addr)
+#define user_ld(reg, addr)             kernel_ld(reg, addr)
 #endif /* CONFIG_32BIT */
 
 #endif /* CONFIG_EVA */
 
 #else /* __ASSEMBLY__ */
 
+#define kernel_cache(op, base)         cache op, base
+#define kernel_ll(reg, addr)           ll reg, addr
+#define kernel_sc(reg, addr)           sc reg, addr
+#define kernel_lw(reg, addr)           lw reg, addr
+#define kernel_lwl(reg, addr)          lwl reg, addr
+#define kernel_lwr(reg, addr)          lwr reg, addr
+#define kernel_lh(reg, addr)           lh reg, addr
+#define kernel_lb(reg, addr)           lb reg, addr
+#define kernel_lbu(reg, addr)          lbu reg, addr
+#define kernel_sw(reg, addr)           sw reg, addr
+#define kernel_swl(reg, addr)          swl reg, addr
+#define kernel_swr(reg, addr)          swr reg, addr
+#define kernel_sh(reg, addr)           sh reg, addr
+#define kernel_sb(reg, addr)           sb reg, addr
+
+#ifdef CONFIG_32BIT
+/*
+ * No 'sd' or 'ld' instructions in 32-bit but the code will
+ * do the correct thing
+ */
+#define kernel_sd(reg, addr)           user_sw(reg, addr)
+#define kernel_ld(reg, addr)           user_lw(reg, addr)
+#else
+#define kernel_sd(reg, addr)           sd reg, addr
+#define kernel_ld(reg, addr)           ld reg, addr
+#endif /* CONFIG_32BIT */
+
 #ifdef CONFIG_EVA
 
 #define __BUILD_EVA_INSN(insn, reg, addr)                      \
 #define user_sd(reg, addr)             user_sw(reg, addr)
 #else
 
-#define user_cache(op, base)           cache op, base
-#define user_ll(reg, addr)             ll reg, addr
-#define user_sc(reg, addr)             sc reg, addr
-#define user_lw(reg, addr)             lw reg, addr
-#define user_lwl(reg, addr)            lwl reg, addr
-#define user_lwr(reg, addr)            lwr reg, addr
-#define user_lh(reg, addr)             lh reg, addr
-#define user_lb(reg, addr)             lb reg, addr
-#define user_lbu(reg, addr)            lbu reg, addr
-#define user_sw(reg, addr)             sw reg, addr
-#define user_swl(reg, addr)            swl reg, addr
-#define user_swr(reg, addr)            swr reg, addr
-#define user_sh(reg, addr)             sh reg, addr
-#define user_sb(reg, addr)             sb reg, addr
+#define user_cache(op, base)           kernel_cache(op, base)
+#define user_ll(reg, addr)             kernel_ll(reg, addr)
+#define user_sc(reg, addr)             kernel_sc(reg, addr)
+#define user_lw(reg, addr)             kernel_lw(reg, addr)
+#define user_lwl(reg, addr)            kernel_lwl(reg, addr)
+#define user_lwr(reg, addr)            kernel_lwr(reg, addr)
+#define user_lh(reg, addr)             kernel_lh(reg, addr)
+#define user_lb(reg, addr)             kernel_lb(reg, addr)
+#define user_lbu(reg, addr)            kernel_lbu(reg, addr)
+#define user_sw(reg, addr)             kernel_sw(reg, addr)
+#define user_swl(reg, addr)            kernel_swl(reg, addr)
+#define user_swr(reg, addr)            kernel_swr(reg, addr)
+#define user_sh(reg, addr)             kernel_sh(reg, addr)
+#define user_sb(reg, addr)             kernel_sb(reg, addr)
 
 #ifdef CONFIG_32BIT
-/*
- * No 'sd' or 'ld' instructions in 32-bit but the code will
- * do the correct thing
- */
-#define user_sd(reg, addr)             user_sw(reg, addr)
-#define user_ld(reg, addr)             user_lw(reg, addr)
+#define user_sd(reg, addr)             kernel_sw(reg, addr)
+#define user_ld(reg, addr)             kernel_lw(reg, addr)
 #else
-#define user_sd(reg, addr)             sd reg, addr
-#define user_ld(reg, addr)             ld reg, addr
+#define user_sd(reg, addr)             kernel_sd(reg, addr)
+#define user_ld(reg, addr)             kernel_sd(reg, addr)
 #endif /* CONFIG_32BIT */
 
 #endif /* CONFIG_EVA */
index 8038647..0ef39ad 100644 (file)
        .set push
        SET_HARDFLOAT
        cfc1    \tmp,  fcr31
-       swc1    $f0,  THREAD_FPR0(\thread)
-       swc1    $f1,  THREAD_FPR1(\thread)
-       swc1    $f2,  THREAD_FPR2(\thread)
-       swc1    $f3,  THREAD_FPR3(\thread)
-       swc1    $f4,  THREAD_FPR4(\thread)
-       swc1    $f5,  THREAD_FPR5(\thread)
-       swc1    $f6,  THREAD_FPR6(\thread)
-       swc1    $f7,  THREAD_FPR7(\thread)
-       swc1    $f8,  THREAD_FPR8(\thread)
-       swc1    $f9,  THREAD_FPR9(\thread)
-       swc1    $f10, THREAD_FPR10(\thread)
-       swc1    $f11, THREAD_FPR11(\thread)
-       swc1    $f12, THREAD_FPR12(\thread)
-       swc1    $f13, THREAD_FPR13(\thread)
-       swc1    $f14, THREAD_FPR14(\thread)
-       swc1    $f15, THREAD_FPR15(\thread)
-       swc1    $f16, THREAD_FPR16(\thread)
-       swc1    $f17, THREAD_FPR17(\thread)
-       swc1    $f18, THREAD_FPR18(\thread)
-       swc1    $f19, THREAD_FPR19(\thread)
-       swc1    $f20, THREAD_FPR20(\thread)
-       swc1    $f21, THREAD_FPR21(\thread)
-       swc1    $f22, THREAD_FPR22(\thread)
-       swc1    $f23, THREAD_FPR23(\thread)
-       swc1    $f24, THREAD_FPR24(\thread)
-       swc1    $f25, THREAD_FPR25(\thread)
-       swc1    $f26, THREAD_FPR26(\thread)
-       swc1    $f27, THREAD_FPR27(\thread)
-       swc1    $f28, THREAD_FPR28(\thread)
-       swc1    $f29, THREAD_FPR29(\thread)
-       swc1    $f30, THREAD_FPR30(\thread)
-       swc1    $f31, THREAD_FPR31(\thread)
+       s.d     $f0,  THREAD_FPR0(\thread)
+       s.d     $f2,  THREAD_FPR2(\thread)
+       s.d     $f4,  THREAD_FPR4(\thread)
+       s.d     $f6,  THREAD_FPR6(\thread)
+       s.d     $f8,  THREAD_FPR8(\thread)
+       s.d     $f10, THREAD_FPR10(\thread)
+       s.d     $f12, THREAD_FPR12(\thread)
+       s.d     $f14, THREAD_FPR14(\thread)
+       s.d     $f16, THREAD_FPR16(\thread)
+       s.d     $f18, THREAD_FPR18(\thread)
+       s.d     $f20, THREAD_FPR20(\thread)
+       s.d     $f22, THREAD_FPR22(\thread)
+       s.d     $f24, THREAD_FPR24(\thread)
+       s.d     $f26, THREAD_FPR26(\thread)
+       s.d     $f28, THREAD_FPR28(\thread)
+       s.d     $f30, THREAD_FPR30(\thread)
        sw      \tmp, THREAD_FCR31(\thread)
        .set pop
        .endm
        .set push
        SET_HARDFLOAT
        lw      \tmp, THREAD_FCR31(\thread)
-       lwc1    $f0,  THREAD_FPR0(\thread)
-       lwc1    $f1,  THREAD_FPR1(\thread)
-       lwc1    $f2,  THREAD_FPR2(\thread)
-       lwc1    $f3,  THREAD_FPR3(\thread)
-       lwc1    $f4,  THREAD_FPR4(\thread)
-       lwc1    $f5,  THREAD_FPR5(\thread)
-       lwc1    $f6,  THREAD_FPR6(\thread)
-       lwc1    $f7,  THREAD_FPR7(\thread)
-       lwc1    $f8,  THREAD_FPR8(\thread)
-       lwc1    $f9,  THREAD_FPR9(\thread)
-       lwc1    $f10, THREAD_FPR10(\thread)
-       lwc1    $f11, THREAD_FPR11(\thread)
-       lwc1    $f12, THREAD_FPR12(\thread)
-       lwc1    $f13, THREAD_FPR13(\thread)
-       lwc1    $f14, THREAD_FPR14(\thread)
-       lwc1    $f15, THREAD_FPR15(\thread)
-       lwc1    $f16, THREAD_FPR16(\thread)
-       lwc1    $f17, THREAD_FPR17(\thread)
-       lwc1    $f18, THREAD_FPR18(\thread)
-       lwc1    $f19, THREAD_FPR19(\thread)
-       lwc1    $f20, THREAD_FPR20(\thread)
-       lwc1    $f21, THREAD_FPR21(\thread)
-       lwc1    $f22, THREAD_FPR22(\thread)
-       lwc1    $f23, THREAD_FPR23(\thread)
-       lwc1    $f24, THREAD_FPR24(\thread)
-       lwc1    $f25, THREAD_FPR25(\thread)
-       lwc1    $f26, THREAD_FPR26(\thread)
-       lwc1    $f27, THREAD_FPR27(\thread)
-       lwc1    $f28, THREAD_FPR28(\thread)
-       lwc1    $f29, THREAD_FPR29(\thread)
-       lwc1    $f30, THREAD_FPR30(\thread)
-       lwc1    $f31, THREAD_FPR31(\thread)
+       l.d     $f0,  THREAD_FPR0(\thread)
+       l.d     $f2,  THREAD_FPR2(\thread)
+       l.d     $f4,  THREAD_FPR4(\thread)
+       l.d     $f6,  THREAD_FPR6(\thread)
+       l.d     $f8,  THREAD_FPR8(\thread)
+       l.d     $f10, THREAD_FPR10(\thread)
+       l.d     $f12, THREAD_FPR12(\thread)
+       l.d     $f14, THREAD_FPR14(\thread)
+       l.d     $f16, THREAD_FPR16(\thread)
+       l.d     $f18, THREAD_FPR18(\thread)
+       l.d     $f20, THREAD_FPR20(\thread)
+       l.d     $f22, THREAD_FPR22(\thread)
+       l.d     $f24, THREAD_FPR24(\thread)
+       l.d     $f26, THREAD_FPR26(\thread)
+       l.d     $f28, THREAD_FPR28(\thread)
+       l.d     $f30, THREAD_FPR30(\thread)
        ctc1    \tmp, fcr31
        .set pop
        .endm
index 9f935f6..0cf29bd 100644 (file)
@@ -481,7 +481,7 @@ static inline unsigned long __fls(unsigned long word)
 {
        int num;
 
-       if (BITS_PER_LONG == 32 &&
+       if (BITS_PER_LONG == 32 && !__builtin_constant_p(word) &&
            __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
                __asm__(
                "       .set    push                                    \n"
@@ -494,7 +494,7 @@ static inline unsigned long __fls(unsigned long word)
                return 31 - num;
        }
 
-       if (BITS_PER_LONG == 64 &&
+       if (BITS_PER_LONG == 64 && !__builtin_constant_p(word) &&
            __builtin_constant_p(cpu_has_mips64) && cpu_has_mips64) {
                __asm__(
                "       .set    push                                    \n"
@@ -559,7 +559,8 @@ static inline int fls(int x)
 {
        int r;
 
-       if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
+       if (!__builtin_constant_p(x) &&
+           __builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) {
                __asm__(
                "       .set    push                                    \n"
                "       .set    "MIPS_ISA_LEVEL"                        \n"
index 30939b0..6d25ad3 100644 (file)
@@ -122,6 +122,22 @@ static inline void bmips_write_zscm_reg(unsigned int offset, unsigned long data)
        barrier();
 }
 
+static inline void bmips_post_dma_flush(struct device *dev)
+{
+       void __iomem *cbr = BMIPS_GET_CBR();
+       u32 cfg;
+
+       if (boot_cpu_type() != CPU_BMIPS3300 &&
+           boot_cpu_type() != CPU_BMIPS4350 &&
+           boot_cpu_type() != CPU_BMIPS4380)
+               return;
+
+       /* Flush stale data out of the readahead cache */
+       cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
+       __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
+       __raw_readl(cbr + BMIPS_RAC_CONFIG);
+}
+
 #endif /* !defined(__ASSEMBLY__) */
 
 #endif /* _ASM_BMIPS_H */
index e08381a..723229f 100644 (file)
  *  - flush_icache_all() flush the entire instruction cache
  *  - flush_data_cache_page() flushes a page from the data cache
  */
+
+ /*
+ * This flag is used to indicate that the page pointed to by a pte
+ * is dirty and requires cleaning before returning it to the user.
+ */
+#define PG_dcache_dirty                        PG_arch_1
+
+#define Page_dcache_dirty(page)                \
+       test_bit(PG_dcache_dirty, &(page)->flags)
+#define SetPageDcacheDirty(page)       \
+       set_bit(PG_dcache_dirty, &(page)->flags)
+#define ClearPageDcacheDirty(page)     \
+       clear_bit(PG_dcache_dirty, &(page)->flags)
+
 extern void (*flush_cache_all)(void);
 extern void (*__flush_cache_all)(void);
 extern void (*flush_cache_mm)(struct mm_struct *mm);
@@ -37,13 +51,15 @@ extern void (*flush_cache_range)(struct vm_area_struct *vma,
        unsigned long start, unsigned long end);
 extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
 extern void __flush_dcache_page(struct page *page);
+extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page);
 
 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
 static inline void flush_dcache_page(struct page *page)
 {
-       if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc)
+       if (cpu_has_dc_aliases)
                __flush_dcache_page(page);
-
+       else if (!cpu_has_ic_fills_f_dc)
+               SetPageDcacheDirty(page);
 }
 
 #define flush_dcache_mmap_lock(mapping)                do { } while (0)
@@ -61,6 +77,11 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
 static inline void flush_icache_page(struct vm_area_struct *vma,
        struct page *page)
 {
+       if (!cpu_has_ic_fills_f_dc && (vma->vm_flags & VM_EXEC) &&
+           Page_dcache_dirty(page)) {
+               __flush_icache_page(vma, page);
+               ClearPageDcacheDirty(page);
+       }
 }
 
 extern void (*flush_icache_range)(unsigned long start, unsigned long end);
@@ -95,19 +116,6 @@ extern void (*flush_icache_all)(void);
 extern void (*local_flush_data_cache_page)(void * addr);
 extern void (*flush_data_cache_page)(unsigned long addr);
 
-/*
- * This flag is used to indicate that the page pointed to by a pte
- * is dirty and requires cleaning before returning it to the user.
- */
-#define PG_dcache_dirty                        PG_arch_1
-
-#define Page_dcache_dirty(page)                \
-       test_bit(PG_dcache_dirty, &(page)->flags)
-#define SetPageDcacheDirty(page)       \
-       set_bit(PG_dcache_dirty, &(page)->flags)
-#define ClearPageDcacheDirty(page)     \
-       clear_bit(PG_dcache_dirty, &(page)->flags)
-
 /* Run kernel code uncached, useful for cache probing functions. */
 unsigned long run_uncached(void *func);
 
diff --git a/arch/mips/include/asm/cdmm.h b/arch/mips/include/asm/cdmm.h
new file mode 100644 (file)
index 0000000..16e22ce
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2014 Imagination Technologies Ltd.
+ */
+#ifndef __ASM_CDMM_H
+#define __ASM_CDMM_H
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+/**
+ * struct mips_cdmm_device - Represents a single device on a CDMM bus.
+ * @dev:       Driver model device object.
+ * @cpu:       CPU which can access this device.
+ * @res:       MMIO resource.
+ * @type:      Device type identifier.
+ * @rev:       Device revision number.
+ */
+struct mips_cdmm_device {
+       struct device           dev;
+       unsigned int            cpu;
+       struct resource         res;
+       unsigned int            type;
+       unsigned int            rev;
+};
+
+/**
+ * struct mips_cdmm_driver - Represents a driver for a CDMM device.
+ * @drv:       Driver model driver object.
+ * @probe      Callback for probing newly discovered devices.
+ * @remove:    Callback to remove the device.
+ * @shutdown:  Callback on system shutdown.
+ * @cpu_down:  Callback when the parent CPU is going down.
+ *             Any CPU pinned threads/timers should be disabled.
+ * @cpu_up:    Callback when the parent CPU is coming back up again.
+ *             CPU pinned threads/timers can be restarted.
+ * @id_table:  Table for CDMM IDs to match against.
+ */
+struct mips_cdmm_driver {
+       struct device_driver    drv;
+       int                     (*probe)(struct mips_cdmm_device *);
+       int                     (*remove)(struct mips_cdmm_device *);
+       void                    (*shutdown)(struct mips_cdmm_device *);
+       int                     (*cpu_down)(struct mips_cdmm_device *);
+       int                     (*cpu_up)(struct mips_cdmm_device *);
+       const struct mips_cdmm_device_id *id_table;
+};
+
+/**
+ * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.
+ *
+ * Picking a suitable physical address at which to map the CDMM region is
+ * platform specific, so this weak function can be defined by platform code to
+ * pick a suitable value if none is configured by the bootloader.
+ *
+ * This address must be 32kB aligned, and the region occupies a maximum of 32kB
+ * of physical address space which must not be used for anything else.
+ *
+ * Returns:    Physical base address for CDMM region, or 0 on failure.
+ */
+phys_addr_t __weak mips_cdmm_phys_base(void);
+
+extern struct bus_type mips_cdmm_bustype;
+void __iomem *mips_cdmm_early_probe(unsigned int dev_type);
+
+#define to_mips_cdmm_device(d) container_of(d, struct mips_cdmm_device, dev)
+
+#define mips_cdmm_get_drvdata(d)       dev_get_drvdata(&d->dev)
+#define mips_cdmm_set_drvdata(d, p)    dev_set_drvdata(&d->dev, p)
+
+int mips_cdmm_driver_register(struct mips_cdmm_driver *);
+void mips_cdmm_driver_unregister(struct mips_cdmm_driver *);
+
+/*
+ * module_mips_cdmm_driver() - Helper macro for drivers that don't do
+ * anything special in module init/exit.  This eliminates a lot of
+ * boilerplate.  Each module may only use this macro once, and
+ * calling it replaces module_init() and module_exit()
+ */
+#define module_mips_cdmm_driver(__mips_cdmm_driver) \
+       module_driver(__mips_cdmm_driver, mips_cdmm_driver_register, \
+                       mips_cdmm_driver_unregister)
+
+/* drivers/tty/mips_ejtag_fdc.c */
+
+#ifdef CONFIG_MIPS_EJTAG_FDC_EARLYCON
+int setup_early_fdc_console(void);
+#else
+static inline int setup_early_fdc_console(void)
+{
+       return -ENODEV;
+}
+#endif
+
+#endif /* __ASM_CDMM_H */
index 65f9bdd..f0edf6f 100644 (file)
@@ -27,23 +27,4 @@ irqreturn_t c0_compare_interrupt(int, void *);
 extern struct irqaction c0_compare_irqaction;
 extern int cp0_timer_irq_installed;
 
-/*
- * Possibly handle a performance counter interrupt.
- * Return true if the timer interrupt should not be checked
- */
-
-static inline int handle_perf_irq(int r2)
-{
-       /*
-        * The performance counter overflow interrupt may be shared with the
-        * timer interrupt (cp0_perfcount_irq < 0). If it is and a
-        * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
-        * and we can't reliably determine if a counter interrupt has also
-        * happened (!r2) then don't check for a timer interrupt.
-        */
-       return (cp0_perfcount_irq < 0) &&
-               perf_irq() == IRQ_HANDLED &&
-               !r2;
-}
-
 #endif /* __ASM_CEVT_R4K_H */
index 5c585c5..3ceacde 100644 (file)
@@ -218,6 +218,8 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
                                          __u32 len, unsigned short proto,
                                          __wsum sum)
 {
+       __wsum tmp;
+
        __asm__(
        "       .set    push            # csum_ipv6_magic\n"
        "       .set    noreorder       \n"
@@ -270,9 +272,9 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
 
        "       addu    %0, $1          # Add final carry\n"
        "       .set    pop"
-       : "=r" (sum), "=r" (proto)
+       : "=&r" (sum), "=&r" (tmp)
        : "r" (saddr), "r" (daddr),
-         "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
+         "0" (htonl(len)), "r" (htonl(proto)), "r" (sum));
 
        return csum_fold(sum);
 }
index d0a2a68..412f945 100644 (file)
@@ -229,21 +229,22 @@ extern void __cmpxchg_called_with_bad_pointer(void);
 #define cmpxchg(ptr, old, new)         __cmpxchg(ptr, old, new, smp_mb__before_llsc(), smp_llsc_mb())
 #define cmpxchg_local(ptr, old, new)   __cmpxchg(ptr, old, new, , )
 
-#define cmpxchg64(ptr, o, n)                                           \
+#ifdef CONFIG_64BIT
+#define cmpxchg64_local(ptr, o, n)                                     \
   ({                                                                   \
        BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
-       cmpxchg((ptr), (o), (n));                                       \
+       cmpxchg_local((ptr), (o), (n));                                 \
   })
 
-#ifdef CONFIG_64BIT
-#define cmpxchg64_local(ptr, o, n)                                     \
+#define cmpxchg64(ptr, o, n)                                           \
   ({                                                                   \
        BUILD_BUG_ON(sizeof(*(ptr)) != 8);                              \
-       cmpxchg_local((ptr), (o), (n));                                 \
+       cmpxchg((ptr), (o), (n));                                       \
   })
 #else
 #include <asm-generic/cmpxchg-local.h>
 #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
 #endif
 
 #endif /* __ASM_CMPXCHG_H */
index 0d8208d..5aeaf19 100644 (file)
@@ -68,6 +68,7 @@
 #ifndef cpu_has_octeon_cache
 #define cpu_has_octeon_cache   0
 #endif
+/* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work.  */
 #ifndef cpu_has_fpu
 #define cpu_has_fpu            (current_cpu_data.options & MIPS_CPU_FPU)
 #define raw_cpu_has_fpu                (raw_current_cpu_data.options & MIPS_CPU_FPU)
 # endif
 #endif
 
+#ifndef cpu_has_xpa
+#define cpu_has_xpa            (cpu_data[0].options & MIPS_CPU_XPA)
+#endif
 #ifndef cpu_has_vtag_icache
 #define cpu_has_vtag_icache    (cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
 #endif
 #define cpu_has_mips_4_5_r     (cpu_has_mips_4 | cpu_has_mips_5_r)
 #define cpu_has_mips_5_r       (cpu_has_mips_5 | cpu_has_mips_r)
 
-#define cpu_has_mips_4_5_r2_r6 (cpu_has_mips_4_5 | cpu_has_mips_r2 | \
-                                cpu_has_mips_r6)
+#define cpu_has_mips_3_4_5_64_r2_r6                                    \
+                               (cpu_has_mips_3 | cpu_has_mips_4_5_64_r2_r6)
+#define cpu_has_mips_4_5_64_r2_r6                                      \
+                               (cpu_has_mips_4_5 | cpu_has_mips64r1 |  \
+                                cpu_has_mips_r2 | cpu_has_mips_r6)
 
 #define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2 | cpu_has_mips32r6)
 #define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2 | cpu_has_mips64r6)
 /* MIPSR2 and MIPSR6 have a lot of similarities */
 #define cpu_has_mips_r2_r6     (cpu_has_mips_r2 | cpu_has_mips_r6)
 
+/*
+ * cpu_has_mips_r2_exec_hazard - return if IHB is required on current processor
+ *
+ * Returns non-zero value if the current processor implementation requires
+ * an IHB instruction to deal with an instruction hazard as per MIPS R2
+ * architecture specification, zero otherwise.
+ */
 #ifndef cpu_has_mips_r2_exec_hazard
-#define cpu_has_mips_r2_exec_hazard (cpu_has_mips_r2 | cpu_has_mips_r6)
+#define cpu_has_mips_r2_exec_hazard                                    \
+({                                                                     \
+       int __res;                                                      \
+                                                                       \
+       switch (current_cpu_type()) {                                   \
+       case CPU_M14KC:                                                 \
+       case CPU_74K:                                                   \
+       case CPU_1074K:                                                 \
+       case CPU_PROAPTIV:                                              \
+       case CPU_P5600:                                                 \
+       case CPU_M5150:                                                 \
+       case CPU_QEMU_GENERIC:                                          \
+       case CPU_CAVIUM_OCTEON:                                         \
+       case CPU_CAVIUM_OCTEON_PLUS:                                    \
+       case CPU_CAVIUM_OCTEON2:                                        \
+       case CPU_CAVIUM_OCTEON3:                                        \
+               __res = 0;                                              \
+               break;                                                  \
+                                                                       \
+       default:                                                        \
+               __res = 1;                                              \
+       }                                                               \
+                                                                       \
+       __res;                                                          \
+})
 #endif
 
 /*
 # define cpu_has_fre           (cpu_data[0].options & MIPS_CPU_FRE)
 #endif
 
+#ifndef cpu_has_cdmm
+# define cpu_has_cdmm          (cpu_data[0].options & MIPS_CPU_CDMM)
+#endif
+
 #endif /* __ASM_CPU_FEATURES_H */
index c3f4f2d..e7dc785 100644 (file)
@@ -49,6 +49,8 @@ struct cpuinfo_mips {
        unsigned int            udelay_val;
        unsigned int            processor_id;
        unsigned int            fpu_id;
+       unsigned int            fpu_csr31;
+       unsigned int            fpu_msk31;
        unsigned int            msa_id;
        unsigned int            cputype;
        int                     isa_level;
index 8245875..33f3cab 100644 (file)
@@ -157,6 +157,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
        case CPU_R10000:
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
 #endif
 #ifdef CONFIG_SYS_HAS_CPU_RM7000
        case CPU_RM7000:
index 1568723..e3adca1 100644 (file)
@@ -67,7 +67,7 @@
 #define PRID_IMP_R4300         0x0b00
 #define PRID_IMP_VR41XX                0x0c00
 #define PRID_IMP_R12000                0x0e00
-#define PRID_IMP_R14000                0x0f00
+#define PRID_IMP_R14000                0x0f00          /* R14K && R16K */
 #define PRID_IMP_R8000         0x1000
 #define PRID_IMP_PR4450                0x1200
 #define PRID_IMP_R4600         0x2000
@@ -284,8 +284,8 @@ enum cpu_type_enum {
        CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310,
        CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650,
        CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000,
-       CPU_R12000, CPU_R14000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, CPU_VR4122,
-       CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
+       CPU_R12000, CPU_R14000, CPU_R16000, CPU_VR41XX, CPU_VR4111, CPU_VR4121,
+       CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000,
        CPU_SR71000, CPU_TX49XX,
 
        /*
@@ -377,6 +377,8 @@ enum cpu_type_enum {
 #define MIPS_CPU_MAAR          0x400000000ull /* MAAR(I) registers are present */
 #define MIPS_CPU_FRE           0x800000000ull /* FRE & UFE bits implemented */
 #define MIPS_CPU_RW_LLB                0x1000000000ull /* LLADDR/LLB writes are allowed */
+#define MIPS_CPU_XPA           0x2000000000ull /* CPU supports Extended Physical Addressing */
+#define MIPS_CPU_CDMM          0x4000000000ull /* CPU has Common Device Memory Map */
 
 /*
  * CPU ASE encodings
index 06412aa..fd1b4a1 100644 (file)
@@ -23,7 +23,7 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
        if (!dev->dma_mask)
-               return 0;
+               return false;
 
        return addr + size <= *dev->dma_mask;
 }
index 31d747d..a594d8e 100644 (file)
@@ -11,6 +11,9 @@
 #include <linux/fs.h>
 #include <uapi/linux/elf.h>
 
+#include <asm/cpu-info.h>
+#include <asm/current.h>
+
 /* ELF header e_flags defines. */
 /* MIPS architecture level. */
 #define EF_MIPS_ARCH_1         0x00000000      /* -mips1 code.  */
@@ -294,9 +297,14 @@ do {                                                                       \
        if (personality(current->personality) != PER_LINUX)             \
                set_personality(PER_LINUX);                             \
                                                                        \
+       clear_thread_flag(TIF_HYBRID_FPREGS);                           \
+       set_thread_flag(TIF_32BIT_FPREGS);                              \
+                                                                       \
        mips_set_personality_fp(state);                                 \
                                                                        \
        current->thread.abi = &mips_abi;                                \
+                                                                       \
+       current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31;         \
 } while (0)
 
 #endif /* CONFIG_32BIT */
@@ -319,6 +327,8 @@ do {                                                                        \
        do {                                                            \
                set_thread_flag(TIF_32BIT_REGS);                        \
                set_thread_flag(TIF_32BIT_ADDR);                        \
+               clear_thread_flag(TIF_HYBRID_FPREGS);                   \
+               set_thread_flag(TIF_32BIT_FPREGS);                      \
                                                                        \
                mips_set_personality_fp(state);                         \
                                                                        \
@@ -356,6 +366,8 @@ do {                                                                        \
        else                                                            \
                current->thread.abi = &mips_abi;                        \
                                                                        \
+       current->thread.fpu.fcr31 = current_cpu_data.fpu_csr31;         \
+                                                                       \
        p = personality(current->personality);                          \
        if (p != PER_LINUX32 && p != PER_LINUX)                         \
                set_personality(PER_LINUX);                             \
index b104ad9..084780b 100644 (file)
@@ -30,7 +30,7 @@
 struct sigcontext;
 struct sigcontext32;
 
-extern void _init_fpu(void);
+extern void _init_fpu(unsigned int);
 extern void _save_fp(struct task_struct *);
 extern void _restore_fp(struct task_struct *);
 
@@ -188,6 +188,7 @@ static inline void lose_fpu(int save)
 
 static inline int init_fpu(void)
 {
+       unsigned int fcr31 = current->thread.fpu.fcr31;
        int ret = 0;
 
        if (cpu_has_fpu) {
@@ -198,7 +199,7 @@ static inline int init_fpu(void)
                        return ret;
 
                if (!cpu_has_fre) {
-                       _init_fpu();
+                       _init_fpu(fcr31);
 
                        return 0;
                }
@@ -212,7 +213,7 @@ static inline int init_fpu(void)
                config5 = clear_c0_config5(MIPS_CONF5_FRE);
                enable_fpu_hazard();
 
-               _init_fpu();
+               _init_fpu(fcr31);
 
                /* Restore FRE */
                write_c0_config5(config5);
index 3ee3477..2f021cd 100644 (file)
@@ -44,6 +44,7 @@ struct mips_fpu_emulator_stats {
        unsigned long ieee754_overflow;
        unsigned long ieee754_zerodiv;
        unsigned long ieee754_invalidop;
+       unsigned long ds_emul;
 };
 
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
@@ -65,7 +66,8 @@ extern int do_dsemulret(struct pt_regs *xcp);
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
                                    struct mips_fpu_struct *ctx, int has_fpu,
                                    void *__user *fault_addr);
-int process_fpemu_return(int sig, void __user *fault_addr);
+int process_fpemu_return(int sig, void __user *fault_addr,
+                        unsigned long fcr31);
 int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
                     unsigned long *contpc);
 
@@ -86,8 +88,6 @@ static inline void fpu_emulator_init_fpu(void)
        struct task_struct *t = current;
        int i;
 
-       t->thread.fpu.fcr31 = 0;
-
        for (i = 0; i < 32; i++)
                set_fpr64(&t->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
 }
index 5a4e1bb..f0db99f 100644 (file)
@@ -47,6 +47,9 @@ extern void free_irqno(unsigned int irq);
 extern int cp0_compare_irq;
 extern int cp0_compare_irq_shift;
 extern int cp0_perfcount_irq;
+extern int cp0_fdc_irq;
+
+extern int __weak get_c0_fdc_int(void);
 
 void arch_trigger_all_cpu_backtrace(bool);
 #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
diff --git a/arch/mips/include/asm/mach-ar7/war.h b/arch/mips/include/asm/mach-ar7/war.h
deleted file mode 100644 (file)
index 99071e5..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_AR7_WAR_H
-#define __ASM_MIPS_MACH_AR7_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_AR7_WAR_H */
index d8009c9..d5defdd 100644 (file)
@@ -59,16 +59,6 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-                                        dma_addr_t dma_addr)
-{
-       return 0;
-}
-
 static inline int plat_device_is_coherent(struct device *dev)
 {
 #ifdef CONFIG_DMA_COHERENT
@@ -79,4 +69,8 @@ static inline int plat_device_is_coherent(struct device *dev)
 #endif
 }
 
+static inline void plat_post_dma_flush(struct device *dev)
+{
+}
+
 #endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-ath25/war.h b/arch/mips/include/asm/mach-ath25/war.h
deleted file mode 100644 (file)
index e3a5250..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
- */
-#ifndef __ASM_MACH_ATH25_WAR_H
-#define __ASM_MACH_ATH25_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define RM9000_CDEX_SMP_WAR            0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MACH_ATH25_WAR_H */
diff --git a/arch/mips/include/asm/mach-ath79/war.h b/arch/mips/include/asm/mach-ath79/war.h
deleted file mode 100644 (file)
index 0bb3090..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MACH_ATH79_WAR_H
-#define __ASM_MACH_ATH79_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MACH_ATH79_WAR_H */
diff --git a/arch/mips/include/asm/mach-au1x00/war.h b/arch/mips/include/asm/mach-au1x00/war.h
deleted file mode 100644 (file)
index 72e260d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_AU1X00_WAR_H
-#define __ASM_MIPS_MACH_AU1X00_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_AU1X00_WAR_H */
diff --git a/arch/mips/include/asm/mach-bcm3384/war.h b/arch/mips/include/asm/mach-bcm3384/war.h
deleted file mode 100644 (file)
index 59d7599..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_BCM3384_WAR_H
-#define __ASM_MIPS_MACH_BCM3384_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_BCM3384_WAR_H */
index 7527c1d..8ed77f6 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ssb/ssb.h>
 #include <linux/bcma/bcma.h>
 #include <linux/bcma/bcma_soc.h>
+#include <linux/bcm47xx_nvram.h>
 
 enum bcm47xx_bus_type {
 #ifdef CONFIG_BCM47XX_SSB
index 1f5643b..c41d1dc 100644 (file)
@@ -67,6 +67,7 @@ enum bcm47xx_board {
        BCM47XX_BOARD_LINKSYS_WRT150NV11,
        BCM47XX_BOARD_LINKSYS_WRT160NV1,
        BCM47XX_BOARD_LINKSYS_WRT160NV3,
+       BCM47XX_BOARD_LINKSYS_WRT300N_V1,
        BCM47XX_BOARD_LINKSYS_WRT300NV11,
        BCM47XX_BOARD_LINKSYS_WRT310NV1,
        BCM47XX_BOARD_LINKSYS_WRT310NV2,
@@ -74,6 +75,7 @@ enum bcm47xx_board {
        BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101,
        BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467,
        BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708,
+       BCM47XX_BOARD_LINKSYS_WRT600N_V11,
        BCM47XX_BOARD_LINKSYS_WRT610NV1,
        BCM47XX_BOARD_LINKSYS_WRT610NV2,
        BCM47XX_BOARD_LINKSYS_WRTSL54GS,
@@ -86,9 +88,11 @@ enum bcm47xx_board {
 
        BCM47XX_BOARD_NETGEAR_WGR614V8,
        BCM47XX_BOARD_NETGEAR_WGR614V9,
+       BCM47XX_BOARD_NETGEAR_WGR614_V10,
        BCM47XX_BOARD_NETGEAR_WNDR3300,
        BCM47XX_BOARD_NETGEAR_WNDR3400V1,
        BCM47XX_BOARD_NETGEAR_WNDR3400V2,
+       BCM47XX_BOARD_NETGEAR_WNDR3400_V3,
        BCM47XX_BOARD_NETGEAR_WNDR3400VCNA,
        BCM47XX_BOARD_NETGEAR_WNDR3700V3,
        BCM47XX_BOARD_NETGEAR_WNDR4000,
diff --git a/arch/mips/include/asm/mach-bcm47xx/war.h b/arch/mips/include/asm/mach-bcm47xx/war.h
deleted file mode 100644 (file)
index a3d2f44..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_BCM47XX_WAR_H
-#define __ASM_MIPS_MACH_BCM47XX_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_BCM47XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/dma-coherence.h b/arch/mips/include/asm/mach-bcm63xx/dma-coherence.h
new file mode 100644 (file)
index 0000000..11d3b57
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __ASM_MACH_BCM63XX_DMA_COHERENCE_H
+#define __ASM_MACH_BCM63XX_DMA_COHERENCE_H
+
+#include <asm/bmips.h>
+
+#define plat_post_dma_flush    bmips_post_dma_flush
+
+#include <asm/mach-generic/dma-coherence.h>
+
+#endif /* __ASM_MACH_BCM63XX_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/war.h b/arch/mips/include/asm/mach-bcm63xx/war.h
deleted file mode 100644 (file)
index 05ee867..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_BCM63XX_WAR_H
-#define __ASM_MIPS_MACH_BCM63XX_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_BCM63XX_WAR_H */
  * GNU General Public License for more details.
  */
 
-#ifndef __ASM_MACH_BCM3384_DMA_COHERENCE_H
-#define __ASM_MACH_BCM3384_DMA_COHERENCE_H
+#ifndef __ASM_MACH_BMIPS_DMA_COHERENCE_H
+#define __ASM_MACH_BMIPS_DMA_COHERENCE_H
+
+#include <asm/bmips.h>
+#include <asm/cpu-type.h>
+#include <asm/cpu.h>
 
 struct device;
 
@@ -45,4 +49,6 @@ static inline int plat_device_is_coherent(struct device *dev)
        return 0;
 }
 
-#endif /* __ASM_MACH_BCM3384_DMA_COHERENCE_H */
+#define plat_post_dma_flush    bmips_post_dma_flush
+
+#endif /* __ASM_MACH_BMIPS_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-bmips/spaces.h b/arch/mips/include/asm/mach-bmips/spaces.h
new file mode 100644 (file)
index 0000000..1b05bdd
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1999, 2000, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2002  Maciej W. Rozycki
+ * Copyright (C) 1990, 1999, 2000 Silicon Graphics, Inc.
+ */
+#ifndef _ASM_BMIPS_SPACES_H
+#define _ASM_BMIPS_SPACES_H
+
+/* Avoid collisions with system base register (SBR) region on BMIPS3300 */
+#define FIXADDR_TOP            ((unsigned long)(long)(int)0xff000000)
+
+#include <asm/mach-generic/spaces.h>
+
+#endif /* __ASM_BMIPS_SPACES_H */
index fa1f3cf..d68e685 100644 (file)
@@ -50,7 +50,6 @@
 #define cpu_has_mips32r2       0
 #define cpu_has_mips64r1       0
 #define cpu_has_mips64r2       1
-#define cpu_has_mips_r2_exec_hazard 0
 #define cpu_has_dsp            0
 #define cpu_has_dsp2           0
 #define cpu_has_mipsmt         0
index f9f4486..460042e 100644 (file)
@@ -57,6 +57,10 @@ static inline int plat_device_is_coherent(struct device *dev)
        return 1;
 }
 
+static inline void plat_post_dma_flush(struct device *dev)
+{
+}
+
 dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr);
 phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr);
 
diff --git a/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h b/arch/mips/include/asm/mach-cavium-octeon/mangle-port.h
new file mode 100644 (file)
index 0000000..374eefa
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ */
+#ifndef __ASM_MACH_GENERIC_MANGLE_PORT_H
+#define __ASM_MACH_GENERIC_MANGLE_PORT_H
+
+#include <asm/byteorder.h>
+
+#ifdef __BIG_ENDIAN
+
+# define __swizzle_addr_b(port)        (port)
+# define __swizzle_addr_w(port)        (port)
+# define __swizzle_addr_l(port)        (port)
+# define __swizzle_addr_q(port)        (port)
+
+#else /* __LITTLE_ENDIAN */
+
+static inline bool __should_swizzle_addr(unsigned long p)
+{
+       /* boot bus? */
+       return ((p >> 40) & 0xff) == 0;
+}
+
+# define __swizzle_addr_b(port)        \
+       (__should_swizzle_addr(port) ? (port) ^ 7 : (port))
+# define __swizzle_addr_w(port)        \
+       (__should_swizzle_addr(port) ? (port) ^ 6 : (port))
+# define __swizzle_addr_l(port)        \
+       (__should_swizzle_addr(port) ? (port) ^ 4 : (port))
+# define __swizzle_addr_q(port)        (port)
+
+#endif /* __BIG_ENDIAN */
+
+/*
+ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
+ * less sane hardware forces software to fiddle with this...
+ *
+ * Regardless, if the host bus endianness mismatches that of PCI/ISA, then
+ * you can't have the numerical value of data and byte addresses within
+ * multibyte quantities both preserved at the same time.  Hence two
+ * variations of functions: non-prefixed ones that preserve the value
+ * and prefixed ones that preserve byte addresses.  The latters are
+ * typically used for moving raw data between a peripheral and memory (cf.
+ * string I/O functions), hence the "__mem_" prefix.
+ */
+#if defined(CONFIG_SWAP_IO_SPACE)
+
+# define ioswabb(a, x)         (x)
+# define __mem_ioswabb(a, x)   (x)
+# define ioswabw(a, x)         le16_to_cpu(x)
+# define __mem_ioswabw(a, x)   (x)
+# define ioswabl(a, x)         le32_to_cpu(x)
+# define __mem_ioswabl(a, x)   (x)
+# define ioswabq(a, x)         le64_to_cpu(x)
+# define __mem_ioswabq(a, x)   (x)
+
+#else
+
+# define ioswabb(a, x)         (x)
+# define __mem_ioswabb(a, x)   (x)
+# define ioswabw(a, x)         (x)
+# define __mem_ioswabw(a, x)   cpu_to_le16(x)
+# define ioswabl(a, x)         (x)
+# define __mem_ioswabl(a, x)   cpu_to_le32(x)
+# define ioswabq(a, x)         (x)
+# define __mem_ioswabq(a, x)   cpu_to_le32(x)
+
+#endif
+
+#endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */
index 71d4bfa..30c5cd9 100644 (file)
@@ -14,7 +14,6 @@
 #define cpu_has_3k_cache       0
 #define cpu_has_4k_cache       1
 #define cpu_has_tx39_cache     0
-#define cpu_has_fpu            1
 #define cpu_has_32fpr          1
 #define cpu_has_counter                1
 #define cpu_has_watch          0
diff --git a/arch/mips/include/asm/mach-cobalt/war.h b/arch/mips/include/asm/mach-cobalt/war.h
deleted file mode 100644 (file)
index 34ae404..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_COBALT_WAR_H
-#define __ASM_MIPS_MACH_COBALT_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_COBALT_WAR_H */
index acce27f..bdf045f 100644 (file)
@@ -15,7 +15,6 @@
 /* Generic ones first.  */
 #define cpu_has_tlb                    1
 #define cpu_has_tx39_cache             0
-#define cpu_has_fpu                    1
 #define cpu_has_divec                  0
 #define cpu_has_prefetch               0
 #define cpu_has_mcheck                 0
diff --git a/arch/mips/include/asm/mach-dec/war.h b/arch/mips/include/asm/mach-dec/war.h
deleted file mode 100644 (file)
index d29996f..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_DEC_WAR_H
-#define __ASM_MIPS_MACH_DEC_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_DEC_WAR_H */
diff --git a/arch/mips/include/asm/mach-emma2rh/war.h b/arch/mips/include/asm/mach-emma2rh/war.h
deleted file mode 100644 (file)
index 79ae82d..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_EMMA2RH_WAR_H
-#define __ASM_MIPS_MACH_EMMA2RH_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_EMMA2RH_WAR_H */
index 7629c35..0f8a354 100644 (file)
@@ -52,6 +52,12 @@ static inline int plat_device_is_coherent(struct device *dev)
        return coherentio;
 }
 
+#ifndef plat_post_dma_flush
+static inline void plat_post_dma_flush(struct device *dev)
+{
+}
+#endif
+
 #ifdef CONFIG_SWIOTLB
 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
similarity index 86%
rename from arch/mips/include/asm/mach-ralink/war.h
rename to arch/mips/include/asm/mach-generic/war.h
index c074b5d..a1bc2e7 100644 (file)
@@ -5,8 +5,8 @@
  *
  * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
  */
-#ifndef __ASM_MACH_RALINK_WAR_H
-#define __ASM_MACH_RALINK_WAR_H
+#ifndef __ASM_MACH_GENERIC_WAR_H
+#define __ASM_MACH_GENERIC_WAR_H
 
 #define R4600_V1_INDEX_ICACHEOP_WAR    0
 #define R4600_V1_HIT_CACHEOP_WAR       0
@@ -21,4 +21,4 @@
 #define R10000_LLSC_WAR                        0
 #define MIPS34K_MISSED_ITLB_WAR                0
 
-#endif /* __ASM_MACH_RALINK_WAR_H */
+#endif /* __ASM_MACH_GENERIC_WAR_H */
index 1dfe474..9b19b72 100644 (file)
@@ -16,7 +16,6 @@
 #define cpu_has_tlb            1
 #define cpu_has_4kex           1
 #define cpu_has_4k_cache       1
-#define cpu_has_fpu            1
 #define cpu_has_32fpr          1
 #define cpu_has_counter                1
 #define cpu_has_mips16         0
index 4ffddfd..1daa644 100644 (file)
@@ -58,6 +58,10 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
+static inline void plat_post_dma_flush(struct device *dev)
+{
+}
+
 static inline int plat_device_is_coherent(struct device *dev)
 {
        return 1;               /* IP27 non-cohernet mode is unsupported */
index 2e1ec6c..241409b 100644 (file)
@@ -26,7 +26,6 @@
 /* Settings which are common for all ip32 CPUs */
 #define cpu_has_tlb            1
 #define cpu_has_4kex           1
-#define cpu_has_fpu            1
 #define cpu_has_32fpr          1
 #define cpu_has_counter                1
 #define cpu_has_mips16         0
index 104cfbc..0a0b0e2 100644 (file)
@@ -80,6 +80,10 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
+static inline void plat_post_dma_flush(struct device *dev)
+{
+}
+
 static inline int plat_device_is_coherent(struct device *dev)
 {
        return 0;               /* IP32 is non-cohernet */
index 949003e..dc347c2 100644 (file)
@@ -48,6 +48,10 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
        return 1;
 }
 
+static inline void plat_post_dma_flush(struct device *dev)
+{
+}
+
 static inline int plat_device_is_coherent(struct device *dev)
 {
        return 0;
diff --git a/arch/mips/include/asm/mach-jazz/war.h b/arch/mips/include/asm/mach-jazz/war.h
deleted file mode 100644 (file)
index 5b18b9a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_JAZZ_WAR_H
-#define __ASM_MIPS_MACH_JAZZ_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_JAZZ_WAR_H */
diff --git a/arch/mips/include/asm/mach-jz4740/war.h b/arch/mips/include/asm/mach-jz4740/war.h
deleted file mode 100644 (file)
index 9b511d3..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_JZ4740_WAR_H
-#define __ASM_MIPS_MACH_JZ4740_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_JZ4740_WAR_H */
diff --git a/arch/mips/include/asm/mach-lantiq/war.h b/arch/mips/include/asm/mach-lantiq/war.h
deleted file mode 100644 (file)
index 358ca97..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- */
-#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H
-#define __ASM_MIPS_MACH_LANTIQ_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif
diff --git a/arch/mips/include/asm/mach-lasat/war.h b/arch/mips/include/asm/mach-lasat/war.h
deleted file mode 100644 (file)
index 741ae72..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_LASAT_WAR_H
-#define __ASM_MIPS_MACH_LASAT_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_LASAT_WAR_H */
index 6d69332..acc3768 100644 (file)
@@ -34,7 +34,6 @@
 #define cpu_has_dsp            0
 #define cpu_has_dsp2           0
 #define cpu_has_ejtag          0
-#define cpu_has_fpu            1
 #define cpu_has_ic_fills_f_dc  0
 #define cpu_has_inclusive_pcaches      1
 #define cpu_has_llsc           1
index a905341..4bf4e19 100644 (file)
@@ -78,4 +78,8 @@ static inline int plat_device_is_coherent(struct device *dev)
 #endif /* CONFIG_DMA_NONCOHERENT */
 }
 
+static inline void plat_post_dma_flush(struct device *dev)
+{
+}
+
 #endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */
index 5459ac0..9783103 100644 (file)
@@ -255,6 +255,10 @@ static inline void do_perfcnt_IRQ(void)
 extern u64 loongson_chipcfg[MAX_PACKAGES];
 #define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id]))
 
+/* Chip Temperature registor of each physical cpu package, PRid >= Loongson-3A */
+extern u64 loongson_chiptemp[MAX_PACKAGES];
+#define LOONGSON_CHIPTEMP(id) (*(volatile u32 *)(loongson_chiptemp[id]))
+
 /* Freq Control register of each physical cpu package, PRid >= Loongson-3B */
 extern u64 loongson_freqctrl[MAX_PACKAGES];
 #define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id]))
diff --git a/arch/mips/include/asm/mach-loongson/war.h b/arch/mips/include/asm/mach-loongson/war.h
deleted file mode 100644 (file)
index f2570df..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MACH_LOONGSON_WAR_H
-#define __ASM_MACH_LOONGSON_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MACH_LEMOTE_WAR_H */
diff --git a/arch/mips/include/asm/mach-loongson1/war.h b/arch/mips/include/asm/mach-loongson1/war.h
deleted file mode 100644 (file)
index 8fb50d0..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MACH_LOONGSON1_WAR_H
-#define __ASM_MACH_LOONGSON1_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MACH_LOONGSON1_WAR_H */
index 9ed8dac..8bdf47e 100644 (file)
 #endif
 
 #define NLM_THREADS_PER_CORE   4
-#ifdef CONFIG_CPU_XLR
-#define nlm_cores_per_node()   8
-#else
-extern unsigned int xlp_cores_per_node;
-#define nlm_cores_per_node()   xlp_cores_per_node
-#endif
-
-#define nlm_threads_per_node() (nlm_cores_per_node() * NLM_THREADS_PER_CORE)
-#define nlm_cpuid_to_node(c)   ((c) / nlm_threads_per_node())
 
 struct nlm_soc_info {
        unsigned long   coremask;       /* cores enabled on the soc */
diff --git a/arch/mips/include/asm/mach-netlogic/topology.h b/arch/mips/include/asm/mach-netlogic/topology.h
deleted file mode 100644 (file)
index 0eb43c8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2013 Broadcom Corporation
- */
-#ifndef _ASM_MACH_NETLOGIC_TOPOLOGY_H
-#define _ASM_MACH_NETLOGIC_TOPOLOGY_H
-
-#include <asm/mach-netlogic/multi-node.h>
-
-#include <asm-generic/topology.h>
-
-#endif /* _ASM_MACH_NETLOGIC_TOPOLOGY_H */
diff --git a/arch/mips/include/asm/mach-netlogic/war.h b/arch/mips/include/asm/mach-netlogic/war.h
deleted file mode 100644 (file)
index 2c72168..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2011 Netlogic Microsystems.
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_NLM_WAR_H
-#define __ASM_MIPS_MACH_NLM_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_NLM_WAR_H */
diff --git a/arch/mips/include/asm/mach-paravirt/war.h b/arch/mips/include/asm/mach-paravirt/war.h
deleted file mode 100644 (file)
index 36d3afb..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- * Copyright (C) 2013 Cavium Networks <support@caviumnetworks.com>
- */
-#ifndef __ASM_MIPS_MACH_PARAVIRT_WAR_H
-#define __ASM_MIPS_MACH_PARAVIRT_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_PARAVIRT_WAR_H */
diff --git a/arch/mips/include/asm/mach-pistachio/gpio.h b/arch/mips/include/asm/mach-pistachio/gpio.h
new file mode 100644 (file)
index 0000000..6c1649c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Pistachio IRQ setup
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_PISTACHIO_GPIO_H
+#define __ASM_MACH_PISTACHIO_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep  __gpio_cansleep
+#define gpio_to_irq    __gpio_to_irq
+
+#endif /* __ASM_MACH_PISTACHIO_GPIO_H */
diff --git a/arch/mips/include/asm/mach-pistachio/irq.h b/arch/mips/include/asm/mach-pistachio/irq.h
new file mode 100644 (file)
index 0000000..b94a09a
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Pistachio IRQ setup
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_PISTACHIO_IRQ_H
+#define __ASM_MACH_PISTACHIO_IRQ_H
+
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_PISTACHIO_IRQ_H */
diff --git a/arch/mips/include/asm/mach-pnx833x/war.h b/arch/mips/include/asm/mach-pnx833x/war.h
deleted file mode 100644 (file)
index e410df4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_PNX833X_WAR_H
-#define __ASM_MIPS_MACH_PNX833X_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_PNX833X_WAR_H */
index f095c52..98cf404 100644 (file)
@@ -15,7 +15,6 @@
 #define cpu_has_tlb            1
 #define cpu_has_4kex           1
 #define cpu_has_4k_cache       1
-#define cpu_has_fpu            1
 #define cpu_has_32fpr          1
 #define cpu_has_counter                1
 #define cpu_has_watch          0
diff --git a/arch/mips/include/asm/mach-tx39xx/war.h b/arch/mips/include/asm/mach-tx39xx/war.h
deleted file mode 100644 (file)
index 6a52e65..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_TX39XX_WAR_H
-#define __ASM_MIPS_MACH_TX39XX_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_TX39XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-vr41xx/war.h b/arch/mips/include/asm/mach-vr41xx/war.h
deleted file mode 100644 (file)
index ffe31e7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_VR41XX_WAR_H
-#define __ASM_MIPS_MACH_VR41XX_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR    0
-#define R4600_V1_HIT_CACHEOP_WAR       0
-#define R4600_V2_HIT_CACHEOP_WAR       0
-#define R5432_CP0_INTERRUPT_WAR                0
-#define BCM1250_M3_WAR                 0
-#define SIBYTE_1956_WAR                        0
-#define MIPS4K_ICACHE_REFILL_WAR       0
-#define MIPS_CACHE_SYNC_WAR            0
-#define TX49XX_ICACHE_INDEX_INV_WAR    0
-#define ICACHE_REFILLS_WORKAROUND_WAR  0
-#define R10000_LLSC_WAR                        0
-#define MIPS34K_MISSED_ITLB_WAR                0
-
-#endif /* __ASM_MIPS_MACH_VR41XX_WAR_H */
diff --git a/arch/mips/include/asm/mips-boards/sead3-addr.h b/arch/mips/include/asm/mips-boards/sead3-addr.h
new file mode 100644 (file)
index 0000000..c0db578
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2015 Imagination Technologies, Inc.
+ *   written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_BOARDS_SEAD3_ADDR_H
+#define __ASM_MIPS_BOARDS_SEAD3_ADDR_H
+
+/*
+ * Target #0 Register Decode
+ */
+#define SEAD3_SD_SPDCNF                                0xbb000040
+#define SEAD3_SD_SPADDR                                0xbb000048
+#define SEAD3_SD_DATA                          0xbb000050
+
+/*
+ * Target #1 Register Decode
+ */
+#define SEAD3_CFG                              0xbb100110
+#define SEAD3_GIC_BASE_ADDRESS                 0xbb1c0000
+#define SEAD3_SHARED_SECTION                   0xbb1c0000
+#define SEAD3_VPE_LOCAL_SECTION                        0xbb1c8000
+#define SEAD3_VPE_OTHER_SECTION                        0xbb1cc000
+#define SEAD3_USER_MODE_VISIBLE_SECTION                0xbb1d0000
+
+/*
+ * Target #3 Register Decode
+ */
+#define SEAD3_USB_HS_BASE                      0xbb200000
+#define SEAD3_USB_HS_IDENTIFICATION_REGS       0xbb200000
+#define SEAD3_USB_HS_CAPABILITY_REGS           0xbb200100
+#define SEAD3_USB_HS_OPERATIONAL_REGS          0xbb200140
+#define SEAD3_RESERVED                         0xbe800000
+
+/*
+ * Target #3 Register Decode
+ */
+#define SEAD3_SRAM                             0xbe000000
+#define SEAD3_OPTIONAL_SRAM                    0xbe400000
+#define SEAD3_FPGA                             0xbf000000
+
+#define SEAD3_PI_PIC32_USB_STATUS              0xbf000060
+#define   SEAD3_PI_PIC32_USB_STATUS_IO_RDY     (1 << 0)
+#define   SEAD3_PI_PIC32_USB_STATUS_SPL_INT    (1 << 1)
+#define   SEAD3_PI_PIC32_USB_STATUS_GPIOA_INT  (1 << 2)
+#define   SEAD3_PI_PIC32_USB_STATUS_GPIOB_INT  (1 << 3)
+
+#define SEAD3_PI_SOFT_ENDIAN                   0xbf000070
+
+#define SEAD3_CPLD_P_SWITCH                    0xbf000200
+#define SEAD3_CPLD_F_SWITCH                    0xbf000208
+#define SEAD3_CPLD_P_LED                       0xbf000210
+#define SEAD3_CPLD_F_LED                       0xbf000218
+#define SEAD3_NEWSC_LIVE                       0xbf000220
+#define SEAD3_NEWSC_REG                                0xbf000228
+#define SEAD3_NEWSC_CTRL                       0xbf000230
+
+#define SEAD3_LCD_CONTROL                      0xbf000400
+#define SEAD3_LCD_DATA                         0xbf000408
+#define SEAD3_CPLD_LCD_STATUS                  0xbf000410
+#define SEAD3_CPLD_LCD_DATA                    0xbf000418
+
+#define SEAD3_CPLD_PI_DEVRST                   0xbf000480
+#define SEAD3_CPLD_PI_DEVRST_IC32_RST          (1 << 0)
+#define SEAD3_RESERVED_0                       0xbf000500
+
+#define SEAD3_PIC32_REGISTERS                  0xbf000600
+#define SEAD3_RESERVED_1                       0xbf000700
+#define SEAD3_UART_CH_0                                0xbf000800
+#define SEAD3_UART_CH_1                                0xbf000900
+#define SEAD3_RESERVED_2                       0xbf000a00
+#define SEAD3_ETHERNET                         0xbf010000
+#define SEAD3_RESERVED_3                       0xbf020000
+#define SEAD3_USER_EXPANSION                   0xbf400000
+#define SEAD3_RESERVED_4                       0xbf800000
+#define SEAD3_BOOT_FLASH_EXTENSION             0xbfa00000
+#define SEAD3_BOOT_FLASH                       0xbfc00000
+#define SEAD3_REVISION_REGISTER                        0xbfc00010
+
+#endif /* __ASM_MIPS_BOARDS_SEAD3_ADDR_H  */
index 60570f2..4b89f28 100644 (file)
@@ -84,11 +84,16 @@ extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
 
 #ifndef CONFIG_MIPSR2_TO_R6_EMULATOR
 static int mipsr2_emulation;
-static __maybe_unused int mipsr2_decoder(struct pt_regs *regs, u32 inst) { return 0; };
+static inline int mipsr2_decoder(struct pt_regs *regs, u32 inst,
+                                unsigned long *fcr31)
+{
+       return 0;
+};
 #else
 /* MIPS R2 Emulator ON/OFF */
 extern int mipsr2_emulation;
-extern int mipsr2_decoder(struct pt_regs *regs, u32 inst);
+extern int mipsr2_decoder(struct pt_regs *regs, u32 inst,
+                         unsigned long *fcr31);
 #endif /* CONFIG_MIPSR2_TO_R6_EMULATOR */
 
 #define NO_R6EMU       (cpu_has_mips_r6 && !mipsr2_emulation)
index fef0044..764e275 100644 (file)
  */
 #define CP0_TX39_CACHE $7
 
-/*
- * Coprocessor 1 (FPU) register names
- */
-#define CP1_REVISION   $0
-#define CP1_STATUS     $31
-
-/*
- * FPU Status Register Values
- */
-/*
- * Status Register Values
- */
-
-#define FPU_CSR_FLUSH  0x01000000      /* flush denormalised results to 0 */
-#define FPU_CSR_COND   0x00800000      /* $fcc0 */
-#define FPU_CSR_COND0  0x00800000      /* $fcc0 */
-#define FPU_CSR_COND1  0x02000000      /* $fcc1 */
-#define FPU_CSR_COND2  0x04000000      /* $fcc2 */
-#define FPU_CSR_COND3  0x08000000      /* $fcc3 */
-#define FPU_CSR_COND4  0x10000000      /* $fcc4 */
-#define FPU_CSR_COND5  0x20000000      /* $fcc5 */
-#define FPU_CSR_COND6  0x40000000      /* $fcc6 */
-#define FPU_CSR_COND7  0x80000000      /* $fcc7 */
-
-/*
- * Bits 18 - 20 of the FPU Status Register will be read as 0,
- * and should be written as zero.
- */
-#define FPU_CSR_RSVD   0x001c0000
-
-/*
- * X the exception cause indicator
- * E the exception enable
- * S the sticky/flag bit
-*/
-#define FPU_CSR_ALL_X  0x0003f000
-#define FPU_CSR_UNI_X  0x00020000
-#define FPU_CSR_INV_X  0x00010000
-#define FPU_CSR_DIV_X  0x00008000
-#define FPU_CSR_OVF_X  0x00004000
-#define FPU_CSR_UDF_X  0x00002000
-#define FPU_CSR_INE_X  0x00001000
-
-#define FPU_CSR_ALL_E  0x00000f80
-#define FPU_CSR_INV_E  0x00000800
-#define FPU_CSR_DIV_E  0x00000400
-#define FPU_CSR_OVF_E  0x00000200
-#define FPU_CSR_UDF_E  0x00000100
-#define FPU_CSR_INE_E  0x00000080
-
-#define FPU_CSR_ALL_S  0x0000007c
-#define FPU_CSR_INV_S  0x00000040
-#define FPU_CSR_DIV_S  0x00000020
-#define FPU_CSR_OVF_S  0x00000010
-#define FPU_CSR_UDF_S  0x00000008
-#define FPU_CSR_INE_S  0x00000004
-
-/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
-#define FPU_CSR_RM     0x00000003
-#define FPU_CSR_RN     0x0     /* nearest */
-#define FPU_CSR_RZ     0x1     /* towards zero */
-#define FPU_CSR_RU     0x2     /* towards +Infinity */
-#define FPU_CSR_RD     0x3     /* towards -Infinity */
-
 
 /*
  * Values for PageMask register
 #define ST0_MX                 0x01000000
 
 /*
- * Bitfields in the TX39 family CP0 Configuration Register 3
- */
-#define TX39_CONF_ICS_SHIFT    19
-#define TX39_CONF_ICS_MASK     0x00380000
-#define TX39_CONF_ICS_1KB      0x00000000
-#define TX39_CONF_ICS_2KB      0x00080000
-#define TX39_CONF_ICS_4KB      0x00100000
-#define TX39_CONF_ICS_8KB      0x00180000
-#define TX39_CONF_ICS_16KB     0x00200000
-
-#define TX39_CONF_DCS_SHIFT    16
-#define TX39_CONF_DCS_MASK     0x00070000
-#define TX39_CONF_DCS_1KB      0x00000000
-#define TX39_CONF_DCS_2KB      0x00010000
-#define TX39_CONF_DCS_4KB      0x00020000
-#define TX39_CONF_DCS_8KB      0x00030000
-#define TX39_CONF_DCS_16KB     0x00040000
-
-#define TX39_CONF_CWFON                0x00004000
-#define TX39_CONF_WBON         0x00002000
-#define TX39_CONF_RF_SHIFT     10
-#define TX39_CONF_RF_MASK      0x00000c00
-#define TX39_CONF_DOZE         0x00000200
-#define TX39_CONF_HALT         0x00000100
-#define TX39_CONF_LOCK         0x00000080
-#define TX39_CONF_ICE          0x00000020
-#define TX39_CONF_DCE          0x00000010
-#define TX39_CONF_IRSIZE_SHIFT 2
-#define TX39_CONF_IRSIZE_MASK  0x0000000c
-#define TX39_CONF_DRSIZE_SHIFT 0
-#define TX39_CONF_DRSIZE_MASK  0x00000003
-
-/*
  * Status register bits available in all MIPS CPUs.
  */
 #define ST0_IM                 0x0000ff00
 
 /*
  * Bitfields and bit numbers in the coprocessor 0 IntCtl register. (MIPSR2)
- *
- * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
  */
+#define INTCTLB_IPFDC          23
+#define INTCTLF_IPFDC          (_ULCAST_(7) << INTCTLB_IPFDC)
 #define INTCTLB_IPPCI          26
 #define INTCTLF_IPPCI          (_ULCAST_(7) << INTCTLB_IPPCI)
 #define INTCTLB_IPTI           29
  *
  * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
  */
-#define         CAUSEB_EXCCODE         2
-#define         CAUSEF_EXCCODE         (_ULCAST_(31)  <<  2)
-#define         CAUSEB_IP              8
-#define         CAUSEF_IP              (_ULCAST_(255) <<  8)
+#define CAUSEB_EXCCODE         2
+#define CAUSEF_EXCCODE         (_ULCAST_(31)  <<  2)
+#define CAUSEB_IP              8
+#define CAUSEF_IP              (_ULCAST_(255) <<  8)
 #define         CAUSEB_IP0             8
 #define         CAUSEF_IP0             (_ULCAST_(1)   <<  8)
 #define         CAUSEB_IP1             9
 #define         CAUSEF_IP6             (_ULCAST_(1)   << 14)
 #define         CAUSEB_IP7             15
 #define         CAUSEF_IP7             (_ULCAST_(1)   << 15)
-#define         CAUSEB_IV              23
-#define         CAUSEF_IV              (_ULCAST_(1)   << 23)
-#define         CAUSEB_PCI             26
-#define         CAUSEF_PCI             (_ULCAST_(1)   << 26)
-#define         CAUSEB_CE              28
-#define         CAUSEF_CE              (_ULCAST_(3)   << 28)
-#define         CAUSEB_TI              30
-#define         CAUSEF_TI              (_ULCAST_(1)   << 30)
-#define         CAUSEB_BD              31
-#define         CAUSEF_BD              (_ULCAST_(1)   << 31)
+#define CAUSEB_FDCI            21
+#define CAUSEF_FDCI            (_ULCAST_(1)   << 21)
+#define CAUSEB_IV              23
+#define CAUSEF_IV              (_ULCAST_(1)   << 23)
+#define CAUSEB_PCI             26
+#define CAUSEF_PCI             (_ULCAST_(1)   << 26)
+#define CAUSEB_CE              28
+#define CAUSEF_CE              (_ULCAST_(3)   << 28)
+#define CAUSEB_TI              30
+#define CAUSEF_TI              (_ULCAST_(1)   << 30)
+#define CAUSEB_BD              31
+#define CAUSEF_BD              (_ULCAST_(1)   << 31)
 
 /*
  * Bits in the coprocessor 0 config register.
 #define MIPS_CMGCRF_BASE       (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))
 
 /*
- * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
- */
-#define MIPS_FPIR_S            (_ULCAST_(1) << 16)
-#define MIPS_FPIR_D            (_ULCAST_(1) << 17)
-#define MIPS_FPIR_PS           (_ULCAST_(1) << 18)
-#define MIPS_FPIR_3D           (_ULCAST_(1) << 19)
-#define MIPS_FPIR_W            (_ULCAST_(1) << 20)
-#define MIPS_FPIR_L            (_ULCAST_(1) << 21)
-#define MIPS_FPIR_F64          (_ULCAST_(1) << 22)
-#define MIPS_FPIR_FREP         (_ULCAST_(1) << 29)
-
-/*
  * Bits in the MIPS32 Memory Segmentation registers.
  */
 #define MIPS_SEGCFG_PA_SHIFT   9
 #define MIPS_PWCTL_PSN_SHIFT   0
 #define MIPS_PWCTL_PSN_MASK    0x0000003f
 
+/* CDMMBase register bit definitions */
+#define MIPS_CDMMBASE_SIZE_SHIFT 0
+#define MIPS_CDMMBASE_SIZE     (_ULCAST_(511) << MIPS_CDMMBASE_SIZE_SHIFT)
+#define MIPS_CDMMBASE_CI       (_ULCAST_(1) << 9)
+#define MIPS_CDMMBASE_EN       (_ULCAST_(1) << 10)
+#define MIPS_CDMMBASE_ADDR_SHIFT 11
+#define MIPS_CDMMBASE_ADDR_START 15
+
+/*
+ * Bitfields in the TX39 family CP0 Configuration Register 3
+ */
+#define TX39_CONF_ICS_SHIFT    19
+#define TX39_CONF_ICS_MASK     0x00380000
+#define TX39_CONF_ICS_1KB      0x00000000
+#define TX39_CONF_ICS_2KB      0x00080000
+#define TX39_CONF_ICS_4KB      0x00100000
+#define TX39_CONF_ICS_8KB      0x00180000
+#define TX39_CONF_ICS_16KB     0x00200000
+
+#define TX39_CONF_DCS_SHIFT    16
+#define TX39_CONF_DCS_MASK     0x00070000
+#define TX39_CONF_DCS_1KB      0x00000000
+#define TX39_CONF_DCS_2KB      0x00010000
+#define TX39_CONF_DCS_4KB      0x00020000
+#define TX39_CONF_DCS_8KB      0x00030000
+#define TX39_CONF_DCS_16KB     0x00040000
+
+#define TX39_CONF_CWFON                0x00004000
+#define TX39_CONF_WBON         0x00002000
+#define TX39_CONF_RF_SHIFT     10
+#define TX39_CONF_RF_MASK      0x00000c00
+#define TX39_CONF_DOZE         0x00000200
+#define TX39_CONF_HALT         0x00000100
+#define TX39_CONF_LOCK         0x00000080
+#define TX39_CONF_ICE          0x00000020
+#define TX39_CONF_DCE          0x00000010
+#define TX39_CONF_IRSIZE_SHIFT 2
+#define TX39_CONF_IRSIZE_MASK  0x0000000c
+#define TX39_CONF_DRSIZE_SHIFT 0
+#define TX39_CONF_DRSIZE_MASK  0x00000003
+
+
+/*
+ * Coprocessor 1 (FPU) register names
+ */
+#define CP1_REVISION   $0
+#define CP1_UFR                $1
+#define CP1_UNFR       $4
+#define CP1_FCCR       $25
+#define CP1_FEXR       $26
+#define CP1_FENR       $28
+#define CP1_STATUS     $31
+
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
+ */
+#define MIPS_FPIR_S            (_ULCAST_(1) << 16)
+#define MIPS_FPIR_D            (_ULCAST_(1) << 17)
+#define MIPS_FPIR_PS           (_ULCAST_(1) << 18)
+#define MIPS_FPIR_3D           (_ULCAST_(1) << 19)
+#define MIPS_FPIR_W            (_ULCAST_(1) << 20)
+#define MIPS_FPIR_L            (_ULCAST_(1) << 21)
+#define MIPS_FPIR_F64          (_ULCAST_(1) << 22)
+#define MIPS_FPIR_HAS2008      (_ULCAST_(1) << 23)
+#define MIPS_FPIR_UFRP         (_ULCAST_(1) << 28)
+#define MIPS_FPIR_FREP         (_ULCAST_(1) << 29)
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) condition codes register.
+ */
+#define MIPS_FCCR_CONDX_S      0
+#define MIPS_FCCR_CONDX                (_ULCAST_(255) << MIPS_FCCR_CONDX_S)
+#define MIPS_FCCR_COND0_S      0
+#define MIPS_FCCR_COND0                (_ULCAST_(1) << MIPS_FCCR_COND0_S)
+#define MIPS_FCCR_COND1_S      1
+#define MIPS_FCCR_COND1                (_ULCAST_(1) << MIPS_FCCR_COND1_S)
+#define MIPS_FCCR_COND2_S      2
+#define MIPS_FCCR_COND2                (_ULCAST_(1) << MIPS_FCCR_COND2_S)
+#define MIPS_FCCR_COND3_S      3
+#define MIPS_FCCR_COND3                (_ULCAST_(1) << MIPS_FCCR_COND3_S)
+#define MIPS_FCCR_COND4_S      4
+#define MIPS_FCCR_COND4                (_ULCAST_(1) << MIPS_FCCR_COND4_S)
+#define MIPS_FCCR_COND5_S      5
+#define MIPS_FCCR_COND5                (_ULCAST_(1) << MIPS_FCCR_COND5_S)
+#define MIPS_FCCR_COND6_S      6
+#define MIPS_FCCR_COND6                (_ULCAST_(1) << MIPS_FCCR_COND6_S)
+#define MIPS_FCCR_COND7_S      7
+#define MIPS_FCCR_COND7                (_ULCAST_(1) << MIPS_FCCR_COND7_S)
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) enables register.
+ */
+#define MIPS_FENR_FS_S         2
+#define MIPS_FENR_FS           (_ULCAST_(1) << MIPS_FENR_FS_S)
+
+/*
+ * FPU Status Register Values
+ */
+#define FPU_CSR_COND_S 23                                      /* $fcc0 */
+#define FPU_CSR_COND   (_ULCAST_(1) << FPU_CSR_COND_S)
+
+#define FPU_CSR_FS_S   24              /* flush denormalised results to 0 */
+#define FPU_CSR_FS     (_ULCAST_(1) << FPU_CSR_FS_S)
+
+#define FPU_CSR_CONDX_S        25                                      /* $fcc[7:1] */
+#define FPU_CSR_CONDX  (_ULCAST_(127) << FPU_CSR_CONDX_S)
+#define FPU_CSR_COND1_S        25                                      /* $fcc1 */
+#define FPU_CSR_COND1  (_ULCAST_(1) << FPU_CSR_COND1_S)
+#define FPU_CSR_COND2_S        26                                      /* $fcc2 */
+#define FPU_CSR_COND2  (_ULCAST_(1) << FPU_CSR_COND2_S)
+#define FPU_CSR_COND3_S        27                                      /* $fcc3 */
+#define FPU_CSR_COND3  (_ULCAST_(1) << FPU_CSR_COND3_S)
+#define FPU_CSR_COND4_S        28                                      /* $fcc4 */
+#define FPU_CSR_COND4  (_ULCAST_(1) << FPU_CSR_COND4_S)
+#define FPU_CSR_COND5_S        29                                      /* $fcc5 */
+#define FPU_CSR_COND5  (_ULCAST_(1) << FPU_CSR_COND5_S)
+#define FPU_CSR_COND6_S        30                                      /* $fcc6 */
+#define FPU_CSR_COND6  (_ULCAST_(1) << FPU_CSR_COND6_S)
+#define FPU_CSR_COND7_S        31                                      /* $fcc7 */
+#define FPU_CSR_COND7  (_ULCAST_(1) << FPU_CSR_COND7_S)
+
+/*
+ * Bits 22:20 of the FPU Status Register will be read as 0,
+ * and should be written as zero.
+ */
+#define FPU_CSR_RSVD   (_ULCAST_(7) << 20)
+
+#define FPU_CSR_ABS2008        (_ULCAST_(1) << 19)
+#define FPU_CSR_NAN2008        (_ULCAST_(1) << 18)
+
+/*
+ * X the exception cause indicator
+ * E the exception enable
+ * S the sticky/flag bit
+*/
+#define FPU_CSR_ALL_X  0x0003f000
+#define FPU_CSR_UNI_X  0x00020000
+#define FPU_CSR_INV_X  0x00010000
+#define FPU_CSR_DIV_X  0x00008000
+#define FPU_CSR_OVF_X  0x00004000
+#define FPU_CSR_UDF_X  0x00002000
+#define FPU_CSR_INE_X  0x00001000
+
+#define FPU_CSR_ALL_E  0x00000f80
+#define FPU_CSR_INV_E  0x00000800
+#define FPU_CSR_DIV_E  0x00000400
+#define FPU_CSR_OVF_E  0x00000200
+#define FPU_CSR_UDF_E  0x00000100
+#define FPU_CSR_INE_E  0x00000080
+
+#define FPU_CSR_ALL_S  0x0000007c
+#define FPU_CSR_INV_S  0x00000040
+#define FPU_CSR_DIV_S  0x00000020
+#define FPU_CSR_OVF_S  0x00000010
+#define FPU_CSR_UDF_S  0x00000008
+#define FPU_CSR_INE_S  0x00000004
+
+/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
+#define FPU_CSR_RM     0x00000003
+#define FPU_CSR_RN     0x0     /* nearest */
+#define FPU_CSR_RZ     0x1     /* towards zero */
+#define FPU_CSR_RU     0x2     /* towards +Infinity */
+#define FPU_CSR_RD     0x3     /* towards -Infinity */
+
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -1282,6 +1341,9 @@ do {                                                                      \
 #define read_c0_ebase()                __read_32bit_c0_register($15, 1)
 #define write_c0_ebase(val)    __write_32bit_c0_register($15, 1, val)
 
+#define read_c0_cdmmbase()     __read_ulong_c0_register($15, 2)
+#define write_c0_cdmmbase(val) __write_ulong_c0_register($15, 2, val)
+
 /* MIPSR3 */
 #define read_c0_segctl0()      __read_32bit_c0_register($5, 2)
 #define write_c0_segctl0(val)  __write_32bit_c0_register($5, 2, val)
index c281f03..2a4c128 100644 (file)
@@ -111,6 +111,25 @@ static inline int nlm_irq_to_xirq(int node, int irq)
        return node * NR_IRQS / NLM_NR_NODES + irq;
 }
 
-extern int nlm_cpu_ready[];
+#ifdef CONFIG_CPU_XLR
+#define nlm_cores_per_node()   8
+#else
+static inline int nlm_cores_per_node(void)
+{
+       return ((read_c0_prid() & PRID_IMP_MASK)
+                               == PRID_IMP_NETLOGIC_XLP9XX) ? 32 : 8;
+}
 #endif
+static inline int nlm_threads_per_node(void)
+{
+       return nlm_cores_per_node() * NLM_THREADS_PER_CORE;
+}
+
+static inline int nlm_hwtid_to_node(int hwtid)
+{
+       return hwtid / nlm_threads_per_node();
+}
+
+extern int nlm_cpu_ready[];
+#endif /* __ASSEMBLY__ */
 #endif /* _NETLOGIC_COMMON_H_ */
index 06f1f75..788baf3 100644 (file)
@@ -157,7 +157,13 @@ static inline int nlm_nodeid(void)
 
 static inline unsigned int nlm_core_id(void)
 {
-       return (read_c0_ebase() & 0x1c) >> 2;
+       uint32_t prid = read_c0_prid() & PRID_IMP_MASK;
+
+       if ((prid == PRID_IMP_NETLOGIC_XLP9XX) ||
+                       (prid == PRID_IMP_NETLOGIC_XLP5XX))
+               return (read_c0_ebase() & 0x7c) >> 2;
+       else
+               return (read_c0_ebase() & 0x1c) >> 2;
 }
 
 static inline unsigned int nlm_thread_id(void)
index 6d2e58a..a06b592 100644 (file)
@@ -46,6 +46,8 @@
 #define CPU_BLOCKID_FPU                9
 #define CPU_BLOCKID_MAP                10
 
+#define IFU_BRUB_RESERVE       0x007
+
 #define ICU_DEFEATURE          0x100
 
 #define LSU_DEFEATURE          0x304
index bc7bddf..6bcf395 100644 (file)
 #define SYS_9XX_CLK_DEV_DIV                    0x18d
 #define SYS_9XX_CLK_DEV_CHG                    0x18f
 
+#define SYS_9XX_CLK_DEV_SEL_REG                        0x1a4
+#define SYS_9XX_CLK_DEV_DIV_REG                        0x1a6
+
 /* Registers changed on 9XX */
 #define SYS_9XX_POWER_ON_RESET_CFG             0x00
 #define SYS_9XX_CHIP_RESET                     0x01
index a862b93..feb6ed8 100644 (file)
@@ -52,6 +52,7 @@
 #define PIC_2XX_XHCI_2_IRQ             25
 #define PIC_9XX_XHCI_0_IRQ             23
 #define PIC_9XX_XHCI_1_IRQ             24
+#define PIC_9XX_XHCI_2_IRQ             25
 
 #define PIC_MMC_IRQ                    29
 #define PIC_I2C_0_IRQ                  30
@@ -89,7 +90,7 @@ void xlp_wakeup_secondary_cpus(void);
 
 void xlp_mmu_init(void);
 void nlm_hal_init(void);
-int xlp_get_dram_map(int n, uint64_t *dram_map);
+int nlm_get_dram_map(int node, uint64_t *dram_map, int nentries);
 
 struct pci_dev;
 int xlp_socdev_to_node(const struct pci_dev *dev);
index e2d874e..e4444f8 100644 (file)
@@ -104,6 +104,7 @@ typedef enum {
 typedef union {
 
        uint64_t u64;
+#ifdef __BIG_ENDIAN_BITFIELD
        /* mapped or unmapped virtual address */
        struct {
                uint64_t R:2;
@@ -202,6 +203,72 @@ typedef union {
                uint64_t didspace:24;
                uint64_t unused:40;
        } sfilldidspace;
+#else
+       struct {
+               uint64_t offset:62;
+               uint64_t R:2;
+       } sva;
+
+       struct {
+               uint64_t offset:31;
+               uint64_t zeroes:33;
+       } suseg;
+
+       struct {
+               uint64_t offset:29;
+               uint64_t sp:2;
+               uint64_t ones:33;
+       } sxkseg;
+
+       struct {
+               uint64_t pa:49;
+               uint64_t mbz:10;
+               uint64_t cca:3;
+               uint64_t R:2;
+       } sxkphys;
+
+       struct {
+               uint64_t offset:36;
+               uint64_t unaddr:4;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t mbz:15;
+       } sphys;
+
+       struct {
+               uint64_t offset:36;
+               uint64_t unaddr:4;
+               uint64_t zeroes:24;
+       } smem;
+
+       struct {
+               uint64_t offset:36;
+               uint64_t unaddr:4;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t mbz:13;
+               uint64_t mem_region:2;
+       } sio;
+
+       struct {
+               uint64_t addr:13;
+               cvmx_add_win_dec_t csrdec:2;
+               uint64_t ones:49;
+       } sscr;
+
+       struct {
+               uint64_t addr:7;
+               uint64_t type:3;
+               uint64_t unused2:3;
+               uint64_t csrdec:2;
+               uint64_t ones:49;
+       } sdma;
+
+       struct {
+               uint64_t unused:40;
+               uint64_t didspace:24;
+       } sfilldidspace;
+#endif
 
 } cvmx_addr_t;
 
index 2298199..c373d95 100644 (file)
@@ -53,6 +53,7 @@
  * to 0.
  */
 struct cvmx_bootinfo {
+#ifdef __BIG_ENDIAN_BITFIELD
        uint32_t major_version;
        uint32_t minor_version;
 
@@ -123,6 +124,60 @@ struct cvmx_bootinfo {
         */
        uint64_t fdt_addr;
 #endif
+#else                          /* __BIG_ENDIAN */
+       /*
+        * Little-Endian: When the CPU mode is switched to
+        * little-endian, the view of the structure has some of the
+        * fields swapped.
+        */
+       uint32_t minor_version;
+       uint32_t major_version;
+
+       uint64_t stack_top;
+       uint64_t heap_base;
+       uint64_t heap_end;
+       uint64_t desc_vaddr;
+
+       uint32_t stack_size;
+       uint32_t exception_base_addr;
+
+       uint32_t core_mask;
+       uint32_t flags;
+
+       uint32_t phy_mem_desc_addr;
+       uint32_t dram_size;
+
+       uint32_t eclock_hz;
+       uint32_t debugger_flags_base_addr;
+
+       uint32_t reserved0;
+       uint32_t dclock_hz;
+
+       uint8_t reserved3;
+       uint8_t reserved2;
+       uint16_t reserved1;
+       uint8_t board_rev_minor;
+       uint8_t board_rev_major;
+       uint16_t board_type;
+
+       char board_serial_number[CVMX_BOOTINFO_OCTEON_SERIAL_LEN];
+       uint8_t mac_addr_base[6];
+       uint8_t mac_addr_count;
+       uint8_t pad[5];
+
+#if (CVMX_BOOTINFO_MIN_VER >= 1)
+       uint64_t compact_flash_common_base_addr;
+       uint64_t compact_flash_attribute_base_addr;
+       uint64_t led_display_base_addr;
+#endif
+#if (CVMX_BOOTINFO_MIN_VER >= 2)
+       uint32_t config_flags;
+       uint32_t dfa_ref_clock_hz;
+#endif
+#if (CVMX_BOOTINFO_MIN_VER >= 3)
+       uint64_t fdt_addr;
+#endif
+#endif
 };
 
 #define CVMX_BOOTINFO_CFG_FLAG_PCI_HOST                        (1ull << 0)
index 352f1dc..3745625 100644 (file)
@@ -95,6 +95,7 @@ struct cvmx_bootmem_named_block_desc {
  * positions for backwards compatibility.
  */
 struct cvmx_bootmem_desc {
+#if defined(__BIG_ENDIAN_BITFIELD) || defined(CVMX_BUILD_FOR_LINUX_HOST)
        /* spinlock to control access to list */
        uint32_t lock;
        /* flags for indicating various conditions */
@@ -120,7 +121,20 @@ struct cvmx_bootmem_desc {
        uint32_t named_block_name_len;
        /* address of named memory block descriptors */
        uint64_t named_block_array_addr;
+#else                           /* __LITTLE_ENDIAN */
+       uint32_t flags;
+       uint32_t lock;
+       uint64_t head_addr;
 
+       uint32_t minor_version;
+       uint32_t major_version;
+       uint64_t app_data_addr;
+       uint64_t app_data_size;
+
+       uint32_t named_block_name_len;
+       uint32_t named_block_num_blocks;
+       uint64_t named_block_array_addr;
+#endif
 };
 
 /**
index ef98f7f..dafeae3 100644 (file)
@@ -105,6 +105,16 @@ typedef union {
        } s;
 } cvmx_fau_async_tagwait_result_t;
 
+#ifdef __BIG_ENDIAN_BITFIELD
+#define SWIZZLE_8  0
+#define SWIZZLE_16 0
+#define SWIZZLE_32 0
+#else
+#define SWIZZLE_8  0x7
+#define SWIZZLE_16 0x6
+#define SWIZZLE_32 0x4
+#endif
+
 /**
  * Builds a store I/O address for writing to the FAU
  *
@@ -175,6 +185,7 @@ static inline int64_t cvmx_fau_fetch_and_add64(cvmx_fau_reg_64_t reg,
 static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg_32_t reg,
                                               int32_t value)
 {
+       reg ^= SWIZZLE_32;
        return cvmx_read64_int32(__cvmx_fau_atomic_address(0, reg, value));
 }
 
@@ -189,6 +200,7 @@ static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg_32_t reg,
 static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg_16_t reg,
                                               int16_t value)
 {
+       reg ^= SWIZZLE_16;
        return cvmx_read64_int16(__cvmx_fau_atomic_address(0, reg, value));
 }
 
@@ -201,6 +213,7 @@ static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg_16_t reg,
  */
 static inline int8_t cvmx_fau_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
 {
+       reg ^= SWIZZLE_8;
        return cvmx_read64_int8(__cvmx_fau_atomic_address(0, reg, value));
 }
 
@@ -247,6 +260,7 @@ cvmx_fau_tagwait_fetch_and_add32(cvmx_fau_reg_32_t reg, int32_t value)
                uint64_t i32;
                cvmx_fau_tagwait32_t t;
        } result;
+       reg ^= SWIZZLE_32;
        result.i32 =
            cvmx_read64_int32(__cvmx_fau_atomic_address(1, reg, value));
        return result.t;
@@ -270,6 +284,7 @@ cvmx_fau_tagwait_fetch_and_add16(cvmx_fau_reg_16_t reg, int16_t value)
                uint64_t i16;
                cvmx_fau_tagwait16_t t;
        } result;
+       reg ^= SWIZZLE_16;
        result.i16 =
            cvmx_read64_int16(__cvmx_fau_atomic_address(1, reg, value));
        return result.t;
@@ -292,6 +307,7 @@ cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
                uint64_t i8;
                cvmx_fau_tagwait8_t t;
        } result;
+       reg ^= SWIZZLE_8;
        result.i8 = cvmx_read64_int8(__cvmx_fau_atomic_address(1, reg, value));
        return result.t;
 }
@@ -521,6 +537,7 @@ static inline void cvmx_fau_atomic_add64(cvmx_fau_reg_64_t reg, int64_t value)
  */
 static inline void cvmx_fau_atomic_add32(cvmx_fau_reg_32_t reg, int32_t value)
 {
+       reg ^= SWIZZLE_32;
        cvmx_write64_int32(__cvmx_fau_store_address(0, reg), value);
 }
 
@@ -533,6 +550,7 @@ static inline void cvmx_fau_atomic_add32(cvmx_fau_reg_32_t reg, int32_t value)
  */
 static inline void cvmx_fau_atomic_add16(cvmx_fau_reg_16_t reg, int16_t value)
 {
+       reg ^= SWIZZLE_16;
        cvmx_write64_int16(__cvmx_fau_store_address(0, reg), value);
 }
 
@@ -544,6 +562,7 @@ static inline void cvmx_fau_atomic_add16(cvmx_fau_reg_16_t reg, int16_t value)
  */
 static inline void cvmx_fau_atomic_add8(cvmx_fau_reg_8_t reg, int8_t value)
 {
+       reg ^= SWIZZLE_8;
        cvmx_write64_int8(__cvmx_fau_store_address(0, reg), value);
 }
 
@@ -568,6 +587,7 @@ static inline void cvmx_fau_atomic_write64(cvmx_fau_reg_64_t reg, int64_t value)
  */
 static inline void cvmx_fau_atomic_write32(cvmx_fau_reg_32_t reg, int32_t value)
 {
+       reg ^= SWIZZLE_32;
        cvmx_write64_int32(__cvmx_fau_store_address(1, reg), value);
 }
 
@@ -580,6 +600,7 @@ static inline void cvmx_fau_atomic_write32(cvmx_fau_reg_32_t reg, int32_t value)
  */
 static inline void cvmx_fau_atomic_write16(cvmx_fau_reg_16_t reg, int16_t value)
 {
+       reg ^= SWIZZLE_16;
        cvmx_write64_int16(__cvmx_fau_store_address(1, reg), value);
 }
 
@@ -591,6 +612,7 @@ static inline void cvmx_fau_atomic_write16(cvmx_fau_reg_16_t reg, int16_t value)
  */
 static inline void cvmx_fau_atomic_write8(cvmx_fau_reg_8_t reg, int8_t value)
 {
+       reg ^= SWIZZLE_8;
        cvmx_write64_int8(__cvmx_fau_store_address(1, reg), value);
 }
 
index aa26a2c..c00501d 100644 (file)
@@ -49,6 +49,7 @@
 typedef union {
        uint64_t u64;
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /*
                 * the (64-bit word) location in scratchpad to write
                 * to (if len != 0)
@@ -63,6 +64,12 @@ typedef union {
                 * the NCB bus.
                 */
                uint64_t addr:40;
+#else
+               uint64_t addr:40;
+               uint64_t did:8;
+               uint64_t len:8;
+               uint64_t scraddr:8;
+#endif
        } s;
 } cvmx_fpa_iobdma_data_t;
 
index 11c0a8f..ddb4292 100644 (file)
 union cvmx_l2c_tag {
        uint64_t u64;
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved:28;
                uint64_t V:1;           /* Line valid */
                uint64_t D:1;           /* Line dirty */
                uint64_t L:1;           /* Line locked */
                uint64_t U:1;           /* Use, LRU eviction */
                uint64_t addr:32;       /* Phys mem (not all bits valid) */
+#else
+               uint64_t addr:32;       /* Phys mem (not all bits valid) */
+               uint64_t U:1;           /* Use, LRU eviction */
+               uint64_t L:1;           /* Line locked */
+               uint64_t D:1;           /* Line dirty */
+               uint64_t V:1;           /* Line valid */
+               uint64_t reserved:28;
+#endif
        } s;
 };
 
index 38aefa1..895e93d 100644 (file)
@@ -39,6 +39,7 @@ union cvmx_buf_ptr {
        void *ptr;
        uint64_t u64;
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* if set, invert the "free" pick of the overall
                 * packet. HW always sets this bit to 0 on inbound
                 * packet */
@@ -55,6 +56,13 @@ union cvmx_buf_ptr {
                uint64_t size:16;
                /* Pointer to the first byte of the data, NOT buffer */
                uint64_t addr:40;
+#else
+               uint64_t addr:40;
+               uint64_t size:16;
+               uint64_t pool:3;
+               uint64_t back:4;
+               uint64_t i:1;
+#endif
        } s;
 };
 
index f7d2a67..3da59bb 100644 (file)
@@ -127,6 +127,7 @@ typedef struct {
 typedef union {
        uint64_t u64;
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* Must CVMX_IO_SEG */
                uint64_t mem_space:2;
                /* Must be zero */
@@ -151,6 +152,17 @@ typedef union {
                uint64_t queue:9;
                /* Must be zero */
                uint64_t reserved4:3;
+#else
+               uint64_t reserved4:3;
+               uint64_t queue:9;
+               uint64_t port:9;
+               uint64_t reserved3:15;
+               uint64_t reserved2:4;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t reserved:13;
+               uint64_t mem_space:2;
+#endif
        } s;
 } cvmx_pko_doorbell_address_t;
 
@@ -160,6 +172,7 @@ typedef union {
 typedef union {
        uint64_t u64;
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /*
                 * The size of the reg1 operation - could be 8, 16,
                 * 32, or 64 bits.
@@ -229,6 +242,24 @@ typedef union {
                uint64_t segs:6;
                /* Including L2, but no trailing CRC */
                uint64_t total_bytes:16;
+#else
+               uint64_t total_bytes:16;
+               uint64_t segs:6;
+               uint64_t dontfree:1;
+               uint64_t ignore_i:1;
+               uint64_t ipoffp1:7;
+               uint64_t gather:1;
+               uint64_t rsp:1;
+               uint64_t wqp:1;
+               uint64_t n2:1;
+               uint64_t le:1;
+               uint64_t reg0:11;
+               uint64_t subone0:1;
+               uint64_t reg1:11;
+               uint64_t subone1:1;
+               uint64_t size0:2;
+               uint64_t size1:2;
+#endif
        } s;
 } cvmx_pko_command_word0_t;
 
index 2188e65..d5565d7 100644 (file)
@@ -178,6 +178,7 @@ typedef enum {
 typedef union {
        uint64_t u64;
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /*
                 * Don't reschedule this entry. no_sched is used for
                 * CVMX_POW_TAG_OP_SWTAG_DESCH and
@@ -217,6 +218,17 @@ typedef union {
                 * CVMX_POW_TAG_OP_*_NSCHED
                 */
                uint64_t tag:32;
+#else
+               uint64_t tag:32;
+               uint64_t type:3;
+               uint64_t grp:4;
+               uint64_t qos:3;
+               uint64_t unused2:2;
+               cvmx_pow_tag_op_t op:4;
+               uint64_t index:13;
+               uint64_t unused:2;
+               uint64_t no_sched:1;
+#endif
        } s;
 } cvmx_pow_tag_req_t;
 
@@ -230,6 +242,7 @@ typedef union {
      * Address for new work request loads (did<2:0> == 0)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* Mips64 address region. Should be CVMX_IO_SEG */
                uint64_t mem_region:2;
                /* Must be zero */
@@ -247,12 +260,22 @@ typedef union {
                uint64_t wait:1;
                /* Must be zero */
                uint64_t reserved_0_2:3;
+#else
+               uint64_t reserved_0_2:3;
+               uint64_t wait:1;
+               uint64_t reserved_4_39:36;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t reserved_49_61:13;
+               uint64_t mem_region:2;
+#endif
        } swork;
 
     /**
      * Address for loads to get POW internal status
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* Mips64 address region. Should be CVMX_IO_SEG */
                uint64_t mem_region:2;
                /* Must be zero */
@@ -282,12 +305,25 @@ typedef union {
                uint64_t get_wqp:1;
                /* Must be zero */
                uint64_t reserved_0_2:3;
+#else
+               uint64_t reserved_0_2:3;
+               uint64_t get_wqp:1;
+               uint64_t get_cur:1;
+               uint64_t get_rev:1;
+               uint64_t coreid:4;
+               uint64_t reserved_10_39:30;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t reserved_49_61:13;
+               uint64_t mem_region:2;
+#endif
        } sstatus;
 
     /**
      * Address for memory loads to get POW internal state
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* Mips64 address region. Should be CVMX_IO_SEG */
                uint64_t mem_region:2;
                /* Must be zero */
@@ -314,12 +350,24 @@ typedef union {
                uint64_t get_wqp:1;
                /* Must be zero */
                uint64_t reserved_0_2:3;
+#else
+               uint64_t reserved_0_2:3;
+               uint64_t get_wqp:1;
+               uint64_t get_des:1;
+               uint64_t index:11;
+               uint64_t reserved_16_39:24;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t reserved_49_61:13;
+               uint64_t mem_region:2;
+#endif
        } smemload;
 
     /**
      * Address for index/pointer loads
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* Mips64 address region. Should be CVMX_IO_SEG */
                uint64_t mem_region:2;
                /* Must be zero */
@@ -366,6 +414,17 @@ typedef union {
                uint64_t get_rmt:1;
                /* Must be zero */
                uint64_t reserved_0_2:3;
+#else
+               uint64_t reserved_0_2:3;
+               uint64_t get_rmt:1;
+               uint64_t get_des_get_tail:1;
+               uint64_t qosgrp:4;
+               uint64_t reserved_9_39:31;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t reserved_49_61:13;
+               uint64_t mem_region:2;
+#endif
        } sindexload;
 
     /**
@@ -377,6 +436,7 @@ typedef union {
      * available.)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* Mips64 address region. Should be CVMX_IO_SEG */
                uint64_t mem_region:2;
                /* Must be zero */
@@ -387,6 +447,13 @@ typedef union {
                uint64_t did:8;
                /* Must be zero */
                uint64_t reserved_0_39:40;
+#else
+               uint64_t reserved_0_39:40;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t reserved_49_61:13;
+               uint64_t mem_region:2;
+#endif
        } snull_rd;
 } cvmx_pow_load_addr_t;
 
@@ -401,6 +468,7 @@ typedef union {
      * Response to new work request loads
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /*
                 * Set when no new work queue entry was returned.  *
                 * If there was de-scheduled work, the HW will
@@ -419,12 +487,18 @@ typedef union {
                uint64_t reserved_40_62:23;
                /* 36 in O1 -- the work queue pointer */
                uint64_t addr:40;
+#else
+               uint64_t addr:40;
+               uint64_t reserved_40_62:23;
+               uint64_t no_work:1;
+#endif
        } s_work;
 
     /**
      * Result for a POW Status Load (when get_cur==0 and get_wqp==0)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_62_63:2;
                /* Set when there is a pending non-NULL SWTAG or
                 * SWTAG_FULL, and the POW entry has not left the list
@@ -476,12 +550,32 @@ typedef union {
                 *    AND pend_desched_switch) are set.
                 */
                uint64_t pend_tag:32;
+#else
+               uint64_t pend_tag:32;
+               uint64_t pend_type:2;
+               uint64_t reserved_34_35:2;
+               uint64_t pend_grp:4;
+               uint64_t pend_index:11;
+               uint64_t reserved_51:1;
+               uint64_t pend_nosched_clr:1;
+               uint64_t pend_null_rd:1;
+               uint64_t pend_new_work_wait:1;
+               uint64_t pend_new_work:1;
+               uint64_t pend_nosched:1;
+               uint64_t pend_desched_switch:1;
+               uint64_t pend_desched:1;
+               uint64_t pend_switch_null:1;
+               uint64_t pend_switch_full:1;
+               uint64_t pend_switch:1;
+               uint64_t reserved_62_63:2;
+#endif
        } s_sstatus0;
 
     /**
      * Result for a POW Status Load (when get_cur==0 and get_wqp==1)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_62_63:2;
                /*
                 * Set when there is a pending non-NULL SWTAG or
@@ -529,6 +623,23 @@ typedef union {
                uint64_t pend_grp:4;
                /* This is the wqp when pend_nosched_clr is set. */
                uint64_t pend_wqp:36;
+#else
+               uint64_t pend_wqp:36;
+               uint64_t pend_grp:4;
+               uint64_t pend_index:11;
+               uint64_t reserved_51:1;
+               uint64_t pend_nosched_clr:1;
+               uint64_t pend_null_rd:1;
+               uint64_t pend_new_work_wait:1;
+               uint64_t pend_new_work:1;
+               uint64_t pend_nosched:1;
+               uint64_t pend_desched_switch:1;
+               uint64_t pend_desched:1;
+               uint64_t pend_switch_null:1;
+               uint64_t pend_switch_full:1;
+               uint64_t pend_switch:1;
+               uint64_t reserved_62_63:2;
+#endif
        } s_sstatus1;
 
     /**
@@ -536,6 +647,7 @@ typedef union {
      * get_rev==0)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_62_63:2;
                /*
                 * Points to the next POW entry in the tag list when
@@ -573,12 +685,23 @@ typedef union {
                 * SWTAG_DESCHED).
                 */
                uint64_t tag:32;
+#else
+               uint64_t tag:32;
+               uint64_t tag_type:2;
+               uint64_t tail:1;
+               uint64_t head:1;
+               uint64_t grp:4;
+               uint64_t index:11;
+               uint64_t link_index:11;
+               uint64_t reserved_62_63:2;
+#endif
        } s_sstatus2;
 
     /**
      * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_62_63:2;
                /*
                 * Points to the prior POW entry in the tag list when
@@ -617,6 +740,16 @@ typedef union {
                 * SWTAG_DESCHED).
                 */
                uint64_t tag:32;
+#else
+               uint64_t tag:32;
+               uint64_t tag_type:2;
+               uint64_t tail:1;
+               uint64_t head:1;
+               uint64_t grp:4;
+               uint64_t index:11;
+               uint64_t revlink_index:11;
+               uint64_t reserved_62_63:2;
+#endif
        } s_sstatus3;
 
     /**
@@ -624,6 +757,7 @@ typedef union {
      * get_rev==0)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_62_63:2;
                /*
                 * Points to the next POW entry in the tag list when
@@ -642,6 +776,13 @@ typedef union {
                 * list entered on SWTAG_FULL).
                 */
                uint64_t wqp:36;
+#else
+               uint64_t wqp:36;
+               uint64_t grp:4;
+               uint64_t index:11;
+               uint64_t link_index:11;
+               uint64_t reserved_62_63:2;
+#endif
        } s_sstatus4;
 
     /**
@@ -649,6 +790,7 @@ typedef union {
      * get_rev==1)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_62_63:2;
                /*
                 * Points to the prior POW entry in the tag list when
@@ -669,12 +811,20 @@ typedef union {
                 * list entered on SWTAG_FULL).
                 */
                uint64_t wqp:36;
+#else
+               uint64_t wqp:36;
+               uint64_t grp:4;
+               uint64_t index:11;
+               uint64_t revlink_index:11;
+               uint64_t reserved_62_63:2;
+#endif
        } s_sstatus5;
 
     /**
      * Result For POW Memory Load (get_des == 0 and get_wqp == 0)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_51_63:13;
                /*
                 * The next entry in the input, free, descheduled_head
@@ -695,12 +845,22 @@ typedef union {
                uint64_t tag_type:2;
                /* The tag of the POW entry. */
                uint64_t tag:32;
+#else
+               uint64_t tag:32;
+               uint64_t tag_type:2;
+               uint64_t tail:1;
+               uint64_t reserved_35:1;
+               uint64_t grp:4;
+               uint64_t next_index:11;
+               uint64_t reserved_51_63:13;
+#endif
        } s_smemload0;
 
     /**
      * Result For POW Memory Load (get_des == 0 and get_wqp == 1)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_51_63:13;
                /*
                 * The next entry in the input, free, descheduled_head
@@ -712,12 +872,19 @@ typedef union {
                uint64_t grp:4;
                /* The WQP held in the POW entry. */
                uint64_t wqp:36;
+#else
+               uint64_t wqp:36;
+               uint64_t grp:4;
+               uint64_t next_index:11;
+               uint64_t reserved_51_63:13;
+#endif
        } s_smemload1;
 
     /**
      * Result For POW Memory Load (get_des == 1)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_51_63:13;
                /*
                 * The next entry in the tag list connected to the
@@ -740,12 +907,22 @@ typedef union {
                 * is set.
                 */
                uint64_t pend_tag:32;
+#else
+               uint64_t pend_tag:32;
+               uint64_t pend_type:2;
+               uint64_t pend_switch:1;
+               uint64_t nosched:1;
+               uint64_t grp:4;
+               uint64_t fwd_index:11;
+               uint64_t reserved_51_63:13;
+#endif
        } s_smemload2;
 
     /**
      * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_52_63:12;
                /*
                 * set when there is one or more POW entries on the
@@ -791,12 +968,28 @@ typedef union {
                 * the input Q list selected by qosgrp.
                 */
                uint64_t loc_tail:11;
+#else
+               uint64_t loc_tail:11;
+               uint64_t reserved_11:1;
+               uint64_t loc_head:11;
+               uint64_t reserved_23:1;
+               uint64_t loc_one:1;
+               uint64_t loc_val:1;
+               uint64_t free_tail:11;
+               uint64_t reserved_37:1;
+               uint64_t free_head:11;
+               uint64_t reserved_49:1;
+               uint64_t free_one:1;
+               uint64_t free_val:1;
+               uint64_t reserved_52_63:12;
+#endif
        } sindexload0;
 
     /**
      * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_52_63:12;
                /*
                 * set when there is one or more POW entries on the
@@ -843,12 +1036,28 @@ typedef union {
                 * head on the descheduled list selected by qosgrp.
                 */
                uint64_t des_tail:11;
+#else
+               uint64_t des_tail:11;
+               uint64_t reserved_11:1;
+               uint64_t des_head:11;
+               uint64_t reserved_23:1;
+               uint64_t des_one:1;
+               uint64_t des_val:1;
+               uint64_t nosched_tail:11;
+               uint64_t reserved_37:1;
+               uint64_t nosched_head:11;
+               uint64_t reserved_49:1;
+               uint64_t nosched_one:1;
+               uint64_t nosched_val:1;
+               uint64_t reserved_52_63:12;
+#endif
        } sindexload1;
 
     /**
      * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_39_63:25;
                /*
                 * Set when this DRAM list is the current head
@@ -877,6 +1086,13 @@ typedef union {
                 * qosgrp.
                 */
                uint64_t rmt_head:36;
+#else
+               uint64_t rmt_head:36;
+               uint64_t rmt_one:1;
+               uint64_t rmt_val:1;
+               uint64_t rmt_is_head:1;
+               uint64_t reserved_39_63:25;
+#endif
        } sindexload2;
 
     /**
@@ -884,6 +1100,7 @@ typedef union {
      * 1/get_des_get_tail == 1)
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t reserved_39_63:25;
                /*
                 * set when this DRAM list is the current head
@@ -912,12 +1129,20 @@ typedef union {
                 * qosgrp.
                 */
                uint64_t rmt_tail:36;
+#else
+               uint64_t rmt_tail:36;
+               uint64_t rmt_one:1;
+               uint64_t rmt_val:1;
+               uint64_t rmt_is_head:1;
+               uint64_t reserved_39_63:25;
+#endif
        } sindexload3;
 
     /**
      * Response to NULL_RD request loads
      */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t unused:62;
                /* of type cvmx_pow_tag_type_t. state is one of the
                 * following:
@@ -928,6 +1153,10 @@ typedef union {
                 * - CVMX_POW_TAG_TYPE_NULL_NULL
                 */
                uint64_t state:2;
+#else
+               uint64_t state:2;
+               uint64_t unused:62;
+#endif
        } s_null_rd;
 
 } cvmx_pow_tag_load_resp_t;
@@ -962,6 +1191,7 @@ typedef union {
        uint64_t u64;
 
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* Memory region.  Should be CVMX_IO_SEG in most cases */
                uint64_t mem_reg:2;
                uint64_t reserved_49_61:13;     /* Must be zero */
@@ -971,6 +1201,14 @@ typedef union {
                uint64_t reserved_36_39:4;      /* Must be zero */
                /* Address field. addr<2:0> must be zero */
                uint64_t addr:36;
+#else
+               uint64_t addr:36;
+               uint64_t reserved_36_39:4;
+               uint64_t did:8;
+               uint64_t is_io:1;
+               uint64_t reserved_49_61:13;
+               uint64_t mem_reg:2;
+#endif
        } stag;
 } cvmx_pow_tag_store_addr_t;
 
@@ -981,6 +1219,7 @@ typedef union {
        uint64_t u64;
 
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /*
                 * the (64-bit word) location in scratchpad to write
                 * to (if len != 0)
@@ -994,6 +1233,14 @@ typedef union {
                /* if set, don't return load response until work is available */
                uint64_t wait:1;
                uint64_t unused2:3;
+#else
+               uint64_t unused2:3;
+               uint64_t wait:1;
+               uint64_t unused:36;
+               uint64_t did:8;
+               uint64_t len:8;
+               uint64_t scraddr:8;
+#endif
        } s;
 
 } cvmx_pow_iobdma_store_t;
index aa0d3d0..2d6d0c7 100644 (file)
@@ -57,6 +57,7 @@ typedef union {
 
        /* Use this struct if the hardware determines that the packet is IP */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /* HW sets this to the number of buffers used by this packet */
                uint64_t bufs:8;
                /* HW sets to the number of L2 bytes prior to the IP */
@@ -166,13 +167,45 @@ typedef union {
                 * the slow path */
                /* type is cvmx_pip_err_t */
                uint64_t err_code:8;
+#else
+               uint64_t err_code:8;
+               uint64_t rcv_error:1;
+               uint64_t not_IP:1;
+               uint64_t is_mcast:1;
+               uint64_t is_bcast:1;
+               uint64_t IP_exc:1;
+               uint64_t is_frag:1;
+               uint64_t L4_error:1;
+               uint64_t software:1;
+               uint64_t is_v6:1;
+               uint64_t dec_ipsec:1;
+               uint64_t tcp_or_udp:1;
+               uint64_t dec_ipcomp:1;
+               uint64_t unassigned2:4;
+               uint64_t unassigned2a:4;
+               uint64_t pr:4;
+               uint64_t vlan_id:12;
+               uint64_t vlan_cfi:1;
+               uint64_t unassigned:1;
+               uint64_t vlan_stacked:1;
+               uint64_t vlan_valid:1;
+               uint64_t ip_offset:8;
+               uint64_t bufs:8;
+#endif
        } s;
 
        /* use this to get at the 16 vlan bits */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                uint64_t unused1:16;
                uint64_t vlan:16;
                uint64_t unused2:32;
+#else
+               uint64_t unused2:32;
+               uint64_t vlan:16;
+               uint64_t unused1:16;
+
+#endif
        } svlan;
 
        /*
@@ -180,6 +213,7 @@ typedef union {
         * the packet is ip.
         */
        struct {
+#ifdef __BIG_ENDIAN_BITFIELD
                /*
                 * HW sets this to the number of buffers used by this
                 * packet.
@@ -296,6 +330,27 @@ typedef union {
                 */
                /* type is cvmx_pip_err_t (union, so can't use directly */
                uint64_t err_code:8;
+#else
+               uint64_t err_code:8;
+               uint64_t rcv_error:1;
+               uint64_t not_IP:1;
+               uint64_t is_mcast:1;
+               uint64_t is_bcast:1;
+               uint64_t is_arp:1;
+               uint64_t is_rarp:1;
+               uint64_t unassigned3:1;
+               uint64_t software:1;
+               uint64_t unassigned2:4;
+               uint64_t unassigned2a:8;
+               uint64_t pr:4;
+               uint64_t vlan_id:12;
+               uint64_t vlan_cfi:1;
+               uint64_t unassigned:1;
+               uint64_t vlan_stacked:1;
+               uint64_t vlan_valid:1;
+               uint64_t unused:8;
+               uint64_t bufs:8;
+#endif
        } snoip;
 
 } cvmx_pip_wqe_word2;
@@ -312,6 +367,7 @@ typedef struct {
      * HW WRITE: the following 64 bits are filled by HW when a packet arrives
      */
 
+#ifdef __BIG_ENDIAN_BITFIELD
     /**
      * raw chksum result generated by the HW
      */
@@ -327,12 +383,18 @@ typedef struct {
      * (Only 36 bits used in Octeon 1)
      */
        uint64_t next_ptr:40;
+#else
+       uint64_t next_ptr:40;
+       uint8_t unused;
+       uint16_t hw_chksum;
+#endif
 
     /*****************************************************************
      * WORD 1
      * HW WRITE: the following 64 bits are filled by HW when a packet arrives
      */
 
+#ifdef __BIG_ENDIAN_BITFIELD
     /**
      * HW sets to the total number of bytes in the packet
      */
@@ -359,6 +421,15 @@ typedef struct {
      * the synchronization/ordering tag
      */
        uint64_t tag:32;
+#else
+       uint64_t tag:32;
+       uint64_t tag_type:2;
+       uint64_t zero_2:1;
+       uint64_t grp:4;
+       uint64_t qos:3;
+       uint64_t ipprt:6;
+       uint64_t len:16;
+#endif
 
     /**
      * WORD 2 HW WRITE: the following 64-bits are filled in by
index 33db1c8..774bb45 100644 (file)
@@ -436,14 +436,6 @@ static inline uint64_t cvmx_get_cycle_global(void)
 
 /***************************************************************************/
 
-static inline void cvmx_reset_octeon(void)
-{
-       union cvmx_ciu_soft_rst ciu_soft_rst;
-       ciu_soft_rst.u64 = 0;
-       ciu_soft_rst.s.soft_rst = 1;
-       cvmx_write_csr(CVMX_CIU_SOFT_RST, ciu_soft_rst.u64);
-}
-
 /* Return the number of cores available in the chip */
 static inline uint32_t cvmx_octeon_num_cores(void)
 {
index 0415965..de9f74e 100644 (file)
@@ -335,4 +335,6 @@ void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t);
 
 extern void octeon_fixup_irqs(void);
 
+extern struct semaphore octeon_bootbus_sem;
+
 #endif /* __ASM_OCTEON_OCTEON_H */
index 64ba56a..1884609 100644 (file)
@@ -11,9 +11,6 @@
 
 #include <linux/pci.h>
 
-/* Some PCI cards require delays when accessing config space. */
-#define PCI_CONFIG_SPACE_DELAY 10000
-
 /*
  * The physical memory base mapped by BAR1.  256MB at the end of the
  * first 4GB.
index 154b70a..89dd7fe 100644 (file)
@@ -105,8 +105,6 @@ static inline void clear_user_page(void *addr, unsigned long vaddr,
                flush_data_cache_page((unsigned long)addr);
 }
 
-extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
-       struct page *to);
 struct vm_area_struct;
 extern void copy_user_highpage(struct page *to, struct page *from,
        unsigned long vaddr, struct vm_area_struct *vma);
index 193b4c6..d969299 100644 (file)
@@ -35,6 +35,8 @@ struct pci_controller {
        struct resource *io_resource;
        unsigned long io_offset;
        unsigned long io_map_base;
+       struct resource *busn_resource;
+       unsigned long busn_offset;
 
        unsigned int index;
        /* For compatibility with current (as of July 2003) pciutils
index af2c8a3..8d7a63b 100644 (file)
@@ -835,6 +835,7 @@ struct bridge_controller {
        struct pci_controller   pc;
        struct resource         mem;
        struct resource         io;
+       struct resource         busn;
        bridge_t                *base;
        nasid_t                 nasid;
        unsigned int            widget_id;
index a6be006..7d56686 100644 (file)
@@ -105,13 +105,16 @@ static inline void pmd_clear(pmd_t *pmdp)
 
 #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
 #define pte_page(x)            pfn_to_page(pte_pfn(x))
-#define pte_pfn(x)             ((unsigned long)((x).pte_high >> 6))
+#define pte_pfn(x)             (((unsigned long)((x).pte_high >> _PFN_SHIFT)) | (unsigned long)((x).pte_low << _PAGE_PRESENT_SHIFT))
 static inline pte_t
 pfn_pte(unsigned long pfn, pgprot_t prot)
 {
        pte_t pte;
-       pte.pte_high = (pfn << 6) | (pgprot_val(prot) & 0x3f);
-       pte.pte_low = pgprot_val(prot);
+
+       pte.pte_low = (pfn >> _PAGE_PRESENT_SHIFT) |
+                               (pgprot_val(prot) & ~_PFNX_MASK);
+       pte.pte_high = (pfn << _PFN_SHIFT) |
+                               (pgprot_val(prot) & ~_PFN_MASK);
        return pte;
 }
 
@@ -166,9 +169,9 @@ pfn_pte(unsigned long pfn, pgprot_t prot)
 #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
 
 /* Swap entries must have VALID and GLOBAL bits cleared. */
-#define __swp_type(x)                  (((x).val >> 2) & 0x1f)
-#define __swp_offset(x)                         ((x).val >> 7)
-#define __swp_entry(type,offset)       ((swp_entry_t)  { ((type) << 2) | ((offset) << 7) })
+#define __swp_type(x)                  (((x).val >> 4) & 0x1f)
+#define __swp_offset(x)                         ((x).val >> 9)
+#define __swp_entry(type,offset)       ((swp_entry_t)  { ((type) << 4) | ((offset) << 9) })
 #define __pte_to_swp_entry(pte)                ((swp_entry_t) { (pte).pte_high })
 #define __swp_entry_to_pte(x)          ((pte_t) { 0, (x).val })
 
index 1659bb9..cf661a2 100644 (file)
@@ -279,14 +279,14 @@ extern void pgd_init(unsigned long page);
 extern void pmd_init(unsigned long page, unsigned long pagetable);
 
 /*
- * Non-present pages:  high 24 bits are offset, next 8 bits type,
- * low 32 bits zero.
+ * Non-present pages:  high 40 bits are offset, next 8 bits type,
+ * low 16 bits zero.
  */
 static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
-{ pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; }
+{ pte_t pte; pte_val(pte) = (type << 16) | (offset << 24); return pte; }
 
-#define __swp_type(x)          (((x).val >> 32) & 0xff)
-#define __swp_offset(x)                ((x).val >> 40)
+#define __swp_type(x)          (((x).val >> 16) & 0xff)
+#define __swp_offset(x)                ((x).val >> 24)
 #define __swp_entry(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type), (offset))) })
 #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
 #define __swp_entry_to_pte(x)  ((pte_t) { (x).val })
index 91747c2..18ae5dd 100644 (file)
 /*
  * The following bits are implemented by the TLB hardware
  */
-#define _PAGE_GLOBAL_SHIFT     0
+#define _PAGE_NO_EXEC_SHIFT    0
+#define _PAGE_NO_EXEC          (1 << _PAGE_NO_EXEC_SHIFT)
+#define _PAGE_NO_READ_SHIFT    (_PAGE_NO_EXEC_SHIFT + 1)
+#define _PAGE_NO_READ          (1 << _PAGE_NO_READ_SHIFT)
+#define _PAGE_GLOBAL_SHIFT     (_PAGE_NO_READ_SHIFT + 1)
 #define _PAGE_GLOBAL           (1 << _PAGE_GLOBAL_SHIFT)
 #define _PAGE_VALID_SHIFT      (_PAGE_GLOBAL_SHIFT + 1)
 #define _PAGE_VALID            (1 << _PAGE_VALID_SHIFT)
@@ -49,7 +53,7 @@
 /*
  * The following bits are implemented in software
  */
-#define _PAGE_PRESENT_SHIFT    (_CACHE_SHIFT + 3)
+#define _PAGE_PRESENT_SHIFT    (24)
 #define _PAGE_PRESENT          (1 << _PAGE_PRESENT_SHIFT)
 #define _PAGE_READ_SHIFT       (_PAGE_PRESENT_SHIFT + 1)
 #define _PAGE_READ             (1 << _PAGE_READ_SHIFT)
 
 #define _PFN_SHIFT             (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
 
+/*
+ * Bits for extended EntryLo0/EntryLo1 registers
+ */
+#define _PFNX_MASK             0xffffff
+
 #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
 /*
 
 #else
 /*
- * When using the RI/XI bit support, we have 13 bits of flags below
- * the physical address. The RI/XI bits are placed such that a SRL 5
- * can strip off the software bits, then a ROTR 2 can move the RI/XI
- * into bits [63:62]. This also limits physical address to 56 bits,
- * which is more than we need right now.
+ * Below are the "Normal" R4K cases
  */
 
 /*
  */
 #define _PAGE_PRESENT_SHIFT    0
 #define _PAGE_PRESENT          (1 << _PAGE_PRESENT_SHIFT)
-#define _PAGE_READ_SHIFT       (cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
-#define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; })
+/* R2 or later cores check for RI/XI support to determine _PAGE_READ */
+#ifdef CONFIG_CPU_MIPSR2
+#define _PAGE_WRITE_SHIFT      (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_WRITE            (1 << _PAGE_WRITE_SHIFT)
+#else
+#define _PAGE_READ_SHIFT       (_PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_READ             (1 << _PAGE_READ_SHIFT)
 #define _PAGE_WRITE_SHIFT      (_PAGE_READ_SHIFT + 1)
 #define _PAGE_WRITE            (1 << _PAGE_WRITE_SHIFT)
+#endif
 #define _PAGE_ACCESSED_SHIFT   (_PAGE_WRITE_SHIFT + 1)
 #define _PAGE_ACCESSED         (1 << _PAGE_ACCESSED_SHIFT)
 #define _PAGE_MODIFIED_SHIFT   (_PAGE_ACCESSED_SHIFT + 1)
 #define _PAGE_MODIFIED         (1 << _PAGE_MODIFIED_SHIFT)
 
-#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
-/* huge tlb page */
+#if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT)
+/* Huge TLB page */
 #define _PAGE_HUGE_SHIFT       (_PAGE_MODIFIED_SHIFT + 1)
 #define _PAGE_HUGE             (1 << _PAGE_HUGE_SHIFT)
 #define _PAGE_SPLITTING_SHIFT  (_PAGE_HUGE_SHIFT + 1)
 #define _PAGE_SPLITTING                (1 << _PAGE_SPLITTING_SHIFT)
+
+/* Only R2 or newer cores have the XI bit */
+#ifdef CONFIG_CPU_MIPSR2
+#define _PAGE_NO_EXEC_SHIFT    (_PAGE_SPLITTING_SHIFT + 1)
 #else
-#define _PAGE_HUGE_SHIFT       (_PAGE_MODIFIED_SHIFT)
-#define _PAGE_HUGE             ({BUG(); 1; })  /* Dummy value */
-#define _PAGE_SPLITTING_SHIFT  (_PAGE_HUGE_SHIFT)
-#define _PAGE_SPLITTING                ({BUG(); 1; })  /* Dummy value */
-#endif
+#define _PAGE_GLOBAL_SHIFT     (_PAGE_SPLITTING_SHIFT + 1)
+#define _PAGE_GLOBAL           (1 << _PAGE_GLOBAL_SHIFT)
+#endif /* CONFIG_CPU_MIPSR2 */
 
-/* Page cannot be executed */
-#define _PAGE_NO_EXEC_SHIFT    (cpu_has_rixi ? _PAGE_SPLITTING_SHIFT + 1 : _PAGE_SPLITTING_SHIFT)
-#define _PAGE_NO_EXEC          ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; })
+#endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */
 
-/* Page cannot be read */
-#define _PAGE_NO_READ_SHIFT    (cpu_has_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
-#define _PAGE_NO_READ          ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_READ_SHIFT; })
+#ifdef CONFIG_CPU_MIPSR2
+/* XI - page cannot be executed */
+#ifndef _PAGE_NO_EXEC_SHIFT
+#define _PAGE_NO_EXEC_SHIFT    (_PAGE_MODIFIED_SHIFT + 1)
+#endif
+#define _PAGE_NO_EXEC          (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0)
+
+/* RI - page cannot be read */
+#define _PAGE_READ_SHIFT       (_PAGE_NO_EXEC_SHIFT + 1)
+#define _PAGE_READ             (cpu_has_rixi ? 0 : (1 << _PAGE_READ_SHIFT))
+#define _PAGE_NO_READ_SHIFT    _PAGE_READ_SHIFT
+#define _PAGE_NO_READ          (cpu_has_rixi ? (1 << _PAGE_READ_SHIFT) : 0)
 
 #define _PAGE_GLOBAL_SHIFT     (_PAGE_NO_READ_SHIFT + 1)
 #define _PAGE_GLOBAL           (1 << _PAGE_GLOBAL_SHIFT)
+
+#else  /* !CONFIG_CPU_MIPSR2 */
+#define _PAGE_GLOBAL_SHIFT     (_PAGE_MODIFIED_SHIFT + 1)
+#define _PAGE_GLOBAL           (1 << _PAGE_GLOBAL_SHIFT)
+#endif /* CONFIG_CPU_MIPSR2 */
+
 #define _PAGE_VALID_SHIFT      (_PAGE_GLOBAL_SHIFT + 1)
 #define _PAGE_VALID            (1 << _PAGE_VALID_SHIFT)
 #define _PAGE_DIRTY_SHIFT      (_PAGE_VALID_SHIFT + 1)
 
 #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */
 
+#ifndef _PAGE_NO_EXEC
+#define _PAGE_NO_EXEC          0
+#endif
+#ifndef _PAGE_NO_READ
+#define _PAGE_NO_READ          0
+#endif
+
 #define _PAGE_SILENT_READ      _PAGE_VALID
 #define _PAGE_SILENT_WRITE     _PAGE_DIRTY
 
 #define _PFN_MASK              (~((1 << (_PFN_SHIFT)) - 1))
 
-#ifndef _PAGE_NO_READ
-#define _PAGE_NO_READ ({BUG(); 0; })
-#define _PAGE_NO_READ_SHIFT ({BUG(); 0; })
-#endif
-#ifndef _PAGE_NO_EXEC
-#define _PAGE_NO_EXEC ({BUG(); 0; })
-#endif
+/*
+ * The final layouts of the PTE bits are:
+ *
+ *   64-bit, R1 or earlier:     CCC D V G [S H] M A W R P
+ *   32-bit, R1 or earler:      CCC D V G M A W R P
+ *   64-bit, R2 or later:       CCC D V G RI/R XI [S H] M A W P
+ *   32-bit, R2 or later:       CCC D V G RI/R XI M A W P
+ */
 
 
 #ifndef __ASSEMBLY__
  */
 static inline uint64_t pte_to_entrylo(unsigned long pte_val)
 {
+#ifdef CONFIG_CPU_MIPSR2
        if (cpu_has_rixi) {
                int sa;
 #ifdef CONFIG_32BIT
@@ -186,6 +221,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
                return (pte_val >> _PAGE_GLOBAL_SHIFT) |
                        ((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa);
        }
+#endif
 
        return pte_val >> _PAGE_GLOBAL_SHIFT;
 }
@@ -245,7 +281,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)
 #define _CACHE_UNCACHED_ACCELERATED    (7<<_CACHE_SHIFT)
 #endif
 
-#define __READABLE     (_PAGE_SILENT_READ | _PAGE_ACCESSED | (cpu_has_rixi ? 0 : _PAGE_READ))
+#define __READABLE     (_PAGE_SILENT_READ | _PAGE_READ | _PAGE_ACCESSED)
 #define __WRITEABLE    (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED)
 
 #define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED |      \
index bef782c..819af9d 100644 (file)
@@ -24,17 +24,17 @@ struct mm_struct;
 struct vm_area_struct;
 
 #define PAGE_NONE      __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | (cpu_has_rixi ? 0 : _PAGE_READ) | \
+#define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | \
                                 _page_cachable_default)
-#define PAGE_COPY      __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | \
-                                (cpu_has_rixi ?  _PAGE_NO_EXEC : 0) | _page_cachable_default)
-#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | \
+#define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_NO_EXEC | \
+                                _page_cachable_default)
+#define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_READ | \
                                 _page_cachable_default)
 #define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
                                 _PAGE_GLOBAL | _page_cachable_default)
 #define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
                                 _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
+#define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
                                 _page_cachable_default)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
                        __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
@@ -127,13 +127,9 @@ do {                                                                       \
        }                                                               \
 } while(0)
 
-
-extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
-       pte_t pteval);
-
 #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
 
-#define pte_none(pte)          (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
+#define pte_none(pte)          (!(((pte).pte_high) & ~_PAGE_GLOBAL))
 #define pte_present(pte)       ((pte).pte_low & _PAGE_PRESENT)
 
 static inline void set_pte(pte_t *ptep, pte_t pte)
@@ -142,18 +138,17 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
        smp_wmb();
        ptep->pte_low = pte.pte_low;
 
-       if (pte.pte_low & _PAGE_GLOBAL) {
+       if (pte.pte_high & _PAGE_GLOBAL) {
                pte_t *buddy = ptep_buddy(ptep);
                /*
                 * Make sure the buddy is global too (if it's !none,
                 * it better already be global)
                 */
-               if (pte_none(*buddy)) {
-                       buddy->pte_low  |= _PAGE_GLOBAL;
+               if (pte_none(*buddy))
                        buddy->pte_high |= _PAGE_GLOBAL;
-               }
        }
 }
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
@@ -161,8 +156,8 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
 
        htw_stop();
        /* Preserve global status for the pair */
-       if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL)
-               null.pte_low = null.pte_high = _PAGE_GLOBAL;
+       if (ptep_buddy(ptep)->pte_high & _PAGE_GLOBAL)
+               null.pte_high = _PAGE_GLOBAL;
 
        set_pte_at(mm, addr, ptep, null);
        htw_start();
@@ -192,6 +187,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
        }
 #endif
 }
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
@@ -242,21 +238,21 @@ static inline int pte_young(pte_t pte)    { return pte.pte_low & _PAGE_ACCESSED; }
 
 static inline pte_t pte_wrprotect(pte_t pte)
 {
-       pte.pte_low  &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+       pte.pte_low  &= ~_PAGE_WRITE;
        pte.pte_high &= ~_PAGE_SILENT_WRITE;
        return pte;
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
 {
-       pte.pte_low  &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
+       pte.pte_low  &= ~_PAGE_MODIFIED;
        pte.pte_high &= ~_PAGE_SILENT_WRITE;
        return pte;
 }
 
 static inline pte_t pte_mkold(pte_t pte)
 {
-       pte.pte_low  &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
+       pte.pte_low  &= ~_PAGE_ACCESSED;
        pte.pte_high &= ~_PAGE_SILENT_READ;
        return pte;
 }
@@ -264,30 +260,24 @@ static inline pte_t pte_mkold(pte_t pte)
 static inline pte_t pte_mkwrite(pte_t pte)
 {
        pte.pte_low |= _PAGE_WRITE;
-       if (pte.pte_low & _PAGE_MODIFIED) {
-               pte.pte_low  |= _PAGE_SILENT_WRITE;
+       if (pte.pte_low & _PAGE_MODIFIED)
                pte.pte_high |= _PAGE_SILENT_WRITE;
-       }
        return pte;
 }
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
        pte.pte_low |= _PAGE_MODIFIED;
-       if (pte.pte_low & _PAGE_WRITE) {
-               pte.pte_low  |= _PAGE_SILENT_WRITE;
+       if (pte.pte_low & _PAGE_WRITE)
                pte.pte_high |= _PAGE_SILENT_WRITE;
-       }
        return pte;
 }
 
 static inline pte_t pte_mkyoung(pte_t pte)
 {
        pte.pte_low |= _PAGE_ACCESSED;
-       if (pte.pte_low & _PAGE_READ) {
-               pte.pte_low  |= _PAGE_SILENT_READ;
+       if (pte.pte_low & _PAGE_READ)
                pte.pte_high |= _PAGE_SILENT_READ;
-       }
        return pte;
 }
 #else
@@ -332,13 +322,13 @@ static inline pte_t pte_mkdirty(pte_t pte)
 static inline pte_t pte_mkyoung(pte_t pte)
 {
        pte_val(pte) |= _PAGE_ACCESSED;
-       if (cpu_has_rixi) {
-               if (!(pte_val(pte) & _PAGE_NO_READ))
-                       pte_val(pte) |= _PAGE_SILENT_READ;
-       } else {
-               if (pte_val(pte) & _PAGE_READ)
-                       pte_val(pte) |= _PAGE_SILENT_READ;
-       }
+#ifdef CONFIG_CPU_MIPSR2
+       if (!(pte_val(pte) & _PAGE_NO_READ))
+               pte_val(pte) |= _PAGE_SILENT_READ;
+       else
+#endif
+       if (pte_val(pte) & _PAGE_READ)
+               pte_val(pte) |= _PAGE_SILENT_READ;
        return pte;
 }
 
@@ -391,10 +381,10 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
 #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
-       pte.pte_low  &= _PAGE_CHG_MASK;
+       pte.pte_low  &= (_PAGE_MODIFIED | _PAGE_ACCESSED | _PFNX_MASK);
        pte.pte_high &= (_PFN_MASK | _CACHE_MASK);
-       pte.pte_low  |= pgprot_val(newprot);
-       pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK);
+       pte.pte_low  |= pgprot_val(newprot) & ~_PFNX_MASK;
+       pte.pte_high |= pgprot_val(newprot) & ~_PFN_MASK;
        return pte;
 }
 #else
@@ -407,12 +397,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 
 extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
        pte_t pte);
+extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
+       pte_t pte);
 
 static inline void update_mmu_cache(struct vm_area_struct *vma,
        unsigned long address, pte_t *ptep)
 {
        pte_t pte = *ptep;
        __update_tlb(vma, address, pte);
+       __update_cache(vma, address, pte);
 }
 
 static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
@@ -534,13 +527,13 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd)
 {
        pmd_val(pmd) |= _PAGE_ACCESSED;
 
-       if (cpu_has_rixi) {
-               if (!(pmd_val(pmd) & _PAGE_NO_READ))
-                       pmd_val(pmd) |= _PAGE_SILENT_READ;
-       } else {
-               if (pmd_val(pmd) & _PAGE_READ)
-                       pmd_val(pmd) |= _PAGE_SILENT_READ;
-       }
+#ifdef CONFIG_CPU_MIPSR2
+       if (!(pmd_val(pmd) & _PAGE_NO_READ))
+               pmd_val(pmd) |= _PAGE_SILENT_READ;
+       else
+#endif
+       if (pmd_val(pmd) & _PAGE_READ)
+               pmd_val(pmd) |= _PAGE_SILENT_READ;
 
        return pmd;
 }
index 1b22d2d..38902bf 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef _ASM_R4KCACHE_H
 #define _ASM_R4KCACHE_H
 
+#include <linux/stringify.h>
+
 #include <asm/asm.h>
 #include <asm/cacheops.h>
 #include <asm/compiler.h>
@@ -344,7 +346,7 @@ static inline void invalidate_tcache_page(unsigned long addr)
        "       cache %1, 0x0a0(%0); cache %1, 0x0b0(%0)\n"     \
        "       cache %1, 0x0c0(%0); cache %1, 0x0d0(%0)\n"     \
        "       cache %1, 0x0e0(%0); cache %1, 0x0f0(%0)\n"     \
-       "       addiu $1, $0, 0x100                     \n"     \
+       "       "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x010($1)\n"     \
        "       cache %1, 0x020($1); cache %1, 0x030($1)\n"     \
        "       cache %1, 0x040($1); cache %1, 0x050($1)\n"     \
@@ -368,17 +370,17 @@ static inline void invalidate_tcache_page(unsigned long addr)
        "       cache %1, 0x040(%0); cache %1, 0x060(%0)\n"     \
        "       cache %1, 0x080(%0); cache %1, 0x0a0(%0)\n"     \
        "       cache %1, 0x0c0(%0); cache %1, 0x0e0(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x020($1)\n"     \
        "       cache %1, 0x040($1); cache %1, 0x060($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0a0($1)\n"     \
        "       cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n"     \
-       "       addiu $1, $1, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x020($1)\n"     \
        "       cache %1, 0x040($1); cache %1, 0x060($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0a0($1)\n"     \
        "       cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n"     \
-       "       addiu $1, $1, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100\n"      \
        "       cache %1, 0x000($1); cache %1, 0x020($1)\n"     \
        "       cache %1, 0x040($1); cache %1, 0x060($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0a0($1)\n"     \
@@ -396,25 +398,25 @@ static inline void invalidate_tcache_page(unsigned long addr)
        "       .set noat\n"                                    \
        "       cache %1, 0x000(%0); cache %1, 0x040(%0)\n"     \
        "       cache %1, 0x080(%0); cache %1, 0x0c0(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x040($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0c0($1)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x040($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0c0($1)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x040($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0c0($1)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x040($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0c0($1)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x040($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0c0($1)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x040($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0c0($1)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
        "       cache %1, 0x000($1); cache %1, 0x040($1)\n"     \
        "       cache %1, 0x080($1); cache %1, 0x0c0($1)\n"     \
        "       .set pop\n"                                     \
@@ -429,39 +431,38 @@ static inline void invalidate_tcache_page(unsigned long addr)
        "       .set mips64r6\n"                                \
        "       .set noat\n"                                    \
        "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
-       "       cache %1, 0x000(%0); cache %1, 0x080(%0)\n"     \
-       "       addiu $1, %0, 0x100\n"                          \
+       "       "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
+       "       "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n"     \
+       "       cache %1, 0x000($1); cache %1, 0x080($1)\n"     \
        "       .set pop\n"                                     \
                :                                               \
                : "r" (base),                                   \
index 645cea7..b615571 100644 (file)
@@ -22,14 +22,15 @@ enum sgi_mach {
        ip17,   /* R4K UP */
        ip19,   /* R4K MP */
        ip20,   /* R4K UP, Indigo */
-       ip21,   /* TFP MP */
-       ip22,   /* R4x00 UP, Indigo2 */
+       ip21,   /* R8k/TFP MP */
+       ip22,   /* R4x00 UP, Indy, Indigo2 */
        ip25,   /* R10k MP */
-       ip26,   /* TFP UP, Indigo2 */
-       ip27,   /* R10k MP, R12k MP, Origin */
-       ip28,   /* R10k UP, Indigo2 */
-       ip30,   /* Octane */
-       ip32,   /* O2 */
+       ip26,   /* R8k/TFP UP, Indigo2 */
+       ip27,   /* R10k MP, R12k MP, R14k MP, Origin 200/2k, Onyx2 */
+       ip28,   /* R10k UP, Indigo2 Impact R10k */
+       ip30,   /* R10k MP, R12k MP, R14k MP, Octane */
+       ip32,   /* R5k UP, RM5200 UP, RM7k UP, R10k UP, R12k UP, O2 */
+       ip35,   /* R14k MP, R16k MP, Origin 300/3k, Onyx3, Fuel, Tezro */
 };
 
 extern enum sgi_mach sgimach;
index b454869..1fca2e0 100644 (file)
@@ -263,7 +263,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
        if (R10000_LLSC_WAR) {
                __asm__ __volatile__(
                "1:     ll      %1, %2          # arch_read_unlock      \n"
-               "       addiu   %1,                                   \n"
+               "       addiu   %1, -1                                  \n"
                "       sc      %1, %0                                  \n"
                "       beqzl   %1, 1b                                  \n"
                : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp)
index 8408a30..9c0014e 100644 (file)
@@ -53,10 +53,10 @@ struct thread_info {
 #define init_stack             (init_thread_union.stack)
 
 /* How to get the thread information struct from C.  */
+register struct thread_info *__current_thread_info __asm__("$28");
+
 static inline struct thread_info *current_thread_info(void)
 {
-       register struct thread_info *__current_thread_info __asm__("$28");
-
        return __current_thread_info;
 }
 
index ba91be9..c41d300 100644 (file)
@@ -1,3 +1,4 @@
 platform-$(CONFIG_MACH_JZ4740) += jz4740/
 cflags-$(CONFIG_MACH_JZ4740)   += -I$(srctree)/arch/mips/include/asm/mach-jz4740
 load-$(CONFIG_MACH_JZ4740)     += 0xffffffff80010000
+zload-$(CONFIG_MACH_JZ4740)    += 0xffffffff80600000
index 5e430ce..72b0cec 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/time.h>
 
 #include <linux/clockchips.h>
+#include <linux/sched_clock.h>
 
 #include <asm/mach-jz4740/irq.h>
 #include <asm/mach-jz4740/timer.h>
@@ -43,6 +44,11 @@ static struct clocksource jz4740_clocksource = {
        .flags = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static u64 notrace jz4740_read_sched_clock(void)
+{
+       return jz4740_timer_get_count(TIMER_CLOCKSOURCE);
+}
+
 static irqreturn_t jz4740_clockevent_irq(int irq, void *devid)
 {
        struct clock_event_device *cd = devid;
@@ -126,6 +132,8 @@ void __init plat_time_init(void)
        if (ret)
                printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
 
+       sched_clock_register(jz4740_read_sched_clock, 16, clk_rate);
+
        setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
 
        ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
index c2e0f45..c0c5e59 100644 (file)
@@ -36,8 +36,10 @@ int __isa_exception_epc(struct pt_regs *regs)
                return epc;
        }
        if (cpu_has_mips16) {
-               if (((union mips16e_instruction)inst).ri.opcode
-                               == MIPS16e_jal_op)
+               union mips16e_instruction inst_mips16e;
+
+               inst_mips16e.full = inst;
+               if (inst_mips16e.ri.opcode == MIPS16e_jal_op)
                        epc += 4;
                else
                        epc += 2;
index 82bd2b2..d70c4d8 100644 (file)
@@ -37,6 +37,24 @@ void mips_set_clock_mode(enum clock_event_mode mode,
 DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
 int cp0_timer_irq_installed;
 
+/*
+ * Possibly handle a performance counter interrupt.
+ * Return true if the timer interrupt should not be checked
+ */
+static inline int handle_perf_irq(int r2)
+{
+       /*
+        * The performance counter overflow interrupt may be shared with the
+        * timer interrupt (cp0_perfcount_irq < 0). If it is and a
+        * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
+        * and we can't reliably determine if a counter interrupt has also
+        * happened (!r2) then don't check for a timer interrupt.
+        */
+       return (cp0_perfcount_irq < 0) &&
+               perf_irq() == IRQ_HANDLED &&
+               !r2;
+}
+
 irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
 {
        const int r2 = cpu_has_mips_r2_r6;
@@ -50,27 +68,32 @@ irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
         * the performance counter interrupt handler anyway.
         */
        if (handle_perf_irq(r2))
-               goto out;
+               return IRQ_HANDLED;
 
        /*
         * The same applies to performance counter interrupts.  But with the
         * above we now know that the reason we got here must be a timer
         * interrupt.  Being the paranoiacs we are we check anyway.
         */
-       if (!r2 || (read_c0_cause() & (1 << 30))) {
+       if (!r2 || (read_c0_cause() & CAUSEF_TI)) {
                /* Clear Count/Compare Interrupt */
                write_c0_compare(read_c0_compare());
                cd = &per_cpu(mips_clockevent_device, cpu);
                cd->event_handler(cd);
+
+               return IRQ_HANDLED;
        }
 
-out:
-       return IRQ_HANDLED;
+       return IRQ_NONE;
 }
 
 struct irqaction c0_compare_irqaction = {
        .handler = c0_compare_interrupt,
-       .flags = IRQF_PERCPU | IRQF_TIMER,
+       /*
+        * IRQF_SHARED: The timer interrupt may be shared with other interrupts
+        * such as perf counter and FDC interrupts.
+        */
+       .flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED,
        .name = "timer",
 };
 
index 2ae0846..7239324 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/sched_clock.h>
 #include <asm/time.h>
 #include <asm/txx9tmr.h>
 
@@ -46,6 +47,11 @@ static struct txx9_clocksource txx9_clocksource = {
        },
 };
 
+static u64 notrace txx9_read_sched_clock(void)
+{
+       return __raw_readl(&txx9_clocksource.tmrptr->trr);
+}
+
 void __init txx9_clocksource_init(unsigned long baseaddr,
                                  unsigned int imbusclk)
 {
@@ -61,6 +67,9 @@ void __init txx9_clocksource_init(unsigned long baseaddr,
        __raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
        __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
        txx9_clocksource.tmrptr = tmrptr;
+
+       sched_clock_register(txx9_read_sched_clock, TXX9_CLOCKSOURCE_BITS,
+                            TIMER_CLK(imbusclk));
 }
 
 struct txx9_clock_event_device {
index 48dfb9d..e36515d 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <asm/bugs.h>
 #include <asm/cpu.h>
+#include <asm/cpu-features.h>
 #include <asm/cpu-type.h>
 #include <asm/fpu.h>
 #include <asm/mipsregs.h>
 #include <asm/spram.h>
 #include <asm/uaccess.h>
 
+/*
+ * Get the FPU Implementation/Revision.
+ */
+static inline unsigned long cpu_get_fpu_id(void)
+{
+       unsigned long tmp, fpu_id;
+
+       tmp = read_c0_status();
+       __enable_fpu(FPU_AS_IS);
+       fpu_id = read_32bit_cp1_register(CP1_REVISION);
+       write_c0_status(tmp);
+       return fpu_id;
+}
+
+/*
+ * Check if the CPU has an external FPU.
+ */
+static inline int __cpu_has_fpu(void)
+{
+       return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
+}
+
+static inline unsigned long cpu_get_msa_id(void)
+{
+       unsigned long status, msa_id;
+
+       status = read_c0_status();
+       __enable_fpu(FPU_64BIT);
+       enable_msa();
+       msa_id = read_msa_ir();
+       disable_msa();
+       write_c0_status(status);
+       return msa_id;
+}
+
+/*
+ * Determine the FCSR mask for FPU hardware.
+ */
+static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
+{
+       unsigned long sr, mask, fcsr, fcsr0, fcsr1;
+
+       mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM;
+
+       sr = read_c0_status();
+       __enable_fpu(FPU_AS_IS);
+
+       fcsr = read_32bit_cp1_register(CP1_STATUS);
+
+       fcsr0 = fcsr & mask;
+       write_32bit_cp1_register(CP1_STATUS, fcsr0);
+       fcsr0 = read_32bit_cp1_register(CP1_STATUS);
+
+       fcsr1 = fcsr | ~mask;
+       write_32bit_cp1_register(CP1_STATUS, fcsr1);
+       fcsr1 = read_32bit_cp1_register(CP1_STATUS);
+
+       write_32bit_cp1_register(CP1_STATUS, fcsr);
+
+       write_c0_status(sr);
+
+       c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask;
+}
+
+/*
+ * Set the FIR feature flags for the FPU emulator.
+ */
+static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
+{
+       u32 value;
+
+       value = 0;
+       if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+                           MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+                           MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
+               value |= MIPS_FPIR_D | MIPS_FPIR_S;
+       if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+                           MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
+               value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
+       c->fpu_id = value;
+}
+
+/* Determined FPU emulator mask to use for the boot CPU with "nofpu".  */
+static unsigned int mips_nofpu_msk31;
+
+/*
+ * Set options for FPU hardware.
+ */
+static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
+{
+       c->fpu_id = cpu_get_fpu_id();
+       mips_nofpu_msk31 = c->fpu_msk31;
+
+       if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
+                           MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
+                           MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
+               if (c->fpu_id & MIPS_FPIR_3D)
+                       c->ases |= MIPS_ASE_MIPS3D;
+               if (c->fpu_id & MIPS_FPIR_FREP)
+                       c->options |= MIPS_CPU_FRE;
+       }
+
+       cpu_set_fpu_fcsr_mask(c);
+}
+
+/*
+ * Set options for the FPU emulator.
+ */
+static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
+{
+       c->options &= ~MIPS_CPU_FPU;
+       c->fpu_msk31 = mips_nofpu_msk31;
+
+       cpu_set_nofpu_id(c);
+}
+
 static int mips_fpu_disabled;
 
 static int __init fpu_disable(char *s)
 {
-       cpu_data[0].options &= ~MIPS_CPU_FPU;
+       cpu_set_nofpu_opts(&boot_cpu_data);
        mips_fpu_disabled = 1;
 
        return 1;
@@ -178,41 +295,6 @@ static inline void set_elf_platform(int cpu, const char *plat)
                __elf_platform = plat;
 }
 
-/*
- * Get the FPU Implementation/Revision.
- */
-static inline unsigned long cpu_get_fpu_id(void)
-{
-       unsigned long tmp, fpu_id;
-
-       tmp = read_c0_status();
-       __enable_fpu(FPU_AS_IS);
-       fpu_id = read_32bit_cp1_register(CP1_REVISION);
-       write_c0_status(tmp);
-       return fpu_id;
-}
-
-/*
- * Check the CPU has an FPU the official way.
- */
-static inline int __cpu_has_fpu(void)
-{
-       return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
-}
-
-static inline unsigned long cpu_get_msa_id(void)
-{
-       unsigned long status, msa_id;
-
-       status = read_c0_status();
-       __enable_fpu(FPU_64BIT);
-       enable_msa();
-       msa_id = read_msa_ir();
-       disable_msa();
-       write_c0_status(status);
-       return msa_id;
-}
-
 static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
 {
 #ifdef __NEED_VMBITS_PROBE
@@ -441,6 +523,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
                c->htw_seq = 0;
                c->options |= MIPS_CPU_HTW;
        }
+       if (config3 & MIPS_CONF3_CDMM)
+               c->options |= MIPS_CPU_CDMM;
 
        return config3 & MIPS_CONF_M;
 }
@@ -516,6 +600,10 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c)
                c->options |= MIPS_CPU_MAAR;
        if (config5 & MIPS_CONF5_LLB)
                c->options |= MIPS_CPU_RW_LLB;
+#ifdef CONFIG_XPA
+       if (config5 & MIPS_CONF5_MVH)
+               c->options |= MIPS_CPU_XPA;
+#endif
 
        return config5 & MIPS_CONF_M;
 }
@@ -575,6 +663,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
        case PRID_IMP_R2000:
                c->cputype = CPU_R2000;
                __cpu_name[cpu] = "R2000";
+               c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
                c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
                             MIPS_CPU_NOFPUEX;
                if (__cpu_has_fpu())
@@ -594,6 +683,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                        c->cputype = CPU_R3000;
                        __cpu_name[cpu] = "R3000";
                }
+               c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
                c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
                             MIPS_CPU_NOFPUEX;
                if (__cpu_has_fpu())
@@ -642,6 +732,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                }
 
                set_isa(c, MIPS_CPU_ISA_III);
+               c->fpu_msk31 |= FPU_CSR_CONDX;
                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
                             MIPS_CPU_WATCH | MIPS_CPU_VCE |
                             MIPS_CPU_LLSC;
@@ -649,6 +740,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                break;
        case PRID_IMP_VR41XX:
                set_isa(c, MIPS_CPU_ISA_III);
+               c->fpu_msk31 |= FPU_CSR_CONDX;
                c->options = R4K_OPTS;
                c->tlbsize = 32;
                switch (c->processor_id & 0xf0) {
@@ -690,6 +782,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_R4300;
                __cpu_name[cpu] = "R4300";
                set_isa(c, MIPS_CPU_ISA_III);
+               c->fpu_msk31 |= FPU_CSR_CONDX;
                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
                             MIPS_CPU_LLSC;
                c->tlbsize = 32;
@@ -698,6 +791,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_R4600;
                __cpu_name[cpu] = "R4600";
                set_isa(c, MIPS_CPU_ISA_III);
+               c->fpu_msk31 |= FPU_CSR_CONDX;
                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
                             MIPS_CPU_LLSC;
                c->tlbsize = 48;
@@ -713,11 +807,13 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_R4650;
                __cpu_name[cpu] = "R4650";
                set_isa(c, MIPS_CPU_ISA_III);
+               c->fpu_msk31 |= FPU_CSR_CONDX;
                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC;
                c->tlbsize = 48;
                break;
        #endif
        case PRID_IMP_TX39:
+               c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
                c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
 
                if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
@@ -743,6 +839,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_R4700;
                __cpu_name[cpu] = "R4700";
                set_isa(c, MIPS_CPU_ISA_III);
+               c->fpu_msk31 |= FPU_CSR_CONDX;
                c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
                             MIPS_CPU_LLSC;
                c->tlbsize = 48;
@@ -751,6 +848,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_TX49XX;
                __cpu_name[cpu] = "R49XX";
                set_isa(c, MIPS_CPU_ISA_III);
+               c->fpu_msk31 |= FPU_CSR_CONDX;
                c->options = R4K_OPTS | MIPS_CPU_LLSC;
                if (!(c->processor_id & 0x08))
                        c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR;
@@ -792,6 +890,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_R6000;
                __cpu_name[cpu] = "R6000";
                set_isa(c, MIPS_CPU_ISA_II);
+               c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
                c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
                             MIPS_CPU_LLSC;
                c->tlbsize = 32;
@@ -800,6 +899,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_R6000A;
                __cpu_name[cpu] = "R6000A";
                set_isa(c, MIPS_CPU_ISA_II);
+               c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
                c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
                             MIPS_CPU_LLSC;
                c->tlbsize = 32;
@@ -850,8 +950,13 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->tlbsize = 64;
                break;
        case PRID_IMP_R14000:
-               c->cputype = CPU_R14000;
-               __cpu_name[cpu] = "R14000";
+               if (((c->processor_id >> 4) & 0x0f) > 2) {
+                       c->cputype = CPU_R16000;
+                       __cpu_name[cpu] = "R16000";
+               } else {
+                       c->cputype = CPU_R14000;
+                       __cpu_name[cpu] = "R14000";
+               }
                set_isa(c, MIPS_CPU_ISA_IV);
                c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
                             MIPS_CPU_FPU | MIPS_CPU_32FPR |
@@ -866,12 +971,14 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                        __cpu_name[cpu] = "ICT Loongson-2";
                        set_elf_platform(cpu, "loongson2e");
                        set_isa(c, MIPS_CPU_ISA_III);
+                       c->fpu_msk31 |= FPU_CSR_CONDX;
                        break;
                case PRID_REV_LOONGSON2F:
                        c->cputype = CPU_LOONGSON2;
                        __cpu_name[cpu] = "ICT Loongson-2";
                        set_elf_platform(cpu, "loongson2f");
                        set_isa(c, MIPS_CPU_ISA_III);
+                       c->fpu_msk31 |= FPU_CSR_CONDX;
                        break;
                case PRID_REV_LOONGSON3A:
                        c->cputype = CPU_LOONGSON3;
@@ -1308,6 +1415,9 @@ void cpu_probe(void)
        c->cputype      = CPU_UNKNOWN;
        c->writecombine = _CACHE_UNCACHED;
 
+       c->fpu_csr31    = FPU_CSR_RN;
+       c->fpu_msk31    = FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
+
        c->processor_id = read_c0_prid();
        switch (c->processor_id & PRID_COMP_MASK) {
        case PRID_COMP_LEGACY:
@@ -1364,16 +1474,10 @@ void cpu_probe(void)
                               ~(1 << MIPS_PWCTL_PWEN_SHIFT));
        }
 
-       if (c->options & MIPS_CPU_FPU) {
-               c->fpu_id = cpu_get_fpu_id();
-
-               if (c->isa_level & cpu_has_mips_r) {
-                       if (c->fpu_id & MIPS_FPIR_3D)
-                               c->ases |= MIPS_ASE_MIPS3D;
-                       if (c->fpu_id & MIPS_FPIR_FREP)
-                               c->options |= MIPS_CPU_FRE;
-               }
-       }
+       if (c->options & MIPS_CPU_FPU)
+               cpu_set_fpu_opts(c);
+       else
+               cpu_set_nofpu_opts(c);
 
        if (cpu_has_mips_r2_r6) {
                c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
index 468f3eb..7f65b53 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/clocksource.h>
+#include <linux/sched_clock.h>
 
 #include <asm/addrspace.h>
 #include <asm/io.h>
@@ -41,6 +38,11 @@ struct clocksource bcm1480_clocksource = {
        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static u64 notrace sb1480_read_sched_clock(void)
+{
+       return __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
+}
+
 void __init sb1480_clocksource_init(void)
 {
        struct clocksource *cs = &bcm1480_clocksource;
@@ -50,4 +52,6 @@ void __init sb1480_clocksource_init(void)
        plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
        zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
        clocksource_register_hz(cs, zbbus);
+
+       sched_clock_register(sb1480_read_sched_clock, 64, zbbus);
 }
index 6cbbf6e..722f558 100644 (file)
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <linux/clocksource.h>
+#include <linux/sched_clock.h>
 #include <linux/init.h>
 
 #include <asm/ds1287.h>
@@ -37,6 +34,11 @@ static struct clocksource clocksource_dec = {
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static u64 notrace dec_ioasic_read_sched_clock(void)
+{
+       return ioasic_read(IO_REG_FCTR);
+}
+
 int __init dec_ioasic_clocksource_init(void)
 {
        unsigned int freq;
@@ -65,5 +67,8 @@ int __init dec_ioasic_clocksource_init(void)
 
        clocksource_dec.rating = 200 + freq / 10000000;
        clocksource_register_hz(&clocksource_dec, freq);
+
+       sched_clock_register(dec_ioasic_read_sched_clock, 32, freq);
+
        return 0;
 }
index decd1fa..e5ed7ad 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <linux/clocksource.h>
 #include <linux/init.h>
+#include <linux/sched_clock.h>
 
 #include <asm/time.h>
 
@@ -22,6 +23,11 @@ static struct clocksource clocksource_mips = {
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static u64 notrace r4k_read_sched_clock(void)
+{
+       return read_c0_count();
+}
+
 int __init init_r4k_clocksource(void)
 {
        if (!cpu_has_counter || !mips_hpt_frequency)
@@ -32,5 +38,7 @@ int __init init_r4k_clocksource(void)
 
        clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
 
+       sched_clock_register(r4k_read_sched_clock, 32, mips_hpt_frequency);
+
        return 0;
 }
index 6ecb77d..d915652 100644 (file)
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/clocksource.h>
+#include <linux/sched_clock.h>
 
 #include <asm/addrspace.h>
 #include <asm/io.h>
  * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
  * again.
  */
-static cycle_t sb1250_hpt_read(struct clocksource *cs)
+static inline cycle_t sb1250_hpt_get_cycles(void)
 {
        unsigned int count;
+       void __iomem *addr;
 
-       count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT))));
+       addr = IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT));
+       count = G_SCD_TIMER_CNT(__raw_readq(addr));
 
        return SB1250_HPT_VALUE - count;
 }
 
+static cycle_t sb1250_hpt_read(struct clocksource *cs)
+{
+       return sb1250_hpt_get_cycles();
+}
+
 struct clocksource bcm1250_clocksource = {
        .name   = "bcm1250-counter-3",
        .rating = 200,
@@ -50,6 +54,11 @@ struct clocksource bcm1250_clocksource = {
        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static u64 notrace sb1250_read_sched_clock(void)
+{
+       return sb1250_hpt_get_cycles();
+}
+
 void __init sb1250_clocksource_init(void)
 {
        struct clocksource *cs = &bcm1250_clocksource;
@@ -66,4 +75,6 @@ void __init sb1250_clocksource_init(void)
                                                 R_SCD_TIMER_CFG)));
 
        clocksource_register_hz(cs, V_SCD_TIMER_FREQ);
+
+       sched_clock_register(sb1250_read_sched_clock, 23, V_SCD_TIMER_FREQ);
 }
index d2c09f6..be4899f 100644 (file)
@@ -131,16 +131,6 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
        return 0;
 }
 
-static inline unsigned get_fp_abi(int in_abi)
-{
-       /* If the ABI requirement is provided, simply return that */
-       if (in_abi != MIPS_ABI_FP_UNKNOWN)
-               return in_abi;
-
-       /* Unknown ABI */
-       return MIPS_ABI_FP_UNKNOWN;
-}
-
 int arch_check_elf(void *_ehdr, bool has_interpreter,
                   struct arch_elf_state *state)
 {
@@ -151,10 +141,10 @@ int arch_check_elf(void *_ehdr, bool has_interpreter,
        if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT))
                return 0;
 
-       fp_abi = get_fp_abi(state->fp_abi);
+       fp_abi = state->fp_abi;
 
        if (has_interpreter) {
-               interp_fp_abi = get_fp_abi(state->interp_fp_abi);
+               interp_fp_abi = state->interp_fp_abi;
 
                abi0 = min(fp_abi, interp_fp_abi);
                abi1 = max(fp_abi, interp_fp_abi);
index af41ba6..7791840 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
+#include <asm/compiler.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
@@ -185,7 +186,7 @@ syscall_exit_work:
  * For C code use the inline version named instruction_hazard().
  */
 LEAF(mips_ihb)
-       .set    mips32r2
+       .set    MIPS_ISA_LEVEL_RAW
        jr.hb   ra
        nop
        END(mips_ihb)
index 368c88b..e4f62b7 100644 (file)
@@ -176,6 +176,17 @@ void __init check_wait(void)
                cpu_wait = rm7k_wait_irqoff;
                break;
 
+       case CPU_PROAPTIV:
+       case CPU_P5600:
+               /*
+                * Incoming Fast Debug Channel (FDC) data during a wait
+                * instruction causes the wait never to resume, even if an
+                * interrupt is received. Avoid using wait at all if FDC data is
+                * likely to be received.
+                */
+               if (IS_ENABLED(CONFIG_MIPS_EJTAG_FDC_TTY))
+                       break;
+               /* fall through */
        case CPU_M14KC:
        case CPU_M14KEC:
        case CPU_24K:
@@ -183,8 +194,6 @@ void __init check_wait(void)
        case CPU_1004K:
        case CPU_1074K:
        case CPU_INTERAPTIV:
-       case CPU_PROAPTIV:
-       case CPU_P5600:
        case CPU_M5150:
        case CPU_QEMU_GENERIC:
                cpu_wait = r4k_wait;
index 64d17e4..f2977f0 100644 (file)
@@ -187,7 +187,7 @@ static inline int mipsr6_emul(struct pt_regs *regs, u32 ir)
 }
 
 /**
- * movt_func - Emulate a MOVT instruction
+ * movf_func - Emulate a MOVF instruction
  * @regs: Process register set
  * @ir: Instruction
  *
@@ -200,9 +200,12 @@ static int movf_func(struct pt_regs *regs, u32 ir)
 
        csr = current->thread.fpu.fcr31;
        cond = fpucondbit[MIPSInst_RT(ir) >> 2];
+
        if (((csr & cond) == 0) && MIPSInst_RD(ir))
                regs->regs[MIPSInst_RD(ir)] = regs->regs[MIPSInst_RS(ir)];
+
        MIPS_R2_STATS(movs);
+
        return 0;
 }
 
@@ -895,8 +898,9 @@ static inline int mipsr2_find_op_func(struct pt_regs *regs, u32 inst,
  * mipsr2_decoder: Decode and emulate a MIPS R2 instruction
  * @regs: Process register set
  * @inst: Instruction to decode and emulate
+ * @fcr31: Floating Point Control and Status Register returned
  */
-int mipsr2_decoder(struct pt_regs *regs, u32 inst)
+int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31)
 {
        int err = 0;
        unsigned long vaddr;
@@ -1165,6 +1169,13 @@ fpu_emul:
 
                err = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 0,
                                               &fault_addr);
+               *fcr31 = current->thread.fpu.fcr31;
+
+               /*
+                * We can't allow the emulated instruction to leave any of
+                * the cause bits set in $fcr31.
+                */
+               current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
 
                /*
                 * this is a tricky issue - lose_fpu() uses LL/SC atomics
index 9466184..cc1b6fa 100644 (file)
@@ -558,8 +558,10 @@ static int mipspmu_get_irq(void)
        if (mipspmu.irq >= 0) {
                /* Request my own irq handler. */
                err = request_irq(mipspmu.irq, mipsxx_pmu_handle_irq,
-                       IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD,
-                       "mips_perf_pmu", NULL);
+                                 IRQF_PERCPU | IRQF_NOBALANCING |
+                                 IRQF_NO_THREAD | IRQF_NO_SUSPEND |
+                                 IRQF_SHARED,
+                                 "mips_perf_pmu", &mipspmu);
                if (err) {
                        pr_warn("Unable to request IRQ%d for MIPS performance counters!\n",
                                mipspmu.irq);
@@ -582,7 +584,7 @@ static int mipspmu_get_irq(void)
 static void mipspmu_free_irq(void)
 {
        if (mipspmu.irq >= 0)
-               free_irq(mipspmu.irq, NULL);
+               free_irq(mipspmu.irq, &mipspmu);
        else if (cp0_perfcount_irq < 0)
                perf_irq = save_perf_irq;
 }
@@ -775,6 +777,7 @@ static int n_counters(void)
 
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
                counters = 4;
                break;
 
@@ -822,6 +825,13 @@ static const struct mips_perf_event mipsxxcore_event_map2
        [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T },
 };
 
+static const struct mips_perf_event loongson3_event_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN },
+       [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, CNTR_ODD },
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x01, CNTR_EVEN },
+       [PERF_COUNT_HW_BRANCH_MISSES] = { 0x01, CNTR_ODD },
+};
+
 static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = {
        [PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL },
        [PERF_COUNT_HW_INSTRUCTIONS] = { 0x03, CNTR_ALL },
@@ -1005,6 +1015,61 @@ static const struct mips_perf_event mipsxxcore_cache_map2
 },
 };
 
+static const struct mips_perf_event loongson3_cache_map
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+[C(L1D)] = {
+       /*
+        * Like some other architectures (e.g. ARM), the performance
+        * counters don't differentiate between read and write
+        * accesses/misses, so this isn't strictly correct, but it's the
+        * best we can do. Writes and reads get combined.
+        */
+       [C(OP_READ)] = {
+               [C(RESULT_MISS)]        = { 0x04, CNTR_ODD },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_MISS)]        = { 0x04, CNTR_ODD },
+       },
+},
+[C(L1I)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_MISS)]        = { 0x04, CNTR_EVEN },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_MISS)]        = { 0x04, CNTR_EVEN },
+       },
+},
+[C(DTLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_MISS)]        = { 0x09, CNTR_ODD },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_MISS)]        = { 0x09, CNTR_ODD },
+       },
+},
+[C(ITLB)] = {
+       [C(OP_READ)] = {
+               [C(RESULT_MISS)]        = { 0x0c, CNTR_ODD },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_MISS)]        = { 0x0c, CNTR_ODD },
+       },
+},
+[C(BPU)] = {
+       /* Using the same code for *HW_BRANCH* */
+       [C(OP_READ)] = {
+               [C(RESULT_ACCESS)]      = { 0x02, CNTR_EVEN },
+               [C(RESULT_MISS)]        = { 0x02, CNTR_ODD },
+       },
+       [C(OP_WRITE)] = {
+               [C(RESULT_ACCESS)]      = { 0x02, CNTR_EVEN },
+               [C(RESULT_MISS)]        = { 0x02, CNTR_ODD },
+       },
+},
+};
+
 /* BMIPS5000 */
 static const struct mips_perf_event bmips5000_cache_map
                                [PERF_COUNT_HW_CACHE_MAX]
@@ -1539,6 +1604,10 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
                else
                        raw_event.cntr_mask =
                                raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+               break;
+       case CPU_LOONGSON3:
+               raw_event.cntr_mask = raw_id > 127 ? CNTR_ODD : CNTR_EVEN;
+       break;
        }
 
        raw_event.event_id = base_id;
@@ -1615,8 +1684,7 @@ init_hw_perf_events(void)
 
        if (get_c0_perfcount_int)
                irq = get_c0_perfcount_int();
-       else if ((cp0_perfcount_irq >= 0) &&
-                (cp0_compare_irq != cp0_perfcount_irq))
+       else if (cp0_perfcount_irq >= 0)
                irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
        else
                irq = -1;
@@ -1669,6 +1737,11 @@ init_hw_perf_events(void)
                mipspmu.general_event_map = &mipsxxcore_event_map;
                mipspmu.cache_event_map = &mipsxxcore_cache_map;
                break;
+       case CPU_LOONGSON3:
+               mipspmu.name = "mips/loongson3";
+               mipspmu.general_event_map = &loongson3_event_map;
+               mipspmu.cache_event_map = &loongson3_cache_map;
+               break;
        case CPU_CAVIUM_OCTEON:
        case CPU_CAVIUM_OCTEON_PLUS:
        case CPU_CAVIUM_OCTEON2:
index 130af7d..298b2b7 100644 (file)
@@ -120,6 +120,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        if (cpu_has_msa)        seq_printf(m, "%s", " msa");
        if (cpu_has_eva)        seq_printf(m, "%s", " eva");
        if (cpu_has_htw)        seq_printf(m, "%s", " htw");
+       if (cpu_has_xpa)        seq_printf(m, "%s", " xpa");
        seq_printf(m, "\n");
 
        if (cpu_has_mmips) {
index bf85cc1..d295bd1 100644 (file)
@@ -107,8 +107,11 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
        return 0;
 }
 
+/*
+ * Copy architecture-specific thread state
+ */
 int copy_thread(unsigned long clone_flags, unsigned long usp,
-       unsigned long arg, struct task_struct *p)
+       unsigned long kthread_arg, struct task_struct *p)
 {
        struct thread_info *ti = task_thread_info(p);
        struct pt_regs *childregs, *regs = current_pt_regs();
@@ -123,11 +126,12 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        childksp = (unsigned long) childregs;
        p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1);
        if (unlikely(p->flags & PF_KTHREAD)) {
+               /* kernel thread */
                unsigned long status = p->thread.cp0_status;
                memset(childregs, 0, sizeof(struct pt_regs));
                ti->addr_limit = KERNEL_DS;
                p->thread.reg16 = usp; /* fn */
-               p->thread.reg17 = arg;
+               p->thread.reg17 = kthread_arg;
                p->thread.reg29 = childksp;
                p->thread.reg31 = (unsigned long) ret_from_kernel_thread;
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
@@ -139,6 +143,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
                childregs->cp0_status = status;
                return 0;
        }
+
+       /* user thread */
        *childregs = *regs;
        childregs->regs[7] = 0; /* Clear error flag */
        childregs->regs[2] = 0; /* Child gets zero as return value */
index 452d435..e303cb1 100644 (file)
@@ -64,7 +64,10 @@ int __init __dt_register_buses(const char *bus0, const char *bus1)
                panic("device tree not present");
 
        strlcpy(of_ids[0].compatible, bus0, sizeof(of_ids[0].compatible));
-       strlcpy(of_ids[1].compatible, bus1, sizeof(of_ids[1].compatible));
+       if (bus1) {
+               strlcpy(of_ids[1].compatible, bus1,
+                       sizeof(of_ids[1].compatible));
+       }
 
        if (of_platform_populate(NULL, of_ids, NULL, NULL))
                panic("failed to populate DT");
index 7da6e32..d544e77 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
+#include <asm/cpu-info.h>
 #include <asm/dsp.h>
 #include <asm/fpu.h>
 #include <asm/mipsregs.h>
@@ -157,6 +158,9 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
 {
        union fpureg *fregs;
        u64 fpr_val;
+       u32 fcr31;
+       u32 value;
+       u32 mask;
        int i;
 
        if (!access_ok(VERIFY_READ, data, 33 * 8))
@@ -170,8 +174,10 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
                set_fpr64(&fregs[i], 0, fpr_val);
        }
 
-       __get_user(child->thread.fpu.fcr31, data + 64);
-       child->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+       __get_user(value, data + 64);
+       fcr31 = child->thread.fpu.fcr31;
+       mask = current_cpu_data.fpu_msk31;
+       child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
 
        /* FIR may not be written.  */
 
index 435ea65..5087a4b 100644 (file)
@@ -115,11 +115,9 @@ LEAF(_restore_fp)
  * the property that no matter whether considered as single or as double
  * precision represents signaling NANS.
  *
- * We initialize fcr31 to rounding to nearest, no exceptions.
+ * The value to initialize fcr31 to comes in $a0.
  */
 
-#define FPU_DEFAULT  0x00000000
-
        .set push
        SET_HARDFLOAT
 
@@ -129,8 +127,7 @@ LEAF(_init_fpu)
        or      t0, t1
        mtc0    t0, CP0_STATUS
 
-       li      t1, FPU_DEFAULT
-       ctc1    t1, fcr31
+       ctc1    a0, fcr31
 
        li      t0, -1
 
index 3b1a36f..04cbbde 100644 (file)
@@ -165,11 +165,9 @@ LEAF(_init_msa_upper)
  * the property that no matter whether considered as single or as double
  * precision represents signaling NANS.
  *
- * We initialize fcr31 to rounding to nearest, no exceptions.
+ * The value to initialize fcr31 to comes in $a0.
  */
 
-#define FPU_DEFAULT  0x00000000
-
        .set push
        SET_HARDFLOAT
 
@@ -180,8 +178,7 @@ LEAF(_init_fpu)
        mtc0    t0, CP0_STATUS
        enable_fpu_hazard
 
-       li      t1, FPU_DEFAULT
-       ctc1    t1, fcr31
+       ctc1    a0, fcr31
 
        li      t1, -1                          # SNaN
 
index 07fc524..7c746d3 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/pm.h>
 #include <linux/types.h>
 #include <linux/reboot.h>
+#include <linux/delay.h>
 
 #include <asm/reboot.h>
 
@@ -29,16 +30,40 @@ void machine_restart(char *command)
 {
        if (_machine_restart)
                _machine_restart(command);
+
+#ifdef CONFIG_SMP
+       preempt_disable();
+       smp_send_stop();
+#endif
+       do_kernel_restart(command);
+       mdelay(1000);
+       pr_emerg("Reboot failed -- System halted\n");
+       local_irq_disable();
+       while (1);
 }
 
 void machine_halt(void)
 {
        if (_machine_halt)
                _machine_halt();
+
+#ifdef CONFIG_SMP
+       preempt_disable();
+       smp_send_stop();
+#endif
+       local_irq_disable();
+       while (1);
 }
 
 void machine_power_off(void)
 {
        if (pm_power_off)
                pm_power_off();
+
+#ifdef CONFIG_SMP
+       preempt_disable();
+       smp_send_stop();
+#endif
+       local_irq_disable();
+       while (1);
 }
index 0589290..be73c49 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/bootinfo.h>
 #include <asm/bugs.h>
 #include <asm/cache.h>
+#include <asm/cdmm.h>
 #include <asm/cpu.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
@@ -763,6 +764,7 @@ void __init setup_arch(char **cmdline_p)
        cpu_probe();
        prom_init();
 
+       setup_early_fdc_console();
 #ifdef CONFIG_EARLY_PRINTK
        setup_early_printk();
 #endif
index bed7590..d5589be 100644 (file)
@@ -88,6 +88,12 @@ static void __init cps_smp_setup(void)
 
        /* Make core 0 coherent with everything */
        write_gcr_cl_coherence(0xff);
+
+#ifdef CONFIG_MIPS_MT_FPAFF
+       /* If we have an FPU, enroll ourselves in the FPU-full mask */
+       if (cpu_has_fpu)
+               cpu_set(0, mt_fpu_cpumask);
+#endif /* CONFIG_MIPS_MT_FPAFF */
 }
 
 static void __init cps_prepare_cpus(unsigned int max_cpus)
index 1c0d8c5..5b020bd 100644 (file)
@@ -176,10 +176,8 @@ static void stop_this_cpu(void *dummy)
         * Remove this CPU:
         */
        set_cpu_online(smp_processor_id(), false);
-       for (;;) {
-               if (cpu_wait)
-                       (*cpu_wait)();          /* Wait if available. */
-       }
+       local_irq_disable();
+       while (1);
 }
 
 void smp_send_stop(void)
index 5b4d711..e334c64 100644 (file)
@@ -12,6 +12,7 @@
  * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
  * Copyright (C) 2014, Imagination Technologies Ltd.
  */
+#include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/compiler.h>
 #include <linux/context_tracking.h>
@@ -699,36 +700,60 @@ asmlinkage void do_ov(struct pt_regs *regs)
        exception_exit(prev_state);
 }
 
-int process_fpemu_return(int sig, void __user *fault_addr)
+int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
 {
-       /*
-        * We can't allow the emulated instruction to leave any of the cause
-        * bits set in FCSR. If they were then the kernel would take an FP
-        * exception when restoring FP context.
-        */
-       current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+       struct siginfo si = { 0 };
+
+       switch (sig) {
+       case 0:
+               return 0;
 
-       if (sig == SIGSEGV || sig == SIGBUS) {
-               struct siginfo si = {0};
+       case SIGFPE:
                si.si_addr = fault_addr;
                si.si_signo = sig;
-               if (sig == SIGSEGV) {
-                       down_read(&current->mm->mmap_sem);
-                       if (find_vma(current->mm, (unsigned long)fault_addr))
-                               si.si_code = SEGV_ACCERR;
-                       else
-                               si.si_code = SEGV_MAPERR;
-                       up_read(&current->mm->mmap_sem);
-               } else {
-                       si.si_code = BUS_ADRERR;
-               }
+               /*
+                * Inexact can happen together with Overflow or Underflow.
+                * Respect the mask to deliver the correct exception.
+                */
+               fcr31 &= (fcr31 & FPU_CSR_ALL_E) <<
+                        (ffs(FPU_CSR_ALL_X) - ffs(FPU_CSR_ALL_E));
+               if (fcr31 & FPU_CSR_INV_X)
+                       si.si_code = FPE_FLTINV;
+               else if (fcr31 & FPU_CSR_DIV_X)
+                       si.si_code = FPE_FLTDIV;
+               else if (fcr31 & FPU_CSR_OVF_X)
+                       si.si_code = FPE_FLTOVF;
+               else if (fcr31 & FPU_CSR_UDF_X)
+                       si.si_code = FPE_FLTUND;
+               else if (fcr31 & FPU_CSR_INE_X)
+                       si.si_code = FPE_FLTRES;
+               else
+                       si.si_code = __SI_FAULT;
+               force_sig_info(sig, &si, current);
+               return 1;
+
+       case SIGBUS:
+               si.si_addr = fault_addr;
+               si.si_signo = sig;
+               si.si_code = BUS_ADRERR;
+               force_sig_info(sig, &si, current);
+               return 1;
+
+       case SIGSEGV:
+               si.si_addr = fault_addr;
+               si.si_signo = sig;
+               down_read(&current->mm->mmap_sem);
+               if (find_vma(current->mm, (unsigned long)fault_addr))
+                       si.si_code = SEGV_ACCERR;
+               else
+                       si.si_code = SEGV_MAPERR;
+               up_read(&current->mm->mmap_sem);
                force_sig_info(sig, &si, current);
                return 1;
-       } else if (sig) {
+
+       default:
                force_sig(sig, current);
                return 1;
-       } else {
-               return 0;
        }
 }
 
@@ -736,7 +761,8 @@ static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
                       unsigned long old_epc, unsigned long old_ra)
 {
        union mips_instruction inst = { .word = opcode };
-       void __user *fault_addr = NULL;
+       void __user *fault_addr;
+       unsigned long fcr31;
        int sig;
 
        /* If it's obviously not an FP instruction, skip it */
@@ -766,13 +792,20 @@ static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
        /* Run the emulator */
        sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
                                       &fault_addr);
+       fcr31 = current->thread.fpu.fcr31;
 
-       /* If something went wrong, signal */
-       process_fpemu_return(sig, fault_addr);
+       /*
+        * We can't allow the emulated instruction to leave any of
+        * the cause bits set in $fcr31.
+        */
+       current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
 
        /* Restore the hardware register state */
        own_fpu(1);
 
+       /* Send a signal if required.  */
+       process_fpemu_return(sig, fault_addr, fcr31);
+
        return 0;
 }
 
@@ -782,7 +815,8 @@ static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
        enum ctx_state prev_state;
-       siginfo_t info = {0};
+       void __user *fault_addr;
+       int sig;
 
        prev_state = exception_enter();
        if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs),
@@ -796,9 +830,6 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
        die_if_kernel("FP exception in kernel code", regs);
 
        if (fcr31 & FPU_CSR_UNI_X) {
-               int sig;
-               void __user *fault_addr = NULL;
-
                /*
                 * Unimplemented operation exception.  If we've got the full
                 * software emulator on-board, let's use it...
@@ -815,30 +846,23 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                /* Run the emulator */
                sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
                                               &fault_addr);
+               fcr31 = current->thread.fpu.fcr31;
 
-               /* If something went wrong, signal */
-               process_fpemu_return(sig, fault_addr);
+               /*
+                * We can't allow the emulated instruction to leave any of
+                * the cause bits set in $fcr31.
+                */
+               current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
 
                /* Restore the hardware register state */
                own_fpu(1);     /* Using the FPU again.  */
+       } else {
+               sig = SIGFPE;
+               fault_addr = (void __user *) regs->cp0_epc;
+       }
 
-               goto out;
-       } else if (fcr31 & FPU_CSR_INV_X)
-               info.si_code = FPE_FLTINV;
-       else if (fcr31 & FPU_CSR_DIV_X)
-               info.si_code = FPE_FLTDIV;
-       else if (fcr31 & FPU_CSR_OVF_X)
-               info.si_code = FPE_FLTOVF;
-       else if (fcr31 & FPU_CSR_UDF_X)
-               info.si_code = FPE_FLTUND;
-       else if (fcr31 & FPU_CSR_INE_X)
-               info.si_code = FPE_FLTRES;
-       else
-               info.si_code = __SI_FAULT;
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_addr = (void __user *) regs->cp0_epc;
-       force_sig_info(SIGFPE, &info, current);
+       /* Send a signal if required.  */
+       process_fpemu_return(sig, fault_addr, fcr31);
 
 out:
        exception_exit(prev_state);
@@ -885,9 +909,9 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
                break;
        case BRK_MEMU:
                /*
-                * Address errors may be deliberately induced by the FPU
-                * emulator to retake control of the CPU after executing the
-                * instruction in the delay slot of an emulated branch.
+                * This breakpoint code is used by the FPU emulator to retake
+                * control of the CPU after executing the instruction from the
+                * delay slot of an emulated branch.
                 *
                 * Terminate if exception was recognized as a delay slot return
                 * otherwise handle as normal.
@@ -907,10 +931,9 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
 
 asmlinkage void do_bp(struct pt_regs *regs)
 {
+       unsigned long epc = msk_isa16_mode(exception_epc(regs));
        unsigned int opcode, bcode;
        enum ctx_state prev_state;
-       unsigned long epc;
-       u16 instr[2];
        mm_segment_t seg;
 
        seg = get_fs();
@@ -919,26 +942,28 @@ asmlinkage void do_bp(struct pt_regs *regs)
 
        prev_state = exception_enter();
        if (get_isa16_mode(regs->cp0_epc)) {
-               /* Calculate EPC. */
-               epc = exception_epc(regs);
-               if (cpu_has_mmips) {
-                       if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc)) ||
-                           (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2)))))
-                               goto out_sigsegv;
-                       opcode = (instr[0] << 16) | instr[1];
-               } else {
+               u16 instr[2];
+
+               if (__get_user(instr[0], (u16 __user *)epc))
+                       goto out_sigsegv;
+
+               if (!cpu_has_mmips) {
                        /* MIPS16e mode */
-                       if (__get_user(instr[0],
-                                      (u16 __user *)msk_isa16_mode(epc)))
+                       bcode = (instr[0] >> 5) & 0x3f;
+               } else if (mm_insn_16bit(instr[0])) {
+                       /* 16-bit microMIPS BREAK */
+                       bcode = instr[0] & 0xf;
+               } else {
+                       /* 32-bit microMIPS BREAK */
+                       if (__get_user(instr[1], (u16 __user *)(epc + 2)))
                                goto out_sigsegv;
-                       bcode = (instr[0] >> 6) & 0x3f;
-                       do_trap_or_bp(regs, bcode, "Break");
-                       goto out;
+                       opcode = (instr[0] << 16) | instr[1];
+                       bcode = (opcode >> 6) & ((1 << 20) - 1);
                }
        } else {
-               if (__get_user(opcode,
-                              (unsigned int __user *) exception_epc(regs)))
+               if (__get_user(opcode, (unsigned int __user *)epc))
                        goto out_sigsegv;
+               bcode = (opcode >> 6) & ((1 << 20) - 1);
        }
 
        /*
@@ -947,9 +972,8 @@ asmlinkage void do_bp(struct pt_regs *regs)
         * Gas is bug-compatible, but not always, grrr...
         * We handle both cases with a simple heuristics.  --macro
         */
-       bcode = ((opcode >> 6) & ((1 << 20) - 1));
        if (bcode >= (1 << 10))
-               bcode >>= 10;
+               bcode = ((bcode & ((1 << 10) - 1)) << 10) | (bcode >> 10);
 
        /*
         * notify the kprobe handlers, if instruction is likely to
@@ -1039,22 +1063,24 @@ asmlinkage void do_ri(struct pt_regs *regs)
         * as quickly as possible.
         */
        if (mipsr2_emulation && cpu_has_mips_r6 &&
-           likely(user_mode(regs))) {
-               if (likely(get_user(opcode, epc) >= 0)) {
-                       status = mipsr2_decoder(regs, opcode);
-                       switch (status) {
-                       case 0:
-                       case SIGEMT:
-                               task_thread_info(current)->r2_emul_return = 1;
-                               return;
-                       case SIGILL:
-                               goto no_r2_instr;
-                       default:
-                               process_fpemu_return(status,
-                                                    &current->thread.cp0_baduaddr);
-                               task_thread_info(current)->r2_emul_return = 1;
-                               return;
-                       }
+           likely(user_mode(regs)) &&
+           likely(get_user(opcode, epc) >= 0)) {
+               unsigned long fcr31 = 0;
+
+               status = mipsr2_decoder(regs, opcode, &fcr31);
+               switch (status) {
+               case 0:
+               case SIGEMT:
+                       task_thread_info(current)->r2_emul_return = 1;
+                       return;
+               case SIGILL:
+                       goto no_r2_instr;
+               default:
+                       process_fpemu_return(status,
+                                            &current->thread.cp0_baduaddr,
+                                            fcr31);
+                       task_thread_info(current)->r2_emul_return = 1;
+                       return;
                }
        }
 
@@ -1299,10 +1325,13 @@ asmlinkage void do_cpu(struct pt_regs *regs)
        enum ctx_state prev_state;
        unsigned int __user *epc;
        unsigned long old_epc, old31;
+       void __user *fault_addr;
        unsigned int opcode;
+       unsigned long fcr31;
        unsigned int cpid;
        int status, err;
        unsigned long __maybe_unused flags;
+       int sig;
 
        prev_state = exception_enter();
        cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
@@ -1319,7 +1348,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
                status = -1;
 
                if (unlikely(compute_return_epc(regs) < 0))
-                       goto out;
+                       break;
 
                if (get_isa16_mode(regs->cp0_epc)) {
                        unsigned short mmop[2] = { 0 };
@@ -1352,49 +1381,54 @@ asmlinkage void do_cpu(struct pt_regs *regs)
                        force_sig(status, current);
                }
 
-               goto out;
+               break;
 
        case 3:
                /*
-                * Old (MIPS I and MIPS II) processors will set this code
-                * for COP1X opcode instructions that replaced the original
-                * COP3 space.  We don't limit COP1 space instructions in
-                * the emulator according to the CPU ISA, so we want to
-                * treat COP1X instructions consistently regardless of which
-                * code the CPU chose.  Therefore we redirect this trap to
-                * the FP emulator too.
-                *
-                * Then some newer FPU-less processors use this code
-                * erroneously too, so they are covered by this choice
-                * as well.
+                * The COP3 opcode space and consequently the CP0.Status.CU3
+                * bit and the CP0.Cause.CE=3 encoding have been removed as
+                * of the MIPS III ISA.  From the MIPS IV and MIPS32r2 ISAs
+                * up the space has been reused for COP1X instructions, that
+                * are enabled by the CP0.Status.CU1 bit and consequently
+                * use the CP0.Cause.CE=1 encoding for Coprocessor Unusable
+                * exceptions.  Some FPU-less processors that implement one
+                * of these ISAs however use this code erroneously for COP1X
+                * instructions.  Therefore we redirect this trap to the FP
+                * emulator too.
                 */
-               if (raw_cpu_has_fpu)
+               if (raw_cpu_has_fpu || !cpu_has_mips_4_5_64_r2_r6) {
+                       force_sig(SIGILL, current);
                        break;
+               }
                /* Fall through.  */
 
        case 1:
                err = enable_restore_fp_context(0);
 
-               if (!raw_cpu_has_fpu || err) {
-                       int sig;
-                       void __user *fault_addr = NULL;
-                       sig = fpu_emulator_cop1Handler(regs,
-                                                      &current->thread.fpu,
-                                                      0, &fault_addr);
-                       if (!process_fpemu_return(sig, fault_addr) && !err)
-                               mt_ase_fp_affinity();
-               }
+               if (raw_cpu_has_fpu && !err)
+                       break;
 
-               goto out;
+               sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 0,
+                                              &fault_addr);
+               fcr31 = current->thread.fpu.fcr31;
+
+               /*
+                * We can't allow the emulated instruction to leave
+                * any of the cause bits set in $fcr31.
+                */
+               current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
+
+               /* Send a signal if required.  */
+               if (!process_fpemu_return(sig, fault_addr, fcr31) && !err)
+                       mt_ase_fp_affinity();
+
+               break;
 
        case 2:
                raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
-               goto out;
+               break;
        }
 
-       force_sig(SIGILL, current);
-
-out:
        exception_exit(prev_state);
 }
 
@@ -1984,6 +2018,12 @@ int cp0_compare_irq_shift;
 int cp0_perfcount_irq;
 EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
 
+/*
+ * Fast debug channel IRQ or -1 if not present
+ */
+int cp0_fdc_irq;
+EXPORT_SYMBOL_GPL(cp0_fdc_irq);
+
 static int noulri;
 
 static int __init ulri_disable(char *s)
@@ -2065,17 +2105,21 @@ void per_cpu_trap_init(bool is_boot_cpu)
         *
         *  o read IntCtl.IPTI to determine the timer interrupt
         *  o read IntCtl.IPPCI to determine the performance counter interrupt
+        *  o read IntCtl.IPFDC to determine the fast debug channel interrupt
         */
        if (cpu_has_mips_r2_r6) {
                cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
                cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
                cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
-               if (cp0_perfcount_irq == cp0_compare_irq)
-                       cp0_perfcount_irq = -1;
+               cp0_fdc_irq = (read_c0_intctl() >> INTCTLB_IPFDC) & 7;
+               if (!cp0_fdc_irq)
+                       cp0_fdc_irq = -1;
+
        } else {
                cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
                cp0_compare_irq_shift = CP0_LEGACY_PERFCNT_IRQ;
                cp0_perfcount_irq = -1;
+               cp0_fdc_irq = -1;
        }
 
        if (!cpu_data[cpu].asid_cache)
index bbb6969..af84bef 100644 (file)
@@ -89,8 +89,6 @@
 #include <asm/fpu_emulator.h>
 #include <asm/inst.h>
 #include <asm/uaccess.h>
-#include <asm/fpu.h>
-#include <asm/fpu_emulator.h>
 
 #define STR(x) __STR(x)
 #define __STR(x)  #x
@@ -109,10 +107,11 @@ static u32 unaligned_action;
 extern void show_registers(struct pt_regs *regs);
 
 #ifdef __BIG_ENDIAN
-#define     LoadHW(addr, value, res)  \
+#define     _LoadHW(addr, value, res, type)  \
+do {                                                        \
                __asm__ __volatile__ (".set\tnoat\n"        \
-                       "1:\t"user_lb("%0", "0(%2)")"\n"    \
-                       "2:\t"user_lbu("$1", "1(%2)")"\n\t" \
+                       "1:\t"type##_lb("%0", "0(%2)")"\n"  \
+                       "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
                        "li\t%1, 0\n"                       \
@@ -127,13 +126,15 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 
 #ifndef CONFIG_CPU_MIPSR6
-#define     LoadW(addr, value, res)   \
+#define     _LoadW(addr, value, res, type)   \
+do {                                                        \
                __asm__ __volatile__ (                      \
-                       "1:\t"user_lwl("%0", "(%2)")"\n"    \
-                       "2:\t"user_lwr("%0", "3(%2)")"\n\t" \
+                       "1:\t"type##_lwl("%0", "(%2)")"\n"   \
+                       "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
                        "li\t%1, 0\n"                       \
                        "3:\n\t"                            \
                        ".insn\n\t"                         \
@@ -146,21 +147,24 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
+
 #else
 /* MIPSR6 has no lwl instruction */
-#define     LoadW(addr, value, res) \
+#define     _LoadW(addr, value, res, type) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n"                      \
                        ".set\tnoat\n\t"                    \
-                       "1:"user_lb("%0", "0(%2)")"\n\t"    \
-                       "2:"user_lbu("$1", "1(%2)")"\n\t"   \
+                       "1:"type##_lb("%0", "0(%2)")"\n\t"  \
+                       "2:"type##_lbu("$1", "1(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
-                       "3:"user_lbu("$1", "2(%2)")"\n\t"   \
+                       "3:"type##_lbu("$1", "2(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
-                       "4:"user_lbu("$1", "3(%2)")"\n\t"   \
+                       "4:"type##_lbu("$1", "3(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
                        "li\t%1, 0\n"                       \
@@ -178,14 +182,17 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t4b, 11b\n\t"             \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
+
 #endif /* CONFIG_CPU_MIPSR6 */
 
-#define     LoadHWU(addr, value, res) \
+#define     _LoadHWU(addr, value, res, type) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tnoat\n"                      \
-                       "1:\t"user_lbu("%0", "0(%2)")"\n"   \
-                       "2:\t"user_lbu("$1", "1(%2)")"\n\t" \
+                       "1:\t"type##_lbu("%0", "0(%2)")"\n" \
+                       "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
                        "li\t%1, 0\n"                       \
@@ -201,13 +208,15 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 
 #ifndef CONFIG_CPU_MIPSR6
-#define     LoadWU(addr, value, res)  \
+#define     _LoadWU(addr, value, res, type)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
-                       "1:\t"user_lwl("%0", "(%2)")"\n"    \
-                       "2:\t"user_lwr("%0", "3(%2)")"\n\t" \
+                       "1:\t"type##_lwl("%0", "(%2)")"\n"  \
+                       "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\
                        "dsll\t%0, %0, 32\n\t"              \
                        "dsrl\t%0, %0, 32\n\t"              \
                        "li\t%1, 0\n"                       \
@@ -222,9 +231,11 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 
-#define     LoadDW(addr, value, res)  \
+#define     _LoadDW(addr, value, res)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        "1:\tldl\t%0, (%2)\n"               \
                        "2:\tldr\t%0, 7(%2)\n\t"            \
@@ -240,21 +251,24 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
+
 #else
 /* MIPSR6 has not lwl and ldl instructions */
-#define            LoadWU(addr, value, res) \
+#define            _LoadWU(addr, value, res, type) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n\t"                    \
                        ".set\tnoat\n\t"                    \
-                       "1:"user_lbu("%0", "0(%2)")"\n\t"   \
-                       "2:"user_lbu("$1", "1(%2)")"\n\t"   \
+                       "1:"type##_lbu("%0", "0(%2)")"\n\t" \
+                       "2:"type##_lbu("$1", "1(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
-                       "3:"user_lbu("$1", "2(%2)")"\n\t"   \
+                       "3:"type##_lbu("$1", "2(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
-                       "4:"user_lbu("$1", "3(%2)")"\n\t"   \
+                       "4:"type##_lbu("$1", "3(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
                        "li\t%1, 0\n"                       \
@@ -272,9 +286,11 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t4b, 11b\n\t"             \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 
-#define     LoadDW(addr, value, res)  \
+#define     _LoadDW(addr, value, res)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n\t"                    \
                        ".set\tnoat\n\t"                    \
@@ -319,16 +335,19 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t8b, 11b\n\t"             \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
+
 #endif /* CONFIG_CPU_MIPSR6 */
 
 
-#define     StoreHW(addr, value, res) \
+#define     _StoreHW(addr, value, res, type) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tnoat\n"                      \
-                       "1:\t"user_sb("%1", "1(%2)")"\n"    \
+                       "1:\t"type##_sb("%1", "1(%2)")"\n"  \
                        "srl\t$1, %1, 0x8\n"                \
-                       "2:\t"user_sb("$1", "0(%2)")"\n"    \
+                       "2:\t"type##_sb("$1", "0(%2)")"\n"  \
                        ".set\tat\n\t"                      \
                        "li\t%0, 0\n"                       \
                        "3:\n\t"                            \
@@ -342,13 +361,15 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=r" (res)                        \
-                       : "r" (value), "r" (addr), "i" (-EFAULT));
+                       : "r" (value), "r" (addr), "i" (-EFAULT));\
+} while(0)
 
 #ifndef CONFIG_CPU_MIPSR6
-#define     StoreW(addr, value, res)  \
+#define     _StoreW(addr, value, res, type)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
-                       "1:\t"user_swl("%1", "(%2)")"\n"    \
-                       "2:\t"user_swr("%1", "3(%2)")"\n\t" \
+                       "1:\t"type##_swl("%1", "(%2)")"\n"  \
+                       "2:\t"type##_swr("%1", "3(%2)")"\n\t"\
                        "li\t%0, 0\n"                       \
                        "3:\n\t"                            \
                        ".insn\n\t"                         \
@@ -361,9 +382,11 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                : "=r" (res)                                \
-               : "r" (value), "r" (addr), "i" (-EFAULT));
+               : "r" (value), "r" (addr), "i" (-EFAULT));  \
+} while(0)
 
-#define     StoreDW(addr, value, res) \
+#define     _StoreDW(addr, value, res) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        "1:\tsdl\t%1,(%2)\n"                \
                        "2:\tsdr\t%1, 7(%2)\n\t"            \
@@ -379,20 +402,23 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                : "=r" (res)                                \
-               : "r" (value), "r" (addr), "i" (-EFAULT));
+               : "r" (value), "r" (addr), "i" (-EFAULT));  \
+} while(0)
+
 #else
 /* MIPSR6 has no swl and sdl instructions */
-#define     StoreW(addr, value, res)  \
+#define     _StoreW(addr, value, res, type)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n\t"                    \
                        ".set\tnoat\n\t"                    \
-                       "1:"user_sb("%1", "3(%2)")"\n\t"    \
+                       "1:"type##_sb("%1", "3(%2)")"\n\t"  \
                        "srl\t$1, %1, 0x8\n\t"              \
-                       "2:"user_sb("$1", "2(%2)")"\n\t"    \
+                       "2:"type##_sb("$1", "2(%2)")"\n\t"  \
                        "srl\t$1, $1,  0x8\n\t"             \
-                       "3:"user_sb("$1", "1(%2)")"\n\t"    \
+                       "3:"type##_sb("$1", "1(%2)")"\n\t"  \
                        "srl\t$1, $1, 0x8\n\t"              \
-                       "4:"user_sb("$1", "0(%2)")"\n\t"    \
+                       "4:"type##_sb("$1", "0(%2)")"\n\t"  \
                        ".set\tpop\n\t"                     \
                        "li\t%0, 0\n"                       \
                        "10:\n\t"                           \
@@ -409,9 +435,11 @@ extern void show_registers(struct pt_regs *regs);
                        ".previous"                         \
                : "=&r" (res)                               \
                : "r" (value), "r" (addr), "i" (-EFAULT)    \
-               : "memory");
+               : "memory");                                \
+} while(0)
 
 #define     StoreDW(addr, value, res) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n\t"                    \
                        ".set\tnoat\n\t"                    \
@@ -451,15 +479,18 @@ extern void show_registers(struct pt_regs *regs);
                        ".previous"                         \
                : "=&r" (res)                               \
                : "r" (value), "r" (addr), "i" (-EFAULT)    \
-               : "memory");
+               : "memory");                                \
+} while(0)
+
 #endif /* CONFIG_CPU_MIPSR6 */
 
 #else /* __BIG_ENDIAN */
 
-#define     LoadHW(addr, value, res)  \
+#define     _LoadHW(addr, value, res, type)  \
+do {                                                        \
                __asm__ __volatile__ (".set\tnoat\n"        \
-                       "1:\t"user_lb("%0", "1(%2)")"\n"    \
-                       "2:\t"user_lbu("$1", "0(%2)")"\n\t" \
+                       "1:\t"type##_lb("%0", "1(%2)")"\n"  \
+                       "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
                        "li\t%1, 0\n"                       \
@@ -474,13 +505,15 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 
 #ifndef CONFIG_CPU_MIPSR6
-#define     LoadW(addr, value, res)   \
+#define     _LoadW(addr, value, res, type)   \
+do {                                                        \
                __asm__ __volatile__ (                      \
-                       "1:\t"user_lwl("%0", "3(%2)")"\n"   \
-                       "2:\t"user_lwr("%0", "(%2)")"\n\t"  \
+                       "1:\t"type##_lwl("%0", "3(%2)")"\n" \
+                       "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
                        "li\t%1, 0\n"                       \
                        "3:\n\t"                            \
                        ".insn\n\t"                         \
@@ -493,21 +526,24 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
+
 #else
 /* MIPSR6 has no lwl instruction */
-#define     LoadW(addr, value, res) \
+#define     _LoadW(addr, value, res, type) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n"                      \
                        ".set\tnoat\n\t"                    \
-                       "1:"user_lb("%0", "3(%2)")"\n\t"    \
-                       "2:"user_lbu("$1", "2(%2)")"\n\t"   \
+                       "1:"type##_lb("%0", "3(%2)")"\n\t"  \
+                       "2:"type##_lbu("$1", "2(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
-                       "3:"user_lbu("$1", "1(%2)")"\n\t"   \
+                       "3:"type##_lbu("$1", "1(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
-                       "4:"user_lbu("$1", "0(%2)")"\n\t"   \
+                       "4:"type##_lbu("$1", "0(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
                        "li\t%1, 0\n"                       \
@@ -525,15 +561,18 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t4b, 11b\n\t"             \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
+
 #endif /* CONFIG_CPU_MIPSR6 */
 
 
-#define     LoadHWU(addr, value, res) \
+#define     _LoadHWU(addr, value, res, type) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tnoat\n"                      \
-                       "1:\t"user_lbu("%0", "1(%2)")"\n"   \
-                       "2:\t"user_lbu("$1", "0(%2)")"\n\t" \
+                       "1:\t"type##_lbu("%0", "1(%2)")"\n" \
+                       "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
                        "li\t%1, 0\n"                       \
@@ -549,13 +588,15 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 
 #ifndef CONFIG_CPU_MIPSR6
-#define     LoadWU(addr, value, res)  \
+#define     _LoadWU(addr, value, res, type)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
-                       "1:\t"user_lwl("%0", "3(%2)")"\n"   \
-                       "2:\t"user_lwr("%0", "(%2)")"\n\t"  \
+                       "1:\t"type##_lwl("%0", "3(%2)")"\n" \
+                       "2:\t"type##_lwr("%0", "(%2)")"\n\t"\
                        "dsll\t%0, %0, 32\n\t"              \
                        "dsrl\t%0, %0, 32\n\t"              \
                        "li\t%1, 0\n"                       \
@@ -570,9 +611,11 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 
-#define     LoadDW(addr, value, res)  \
+#define     _LoadDW(addr, value, res)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        "1:\tldl\t%0, 7(%2)\n"              \
                        "2:\tldr\t%0, (%2)\n\t"             \
@@ -588,21 +631,24 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
+
 #else
 /* MIPSR6 has not lwl and ldl instructions */
-#define            LoadWU(addr, value, res) \
+#define            _LoadWU(addr, value, res, type) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n\t"                    \
                        ".set\tnoat\n\t"                    \
-                       "1:"user_lbu("%0", "3(%2)")"\n\t"   \
-                       "2:"user_lbu("$1", "2(%2)")"\n\t"   \
+                       "1:"type##_lbu("%0", "3(%2)")"\n\t" \
+                       "2:"type##_lbu("$1", "2(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
-                       "3:"user_lbu("$1", "1(%2)")"\n\t"   \
+                       "3:"type##_lbu("$1", "1(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
-                       "4:"user_lbu("$1", "0(%2)")"\n\t"   \
+                       "4:"type##_lbu("$1", "0(%2)")"\n\t" \
                        "sll\t%0, 0x8\n\t"                  \
                        "or\t%0, $1\n\t"                    \
                        "li\t%1, 0\n"                       \
@@ -620,9 +666,11 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t4b, 11b\n\t"             \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 
-#define     LoadDW(addr, value, res)  \
+#define     _LoadDW(addr, value, res)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n\t"                    \
                        ".set\tnoat\n\t"                    \
@@ -667,15 +715,17 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t8b, 11b\n\t"             \
                        ".previous"                         \
                        : "=&r" (value), "=r" (res)         \
-                       : "r" (addr), "i" (-EFAULT));
+                       : "r" (addr), "i" (-EFAULT));       \
+} while(0)
 #endif /* CONFIG_CPU_MIPSR6 */
 
-#define     StoreHW(addr, value, res) \
+#define     _StoreHW(addr, value, res, type) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tnoat\n"                      \
-                       "1:\t"user_sb("%1", "0(%2)")"\n"    \
+                       "1:\t"type##_sb("%1", "0(%2)")"\n"  \
                        "srl\t$1,%1, 0x8\n"                 \
-                       "2:\t"user_sb("$1", "1(%2)")"\n"    \
+                       "2:\t"type##_sb("$1", "1(%2)")"\n"  \
                        ".set\tat\n\t"                      \
                        "li\t%0, 0\n"                       \
                        "3:\n\t"                            \
@@ -689,12 +739,15 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                        : "=r" (res)                        \
-                       : "r" (value), "r" (addr), "i" (-EFAULT));
+                       : "r" (value), "r" (addr), "i" (-EFAULT));\
+} while(0)
+
 #ifndef CONFIG_CPU_MIPSR6
-#define     StoreW(addr, value, res)  \
+#define     _StoreW(addr, value, res, type)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
-                       "1:\t"user_swl("%1", "3(%2)")"\n"   \
-                       "2:\t"user_swr("%1", "(%2)")"\n\t"  \
+                       "1:\t"type##_swl("%1", "3(%2)")"\n" \
+                       "2:\t"type##_swr("%1", "(%2)")"\n\t"\
                        "li\t%0, 0\n"                       \
                        "3:\n\t"                            \
                        ".insn\n\t"                         \
@@ -707,9 +760,11 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                : "=r" (res)                                \
-               : "r" (value), "r" (addr), "i" (-EFAULT));
+               : "r" (value), "r" (addr), "i" (-EFAULT));  \
+} while(0)
 
-#define     StoreDW(addr, value, res) \
+#define     _StoreDW(addr, value, res) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        "1:\tsdl\t%1, 7(%2)\n"              \
                        "2:\tsdr\t%1, (%2)\n\t"             \
@@ -725,20 +780,23 @@ extern void show_registers(struct pt_regs *regs);
                        STR(PTR)"\t2b, 4b\n\t"              \
                        ".previous"                         \
                : "=r" (res)                                \
-               : "r" (value), "r" (addr), "i" (-EFAULT));
+               : "r" (value), "r" (addr), "i" (-EFAULT));  \
+} while(0)
+
 #else
 /* MIPSR6 has no swl and sdl instructions */
-#define     StoreW(addr, value, res)  \
+#define     _StoreW(addr, value, res, type)  \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n\t"                    \
                        ".set\tnoat\n\t"                    \
-                       "1:"user_sb("%1", "0(%2)")"\n\t"    \
+                       "1:"type##_sb("%1", "0(%2)")"\n\t"  \
                        "srl\t$1, %1, 0x8\n\t"              \
-                       "2:"user_sb("$1", "1(%2)")"\n\t"    \
+                       "2:"type##_sb("$1", "1(%2)")"\n\t"  \
                        "srl\t$1, $1,  0x8\n\t"             \
-                       "3:"user_sb("$1", "2(%2)")"\n\t"    \
+                       "3:"type##_sb("$1", "2(%2)")"\n\t"  \
                        "srl\t$1, $1, 0x8\n\t"              \
-                       "4:"user_sb("$1", "3(%2)")"\n\t"    \
+                       "4:"type##_sb("$1", "3(%2)")"\n\t"  \
                        ".set\tpop\n\t"                     \
                        "li\t%0, 0\n"                       \
                        "10:\n\t"                           \
@@ -755,9 +813,11 @@ extern void show_registers(struct pt_regs *regs);
                        ".previous"                         \
                : "=&r" (res)                               \
                : "r" (value), "r" (addr), "i" (-EFAULT)    \
-               : "memory");
+               : "memory");                                \
+} while(0)
 
-#define     StoreDW(addr, value, res) \
+#define     _StoreDW(addr, value, res) \
+do {                                                        \
                __asm__ __volatile__ (                      \
                        ".set\tpush\n\t"                    \
                        ".set\tnoat\n\t"                    \
@@ -797,10 +857,28 @@ extern void show_registers(struct pt_regs *regs);
                        ".previous"                         \
                : "=&r" (res)                               \
                : "r" (value), "r" (addr), "i" (-EFAULT)    \
-               : "memory");
+               : "memory");                                \
+} while(0)
+
 #endif /* CONFIG_CPU_MIPSR6 */
 #endif
 
+#define LoadHWU(addr, value, res)      _LoadHWU(addr, value, res, kernel)
+#define LoadHWUE(addr, value, res)     _LoadHWU(addr, value, res, user)
+#define LoadWU(addr, value, res)       _LoadWU(addr, value, res, kernel)
+#define LoadWUE(addr, value, res)      _LoadWU(addr, value, res, user)
+#define LoadHW(addr, value, res)       _LoadHW(addr, value, res, kernel)
+#define LoadHWE(addr, value, res)      _LoadHW(addr, value, res, user)
+#define LoadW(addr, value, res)                _LoadW(addr, value, res, kernel)
+#define LoadWE(addr, value, res)       _LoadW(addr, value, res, user)
+#define LoadDW(addr, value, res)       _LoadDW(addr, value, res)
+
+#define StoreHW(addr, value, res)      _StoreHW(addr, value, res, kernel)
+#define StoreHWE(addr, value, res)     _StoreHW(addr, value, res, user)
+#define StoreW(addr, value, res)       _StoreW(addr, value, res, kernel)
+#define StoreWE(addr, value, res)      _StoreW(addr, value, res, user)
+#define StoreDW(addr, value, res)      _StoreDW(addr, value, res)
+
 static void emulate_load_store_insn(struct pt_regs *regs,
        void __user *addr, unsigned int __user *pc)
 {
@@ -872,7 +950,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                                set_fs(seg);
                                goto sigbus;
                        }
-                       LoadHW(addr, value, res);
+                       LoadHWE(addr, value, res);
                        if (res) {
                                set_fs(seg);
                                goto fault;
@@ -885,7 +963,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                                set_fs(seg);
                                goto sigbus;
                        }
-                               LoadW(addr, value, res);
+                               LoadWE(addr, value, res);
                        if (res) {
                                set_fs(seg);
                                goto fault;
@@ -898,7 +976,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                                set_fs(seg);
                                goto sigbus;
                        }
-                       LoadHWU(addr, value, res);
+                       LoadHWUE(addr, value, res);
                        if (res) {
                                set_fs(seg);
                                goto fault;
@@ -913,7 +991,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                        }
                        compute_return_epc(regs);
                        value = regs->regs[insn.spec3_format.rt];
-                       StoreHW(addr, value, res);
+                       StoreHWE(addr, value, res);
                        if (res) {
                                set_fs(seg);
                                goto fault;
@@ -926,7 +1004,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                        }
                        compute_return_epc(regs);
                        value = regs->regs[insn.spec3_format.rt];
-                       StoreW(addr, value, res);
+                       StoreWE(addr, value, res);
                        if (res) {
                                set_fs(seg);
                                goto fault;
@@ -943,7 +1021,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                if (!access_ok(VERIFY_READ, addr, 2))
                        goto sigbus;
 
-               LoadHW(addr, value, res);
+               if (config_enabled(CONFIG_EVA)) {
+                       if (segment_eq(get_fs(), get_ds()))
+                               LoadHW(addr, value, res);
+                       else
+                               LoadHWE(addr, value, res);
+               } else {
+                       LoadHW(addr, value, res);
+               }
+
                if (res)
                        goto fault;
                compute_return_epc(regs);
@@ -954,7 +1040,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                if (!access_ok(VERIFY_READ, addr, 4))
                        goto sigbus;
 
-               LoadW(addr, value, res);
+               if (config_enabled(CONFIG_EVA)) {
+                       if (segment_eq(get_fs(), get_ds()))
+                               LoadW(addr, value, res);
+                       else
+                               LoadWE(addr, value, res);
+               } else {
+                       LoadW(addr, value, res);
+               }
+
                if (res)
                        goto fault;
                compute_return_epc(regs);
@@ -965,7 +1059,15 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                if (!access_ok(VERIFY_READ, addr, 2))
                        goto sigbus;
 
-               LoadHWU(addr, value, res);
+               if (config_enabled(CONFIG_EVA)) {
+                       if (segment_eq(get_fs(), get_ds()))
+                               LoadHWU(addr, value, res);
+                       else
+                               LoadHWUE(addr, value, res);
+               } else {
+                       LoadHWU(addr, value, res);
+               }
+
                if (res)
                        goto fault;
                compute_return_epc(regs);
@@ -1024,7 +1126,16 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 
                compute_return_epc(regs);
                value = regs->regs[insn.i_format.rt];
-               StoreHW(addr, value, res);
+
+               if (config_enabled(CONFIG_EVA)) {
+                       if (segment_eq(get_fs(), get_ds()))
+                               StoreHW(addr, value, res);
+                       else
+                               StoreHWE(addr, value, res);
+               } else {
+                       StoreHW(addr, value, res);
+               }
+
                if (res)
                        goto fault;
                break;
@@ -1035,7 +1146,16 @@ static void emulate_load_store_insn(struct pt_regs *regs,
 
                compute_return_epc(regs);
                value = regs->regs[insn.i_format.rt];
-               StoreW(addr, value, res);
+
+               if (config_enabled(CONFIG_EVA)) {
+                       if (segment_eq(get_fs(), get_ds()))
+                               StoreW(addr, value, res);
+                       else
+                               StoreWE(addr, value, res);
+               } else {
+                       StoreW(addr, value, res);
+               }
+
                if (res)
                        goto fault;
                break;
@@ -1076,7 +1196,7 @@ static void emulate_load_store_insn(struct pt_regs *regs,
                own_fpu(1);     /* Restore FPU state. */
 
                /* Signal if something went wrong. */
-               process_fpemu_return(res, fault_addr);
+               process_fpemu_return(res, fault_addr, 0);
 
                if (res == 0)
                        break;
@@ -1511,7 +1631,7 @@ fpu_emul:
                own_fpu(1);     /* restore FPU state */
 
                /* If something went wrong, signal */
-               process_fpemu_return(res, fault_addr);
+               process_fpemu_return(res, fault_addr, 0);
 
                if (res == 0)
                        goto success;
index 39ab3e7..0db099e 100644 (file)
@@ -41,7 +41,7 @@ int ltq_soc_type(void)
        return soc_info.type;
 }
 
-void prom_free_prom_memory(void)
+void __init prom_free_prom_memory(void)
 {
 }
 
index 696cd57..d001bc3 100644 (file)
@@ -61,7 +61,6 @@ static struct platform_driver vmmc_driver = {
        .probe = vmmc_probe,
        .driver = {
                .name = "lantiq,vmmc",
-               .owner = THIS_MODULE,
                .of_match_table = vmmc_match,
        },
 };
index cf9b463..a57959e 100644 (file)
@@ -53,21 +53,6 @@ int proc_dolasatstring(struct ctl_table *table, int write,
        return 0;
 }
 
-/* proc function to write EEPROM after changing int entry */
-int proc_dolasatint(struct ctl_table *table, int write,
-                      void *buffer, size_t *lenp, loff_t *ppos)
-{
-       int r;
-
-       r = proc_dointvec(table, write, buffer, lenp, ppos);
-       if ((!write) || r)
-               return r;
-
-       lasat_write_eeprom_info();
-
-       return 0;
-}
-
 #ifdef CONFIG_DS1603
 static int rtctmp;
 
index 4c721e2..ed88647 100644 (file)
        LOAD    _t1, (offset + UNIT(1))(src);                   \
        LOAD    _t2, (offset + UNIT(2))(src);                   \
        LOAD    _t3, (offset + UNIT(3))(src);                   \
+       ADDC(_t0, _t1);                                         \
+       ADDC(_t2, _t3);                                         \
        ADDC(sum, _t0);                                         \
-       ADDC(sum, _t1);                                         \
-       ADDC(sum, _t2);                                         \
-       ADDC(sum, _t3)
+       ADDC(sum, _t2)
 
 #ifdef USE_DOUBLE
 #define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3)    \
@@ -504,21 +504,21 @@ LEAF(csum_partial)
        SUB     len, len, 8*NBYTES
        ADD     src, src, 8*NBYTES
        STORE(t0, UNIT(0)(dst), .Ls_exc\@)
-       ADDC(sum, t0)
+       ADDC(t0, t1)
        STORE(t1, UNIT(1)(dst), .Ls_exc\@)
-       ADDC(sum, t1)
+       ADDC(sum, t0)
        STORE(t2, UNIT(2)(dst), .Ls_exc\@)
-       ADDC(sum, t2)
+       ADDC(t2, t3)
        STORE(t3, UNIT(3)(dst), .Ls_exc\@)
-       ADDC(sum, t3)
+       ADDC(sum, t2)
        STORE(t4, UNIT(4)(dst), .Ls_exc\@)
-       ADDC(sum, t4)
+       ADDC(t4, t5)
        STORE(t5, UNIT(5)(dst), .Ls_exc\@)
-       ADDC(sum, t5)
+       ADDC(sum, t4)
        STORE(t6, UNIT(6)(dst), .Ls_exc\@)
-       ADDC(sum, t6)
+       ADDC(t6, t7)
        STORE(t7, UNIT(7)(dst), .Ls_exc\@)
-       ADDC(sum, t7)
+       ADDC(sum, t6)
        .set    reorder                         /* DADDI_WAR */
        ADD     dst, dst, 8*NBYTES
        bgez    len, 1b
@@ -544,13 +544,13 @@ LEAF(csum_partial)
        SUB     len, len, 4*NBYTES
        ADD     src, src, 4*NBYTES
        STORE(t0, UNIT(0)(dst), .Ls_exc\@)
-       ADDC(sum, t0)
+       ADDC(t0, t1)
        STORE(t1, UNIT(1)(dst), .Ls_exc\@)
-       ADDC(sum, t1)
+       ADDC(sum, t0)
        STORE(t2, UNIT(2)(dst), .Ls_exc\@)
-       ADDC(sum, t2)
+       ADDC(t2, t3)
        STORE(t3, UNIT(3)(dst), .Ls_exc\@)
-       ADDC(sum, t3)
+       ADDC(sum, t2)
        .set    reorder                         /* DADDI_WAR */
        ADD     dst, dst, 4*NBYTES
        beqz    len, .Ldone\@
@@ -649,13 +649,13 @@ LEAF(csum_partial)
        nop                             # improves slotting
 #endif
        STORE(t0, UNIT(0)(dst), .Ls_exc\@)
-       ADDC(sum, t0)
+       ADDC(t0, t1)
        STORE(t1, UNIT(1)(dst), .Ls_exc\@)
-       ADDC(sum, t1)
+       ADDC(sum, t0)
        STORE(t2, UNIT(2)(dst), .Ls_exc\@)
-       ADDC(sum, t2)
+       ADDC(t2, t3)
        STORE(t3, UNIT(3)(dst), .Ls_exc\@)
-       ADDC(sum, t3)
+       ADDC(sum, t2)
        .set    reorder                         /* DADDI_WAR */
        ADD     dst, dst, 4*NBYTES
        bne     len, rem, 1b
index 045ea3d..22f04ca 100644 (file)
@@ -29,6 +29,7 @@ struct efi_memory_map_loongson *loongson_memmap;
 struct loongson_system_configuration loongson_sysconf;
 
 u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180};
+u64 loongson_chiptemp[MAX_PACKAGES];
 u64 loongson_freqctrl[MAX_PACKAGES];
 
 unsigned long long smp_group[4];
@@ -97,6 +98,10 @@ void __init prom_init_env(void)
                loongson_chipcfg[1] = 0x900010001fe00180;
                loongson_chipcfg[2] = 0x900020001fe00180;
                loongson_chipcfg[3] = 0x900030001fe00180;
+               loongson_chiptemp[0] = 0x900000001fe0019c;
+               loongson_chiptemp[1] = 0x900010001fe0019c;
+               loongson_chiptemp[2] = 0x900020001fe0019c;
+               loongson_chiptemp[3] = 0x900030001fe0019c;
                loongson_sysconf.ht_control_base = 0x90000EFDFB000000;
                loongson_sysconf.workarounds = WORKAROUND_CPUFREQ;
        } else if (ecpu->cputype == Loongson_3B) {
@@ -110,6 +115,10 @@ void __init prom_init_env(void)
                loongson_chipcfg[1] = 0x900020001fe00180;
                loongson_chipcfg[2] = 0x900040001fe00180;
                loongson_chipcfg[3] = 0x900060001fe00180;
+               loongson_chiptemp[0] = 0x900000001fe0019c;
+               loongson_chiptemp[1] = 0x900020001fe0019c;
+               loongson_chiptemp[2] = 0x900040001fe0019c;
+               loongson_chiptemp[3] = 0x900060001fe0019c;
                loongson_freqctrl[0] = 0x900000001fe001d0;
                loongson_freqctrl[1] = 0x900020001fe001d0;
                loongson_freqctrl[2] = 0x900040001fe001d0;
index 003ab4e..4e25756 100644 (file)
@@ -78,6 +78,8 @@ static void __init setup_pcimap(void)
 #endif
 }
 
+extern int sbx00_acpi_init(void);
+
 static int __init pcibios_init(void)
 {
        setup_pcimap();
@@ -89,6 +91,10 @@ static int __init pcibios_init(void)
 #endif
        register_pci_controller(&loongson_pci_controller);
 
+#ifdef CONFIG_CPU_LOONGSON3
+       sbx00_acpi_init();
+#endif
+
        return 0;
 }
 
index b03e37d..ea13764 100644 (file)
@@ -43,7 +43,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
                if (!fpu_owned) {
                        set_thread_flag(TIF_USEDFPU);
                        if (!used_math()) {
-                               _init_fpu();
+                               _init_fpu(current->thread.fpu.fcr31);
                                set_used_math();
                        } else
                                _restore_fp(current);
index 21221ed..0f75b6b 100644 (file)
@@ -44,6 +44,7 @@ void mach_irq_dispatch(unsigned int pending)
 
 static struct irqaction cascade_irqaction = {
        .handler = no_action,
+       .flags = IRQF_NO_SUSPEND,
        .name = "cascade",
 };
 
index 619cfc1..2e5f962 100644 (file)
@@ -2,12 +2,15 @@
 # Makefile for the Linux/MIPS kernel FPU emulation.
 #
 
-obj-y  += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o dp_div.o dp_mul.o \
-          dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o dp_tint.o \
-          dp_fint.o dp_tlong.o dp_flong.o sp_div.o sp_mul.o sp_sub.o \
-          sp_add.o sp_fdp.o sp_cmp.o sp_simple.o sp_tint.o sp_fint.o \
-          sp_tlong.o sp_flong.o dsemul.o
+obj-y  += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \
+          dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \
+          dp_tint.o dp_fint.o \
+          sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \
+          sp_tint.o sp_fint.o \
+          dsemul.o
 
-lib-y  += ieee754d.o dp_sqrt.o sp_sqrt.o
+lib-y  += ieee754d.o \
+          dp_tlong.o dp_flong.o dp_sqrt.o \
+          sp_tlong.o sp_flong.o sp_sqrt.o
 
 obj-$(CONFIG_DEBUG_FS) += me-debugfs.o
index b30bf65..d31c537 100644 (file)
@@ -45,6 +45,7 @@
 #include <asm/signal.h>
 #include <asm/uaccess.h>
 
+#include <asm/cpu-info.h>
 #include <asm/processor.h>
 #include <asm/fpu_emulator.h>
 #include <asm/fpu.h>
@@ -63,14 +64,14 @@ static int fpux_emu(struct pt_regs *,
 /* Control registers */
 
 #define FPCREG_RID     0       /* $0  = revision id */
+#define FPCREG_FCCR    25      /* $25 = fccr */
+#define FPCREG_FEXR    26      /* $26 = fexr */
+#define FPCREG_FENR    28      /* $28 = fenr */
 #define FPCREG_CSR     31      /* $31 = csr */
 
-/* Determine rounding mode from the RM bits of the FCSR */
-#define modeindex(v) ((v) & FPU_CSR_RM)
-
 /* convert condition code register number to csr bit */
 const unsigned int fpucondbit[8] = {
-       FPU_CSR_COND0,
+       FPU_CSR_COND,
        FPU_CSR_COND1,
        FPU_CSR_COND2,
        FPU_CSR_COND3,
@@ -843,6 +844,127 @@ do {                                                                      \
 #define DPTOREG(dp, x) DITOREG((dp).bits, x)
 
 /*
+ * Emulate a CFC1 instruction.
+ */
+static inline void cop1_cfc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+                           mips_instruction ir)
+{
+       u32 fcr31 = ctx->fcr31;
+       u32 value = 0;
+
+       switch (MIPSInst_RD(ir)) {
+       case FPCREG_CSR:
+               value = fcr31;
+               pr_debug("%p gpr[%d]<-csr=%08x\n",
+                        (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+               break;
+
+       case FPCREG_FENR:
+               if (!cpu_has_mips_r)
+                       break;
+               value = (fcr31 >> (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
+                       MIPS_FENR_FS;
+               value |= fcr31 & (FPU_CSR_ALL_E | FPU_CSR_RM);
+               pr_debug("%p gpr[%d]<-enr=%08x\n",
+                        (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+               break;
+
+       case FPCREG_FEXR:
+               if (!cpu_has_mips_r)
+                       break;
+               value = fcr31 & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
+               pr_debug("%p gpr[%d]<-exr=%08x\n",
+                        (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+               break;
+
+       case FPCREG_FCCR:
+               if (!cpu_has_mips_r)
+                       break;
+               value = (fcr31 >> (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
+                       MIPS_FCCR_COND0;
+               value |= (fcr31 >> (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
+                        (MIPS_FCCR_CONDX & ~MIPS_FCCR_COND0);
+               pr_debug("%p gpr[%d]<-ccr=%08x\n",
+                        (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+               break;
+
+       case FPCREG_RID:
+               value = current_cpu_data.fpu_id;
+               break;
+
+       default:
+               break;
+       }
+
+       if (MIPSInst_RT(ir))
+               xcp->regs[MIPSInst_RT(ir)] = value;
+}
+
+/*
+ * Emulate a CTC1 instruction.
+ */
+static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+                           mips_instruction ir)
+{
+       u32 fcr31 = ctx->fcr31;
+       u32 value;
+       u32 mask;
+
+       if (MIPSInst_RT(ir) == 0)
+               value = 0;
+       else
+               value = xcp->regs[MIPSInst_RT(ir)];
+
+       switch (MIPSInst_RD(ir)) {
+       case FPCREG_CSR:
+               pr_debug("%p gpr[%d]->csr=%08x\n",
+                        (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+
+               /* Preserve read-only bits.  */
+               mask = current_cpu_data.fpu_msk31;
+               fcr31 = (value & ~mask) | (fcr31 & mask);
+               break;
+
+       case FPCREG_FENR:
+               if (!cpu_has_mips_r)
+                       break;
+               pr_debug("%p gpr[%d]->enr=%08x\n",
+                        (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+               fcr31 &= ~(FPU_CSR_FS | FPU_CSR_ALL_E | FPU_CSR_RM);
+               fcr31 |= (value << (FPU_CSR_FS_S - MIPS_FENR_FS_S)) &
+                        FPU_CSR_FS;
+               fcr31 |= value & (FPU_CSR_ALL_E | FPU_CSR_RM);
+               break;
+
+       case FPCREG_FEXR:
+               if (!cpu_has_mips_r)
+                       break;
+               pr_debug("%p gpr[%d]->exr=%08x\n",
+                        (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+               fcr31 &= ~(FPU_CSR_ALL_X | FPU_CSR_ALL_S);
+               fcr31 |= value & (FPU_CSR_ALL_X | FPU_CSR_ALL_S);
+               break;
+
+       case FPCREG_FCCR:
+               if (!cpu_has_mips_r)
+                       break;
+               pr_debug("%p gpr[%d]->ccr=%08x\n",
+                        (void *)xcp->cp0_epc, MIPSInst_RT(ir), value);
+               fcr31 &= ~(FPU_CSR_CONDX | FPU_CSR_COND);
+               fcr31 |= (value << (FPU_CSR_COND_S - MIPS_FCCR_COND0_S)) &
+                        FPU_CSR_COND;
+               fcr31 |= (value << (FPU_CSR_COND1_S - MIPS_FCCR_COND1_S)) &
+                        FPU_CSR_CONDX;
+               break;
+
+       default:
+               break;
+       }
+
+       ctx->fcr31 = fcr31;
+}
+
+/*
  * Emulate the single floating point instruction pointed at by EPC.
  * Two instructions if the instruction is in a branch delay slot.
  */
@@ -856,7 +978,6 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        int likely, pc_inc;
        u32 __user *wva;
        u64 __user *dva;
-       u32 value;
        u32 wval;
        u64 dval;
        int sig;
@@ -1049,42 +1170,12 @@ emul:
 
                case cfc_op:
                        /* cop control register rd -> gpr[rt] */
-                       if (MIPSInst_RD(ir) == FPCREG_CSR) {
-                               value = ctx->fcr31;
-                               value = (value & ~FPU_CSR_RM) | modeindex(value);
-                               pr_debug("%p gpr[%d]<-csr=%08x\n",
-                                        (void *) (xcp->cp0_epc),
-                                        MIPSInst_RT(ir), value);
-                       }
-                       else if (MIPSInst_RD(ir) == FPCREG_RID)
-                               value = 0;
-                       else
-                               value = 0;
-                       if (MIPSInst_RT(ir))
-                               xcp->regs[MIPSInst_RT(ir)] = value;
+                       cop1_cfc(xcp, ctx, ir);
                        break;
 
                case ctc_op:
                        /* copregister rd <- rt */
-                       if (MIPSInst_RT(ir) == 0)
-                               value = 0;
-                       else
-                               value = xcp->regs[MIPSInst_RT(ir)];
-
-                       /* we only have one writable control reg
-                        */
-                       if (MIPSInst_RD(ir) == FPCREG_CSR) {
-                               pr_debug("%p gpr[%d]->csr=%08x\n",
-                                        (void *) (xcp->cp0_epc),
-                                        MIPSInst_RT(ir), value);
-
-                               /*
-                                * Don't write reserved bits,
-                                * and convert to ieee library modes
-                                */
-                               ctx->fcr31 = (value & ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
-                                            modeindex(value);
-                       }
+                       cop1_ctc(xcp, ctx, ir);
                        if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
                                return SIGFPE;
                        }
@@ -1103,17 +1194,18 @@ emul:
                        likely = 0;
                        switch (MIPSInst_RT(ir) & 3) {
                        case bcfl_op:
-                               likely = 1;
+                               if (cpu_has_mips_2_3_4_5_r)
+                                       likely = 1;
+                               /* Fall through */
                        case bcf_op:
                                cond = !cond;
                                break;
                        case bctl_op:
-                               likely = 1;
+                               if (cpu_has_mips_2_3_4_5_r)
+                                       likely = 1;
+                               /* Fall through */
                        case bct_op:
                                break;
-                       default:
-                               /* thats an illegal instruction */
-                               return SIGILL;
                        }
 
                        set_delay_slot(xcp);
@@ -1121,6 +1213,14 @@ emul:
                                /*
                                 * Branch taken: emulate dslot instruction
                                 */
+                               unsigned long bcpc;
+
+                               /*
+                                * Remember EPC at the branch to point back
+                                * at so that any delay-slot instruction
+                                * signal is not silently ignored.
+                                */
+                               bcpc = xcp->cp0_epc;
                                xcp->cp0_epc += dec_insn.pc_inc;
 
                                contpc = MIPSInst_SIMM(ir);
@@ -1146,63 +1246,77 @@ emul:
                                                 * Single step the non-CP1
                                                 * instruction in the dslot.
                                                 */
-                                               return mips_dsemul(xcp, ir, contpc);
+                                               sig = mips_dsemul(xcp, ir,
+                                                                 contpc);
+                                               if (sig)
+                                                       xcp->cp0_epc = bcpc;
+                                               /*
+                                                * SIGILL forces out of
+                                                * the emulation loop.
+                                                */
+                                               return sig ? sig : SIGILL;
                                        }
                                } else
                                        contpc = (xcp->cp0_epc + (contpc << 2));
 
                                switch (MIPSInst_OPCODE(ir)) {
                                case lwc1_op:
-                                       goto emul;
-
                                case swc1_op:
                                        goto emul;
 
                                case ldc1_op:
                                case sdc1_op:
-                                       if (cpu_has_mips_2_3_4_5 ||
-                                           cpu_has_mips64)
+                                       if (cpu_has_mips_2_3_4_5_r)
                                                goto emul;
 
-                                       return SIGILL;
-                                       goto emul;
+                                       goto bc_sigill;
 
                                case cop1_op:
                                        goto emul;
 
                                case cop1x_op:
-                                       if (cpu_has_mips_4_5 || cpu_has_mips64 || cpu_has_mips32r2)
+                                       if (cpu_has_mips_4_5_64_r2_r6)
                                                /* its one of ours */
                                                goto emul;
 
-                                       return SIGILL;
+                                       goto bc_sigill;
 
                                case spec_op:
-                                       if (!cpu_has_mips_4_5_r)
-                                               return SIGILL;
+                                       switch (MIPSInst_FUNC(ir)) {
+                                       case movc_op:
+                                               if (cpu_has_mips_4_5_r)
+                                                       goto emul;
 
-                                       if (MIPSInst_FUNC(ir) == movc_op)
-                                               goto emul;
+                                               goto bc_sigill;
+                                       }
                                        break;
+
+                               bc_sigill:
+                                       xcp->cp0_epc = bcpc;
+                                       return SIGILL;
                                }
 
                                /*
                                 * Single step the non-cp1
                                 * instruction in the dslot
                                 */
-                               return mips_dsemul(xcp, ir, contpc);
+                               sig = mips_dsemul(xcp, ir, contpc);
+                               if (sig)
+                                       xcp->cp0_epc = bcpc;
+                               /* SIGILL forces out of the emulation loop.  */
+                               return sig ? sig : SIGILL;
                        } else if (likely) {    /* branch not taken */
-                                       /*
-                                        * branch likely nullifies
-                                        * dslot if not taken
-                                        */
-                                       xcp->cp0_epc += dec_insn.pc_inc;
-                                       contpc += dec_insn.pc_inc;
-                                       /*
-                                        * else continue & execute
-                                        * dslot as normal insn
-                                        */
-                               }
+                               /*
+                                * branch likely nullifies
+                                * dslot if not taken
+                                */
+                               xcp->cp0_epc += dec_insn.pc_inc;
+                               contpc += dec_insn.pc_inc;
+                               /*
+                                * else continue & execute
+                                * dslot as normal insn
+                                */
+                       }
                        break;
 
                default:
@@ -1216,7 +1330,7 @@ emul:
                break;
 
        case cop1x_op:
-               if (!cpu_has_mips_4_5 && !cpu_has_mips64 && !cpu_has_mips32r2)
+               if (!cpu_has_mips_4_5_64_r2_r6)
                        return SIGILL;
 
                sig = fpux_emu(xcp, ctx, ir, fault_addr);
@@ -1549,7 +1663,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
                        /* unary  ops */
                case fsqrt_op:
-                       if (!cpu_has_mips_4_5_r)
+                       if (!cpu_has_mips_2_3_4_5_r)
                                return SIGILL;
 
                        handler.u = ieee754sp_sqrt;
@@ -1561,14 +1675,14 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                 * achieve full IEEE-754 accuracy - however this emulator does.
                 */
                case frsqrt_op:
-                       if (!cpu_has_mips_4_5_r2_r6)
+                       if (!cpu_has_mips_4_5_64_r2_r6)
                                return SIGILL;
 
                        handler.u = fpemu_sp_rsqrt;
                        goto scopuop;
 
                case frecip_op:
-                       if (!cpu_has_mips_4_5_r2_r6)
+                       if (!cpu_has_mips_4_5_64_r2_r6)
                                return SIGILL;
 
                        handler.u = fpemu_sp_recip;
@@ -1670,19 +1784,19 @@ copcsr:
                case ftrunc_op:
                case fceil_op:
                case ffloor_op:
-                       if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_2_3_4_5_r)
                                return SIGILL;
 
                        oldrm = ieee754_csr.rm;
                        SPFROMREG(fs, MIPSInst_FS(ir));
-                       ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+                       ieee754_csr.rm = MIPSInst_FUNC(ir);
                        rv.w = ieee754sp_tint(fs);
                        ieee754_csr.rm = oldrm;
                        rfmt = w_fmt;
                        goto copcsr;
 
                case fcvtl_op:
-                       if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_3_4_5_64_r2_r6)
                                return SIGILL;
 
                        SPFROMREG(fs, MIPSInst_FS(ir));
@@ -1694,12 +1808,12 @@ copcsr:
                case ftruncl_op:
                case fceill_op:
                case ffloorl_op:
-                       if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_3_4_5_64_r2_r6)
                                return SIGILL;
 
                        oldrm = ieee754_csr.rm;
                        SPFROMREG(fs, MIPSInst_FS(ir));
-                       ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+                       ieee754_csr.rm = MIPSInst_FUNC(ir);
                        rv.l = ieee754sp_tlong(fs);
                        ieee754_csr.rm = oldrm;
                        rfmt = l_fmt;
@@ -1763,13 +1877,13 @@ copcsr:
                 * achieve full IEEE-754 accuracy - however this emulator does.
                 */
                case frsqrt_op:
-                       if (!cpu_has_mips_4_5_r2_r6)
+                       if (!cpu_has_mips_4_5_64_r2_r6)
                                return SIGILL;
 
                        handler.u = fpemu_dp_rsqrt;
                        goto dcopuop;
                case frecip_op:
-                       if (!cpu_has_mips_4_5_r2_r6)
+                       if (!cpu_has_mips_4_5_64_r2_r6)
                                return SIGILL;
 
                        handler.u = fpemu_dp_recip;
@@ -1852,14 +1966,14 @@ dcopuop:
 
                        oldrm = ieee754_csr.rm;
                        DPFROMREG(fs, MIPSInst_FS(ir));
-                       ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+                       ieee754_csr.rm = MIPSInst_FUNC(ir);
                        rv.w = ieee754dp_tint(fs);
                        ieee754_csr.rm = oldrm;
                        rfmt = w_fmt;
                        goto copcsr;
 
                case fcvtl_op:
-                       if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_3_4_5_64_r2_r6)
                                return SIGILL;
 
                        DPFROMREG(fs, MIPSInst_FS(ir));
@@ -1871,12 +1985,12 @@ dcopuop:
                case ftruncl_op:
                case fceill_op:
                case ffloorl_op:
-                       if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+                       if (!cpu_has_mips_3_4_5_64_r2_r6)
                                return SIGILL;
 
                        oldrm = ieee754_csr.rm;
                        DPFROMREG(fs, MIPSInst_FS(ir));
-                       ieee754_csr.rm = modeindex(MIPSInst_FUNC(ir));
+                       ieee754_csr.rm = MIPSInst_FUNC(ir);
                        rv.l = ieee754dp_tlong(fs);
                        ieee754_csr.rm = oldrm;
                        rfmt = l_fmt;
@@ -1930,7 +2044,7 @@ dcopuop:
 
        case l_fmt:
 
-               if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+               if (!cpu_has_mips_3_4_5_64_r2_r6)
                        return SIGILL;
 
                DIFROMREG(bits, MIPSInst_FS(ir));
@@ -1994,7 +2108,7 @@ dcopuop:
                SITOREG(rv.w, MIPSInst_FD(ir));
                break;
        case l_fmt:
-               if (!cpu_has_mips_3_4_5 && !cpu_has_mips64)
+               if (!cpu_has_mips_3_4_5_64_r2_r6)
                        return SIGILL;
 
                DITOREG(rv.l, MIPSInst_FD(ir));
@@ -2081,10 +2195,8 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        xcp->cp0_epc += dec_insn.pc_inc;        /* Skip NOPs */
                else {
                        /*
-                        * The 'ieee754_csr' is an alias of
-                        * ctx->fcr31.  No need to copy ctx->fcr31 to
-                        * ieee754_csr.  But ieee754_csr.rm is ieee
-                        * library modes. (not mips rounding mode)
+                        * The 'ieee754_csr' is an alias of ctx->fcr31.
+                        * No need to copy ctx->fcr31 to ieee754_csr.
                         */
                        sig = cop1Emulate(xcp, ctx, dec_insn, fault_addr);
                }
index 7f64577..8954ef0 100644 (file)
@@ -37,19 +37,20 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
        FLUSHYDP;
 
        switch (CLPAIR(xc, yc)) {
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+               return ieee754dp_nanxcpt(y);
+
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754dp_nanxcpt(ieee754dp_indef());
+               return ieee754dp_nanxcpt(x);
 
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -150,8 +151,6 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
                 * leaving result in xm, xs and xe.
                 */
                xm = xm + ym;
-               xe = xe;
-               xs = xs;
 
                if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
                        xm = XDPSRS1(xm);
@@ -160,11 +159,8 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
        } else {
                if (xm >= ym) {
                        xm = xm - ym;
-                       xe = xe;
-                       xs = xs;
                } else {
                        xm = ym - xm;
-                       xe = xe;
                        xs = ys;
                }
                if (xm == 0)
index 30f95f6..a29880e 100644 (file)
@@ -35,16 +35,11 @@ int ieee754dp_cmp(union ieee754dp x, union ieee754dp y, int cmp, int sig)
        FLUSHYDP;
        ieee754_clearcx();      /* Even clear inexact flag here */
 
-       if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
-               if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+       if (ieee754_class_nan(xc) || ieee754_class_nan(yc)) {
+               if (sig ||
+                   xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-               if (cmp & IEEE754_CUN)
-                       return 1;
-               if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-                       if (sig && ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
-                               return 0;
-               }
-               return 0;
+               return (cmp & IEEE754_CUN) != 0;
        } else {
                vx = x.bits;
                vy = y.bits;
index bef0e55..f4746f7 100644 (file)
@@ -39,19 +39,20 @@ union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y)
        FLUSHYDP;
 
        switch (CLPAIR(xc, yc)) {
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+               return ieee754dp_nanxcpt(y);
+
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754dp_nanxcpt(ieee754dp_indef());
+               return ieee754dp_nanxcpt(x);
 
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
index ffb69c5..57d09ca 100644 (file)
 #include "ieee754sp.h"
 #include "ieee754dp.h"
 
+static inline union ieee754dp ieee754dp_nan_fsp(int xs, u64 xm)
+{
+       return builddp(xs, DP_EMAX + 1 + DP_EBIAS,
+                      xm << (DP_FBITS - SP_FBITS));
+}
+
 union ieee754dp ieee754dp_fsp(union ieee754sp x)
 {
        COMPXSP;
@@ -34,15 +40,11 @@ union ieee754dp ieee754dp_fsp(union ieee754sp x)
 
        switch (xc) {
        case IEEE754_CLASS_SNAN:
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754dp_nanxcpt(ieee754dp_indef());
+               return ieee754dp_nanxcpt(ieee754dp_nan_fsp(xs, xm));
 
        case IEEE754_CLASS_QNAN:
-               return ieee754dp_nanxcpt(builddp(xs,
-                                                DP_EMAX + 1 + DP_EBIAS,
-                                                ((u64) xm
-                                                 << (DP_FBITS -
-                                                     SP_FBITS))));
+               return ieee754dp_nan_fsp(xs, xm);
+
        case IEEE754_CLASS_INF:
                return ieee754dp_inf(xs);
 
index d3acded..d0901f0 100644 (file)
@@ -47,19 +47,20 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y)
        FLUSHYDP;
 
        switch (CLPAIR(xc, yc)) {
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+               return ieee754dp_nanxcpt(y);
+
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754dp_nanxcpt(ieee754dp_indef());
+               return ieee754dp_nanxcpt(x);
 
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
index bccbe90..926d56b 100644 (file)
 
 union ieee754dp ieee754dp_neg(union ieee754dp x)
 {
-       COMPXDP;
-
-       EXPLODEXDP;
-       ieee754_clearcx();
-       FLUSHXDP;
-
-       /*
-        * Invert the sign ALWAYS to prevent an endless recursion on
-        * pow() in libc.
-        */
-       /* quick fix up */
-       DPSIGN(x) ^= 1;
-
-       if (xc == IEEE754_CLASS_SNAN) {
-               union ieee754dp y = ieee754dp_indef();
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               DPSIGN(y) = DPSIGN(x);
-               return ieee754dp_nanxcpt(y);
-       }
-
-       return x;
+       unsigned int oldrm;
+       union ieee754dp y;
+
+       oldrm = ieee754_csr.rm;
+       ieee754_csr.rm = FPU_CSR_RD;
+       y = ieee754dp_sub(ieee754dp_zero(0), x);
+       ieee754_csr.rm = oldrm;
+       return y;
 }
 
 union ieee754dp ieee754dp_abs(union ieee754dp x)
 {
-       COMPXDP;
-
-       EXPLODEXDP;
-       ieee754_clearcx();
-       FLUSHXDP;
-
-       /* Clear sign ALWAYS, irrespective of NaN */
-       DPSIGN(x) = 0;
-
-       if (xc == IEEE754_CLASS_SNAN) {
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754dp_nanxcpt(ieee754dp_indef());
-       }
-
-       return x;
+       unsigned int oldrm;
+       union ieee754dp y;
+
+       oldrm = ieee754_csr.rm;
+       ieee754_csr.rm = FPU_CSR_RD;
+       if (DPSIGN(x))
+               y = ieee754dp_sub(ieee754dp_zero(0), x);
+       else
+               y = ieee754dp_add(ieee754dp_zero(0), x);
+       ieee754_csr.rm = oldrm;
+       return y;
 }
index 041bbb6..cd5bc08 100644 (file)
@@ -42,13 +42,12 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
 
        /* x == INF or NAN? */
        switch (xc) {
-       case IEEE754_CLASS_QNAN:
-               /* sqrt(Nan) = Nan */
+       case IEEE754_CLASS_SNAN:
                return ieee754dp_nanxcpt(x);
 
-       case IEEE754_CLASS_SNAN:
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754dp_nanxcpt(ieee754dp_indef());
+       case IEEE754_CLASS_QNAN:
+               /* sqrt(Nan) = Nan */
+               return x;
 
        case IEEE754_CLASS_ZERO:
                /* sqrt(0) = 0 */
@@ -58,7 +57,7 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
                if (xs) {
                        /* sqrt(-Inf) = Nan */
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-                       return ieee754dp_nanxcpt(ieee754dp_indef());
+                       return ieee754dp_indef();
                }
                /* sqrt(+Inf) = Inf */
                return x;
@@ -71,7 +70,7 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
                if (xs) {
                        /* sqrt(-x) = Nan */
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-                       return ieee754dp_nanxcpt(ieee754dp_indef());
+                       return ieee754dp_indef();
                }
                break;
        }
index 7a17402..fc17a78 100644 (file)
@@ -37,19 +37,20 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
        FLUSHYDP;
 
        switch (CLPAIR(xc, yc)) {
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+               return ieee754dp_nanxcpt(y);
+
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754dp_nanxcpt(ieee754dp_indef());
+               return ieee754dp_nanxcpt(x);
 
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -153,8 +154,6 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
                /* generate 28 bit result of adding two 27 bit numbers
                 */
                xm = xm + ym;
-               xe = xe;
-               xs = xs;
 
                if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
                        xm = XDPSRS1(xm);       /* shift preserving sticky */
@@ -163,11 +162,8 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
        } else {
                if (xm >= ym) {
                        xm = xm - ym;
-                       xe = xe;
-                       xs = xs;
                } else {
                        xm = ym - xm;
-                       xe = xe;
                        xs = ys;
                }
                if (xm == 0) {
index 4f514f3..e0b5cc2 100644 (file)
@@ -94,9 +94,9 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
        regs->cp0_epc = ((unsigned long) &fr->emul) |
                get_isa16_mode(regs->cp0_epc);
 
-       flush_cache_sigtramp((unsigned long)&fr->badinst);
+       flush_cache_sigtramp((unsigned long)&fr->emul);
 
-       return SIGILL;          /* force out of emulation loop */
+       return 0;
 }
 
 int do_dsemulret(struct pt_regs *xcp)
@@ -158,6 +158,6 @@ int do_dsemulret(struct pt_regs *xcp)
 
        /* Set EPC to return to post-branch instruction */
        xcp->cp0_epc = epc;
-
+       MIPS_FPU_EMU_INC_STATS(ds_emul);
        return 1;
 }
index 43c4fb5..a5ca108 100644 (file)
@@ -126,84 +126,21 @@ enum {
 #define IEEE754_CGT    0x04
 #define IEEE754_CUN    0x08
 
-/* "normal" comparisons
-*/
-static inline int ieee754sp_eq(union ieee754sp x, union ieee754sp y)
-{
-       return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
-}
-
-static inline int ieee754sp_ne(union ieee754sp x, union ieee754sp y)
-{
-       return ieee754sp_cmp(x, y,
-                            IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
-}
-
-static inline int ieee754sp_lt(union ieee754sp x, union ieee754sp y)
-{
-       return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
-}
-
-static inline int ieee754sp_le(union ieee754sp x, union ieee754sp y)
-{
-       return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
-}
-
-static inline int ieee754sp_gt(union ieee754sp x, union ieee754sp y)
-{
-       return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
-}
-
-
-static inline int ieee754sp_ge(union ieee754sp x, union ieee754sp y)
-{
-       return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
-}
-
-static inline int ieee754dp_eq(union ieee754dp x, union ieee754dp y)
-{
-       return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
-}
-
-static inline int ieee754dp_ne(union ieee754dp x, union ieee754dp y)
-{
-       return ieee754dp_cmp(x, y,
-                            IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
-}
-
-static inline int ieee754dp_lt(union ieee754dp x, union ieee754dp y)
-{
-       return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
-}
-
-static inline int ieee754dp_le(union ieee754dp x, union ieee754dp y)
-{
-       return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
-}
-
-static inline int ieee754dp_gt(union ieee754dp x, union ieee754dp y)
-{
-       return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
-}
-
-static inline int ieee754dp_ge(union ieee754dp x, union ieee754dp y)
-{
-       return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
-}
-
 /*
  * The control status register
  */
 struct _ieee754_csr {
-       __BITFIELD_FIELD(unsigned pad0:7,
-       __BITFIELD_FIELD(unsigned nod:1,        /* set 1 for no denormalised numbers */
-       __BITFIELD_FIELD(unsigned c:1,          /* condition */
-       __BITFIELD_FIELD(unsigned pad1:5,
+       __BITFIELD_FIELD(unsigned fcc:7,        /* condition[7:1] */
+       __BITFIELD_FIELD(unsigned nod:1,        /* set 1 for no denormals */
+       __BITFIELD_FIELD(unsigned c:1,          /* condition[0] */
+       __BITFIELD_FIELD(unsigned pad0:3,
+       __BITFIELD_FIELD(unsigned abs2008:1,    /* IEEE 754-2008 ABS/NEG.fmt */
+       __BITFIELD_FIELD(unsigned nan2008:1,    /* IEEE 754-2008 NaN mode */
        __BITFIELD_FIELD(unsigned cx:6,         /* exceptions this operation */
        __BITFIELD_FIELD(unsigned mx:5,         /* exception enable  mask */
        __BITFIELD_FIELD(unsigned sx:5,         /* exceptions total */
        __BITFIELD_FIELD(unsigned rm:2,         /* current rounding mode */
-       ;))))))))
+       ;))))))))))
 };
 #define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.fcr31))
 
@@ -257,23 +194,23 @@ static inline int ieee754_sxtest(unsigned n)
 union ieee754sp ieee754sp_dump(char *s, union ieee754sp x);
 union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
 
-#define IEEE754_SPCVAL_PZERO   0
-#define IEEE754_SPCVAL_NZERO   1
-#define IEEE754_SPCVAL_PONE    2
-#define IEEE754_SPCVAL_NONE    3
-#define IEEE754_SPCVAL_PTEN    4
-#define IEEE754_SPCVAL_NTEN    5
-#define IEEE754_SPCVAL_PINFINITY       6
-#define IEEE754_SPCVAL_NINFINITY       7
-#define IEEE754_SPCVAL_INDEF   8
-#define IEEE754_SPCVAL_PMAX    9       /* +max norm */
-#define IEEE754_SPCVAL_NMAX    10      /* -max norm */
-#define IEEE754_SPCVAL_PMIN    11      /* +min norm */
-#define IEEE754_SPCVAL_NMIN    12      /* +min norm */
-#define IEEE754_SPCVAL_PMIND   13      /* +min denorm */
-#define IEEE754_SPCVAL_NMIND   14      /* +min denorm */
-#define IEEE754_SPCVAL_P1E31   15      /* + 1.0e31 */
-#define IEEE754_SPCVAL_P1E63   16      /* + 1.0e63 */
+#define IEEE754_SPCVAL_PZERO           0       /* +0.0 */
+#define IEEE754_SPCVAL_NZERO           1       /* -0.0 */
+#define IEEE754_SPCVAL_PONE            2       /* +1.0 */
+#define IEEE754_SPCVAL_NONE            3       /* -1.0 */
+#define IEEE754_SPCVAL_PTEN            4       /* +10.0 */
+#define IEEE754_SPCVAL_NTEN            5       /* -10.0 */
+#define IEEE754_SPCVAL_PINFINITY       6       /* +inf */
+#define IEEE754_SPCVAL_NINFINITY       7       /* -inf */
+#define IEEE754_SPCVAL_INDEF           8       /* quiet NaN */
+#define IEEE754_SPCVAL_PMAX            9       /* +max norm */
+#define IEEE754_SPCVAL_NMAX            10      /* -max norm */
+#define IEEE754_SPCVAL_PMIN            11      /* +min norm */
+#define IEEE754_SPCVAL_NMIN            12      /* -min norm */
+#define IEEE754_SPCVAL_PMIND           13      /* +min denorm */
+#define IEEE754_SPCVAL_NMIND           14      /* -min denorm */
+#define IEEE754_SPCVAL_P1E31           15      /* + 1.0e31 */
+#define IEEE754_SPCVAL_P1E63           16      /* + 1.0e63 */
 
 extern const union ieee754dp __ieee754dp_spcvals[];
 extern const union ieee754sp __ieee754sp_spcvals[];
index 068f45a..522d843 100644 (file)
@@ -30,9 +30,9 @@ int ieee754dp_class(union ieee754dp x)
        return xc;
 }
 
-int ieee754dp_isnan(union ieee754dp x)
+static inline int ieee754dp_isnan(union ieee754dp x)
 {
-       return ieee754dp_class(x) >= IEEE754_CLASS_SNAN;
+       return ieee754_class_nan(ieee754dp_class(x));
 }
 
 static inline int ieee754dp_issnan(union ieee754dp x)
@@ -42,23 +42,16 @@ static inline int ieee754dp_issnan(union ieee754dp x)
 }
 
 
+/*
+ * Raise the Invalid Operation IEEE 754 exception
+ * and convert the signaling NaN supplied to a quiet NaN.
+ */
 union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r)
 {
-       assert(ieee754dp_isnan(r));
-
-       if (!ieee754dp_issnan(r))       /* QNAN does not cause invalid op !! */
-               return r;
-
-       if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION)) {
-               /* not enabled convert to a quiet NaN */
-               DPMANT(r) &= (~DP_MBIT(DP_FBITS-1));
-               if (ieee754dp_isnan(r))
-                       return r;
-               else
-                       return ieee754dp_indef();
-       }
+       assert(ieee754dp_issnan(r));
 
-       return r;
+       ieee754_setcx(IEEE754_INVALID_OPERATION);
+       return ieee754dp_indef();
 }
 
 static u64 ieee754dp_get_rounding(int sn, u64 xm)
index 61fd6fd..e2babd9 100644 (file)
@@ -77,6 +77,5 @@ static inline union ieee754dp builddp(int s, int bx, u64 m)
        return r;
 }
 
-extern int ieee754dp_isnan(union ieee754dp);
 extern union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp);
 extern union ieee754dp ieee754dp_format(int, int, u64);
index f0365bb..05389d5 100644 (file)
@@ -44,6 +44,11 @@ static inline int ieee754_setandtestcx(const unsigned int x)
        return ieee754_csr.mx & x;
 }
 
+static inline int ieee754_class_nan(int xc)
+{
+       return xc >= IEEE754_CLASS_SNAN;
+}
+
 #define COMPXSP \
        unsigned xm; int xe; int xs __maybe_unused; int xc
 
index ba88301..ca8e35e 100644 (file)
@@ -30,9 +30,9 @@ int ieee754sp_class(union ieee754sp x)
        return xc;
 }
 
-int ieee754sp_isnan(union ieee754sp x)
+static inline int ieee754sp_isnan(union ieee754sp x)
 {
-       return ieee754sp_class(x) >= IEEE754_CLASS_SNAN;
+       return ieee754_class_nan(ieee754sp_class(x));
 }
 
 static inline int ieee754sp_issnan(union ieee754sp x)
@@ -42,23 +42,16 @@ static inline int ieee754sp_issnan(union ieee754sp x)
 }
 
 
+/*
+ * Raise the Invalid Operation IEEE 754 exception
+ * and convert the signaling NaN supplied to a quiet NaN.
+ */
 union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r)
 {
-       assert(ieee754sp_isnan(r));
-
-       if (!ieee754sp_issnan(r))       /* QNAN does not cause invalid op !! */
-               return r;
-
-       if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION)) {
-               /* not enabled convert to a quiet NaN */
-               SPMANT(r) &= (~SP_MBIT(SP_FBITS-1));
-               if (ieee754sp_isnan(r))
-                       return r;
-               else
-                       return ieee754sp_indef();
-       }
+       assert(ieee754sp_issnan(r));
 
-       return r;
+       ieee754_setcx(IEEE754_INVALID_OPERATION);
+       return ieee754sp_indef();
 }
 
 static unsigned ieee754sp_get_rounding(int sn, unsigned xm)
index ad268e3..374a3f0 100644 (file)
@@ -82,6 +82,5 @@ static inline union ieee754sp buildsp(int s, int bx, unsigned m)
        return r;
 }
 
-extern int ieee754sp_isnan(union ieee754sp);
 extern union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp);
 extern union ieee754sp ieee754sp_format(int, int, unsigned);
index becdd63..f308e0f 100644 (file)
@@ -61,6 +61,7 @@ do {                                                                  \
        FPU_STAT_CREATE(ieee754_overflow);
        FPU_STAT_CREATE(ieee754_zerodiv);
        FPU_STAT_CREATE(ieee754_invalidop);
+       FPU_STAT_CREATE(ds_emul);
 
        return 0;
 }
index 2d84d46..f1c87b0 100644 (file)
@@ -37,19 +37,20 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
        FLUSHYSP;
 
        switch (CLPAIR(xc, yc)) {
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+               return ieee754sp_nanxcpt(y);
+
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754sp_nanxcpt(ieee754sp_indef());
+               return ieee754sp_nanxcpt(x);
 
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -148,8 +149,6 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
                 * leaving result in xm, xs and xe.
                 */
                xm = xm + ym;
-               xe = xe;
-               xs = xs;
 
                if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
                        SPXSRSX1();
@@ -157,11 +156,8 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
        } else {
                if (xm >= ym) {
                        xm = xm - ym;
-                       xe = xe;
-                       xs = xs;
                } else {
                        xm = ym - xm;
-                       xe = xe;
                        xs = ys;
                }
                if (xm == 0)
index addbccb..67b82f1 100644 (file)
@@ -35,16 +35,11 @@ int ieee754sp_cmp(union ieee754sp x, union ieee754sp y, int cmp, int sig)
        FLUSHYSP;
        ieee754_clearcx();      /* Even clear inexact flag here */
 
-       if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
-               if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
+       if (ieee754_class_nan(xc) || ieee754_class_nan(yc)) {
+               if (sig ||
+                   xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-               if (cmp & IEEE754_CUN)
-                       return 1;
-               if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
-                       if (sig && ieee754_setandtestcx(IEEE754_INVALID_OPERATION))
-                               return 0;
-               }
-               return 0;
+               return (cmp & IEEE754_CUN) != 0;
        } else {
                vx = x.bits;
                vy = y.bits;
index 721f317..27f6db3 100644 (file)
@@ -39,19 +39,20 @@ union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y)
        FLUSHYSP;
 
        switch (CLPAIR(xc, yc)) {
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+               return ieee754sp_nanxcpt(y);
+
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754sp_nanxcpt(ieee754sp_indef());
+               return ieee754sp_nanxcpt(x);
 
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
index 1b266fb..3797148 100644 (file)
 #include "ieee754sp.h"
 #include "ieee754dp.h"
 
+static inline union ieee754sp ieee754sp_nan_fdp(int xs, u64 xm)
+{
+       return buildsp(xs, SP_EMAX + 1 + SP_EBIAS,
+                      xm >> (DP_FBITS - SP_FBITS));
+}
+
 union ieee754sp ieee754sp_fdp(union ieee754dp x)
 {
+       union ieee754sp y;
        u32 rm;
 
        COMPXDP;
-       union ieee754sp nan;
+       COMPYSP;
 
        EXPLODEXDP;
 
@@ -37,15 +44,14 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x)
 
        switch (xc) {
        case IEEE754_CLASS_SNAN:
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754sp_nanxcpt(ieee754sp_indef());
+               return ieee754sp_nanxcpt(ieee754sp_nan_fdp(xs, xm));
 
        case IEEE754_CLASS_QNAN:
-               nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32)
-                               (xm >> (DP_FBITS - SP_FBITS)));
-               if (!ieee754sp_isnan(nan))
-                       nan = ieee754sp_indef();
-               return ieee754sp_nanxcpt(nan);
+               y = ieee754sp_nan_fdp(xs, xm);
+               EXPLODEYSP;
+               if (!ieee754_class_nan(yc))
+                       y = ieee754sp_indef();
+               return y;
 
        case IEEE754_CLASS_INF:
                return ieee754sp_inf(xs);
index 890c13a..d910c43 100644 (file)
@@ -47,19 +47,20 @@ union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y)
        FLUSHYSP;
 
        switch (CLPAIR(xc, yc)) {
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+               return ieee754sp_nanxcpt(y);
+
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754sp_nanxcpt(ieee754sp_indef());
+               return ieee754sp_nanxcpt(x);
 
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
index f1ffaa9..c50e945 100644 (file)
 
 union ieee754sp ieee754sp_neg(union ieee754sp x)
 {
-       COMPXSP;
-
-       EXPLODEXSP;
-       ieee754_clearcx();
-       FLUSHXSP;
-
-       /*
-        * Invert the sign ALWAYS to prevent an endless recursion on
-        * pow() in libc.
-        */
-       /* quick fix up */
-       SPSIGN(x) ^= 1;
-
-       if (xc == IEEE754_CLASS_SNAN) {
-               union ieee754sp y = ieee754sp_indef();
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               SPSIGN(y) = SPSIGN(x);
-               return ieee754sp_nanxcpt(y);
-       }
-
-       return x;
+       unsigned int oldrm;
+       union ieee754sp y;
+
+       oldrm = ieee754_csr.rm;
+       ieee754_csr.rm = FPU_CSR_RD;
+       y = ieee754sp_sub(ieee754sp_zero(0), x);
+       ieee754_csr.rm = oldrm;
+       return y;
 }
 
 union ieee754sp ieee754sp_abs(union ieee754sp x)
 {
-       COMPXSP;
-
-       EXPLODEXSP;
-       ieee754_clearcx();
-       FLUSHXSP;
-
-       /* Clear sign ALWAYS, irrespective of NaN */
-       SPSIGN(x) = 0;
-
-       if (xc == IEEE754_CLASS_SNAN) {
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754sp_nanxcpt(ieee754sp_indef());
-       }
-
-       return x;
+       unsigned int oldrm;
+       union ieee754sp y;
+
+       oldrm = ieee754_csr.rm;
+       ieee754_csr.rm = FPU_CSR_RD;
+       if (SPSIGN(x))
+               y = ieee754sp_sub(ieee754sp_zero(0), x);
+       else
+               y = ieee754sp_add(ieee754sp_zero(0), x);
+       ieee754_csr.rm = oldrm;
+       return y;
 }
index b7c098a..67059c3 100644 (file)
@@ -35,13 +35,12 @@ union ieee754sp ieee754sp_sqrt(union ieee754sp x)
 
        /* x == INF or NAN? */
        switch (xc) {
-       case IEEE754_CLASS_QNAN:
-               /* sqrt(Nan) = Nan */
+       case IEEE754_CLASS_SNAN:
                return ieee754sp_nanxcpt(x);
 
-       case IEEE754_CLASS_SNAN:
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754sp_nanxcpt(ieee754sp_indef());
+       case IEEE754_CLASS_QNAN:
+               /* sqrt(Nan) = Nan */
+               return x;
 
        case IEEE754_CLASS_ZERO:
                /* sqrt(0) = 0 */
@@ -51,7 +50,7 @@ union ieee754sp ieee754sp_sqrt(union ieee754sp x)
                if (xs) {
                        /* sqrt(-Inf) = Nan */
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-                       return ieee754sp_nanxcpt(ieee754sp_indef());
+                       return ieee754sp_indef();
                }
                /* sqrt(+Inf) = Inf */
                return x;
@@ -61,7 +60,7 @@ union ieee754sp ieee754sp_sqrt(union ieee754sp x)
                if (xs) {
                        /* sqrt(-x) = Nan */
                        ieee754_setcx(IEEE754_INVALID_OPERATION);
-                       return ieee754sp_nanxcpt(ieee754sp_indef());
+                       return ieee754sp_indef();
                }
                break;
        }
index 8592e49..ec5f937 100644 (file)
@@ -37,19 +37,20 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
        FLUSHYSP;
 
        switch (CLPAIR(xc, yc)) {
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
-       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
        case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
+               return ieee754sp_nanxcpt(y);
+
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
        case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
-               ieee754_setcx(IEEE754_INVALID_OPERATION);
-               return ieee754sp_nanxcpt(ieee754sp_indef());
+               return ieee754sp_nanxcpt(x);
 
        case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
        case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
@@ -148,8 +149,6 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
                /* generate 28 bit result of adding two 27 bit numbers
                 */
                xm = xm + ym;
-               xe = xe;
-               xs = xs;
 
                if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
                        SPXSRSX1();     /* shift preserving sticky */
@@ -157,11 +156,8 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
        } else {
                if (xm >= ym) {
                        xm = xm - ym;
-                       xe = xe;
-                       xs = xs;
                } else {
                        xm = ym - xm;
-                       xe = xe;
                        xs = ys;
                }
                if (xm == 0) {
index 3f80596..0dbb65a 100644 (file)
@@ -430,6 +430,7 @@ static inline void local_r4k___flush_cache_all(void * args)
        case CPU_R10000:
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
                /*
                 * These caches are inclusive caches, that is, if something
                 * is not cached in the S-cache, we know it also won't be
@@ -506,7 +507,7 @@ static inline void local_r4k_flush_cache_mm(void * args)
 
        /*
         * Kludge alert.  For obscure reasons R4000SC and R4400SC go nuts if we
-        * only flush the primary caches but R10000 and R12000 behave sane ...
+        * only flush the primary caches but R1x000 behave sane ...
         * R4000SC and R4400SC indexed S-cache ops also invalidate primary
         * caches, so we can bail out early.
         */
@@ -888,33 +889,39 @@ static inline void rm7k_erratum31(void)
        }
 }
 
-static inline void alias_74k_erratum(struct cpuinfo_mips *c)
+static inline int alias_74k_erratum(struct cpuinfo_mips *c)
 {
        unsigned int imp = c->processor_id & PRID_IMP_MASK;
        unsigned int rev = c->processor_id & PRID_REV_MASK;
+       int present = 0;
 
        /*
         * Early versions of the 74K do not update the cache tags on a
         * vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG
-        * aliases. In this case it is better to treat the cache as always
-        * having aliases.
+        * aliases.  In this case it is better to treat the cache as always
+        * having aliases.  Also disable the synonym tag update feature
+        * where available.  In this case no opportunistic tag update will
+        * happen where a load causes a virtual address miss but a physical
+        * address hit during a D-cache look-up.
         */
        switch (imp) {
        case PRID_IMP_74K:
                if (rev <= PRID_REV_ENCODE_332(2, 4, 0))
-                       c->dcache.flags |= MIPS_CACHE_VTAG;
+                       present = 1;
                if (rev == PRID_REV_ENCODE_332(2, 4, 0))
                        write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
                break;
        case PRID_IMP_1074K:
                if (rev <= PRID_REV_ENCODE_332(1, 1, 0)) {
-                       c->dcache.flags |= MIPS_CACHE_VTAG;
+                       present = 1;
                        write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
                }
                break;
        default:
                BUG();
        }
+
+       return present;
 }
 
 static void b5k_instruction_hazard(void)
@@ -938,6 +945,7 @@ static void probe_pcache(void)
        struct cpuinfo_mips *c = &current_cpu_data;
        unsigned int config = read_c0_config();
        unsigned int prid = read_c0_prid();
+       int has_74k_erratum = 0;
        unsigned long config1;
        unsigned int lsize;
 
@@ -1012,6 +1020,7 @@ static void probe_pcache(void)
        case CPU_R10000:
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
                icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29));
                c->icache.linesz = 64;
                c->icache.ways = 2;
@@ -1223,8 +1232,8 @@ static void probe_pcache(void)
                dcache_size / (c->dcache.linesz * c->dcache.ways) : 0;
 
        /*
-        * R10000 and R12000 P-caches are odd in a positive way.  They're 32kB
-        * 2-way virtually indexed so normally would suffer from aliases.  So
+        * R1x000 P-caches are odd in a positive way.  They're 32kB 2-way
+        * virtually indexed so normally would suffer from aliases.  So
         * normally they'd suffer from aliases but magic in the hardware deals
         * with that for us so we don't need to take care ourselves.
         */
@@ -1240,11 +1249,12 @@ static void probe_pcache(void)
        case CPU_R10000:
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
                break;
 
        case CPU_74K:
        case CPU_1074K:
-               alias_74k_erratum(c);
+               has_74k_erratum = alias_74k_erratum(c);
                /* Fall through. */
        case CPU_M14KC:
        case CPU_M14KEC:
@@ -1259,7 +1269,7 @@ static void probe_pcache(void)
                if (!(read_c0_config7() & MIPS_CONF7_IAR) &&
                    (c->icache.waysize > PAGE_SIZE))
                        c->icache.flags |= MIPS_CACHE_ALIASES;
-               if (read_c0_config7() & MIPS_CONF7_AR) {
+               if (!has_74k_erratum && (read_c0_config7() & MIPS_CONF7_AR)) {
                        /*
                         * Effectively physically indexed dcache,
                         * thus no virtual aliases.
@@ -1268,7 +1278,7 @@ static void probe_pcache(void)
                        break;
                }
        default:
-               if (c->dcache.waysize > PAGE_SIZE)
+               if (has_74k_erratum || c->dcache.waysize > PAGE_SIZE)
                        c->dcache.flags |= MIPS_CACHE_ALIASES;
        }
 
@@ -1438,6 +1448,7 @@ static void setup_scache(void)
        case CPU_R10000:
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
                scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16);
                c->scache.linesz = 64 << ((config >> 13) & 1);
                c->scache.ways = 2;
index 7e3ea77..77d96db 100644 (file)
@@ -119,36 +119,37 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
 
 EXPORT_SYMBOL(__flush_anon_page);
 
-static void mips_flush_dcache_from_pte(pte_t pteval, unsigned long address)
+void __flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+       unsigned long addr;
+
+       if (PageHighMem(page))
+               return;
+
+       addr = (unsigned long) page_address(page);
+       flush_data_cache_page(addr);
+}
+EXPORT_SYMBOL_GPL(__flush_icache_page);
+
+void __update_cache(struct vm_area_struct *vma, unsigned long address,
+       pte_t pte)
 {
        struct page *page;
-       unsigned long pfn = pte_pfn(pteval);
+       unsigned long pfn, addr;
+       int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
 
+       pfn = pte_pfn(pte);
        if (unlikely(!pfn_valid(pfn)))
                return;
-
        page = pfn_to_page(pfn);
        if (page_mapping(page) && Page_dcache_dirty(page)) {
-               unsigned long page_addr = (unsigned long) page_address(page);
-
-               if (!cpu_has_ic_fills_f_dc ||
-                   pages_do_alias(page_addr, address & PAGE_MASK))
-                       flush_data_cache_page(page_addr);
+               addr = (unsigned long) page_address(page);
+               if (exec || pages_do_alias(addr, address & PAGE_MASK))
+                       flush_data_cache_page(addr);
                ClearPageDcacheDirty(page);
        }
 }
 
-void set_pte_at(struct mm_struct *mm, unsigned long addr,
-        pte_t *ptep, pte_t pteval)
-{
-        if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) {
-                if (pte_present(pteval))
-                        mips_flush_dcache_from_pte(pteval, addr);
-        }
-
-        set_pte(ptep, pteval);
-}
-
 unsigned long _page_cachable_default;
 EXPORT_SYMBOL(_page_cachable_default);
 
index af5f046..609d124 100644 (file)
@@ -258,7 +258,7 @@ static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
        if (cpu_needs_post_dma_flush(dev))
                __dma_sync(dma_addr_to_page(dev, dma_addr),
                           dma_addr & ~PAGE_MASK, size, direction);
-
+       plat_post_dma_flush(dev);
        plat_unmap_dma_mem(dev, dma_addr, size, direction);
 }
 
@@ -312,6 +312,7 @@ static void mips_dma_sync_single_for_cpu(struct device *dev,
        if (cpu_needs_post_dma_flush(dev))
                __dma_sync(dma_addr_to_page(dev, dma_handle),
                           dma_handle & ~PAGE_MASK, size, direction);
+       plat_post_dma_flush(dev);
 }
 
 static void mips_dma_sync_single_for_device(struct device *dev,
@@ -331,6 +332,7 @@ static void mips_dma_sync_sg_for_cpu(struct device *dev,
                for (i = 0; i < nelems; i++, sg++)
                        __dma_sync(sg_page(sg), sg->offset, sg->length,
                                   direction);
+       plat_post_dma_flush(dev);
 }
 
 static void mips_dma_sync_sg_for_device(struct device *dev,
index 448cde3..faa5c98 100644 (file)
@@ -96,7 +96,7 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
        vaddr = __fix_to_virt(FIX_CMAP_END - idx);
        pte = mk_pte(page, prot);
 #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
-       entrylo = pte.pte_high;
+       entrylo = pte_to_entrylo(pte.pte_high);
 #else
        entrylo = pte_to_entrylo(pte_val(pte));
 #endif
@@ -106,6 +106,11 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot)
        write_c0_entryhi(vaddr & (PAGE_MASK << 1));
        write_c0_entrylo0(entrylo);
        write_c0_entrylo1(entrylo);
+#ifdef CONFIG_XPA
+       entrylo = (pte.pte_low & _PFNX_MASK);
+       writex_c0_entrylo0(entrylo);
+       writex_c0_entrylo1(entrylo);
+#endif
        tlbidx = read_c0_wired();
        write_c0_wired(tlbidx + 1);
        write_c0_index(tlbidx);
index 3f85f92..885d73f 100644 (file)
@@ -157,6 +157,7 @@ static void set_prefetch_parameters(void)
                case CPU_R10000:
                case CPU_R12000:
                case CPU_R14000:
+               case CPU_R16000:
                        /*
                         * Those values have been experimentally tuned for an
                         * Origin 200.
index b2afa49..a27a088 100644 (file)
@@ -333,9 +333,17 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
                ptep = pte_offset_map(pmdp, address);
 
 #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
+#ifdef CONFIG_XPA
+               write_c0_entrylo0(pte_to_entrylo(ptep->pte_high));
+               writex_c0_entrylo0(ptep->pte_low & _PFNX_MASK);
+               ptep++;
+               write_c0_entrylo1(pte_to_entrylo(ptep->pte_high));
+               writex_c0_entrylo1(ptep->pte_low & _PFNX_MASK);
+#else
                write_c0_entrylo0(ptep->pte_high);
                ptep++;
                write_c0_entrylo1(ptep->pte_high);
+#endif
 #else
                write_c0_entrylo0(pte_to_entrylo(pte_val(*ptep++)));
                write_c0_entrylo1(pte_to_entrylo(pte_val(*ptep)));
@@ -355,6 +363,9 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
 void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
                     unsigned long entryhi, unsigned long pagemask)
 {
+#ifdef CONFIG_XPA
+       panic("Broken for XPA kernels");
+#else
        unsigned long flags;
        unsigned long wired;
        unsigned long old_pagemask;
@@ -383,6 +394,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
        write_c0_pagemask(old_pagemask);
        local_flush_tlb_all();
        local_irq_restore(flags);
+#endif
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -477,7 +489,8 @@ static void r4k_tlb_configure(void)
        write_c0_wired(0);
        if (current_cpu_type() == CPU_R10000 ||
            current_cpu_type() == CPU_R12000 ||
-           current_cpu_type() == CPU_R14000)
+           current_cpu_type() == CPU_R14000 ||
+           current_cpu_type() == CPU_R16000)
                write_c0_framemask(0);
 
        if (cpu_has_rixi) {
index d75ff73..97c8702 100644 (file)
 #include <asm/uasm.h>
 #include <asm/setup.h>
 
+static int __cpuinitdata mips_xpa_disabled;
+
+static int __init xpa_disable(char *s)
+{
+       mips_xpa_disabled = 1;
+
+       return 1;
+}
+
+__setup("noxpa", xpa_disable);
+
 /*
  * TLB load/store/modify handlers.
  *
@@ -231,14 +242,14 @@ static void output_pgtable_bits_defines(void)
        pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT);
        pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT);
 #endif
+#ifdef CONFIG_CPU_MIPSR2
        if (cpu_has_rixi) {
 #ifdef _PAGE_NO_EXEC_SHIFT
                pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);
-#endif
-#ifdef _PAGE_NO_READ_SHIFT
                pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT);
 #endif
        }
+#endif
        pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT);
        pr_define("_PAGE_VALID_SHIFT %d\n", _PAGE_VALID_SHIFT);
        pr_define("_PAGE_DIRTY_SHIFT %d\n", _PAGE_DIRTY_SHIFT);
@@ -501,26 +512,9 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
        case tlb_indexed: tlbw = uasm_i_tlbwi; break;
        }
 
-       if (cpu_has_mips_r2_exec_hazard) {
-               /*
-                * The architecture spec says an ehb is required here,
-                * but a number of cores do not have the hazard and
-                * using an ehb causes an expensive pipeline stall.
-                */
-               switch (current_cpu_type()) {
-               case CPU_M14KC:
-               case CPU_74K:
-               case CPU_1074K:
-               case CPU_PROAPTIV:
-               case CPU_P5600:
-               case CPU_M5150:
-               case CPU_QEMU_GENERIC:
-                       break;
-
-               default:
+       if (cpu_has_mips_r2_r6) {
+               if (cpu_has_mips_r2_exec_hazard)
                        uasm_i_ehb(p);
-                       break;
-               }
                tlbw(p);
                return;
        }
@@ -569,6 +563,7 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
        case CPU_R10000:
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
        case CPU_4KC:
        case CPU_4KEC:
        case CPU_M14KC:
@@ -1027,12 +1022,27 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep)
        } else {
                int pte_off_even = sizeof(pte_t) / 2;
                int pte_off_odd = pte_off_even + sizeof(pte_t);
+#ifdef CONFIG_XPA
+               const int scratch = 1; /* Our extra working register */
 
-               /* The pte entries are pre-shifted */
-               uasm_i_lw(p, tmp, pte_off_even, ptep); /* get even pte */
-               UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
-               uasm_i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */
-               UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
+               uasm_i_addu(p, scratch, 0, ptep);
+#endif
+               uasm_i_lw(p, tmp, pte_off_even, ptep); /* even pte */
+               uasm_i_lw(p, ptep, pte_off_odd, ptep); /* odd pte */
+               UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL));
+               UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL));
+               UASM_i_MTC0(p, tmp, C0_ENTRYLO0);
+               UASM_i_MTC0(p, ptep, C0_ENTRYLO1);
+#ifdef CONFIG_XPA
+               uasm_i_lw(p, tmp, 0, scratch);
+               uasm_i_lw(p, ptep, sizeof(pte_t), scratch);
+               uasm_i_lui(p, scratch, 0xff);
+               uasm_i_ori(p, scratch, scratch, 0xffff);
+               uasm_i_and(p, tmp, scratch, tmp);
+               uasm_i_and(p, ptep, scratch, ptep);
+               uasm_i_mthc0(p, tmp, C0_ENTRYLO0);
+               uasm_i_mthc0(p, ptep, C0_ENTRYLO1);
+#endif
        }
 #else
        UASM_i_LW(p, tmp, 0, ptep); /* get even pte */
@@ -1533,8 +1543,14 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr,
 {
 #ifdef CONFIG_PHYS_ADDR_T_64BIT
        unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY);
-#endif
 
+       if (!cpu_has_64bits) {
+               const int scratch = 1; /* Our extra working register */
+
+               uasm_i_lui(p, scratch, (mode >> 16));
+               uasm_i_or(p, pte, pte, scratch);
+       } else
+#endif
        uasm_i_ori(p, pte, pte, mode);
 #ifdef CONFIG_SMP
 # ifdef CONFIG_PHYS_ADDR_T_64BIT
@@ -1598,15 +1614,17 @@ build_pte_present(u32 **p, struct uasm_reloc **r,
                        uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
                        uasm_i_nop(p);
                } else {
-                       uasm_i_andi(p, t, pte, _PAGE_PRESENT);
+                       uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT);
+                       uasm_i_andi(p, t, t, 1);
                        uasm_il_beqz(p, r, t, lid);
                        if (pte == t)
                                /* You lose the SMP race :-(*/
                                iPTE_LW(p, pte, ptr);
                }
        } else {
-               uasm_i_andi(p, t, pte, _PAGE_PRESENT | _PAGE_READ);
-               uasm_i_xori(p, t, t, _PAGE_PRESENT | _PAGE_READ);
+               uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT);
+               uasm_i_andi(p, t, t, 3);
+               uasm_i_xori(p, t, t, 3);
                uasm_il_bnez(p, r, t, lid);
                if (pte == t)
                        /* You lose the SMP race :-(*/
@@ -1635,8 +1653,9 @@ build_pte_writable(u32 **p, struct uasm_reloc **r,
 {
        int t = scratch >= 0 ? scratch : pte;
 
-       uasm_i_andi(p, t, pte, _PAGE_PRESENT | _PAGE_WRITE);
-       uasm_i_xori(p, t, t, _PAGE_PRESENT | _PAGE_WRITE);
+       uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT);
+       uasm_i_andi(p, t, t, 5);
+       uasm_i_xori(p, t, t, 5);
        uasm_il_bnez(p, r, t, lid);
        if (pte == t)
                /* You lose the SMP race :-(*/
@@ -1672,7 +1691,8 @@ build_pte_modifiable(u32 **p, struct uasm_reloc **r,
                uasm_i_nop(p);
        } else {
                int t = scratch >= 0 ? scratch : pte;
-               uasm_i_andi(p, t, pte, _PAGE_WRITE);
+               uasm_i_srl(p, t, pte, _PAGE_WRITE_SHIFT);
+               uasm_i_andi(p, t, t, 1);
                uasm_il_beqz(p, r, t, lid);
                if (pte == t)
                        /* You lose the SMP race :-(*/
@@ -2285,6 +2305,11 @@ static void config_htw_params(void)
 
        pwsize = ilog2(PTRS_PER_PGD) << MIPS_PWSIZE_GDW_SHIFT;
        pwsize |= ilog2(PTRS_PER_PTE) << MIPS_PWSIZE_PTW_SHIFT;
+
+       /* If XPA has been enabled, PTEs are 64-bit in size. */
+       if (read_c0_pagegrain() & PG_ELPA)
+               pwsize |= 1;
+
        write_c0_pwsize(pwsize);
 
        /* Make sure everything is set before we enable the HTW */
@@ -2298,6 +2323,28 @@ static void config_htw_params(void)
        print_htw_config();
 }
 
+static void config_xpa_params(void)
+{
+#ifdef CONFIG_XPA
+       unsigned int pagegrain;
+
+       if (mips_xpa_disabled) {
+               pr_info("Extended Physical Addressing (XPA) disabled\n");
+               return;
+       }
+
+       pagegrain = read_c0_pagegrain();
+       write_c0_pagegrain(pagegrain | PG_ELPA);
+       back_to_back_c0_hazard();
+       pagegrain = read_c0_pagegrain();
+
+       if (pagegrain & PG_ELPA)
+               pr_info("Extended Physical Addressing (XPA) enabled\n");
+       else
+               panic("Extended Physical Addressing (XPA) disabled");
+#endif
+}
+
 void build_tlb_refill_handler(void)
 {
        /*
@@ -2362,8 +2409,9 @@ void build_tlb_refill_handler(void)
                }
                if (cpu_has_local_ebase)
                        build_r4000_tlb_refill_handler();
+               if (cpu_has_xpa)
+                       config_xpa_params();
                if (cpu_has_htw)
                        config_htw_params();
-
        }
 }
index 8fddd2c..b769657 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
+#include <asm/cdmm.h>
 #include <asm/maar.h>
 #include <asm/sections.h>
 #include <asm/fw/fw.h>
@@ -53,6 +54,12 @@ fw_memblock_t * __init fw_getmdesc(int eva)
                pr_warn("memsize not set in YAMON, set to default (32Mb)\n");
                physical_memsize = 0x02000000;
        } else {
+               if (memsize > (256 << 20)) { /* memsize should be capped to 256M */
+                       pr_warn("Unsupported memsize value (0x%lx) detected! "
+                               "Using 0x10000000 (256M) instead\n",
+                               memsize);
+                       memsize = 256 << 20;
+               }
                /* If ememsize is set, then set physical_memsize to that */
                physical_memsize = ememsize ? : memsize;
        }
@@ -196,3 +203,9 @@ unsigned platform_maar_init(unsigned num_pairs)
 
        return maar_config(cfg, num_cfg, num_pairs);
 }
+
+phys_addr_t mips_cdmm_phys_base(void)
+{
+       /* This address is "typically unused" */
+       return 0x1fc10000;
+}
index ce02dbd..185e682 100644 (file)
@@ -87,8 +87,10 @@ static void __init estimate_frequencies(void)
 
        /* Initialize counters. */
        start = read_c0_count();
-       if (gic_present)
+       if (gic_present) {
+               gic_start_count();
                gicstart = gic_read_count();
+       }
 
        /* Read counter exactly on falling edge of update flag. */
        while (CMOS_READ(RTC_REG_A) & RTC_UIP);
@@ -115,6 +117,22 @@ void read_persistent_clock(struct timespec *ts)
        ts->tv_nsec = 0;
 }
 
+int get_c0_fdc_int(void)
+{
+       int mips_cpu_fdc_irq;
+
+       if (cpu_has_veic)
+               mips_cpu_fdc_irq = -1;
+       else if (gic_present)
+               mips_cpu_fdc_irq = gic_get_c0_fdc_int();
+       else if (cp0_fdc_irq >= 0)
+               mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
+       else
+               mips_cpu_fdc_irq = -1;
+
+       return mips_cpu_fdc_irq;
+}
+
 int get_c0_perfcount_int(void)
 {
        if (cpu_has_veic) {
index 2ae49e9..ecd71db 100644 (file)
@@ -9,14 +9,11 @@
 # Steven J. Hill <sjhill@mips.com>
 #
 obj-y                          := sead3-lcd.o sead3-display.o sead3-init.o \
-                                  sead3-int.o sead3-mtd.o sead3-net.o \
-                                  sead3-platform.o sead3-reset.o \
+                                  sead3-int.o sead3-platform.o sead3-reset.o \
                                   sead3-setup.o sead3-time.o
 
-obj-y                          += sead3-i2c-dev.o sead3-i2c.o \
-                                  leds-sead3.o sead3-leds.o
+obj-y                          += leds-sead3.o
 
 obj-$(CONFIG_EARLY_PRINTK)     += sead3-console.o
-obj-$(CONFIG_USB_EHCI_HCD)     += sead3-ehci.o
 
 CFLAGS_sead3-setup.o = -I$(src)/../../../scripts/dtc/libfdt
index 3abe47b..c938cee 100644 (file)
@@ -4,6 +4,7 @@
  * for more details.
  *
  * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2015 Imagination Technologies, Inc.
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/io.h>
 
-#define DRVNAME "sead3-led"
-
-static struct platform_device *pdev;
+#include <asm/mips-boards/sead3-addr.h>
 
 static void sead3_pled_set(struct led_classdev *led_cdev,
                enum led_brightness value)
 {
-       pr_debug("sead3_pled_set\n");
-       writel(value, (void __iomem *)0xBF000210);      /* FIXME */
+       writel(value, (void __iomem *)SEAD3_CPLD_P_LED);
 }
 
 static void sead3_fled_set(struct led_classdev *led_cdev,
                enum led_brightness value)
 {
-       pr_debug("sead3_fled_set\n");
-       writel(value, (void __iomem *)0xBF000218);      /* FIXME */
+       writel(value, (void __iomem *)SEAD3_CPLD_F_LED);
 }
 
 static struct led_classdev sead3_pled = {
@@ -69,37 +66,11 @@ static struct platform_driver sead3_led_driver = {
        .probe          = sead3_led_probe,
        .remove         = sead3_led_remove,
        .driver         = {
-               .name           = DRVNAME,
+               .name           = "sead3-led",
        },
 };
 
-static int __init sead3_led_init(void)
-{
-       int ret;
-
-       ret = platform_driver_register(&sead3_led_driver);
-       if (ret < 0)
-               goto out;
-
-       pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
-       if (IS_ERR(pdev)) {
-               ret = PTR_ERR(pdev);
-               platform_driver_unregister(&sead3_led_driver);
-               goto out;
-       }
-
-out:
-       return ret;
-}
-
-static void __exit sead3_led_exit(void)
-{
-       platform_device_unregister(pdev);
-       platform_driver_unregister(&sead3_led_driver);
-}
-
-module_init(sead3_led_init);
-module_exit(sead3_led_exit);
+module_platform_driver(sead3_led_driver);
 
 MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>");
 MODULE_DESCRIPTION("SEAD3 LED driver");
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c
deleted file mode 100644 (file)
index 014dd7b..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/module.h>
-#include <linux/irq.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#include <linux/irqchip/mips-gic.h>
-
-#include <asm/mips-boards/sead3int.h>
-
-struct resource ehci_resources[] = {
-       {
-               .start                  = 0x1b200000,
-               .end                    = 0x1b200fff,
-               .flags                  = IORESOURCE_MEM
-       },
-       {
-               .flags                  = IORESOURCE_IRQ
-       }
-};
-
-u64 sead3_usbdev_dma_mask = DMA_BIT_MASK(32);
-
-static struct platform_device ehci_device = {
-       .name           = "sead3-ehci",
-       .id             = 0,
-       .dev            = {
-               .dma_mask               = &sead3_usbdev_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32)
-       },
-       .num_resources  = ARRAY_SIZE(ehci_resources),
-       .resource       = ehci_resources
-};
-
-static int __init ehci_init(void)
-{
-       if (gic_present)
-               ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI;
-       else
-               ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI;
-       return platform_device_register(&ehci_device);
-}
-
-module_init(ehci_init);
-
-MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("EHCI probe driver for SEAD3");
diff --git a/arch/mips/mti-sead3/sead3-i2c-dev.c b/arch/mips/mti-sead3/sead3-i2c-dev.c
deleted file mode 100644 (file)
index eca0b53..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/i2c.h>
-
-static struct i2c_board_info __initdata sead3_i2c_devices[] = {
-       {
-               I2C_BOARD_INFO("adt7476", 0x2c),
-               .irq = 0,
-       },
-       {
-               I2C_BOARD_INFO("m41t80", 0x68),
-               .irq = 0,
-       },
-};
-
-static int __init sead3_i2c_init(void)
-{
-       int err;
-
-       err = i2c_register_board_info(0, sead3_i2c_devices,
-                                       ARRAY_SIZE(sead3_i2c_devices));
-       if (err < 0)
-               pr_err("sead3-i2c-dev: cannot register board I2C devices\n");
-       return err;
-}
-
-arch_initcall(sead3_i2c_init);
diff --git a/arch/mips/mti-sead3/sead3-i2c-drv.c b/arch/mips/mti-sead3/sead3-i2c-drv.c
deleted file mode 100644 (file)
index 2bebf09..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-
-#define PIC32_I2CxCON          0x0000
-#define         PIC32_I2CCON_ON        (1<<15)
-#define         PIC32_I2CCON_ACKDT     (1<<5)
-#define         PIC32_I2CCON_ACKEN     (1<<4)
-#define         PIC32_I2CCON_RCEN      (1<<3)
-#define         PIC32_I2CCON_PEN       (1<<2)
-#define         PIC32_I2CCON_RSEN      (1<<1)
-#define         PIC32_I2CCON_SEN       (1<<0)
-#define PIC32_I2CxCONCLR       0x0004
-#define PIC32_I2CxCONSET       0x0008
-#define PIC32_I2CxSTAT         0x0010
-#define PIC32_I2CxSTATCLR      0x0014
-#define         PIC32_I2CSTAT_ACKSTAT  (1<<15)
-#define         PIC32_I2CSTAT_TRSTAT   (1<<14)
-#define         PIC32_I2CSTAT_BCL      (1<<10)
-#define         PIC32_I2CSTAT_IWCOL    (1<<7)
-#define         PIC32_I2CSTAT_I2COV    (1<<6)
-#define PIC32_I2CxBRG          0x0040
-#define PIC32_I2CxTRN          0x0050
-#define PIC32_I2CxRCV          0x0060
-
-static DEFINE_SPINLOCK(pic32_bus_lock);
-
-static void __iomem *bus_xfer  = (void __iomem *)0xbf000600;
-static void __iomem *bus_status = (void __iomem *)0xbf000060;
-
-#define DELAY() udelay(100)
-
-static inline unsigned int ioready(void)
-{
-       return readl(bus_status) & 1;
-}
-
-static inline void wait_ioready(void)
-{
-       do { } while (!ioready());
-}
-
-static inline void wait_ioclear(void)
-{
-       do { } while (ioready());
-}
-
-static inline void check_ioclear(void)
-{
-       if (ioready()) {
-               do {
-                       (void) readl(bus_xfer);
-                       DELAY();
-               } while (ioready());
-       }
-}
-
-static u32 pic32_bus_readl(u32 reg)
-{
-       unsigned long flags;
-       u32 status, val;
-
-       spin_lock_irqsave(&pic32_bus_lock, flags);
-
-       check_ioclear();
-       writel((0x01 << 24) | (reg & 0x00ffffff), bus_xfer);
-       DELAY();
-       wait_ioready();
-       status = readl(bus_xfer);
-       DELAY();
-       val = readl(bus_xfer);
-       wait_ioclear();
-
-       spin_unlock_irqrestore(&pic32_bus_lock, flags);
-
-       return val;
-}
-
-static void pic32_bus_writel(u32 val, u32 reg)
-{
-       unsigned long flags;
-       u32 status;
-
-       spin_lock_irqsave(&pic32_bus_lock, flags);
-
-       check_ioclear();
-       writel((0x10 << 24) | (reg & 0x00ffffff), bus_xfer);
-       DELAY();
-       writel(val, bus_xfer);
-       DELAY();
-       wait_ioready();
-       status = readl(bus_xfer);
-       wait_ioclear();
-
-       spin_unlock_irqrestore(&pic32_bus_lock, flags);
-}
-
-struct pic32_i2c_platform_data {
-       u32     base;
-       struct i2c_adapter adap;
-       u32     xfer_timeout;
-       u32     ack_timeout;
-       u32     ctl_timeout;
-};
-
-static inline void pic32_i2c_start(struct pic32_i2c_platform_data *adap)
-{
-       pic32_bus_writel(PIC32_I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
-}
-
-static inline void pic32_i2c_stop(struct pic32_i2c_platform_data *adap)
-{
-       pic32_bus_writel(PIC32_I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
-}
-
-static inline void pic32_i2c_ack(struct pic32_i2c_platform_data *adap)
-{
-       pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
-       pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
-}
-
-static inline void pic32_i2c_nack(struct pic32_i2c_platform_data *adap)
-{
-       pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
-       pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
-}
-
-static inline int pic32_i2c_idle(struct pic32_i2c_platform_data *adap)
-{
-       int i;
-
-       for (i = 0; i < adap->ctl_timeout; i++) {
-               if (((pic32_bus_readl(adap->base + PIC32_I2CxCON) &
-                     (PIC32_I2CCON_ACKEN | PIC32_I2CCON_RCEN |
-                      PIC32_I2CCON_PEN | PIC32_I2CCON_RSEN |
-                      PIC32_I2CCON_SEN)) == 0) &&
-                   ((pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
-                     (PIC32_I2CSTAT_TRSTAT)) == 0))
-                       return 0;
-               udelay(1);
-       }
-       return -ETIMEDOUT;
-}
-
-static inline u32 pic32_i2c_master_write(struct pic32_i2c_platform_data *adap,
-               u32 byte)
-{
-       pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
-       return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
-                       PIC32_I2CSTAT_IWCOL;
-}
-
-static inline u32 pic32_i2c_master_read(struct pic32_i2c_platform_data *adap)
-{
-       pic32_bus_writel(PIC32_I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
-       while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & PIC32_I2CCON_RCEN)
-               ;
-       pic32_bus_writel(PIC32_I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
-       return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
-}
-
-static int pic32_i2c_address(struct pic32_i2c_platform_data *adap,
-               unsigned int addr, int rd)
-{
-       pic32_i2c_idle(adap);
-       pic32_i2c_start(adap);
-       pic32_i2c_idle(adap);
-
-       addr <<= 1;
-       if (rd)
-               addr |= 1;
-
-       if (pic32_i2c_master_write(adap, addr))
-               return -EIO;
-       pic32_i2c_idle(adap);
-       if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
-                       PIC32_I2CSTAT_ACKSTAT)
-               return -EIO;
-       return 0;
-}
-
-static int sead3_i2c_read(struct pic32_i2c_platform_data *adap,
-               unsigned char *buf, unsigned int len)
-{
-       u32 data;
-       int i;
-
-       i = 0;
-       while (i < len) {
-               data = pic32_i2c_master_read(adap);
-               buf[i++] = data;
-               if (i < len)
-                       pic32_i2c_ack(adap);
-               else
-                       pic32_i2c_nack(adap);
-       }
-
-       pic32_i2c_stop(adap);
-       pic32_i2c_idle(adap);
-       return 0;
-}
-
-static int sead3_i2c_write(struct pic32_i2c_platform_data *adap,
-               unsigned char *buf, unsigned int len)
-{
-       int i;
-       u32 data;
-
-       i = 0;
-       while (i < len) {
-               data = buf[i];
-               if (pic32_i2c_master_write(adap, data))
-                       return -EIO;
-               pic32_i2c_idle(adap);
-               if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
-                                       PIC32_I2CSTAT_ACKSTAT)
-                       return -EIO;
-               i++;
-       }
-
-       pic32_i2c_stop(adap);
-       pic32_i2c_idle(adap);
-       return 0;
-}
-
-static int sead3_pic32_platform_xfer(struct i2c_adapter *i2c_adap,
-               struct i2c_msg *msgs, int num)
-{
-       struct pic32_i2c_platform_data *adap = i2c_adap->algo_data;
-       struct i2c_msg *p;
-       int i, err = 0;
-
-       for (i = 0; i < num; i++) {
-#define __BUFSIZE 80
-               int ii;
-               static char buf[__BUFSIZE];
-               char *b = buf;
-
-               p = &msgs[i];
-               b += sprintf(buf, " [%d bytes]", p->len);
-               if ((p->flags & I2C_M_RD) == 0) {
-                       for (ii = 0; ii < p->len; ii++) {
-                               if (b < &buf[__BUFSIZE-4]) {
-                                       b += sprintf(b, " %02x", p->buf[ii]);
-                               } else {
-                                       strcat(b, "...");
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       for (i = 0; !err && i < num; i++) {
-               p = &msgs[i];
-               err = pic32_i2c_address(adap, p->addr, p->flags & I2C_M_RD);
-               if (err || !p->len)
-                       continue;
-               if (p->flags & I2C_M_RD)
-                       err = sead3_i2c_read(adap, p->buf, p->len);
-               else
-                       err = sead3_i2c_write(adap, p->buf, p->len);
-       }
-
-       /* Return the number of messages processed, or the error code. */
-       if (err == 0)
-               err = num;
-
-       return err;
-}
-
-static u32 sead3_pic32_platform_func(struct i2c_adapter *adap)
-{
-       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm sead3_platform_algo = {
-       .master_xfer    = sead3_pic32_platform_xfer,
-       .functionality  = sead3_pic32_platform_func,
-};
-
-static void sead3_i2c_platform_setup(struct pic32_i2c_platform_data *priv)
-{
-       pic32_bus_writel(500, priv->base + PIC32_I2CxBRG);
-       pic32_bus_writel(PIC32_I2CCON_ON, priv->base + PIC32_I2CxCONCLR);
-       pic32_bus_writel(PIC32_I2CCON_ON, priv->base + PIC32_I2CxCONSET);
-       pic32_bus_writel(PIC32_I2CSTAT_BCL | PIC32_I2CSTAT_IWCOL,
-               priv->base + PIC32_I2CxSTATCLR);
-}
-
-static int sead3_i2c_platform_probe(struct platform_device *pdev)
-{
-       struct pic32_i2c_platform_data *priv;
-       struct resource *r;
-       int ret;
-
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!r) {
-               ret = -ENODEV;
-               goto out;
-       }
-
-       priv = kzalloc(sizeof(struct pic32_i2c_platform_data), GFP_KERNEL);
-       if (!priv) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       priv->base = r->start;
-       if (!priv->base) {
-               ret = -EBUSY;
-               goto out_mem;
-       }
-
-       priv->xfer_timeout = 200;
-       priv->ack_timeout = 200;
-       priv->ctl_timeout = 200;
-
-       priv->adap.nr = pdev->id;
-       priv->adap.algo = &sead3_platform_algo;
-       priv->adap.algo_data = priv;
-       priv->adap.dev.parent = &pdev->dev;
-       strlcpy(priv->adap.name, "SEAD3 PIC32", sizeof(priv->adap.name));
-
-       sead3_i2c_platform_setup(priv);
-
-       ret = i2c_add_numbered_adapter(&priv->adap);
-       if (ret == 0) {
-               platform_set_drvdata(pdev, priv);
-               return 0;
-       }
-
-out_mem:
-       kfree(priv);
-out:
-       return ret;
-}
-
-static int sead3_i2c_platform_remove(struct platform_device *pdev)
-{
-       struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
-
-       platform_set_drvdata(pdev, NULL);
-       i2c_del_adapter(&priv->adap);
-       kfree(priv);
-       return 0;
-}
-
-#ifdef CONFIG_PM
-static int sead3_i2c_platform_suspend(struct platform_device *pdev,
-               pm_message_t state)
-{
-       dev_dbg(&pdev->dev, "i2c_platform_disable\n");
-       return 0;
-}
-
-static int sead3_i2c_platform_resume(struct platform_device *pdev)
-{
-       struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
-
-       dev_dbg(&pdev->dev, "sead3_i2c_platform_setup\n");
-       sead3_i2c_platform_setup(priv);
-
-       return 0;
-}
-#else
-#define sead3_i2c_platform_suspend     NULL
-#define sead3_i2c_platform_resume      NULL
-#endif
-
-static struct platform_driver sead3_i2c_platform_driver = {
-       .driver = {
-               .name   = "sead3-i2c",
-       },
-       .probe          = sead3_i2c_platform_probe,
-       .remove         = sead3_i2c_platform_remove,
-       .suspend        = sead3_i2c_platform_suspend,
-       .resume         = sead3_i2c_platform_resume,
-};
-
-static int __init sead3_i2c_platform_init(void)
-{
-       return platform_driver_register(&sead3_i2c_platform_driver);
-}
-module_init(sead3_i2c_platform_init);
-
-static void __exit sead3_i2c_platform_exit(void)
-{
-       platform_driver_unregister(&sead3_i2c_platform_driver);
-}
-module_exit(sead3_i2c_platform_exit);
-
-MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
-MODULE_DESCRIPTION("SEAD3 PIC32 I2C driver");
-MODULE_LICENSE("GPL");
diff --git a/arch/mips/mti-sead3/sead3-i2c.c b/arch/mips/mti-sead3/sead3-i2c.c
deleted file mode 100644 (file)
index 795ae83..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-struct resource sead3_i2c_resources[] = {
-       {
-               .start  = 0x805200,
-               .end    = 0x8053ff,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device sead3_i2c_device = {
-       .name           = "sead3-i2c",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(sead3_i2c_resources),
-       .resource       = sead3_i2c_resources,
-};
-
-static int __init sead3_i2c_init(void)
-{
-       return platform_device_register(&sead3_i2c_device);
-}
-
-device_initcall(sead3_i2c_init);
index bfbd17b..3572ea3 100644 (file)
@@ -147,6 +147,6 @@ void __init prom_init(void)
 #endif
 }
 
-void prom_free_prom_memory(void)
+void __init prom_free_prom_memory(void)
 {
 }
diff --git a/arch/mips/mti-sead3/sead3-leds.c b/arch/mips/mti-sead3/sead3-leds.c
deleted file mode 100644 (file)
index c427c57..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/leds.h>
-#include <linux/platform_device.h>
-
-#define LEDFLAGS(bits, shift)          \
-       ((bits << 8) | (shift << 8))
-
-#define LEDBITS(id, shift, bits)       \
-       .name = id #shift,              \
-       .flags = LEDFLAGS(bits, shift)
-
-struct led_info led_data_info[] = {
-       { LEDBITS("bit", 0, 1) },
-       { LEDBITS("bit", 1, 1) },
-       { LEDBITS("bit", 2, 1) },
-       { LEDBITS("bit", 3, 1) },
-       { LEDBITS("bit", 4, 1) },
-       { LEDBITS("bit", 5, 1) },
-       { LEDBITS("bit", 6, 1) },
-       { LEDBITS("bit", 7, 1) },
-       { LEDBITS("all", 0, 8) },
-};
-
-static struct led_platform_data led_data = {
-       .num_leds       = ARRAY_SIZE(led_data_info),
-       .leds           = led_data_info
-};
-
-static struct resource pled_resources[] = {
-       {
-               .start  = 0x1f000210,
-               .end    = 0x1f000217,
-               .flags  = IORESOURCE_MEM
-       }
-};
-
-static struct platform_device pled_device = {
-       .name                   = "sead3::pled",
-       .id                     = 0,
-       .dev                    = {
-               .platform_data  = &led_data,
-       },
-       .num_resources          = ARRAY_SIZE(pled_resources),
-       .resource               = pled_resources
-};
-
-
-static struct resource fled_resources[] = {
-       {
-               .start                  = 0x1f000218,
-               .end                    = 0x1f00021f,
-               .flags                  = IORESOURCE_MEM
-       }
-};
-
-static struct platform_device fled_device = {
-       .name                   = "sead3::fled",
-       .id                     = 0,
-       .dev                    = {
-               .platform_data  = &led_data,
-       },
-       .num_resources          = ARRAY_SIZE(fled_resources),
-       .resource               = fled_resources
-};
-
-static int __init led_init(void)
-{
-       platform_device_register(&pled_device);
-       return platform_device_register(&fled_device);
-}
-
-device_initcall(led_init);
diff --git a/arch/mips/mti-sead3/sead3-mtd.c b/arch/mips/mti-sead3/sead3-mtd.c
deleted file mode 100644 (file)
index f9c890d..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-
-static struct mtd_partition sead3_mtd_partitions[] = {
-       {
-               .name =         "User FS",
-               .offset =       0x00000000,
-               .size =         0x01fc0000,
-       }, {
-               .name =         "Board Config",
-               .offset =       0x01fc0000,
-               .size =         0x00040000,
-               .mask_flags =   MTD_WRITEABLE
-       },
-};
-
-static struct physmap_flash_data sead3_flash_data = {
-       .width          = 4,
-       .nr_parts       = ARRAY_SIZE(sead3_mtd_partitions),
-       .parts          = sead3_mtd_partitions
-};
-
-static struct resource sead3_flash_resource = {
-       .start          = 0x1c000000,
-       .end            = 0x1dffffff,
-       .flags          = IORESOURCE_MEM
-};
-
-static struct platform_device sead3_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &sead3_flash_data,
-       },
-       .num_resources  = 1,
-       .resource       = &sead3_flash_resource,
-};
-
-static int __init sead3_mtd_init(void)
-{
-       platform_device_register(&sead3_flash);
-
-       return 0;
-}
-device_initcall(sead3_mtd_init);
diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c
deleted file mode 100644 (file)
index 46176b8..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
- */
-#include <linux/module.h>
-#include <linux/irq.h>
-#include <linux/irqchip/mips-gic.h>
-#include <linux/platform_device.h>
-#include <linux/smsc911x.h>
-
-#include <asm/mips-boards/sead3int.h>
-
-static struct smsc911x_platform_config sead3_smsc911x_data = {
-       .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-       .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
-       .flags  = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
-       .phy_interface = PHY_INTERFACE_MODE_MII,
-};
-
-struct resource sead3_net_resources[] = {
-       {
-               .start                  = 0x1f010000,
-               .end                    = 0x1f01ffff,
-               .flags                  = IORESOURCE_MEM
-       },
-       {
-               .flags                  = IORESOURCE_IRQ
-       }
-};
-
-static struct platform_device sead3_net_device = {
-       .name                   = "smsc911x",
-       .id                     = 0,
-       .dev                    = {
-               .platform_data  = &sead3_smsc911x_data,
-       },
-       .num_resources          = ARRAY_SIZE(sead3_net_resources),
-       .resource               = sead3_net_resources
-};
-
-static int __init sead3_net_init(void)
-{
-       if (gic_present)
-               sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET;
-       else
-               sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET;
-       return platform_device_register(&sead3_net_device);
-}
-
-module_init(sead3_net_init);
-
-MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Network probe driver for SEAD-3");
index 53ee6f1..73b73ef 100644 (file)
@@ -5,10 +5,15 @@
  *
  * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
  */
-#include <linux/module.h>
+#include <linux/dma-mapping.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 #include <linux/irqchip/mips-gic.h>
+#include <linux/leds.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
 #include <linux/serial_8250.h>
+#include <linux/smsc911x.h>
 
 #include <asm/mips-boards/sead3int.h>
 
@@ -36,20 +41,183 @@ static struct platform_device uart8250_device = {
        },
 };
 
-static int __init uart8250_init(void)
+static struct smsc911x_platform_config sead3_smsc911x_data = {
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+       .flags          = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+};
+
+static struct resource sead3_net_resources[] = {
+       {
+               .start                  = 0x1f010000,
+               .end                    = 0x1f01ffff,
+               .flags                  = IORESOURCE_MEM
+       }, {
+               .flags                  = IORESOURCE_IRQ
+       }
+};
+
+static struct platform_device sead3_net_device = {
+       .name                   = "smsc911x",
+       .id                     = 0,
+       .dev                    = {
+               .platform_data  = &sead3_smsc911x_data,
+       },
+       .num_resources          = ARRAY_SIZE(sead3_net_resources),
+       .resource               = sead3_net_resources
+};
+
+static struct mtd_partition sead3_mtd_partitions[] = {
+       {
+               .name =         "User FS",
+               .offset =       0x00000000,
+               .size =         0x01fc0000,
+       }, {
+               .name =         "Board Config",
+               .offset =       0x01fc0000,
+               .size =         0x00040000,
+               .mask_flags =   MTD_WRITEABLE
+       },
+};
+
+static struct physmap_flash_data sead3_flash_data = {
+       .width          = 4,
+       .nr_parts       = ARRAY_SIZE(sead3_mtd_partitions),
+       .parts          = sead3_mtd_partitions
+};
+
+static struct resource sead3_flash_resource = {
+       .start          = 0x1c000000,
+       .end            = 0x1dffffff,
+       .flags          = IORESOURCE_MEM
+};
+
+static struct platform_device sead3_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &sead3_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &sead3_flash_resource,
+};
+
+#define LEDFLAGS(bits, shift)          \
+       ((bits << 8) | (shift << 8))
+
+#define LEDBITS(id, shift, bits)       \
+       .name = id #shift,              \
+       .flags = LEDFLAGS(bits, shift)
+
+static struct led_info led_data_info[] = {
+       { LEDBITS("bit", 0, 1) },
+       { LEDBITS("bit", 1, 1) },
+       { LEDBITS("bit", 2, 1) },
+       { LEDBITS("bit", 3, 1) },
+       { LEDBITS("bit", 4, 1) },
+       { LEDBITS("bit", 5, 1) },
+       { LEDBITS("bit", 6, 1) },
+       { LEDBITS("bit", 7, 1) },
+       { LEDBITS("all", 0, 8) },
+};
+
+static struct led_platform_data led_data = {
+       .num_leds       = ARRAY_SIZE(led_data_info),
+       .leds           = led_data_info
+};
+
+static struct resource pled_resources[] = {
+       {
+               .start  = 0x1f000210,
+               .end    = 0x1f000217,
+               .flags  = IORESOURCE_MEM
+       }
+};
+
+static struct platform_device pled_device = {
+       .name                   = "sead3::pled",
+       .id                     = 0,
+       .dev                    = {
+               .platform_data  = &led_data,
+       },
+       .num_resources          = ARRAY_SIZE(pled_resources),
+       .resource               = pled_resources
+};
+
+
+static struct resource fled_resources[] = {
+       {
+               .start                  = 0x1f000218,
+               .end                    = 0x1f00021f,
+               .flags                  = IORESOURCE_MEM
+       }
+};
+
+static struct platform_device fled_device = {
+       .name                   = "sead3::fled",
+       .id                     = 0,
+       .dev                    = {
+               .platform_data  = &led_data,
+       },
+       .num_resources          = ARRAY_SIZE(fled_resources),
+       .resource               = fled_resources
+};
+
+static struct platform_device sead3_led_device = {
+        .name   = "sead3-led",
+        .id     = -1,
+};
+
+static struct resource ehci_resources[] = {
+       {
+               .start                  = 0x1b200000,
+               .end                    = 0x1b200fff,
+               .flags                  = IORESOURCE_MEM
+       }, {
+               .flags                  = IORESOURCE_IRQ
+       }
+};
+
+static u64 sead3_usbdev_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ehci_device = {
+       .name           = "sead3-ehci",
+       .id             = 0,
+       .dev            = {
+               .dma_mask               = &sead3_usbdev_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32)
+       },
+       .num_resources  = ARRAY_SIZE(ehci_resources),
+       .resource       = ehci_resources
+};
+
+static struct platform_device *sead3_platform_devices[] __initdata = {
+       &uart8250_device,
+       &sead3_flash,
+       &pled_device,
+       &fled_device,
+       &sead3_led_device,
+       &ehci_device,
+       &sead3_net_device,
+};
+
+static int __init sead3_platforms_device_init(void)
 {
        if (gic_present) {
                uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0;
                uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1;
+               ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI;
+               sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET;
        } else {
                uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0;
                uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1;
+               ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI;
+               sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET;
        }
-       return platform_device_register(&uart8250_device);
-}
 
-module_init(uart8250_init);
+       return platform_add_devices(sead3_platform_devices,
+                                   ARRAY_SIZE(sead3_platform_devices));
+}
 
-MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("8250 UART probe driver for SEAD3");
+device_initcall(sead3_platforms_device_init);
index 0823321..fb00606 100644 (file)
@@ -41,6 +41,15 @@ config DT_XLP_GVP
          pointer to the kernel.  The corresponding DTS file is at
          arch/mips/netlogic/dts/xlp_gvp.dts
 
+config DT_XLP_RVP
+       bool "Built-in device tree for XLP RVP boards"
+       default y
+       help
+         Add an FDT blob for XLP RVP board into the kernel.
+         This DTB will be used if the firmware does not pass in a DTB
+         pointer to the kernel.  The corresponding DTS file is at
+         arch/mips/netlogic/dts/xlp_rvp.dts
+
 config NLM_MULTINODE
        bool "Support for multi-chip boards"
        depends on NLM_XLP_BOARD
index c100b9a..5f5d18b 100644 (file)
@@ -230,16 +230,16 @@ static void nlm_init_node_irqs(int node)
        }
 }
 
-void nlm_smp_irq_init(int hwcpuid)
+void nlm_smp_irq_init(int hwtid)
 {
-       int node, cpu;
+       int cpu, node;
 
-       node = nlm_cpuid_to_node(hwcpuid);
-       cpu  = hwcpuid % nlm_threads_per_node();
+       cpu = hwtid % nlm_threads_per_node();
+       node = hwtid / nlm_threads_per_node();
 
        if (cpu == 0 && node != 0)
                nlm_init_node_irqs(node);
-       write_c0_eimr(nlm_current_node()->irqmask);
+       write_c0_eimr(nlm_get_node(node)->irqmask);
 }
 
 asmlinkage void plat_irq_dispatch(void)
index 701c4bc..edbab9b 100644 (file)
@@ -60,7 +60,7 @@
        li      t0, LSU_DEFEATURE
        mfcr    t1, t0
 
-       lui     t2, 0xc080      /* SUE, Enable Unaligned Access, L2HPE */
+       lui     t2, 0x4080      /* Enable Unaligned Access, L2HPE */
        or      t1, t1, t2
        mtcr    t1, t0
 
@@ -235,6 +235,26 @@ EXPORT(nlm_boot_siblings)
        mfc0    v0, CP0_EBASE, 1
        andi    v0, 0x3ff               /* v0 <- node/core */
 
+       /*
+        * Errata: to avoid potential live lock, setup IFU_BRUB_RESERVE
+        * when running 4 threads per core
+        */
+       andi    v1, v0, 0x3             /* v1 <- thread id */
+       bnez    v1, 2f
+       nop
+
+       /* thread 0 of each core. */
+       li      t0, CKSEG1ADDR(RESET_DATA_PHYS)
+       lw      t1, BOOT_THREAD_MODE(t0)        /* t1 <- thread mode */
+       subu    t1, 0x3                         /* 4-thread per core mode? */
+       bnez    t1, 2f
+       nop
+
+       li      t0, IFU_BRUB_RESERVE
+       li      t1, 0x55
+       mtcr    t1, t0
+       _ehb
+2:
        beqz    v0, 4f          /* boot cpu (cpuid == 0)? */
        nop
 
index e743bdd..dc3e327 100644 (file)
 
 void nlm_send_ipi_single(int logical_cpu, unsigned int action)
 {
-       int cpu, node;
+       unsigned int hwtid;
        uint64_t picbase;
 
-       cpu = cpu_logical_map(logical_cpu);
-       node = nlm_cpuid_to_node(cpu);
-       picbase = nlm_get_node(node)->picbase;
+       /* node id is part of hwtid, and needed for send_ipi */
+       hwtid = cpu_logical_map(logical_cpu);
+       picbase = nlm_get_node(nlm_hwtid_to_node(hwtid))->picbase;
 
        if (action & SMP_CALL_FUNCTION)
-               nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_FUNCTION, 0);
+               nlm_pic_send_ipi(picbase, hwtid, IRQ_IPI_SMP_FUNCTION, 0);
        if (action & SMP_RESCHEDULE_YOURSELF)
-               nlm_pic_send_ipi(picbase, cpu, IRQ_IPI_SMP_RESCHEDULE, 0);
+               nlm_pic_send_ipi(picbase, hwtid, IRQ_IPI_SMP_RESCHEDULE, 0);
 }
 
 void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
@@ -120,6 +120,7 @@ static void nlm_init_secondary(void)
 
        hwtid = hard_smp_processor_id();
        current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE;
+       current_cpu_data.package = nlm_nodeid();
        nlm_percpu_init(hwtid);
        nlm_smp_irq_init(hwtid);
 }
@@ -145,16 +146,18 @@ static cpumask_t phys_cpu_present_mask;
 
 void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
 {
-       int cpu, node;
+       uint64_t picbase;
+       int hwtid;
+
+       hwtid = cpu_logical_map(logical_cpu);
+       picbase = nlm_get_node(nlm_hwtid_to_node(hwtid))->picbase;
 
-       cpu = cpu_logical_map(logical_cpu);
-       node = nlm_cpuid_to_node(logical_cpu);
        nlm_next_sp = (unsigned long)__KSTK_TOS(idle);
        nlm_next_gp = (unsigned long)task_thread_info(idle);
 
        /* barrier for sp/gp store above */
        __sync();
-       nlm_pic_send_ipi(nlm_get_node(node)->picbase, cpu, 1, 1);  /* NMI */
+       nlm_pic_send_ipi(picbase, hwtid, 1, 1);  /* NMI */
 }
 
 void __init nlm_smp_setup(void)
@@ -182,7 +185,7 @@ void __init nlm_smp_setup(void)
                        __cpu_number_map[i] = num_cpus;
                        __cpu_logical_map[num_cpus] = i;
                        set_cpu_possible(num_cpus, true);
-                       node = nlm_cpuid_to_node(i);
+                       node = nlm_hwtid_to_node(i);
                        cpumask_set_cpu(num_cpus, &nlm_get_node(node)->cpumask);
                        ++num_cpus;
                }
index 0c0a1a6..5873c83 100644 (file)
@@ -40,7 +40,6 @@
 #include <asm/netlogic/interrupt.h>
 #include <asm/netlogic/common.h>
 #include <asm/netlogic/haldefs.h>
-#include <asm/netlogic/common.h>
 
 #if defined(CONFIG_CPU_XLP)
 #include <asm/netlogic/xlp-hal/iomap.h>
index c83dbf3..7b066a4 100644 (file)
@@ -203,6 +203,7 @@ static u8 read_phy_reg(u64 regbase, u32 addr, u32 physel)
 static void config_sata_phy(u64 regbase)
 {
        u32 port, i, reg;
+       u8 val;
 
        for (port = 0; port < 2; port++) {
                for (i = 0, reg = RXCDRCALFOSC0; reg <= CALDUTY; reg++, i++)
@@ -210,6 +211,18 @@ static void config_sata_phy(u64 regbase)
 
                for (i = 0, reg = RXDPIF; reg <= PPMDRIFTMAX_HI; reg++, i++)
                        write_phy_reg(regbase, reg, port, sata_phy_config2[i]);
+
+               /* Fix for PHY link up failures at lower temperatures */
+               write_phy_reg(regbase, 0x800F, port, 0x1f);
+
+               val = read_phy_reg(regbase, 0x0029, port);
+               write_phy_reg(regbase, 0x0029, port, val | (0x7 << 1));
+
+               val = read_phy_reg(regbase, 0x0056, port);
+               write_phy_reg(regbase, 0x0056, port, val & ~(1 << 3));
+
+               val = read_phy_reg(regbase, 0x0018, port);
+               write_phy_reg(regbase, 0x0018, port, val & ~(0x7 << 0));
        }
 }
 
index a9d0fae..92be1a3 100644 (file)
@@ -151,7 +151,7 @@ static void nlm_sata_firmware_init(int node)
 static int __init nlm_ahci_init(void)
 {
        int node = 0;
-       int chip = read_c0_prid() & PRID_REV_MASK;
+       int chip = read_c0_prid() & PRID_IMP_MASK;
 
        if (chip == PRID_IMP_NETLOGIC_XLP3XX)
                nlm_sata_firmware_init(node);
index 7cc4603..a625bdb 100644 (file)
 
 #include <asm/prom.h>
 
-extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[],
-       __dtb_xlp_fvp_begin[], __dtb_xlp_gvp_begin[];
+extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[], __dtb_xlp_fvp_begin[],
+       __dtb_xlp_gvp_begin[], __dtb_xlp_rvp_begin[];
 static void *xlp_fdt_blob;
 
 void __init *xlp_dt_init(void *fdtp)
 {
        if (!fdtp) {
                switch (current_cpu_data.processor_id & PRID_IMP_MASK) {
+#ifdef CONFIG_DT_XLP_RVP
+               case PRID_IMP_NETLOGIC_XLP5XX:
+                       fdtp = __dtb_xlp_rvp_begin;
+                       break;
+#endif
 #ifdef CONFIG_DT_XLP_GVP
                case PRID_IMP_NETLOGIC_XLP9XX:
-               case PRID_IMP_NETLOGIC_XLP5XX:
                        fdtp = __dtb_xlp_gvp_begin;
                        break;
 #endif
index bc24beb..a8f4144 100644 (file)
@@ -71,10 +71,20 @@ static int xlp9xx_irq_to_irt(int irq)
        switch (irq) {
        case PIC_GPIO_IRQ:
                return 12;
+       case PIC_I2C_0_IRQ:
+               return 125;
+       case PIC_I2C_1_IRQ:
+               return 126;
+       case PIC_I2C_2_IRQ:
+               return 127;
+       case PIC_I2C_3_IRQ:
+               return 128;
        case PIC_9XX_XHCI_0_IRQ:
                return 114;
        case PIC_9XX_XHCI_1_IRQ:
                return 115;
+       case PIC_9XX_XHCI_2_IRQ:
+               return 116;
        case PIC_UART_0_IRQ:
                return 133;
        case PIC_UART_1_IRQ:
@@ -170,16 +180,23 @@ static int xlp_irq_to_irt(int irq)
        }
 
        if (devoff != 0) {
+               uint32_t val;
+
                pcibase = nlm_pcicfg_base(devoff);
-               irt = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG) & 0xffff;
-               /* HW weirdness, I2C IRT entry has to be fixed up */
-               switch (irq) {
-               case PIC_I2C_1_IRQ:
-                       irt = irt + 1; break;
-               case PIC_I2C_2_IRQ:
-                       irt = irt + 2; break;
-               case PIC_I2C_3_IRQ:
-                       irt = irt + 3; break;
+               val = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG);
+               if (val == 0xffffffff) {
+                       irt = -1;
+               } else {
+                       irt = val & 0xffff;
+                       /* HW weirdness, I2C IRT entry has to be fixed up */
+                       switch (irq) {
+                       case PIC_I2C_1_IRQ:
+                               irt = irt + 1; break;
+                       case PIC_I2C_2_IRQ:
+                               irt = irt + 2; break;
+                       case PIC_I2C_3_IRQ:
+                               irt = irt + 3; break;
+                       }
                }
        } else if (irq >= PIC_PCIE_LINK_LEGACY_IRQ(0) &&
                        irq <= PIC_PCIE_LINK_LEGACY_IRQ(3)) {
@@ -325,7 +342,7 @@ static unsigned int nlm_xlp2_get_pic_frequency(int node)
        /* Find the clock source PLL device for PIC */
        if (cpu_xlp9xx) {
                reg_select = nlm_read_sys_reg(clockbase,
-                               SYS_9XX_CLK_DEV_SEL) & 0x3;
+                               SYS_9XX_CLK_DEV_SEL_REG) & 0x3;
                switch (reg_select) {
                case 0:
                        ctrl_val0 = nlm_read_sys_reg(clockbase,
@@ -354,7 +371,7 @@ static unsigned int nlm_xlp2_get_pic_frequency(int node)
                }
        } else {
                reg_select = (nlm_read_sys_reg(sysbase,
-                                       SYS_CLK_DEV_SEL) >> 22) & 0x3;
+                                       SYS_CLK_DEV_SEL_REG) >> 22) & 0x3;
                switch (reg_select) {
                case 0:
                        ctrl_val0 = nlm_read_sys_reg(sysbase,
@@ -410,7 +427,7 @@ static unsigned int nlm_xlp2_get_pic_frequency(int node)
 
        fdiv = fdiv/(1 << 13);
        pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv;
-       pll_out_freq_den = (1 << vco_post_div) * pll_post_div * 3;
+       pll_out_freq_den = (1 << vco_post_div) * pll_post_div * ref_div;
 
        if (pll_out_freq_den > 0)
                do_div(pll_out_freq_num, pll_out_freq_den);
@@ -418,10 +435,10 @@ static unsigned int nlm_xlp2_get_pic_frequency(int node)
        /* PIC post divider, which happens after PLL */
        if (cpu_xlp9xx)
                pic_div = nlm_read_sys_reg(clockbase,
-                               SYS_9XX_CLK_DEV_DIV) & 0x3;
+                               SYS_9XX_CLK_DEV_DIV_REG) & 0x3;
        else
                pic_div = (nlm_read_sys_reg(sysbase,
-                                       SYS_CLK_DEV_DIV) >> 22) & 0x3;
+                                       SYS_CLK_DEV_DIV_REG) >> 22) & 0x3;
        do_div(pll_out_freq_num, 1 << pic_div);
 
        return pll_out_freq_num;
@@ -442,19 +459,21 @@ unsigned int nlm_get_cpu_frequency(void)
 
 /*
  * Fills upto 8 pairs of entries containing the DRAM map of a node
- * if n < 0, get dram map for all nodes
+ * if node < 0, get dram map for all nodes
  */
-int xlp_get_dram_map(int n, uint64_t *dram_map)
+int nlm_get_dram_map(int node, uint64_t *dram_map, int nentries)
 {
        uint64_t bridgebase, base, lim;
        uint32_t val;
        unsigned int barreg, limreg, xlatreg;
-       int i, node, rv;
+       int i, n, rv;
 
        /* Look only at mapping on Node 0, we don't handle crazy configs */
        bridgebase = nlm_get_bridge_regbase(0);
        rv = 0;
        for (i = 0; i < 8; i++) {
+               if (rv + 1 >= nentries)
+                       break;
                if (cpu_is_xlp9xx()) {
                        barreg = BRIDGE_9XX_DRAM_BAR(i);
                        limreg = BRIDGE_9XX_DRAM_LIMIT(i);
@@ -464,10 +483,10 @@ int xlp_get_dram_map(int n, uint64_t *dram_map)
                        limreg = BRIDGE_DRAM_LIMIT(i);
                        xlatreg = BRIDGE_DRAM_NODE_TRANSLN(i);
                }
-               if (n >= 0) {
+               if (node >= 0) {
                        /* node specified, get node mapping of BAR */
                        val = nlm_read_bridge_reg(bridgebase, xlatreg);
-                       node = (val >> 1) & 0x3;
+                       n = (val >> 1) & 0x3;
                        if (n != node)
                                continue;
                }
index 4fdd9fd..f743fd9 100644 (file)
@@ -51,7 +51,6 @@ uint64_t nlm_io_base;
 struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
 cpumask_t nlm_cpumask = CPU_MASK_CPU0;
 unsigned int nlm_threads_per_core;
-unsigned int xlp_cores_per_node;
 
 static void nlm_linux_exit(void)
 {
@@ -82,7 +81,7 @@ static void __init xlp_init_mem_from_bars(void)
        uint64_t map[16];
        int i, n;
 
-       n = xlp_get_dram_map(-1, map);  /* -1: info for all nodes */
+       n = nlm_get_dram_map(-1, map, ARRAY_SIZE(map)); /* -1 : all nodes */
        for (i = 0; i < n; i += 2) {
                /* exclude 0x1000_0000-0x2000_0000, u-boot device */
                if (map[i] <= 0x10000000 && map[i+1] > 0x10000000)
@@ -163,10 +162,6 @@ void __init prom_init(void)
        void *reset_vec;
 
        nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
-       if (cpu_is_xlp9xx())
-               xlp_cores_per_node = 32;
-       else
-               xlp_cores_per_node = 8;
        nlm_init_boot_cpu();
        xlp_mmu_init();
        nlm_node_init(0);
index 17ade1c..2524939 100644 (file)
@@ -128,6 +128,9 @@ static void xlp9xx_usb_ack(struct irq_data *data)
        case PIC_9XX_XHCI_1_IRQ:
                port_addr = nlm_xlpii_get_usb_regbase(node, 2);
                break;
+       case PIC_9XX_XHCI_2_IRQ:
+               port_addr = nlm_xlpii_get_usb_regbase(node, 3);
+               break;
        default:
                pr_err("No matching USB irq %d node  %d!\n", irq, node);
                return;
@@ -222,14 +225,16 @@ static int __init nlm_platform_xlpii_usb_init(void)
        }
 
        /* XLP 9XX, multi-node */
-       pr_info("Initializing 9XX USB Interface\n");
+       pr_info("Initializing 9XX/5XX USB Interface\n");
        for (node = 0; node < NLM_NR_NODES; node++) {
                if (!nlm_node_present(node))
                        continue;
                nlm_xlpii_usb_hw_reset(node, 1);
                nlm_xlpii_usb_hw_reset(node, 2);
+               nlm_xlpii_usb_hw_reset(node, 3);
                nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_0_IRQ, xlp9xx_usb_ack);
                nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_1_IRQ, xlp9xx_usb_ack);
+               nlm_set_pic_extra_ack(node, PIC_9XX_XHCI_2_IRQ, xlp9xx_usb_ack);
        }
        return 0;
 }
@@ -253,6 +258,9 @@ static void nlm_xlp9xx_usb_fixup_final(struct pci_dev *dev)
        case 0x22:
                dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_1_IRQ);
                break;
+       case 0x23:
+               dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_2_IRQ);
+               break;
        }
 }
 
index e5f44d2..87d7846 100644 (file)
@@ -99,7 +99,7 @@ static int wait_for_cpus(int cpu, int bootcpu)
        do {
                notready = nlm_threads_per_core;
                for (i = 0; i < nlm_threads_per_core; i++)
-                       if (cpu_ready[cpu + i] || cpu == bootcpu)
+                       if (cpu_ready[cpu + i] || (cpu + i) == bootcpu)
                                --notready;
        } while (notready != 0 && --count > 0);
 
@@ -111,7 +111,7 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
        struct nlm_soc_info *nodep;
        uint64_t syspcibase, fusebase;
        uint32_t syscoremask, mask, fusemask;
-       int core, n, cpu;
+       int core, n, cpu, ncores;
 
        for (n = 0; n < NLM_NR_NODES; n++) {
                if (n != 0) {
@@ -168,7 +168,8 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
                syscoremask = (1 << hweight32(~fusemask & mask)) - 1;
 
                pr_info("Node %d - SYS/FUSE coremask %x\n", n, syscoremask);
-               for (core = 0; core < nlm_cores_per_node(); core++) {
+               ncores = nlm_cores_per_node();
+               for (core = 0; core < ncores; core++) {
                        /* we will be on node 0 core 0 */
                        if (n == 0 && core == 0)
                                continue;
@@ -178,8 +179,7 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
                                continue;
 
                        /* see if at least the first hw thread is enabled */
-                       cpu = (n * nlm_cores_per_node() + core)
-                                               * NLM_THREADS_PER_CORE;
+                       cpu = (n * ncores + core) * NLM_THREADS_PER_CORE;
                        if (!cpumask_test_cpu(cpu, wakeup_mask))
                                continue;
 
index a26cbe3..81f5895 100644 (file)
@@ -98,6 +98,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        case CPU_R10000:
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
        case CPU_XLR:
                lmodel = &op_model_mipsxx_ops;
                break;
index 01f721a..6a6e2cc 100644 (file)
@@ -246,7 +246,7 @@ static int mipsxx_perfcount_handler(void)
        unsigned int counter;
        int handled = IRQ_NONE;
 
-       if (cpu_has_mips_r2 && !(read_c0_cause() & (1 << 26)))
+       if (cpu_has_mips_r2 && !(read_c0_cause() & CAUSEF_PCI))
                return handled;
 
        switch (counters) {
@@ -296,6 +296,7 @@ static inline int n_counters(void)
 
        case CPU_R12000:
        case CPU_R14000:
+       case CPU_R16000:
                counters = 4;
                break;
 
@@ -411,6 +412,10 @@ static int __init mipsxx_init(void)
                op_model_mipsxx_ops.cpu_type = "mips/r12000";
                break;
 
+       case CPU_R16000:
+               op_model_mipsxx_ops.cpu_type = "mips/r16000";
+               break;
+
        case CPU_SB1:
        case CPU_SB1A:
                op_model_mipsxx_ops.cpu_type = "mips/sb1";
@@ -435,15 +440,17 @@ static int __init mipsxx_init(void)
 
        if (get_c0_perfcount_int)
                perfcount_irq = get_c0_perfcount_int();
-       else if ((cp0_perfcount_irq >= 0) &&
-                (cp0_compare_irq != cp0_perfcount_irq))
+       else if (cp0_perfcount_irq >= 0)
                perfcount_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
        else
                perfcount_irq = -1;
 
        if (perfcount_irq >= 0)
                return request_irq(perfcount_irq, mipsxx_perfcount_int,
-                       0, "Perfcounter", save_perf_irq);
+                                  IRQF_PERCPU | IRQF_NOBALANCING |
+                                  IRQF_NO_THREAD | IRQF_NO_SUSPEND |
+                                  IRQF_SHARED,
+                                  "Perfcounter", save_perf_irq);
 
        return 0;
 }
index 300591c..2eda01e 100644 (file)
@@ -43,7 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80)  += pci-bcm1480.o pci-bcm1480ht.o
 obj-$(CONFIG_SNI_RM)           += fixup-sni.o ops-sni.o
 obj-$(CONFIG_LANTIQ)           += fixup-lantiq.o
 obj-$(CONFIG_PCI_LANTIQ)       += pci-lantiq.o ops-lantiq.o
-obj-$(CONFIG_SOC_RT2880)       += pci-rt2880.o
+obj-$(CONFIG_SOC_RT288X)       += pci-rt2880.o
 obj-$(CONFIG_SOC_RT3883)       += pci-rt3883.o
 obj-$(CONFIG_TANBAC_TB0219)    += fixup-tb0219.o
 obj-$(CONFIG_TANBAC_TB0226)    += fixup-tb0226.o
index 6a40f24..3407495 100644 (file)
@@ -178,13 +178,6 @@ static void xlp_msi_mask_ack(struct irq_data *d)
        else
                nlm_write_reg(md->lnkbase, PCIE_MSI_STATUS, 1u << vec);
 
-       /* Ack at eirr and PIC */
-       ack_c0_eirr(PIC_PCIE_LINK_MSI_IRQ(link));
-       if (cpu_is_xlp9xx())
-               nlm_pic_ack(md->node->picbase,
-                               PIC_9XX_IRT_PCIE_LINK_INDEX(link));
-       else
-               nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_LINK_INDEX(link));
 }
 
 static struct irq_chip xlp_msi_chip = {
@@ -230,8 +223,6 @@ static void xlp_msix_mask_ack(struct irq_data *d)
        }
        nlm_write_reg(md->lnkbase, status_reg, 1u << bit);
 
-       /* Ack at eirr and PIC */
-       ack_c0_eirr(PIC_PCIE_MSIX_IRQ(link));
        if (!cpu_is_xlp9xx())
                nlm_pic_ack(md->node->picbase,
                                PIC_IRT_PCIE_MSIX_INDEX(msixvec));
@@ -541,6 +532,14 @@ void nlm_dispatch_msi(int node, int lirq)
                do_IRQ(irqbase + i);
                status &= status - 1;
        }
+
+       /* Ack at eirr and PIC */
+       ack_c0_eirr(PIC_PCIE_LINK_MSI_IRQ(link));
+       if (cpu_is_xlp9xx())
+               nlm_pic_ack(md->node->picbase,
+                               PIC_9XX_IRT_PCIE_LINK_INDEX(link));
+       else
+               nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_LINK_INDEX(link));
 }
 
 void nlm_dispatch_msix(int node, int lirq)
@@ -567,4 +566,6 @@ void nlm_dispatch_msix(int node, int lirq)
                do_IRQ(irqbase + i);
                status &= status - 1;
        }
+       /* Ack at eirr and PIC */
+       ack_c0_eirr(PIC_PCIE_MSIX_IRQ(link));
 }
index bd2b3b6..07a1822 100644 (file)
@@ -488,7 +488,6 @@ static struct platform_driver ar2315_pci_driver = {
        .probe = ar2315_pci_probe,
        .driver = {
                .name = "ar2315-pci",
-               .owner = THIS_MODULE,
        },
 };
 
index a04af55..c258cd4 100644 (file)
@@ -214,6 +214,8 @@ const char *octeon_get_pci_interrupts(void)
                return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
        case CVMX_BOARD_TYPE_BBGW_REF:
                return "AABCD";
+       case CVMX_BOARD_TYPE_CUST_DSR1000N:
+               return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
        case CVMX_BOARD_TYPE_THUNDER:
        case CVMX_BOARD_TYPE_EBH3000:
        default:
@@ -271,9 +273,6 @@ static int octeon_read_config(struct pci_bus *bus, unsigned int devfn,
        pci_addr.s.func = devfn & 0x7;
        pci_addr.s.reg = reg;
 
-#if PCI_CONFIG_SPACE_DELAY
-       udelay(PCI_CONFIG_SPACE_DELAY);
-#endif
        switch (size) {
        case 4:
                *val = le32_to_cpu(cvmx_read64_uint32(pci_addr.u64));
@@ -308,9 +307,6 @@ static int octeon_write_config(struct pci_bus *bus, unsigned int devfn,
        pci_addr.s.func = devfn & 0x7;
        pci_addr.s.reg = reg;
 
-#if PCI_CONFIG_SPACE_DELAY
-       udelay(PCI_CONFIG_SPACE_DELAY);
-#endif
        switch (size) {
        case 4:
                cvmx_write64_uint32(pci_addr.u64, cpu_to_le32(val));
index a457494..8a97802 100644 (file)
@@ -267,7 +267,6 @@ static struct platform_driver rt288x_pci_driver = {
        .probe = rt288x_pci_probe,
        .driver = {
                .name = "rt288x-pci",
-               .owner = THIS_MODULE,
                .of_match_table = rt288x_pci_match,
        },
 };
index 8bb13a4..b8a0bf5 100644 (file)
@@ -91,7 +91,10 @@ static void pcibios_scanbus(struct pci_controller *hose)
 
        pci_add_resource_offset(&resources,
                                hose->mem_resource, hose->mem_offset);
-       pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset);
+       pci_add_resource_offset(&resources,
+                               hose->io_resource, hose->io_offset);
+       pci_add_resource_offset(&resources,
+                               hose->busn_resource, hose->busn_offset);
        bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
                                &resources);
        hose->bus = bus;
index 1bb0b2b..99f3db4 100644 (file)
@@ -1762,14 +1762,6 @@ static int octeon_pcie_write_config(unsigned int pcie_port, struct pci_bus *bus,
        default:
                return PCIBIOS_FUNC_NOT_SUPPORTED;
        }
-#if PCI_CONFIG_SPACE_DELAY
-       /*
-        * Delay on writes so that devices have time to come up. Some
-        * bridges need this to allow time for the secondary busses to
-        * work
-        */
-       udelay(PCI_CONFIG_SPACE_DELAY);
-#endif
        return PCIBIOS_SUCCESSFUL;
 }
 
diff --git a/arch/mips/pistachio/Makefile b/arch/mips/pistachio/Makefile
new file mode 100644 (file)
index 0000000..32189c6
--- /dev/null
@@ -0,0 +1 @@
+obj-y  += init.o irq.o time.o
diff --git a/arch/mips/pistachio/Platform b/arch/mips/pistachio/Platform
new file mode 100644 (file)
index 0000000..d80cd61
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# IMG Pistachio SoC
+#
+platform-$(CONFIG_MACH_PISTACHIO)      += pistachio/
+cflags-$(CONFIG_MACH_PISTACHIO)                +=                              \
+               -I$(srctree)/arch/mips/include/asm/mach-pistachio
+load-$(CONFIG_MACH_PISTACHIO)          += 0xffffffff80400000
+zload-$(CONFIG_MACH_PISTACHIO)         += 0xffffffff81000000
diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c
new file mode 100644 (file)
index 0000000..d2dc836
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Pistachio platform setup
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+
+#include <asm/cacheflush.h>
+#include <asm/dma-coherence.h>
+#include <asm/fw/fw.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-cm.h>
+#include <asm/mips-cpc.h>
+#include <asm/prom.h>
+#include <asm/smp-ops.h>
+#include <asm/traps.h>
+
+const char *get_system_type(void)
+{
+       return "IMG Pistachio SoC";
+}
+
+static void __init plat_setup_iocoherency(void)
+{
+       /*
+        * Kernel has been configured with software coherency
+        * but we might choose to turn it off and use hardware
+        * coherency instead.
+        */
+       if (mips_cm_numiocu() != 0) {
+               /* Nothing special needs to be done to enable coherency */
+               pr_info("CMP IOCU detected\n");
+               hw_coherentio = 1;
+               if (coherentio == 0)
+                       pr_info("Hardware DMA cache coherency disabled\n");
+               else
+                       pr_info("Hardware DMA cache coherency enabled\n");
+       } else {
+               if (coherentio == 1)
+                       pr_info("Hardware DMA cache coherency unsupported, but enabled from command line!\n");
+               else
+                       pr_info("Software DMA cache coherency enabled\n");
+       }
+}
+
+void __init plat_mem_setup(void)
+{
+       if (fw_arg0 != -2)
+               panic("Device-tree not present");
+
+       __dt_setup_arch((void *)fw_arg1);
+       strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+
+       plat_setup_iocoherency();
+}
+
+#define DEFAULT_CPC_BASE_ADDR 0x1bde0000
+
+phys_addr_t mips_cpc_default_phys_base(void)
+{
+       return DEFAULT_CPC_BASE_ADDR;
+}
+
+static void __init mips_nmi_setup(void)
+{
+       void *base;
+       extern char except_vec_nmi;
+
+       base = cpu_has_veic ?
+               (void *)(CAC_BASE + 0xa80) :
+               (void *)(CAC_BASE + 0x380);
+       memcpy(base, &except_vec_nmi, 0x80);
+       flush_icache_range((unsigned long)base,
+                          (unsigned long)base + 0x80);
+}
+
+static void __init mips_ejtag_setup(void)
+{
+       void *base;
+       extern char except_vec_ejtag_debug;
+
+       base = cpu_has_veic ?
+               (void *)(CAC_BASE + 0xa00) :
+               (void *)(CAC_BASE + 0x300);
+       memcpy(base, &except_vec_ejtag_debug, 0x80);
+       flush_icache_range((unsigned long)base,
+                          (unsigned long)base + 0x80);
+}
+
+void __init prom_init(void)
+{
+       board_nmi_handler_setup = mips_nmi_setup;
+       board_ejtag_handler_setup = mips_ejtag_setup;
+
+       mips_cm_probe();
+       mips_cpc_probe();
+       register_cps_smp_ops();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init device_tree_init(void)
+{
+       if (!initial_boot_params)
+               return;
+
+       unflatten_and_copy_device_tree();
+}
+
+static int __init plat_of_setup(void)
+{
+       if (!of_have_populated_dt())
+               panic("Device tree not present");
+
+       if (of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL))
+               panic("Failed to populate DT");
+
+       return 0;
+}
+arch_initcall(plat_of_setup);
diff --git a/arch/mips/pistachio/irq.c b/arch/mips/pistachio/irq.c
new file mode 100644 (file)
index 0000000..0a6b24c
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Pistachio IRQ setup
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/mips-gic.h>
+#include <linux/kernel.h>
+
+#include <asm/cpu-features.h>
+#include <asm/irq_cpu.h>
+
+void __init arch_init_irq(void)
+{
+       pr_info("EIC is %s\n", cpu_has_veic ? "on" : "off");
+       pr_info("VINT is %s\n", cpu_has_vint ? "on" : "off");
+
+       if (!cpu_has_veic)
+               mips_cpu_irq_init();
+
+       irqchip_init();
+}
diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c
new file mode 100644 (file)
index 0000000..67889fc
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Pistachio clocksource/timer setup
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/irqchip/mips-gic.h>
+#include <linux/of.h>
+
+#include <asm/time.h>
+
+unsigned int get_c0_compare_int(void)
+{
+       return gic_get_c0_compare_int();
+}
+
+int get_c0_perfcount_int(void)
+{
+       return gic_get_c0_perfcount_int();
+}
+
+void __init plat_time_init(void)
+{
+       struct device_node *np;
+       struct clk *clk;
+
+       of_clk_init(NULL);
+       clocksource_of_init();
+
+       np = of_get_cpu_node(0, NULL);
+       if (!np) {
+               pr_err("Failed to get CPU node\n");
+               return;
+       }
+
+       clk = of_clk_get(np, 0);
+       if (IS_ERR(clk)) {
+               pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk));
+               return;
+       }
+
+       mips_hpt_frequency = clk_get_rate(clk) / 2;
+       clk_put(clk);
+}
index 73d56b8..70bd788 100644 (file)
@@ -1 +1 @@
-obj-$(CONFIG_HIBERNATION) += cpu.o hibernate.o
+obj-$(CONFIG_HIBERNATION) += cpu.o hibernate.o hibernate_asm.o
diff --git a/arch/mips/power/hibernate.c b/arch/mips/power/hibernate.c
new file mode 100644 (file)
index 0000000..19a9af6
--- /dev/null
@@ -0,0 +1,10 @@
+#include <asm/tlbflush.h>
+
+extern int restore_image(void);
+
+int swsusp_arch_resume(void)
+{
+       /* Avoid TLB mismatch during and after kernel resume */
+       local_flush_tlb_all();
+       return restore_image();
+}
similarity index 91%
rename from arch/mips/power/hibernate.S
rename to arch/mips/power/hibernate_asm.S
index 32a7c82..b1fab95 100644 (file)
@@ -29,7 +29,7 @@ LEAF(swsusp_arch_suspend)
        j swsusp_save
 END(swsusp_arch_suspend)
 
-LEAF(swsusp_arch_resume)
+LEAF(restore_image)
        PTR_L t0, restore_pblist
 0:
        PTR_L t1, PBE_ADDRESS(t0)   /* source */
@@ -43,7 +43,6 @@ LEAF(swsusp_arch_resume)
        bne t1, t3, 1b
        PTR_L t0, PBE_NEXT(t0)
        bnez t0, 0b
-       jal local_flush_tlb_all /* Avoid TLB mismatch after kernel resume */
        PTR_LA t0, saved_regs
        PTR_L ra, PT_R31(t0)
        PTR_L sp, PT_R29(t0)
@@ -59,4 +58,4 @@ LEAF(swsusp_arch_resume)
        PTR_L s7, PT_R23(t0)
        PTR_LI v0, 0x0
        jr ra
-END(swsusp_arch_resume)
+END(restore_image)
index b1c52ca..e9bc8c9 100644 (file)
@@ -7,6 +7,11 @@ config CLKEVT_RT3352
        select CLKSRC_OF
        select CLKSRC_MMIO
 
+config RALINK_ILL_ACC
+       bool
+       depends on SOC_RT305X
+       default y
+
 choice
        prompt "Ralink SoC selection"
        default SOC_RT305X
index 1d97eab..a6d10f6 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/sched_clock.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/param.h>
@@ -159,11 +160,18 @@ struct clocksource hub_rt_clocksource = {
        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static u64 notrace hub_rt_read_sched_clock(void)
+{
+       return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
+}
+
 static void __init hub_rt_clocksource_init(void)
 {
        struct clocksource *cs = &hub_rt_clocksource;
 
        clocksource_register_hz(cs, CYCLES_PER_SEC);
+
+       sched_clock_register(hub_rt_read_sched_clock, 52, CYCLES_PER_SEC);
 }
 
 void __init plat_time_init(void)
index b522477..0134db2 100644 (file)
@@ -5,7 +5,6 @@
  *
  * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
  */
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
@@ -137,7 +136,3 @@ struct platform_device ip32_rtc_device = {
 }
 
 device_initcall(sgio2_cmos_devinit);
-
-MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2");
index 04faf6d..24424f3 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/serial_reg.h>
 #include <linux/time.h>
 #ifdef CONFIG_BCM47XX
-#include <bcm47xx_nvram.h>
+#include <linux/bcm47xx_nvram.h>
 #endif
 
 enum bcma_boot_dev {
index b99729e..cbddbad 100644 (file)
@@ -20,6 +20,19 @@ config IMX_WEIM
          The WEIM(Wireless External Interface Module) works like a bus.
          You can attach many different devices on it, such as NOR, onenand.
 
+config MIPS_CDMM
+       bool "MIPS Common Device Memory Map (CDMM) Driver"
+       depends on CPU_MIPSR2
+       help
+         Driver needed for the MIPS Common Device Memory Map bus in MIPS
+         cores. This bus is for per-CPU tightly coupled devices such as the
+         Fast Debug Channel (FDC).
+
+         For this to work, either your bootloader needs to enable the CDMM
+         region at an unused physical address on the boot CPU, or else your
+         platform code needs to implement mips_cdmm_phys_base() (see
+         asm/cdmm.h).
+
 config MVEBU_MBUS
        bool
        depends on PLAT_ORION
index 2973c18..807dd17 100644 (file)
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmstb_gisb.o
 obj-$(CONFIG_IMX_WEIM) += imx-weim.o
+obj-$(CONFIG_MIPS_CDMM) += mips_cdmm.o
 obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
 obj-$(CONFIG_OMAP_OCP2SCP)     += omap-ocp2scp.o
 
diff --git a/drivers/bus/mips_cdmm.c b/drivers/bus/mips_cdmm.c
new file mode 100644 (file)
index 0000000..5bd792c
--- /dev/null
@@ -0,0 +1,716 @@
+/*
+ * Bus driver for MIPS Common Device Memory Map (CDMM).
+ *
+ * Copyright (C) 2014-2015 Imagination Technologies Ltd.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/atomic.h>
+#include <linux/err.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <asm/cdmm.h>
+#include <asm/hazards.h>
+#include <asm/mipsregs.h>
+
+/* Access control and status register fields */
+#define CDMM_ACSR_DEVTYPE_SHIFT        24
+#define CDMM_ACSR_DEVTYPE      (255ul << CDMM_ACSR_DEVTYPE_SHIFT)
+#define CDMM_ACSR_DEVSIZE_SHIFT        16
+#define CDMM_ACSR_DEVSIZE      (31ul << CDMM_ACSR_DEVSIZE_SHIFT)
+#define CDMM_ACSR_DEVREV_SHIFT 12
+#define CDMM_ACSR_DEVREV       (15ul << CDMM_ACSR_DEVREV_SHIFT)
+#define CDMM_ACSR_UW           (1ul << 3)
+#define CDMM_ACSR_UR           (1ul << 2)
+#define CDMM_ACSR_SW           (1ul << 1)
+#define CDMM_ACSR_SR           (1ul << 0)
+
+/* Each block of device registers is 64 bytes */
+#define CDMM_DRB_SIZE          64
+
+#define to_mips_cdmm_driver(d) container_of(d, struct mips_cdmm_driver, drv)
+
+/* Default physical base address */
+static phys_addr_t mips_cdmm_default_base;
+
+/* Bus operations */
+
+static const struct mips_cdmm_device_id *
+mips_cdmm_lookup(const struct mips_cdmm_device_id *table,
+                struct mips_cdmm_device *dev)
+{
+       int ret = 0;
+
+       for (; table->type; ++table) {
+               ret = (dev->type == table->type);
+               if (ret)
+                       break;
+       }
+
+       return ret ? table : NULL;
+}
+
+static int mips_cdmm_match(struct device *dev, struct device_driver *drv)
+{
+       struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);
+       struct mips_cdmm_driver *cdrv = to_mips_cdmm_driver(drv);
+
+       return mips_cdmm_lookup(cdrv->id_table, cdev) != NULL;
+}
+
+static int mips_cdmm_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);
+       int retval = 0;
+
+       retval = add_uevent_var(env, "CDMM_CPU=%u", cdev->cpu);
+       if (retval)
+               return retval;
+
+       retval = add_uevent_var(env, "CDMM_TYPE=0x%02x", cdev->type);
+       if (retval)
+               return retval;
+
+       retval = add_uevent_var(env, "CDMM_REV=%u", cdev->rev);
+       if (retval)
+               return retval;
+
+       retval = add_uevent_var(env, "MODALIAS=mipscdmm:t%02X", cdev->type);
+       return retval;
+}
+
+/* Device attributes */
+
+#define CDMM_ATTR(name, fmt, arg...)                                   \
+static ssize_t name##_show(struct device *_dev,                                \
+                          struct device_attribute *attr, char *buf)    \
+{                                                                      \
+       struct mips_cdmm_device *dev = to_mips_cdmm_device(_dev);       \
+       return sprintf(buf, fmt, arg);                                  \
+}                                                                      \
+static DEVICE_ATTR_RO(name);
+
+CDMM_ATTR(cpu, "%u\n", dev->cpu);
+CDMM_ATTR(type, "0x%02x\n", dev->type);
+CDMM_ATTR(revision, "%u\n", dev->rev);
+CDMM_ATTR(modalias, "mipscdmm:t%02X\n", dev->type);
+CDMM_ATTR(resource, "\t%016llx\t%016llx\t%016lx\n",
+         (unsigned long long)dev->res.start,
+         (unsigned long long)dev->res.end,
+         dev->res.flags);
+
+static struct attribute *mips_cdmm_dev_attrs[] = {
+       &dev_attr_cpu.attr,
+       &dev_attr_type.attr,
+       &dev_attr_revision.attr,
+       &dev_attr_modalias.attr,
+       &dev_attr_resource.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(mips_cdmm_dev);
+
+struct bus_type mips_cdmm_bustype = {
+       .name           = "cdmm",
+       .dev_groups     = mips_cdmm_dev_groups,
+       .match          = mips_cdmm_match,
+       .uevent         = mips_cdmm_uevent,
+};
+EXPORT_SYMBOL_GPL(mips_cdmm_bustype);
+
+/*
+ * Standard driver callback helpers.
+ *
+ * All the CDMM driver callbacks need to be executed on the appropriate CPU from
+ * workqueues. For the standard driver callbacks we need a work function
+ * (mips_cdmm_{void,int}_work()) to do the actual call from the right CPU, and a
+ * wrapper function (generated with BUILD_PERCPU_HELPER) to arrange for the work
+ * function to be called on that CPU.
+ */
+
+/**
+ * struct mips_cdmm_work_dev - Data for per-device call work.
+ * @fn:                CDMM driver callback function to call for the device.
+ * @dev:       CDMM device to pass to @fn.
+ */
+struct mips_cdmm_work_dev {
+       void                    *fn;
+       struct mips_cdmm_device *dev;
+};
+
+/**
+ * mips_cdmm_void_work() - Call a void returning CDMM driver callback.
+ * @data:      struct mips_cdmm_work_dev pointer.
+ *
+ * A work_on_cpu() callback function to call an arbitrary CDMM driver callback
+ * function which doesn't return a value.
+ */
+static long mips_cdmm_void_work(void *data)
+{
+       struct mips_cdmm_work_dev *work = data;
+       void (*fn)(struct mips_cdmm_device *) = work->fn;
+
+       fn(work->dev);
+       return 0;
+}
+
+/**
+ * mips_cdmm_int_work() - Call an int returning CDMM driver callback.
+ * @data:      struct mips_cdmm_work_dev pointer.
+ *
+ * A work_on_cpu() callback function to call an arbitrary CDMM driver callback
+ * function which returns an int.
+ */
+static long mips_cdmm_int_work(void *data)
+{
+       struct mips_cdmm_work_dev *work = data;
+       int (*fn)(struct mips_cdmm_device *) = work->fn;
+
+       return fn(work->dev);
+}
+
+#define _BUILD_RET_void
+#define _BUILD_RET_int return
+
+/**
+ * BUILD_PERCPU_HELPER() - Helper to call a CDMM driver callback on right CPU.
+ * @_ret:      Return type (void or int).
+ * @_name:     Name of CDMM driver callback function.
+ *
+ * Generates a specific device callback function to call a CDMM driver callback
+ * function on the appropriate CPU for the device, and if applicable return the
+ * result.
+ */
+#define BUILD_PERCPU_HELPER(_ret, _name)                               \
+static _ret mips_cdmm_##_name(struct device *dev)                      \
+{                                                                      \
+       struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);       \
+       struct mips_cdmm_driver *cdrv = to_mips_cdmm_driver(dev->driver); \
+       struct mips_cdmm_work_dev work = {                              \
+               .fn     = cdrv->_name,                                  \
+               .dev    = cdev,                                         \
+       };                                                              \
+                                                                       \
+       _BUILD_RET_##_ret work_on_cpu(cdev->cpu,                        \
+                                     mips_cdmm_##_ret##_work, &work);  \
+}
+
+/* Driver callback functions */
+BUILD_PERCPU_HELPER(int, probe)     /* int mips_cdmm_probe(struct device) */
+BUILD_PERCPU_HELPER(int, remove)    /* int mips_cdmm_remove(struct device) */
+BUILD_PERCPU_HELPER(void, shutdown) /* void mips_cdmm_shutdown(struct device) */
+
+
+/* Driver registration */
+
+/**
+ * mips_cdmm_driver_register() - Register a CDMM driver.
+ * @drv:       CDMM driver information.
+ *
+ * Register a CDMM driver with the CDMM subsystem. The driver will be informed
+ * of matching devices which are discovered.
+ *
+ * Returns:    0 on success.
+ */
+int mips_cdmm_driver_register(struct mips_cdmm_driver *drv)
+{
+       drv->drv.bus = &mips_cdmm_bustype;
+
+       if (drv->probe)
+               drv->drv.probe = mips_cdmm_probe;
+       if (drv->remove)
+               drv->drv.remove = mips_cdmm_remove;
+       if (drv->shutdown)
+               drv->drv.shutdown = mips_cdmm_shutdown;
+
+       return driver_register(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(mips_cdmm_driver_register);
+
+/**
+ * mips_cdmm_driver_unregister() - Unregister a CDMM driver.
+ * @drv:       CDMM driver information.
+ *
+ * Unregister a CDMM driver from the CDMM subsystem.
+ */
+void mips_cdmm_driver_unregister(struct mips_cdmm_driver *drv)
+{
+       driver_unregister(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(mips_cdmm_driver_unregister);
+
+
+/* CDMM initialisation and bus discovery */
+
+/**
+ * struct mips_cdmm_bus - Info about CDMM bus.
+ * @phys:              Physical address at which it is mapped.
+ * @regs:              Virtual address where registers can be accessed.
+ * @drbs:              Total number of DRBs.
+ * @drbs_reserved:     Number of DRBs reserved.
+ * @discovered:                Whether the devices on the bus have been discovered yet.
+ * @offline:           Whether the CDMM bus is going offline (or very early
+ *                     coming back online), in which case it should be
+ *                     reconfigured each time.
+ */
+struct mips_cdmm_bus {
+       phys_addr_t      phys;
+       void __iomem    *regs;
+       unsigned int     drbs;
+       unsigned int     drbs_reserved;
+       bool             discovered;
+       bool             offline;
+};
+
+static struct mips_cdmm_bus mips_cdmm_boot_bus;
+static DEFINE_PER_CPU(struct mips_cdmm_bus *, mips_cdmm_buses);
+static atomic_t mips_cdmm_next_id = ATOMIC_INIT(-1);
+
+/**
+ * mips_cdmm_get_bus() - Get the per-CPU CDMM bus information.
+ *
+ * Get information about the per-CPU CDMM bus, if the bus is present.
+ *
+ * The caller must prevent migration to another CPU, either by disabling
+ * pre-emption or by running from a pinned kernel thread.
+ *
+ * Returns:    Pointer to CDMM bus information for the current CPU.
+ *             May return ERR_PTR(-errno) in case of error, so check with
+ *             IS_ERR().
+ */
+static struct mips_cdmm_bus *mips_cdmm_get_bus(void)
+{
+       struct mips_cdmm_bus *bus, **bus_p;
+       unsigned long flags;
+       unsigned int cpu;
+
+       if (!cpu_has_cdmm)
+               return ERR_PTR(-ENODEV);
+
+       cpu = smp_processor_id();
+       /* Avoid early use of per-cpu primitives before initialised */
+       if (cpu == 0)
+               return &mips_cdmm_boot_bus;
+
+       /* Get bus pointer */
+       bus_p = per_cpu_ptr(&mips_cdmm_buses, cpu);
+       local_irq_save(flags);
+       bus = *bus_p;
+       /* Attempt allocation if NULL */
+       if (unlikely(!bus)) {
+               bus = kzalloc(sizeof(*bus), GFP_ATOMIC);
+               if (unlikely(!bus))
+                       bus = ERR_PTR(-ENOMEM);
+               else
+                       *bus_p = bus;
+       }
+       local_irq_restore(flags);
+       return bus;
+}
+
+/**
+ * mips_cdmm_cur_base() - Find current physical base address of CDMM region.
+ *
+ * Returns:    Physical base address of CDMM region according to cdmmbase CP0
+ *             register, or 0 if the CDMM region is disabled.
+ */
+static phys_addr_t mips_cdmm_cur_base(void)
+{
+       unsigned long cdmmbase = read_c0_cdmmbase();
+
+       if (!(cdmmbase & MIPS_CDMMBASE_EN))
+               return 0;
+
+       return (cdmmbase >> MIPS_CDMMBASE_ADDR_SHIFT)
+               << MIPS_CDMMBASE_ADDR_START;
+}
+
+/**
+ * mips_cdmm_setup() - Ensure the CDMM bus is initialised and usable.
+ * @bus:       Pointer to bus information for current CPU.
+ *             IS_ERR(bus) is checked, so no need for caller to check.
+ *
+ * The caller must prevent migration to another CPU, either by disabling
+ * pre-emption or by running from a pinned kernel thread.
+ *
+ * Returns     0 on success, -errno on failure.
+ */
+static int mips_cdmm_setup(struct mips_cdmm_bus *bus)
+{
+       unsigned long cdmmbase, flags;
+       int ret = 0;
+
+       if (IS_ERR(bus))
+               return PTR_ERR(bus);
+
+       local_irq_save(flags);
+       /* Don't set up bus a second time unless marked offline */
+       if (bus->offline) {
+               /* If CDMM region is still set up, nothing to do */
+               if (bus->phys == mips_cdmm_cur_base())
+                       goto out;
+               /*
+                * The CDMM region isn't set up as expected, so it needs
+                * reconfiguring, but then we can stop checking it.
+                */
+               bus->offline = false;
+       } else if (bus->phys > 1) {
+               goto out;
+       }
+
+       /* If the CDMM region is already configured, inherit that setup */
+       if (!bus->phys)
+               bus->phys = mips_cdmm_cur_base();
+       /* Otherwise, ask platform code for suggestions */
+       if (!bus->phys && mips_cdmm_phys_base)
+               bus->phys = mips_cdmm_phys_base();
+       /* Otherwise, copy what other CPUs have done */
+       if (!bus->phys)
+               bus->phys = mips_cdmm_default_base;
+       /* Otherwise, complain once */
+       if (!bus->phys) {
+               bus->phys = 1;
+               /*
+                * If you hit this, either your bootloader needs to set up the
+                * CDMM on the boot CPU, or else you need to implement
+                * mips_cdmm_phys_base() for your platform (see asm/cdmm.h).
+                */
+               pr_err("cdmm%u: Failed to choose a physical base\n",
+                      smp_processor_id());
+       }
+       /* Already complained? */
+       if (bus->phys == 1) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       /* Record our success for other CPUs to copy */
+       mips_cdmm_default_base = bus->phys;
+
+       pr_debug("cdmm%u: Enabling CDMM region at %pa\n",
+                smp_processor_id(), &bus->phys);
+
+       /* Enable CDMM */
+       cdmmbase = read_c0_cdmmbase();
+       cdmmbase &= (1ul << MIPS_CDMMBASE_ADDR_SHIFT) - 1;
+       cdmmbase |= (bus->phys >> MIPS_CDMMBASE_ADDR_START)
+                       << MIPS_CDMMBASE_ADDR_SHIFT;
+       cdmmbase |= MIPS_CDMMBASE_EN;
+       write_c0_cdmmbase(cdmmbase);
+       tlbw_use_hazard();
+
+       bus->regs = (void __iomem *)CKSEG1ADDR(bus->phys);
+       bus->drbs = 1 + ((cdmmbase & MIPS_CDMMBASE_SIZE) >>
+                        MIPS_CDMMBASE_SIZE_SHIFT);
+       bus->drbs_reserved = !!(cdmmbase & MIPS_CDMMBASE_CI);
+
+out:
+       local_irq_restore(flags);
+       return ret;
+}
+
+/**
+ * mips_cdmm_early_probe() - Minimally probe for a specific device on CDMM.
+ * @dev_type:  CDMM type code to look for.
+ *
+ * Minimally configure the in-CPU Common Device Memory Map (CDMM) and look for a
+ * specific device. This can be used to find a device very early in boot for
+ * example to configure an early FDC console device.
+ *
+ * The caller must prevent migration to another CPU, either by disabling
+ * pre-emption or by running from a pinned kernel thread.
+ *
+ * Returns:    MMIO pointer to device memory. The caller can read the ACSR
+ *             register to find more information about the device (such as the
+ *             version number or the number of blocks).
+ *             May return IOMEM_ERR_PTR(-errno) in case of error, so check with
+ *             IS_ERR().
+ */
+void __iomem *mips_cdmm_early_probe(unsigned int dev_type)
+{
+       struct mips_cdmm_bus *bus;
+       void __iomem *cdmm;
+       u32 acsr;
+       unsigned int drb, type, size;
+       int err;
+
+       if (WARN_ON(!dev_type))
+               return IOMEM_ERR_PTR(-ENODEV);
+
+       bus = mips_cdmm_get_bus();
+       err = mips_cdmm_setup(bus);
+       if (err)
+               return IOMEM_ERR_PTR(err);
+
+       /* Skip the first block if it's reserved for more registers */
+       drb = bus->drbs_reserved;
+       cdmm = bus->regs;
+
+       /* Look for a specific device type */
+       for (; drb < bus->drbs; drb += size + 1) {
+               acsr = readl(cdmm + drb * CDMM_DRB_SIZE);
+               type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT;
+               if (type == dev_type)
+                       return cdmm + drb * CDMM_DRB_SIZE;
+               size = (acsr & CDMM_ACSR_DEVSIZE) >> CDMM_ACSR_DEVSIZE_SHIFT;
+       }
+
+       return IOMEM_ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(mips_cdmm_early_probe);
+
+/**
+ * mips_cdmm_release() - Release a removed CDMM device.
+ * @dev:       Device object
+ *
+ * Clean up the struct mips_cdmm_device for an unused CDMM device. This is
+ * called automatically by the driver core when a device is removed.
+ */
+static void mips_cdmm_release(struct device *dev)
+{
+       struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);
+
+       kfree(cdev);
+}
+
+/**
+ * mips_cdmm_bus_discover() - Discover the devices on the CDMM bus.
+ * @bus:       CDMM bus information, must already be set up.
+ */
+static void mips_cdmm_bus_discover(struct mips_cdmm_bus *bus)
+{
+       void __iomem *cdmm;
+       u32 acsr;
+       unsigned int drb, type, size, rev;
+       struct mips_cdmm_device *dev;
+       unsigned int cpu = smp_processor_id();
+       int ret = 0;
+       int id = 0;
+
+       /* Skip the first block if it's reserved for more registers */
+       drb = bus->drbs_reserved;
+       cdmm = bus->regs;
+
+       /* Discover devices */
+       bus->discovered = true;
+       pr_info("cdmm%u discovery (%u blocks)\n", cpu, bus->drbs);
+       for (; drb < bus->drbs; drb += size + 1) {
+               acsr = readl(cdmm + drb * CDMM_DRB_SIZE);
+               type = (acsr & CDMM_ACSR_DEVTYPE) >> CDMM_ACSR_DEVTYPE_SHIFT;
+               size = (acsr & CDMM_ACSR_DEVSIZE) >> CDMM_ACSR_DEVSIZE_SHIFT;
+               rev  = (acsr & CDMM_ACSR_DEVREV)  >> CDMM_ACSR_DEVREV_SHIFT;
+
+               if (!type)
+                       continue;
+
+               pr_info("cdmm%u-%u: @%u (%#x..%#x), type 0x%02x, rev %u\n",
+                       cpu, id, drb, drb * CDMM_DRB_SIZE,
+                       (drb + size + 1) * CDMM_DRB_SIZE - 1,
+                       type, rev);
+
+               dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+               if (!dev)
+                       break;
+
+               dev->cpu = cpu;
+               dev->res.start = bus->phys + drb * CDMM_DRB_SIZE;
+               dev->res.end = bus->phys +
+                               (drb + size + 1) * CDMM_DRB_SIZE - 1;
+               dev->res.flags = IORESOURCE_MEM;
+               dev->type = type;
+               dev->rev = rev;
+               dev->dev.parent = get_cpu_device(cpu);
+               dev->dev.bus = &mips_cdmm_bustype;
+               dev->dev.id = atomic_inc_return(&mips_cdmm_next_id);
+               dev->dev.release = mips_cdmm_release;
+
+               dev_set_name(&dev->dev, "cdmm%u-%u", cpu, id);
+               ++id;
+               ret = device_register(&dev->dev);
+               if (ret) {
+                       put_device(&dev->dev);
+                       kfree(dev);
+               }
+       }
+}
+
+
+/*
+ * CPU hotplug and initialisation
+ *
+ * All the CDMM driver callbacks need to be executed on the appropriate CPU from
+ * workqueues. For the CPU callbacks, they need to be called for all devices on
+ * that CPU, so the work function calls bus_for_each_dev, using a helper
+ * (generated with BUILD_PERDEV_HELPER) to call the driver callback if the
+ * device's CPU matches.
+ */
+
+/**
+ * BUILD_PERDEV_HELPER() - Helper to call a CDMM driver callback if CPU matches.
+ * @_name:     Name of CDMM driver callback function.
+ *
+ * Generates a bus_for_each_dev callback function to call a specific CDMM driver
+ * callback function for the device if the device's CPU matches that pointed to
+ * by the data argument.
+ *
+ * This is used for informing drivers for all devices on a given CPU of some
+ * event (such as the CPU going online/offline).
+ *
+ * It is expected to already be called from the appropriate CPU.
+ */
+#define BUILD_PERDEV_HELPER(_name)                                     \
+static int mips_cdmm_##_name##_helper(struct device *dev, void *data)  \
+{                                                                      \
+       struct mips_cdmm_device *cdev = to_mips_cdmm_device(dev);       \
+       struct mips_cdmm_driver *cdrv;                                  \
+       unsigned int cpu = *(unsigned int *)data;                       \
+                                                                       \
+       if (cdev->cpu != cpu || !dev->driver)                           \
+               return 0;                                               \
+                                                                       \
+       cdrv = to_mips_cdmm_driver(dev->driver);                        \
+       if (!cdrv->_name)                                               \
+               return 0;                                               \
+       return cdrv->_name(cdev);                                       \
+}
+
+/* bus_for_each_dev callback helper functions */
+BUILD_PERDEV_HELPER(cpu_down)       /* int mips_cdmm_cpu_down_helper(...) */
+BUILD_PERDEV_HELPER(cpu_up)         /* int mips_cdmm_cpu_up_helper(...) */
+
+/**
+ * mips_cdmm_bus_down() - Tear down the CDMM bus.
+ * @data:      Pointer to unsigned int CPU number.
+ *
+ * This work_on_cpu callback function is executed on a given CPU to call the
+ * CDMM driver cpu_down callback for all devices on that CPU.
+ */
+static long mips_cdmm_bus_down(void *data)
+{
+       struct mips_cdmm_bus *bus;
+       long ret;
+
+       /* Inform all the devices on the bus */
+       ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, data,
+                              mips_cdmm_cpu_down_helper);
+
+       /*
+        * While bus is offline, each use of it should reconfigure it just in
+        * case it is first use when coming back online again.
+        */
+       bus = mips_cdmm_get_bus();
+       if (!IS_ERR(bus))
+               bus->offline = true;
+
+       return ret;
+}
+
+/**
+ * mips_cdmm_bus_up() - Bring up the CDMM bus.
+ * @data:      Pointer to unsigned int CPU number.
+ *
+ * This work_on_cpu callback function is executed on a given CPU to discover
+ * CDMM devices on that CPU, or to call the CDMM driver cpu_up callback for all
+ * devices already discovered on that CPU.
+ *
+ * It is used during initialisation and when CPUs are brought online.
+ */
+static long mips_cdmm_bus_up(void *data)
+{
+       struct mips_cdmm_bus *bus;
+       long ret;
+
+       bus = mips_cdmm_get_bus();
+       ret = mips_cdmm_setup(bus);
+       if (ret)
+               return ret;
+
+       /* Bus now set up, so we can drop the offline flag if still set */
+       bus->offline = false;
+
+       if (!bus->discovered)
+               mips_cdmm_bus_discover(bus);
+       else
+               /* Inform all the devices on the bus */
+               ret = bus_for_each_dev(&mips_cdmm_bustype, NULL, data,
+                                      mips_cdmm_cpu_up_helper);
+
+       return ret;
+}
+
+/**
+ * mips_cdmm_cpu_notify() - Take action when a CPU is going online or offline.
+ * @nb:                CPU notifier block .
+ * @action:    Event that has taken place (CPU_*).
+ * @data:      CPU number.
+ *
+ * This notifier is used to keep the CDMM buses updated as CPUs are offlined and
+ * onlined. When CPUs go offline or come back online, so does their CDMM bus, so
+ * devices must be informed. Also when CPUs come online for the first time the
+ * devices on the CDMM bus need discovering.
+ *
+ * Returns:    NOTIFY_OK if event was used.
+ *             NOTIFY_DONE if we didn't care.
+ */
+static int mips_cdmm_cpu_notify(struct notifier_block *nb,
+                               unsigned long action, void *data)
+{
+       unsigned int cpu = (unsigned int)data;
+
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_ONLINE:
+       case CPU_DOWN_FAILED:
+               work_on_cpu(cpu, mips_cdmm_bus_up, &cpu);
+               break;
+       case CPU_DOWN_PREPARE:
+               work_on_cpu(cpu, mips_cdmm_bus_down, &cpu);
+               break;
+       default:
+               return NOTIFY_DONE;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block mips_cdmm_cpu_nb = {
+       .notifier_call = mips_cdmm_cpu_notify,
+};
+
+/**
+ * mips_cdmm_init() - Initialise CDMM bus.
+ *
+ * Initialise CDMM bus, discover CDMM devices for online CPUs, and arrange for
+ * hotplug notifications so the CDMM drivers can be kept up to date.
+ */
+static int __init mips_cdmm_init(void)
+{
+       unsigned int cpu;
+       int ret;
+
+       /* Register the bus */
+       ret = bus_register(&mips_cdmm_bustype);
+       if (ret)
+               return ret;
+
+       /* We want to be notified about new CPUs */
+       ret = register_cpu_notifier(&mips_cdmm_cpu_nb);
+       if (ret) {
+               pr_warn("cdmm: Failed to register CPU notifier\n");
+               goto out;
+       }
+
+       /* Discover devices on CDMM of online CPUs */
+       for_each_online_cpu(cpu)
+               work_on_cpu(cpu, mips_cdmm_bus_up, &cpu);
+
+       return 0;
+out:
+       bus_unregister(&mips_cdmm_bustype);
+       return ret;
+}
+subsys_initcall(mips_cdmm_init);
index d478ceb..e43ff53 100644 (file)
@@ -54,6 +54,7 @@ obj-$(CONFIG_ARCH_MMP)                        += mmp/
 endif
 obj-$(CONFIG_PLAT_ORION)               += mvebu/
 obj-$(CONFIG_ARCH_MXS)                 += mxs/
+obj-$(CONFIG_MACH_PISTACHIO)           += pistachio/
 obj-$(CONFIG_COMMON_CLK_PXA)           += pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)          += qcom/
 obj-$(CONFIG_ARCH_ROCKCHIP)            += rockchip/
diff --git a/drivers/clk/pistachio/Makefile b/drivers/clk/pistachio/Makefile
new file mode 100644 (file)
index 0000000..f1e151f
--- /dev/null
@@ -0,0 +1,3 @@
+obj-y  += clk.o
+obj-y  += clk-pll.o
+obj-y  += clk-pistachio.o
diff --git a/drivers/clk/pistachio/clk-pistachio.c b/drivers/clk/pistachio/clk-pistachio.c
new file mode 100644 (file)
index 0000000..8c0fe88
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * Pistachio SoC clock controllers
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/pistachio-clk.h>
+
+#include "clk.h"
+
+static struct pistachio_gate pistachio_gates[] __initdata = {
+       GATE(CLK_MIPS, "mips", "mips_div", 0x104, 0),
+       GATE(CLK_AUDIO_IN, "audio_in", "audio_clk_in_gate", 0x104, 1),
+       GATE(CLK_AUDIO, "audio", "audio_div", 0x104, 2),
+       GATE(CLK_I2S, "i2s", "i2s_div", 0x104, 3),
+       GATE(CLK_SPDIF, "spdif", "spdif_div", 0x104, 4),
+       GATE(CLK_AUDIO_DAC, "audio_dac", "audio_dac_div", 0x104, 5),
+       GATE(CLK_RPU_V, "rpu_v", "rpu_v_div", 0x104, 6),
+       GATE(CLK_RPU_L, "rpu_l", "rpu_l_div", 0x104, 7),
+       GATE(CLK_RPU_SLEEP, "rpu_sleep", "rpu_sleep_div", 0x104, 8),
+       GATE(CLK_WIFI_PLL_GATE, "wifi_pll_gate", "wifi_pll_mux", 0x104, 9),
+       GATE(CLK_RPU_CORE, "rpu_core", "rpu_core_div", 0x104, 10),
+       GATE(CLK_WIFI_ADC, "wifi_adc", "wifi_div8_mux", 0x104, 11),
+       GATE(CLK_WIFI_DAC, "wifi_dac", "wifi_div4_mux", 0x104, 12),
+       GATE(CLK_USB_PHY, "usb_phy", "usb_phy_div", 0x104, 13),
+       GATE(CLK_ENET_IN, "enet_in", "enet_clk_in_gate", 0x104, 14),
+       GATE(CLK_ENET, "enet", "enet_div", 0x104, 15),
+       GATE(CLK_UART0, "uart0", "uart0_div", 0x104, 16),
+       GATE(CLK_UART1, "uart1", "uart1_div", 0x104, 17),
+       GATE(CLK_PERIPH_SYS, "periph_sys", "sys_internal_div", 0x104, 18),
+       GATE(CLK_SPI0, "spi0", "spi0_div", 0x104, 19),
+       GATE(CLK_SPI1, "spi1", "spi1_div", 0x104, 20),
+       GATE(CLK_EVENT_TIMER, "event_timer", "event_timer_div", 0x104, 21),
+       GATE(CLK_AUX_ADC_INTERNAL, "aux_adc_internal", "sys_internal_div",
+            0x104, 22),
+       GATE(CLK_AUX_ADC, "aux_adc", "aux_adc_div", 0x104, 23),
+       GATE(CLK_SD_HOST, "sd_host", "sd_host_div", 0x104, 24),
+       GATE(CLK_BT, "bt", "bt_div", 0x104, 25),
+       GATE(CLK_BT_DIV4, "bt_div4", "bt_div4_div", 0x104, 26),
+       GATE(CLK_BT_DIV8, "bt_div8", "bt_div8_div", 0x104, 27),
+       GATE(CLK_BT_1MHZ, "bt_1mhz", "bt_1mhz_div", 0x104, 28),
+};
+
+static struct pistachio_fixed_factor pistachio_ffs[] __initdata = {
+       FIXED_FACTOR(CLK_WIFI_DIV4, "wifi_div4", "wifi_pll", 4),
+       FIXED_FACTOR(CLK_WIFI_DIV8, "wifi_div8", "wifi_pll", 8),
+};
+
+static struct pistachio_div pistachio_divs[] __initdata = {
+       DIV(CLK_MIPS_INTERNAL_DIV, "mips_internal_div", "mips_pll_mux",
+           0x204, 2),
+       DIV(CLK_MIPS_DIV, "mips_div", "mips_internal_div", 0x208, 8),
+       DIV_F(CLK_AUDIO_DIV, "audio_div", "audio_mux",
+               0x20c, 8, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(CLK_I2S_DIV, "i2s_div", "audio_pll_mux",
+               0x210, 8, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(CLK_SPDIF_DIV, "spdif_div", "audio_pll_mux",
+               0x214, 8, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(CLK_AUDIO_DAC_DIV, "audio_dac_div", "audio_pll_mux",
+               0x218, 8, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV(CLK_RPU_V_DIV, "rpu_v_div", "rpu_v_pll_mux", 0x21c, 2),
+       DIV(CLK_RPU_L_DIV, "rpu_l_div", "rpu_l_mux", 0x220, 2),
+       DIV(CLK_RPU_SLEEP_DIV, "rpu_sleep_div", "xtal", 0x224, 10),
+       DIV(CLK_RPU_CORE_DIV, "rpu_core_div", "rpu_core_mux", 0x228, 3),
+       DIV(CLK_USB_PHY_DIV, "usb_phy_div", "sys_internal_div", 0x22c, 6),
+       DIV(CLK_ENET_DIV, "enet_div", "enet_mux", 0x230, 6),
+       DIV_F(CLK_UART0_INTERNAL_DIV, "uart0_internal_div", "sys_pll_mux",
+             0x234, 3, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(CLK_UART0_DIV, "uart0_div", "uart0_internal_div", 0x238, 10,
+             CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(CLK_UART1_INTERNAL_DIV, "uart1_internal_div", "sys_pll_mux",
+             0x23c, 3, CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(CLK_UART1_DIV, "uart1_div", "uart1_internal_div", 0x240, 10,
+             CLK_DIVIDER_ROUND_CLOSEST),
+       DIV(CLK_SYS_INTERNAL_DIV, "sys_internal_div", "sys_pll_mux", 0x244, 3),
+       DIV(CLK_SPI0_INTERNAL_DIV, "spi0_internal_div", "sys_pll_mux",
+           0x248, 3),
+       DIV(CLK_SPI0_DIV, "spi0_div", "spi0_internal_div", 0x24c, 7),
+       DIV(CLK_SPI1_INTERNAL_DIV, "spi1_internal_div", "sys_pll_mux",
+           0x250, 3),
+       DIV(CLK_SPI1_DIV, "spi1_div", "spi1_internal_div", 0x254, 7),
+       DIV(CLK_EVENT_TIMER_INTERNAL_DIV, "event_timer_internal_div",
+           "event_timer_mux", 0x258, 3),
+       DIV(CLK_EVENT_TIMER_DIV, "event_timer_div", "event_timer_internal_div",
+           0x25c, 12),
+       DIV(CLK_AUX_ADC_INTERNAL_DIV, "aux_adc_internal_div",
+           "aux_adc_internal", 0x260, 3),
+       DIV(CLK_AUX_ADC_DIV, "aux_adc_div", "aux_adc_internal_div", 0x264, 10),
+       DIV(CLK_SD_HOST_DIV, "sd_host_div", "sd_host_mux", 0x268, 6),
+       DIV(CLK_BT_DIV, "bt_div", "bt_pll_mux", 0x26c, 6),
+       DIV(CLK_BT_DIV4_DIV, "bt_div4_div", "bt_pll_mux", 0x270, 6),
+       DIV(CLK_BT_DIV8_DIV, "bt_div8_div", "bt_pll_mux", 0x274, 6),
+       DIV(CLK_BT_1MHZ_INTERNAL_DIV, "bt_1mhz_internal_div", "bt_pll_mux",
+           0x278, 3),
+       DIV(CLK_BT_1MHZ_DIV, "bt_1mhz_div", "bt_1mhz_internal_div", 0x27c, 10),
+};
+
+PNAME(mux_xtal_audio_refclk) = { "xtal", "audio_clk_in_gate" };
+PNAME(mux_xtal_mips) = { "xtal", "mips_pll" };
+PNAME(mux_xtal_audio) = { "xtal", "audio_pll", "audio_in" };
+PNAME(mux_audio_debug) = { "audio_pll_mux", "debug_mux" };
+PNAME(mux_xtal_rpu_v) = { "xtal", "rpu_v_pll" };
+PNAME(mux_xtal_rpu_l) = { "xtal", "rpu_l_pll" };
+PNAME(mux_rpu_l_mips) = { "rpu_l_pll_mux", "mips_pll_mux" };
+PNAME(mux_xtal_wifi) = { "xtal", "wifi_pll" };
+PNAME(mux_xtal_wifi_div4) = { "xtal", "wifi_div4" };
+PNAME(mux_xtal_wifi_div8) = { "xtal", "wifi_div8" };
+PNAME(mux_wifi_div4_rpu_l) = { "wifi_pll_gate", "wifi_div4_mux",
+                              "rpu_l_pll_mux" };
+PNAME(mux_xtal_sys) = { "xtal", "sys_pll" };
+PNAME(mux_sys_enet) = { "sys_internal_div", "enet_in" };
+PNAME(mux_audio_sys) = { "audio_pll_mux", "sys_internal_div" };
+PNAME(mux_sys_bt) = { "sys_internal_div", "bt_pll_mux" };
+PNAME(mux_xtal_bt) = { "xtal", "bt_pll" };
+
+static struct pistachio_mux pistachio_muxes[] __initdata = {
+       MUX(CLK_AUDIO_REF_MUX, "audio_refclk_mux", mux_xtal_audio_refclk,
+           0x200, 0),
+       MUX(CLK_MIPS_PLL_MUX, "mips_pll_mux", mux_xtal_mips, 0x200, 1),
+       MUX(CLK_AUDIO_PLL_MUX, "audio_pll_mux", mux_xtal_audio, 0x200, 2),
+       MUX(CLK_AUDIO_MUX, "audio_mux", mux_audio_debug, 0x200, 4),
+       MUX(CLK_RPU_V_PLL_MUX, "rpu_v_pll_mux", mux_xtal_rpu_v, 0x200, 5),
+       MUX(CLK_RPU_L_PLL_MUX, "rpu_l_pll_mux", mux_xtal_rpu_l, 0x200, 6),
+       MUX(CLK_RPU_L_MUX, "rpu_l_mux", mux_rpu_l_mips, 0x200, 7),
+       MUX(CLK_WIFI_PLL_MUX, "wifi_pll_mux", mux_xtal_wifi, 0x200, 8),
+       MUX(CLK_WIFI_DIV4_MUX, "wifi_div4_mux", mux_xtal_wifi_div4, 0x200, 9),
+       MUX(CLK_WIFI_DIV8_MUX, "wifi_div8_mux", mux_xtal_wifi_div8, 0x200, 10),
+       MUX(CLK_RPU_CORE_MUX, "rpu_core_mux", mux_wifi_div4_rpu_l, 0x200, 11),
+       MUX(CLK_SYS_PLL_MUX, "sys_pll_mux", mux_xtal_sys, 0x200, 13),
+       MUX(CLK_ENET_MUX, "enet_mux", mux_sys_enet, 0x200, 14),
+       MUX(CLK_EVENT_TIMER_MUX, "event_timer_mux", mux_audio_sys, 0x200, 15),
+       MUX(CLK_SD_HOST_MUX, "sd_host_mux", mux_sys_bt, 0x200, 16),
+       MUX(CLK_BT_PLL_MUX, "bt_pll_mux", mux_xtal_bt, 0x200, 17),
+};
+
+static struct pistachio_pll pistachio_plls[] __initdata = {
+       PLL_FIXED(CLK_MIPS_PLL, "mips_pll", "xtal", PLL_GF40LP_LAINT, 0x0),
+       PLL_FIXED(CLK_AUDIO_PLL, "audio_pll", "audio_refclk_mux",
+                 PLL_GF40LP_FRAC, 0xc),
+       PLL_FIXED(CLK_RPU_V_PLL, "rpu_v_pll", "xtal", PLL_GF40LP_LAINT, 0x20),
+       PLL_FIXED(CLK_RPU_L_PLL, "rpu_l_pll", "xtal", PLL_GF40LP_LAINT, 0x2c),
+       PLL_FIXED(CLK_SYS_PLL, "sys_pll", "xtal", PLL_GF40LP_FRAC, 0x38),
+       PLL_FIXED(CLK_WIFI_PLL, "wifi_pll", "xtal", PLL_GF40LP_FRAC, 0x4c),
+       PLL_FIXED(CLK_BT_PLL, "bt_pll", "xtal", PLL_GF40LP_LAINT, 0x60),
+};
+
+PNAME(mux_debug) = { "mips_pll_mux", "rpu_v_pll_mux",
+                    "rpu_l_pll_mux", "sys_pll_mux",
+                    "wifi_pll_mux", "bt_pll_mux" };
+static u32 mux_debug_idx[] = { 0x0, 0x1, 0x2, 0x4, 0x8, 0x10 };
+
+static unsigned int pistachio_critical_clks[] __initdata = {
+       CLK_MIPS,
+       CLK_PERIPH_SYS,
+};
+
+static void __init pistachio_clk_init(struct device_node *np)
+{
+       struct pistachio_clk_provider *p;
+       struct clk *debug_clk;
+
+       p = pistachio_clk_alloc_provider(np, CLK_NR_CLKS);
+       if (!p)
+               return;
+
+       pistachio_clk_register_pll(p, pistachio_plls,
+                                  ARRAY_SIZE(pistachio_plls));
+       pistachio_clk_register_mux(p, pistachio_muxes,
+                                  ARRAY_SIZE(pistachio_muxes));
+       pistachio_clk_register_div(p, pistachio_divs,
+                                  ARRAY_SIZE(pistachio_divs));
+       pistachio_clk_register_fixed_factor(p, pistachio_ffs,
+                                           ARRAY_SIZE(pistachio_ffs));
+       pistachio_clk_register_gate(p, pistachio_gates,
+                                   ARRAY_SIZE(pistachio_gates));
+
+       debug_clk = clk_register_mux_table(NULL, "debug_mux", mux_debug,
+                                          ARRAY_SIZE(mux_debug),
+                                          CLK_SET_RATE_NO_REPARENT,
+                                          p->base + 0x200, 18, 0x1f, 0,
+                                          mux_debug_idx, NULL);
+       p->clk_data.clks[CLK_DEBUG_MUX] = debug_clk;
+
+       pistachio_clk_register_provider(p);
+
+       pistachio_clk_force_enable(p, pistachio_critical_clks,
+                                  ARRAY_SIZE(pistachio_critical_clks));
+}
+CLK_OF_DECLARE(pistachio_clk, "img,pistachio-clk", pistachio_clk_init);
+
+static struct pistachio_gate pistachio_periph_gates[] __initdata = {
+       GATE(PERIPH_CLK_SYS, "sys", "periph_sys", 0x100, 0),
+       GATE(PERIPH_CLK_SYS_BUS, "bus_sys", "periph_sys", 0x100, 1),
+       GATE(PERIPH_CLK_DDR, "ddr", "periph_sys", 0x100, 2),
+       GATE(PERIPH_CLK_ROM, "rom", "rom_div", 0x100, 3),
+       GATE(PERIPH_CLK_COUNTER_FAST, "counter_fast", "counter_fast_div",
+            0x100, 4),
+       GATE(PERIPH_CLK_COUNTER_SLOW, "counter_slow", "counter_slow_div",
+            0x100, 5),
+       GATE(PERIPH_CLK_IR, "ir", "ir_div", 0x100, 6),
+       GATE(PERIPH_CLK_WD, "wd", "wd_div", 0x100, 7),
+       GATE(PERIPH_CLK_PDM, "pdm", "pdm_div", 0x100, 8),
+       GATE(PERIPH_CLK_PWM, "pwm", "pwm_div", 0x100, 9),
+       GATE(PERIPH_CLK_I2C0, "i2c0", "i2c0_div", 0x100, 10),
+       GATE(PERIPH_CLK_I2C1, "i2c1", "i2c1_div", 0x100, 11),
+       GATE(PERIPH_CLK_I2C2, "i2c2", "i2c2_div", 0x100, 12),
+       GATE(PERIPH_CLK_I2C3, "i2c3", "i2c3_div", 0x100, 13),
+};
+
+static struct pistachio_div pistachio_periph_divs[] __initdata = {
+       DIV(PERIPH_CLK_ROM_DIV, "rom_div", "periph_sys", 0x10c, 7),
+       DIV(PERIPH_CLK_COUNTER_FAST_DIV, "counter_fast_div", "periph_sys",
+           0x110, 7),
+       DIV(PERIPH_CLK_COUNTER_SLOW_PRE_DIV, "counter_slow_pre_div",
+           "periph_sys", 0x114, 7),
+       DIV(PERIPH_CLK_COUNTER_SLOW_DIV, "counter_slow_div",
+           "counter_slow_pre_div", 0x118, 7),
+       DIV_F(PERIPH_CLK_IR_PRE_DIV, "ir_pre_div", "periph_sys", 0x11c, 7,
+             CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(PERIPH_CLK_IR_DIV, "ir_div", "ir_pre_div", 0x120, 7,
+             CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(PERIPH_CLK_WD_PRE_DIV, "wd_pre_div", "periph_sys", 0x124, 7,
+             CLK_DIVIDER_ROUND_CLOSEST),
+       DIV_F(PERIPH_CLK_WD_DIV, "wd_div", "wd_pre_div", 0x128, 7,
+             CLK_DIVIDER_ROUND_CLOSEST),
+       DIV(PERIPH_CLK_PDM_PRE_DIV, "pdm_pre_div", "periph_sys", 0x12c, 7),
+       DIV(PERIPH_CLK_PDM_DIV, "pdm_div", "pdm_pre_div", 0x130, 7),
+       DIV(PERIPH_CLK_PWM_PRE_DIV, "pwm_pre_div", "periph_sys", 0x134, 7),
+       DIV(PERIPH_CLK_PWM_DIV, "pwm_div", "pwm_pre_div", 0x138, 7),
+       DIV(PERIPH_CLK_I2C0_PRE_DIV, "i2c0_pre_div", "periph_sys", 0x13c, 7),
+       DIV(PERIPH_CLK_I2C0_DIV, "i2c0_div", "i2c0_pre_div", 0x140, 7),
+       DIV(PERIPH_CLK_I2C1_PRE_DIV, "i2c1_pre_div", "periph_sys", 0x144, 7),
+       DIV(PERIPH_CLK_I2C1_DIV, "i2c1_div", "i2c1_pre_div", 0x148, 7),
+       DIV(PERIPH_CLK_I2C2_PRE_DIV, "i2c2_pre_div", "periph_sys", 0x14c, 7),
+       DIV(PERIPH_CLK_I2C2_DIV, "i2c2_div", "i2c2_pre_div", 0x150, 7),
+       DIV(PERIPH_CLK_I2C3_PRE_DIV, "i2c3_pre_div", "periph_sys", 0x154, 7),
+       DIV(PERIPH_CLK_I2C3_DIV, "i2c3_div", "i2c3_pre_div", 0x158, 7),
+};
+
+static void __init pistachio_clk_periph_init(struct device_node *np)
+{
+       struct pistachio_clk_provider *p;
+
+       p = pistachio_clk_alloc_provider(np, PERIPH_CLK_NR_CLKS);
+       if (!p)
+               return;
+
+       pistachio_clk_register_div(p, pistachio_periph_divs,
+                                  ARRAY_SIZE(pistachio_periph_divs));
+       pistachio_clk_register_gate(p, pistachio_periph_gates,
+                                   ARRAY_SIZE(pistachio_periph_gates));
+
+       pistachio_clk_register_provider(p);
+}
+CLK_OF_DECLARE(pistachio_clk_periph, "img,pistachio-clk-periph",
+              pistachio_clk_periph_init);
+
+static struct pistachio_gate pistachio_sys_gates[] __initdata = {
+       GATE(SYS_CLK_I2C0, "i2c0_sys", "sys", 0x8, 0),
+       GATE(SYS_CLK_I2C1, "i2c1_sys", "sys", 0x8, 1),
+       GATE(SYS_CLK_I2C2, "i2c2_sys", "sys", 0x8, 2),
+       GATE(SYS_CLK_I2C3, "i2c3_sys", "sys", 0x8, 3),
+       GATE(SYS_CLK_I2S_IN, "i2s_in_sys", "sys", 0x8, 4),
+       GATE(SYS_CLK_PAUD_OUT, "paud_out_sys", "sys", 0x8, 5),
+       GATE(SYS_CLK_SPDIF_OUT, "spdif_out_sys", "sys", 0x8, 6),
+       GATE(SYS_CLK_SPI0_MASTER, "spi0_master_sys", "sys", 0x8, 7),
+       GATE(SYS_CLK_SPI0_SLAVE, "spi0_slave_sys", "sys", 0x8, 8),
+       GATE(SYS_CLK_PWM, "pwm_sys", "sys", 0x8, 9),
+       GATE(SYS_CLK_UART0, "uart0_sys", "sys", 0x8, 10),
+       GATE(SYS_CLK_UART1, "uart1_sys", "sys", 0x8, 11),
+       GATE(SYS_CLK_SPI1, "spi1_sys", "sys", 0x8, 12),
+       GATE(SYS_CLK_MDC, "mdc_sys", "sys", 0x8, 13),
+       GATE(SYS_CLK_SD_HOST, "sd_host_sys", "sys", 0x8, 14),
+       GATE(SYS_CLK_ENET, "enet_sys", "sys", 0x8, 15),
+       GATE(SYS_CLK_IR, "ir_sys", "sys", 0x8, 16),
+       GATE(SYS_CLK_WD, "wd_sys", "sys", 0x8, 17),
+       GATE(SYS_CLK_TIMER, "timer_sys", "sys", 0x8, 18),
+       GATE(SYS_CLK_I2S_OUT, "i2s_out_sys", "sys", 0x8, 24),
+       GATE(SYS_CLK_SPDIF_IN, "spdif_in_sys", "sys", 0x8, 25),
+       GATE(SYS_CLK_EVENT_TIMER, "event_timer_sys", "sys", 0x8, 26),
+       GATE(SYS_CLK_HASH, "hash_sys", "sys", 0x8, 27),
+};
+
+static void __init pistachio_cr_periph_init(struct device_node *np)
+{
+       struct pistachio_clk_provider *p;
+
+       p = pistachio_clk_alloc_provider(np, SYS_CLK_NR_CLKS);
+       if (!p)
+               return;
+
+       pistachio_clk_register_gate(p, pistachio_sys_gates,
+                                   ARRAY_SIZE(pistachio_sys_gates));
+
+       pistachio_clk_register_provider(p);
+}
+CLK_OF_DECLARE(pistachio_cr_periph, "img,pistachio-cr-periph",
+              pistachio_cr_periph_init);
+
+static struct pistachio_gate pistachio_ext_gates[] __initdata = {
+       GATE(EXT_CLK_ENET_IN, "enet_clk_in_gate", "enet_clk_in", 0x58, 5),
+       GATE(EXT_CLK_AUDIO_IN, "audio_clk_in_gate", "audio_clk_in", 0x58, 8)
+};
+
+static void __init pistachio_cr_top_init(struct device_node *np)
+{
+       struct pistachio_clk_provider *p;
+
+       p = pistachio_clk_alloc_provider(np, EXT_CLK_NR_CLKS);
+       if (!p)
+               return;
+
+       pistachio_clk_register_gate(p, pistachio_ext_gates,
+                                   ARRAY_SIZE(pistachio_ext_gates));
+
+       pistachio_clk_register_provider(p);
+}
+CLK_OF_DECLARE(pistachio_cr_top, "img,pistachio-cr-top",
+              pistachio_cr_top_init);
diff --git a/drivers/clk/pistachio/clk-pll.c b/drivers/clk/pistachio/clk-pll.c
new file mode 100644 (file)
index 0000000..de53756
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+#define PLL_STATUS                     0x0
+#define PLL_STATUS_LOCK                        BIT(0)
+
+#define PLL_CTRL1                      0x4
+#define PLL_CTRL1_REFDIV_SHIFT         0
+#define PLL_CTRL1_REFDIV_MASK          0x3f
+#define PLL_CTRL1_FBDIV_SHIFT          6
+#define PLL_CTRL1_FBDIV_MASK           0xfff
+#define PLL_INT_CTRL1_POSTDIV1_SHIFT   18
+#define PLL_INT_CTRL1_POSTDIV1_MASK    0x7
+#define PLL_INT_CTRL1_POSTDIV2_SHIFT   21
+#define PLL_INT_CTRL1_POSTDIV2_MASK    0x7
+#define PLL_INT_CTRL1_PD               BIT(24)
+#define PLL_INT_CTRL1_DSMPD            BIT(25)
+#define PLL_INT_CTRL1_FOUTPOSTDIVPD    BIT(26)
+#define PLL_INT_CTRL1_FOUTVCOPD                BIT(27)
+
+#define PLL_CTRL2                      0x8
+#define PLL_FRAC_CTRL2_FRAC_SHIFT      0
+#define PLL_FRAC_CTRL2_FRAC_MASK       0xffffff
+#define PLL_FRAC_CTRL2_POSTDIV1_SHIFT  24
+#define PLL_FRAC_CTRL2_POSTDIV1_MASK   0x7
+#define PLL_FRAC_CTRL2_POSTDIV2_SHIFT  27
+#define PLL_FRAC_CTRL2_POSTDIV2_MASK   0x7
+#define PLL_INT_CTRL2_BYPASS           BIT(28)
+
+#define PLL_CTRL3                      0xc
+#define PLL_FRAC_CTRL3_PD              BIT(0)
+#define PLL_FRAC_CTRL3_DACPD           BIT(1)
+#define PLL_FRAC_CTRL3_DSMPD           BIT(2)
+#define PLL_FRAC_CTRL3_FOUTPOSTDIVPD   BIT(3)
+#define PLL_FRAC_CTRL3_FOUT4PHASEPD    BIT(4)
+#define PLL_FRAC_CTRL3_FOUTVCOPD       BIT(5)
+
+#define PLL_CTRL4                      0x10
+#define PLL_FRAC_CTRL4_BYPASS          BIT(28)
+
+struct pistachio_clk_pll {
+       struct clk_hw hw;
+       void __iomem *base;
+       struct pistachio_pll_rate_table *rates;
+       unsigned int nr_rates;
+};
+
+static inline u32 pll_readl(struct pistachio_clk_pll *pll, u32 reg)
+{
+       return readl(pll->base + reg);
+}
+
+static inline void pll_writel(struct pistachio_clk_pll *pll, u32 val, u32 reg)
+{
+       writel(val, pll->base + reg);
+}
+
+static inline u32 do_div_round_closest(u64 dividend, u32 divisor)
+{
+       dividend += divisor / 2;
+       do_div(dividend, divisor);
+
+       return dividend;
+}
+
+static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw)
+{
+       return container_of(hw, struct pistachio_clk_pll, hw);
+}
+
+static struct pistachio_pll_rate_table *
+pll_get_params(struct pistachio_clk_pll *pll, unsigned long fref,
+              unsigned long fout)
+{
+       unsigned int i;
+
+       for (i = 0; i < pll->nr_rates; i++) {
+               if (pll->rates[i].fref == fref && pll->rates[i].fout == fout)
+                       return &pll->rates[i];
+       }
+
+       return NULL;
+}
+
+static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
+                          unsigned long *parent_rate)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       unsigned int i;
+
+       for (i = 0; i < pll->nr_rates; i++) {
+               if (i > 0 && pll->rates[i].fref == *parent_rate &&
+                   pll->rates[i].fout <= rate)
+                       return pll->rates[i - 1].fout;
+       }
+
+       return pll->rates[0].fout;
+}
+
+static int pll_gf40lp_frac_enable(struct clk_hw *hw)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       u32 val;
+
+       val = pll_readl(pll, PLL_CTRL3);
+       val &= ~(PLL_FRAC_CTRL3_PD | PLL_FRAC_CTRL3_DACPD |
+                PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_FOUTPOSTDIVPD |
+                PLL_FRAC_CTRL3_FOUT4PHASEPD | PLL_FRAC_CTRL3_FOUTVCOPD);
+       pll_writel(pll, val, PLL_CTRL3);
+
+       val = pll_readl(pll, PLL_CTRL4);
+       val &= ~PLL_FRAC_CTRL4_BYPASS;
+       pll_writel(pll, val, PLL_CTRL4);
+
+       return 0;
+}
+
+static void pll_gf40lp_frac_disable(struct clk_hw *hw)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       u32 val;
+
+       val = pll_readl(pll, PLL_CTRL3);
+       val |= PLL_FRAC_CTRL3_PD;
+       pll_writel(pll, val, PLL_CTRL3);
+}
+
+static int pll_gf40lp_frac_is_enabled(struct clk_hw *hw)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+
+       return !(pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_PD);
+}
+
+static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
+                                   unsigned long parent_rate)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       struct pistachio_pll_rate_table *params;
+       bool was_enabled;
+       u32 val;
+
+       params = pll_get_params(pll, parent_rate, rate);
+       if (!params)
+               return -EINVAL;
+
+       was_enabled = pll_gf40lp_frac_is_enabled(hw);
+       if (!was_enabled)
+               pll_gf40lp_frac_enable(hw);
+
+       val = pll_readl(pll, PLL_CTRL1);
+       val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
+                (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT));
+       val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
+               (params->fbdiv << PLL_CTRL1_FBDIV_SHIFT);
+       pll_writel(pll, val, PLL_CTRL1);
+
+       val = pll_readl(pll, PLL_CTRL2);
+       val &= ~((PLL_FRAC_CTRL2_FRAC_MASK << PLL_FRAC_CTRL2_FRAC_SHIFT) |
+                (PLL_FRAC_CTRL2_POSTDIV1_MASK <<
+                 PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
+                (PLL_FRAC_CTRL2_POSTDIV2_MASK <<
+                 PLL_FRAC_CTRL2_POSTDIV2_SHIFT));
+       val |= (params->frac << PLL_FRAC_CTRL2_FRAC_SHIFT) |
+               (params->postdiv1 << PLL_FRAC_CTRL2_POSTDIV1_SHIFT) |
+               (params->postdiv2 << PLL_FRAC_CTRL2_POSTDIV2_SHIFT);
+       pll_writel(pll, val, PLL_CTRL2);
+
+       while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK))
+               cpu_relax();
+
+       if (!was_enabled)
+               pll_gf40lp_frac_disable(hw);
+
+       return 0;
+}
+
+static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw,
+                                                unsigned long parent_rate)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       u32 val, prediv, fbdiv, frac, postdiv1, postdiv2;
+       u64 rate = parent_rate;
+
+       val = pll_readl(pll, PLL_CTRL1);
+       prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
+       fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
+
+       val = pll_readl(pll, PLL_CTRL2);
+       postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) &
+               PLL_FRAC_CTRL2_POSTDIV1_MASK;
+       postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) &
+               PLL_FRAC_CTRL2_POSTDIV2_MASK;
+       frac = (val >> PLL_FRAC_CTRL2_FRAC_SHIFT) & PLL_FRAC_CTRL2_FRAC_MASK;
+
+       rate *= (fbdiv << 24) + frac;
+       rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24);
+
+       return rate;
+}
+
+static struct clk_ops pll_gf40lp_frac_ops = {
+       .enable = pll_gf40lp_frac_enable,
+       .disable = pll_gf40lp_frac_disable,
+       .is_enabled = pll_gf40lp_frac_is_enabled,
+       .recalc_rate = pll_gf40lp_frac_recalc_rate,
+       .round_rate = pll_round_rate,
+       .set_rate = pll_gf40lp_frac_set_rate,
+};
+
+static struct clk_ops pll_gf40lp_frac_fixed_ops = {
+       .enable = pll_gf40lp_frac_enable,
+       .disable = pll_gf40lp_frac_disable,
+       .is_enabled = pll_gf40lp_frac_is_enabled,
+       .recalc_rate = pll_gf40lp_frac_recalc_rate,
+};
+
+static int pll_gf40lp_laint_enable(struct clk_hw *hw)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       u32 val;
+
+       val = pll_readl(pll, PLL_CTRL1);
+       val &= ~(PLL_INT_CTRL1_PD | PLL_INT_CTRL1_DSMPD |
+                PLL_INT_CTRL1_FOUTPOSTDIVPD | PLL_INT_CTRL1_FOUTVCOPD);
+       pll_writel(pll, val, PLL_CTRL1);
+
+       val = pll_readl(pll, PLL_CTRL2);
+       val &= ~PLL_INT_CTRL2_BYPASS;
+       pll_writel(pll, val, PLL_CTRL2);
+
+       return 0;
+}
+
+static void pll_gf40lp_laint_disable(struct clk_hw *hw)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       u32 val;
+
+       val = pll_readl(pll, PLL_CTRL1);
+       val |= PLL_INT_CTRL1_PD;
+       pll_writel(pll, val, PLL_CTRL1);
+}
+
+static int pll_gf40lp_laint_is_enabled(struct clk_hw *hw)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+
+       return !(pll_readl(pll, PLL_CTRL1) & PLL_INT_CTRL1_PD);
+}
+
+static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
+                                    unsigned long parent_rate)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       struct pistachio_pll_rate_table *params;
+       bool was_enabled;
+       u32 val;
+
+       params = pll_get_params(pll, parent_rate, rate);
+       if (!params)
+               return -EINVAL;
+
+       was_enabled = pll_gf40lp_laint_is_enabled(hw);
+       if (!was_enabled)
+               pll_gf40lp_laint_enable(hw);
+
+       val = pll_readl(pll, PLL_CTRL1);
+       val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) |
+                (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT) |
+                (PLL_INT_CTRL1_POSTDIV1_MASK << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
+                (PLL_INT_CTRL1_POSTDIV2_MASK << PLL_INT_CTRL1_POSTDIV2_SHIFT));
+       val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) |
+               (params->fbdiv << PLL_CTRL1_FBDIV_SHIFT) |
+               (params->postdiv1 << PLL_INT_CTRL1_POSTDIV1_SHIFT) |
+               (params->postdiv2 << PLL_INT_CTRL1_POSTDIV2_SHIFT);
+       pll_writel(pll, val, PLL_CTRL1);
+
+       while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK))
+               cpu_relax();
+
+       if (!was_enabled)
+               pll_gf40lp_laint_disable(hw);
+
+       return 0;
+}
+
+static unsigned long pll_gf40lp_laint_recalc_rate(struct clk_hw *hw,
+                                                 unsigned long parent_rate)
+{
+       struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
+       u32 val, prediv, fbdiv, postdiv1, postdiv2;
+       u64 rate = parent_rate;
+
+       val = pll_readl(pll, PLL_CTRL1);
+       prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
+       fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK;
+       postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) &
+               PLL_INT_CTRL1_POSTDIV1_MASK;
+       postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) &
+               PLL_INT_CTRL1_POSTDIV2_MASK;
+
+       rate *= fbdiv;
+       rate = do_div_round_closest(rate, prediv * postdiv1 * postdiv2);
+
+       return rate;
+}
+
+static struct clk_ops pll_gf40lp_laint_ops = {
+       .enable = pll_gf40lp_laint_enable,
+       .disable = pll_gf40lp_laint_disable,
+       .is_enabled = pll_gf40lp_laint_is_enabled,
+       .recalc_rate = pll_gf40lp_laint_recalc_rate,
+       .round_rate = pll_round_rate,
+       .set_rate = pll_gf40lp_laint_set_rate,
+};
+
+static struct clk_ops pll_gf40lp_laint_fixed_ops = {
+       .enable = pll_gf40lp_laint_enable,
+       .disable = pll_gf40lp_laint_disable,
+       .is_enabled = pll_gf40lp_laint_is_enabled,
+       .recalc_rate = pll_gf40lp_laint_recalc_rate,
+};
+
+static struct clk *pll_register(const char *name, const char *parent_name,
+                               unsigned long flags, void __iomem *base,
+                               enum pistachio_pll_type type,
+                               struct pistachio_pll_rate_table *rates,
+                               unsigned int nr_rates)
+{
+       struct pistachio_clk_pll *pll;
+       struct clk_init_data init;
+       struct clk *clk;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.flags = flags | CLK_GET_RATE_NOCACHE;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       switch (type) {
+       case PLL_GF40LP_FRAC:
+               if (rates)
+                       init.ops = &pll_gf40lp_frac_ops;
+               else
+                       init.ops = &pll_gf40lp_frac_fixed_ops;
+               break;
+       case PLL_GF40LP_LAINT:
+               if (rates)
+                       init.ops = &pll_gf40lp_laint_ops;
+               else
+                       init.ops = &pll_gf40lp_laint_fixed_ops;
+               break;
+       default:
+               pr_err("Unrecognized PLL type %u\n", type);
+               kfree(pll);
+               return ERR_PTR(-EINVAL);
+       }
+
+       pll->hw.init = &init;
+       pll->base = base;
+       pll->rates = rates;
+       pll->nr_rates = nr_rates;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
+}
+
+void pistachio_clk_register_pll(struct pistachio_clk_provider *p,
+                               struct pistachio_pll *pll,
+                               unsigned int num)
+{
+       struct clk *clk;
+       unsigned int i;
+
+       for (i = 0; i < num; i++) {
+               clk = pll_register(pll[i].name, pll[i].parent,
+                                  0, p->base + pll[i].reg_base,
+                                  pll[i].type, pll[i].rates,
+                                  pll[i].nr_rates);
+               p->clk_data.clks[pll[i].id] = clk;
+       }
+}
diff --git a/drivers/clk/pistachio/clk.c b/drivers/clk/pistachio/clk.c
new file mode 100644 (file)
index 0000000..85faa83
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk.h"
+
+struct pistachio_clk_provider *
+pistachio_clk_alloc_provider(struct device_node *node, unsigned int num_clks)
+{
+       struct pistachio_clk_provider *p;
+
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return p;
+
+       p->clk_data.clks = kcalloc(num_clks, sizeof(struct clk *), GFP_KERNEL);
+       if (!p->clk_data.clks)
+               goto free_provider;
+       p->clk_data.clk_num = num_clks;
+       p->node = node;
+       p->base = of_iomap(node, 0);
+       if (!p->base) {
+               pr_err("Failed to map clock provider registers\n");
+               goto free_clks;
+       }
+
+       return p;
+
+free_clks:
+       kfree(p->clk_data.clks);
+free_provider:
+       kfree(p);
+       return NULL;
+}
+
+void pistachio_clk_register_provider(struct pistachio_clk_provider *p)
+{
+       unsigned int i;
+
+       for (i = 0; i < p->clk_data.clk_num; i++) {
+               if (IS_ERR(p->clk_data.clks[i]))
+                       pr_warn("Failed to register clock %d: %ld\n", i,
+                               PTR_ERR(p->clk_data.clks[i]));
+       }
+
+       of_clk_add_provider(p->node, of_clk_src_onecell_get, &p->clk_data);
+}
+
+void pistachio_clk_register_gate(struct pistachio_clk_provider *p,
+                                struct pistachio_gate *gate,
+                                unsigned int num)
+{
+       struct clk *clk;
+       unsigned int i;
+
+       for (i = 0; i < num; i++) {
+               clk = clk_register_gate(NULL, gate[i].name, gate[i].parent,
+                                       CLK_SET_RATE_PARENT,
+                                       p->base + gate[i].reg, gate[i].shift,
+                                       0, NULL);
+               p->clk_data.clks[gate[i].id] = clk;
+       }
+}
+
+void pistachio_clk_register_mux(struct pistachio_clk_provider *p,
+                               struct pistachio_mux *mux,
+                               unsigned int num)
+{
+       struct clk *clk;
+       unsigned int i;
+
+       for (i = 0; i < num; i++) {
+               clk = clk_register_mux(NULL, mux[i].name, mux[i].parents,
+                                      mux[i].num_parents,
+                                      CLK_SET_RATE_NO_REPARENT,
+                                      p->base + mux[i].reg, mux[i].shift,
+                                      get_count_order(mux[i].num_parents),
+                                      0, NULL);
+               p->clk_data.clks[mux[i].id] = clk;
+       }
+}
+
+void pistachio_clk_register_div(struct pistachio_clk_provider *p,
+                               struct pistachio_div *div,
+                               unsigned int num)
+{
+       struct clk *clk;
+       unsigned int i;
+
+       for (i = 0; i < num; i++) {
+               clk = clk_register_divider(NULL, div[i].name, div[i].parent,
+                                          0, p->base + div[i].reg, 0,
+                                          div[i].width, div[i].div_flags,
+                                          NULL);
+               p->clk_data.clks[div[i].id] = clk;
+       }
+}
+
+void pistachio_clk_register_fixed_factor(struct pistachio_clk_provider *p,
+                                        struct pistachio_fixed_factor *ff,
+                                        unsigned int num)
+{
+       struct clk *clk;
+       unsigned int i;
+
+       for (i = 0; i < num; i++) {
+               clk = clk_register_fixed_factor(NULL, ff[i].name, ff[i].parent,
+                                               0, 1, ff[i].div);
+               p->clk_data.clks[ff[i].id] = clk;
+       }
+}
+
+void pistachio_clk_force_enable(struct pistachio_clk_provider *p,
+                               unsigned int *clk_ids, unsigned int num)
+{
+       unsigned int i;
+       int err;
+
+       for (i = 0; i < num; i++) {
+               struct clk *clk = p->clk_data.clks[clk_ids[i]];
+
+               if (IS_ERR(clk))
+                       continue;
+
+               err = clk_prepare_enable(clk);
+               if (err)
+                       pr_err("Failed to enable clock %s: %d\n",
+                              __clk_get_name(clk), err);
+       }
+}
diff --git a/drivers/clk/pistachio/clk.h b/drivers/clk/pistachio/clk.h
new file mode 100644 (file)
index 0000000..52fabbc
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef __PISTACHIO_CLK_H
+#define __PISTACHIO_CLK_H
+
+#include <linux/clk-provider.h>
+
+struct pistachio_gate {
+       unsigned int id;
+       unsigned long reg;
+       unsigned int shift;
+       const char *name;
+       const char *parent;
+};
+
+#define GATE(_id, _name, _pname, _reg, _shift) \
+       {                                       \
+               .id     = _id,                  \
+               .reg    = _reg,                 \
+               .shift  = _shift,               \
+               .name   = _name,                \
+               .parent = _pname,               \
+       }
+
+struct pistachio_mux {
+       unsigned int id;
+       unsigned long reg;
+       unsigned int shift;
+       unsigned int num_parents;
+       const char *name;
+       const char **parents;
+};
+
+#define PNAME(x) static const char *x[] __initconst
+
+#define MUX(_id, _name, _pnames, _reg, _shift)                 \
+       {                                                       \
+               .id             = _id,                          \
+               .reg            = _reg,                         \
+               .shift          = _shift,                       \
+               .name           = _name,                        \
+               .parents        = _pnames,                      \
+               .num_parents    = ARRAY_SIZE(_pnames)           \
+       }
+
+
+struct pistachio_div {
+       unsigned int id;
+       unsigned long reg;
+       unsigned int width;
+       unsigned int div_flags;
+       const char *name;
+       const char *parent;
+};
+
+#define DIV(_id, _name, _pname, _reg, _width)                  \
+       {                                                       \
+               .id             = _id,                          \
+               .reg            = _reg,                         \
+               .width          = _width,                       \
+               .div_flags      = 0,                            \
+               .name           = _name,                        \
+               .parent         = _pname,                       \
+       }
+
+#define DIV_F(_id, _name, _pname, _reg, _width, _div_flags)    \
+       {                                                       \
+               .id             = _id,                          \
+               .reg            = _reg,                         \
+               .width          = _width,                       \
+               .div_flags      = _div_flags,                   \
+               .name           = _name,                        \
+               .parent         = _pname,                       \
+       }
+
+struct pistachio_fixed_factor {
+       unsigned int id;
+       unsigned int div;
+       const char *name;
+       const char *parent;
+};
+
+#define FIXED_FACTOR(_id, _name, _pname, _div)                 \
+       {                                                       \
+               .id             = _id,                          \
+               .div            = _div,                         \
+               .name           = _name,                        \
+               .parent         = _pname,                       \
+       }
+
+struct pistachio_pll_rate_table {
+       unsigned long fref;
+       unsigned long fout;
+       unsigned int refdiv;
+       unsigned int fbdiv;
+       unsigned int postdiv1;
+       unsigned int postdiv2;
+       unsigned int frac;
+};
+
+enum pistachio_pll_type {
+       PLL_GF40LP_LAINT,
+       PLL_GF40LP_FRAC,
+};
+
+struct pistachio_pll {
+       unsigned int id;
+       unsigned long reg_base;
+       enum pistachio_pll_type type;
+       struct pistachio_pll_rate_table *rates;
+       unsigned int nr_rates;
+       const char *name;
+       const char *parent;
+};
+
+#define PLL(_id, _name, _pname, _type, _reg, _rates)           \
+       {                                                       \
+               .id             = _id,                          \
+               .reg_base       = _reg,                         \
+               .type           = _type,                        \
+               .rates          = _rates,                       \
+               .nr_rates       = ARRAY_SIZE(_rates),           \
+               .name           = _name,                        \
+               .parent         = _pname,                       \
+       }
+
+#define PLL_FIXED(_id, _name, _pname, _type, _reg)             \
+       {                                                       \
+               .id             = _id,                          \
+               .reg_base       = _reg,                         \
+               .type           = _type,                        \
+               .rates          = NULL,                         \
+               .nr_rates       = 0,                            \
+               .name           = _name,                        \
+               .parent         = _pname,                       \
+       }
+
+struct pistachio_clk_provider {
+       struct device_node *node;
+       void __iomem *base;
+       struct clk_onecell_data clk_data;
+};
+
+extern struct pistachio_clk_provider *
+pistachio_clk_alloc_provider(struct device_node *node, unsigned int num_clks);
+extern void pistachio_clk_register_provider(struct pistachio_clk_provider *p);
+
+extern void pistachio_clk_register_gate(struct pistachio_clk_provider *p,
+                                       struct pistachio_gate *gate,
+                                       unsigned int num);
+extern void pistachio_clk_register_mux(struct pistachio_clk_provider *p,
+                                      struct pistachio_mux *mux,
+                                      unsigned int num);
+extern void pistachio_clk_register_div(struct pistachio_clk_provider *p,
+                                      struct pistachio_div *div,
+                                      unsigned int num);
+extern void
+pistachio_clk_register_fixed_factor(struct pistachio_clk_provider *p,
+                                   struct pistachio_fixed_factor *ff,
+                                   unsigned int num);
+extern void pistachio_clk_register_pll(struct pistachio_clk_provider *p,
+                                      struct pistachio_pll *pll,
+                                      unsigned int num);
+
+extern void pistachio_clk_force_enable(struct pistachio_clk_provider *p,
+                                      unsigned int *clk_ids, unsigned int num);
+
+#endif
index a0b036c..b4ac7cf 100644 (file)
@@ -233,7 +233,7 @@ config CLKSRC_QCOM
 
 config CLKSRC_VERSATILE
        bool "ARM Versatile (Express) reference platforms clock source"
-       depends on GENERIC_SCHED_CLOCK && !ARCH_USES_GETTIMEOFFSET
+       depends on PLAT_VERSATILE && GENERIC_SCHED_CLOCK && !ARCH_USES_GETTIMEOFFSET
        select CLKSRC_OF
        default y if MFD_VEXPRESS_SYSREG
        help
index 3bd31b1..b81ed1a 100644 (file)
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
  */
+#include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/cpu.h>
 #include <linux/init.h>
@@ -133,6 +134,9 @@ static void __init __gic_clocksource_init(void)
        clocksource_register_hz(&gic_clocksource, gic_frequency);
 
        gic_clockevent_init();
+
+       /* And finally start the counter */
+       gic_start_count();
 }
 
 void __init gic_clocksource_init(unsigned int frequency)
@@ -146,11 +150,18 @@ void __init gic_clocksource_init(unsigned int frequency)
 
 static void __init gic_clocksource_of_init(struct device_node *node)
 {
+       struct clk *clk;
+
        if (WARN_ON(!gic_present || !node->parent ||
                    !of_device_is_compatible(node->parent, "mti,gic")))
                return;
 
-       if (of_property_read_u32(node, "clock-frequency", &gic_frequency)) {
+       clk = of_clk_get(node, 0);
+       if (!IS_ERR(clk)) {
+               gic_frequency = clk_get_rate(clk);
+               clk_put(clk);
+       } else if (of_property_read_u32(node, "clock-frequency",
+                                       &gic_frequency)) {
                pr_err("GIC frequency not specified.\n");
                return;
        }
index c8d260e..6de62a9 100644 (file)
@@ -60,6 +60,11 @@ config ATMEL_AIC5_IRQ
        select MULTI_IRQ_HANDLER
        select SPARSE_IRQ
 
+config BCM7038_L1_IRQ
+       bool
+       select GENERIC_IRQ_CHIP
+       select IRQ_DOMAIN
+
 config BCM7120_L2_IRQ
        bool
        select GENERIC_IRQ_CHIP
index 552a740..dda4927 100644 (file)
@@ -40,6 +40,7 @@ obj-$(CONFIG_XTENSA)                  += irq-xtensa-pic.o
 obj-$(CONFIG_XTENSA_MX)                        += irq-xtensa-mx.o
 obj-$(CONFIG_IRQ_CROSSBAR)             += irq-crossbar.o
 obj-$(CONFIG_SOC_VF610)                        += irq-vf610-mscm-ir.o
+obj-$(CONFIG_BCM7038_L1_IRQ)           += irq-bcm7038-l1.o
 obj-$(CONFIG_BCM7120_L2_IRQ)           += irq-bcm7120-l2.o
 obj-$(CONFIG_BRCMSTB_L2_IRQ)           += irq-brcmstb-l2.o
 obj-$(CONFIG_KEYSTONE_IRQ)             += irq-keystone.o
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
new file mode 100644 (file)
index 0000000..d3b8c8b
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * Broadcom BCM7038 style Level 1 interrupt controller driver
+ *
+ * Copyright (C) 2014 Broadcom Corporation
+ * Author: Kevin Cernekee
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME  ": " fmt
+
+#include <linux/bitops.h>
+#include <linux/kconfig.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+#include <linux/irqchip/chained_irq.h>
+
+#include "irqchip.h"
+
+#define IRQS_PER_WORD          32
+#define REG_BYTES_PER_IRQ_WORD (sizeof(u32) * 4)
+#define MAX_WORDS              8
+
+struct bcm7038_l1_cpu;
+
+struct bcm7038_l1_chip {
+       raw_spinlock_t          lock;
+       unsigned int            n_words;
+       struct irq_domain       *domain;
+       struct bcm7038_l1_cpu   *cpus[NR_CPUS];
+       u8                      affinity[MAX_WORDS * IRQS_PER_WORD];
+};
+
+struct bcm7038_l1_cpu {
+       void __iomem            *map_base;
+       u32                     mask_cache[0];
+};
+
+/*
+ * STATUS/MASK_STATUS/MASK_SET/MASK_CLEAR are packed one right after another:
+ *
+ * 7038:
+ *   0x1000_1400: W0_STATUS
+ *   0x1000_1404: W1_STATUS
+ *   0x1000_1408: W0_MASK_STATUS
+ *   0x1000_140c: W1_MASK_STATUS
+ *   0x1000_1410: W0_MASK_SET
+ *   0x1000_1414: W1_MASK_SET
+ *   0x1000_1418: W0_MASK_CLEAR
+ *   0x1000_141c: W1_MASK_CLEAR
+ *
+ * 7445:
+ *   0xf03e_1500: W0_STATUS
+ *   0xf03e_1504: W1_STATUS
+ *   0xf03e_1508: W2_STATUS
+ *   0xf03e_150c: W3_STATUS
+ *   0xf03e_1510: W4_STATUS
+ *   0xf03e_1514: W0_MASK_STATUS
+ *   0xf03e_1518: W1_MASK_STATUS
+ *   [...]
+ */
+
+static inline unsigned int reg_status(struct bcm7038_l1_chip *intc,
+                                     unsigned int word)
+{
+       return (0 * intc->n_words + word) * sizeof(u32);
+}
+
+static inline unsigned int reg_mask_status(struct bcm7038_l1_chip *intc,
+                                          unsigned int word)
+{
+       return (1 * intc->n_words + word) * sizeof(u32);
+}
+
+static inline unsigned int reg_mask_set(struct bcm7038_l1_chip *intc,
+                                       unsigned int word)
+{
+       return (2 * intc->n_words + word) * sizeof(u32);
+}
+
+static inline unsigned int reg_mask_clr(struct bcm7038_l1_chip *intc,
+                                       unsigned int word)
+{
+       return (3 * intc->n_words + word) * sizeof(u32);
+}
+
+static inline u32 l1_readl(void __iomem *reg)
+{
+       if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+               return ioread32be(reg);
+       else
+               return readl(reg);
+}
+
+static inline void l1_writel(u32 val, void __iomem *reg)
+{
+       if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
+               iowrite32be(val, reg);
+       else
+               writel(val, reg);
+}
+
+static void bcm7038_l1_irq_handle(unsigned int irq, struct irq_desc *desc)
+{
+       struct bcm7038_l1_chip *intc = irq_desc_get_handler_data(desc);
+       struct bcm7038_l1_cpu *cpu;
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+       unsigned int idx;
+
+#ifdef CONFIG_SMP
+       cpu = intc->cpus[cpu_logical_map(smp_processor_id())];
+#else
+       cpu = intc->cpus[0];
+#endif
+
+       chained_irq_enter(chip, desc);
+
+       for (idx = 0; idx < intc->n_words; idx++) {
+               int base = idx * IRQS_PER_WORD;
+               unsigned long pending, flags;
+               int hwirq;
+
+               raw_spin_lock_irqsave(&intc->lock, flags);
+               pending = l1_readl(cpu->map_base + reg_status(intc, idx)) &
+                         ~cpu->mask_cache[idx];
+               raw_spin_unlock_irqrestore(&intc->lock, flags);
+
+               for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
+                       generic_handle_irq(irq_find_mapping(intc->domain,
+                                                           base + hwirq));
+               }
+       }
+
+       chained_irq_exit(chip, desc);
+}
+
+static void __bcm7038_l1_unmask(struct irq_data *d, unsigned int cpu_idx)
+{
+       struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
+       u32 word = d->hwirq / IRQS_PER_WORD;
+       u32 mask = BIT(d->hwirq % IRQS_PER_WORD);
+
+       intc->cpus[cpu_idx]->mask_cache[word] &= ~mask;
+       l1_writel(mask, intc->cpus[cpu_idx]->map_base +
+                       reg_mask_clr(intc, word));
+}
+
+static void __bcm7038_l1_mask(struct irq_data *d, unsigned int cpu_idx)
+{
+       struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
+       u32 word = d->hwirq / IRQS_PER_WORD;
+       u32 mask = BIT(d->hwirq % IRQS_PER_WORD);
+
+       intc->cpus[cpu_idx]->mask_cache[word] |= mask;
+       l1_writel(mask, intc->cpus[cpu_idx]->map_base +
+                       reg_mask_set(intc, word));
+}
+
+static void bcm7038_l1_unmask(struct irq_data *d)
+{
+       struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&intc->lock, flags);
+       __bcm7038_l1_unmask(d, intc->affinity[d->hwirq]);
+       raw_spin_unlock_irqrestore(&intc->lock, flags);
+}
+
+static void bcm7038_l1_mask(struct irq_data *d)
+{
+       struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&intc->lock, flags);
+       __bcm7038_l1_mask(d, intc->affinity[d->hwirq]);
+       raw_spin_unlock_irqrestore(&intc->lock, flags);
+}
+
+static int bcm7038_l1_set_affinity(struct irq_data *d,
+                                  const struct cpumask *dest,
+                                  bool force)
+{
+       struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d);
+       unsigned long flags;
+       irq_hw_number_t hw = d->hwirq;
+       u32 word = hw / IRQS_PER_WORD;
+       u32 mask = BIT(hw % IRQS_PER_WORD);
+       unsigned int first_cpu = cpumask_any_and(dest, cpu_online_mask);
+       bool was_disabled;
+
+       raw_spin_lock_irqsave(&intc->lock, flags);
+
+       was_disabled = !!(intc->cpus[intc->affinity[hw]]->mask_cache[word] &
+                         mask);
+       __bcm7038_l1_mask(d, intc->affinity[hw]);
+       intc->affinity[hw] = first_cpu;
+       if (!was_disabled)
+               __bcm7038_l1_unmask(d, first_cpu);
+
+       raw_spin_unlock_irqrestore(&intc->lock, flags);
+       return 0;
+}
+
+static int __init bcm7038_l1_init_one(struct device_node *dn,
+                                     unsigned int idx,
+                                     struct bcm7038_l1_chip *intc)
+{
+       struct resource res;
+       resource_size_t sz;
+       struct bcm7038_l1_cpu *cpu;
+       unsigned int i, n_words, parent_irq;
+
+       if (of_address_to_resource(dn, idx, &res))
+               return -EINVAL;
+       sz = resource_size(&res);
+       n_words = sz / REG_BYTES_PER_IRQ_WORD;
+
+       if (n_words > MAX_WORDS)
+               return -EINVAL;
+       else if (!intc->n_words)
+               intc->n_words = n_words;
+       else if (intc->n_words != n_words)
+               return -EINVAL;
+
+       cpu = intc->cpus[idx] = kzalloc(sizeof(*cpu) + n_words * sizeof(u32),
+                                       GFP_KERNEL);
+       if (!cpu)
+               return -ENOMEM;
+
+       cpu->map_base = ioremap(res.start, sz);
+       if (!cpu->map_base)
+               return -ENOMEM;
+
+       for (i = 0; i < n_words; i++) {
+               l1_writel(0xffffffff, cpu->map_base + reg_mask_set(intc, i));
+               cpu->mask_cache[i] = 0xffffffff;
+       }
+
+       parent_irq = irq_of_parse_and_map(dn, idx);
+       if (!parent_irq) {
+               pr_err("failed to map parent interrupt %d\n", parent_irq);
+               return -EINVAL;
+       }
+       irq_set_handler_data(parent_irq, intc);
+       irq_set_chained_handler(parent_irq, bcm7038_l1_irq_handle);
+
+       return 0;
+}
+
+static struct irq_chip bcm7038_l1_irq_chip = {
+       .name                   = "bcm7038-l1",
+       .irq_mask               = bcm7038_l1_mask,
+       .irq_unmask             = bcm7038_l1_unmask,
+       .irq_set_affinity       = bcm7038_l1_set_affinity,
+};
+
+static int bcm7038_l1_map(struct irq_domain *d, unsigned int virq,
+                         irq_hw_number_t hw_irq)
+{
+       irq_set_chip_and_handler(virq, &bcm7038_l1_irq_chip, handle_level_irq);
+       irq_set_chip_data(virq, d->host_data);
+       return 0;
+}
+
+static const struct irq_domain_ops bcm7038_l1_domain_ops = {
+       .xlate                  = irq_domain_xlate_onecell,
+       .map                    = bcm7038_l1_map,
+};
+
+int __init bcm7038_l1_of_init(struct device_node *dn,
+                             struct device_node *parent)
+{
+       struct bcm7038_l1_chip *intc;
+       int idx, ret;
+
+       intc = kzalloc(sizeof(*intc), GFP_KERNEL);
+       if (!intc)
+               return -ENOMEM;
+
+       raw_spin_lock_init(&intc->lock);
+       for_each_possible_cpu(idx) {
+               ret = bcm7038_l1_init_one(dn, idx, intc);
+               if (ret < 0) {
+                       if (idx)
+                               break;
+                       pr_err("failed to remap intc L1 registers\n");
+                       goto out_free;
+               }
+       }
+
+       intc->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * intc->n_words,
+                                            &bcm7038_l1_domain_ops,
+                                            intc);
+       if (!intc->domain) {
+               ret = -ENOMEM;
+               goto out_unmap;
+       }
+
+       pr_info("registered BCM7038 L1 intc (mem: 0x%p, IRQs: %d)\n",
+               intc->cpus[0]->map_base, IRQS_PER_WORD * intc->n_words);
+
+       return 0;
+
+out_unmap:
+       for_each_possible_cpu(idx) {
+               struct bcm7038_l1_cpu *cpu = intc->cpus[idx];
+
+               if (cpu) {
+                       if (cpu->map_base)
+                               iounmap(cpu->map_base);
+                       kfree(cpu);
+               }
+       }
+out_free:
+       kfree(intc);
+       return ret;
+}
+
+IRQCHIP_DECLARE(bcm7038_l1, "brcm,bcm7038-l1-intc", bcm7038_l1_of_init);
index 8eec8e1..3ba5cc7 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kconfig.h>
+#include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #define IRQSTAT                0x04
 
 #define MAX_WORDS      4
+#define MAX_MAPPINGS   (MAX_WORDS * 2)
 #define IRQS_PER_WORD  32
 
 struct bcm7120_l2_intc_data {
        unsigned int n_words;
-       void __iomem *base[MAX_WORDS];
+       void __iomem *map_base[MAX_MAPPINGS];
+       void __iomem *pair_base[MAX_WORDS];
+       int en_offset[MAX_WORDS];
+       int stat_offset[MAX_WORDS];
        struct irq_domain *domain;
        bool can_wake;
        u32 irq_fwd_mask[MAX_WORDS];
        u32 irq_map_mask[MAX_WORDS];
+       int num_parent_irqs;
+       const __be32 *map_mask_prop;
 };
 
 static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
@@ -61,7 +68,8 @@ static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
                int hwirq;
 
                irq_gc_lock(gc);
-               pending = irq_reg_readl(gc, IRQSTAT) & gc->mask_cache;
+               pending = irq_reg_readl(gc, b->stat_offset[idx]) &
+                                           gc->mask_cache;
                irq_gc_unlock(gc);
 
                for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
@@ -76,27 +84,30 @@ static void bcm7120_l2_intc_irq_handle(unsigned int irq, struct irq_desc *desc)
 static void bcm7120_l2_intc_suspend(struct irq_data *d)
 {
        struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
        struct bcm7120_l2_intc_data *b = gc->private;
 
        irq_gc_lock(gc);
        if (b->can_wake)
-               irq_reg_writel(gc, gc->mask_cache | gc->wake_active, IRQEN);
+               irq_reg_writel(gc, gc->mask_cache | gc->wake_active,
+                              ct->regs.mask);
        irq_gc_unlock(gc);
 }
 
 static void bcm7120_l2_intc_resume(struct irq_data *d)
 {
        struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+       struct irq_chip_type *ct = irq_data_get_chip_type(d);
 
        /* Restore the saved mask */
        irq_gc_lock(gc);
-       irq_reg_writel(gc, gc->mask_cache, IRQEN);
+       irq_reg_writel(gc, gc->mask_cache, ct->regs.mask);
        irq_gc_unlock(gc);
 }
 
 static int bcm7120_l2_intc_init_one(struct device_node *dn,
                                        struct bcm7120_l2_intc_data *data,
-                                       int irq, const __be32 *map_mask)
+                                       int irq)
 {
        int parent_irq;
        unsigned int idx;
@@ -110,9 +121,15 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
        /* For multiple parent IRQs with multiple words, this looks like:
         * <irq0_w0 irq0_w1 irq1_w0 irq1_w1 ...>
         */
-       for (idx = 0; idx < data->n_words; idx++)
-               data->irq_map_mask[idx] |=
-                       be32_to_cpup(map_mask + irq * data->n_words + idx);
+       for (idx = 0; idx < data->n_words; idx++) {
+               if (data->map_mask_prop) {
+                       data->irq_map_mask[idx] |=
+                               be32_to_cpup(data->map_mask_prop +
+                                            irq * data->n_words + idx);
+               } else {
+                       data->irq_map_mask[idx] = 0xffffffff;
+               }
+       }
 
        irq_set_handler_data(parent_irq, data);
        irq_set_chained_handler(parent_irq, bcm7120_l2_intc_irq_handle);
@@ -120,68 +137,107 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn,
        return 0;
 }
 
-int __init bcm7120_l2_intc_of_init(struct device_node *dn,
-                                       struct device_node *parent)
+static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn,
+                                            struct bcm7120_l2_intc_data *data)
+{
+       int ret;
+
+       data->map_base[0] = of_iomap(dn, 0);
+       if (!data->map_base[0]) {
+               pr_err("unable to map registers\n");
+               return -ENOMEM;
+       }
+
+       data->pair_base[0] = data->map_base[0];
+       data->en_offset[0] = IRQEN;
+       data->stat_offset[0] = IRQSTAT;
+       data->n_words = 1;
+
+       ret = of_property_read_u32_array(dn, "brcm,int-fwd-mask",
+                                        data->irq_fwd_mask, data->n_words);
+       if (ret != 0 && ret != -EINVAL) {
+               /* property exists but has the wrong number of words */
+               pr_err("invalid brcm,int-fwd-mask property\n");
+               return -EINVAL;
+       }
+
+       data->map_mask_prop = of_get_property(dn, "brcm,int-map-mask", &ret);
+       if (!data->map_mask_prop ||
+           (ret != (sizeof(__be32) * data->num_parent_irqs * data->n_words))) {
+               pr_err("invalid brcm,int-map-mask property\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn,
+                                            struct bcm7120_l2_intc_data *data)
+{
+       unsigned int gc_idx;
+
+       for (gc_idx = 0; gc_idx < MAX_WORDS; gc_idx++) {
+               unsigned int map_idx = gc_idx * 2;
+               void __iomem *en = of_iomap(dn, map_idx + 0);
+               void __iomem *stat = of_iomap(dn, map_idx + 1);
+               void __iomem *base = min(en, stat);
+
+               data->map_base[map_idx + 0] = en;
+               data->map_base[map_idx + 1] = stat;
+
+               if (!base)
+                       break;
+
+               data->pair_base[gc_idx] = base;
+               data->en_offset[gc_idx] = en - base;
+               data->stat_offset[gc_idx] = stat - base;
+       }
+
+       if (!gc_idx) {
+               pr_err("unable to map registers\n");
+               return -EINVAL;
+       }
+
+       data->n_words = gc_idx;
+       return 0;
+}
+
+int __init bcm7120_l2_intc_probe(struct device_node *dn,
+                                struct device_node *parent,
+                                int (*iomap_regs_fn)(struct device_node *,
+                                       struct bcm7120_l2_intc_data *),
+                                const char *intc_name)
 {
        unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
        struct bcm7120_l2_intc_data *data;
        struct irq_chip_generic *gc;
        struct irq_chip_type *ct;
-       const __be32 *map_mask;
-       int num_parent_irqs;
-       int ret = 0, len;
+       int ret = 0;
        unsigned int idx, irq, flags;
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
-       for (idx = 0; idx < MAX_WORDS; idx++) {
-               data->base[idx] = of_iomap(dn, idx);
-               if (!data->base[idx])
-                       break;
-               data->n_words = idx + 1;
-       }
-       if (!data->n_words) {
-               pr_err("failed to remap intc L2 registers\n");
-               ret = -ENOMEM;
-               goto out_unmap;
-       }
-
-       /* Enable all interrupts specified in the interrupt forward mask;
-        * disable all others.  If the property doesn't exist (-EINVAL),
-        * assume all zeroes.
-        */
-       ret = of_property_read_u32_array(dn, "brcm,int-fwd-mask",
-                                        data->irq_fwd_mask, data->n_words);
-       if (ret == 0 || ret == -EINVAL) {
-               for (idx = 0; idx < data->n_words; idx++)
-                       __raw_writel(data->irq_fwd_mask[idx],
-                                    data->base[idx] + IRQEN);
-       } else {
-               /* property exists but has the wrong number of words */
-               pr_err("invalid int-fwd-mask property\n");
-               ret = -EINVAL;
-               goto out_unmap;
-       }
-
-       num_parent_irqs = of_irq_count(dn);
-       if (num_parent_irqs <= 0) {
+       data->num_parent_irqs = of_irq_count(dn);
+       if (data->num_parent_irqs <= 0) {
                pr_err("invalid number of parent interrupts\n");
                ret = -ENOMEM;
                goto out_unmap;
        }
 
-       map_mask = of_get_property(dn, "brcm,int-map-mask", &len);
-       if (!map_mask ||
-           (len != (sizeof(*map_mask) * num_parent_irqs * data->n_words))) {
-               pr_err("invalid brcm,int-map-mask property\n");
-               ret = -EINVAL;
+       ret = iomap_regs_fn(dn, data);
+       if (ret < 0)
                goto out_unmap;
+
+       for (idx = 0; idx < data->n_words; idx++) {
+               __raw_writel(data->irq_fwd_mask[idx],
+                            data->pair_base[idx] +
+                            data->en_offset[idx]);
        }
 
-       for (irq = 0; irq < num_parent_irqs; irq++) {
-               ret = bcm7120_l2_intc_init_one(dn, data, irq, map_mask);
+       for (irq = 0; irq < data->num_parent_irqs; irq++) {
+               ret = bcm7120_l2_intc_init_one(dn, data, irq);
                if (ret)
                        goto out_unmap;
        }
@@ -215,11 +271,12 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
                gc = irq_get_domain_generic_chip(data->domain, irq);
 
                gc->unused = 0xffffffff & ~data->irq_map_mask[idx];
-               gc->reg_base = data->base[idx];
                gc->private = data;
                ct = gc->chip_types;
 
-               ct->regs.mask = IRQEN;
+               gc->reg_base = data->pair_base[idx];
+               ct->regs.mask = data->en_offset[idx];
+
                ct->chip.irq_mask = irq_gc_mask_clr_bit;
                ct->chip.irq_unmask = irq_gc_mask_set_bit;
                ct->chip.irq_ack = irq_gc_noop;
@@ -236,20 +293,38 @@ int __init bcm7120_l2_intc_of_init(struct device_node *dn,
                }
        }
 
-       pr_info("registered BCM7120 L2 intc (mem: 0x%p, parent IRQ(s): %d)\n",
-                       data->base[0], num_parent_irqs);
+       pr_info("registered %s intc (mem: 0x%p, parent IRQ(s): %d)\n",
+                       intc_name, data->map_base[0], data->num_parent_irqs);
 
        return 0;
 
 out_free_domain:
        irq_domain_remove(data->domain);
 out_unmap:
-       for (idx = 0; idx < MAX_WORDS; idx++) {
-               if (data->base[idx])
-                       iounmap(data->base[idx]);
+       for (idx = 0; idx < MAX_MAPPINGS; idx++) {
+               if (data->map_base[idx])
+                       iounmap(data->map_base[idx]);
        }
        kfree(data);
        return ret;
 }
+
+int __init bcm7120_l2_intc_probe_7120(struct device_node *dn,
+                                     struct device_node *parent)
+{
+       return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120,
+                                    "BCM7120 L2");
+}
+
+int __init bcm7120_l2_intc_probe_3380(struct device_node *dn,
+                                     struct device_node *parent)
+{
+       return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380,
+                                    "BCM3380 L2");
+}
+
 IRQCHIP_DECLARE(bcm7120_l2_intc, "brcm,bcm7120-l2-intc",
-               bcm7120_l2_intc_of_init);
+               bcm7120_l2_intc_probe_7120);
+
+IRQCHIP_DECLARE(bcm3380_l2_intc, "brcm,bcm3380-l2-intc",
+               bcm7120_l2_intc_probe_3380);
index 313c2c6..d6bcc6b 100644 (file)
@@ -136,7 +136,11 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
 
        /* Disable all interrupts by default */
        writel(0xffffffff, data->base + CPU_MASK_SET);
-       writel(0xffffffff, data->base + CPU_CLEAR);
+
+       /* Wakeup interrupts may be retained from S5 (cold boot) */
+       data->can_wake = of_property_read_bool(np, "brcm,irq-can-wake");
+       if (!data->can_wake)
+               writel(0xffffffff, data->base + CPU_CLEAR);
 
        data->parent_irq = irq_of_parse_and_map(np, 0);
        if (!data->parent_irq) {
@@ -188,8 +192,7 @@ int __init brcmstb_l2_intc_of_init(struct device_node *np,
        ct->chip.irq_suspend = brcmstb_l2_intc_suspend;
        ct->chip.irq_resume = brcmstb_l2_intc_resume;
 
-       if (of_property_read_bool(np, "brcm,irq-can-wake")) {
-               data->can_wake = true;
+       if (data->can_wake) {
                /* This IRQ chip can wake the system, set all child interrupts
                 * in wake_enabled mask
                 */
index f2d269b..bc48b7d 100644 (file)
@@ -239,7 +239,7 @@ int gic_get_c0_compare_int(void)
 int gic_get_c0_perfcount_int(void)
 {
        if (!gic_local_irq_is_routable(GIC_LOCAL_INT_PERFCTR)) {
-               /* Is the erformance counter shared with the timer? */
+               /* Is the performance counter shared with the timer? */
                if (cp0_perfcount_irq < 0)
                        return -1;
                return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
@@ -248,6 +248,29 @@ int gic_get_c0_perfcount_int(void)
                                  GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_PERFCTR));
 }
 
+int gic_get_c0_fdc_int(void)
+{
+       if (!gic_local_irq_is_routable(GIC_LOCAL_INT_FDC)) {
+               /* Is the FDC IRQ even present? */
+               if (cp0_fdc_irq < 0)
+                       return -1;
+               return MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
+       }
+
+       /*
+        * Some cores claim the FDC is routable but it doesn't actually seem to
+        * be connected.
+        */
+       switch (current_cpu_type()) {
+       case CPU_INTERAPTIV:
+       case CPU_PROAPTIV:
+               return -1;
+       }
+
+       return irq_create_mapping(gic_irq_domain,
+                                 GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_FDC));
+}
+
 static void gic_handle_shared_int(void)
 {
        unsigned int i, intr, virq;
@@ -613,15 +636,20 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
         * of the MIPS kernel code does not use the percpu IRQ API for
         * the CP0 timer and performance counter interrupts.
         */
-       if (intr != GIC_LOCAL_INT_TIMER && intr != GIC_LOCAL_INT_PERFCTR) {
+       switch (intr) {
+       case GIC_LOCAL_INT_TIMER:
+       case GIC_LOCAL_INT_PERFCTR:
+       case GIC_LOCAL_INT_FDC:
+               irq_set_chip_and_handler(virq,
+                                        &gic_all_vpes_local_irq_controller,
+                                        handle_percpu_irq);
+               break;
+       default:
                irq_set_chip_and_handler(virq,
                                         &gic_local_irq_controller,
                                         handle_percpu_devid_irq);
                irq_set_percpu_devid(virq);
-       } else {
-               irq_set_chip_and_handler(virq,
-                                        &gic_all_vpes_local_irq_controller,
-                                        handle_percpu_irq);
+               break;
        }
 
        spin_lock_irqsave(&gic_lock, flags);
index bd5916a..77363d6 100644 (file)
@@ -400,7 +400,7 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
 }
 
 #ifdef CONFIG_BCM47XX
-#include <bcm47xx_nvram.h>
+#include <linux/bcm47xx_nvram.h>
 static void b44_wap54g10_workaround(struct b44 *bp)
 {
        char buf[20];
index 5cb93d1..de77d3a 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/phy_fixed.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
-#include <bcm47xx_nvram.h>
+#include <linux/bcm47xx_nvram.h>
 
 static const struct bcma_device_id bgmac_bcma_tbl[] = {
        BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_4706_MAC_GBIT, BCMA_ANY_REV, BCMA_ANY_CLASS),
index 09fde58..0adccbf 100644 (file)
@@ -1,6 +1,9 @@
 if X86
 source "drivers/platform/x86/Kconfig"
 endif
+if MIPS
+source "drivers/platform/mips/Kconfig"
+endif
 if GOLDFISH
 source "drivers/platform/goldfish/Kconfig"
 endif
index 3656b7b..ca26925 100644 (file)
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_X86)              += x86/
+obj-$(CONFIG_MIPS)             += mips/
 obj-$(CONFIG_OLPC)             += olpc/
 obj-$(CONFIG_GOLDFISH)         += goldfish/
 obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
diff --git a/drivers/platform/mips/Kconfig b/drivers/platform/mips/Kconfig
new file mode 100644 (file)
index 0000000..125e569
--- /dev/null
@@ -0,0 +1,30 @@
+#
+# MIPS Platform Specific Drivers
+#
+
+menuconfig MIPS_PLATFORM_DEVICES
+       bool "MIPS Platform Specific Device Drivers"
+       default y
+       help
+         Say Y here to get to see options for device drivers of various
+         MIPS platforms, including vendor-specific netbook/laptop/desktop
+         extension and hardware monitor drivers. This option itself does
+         not add any kernel code.
+
+         If you say N, all options in this submenu will be skipped and disabled.
+
+if MIPS_PLATFORM_DEVICES
+
+config MIPS_ACPI
+       bool
+       default y if LOONGSON_MACH3X
+
+config CPU_HWMON
+       tristate "Loongson CPU HWMon Driver"
+       depends on LOONGSON_MACH3X
+       select HWMON
+       default y
+       help
+         Loongson-3A/3B CPU Hwmon (temperature sensor) driver.
+
+endif # MIPS_PLATFORM_DEVICES
diff --git a/drivers/platform/mips/Makefile b/drivers/platform/mips/Makefile
new file mode 100644 (file)
index 0000000..4341284
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MIPS_ACPI) += acpi_init.o
+obj-$(CONFIG_CPU_HWMON) += cpu_hwmon.o
diff --git a/drivers/platform/mips/acpi_init.c b/drivers/platform/mips/acpi_init.c
new file mode 100644 (file)
index 0000000..dbdad79
--- /dev/null
@@ -0,0 +1,150 @@
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/export.h>
+
+#define SBX00_ACPI_IO_BASE 0x800
+#define SBX00_ACPI_IO_SIZE 0x100
+
+#define ACPI_PM_EVT_BLK         (SBX00_ACPI_IO_BASE + 0x00) /* 4 bytes */
+#define ACPI_PM_CNT_BLK         (SBX00_ACPI_IO_BASE + 0x04) /* 2 bytes */
+#define ACPI_PMA_CNT_BLK        (SBX00_ACPI_IO_BASE + 0x0F) /* 1 byte */
+#define ACPI_PM_TMR_BLK         (SBX00_ACPI_IO_BASE + 0x18) /* 4 bytes */
+#define ACPI_GPE0_BLK           (SBX00_ACPI_IO_BASE + 0x10) /* 8 bytes */
+#define ACPI_END                (SBX00_ACPI_IO_BASE + 0x80)
+
+#define PM_INDEX        0xCD6
+#define PM_DATA         0xCD7
+#define PM2_INDEX       0xCD0
+#define PM2_DATA        0xCD1
+
+/*
+ * SCI interrupt need acpi space, allocate here
+ */
+
+static int __init register_acpi_resource(void)
+{
+       request_region(SBX00_ACPI_IO_BASE, SBX00_ACPI_IO_SIZE, "acpi");
+       return 0;
+}
+
+static void pmio_write_index(u16 index, u8 reg, u8 value)
+{
+       outb(reg, index);
+       outb(value, index + 1);
+}
+
+static u8 pmio_read_index(u16 index, u8 reg)
+{
+       outb(reg, index);
+       return inb(index + 1);
+}
+
+void pm_iowrite(u8 reg, u8 value)
+{
+       pmio_write_index(PM_INDEX, reg, value);
+}
+EXPORT_SYMBOL(pm_iowrite);
+
+u8 pm_ioread(u8 reg)
+{
+       return pmio_read_index(PM_INDEX, reg);
+}
+EXPORT_SYMBOL(pm_ioread);
+
+void pm2_iowrite(u8 reg, u8 value)
+{
+       pmio_write_index(PM2_INDEX, reg, value);
+}
+EXPORT_SYMBOL(pm2_iowrite);
+
+u8 pm2_ioread(u8 reg)
+{
+       return pmio_read_index(PM2_INDEX, reg);
+}
+EXPORT_SYMBOL(pm2_ioread);
+
+static void acpi_hw_clear_status(void)
+{
+       u16 value;
+
+       /* PMStatus: Clear WakeStatus/PwrBtnStatus */
+       value = inw(ACPI_PM_EVT_BLK);
+       value |= (1 << 8 | 1 << 15);
+       outw(value, ACPI_PM_EVT_BLK);
+
+       /* GPEStatus: Clear all generated events */
+       outl(inl(ACPI_GPE0_BLK), ACPI_GPE0_BLK);
+}
+
+void acpi_registers_setup(void)
+{
+       u32 value;
+
+       /* PM Status Base */
+       pm_iowrite(0x20, ACPI_PM_EVT_BLK & 0xff);
+       pm_iowrite(0x21, ACPI_PM_EVT_BLK >> 8);
+
+       /* PM Control Base */
+       pm_iowrite(0x22, ACPI_PM_CNT_BLK & 0xff);
+       pm_iowrite(0x23, ACPI_PM_CNT_BLK >> 8);
+
+       /* GPM Base */
+       pm_iowrite(0x28, ACPI_GPE0_BLK & 0xff);
+       pm_iowrite(0x29, ACPI_GPE0_BLK >> 8);
+
+       /* ACPI End */
+       pm_iowrite(0x2e, ACPI_END & 0xff);
+       pm_iowrite(0x2f, ACPI_END >> 8);
+
+       /* IO Decode: When AcpiDecodeEnable set, South-Bridge uses the contents
+        * of the PM registers at index 0x20~0x2B to decode ACPI I/O address. */
+       pm_iowrite(0x0e, 1 << 3);
+
+       /* SCI_EN set */
+       outw(1, ACPI_PM_CNT_BLK);
+
+       /* Enable to generate SCI */
+       pm_iowrite(0x10, pm_ioread(0x10) | 1);
+
+       /* GPM3/GPM9 enable */
+       value = inl(ACPI_GPE0_BLK + 4);
+       outl(value | (1 << 14) | (1 << 22), ACPI_GPE0_BLK + 4);
+
+       /* Set GPM9 as input */
+       pm_iowrite(0x8d, pm_ioread(0x8d) & (~(1 << 1)));
+
+       /* Set GPM9 as non-output */
+       pm_iowrite(0x94, pm_ioread(0x94) | (1 << 3));
+
+       /* GPM3 config ACPI trigger SCIOUT */
+       pm_iowrite(0x33, pm_ioread(0x33) & (~(3 << 4)));
+
+       /* GPM9 config ACPI trigger SCIOUT */
+       pm_iowrite(0x3d, pm_ioread(0x3d) & (~(3 << 2)));
+
+       /* GPM3 config falling edge trigger */
+       pm_iowrite(0x37, pm_ioread(0x37) & (~(1 << 6)));
+
+       /* No wait for STPGNT# in ACPI Sx state */
+       pm_iowrite(0x7c, pm_ioread(0x7c) | (1 << 6));
+
+       /* Set GPM3 pull-down enable */
+       value = pm2_ioread(0xf6);
+       value |= ((1 << 7) | (1 << 3));
+       pm2_iowrite(0xf6, value);
+
+       /* Set GPM9 pull-down enable */
+       value = pm2_ioread(0xf8);
+       value |= ((1 << 5) | (1 << 1));
+       pm2_iowrite(0xf8, value);
+}
+
+int __init sbx00_acpi_init(void)
+{
+       register_acpi_resource();
+       acpi_registers_setup();
+       acpi_hw_clear_status();
+
+       return 0;
+}
diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c
new file mode 100644 (file)
index 0000000..0f6c63e
--- /dev/null
@@ -0,0 +1,207 @@
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/jiffies.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+#include <loongson.h>
+#include <boot_param.h>
+#include <loongson_hwmon.h>
+
+/*
+ * Loongson-3 series cpu has two sensors inside,
+ * each of them from 0 to 255,
+ * if more than 127, that is dangerous.
+ * here only provide sensor1 data, because it always hot than sensor0
+ */
+int loongson3_cpu_temp(int cpu)
+{
+       u32 reg;
+
+       reg = LOONGSON_CHIPTEMP(cpu);
+       if (loongson_sysconf.cputype == Loongson_3A)
+               reg = (reg >> 8) & 0xff;
+       else if (loongson_sysconf.cputype == Loongson_3B)
+               reg = ((reg >> 8) & 0xff) - 100;
+
+       return (int)reg * 1000;
+}
+
+static struct device *cpu_hwmon_dev;
+
+static ssize_t get_hwmon_name(struct device *dev,
+                       struct device_attribute *attr, char *buf);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, get_hwmon_name, NULL, 0);
+
+static struct attribute *cpu_hwmon_attributes[] = {
+       &sensor_dev_attr_name.dev_attr.attr,
+       NULL
+};
+
+/* Hwmon device attribute group */
+static struct attribute_group cpu_hwmon_attribute_group = {
+       .attrs = cpu_hwmon_attributes,
+};
+
+/* Hwmon device get name */
+static ssize_t get_hwmon_name(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "cpu-hwmon\n");
+}
+
+static ssize_t get_cpu0_temp(struct device *dev,
+                       struct device_attribute *attr, char *buf);
+static ssize_t get_cpu1_temp(struct device *dev,
+                       struct device_attribute *attr, char *buf);
+static ssize_t cpu0_temp_label(struct device *dev,
+                       struct device_attribute *attr, char *buf);
+static ssize_t cpu1_temp_label(struct device *dev,
+                       struct device_attribute *attr, char *buf);
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu0_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu0_temp_label, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu1_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu1_temp_label, NULL, 2);
+
+static const struct attribute *hwmon_cputemp1[] = {
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_label.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute *hwmon_cputemp2[] = {
+       &sensor_dev_attr_temp2_input.dev_attr.attr,
+       &sensor_dev_attr_temp2_label.dev_attr.attr,
+       NULL
+};
+
+static ssize_t cpu0_temp_label(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "CPU 0 Temprature\n");
+}
+
+static ssize_t cpu1_temp_label(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "CPU 1 Temprature\n");
+}
+
+static ssize_t get_cpu0_temp(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       int value = loongson3_cpu_temp(0);
+       return sprintf(buf, "%d\n", value);
+}
+
+static ssize_t get_cpu1_temp(struct device *dev,
+                       struct device_attribute *attr, char *buf)
+{
+       int value = loongson3_cpu_temp(1);
+       return sprintf(buf, "%d\n", value);
+}
+
+static int create_sysfs_cputemp_files(struct kobject *kobj)
+{
+       int ret;
+
+       ret = sysfs_create_files(kobj, hwmon_cputemp1);
+       if (ret)
+               goto sysfs_create_temp1_fail;
+
+       if (loongson_sysconf.nr_cpus <= loongson_sysconf.cores_per_package)
+               return 0;
+
+       ret = sysfs_create_files(kobj, hwmon_cputemp2);
+       if (ret)
+               goto sysfs_create_temp2_fail;
+
+       return 0;
+
+sysfs_create_temp2_fail:
+       sysfs_remove_files(kobj, hwmon_cputemp1);
+
+sysfs_create_temp1_fail:
+       return -1;
+}
+
+static void remove_sysfs_cputemp_files(struct kobject *kobj)
+{
+       sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp1);
+
+       if (loongson_sysconf.nr_cpus > loongson_sysconf.cores_per_package)
+               sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp2);
+}
+
+#define CPU_THERMAL_THRESHOLD 90000
+static struct delayed_work thermal_work;
+
+static void do_thermal_timer(struct work_struct *work)
+{
+       int value = loongson3_cpu_temp(0);
+       if (value <= CPU_THERMAL_THRESHOLD)
+               schedule_delayed_work(&thermal_work, msecs_to_jiffies(5000));
+       else
+               orderly_poweroff(true);
+}
+
+static int __init loongson_hwmon_init(void)
+{
+       int ret;
+
+       pr_info("Loongson Hwmon Enter...\n");
+
+       cpu_hwmon_dev = hwmon_device_register(NULL);
+       if (IS_ERR(cpu_hwmon_dev)) {
+               ret = -ENOMEM;
+               pr_err("hwmon_device_register fail!\n");
+               goto fail_hwmon_device_register;
+       }
+
+       ret = sysfs_create_group(&cpu_hwmon_dev->kobj,
+                               &cpu_hwmon_attribute_group);
+       if (ret) {
+               pr_err("fail to create loongson hwmon!\n");
+               goto fail_sysfs_create_group_hwmon;
+       }
+
+       ret = create_sysfs_cputemp_files(&cpu_hwmon_dev->kobj);
+       if (ret) {
+               pr_err("fail to create cpu temprature interface!\n");
+               goto fail_create_sysfs_cputemp_files;
+       }
+
+       INIT_DEFERRABLE_WORK(&thermal_work, do_thermal_timer);
+       schedule_delayed_work(&thermal_work, msecs_to_jiffies(20000));
+
+       return ret;
+
+fail_create_sysfs_cputemp_files:
+       sysfs_remove_group(&cpu_hwmon_dev->kobj,
+                               &cpu_hwmon_attribute_group);
+
+fail_sysfs_create_group_hwmon:
+       hwmon_device_unregister(cpu_hwmon_dev);
+
+fail_hwmon_device_register:
+       return ret;
+}
+
+static void __exit loongson_hwmon_exit(void)
+{
+       cancel_delayed_work_sync(&thermal_work);
+       remove_sysfs_cputemp_files(&cpu_hwmon_dev->kobj);
+       sysfs_remove_group(&cpu_hwmon_dev->kobj,
+                               &cpu_hwmon_attribute_group);
+       hwmon_device_unregister(cpu_hwmon_dev);
+}
+
+module_init(loongson_hwmon_init);
+module_exit(loongson_hwmon_exit);
+
+MODULE_AUTHOR("Yu Xiang <xiangy@lemote.com>");
+MODULE_AUTHOR("Huacai Chen <chenhc@lemote.com>");
+MODULE_DESCRIPTION("Loongson CPU Hwmon driver");
+MODULE_LICENSE("GPL");
index 75b3603..f0d22cd 100644 (file)
@@ -130,6 +130,7 @@ config SSB_DRIVER_MIPS
        bool "SSB Broadcom MIPS core driver"
        depends on SSB && MIPS
        select SSB_SERIAL
+       select SSB_SFLASH
        help
          Driver for the Sonics Silicon Backplane attached
          Broadcom MIPS core.
index 1173a09..0942841 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/delay.h>
 #include <linux/export.h>
 #ifdef CONFIG_BCM47XX
-#include <bcm47xx_nvram.h>
+#include <linux/bcm47xx_nvram.h>
 #endif
 
 #include "ssb_private.h"
index 7b986f9..f87efef 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/serial_reg.h>
 #include <linux/time.h>
 #ifdef CONFIG_BCM47XX
-#include <bcm47xx_nvram.h>
+#include <linux/bcm47xx_nvram.h>
 #endif
 
 #include "ssb_private.h"
index b7a7854..5b9ac1f 100644 (file)
@@ -274,6 +274,9 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Build the PKO command */
        pko_command.u64 = 0;
+#ifdef __LITTLE_ENDIAN
+       pko_command.s.le = 1;
+#endif
        pko_command.s.n2 = 1;   /* Don't pollute L2 with the outgoing packet */
        pko_command.s.segs = 1;
        pko_command.s.total_bytes = skb->len;
@@ -410,7 +413,7 @@ dont_put_skbuff_in_hw:
        /* Check if we can use the hardware checksumming */
        if (USE_HW_TCPUDP_CHECKSUM && (skb->protocol == htons(ETH_P_IP)) &&
            (ip_hdr(skb)->version == 4) && (ip_hdr(skb)->ihl == 5) &&
-           ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == 1 << 14))
+           ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == htons(1 << 14)))
            && ((ip_hdr(skb)->protocol == IPPROTO_TCP)
                || (ip_hdr(skb)->protocol == IPPROTO_UDP))) {
                /* Use hardware checksum calc */
index f539d82..fbbe866 100644 (file)
@@ -170,6 +170,16 @@ static void cvm_oct_configure_common_hw(void)
                cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
                                     CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
 
+#ifdef __LITTLE_ENDIAN
+       {
+               union cvmx_ipd_ctl_status ipd_ctl_status;
+               ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
+               ipd_ctl_status.s.pkt_lend = 1;
+               ipd_ctl_status.s.wqe_lend = 1;
+               cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);
+       }
+#endif
+
        if (USE_RED)
                cvmx_helper_setup_red(num_packet_buffers / 4,
                                      num_packet_buffers / 8);
index b24aa01..c01f450 100644 (file)
@@ -419,4 +419,51 @@ config DA_CONSOLE
        help
          This enables a console on a Dash channel.
 
+config MIPS_EJTAG_FDC_TTY
+       bool "MIPS EJTAG Fast Debug Channel TTY"
+       depends on MIPS_CDMM
+       help
+         This enables a TTY and console on the MIPS EJTAG Fast Debug Channels,
+         if they are present. This can be useful when working with an EJTAG
+         probe which supports it, to get console output and a login prompt via
+         EJTAG without needing to connect a serial cable.
+
+         TTY devices are named e.g. ttyFDC3c2 (for FDC channel 2 of the FDC on
+         CPU3).
+
+         The console can be enabled with console=fdc1 (for FDC channel 1 on all
+         CPUs). Do not use the console unless there is a debug probe attached
+         to drain the FDC TX FIFO.
+
+         If unsure, say N.
+
+config MIPS_EJTAG_FDC_EARLYCON
+       bool "Early FDC console"
+       depends on MIPS_EJTAG_FDC_TTY
+       help
+         This registers a console on FDC channel 1 very early during boot (from
+         MIPS arch code). This is useful for bring-up and debugging early boot
+         issues.
+
+         Do not enable unless there is a debug probe attached to drain the FDC
+         TX FIFO.
+
+         If unsure, say N.
+
+config MIPS_EJTAG_FDC_KGDB
+       bool "Use KGDB over an FDC channel"
+       depends on MIPS_EJTAG_FDC_TTY && KGDB
+       default y
+       help
+          This enables the use of KGDB over an FDC channel, allowing KGDB to be
+          used remotely or when a serial port isn't available.
+
+config MIPS_EJTAG_FDC_KGDB_CHAN
+       int "KGDB FDC channel"
+       depends on MIPS_EJTAG_FDC_KGDB
+       range 2 15
+       default 3
+       help
+         FDC channel number to use for KGDB.
+
 endif # TTY
index 58ad1c0..5817e23 100644 (file)
@@ -29,5 +29,6 @@ obj-$(CONFIG_SYNCLINK)                += synclink.o
 obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o
 obj-$(CONFIG_GOLDFISH_TTY)     += goldfish.o
 obj-$(CONFIG_DA_TTY)           += metag_da.o
+obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o
 
 obj-y += ipwireless/
diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c
new file mode 100644 (file)
index 0000000..04d9e23
--- /dev/null
@@ -0,0 +1,1303 @@
+/*
+ * TTY driver for MIPS EJTAG Fast Debug Channels.
+ *
+ * Copyright (C) 2007-2015 Imagination Technologies Ltd
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for more
+ * details.
+ */
+
+#include <linux/atomic.h>
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/kgdb.h>
+#include <linux/kthread.h>
+#include <linux/sched.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/uaccess.h>
+
+#include <asm/cdmm.h>
+#include <asm/irq.h>
+
+/* Register offsets */
+#define REG_FDACSR     0x00    /* FDC Access Control and Status Register */
+#define REG_FDCFG      0x08    /* FDC Configuration Register */
+#define REG_FDSTAT     0x10    /* FDC Status Register */
+#define REG_FDRX       0x18    /* FDC Receive Register */
+#define REG_FDTX(N)    (0x20+0x8*(N))  /* FDC Transmit Register n (0..15) */
+
+/* Register fields */
+
+#define REG_FDCFG_TXINTTHRES_SHIFT     18
+#define REG_FDCFG_TXINTTHRES           (0x3 << REG_FDCFG_TXINTTHRES_SHIFT)
+#define REG_FDCFG_TXINTTHRES_DISABLED  (0x0 << REG_FDCFG_TXINTTHRES_SHIFT)
+#define REG_FDCFG_TXINTTHRES_EMPTY     (0x1 << REG_FDCFG_TXINTTHRES_SHIFT)
+#define REG_FDCFG_TXINTTHRES_NOTFULL   (0x2 << REG_FDCFG_TXINTTHRES_SHIFT)
+#define REG_FDCFG_TXINTTHRES_NEAREMPTY (0x3 << REG_FDCFG_TXINTTHRES_SHIFT)
+#define REG_FDCFG_RXINTTHRES_SHIFT     16
+#define REG_FDCFG_RXINTTHRES           (0x3 << REG_FDCFG_RXINTTHRES_SHIFT)
+#define REG_FDCFG_RXINTTHRES_DISABLED  (0x0 << REG_FDCFG_RXINTTHRES_SHIFT)
+#define REG_FDCFG_RXINTTHRES_FULL      (0x1 << REG_FDCFG_RXINTTHRES_SHIFT)
+#define REG_FDCFG_RXINTTHRES_NOTEMPTY  (0x2 << REG_FDCFG_RXINTTHRES_SHIFT)
+#define REG_FDCFG_RXINTTHRES_NEARFULL  (0x3 << REG_FDCFG_RXINTTHRES_SHIFT)
+#define REG_FDCFG_TXFIFOSIZE_SHIFT     8
+#define REG_FDCFG_TXFIFOSIZE           (0xff << REG_FDCFG_TXFIFOSIZE_SHIFT)
+#define REG_FDCFG_RXFIFOSIZE_SHIFT     0
+#define REG_FDCFG_RXFIFOSIZE           (0xff << REG_FDCFG_RXFIFOSIZE_SHIFT)
+
+#define REG_FDSTAT_TXCOUNT_SHIFT       24
+#define REG_FDSTAT_TXCOUNT             (0xff << REG_FDSTAT_TXCOUNT_SHIFT)
+#define REG_FDSTAT_RXCOUNT_SHIFT       16
+#define REG_FDSTAT_RXCOUNT             (0xff << REG_FDSTAT_RXCOUNT_SHIFT)
+#define REG_FDSTAT_RXCHAN_SHIFT                4
+#define REG_FDSTAT_RXCHAN              (0xf << REG_FDSTAT_RXCHAN_SHIFT)
+#define REG_FDSTAT_RXE                 BIT(3)  /* Rx Empty */
+#define REG_FDSTAT_RXF                 BIT(2)  /* Rx Full */
+#define REG_FDSTAT_TXE                 BIT(1)  /* Tx Empty */
+#define REG_FDSTAT_TXF                 BIT(0)  /* Tx Full */
+
+/* Default channel for the early console */
+#define CONSOLE_CHANNEL      1
+
+#define NUM_TTY_CHANNELS     16
+
+#define RX_BUF_SIZE 1024
+
+/*
+ * When the IRQ is unavailable, the FDC state must be polled for incoming data
+ * and space becoming available in TX FIFO.
+ */
+#define FDC_TTY_POLL (HZ / 50)
+
+struct mips_ejtag_fdc_tty;
+
+/**
+ * struct mips_ejtag_fdc_tty_port - Wrapper struct for FDC tty_port.
+ * @port:              TTY port data
+ * @driver:            TTY driver.
+ * @rx_lock:           Lock for rx_buf.
+ *                     This protects between the hard interrupt and user
+ *                     context. It's also held during read SWITCH operations.
+ * @rx_buf:            Read buffer.
+ * @xmit_lock:         Lock for xmit_*, and port.xmit_buf.
+ *                     This protects between user context and kernel thread.
+ *                     It is used from chars_in_buffer()/write_room() TTY
+ *                     callbacks which are used during wait operations, so a
+ *                     mutex is unsuitable.
+ * @xmit_cnt:          Size of xmit buffer contents.
+ * @xmit_head:         Head of xmit buffer where data is written.
+ * @xmit_tail:         Tail of xmit buffer where data is read.
+ * @xmit_empty:                Completion for xmit buffer being empty.
+ */
+struct mips_ejtag_fdc_tty_port {
+       struct tty_port                  port;
+       struct mips_ejtag_fdc_tty       *driver;
+       raw_spinlock_t                   rx_lock;
+       void                            *rx_buf;
+       spinlock_t                       xmit_lock;
+       unsigned int                     xmit_cnt;
+       unsigned int                     xmit_head;
+       unsigned int                     xmit_tail;
+       struct completion                xmit_empty;
+};
+
+/**
+ * struct mips_ejtag_fdc_tty - Driver data for FDC as a whole.
+ * @dev:               FDC device (for dev_*() logging).
+ * @driver:            TTY driver.
+ * @cpu:               CPU number for this FDC.
+ * @fdc_name:          FDC name (not for base of channel names).
+ * @driver_name:       Base of driver name.
+ * @ports:             Per-channel data.
+ * @waitqueue:         Wait queue for waiting for TX data, or for space in TX
+ *                     FIFO.
+ * @lock:              Lock to protect FDCFG (interrupt enable).
+ * @thread:            KThread for writing out data to FDC.
+ * @reg:               FDC registers.
+ * @tx_fifo:           TX FIFO size.
+ * @xmit_size:         Size of each port's xmit buffer.
+ * @xmit_total:                Total number of bytes (from all ports) to transmit.
+ * @xmit_next:         Next port number to transmit from (round robin).
+ * @xmit_full:         Indicates TX FIFO is full, we're waiting for space.
+ * @irq:               IRQ number (negative if no IRQ).
+ * @removing:          Indicates the device is being removed and @poll_timer
+ *                     should not be restarted.
+ * @poll_timer:                Timer for polling for interrupt events when @irq < 0.
+ * @sysrq_pressed:     Whether the magic sysrq key combination has been
+ *                     detected. See mips_ejtag_fdc_handle().
+ */
+struct mips_ejtag_fdc_tty {
+       struct device                   *dev;
+       struct tty_driver               *driver;
+       unsigned int                     cpu;
+       char                             fdc_name[16];
+       char                             driver_name[16];
+       struct mips_ejtag_fdc_tty_port   ports[NUM_TTY_CHANNELS];
+       wait_queue_head_t                waitqueue;
+       raw_spinlock_t                   lock;
+       struct task_struct              *thread;
+
+       void __iomem                    *reg;
+       u8                               tx_fifo;
+
+       unsigned int                     xmit_size;
+       atomic_t                         xmit_total;
+       unsigned int                     xmit_next;
+       bool                             xmit_full;
+
+       int                              irq;
+       bool                             removing;
+       struct timer_list                poll_timer;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+       bool                             sysrq_pressed;
+#endif
+};
+
+/* Hardware access */
+
+static inline void mips_ejtag_fdc_write(struct mips_ejtag_fdc_tty *priv,
+                                       unsigned int offs, unsigned int data)
+{
+       iowrite32(data, priv->reg + offs);
+}
+
+static inline unsigned int mips_ejtag_fdc_read(struct mips_ejtag_fdc_tty *priv,
+                                              unsigned int offs)
+{
+       return ioread32(priv->reg + offs);
+}
+
+/* Encoding of byte stream in FDC words */
+
+/**
+ * struct fdc_word - FDC word encoding some number of bytes of data.
+ * @word:              Raw FDC word.
+ * @bytes:             Number of bytes encoded by @word.
+ */
+struct fdc_word {
+       u32             word;
+       unsigned int    bytes;
+};
+
+/*
+ * This is a compact encoding which allows every 1 byte, 2 byte, and 3 byte
+ * sequence to be encoded in a single word, while allowing the majority of 4
+ * byte sequences (including all ASCII and common binary data) to be encoded in
+ * a single word too.
+ *    _______________________ _____________
+ *   |       FDC Word        |             |
+ *   |31-24|23-16|15-8 | 7-0 |    Bytes    |
+ *   |_____|_____|_____|_____|_____________|
+ *   |     |     |     |     |             |
+ *   |0x80 |0x80 |0x80 |  WW | WW          |
+ *   |0x81 |0x81 |  XX |  WW | WW XX       |
+ *   |0x82 |  YY |  XX |  WW | WW XX YY    |
+ *   |  ZZ |  YY |  XX |  WW | WW XX YY ZZ |
+ *   |_____|_____|_____|_____|_____________|
+ *
+ * Note that the 4-byte encoding can only be used where none of the other 3
+ * encodings match, otherwise it must fall back to the 3 byte encoding.
+ */
+
+/* ranges >= 1 && sizes[0] >= 1 */
+static struct fdc_word mips_ejtag_fdc_encode(const char **ptrs,
+                                            unsigned int *sizes,
+                                            unsigned int ranges)
+{
+       struct fdc_word word = { 0, 0 };
+       const char **ptrs_end = ptrs + ranges;
+
+       for (; ptrs < ptrs_end; ++ptrs) {
+               const char *ptr = *(ptrs++);
+               const char *end = ptr + *(sizes++);
+
+               for (; ptr < end; ++ptr) {
+                       word.word |= (u8)*ptr << (8*word.bytes);
+                       ++word.bytes;
+                       if (word.bytes == 4)
+                               goto done;
+               }
+       }
+done:
+       /* Choose the appropriate encoding */
+       switch (word.bytes) {
+       case 4:
+               /* 4 byte encoding, but don't match the 1-3 byte encodings */
+               if ((word.word >> 8) != 0x808080 &&
+                   (word.word >> 16) != 0x8181 &&
+                   (word.word >> 24) != 0x82)
+                       break;
+               /* Fall back to a 3 byte encoding */
+               word.bytes = 3;
+               word.word &= 0x00ffffff;
+       case 3:
+               /* 3 byte encoding */
+               word.word |= 0x82000000;
+               break;
+       case 2:
+               /* 2 byte encoding */
+               word.word |= 0x81810000;
+               break;
+       case 1:
+               /* 1 byte encoding */
+               word.word |= 0x80808000;
+               break;
+       }
+       return word;
+}
+
+static unsigned int mips_ejtag_fdc_decode(u32 word, char *buf)
+{
+       buf[0] = (u8)word;
+       word >>= 8;
+       if (word == 0x808080)
+               return 1;
+       buf[1] = (u8)word;
+       word >>= 8;
+       if (word == 0x8181)
+               return 2;
+       buf[2] = (u8)word;
+       word >>= 8;
+       if (word == 0x82)
+               return 3;
+       buf[3] = (u8)word;
+       return 4;
+}
+
+/* Console operations */
+
+/**
+ * struct mips_ejtag_fdc_console - Wrapper struct for FDC consoles.
+ * @cons:              Console object.
+ * @tty_drv:           TTY driver associated with this console.
+ * @lock:              Lock to protect concurrent access to other fields.
+ *                     This is raw because it may be used very early.
+ * @initialised:       Whether the console is initialised.
+ * @regs:              Registers base address for each CPU.
+ */
+struct mips_ejtag_fdc_console {
+       struct console           cons;
+       struct tty_driver       *tty_drv;
+       raw_spinlock_t           lock;
+       bool                     initialised;
+       void __iomem            *regs[NR_CPUS];
+};
+
+/* Low level console write shared by early console and normal console */
+static void mips_ejtag_fdc_console_write(struct console *c, const char *s,
+                                        unsigned int count)
+{
+       struct mips_ejtag_fdc_console *cons =
+               container_of(c, struct mips_ejtag_fdc_console, cons);
+       void __iomem *regs;
+       struct fdc_word word;
+       unsigned long flags;
+       unsigned int i, buf_len, cpu;
+       bool done_cr = false;
+       char buf[4];
+       const char *buf_ptr = buf;
+       /* Number of bytes of input data encoded up to each byte in buf */
+       u8 inc[4];
+
+       local_irq_save(flags);
+       cpu = smp_processor_id();
+       regs = cons->regs[cpu];
+       /* First console output on this CPU? */
+       if (!regs) {
+               regs = mips_cdmm_early_probe(0xfd);
+               cons->regs[cpu] = regs;
+       }
+       /* Already tried and failed to find FDC on this CPU? */
+       if (IS_ERR(regs))
+               goto out;
+       while (count) {
+               /*
+                * Copy the next few characters to a buffer so we can inject
+                * carriage returns before newlines.
+                */
+               for (buf_len = 0, i = 0; buf_len < 4 && i < count; ++buf_len) {
+                       if (s[i] == '\n' && !done_cr) {
+                               buf[buf_len] = '\r';
+                               done_cr = true;
+                       } else {
+                               buf[buf_len] = s[i];
+                               done_cr = false;
+                               ++i;
+                       }
+                       inc[buf_len] = i;
+               }
+               word = mips_ejtag_fdc_encode(&buf_ptr, &buf_len, 1);
+               count -= inc[word.bytes - 1];
+               s += inc[word.bytes - 1];
+
+               /* Busy wait until there's space in fifo */
+               while (ioread32(regs + REG_FDSTAT) & REG_FDSTAT_TXF)
+                       ;
+               iowrite32(word.word, regs + REG_FDTX(c->index));
+       }
+out:
+       local_irq_restore(flags);
+}
+
+static struct tty_driver *mips_ejtag_fdc_console_device(struct console *c,
+                                                       int *index)
+{
+       struct mips_ejtag_fdc_console *cons =
+               container_of(c, struct mips_ejtag_fdc_console, cons);
+
+       *index = c->index;
+       return cons->tty_drv;
+}
+
+/* Initialise an FDC console (early or normal */
+static int __init mips_ejtag_fdc_console_init(struct mips_ejtag_fdc_console *c)
+{
+       void __iomem *regs;
+       unsigned long flags;
+       int ret = 0;
+
+       raw_spin_lock_irqsave(&c->lock, flags);
+       /* Don't init twice */
+       if (c->initialised)
+               goto out;
+       /* Look for the FDC device */
+       regs = mips_cdmm_early_probe(0xfd);
+       if (IS_ERR(regs)) {
+               ret = PTR_ERR(regs);
+               goto out;
+       }
+
+       c->initialised = true;
+       c->regs[smp_processor_id()] = regs;
+       register_console(&c->cons);
+out:
+       raw_spin_unlock_irqrestore(&c->lock, flags);
+       return ret;
+}
+
+static struct mips_ejtag_fdc_console mips_ejtag_fdc_con = {
+       .cons   = {
+               .name   = "fdc",
+               .write  = mips_ejtag_fdc_console_write,
+               .device = mips_ejtag_fdc_console_device,
+               .flags  = CON_PRINTBUFFER,
+               .index  = -1,
+       },
+       .lock   = __RAW_SPIN_LOCK_UNLOCKED(mips_ejtag_fdc_con.lock),
+};
+
+/* TTY RX/TX operations */
+
+/**
+ * mips_ejtag_fdc_put_chan() - Write out a block of channel data.
+ * @priv:      Pointer to driver private data.
+ * @chan:      Channel number.
+ *
+ * Write a single block of data out to the debug adapter. If the circular buffer
+ * is wrapped then only the first block is written.
+ *
+ * Returns:    The number of bytes that were written.
+ */
+static unsigned int mips_ejtag_fdc_put_chan(struct mips_ejtag_fdc_tty *priv,
+                                           unsigned int chan)
+{
+       struct mips_ejtag_fdc_tty_port *dport;
+       struct tty_struct *tty;
+       const char *ptrs[2];
+       unsigned int sizes[2] = { 0 };
+       struct fdc_word word = { .bytes = 0 };
+       unsigned long flags;
+
+       dport = &priv->ports[chan];
+       spin_lock(&dport->xmit_lock);
+       if (dport->xmit_cnt) {
+               ptrs[0] = dport->port.xmit_buf + dport->xmit_tail;
+               sizes[0] = min_t(unsigned int,
+                                priv->xmit_size - dport->xmit_tail,
+                                dport->xmit_cnt);
+               ptrs[1] = dport->port.xmit_buf;
+               sizes[1] = dport->xmit_cnt - sizes[0];
+               word = mips_ejtag_fdc_encode(ptrs, sizes, 1 + !!sizes[1]);
+
+               dev_dbg(priv->dev, "%s%u: out %08x: \"%*pE%*pE\"\n",
+                       priv->driver_name, chan, word.word,
+                       min_t(int, word.bytes, sizes[0]), ptrs[0],
+                       max_t(int, 0, word.bytes - sizes[0]), ptrs[1]);
+
+               local_irq_save(flags);
+               /* Maybe we raced with the console and TX FIFO is full */
+               if (mips_ejtag_fdc_read(priv, REG_FDSTAT) & REG_FDSTAT_TXF)
+                       word.bytes = 0;
+               else
+                       mips_ejtag_fdc_write(priv, REG_FDTX(chan), word.word);
+               local_irq_restore(flags);
+
+               dport->xmit_cnt -= word.bytes;
+               if (!dport->xmit_cnt) {
+                       /* Reset pointers to avoid wraps */
+                       dport->xmit_head = 0;
+                       dport->xmit_tail = 0;
+                       complete(&dport->xmit_empty);
+               } else {
+                       dport->xmit_tail += word.bytes;
+                       if (dport->xmit_tail >= priv->xmit_size)
+                               dport->xmit_tail -= priv->xmit_size;
+               }
+               atomic_sub(word.bytes, &priv->xmit_total);
+       }
+       spin_unlock(&dport->xmit_lock);
+
+       /* If we've made more data available, wake up tty */
+       if (sizes[0] && word.bytes) {
+               tty = tty_port_tty_get(&dport->port);
+               if (tty) {
+                       tty_wakeup(tty);
+                       tty_kref_put(tty);
+               }
+       }
+
+       return word.bytes;
+}
+
+/**
+ * mips_ejtag_fdc_put() - Kernel thread to write out channel data to FDC.
+ * @arg:       Driver pointer.
+ *
+ * This kernel thread runs while @priv->xmit_total != 0, and round robins the
+ * channels writing out blocks of buffered data to the FDC TX FIFO.
+ */
+static int mips_ejtag_fdc_put(void *arg)
+{
+       struct mips_ejtag_fdc_tty *priv = arg;
+       struct mips_ejtag_fdc_tty_port *dport;
+       unsigned int ret;
+       u32 cfg;
+
+       __set_current_state(TASK_RUNNING);
+       while (!kthread_should_stop()) {
+               /* Wait for data to actually write */
+               wait_event_interruptible(priv->waitqueue,
+                                        atomic_read(&priv->xmit_total) ||
+                                        kthread_should_stop());
+               if (kthread_should_stop())
+                       break;
+
+               /* Wait for TX FIFO space to write data */
+               raw_spin_lock_irq(&priv->lock);
+               if (mips_ejtag_fdc_read(priv, REG_FDSTAT) & REG_FDSTAT_TXF) {
+                       priv->xmit_full = true;
+                       if (priv->irq >= 0) {
+                               /* Enable TX interrupt */
+                               cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
+                               cfg &= ~REG_FDCFG_TXINTTHRES;
+                               cfg |= REG_FDCFG_TXINTTHRES_NOTFULL;
+                               mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
+                       }
+               }
+               raw_spin_unlock_irq(&priv->lock);
+               wait_event_interruptible(priv->waitqueue,
+                                        !(mips_ejtag_fdc_read(priv, REG_FDSTAT)
+                                          & REG_FDSTAT_TXF) ||
+                                        kthread_should_stop());
+               if (kthread_should_stop())
+                       break;
+
+               /* Find next channel with data to output */
+               for (;;) {
+                       dport = &priv->ports[priv->xmit_next];
+                       spin_lock(&dport->xmit_lock);
+                       ret = dport->xmit_cnt;
+                       spin_unlock(&dport->xmit_lock);
+                       if (ret)
+                               break;
+                       /* Round robin */
+                       ++priv->xmit_next;
+                       if (priv->xmit_next >= NUM_TTY_CHANNELS)
+                               priv->xmit_next = 0;
+               }
+
+               /* Try writing data to the chosen channel */
+               ret = mips_ejtag_fdc_put_chan(priv, priv->xmit_next);
+
+               /*
+                * If anything was output, move on to the next channel so as not
+                * to starve other channels.
+                */
+               if (ret) {
+                       ++priv->xmit_next;
+                       if (priv->xmit_next >= NUM_TTY_CHANNELS)
+                               priv->xmit_next = 0;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * mips_ejtag_fdc_handle() - Handle FDC events.
+ * @priv:      Pointer to driver private data.
+ *
+ * Handle FDC events, such as new incoming data which needs draining out of the
+ * RX FIFO and feeding into the appropriate TTY ports, and space becoming
+ * available in the TX FIFO which would allow more data to be written out.
+ */
+static void mips_ejtag_fdc_handle(struct mips_ejtag_fdc_tty *priv)
+{
+       struct mips_ejtag_fdc_tty_port *dport;
+       unsigned int stat, channel, data, cfg, i, flipped;
+       int len;
+       char buf[4];
+
+       for (;;) {
+               /* Find which channel the next FDC word is destined for */
+               stat = mips_ejtag_fdc_read(priv, REG_FDSTAT);
+               if (stat & REG_FDSTAT_RXE)
+                       break;
+               channel = (stat & REG_FDSTAT_RXCHAN) >> REG_FDSTAT_RXCHAN_SHIFT;
+               dport = &priv->ports[channel];
+
+               /* Read out the FDC word, decode it, and pass to tty layer */
+               raw_spin_lock(&dport->rx_lock);
+               data = mips_ejtag_fdc_read(priv, REG_FDRX);
+
+               len = mips_ejtag_fdc_decode(data, buf);
+               dev_dbg(priv->dev, "%s%u: in  %08x: \"%*pE\"\n",
+                       priv->driver_name, channel, data, len, buf);
+
+               flipped = 0;
+               for (i = 0; i < len; ++i) {
+#ifdef CONFIG_MAGIC_SYSRQ
+#ifdef CONFIG_MIPS_EJTAG_FDC_KGDB
+                       /* Support just Ctrl+C with KGDB channel */
+                       if (channel == CONFIG_MIPS_EJTAG_FDC_KGDB_CHAN) {
+                               if (buf[i] == '\x03') { /* ^C */
+                                       handle_sysrq('g');
+                                       continue;
+                               }
+                       }
+#endif
+                       /* Support Ctrl+O for console channel */
+                       if (channel == mips_ejtag_fdc_con.cons.index) {
+                               if (buf[i] == '\x0f') { /* ^O */
+                                       priv->sysrq_pressed =
+                                               !priv->sysrq_pressed;
+                                       if (priv->sysrq_pressed)
+                                               continue;
+                               } else if (priv->sysrq_pressed) {
+                                       handle_sysrq(buf[i]);
+                                       priv->sysrq_pressed = false;
+                                       continue;
+                               }
+                       }
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+                       /* Check the port isn't being shut down */
+                       if (!dport->rx_buf)
+                               continue;
+
+                       flipped += tty_insert_flip_char(&dport->port, buf[i],
+                                                       TTY_NORMAL);
+               }
+               if (flipped)
+                       tty_flip_buffer_push(&dport->port);
+
+               raw_spin_unlock(&dport->rx_lock);
+       }
+
+       /* If TX FIFO no longer full we may be able to write more data */
+       raw_spin_lock(&priv->lock);
+       if (priv->xmit_full && !(stat & REG_FDSTAT_TXF)) {
+               priv->xmit_full = false;
+
+               /* Disable TX interrupt */
+               cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
+               cfg &= ~REG_FDCFG_TXINTTHRES;
+               cfg |= REG_FDCFG_TXINTTHRES_DISABLED;
+               mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
+
+               /* Wait the kthread so it can try writing more data */
+               wake_up_interruptible(&priv->waitqueue);
+       }
+       raw_spin_unlock(&priv->lock);
+}
+
+/**
+ * mips_ejtag_fdc_isr() - Interrupt handler.
+ * @irq:       IRQ number.
+ * @dev_id:    Pointer to driver private data.
+ *
+ * This is the interrupt handler, used when interrupts are enabled.
+ *
+ * It simply triggers the common FDC handler code.
+ *
+ * Returns:    IRQ_HANDLED if an FDC interrupt was pending.
+ *             IRQ_NONE otherwise.
+ */
+static irqreturn_t mips_ejtag_fdc_isr(int irq, void *dev_id)
+{
+       struct mips_ejtag_fdc_tty *priv = dev_id;
+
+       /*
+        * We're not using proper per-cpu IRQs, so we must be careful not to
+        * handle IRQs on CPUs we're not interested in.
+        *
+        * Ideally proper per-cpu IRQ handlers could be used, but that doesn't
+        * fit well with the whole sharing of the main CPU IRQ lines. When we
+        * have something with a GIC that routes the FDC IRQs (i.e. no sharing
+        * between handlers) then support could be added more easily.
+        */
+       if (smp_processor_id() != priv->cpu)
+               return IRQ_NONE;
+
+       /* If no FDC interrupt pending, it wasn't for us */
+       if (!(read_c0_cause() & CAUSEF_FDCI))
+               return IRQ_NONE;
+
+       mips_ejtag_fdc_handle(priv);
+       return IRQ_HANDLED;
+}
+
+/**
+ * mips_ejtag_fdc_tty_timer() - Poll FDC for incoming data.
+ * @opaque:    Pointer to driver private data.
+ *
+ * This is the timer handler for when interrupts are disabled and polling the
+ * FDC state is required.
+ *
+ * It simply triggers the common FDC handler code and arranges for further
+ * polling.
+ */
+static void mips_ejtag_fdc_tty_timer(unsigned long opaque)
+{
+       struct mips_ejtag_fdc_tty *priv = (void *)opaque;
+
+       mips_ejtag_fdc_handle(priv);
+       if (!priv->removing)
+               mod_timer_pinned(&priv->poll_timer, jiffies + FDC_TTY_POLL);
+}
+
+/* TTY Port operations */
+
+static int mips_ejtag_fdc_tty_port_activate(struct tty_port *port,
+                                           struct tty_struct *tty)
+{
+       struct mips_ejtag_fdc_tty_port *dport =
+               container_of(port, struct mips_ejtag_fdc_tty_port, port);
+       void *rx_buf;
+
+       /* Allocate the buffer we use for writing data */
+       if (tty_port_alloc_xmit_buf(port) < 0)
+               goto err;
+
+       /* Allocate the buffer we use for reading data */
+       rx_buf = kzalloc(RX_BUF_SIZE, GFP_KERNEL);
+       if (!rx_buf)
+               goto err_free_xmit;
+
+       raw_spin_lock_irq(&dport->rx_lock);
+       dport->rx_buf = rx_buf;
+       raw_spin_unlock_irq(&dport->rx_lock);
+
+       return 0;
+err_free_xmit:
+       tty_port_free_xmit_buf(port);
+err:
+       return -ENOMEM;
+}
+
+static void mips_ejtag_fdc_tty_port_shutdown(struct tty_port *port)
+{
+       struct mips_ejtag_fdc_tty_port *dport =
+               container_of(port, struct mips_ejtag_fdc_tty_port, port);
+       struct mips_ejtag_fdc_tty *priv = dport->driver;
+       void *rx_buf;
+       unsigned int count;
+
+       spin_lock(&dport->xmit_lock);
+       count = dport->xmit_cnt;
+       spin_unlock(&dport->xmit_lock);
+       if (count) {
+               /*
+                * There's still data to write out, so wake and wait for the
+                * writer thread to drain the buffer.
+                */
+               wake_up_interruptible(&priv->waitqueue);
+               wait_for_completion(&dport->xmit_empty);
+       }
+
+       /* Null the read buffer (timer could still be running!) */
+       raw_spin_lock_irq(&dport->rx_lock);
+       rx_buf = dport->rx_buf;
+       dport->rx_buf = NULL;
+       raw_spin_unlock_irq(&dport->rx_lock);
+       /* Free the read buffer */
+       kfree(rx_buf);
+
+       /* Free the write buffer */
+       tty_port_free_xmit_buf(port);
+}
+
+static const struct tty_port_operations mips_ejtag_fdc_tty_port_ops = {
+       .activate       = mips_ejtag_fdc_tty_port_activate,
+       .shutdown       = mips_ejtag_fdc_tty_port_shutdown,
+};
+
+/* TTY operations */
+
+static int mips_ejtag_fdc_tty_install(struct tty_driver *driver,
+                                     struct tty_struct *tty)
+{
+       struct mips_ejtag_fdc_tty *priv = driver->driver_state;
+
+       tty->driver_data = &priv->ports[tty->index];
+       return tty_port_install(&priv->ports[tty->index].port, driver, tty);
+}
+
+static int mips_ejtag_fdc_tty_open(struct tty_struct *tty, struct file *filp)
+{
+       return tty_port_open(tty->port, tty, filp);
+}
+
+static void mips_ejtag_fdc_tty_close(struct tty_struct *tty, struct file *filp)
+{
+       return tty_port_close(tty->port, tty, filp);
+}
+
+static void mips_ejtag_fdc_tty_hangup(struct tty_struct *tty)
+{
+       struct mips_ejtag_fdc_tty_port *dport = tty->driver_data;
+       struct mips_ejtag_fdc_tty *priv = dport->driver;
+
+       /* Drop any data in the xmit buffer */
+       spin_lock(&dport->xmit_lock);
+       if (dport->xmit_cnt) {
+               atomic_sub(dport->xmit_cnt, &priv->xmit_total);
+               dport->xmit_cnt = 0;
+               dport->xmit_head = 0;
+               dport->xmit_tail = 0;
+               complete(&dport->xmit_empty);
+       }
+       spin_unlock(&dport->xmit_lock);
+
+       tty_port_hangup(tty->port);
+}
+
+static int mips_ejtag_fdc_tty_write(struct tty_struct *tty,
+                                   const unsigned char *buf, int total)
+{
+       int count, block;
+       struct mips_ejtag_fdc_tty_port *dport = tty->driver_data;
+       struct mips_ejtag_fdc_tty *priv = dport->driver;
+
+       /*
+        * Write to output buffer.
+        *
+        * The reason that we asynchronously write the buffer is because if we
+        * were to write the buffer synchronously then because the channels are
+        * per-CPU the buffer would be written to the channel of whatever CPU
+        * we're running on.
+        *
+        * What we actually want to happen is have all input and output done on
+        * one CPU.
+        */
+       spin_lock(&dport->xmit_lock);
+       /* Work out how many bytes we can write to the xmit buffer */
+       total = min(total, (int)(priv->xmit_size - dport->xmit_cnt));
+       atomic_add(total, &priv->xmit_total);
+       dport->xmit_cnt += total;
+       /* Write the actual bytes (may need splitting if it wraps) */
+       for (count = total; count; count -= block) {
+               block = min(count, (int)(priv->xmit_size - dport->xmit_head));
+               memcpy(dport->port.xmit_buf + dport->xmit_head, buf, block);
+               dport->xmit_head += block;
+               if (dport->xmit_head >= priv->xmit_size)
+                       dport->xmit_head -= priv->xmit_size;
+               buf += block;
+       }
+       count = dport->xmit_cnt;
+       /* Xmit buffer no longer empty? */
+       if (count)
+               reinit_completion(&dport->xmit_empty);
+       spin_unlock(&dport->xmit_lock);
+
+       /* Wake up the kthread */
+       if (total)
+               wake_up_interruptible(&priv->waitqueue);
+       return total;
+}
+
+static int mips_ejtag_fdc_tty_write_room(struct tty_struct *tty)
+{
+       struct mips_ejtag_fdc_tty_port *dport = tty->driver_data;
+       struct mips_ejtag_fdc_tty *priv = dport->driver;
+       int room;
+
+       /* Report the space in the xmit buffer */
+       spin_lock(&dport->xmit_lock);
+       room = priv->xmit_size - dport->xmit_cnt;
+       spin_unlock(&dport->xmit_lock);
+
+       return room;
+}
+
+static int mips_ejtag_fdc_tty_chars_in_buffer(struct tty_struct *tty)
+{
+       struct mips_ejtag_fdc_tty_port *dport = tty->driver_data;
+       int chars;
+
+       /* Report the number of bytes in the xmit buffer */
+       spin_lock(&dport->xmit_lock);
+       chars = dport->xmit_cnt;
+       spin_unlock(&dport->xmit_lock);
+
+       return chars;
+}
+
+static const struct tty_operations mips_ejtag_fdc_tty_ops = {
+       .install                = mips_ejtag_fdc_tty_install,
+       .open                   = mips_ejtag_fdc_tty_open,
+       .close                  = mips_ejtag_fdc_tty_close,
+       .hangup                 = mips_ejtag_fdc_tty_hangup,
+       .write                  = mips_ejtag_fdc_tty_write,
+       .write_room             = mips_ejtag_fdc_tty_write_room,
+       .chars_in_buffer        = mips_ejtag_fdc_tty_chars_in_buffer,
+};
+
+static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev)
+{
+       int ret, nport;
+       struct mips_ejtag_fdc_tty_port *dport;
+       struct mips_ejtag_fdc_tty *priv;
+       struct tty_driver *driver;
+       unsigned int cfg, tx_fifo;
+
+       priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       priv->cpu = dev->cpu;
+       priv->dev = &dev->dev;
+       mips_cdmm_set_drvdata(dev, priv);
+       atomic_set(&priv->xmit_total, 0);
+       raw_spin_lock_init(&priv->lock);
+
+       priv->reg = devm_ioremap_nocache(priv->dev, dev->res.start,
+                                        resource_size(&dev->res));
+       if (!priv->reg) {
+               dev_err(priv->dev, "ioremap failed for resource %pR\n",
+                       &dev->res);
+               return -ENOMEM;
+       }
+
+       cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
+       tx_fifo = (cfg & REG_FDCFG_TXFIFOSIZE) >> REG_FDCFG_TXFIFOSIZE_SHIFT;
+       /* Disable interrupts */
+       cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES);
+       cfg |= REG_FDCFG_TXINTTHRES_DISABLED;
+       cfg |= REG_FDCFG_RXINTTHRES_DISABLED;
+       mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
+
+       /* Make each port's xmit FIFO big enough to fill FDC TX FIFO */
+       priv->xmit_size = min(tx_fifo * 4, (unsigned int)SERIAL_XMIT_SIZE);
+
+       driver = tty_alloc_driver(NUM_TTY_CHANNELS, TTY_DRIVER_REAL_RAW);
+       if (IS_ERR(driver))
+               return PTR_ERR(driver);
+       priv->driver = driver;
+
+       driver->driver_name = "ejtag_fdc";
+       snprintf(priv->fdc_name, sizeof(priv->fdc_name), "ttyFDC%u", dev->cpu);
+       snprintf(priv->driver_name, sizeof(priv->driver_name), "%sc",
+                priv->fdc_name);
+       driver->name = priv->driver_name;
+       driver->major = 0; /* Auto-allocate */
+       driver->minor_start = 0;
+       driver->type = TTY_DRIVER_TYPE_SERIAL;
+       driver->subtype = SERIAL_TYPE_NORMAL;
+       driver->init_termios = tty_std_termios;
+       driver->init_termios.c_cflag |= CLOCAL;
+       driver->driver_state = priv;
+
+       tty_set_operations(driver, &mips_ejtag_fdc_tty_ops);
+       for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) {
+               dport = &priv->ports[nport];
+               dport->driver = priv;
+               tty_port_init(&dport->port);
+               dport->port.ops = &mips_ejtag_fdc_tty_port_ops;
+               raw_spin_lock_init(&dport->rx_lock);
+               spin_lock_init(&dport->xmit_lock);
+               /* The xmit buffer starts empty, i.e. completely written */
+               init_completion(&dport->xmit_empty);
+               complete(&dport->xmit_empty);
+       }
+
+       /* Set up the console */
+       mips_ejtag_fdc_con.regs[dev->cpu] = priv->reg;
+       if (dev->cpu == 0)
+               mips_ejtag_fdc_con.tty_drv = driver;
+
+       init_waitqueue_head(&priv->waitqueue);
+       priv->thread = kthread_create(mips_ejtag_fdc_put, priv, priv->fdc_name);
+       if (IS_ERR(priv->thread)) {
+               ret = PTR_ERR(priv->thread);
+               dev_err(priv->dev, "Couldn't create kthread (%d)\n", ret);
+               goto err_destroy_ports;
+       }
+       /*
+        * Bind the writer thread to the right CPU so it can't migrate.
+        * The channels are per-CPU and we want all channel I/O to be on a
+        * single predictable CPU.
+        */
+       kthread_bind(priv->thread, dev->cpu);
+       wake_up_process(priv->thread);
+
+       /* Look for an FDC IRQ */
+       priv->irq = -1;
+       if (get_c0_fdc_int)
+               priv->irq = get_c0_fdc_int();
+
+       /* Try requesting the IRQ */
+       if (priv->irq >= 0) {
+               /*
+                * IRQF_SHARED, IRQF_NO_SUSPEND: The FDC IRQ may be shared with
+                * other local interrupts such as the timer which sets
+                * IRQF_TIMER (including IRQF_NO_SUSPEND).
+                *
+                * IRQF_NO_THREAD: The FDC IRQ isn't individually maskable so it
+                * cannot be deferred and handled by a thread on RT kernels. For
+                * this reason any spinlocks used from the ISR are raw.
+                */
+               ret = devm_request_irq(priv->dev, priv->irq, mips_ejtag_fdc_isr,
+                                      IRQF_PERCPU | IRQF_SHARED |
+                                      IRQF_NO_THREAD | IRQF_NO_SUSPEND,
+                                      priv->fdc_name, priv);
+               if (ret)
+                       priv->irq = -1;
+       }
+       if (priv->irq >= 0) {
+               /* IRQ is usable, enable RX interrupt */
+               raw_spin_lock_irq(&priv->lock);
+               cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
+               cfg &= ~REG_FDCFG_RXINTTHRES;
+               cfg |= REG_FDCFG_RXINTTHRES_NOTEMPTY;
+               mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
+               raw_spin_unlock_irq(&priv->lock);
+       } else {
+               /* If we didn't get an usable IRQ, poll instead */
+               setup_timer(&priv->poll_timer, mips_ejtag_fdc_tty_timer,
+                           (unsigned long)priv);
+               priv->poll_timer.expires = jiffies + FDC_TTY_POLL;
+               /*
+                * Always attach the timer to the right CPU. The channels are
+                * per-CPU so all polling should be from a single CPU.
+                */
+               add_timer_on(&priv->poll_timer, dev->cpu);
+
+               dev_info(priv->dev, "No usable IRQ, polling enabled\n");
+       }
+
+       ret = tty_register_driver(driver);
+       if (ret < 0) {
+               dev_err(priv->dev, "Couldn't install tty driver (%d)\n", ret);
+               goto err_stop_irq;
+       }
+
+       return 0;
+
+err_stop_irq:
+       if (priv->irq >= 0) {
+               raw_spin_lock_irq(&priv->lock);
+               cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
+               /* Disable interrupts */
+               cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES);
+               cfg |= REG_FDCFG_TXINTTHRES_DISABLED;
+               cfg |= REG_FDCFG_RXINTTHRES_DISABLED;
+               mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
+               raw_spin_unlock_irq(&priv->lock);
+       } else {
+               priv->removing = true;
+               del_timer_sync(&priv->poll_timer);
+       }
+       kthread_stop(priv->thread);
+err_destroy_ports:
+       if (dev->cpu == 0)
+               mips_ejtag_fdc_con.tty_drv = NULL;
+       for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) {
+               dport = &priv->ports[nport];
+               tty_port_destroy(&dport->port);
+       }
+       put_tty_driver(priv->driver);
+       return ret;
+}
+
+static int mips_ejtag_fdc_tty_remove(struct mips_cdmm_device *dev)
+{
+       struct mips_ejtag_fdc_tty *priv = mips_cdmm_get_drvdata(dev);
+       struct mips_ejtag_fdc_tty_port *dport;
+       int nport;
+       unsigned int cfg;
+
+       if (priv->irq >= 0) {
+               raw_spin_lock_irq(&priv->lock);
+               cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
+               /* Disable interrupts */
+               cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES);
+               cfg |= REG_FDCFG_TXINTTHRES_DISABLED;
+               cfg |= REG_FDCFG_RXINTTHRES_DISABLED;
+               mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
+               raw_spin_unlock_irq(&priv->lock);
+       } else {
+               priv->removing = true;
+               del_timer_sync(&priv->poll_timer);
+       }
+       kthread_stop(priv->thread);
+       if (dev->cpu == 0)
+               mips_ejtag_fdc_con.tty_drv = NULL;
+       tty_unregister_driver(priv->driver);
+       for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) {
+               dport = &priv->ports[nport];
+               tty_port_destroy(&dport->port);
+       }
+       put_tty_driver(priv->driver);
+       return 0;
+}
+
+static int mips_ejtag_fdc_tty_cpu_down(struct mips_cdmm_device *dev)
+{
+       struct mips_ejtag_fdc_tty *priv = mips_cdmm_get_drvdata(dev);
+       unsigned int cfg;
+
+       if (priv->irq >= 0) {
+               raw_spin_lock_irq(&priv->lock);
+               cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
+               /* Disable interrupts */
+               cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES);
+               cfg |= REG_FDCFG_TXINTTHRES_DISABLED;
+               cfg |= REG_FDCFG_RXINTTHRES_DISABLED;
+               mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
+               raw_spin_unlock_irq(&priv->lock);
+       } else {
+               priv->removing = true;
+               del_timer_sync(&priv->poll_timer);
+       }
+       kthread_stop(priv->thread);
+
+       return 0;
+}
+
+static int mips_ejtag_fdc_tty_cpu_up(struct mips_cdmm_device *dev)
+{
+       struct mips_ejtag_fdc_tty *priv = mips_cdmm_get_drvdata(dev);
+       unsigned int cfg;
+       int ret = 0;
+
+       if (priv->irq >= 0) {
+               /*
+                * IRQ is usable, enable RX interrupt
+                * This must be before kthread is restarted, as kthread may
+                * enable TX interrupt.
+                */
+               raw_spin_lock_irq(&priv->lock);
+               cfg = mips_ejtag_fdc_read(priv, REG_FDCFG);
+               cfg &= ~(REG_FDCFG_TXINTTHRES | REG_FDCFG_RXINTTHRES);
+               cfg |= REG_FDCFG_TXINTTHRES_DISABLED;
+               cfg |= REG_FDCFG_RXINTTHRES_NOTEMPTY;
+               mips_ejtag_fdc_write(priv, REG_FDCFG, cfg);
+               raw_spin_unlock_irq(&priv->lock);
+       } else {
+               /* Restart poll timer */
+               priv->removing = false;
+               add_timer_on(&priv->poll_timer, dev->cpu);
+       }
+
+       /* Restart the kthread */
+       priv->thread = kthread_create(mips_ejtag_fdc_put, priv, priv->fdc_name);
+       if (IS_ERR(priv->thread)) {
+               ret = PTR_ERR(priv->thread);
+               dev_err(priv->dev, "Couldn't re-create kthread (%d)\n", ret);
+               goto out;
+       }
+       /* Bind it back to the right CPU and set it off */
+       kthread_bind(priv->thread, dev->cpu);
+       wake_up_process(priv->thread);
+out:
+       return ret;
+}
+
+static struct mips_cdmm_device_id mips_ejtag_fdc_tty_ids[] = {
+       { .type = 0xfd },
+       { }
+};
+
+static struct mips_cdmm_driver mips_ejtag_fdc_tty_driver = {
+       .drv            = {
+               .name   = "mips_ejtag_fdc",
+       },
+       .probe          = mips_ejtag_fdc_tty_probe,
+       .remove         = mips_ejtag_fdc_tty_remove,
+       .cpu_down       = mips_ejtag_fdc_tty_cpu_down,
+       .cpu_up         = mips_ejtag_fdc_tty_cpu_up,
+       .id_table       = mips_ejtag_fdc_tty_ids,
+};
+module_mips_cdmm_driver(mips_ejtag_fdc_tty_driver);
+
+static int __init mips_ejtag_fdc_init_console(void)
+{
+       return mips_ejtag_fdc_console_init(&mips_ejtag_fdc_con);
+}
+console_initcall(mips_ejtag_fdc_init_console);
+
+#ifdef CONFIG_MIPS_EJTAG_FDC_EARLYCON
+static struct mips_ejtag_fdc_console mips_ejtag_fdc_earlycon = {
+       .cons   = {
+               .name   = "early_fdc",
+               .write  = mips_ejtag_fdc_console_write,
+               .flags  = CON_PRINTBUFFER | CON_BOOT,
+               .index  = CONSOLE_CHANNEL,
+       },
+       .lock   = __RAW_SPIN_LOCK_UNLOCKED(mips_ejtag_fdc_earlycon.lock),
+};
+
+int __init setup_early_fdc_console(void)
+{
+       return mips_ejtag_fdc_console_init(&mips_ejtag_fdc_earlycon);
+}
+#endif
+
+#ifdef CONFIG_MIPS_EJTAG_FDC_KGDB
+
+/* read buffer to allow decompaction */
+static unsigned int kgdbfdc_rbuflen;
+static unsigned int kgdbfdc_rpos;
+static char kgdbfdc_rbuf[4];
+
+/* write buffer to allow compaction */
+static unsigned int kgdbfdc_wbuflen;
+static char kgdbfdc_wbuf[4];
+
+static void __iomem *kgdbfdc_setup(void)
+{
+       void __iomem *regs;
+       unsigned int cpu;
+
+       /* Find address, piggy backing off console percpu regs */
+       cpu = smp_processor_id();
+       regs = mips_ejtag_fdc_con.regs[cpu];
+       /* First console output on this CPU? */
+       if (!regs) {
+               regs = mips_cdmm_early_probe(0xfd);
+               mips_ejtag_fdc_con.regs[cpu] = regs;
+       }
+       /* Already tried and failed to find FDC on this CPU? */
+       if (IS_ERR(regs))
+               return regs;
+
+       return regs;
+}
+
+/* read a character from the read buffer, filling from FDC RX FIFO */
+static int kgdbfdc_read_char(void)
+{
+       unsigned int stat, channel, data;
+       void __iomem *regs;
+
+       /* No more data, try and read another FDC word from RX FIFO */
+       if (kgdbfdc_rpos >= kgdbfdc_rbuflen) {
+               kgdbfdc_rpos = 0;
+               kgdbfdc_rbuflen = 0;
+
+               regs = kgdbfdc_setup();
+               if (IS_ERR(regs))
+                       return NO_POLL_CHAR;
+
+               /* Read next word from KGDB channel */
+               do {
+                       stat = ioread32(regs + REG_FDSTAT);
+
+                       /* No data waiting? */
+                       if (stat & REG_FDSTAT_RXE)
+                               return NO_POLL_CHAR;
+
+                       /* Read next word */
+                       channel = (stat & REG_FDSTAT_RXCHAN) >>
+                                       REG_FDSTAT_RXCHAN_SHIFT;
+                       data = ioread32(regs + REG_FDRX);
+               } while (channel != CONFIG_MIPS_EJTAG_FDC_KGDB_CHAN);
+
+               /* Decode into rbuf */
+               kgdbfdc_rbuflen = mips_ejtag_fdc_decode(data, kgdbfdc_rbuf);
+       }
+       pr_devel("kgdbfdc r %c\n", kgdbfdc_rbuf[kgdbfdc_rpos]);
+       return kgdbfdc_rbuf[kgdbfdc_rpos++];
+}
+
+/* push an FDC word from write buffer to TX FIFO */
+static void kgdbfdc_push_one(void)
+{
+       const char *bufs[1] = { kgdbfdc_wbuf };
+       struct fdc_word word;
+       void __iomem *regs;
+       unsigned int i;
+
+       /* Construct a word from any data in buffer */
+       word = mips_ejtag_fdc_encode(bufs, &kgdbfdc_wbuflen, 1);
+       /* Relocate any remaining data to beginnning of buffer */
+       kgdbfdc_wbuflen -= word.bytes;
+       for (i = 0; i < kgdbfdc_wbuflen; ++i)
+               kgdbfdc_wbuf[i] = kgdbfdc_wbuf[i + word.bytes];
+
+       regs = kgdbfdc_setup();
+       if (IS_ERR(regs))
+               return;
+
+       /* Busy wait until there's space in fifo */
+       while (ioread32(regs + REG_FDSTAT) & REG_FDSTAT_TXF)
+               ;
+       iowrite32(word.word, regs + REG_FDTX(CONFIG_MIPS_EJTAG_FDC_KGDB_CHAN));
+}
+
+/* flush the whole write buffer to the TX FIFO */
+static void kgdbfdc_flush(void)
+{
+       while (kgdbfdc_wbuflen)
+               kgdbfdc_push_one();
+}
+
+/* write a character into the write buffer, writing out if full */
+static void kgdbfdc_write_char(u8 chr)
+{
+       pr_devel("kgdbfdc w %c\n", chr);
+       kgdbfdc_wbuf[kgdbfdc_wbuflen++] = chr;
+       if (kgdbfdc_wbuflen >= sizeof(kgdbfdc_wbuf))
+               kgdbfdc_push_one();
+}
+
+static struct kgdb_io kgdbfdc_io_ops = {
+       .name           = "kgdbfdc",
+       .read_char      = kgdbfdc_read_char,
+       .write_char     = kgdbfdc_write_char,
+       .flush          = kgdbfdc_flush,
+};
+
+static int __init kgdbfdc_init(void)
+{
+       kgdb_register_io_module(&kgdbfdc_io_ops);
+       return 0;
+}
+early_initcall(kgdbfdc_init);
+#endif
diff --git a/include/dt-bindings/clock/pistachio-clk.h b/include/dt-bindings/clock/pistachio-clk.h
new file mode 100644 (file)
index 0000000..039f83f
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_PISTACHIO_H
+#define _DT_BINDINGS_CLOCK_PISTACHIO_H
+
+/* PLLs */
+#define CLK_MIPS_PLL                   0
+#define CLK_AUDIO_PLL                  1
+#define CLK_RPU_V_PLL                  2
+#define CLK_RPU_L_PLL                  3
+#define CLK_SYS_PLL                    4
+#define CLK_WIFI_PLL                   5
+#define CLK_BT_PLL                     6
+
+/* Fixed-factor clocks */
+#define CLK_WIFI_DIV4                  16
+#define CLK_WIFI_DIV8                  17
+
+/* Gate clocks */
+#define CLK_MIPS                       32
+#define CLK_AUDIO_IN                   33
+#define CLK_AUDIO                      34
+#define CLK_I2S                                35
+#define CLK_SPDIF                      36
+#define CLK_AUDIO_DAC                  37
+#define CLK_RPU_V                      38
+#define CLK_RPU_L                      39
+#define CLK_RPU_SLEEP                  40
+#define CLK_WIFI_PLL_GATE              41
+#define CLK_RPU_CORE                   42
+#define CLK_WIFI_ADC                   43
+#define CLK_WIFI_DAC                   44
+#define CLK_USB_PHY                    45
+#define CLK_ENET_IN                    46
+#define CLK_ENET                       47
+#define CLK_UART0                      48
+#define CLK_UART1                      49
+#define CLK_PERIPH_SYS                 50
+#define CLK_SPI0                       51
+#define CLK_SPI1                       52
+#define CLK_EVENT_TIMER                        53
+#define CLK_AUX_ADC_INTERNAL           54
+#define CLK_AUX_ADC                    55
+#define CLK_SD_HOST                    56
+#define CLK_BT                         57
+#define CLK_BT_DIV4                    58
+#define CLK_BT_DIV8                    59
+#define CLK_BT_1MHZ                    60
+
+/* Divider clocks */
+#define CLK_MIPS_INTERNAL_DIV          64
+#define CLK_MIPS_DIV                   65
+#define CLK_AUDIO_DIV                  66
+#define CLK_I2S_DIV                    67
+#define CLK_SPDIF_DIV                  68
+#define CLK_AUDIO_DAC_DIV              69
+#define CLK_RPU_V_DIV                  70
+#define CLK_RPU_L_DIV                  71
+#define CLK_RPU_SLEEP_DIV              72
+#define CLK_RPU_CORE_DIV               73
+#define CLK_USB_PHY_DIV                        74
+#define CLK_ENET_DIV                   75
+#define CLK_UART0_INTERNAL_DIV         76
+#define CLK_UART0_DIV                  77
+#define CLK_UART1_INTERNAL_DIV         78
+#define CLK_UART1_DIV                  79
+#define CLK_SYS_INTERNAL_DIV           80
+#define CLK_SPI0_INTERNAL_DIV          81
+#define CLK_SPI0_DIV                   82
+#define CLK_SPI1_INTERNAL_DIV          83
+#define CLK_SPI1_DIV                   84
+#define CLK_EVENT_TIMER_INTERNAL_DIV   85
+#define CLK_EVENT_TIMER_DIV            86
+#define CLK_AUX_ADC_INTERNAL_DIV       87
+#define CLK_AUX_ADC_DIV                        88
+#define CLK_SD_HOST_DIV                        89
+#define CLK_BT_DIV                     90
+#define CLK_BT_DIV4_DIV                        91
+#define CLK_BT_DIV8_DIV                        92
+#define CLK_BT_1MHZ_INTERNAL_DIV       93
+#define CLK_BT_1MHZ_DIV                        94
+
+/* Mux clocks */
+#define CLK_AUDIO_REF_MUX              96
+#define CLK_MIPS_PLL_MUX               97
+#define CLK_AUDIO_PLL_MUX              98
+#define CLK_AUDIO_MUX                  99
+#define CLK_RPU_V_PLL_MUX              100
+#define CLK_RPU_L_PLL_MUX              101
+#define CLK_RPU_L_MUX                  102
+#define CLK_WIFI_PLL_MUX               103
+#define CLK_WIFI_DIV4_MUX              104
+#define CLK_WIFI_DIV8_MUX              105
+#define CLK_RPU_CORE_MUX               106
+#define CLK_SYS_PLL_MUX                        107
+#define CLK_ENET_MUX                   108
+#define CLK_EVENT_TIMER_MUX            109
+#define CLK_SD_HOST_MUX                        110
+#define CLK_BT_PLL_MUX                 111
+#define CLK_DEBUG_MUX                  112
+
+#define CLK_NR_CLKS                    113
+
+/* Peripheral gate clocks */
+#define PERIPH_CLK_SYS                 0
+#define PERIPH_CLK_SYS_BUS             1
+#define PERIPH_CLK_DDR                 2
+#define PERIPH_CLK_ROM                 3
+#define PERIPH_CLK_COUNTER_FAST                4
+#define PERIPH_CLK_COUNTER_SLOW                5
+#define PERIPH_CLK_IR                  6
+#define PERIPH_CLK_WD                  7
+#define PERIPH_CLK_PDM                 8
+#define PERIPH_CLK_PWM                 9
+#define PERIPH_CLK_I2C0                        10
+#define PERIPH_CLK_I2C1                        11
+#define PERIPH_CLK_I2C2                        12
+#define PERIPH_CLK_I2C3                        13
+
+/* Peripheral divider clocks */
+#define PERIPH_CLK_ROM_DIV             32
+#define PERIPH_CLK_COUNTER_FAST_DIV    33
+#define PERIPH_CLK_COUNTER_SLOW_PRE_DIV        34
+#define PERIPH_CLK_COUNTER_SLOW_DIV    35
+#define PERIPH_CLK_IR_PRE_DIV          36
+#define PERIPH_CLK_IR_DIV              37
+#define PERIPH_CLK_WD_PRE_DIV          38
+#define PERIPH_CLK_WD_DIV              39
+#define PERIPH_CLK_PDM_PRE_DIV         40
+#define PERIPH_CLK_PDM_DIV             41
+#define PERIPH_CLK_PWM_PRE_DIV         42
+#define PERIPH_CLK_PWM_DIV             43
+#define PERIPH_CLK_I2C0_PRE_DIV                44
+#define PERIPH_CLK_I2C0_DIV            45
+#define PERIPH_CLK_I2C1_PRE_DIV                46
+#define PERIPH_CLK_I2C1_DIV            47
+#define PERIPH_CLK_I2C2_PRE_DIV                48
+#define PERIPH_CLK_I2C2_DIV            49
+#define PERIPH_CLK_I2C3_PRE_DIV                50
+#define PERIPH_CLK_I2C3_DIV            51
+
+#define PERIPH_CLK_NR_CLKS             52
+
+/* System gate clocks */
+#define SYS_CLK_I2C0                   0
+#define SYS_CLK_I2C1                   1
+#define SYS_CLK_I2C2                   2
+#define SYS_CLK_I2C3                   3
+#define SYS_CLK_I2S_IN                 4
+#define SYS_CLK_PAUD_OUT               5
+#define SYS_CLK_SPDIF_OUT              6
+#define SYS_CLK_SPI0_MASTER            7
+#define SYS_CLK_SPI0_SLAVE             8
+#define SYS_CLK_PWM                    9
+#define SYS_CLK_UART0                  10
+#define SYS_CLK_UART1                  11
+#define SYS_CLK_SPI1                   12
+#define SYS_CLK_MDC                    13
+#define SYS_CLK_SD_HOST                        14
+#define SYS_CLK_ENET                   15
+#define SYS_CLK_IR                     16
+#define SYS_CLK_WD                     17
+#define SYS_CLK_TIMER                  18
+#define SYS_CLK_I2S_OUT                        24
+#define SYS_CLK_SPDIF_IN               25
+#define SYS_CLK_EVENT_TIMER            26
+#define SYS_CLK_HASH                   27
+
+#define SYS_CLK_NR_CLKS                        28
+
+/* Gates for external input clocks */
+#define EXT_CLK_AUDIO_IN               0
+#define EXT_CLK_ENET_IN                        1
+
+#define EXT_CLK_NR_CLKS                        2
+
+#endif /* _DT_BINDINGS_CLOCK_PISTACHIO_H */
similarity index 63%
rename from arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h
rename to include/linux/bcm47xx_nvram.h
index ee59ffe..b12b07e 100644 (file)
@@ -1,7 +1,4 @@
 /*
- *  Copyright (C) 2005, Broadcom Corporation
- *  Copyright (C) 2006, Felix Fietkau <nbd@openwrt.org>
- *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
  *  Free Software Foundation;  either version 2 of the  License, or (at your
 #include <linux/types.h>
 #include <linux/kernel.h>
 
+#ifdef CONFIG_BCM47XX
 int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
 int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
 int bcm47xx_nvram_gpio_pin(const char *name);
+#else
+static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
+{
+       return -ENOTSUPP;
+};
+static inline int bcm47xx_nvram_getenv(const char *name, char *val,
+                                      size_t val_len)
+{
+       return -ENOTSUPP;
+};
+static inline int bcm47xx_nvram_gpio_pin(const char *name)
+{
+       return -ENOTSUPP;
+};
+#endif
 
 #endif /* __BCM47XX_NVRAM_H */
index 3ea2e47..9b1ad37 100644 (file)
 #define GIC_VPE_PEND_SWINT0_MSK                (MSK(1) << GIC_VPE_PEND_SWINT0_SHF)
 #define GIC_VPE_PEND_SWINT1_SHF                5
 #define GIC_VPE_PEND_SWINT1_MSK                (MSK(1) << GIC_VPE_PEND_SWINT1_SHF)
+#define GIC_VPE_PEND_FDC_SHF           6
+#define GIC_VPE_PEND_FDC_MSK           (MSK(1) << GIC_VPE_PEND_FDC_SHF)
 
 /* GIC_VPE_RMASK Masks */
 #define GIC_VPE_RMASK_WD_SHF           0
 #define GIC_VPE_RMASK_SWINT0_MSK       (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF)
 #define GIC_VPE_RMASK_SWINT1_SHF       5
 #define GIC_VPE_RMASK_SWINT1_MSK       (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF)
+#define GIC_VPE_RMASK_FDC_SHF          6
+#define GIC_VPE_RMASK_FDC_MSK          (MSK(1) << GIC_VPE_RMASK_FDC_SHF)
 
 /* GIC_VPE_SMASK Masks */
 #define GIC_VPE_SMASK_WD_SHF           0
 #define GIC_VPE_SMASK_SWINT0_MSK       (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF)
 #define GIC_VPE_SMASK_SWINT1_SHF       5
 #define GIC_VPE_SMASK_SWINT1_MSK       (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF)
+#define GIC_VPE_SMASK_FDC_SHF          6
+#define GIC_VPE_SMASK_FDC_MSK          (MSK(1) << GIC_VPE_SMASK_FDC_SHF)
 
 /* GIC nomenclature for Core Interrupt Pins. */
 #define GIC_CPU_INT0           0 /* Core Interrupt 2 */
@@ -247,4 +253,5 @@ extern unsigned int plat_ipi_call_int_xlate(unsigned int);
 extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
 extern int gic_get_c0_compare_int(void);
 extern int gic_get_c0_perfcount_int(void);
+extern int gic_get_c0_fdc_int(void);
 #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */
index e530533..3bfd567 100644 (file)
@@ -546,6 +546,14 @@ struct amba_id {
        void                    *data;
 };
 
+/**
+ * struct mips_cdmm_device_id - identifies devices in MIPS CDMM bus
+ * @type:      Device type identifier.
+ */
+struct mips_cdmm_device_id {
+       __u8    type;
+};
+
 /*
  * Match x86 CPUs for CPU specific drivers.
  * See documentation of "x86_match_cpu" for details.
index f282516..fce36d0 100644 (file)
@@ -168,6 +168,9 @@ int main(void)
        DEVID_FIELD(amba_id, id);
        DEVID_FIELD(amba_id, mask);
 
+       DEVID(mips_cdmm_device_id);
+       DEVID_FIELD(mips_cdmm_device_id, type);
+
        DEVID(x86_cpu_id);
        DEVID_FIELD(x86_cpu_id, feature);
        DEVID_FIELD(x86_cpu_id, family);
index e614ef6..78691d5 100644 (file)
@@ -1109,6 +1109,22 @@ static int do_amba_entry(const char *filename,
 }
 ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry);
 
+/*
+ * looks like: "mipscdmm:tN"
+ *
+ * N is exactly 2 digits, where each is an upper-case hex digit, or
+ *     a ? or [] pattern matching exactly one digit.
+ */
+static int do_mips_cdmm_entry(const char *filename,
+                             void *symval, char *alias)
+{
+       DEF_FIELD(symval, mips_cdmm_device_id, type);
+
+       sprintf(alias, "mipscdmm:t%02X*", type);
+       return 1;
+}
+ADD_TO_DEVTABLE("mipscdmm", mips_cdmm_device_id, do_mips_cdmm_entry);
+
 /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,*
  * All fields are numbers. It would be nicer to use strings for vendor
  * and feature, but getting those out of the build system here is too