The main MIPS changes for 5.6:
- Support mremap() for the VDSO, primarily to allow CRIU to restore the VDSO to its checkpointed location. - Restore the MIPS32 cBPF JIT, after having reverted the enablement of the eBPF JIT for MIPS32 systems in the 5.5 cycle. - Improve cop0 counter synchronization behaviour whilst onlining CPUs by running with interrupts disabled. - Better match FPU behaviour when emulating multiply-accumulate instructions on pre-r6 systems that implement IEEE754-2008 style MACs. - Loongson64 kernels now build using the MIPS64r2 ISA, allowing them to take advantage of instructions introduced by r2. - Support for the Ingenic X1000 SoC & the really nice little CU Neo development board that's using it. - Support for WMAC on GARDENA Smart Gateway devices. - Lots of cleanup & refactoring of SGI IP27 (Origin 2*) support in preparation for introducing IP35 (Origin 3*) support. - Various Kconfig & Makefile cleanups. -----BEGIN PGP SIGNATURE----- iIwEABYIADQWIQRgLjeFAZEXQzy86/s+p5+stXUA3QUCXjRnpxYccGF1bGJ1cnRv bkBrZXJuZWwub3JnAAoJED6nn6y1dQDdNYoA/3ZhgKX1L/hwvkPKwu7FxbL41pjB WAm8IYDaxPvgxkcSAP9FNNepHK+oBPM8I2e3DvDvmcuYjumztdikzYbJ5HuMBA== =MV2S -----END PGP SIGNATURE----- Merge tag 'mips_5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux Pull MIPS changes from Paul Burton: "Nothing too big or scary in here: - Support mremap() for the VDSO, primarily to allow CRIU to restore the VDSO to its checkpointed location. - Restore the MIPS32 cBPF JIT, after having reverted the enablement of the eBPF JIT for MIPS32 systems in the 5.5 cycle. - Improve cop0 counter synchronization behaviour whilst onlining CPUs by running with interrupts disabled. - Better match FPU behaviour when emulating multiply-accumulate instructions on pre-r6 systems that implement IEEE754-2008 style MACs. - Loongson64 kernels now build using the MIPS64r2 ISA, allowing them to take advantage of instructions introduced by r2. - Support for the Ingenic X1000 SoC & the really nice little CU Neo development board that's using it. - Support for WMAC on GARDENA Smart Gateway devices. - Lots of cleanup & refactoring of SGI IP27 (Origin 2*) support in preparation for introducing IP35 (Origin 3*) support. - Various Kconfig & Makefile cleanups" * tag 'mips_5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (60 commits) MIPS: PCI: Add detection of IOC3 on IO7, IO8, IO9 and Fuel MIPS: Loongson64: Disable exec hazard MIPS: Loongson64: Bump ISA level to MIPSR2 MIPS: Make DIEI support as a config option MIPS: OCTEON: octeon-irq: fix spelling mistake "to" -> "too" MIPS: asm: local: add barriers for Loongson MIPS: Loongson64: Select mac2008 only feature MIPS: Add MAC2008 Support Revert "MIPS: Add custom serial.h with BASE_BAUD override for generic kernel" MIPS: sort MIPS and MIPS_GENERIC Kconfig selects alphabetically (again) MIPS: make CPU_HAS_LOAD_STORE_LR opt-out MIPS: generic: don't unconditionally select PINCTRL MIPS: don't explicitly select LIBFDT in Kconfig MIPS: sync-r4k: do slave counter synchronization with disabled HW interrupts MIPS: SGI-IP30: Check for valid pointer before using it MIPS: syscalls: fix indentation of the 'SYSNR' message MIPS: boot: fix typo in 'vmlinux.lzma.its' target MIPS: fix indentation of the 'RELOCS' message dt-bindings: Document loongson vendor-prefix MIPS: CU1000-Neo: Refresh defconfig to support HWMON and WiFi. ...
This commit is contained in:
Коммит
c5951e7c8e
|
@ -0,0 +1,35 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mips/ingenic/devices.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Ingenic XBurst based Platforms Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
|
||||
description: |
|
||||
Devices with a Ingenic XBurst CPU shall have the following properties.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
const: '/'
|
||||
compatible:
|
||||
oneOf:
|
||||
|
||||
- description: Qi Hardware Ben NanoNote
|
||||
items:
|
||||
- const: qi,lb60
|
||||
|
||||
- description: Game Consoles Worldwide GCW Zero
|
||||
items:
|
||||
- const: gcw,zero
|
||||
|
||||
- description: MIPS Creator CI20
|
||||
items:
|
||||
- const: img,ci20
|
||||
|
||||
- description: YSH & ATIL General Board CU Neo
|
||||
items:
|
||||
- const: yna,cu1000-neo
|
||||
...
|
|
@ -555,6 +555,8 @@ patternProperties:
|
|||
description: Logic PD, Inc.
|
||||
"^longcheer,.*":
|
||||
description: Longcheer Technology (Shanghai) Co., Ltd.
|
||||
"^loongson,.*":
|
||||
description: Loongson Technology Corporation Limited
|
||||
"^lsi,.*":
|
||||
description: LSI Corp. (LSI Logic)
|
||||
"^lwn,.*":
|
||||
|
@ -1084,6 +1086,8 @@ patternProperties:
|
|||
description: Shenzhen Xunlong Software CO.,Limited
|
||||
"^xylon,.*":
|
||||
description: Xylon
|
||||
"^yna,.*":
|
||||
description: YSH & ATIL
|
||||
"^yones-toptech,.*":
|
||||
description: Yones Toptech Co., Ltd.
|
||||
"^ysoft,.*":
|
||||
|
|
|
@ -11116,7 +11116,6 @@ F: drivers/usb/image/microtek.*
|
|||
MIPS
|
||||
M: Ralf Baechle <ralf@linux-mips.org>
|
||||
M: Paul Burton <paulburton@kernel.org>
|
||||
M: James Hogan <jhogan@kernel.org>
|
||||
L: linux-mips@vger.kernel.org
|
||||
W: http://www.linux-mips.org/
|
||||
T: git git://git.linux-mips.org/pub/scm/ralf/linux.git
|
||||
|
|
|
@ -5,9 +5,11 @@ config MIPS
|
|||
select ARCH_32BIT_OFF_T if !64BIT
|
||||
select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT
|
||||
select ARCH_CLOCKSOURCE_DATA
|
||||
select ARCH_HAS_FORTIFY_SOURCE
|
||||
select ARCH_HAS_KCOV
|
||||
select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI)
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select ARCH_HAS_UBSAN_SANITIZE_ALL
|
||||
select ARCH_HAS_FORTIFY_SOURCE
|
||||
select ARCH_SUPPORTS_UPROBES
|
||||
select ARCH_USE_BUILTIN_BSWAP
|
||||
select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
|
||||
|
@ -47,7 +49,7 @@ config MIPS
|
|||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES
|
||||
select HAVE_ASM_MODVERSIONS
|
||||
select HAVE_EBPF_JIT if 64BIT && !CPU_MICROMIPS && TARGET_ISA_REV >= 2
|
||||
select HAVE_CBPF_JIT if !64BIT && !CPU_MICROMIPS
|
||||
select HAVE_CONTEXT_TRACKING
|
||||
select HAVE_COPY_THREAD_TLS
|
||||
select HAVE_C_RECORDMCOUNT
|
||||
|
@ -55,11 +57,14 @@ config MIPS
|
|||
select HAVE_DEBUG_STACKOVERFLOW
|
||||
select HAVE_DMA_CONTIGUOUS
|
||||
select HAVE_DYNAMIC_FTRACE
|
||||
select HAVE_EBPF_JIT if 64BIT && !CPU_MICROMIPS && TARGET_ISA_REV >= 2
|
||||
select HAVE_EXIT_THREAD
|
||||
select HAVE_FAST_GUP
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_GCC_PLUGINS
|
||||
select HAVE_GENERIC_VDSO
|
||||
select HAVE_IDE
|
||||
select HAVE_IOREMAP_PROT
|
||||
select HAVE_IRQ_EXIT_ON_IRQ_STACK
|
||||
|
@ -78,18 +83,14 @@ config MIPS
|
|||
select HAVE_STACKPROTECTOR
|
||||
select HAVE_SYSCALL_TRACEPOINTS
|
||||
select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP
|
||||
select HAVE_GENERIC_VDSO
|
||||
select IRQ_FORCED_THREADING
|
||||
select ISA if EISA
|
||||
select MODULES_USE_ELF_RELA if MODULES && 64BIT
|
||||
select MODULES_USE_ELF_REL if MODULES
|
||||
select MODULES_USE_ELF_RELA if MODULES && 64BIT
|
||||
select PERF_USE_VMALLOC
|
||||
select RTC_LIB
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select VIRT_TO_BUS
|
||||
select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI)
|
||||
select ARCH_HAS_KCOV
|
||||
select HAVE_GCC_PLUGINS
|
||||
|
||||
menu "Machine selection"
|
||||
|
||||
|
@ -104,20 +105,18 @@ config MIPS_GENERIC
|
|||
select CEVT_R4K
|
||||
select CLKSRC_MIPS_GIC
|
||||
select COMMON_CLK
|
||||
select CPU_MIPSR2_IRQ_VI
|
||||
select CPU_MIPSR2_IRQ_EI
|
||||
select CPU_MIPSR2_IRQ_VI
|
||||
select CSRC_R4K
|
||||
select DMA_PERDEV_COHERENT
|
||||
select HAVE_PCI
|
||||
select IRQ_MIPS_CPU
|
||||
select LIBFDT
|
||||
select MIPS_AUTO_PFN_OFFSET
|
||||
select MIPS_CPU_SCACHE
|
||||
select MIPS_GIC
|
||||
select MIPS_L1_CACHE_SHIFT_7
|
||||
select NO_EXCEPT_FILL
|
||||
select PCI_DRIVERS_GENERIC
|
||||
select PINCTRL
|
||||
select SMP_UP if SMP
|
||||
select SWAP_IO_SPACE
|
||||
select SYS_HAS_CPU_MIPS32_R1
|
||||
|
@ -132,11 +131,12 @@ config MIPS_GENERIC
|
|||
select SYS_SUPPORTS_HIGHMEM
|
||||
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||
select SYS_SUPPORTS_MICROMIPS
|
||||
select SYS_SUPPORTS_MIPS_CPS
|
||||
select SYS_SUPPORTS_MIPS16
|
||||
select SYS_SUPPORTS_MIPS_CPS
|
||||
select SYS_SUPPORTS_MULTITHREADING
|
||||
select SYS_SUPPORTS_RELOCATABLE
|
||||
select SYS_SUPPORTS_SMARTMIPS
|
||||
select UHI_BOOT
|
||||
select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||
select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||
select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||
|
@ -144,7 +144,6 @@ config MIPS_GENERIC
|
|||
select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
|
||||
select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
|
||||
select USE_OF
|
||||
select UHI_BOOT
|
||||
help
|
||||
Select this to build a kernel which aims to support multiple boards,
|
||||
generally using a flattened device tree passed from the bootloader
|
||||
|
@ -403,7 +402,6 @@ config MACH_INGENIC
|
|||
select GENERIC_IRQ_CHIP
|
||||
select BUILTIN_DTB if MIPS_NO_APPENDED_DTB
|
||||
select USE_OF
|
||||
select LIBFDT
|
||||
|
||||
config LANTIQ
|
||||
bool "Lantiq based platforms"
|
||||
|
@ -510,7 +508,6 @@ config MACH_PISTACHIO
|
|||
select DMA_NONCOHERENT
|
||||
select GPIOLIB
|
||||
select IRQ_MIPS_CPU
|
||||
select LIBFDT
|
||||
select MFD_SYSCON
|
||||
select MIPS_CPU_SCACHE
|
||||
select MIPS_GIC
|
||||
|
@ -548,7 +545,6 @@ config MIPS_MALTA
|
|||
select I8253
|
||||
select I8259
|
||||
select IRQ_MIPS_CPU
|
||||
select LIBFDT
|
||||
select MIPS_BONITO64
|
||||
select MIPS_CPU_SCACHE
|
||||
select MIPS_GIC
|
||||
|
@ -980,7 +976,6 @@ config CAVIUM_OCTEON_SOC
|
|||
select ZONE_DMA32
|
||||
select HOLES_IN_ZONE
|
||||
select GPIOLIB
|
||||
select LIBFDT
|
||||
select USE_OF
|
||||
select ARCH_SPARSEMEM_ENABLE
|
||||
select SYS_SUPPORTS_SMP
|
||||
|
@ -1223,8 +1218,7 @@ config NO_IOPORT_MAP
|
|||
def_bool n
|
||||
|
||||
config GENERIC_CSUM
|
||||
bool
|
||||
default y if !CPU_HAS_LOAD_STORE_LR
|
||||
def_bool CPU_NO_LOAD_STORE_LR
|
||||
|
||||
config GENERIC_ISA_DMA
|
||||
bool
|
||||
|
@ -1442,11 +1436,14 @@ config CPU_LOONGSON64
|
|||
bool "Loongson 64-bit CPU"
|
||||
depends on SYS_HAS_CPU_LOONGSON64
|
||||
select ARCH_HAS_PHYS_TO_DMA
|
||||
select CPU_MIPSR2
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select CPU_SUPPORTS_MSA
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_DIEI_BROKEN if !LOONGSON3_ENHANCEMENT
|
||||
select CPU_MIPSR2_IRQ_VI
|
||||
select WEAK_ORDERING
|
||||
select WEAK_REORDERING_BEYOND_LLSC
|
||||
select MIPS_ASID_BITS_VARIABLE
|
||||
|
@ -1464,8 +1461,6 @@ config CPU_LOONGSON64
|
|||
config LOONGSON3_ENHANCEMENT
|
||||
bool "New Loongson-3 CPU Enhancements"
|
||||
default n
|
||||
select CPU_MIPSR2
|
||||
select CPU_HAS_PREFETCH
|
||||
depends on CPU_LOONGSON64
|
||||
help
|
||||
New Loongson-3 cores (since Loongson-3A R2, as opposed to Loongson-3A
|
||||
|
@ -1542,7 +1537,6 @@ config CPU_MIPS32_R1
|
|||
bool "MIPS32 Release 1"
|
||||
depends on SYS_HAS_CPU_MIPS32_R1
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
help
|
||||
|
@ -1560,7 +1554,6 @@ config CPU_MIPS32_R2
|
|||
bool "MIPS32 Release 2"
|
||||
depends on SYS_HAS_CPU_MIPS32_R2
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
select CPU_SUPPORTS_MSA
|
||||
|
@ -1576,6 +1569,7 @@ config CPU_MIPS32_R6
|
|||
bool "MIPS32 Release 6"
|
||||
depends on SYS_HAS_CPU_MIPS32_R6
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_NO_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
select CPU_SUPPORTS_MSA
|
||||
|
@ -1591,7 +1585,6 @@ config CPU_MIPS64_R1
|
|||
bool "MIPS64 Release 1"
|
||||
depends on SYS_HAS_CPU_MIPS64_R1
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1611,7 +1604,6 @@ config CPU_MIPS64_R2
|
|||
bool "MIPS64 Release 2"
|
||||
depends on SYS_HAS_CPU_MIPS64_R2
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1629,6 +1621,7 @@ config CPU_MIPS64_R6
|
|||
bool "MIPS64 Release 6"
|
||||
depends on SYS_HAS_CPU_MIPS64_R6
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_NO_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1646,7 +1639,6 @@ config CPU_R3000
|
|||
bool "R3000"
|
||||
depends on SYS_HAS_CPU_R3000
|
||||
select CPU_HAS_WB
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_R3K_TLB
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1662,7 +1654,6 @@ config CPU_TX39XX
|
|||
bool "R39XX"
|
||||
depends on SYS_HAS_CPU_TX39XX
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_R3K_TLB
|
||||
|
||||
config CPU_VR41XX
|
||||
|
@ -1670,7 +1661,6 @@ config CPU_VR41XX
|
|||
depends on SYS_HAS_CPU_VR41XX
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
help
|
||||
The options selects support for the NEC VR4100 series of processors.
|
||||
Only choose this option if you have one of these processors as a
|
||||
|
@ -1683,7 +1673,6 @@ config CPU_R4X00
|
|||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
help
|
||||
MIPS Technologies R4000-series processors other than 4300, including
|
||||
the R4000, R4400, R4600, and 4700.
|
||||
|
@ -1692,7 +1681,6 @@ config CPU_TX49XX
|
|||
bool "R49XX"
|
||||
depends on SYS_HAS_CPU_TX49XX
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
|
@ -1703,7 +1691,6 @@ config CPU_R5000
|
|||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
help
|
||||
MIPS Technologies R5000-series processors other than the Nevada.
|
||||
|
||||
|
@ -1713,7 +1700,6 @@ config CPU_R5500
|
|||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
help
|
||||
NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
|
||||
instruction set.
|
||||
|
@ -1724,7 +1710,6 @@ config CPU_NEVADA
|
|||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
help
|
||||
QED / PMC-Sierra RM52xx-series ("Nevada") processors.
|
||||
|
||||
|
@ -1732,7 +1717,6 @@ config CPU_R10000
|
|||
bool "R10000"
|
||||
depends on SYS_HAS_CPU_R10000
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1744,7 +1728,6 @@ config CPU_RM7000
|
|||
bool "RM7000"
|
||||
depends on SYS_HAS_CPU_RM7000
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1753,7 +1736,6 @@ config CPU_RM7000
|
|||
config CPU_SB1
|
||||
bool "SB1"
|
||||
depends on SYS_HAS_CPU_SB1
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1764,7 +1746,6 @@ config CPU_CAVIUM_OCTEON
|
|||
bool "Cavium Octeon processor"
|
||||
depends on SYS_HAS_CPU_CAVIUM_OCTEON
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select WEAK_ORDERING
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1794,7 +1775,6 @@ config CPU_BMIPS
|
|||
select WEAK_ORDERING
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_CPUFREQ
|
||||
select MIPS_EXTERNAL_TIMER
|
||||
help
|
||||
|
@ -1803,7 +1783,6 @@ config CPU_BMIPS
|
|||
config CPU_XLR
|
||||
bool "Netlogic XLR SoC"
|
||||
depends on SYS_HAS_CPU_XLR
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_64BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
|
@ -1822,7 +1801,6 @@ config CPU_XLP
|
|||
select WEAK_ORDERING
|
||||
select WEAK_REORDERING_BEYOND_LLSC
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_MIPSR2
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select MIPS_ASID_BITS_VARIABLE
|
||||
|
@ -1928,14 +1906,12 @@ config CPU_LOONGSON2EF
|
|||
select CPU_SUPPORTS_HIGHMEM
|
||||
select CPU_SUPPORTS_HUGEPAGES
|
||||
select ARCH_HAS_PHYS_TO_DMA
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
|
||||
config CPU_LOONGSON32
|
||||
bool
|
||||
select CPU_MIPS32
|
||||
select CPU_MIPSR2
|
||||
select CPU_HAS_PREFETCH
|
||||
select CPU_HAS_LOAD_STORE_LR
|
||||
select CPU_SUPPORTS_32BIT_KERNEL
|
||||
select CPU_SUPPORTS_HIGHMEM
|
||||
select CPU_SUPPORTS_CPUFREQ
|
||||
|
@ -2110,12 +2086,14 @@ config CPU_MIPSR2
|
|||
bool
|
||||
default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON
|
||||
select CPU_HAS_RIXI
|
||||
select CPU_HAS_DIEI if !CPU_DIEI_BROKEN
|
||||
select MIPS_SPRAM
|
||||
|
||||
config CPU_MIPSR6
|
||||
bool
|
||||
default y if CPU_MIPS32_R6 || CPU_MIPS64_R6
|
||||
select CPU_HAS_RIXI
|
||||
select CPU_HAS_DIEI if !CPU_DIEI_BROKEN
|
||||
select HAVE_ARCH_BITREVERSE
|
||||
select MIPS_ASID_BITS_VARIABLE
|
||||
select MIPS_CRC_SUPPORT
|
||||
|
@ -2575,15 +2553,23 @@ config CPU_HAS_WB
|
|||
config XKS01
|
||||
bool
|
||||
|
||||
config CPU_HAS_DIEI
|
||||
depends on !CPU_DIEI_BROKEN
|
||||
bool
|
||||
|
||||
config CPU_DIEI_BROKEN
|
||||
bool
|
||||
|
||||
config CPU_HAS_RIXI
|
||||
bool
|
||||
|
||||
config CPU_HAS_LOAD_STORE_LR
|
||||
config CPU_NO_LOAD_STORE_LR
|
||||
bool
|
||||
help
|
||||
CPU has support for unaligned load and store instructions:
|
||||
CPU lacks support for unaligned load and store instructions:
|
||||
LWL, LWR, SWL, SWR (Load/store word left/right).
|
||||
LDL, LDR, SDL, SDR (Load/store doubleword left/right, for 64bit systems).
|
||||
LDL, LDR, SDL, SDR (Load/store doubleword left/right, for 64bit
|
||||
systems).
|
||||
|
||||
#
|
||||
# Vectored interrupt mode is an R2 feature
|
||||
|
@ -2696,6 +2682,14 @@ config NUMA
|
|||
config SYS_SUPPORTS_NUMA
|
||||
bool
|
||||
|
||||
config HAVE_SETUP_PER_CPU_AREA
|
||||
def_bool y
|
||||
depends on NUMA
|
||||
|
||||
config NEED_PER_CPU_EMBED_FIRST_CHUNK
|
||||
def_bool y
|
||||
depends on NUMA
|
||||
|
||||
config RELOCATABLE
|
||||
bool "Relocatable kernel"
|
||||
depends on SYS_SUPPORTS_RELOCATABLE && (CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_MIPS32_R6 || CPU_MIPS64_R6 || CAVIUM_OCTEON_SOC)
|
||||
|
|
|
@ -17,7 +17,7 @@ quiet_cmd_ls3_llsc = LLSCCHK $@
|
|||
cmd_ls3_llsc = $(CMD_LS3_LLSC) $@
|
||||
|
||||
CMD_RELOCS = arch/mips/boot/tools/relocs
|
||||
quiet_cmd_relocs = RELOCS $@
|
||||
quiet_cmd_relocs = RELOCS $@
|
||||
cmd_relocs = $(CMD_RELOCS) $@
|
||||
|
||||
# `@true` prevents complaint when there is nothing to be done
|
||||
|
|
|
@ -123,7 +123,7 @@ $(obj)/vmlinux.its.S: $(addprefix $(srctree)/arch/mips/$(PLATFORM)/,$(ITS_INPUTS
|
|||
targets += vmlinux.its
|
||||
targets += vmlinux.gz.its
|
||||
targets += vmlinux.bz2.its
|
||||
targets += vmlinux.lzmo.its
|
||||
targets += vmlinux.lzma.its
|
||||
targets += vmlinux.lzo.its
|
||||
|
||||
quiet_cmd_cpp_its_S = ITS $@
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
dtb-$(CONFIG_JZ4740_QI_LB60) += qi_lb60.dtb
|
||||
dtb-$(CONFIG_JZ4770_GCW0) += gcw0.dtb
|
||||
dtb-$(CONFIG_JZ4780_CI20) += ci20.dtb
|
||||
dtb-$(CONFIG_X1000_CU1000_NEO) += cu1000-neo.dtb
|
||||
|
||||
obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/dts-v1/;
|
||||
|
||||
#include "x1000.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/clock/ingenic,tcu.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
/ {
|
||||
compatible = "yna,cu1000-neo", "ingenic,x1000";
|
||||
model = "YSH & ATIL General Board CU Neo";
|
||||
|
||||
aliases {
|
||||
serial2 = &uart2;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial2:115200n8";
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0x0 0x04000000>;
|
||||
};
|
||||
|
||||
wlan_pwrseq: msc1-pwrseq {
|
||||
compatible = "mmc-pwrseq-simple";
|
||||
|
||||
clocks = <&lpoclk>;
|
||||
clock-names = "ext_clock";
|
||||
|
||||
reset-gpios = <&gpc 17 GPIO_ACTIVE_LOW>;
|
||||
post-power-on-delay-ms = <200>;
|
||||
|
||||
lpoclk: ap6212a {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&exclk {
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
|
||||
&tcu {
|
||||
/* 1500 kHz for the system timer and clocksource */
|
||||
assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER2>;
|
||||
assigned-clock-rates = <1500000>, <1500000>;
|
||||
|
||||
/* Use channel #0 for the system timer channel #2 for the clocksource */
|
||||
ingenic,pwm-channels-mask = <0xfa>;
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
|
||||
clock-frequency = <400000>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_i2c0>;
|
||||
|
||||
ads7830@48 {
|
||||
compatible = "ti,ads7830";
|
||||
reg = <0x48>;
|
||||
};
|
||||
};
|
||||
|
||||
&uart2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_uart2>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mac {
|
||||
phy-mode = "rmii";
|
||||
phy-handle = <&lan8720a>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_mac>;
|
||||
|
||||
snps,reset-gpio = <&gpc 23 GPIO_ACTIVE_LOW>; /* PC23 */
|
||||
snps,reset-active-low;
|
||||
snps,reset-delays-us = <0 10000 30000>;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&mdio {
|
||||
status = "okay";
|
||||
|
||||
lan8720a: ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-id0007.c0f0", "ethernet-phy-ieee802.3-c22";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&msc0 {
|
||||
bus-width = <8>;
|
||||
max-frequency = <50000000>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_msc0>;
|
||||
|
||||
non-removable;
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&msc1 {
|
||||
bus-width = <4>;
|
||||
max-frequency = <50000000>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pins_msc1>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
non-removable;
|
||||
|
||||
mmc-pwrseq = <&wlan_pwrseq>;
|
||||
|
||||
status = "okay";
|
||||
|
||||
ap6212a: wifi@1 {
|
||||
compatible = "brcm,bcm4329-fmac";
|
||||
reg = <1>;
|
||||
|
||||
interrupt-parent = <&gpc>;
|
||||
interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-names = "host-wake";
|
||||
|
||||
brcm,drive-strength = <10>;
|
||||
};
|
||||
};
|
||||
|
||||
&pinctrl {
|
||||
pins_i2c0: i2c0 {
|
||||
function = "i2c0";
|
||||
groups = "i2c0-data";
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pins_uart2: uart2 {
|
||||
function = "uart2";
|
||||
groups = "uart2-data-d";
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pins_mac: mac {
|
||||
function = "mac";
|
||||
groups = "mac";
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pins_msc0: msc0 {
|
||||
function = "mmc0";
|
||||
groups = "mmc0-1bit", "mmc0-4bit", "mmc0-8bit";
|
||||
bias-disable;
|
||||
};
|
||||
|
||||
pins_msc1: msc1 {
|
||||
function = "mmc1";
|
||||
groups = "mmc1-1bit", "mmc1-4bit";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,317 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <dt-bindings/clock/x1000-cgu.h>
|
||||
#include <dt-bindings/dma/x1000-dma.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "ingenic,x1000", "ingenic,x1000e";
|
||||
|
||||
cpuintc: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
compatible = "mti,cpu-interrupt-controller";
|
||||
};
|
||||
|
||||
intc: interrupt-controller@10001000 {
|
||||
compatible = "ingenic,x1000-intc", "ingenic,jz4780-intc";
|
||||
reg = <0x10001000 0x50>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&cpuintc>;
|
||||
interrupts = <2>;
|
||||
};
|
||||
|
||||
exclk: ext {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
rtclk: rtc {
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
};
|
||||
|
||||
cgu: x1000-cgu@10000000 {
|
||||
compatible = "ingenic,x1000-cgu";
|
||||
reg = <0x10000000 0x100>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&exclk>, <&rtclk>;
|
||||
clock-names = "ext", "rtc";
|
||||
};
|
||||
|
||||
tcu: timer@10002000 {
|
||||
compatible = "ingenic,x1000-tcu",
|
||||
"ingenic,jz4770-tcu",
|
||||
"simple-mfd";
|
||||
reg = <0x10002000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x10002000 0x1000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_RTCLK
|
||||
&cgu X1000_CLK_EXCLK
|
||||
&cgu X1000_CLK_PCLK>;
|
||||
clock-names = "rtc", "ext", "pclk";
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <27 26 25>;
|
||||
|
||||
wdt: watchdog@0 {
|
||||
compatible = "ingenic,x1000-watchdog", "ingenic,jz4780-watchdog";
|
||||
reg = <0x0 0x10>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_RTCLK>;
|
||||
clock-names = "wdt";
|
||||
};
|
||||
};
|
||||
|
||||
rtc: rtc@10003000 {
|
||||
compatible = "ingenic,x1000-rtc", "ingenic,jz4780-rtc";
|
||||
reg = <0x10003000 0x4c>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <32>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_RTCLK>;
|
||||
clock-names = "rtc";
|
||||
};
|
||||
|
||||
pinctrl: pin-controller@10010000 {
|
||||
compatible = "ingenic,x1000-pinctrl";
|
||||
reg = <0x10010000 0x800>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gpa: gpio@0 {
|
||||
compatible = "ingenic,x1000-gpio";
|
||||
reg = <0>;
|
||||
|
||||
gpio-controller;
|
||||
gpio-ranges = <&pinctrl 0 0 32>;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <17>;
|
||||
};
|
||||
|
||||
gpb: gpio@1 {
|
||||
compatible = "ingenic,x1000-gpio";
|
||||
reg = <1>;
|
||||
|
||||
gpio-controller;
|
||||
gpio-ranges = <&pinctrl 0 32 32>;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <16>;
|
||||
};
|
||||
|
||||
gpc: gpio@2 {
|
||||
compatible = "ingenic,x1000-gpio";
|
||||
reg = <2>;
|
||||
|
||||
gpio-controller;
|
||||
gpio-ranges = <&pinctrl 0 64 32>;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <15>;
|
||||
};
|
||||
|
||||
gpd: gpio@3 {
|
||||
compatible = "ingenic,x1000-gpio";
|
||||
reg = <3>;
|
||||
|
||||
gpio-controller;
|
||||
gpio-ranges = <&pinctrl 0 96 32>;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <14>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c0: i2c-controller@10050000 {
|
||||
compatible = "ingenic,x1000-i2c";
|
||||
reg = <0x10050000 0x1000>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <60>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_I2C0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c1: i2c-controller@10051000 {
|
||||
compatible = "ingenic,x1000-i2c";
|
||||
reg = <0x10051000 0x1000>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <59>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_I2C1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c2: i2c-controller@10052000 {
|
||||
compatible = "ingenic,x1000-i2c";
|
||||
reg = <0x10052000 0x1000>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <58>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_I2C2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart0: serial@10030000 {
|
||||
compatible = "ingenic,x1000-uart";
|
||||
reg = <0x10030000 0x100>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <51>;
|
||||
|
||||
clocks = <&exclk>, <&cgu X1000_CLK_UART0>;
|
||||
clock-names = "baud", "module";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart1: serial@10031000 {
|
||||
compatible = "ingenic,x1000-uart";
|
||||
reg = <0x10031000 0x100>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <50>;
|
||||
|
||||
clocks = <&exclk>, <&cgu X1000_CLK_UART1>;
|
||||
clock-names = "baud", "module";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart2: serial@10032000 {
|
||||
compatible = "ingenic,x1000-uart";
|
||||
reg = <0x10032000 0x100>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <49>;
|
||||
|
||||
clocks = <&exclk>, <&cgu X1000_CLK_UART2>;
|
||||
clock-names = "baud", "module";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pdma: dma-controller@13420000 {
|
||||
compatible = "ingenic,x1000-dma";
|
||||
reg = <0x13420000 0x400
|
||||
0x13421000 0x40>;
|
||||
#dma-cells = <2>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <10>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_PDMA>;
|
||||
};
|
||||
|
||||
mac: ethernet@134b0000 {
|
||||
compatible = "ingenic,x1000-mac", "snps,dwmac";
|
||||
reg = <0x134b0000 0x2000>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <55>;
|
||||
interrupt-names = "macirq";
|
||||
|
||||
clocks = <&cgu X1000_CLK_MAC>;
|
||||
clock-names = "stmmaceth";
|
||||
|
||||
status = "disabled";
|
||||
|
||||
mdio: mdio {
|
||||
compatible = "snps,dwmac-mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
msc0: mmc@13450000 {
|
||||
compatible = "ingenic,x1000-mmc";
|
||||
reg = <0x13450000 0x1000>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <37>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_MSC0>;
|
||||
clock-names = "mmc";
|
||||
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
cap-sdio-irq;
|
||||
|
||||
dmas = <&pdma X1000_DMA_MSC0_RX 0xffffffff>,
|
||||
<&pdma X1000_DMA_MSC0_TX 0xffffffff>;
|
||||
dma-names = "rx", "tx";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
msc1: mmc@13460000 {
|
||||
compatible = "ingenic,x1000-mmc";
|
||||
reg = <0x13460000 0x1000>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <36>;
|
||||
|
||||
clocks = <&cgu X1000_CLK_MSC1>;
|
||||
clock-names = "mmc";
|
||||
|
||||
cap-sd-highspeed;
|
||||
cap-mmc-highspeed;
|
||||
cap-sdio-irq;
|
||||
|
||||
dmas = <&pdma X1000_DMA_MSC1_RX 0xffffffff>,
|
||||
<&pdma X1000_DMA_MSC1_TX 0xffffffff>;
|
||||
dma-names = "rx", "tx";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
|
@ -177,6 +177,9 @@
|
|||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinmux_i2s_gpio>; /* GPIO0..3 */
|
||||
|
||||
fifo-size = <8>;
|
||||
tx-threshold = <8>;
|
||||
|
||||
rts-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
|
||||
cts-gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
@ -195,3 +198,8 @@
|
|||
&watchdog {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wmac {
|
||||
status = "okay";
|
||||
mediatek,mtd-eeprom = <&factory 0x0000>;
|
||||
};
|
||||
|
|
|
@ -285,4 +285,14 @@
|
|||
interrupt-parent = <&intc>;
|
||||
interrupts = <18>;
|
||||
};
|
||||
|
||||
wmac: wmac@10300000 {
|
||||
compatible = "mediatek,mt7628-wmac";
|
||||
reg = <0x10300000 0x100000>;
|
||||
|
||||
interrupt-parent = <&cpuintc>;
|
||||
interrupts = <6>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2193,7 +2193,7 @@ static int octeon_irq_cib_map(struct irq_domain *d,
|
|||
struct octeon_irq_cib_chip_data *cd;
|
||||
|
||||
if (hw >= host_data->max_bits) {
|
||||
pr_err("ERROR: %s mapping %u is to big!\n",
|
||||
pr_err("ERROR: %s mapping %u is too big!\n",
|
||||
irq_domain_get_of_node(d)->name, (unsigned)hw);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
CONFIG_LOCALVERSION_AUTO=y
|
||||
CONFIG_KERNEL_GZIP=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_HIGH_RES_TIMERS=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_KMEM=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
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_MACH_INGENIC=y
|
||||
CONFIG_X1000_CU1000_NEO=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_HZ_100=y
|
||||
# CONFIG_SECCOMP is not set
|
||||
# CONFIG_SUSPEND is not set
|
||||
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
|
||||
# CONFIG_COMPACTION is not set
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_AREAS=7
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_CFG80211=y
|
||||
CONFIG_UEVENT_HELPER=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
# CONFIG_FW_LOADER is not set
|
||||
# CONFIG_ALLOW_DEV_COREDUMP is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_STMMAC_ETH=y
|
||||
CONFIG_SMSC_PHY=y
|
||||
CONFIG_BRCMFMAC=y
|
||||
# CONFIG_INPUT_MOUSEDEV is not set
|
||||
# CONFIG_INPUT_KEYBOARD is not set
|
||||
# CONFIG_INPUT_MOUSE is not set
|
||||
# CONFIG_SERIO is not set
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_LEGACY_PTY_COUNT=2
|
||||
CONFIG_SERIAL_EARLYCON=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=3
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=3
|
||||
CONFIG_SERIAL_8250_INGENIC=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_JZ4780=y
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
CONFIG_SENSORS_ADS7828=y
|
||||
CONFIG_WATCHDOG=y
|
||||
CONFIG_JZ4740_WDT=y
|
||||
# CONFIG_LCD_CLASS_DEVICE is not set
|
||||
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
# CONFIG_HID is not set
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_JZ4740=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_JZ4740=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_JZ4780=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_NVMEM_SYSFS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
# CONFIG_DNOTIFY is not set
|
||||
CONFIG_AUTOFS_FS=y
|
||||
CONFIG_PROC_KCORE=y
|
||||
# CONFIG_PROC_PAGE_MONITOR is not set
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
CONFIG_NFS_FS=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NLS_CODEPAGE_936=y
|
||||
CONFIG_NLS_CODEPAGE_950=y
|
||||
CONFIG_NLS_ASCII=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NLS_UTF8=y
|
||||
CONFIG_CRYPTO_ECHAINIV=y
|
||||
CONFIG_CRYPTO_AES=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
|
||||
CONFIG_CONSOLE_LOGLEVEL_QUIET=15
|
||||
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
CONFIG_PANIC_TIMEOUT=10
|
||||
# CONFIG_SCHED_DEBUG is not set
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
CONFIG_STACKTRACE=y
|
||||
# CONFIG_FTRACE is not set
|
||||
CONFIG_CMDLINE_BOOL=y
|
||||
CONFIG_CMDLINE="earlycon clk_ignore_unused"
|
|
@ -41,6 +41,7 @@ CONFIG_SPI_DESIGNWARE=y
|
|||
CONFIG_SPI_DW_MMIO=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_OCELOT=y
|
||||
|
||||
CONFIG_GPIO_SYSFS=y
|
||||
|
|
|
@ -19,6 +19,7 @@ generic-y += preempt.h
|
|||
generic-y += qrwlock.h
|
||||
generic-y += qspinlock.h
|
||||
generic-y += sections.h
|
||||
generic-y += serial.h
|
||||
generic-y += trace_clock.h
|
||||
generic-y += unaligned.h
|
||||
generic-y += user.h
|
||||
|
|
|
@ -81,6 +81,7 @@ enum loongson2ef_machine_type {
|
|||
#define MACH_INGENIC_JZ4770 2 /* JZ4770 SOC */
|
||||
#define MACH_INGENIC_JZ4780 3 /* JZ4780 SOC */
|
||||
#define MACH_INGENIC_X1000 4 /* X1000 SOC */
|
||||
#define MACH_INGENIC_X1830 5 /* X1830 SOC */
|
||||
|
||||
extern char *system_type;
|
||||
const char *get_system_type(void);
|
||||
|
|
|
@ -555,6 +555,10 @@
|
|||
# define cpu_has_perf __opt(MIPS_CPU_PERF)
|
||||
#endif
|
||||
|
||||
#ifndef cpu_has_mac2008_only
|
||||
# define cpu_has_mac2008_only __opt(MIPS_CPU_MAC_2008_ONLY)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* Some systems share FTLB RAMs between threads within a core (siblings in
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#define PRID_COMP_NETLOGIC 0x0c0000
|
||||
#define PRID_COMP_CAVIUM 0x0d0000
|
||||
#define PRID_COMP_LOONGSON 0x140000
|
||||
#define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */
|
||||
#define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750, X1830 */
|
||||
#define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775, X1000 */
|
||||
#define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */
|
||||
|
||||
|
@ -185,7 +185,8 @@
|
|||
* These are the PRID's for when 23:16 == PRID_COMP_INGENIC_*
|
||||
*/
|
||||
|
||||
#define PRID_IMP_XBURST 0x0200
|
||||
#define PRID_IMP_XBURST_REV1 0x0200 /* XBurst with MXU SIMD ISA */
|
||||
#define PRID_IMP_XBURST_REV2 0x0100 /* XBurst with MXU2 SIMD ISA */
|
||||
|
||||
/*
|
||||
* These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC
|
||||
|
@ -415,6 +416,7 @@ enum cpu_type_enum {
|
|||
#define MIPS_CPU_MT_PER_TC_PERF_COUNTERS \
|
||||
BIT_ULL(56) /* CPU has perf counters implemented per TC (MIPSMT ASE) */
|
||||
#define MIPS_CPU_MMID BIT_ULL(57) /* CPU supports MemoryMapIDs */
|
||||
#define MIPS_CPU_MAC_2008_ONLY BIT_ULL(58) /* CPU Only support MAC2008 Fused multiply-add instruction */
|
||||
|
||||
/*
|
||||
* CPU ASE encodings
|
||||
|
|
|
@ -32,8 +32,6 @@ struct gio_driver {
|
|||
};
|
||||
#define to_gio_driver(drv) container_of(drv, struct gio_driver, driver)
|
||||
|
||||
extern const struct gio_device_id *gio_match_device(const struct gio_device_id *,
|
||||
const struct gio_device *);
|
||||
extern struct gio_device *gio_dev_get(struct gio_device *);
|
||||
extern void gio_dev_put(struct gio_device *);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* TLB hazards
|
||||
*/
|
||||
#if (defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)) && \
|
||||
!defined(CONFIG_CPU_CAVIUM_OCTEON) && !defined(CONFIG_LOONGSON3_ENHANCEMENT)
|
||||
!defined(CONFIG_CPU_CAVIUM_OCTEON) && !defined(CONFIG_CPU_LOONGSON64)
|
||||
|
||||
/*
|
||||
* MIPSR2 defines ehb for hazard avoidance
|
||||
|
@ -158,7 +158,7 @@ do { \
|
|||
} while (0)
|
||||
|
||||
#elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
|
||||
defined(CONFIG_CPU_LOONGSON2EF) || defined(CONFIG_LOONGSON3_ENHANCEMENT) || \
|
||||
defined(CONFIG_CPU_LOONGSON2EF) || defined(CONFIG_CPU_LOONGSON64) || \
|
||||
defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR)
|
||||
|
||||
/*
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <asm/compiler.h>
|
||||
#include <asm/hazards.h>
|
||||
|
||||
#if defined(CONFIG_CPU_MIPSR2) || defined (CONFIG_CPU_MIPSR6)
|
||||
#if defined(CONFIG_CPU_HAS_DIEI)
|
||||
|
||||
static inline void arch_local_irq_disable(void)
|
||||
{
|
||||
|
@ -94,7 +94,7 @@ static inline void arch_local_irq_restore(unsigned long flags)
|
|||
void arch_local_irq_disable(void);
|
||||
unsigned long arch_local_irq_save(void);
|
||||
void arch_local_irq_restore(unsigned long flags);
|
||||
#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
|
||||
#endif /* CONFIG_CPU_HAS_DIEI */
|
||||
|
||||
static inline void arch_local_irq_enable(void)
|
||||
{
|
||||
|
@ -102,7 +102,7 @@ static inline void arch_local_irq_enable(void)
|
|||
" .set push \n"
|
||||
" .set reorder \n"
|
||||
" .set noat \n"
|
||||
#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
|
||||
#if defined(CONFIG_CPU_HAS_DIEI)
|
||||
" ei \n"
|
||||
#else
|
||||
" mfc0 $1,$12 \n"
|
||||
|
|
|
@ -37,6 +37,7 @@ static __inline__ long local_add_return(long i, local_t * l)
|
|||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set arch=r4000 \n"
|
||||
__SYNC(full, loongson3_war) " \n"
|
||||
"1:" __LL "%1, %2 # local_add_return \n"
|
||||
" addu %0, %1, %3 \n"
|
||||
__SC "%0, %2 \n"
|
||||
|
@ -52,6 +53,7 @@ static __inline__ long local_add_return(long i, local_t * l)
|
|||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_ARCH_LEVEL" \n"
|
||||
__SYNC(full, loongson3_war) " \n"
|
||||
"1:" __LL "%1, %2 # local_add_return \n"
|
||||
" addu %0, %1, %3 \n"
|
||||
__SC "%0, %2 \n"
|
||||
|
@ -84,6 +86,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
|
|||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set arch=r4000 \n"
|
||||
__SYNC(full, loongson3_war) " \n"
|
||||
"1:" __LL "%1, %2 # local_sub_return \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
__SC "%0, %2 \n"
|
||||
|
@ -99,6 +102,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
|
|||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_ARCH_LEVEL" \n"
|
||||
__SYNC(full, loongson3_war) " \n"
|
||||
"1:" __LL "%1, %2 # local_sub_return \n"
|
||||
" subu %0, %1, %3 \n"
|
||||
__SC "%0, %2 \n"
|
||||
|
|
|
@ -10,19 +10,9 @@
|
|||
#define __ASM_MACH_IP27_KERNEL_ENTRY_H
|
||||
|
||||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/sn0/hubni.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/klkernvars.h>
|
||||
|
||||
/*
|
||||
* Returns the local nasid into res.
|
||||
*/
|
||||
.macro GET_NASID_ASM res
|
||||
dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
|
||||
ld \res, (\res)
|
||||
and \res, NSRI_NODEID_MASK
|
||||
dsrl \res, NSRI_NODEID_SHFT
|
||||
.endm
|
||||
|
||||
/*
|
||||
* TLB bits
|
||||
*/
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#ifndef __ASM_MACH_IP27_MANGLE_PORT_H
|
||||
#define __ASM_MACH_IP27_MANGLE_PORT_H
|
||||
|
||||
#define __swizzle_addr_b(port) (port)
|
||||
#define __swizzle_addr_b(port) ((port) ^ 3)
|
||||
#define __swizzle_addr_w(port) ((port) ^ 2)
|
||||
#define __swizzle_addr_l(port) (port)
|
||||
#define __swizzle_addr_q(port) (port)
|
||||
|
@ -20,6 +20,6 @@
|
|||
# define ioswabl(a, x) (x)
|
||||
# define __mem_ioswabl(a, x) cpu_to_le32(x)
|
||||
# define ioswabq(a, x) (x)
|
||||
# define __mem_ioswabq(a, x) cpu_to_le32(x)
|
||||
# define __mem_ioswabq(a, x) cpu_to_le64(x)
|
||||
|
||||
#endif /* __ASM_MACH_IP27_MANGLE_PORT_H */
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/klkernvars.h>
|
||||
|
||||
#define pa_to_nid(addr) NASID_GET(addr)
|
||||
|
||||
|
@ -12,7 +13,6 @@ struct hub_data {
|
|||
kern_vars_t kern_vars;
|
||||
DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW);
|
||||
cpumask_t h_cpus;
|
||||
unsigned long slice_map;
|
||||
};
|
||||
|
||||
struct node_data {
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
#ifndef _ASM_MACH_TOPOLOGY_H
|
||||
#define _ASM_MACH_TOPOLOGY_H 1
|
||||
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/sn/types.h>
|
||||
#include <asm/mmzone.h>
|
||||
|
||||
struct cpuinfo_ip27 {
|
||||
nasid_t p_nasid; /* my node ID in numa-as-id-space */
|
||||
unsigned short p_speed; /* cpu speed in MHz */
|
||||
unsigned char p_slice; /* Physical position on node board */
|
||||
};
|
||||
|
||||
|
|
|
@ -46,5 +46,7 @@
|
|||
#define cpu_has_wsbh 1
|
||||
#define cpu_has_ic_fills_f_dc 1
|
||||
#define cpu_hwrena_impl_bits 0xc0000000
|
||||
#define cpu_has_mac2008_only 1
|
||||
#define cpu_has_mips_r2_exec_hazard 0
|
||||
|
||||
#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */
|
||||
|
|
|
@ -1101,9 +1101,12 @@
|
|||
/*
|
||||
* Bits 22:20 of the FPU Status Register will be read as 0,
|
||||
* and should be written as zero.
|
||||
* MAC2008 was removed in Release 5 so we still treat it as
|
||||
* reserved.
|
||||
*/
|
||||
#define FPU_CSR_RSVD (_ULCAST_(7) << 20)
|
||||
|
||||
#define FPU_CSR_MAC2008 (_ULCAST_(1) << 20)
|
||||
#define FPU_CSR_ABS2008 (_ULCAST_(1) << 19)
|
||||
#define FPU_CSR_NAN2008 (_ULCAST_(1) << 18)
|
||||
|
||||
|
|
|
@ -806,7 +806,8 @@ struct bridge_controller {
|
|||
unsigned long baddr;
|
||||
unsigned long intr_addr;
|
||||
struct irq_domain *domain;
|
||||
unsigned int pci_int[8];
|
||||
unsigned int pci_int[8][2];
|
||||
unsigned int int_mapping[8][2];
|
||||
u32 ioc3_sid[8];
|
||||
nasid_t nasid;
|
||||
};
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2017 MIPS Tech, LLC
|
||||
*/
|
||||
#ifndef __ASM__SERIAL_H
|
||||
#define __ASM__SERIAL_H
|
||||
|
||||
#ifdef CONFIG_MIPS_GENERIC
|
||||
/*
|
||||
* Generic kernels cannot know a correct value for all platforms at
|
||||
* compile time. Set it to 0 to prevent 8250_early using it
|
||||
*/
|
||||
#define BASE_BAUD 0
|
||||
#else
|
||||
#include <asm-generic/serial.h>
|
||||
#endif
|
||||
|
||||
#endif /* __ASM__SERIAL_H */
|
|
@ -25,7 +25,4 @@
|
|||
#define INVALID_MODULE (moduleid_t)-1
|
||||
#define INVALID_PARTID (partid_t)-1
|
||||
|
||||
extern nasid_t get_nasid(void);
|
||||
extern int get_cpu_slice(cpuid_t);
|
||||
|
||||
#endif /* _ASM_SN_ARCH_H */
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_SN_HUB_H
|
||||
#define __ASM_SN_HUB_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <asm/sn/types.h>
|
||||
#include <asm/sn/io.h>
|
||||
#include <asm/sn/klkernvars.h>
|
||||
#include <asm/xtalk/xtalk.h>
|
||||
|
||||
/* ip27-hubio.c */
|
||||
extern unsigned long hub_pio_map(nasid_t nasid, xwidgetnum_t widget,
|
||||
unsigned long xtalk_addr, size_t size);
|
||||
extern void hub_pio_init(nasid_t nasid);
|
||||
|
||||
#endif /* __ASM_SN_HUB_H */
|
|
@ -8,15 +8,6 @@
|
|||
#ifndef __ASM_SN_INTR_H
|
||||
#define __ASM_SN_INTR_H
|
||||
|
||||
/* Number of interrupt levels associated with each interrupt register. */
|
||||
#define N_INTPEND_BITS 64
|
||||
|
||||
#define INT_PEND0_BASELVL 0
|
||||
#define INT_PEND1_BASELVL 64
|
||||
|
||||
#define N_INTPENDJUNK_BITS 8
|
||||
#define INTPENDJUNK_CLRBIT 0x80
|
||||
|
||||
/*
|
||||
* Macros to manipulate the interrupt register on the calling hub chip.
|
||||
*/
|
||||
|
@ -84,14 +75,6 @@ do { \
|
|||
#define CPU_RESCHED_B_IRQ 8
|
||||
#define CPU_CALL_A_IRQ 9
|
||||
#define CPU_CALL_B_IRQ 10
|
||||
#define MSC_MESG_INTR 11
|
||||
#define BASE_PCI_IRQ 12
|
||||
|
||||
/*
|
||||
* INT_PEND0 again, bits determined by hardware / hardcoded:
|
||||
*/
|
||||
#define SDISK_INTR 63 /* SABLE name */
|
||||
#define IP_PEND0_6_63 63 /* What is this bit? */
|
||||
|
||||
/*
|
||||
* INT_PEND1 hard-coded bits:
|
||||
|
|
|
@ -21,50 +21,50 @@ struct ioc3_serialregs {
|
|||
|
||||
/* SUPERIO uart register map */
|
||||
struct ioc3_uartregs {
|
||||
u8 iu_lcr;
|
||||
union {
|
||||
u8 iu_rbr; /* read only, DLAB == 0 */
|
||||
u8 iu_thr; /* write only, DLAB == 0 */
|
||||
u8 iu_dll; /* DLAB == 1 */
|
||||
u8 iu_iir; /* read only */
|
||||
u8 iu_fcr; /* write only */
|
||||
};
|
||||
union {
|
||||
u8 iu_ier; /* DLAB == 0 */
|
||||
u8 iu_dlm; /* DLAB == 1 */
|
||||
};
|
||||
union {
|
||||
u8 iu_iir; /* read only */
|
||||
u8 iu_fcr; /* write only */
|
||||
u8 iu_rbr; /* read only, DLAB == 0 */
|
||||
u8 iu_thr; /* write only, DLAB == 0 */
|
||||
u8 iu_dll; /* DLAB == 1 */
|
||||
};
|
||||
u8 iu_lcr;
|
||||
u8 iu_mcr;
|
||||
u8 iu_lsr;
|
||||
u8 iu_msr;
|
||||
u8 iu_scr;
|
||||
u8 iu_msr;
|
||||
u8 iu_lsr;
|
||||
u8 iu_mcr;
|
||||
};
|
||||
|
||||
struct ioc3_sioregs {
|
||||
u8 fill[0x141]; /* starts at 0x141 */
|
||||
|
||||
u8 uartc;
|
||||
u8 kbdcg;
|
||||
u8 uartc;
|
||||
|
||||
u8 fill0[0x150 - 0x142 - 1];
|
||||
u8 fill0[0x151 - 0x142 - 1];
|
||||
|
||||
u8 pp_data;
|
||||
u8 pp_dsr;
|
||||
u8 pp_dcr;
|
||||
u8 pp_dsr;
|
||||
u8 pp_data;
|
||||
|
||||
u8 fill1[0x158 - 0x152 - 1];
|
||||
u8 fill1[0x159 - 0x153 - 1];
|
||||
|
||||
u8 pp_fifa;
|
||||
u8 pp_cfgb;
|
||||
u8 pp_ecr;
|
||||
u8 pp_cfgb;
|
||||
u8 pp_fifa;
|
||||
|
||||
u8 fill2[0x168 - 0x15a - 1];
|
||||
u8 fill2[0x16a - 0x15b - 1];
|
||||
|
||||
u8 rtcad;
|
||||
u8 rtcdat;
|
||||
u8 rtcad;
|
||||
|
||||
u8 fill3[0x170 - 0x169 - 1];
|
||||
u8 fill3[0x170 - 0x16b - 1];
|
||||
|
||||
struct ioc3_uartregs uartb; /* 0x20170 */
|
||||
struct ioc3_uartregs uarta; /* 0x20178 */
|
||||
|
@ -598,5 +598,9 @@ struct ioc3_etxd {
|
|||
#define IOC3_SUBSYS_IP30_SYSBOARD 0xc304
|
||||
#define IOC3_SUBSYS_MENET 0xc305
|
||||
#define IOC3_SUBSYS_MENET4 0xc306
|
||||
#define IOC3_SUBSYS_IO7 0xc307
|
||||
#define IOC3_SUBSYS_IO8 0xc308
|
||||
#define IOC3_SUBSYS_IO9 0xc309
|
||||
#define IOC3_SUBSYS_IP34_SYSBOARD 0xc30A
|
||||
|
||||
#endif /* MIPS_SN_IOC3_H */
|
||||
|
|
|
@ -889,10 +889,6 @@ typedef union {
|
|||
extern lboard_t *find_lboard(lboard_t *start, unsigned char type);
|
||||
extern klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char type);
|
||||
extern klinfo_t *find_first_component(lboard_t *brd, unsigned char type);
|
||||
extern klcpu_t *nasid_slice_to_cpuinfo(nasid_t, int);
|
||||
extern lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_class);
|
||||
|
||||
|
||||
extern klcpu_t *sn_get_cpuinfo(cpuid_t cpu);
|
||||
|
||||
#endif /* _ASM_SN_KLCONFIG_H */
|
||||
|
|
|
@ -1,201 +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.
|
||||
*
|
||||
* Derived from IRIX <sys/SN/kldir.h>, revision 1.21.
|
||||
*
|
||||
* Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
|
||||
* Copyright (C) 1999, 2000 by Ralf Baechle
|
||||
*/
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _ASM_SN_KLDIR_H
|
||||
#define _ASM_SN_KLDIR_H
|
||||
|
||||
|
||||
/*
|
||||
* The kldir memory area resides at a fixed place in each node's memory and
|
||||
* provides pointers to most other IP27 memory areas. This allows us to
|
||||
* resize and/or relocate memory areas at a later time without breaking all
|
||||
* firmware and kernels that use them. Indices in the array are
|
||||
* permanently dedicated to areas listed below. Some memory areas (marked
|
||||
* below) reside at a permanently fixed location, but are included in the
|
||||
* directory for completeness.
|
||||
*/
|
||||
|
||||
#define KLDIR_MAGIC 0x434d5f53505f5357
|
||||
|
||||
/*
|
||||
* The upper portion of the memory map applies during boot
|
||||
* only and is overwritten by IRIX/SYMMON.
|
||||
*
|
||||
* MEMORY MAP PER NODE
|
||||
*
|
||||
* 0x2000000 (32M) +-----------------------------------------+
|
||||
* | IO6 BUFFERS FOR FLASH ENET IOC3 |
|
||||
* 0x1F80000 (31.5M) +-----------------------------------------+
|
||||
* | IO6 TEXT/DATA/BSS/stack |
|
||||
* 0x1C00000 (30M) +-----------------------------------------+
|
||||
* | IO6 PROM DEBUG TEXT/DATA/BSS/stack |
|
||||
* 0x0800000 (28M) +-----------------------------------------+
|
||||
* | IP27 PROM TEXT/DATA/BSS/stack |
|
||||
* 0x1B00000 (27M) +-----------------------------------------+
|
||||
* | IP27 CFG |
|
||||
* 0x1A00000 (26M) +-----------------------------------------+
|
||||
* | Graphics PROM |
|
||||
* 0x1800000 (24M) +-----------------------------------------+
|
||||
* | 3rd Party PROM drivers |
|
||||
* 0x1600000 (22M) +-----------------------------------------+
|
||||
* | |
|
||||
* | Free |
|
||||
* | |
|
||||
* +-----------------------------------------+
|
||||
* | UNIX DEBUG Version |
|
||||
* 0x190000 (2M--) +-----------------------------------------+
|
||||
* | SYMMON |
|
||||
* | (For UNIX Debug only) |
|
||||
* 0x34000 (208K) +-----------------------------------------+
|
||||
* | SYMMON STACK [NUM_CPU_PER_NODE] |
|
||||
* | (For UNIX Debug only) |
|
||||
* 0x25000 (148K) +-----------------------------------------+
|
||||
* | KLCONFIG - II (temp) |
|
||||
* | |
|
||||
* | ---------------------------- |
|
||||
* | |
|
||||
* | UNIX NON-DEBUG Version |
|
||||
* 0x19000 (100K) +-----------------------------------------+
|
||||
*
|
||||
*
|
||||
* The lower portion of the memory map contains information that is
|
||||
* permanent and is used by the IP27PROM, IO6PROM and IRIX.
|
||||
*
|
||||
* 0x19000 (100K) +-----------------------------------------+
|
||||
* | |
|
||||
* | PI Error Spools (32K) |
|
||||
* | |
|
||||
* 0x12000 (72K) +-----------------------------------------+
|
||||
* | Unused |
|
||||
* 0x11c00 (71K) +-----------------------------------------+
|
||||
* | CPU 1 NMI Eframe area |
|
||||
* 0x11a00 (70.5K) +-----------------------------------------+
|
||||
* | CPU 0 NMI Eframe area |
|
||||
* 0x11800 (70K) +-----------------------------------------+
|
||||
* | CPU 1 NMI Register save area |
|
||||
* 0x11600 (69.5K) +-----------------------------------------+
|
||||
* | CPU 0 NMI Register save area |
|
||||
* 0x11400 (69K) +-----------------------------------------+
|
||||
* | GDA (1k) |
|
||||
* 0x11000 (68K) +-----------------------------------------+
|
||||
* | Early cache Exception stack |
|
||||
* | and/or |
|
||||
* | kernel/io6prom nmi registers |
|
||||
* 0x10800 (66k) +-----------------------------------------+
|
||||
* | cache error eframe |
|
||||
* 0x10400 (65K) +-----------------------------------------+
|
||||
* | Exception Handlers (UALIAS copy) |
|
||||
* 0x10000 (64K) +-----------------------------------------+
|
||||
* | |
|
||||
* | |
|
||||
* | KLCONFIG - I (permanent) (48K) |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* 0x4000 (16K) +-----------------------------------------+
|
||||
* | NMI Handler (Protected Page) |
|
||||
* 0x3000 (12K) +-----------------------------------------+
|
||||
* | ARCS PVECTORS (master node only) |
|
||||
* 0x2c00 (11K) +-----------------------------------------+
|
||||
* | ARCS TVECTORS (master node only) |
|
||||
* 0x2800 (10K) +-----------------------------------------+
|
||||
* | LAUNCH [NUM_CPU] |
|
||||
* 0x2400 (9K) +-----------------------------------------+
|
||||
* | Low memory directory (KLDIR) |
|
||||
* 0x2000 (8K) +-----------------------------------------+
|
||||
* | ARCS SPB (1K) |
|
||||
* 0x1000 (4K) +-----------------------------------------+
|
||||
* | Early cache Exception stack |
|
||||
* | and/or |
|
||||
* | kernel/io6prom nmi registers |
|
||||
* 0x800 (2k) +-----------------------------------------+
|
||||
* | cache error eframe |
|
||||
* 0x400 (1K) +-----------------------------------------+
|
||||
* | Exception Handlers |
|
||||
* 0x0 (0K) +-----------------------------------------+
|
||||
*/
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#define KLDIR_OFF_MAGIC 0x00
|
||||
#define KLDIR_OFF_OFFSET 0x08
|
||||
#define KLDIR_OFF_POINTER 0x10
|
||||
#define KLDIR_OFF_SIZE 0x18
|
||||
#define KLDIR_OFF_COUNT 0x20
|
||||
#define KLDIR_OFF_STRIDE 0x28
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* This is defined here because IP27_SYMMON_STK_SIZE must be at least what
|
||||
* we define here. Since it's set up in the prom. We can't redefine it later
|
||||
* and expect more space to be allocated. The way to find out the true size
|
||||
* of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE
|
||||
* for a particular node.
|
||||
*/
|
||||
#define SYMMON_STACK_SIZE 0x8000
|
||||
|
||||
#if defined(PROM)
|
||||
|
||||
/*
|
||||
* These defines are prom version dependent. No code other than the IP27
|
||||
* prom should attempt to use these values.
|
||||
*/
|
||||
#define IP27_LAUNCH_OFFSET 0x2400
|
||||
#define IP27_LAUNCH_SIZE 0x400
|
||||
#define IP27_LAUNCH_COUNT 2
|
||||
#define IP27_LAUNCH_STRIDE 0x200
|
||||
|
||||
#define IP27_KLCONFIG_OFFSET 0x4000
|
||||
#define IP27_KLCONFIG_SIZE 0xc000
|
||||
#define IP27_KLCONFIG_COUNT 1
|
||||
#define IP27_KLCONFIG_STRIDE 0
|
||||
|
||||
#define IP27_NMI_OFFSET 0x3000
|
||||
#define IP27_NMI_SIZE 0x40
|
||||
#define IP27_NMI_COUNT 2
|
||||
#define IP27_NMI_STRIDE 0x40
|
||||
|
||||
#define IP27_PI_ERROR_OFFSET 0x12000
|
||||
#define IP27_PI_ERROR_SIZE 0x4000
|
||||
#define IP27_PI_ERROR_COUNT 1
|
||||
#define IP27_PI_ERROR_STRIDE 0
|
||||
|
||||
#define IP27_SYMMON_STK_OFFSET 0x25000
|
||||
#define IP27_SYMMON_STK_SIZE 0xe000
|
||||
#define IP27_SYMMON_STK_COUNT 2
|
||||
/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */
|
||||
#define IP27_SYMMON_STK_STRIDE 0x7000
|
||||
|
||||
#define IP27_FREEMEM_OFFSET 0x19000
|
||||
#define IP27_FREEMEM_SIZE -1
|
||||
#define IP27_FREEMEM_COUNT 1
|
||||
#define IP27_FREEMEM_STRIDE 0
|
||||
|
||||
#endif /* PROM */
|
||||
/*
|
||||
* There will be only one of these in a partition so the IO6 must set it up.
|
||||
*/
|
||||
#define IO6_GDA_OFFSET 0x11000
|
||||
#define IO6_GDA_SIZE 0x400
|
||||
#define IO6_GDA_COUNT 1
|
||||
#define IO6_GDA_STRIDE 0
|
||||
|
||||
/*
|
||||
* save area of kernel nmi regs in the prom format
|
||||
*/
|
||||
#define IP27_NMI_KREGS_OFFSET 0x11400
|
||||
#define IP27_NMI_KREGS_CPU_SIZE 0x200
|
||||
/*
|
||||
* save area of kernel nmi regs in eframe format
|
||||
*/
|
||||
#define IP27_NMI_EFRAME_OFFSET 0x11800
|
||||
#define IP27_NMI_EFRAME_SIZE 0x200
|
||||
|
||||
#define KLDIR_ENT_SIZE 0x40
|
||||
#define KLDIR_MAX_ENTRIES (0x400 / 0x40)
|
||||
|
@ -214,4 +29,8 @@ typedef struct kldir_ent_s {
|
|||
} kldir_ent_t;
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#ifdef CONFIG_SGI_IP27
|
||||
#include <asm/sn/sn0/kldir.h>
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_SN_KLDIR_H */
|
||||
|
|
|
@ -37,4 +37,26 @@
|
|||
#define UATTR_MSPEC 2
|
||||
#define UATTR_UNCAC 3
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
/*
|
||||
* Returns the local nasid into res.
|
||||
*/
|
||||
.macro GET_NASID_ASM res
|
||||
dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID)
|
||||
ld \res, (\res)
|
||||
and \res, NSRI_NODEID_MASK
|
||||
dsrl \res, NSRI_NODEID_SHFT
|
||||
.endm
|
||||
#else
|
||||
|
||||
/*
|
||||
* get_nasid() returns the physical node id number of the caller.
|
||||
*/
|
||||
static inline nasid_t get_nasid(void)
|
||||
{
|
||||
return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
|
||||
>> NSRI_NODEID_SHFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_SN_SN0_HUB_H */
|
||||
|
|
|
@ -250,6 +250,14 @@ typedef union hubni_port_error_u {
|
|||
#define NI_LLP_CB_MAX 0xff
|
||||
#define NI_LLP_SN_MAX 0xff
|
||||
|
||||
static inline int get_region_shift(void)
|
||||
{
|
||||
if (LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK)
|
||||
return NASID_TO_FINEREG_SHFT;
|
||||
|
||||
return NASID_TO_COARSEREG_SHFT;
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_SGI_SN0_HUBNI_H */
|
||||
|
|
|
@ -1,85 +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.
|
||||
*
|
||||
* Derived from IRIX <sys/SN/SN0/IP27.h>.
|
||||
*
|
||||
* Copyright (C) 1992 - 1997, 1999 Silicon Graphics, Inc.
|
||||
* Copyright (C) 1999, 2006 by Ralf Baechle
|
||||
*/
|
||||
#ifndef _ASM_SN_SN0_IP27_H
|
||||
#define _ASM_SN_SN0_IP27_H
|
||||
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
/*
|
||||
* Simple definitions for the masks which remove SW bits from pte.
|
||||
*/
|
||||
|
||||
#define TLBLO_HWBITSHIFT 0 /* Shift value, for masking */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define CAUSE_BERRINTR IE_IRQ5
|
||||
|
||||
#define ECCF_CACHE_ERR 0
|
||||
#define ECCF_TAGLO 1
|
||||
#define ECCF_ECC 2
|
||||
#define ECCF_ERROREPC 3
|
||||
#define ECCF_PADDR 4
|
||||
#define ECCF_SIZE (5 * sizeof(long))
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* KL_GET_CPUNUM (similar to EV_GET_SPNUM for EVEREST platform) reads
|
||||
* the processor number of the calling processor. The proc parameters
|
||||
* must be a register.
|
||||
*/
|
||||
#define KL_GET_CPUNUM(proc) \
|
||||
dli proc, LOCAL_HUB(0); \
|
||||
ld proc, PI_CPU_NUM(proc)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* R10000 status register interrupt bit mask usage for IP27.
|
||||
*/
|
||||
#define SRB_SWTIMO IE_SW0 /* 0x0100 */
|
||||
#define SRB_NET IE_SW1 /* 0x0200 */
|
||||
#define SRB_DEV0 IE_IRQ0 /* 0x0400 */
|
||||
#define SRB_DEV1 IE_IRQ1 /* 0x0800 */
|
||||
#define SRB_TIMOCLK IE_IRQ2 /* 0x1000 */
|
||||
#define SRB_PROFCLK IE_IRQ3 /* 0x2000 */
|
||||
#define SRB_ERR IE_IRQ4 /* 0x4000 */
|
||||
#define SRB_SCHEDCLK IE_IRQ5 /* 0x8000 */
|
||||
|
||||
#define SR_IBIT_HI SRB_DEV0
|
||||
#define SR_IBIT_PROF SRB_PROFCLK
|
||||
|
||||
#define SRB_SWTIMO_IDX 0
|
||||
#define SRB_NET_IDX 1
|
||||
#define SRB_DEV0_IDX 2
|
||||
#define SRB_DEV1_IDX 3
|
||||
#define SRB_TIMOCLK_IDX 4
|
||||
#define SRB_PROFCLK_IDX 5
|
||||
#define SRB_ERR_IDX 6
|
||||
#define SRB_SCHEDCLK_IDX 7
|
||||
|
||||
#define NUM_CAUSE_INTRS 8
|
||||
|
||||
#define SCACHE_LINESIZE 128
|
||||
#define SCACHE_LINEMASK (SCACHE_LINESIZE - 1)
|
||||
|
||||
#include <asm/sn/addrs.h>
|
||||
|
||||
#define LED_CYCLE_MASK 0x0f
|
||||
#define LED_CYCLE_SHFT 4
|
||||
|
||||
#define SEND_NMI(_nasid, _slice) \
|
||||
REMOTE_HUB_S((_nasid), (PI_NMI_A + ((_slice) * PI_NMI_OFFSET)), 1)
|
||||
|
||||
#endif /* _ASM_SN_SN0_IP27_H */
|
|
@ -0,0 +1,186 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Derived from IRIX <sys/SN/kldir.h>, revision 1.21.
|
||||
*
|
||||
* Copyright (C) 1992 - 1997, 1999, 2000 Silicon Graphics, Inc.
|
||||
* Copyright (C) 1999, 2000 by Ralf Baechle
|
||||
*/
|
||||
#ifndef _ASM_SN_SN0_KLDIR_H
|
||||
#define _ASM_SN_SN0_KLDIR_H
|
||||
|
||||
|
||||
/*
|
||||
* The kldir memory area resides at a fixed place in each node's memory and
|
||||
* provides pointers to most other IP27 memory areas. This allows us to
|
||||
* resize and/or relocate memory areas at a later time without breaking all
|
||||
* firmware and kernels that use them. Indices in the array are
|
||||
* permanently dedicated to areas listed below. Some memory areas (marked
|
||||
* below) reside at a permanently fixed location, but are included in the
|
||||
* directory for completeness.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The upper portion of the memory map applies during boot
|
||||
* only and is overwritten by IRIX/SYMMON.
|
||||
*
|
||||
* MEMORY MAP PER NODE
|
||||
*
|
||||
* 0x2000000 (32M) +-----------------------------------------+
|
||||
* | IO6 BUFFERS FOR FLASH ENET IOC3 |
|
||||
* 0x1F80000 (31.5M) +-----------------------------------------+
|
||||
* | IO6 TEXT/DATA/BSS/stack |
|
||||
* 0x1C00000 (30M) +-----------------------------------------+
|
||||
* | IO6 PROM DEBUG TEXT/DATA/BSS/stack |
|
||||
* 0x0800000 (28M) +-----------------------------------------+
|
||||
* | IP27 PROM TEXT/DATA/BSS/stack |
|
||||
* 0x1B00000 (27M) +-----------------------------------------+
|
||||
* | IP27 CFG |
|
||||
* 0x1A00000 (26M) +-----------------------------------------+
|
||||
* | Graphics PROM |
|
||||
* 0x1800000 (24M) +-----------------------------------------+
|
||||
* | 3rd Party PROM drivers |
|
||||
* 0x1600000 (22M) +-----------------------------------------+
|
||||
* | |
|
||||
* | Free |
|
||||
* | |
|
||||
* +-----------------------------------------+
|
||||
* | UNIX DEBUG Version |
|
||||
* 0x190000 (2M--) +-----------------------------------------+
|
||||
* | SYMMON |
|
||||
* | (For UNIX Debug only) |
|
||||
* 0x34000 (208K) +-----------------------------------------+
|
||||
* | SYMMON STACK [NUM_CPU_PER_NODE] |
|
||||
* | (For UNIX Debug only) |
|
||||
* 0x25000 (148K) +-----------------------------------------+
|
||||
* | KLCONFIG - II (temp) |
|
||||
* | |
|
||||
* | ---------------------------- |
|
||||
* | |
|
||||
* | UNIX NON-DEBUG Version |
|
||||
* 0x19000 (100K) +-----------------------------------------+
|
||||
*
|
||||
*
|
||||
* The lower portion of the memory map contains information that is
|
||||
* permanent and is used by the IP27PROM, IO6PROM and IRIX.
|
||||
*
|
||||
* 0x19000 (100K) +-----------------------------------------+
|
||||
* | |
|
||||
* | PI Error Spools (32K) |
|
||||
* | |
|
||||
* 0x12000 (72K) +-----------------------------------------+
|
||||
* | Unused |
|
||||
* 0x11c00 (71K) +-----------------------------------------+
|
||||
* | CPU 1 NMI Eframe area |
|
||||
* 0x11a00 (70.5K) +-----------------------------------------+
|
||||
* | CPU 0 NMI Eframe area |
|
||||
* 0x11800 (70K) +-----------------------------------------+
|
||||
* | CPU 1 NMI Register save area |
|
||||
* 0x11600 (69.5K) +-----------------------------------------+
|
||||
* | CPU 0 NMI Register save area |
|
||||
* 0x11400 (69K) +-----------------------------------------+
|
||||
* | GDA (1k) |
|
||||
* 0x11000 (68K) +-----------------------------------------+
|
||||
* | Early cache Exception stack |
|
||||
* | and/or |
|
||||
* | kernel/io6prom nmi registers |
|
||||
* 0x10800 (66k) +-----------------------------------------+
|
||||
* | cache error eframe |
|
||||
* 0x10400 (65K) +-----------------------------------------+
|
||||
* | Exception Handlers (UALIAS copy) |
|
||||
* 0x10000 (64K) +-----------------------------------------+
|
||||
* | |
|
||||
* | |
|
||||
* | KLCONFIG - I (permanent) (48K) |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* 0x4000 (16K) +-----------------------------------------+
|
||||
* | NMI Handler (Protected Page) |
|
||||
* 0x3000 (12K) +-----------------------------------------+
|
||||
* | ARCS PVECTORS (master node only) |
|
||||
* 0x2c00 (11K) +-----------------------------------------+
|
||||
* | ARCS TVECTORS (master node only) |
|
||||
* 0x2800 (10K) +-----------------------------------------+
|
||||
* | LAUNCH [NUM_CPU] |
|
||||
* 0x2400 (9K) +-----------------------------------------+
|
||||
* | Low memory directory (KLDIR) |
|
||||
* 0x2000 (8K) +-----------------------------------------+
|
||||
* | ARCS SPB (1K) |
|
||||
* 0x1000 (4K) +-----------------------------------------+
|
||||
* | Early cache Exception stack |
|
||||
* | and/or |
|
||||
* | kernel/io6prom nmi registers |
|
||||
* 0x800 (2k) +-----------------------------------------+
|
||||
* | cache error eframe |
|
||||
* 0x400 (1K) +-----------------------------------------+
|
||||
* | Exception Handlers |
|
||||
* 0x0 (0K) +-----------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is defined here because IP27_SYMMON_STK_SIZE must be at least what
|
||||
* we define here. Since it's set up in the prom. We can't redefine it later
|
||||
* and expect more space to be allocated. The way to find out the true size
|
||||
* of the symmon stacks is to divide SYMMON_STK_SIZE by SYMMON_STK_STRIDE
|
||||
* for a particular node.
|
||||
*/
|
||||
#define SYMMON_STACK_SIZE 0x8000
|
||||
|
||||
#if defined(PROM)
|
||||
|
||||
/*
|
||||
* These defines are prom version dependent. No code other than the IP27
|
||||
* prom should attempt to use these values.
|
||||
*/
|
||||
#define IP27_LAUNCH_OFFSET 0x2400
|
||||
#define IP27_LAUNCH_SIZE 0x400
|
||||
#define IP27_LAUNCH_COUNT 2
|
||||
#define IP27_LAUNCH_STRIDE 0x200
|
||||
|
||||
#define IP27_KLCONFIG_OFFSET 0x4000
|
||||
#define IP27_KLCONFIG_SIZE 0xc000
|
||||
#define IP27_KLCONFIG_COUNT 1
|
||||
#define IP27_KLCONFIG_STRIDE 0
|
||||
|
||||
#define IP27_NMI_OFFSET 0x3000
|
||||
#define IP27_NMI_SIZE 0x40
|
||||
#define IP27_NMI_COUNT 2
|
||||
#define IP27_NMI_STRIDE 0x40
|
||||
|
||||
#define IP27_PI_ERROR_OFFSET 0x12000
|
||||
#define IP27_PI_ERROR_SIZE 0x4000
|
||||
#define IP27_PI_ERROR_COUNT 1
|
||||
#define IP27_PI_ERROR_STRIDE 0
|
||||
|
||||
#define IP27_SYMMON_STK_OFFSET 0x25000
|
||||
#define IP27_SYMMON_STK_SIZE 0xe000
|
||||
#define IP27_SYMMON_STK_COUNT 2
|
||||
/* IP27_SYMMON_STK_STRIDE must be >= SYMMON_STACK_SIZE */
|
||||
#define IP27_SYMMON_STK_STRIDE 0x7000
|
||||
|
||||
#define IP27_FREEMEM_OFFSET 0x19000
|
||||
#define IP27_FREEMEM_SIZE -1
|
||||
#define IP27_FREEMEM_COUNT 1
|
||||
#define IP27_FREEMEM_STRIDE 0
|
||||
|
||||
#endif /* PROM */
|
||||
/*
|
||||
* There will be only one of these in a partition so the IO6 must set it up.
|
||||
*/
|
||||
#define IO6_GDA_OFFSET 0x11000
|
||||
#define IO6_GDA_SIZE 0x400
|
||||
#define IO6_GDA_COUNT 1
|
||||
#define IO6_GDA_STRIDE 0
|
||||
|
||||
/*
|
||||
* save area of kernel nmi regs in the prom format
|
||||
*/
|
||||
#define IP27_NMI_KREGS_OFFSET 0x11400
|
||||
#define IP27_NMI_KREGS_CPU_SIZE 0x200
|
||||
/*
|
||||
* save area of kernel nmi regs in eframe format
|
||||
*/
|
||||
#define IP27_NMI_EFRAME_OFFSET 0x11800
|
||||
#define IP27_NMI_EFRAME_SIZE 0x200
|
||||
|
||||
#endif /* _ASM_SN_SN0_KLDIR_H */
|
|
@ -1,19 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __ASM_SN_SN_PRIVATE_H
|
||||
#define __ASM_SN_SN_PRIVATE_H
|
||||
|
||||
#include <asm/sn/types.h>
|
||||
|
||||
extern nasid_t master_nasid;
|
||||
|
||||
extern void cpu_node_probe(void);
|
||||
extern void hub_rtc_init(nasid_t nasid);
|
||||
extern void cpu_time_init(void);
|
||||
extern void per_cpu_init(void);
|
||||
extern void install_cpu_nmi_handler(int slice);
|
||||
extern void install_ipi(void);
|
||||
extern void setup_replication_mask(void);
|
||||
extern void replicate_kernel_text(void);
|
||||
extern unsigned long node_getfirstfree(nasid_t nasid);
|
||||
|
||||
#endif /* __ASM_SN_SN_PRIVATE_H */
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
typedef unsigned long cpuid_t;
|
||||
typedef signed short nasid_t; /* node id in numa-as-id space */
|
||||
typedef signed char partid_t; /* partition ID type */
|
||||
|
@ -18,4 +20,6 @@ typedef signed short moduleid_t; /* user-visible module number type */
|
|||
|
||||
typedef dev_t vertex_hdl_t; /* hardware graph vertex handle */
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_SN_TYPES_H */
|
||||
|
|
|
@ -16,6 +16,10 @@ config JZ4780_CI20
|
|||
bool "MIPS Creator CI20"
|
||||
select MACH_JZ4780
|
||||
|
||||
config X1000_CU1000_NEO
|
||||
bool "YSH & ATIL CU1000 Module with Neo backplane"
|
||||
select MACH_X1000
|
||||
|
||||
endchoice
|
||||
|
||||
config MACH_JZ4740
|
||||
|
@ -33,3 +37,9 @@ config MACH_JZ4780
|
|||
select MIPS_CPU_SCACHE
|
||||
select SYS_HAS_CPU_MIPS32_R2
|
||||
select SYS_SUPPORTS_HIGHMEM
|
||||
|
||||
config MACH_X1000
|
||||
bool
|
||||
select MIPS_CPU_SCACHE
|
||||
select SYS_HAS_CPU_MIPS32_R2
|
||||
select SYS_SUPPORTS_HIGHMEM
|
||||
|
|
|
@ -44,6 +44,8 @@ static void __init jz4740_detect_mem(void)
|
|||
|
||||
static unsigned long __init get_board_mach_type(const void *fdt)
|
||||
{
|
||||
if (!fdt_node_check_compatible(fdt, 0, "ingenic,x1830"))
|
||||
return MACH_INGENIC_X1830;
|
||||
if (!fdt_node_check_compatible(fdt, 0, "ingenic,x1000"))
|
||||
return MACH_INGENIC_X1000;
|
||||
if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780"))
|
||||
|
@ -86,6 +88,8 @@ void __init device_tree_init(void)
|
|||
const char *get_system_type(void)
|
||||
{
|
||||
switch (mips_machtype) {
|
||||
case MACH_INGENIC_X1830:
|
||||
return "X1830";
|
||||
case MACH_INGENIC_X1000:
|
||||
return "X1000";
|
||||
case MACH_INGENIC_JZ4780:
|
||||
|
|
|
@ -102,7 +102,12 @@ static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
|
|||
if (fir & MIPS_FPIR_HAS2008) {
|
||||
fcsr = read_32bit_cp1_register(CP1_STATUS);
|
||||
|
||||
fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
|
||||
/*
|
||||
* MAC2008 toolchain never landed in real world, so we're only
|
||||
* testing wether it can be disabled and don't try to enabled
|
||||
* it.
|
||||
*/
|
||||
fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008 | FPU_CSR_MAC2008);
|
||||
write_32bit_cp1_register(CP1_STATUS, fcsr0);
|
||||
fcsr0 = read_32bit_cp1_register(CP1_STATUS);
|
||||
|
||||
|
@ -112,6 +117,15 @@ static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
|
|||
|
||||
write_32bit_cp1_register(CP1_STATUS, fcsr);
|
||||
|
||||
if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2)) {
|
||||
/*
|
||||
* The bit for MAC2008 might be reused by R6 in future,
|
||||
* so we only test for R2-R5.
|
||||
*/
|
||||
if (fcsr0 & FPU_CSR_MAC2008)
|
||||
c->options |= MIPS_CPU_MAC_2008_ONLY;
|
||||
}
|
||||
|
||||
if (!(fcsr0 & FPU_CSR_NAN2008))
|
||||
c->options |= MIPS_CPU_NAN_LEGACY;
|
||||
if (fcsr1 & FPU_CSR_NAN2008)
|
||||
|
@ -1960,10 +1974,8 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
|
|||
BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
|
||||
|
||||
switch (c->processor_id & PRID_IMP_MASK) {
|
||||
case PRID_IMP_XBURST:
|
||||
c->cputype = CPU_XBURST;
|
||||
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
|
||||
__cpu_name[cpu] = "Ingenic JZRISC";
|
||||
case PRID_IMP_XBURST_REV1:
|
||||
|
||||
/*
|
||||
* The XBurst core by default attempts to avoid branch target
|
||||
* buffer lookups by detecting & special casing loops. This
|
||||
|
@ -1971,36 +1983,45 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
|
|||
* Set cp0 config7 bit 4 to disable this feature.
|
||||
*/
|
||||
set_c0_config7(MIPS_CONF7_BTB_LOOP_EN);
|
||||
|
||||
switch (c->processor_id & PRID_COMP_MASK) {
|
||||
|
||||
/*
|
||||
* The config0 register in the XBurst CPUs with a processor ID of
|
||||
* PRID_COMP_INGENIC_D0 report themselves as MIPS32r2 compatible,
|
||||
* but they don't actually support this ISA.
|
||||
*/
|
||||
case PRID_COMP_INGENIC_D0:
|
||||
c->isa_level &= ~MIPS_CPU_ISA_M32R2;
|
||||
break;
|
||||
|
||||
/*
|
||||
* The config0 register in the XBurst CPUs with a processor ID of
|
||||
* PRID_COMP_INGENIC_D1 has an abandoned huge page tlb mode, this
|
||||
* mode is not compatible with the MIPS standard, it will cause
|
||||
* tlbmiss and into an infinite loop (line 21 in the tlb-funcs.S)
|
||||
* when starting the init process. After chip reset, the default
|
||||
* is HPTLB mode, Write 0xa9000000 to cp0 register 5 sel 4 to
|
||||
* switch back to VTLB mode to prevent getting stuck.
|
||||
*/
|
||||
case PRID_COMP_INGENIC_D1:
|
||||
write_c0_page_ctrl(XBURST_PAGECTRL_HPTLB_DIS);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* fall-through */
|
||||
case PRID_IMP_XBURST_REV2:
|
||||
c->cputype = CPU_XBURST;
|
||||
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
|
||||
__cpu_name[cpu] = "Ingenic XBurst";
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Unknown Ingenic Processor ID!");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c->processor_id & PRID_COMP_MASK) {
|
||||
/*
|
||||
* The config0 register in the XBurst CPUs with a processor ID of
|
||||
* PRID_COMP_INGENIC_D1 has an abandoned huge page tlb mode, this
|
||||
* mode is not compatible with the MIPS standard, it will cause
|
||||
* tlbmiss and into an infinite loop (line 21 in the tlb-funcs.S)
|
||||
* when starting the init process. After chip reset, the default
|
||||
* is HPTLB mode, Write 0xa9000000 to cp0 register 5 sel 4 to
|
||||
* switch back to VTLB mode to prevent getting stuck.
|
||||
*/
|
||||
case PRID_COMP_INGENIC_D1:
|
||||
write_c0_page_ctrl(XBURST_PAGECTRL_HPTLB_DIS);
|
||||
break;
|
||||
/*
|
||||
* The config0 register in the XBurst CPUs with a processor ID of
|
||||
* PRID_COMP_INGENIC_D0 report themselves as MIPS32r2 compatible,
|
||||
* but they don't actually support this ISA.
|
||||
*/
|
||||
case PRID_COMP_INGENIC_D0:
|
||||
c->isa_level &= ~MIPS_CPU_ISA_M32R2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
|
||||
|
|
|
@ -515,8 +515,7 @@ static void __init request_crashkernel(struct resource *res)
|
|||
ret = request_resource(res, &crashk_res);
|
||||
if (!ret)
|
||||
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel\n",
|
||||
(unsigned long)((crashk_res.end -
|
||||
crashk_res.start + 1) >> 20),
|
||||
(unsigned long)(resource_size(&crashk_res) >> 20),
|
||||
(unsigned long)(crashk_res.start >> 20));
|
||||
}
|
||||
#else /* !defined(CONFIG_KEXEC) */
|
||||
|
@ -698,8 +697,7 @@ static void __init arch_mem_init(char **cmdline_p)
|
|||
mips_parse_crashkernel();
|
||||
#ifdef CONFIG_KEXEC
|
||||
if (crashk_res.start != crashk_res.end)
|
||||
memblock_reserve(crashk_res.start,
|
||||
crashk_res.end - crashk_res.start + 1);
|
||||
memblock_reserve(crashk_res.start, resource_size(&crashk_res));
|
||||
#endif
|
||||
device_tree_init();
|
||||
sparse_init();
|
||||
|
|
|
@ -90,6 +90,9 @@ void synchronise_count_master(int cpu)
|
|||
void synchronise_count_slave(int cpu)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
/*
|
||||
* Not every cpu is online at the time this gets called,
|
||||
|
@ -113,5 +116,7 @@ void synchronise_count_slave(int cpu)
|
|||
}
|
||||
/* Arrange for an interrupt in a short while */
|
||||
write_c0_compare(read_c0_count() + COUNTON);
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
#undef NR_LOOPS
|
||||
|
|
|
@ -18,7 +18,7 @@ quiet_cmd_syshdr = SYSHDR $@
|
|||
'$(syshdr_pfx_$(basetarget))' \
|
||||
'$(syshdr_offset_$(basetarget))'
|
||||
|
||||
quiet_cmd_sysnr = SYSNR $@
|
||||
quiet_cmd_sysnr = SYSNR $@
|
||||
cmd_sysnr = $(CONFIG_SHELL) '$(sysnr)' '$<' '$@' \
|
||||
'$(sysnr_abis_$(basetarget))' \
|
||||
'$(sysnr_pfx_$(basetarget))' \
|
||||
|
|
|
@ -131,7 +131,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
#define _LoadW(addr, value, res, type) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
|
@ -152,7 +152,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
/* For CPUs without lwl instruction */
|
||||
#define _LoadW(addr, value, res, type) \
|
||||
do { \
|
||||
|
@ -187,7 +187,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
|
||||
#define _LoadHWU(addr, value, res, type) \
|
||||
do { \
|
||||
|
@ -213,7 +213,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
#define _LoadWU(addr, value, res, type) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
|
@ -256,7 +256,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
/* For CPUs without lwl and ldl instructions */
|
||||
#define _LoadWU(addr, value, res, type) \
|
||||
do { \
|
||||
|
@ -340,7 +340,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
|
||||
|
||||
#define _StoreHW(addr, value, res, type) \
|
||||
|
@ -366,7 +366,7 @@ do { \
|
|||
: "r" (value), "r" (addr), "i" (-EFAULT));\
|
||||
} while(0)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
#define _StoreW(addr, value, res, type) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
|
@ -407,7 +407,7 @@ do { \
|
|||
: "r" (value), "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
#define _StoreW(addr, value, res, type) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
|
@ -483,7 +483,7 @@ do { \
|
|||
: "memory"); \
|
||||
} while(0)
|
||||
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
|
||||
#else /* __BIG_ENDIAN */
|
||||
|
||||
|
@ -509,7 +509,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
#define _LoadW(addr, value, res, type) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
|
@ -530,7 +530,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
/* For CPUs without lwl instruction */
|
||||
#define _LoadW(addr, value, res, type) \
|
||||
do { \
|
||||
|
@ -565,7 +565,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
|
||||
|
||||
#define _LoadHWU(addr, value, res, type) \
|
||||
|
@ -592,7 +592,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
#define _LoadWU(addr, value, res, type) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
|
@ -635,7 +635,7 @@ do { \
|
|||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
/* For CPUs without lwl and ldl instructions */
|
||||
#define _LoadWU(addr, value, res, type) \
|
||||
do { \
|
||||
|
@ -718,7 +718,7 @@ do { \
|
|||
: "=&r" (value), "=r" (res) \
|
||||
: "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
|
||||
#define _StoreHW(addr, value, res, type) \
|
||||
do { \
|
||||
|
@ -743,7 +743,7 @@ do { \
|
|||
: "r" (value), "r" (addr), "i" (-EFAULT));\
|
||||
} while(0)
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
#define _StoreW(addr, value, res, type) \
|
||||
do { \
|
||||
__asm__ __volatile__ ( \
|
||||
|
@ -784,7 +784,7 @@ do { \
|
|||
: "r" (value), "r" (addr), "i" (-EFAULT)); \
|
||||
} while(0)
|
||||
|
||||
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
/* For CPUs without swl and sdl instructions */
|
||||
#define _StoreW(addr, value, res, type) \
|
||||
do { \
|
||||
|
@ -861,7 +861,7 @@ do { \
|
|||
: "memory"); \
|
||||
} while(0)
|
||||
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
#endif
|
||||
|
||||
#define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel)
|
||||
|
|
|
@ -301,14 +301,14 @@
|
|||
and t0, src, ADDRMASK
|
||||
PREFS( 0, 2*32(src) )
|
||||
PREFD( 1, 2*32(dst) )
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
bnez t1, .Ldst_unaligned\@
|
||||
nop
|
||||
bnez t0, .Lsrc_unaligned_dst_aligned\@
|
||||
#else
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
or t0, t0, t1
|
||||
bnez t0, .Lcopy_unaligned_bytes\@
|
||||
#endif
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
/*
|
||||
* use delay slot for fall-through
|
||||
* src and dst are aligned; need to compute rem
|
||||
|
@ -389,7 +389,7 @@
|
|||
bne rem, len, 1b
|
||||
.set noreorder
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
/*
|
||||
* src and dst are aligned, need to copy rem bytes (rem < NBYTES)
|
||||
* A loop would do only a byte at a time with possible branch
|
||||
|
@ -491,7 +491,7 @@
|
|||
bne len, rem, 1b
|
||||
.set noreorder
|
||||
|
||||
#endif /* CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* !CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
.Lcopy_bytes_checklen\@:
|
||||
beqz len, .Ldone\@
|
||||
nop
|
||||
|
@ -520,7 +520,7 @@
|
|||
jr ra
|
||||
nop
|
||||
|
||||
#ifndef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifdef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
.Lcopy_unaligned_bytes\@:
|
||||
1:
|
||||
COPY_BYTE(0)
|
||||
|
@ -534,7 +534,7 @@
|
|||
ADD src, src, 8
|
||||
b 1b
|
||||
ADD dst, dst, 8
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
.if __memcpy == 1
|
||||
END(memcpy)
|
||||
.set __memcpy, 0
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
#endif
|
||||
.set reorder
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
R10KCBARRIER(0(ra))
|
||||
#ifdef __MIPSEB__
|
||||
EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */
|
||||
|
@ -125,7 +125,7 @@
|
|||
PTR_SUBU a0, t0 /* long align ptr */
|
||||
PTR_ADDU a2, t0 /* correct size */
|
||||
|
||||
#else /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
#define STORE_BYTE(N) \
|
||||
EX(sb, a1, N(a0), .Lbyte_fixup\@); \
|
||||
.set noreorder; \
|
||||
|
@ -150,7 +150,7 @@
|
|||
ori a0, STORMASK
|
||||
xori a0, STORMASK
|
||||
PTR_ADDIU a0, STORSIZE
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
1: ori t1, a2, 0x3f /* # of full blocks */
|
||||
xori t1, 0x3f
|
||||
andi t0, a2, 0x40-STORSIZE
|
||||
|
@ -185,7 +185,7 @@
|
|||
|
||||
.set noreorder
|
||||
beqz a2, 1f
|
||||
#ifdef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifndef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
PTR_ADDU a0, a2 /* What's left */
|
||||
.set reorder
|
||||
R10KCBARRIER(0(ra))
|
||||
|
@ -194,7 +194,7 @@
|
|||
#else
|
||||
EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@)
|
||||
#endif
|
||||
#else
|
||||
#else /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
PTR_SUBU t0, $0, a2
|
||||
.set reorder
|
||||
move a2, zero /* No remaining longs */
|
||||
|
@ -211,7 +211,7 @@
|
|||
EX(sb, a1, 6(a0), .Lbyte_fixup\@)
|
||||
#endif
|
||||
0:
|
||||
#endif
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
1: move a2, zero
|
||||
jr ra
|
||||
|
||||
|
@ -234,7 +234,7 @@
|
|||
.hidden __memset
|
||||
.endif
|
||||
|
||||
#ifndef CONFIG_CPU_HAS_LOAD_STORE_LR
|
||||
#ifdef CONFIG_CPU_NO_LOAD_STORE_LR
|
||||
.Lbyte_fixup\@:
|
||||
/*
|
||||
* unset_bytes = (#bytes - (#unaligned bytes)) - (-#unaligned bytes remaining + 1) + 1
|
||||
|
@ -243,7 +243,7 @@
|
|||
PTR_SUBU a2, t0
|
||||
PTR_ADDIU a2, 1
|
||||
jr ra
|
||||
#endif /* !CONFIG_CPU_HAS_LOAD_STORE_LR */
|
||||
#endif /* CONFIG_CPU_NO_LOAD_STORE_LR */
|
||||
|
||||
.Lfirst_fixup\@:
|
||||
/* unset_bytes already in a2 */
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <linux/export.h>
|
||||
#include <linux/stringify.h>
|
||||
|
||||
#if !defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_CPU_MIPSR6)
|
||||
#if !defined(CONFIG_CPU_HAS_DIEI)
|
||||
|
||||
/*
|
||||
* For cli() we have to insert nops to make sure that the new value
|
||||
|
@ -110,4 +110,4 @@ notrace void arch_local_irq_restore(unsigned long flags)
|
|||
}
|
||||
EXPORT_SYMBOL(arch_local_irq_restore);
|
||||
|
||||
#endif /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */
|
||||
#endif /* !CONFIG_CPU_HAS_DIEI */
|
||||
|
|
|
@ -91,7 +91,7 @@ static inline void stop_perf_counters(void)
|
|||
|
||||
static void loongson_suspend_enter(void)
|
||||
{
|
||||
static unsigned int cached_cpu_freq;
|
||||
unsigned int cached_cpu_freq;
|
||||
|
||||
/* setup wakeup events via enabling the IRQs */
|
||||
setup_wakeup_events();
|
||||
|
|
|
@ -75,7 +75,7 @@ static int __init compute_node_distance(int row, int col)
|
|||
loongson_sysconf.cores_per_package;
|
||||
|
||||
if (col == row)
|
||||
return 0;
|
||||
return LOCAL_DISTANCE;
|
||||
else if (package_row == package_col)
|
||||
return 40;
|
||||
else
|
||||
|
|
|
@ -27,6 +27,9 @@ static int __init loongson3_platform_init(void)
|
|||
continue;
|
||||
|
||||
pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
pdev->name = loongson_sysconf.sensors[i].name;
|
||||
pdev->id = loongson_sysconf.sensors[i].id;
|
||||
pdev->dev.platform_data = &loongson_sysconf.sensors[i];
|
||||
|
|
|
@ -1514,16 +1514,28 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
break;
|
||||
|
||||
case madd_s_op:
|
||||
handler = fpemu_sp_madd;
|
||||
if (cpu_has_mac2008_only)
|
||||
handler = ieee754sp_madd;
|
||||
else
|
||||
handler = fpemu_sp_madd;
|
||||
goto scoptop;
|
||||
case msub_s_op:
|
||||
handler = fpemu_sp_msub;
|
||||
if (cpu_has_mac2008_only)
|
||||
handler = ieee754sp_msub;
|
||||
else
|
||||
handler = fpemu_sp_msub;
|
||||
goto scoptop;
|
||||
case nmadd_s_op:
|
||||
handler = fpemu_sp_nmadd;
|
||||
if (cpu_has_mac2008_only)
|
||||
handler = ieee754sp_nmadd;
|
||||
else
|
||||
handler = fpemu_sp_nmadd;
|
||||
goto scoptop;
|
||||
case nmsub_s_op:
|
||||
handler = fpemu_sp_nmsub;
|
||||
if (cpu_has_mac2008_only)
|
||||
handler = ieee754sp_nmsub;
|
||||
else
|
||||
handler = fpemu_sp_nmsub;
|
||||
goto scoptop;
|
||||
|
||||
scoptop:
|
||||
|
@ -1610,15 +1622,27 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
|||
break;
|
||||
|
||||
case madd_d_op:
|
||||
handler = fpemu_dp_madd;
|
||||
if (cpu_has_mac2008_only)
|
||||
handler = ieee754dp_madd;
|
||||
else
|
||||
handler = fpemu_dp_madd;
|
||||
goto dcoptop;
|
||||
case msub_d_op:
|
||||
handler = fpemu_dp_msub;
|
||||
if (cpu_has_mac2008_only)
|
||||
handler = ieee754dp_msub;
|
||||
else
|
||||
handler = fpemu_dp_msub;
|
||||
goto dcoptop;
|
||||
case nmadd_d_op:
|
||||
handler = fpemu_dp_nmadd;
|
||||
if (cpu_has_mac2008_only)
|
||||
handler = ieee754dp_nmadd;
|
||||
else
|
||||
handler = fpemu_dp_nmadd;
|
||||
goto dcoptop;
|
||||
case nmsub_d_op:
|
||||
if (cpu_has_mac2008_only)
|
||||
handler = ieee754dp_nmsub;
|
||||
else
|
||||
handler = fpemu_dp_nmsub;
|
||||
goto dcoptop;
|
||||
|
||||
|
|
|
@ -68,6 +68,12 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
|
|||
|
||||
ieee754_clearcx();
|
||||
|
||||
rs = xs ^ ys;
|
||||
if (flags & MADDF_NEGATE_PRODUCT)
|
||||
rs ^= 1;
|
||||
if (flags & MADDF_NEGATE_ADDITION)
|
||||
zs ^= 1;
|
||||
|
||||
/*
|
||||
* Handle the cases when at least one of x, y or z is a NaN.
|
||||
* Order of precedence is sNaN, qNaN and z, x, y.
|
||||
|
@ -104,9 +110,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
|
|||
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
|
||||
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
|
||||
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
|
||||
if ((zc == IEEE754_CLASS_INF) &&
|
||||
((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
|
||||
((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
|
||||
if ((zc == IEEE754_CLASS_INF) && (zs != rs)) {
|
||||
/*
|
||||
* Cases of addition of infinities with opposite signs
|
||||
* or subtraction of infinities with same signs.
|
||||
|
@ -116,15 +120,10 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
|
|||
}
|
||||
/*
|
||||
* z is here either not an infinity, or an infinity having the
|
||||
* same sign as product (x*y) (in case of MADDF.D instruction)
|
||||
* or product -(x*y) (in MSUBF.D case). The result must be an
|
||||
* infinity, and its sign is determined only by the value of
|
||||
* (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
|
||||
* same sign as product (x*y). The result must be an infinity,
|
||||
* and its sign is determined only by the sign of product (x*y).
|
||||
*/
|
||||
if (flags & MADDF_NEGATE_PRODUCT)
|
||||
return ieee754dp_inf(1 ^ (xs ^ ys));
|
||||
else
|
||||
return ieee754dp_inf(xs ^ ys);
|
||||
return ieee754dp_inf(rs);
|
||||
|
||||
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
|
||||
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
|
||||
|
@ -135,10 +134,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
|
|||
return ieee754dp_inf(zs);
|
||||
if (zc == IEEE754_CLASS_ZERO) {
|
||||
/* Handle cases +0 + (-0) and similar ones. */
|
||||
if ((!(flags & MADDF_NEGATE_PRODUCT)
|
||||
&& (zs == (xs ^ ys))) ||
|
||||
((flags & MADDF_NEGATE_PRODUCT)
|
||||
&& (zs != (xs ^ ys))))
|
||||
if (zs == rs)
|
||||
/*
|
||||
* Cases of addition of zeros of equal signs
|
||||
* or subtraction of zeroes of opposite signs.
|
||||
|
@ -187,9 +183,6 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
|
|||
assert(ym & DP_HIDDEN_BIT);
|
||||
|
||||
re = xe + ye;
|
||||
rs = xs ^ ys;
|
||||
if (flags & MADDF_NEGATE_PRODUCT)
|
||||
rs ^= 1;
|
||||
|
||||
/* shunt to top of word */
|
||||
xm <<= 64 - (DP_FBITS + 1);
|
||||
|
@ -340,3 +333,27 @@ union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
|
|||
{
|
||||
return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
|
||||
}
|
||||
|
||||
union ieee754dp ieee754dp_madd(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y)
|
||||
{
|
||||
return _dp_maddf(z, x, y, 0);
|
||||
}
|
||||
|
||||
union ieee754dp ieee754dp_msub(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y)
|
||||
{
|
||||
return _dp_maddf(z, x, y, MADDF_NEGATE_ADDITION);
|
||||
}
|
||||
|
||||
union ieee754dp ieee754dp_nmadd(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y)
|
||||
{
|
||||
return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT|MADDF_NEGATE_ADDITION);
|
||||
}
|
||||
|
||||
union ieee754dp ieee754dp_nmsub(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y)
|
||||
{
|
||||
return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
|
||||
}
|
||||
|
|
|
@ -68,6 +68,14 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x,
|
|||
union ieee754sp y);
|
||||
union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y);
|
||||
union ieee754sp ieee754sp_madd(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y);
|
||||
union ieee754sp ieee754sp_msub(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y);
|
||||
union ieee754sp ieee754sp_nmadd(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y);
|
||||
union ieee754sp ieee754sp_nmsub(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y);
|
||||
int ieee754sp_2008class(union ieee754sp x);
|
||||
union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y);
|
||||
union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y);
|
||||
|
@ -103,6 +111,14 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
|
|||
union ieee754dp y);
|
||||
union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y);
|
||||
union ieee754dp ieee754dp_madd(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y);
|
||||
union ieee754dp ieee754dp_msub(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y);
|
||||
union ieee754dp ieee754dp_nmadd(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y);
|
||||
union ieee754dp ieee754dp_nmsub(union ieee754dp z, union ieee754dp x,
|
||||
union ieee754dp y);
|
||||
int ieee754dp_2008class(union ieee754dp x);
|
||||
union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y);
|
||||
union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
enum maddf_flags {
|
||||
MADDF_NEGATE_PRODUCT = 1 << 0,
|
||||
MADDF_NEGATE_ADDITION = 1 << 1,
|
||||
};
|
||||
|
||||
static inline void ieee754_clearcx(void)
|
||||
|
|
|
@ -36,6 +36,12 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
|
|||
|
||||
ieee754_clearcx();
|
||||
|
||||
rs = xs ^ ys;
|
||||
if (flags & MADDF_NEGATE_PRODUCT)
|
||||
rs ^= 1;
|
||||
if (flags & MADDF_NEGATE_ADDITION)
|
||||
zs ^= 1;
|
||||
|
||||
/*
|
||||
* Handle the cases when at least one of x, y or z is a NaN.
|
||||
* Order of precedence is sNaN, qNaN and z, x, y.
|
||||
|
@ -73,9 +79,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
|
|||
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
|
||||
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
|
||||
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
|
||||
if ((zc == IEEE754_CLASS_INF) &&
|
||||
((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
|
||||
((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
|
||||
if ((zc == IEEE754_CLASS_INF) && (zs != rs)) {
|
||||
/*
|
||||
* Cases of addition of infinities with opposite signs
|
||||
* or subtraction of infinities with same signs.
|
||||
|
@ -85,15 +89,10 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
|
|||
}
|
||||
/*
|
||||
* z is here either not an infinity, or an infinity having the
|
||||
* same sign as product (x*y) (in case of MADDF.D instruction)
|
||||
* or product -(x*y) (in MSUBF.D case). The result must be an
|
||||
* infinity, and its sign is determined only by the value of
|
||||
* (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
|
||||
* same sign as product (x*y). The result must be an infinity,
|
||||
* and its sign is determined only by the sign of product (x*y).
|
||||
*/
|
||||
if (flags & MADDF_NEGATE_PRODUCT)
|
||||
return ieee754sp_inf(1 ^ (xs ^ ys));
|
||||
else
|
||||
return ieee754sp_inf(xs ^ ys);
|
||||
return ieee754sp_inf(rs);
|
||||
|
||||
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
|
||||
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
|
||||
|
@ -104,10 +103,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
|
|||
return ieee754sp_inf(zs);
|
||||
if (zc == IEEE754_CLASS_ZERO) {
|
||||
/* Handle cases +0 + (-0) and similar ones. */
|
||||
if ((!(flags & MADDF_NEGATE_PRODUCT)
|
||||
&& (zs == (xs ^ ys))) ||
|
||||
((flags & MADDF_NEGATE_PRODUCT)
|
||||
&& (zs != (xs ^ ys))))
|
||||
if (zs == rs)
|
||||
/*
|
||||
* Cases of addition of zeros of equal signs
|
||||
* or subtraction of zeroes of opposite signs.
|
||||
|
@ -158,9 +154,6 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
|
|||
assert(ym & SP_HIDDEN_BIT);
|
||||
|
||||
re = xe + ye;
|
||||
rs = xs ^ ys;
|
||||
if (flags & MADDF_NEGATE_PRODUCT)
|
||||
rs ^= 1;
|
||||
|
||||
/* Multiple 24 bit xm and ym to give 48 bit results */
|
||||
rm64 = (uint64_t)xm * ym;
|
||||
|
@ -260,3 +253,27 @@ union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
|
|||
{
|
||||
return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
|
||||
}
|
||||
|
||||
union ieee754sp ieee754sp_madd(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y)
|
||||
{
|
||||
return _sp_maddf(z, x, y, 0);
|
||||
}
|
||||
|
||||
union ieee754sp ieee754sp_msub(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y)
|
||||
{
|
||||
return _sp_maddf(z, x, y, MADDF_NEGATE_ADDITION);
|
||||
}
|
||||
|
||||
union ieee754sp ieee754sp_nmadd(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y)
|
||||
{
|
||||
return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT|MADDF_NEGATE_ADDITION);
|
||||
}
|
||||
|
||||
union ieee754sp ieee754sp_nmsub(union ieee754sp z, union ieee754sp x,
|
||||
union ieee754sp y)
|
||||
{
|
||||
return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
|
||||
}
|
||||
|
|
|
@ -508,6 +508,51 @@ void __ref free_initmem(void)
|
|||
free_initmem_default(POISON_FREE_INITMEM);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA
|
||||
unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
|
||||
EXPORT_SYMBOL(__per_cpu_offset);
|
||||
|
||||
static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
|
||||
{
|
||||
return node_distance(cpu_to_node(from), cpu_to_node(to));
|
||||
}
|
||||
|
||||
static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size,
|
||||
size_t align)
|
||||
{
|
||||
return memblock_alloc_try_nid(size, align, __pa(MAX_DMA_ADDRESS),
|
||||
MEMBLOCK_ALLOC_ACCESSIBLE,
|
||||
cpu_to_node(cpu));
|
||||
}
|
||||
|
||||
static void __init pcpu_fc_free(void *ptr, size_t size)
|
||||
{
|
||||
memblock_free_early(__pa(ptr), size);
|
||||
}
|
||||
|
||||
void __init setup_per_cpu_areas(void)
|
||||
{
|
||||
unsigned long delta;
|
||||
unsigned int cpu;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Always reserve area for module percpu variables. That's
|
||||
* what the legacy allocator did.
|
||||
*/
|
||||
rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
|
||||
PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
|
||||
pcpu_cpu_distance,
|
||||
pcpu_fc_alloc, pcpu_fc_free);
|
||||
if (rc < 0)
|
||||
panic("Failed to initialize percpu areas.");
|
||||
|
||||
delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
|
||||
for_each_possible_cpu(cpu)
|
||||
__per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MIPS_PGD_C0_CONTEXT
|
||||
unsigned long pgd_current[NR_CPUS];
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# MIPS networking code
|
||||
|
||||
obj-$(CONFIG_MIPS_CBPF_JIT) += bpf_jit.o bpf_jit_asm.o
|
||||
obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* bpf_jib_asm.S: Packet/header access helper functions for MIPS/MIPS64 BPF
|
||||
* compiler.
|
||||
*
|
||||
* Copyright (C) 2015 Imagination Technologies Ltd.
|
||||
* Author: Markos Chandras <markos.chandras@imgtec.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <asm/asm.h>
|
||||
#include <asm/isa-rev.h>
|
||||
#include <asm/regdef.h>
|
||||
#include "bpf_jit.h"
|
||||
|
||||
/* ABI
|
||||
*
|
||||
* r_skb_hl skb header length
|
||||
* r_skb_data skb data
|
||||
* r_off(a1) offset register
|
||||
* r_A BPF register A
|
||||
* r_X PF register X
|
||||
* r_skb(a0) *skb
|
||||
* r_M *scratch memory
|
||||
* r_skb_le skb length
|
||||
* r_s0 Scratch register 0
|
||||
* r_s1 Scratch register 1
|
||||
*
|
||||
* On entry:
|
||||
* a0: *skb
|
||||
* a1: offset (imm or imm + X)
|
||||
*
|
||||
* All non-BPF-ABI registers are free for use. On return, we only
|
||||
* care about r_ret. The BPF-ABI registers are assumed to remain
|
||||
* unmodified during the entire filter operation.
|
||||
*/
|
||||
|
||||
#define skb a0
|
||||
#define offset a1
|
||||
#define SKF_LL_OFF (-0x200000) /* Can't include linux/filter.h in assembly */
|
||||
|
||||
/* We know better :) so prevent assembler reordering etc */
|
||||
.set noreorder
|
||||
|
||||
#define is_offset_negative(TYPE) \
|
||||
/* If offset is negative we have more work to do */ \
|
||||
slti t0, offset, 0; \
|
||||
bgtz t0, bpf_slow_path_##TYPE##_neg; \
|
||||
/* Be careful what follows in DS. */
|
||||
|
||||
#define is_offset_in_header(SIZE, TYPE) \
|
||||
/* Reading from header? */ \
|
||||
addiu $r_s0, $r_skb_hl, -SIZE; \
|
||||
slt t0, $r_s0, offset; \
|
||||
bgtz t0, bpf_slow_path_##TYPE; \
|
||||
|
||||
LEAF(sk_load_word)
|
||||
is_offset_negative(word)
|
||||
FEXPORT(sk_load_word_positive)
|
||||
is_offset_in_header(4, word)
|
||||
/* Offset within header boundaries */
|
||||
PTR_ADDU t1, $r_skb_data, offset
|
||||
.set reorder
|
||||
lw $r_A, 0(t1)
|
||||
.set noreorder
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
# if MIPS_ISA_REV >= 2
|
||||
wsbh t0, $r_A
|
||||
rotr $r_A, t0, 16
|
||||
# else
|
||||
sll t0, $r_A, 24
|
||||
srl t1, $r_A, 24
|
||||
srl t2, $r_A, 8
|
||||
or t0, t0, t1
|
||||
andi t2, t2, 0xff00
|
||||
andi t1, $r_A, 0xff00
|
||||
or t0, t0, t2
|
||||
sll t1, t1, 8
|
||||
or $r_A, t0, t1
|
||||
# endif
|
||||
#endif
|
||||
jr $r_ra
|
||||
move $r_ret, zero
|
||||
END(sk_load_word)
|
||||
|
||||
LEAF(sk_load_half)
|
||||
is_offset_negative(half)
|
||||
FEXPORT(sk_load_half_positive)
|
||||
is_offset_in_header(2, half)
|
||||
/* Offset within header boundaries */
|
||||
PTR_ADDU t1, $r_skb_data, offset
|
||||
lhu $r_A, 0(t1)
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
# if MIPS_ISA_REV >= 2
|
||||
wsbh $r_A, $r_A
|
||||
# else
|
||||
sll t0, $r_A, 8
|
||||
srl t1, $r_A, 8
|
||||
andi t0, t0, 0xff00
|
||||
or $r_A, t0, t1
|
||||
# endif
|
||||
#endif
|
||||
jr $r_ra
|
||||
move $r_ret, zero
|
||||
END(sk_load_half)
|
||||
|
||||
LEAF(sk_load_byte)
|
||||
is_offset_negative(byte)
|
||||
FEXPORT(sk_load_byte_positive)
|
||||
is_offset_in_header(1, byte)
|
||||
/* Offset within header boundaries */
|
||||
PTR_ADDU t1, $r_skb_data, offset
|
||||
lbu $r_A, 0(t1)
|
||||
jr $r_ra
|
||||
move $r_ret, zero
|
||||
END(sk_load_byte)
|
||||
|
||||
/*
|
||||
* call skb_copy_bits:
|
||||
* (prototype in linux/skbuff.h)
|
||||
*
|
||||
* int skb_copy_bits(sk_buff *skb, int offset, void *to, int len)
|
||||
*
|
||||
* o32 mandates we leave 4 spaces for argument registers in case
|
||||
* the callee needs to use them. Even though we don't care about
|
||||
* the argument registers ourselves, we need to allocate that space
|
||||
* to remain ABI compliant since the callee may want to use that space.
|
||||
* We also allocate 2 more spaces for $r_ra and our return register (*to).
|
||||
*
|
||||
* n64 is a bit different. The *caller* will allocate the space to preserve
|
||||
* the arguments. So in 64-bit kernels, we allocate the 4-arg space for no
|
||||
* good reason but it does not matter that much really.
|
||||
*
|
||||
* (void *to) is returned in r_s0
|
||||
*
|
||||
*/
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
#define DS_OFFSET(SIZE) (4 * SZREG)
|
||||
#else
|
||||
#define DS_OFFSET(SIZE) ((4 * SZREG) + (4 - SIZE))
|
||||
#endif
|
||||
#define bpf_slow_path_common(SIZE) \
|
||||
/* Quick check. Are we within reasonable boundaries? */ \
|
||||
LONG_ADDIU $r_s1, $r_skb_len, -SIZE; \
|
||||
sltu $r_s0, offset, $r_s1; \
|
||||
beqz $r_s0, fault; \
|
||||
/* Load 4th argument in DS */ \
|
||||
LONG_ADDIU a3, zero, SIZE; \
|
||||
PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \
|
||||
PTR_LA t0, skb_copy_bits; \
|
||||
PTR_S $r_ra, (5 * SZREG)($r_sp); \
|
||||
/* Assign low slot to a2 */ \
|
||||
PTR_ADDIU a2, $r_sp, DS_OFFSET(SIZE); \
|
||||
jalr t0; \
|
||||
/* Reset our destination slot (DS but it's ok) */ \
|
||||
INT_S zero, (4 * SZREG)($r_sp); \
|
||||
/* \
|
||||
* skb_copy_bits returns 0 on success and -EFAULT \
|
||||
* on error. Our data live in a2. Do not bother with \
|
||||
* our data if an error has been returned. \
|
||||
*/ \
|
||||
/* Restore our frame */ \
|
||||
PTR_L $r_ra, (5 * SZREG)($r_sp); \
|
||||
INT_L $r_s0, (4 * SZREG)($r_sp); \
|
||||
bltz v0, fault; \
|
||||
PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \
|
||||
move $r_ret, zero; \
|
||||
|
||||
NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp)
|
||||
bpf_slow_path_common(4)
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
# if MIPS_ISA_REV >= 2
|
||||
wsbh t0, $r_s0
|
||||
jr $r_ra
|
||||
rotr $r_A, t0, 16
|
||||
# else
|
||||
sll t0, $r_s0, 24
|
||||
srl t1, $r_s0, 24
|
||||
srl t2, $r_s0, 8
|
||||
or t0, t0, t1
|
||||
andi t2, t2, 0xff00
|
||||
andi t1, $r_s0, 0xff00
|
||||
or t0, t0, t2
|
||||
sll t1, t1, 8
|
||||
jr $r_ra
|
||||
or $r_A, t0, t1
|
||||
# endif
|
||||
#else
|
||||
jr $r_ra
|
||||
move $r_A, $r_s0
|
||||
#endif
|
||||
|
||||
END(bpf_slow_path_word)
|
||||
|
||||
NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp)
|
||||
bpf_slow_path_common(2)
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
# if MIPS_ISA_REV >= 2
|
||||
jr $r_ra
|
||||
wsbh $r_A, $r_s0
|
||||
# else
|
||||
sll t0, $r_s0, 8
|
||||
andi t1, $r_s0, 0xff00
|
||||
andi t0, t0, 0xff00
|
||||
srl t1, t1, 8
|
||||
jr $r_ra
|
||||
or $r_A, t0, t1
|
||||
# endif
|
||||
#else
|
||||
jr $r_ra
|
||||
move $r_A, $r_s0
|
||||
#endif
|
||||
|
||||
END(bpf_slow_path_half)
|
||||
|
||||
NESTED(bpf_slow_path_byte, (6 * SZREG), $r_sp)
|
||||
bpf_slow_path_common(1)
|
||||
jr $r_ra
|
||||
move $r_A, $r_s0
|
||||
|
||||
END(bpf_slow_path_byte)
|
||||
|
||||
/*
|
||||
* Negative entry points
|
||||
*/
|
||||
.macro bpf_is_end_of_data
|
||||
li t0, SKF_LL_OFF
|
||||
/* Reading link layer data? */
|
||||
slt t1, offset, t0
|
||||
bgtz t1, fault
|
||||
/* Be careful what follows in DS. */
|
||||
.endm
|
||||
/*
|
||||
* call skb_copy_bits:
|
||||
* (prototype in linux/filter.h)
|
||||
*
|
||||
* void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb,
|
||||
* int k, unsigned int size)
|
||||
*
|
||||
* see above (bpf_slow_path_common) for ABI restrictions
|
||||
*/
|
||||
#define bpf_negative_common(SIZE) \
|
||||
PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \
|
||||
PTR_LA t0, bpf_internal_load_pointer_neg_helper; \
|
||||
PTR_S $r_ra, (5 * SZREG)($r_sp); \
|
||||
jalr t0; \
|
||||
li a2, SIZE; \
|
||||
PTR_L $r_ra, (5 * SZREG)($r_sp); \
|
||||
/* Check return pointer */ \
|
||||
beqz v0, fault; \
|
||||
PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \
|
||||
/* Preserve our pointer */ \
|
||||
move $r_s0, v0; \
|
||||
/* Set return value */ \
|
||||
move $r_ret, zero; \
|
||||
|
||||
bpf_slow_path_word_neg:
|
||||
bpf_is_end_of_data
|
||||
NESTED(sk_load_word_negative, (6 * SZREG), $r_sp)
|
||||
bpf_negative_common(4)
|
||||
jr $r_ra
|
||||
lw $r_A, 0($r_s0)
|
||||
END(sk_load_word_negative)
|
||||
|
||||
bpf_slow_path_half_neg:
|
||||
bpf_is_end_of_data
|
||||
NESTED(sk_load_half_negative, (6 * SZREG), $r_sp)
|
||||
bpf_negative_common(2)
|
||||
jr $r_ra
|
||||
lhu $r_A, 0($r_s0)
|
||||
END(sk_load_half_negative)
|
||||
|
||||
bpf_slow_path_byte_neg:
|
||||
bpf_is_end_of_data
|
||||
NESTED(sk_load_byte_negative, (6 * SZREG), $r_sp)
|
||||
bpf_negative_common(1)
|
||||
jr $r_ra
|
||||
lbu $r_A, 0($r_s0)
|
||||
END(sk_load_byte_negative)
|
||||
|
||||
fault:
|
||||
jr $r_ra
|
||||
addiu $r_ret, zero, 1
|
|
@ -10,7 +10,7 @@
|
|||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/types.h>
|
||||
#include <asm/sn/klconfig.h>
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/ioc3.h>
|
||||
#include <asm/pci/bridge.h>
|
||||
|
||||
|
|
|
@ -437,17 +437,28 @@ static int bridge_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
|||
struct irq_alloc_info info;
|
||||
int irq;
|
||||
|
||||
irq = bc->pci_int[slot];
|
||||
switch (pin) {
|
||||
case PCI_INTERRUPT_UNKNOWN:
|
||||
case PCI_INTERRUPT_INTA:
|
||||
case PCI_INTERRUPT_INTC:
|
||||
pin = 0;
|
||||
break;
|
||||
case PCI_INTERRUPT_INTB:
|
||||
case PCI_INTERRUPT_INTD:
|
||||
pin = 1;
|
||||
}
|
||||
|
||||
irq = bc->pci_int[slot][pin];
|
||||
if (irq == -1) {
|
||||
info.ctrl = bc;
|
||||
info.nasid = bc->nasid;
|
||||
info.pin = slot;
|
||||
info.pin = bc->int_mapping[slot][pin];
|
||||
|
||||
irq = irq_domain_alloc_irqs(bc->domain, 1, bc->nasid, &info);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
bc->pci_int[slot] = irq;
|
||||
bc->pci_int[slot][pin] = irq;
|
||||
}
|
||||
return irq;
|
||||
}
|
||||
|
@ -458,21 +469,26 @@ static void bridge_setup_ip27_baseio6g(struct bridge_controller *bc)
|
|||
{
|
||||
bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP27_BASEIO6G);
|
||||
bc->ioc3_sid[6] = IOC3_SID(IOC3_SUBSYS_IP27_MIO);
|
||||
bc->int_mapping[2][1] = 4;
|
||||
bc->int_mapping[6][1] = 6;
|
||||
}
|
||||
|
||||
static void bridge_setup_ip27_baseio(struct bridge_controller *bc)
|
||||
{
|
||||
bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP27_BASEIO);
|
||||
bc->int_mapping[2][1] = 4;
|
||||
}
|
||||
|
||||
static void bridge_setup_ip29_baseio(struct bridge_controller *bc)
|
||||
{
|
||||
bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP29_SYSBOARD);
|
||||
bc->int_mapping[2][1] = 3;
|
||||
}
|
||||
|
||||
static void bridge_setup_ip30_sysboard(struct bridge_controller *bc)
|
||||
{
|
||||
bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP30_SYSBOARD);
|
||||
bc->int_mapping[2][1] = 4;
|
||||
}
|
||||
|
||||
static void bridge_setup_menet(struct bridge_controller *bc)
|
||||
|
@ -483,6 +499,26 @@ static void bridge_setup_menet(struct bridge_controller *bc)
|
|||
bc->ioc3_sid[3] = IOC3_SID(IOC3_SUBSYS_MENET4);
|
||||
}
|
||||
|
||||
static void bridge_setup_io7(struct bridge_controller *bc)
|
||||
{
|
||||
bc->ioc3_sid[4] = IOC3_SID(IOC3_SUBSYS_IO7);
|
||||
}
|
||||
|
||||
static void bridge_setup_io8(struct bridge_controller *bc)
|
||||
{
|
||||
bc->ioc3_sid[4] = IOC3_SID(IOC3_SUBSYS_IO8);
|
||||
}
|
||||
|
||||
static void bridge_setup_io9(struct bridge_controller *bc)
|
||||
{
|
||||
bc->ioc3_sid[1] = IOC3_SID(IOC3_SUBSYS_IO9);
|
||||
}
|
||||
|
||||
static void bridge_setup_ip34_fuel_sysboard(struct bridge_controller *bc)
|
||||
{
|
||||
bc->ioc3_sid[4] = IOC3_SID(IOC3_SUBSYS_IP34_SYSBOARD);
|
||||
}
|
||||
|
||||
#define BRIDGE_BOARD_SETUP(_partno, _setup) \
|
||||
{ .match = _partno, .setup = _setup }
|
||||
|
||||
|
@ -500,6 +536,10 @@ static const struct {
|
|||
BRIDGE_BOARD_SETUP("030-0887-", bridge_setup_ip30_sysboard),
|
||||
BRIDGE_BOARD_SETUP("030-1467-", bridge_setup_ip30_sysboard),
|
||||
BRIDGE_BOARD_SETUP("030-0873-", bridge_setup_menet),
|
||||
BRIDGE_BOARD_SETUP("030-1557-", bridge_setup_io7),
|
||||
BRIDGE_BOARD_SETUP("030-1673-", bridge_setup_io8),
|
||||
BRIDGE_BOARD_SETUP("030-1771-", bridge_setup_io9),
|
||||
BRIDGE_BOARD_SETUP("030-1707-", bridge_setup_ip34_fuel_sysboard),
|
||||
};
|
||||
|
||||
static void bridge_setup_board(struct bridge_controller *bc, char *partnum)
|
||||
|
@ -655,7 +695,11 @@ static int bridge_probe(struct platform_device *pdev)
|
|||
|
||||
for (slot = 0; slot < 8; slot++) {
|
||||
bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR);
|
||||
bc->pci_int[slot] = -1;
|
||||
bc->pci_int[slot][0] = -1;
|
||||
bc->pci_int[slot][1] = -1;
|
||||
/* default interrupt pin mapping */
|
||||
bc->int_mapping[slot][0] = slot;
|
||||
bc->int_mapping[slot][1] = slot ^ 4;
|
||||
}
|
||||
bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */
|
||||
|
||||
|
|
|
@ -67,11 +67,13 @@ static int __init ill_acc_of_setup(void)
|
|||
irq = irq_of_parse_and_map(np, 0);
|
||||
if (!irq) {
|
||||
dev_err(&pdev->dev, "failed to get irq\n");
|
||||
put_device(&pdev->dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) {
|
||||
dev_err(&pdev->dev, "failed to request irq\n");
|
||||
put_device(&pdev->dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,9 @@ static struct device gio_bus = {
|
|||
* Used by a driver to check whether an of_device present in the
|
||||
* system is in its list of supported devices.
|
||||
*/
|
||||
const struct gio_device_id *gio_match_device(const struct gio_device_id *match,
|
||||
const struct gio_device *dev)
|
||||
static const struct gio_device_id *
|
||||
gio_match_device(const struct gio_device_id *match,
|
||||
const struct gio_device *dev)
|
||||
{
|
||||
const struct gio_device_id *ids;
|
||||
|
||||
|
@ -58,7 +59,6 @@ const struct gio_device_id *gio_match_device(const struct gio_device_id *match,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gio_match_device);
|
||||
|
||||
struct gio_device *gio_dev_get(struct gio_device *dev)
|
||||
{
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/sn0/hub.h>
|
||||
#include <asm/tlbdebug.h>
|
||||
#include <asm/traps.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
@ -30,29 +30,31 @@ static void dump_hub_information(unsigned long errst0, unsigned long errst1)
|
|||
{ "WERR", "Uncached Partial Write", "PWERR", "Write Timeout",
|
||||
NULL, NULL, NULL, NULL }
|
||||
};
|
||||
int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK;
|
||||
union pi_err_stat0 st0;
|
||||
union pi_err_stat1 st1;
|
||||
|
||||
if (!(errst0 & PI_ERR_ST0_VALID_MASK)) {
|
||||
printk("Hub does not contain valid error information\n");
|
||||
st0.pi_stat0_word = errst0;
|
||||
st1.pi_stat1_word = errst1;
|
||||
|
||||
if (!st0.pi_stat0_fmt.s0_valid) {
|
||||
pr_info("Hub does not contain valid error information\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
printk("Hub has valid error information:\n");
|
||||
if (errst0 & PI_ERR_ST0_OVERRUN_MASK)
|
||||
printk("Overrun is set. Error stack may contain additional "
|
||||
pr_info("Hub has valid error information:\n");
|
||||
if (st0.pi_stat0_fmt.s0_ovr_run)
|
||||
pr_info("Overrun is set. Error stack may contain additional "
|
||||
"information.\n");
|
||||
printk("Hub error address is %08lx\n",
|
||||
(errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3));
|
||||
printk("Incoming message command 0x%lx\n",
|
||||
(errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT);
|
||||
printk("Supplemental field of incoming message is 0x%lx\n",
|
||||
(errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT);
|
||||
printk("T5 Rn (for RRB only) is 0x%lx\n",
|
||||
(errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT);
|
||||
printk("Error type is %s\n", err_type[wrb]
|
||||
[(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT]
|
||||
? : "invalid");
|
||||
pr_info("Hub error address is %08lx\n",
|
||||
(unsigned long)st0.pi_stat0_fmt.s0_addr);
|
||||
pr_info("Incoming message command 0x%lx\n",
|
||||
(unsigned long)st0.pi_stat0_fmt.s0_cmd);
|
||||
pr_info("Supplemental field of incoming message is 0x%lx\n",
|
||||
(unsigned long)st0.pi_stat0_fmt.s0_supl);
|
||||
pr_info("T5 Rn (for RRB only) is 0x%lx\n",
|
||||
(unsigned long)st0.pi_stat0_fmt.s0_t5_req);
|
||||
pr_info("Error type is %s\n", err_type[st1.pi_stat1_fmt.s1_rw_rb]
|
||||
[st0.pi_stat0_fmt.s0_err_type] ? : "invalid");
|
||||
}
|
||||
|
||||
int ip27_be_handler(struct pt_regs *regs, int is_fixup)
|
||||
|
|
|
@ -3,8 +3,18 @@
|
|||
#ifndef __IP27_COMMON_H
|
||||
#define __IP27_COMMON_H
|
||||
|
||||
extern void ip27_reboot_setup(void);
|
||||
extern nasid_t master_nasid;
|
||||
|
||||
extern void cpu_node_probe(void);
|
||||
extern void hub_rt_clock_event_init(void);
|
||||
extern void hub_rtc_init(nasid_t nasid);
|
||||
extern void install_cpu_nmi_handler(int slice);
|
||||
extern void install_ipi(void);
|
||||
extern void ip27_reboot_setup(void);
|
||||
extern const struct plat_smp_ops ip27_smp_ops;
|
||||
extern unsigned long node_getfirstfree(nasid_t nasid);
|
||||
extern void per_cpu_init(void);
|
||||
extern void replicate_kernel_text(void);
|
||||
extern void setup_replication_mask(void);
|
||||
|
||||
#endif /* __IP27_COMMON_H */
|
||||
|
|
|
@ -9,14 +9,15 @@
|
|||
#include <asm/page.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/sn0/hub.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/klconfig.h>
|
||||
#include <asm/sn/ioc3.h>
|
||||
#include <asm/sn/sn_private.h>
|
||||
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
|
||||
#include "ip27-common.h"
|
||||
|
||||
#define IOC3_CLK (22000000 / 3)
|
||||
#define IOC3_FLAGS (0)
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
#include <linux/mmzone.h>
|
||||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/io.h>
|
||||
#include <asm/xtalk/xtalk.h>
|
||||
|
||||
|
||||
static int force_fire_and_forget = 1;
|
||||
|
@ -82,7 +84,7 @@ unsigned long hub_pio_map(nasid_t nasid, xwidgetnum_t widget,
|
|||
*/
|
||||
static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
|
||||
{
|
||||
iprb_t prb;
|
||||
union iprb_u prb;
|
||||
int prb_offset;
|
||||
|
||||
/*
|
||||
|
@ -135,7 +137,7 @@ static void hub_setup_prb(nasid_t nasid, int prbnum, int credits)
|
|||
static void hub_set_piomode(nasid_t nasid)
|
||||
{
|
||||
u64 ii_iowa;
|
||||
hubii_wcr_t ii_wcr;
|
||||
union hubii_wcr_u ii_wcr;
|
||||
unsigned i;
|
||||
|
||||
ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
|
||||
|
|
|
@ -19,23 +19,18 @@
|
|||
#include <asm/pgtable.h>
|
||||
#include <asm/sgialib.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/types.h>
|
||||
#include <asm/sn/sn0/addrs.h>
|
||||
#include <asm/sn/sn0/hubni.h>
|
||||
#include <asm/sn/sn0/hubio.h>
|
||||
#include <asm/sn/klconfig.h>
|
||||
#include <asm/sn/ioc3.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/sn/gda.h>
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/sn/intr.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/sn/launch.h>
|
||||
#include <asm/sn/sn_private.h>
|
||||
#include <asm/sn/sn0/ip27.h>
|
||||
#include <asm/sn/mapped_kernel.h>
|
||||
|
||||
#include "ip27-common.h"
|
||||
|
@ -77,18 +72,14 @@ static void per_hub_init(nasid_t nasid)
|
|||
void per_cpu_init(void)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
int slice = LOCAL_HUB_L(PI_CPU_NUM);
|
||||
nasid_t nasid = get_nasid();
|
||||
struct hub_data *hub = hub_data(nasid);
|
||||
|
||||
if (test_and_set_bit(slice, &hub->slice_map))
|
||||
return;
|
||||
|
||||
clear_c0_status(ST0_IM);
|
||||
|
||||
per_hub_init(nasid);
|
||||
|
||||
cpu_time_init();
|
||||
pr_info("CPU %d clock is %dMHz.\n", cpu, sn_cpu_info[cpu].p_speed);
|
||||
|
||||
install_ipi();
|
||||
|
||||
/* Install our NMI handler if symmon hasn't installed one. */
|
||||
|
@ -98,16 +89,6 @@ void per_cpu_init(void)
|
|||
enable_percpu_irq(IP27_HUB_PEND1_IRQ, IRQ_TYPE_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_nasid() returns the physical node id number of the caller.
|
||||
*/
|
||||
nasid_t
|
||||
get_nasid(void)
|
||||
{
|
||||
return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
|
||||
>> NSRI_NODEID_SHFT);
|
||||
}
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
u64 p, e, n_mode;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/sn/intr.h>
|
||||
#include <asm/sn/irq_alloc.h>
|
||||
|
||||
|
@ -288,11 +287,9 @@ void __init arch_init_irq(void)
|
|||
* Mark these as reserved right away so they won't be used accidentally
|
||||
* later.
|
||||
*/
|
||||
for (i = 0; i <= BASE_PCI_IRQ; i++)
|
||||
for (i = 0; i <= CPU_CALL_B_IRQ; i++)
|
||||
set_bit(i, hub_irq_map);
|
||||
|
||||
set_bit(IP_PEND0_6_63, hub_irq_map);
|
||||
|
||||
for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++)
|
||||
set_bit(i, hub_irq_map);
|
||||
|
||||
|
|
|
@ -72,54 +72,3 @@ lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_type)
|
|||
/* Didn't find it. */
|
||||
return (lboard_t *)NULL;
|
||||
}
|
||||
|
||||
klcpu_t *nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
|
||||
{
|
||||
lboard_t *brd;
|
||||
klcpu_t *acpu;
|
||||
|
||||
if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
|
||||
return (klcpu_t *)NULL;
|
||||
|
||||
if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
|
||||
return (klcpu_t *)NULL;
|
||||
|
||||
do {
|
||||
if ((acpu->cpu_info.physid) == slice)
|
||||
return acpu;
|
||||
} while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
|
||||
KLSTRUCT_CPU)));
|
||||
return (klcpu_t *)NULL;
|
||||
}
|
||||
|
||||
klcpu_t *sn_get_cpuinfo(cpuid_t cpu)
|
||||
{
|
||||
nasid_t nasid;
|
||||
int slice;
|
||||
klcpu_t *acpu;
|
||||
|
||||
if (!(cpu < MAXCPUS)) {
|
||||
printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nasid = cputonasid(cpu);
|
||||
if (nasid == INVALID_NASID)
|
||||
return NULL;
|
||||
|
||||
for (slice = 0; slice < CPUS_PER_NODE; slice++) {
|
||||
acpu = nasid_slice_to_cpuinfo(nasid, slice);
|
||||
if (acpu && acpu->cpu_info.virtid == cpu)
|
||||
return acpu;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int get_cpu_slice(cpuid_t cpu)
|
||||
{
|
||||
klcpu_t *acpu;
|
||||
|
||||
if ((acpu = sn_get_cpuinfo(cpu)) == NULL)
|
||||
return -1;
|
||||
return acpu->cpu_info.physid;
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
#include <asm/sn/types.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/gda.h>
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/sn/mapped_kernel.h>
|
||||
#include <asm/sn/sn_private.h>
|
||||
|
||||
static cpumask_t ktext_repmask;
|
||||
#include "ip27-common.h"
|
||||
|
||||
static nodemask_t ktext_repmask;
|
||||
|
||||
/*
|
||||
* XXX - This needs to be much smarter about where it puts copies of the
|
||||
|
@ -30,8 +30,8 @@ static cpumask_t ktext_repmask;
|
|||
void __init setup_replication_mask(void)
|
||||
{
|
||||
/* Set only the master cnode's bit. The master cnode is always 0. */
|
||||
cpumask_clear(&ktext_repmask);
|
||||
cpumask_set_cpu(0, &ktext_repmask);
|
||||
nodes_clear(ktext_repmask);
|
||||
node_set(0, ktext_repmask);
|
||||
|
||||
#ifdef CONFIG_REPLICATE_KTEXT
|
||||
#ifndef CONFIG_MAPPED_KERNEL
|
||||
|
@ -44,7 +44,7 @@ void __init setup_replication_mask(void)
|
|||
if (nasid == 0)
|
||||
continue;
|
||||
/* Advertise that we have a copy of the kernel */
|
||||
cpumask_set_cpu(nasid, &ktext_repmask);
|
||||
node_set(nasid, ktext_repmask);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -98,7 +98,7 @@ void __init replicate_kernel_text(void)
|
|||
continue;
|
||||
|
||||
/* Check if this node should get a copy of the kernel */
|
||||
if (cpumask_test_cpu(client_nasid, &ktext_repmask)) {
|
||||
if (node_isset(client_nasid, ktext_repmask)) {
|
||||
server_nasid = client_nasid;
|
||||
copy_kernel(server_nasid);
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ unsigned long node_getfirstfree(nasid_t nasid)
|
|||
loadbase += 16777216;
|
||||
#endif
|
||||
offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
|
||||
if ((nasid == 0) || (cpumask_test_cpu(nasid, &ktext_repmask)))
|
||||
if ((nasid == 0) || (node_isset(nasid, ktext_repmask)))
|
||||
return TO_NODE(nasid, offset) >> PAGE_SHIFT;
|
||||
else
|
||||
return KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> PAGE_SHIFT;
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
#include <asm/sections.h>
|
||||
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/klconfig.h>
|
||||
#include <asm/sn/sn_private.h>
|
||||
|
||||
#include "ip27-common.h"
|
||||
|
||||
#define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT)
|
||||
#define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT)
|
||||
|
@ -37,31 +37,18 @@ struct node_data *__node_data[MAX_NUMNODES];
|
|||
|
||||
EXPORT_SYMBOL(__node_data);
|
||||
|
||||
static int fine_mode;
|
||||
|
||||
static int is_fine_dirmode(void)
|
||||
{
|
||||
return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE;
|
||||
}
|
||||
|
||||
static u64 get_region(nasid_t nasid)
|
||||
{
|
||||
if (fine_mode)
|
||||
return nasid >> NASID_TO_FINEREG_SHFT;
|
||||
else
|
||||
return nasid >> NASID_TO_COARSEREG_SHFT;
|
||||
}
|
||||
|
||||
static u64 region_mask;
|
||||
|
||||
static void gen_region_mask(u64 *region_mask)
|
||||
static u64 gen_region_mask(void)
|
||||
{
|
||||
int region_shift;
|
||||
u64 region_mask;
|
||||
nasid_t nasid;
|
||||
|
||||
(*region_mask) = 0;
|
||||
for_each_online_node(nasid) {
|
||||
(*region_mask) |= 1ULL << get_region(nasid);
|
||||
}
|
||||
region_shift = get_region_shift();
|
||||
region_mask = 0;
|
||||
for_each_online_node(nasid)
|
||||
region_mask |= BIT_ULL(nasid >> region_shift);
|
||||
|
||||
return region_mask;
|
||||
}
|
||||
|
||||
#define rou_rflag rou_flags
|
||||
|
@ -148,25 +135,25 @@ static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b)
|
|||
} while ((brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)));
|
||||
}
|
||||
|
||||
if (nasid_a == nasid_b)
|
||||
return LOCAL_DISTANCE;
|
||||
|
||||
if (router_a == router_b)
|
||||
return LOCAL_DISTANCE + 1;
|
||||
|
||||
if (router_a == NULL) {
|
||||
pr_info("node_distance: router_a NULL\n");
|
||||
return -1;
|
||||
return 255;
|
||||
}
|
||||
if (router_b == NULL) {
|
||||
pr_info("node_distance: router_b NULL\n");
|
||||
return -1;
|
||||
return 255;
|
||||
}
|
||||
|
||||
if (nasid_a == nasid_b)
|
||||
return 0;
|
||||
|
||||
if (router_a == router_b)
|
||||
return 1;
|
||||
|
||||
router_distance = 100;
|
||||
router_recurse(router_a, router_b, 2);
|
||||
|
||||
return router_distance;
|
||||
return LOCAL_DISTANCE + router_distance;
|
||||
}
|
||||
|
||||
static void __init init_topology_matrix(void)
|
||||
|
@ -281,10 +268,10 @@ static unsigned long __init slot_psize_compute(nasid_t nasid, int slot)
|
|||
|
||||
static void __init mlreset(void)
|
||||
{
|
||||
u64 region_mask;
|
||||
nasid_t nasid;
|
||||
|
||||
master_nasid = get_nasid();
|
||||
fine_mode = is_fine_dirmode();
|
||||
|
||||
/*
|
||||
* Probe for all CPUs - this creates the cpumask and sets up the
|
||||
|
@ -297,7 +284,7 @@ static void __init mlreset(void)
|
|||
init_topology_matrix();
|
||||
dump_topology();
|
||||
|
||||
gen_region_mask(®ion_mask);
|
||||
region_mask = gen_region_mask();
|
||||
|
||||
setup_replication_mask();
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/nmi.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/sn0/hub.h>
|
||||
#include <asm/sn/agent.h>
|
||||
|
||||
#if 0
|
||||
#define NODE_NUM_CPUS(n) CNODE_NUM_CPUS(n)
|
||||
|
@ -17,6 +17,9 @@
|
|||
#define NODE_NUM_CPUS(n) CPUS_PER_NODE
|
||||
#endif
|
||||
|
||||
#define SEND_NMI(_nasid, _slice) \
|
||||
REMOTE_HUB_S((_nasid), (PI_NMI_A + ((_slice) * PI_NMI_OFFSET)), 1)
|
||||
|
||||
typedef unsigned long machreg_t;
|
||||
|
||||
static arch_spinlock_t nmi_lock = __ARCH_SPIN_LOCK_UNLOCKED;
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
#include <asm/reboot.h>
|
||||
#include <asm/sgialib.h>
|
||||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/gda.h>
|
||||
#include <asm/sn/sn0/hub.h>
|
||||
|
||||
#include "ip27-common.h"
|
||||
|
||||
|
|
|
@ -15,36 +15,22 @@
|
|||
#include <asm/page.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/sn/agent.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/gda.h>
|
||||
#include <asm/sn/intr.h>
|
||||
#include <asm/sn/klconfig.h>
|
||||
#include <asm/sn/launch.h>
|
||||
#include <asm/sn/mapped_kernel.h>
|
||||
#include <asm/sn/sn_private.h>
|
||||
#include <asm/sn/types.h>
|
||||
#include <asm/sn/sn0/hubpi.h>
|
||||
#include <asm/sn/sn0/hubio.h>
|
||||
#include <asm/sn/sn0/ip27.h>
|
||||
|
||||
#include "ip27-common.h"
|
||||
|
||||
/*
|
||||
* Takes as first input the PROM assigned cpu id, and the kernel
|
||||
* assigned cpu id as the second.
|
||||
*/
|
||||
static void alloc_cpupda(nasid_t nasid, cpuid_t cpu, int cpunum)
|
||||
static int node_scan_cpus(nasid_t nasid, int highest)
|
||||
{
|
||||
cputonasid(cpunum) = nasid;
|
||||
cputoslice(cpunum) = get_cpu_slice(cpu);
|
||||
}
|
||||
|
||||
static int do_cpumask(nasid_t nasid, int highest)
|
||||
{
|
||||
static int tot_cpus_found = 0;
|
||||
static int cpus_found;
|
||||
lboard_t *brd;
|
||||
klcpu_t *acpu;
|
||||
int cpus_found = 0;
|
||||
cpuid_t cpuid;
|
||||
|
||||
brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
|
||||
|
@ -55,13 +41,15 @@ static int do_cpumask(nasid_t nasid, int highest)
|
|||
cpuid = acpu->cpu_info.virtid;
|
||||
/* Only let it join in if it's marked enabled */
|
||||
if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
|
||||
(tot_cpus_found != NR_CPUS)) {
|
||||
(cpus_found != NR_CPUS)) {
|
||||
if (cpuid > highest)
|
||||
highest = cpuid;
|
||||
set_cpu_possible(cpuid, true);
|
||||
alloc_cpupda(nasid, cpuid, tot_cpus_found);
|
||||
cputonasid(cpus_found) = nasid;
|
||||
cputoslice(cpus_found) = acpu->cpu_info.physid;
|
||||
sn_cpu_info[cpus_found].p_speed =
|
||||
acpu->cpu_speed;
|
||||
cpus_found++;
|
||||
tot_cpus_found++;
|
||||
}
|
||||
acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
|
||||
KLSTRUCT_CPU);
|
||||
|
@ -87,7 +75,7 @@ void cpu_node_probe(void)
|
|||
if (nasid == INVALID_NASID)
|
||||
break;
|
||||
node_set_online(nasid);
|
||||
highest = do_cpumask(nasid, highest);
|
||||
highest = node_scan_cpus(nasid, highest);
|
||||
}
|
||||
|
||||
printk("Discovered %d cpus on %d nodes\n", highest + 1, num_online_nodes());
|
||||
|
@ -180,7 +168,8 @@ static void __init ip27_smp_setup(void)
|
|||
/*
|
||||
* PROM sets up system, that boot cpu is always first CPU on nasid 0
|
||||
*/
|
||||
alloc_cpupda(0, 0, 0);
|
||||
cputonasid(0) = 0;
|
||||
cputoslice(0) = LOCAL_HUB_L(PI_CPU_NUM);
|
||||
}
|
||||
|
||||
static void __init ip27_prepare_cpus(unsigned int max_cpus)
|
||||
|
|
|
@ -25,17 +25,14 @@
|
|||
#include <asm/sn/klconfig.h>
|
||||
#include <asm/sn/arch.h>
|
||||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/sn_private.h>
|
||||
#include <asm/sn/sn0/ip27.h>
|
||||
#include <asm/sn/sn0/hub.h>
|
||||
#include <asm/sn/agent.h>
|
||||
|
||||
#include "ip27-common.h"
|
||||
|
||||
#define TICK_SIZE (tick_nsec / 1000)
|
||||
|
||||
/* Includes for ioc3_init(). */
|
||||
#include <asm/sn/types.h>
|
||||
#include <asm/sn/sn0/addrs.h>
|
||||
#include <asm/sn/sn0/hubni.h>
|
||||
#include <asm/sn/sn0/hubio.h>
|
||||
#include <asm/pci/bridge.h>
|
||||
|
||||
#include "ip27-common.h"
|
||||
|
@ -153,25 +150,6 @@ void __init plat_time_init(void)
|
|||
hub_rt_clock_event_init();
|
||||
}
|
||||
|
||||
void cpu_time_init(void)
|
||||
{
|
||||
lboard_t *board;
|
||||
klcpu_t *cpu;
|
||||
int cpuid;
|
||||
|
||||
/* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */
|
||||
board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
|
||||
if (!board)
|
||||
panic("Can't find board info for myself.");
|
||||
|
||||
cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
|
||||
cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
|
||||
if (!cpu)
|
||||
panic("No information about myself?");
|
||||
|
||||
printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
|
||||
}
|
||||
|
||||
void hub_rtc_init(nasid_t nasid)
|
||||
{
|
||||
|
||||
|
@ -190,23 +168,3 @@ void hub_rtc_init(nasid_t nasid)
|
|||
LOCAL_HUB_S(PI_RT_PEND_B, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init sgi_ip27_rtc_devinit(void)
|
||||
{
|
||||
struct resource res;
|
||||
|
||||
memset(&res, 0, sizeof(res));
|
||||
res.start = XPHYSADDR(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base +
|
||||
IOC3_BYTEBUS_DEV0);
|
||||
res.end = res.start + 32767;
|
||||
res.flags = IORESOURCE_MEM;
|
||||
|
||||
return IS_ERR(platform_device_register_simple("rtc-m48t35", -1,
|
||||
&res, 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* kludge make this a device_initcall after ioc3 resource conflicts
|
||||
* are resolved
|
||||
*/
|
||||
late_initcall(sgi_ip27_rtc_devinit);
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <asm/sn/addrs.h>
|
||||
#include <asm/sn/types.h>
|
||||
#include <asm/sn/klconfig.h>
|
||||
#include <asm/sn/hub.h>
|
||||
#include <asm/pci/bridge.h>
|
||||
#include <asm/xtalk/xtalk.h>
|
||||
|
||||
|
|
|
@ -232,9 +232,10 @@ static void heart_domain_free(struct irq_domain *domain,
|
|||
return;
|
||||
|
||||
irqd = irq_domain_get_irq_data(domain, virq);
|
||||
clear_bit(irqd->hwirq, heart_irq_map);
|
||||
if (irqd && irqd->chip_data)
|
||||
if (irqd) {
|
||||
clear_bit(irqd->hwirq, heart_irq_map);
|
||||
kfree(irqd->chip_data);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops heart_domain_ops = {
|
||||
|
|
|
@ -251,6 +251,18 @@ int main(int argc, char **argv)
|
|||
fprintf(out_file, "#include <linux/linkage.h>\n");
|
||||
fprintf(out_file, "#include <linux/mm.h>\n");
|
||||
fprintf(out_file, "#include <asm/vdso.h>\n");
|
||||
fprintf(out_file, "static int vdso_mremap(\n");
|
||||
fprintf(out_file, " const struct vm_special_mapping *sm,\n");
|
||||
fprintf(out_file, " struct vm_area_struct *new_vma)\n");
|
||||
fprintf(out_file, "{\n");
|
||||
fprintf(out_file, " unsigned long new_size =\n");
|
||||
fprintf(out_file, " new_vma->vm_end - new_vma->vm_start;\n");
|
||||
fprintf(out_file, " if (vdso_image.size != new_size)\n");
|
||||
fprintf(out_file, " return -EINVAL;\n");
|
||||
fprintf(out_file, " current->mm->context.vdso =\n");
|
||||
fprintf(out_file, " (void __user *)(new_vma->vm_start);\n");
|
||||
fprintf(out_file, " return 0;\n");
|
||||
fprintf(out_file, "}\n");
|
||||
|
||||
/* Write out the stripped VDSO data. */
|
||||
fprintf(out_file,
|
||||
|
@ -275,6 +287,7 @@ int main(int argc, char **argv)
|
|||
fprintf(out_file, "\t.mapping = {\n");
|
||||
fprintf(out_file, "\t\t.name = \"[vdso]\",\n");
|
||||
fprintf(out_file, "\t\t.pages = vdso_pages,\n");
|
||||
fprintf(out_file, "\t\t.mremap = vdso_mremap,\n");
|
||||
fprintf(out_file, "\t},\n");
|
||||
|
||||
/* Calculate and write symbol offsets to <output file> */
|
||||
|
|
|
@ -2004,5 +2004,18 @@ config RAVE_SP_CORE
|
|||
Select this to get support for the Supervisory Processor
|
||||
device found on several devices in RAVE line of hardware.
|
||||
|
||||
config SGI_MFD_IOC3
|
||||
tristate "SGI IOC3 core driver"
|
||||
depends on PCI && MIPS && 64BIT
|
||||
select MFD_CORE
|
||||
help
|
||||
This option enables basic support for the SGI IOC3-based
|
||||
controller cards. This option does not enable any specific
|
||||
functions on such a card, but provides necessary infrastructure
|
||||
for other drivers to utilize.
|
||||
|
||||
If you have an SGI Origin, Octane, or a PCI IOC3 card,
|
||||
then say Y. Otherwise say N.
|
||||
|
||||
endmenu
|
||||
endif
|
||||
|
|
|
@ -255,3 +255,4 @@ obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o
|
|||
obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
|
||||
obj-$(CONFIG_MFD_STMFX) += stmfx.o
|
||||
|
||||
obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o
|
||||
|
|
|
@ -0,0 +1,669 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* SGI IOC3 multifunction device driver
|
||||
*
|
||||
* Copyright (C) 2018, 2019 Thomas Bogendoerfer <tbogendoerfer@suse.de>
|
||||
*
|
||||
* Based on work by:
|
||||
* Stanislaw Skowronek <skylark@unaligned.org>
|
||||
* Joshua Kinard <kumba@gentoo.org>
|
||||
* Brent Casavant <bcasavan@sgi.com> - IOC4 master driver
|
||||
* Pat Gefre <pfg@sgi.com> - IOC3 serial port IRQ demuxer
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/sgi-w1.h>
|
||||
#include <linux/rtc/ds1685.h>
|
||||
|
||||
#include <asm/pci/bridge.h>
|
||||
#include <asm/sn/ioc3.h>
|
||||
|
||||
#define IOC3_IRQ_SERIAL_A 6
|
||||
#define IOC3_IRQ_SERIAL_B 15
|
||||
#define IOC3_IRQ_KBD 22
|
||||
|
||||
/* Bitmask for selecting which IRQs are level triggered */
|
||||
#define IOC3_LVL_MASK (BIT(IOC3_IRQ_SERIAL_A) | BIT(IOC3_IRQ_SERIAL_B))
|
||||
|
||||
#define M48T35_REG_SIZE 32768 /* size of m48t35 registers */
|
||||
|
||||
/* 1.2 us latency timer (40 cycles at 33 MHz) */
|
||||
#define IOC3_LATENCY 40
|
||||
|
||||
struct ioc3_priv_data {
|
||||
struct irq_domain *domain;
|
||||
struct ioc3 __iomem *regs;
|
||||
struct pci_dev *pdev;
|
||||
int domain_irq;
|
||||
};
|
||||
|
||||
static void ioc3_irq_ack(struct irq_data *d)
|
||||
{
|
||||
struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
|
||||
writel(BIT(hwirq), &ipd->regs->sio_ir);
|
||||
}
|
||||
|
||||
static void ioc3_irq_mask(struct irq_data *d)
|
||||
{
|
||||
struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
|
||||
writel(BIT(hwirq), &ipd->regs->sio_iec);
|
||||
}
|
||||
|
||||
static void ioc3_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct ioc3_priv_data *ipd = irq_data_get_irq_chip_data(d);
|
||||
unsigned int hwirq = irqd_to_hwirq(d);
|
||||
|
||||
writel(BIT(hwirq), &ipd->regs->sio_ies);
|
||||
}
|
||||
|
||||
static struct irq_chip ioc3_irq_chip = {
|
||||
.name = "IOC3",
|
||||
.irq_ack = ioc3_irq_ack,
|
||||
.irq_mask = ioc3_irq_mask,
|
||||
.irq_unmask = ioc3_irq_unmask,
|
||||
};
|
||||
|
||||
static int ioc3_irq_domain_map(struct irq_domain *d, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
/* Set level IRQs for every interrupt contained in IOC3_LVL_MASK */
|
||||
if (BIT(hwirq) & IOC3_LVL_MASK)
|
||||
irq_set_chip_and_handler(irq, &ioc3_irq_chip, handle_level_irq);
|
||||
else
|
||||
irq_set_chip_and_handler(irq, &ioc3_irq_chip, handle_edge_irq);
|
||||
|
||||
irq_set_chip_data(irq, d->host_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ioc3_irq_domain_unmap(struct irq_domain *d, unsigned int irq)
|
||||
{
|
||||
irq_set_chip_and_handler(irq, NULL, NULL);
|
||||
irq_set_chip_data(irq, NULL);
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops ioc3_irq_domain_ops = {
|
||||
.map = ioc3_irq_domain_map,
|
||||
.unmap = ioc3_irq_domain_unmap,
|
||||
};
|
||||
|
||||
static void ioc3_irq_handler(struct irq_desc *desc)
|
||||
{
|
||||
struct irq_domain *domain = irq_desc_get_handler_data(desc);
|
||||
struct ioc3_priv_data *ipd = domain->host_data;
|
||||
struct ioc3 __iomem *regs = ipd->regs;
|
||||
u32 pending, mask;
|
||||
unsigned int irq;
|
||||
|
||||
pending = readl(®s->sio_ir);
|
||||
mask = readl(®s->sio_ies);
|
||||
pending &= mask; /* Mask off not enabled interrupts */
|
||||
|
||||
if (pending) {
|
||||
irq = irq_find_mapping(domain, __ffs(pending));
|
||||
if (irq)
|
||||
generic_handle_irq(irq);
|
||||
} else {
|
||||
spurious_interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* System boards/BaseIOs use more interrupt pins of the bridge ASIC
|
||||
* to which the IOC3 is connected. Since the IOC3 MFD driver
|
||||
* knows wiring of these extra pins, we use the map_irq function
|
||||
* to get interrupts activated
|
||||
*/
|
||||
static int ioc3_map_irq(struct pci_dev *pdev, int slot, int pin)
|
||||
{
|
||||
struct pci_host_bridge *hbrg = pci_find_host_bridge(pdev->bus);
|
||||
|
||||
return hbrg->map_irq(pdev, slot, pin);
|
||||
}
|
||||
|
||||
static int ioc3_irq_domain_setup(struct ioc3_priv_data *ipd, int irq)
|
||||
{
|
||||
struct irq_domain *domain;
|
||||
struct fwnode_handle *fn;
|
||||
|
||||
fn = irq_domain_alloc_named_fwnode("IOC3");
|
||||
if (!fn)
|
||||
goto err;
|
||||
|
||||
domain = irq_domain_create_linear(fn, 24, &ioc3_irq_domain_ops, ipd);
|
||||
if (!domain)
|
||||
goto err;
|
||||
|
||||
irq_domain_free_fwnode(fn);
|
||||
ipd->domain = domain;
|
||||
|
||||
irq_set_chained_handler_and_data(irq, ioc3_irq_handler, domain);
|
||||
ipd->domain_irq = irq;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err(&ipd->pdev->dev, "irq domain setup failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static struct resource ioc3_uarta_resources[] = {
|
||||
DEFINE_RES_MEM(offsetof(struct ioc3, sregs.uarta),
|
||||
sizeof_field(struct ioc3, sregs.uarta)),
|
||||
DEFINE_RES_IRQ(IOC3_IRQ_SERIAL_A)
|
||||
};
|
||||
|
||||
static struct resource ioc3_uartb_resources[] = {
|
||||
DEFINE_RES_MEM(offsetof(struct ioc3, sregs.uartb),
|
||||
sizeof_field(struct ioc3, sregs.uartb)),
|
||||
DEFINE_RES_IRQ(IOC3_IRQ_SERIAL_B)
|
||||
};
|
||||
|
||||
static struct mfd_cell ioc3_serial_cells[] = {
|
||||
{
|
||||
.name = "ioc3-serial8250",
|
||||
.resources = ioc3_uarta_resources,
|
||||
.num_resources = ARRAY_SIZE(ioc3_uarta_resources),
|
||||
},
|
||||
{
|
||||
.name = "ioc3-serial8250",
|
||||
.resources = ioc3_uartb_resources,
|
||||
.num_resources = ARRAY_SIZE(ioc3_uartb_resources),
|
||||
}
|
||||
};
|
||||
|
||||
static int ioc3_serial_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Set gpio pins for RS232/RS422 mode selection */
|
||||
writel(GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL,
|
||||
&ipd->regs->gpcr_s);
|
||||
/* Select RS232 mode for uart a */
|
||||
writel(0, &ipd->regs->gppr[6]);
|
||||
/* Select RS232 mode for uart b */
|
||||
writel(0, &ipd->regs->gppr[7]);
|
||||
|
||||
/* Switch both ports to 16650 mode */
|
||||
writel(readl(&ipd->regs->port_a.sscr) & ~SSCR_DMA_EN,
|
||||
&ipd->regs->port_a.sscr);
|
||||
writel(readl(&ipd->regs->port_b.sscr) & ~SSCR_DMA_EN,
|
||||
&ipd->regs->port_b.sscr);
|
||||
udelay(1000); /* Wait until mode switch is done */
|
||||
|
||||
ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
|
||||
ioc3_serial_cells, ARRAY_SIZE(ioc3_serial_cells),
|
||||
&ipd->pdev->resource[0], 0, ipd->domain);
|
||||
if (ret) {
|
||||
dev_err(&ipd->pdev->dev, "Failed to add 16550 subdevs\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct resource ioc3_kbd_resources[] = {
|
||||
DEFINE_RES_MEM(offsetof(struct ioc3, serio),
|
||||
sizeof_field(struct ioc3, serio)),
|
||||
DEFINE_RES_IRQ(IOC3_IRQ_KBD)
|
||||
};
|
||||
|
||||
static struct mfd_cell ioc3_kbd_cells[] = {
|
||||
{
|
||||
.name = "ioc3-kbd",
|
||||
.resources = ioc3_kbd_resources,
|
||||
.num_resources = ARRAY_SIZE(ioc3_kbd_resources),
|
||||
}
|
||||
};
|
||||
|
||||
static int ioc3_kbd_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
|
||||
ioc3_kbd_cells, ARRAY_SIZE(ioc3_kbd_cells),
|
||||
&ipd->pdev->resource[0], 0, ipd->domain);
|
||||
if (ret) {
|
||||
dev_err(&ipd->pdev->dev, "Failed to add 16550 subdevs\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct resource ioc3_eth_resources[] = {
|
||||
DEFINE_RES_MEM(offsetof(struct ioc3, eth),
|
||||
sizeof_field(struct ioc3, eth)),
|
||||
DEFINE_RES_MEM(offsetof(struct ioc3, ssram),
|
||||
sizeof_field(struct ioc3, ssram)),
|
||||
DEFINE_RES_IRQ(0)
|
||||
};
|
||||
|
||||
static struct resource ioc3_w1_resources[] = {
|
||||
DEFINE_RES_MEM(offsetof(struct ioc3, mcr),
|
||||
sizeof_field(struct ioc3, mcr)),
|
||||
};
|
||||
static struct sgi_w1_platform_data ioc3_w1_platform_data;
|
||||
|
||||
static struct mfd_cell ioc3_eth_cells[] = {
|
||||
{
|
||||
.name = "ioc3-eth",
|
||||
.resources = ioc3_eth_resources,
|
||||
.num_resources = ARRAY_SIZE(ioc3_eth_resources),
|
||||
},
|
||||
{
|
||||
.name = "sgi_w1",
|
||||
.resources = ioc3_w1_resources,
|
||||
.num_resources = ARRAY_SIZE(ioc3_w1_resources),
|
||||
.platform_data = &ioc3_w1_platform_data,
|
||||
.pdata_size = sizeof(ioc3_w1_platform_data),
|
||||
}
|
||||
};
|
||||
|
||||
static int ioc3_eth_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Enable One-Wire bus */
|
||||
writel(GPCR_MLAN_EN, &ipd->regs->gpcr_s);
|
||||
|
||||
/* Generate unique identifier */
|
||||
snprintf(ioc3_w1_platform_data.dev_id,
|
||||
sizeof(ioc3_w1_platform_data.dev_id), "ioc3-%012llx",
|
||||
ipd->pdev->resource->start);
|
||||
|
||||
ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
|
||||
ioc3_eth_cells, ARRAY_SIZE(ioc3_eth_cells),
|
||||
&ipd->pdev->resource[0], ipd->pdev->irq, NULL);
|
||||
if (ret) {
|
||||
dev_err(&ipd->pdev->dev, "Failed to add ETH/W1 subdev\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct resource ioc3_m48t35_resources[] = {
|
||||
DEFINE_RES_MEM(IOC3_BYTEBUS_DEV0, M48T35_REG_SIZE)
|
||||
};
|
||||
|
||||
static struct mfd_cell ioc3_m48t35_cells[] = {
|
||||
{
|
||||
.name = "rtc-m48t35",
|
||||
.resources = ioc3_m48t35_resources,
|
||||
.num_resources = ARRAY_SIZE(ioc3_m48t35_resources),
|
||||
}
|
||||
};
|
||||
|
||||
static int ioc3_m48t35_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mfd_add_devices(&ipd->pdev->dev, PLATFORM_DEVID_AUTO,
|
||||
ioc3_m48t35_cells, ARRAY_SIZE(ioc3_m48t35_cells),
|
||||
&ipd->pdev->resource[0], 0, ipd->domain);
|
||||
if (ret)
|
||||
dev_err(&ipd->pdev->dev, "Failed to add M48T35 subdev\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct ds1685_rtc_platform_data ip30_rtc_platform_data = {
|
||||
.bcd_mode = false,
|
||||
.no_irq = false,
|
||||
.uie_unsupported = true,
|
||||
.access_type = ds1685_reg_indirect,
|
||||
};
|
||||
|
||||
static struct resource ioc3_rtc_ds1685_resources[] = {
|
||||
DEFINE_RES_MEM(IOC3_BYTEBUS_DEV1, 1),
|
||||
DEFINE_RES_MEM(IOC3_BYTEBUS_DEV2, 1),
|
||||
DEFINE_RES_IRQ(0)
|
||||
};
|
||||
|
||||
static struct mfd_cell ioc3_ds1685_cells[] = {
|
||||
{
|
||||
.name = "rtc-ds1685",
|
||||
.resources = ioc3_rtc_ds1685_resources,
|
||||
.num_resources = ARRAY_SIZE(ioc3_rtc_ds1685_resources),
|
||||
.platform_data = &ip30_rtc_platform_data,
|
||||
.pdata_size = sizeof(ip30_rtc_platform_data),
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
}
|
||||
};
|
||||
|
||||
static int ioc3_ds1685_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret, irq;
|
||||
|
||||
irq = ioc3_map_irq(ipd->pdev, 6, 0);
|
||||
|
||||
ret = mfd_add_devices(&ipd->pdev->dev, 0, ioc3_ds1685_cells,
|
||||
ARRAY_SIZE(ioc3_ds1685_cells),
|
||||
&ipd->pdev->resource[0], irq, NULL);
|
||||
if (ret)
|
||||
dev_err(&ipd->pdev->dev, "Failed to add DS1685 subdev\n");
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
static struct resource ioc3_leds_resources[] = {
|
||||
DEFINE_RES_MEM(offsetof(struct ioc3, gppr[0]),
|
||||
sizeof_field(struct ioc3, gppr[0])),
|
||||
DEFINE_RES_MEM(offsetof(struct ioc3, gppr[1]),
|
||||
sizeof_field(struct ioc3, gppr[1])),
|
||||
};
|
||||
|
||||
static struct mfd_cell ioc3_led_cells[] = {
|
||||
{
|
||||
.name = "ip30-leds",
|
||||
.resources = ioc3_leds_resources,
|
||||
.num_resources = ARRAY_SIZE(ioc3_leds_resources),
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
}
|
||||
};
|
||||
|
||||
static int ioc3_led_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mfd_add_devices(&ipd->pdev->dev, 0, ioc3_led_cells,
|
||||
ARRAY_SIZE(ioc3_led_cells),
|
||||
&ipd->pdev->resource[0], 0, ipd->domain);
|
||||
if (ret)
|
||||
dev_err(&ipd->pdev->dev, "Failed to add LED subdev\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ip27_baseio_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret, io_irq;
|
||||
|
||||
io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
|
||||
PCI_INTERRUPT_INTB);
|
||||
ret = ioc3_irq_domain_setup(ipd, io_irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_eth_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_serial_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ioc3_m48t35_setup(ipd);
|
||||
}
|
||||
|
||||
static int ip27_baseio6g_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret, io_irq;
|
||||
|
||||
io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
|
||||
PCI_INTERRUPT_INTB);
|
||||
ret = ioc3_irq_domain_setup(ipd, io_irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_eth_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_serial_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_m48t35_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ioc3_kbd_setup(ipd);
|
||||
}
|
||||
|
||||
static int ip27_mio_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ioc3_irq_domain_setup(ipd, ipd->pdev->irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_serial_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ioc3_kbd_setup(ipd);
|
||||
}
|
||||
|
||||
static int ip30_sysboard_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret, io_irq;
|
||||
|
||||
io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
|
||||
PCI_INTERRUPT_INTB);
|
||||
ret = ioc3_irq_domain_setup(ipd, io_irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_eth_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_serial_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_kbd_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_ds1685_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ioc3_led_setup(ipd);
|
||||
}
|
||||
|
||||
static int ioc3_menet_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret, io_irq;
|
||||
|
||||
io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
|
||||
PCI_INTERRUPT_INTB);
|
||||
ret = ioc3_irq_domain_setup(ipd, io_irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_eth_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ioc3_serial_setup(ipd);
|
||||
}
|
||||
|
||||
static int ioc3_menet4_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
return ioc3_eth_setup(ipd);
|
||||
}
|
||||
|
||||
static int ioc3_cad_duo_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
int ret, io_irq;
|
||||
|
||||
io_irq = ioc3_map_irq(ipd->pdev, PCI_SLOT(ipd->pdev->devfn),
|
||||
PCI_INTERRUPT_INTB);
|
||||
ret = ioc3_irq_domain_setup(ipd, io_irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ioc3_eth_setup(ipd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ioc3_kbd_setup(ipd);
|
||||
}
|
||||
|
||||
/* Helper macro for filling ioc3_info array */
|
||||
#define IOC3_SID(_name, _sid, _setup) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.sid = PCI_VENDOR_ID_SGI | (IOC3_SUBSYS_ ## _sid << 16), \
|
||||
.setup = _setup, \
|
||||
}
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
u32 sid;
|
||||
int (*setup)(struct ioc3_priv_data *ipd);
|
||||
} ioc3_infos[] = {
|
||||
IOC3_SID("IP27 BaseIO6G", IP27_BASEIO6G, &ip27_baseio6g_setup),
|
||||
IOC3_SID("IP27 MIO", IP27_MIO, &ip27_mio_setup),
|
||||
IOC3_SID("IP27 BaseIO", IP27_BASEIO, &ip27_baseio_setup),
|
||||
IOC3_SID("IP29 System Board", IP29_SYSBOARD, &ip27_baseio6g_setup),
|
||||
IOC3_SID("IP30 System Board", IP30_SYSBOARD, &ip30_sysboard_setup),
|
||||
IOC3_SID("MENET", MENET, &ioc3_menet_setup),
|
||||
IOC3_SID("MENET4", MENET4, &ioc3_menet4_setup)
|
||||
};
|
||||
#undef IOC3_SID
|
||||
|
||||
static int ioc3_setup(struct ioc3_priv_data *ipd)
|
||||
{
|
||||
u32 sid;
|
||||
int i;
|
||||
|
||||
/* Clear IRQs */
|
||||
writel(~0, &ipd->regs->sio_iec);
|
||||
writel(~0, &ipd->regs->sio_ir);
|
||||
writel(0, &ipd->regs->eth.eier);
|
||||
writel(~0, &ipd->regs->eth.eisr);
|
||||
|
||||
/* Read subsystem vendor id and subsystem id */
|
||||
pci_read_config_dword(ipd->pdev, PCI_SUBSYSTEM_VENDOR_ID, &sid);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ioc3_infos); i++)
|
||||
if (sid == ioc3_infos[i].sid) {
|
||||
pr_info("ioc3: %s\n", ioc3_infos[i].name);
|
||||
return ioc3_infos[i].setup(ipd);
|
||||
}
|
||||
|
||||
/* Treat everything not identified by PCI subid as CAD DUO */
|
||||
pr_info("ioc3: CAD DUO\n");
|
||||
return ioc3_cad_duo_setup(ipd);
|
||||
}
|
||||
|
||||
static int ioc3_mfd_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
struct ioc3_priv_data *ipd;
|
||||
struct ioc3 __iomem *regs;
|
||||
int ret;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, IOC3_LATENCY);
|
||||
pci_set_master(pdev);
|
||||
|
||||
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
|
||||
if (ret) {
|
||||
pr_err("%s: No usable DMA configuration, aborting.\n",
|
||||
pci_name(pdev));
|
||||
goto out_disable_device;
|
||||
}
|
||||
|
||||
/* Set up per-IOC3 data */
|
||||
ipd = devm_kzalloc(&pdev->dev, sizeof(struct ioc3_priv_data),
|
||||
GFP_KERNEL);
|
||||
if (!ipd) {
|
||||
ret = -ENOMEM;
|
||||
goto out_disable_device;
|
||||
}
|
||||
ipd->pdev = pdev;
|
||||
|
||||
/*
|
||||
* Map all IOC3 registers. These are shared between subdevices
|
||||
* so the main IOC3 module manages them.
|
||||
*/
|
||||
regs = pci_ioremap_bar(pdev, 0);
|
||||
if (!regs) {
|
||||
dev_warn(&pdev->dev, "ioc3: Unable to remap PCI BAR for %s.\n",
|
||||
pci_name(pdev));
|
||||
ret = -ENOMEM;
|
||||
goto out_disable_device;
|
||||
}
|
||||
ipd->regs = regs;
|
||||
|
||||
/* Track PCI-device specific data */
|
||||
pci_set_drvdata(pdev, ipd);
|
||||
|
||||
ret = ioc3_setup(ipd);
|
||||
if (ret) {
|
||||
/* Remove all already added MFD devices */
|
||||
mfd_remove_devices(&ipd->pdev->dev);
|
||||
if (ipd->domain) {
|
||||
irq_domain_remove(ipd->domain);
|
||||
free_irq(ipd->domain_irq, (void *)ipd);
|
||||
}
|
||||
pci_iounmap(pdev, regs);
|
||||
goto out_disable_device;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_disable_device:
|
||||
pci_disable_device(pdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ioc3_mfd_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct ioc3_priv_data *ipd;
|
||||
|
||||
ipd = pci_get_drvdata(pdev);
|
||||
|
||||
/* Clear and disable all IRQs */
|
||||
writel(~0, &ipd->regs->sio_iec);
|
||||
writel(~0, &ipd->regs->sio_ir);
|
||||
|
||||
/* Release resources */
|
||||
mfd_remove_devices(&ipd->pdev->dev);
|
||||
if (ipd->domain) {
|
||||
irq_domain_remove(ipd->domain);
|
||||
free_irq(ipd->domain_irq, (void *)ipd);
|
||||
}
|
||||
pci_iounmap(pdev, ipd->regs);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static struct pci_device_id ioc3_mfd_id_table[] = {
|
||||
{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ 0, },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ioc3_mfd_id_table);
|
||||
|
||||
static struct pci_driver ioc3_mfd_driver = {
|
||||
.name = "IOC3",
|
||||
.id_table = ioc3_mfd_id_table,
|
||||
.probe = ioc3_mfd_probe,
|
||||
.remove = ioc3_mfd_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(ioc3_mfd_driver);
|
||||
|
||||
MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>");
|
||||
MODULE_DESCRIPTION("SGI IOC3 MFD driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -6,7 +6,7 @@
|
|||
config NET_VENDOR_SGI
|
||||
bool "SGI devices"
|
||||
default y
|
||||
depends on (PCI && SGI_IP27) || SGI_IP32
|
||||
depends on (PCI && SGI_MFD_IOC3) || SGI_IP32
|
||||
---help---
|
||||
If you have a network (Ethernet) card belonging to this class, say Y.
|
||||
|
||||
|
@ -19,7 +19,8 @@ if NET_VENDOR_SGI
|
|||
|
||||
config SGI_IOC3_ETH
|
||||
bool "SGI IOC3 Ethernet"
|
||||
depends on PCI && SGI_IP27
|
||||
depends on PCI && SGI_MFD_IOC3
|
||||
select CRC16
|
||||
select CRC32
|
||||
select MII
|
||||
---help---
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
* o Use prefetching for large packets. What is a good lower limit for
|
||||
* prefetching?
|
||||
* o Use hardware checksums.
|
||||
* o Convert to using a IOC3 meta driver.
|
||||
* o Which PHYs might possibly be attached to the IOC3 in real live,
|
||||
* which workarounds are required for them? Do we ever have Lucent's?
|
||||
* o For the 2.5 branch kill the mii-tool ioctls.
|
||||
|
@ -28,7 +27,8 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/crc16.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/in.h>
|
||||
|
@ -37,28 +37,22 @@
|
|||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#endif
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
|
||||
#include <net/ip.h>
|
||||
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/sn/types.h>
|
||||
#include <asm/sn/ioc3.h>
|
||||
#include <asm/pci/bridge.h>
|
||||
|
||||
#define CRC16_INIT 0
|
||||
#define CRC16_VALID 0xb001
|
||||
|
||||
/* Number of RX buffers. This is tunable in the range of 16 <= x < 512.
|
||||
* The value must be a power of two.
|
||||
*/
|
||||
|
@ -85,7 +79,6 @@
|
|||
/* Private per NIC data of the driver. */
|
||||
struct ioc3_private {
|
||||
struct ioc3_ethregs *regs;
|
||||
struct ioc3 *all_regs;
|
||||
struct device *dma_dev;
|
||||
u32 *ssram;
|
||||
unsigned long *rxr; /* pointer to receiver ring */
|
||||
|
@ -104,9 +97,6 @@ struct ioc3_private {
|
|||
spinlock_t ioc3_lock;
|
||||
struct mii_if_info mii;
|
||||
|
||||
struct net_device *dev;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
/* Members used by autonegotiation */
|
||||
struct timer_list ioc3_timer;
|
||||
};
|
||||
|
@ -123,10 +113,8 @@ static int ioc3_alloc_rx_bufs(struct net_device *dev);
|
|||
static void ioc3_free_rx_bufs(struct ioc3_private *ip);
|
||||
static inline void ioc3_clean_tx_ring(struct ioc3_private *ip);
|
||||
|
||||
static const char ioc3_str[] = "IOC3 Ethernet";
|
||||
static const struct ethtool_ops ioc3_ethtool_ops;
|
||||
|
||||
|
||||
static inline unsigned long aligned_rx_skb_addr(unsigned long addr)
|
||||
{
|
||||
return (~addr + 1) & (IOC3_DMA_XFER_LEN - 1UL);
|
||||
|
@ -179,225 +167,61 @@ static inline unsigned long ioc3_map(dma_addr_t addr, unsigned long attr)
|
|||
#define ERBAR_VAL 0
|
||||
#endif
|
||||
|
||||
#define IOC3_SIZE 0x100000
|
||||
|
||||
static inline u32 mcr_pack(u32 pulse, u32 sample)
|
||||
static int ioc3eth_nvmem_match(struct device *dev, const void *data)
|
||||
{
|
||||
return (pulse << 10) | (sample << 2);
|
||||
}
|
||||
const char *name = dev_name(dev);
|
||||
const char *prefix = data;
|
||||
int prefix_len;
|
||||
|
||||
static int nic_wait(u32 __iomem *mcr)
|
||||
{
|
||||
u32 m;
|
||||
prefix_len = strlen(prefix);
|
||||
if (strlen(name) < (prefix_len + 3))
|
||||
return 0;
|
||||
|
||||
do {
|
||||
m = readl(mcr);
|
||||
} while (!(m & 2));
|
||||
if (memcmp(prefix, name, prefix_len) != 0)
|
||||
return 0;
|
||||
|
||||
return m & 1;
|
||||
}
|
||||
|
||||
static int nic_reset(u32 __iomem *mcr)
|
||||
{
|
||||
int presence;
|
||||
|
||||
writel(mcr_pack(500, 65), mcr);
|
||||
presence = nic_wait(mcr);
|
||||
|
||||
writel(mcr_pack(0, 500), mcr);
|
||||
nic_wait(mcr);
|
||||
|
||||
return presence;
|
||||
}
|
||||
|
||||
static inline int nic_read_bit(u32 __iomem *mcr)
|
||||
{
|
||||
int result;
|
||||
|
||||
writel(mcr_pack(6, 13), mcr);
|
||||
result = nic_wait(mcr);
|
||||
writel(mcr_pack(0, 100), mcr);
|
||||
nic_wait(mcr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void nic_write_bit(u32 __iomem *mcr, int bit)
|
||||
{
|
||||
if (bit)
|
||||
writel(mcr_pack(6, 110), mcr);
|
||||
else
|
||||
writel(mcr_pack(80, 30), mcr);
|
||||
|
||||
nic_wait(mcr);
|
||||
}
|
||||
|
||||
/* Read a byte from an iButton device
|
||||
*/
|
||||
static u32 nic_read_byte(u32 __iomem *mcr)
|
||||
{
|
||||
u32 result = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
result = (result >> 1) | (nic_read_bit(mcr) << 7);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Write a byte to an iButton device
|
||||
*/
|
||||
static void nic_write_byte(u32 __iomem *mcr, int byte)
|
||||
{
|
||||
int i, bit;
|
||||
|
||||
for (i = 8; i; i--) {
|
||||
bit = byte & 1;
|
||||
byte >>= 1;
|
||||
|
||||
nic_write_bit(mcr, bit);
|
||||
}
|
||||
}
|
||||
|
||||
static u64 nic_find(u32 __iomem *mcr, int *last)
|
||||
{
|
||||
int a, b, index, disc;
|
||||
u64 address = 0;
|
||||
|
||||
nic_reset(mcr);
|
||||
/* Search ROM. */
|
||||
nic_write_byte(mcr, 0xf0);
|
||||
|
||||
/* Algorithm from ``Book of iButton Standards''. */
|
||||
for (index = 0, disc = 0; index < 64; index++) {
|
||||
a = nic_read_bit(mcr);
|
||||
b = nic_read_bit(mcr);
|
||||
|
||||
if (a && b) {
|
||||
pr_warn("NIC search failed (not fatal).\n");
|
||||
*last = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!a && !b) {
|
||||
if (index == *last) {
|
||||
address |= 1UL << index;
|
||||
} else if (index > *last) {
|
||||
address &= ~(1UL << index);
|
||||
disc = index;
|
||||
} else if ((address & (1UL << index)) == 0) {
|
||||
disc = index;
|
||||
}
|
||||
nic_write_bit(mcr, address & (1UL << index));
|
||||
continue;
|
||||
} else {
|
||||
if (a)
|
||||
address |= 1UL << index;
|
||||
else
|
||||
address &= ~(1UL << index);
|
||||
nic_write_bit(mcr, a);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
*last = disc;
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static int nic_init(u32 __iomem *mcr)
|
||||
{
|
||||
const char *unknown = "unknown";
|
||||
const char *type = unknown;
|
||||
u8 crc;
|
||||
u8 serial[6];
|
||||
int save = 0, i;
|
||||
|
||||
while (1) {
|
||||
u64 reg;
|
||||
|
||||
reg = nic_find(mcr, &save);
|
||||
|
||||
switch (reg & 0xff) {
|
||||
case 0x91:
|
||||
type = "DS1981U";
|
||||
break;
|
||||
default:
|
||||
if (save == 0) {
|
||||
/* Let the caller try again. */
|
||||
return -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
nic_reset(mcr);
|
||||
|
||||
/* Match ROM. */
|
||||
nic_write_byte(mcr, 0x55);
|
||||
for (i = 0; i < 8; i++)
|
||||
nic_write_byte(mcr, (reg >> (i << 3)) & 0xff);
|
||||
|
||||
reg >>= 8; /* Shift out type. */
|
||||
for (i = 0; i < 6; i++) {
|
||||
serial[i] = reg & 0xff;
|
||||
reg >>= 8;
|
||||
}
|
||||
crc = reg & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
pr_info("Found %s NIC", type);
|
||||
if (type != unknown)
|
||||
pr_cont(" registration number %pM, CRC %02x", serial, crc);
|
||||
pr_cont(".\n");
|
||||
/* found nvmem device which is attached to our ioc3
|
||||
* now check for one wire family code 09, 89 and 91
|
||||
*/
|
||||
if (memcmp(name + prefix_len, "09-", 3) == 0)
|
||||
return 1;
|
||||
if (memcmp(name + prefix_len, "89-", 3) == 0)
|
||||
return 1;
|
||||
if (memcmp(name + prefix_len, "91-", 3) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read the NIC (Number-In-a-Can) device used to store the MAC address on
|
||||
* SN0 / SN00 nodeboards and PCI cards.
|
||||
*/
|
||||
static void ioc3_get_eaddr_nic(struct ioc3_private *ip)
|
||||
static int ioc3eth_get_mac_addr(struct resource *res, u8 mac_addr[6])
|
||||
{
|
||||
u32 __iomem *mcr = &ip->all_regs->mcr;
|
||||
int tries = 2; /* There may be some problem with the battery? */
|
||||
u8 nic[14];
|
||||
struct nvmem_device *nvmem;
|
||||
char prefix[24];
|
||||
u8 prom[16];
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
writel(1 << 21, &ip->all_regs->gpcr_s);
|
||||
snprintf(prefix, sizeof(prefix), "ioc3-%012llx-",
|
||||
res->start & ~0xffff);
|
||||
|
||||
while (tries--) {
|
||||
if (!nic_init(mcr))
|
||||
break;
|
||||
udelay(500);
|
||||
}
|
||||
nvmem = nvmem_device_find(prefix, ioc3eth_nvmem_match);
|
||||
if (IS_ERR(nvmem))
|
||||
return PTR_ERR(nvmem);
|
||||
|
||||
if (tries < 0) {
|
||||
pr_err("Failed to read MAC address\n");
|
||||
return;
|
||||
}
|
||||
ret = nvmem_device_read(nvmem, 0, 16, prom);
|
||||
nvmem_device_put(nvmem);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Read Memory. */
|
||||
nic_write_byte(mcr, 0xf0);
|
||||
nic_write_byte(mcr, 0x00);
|
||||
nic_write_byte(mcr, 0x00);
|
||||
/* check, if content is valid */
|
||||
if (prom[0] != 0x0a ||
|
||||
crc16(CRC16_INIT, prom, 13) != CRC16_VALID)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 13; i >= 0; i--)
|
||||
nic[i] = nic_read_byte(mcr);
|
||||
for (i = 0; i < 6; i++)
|
||||
mac_addr[i] = prom[10 - i];
|
||||
|
||||
for (i = 2; i < 8; i++)
|
||||
ip->dev->dev_addr[i - 2] = nic[i];
|
||||
}
|
||||
|
||||
/* Ok, this is hosed by design. It's necessary to know what machine the
|
||||
* NIC is in in order to know how to read the NIC address. We also have
|
||||
* to know if it's a PCI card or a NIC in on the node board ...
|
||||
*/
|
||||
static void ioc3_get_eaddr(struct ioc3_private *ip)
|
||||
{
|
||||
ioc3_get_eaddr_nic(ip);
|
||||
|
||||
pr_info("Ethernet address is %pM.\n", ip->dev->dev_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __ioc3_set_mac_address(struct net_device *dev)
|
||||
|
@ -770,7 +594,7 @@ static int ioc3_mii_init(struct ioc3_private *ip)
|
|||
u16 word;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
word = ioc3_mdio_read(ip->dev, i, MII_PHYSID1);
|
||||
word = ioc3_mdio_read(ip->mii.dev, i, MII_PHYSID1);
|
||||
|
||||
if (word != 0xffff && word != 0x0000) {
|
||||
found = 1;
|
||||
|
@ -975,12 +799,6 @@ static int ioc3_open(struct net_device *dev)
|
|||
{
|
||||
struct ioc3_private *ip = netdev_priv(dev);
|
||||
|
||||
if (request_irq(dev->irq, ioc3_interrupt, IRQF_SHARED, ioc3_str, dev)) {
|
||||
netdev_err(dev, "Can't get irq %d\n", dev->irq);
|
||||
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
ip->ehar_h = 0;
|
||||
ip->ehar_l = 0;
|
||||
|
||||
|
@ -1013,147 +831,6 @@ static int ioc3_close(struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* MENET cards have four IOC3 chips, which are attached to two sets of
|
||||
* PCI slot resources each: the primary connections are on slots
|
||||
* 0..3 and the secondaries are on 4..7
|
||||
*
|
||||
* All four ethernets are brought out to connectors; six serial ports
|
||||
* (a pair from each of the first three IOC3s) are brought out to
|
||||
* MiniDINs; all other subdevices are left swinging in the wind, leave
|
||||
* them disabled.
|
||||
*/
|
||||
|
||||
static int ioc3_adjacent_is_ioc3(struct pci_dev *pdev, int slot)
|
||||
{
|
||||
struct pci_dev *dev = pci_get_slot(pdev->bus, PCI_DEVFN(slot, 0));
|
||||
int ret = 0;
|
||||
|
||||
if (dev) {
|
||||
if (dev->vendor == PCI_VENDOR_ID_SGI &&
|
||||
dev->device == PCI_DEVICE_ID_SGI_IOC3)
|
||||
ret = 1;
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ioc3_is_menet(struct pci_dev *pdev)
|
||||
{
|
||||
return !pdev->bus->parent &&
|
||||
ioc3_adjacent_is_ioc3(pdev, 0) &&
|
||||
ioc3_adjacent_is_ioc3(pdev, 1) &&
|
||||
ioc3_adjacent_is_ioc3(pdev, 2);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250
|
||||
/* Note about serial ports and consoles:
|
||||
* For console output, everyone uses the IOC3 UARTA (offset 0x178)
|
||||
* connected to the master node (look in ip27_setup_console() and
|
||||
* ip27prom_console_write()).
|
||||
*
|
||||
* For serial (/dev/ttyS0 etc), we can not have hardcoded serial port
|
||||
* addresses on a partitioned machine. Since we currently use the ioc3
|
||||
* serial ports, we use dynamic serial port discovery that the serial.c
|
||||
* driver uses for pci/pnp ports (there is an entry for the SGI ioc3
|
||||
* boards in pci_boards[]). Unfortunately, UARTA's pio address is greater
|
||||
* than UARTB's, although UARTA on o200s has traditionally been known as
|
||||
* port 0. So, we just use one serial port from each ioc3 (since the
|
||||
* serial driver adds addresses to get to higher ports).
|
||||
*
|
||||
* The first one to do a register_console becomes the preferred console
|
||||
* (if there is no kernel command line console= directive). /dev/console
|
||||
* (ie 5, 1) is then "aliased" into the device number returned by the
|
||||
* "device" routine referred to in this console structure
|
||||
* (ip27prom_console_dev).
|
||||
*
|
||||
* Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working
|
||||
* around ioc3 oddities in this respect.
|
||||
*
|
||||
* The IOC3 serials use a 22MHz clock rate with an additional divider which
|
||||
* can be programmed in the SCR register if the DLAB bit is set.
|
||||
*
|
||||
* Register to interrupt zero because we share the interrupt with
|
||||
* the serial driver which we don't properly support yet.
|
||||
*
|
||||
* Can't use UPF_IOREMAP as the whole of IOC3 resources have already been
|
||||
* registered.
|
||||
*/
|
||||
static void ioc3_8250_register(struct ioc3_uartregs __iomem *uart)
|
||||
{
|
||||
#define COSMISC_CONSTANT 6
|
||||
|
||||
struct uart_8250_port port = {
|
||||
.port = {
|
||||
.irq = 0,
|
||||
.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
|
||||
.iotype = UPIO_MEM,
|
||||
.regshift = 0,
|
||||
.uartclk = (22000000 << 1) / COSMISC_CONSTANT,
|
||||
|
||||
.membase = (unsigned char __iomem *)uart,
|
||||
.mapbase = (unsigned long)uart,
|
||||
}
|
||||
};
|
||||
unsigned char lcr;
|
||||
|
||||
lcr = readb(&uart->iu_lcr);
|
||||
writeb(lcr | UART_LCR_DLAB, &uart->iu_lcr);
|
||||
writeb(COSMISC_CONSTANT, &uart->iu_scr);
|
||||
writeb(lcr, &uart->iu_lcr);
|
||||
readb(&uart->iu_lcr);
|
||||
serial8250_register_8250_port(&port);
|
||||
}
|
||||
|
||||
static void ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
|
||||
{
|
||||
u32 sio_iec;
|
||||
|
||||
/* We need to recognice and treat the fourth MENET serial as it
|
||||
* does not have an SuperIO chip attached to it, therefore attempting
|
||||
* to access it will result in bus errors. We call something an
|
||||
* MENET if PCI slot 0, 1, 2 and 3 of a master PCI bus all have an IOC3
|
||||
* in it. This is paranoid but we want to avoid blowing up on a
|
||||
* showhorn PCI box that happens to have 4 IOC3 cards in it so it's
|
||||
* not paranoid enough ...
|
||||
*/
|
||||
if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3)
|
||||
return;
|
||||
|
||||
/* Switch IOC3 to PIO mode. It probably already was but let's be
|
||||
* paranoid
|
||||
*/
|
||||
writel(GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL, &ioc3->gpcr_s);
|
||||
readl(&ioc3->gpcr_s);
|
||||
writel(0, &ioc3->gppr[6]);
|
||||
readl(&ioc3->gppr[6]);
|
||||
writel(0, &ioc3->gppr[7]);
|
||||
readl(&ioc3->gppr[7]);
|
||||
writel(readl(&ioc3->port_a.sscr) & ~SSCR_DMA_EN, &ioc3->port_a.sscr);
|
||||
readl(&ioc3->port_a.sscr);
|
||||
writel(readl(&ioc3->port_b.sscr) & ~SSCR_DMA_EN, &ioc3->port_b.sscr);
|
||||
readl(&ioc3->port_b.sscr);
|
||||
/* Disable all SA/B interrupts except for SA/B_INT in SIO_IEC. */
|
||||
sio_iec = readl(&ioc3->sio_iec);
|
||||
sio_iec &= ~(SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL |
|
||||
SIO_IR_SA_RX_HIGH | SIO_IR_SA_RX_TIMER |
|
||||
SIO_IR_SA_DELTA_DCD | SIO_IR_SA_DELTA_CTS |
|
||||
SIO_IR_SA_TX_EXPLICIT | SIO_IR_SA_MEMERR);
|
||||
sio_iec |= SIO_IR_SA_INT;
|
||||
sio_iec &= ~(SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL |
|
||||
SIO_IR_SB_RX_HIGH | SIO_IR_SB_RX_TIMER |
|
||||
SIO_IR_SB_DELTA_DCD | SIO_IR_SB_DELTA_CTS |
|
||||
SIO_IR_SB_TX_EXPLICIT | SIO_IR_SB_MEMERR);
|
||||
sio_iec |= SIO_IR_SB_INT;
|
||||
writel(sio_iec, &ioc3->sio_iec);
|
||||
writel(0, &ioc3->port_a.sscr);
|
||||
writel(0, &ioc3->port_b.sscr);
|
||||
|
||||
ioc3_8250_register(&ioc3->sregs.uarta);
|
||||
ioc3_8250_register(&ioc3->sregs.uartb);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct net_device_ops ioc3_netdev_ops = {
|
||||
.ndo_open = ioc3_open,
|
||||
.ndo_stop = ioc3_close,
|
||||
|
@ -1166,61 +843,52 @@ static const struct net_device_ops ioc3_netdev_ops = {
|
|||
.ndo_set_mac_address = ioc3_set_mac_address,
|
||||
};
|
||||
|
||||
static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
static int ioc3eth_probe(struct platform_device *pdev)
|
||||
{
|
||||
unsigned int sw_physid1, sw_physid2;
|
||||
struct net_device *dev = NULL;
|
||||
u32 sw_physid1, sw_physid2, vendor, model, rev;
|
||||
struct ioc3_private *ip;
|
||||
struct ioc3 *ioc3;
|
||||
unsigned long ioc3_base, ioc3_size;
|
||||
u32 vendor, model, rev;
|
||||
struct net_device *dev;
|
||||
struct resource *regs;
|
||||
u8 mac_addr[6];
|
||||
int err;
|
||||
|
||||
/* Configure DMA attributes. */
|
||||
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
|
||||
if (err) {
|
||||
pr_err("%s: No usable DMA configuration, aborting.\n",
|
||||
pci_name(pdev));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (pci_enable_device(pdev))
|
||||
return -ENODEV;
|
||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
/* get mac addr from one wire prom */
|
||||
if (ioc3eth_get_mac_addr(regs, mac_addr))
|
||||
return -EPROBE_DEFER; /* not available yet */
|
||||
|
||||
dev = alloc_etherdev(sizeof(struct ioc3_private));
|
||||
if (!dev) {
|
||||
err = -ENOMEM;
|
||||
goto out_disable;
|
||||
}
|
||||
|
||||
err = pci_request_regions(pdev, "ioc3");
|
||||
if (err)
|
||||
goto out_free;
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||
|
||||
ip = netdev_priv(dev);
|
||||
ip->dev = dev;
|
||||
ip->dma_dev = &pdev->dev;
|
||||
|
||||
dev->irq = pdev->irq;
|
||||
|
||||
ioc3_base = pci_resource_start(pdev, 0);
|
||||
ioc3_size = pci_resource_len(pdev, 0);
|
||||
ioc3 = (struct ioc3 *)ioremap(ioc3_base, ioc3_size);
|
||||
if (!ioc3) {
|
||||
pr_err("ioc3eth(%s): ioremap failed, goodbye.\n",
|
||||
pci_name(pdev));
|
||||
ip->dma_dev = pdev->dev.parent;
|
||||
ip->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (!ip->regs) {
|
||||
err = -ENOMEM;
|
||||
goto out_res;
|
||||
goto out_free;
|
||||
}
|
||||
ip->regs = &ioc3->eth;
|
||||
ip->ssram = ioc3->ssram;
|
||||
ip->all_regs = ioc3;
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250
|
||||
ioc3_serial_probe(pdev, ioc3);
|
||||
#endif
|
||||
ip->ssram = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (!ip->ssram) {
|
||||
err = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
dev->irq = platform_get_irq(pdev, 0);
|
||||
if (dev->irq < 0) {
|
||||
err = dev->irq;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (devm_request_irq(&pdev->dev, dev->irq, ioc3_interrupt,
|
||||
IRQF_SHARED, "ioc3-eth", dev)) {
|
||||
dev_err(&pdev->dev, "Can't get irq %d\n", dev->irq);
|
||||
err = -ENODEV;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
spin_lock_init(&ip->ioc3_lock);
|
||||
timer_setup(&ip->ioc3_timer, ioc3_timer, 0);
|
||||
|
@ -1250,8 +918,6 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
ioc3_init(dev);
|
||||
|
||||
ip->pdev = pdev;
|
||||
|
||||
ip->mii.phy_id_mask = 0x1f;
|
||||
ip->mii.reg_num_mask = 0x1f;
|
||||
ip->mii.dev = dev;
|
||||
|
@ -1261,15 +927,14 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
ioc3_mii_init(ip);
|
||||
|
||||
if (ip->mii.phy_id == -1) {
|
||||
pr_err("ioc3-eth(%s): Didn't find a PHY, goodbye.\n",
|
||||
pci_name(pdev));
|
||||
netdev_err(dev, "Didn't find a PHY, goodbye.\n");
|
||||
err = -ENODEV;
|
||||
goto out_stop;
|
||||
}
|
||||
|
||||
ioc3_mii_start(ip);
|
||||
ioc3_ssram_disc(ip);
|
||||
ioc3_get_eaddr(ip);
|
||||
memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
|
||||
|
||||
/* The IOC3-specific entries in the device structure. */
|
||||
dev->watchdog_timeo = 5 * HZ;
|
||||
|
@ -1306,21 +971,14 @@ out_stop:
|
|||
if (ip->tx_ring)
|
||||
dma_free_coherent(ip->dma_dev, TX_RING_SIZE, ip->tx_ring,
|
||||
ip->txr_dma);
|
||||
out_res:
|
||||
pci_release_regions(pdev);
|
||||
out_free:
|
||||
free_netdev(dev);
|
||||
out_disable:
|
||||
/* We should call pci_disable_device(pdev); here if the IOC3 wasn't
|
||||
* such a weird device ...
|
||||
*/
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void ioc3_remove_one(struct pci_dev *pdev)
|
||||
static int ioc3eth_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = pci_get_drvdata(pdev);
|
||||
struct net_device *dev = platform_get_drvdata(pdev);
|
||||
struct ioc3_private *ip = netdev_priv(dev);
|
||||
|
||||
dma_free_coherent(ip->dma_dev, RX_RING_SIZE, ip->rxr, ip->rxr_dma);
|
||||
|
@ -1328,27 +986,11 @@ static void ioc3_remove_one(struct pci_dev *pdev)
|
|||
|
||||
unregister_netdev(dev);
|
||||
del_timer_sync(&ip->ioc3_timer);
|
||||
|
||||
iounmap(ip->all_regs);
|
||||
pci_release_regions(pdev);
|
||||
free_netdev(dev);
|
||||
/* We should call pci_disable_device(pdev); here if the IOC3 wasn't
|
||||
* such a weird device ...
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pci_device_id ioc3_pci_tbl[] = {
|
||||
{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ 0 }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ioc3_pci_tbl);
|
||||
|
||||
static struct pci_driver ioc3_driver = {
|
||||
.name = "ioc3-eth",
|
||||
.id_table = ioc3_pci_tbl,
|
||||
.probe = ioc3_probe,
|
||||
.remove = ioc3_remove_one,
|
||||
};
|
||||
|
||||
static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
|
@ -1530,11 +1172,10 @@ static inline unsigned int ioc3_hash(const unsigned char *addr)
|
|||
static void ioc3_get_drvinfo(struct net_device *dev,
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
struct ioc3_private *ip = netdev_priv(dev);
|
||||
|
||||
strlcpy(info->driver, IOC3_NAME, sizeof(info->driver));
|
||||
strlcpy(info->version, IOC3_VERSION, sizeof(info->version));
|
||||
strlcpy(info->bus_info, pci_name(ip->pdev), sizeof(info->bus_info));
|
||||
strlcpy(info->bus_info, pci_name(to_pci_dev(dev->dev.parent)),
|
||||
sizeof(info->bus_info));
|
||||
}
|
||||
|
||||
static int ioc3_get_link_ksettings(struct net_device *dev,
|
||||
|
@ -1646,7 +1287,16 @@ static void ioc3_set_multicast_list(struct net_device *dev)
|
|||
spin_unlock_irq(&ip->ioc3_lock);
|
||||
}
|
||||
|
||||
module_pci_driver(ioc3_driver);
|
||||
static struct platform_driver ioc3eth_driver = {
|
||||
.probe = ioc3eth_probe,
|
||||
.remove = ioc3eth_remove,
|
||||
.driver = {
|
||||
.name = "ioc3-eth",
|
||||
}
|
||||
};
|
||||
|
||||
module_platform_driver(ioc3eth_driver);
|
||||
|
||||
MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");
|
||||
MODULE_DESCRIPTION("SGI IOC3 Ethernet driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -20,6 +20,16 @@
|
|||
|
||||
struct m48t35_rtc {
|
||||
u8 pad[0x7ff8]; /* starts at 0x7ff8 */
|
||||
#ifdef CONFIG_SGI_IP27
|
||||
u8 hour;
|
||||
u8 min;
|
||||
u8 sec;
|
||||
u8 control;
|
||||
u8 year;
|
||||
u8 month;
|
||||
u8 date;
|
||||
u8 day;
|
||||
#else
|
||||
u8 control;
|
||||
u8 sec;
|
||||
u8 min;
|
||||
|
@ -28,6 +38,7 @@ struct m48t35_rtc {
|
|||
u8 date;
|
||||
u8 month;
|
||||
u8 year;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define M48T35_RTC_SET 0x80
|
||||
|
|
|
@ -28,14 +28,12 @@ static int ltq_fpi_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct resource *res_xbar;
|
||||
struct regmap *rcu_regmap;
|
||||
void __iomem *xbar_membase;
|
||||
u32 rcu_ahb_endianness_reg_offset;
|
||||
int ret;
|
||||
|
||||
res_xbar = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
xbar_membase = devm_ioremap_resource(dev, res_xbar);
|
||||
xbar_membase = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(xbar_membase))
|
||||
return PTR_ERR(xbar_membase);
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ EXPORT_SYMBOL(tc_unregister_driver);
|
|||
* system is in its list of supported devices. Returns the matching
|
||||
* tc_device_id structure or %NULL if there is no match.
|
||||
*/
|
||||
const struct tc_device_id *tc_match_device(struct tc_driver *tdrv,
|
||||
struct tc_dev *tdev)
|
||||
static const struct tc_device_id *tc_match_device(struct tc_driver *tdrv,
|
||||
struct tc_dev *tdev)
|
||||
{
|
||||
const struct tc_device_id *id = tdrv->id_table;
|
||||
|
||||
|
@ -71,7 +71,6 @@ const struct tc_device_id *tc_match_device(struct tc_driver *tdrv,
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(tc_match_device);
|
||||
|
||||
/**
|
||||
* tc_bus_match - Tell if a device structure has a matching
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* SGI IOC3 8250 UART driver
|
||||
*
|
||||
* Copyright (C) 2019 Thomas Bogendoerfer <tbogendoerfer@suse.de>
|
||||
*
|
||||
* based on code Copyright (C) 2005 Stanislaw Skowronek <skylark@unaligned.org>
|
||||
* Copyright (C) 2014 Joshua Kinard <kumba@gentoo.org>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "8250.h"
|
||||
|
||||
#define IOC3_UARTCLK (22000000 / 3)
|
||||
|
||||
struct ioc3_8250_data {
|
||||
int line;
|
||||
};
|
||||
|
||||
static unsigned int ioc3_serial_in(struct uart_port *p, int offset)
|
||||
{
|
||||
return readb(p->membase + (offset ^ 3));
|
||||
}
|
||||
|
||||
static void ioc3_serial_out(struct uart_port *p, int offset, int value)
|
||||
{
|
||||
writeb(value, p->membase + (offset ^ 3));
|
||||
}
|
||||
|
||||
static int serial8250_ioc3_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ioc3_8250_data *data;
|
||||
struct uart_8250_port up;
|
||||
struct resource *r;
|
||||
void __iomem *membase;
|
||||
int irq, line;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!r)
|
||||
return -ENODEV;
|
||||
|
||||
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
membase = devm_ioremap_nocache(&pdev->dev, r->start, resource_size(r));
|
||||
if (!membase)
|
||||
return -ENOMEM;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
irq = 0; /* no interrupt -> use polling */
|
||||
|
||||
/* Register serial ports with 8250.c */
|
||||
memset(&up, 0, sizeof(struct uart_8250_port));
|
||||
up.port.iotype = UPIO_MEM;
|
||||
up.port.uartclk = IOC3_UARTCLK;
|
||||
up.port.type = PORT_16550A;
|
||||
up.port.irq = irq;
|
||||
up.port.flags = (UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ);
|
||||
up.port.dev = &pdev->dev;
|
||||
up.port.membase = membase;
|
||||
up.port.mapbase = r->start;
|
||||
up.port.serial_in = ioc3_serial_in;
|
||||
up.port.serial_out = ioc3_serial_out;
|
||||
line = serial8250_register_8250_port(&up);
|
||||
if (line < 0)
|
||||
return line;
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial8250_ioc3_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ioc3_8250_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
serial8250_unregister_port(data->line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver serial8250_ioc3_driver = {
|
||||
.probe = serial8250_ioc3_probe,
|
||||
.remove = serial8250_ioc3_remove,
|
||||
.driver = {
|
||||
.name = "ioc3-serial8250",
|
||||
}
|
||||
};
|
||||
|
||||
module_platform_driver(serial8250_ioc3_driver);
|
||||
|
||||
MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>");
|
||||
MODULE_DESCRIPTION("SGI IOC3 8250 UART driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -381,6 +381,17 @@ config SERIAL_8250_EM
|
|||
port hardware found on the Emma Mobile line of processors.
|
||||
If unsure, say N.
|
||||
|
||||
config SERIAL_8250_IOC3
|
||||
tristate "SGI IOC3 8250 UART support"
|
||||
depends on SGI_MFD_IOC3 && SERIAL_8250
|
||||
select SERIAL_8250_EXTENDED
|
||||
select SERIAL_8250_SHARE_IRQ
|
||||
help
|
||||
Enable this if you have a SGI Origin or Octane machine. This module
|
||||
provides basic serial support by directly driving the UART chip
|
||||
behind the IOC3 device on those systems. Maximum baud speed is
|
||||
38400bps using this driver.
|
||||
|
||||
config SERIAL_8250_RT288X
|
||||
bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support"
|
||||
depends on SERIAL_8250
|
||||
|
|
|
@ -28,6 +28,7 @@ obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
|
|||
obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o
|
||||
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
|
||||
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
|
||||
obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o
|
||||
obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o
|
||||
obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o
|
||||
obj-$(CONFIG_SERIAL_8250_MT6577) += 8250_mtk.o
|
||||
|
|
Загрузка…
Ссылка в новой задаче