Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 Jan 2014 01:20:32 +0000 (17:20 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 31 Jan 2014 01:20:32 +0000 (17:20 -0800)
Pull MIPS updates from Ralf Baechle:
 "The most notable new addition inside this pull request is the support
  for MIPS's latest and greatest core called "inter/proAptiv".  The
  patch series describes this core as follows.

    "The interAptiv is a power-efficient multi-core microprocessor
     for use in system-on-chip (SoC) applications. The interAptiv combines
     a multi-threading pipeline with a coherence manager to deliver improved
     computational throughput and power efficiency. The interAptiv can
     contain one to four MIPS32R3 interAptiv cores, system level
     coherence manager with L2 cache, optional coherent I/O port,
     and optional floating point unit."

  The platform specific patches touch all 3 Broadcom families.  It adds
  support for the new Broadcom/Netlogix XLP9xx Soc, building a common
  BCM63XX SMP kernel for all BCM63XX SoCs regardless of core type/count
  and full gpio button/led descriptions for BCM47xx.

  The rest of the series are cleanups and bug fixes that are MIPS
  generic and consist largely of changes that Imgtec/MIPS had published
  in their linux-mti-3.10.git stable tree.  Random other cleanups and
  patches preparing code to be merged in 3.15"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (139 commits)
  mips: select ARCH_MIGHT_HAVE_PC_SERIO
  mips: delete non-required instances of include <linux/init.h>
  MIPS: KVM: remove shadow_tlb code
  MIPS: KVM: use common EHINV aware UNIQUE_ENTRYHI
  mips/ide: flush dcache also if icache does not snoop dcache
  MIPS: BCM47XX: fix position of cpu_wait disabling
  MIPS: BCM63XX: select correct MIPS_L1_CACHE_SHIFT value
  MIPS: update MIPS_L1_CACHE_SHIFT based on MIPS_L1_CACHE_SHIFT_<N>
  MIPS: introduce MIPS_L1_CACHE_SHIFT_<N>
  MIPS: ZBOOT: gather string functions into string.c
  arch/mips/pci: don't check resource with devm_ioremap_resource
  arch/mips/lantiq/xway: don't check resource with devm_ioremap_resource
  bcma: gpio: don't cast u32 to unsigned long
  ssb: gpio: add own IRQ domain
  MIPS: BCM47XX: fix sparse warnings in board.c
  MIPS: BCM47XX: add board detection for Linksys WRT54GS V1
  MIPS: BCM47XX: fix detection for some boards
  MIPS: BCM47XX: Enable buttons support on SSB
  MIPS: BCM47XX: Convert WNDR4500 to new syntax
  MIPS: BCM47XX: Use "timer" trigger for status LEDs
  ...

224 files changed:
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/alchemy/common/power.c
arch/mips/ar7/time.c
arch/mips/ath79/common.h
arch/mips/bcm47xx/Kconfig
arch/mips/bcm47xx/Makefile
arch/mips/bcm47xx/bcm47xx_private.h [new file with mode: 0644]
arch/mips/bcm47xx/board.c
arch/mips/bcm47xx/buttons.c [new file with mode: 0644]
arch/mips/bcm47xx/irq.c
arch/mips/bcm47xx/leds.c [new file with mode: 0644]
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/wgt634u.c [deleted file]
arch/mips/bcm63xx/Kconfig
arch/mips/bcm63xx/Makefile
arch/mips/bcm63xx/boards/board_bcm963xx.c
arch/mips/bcm63xx/clk.c
arch/mips/bcm63xx/cpu.c
arch/mips/bcm63xx/dev-hsspi.c [new file with mode: 0644]
arch/mips/bcm63xx/early_printk.c
arch/mips/bcm63xx/prom.c
arch/mips/boot/compressed/Makefile
arch/mips/boot/compressed/dbg.c
arch/mips/boot/compressed/decompress.c
arch/mips/boot/compressed/string.c [new file with mode: 0644]
arch/mips/boot/compressed/uart-16550.c
arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c
arch/mips/cavium-octeon/executive/cvmx-helper-board.c
arch/mips/cavium-octeon/executive/cvmx-helper-util.c
arch/mips/cavium-octeon/executive/cvmx-helper.c
arch/mips/cavium-octeon/executive/cvmx-pko.c
arch/mips/cavium-octeon/executive/cvmx-spi.c
arch/mips/cavium-octeon/octeon-platform.c
arch/mips/cavium-octeon/octeon_3xxx.dts
arch/mips/cavium-octeon/smp.c
arch/mips/configs/ar7_defconfig
arch/mips/configs/bcm47xx_defconfig
arch/mips/configs/bcm63xx_defconfig
arch/mips/configs/cobalt_defconfig
arch/mips/configs/gpr_defconfig
arch/mips/configs/jmr3927_defconfig
arch/mips/configs/lasat_defconfig
arch/mips/configs/maltasmvp_defconfig
arch/mips/configs/markeins_defconfig
arch/mips/configs/mtx1_defconfig
arch/mips/configs/pnx8335_stb225_defconfig
arch/mips/configs/qi_lb60_defconfig [new file with mode: 0644]
arch/mips/configs/rb532_defconfig
arch/mips/configs/rbtx49xx_defconfig
arch/mips/fw/arc/file.c
arch/mips/include/asm/amon.h
arch/mips/include/asm/asmmacro-32.h
arch/mips/include/asm/asmmacro-64.h
arch/mips/include/asm/asmmacro.h
arch/mips/include/asm/bmips.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-coherence.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/fpu.h
arch/mips/include/asm/highmem.h
arch/mips/include/asm/kvm_host.h
arch/mips/include/asm/mach-ath79/ar71xx_regs.h
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
arch/mips/include/asm/mach-generic/dma-coherence.h
arch/mips/include/asm/mach-generic/floppy.h
arch/mips/include/asm/mach-generic/ide.h
arch/mips/include/asm/mach-jazz/floppy.h
arch/mips/include/asm/mach-jz4740/platform.h
arch/mips/include/asm/mach-netlogic/irq.h
arch/mips/include/asm/mach-netlogic/multi-node.h
arch/mips/include/asm/mach-netlogic/topology.h [new file with mode: 0644]
arch/mips/include/asm/mips-boards/piix4.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/bridge.h
arch/mips/include/asm/netlogic/xlp-hal/iomap.h
arch/mips/include/asm/netlogic/xlp-hal/pcibus.h
arch/mips/include/asm/netlogic/xlp-hal/pic.h
arch/mips/include/asm/netlogic/xlp-hal/sys.h
arch/mips/include/asm/netlogic/xlp-hal/uart.h
arch/mips/include/asm/netlogic/xlp-hal/xlp.h
arch/mips/include/asm/netlogic/xlr/xlr.h
arch/mips/include/asm/octeon/cvmx-helper-board.h
arch/mips/include/asm/page.h
arch/mips/include/asm/rtlx.h
arch/mips/include/asm/switch_to.h
arch/mips/include/asm/syscall.h
arch/mips/include/asm/thread_info.h
arch/mips/include/asm/tlb.h
arch/mips/include/asm/vpe.h
arch/mips/include/uapi/asm/inst.h
arch/mips/jz4740/board-qi_lb60.c
arch/mips/jz4740/platform.c
arch/mips/kernel/Makefile
arch/mips/kernel/binfmt_elfo32.c
arch/mips/kernel/bmips_vec.S
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/crash.c
arch/mips/kernel/genex.S
arch/mips/kernel/idle.c
arch/mips/kernel/proc.c
arch/mips/kernel/process.c
arch/mips/kernel/ptrace.c
arch/mips/kernel/ptrace32.c
arch/mips/kernel/r4k_fpu.S
arch/mips/kernel/r4k_switch.S
arch/mips/kernel/rtlx-cmp.c [new file with mode: 0644]
arch/mips/kernel/rtlx-mt.c [new file with mode: 0644]
arch/mips/kernel/rtlx.c
arch/mips/kernel/segment.c [new file with mode: 0644]
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/smp-bmips.c
arch/mips/kernel/smp-cmp.c
arch/mips/kernel/smp-mt.c
arch/mips/kernel/spram.c
arch/mips/kernel/sync-r4k.c
arch/mips/kernel/traps.c
arch/mips/kernel/vpe-cmp.c [new file with mode: 0644]
arch/mips/kernel/vpe-mt.c [new file with mode: 0644]
arch/mips/kernel/vpe.c
arch/mips/kvm/kvm_mips.c
arch/mips/kvm/kvm_tlb.c
arch/mips/lantiq/xway/clk.c
arch/mips/lantiq/xway/dma.c
arch/mips/lasat/at93c.c
arch/mips/lasat/picvue.c
arch/mips/lib/uncached.c
arch/mips/loongson/lemote-2f/clock.c
arch/mips/math-emu/cp1emu.c
arch/mips/math-emu/kernel_linkage.c
arch/mips/mm/c-octeon.c
arch/mips/mm/c-r3k.c
arch/mips/mm/c-r4k.c
arch/mips/mm/cache.c
arch/mips/mm/cex-sb1.S
arch/mips/mm/dma-default.c
arch/mips/mm/hugetlbpage.c
arch/mips/mm/init.c
arch/mips/mm/page.c
arch/mips/mm/sc-mips.c
arch/mips/mm/sc-rm7k.c
arch/mips/mm/tlb-r3k.c
arch/mips/mm/tlb-r4k.c
arch/mips/mm/tlb-r8k.c
arch/mips/mm/tlbex.c
arch/mips/mm/uasm-micromips.c
arch/mips/mm/uasm-mips.c
arch/mips/mti-malta/Makefile
arch/mips/mti-malta/malta-amon.c
arch/mips/mti-malta/malta-console.c [deleted file]
arch/mips/mti-malta/malta-init.c
arch/mips/mti-malta/malta-int.c
arch/mips/mti-malta/malta-platform.c
arch/mips/mti-malta/malta-time.c
arch/mips/mti-sead3/Makefile
arch/mips/mti-sead3/sead3-pic32-bus.c
arch/mips/mti-sead3/sead3-setup.c
arch/mips/mti-sead3/sead3-time.c
arch/mips/mti-sead3/sead3.dts
arch/mips/netlogic/Kconfig
arch/mips/netlogic/common/earlycons.c
arch/mips/netlogic/common/irq.c
arch/mips/netlogic/common/reset.S
arch/mips/netlogic/common/smp.c
arch/mips/netlogic/common/smpboot.S
arch/mips/netlogic/dts/Makefile
arch/mips/netlogic/dts/xlp_gvp.dts [new file with mode: 0644]
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/netlogic/xlr/platform.c
arch/mips/netlogic/xlr/setup.c
arch/mips/netlogic/xlr/wakeup.c
arch/mips/oprofile/common.c
arch/mips/oprofile/op_model_mipsxx.c
arch/mips/pci/Makefile
arch/mips/pci/fixup-malta.c
arch/mips/pci/fixup-rc32434.c
arch/mips/pci/fixup-sb1250.c
arch/mips/pci/msi-xlp.c [new file with mode: 0644]
arch/mips/pci/ops-bcm63xx.c
arch/mips/pci/ops-bonito64.c
arch/mips/pci/ops-lantiq.c
arch/mips/pci/ops-loongson2.c
arch/mips/pci/ops-mace.c
arch/mips/pci/ops-msc.c
arch/mips/pci/ops-nile4.c
arch/mips/pci/ops-rc32434.c
arch/mips/pci/pci-ip27.c
arch/mips/pci/pci-malta.c
arch/mips/pci/pci-rt3883.c
arch/mips/pci/pci-xlp.c
arch/mips/pmcs-msp71xx/Kconfig
arch/mips/ralink/Kconfig
arch/mips/sgi-ip27/ip27-console.c
arch/mips/sgi-ip27/ip27-irq-pci.c
arch/mips/sgi-ip27/ip27-klconfig.c
arch/mips/sgi-ip27/ip27-xtalk.c
drivers/bcma/Kconfig
drivers/bcma/driver_gpio.c
drivers/ssb/Kconfig
drivers/ssb/driver_gpio.c
drivers/ssb/main.c
drivers/tty/serial/bcm63xx_uart.c
include/linux/bcma/bcma_driver_chipcommon.h
include/linux/serial_bcm63xx.h [new file with mode: 0644]
include/linux/ssb/ssb.h

index c02f1c0..dcae3a7 100644 (file)
@@ -116,7 +116,6 @@ config BCM47XX
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
-       select FW_CFE
        select HW_HAS_PCI
        select IRQ_CPU
        select SYS_HAS_CPU_MIPS32_R1
@@ -124,6 +123,7 @@ config BCM47XX
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
        select SYS_HAS_EARLY_PRINTK
+       select EARLY_PRINTK_8250 if EARLY_PRINTK
        help
         Support for BCM47XX based boards
 
@@ -134,14 +134,13 @@ config BCM63XX
        select CSRC_R4K
        select DMA_NONCOHERENT
        select IRQ_CPU
-       select SYS_HAS_CPU_MIPS32_R1
-       select SYS_HAS_CPU_BMIPS4350 if !BCM63XX_CPU_6338 && !BCM63XX_CPU_6345 && !BCM63XX_CPU_6348
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_HAS_EARLY_PRINTK
        select SWAP_IO_SPACE
        select ARCH_REQUIRE_GPIOLIB
        select HAVE_CLK
+       select MIPS_L1_CACHE_SHIFT_4
        help
         Support for BCM63XX based boards
 
@@ -186,6 +185,7 @@ config MACH_DECSTATION
        select SYS_SUPPORTS_128HZ
        select SYS_SUPPORTS_256HZ
        select SYS_SUPPORTS_1024HZ
+       select MIPS_L1_CACHE_SHIFT_4
        help
          This enables support for DEC's MIPS based workstations.  For details
          see the Linux/MIPS FAQ on <http://www.linux-mips.org/> and the
@@ -305,7 +305,7 @@ config MIPS_MALTA
        select CEVT_R4K
        select CSRC_R4K
        select CSRC_GIC
-       select DMA_NONCOHERENT
+       select DMA_MAYBE_COHERENT
        select GENERIC_ISA_DMA
        select HAVE_PCSPKR_PLATFORM
        select IRQ_CPU
@@ -324,7 +324,6 @@ config MIPS_MALTA
        select SYS_HAS_CPU_MIPS64_R2
        select SYS_HAS_CPU_NEVADA
        select SYS_HAS_CPU_RM7000
-       select SYS_HAS_EARLY_PRINTK
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
@@ -349,6 +348,7 @@ config MIPS_SEAD3
        select DMA_NONCOHERENT
        select IRQ_CPU
        select IRQ_GIC
+       select LIBFDT
        select MIPS_MSC
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_HAS_CPU_MIPS32_R2
@@ -471,6 +471,7 @@ config SGI_IP22
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
+       select MIPS_L1_CACHE_SHIFT_7
        help
          This are the SGI Indy, Challenge S and Indigo2, as well as certain
          OEM variants like the Tandem CMN B006S. To compile a Linux kernel
@@ -491,6 +492,7 @@ config SGI_IP27
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_NUMA
        select SYS_SUPPORTS_SMP
+       select MIPS_L1_CACHE_SHIFT_7
        help
          This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
          workstations.  To compile a Linux kernel that runs on these, say Y
@@ -697,6 +699,7 @@ config MIKROTIK_RB532
        select SWAP_IO_SPACE
        select BOOT_RAW
        select ARCH_REQUIRE_GPIOLIB
+       select MIPS_L1_CACHE_SHIFT_4
        help
          Support the Mikrotik(tm) RouterBoard 532 series,
          based on the IDT RC32434 SoC.
@@ -779,6 +782,7 @@ config NLM_XLP_BOARD
        select CEVT_R4K
        select CSRC_R4K
        select IRQ_CPU
+       select ARCH_SUPPORTS_MSI
        select ZONE_DMA32 if 64BIT
        select SYNC_R4K
        select SYS_HAS_EARLY_PRINTK
@@ -897,6 +901,10 @@ config FW_CFE
 config ARCH_DMA_ADDR_T_64BIT
        def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT
 
+config DMA_MAYBE_COHERENT
+       select DMA_NONCOHERENT
+       bool
+
 config DMA_COHERENT
        bool
 
@@ -1091,11 +1099,24 @@ config FW_SNIPROM
 config BOOT_ELF32
        bool
 
+config MIPS_L1_CACHE_SHIFT_4
+       bool
+
+config MIPS_L1_CACHE_SHIFT_5
+       bool
+
+config MIPS_L1_CACHE_SHIFT_6
+       bool
+
+config MIPS_L1_CACHE_SHIFT_7
+       bool
+
 config MIPS_L1_CACHE_SHIFT
        int
-       default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL || SOC_RT288X
-       default "6" if MIPS_CPU_SCACHE
-       default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
+       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 "5"
 
 config HAVE_STD_PC_SERIAL_PORT
@@ -1375,47 +1396,31 @@ config CPU_CAVIUM_OCTEON
        select LIBFDT
        select USE_OF
        select USB_EHCI_BIG_ENDIAN_MMIO
+       select SYS_HAS_DMA_OPS
+       select MIPS_L1_CACHE_SHIFT_7
        help
          The Cavium Octeon processor is a highly integrated chip containing
          many ethernet hardware widgets for networking tasks. The processor
          can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
          Full details can be found at http://www.caviumnetworks.com.
 
-config CPU_BMIPS3300
-       bool "BMIPS3300"
-       depends on SYS_HAS_CPU_BMIPS3300
-       select CPU_BMIPS
-       help
-         Broadcom BMIPS3300 processors.
-
-config CPU_BMIPS4350
-       bool "BMIPS4350"
-       depends on SYS_HAS_CPU_BMIPS4350
-       select CPU_BMIPS
-       select SYS_SUPPORTS_SMP
-       select SYS_SUPPORTS_HOTPLUG_CPU
-       help
-         Broadcom BMIPS4350 ("VIPER") processors.
-
-config CPU_BMIPS4380
-       bool "BMIPS4380"
-       depends on SYS_HAS_CPU_BMIPS4380
-       select CPU_BMIPS
-       select SYS_SUPPORTS_SMP
-       select SYS_SUPPORTS_HOTPLUG_CPU
-       help
-         Broadcom BMIPS4380 processors.
-
-config CPU_BMIPS5000
-       bool "BMIPS5000"
-       depends on SYS_HAS_CPU_BMIPS5000
-       select CPU_BMIPS
+config CPU_BMIPS
+       bool "Broadcom BMIPS"
+       depends on SYS_HAS_CPU_BMIPS
+       select CPU_MIPS32
+       select CPU_BMIPS32_3300 if SYS_HAS_CPU_BMIPS32_3300
+       select CPU_BMIPS4350 if SYS_HAS_CPU_BMIPS4350
+       select CPU_BMIPS4380 if SYS_HAS_CPU_BMIPS4380
+       select CPU_BMIPS5000 if SYS_HAS_CPU_BMIPS5000
+       select CPU_SUPPORTS_32BIT_KERNEL
+       select DMA_NONCOHERENT
+       select IRQ_CPU
+       select SWAP_IO_SPACE
+       select WEAK_ORDERING
        select CPU_SUPPORTS_HIGHMEM
-       select MIPS_CPU_SCACHE
-       select SYS_SUPPORTS_SMP
-       select SYS_SUPPORTS_HOTPLUG_CPU
+       select CPU_HAS_PREFETCH
        help
-         Broadcom BMIPS5000 processors.
+         Support for BMIPS32/3300/4350/4380 and BMIPS5000 processors.
 
 config CPU_XLR
        bool "Netlogic XLR SoC"
@@ -1498,14 +1503,25 @@ config CPU_LOONGSON1
        select CPU_SUPPORTS_32BIT_KERNEL
        select CPU_SUPPORTS_HIGHMEM
 
-config CPU_BMIPS
+config CPU_BMIPS32_3300
+       select SMP_UP if SMP
        bool
-       select CPU_MIPS32
-       select CPU_SUPPORTS_32BIT_KERNEL
-       select DMA_NONCOHERENT
-       select IRQ_CPU
-       select SWAP_IO_SPACE
-       select WEAK_ORDERING
+
+config CPU_BMIPS4350
+       bool
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
+
+config CPU_BMIPS4380
+       bool
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
+
+config CPU_BMIPS5000
+       bool
+       select MIPS_CPU_SCACHE
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_HOTPLUG_CPU
 
 config SYS_HAS_CPU_LOONGSON2E
        bool
@@ -1579,17 +1595,24 @@ config SYS_HAS_CPU_SB1
 config SYS_HAS_CPU_CAVIUM_OCTEON
        bool
 
-config SYS_HAS_CPU_BMIPS3300
+config SYS_HAS_CPU_BMIPS
+       bool
+
+config SYS_HAS_CPU_BMIPS32_3300
        bool
+       select SYS_HAS_CPU_BMIPS
 
 config SYS_HAS_CPU_BMIPS4350
        bool
+       select SYS_HAS_CPU_BMIPS
 
 config SYS_HAS_CPU_BMIPS4380
        bool
+       select SYS_HAS_CPU_BMIPS
 
 config SYS_HAS_CPU_BMIPS5000
        bool
+       select SYS_HAS_CPU_BMIPS
 
 config SYS_HAS_CPU_XLR
        bool
@@ -1797,6 +1820,7 @@ config IP22_CPU_SCACHE
 config MIPS_CPU_SCACHE
        bool
        select BOARD_SCACHE
+       select MIPS_L1_CACHE_SHIFT_6
 
 config R5000_CPU_SCACHE
        bool
@@ -1833,59 +1857,48 @@ choice
        prompt "MIPS MT options"
 
 config MIPS_MT_DISABLED
-       bool "Disable multithreading support."
+       bool "Disable multithreading support"
        help
-         Use this option if your workload can't take advantage of
-         MIPS hardware multithreading support.  On systems that don't have
-         the option of an MT-enabled processor this option will be the only
-         option in this menu.
+         Use this option if your platform does not support the MT ASE
+         which is hardware multithreading support. On systems without
+         an MT-enabled processor, this will be the only option that is
+         available in this menu.
 
 config MIPS_MT_SMP
        bool "Use 1 TC on each available VPE for SMP"
        depends on SYS_SUPPORTS_MULTITHREADING
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_IRQ_EI
+       select SYNC_R4K
        select MIPS_MT
        select SMP
-       select SYS_SUPPORTS_SCHED_SMT if SMP
-       select SYS_SUPPORTS_SMP
        select SMP_UP
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_SCHED_SMT
        select MIPS_PERF_SHARED_TC_COUNTERS
        help
-         This is a kernel model which is known a VSMP but lately has been
-         marketesed into SMVP.
-         Virtual SMP uses the processor's VPEs  to implement virtual
-         processors. In currently available configuration of the 34K processor
-         this allows for a dual processor. Both processors will share the same
-         primary caches; each will obtain the half of the TLB for it's own
-         exclusive use. For a layman this model can be described as similar to
-         what Intel calls Hyperthreading.
-
-         For further information see http://www.linux-mips.org/wiki/34K#VSMP
+         This is a kernel model which is known as SMVP. This is supported
+         on cores with the MT ASE and uses the available VPEs to implement
+         virtual processors which supports SMP. This is equivalent to the
+         Intel Hyperthreading feature. For further information go to
+         <http://www.imgtec.com/mips/mips-multithreading.asp>.
 
 config MIPS_MT_SMTC
-       bool "SMTC: Use all TCs on all VPEs for SMP"
+       bool "Use all TCs on all VPEs for SMP (DEPRECATED)"
        depends on CPU_MIPS32_R2
-       #depends on CPU_MIPS64_R2               # once there is hardware ...
        depends on SYS_SUPPORTS_MULTITHREADING
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_IRQ_EI
        select MIPS_MT
-       select NR_CPUS_DEFAULT_8
        select SMP
-       select SYS_SUPPORTS_SMP
        select SMP_UP
+       select SYS_SUPPORTS_SMP
+       select NR_CPUS_DEFAULT_8
        help
-         This is a kernel model which is known a SMTC or lately has been
-         marketesed into SMVP.
-         is presenting the available TC's of the core as processors to Linux.
-         On currently available 34K processors this means a Linux system will
-         see up to 5 processors. The implementation of the SMTC kernel differs
-         significantly from VSMP and cannot efficiently coexist in the same
-         kernel binary so the choice between VSMP and SMTC is a compile time
-         decision.
-
-         For further information see http://www.linux-mips.org/wiki/34K#SMTC
+         This is a kernel model which is known as SMTC. This is
+         supported on cores with the MT ASE and presents all TCs
+         available on all VPEs to support SMP. For further
+         information see <http://www.linux-mips.org/wiki/34K#SMTC>.
 
 endchoice
 
@@ -1922,6 +1935,16 @@ config MIPS_VPE_LOADER
          Includes a loader for loading an elf relocatable object
          onto another VPE and running it.
 
+config MIPS_VPE_LOADER_CMP
+       bool
+       default "y"
+       depends on MIPS_VPE_LOADER && MIPS_CMP
+
+config MIPS_VPE_LOADER_MT
+       bool
+       default "y"
+       depends on MIPS_VPE_LOADER && !MIPS_CMP
+
 config MIPS_MT_SMTC_IM_BACKSTOP
        bool "Use per-TC register bits as backstop for inhibited IM bits"
        depends on MIPS_MT_SMTC
@@ -1955,24 +1978,29 @@ config MIPS_VPE_LOADER_TOM
          you to ensure the amount you put in the option and the space your
          program requires is less or equal to the amount physically present.
 
-# this should possibly be in drivers/char, but it is rather cpu related. Hmmm
 config MIPS_VPE_APSP_API
        bool "Enable support for AP/SP API (RTLX)"
        depends on MIPS_VPE_LOADER
        help
 
+config MIPS_VPE_APSP_API_CMP
+       bool
+       default "y"
+       depends on MIPS_VPE_APSP_API && MIPS_CMP
+
+config MIPS_VPE_APSP_API_MT
+       bool
+       default "y"
+       depends on MIPS_VPE_APSP_API && !MIPS_CMP
+
 config MIPS_CMP
-       bool "MIPS CMP framework support"
-       depends on SYS_SUPPORTS_MIPS_CMP
-       select SMP
+       bool "MIPS CMP support"
+       depends on SYS_SUPPORTS_MIPS_CMP && MIPS_MT_SMP
        select SYNC_R4K
-       select SYS_SUPPORTS_SMP
-       select SYS_SUPPORTS_SCHED_SMT if SMP
        select WEAK_ORDERING
        default n
        help
-         This is a placeholder option for the GCMP work. It will need to
-         be handled differently...
+         Enable Coherency Manager processor (CMP) support.
 
 config SB1_PASS_1_WORKAROUNDS
        bool
@@ -2324,6 +2352,23 @@ config SECCOMP
 
          If unsure, say Y. Only embedded should say N here.
 
+config MIPS_O32_FP64_SUPPORT
+       bool "Support for O32 binaries using 64-bit FP"
+       depends on 32BIT || MIPS32_O32
+       default y
+       help
+         When this is enabled, the kernel will support use of 64-bit floating
+         point registers with binaries using the O32 ABI along with the
+         EF_MIPS_FP64 ELF header flag (typically built with -mfp64). On
+         32-bit MIPS systems this support is at the cost of increasing the
+         size and complexity of the compiled FPU emulator. Thus if you are
+         running a MIPS32 system and know that none of your userland binaries
+         will require 64-bit floating point, you may wish to reduce the size
+         of your kernel & potentially improve FP emulation performance by
+         saying N here.
+
+         If unsure, say Y.
+
 config USE_OF
        bool
        select OF
index efe5078..9b8556d 100644 (file)
@@ -114,7 +114,7 @@ cflags-$(CONFIG_CPU_BIG_ENDIAN)             += $(shell $(CC) -dumpmachine |grep -q 'mips.*e
 cflags-$(CONFIG_CPU_LITTLE_ENDIAN)     += $(shell $(CC) -dumpmachine |grep -q 'mips.*el-.*' || echo -EL $(undef-all) $(predef-le))
 
 cflags-$(CONFIG_CPU_HAS_SMARTMIPS)     += $(call cc-option,-msmartmips)
-cflags-$(CONFIG_CPU_MICROMIPS) += $(call cc-option,-mmicromips -mno-jals)
+cflags-$(CONFIG_CPU_MICROMIPS) += $(call cc-option,-mmicromips)
 
 cflags-$(CONFIG_SB1XXX_CORELIS)        += $(call cc-option,-mno-sched-prolog) \
                                   -fno-omit-frame-pointer
index 0c7fce2..bdb28de 100644 (file)
@@ -29,7 +29,6 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/sysctl.h>
 #include <linux/jiffies.h>
index 22c9321..1dc6c3b 100644 (file)
@@ -18,7 +18,6 @@
  * Setting up the clock on the MIPS boards.
  */
 
-#include <linux/init.h>
 #include <linux/time.h>
 #include <linux/err.h>
 #include <linux/clk.h>
index 648d2da..a312071 100644 (file)
@@ -15,7 +15,6 @@
 #define __ATH79_COMMON_H
 
 #include <linux/types.h>
-#include <linux/init.h>
 
 #define ATH79_MEM_SIZE_MIN     (2 * 1024 * 1024)
 #define ATH79_MEM_SIZE_MAX     (128 * 1024 * 1024)
index 2b8b118..09cb6f7 100644 (file)
@@ -2,6 +2,7 @@ if BCM47XX
 
 config BCM47XX_SSB
        bool "SSB Support for Broadcom BCM47XX"
+       select SYS_HAS_CPU_BMIPS32_3300
        select SSB
        select SSB_DRIVER_MIPS
        select SSB_DRIVER_EXTIF
@@ -11,6 +12,7 @@ config BCM47XX_SSB
        select SSB_PCICORE_HOSTMODE if PCI
        select SSB_DRIVER_GPIO
        select GPIOLIB
+       select LEDS_GPIO_REGISTER
        default y
        help
         Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
@@ -20,6 +22,7 @@ config BCM47XX_SSB
 config BCM47XX_BCMA
        bool "BCMA Support for Broadcom BCM47XX"
        select SYS_HAS_CPU_MIPS32_R2
+       select CPU_MIPSR2_IRQ_VI
        select BCMA
        select BCMA_HOST_SOC
        select BCMA_DRIVER_MIPS
@@ -27,6 +30,7 @@ config BCM47XX_BCMA
        select BCMA_DRIVER_PCI_HOSTMODE if PCI
        select BCMA_DRIVER_GPIO
        select GPIOLIB
+       select LEDS_GPIO_REGISTER
        default y
        help
         Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
index c52daf9..4688b6a 100644 (file)
@@ -4,5 +4,4 @@
 #
 
 obj-y                          += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
-obj-y                          += board.o
-obj-$(CONFIG_BCM47XX_SSB)      += wgt634u.o
+obj-y                          += board.o buttons.o leds.o
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h
new file mode 100644 (file)
index 0000000..5c94ace
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef LINUX_BCM47XX_PRIVATE_H_
+#define LINUX_BCM47XX_PRIVATE_H_
+
+#include <linux/kernel.h>
+
+/* buttons.c */
+int __init bcm47xx_buttons_register(void);
+
+/* leds.c */
+void __init bcm47xx_leds_register(void);
+
+#endif
index f3f6bfe..6d612e2 100644 (file)
@@ -36,26 +36,32 @@ static const
 struct bcm47xx_board_type_list1 bcm47xx_board_list_model_name[] __initconst = {
        {{BCM47XX_BOARD_DLINK_DIR130, "D-Link DIR-130"}, "DIR-130"},
        {{BCM47XX_BOARD_DLINK_DIR330, "D-Link DIR-330"}, "DIR-330"},
-       { {0}, 0},
+       { {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}, 0},
+       { {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}, 0},
+       { {0}, NULL},
 };
 
 /* hardware_version */
 static const
 struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = {
+       {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"},
+       {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"},
+       {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"},
+       {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"},
+       {{BCM47XX_BOARD_ASUS_RTN12D1, "Asus RT-N12D1"}, "RTN12D1"},
+       {{BCM47XX_BOARD_ASUS_RTN12HP, "Asus RT-N12HP"}, "RTN12HP"},
        {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16-"},
        {{BCM47XX_BOARD_ASUS_WL320GE, "Asus WL320GE"}, "WL320G-"},
        {{BCM47XX_BOARD_ASUS_WL330GE, "Asus WL330GE"}, "WL330GE-"},
@@ -66,7 +72,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initcons
        {{BCM47XX_BOARD_ASUS_WL520GC, "Asus WL520GC"}, "WL520GC-"},
        {{BCM47XX_BOARD_ASUS_WL520GU, "Asus WL520GU"}, "WL520GU-"},
        {{BCM47XX_BOARD_BELKIN_F7D4301, "Belkin F7D4301"}, "F7D4301"},
-       { {0}, 0},
+       { {0}, NULL},
 };
 
 /* productid */
@@ -75,19 +81,13 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = {
        {{BCM47XX_BOARD_ASUS_RTAC66U, "Asus RT-AC66U"}, "RT-AC66U"},
        {{BCM47XX_BOARD_ASUS_RTN10, "Asus RT-N10"}, "RT-N10"},
        {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RT-N10D"},
-       {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RT-N10U"},
-       {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"},
-       {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RT-N12B1"},
-       {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RT-N12C1"},
-       {{BCM47XX_BOARD_ASUS_RTN12D1, "Asus RT-N12D1"}, "RT-N12D1"},
-       {{BCM47XX_BOARD_ASUS_RTN12HP, "Asus RT-N12HP"}, "RT-N12HP"},
        {{BCM47XX_BOARD_ASUS_RTN15U, "Asus RT-N15U"}, "RT-N15U"},
        {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16"},
        {{BCM47XX_BOARD_ASUS_RTN53, "Asus RT-N53"}, "RT-N53"},
        {{BCM47XX_BOARD_ASUS_RTN66U, "Asus RT-N66U"}, "RT-N66U"},
        {{BCM47XX_BOARD_ASUS_WL300G, "Asus WL300G"}, "WL300g"},
        {{BCM47XX_BOARD_ASUS_WLHDD, "Asus WLHDD"}, "WLHDD"},
-       { {0}, 0},
+       { {0}, NULL},
 };
 
 /* ModelId */
@@ -97,7 +97,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = {
        {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"},
        {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"},
        {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"},
-       { {0}, 0},
+       { {0}, NULL},
 };
 
 /* melco_id or buf1falo_id */
@@ -112,7 +112,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_melco_id[] __initconst = {
        {{BCM47XX_BOARD_BUFFALO_WZR_G300N, "Buffalo WZR-G300N"}, "31120"},
        {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54, "Buffalo WZR-RS-G54"}, "30083"},
        {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP, "Buffalo WZR-RS-G54HP"}, "30103"},
-       { {0}, 0},
+       { {0}, NULL},
 };
 
 /* boot_hw_model, boot_hw_ver */
@@ -143,7 +143,7 @@ struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = {
        {{BCM47XX_BOARD_LINKSYS_WRT54G3GV2, "Linksys WRT54G3GV2-VF"}, "WRT54G3GV2-VF", "1.0"},
        {{BCM47XX_BOARD_LINKSYS_WRT610NV1, "Linksys WRT610N V1"}, "WRT610N", "1.0"},
        {{BCM47XX_BOARD_LINKSYS_WRT610NV2, "Linksys WRT610N V2"}, "WRT610N", "2.0"},
-       { {0}, 0},
+       { {0}, NULL},
 };
 
 /* board_id */
@@ -165,7 +165,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = {
        {{BCM47XX_BOARD_NETGEAR_WNR3500V2, "Netgear WNR3500 V2"}, "U12H127T00_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WNR3500V2VC, "Netgear WNR3500 V2vc"}, "U12H127T70_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WNR834BV2, "Netgear WNR834B V2"}, "U12H081T00_NETGEAR"},
-       { {0}, 0},
+       { {0}, NULL},
 };
 
 /* boardtype, boardnum, boardrev */
@@ -174,7 +174,9 @@ struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = {
        {{BCM47XX_BOARD_HUAWEI_E970, "Huawei E970"}, "0x048e", "0x5347", "0x11"},
        {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"},
        {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"},
-       { {0}, 0},
+       {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"},
+       {{BCM47XX_BOARD_LINKSYS_WRT54GSV1, "Linksys WRT54GS V1"}, "0x0101", "42", "0x10"},
+       { {0}, NULL},
 };
 
 static const
diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c
new file mode 100644 (file)
index 0000000..872c62e
--- /dev/null
@@ -0,0 +1,531 @@
+#include "bcm47xx_private.h"
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/interrupt.h>
+#include <bcm47xx_board.h>
+#include <bcm47xx.h>
+
+/**************************************************
+ * Database
+ **************************************************/
+
+#define BCM47XX_GPIO_KEY(_gpio, _code)                                 \
+       {                                                               \
+               .code           = _code,                                \
+               .gpio           = _gpio,                                \
+               .active_low     = 1,                                    \
+       }
+
+/* Asus */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_rtn12[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(1, KEY_RESTART),
+       BCM47XX_GPIO_KEY(4, BTN_0), /* Router mode */
+       BCM47XX_GPIO_KEY(5, BTN_1), /* Repeater mode */
+       BCM47XX_GPIO_KEY(6, BTN_2), /* AP mode */
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_rtn16[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(8, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_rtn66u[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(9, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl300g[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl320ge[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl330ge[] __initconst = {
+       BCM47XX_GPIO_KEY(2, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl500gd[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl500gpv1[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_RESTART),
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
+       BCM47XX_GPIO_KEY(2, KEY_RESTART),
+       BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl500w[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+       BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl520gc[] __initconst = {
+       BCM47XX_GPIO_KEY(2, KEY_RESTART),
+       BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl520gu[] __initconst = {
+       BCM47XX_GPIO_KEY(2, KEY_RESTART),
+       BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wl700ge[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_POWER), /* Hard disk power switch */
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), /* EZSetup */
+       BCM47XX_GPIO_KEY(6, KEY_COPY), /* Copy data from USB to internal disk */
+       BCM47XX_GPIO_KEY(7, KEY_RESTART), /* Hard reset */
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_asus_wlhdd[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+/* Huawei */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_huawei_e970[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+/* Belkin */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_belkin_f7d4301[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+       BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
+};
+
+/* Buffalo */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_buffalo_whr2_a54g54[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_buffalo_whr_g125[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(4, KEY_RESTART),
+       BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_buffalo_whr_g54s[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(4, KEY_RESTART),
+       BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_buffalo_whr_hp_g54[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(4, KEY_RESTART),
+       BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_buffalo_wzr_g300n[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_buffalo_wzr_rs_g54[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(4, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_buffalo_wzr_rs_g54hp[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(4, KEY_RESTART),
+};
+
+/* Dell */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_dell_tm2300[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_RESTART),
+};
+
+/* D-Link */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_dlink_dir130[] __initconst = {
+       BCM47XX_GPIO_KEY(3, KEY_RESTART),
+       BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_dlink_dir330[] __initconst = {
+       BCM47XX_GPIO_KEY(3, KEY_RESTART),
+       BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
+};
+
+/* Linksys */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_e1000v1[] __initconst = {
+       BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_e1000v21[] __initconst = {
+       BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(10, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_e2000v1[] __initconst = {
+       BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(8, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_e3000v1[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_e3200v1[] __initconst = {
+       BCM47XX_GPIO_KEY(5, KEY_RESTART),
+       BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_e4200v1[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt150nv1[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt150nv11[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt160nv1[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt160nv3[] __initconst = {
+       BCM47XX_GPIO_KEY(5, 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),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt310nv1[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+       BCM47XX_GPIO_KEY(8, KEY_UNKNOWN),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt610nv1[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+       BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_linksys_wrt610nv2[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+/* Motorola */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_motorola_we800g[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_motorola_wr850gp[] __initconst = {
+       BCM47XX_GPIO_KEY(5, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = {
+       BCM47XX_GPIO_KEY(5, KEY_RESTART),
+};
+
+/* Netgear */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_netgear_wndr3400v1[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_RESTART),
+       BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(8, KEY_RFKILL),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_netgear_wndr3700v3[] __initconst = {
+       BCM47XX_GPIO_KEY(2, KEY_RFKILL),
+       BCM47XX_GPIO_KEY(3, KEY_RESTART),
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_netgear_wndr4500v1[] __initconst = {
+       BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
+       BCM47XX_GPIO_KEY(5, KEY_RFKILL),
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+static const struct gpio_keys_button
+bcm47xx_buttons_netgear_wnr834bv2[] __initconst = {
+       BCM47XX_GPIO_KEY(6, KEY_RESTART),
+};
+
+/* SimpleTech */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_simpletech_simpleshare[] __initconst = {
+       BCM47XX_GPIO_KEY(0, KEY_RESTART),
+};
+
+/**************************************************
+ * Init
+ **************************************************/
+
+static struct gpio_keys_platform_data bcm47xx_button_pdata;
+
+static struct platform_device bcm47xx_buttons_gpio_keys = {
+       .name = "gpio-keys",
+       .dev = {
+               .platform_data = &bcm47xx_button_pdata,
+       }
+};
+
+/* Copy data from __initconst */
+static int __init bcm47xx_buttons_copy(const struct gpio_keys_button *buttons,
+                                      size_t nbuttons)
+{
+       size_t size = nbuttons * sizeof(*buttons);
+
+       bcm47xx_button_pdata.buttons = kmalloc(size, GFP_KERNEL);
+       if (!bcm47xx_button_pdata.buttons)
+               return -ENOMEM;
+       memcpy(bcm47xx_button_pdata.buttons, buttons, size);
+       bcm47xx_button_pdata.nbuttons = nbuttons;
+
+       return 0;
+}
+
+#define bcm47xx_copy_bdata(dev_buttons)                                        \
+       bcm47xx_buttons_copy(dev_buttons, ARRAY_SIZE(dev_buttons));
+
+int __init bcm47xx_buttons_register(void)
+{
+       enum bcm47xx_board board = bcm47xx_board_get();
+       int err;
+
+       switch (board) {
+       case BCM47XX_BOARD_ASUS_RTN12:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn12);
+               break;
+       case BCM47XX_BOARD_ASUS_RTN16:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn16);
+               break;
+       case BCM47XX_BOARD_ASUS_RTN66U:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn66u);
+               break;
+       case BCM47XX_BOARD_ASUS_WL300G:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl300g);
+               break;
+       case BCM47XX_BOARD_ASUS_WL320GE:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl320ge);
+               break;
+       case BCM47XX_BOARD_ASUS_WL330GE:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge);
+               break;
+       case BCM47XX_BOARD_ASUS_WL500GD:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd);
+               break;
+       case BCM47XX_BOARD_ASUS_WL500GPV1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv1);
+               break;
+       case BCM47XX_BOARD_ASUS_WL500GPV2:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv2);
+               break;
+       case BCM47XX_BOARD_ASUS_WL500W:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500w);
+               break;
+       case BCM47XX_BOARD_ASUS_WL520GC:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gc);
+               break;
+       case BCM47XX_BOARD_ASUS_WL520GU:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gu);
+               break;
+       case BCM47XX_BOARD_ASUS_WL700GE:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl700ge);
+               break;
+       case BCM47XX_BOARD_ASUS_WLHDD:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wlhdd);
+               break;
+
+       case BCM47XX_BOARD_BELKIN_F7D4301:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_belkin_f7d4301);
+               break;
+
+       case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr2_a54g54);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WHR_G125:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g125);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WHR_G54S:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g54s);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_hp_g54);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WZR_G300N:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_g300n);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54hp);
+               break;
+
+       case BCM47XX_BOARD_DELL_TM2300:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_dell_tm2300);
+               break;
+
+       case BCM47XX_BOARD_DLINK_DIR130:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir130);
+               break;
+       case BCM47XX_BOARD_DLINK_DIR330:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir330);
+               break;
+
+       case BCM47XX_BOARD_HUAWEI_E970:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_huawei_e970);
+               break;
+
+       case BCM47XX_BOARD_LINKSYS_E1000V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E1000V21:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v21);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E2000V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e2000v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E3000V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3000v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E3200V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3200v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E4200V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e4200v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT150NV1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT150NV11:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv11);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT160NV1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT160NV3:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv3);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT300NV11:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt300nv11);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT310NV1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT610NV1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT610NV2:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv2);
+               break;
+
+       case BCM47XX_BOARD_MOTOROLA_WE800G:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g);
+               break;
+       case BCM47XX_BOARD_MOTOROLA_WR850GP:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gp);
+               break;
+       case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gv2v3);
+               break;
+
+       case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNDR3700V3:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3700v3);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNR834BV2:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2);
+               break;
+
+       case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_simpletech_simpleshare);
+               break;
+
+       default:
+               pr_debug("No buttons configuration found for this device\n");
+               return -ENOTSUPP;
+       }
+
+       if (err)
+               return -ENOMEM;
+
+       err = platform_device_register(&bcm47xx_buttons_gpio_keys);
+       if (err) {
+               pr_err("Failed to register platform device: %d\n", err);
+               return err;
+       }
+
+       return 0;
+}
index 8cf3833..e0585b7 100644 (file)
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <asm/setup.h>
 #include <asm/irq_cpu.h>
 #include <bcm47xx.h>
 
-void plat_irq_dispatch(void)
+asmlinkage void plat_irq_dispatch(void)
 {
        u32 cause;
 
@@ -50,6 +51,18 @@ void plat_irq_dispatch(void)
                do_IRQ(6);
 }
 
+#define DEFINE_HWx_IRQDISPATCH(x)                                      \
+       static void bcm47xx_hw ## x ## _irqdispatch(void)               \
+       {                                                               \
+               do_IRQ(x);                                              \
+       }
+DEFINE_HWx_IRQDISPATCH(2)
+DEFINE_HWx_IRQDISPATCH(3)
+DEFINE_HWx_IRQDISPATCH(4)
+DEFINE_HWx_IRQDISPATCH(5)
+DEFINE_HWx_IRQDISPATCH(6)
+DEFINE_HWx_IRQDISPATCH(7)
+
 void __init arch_init_irq(void)
 {
 #ifdef CONFIG_BCM47XX_BCMA
@@ -64,4 +77,14 @@ void __init arch_init_irq(void)
        }
 #endif
        mips_cpu_irq_init();
+
+       if (cpu_has_vint) {
+               pr_info("Setting up vectored interrupts\n");
+               set_vi_handler(2, bcm47xx_hw2_irqdispatch);
+               set_vi_handler(3, bcm47xx_hw3_irqdispatch);
+               set_vi_handler(4, bcm47xx_hw4_irqdispatch);
+               set_vi_handler(5, bcm47xx_hw5_irqdispatch);
+               set_vi_handler(6, bcm47xx_hw6_irqdispatch);
+               set_vi_handler(7, bcm47xx_hw7_irqdispatch);
+       }
 }
diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c
new file mode 100644 (file)
index 0000000..647d155
--- /dev/null
@@ -0,0 +1,542 @@
+#include "bcm47xx_private.h"
+
+#include <linux/leds.h>
+#include <bcm47xx_board.h>
+
+/**************************************************
+ * Database
+ **************************************************/
+
+#define BCM47XX_GPIO_LED(_gpio, _color, _function, _active_low,                \
+                        _default_state)                                \
+       {                                                               \
+               .name           = "bcm47xx:" _color ":" _function,      \
+               .gpio           = _gpio,                                \
+               .active_low     = _active_low,                          \
+               .default_state  = _default_state,                       \
+       }
+
+#define BCM47XX_GPIO_LED_TRIGGER(_gpio, _color, _function, _active_low,        \
+                                _default_trigger)                      \
+       {                                                               \
+               .name           = "bcm47xx:" _color ":" _function,      \
+               .gpio           = _gpio,                                \
+               .active_low     = _active_low,                          \
+               .default_state  = LEDS_GPIO_DEFSTATE_OFF,               \
+               .default_trigger        = _default_trigger,             \
+       }
+
+/* Asus */
+
+static const struct gpio_led
+bcm47xx_leds_asus_rtn12[] __initconst = {
+       BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(7, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_rtn16[] __initconst = {
+       BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(7, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_rtn66u[] __initconst = {
+       BCM47XX_GPIO_LED(12, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(15, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl300g[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl320ge[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(11, "unk", "link", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl330ge[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl500gd[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl500gpv1[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl500gpv2[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl500w[] __initconst = {
+       BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl520gc[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl520gu[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wl700ge[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), /* Labeled "READY" (there is no "power" LED). Originally ON, flashing on USB activity. */
+};
+
+static const struct gpio_led
+bcm47xx_leds_asus_wlhdd[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(2, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Belkin */
+
+static const struct gpio_led
+bcm47xx_leds_belkin_f7d4301[] __initconst = {
+       BCM47XX_GPIO_LED(10, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(11, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(12, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(13, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(14, "unk", "usb0", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(15, "unk", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Buffalo */
+
+static const struct gpio_led
+bcm47xx_leds_buffalo_whr2_a54g54[] __initconst = {
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_buffalo_whr_g125[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_buffalo_whr_g54s[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_buffalo_whr_hp_g54[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_buffalo_wzr_g300n[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_buffalo_wzr_rs_g54[] __initconst = {
+       BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_buffalo_wzr_rs_g54hp[] __initconst = {
+       BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Dell */
+
+static const struct gpio_led
+bcm47xx_leds_dell_tm2300[] __initconst = {
+       BCM47XX_GPIO_LED(6, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+/* D-Link */
+
+static const struct gpio_led
+bcm47xx_leds_dlink_dir130[] __initconst = {
+       BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */
+       BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_dlink_dir330[] __initconst = {
+       BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */
+       BCM47XX_GPIO_LED(4, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Huawei */
+
+static const struct gpio_led
+bcm47xx_leds_huawei_e970[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Linksys */
+
+static const struct gpio_led
+bcm47xx_leds_linksys_e1000v1[] __initconst = {
+       BCM47XX_GPIO_LED(0, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_e1000v21[] __initconst = {
+       BCM47XX_GPIO_LED(5, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(6, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_e2000v1[] __initconst = {
+       BCM47XX_GPIO_LED(1, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(2, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(4, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_e3000v1[] __initconst = {
+       BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_e3200v1[] __initconst = {
+       BCM47XX_GPIO_LED(3, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_e4200v1[] __initconst = {
+       BCM47XX_GPIO_LED(5, "white", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_wrt150nv1[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "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_wrt150nv11[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "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_wrt160nv1[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(5, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_wrt160nv3[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(4, "blue", "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),
+       BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_wrt310nv1[] __initconst = {
+       BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(9, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_wrt610nv1[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "usb",  1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "unk", "power",  0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(3, "amber", "wps",  1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(9, "blue", "wps",  1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_linksys_wrt610nv2[] __initconst = {
+       BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Motorola */
+
+static const struct gpio_led
+bcm47xx_leds_motorola_we800g[] __initconst = {
+       BCM47XX_GPIO_LED(1, "amber", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(2, "unk", "unk", 1, LEDS_GPIO_DEFSTATE_OFF), /* There are only 3 LEDs: Power, Wireless and Device (ethernet) */
+       BCM47XX_GPIO_LED(4, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+};
+
+static const struct gpio_led
+bcm47xx_leds_motorola_wr850gp[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(6, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_motorola_wr850gv2v3[] __initconst = {
+       BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* Netgear */
+
+static const struct gpio_led
+bcm47xx_leds_netgear_wndr3400v1[] __initconst = {
+       BCM47XX_GPIO_LED(2, "green", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_netgear_wndr4500v1[] __initconst = {
+       BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(2, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(3, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(8, "green", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(9, "green", "2ghz", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(11, "blue", "5ghz", 1, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(14, "green", "usb2", 1, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+static const struct gpio_led
+bcm47xx_leds_netgear_wnr834bv2[] __initconst = {
+       BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
+       BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(7, "unk", "connected", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
+/* SimpleTech */
+
+static const struct gpio_led
+bcm47xx_leds_simpletech_simpleshare[] __initconst = {
+       BCM47XX_GPIO_LED(1, "unk", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* "Ready" LED */
+};
+
+/**************************************************
+ * Init
+ **************************************************/
+
+static struct gpio_led_platform_data bcm47xx_leds_pdata;
+
+#define bcm47xx_set_pdata(dev_leds) do {                               \
+       bcm47xx_leds_pdata.leds = dev_leds;                             \
+       bcm47xx_leds_pdata.num_leds = ARRAY_SIZE(dev_leds);             \
+} while (0)
+
+void __init bcm47xx_leds_register(void)
+{
+       enum bcm47xx_board board = bcm47xx_board_get();
+
+       switch (board) {
+       case BCM47XX_BOARD_ASUS_RTN12:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12);
+               break;
+       case BCM47XX_BOARD_ASUS_RTN16:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16);
+               break;
+       case BCM47XX_BOARD_ASUS_RTN66U:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_rtn66u);
+               break;
+       case BCM47XX_BOARD_ASUS_WL300G:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl300g);
+               break;
+       case BCM47XX_BOARD_ASUS_WL320GE:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl320ge);
+               break;
+       case BCM47XX_BOARD_ASUS_WL330GE:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge);
+               break;
+       case BCM47XX_BOARD_ASUS_WL500GD:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd);
+               break;
+       case BCM47XX_BOARD_ASUS_WL500GPV1:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv1);
+               break;
+       case BCM47XX_BOARD_ASUS_WL500GPV2:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv2);
+               break;
+       case BCM47XX_BOARD_ASUS_WL500W:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl500w);
+               break;
+       case BCM47XX_BOARD_ASUS_WL520GC:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gc);
+               break;
+       case BCM47XX_BOARD_ASUS_WL520GU:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gu);
+               break;
+       case BCM47XX_BOARD_ASUS_WL700GE:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wl700ge);
+               break;
+       case BCM47XX_BOARD_ASUS_WLHDD:
+               bcm47xx_set_pdata(bcm47xx_leds_asus_wlhdd);
+               break;
+
+       case BCM47XX_BOARD_BELKIN_F7D4301:
+               bcm47xx_set_pdata(bcm47xx_leds_belkin_f7d4301);
+               break;
+
+       case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
+               bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr2_a54g54);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WHR_G125:
+               bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g125);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WHR_G54S:
+               bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g54s);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
+               bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_hp_g54);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WZR_G300N:
+               bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_g300n);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
+               bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54);
+               break;
+       case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
+               bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54hp);
+               break;
+
+       case BCM47XX_BOARD_DELL_TM2300:
+               bcm47xx_set_pdata(bcm47xx_leds_dell_tm2300);
+               break;
+
+       case BCM47XX_BOARD_DLINK_DIR130:
+               bcm47xx_set_pdata(bcm47xx_leds_dlink_dir130);
+               break;
+       case BCM47XX_BOARD_DLINK_DIR330:
+               bcm47xx_set_pdata(bcm47xx_leds_dlink_dir330);
+               break;
+
+       case BCM47XX_BOARD_HUAWEI_E970:
+               bcm47xx_set_pdata(bcm47xx_leds_huawei_e970);
+               break;
+
+       case BCM47XX_BOARD_LINKSYS_E1000V1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E1000V21:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v21);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E2000V1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_e2000v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E3000V1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_e3000v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E3200V1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_e3200v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_E4200V1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_e4200v1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT150NV1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT150NV11:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv11);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT160NV1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT160NV3:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv3);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT300NV11:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt300nv11);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT310NV1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT610NV1:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1);
+               break;
+       case BCM47XX_BOARD_LINKSYS_WRT610NV2:
+               bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv2);
+               break;
+
+       case BCM47XX_BOARD_MOTOROLA_WE800G:
+               bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g);
+               break;
+       case BCM47XX_BOARD_MOTOROLA_WR850GP:
+               bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gp);
+               break;
+       case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
+               bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gv2v3);
+               break;
+
+       case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
+               bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr3400v1);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
+               bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1);
+               break;
+       case BCM47XX_BOARD_NETGEAR_WNR834BV2:
+               bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
+               break;
+
+       case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
+               bcm47xx_set_pdata(bcm47xx_leds_simpletech_simpleshare);
+               break;
+
+       default:
+               pr_debug("No LEDs configuration found for this device\n");
+               return;
+       }
+
+       gpio_led_register_device(-1, &bcm47xx_leds_pdata);
+}
index b4c585b..6decb27 100644 (file)
@@ -11,7 +11,6 @@
  * option) any later version.
  */
 
-#include <linux/init.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/ssb/ssb.h>
 #include <asm/mach-bcm47xx/bcm47xx.h>
 
 static char nvram_buf[NVRAM_SPACE];
+static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
 
 static u32 find_nvram_size(u32 end)
 {
        struct nvram_header *header;
-       u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
        int i;
 
        for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
index 5cba318..0af808d 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/ssb/ssb_driver_chipcommon.h>
+#include <linux/ssb/ssb_regs.h>
 #include <linux/smp.h>
 #include <asm/bootinfo.h>
-#include <asm/fw/cfe/cfe_api.h>
-#include <asm/fw/cfe/cfe_error.h>
 #include <bcm47xx.h>
 #include <bcm47xx_board.h>
 
-static int cfe_cons_handle;
 
-static u16 get_chip_id(void)
-{
-       switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
-       case BCM47XX_BUS_TYPE_SSB:
-               return bcm47xx_bus.ssb.chip_id;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
-       case BCM47XX_BUS_TYPE_BCMA:
-               return bcm47xx_bus.bcma.bus.chipinfo.id;
-#endif
-       }
-       return 0;
-}
+static char bcm47xx_system_type[20] = "Broadcom BCM47XX";
 
 const char *get_system_type(void)
 {
-       static char buf[50];
-       u16 chip_id = get_chip_id();
-
-       snprintf(buf, sizeof(buf),
-                (chip_id > 0x9999) ? "Broadcom BCM%d (%s)" :
-                                     "Broadcom BCM%04X (%s)",
-                chip_id, bcm47xx_board_get_name());
-
-       return buf;
-}
-
-void prom_putchar(char c)
-{
-       while (cfe_write(cfe_cons_handle, &c, 1) == 0)
-               ;
+       return bcm47xx_system_type;
 }
 
-static __init void prom_init_cfe(void)
+__init void bcm47xx_set_system_type(u16 chip_id)
 {
-       uint32_t cfe_ept;
-       uint32_t cfe_handle;
-       uint32_t cfe_eptseal;
-       int argc = fw_arg0;
-       char **envp = (char **) fw_arg2;
-       int *prom_vec = (int *) fw_arg3;
-
-       /*
-        * Check if a loader was used; if NOT, the 4 arguments are
-        * what CFE gives us (handle, 0, EPT and EPTSEAL)
-        */
-       if (argc < 0) {
-               cfe_handle = (uint32_t)argc;
-               cfe_ept = (uint32_t)envp;
-               cfe_eptseal = (uint32_t)prom_vec;
-       } else {
-               if ((int)prom_vec < 0) {
-                       /*
-                        * Old loader; all it gives us is the handle,
-                        * so use the "known" entrypoint and assume
-                        * the seal.
-                        */
-                       cfe_handle = (uint32_t)prom_vec;
-                       cfe_ept = 0xBFC00500;
-                       cfe_eptseal = CFE_EPTSEAL;
-               } else {
-                       /*
-                        * Newer loaders bundle the handle/ept/eptseal
-                        * Note: prom_vec is in the loader's useg
-                        * which is still alive in the TLB.
-                        */
-                       cfe_handle = prom_vec[0];
-                       cfe_ept = prom_vec[2];
-                       cfe_eptseal = prom_vec[3];
-               }
-       }
-
-       if (cfe_eptseal != CFE_EPTSEAL) {
-               /* too early for panic to do any good */
-               printk(KERN_ERR "CFE's entrypoint seal doesn't match.");
-               while (1) ;
-       }
-
-       cfe_init(cfe_handle, cfe_ept);
-}
-
-static __init void prom_init_console(void)
-{
-       /* Initialize CFE console */
-       cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
-}
-
-static __init void prom_init_cmdline(void)
-{
-       static char buf[COMMAND_LINE_SIZE] __initdata;
-
-       /* Get the kernel command line from CFE */
-       if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) {
-               buf[COMMAND_LINE_SIZE - 1] = 0;
-               strcpy(arcs_cmdline, buf);
-       }
-
-       /* Force a console handover by adding a console= argument if needed,
-        * as CFE is not available anymore later in the boot process. */
-       if ((strstr(arcs_cmdline, "console=")) == NULL) {
-               /* Try to read the default serial port used by CFE */
-               if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0)
-                   || (strncmp("uart", buf, 4)))
-                       /* Default to uart0 */
-                       strcpy(buf, "uart0");
-
-               /* Compute the new command line */
-               snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200",
-                        arcs_cmdline, buf[4]);
-       }
+       snprintf(bcm47xx_system_type, sizeof(bcm47xx_system_type),
+                (chip_id > 0x9999) ? "Broadcom BCM%d" :
+                                     "Broadcom BCM%04X",
+                chip_id);
 }
 
 static __init void prom_init_mem(void)
@@ -195,12 +96,16 @@ static __init void prom_init_mem(void)
        add_memory_region(0, mem, BOOT_MEM_RAM);
 }
 
+/*
+ * This is the first serial on the chip common core, it is at this position
+ * for sb (ssb) and ai (bcma) bus.
+ */
+#define BCM47XX_SERIAL_ADDR (SSB_ENUM_BASE + SSB_CHIPCO_UART0_DATA)
+
 void __init prom_init(void)
 {
-       prom_init_cfe();
-       prom_init_console();
-       prom_init_cmdline();
        prom_init_mem();
+       setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0);
 }
 
 void __init prom_free_prom_memory(void)
index b8ef965..2f5bbd6 100644 (file)
@@ -31,7 +31,8 @@ static int __init uart8250_init_ssb(void)
 
        memset(&uart8250_data, 0,  sizeof(uart8250_data));
 
-       for (i = 0; i < mcore->nr_serial_ports; i++) {
+       for (i = 0; i < mcore->nr_serial_ports &&
+                   i < ARRAY_SIZE(uart8250_data) - 1; i++) {
                struct plat_serial8250_port *p = &(uart8250_data[i]);
                struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]);
 
@@ -55,7 +56,8 @@ static int __init uart8250_init_bcma(void)
 
        memset(&uart8250_data, 0,  sizeof(uart8250_data));
 
-       for (i = 0; i < cc->nr_serial_ports; i++) {
+       for (i = 0; i < cc->nr_serial_ports &&
+                   i < ARRAY_SIZE(uart8250_data) - 1; i++) {
                struct plat_serial8250_port *p = &(uart8250_data[i]);
                struct bcma_serial_port *bcma_port;
                bcma_port = &(cc->serial_ports[i]);
index 9057728..025be21 100644 (file)
@@ -26,6 +26,8 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include "bcm47xx_private.h"
+
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/ethtool.h>
@@ -35,6 +37,8 @@
 #include <linux/ssb/ssb_embedded.h>
 #include <linux/bcma/bcma_soc.h>
 #include <asm/bootinfo.h>
+#include <asm/idle.h>
+#include <asm/prom.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <bcm47xx.h>
@@ -213,12 +217,14 @@ void __init plat_mem_setup(void)
 #ifdef CONFIG_BCM47XX_BCMA
                bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
                bcm47xx_register_bcma();
+               bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
 #endif
        } else {
                printk(KERN_INFO "bcm47xx: using ssb bus\n");
 #ifdef CONFIG_BCM47XX_SSB
                bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
                bcm47xx_register_ssb();
+               bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id);
 #endif
        }
 
@@ -226,8 +232,34 @@ void __init plat_mem_setup(void)
        _machine_halt = bcm47xx_machine_halt;
        pm_power_off = bcm47xx_machine_halt;
        bcm47xx_board_detect();
+       mips_set_machine_name(bcm47xx_board_get_name());
 }
 
+static int __init bcm47xx_cpu_fixes(void)
+{
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               /* Nothing to do */
+               break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               /* The BCM4706 has a problem with the CPU wait instruction.
+                * When r4k_wait or r4k_wait_irqoff is used will just hang and
+                * not return from a msleep(). Removing the cpu_wait
+                * functionality is a workaround for this problem. The BCM4716
+                * does not have this problem.
+                */
+               if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
+                       cpu_wait = NULL;
+               break;
+#endif
+       }
+       return 0;
+}
+arch_initcall(bcm47xx_cpu_fixes);
+
 static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = {
        .link   = 1,
        .speed  = SPEED_100,
@@ -248,6 +280,9 @@ static int __init bcm47xx_register_bus_complete(void)
                break;
 #endif
        }
+       bcm47xx_buttons_register();
+       bcm47xx_leds_register();
+
        fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
        return 0;
 }
index ad03c93..a8b5408 100644 (file)
@@ -135,7 +135,7 @@ static void nvram_read_leddc(const char *prefix, const char *name,
 }
 
 static void nvram_read_macaddr(const char *prefix, const char *name,
-                              u8 (*val)[6], bool fallback)
+                              u8 val[6], bool fallback)
 {
        char buf[100];
        int err;
@@ -144,11 +144,11 @@ static void nvram_read_macaddr(const char *prefix, const char *name,
        if (err < 0)
                return;
 
-       bcm47xx_nvram_parse_macaddr(buf, *val);
+       bcm47xx_nvram_parse_macaddr(buf, val);
 }
 
 static void nvram_read_alpha2(const char *prefix, const char *name,
-                            char (*val)[2], bool fallback)
+                            char val[2], bool fallback)
 {
        char buf[10];
        int err;
@@ -162,7 +162,7 @@ static void nvram_read_alpha2(const char *prefix, const char *name,
                pr_warn("alpha2 is too long %s\n", buf);
                return;
        }
-       memcpy(val, buf, sizeof(val));
+       memcpy(val, buf, 2);
 }
 
 static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
@@ -180,7 +180,7 @@ static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
                      fallback);
        nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0,
                      fallback);
-       nvram_read_alpha2(prefix, "ccode", &sprom->alpha2, fallback);
+       nvram_read_alpha2(prefix, "ccode", sprom->alpha2, fallback);
 }
 
 static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom,
@@ -633,20 +633,20 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
 static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
                                        const char *prefix, bool fallback)
 {
-       nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac, fallback);
+       nvram_read_macaddr(prefix, "et0macaddr", sprom->et0mac, fallback);
        nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0,
                      fallback);
        nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0,
                      fallback);
 
-       nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac, fallback);
+       nvram_read_macaddr(prefix, "et1macaddr", sprom->et1mac, fallback);
        nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0,
                      fallback);
        nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0,
                      fallback);
 
-       nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac, fallback);
-       nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac, fallback);
+       nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback);
+       nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
 }
 
 static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c
deleted file mode 100644 (file)
index c63a4c2..0000000
+++ /dev/null
@@ -1,174 +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) 2007 Aurelien Jarno <aurelien@aurel32.net>
- */
-
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/leds.h>
-#include <linux/mtd/physmap.h>
-#include <linux/ssb/ssb.h>
-#include <linux/ssb/ssb_embedded.h>
-#include <linux/interrupt.h>
-#include <linux/reboot.h>
-#include <linux/gpio.h>
-#include <asm/mach-bcm47xx/bcm47xx.h>
-
-/* GPIO definitions for the WGT634U */
-#define WGT634U_GPIO_LED       3
-#define WGT634U_GPIO_RESET     2
-#define WGT634U_GPIO_TP1       7
-#define WGT634U_GPIO_TP2       6
-#define WGT634U_GPIO_TP3       5
-#define WGT634U_GPIO_TP4       4
-#define WGT634U_GPIO_TP5       1
-
-static struct gpio_led wgt634u_leds[] = {
-       {
-               .name = "power",
-               .gpio = WGT634U_GPIO_LED,
-               .active_low = 1,
-               .default_trigger = "heartbeat",
-       },
-};
-
-static struct gpio_led_platform_data wgt634u_led_data = {
-       .num_leds =     ARRAY_SIZE(wgt634u_leds),
-       .leds =         wgt634u_leds,
-};
-
-static struct platform_device wgt634u_gpio_leds = {
-       .name =         "leds-gpio",
-       .id =           -1,
-       .dev = {
-               .platform_data = &wgt634u_led_data,
-       }
-};
-
-
-/* 8MiB flash. The struct mtd_partition matches original Netgear WGT634U
-   firmware. */
-static struct mtd_partition wgt634u_partitions[] = {
-       {
-               .name       = "cfe",
-               .offset     = 0,
-               .size       = 0x60000,          /* 384k */
-               .mask_flags = MTD_WRITEABLE     /* force read-only */
-       },
-       {
-               .name   = "config",
-               .offset = 0x60000,
-               .size   = 0x20000               /* 128k */
-       },
-       {
-               .name   = "linux",
-               .offset = 0x80000,
-               .size   = 0x140000              /* 1280k */
-       },
-       {
-               .name   = "jffs",
-               .offset = 0x1c0000,
-               .size   = 0x620000              /* 6272k */
-       },
-       {
-               .name   = "nvram",
-               .offset = 0x7e0000,
-               .size   = 0x20000               /* 128k */
-       },
-};
-
-static struct physmap_flash_data wgt634u_flash_data = {
-       .parts    = wgt634u_partitions,
-       .nr_parts = ARRAY_SIZE(wgt634u_partitions)
-};
-
-static struct resource wgt634u_flash_resource = {
-       .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device wgt634u_flash = {
-       .name          = "physmap-flash",
-       .id            = 0,
-       .dev           = { .platform_data = &wgt634u_flash_data, },
-       .resource      = &wgt634u_flash_resource,
-       .num_resources = 1,
-};
-
-/* Platform devices */
-static struct platform_device *wgt634u_devices[] __initdata = {
-       &wgt634u_flash,
-       &wgt634u_gpio_leds,
-};
-
-static irqreturn_t gpio_interrupt(int irq, void *ignored)
-{
-       int state;
-
-       /* Interrupts are shared, check if the current one is
-          a GPIO interrupt. */
-       if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
-                                  SSB_CHIPCO_IRQ_GPIO))
-               return IRQ_NONE;
-
-       state = gpio_get_value(WGT634U_GPIO_RESET);
-
-       /* Interrupt are level triggered, revert the interrupt polarity
-          to clear the interrupt. */
-       ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << WGT634U_GPIO_RESET,
-                         state ? 1 << WGT634U_GPIO_RESET : 0);
-
-       if (!state) {
-               printk(KERN_INFO "Reset button pressed");
-               ctrl_alt_del();
-       }
-
-       return IRQ_HANDLED;
-}
-
-static int __init wgt634u_init(void)
-{
-       /* There is no easy way to detect that we are running on a WGT634U
-        * machine. Use the MAC address as an heuristic. Netgear Inc. has
-        * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
-        */
-       u8 *et0mac;
-
-       if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
-               return -ENODEV;
-
-       et0mac = bcm47xx_bus.ssb.sprom.et0mac;
-
-       if (et0mac[0] == 0x00 &&
-           ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
-            (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
-               struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
-
-               printk(KERN_INFO "WGT634U machine detected.\n");
-
-               if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
-                                gpio_interrupt, IRQF_SHARED,
-                                "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
-                       gpio_direction_input(WGT634U_GPIO_RESET);
-                       ssb_gpio_intmask(&bcm47xx_bus.ssb,
-                                        1 << WGT634U_GPIO_RESET,
-                                        1 << WGT634U_GPIO_RESET);
-                       ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
-                                           SSB_CHIPCO_IRQ_GPIO,
-                                           SSB_CHIPCO_IRQ_GPIO);
-               }
-
-               wgt634u_flash_data.width = mcore->pflash.buswidth;
-               wgt634u_flash_resource.start = mcore->pflash.window;
-               wgt634u_flash_resource.end = mcore->pflash.window
-                                          + mcore->pflash.window_size
-                                          - 1;
-               return platform_add_devices(wgt634u_devices,
-                                           ARRAY_SIZE(wgt634u_devices));
-       } else
-               return -ENODEV;
-}
-
-module_init(wgt634u_init);
index b78306c..a057fdf 100644 (file)
@@ -3,33 +3,41 @@ menu "CPU support"
 
 config BCM63XX_CPU_3368
        bool "support 3368 CPU"
+       select SYS_HAS_CPU_BMIPS4350
        select HW_HAS_PCI
 
 config BCM63XX_CPU_6328
        bool "support 6328 CPU"
+       select SYS_HAS_CPU_BMIPS4350
        select HW_HAS_PCI
 
 config BCM63XX_CPU_6338
        bool "support 6338 CPU"
+       select SYS_HAS_CPU_BMIPS32_3300
        select HW_HAS_PCI
 
 config BCM63XX_CPU_6345
        bool "support 6345 CPU"
+       select SYS_HAS_CPU_BMIPS32_3300
 
 config BCM63XX_CPU_6348
        bool "support 6348 CPU"
+       select SYS_HAS_CPU_BMIPS32_3300
        select HW_HAS_PCI
 
 config BCM63XX_CPU_6358
        bool "support 6358 CPU"
+       select SYS_HAS_CPU_BMIPS4350
        select HW_HAS_PCI
 
 config BCM63XX_CPU_6362
        bool "support 6362 CPU"
+       select SYS_HAS_CPU_BMIPS4350
        select HW_HAS_PCI
 
 config BCM63XX_CPU_6368
        bool "support 6368 CPU"
+       select SYS_HAS_CPU_BMIPS4350
        select HW_HAS_PCI
 endmenu
 
index ac28073..9019f54 100644 (file)
@@ -1,7 +1,7 @@
 obj-y          += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \
                   setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \
-                  dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-wdt.o \
-                  dev-usb-usbd.o
+                  dev-pcmcia.o dev-rng.o dev-spi.o dev-hsspi.o dev-uart.o \
+                  dev-wdt.o dev-usb-usbd.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
 
 obj-y          += boards/
index 5b974eb..33727e7 100644 (file)
@@ -23,6 +23,7 @@
 #include <bcm63xx_dev_enet.h>
 #include <bcm63xx_dev_dsp.h>
 #include <bcm63xx_dev_flash.h>
+#include <bcm63xx_dev_hsspi.h>
 #include <bcm63xx_dev_pcmcia.h>
 #include <bcm63xx_dev_spi.h>
 #include <bcm63xx_dev_usb_usbd.h>
@@ -915,6 +916,8 @@ int __init board_register_devices(void)
 
        bcm63xx_spi_register();
 
+       bcm63xx_hsspi_register();
+
        bcm63xx_flash_register();
 
        bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
index 43da4ae..6375652 100644 (file)
@@ -225,6 +225,28 @@ static struct clk clk_spi = {
        .set    = spi_set,
 };
 
+/*
+ * HSSPI clock
+ */
+static void hsspi_set(struct clk *clk, int enable)
+{
+       u32 mask;
+
+       if (BCMCPU_IS_6328())
+               mask = CKCTL_6328_HSSPI_EN;
+       else if (BCMCPU_IS_6362())
+               mask = CKCTL_6362_HSSPI_EN;
+       else
+               return;
+
+       bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_hsspi = {
+       .set    = hsspi_set,
+};
+
+
 /*
  * XTM clock
  */
@@ -346,6 +368,8 @@ struct clk *clk_get(struct device *dev, const char *id)
                return &clk_usbd;
        if (!strcmp(id, "spi"))
                return &clk_spi;
+       if (!strcmp(id, "hsspi"))
+               return &clk_hsspi;
        if (!strcmp(id, "xtm"))
                return &clk_xtm;
        if (!strcmp(id, "periph"))
@@ -366,3 +390,21 @@ void clk_put(struct clk *clk)
 }
 
 EXPORT_SYMBOL(clk_put);
+
+#define HSSPI_PLL_HZ_6328      133333333
+#define HSSPI_PLL_HZ_6362      400000000
+
+static int __init bcm63xx_clk_init(void)
+{
+       switch (bcm63xx_get_cpu_id()) {
+       case BCM6328_CPU_ID:
+               clk_hsspi.rate = HSSPI_PLL_HZ_6328;
+               break;
+       case BCM6362_CPU_ID:
+               clk_hsspi.rate = HSSPI_PLL_HZ_6362;
+               break;
+       }
+
+       return 0;
+}
+arch_initcall(bcm63xx_clk_init);
index b713cd6..1b1b8a8 100644 (file)
@@ -123,7 +123,9 @@ unsigned int bcm63xx_get_memory_size(void)
 
 static unsigned int detect_cpu_clock(void)
 {
-       switch (bcm63xx_get_cpu_id()) {
+       u16 cpu_id = bcm63xx_get_cpu_id();
+
+       switch (cpu_id) {
        case BCM3368_CPU_ID:
                return 300000000;
 
@@ -249,7 +251,7 @@ static unsigned int detect_cpu_clock(void)
        }
 
        default:
-               BUG();
+               panic("Failed to detect clock for CPU with id=%04X\n", cpu_id);
        }
 }
 
diff --git a/arch/mips/bcm63xx/dev-hsspi.c b/arch/mips/bcm63xx/dev-hsspi.c
new file mode 100644 (file)
index 0000000..696abc4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_hsspi.h>
+#include <bcm63xx_regs.h>
+
+static struct resource spi_resources[] = {
+       {
+               .start          = -1, /* filled at runtime */
+               .end            = -1, /* filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = -1, /* filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bcm63xx_hsspi_device = {
+       .name           = "bcm63xx-hsspi",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(spi_resources),
+       .resource       = spi_resources,
+};
+
+int __init bcm63xx_hsspi_register(void)
+{
+       if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362())
+               return -ENODEV;
+
+       spi_resources[0].start = bcm63xx_regset_address(RSET_HSSPI);
+       spi_resources[0].end = spi_resources[0].start;
+       spi_resources[0].end += RSET_HSSPI_SIZE - 1;
+       spi_resources[1].start = bcm63xx_get_irq_number(IRQ_HSSPI);
+
+       return platform_device_register(&bcm63xx_hsspi_device);
+}
index aa8f7f9..6092226 100644 (file)
@@ -6,9 +6,8 @@
  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
  */
 
-#include <linux/init.h>
 #include <bcm63xx_io.h>
-#include <bcm63xx_regs.h>
+#include <linux/serial_bcm63xx.h>
 
 static void wait_xfered(void)
 {
index 8ac4e09..e1f27d6 100644 (file)
@@ -59,14 +59,12 @@ void __init prom_init(void)
        /* do low level board init */
        board_prom_init();
 
-       if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
-               /* set up SMP */
-               register_smp_ops(&bmips_smp_ops);
-
+       /* set up SMP */
+       if (!register_bmips_smp_ops()) {
                /*
-                * BCM6328 might not have its second CPU enabled, while BCM6358
-                * needs special handling for its shared TLB, so disable SMP
-                * for now.
+                * BCM6328 might not have its second CPU enabled, while BCM3368
+                * and BCM6358 need special handling for their shared TLB, so
+                * disable SMP for now.
                 */
                if (BCMCPU_IS_6328()) {
                        reg = bcm_readl(BCM_6328_OTP_BASE +
@@ -74,7 +72,7 @@ void __init prom_init(void)
 
                        if (reg & OTP_6328_REG3_TP1_DISABLED)
                                bmips_smp_enabled = 0;
-               } else if (BCMCPU_IS_6358()) {
+               } else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
                        bmips_smp_enabled = 0;
                }
 
index ca0c343..61af6b6 100644 (file)
@@ -27,10 +27,10 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
        -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
        -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS)
 
-targets := head.o decompress.o dbg.o uart-16550.o uart-alchemy.o
+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)/dbg.o
+vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o $(obj)/dbg.o
 
 ifdef CONFIG_DEBUG_ZBOOT
 vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
index 134a616..06c6a5b 100644 (file)
@@ -6,7 +6,6 @@
  * need to implement your own putc().
  */
 #include <linux/compiler.h>
-#include <linux/init.h>
 #include <linux/types.h>
 
 void __weak putc(char c)
index a8c6fd6..c00c4dd 100644 (file)
@@ -43,33 +43,11 @@ void error(char *x)
 /* activate the code for pre-boot environment */
 #define STATIC static
 
-#if defined(CONFIG_KERNEL_GZIP) || defined(CONFIG_KERNEL_XZ) || \
-       defined(CONFIG_KERNEL_LZ4)
-void *memcpy(void *dest, const void *src, size_t n)
-{
-       int i;
-       const char *s = src;
-       char *d = dest;
-
-       for (i = 0; i < n; i++)
-               d[i] = s[i];
-       return dest;
-}
-#endif
 #ifdef CONFIG_KERNEL_GZIP
 #include "../../../../lib/decompress_inflate.c"
 #endif
 
 #ifdef CONFIG_KERNEL_BZIP2
-void *memset(void *s, int c, size_t n)
-{
-       int i;
-       char *ss = s;
-
-       for (i = 0; i < n; i++)
-               ss[i] = c;
-       return s;
-}
 #include "../../../../lib/decompress_bunzip2.c"
 #endif
 
diff --git a/arch/mips/boot/compressed/string.c b/arch/mips/boot/compressed/string.c
new file mode 100644 (file)
index 0000000..9de9885
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * arch/mips/boot/compressed/string.c
+ *
+ * Very small subset of simple string routines
+ */
+
+#include <linux/types.h>
+
+void *memcpy(void *dest, const void *src, size_t n)
+{
+       int i;
+       const char *s = src;
+       char *d = dest;
+
+       for (i = 0; i < n; i++)
+               d[i] = s[i];
+       return dest;
+}
+
+void *memset(void *s, int c, size_t n)
+{
+       int i;
+       char *ss = s;
+
+       for (i = 0; i < n; i++)
+               ss[i] = c;
+       return s;
+}
index c01d343..237494b 100644 (file)
@@ -4,7 +4,6 @@
 
 #include <linux/types.h>
 #include <linux/serial_reg.h>
-#include <linux/init.h>
 
 #include <asm/addrspace.h>
 
@@ -19,8 +18,8 @@
 #endif
 
 #ifdef CONFIG_MACH_JZ4740
-#define UART0_BASE  0xB0030000
-#define PORT(offset) (UART0_BASE + (4 * offset))
+#include <asm/mach-jz4740/base.h>
+#define PORT(offset) (CKSEG1ADDR(JZ4740_UART0_BASE_ADDR) + (4 * offset))
 #endif
 
 #ifdef CONFIG_CPU_XLR
index 132bccc..8241fc6 100644 (file)
@@ -47,6 +47,7 @@
  * state. It points to a bootmem named block.
  */
 __cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr;
+EXPORT_SYMBOL_GPL(__cvmx_cmd_queue_state_ptr);
 
 /**
  * Initialize the Global queue state pointer.
index 0a1283c..b764df6 100644 (file)
@@ -722,3 +722,30 @@ int __cvmx_helper_board_hardware_enable(int interface)
        }
        return 0;
 }
+
+/**
+ * Get the clock type used for the USB block based on board type.
+ * Used by the USB code for auto configuration of clock type.
+ *
+ * Return USB clock type enumeration
+ */
+enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void)
+{
+       switch (cvmx_sysinfo_get()->board_type) {
+       case CVMX_BOARD_TYPE_BBGW_REF:
+       case CVMX_BOARD_TYPE_LANAI2_A:
+       case CVMX_BOARD_TYPE_LANAI2_U:
+       case CVMX_BOARD_TYPE_LANAI2_G:
+       case CVMX_BOARD_TYPE_NIC10E_66:
+       case CVMX_BOARD_TYPE_UBNT_E100:
+               return USB_CLOCK_TYPE_CRYSTAL_12;
+       case CVMX_BOARD_TYPE_NIC10E:
+               return USB_CLOCK_TYPE_REF_12;
+       default:
+               break;
+       }
+       /* Most boards except NIC10e use a 12MHz crystal */
+       if (OCTEON_IS_MODEL(OCTEON_FAM_2))
+               return USB_CLOCK_TYPE_CRYSTAL_12;
+       return USB_CLOCK_TYPE_REF_48;
+}
index 65d2bc9..453d7f6 100644 (file)
@@ -251,6 +251,7 @@ int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_setup_red);
 
 /**
  * Setup the common GMX settings that determine the number of
@@ -384,6 +385,7 @@ int cvmx_helper_get_ipd_port(int interface, int port)
        }
        return -1;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_get_ipd_port);
 
 /**
  * Returns the interface number for an IPD/PKO port number.
@@ -408,6 +410,7 @@ int cvmx_helper_get_interface_num(int ipd_port)
 
        return -1;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_get_interface_num);
 
 /**
  * Returns the interface index number for an IPD/PKO port
@@ -431,3 +434,4 @@ int cvmx_helper_get_interface_index_num(int ipd_port)
 
        return -1;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_get_interface_index_num);
index d63d20d..8553ad5 100644 (file)
@@ -67,7 +67,7 @@ void (*cvmx_override_pko_queue_priority) (int pko_port,
 void (*cvmx_override_ipd_port_setup) (int ipd_port);
 
 /* Port count per interface */
-static int interface_port_count[4] = { 0, 0, 0, 0 };
+static int interface_port_count[5];
 
 /* Port last configured link info index by IPD/PKO port */
 static cvmx_helper_link_info_t
@@ -88,6 +88,7 @@ int cvmx_helper_get_number_of_interfaces(void)
        else
                return 3;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces);
 
 /**
  * Return the number of ports on an interface. Depending on the
@@ -102,6 +103,7 @@ int cvmx_helper_ports_on_interface(int interface)
 {
        return interface_port_count[interface];
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
 
 /**
  * Get the operating mode of an interface. Depending on the Octeon
@@ -179,6 +181,7 @@ cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
                        return CVMX_HELPER_INTERFACE_MODE_RGMII;
        }
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode);
 
 /**
  * Configure the IPD/PIP tagging and QoS options for a specific
@@ -825,6 +828,7 @@ int cvmx_helper_ipd_and_packet_input_enable(void)
                __cvmx_helper_errata_fix_ipd_ptr_alignment();
        return 0;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable);
 
 /**
  * Initialize the PIP, IPD, and PKO hardware to support
@@ -903,6 +907,7 @@ int cvmx_helper_initialize_packet_io_global(void)
 #endif
        return result;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global);
 
 /**
  * Does core local initialization for packet io
@@ -947,6 +952,7 @@ cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
         */
        return port_link_info[ipd_port];
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_link_autoconf);
 
 /**
  * Return the link state of an IPD/PKO port as returned by
@@ -1005,6 +1011,7 @@ cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
        }
        return result;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_link_get);
 
 /**
  * Configure an IPD/PKO port for the specified link state. This
@@ -1060,6 +1067,7 @@ int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
                port_link_info[ipd_port].u64 = link_info.u64;
        return result;
 }
+EXPORT_SYMBOL_GPL(cvmx_helper_link_set);
 
 /**
  * Configure a port for internal and/or external loopback. Internal loopback
index f2c8775..008b881 100644 (file)
@@ -140,7 +140,7 @@ void cvmx_pko_disable(void)
        pko_reg_flags.s.ena_pko = 0;
        cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
 }
-
+EXPORT_SYMBOL_GPL(cvmx_pko_disable);
 
 /**
  * Reset the packet output.
@@ -182,6 +182,7 @@ void cvmx_pko_shutdown(void)
        }
        __cvmx_pko_reset();
 }
+EXPORT_SYMBOL_GPL(cvmx_pko_shutdown);
 
 /**
  * Configure a output port and the associated queues for use.
index ef5198d..459e3b1 100644 (file)
@@ -177,6 +177,7 @@ int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout)
 
        return res;
 }
+EXPORT_SYMBOL_GPL(cvmx_spi_restart_interface);
 
 /**
  * Callback to perform SPI4 reset
index 1830874..6df0f4d 100644 (file)
@@ -171,6 +171,7 @@ device_initcall(octeon_ohci_device_init);
 static struct of_device_id __initdata octeon_ids[] = {
        { .compatible = "simple-bus", },
        { .compatible = "cavium,octeon-6335-uctl", },
+       { .compatible = "cavium,octeon-5750-usbn", },
        { .compatible = "cavium,octeon-3860-bootbus", },
        { .compatible = "cavium,mdio-mux", },
        { .compatible = "gpio-leds", },
@@ -336,14 +337,14 @@ static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac)
        int p;
        int count = 0;
 
-       if (cvmx_helper_interface_enumerate(idx) == 0)
-               count = cvmx_helper_ports_on_interface(idx);
-
        snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx);
        iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer);
        if (iface < 0)
                return;
 
+       if (cvmx_helper_interface_enumerate(idx) == 0)
+               count = cvmx_helper_ports_on_interface(idx);
+
        for (p = 0; p < 16; p++)
                octeon_fdt_pip_port(iface, idx, p, count - 1, pmac);
 }
@@ -682,6 +683,37 @@ end_led:
                }
        }
 
+       /* DWC2 USB */
+       alias_prop = fdt_getprop(initial_boot_params, aliases,
+                                "usbn", NULL);
+       if (alias_prop) {
+               int usbn = fdt_path_offset(initial_boot_params, alias_prop);
+
+               if (usbn >= 0 && (current_cpu_type() == CPU_CAVIUM_OCTEON2 ||
+                                 !octeon_has_feature(OCTEON_FEATURE_USB))) {
+                       pr_debug("Deleting usbn\n");
+                       fdt_nop_node(initial_boot_params, usbn);
+                       fdt_nop_property(initial_boot_params, aliases, "usbn");
+               } else  {
+                       __be32 new_f[1];
+                       enum cvmx_helper_board_usb_clock_types c;
+                       c = __cvmx_helper_board_usb_get_clock_type();
+                       switch (c) {
+                       case USB_CLOCK_TYPE_REF_48:
+                               new_f[0] = cpu_to_be32(48000000);
+                               fdt_setprop_inplace(initial_boot_params, usbn,
+                                                   "refclk-frequency",  new_f, sizeof(new_f));
+                               /* Fall through ...*/
+                       case USB_CLOCK_TYPE_REF_12:
+                               /* Missing "refclk-type" defaults to external. */
+                               fdt_nop_property(initial_boot_params, usbn, "refclk-type");
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+
        return 0;
 }
 
index 88cb42d..fa33115 100644 (file)
                                big-endian-regs;
                        };
                };
+
+               usbn: usbn@1180068000000 {
+                       compatible = "cavium,octeon-5750-usbn";
+                       reg = <0x11800 0x68000000 0x0 0x1000>;
+                       ranges; /* Direct mapping */
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       /* 12MHz, 24MHz and 48MHz allowed */
+                       refclk-frequency = <12000000>;
+                       /* Either "crystal" or "external" */
+                       refclk-type = "crystal";
+
+                       usbc@16f0010000000 {
+                               compatible = "cavium,octeon-5750-usbc";
+                               reg = <0x16f00 0x10000000 0x0 0x80000>;
+                               interrupts = <0 56>;
+                       };
+               };
        };
 
        aliases {
                flash0 = &flash0;
                cf0 = &cf0;
                uctl = &uctl;
+               usbn = &usbn;
                led0 = &led0;
        };
  };
index 24a2167..67a078f 100644 (file)
@@ -6,7 +6,6 @@
  * Copyright (C) 2004-2008, 2009, 2010 Cavium Networks
  */
 #include <linux/cpu.h>
-#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
index 80e012f..320772c 100644 (file)
@@ -86,7 +86,6 @@ CONFIG_MAC80211_RC_DEFAULT_PID=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index 4ca8e5c..0db4eb3 100644 (file)
 CONFIG_BCM47XX=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_KEXEC=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_AUDIT=y
-CONFIG_TINY_RCU=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_RELAY=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_UIDGID_STRICT_TYPE_CHECKS=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_RD_LZMA=y
-CONFIG_EXPERT=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_PCI=y
-CONFIG_BINFMT_MISC=m
+# CONFIG_SUSPEND is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
 CONFIG_IP_MULTIPLE_TABLES=y
 CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
 CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
 CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
 CONFIG_TCP_CONG_ADVANCED=y
-CONFIG_TCP_CONG_BIC=y
-CONFIG_TCP_CONG_CUBIC=m
-CONFIG_TCP_CONG_HSTCP=m
-CONFIG_TCP_CONG_HYBLA=m
-CONFIG_TCP_CONG_SCALABLE=m
-CONFIG_TCP_CONG_LP=m
-CONFIG_TCP_CONG_VENO=m
-CONFIG_TCP_CONG_YEAH=m
-CONFIG_TCP_CONG_ILLINOIS=m
 CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_TUNNEL=m
 CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_IPV6_SUBTREES=y
-CONFIG_NETWORK_SECMARK=y
+CONFIG_IPV6_MROUTE=y
 CONFIG_NETFILTER=y
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_UDPLITE=m
-CONFIG_NF_CONNTRACK_AMANDA=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_H323=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_NETBIOS_NS=m
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SANE=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_DSCP=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_IP_VS=m
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-CONFIG_IP_VS_FTP=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_NF_NAT=m
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_AH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_MH=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m
-CONFIG_BRIDGE_NF_EBTABLES=m
-CONFIG_BRIDGE_EBT_BROUTE=m
-CONFIG_BRIDGE_EBT_T_FILTER=m
-CONFIG_BRIDGE_EBT_T_NAT=m
-CONFIG_BRIDGE_EBT_802_3=m
-CONFIG_BRIDGE_EBT_AMONG=m
-CONFIG_BRIDGE_EBT_ARP=m
-CONFIG_BRIDGE_EBT_IP=m
-CONFIG_BRIDGE_EBT_LIMIT=m
-CONFIG_BRIDGE_EBT_MARK=m
-CONFIG_BRIDGE_EBT_PKTTYPE=m
-CONFIG_BRIDGE_EBT_STP=m
-CONFIG_BRIDGE_EBT_VLAN=m
-CONFIG_BRIDGE_EBT_ARPREPLY=m
-CONFIG_BRIDGE_EBT_DNAT=m
-CONFIG_BRIDGE_EBT_MARK_T=m
-CONFIG_BRIDGE_EBT_REDIRECT=m
-CONFIG_BRIDGE_EBT_SNAT=m
-CONFIG_BRIDGE_EBT_LOG=m
-CONFIG_BRIDGE_EBT_ULOG=m
-CONFIG_IP_DCCP=m
-CONFIG_TIPC=m
-CONFIG_TIPC_ADVANCED=y
-CONFIG_ATM=m
-CONFIG_ATM_CLIP=m
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
-CONFIG_ATM_BR2684=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q=y
 CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_CLS_U32_PERF=y
-CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_EMATCH=y
-CONFIG_NET_EMATCH_CMP=m
-CONFIG_NET_EMATCH_NBYTE=m
-CONFIG_NET_EMATCH_U32=m
-CONFIG_NET_EMATCH_META=m
-CONFIG_NET_EMATCH_TEXT=m
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=m
-CONFIG_NET_ACT_GACT=m
-CONFIG_GACT_PROB=y
-CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
-CONFIG_NET_ACT_NAT=m
-CONFIG_NET_ACT_PEDIT=m
-CONFIG_NET_ACT_SIMP=m
-CONFIG_NET_CLS_IND=y
-CONFIG_NET_PKTGEN=m
-CONFIG_BT=m
-CONFIG_BT_HCIUART=m
-CONFIG_BT_HCIUART_H4=y
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_LL=y
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIVHCI=m
-CONFIG_CFG80211=m
-CONFIG_MAC80211=m
-CONFIG_MAC80211_RC_PID=y
-CONFIG_MAC80211_RC_DEFAULT_PID=y
-CONFIG_MAC80211_MESH=y
-CONFIG_RFKILL=m
-CONFIG_RFKILL_INPUT=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_FW_LOADER=m
-CONFIG_CONNECTOR=m
+CONFIG_NET_SCH_FQ_CODEL=y
+CONFIG_HAMRADIO=y
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
+CONFIG_MTD_BCM47XX_PARTS=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_STAA=y
-CONFIG_MTD_RAM=y
-CONFIG_MTD_ROM=y
-CONFIG_MTD_ABSENT=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_ATA_OVER_ETH=m
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=y
-CONFIG_SCSI_TGT=m
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=m
-CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_ISCSI_TCP=m
+CONFIG_MTD_BCM47XXSFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_BCM47XXNFLASH=y
 CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_EQUALIZER=m
-CONFIG_TUN=m
-CONFIG_VETH=m
-CONFIG_PHYLIB=m
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-CONFIG_VITESSE_PHY=m
-CONFIG_SMSC_PHY=m
-CONFIG_BROADCOM_PHY=m
-CONFIG_ICPLUS_PHY=m
-CONFIG_MDIO_BITBANG=m
-CONFIG_NET_ETHERNET=y
-CONFIG_NET_PCI=y
 CONFIG_B44=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_ATH_COMMON=m
-CONFIG_ATH5K=m
-CONFIG_B43=m
-CONFIG_B43LEGACY=m
-CONFIG_ZD1211RW=m
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_DM9601=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-CONFIG_USB_SIERRA_NET=m
-CONFIG_ATM_DUMMY=m
-CONFIG_ATM_TCP=m
-CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPPOATM=m
-CONFIG_SLIP=m
-CONFIG_INPUT_EVDEV=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
+CONFIG_TIGON3=y
+CONFIG_BGMAC=y
+CONFIG_ATH_CARDS=y
+CONFIG_ATH5K=y
+CONFIG_B43=y
+CONFIG_B43LEGACY=y
+CONFIG_BRCMSMAC=y
+CONFIG_ISDN=y
 CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_PCI is not set
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_W1=m
-CONFIG_W1_MASTER_MATROX=m
-CONFIG_W1_MASTER_DS2490=m
-CONFIG_W1_SLAVE_THERM=m
-CONFIG_W1_SLAVE_SMEM=m
-CONFIG_W1_SLAVE_DS2433=m
-CONFIG_W1_SLAVE_DS2760=m
-# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_HW_RANDOM=y
+CONFIG_GPIO_SYSFS=y
 CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_BCM47XX_WDT=y
+CONFIG_SSB_DEBUG=y
 CONFIG_SSB_DRIVER_GIGE=y
-CONFIG_DISPLAY_SUPPORT=m
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_SEQUENCER_OSS=y
-CONFIG_SND_DUMMY=m
-CONFIG_SND_VIRMIDI=m
-CONFIG_SND_USB_AUDIO=m
-CONFIG_HID=m
-CONFIG_USB_HID=m
-CONFIG_USB_HIDDEV=y
+CONFIG_BCMA_DRIVER_GMAC_CMN=y
 CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_U132_HCD=m
-CONFIG_USB_R8A66597_HCD=m
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_MDC800=m
-CONFIG_USB_MICROTEK=m
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_AIRCABLE=m
-CONFIG_USB_SERIAL_ARK3116=m
-CONFIG_USB_SERIAL_BELKIN=m
-CONFIG_USB_SERIAL_CH341=m
-CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-CONFIG_USB_SERIAL_CYPRESS_M8=m
-CONFIG_USB_SERIAL_EMPEG=m
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_FUNSOFT=m
-CONFIG_USB_SERIAL_VISOR=m
-CONFIG_USB_SERIAL_IPAQ=m
-CONFIG_USB_SERIAL_IR=m
-CONFIG_USB_SERIAL_GARMIN=m
-CONFIG_USB_SERIAL_IPW=m
-CONFIG_USB_SERIAL_KEYSPAN_PDA=m
-CONFIG_USB_SERIAL_KLSI=m
-CONFIG_USB_SERIAL_KOBIL_SCT=m
-CONFIG_USB_SERIAL_MCT_U232=m
-CONFIG_USB_SERIAL_MOS7720=m
-CONFIG_USB_SERIAL_MOS7840=m
-CONFIG_USB_SERIAL_NAVMAN=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_SERIAL_OTI6858=m
-CONFIG_USB_SERIAL_HP4X=m
-CONFIG_USB_SERIAL_SAFE=m
-CONFIG_USB_SERIAL_SIERRAWIRELESS=m
-CONFIG_USB_SERIAL_CYBERJACK=m
-CONFIG_USB_SERIAL_XIRCOM=m
-CONFIG_USB_SERIAL_OPTION=m
-CONFIG_USB_SERIAL_OMNINET=m
-CONFIG_USB_SERIAL_DEBUG=m
-CONFIG_USB_ADUTUX=m
-CONFIG_USB_RIO500=m
-CONFIG_USB_LEGOTOWER=m
-CONFIG_USB_LCD=m
-CONFIG_USB_LED=m
-CONFIG_USB_CYPRESS_CY7C63=m
-CONFIG_USB_CYTHERM=m
-CONFIG_USB_IDMOUSE=m
-CONFIG_USB_FTDI_ELAN=m
-CONFIG_USB_SISUSBVGA=m
-CONFIG_USB_LD=m
-CONFIG_USB_TRANCEVIBRATOR=m
-CONFIG_USB_IOWARRIOR=m
-CONFIG_USB_TEST=m
-CONFIG_USB_ATM=m
-CONFIG_USB_SPEEDTOUCH=m
-CONFIG_USB_CXACRU=m
-CONFIG_USB_UEAGLEATM=m
-CONFIG_USB_XUSBATM=m
-CONFIG_USB_GADGET=m
-CONFIG_USB_GADGET_NET2280=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_MASS_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_USB_MIDI_GADGET=m
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
+CONFIG_USB_HCD_BCMA=y
+CONFIG_USB_HCD_SSB=y
 CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_REISERFS_FS=m
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-CONFIG_JFS_FS=m
-CONFIG_JFS_POSIX_ACL=y
-CONFIG_JFS_SECURITY=y
-CONFIG_XFS_FS=m
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_XFS_RT=y
-CONFIG_GFS2_FS=m
-CONFIG_QUOTA=y
-CONFIG_QUOTA_NETLINK_INTERFACE=y
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_ADFS_FS=m
-CONFIG_AFFS_FS=m
-CONFIG_HFS_FS=m
-CONFIG_HFSPLUS_FS=m
-CONFIG_BEFS_FS=m
-CONFIG_BFS_FS=m
-CONFIG_EFS_FS=m
-CONFIG_JFFS2_FS=m
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_CRAMFS=m
-CONFIG_VXFS_FS=m
-CONFIG_MINIX_FS=m
-CONFIG_HPFS_FS=m
-CONFIG_QNX4FS_FS=m
-CONFIG_ROMFS_FS=m
-CONFIG_SYSV_FS=m
-CONFIG_UFS_FS=m
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_RPCSEC_GSS_SPKM3=m
-CONFIG_CIFS=m
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-CONFIG_NCP_FS=m
-CONFIG_NCPFS_NFS_NS=y
-CONFIG_NCPFS_OS2_NS=y
-CONFIG_NCPFS_NLS=y
-CONFIG_NCPFS_EXTRAS=y
-CONFIG_CODA_FS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_KARMA_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_DLM=m
-CONFIG_DLM_DEBUG=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_STRIP_ASM_SYMS=y
 CONFIG_DEBUG_FS=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SEED=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRC16=m
-CONFIG_CRC7=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,115200"
+CONFIG_CRC32_SARWATE=y
index 9190051..3fec264 100644 (file)
@@ -44,7 +44,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
index 5419adb..23b6693 100644 (file)
@@ -19,7 +19,6 @@ CONFIG_INET=y
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_JEDECPROBE=y
index fb64589..8f219da 100644 (file)
@@ -165,7 +165,6 @@ CONFIG_YAM=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index db5705e..9bc08f2 100644 (file)
@@ -22,7 +22,6 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_CFI=y
index d9f3db2..0179c7f 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_INET=y
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index 8a66602..d759318 100644 (file)
@@ -4,7 +4,7 @@ CONFIG_CPU_MIPS32_R2=y
 CONFIG_MIPS_MT_SMP=y
 CONFIG_SCHED_SMT=y
 CONFIG_MIPS_CMP=y
-CONFIG_NR_CPUS=8
+CONFIG_NR_CPUS=2
 CONFIG_HZ_100=y
 CONFIG_LOCALVERSION="cmp"
 CONFIG_SYSVIPC=y
@@ -58,7 +58,6 @@ CONFIG_ATALK=m
 CONFIG_DEV_APPLETALK=m
 CONFIG_IPDDP=m
 CONFIG_IPDDP_ENCAP=y
-CONFIG_IPDDP_DECAP=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
index 636f82b..4c2c0c4 100644 (file)
@@ -124,7 +124,6 @@ CONFIG_IP6_NF_MANGLE=m
 CONFIG_IP6_NF_RAW=m
 CONFIG_FW_LOADER=m
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 9fa8f16..593946a 100644 (file)
@@ -246,7 +246,6 @@ CONFIG_BT_HCIBTUART=m
 CONFIG_BT_HCIVHCI=m
 CONFIG_CONNECTOR=m
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index f292576..c887066 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_INET_AH=y
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
diff --git a/arch/mips/configs/qi_lb60_defconfig b/arch/mips/configs/qi_lb60_defconfig
new file mode 100644 (file)
index 0000000..2b96547
--- /dev/null
@@ -0,0 +1,188 @@
+CONFIG_MACH_JZ4740=y
+# CONFIG_COMPACTION is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_HZ_100=y
+CONFIG_PREEMPT=y
+# CONFIG_SECCOMP is not set
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_CUBIC is not set
+CONFIG_TCP_CONG_WESTWOOD=y
+# CONFIG_TCP_CONG_HTCP is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_JZ4740=y
+CONFIG_MTD_UBI=y
+CONFIG_NETDEVICES=y
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_MATRIX=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_DMA is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_HW_RANDOM is not set
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_JZ4740=y
+CONFIG_CHARGER_GPIO=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_JZ4740_ADC=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_FB=y
+CONFIG_FB_JZ4740=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_JZ4740_SOC=y
+CONFIG_SND_JZ4740_SOC_QI_LB60=y
+CONFIG_USB=y
+CONFIG_USB_OTG_BLACKLIST_HUB=y
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_GADGET=y
+CONFIG_USB_MUSB_JZ4740=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_JZ4740=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_JZ4740=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_JZ4740=y
+CONFIG_PWM=y
+CONFIG_PWM_JZ4740=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+# CONFIG_JFFS2_ZLIB is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_READABLE_ASM=y
+CONFIG_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_FTRACE is not set
+CONFIG_KGDB=y
+CONFIG_RUNTIME_DEBUG=y
+CONFIG_CRYPTO_ZLIB=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_FONTS=y
+CONFIG_FONT_SUN8x16=y
index b85b121..5d9d708 100644 (file)
@@ -114,7 +114,6 @@ CONFIG_NET_CLS_IND=y
 CONFIG_HAMRADIO=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_BLOCK2MTD=y
index 9cba856..f8bf9b4 100644 (file)
@@ -35,7 +35,6 @@ CONFIG_IP_PNP=y
 # CONFIG_IPV6 is not set
 # CONFIG_WIRELESS is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=m
index a8b0803..49fd3ff 100644 (file)
@@ -8,7 +8,6 @@
  * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#include <linux/init.h>
 
 #include <asm/fw/arc/types.h>
 #include <asm/sgialib.h>
index c3dc1a6..3cc03c6 100644 (file)
@@ -1,7 +1,12 @@
 /*
- * Amon support
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ *
+ * Arbitrary Monitor Support (AMON)
  */
-
-int amon_cpu_avail(int);
-void amon_cpu_start(int, unsigned long, unsigned long,
-                   unsigned long, unsigned long);
+int amon_cpu_avail(int cpu);
+int amon_cpu_start(int cpu, unsigned long pc, unsigned long sp,
+                  unsigned long gp, unsigned long a0);
index 2413afe..70e1f17 100644 (file)
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 
-       .macro  fpu_save_double thread status tmp1=t0
-       cfc1    \tmp1,  fcr31
-       sdc1    $f0,  THREAD_FPR0(\thread)
-       sdc1    $f2,  THREAD_FPR2(\thread)
-       sdc1    $f4,  THREAD_FPR4(\thread)
-       sdc1    $f6,  THREAD_FPR6(\thread)
-       sdc1    $f8,  THREAD_FPR8(\thread)
-       sdc1    $f10, THREAD_FPR10(\thread)
-       sdc1    $f12, THREAD_FPR12(\thread)
-       sdc1    $f14, THREAD_FPR14(\thread)
-       sdc1    $f16, THREAD_FPR16(\thread)
-       sdc1    $f18, THREAD_FPR18(\thread)
-       sdc1    $f20, THREAD_FPR20(\thread)
-       sdc1    $f22, THREAD_FPR22(\thread)
-       sdc1    $f24, THREAD_FPR24(\thread)
-       sdc1    $f26, THREAD_FPR26(\thread)
-       sdc1    $f28, THREAD_FPR28(\thread)
-       sdc1    $f30, THREAD_FPR30(\thread)
-       sw      \tmp1, THREAD_FCR31(\thread)
-       .endm
-
        .macro  fpu_save_single thread tmp=t0
        cfc1    \tmp,  fcr31
        swc1    $f0,  THREAD_FPR0(\thread)
        sw      \tmp, THREAD_FCR31(\thread)
        .endm
 
-       .macro  fpu_restore_double thread status tmp=t0
-       lw      \tmp, THREAD_FCR31(\thread)
-       ldc1    $f0,  THREAD_FPR0(\thread)
-       ldc1    $f2,  THREAD_FPR2(\thread)
-       ldc1    $f4,  THREAD_FPR4(\thread)
-       ldc1    $f6,  THREAD_FPR6(\thread)
-       ldc1    $f8,  THREAD_FPR8(\thread)
-       ldc1    $f10, THREAD_FPR10(\thread)
-       ldc1    $f12, THREAD_FPR12(\thread)
-       ldc1    $f14, THREAD_FPR14(\thread)
-       ldc1    $f16, THREAD_FPR16(\thread)
-       ldc1    $f18, THREAD_FPR18(\thread)
-       ldc1    $f20, THREAD_FPR20(\thread)
-       ldc1    $f22, THREAD_FPR22(\thread)
-       ldc1    $f24, THREAD_FPR24(\thread)
-       ldc1    $f26, THREAD_FPR26(\thread)
-       ldc1    $f28, THREAD_FPR28(\thread)
-       ldc1    $f30, THREAD_FPR30(\thread)
-       ctc1    \tmp, fcr31
-       .endm
-
        .macro  fpu_restore_single thread tmp=t0
        lw      \tmp, THREAD_FCR31(\thread)
        lwc1    $f0,  THREAD_FPR0(\thread)
index 08a527d..38ea609 100644 (file)
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 
-       .macro  fpu_save_16even thread tmp=t0
-       cfc1    \tmp, fcr31
-       sdc1    $f0,  THREAD_FPR0(\thread)
-       sdc1    $f2,  THREAD_FPR2(\thread)
-       sdc1    $f4,  THREAD_FPR4(\thread)
-       sdc1    $f6,  THREAD_FPR6(\thread)
-       sdc1    $f8,  THREAD_FPR8(\thread)
-       sdc1    $f10, THREAD_FPR10(\thread)
-       sdc1    $f12, THREAD_FPR12(\thread)
-       sdc1    $f14, THREAD_FPR14(\thread)
-       sdc1    $f16, THREAD_FPR16(\thread)
-       sdc1    $f18, THREAD_FPR18(\thread)
-       sdc1    $f20, THREAD_FPR20(\thread)
-       sdc1    $f22, THREAD_FPR22(\thread)
-       sdc1    $f24, THREAD_FPR24(\thread)
-       sdc1    $f26, THREAD_FPR26(\thread)
-       sdc1    $f28, THREAD_FPR28(\thread)
-       sdc1    $f30, THREAD_FPR30(\thread)
-       sw      \tmp, THREAD_FCR31(\thread)
-       .endm
-
-       .macro  fpu_save_16odd thread
-       sdc1    $f1,  THREAD_FPR1(\thread)
-       sdc1    $f3,  THREAD_FPR3(\thread)
-       sdc1    $f5,  THREAD_FPR5(\thread)
-       sdc1    $f7,  THREAD_FPR7(\thread)
-       sdc1    $f9,  THREAD_FPR9(\thread)
-       sdc1    $f11, THREAD_FPR11(\thread)
-       sdc1    $f13, THREAD_FPR13(\thread)
-       sdc1    $f15, THREAD_FPR15(\thread)
-       sdc1    $f17, THREAD_FPR17(\thread)
-       sdc1    $f19, THREAD_FPR19(\thread)
-       sdc1    $f21, THREAD_FPR21(\thread)
-       sdc1    $f23, THREAD_FPR23(\thread)
-       sdc1    $f25, THREAD_FPR25(\thread)
-       sdc1    $f27, THREAD_FPR27(\thread)
-       sdc1    $f29, THREAD_FPR29(\thread)
-       sdc1    $f31, THREAD_FPR31(\thread)
-       .endm
-
-       .macro  fpu_save_double thread status tmp
-       sll     \tmp, \status, 5
-       bgez    \tmp, 2f
-       fpu_save_16odd \thread
-2:
-       fpu_save_16even \thread \tmp
-       .endm
-
-       .macro  fpu_restore_16even thread tmp=t0
-       lw      \tmp, THREAD_FCR31(\thread)
-       ldc1    $f0,  THREAD_FPR0(\thread)
-       ldc1    $f2,  THREAD_FPR2(\thread)
-       ldc1    $f4,  THREAD_FPR4(\thread)
-       ldc1    $f6,  THREAD_FPR6(\thread)
-       ldc1    $f8,  THREAD_FPR8(\thread)
-       ldc1    $f10, THREAD_FPR10(\thread)
-       ldc1    $f12, THREAD_FPR12(\thread)
-       ldc1    $f14, THREAD_FPR14(\thread)
-       ldc1    $f16, THREAD_FPR16(\thread)
-       ldc1    $f18, THREAD_FPR18(\thread)
-       ldc1    $f20, THREAD_FPR20(\thread)
-       ldc1    $f22, THREAD_FPR22(\thread)
-       ldc1    $f24, THREAD_FPR24(\thread)
-       ldc1    $f26, THREAD_FPR26(\thread)
-       ldc1    $f28, THREAD_FPR28(\thread)
-       ldc1    $f30, THREAD_FPR30(\thread)
-       ctc1    \tmp, fcr31
-       .endm
-
-       .macro  fpu_restore_16odd thread
-       ldc1    $f1,  THREAD_FPR1(\thread)
-       ldc1    $f3,  THREAD_FPR3(\thread)
-       ldc1    $f5,  THREAD_FPR5(\thread)
-       ldc1    $f7,  THREAD_FPR7(\thread)
-       ldc1    $f9,  THREAD_FPR9(\thread)
-       ldc1    $f11, THREAD_FPR11(\thread)
-       ldc1    $f13, THREAD_FPR13(\thread)
-       ldc1    $f15, THREAD_FPR15(\thread)
-       ldc1    $f17, THREAD_FPR17(\thread)
-       ldc1    $f19, THREAD_FPR19(\thread)
-       ldc1    $f21, THREAD_FPR21(\thread)
-       ldc1    $f23, THREAD_FPR23(\thread)
-       ldc1    $f25, THREAD_FPR25(\thread)
-       ldc1    $f27, THREAD_FPR27(\thread)
-       ldc1    $f29, THREAD_FPR29(\thread)
-       ldc1    $f31, THREAD_FPR31(\thread)
-       .endm
-
-       .macro  fpu_restore_double thread status tmp
-       sll     \tmp, \status, 5
-       bgez    \tmp, 1f                                # 16 register mode?
-
-       fpu_restore_16odd \thread
-1:     fpu_restore_16even \thread \tmp
-       .endm
-
        .macro  cpu_save_nonscratch thread
        LONG_S  s0, THREAD_REG16(\thread)
        LONG_S  s1, THREAD_REG17(\thread)
index 6c8342a..3220c93 100644 (file)
        .endm
 #endif /* CONFIG_MIPS_MT_SMTC */
 
+       .macro  fpu_save_16even thread tmp=t0
+       cfc1    \tmp, fcr31
+       sdc1    $f0,  THREAD_FPR0(\thread)
+       sdc1    $f2,  THREAD_FPR2(\thread)
+       sdc1    $f4,  THREAD_FPR4(\thread)
+       sdc1    $f6,  THREAD_FPR6(\thread)
+       sdc1    $f8,  THREAD_FPR8(\thread)
+       sdc1    $f10, THREAD_FPR10(\thread)
+       sdc1    $f12, THREAD_FPR12(\thread)
+       sdc1    $f14, THREAD_FPR14(\thread)
+       sdc1    $f16, THREAD_FPR16(\thread)
+       sdc1    $f18, THREAD_FPR18(\thread)
+       sdc1    $f20, THREAD_FPR20(\thread)
+       sdc1    $f22, THREAD_FPR22(\thread)
+       sdc1    $f24, THREAD_FPR24(\thread)
+       sdc1    $f26, THREAD_FPR26(\thread)
+       sdc1    $f28, THREAD_FPR28(\thread)
+       sdc1    $f30, THREAD_FPR30(\thread)
+       sw      \tmp, THREAD_FCR31(\thread)
+       .endm
+
+       .macro  fpu_save_16odd thread
+       .set    push
+       .set    mips64r2
+       sdc1    $f1,  THREAD_FPR1(\thread)
+       sdc1    $f3,  THREAD_FPR3(\thread)
+       sdc1    $f5,  THREAD_FPR5(\thread)
+       sdc1    $f7,  THREAD_FPR7(\thread)
+       sdc1    $f9,  THREAD_FPR9(\thread)
+       sdc1    $f11, THREAD_FPR11(\thread)
+       sdc1    $f13, THREAD_FPR13(\thread)
+       sdc1    $f15, THREAD_FPR15(\thread)
+       sdc1    $f17, THREAD_FPR17(\thread)
+       sdc1    $f19, THREAD_FPR19(\thread)
+       sdc1    $f21, THREAD_FPR21(\thread)
+       sdc1    $f23, THREAD_FPR23(\thread)
+       sdc1    $f25, THREAD_FPR25(\thread)
+       sdc1    $f27, THREAD_FPR27(\thread)
+       sdc1    $f29, THREAD_FPR29(\thread)
+       sdc1    $f31, THREAD_FPR31(\thread)
+       .set    pop
+       .endm
+
+       .macro  fpu_save_double thread status tmp
+#if defined(CONFIG_MIPS64) || defined(CONFIG_CPU_MIPS32_R2)
+       sll     \tmp, \status, 5
+       bgez    \tmp, 10f
+       fpu_save_16odd \thread
+10:
+#endif
+       fpu_save_16even \thread \tmp
+       .endm
+
+       .macro  fpu_restore_16even thread tmp=t0
+       lw      \tmp, THREAD_FCR31(\thread)
+       ldc1    $f0,  THREAD_FPR0(\thread)
+       ldc1    $f2,  THREAD_FPR2(\thread)
+       ldc1    $f4,  THREAD_FPR4(\thread)
+       ldc1    $f6,  THREAD_FPR6(\thread)
+       ldc1    $f8,  THREAD_FPR8(\thread)
+       ldc1    $f10, THREAD_FPR10(\thread)
+       ldc1    $f12, THREAD_FPR12(\thread)
+       ldc1    $f14, THREAD_FPR14(\thread)
+       ldc1    $f16, THREAD_FPR16(\thread)
+       ldc1    $f18, THREAD_FPR18(\thread)
+       ldc1    $f20, THREAD_FPR20(\thread)
+       ldc1    $f22, THREAD_FPR22(\thread)
+       ldc1    $f24, THREAD_FPR24(\thread)
+       ldc1    $f26, THREAD_FPR26(\thread)
+       ldc1    $f28, THREAD_FPR28(\thread)
+       ldc1    $f30, THREAD_FPR30(\thread)
+       ctc1    \tmp, fcr31
+       .endm
+
+       .macro  fpu_restore_16odd thread
+       .set    push
+       .set    mips64r2
+       ldc1    $f1,  THREAD_FPR1(\thread)
+       ldc1    $f3,  THREAD_FPR3(\thread)
+       ldc1    $f5,  THREAD_FPR5(\thread)
+       ldc1    $f7,  THREAD_FPR7(\thread)
+       ldc1    $f9,  THREAD_FPR9(\thread)
+       ldc1    $f11, THREAD_FPR11(\thread)
+       ldc1    $f13, THREAD_FPR13(\thread)
+       ldc1    $f15, THREAD_FPR15(\thread)
+       ldc1    $f17, THREAD_FPR17(\thread)
+       ldc1    $f19, THREAD_FPR19(\thread)
+       ldc1    $f21, THREAD_FPR21(\thread)
+       ldc1    $f23, THREAD_FPR23(\thread)
+       ldc1    $f25, THREAD_FPR25(\thread)
+       ldc1    $f27, THREAD_FPR27(\thread)
+       ldc1    $f29, THREAD_FPR29(\thread)
+       ldc1    $f31, THREAD_FPR31(\thread)
+       .set    pop
+       .endm
+
+       .macro  fpu_restore_double thread status tmp
+#if defined(CONFIG_MIPS64) || defined(CONFIG_CPU_MIPS32_R2)
+       sll     \tmp, \status, 5
+       bgez    \tmp, 10f                               # 16 register mode?
+
+       fpu_restore_16odd \thread
+10:
+#endif
+       fpu_restore_16even \thread \tmp
+       .endm
+
 /*
  * Temporary until all gas have MT ASE support
  */
index 27bd060..cbacceb 100644 (file)
 
 #include <linux/cpumask.h>
 #include <asm/r4kcache.h>
+#include <asm/smp-ops.h>
+
+extern struct plat_smp_ops bmips43xx_smp_ops;
+extern struct plat_smp_ops bmips5000_smp_ops;
+
+static inline int register_bmips_smp_ops(void)
+{
+#if IS_ENABLED(CONFIG_CPU_BMIPS) && IS_ENABLED(CONFIG_SMP)
+       switch (current_cpu_type()) {
+       case CPU_BMIPS32:
+       case CPU_BMIPS3300:
+               return register_up_smp_ops();
+       case CPU_BMIPS4350:
+       case CPU_BMIPS4380:
+               register_smp_ops(&bmips43xx_smp_ops);
+               break;
+       case CPU_BMIPS5000:
+               register_smp_ops(&bmips5000_smp_ops);
+               break;
+       default:
+               return -ENODEV;
+       }
+
+       return 0;
+#else
+       return -ENODEV;
+#endif
+}
 
-extern struct plat_smp_ops bmips_smp_ops;
 extern char bmips_reset_nmi_vec;
 extern char bmips_reset_nmi_vec_end;
 extern char bmips_smp_movevec;
index d445d06..6e70b03 100644 (file)
 #ifndef cpu_has_tlb
 #define cpu_has_tlb            (cpu_data[0].options & MIPS_CPU_TLB)
 #endif
+#ifndef cpu_has_tlbinv
+#define cpu_has_tlbinv         (cpu_data[0].options & MIPS_CPU_TLBINV)
+#endif
+#ifndef cpu_has_segments
+#define cpu_has_segments       (cpu_data[0].options & MIPS_CPU_SEGMENTS)
+#endif
+
 
 /*
  * For the moment we don't consider R6000 and R8000 so we can assume that
index 21c8e29..8f7adf0 100644 (file)
@@ -52,6 +52,9 @@ struct cpuinfo_mips {
        unsigned int            cputype;
        int                     isa_level;
        int                     tlbsize;
+       int                     tlbsizevtlb;
+       int                     tlbsizeftlbsets;
+       int                     tlbsizeftlbways;
        struct cache_desc       icache; /* Primary I-cache */
        struct cache_desc       dcache; /* Primary D or combined I/D cache */
        struct cache_desc       scache; /* Secondary cache */
index 4a402cc..02f591b 100644 (file)
@@ -27,10 +27,7 @@ static inline int __pure __get_cpu_type(const int cpu_type)
 #ifdef CONFIG_SYS_HAS_CPU_MIPS32_R1
        case CPU_4KC:
        case CPU_ALCHEMY:
-       case CPU_BMIPS3300:
-       case CPU_BMIPS4350:
        case CPU_PR4450:
-       case CPU_BMIPS32:
        case CPU_JZRISC:
 #endif
 
@@ -47,6 +44,8 @@ static inline int __pure __get_cpu_type(const int cpu_type)
        case CPU_74K:
        case CPU_M14KC:
        case CPU_M14KEC:
+       case CPU_INTERAPTIV:
+       case CPU_PROAPTIV:
 #endif
 
 #ifdef CONFIG_SYS_HAS_CPU_MIPS64_R1
@@ -163,6 +162,16 @@ static inline int __pure __get_cpu_type(const int cpu_type)
        case CPU_CAVIUM_OCTEON2:
 #endif
 
+#if defined(CONFIG_SYS_HAS_CPU_BMIPS32_3300) || \
+       defined (CONFIG_SYS_HAS_CPU_MIPS32_R1)
+       case CPU_BMIPS32:
+       case CPU_BMIPS3300:
+#endif
+
+#ifdef CONFIG_SYS_HAS_CPU_BMIPS4350
+       case CPU_BMIPS4350:
+#endif
+
 #ifdef CONFIG_SYS_HAS_CPU_BMIPS4380
        case CPU_BMIPS4380:
 #endif
index d2035e1..76411df 100644 (file)
 #define PRID_IMP_1074K         0x9a00
 #define PRID_IMP_M14KC         0x9c00
 #define PRID_IMP_M14KEC                0x9e00
+#define PRID_IMP_INTERAPTIV_UP 0xa000
+#define PRID_IMP_INTERAPTIV_MP 0xa100
+#define PRID_IMP_PROAPTIV_UP   0xa200
+#define PRID_IMP_PROAPTIV_MP   0xa300
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
 #define PRID_IMP_NETLOGIC_XLP8XX       0x1000
 #define PRID_IMP_NETLOGIC_XLP3XX       0x1100
 #define PRID_IMP_NETLOGIC_XLP2XX       0x1200
+#define PRID_IMP_NETLOGIC_XLP9XX       0x1500
 
 /*
  * Particular Revision values for bits 7:0 of the PRId register.
 
 #define FPIR_IMP_NONE          0x0000
 
+#if !defined(__ASSEMBLY__)
+
 enum cpu_type_enum {
        CPU_UNKNOWN,
 
@@ -289,7 +296,7 @@ enum cpu_type_enum {
        CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
        CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
        CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
-       CPU_M14KEC,
+       CPU_M14KEC, CPU_INTERAPTIV, CPU_PROAPTIV,
 
        /*
         * MIPS64 class processors
@@ -301,6 +308,7 @@ enum cpu_type_enum {
        CPU_LAST
 };
 
+#endif /* !__ASSEMBLY */
 
 /*
  * ISA Level encodings
@@ -348,6 +356,8 @@ enum cpu_type_enum {
 #define MIPS_CPU_PCI           0x00400000 /* CPU has Perf Ctr Int indicator */
 #define MIPS_CPU_RIXI          0x00800000 /* CPU has TLB Read/eXec Inhibit */
 #define MIPS_CPU_MICROMIPS     0x01000000 /* CPU has microMIPS capability */
+#define MIPS_CPU_TLBINV                0x02000000 /* CPU supports TLBINV/F */
+#define MIPS_CPU_SEGMENTS      0x04000000 /* CPU supports Segmentation Control registers */
 
 /*
  * CPU ASE encodings
index 242cbb3..bc5e85d 100644 (file)
@@ -9,7 +9,16 @@
 #ifndef __ASM_DMA_COHERENCE_H
 #define __ASM_DMA_COHERENCE_H
 
+#ifdef CONFIG_DMA_MAYBE_COHERENT
 extern int coherentio;
 extern int hw_coherentio;
+#else
+#ifdef CONFIG_DMA_COHERENT
+#define coherentio     1
+#else
+#define coherentio     0
+#endif
+#define hw_coherentio  0
+#endif /* CONFIG_DMA_MAYBE_COHERENT */
 
 #endif
index a66359e..d414405 100644 (file)
@@ -36,6 +36,7 @@
 #define EF_MIPS_ABI2           0x00000020
 #define EF_MIPS_OPTIONS_FIRST  0x00000080
 #define EF_MIPS_32BITMODE      0x00000100
+#define EF_MIPS_FP64           0x00000200
 #define EF_MIPS_ABI            0x0000f000
 #define EF_MIPS_ARCH           0xf0000000
 
@@ -175,6 +176,18 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
 #ifdef CONFIG_32BIT
 
+/*
+ * In order to be sure that we don't attempt to execute an O32 binary which
+ * requires 64 bit FP (FR=1) on a system which does not support it we refuse
+ * to execute any binary which has bits specified by the following macro set
+ * in its ELF header flags.
+ */
+#ifdef CONFIG_MIPS_O32_FP64_SUPPORT
+# define __MIPS_O32_FP64_MUST_BE_ZERO  0
+#else
+# define __MIPS_O32_FP64_MUST_BE_ZERO  EF_MIPS_FP64
+#endif
+
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
@@ -191,6 +204,8 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
                __res = 0;                                              \
        if (((__h->e_flags & EF_MIPS_ABI) != 0) &&                      \
            ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32))          \
+               __res = 0;                                              \
+       if (__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO)                \
                __res = 0;                                              \
                                                                        \
        __res;                                                          \
@@ -249,6 +264,11 @@ extern struct mips_abi mips_abi_n32;
 
 #define SET_PERSONALITY(ex)                                            \
 do {                                                                   \
+       if ((ex).e_flags & EF_MIPS_FP64)                                \
+               clear_thread_flag(TIF_32BIT_FPREGS);                    \
+       else                                                            \
+               set_thread_flag(TIF_32BIT_FPREGS);                      \
+                                                                       \
        if (personality(current->personality) != PER_LINUX)             \
                set_personality(PER_LINUX);                             \
                                                                        \
@@ -271,14 +291,18 @@ do {                                                                      \
 #endif
 
 #ifdef CONFIG_MIPS32_O32
-#define __SET_PERSONALITY32_O32()                                      \
+#define __SET_PERSONALITY32_O32(ex)                                    \
        do {                                                            \
                set_thread_flag(TIF_32BIT_REGS);                        \
                set_thread_flag(TIF_32BIT_ADDR);                        \
+                                                                       \
+               if (!((ex).e_flags & EF_MIPS_FP64))                     \
+                       set_thread_flag(TIF_32BIT_FPREGS);              \
+                                                                       \
                current->thread.abi = &mips_abi_32;                     \
        } while (0)
 #else
-#define __SET_PERSONALITY32_O32()                                      \
+#define __SET_PERSONALITY32_O32(ex)                                    \
        do { } while (0)
 #endif
 
@@ -289,7 +313,7 @@ do {                                                                        \
             ((ex).e_flags & EF_MIPS_ABI) == 0)                         \
                __SET_PERSONALITY32_N32();                              \
        else                                                            \
-               __SET_PERSONALITY32_O32();                              \
+               __SET_PERSONALITY32_O32(ex);                            \
 } while (0)
 #else
 #define __SET_PERSONALITY32(ex) do { } while (0)
@@ -300,6 +324,7 @@ do {                                                                        \
        unsigned int p;                                                 \
                                                                        \
        clear_thread_flag(TIF_32BIT_REGS);                              \
+       clear_thread_flag(TIF_32BIT_FPREGS);                            \
        clear_thread_flag(TIF_32BIT_ADDR);                              \
                                                                        \
        if ((ex).e_ident[EI_CLASS] == ELFCLASS32)                       \
index d088e5d..cfe092f 100644 (file)
@@ -33,11 +33,48 @@ extern void _init_fpu(void);
 extern void _save_fp(struct task_struct *);
 extern void _restore_fp(struct task_struct *);
 
-#define __enable_fpu()                                                 \
-do {                                                                   \
-       set_c0_status(ST0_CU1);                                         \
-       enable_fpu_hazard();                                            \
-} while (0)
+/*
+ * This enum specifies a mode in which we want the FPU to operate, for cores
+ * which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT
+ * purposefully have the values 0 & 1 respectively, so that an integer value
+ * of Status.FR can be trivially casted to the corresponding enum fpu_mode.
+ */
+enum fpu_mode {
+       FPU_32BIT = 0,          /* FR = 0 */
+       FPU_64BIT,              /* FR = 1 */
+       FPU_AS_IS,
+};
+
+static inline int __enable_fpu(enum fpu_mode mode)
+{
+       int fr;
+
+       switch (mode) {
+       case FPU_AS_IS:
+               /* just enable the FPU in its current mode */
+               set_c0_status(ST0_CU1);
+               enable_fpu_hazard();
+               return 0;
+
+       case FPU_64BIT:
+#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_MIPS64))
+               /* we only have a 32-bit FPU */
+               return SIGFPE;
+#endif
+               /* fall through */
+       case FPU_32BIT:
+               /* set CU1 & change FR appropriately */
+               fr = (int)mode;
+               change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0));
+               enable_fpu_hazard();
+
+               /* check FR has the desired value */
+               return (!!(read_c0_status() & ST0_FR) == !!fr) ? 0 : SIGFPE;
+
+       default:
+               BUG();
+       }
+}
 
 #define __disable_fpu()                                                        \
 do {                                                                   \
@@ -45,19 +82,6 @@ do {                                                                 \
        disable_fpu_hazard();                                           \
 } while (0)
 
-#define enable_fpu()                                                   \
-do {                                                                   \
-       if (cpu_has_fpu)                                                \
-               __enable_fpu();                                         \
-} while (0)
-
-#define disable_fpu()                                                  \
-do {                                                                   \
-       if (cpu_has_fpu)                                                \
-               __disable_fpu();                                        \
-} while (0)
-
-
 #define clear_fpu_owner()      clear_thread_flag(TIF_USEDFPU)
 
 static inline int __is_fpu_owner(void)
@@ -70,27 +94,46 @@ static inline int is_fpu_owner(void)
        return cpu_has_fpu && __is_fpu_owner();
 }
 
-static inline void __own_fpu(void)
+static inline int __own_fpu(void)
 {
-       __enable_fpu();
+       enum fpu_mode mode;
+       int ret;
+
+       mode = !test_thread_flag(TIF_32BIT_FPREGS);
+       ret = __enable_fpu(mode);
+       if (ret)
+               return ret;
+
        KSTK_STATUS(current) |= ST0_CU1;
+       if (mode == FPU_64BIT)
+               KSTK_STATUS(current) |= ST0_FR;
+       else /* mode == FPU_32BIT */
+               KSTK_STATUS(current) &= ~ST0_FR;
+
        set_thread_flag(TIF_USEDFPU);
+       return 0;
 }
 
-static inline void own_fpu_inatomic(int restore)
+static inline int own_fpu_inatomic(int restore)
 {
+       int ret = 0;
+
        if (cpu_has_fpu && !__is_fpu_owner()) {
-               __own_fpu();
-               if (restore)
+               ret = __own_fpu();
+               if (restore && !ret)
                        _restore_fp(current);
        }
+       return ret;
 }
 
-static inline void own_fpu(int restore)
+static inline int own_fpu(int restore)
 {
+       int ret;
+
        preempt_disable();
-       own_fpu_inatomic(restore);
+       ret = own_fpu_inatomic(restore);
        preempt_enable();
+       return ret;
 }
 
 static inline void lose_fpu(int save)
@@ -106,16 +149,21 @@ static inline void lose_fpu(int save)
        preempt_enable();
 }
 
-static inline void init_fpu(void)
+static inline int init_fpu(void)
 {
+       int ret = 0;
+
        preempt_disable();
        if (cpu_has_fpu) {
-               __own_fpu();
-               _init_fpu();
+               ret = __own_fpu();
+               if (!ret)
+                       _init_fpu();
        } else {
                fpu_emulator_init_fpu();
        }
+
        preempt_enable();
+       return ret;
 }
 
 static inline void save_fp(struct task_struct *tsk)
index b0dd0c8..572e63e 100644 (file)
@@ -19,7 +19,6 @@
 
 #ifdef __KERNEL__
 
-#include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
 #include <asm/kmap_types.h>
index 3296696..a995fce 100644 (file)
@@ -391,9 +391,6 @@ struct kvm_vcpu_arch {
        uint32_t guest_kernel_asid[NR_CPUS];
        struct mm_struct guest_kernel_mm, guest_user_mm;
 
-       struct kvm_mips_tlb shadow_tlb[NR_CPUS][KVM_MIPS_GUEST_TLB_SIZE];
-
-
        struct hrtimer comparecount_timer;
 
        int last_sched_cpu;
@@ -529,7 +526,6 @@ extern enum emulation_result kvm_mips_handle_tlbmod(unsigned long cause,
 
 extern void kvm_mips_dump_host_tlbs(void);
 extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu);
-extern void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu);
 extern void kvm_mips_flush_host_tlb(int skip_kseg0);
 extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi);
 extern int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index);
@@ -541,10 +537,7 @@ extern unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu
                                                   unsigned long gva);
 extern void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
                                    struct kvm_vcpu *vcpu);
-extern void kvm_shadow_tlb_put(struct kvm_vcpu *vcpu);
-extern void kvm_shadow_tlb_load(struct kvm_vcpu *vcpu);
 extern void kvm_local_flush_tlb_all(void);
-extern void kvm_mips_init_shadow_tlb(struct kvm_vcpu *vcpu);
 extern void kvm_mips_alloc_new_mmu_context(struct kvm_vcpu *vcpu);
 extern void kvm_mips_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
 extern void kvm_mips_vcpu_put(struct kvm_vcpu *vcpu);
index b86a125..cd41e93 100644 (file)
@@ -16,7 +16,6 @@
 #define __ASM_MACH_AR71XX_REGS_H
 
 #include <linux/types.h>
-#include <linux/init.h>
 #include <linux/io.h>
 #include <linux/bitops.h>
 
index cc7563b..7527c1d 100644 (file)
@@ -56,4 +56,6 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
                                 const char *prefix);
 #endif
 
+void bcm47xx_set_system_type(u16 chip_id);
+
 #endif /* __ASM_BCM47XX_H */
index 00867dd..40005fb 100644 (file)
@@ -66,6 +66,7 @@ enum bcm47xx_board {
        BCM47XX_BOARD_LINKSYS_WRT310NV1,
        BCM47XX_BOARD_LINKSYS_WRT310NV2,
        BCM47XX_BOARD_LINKSYS_WRT54G3GV2,
+       BCM47XX_BOARD_LINKSYS_WRT54GSV1,
        BCM47XX_BOARD_LINKSYS_WRT610NV1,
        BCM47XX_BOARD_LINKSYS_WRT610NV2,
        BCM47XX_BOARD_LINKSYS_WRTSL54GS,
diff --git a/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h
new file mode 100644 (file)
index 0000000..b7992cd
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb                    1
+#define cpu_has_4kex                   1
+#define cpu_has_3k_cache               0
+#define cpu_has_4k_cache               1
+#define cpu_has_tx39_cache             0
+#define cpu_has_fpu                    0
+#define cpu_has_32fpr                  0
+#define cpu_has_counter                        1
+#if defined(CONFIG_BCM47XX_BCMA) && !defined(CONFIG_BCM47XX_SSB)
+#define cpu_has_watch                  1
+#elif defined(CONFIG_BCM47XX_SSB) && !defined(CONFIG_BCM47XX_BCMA)
+#define cpu_has_watch                  0
+#endif
+#define cpu_has_divec                  1
+#define cpu_has_vce                    0
+#define cpu_has_cache_cdex_p           0
+#define cpu_has_cache_cdex_s           0
+#define cpu_has_prefetch               1
+#define cpu_has_mcheck                 1
+#define cpu_has_ejtag                  1
+#define cpu_has_llsc                   1
+
+/* cpu_has_mips16 */
+#define cpu_has_mdmx                   0
+#define cpu_has_mips3d                 0
+#define cpu_has_rixi                   0
+#define cpu_has_mmips                  0
+#define cpu_has_smartmips              0
+#define cpu_has_vtag_icache            0
+/* cpu_has_dc_aliases */
+#define cpu_has_ic_fills_f_dc          0
+#define cpu_has_pindexed_dcache                0
+#define cpu_icache_snoops_remote_store 0
+
+#define cpu_has_mips_2                 1
+#define cpu_has_mips_3                 0
+#define cpu_has_mips32r1               1
+#if defined(CONFIG_BCM47XX_BCMA) && !defined(CONFIG_BCM47XX_SSB)
+#define cpu_has_mips32r2               1
+#elif defined(CONFIG_BCM47XX_SSB) && !defined(CONFIG_BCM47XX_BCMA)
+#define cpu_has_mips32r2               0
+#endif
+#define cpu_has_mips64r1               0
+#define cpu_has_mips64r2               0
+
+#if defined(CONFIG_BCM47XX_BCMA) && !defined(CONFIG_BCM47XX_SSB)
+#define cpu_has_dsp                    1
+#define cpu_has_dsp2                   1
+#elif defined(CONFIG_BCM47XX_SSB) && !defined(CONFIG_BCM47XX_BCMA)
+#define cpu_has_dsp                    0
+#define cpu_has_dsp2                   0
+#endif
+#define cpu_has_mipsmt                 0
+/* cpu_has_userlocal */
+
+#define cpu_has_nofpuex                        0
+#define cpu_has_64bits                 0
+#define cpu_has_64bit_zero_reg         0
+#if defined(CONFIG_BCM47XX_BCMA) && !defined(CONFIG_BCM47XX_SSB)
+#define cpu_has_vint                   1
+#elif defined(CONFIG_BCM47XX_SSB) && !defined(CONFIG_BCM47XX_BCMA)
+#define cpu_has_vint                   0
+#endif
+#define cpu_has_veic                   0
+#define cpu_has_inclusive_pcaches      0
+
+#if defined(CONFIG_BCM47XX_BCMA) && !defined(CONFIG_BCM47XX_SSB)
+#define cpu_dcache_line_size()         32
+#define cpu_icache_line_size()         32
+#define cpu_has_perf_cntr_intr_bit     1
+#elif defined(CONFIG_BCM47XX_SSB) && !defined(CONFIG_BCM47XX_BCMA)
+#define cpu_dcache_line_size()         16
+#define cpu_icache_line_size()         16
+#define cpu_has_perf_cntr_intr_bit     0
+#endif
+#define cpu_scache_line_size()         0
+#define cpu_has_vz                     0
+
+#endif /* __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H */
index 19f9134..3112f08 100644 (file)
@@ -145,6 +145,7 @@ enum bcm63xx_regs_set {
        RSET_UART1,
        RSET_GPIO,
        RSET_SPI,
+       RSET_HSSPI,
        RSET_UDC0,
        RSET_OHCI0,
        RSET_OHCI_PRIV,
@@ -193,6 +194,7 @@ enum bcm63xx_regs_set {
 #define RSET_ENETDMAS_SIZE(chans)      (16 * (chans))
 #define RSET_ENETSW_SIZE               65536
 #define RSET_UART_SIZE                 24
+#define RSET_HSSPI_SIZE                        1536
 #define RSET_UDC_SIZE                  256
 #define RSET_OHCI_SIZE                 256
 #define RSET_EHCI_SIZE                 256
@@ -265,6 +267,7 @@ enum bcm63xx_regs_set {
 #define BCM_6328_UART1_BASE            (0xb0000120)
 #define BCM_6328_GPIO_BASE             (0xb0000080)
 #define BCM_6328_SPI_BASE              (0xdeadbeef)
+#define BCM_6328_HSSPI_BASE            (0xb0001000)
 #define BCM_6328_UDC0_BASE             (0xdeadbeef)
 #define BCM_6328_USBDMA_BASE           (0xb000c000)
 #define BCM_6328_OHCI0_BASE            (0xb0002600)
@@ -313,6 +316,7 @@ enum bcm63xx_regs_set {
 #define BCM_6338_UART1_BASE            (0xdeadbeef)
 #define BCM_6338_GPIO_BASE             (0xfffe0400)
 #define BCM_6338_SPI_BASE              (0xfffe0c00)
+#define BCM_6338_HSSPI_BASE            (0xdeadbeef)
 #define BCM_6338_UDC0_BASE             (0xdeadbeef)
 #define BCM_6338_USBDMA_BASE           (0xfffe2400)
 #define BCM_6338_OHCI0_BASE            (0xdeadbeef)
@@ -360,6 +364,7 @@ enum bcm63xx_regs_set {
 #define BCM_6345_UART1_BASE            (0xdeadbeef)
 #define BCM_6345_GPIO_BASE             (0xfffe0400)
 #define BCM_6345_SPI_BASE              (0xdeadbeef)
+#define BCM_6345_HSSPI_BASE            (0xdeadbeef)
 #define BCM_6345_UDC0_BASE             (0xdeadbeef)
 #define BCM_6345_USBDMA_BASE           (0xfffe2800)
 #define BCM_6345_ENET0_BASE            (0xfffe1800)
@@ -406,6 +411,7 @@ enum bcm63xx_regs_set {
 #define BCM_6348_UART1_BASE            (0xdeadbeef)
 #define BCM_6348_GPIO_BASE             (0xfffe0400)
 #define BCM_6348_SPI_BASE              (0xfffe0c00)
+#define BCM_6348_HSSPI_BASE            (0xdeadbeef)
 #define BCM_6348_UDC0_BASE             (0xfffe1000)
 #define BCM_6348_USBDMA_BASE           (0xdeadbeef)
 #define BCM_6348_OHCI0_BASE            (0xfffe1b00)
@@ -451,6 +457,7 @@ enum bcm63xx_regs_set {
 #define BCM_6358_UART1_BASE            (0xfffe0120)
 #define BCM_6358_GPIO_BASE             (0xfffe0080)
 #define BCM_6358_SPI_BASE              (0xfffe0800)
+#define BCM_6358_HSSPI_BASE            (0xdeadbeef)
 #define BCM_6358_UDC0_BASE             (0xfffe0800)
 #define BCM_6358_USBDMA_BASE           (0xdeadbeef)
 #define BCM_6358_OHCI0_BASE            (0xfffe1400)
@@ -553,6 +560,7 @@ enum bcm63xx_regs_set {
 #define BCM_6368_UART1_BASE            (0xb0000120)
 #define BCM_6368_GPIO_BASE             (0xb0000080)
 #define BCM_6368_SPI_BASE              (0xb0000800)
+#define BCM_6368_HSSPI_BASE            (0xdeadbeef)
 #define BCM_6368_UDC0_BASE             (0xdeadbeef)
 #define BCM_6368_USBDMA_BASE           (0xb0004800)
 #define BCM_6368_OHCI0_BASE            (0xb0001600)
@@ -604,6 +612,7 @@ extern const unsigned long *bcm63xx_regs_base;
        __GEN_RSET_BASE(__cpu, UART1)                                   \
        __GEN_RSET_BASE(__cpu, GPIO)                                    \
        __GEN_RSET_BASE(__cpu, SPI)                                     \
+       __GEN_RSET_BASE(__cpu, HSSPI)                                   \
        __GEN_RSET_BASE(__cpu, UDC0)                                    \
        __GEN_RSET_BASE(__cpu, OHCI0)                                   \
        __GEN_RSET_BASE(__cpu, OHCI_PRIV)                               \
@@ -647,6 +656,7 @@ extern const unsigned long *bcm63xx_regs_base;
        [RSET_UART1]            = BCM_## __cpu ##_UART1_BASE,           \
        [RSET_GPIO]             = BCM_## __cpu ##_GPIO_BASE,            \
        [RSET_SPI]              = BCM_## __cpu ##_SPI_BASE,             \
+       [RSET_HSSPI]            = BCM_## __cpu ##_HSSPI_BASE,           \
        [RSET_UDC0]             = BCM_## __cpu ##_UDC0_BASE,            \
        [RSET_OHCI0]            = BCM_## __cpu ##_OHCI0_BASE,           \
        [RSET_OHCI_PRIV]        = BCM_## __cpu ##_OHCI_PRIV_BASE,       \
@@ -727,6 +737,7 @@ enum bcm63xx_irq {
        IRQ_ENET0,
        IRQ_ENET1,
        IRQ_ENET_PHY,
+       IRQ_HSSPI,
        IRQ_OHCI0,
        IRQ_EHCI0,
        IRQ_USBD,
@@ -815,6 +826,7 @@ enum bcm63xx_irq {
 #define BCM_6328_ENET0_IRQ             0
 #define BCM_6328_ENET1_IRQ             0
 #define BCM_6328_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 12)
+#define BCM_6328_HSSPI_IRQ             (IRQ_INTERNAL_BASE + 29)
 #define BCM_6328_OHCI0_IRQ             (BCM_6328_HIGH_IRQ_BASE + 9)
 #define BCM_6328_EHCI0_IRQ             (BCM_6328_HIGH_IRQ_BASE + 10)
 #define BCM_6328_USBD_IRQ              (IRQ_INTERNAL_BASE + 4)
@@ -860,6 +872,7 @@ enum bcm63xx_irq {
 #define BCM_6338_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
 #define BCM_6338_ENET1_IRQ             0
 #define BCM_6338_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 9)
+#define BCM_6338_HSSPI_IRQ             0
 #define BCM_6338_OHCI0_IRQ             0
 #define BCM_6338_EHCI0_IRQ             0
 #define BCM_6338_USBD_IRQ              0
@@ -898,6 +911,7 @@ enum bcm63xx_irq {
 #define BCM_6345_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
 #define BCM_6345_ENET1_IRQ             0
 #define BCM_6345_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 12)
+#define BCM_6345_HSSPI_IRQ             0
 #define BCM_6345_OHCI0_IRQ             0
 #define BCM_6345_EHCI0_IRQ             0
 #define BCM_6345_USBD_IRQ              0
@@ -936,6 +950,7 @@ enum bcm63xx_irq {
 #define BCM_6348_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
 #define BCM_6348_ENET1_IRQ             (IRQ_INTERNAL_BASE + 7)
 #define BCM_6348_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 9)
+#define BCM_6348_HSSPI_IRQ             0
 #define BCM_6348_OHCI0_IRQ             (IRQ_INTERNAL_BASE + 12)
 #define BCM_6348_EHCI0_IRQ             0
 #define BCM_6348_USBD_IRQ              0
@@ -974,6 +989,7 @@ enum bcm63xx_irq {
 #define BCM_6358_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
 #define BCM_6358_ENET1_IRQ             (IRQ_INTERNAL_BASE + 6)
 #define BCM_6358_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 9)
+#define BCM_6358_HSSPI_IRQ             0
 #define BCM_6358_OHCI0_IRQ             (IRQ_INTERNAL_BASE + 5)
 #define BCM_6358_EHCI0_IRQ             (IRQ_INTERNAL_BASE + 10)
 #define BCM_6358_USBD_IRQ              0
@@ -1086,6 +1102,7 @@ enum bcm63xx_irq {
 #define BCM_6368_ENET0_IRQ             0
 #define BCM_6368_ENET1_IRQ             0
 #define BCM_6368_ENET_PHY_IRQ          (IRQ_INTERNAL_BASE + 15)
+#define BCM_6368_HSSPI_IRQ             0
 #define BCM_6368_OHCI0_IRQ             (IRQ_INTERNAL_BASE + 5)
 #define BCM_6368_EHCI0_IRQ             (IRQ_INTERNAL_BASE + 7)
 #define BCM_6368_USBD_IRQ              (IRQ_INTERNAL_BASE + 8)
@@ -1133,6 +1150,7 @@ extern const int *bcm63xx_irqs;
        [IRQ_ENET0]             = BCM_## __cpu ##_ENET0_IRQ,            \
        [IRQ_ENET1]             = BCM_## __cpu ##_ENET1_IRQ,            \
        [IRQ_ENET_PHY]          = BCM_## __cpu ##_ENET_PHY_IRQ,         \
+       [IRQ_HSSPI]             = BCM_## __cpu ##_HSSPI_IRQ,            \
        [IRQ_OHCI0]             = BCM_## __cpu ##_OHCI0_IRQ,            \
        [IRQ_EHCI0]             = BCM_## __cpu ##_EHCI0_IRQ,            \
        [IRQ_USBD]              = BCM_## __cpu ##_USBD_IRQ,             \
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h
new file mode 100644 (file)
index 0000000..1b1acaf
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef BCM63XX_DEV_HSSPI_H
+#define BCM63XX_DEV_HSSPI_H
+
+#include <linux/types.h>
+
+int bcm63xx_hsspi_register(void);
+
+#endif /* BCM63XX_DEV_HSSPI_H */
index 9875db3..ab427f8 100644 (file)
 /* Watchdog soft reset register (BCM6328 only) */
 #define WDT_SOFTRESET_REG              0xc
 
-/*************************************************************************
- * _REG relative to RSET_UARTx
- *************************************************************************/
-
-/* UART Control Register */
-#define UART_CTL_REG                   0x0
-#define UART_CTL_RXTMOUTCNT_SHIFT      0
-#define UART_CTL_RXTMOUTCNT_MASK       (0x1f << UART_CTL_RXTMOUTCNT_SHIFT)
-#define UART_CTL_RSTTXDN_SHIFT         5
-#define UART_CTL_RSTTXDN_MASK          (1 << UART_CTL_RSTTXDN_SHIFT)
-#define UART_CTL_RSTRXFIFO_SHIFT               6
-#define UART_CTL_RSTRXFIFO_MASK                (1 << UART_CTL_RSTRXFIFO_SHIFT)
-#define UART_CTL_RSTTXFIFO_SHIFT               7
-#define UART_CTL_RSTTXFIFO_MASK                (1 << UART_CTL_RSTTXFIFO_SHIFT)
-#define UART_CTL_STOPBITS_SHIFT                8
-#define UART_CTL_STOPBITS_MASK         (0xf << UART_CTL_STOPBITS_SHIFT)
-#define UART_CTL_STOPBITS_1            (0x7 << UART_CTL_STOPBITS_SHIFT)
-#define UART_CTL_STOPBITS_2            (0xf << UART_CTL_STOPBITS_SHIFT)
-#define UART_CTL_BITSPERSYM_SHIFT      12
-#define UART_CTL_BITSPERSYM_MASK       (0x3 << UART_CTL_BITSPERSYM_SHIFT)
-#define UART_CTL_XMITBRK_SHIFT         14
-#define UART_CTL_XMITBRK_MASK          (1 << UART_CTL_XMITBRK_SHIFT)
-#define UART_CTL_RSVD_SHIFT            15
-#define UART_CTL_RSVD_MASK             (1 << UART_CTL_RSVD_SHIFT)
-#define UART_CTL_RXPAREVEN_SHIFT               16
-#define UART_CTL_RXPAREVEN_MASK                (1 << UART_CTL_RXPAREVEN_SHIFT)
-#define UART_CTL_RXPAREN_SHIFT         17
-#define UART_CTL_RXPAREN_MASK          (1 << UART_CTL_RXPAREN_SHIFT)
-#define UART_CTL_TXPAREVEN_SHIFT               18
-#define UART_CTL_TXPAREVEN_MASK                (1 << UART_CTL_TXPAREVEN_SHIFT)
-#define UART_CTL_TXPAREN_SHIFT         18
-#define UART_CTL_TXPAREN_MASK          (1 << UART_CTL_TXPAREN_SHIFT)
-#define UART_CTL_LOOPBACK_SHIFT                20
-#define UART_CTL_LOOPBACK_MASK         (1 << UART_CTL_LOOPBACK_SHIFT)
-#define UART_CTL_RXEN_SHIFT            21
-#define UART_CTL_RXEN_MASK             (1 << UART_CTL_RXEN_SHIFT)
-#define UART_CTL_TXEN_SHIFT            22
-#define UART_CTL_TXEN_MASK             (1 << UART_CTL_TXEN_SHIFT)
-#define UART_CTL_BRGEN_SHIFT           23
-#define UART_CTL_BRGEN_MASK            (1 << UART_CTL_BRGEN_SHIFT)
-
-/* UART Baudword register */
-#define UART_BAUD_REG                  0x4
-
-/* UART Misc Control register */
-#define UART_MCTL_REG                  0x8
-#define UART_MCTL_DTR_SHIFT            0
-#define UART_MCTL_DTR_MASK             (1 << UART_MCTL_DTR_SHIFT)
-#define UART_MCTL_RTS_SHIFT            1
-#define UART_MCTL_RTS_MASK             (1 << UART_MCTL_RTS_SHIFT)
-#define UART_MCTL_RXFIFOTHRESH_SHIFT   8
-#define UART_MCTL_RXFIFOTHRESH_MASK    (0xf << UART_MCTL_RXFIFOTHRESH_SHIFT)
-#define UART_MCTL_TXFIFOTHRESH_SHIFT   12
-#define UART_MCTL_TXFIFOTHRESH_MASK    (0xf << UART_MCTL_TXFIFOTHRESH_SHIFT)
-#define UART_MCTL_RXFIFOFILL_SHIFT     16
-#define UART_MCTL_RXFIFOFILL_MASK      (0x1f << UART_MCTL_RXFIFOFILL_SHIFT)
-#define UART_MCTL_TXFIFOFILL_SHIFT     24
-#define UART_MCTL_TXFIFOFILL_MASK      (0x1f << UART_MCTL_TXFIFOFILL_SHIFT)
-
-/* UART External Input Configuration register */
-#define UART_EXTINP_REG                        0xc
-#define UART_EXTINP_RI_SHIFT           0
-#define UART_EXTINP_RI_MASK            (1 << UART_EXTINP_RI_SHIFT)
-#define UART_EXTINP_CTS_SHIFT          1
-#define UART_EXTINP_CTS_MASK           (1 << UART_EXTINP_CTS_SHIFT)
-#define UART_EXTINP_DCD_SHIFT          2
-#define UART_EXTINP_DCD_MASK           (1 << UART_EXTINP_DCD_SHIFT)
-#define UART_EXTINP_DSR_SHIFT          3
-#define UART_EXTINP_DSR_MASK           (1 << UART_EXTINP_DSR_SHIFT)
-#define UART_EXTINP_IRSTAT(x)          (1 << (x + 4))
-#define UART_EXTINP_IRMASK(x)          (1 << (x + 8))
-#define UART_EXTINP_IR_RI              0
-#define UART_EXTINP_IR_CTS             1
-#define UART_EXTINP_IR_DCD             2
-#define UART_EXTINP_IR_DSR             3
-#define UART_EXTINP_RI_NOSENSE_SHIFT   16
-#define UART_EXTINP_RI_NOSENSE_MASK    (1 << UART_EXTINP_RI_NOSENSE_SHIFT)
-#define UART_EXTINP_CTS_NOSENSE_SHIFT  17
-#define UART_EXTINP_CTS_NOSENSE_MASK   (1 << UART_EXTINP_CTS_NOSENSE_SHIFT)
-#define UART_EXTINP_DCD_NOSENSE_SHIFT  18
-#define UART_EXTINP_DCD_NOSENSE_MASK   (1 << UART_EXTINP_DCD_NOSENSE_SHIFT)
-#define UART_EXTINP_DSR_NOSENSE_SHIFT  19
-#define UART_EXTINP_DSR_NOSENSE_MASK   (1 << UART_EXTINP_DSR_NOSENSE_SHIFT)
-
-/* UART Interrupt register */
-#define UART_IR_REG                    0x10
-#define UART_IR_MASK(x)                        (1 << (x + 16))
-#define UART_IR_STAT(x)                        (1 << (x))
-#define UART_IR_EXTIP                  0
-#define UART_IR_TXUNDER                        1
-#define UART_IR_TXOVER                 2
-#define UART_IR_TXTRESH                        3
-#define UART_IR_TXRDLATCH              4
-#define UART_IR_TXEMPTY                        5
-#define UART_IR_RXUNDER                        6
-#define UART_IR_RXOVER                 7
-#define UART_IR_RXTIMEOUT              8
-#define UART_IR_RXFULL                 9
-#define UART_IR_RXTHRESH               10
-#define UART_IR_RXNOTEMPTY             11
-#define UART_IR_RXFRAMEERR             12
-#define UART_IR_RXPARERR               13
-#define UART_IR_RXBRK                  14
-#define UART_IR_TXDONE                 15
-
-/* UART Fifo register */
-#define UART_FIFO_REG                  0x14
-#define UART_FIFO_VALID_SHIFT          0
-#define UART_FIFO_VALID_MASK           0xff
-#define UART_FIFO_FRAMEERR_SHIFT       8
-#define UART_FIFO_FRAMEERR_MASK                (1 << UART_FIFO_FRAMEERR_SHIFT)
-#define UART_FIFO_PARERR_SHIFT         9
-#define UART_FIFO_PARERR_MASK          (1 << UART_FIFO_PARERR_SHIFT)
-#define UART_FIFO_BRKDET_SHIFT         10
-#define UART_FIFO_BRKDET_MASK          (1 << UART_FIFO_BRKDET_SHIFT)
-#define UART_FIFO_ANYERR_MASK          (UART_FIFO_FRAMEERR_MASK |      \
-                                       UART_FIFO_PARERR_MASK |         \
-                                       UART_FIFO_BRKDET_MASK)
-
-
 /*************************************************************************
  * _REG relative to RSET_GPIO
  *************************************************************************/
index a9e8f6b..7629c35 100644 (file)
@@ -49,11 +49,7 @@ static inline int plat_dma_supported(struct device *dev, u64 mask)
 
 static inline int plat_device_is_coherent(struct device *dev)
 {
-#ifdef CONFIG_DMA_COHERENT
-       return 1;
-#else
        return coherentio;
-#endif
 }
 
 #ifdef CONFIG_SWIOTLB
index 5b5cd68..e2561d9 100644 (file)
@@ -9,7 +9,6 @@
 #define __ASM_MACH_GENERIC_FLOPPY_H
 
 #include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/linkage.h>
index affa66f..4ae5fbc 100644 (file)
@@ -23,7 +23,7 @@
 static inline void __ide_flush_prologue(void)
 {
 #ifdef CONFIG_SMP
-       if (cpu_has_dc_aliases)
+       if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc)
                preempt_disable();
 #endif
 }
@@ -31,14 +31,14 @@ static inline void __ide_flush_prologue(void)
 static inline void __ide_flush_epilogue(void)
 {
 #ifdef CONFIG_SMP
-       if (cpu_has_dc_aliases)
+       if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc)
                preempt_enable();
 #endif
 }
 
 static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size)
 {
-       if (cpu_has_dc_aliases) {
+       if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) {
                unsigned long end = addr + size;
 
                while (addr < end) {
index 62aa1e2..4b86c88 100644 (file)
@@ -9,7 +9,6 @@
 #define __ASM_MACH_JAZZ_FLOPPY_H
 
 #include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/linkage.h>
 #include <linux/types.h>
 #include <linux/mm.h>
index 05988c2..069b43a 100644 (file)
@@ -21,6 +21,7 @@
 
 extern struct platform_device jz4740_usb_ohci_device;
 extern struct platform_device jz4740_udc_device;
+extern struct platform_device jz4740_udc_xceiv_device;
 extern struct platform_device jz4740_mmc_device;
 extern struct platform_device jz4740_rtc_device;
 extern struct platform_device jz4740_i2c_device;
index 868ed8a..c0dbd53 100644 (file)
@@ -9,7 +9,8 @@
 #define __ASM_NETLOGIC_IRQ_H
 
 #include <asm/mach-netlogic/multi-node.h>
-#define NR_IRQS                        (64 * NLM_NR_NODES)
+#define NLM_IRQS_PER_NODE      1024
+#define NR_IRQS                        (NLM_IRQS_PER_NODE * NLM_NR_NODES)
 
 #define MIPS_CPU_IRQ_BASE      0
 
index d62fc77..9ed8dac 100644 (file)
 #endif
 #endif
 
-#define NLM_CORES_PER_NODE     8
 #define NLM_THREADS_PER_CORE   4
-#define NLM_CPUS_PER_NODE      (NLM_CORES_PER_NODE * NLM_THREADS_PER_CORE)
+#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 */
+       unsigned long   ebase;          /* not used now */
+       uint64_t        irqmask;        /* EIMR for the node */
+       uint64_t        sysbase;        /* only for XLP - sys block base */
+       uint64_t        picbase;        /* PIC block base */
+       spinlock_t      piclock;        /* lock for PIC access */
+       cpumask_t       cpumask;        /* logical cpu mask for node */
+       unsigned int    socbus;
+};
+
+extern struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
+#define nlm_get_node(i)                (&nlm_nodes[i])
+#define nlm_node_present(n)    ((n) >= 0 && (n) < NLM_NR_NODES && \
+                                       nlm_get_node(n)->coremask != 0)
+#ifdef CONFIG_CPU_XLR
+#define nlm_current_node()     (&nlm_nodes[0])
+#else
+#define nlm_current_node()     (&nlm_nodes[nlm_nodeid()])
+#endif
+void nlm_node_init(int node);
 
 #endif
diff --git a/arch/mips/include/asm/mach-netlogic/topology.h b/arch/mips/include/asm/mach-netlogic/topology.h
new file mode 100644 (file)
index 0000000..0da99fa
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Broadcom Corporation
+ */
+#ifndef _ASM_MACH_NETLOGIC_TOPOLOGY_H
+#define _ASM_MACH_NETLOGIC_TOPOLOGY_H
+
+#include <asm/mach-netlogic/multi-node.h>
+
+#define topology_physical_package_id(cpu)      cpu_to_node(cpu)
+#define topology_core_id(cpu)  (cpu_logical_map(cpu) / NLM_THREADS_PER_CORE)
+#define topology_thread_cpumask(cpu)           (&cpu_sibling_map[cpu])
+#define topology_core_cpumask(cpu)     cpumask_of_node(cpu_to_node(cpu))
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_MACH_NETLOGIC_TOPOLOGY_H */
index e332279..836e2ed 100644 (file)
 #define   PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_DISABLE       (1 << 7)
 #define   PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MASK          0xf
 #define   PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MAX           16
+/* SERIRQ Control */
+#define PIIX4_FUNC0_SERIRQC                    0x64
+#define   PIIX4_FUNC0_SERIRQC_EN                       (1 << 7)
+#define   PIIX4_FUNC0_SERIRQC_CONT                     (1 << 6)
 /* Top Of Memory */
 #define PIIX4_FUNC0_TOM                                0x69
 #define   PIIX4_FUNC0_TOM_TOP_OF_MEMORY_MASK           0xf0
@@ -34,6 +38,9 @@
 #define   PIIX4_FUNC0_DLC_USBPR_EN                     (1 << 2)
 #define   PIIX4_FUNC0_DLC_PASSIVE_RELEASE_EN           (1 << 1)
 #define   PIIX4_FUNC0_DLC_DELAYED_TRANSACTION_EN       (1 << 0)
+/* General Configuration */
+#define PIIX4_FUNC0_GENCFG                     0xb0
+#define   PIIX4_FUNC0_GENCFG_SERIRQ                    (1 << 16)
 
 /* IDE Timing */
 #define PIIX4_FUNC1_IDETIM_PRIMARY_LO          0x40
index e033141..bbc3dd4 100644 (file)
@@ -14,6 +14,7 @@
 #define _ASM_MIPSREGS_H
 
 #include <linux/linkage.h>
+#include <linux/types.h>
 #include <asm/hazards.h>
 #include <asm/war.h>
 
 #define MIPS_CONF1_IA          (_ULCAST_(7) << 16)
 #define MIPS_CONF1_IL          (_ULCAST_(7) << 19)
 #define MIPS_CONF1_IS          (_ULCAST_(7) << 22)
-#define MIPS_CONF1_TLBS                (_ULCAST_(63)<< 25)
+#define MIPS_CONF1_TLBS_SHIFT   (25)
+#define MIPS_CONF1_TLBS_SIZE    (6)
+#define MIPS_CONF1_TLBS         (_ULCAST_(63) << MIPS_CONF1_TLBS_SHIFT)
 
 #define MIPS_CONF2_SA          (_ULCAST_(15)<<  0)
 #define MIPS_CONF2_SL          (_ULCAST_(15)<<  4)
 #define MIPS_CONF3_TL          (_ULCAST_(1) <<  0)
 #define MIPS_CONF3_SM          (_ULCAST_(1) <<  1)
 #define MIPS_CONF3_MT          (_ULCAST_(1) <<  2)
+#define MIPS_CONF3_CDMM                (_ULCAST_(1) <<  3)
 #define MIPS_CONF3_SP          (_ULCAST_(1) <<  4)
 #define MIPS_CONF3_VINT                (_ULCAST_(1) <<  5)
 #define MIPS_CONF3_VEIC                (_ULCAST_(1) <<  6)
 #define MIPS_CONF3_LPA         (_ULCAST_(1) <<  7)
+#define MIPS_CONF3_ITL         (_ULCAST_(1) <<  8)
+#define MIPS_CONF3_CTXTC       (_ULCAST_(1) <<  9)
 #define MIPS_CONF3_DSP         (_ULCAST_(1) << 10)
 #define MIPS_CONF3_DSP2P       (_ULCAST_(1) << 11)
 #define MIPS_CONF3_RXI         (_ULCAST_(1) << 12)
 #define MIPS_CONF3_ULRI                (_ULCAST_(1) << 13)
 #define MIPS_CONF3_ISA         (_ULCAST_(3) << 14)
 #define MIPS_CONF3_ISA_OE      (_ULCAST_(1) << 16)
+#define MIPS_CONF3_MCU         (_ULCAST_(1) << 17)
+#define MIPS_CONF3_MMAR                (_ULCAST_(7) << 18)
+#define MIPS_CONF3_IPLW                (_ULCAST_(3) << 21)
 #define MIPS_CONF3_VZ          (_ULCAST_(1) << 23)
-
+#define MIPS_CONF3_PW          (_ULCAST_(1) << 24)
+#define MIPS_CONF3_SC          (_ULCAST_(1) << 25)
+#define MIPS_CONF3_BI          (_ULCAST_(1) << 26)
+#define MIPS_CONF3_BP          (_ULCAST_(1) << 27)
+#define MIPS_CONF3_MSA         (_ULCAST_(1) << 28)
+#define MIPS_CONF3_CMGCR       (_ULCAST_(1) << 29)
+#define MIPS_CONF3_BPG         (_ULCAST_(1) << 30)
+
+#define MIPS_CONF4_MMUSIZEEXT_SHIFT    (0)
 #define MIPS_CONF4_MMUSIZEEXT  (_ULCAST_(255) << 0)
+#define MIPS_CONF4_FTLBSETS_SHIFT      (0)
+#define MIPS_CONF4_FTLBSETS_SHIFT      (0)
+#define MIPS_CONF4_FTLBSETS    (_ULCAST_(15) << MIPS_CONF4_FTLBSETS_SHIFT)
+#define MIPS_CONF4_FTLBWAYS_SHIFT      (4)
+#define MIPS_CONF4_FTLBWAYS    (_ULCAST_(15) << MIPS_CONF4_FTLBWAYS_SHIFT)
+#define MIPS_CONF4_FTLBPAGESIZE_SHIFT  (8)
+/* bits 10:8 in FTLB-only configurations */
+#define MIPS_CONF4_FTLBPAGESIZE (_ULCAST_(7) << MIPS_CONF4_FTLBPAGESIZE_SHIFT)
+/* bits 12:8 in VTLB-FTLB only configurations */
+#define MIPS_CONF4_VFTLBPAGESIZE (_ULCAST_(31) << MIPS_CONF4_FTLBPAGESIZE_SHIFT)
 #define MIPS_CONF4_MMUEXTDEF   (_ULCAST_(3) << 14)
 #define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14)
+#define MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT       (_ULCAST_(2) << 14)
+#define MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT       (_ULCAST_(3) << 14)
+#define MIPS_CONF4_KSCREXIST   (_ULCAST_(255) << 16)
+#define MIPS_CONF4_VTLBSIZEEXT_SHIFT   (24)
+#define MIPS_CONF4_VTLBSIZEEXT (_ULCAST_(15) << MIPS_CONF4_VTLBSIZEEXT_SHIFT)
+#define MIPS_CONF4_AE          (_ULCAST_(1) << 28)
+#define MIPS_CONF4_IE          (_ULCAST_(3) << 29)
+#define MIPS_CONF4_TLBINV      (_ULCAST_(2) << 29)
 
 #define MIPS_CONF5_NF          (_ULCAST_(1) << 0)
 #define MIPS_CONF5_UFR         (_ULCAST_(1) << 2)
 #define MIPS_CONF5_K           (_ULCAST_(1) << 30)
 
 #define MIPS_CONF6_SYND                (_ULCAST_(1) << 13)
+/* proAptiv FTLB on/off bit */
+#define MIPS_CONF6_FTLBEN      (_ULCAST_(1) << 15)
 
 #define MIPS_CONF7_WII         (_ULCAST_(1) << 31)
 
 #define MIPS_CONF7_RPS         (_ULCAST_(1) << 2)
 
+/*  EntryHI bit definition */
+#define MIPS_ENTRYHI_EHINV     (_ULCAST_(1) << 10)
 
 /*
  * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
 #define MIPS_FPIR_L            (_ULCAST_(1) << 21)
 #define MIPS_FPIR_F64          (_ULCAST_(1) << 22)
 
+/*
+ * Bits in the MIPS32 Memory Segmentation registers.
+ */
+#define MIPS_SEGCFG_PA_SHIFT   9
+#define MIPS_SEGCFG_PA         (_ULCAST_(127) << MIPS_SEGCFG_PA_SHIFT)
+#define MIPS_SEGCFG_AM_SHIFT   4
+#define MIPS_SEGCFG_AM         (_ULCAST_(7) << MIPS_SEGCFG_AM_SHIFT)
+#define MIPS_SEGCFG_EU_SHIFT   3
+#define MIPS_SEGCFG_EU         (_ULCAST_(1) << MIPS_SEGCFG_EU_SHIFT)
+#define MIPS_SEGCFG_C_SHIFT    0
+#define MIPS_SEGCFG_C          (_ULCAST_(7) << MIPS_SEGCFG_C_SHIFT)
+
+#define MIPS_SEGCFG_UUSK       _ULCAST_(7)
+#define MIPS_SEGCFG_USK                _ULCAST_(5)
+#define MIPS_SEGCFG_MUSUK      _ULCAST_(4)
+#define MIPS_SEGCFG_MUSK       _ULCAST_(3)
+#define MIPS_SEGCFG_MSK                _ULCAST_(2)
+#define MIPS_SEGCFG_MK         _ULCAST_(1)
+#define MIPS_SEGCFG_UK         _ULCAST_(0)
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -648,6 +707,19 @@ static inline int mm_insn_16bit(u16 insn)
        return (opcode >= 1 && opcode <= 3) ? 1 : 0;
 }
 
+/*
+ * TLB Invalidate Flush
+ */
+static inline void tlbinvf(void)
+{
+       __asm__ __volatile__(
+               ".set push\n\t"
+               ".set noreorder\n\t"
+               ".word 0x42000004\n\t" /* tlbinvf */
+               ".set pop");
+}
+
+
 /*
  * Functions to access the R10000 performance counters.         These are basically
  * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
@@ -1102,6 +1174,15 @@ do {                                                                     \
 #define read_c0_ebase()                __read_32bit_c0_register($15, 1)
 #define write_c0_ebase(val)    __write_32bit_c0_register($15, 1, val)
 
+/* MIPSR3 */
+#define read_c0_segctl0()      __read_32bit_c0_register($5, 2)
+#define write_c0_segctl0(val)  __write_32bit_c0_register($5, 2, val)
+
+#define read_c0_segctl1()      __read_32bit_c0_register($5, 3)
+#define write_c0_segctl1(val)  __write_32bit_c0_register($5, 3, val)
+
+#define read_c0_segctl2()      __read_32bit_c0_register($5, 4)
+#define write_c0_segctl2(val)  __write_32bit_c0_register($5, 4, val)
 
 /* Cavium OCTEON (cnMIPS) */
 #define read_c0_cvmcount()     __read_ulong_c0_register($9, 6)
index bb68c33..c281f03 100644 (file)
@@ -84,7 +84,6 @@ nlm_set_nmi_handler(void *handler)
  */
 void nlm_init_boot_cpu(void);
 unsigned int nlm_get_cpu_frequency(void);
-void nlm_node_init(int node);
 extern struct plat_smp_ops nlm_smp_ops;
 extern char nlm_reset_entry[], nlm_reset_entry_end[];
 
@@ -94,26 +93,16 @@ extern struct dma_map_ops nlm_swiotlb_dma_ops;
 extern unsigned int nlm_threads_per_core;
 extern cpumask_t nlm_cpumask;
 
-struct nlm_soc_info {
-       unsigned long coremask; /* cores enabled on the soc */
-       unsigned long ebase;
-       uint64_t irqmask;
-       uint64_t sysbase;       /* only for XLP */
-       uint64_t picbase;
-       spinlock_t piclock;
-};
-
-#define nlm_get_node(i)                (&nlm_nodes[i])
-#ifdef CONFIG_CPU_XLR
-#define nlm_current_node()     (&nlm_nodes[0])
-#else
-#define nlm_current_node()     (&nlm_nodes[nlm_nodeid()])
-#endif
-
 struct irq_data;
 uint64_t nlm_pci_irqmask(int node);
+void nlm_setup_pic_irq(int node, int picirq, int irq, int irt);
 void nlm_set_pic_extra_ack(int node, int irq,  void (*xack)(struct irq_data *));
 
+#ifdef CONFIG_PCI_MSI
+void nlm_dispatch_msi(int node, int lirq);
+void nlm_dispatch_msix(int node, int msixirq);
+#endif
+
 /*
  * The NR_IRQs is divided between nodes, each of them has a separate irq space
  */
@@ -122,7 +111,6 @@ static inline int nlm_irq_to_xirq(int node, int irq)
        return node * NR_IRQS / NLM_NR_NODES + irq;
 }
 
-extern struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
 extern int nlm_cpu_ready[];
 #endif
 #endif /* _NETLOGIC_COMMON_H_ */
index f299d31..de9aada 100644 (file)
@@ -146,7 +146,12 @@ static inline int hard_smp_processor_id(void)
 
 static inline int nlm_nodeid(void)
 {
-       return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
+       uint32_t prid = read_c0_prid();
+
+       if ((prid & 0xff00) == PRID_IMP_NETLOGIC_XLP9XX)
+               return (__read_32bit_c0_register($15, 1) >> 7) & 0x7;
+       else
+               return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
 }
 
 static inline unsigned int nlm_core_id(void)
index 4e8eacb..3067f98 100644 (file)
 #define BRIDGE_FLASH_LIMIT3            0x13
 
 #define BRIDGE_DRAM_BAR(i)             (0x14 + (i))
-#define BRIDGE_DRAM_BAR0               0x14
-#define BRIDGE_DRAM_BAR1               0x15
-#define BRIDGE_DRAM_BAR2               0x16
-#define BRIDGE_DRAM_BAR3               0x17
-#define BRIDGE_DRAM_BAR4               0x18
-#define BRIDGE_DRAM_BAR5               0x19
-#define BRIDGE_DRAM_BAR6               0x1a
-#define BRIDGE_DRAM_BAR7               0x1b
-
 #define BRIDGE_DRAM_LIMIT(i)           (0x1c + (i))
-#define BRIDGE_DRAM_LIMIT0             0x1c
-#define BRIDGE_DRAM_LIMIT1             0x1d
-#define BRIDGE_DRAM_LIMIT2             0x1e
-#define BRIDGE_DRAM_LIMIT3             0x1f
-#define BRIDGE_DRAM_LIMIT4             0x20
-#define BRIDGE_DRAM_LIMIT5             0x21
-#define BRIDGE_DRAM_LIMIT6             0x22
-#define BRIDGE_DRAM_LIMIT7             0x23
-
 #define BRIDGE_DRAM_NODE_TRANSLN(i)    (0x24 + (i))
-#define BRIDGE_DRAM_NODE_TRANSLN0      0x24
-#define BRIDGE_DRAM_NODE_TRANSLN1      0x25
-#define BRIDGE_DRAM_NODE_TRANSLN2      0x26
-#define BRIDGE_DRAM_NODE_TRANSLN3      0x27
-#define BRIDGE_DRAM_NODE_TRANSLN4      0x28
-#define BRIDGE_DRAM_NODE_TRANSLN5      0x29
-#define BRIDGE_DRAM_NODE_TRANSLN6      0x2a
-#define BRIDGE_DRAM_NODE_TRANSLN7      0x2b
-
 #define BRIDGE_DRAM_CHNL_TRANSLN(i)    (0x2c + (i))
-#define BRIDGE_DRAM_CHNL_TRANSLN0      0x2c
-#define BRIDGE_DRAM_CHNL_TRANSLN1      0x2d
-#define BRIDGE_DRAM_CHNL_TRANSLN2      0x2e
-#define BRIDGE_DRAM_CHNL_TRANSLN3      0x2f
-#define BRIDGE_DRAM_CHNL_TRANSLN4      0x30
-#define BRIDGE_DRAM_CHNL_TRANSLN5      0x31
-#define BRIDGE_DRAM_CHNL_TRANSLN6      0x32
-#define BRIDGE_DRAM_CHNL_TRANSLN7      0x33
 
 #define BRIDGE_PCIEMEM_BASE0           0x34
 #define BRIDGE_PCIEMEM_BASE1           0x35
 #define BRIDGE_GIO_WEIGHT              0x2cb
 #define BRIDGE_FLASH_WEIGHT            0x2cc
 
+/* FIXME verify */
+#define BRIDGE_9XX_FLASH_BAR(i)                (0x11 + (i))
+#define BRIDGE_9XX_FLASH_BAR_LIMIT(i)  (0x15 + (i))
+
+#define BRIDGE_9XX_DRAM_BAR(i)         (0x19 + (i))
+#define BRIDGE_9XX_DRAM_LIMIT(i)       (0x29 + (i))
+#define BRIDGE_9XX_DRAM_NODE_TRANSLN(i)        (0x39 + (i))
+#define BRIDGE_9XX_DRAM_CHNL_TRANSLN(i)        (0x49 + (i))
+
+#define BRIDGE_9XX_ADDRESS_ERROR0      0x9d
+#define BRIDGE_9XX_ADDRESS_ERROR1      0x9e
+#define BRIDGE_9XX_ADDRESS_ERROR2      0x9f
+
+#define BRIDGE_9XX_PCIEMEM_BASE0       0x59
+#define BRIDGE_9XX_PCIEMEM_BASE1       0x5a
+#define BRIDGE_9XX_PCIEMEM_BASE2       0x5b
+#define BRIDGE_9XX_PCIEMEM_BASE3       0x5c
+#define BRIDGE_9XX_PCIEMEM_LIMIT0      0x5d
+#define BRIDGE_9XX_PCIEMEM_LIMIT1      0x5e
+#define BRIDGE_9XX_PCIEMEM_LIMIT2      0x5f
+#define BRIDGE_9XX_PCIEMEM_LIMIT3      0x60
+#define BRIDGE_9XX_PCIEIO_BASE0                0x61
+#define BRIDGE_9XX_PCIEIO_BASE1                0x62
+#define BRIDGE_9XX_PCIEIO_BASE2                0x63
+#define BRIDGE_9XX_PCIEIO_BASE3                0x64
+#define BRIDGE_9XX_PCIEIO_LIMIT0       0x65
+#define BRIDGE_9XX_PCIEIO_LIMIT1       0x66
+#define BRIDGE_9XX_PCIEIO_LIMIT2       0x67
+#define BRIDGE_9XX_PCIEIO_LIMIT3       0x68
+
 #ifndef __ASSEMBLY__
 
 #define nlm_read_bridge_reg(b, r)      nlm_read_reg(b, r)
 #define nlm_write_bridge_reg(b, r, v)  nlm_write_reg(b, r, v)
-#define nlm_get_bridge_pcibase(node)   \
-                       nlm_pcicfg_base(XLP_IO_BRIDGE_OFFSET(node))
+#define nlm_get_bridge_pcibase(node)   nlm_pcicfg_base(cpu_is_xlp9xx() ? \
+               XLP9XX_IO_BRIDGE_OFFSET(node) : XLP_IO_BRIDGE_OFFSET(node))
 #define nlm_get_bridge_regbase(node)   \
                        (nlm_get_bridge_pcibase(node) + XLP_IO_PCI_HDRSZ)
 
index 55eee77..1f23dfa 100644 (file)
 #define XLP_IO_SIZE                    (64 << 20)      /* ECFG space size */
 #define XLP_IO_PCI_HDRSZ               0x100
 #define XLP_IO_DEV(node, dev)          ((dev) + (node) * 8)
-#define XLP_HDR_OFFSET(node, bus, dev, fn)     (((bus) << 20) | \
-                               ((XLP_IO_DEV(node, dev)) << 15) | ((fn) << 12))
+#define XLP_IO_PCI_OFFSET(b, d, f)     (((b) << 20) | ((d) << 15) | ((f) << 12))
+
+#define XLP_HDR_OFFSET(node, bus, dev, fn) \
+               XLP_IO_PCI_OFFSET(bus, XLP_IO_DEV(node, dev), fn)
 
 #define XLP_IO_BRIDGE_OFFSET(node)     XLP_HDR_OFFSET(node, 0, 0, 0)
 /* coherent inter chip */
 #define XLP_IO_MMC_OFFSET(node, slot)  \
                ((XLP_IO_SD_OFFSET(node))+(slot*0x100)+XLP_IO_PCI_HDRSZ)
 
+/* Things have changed drastically in XLP 9XX */
+#define XLP9XX_HDR_OFFSET(n, d, f)     \
+                       XLP_IO_PCI_OFFSET(xlp9xx_get_socbus(n), d, f)
+
+#define XLP9XX_IO_BRIDGE_OFFSET(node)  XLP_IO_PCI_OFFSET(0, 0, node)
+#define XLP9XX_IO_PIC_OFFSET(node)     XLP9XX_HDR_OFFSET(node, 2, 0)
+#define XLP9XX_IO_UART_OFFSET(node)    XLP9XX_HDR_OFFSET(node, 2, 2)
+#define XLP9XX_IO_SYS_OFFSET(node)     XLP9XX_HDR_OFFSET(node, 6, 0)
+#define XLP9XX_IO_FUSE_OFFSET(node)    XLP9XX_HDR_OFFSET(node, 6, 1)
+#define XLP9XX_IO_JTAG_OFFSET(node)    XLP9XX_HDR_OFFSET(node, 6, 4)
+
+#define XLP9XX_IO_PCIE_OFFSET(node, i) XLP9XX_HDR_OFFSET(node, 1, i)
+#define XLP9XX_IO_PCIE0_OFFSET(node)   XLP9XX_HDR_OFFSET(node, 1, 0)
+#define XLP9XX_IO_PCIE2_OFFSET(node)   XLP9XX_HDR_OFFSET(node, 1, 2)
+#define XLP9XX_IO_PCIE3_OFFSET(node)   XLP9XX_HDR_OFFSET(node, 1, 3)
+
+/* XLP9xx USB block */
+#define XLP9XX_IO_USB_OFFSET(node, i)          XLP9XX_HDR_OFFSET(node, 4, i)
+#define XLP9XX_IO_USB_XHCI0_OFFSET(node)       XLP9XX_HDR_OFFSET(node, 4, 1)
+#define XLP9XX_IO_USB_XHCI1_OFFSET(node)       XLP9XX_HDR_OFFSET(node, 4, 2)
+
+/* XLP9XX on-chip SATA controller */
+#define XLP9XX_IO_SATA_OFFSET(node)            XLP9XX_HDR_OFFSET(node, 3, 2)
+
+#define XLP9XX_IO_NOR_OFFSET(node)             XLP9XX_HDR_OFFSET(node, 7, 0)
+#define XLP9XX_IO_NAND_OFFSET(node)            XLP9XX_HDR_OFFSET(node, 7, 1)
+#define XLP9XX_IO_SPI_OFFSET(node)             XLP9XX_HDR_OFFSET(node, 7, 2)
+/* SD flash */
+#define XLP9XX_IO_MMCSD_OFFSET(node)           XLP9XX_HDR_OFFSET(node, 7, 3)
+
 /* PCI config header register id's */
 #define XLP_PCI_CFGREG0                        0x00
 #define XLP_PCI_CFGREG1                        0x01
 #define PCI_DEVICE_ID_NLM_MMC          0x1018
 #define PCI_DEVICE_ID_NLM_XHCI         0x101d
 
+#define PCI_DEVICE_ID_XLP9XX_SATA      0x901A
+#define PCI_DEVICE_ID_XLP9XX_XHCI      0x901D
+
 #ifndef __ASSEMBLY__
 
 #define nlm_read_pci_reg(b, r)         nlm_read_reg(b, r)
 #define nlm_write_pci_reg(b, r, v)     nlm_write_reg(b, r, v)
 
+static inline int xlp9xx_get_socbus(int node)
+{
+       uint64_t socbridge;
+
+       if (node == 0)
+               return 1;
+       socbridge = nlm_pcicfg_base(XLP9XX_IO_BRIDGE_OFFSET(node));
+       return (nlm_read_pci_reg(socbridge, 0x6) >> 8) & 0xff;
+}
 #endif /* !__ASSEMBLY */
 
 #endif /* __NLM_HAL_IOMAP_H__ */
index b559cb9..d4deb87 100644 (file)
 #define PCIE_BYTE_SWAP_MEM_LIM         0x248
 #define PCIE_BYTE_SWAP_IO_BASE         0x249
 #define PCIE_BYTE_SWAP_IO_LIM          0x24A
+
+#define PCIE_BRIDGE_MSIX_ADDR_BASE     0x24F
+#define PCIE_BRIDGE_MSIX_ADDR_LIMIT    0x250
 #define PCIE_MSI_STATUS                        0x25A
 #define PCIE_MSI_EN                    0x25B
+#define PCIE_MSIX_STATUS               0x25D
+#define PCIE_INT_STATUS0               0x25F
+#define PCIE_INT_STATUS1               0x260
 #define PCIE_INT_EN0                   0x261
+#define PCIE_INT_EN1                   0x262
 
-/* PCIE_MSI_EN */
-#define PCIE_MSI_VECTOR_INT_EN         0xFFFFFFFF
+/* XLP9XX has basic changes */
+#define PCIE_9XX_BYTE_SWAP_MEM_BASE    0x25c
+#define PCIE_9XX_BYTE_SWAP_MEM_LIM     0x25d
+#define PCIE_9XX_BYTE_SWAP_IO_BASE     0x25e
+#define PCIE_9XX_BYTE_SWAP_IO_LIM      0x25f
 
-/* PCIE_INT_EN0 */
-#define PCIE_MSI_INT_EN                        (1 << 9)
+/* other */
+#define PCIE_NLINKS                    4
 
+/* MSI addresses */
+#define MSI_ADDR_BASE                  0xfffee00000ULL
+#define MSI_ADDR_SZ                    0x10000
+#define MSI_LINK_ADDR(n, l)            (MSI_ADDR_BASE + \
+                               (PCIE_NLINKS * (n) + (l)) * MSI_ADDR_SZ)
+#define MSIX_ADDR_BASE                 0xfffef00000ULL
+#define MSIX_LINK_ADDR(n, l)           (MSIX_ADDR_BASE + \
+                               (PCIE_NLINKS * (n) + (l)) * MSI_ADDR_SZ)
 #ifndef __ASSEMBLY__
 
 #define nlm_read_pcie_reg(b, r)                nlm_read_reg(b, r)
 #define nlm_write_pcie_reg(b, r, v)    nlm_write_reg(b, r, v)
-#define nlm_get_pcie_base(node, inst)  \
-                       nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, inst))
-#define nlm_get_pcie_regbase(node, inst)       \
-                       (nlm_get_pcie_base(node, inst) + XLP_IO_PCI_HDRSZ)
+#define nlm_get_pcie_base(node, inst)  nlm_pcicfg_base(cpu_is_xlp9xx() ? \
+       XLP9XX_IO_PCIE_OFFSET(node, inst) : XLP_IO_PCIE_OFFSET(node, inst))
+
+#ifdef CONFIG_PCI_MSI
+void xlp_init_node_msi_irqs(int node, int link);
+#else
+static inline void xlp_init_node_msi_irqs(int node, int link) {}
+#endif
+
+struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev);
 
-int xlp_pcie_link_irt(int link);
 #endif
 #endif /* __NLM_HAL_PCIBUS_H__ */
index 105389b..f10bf3b 100644 (file)
 #define PIC_IRT0               0x74
 #define PIC_IRT(i)             (PIC_IRT0 + ((i) * 2))
 
-#define TIMER_CYCLES_MAXVAL    0xffffffffffffffffULL
+#define PIC_9XX_PENDING_0      0x6
+#define PIC_9XX_PENDING_1      0x8
+#define PIC_9XX_PENDING_2      0xa
+#define PIC_9XX_PENDING_3      0xc
+
+#define PIC_9XX_IRT0           0x1c0
+#define PIC_9XX_IRT(i)         (PIC_9XX_IRT0 + ((i) * 2))
 
 /*
  *    IRT Map
  */
 #define PIC_NUM_IRTS           160
+#define PIC_9XX_NUM_IRTS       256
 
 #define PIC_IRT_WD_0_INDEX     0
 #define PIC_IRT_WD_1_INDEX     1
 #define PIC_IRT_PCIE_LINK_INDEX(num)   ((num) + PIC_IRT_PCIE_LINK_0_INDEX)
 
 #define PIC_CLOCK_TIMER                        7
-#define PIC_IRQ_BASE                   8
 
 #if !defined(LOCORE) && !defined(__ASSEMBLY__)
 
-#define PIC_IRT_FIRST_IRQ              (PIC_IRQ_BASE)
-#define PIC_IRT_LAST_IRQ               63
-#define PIC_IRQ_IS_IRT(irq)            ((irq) >= PIC_IRT_FIRST_IRQ)
-
 /*
  *   Misc
  */
 
 #define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r)
 #define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v)
-#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
+#define nlm_get_pic_pcibase(node)      nlm_pcicfg_base(cpu_is_xlp9xx() ? \
+               XLP9XX_IO_PIC_OFFSET(node) : XLP_IO_PIC_OFFSET(node))
 #define nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ)
 
 /* We use PIC on node 0 as a timer */
 #define pic_timer_freq()               nlm_get_pic_frequency(0)
 
 /* IRT and h/w interrupt routines */
-static inline int
-nlm_pic_read_irt(uint64_t base, int irt_index)
-{
-       return nlm_read_pic_reg(base, PIC_IRT(irt_index));
-}
-
 static inline void
-nlm_set_irt_to_cpu(uint64_t base, int irt, int cpu)
+nlm_9xx_pic_write_irt(uint64_t base, int irt_num, int en, int nmi,
+       int sch, int vec, int dt, int db, int cpu)
 {
        uint64_t val;
 
-       val = nlm_read_pic_reg(base, PIC_IRT(irt));
-       /* clear cpuset and mask */
-       val &= ~((0x7ull << 16) | 0xffff);
-       /* set DB, cpuset and cpumask */
-       val |= (1 << 19) | ((cpu >> 4) << 16) | (1 << (cpu & 0xf));
-       nlm_write_pic_reg(base, PIC_IRT(irt), val);
+       val = (((uint64_t)en & 0x1) << 22) | ((nmi & 0x1) << 23) |
+                       ((0 /*mc*/) << 20) | ((vec & 0x3f) << 24) |
+                       ((dt & 0x1) << 21) | (0 /*ptr*/ << 16) |
+                       (cpu & 0x3ff);
+
+       nlm_write_pic_reg(base, PIC_9XX_IRT(irt_num), val);
 }
 
 static inline void
@@ -254,9 +252,13 @@ static inline void
 nlm_pic_write_irt_direct(uint64_t base, int irt_num, int en, int nmi,
        int sch, int vec, int cpu)
 {
-       nlm_pic_write_irt(base, irt_num, en, nmi, sch, vec, 1,
-               (cpu >> 4),             /* thread group */
-               1 << (cpu & 0xf));      /* thread mask */
+       if (cpu_is_xlp9xx())
+               nlm_9xx_pic_write_irt(base, irt_num, en, nmi, sch, vec,
+                                                       1, 0, cpu);
+       else
+               nlm_pic_write_irt(base, irt_num, en, nmi, sch, vec, 1,
+                       (cpu >> 4),             /* thread group */
+                       1 << (cpu & 0xf));      /* thread mask */
 }
 
 static inline uint64_t
@@ -298,8 +300,13 @@ nlm_pic_enable_irt(uint64_t base, int irt)
 {
        uint64_t reg;
 
-       reg = nlm_read_pic_reg(base, PIC_IRT(irt));
-       nlm_write_pic_reg(base, PIC_IRT(irt), reg | (1u << 31));
+       if (cpu_is_xlp9xx()) {
+               reg = nlm_read_pic_reg(base, PIC_9XX_IRT(irt));
+               nlm_write_pic_reg(base, PIC_9XX_IRT(irt), reg | (1 << 22));
+       } else {
+               reg = nlm_read_pic_reg(base, PIC_IRT(irt));
+               nlm_write_pic_reg(base, PIC_IRT(irt), reg | (1u << 31));
+       }
 }
 
 static inline void
@@ -307,8 +314,15 @@ nlm_pic_disable_irt(uint64_t base, int irt)
 {
        uint64_t reg;
 
-       reg = nlm_read_pic_reg(base, PIC_IRT(irt));
-       nlm_write_pic_reg(base, PIC_IRT(irt), reg & ~((uint64_t)1 << 31));
+       if (cpu_is_xlp9xx()) {
+               reg = nlm_read_pic_reg(base, PIC_9XX_IRT(irt));
+               reg &= ~((uint64_t)1 << 22);
+               nlm_write_pic_reg(base, PIC_9XX_IRT(irt), reg);
+       } else {
+               reg = nlm_read_pic_reg(base, PIC_IRT(irt));
+               reg &= ~((uint64_t)1 << 31);
+               nlm_write_pic_reg(base, PIC_IRT(irt), reg);
+       }
 }
 
 static inline void
@@ -316,8 +330,13 @@ nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi)
 {
        uint64_t ipi;
 
-       ipi = ((uint64_t)nmi << 31) | (irq << 20);
-       ipi |= ((hwt >> 4) << 16) | (1 << (hwt & 0xf)); /* cpuset and mask */
+       if (cpu_is_xlp9xx())
+               ipi = (nmi << 23) | (irq << 24) |
+                       (0/*mcm*/ << 20) | (0/*ptr*/ << 16) | hwt;
+       else
+               ipi = ((uint64_t)nmi << 31) | (irq << 20) |
+                       ((hwt >> 4) << 16) | (1 << (hwt & 0xf));
+
        nlm_write_pic_reg(base, PIC_IPI_CTL, ipi);
 }
 
index fcf2833..d9b107f 100644 (file)
 #define SYS_SYS_PLL_MEM_REQ                    0x2a3
 #define SYS_PLL_MEM_STAT                       0x2a4
 
+/* Registers changed on 9XX */
+#define SYS_9XX_POWER_ON_RESET_CFG             0x00
+#define SYS_9XX_CHIP_RESET                     0x01
+#define SYS_9XX_CPU_RESET                      0x02
+#define SYS_9XX_CPU_NONCOHERENT_MODE           0x03
+
+/* XLP 9XX fuse block registers */
+#define FUSE_9XX_DEVCFG6                       0xc6
+
 #ifndef __ASSEMBLY__
 
 #define nlm_read_sys_reg(b, r)         nlm_read_reg(b, r)
 #define nlm_write_sys_reg(b, r, v)     nlm_write_reg(b, r, v)
-#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
+#define nlm_get_sys_pcibase(node)      nlm_pcicfg_base(cpu_is_xlp9xx() ? \
+               XLP9XX_IO_SYS_OFFSET(node) : XLP_IO_SYS_OFFSET(node))
 #define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
 
+/* XLP9XX fuse block */
+#define nlm_get_fuse_pcibase(node)     \
+                       nlm_pcicfg_base(XLP9XX_IO_FUSE_OFFSET(node))
+#define nlm_get_fuse_regbase(node)     \
+                       (nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ)
+
 unsigned int nlm_get_pic_frequency(int node);
 #endif
 #endif
index 86d16e1..a6c5442 100644 (file)
@@ -94,7 +94,8 @@
 #define nlm_read_uart_reg(b, r)                nlm_read_reg(b, r)
 #define nlm_write_uart_reg(b, r, v)    nlm_write_reg(b, r, v)
 #define nlm_get_uart_pcibase(node, inst)       \
-               nlm_pcicfg_base(XLP_IO_UART_OFFSET(node, inst))
+       nlm_pcicfg_base(cpu_is_xlp9xx() ?  XLP9XX_IO_UART_OFFSET(node) : \
+                                               XLP_IO_UART_OFFSET(node, inst))
 #define nlm_get_uart_regbase(node, inst)       \
                        (nlm_get_uart_pcibase(node, inst) + XLP_IO_PCI_HDRSZ)
 
index 470f209..2b0c959 100644 (file)
 
 #define PIC_UART_0_IRQ                 17
 #define PIC_UART_1_IRQ                 18
-#define PIC_PCIE_LINK_0_IRQ            19
-#define PIC_PCIE_LINK_1_IRQ            20
-#define PIC_PCIE_LINK_2_IRQ            21
-#define PIC_PCIE_LINK_3_IRQ            22
+
+#define PIC_PCIE_LINK_LEGACY_IRQ_BASE  19
+#define PIC_PCIE_LINK_LEGACY_IRQ(i)    (19 + (i))
 
 #define PIC_EHCI_0_IRQ                 23
 #define PIC_EHCI_1_IRQ                 24
@@ -51,6 +50,8 @@
 #define PIC_2XX_XHCI_0_IRQ             23
 #define PIC_2XX_XHCI_1_IRQ             24
 #define PIC_2XX_XHCI_2_IRQ             25
+#define PIC_9XX_XHCI_0_IRQ             23
+#define PIC_9XX_XHCI_1_IRQ             24
 
 #define PIC_MMC_IRQ                    29
 #define PIC_I2C_0_IRQ                  30
 #define PIC_I2C_2_IRQ                  32
 #define PIC_I2C_3_IRQ                  33
 
+#define PIC_PCIE_LINK_MSI_IRQ_BASE     44      /* 44 - 47 MSI IRQ */
+#define PIC_PCIE_LINK_MSI_IRQ(i)       (44 + (i))
+
+/* MSI-X with second link-level dispatch */
+#define PIC_PCIE_MSIX_IRQ_BASE         48      /* 48 - 51 MSI-X IRQ */
+#define PIC_PCIE_MSIX_IRQ(i)           (48 + (i))
+
+#define NLM_MSIX_VEC_BASE              96      /* 96 - 127 - MSIX mapped */
+#define NLM_MSI_VEC_BASE               128     /* 128 -255 - MSI mapped */
+
+#define NLM_PIC_INDIRECT_VEC_BASE      512
+#define NLM_GPIO_VEC_BASE              768
+
+#define PIC_IRQ_BASE                   8
+#define PIC_IRT_FIRST_IRQ              PIC_IRQ_BASE
+#define PIC_IRT_LAST_IRQ               63
+
 #ifndef __ASSEMBLY__
 
 /* SMP support functions */
@@ -68,6 +86,9 @@ void xlp_mmu_init(void);
 void nlm_hal_init(void);
 int xlp_get_dram_map(int n, uint64_t *dram_map);
 
+struct pci_dev;
+int xlp_socdev_to_node(const struct pci_dev *dev);
+
 /* Device tree related */
 void xlp_early_init_devtree(void);
 void *xlp_dt_init(void *fdtp);
@@ -76,8 +97,15 @@ static inline int cpu_is_xlpii(void)
 {
        int chip = read_c0_prid() & 0xff00;
 
-       return chip == PRID_IMP_NETLOGIC_XLP2XX;
+       return chip == PRID_IMP_NETLOGIC_XLP2XX ||
+               chip == PRID_IMP_NETLOGIC_XLP9XX;
 }
 
+static inline int cpu_is_xlp9xx(void)
+{
+       int chip = read_c0_prid() & 0xff00;
+
+       return chip == PRID_IMP_NETLOGIC_XLP9XX;
+}
 #endif /* !__ASSEMBLY__ */
 #endif /* _ASM_NLM_XLP_H */
index c1667e0..ceb991c 100644 (file)
 #ifndef _ASM_NLM_XLR_H
 #define _ASM_NLM_XLR_H
 
-/* Platform UART functions */
-struct uart_port;
-unsigned int nlm_xlr_uart_in(struct uart_port *, int);
-void nlm_xlr_uart_out(struct uart_port *, int, int);
-
 /* SMP helpers */
 void xlr_wakeup_secondary_cpus(void);
 
index 41785dd..8933203 100644 (file)
 
 #include <asm/octeon/cvmx-helper.h>
 
+enum cvmx_helper_board_usb_clock_types {
+       USB_CLOCK_TYPE_REF_12,
+       USB_CLOCK_TYPE_REF_24,
+       USB_CLOCK_TYPE_REF_48,
+       USB_CLOCK_TYPE_CRYSTAL_12,
+};
+
 typedef enum {
        set_phy_link_flags_autoneg = 0x1,
        set_phy_link_flags_flow_control_dont_touch = 0x0 << 1,
@@ -154,4 +161,6 @@ extern int __cvmx_helper_board_interface_probe(int interface,
  */
 extern int __cvmx_helper_board_hardware_enable(int interface);
 
+enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void);
+
 #endif /* __CVMX_HELPER_BOARD_H__ */
index f6be474..5e08bcc 100644 (file)
@@ -11,6 +11,8 @@
 
 #include <spaces.h>
 #include <linux/const.h>
+#include <linux/kernel.h>
+#include <asm/mipsregs.h>
 
 /*
  * PAGE_SHIFT determines the page size
 #define PAGE_SIZE      (_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK      (~((1 << PAGE_SHIFT) - 1))
 
+/*
+ * This is used for calculating the real page sizes
+ * for FTLB or VTLB + FTLB confugrations.
+ */
+static inline unsigned int page_size_ftlb(unsigned int mmuextdef)
+{
+       switch (mmuextdef) {
+       case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
+               if (PAGE_SIZE == (1 << 30))
+                       return 5;
+               if (PAGE_SIZE == (1llu << 32))
+                       return 6;
+               if (PAGE_SIZE > (256 << 10))
+                       return 7; /* reserved */
+                       /* fall through */
+       case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT:
+               return (PAGE_SHIFT - 10) / 2;
+       default:
+               panic("Invalid FTLB configuration with Conf4_mmuextdef=%d value\n",
+                     mmuextdef >> 14);
+       }
+}
+
 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
 #define HPAGE_SHIFT    (PAGE_SHIFT + PAGE_SHIFT - 3)
 #define HPAGE_SIZE     (_AC(1,UL) << HPAGE_SHIFT)
index 90985b6..c102065 100644 (file)
@@ -1,13 +1,18 @@
 /*
- * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
  */
-
 #ifndef __ASM_RTLX_H_
 #define __ASM_RTLX_H_
 
 #include <irq.h>
 
+#define RTLX_MODULE_NAME "rtlx"
+
 #define LX_NODE_BASE 10
 
 #define MIPS_CPU_RTLX_IRQ 0
 #define RTLX_VERSION 2
 #define RTLX_xID 0x12345600
 #define RTLX_ID (RTLX_xID | RTLX_VERSION)
+#define RTLX_BUFFER_SIZE 2048
 #define RTLX_CHANNELS 8
 
 #define RTLX_CHANNEL_STDIO     0
 #define RTLX_CHANNEL_DBG       1
 #define RTLX_CHANNEL_SYSIO     2
 
-extern int rtlx_open(int index, int can_sleep);
-extern int rtlx_release(int index);
-extern ssize_t rtlx_read(int index, void __user *buff, size_t count);
-extern ssize_t rtlx_write(int index, const void __user *buffer, size_t count);
-extern unsigned int rtlx_read_poll(int index, int can_sleep);
-extern unsigned int rtlx_write_poll(int index);
+void rtlx_starting(int vpe);
+void rtlx_stopping(int vpe);
+
+int rtlx_open(int index, int can_sleep);
+int rtlx_release(int index);
+ssize_t rtlx_read(int index, void __user *buff, size_t count);
+ssize_t rtlx_write(int index, const void __user *buffer, size_t count);
+unsigned int rtlx_read_poll(int index, int can_sleep);
+unsigned int rtlx_write_poll(int index);
+
+int __init rtlx_module_init(void);
+void __exit rtlx_module_exit(void);
+
+void _interrupt_sp(void);
+
+extern struct vpe_notifications rtlx_notify;
+extern const struct file_operations rtlx_fops;
+extern void (*aprp_hook)(void);
 
 enum rtlx_state {
        RTLX_STATE_UNUSED = 0,
@@ -35,10 +53,15 @@ enum rtlx_state {
        RTLX_STATE_OPENED
 };
 
-#define RTLX_BUFFER_SIZE 2048
+extern struct chan_waitqueues {
+       wait_queue_head_t rt_queue;
+       wait_queue_head_t lx_queue;
+       atomic_t in_open;
+       struct mutex mutex;
+} channel_wqs[RTLX_CHANNELS];
 
 /* each channel supports read and write.
-   linux (vpe0) reads lx_buffer         and writes rt_buffer
+   linux (vpe0) reads lx_buffer and writes rt_buffer
    SP (vpe1) reads rt_buffer and writes lx_buffer
 */
 struct rtlx_channel {
@@ -55,11 +78,11 @@ struct rtlx_channel {
        char *lx_buffer;
 };
 
-struct rtlx_info {
+extern struct rtlx_info {
        unsigned long id;
        enum rtlx_state state;
+       int ap_int_pending;     /* Status of 0 or 1 for CONFIG_MIPS_CMP only */
 
        struct rtlx_channel channel[RTLX_CHANNELS];
-};
-
+} *rtlx;
 #endif /* __ASM_RTLX_H_ */
index eb0af15..278d45a 100644 (file)
 
 struct task_struct;
 
-/*
- * switch_to(n) should switch tasks to task nr n, first
- * checking that n isn't the current task, in which case it does nothing.
+/**
+ * resume - resume execution of a task
+ * @prev:      The task previously executed.
+ * @next:      The task to begin executing.
+ * @next_ti:   task_thread_info(next).
+ * @usedfpu:   Non-zero if prev's FP context should be saved.
+ *
+ * This function is used whilst scheduling to save the context of prev & load
+ * the context of next. Returns prev.
  */
-extern asmlinkage void *resume(void *last, void *next, void *next_ti, u32 __usedfpu);
+extern asmlinkage struct task_struct *resume(struct task_struct *prev,
+               struct task_struct *next, struct thread_info *next_ti,
+               u32 usedfpu);
 
 extern unsigned int ll_bit;
 extern struct task_struct *ll_task;
index 81c8913..33e8dbf 100644 (file)
@@ -29,7 +29,7 @@ static inline long syscall_get_nr(struct task_struct *task,
 static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
        struct task_struct *task, struct pt_regs *regs, unsigned int n)
 {
-       unsigned long usp = regs->regs[29];
+       unsigned long usp __maybe_unused = regs->regs[29];
 
        switch (n) {
        case 0: case 1: case 2: case 3:
index 4f58ef6..24846f9 100644 (file)
@@ -110,11 +110,12 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_NOHZ               19      /* in adaptive nohz mode */
 #define TIF_FIXADE             20      /* Fix address errors in software */
 #define TIF_LOGADE             21      /* Log address errors to syslog */
-#define TIF_32BIT_REGS         22      /* also implies 16/32 fprs */
+#define TIF_32BIT_REGS         22      /* 32-bit general purpose registers */
 #define TIF_32BIT_ADDR         23      /* 32-bit address space (o32/n32) */
 #define TIF_FPUBOUND           24      /* thread bound to FPU-full CPU set */
 #define TIF_LOAD_WATCH         25      /* If set, load watch registers */
 #define TIF_SYSCALL_TRACEPOINT 26      /* syscall tracepoint instrumentation */
+#define TIF_32BIT_FPREGS       27      /* 32-bit floating point registers */
 #define TIF_SYSCALL_TRACE      31      /* syscall trace active */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
@@ -131,6 +132,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_32BIT_ADDR                (1<<TIF_32BIT_ADDR)
 #define _TIF_FPUBOUND          (1<<TIF_FPUBOUND)
 #define _TIF_LOAD_WATCH                (1<<TIF_LOAD_WATCH)
+#define _TIF_32BIT_FPREGS      (1<<TIF_32BIT_FPREGS)
 #define _TIF_SYSCALL_TRACEPOINT        (1<<TIF_SYSCALL_TRACEPOINT)
 
 #define _TIF_WORK_SYSCALL_ENTRY        (_TIF_NOHZ | _TIF_SYSCALL_TRACE |       \
index c67842b..4a23493 100644 (file)
  */
 #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
 
+#define UNIQUE_ENTRYHI(idx)                                            \
+               ((CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) |               \
+                (cpu_has_tlbinv ? MIPS_ENTRYHI_EHINV : 0))
+
 #include <asm-generic/tlb.h>
 
 #endif /* __ASM_TLB_H */
index 0880fe8..7849f39 100644 (file)
@@ -1,24 +1,95 @@
 /*
- * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
+ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
  */
-
 #ifndef _ASM_VPE_H
 #define _ASM_VPE_H
 
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+
+#define VPE_MODULE_NAME "vpe"
+#define VPE_MODULE_MINOR 1
+
+/* grab the likely amount of memory we will need. */
+#ifdef CONFIG_MIPS_VPE_LOADER_TOM
+#define P_SIZE (2 * 1024 * 1024)
+#else
+/* add an overhead to the max kmalloc size for non-striped symbols/etc */
+#define P_SIZE (256 * 1024)
+#endif
+
+#define MAX_VPES 16
+#define VPE_PATH_MAX 256
+
+static inline int aprp_cpu_index(void)
+{
+#ifdef CONFIG_MIPS_CMP
+       return setup_max_cpus;
+#else
+       extern int tclimit;
+       return tclimit;
+#endif
+}
+
+enum vpe_state {
+       VPE_STATE_UNUSED = 0,
+       VPE_STATE_INUSE,
+       VPE_STATE_RUNNING
+};
+
+enum tc_state {
+       TC_STATE_UNUSED = 0,
+       TC_STATE_INUSE,
+       TC_STATE_RUNNING,
+       TC_STATE_DYNAMIC
+};
+
+struct vpe {
+       enum vpe_state state;
+
+       /* (device) minor associated with this vpe */
+       int minor;
+
+       /* elfloader stuff */
+       void *load_addr;
+       unsigned long len;
+       char *pbuffer;
+       unsigned long plen;
+       char cwd[VPE_PATH_MAX];
+
+       unsigned long __start;
+
+       /* tc's associated with this vpe */
+       struct list_head tc;
+
+       /* The list of vpe's */
+       struct list_head list;
+
+       /* shared symbol address */
+       void *shared_ptr;
+
+       /* the list of who wants to know when something major happens */
+       struct list_head notify;
+
+       unsigned int ntcs;
+};
+
+struct tc {
+       enum tc_state state;
+       int index;
+
+       struct vpe *pvpe;       /* parent VPE */
+       struct list_head tc;    /* The list of TC's with this VPE */
+       struct list_head list;  /* The global list of tc's */
+};
+
 struct vpe_notifications {
        void (*start)(int vpe);
        void (*stop)(int vpe);
@@ -26,10 +97,34 @@ struct vpe_notifications {
        struct list_head list;
 };
 
+struct vpe_control {
+       spinlock_t vpe_list_lock;
+       struct list_head vpe_list;      /* Virtual processing elements */
+       spinlock_t tc_list_lock;
+       struct list_head tc_list;       /* Thread contexts */
+};
+
+extern unsigned long physical_memsize;
+extern struct vpe_control vpecontrol;
+extern const struct file_operations vpe_fops;
+
+int vpe_notify(int index, struct vpe_notifications *notify);
+
+void *vpe_get_shared(int index);
+char *vpe_getcwd(int index);
+
+struct vpe *get_vpe(int minor);
+struct tc *get_tc(int index);
+struct vpe *alloc_vpe(int minor);
+struct tc *alloc_tc(int index);
+void release_vpe(struct vpe *v);
 
-extern int vpe_notify(int index, struct vpe_notifications *notify);
+void *alloc_progmem(unsigned long len);
+void release_progmem(void *ptr);
 
-extern void *vpe_get_shared(int index);
-extern char *vpe_getcwd(int index);
+int __weak vpe_run(struct vpe *v);
+void cleanup_tc(struct tc *tc);
 
+int __init vpe_module_init(void);
+void __exit vpe_module_exit(void);
 #endif /* _ASM_VPE_H */
index e5a676e..b39ba25 100644 (file)
@@ -98,8 +98,9 @@ enum rt_op {
  */
 enum cop_op {
        mfc_op        = 0x00, dmfc_op       = 0x01,
-       cfc_op        = 0x02, mtc_op        = 0x04,
-       dmtc_op       = 0x05, ctc_op        = 0x06,
+       cfc_op        = 0x02, mfhc_op       = 0x03,
+       mtc_op        = 0x04, dmtc_op       = 0x05,
+       ctc_op        = 0x06, mthc_op       = 0x07,
        bc_op         = 0x08, cop_op        = 0x10,
        copm_op       = 0x18
 };
@@ -397,8 +398,10 @@ enum mm_32f_73_minor_op {
        mm_movt1_op = 0xa5,
        mm_ftruncw_op = 0xac,
        mm_fneg1_op = 0xad,
+       mm_mfhc1_op = 0xc0,
        mm_froundl_op = 0xcc,
        mm_fcvtd1_op = 0xcd,
+       mm_mthc1_op = 0xe0,
        mm_froundw_op = 0xec,
        mm_fcvts1_op = 0xed,
 };
index 8a5ec0e..c01900e 100644 (file)
@@ -427,6 +427,7 @@ static struct platform_device qi_lb60_audio_device = {
 
 static struct platform_device *jz_platform_devices[] __initdata = {
        &jz4740_udc_device,
+       &jz4740_udc_xceiv_device,
        &jz4740_mmc_device,
        &jz4740_nand_device,
        &qi_lb60_keypad,
index df65677..a447101 100644 (file)
  */
 
 #include <linux/device.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
 
 #include <linux/dma-mapping.h>
 
+#include <linux/usb/musb.h>
+
 #include <asm/mach-jz4740/platform.h>
 #include <asm/mach-jz4740/base.h>
 #include <asm/mach-jz4740/irq.h>
@@ -56,29 +57,35 @@ struct platform_device jz4740_usb_ohci_device = {
        .resource       = jz4740_usb_ohci_resources,
 };
 
-/* UDC (USB gadget controller) */
-static struct resource jz4740_usb_gdt_resources[] = {
-       {
-               .start  = JZ4740_UDC_BASE_ADDR,
-               .end    = JZ4740_UDC_BASE_ADDR + 0x1000 - 1,
-               .flags  = IORESOURCE_MEM,
+/* USB Device Controller */
+struct platform_device jz4740_udc_xceiv_device = {
+       .name = "usb_phy_gen_xceiv",
+       .id   = 0,
+};
+
+static struct resource jz4740_udc_resources[] = {
+       [0] = {
+               .start = JZ4740_UDC_BASE_ADDR,
+               .end   = JZ4740_UDC_BASE_ADDR + 0x10000 - 1,
+               .flags = IORESOURCE_MEM,
        },
-       {
-               .start  = JZ4740_IRQ_UDC,
-               .end    = JZ4740_IRQ_UDC,
-               .flags  = IORESOURCE_IRQ,
+       [1] = {
+               .start = JZ4740_IRQ_UDC,
+               .end   = JZ4740_IRQ_UDC,
+               .flags = IORESOURCE_IRQ,
+               .name  = "mc",
        },
 };
 
 struct platform_device jz4740_udc_device = {
-       .name           = "jz-udc",
-       .id             = -1,
-       .dev = {
-               .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask,
+       .name = "musb-jz4740",
+       .id   = -1,
+       .dev  = {
+               .dma_mask          = &jz4740_udc_device.dev.coherent_dma_mask,
                .coherent_dma_mask = DMA_BIT_MASK(32),
        },
-       .num_resources  = ARRAY_SIZE(jz4740_usb_gdt_resources),
-       .resource       = jz4740_usb_gdt_resources,
+       .num_resources = ARRAY_SIZE(jz4740_udc_resources),
+       .resource      = jz4740_udc_resources,
 };
 
 /* MMC/SD controller */
index 1c1b717..26c6175 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_CSRC_R4K)                += csrc-r4k.o
 obj-$(CONFIG_CSRC_SB1250)      += csrc-sb1250.o
 obj-$(CONFIG_SYNC_R4K)         += sync-r4k.o
 
+obj-$(CONFIG_DEBUG_FS)         += segment.o
 obj-$(CONFIG_STACKTRACE)       += stacktrace.o
 obj-$(CONFIG_MODULES)          += mips_ksyms.o module.o
 obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o
@@ -55,7 +56,11 @@ obj-$(CONFIG_MIPS_CMP)               += smp-cmp.o
 obj-$(CONFIG_CPU_MIPSR2)       += spram.o
 
 obj-$(CONFIG_MIPS_VPE_LOADER)  += vpe.o
+obj-$(CONFIG_MIPS_VPE_LOADER_CMP) += vpe-cmp.o
+obj-$(CONFIG_MIPS_VPE_LOADER_MT) += vpe-mt.o
 obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o
+obj-$(CONFIG_MIPS_VPE_APSP_API_CMP) += rtlx-cmp.o
+obj-$(CONFIG_MIPS_VPE_APSP_API_MT) += rtlx-mt.o
 
 obj-$(CONFIG_I8259)            += i8259.o
 obj-$(CONFIG_IRQ_CPU)          += irq_cpu.o
index 202e581..7faf5f2 100644 (file)
@@ -27,6 +27,18 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 typedef double elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
+/*
+ * In order to be sure that we don't attempt to execute an O32 binary which
+ * requires 64 bit FP (FR=1) on a system which does not support it we refuse
+ * to execute any binary which has bits specified by the following macro set
+ * in its ELF header flags.
+ */
+#ifdef CONFIG_MIPS_O32_FP64_SUPPORT
+# define __MIPS_O32_FP64_MUST_BE_ZERO  0
+#else
+# define __MIPS_O32_FP64_MUST_BE_ZERO  EF_MIPS_FP64
+#endif
+
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
@@ -43,6 +55,8 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
                __res = 0;                                              \
        if (((__h->e_flags & EF_MIPS_ABI) != 0) &&                      \
            ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32))          \
+               __res = 0;                                              \
+       if (__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO)                \
                __res = 0;                                              \
                                                                        \
        __res;                                                          \
index bd79c4f..a5bf73d 100644 (file)
@@ -8,11 +8,11 @@
  * Reset/NMI/re-entry vectors for BMIPS processors
  */
 
-#include <linux/init.h>
 
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
 #include <asm/cacheops.h>
+#include <asm/cpu.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
@@ -91,12 +91,18 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
        beqz    k0, bmips_smp_entry
 
 #if defined(CONFIG_CPU_BMIPS5000)
+       mfc0    k0, CP0_PRID
+       li      k1, PRID_IMP_BMIPS5000
+       andi    k0, 0xff00
+       bne     k0, k1, 1f
+
        /* if we're not on core 0, this must be the SMP boot signal */
        li      k1, (3 << 25)
        mfc0    k0, $22
        and     k0, k1
        bnez    k0, bmips_smp_entry
-#endif
+1:
+#endif /* CONFIG_CPU_BMIPS5000 */
 #endif /* CONFIG_SMP */
 
        /* nope, it's just a regular NMI */
@@ -139,7 +145,12 @@ bmips_smp_entry:
        xori    k0, 0x04
        mtc0    k0, CP0_CONFIG
 
+       mfc0    k0, CP0_PRID
+       andi    k0, 0xff00
 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
+       li      k1, PRID_IMP_BMIPS43XX
+       bne     k0, k1, 2f
+
        /* initialize CPU1's local I-cache */
        li      k0, 0x80000000
        li      k1, 0x80010000
@@ -150,14 +161,21 @@ bmips_smp_entry:
 1:     cache   Index_Store_Tag_I, 0(k0)
        addiu   k0, 16
        bne     k0, k1, 1b
-#elif defined(CONFIG_CPU_BMIPS5000)
+
+       b       3f
+2:
+#endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */
+#if defined(CONFIG_CPU_BMIPS5000)
        /* set exception vector base */
+       li      k1, PRID_IMP_BMIPS5000
+       bne     k0, k1, 3f
+
        la      k0, ebase
        lw      k0, 0(k0)
        mtc0    k0, $15, 1
        BARRIER
-#endif
-
+#endif /* CONFIG_CPU_BMIPS5000 */
+3:
        /* jump back to kseg0 in case we need to remap the kseg1 area */
        la      k0, 1f
        jr      k0
@@ -221,8 +239,18 @@ END(bmips_smp_int_vec)
 LEAF(bmips_enable_xks01)
 
 #if defined(CONFIG_XKS01)
-
+       mfc0    t0, CP0_PRID
+       andi    t2, t0, 0xff00
 #if defined(CONFIG_CPU_BMIPS4380)
+       li      t1, PRID_IMP_BMIPS43XX
+       bne     t2, t1, 1f
+
+       andi    t0, 0xff
+       addiu   t1, t0, -PRID_REV_BMIPS4380_HI
+       bgtz    t1, 2f
+       addiu   t0, -PRID_REV_BMIPS4380_LO
+       bltz    t0, 2f
+
        mfc0    t0, $22, 3
        li      t1, 0x1ff0
        li      t2, (1 << 12) | (1 << 9)
@@ -231,7 +259,13 @@ LEAF(bmips_enable_xks01)
        or      t0, t2
        mtc0    t0, $22, 3
        BARRIER
-#elif defined(CONFIG_CPU_BMIPS5000)
+       b       2f
+1:
+#endif /* CONFIG_CPU_BMIPS4380 */
+#if defined(CONFIG_CPU_BMIPS5000)
+       li      t1, PRID_IMP_BMIPS5000
+       bne     t2, t1, 2f
+
        mfc0    t0, $22, 5
        li      t1, 0x01ff
        li      t2, (1 << 8) | (1 << 5)
@@ -240,12 +274,8 @@ LEAF(bmips_enable_xks01)
        or      t0, t2
        mtc0    t0, $22, 5
        BARRIER
-#else
-
-#error Missing XKS01 setup
-
-#endif
-
+#endif /* CONFIG_CPU_BMIPS5000 */
+2:
 #endif /* defined(CONFIG_XKS01) */
 
        jr      ra
index c814287..530f832 100644 (file)
@@ -112,7 +112,7 @@ static inline unsigned long cpu_get_fpu_id(void)
        unsigned long tmp, fpu_id;
 
        tmp = read_c0_status();
-       __enable_fpu();
+       __enable_fpu(FPU_AS_IS);
        fpu_id = read_32bit_cp1_register(CP1_REVISION);
        write_c0_status(tmp);
        return fpu_id;
@@ -163,6 +163,25 @@ static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
 static char unknown_isa[] = KERN_ERR \
        "Unsupported ISA type, c0.config0: %d.";
 
+static void set_ftlb_enable(struct cpuinfo_mips *c, int enable)
+{
+       unsigned int config6;
+       /*
+        * Config6 is implementation dependent and it's currently only
+        * used by proAptiv
+        */
+       if (c->cputype == CPU_PROAPTIV) {
+               config6 = read_c0_config6();
+               if (enable)
+                       /* Enable FTLB */
+                       write_c0_config6(config6 | MIPS_CONF6_FTLBEN);
+               else
+                       /* Disable FTLB */
+                       write_c0_config6(config6 &  ~MIPS_CONF6_FTLBEN);
+               back_to_back_c0_hazard();
+       }
+}
+
 static inline unsigned int decode_config0(struct cpuinfo_mips *c)
 {
        unsigned int config0;
@@ -170,8 +189,13 @@ static inline unsigned int decode_config0(struct cpuinfo_mips *c)
 
        config0 = read_c0_config();
 
-       if (((config0 & MIPS_CONF_MT) >> 7) == 1)
+       /*
+        * Look for Standard TLB or Dual VTLB and FTLB
+        */
+       if ((((config0 & MIPS_CONF_MT) >> 7) == 1) ||
+           (((config0 & MIPS_CONF_MT) >> 7) == 4))
                c->options |= MIPS_CPU_TLB;
+
        isa = (config0 & MIPS_CONF_AT) >> 13;
        switch (isa) {
        case 0:
@@ -226,8 +250,11 @@ static inline unsigned int decode_config1(struct cpuinfo_mips *c)
                c->options |= MIPS_CPU_FPU;
                c->options |= MIPS_CPU_32FPR;
        }
-       if (cpu_has_tlb)
+       if (cpu_has_tlb) {
                c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
+               c->tlbsizevtlb = c->tlbsize;
+               c->tlbsizeftlbsets = 0;
+       }
 
        return config1 & MIPS_CONF_M;
 }
@@ -272,6 +299,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
                c->options |= MIPS_CPU_MICROMIPS;
        if (config3 & MIPS_CONF3_VZ)
                c->ases |= MIPS_ASE_VZ;
+       if (config3 & MIPS_CONF3_SC)
+               c->options |= MIPS_CPU_SEGMENTS;
 
        return config3 & MIPS_CONF_M;
 }
@@ -279,12 +308,51 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)
 static inline unsigned int decode_config4(struct cpuinfo_mips *c)
 {
        unsigned int config4;
+       unsigned int newcf4;
+       unsigned int mmuextdef;
+       unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE;
 
        config4 = read_c0_config4();
 
-       if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT
-           && cpu_has_tlb)
-               c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+       if (cpu_has_tlb) {
+               if (((config4 & MIPS_CONF4_IE) >> 29) == 2)
+                       c->options |= MIPS_CPU_TLBINV;
+               mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
+               switch (mmuextdef) {
+               case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:
+                       c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+                       c->tlbsizevtlb = c->tlbsize;
+                       break;
+               case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT:
+                       c->tlbsizevtlb +=
+                               ((config4 & MIPS_CONF4_VTLBSIZEEXT) >>
+                                 MIPS_CONF4_VTLBSIZEEXT_SHIFT) * 0x40;
+                       c->tlbsize = c->tlbsizevtlb;
+                       ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
+                       /* fall through */
+               case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
+                       newcf4 = (config4 & ~ftlb_page) |
+                               (page_size_ftlb(mmuextdef) <<
+                                MIPS_CONF4_FTLBPAGESIZE_SHIFT);
+                       write_c0_config4(newcf4);
+                       back_to_back_c0_hazard();
+                       config4 = read_c0_config4();
+                       if (config4 != newcf4) {
+                               pr_err("PAGE_SIZE 0x%lx is not supported by FTLB (config4=0x%x)\n",
+                                      PAGE_SIZE, config4);
+                               /* Switch FTLB off */
+                               set_ftlb_enable(c, 0);
+                               break;
+                       }
+                       c->tlbsizeftlbsets = 1 <<
+                               ((config4 & MIPS_CONF4_FTLBSETS) >>
+                                MIPS_CONF4_FTLBSETS_SHIFT);
+                       c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >>
+                                             MIPS_CONF4_FTLBWAYS_SHIFT) + 2;
+                       c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets;
+                       break;
+               }
+       }
 
        c->kscratch_mask = (config4 >> 16) & 0xff;
 
@@ -312,6 +380,9 @@ static void decode_configs(struct cpuinfo_mips *c)
 
        c->scache.flags = MIPS_CACHE_NOT_PRESENT;
 
+       /* Enable FTLB if present */
+       set_ftlb_enable(c, 1);
+
        ok = decode_config0(c);                 /* Read Config registers.  */
        BUG_ON(!ok);                            /* Arch spec violation!  */
        if (ok)
@@ -675,7 +746,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
 
 static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
 {
-       decode_configs(c);
        switch (c->processor_id & PRID_IMP_MASK) {
        case PRID_IMP_4KC:
                c->cputype = CPU_4KC;
@@ -739,8 +809,26 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
                c->cputype = CPU_74K;
                __cpu_name[cpu] = "MIPS 1074Kc";
                break;
+       case PRID_IMP_INTERAPTIV_UP:
+               c->cputype = CPU_INTERAPTIV;
+               __cpu_name[cpu] = "MIPS interAptiv";
+               break;
+       case PRID_IMP_INTERAPTIV_MP:
+               c->cputype = CPU_INTERAPTIV;
+               __cpu_name[cpu] = "MIPS interAptiv (multi)";
+               break;
+       case PRID_IMP_PROAPTIV_UP:
+               c->cputype = CPU_PROAPTIV;
+               __cpu_name[cpu] = "MIPS proAptiv";
+               break;
+       case PRID_IMP_PROAPTIV_MP:
+               c->cputype = CPU_PROAPTIV;
+               __cpu_name[cpu] = "MIPS proAptiv (multi)";
+               break;
        }
 
+       decode_configs(c);
+
        spram_config();
 }
 
@@ -943,6 +1031,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
 
        switch (c->processor_id & PRID_IMP_MASK) {
        case PRID_IMP_NETLOGIC_XLP2XX:
+       case PRID_IMP_NETLOGIC_XLP9XX:
                c->cputype = CPU_XLP;
                __cpu_name[cpu] = "Broadcom XLPII";
                break;
index 93aa302..d212646 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/bootmem.h>
 #include <linux/crash_dump.h>
 #include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/types.h>
 #include <linux/sched.h>
index 47d7583..d84f6a5 100644 (file)
@@ -476,6 +476,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
        BUILD_HANDLER ov ov sti silent                  /* #12 */
        BUILD_HANDLER tr tr sti silent                  /* #13 */
        BUILD_HANDLER fpe fpe fpe silent                /* #15 */
+       BUILD_HANDLER ftlb ftlb none silent             /* #16 */
        BUILD_HANDLER mdmx mdmx sti silent              /* #22 */
 #ifdef CONFIG_HARDWARE_WATCHPOINTS
        /*
index f7991d9..3553243 100644 (file)
@@ -184,6 +184,8 @@ void __init check_wait(void)
        case CPU_24K:
        case CPU_34K:
        case CPU_1004K:
+       case CPU_INTERAPTIV:
+       case CPU_PROAPTIV:
                cpu_wait = r4k_wait;
                if (read_c0_config7() & MIPS_CONF7_WII)
                        cpu_wait = r4k_wait_irqoff;
index 8c58d8a..00d2097 100644 (file)
@@ -65,26 +65,25 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                                cpu_data[n].watch_reg_masks[i]);
                seq_printf(m, "]\n");
        }
-       if (cpu_has_mips_r) {
-               seq_printf(m, "isa\t\t\t: mips1");
-               if (cpu_has_mips_2)
-                       seq_printf(m, "%s", " mips2");
-               if (cpu_has_mips_3)
-                       seq_printf(m, "%s", " mips3");
-               if (cpu_has_mips_4)
-                       seq_printf(m, "%s", " mips4");
-               if (cpu_has_mips_5)
-                       seq_printf(m, "%s", " mips5");
-               if (cpu_has_mips32r1)
-                       seq_printf(m, "%s", " mips32r1");
-               if (cpu_has_mips32r2)
-                       seq_printf(m, "%s", " mips32r2");
-               if (cpu_has_mips64r1)
-                       seq_printf(m, "%s", " mips64r1");
-               if (cpu_has_mips64r2)
-                       seq_printf(m, "%s", " mips64r2");
-               seq_printf(m, "\n");
-       }
+
+       seq_printf(m, "isa\t\t\t: mips1");
+       if (cpu_has_mips_2)
+               seq_printf(m, "%s", " mips2");
+       if (cpu_has_mips_3)
+               seq_printf(m, "%s", " mips3");
+       if (cpu_has_mips_4)
+               seq_printf(m, "%s", " mips4");
+       if (cpu_has_mips_5)
+               seq_printf(m, "%s", " mips5");
+       if (cpu_has_mips32r1)
+               seq_printf(m, "%s", " mips32r1");
+       if (cpu_has_mips32r2)
+               seq_printf(m, "%s", " mips32r2");
+       if (cpu_has_mips64r1)
+               seq_printf(m, "%s", " mips64r1");
+       if (cpu_has_mips64r2)
+               seq_printf(m, "%s", " mips64r2");
+       seq_printf(m, "\n");
 
        seq_printf(m, "ASEs implemented\t:");
        if (cpu_has_mips16)     seq_printf(m, "%s", " mips16");
@@ -107,7 +106,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        seq_printf(m, "kscratch registers\t: %d\n",
                      hweight8(cpu_data[n].kscratch_mask));
        seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
-
+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
+       if (cpu_has_mipsmt) {
+               seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id);
+#if defined(CONFIG_MIPS_MT_SMTC)
+               seq_printf(m, "TC\t\t\t: %d\n", cpu_data[n].tc_id);
+#endif
+       }
+#endif
        sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
                      cpu_has_vce ? "%u" : "not available");
        seq_printf(m, fmt, 'D', vced_count);
index ddc7610..6ae540e 100644 (file)
@@ -60,15 +60,11 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
 
        /* New thread loses kernel privileges. */
        status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK);
-#ifdef CONFIG_64BIT
-       status |= test_thread_flag(TIF_32BIT_REGS) ? 0 : ST0_FR;
-#endif
        status |= KU_USER;
        regs->cp0_status = status;
        clear_used_math();
        clear_fpu_owner();
-       if (cpu_has_dsp)
-               __init_dsp();
+       init_dsp();
        regs->cp0_epc = pc;
        regs->regs[29] = sp;
 }
index b52e1d2..7da9b76 100644 (file)
@@ -137,13 +137,13 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
                if (cpu_has_mipsmt) {
                        unsigned int vpflags = dvpe();
                        flags = read_c0_status();
-                       __enable_fpu();
+                       __enable_fpu(FPU_AS_IS);
                        __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
                        write_c0_status(flags);
                        evpe(vpflags);
                } else {
                        flags = read_c0_status();
-                       __enable_fpu();
+                       __enable_fpu(FPU_AS_IS);
                        __asm__ __volatile__("cfc1\t%0,$0" : "=r" (tmp));
                        write_c0_status(flags);
                }
@@ -408,6 +408,7 @@ long arch_ptrace(struct task_struct *child, long request,
        /* Read the word at location addr in the USER area. */
        case PTRACE_PEEKUSR: {
                struct pt_regs *regs;
+               fpureg_t *fregs;
                unsigned long tmp = 0;
 
                regs = task_pt_regs(child);
@@ -418,26 +419,28 @@ long arch_ptrace(struct task_struct *child, long request,
                        tmp = regs->regs[addr];
                        break;
                case FPR_BASE ... FPR_BASE + 31:
-                       if (tsk_used_math(child)) {
-                               fpureg_t *fregs = get_fpu_regs(child);
+                       if (!tsk_used_math(child)) {
+                               /* FP not yet used */
+                               tmp = -1;
+                               break;
+                       }
+                       fregs = get_fpu_regs(child);
 
 #ifdef CONFIG_32BIT
+                       if (test_thread_flag(TIF_32BIT_FPREGS)) {
                                /*
                                 * The odd registers are actually the high
                                 * order bits of the values stored in the even
                                 * registers - unless we're using r2k_switch.S.
                                 */
                                if (addr & 1)
-                                       tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+                                       tmp = fregs[(addr & ~1) - 32] >> 32;
                                else
-                                       tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
-#endif
-#ifdef CONFIG_64BIT
-                               tmp = fregs[addr - FPR_BASE];
-#endif
-                       } else {
-                               tmp = -1;       /* FP not yet used  */
+                                       tmp = fregs[addr - 32];
+                               break;
                        }
+#endif
+                       tmp = fregs[addr - FPR_BASE];
                        break;
                case PC:
                        tmp = regs->cp0_epc;
@@ -483,13 +486,13 @@ long arch_ptrace(struct task_struct *child, long request,
                        if (cpu_has_mipsmt) {
                                unsigned int vpflags = dvpe();
                                flags = read_c0_status();
-                               __enable_fpu();
+                               __enable_fpu(FPU_AS_IS);
                                __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
                                write_c0_status(flags);
                                evpe(vpflags);
                        } else {
                                flags = read_c0_status();
-                               __enable_fpu();
+                               __enable_fpu(FPU_AS_IS);
                                __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
                                write_c0_status(flags);
                        }
@@ -554,22 +557,25 @@ long arch_ptrace(struct task_struct *child, long request,
                                child->thread.fpu.fcr31 = 0;
                        }
 #ifdef CONFIG_32BIT
-                       /*
-                        * The odd registers are actually the high order bits
-                        * of the values stored in the even registers - unless
-                        * we're using r2k_switch.S.
-                        */
-                       if (addr & 1) {
-                               fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
-                               fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
-                       } else {
-                               fregs[addr - FPR_BASE] &= ~0xffffffffLL;
-                               fregs[addr - FPR_BASE] |= data;
+                       if (test_thread_flag(TIF_32BIT_FPREGS)) {
+                               /*
+                                * The odd registers are actually the high
+                                * order bits of the values stored in the even
+                                * registers - unless we're using r2k_switch.S.
+                                */
+                               if (addr & 1) {
+                                       fregs[(addr & ~1) - FPR_BASE] &=
+                                               0xffffffff;
+                                       fregs[(addr & ~1) - FPR_BASE] |=
+                                               ((u64)data) << 32;
+                               } else {
+                                       fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+                                       fregs[addr - FPR_BASE] |= data;
+                               }
+                               break;
                        }
 #endif
-#ifdef CONFIG_64BIT
                        fregs[addr - FPR_BASE] = data;
-#endif
                        break;
                }
                case PC:
index 9486055..b8aa2dd 100644 (file)
@@ -80,6 +80,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
        /* Read the word at location addr in the USER area. */
        case PTRACE_PEEKUSR: {
                struct pt_regs *regs;
+               fpureg_t *fregs;
                unsigned int tmp;
 
                regs = task_pt_regs(child);
@@ -90,21 +91,25 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        tmp = regs->regs[addr];
                        break;
                case FPR_BASE ... FPR_BASE + 31:
-                       if (tsk_used_math(child)) {
-                               fpureg_t *fregs = get_fpu_regs(child);
-
+                       if (!tsk_used_math(child)) {
+                               /* FP not yet used */
+                               tmp = -1;
+                               break;
+                       }
+                       fregs = get_fpu_regs(child);
+                       if (test_thread_flag(TIF_32BIT_FPREGS)) {
                                /*
                                 * The odd registers are actually the high
                                 * order bits of the values stored in the even
                                 * registers - unless we're using r2k_switch.S.
                                 */
                                if (addr & 1)
-                                       tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32);
+                                       tmp = fregs[(addr & ~1) - 32] >> 32;
                                else
-                                       tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff);
-                       } else {
-                               tmp = -1;       /* FP not yet used  */
+                                       tmp = fregs[addr - 32];
+                               break;
                        }
+                       tmp = fregs[addr - FPR_BASE];
                        break;
                case PC:
                        tmp = regs->cp0_epc;
@@ -147,13 +152,13 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        if (cpu_has_mipsmt) {
                                unsigned int vpflags = dvpe();
                                flags = read_c0_status();
-                               __enable_fpu();
+                               __enable_fpu(FPU_AS_IS);
                                __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
                                write_c0_status(flags);
                                evpe(vpflags);
                        } else {
                                flags = read_c0_status();
-                               __enable_fpu();
+                               __enable_fpu(FPU_AS_IS);
                                __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
                                write_c0_status(flags);
                        }
@@ -236,20 +241,24 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                                       sizeof(child->thread.fpu));
                                child->thread.fpu.fcr31 = 0;
                        }
-                       /*
-                        * The odd registers are actually the high order bits
-                        * of the values stored in the even registers - unless
-                        * we're using r2k_switch.S.
-                        */
-                       if (addr & 1) {
-                               fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff;
-                               fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32;
-                       } else {
-                               fregs[addr - FPR_BASE] &= ~0xffffffffLL;
-                               /* Must cast, lest sign extension fill upper
-                                  bits!  */
-                               fregs[addr - FPR_BASE] |= (unsigned int)data;
+                       if (test_thread_flag(TIF_32BIT_FPREGS)) {
+                               /*
+                                * The odd registers are actually the high
+                                * order bits of the values stored in the even
+                                * registers - unless we're using r2k_switch.S.
+                                */
+                               if (addr & 1) {
+                                       fregs[(addr & ~1) - FPR_BASE] &=
+                                               0xffffffff;
+                                       fregs[(addr & ~1) - FPR_BASE] |=
+                                               ((u64)data) << 32;
+                               } else {
+                                       fregs[addr - FPR_BASE] &= ~0xffffffffLL;
+                                       fregs[addr - FPR_BASE] |= data;
+                               }
+                               break;
                        }
+                       fregs[addr - FPR_BASE] = data;
                        break;
                }
                case PC:
index 55ffe14..253b2fb 100644 (file)
 LEAF(_save_fp_context)
        cfc1    t1, fcr31
 
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS32_R2)
+       .set    push
+#ifdef CONFIG_MIPS32_R2
+       .set    mips64r2
+       mfc0    t0, CP0_STATUS
+       sll     t0, t0, 5
+       bgez    t0, 1f                  # skip storing odd if FR=0
+        nop
+#endif
        /* Store the 16 odd double precision registers */
        EX      sdc1 $f1, SC_FPREGS+8(a0)
        EX      sdc1 $f3, SC_FPREGS+24(a0)
@@ -53,6 +61,7 @@ LEAF(_save_fp_context)
        EX      sdc1 $f27, SC_FPREGS+216(a0)
        EX      sdc1 $f29, SC_FPREGS+232(a0)
        EX      sdc1 $f31, SC_FPREGS+248(a0)
+1:     .set    pop
 #endif
 
        /* Store the 16 even double precision registers */
@@ -82,7 +91,31 @@ LEAF(_save_fp_context)
 LEAF(_save_fp_context32)
        cfc1    t1, fcr31
 
-       EX      sdc1 $f0, SC32_FPREGS+0(a0)
+       mfc0    t0, CP0_STATUS
+       sll     t0, t0, 5
+       bgez    t0, 1f                  # skip storing odd if FR=0
+        nop
+
+       /* Store the 16 odd double precision registers */
+       EX      sdc1 $f1, SC32_FPREGS+8(a0)
+       EX      sdc1 $f3, SC32_FPREGS+24(a0)
+       EX      sdc1 $f5, SC32_FPREGS+40(a0)
+       EX      sdc1 $f7, SC32_FPREGS+56(a0)
+       EX      sdc1 $f9, SC32_FPREGS+72(a0)
+       EX      sdc1 $f11, SC32_FPREGS+88(a0)
+       EX      sdc1 $f13, SC32_FPREGS+104(a0)
+       EX      sdc1 $f15, SC32_FPREGS+120(a0)
+       EX      sdc1 $f17, SC32_FPREGS+136(a0)
+       EX      sdc1 $f19, SC32_FPREGS+152(a0)
+       EX      sdc1 $f21, SC32_FPREGS+168(a0)
+       EX      sdc1 $f23, SC32_FPREGS+184(a0)
+       EX      sdc1 $f25, SC32_FPREGS+200(a0)
+       EX      sdc1 $f27, SC32_FPREGS+216(a0)
+       EX      sdc1 $f29, SC32_FPREGS+232(a0)
+       EX      sdc1 $f31, SC32_FPREGS+248(a0)
+
+       /* Store the 16 even double precision registers */
+1:     EX      sdc1 $f0, SC32_FPREGS+0(a0)
        EX      sdc1 $f2, SC32_FPREGS+16(a0)
        EX      sdc1 $f4, SC32_FPREGS+32(a0)
        EX      sdc1 $f6, SC32_FPREGS+48(a0)
@@ -114,7 +147,16 @@ LEAF(_save_fp_context32)
  */
 LEAF(_restore_fp_context)
        EX      lw t0, SC_FPC_CSR(a0)
-#ifdef CONFIG_64BIT
+
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS32_R2)
+       .set    push
+#ifdef CONFIG_MIPS32_R2
+       .set    mips64r2
+       mfc0    t0, CP0_STATUS
+       sll     t0, t0, 5
+       bgez    t0, 1f                  # skip loading odd if FR=0
+        nop
+#endif
        EX      ldc1 $f1, SC_FPREGS+8(a0)
        EX      ldc1 $f3, SC_FPREGS+24(a0)
        EX      ldc1 $f5, SC_FPREGS+40(a0)
@@ -131,6 +173,7 @@ LEAF(_restore_fp_context)
        EX      ldc1 $f27, SC_FPREGS+216(a0)
        EX      ldc1 $f29, SC_FPREGS+232(a0)
        EX      ldc1 $f31, SC_FPREGS+248(a0)
+1:     .set pop
 #endif
        EX      ldc1 $f0, SC_FPREGS+0(a0)
        EX      ldc1 $f2, SC_FPREGS+16(a0)
@@ -157,7 +200,30 @@ LEAF(_restore_fp_context)
 LEAF(_restore_fp_context32)
        /* Restore an o32 sigcontext.  */
        EX      lw t0, SC32_FPC_CSR(a0)
-       EX      ldc1 $f0, SC32_FPREGS+0(a0)
+
+       mfc0    t0, CP0_STATUS
+       sll     t0, t0, 5
+       bgez    t0, 1f                  # skip loading odd if FR=0
+        nop
+
+       EX      ldc1 $f1, SC32_FPREGS+8(a0)
+       EX      ldc1 $f3, SC32_FPREGS+24(a0)
+       EX      ldc1 $f5, SC32_FPREGS+40(a0)
+       EX      ldc1 $f7, SC32_FPREGS+56(a0)
+       EX      ldc1 $f9, SC32_FPREGS+72(a0)
+       EX      ldc1 $f11, SC32_FPREGS+88(a0)
+       EX      ldc1 $f13, SC32_FPREGS+104(a0)
+       EX      ldc1 $f15, SC32_FPREGS+120(a0)
+       EX      ldc1 $f17, SC32_FPREGS+136(a0)
+       EX      ldc1 $f19, SC32_FPREGS+152(a0)
+       EX      ldc1 $f21, SC32_FPREGS+168(a0)
+       EX      ldc1 $f23, SC32_FPREGS+184(a0)
+       EX      ldc1 $f25, SC32_FPREGS+200(a0)
+       EX      ldc1 $f27, SC32_FPREGS+216(a0)
+       EX      ldc1 $f29, SC32_FPREGS+232(a0)
+       EX      ldc1 $f31, SC32_FPREGS+248(a0)
+
+1:     EX      ldc1 $f0, SC32_FPREGS+0(a0)
        EX      ldc1 $f2, SC32_FPREGS+16(a0)
        EX      ldc1 $f4, SC32_FPREGS+32(a0)
        EX      ldc1 $f6, SC32_FPREGS+48(a0)
index 078de5e..cc78dd9 100644 (file)
  * Save a thread's fp context.
  */
 LEAF(_save_fp)
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
        mfc0    t0, CP0_STATUS
 #endif
        fpu_save_double a0 t0 t1                # clobbers t1
@@ -134,7 +134,7 @@ LEAF(_save_fp)
  * Restore a thread's fp context.
  */
 LEAF(_restore_fp)
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
        mfc0    t0, CP0_STATUS
 #endif
        fpu_restore_double a0 t0 t1             # clobbers t1
@@ -228,6 +228,47 @@ LEAF(_init_fpu)
        mtc1    t1, $f29
        mtc1    t1, $f30
        mtc1    t1, $f31
+
+#ifdef CONFIG_CPU_MIPS32_R2
+       .set    push
+       .set    mips64r2
+       sll     t0, t0, 5                       # is Status.FR set?
+       bgez    t0, 1f                          # no: skip setting upper 32b
+
+       mthc1   t1, $f0
+       mthc1   t1, $f1
+       mthc1   t1, $f2
+       mthc1   t1, $f3
+       mthc1   t1, $f4
+       mthc1   t1, $f5
+       mthc1   t1, $f6
+       mthc1   t1, $f7
+       mthc1   t1, $f8
+       mthc1   t1, $f9
+       mthc1   t1, $f10
+       mthc1   t1, $f11
+       mthc1   t1, $f12
+       mthc1   t1, $f13
+       mthc1   t1, $f14
+       mthc1   t1, $f15
+       mthc1   t1, $f16
+       mthc1   t1, $f17
+       mthc1   t1, $f18
+       mthc1   t1, $f19
+       mthc1   t1, $f20
+       mthc1   t1, $f21
+       mthc1   t1, $f22
+       mthc1   t1, $f23
+       mthc1   t1, $f24
+       mthc1   t1, $f25
+       mthc1   t1, $f26
+       mthc1   t1, $f27
+       mthc1   t1, $f28
+       mthc1   t1, $f29
+       mthc1   t1, $f30
+       mthc1   t1, $f31
+1:     .set    pop
+#endif /* CONFIG_CPU_MIPS32_R2 */
 #else
        .set    mips3
        dmtc1   t1, $f0
diff --git a/arch/mips/kernel/rtlx-cmp.c b/arch/mips/kernel/rtlx-cmp.c
new file mode 100644 (file)
index 0000000..56dc696
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ */
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+
+#include <asm/mips_mt.h>
+#include <asm/vpe.h>
+#include <asm/rtlx.h>
+
+static int major;
+
+static void rtlx_interrupt(void)
+{
+       int i;
+       struct rtlx_info *info;
+       struct rtlx_info **p = vpe_get_shared(aprp_cpu_index());
+
+       if (p == NULL || *p == NULL)
+               return;
+
+       info = *p;
+
+       if (info->ap_int_pending == 1 && smp_processor_id() == 0) {
+               for (i = 0; i < RTLX_CHANNELS; i++) {
+                       wake_up(&channel_wqs[i].lx_queue);
+                       wake_up(&channel_wqs[i].rt_queue);
+               }
+               info->ap_int_pending = 0;
+       }
+}
+
+void _interrupt_sp(void)
+{
+       smp_send_reschedule(aprp_cpu_index());
+}
+
+int __init rtlx_module_init(void)
+{
+       struct device *dev;
+       int i, err;
+
+       if (!cpu_has_mipsmt) {
+               pr_warn("VPE loader: not a MIPS MT capable processor\n");
+               return -ENODEV;
+       }
+
+       if (num_possible_cpus() - aprp_cpu_index() < 1) {
+               pr_warn("No TCs reserved for AP/SP, not initializing RTLX.\n"
+                       "Pass maxcpus=<n> argument as kernel argument\n");
+
+               return -ENODEV;
+       }
+
+       major = register_chrdev(0, RTLX_MODULE_NAME, &rtlx_fops);
+       if (major < 0) {
+               pr_err("rtlx_module_init: unable to register device\n");
+               return major;
+       }
+
+       /* initialise the wait queues */
+       for (i = 0; i < RTLX_CHANNELS; i++) {
+               init_waitqueue_head(&channel_wqs[i].rt_queue);
+               init_waitqueue_head(&channel_wqs[i].lx_queue);
+               atomic_set(&channel_wqs[i].in_open, 0);
+               mutex_init(&channel_wqs[i].mutex);
+
+               dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
+                                   "%s%d", RTLX_MODULE_NAME, i);
+               if (IS_ERR(dev)) {
+                       err = PTR_ERR(dev);
+                       goto out_chrdev;
+               }
+       }
+
+       /* set up notifiers */
+       rtlx_notify.start = rtlx_starting;
+       rtlx_notify.stop = rtlx_stopping;
+       vpe_notify(aprp_cpu_index(), &rtlx_notify);
+
+       if (cpu_has_vint) {
+               aprp_hook = rtlx_interrupt;
+       } else {
+               pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
+               err = -ENODEV;
+               goto out_class;
+       }
+
+       return 0;
+
+out_class:
+       for (i = 0; i < RTLX_CHANNELS; i++)
+               device_destroy(mt_class, MKDEV(major, i));
+out_chrdev:
+       unregister_chrdev(major, RTLX_MODULE_NAME);
+
+       return err;
+}
+
+void __exit rtlx_module_exit(void)
+{
+       int i;
+
+       for (i = 0; i < RTLX_CHANNELS; i++)
+               device_destroy(mt_class, MKDEV(major, i));
+       unregister_chrdev(major, RTLX_MODULE_NAME);
+}
diff --git a/arch/mips/kernel/rtlx-mt.c b/arch/mips/kernel/rtlx-mt.c
new file mode 100644 (file)
index 0000000..91d61ba
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ */
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/mips_mt.h>
+#include <asm/vpe.h>
+#include <asm/rtlx.h>
+
+static int major;
+
+static void rtlx_dispatch(void)
+{
+       if (read_c0_cause() & read_c0_status() & C_SW0)
+               do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ);
+}
+
+/*
+ * Interrupt handler may be called before rtlx_init has otherwise had
+ * a chance to run.
+ */
+static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
+{
+       unsigned int vpeflags;
+       unsigned long flags;
+       int i;
+
+       /* Ought not to be strictly necessary for SMTC builds */
+       local_irq_save(flags);
+       vpeflags = dvpe();
+       set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
+       irq_enable_hazard();
+       evpe(vpeflags);
+       local_irq_restore(flags);
+
+       for (i = 0; i < RTLX_CHANNELS; i++) {
+               wake_up(&channel_wqs[i].lx_queue);
+               wake_up(&channel_wqs[i].rt_queue);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction rtlx_irq = {
+       .handler        = rtlx_interrupt,
+       .name           = "RTLX",
+};
+
+static int rtlx_irq_num = MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ;
+
+void _interrupt_sp(void)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       dvpe();
+       settc(1);
+       write_vpe_c0_cause(read_vpe_c0_cause() | C_SW0);
+       evpe(EVPE_ENABLE);
+       local_irq_restore(flags);
+}
+
+int __init rtlx_module_init(void)
+{
+       struct device *dev;
+       int i, err;
+
+       if (!cpu_has_mipsmt) {
+               pr_warn("VPE loader: not a MIPS MT capable processor\n");
+               return -ENODEV;
+       }
+
+       if (aprp_cpu_index() == 0) {
+               pr_warn("No TCs reserved for AP/SP, not initializing RTLX.\n"
+                       "Pass maxtcs=<n> argument as kernel argument\n");
+
+               return -ENODEV;
+       }
+
+       major = register_chrdev(0, RTLX_MODULE_NAME, &rtlx_fops);
+       if (major < 0) {
+               pr_err("rtlx_module_init: unable to register device\n");
+               return major;
+       }
+
+       /* initialise the wait queues */
+       for (i = 0; i < RTLX_CHANNELS; i++) {
+               init_waitqueue_head(&channel_wqs[i].rt_queue);
+               init_waitqueue_head(&channel_wqs[i].lx_queue);
+               atomic_set(&channel_wqs[i].in_open, 0);
+               mutex_init(&channel_wqs[i].mutex);
+
+               dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
+                                   "%s%d", RTLX_MODULE_NAME, i);
+               if (IS_ERR(dev)) {
+                       err = PTR_ERR(dev);
+                       goto out_chrdev;
+               }
+       }
+
+       /* set up notifiers */
+       rtlx_notify.start = rtlx_starting;
+       rtlx_notify.stop = rtlx_stopping;
+       vpe_notify(aprp_cpu_index(), &rtlx_notify);
+
+       if (cpu_has_vint) {
+               aprp_hook = rtlx_dispatch;
+       } else {
+               pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
+               err = -ENODEV;
+               goto out_class;
+       }
+
+       rtlx_irq.dev_id = rtlx;
+       err = setup_irq(rtlx_irq_num, &rtlx_irq);
+       if (err)
+               goto out_class;
+
+       return 0;
+
+out_class:
+       for (i = 0; i < RTLX_CHANNELS; i++)
+               device_destroy(mt_class, MKDEV(major, i));
+out_chrdev:
+       unregister_chrdev(major, RTLX_MODULE_NAME);
+
+       return err;
+}
+
+void __exit rtlx_module_exit(void)
+{
+       int i;
+
+       for (i = 0; i < RTLX_CHANNELS; i++)
+               device_destroy(mt_class, MKDEV(major, i));
+       unregister_chrdev(major, RTLX_MODULE_NAME);
+}
index 2c12ea1..31b1b76 100644 (file)
 /*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
  * Copyright (C) 2005, 06 Ralf Baechle (ralf@linux-mips.org)
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
+ * Copyright (C) 2013 Imagination Technologies Ltd.
  */
-
-#include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <linux/list.h>
-#include <linux/vmalloc.h>
-#include <linux/elf.h>
-#include <linux/seq_file.h>
 #include <linux/syscalls.h>
 #include <linux/moduleloader.h>
-#include <linux/interrupt.h>
-#include <linux/poll.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
+#include <linux/atomic.h>
 #include <asm/mipsmtregs.h>
 #include <asm/mips_mt.h>
-#include <asm/cacheflush.h>
-#include <linux/atomic.h>
-#include <asm/cpu.h>
 #include <asm/processor.h>
-#include <asm/vpe.h>
 #include <asm/rtlx.h>
 #include <asm/setup.h>
+#include <asm/vpe.h>
 
-static struct rtlx_info *rtlx;
-static int major;
-static char module_name[] = "rtlx";
-
-static struct chan_waitqueues {
-       wait_queue_head_t rt_queue;
-       wait_queue_head_t lx_queue;
-       atomic_t in_open;
-       struct mutex mutex;
-} channel_wqs[RTLX_CHANNELS];
-
-static struct vpe_notifications notify;
 static int sp_stopping;
-
-extern void *vpe_get_shared(int index);
-
-static void rtlx_dispatch(void)
-{
-       do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ);
-}
-
-
-/* Interrupt handler may be called before rtlx_init has otherwise had
-   a chance to run.
-*/
-static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
-{
-       unsigned int vpeflags;
-       unsigned long flags;
-       int i;
-
-       /* Ought not to be strictly necessary for SMTC builds */
-       local_irq_save(flags);
-       vpeflags = dvpe();
-       set_c0_status(0x100 << MIPS_CPU_RTLX_IRQ);
-       irq_enable_hazard();
-       evpe(vpeflags);
-       local_irq_restore(flags);
-
-       for (i = 0; i < RTLX_CHANNELS; i++) {
-                       wake_up(&channel_wqs[i].lx_queue);
-                       wake_up(&channel_wqs[i].rt_queue);
-       }
-
-       return IRQ_HANDLED;
-}
+struct rtlx_info *rtlx;
+struct chan_waitqueues channel_wqs[RTLX_CHANNELS];
+struct vpe_notifications rtlx_notify;
+void (*aprp_hook)(void) = NULL;
+EXPORT_SYMBOL(aprp_hook);
 
 static void __used dump_rtlx(void)
 {
        int i;
 
-       printk("id 0x%lx state %d\n", rtlx->id, rtlx->state);
+       pr_info("id 0x%lx state %d\n", rtlx->id, rtlx->state);
 
        for (i = 0; i < RTLX_CHANNELS; i++) {
                struct rtlx_channel *chan = &rtlx->channel[i];
 
-               printk(" rt_state %d lx_state %d buffer_size %d\n",
-                      chan->rt_state, chan->lx_state, chan->buffer_size);
+               pr_info(" rt_state %d lx_state %d buffer_size %d\n",
+                       chan->rt_state, chan->lx_state, chan->buffer_size);
 
-               printk(" rt_read %d rt_write %d\n",
-                      chan->rt_read, chan->rt_write);
+               pr_info(" rt_read %d rt_write %d\n",
+                       chan->rt_read, chan->rt_write);
 
-               printk(" lx_read %d lx_write %d\n",
-                      chan->lx_read, chan->lx_write);
+               pr_info(" lx_read %d lx_write %d\n",
+                       chan->lx_read, chan->lx_write);
 
-               printk(" rt_buffer <%s>\n", chan->rt_buffer);
-               printk(" lx_buffer <%s>\n", chan->lx_buffer);
+               pr_info(" rt_buffer <%s>\n", chan->rt_buffer);
+               pr_info(" lx_buffer <%s>\n", chan->lx_buffer);
        }
 }
 
@@ -116,8 +53,7 @@ static void __used dump_rtlx(void)
 static int rtlx_init(struct rtlx_info *rtlxi)
 {
        if (rtlxi->id != RTLX_ID) {
-               printk(KERN_ERR "no valid RTLX id at 0x%p 0x%lx\n",
-                       rtlxi, rtlxi->id);
+               pr_err("no valid RTLX id at 0x%p 0x%lx\n", rtlxi, rtlxi->id);
                return -ENOEXEC;
        }
 
@@ -127,20 +63,20 @@ static int rtlx_init(struct rtlx_info *rtlxi)
 }
 
 /* notifications */
-static void starting(int vpe)
+void rtlx_starting(int vpe)
 {
        int i;
        sp_stopping = 0;
 
        /* force a reload of rtlx */
-       rtlx=NULL;
+       rtlx = NULL;
 
        /* wake up any sleeping rtlx_open's */
        for (i = 0; i < RTLX_CHANNELS; i++)
                wake_up_interruptible(&channel_wqs[i].lx_queue);
 }
 
-static void stopping(int vpe)
+void rtlx_stopping(int vpe)
 {
        int i;
 
@@ -158,31 +94,30 @@ int rtlx_open(int index, int can_sleep)
        int ret = 0;
 
        if (index >= RTLX_CHANNELS) {
-               printk(KERN_DEBUG "rtlx_open index out of range\n");
+               pr_debug(KERN_DEBUG "rtlx_open index out of range\n");
                return -ENOSYS;
        }
 
        if (atomic_inc_return(&channel_wqs[index].in_open) > 1) {
-               printk(KERN_DEBUG "rtlx_open channel %d already opened\n",
-                      index);
+               pr_debug(KERN_DEBUG "rtlx_open channel %d already opened\n", index);
                ret = -EBUSY;
                goto out_fail;
        }
 
        if (rtlx == NULL) {
-               if( (p = vpe_get_shared(tclimit)) == NULL) {
-                   if (can_sleep) {
-                       ret = __wait_event_interruptible(
+               p = vpe_get_shared(aprp_cpu_index());
+               if (p == NULL) {
+                       if (can_sleep) {
+                               ret = __wait_event_interruptible(
                                        channel_wqs[index].lx_queue,
-                                       (p = vpe_get_shared(tclimit)));
-                       if (ret)
+                                       (p = vpe_get_shared(aprp_cpu_index())));
+                               if (ret)
+                                       goto out_fail;
+                       } else {
+                               pr_debug("No SP program loaded, and device opened with O_NONBLOCK\n");
+                               ret = -ENOSYS;
                                goto out_fail;
-                   } else {
-                       printk(KERN_DEBUG "No SP program loaded, and device "
-                                       "opened with O_NONBLOCK\n");
-                       ret = -ENOSYS;
-                       goto out_fail;
-                   }
+                       }
                }
 
                smp_rmb();
@@ -204,24 +139,24 @@ int rtlx_open(int index, int can_sleep)
                                        ret = -ERESTARTSYS;
                                        goto out_fail;
                                }
-                               finish_wait(&channel_wqs[index].lx_queue, &wait);
+                               finish_wait(&channel_wqs[index].lx_queue,
+                                           &wait);
                        } else {
-                               pr_err(" *vpe_get_shared is NULL. "
-                                      "Has an SP program been loaded?\n");
+                               pr_err(" *vpe_get_shared is NULL. Has an SP program been loaded?\n");
                                ret = -ENOSYS;
                                goto out_fail;
                        }
                }
 
                if ((unsigned int)*p < KSEG0) {
-                       printk(KERN_WARNING "vpe_get_shared returned an "
-                              "invalid pointer maybe an error code %d\n",
-                              (int)*p);
+                       pr_warn("vpe_get_shared returned an invalid pointer maybe an error code %d\n",
+                               (int)*p);
                        ret = -ENOSYS;
                        goto out_fail;
                }
 
-               if ((ret = rtlx_init(*p)) < 0)
+               ret = rtlx_init(*p);
+               if (ret < 0)
                        goto out_ret;
        }
 
@@ -352,7 +287,7 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count)
        size_t fl;
 
        if (rtlx == NULL)
-               return(-ENOSYS);
+               return -ENOSYS;
 
        rt = &rtlx->channel[index];
 
@@ -361,8 +296,8 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count)
        rt_read = rt->rt_read;
 
        /* total number of bytes to copy */
-       count = min(count, (size_t)write_spacefree(rt_read, rt->rt_write,
-                                                       rt->buffer_size));
+       count = min_t(size_t, count, write_spacefree(rt_read, rt->rt_write,
+                                                    rt->buffer_size));
 
        /* first bit from write pointer to the end of the buffer, or count */
        fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
@@ -372,9 +307,8 @@ ssize_t rtlx_write(int index, const void __user *buffer, size_t count)
                goto out;
 
        /* if there's any left copy to the beginning of the buffer */
-       if (count - fl) {
+       if (count - fl)
                failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
-       }
 
 out:
        count -= failed;
@@ -384,6 +318,8 @@ out:
        smp_wmb();
        mutex_unlock(&channel_wqs[index].mutex);
 
+       _interrupt_sp();
+
        return count;
 }
 
@@ -398,7 +334,7 @@ static int file_release(struct inode *inode, struct file *filp)
        return rtlx_release(iminor(inode));
 }
 
-static unsigned int file_poll(struct file *file, poll_table * wait)
+static unsigned int file_poll(struct file *file, poll_table *wait)
 {
        int minor = iminor(file_inode(file));
        unsigned int mask = 0;
@@ -420,21 +356,20 @@ static unsigned int file_poll(struct file *file, poll_table * wait)
        return mask;
 }
 
-static ssize_t file_read(struct file *file, char __user * buffer, size_t count,
-                        loff_t * ppos)
+static ssize_t file_read(struct file *file, char __user *buffer, size_t count,
+                        loff_t *ppos)
 {
        int minor = iminor(file_inode(file));
 
        /* data available? */
-       if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) {
-               return 0;       // -EAGAIN makes cat whinge
-       }
+       if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1))
+               return 0;       /* -EAGAIN makes 'cat' whine */
 
        return rtlx_read(minor, buffer, count);
 }
 
-static ssize_t file_write(struct file *file, const char __user * buffer,
-                         size_t count, loff_t * ppos)
+static ssize_t file_write(struct file *file, const char __user *buffer,
+                         size_t count, loff_t *ppos)
 {
        int minor = iminor(file_inode(file));
 
@@ -454,100 +389,16 @@ static ssize_t file_write(struct file *file, const char __user * buffer,
        return rtlx_write(minor, buffer, count);
 }
 
-static const struct file_operations rtlx_fops = {
+const struct file_operations rtlx_fops = {
        .owner =   THIS_MODULE,
-       .open =    file_open,
+       .open =    file_open,
        .release = file_release,
        .write =   file_write,
-       .read =    file_read,
-       .poll =    file_poll,
+       .read =    file_read,
+       .poll =    file_poll,
        .llseek =  noop_llseek,
 };
 
-static struct irqaction rtlx_irq = {
-       .handler        = rtlx_interrupt,
-       .name           = "RTLX",
-};
-
-static int rtlx_irq_num = MIPS_CPU_IRQ_BASE + MIPS_CPU_RTLX_IRQ;
-
-static char register_chrdev_failed[] __initdata =
-       KERN_ERR "rtlx_module_init: unable to register device\n";
-
-static int __init rtlx_module_init(void)
-{
-       struct device *dev;
-       int i, err;
-
-       if (!cpu_has_mipsmt) {
-               printk("VPE loader: not a MIPS MT capable processor\n");
-               return -ENODEV;
-       }
-
-       if (tclimit == 0) {
-               printk(KERN_WARNING "No TCs reserved for AP/SP, not "
-                      "initializing RTLX.\nPass maxtcs=<n> argument as kernel "
-                      "argument\n");
-
-               return -ENODEV;
-       }
-
-       major = register_chrdev(0, module_name, &rtlx_fops);
-       if (major < 0) {
-               printk(register_chrdev_failed);
-               return major;
-       }
-
-       /* initialise the wait queues */
-       for (i = 0; i < RTLX_CHANNELS; i++) {
-               init_waitqueue_head(&channel_wqs[i].rt_queue);
-               init_waitqueue_head(&channel_wqs[i].lx_queue);
-               atomic_set(&channel_wqs[i].in_open, 0);
-               mutex_init(&channel_wqs[i].mutex);
-
-               dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
-                                   "%s%d", module_name, i);
-               if (IS_ERR(dev)) {
-                       err = PTR_ERR(dev);
-                       goto out_chrdev;
-               }
-       }
-
-       /* set up notifiers */
-       notify.start = starting;
-       notify.stop = stopping;
-       vpe_notify(tclimit, &notify);
-
-       if (cpu_has_vint)
-               set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
-       else {
-               pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
-               err = -ENODEV;
-               goto out_chrdev;
-       }
-
-       rtlx_irq.dev_id = rtlx;
-       setup_irq(rtlx_irq_num, &rtlx_irq);
-
-       return 0;
-
-out_chrdev:
-       for (i = 0; i < RTLX_CHANNELS; i++)
-               device_destroy(mt_class, MKDEV(major, i));
-
-       return err;
-}
-
-static void __exit rtlx_module_exit(void)
-{
-       int i;
-
-       for (i = 0; i < RTLX_CHANNELS; i++)
-               device_destroy(mt_class, MKDEV(major, i));
-
-       unregister_chrdev(major, module_name);
-}
-
 module_init(rtlx_module_init);
 module_exit(rtlx_module_exit);
 
diff --git a/arch/mips/kernel/segment.c b/arch/mips/kernel/segment.c
new file mode 100644 (file)
index 0000000..076ead2
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ */
+
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <asm/cpu.h>
+#include <asm/mipsregs.h>
+
+static void build_segment_config(char *str, unsigned int cfg)
+{
+       unsigned int am;
+       static const char * const am_str[] = {
+               "UK", "MK", "MSK", "MUSK", "MUSUK", "USK",
+               "RSRVD", "UUSK"};
+
+       /* Segment access mode. */
+       am = (cfg & MIPS_SEGCFG_AM) >> MIPS_SEGCFG_AM_SHIFT;
+       str += sprintf(str, "%-5s", am_str[am]);
+
+       /*
+        * Access modes MK, MSK and MUSK are mapped segments. Therefore
+        * there is no direct physical address mapping.
+        */
+       if ((am == 0) || (am > 3)) {
+               str += sprintf(str, "         %03lx",
+                       ((cfg & MIPS_SEGCFG_PA) >> MIPS_SEGCFG_PA_SHIFT));
+               str += sprintf(str, "         %01ld",
+                       ((cfg & MIPS_SEGCFG_C) >> MIPS_SEGCFG_C_SHIFT));
+       } else {
+               str += sprintf(str, "         UND");
+               str += sprintf(str, "         U");
+       }
+
+       /* Exception configuration. */
+       str += sprintf(str, "       %01ld\n",
+               ((cfg & MIPS_SEGCFG_EU) >> MIPS_SEGCFG_EU_SHIFT));
+}
+
+static int show_segments(struct seq_file *m, void *v)
+{
+       unsigned int segcfg;
+       char str[42];
+
+       seq_puts(m, "Segment   Virtual    Size   Access Mode   Physical   Caching   EU\n");
+       seq_puts(m, "-------   -------    ----   -----------   --------   -------   --\n");
+
+       segcfg = read_c0_segctl0();
+       build_segment_config(str, segcfg);
+       seq_printf(m, "   0      e0000000   512M      %s", str);
+
+       segcfg >>= 16;
+       build_segment_config(str, segcfg);
+       seq_printf(m, "   1      c0000000   512M      %s", str);
+
+       segcfg = read_c0_segctl1();
+       build_segment_config(str, segcfg);
+       seq_printf(m, "   2      a0000000   512M      %s", str);
+
+       segcfg >>= 16;
+       build_segment_config(str, segcfg);
+       seq_printf(m, "   3      80000000   512M      %s", str);
+
+       segcfg = read_c0_segctl2();
+       build_segment_config(str, segcfg);
+       seq_printf(m, "   4      40000000    1G       %s", str);
+
+       segcfg >>= 16;
+       build_segment_config(str, segcfg);
+       seq_printf(m, "   5      00000000    1G       %s\n", str);
+
+       return 0;
+}
+
+static int segments_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, show_segments, NULL);
+}
+
+static const struct file_operations segments_fops = {
+       .open           = segments_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init segments_info(void)
+{
+       extern struct dentry *mips_debugfs_dir;
+       struct dentry *segments;
+
+       if (cpu_has_segments) {
+               if (!mips_debugfs_dir)
+                       return -ENODEV;
+
+               segments = debugfs_create_file("segments", S_IRUGO,
+                                              mips_debugfs_dir, NULL,
+                                              &segments_fops);
+               if (!segments)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+device_initcall(segments_info);
index 2f285ab..5199563 100644 (file)
@@ -71,8 +71,9 @@ static int protected_save_fp_context(struct sigcontext __user *sc)
        int err;
        while (1) {
                lock_fpu_owner();
-               own_fpu_inatomic(1);
-               err = save_fp_context(sc); /* this might fail */
+               err = own_fpu_inatomic(1);
+               if (!err)
+                       err = save_fp_context(sc); /* this might fail */
                unlock_fpu_owner();
                if (likely(!err))
                        break;
@@ -91,8 +92,9 @@ static int protected_restore_fp_context(struct sigcontext __user *sc)
        int err, tmp __maybe_unused;
        while (1) {
                lock_fpu_owner();
-               own_fpu_inatomic(0);
-               err = restore_fp_context(sc); /* this might fail */
+               err = own_fpu_inatomic(0);
+               if (!err)
+                       err = restore_fp_context(sc); /* this might fail */
                unlock_fpu_owner();
                if (likely(!err))
                        break;
index 1905a41..3d60f77 100644 (file)
@@ -85,8 +85,9 @@ static int protected_save_fp_context32(struct sigcontext32 __user *sc)
        int err;
        while (1) {
                lock_fpu_owner();
-               own_fpu_inatomic(1);
-               err = save_fp_context32(sc); /* this might fail */
+               err = own_fpu_inatomic(1);
+               if (!err)
+                       err = save_fp_context32(sc); /* this might fail */
                unlock_fpu_owner();
                if (likely(!err))
                        break;
@@ -105,8 +106,9 @@ static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
        int err, tmp __maybe_unused;
        while (1) {
                lock_fpu_owner();
-               own_fpu_inatomic(0);
-               err = restore_fp_context32(sc); /* this might fail */
+               err = own_fpu_inatomic(0);
+               if (!err)
+                       err = restore_fp_context32(sc); /* this might fail */
                unlock_fpu_owner();
                if (likely(!err))
                        break;
index 2362665..ea4c2dc 100644 (file)
@@ -49,8 +49,10 @@ cpumask_t bmips_booted_mask;
 unsigned long bmips_smp_boot_sp;
 unsigned long bmips_smp_boot_gp;
 
-static void bmips_send_ipi_single(int cpu, unsigned int action);
-static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
+static void bmips43xx_send_ipi_single(int cpu, unsigned int action);
+static void bmips5000_send_ipi_single(int cpu, unsigned int action);
+static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id);
+static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id);
 
 /* SW interrupts 0,1 are used for interprocessor signaling */
 #define IPI0_IRQ                       (MIPS_CPU_IRQ_BASE + 0)
@@ -64,49 +66,58 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
 static void __init bmips_smp_setup(void)
 {
        int i, cpu = 1, boot_cpu = 0;
-
-#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
        int cpu_hw_intr;
 
-       /* arbitration priority */
-       clear_c0_brcm_cmt_ctrl(0x30);
-
-       /* NBK and weak order flags */
-       set_c0_brcm_config_0(0x30000);
-
-       /* Find out if we are running on TP0 or TP1 */
-       boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
-
-       /*
-        * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
-        * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
-        * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
-        */
-       if (boot_cpu == 0)
-               cpu_hw_intr = 0x02;
-       else
-               cpu_hw_intr = 0x1d;
-
-       change_c0_brcm_cmt_intr(0xf8018000, (cpu_hw_intr << 27) | (0x03 << 15));
-
-       /* single core, 2 threads (2 pipelines) */
-       max_cpus = 2;
-#elif defined(CONFIG_CPU_BMIPS5000)
-       /* enable raceless SW interrupts */
-       set_c0_brcm_config(0x03 << 22);
-
-       /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
-       change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
-
-       /* N cores, 2 threads per core */
-       max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
+       switch (current_cpu_type()) {
+       case CPU_BMIPS4350:
+       case CPU_BMIPS4380:
+               /* arbitration priority */
+               clear_c0_brcm_cmt_ctrl(0x30);
+
+               /* NBK and weak order flags */
+               set_c0_brcm_config_0(0x30000);
+
+               /* Find out if we are running on TP0 or TP1 */
+               boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
+
+               /*
+                * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other
+                * thread
+                * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
+                * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
+                */
+               if (boot_cpu == 0)
+                       cpu_hw_intr = 0x02;
+               else
+                       cpu_hw_intr = 0x1d;
+
+               change_c0_brcm_cmt_intr(0xf8018000,
+                                       (cpu_hw_intr << 27) | (0x03 << 15));
+
+               /* single core, 2 threads (2 pipelines) */
+               max_cpus = 2;
+
+               break;
+       case CPU_BMIPS5000:
+               /* enable raceless SW interrupts */
+               set_c0_brcm_config(0x03 << 22);
+
+               /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
+               change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
+
+               /* N cores, 2 threads per core */
+               max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
+
+               /* clear any pending SW interrupts */
+               for (i = 0; i < max_cpus; i++) {
+                       write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
+                       write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
+               }
 
-       /* clear any pending SW interrupts */
-       for (i = 0; i < max_cpus; i++) {
-               write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
-               write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
+               break;
+       default:
+               max_cpus = 1;
        }
-#endif
 
        if (!bmips_smp_enabled)
                max_cpus = 1;
@@ -134,6 +145,20 @@ static void __init bmips_smp_setup(void)
  */
 static void bmips_prepare_cpus(unsigned int max_cpus)
 {
+       irqreturn_t (*bmips_ipi_interrupt)(int irq, void *dev_id);
+
+       switch (current_cpu_type()) {
+       case CPU_BMIPS4350:
+       case CPU_BMIPS4380:
+               bmips_ipi_interrupt = bmips43xx_ipi_interrupt;
+               break;
+       case CPU_BMIPS5000:
+               bmips_ipi_interrupt = bmips5000_ipi_interrupt;
+               break;
+       default:
+               return;
+       }
+
        if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
                        "smp_ipi0", NULL))
                panic("Can't request IPI0 interrupt");
@@ -168,26 +193,39 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
 
        pr_info("SMP: Booting CPU%d...\n", cpu);
 
-       if (cpumask_test_cpu(cpu, &bmips_booted_mask))
-               bmips_send_ipi_single(cpu, 0);
+       if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
+               switch (current_cpu_type()) {
+               case CPU_BMIPS4350:
+               case CPU_BMIPS4380:
+                       bmips43xx_send_ipi_single(cpu, 0);
+                       break;
+               case CPU_BMIPS5000:
+                       bmips5000_send_ipi_single(cpu, 0);
+                       break;
+               }
+       }
        else {
-#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
-               /* Reset slave TP1 if booting from TP0 */
-               if (cpu_logical_map(cpu) == 1)
-                       set_c0_brcm_cmt_ctrl(0x01);
-#elif defined(CONFIG_CPU_BMIPS5000)
-               if (cpu & 0x01)
-                       write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
-               else {
-                       /*
-                        * core N thread 0 was already booted; just
-                        * pulse the NMI line
-                        */
-                       bmips_write_zscm_reg(0x210, 0xc0000000);
-                       udelay(10);
-                       bmips_write_zscm_reg(0x210, 0x00);
+               switch (current_cpu_type()) {
+               case CPU_BMIPS4350:
+               case CPU_BMIPS4380:
+                       /* Reset slave TP1 if booting from TP0 */
+                       if (cpu_logical_map(cpu) == 1)
+                               set_c0_brcm_cmt_ctrl(0x01);
+                       break;
+               case CPU_BMIPS5000:
+                       if (cpu & 0x01)
+                               write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
+                       else {
+                               /*
+                                * core N thread 0 was already booted; just
+                                * pulse the NMI line
+                                */
+                               bmips_write_zscm_reg(0x210, 0xc0000000);
+                               udelay(10);
+                               bmips_write_zscm_reg(0x210, 0x00);
+                       }
+                       break;
                }
-#endif
                cpumask_set_cpu(cpu, &bmips_booted_mask);
        }
 }
@@ -199,26 +237,32 @@ static void bmips_init_secondary(void)
 {
        /* move NMI vector to kseg0, in case XKS01 is enabled */
 
-#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
-       void __iomem *cbr = BMIPS_GET_CBR();
+       void __iomem *cbr;
        unsigned long old_vec;
        unsigned long relo_vector;
        int boot_cpu;
 
-       boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
-       relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
-                         BMIPS_RELO_VECTOR_CONTROL_1;
+       switch (current_cpu_type()) {
+       case CPU_BMIPS4350:
+       case CPU_BMIPS4380:
+               cbr = BMIPS_GET_CBR();
 
-       old_vec = __raw_readl(cbr + relo_vector);
-       __raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
+               boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
+               relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
+                                 BMIPS_RELO_VECTOR_CONTROL_1;
 
-       clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
-#elif defined(CONFIG_CPU_BMIPS5000)
-       write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
-               (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
+               old_vec = __raw_readl(cbr + relo_vector);
+               __raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
 
-       write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
-#endif
+               clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
+               break;
+       case CPU_BMIPS5000:
+               write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
+                       (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
+
+               write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
+               break;
+       }
 }
 
 /*
@@ -243,8 +287,6 @@ static void bmips_cpus_done(void)
 {
 }
 
-#if defined(CONFIG_CPU_BMIPS5000)
-
 /*
  * BMIPS5000 raceless IPIs
  *
@@ -253,12 +295,12 @@ static void bmips_cpus_done(void)
  * IPI1 is used for SMP_CALL_FUNCTION
  */
 
-static void bmips_send_ipi_single(int cpu, unsigned int action)
+static void bmips5000_send_ipi_single(int cpu, unsigned int action)
 {
        write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
 }
 
-static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
+static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id)
 {
        int action = irq - IPI0_IRQ;
 
@@ -272,7 +314,14 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-#else
+static void bmips5000_send_ipi_mask(const struct cpumask *mask,
+       unsigned int action)
+{
+       unsigned int i;
+
+       for_each_cpu(i, mask)
+               bmips5000_send_ipi_single(i, action);
+}
 
 /*
  * BMIPS43xx racey IPIs
@@ -287,7 +336,7 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
 static DEFINE_SPINLOCK(ipi_lock);
 static DEFINE_PER_CPU(int, ipi_action_mask);
 
-static void bmips_send_ipi_single(int cpu, unsigned int action)
+static void bmips43xx_send_ipi_single(int cpu, unsigned int action)
 {
        unsigned long flags;
 
@@ -298,7 +347,7 @@ static void bmips_send_ipi_single(int cpu, unsigned int action)
        spin_unlock_irqrestore(&ipi_lock, flags);
 }
 
-static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
+static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
 {
        unsigned long flags;
        int action, cpu = irq - IPI0_IRQ;
@@ -317,15 +366,13 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-#endif /* BMIPS type */
-
-static void bmips_send_ipi_mask(const struct cpumask *mask,
+static void bmips43xx_send_ipi_mask(const struct cpumask *mask,
        unsigned int action)
 {
        unsigned int i;
 
        for_each_cpu(i, mask)
-               bmips_send_ipi_single(i, action);
+               bmips43xx_send_ipi_single(i, action);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -381,15 +428,30 @@ void __ref play_dead(void)
 
 #endif /* CONFIG_HOTPLUG_CPU */
 
-struct plat_smp_ops bmips_smp_ops = {
+struct plat_smp_ops bmips43xx_smp_ops = {
+       .smp_setup              = bmips_smp_setup,
+       .prepare_cpus           = bmips_prepare_cpus,
+       .boot_secondary         = bmips_boot_secondary,
+       .smp_finish             = bmips_smp_finish,
+       .init_secondary         = bmips_init_secondary,
+       .cpus_done              = bmips_cpus_done,
+       .send_ipi_single        = bmips43xx_send_ipi_single,
+       .send_ipi_mask          = bmips43xx_send_ipi_mask,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_disable            = bmips_cpu_disable,
+       .cpu_die                = bmips_cpu_die,
+#endif
+};
+
+struct plat_smp_ops bmips5000_smp_ops = {
        .smp_setup              = bmips_smp_setup,
        .prepare_cpus           = bmips_prepare_cpus,
        .boot_secondary         = bmips_boot_secondary,
        .smp_finish             = bmips_smp_finish,
        .init_secondary         = bmips_init_secondary,
        .cpus_done              = bmips_cpus_done,
-       .send_ipi_single        = bmips_send_ipi_single,
-       .send_ipi_mask          = bmips_send_ipi_mask,
+       .send_ipi_single        = bmips5000_send_ipi_single,
+       .send_ipi_mask          = bmips5000_send_ipi_mask,
 #ifdef CONFIG_HOTPLUG_CPU
        .cpu_disable            = bmips_cpu_disable,
        .cpu_die                = bmips_cpu_die,
@@ -427,43 +489,47 @@ void bmips_ebase_setup(void)
 
        BUG_ON(ebase != CKSEG0);
 
-#if defined(CONFIG_CPU_BMIPS4350)
-       /*
-        * BMIPS4350 cannot relocate the normal vectors, but it
-        * can relocate the BEV=1 vectors.  So CPU1 starts up at
-        * the relocated BEV=1, IV=0 general exception vector @
-        * 0xa000_0380.
-        *
-        * set_uncached_handler() is used here because:
-        *  - CPU1 will run this from uncached space
-        *  - None of the cacheflush functions are set up yet
-        */
-       set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
-               &bmips_smp_int_vec, 0x80);
-       __sync();
-       return;
-#elif defined(CONFIG_CPU_BMIPS4380)
-       /*
-        * 0x8000_0000: reset/NMI (initially in kseg1)
-        * 0x8000_0400: normal vectors
-        */
-       new_ebase = 0x80000400;
-       cbr = BMIPS_GET_CBR();
-       __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
-       __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
-#elif defined(CONFIG_CPU_BMIPS5000)
-       /*
-        * 0x8000_0000: reset/NMI (initially in kseg1)
-        * 0x8000_1000: normal vectors
-        */
-       new_ebase = 0x80001000;
-       write_c0_brcm_bootvec(0xa0088008);
-       write_c0_ebase(new_ebase);
-       if (max_cpus > 2)
-               bmips_write_zscm_reg(0xa0, 0xa008a008);
-#else
-       return;
-#endif
+       switch (current_cpu_type()) {
+       case CPU_BMIPS4350:
+               /*
+                * BMIPS4350 cannot relocate the normal vectors, but it
+                * can relocate the BEV=1 vectors.  So CPU1 starts up at
+                * the relocated BEV=1, IV=0 general exception vector @
+                * 0xa000_0380.
+                *
+                * set_uncached_handler() is used here because:
+                *  - CPU1 will run this from uncached space
+                *  - None of the cacheflush functions are set up yet
+                */
+               set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
+                       &bmips_smp_int_vec, 0x80);
+               __sync();
+               return;
+       case CPU_BMIPS4380:
+               /*
+                * 0x8000_0000: reset/NMI (initially in kseg1)
+                * 0x8000_0400: normal vectors
+                */
+               new_ebase = 0x80000400;
+               cbr = BMIPS_GET_CBR();
+               __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
+               __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+               break;
+       case CPU_BMIPS5000:
+               /*
+                * 0x8000_0000: reset/NMI (initially in kseg1)
+                * 0x8000_1000: normal vectors
+                */
+               new_ebase = 0x80001000;
+               write_c0_brcm_bootvec(0xa0088008);
+               write_c0_ebase(new_ebase);
+               if (max_cpus > 2)
+                       bmips_write_zscm_reg(0xa0, 0xa008a008);
+               break;
+       default:
+               return;
+       }
+
        board_nmi_handler_setup = &bmips_nmi_handler_setup;
        ebase = new_ebase;
 }
index 5969f1e..1b925d8 100644 (file)
@@ -199,11 +199,14 @@ void __init cmp_prepare_cpus(unsigned int max_cpus)
        pr_debug("SMPCMP: CPU%d: %s max_cpus=%d\n",
                 smp_processor_id(), __func__, max_cpus);
 
+#ifdef CONFIG_MIPS_MT
        /*
         * FIXME: some of these options are per-system, some per-core and
         * some per-cpu
         */
        mips_mt_set_cpuoptions();
+#endif
+
 }
 
 struct plat_smp_ops cmp_smp_ops = {
index 57a3f7a..0fb8cef 100644 (file)
@@ -71,6 +71,7 @@ static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,
 
                /* Record this as available CPU */
                set_cpu_possible(tc, true);
+               set_cpu_present(tc, true);
                __cpu_number_map[tc]    = ++ncpu;
                __cpu_logical_map[ncpu] = tc;
        }
@@ -112,12 +113,39 @@ static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)
        write_tc_c0_tchalt(TCHALT_H);
 }
 
+#ifdef CONFIG_IRQ_GIC
+static void mp_send_ipi_single(int cpu, unsigned int action)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+       switch (action) {
+       case SMP_CALL_FUNCTION:
+               gic_send_ipi(plat_ipi_call_int_xlate(cpu));
+               break;
+
+       case SMP_RESCHEDULE_YOURSELF:
+               gic_send_ipi(plat_ipi_resched_int_xlate(cpu));
+               break;
+       }
+
+       local_irq_restore(flags);
+}
+#endif
+
 static void vsmp_send_ipi_single(int cpu, unsigned int action)
 {
        int i;
        unsigned long flags;
        int vpflags;
 
+#ifdef CONFIG_IRQ_GIC
+       if (gic_present) {
+               mp_send_ipi_single(cpu, action);
+               return;
+       }
+#endif
        local_irq_save(flags);
 
        vpflags = dvpe();       /* can't access the other CPU's registers whilst MVPE enabled */
index 93f8681..b242e2c 100644 (file)
@@ -8,7 +8,6 @@
  *
  * Copyright (C) 2007, 2008 MIPS Technologies, Inc.
  */
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
 #include <linux/stddef.h>
@@ -206,6 +205,8 @@ void spram_config(void)
        case CPU_34K:
        case CPU_74K:
        case CPU_1004K:
+       case CPU_INTERAPTIV:
+       case CPU_PROAPTIV:
                config0 = read_c0_config();
                /* FIXME: addresses are Malta specific */
                if (config0 & (1<<24)) {
index 84536bf..c24ad5f 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/irqflags.h>
 #include <linux/cpumask.h>
 
index f9c8746..e0b4996 100644 (file)
@@ -78,6 +78,7 @@ extern asmlinkage void handle_cpu(void);
 extern asmlinkage void handle_ov(void);
 extern asmlinkage void handle_tr(void);
 extern asmlinkage void handle_fpe(void);
+extern asmlinkage void handle_ftlb(void);
 extern asmlinkage void handle_mdmx(void);
 extern asmlinkage void handle_watch(void);
 extern asmlinkage void handle_mt(void);
@@ -1080,7 +1081,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
        unsigned long old_epc, old31;
        unsigned int opcode;
        unsigned int cpid;
-       int status;
+       int status, err;
        unsigned long __maybe_unused flags;
 
        prev_state = exception_enter();
@@ -1153,19 +1154,19 @@ asmlinkage void do_cpu(struct pt_regs *regs)
 
        case 1:
                if (used_math())        /* Using the FPU again.  */
-                       own_fpu(1);
+                       err = own_fpu(1);
                else {                  /* First time FPU user.  */
-                       init_fpu();
+                       err = init_fpu();
                        set_used_math();
                }
 
-               if (!raw_cpu_has_fpu) {
+               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))
+                       if (!process_fpemu_return(sig, fault_addr) && !err)
                                mt_ase_fp_affinity();
                }
 
@@ -1336,6 +1337,8 @@ static inline void parity_protection_init(void)
        case CPU_34K:
        case CPU_74K:
        case CPU_1004K:
+       case CPU_INTERAPTIV:
+       case CPU_PROAPTIV:
                {
 #define ERRCTL_PE      0x80000000
 #define ERRCTL_L2P     0x00800000
@@ -1425,14 +1428,27 @@ asmlinkage void cache_parity_error(void)
        printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
               reg_val & (1<<30) ? "secondary" : "primary",
               reg_val & (1<<31) ? "data" : "insn");
-       printk("Error bits: %s%s%s%s%s%s%s\n",
-              reg_val & (1<<29) ? "ED " : "",
-              reg_val & (1<<28) ? "ET " : "",
-              reg_val & (1<<26) ? "EE " : "",
-              reg_val & (1<<25) ? "EB " : "",
-              reg_val & (1<<24) ? "EI " : "",
-              reg_val & (1<<23) ? "E1 " : "",
-              reg_val & (1<<22) ? "E0 " : "");
+       if (cpu_has_mips_r2 &&
+           ((current_cpu_data.processor_id && 0xff0000) == PRID_COMP_MIPS)) {
+               pr_err("Error bits: %s%s%s%s%s%s%s%s\n",
+                       reg_val & (1<<29) ? "ED " : "",
+                       reg_val & (1<<28) ? "ET " : "",
+                       reg_val & (1<<27) ? "ES " : "",
+                       reg_val & (1<<26) ? "EE " : "",
+                       reg_val & (1<<25) ? "EB " : "",
+                       reg_val & (1<<24) ? "EI " : "",
+                       reg_val & (1<<23) ? "E1 " : "",
+                       reg_val & (1<<22) ? "E0 " : "");
+       } else {
+               pr_err("Error bits: %s%s%s%s%s%s%s\n",
+                       reg_val & (1<<29) ? "ED " : "",
+                       reg_val & (1<<28) ? "ET " : "",
+                       reg_val & (1<<26) ? "EE " : "",
+                       reg_val & (1<<25) ? "EB " : "",
+                       reg_val & (1<<24) ? "EI " : "",
+                       reg_val & (1<<23) ? "E1 " : "",
+                       reg_val & (1<<22) ? "E0 " : "");
+       }
        printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
 
 #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
@@ -1446,6 +1462,34 @@ asmlinkage void cache_parity_error(void)
        panic("Can't handle the cache error!");
 }
 
+asmlinkage void do_ftlb(void)
+{
+       const int field = 2 * sizeof(unsigned long);
+       unsigned int reg_val;
+
+       /* For the moment, report the problem and hang. */
+       if (cpu_has_mips_r2 &&
+           ((current_cpu_data.processor_id && 0xff0000) == PRID_COMP_MIPS)) {
+               pr_err("FTLB error exception, cp0_ecc=0x%08x:\n",
+                      read_c0_ecc());
+               pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
+               reg_val = read_c0_cacheerr();
+               pr_err("c0_cacheerr == %08x\n", reg_val);
+
+               if ((reg_val & 0xc0000000) == 0xc0000000) {
+                       pr_err("Decoded c0_cacheerr: FTLB parity error\n");
+               } else {
+                       pr_err("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
+                              reg_val & (1<<30) ? "secondary" : "primary",
+                              reg_val & (1<<31) ? "data" : "insn");
+               }
+       } else {
+               pr_err("FTLB error exception\n");
+       }
+       /* Just print the cacheerr bits for now */
+       cache_parity_error();
+}
+
 /*
  * SDBBP EJTAG debug exception handler.
  * We skip the instruction and return to the next instruction.
@@ -1995,6 +2039,7 @@ void __init trap_init(void)
        if (cpu_has_fpu && !cpu_has_nofpuex)
                set_except_vector(15, handle_fpe);
 
+       set_except_vector(16, handle_ftlb);
        set_except_vector(22, handle_mdmx);
 
        if (cpu_has_mcheck)
diff --git a/arch/mips/kernel/vpe-cmp.c b/arch/mips/kernel/vpe-cmp.c
new file mode 100644 (file)
index 0000000..9268ebc
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ */
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+
+#include <asm/vpe.h>
+
+static int major;
+
+void cleanup_tc(struct tc *tc)
+{
+
+}
+
+static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t len)
+{
+       struct vpe *vpe = get_vpe(aprp_cpu_index());
+       struct vpe_notifications *notifier;
+
+       list_for_each_entry(notifier, &vpe->notify, list)
+               notifier->stop(aprp_cpu_index());
+
+       release_progmem(vpe->load_addr);
+       vpe->state = VPE_STATE_UNUSED;
+
+       return len;
+}
+static DEVICE_ATTR(kill, S_IWUSR, NULL, store_kill);
+
+static ssize_t ntcs_show(struct device *cd, struct device_attribute *attr,
+                        char *buf)
+{
+       struct vpe *vpe = get_vpe(aprp_cpu_index());
+
+       return sprintf(buf, "%d\n", vpe->ntcs);
+}
+
+static ssize_t ntcs_store(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t len)
+{
+       struct vpe *vpe = get_vpe(aprp_cpu_index());
+       unsigned long new;
+       int ret;
+
+       ret = kstrtoul(buf, 0, &new);
+       if (ret < 0)
+               return ret;
+
+       /* APRP can only reserve one TC in a VPE and no more. */
+       if (new != 1)
+               return -EINVAL;
+
+       vpe->ntcs = new;
+
+       return len;
+}
+static DEVICE_ATTR_RW(ntcs);
+
+static struct attribute *vpe_attrs[] = {
+       &dev_attr_kill.attr,
+       &dev_attr_ntcs.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(vpe);
+
+static void vpe_device_release(struct device *cd)
+{
+       kfree(cd);
+}
+
+static struct class vpe_class = {
+       .name = "vpe",
+       .owner = THIS_MODULE,
+       .dev_release = vpe_device_release,
+       .dev_groups = vpe_groups,
+};
+
+static struct device vpe_device;
+
+int __init vpe_module_init(void)
+{
+       struct vpe *v = NULL;
+       struct tc *t;
+       int err;
+
+       if (!cpu_has_mipsmt) {
+               pr_warn("VPE loader: not a MIPS MT capable processor\n");
+               return -ENODEV;
+       }
+
+       if (num_possible_cpus() - aprp_cpu_index() < 1) {
+               pr_warn("No VPEs reserved for AP/SP, not initialize VPE loader\n"
+                       "Pass maxcpus=<n> argument as kernel argument\n");
+               return -ENODEV;
+       }
+
+       major = register_chrdev(0, VPE_MODULE_NAME, &vpe_fops);
+       if (major < 0) {
+               pr_warn("VPE loader: unable to register character device\n");
+               return major;
+       }
+
+       err = class_register(&vpe_class);
+       if (err) {
+               pr_err("vpe_class registration failed\n");
+               goto out_chrdev;
+       }
+
+       device_initialize(&vpe_device);
+       vpe_device.class        = &vpe_class,
+       vpe_device.parent       = NULL,
+       dev_set_name(&vpe_device, "vpe_sp");
+       vpe_device.devt = MKDEV(major, VPE_MODULE_MINOR);
+       err = device_add(&vpe_device);
+       if (err) {
+               pr_err("Adding vpe_device failed\n");
+               goto out_class;
+       }
+
+       t = alloc_tc(aprp_cpu_index());
+       if (!t) {
+               pr_warn("VPE: unable to allocate TC\n");
+               err = -ENOMEM;
+               goto out_dev;
+       }
+
+       /* VPE */
+       v = alloc_vpe(aprp_cpu_index());
+       if (v == NULL) {
+               pr_warn("VPE: unable to allocate VPE\n");
+               kfree(t);
+               err = -ENOMEM;
+               goto out_dev;
+       }
+
+       v->ntcs = 1;
+
+       /* add the tc to the list of this vpe's tc's. */
+       list_add(&t->tc, &v->tc);
+
+       /* TC */
+       t->pvpe = v;    /* set the parent vpe */
+
+       return 0;
+
+out_dev:
+       device_del(&vpe_device);
+
+out_class:
+       class_unregister(&vpe_class);
+
+out_chrdev:
+       unregister_chrdev(major, VPE_MODULE_NAME);
+
+       return err;
+}
+
+void __exit vpe_module_exit(void)
+{
+       struct vpe *v, *n;
+
+       device_del(&vpe_device);
+       class_unregister(&vpe_class);
+       unregister_chrdev(major, VPE_MODULE_NAME);
+
+       /* No locking needed here */
+       list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list)
+               if (v->state != VPE_STATE_UNUSED)
+                       release_vpe(v);
+}
diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c
new file mode 100644 (file)
index 0000000..949ae0e
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
+ */
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <asm/mips_mt.h>
+#include <asm/vpe.h>
+
+static int major;
+
+/* The number of TCs and VPEs physically available on the core */
+static int hw_tcs, hw_vpes;
+
+/* We are prepared so configure and start the VPE... */
+int vpe_run(struct vpe *v)
+{
+       unsigned long flags, val, dmt_flag;
+       struct vpe_notifications *notifier;
+       unsigned int vpeflags;
+       struct tc *t;
+
+       /* check we are the Master VPE */
+       local_irq_save(flags);
+       val = read_c0_vpeconf0();
+       if (!(val & VPECONF0_MVP)) {
+               pr_warn("VPE loader: only Master VPE's are able to config MT\n");
+               local_irq_restore(flags);
+
+               return -1;
+       }
+
+       dmt_flag = dmt();
+       vpeflags = dvpe();
+
+       if (list_empty(&v->tc)) {
+               evpe(vpeflags);
+               emt(dmt_flag);
+               local_irq_restore(flags);
+
+               pr_warn("VPE loader: No TC's associated with VPE %d\n",
+                       v->minor);
+
+               return -ENOEXEC;
+       }
+
+       t = list_first_entry(&v->tc, struct tc, tc);
+
+       /* Put MVPE's into 'configuration state' */
+       set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+       settc(t->index);
+
+       /* should check it is halted, and not activated */
+       if ((read_tc_c0_tcstatus() & TCSTATUS_A) ||
+          !(read_tc_c0_tchalt() & TCHALT_H)) {
+               evpe(vpeflags);
+               emt(dmt_flag);
+               local_irq_restore(flags);
+
+               pr_warn("VPE loader: TC %d is already active!\n",
+                       t->index);
+
+               return -ENOEXEC;
+       }
+
+       /*
+        * Write the address we want it to start running from in the TCPC
+        * register.
+        */
+       write_tc_c0_tcrestart((unsigned long)v->__start);
+       write_tc_c0_tccontext((unsigned long)0);
+
+       /*
+        * Mark the TC as activated, not interrupt exempt and not dynamically
+        * allocatable
+        */
+       val = read_tc_c0_tcstatus();
+       val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A;
+       write_tc_c0_tcstatus(val);
+
+       write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
+
+       /*
+        * The sde-kit passes 'memsize' to __start in $a3, so set something
+        * here...  Or set $a3 to zero and define DFLT_STACK_SIZE and
+        * DFLT_HEAP_SIZE when you compile your program
+        */
+       mttgpr(6, v->ntcs);
+       mttgpr(7, physical_memsize);
+
+       /* set up VPE1 */
+       /*
+        * bind the TC to VPE 1 as late as possible so we only have the final
+        * VPE registers to set up, and so an EJTAG probe can trigger on it
+        */
+       write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | 1);
+
+       write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~(VPECONF0_VPA));
+
+       back_to_back_c0_hazard();
+
+       /* Set up the XTC bit in vpeconf0 to point at our tc */
+       write_vpe_c0_vpeconf0((read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC))
+                             | (t->index << VPECONF0_XTC_SHIFT));
+
+       back_to_back_c0_hazard();
+
+       /* enable this VPE */
+       write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
+
+       /* clear out any left overs from a previous program */
+       write_vpe_c0_status(0);
+       write_vpe_c0_cause(0);
+
+       /* take system out of configuration state */
+       clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+       /*
+        * SMTC/SMVP kernels manage VPE enable independently,
+        * but uniprocessor kernels need to turn it on, even
+        * if that wasn't the pre-dvpe() state.
+        */
+#ifdef CONFIG_SMP
+       evpe(vpeflags);
+#else
+       evpe(EVPE_ENABLE);
+#endif
+       emt(dmt_flag);
+       local_irq_restore(flags);
+
+       list_for_each_entry(notifier, &v->notify, list)
+               notifier->start(VPE_MODULE_MINOR);
+
+       return 0;
+}
+
+void cleanup_tc(struct tc *tc)
+{
+       unsigned long flags;
+       unsigned int mtflags, vpflags;
+       int tmp;
+
+       local_irq_save(flags);
+       mtflags = dmt();
+       vpflags = dvpe();
+       /* Put MVPE's into 'configuration state' */
+       set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+       settc(tc->index);
+       tmp = read_tc_c0_tcstatus();
+
+       /* mark not allocated and not dynamically allocatable */
+       tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+       tmp |= TCSTATUS_IXMT;   /* interrupt exempt */
+       write_tc_c0_tcstatus(tmp);
+
+       write_tc_c0_tchalt(TCHALT_H);
+       mips_ihb();
+
+       clear_c0_mvpcontrol(MVPCONTROL_VPC);
+       evpe(vpflags);
+       emt(mtflags);
+       local_irq_restore(flags);
+}
+
+/* module wrapper entry points */
+/* give me a vpe */
+void *vpe_alloc(void)
+{
+       int i;
+       struct vpe *v;
+
+       /* find a vpe */
+       for (i = 1; i < MAX_VPES; i++) {
+               v = get_vpe(i);
+               if (v != NULL) {
+                       v->state = VPE_STATE_INUSE;
+                       return v;
+               }
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(vpe_alloc);
+
+/* start running from here */
+int vpe_start(void *vpe, unsigned long start)
+{
+       struct vpe *v = vpe;
+
+       v->__start = start;
+       return vpe_run(v);
+}
+EXPORT_SYMBOL(vpe_start);
+
+/* halt it for now */
+int vpe_stop(void *vpe)
+{
+       struct vpe *v = vpe;
+       struct tc *t;
+       unsigned int evpe_flags;
+
+       evpe_flags = dvpe();
+
+       t = list_entry(v->tc.next, struct tc, tc);
+       if (t != NULL) {
+               settc(t->index);
+               write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
+       }
+
+       evpe(evpe_flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(vpe_stop);
+
+/* I've done with it thank you */
+int vpe_free(void *vpe)
+{
+       struct vpe *v = vpe;
+       struct tc *t;
+       unsigned int evpe_flags;
+
+       t = list_entry(v->tc.next, struct tc, tc);
+       if (t == NULL)
+               return -ENOEXEC;
+
+       evpe_flags = dvpe();
+
+       /* Put MVPE's into 'configuration state' */
+       set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+       settc(t->index);
+       write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
+
+       /* halt the TC */
+       write_tc_c0_tchalt(TCHALT_H);
+       mips_ihb();
+
+       /* mark the TC unallocated */
+       write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
+
+       v->state = VPE_STATE_UNUSED;
+
+       clear_c0_mvpcontrol(MVPCONTROL_VPC);
+       evpe(evpe_flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(vpe_free);
+
+static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t len)
+{
+       struct vpe *vpe = get_vpe(aprp_cpu_index());
+       struct vpe_notifications *notifier;
+
+       list_for_each_entry(notifier, &vpe->notify, list)
+               notifier->stop(aprp_cpu_index());
+
+       release_progmem(vpe->load_addr);
+       cleanup_tc(get_tc(aprp_cpu_index()));
+       vpe_stop(vpe);
+       vpe_free(vpe);
+
+       return len;
+}
+static DEVICE_ATTR(kill, S_IWUSR, NULL, store_kill);
+
+static ssize_t ntcs_show(struct device *cd, struct device_attribute *attr,
+                        char *buf)
+{
+       struct vpe *vpe = get_vpe(aprp_cpu_index());
+
+       return sprintf(buf, "%d\n", vpe->ntcs);
+}
+
+static ssize_t ntcs_store(struct device *dev, struct device_attribute *attr,
+                         const char *buf, size_t len)
+{
+       struct vpe *vpe = get_vpe(aprp_cpu_index());
+       unsigned long new;
+       int ret;
+
+       ret = kstrtoul(buf, 0, &new);
+       if (ret < 0)
+               return ret;
+
+       if (new == 0 || new > (hw_tcs - aprp_cpu_index()))
+               return -EINVAL;
+
+       vpe->ntcs = new;
+
+       return len;
+}
+static DEVICE_ATTR_RW(ntcs);
+
+static struct attribute *vpe_attrs[] = {
+       &dev_attr_kill.attr,
+       &dev_attr_ntcs.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(vpe);
+
+static void vpe_device_release(struct device *cd)
+{
+       kfree(cd);
+}
+
+static struct class vpe_class = {
+       .name = "vpe",
+       .owner = THIS_MODULE,
+       .dev_release = vpe_device_release,
+       .dev_groups = vpe_groups,
+};
+
+static struct device vpe_device;
+
+int __init vpe_module_init(void)
+{
+       unsigned int mtflags, vpflags;
+       unsigned long flags, val;
+       struct vpe *v = NULL;
+       struct tc *t;
+       int tc, err;
+
+       if (!cpu_has_mipsmt) {
+               pr_warn("VPE loader: not a MIPS MT capable processor\n");
+               return -ENODEV;
+       }
+
+       if (vpelimit == 0) {
+               pr_warn("No VPEs reserved for AP/SP, not initialize VPE loader\n"
+                       "Pass maxvpes=<n> argument as kernel argument\n");
+
+               return -ENODEV;
+       }
+
+       if (aprp_cpu_index() == 0) {
+               pr_warn("No TCs reserved for AP/SP, not initialize VPE loader\n"
+                       "Pass maxtcs=<n> argument as kernel argument\n");
+
+               return -ENODEV;
+       }
+
+       major = register_chrdev(0, VPE_MODULE_NAME, &vpe_fops);
+       if (major < 0) {
+               pr_warn("VPE loader: unable to register character device\n");
+               return major;
+       }
+
+       err = class_register(&vpe_class);
+       if (err) {
+               pr_err("vpe_class registration failed\n");
+               goto out_chrdev;
+       }
+
+       device_initialize(&vpe_device);
+       vpe_device.class        = &vpe_class,
+       vpe_device.parent       = NULL,
+       dev_set_name(&vpe_device, "vpe1");
+       vpe_device.devt = MKDEV(major, VPE_MODULE_MINOR);
+       err = device_add(&vpe_device);
+       if (err) {
+               pr_err("Adding vpe_device failed\n");
+               goto out_class;
+       }
+
+       local_irq_save(flags);
+       mtflags = dmt();
+       vpflags = dvpe();
+
+       /* Put MVPE's into 'configuration state' */
+       set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+       val = read_c0_mvpconf0();
+       hw_tcs = (val & MVPCONF0_PTC) + 1;
+       hw_vpes = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
+
+       for (tc = aprp_cpu_index(); tc < hw_tcs; tc++) {
+               /*
+                * Must re-enable multithreading temporarily or in case we
+                * reschedule send IPIs or similar we might hang.
+                */
+               clear_c0_mvpcontrol(MVPCONTROL_VPC);
+               evpe(vpflags);
+               emt(mtflags);
+               local_irq_restore(flags);
+               t = alloc_tc(tc);
+               if (!t) {
+                       err = -ENOMEM;
+                       goto out_dev;
+               }
+
+               local_irq_save(flags);
+               mtflags = dmt();
+               vpflags = dvpe();
+               set_c0_mvpcontrol(MVPCONTROL_VPC);
+
+               /* VPE's */
+               if (tc < hw_tcs) {
+                       settc(tc);
+
+                       v = alloc_vpe(tc);
+                       if (v == NULL) {
+                               pr_warn("VPE: unable to allocate VPE\n");
+                               goto out_reenable;
+                       }
+
+                       v->ntcs = hw_tcs - aprp_cpu_index();
+
+                       /* add the tc to the list of this vpe's tc's. */
+                       list_add(&t->tc, &v->tc);
+
+                       /* deactivate all but vpe0 */
+                       if (tc >= aprp_cpu_index()) {
+                               unsigned long tmp = read_vpe_c0_vpeconf0();
+
+                               tmp &= ~VPECONF0_VPA;
+
+                               /* master VPE */
+                               tmp |= VPECONF0_MVP;
+                               write_vpe_c0_vpeconf0(tmp);
+                       }
+
+                       /* disable multi-threading with TC's */
+                       write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() &
+                                               ~VPECONTROL_TE);
+
+                       if (tc >= vpelimit) {
+                               /*
+                                * Set config to be the same as vpe0,
+                                * particularly kseg0 coherency alg
+                                */
+                               write_vpe_c0_config(read_c0_config());
+                       }
+               }
+
+               /* TC's */
+               t->pvpe = v;    /* set the parent vpe */
+
+               if (tc >= aprp_cpu_index()) {
+                       unsigned long tmp;
+
+                       settc(tc);
+
+                       /* Any TC that is bound to VPE0 gets left as is - in
+                        * case we are running SMTC on VPE0. A TC that is bound
+                        * to any other VPE gets bound to VPE0, ideally I'd like
+                        * to make it homeless but it doesn't appear to let me
+                        * bind a TC to a non-existent VPE. Which is perfectly
+                        * reasonable.
+                        *
+                        * The (un)bound state is visible to an EJTAG probe so
+                        * may notify GDB...
+                        */
+                       tmp = read_tc_c0_tcbind();
+                       if (tmp & TCBIND_CURVPE) {
+                               /* tc is bound >vpe0 */
+                               write_tc_c0_tcbind(tmp & ~TCBIND_CURVPE);
+
+                               t->pvpe = get_vpe(0);   /* set the parent vpe */
+                       }
+
+                       /* halt the TC */
+                       write_tc_c0_tchalt(TCHALT_H);
+                       mips_ihb();
+
+                       tmp = read_tc_c0_tcstatus();
+
+                       /* mark not activated and not dynamically allocatable */
+                       tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+                       tmp |= TCSTATUS_IXMT;   /* interrupt exempt */
+                       write_tc_c0_tcstatus(tmp);
+               }
+       }
+
+out_reenable:
+       /* release config state */
+       clear_c0_mvpcontrol(MVPCONTROL_VPC);
+
+       evpe(vpflags);
+       emt(mtflags);
+       local_irq_restore(flags);
+
+       return 0;
+
+out_dev:
+       device_del(&vpe_device);
+
+out_class:
+       class_unregister(&vpe_class);
+
+out_chrdev:
+       unregister_chrdev(major, VPE_MODULE_NAME);
+
+       return err;
+}
+
+void __exit vpe_module_exit(void)
+{
+       struct vpe *v, *n;
+
+       device_del(&vpe_device);
+       class_unregister(&vpe_class);
+       unregister_chrdev(major, VPE_MODULE_NAME);
+
+       /* No locking needed here */
+       list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
+               if (v->state != VPE_STATE_UNUSED)
+                       release_vpe(v);
+       }
+}
index 2d5c142..11da314 100644 (file)
@@ -1,37 +1,22 @@
 /*
- * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-
-/*
- * VPE support module
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- * Provides support for loading a MIPS SP program on VPE1.
- * The SP environment is rather simple, no tlb's.  It needs to be relocatable
- * (or partially linked). You should initialise your stack in the startup
- * code. This loader looks for the symbol __start and sets up
- * execution to resume from there. The MIPS SDE kit contains suitable examples.
+ * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
  *
- * To load and run, simply cat a SP 'program file' to /dev/vpe1.
- * i.e cat spapp >/dev/vpe1.
+ * VPE spport module for loading a MIPS SP program into VPE1. The SP
+ * environment is rather simple since there are no TLBs. It needs
+ * to be relocatable (or partiall linked). Initialize your stack in
+ * the startup-code. The loader looks for the symbol __start and sets
+ * up the execution to resume from there. To load and run, simply do
+ * a cat SP 'binary' to the /dev/vpe1 device.
  */
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/init.h>
-#include <asm/uaccess.h>
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/vmalloc.h>
 #include <asm/mipsmtregs.h>
 #include <asm/cacheflush.h>
 #include <linux/atomic.h>
-#include <asm/cpu.h>
 #include <asm/mips_mt.h>
 #include <asm/processor.h>
 #include <asm/vpe.h>
 
-typedef void *vpe_handle;
-
 #ifndef ARCH_SHF_SMALL
 #define ARCH_SHF_SMALL 0
 #endif
@@ -60,95 +42,15 @@ typedef void *vpe_handle;
 /* If this is set, the section belongs in the init part of the module */
 #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
 
-/*
- * The number of TCs and VPEs physically available on the core
- */
-static int hw_tcs, hw_vpes;
-static char module_name[] = "vpe";
-static int major;
-static const int minor = 1;    /* fixed for now  */
-
-/* grab the likely amount of memory we will need. */
-#ifdef CONFIG_MIPS_VPE_LOADER_TOM
-#define P_SIZE (2 * 1024 * 1024)
-#else
-/* add an overhead to the max kmalloc size for non-striped symbols/etc */
-#define P_SIZE (256 * 1024)
-#endif
-
-extern unsigned long physical_memsize;
-
-#define MAX_VPES 16
-#define VPE_PATH_MAX 256
-
-enum vpe_state {
-       VPE_STATE_UNUSED = 0,
-       VPE_STATE_INUSE,
-       VPE_STATE_RUNNING
-};
-
-enum tc_state {
-       TC_STATE_UNUSED = 0,
-       TC_STATE_INUSE,
-       TC_STATE_RUNNING,
-       TC_STATE_DYNAMIC
-};
-
-struct vpe {
-       enum vpe_state state;
-
-       /* (device) minor associated with this vpe */
-       int minor;
-
-       /* elfloader stuff */
-       void *load_addr;
-       unsigned long len;
-       char *pbuffer;
-       unsigned long plen;
-       char cwd[VPE_PATH_MAX];
-
-       unsigned long __start;
-
-       /* tc's associated with this vpe */
-       struct list_head tc;
-
-       /* The list of vpe's */
-       struct list_head list;
-
-       /* shared symbol address */
-       void *shared_ptr;
-
-       /* the list of who wants to know when something major happens */
-       struct list_head notify;
-
-       unsigned int ntcs;
-};
-
-struct tc {
-       enum tc_state state;
-       int index;
-
-       struct vpe *pvpe;       /* parent VPE */
-       struct list_head tc;    /* The list of TC's with this VPE */
-       struct list_head list;  /* The global list of tc's */
-};
-
-struct {
-       spinlock_t vpe_list_lock;
-       struct list_head vpe_list;      /* Virtual processing elements */
-       spinlock_t tc_list_lock;
-       struct list_head tc_list;       /* Thread contexts */
-} vpecontrol = {
+struct vpe_control vpecontrol = {
        .vpe_list_lock  = __SPIN_LOCK_UNLOCKED(vpe_list_lock),
        .vpe_list       = LIST_HEAD_INIT(vpecontrol.vpe_list),
        .tc_list_lock   = __SPIN_LOCK_UNLOCKED(tc_list_lock),
        .tc_list        = LIST_HEAD_INIT(vpecontrol.tc_list)
 };
 
-static void release_progmem(void *ptr);
-
 /* get the vpe associated with this minor */
-static struct vpe *get_vpe(int minor)
+struct vpe *get_vpe(int minor)
 {
        struct vpe *res, *v;
 
@@ -158,7 +60,7 @@ static struct vpe *get_vpe(int minor)
        res = NULL;
        spin_lock(&vpecontrol.vpe_list_lock);
        list_for_each_entry(v, &vpecontrol.vpe_list, list) {
-               if (v->minor == minor) {
+               if (v->minor == VPE_MODULE_MINOR) {
                        res = v;
                        break;
                }
@@ -169,7 +71,7 @@ static struct vpe *get_vpe(int minor)
 }
 
 /* get the vpe associated with this minor */
-static struct tc *get_tc(int index)
+struct tc *get_tc(int index)
 {
        struct tc *res, *t;
 
@@ -187,12 +89,13 @@ static struct tc *get_tc(int index)
 }
 
 /* allocate a vpe and associate it with this minor (or index) */
-static struct vpe *alloc_vpe(int minor)
+struct vpe *alloc_vpe(int minor)
 {
        struct vpe *v;
 
-       if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL)
-               return NULL;
+       v = kzalloc(sizeof(struct vpe), GFP_KERNEL);
+       if (v == NULL)
+               goto out;
 
        INIT_LIST_HEAD(&v->tc);
        spin_lock(&vpecontrol.vpe_list_lock);
@@ -200,17 +103,19 @@ static struct vpe *alloc_vpe(int minor)
        spin_unlock(&vpecontrol.vpe_list_lock);
 
        INIT_LIST_HEAD(&v->notify);
-       v->minor = minor;
+       v->minor = VPE_MODULE_MINOR;
 
+out:
        return v;
 }
 
 /* allocate a tc. At startup only tc0 is running, all other can be halted. */
-static struct tc *alloc_tc(int index)
+struct tc *alloc_tc(int index)
 {
        struct tc *tc;
 
-       if ((tc = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL)
+       tc = kzalloc(sizeof(struct tc), GFP_KERNEL);
+       if (tc == NULL)
                goto out;
 
        INIT_LIST_HEAD(&tc->tc);
@@ -225,7 +130,7 @@ out:
 }
 
 /* clean up and free everything */
-static void release_vpe(struct vpe *v)
+void release_vpe(struct vpe *v)
 {
        list_del(&v->list);
        if (v->load_addr)
@@ -233,28 +138,8 @@ static void release_vpe(struct vpe *v)
        kfree(v);
 }
 
-static void __maybe_unused dump_mtregs(void)
-{
-       unsigned long val;
-
-       val = read_c0_config3();
-       printk("config3 0x%lx MT %ld\n", val,
-              (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT);
-
-       val = read_c0_mvpcontrol();
-       printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val,
-              (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT,
-              (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT,
-              (val & MVPCONTROL_EVP));
-
-       val = read_c0_mvpconf0();
-       printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val,
-              (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT,
-              val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
-}
-
-/* Find some VPE program space */
-static void *alloc_progmem(unsigned long len)
+/* Find some VPE program space */
+void *alloc_progmem(unsigned long len)
 {
        void *addr;
 
@@ -273,7 +158,7 @@ static void *alloc_progmem(unsigned long len)
        return addr;
 }
 
-static void release_progmem(void *ptr)
+void release_progmem(void *ptr)
 {
 #ifndef CONFIG_MIPS_VPE_LOADER_TOM
        kfree(ptr);
@@ -281,7 +166,7 @@ static void release_progmem(void *ptr)
 }
 
 /* Update size with this section: return offset. */
-static long get_offset(unsigned long *size, Elf_Shdr * sechdr)
+static long get_offset(unsigned long *size, Elf_Shdr *sechdr)
 {
        long ret;
 
@@ -294,8 +179,8 @@ static long get_offset(unsigned long *size, Elf_Shdr * sechdr)
    might -- code, read-only data, read-write data, small data. Tally
    sizes, and place the offsets into sh_entsize fields: high bit means it
    belongs in init. */
-static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
-                           Elf_Shdr * sechdrs, const char *secstrings)
+static void layout_sections(struct module *mod, const Elf_Ehdr *hdr,
+                           Elf_Shdr *sechdrs, const char *secstrings)
 {
        static unsigned long const masks[][2] = {
                /* NOTE: all executable code must be the first section
@@ -315,7 +200,6 @@ static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
                for (i = 0; i < hdr->e_shnum; ++i) {
                        Elf_Shdr *s = &sechdrs[i];
 
-                       //  || strncmp(secstrings + s->sh_name, ".init", 5) == 0)
                        if ((s->sh_flags & masks[m][0]) != masks[m][0]
                            || (s->sh_flags & masks[m][1])
                            || s->sh_entsize != ~0UL)
@@ -330,7 +214,6 @@ static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
        }
 }
 
-
 /* from module-elf32.c, but subverted a little */
 
 struct mips_hi16 {
@@ -353,20 +236,18 @@ static int apply_r_mips_gprel16(struct module *me, uint32_t *location,
 {
        int rel;
 
-       if( !(*location & 0xffff) ) {
+       if (!(*location & 0xffff)) {
                rel = (int)v - gp_addr;
-       }
-       else {
+       } else {
                /* .sbss + gp(relative) + offset */
                /* kludge! */
                rel =  (int)(short)((int)v + gp_offs +
                                    (int)(short)(*location & 0xffff) - gp_addr);
        }
 
-       if( (rel > 32768) || (rel < -32768) ) {
-               printk(KERN_DEBUG "VPE loader: apply_r_mips_gprel16: "
-                      "relative address 0x%x out of range of gp register\n",
-                      rel);
+       if ((rel > 32768) || (rel < -32768)) {
+               pr_debug("VPE loader: apply_r_mips_gprel16: relative address 0x%x out of range of gp register\n",
+                        rel);
                return -ENOEXEC;
        }
 
@@ -380,12 +261,12 @@ static int apply_r_mips_pc16(struct module *me, uint32_t *location,
 {
        int rel;
        rel = (((unsigned int)v - (unsigned int)location));
-       rel >>= 2;              // because the offset is in _instructions_ not bytes.
-       rel -= 1;               // and one instruction less due to the branch delay slot.
+       rel >>= 2; /* because the offset is in _instructions_ not bytes. */
+       rel -= 1;  /* and one instruction less due to the branch delay slot. */
 
-       if( (rel > 32768) || (rel < -32768) ) {
-               printk(KERN_DEBUG "VPE loader: "
-                      "apply_r_mips_pc16: relative address out of range 0x%x\n", rel);
+       if ((rel > 32768) || (rel < -32768)) {
+               pr_debug("VPE loader: apply_r_mips_pc16: relative address out of range 0x%x\n",
+                        rel);
                return -ENOEXEC;
        }
 
@@ -406,8 +287,7 @@ static int apply_r_mips_26(struct module *me, uint32_t *location,
                           Elf32_Addr v)
 {
        if (v % 4) {
-               printk(KERN_DEBUG "VPE loader: apply_r_mips_26 "
-                      " unaligned relocation\n");
+               pr_debug("VPE loader: apply_r_mips_26: unaligned relocation\n");
                return -ENOEXEC;
        }
 
@@ -438,7 +318,7 @@ static int apply_r_mips_hi16(struct module *me, uint32_t *location,
         * the carry we need to add.  Save the information, and let LO16 do the
         * actual relocation.
         */
-       n = kmalloc(sizeof *n, GFP_KERNEL);
+       n = kmalloc(sizeof(*n), GFP_KERNEL);
        if (!n)
                return -ENOMEM;
 
@@ -470,9 +350,7 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location,
                         * The value for the HI16 had best be the same.
                         */
                        if (v != l->value) {
-                               printk(KERN_DEBUG "VPE loader: "
-                                      "apply_r_mips_lo16/hi16: \t"
-                                      "inconsistent value information\n");
+                               pr_debug("VPE loader: apply_r_mips_lo16/hi16: inconsistent value information\n");
                                goto out_free;
                        }
 
@@ -568,20 +446,19 @@ static int apply_relocations(Elf32_Shdr *sechdrs,
                        + ELF32_R_SYM(r_info);
 
                if (!sym->st_value) {
-                       printk(KERN_DEBUG "%s: undefined weak symbol %s\n",
-                              me->name, strtab + sym->st_name);
+                       pr_debug("%s: undefined weak symbol %s\n",
+                                me->name, strtab + sym->st_name);
                        /* just print the warning, dont barf */
                }
 
                v = sym->st_value;
 
                res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
-               if( res ) {
+               if (res) {
                        char *r = rstrs[ELF32_R_TYPE(r_info)];
-                       printk(KERN_WARNING "VPE loader: .text+0x%x "
-                              "relocation type %s for symbol \"%s\" failed\n",
-                              rel[i].r_offset, r ? r : "UNKNOWN",
-                              strtab + sym->st_name);
+                       pr_warn("VPE loader: .text+0x%x relocation type %s for symbol \"%s\" failed\n",
+                               rel[i].r_offset, r ? r : "UNKNOWN",
+                               strtab + sym->st_name);
                        return res;
                }
        }
@@ -596,10 +473,8 @@ static inline void save_gp_address(unsigned int secbase, unsigned int rel)
 }
 /* end module-elf32.c */
 
-
-
 /* Change all symbols so that sh_value encodes the pointer directly. */
-static void simplify_symbols(Elf_Shdr * sechdrs,
+static void simplify_symbols(Elf_Shdr *sechdrs,
                            unsigned int symindex,
                            const char *strtab,
                            const char *secstrings,
@@ -640,18 +515,16 @@ static void simplify_symbols(Elf_Shdr * sechdrs,
                        break;
 
                case SHN_MIPS_SCOMMON:
-                       printk(KERN_DEBUG "simplify_symbols: ignoring SHN_MIPS_SCOMMON "
-                              "symbol <%s> st_shndx %d\n", strtab + sym[i].st_name,
-                              sym[i].st_shndx);
-                       // .sbss section
+                       pr_debug("simplify_symbols: ignoring SHN_MIPS_SCOMMON symbol <%s> st_shndx %d\n",
+                                strtab + sym[i].st_name, sym[i].st_shndx);
+                       /* .sbss section */
                        break;
 
                default:
                        secbase = sechdrs[sym[i].st_shndx].sh_addr;
 
-                       if (strncmp(strtab + sym[i].st_name, "_gp", 3) == 0) {
+                       if (strncmp(strtab + sym[i].st_name, "_gp", 3) == 0)
                                save_gp_address(secbase, sym[i].st_value);
-                       }
 
                        sym[i].st_value += secbase;
                        break;
@@ -660,142 +533,21 @@ static void simplify_symbols(Elf_Shdr * sechdrs,
 }
 
 #ifdef DEBUG_ELFLOADER
-static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex,
+static void dump_elfsymbols(Elf_Shdr *sechdrs, unsigned int symindex,
                            const char *strtab, struct module *mod)
 {
        Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
        unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
 
-       printk(KERN_DEBUG "dump_elfsymbols: n %d\n", n);
+       pr_debug("dump_elfsymbols: n %d\n", n);
        for (i = 1; i < n; i++) {
-               printk(KERN_DEBUG " i %d name <%s> 0x%x\n", i,
-                      strtab + sym[i].st_name, sym[i].st_value);
+               pr_debug(" i %d name <%s> 0x%x\n", i, strtab + sym[i].st_name,
+                        sym[i].st_value);
        }
 }
 #endif
 
-/* We are prepared so configure and start the VPE... */
-static int vpe_run(struct vpe * v)
-{
-       unsigned long flags, val, dmt_flag;
-       struct vpe_notifications *n;
-       unsigned int vpeflags;
-       struct tc *t;
-
-       /* check we are the Master VPE */
-       local_irq_save(flags);
-       val = read_c0_vpeconf0();
-       if (!(val & VPECONF0_MVP)) {
-               printk(KERN_WARNING
-                      "VPE loader: only Master VPE's are allowed to configure MT\n");
-               local_irq_restore(flags);
-
-               return -1;
-       }
-
-       dmt_flag = dmt();
-       vpeflags = dvpe();
-
-       if (list_empty(&v->tc)) {
-               evpe(vpeflags);
-               emt(dmt_flag);
-               local_irq_restore(flags);
-
-               printk(KERN_WARNING
-                      "VPE loader: No TC's associated with VPE %d\n",
-                      v->minor);
-
-               return -ENOEXEC;
-       }
-
-       t = list_first_entry(&v->tc, struct tc, tc);
-
-       /* Put MVPE's into 'configuration state' */
-       set_c0_mvpcontrol(MVPCONTROL_VPC);
-
-       settc(t->index);
-
-       /* should check it is halted, and not activated */
-       if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) {
-               evpe(vpeflags);
-               emt(dmt_flag);
-               local_irq_restore(flags);
-
-               printk(KERN_WARNING "VPE loader: TC %d is already active!\n",
-                      t->index);
-
-               return -ENOEXEC;
-       }
-
-       /* Write the address we want it to start running from in the TCPC register. */
-       write_tc_c0_tcrestart((unsigned long)v->__start);
-       write_tc_c0_tccontext((unsigned long)0);
-
-       /*
-        * Mark the TC as activated, not interrupt exempt and not dynamically
-        * allocatable
-        */
-       val = read_tc_c0_tcstatus();
-       val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A;
-       write_tc_c0_tcstatus(val);
-
-       write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
-
-       /*
-        * The sde-kit passes 'memsize' to __start in $a3, so set something
-        * here...  Or set $a3 to zero and define DFLT_STACK_SIZE and
-        * DFLT_HEAP_SIZE when you compile your program
-        */
-       mttgpr(6, v->ntcs);
-       mttgpr(7, physical_memsize);
-
-       /* set up VPE1 */
-       /*
-        * bind the TC to VPE 1 as late as possible so we only have the final
-        * VPE registers to set up, and so an EJTAG probe can trigger on it
-        */
-       write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | 1);
-
-       write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~(VPECONF0_VPA));
-
-       back_to_back_c0_hazard();
-
-       /* Set up the XTC bit in vpeconf0 to point at our tc */
-       write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC))
-                             | (t->index << VPECONF0_XTC_SHIFT));
-
-       back_to_back_c0_hazard();
-
-       /* enable this VPE */
-       write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
-
-       /* clear out any left overs from a previous program */
-       write_vpe_c0_status(0);
-       write_vpe_c0_cause(0);
-
-       /* take system out of configuration state */
-       clear_c0_mvpcontrol(MVPCONTROL_VPC);
-
-       /*
-        * SMTC/SMVP kernels manage VPE enable independently,
-        * but uniprocessor kernels need to turn it on, even
-        * if that wasn't the pre-dvpe() state.
-        */
-#ifdef CONFIG_SMP
-       evpe(vpeflags);
-#else
-       evpe(EVPE_ENABLE);
-#endif
-       emt(dmt_flag);
-       local_irq_restore(flags);
-
-       list_for_each_entry(n, &v->notify, list)
-               n->start(minor);
-
-       return 0;
-}
-
-static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
+static int find_vpe_symbols(struct vpe *v, Elf_Shdr *sechdrs,
                                      unsigned int symindex, const char *strtab,
                                      struct module *mod)
 {
@@ -803,16 +555,14 @@ static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
        unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
 
        for (i = 1; i < n; i++) {
-               if (strcmp(strtab + sym[i].st_name, "__start") == 0) {
+               if (strcmp(strtab + sym[i].st_name, "__start") == 0)
                        v->__start = sym[i].st_value;
-               }
 
-               if (strcmp(strtab + sym[i].st_name, "vpe_shared") == 0) {
+               if (strcmp(strtab + sym[i].st_name, "vpe_shared") == 0)
                        v->shared_ptr = (void *)sym[i].st_value;
-               }
        }
 
-       if ( (v->__start == 0) || (v->shared_ptr == NULL))
+       if ((v->__start == 0) || (v->shared_ptr == NULL))
                return -1;
 
        return 0;
@@ -823,14 +573,14 @@ static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
  * contents of the program (p)buffer performing relocatations/etc, free's it
  * when finished.
  */
-static int vpe_elfload(struct vpe * v)
+static int vpe_elfload(struct vpe *v)
 {
        Elf_Ehdr *hdr;
        Elf_Shdr *sechdrs;
        long err = 0;
        char *secstrings, *strtab = NULL;
        unsigned int len, i, symindex = 0, strindex = 0, relocate = 0;
-       struct module mod;      // so we can re-use the relocations code
+       struct module mod; /* so we can re-use the relocations code */
 
        memset(&mod, 0, sizeof(struct module));
        strcpy(mod.name, "VPE loader");
@@ -844,8 +594,7 @@ static int vpe_elfload(struct vpe * v)
            || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
            || !elf_check_arch(hdr)
            || hdr->e_shentsize != sizeof(*sechdrs)) {
-               printk(KERN_WARNING
-                      "VPE loader: program wrong arch or weird elf version\n");
+               pr_warn("VPE loader: program wrong arch or weird elf version\n");
 
                return -ENOEXEC;
        }
@@ -854,8 +603,7 @@ static int vpe_elfload(struct vpe * v)
                relocate = 1;
 
        if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
-               printk(KERN_ERR "VPE loader: program length %u truncated\n",
-                      len);
+               pr_err("VPE loader: program length %u truncated\n", len);
 
                return -ENOEXEC;
        }
@@ -870,22 +618,24 @@ static int vpe_elfload(struct vpe * v)
 
        if (relocate) {
                for (i = 1; i < hdr->e_shnum; i++) {
-                       if (sechdrs[i].sh_type != SHT_NOBITS
-                           && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) {
-                               printk(KERN_ERR "VPE program length %u truncated\n",
+                       if ((sechdrs[i].sh_type != SHT_NOBITS) &&
+                           (len < sechdrs[i].sh_offset + sechdrs[i].sh_size)) {
+                               pr_err("VPE program length %u truncated\n",
                                       len);
                                return -ENOEXEC;
                        }
 
                        /* Mark all sections sh_addr with their address in the
                           temporary image. */
-                       sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
+                       sechdrs[i].sh_addr = (size_t) hdr +
+                               sechdrs[i].sh_offset;
 
                        /* Internal symbols and strings. */
                        if (sechdrs[i].sh_type == SHT_SYMTAB) {
                                symindex = i;
                                strindex = sechdrs[i].sh_link;
-                               strtab = (char *)hdr + sechdrs[strindex].sh_offset;
+                               strtab = (char *)hdr +
+                                       sechdrs[strindex].sh_offset;
                        }
                }
                layout_sections(&mod, hdr, sechdrs, secstrings);
@@ -912,8 +662,9 @@ static int vpe_elfload(struct vpe * v)
                        /* Update sh_addr to point to copy in image. */
                        sechdrs[i].sh_addr = (unsigned long)dest;
 
-                       printk(KERN_DEBUG " section sh_name %s sh_addr 0x%x\n",
-                              secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr);
+                       pr_debug(" section sh_name %s sh_addr 0x%x\n",
+                                secstrings + sechdrs[i].sh_name,
+                                sechdrs[i].sh_addr);
                }
 
                /* Fix up syms, so that st_value is a pointer to location. */
@@ -934,17 +685,18 @@ static int vpe_elfload(struct vpe * v)
                                continue;
 
                        if (sechdrs[i].sh_type == SHT_REL)
-                               err = apply_relocations(sechdrs, strtab, symindex, i,
-                                                       &mod);
+                               err = apply_relocations(sechdrs, strtab,
+                                                       symindex, i, &mod);
                        else if (sechdrs[i].sh_type == SHT_RELA)
-                               err = apply_relocate_add(sechdrs, strtab, symindex, i,
-                                                        &mod);
+                               err = apply_relocate_add(sechdrs, strtab,
+                                                        symindex, i, &mod);
                        if (err < 0)
                                return err;
 
                }
        } else {
-               struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);
+               struct elf_phdr *phdr = (struct elf_phdr *)
+                                               ((char *)hdr + hdr->e_phoff);
 
                for (i = 0; i < hdr->e_phnum; i++) {
                        if (phdr->p_type == PT_LOAD) {
@@ -962,11 +714,15 @@ static int vpe_elfload(struct vpe * v)
                        if (sechdrs[i].sh_type == SHT_SYMTAB) {
                                symindex = i;
                                strindex = sechdrs[i].sh_link;
-                               strtab = (char *)hdr + sechdrs[strindex].sh_offset;
+                               strtab = (char *)hdr +
+                                       sechdrs[strindex].sh_offset;
 
-                               /* mark the symtab's address for when we try to find the
-                                  magic symbols */
-                               sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
+                               /*
+                                * mark symtab's address for when we try
+                                * to find the magic symbols
+                                */
+                               sechdrs[i].sh_addr = (size_t) hdr +
+                                       sechdrs[i].sh_offset;
                        }
                }
        }
@@ -977,53 +733,19 @@ static int vpe_elfload(struct vpe * v)
 
        if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
                if (v->__start == 0) {
-                       printk(KERN_WARNING "VPE loader: program does not contain "
-                              "a __start symbol\n");
+                       pr_warn("VPE loader: program does not contain a __start symbol\n");
                        return -ENOEXEC;
                }
 
                if (v->shared_ptr == NULL)
-                       printk(KERN_WARNING "VPE loader: "
-                              "program does not contain vpe_shared symbol.\n"
-                              " Unable to use AMVP (AP/SP) facilities.\n");
+                       pr_warn("VPE loader: program does not contain vpe_shared symbol.\n"
+                               " Unable to use AMVP (AP/SP) facilities.\n");
        }
 
-       printk(" elf loaded\n");
+       pr_info(" elf loaded\n");
        return 0;
 }
 
-static void cleanup_tc(struct tc *tc)
-{
-       unsigned long flags;
-       unsigned int mtflags, vpflags;
-       int tmp;
-
-       local_irq_save(flags);
-       mtflags = dmt();
-       vpflags = dvpe();
-       /* Put MVPE's into 'configuration state' */
-       set_c0_mvpcontrol(MVPCONTROL_VPC);
-
-       settc(tc->index);
-       tmp = read_tc_c0_tcstatus();
-
-       /* mark not allocated and not dynamically allocatable */
-       tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
-       tmp |= TCSTATUS_IXMT;   /* interrupt exempt */
-       write_tc_c0_tcstatus(tmp);
-
-       write_tc_c0_tchalt(TCHALT_H);
-       mips_ihb();
-
-       /* bind it to anything other than VPE1 */
-//     write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE
-
-       clear_c0_mvpcontrol(MVPCONTROL_VPC);
-       evpe(vpflags);
-       emt(mtflags);
-       local_irq_restore(flags);
-}
-
 static int getcwd(char *buff, int size)
 {
        mm_segment_t old_fs;
@@ -1043,39 +765,39 @@ static int getcwd(char *buff, int size)
 static int vpe_open(struct inode *inode, struct file *filp)
 {
        enum vpe_state state;
-       struct vpe_notifications *not;
+       struct vpe_notifications *notifier;
        struct vpe *v;
        int ret;
 
-       if (minor != iminor(inode)) {
+       if (VPE_MODULE_MINOR != iminor(inode)) {
                /* assume only 1 device at the moment. */
-               pr_warning("VPE loader: only vpe1 is supported\n");
+               pr_warn("VPE loader: only vpe1 is supported\n");
 
                return -ENODEV;
        }
 
-       if ((v = get_vpe(tclimit)) == NULL) {
-               pr_warning("VPE loader: unable to get vpe\n");
+       v = get_vpe(aprp_cpu_index());
+       if (v == NULL) {
+               pr_warn("VPE loader: unable to get vpe\n");
 
                return -ENODEV;
        }
 
        state = xchg(&v->state, VPE_STATE_INUSE);
        if (state != VPE_STATE_UNUSED) {
-               printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n");
+               pr_debug("VPE loader: tc in use dumping regs\n");
 
-               list_for_each_entry(not, &v->notify, list) {
-                       not->stop(tclimit);
-               }
+               list_for_each_entry(notifier, &v->notify, list)
+                       notifier->stop(aprp_cpu_index());
 
                release_progmem(v->load_addr);
-               cleanup_tc(get_tc(tclimit));
+               cleanup_tc(get_tc(aprp_cpu_index()));
        }
 
        /* this of-course trashes what was there before... */
        v->pbuffer = vmalloc(P_SIZE);
        if (!v->pbuffer) {
-               pr_warning("VPE loader: unable to allocate memory\n");
+               pr_warn("VPE loader: unable to allocate memory\n");
                return -ENOMEM;
        }
        v->plen = P_SIZE;
@@ -1085,7 +807,7 @@ static int vpe_open(struct inode *inode, struct file *filp)
        v->cwd[0] = 0;
        ret = getcwd(v->cwd, VPE_PATH_MAX);
        if (ret < 0)
-               printk(KERN_WARNING "VPE loader: open, getcwd returned %d\n", ret);
+               pr_warn("VPE loader: open, getcwd returned %d\n", ret);
 
        v->shared_ptr = NULL;
        v->__start = 0;
@@ -1099,20 +821,20 @@ static int vpe_release(struct inode *inode, struct file *filp)
        Elf_Ehdr *hdr;
        int ret = 0;
 
-       v = get_vpe(tclimit);
+       v = get_vpe(aprp_cpu_index());
        if (v == NULL)
                return -ENODEV;
 
        hdr = (Elf_Ehdr *) v->pbuffer;
        if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
-               if (vpe_elfload(v) >= 0) {
+               if ((vpe_elfload(v) >= 0) && vpe_run) {
                        vpe_run(v);
                } else {
-                       printk(KERN_WARNING "VPE loader: ELF load failed.\n");
+                       pr_warn("VPE loader: ELF load failed.\n");
                        ret = -ENOEXEC;
                }
        } else {
-               printk(KERN_WARNING "VPE loader: only elf files are supported\n");
+               pr_warn("VPE loader: only elf files are supported\n");
                ret = -ENOEXEC;
        }
 
@@ -1130,22 +852,22 @@ static int vpe_release(struct inode *inode, struct file *filp)
        return ret;
 }
 
-static ssize_t vpe_write(struct file *file, const char __user * buffer,
-                        size_t count, loff_t * ppos)
+static ssize_t vpe_write(struct file *file, const char __user *buffer,
+                        size_t count, loff_t *ppos)
 {
        size_t ret = count;
        struct vpe *v;
 
-       if (iminor(file_inode(file)) != minor)
+       if (iminor(file_inode(file)) != VPE_MODULE_MINOR)
                return -ENODEV;
 
-       v = get_vpe(tclimit);
+       v = get_vpe(aprp_cpu_index());
+
        if (v == NULL)
                return -ENODEV;
 
        if ((count + v->len) > v->plen) {
-               printk(KERN_WARNING
-                      "VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
+               pr_warn("VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
                return -ENOMEM;
        }
 
@@ -1157,7 +879,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
        return ret;
 }
 
-static const struct file_operations vpe_fops = {
+const struct file_operations vpe_fops = {
        .owner = THIS_MODULE,
        .open = vpe_open,
        .release = vpe_release,
@@ -1165,396 +887,40 @@ static const struct file_operations vpe_fops = {
        .llseek = noop_llseek,
 };
 
-/* module wrapper entry points */
-/* give me a vpe */
-vpe_handle vpe_alloc(void)
-{
-       int i;
-       struct vpe *v;
-
-       /* find a vpe */
-       for (i = 1; i < MAX_VPES; i++) {
-               if ((v = get_vpe(i)) != NULL) {
-                       v->state = VPE_STATE_INUSE;
-                       return v;
-               }
-       }
-       return NULL;
-}
-
-EXPORT_SYMBOL(vpe_alloc);
-
-/* start running from here */
-int vpe_start(vpe_handle vpe, unsigned long start)
-{
-       struct vpe *v = vpe;
-
-       v->__start = start;
-       return vpe_run(v);
-}
-
-EXPORT_SYMBOL(vpe_start);
-
-/* halt it for now */
-int vpe_stop(vpe_handle vpe)
-{
-       struct vpe *v = vpe;
-       struct tc *t;
-       unsigned int evpe_flags;
-
-       evpe_flags = dvpe();
-
-       if ((t = list_entry(v->tc.next, struct tc, tc)) != NULL) {
-
-               settc(t->index);
-               write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
-       }
-
-       evpe(evpe_flags);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(vpe_stop);
-
-/* I've done with it thank you */
-int vpe_free(vpe_handle vpe)
-{
-       struct vpe *v = vpe;
-       struct tc *t;
-       unsigned int evpe_flags;
-
-       if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
-               return -ENOEXEC;
-       }
-
-       evpe_flags = dvpe();
-
-       /* Put MVPE's into 'configuration state' */
-       set_c0_mvpcontrol(MVPCONTROL_VPC);
-
-       settc(t->index);
-       write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
-
-       /* halt the TC */
-       write_tc_c0_tchalt(TCHALT_H);
-       mips_ihb();
-
-       /* mark the TC unallocated */
-       write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);
-
-       v->state = VPE_STATE_UNUSED;
-
-       clear_c0_mvpcontrol(MVPCONTROL_VPC);
-       evpe(evpe_flags);
-
-       return 0;
-}
-
-EXPORT_SYMBOL(vpe_free);
-
 void *vpe_get_shared(int index)
 {
-       struct vpe *v;
+       struct vpe *v = get_vpe(index);
 
-       if ((v = get_vpe(index)) == NULL)
+       if (v == NULL)
                return NULL;
 
        return v->shared_ptr;
 }
-
 EXPORT_SYMBOL(vpe_get_shared);
 
 int vpe_notify(int index, struct vpe_notifications *notify)
 {
-       struct vpe *v;
+       struct vpe *v = get_vpe(index);
 
-       if ((v = get_vpe(index)) == NULL)
+       if (v == NULL)
                return -1;
 
        list_add(&notify->list, &v->notify);
        return 0;
 }
-
 EXPORT_SYMBOL(vpe_notify);
 
 char *vpe_getcwd(int index)
 {
-       struct vpe *v;
+       struct vpe *v = get_vpe(index);
 
-       if ((v = get_vpe(index)) == NULL)
+       if (v == NULL)
                return NULL;
 
        return v->cwd;
 }
-
 EXPORT_SYMBOL(vpe_getcwd);
 
-static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
-                         const char *buf, size_t len)
-{
-       struct vpe *vpe = get_vpe(tclimit);
-       struct vpe_notifications *not;
-
-       list_for_each_entry(not, &vpe->notify, list) {
-               not->stop(tclimit);
-       }
-
-       release_progmem(vpe->load_addr);
-       cleanup_tc(get_tc(tclimit));
-       vpe_stop(vpe);
-       vpe_free(vpe);
-
-       return len;
-}
-static DEVICE_ATTR(kill, S_IWUSR, NULL, store_kill);
-
-static ssize_t ntcs_show(struct device *cd, struct device_attribute *attr,
-                        char *buf)
-{
-       struct vpe *vpe = get_vpe(tclimit);
-
-       return sprintf(buf, "%d\n", vpe->ntcs);
-}
-
-static ssize_t ntcs_store(struct device *dev, struct device_attribute *attr,
-                         const char *buf, size_t len)
-{
-       struct vpe *vpe = get_vpe(tclimit);
-       unsigned long new;
-       char *endp;
-
-       new = simple_strtoul(buf, &endp, 0);
-       if (endp == buf)
-               goto out_einval;
-
-       if (new == 0 || new > (hw_tcs - tclimit))
-               goto out_einval;
-
-       vpe->ntcs = new;
-
-       return len;
-
-out_einval:
-       return -EINVAL;
-}
-static DEVICE_ATTR_RW(ntcs);
-
-static struct attribute *vpe_attrs[] = {
-       &dev_attr_kill.attr,
-       &dev_attr_ntcs.attr,
-       NULL,
-};
-ATTRIBUTE_GROUPS(vpe);
-
-static void vpe_device_release(struct device *cd)
-{
-       kfree(cd);
-}
-
-struct class vpe_class = {
-       .name = "vpe",
-       .owner = THIS_MODULE,
-       .dev_release = vpe_device_release,
-       .dev_groups = vpe_groups,
-};
-
-struct device vpe_device;
-
-static int __init vpe_module_init(void)
-{
-       unsigned int mtflags, vpflags;
-       unsigned long flags, val;
-       struct vpe *v = NULL;
-       struct tc *t;
-       int tc, err;
-
-       if (!cpu_has_mipsmt) {
-               printk("VPE loader: not a MIPS MT capable processor\n");
-               return -ENODEV;
-       }
-
-       if (vpelimit == 0) {
-               printk(KERN_WARNING "No VPEs reserved for AP/SP, not "
-                      "initializing VPE loader.\nPass maxvpes=<n> argument as "
-                      "kernel argument\n");
-
-               return -ENODEV;
-       }
-
-       if (tclimit == 0) {
-               printk(KERN_WARNING "No TCs reserved for AP/SP, not "
-                      "initializing VPE loader.\nPass maxtcs=<n> argument as "
-                      "kernel argument\n");
-
-               return -ENODEV;
-       }
-
-       major = register_chrdev(0, module_name, &vpe_fops);
-       if (major < 0) {
-               printk("VPE loader: unable to register character device\n");
-               return major;
-       }
-
-       err = class_register(&vpe_class);
-       if (err) {
-               printk(KERN_ERR "vpe_class registration failed\n");
-               goto out_chrdev;
-       }
-
-       device_initialize(&vpe_device);
-       vpe_device.class        = &vpe_class,
-       vpe_device.parent       = NULL,
-       dev_set_name(&vpe_device, "vpe1");
-       vpe_device.devt = MKDEV(major, minor);
-       err = device_add(&vpe_device);
-       if (err) {
-               printk(KERN_ERR "Adding vpe_device failed\n");
-               goto out_class;
-       }
-
-       local_irq_save(flags);
-       mtflags = dmt();
-       vpflags = dvpe();
-
-       /* Put MVPE's into 'configuration state' */
-       set_c0_mvpcontrol(MVPCONTROL_VPC);
-
-       /* dump_mtregs(); */
-
-       val = read_c0_mvpconf0();
-       hw_tcs = (val & MVPCONF0_PTC) + 1;
-       hw_vpes = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
-
-       for (tc = tclimit; tc < hw_tcs; tc++) {
-               /*
-                * Must re-enable multithreading temporarily or in case we
-                * reschedule send IPIs or similar we might hang.
-                */
-               clear_c0_mvpcontrol(MVPCONTROL_VPC);
-               evpe(vpflags);
-               emt(mtflags);
-               local_irq_restore(flags);
-               t = alloc_tc(tc);
-               if (!t) {
-                       err = -ENOMEM;
-                       goto out;
-               }
-
-               local_irq_save(flags);
-               mtflags = dmt();
-               vpflags = dvpe();
-               set_c0_mvpcontrol(MVPCONTROL_VPC);
-
-               /* VPE's */
-               if (tc < hw_tcs) {
-                       settc(tc);
-
-                       if ((v = alloc_vpe(tc)) == NULL) {
-                               printk(KERN_WARNING "VPE: unable to allocate VPE\n");
-
-                               goto out_reenable;
-                       }
-
-                       v->ntcs = hw_tcs - tclimit;
-
-                       /* add the tc to the list of this vpe's tc's. */
-                       list_add(&t->tc, &v->tc);
-
-                       /* deactivate all but vpe0 */
-                       if (tc >= tclimit) {
-                               unsigned long tmp = read_vpe_c0_vpeconf0();
-
-                               tmp &= ~VPECONF0_VPA;
-
-                               /* master VPE */
-                               tmp |= VPECONF0_MVP;
-                               write_vpe_c0_vpeconf0(tmp);
-                       }
-
-                       /* disable multi-threading with TC's */
-                       write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
-
-                       if (tc >= vpelimit) {
-                               /*
-                                * Set config to be the same as vpe0,
-                                * particularly kseg0 coherency alg
-                                */
-                               write_vpe_c0_config(read_c0_config());
-                       }
-               }
-
-               /* TC's */
-               t->pvpe = v;    /* set the parent vpe */
-
-               if (tc >= tclimit) {
-                       unsigned long tmp;
-
-                       settc(tc);
-
-                       /* Any TC that is bound to VPE0 gets left as is - in case
-                          we are running SMTC on VPE0. A TC that is bound to any
-                          other VPE gets bound to VPE0, ideally I'd like to make
-                          it homeless but it doesn't appear to let me bind a TC
-                          to a non-existent VPE. Which is perfectly reasonable.
-
-                          The (un)bound state is visible to an EJTAG probe so may
-                          notify GDB...
-                       */
-
-                       if (((tmp = read_tc_c0_tcbind()) & TCBIND_CURVPE)) {
-                               /* tc is bound >vpe0 */
-                               write_tc_c0_tcbind(tmp & ~TCBIND_CURVPE);
-
-                               t->pvpe = get_vpe(0);   /* set the parent vpe */
-                       }
-
-                       /* halt the TC */
-                       write_tc_c0_tchalt(TCHALT_H);
-                       mips_ihb();
-
-                       tmp = read_tc_c0_tcstatus();
-
-                       /* mark not activated and not dynamically allocatable */
-                       tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
-                       tmp |= TCSTATUS_IXMT;   /* interrupt exempt */
-                       write_tc_c0_tcstatus(tmp);
-               }
-       }
-
-out_reenable:
-       /* release config state */
-       clear_c0_mvpcontrol(MVPCONTROL_VPC);
-
-       evpe(vpflags);
-       emt(mtflags);
-       local_irq_restore(flags);
-
-       return 0;
-
-out_class:
-       class_unregister(&vpe_class);
-out_chrdev:
-       unregister_chrdev(major, module_name);
-
-out:
-       return err;
-}
-
-static void __exit vpe_module_exit(void)
-{
-       struct vpe *v, *n;
-
-       device_del(&vpe_device);
-       unregister_chrdev(major, module_name);
-
-       /* No locking needed here */
-       list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
-               if (v->state != VPE_STATE_UNUSED)
-                       release_vpe(v);
-       }
-}
-
 module_init(vpe_module_init);
 module_exit(vpe_module_exit);
 MODULE_DESCRIPTION("MIPS VPE Loader");
index 73b3482..da5186f 100644 (file)
@@ -1001,7 +1001,6 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
        hrtimer_init(&vcpu->arch.comparecount_timer, CLOCK_MONOTONIC,
                     HRTIMER_MODE_REL);
        vcpu->arch.comparecount_timer.function = kvm_mips_comparecount_wakeup;
-       kvm_mips_init_shadow_tlb(vcpu);
        return 0;
 }
 
index c777dd3..50ab9c4 100644 (file)
@@ -10,7 +10,6 @@
 * Authors: Sanjay Lal <sanjayl@kymasys.com>
 */
 
-#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
@@ -25,6 +24,7 @@
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
+#include <asm/tlb.h>
 
 #undef CONFIG_MIPS_MT
 #include <asm/r4kcache.h>
@@ -35,9 +35,6 @@
 
 #define PRIx64 "llx"
 
-/* Use VZ EntryHi.EHINV to invalidate TLB entries */
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
 atomic_t kvm_mips_instance;
 EXPORT_SYMBOL(kvm_mips_instance);
 
@@ -147,30 +144,6 @@ void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
        }
 }
 
-void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu)
-{
-       int i;
-       volatile struct kvm_mips_tlb tlb;
-
-       printk("Shadow TLBs:\n");
-       for (i = 0; i < KVM_MIPS_GUEST_TLB_SIZE; i++) {
-               tlb = vcpu->arch.shadow_tlb[smp_processor_id()][i];
-               printk("TLB%c%3d Hi 0x%08lx ",
-                      (tlb.tlb_lo0 | tlb.tlb_lo1) & MIPS3_PG_V ? ' ' : '*',
-                      i, tlb.tlb_hi);
-               printk("Lo0=0x%09" PRIx64 " %c%c attr %lx ",
-                      (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo0),
-                      (tlb.tlb_lo0 & MIPS3_PG_D) ? 'D' : ' ',
-                      (tlb.tlb_lo0 & MIPS3_PG_G) ? 'G' : ' ',
-                      (tlb.tlb_lo0 >> 3) & 7);
-               printk("Lo1=0x%09" PRIx64 " %c%c attr %lx sz=%lx\n",
-                      (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo1),
-                      (tlb.tlb_lo1 & MIPS3_PG_D) ? 'D' : ' ',
-                      (tlb.tlb_lo1 & MIPS3_PG_G) ? 'G' : ' ',
-                      (tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask);
-       }
-}
-
 static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
 {
        int srcu_idx, err = 0;
@@ -657,70 +630,6 @@ kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
        cpu_context(cpu, mm) = asid_cache(cpu) = asid;
 }
 
-void kvm_shadow_tlb_put(struct kvm_vcpu *vcpu)
-{
-       unsigned long flags;
-       unsigned long old_entryhi;
-       unsigned long old_pagemask;
-       int entry = 0;
-       int cpu = smp_processor_id();
-
-       local_irq_save(flags);
-
-       old_entryhi = read_c0_entryhi();
-       old_pagemask = read_c0_pagemask();
-
-       for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
-               write_c0_index(entry);
-               mtc0_tlbw_hazard();
-               tlb_read();
-               tlbw_use_hazard();
-
-               vcpu->arch.shadow_tlb[cpu][entry].tlb_hi = read_c0_entryhi();
-               vcpu->arch.shadow_tlb[cpu][entry].tlb_lo0 = read_c0_entrylo0();
-               vcpu->arch.shadow_tlb[cpu][entry].tlb_lo1 = read_c0_entrylo1();
-               vcpu->arch.shadow_tlb[cpu][entry].tlb_mask = read_c0_pagemask();
-       }
-
-       write_c0_entryhi(old_entryhi);
-       write_c0_pagemask(old_pagemask);
-       mtc0_tlbw_hazard();
-
-       local_irq_restore(flags);
-
-}
-
-void kvm_shadow_tlb_load(struct kvm_vcpu *vcpu)
-{
-       unsigned long flags;
-       unsigned long old_ctx;
-       int entry;
-       int cpu = smp_processor_id();
-
-       local_irq_save(flags);
-
-       old_ctx = read_c0_entryhi();
-
-       for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
-               write_c0_entryhi(vcpu->arch.shadow_tlb[cpu][entry].tlb_hi);
-               mtc0_tlbw_hazard();
-               write_c0_entrylo0(vcpu->arch.shadow_tlb[cpu][entry].tlb_lo0);
-               write_c0_entrylo1(vcpu->arch.shadow_tlb[cpu][entry].tlb_lo1);
-
-               write_c0_index(entry);
-               mtc0_tlbw_hazard();
-
-               tlb_write_indexed();
-               tlbw_use_hazard();
-       }
-
-       tlbw_use_hazard();
-       write_c0_entryhi(old_ctx);
-       mtc0_tlbw_hazard();
-       local_irq_restore(flags);
-}
-
-
 void kvm_local_flush_tlb_all(void)
 {
        unsigned long flags;
@@ -749,30 +658,6 @@ void kvm_local_flush_tlb_all(void)
        local_irq_restore(flags);
 }
 
-void kvm_mips_init_shadow_tlb(struct kvm_vcpu *vcpu)
-{
-       int cpu, entry;
-
-       for_each_possible_cpu(cpu) {
-               for (entry = 0; entry < current_cpu_data.tlbsize; entry++) {
-                       vcpu->arch.shadow_tlb[cpu][entry].tlb_hi =
-                           UNIQUE_ENTRYHI(entry);
-                       vcpu->arch.shadow_tlb[cpu][entry].tlb_lo0 = 0x0;
-                       vcpu->arch.shadow_tlb[cpu][entry].tlb_lo1 = 0x0;
-                       vcpu->arch.shadow_tlb[cpu][entry].tlb_mask =
-                           read_c0_pagemask();
-#ifdef DEBUG
-                       kvm_debug
-                           ("shadow_tlb[%d][%d]: tlb_hi: %#lx, lo0: %#lx, lo1: %#lx\n",
-                            cpu, entry,
-                            vcpu->arch.shadow_tlb[cpu][entry].tlb_hi,
-                            vcpu->arch.shadow_tlb[cpu][entry].tlb_lo0,
-                            vcpu->arch.shadow_tlb[cpu][entry].tlb_lo1);
-#endif
-               }
-       }
-}
-
 /* Restore ASID once we are scheduled back after preemption */
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
@@ -810,14 +695,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
                         vcpu->arch.last_sched_cpu, cpu, vcpu->vcpu_id);
        }
 
-       /* Only reload shadow host TLB if new ASIDs haven't been allocated */
-#if 0
-       if ((atomic_read(&kvm_mips_instance) > 1) && !newasid) {
-               kvm_mips_flush_host_tlb(0);
-               kvm_shadow_tlb_load(vcpu);
-       }
-#endif
-
        if (!newasid) {
                /* If we preempted while the guest was executing, then reload the pre-empted ASID */
                if (current->flags & PF_VCPU) {
@@ -863,12 +740,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
        vcpu->arch.preempt_entryhi = read_c0_entryhi();
        vcpu->arch.last_sched_cpu = cpu;
 
-#if 0
-       if ((atomic_read(&kvm_mips_instance) > 1)) {
-               kvm_shadow_tlb_put(vcpu);
-       }
-#endif
-
        if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) &
             ASID_VERSION_MASK)) {
                kvm_debug("%s: Dropping MMU Context:  %#lx\n", __func__,
@@ -930,10 +801,8 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
 }
 
 EXPORT_SYMBOL(kvm_local_flush_tlb_all);
-EXPORT_SYMBOL(kvm_shadow_tlb_put);
 EXPORT_SYMBOL(kvm_mips_handle_mapped_seg_tlb_fault);
 EXPORT_SYMBOL(kvm_mips_handle_commpage_tlb_fault);
-EXPORT_SYMBOL(kvm_mips_init_shadow_tlb);
 EXPORT_SYMBOL(kvm_mips_dump_host_tlbs);
 EXPORT_SYMBOL(kvm_mips_handle_kseg0_tlb_fault);
 EXPORT_SYMBOL(kvm_mips_host_tlb_lookup);
@@ -941,8 +810,6 @@ EXPORT_SYMBOL(kvm_mips_flush_host_tlb);
 EXPORT_SYMBOL(kvm_mips_guest_tlb_lookup);
 EXPORT_SYMBOL(kvm_mips_host_tlb_inv);
 EXPORT_SYMBOL(kvm_mips_translate_guest_kseg0_to_hpa);
-EXPORT_SYMBOL(kvm_shadow_tlb_load);
-EXPORT_SYMBOL(kvm_mips_dump_shadow_tlbs);
 EXPORT_SYMBOL(kvm_mips_dump_guest_tlbs);
 EXPORT_SYMBOL(kvm_get_inst);
 EXPORT_SYMBOL(kvm_arch_vcpu_load);
index 1ab576d..8750dc0 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/io.h>
 #include <linux/export.h>
-#include <linux/init.h>
 #include <linux/clk.h>
 
 #include <asm/time.h>
index 08f7ebd..78a91fa 100644 (file)
@@ -220,10 +220,6 @@ ltq_dma_init(struct platform_device *pdev)
        int i;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               panic("Failed to get dma resource");
-
-       /* remap dma register range */
        ltq_dma_membase = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(ltq_dma_membase))
                panic("Failed to remap dma resource");
index 793e234..942f32b 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/delay.h>
 #include <asm/lasat/lasat.h>
 #include <linux/module.h>
-#include <linux/init.h>
 
 #include "at93c.h"
 
index 7eb3348..d613b97 100644 (file)
@@ -9,7 +9,6 @@
 #include <asm/bootinfo.h>
 #include <asm/lasat/lasat.h>
 #include <linux/module.h>
-#include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 
index d8522f8..09d5dee 100644 (file)
@@ -8,7 +8,6 @@
  *     Author: Maciej W. Rozycki <macro@mips.com>
  */
 
-#include <linux/init.h>
 
 #include <asm/addrspace.h>
 #include <asm/bug.h>
index 4dc2f5f..aed32b8 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/cpufreq.h>
 #include <linux/errno.h>
 #include <linux/export.h>
-#include <linux/init.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
index efe0088..506925b 100644 (file)
@@ -417,14 +417,20 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
                        case mm_mtc1_op:
                        case mm_cfc1_op:
                        case mm_ctc1_op:
+                       case mm_mfhc1_op:
+                       case mm_mthc1_op:
                                if (insn.mm_fp1_format.op == mm_mfc1_op)
                                        op = mfc_op;
                                else if (insn.mm_fp1_format.op == mm_mtc1_op)
                                        op = mtc_op;
                                else if (insn.mm_fp1_format.op == mm_cfc1_op)
                                        op = cfc_op;
-                               else
+                               else if (insn.mm_fp1_format.op == mm_ctc1_op)
                                        op = ctc_op;
+                               else if (insn.mm_fp1_format.op == mm_mfhc1_op)
+                                       op = mfhc_op;
+                               else
+                                       op = mthc_op;
                                mips32_insn.fp1_format.opcode = cop1_op;
                                mips32_insn.fp1_format.op = op;
                                mips32_insn.fp1_format.rt =
@@ -853,20 +859,20 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
  * In the Linux kernel, we support selection of FPR format on the
  * basis of the Status.FR bit. If an FPU is not present, the FR bit
  * is hardwired to zero, which would imply a 32-bit FPU even for
- * 64-bit CPUs so we rather look at TIF_32BIT_REGS.
+ * 64-bit CPUs so we rather look at TIF_32BIT_FPREGS.
  * FPU emu is slow and bulky and optimizing this function offers fairly
  * sizeable benefits so we try to be clever and make this function return
  * a constant whenever possible, that is on 64-bit kernels without O32
- * compatibility enabled and on 32-bit kernels.
+ * compatibility enabled and on 32-bit without 64-bit FPU support.
  */
 static inline int cop1_64bit(struct pt_regs *xcp)
 {
 #if defined(CONFIG_64BIT) && !defined(CONFIG_MIPS32_O32)
        return 1;
-#elif defined(CONFIG_64BIT) && defined(CONFIG_MIPS32_O32)
-       return !test_thread_flag(TIF_32BIT_REGS);
-#else
+#elif defined(CONFIG_32BIT) && !defined(CONFIG_MIPS_O32_FP64_SUPPORT)
        return 0;
+#else
+       return !test_thread_flag(TIF_32BIT_FPREGS);
 #endif
 }
 
@@ -878,6 +884,10 @@ static inline int cop1_64bit(struct pt_regs *xcp)
                        ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
                        ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
 
+#define SIFROMHREG(si, x)      ((si) = (int)(ctx->fpr[x] >> 32))
+#define SITOHREG(si, x)                (ctx->fpr[x] = \
+                               ctx->fpr[x] << 32 >> 32 | (u64)(si) << 32)
+
 #define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
 #define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
 
@@ -1055,6 +1065,25 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        break;
 #endif
 
+               case mfhc_op:
+                       if (!cpu_has_mips_r2)
+                               goto sigill;
+
+                       /* copregister rd -> gpr[rt] */
+                       if (MIPSInst_RT(ir) != 0) {
+                               SIFROMHREG(xcp->regs[MIPSInst_RT(ir)],
+                                       MIPSInst_RD(ir));
+                       }
+                       break;
+
+               case mthc_op:
+                       if (!cpu_has_mips_r2)
+                               goto sigill;
+
+                       /* copregister rd <- gpr[rt] */
+                       SITOHREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir));
+                       break;
+
                case mfc_op:
                        /* copregister rd -> gpr[rt] */
                        if (MIPSInst_RT(ir) != 0) {
@@ -1263,6 +1292,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 #endif
 
        default:
+sigill:
                return SIGILL;
        }
 
index 1c58657..3aeae07 100644 (file)
@@ -89,8 +89,9 @@ int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
 {
        int i;
        int err = 0;
+       int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
 
-       for (i = 0; i < 32; i+=2) {
+       for (i = 0; i < 32; i += inc) {
                err |=
                    __put_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
        }
@@ -103,8 +104,9 @@ int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
 {
        int i;
        int err = 0;
+       int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
 
-       for (i = 0; i < 32; i+=2) {
+       for (i = 0; i < 32; i += inc) {
                err |=
                    __get_user(current->thread.fpu.fpr[i], &sc->sc_fpregs[i]);
        }
index c8efdb5..f41a5c5 100644 (file)
@@ -6,7 +6,6 @@
  * Copyright (C) 2005-2007 Cavium Networks
  */
 #include <linux/export.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
index 2fcde0c..135ec31 100644 (file)
@@ -9,7 +9,6 @@
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  * Copyright (C) 2001, 2004, 2007  Maciej W. Rozycki
  */
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
index 49e572d..c14259e 100644 (file)
@@ -1020,10 +1020,14 @@ static void probe_pcache(void)
                 */
                config1 = read_c0_config1();
 
-               if ((lsize = ((config1 >> 19) & 7)))
-                       c->icache.linesz = 2 << lsize;
-               else
-                       c->icache.linesz = lsize;
+               lsize = (config1 >> 19) & 7;
+
+               /* IL == 7 is reserved */
+               if (lsize == 7)
+                       panic("Invalid icache line size");
+
+               c->icache.linesz = lsize ? 2 << lsize : 0;
+
                c->icache.sets = 32 << (((config1 >> 22) + 1) & 7);
                c->icache.ways = 1 + ((config1 >> 16) & 7);
 
@@ -1040,10 +1044,14 @@ static void probe_pcache(void)
                 */
                c->dcache.flags = 0;
 
-               if ((lsize = ((config1 >> 10) & 7)))
-                       c->dcache.linesz = 2 << lsize;
-               else
-                       c->dcache.linesz= lsize;
+               lsize = (config1 >> 10) & 7;
+
+               /* DL == 7 is reserved */
+               if (lsize == 7)
+                       panic("Invalid dcache line size");
+
+               c->dcache.linesz = lsize ? 2 << lsize : 0;
+
                c->dcache.sets = 32 << (((config1 >> 13) + 1) & 7);
                c->dcache.ways = 1 + ((config1 >> 7) & 7);
 
@@ -1105,6 +1113,8 @@ static void probe_pcache(void)
        case CPU_34K:
        case CPU_74K:
        case CPU_1004K:
+       case CPU_INTERAPTIV:
+       case CPU_PROAPTIV:
                if (current_cpu_type() == CPU_74K)
                        alias_74k_erratum(c);
                if ((read_c0_config7() & (1 << 16))) {
index 15f813c..fde7e56 100644 (file)
@@ -8,7 +8,6 @@
  */
 #include <linux/fs.h>
 #include <linux/fcntl.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/linkage.h>
 #include <linux/module.h>
index 191cf6e..5d5f296 100644 (file)
@@ -15,7 +15,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
-#include <linux/init.h>
 
 #include <asm/asm.h>
 #include <asm/regdef.h>
index 2e94185..44b6dff 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <dma-coherence.h>
 
+#ifdef CONFIG_DMA_MAYBE_COHERENT
 int coherentio = 0;    /* User defined DMA coherency from command line. */
 EXPORT_SYMBOL_GPL(coherentio);
 int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */
@@ -42,6 +43,7 @@ static int __init setnocoherentio(char *str)
        return 0;
 }
 early_param("nocoherentio", setnocoherentio);
+#endif
 
 static inline struct page *dma_addr_to_page(struct device *dev,
        dma_addr_t dma_addr)
index 01fda44..77e0ae0 100644 (file)
@@ -11,7 +11,6 @@
  * Copyright (C) 2008, 2009 Cavium Networks, Inc.
  */
 
-#include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
index 1215617..6b59617 100644 (file)
@@ -171,8 +171,6 @@ void *kmap_coherent(struct page *page, unsigned long addr)
        return (void*) vaddr;
 }
 
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
 void kunmap_coherent(void)
 {
 #ifndef CONFIG_MIPS_MT_SMTC
index cbd81d1..58033c4 100644 (file)
@@ -8,7 +8,6 @@
  * Copyright (C) 2008  Thiemo Seufer
  * Copyright (C) 2012  MIPS Technologies, Inc.
  */
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
index 08d05ae..7a56aee 100644 (file)
@@ -76,6 +76,8 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
        case CPU_34K:
        case CPU_74K:
        case CPU_1004K:
+       case CPU_INTERAPTIV:
+       case CPU_PROAPTIV:
        case CPU_BMIPS5000:
                if (config2 & (1 << 12))
                        return 0;
index aaffbba..9ac1efc 100644 (file)
@@ -6,7 +6,6 @@
 
 #undef DEBUG
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/bitops.h>
index 9aca109..d657493 100644 (file)
@@ -10,7 +10,6 @@
  * Copyright (C) 2002  Ralf Baechle
  * Copyright (C) 2002  Maciej W. Rozycki
  */
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
index da3b0b9..ae4ca24 100644 (file)
 #include <asm/bootinfo.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
+#include <asm/tlb.h>
 #include <asm/tlbmisc.h>
 
 extern void build_tlb_refill_handler(void);
 
-/*
- * Make sure all entries differ.  If they're not different
- * MIPS32 will take revenge ...
- */
-#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-
 /* Atomicity and interruptability */
 #ifdef CONFIG_MIPS_MT_SMTC
 
@@ -77,7 +72,7 @@ void local_flush_tlb_all(void)
 {
        unsigned long flags;
        unsigned long old_ctx;
-       int entry;
+       int entry, ftlbhighset;
 
        ENTER_CRITICAL(flags);
        /* Save old context and create impossible VPN2 value */
@@ -88,13 +83,30 @@ void local_flush_tlb_all(void)
        entry = read_c0_wired();
 
        /* Blast 'em all away. */
-       while (entry < current_cpu_data.tlbsize) {
-               /* Make sure all entries differ. */
-               write_c0_entryhi(UNIQUE_ENTRYHI(entry));
-               write_c0_index(entry);
-               mtc0_tlbw_hazard();
-               tlb_write_indexed();
-               entry++;
+       if (cpu_has_tlbinv) {
+               if (current_cpu_data.tlbsizevtlb) {
+                       write_c0_index(0);
+                       mtc0_tlbw_hazard();
+                       tlbinvf();  /* invalidate VTLB */
+               }
+               ftlbhighset = current_cpu_data.tlbsizevtlb +
+                       current_cpu_data.tlbsizeftlbsets;
+               for (entry = current_cpu_data.tlbsizevtlb;
+                    entry < ftlbhighset;
+                    entry++) {
+                       write_c0_index(entry);
+                       mtc0_tlbw_hazard();
+                       tlbinvf();  /* invalidate one FTLB set */
+               }
+       } else {
+               while (entry < current_cpu_data.tlbsize) {
+                       /* Make sure all entries differ. */
+                       write_c0_entryhi(UNIQUE_ENTRYHI(entry));
+                       write_c0_index(entry);
+                       mtc0_tlbw_hazard();
+                       tlb_write_indexed();
+                       entry++;
+               }
        }
        tlbw_use_hazard();
        write_c0_entryhi(old_ctx);
@@ -133,7 +145,9 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
                start = round_down(start, PAGE_SIZE << 1);
                end = round_up(end, PAGE_SIZE << 1);
                size = (end - start) >> (PAGE_SHIFT + 1);
-               if (size <= current_cpu_data.tlbsize/2) {
+               if (size <= (current_cpu_data.tlbsizeftlbsets ?
+                            current_cpu_data.tlbsize / 8 :
+                            current_cpu_data.tlbsize / 2)) {
                        int oldpid = read_c0_entryhi();
                        int newpid = cpu_asid(cpu, mm);
 
@@ -172,7 +186,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
        ENTER_CRITICAL(flags);
        size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
        size = (size + 1) >> 1;
-       if (size <= current_cpu_data.tlbsize / 2) {
+       if (size <= (current_cpu_data.tlbsizeftlbsets ?
+                    current_cpu_data.tlbsize / 8 :
+                    current_cpu_data.tlbsize / 2)) {
                int pid = read_c0_entryhi();
 
                start &= (PAGE_MASK << 1);
index 6a99733..138a2ec 100644 (file)
@@ -8,7 +8,6 @@
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
  */
-#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/mm.h>
index 183f2b5..b234b1b 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/types.h>
 #include <linux/smp.h>
 #include <linux/string.h>
-#include <linux/init.h>
 #include <linux/cache.h>
 
 #include <asm/cacheflush.h>
@@ -510,6 +509,7 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l,
                switch (current_cpu_type()) {
                case CPU_M14KC:
                case CPU_74K:
+               case CPU_PROAPTIV:
                        break;
 
                default:
index 060000f..b8d580c 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/init.h>
 
 #include <asm/inst.h>
 #include <asm/elf.h>
index 0c72458..3abd609 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/init.h>
 
 #include <asm/inst.h>
 #include <asm/elf.h>
index 72fdedb..eae0ba3 100644 (file)
@@ -9,7 +9,5 @@ obj-y                           := malta-amon.o malta-display.o malta-init.o \
                                   malta-int.o malta-memory.o malta-platform.o \
                                   malta-reset.o malta-setup.o malta-time.o
 
-obj-$(CONFIG_EARLY_PRINTK)     += malta-console.o
-
 # FIXME FIXME FIXME
 obj-$(CONFIG_MIPS_MT_SMTC)     += malta-smtc.o
index 1e47844..592ac04 100644 (file)
@@ -1,30 +1,20 @@
 /*
- * Copyright (C) 2007  MIPS Technologies, Inc.
- *     All rights reserved.
-
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
  *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * Copyright (C) 2007 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
  *
- * Arbitrary Monitor interface
+ * Arbitrary Monitor Interface
  */
-
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/smp.h>
 
 #include <asm/addrspace.h>
-#include <asm/mips-boards/launch.h>
 #include <asm/mipsmtregs.h>
+#include <asm/mips-boards/launch.h>
+#include <asm/vpe.h>
 
 int amon_cpu_avail(int cpu)
 {
@@ -48,7 +38,7 @@ int amon_cpu_avail(int cpu)
        return 1;
 }
 
-void amon_cpu_start(int cpu,
+int amon_cpu_start(int cpu,
                    unsigned long pc, unsigned long sp,
                    unsigned long gp, unsigned long a0)
 {
@@ -56,10 +46,10 @@ void amon_cpu_start(int cpu,
                (struct cpulaunch  *)CKSEG0ADDR(CPULAUNCH);
 
        if (!amon_cpu_avail(cpu))
-               return;
+               return -1;
        if (cpu == smp_processor_id()) {
                pr_debug("launch: I am cpu%d!\n", cpu);
-               return;
+               return -1;
        }
        launch += cpu;
 
@@ -78,4 +68,21 @@ void amon_cpu_start(int cpu,
                ;
        smp_rmb();      /* Target will be updating flags soon */
        pr_debug("launch: cpu%d gone!\n", cpu);
+
+       return 0;
+}
+
+#ifdef CONFIG_MIPS_VPE_LOADER
+int vpe_run(struct vpe *v)
+{
+       struct vpe_notifications *n;
+
+       if (amon_cpu_start(aprp_cpu_index(), v->__start, 0, 0, 0) < 0)
+               return -1;
+
+       list_for_each_entry(n, &v->notify, list)
+               n->start(VPE_MODULE_MINOR);
+
+       return 0;
 }
+#endif
diff --git a/arch/mips/mti-malta/malta-console.c b/arch/mips/mti-malta/malta-console.c
deleted file mode 100644 (file)
index 43bcfb4..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Putting things on the screen/serial line using YAMONs facilities.
- */
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/serial_reg.h>
-#include <asm/io.h>
-
-
-#define PORT(offset) (0x3f8 + (offset))
-
-
-static inline unsigned int serial_in(int offset)
-{
-       return inb(PORT(offset));
-}
-
-static inline void serial_out(int offset, int value)
-{
-       outb(value, PORT(offset));
-}
-
-int prom_putchar(char c)
-{
-       while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
-               ;
-
-       serial_out(UART_TX, c);
-
-       return 1;
-}
index ff8caff..fcebfce 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/serial_8250.h>
 
 #include <asm/cacheflush.h>
 #include <asm/smp-ops.h>
@@ -44,32 +45,39 @@ static void __init console_config(void)
        char parity = '\0', bits = '\0', flow = '\0';
        char *s;
 
-       if ((strstr(fw_getcmdline(), "console=")) == NULL) {
-               s = fw_getenv("modetty0");
-               if (s) {
-                       while (*s >= '0' && *s <= '9')
-                               baud = baud*10 + *s++ - '0';
-                       if (*s == ',')
-                               s++;
-                       if (*s)
-                               parity = *s++;
-                       if (*s == ',')
-                               s++;
-                       if (*s)
-                               bits = *s++;
-                       if (*s == ',')
-                               s++;
-                       if (*s == 'h')
-                               flow = 'r';
-               }
-               if (baud == 0)
-                       baud = 38400;
-               if (parity != 'n' && parity != 'o' && parity != 'e')
-                       parity = 'n';
-               if (bits != '7' && bits != '8')
-                       bits = '8';
-               if (flow == '\0')
+       s = fw_getenv("modetty0");
+       if (s) {
+               while (*s >= '0' && *s <= '9')
+                       baud = baud*10 + *s++ - '0';
+               if (*s == ',')
+                       s++;
+               if (*s)
+                       parity = *s++;
+               if (*s == ',')
+                       s++;
+               if (*s)
+                       bits = *s++;
+               if (*s == ',')
+                       s++;
+               if (*s == 'h')
                        flow = 'r';
+       }
+       if (baud == 0)
+               baud = 38400;
+       if (parity != 'n' && parity != 'o' && parity != 'e')
+               parity = 'n';
+       if (bits != '7' && bits != '8')
+               bits = '8';
+       if (flow == '\0')
+               flow = 'r';
+
+       if ((strstr(fw_getcmdline(), "earlycon=")) == NULL) {
+               sprintf(console_string, "uart8250,io,0x3f8,%d%c%c", baud,
+                       parity, bits);
+               setup_early_serial8250_console(console_string);
+       }
+
+       if ((strstr(fw_getcmdline(), "console=")) == NULL) {
                sprintf(console_string, " console=ttyS0,%d%c%c%c", baud,
                        parity, bits, flow);
                strcat(fw_getcmdline(), console_string);
index 0892575..ca3e3a4 100644 (file)
@@ -1,25 +1,16 @@
 /*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
  * Copyright (C) 2001 Ralf Baechle
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
  *
  * Routines for generic manipulation of the interrupts found on the MIPS
- * Malta board.
- * The interrupt controller is located in the South Bridge a PIIX4 device
- * with two internal 82C95 interrupt controllers.
+ * Malta board. The interrupt controller is located in the South Bridge
+ * a PIIX4 device with two internal 82C95 interrupt controllers.
  */
 #include <linux/init.h>
 #include <linux/irq.h>
@@ -44,6 +35,7 @@
 #include <asm/gic.h>
 #include <asm/gcmpregs.h>
 #include <asm/setup.h>
+#include <asm/rtlx.h>
 
 int gcmp_present = -1;
 static unsigned long _msc01_biu_base;
@@ -90,7 +82,7 @@ static inline int mips_pcibios_iack(void)
                BONITO_PCIMAP_CFG = 0;
                break;
        default:
-               printk(KERN_WARNING "Unknown system controller.\n");
+               pr_emerg("Unknown system controller.\n");
                return -1;
        }
        return irq;
@@ -126,6 +118,11 @@ static void malta_hw0_irqdispatch(void)
        }
 
        do_IRQ(MALTA_INT_BASE + irq);
+
+#ifdef MIPS_VPE_APSP_API
+       if (aprp_hook)
+               aprp_hook();
+#endif
 }
 
 static void malta_ipi_irqdispatch(void)
@@ -149,11 +146,11 @@ static void corehi_irqdispatch(void)
        unsigned int intrcause, datalo, datahi;
        struct pt_regs *regs = get_irq_regs();
 
-       printk(KERN_EMERG "CoreHI interrupt, shouldn't happen, we die here!\n");
-       printk(KERN_EMERG "epc   : %08lx\nStatus: %08lx\n"
-                       "Cause : %08lx\nbadVaddr : %08lx\n",
-                       regs->cp0_epc, regs->cp0_status,
-                       regs->cp0_cause, regs->cp0_badvaddr);
+       pr_emerg("CoreHI interrupt, shouldn't happen, we die here!\n");
+       pr_emerg("epc    : %08lx\nStatus: %08lx\n"
+                "Cause : %08lx\nbadVaddr : %08lx\n",
+                regs->cp0_epc, regs->cp0_status,
+                regs->cp0_cause, regs->cp0_badvaddr);
 
        /* Read all the registers and then print them as there is a
           problem with interspersed printk's upsetting the Bonito controller.
@@ -171,8 +168,8 @@ static void corehi_irqdispatch(void)
                intrcause = GT_READ(GT_INTRCAUSE_OFS);
                datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
                datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
-               printk(KERN_EMERG "GT_INTRCAUSE = %08x\n", intrcause);
-               printk(KERN_EMERG "GT_CPUERR_ADDR = %02x%08x\n",
+               pr_emerg("GT_INTRCAUSE = %08x\n", intrcause);
+               pr_emerg("GT_CPUERR_ADDR = %02x%08x\n",
                                datahi, datalo);
                break;
        case MIPS_REVISION_SCON_BONITO:
@@ -184,14 +181,14 @@ static void corehi_irqdispatch(void)
                intedge = BONITO_INTEDGE;
                intsteer = BONITO_INTSTEER;
                pcicmd = BONITO_PCICMD;
-               printk(KERN_EMERG "BONITO_INTISR = %08x\n", intisr);
-               printk(KERN_EMERG "BONITO_INTEN = %08x\n", inten);
-               printk(KERN_EMERG "BONITO_INTPOL = %08x\n", intpol);
-               printk(KERN_EMERG "BONITO_INTEDGE = %08x\n", intedge);
-               printk(KERN_EMERG "BONITO_INTSTEER = %08x\n", intsteer);
-               printk(KERN_EMERG "BONITO_PCICMD = %08x\n", pcicmd);
-               printk(KERN_EMERG "BONITO_PCIBADADDR = %08x\n", pcibadaddr);
-               printk(KERN_EMERG "BONITO_PCIMSTAT = %08x\n", pcimstat);
+               pr_emerg("BONITO_INTISR = %08x\n", intisr);
+               pr_emerg("BONITO_INTEN = %08x\n", inten);
+               pr_emerg("BONITO_INTPOL = %08x\n", intpol);
+               pr_emerg("BONITO_INTEDGE = %08x\n", intedge);
+               pr_emerg("BONITO_INTSTEER = %08x\n", intsteer);
+               pr_emerg("BONITO_PCICMD = %08x\n", pcicmd);
+               pr_emerg("BONITO_PCIBADADDR = %08x\n", pcibadaddr);
+               pr_emerg("BONITO_PCIMSTAT = %08x\n", pcimstat);
                break;
        }
 
@@ -313,6 +310,11 @@ static void ipi_call_dispatch(void)
 
 static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
 {
+#ifdef MIPS_VPE_APSP_API
+       if (aprp_hook)
+               aprp_hook();
+#endif
+
        scheduler_ipi();
 
        return IRQ_HANDLED;
@@ -365,13 +367,13 @@ static struct irqaction corehi_irqaction = {
        .flags = IRQF_NO_THREAD,
 };
 
-static msc_irqmap_t __initdata msc_irqmap[] = {
+static msc_irqmap_t msc_irqmap[] __initdata = {
        {MSC01C_INT_TMR,                MSC01_IRQ_EDGE, 0},
        {MSC01C_INT_PCI,                MSC01_IRQ_LEVEL, 0},
 };
-static int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap);
+static int msc_nr_irqs __initdata = ARRAY_SIZE(msc_irqmap);
 
-static msc_irqmap_t __initdata msc_eicirqmap[] = {
+static msc_irqmap_t msc_eicirqmap[] __initdata = {
        {MSC01E_INT_SW0,                MSC01_IRQ_LEVEL, 0},
        {MSC01E_INT_SW1,                MSC01_IRQ_LEVEL, 0},
        {MSC01E_INT_I8259A,             MSC01_IRQ_LEVEL, 0},
@@ -384,7 +386,7 @@ static msc_irqmap_t __initdata msc_eicirqmap[] = {
        {MSC01E_INT_CPUCTR,             MSC01_IRQ_LEVEL, 0}
 };
 
-static int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);
+static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap);
 
 /*
  * This GIC specific tabular array defines the association between External
@@ -431,9 +433,12 @@ int __init gcmp_probe(unsigned long addr, unsigned long size)
        if (gcmp_present >= 0)
                return gcmp_present;
 
-       _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ);
-       _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE, MSC01_BIU_ADDRSPACE_SZ);
-       gcmp_present = (GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) == GCMP_BASE_ADDR;
+       _gcmp_base = (unsigned long) ioremap_nocache(GCMP_BASE_ADDR,
+               GCMP_ADDRSPACE_SZ);
+       _msc01_biu_base = (unsigned long) ioremap_nocache(MSC01_BIU_REG_BASE,
+               MSC01_BIU_ADDRSPACE_SZ);
+       gcmp_present = ((GCMPGCB(GCMPB) & GCMP_GCB_GCMPB_GCMPBASE_MSK) ==
+               GCMP_BASE_ADDR);
 
        if (gcmp_present)
                pr_debug("GCMP present\n");
@@ -443,9 +448,8 @@ int __init gcmp_probe(unsigned long addr, unsigned long size)
 /* Return the number of IOCU's present */
 int __init gcmp_niocu(void)
 {
-  return gcmp_present ?
-    (GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >> GCMP_GCB_GC_NUMIOCU_SHF :
-    0;
+       return gcmp_present ? ((GCMPGCB(GC) & GCMP_GCB_GC_NUMIOCU_MSK) >>
+               GCMP_GCB_GC_NUMIOCU_SHF) : 0;
 }
 
 /* Set GCMP region attributes */
@@ -594,11 +598,14 @@ void __init arch_init_irq(void)
                        set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch);
                }
                /* Argh.. this really needs sorting out.. */
-               printk("CPU%d: status register was %08x\n", smp_processor_id(), read_c0_status());
+               pr_info("CPU%d: status register was %08x\n",
+                       smp_processor_id(), read_c0_status());
                write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4);
-               printk("CPU%d: status register now %08x\n", smp_processor_id(), read_c0_status());
+               pr_info("CPU%d: status register now %08x\n",
+                       smp_processor_id(), read_c0_status());
                write_c0_status(0x1100dc00);
-               printk("CPU%d: status register frc %08x\n", smp_processor_id(), read_c0_status());
+               pr_info("CPU%d: status register frc %08x\n",
+                       smp_processor_id(), read_c0_status());
                for (i = 0; i < nr_cpu_ids; i++) {
                        arch_init_ipiirq(MIPS_GIC_IRQ_BASE +
                                         GIC_RESCHED_INT(i), &irq_resched);
@@ -616,11 +623,15 @@ void __init arch_init_irq(void)
                        cpu_ipi_call_irq = MSC01E_INT_SW1;
                } else {
                        if (cpu_has_vint) {
-                               set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
-                               set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
+                               set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ,
+                                       ipi_resched_dispatch);
+                               set_vi_handler (MIPS_CPU_IPI_CALL_IRQ,
+                                       ipi_call_dispatch);
                        }
-                       cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
-                       cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ;
+                       cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE +
+                               MIPS_CPU_IPI_RESCHED_IRQ;
+                       cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE +
+                               MIPS_CPU_IPI_CALL_IRQ;
                }
                arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched);
                arch_init_ipiirq(cpu_ipi_call_irq, &irq_call);
@@ -630,9 +641,7 @@ void __init arch_init_irq(void)
 
 void malta_be_init(void)
 {
-       if (gcmp_present) {
-               /* Could change CM error mask register */
-       }
+       /* Could change CM error mask register. */
 }
 
 
@@ -712,14 +721,14 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup)
                        if (cause < 16) {
                                unsigned long cca_bits = (cm_error >> 15) & 7;
                                unsigned long tr_bits = (cm_error >> 12) & 7;
-                               unsigned long mcmd_bits = (cm_error >> 7) & 0x1f;
+                               unsigned long cmd_bits = (cm_error >> 7) & 0x1f;
                                unsigned long stag_bits = (cm_error >> 3) & 15;
                                unsigned long sport_bits = (cm_error >> 0) & 7;
 
                                snprintf(buf, sizeof(buf),
                                         "CCA=%lu TR=%s MCmd=%s STag=%lu "
                                         "SPort=%lu\n",
-                                        cca_bits, tr[tr_bits], mcmd[mcmd_bits],
+                                        cca_bits, tr[tr_bits], mcmd[cmd_bits],
                                         stag_bits, sport_bits);
                        } else {
                                /* glob state & sresp together */
@@ -728,7 +737,7 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup)
                                unsigned long c1_bits = (cm_error >> 12) & 7;
                                unsigned long c0_bits = (cm_error >> 9) & 7;
                                unsigned long sc_bit = (cm_error >> 8) & 1;
-                               unsigned long mcmd_bits = (cm_error >> 3) & 0x1f;
+                               unsigned long cmd_bits = (cm_error >> 3) & 0x1f;
                                unsigned long sport_bits = (cm_error >> 0) & 7;
                                snprintf(buf, sizeof(buf),
                                         "C3=%s C2=%s C1=%s C0=%s SC=%s "
@@ -736,16 +745,16 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup)
                                         core[c3_bits], core[c2_bits],
                                         core[c1_bits], core[c0_bits],
                                         sc_bit ? "True" : "False",
-                                        mcmd[mcmd_bits], sport_bits);
+                                        mcmd[cmd_bits], sport_bits);
                        }
 
                        ocause = (cm_other & GCMP_GCB_GMEO_ERROR_2ND_MSK) >>
                                 GCMP_GCB_GMEO_ERROR_2ND_SHF;
 
-                       printk("CM_ERROR=%08lx %s <%s>\n", cm_error,
+                       pr_err("CM_ERROR=%08lx %s <%s>\n", cm_error,
                               causes[cause], buf);
-                       printk("CM_ADDR =%08lx\n", cm_addr);
-                       printk("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]);
+                       pr_err("CM_ADDR =%08lx\n", cm_addr);
+                       pr_err("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]);
 
                        /* reprime cause register */
                        GCMPGCB(GCMEC) = 0;
index 132f866..e1dd1c1 100644 (file)
@@ -47,6 +47,7 @@
 static struct plat_serial8250_port uart8250_data[] = {
        SMC_PORT(0x3F8, 4),
        SMC_PORT(0x2F8, 3),
+#ifndef CONFIG_MIPS_CMP
        {
                .mapbase        = 0x1f000900,   /* The CBUS UART */
                .irq            = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2,
@@ -55,6 +56,7 @@ static struct plat_serial8250_port uart8250_data[] = {
                .flags          = CBUS_UART_FLAGS,
                .regshift       = 3,
        },
+#endif
        { },
 };
 
index a18af5f..3190099 100644 (file)
@@ -42,8 +42,6 @@
 #include <asm/mips-boards/generic.h>
 #include <asm/mips-boards/maltaint.h>
 
-unsigned long cpu_khz;
-
 static int mips_cpu_timer_irq;
 static int mips_cpu_perf_irq;
 extern int cp0_perfcount_irq;
@@ -168,11 +166,24 @@ unsigned int get_c0_compare_int(void)
        return mips_cpu_timer_irq;
 }
 
+static void __init init_rtc(void)
+{
+       /* stop the clock whilst setting it up */
+       CMOS_WRITE(RTC_SET | RTC_24H, RTC_CONTROL);
+
+       /* 32KHz time base */
+       CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_FREQ_SELECT);
+
+       /* start the clock */
+       CMOS_WRITE(RTC_24H, RTC_CONTROL);
+}
+
 void __init plat_time_init(void)
 {
        unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK);
        unsigned int freq;
 
+       init_rtc();
        estimate_frequencies();
 
        freq = mips_hpt_frequency;
@@ -182,7 +193,6 @@ void __init plat_time_init(void)
        freq = freqround(freq, 5000);
        printk("CPU frequency %d.%02d MHz\n", freq/1000000,
               (freq%1000000)*100/1000000);
-       cpu_khz = freq / 1000;
 
        mips_scroll_message();
 
index be11420..071786f 100644 (file)
@@ -21,5 +21,7 @@ obj-$(CONFIG_EARLY_PRINTK)    += sead3-console.o
 obj-$(CONFIG_USB_EHCI_HCD)     += sead3-ehci.o
 obj-$(CONFIG_OF)               += sead3.dtb.o
 
+CFLAGS_sead3-setup.o = -I$(src)/../../../scripts/dtc/libfdt
+
 $(obj)/%.dtb: $(obj)/%.dts
        $(call if_changed,dtc)
index eb2bf93..3b12aa5 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
-#include <linux/init.h>
 #include <linux/io.h>
 #include <linux/errno.h>
 
index 928ba84..bf7fe48 100644 (file)
@@ -4,13 +4,15 @@
  * for more details.
  *
  * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2013 Imagination Technologies Ltd.
  */
 #include <linux/init.h>
+#include <linux/libfdt.h>
 #include <linux/of_platform.h>
 #include <linux/of_fdt.h>
-#include <linux/bootmem.h>
 
 #include <asm/prom.h>
+#include <asm/fw/fw.h>
 
 #include <asm/mips-boards/generic.h>
 
@@ -19,8 +21,73 @@ const char *get_system_type(void)
        return "MIPS SEAD3";
 }
 
+static uint32_t get_memsize_from_cmdline(void)
+{
+       int memsize = 0;
+       char *p = arcs_cmdline;
+       char *s = "memsize=";
+
+       p = strstr(p, s);
+       if (p) {
+               p += strlen(s);
+               memsize = memparse(p, NULL);
+       }
+
+       return memsize;
+}
+
+static uint32_t get_memsize_from_env(void)
+{
+       int memsize = 0;
+       char *p;
+
+       p = fw_getenv("memsize");
+       if (p)
+               memsize = memparse(p, NULL);
+
+       return memsize;
+}
+
+static uint32_t get_memsize(void)
+{
+       uint32_t memsize;
+
+       memsize = get_memsize_from_cmdline();
+       if (memsize)
+               return memsize;
+
+       return get_memsize_from_env();
+}
+
+static void __init parse_memsize_param(void)
+{
+       int offset;
+       const uint64_t *prop_value;
+       int prop_len;
+       uint32_t memsize = get_memsize();
+
+       if (!memsize)
+               return;
+
+       offset = fdt_path_offset(&__dtb_start, "/memory");
+       if (offset > 0) {
+               uint64_t new_value;
+               /*
+                * reg contains 2 32-bits BE values, offset and size. We just
+                * want to replace the size value without affecting the offset
+                */
+               prop_value = fdt_getprop(&__dtb_start, offset, "reg", &prop_len);
+               new_value = be64_to_cpu(*prop_value);
+               new_value =  (new_value & ~0xffffffffllu) | memsize;
+               fdt_setprop_inplace_u64(&__dtb_start, offset, "reg", new_value);
+       }
+}
+
 void __init plat_mem_setup(void)
 {
+       /* allow command line/bootloader env to override memory size in DT */
+       parse_memsize_param();
+
        /*
         * Load the builtin devicetree. This causes the chosen node to be
         * parsed resulting in our memory appearing
@@ -30,16 +97,15 @@ void __init plat_mem_setup(void)
 
 void __init device_tree_init(void)
 {
-       unsigned long base, size;
-
        if (!initial_boot_params)
                return;
 
-       base = virt_to_phys((void *)initial_boot_params);
-       size = be32_to_cpu(initial_boot_params->totalsize);
-
-       /* Before we do anything, lets reserve the dt blob */
-       reserve_bootmem(base, size, BOOTMEM_DEFAULT);
+       unflatten_and_copy_device_tree();
+}
 
-       unflatten_device_tree();
+static int __init customize_machine(void)
+{
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       return 0;
 }
+arch_initcall(customize_machine);
index 552d26c..678d03d 100644 (file)
@@ -13,8 +13,6 @@
 #include <asm/irq.h>
 #include <asm/mips-boards/generic.h>
 
-unsigned long cpu_khz;
-
 static int mips_cpu_timer_irq;
 static int mips_cpu_perf_irq;
 
@@ -109,8 +107,6 @@ void __init plat_time_init(void)
        pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000),
                (est_freq % 1000000) * 100 / 1000000);
 
-       cpu_khz = est_freq / 1000;
-
        mips_scroll_message();
 
        plat_perf_setup();
index 658f437..e4b317d 100644 (file)
                };
        };
 
-       chosen {
-               bootargs = "console=ttyS1,38400 rootdelay=10 root=/dev/sda3";
-       };
-
        memory {
                device_type = "memory";
                reg = <0x0 0x08000000>;
index 852a4ee..4eb683a 100644 (file)
@@ -28,6 +28,15 @@ config DT_XLP_FVP
          pointer to the kernel.  The corresponding DTS file is at
          arch/mips/netlogic/dts/xlp_fvp.dts
 
+config DT_XLP_GVP
+       bool "Built-in device tree for XLP GVP boards"
+       default y
+       help
+         Add an FDT blob for XLP GVP 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_gvp.dts
+
 config NLM_MULTINODE
        bool "Support for multi-chip boards"
        depends on NLM_XLP_BOARD
index 1902fa2..769f930 100644 (file)
 
 #include <asm/mipsregs.h>
 #include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
 
 #if defined(CONFIG_CPU_XLP)
 #include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
 #include <asm/netlogic/xlp-hal/uart.h>
 #elif defined(CONFIG_CPU_XLR)
 #include <asm/netlogic/xlr/iomap.h>
index 1c7e3a1..5afc4b7 100644 (file)
@@ -180,6 +180,7 @@ static void __init nlm_init_percpu_irqs(void)
 #endif
 }
 
+
 void nlm_setup_pic_irq(int node, int picirq, int irq, int irt)
 {
        struct nlm_pic_irq *pic_data;
@@ -207,32 +208,32 @@ void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *))
 
 static void nlm_init_node_irqs(int node)
 {
-       int i, irt;
-       uint64_t irqmask;
        struct nlm_soc_info *nodep;
+       int i, irt;
 
        pr_info("Init IRQ for node %d\n", node);
        nodep = nlm_get_node(node);
-       irqmask = PERCPU_IRQ_MASK;
+       nodep->irqmask = PERCPU_IRQ_MASK;
        for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++) {
                irt = nlm_irq_to_irt(i);
-               if (irt == -1)
+               if (irt == -1)          /* unused irq */
                        continue;
-               nlm_setup_pic_irq(node, i, i, irt);
-               /* set interrupts to first cpu in node */
+               nodep->irqmask |= 1ull << i;
+               if (irt == -2)          /* not a direct PIC irq */
+                       continue;
+
                nlm_pic_init_irt(nodep->picbase, irt, i,
-                                       node * NLM_CPUS_PER_NODE, 0);
-               irqmask |= (1ull << i);
+                               node * nlm_threads_per_node(), 0);
+               nlm_setup_pic_irq(node, i, i, irt);
        }
-       nodep->irqmask = irqmask;
 }
 
 void nlm_smp_irq_init(int hwcpuid)
 {
        int node, cpu;
 
-       node = hwcpuid / NLM_CPUS_PER_NODE;
-       cpu  = hwcpuid % NLM_CPUS_PER_NODE;
+       node = nlm_cpuid_to_node(hwcpuid);
+       cpu  = hwcpuid % nlm_threads_per_node();
 
        if (cpu == 0 && node != 0)
                nlm_init_node_irqs(node);
@@ -256,13 +257,23 @@ asmlinkage void plat_irq_dispatch(void)
                return;
        }
 
+#if defined(CONFIG_PCI_MSI) && defined(CONFIG_CPU_XLP)
+       /* PCI interrupts need a second level dispatch for MSI bits */
+       if (i >= PIC_PCIE_LINK_MSI_IRQ(0) && i <= PIC_PCIE_LINK_MSI_IRQ(3)) {
+               nlm_dispatch_msi(node, i);
+               return;
+       }
+       if (i >= PIC_PCIE_MSIX_IRQ(0) && i <= PIC_PCIE_MSIX_IRQ(3)) {
+               nlm_dispatch_msix(node, i);
+               return;
+       }
+
+#endif
        /* top level irq handling */
        do_IRQ(nlm_irq_to_xirq(node, i));
 }
 
 #ifdef CONFIG_OF
-static struct irq_domain *xlp_pic_domain;
-
 static const struct irq_domain_ops xlp_pic_irq_domain_ops = {
        .xlate = irq_domain_xlate_onetwocell,
 };
@@ -271,8 +282,9 @@ static int __init xlp_of_pic_init(struct device_node *node,
                                        struct device_node *parent)
 {
        const int n_picirqs = PIC_IRT_LAST_IRQ - PIC_IRQ_BASE + 1;
+       struct irq_domain *xlp_pic_domain;
        struct resource res;
-       int socid, ret;
+       int socid, ret, bus;
 
        /* we need a hack to get the PIC's SoC chip id */
        ret = of_address_to_resource(node, 0, &res);
@@ -280,7 +292,34 @@ static int __init xlp_of_pic_init(struct device_node *node,
                pr_err("PIC %s: reg property not found!\n", node->name);
                return -EINVAL;
        }
-       socid = (res.start >> 18) & 0x3;
+
+       if (cpu_is_xlp9xx()) {
+               bus = (res.start >> 20) & 0xf;
+               for (socid = 0; socid < NLM_NR_NODES; socid++) {
+                       if (!nlm_node_present(socid))
+                               continue;
+                       if (nlm_get_node(socid)->socbus == bus)
+                               break;
+               }
+               if (socid == NLM_NR_NODES) {
+                       pr_err("PIC %s: Node mapping for bus %d not found!\n",
+                                       node->name, bus);
+                       return -EINVAL;
+               }
+       } else {
+               socid = (res.start >> 18) & 0x3;
+               if (!nlm_node_present(socid)) {
+                       pr_err("PIC %s: node %d does not exist!\n",
+                                                       node->name, socid);
+                       return -EINVAL;
+               }
+       }
+
+       if (!nlm_node_present(socid)) {
+               pr_err("PIC %s: node %d does not exist!\n", node->name, socid);
+               return -EINVAL;
+       }
+
        xlp_pic_domain = irq_domain_add_legacy(node, n_picirqs,
                nlm_irq_to_xirq(socid, PIC_IRQ_BASE), PIC_IRQ_BASE,
                &xlp_pic_irq_domain_ops, NULL);
@@ -288,8 +327,7 @@ static int __init xlp_of_pic_init(struct device_node *node,
                pr_err("PIC %s: Creating legacy domain failed!\n", node->name);
                return -EINVAL;
        }
-       pr_info("Node %d: IRQ domain created for PIC@%pa\n", socid,
-                                                       &res.start);
+       pr_info("Node %d: IRQ domain created for PIC@%pR\n", socid, &res);
        return 0;
 }
 
index adb1828..b231fe1 100644 (file)
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <linux/init.h>
 
 #include <asm/asm.h>
 #include <asm/asm-offsets.h>
+#include <asm/cacheops.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 #include <asm/stackframe.h>
@@ -50,8 +50,8 @@
 #include <asm/netlogic/xlp-hal/cpucontrol.h>
 
 #define CP0_EBASE      $15
-#define SYS_CPU_COHERENT_BASE(node)    CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
-                       XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
+#define SYS_CPU_COHERENT_BASE  CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
+                       XLP_IO_SYS_OFFSET(0) + XLP_IO_PCI_HDRSZ + \
                        SYS_CPU_NONCOHERENT_MODE * 4
 
 /* Enable XLP features and workarounds in the LSU */
 .endm
 
 /*
- * Low level flush for L1D cache on XLP, the normal cache ops does
- * not do the complete and correct cache flush.
+ * L1D cache has to be flushed before enabling threads in XLP.
+ * On XLP8xx/XLP3xx, we do a low level flush using processor control
+ * registers. On XLPII CPUs, usual cache instructions work.
  */
 .macro xlp_flush_l1_dcache
+       mfc0    t0, CP0_EBASE, 0
+       andi    t0, t0, 0xff00
+       slt     t1, t0, 0x1200
+       beqz    t1, 15f
+       nop
+
+       /* XLP8xx low level cache flush */
        li      t0, LSU_DEBUG_DATA0
        li      t1, LSU_DEBUG_ADDR
        li      t2, 0           /* index */
        li      t3, 0x1000      /* loop count */
-1:
+11:
        sll     v0, t2, 5
        mtcr    zero, t0
        ori     v1, v0, 0x3     /* way0 | write_enable | write_active */
        mtcr    v1, t1
-2:
+12:
        mfcr    v1, t1
        andi    v1, 0x1         /* wait for write_active == 0 */
-       bnez    v1, 2b
+       bnez    v1, 12b
        nop
        mtcr    zero, t0
        ori     v1, v0, 0x7     /* way1 | write_enable | write_active */
        mtcr    v1, t1
-3:
+13:
        mfcr    v1, t1
        andi    v1, 0x1         /* wait for write_active == 0 */
-       bnez    v1, 3b
+       bnez    v1, 13b
        nop
        addi    t2, 1
-       bne     t3, t2, 1b
+       bne     t3, t2, 11b
+       nop
+       b       17f
+       nop
+
+       /* XLPII CPUs, Invalidate all 64k of L1 D-cache */
+15:
+       li      t0, 0x80000000
+       li      t1, 0x80010000
+16:    cache   Index_Writeback_Inv_D, 0(t0)
+       addiu   t0, t0, 32
+       bne     t0, t1, 16b
        nop
+17:
 .endm
 
 /*
@@ -138,6 +158,13 @@ FEXPORT(nlm_reset_entry)
        nop
 
 1:     /* Entry point on core wakeup */
+       mfc0    t0, CP0_EBASE, 0        /* processor ID */
+       andi    t0, 0xff00
+       li      t1, 0x1500              /* XLP 9xx */
+       beq     t0, t1, 2f              /* does not need to set coherent */
+       nop
+
+       /* set bit in SYS coherent register for the core */
        mfc0    t0, CP0_EBASE, 1
        mfc0    t1, CP0_EBASE, 1
        srl     t1, 5
@@ -149,7 +176,7 @@ FEXPORT(nlm_reset_entry)
        li      t1, 0x1
        sll     t0, t1, t0
        nor     t0, t0, zero            /* t0 <- ~(1 << core) */
-       li      t2, SYS_CPU_COHERENT_BASE(0)
+       li      t2, SYS_CPU_COHERENT_BASE
        add     t2, t2, t3              /* t2 <- SYS offset for node */
        lw      t1, 0(t2)
        and     t1, t1, t0
@@ -159,13 +186,13 @@ FEXPORT(nlm_reset_entry)
        lw      t1, 0(t2)
        sync
 
+2:
        /* Configure LSU on Non-0 Cores. */
        xlp_config_lsu
        /* FALL THROUGH */
 
 /*
- * Wake up sibling threads from the initial thread in
- * a core.
+ * Wake up sibling threads from the initial thread in a core.
  */
 EXPORT(nlm_boot_siblings)
        /* core L1D flush before enable threads */
@@ -181,8 +208,10 @@ EXPORT(nlm_boot_siblings)
        /*
         * The new hardware thread starts at the next instruction
         * For all the cases other than core 0 thread 0, we will
-       * jump to the secondary wait function.
-       */
+        * jump to the secondary wait function.
+
+        * NOTE: All GPR contents are lost after the mtcr above!
+        */
        mfc0    v0, CP0_EBASE, 1
        andi    v0, 0x3ff               /* v0 <- node/core */
 
@@ -196,7 +225,7 @@ EXPORT(nlm_boot_siblings)
 #endif
        mtc0    t1, CP0_STATUS
 
-       /* mark CPU ready, careful here, previous mtcr trashed registers */
+       /* mark CPU ready */
        li      t3, CKSEG1ADDR(RESET_DATA_PHYS)
        ADDIU   t1, t3, BOOT_CPU_READY
        sll     v1, v0, 2
index c0eded0..6baae15 100644 (file)
@@ -63,7 +63,7 @@ void nlm_send_ipi_single(int logical_cpu, unsigned int action)
        uint64_t picbase;
 
        cpu = cpu_logical_map(logical_cpu);
-       node = cpu / NLM_CPUS_PER_NODE;
+       node = nlm_cpuid_to_node(cpu);
        picbase = nlm_get_node(node)->picbase;
 
        if (action & SMP_CALL_FUNCTION)
@@ -152,7 +152,7 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
        int cpu, node;
 
        cpu = cpu_logical_map(logical_cpu);
-       node = cpu / NLM_CPUS_PER_NODE;
+       node = nlm_cpuid_to_node(logical_cpu);
        nlm_next_sp = (unsigned long)__KSTK_TOS(idle);
        nlm_next_gp = (unsigned long)task_thread_info(idle);
 
@@ -164,7 +164,7 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
 void __init nlm_smp_setup(void)
 {
        unsigned int boot_cpu;
-       int num_cpus, i, ncore;
+       int num_cpus, i, ncore, node;
        volatile u32 *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
        char buf[64];
 
@@ -187,6 +187,8 @@ 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);
+                       cpumask_set_cpu(num_cpus, &nlm_get_node(node)->cpumask);
                        ++num_cpus;
                }
        }
index aa6cff0..8597657 100644 (file)
@@ -32,7 +32,6 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <linux/init.h>
 
 #include <asm/asm.h>
 #include <asm/asm-offsets.h>
@@ -98,7 +97,7 @@ END(nlm_boot_secondary_cpus)
  * In case of RMIboot bootloader which is used on XLR boards, the CPUs
  * be already woken up and waiting in bootloader code.
  * This will get them out of the bootloader code and into linux. Needed
- *  because the bootloader area will be taken and initialized by linux.
+ * because the bootloader area will be taken and initialized by linux.
  */
 NESTED(nlm_rmiboot_preboot, 16, sp)
        mfc0    t0, $15, 1      /* read ebase */
@@ -133,6 +132,7 @@ NESTED(nlm_rmiboot_preboot, 16, sp)
        or      t1, t2, v1      /* put in new value */
        mtcr    t1, t0          /* update core control */
 
+       /* wait for NMI to hit */
 1:     wait
        b       1b
        nop
index 0b9be5f..25c8e87 100644 (file)
@@ -1,3 +1,4 @@
 obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o
 obj-$(CONFIG_DT_XLP_SVP) += xlp_svp.dtb.o
 obj-$(CONFIG_DT_XLP_FVP) += xlp_fvp.dtb.o
+obj-$(CONFIG_DT_XLP_GVP) += xlp_gvp.dtb.o
diff --git a/arch/mips/netlogic/dts/xlp_gvp.dts b/arch/mips/netlogic/dts/xlp_gvp.dts
new file mode 100644 (file)
index 0000000..047d27f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * XLP9XX Device Tree Source for GVP boards
+ */
+
+/dts-v1/;
+/ {
+       model = "netlogic,XLP-GVP";
+       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@4000 {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+                       reg = <0 0x110000 0x200>;
+               };
+
+               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";
+       };
+};
index 8316d54..5754097 100644 (file)
 #include <asm/prom.h>
 
 extern u32 __dtb_xlp_evp_begin[], __dtb_xlp_svp_begin[],
-       __dtb_xlp_fvp_begin[], __dtb_start[];
+       __dtb_xlp_fvp_begin[], __dtb_xlp_gvp_begin[], __dtb_start[];
 static void *xlp_fdt_blob;
 
 void __init *xlp_dt_init(void *fdtp)
 {
        if (!fdtp) {
                switch (current_cpu_data.processor_id & 0xff00) {
+#ifdef CONFIG_DT_XLP_GVP
+               case PRID_IMP_NETLOGIC_XLP9XX:
+                       fdtp = __dtb_xlp_gvp_begin;
+                       break;
+#endif
 #ifdef CONFIG_DT_XLP_FVP
                case PRID_IMP_NETLOGIC_XLP2XX:
                        fdtp = __dtb_xlp_fvp_begin;
index 56c50ba..997cd9e 100644 (file)
@@ -57,6 +57,10 @@ void nlm_node_init(int node)
        nodep->sysbase = nlm_get_sys_regbase(node);
        nodep->picbase = nlm_get_pic_regbase(node);
        nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));
+       if (cpu_is_xlp9xx())
+               nodep->socbus = xlp9xx_get_socbus(node);
+       else
+               nodep->socbus = 0;
        spin_lock_init(&nodep->piclock);
 }
 
@@ -65,6 +69,26 @@ int nlm_irq_to_irt(int irq)
        uint64_t pcibase;
        int devoff, irt;
 
+       /* bypass for 9xx */
+       if (cpu_is_xlp9xx()) {
+               switch (irq) {
+               case PIC_9XX_XHCI_0_IRQ:
+                       return 114;
+               case PIC_9XX_XHCI_1_IRQ:
+                       return 115;
+               case PIC_UART_0_IRQ:
+                       return 133;
+               case PIC_UART_1_IRQ:
+                       return 134;
+               case PIC_PCIE_LINK_LEGACY_IRQ(0):
+               case PIC_PCIE_LINK_LEGACY_IRQ(1):
+               case PIC_PCIE_LINK_LEGACY_IRQ(2):
+               case PIC_PCIE_LINK_LEGACY_IRQ(3):
+                       return 191 + irq - PIC_PCIE_LINK_LEGACY_IRQ_BASE;
+               }
+               return -1;
+       }
+
        devoff = 0;
        switch (irq) {
        case PIC_UART_0_IRQ:
@@ -135,9 +159,17 @@ int nlm_irq_to_irt(int irq)
                case PIC_I2C_3_IRQ:
                        irt = irt + 3; break;
                }
-       } else if (irq >= PIC_PCIE_LINK_0_IRQ && irq <= PIC_PCIE_LINK_3_IRQ) {
+       } else if (irq >= PIC_PCIE_LINK_LEGACY_IRQ(0) &&
+                       irq <= PIC_PCIE_LINK_LEGACY_IRQ(3)) {
                /* HW bug, PCI IRT entries are bad on early silicon, fix */
-               irt = PIC_IRT_PCIE_LINK_INDEX(irq - PIC_PCIE_LINK_0_IRQ);
+               irt = PIC_IRT_PCIE_LINK_INDEX(irq -
+                                       PIC_PCIE_LINK_LEGACY_IRQ_BASE);
+       } else if (irq >= PIC_PCIE_LINK_MSI_IRQ(0) &&
+                       irq <= PIC_PCIE_LINK_MSI_IRQ(3)) {
+               irt = -2;
+       } else if (irq >= PIC_PCIE_MSIX_IRQ(0) &&
+                       irq <= PIC_PCIE_MSIX_IRQ(3)) {
+               irt = -2;
        } else {
                irt = -1;
        }
@@ -151,7 +183,10 @@ unsigned int nlm_get_core_frequency(int node, int core)
        uint64_t num, sysbase;
 
        sysbase = nlm_get_node(node)->sysbase;
-       rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
+       if (cpu_is_xlp9xx())
+               rstval = nlm_read_sys_reg(sysbase, SYS_9XX_POWER_ON_RESET_CFG);
+       else
+               rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
        if (cpu_is_xlpii()) {
                num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26));
                denom = 3;
@@ -265,6 +300,10 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
 
 unsigned int nlm_get_pic_frequency(int node)
 {
+       /* TODO Has to calculate freq as like 2xx */
+       if (cpu_is_xlp9xx())
+               return 250000000;
+
        if (cpu_is_xlpii())
                return nlm_2xx_get_pic_frequency(node);
        else
@@ -284,21 +323,33 @@ int xlp_get_dram_map(int n, uint64_t *dram_map)
 {
        uint64_t bridgebase, base, lim;
        uint32_t val;
+       unsigned int barreg, limreg, xlatreg;
        int i, node, 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++) {
-               val = nlm_read_bridge_reg(bridgebase,
-                                       BRIDGE_DRAM_NODE_TRANSLN(i));
-               node = (val >> 1) & 0x3;
-               if (n >= 0 && n != node)
-                       continue;
-               val = nlm_read_bridge_reg(bridgebase, BRIDGE_DRAM_BAR(i));
+               if (cpu_is_xlp9xx()) {
+                       barreg = BRIDGE_9XX_DRAM_BAR(i);
+                       limreg = BRIDGE_9XX_DRAM_LIMIT(i);
+                       xlatreg = BRIDGE_9XX_DRAM_NODE_TRANSLN(i);
+               } else {
+                       barreg = BRIDGE_DRAM_BAR(i);
+                       limreg = BRIDGE_DRAM_LIMIT(i);
+                       xlatreg = BRIDGE_DRAM_NODE_TRANSLN(i);
+               }
+               if (n >= 0) {
+                       /* node specified, get node mapping of BAR */
+                       val = nlm_read_bridge_reg(bridgebase, xlatreg);
+                       node = (val >> 1) & 0x3;
+                       if (n != node)
+                               continue;
+               }
+               val = nlm_read_bridge_reg(bridgebase, barreg);
                val = (val >>  12) & 0xfffff;
                base = (uint64_t) val << 20;
-               val = nlm_read_bridge_reg(bridgebase, BRIDGE_DRAM_LIMIT(i));
+               val = nlm_read_bridge_reg(bridgebase, limreg);
                val = (val >>  12) & 0xfffff;
                if (val == 0)   /* BAR not used */
                        continue;
index 54e75c7..8c60a2d 100644 (file)
@@ -51,12 +51,16 @@ 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)
 {
        uint64_t sysbase = nlm_get_node(0)->sysbase;
 
-       nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1);
+       if (cpu_is_xlp9xx())
+               nlm_write_sys_reg(sysbase, SYS_9XX_CHIP_RESET, 1);
+       else
+               nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1);
        for ( ; ; )
                cpu_wait();
 }
@@ -92,6 +96,14 @@ static void __init xlp_init_mem_from_bars(void)
 
 void __init plat_mem_setup(void)
 {
+#ifdef CONFIG_SMP
+       nlm_wakeup_secondary_cpus();
+
+       /* update TLB size after waking up threads */
+       current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
+
+       register_smp_ops(&nlm_smp_ops);
+#endif
        _machine_restart = (void (*)(char *))nlm_linux_exit;
        _machine_halt   = nlm_linux_exit;
        pm_power_off    = nlm_linux_exit;
@@ -110,6 +122,7 @@ void __init plat_mem_setup(void)
 const char *get_system_type(void)
 {
        switch (read_c0_prid() & 0xff00) {
+       case PRID_IMP_NETLOGIC_XLP9XX:
        case PRID_IMP_NETLOGIC_XLP2XX:
                return "Broadcom XLPII Series";
        default:
@@ -149,6 +162,10 @@ 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);
@@ -162,11 +179,5 @@ void __init prom_init(void)
 
 #ifdef CONFIG_SMP
        cpumask_setall(&nlm_cpumask);
-       nlm_wakeup_secondary_cpus();
-
-       /* update TLB size after waking up threads */
-       current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
-
-       register_smp_ops(&nlm_smp_ops);
 #endif
 }
index 36e9c22..17ade1c 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 
 #define nlm_read_usb_reg(b, r)         nlm_read_reg(b, r)
 #define nlm_write_usb_reg(b, r, v)     nlm_write_reg(b, r, v)
 
-#define nlm_xlpii_get_usb_pcibase(node, inst)          \
-       nlm_pcicfg_base(XLP2XX_IO_USB_OFFSET(node, inst))
+#define nlm_xlpii_get_usb_pcibase(node, inst)                  \
+                       nlm_pcicfg_base(cpu_is_xlp9xx() ?       \
+                       XLP9XX_IO_USB_OFFSET(node, inst) :      \
+                       XLP2XX_IO_USB_OFFSET(node, inst))
 #define nlm_xlpii_get_usb_regbase(node, inst)          \
        (nlm_xlpii_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ)
 
-static void xlpii_usb_ack(struct irq_data *data)
+static void xlp2xx_usb_ack(struct irq_data *data)
 {
        u64 port_addr;
 
@@ -109,6 +112,29 @@ static void xlpii_usb_ack(struct irq_data *data)
        nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff);
 }
 
+static void xlp9xx_usb_ack(struct irq_data *data)
+{
+       u64 port_addr;
+       int node, irq;
+
+       /* Find the node and irq on the node */
+       irq = data->irq % NLM_IRQS_PER_NODE;
+       node = data->irq / NLM_IRQS_PER_NODE;
+
+       switch (irq) {
+       case PIC_9XX_XHCI_0_IRQ:
+               port_addr = nlm_xlpii_get_usb_regbase(node, 1);
+               break;
+       case PIC_9XX_XHCI_1_IRQ:
+               port_addr = nlm_xlpii_get_usb_regbase(node, 2);
+               break;
+       default:
+               pr_err("No matching USB irq %d node  %d!\n", irq, node);
+               return;
+       }
+       nlm_write_usb_reg(port_addr, XLPII_USB3_INT_REG, 0xffffffff);
+}
+
 static void nlm_xlpii_usb_hw_reset(int node, int port)
 {
        u64 port_addr, xhci_base, pci_base;
@@ -178,17 +204,33 @@ static void nlm_xlpii_usb_hw_reset(int node, int port)
 
 static int __init nlm_platform_xlpii_usb_init(void)
 {
+       int node;
+
        if (!cpu_is_xlpii())
                return 0;
 
-       pr_info("Initializing 2XX USB Interface\n");
-       nlm_xlpii_usb_hw_reset(0, 1);
-       nlm_xlpii_usb_hw_reset(0, 2);
-       nlm_xlpii_usb_hw_reset(0, 3);
-       nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlpii_usb_ack);
-       nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlpii_usb_ack);
-       nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlpii_usb_ack);
+       if (!cpu_is_xlp9xx()) {
+               /* XLP 2XX single node */
+               pr_info("Initializing 2XX USB Interface\n");
+               nlm_xlpii_usb_hw_reset(0, 1);
+               nlm_xlpii_usb_hw_reset(0, 2);
+               nlm_xlpii_usb_hw_reset(0, 3);
+               nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_0_IRQ, xlp2xx_usb_ack);
+               nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_1_IRQ, xlp2xx_usb_ack);
+               nlm_set_pic_extra_ack(0, PIC_2XX_XHCI_2_IRQ, xlp2xx_usb_ack);
+               return 0;
+       }
 
+       /* XLP 9XX, multi-node */
+       pr_info("Initializing 9XX 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_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);
+       }
        return 0;
 }
 
@@ -196,8 +238,26 @@ arch_initcall(nlm_platform_xlpii_usb_init);
 
 static u64 xlp_usb_dmamask = ~(u32)0;
 
-/* Fixup IRQ for USB devices on XLP the SoC PCIe bus */
-static void nlm_usb_fixup_final(struct pci_dev *dev)
+/* Fixup the IRQ for USB devices which is exist on XLP9XX SOC PCIE bus */
+static void nlm_xlp9xx_usb_fixup_final(struct pci_dev *dev)
+{
+       int node;
+
+       node = xlp_socdev_to_node(dev);
+       dev->dev.dma_mask               = &xlp_usb_dmamask;
+       dev->dev.coherent_dma_mask      = DMA_BIT_MASK(32);
+       switch (dev->devfn) {
+       case 0x21:
+               dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_0_IRQ);
+               break;
+       case 0x22:
+               dev->irq = nlm_irq_to_xirq(node, PIC_9XX_XHCI_1_IRQ);
+               break;
+       }
+}
+
+/* Fixup the IRQ for USB devices which is exist on XLP2XX SOC PCIE bus */
+static void nlm_xlp2xx_usb_fixup_final(struct pci_dev *dev)
 {
        dev->dev.dma_mask               = &xlp_usb_dmamask;
        dev->dev.coherent_dma_mask      = DMA_BIT_MASK(32);
@@ -214,5 +274,7 @@ static void nlm_usb_fixup_final(struct pci_dev *dev)
        }
 }
 
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_XLP9XX_XHCI,
+               nlm_xlp9xx_usb_fixup_final);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_XHCI,
-               nlm_usb_fixup_final);
+               nlm_xlp2xx_usb_fixup_final);
index 682d563..9a92617 100644 (file)
@@ -32,7 +32,6 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/threads.h>
 
 #include <asm/netlogic/mips-extns.h>
 
 #include <asm/netlogic/xlp-hal/iomap.h>
-#include <asm/netlogic/xlp-hal/pic.h>
 #include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pic.h>
 #include <asm/netlogic/xlp-hal/sys.h>
 
 static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
 {
        uint32_t coremask, value;
-       int count;
+       int count, resetreg;
 
        coremask = (1 << core);
 
@@ -65,12 +64,24 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
                nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);
        }
 
+       /* On 9XX, mark coherent first */
+       if (cpu_is_xlp9xx()) {
+               value = nlm_read_sys_reg(sysbase, SYS_9XX_CPU_NONCOHERENT_MODE);
+               value &= ~coremask;
+               nlm_write_sys_reg(sysbase, SYS_9XX_CPU_NONCOHERENT_MODE, value);
+       }
+
        /* Remove CPU Reset */
-       value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET);
+       resetreg = cpu_is_xlp9xx() ? SYS_9XX_CPU_RESET : SYS_CPU_RESET;
+       value = nlm_read_sys_reg(sysbase, resetreg);
        value &= ~coremask;
-       nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value);
+       nlm_write_sys_reg(sysbase, resetreg, value);
+
+       /* We are done on 9XX */
+       if (cpu_is_xlp9xx())
+               return 1;
 
-       /* Poll for CPU to mark itself coherent */
+       /* Poll for CPU to mark itself coherent on other type of XLP */
        count = 100000;
        do {
                value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE);
@@ -84,7 +95,7 @@ static int wait_for_cpus(int cpu, int bootcpu)
        volatile uint32_t *cpu_ready = nlm_get_boot_data(BOOT_CPU_READY);
        int i, count, notready;
 
-       count = 0x20000000;
+       count = 0x800000;
        do {
                notready = nlm_threads_per_core;
                for (i = 0; i < nlm_threads_per_core; i++)
@@ -98,27 +109,62 @@ static int wait_for_cpus(int cpu, int bootcpu)
 static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
 {
        struct nlm_soc_info *nodep;
-       uint64_t syspcibase;
-       uint32_t syscoremask;
+       uint64_t syspcibase, fusebase;
+       uint32_t syscoremask, mask, fusemask;
        int core, n, cpu;
 
        for (n = 0; n < NLM_NR_NODES; n++) {
-               syspcibase = nlm_get_sys_pcibase(n);
-               if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
-                       break;
+               if (n != 0) {
+                       /* check if node exists and is online */
+                       if (cpu_is_xlp9xx()) {
+                               int b = xlp9xx_get_socbus(n);
+                               pr_info("Node %d SoC PCI bus %d.\n", n, b);
+                               if (b == 0)
+                                       break;
+                       } else {
+                               syspcibase = nlm_get_sys_pcibase(n);
+                               if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
+                                       break;
+                       }
+                       nlm_node_init(n);
+               }
 
                /* read cores in reset from SYS */
-               if (n != 0)
-                       nlm_node_init(n);
                nodep = nlm_get_node(n);
-               syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);
+
+               if (cpu_is_xlp9xx()) {
+                       fusebase = nlm_get_fuse_regbase(n);
+                       fusemask = nlm_read_reg(fusebase, FUSE_9XX_DEVCFG6);
+                       mask = 0xfffff;
+               } else {
+                       fusemask = nlm_read_sys_reg(nodep->sysbase,
+                                               SYS_EFUSE_DEVICE_CFG_STATUS0);
+                       switch (read_c0_prid() & 0xff00) {
+                       case PRID_IMP_NETLOGIC_XLP3XX:
+                               mask = 0xf;
+                               break;
+                       case PRID_IMP_NETLOGIC_XLP2XX:
+                               mask = 0x3;
+                               break;
+                       case PRID_IMP_NETLOGIC_XLP8XX:
+                       default:
+                               mask = 0xff;
+                               break;
+                       }
+               }
+
+               /*
+                * Fused out cores are set in the fusemask, and the remaining
+                * cores are renumbered to range 0 .. nactive-1
+                */
+               syscoremask = (1 << hweight32(~fusemask & mask)) - 1;
+
                /* The boot cpu */
-               if (n == 0) {
-                       syscoremask |= 1;
+               if (n == 0)
                        nodep->coremask = 1;
-               }
 
-               for (core = 0; core < NLM_CORES_PER_NODE; core++) {
+               pr_info("Node %d - SYS/FUSE coremask %x\n", n, syscoremask);
+               for (core = 0; core < nlm_cores_per_node(); core++) {
                        /* we will be on node 0 core 0 */
                        if (n == 0 && core == 0)
                                continue;
@@ -128,7 +174,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)
+                       cpu = (n * nlm_cores_per_node() + core)
                                                * NLM_THREADS_PER_CORE;
                        if (!cpumask_test_cpu(cpu, wakeup_mask))
                                continue;
@@ -141,7 +187,8 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
                        nodep->coremask |= 1u << core;
 
                        /* spin until the hw threads sets their ready */
-                       wait_for_cpus(cpu, 0);
+                       if (!wait_for_cpus(cpu, 0))
+                               pr_err("Node %d : timeout core %d\n", n, core);
                }
        }
 }
@@ -153,7 +200,8 @@ void xlp_wakeup_secondary_cpus()
         * first wakeup core 0 threads
         */
        xlp_boot_core0_siblings();
-       wait_for_cpus(0, 0);
+       if (!wait_for_cpus(0, 0))
+               pr_err("Node 0 : timeout core 0\n");
 
        /* now get other cores out of reset */
        xlp_enable_secondary_cores(&nlm_cpumask);
index 7b96a91..4785932 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/netlogic/xlr/pic.h>
 #include <asm/netlogic/xlr/xlr.h>
 
-unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
+static unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
 {
        uint64_t uartbase;
        unsigned int value;
@@ -41,7 +41,7 @@ unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
        return value;
 }
 
-void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
+static void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
 {
        uint64_t uartbase;
 
index 921be5f..d118b9a 100644 (file)
@@ -60,25 +60,6 @@ unsigned int  nlm_threads_per_core = 1;
 struct nlm_soc_info nlm_nodes[NLM_NR_NODES];
 cpumask_t nlm_cpumask = CPU_MASK_CPU0;
 
-static void __init nlm_early_serial_setup(void)
-{
-       struct uart_port s;
-       unsigned long uart_base;
-
-       uart_base = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
-       memset(&s, 0, sizeof(s));
-       s.flags         = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
-       s.iotype        = UPIO_MEM32;
-       s.regshift      = 2;
-       s.irq           = PIC_UART_0_IRQ;
-       s.uartclk       = PIC_CLK_HZ;
-       s.serial_in     = nlm_xlr_uart_in;
-       s.serial_out    = nlm_xlr_uart_out;
-       s.mapbase       = uart_base;
-       s.membase       = (unsigned char __iomem *)uart_base;
-       early_serial_setup(&s);
-}
-
 static void nlm_linux_exit(void)
 {
        uint64_t gpiobase;
@@ -214,7 +195,6 @@ void __init prom_init(void)
        memcpy(reset_vec, (void *)nlm_reset_entry,
                        (nlm_reset_entry_end - nlm_reset_entry));
 
-       nlm_early_serial_setup();
        build_arcs_cmdline(argv);
        prom_add_memory();
 
index 9fb81fa..d61cba1 100644 (file)
@@ -32,7 +32,6 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/threads.h>
 
@@ -70,7 +69,7 @@ int xlr_wakeup_secondary_cpus(void)
 
        /* Fill up the coremask early */
        nodep->coremask = 1;
-       for (i = 1; i < NLM_CORES_PER_NODE; i++) {
+       for (i = 1; i < nlm_cores_per_node(); i++) {
                for (j = 1000000; j > 0; j--) {
                        if (cpu_ready[i * NLM_THREADS_PER_CORE])
                                break;
index 4d1736f..2a86e38 100644 (file)
@@ -86,6 +86,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        case CPU_34K:
        case CPU_1004K:
        case CPU_74K:
+       case CPU_INTERAPTIV:
+       case CPU_PROAPTIV:
        case CPU_LOONGSON1:
        case CPU_SB1:
        case CPU_SB1A:
index 3a2b6e9..4d94d75 100644 (file)
@@ -376,6 +376,14 @@ static int __init mipsxx_init(void)
                op_model_mipsxx_ops.cpu_type = "mips/74K";
                break;
 
+       case CPU_INTERAPTIV:
+               op_model_mipsxx_ops.cpu_type = "mips/interAptiv";
+               break;
+
+       case CPU_PROAPTIV:
+               op_model_mipsxx_ops.cpu_type = "mips/proAptiv";
+               break;
+
        case CPU_5KC:
                op_model_mipsxx_ops.cpu_type = "mips/5K";
                break;
index 719e455..137f2a6 100644 (file)
@@ -60,4 +60,5 @@ obj-$(CONFIG_CPU_XLP)         += pci-xlp.o
 
 ifdef CONFIG_PCI_MSI
 obj-$(CONFIG_CAVIUM_OCTEON_SOC) += msi-octeon.o
+obj-$(CONFIG_CPU_XLP)          += msi-xlp.o
 endif
index df36e23..7a0eda7 100644 (file)
@@ -54,6 +54,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
 static void malta_piix_func0_fixup(struct pci_dev *pdev)
 {
        unsigned char reg_val;
+       u32 reg_val32;
        /* PIIX PIRQC[A:D] irq mappings */
        static int piixirqmap[PIIX4_FUNC0_PIRQRC_IRQ_ROUTING_MAX] = {
                0,  0,  0,  3,
@@ -83,6 +84,16 @@ static void malta_piix_func0_fixup(struct pci_dev *pdev)
                pci_write_config_byte(pdev, PIIX4_FUNC0_TOM, reg_val |
                                PIIX4_FUNC0_TOM_TOP_OF_MEMORY_MASK);
        }
+
+       /* Mux SERIRQ to its pin */
+       pci_read_config_dword(pdev, PIIX4_FUNC0_GENCFG, &reg_val32);
+       pci_write_config_dword(pdev, PIIX4_FUNC0_GENCFG,
+                              reg_val32 | PIIX4_FUNC0_GENCFG_SERIRQ);
+
+       /* Enable SERIRQ */
+       pci_read_config_byte(pdev, PIIX4_FUNC0_SERIRQC, &reg_val);
+       reg_val |= PIIX4_FUNC0_SERIRQC_EN | PIIX4_FUNC0_SERIRQC_CONT;
+       pci_write_config_byte(pdev, PIIX4_FUNC0_SERIRQC, reg_val);
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
index d0f6ecb..7fcafd5 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 
 #include <asm/mach-rc32434/rc32434.h>
 #include <asm/mach-rc32434/irq.h>
index 1441bec..8feae91 100644 (file)
@@ -8,7 +8,6 @@
  *     2 of the License, or (at your option) any later version.
  */
 
-#include <linux/init.h>
 #include <linux/pci.h>
 
 /*
diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
new file mode 100644 (file)
index 0000000..afd8405
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/msi.h>
+#include <linux/mm.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/console.h>
+
+#include <asm/io.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
+#include <asm/netlogic/mips-extns.h>
+
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pic.h>
+#include <asm/netlogic/xlp-hal/pcibus.h>
+#include <asm/netlogic/xlp-hal/bridge.h>
+
+#define XLP_MSIVEC_PER_LINK    32
+#define XLP_MSIXVEC_TOTAL      32
+#define XLP_MSIXVEC_PER_LINK   8
+
+/* 128 MSI irqs per node, mapped starting at NLM_MSI_VEC_BASE */
+static inline int nlm_link_msiirq(int link, int msivec)
+{
+       return NLM_MSI_VEC_BASE + link * XLP_MSIVEC_PER_LINK + msivec;
+}
+
+static inline int nlm_irq_msivec(int irq)
+{
+       return irq % XLP_MSIVEC_PER_LINK;
+}
+
+static inline int nlm_irq_msilink(int irq)
+{
+       return (irq % (XLP_MSIVEC_PER_LINK * PCIE_NLINKS)) /
+                                               XLP_MSIVEC_PER_LINK;
+}
+
+/*
+ * Only 32 MSI-X vectors are possible because there are only 32 PIC
+ * interrupts for MSI. We split them statically and use 8 MSI-X vectors
+ * per link - this keeps the allocation and lookup simple.
+ */
+static inline int nlm_link_msixirq(int link, int bit)
+{
+       return NLM_MSIX_VEC_BASE + link * XLP_MSIXVEC_PER_LINK + bit;
+}
+
+static inline int nlm_irq_msixvec(int irq)
+{
+       return irq % XLP_MSIXVEC_TOTAL;  /* works when given xirq */
+}
+
+static inline int nlm_irq_msixlink(int irq)
+{
+       return nlm_irq_msixvec(irq) / XLP_MSIXVEC_PER_LINK;
+}
+
+/*
+ * Per link MSI and MSI-X information, set as IRQ handler data for
+ * MSI and MSI-X interrupts.
+ */
+struct xlp_msi_data {
+       struct nlm_soc_info *node;
+       uint64_t        lnkbase;
+       uint32_t        msi_enabled_mask;
+       uint32_t        msi_alloc_mask;
+       uint32_t        msix_alloc_mask;
+       spinlock_t      msi_lock;
+};
+
+/*
+ * MSI Chip definitions
+ *
+ * On XLP, there is a PIC interrupt associated with each PCIe link on the
+ * chip (which appears as a PCI bridge to us). This gives us 32 MSI irqa
+ * per link and 128 overall.
+ *
+ * When a device connected to the link raises a MSI interrupt, we get a
+ * link interrupt and we then have to look at PCIE_MSI_STATUS register at
+ * the bridge to map it to the IRQ
+ */
+static void xlp_msi_enable(struct irq_data *d)
+{
+       struct xlp_msi_data *md = irq_data_get_irq_handler_data(d);
+       unsigned long flags;
+       int vec;
+
+       vec = nlm_irq_msivec(d->irq);
+       spin_lock_irqsave(&md->msi_lock, flags);
+       md->msi_enabled_mask |= 1u << vec;
+       nlm_write_reg(md->lnkbase, PCIE_MSI_EN, md->msi_enabled_mask);
+       spin_unlock_irqrestore(&md->msi_lock, flags);
+}
+
+static void xlp_msi_disable(struct irq_data *d)
+{
+       struct xlp_msi_data *md = irq_data_get_irq_handler_data(d);
+       unsigned long flags;
+       int vec;
+
+       vec = nlm_irq_msivec(d->irq);
+       spin_lock_irqsave(&md->msi_lock, flags);
+       md->msi_enabled_mask &= ~(1u << vec);
+       nlm_write_reg(md->lnkbase, PCIE_MSI_EN, md->msi_enabled_mask);
+       spin_unlock_irqrestore(&md->msi_lock, flags);
+}
+
+static void xlp_msi_mask_ack(struct irq_data *d)
+{
+       struct xlp_msi_data *md = irq_data_get_irq_handler_data(d);
+       int link, vec;
+
+       link = nlm_irq_msilink(d->irq);
+       vec = nlm_irq_msivec(d->irq);
+       xlp_msi_disable(d);
+
+       /* Ack MSI on bridge */
+       nlm_write_reg(md->lnkbase, PCIE_MSI_STATUS, 1u << vec);
+
+       /* Ack at eirr and PIC */
+       ack_c0_eirr(PIC_PCIE_LINK_MSI_IRQ(link));
+       nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_LINK_INDEX(link));
+}
+
+static struct irq_chip xlp_msi_chip = {
+       .name           = "XLP-MSI",
+       .irq_enable     = xlp_msi_enable,
+       .irq_disable    = xlp_msi_disable,
+       .irq_mask_ack   = xlp_msi_mask_ack,
+       .irq_unmask     = xlp_msi_enable,
+};
+
+/*
+ * The MSI-X interrupt handling is different from MSI, there are 32
+ * MSI-X interrupts generated by the PIC and each of these correspond
+ * to a MSI-X vector (0-31) that can be assigned.
+ *
+ * We divide the MSI-X vectors to 8 per link and do a per-link
+ * allocation
+ *
+ * Enable and disable done using standard MSI functions.
+ */
+static void xlp_msix_mask_ack(struct irq_data *d)
+{
+       struct xlp_msi_data *md = irq_data_get_irq_handler_data(d);
+       int link, msixvec;
+
+       msixvec = nlm_irq_msixvec(d->irq);
+       link = nlm_irq_msixlink(d->irq);
+       mask_msi_irq(d);
+
+       /* Ack MSI on bridge */
+       nlm_write_reg(md->lnkbase, PCIE_MSIX_STATUS, 1u << msixvec);
+
+       /* Ack at eirr and PIC */
+       ack_c0_eirr(PIC_PCIE_MSIX_IRQ(link));
+       nlm_pic_ack(md->node->picbase, PIC_IRT_PCIE_MSIX_INDEX(msixvec));
+}
+
+static struct irq_chip xlp_msix_chip = {
+       .name           = "XLP-MSIX",
+       .irq_enable     = unmask_msi_irq,
+       .irq_disable    = mask_msi_irq,
+       .irq_mask_ack   = xlp_msix_mask_ack,
+       .irq_unmask     = unmask_msi_irq,
+};
+
+void destroy_irq(unsigned int irq)
+{
+           /* nothing to do yet */
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+       destroy_irq(irq);
+}
+
+/*
+ * Setup a PCIe link for MSI.  By default, the links are in
+ * legacy interrupt mode.  We will switch them to MSI mode
+ * at the first MSI request.
+ */
+static void xlp_config_link_msi(uint64_t lnkbase, int lirq, uint64_t msiaddr)
+{
+       u32 val;
+
+       val = nlm_read_reg(lnkbase, PCIE_INT_EN0);
+       if ((val & 0x200) == 0) {
+               val |= 0x200;           /* MSI Interrupt enable */
+               nlm_write_reg(lnkbase, PCIE_INT_EN0, val);
+       }
+
+       val = nlm_read_reg(lnkbase, 0x1);       /* CMD */
+       if ((val & 0x0400) == 0) {
+               val |= 0x0400;
+               nlm_write_reg(lnkbase, 0x1, val);
+       }
+
+       /* Update IRQ in the PCI irq reg */
+       val = nlm_read_pci_reg(lnkbase, 0xf);
+       val &= ~0x1fu;
+       val |= (1 << 8) | lirq;
+       nlm_write_pci_reg(lnkbase, 0xf, val);
+
+       /* MSI addr */
+       nlm_write_reg(lnkbase, PCIE_BRIDGE_MSI_ADDRH, msiaddr >> 32);
+       nlm_write_reg(lnkbase, PCIE_BRIDGE_MSI_ADDRL, msiaddr & 0xffffffff);
+
+       /* MSI cap for bridge */
+       val = nlm_read_reg(lnkbase, PCIE_BRIDGE_MSI_CAP);
+       if ((val & (1 << 16)) == 0) {
+               val |= 0xb << 16;               /* mmc32, msi enable */
+               nlm_write_reg(lnkbase, PCIE_BRIDGE_MSI_CAP, val);
+       }
+}
+
+/*
+ * Allocate a MSI vector on a link
+ */
+static int xlp_setup_msi(uint64_t lnkbase, int node, int link,
+       struct msi_desc *desc)
+{
+       struct xlp_msi_data *md;
+       struct msi_msg msg;
+       unsigned long flags;
+       int msivec, irt, lirq, xirq, ret;
+       uint64_t msiaddr;
+
+       /* Get MSI data for the link */
+       lirq = PIC_PCIE_LINK_MSI_IRQ(link);
+       xirq = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));
+       md = irq_get_handler_data(xirq);
+       msiaddr = MSI_LINK_ADDR(node, link);
+
+       spin_lock_irqsave(&md->msi_lock, flags);
+       if (md->msi_alloc_mask == 0) {
+               /* switch the link IRQ to MSI range */
+               xlp_config_link_msi(lnkbase, lirq, msiaddr);
+               irt = PIC_IRT_PCIE_LINK_INDEX(link);
+               nlm_setup_pic_irq(node, lirq, lirq, irt);
+               nlm_pic_init_irt(nlm_get_node(node)->picbase, irt, lirq,
+                                node * nlm_threads_per_node(), 1 /*en */);
+       }
+
+       /* allocate a MSI vec, and tell the bridge about it */
+       msivec = fls(md->msi_alloc_mask);
+       if (msivec == XLP_MSIVEC_PER_LINK) {
+               spin_unlock_irqrestore(&md->msi_lock, flags);
+               return -ENOMEM;
+       }
+       md->msi_alloc_mask |= (1u << msivec);
+       spin_unlock_irqrestore(&md->msi_lock, flags);
+
+       msg.address_hi = msiaddr >> 32;
+       msg.address_lo = msiaddr & 0xffffffff;
+       msg.data = 0xc00 | msivec;
+
+       xirq = xirq + msivec;           /* msi mapped to global irq space */
+       ret = irq_set_msi_desc(xirq, desc);
+       if (ret < 0) {
+               destroy_irq(xirq);
+               return ret;
+       }
+
+       write_msi_msg(xirq, &msg);
+       return 0;
+}
+
+/*
+ * Switch a link to MSI-X mode
+ */
+static void xlp_config_link_msix(uint64_t lnkbase, int lirq, uint64_t msixaddr)
+{
+       u32 val;
+
+       val = nlm_read_reg(lnkbase, 0x2C);
+       if ((val & 0x80000000U) == 0) {
+               val |= 0x80000000U;
+               nlm_write_reg(lnkbase, 0x2C, val);
+       }
+       val = nlm_read_reg(lnkbase, PCIE_INT_EN0);
+       if ((val & 0x200) == 0) {
+               val |= 0x200;           /* MSI Interrupt enable */
+               nlm_write_reg(lnkbase, PCIE_INT_EN0, val);
+       }
+
+       val = nlm_read_reg(lnkbase, 0x1);       /* CMD */
+       if ((val & 0x0400) == 0) {
+               val |= 0x0400;
+               nlm_write_reg(lnkbase, 0x1, val);
+       }
+
+       /* Update IRQ in the PCI irq reg */
+       val = nlm_read_pci_reg(lnkbase, 0xf);
+       val &= ~0x1fu;
+       val |= (1 << 8) | lirq;
+       nlm_write_pci_reg(lnkbase, 0xf, val);
+
+       /* MSI-X addresses */
+       nlm_write_reg(lnkbase, PCIE_BRIDGE_MSIX_ADDR_BASE, msixaddr >> 8);
+       nlm_write_reg(lnkbase, PCIE_BRIDGE_MSIX_ADDR_LIMIT,
+                                       (msixaddr + MSI_ADDR_SZ) >> 8);
+}
+
+/*
+ *  Allocate a MSI-X vector
+ */
+static int xlp_setup_msix(uint64_t lnkbase, int node, int link,
+       struct msi_desc *desc)
+{
+       struct xlp_msi_data *md;
+       struct msi_msg msg;
+       unsigned long flags;
+       int t, msixvec, lirq, xirq, ret;
+       uint64_t msixaddr;
+
+       /* Get MSI data for the link */
+       lirq = PIC_PCIE_MSIX_IRQ(link);
+       xirq = nlm_irq_to_xirq(node, nlm_link_msixirq(link, 0));
+       md = irq_get_handler_data(xirq);
+       msixaddr = MSIX_LINK_ADDR(node, link);
+
+       spin_lock_irqsave(&md->msi_lock, flags);
+       /* switch the PCIe link to MSI-X mode at the first alloc */
+       if (md->msix_alloc_mask == 0)
+               xlp_config_link_msix(lnkbase, lirq, msixaddr);
+
+       /* allocate a MSI-X vec, and tell the bridge about it */
+       t = fls(md->msix_alloc_mask);
+       if (t == XLP_MSIXVEC_PER_LINK) {
+               spin_unlock_irqrestore(&md->msi_lock, flags);
+               return -ENOMEM;
+       }
+       md->msix_alloc_mask |= (1u << t);
+       spin_unlock_irqrestore(&md->msi_lock, flags);
+
+       xirq += t;
+       msixvec = nlm_irq_msixvec(xirq);
+       msg.address_hi = msixaddr >> 32;
+       msg.address_lo = msixaddr & 0xffffffff;
+       msg.data = 0xc00 | msixvec;
+
+       ret = irq_set_msi_desc(xirq, desc);
+       if (ret < 0) {
+               destroy_irq(xirq);
+               return ret;
+       }
+
+       write_msi_msg(xirq, &msg);
+       return 0;
+}
+
+int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+{
+       struct pci_dev *lnkdev;
+       uint64_t lnkbase;
+       int node, link, slot;
+
+       lnkdev = xlp_get_pcie_link(dev);
+       if (lnkdev == NULL) {
+               dev_err(&dev->dev, "Could not find bridge\n");
+               return 1;
+       }
+       slot = PCI_SLOT(lnkdev->devfn);
+       link = PCI_FUNC(lnkdev->devfn);
+       node = slot / 8;
+       lnkbase = nlm_get_pcie_base(node, link);
+
+       if (desc->msi_attrib.is_msix)
+               return xlp_setup_msix(lnkbase, node, link, desc);
+       else
+               return xlp_setup_msi(lnkbase, node, link, desc);
+}
+
+void __init xlp_init_node_msi_irqs(int node, int link)
+{
+       struct nlm_soc_info *nodep;
+       struct xlp_msi_data *md;
+       int irq, i, irt, msixvec;
+
+       pr_info("[%d %d] Init node PCI IRT\n", node, link);
+       nodep = nlm_get_node(node);
+
+       /* Alloc an MSI block for the link */
+       md = kzalloc(sizeof(*md), GFP_KERNEL);
+       spin_lock_init(&md->msi_lock);
+       md->msi_enabled_mask = 0;
+       md->msi_alloc_mask = 0;
+       md->msix_alloc_mask = 0;
+       md->node = nodep;
+       md->lnkbase = nlm_get_pcie_base(node, link);
+
+       /* extended space for MSI interrupts */
+       irq = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));
+       for (i = irq; i < irq + XLP_MSIVEC_PER_LINK; i++) {
+               irq_set_chip_and_handler(i, &xlp_msi_chip, handle_level_irq);
+               irq_set_handler_data(i, md);
+       }
+
+       for (i = 0; i < XLP_MSIXVEC_PER_LINK; i++) {
+               /* Initialize MSI-X irts to generate one interrupt per link */
+               msixvec = link * XLP_MSIXVEC_PER_LINK + i;
+               irt = PIC_IRT_PCIE_MSIX_INDEX(msixvec);
+               nlm_pic_init_irt(nodep->picbase, irt, PIC_PCIE_MSIX_IRQ(link),
+                       node * nlm_threads_per_node(), 1 /* enable */);
+
+               /* Initialize MSI-X extended irq space for the link  */
+               irq = nlm_irq_to_xirq(node, nlm_link_msixirq(link, i));
+               irq_set_chip_and_handler(irq, &xlp_msix_chip, handle_level_irq);
+               irq_set_handler_data(irq, md);
+       }
+
+}
+
+void nlm_dispatch_msi(int node, int lirq)
+{
+       struct xlp_msi_data *md;
+       int link, i, irqbase;
+       u32 status;
+
+       link = lirq - PIC_PCIE_LINK_MSI_IRQ_BASE;
+       irqbase = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));
+       md = irq_get_handler_data(irqbase);
+       status = nlm_read_reg(md->lnkbase, PCIE_MSI_STATUS) &
+                                               md->msi_enabled_mask;
+       while (status) {
+               i = __ffs(status);
+               do_IRQ(irqbase + i);
+               status &= status - 1;
+       }
+}
+
+void nlm_dispatch_msix(int node, int lirq)
+{
+       struct xlp_msi_data *md;
+       int link, i, irqbase;
+       u32 status;
+
+       link = lirq - PIC_PCIE_MSIX_IRQ_BASE;
+       irqbase = nlm_irq_to_xirq(node, nlm_link_msixirq(link, 0));
+       md = irq_get_handler_data(irqbase);
+       status = nlm_read_reg(md->lnkbase, PCIE_MSIX_STATUS);
+
+       /* narrow it down to the MSI-x vectors for our link */
+       status = (status >> (link * XLP_MSIXVEC_PER_LINK)) &
+                       ((1 << XLP_MSIXVEC_PER_LINK) - 1);
+
+       while (status) {
+               i = __ffs(status);
+               do_IRQ(irqbase + i);
+               status &= status - 1;
+       }
+}
index 6144bb3..13eea69 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 
index 830352e..c06205a 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 
 #include <asm/mips-boards/bonito64.h>
 
index 16e7c25..e5738ee 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <asm/addrspace.h>
index 98254af..24138bb 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/export.h>
 
 #include <loongson.h>
index 1cfb558..6b5821f 100644 (file)
@@ -6,7 +6,6 @@
  * Copyright (C) 2000, 2001 Keith M Wesolowski
  */
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/types.h>
 #include <asm/pci.h>
index 92a8543..dbbf365 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/init.h>
 
 #include <asm/mips-boards/msc01_pci.h>
 
index 499e35c..a1a7c9f 100644 (file)
@@ -1,5 +1,4 @@
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/pci.h>
 #include <asm/bootinfo.h>
 
index 7c7182e..874ed6d 100644 (file)
@@ -26,7 +26,6 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 #include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/io.h>
 #include <linux/pci.h>
 #include <linux/types.h>
index 162b4cb..0f09eaf 100644 (file)
@@ -7,7 +7,6 @@
  * Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/pci.h>
index 37134dd..f1a7389 100644 (file)
@@ -241,9 +241,9 @@ void __init mips_pcibios_init(void)
                return;
        }
 
-       /* Change start address to avoid conflicts with ACPI and SMB devices */
-       if (controller->io_resource->start < 0x00002000UL)
-               controller->io_resource->start = 0x00002000UL;
+       /* PIIX4 ACPI starts at 0x1000 */
+       if (controller->io_resource->start < 0x00001000UL)
+               controller->io_resource->start = 0x00001000UL;
 
        iomem_resource.end &= 0xfffffffffULL;                   /* 64 GB */
        ioport_resource.end = controller->io_resource->end;
index adeff2b..72919ae 100644 (file)
@@ -436,9 +436,6 @@ static int rt3883_pci_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -EINVAL;
-
        rpc->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(rpc->base))
                return PTR_ERR(rpc->base);
index 653d2db..7babf01 100644 (file)
 #include <asm/netlogic/interrupt.h>
 #include <asm/netlogic/haldefs.h>
 #include <asm/netlogic/common.h>
+#include <asm/netlogic/mips-extns.h>
 
 #include <asm/netlogic/xlp-hal/iomap.h>
-#include <asm/netlogic/xlp-hal/pic.h>
 #include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pic.h>
 #include <asm/netlogic/xlp-hal/pcibus.h>
 #include <asm/netlogic/xlp-hal/bridge.h>
 
@@ -66,9 +67,22 @@ static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn,
        u32 *cfgaddr;
 
        where &= ~3;
-       if (bus->number == 0 && PCI_SLOT(devfn) == 1 && where == 0x954)
+       if (cpu_is_xlp9xx()) {
+               /* be very careful on SoC buses */
+               if (bus->number == 0) {
+                       /* Scan only existing nodes - uboot bug? */
+                       if (PCI_SLOT(devfn) != 0 ||
+                                          !nlm_node_present(PCI_FUNC(devfn)))
+                               return 0xffffffff;
+               } else if (bus->parent->number == 0) {  /* SoC bus */
+                       if (PCI_SLOT(devfn) == 0)       /* b.0.0 hangs */
+                               return 0xffffffff;
+                       if (devfn == 44)                /* b.5.4 hangs */
+                               return 0xffffffff;
+               }
+       } else if (bus->number == 0 && PCI_SLOT(devfn) == 1 && where == 0x954) {
                return 0xffffffff;
-
+       }
        cfgaddr = (u32 *)(pci_config_base +
                        pci_cfg_addr(bus->number, devfn, where));
        data = *cfgaddr;
@@ -162,27 +176,39 @@ struct pci_controller nlm_pci_controller = {
        .io_offset      = 0x00000000UL,
 };
 
-static struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev)
+struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev)
 {
        struct pci_bus *bus, *p;
 
-       /* Find the bridge on bus 0 */
        bus = dev->bus;
-       for (p = bus->parent; p && p->number != 0; p = p->parent)
-               bus = p;
 
-       return p ? bus->self : NULL;
+       if (cpu_is_xlp9xx()) {
+               /* find bus with grand parent number == 0 */
+               for (p = bus->parent; p && p->parent && p->parent->number != 0;
+                               p = p->parent)
+                       bus = p;
+               return (p && p->parent) ? bus->self : NULL;
+       } else {
+               /* Find the bridge on bus 0 */
+               for (p = bus->parent; p && p->number != 0; p = p->parent)
+                       bus = p;
+
+               return p ? bus->self : NULL;
+       }
 }
 
-static inline int nlm_pci_link_to_irq(int link)
+int xlp_socdev_to_node(const struct pci_dev *lnkdev)
 {
-       return PIC_PCIE_LINK_0_IRQ + link;
+       if (cpu_is_xlp9xx())
+               return PCI_FUNC(lnkdev->bus->self->devfn);
+       else
+               return PCI_SLOT(lnkdev->devfn) / 8;
 }
 
 int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct pci_dev *lnkdev;
-       int lnkslot, lnkfunc;
+       int lnkfunc, node;
 
        /*
         * For XLP PCIe, there is an IRQ per Link, find out which
@@ -191,9 +217,11 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
        lnkdev = xlp_get_pcie_link(dev);
        if (lnkdev == NULL)
                return 0;
+
        lnkfunc = PCI_FUNC(lnkdev->devfn);
-       lnkslot = PCI_SLOT(lnkdev->devfn);
-       return nlm_irq_to_xirq(lnkslot / 8, nlm_pci_link_to_irq(lnkfunc));
+       node = xlp_socdev_to_node(lnkdev);
+
+       return nlm_irq_to_xirq(node, PIC_PCIE_LINK_LEGACY_IRQ(lnkfunc));
 }
 
 /* Do platform specific device initialization at pci_enable_device() time */
@@ -220,17 +248,38 @@ static void xlp_config_pci_bswap(int node, int link)
         *  Enable byte swap in hardware. Program each link's PCIe SWAP regions
         * from the link's address ranges.
         */
-       reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_BASE0 + link);
-       nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_BASE, reg);
-
-       reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_LIMIT0 + link);
-       nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_LIM, reg | 0xfff);
-
-       reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_BASE0 + link);
-       nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_BASE, reg);
-
-       reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_LIMIT0 + link);
-       nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
+       if (cpu_is_xlp9xx()) {
+               reg = nlm_read_bridge_reg(nbubase,
+                               BRIDGE_9XX_PCIEMEM_BASE0 + link);
+               nlm_write_pci_reg(lnkbase, PCIE_9XX_BYTE_SWAP_MEM_BASE, reg);
+
+               reg = nlm_read_bridge_reg(nbubase,
+                               BRIDGE_9XX_PCIEMEM_LIMIT0 + link);
+               nlm_write_pci_reg(lnkbase,
+                               PCIE_9XX_BYTE_SWAP_MEM_LIM, reg | 0xfff);
+
+               reg = nlm_read_bridge_reg(nbubase,
+                               BRIDGE_9XX_PCIEIO_BASE0 + link);
+               nlm_write_pci_reg(lnkbase, PCIE_9XX_BYTE_SWAP_IO_BASE, reg);
+
+               reg = nlm_read_bridge_reg(nbubase,
+                               BRIDGE_9XX_PCIEIO_LIMIT0 + link);
+               nlm_write_pci_reg(lnkbase,
+                               PCIE_9XX_BYTE_SWAP_IO_LIM, reg | 0xfff);
+       } else {
+               reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEMEM_BASE0 + link);
+               nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_BASE, reg);
+
+               reg = nlm_read_bridge_reg(nbubase,
+                                       BRIDGE_PCIEMEM_LIMIT0 + link);
+               nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_MEM_LIM, reg | 0xfff);
+
+               reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_BASE0 + link);
+               nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_BASE, reg);
+
+               reg = nlm_read_bridge_reg(nbubase, BRIDGE_PCIEIO_LIMIT0 + link);
+               nlm_write_pci_reg(lnkbase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
+       }
 }
 #else
 /* Swap configuration not needed in little-endian mode */
@@ -239,7 +288,6 @@ static inline void xlp_config_pci_bswap(int node, int link) {}
 
 static int __init pcibios_init(void)
 {
-       struct nlm_soc_info *nodep;
        uint64_t pciebase;
        int link, n;
        u32 reg;
@@ -253,20 +301,20 @@ static int __init pcibios_init(void)
        ioport_resource.end   = ~0;
 
        for (n = 0; n < NLM_NR_NODES; n++) {
-               nodep = nlm_get_node(n);
-               if (!nodep->coremask)
-                       continue;       /* node does not exist */
+               if (!nlm_node_present(n))
+                       continue;
 
-               for (link = 0; link < 4; link++) {
+               for (link = 0; link < PCIE_NLINKS; link++) {
                        pciebase = nlm_get_pcie_base(n, link);
                        if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
                                continue;
                        xlp_config_pci_bswap(n, link);
+                       xlp_init_node_msi_irqs(n, link);
 
                        /* put in intpin and irq - u-boot does not */
                        reg = nlm_read_pci_reg(pciebase, 0xf);
-                       reg &= ~0x1fu;
-                       reg |= (1 << 8) | nlm_pci_link_to_irq(link);
+                       reg &= ~0x1ffu;
+                       reg |= (1 << 8) | PIC_PCIE_LINK_LEGACY_IRQ(link);
                        nlm_write_pci_reg(pciebase, 0xf, reg);
                        pr_info("XLP PCIe: Link %d-%d initialized.\n", n, link);
                }
index 3482b8c..6073ca4 100644 (file)
@@ -6,6 +6,7 @@ config PMC_MSP4200_EVAL
        bool "PMC-Sierra MSP4200 Eval Board"
        select IRQ_MSP_SLP
        select HW_HAS_PCI
+       select MIPS_L1_CACHE_SHIFT_4
 
 config PMC_MSP4200_GW
        bool "PMC-Sierra MSP4200 VoIP Gateway"
index 424f034..1bfd1c1 100644 (file)
@@ -15,6 +15,7 @@ choice
 
        config SOC_RT288X
                bool "RT288x"
+               select MIPS_L1_CACHE_SHIFT_4
 
        config SOC_RT305X
                bool "RT305x"
index b952d5b..45fdfbc 100644 (file)
@@ -5,7 +5,6 @@
  *
  * Copyright (C) 2001, 2002 Ralf Baechle
  */
-#include <linux/init.h>
 
 #include <asm/page.h>
 #include <asm/sn/addrs.h>
index ec22ec5..2a1c407 100644 (file)
@@ -8,7 +8,6 @@
 
 #undef DEBUG
 
-#include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
index 7afe146..c873d62 100644 (file)
@@ -2,7 +2,6 @@
  * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
index d59b820..20f582a 100644 (file)
@@ -7,7 +7,6 @@
  * Generic XTALK initialization code
  */
 
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <asm/sn/types.h>
index 7c081b3..0ee48be 100644 (file)
@@ -75,6 +75,7 @@ config BCMA_DRIVER_GMAC_CMN
 config BCMA_DRIVER_GPIO
        bool "BCMA GPIO driver"
        depends on BCMA && GPIOLIB
+       select IRQ_DOMAIN if BCMA_HOST_SOC
        help
          Driver to provide access to the GPIO pins of the bcma bus.
 
index 45f0996..25f9887 100644 (file)
@@ -9,6 +9,9 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/export.h>
 #include <linux/bcma/bcma.h>
 
@@ -73,19 +76,136 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
        bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
 }
 
+#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
 static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
 {
        struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
 
        if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
-               return bcma_core_irq(cc->core);
+               return irq_find_mapping(cc->irq_domain, gpio);
        else
                return -EINVAL;
 }
 
+static void bcma_gpio_irq_unmask(struct irq_data *d)
+{
+       struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
+       int gpio = irqd_to_hwirq(d);
+       u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
+
+       bcma_chipco_gpio_polarity(cc, BIT(gpio), val);
+       bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio));
+}
+
+static void bcma_gpio_irq_mask(struct irq_data *d)
+{
+       struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
+       int gpio = irqd_to_hwirq(d);
+
+       bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
+}
+
+static struct irq_chip bcma_gpio_irq_chip = {
+       .name           = "BCMA-GPIO",
+       .irq_mask       = bcma_gpio_irq_mask,
+       .irq_unmask     = bcma_gpio_irq_unmask,
+};
+
+static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
+{
+       struct bcma_drv_cc *cc = dev_id;
+       u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN);
+       u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ);
+       u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL);
+       unsigned long irqs = (val ^ pol) & mask;
+       int gpio;
+
+       if (!irqs)
+               return IRQ_NONE;
+
+       for_each_set_bit(gpio, &irqs, cc->gpio.ngpio)
+               generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio));
+       bcma_chipco_gpio_polarity(cc, irqs, val & irqs);
+
+       return IRQ_HANDLED;
+}
+
+static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
+{
+       struct gpio_chip *chip = &cc->gpio;
+       int gpio, hwirq, err;
+
+       if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
+               return 0;
+
+       cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
+                                              &irq_domain_simple_ops, cc);
+       if (!cc->irq_domain) {
+               err = -ENODEV;
+               goto err_irq_domain;
+       }
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_create_mapping(cc->irq_domain, gpio);
+
+               irq_set_chip_data(irq, cc);
+               irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip,
+                                        handle_simple_irq);
+       }
+
+       hwirq = bcma_core_irq(cc->core);
+       err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio",
+                         cc);
+       if (err)
+               goto err_req_irq;
+
+       bcma_chipco_gpio_intmask(cc, ~0, 0);
+       bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
+
+       return 0;
+
+err_req_irq:
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_find_mapping(cc->irq_domain, gpio);
+
+               irq_dispose_mapping(irq);
+       }
+       irq_domain_remove(cc->irq_domain);
+err_irq_domain:
+       return err;
+}
+
+static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
+{
+       struct gpio_chip *chip = &cc->gpio;
+       int gpio;
+
+       if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
+               return;
+
+       bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO);
+       free_irq(bcma_core_irq(cc->core), cc);
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_find_mapping(cc->irq_domain, gpio);
+
+               irq_dispose_mapping(irq);
+       }
+       irq_domain_remove(cc->irq_domain);
+}
+#else
+static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
+{
+       return 0;
+}
+
+static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
+{
+}
+#endif
+
 int bcma_gpio_init(struct bcma_drv_cc *cc)
 {
        struct gpio_chip *chip = &cc->gpio;
+       int err;
 
        chip->label             = "bcma_gpio";
        chip->owner             = THIS_MODULE;
@@ -95,7 +215,9 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
        chip->set               = bcma_gpio_set_value;
        chip->direction_input   = bcma_gpio_direction_input;
        chip->direction_output  = bcma_gpio_direction_output;
+#if IS_BUILTIN(CONFIG_BCMA_HOST_SOC)
        chip->to_irq            = bcma_gpio_to_irq;
+#endif
        chip->ngpio             = 16;
        /* There is just one SoC in one device and its GPIO addresses should be
         * deterministic to address them more easily. The other buses could get
@@ -105,10 +227,21 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
        else
                chip->base              = -1;
 
-       return gpiochip_add(chip);
+       err = bcma_gpio_irq_domain_init(cc);
+       if (err)
+               return err;
+
+       err = gpiochip_add(chip);
+       if (err) {
+               bcma_gpio_irq_domain_exit(cc);
+               return err;
+       }
+
+       return 0;
 }
 
 int bcma_gpio_unregister(struct bcma_drv_cc *cc)
 {
+       bcma_gpio_irq_domain_exit(cc);
        return gpiochip_remove(&cc->gpio);
 }
index 2cd9b0e..75b3603 100644 (file)
@@ -168,6 +168,7 @@ config SSB_DRIVER_GIGE
 config SSB_DRIVER_GPIO
        bool "SSB GPIO driver"
        depends on SSB && GPIOLIB
+       select IRQ_DOMAIN if SSB_EMBEDDED
        help
          Driver to provide access to the GPIO pins on the bus.
 
index dc109de..ba350d2 100644 (file)
@@ -9,16 +9,40 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/export.h>
 #include <linux/ssb/ssb.h>
 
 #include "ssb_private.h"
 
+
+/**************************************************
+ * Shared
+ **************************************************/
+
 static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip)
 {
        return container_of(chip, struct ssb_bus, gpio);
 }
 
+#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
+static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
+{
+       struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+
+       if (bus->bustype == SSB_BUSTYPE_SSB)
+               return irq_find_mapping(bus->irq_domain, gpio);
+       else
+               return -EINVAL;
+}
+#endif
+
+/**************************************************
+ * ChipCommon
+ **************************************************/
+
 static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio)
 {
        struct ssb_bus *bus = ssb_gpio_get_bus(chip);
@@ -74,19 +98,129 @@ static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio)
        ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
 }
 
-static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio)
+#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
+static void ssb_gpio_irq_chipco_mask(struct irq_data *d)
 {
-       struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+       struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
+       int gpio = irqd_to_hwirq(d);
 
-       if (bus->bustype == SSB_BUSTYPE_SSB)
-               return ssb_mips_irq(bus->chipco.dev) + 2;
-       else
-               return -EINVAL;
+       ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), 0);
+}
+
+static void ssb_gpio_irq_chipco_unmask(struct irq_data *d)
+{
+       struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
+       int gpio = irqd_to_hwirq(d);
+       u32 val = ssb_chipco_gpio_in(&bus->chipco, BIT(gpio));
+
+       ssb_chipco_gpio_polarity(&bus->chipco, BIT(gpio), val);
+       ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), BIT(gpio));
+}
+
+static struct irq_chip ssb_gpio_irq_chipco_chip = {
+       .name           = "SSB-GPIO-CC",
+       .irq_mask       = ssb_gpio_irq_chipco_mask,
+       .irq_unmask     = ssb_gpio_irq_chipco_unmask,
+};
+
+static irqreturn_t ssb_gpio_irq_chipco_handler(int irq, void *dev_id)
+{
+       struct ssb_bus *bus = dev_id;
+       struct ssb_chipcommon *chipco = &bus->chipco;
+       u32 val = chipco_read32(chipco, SSB_CHIPCO_GPIOIN);
+       u32 mask = chipco_read32(chipco, SSB_CHIPCO_GPIOIRQ);
+       u32 pol = chipco_read32(chipco, SSB_CHIPCO_GPIOPOL);
+       unsigned long irqs = (val ^ pol) & mask;
+       int gpio;
+
+       if (!irqs)
+               return IRQ_NONE;
+
+       for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
+               generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
+       ssb_chipco_gpio_polarity(chipco, irqs, val & irqs);
+
+       return IRQ_HANDLED;
+}
+
+static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
+{
+       struct ssb_chipcommon *chipco = &bus->chipco;
+       struct gpio_chip *chip = &bus->gpio;
+       int gpio, hwirq, err;
+
+       if (bus->bustype != SSB_BUSTYPE_SSB)
+               return 0;
+
+       bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
+                                               &irq_domain_simple_ops, chipco);
+       if (!bus->irq_domain) {
+               err = -ENODEV;
+               goto err_irq_domain;
+       }
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_create_mapping(bus->irq_domain, gpio);
+
+               irq_set_chip_data(irq, bus);
+               irq_set_chip_and_handler(irq, &ssb_gpio_irq_chipco_chip,
+                                        handle_simple_irq);
+       }
+
+       hwirq = ssb_mips_irq(bus->chipco.dev) + 2;
+       err = request_irq(hwirq, ssb_gpio_irq_chipco_handler, IRQF_SHARED,
+                         "gpio", bus);
+       if (err)
+               goto err_req_irq;
+
+       ssb_chipco_gpio_intmask(&bus->chipco, ~0, 0);
+       chipco_set32(chipco, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO);
+
+       return 0;
+
+err_req_irq:
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_find_mapping(bus->irq_domain, gpio);
+
+               irq_dispose_mapping(irq);
+       }
+       irq_domain_remove(bus->irq_domain);
+err_irq_domain:
+       return err;
+}
+
+static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
+{
+       struct ssb_chipcommon *chipco = &bus->chipco;
+       struct gpio_chip *chip = &bus->gpio;
+       int gpio;
+
+       if (bus->bustype != SSB_BUSTYPE_SSB)
+               return;
+
+       chipco_mask32(chipco, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO);
+       free_irq(ssb_mips_irq(bus->chipco.dev) + 2, chipco);
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_find_mapping(bus->irq_domain, gpio);
+
+               irq_dispose_mapping(irq);
+       }
+       irq_domain_remove(bus->irq_domain);
+}
+#else
+static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
+{
+       return 0;
 }
 
+static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus)
+{
+}
+#endif
+
 static int ssb_gpio_chipco_init(struct ssb_bus *bus)
 {
        struct gpio_chip *chip = &bus->gpio;
+       int err;
 
        chip->label             = "ssb_chipco_gpio";
        chip->owner             = THIS_MODULE;
@@ -96,7 +230,9 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
        chip->set               = ssb_gpio_chipco_set_value;
        chip->direction_input   = ssb_gpio_chipco_direction_input;
        chip->direction_output  = ssb_gpio_chipco_direction_output;
-       chip->to_irq            = ssb_gpio_chipco_to_irq;
+#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
+       chip->to_irq            = ssb_gpio_to_irq;
+#endif
        chip->ngpio             = 16;
        /* There is just one SoC in one device and its GPIO addresses should be
         * deterministic to address them more easily. The other buses could get
@@ -106,9 +242,23 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus)
        else
                chip->base              = -1;
 
-       return gpiochip_add(chip);
+       err = ssb_gpio_irq_chipco_domain_init(bus);
+       if (err)
+               return err;
+
+       err = gpiochip_add(chip);
+       if (err) {
+               ssb_gpio_irq_chipco_domain_exit(bus);
+               return err;
+       }
+
+       return 0;
 }
 
+/**************************************************
+ * EXTIF
+ **************************************************/
+
 #ifdef CONFIG_SSB_DRIVER_EXTIF
 
 static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio)
@@ -145,19 +295,127 @@ static int ssb_gpio_extif_direction_output(struct gpio_chip *chip,
        return 0;
 }
 
-static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio)
+#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
+static void ssb_gpio_irq_extif_mask(struct irq_data *d)
 {
-       struct ssb_bus *bus = ssb_gpio_get_bus(chip);
+       struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
+       int gpio = irqd_to_hwirq(d);
 
-       if (bus->bustype == SSB_BUSTYPE_SSB)
-               return ssb_mips_irq(bus->extif.dev) + 2;
-       else
-               return -EINVAL;
+       ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), 0);
+}
+
+static void ssb_gpio_irq_extif_unmask(struct irq_data *d)
+{
+       struct ssb_bus *bus = irq_data_get_irq_chip_data(d);
+       int gpio = irqd_to_hwirq(d);
+       u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio));
+
+       ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val);
+       ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio));
+}
+
+static struct irq_chip ssb_gpio_irq_extif_chip = {
+       .name           = "SSB-GPIO-EXTIF",
+       .irq_mask       = ssb_gpio_irq_extif_mask,
+       .irq_unmask     = ssb_gpio_irq_extif_unmask,
+};
+
+static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id)
+{
+       struct ssb_bus *bus = dev_id;
+       struct ssb_extif *extif = &bus->extif;
+       u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN);
+       u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK);
+       u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL);
+       unsigned long irqs = (val ^ pol) & mask;
+       int gpio;
+
+       if (!irqs)
+               return IRQ_NONE;
+
+       for_each_set_bit(gpio, &irqs, bus->gpio.ngpio)
+               generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio));
+       ssb_extif_gpio_polarity(extif, irqs, val & irqs);
+
+       return IRQ_HANDLED;
+}
+
+static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
+{
+       struct ssb_extif *extif = &bus->extif;
+       struct gpio_chip *chip = &bus->gpio;
+       int gpio, hwirq, err;
+
+       if (bus->bustype != SSB_BUSTYPE_SSB)
+               return 0;
+
+       bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
+                                               &irq_domain_simple_ops, extif);
+       if (!bus->irq_domain) {
+               err = -ENODEV;
+               goto err_irq_domain;
+       }
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_create_mapping(bus->irq_domain, gpio);
+
+               irq_set_chip_data(irq, bus);
+               irq_set_chip_and_handler(irq, &ssb_gpio_irq_extif_chip,
+                                        handle_simple_irq);
+       }
+
+       hwirq = ssb_mips_irq(bus->extif.dev) + 2;
+       err = request_irq(hwirq, ssb_gpio_irq_extif_handler, IRQF_SHARED,
+                         "gpio", bus);
+       if (err)
+               goto err_req_irq;
+
+       ssb_extif_gpio_intmask(&bus->extif, ~0, 0);
+
+       return 0;
+
+err_req_irq:
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_find_mapping(bus->irq_domain, gpio);
+
+               irq_dispose_mapping(irq);
+       }
+       irq_domain_remove(bus->irq_domain);
+err_irq_domain:
+       return err;
+}
+
+static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
+{
+       struct ssb_extif *extif = &bus->extif;
+       struct gpio_chip *chip = &bus->gpio;
+       int gpio;
+
+       if (bus->bustype != SSB_BUSTYPE_SSB)
+               return;
+
+       free_irq(ssb_mips_irq(bus->extif.dev) + 2, extif);
+       for (gpio = 0; gpio < chip->ngpio; gpio++) {
+               int irq = irq_find_mapping(bus->irq_domain, gpio);
+
+               irq_dispose_mapping(irq);
+       }
+       irq_domain_remove(bus->irq_domain);
 }
+#else
+static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus)
+{
+       return 0;
+}
+
+static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus)
+{
+}
+#endif
 
 static int ssb_gpio_extif_init(struct ssb_bus *bus)
 {
        struct gpio_chip *chip = &bus->gpio;
+       int err;
 
        chip->label             = "ssb_extif_gpio";
        chip->owner             = THIS_MODULE;
@@ -165,7 +423,9 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
        chip->set               = ssb_gpio_extif_set_value;
        chip->direction_input   = ssb_gpio_extif_direction_input;
        chip->direction_output  = ssb_gpio_extif_direction_output;
-       chip->to_irq            = ssb_gpio_extif_to_irq;
+#if IS_ENABLED(CONFIG_SSB_EMBEDDED)
+       chip->to_irq            = ssb_gpio_to_irq;
+#endif
        chip->ngpio             = 5;
        /* There is just one SoC in one device and its GPIO addresses should be
         * deterministic to address them more easily. The other buses could get
@@ -175,7 +435,17 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
        else
                chip->base              = -1;
 
-       return gpiochip_add(chip);
+       err = ssb_gpio_irq_extif_domain_init(bus);
+       if (err)
+               return err;
+
+       err = gpiochip_add(chip);
+       if (err) {
+               ssb_gpio_irq_extif_domain_exit(bus);
+               return err;
+       }
+
+       return 0;
 }
 
 #else
@@ -185,6 +455,10 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus)
 }
 #endif
 
+/**************************************************
+ * Init
+ **************************************************/
+
 int ssb_gpio_init(struct ssb_bus *bus)
 {
        if (ssb_chipco_available(&bus->chipco))
index 32a811d..2fead38 100644 (file)
@@ -593,6 +593,13 @@ static int ssb_attach_queued_buses(void)
                ssb_pcicore_init(&bus->pcicore);
                if (bus->bustype == SSB_BUSTYPE_SSB)
                        ssb_watchdog_register(bus);
+
+               err = ssb_gpio_init(bus);
+               if (err == -ENOTSUPP)
+                       ssb_dbg("GPIO driver not activated\n");
+               else if (err)
+                       ssb_dbg("Error registering GPIO driver: %i\n", err);
+
                ssb_bus_may_powerdown(bus);
 
                err = ssb_devices_register(bus);
@@ -830,11 +837,6 @@ static int ssb_bus_register(struct ssb_bus *bus,
        ssb_chipcommon_init(&bus->chipco);
        ssb_extif_init(&bus->extif);
        ssb_mipscore_init(&bus->mipscore);
-       err = ssb_gpio_init(bus);
-       if (err == -ENOTSUPP)
-               ssb_dbg("GPIO driver not activated\n");
-       else if (err)
-               ssb_dbg("Error registering GPIO driver: %i\n", err);
        err = ssb_fetch_invariants(bus, get_invariants);
        if (err) {
                ssb_bus_may_powerdown(bus);
index 649d512..78e82b0 100644 (file)
 #include <linux/sysrq.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
-
-#include <bcm63xx_irq.h>
-#include <bcm63xx_regs.h>
-#include <bcm63xx_io.h>
+#include <linux/serial_bcm63xx.h>
 
 #define BCM63XX_NR_UARTS       2
 
@@ -81,13 +78,13 @@ static struct uart_port ports[BCM63XX_NR_UARTS];
 static inline unsigned int bcm_uart_readl(struct uart_port *port,
                                         unsigned int offset)
 {
-       return bcm_readl(port->membase + offset);
+       return __raw_readl(port->membase + offset);
 }
 
 static inline void bcm_uart_writel(struct uart_port *port,
                                  unsigned int value, unsigned int offset)
 {
-       bcm_writel(value, port->membase + offset);
+       __raw_writel(value, port->membase + offset);
 }
 
 /*
index c49e1a1..63d105c 100644 (file)
@@ -640,6 +640,7 @@ struct bcma_drv_cc {
        spinlock_t gpio_lock;
 #ifdef CONFIG_BCMA_DRIVER_GPIO
        struct gpio_chip gpio;
+       struct irq_domain *irq_domain;
 #endif
 };
 
diff --git a/include/linux/serial_bcm63xx.h b/include/linux/serial_bcm63xx.h
new file mode 100644 (file)
index 0000000..570e964
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef _LINUX_SERIAL_BCM63XX_H
+#define _LINUX_SERIAL_BCM63XX_H
+
+/* UART Control Register */
+#define UART_CTL_REG                   0x0
+#define UART_CTL_RXTMOUTCNT_SHIFT      0
+#define UART_CTL_RXTMOUTCNT_MASK       (0x1f << UART_CTL_RXTMOUTCNT_SHIFT)
+#define UART_CTL_RSTTXDN_SHIFT         5
+#define UART_CTL_RSTTXDN_MASK          (1 << UART_CTL_RSTTXDN_SHIFT)
+#define UART_CTL_RSTRXFIFO_SHIFT               6
+#define UART_CTL_RSTRXFIFO_MASK                (1 << UART_CTL_RSTRXFIFO_SHIFT)
+#define UART_CTL_RSTTXFIFO_SHIFT               7
+#define UART_CTL_RSTTXFIFO_MASK                (1 << UART_CTL_RSTTXFIFO_SHIFT)
+#define UART_CTL_STOPBITS_SHIFT                8
+#define UART_CTL_STOPBITS_MASK         (0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_1            (0x7 << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_2            (0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_BITSPERSYM_SHIFT      12
+#define UART_CTL_BITSPERSYM_MASK       (0x3 << UART_CTL_BITSPERSYM_SHIFT)
+#define UART_CTL_XMITBRK_SHIFT         14
+#define UART_CTL_XMITBRK_MASK          (1 << UART_CTL_XMITBRK_SHIFT)
+#define UART_CTL_RSVD_SHIFT            15
+#define UART_CTL_RSVD_MASK             (1 << UART_CTL_RSVD_SHIFT)
+#define UART_CTL_RXPAREVEN_SHIFT               16
+#define UART_CTL_RXPAREVEN_MASK                (1 << UART_CTL_RXPAREVEN_SHIFT)
+#define UART_CTL_RXPAREN_SHIFT         17
+#define UART_CTL_RXPAREN_MASK          (1 << UART_CTL_RXPAREN_SHIFT)
+#define UART_CTL_TXPAREVEN_SHIFT               18
+#define UART_CTL_TXPAREVEN_MASK                (1 << UART_CTL_TXPAREVEN_SHIFT)
+#define UART_CTL_TXPAREN_SHIFT         18
+#define UART_CTL_TXPAREN_MASK          (1 << UART_CTL_TXPAREN_SHIFT)
+#define UART_CTL_LOOPBACK_SHIFT                20
+#define UART_CTL_LOOPBACK_MASK         (1 << UART_CTL_LOOPBACK_SHIFT)
+#define UART_CTL_RXEN_SHIFT            21
+#define UART_CTL_RXEN_MASK             (1 << UART_CTL_RXEN_SHIFT)
+#define UART_CTL_TXEN_SHIFT            22
+#define UART_CTL_TXEN_MASK             (1 << UART_CTL_TXEN_SHIFT)
+#define UART_CTL_BRGEN_SHIFT           23
+#define UART_CTL_BRGEN_MASK            (1 << UART_CTL_BRGEN_SHIFT)
+
+/* UART Baudword register */
+#define UART_BAUD_REG                  0x4
+
+/* UART Misc Control register */
+#define UART_MCTL_REG                  0x8
+#define UART_MCTL_DTR_SHIFT            0
+#define UART_MCTL_DTR_MASK             (1 << UART_MCTL_DTR_SHIFT)
+#define UART_MCTL_RTS_SHIFT            1
+#define UART_MCTL_RTS_MASK             (1 << UART_MCTL_RTS_SHIFT)
+#define UART_MCTL_RXFIFOTHRESH_SHIFT   8
+#define UART_MCTL_RXFIFOTHRESH_MASK    (0xf << UART_MCTL_RXFIFOTHRESH_SHIFT)
+#define UART_MCTL_TXFIFOTHRESH_SHIFT   12
+#define UART_MCTL_TXFIFOTHRESH_MASK    (0xf << UART_MCTL_TXFIFOTHRESH_SHIFT)
+#define UART_MCTL_RXFIFOFILL_SHIFT     16
+#define UART_MCTL_RXFIFOFILL_MASK      (0x1f << UART_MCTL_RXFIFOFILL_SHIFT)
+#define UART_MCTL_TXFIFOFILL_SHIFT     24
+#define UART_MCTL_TXFIFOFILL_MASK      (0x1f << UART_MCTL_TXFIFOFILL_SHIFT)
+
+/* UART External Input Configuration register */
+#define UART_EXTINP_REG                        0xc
+#define UART_EXTINP_RI_SHIFT           0
+#define UART_EXTINP_RI_MASK            (1 << UART_EXTINP_RI_SHIFT)
+#define UART_EXTINP_CTS_SHIFT          1
+#define UART_EXTINP_CTS_MASK           (1 << UART_EXTINP_CTS_SHIFT)
+#define UART_EXTINP_DCD_SHIFT          2
+#define UART_EXTINP_DCD_MASK           (1 << UART_EXTINP_DCD_SHIFT)
+#define UART_EXTINP_DSR_SHIFT          3
+#define UART_EXTINP_DSR_MASK           (1 << UART_EXTINP_DSR_SHIFT)
+#define UART_EXTINP_IRSTAT(x)          (1 << (x + 4))
+#define UART_EXTINP_IRMASK(x)          (1 << (x + 8))
+#define UART_EXTINP_IR_RI              0
+#define UART_EXTINP_IR_CTS             1
+#define UART_EXTINP_IR_DCD             2
+#define UART_EXTINP_IR_DSR             3
+#define UART_EXTINP_RI_NOSENSE_SHIFT   16
+#define UART_EXTINP_RI_NOSENSE_MASK    (1 << UART_EXTINP_RI_NOSENSE_SHIFT)
+#define UART_EXTINP_CTS_NOSENSE_SHIFT  17
+#define UART_EXTINP_CTS_NOSENSE_MASK   (1 << UART_EXTINP_CTS_NOSENSE_SHIFT)
+#define UART_EXTINP_DCD_NOSENSE_SHIFT  18
+#define UART_EXTINP_DCD_NOSENSE_MASK   (1 << UART_EXTINP_DCD_NOSENSE_SHIFT)
+#define UART_EXTINP_DSR_NOSENSE_SHIFT  19
+#define UART_EXTINP_DSR_NOSENSE_MASK   (1 << UART_EXTINP_DSR_NOSENSE_SHIFT)
+
+/* UART Interrupt register */
+#define UART_IR_REG                    0x10
+#define UART_IR_MASK(x)                        (1 << (x + 16))
+#define UART_IR_STAT(x)                        (1 << (x))
+#define UART_IR_EXTIP                  0
+#define UART_IR_TXUNDER                        1
+#define UART_IR_TXOVER                 2
+#define UART_IR_TXTRESH                        3
+#define UART_IR_TXRDLATCH              4
+#define UART_IR_TXEMPTY                        5
+#define UART_IR_RXUNDER                        6
+#define UART_IR_RXOVER                 7
+#define UART_IR_RXTIMEOUT              8
+#define UART_IR_RXFULL                 9
+#define UART_IR_RXTHRESH               10
+#define UART_IR_RXNOTEMPTY             11
+#define UART_IR_RXFRAMEERR             12
+#define UART_IR_RXPARERR               13
+#define UART_IR_RXBRK                  14
+#define UART_IR_TXDONE                 15
+
+/* UART Fifo register */
+#define UART_FIFO_REG                  0x14
+#define UART_FIFO_VALID_SHIFT          0
+#define UART_FIFO_VALID_MASK           0xff
+#define UART_FIFO_FRAMEERR_SHIFT       8
+#define UART_FIFO_FRAMEERR_MASK                (1 << UART_FIFO_FRAMEERR_SHIFT)
+#define UART_FIFO_PARERR_SHIFT         9
+#define UART_FIFO_PARERR_MASK          (1 << UART_FIFO_PARERR_SHIFT)
+#define UART_FIFO_BRKDET_SHIFT         10
+#define UART_FIFO_BRKDET_MASK          (1 << UART_FIFO_BRKDET_SHIFT)
+#define UART_FIFO_ANYERR_MASK          (UART_FIFO_FRAMEERR_MASK |      \
+                                       UART_FIFO_PARERR_MASK |         \
+                                       UART_FIFO_BRKDET_MASK)
+
+#endif /* _LINUX_SERIAL_BCM63XX_H */
index c64999f..07ef9b8 100644 (file)
@@ -486,6 +486,7 @@ struct ssb_bus {
 #endif /* EMBEDDED */
 #ifdef CONFIG_SSB_DRIVER_GPIO
        struct gpio_chip gpio;
+       struct irq_domain *irq_domain;
 #endif /* DRIVER_GPIO */
 
        /* Internal-only stuff follows. Do not touch. */